summaryrefslogtreecommitdiff
path: root/gs
diff options
context:
space:
mode:
authorHenry Stiles <henry.stiles@artifex.com>1999-05-24 20:03:13 +0000
committerHenry Stiles <henry.stiles@artifex.com>1999-05-24 20:03:13 +0000
commit5e99d00db40250c4aec92e2e7ecaf51f629540ae (patch)
treec59a16131c363a845609bb0786adc205d3f6fddc /gs
parent7ddfba499458819bf0dbf297b084f8b5b51b8690 (diff)
downloadghostpdl-5e99d00db40250c4aec92e2e7ecaf51f629540ae.tar.gz
initial gs5.84 checkin with pcl and xl compiling.
git-svn-id: http://svn.ghostscript.com/ghostpcl/trunk/ghostpcl@857 06663e23-700e-0410-b217-a244a6096597
Diffstat (limited to 'gs')
-rw-r--r--gs/examples/alphabet.ps56
-rw-r--r--gs/examples/cheq.ps945
-rw-r--r--gs/examples/chess.ps101
-rw-r--r--gs/examples/colorcir.ps122
-rw-r--r--gs/examples/escher.ps379
-rw-r--r--gs/examples/golfer.ps1398
-rw-r--r--gs/examples/grayalph.ps61
-rw-r--r--gs/examples/snowflak.ps (renamed from gs/lib/snowflak.ps)0
-rw-r--r--gs/examples/tiger.ps (renamed from gs/lib/tiger.ps)0
-rw-r--r--gs/examples/vasarely.ps (renamed from gs/lib/vasarely.ps)0
-rw-r--r--gs/examples/waterfal.ps (renamed from gs/lib/waterfal.ps)0
-rw-r--r--gs/lib/Fontmap19
-rw-r--r--gs/lib/Fontmap.GS19
-rw-r--r--gs/lib/Fontmap.Sol19
-rw-r--r--gs/lib/Fontmap.Ult16
-rw-r--r--gs/lib/errpage.ps364
-rw-r--r--gs/lib/gs_btokn.ps8
-rw-r--r--gs/lib/gs_cff.ps34
-rw-r--r--gs/lib/gs_cidfn.ps64
-rw-r--r--gs/lib/gs_cmap.ps319
-rw-r--r--gs/lib/gs_dps1.ps6
-rw-r--r--gs/lib/gs_dps2.ps116
-rw-r--r--gs/lib/gs_fonts.ps4
-rw-r--r--gs/lib/gs_init.ps287
-rw-r--r--gs/lib/gs_lev2.ps42
-rw-r--r--gs/lib/gs_ll3.ps433
-rw-r--r--gs/lib/gs_mro_e.ps4
-rw-r--r--gs/lib/gs_pdf_e.ps4
-rw-r--r--gs/lib/gs_pdfwr.ps14
-rw-r--r--gs/lib/gs_rdlin.ps22
-rw-r--r--gs/lib/gs_res.ps78
-rw-r--r--gs/lib/gs_sym_e.ps4
-rw-r--r--gs/lib/gs_trap.ps104
-rw-r--r--gs/lib/gs_ttf.ps40
-rw-r--r--gs/lib/gs_typ32.ps25
-rw-r--r--gs/lib/gs_type1.ps50
-rw-r--r--gs/lib/gs_wan_e.ps4
-rw-r--r--gs/lib/ht_ccbnm.ps3137
-rwxr-xr-xgs/lib/lp386.bat2
-rwxr-xr-xgs/lib/lp386r2.bat2
-rwxr-xr-xgs/lib/lpgs.bat2
-rwxr-xr-xgs/lib/lpr2.bat2
-rw-r--r--gs/lib/pdf2dsc.ps157
-rw-r--r--gs/lib/pdf_base.ps58
-rw-r--r--gs/lib/pdf_draw.ps280
-rw-r--r--gs/lib/pdf_font.ps2
-rw-r--r--gs/lib/pdf_main.ps77
-rw-r--r--gs/lib/pdf_ops.ps7
-rwxr-xr-xgs/lib/pfbtopfa5
-rw-r--r--gs/lib/pfbtopfa.ps36
-rw-r--r--gs/lib/ps2ai.ps25
-rw-r--r--gs/lib/ps2ascii.ps66
-rwxr-xr-xgs/lib/ps2pdf10
-rw-r--r--gs/lib/t1tot2.ps486
-rw-r--r--gs/lib/test.ps9
-rw-r--r--gs/lib/traceop.ps77
-rw-r--r--gs/lib/type1ops.ps19
-rw-r--r--gs/lib/viewcmyk.ps2
-rw-r--r--gs/lib/viewmiff.ps126
-rw-r--r--gs/lib/viewpbm.ps227
-rw-r--r--gs/lib/viewpcx.ps27
-rw-r--r--gs/lib/writecff.ps367
-rw-r--r--gs/src/ansi2knr.c153
-rw-r--r--gs/src/bcwin32.mak187
-rw-r--r--gs/src/bfont.h12
-rw-r--r--gs/src/btoken.h12
-rwxr-xr-xgs/src/bughunt.sh120
-rw-r--r--gs/src/ccfont.h16
-rw-r--r--gs/src/ccgs14
-rw-r--r--gs/src/cfonts.mak526
-rw-r--r--gs/src/contrib.mak516
-rwxr-xr-xgs/src/cp.bat15
-rw-r--r--gs/src/devs.mak753
-rw-r--r--gs/src/dpmainc.c1
-rw-r--r--gs/src/dstack.h390
-rwxr-xr-xgs/src/dvx-gcc.mak46
-rw-r--r--gs/src/dvx-head.mak13
-rw-r--r--gs/src/dvx-tail.mak20
-rw-r--r--gs/src/dwdll.cpp1
-rw-r--r--gs/src/dwdll.h12
-rw-r--r--gs/src/dwmain.rc15
-rw-r--r--gs/src/dwnodll.cpp1
-rw-r--r--gs/src/echogs.c36
-rw-r--r--gs/src/errors.h12
-rw-r--r--gs/src/estack.h19
-rw-r--r--gs/src/files.h39
-rw-r--r--gs/src/gconf.c86
-rw-r--r--gs/src/gdev3852.c15
-rw-r--r--gs/src/gdevabuf.c18
-rw-r--r--gs/src/gdevalph.c4
-rw-r--r--gs/src/gdevbbox.h2
-rw-r--r--gs/src/gdevbit.c194
-rw-r--r--gs/src/gdevbjcl.c252
-rw-r--r--gs/src/gdevbjcl.h401
-rw-r--r--gs/src/gdevbmp.c95
-rw-r--r--gs/src/gdevbmp.h3
-rw-r--r--gs/src/gdevbmpa.c626
-rw-r--r--gs/src/gdevbmpc.c46
-rw-r--r--gs/src/gdevcd8.c2852
-rw-r--r--gs/src/gdevcdj.c165
-rw-r--r--gs/src/gdevcgm.c4
-rw-r--r--gs/src/gdevclj.c2
-rw-r--r--gs/src/gdevcljc.c3
-rw-r--r--gs/src/gdevcmap.c4
-rw-r--r--gs/src/gdevcmap.h2
-rw-r--r--gs/src/gdevcslw.c149
-rw-r--r--gs/src/gdevdbit.c22
-rw-r--r--gs/src/gdevdcrd.c178
-rw-r--r--gs/src/gdevdcrd.h29
-rw-r--r--gs/src/gdevddrw.c323
-rw-r--r--gs/src/gdevdflt.c59
-rw-r--r--gs/src/gdevdgbr.c580
-rw-r--r--gs/src/gdevdjet.c57
-rw-r--r--gs/src/gdevdrop.c89
-rw-r--r--gs/src/gdevhit.c6
-rw-r--r--gs/src/gdevhl7x.c20
-rw-r--r--gs/src/gdevifno.c14
-rw-r--r--gs/src/gdevjpeg.c4
-rw-r--r--gs/src/gdevl256.c4
-rw-r--r--gs/src/gdevl31s.c280
-rw-r--r--gs/src/gdevlj56.c3
-rw-r--r--gs/src/gdevlxm.c423
-rw-r--r--gs/src/gdevm1.c17
-rw-r--r--gs/src/gdevm2.c64
-rw-r--r--gs/src/gdevm24.c98
-rw-r--r--gs/src/gdevm32.c95
-rw-r--r--gs/src/gdevmeds.c93
-rw-r--r--gs/src/gdevmeds.h29
-rw-r--r--gs/src/gdevmem.c317
-rw-r--r--gs/src/gdevmem.h10
-rw-r--r--gs/src/gdevmgr.c6
-rw-r--r--gs/src/gdevmpla.c632
-rw-r--r--gs/src/gdevmpla.h48
-rw-r--r--gs/src/gdevmr2n.c1
-rw-r--r--gs/src/gdevmr8n.c45
-rw-r--r--gs/src/gdevmrop.c771
-rw-r--r--gs/src/gdevmrop.h8
-rw-r--r--gs/src/gdevmrun.c657
-rw-r--r--gs/src/gdevmrun.h62
-rw-r--r--gs/src/gdevmswn.c101
-rw-r--r--gs/src/gdevmswn.h4
-rw-r--r--gs/src/gdevmsxf.c4
-rw-r--r--gs/src/gdevnfwd.c366
-rw-r--r--gs/src/gdevpbm.c300
-rw-r--r--gs/src/gdevpcfb.c21
-rw-r--r--gs/src/gdevpcl.c151
-rw-r--r--gs/src/gdevpcl.h9
-rw-r--r--gs/src/gdevpcx.c4
-rw-r--r--gs/src/gdevpdf.c28
-rw-r--r--gs/src/gdevpdfd.c232
-rw-r--r--gs/src/gdevpdfi.c339
-rw-r--r--gs/src/gdevpdfm.c57
-rw-r--r--gs/src/gdevpdfo.c10
-rw-r--r--gs/src/gdevpdfp.c9
-rw-r--r--gs/src/gdevpdfx.h14
-rw-r--r--gs/src/gdevplnx.c1106
-rw-r--r--gs/src/gdevplnx.h75
-rw-r--r--gs/src/gdevpm.c57
-rw-r--r--gs/src/gdevpng.c6
-rw-r--r--gs/src/gdevppla.c134
-rw-r--r--gs/src/gdevppla.h51
-rw-r--r--gs/src/gdevprn.c484
-rw-r--r--gs/src/gdevprn.h233
-rw-r--r--gs/src/gdevprna.h20
-rw-r--r--gs/src/gdevps.c326
-rw-r--r--gs/src/gdevpsdf.c35
-rw-r--r--gs/src/gdevpsdf.h12
-rw-r--r--gs/src/gdevpsdi.c60
-rw-r--r--gs/src/gdevpsdp.c154
-rw-r--r--gs/src/gdevpsds.c65
-rw-r--r--gs/src/gdevpsds.h12
-rw-r--r--gs/src/gdevpx.c986
-rw-r--r--gs/src/gdevrops.c10
-rw-r--r--gs/src/gdevrun.c449
-rw-r--r--gs/src/gdevsgi.c4
-rw-r--r--gs/src/gdevsppr.c6
-rw-r--r--gs/src/gdevsunr.c103
-rw-r--r--gs/src/gdevsvga.c42
-rw-r--r--gs/src/gdevsvga.h4
-rw-r--r--gs/src/gdevtfax.c261
-rw-r--r--gs/src/gdevvec.c298
-rw-r--r--gs/src/gdevvec.h43
-rw-r--r--gs/src/gdevvglb.c4
-rw-r--r--gs/src/gdevwdib.c75
-rw-r--r--gs/src/gdevwpr2.c543
-rw-r--r--gs/src/gdevx.c635
-rw-r--r--gs/src/gdevx.h60
-rw-r--r--gs/src/gdevxalt.c81
-rw-r--r--gs/src/gdevxcmp.c806
-rw-r--r--gs/src/gdevxcmp.h124
-rw-r--r--gs/src/gdevxini.c448
-rw-r--r--gs/src/gdevxres.c138
-rw-r--r--gs/src/gdevxxf.c299
-rw-r--r--gs/src/genarch.c185
-rw-r--r--gs/src/genconf.c188
-rw-r--r--gs/src/genht.c333
-rw-r--r--gs/src/geninit.c101
-rw-r--r--gs/src/gp.h40
-rw-r--r--gs/src/gp_gnrdl.c363
-rw-r--r--gs/src/gp_iwatc.c1
-rw-r--r--gs/src/gp_msio.c11
-rw-r--r--gs/src/gp_nsync.c12
-rw-r--r--gs/src/gp_ntfs.c10
-rw-r--r--gs/src/gp_os2.c12
-rw-r--r--gs/src/gp_strdl.c45
-rw-r--r--gs/src/gp_vms.c7
-rw-r--r--gs/src/gp_win32.c196
-rw-r--r--gs/src/gp_wsync.c208
-rw-r--r--gs/src/gpsync.h2
-rw-r--r--gs/src/gs.c8
-rw-r--r--gs/src/gs.mak231
-rw-r--r--gs/src/gs16spl.rc8
-rw-r--r--gs/src/gsalloc.c35
-rw-r--r--gs/src/gsalphac.c8
-rw-r--r--gs/src/gsargs.c8
-rw-r--r--gs/src/gsargs.h9
-rw-r--r--gs/src/gsbitmap.h40
-rw-r--r--gs/src/gsbitops.c228
-rw-r--r--gs/src/gsbitops.h64
-rw-r--r--gs/src/gsbittab.c9
-rw-r--r--gs/src/gsbittab.h6
-rw-r--r--gs/src/gsccode.h9
-rw-r--r--gs/src/gsccolor.h22
-rw-r--r--gs/src/gscdef.c12
-rw-r--r--gs/src/gscdefs.h20
-rw-r--r--gs/src/gscdevn.c135
-rw-r--r--gs/src/gschar.c117
-rw-r--r--gs/src/gschar.h40
-rw-r--r--gs/src/gschar0.c3
-rw-r--r--gs/src/gscie.c5
-rw-r--r--gs/src/gscie.h29
-rw-r--r--gs/src/gsciemap.c4
-rw-r--r--gs/src/gsclipsr.c71
-rw-r--r--gs/src/gscolor.c30
-rw-r--r--gs/src/gscolor1.c27
-rw-r--r--gs/src/gscolor2.c59
-rw-r--r--gs/src/gscolor2.h14
-rw-r--r--gs/src/gscolor3.c20
-rw-r--r--gs/src/gscparam.c19
-rw-r--r--gs/src/gscpm.h10
-rw-r--r--gs/src/gscrd.c2
-rw-r--r--gs/src/gscrd.h1
-rw-r--r--gs/src/gscrdp.c3
-rw-r--r--gs/src/gscrdp.h1
-rw-r--r--gs/src/gscscie.c4
-rw-r--r--gs/src/gscsepr.c10
-rw-r--r--gs/src/gscsepr.h24
-rw-r--r--gs/src/gscspace.c34
-rw-r--r--gs/src/gscspace.h22
-rw-r--r--gs/src/gscssub.c114
-rw-r--r--gs/src/gscssub.h73
-rw-r--r--gs/src/gsdcolor.h36
-rw-r--r--gs/src/gsdevice.c151
-rw-r--r--gs/src/gsdevice.h20
-rw-r--r--gs/src/gsdll.c32
-rw-r--r--gs/src/gsdll.h37
-rw-r--r--gs/src/gsdll16.def20
-rw-r--r--gs/src/gsdll16.rc26
-rw-r--r--gs/src/gsdll32.rc32
-rw-r--r--gs/src/gsdllos2.h33
-rw-r--r--gs/src/gsdllwin.h46
-rw-r--r--gs/src/gsdparam.c250
-rw-r--r--gs/src/gsfcmap.c19
-rw-r--r--gs/src/gsfcmap.h17
-rw-r--r--gs/src/gsflip.c234
-rw-r--r--gs/src/gsflip.h20
-rw-r--r--gs/src/gsfont.c4
-rw-r--r--gs/src/gsfunc.c17
-rw-r--r--gs/src/gsfunc0.c10
-rw-r--r--gs/src/gsfunc3.c37
-rw-r--r--gs/src/gsgc.h52
-rw-r--r--gs/src/gsht.c161
-rw-r--r--gs/src/gsht1.c195
-rw-r--r--gs/src/gshtscr.c33
-rw-r--r--gs/src/gshtx.c28
-rw-r--r--gs/src/gshtx.h6
-rw-r--r--gs/src/gsimage.c312
-rw-r--r--gs/src/gsimage.h19
-rw-r--r--gs/src/gsio.h7
-rw-r--r--gs/src/gsiodev.c9
-rw-r--r--gs/src/gsiparam.h44
-rw-r--r--gs/src/gsiparm4.h4
-rw-r--r--gs/src/gsistate.c266
-rw-r--r--gs/src/gsjconf.h6
-rw-r--r--gs/src/gslib.c35
-rw-r--r--gs/src/gsline.c2
-rw-r--r--gs/src/gsline.h13
-rw-r--r--gs/src/gsmalloc.c45
-rw-r--r--gs/src/gsmalloc.h2
-rw-r--r--gs/src/gsmatrix.c40
-rw-r--r--gs/src/gsmemlok.c18
-rw-r--r--gs/src/gsmemlok.h2
-rw-r--r--gs/src/gsmemory.c92
-rw-r--r--gs/src/gsmemory.h11
-rw-r--r--gs/src/gsmemraw.h10
-rw-r--r--gs/src/gsmemret.c332
-rw-r--r--gs/src/gsmemret.h72
-rw-r--r--gs/src/gsmisc.c249
-rw-r--r--gs/src/gsnogc.c98
-rw-r--r--gs/src/gsnogc.h30
-rw-r--r--gs/src/gspaint.c61
-rw-r--r--gs/src/gsparam.h15
-rw-r--r--gs/src/gsparams.c104
-rw-r--r--gs/src/gsparamx.c100
-rw-r--r--gs/src/gsparamx.h39
-rw-r--r--gs/src/gspath.c22
-rw-r--r--gs/src/gspath.h15
-rw-r--r--gs/src/gspath1.c232
-rw-r--r--gs/src/gspcolor.c759
-rw-r--r--gs/src/gspcolor.h76
-rw-r--r--gs/src/gsptype1.c817
-rw-r--r--gs/src/gsptype1.h64
-rw-r--r--gs/src/gsptype2.c181
-rw-r--r--gs/src/gsptype2.h35
-rw-r--r--gs/src/gsrect.h22
-rw-r--r--gs/src/gsrefct.h87
-rw-r--r--gs/src/gsropc.c4
-rw-r--r--gs/src/gsropt.h13
-rw-r--r--gs/src/gsshade.c149
-rw-r--r--gs/src/gsshade.h18
-rw-r--r--gs/src/gsstate.c327
-rw-r--r--gs/src/gsstruct.h151
-rw-r--r--gs/src/gsstype.h108
-rw-r--r--gs/src/gstext.c45
-rw-r--r--gs/src/gstext.h179
-rw-r--r--gs/src/gstrap.c115
-rw-r--r--gs/src/gstype1.c21
-rw-r--r--gs/src/gstype1.h17
-rw-r--r--gs/src/gstype2.c13
-rw-r--r--gs/src/gstype42.c376
-rw-r--r--gs/src/gstypes.h36
-rw-r--r--gs/src/gx.h2
-rw-r--r--gs/src/gxacpath.c153
-rw-r--r--gs/src/gxalloc.h33
-rw-r--r--gs/src/gxarith.h13
-rw-r--r--gs/src/gxband.h28
-rw-r--r--gs/src/gxbitfmt.h36
-rw-r--r--gs/src/gxbitmap.h25
-rw-r--r--gs/src/gxccman.c43
-rw-r--r--gs/src/gxcdevn.h51
-rw-r--r--gs/src/gxchar.h32
-rw-r--r--gs/src/gxcht.c667
-rw-r--r--gs/src/gxcindex.h94
-rw-r--r--gs/src/gxclbits.c23
-rw-r--r--gs/src/gxcldev.h33
-rw-r--r--gs/src/gxclimag.c364
-rw-r--r--gs/src/gxclip.c369
-rw-r--r--gs/src/gxclip.h17
-rw-r--r--gs/src/gxclip2.h12
-rw-r--r--gs/src/gxclipsr.h54
-rw-r--r--gs/src/gxclist.c185
-rw-r--r--gs/src/gxclist.h51
-rw-r--r--gs/src/gxclmem.c31
-rw-r--r--gs/src/gxclpath.c106
-rw-r--r--gs/src/gxclpath.h75
-rw-r--r--gs/src/gxclrast.c621
-rw-r--r--gs/src/gxclread.c422
-rw-r--r--gs/src/gxclrect.c46
-rw-r--r--gs/src/gxcmap.c34
-rw-r--r--gs/src/gxcmap.h48
-rw-r--r--gs/src/gxcolor2.h39
-rw-r--r--gs/src/gxcpath.c201
-rw-r--r--gs/src/gxcpath.h25
-rw-r--r--gs/src/gxcspace.h12
-rw-r--r--gs/src/gxctable.c61
-rw-r--r--gs/src/gxctable.h4
-rw-r--r--gs/src/gxdcconv.c17
-rw-r--r--gs/src/gxdcolor.c24
-rw-r--r--gs/src/gxdcolor.h4
-rw-r--r--gs/src/gxdevbuf.h119
-rw-r--r--gs/src/gxdevcli.h159
-rw-r--r--gs/src/gxdevice.h95
-rw-r--r--gs/src/gxdevmem.h126
-rw-r--r--gs/src/gxdht.h75
-rw-r--r--gs/src/gxdhtres.h44
-rw-r--r--gs/src/gxdither.c56
-rw-r--r--gs/src/gxdither.h16
-rw-r--r--gs/src/gxfcache.h4
-rw-r--r--gs/src/gxfcmap.h28
-rw-r--r--gs/src/gxfixed.h67
-rw-r--r--gs/src/gxfmap.h9
-rw-r--r--gs/src/gxfont.h2
-rw-r--r--gs/src/gxfont1.h54
-rw-r--r--gs/src/gxftype.h2
-rw-r--r--gs/src/gxfunc.h5
-rw-r--r--gs/src/gxgetbit.h4
-rw-r--r--gs/src/gxht.c128
-rw-r--r--gs/src/gxht.h25
-rw-r--r--gs/src/gxhtbit.c243
-rw-r--r--gs/src/gxhttype.h10
-rw-r--r--gs/src/gxi12bit.c90
-rw-r--r--gs/src/gxiclass.h62
-rw-r--r--gs/src/gxicolor.c192
-rw-r--r--gs/src/gxidata.c123
-rw-r--r--gs/src/gxifast.c32
-rw-r--r--gs/src/gxiinit.c915
-rw-r--r--gs/src/gximage.c117
-rw-r--r--gs/src/gximage.h89
-rw-r--r--gs/src/gximage1.c9
-rw-r--r--gs/src/gximage2.c6
-rw-r--r--gs/src/gximage3.c274
-rw-r--r--gs/src/gximage4.c13
-rw-r--r--gs/src/gximono.c27
-rw-r--r--gs/src/gxino12b.c (renamed from gs/src/spcxx.h)16
-rw-r--r--gs/src/gxiparam.h60
-rw-r--r--gs/src/gxipixel.c137
-rw-r--r--gs/src/gxiscale.c125
-rw-r--r--gs/src/gxistate.h73
-rw-r--r--gs/src/gxmclip.c4
-rw-r--r--gs/src/gxmclip.h6
-rw-r--r--gs/src/gxobj.h22
-rw-r--r--gs/src/gxp1fill.c34
-rw-r--r--gs/src/gxpageq.c1
-rw-r--r--gs/src/gxpageq.h4
-rw-r--r--gs/src/gxpaint.c16
-rw-r--r--gs/src/gxpaint.h24
-rw-r--r--gs/src/gxpath.c27
-rw-r--r--gs/src/gxpath.h61
-rw-r--r--gs/src/gxpath2.c97
-rw-r--r--gs/src/gxpcmap.c111
-rw-r--r--gs/src/gxpcolor.h102
-rw-r--r--gs/src/gxpcopy.c55
-rw-r--r--gs/src/gxrplane.h51
-rw-r--r--gs/src/gxsample.c63
-rw-r--r--gs/src/gxsample.h22
-rw-r--r--gs/src/gxshade.c4
-rw-r--r--gs/src/gxshade.h37
-rw-r--r--gs/src/gxshade1.c688
-rw-r--r--gs/src/gxshade4.c265
-rw-r--r--gs/src/gxshade4.h22
-rw-r--r--gs/src/gxshade6.c22
-rw-r--r--gs/src/gxstroke.c209
-rw-r--r--gs/src/gxsync.h34
-rw-r--r--gs/src/gxtext.h108
-rw-r--r--gs/src/gxtype1.c58
-rw-r--r--gs/src/gxtype1.h9
-rw-r--r--gs/src/gxxfont.h4
-rw-r--r--gs/src/gzcpath.h4
-rw-r--r--gs/src/gzline.h10
-rw-r--r--gs/src/gzpath.h2
-rw-r--r--gs/src/gzstate.h36
-rw-r--r--gs/src/ialloc.c31
-rw-r--r--gs/src/ialloc.h14
-rw-r--r--gs/src/ibnum.c12
-rw-r--r--gs/src/iccfont.c2
-rw-r--r--gs/src/icfontab.c17
-rw-r--r--gs/src/ichar.h17
-rw-r--r--gs/src/ichar1.h29
-rw-r--r--gs/src/icharout.h10
-rw-r--r--gs/src/icie.h50
-rw-r--r--gs/src/icolor.h28
-rw-r--r--gs/src/iconf.c24
-rw-r--r--gs/src/icontext.c160
-rw-r--r--gs/src/icontext.h9
-rw-r--r--gs/src/icremap.h45
-rw-r--r--gs/src/icsmap.h13
-rw-r--r--gs/src/icstate.h26
-rw-r--r--gs/src/iddict.h48
-rw-r--r--gs/src/iddstack.h40
-rw-r--r--gs/src/idebug.c76
-rw-r--r--gs/src/idebug.h7
-rw-r--r--gs/src/idict.c133
-rw-r--r--gs/src/idict.h33
-rw-r--r--gs/src/idparam.c2
-rw-r--r--gs/src/idparam.h8
-rw-r--r--gs/src/idsdata.h86
-rw-r--r--gs/src/idstack.c46
-rw-r--r--gs/src/idstack.h60
-rw-r--r--gs/src/iesdata.h55
-rw-r--r--gs/src/iestack.h31
-rw-r--r--gs/src/ifilter.h23
-rw-r--r--gs/src/ifont.h6
-rw-r--r--gs/src/ifont1.h53
-rw-r--r--gs/src/ifunc.h15
-rw-r--r--gs/src/igc.c65
-rw-r--r--gs/src/igc.h18
-rw-r--r--gs/src/igcref.c72
-rw-r--r--gs/src/igcstr.c4
-rw-r--r--gs/src/igstate.h64
-rw-r--r--gs/src/iht.h4
-rw-r--r--gs/src/iimage.h13
-rw-r--r--gs/src/iimage2.h11
-rw-r--r--gs/src/iinit.c141
-rw-r--r--gs/src/ilevel.h6
-rw-r--r--gs/src/ilocate.c18
-rw-r--r--gs/src/imain.c106
-rw-r--r--gs/src/imain.h13
-rw-r--r--gs/src/imainarg.c59
-rw-r--r--gs/src/imemory.h8
-rw-r--r--gs/src/iminst.h15
-rw-r--r--gs/src/iname.c22
-rw-r--r--gs/src/inamedef.h24
-rw-r--r--gs/src/inames.h10
-rw-r--r--gs/src/inobtokn.c31
-rw-r--r--gs/src/inouparm.c4
-rw-r--r--gs/src/int.mak1186
-rw-r--r--gs/src/interp.c553
-rw-r--r--gs/src/interp.h24
-rw-r--r--gs/src/iosdata.h40
-rw-r--r--gs/src/iostack.h11
-rw-r--r--gs/src/ipacked.h8
-rw-r--r--gs/src/iparam.c49
-rw-r--r--gs/src/iparam.h8
-rw-r--r--gs/src/iparray.h4
-rw-r--r--gs/src/ipcolor.h41
-rw-r--r--gs/src/ireclaim.c53
-rw-r--r--gs/src/iref.h57
-rw-r--r--gs/src/isave.c86
-rw-r--r--gs/src/iscan.c45
-rw-r--r--gs/src/iscan.h12
-rw-r--r--gs/src/iscanbin.c46
-rw-r--r--gs/src/iscannum.c18
-rw-r--r--gs/src/isdata.h102
-rw-r--r--gs/src/istack.c269
-rw-r--r--gs/src/istack.h200
-rw-r--r--gs/src/istream.h10
-rw-r--r--gs/src/istruct.h2
-rw-r--r--gs/src/iutil.c416
-rw-r--r--gs/src/iutil.h41
-rw-r--r--gs/src/jerror_.h26
-rw-r--r--gs/src/jpeg.mak178
-rw-r--r--gs/src/libpng.mak90
-rw-r--r--gs/src/main.h14
-rw-r--r--gs/src/md5.c388
-rw-r--r--gs/src/md5.h79
-rw-r--r--gs/src/memory_.h52
-rw-r--r--gs/src/msvc32.mak176
-rw-r--r--gs/src/msvccmd.mak6
-rw-r--r--gs/src/msvclib.mak51
-rw-r--r--gs/src/msvctail.mak21
-rwxr-xr-xgs/src/mv.bat2
-rw-r--r--gs/src/opdef.h50
-rw-r--r--gs/src/openvms.mak234
-rw-r--r--gs/src/openvms.mmk488
-rw-r--r--gs/src/oper.h9
-rw-r--r--gs/src/opextern.h102
-rw-r--r--gs/src/os2.mak92
-rw-r--r--gs/src/ostack.h9
-rw-r--r--gs/src/pcwin.mak36
-rw-r--r--gs/src/png_.h26
-rwxr-xr-xgs/src/rm.bat (renamed from gs/lib/rm.bat)1
-rw-r--r--gs/src/sa85d.c157
-rw-r--r--gs/src/sa85d.h42
-rw-r--r--gs/src/sa85x.h33
-rw-r--r--gs/src/scfd.c27
-rw-r--r--gs/src/scfe.c4
-rw-r--r--gs/src/scommon.h8
-rw-r--r--gs/src/sdcparam.c5
-rw-r--r--gs/src/sdctc.c4
-rw-r--r--gs/src/sdctd.c6
-rw-r--r--gs/src/sdcte.c6
-rw-r--r--gs/src/sddparam.c4
-rw-r--r--gs/src/sdeparam.c4
-rw-r--r--gs/src/seexec.c14
-rw-r--r--gs/src/sfilter1.c24
-rw-r--r--gs/src/sfilter2.c154
-rw-r--r--gs/src/sfxfd.c20
-rw-r--r--gs/src/siinterp.c261
-rw-r--r--gs/src/siinterp.h30
-rw-r--r--gs/src/siscale.c158
-rw-r--r--gs/src/siscale.h117
-rw-r--r--gs/src/sisparam.h75
-rw-r--r--gs/src/sjpegc.c96
-rw-r--r--gs/src/sjpegd.c6
-rw-r--r--gs/src/sjpege.c6
-rw-r--r--gs/src/sjpegerr.c82
-rw-r--r--gs/src/spcxd.c69
-rw-r--r--gs/src/spdiff.c427
-rw-r--r--gs/src/spdiffx.h12
-rw-r--r--gs/src/spngp.c90
-rw-r--r--gs/src/srdline.h50
-rw-r--r--gs/src/sstring.c4
-rw-r--r--gs/src/sstring.h5
-rw-r--r--gs/src/stat_.h20
-rw-r--r--gs/src/std.h87
-rw-r--r--gs/src/stdpre.h95
-rw-r--r--gs/src/store.h7
-rw-r--r--gs/src/stream.c172
-rw-r--r--gs/src/stream.h17
-rw-r--r--gs/src/string_.h6
-rw-r--r--gs/src/t29
-rw-r--r--gs/src/ugcclib.mak82
-rw-r--r--gs/src/unix-aux.mak (renamed from gs/src/unixtail.mak)103
-rw-r--r--gs/src/unix-end.mak23
-rwxr-xr-xgs/src/unix-gcc.mak119
-rwxr-xr-xgs/src/unixansi.mak96
-rw-r--r--gs/src/unixhead.mak35
-rw-r--r--gs/src/unixinst.mak40
-rw-r--r--gs/src/unixlink.mak77
-rw-r--r--[-rwxr-xr-x]gs/src/unixtrad.mak (renamed from gs/src/unix-cc.mak)119
-rw-r--r--gs/src/version.mak12
-rw-r--r--gs/src/watc.mak120
-rw-r--r--gs/src/watclib.mak107
-rw-r--r--gs/src/watcw32.mak59
-rw-r--r--gs/src/wccommon.mak87
-rw-r--r--gs/src/wctail.mak49
-rw-r--r--gs/src/windows_.h10
-rw-r--r--gs/src/winint.mak51
-rw-r--r--gs/src/winlib.mak44
-rw-r--r--gs/src/winplat.mak51
-rw-r--r--gs/src/x_.h5
-rw-r--r--gs/src/zarith.c49
-rw-r--r--gs/src/zarray.c11
-rw-r--r--gs/src/zbfont.c551
-rw-r--r--gs/src/zbseq.c42
-rw-r--r--gs/src/zcfont.c29
-rw-r--r--gs/src/zchar.c203
-rw-r--r--gs/src/zchar1.c240
-rw-r--r--gs/src/zchar2.c201
-rw-r--r--gs/src/zchar32.c15
-rw-r--r--gs/src/zchar42.c31
-rw-r--r--gs/src/zcharout.c31
-rw-r--r--gs/src/zcharx.c224
-rw-r--r--gs/src/zcid.c26
-rw-r--r--gs/src/zcie.c411
-rw-r--r--gs/src/zcolor.c64
-rw-r--r--gs/src/zcolor1.c76
-rw-r--r--gs/src/zcolor2.c57
-rw-r--r--gs/src/zcontext.c182
-rw-r--r--gs/src/zcontrol.c207
-rw-r--r--gs/src/zcrd.c66
-rw-r--r--gs/src/zcsdevn.c178
-rw-r--r--gs/src/zcsindex.c78
-rw-r--r--gs/src/zcspixel.c5
-rw-r--r--gs/src/zcssepr.c34
-rw-r--r--gs/src/zdevice.c109
-rw-r--r--gs/src/zdevice2.c86
-rw-r--r--gs/src/zdict.c110
-rw-r--r--gs/src/zdosio.c26
-rw-r--r--gs/src/zdouble.c179
-rw-r--r--gs/src/zdpnext.c65
-rw-r--r--gs/src/zdps.c32
-rw-r--r--gs/src/zdps1.c45
-rw-r--r--gs/src/zfbcp.c18
-rw-r--r--gs/src/zfcmap.c168
-rw-r--r--gs/src/zfdctd.c9
-rw-r--r--gs/src/zfdcte.c12
-rw-r--r--gs/src/zfdecode.c70
-rw-r--r--gs/src/zfile.c137
-rw-r--r--gs/src/zfileio.c365
-rw-r--r--gs/src/zfilter.c55
-rw-r--r--gs/src/zfilter2.c25
-rw-r--r--gs/src/zfilterx.c49
-rw-r--r--gs/src/zfname.c4
-rw-r--r--gs/src/zfont.c71
-rw-r--r--gs/src/zfont0.c33
-rw-r--r--gs/src/zfont1.c208
-rw-r--r--gs/src/zfont2.c550
-rw-r--r--gs/src/zfont32.c10
-rw-r--r--gs/src/zfont42.c15
-rw-r--r--gs/src/zfproc.c27
-rw-r--r--gs/src/zfreuse.c62
-rw-r--r--gs/src/zfunc.c44
-rw-r--r--gs/src/zfunc0.c22
-rw-r--r--gs/src/zfunc3.c30
-rw-r--r--gs/src/zfzlib.c22
-rw-r--r--gs/src/zgeneric.c138
-rw-r--r--gs/src/zgstate.c136
-rw-r--r--gs/src/zhsb.c8
-rw-r--r--gs/src/zht.c49
-rw-r--r--gs/src/zht1.c19
-rw-r--r--gs/src/zht2.c134
-rw-r--r--gs/src/zimage.c365
-rw-r--r--gs/src/zimage2.c28
-rw-r--r--gs/src/zimage3.c22
-rw-r--r--gs/src/ziodev.c146
-rw-r--r--gs/src/ziodev2.c6
-rw-r--r--gs/src/zlib.mak54
-rw-r--r--gs/src/zmath.c53
-rw-r--r--gs/src/zmatrix.c55
-rw-r--r--gs/src/zmedia2.c8
-rw-r--r--gs/src/zmisc.c58
-rw-r--r--gs/src/zmisc1.c25
-rw-r--r--gs/src/zmisc2.c106
-rw-r--r--gs/src/zmisc3.c33
-rw-r--r--gs/src/zpacked.c22
-rw-r--r--gs/src/zpaint.c13
-rw-r--r--gs/src/zpath.c74
-rw-r--r--gs/src/zpath1.c69
-rw-r--r--gs/src/zpcolor.c86
-rw-r--r--gs/src/zrelbit.c61
-rw-r--r--gs/src/zrop.c25
-rw-r--r--gs/src/zshade.c77
-rw-r--r--gs/src/zstack.c34
-rw-r--r--gs/src/zstring.c37
-rw-r--r--gs/src/zsysvm.c58
-rw-r--r--gs/src/ztoken.c49
-rw-r--r--gs/src/ztrap.c7
-rw-r--r--gs/src/ztype.c122
-rw-r--r--gs/src/zupath.c141
-rw-r--r--gs/src/zusparam.c148
-rw-r--r--gs/src/zvmem.c32
-rw-r--r--gs/src/zvmem2.c21
693 files changed, 49200 insertions, 23836 deletions
diff --git a/gs/examples/alphabet.ps b/gs/examples/alphabet.ps
new file mode 100644
index 000000000..80dc25e8a
--- /dev/null
+++ b/gs/examples/alphabet.ps
@@ -0,0 +1,56 @@
+% Check for command line parameters:
+% Name, FirstSize, Ratio, NumSizes, UseOutline.
+
+/FontName where { pop } { /FontName (Palatino-Italic) def } ifelse
+/FirstSize where { pop } { /FirstSize 15 def } ifelse
+/Ratio where { pop } { /Ratio 1.6 def } ifelse
+/NumSizes where { pop } { /NumSizes 3 def } ifelse
+/UseOutline where { pop } { /UseOutline false def } ifelse
+
+/Strings FirstSize 20 gt
+ { [
+ (ABCDEFGHIJ) (KLMNOPQR) (STUVWXYZ)
+ (abcdefghijklm) (nopqrstuvwxyz)
+ (0123456789<=>) (:;?@ !"#$%&')
+ (\(\)*+,-./[\\]^_) (`{|}~)
+ ] }
+ { [
+ (ABCDEFGHIJKLMNOPQRSTUVWXYZ)
+ (abcdefghijklmnopqrstuvwxyz)
+ (0123456789<=>:;?@ !"#$%&')
+ (\(\)*+,-./ [\\]^_ `{|}~)
+ ] }
+ifelse def
+
+/sshow
+ { gsave UseOutline
+ { { gsave ( ) dup 0 4 -1 roll put
+ false charpath pathbbox 0 setlinewidth stroke grestore
+ pop 8 add currentpoint exch pop moveto pop
+ } forall
+ }
+ { 2 0 3 -1 roll ashow }
+ ifelse grestore
+ } def
+
+FontName findfont FirstSize scalefont setfont
+
+clippath pathbbox /top exch def pop pop pop newpath
+10 10 moveto
+NumSizes
+ { gsave nulldevice (Q) false charpath pathbbox grestore
+ exch pop exch sub exch pop 1.25 mul /height exch def
+ Strings
+ { currentpoint exch pop top height 3 mul sub gt
+ { showpage 10 10 height sub moveto
+ }
+ if
+ dup sshow
+ UseOutline not
+ { 0 height rmoveto gsave 0.01 rotate sshow grestore }
+ if
+ 0 height rmoveto
+ } forall
+ Ratio dup scale
+ } repeat
+showpage
diff --git a/gs/examples/cheq.ps b/gs/examples/cheq.ps
new file mode 100644
index 000000000..2e98d0edd
--- /dev/null
+++ b/gs/examples/cheq.ps
@@ -0,0 +1,945 @@
+%!PS-AdobeFont-1.0: Cheq 001.000
+%%CreationDate: Wed May 24 10:41:05 1989
+%%VMusage: 23317 29750
+%% Adobe is licensing this font software "Cheq" to you royalty-free for your
+%% use and not for sale to others. This font software is provided as is and
+%% Adobe disclaims all warranties, including merchantability and fitness for
+%% a particular purpose. Any and all copies of this software must contain
+%% this notice intact. Design (D) 1989 John S. Renner, Adobe Systems,
+%% Inc.
+11 dict begin
+/FontInfo 10 dict dup begin
+/version (001.000) readonly def
+/Notice (Copyright (c) 1989 Adobe Systems Incorporated. All rights reserved.) readonly def
+/Copyright ( Adobe is licensing this font software "Cheq" to you
+ royalty-free for your use and not for sale to others. This
+ font software is provided as is and Adobe disclaims all
+ warranties, including merchantability and fitness for a
+ particular purpose.
+ Any and all copies of this software must contain this notice
+ intact.
+
+ Design (D) 1989 John S. Renner, Adobe Systems, Inc.
+ ) readonly def
+/FullName (Cheq) readonly def
+/FamilyName (Cheq) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /Cheq def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+ %% Encoding below refers to Macintosh keyboard.
+ %% You may want to re-encode for your needs.
+ %% some entries are an attempt to accommodate
+ %% the German/Russian spelling mnemonics,
+ %% except for "B" which remains for Bishop,
+ %% and not for Bauer (the pawn).
+dup 120 /BSquare put % x
+dup 32 /space put % space
+dup 66 /BBishop put % shift-b
+dup 68 /BQueen put % shift-d
+dup 75 /BKing put % shift-k
+dup 76 /BBishop put % shift-l
+dup 78 /BKnight put % shift-n
+dup 80 /BPawn put % shift-p
+dup 81 /BQueen put % shift-q
+dup 82 /BRook put % shift-r
+dup 83 /BKnight put % shift-s
+dup 84 /BRook put % shift-t
+dup 98 /WBishop put % b
+dup 100 /WQueen put % d
+dup 107 /WKing put % k
+dup 108 /WBishop put % l
+dup 110 /WKnight put % n
+dup 112 /WPawn put % p
+dup 113 /WQueen put % q
+dup 114 /WRook put % r
+dup 115 /WKnight put % s
+dup 116 /WRook put % t
+dup 245 /BBishopOnBlack put % shift-option-b
+dup 235 /BQueenOnBlack put % shift-option-d
+dup 240 /BKingOnBlack put % shift-option-k
+dup 241 /BBishopOnBlack put % shift-option-l
+dup 246 /BKnightOnBlack put % shift-option-n
+dup 184 /BPawnOnBlack put % shift-option-p
+dup 206 /BQueenOnBlack put % shift-option-q
+dup 229 /BRookOnBlack put % shift-option-r
+dup 234 /BKnightOnBlack put % shift-option-s
+dup 230 /BRookOnBlack put % shift-option-t
+dup 186 /WBishopOnBlack put % option-b
+dup 182 /WQueenOnBlack put % option-d
+dup 251 /WKingOnBlack put % option-k
+dup 194 /WBishopOnBlack put % option-l
+dup 181 /WKnightOnBlack put % option-m
+dup 185 /WPawnOnBlack put % option-p
+dup 207 /WQueenOnBlack put % option-q
+dup 168 /WRookOnBlack put % option-r
+dup 167 /WKnightOnBlack put % option-s
+dup 160 /WRookOnBlack put % option-t
+dup 47 /left put % slash
+dup 92 /right put % backslash
+dup 95 /top put % underscore
+dup 45 /bottom put % hyphen/minus
+def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/UniqueID 23368 def
+/FontBBox{-50 -150 1050 950}readonly def
+currentdict end
+currentfile eexec
+06ba7b33fcf5ae0f0b258ced9b9688e8a87f93db8efdacd17ec2401f2e7dac03
+bf5515b9e42d78a8037b743d280529fc7630d62bd4c75492c78fd28b2c2aba67
+9cc93d471b097ea30e29f7c89735dd88b4c3e9cb32e14ef50432a6ab37870a14
+af81e471af496fa0e292e1e8168461acf6191017048deb62dd5fd7c784ba88aa
+a921563b3143218981a38441910687a3202a5135e58ce2ecdf9c2d521c6df45b
+aab245f99427574c148904e2a60104e97e6b05bfd9be9a086246a797a03dab25
+948bf8e7996f70ffd6471eef9faeada641e245d63c4964a38500b4754836131f
+86fc61b1de2e0b53ad441b1446fedcd2c533d44c69631a545c98d4c552e5f0b2
+27b40aa0443f7f88e1d6e5bd206ed737fffbe94e8bf001e3481cca5a45735979
+e41ea918a7c0ca5e26ab946df29d27b5ec2671d8e0d7d31b114c29e48ccd3e8d
+7bc69903aeb804fc25aa2dda700de6ede9fc025f0db1aa478b53fa21ed455ec1
+98c7a20020a077a67b743f563cc4c4e59c2d8253bc8c3ea62d4a870f53b2515c
+8b63b857664ab5f0ad71eb89d34decf825e81c10c3a7e676ddddd182cd6ff6da
+631d2051ccb078bea7b2ffab7dc23ca08b337ecc454a8f743a71512149244b00
+72670c8978396cefa735113500de6cec50ab91084340db0ba24a01672dc3a3a5
+e860df42ef02350778cb8e77b5533227aa2f79cbed414f760d92cd071fb5db1b
+669ef0196c6e95a530c8112a8a3ac716fb913a8a1332a590b46d2e267b97b1be
+0e0ba7e4e8c90f1d37b8c1836fbdc93121c5758a31d3ef4650adc41f253ba07a
+ab0dc45d90e8936672b1a47307903dbcbf8e15b70c862d25c57c6e2727f6674b
+c47ff5eae01e0fe7d182742ac456f986d0eb460f4f7fc2693e37899a04b3684e
+fd57e9b235b339017c36b1ef22f9659a0c7743e663e831be7faa602cff221701
+85b13653ad5269a88da74ed803beb08bc40f0bfcfd7cbc49531756b41171c22d
+aae8ff9a454f9d68df7f4b23409634346d8e26ac2109391398ed37705e2e063a
+065a871b78b2b0d4c74b6e4e42877a4450b1974474dc19437e9e1d8a6ff2a374
+0e399857e4f67056577a19f7e26542fae9a75f1e07ed1869c504625d701fdbea
+392b4b2e83ea3c179991f5dded833a74df4d277fdd119f69e8209be9394473f3
+6d6383a762a518d04812f29ec4bb71f451882e9f89a52114215b31b225db3da5
+eb453e7f4f40861963d6412855582128dcd1677d94df95442aba41d3cdf32f0c
+f1a6eace61e491f64152a57410902642145aca0104350bd8b19441072da5e142
+758ef9a1f6c6e0fe47335113843443a07c68606510af206677e764dc0e319ff0
+93d0fef01274205b370422182765a40ac3d23f4c326a732282c455a0eb737ac4
+11673164b7b35e42cb4be5dd4be49958b2c61a5bcc5a332b917d5525c0680a14
+b7c700339112eb47015e80cadfd5a6484af9201f57f6e15b70c0964ea5365173
+ba78aec0d5a7414a4636090b9eef9d71fa424c47fb191bfaeea8d1d29beebbe2
+fc78ea4a1edb5c325bba25851e72146eab86a69e57b6a4a31bc7a4cad9f8910d
+3394c3a92e5189b3447df2fc1a5add98fb8e4ad616685beb6778fe7d444b5ef3
+f4847419c0013e6689e40860aaf46d77f172b86be22630674ac7d37354098a7b
+08add07f1c48dc3dfd56716c3e126f674690d504fc771beaf5e12e9a32f2a17b
+1f753b50c16bb45e2db812bb8e179f1641147da41ac30d08238141315c211f57
+fe8f9c86a087208ebd350f3d1381187a19850d4c2dc0428889c7776047f69574
+4ac1f676453ea360e0d5b18fdf2b2ac8f9e72369e221f447f0eb55bc80460149
+9e5e501c359e1656ab1bc4699569566ba8bee1463746ca84c51ce83cc98adcde
+48f109d71339d0293ed3104a84287b15c3fc4ae425754f5fd66bec0c9f6e27b6
+ea6dbfdbdbdb3c3aaf935969d635a71a61fb4bd8a8384571c4671c98da20d1fd
+accbcdcdd1cca1f44bdd6ea4827ebcf41ea97147921d6894eff290d1bda74208
+38e9c0453e9f9e6d522dcc5667c1b44f57d60be5239c5e58f4b1e16672608a3f
+68f1b7c3d11f609ed4fe10ab359a5b5a7a9da15b44273fd38c303dad6832ace0
+81e7e85a836e4bd7e9f9149276be282442ae3ce0fa74d29a9b4e56a99aa06f2a
+be39c7f4755745f07d29f9a4522a1a43f11f60c31538ea1a37ca793376ecdb2f
+9dee32abb3fb035ad68e1b24d97ac3004508b514f33b86b6e19ab578c1a891ec
+6a2e2f9cb6f784f2c1372978706102bd273bb721cddb3fa2659ff4485119cc94
+2e140051600bb66d0ae6db27205fc9c9e1c6f07a4eb6cda7adec4d86bfbf0748
+45dd09d9178745f790ef5f5679840deff1cc38810e49066d41743db0b6a087bc
+93307d009dd566c4cc13ed3b634b7f60fd6a7e9fb2774eda2b106d2960dfe979
+c76d0fe4689ce8f4490c76c1064861624d909d678379f9602c2b9df3b0f9abcf
+dab614aec38e22bf064950094d9201c6afa52cc5fc7779b279ef41231546f13d
+f1ef498eae5c445f7691f96ebabef21e7f2d1ee2eedd9846c20b067a73aa2159
+a116bd056e733b00a847a9dcc82ce288f3037b76be87412ab5c0f86dc3959ab5
+85223a2465a11d0bc9b5d93805c5e4466081109f175fae62f82c5012ef4a2c7c
+23ff8004c8704103f0dc1589270f8282f9d5a0f51408379ace784d0af862b548
+1c11650e865e17af7e04df20a4049295e93d32f22c1cc3c39a8626fa343d1f18
+a3495bc7dcab911cff66d60d29e1b45a7f16a477b83cf18c523c288c91adc74f
+e6b3a91445a68313118abd7bd8a0a1ce9290f868f583a3ff80db71381eeb2de8
+e80b4d8d2cf70bcdafc08788ba8cd6cb2b6fd739ef809c3cb2ad1ded30e14240
+a7db077e83d18c867e22ba60a57ee2d825c2f7c8b9054d09d6049255a30c67d7
+3d01bca101e4e93d2e82e14a86f331b501736cdcac5f562d16f190aeecb5fe39
+7b434555d2b8a2bd4d363cdd4a19e69c6bf2e7856e3c9214b0931d392ae644b9
+bec489e739e7e091e0dea23212e398e9ae3194d52f42afb75079a63f9c39f205
+73acb5dc43426f3657575930d5c2a053f7fd5b43f2d011ad74070c1ebdd52aa9
+70961253b0715079e17a8339f7d48c9821bad9b4ea2ea0e03e19fefca01f36c8
+bb91586e2ded2b2fd7512bc9e6787340d78d6d308e8fcafc751707f243fb30f2
+5479cf7e89801c62ba25ff7548892e1e224878aeb4cb1f05287cb7febe450986
+5d8f2f6469bba902a8f7f0892a954d7ab83e600ceb2dc127239d570428fe9008
+ba45c4f6b1734a4019122ccea228571be3dee9302bbb7aff9f4ff06290422f91
+97f61416b4b19c2cf8225cb54dd3e8090c74abbe1080301cf19d61faebaee2db
+9e5c3931c102eab99c20676b1920913273aaf753ba60d87773ca7215562fb612
+5f246db99d0b1381f716a7690efe7ab2b54c072853bb28705d12dc35b3722ff6
+11675754ee99e7323b2389024b7112be202194e142285227bf08270b560fcf34
+2d16392b6dd428e30a10e0d87977a5e6b035063b3f43f4fcaa21b30c90a194cc
+5569a0c060b081a054de4bee53914c2bba4e3376b4a44ca48b58e18be2f84a62
+5039ec6f2ef3a6cd1d31d5eb6692420d89306f2e6a712d3f3220e2937f9c4e41
+33cdae5b6d2a09e0a141fb41d58d5ae2111e74501fe591bd3697d6592db2b425
+0ca00f66be5069fc5800e04fd4c4dc1c86f723c02684b7c353f90c4cffa5fd92
+8ee3d10b9b259048c67c3bbfe026185e8a5e8b097390dac73faeedd924ea3d24
+cf82c27494b4f0d7abb77821408175187ce0e81ee5d672000d1dfdb089864ead
+599f8392cb7a14624c0624d8b1116645ecede619b1d864332d521b0124de044f
+e576158176364601a6192366bfe9c3ca0491c91e53d21845b63b54ed4d1f37c1
+8214248152c57a2bfdf8499abb15e1b9dc565456e5765edab49357464a2597c0
+e4c987620bb512fa33b6c3f643f94e89d83b5778cf56e0cdf6c1721f58c4d3b2
+dc13d5372a854d1b4f0415d37e96f6ba8cc5685413ba4481f2fc489484461d6f
+5e081b04a478b0a09139a26ab2944deb0ea32a61f1e787d90cb55ca1c88bbfcd
+37233d2cc2f7deea0112a9ea83ede40232d5d97e4447e02dc450d0c944bd746c
+8d33b0bf6a190614c016bc96dc7b58835bb0daeeeed1b306326a4c516ef39a43
+4e59f1d5e469678ddfb649bfb3ae3726c2a50e680701812e57f5f11056d3b6a4
+df4be50aa1edab57e5df5f5fa7af30f9fe9627b01871e88637ab68e7d7d9aef6
+7920bdfa66b77bcccbaa2f09cb59496e96a4f7cdd7986e6a1fac884a9c729771
+a3c7ce311151e93138e3e02bab11bdd4b1fc2e7073b5a35bb8601ad01da624d8
+2f578fefdd7f81db5ccf4e4eeabba67aac9b5e38a63ce7c1e591dccc86ccd17c
+f978e4fa9ba685854464de478f113a9be8d6575cbed7d32723a879628b9f977c
+42d4771fe17fa0a4cb918b6565dda1c28f7219851e917806cf7105efe42a9a94
+a76536077b3a9732c01dea56b938803a43f521faa3ab493383ddafd8b159f00e
+87dcd4dd42de5bd113ea2ff055a2153bbb1fcf3b51a85fa18191ff143948de0b
+cf606706cba9afc5db85c4911fd1fe2377f68514a3485b40b91c1aa46f526485
+ca9720dd285b3abad88fe5d9ff2afc628caddd01b044161f6c18ec243028b727
+b2aa343385c848560c52d6fb81791f3a2ff66fcadd3ea41691a2073ef984229f
+07355f8a6a37a9489494fe02c233c4506f440043b4062755f0cf7ff4b32bc154
+dd96fc84a35f0f989a1c668a945a8032980f073469b84002a85bebf6ef17fa30
+d332c88ef5235cddf6a66addac6d66d1f8944d9fdf9e33740c319979ca36a0d2
+02e72221f5fa890d1b88734bf6504ff40a4777b27fab35ae19a46338f9542851
+ab50034d1a515fd8aa550bd7074b283b2206acf1c13da6d3a9430b1dc5463b95
+b631f28aa62edf5d9b273ba803e72145bf0dfae33223132539b0346c9de97ed2
+7e553e095c97f9b3a14da699c383840456823419906b5f4be20337e537e0e8ad
+557795a68d1fd3e6f770b2cceadcf493d19d688e2e80f83d8dbaa95ece47f6a3
+5c028455cff81071c06eeb830496722a588204cbf52d18544b9ad755e21afb16
+7e27bd39aba20041bad3a99c66d6c16e67fee8ed79712f2a0a788c51e8f26d73
+54585dee498403b734f56cc3015e2a88a23dc6890f942690ee717ac457a1592a
+ba7b038bf3f0e6f1e056879cf8d23660d8eb5db01951f0ef32ad2e6e8af7e06f
+b81e7e945f45dfe64a264ffa6e8d9f0b03d2ff2ebe450e8b6d4969e49d0f5e1b
+080eec0d7f9ec42dd64d2f2629db0769590fe62871df28a350379426cea16b52
+db14a5e5c23d13da4084723b9346011ac33caa39886424c31899460a5f35f405
+363e69085db6e55b069ded255dd172fe3df0b0d31a0053e234b3e2ec44f433a6
+7a638f9a55a445412fcf8c6ff4d01fdcf6e012ed305beb3fa0b1752441c56e51
+c30b82300e0b98ff032e3bc4e27d6485741e27a07ea8a131bd7e697e28854ef8
+c58801a100ba86d94ebc1213cb54a81083367f385d028644f213bc18eb70734e
+8de376d680e8b71b530a5f235fb14d7f3d3059862cbb7ea9b6bc2d827bf71744
+87226be663ce0a9feb4f248e28b71649355bde7febf2b8cce5f674f6afea22cf
+f42e98405fd872dc2afadb1d8b1630265913cd5452c7b6bfe516624c16e6133c
+3b0152abf170701b5600882b3a4c2fabe4c9794a4bb48c3e2d9a4c03744662b8
+0ffa2ac877f5a0db47d26d97bece9f04220d7a19f7abae2346016a359f183271
+1a022c704e4bb9bf7215089e7979cefb7fd438fce318f3a900385d6162aaf8d6
+23f50ebd7b7de89e426631b59b1fdc688f36fc81ff8621e7adbc3b1aad6c2d19
+b9995b873acdce08661a25f30f551144e88bf163db7739c67fe4f26ed01fb8fa
+9e0a8628ac2338778249c101bcb667f8e7d37f97fa68a680ebe80421ff943a33
+ddb2dd16c13f82c7100d6d4ca8fea5283518cc9004a9cf1e6b590bd8b9795599
+eb091c682528dcc8890bc45517ee013e146f6e2d37e4b20f007c47fbba8d600a
+63288701ae7e57cb2905f5b71557f2d1599f1d5eda80f59896199e2aa744dd56
+74af44b9b87886ff41240188c6753248d30b7f1aec5520c18589120615e458f0
+65e158f2015098676e62329cbfb76bd5bacbe510ab5cd1df00c4b750eab9bc05
+b2a6d05a17ff8f198ddc48abe338e5aa4280080f5256bca57289511d5206dc65
+d77507048626e2483fd6239bd14d81b4e6ee321c957332629f004710adda7007
+04307317a3daa98a28ae9a788c025aba2e667f28e567678f7dd8e1ab1732e74c
+886e342da3330094619b2a0fb6adb7189c0be350c4052e24ac09c307b4de27de
+88b13f8c3690f42ffc6f9b3a16ea9fd3aad6d2529d507de80a66fb2974f96f5a
+6ec51c306f3253a03720e45cdeff9d70d1383ef21e36f9d9a8236fb90504eecc
+5cf90d24debe60c8c45e12ed3f6a61c29788d1c5cd7cada5a2f09dd01bfd1a4e
+f57202691b773a337533dcaf80ed4dadcbbbaccd19765eff4d7316860502a30c
+b422ebaf5d9b9bb9634abd56a40c0e5d05b1e8b76710abf46d8ae3be97ac19b0
+31f01237a0bf80b474cbfec8b863141298ddcc4bbe702d5cc574d64d21921615
+755553007b7a3e031ece5e2797d72e381c49f4c3976594f863660c1529b461fb
+bbd4da0d101d5f1b7e3f00a0e0611758619f0624fffef8c234c224de122ba669
+2621eee9b5edc20b8071453f3773c076ff8025824aaf89ad9d17024b7bbd3db3
+477635edfff2293a9d9e5d7553bf5fdf6eed19a04bca31837facd884f5fa0735
+b2f244ecc17773995d753c3ec1f81fcf46b9c7fc35b6d8c073fe3700a2924c4a
+673fafc2fc4bb02ec5d7e864176d5c87c5348c3b2a8d5c583196fdf8cf6108a0
+0b0381d126076f5ff5283d05b97b0a21091be3f73860f72b69b3a4dbd19372ae
+b661219c6fc715f06d226bf54805fe97a1b03a69f6818a561a3c789ee6db3af6
+8fe31b152e9c8813a880c08295cb6e6167a145b4ab25e97855f7e058d02fa8ef
+0f828432b6e9436ab01c7c6a320a33d542ca5e5446d08ebd597d8dd49ed5f83a
+b9803bb48daaf7bdf9a0457e4247eb2fc41a96c19e562a5513494350acec5ed4
+75d010b13951fd6c1ff7ffdacc977e1f22da9d11636bd77d80c7742bec079523
+fb7036b4c65f16330cbb06bb4441ba6d9695d57f376a7faef1c5c051b0485d08
+25cf232eb12683489e97e46c1addae9f5147ae117c5744fc975eb90821791157
+110fd856d1bd00c7f9bc1040ae0d83b1ddf572d7d958c1af16549c7c9a498007
+002bc771b5286ba7af2ae748c03e5885407d7a5b56aa55e1d86e583fbbd9b88f
+3fce64f8aeb894babf7521ad50dc5608d04765ca71b0a97ea4d4f67fda9efb5f
+1d67b0fba08ddb711f63e52304e098f871ec1c7e9d58b2b2e58c887122e1fab6
+d3d4b391f3253170ace505c35c4877d32c9c36506cde3ae243d1de6aa33f5e18
+fd129165278045b075c43bcf0ced8580a81d702ba464102bdd123a6c2b2310cb
+c2236427fb40b0f16dbcf46c31019d5beed1e6034949377fd5f7cd57bc04479a
+8b53083904c373a63a4a09c60eca4229aff9209449eb78d245ad1cbf3d831867
+7d60c285af422f15d6cab2efe202a00c5f21635ba36b4bfb92bc54557de1c092
+7a3645afb9dc24dc97030dfffb5606c8db3dc60e35bc6a0086aae19ace912bfb
+c12f209036c0d43f1aa6500f94ba24a0c4db2309a26f0960fe1426f4239d4551
+fc9a87d4add8c89cf7c5e40a181396b68043e0b9321caad83cc8a2a71b51c2ca
+3efe240e26ddcb4d64eb6fdcb0b59ec196361f7897a2a16b25bfc5513129bb27
+24023176e04983e273b0780533fea226cedeff949967b1b9aa9815ba9e1cccda
+bdf873229770b6d02b5bc81a2cdca77d93ebc04b79595d1eff2afd3d6ced3489
+b9d273766dfae70b459d5b94b1182cd11bd4beb370c4ef4d5c551063fec1ddb9
+8761995d160323356be08008e366649a771b54b5bf40f822ba6dfe66dcaa7caa
+4ea1ee4ff8fca8aed14a2966baa5d3db25d0d2cb4062a06061adbb7b2a35b2df
+5dc202bafbfeccae75c27aea6c7230320412c30a993e056d6288935160ef1ed2
+c9f6cfa3119948d4b63e5708cc6923dcd520d8a45a1fbbb34567f322d7a8676b
+8fc31fca3c42b5a5528b5151127a445f34f897175f317579593251a920f0b4f6
+a0d85e4aabf120ed28263706965ae8564bf9fdca5fbff9721299b212d7562335
+f12569804a23475ae1f5ca757b91ea476efb0da9baadfa85b1c33f6e4ff91e1d
+1863aca97bb5b63a07e76a2e0d9d88718871f4e9ff325aa7c5fcfcf40dbeeb1b
+82536677ec6ed3e57fc50270ef1067354719a1b2026927e52d0e3e69521d8e8a
+a0186da08d4cbf91f7cb7701ffe8f63ad558fe50e1a19550d6f769068b96f7a4
+7bf99f865c8b6d0de4c4b3a24c9deaf648c462cdd4892a544430ac0ff0932695
+8a9df434c065161b1adfb008cc3cd949c055fb8a99c7712789321628f72a498c
+646096ad2f24620366f20fa7516c2535df0d3745143b62424254dd79e2f14d07
+ac4e4f623b95dfc1e3dc8a980451f248d55cf6b0257c95f72915c53e710cc7e4
+c770c7176434d40d1e2f6ac378dee3d56599be2e75dbb80b68aa0cb1a9b05640
+2eb87374757ebcd800ee8166a7c14344d534ec43c679f19a3faf0831f6ac06c5
+418d0cc5bd0202c8fb9ea4a4bbeec84746782b34f0cdf595537108c04fb2c4f0
+f734dfc1ab7b6e448c5466e596f550709be51ea4ad3d2e1809406081f24bedc2
+afe6b2f0dc106177f0f23e50a68087b935681700a73687311c047b7a3b959e94
+f1d66a5b9d363b07946af750f7c23c88ac57abe52753eee2ca1738ced53e343c
+d7147f4e518e410268717ea1d47f935e68e37f1393f4643295cf9fe6bb6a8e4f
+24eb7d36e5a73e95668dd0484b43dc7fa7a2e1a4771439af53b8292d4dd9ba0f
+87090fa3fc1412e99fbbd9293d622389feab98221d1d17783f4e98f438807085
+f1c5248b0d6cc84306cdd2d6b4b49859030ecca03a3bc135fd0e2e0c4dbce468
+b2fb4d3149b24460809e7a40e7733fc69ff9e1f5034bdbbcf54b02de9ba72d97
+3e02f2391c4ffaad4155684839c9a1ad84259f7e0e0870b443f6065a9e6ba2f2
+5d2b7ed4ff02b658fd881882183a92a619e23b78e368deeac7731942c86e792f
+575e124aba8bc9eb8f1ff27baa023b354cb58a1b4b7bca7ace708aa264079a54
+8a7291a7aa9ce597599c436314f0ce6bd9a91f7d7d6f5fc74311e3a43bca381f
+84343da850a3b97a8b8647428fb3d7675a8c747a364af6733b624c37e119408e
+2b8dbcd0ebf1128d3d622fb12811f6fa86734714fdacd66f22fbbed86e0eef19
+8165412707a465ab93c043d6ace1453d51a027eea5aee64dc20e6b1677bf0c51
+6d988d4c2dea53fd3220ae68b7ba8ec9b4a9e12740610db32c86ff6f9dbbc4be
+c895877b4a50136972e64c5cec736350fcc746b9a35d227e861a84ea1b7a991d
+df9923afa67b38558210e59584be3bc822be7b00f0b676d52860aff3fca1c731
+29ba85e325b7c525bedf73fd53f8cca733dc99afb00c7d35203ec104ab6ef99a
+303c5320a7ae6961e7ad96e49801de1aadfb9a49a4e4938ec5c9866a2a073255
+3a0ca67cd73514e1925cc131a6201522d44caacaed554b6dce99a30ca2fcfbb8
+00b9b263fa2680d678a94aa745d1628c8722384af1a6ffa490b18e3d34d21ddd
+6fb6a7d01123c8071d7325e30c1d0d29c069f00c2b3e6c2c337e4c19c151c5c9
+780d3e2b9fb69473e31406af3d3894edf3d56b15719b27bfbd18bf14e245b809
+f29ecae8d0d23194e99d15e3b3cfe3c6dadfffbf9f33c139f814ba96aaafab3d
+7de097d6ec31f1bae09529750e5a124b1df043b0fcb630631fdcee4fc7238b1e
+08a3a34498bf112ef7a8c543720cbaa77200a40b1cf72b5a6a05d66a0ed37d68
+22533e12b1393da9c1edaad4f2299558c82506af548eaf465c76ed43926797c0
+8c127e349a26c21006cde478eaffe17c59d981f045ae488880e427626ef9c073
+d5c9145af6f127bc9f127f0a859836c56b9f40b6ecc446e137e9d9fff367226e
+73ca9add9ea28abad05f87cac5643bc07e91b82e0b35b36626444dfc50a6dafc
+c37d6306d441ade0b998c7c98dc259e40d974a22d8900263f9421d506386ac95
+c1c00fef532fe5641f4cacd814ceb9cffceb23a219841e9e1b6c465ac9fcf270
+5408cd925a37ee97c64894e02c73d0df87b382622c074734a1e2370aa4a2642c
+1fd382156fd054f3a5e2f66a623e396cf56f44273eccb27b5d11170338d4cf27
+3f61f8effe3e52b90bd1c49dc15e8416f3f1f839b2a5d900ec8a33b3bd8c3ead
+6f51f1d68dd4e4202021adb52ce62191f848273c485a5f88dc1c09952bd38ad9
+4d0d9c08cac17187e36c4bef849ea1b5eae2c15ba8a299e9fb3e8d7353fbafa3
+0d7af0f616bd16a11d8e98b7c5f39155b2c8bc3a360c89961ab212a8520db33f
+763c7caead9ed5815351fcc2026a35646336a498ff3bfc6a074e90f0395ff802
+48c1a6b403c1e57eca7068453f149eb8c5a6c1bd980a0215d90b9825372d8d3b
+3fe32871eb3b517ed6e20e30477c0433de4d2cec73f7d7773210a10c4932e909
+eff2f2f83896892eb69f7d27014b55aca65dcc5e8bc62046fcb80a2a24a52165
+77e8ae37ef099a4dab23cd5979017ad30872aa6e94b2bf4e4d7f495f2eceb4f0
+b6d258f94077d191f62dd3f96f94ab43f4ec19a0c1182c13a8ba469601ff148a
+57e007c07b6d305e3bacb2bc0a6708a1b17bef4ea41982a321240ef969390985
+d83828feea903855db4ed66f678dc7c5d6ab49070c4079106163e37cd1144057
+c781dfd270ee40e3c13b5d74f52324f85c84e55f750298ad9f145759c26b4528
+8e707897bbb2aed1037f30d37109a784174cfd5b0aa698c1e79f25d09c603628
+e23a3abc8d6ee13777f7f5f9e27cf34b97598d3d5bfa96d2499e91e2fa7c505e
+3227f8217212bec21eb2f31622a28d292429ab899aaa92ea40a4ca1033217f4a
+ef6666c16305389f149449a44a0adec2899fe892fba9d88b635668becd219657
+02d4b8792bdf922e4342dd5d6d27dd7392a427f153ff35552140a01d7dbb14b7
+57da81569ced971af93e59ec7a6927843ece2a555a58532c4a5c0c5aa2d27405
+72cab4d7f7b59b45fba1c9f61115ee87574e374554d2ea0c7bc7ef0a07843e37
+cfc76c2baf0bbc7d58a95b70f7ad9d2c2c1cbacc6f5190e4392fc5598792e623
+4f89f3b28442b8d37e3cc2c612b29f960005e68198ccdc8805d2887d9e9fab27
+70299a4eae741dca4c983967bb2275ab152a58299a35457759619c6dc3b25eab
+68fa0ed545b09833bc269e15456c018ed4494d2c8529f176a03b340fb3d39c45
+726f023eaf1cbb5a0c776e2a65b77db5a17e47f75c0debec46166e3ad2804efc
+2e41259900f9cbf3dde0d6b1ee4f16964e1f3df0c332021504140bb87e68694d
+f8046216bc50fb9d7c68a5870ca8ef17d8d543dcc872a32d6421c5b30d561efb
+e55607c7e21669fb949aee071954491d5ed28c97304eedb5941fc51aec6b7d4c
+fb4efd4d49610ca7779e0c384e3435e4e9ad4346616667794b925d638355d76e
+a0130cc84045ef68a6f45a9839d642faec80a9b817474fa8ecf3176570bcb441
+e9b7450ea2d3f2d5586db80b4218d41c3f256ab8d7bed7e59458b91872f91ceb
+fcfad2965a08a73861fa7388dd75cac1924c202b26387b6129e5ba5830b9e88a
+497c7e94c61c286ae8f4d596fee7c17ba5635b829029ff837c7d4c084df29bd1
+b318d69d487a679988ebc1751d7c944b83b6b44824cf91246fc75de3d8a2b092
+d1946b845f3f5ebb0b9b043215188cfe3a4f34fb4fd0d6dd89af38c49d8309f1
+b95e43c6e5a48a4684dd826e526d8bfd8318447b57aa8c210753b55039c057a4
+4a35faf9efa90f25e9c5336ac001e71374dd7e45588759e4c0a2689d82870948
+68f456a56dac56b2f0f60a1b7bd307ef18d7d86a3d0fb8e4599524341d8c57cc
+3f20e4840cf87c11929718d250faeb37a28a5c230e9aac9abd7f0339d4128c54
+eb3cc09e4ec9eda06a4687cdf21d1f117e63aba8fe5079e879eb3d1309d24761
+32dd8f3ed3ec6a3ecefbbd5eddeab99521bd87f39f20b19ed0cbee4fbadb108a
+8a25aef0f277ec0c2d49f30afed6975967c513a0772d8a1176d3a4e0a7768321
+2c85b1cd14ac7825d029b02cdecca22e891f3579ff5ef8304e74cf3dccdcb3a7
+254134118665dfbdff5427c0471b7d7c2b64118d995734a9cb4495bd347cac39
+8805fe76a5973959645a471df1bf99cd333f8a68815706fc4e365de7b496160a
+4aba0c061e8509a1b39fd0f2582f813d21daa11c35a5350036dd993e83ef6c41
+dd17d079fcdc56e9bc4b1c0afd6eb855c7d347612938431ae72bceb78aab6efa
+5ccb731cc337171d3e591140e9ec3436bb12ff9b39ee8631de4a6934bce1a4db
+b61aae9a226e38b0db3afd189165d90812e6a8e74490e080d2d79eb010b96bc1
+548062cf654b1b627b7a8faec8f496cb6898635e123651996d2cb52afd58c014
+ab44719499d2eccbb5378666d6a0b14f8c336226b55f8e4fe55c975c84eda8b3
+cb66b0e4372f23966d4a1ec8e7e2333acd6f7a18423ab867dd5572e30ee1028c
+8a172ab879715601ccc59e4431f3a1923fa3c5f79e1ef8ba28b54ff006bc380c
+db98623bbf0604a247e87888a62fb03473a98e06c9879f158484d243b72b4d3e
+04573192531beffc3202c5740209da69deeefa077d9497e9c5d2309b941d8397
+2d9f88eab63fe121bd4658a3bc09677772f7f63d27ee5374adf60c1cb4f37a43
+355567a8649aa36d60bb14b0ed70932de29a7ec4910b836fcf8662adf5d80f49
+362ed0e804b459be1c5315d4070b61bb6d1296a5a8b2516b11dcb8dfd0bbb426
+c5897ae6a20b531f8f251cc12bb52ae6406ddf28d77784229ce474b8b72b4329
+97073759a48cc211b122ac6e29e089d75b81a983c4c9aee019e5cf78a4c77bca
+b335eebd138ba85807b57bbd7321283d1cc1793721189de7062dcae2c3533402
+06426a9edf0844911997187917ba23fe1d0718acd5c4d4ad8c2819de24db6ef2
+b2cb9701789ded9938eb436641d998078216ebdb97c418428e99b6abdef04853
+bc270a8bd461065d26efea3434e7d3b52eccd21e07f526881b3ea123e3c2329a
+056ed88fb4089b69abb3746877771817f2fe9bb6728a7eb3fd2e64761463ac3d
+669ad3d8928451303c7d645910521533282982bca604677f2bb2988b10f7b848
+2114cf7557798ce13952dea8adc2c68397f100a0ce55f5b790c6b8ead46fe7e3
+6e958c634bf76423a7a87c9448e0824f142d0a64ba8215e8cbc0da34e79d8589
+cc9baa0f29410ca4162c027383eb8260a8705f7f1c2c7676aeec54c4e0c42b08
+5b66dda1c9f7984877dc5219fa062d884266438b49c4a9aa6a1c469440c75a4b
+ae1f5362b78a3c9f74181f0f28b0354af3c84affd618a156a3aad277065fc6cb
+ffcae5406758d4add98169fe89d3e21f9d39e00d018da20350599a441b786cfe
+74a43b7bc4659b5904b02ea88638622bb0096ac3b47af0476594fd3ca6753f65
+357d504941120a2aa326d006e5a69c6b806d3a0e928b926e253dc81ae13b1dfe
+f4ddc4709ff15ecd4bd41b88d8ac189096ed4c56465d3dc7b76ad19f222f7397
+52426640589f5c13136131d42b814a8c40d6597572e6766dced40ecc45059318
+5cce8f0121abe54423c3b28e103a8660df4fbb1b95aa2ef9a9cb0a1253c49a94
+f32be151957c11ab2c0d522f57b245edb047eafed062c59ed0a6b82687caa7c9
+9b203a1c30ec063b4905ae31f0118f800c6c3f7759cdb6b3f043af3243b8ba8c
+cc383e27aaba6334a74868e3f85d9a4fed0550257ef85cdbe8ecb69e7a5d7dc9
+3bfc2ccfc997e74ca7714fd25ddffb54650d15417471c95360ce43693abeeb42
+5804a13f77d03cc1b53084ffdab17f068e4f0c506cf6343b928251165853f6c7
+d337f6c3bd8aa64c57156ccc69050130f1206cbaff5f2202b8a17630d41b7b62
+0c4c276f8c6e76a9228b1756aaa31b87598b29d2bc5a268b45ee3720261cab35
+e5997e262ccbd3c464aa67d0074f1c4b04c786ee08c05d643e01acf498be936c
+d83bf1800d6f30a4b5d7a08c15fb036d4e053e436c9260891534cbc3c8eda536
+2cdeccbc03a423e0f2e508ab719f6bf7c274d8ee7740b79b13a505102acdd25c
+50637a1c6b75840b12e6dc77e1befb1b6e4f3877cf2e1c2ddc399e0098093d39
+c8951f6e32c75fd6ca02d74451fdf614a55007b0bd7b920aab1cbf2de7eb072a
+4d57fd5734e35cbbf8b5693fa3a09e5842d938b609110d33b63dfa6c31bfb1d0
+7696ee850223891791a68294433e6b9d733eef2683785694539e5c9d34d5963e
+22672ae0f47061e450c62df0596aa5742d7d720906e6d8b6002ba1b01a8f0732
+5aa66cb81ec1a2009f72790ffbbf58a0d6838a934c41aa1e9d34edb183e4715d
+e1025b0a03a2b4d3083d5dc24bf1656751ff0d50ed96d3d03ba155a1de7ba075
+cb09c98ac1f7d7565fa3b826d89c02b966b978fd33ca5a42cb96345f356ee8dd
+d392b5a04cc3333002d469e6e1efde17df13d5d2037545694b428a6a3706e769
+6d31cd8cf72cf7245865818fb45979507b876a83aa961312a92bfd0fea3f0037
+a3025364dba8603907e6f3641a4823a1bbc556638b27133a0071790fb8fcbd0e
+abcb83a258007bd8e2fa723b72fc36ede7e4745e67f5ecd38db6278901e4559a
+efb6761215e98f2dec27a53eb6a5090030c74c57d1d1b1a29f0a578ce26e4682
+bdd7854c35cf5690514eac890d2dddabf2b6aa6b66304abc6b9f012d4c70bfb3
+a3ba42cb4bdd4f3550172055a44dda0cec627935ad8d96aa1048ca98256417a8
+c56462c7ac76f1f7977d51a5a65c2ad9bc3115a0728235fcb438f18cf370e880
+684c90971014482b2ca100d46d3a3de6a16b75c1d8e9c4949985b753c4256ef2
+49aaa058a2d4795774325e21f92fd0350dd2ff1a3ea9f8f0e9142a4757b7e926
+8c8ada143c295cb86a21afdb5260b4afb8e3bb4a0902b9d4fe09e3b0a187f7d4
+bd129264d0f121a3e0ca622bee85bfef35a039f29ff88131ebd4ac4ee473773d
+b5c0a258efc4a51dc8582089314ded2ae3d39c42f5a733585c5b32343e23681a
+2c5207e7b8c1477e09a3f131ae893172b7d2ff21d7bd5e67e1fdce06450b5406
+0b163a8c31674c8d6749d270a15117df4a221fe98463eaddadb4c8c8c8638439
+bc34c47fae4ca32e13579ce1fd6d5448bf23fa791905adab3e42aeed0b5bb6c1
+1f541b58bc1355288c4557b690ab27616f462fea63bd490e1c481338e9d7d68f
+daf78b3fed65606463aea70d124b4757f47db307487a0360d2a422dd6aeee042
+27a9f57f734e233a4153fb652c06ee776a4c64991cf2d3e69c90ec4e797273a3
+d1339ddbed5e2810f5b54aa0b611ca5f1565c3cea89bfdd721151f01d625f07d
+0c551db5db902aa5fb2027c8e5513f2000bb5d5e33bd99132536d3e65fb52c4c
+424688691e4801e9d00f29a61dd7493228a9a3c137bb298257714ef0ee4f9f16
+87f0fafa42a93bf619817a73f292ff65941ac480bb3f9e4a5612a98e24a5373c
+30b5e0a5b5d4b55221199eb4f5a6f70b7330a182c3c195229155f9d3ed4d7fd2
+f08cef3911f7ab70cf3d7d4b7dc302623b383a236f3f7c985ab4828709ba1d4c
+c2a0e4daca3ece4c41e53a853c98e7e840c59614a88fe1227be49c38154f024d
+83c4f0339c7f1afdee7b6d58c003359d1bc4f460468448222c26258d81b1844d
+40283e5db7bb6baa955d9effbbe88f9981bd204a79da80206033a5d3c0c1b8f5
+00ec8a79f2472396493eae9ebeafd1662b941db3c23e3e820c7e8f85988a2a53
+7d955f18d7869632f498be0d6f5a81fe7e6727d8e6d0fc88cafa99839629c1cf
+b7ac3cf2b21c43da3f07a3cc1798909400e840f4f48bcd3e76be4f94d9f38ee7
+f480e76021b36b9306c16a51ec9bba0c6f9b98248f17d49dddfde34226e33622
+c94655b5afa1c372d4463bc68155803096a36b6cffb7cf261100a46c0ce8bae0
+9fd42e392888bc3431bc9212de09437d3b7ff15fff9320fe11b2a16adf4f8350
+564725a52e4183b11b06166e8ca561d4913fa14603baff5169b44ab1f9085d2f
+0111e4c3b9f6f72f92b61a915f4b6aff97b5163c5e131f1e0083a00f45e5eb57
+3b5de28f5e51e6484af6eece850985170fae9a91040fd860faf7b6be1fa851f8
+2740f3f32906c221796fef28187ada916dfebc65e327533b83a9a63d164d8b2e
+6a6d834bb6390399d564c91c1b998ec5f992d280ba2538098b91cbfb09379f9d
+c35deb26723693e7ce021f80792262a4d2f6e0f9a4df9f5286705c04f982ec57
+f10d2ac027d949cc4b62304d987640a6bda12acc60644983811ae225a0869ee5
+d5d92ec5ca8571b372033c63c402b0c671c63c3677d129837e6e75528351562e
+bc2f6fba03df82eb600e57094c370d1dc844143b30b7d5dd0f7e20b4dabf379c
+6a2e401a6023773c8b85ee50e1949476341338f3477113e8deea7096b8255aa4
+1fc4bb718842713425c6385227e6fb1ccf1f3fe89cd7f7f153a8132be0fcf7ff
+5e30259022e09ab8a3932cc33d1cb4f6d3e299adf4c15ed0be59df30c1d5ed5b
+471ac14fc7b10192ce7d55a412628142ba12ff9b39dff0cc18176e9693ecfcf4
+452838dd87cc9059f1aff608182b12d37ad5c13ad77ada2114f1cae0951a4d58
+725b18973e4c5c3ce7d4454aab91090409fee42d3ccf5d09cd768712e2a73b6a
+4c134b390e0209773af69e875de4f7903b65f8ac253eefa28de825e83ff35b5e
+7357ae7de5445bc6e2022b3d4c161f3697b2ee9650552271020b06f802f5a418
+d20dd1def4368956c713a197321b545625093fab4cb41413f88b6ed006c8fd54
+296ec46e4834ced1987ce6739f21631e0b79de38542248c7afb9e08a9e8f68fd
+243f7cfb11767e9e4647972dbead5ec136764ad4120e1431b38e2566c0c0bb81
+6117d1d5b188935ba2924653feb532cc4f900f7e81e2e6278a753fcd50fd04c7
+3b0edd77747e070c2bd18ceeea2eae31dbaa343678b28b05b037c7b6e604d048
+394b1e694d23096040a5e709eca5a8755a2f15df09c607843d8abdca62b82e42
+5d0dcfe5bec63ffabe011e9aae3322228a26b0358d7c6a740cf91c526d847b84
+87c084b7f813f6870a27535b9f727253a9c41f502ddefdc210d7367371a8a1ca
+6dd58d8a7234bd5457772728fccb21f82b1b5d1d8c538661c92fdab651e02e56
+766e16d58fb6ec299dd0fab458a79ec777eefe57ef9919b5f966c7de075c87b0
+f624e4900d476b49ff754e3029607cac879c150f12b548cd78aa6a6fcf0dabee
+40412bc17072ea2e951b2268eb3777a619a250fa18c1f25a0db6f5b8895565d1
+5ca1a6f296c7a95aea09063c817468ad8c76694f2025db959a3f476c0235f3cd
+2dc07f725c862e3cc9ecad251596061eeb04156fe89cf21589f6e11082bf3c5b
+8d61dfbdbe592a120402983939b99c7d38b4cd32429237421594e21a21841a6a
+e3756576fc0b063ea6a439f193e4f1dd48edb446da9ae6dbc55f0983f0a5445b
+1223abb431e6bb1683c0d07d33e42ff9c37b2d16a0fbc52ea27f53937ebb52f5
+bc7493f84915b1e4b8f5c05441cd09f43e0e5418cc9d82f31ad35a5a69f32289
+df6f52bca5f1fc74b2625a42185cbf40350779c94b75a4b9f551f30439acd9d8
+3f9b79c46694b87fa60ea3af78ab05a65df0fbd2491d8a33710137a2e7fa7559
+39941651fe072f868f92b80792a40673a91776b083156f36bec4a3120d0ddb82
+9296dcb0f5d70028c9838788b84b6d9a84a12dd167eb1afafede886c6e9e9d21
+4ef74aef4a070cc6ca07a88629d15241be5d62e4975b55c734cdbdf872471c4c
+9bc047036203d37cff7a98848b58e6ebc04412dabba494d4bf25ad9e4b4ef4b4
+ee155539af0c4b9aa1b8b8195375f6d5444a7ba34c0586405946b2492652ddd3
+d3e034add236bfa5a8612e8d453736ecef2fca9d8cada78698cbe62f7a7d9611
+f4bf3e04813a874d0e5bab4de5e3c72a98f38457dfbc0852557f6fb9e376e7c7
+1d3a0c9492e439cfecfdac766b7b5c3b59c29b3239726e2d6f672352a15d2aa4
+14d150814d18468a2558a8b86d2642c2b83db6b296b5a943ef70eaf987be7ee7
+de41f5cd1b1280aaf49289de4f4865f6c1a3a303e77b80a9263b142cf080ab87
+8fb6ebcb18a9701ea271a21b287bb8436d780dbcb0f20cb1bf949f080680a92b
+ea81f980230b41311c8f30e9e25f325c92c2fd4006211444a31f80c86919f8f0
+890e6c1ca1ff51741d0634ce4818c9c2f0c553e5e8a17ffa5b834fa7672fe319
+75c0731a3f73a51585f5815419d05a7b10a7e24abdfae5078f7f8f5b34581bac
+224f8d63b4283dbc34a2a1573b5f69eeb158c93e844403f3bd4e7a3b3a4e1e8a
+ac0878ec2eb7c1b7e1c9e6780233608d46b7c801c6c0c83eb67b5d080f4af67a
+7b0ce2d1a392ece3e3a0b71f7f37ee8c333ac76bf8ccadbbe158caa15c6a2429
+9b350ae180c2ce885d870be5d8378fbc05643de7c8da7171ec14c923c59fa500
+4d4fca2d8f85e7ba1aa642c8a214ff8bce3b9f62ef6a4a88c8129bebdcbfe426
+808e6d59b712b2aa3d7edee5e45bfa7aec02429796717995785614d69721ed40
+c9c5a56c5b10e5fb4d5e30d02371ee0b7c7b67d8c7a9fe60b2b9cc7ff4efac5f
+523fd88267950ec3d0640347966f43bd326def79b20ddf0421551168a43c8791
+627a6ee25d3d8a1200c504226211219c690f3e708465da2317bc25baa1e9efd7
+78c9daef857ecbec0449bc16dad92f9f054d68cb91de65caac086e95605ef628
+702bcb7e8dfe538d683263bef330c0d900bbf6f62fdaf663d6d1346274006ba0
+e321644c01e752faa7793efbeede43a7b83173f7f167f3d6fe970acb6646917f
+d36bb285e6d96ff1fcfc668ae4d185d868c898f3964fda9f0463eb6f83d2cec9
+ed861f5027330eefe13163560908a7129990799e21a1e83e814c7df4dfe15365
+ff29765bd346019d69809f425c453ce0a3948fdf3565b83332e47cd65c73467f
+efb2bf3791994d3172dcff4f82a8d7ae4f9fd53664d180d930dd20aa1001a935
+e61e9410667536058ec3fd7b97aabd163f8de60a45794196df0cee18e8c56276
+25217e4002862b3241a017e7b497ba015662ed624d48749b783f69b204792a35
+1212fcf465faa1d4d5905a68f5f17e25ea35b3bb33498162e88f3b0e44d0b2e5
+756156eaf47340a82db8a28fce1e0b26e104295e94ac9aa330a5292167d153dd
+cdc91e47e273eeff554fd652213148655557763b3aef2797df0ab81b202d53ec
+76f5f57865cd1835f7f94515efd2335b966b9e81c76335a29414e4372bc6f186
+7140b735589bac9c6a9203b83919f44ee6c51e805a5bed6d7ffb66c44ccfe988
+59c87bc52021a819b52b850573c5fff13bf7cb9c11f23387d486eee0afca0052
+334f4858f1643f6163936a27c472b8dafcd6e14d3bf3f91eecd70bb7856ef444
+9cc49c7b9788c6c095e968b2c59923dde8ed1628c62eebcd5f32681ced0dccd0
+8e1e61a074c1a78d340c3d873c1eddc97df7051e3d3feb313e054934d4f8696e
+8d617c28f03d817a40572e3630f050091c8738fd3e40c231abe958a9f5868b3a
+3c9120fcfd2dbc319a91289cba50898b43a409cbb612c040d2f33d43ad9d759a
+4cce86ef8dd46945e33caf837a0a7ecfb6b5900204662c56c9cc1b943427074e
+a3a81765d85dbe3ad77bf5c1162900b5f1ef594285ce655ca2a15ca431afcbc4
+6007c144597fbe8ca9638756b3ce61ffa44d524266d2d4c6d6b7a7273625c55d
+56c00242b0ff2a150297e504b9fef2b0b478531e1cc7e1c14ab647dac9feb0c5
+b7b3b20dbfc4285db7745ebb9a3039b230282cdf2a19c1afc822775f3a8026d7
+d793498b915d792bbda081d45f89d9af12967de9e4f4e3779650d7c2dc3cf1dc
+d91b8debee82d3d4fbcca89dd4e129a73968660b457da664d1cec437e17680bb
+7094ab35e4f77fdcf34b40b84b76f8b7750346b1e2f133686110e9f1de217d4f
+8eb81f8d1be2e871ce57632c635189116b9a0a7deaf78d9d6d85178a4f1edef5
+e30c05971c0d6746dd2e1104281b6148217916a8fcb3944217a35b1a98390849
+68cebde7f17a14ccb58bfc1b5440b5d8c75ada3f1a581db2cf6bba553cc32e52
+0b3c5f0a9f7cc12e549f3c65798f74123c5556c9e0173254c1eeb1e094e0d8ef
+35ea280b388b3d393dc9b84e6400abf8493017c5de85bc0c23ac61919a053262
+9a05cf198df82d4f2fb5d6b837fa75bab14bc34c1b46b9ddc4deb67ef4444152
+c280be46a9f0aeb0fdd5e90e8bfa5449bae9315ab5184a01d4753af4286ceb79
+09dbef7f742f7a488c93ed0024ee725686ba71296a18e04aa758742844d37648
+5541087952778948eff1a7521fe37a8ab311c7a7e818841c1d39751430a7b656
+0453c931b40d6d15915b79a73bd0d06893c0cfa0517e76cd9bd87673f7e7fdc0
+317e639f78ba7baaa5f1b43bb52788807b2461e95cd8193414724d954ea066e4
+63f578d9ac9a67822057b4e61241b8b5c8f3ce019c767ea2b84fec80ee642ab5
+9af04e1490b930da33cee816e91a7ec3756343129efc90f36468b8286566fdd7
+3f94d19bbe2076959797ddd83a7b901741578486b79d8102942f71f70c72b2f7
+359de20293952d3fd821f6a164487ac420dbf4374463889ca97198ade2827ad7
+d08bcc071bf2e455b4703891e0ddd950b5f2a11ab246cd2e4bd5401721b8e9b1
+702b439fdc8f1ba1a4ed9ef30a18eb514ec61d3fee9e20822a84c3ea225e5652
+65eeb21129e3e950d1143cfb759f8ac5e097a42fbd4807034c2b375598b6c439
+a2e90d007a1995738c61217224cbb54be3ad5aab1fc60d9f9414146b0cacc853
+4a57c5aa095ac953a6c4f5c16f001cf51c9586a3e67e2abbbd304e5abd9fe25f
+ad3d2ad2c8b193113bdca6d5cbe2ce54fbc7f7f8feccff8eb98fb09dd1e2b7ae
+b2db85d4a4aa399585edfcd485ca6bbde307e546e39856f24d3ce215a5ca1bc1
+b6aba3df0bce9bfb7ada72b6a9e1d73ffeb9dcdbbbb0861651ff71373d040f9a
+43bb1797bd93db1948fb3a28cb446a04f52c3c8ff33ab4a9d87708e0bb86efc2
+db4e9459f7213ad59a61d9d7790d346d7036d36a8aa2599241d59b8130b8a37b
+0242a2b59220eae2c2b7a1b169b1729da75fb682f0d612c007372135fab5afb2
+a6c05076f0f08c198a8178e84b9943ec3c8321e0d5ffdb4e07004e2d17a8fe28
+632cb2949c1fe77b543318c7b107212b363f9ac881c7b868255952cf50cb9504
+9dfdb8d429d7a0f3337db9da3e48be60d69999be3df1093303c88f2bfc2982e5
+5e8b7004b75d5658f681fe30bfb471863a318d7d0fb496ceec4429bf71d9f07f
+32c5af99df3e6fa0095b096a3ac03c9b8009471cae3cdbf81cb21baaca707ba3
+f0bd970b52a4844cfc81cd66da5930686163303bb503cf72f7bbbb6f47b14785
+f6c40dc6518227a76bdfc5f7788fbb79978b6de3cf37e0e4f8b284bf249fd602
+d5ef47d169eb36137bddb00ba693ab9974d37347e9f8f0eb9f06f87d515cbf4d
+003396ecfcf3305e83ea35edd75e05b2b363111f45fbc056cd13d1cee1e96797
+adab632023d85dbbc2fa22e057c031a84f69448fac91d804e40e3d8861b30469
+2fd221c7d77e7742ff66aa06be2e20150f6ba142e6c2ce640291d2374b849eac
+f6b4b970ec408a84c72aa94de175618cb50e0f0813b179066d3e41e644fcc92f
+97558fd8523d73986daa8e1a598b5a151fa10ba8b0795d9dd932948ceb56fa1a
+3b6a96166bdfb663301bdb0a3d559a7e398c117e425e9c9b809995e757c4423e
+ee52c0271a7ed1fdeba6ff0c18fc199b3d73b8441d7d64b4bcd2231375412415
+85e7c8ce647a5b45e0f1378d7948ec1b69d676ead40dd592947249b4fbf8b75c
+36631914cb78d3bc5cf506520d6f9c1cb2e9aaf47a213b804496242a77e7b160
+1be264e885bb92abbd28ca502653a98b811c244cd92de8d9b95a46457f7e0390
+0ac1f0f5f458f5052d069d7320cd09e76aebfae3b0a6676e4de1742acf1e2fa2
+d5369d5670e30c7bb46abc78f1bb601f1b652ddd740261811cda6d6215be2a58
+cf2c798f9a47abf9b59fc32046e927c413de487117ab003c4da86f1ef4a2a92c
+5d1ba48d463b11fc9a455a56010bac81b71212e818f15b498882338b83053bfc
+f2126947a623eec40ec7348718f95aca261e8de0f35b8cbd5f9412659725a2c4
+9f29bc32e865636e1ef039b0efc8443db058159aaf304477fe7c2dabfc81b3d4
+35499d35a59eb97061292996fa65c5a1c1b4762d31046dfe2dd4a33e3f8e390c
+922447ce8ff34f911e68000e98d0a94e9c84ea366eca151a3b9ba00d021367f2
+03bc330c1ce0f955231ba61a54c655d8dd7b271a0eedd56a844bc77181f724d2
+42e49d31778f9fdeaf240c096ee364c1e9945fec04d9b2b3cd256c70390f8f00
+aa80d6608d747053bfb92005c8b204abfd262dc7f7d015f4b966d7831e4a506e
+87cdc738974049daee1e1c945fa916b7d8a04885c7be53d7191ed6839fb61409
+9a9798c718a6e2d96c362b5ae30d79c432279ef0b7c8e1a53e7e7e7be0074459
+f4941bc1b6f3efb8a8a3df0f0c2fbbfadfc1f48fed0a1c9aad6a08a50bd7582b
+cee2ddb5be2a5ce078cc8e8beb8119bd78e320d6890bc7dcb10aeb7b5562b9ee
+7e3c2d1a6b38fbf551cc5a3b60054d4718fbb6c396753ec4c76f99b5ac70d9e8
+29d607bebc0fbfeb7d33e6c876f0f1ae24e25393d501aa2a5b18a393975da2f1
+0e048f2043c45126643b6827d80f45c649f44580845f0e8e8e1a04e743364248
+cbc3891cb409f801a153bb47c4672976c62caf5d87c2bf547d3ba11abdbda794
+6ac66599f6819bfcc0f6ee2bd9d94562322edb6b87a3767f30d82bad0e023b88
+602eed6dcd0b9e387e586aeefdc3a2ccdb482604f556ef16193355c437e382b5
+0b87aa275f70bafdd7d5fdab98635e4110030e18f7ddf58c3978c7967df99427
+592988661029f55423765dcea061f1ae72f3aeaae59400cf30f6104614e62825
+9ba0d0151dcb3f28aa6ff41f16ac640b01ba51627f923386c33013bdae4aea54
+eaeeeeef8da3109e8866aa8aab18217a1a1f890d10df396a74bd0e1057a2dedd
+7986109646d103f44f1581821446c1f8cf0b3bb5ef8bf04b27938a6ebfcd5001
+c67de72985041253e4df6d5ab6048002bf1d16753cee57e3fd8414e43c2ff7f2
+b46e54c389c058073f7affacc5140294666f06e2ad2eae8a41add24dff1a32d7
+3c94032b739009b75cf1b8771764f48d1c57033e9ee582144e4af8255ee0d7b3
+ea36a8208a72147db694e21b144c29f0d07e4af8c01fda6c109ca8612a1a6fad
+3d2308b8b6b064f2dab4203724b76c0ad3df3f6e03eb5ec4f42739173e2bd19f
+8cd09a5b79a6b1d6851af6e5c47545e4273d0be5f0147d68c3af68f59bbbd05a
+b913d069a61831cfaf101c2f2174aa0f1c3daa7a73074611624db7ebf1f5643e
+2c5bb1da08b0e1418733d28d0da8f543e438076eea37da310b2f4e049d7d3a64
+2db23c12150dddd516ad182b31e7549fb791e28cb54b37655d95b3c23c879ed0
+c6956040b8c5bc89cbb2a8473df767ca889a2e1240b735313254e9294dc91e31
+b3ed5faa6f7b4267f70524bf8e81c0aebdd63dc94ffa5742b20acc20ec097eec
+40f28ea5744a3ee3910dcaae093b74e694dce05ac03ed910eccb4133fba37d0e
+99953a6a3e290725d5ee4c10d03bd7f254ba2a4d1bf25e6b98de5c940f6f5303
+2cb0d0f029f0985b418b1f07af698bbc601329f9fe9978e5038e749f5872f2eb
+5572d9225f688d3e9c228f8c793e227bd5a9a28d0d5ce6cae9bb7a8372ff7519
+e40e2bab027992d8ba49458b42abc954fbfce21141a270468b9fdee484a7ebff
+64cf291404eca8486b14d0a5614604d5b80f8eef6eca462f6e672d72908cc3f8
+57550b516fab7e03c4d74245f2fe2c35df1535196170e9653be1b5cdb555cb60
+2d46549c63987b12a4cb569223c13d255ecb9300ba7a38686eab1c0b4484671c
+3523cab620c1d5670d4bc9e59d23bf85e9bb2f57764031e1840437832ed96e79
+4ecb47cb9b8c8f45a922179f111895947ebcd3fe38d2e54eed036ec309f28af4
+1d9964639cab6eeadd23691b8da7affa00b364817cbb5a2f1100bf653ae568e4
+6cee6fd265e715618c4270e482e5162d85cc1125c7f7218aaf555f518373057b
+75e49bd4a6f0903e0c3345337e00a2c6e1ec2d30162aa033016253af30b9ddd8
+c16dbb6e053ff3ce4c5b052f3f00daccf580a0ab2244670597e8dbfd66f3f088
+a51db45be935a2f8042e2dff5424e3804cd135f96cc59da82cfcb7216e7f719b
+a361f655f268616942e7b79bba5d73683ad747440c75e9d07569d8aa38824a46
+b20d8b3bb3e86297d45632d310abb735d92e2ecd158cefcb4a98c93bb3f13c0a
+36af62f165ea7f5eede9cc125600127618e35d12f3bf700e58cae49b05e22c79
+e591171df2f348d5455eb23b1513521bdbb0eb06d5bcb69b982190e63e28eb39
+7da07c06e388ea6229223ee4f14a9c384dfdc2ba0d8f9ff3c5fe852d0d662628
+d103f681fa2b56421d40944ad0d0e750c84b8e6ff963f5f37b2e3116082662bc
+59e3614531463a63ca3caa4af5fa82add2ba8ec478c04cec24104b3e608d0fb4
+611bc75b97c00d1729e8650a636a36861e8f7e6429c8ca0d2f566e73611a114a
+8b8e9f96300bcafde0cf2324243e77fff438811aa9882989a8bd09c385609a4d
+dcb6209312d4529ad9bc0969a05b91e42492cba53b5249a102662e6edac95704
+271d5502666bc5255d35aa2f20e77729e8ab3987b82521bebd459fee449f240c
+6b1d52790b5ea81f4a4cdadb65d89bff4399fce28a200917fffef754fe24b734
+13186717c09a7579cc44b7946d1838026896e2ccc45f41f5b1354f3de87292be
+7e6a7e66626b69c59cb697684023f79f832fee404e3a83bed6aa7376239c326d
+4c30ce5b557e8670fe2ca161d3d28515a89e9d378c6f2b479a93be0584a26d3e
+c35e7a54c2f25589da8f4c0577e177da9564d0a704e1559046299345d7c9f68c
+3ecd1a372bace2ac0321805c103ac438985078a4766b0daf8590e683db158636
+ce4b7c3ea542584d1df38d2d8f0cdb679bd0b5c82423d902ef6f1fcfd746324b
+50128d13ee0f5ac9957188c08b0eb413328ca4f8080d7beaab16cc3aacd51a8f
+03839492b671138f3960de304ffb63286fe91486319e92ad8493045516b4636a
+8e178794903a2252eef2e90806740071b9817742f87e074af21c498fa3f21dbb
+e1b8e3c8146d7973d10dbb2708d5024eba4f333669bccc0a29312420c0dc7138
+463b986f41d8c25950d7ef64a99ffe90f6a3520939de3d0e516a4dc7be23bea4
+74f3fd1c2f2ad8d7ce4c327ffa20710e2bf6c5f815693a5b4025605314f715a3
+9ef8f5a86b7f260c8a6c345840443bc02d700d46bff7ce8667032a952d4063e7
+0dda03de1244830f0ccaadc7062abc6ff41ddc4ed9ca12488904ebed85608c97
+5d0e302df6ebd6c22a5e213d21019ca37446a679eac1bbe0de6317005f955de8
+6b2a301f0c903915981e74f2ef18c4671bec9f12c2595d7f51788d54009c46ea
+e3e1af39badc71cef60d590ca95e47a8f1c53274a7e02c50e21c8bea2001dbf8
+5d787235e5f31bac2d4d489136d9491c83001256948fdcd34eb2da295a775fae
+9e9fccbd0830a99cdc497bdb8cf2adc6bdbb7ff8c150f306e5875378457e79c0
+1a01ff998cc41965862136b37e22ef4d3aa1234bb3419bdc71a43d45f10f879b
+925fe4aa3b48c736f989898c68d3fefcee68ce151a55590d4b1a5312a2558be5
+6066657d53fc820e84fcb162f67de282b513f80d182931c323959377f16c483b
+fb0b65b28215a0dc15dacc09b82551f9a04cba42cdad1dd1aa8871c534e0413b
+5e1dbdd772e4b0eafb21e01a245bfc273b2f8ad00d518dbc35d0ed6ff463c68d
+00165563ec93b156cc00e7f945a8705726c752907283e71ae5bc8e1dd61ca3d6
+dea7fec8928d460243534d16dba851dd77e3176eed0d7b8284718a891a0e8091
+e8525ca038e4a358ba3fbd2089ad33bc7821bf753dbaa23c1708cd6c80fd8e04
+919a230b790ba7e65e2e6c99c6254ce61b1f23466843a12a87d0bb46993d114f
+2cfa18545e813e0f0bcd42fb41ca0bb3843f5324d9f68825c520beb38e34c1aa
+da4aa7c3e03c55fa023b2f4b4d3ae618a14b2b3555de7f2a55a644f2035fa18b
+787abdf31401eef648529e4bd15d9b8e3e3ff5eed76afa2112a32716ca12e39b
+08f6053b68c42944648bbfc34d02af7e6bd35d21127f9fa0a79406f7c2b6d278
+62103da11c6e1cb34512af560b3af2300882fa769716e84a435a9c6cefdcb0be
+e0ce3c9fd5531cd4d66ea9f663889660385423c905663cbbe9bb46838799f9b2
+1d0485547700339b458c605f15f65030e4ab270ae1500e30a133ce0ddefa2190
+23d55a16daf62c8c788432c3b9813865a25edaaa731831ff905bd900434f2d69
+2f8880b60a14c12e99c74bb7550da6b5ce8d2228ac4b44cc7432b1dc58c96e4d
+1f4390a3b6dcba3569110f0d5f98f77289d27feb69b656257aa14edc8bb3c00d
+2da9a4cbbab69bf6ce190c1270be5fc5efc49df45c0b376f081dcfecd80b12e6
+cced2edb8423294bf8886bdba31002f5c673c0ec8772585640feea2a6e17f385
+1cfb1639e697548a5bd849e688ba187bc1b261c60e67cc84a4e5920fb753d5ca
+5db41f5bca801c9cf1daf7b88c866d8c18c117ec29aa7087fc08ac4518eb94f6
+c761bdfae10843c4e6f279d7ffdc2eb36fe38f777745dd255415a9b2bd9c5b7c
+efc7fbebefb52686382f76cfa9b6af9241d1573bcb8e1e7d2243f621380ea522
+a30c94f1b19e21e9f2e4ce61d1597e45aad5e4180b1d7069b7f9f2e9490722f0
+73f8c7dfb9c8f7514d97d18a2f4ad6a49985f7f4d6447bd439a6ed01e198440d
+4b30845005396d3c346450902f88e470141d2cd45b253f8a7fb94342be3f8dfa
+0fb042e016ce042d04f903e36519b2750136b94c1978a66b660e3c79a698abb2
+d7340e9097fc4bd724050ad42cec80696352c3c6e82558361b6421084a509a0c
+40eaddcee7050ca7c43726daacab25ed87ad4c04bfd64047f24d7c8230cba804
+948d06cd0c1aa4fdba32b51f268dc4730b8d65c8b50a4bf0b2a9b43ece574336
+bd1cd5af9a1994f3709aa64583a2cd451e3a787307a84a7a159d34c2dd276b9d
+a351f2751918509502ae9bc0590450916a99ed8b3778d1afed341f0584589c94
+f0dcca7db60869ff3f91493e636c35194d1dc1a396a48bd1f7e724c6ec46db60
+0a4a38ab1535ff3da2c64000dbbe240236143c66cf63742f621896406fcfcd43
+c4822c4d1c80e2f7722fea857c98180318338e1009afcbd10d5b65ecc2796a8c
+14457624bad811cfe85533418fd87f901ae8b760df86e190e0682da9156b7476
+d6b0f81ba0c303e4dcf6607893de4f15b6ff0de435efcf8398dd55f416502d46
+99baaf44e39a29dc7d7c01332922934bb5fc9e5dadf4688f7a997ef9d8deaad3
+035640e40af15329b528ef163ecd867d31d008aae735f7a9498eaf20c4804f27
+a1ced03d39d4ca49791493e0e570e6fa9796e1f9fc79f3f74db5c1ccfa3c53b0
+182c636df0377c95d1d560da832244fdd446df61ed5cb36a2c5336cd59f63d0e
+df7efd374fee9b2d35dc757ad2922bcf7441bb44167fa4c1e47ce46bb63a787a
+90b9377fd9e42548091bae3db4a20bba6c4471dcb335b9b043c318577c96af23
+d046572134d38c2b38fdff6e5eda47689ef58ac2bcc0159d31355d7d063c4bb9
+5cf7a615ba26328a3173163f081c01aef825343386df17f0226890e536fe35c4
+1792b5115f3c92561da144315039f3f03d7eb6f450bb94931ea74ac6455dfe65
+b7c4b4993417f69ee10db426fc86681a697e7dc9abd96b7eac6b9a243cb6bc41
+f38340628ccf7bb442c089beffaa2ef864a31a736bff274ef95ce0cc2a77f695
+edadda05bc61825f4657bc14e579dcf1d05791a1b079cdccf6def41f026d4aeb
+44604cd93e788fde233afd4d26aa71b111e2024e3b271d0e703022f52f635e5a
+371c892ac55cb627caa3f36c14745b5fdf230211e076965f29ce80b102bd0b57
+a0322849da6cf05aa33b10384e32aee2ee65674e554eeac8cc9074b5d71c7988
+929b350b98950f6704c9448f2fdc0e4cd8c2f650be4a1ab53fced3c25a7bee82
+f35fae1c3bfe26407db5e7aceab1cc4b6dc4da552f5cd79ee8d5f068b1fff665
+e6fa41e77db2a0629507bfc547493051d4942405b0f01eb5deaf18dd9ade3631
+184ef75891ce7a1fafda1380d47e55767dd7d3c88baab501cbe0a87352716873
+8137bfb1a91b6c98b52dbadbee01a113655dcb67359a2314099b2866b3261773
+392aebd266a8fb6a11c04f40b345b4382ed8d2a25eabcf4ece87af1900c891aa
+bd5a30cde2f1a0d3be3e5ce534299632521430f12084948a6ae70b75517ff665
+62e9268f2a454f3a10d7e5710f87ab29b96801b4fa815ce8a8acce2ea4404cba
+5ff8b3a56c64ef081a75d664a6206fa341c605683b17d01abbcda227ef3c55a2
+3c56c79194138ea19d3cf3be55ddb73f45d00c4c681b667b8eda54a174968018
+5a5d990820dc716000a49c13d583bc06cff6a8f0f95ba7bb84e8d8673aef8817
+793f4981e1a4f4378958d7388db7ea6c9d1863d153a536a70a229a240aff8194
+e8ac2dcd2ea751a22d00784c7045c2c9d23e5fb214bc817b60425fc3e8a48f31
+e6e8a9342cc134e95c4e59026d9abdfc49900411c4a5d972027ffb7e1662a19c
+56eeb69c9e67040399fd3913ade537cce040b8180c8c9e323a7d6b1e0c7d12f1
+52b135e2e4b589ce34338eff6bd405f1bb1d7ff5c2d7c221bcf320d672fcb97c
+0bcf0649e70bc0f85b0c7462816a69f038e97fd614d97f82cb01d144c0743126
+e8b4b7a34995fbd9d870a22e9ef270926e0fb1f345e3f70f258a45f3c3af6036
+af94b49a7695dfffaba8d00d7c92687ef96b5f268b5ca004d10e38ee997df62a
+cc19ee6387baeff268359df4880fe6a31bd113b4e10464365f31f7a1dd16bf3b
+5fa72f13f53b1a0d61f7ae2e001b475ac61066bed04fcfbaa0dc7aac8dd693f4
+15eed8a4c33b7ae5d845a61c63d382a0b952b0672cccae58110544e7a7329441
+0bb1b2f7283a052228b7da6f5094202c0ed8eb09dbdf2ce10fa5c55cd44a35e7
+085258438bd77317fd7f990c408f4ad2ac594bf9d3f335e505cb3c024381c1bb
+2fb22bac693761ca67bb1b8942103892402f006015466d5cb35492e507018581
+4ff9733b61051f2a0c71269d06af3c2a58bd5449a65a42d008a139c7beaa45ed
+220a233174b00e35c77ee5a5e2995511f17a2eacd575007e666c2e57761e8385
+dba2ef66791e676bdfdc06efac4fbb27ab2ac285295b5ae013026e1bb7938a13
+e1fb9d071ae6f9fe3eb0f3b382695382783fa00c461d622a50ffe6b4651cd059
+c5cf8a359a5a2222b2ae48acea4f258460c8f69283f7e4554d37b18b691815ad
+faab55eabbc37c18ea30eaaf5991d7e06574d94e9b87e631806c1d94ff0b7d78
+701743409efb366d7c405a11819f5472ffcb3f595ec7bf6146d8570caa949cab
+15327fb424c04827148f1793c7041740ce61b521bdb5144e26bfa74be5adb8ca
+b319e3ddd345b30662422673bbbbd23d30e71f6375c29bcd1ec632652f181c68
+efbc2026dae64875e32d6c7d8412c9724b72011f8a6615f972e5d4bd4f92d308
+ef8bb44cd603d22639fcdea9601ac016efd1284e4f899c1f977272926ff61d89
+89fea615693c7ad528befdc4277c2a50f335299cd065418407a0d3698ec60244
+dc7266dbda3270547e90eff22c65e2676a9fae32c088da780b75ea2ddd2bb617
+2eb6b68c19b0435652f8d5d2690a15747d6ee5180654fbee72f84a3051dcd4a4
+eb767370a85995016bac53ab3c0ee44a2e405903e8f6f33c36bf8feb48410d83
+cf3a04681cb878490415f09229bee9ca1d73da791c2c71313cb951713c5e450c
+8482216a71f86f8a541122bea18446797554323764998165bac81b3096796faf
+8538bf83af476e0bbabfa0813feed0dc578814b387a0473badf2da98a5f1a129
+b1385b2e4c9ab79424548e922b91cf56cb3f7a0dca6f4f04ac1ce5d4681d4062
+dc238c93ece3cb0f6c3523d07115a0c7c018a73490d5cdbb1985165ac41b14fe
+de1352571c132e47e16915b04c85e16e57a07fd5aea653ad9491019970546d19
+3caf494886d2c197c8a39bb5ca92348b18ed84814a6fca4b9e07271c13598990
+08c821cf8044a71b89ee6b7c7581e5be5f0167f7f6c39f1e4eae183ac9a5b9da
+9f71945962b981055d138d93acdafe0ff2162eb6e320a55fb6783e4755624762
+0326c12ae49da52f315f90646fa82072fc772a557b777ffbf2cc54c2c2f76b7f
+09531e2890dce9f26157181c69e8fb98d1de277ea3ef5a9653198ca06524ff00
+248413ef8662efd204a4163e39b86c3d7a27f1e81052713179c5a39fea89b5e5
+5f7ddf87911339a827bdef19ab239624e7c0617ec03e0a6fb4fa29fe6e0b05fa
+c50a614158995dfed1235c3b39fa966d848633c5a740632d285edce385929d15
+0d389b43f47da2171ca336cded4a0851470cc086c04a466e4cf03fddb92f9c20
+1f7c732e4a8077527ba27743f9dd4e207b97a1f7cd53778a99f64b092d66f4f9
+1b6a3455a72666386fbc9dd06631a041ae1c63452b5a0480fa75e9a5eeedb8d2
+7bd88740e3d38d5e954d622aacf4342f536ca534cab1e34d352f706b06e04630
+169bc810621d52699cedb96d4796ae1cc28fee4ba7e2223e77faafb9160e3571
+c013b910f1c61fe188625f318ffcc0a10f614d5716e806f14326aad495ea90a4
+4f7bcf589dba538895d4d3da8b5871eeea731f956594bf088a9c4a67794cf661
+ffb389ca93696eb5fb9589aa2c19f43cfeb41cac18b736775017ad51339e5ccf
+de061c17b697242189fe127db52d26407b204a664a4d4ef5428ca588f07d5b3e
+8d19ad7d2437cdafa87353498a304838433dd2b372b15ed83e7969a11f793b58
+40c2d5161aa2f7398f754e2ab2721cfa51915c1795bfdc775012050ac793768b
+960744ec1b1e34a02bd28a03660e0da853be50177e0a22fe9e8355cebf20ee28
+332ac812ab318ab5a391fe54f18fb88d9effdbabffc20ca9a16d9ef29ea37b8d
+5a10f7d36fb1e102528c65f9535683cbe3e31a5d5d1274ec5c7e57042b9b5126
+38015154d7080dc6068f4a5cad76cd02ccce389db91c27d9eeaaeb619569a4da
+f8c6375fd2e2876111e6d481192007eb92f84674583ff8d706e922d31e97178d
+1a0e968e64ceb0a703df1e3de767135b655e569c6fa83e1713b15532205a736f
+cc3899b0df69a87d53a2f065f69988b35cbd395427bc6e6b688cc3d4a11bf0f4
+311b75cfab9955f347a91c8f3245c8fb5555075e8a3d529f33aedba49aaec0c6
+04a19a7bc5ed45f2f09c7548f6f59b933e96350221fb10d2e654e52f508060ac
+b0082531fc830e5f4b059731a81ac8e36a2ad89735ecec3d1c30aea57af5d4da
+a8769c1801f817e4f29c2214ec66d58c3918a9f233133120541f4938c0c8ab6a
+e2dbf3b0deeb140cb17070d75a64e4b41a169534dd99ad8ee635779da4b131be
+e1165e25aa26a2127fdcab0738d769117d8c4b7ee4dcf2caff4e126fa83dd96d
+0373bfcda5e1a920756329ff21cd4445ebda128a491860b193a4d97d5605acb9
+9610029edc11f240a776c45f55997f7d94e5346e1a94d9d8c9ce272d16331f42
+e6158bd248136122b06bf617d6e51977f2ef2ca94fbfbec1ed369ed566da0a3f
+0011484eea81b59772c52834f41208c87b06bcd4dda705404082ccd6280fe7c5
+72e8e5f7279d16bdb543488fdcdbc01e3781c3f2f1343c805c2f5d3b3b5ef19f
+ebc207585693f4ad3b5333260b10a3fd73ae4c496d62bd0abf05f089a89ab658
+aadceec15421d25fbe0c5df76884133b05214e327cf0f6b872bd93160f69435c
+fb012578b281d2d38ba93de5d992574e0ee2f0dad835146f4cec5373b1213fa3
+c8198b7dfbf455d73a7cc6fd50c37b7adcfb6d5c6b5be7c66bbcfe1f58245626
+96a7369a9d01fd31b358cdd12738bc129f571396931b3d14e65866e5881e92c0
+c57ce463d9af9663b21a4c47fe605cd91d220a72d57c5f5217031634e59a7fdc
+784d90821ad69adf1bff61844e9f87bb12576a97d6a658daff1c8dfc6815df7e
+8dc35d4dde5b42c440259bda1f8112756a956aeb85e59da6b13030837403d79b
+726b4cea02e999a2bfdfe58428731cfaddba5504de48dbfc609d7989ebe36b0e
+b4eaa7e5c3f285d51f3898d1b2e8d3e653374014629b506b8b3fc0bcdab045e0
+8a43aa4513e2355dcc5ac7a703c31dcaa61f24213832aca3bbc7e342d7ad27f3
+4152ae1fe6f4e28eba9245faf38fc3266cd5ae400635942efd22f0ff9dca428f
+ce3a8d7d19b8eaa5b36f4e0057b37f83f1b10a83b5d1aab002d6d63bec695e6c
+2b46ffa670650aa4f2dc3578114987faa786de2d6db7e6e6872282d0a86e1b82
+1cfb6be029aebf854dac8c88f35dab7cdd4a9ed0077dc7ba7c39a34df81662c3
+3a5f558328bd31934517e79a53563d330b41105a5329d1fa7053820da39a811d
+74c4a92a9ee3f923a26d86c59a8908b9a042e1981da48642ff2298a9b05a5878
+5566e7be4c0aa5e34759faaefc41dfbbfc3af607411349681b5030e287d0b577
+a3eafa4753e746f1d71fd7a6915f7708cd60d15ecc6ce797ba3798a93265a03a
+874a07745af0df81363002f3aadd88cb95d5fbb6c45fb044e4ce9e09502003d8
+7c4bef2b82b63f91910a0d4ead2f1ea8c8ba01dffbfade76731a8690dd289a7b
+71ed0c03819641772101c6bf4c433ccc585d18f93f26fa41fdffe0ef8294296a
+b9172a28f500fe5b75eef97ee0165ba4a878084ae651784d5de65f5b65cc479b
+04116a57611681eba68c09f82efec26ae0c60ac40424bb0fdc8b987b75875464
+f59dd2e0b62dba0b3fd820cb03f00c2f7babbdf5e24267b9038b45966cb2ff3b
+115ca8b0af271afd2b574a0153eebd04a87ab4b418c6a554682b3d2b5420d0e2
+e23e16ceb4953105df0355be7f31c233af2c0153858030f9fb16e7e9b4795718
+7b436b9788c463c7e8d8ab67a6cad843d27dce5caefedc3a76ec535ec979093e
+723ca8bd8d0234e1f39973064946c79b93fc892e7b24cefce88d099b821a69c7
+7324c9ccf28db4b97f844fdcca54012b142a6f560426674c19839f5d776b29c4
+424979e3a16e398e7a792a5e92a7eee5727b6d033e3f305e204ce370dfe40997
+b7a84f7eb97795b9e243c8fd58ea4cc7371d9ad3949f1c8e9c174cb9af2b0c28
+633cfbce09b4a380aa29e9199e055d891e3d89d5589c5e83e8aa7770220551d1
+b10a88550cf10372add5884010c25359e45c821611a71adeeff841d5d8068918
+68f204fcb9f4c9493c8d91cc039baeb898efc4b5eec85623bfc6fdbf5bce605f
+5c7c618e19ac01c68961d702b17d16d31368a0b7c3bc46c5b6da34a546e31b5b
+c9ed437ae5209c91433d0e8df0021e606294a22edc3a02ece80bbd267bc3a1e4
+1ce2f5272f1db7002aac2a8d7dc2a649c8316662a941f6baf7fb8ee7e86922c2
+75588ff6af85f540bbcc5a380d86e81a37bf88a3c57a8deaed33d274e87720be
+2d99585c5029538b2fee86082598a139ec39ca4e061c137f1ff59cfc69120c28
+3e654ecb7cc48649900801bb329736c7bf21b07ffba69534036cb85dc5f29396
+9ab322e19804863da9c5f0860ebadc5228badb80cfd4e9f31bc0052430e0f3cc
+0b63b1cff9fa9f4467d43262d4f63eeae49ff8d1560ec55a06a3a92fdcf158bd
+5089f8b188d3095666d4aa9679ffebc6786940132d259d42e7153760de7b6adc
+d3e6056db55f124726cb20d0ac763b67c727e9789979882578ef2ae32c8d0a9e
+2e2947f7ba52cf89944a36cd2f2e5dc4a02656202cb49ba081569584a335be14
+9cb5bd5b785123b7cd202158ba98a831edc01d6a461ba2641c07150d3f55b292
+bcf9c69d619746c9fc9d444a6132c5fc9ed2228bef99ca5c7e6dc772f194a1e7
+7a54a8d99c5e665422be3f13bd4e104e69ad02a479ac3c9ff61bb2e74dfa9735
+e80a744cc4d4674c5b33e674eec87362da4012b98ed0e7f05d75073897a40bc8
+d66140db1a850483fdd4606b3110ab5d7a6bb6229a6df028e8c8c62538a85884
+0abd25dcc84bfe9d13fe4ef567165eb72e0e246826cc67d0f35bcec135c2d4f7
+433f278e9948eb91b30f0c11de38e1c9b7484c5e3970b09d37334df686c704b7
+77fe267a0ce2ad7a5887e5dff00640e3f619dfcab32fbc28192876018f4fa492
+b2ed5983a9a1325acc22366a8c5c94412d26b75eee6a2bd08d3d2d9247d0673b
+59e680ad1d3432849a695c8910b686533f3bd7d64c3fa3e9ccd76475b4e2d079
+0b9e58f792d619b0cc48defcf09cd6855293975b75e38847041662a1899686b7
+74d2bbeaeab5431d53aa8c380a57703a21c1306472c4420d33076c25a2bd2710
+cd7cbe3616afe747a410e03387ff9c5951a89c8818af2879d95d74c5c0734c5a
+c84218c219a639ad2e8329e55f6d339c03c64452aaab6608a0829f6979a745ac
+d351cdc8b67f351549aa6df608197e0eb65718f47b5513bbfbad13a5e32adcd4
+e7869dcfd53b918282c5916f756f6e8eac46cf58f5e9de2d073a4bdd54a54d0b
+f2f4a61432c62430c1f9eb783018d1c7be62df2514f562f3a285e9584819c8da
+91e15749bd71197cd549ef0f89638f560f42a3e02a9dc69a93da820d3748b983
+b1409f29e499401bd76037e195f9c50895b1034089d2bf6fa736591ef5cad597
+836512b623f94e85907d7706b8e3c0686b93432e3d3bf7f42c98de62ad150fdf
+ee1569f3d3b8aad8fe31f00fed1c767736e9dc189d1ef18979d1725538b060bb
+2dac78c707f717a0ecf9bb9f222ef8aff9fda74c4f07ea07b6f52d8b3bc3f02d
+763abd9b9bb4305f4707fcd03750e033d502e9e69bbc3db91f4fc1ab9356f1e8
+b66649370d6e1099250e0638d0b5688bfff1bb8dc7ea038a7163502eee800e53
+a1bda9971e2ac70b7489492bafa8ef42dfe4851f9f1cc7c2c95a40ab25db455c
+12b42cb94aebc3b1b3d7cabdbef637205ec1dec48bf04fe2c86c3f41ff127108
+9d8e5c37f7d406d743962f7fe013149b4c1291d9573a544f2bc8e2fea78fb276
+c5ea8cd6583182ee34fcd8ccdc4dbb7273f848b2c2005dae6e43f99086dd21b1
+0756bb1258696753248513daeaff92bfeaae1eabe8c063491a5fd6c00e1f445c
+cc1ec75c816d6d27e62bc657ed551328c3b85afcd1ca9b09d00373f0053ff68c
+97605c183bf8c30a2bfed48a3245ef6b584398f62024642832c88f24a24d3a01
+be6f512b9c3623843d388c792bc4add0805343713d7535f6a1d03d4a2fce724a
+b91c4977150914ad0a34fef0addb71980c0a764375d91b86e9f379c438562dcf
+11686d0794d26b07d4c59febaff8a93c43946d987e6c4b6ad650c932cd595fa5
+a2b46b2802463c70449af8e61fa30c6e83c748a33be7d81476376064716e3197
+f8703d525f95c6a2ddae5b66a9561d8b1440915286c30c345f599ac82fdd1a12
+a5be554ec240b610383f34d85a1ed94466ee7c0cd5cc1676570a73ac9c6d80df
+f71c2b487882da466f9a08a2cd963653dc67957514976be58d40a12e9ff9962e
+3407c304c750f81a7bfb458a44dcd8a04f8742c8d7ad67b9bc8e4fb9bd425abe
+af4a2714d56d23dd7fe79d99c5d935b2b97d82415e55f326135fcf51db7e4a81
+8e6177e53ce48a628514e93ad45782277eeb78f5dbb51908db22e74825d31478
+f4a9f5ecd373d6f4fda7b89dcc1d124c3d09265a8835ef1b36c31cb078b4de28
+3435ae9df3477504a90b52a788093f0ee924d382b380295faba3c35f56b8f46b
+0bfbe880af354d949dc30f0869b9ccb3f194782f4f784c37b79f575ed5dbb38a
+d3819a668e204d528f6d6e05ba0a45371f7656c6d1be0aff866f9fa6a8ce5654
+fa485ab31cf114a531b1b674371119eb36ccba3350c58ec35af3c410c393f0a5
+d6c2149856ddaf28ed279ef64a66a77297f131a9981ca618b5941f28af7ee370
+30a59da5e4175b5806a786d4981081b31d306b96f4c7a54e024ea32b8892b12b
+6161f3c880242602476dff9070e24a364d40e9a5fde87b26535e9f892c778c50
+98e10efa0b5b661971a3a018028789a71b363c7a62ed0944b0c2cbba0c79e4bb
+9f7a05b1dc1fcc278e2546201c9d23ba42d67d68d1f4614b3735cbd6f50dc46f
+8172cb5d3b6d099e43499c2c0b14c58aecacf63b00a58204f99026dc45994d28
+6de59019e2275322d4ce46ebe5ed630489886160a2bf9a7099abb49a864a6e0b
+a9446b97ed62b61926520d26201f31a803e4bbd8c9bf89d154f3005950dd5721
+e7d1ccd7982ca0beca6a8cd2dcae488fd9edea9f09ecacc6b430ad9e644bfd94
+f43177ef3eaca6f2b22ed5c1f61657102792f438a6a8bcc721cf54d445ae5973
+ed53eef181537f66fe15498f408fce30eb7348a97857391ab7532865f48f7240
+5040adf2af45da7b6f5b03d8a37a94a2647936865b470ecd43dc0d4d72269950
+f0a668b72e6001519f6934380b80a2758686d4f99a618fc4bb61abbb58eddd87
+7bc4f0aabd28d596fb613ccffb0f26a75e53a7c7fd432754422538424fdbd636
+be60414dbede5fa639eeca055c7d0d0f80a121c24f3b2402f98ac91dea0d06de
+0e1faab1c2e4ce5172a48a417c210c2ee4619edcadc89c4b69aec28c8b2efb81
+e37a006366876e99eaa815b69837baa67778e5e359fd316570fb52880a9ca629
+97dd0dbf406138783d84792cf7616dbf2c7a31825aa33670c6bdec650ca2698c
+5c8546a3966159d66473b07c4c99f2d48c95238ad5352a1cb2f06afdd953475a
+4e5dda657bb5f5f834b29b30fc9d9aee7f4d8797dcee9a35cfeb066d8317fb4a
+41924f4a2e65cea7cb1fa8114e9e31c4be6847b0547b9712df4cdcf490709df9
+e76cb3fd933b03b8b7c786790c6ed880458500a3c66ae48306a3dacce3fc1663
+b0d7e2850a7d9d22c4e2b183ec58bfbf818b4fb7717ae53cf58d9b52020c02af
+1686682b215aae195d6c82abf3d27a82a28b2a580a79c88ea264b478196848b3
+f8789685914564daec64c7798d8ceca706aecdbdf57ad457eb1b5058dd8d081b
+b125ecd5b6c8cd541f4fe62c9c48a708df183f53b8ee3d1226bb909492ba6878
+e837627727fa290c2e9296f29991a366a2977ef4ee9c1b9a4635b424b78b0a92
+eea383038fd13201bf9724313c7bef7f3f86a6b854375077625cfd5c90de6f49
+c8f7a0da7c5f31b611ecabb893e90a470ca1bfced8b4b34c757869d0778a4934
+2a73cf77653d660d6815e3fe282d9d172522f351c58ee095b7dcdf3196b59c39
+20309447c3dc2e1679ca39c9efc65b587f0e4c879c8542869bee1ef90f562fb8
+02323011b77fd8e079009aabd0011f382de66d9cd74a581b8810251482c985ec
+af0ca59367f51819c4532af37a5bd5926744b46a03f43da0560bd0eead27310e
+3a3e522593a807ad4b8f800960f78894cb757e82f3476a2724d0ae623f5460f1
+67bf93d0b305322dca45e038a56b299c7ed6dff66fd747bfa55947b9ecb485db
+681af9d82546e9096ae4d6172dcf0aff907642ef8d57ea3f84921041b8a29c94
+d5a8e867bb5d85576e08324ed1c18b9384fb2c0f5fa5aa87f48d4f2f6f2ed3ac
+0cdadc949455fce9165d5e5f5bc4bf4d6314ae8ab1708d2774f95a808ac809fe
+565d77765add2900affc
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/gs/examples/chess.ps b/gs/examples/chess.ps
new file mode 100644
index 000000000..3200f1eab
--- /dev/null
+++ b/gs/examples/chess.ps
@@ -0,0 +1,101 @@
+%!PS-Adobe-2.1
+%%% HOW TO USE: from Unix, "cat Cheq Example | lpr -Pprintername "
+%%Title: Cheq.cheqtxtx
+%%Creator: Glenn Reid and still.ps (V 1.0d release 10 edit 08)
+%%BoundingBox: (atend)
+%%Pages: (atend)
+%%DocumentProcSets: Adobe_distill 0.95
+%%EndComments
+%%BeginProcSet: Adobe_distill 0.95
+/PROLOGUE 30 40 add dict def
+ % 30 procedure entries + room for 40 cached font dictionaries
+ PROLOGUE begin
+ /clip { } def % causes problems. remove if "clip" is needed
+ /bdef { bind def } bind def /ldef { load def } bdef
+ /T { moveto show } bdef /A { moveto ashow } bdef
+ /W { moveto widthshow } bdef /AW { moveto awidthshow } bdef
+ /f /fill ldef /R { { rlineto } repeat } bdef
+ /r /rlineto ldef /L { { lineto } repeat } bdef
+ /m /moveto ldef /l { moveto lineto stroke } bdef
+ /x { 0 rlineto } bdef /y { 0 exch rlineto } bdef
+ /c /curveto ldef /cp /closepath ldef
+ /s /stroke ldef /w /setlinewidth ldef
+ /g /setgray ldef /j /setlinejoin ldef
+ /d /setdash ldef /F /setfont ldef
+ /C /setcmykcolor where { /setcmykcolor get }{ %ifelse
+ { %def
+ 1 sub 3 { 3 index add neg dup 0 lt { pop 0 } if 3 1 roll } repeat
+ setrgbcolor
+ } bind
+ } ifelse def
+ /MF { findfont exch makefont setfont } bdef
+ /DF { findfont exch scalefont setfont currentfont def } bdef
+ /BEGINPAGE { pop /pagesave save def } bdef
+ /ENDPAGE { pop pagesave restore showpage } def
+ /REMAP { %def
+ FontDirectory 2 index known { pop pop pop } { %ifelse
+ findfont dup length dict begin
+ { 1 index /FID ne {def}{pop pop} ifelse } forall
+ exch dup length 0 gt { /Encoding exch def }{ pop } ifelse
+ currentdict end definefont pop
+ } ifelse
+ } bdef
+ /RECODE { %def
+ 3 -1 roll 1 index findfont /Encoding get 256 array copy exch
+ 0 exch { %forall
+ dup type/nametype eq
+ { 3 {2 index} repeat put pop 1 add }{ exch pop }ifelse
+ } forall pop 3 1 roll REMAP
+ } bdef
+ end %PROLOGUE
+%%EndProcSet: Adobe_distill 0.95
+%%EndProlog
+%%BeginSetup
+PROLOGUE begin
+
+%%EndSetup
+%%Page: 1 1
+%%PageFonts: (atend)
+%%PageBoundingBox: (atend)
+
+
+%%%%%% Following line added by Aladdin Enterprises:
+%%%%%% load the font explicitly so it doesn't have to be in Fontmap.
+(cheq.ps) run
+
+
+1 BEGINPAGE
+1 1 1 0 C
+/F1 12 /Times-Roman DF
+(Cheq \(gift of Adobe Systems\) "Chequed Board")
+72 756 T
+(p. 1)
+558 756 T
+/F2 30 /Cheq DF
+
+
+%%%%%% Following line added by Aladdin Enterprises:
+%%%%%% scale up and relocate the image.
+-140 -800 translate 2 2 scale
+
+
+( ________) 72 714 T
+(/R\366B\316K\365N\345\\) 72 684 T
+(/\270P\270P\270P\270P\\) 72 654 T
+(/ x x x x\\) 72 624 T
+(/x xQ\360 x \\) 72 594 T
+(/ x x x x\\) 72 564 T
+(/x x \317kx \\) 72 534 T
+(/p\271p\271p\271p\271\\) 72 504 T
+(/\250n\272q\373b\265r\\) 72 474 T %%%%%% 277??
+( --------) 72 444 T
+2 ENDPAGE
+%%PageTrailer
+%%PageFonts: Times-Roman Cheq
+%%PageBoundingBox: 20 20 576 756
+%%Trailer
+end %PROLOGUE
+%%Pages: 1
+%%BoundingBox: 20 20 576 756
+%%DocumentFonts: Times-Roman Cheq
+%%EOF
diff --git a/gs/examples/colorcir.ps b/gs/examples/colorcir.ps
new file mode 100644
index 000000000..27b07e01b
--- /dev/null
+++ b/gs/examples/colorcir.ps
@@ -0,0 +1,122 @@
+%!
+
+gsave
+/Times-Roman findfont 24 scalefont setfont
+72 72 translate 0 0 moveto 1 0 0 setrgbcolor (Red) show
+72 0 translate 0 0 moveto 0 1 0 setrgbcolor (Green) show
+72 0 translate 0 0 moveto 0 0 1 setrgbcolor (Blue) show
+72 0 translate 0 0 moveto 1 1 0 setrgbcolor (Yellow) show
+72 0 translate 0 0 moveto 1 0 1 setrgbcolor (Pink) show
+72 0 translate 0 0 moveto 0 1 1 setrgbcolor (Cyan) show
+72 0 translate 0 0 moveto 0.9 0.9 0.9 setrgbcolor ('White') show
+grestore
+
+0.0 setlinewidth
+
+/length 0.1 def
+/width 0.02 def
+/hsvcircle {
+gsave
+ /h 0.0 def
+ 0 4 360 {
+ pop
+ gsave
+ 0.5 0.0 translate
+
+ newpath
+ 0.0 0.0 moveto
+ length 0.0 lineto
+ length width lineto
+ 0.0 width lineto
+ closepath
+ h 1.0 1.0 sethsbcolor
+ fill
+
+ %newpath
+ %0.0 0.0 moveto
+ %length 0.0 lineto
+ %length width lineto
+ %0.0 width lineto
+ %closepath
+ %0.0 setgray
+ %stroke
+
+ grestore
+ /h h 4 360 div add def
+ 4 rotate
+ } for
+grestore
+} def
+
+/graycircle {
+gsave
+ /h -1.0 def
+ 0 4 360 {
+ pop
+ gsave
+ 0.5 0.0 translate
+
+ newpath
+ 0.0 0.0 moveto
+ length 0.0 lineto
+ length width lineto
+ 0.0 width lineto
+ closepath
+
+ h abs setgray
+ fill
+
+ %newpath
+ %0.0 0.0 moveto
+ %length 0.0 lineto
+ %length width lineto
+ %0.0 width lineto
+ %closepath
+ %0.0 setgray
+ %stroke
+ grestore
+
+ /h h 8 360 div add def
+ 4 rotate
+ } for
+grestore
+} def
+
+0.0 setlinewidth
+0.0 setgray
+300 400 translate
+500 500 scale
+
+30 rotate
+1.0 0.7 scale
+-30 rotate
+
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+0.8 0.8 scale
+hsvcircle
+0.8 0.8 scale
+graycircle
+
+showpage
diff --git a/gs/examples/escher.ps b/gs/examples/escher.ps
new file mode 100644
index 000000000..c17bf0f4b
--- /dev/null
+++ b/gs/examples/escher.ps
@@ -0,0 +1,379 @@
+%!
+% If you're concerned that the cpu in your PostScript printer will atrophy
+% from disuse, here is another Escher-like contribution to to keep it busy
+% for a while. It uses PostScript color commands, but will still work on
+% a monochrome printer (but isn't very pretty in black & white).
+%
+% The butterflies are arranged in a hexagonal grid (wallpaper group p6),
+% and the moveto, lineto, curveto commands used to render the tesselation
+% are redefined so as to impose a nonlinear transform that shrinks the
+% infinite plane to an ellipse. This is a sleazy way to mimic Escher's
+% "circle limit" sorts of things.
+%
+% The butterfly permimeter was made by imposing all the symmetry constraints
+% on a path, and then that path was filled in using Adobe Illustrator
+%
+% The routines Xform and next_color are easy to change if you want to hack
+% with them. The code was written to sacrifice efficiency for readability.
+%
+% Bob Wallis
+%
+% UUCP {sun,pyramid,cae780,apple}!weitek!wallis
+
+%statusdict begin waittimeout 6000 lt % if you have a slow printer, you
+% {0 60 6000 setdefaulttimeouts} % might need to uncomment this
+%if end
+
+/nlayers 1 def % 1 takes about 10 minutes on a LW+; 2 takes 4x longer
+/warp 1 def % 1 -> ellipsoidal distortion; 0 -> flat Euclidean
+/inch {72 mul} def
+
+/x4 152 def /y4 205.6 def % 6 fold rotation center of bfly
+/x12 387.20 def /y12 403.84 def % 3 fold center of bfly
+
+/dx x4 x12 sub def % [dx,dy] = distance between the
+/dy y4 y12 sub def % two fixed points above
+
+/Dm dx dup mul dy dup mul % magnitude of basis vectors of
+ add sqrt 3 sqrt mul % parallelogram lattice
+def % = |dx,dy| * sqrt(3)
+
+/Da dy dx atan 30 add def
+/D1x Dm Da cos mul def % [D1x, D1y] = basis vector vector #1
+/D1y Dm Da sin mul def % = [Dm,0] exp(j30)
+
+/Da dy dx atan 30 sub def
+/D2x Dm Da cos mul def % [D2x, D2y] = basis vector vector #2
+/D2y Dm Da sin mul def % = [Dm,0] exp(-j30)
+
+/m { moveto} def
+/L {lineto} def
+/S {stroke} def
+/c {curveto} def
+/f {closepath fill} def
+/F {closepath fill} def
+/g { setgray} def
+
+/FillStroke { % fill interior & stroke black border
+ closepath gsave fill grestore 0 setgray stroke
+} def
+
+%
+% Description of 1 butterfly
+%
+/body {
+ 314.96 280.19 m
+ 383.4 261.71 445.11 243.23 513.52 224.68 c
+ 463.68 256.59 490.26 328.83 446.99 360.76 c
+ 423.71 347.32 397.08 339.7 367.07 337.9 c
+ 388.93 358.28 414.14 372.84 442.73 381.58 c
+ 426.68 398.18 394.07 389.7 387.2 403.84 c
+ 371.52 404.96 362.56 372.48 340.16 366.88 c
+ 346.88 396.01 346.88 425.12 340.16 454.24 c
+ 326.72 427.35 320 400.48 320 373.6 c
+ 270.71 352.1 221.44 411.23 168.88 384.02 c
+ 189.04 388.03 202.48 380.4 212.57 366.95 c
+ 216.72 350.85 209.23 341.46 190.1 338.79 c
+ 177.34 343.57 167.94 354.17 161.9 370.59 c
+ 176.06 305.52 132.02 274.05 152 205.6 c
+ 201.29 257.12 250.56 234.72 299.84 279.52 c
+ 288.64 266.08 284.16 252.64 286.4 239.2 c
+ 298.27 223.97 310.15 222.18 322.02 233.82 c
+ 328.62 249.28 328.51 264.74 314.96 280.19 c
+ FillStroke
+} def
+
+/eyes {
+ 294.8125 238.3246 m
+ 296.9115 238.3246 298.6132 242.7964 298.6132 248.3125 c
+ 298.6132 253.8286 296.9115 258.3004 294.8125 258.3004 c
+ 292.7135 258.3004 291.0118 253.8286 291.0118 248.3125 c
+ 291.0118 242.7964 292.7135 238.3246 294.8125 238.3246 c
+ closepath gsave 1 g fill grestore 0 g S
+
+ 319.5 241.1782 m
+ 321.7455 241.1782 323.5659 245.4917 323.5659 250.8125 c
+ 323.5659 256.1333 321.7455 260.4468 319.5 260.4468 c
+ 317.2545 260.4468 315.4341 256.1333 315.4341 250.8125 c
+ 315.4341 245.4917 317.2545 241.1782 319.5 241.1782 c
+ closepath gsave 1 g fill grestore 0 g S
+ 0 g
+ 296.875 242.0939 m
+ 297.4608 242.0939 297.9356 243.479 297.9356 245.1875 c
+ 297.9356 246.896 297.4608 248.2811 296.875 248.2811 c
+ 296.2892 248.2811 295.8143 246.896 295.8143 245.1875 c
+ 295.8143 243.479 296.2892 242.0939 296.875 242.0939 c
+ f
+ 0 g
+ 318.5 243.7707 m
+ 319.281 243.7707 319.9142 245.0766 319.9142 246.6875 c
+ 319.9142 248.2984 319.281 249.6043 318.5 249.6043 c
+ 317.719 249.6043 317.0858 248.2984 317.0858 246.6875 c
+ 317.0858 245.0766 317.719 243.7707 318.5 243.7707 c
+ f
+} def
+
+/stripes {
+ 292 289 m
+ 252 294 241 295 213 279 c
+ 185 263 175 252 159 222 c
+ S
+ 285 313 m
+ 239 326 226 325 206 315 c
+ 186 305 164 278 161 267 c
+ S
+ 298 353 m
+ 262 342 251 339 237 355 c
+ 223 371 213 380 201 383 c
+ S
+ 330 288 m
+ 384 293 385 292 418 280 c
+ 451 268 452 264 473 247 c
+ S
+ 342 306 m
+ 381 311 386 317 410 311 c
+ 434 305 460 287 474 262 c
+ S
+ 345 321 m
+ 352 357 359 367 379 377 c
+ 399 387 409 385 426 382 c
+ S
+ 327.75 367.75 m
+ 336.5 392.25 333.682 403.348 335.25 415.5 c
+ S
+ 320 364.75 m
+ 322 361.75 323.5 360.5 326.25 360 c
+ 329 359.5 332 360.5 334 362.75 c
+ S
+ 316.25 356.5 m
+ 318.75 353.25 320 353 323.25 352.25 c
+ 326.5 351.5 329 352 331.5 353.25 c
+ S
+ 312.5 349 m
+ 316.75 345.5 318.25 344.5 321.25 343.75 c
+ 324.25 343 327 344 329.75 346 c
+ S
+ 310.75 340.75 m
+ 314.25 336.5 316.25 335.25 320 335.25 c
+ 323.75 335.25 327 336.5 329.25 338 c
+ S
+ 308.5 332 m
+ 311.75 328.5 312.5 327.25 317 327 c
+ 321.5 326.75 325.75 328.25 327.75 329.75 c
+ S
+ 305 322 m
+ 309.5 317.75 310.75 317 315 316.5 c
+ 319.25 316 322.25 318 324.75 320 c
+ S
+ 302.25 311 m
+ 307 307.5 307.75 306.25 312.75 306 c
+ 317.75 305.75 320 307.25 323.75 309.5 c
+ S
+ 301.25 298.25 m
+ 304.5 292.75 305.25 292 308.25 292 c
+ 311.25 292 313.75 293.75 315.75 295.75 c
+ S
+} def
+/nostrils {
+ 0 g
+ 304.062 227.775 m
+ 304.599 227.775 305.034 228.883 305.034 230.25 c
+ 305.034 231.616 304.599 232.724 304.062 232.724 c
+ 303.525 232.724 303.09 231.616 303.09 230.25 c
+ 303.09 228.883 303.525 227.775 304.062 227.775 c
+ f
+ 304.062 230.25 m
+ F
+ 309.562 228.275 m
+ 310.099 228.275 310.534 229.383 310.534 230.75 c
+ 310.534 232.116 310.099 233.224 309.562 233.224 c
+ 309.025 233.224 308.59 232.116 308.59 230.75 c
+ 308.59 229.383 309.025 228.275 309.562 228.275 c
+ f
+} def
+/thorax
+{
+ 327.5 300 m
+ 316.5 283 315.5 275.5 308 277.5 c
+ 294 311.5 299 313.5 304 334 c
+ 309 354.5 315.5 362 322.5 372 c
+ 329.5 382 327.5 376.5 331 376 c
+ 334.5 375.5 339.1367 379.1109 339 369 c
+ 338.5 332 333.4999 324.5 330.5 311.5 c
+ 0 g S
+} def
+/spots {
+ next_color
+ 192 242.201 m
+ 202.1535 242.201 210.3848 251.0655 210.3848 262 c
+ 210.3848 272.9345 202.1535 281.799 192 281.799 c
+ 181.8465 281.799 173.6152 272.9345 173.6152 262 c
+ 173.6152 251.0655 181.8465 242.201 192 242.201 c
+ FillStroke
+ next_color
+ 447.5 250.2365 m
+ 459.6061 250.2365 469.4203 257.5181 469.4203 266.5 c
+ 469.4203 275.4819 459.6061 282.7635 447.5 282.7635 c
+ 435.3939 282.7635 425.5797 275.4819 425.5797 266.5 c
+ 425.5797 257.5181 435.3939 250.2365 447.5 250.2365 c
+ FillStroke
+ next_color
+ 401 369.1005 m
+ 409.5914 369.1005 416.5563 373.5327 416.5563 379 c
+ 416.5563 384.4673 409.5914 388.8995 401 388.8995 c
+ 392.4086 388.8995 385.4436 384.4673 385.4436 379 c
+ 385.4436 373.5327 392.4086 369.1005 401 369.1005 c
+ FillStroke
+ next_color
+ 249 348.2721 m
+ 261.4966 348.2721 271.6274 353.9707 271.6274 361 c
+ 271.6274 368.0293 261.4966 373.7279 249 373.7279 c
+ 236.5034 373.7279 226.3726 368.0293 226.3726 361 c
+ 226.3726 353.9707 236.5034 348.2721 249 348.2721 c
+ FillStroke
+} def
+
+/ncolor 6 def
+/cidx 0 def
+
+/next_color {
+ cidx ncolor div % hue
+ .75 % saturation (change these if you like)
+ .8 % lightness
+ sethsbcolor
+ /cidx cidx 1 add ncolor mod def
+} def
+
+/cidx 0 def
+
+/max_r2 % radius^2 for center of outermost ring of butterflies
+ Dm nlayers mul 1.05 mul dup mul
+def
+
+/max_radius max_r2 sqrt def
+/max_radius_inv 1 max_radius div def
+/Dm_inv 1 Dm div def
+
+%
+% Ellipsoidal distortion, maps "nlayers" concentric rings of cells into
+% an ellipse centered on page
+
+% D length of 1 basis vector separating hexagonal cells
+% z0 center of 6-fold rotation = origin of shrink xform
+% z' = (z - z0)/D new coord system
+% |z'| = sqrt(x^2 + [(8.5/11)*y]^2) aspect ratio of paper
+% z" = z' * a/M(|z'|) shrink by "a/M(|z|)" as fcn of radius
+
+% At the max radius, we want the shrunk ellipse to be "W" units wide so it
+% just fits our output format - solve for scale factor "a"
+
+% zmax = n+0.5 for n layers of cells
+% zmax * [a/M(zmax)] = W 1/2 width of output on paper
+% a = M(zmax)*W/zmax solve for "a"
+
+%/M{dup mul 1 add sqrt}bind def % M(u) = sqrt(1+|u|^2) = one possible shrink
+/M { 1.5 add } bind def % M(u) = (1.5+|u|) = another possible one
+/W 3.8 inch def % 1/2 width of ellipse
+/zmax 0.5 nlayers add def % radius at last layer of hexagons
+/a zmax M W mul zmax div def % a = M(zmax)*W/zmax
+
+/Xform { % [x0,y0] = ctr ellipse
+ Matrix transform
+ /y exch def
+ /x exch def
+ /z x dup mul y .773 mul dup mul add sqrt def % ellipse radius
+ /Scale a z M div def % z=a/M(|z|)
+ x Scale mul x0 add % magnify back up
+ y Scale mul y0 add % [x0+x*s, y0+y*s]
+} def
+
+
+/Helvetica findfont 8 scalefont setfont
+4.25 inch 0.5 inch moveto
+(RHW) stringwidth pop -0.5 mul 0 rmoveto
+(RHW) show % autograph
+
+warp 1 eq { % redefine commands to use Xform
+ /moveto { Xform //moveto} def
+ /lineto { Xform //lineto} def
+ /curveto {
+ Xform 6 -2 roll
+ Xform 6 -2 roll
+ Xform 6 -2 roll
+ //curveto
+ } def
+}if
+
+
+/bfly { % paint 1 butterfly
+ next_color body
+ 1 setgray eyes
+ stripes
+ 0 setgray nostrils
+ 0.5 setgray thorax next_color
+ spots
+} def
+
+/x0 x4 def % center
+/y0 y4 def
+
+/T1matrix % xlate to center of image
+ x0 neg y0 neg matrix translate
+def
+
+/Smatrix % scale so that 1 basis vector = 1.0
+ Dm_inv dup matrix scale
+def
+
+/HexCell { % 6 butterflys rotated about center of
+ /cidx 0 def % 6 fold symmetry
+ /color 0 def
+ /T2matrix dx dy matrix translate def
+ 0 60 300 {
+ /angle exch def
+ /Rmatrix angle matrix rotate def
+ /Matrix % translate, rotate, scale - used by Xform
+ T1matrix Rmatrix matrix concatmatrix
+ T2matrix matrix concatmatrix
+ Smatrix matrix concatmatrix
+ def
+ gsave
+ warp 0 eq % then may use usual PostScript machinery
+ { % else using Xform
+ x0 y0 translate angle rotate
+ .5 dup scale
+ dx x0 sub dy y0 sub translate
+ } if
+ bfly
+ next_color
+ grestore
+ } for
+} def
+
+
+%320 x4 sub 240 y4 sub translate
+4.25 inch x4 sub 5.5 inch y4 sub translate
+
+
+0 setlinewidth
+/N 2 def
+N neg 1 N {
+ /i exch def % translate to
+ N neg 1 N { % i*D1 + j*D2
+ /j exch def % and draw HexCell
+ gsave
+ /dx i D1x mul j D2x mul add def % translate HexCell by
+ /dy i D1y mul j D2y mul add def % [dx,dy]
+ /r2 dx dup mul dy dup mul add def % r^2 = |dx,dy|^2
+ r2 max_r2 lt % inside radius?
+ { % yes
+ 1 r2 max_r2 div sub sqrt 2 div
+ setlinewidth % make skinnier lines
+ HexCell % 6 butterflies
+ }
+ if
+ grestore
+ } for
+} for
+
+showpage
diff --git a/gs/examples/golfer.ps b/gs/examples/golfer.ps
new file mode 100644
index 000000000..930f777de
--- /dev/null
+++ b/gs/examples/golfer.ps
@@ -0,0 +1,1398 @@
+%!PS-Adobe-2.0 EPSF-1.2
+%%Creator:Adobe Illustrator(TM) 1.0b2-
+%%Title:golfer art+
+%%CreationDate:1/6/87 9:32 AM
+%%DocumentFonts:Helvetica-Bold
+%%BoundingBox:7 31 577 726
+%%TemplateBox:0 -48 576 672
+%%EndComments
+100 dict begin
+/q{bind def}bind def
+/Q{load def}q
+/x{exch def}q
+/X/def Q
+/g{/_g x/p{_g setgray}X}q
+/G{/_G x/P{_G setgray}X}q
+/k{/_b x/_g x/_r x/p{_r _g _b setrgbcolor}X}q
+/K{/_B x/_G x/_R x/P{_R _G _B setrgbcolor}X}q
+/d/setdash Q
+/i/setflat Q
+/j/setlinejoin Q
+/J/setlinecap Q
+/M/setmiterlimit Q
+/w/setlinewidth Q
+/_C{.25 sub round .25 add}q
+/_c{transform _C exch _C exch itransform}q
+/c{_c curveto}q
+/C/c Q
+/v{currentpoint 6 2 roll _c curveto}q
+/V/v Q
+/y{_c 2 copy curveto}q
+/Y/y Q
+/l{_c lineto}q
+/L/l Q
+/m{_c moveto}q
+/_e[]X
+/_E{_e length 0 ne{gsave 1 g 0 G 1 i 0 J 0 j .5 w 10 M[]0 d
+/Helvetica-Bold 24 0 0 1 z
+[0.966 0.259 -0.259 0.966
+_e 0 get _e 2 get add 2 div _e 1 get _e 3 get add 2 div]a
+(ERROR: can't fill a path)t T grestore}if}q
+/n/newpath Q
+/N/newpath Q
+/F{p{fill}stopped{/_e[pathbbox]X n _E}if}q
+/f{closepath F}q
+/S{P stroke}q
+/s{closepath S}q
+/B{gsave F grestore S}q
+/b{closepath B}q
+/u{}q
+/U{}q
+/_s/ashow Q
+/_S{(?)exch{2 copy 0 exch put pop dup true charpath currentpoint _m setmatrix
+stroke _M setmatrix moveto 3 copy pop rmoveto}forall pop pop pop n}q
+/_A{_a moveto _t exch 0 exch}q
+/_L{0 _l neg translate _M currentmatrix pop}q
+/_w{dup stringwidth exch 3 -1 roll length 1 sub _t mul add exch}q
+/_z[{0 0}bind{dup _w exch neg 2 div exch neg 2 div}bind
+{dup _w exch neg exch neg}bind]X
+/z{_z exch get/_a x/_t x/_l x exch findfont exch scalefont setfont}q
+/_d{matrix currentmatrix X}q
+/_D{/_m _d gsave concat/_M _d}q
+/e{_D p/t{_A _s _L}X}q
+/r{_D P/t{_A _S _L}X}q
+/a{_D/t{dup p _A _s P _A _S _L}X}q
+/o{_D/t{pop _L}X}q
+/T{grestore}q
+/Z{findfont begin currentdict dup length dict begin
+{1 index/FID ne{X}{pop pop}ifelse}forall/FontName exch X dup length 0 ne
+{/Encoding Encoding 256 array copy X 0 exch{dup type/nametype eq
+{Encoding 2 index 2 index put pop 1 add}{exch pop}ifelse}forall}if pop
+currentdict dup end end/FontName get exch definefont pop}q
+n
+%%EndProlog
+u
+0.9 g
+0 G
+1 i
+0 J
+0 j
+1 w
+10 M
+[]0 d
+%%Note:
+15.815 40.248 m
+567.815 40.002 L
+567.748 716.565 L
+15.998 716.81 L
+15.815 40.248 L
+b
+U
+1 g
+285.313 40 m
+567.688 40.125 L
+567.812 78.375 L
+285.312 78.25 L
+285.313 40 L
+b
+0 g
+175.5 163 m
+180.007 163 173.738 169.081 171.75 168.75 c
+174.75 169.25 176.25 169.5 174.5 171.25 C
+178 171.25 176.349 173.783 175 176.75 c
+173.75 179.5 170.75 182.25 168.25 182 C
+165.5 181.25 167.622 182.838 165.25 186 c
+164.5 187 164.75 187.5 161.75 186.75 c
+158.75 186 163.25 190 156.75 190 c
+150.25 190 148.5 189 145.5 186 c
+142.5 183 139.75 183.75 139.5 182.5 c
+139.25 181.25 139.5 176.75 138.75 175.5 c
+138 174.25 136.75 174.25 136.25 178 c
+135.75 181.75 140.25 182.25 134 187 C
+135.75 190.75 134.5 191.75 131 193.5 C
+131 200 129.202 203.364 119.5 208.5 c
+115.25 210.75 107 212.75 104.75 208.75 c
+102.5 204.75 103 206.5 96.5 205.75 c
+90 205 87.25 202.5 86.5 197.75 c
+85.75 193 82.75 195 79 194.75 c
+75.25 194.5 77 192.75 77.25 191.75 c
+77.5 190.75 75.25 192.5 71.5 192 c
+67.75 191.5 64.25 185.5 69.5 180.75 c
+74.75 176 66.5 180.75 64.25 182.25 c
+62 183.75 60.5 181.75 61 180.25 c
+61.5 178.75 58.75 180.75 57.5 180.75 c
+56.25 180.75 51.008 180.188 52 172.25 c
+52.25 170.25 51.5 170.5 49.75 169.25 c
+48 168 45.75 164.25 48.5 158.75 c
+51.25 153.25 49 150 48 145.5 c
+47 141 48 138.25 51.25 137.25 c
+54.5 136.25 54 133.791 54 130.75 C
+57 130.5 59 129.25 58.75 124.5 C
+62.25 124.5 61.75 126.75 62.5 130 c
+63.25 133.25 65.75 129 66.25 127 c
+66.75 125 67.5 125 72 125 C
+74.75 116.25 74.75 120.5 75.25 117.25 C
+80 117.5 79.5 116.75 83.25 113.75 c
+87 110.75 88.25 115.5 92 118.5 c
+95.75 121.5 94.25 122.75 96.25 118.75 c
+98.25 114.75 98.5 119 101.5 119.25 c
+104.5 119.5 101 115.75 105.25 114.5 c
+109.5 113.25 105 113.75 103.5 111.25 c
+102 108.75 95 103.5 101.75 101.5 c
+108.5 99.5 103.5 99.75 94.75 99.5 c
+86 99.25 73.75 87.5 97.25 73.25 C
+117.25 53.25 117.25 53.5 v
+117.25 53.75 175.25 163 175.5 163 c
+f
+1 J
+0.2 w
+389.709 210.076 m
+511.826 210.076 l
+S
+394.709 212.461 m
+516.826 212.461 l
+S
+415.459 215.112 m
+537.576 215.112 l
+S
+399.709 217.762 m
+521.826 217.762 l
+S
+402.459 222.799 m
+524.576 222.799 l
+S
+402.709 225.45 m
+524.826 225.45 l
+S
+392.959 227.851 m
+515.076 227.851 l
+S
+400.691 232.856 m
+522.809 232.856 l
+S
+388.191 235.241 m
+510.309 235.241 l
+S
+393.941 237.892 m
+516.059 237.892 l
+S
+393.441 240.292 m
+515.559 240.292 l
+S
+396.191 242.928 m
+518.309 242.928 l
+S
+386.441 245.579 m
+508.559 245.579 l
+S
+393.191 248.23 m
+515.309 248.23 l
+S
+414.191 250.631 m
+536.309 250.631 l
+S
+397.95 252.973 m
+520.067 252.973 l
+S
+398.7 255.358 m
+520.817 255.358 l
+S
+400.7 258.009 m
+522.817 258.009 l
+S
+384.45 260.659 m
+506.567 260.659 l
+S
+380.7 265.696 m
+502.817 265.696 l
+S
+379.95 268.347 m
+502.067 268.347 l
+S
+386.7 270.748 m
+508.817 270.748 l
+S
+394.433 275.752 m
+516.55 275.752 l
+S
+381.933 278.138 m
+504.05 278.138 l
+S
+379.433 280.789 m
+501.55 280.789 l
+S
+383.183 283.189 m
+505.3 283.189 l
+S
+370.433 285.825 m
+492.55 285.825 l
+S
+382.433 288.476 m
+504.55 288.476 l
+S
+356.183 291.127 m
+478.3 291.127 l
+S
+372.433 293.277 m
+494.55 293.277 l
+S
+361.866 296.006 m
+483.984 296.006 l
+S
+365.616 298.406 m
+487.734 298.406 l
+S
+366.866 301.042 m
+488.984 301.042 l
+S
+346.866 303.693 m
+468.984 303.693 l
+S
+338.616 306.344 m
+460.734 306.344 l
+S
+330.866 308.494 m
+452.984 308.494 l
+S
+301.575 344.342 m
+423.692 344.342 l
+S
+314.075 346.728 m
+436.192 346.728 l
+S
+318.325 349.378 m
+440.442 349.378 l
+S
+312.075 352.029 m
+434.192 352.029 l
+S
+327.325 357.065 m
+449.442 357.065 l
+S
+327.575 359.716 m
+449.692 359.716 l
+S
+317.825 362.117 m
+439.942 362.117 l
+S
+335.558 367.122 m
+457.675 367.122 l
+S
+313.058 369.507 m
+435.175 369.507 l
+S
+318.808 372.158 m
+440.925 372.158 l
+S
+317.579 404.674 m
+439.696 404.674 l
+S
+322.312 409.179 m
+444.429 409.179 l
+S
+323.812 412.065 m
+445.929 412.065 l
+S
+329.562 414.715 m
+451.679 414.715 l
+S
+329.062 417.116 m
+451.179 417.116 l
+S
+331.812 419.752 m
+453.929 419.752 l
+S
+322.062 422.402 m
+444.179 422.402 l
+S
+328.812 425.053 m
+450.929 425.053 l
+S
+349.812 427.454 m
+471.929 427.454 l
+S
+333.571 429.796 m
+455.688 429.796 l
+S
+334.321 432.182 m
+456.438 432.182 l
+S
+336.321 434.832 m
+458.438 434.832 l
+S
+320.071 437.483 m
+442.188 437.483 l
+S
+316.321 442.519 m
+438.438 442.519 l
+S
+315.571 445.17 m
+437.688 445.17 l
+S
+322.321 447.571 m
+444.438 447.571 l
+S
+330.054 452.576 m
+452.171 452.576 l
+S
+317.554 454.961 m
+439.671 454.961 l
+S
+315.054 457.612 m
+437.171 457.612 l
+S
+318.804 460.012 m
+440.921 460.012 l
+S
+306.054 462.648 m
+428.171 462.648 l
+S
+300.054 465.299 m
+422.171 465.299 l
+S
+291.804 467.95 m
+413.921 467.95 l
+S
+308.054 470.101 m
+430.171 470.101 l
+S
+260.834 543.511 m
+382.951 543.511 l
+S
+246.066 548.016 m
+368.184 548.016 l
+S
+256.066 550.901 m
+378.184 550.901 l
+S
+253.566 553.552 m
+375.684 553.552 l
+S
+230.316 555.952 m
+352.434 555.952 l
+S
+244.566 558.588 m
+366.684 558.588 l
+S
+238.566 561.239 m
+360.684 561.239 l
+S
+230.316 563.89 m
+352.434 563.89 l
+S
+216.566 565.541 m
+338.684 565.541 l
+S
+104.443 572.01 m
+226.575 572.209 l
+S
+98.682 567.48 m
+220.814 567.68 l
+S
+91.688 565.11 m
+213.82 565.31 l
+S
+97.192 561.955 m
+219.324 562.155 l
+S
+73.943 559.517 m
+196.075 559.717 l
+S
+88.199 556.904 m
+210.331 557.103 l
+S
+82.203 554.243 m
+204.335 554.443 l
+S
+73.956 551.578 m
+196.088 551.778 l
+S
+73.707 549.405 m
+195.839 549.605 l
+S
+85.302 539.953 m
+207.434 540.152 l
+S
+79.541 535.423 m
+201.673 535.623 l
+S
+72.547 533.053 m
+194.679 533.253 l
+S
+78.051 529.898 m
+200.183 530.098 l
+S
+54.802 527.46 m
+176.934 527.66 l
+S
+69.058 524.847 m
+191.19 525.046 l
+S
+63.061 522.186 m
+185.194 522.385 l
+S
+54.815 519.521 m
+176.947 519.721 l
+S
+54.566 517.348 m
+176.698 517.547 l
+S
+u
+189.475 196.879 m
+311.592 196.879 l
+S
+176.975 199.265 m
+299.092 199.265 l
+S
+174.475 201.916 m
+296.592 201.916 l
+S
+178.225 204.316 m
+300.342 204.316 l
+S
+165.475 206.952 m
+287.592 206.952 l
+S
+177.475 209.603 m
+299.592 209.603 l
+S
+155.725 212.254 m
+277.842 212.254 l
+S
+167.475 214.404 m
+289.592 214.404 l
+S
+156.908 217.133 m
+279.026 217.133 l
+S
+144.658 219.533 m
+266.776 219.533 l
+S
+161.908 222.169 m
+284.026 222.169 l
+S
+153.908 224.82 m
+276.026 224.82 l
+S
+163.658 226.971 m
+285.776 226.971 l
+S
+152.408 229.121 m
+274.526 229.121 l
+S
+145.925 233.316 m
+268.042 233.316 l
+S
+157.675 235.466 m
+279.792 235.466 l
+S
+147.108 238.195 m
+269.226 238.195 l
+S
+134.858 240.595 m
+256.976 240.595 l
+S
+137.608 243.231 m
+259.726 243.231 l
+S
+144.108 245.882 m
+266.226 245.882 l
+S
+153.858 248.033 m
+275.976 248.033 l
+S
+155.108 231.183 m
+277.226 231.183 l
+S
+103.425 247.816 m
+225.542 247.816 l
+S
+100.175 249.966 m
+222.292 249.966 l
+S
+89.608 252.695 m
+211.726 252.695 l
+S
+77.358 255.095 m
+199.476 255.095 l
+S
+U
+u
+1 g
+0 J
+1 w
+120.001 389.999 m
+170.811 344.713 248.714 349.191 294.001 400.001 c
+339.287 450.811 334.809 528.714 283.999 574.001 c
+233.189 619.287 155.286 614.809 109.999 563.999 c
+64.713 513.189 69.191 435.286 120.001 389.999 c
+f
+202 482 m
+F
+U
+u
+258 302 m
+306.6 267.759 373.759 279.4 408 328 c
+442.241 376.6 430.6 443.759 382 478 c
+333.4 512.241 266.241 500.6 232 452 c
+197.759 403.4 209.4 336.241 258 302 c
+f
+320 390 m
+F
+U
+u
+196 376 m
+252.332 345.072 323.072 365.668 354 422 c
+384.928 478.332 364.332 549.072 308 580 c
+251.668 610.928 180.928 590.332 150 534 c
+119.072 477.668 139.668 406.928 196 376 c
+f
+252 478 m
+F
+U
+u
+106 257 m
+170.064 231.595 242.595 262.936 268 327 c
+293.405 391.064 262.064 463.595 198 489 c
+133.936 514.405 61.405 483.064 36 419 c
+10.595 354.936 41.936 282.405 106 257 c
+f
+152 373 m
+F
+U
+u
+366.001 122 m
+415.706 97.7 475.7 118.296 500 168.001 c
+524.3 217.706 503.704 277.7 453.999 302 c
+404.294 326.3 344.3 305.704 320 255.999 c
+295.7 206.294 316.296 146.3 366.001 122 c
+f
+410 212 m
+F
+U
+u
+227.999 198 m
+267.763 185.85 309.849 208.236 322 247.999 c
+334.15 287.763 311.764 329.849 272.001 342 c
+232.237 354.15 190.151 331.764 178 292.001 c
+165.85 252.237 188.236 210.151 227.999 198 c
+f
+250 270 m
+F
+U
+0 g
+15.75 71.25 m
+24.25 82.75 24.75 84.75 27.75 82.25 c
+30.75 79.75 31.75 81.25 32.75 82.75 c
+33.75 84.25 30.75 86.75 35.75 88.75 c
+40.75 90.75 41.25 91.75 43.25 89.75 c
+45.25 87.75 39.25 89.25 50.25 88.75 c
+61.25 88.25 70.25 81.75 74.25 75.25 c
+78.25 68.75 77.75 67.25 75.25 63.25 c
+72.75 59.25 68.25 56.75 72.25 57.25 c
+76.25 57.75 75.75 60.75 77.75 56.75 c
+79.75 52.75 80.25 51.25 79.25 49.25 c
+78.25 47.25 74.25 46.75 81.25 46.25 c
+88.25 45.75 91.75 37.557 91.75 40.25 c
+15.752 40.248 l
+15.75 71.25 l
+f
+340.75 55.5 m
+F
+u
+u
+3 w
+280.774 44.223 m
+567.893 44.223 l
+S
+280.774 48.728 m
+567.893 48.728 l
+S
+280.774 53.734 m
+567.893 53.734 l
+S
+U
+u
+280.774 58.739 m
+567.893 58.739 l
+S
+280.774 63.245 m
+567.893 63.245 l
+S
+280.774 68.251 m
+567.893 68.251 l
+S
+U
+u
+280.774 73.257 m
+567.893 73.257 l
+S
+280.774 78.263 m
+567.893 78.263 l
+S
+U
+U
+0.8 g
+0.2 w
+243 252 m
+323 235 l
+346 273 l
+368 248 l
+376 247 376 248 V
+377 174 380.5 121 330.5 40 C
+90.5 40 91.5 40 V
+138.5 129 163 162 214 200 C
+236 229 234.527 240.11 238 254 c
+240 262 243 252 y
+b
+0.5 g
+359.5 485 m
+389.267 485 402.5 486.25 415.75 489 c
+429 491.75 435 493.25 439 493.5 c
+443 493.75 490.398 537.797 502.5 562 c
+507 571 514.5 577 517.5 579.5 c
+520.5 582 501.5 591 y
+428 512 428 512.5 v
+428 513 356.5 510 356 509.5 c
+355.5 509 351 488 y
+359 485 359.5 485 v
+b
+0.7 g
+370 496.5 m
+368 480.5 365.5 472.5 364.5 471.5 C
+329.5 476.5 l
+323.5 489.5 l
+370 496.5 l
+b
+0.5 g
+352.75 494 m
+380 493.25 399.626 496.75 407.5 499 c
+418 502 424.586 497.135 432.75 505.5 c
+453 526.25 473.5 544.5 496.5 586.5 C
+473.5 590 473.5 590.5 V
+456 571.5 443 563.5 434 558 c
+425 552.5 416 544 408.5 534.5 C
+399 533 379.5 537.5 364 537.5 c
+348.5 537.5 352.75 494 y
+b
+1 g
+500 583 m
+500.5 577.098 517 573.5 520.5 572 c
+524 570.5 526.353 568.989 526.5 579 c
+526.675 590.992 541 586 539 624 C
+538.5 624 506 628 y
+499.958 583.498 500 583 v
+b
+0 g
+1 J
+3 w
+562 629 m
+343 645 217 644 77 601 C
+52 576 L
+59.5 562 80.132 560.877 87 589 c
+89.513 599.292 87 597 101 601 c
+108.323 603.092 265 654 561 617 C
+562 629 l
+f
+1 G
+0 J
+0.7 w
+305 634 m
+391.5 636.5 415 635 473 632 c
+S
+0.5 w
+213 626.5 m
+153.5 619 125.925 611.699 90.75 602.5 c
+78.654 599.337 82.567 597.884 82.5 592 c
+82.395 582.717 73.75 571 59 572.5 c
+S
+1 g
+0 G
+1 w
+73 595.25 m
+79.25 592.5 76.25 574.75 57.25 580 C
+73 595.25 l
+f
+0.5 g
+0.2 w
+312 574.25 m
+311.25 570.5 310.687 571.687 306.187 569.187 C
+307.687 564.187 311.106 565.66 304.5 561.5 c
+302.594 560.299 305.598 556.561 305.75 555.5 c
+306.038 553.485 304.629 548.098 297 548.5 c
+292.25 548.75 255.5 536 y
+229.5 608.5 l
+224 650 224.5 650 v
+248.101 650 273.345 678.918 298 655.5 c
+324.857 629.99 316.981 613.501 316.75 612.875 c
+313.346 603.644 313.238 604.937 314.75 597.375 c
+316.88 586.725 317.016 588.834 318.625 584.75 C
+320.25 581.875 318.625 580.375 y
+316.689 578.236 313.081 579.809 310.375 579 c
+307.013 577.994 312 574.25 y
+B
+0 g
+0.5 w
+288.5 456 m
+S
+0.2 w
+211 511 m
+194.5 518.5 187 520.5 170.5 500 C
+154.5 498.5 149.5 501 131.5 479.5 C
+151 477.5 140 475 161 460 c
+182 445 190.5 436.5 212 461 C
+224.5 458 229 454.5 238.5 447 C
+238 446.5 237 500.5 y
+211 511 l
+f
+1 g
+207.5 526.5 m
+206 514.5 204 506 236 490.5 C
+242.5 509.5 l
+207.5 526.5 l
+b
+0 g
+1 w
+294.464 627.589 m
+288.571 618.522 284.821 617.313 280 615.5 c
+275.179 613.686 271.429 605.224 277.857 587.089 C
+274.107 586.485 275.179 585.88 275.714 582.858 C
+271.429 599.179 270.357 606.433 259.643 609.455 c
+248.929 612.477 245.714 589.507 247.321 566.537 C
+228.572 554.448 L
+224.639 578.851 235.956 576.38 212.5 600.992 c
+194.17 620.226 195.893 654.791 225.357 658.418 C
+223.214 667.485 233.929 678.97 259.107 677.761 c
+284.286 676.552 281.071 667.485 Y
+302.5 667.485 334.964 665.942 301.429 614.895 C
+306.25 639.679 303.571 643.306 296.607 646.933 C
+299.286 634.239 294.464 627.589 y
+f
+0.7 g
+0.2 w
+207.5 524.5 m
+214.75 519.25 241.5 509 y
+239 504.5 l
+232 503 214.5 508.75 206.75 519 C
+207 522.5 207.5 524.5 y
+b
+1 g
+298 546.5 m
+272.625 574.625 248.5 596 195.5 568.5 C
+196.26 524.417 214.492 504.333 239.5 510.5 C
+298 546.5 l
+b
+0.8 g
+351.5 542 m
+367 540 L
+358.5 509.5 357 489.5 357 482 C
+323.5 482.5 295.5 485.5 284.5 477.5 c
+298.5 468.5 l
+299 457 l
+270.5 451 l
+238.5 483.5 l
+241 513.5 l
+250.5 538 252.5 547.5 282.5 550 C
+306.251 550 334.454 541.702 343.687 542.187 C
+342.576 538.175 346.737 538.055 351.5 542 c
+b
+0 g
+1 w
+333.25 484.75 m
+343.25 458.25 371.5 466 349 418.5 C
+359 348.5 378 357 363 336 C
+358.5 333 359 333 v
+359.5 333 353 328 359 327.5 c
+365 327 371 316.5 373.5 253.5 C
+381 245.5 l
+371 221 371 220.5 V
+360.5 247 358 253 351 261.5 C
+340 238 331.5 220.5 328.5 211.5 C
+301 229.5 265 250 232.5 244.5 C
+247.5 287 246 299.5 275 320.5 C
+270 331.5 268.689 334.634 265.75 336.25 c
+255.75 341.75 261.891 340.771 251 375 c
+247.5 386 249.5 384 255.5 399 C
+252.5 397 253.5 401 253.5 402.5 c
+253.5 404 252.057 400.023 251 402.5 c
+235 440 219.5 489.5 249.5 534 C
+238.5 503.5 242.102 477.13 260 463 c
+269.5 455.5 278.75 453.25 291 457.25 C
+297.5 461 299.549 465.787 282 476.75 C
+292.5 487.5 333.25 484.75 y
+f
+457.25 576.25 m
+454.936 574.233 453.51 595.217 479.25 583 C
+495.651 573.321 495.931 560.263 482.5 560.5 C
+486.25 566 491.682 565.465 478.5 575 c
+463.444 585.891 460.318 578.924 457.25 576.25 c
+f
+1 g
+460.75 581.5 m
+463.387 583.699 467.528 583.937 470.5 583.375 c
+473.752 582.76 473.75 581.75 Y
+461.735 583.841 458.891 579.95 460.75 581.5 c
+f
+0 g
+310.393 647.785 m
+329.089 651.66 328.75 623.692 320.178 607.976 C
+319.107 621.274 316.428 636.386 310.536 635.782 c
+304.643 635.177 310.393 647.785 y
+f
+284.286 663.858 m
+286.964 677.157 280.536 689.246 281.071 689.246 C
+289.107 677.761 288.036 665.672 y
+284.286 663.858 l
+f
+0.2 w
+274.643 683.201 m
+278.929 678.97 280 668.694 279.464 665.672 c
+S
+276.25 686.224 m
+284.393 677.036 283.75 662.045 y
+S
+1 w
+297.679 661.44 m
+312.602 661.44 312.143 677.157 310.536 680.784 C
+308.929 672.321 305.179 666.276 292.857 664.463 C
+297.679 661.44 l
+f
+0.2 w
+295 661.44 m
+298.75 666.276 302.5 675.343 294.464 683.201 c
+S
+300.357 681.992 m
+304.265 669.255 303.814 670.807 292.321 656.604 c
+S
+311.821 649.078 m
+321.464 649.078 330.571 646.66 329.5 627.921 c
+S
+307.536 650.892 m
+316.268 651.33 319.057 653.025 326.821 646.056 c
+330.446 642.802 331.1 637.618 331.107 637.593 c
+S
+304.643 665.067 m
+305.629 663.874 321.031 667.072 321.304 651.569 c
+S
+0.5 w
+311.071 639.679 m
+317.893 638.968 312.696 617.332 v
+S
+1 w
+313.375 612.875 m
+315.455 614.262 313.5 617.375 297.125 615.375 C
+310.375 616.625 311.875 611.875 313.375 612.875 c
+f
+1 g
+308.5 604.875 m
+309.833 600.875 309.125 601.25 307.375 599 C
+302.25 600.625 303.25 599.875 299 602.5 C
+304.25 604.75 308.375 605.25 308.5 604.875 c
+f
+0 g
+307.5 604.437 m
+305.463 602.811 305.481 601.49 307.375 598.937 C
+309.261 601.307 309.489 602.172 308.562 605.062 C
+308.562 604.937 308.191 604.989 307.5 604.437 c
+f
+0.2 w
+305.625 583.75 m
+304.687 582.562 306.5 579.375 308.875 579.75 c
+S
+1 w
+311.125 574.5 m
+310.25 573.898 310 573.437 304.937 569.312 C
+306.229 564.611 308.063 564.014 308.312 564.562 C
+309.775 566.476 307.663 569.565 306.687 569.75 C
+311.812 571.75 311.625 572.5 312 574.25 C
+311.687 574.75 311.176 574.535 311.125 574.5 c
+f
+298.625 603 m
+302 600.437 304.294 599.524 307.812 598.937 c
+308.187 598.875 308.562 598.5 308.687 597.875 c
+S
+297.5 602.25 m
+299.939 602.851 307.687 603.062 311.75 607.812 C
+307.812 606 297.011 602.129 297.5 602.25 c
+f
+213.5 576.125 m
+218.674 549.92 230.862 532.355 245.5 526.5 C
+243.75 514.5 209.75 494.25 195.5 568.5 C
+203.75 572.25 213.347 576.901 213.5 576.125 c
+f
+0.2 w
+343.375 541.75 m
+333.375 534.75 318.25 525.5 312 521.25 c
+S
+351.562 541.937 m
+337.936 530.579 327.2 525.581 313.25 517.75 c
+S
+0.3 w
+312.75 495 m
+291.75 483.5 276.25 476 274.25 466 c
+S
+0.5 w
+229 580.75 m
+235.5 571 241.25 554.75 245.75 528 c
+S
+1 w
+235 581 m
+246 555.75 246.75 537.75 245.75 526 C
+252.125 560.5 243.75 567.75 239.75 581.5 C
+240 581.5 237 581.75 235 581 C
+f
+0.7 g
+0.2 w
+248.625 580.5 m
+253.169 564.605 256.75 553.75 250.25 535.75 C
+257.5 552.75 259.125 558.937 252.875 579.687 C
+251.029 580.149 248.517 580.879 248.625 580.5 c
+b
+0 g
+1 w
+258.25 577.75 m
+262.047 567.879 262.5 552.5 259.25 544.25 C
+267.75 548.25 275 549.75 278.25 549.75 C
+281.75 555.25 282.75 556.75 279.5 565.25 C
+270.06 573.13 257.909 578.635 258.25 577.75 c
+f
+207.5 524.5 m
+F
+207.25 514.75 m
+207.185 514.86 228.75 497.5 238 500.75 C
+236 494.5 l
+225 498 213.924 503.454 207.25 514.75 c
+f
+1 g
+0.2 w
+191 516 m
+175.472 497.418 168.5 492 171.5 453 C
+185 443.5 189 443.5 200 450.5 C
+186.5 469.5 182 491 198.5 515.5 C
+194.5 516 191.339 516.406 191 516 c
+b
+201 515 m
+194 499 187 484 203.5 453 C
+206.5 455 211.5 460.5 212 461 C
+203.5 480.5 193.5 501.5 206 510.5 C
+205 499.5 210.5 490.5 232.5 473.5 C
+232.5 483 231.5 482.5 233 492 C
+221 498 210 505 208 512.5 C
+201 515 l
+b
+0 g
+1 G
+0.5 w
+268 442.5 m
+253.5 402.5 l
+S
+269.5 435.5 m
+258.5 407 258.5 407.5 v
+S
+0.5 G
+0.4 w
+293.5 480.5 m
+297.5 463.5 298.5 460.5 289 445.5 c
+S
+1 G
+1 J
+0.3 w
+349.125 418.125 m
+338.393 403.978 348.387 416.158 341.625 408.875 c
+S
+u
+1 g
+0 G
+0 J
+0.2 w
+336.038 340.015 m
+338.267 329.694 L
+342.937 338.843 L
+340.707 349.164 L
+336.038 340.015 L
+b
+339.487 339.429 m
+B
+U
+u
+328.791 340.569 m
+331.562 330.38 L
+335.743 339.762 L
+332.972 349.952 L
+328.791 340.569 L
+b
+332.267 340.166 m
+B
+U
+u
+321.758 340.67 m
+325.133 330.664 L
+328.746 340.28 L
+325.37 350.286 L
+321.758 340.67 L
+b
+325.252 340.475 m
+B
+U
+u
+314.504 340.97 m
+317.88 330.964 L
+321.492 340.58 L
+318.117 350.586 L
+314.504 340.97 L
+b
+317.998 340.775 m
+B
+U
+u
+u
+307.24 340.468 m
+311.982 331.033 L
+314.214 341.059 L
+309.473 350.494 L
+307.24 340.468 L
+b
+310.727 340.764 m
+B
+U
+u
+300.016 339.751 m
+304.757 330.316 L
+306.99 340.342 L
+302.249 349.777 L
+300.016 339.751 L
+b
+303.503 340.047 m
+B
+U
+U
+u
+u
+292.985 339.2 m
+298.349 330.104 L
+299.903 340.258 L
+294.54 349.353 L
+292.985 339.2 L
+b
+296.444 339.729 m
+B
+U
+u
+285.826 338 m
+291.189 328.904 L
+292.744 339.057 L
+287.38 348.153 L
+285.826 338 L
+b
+289.285 338.529 m
+B
+U
+U
+u
+278.742 336.229 m
+285.413 328.042 L
+285.423 338.314 L
+278.753 346.501 L
+278.742 336.229 L
+b
+282.083 337.272 m
+B
+U
+u
+272.228 332.392 m
+279.743 324.974 L
+278.644 335.186 L
+271.13 342.604 L
+272.228 332.392 L
+b
+275.437 333.789 m
+B
+U
+0 g
+1 G
+1 w
+266.25 335.5 m
+276.25 351.5 284.659 350 343 350 c
+364 350 363 336 y
+S
+271 321 m
+294 332 309 335 362 324 c
+S
+u
+1 g
+0 G
+0.2 w
+350.823 325.912 m
+364.33 322.302 L
+361.658 347.078 L
+348.151 350.689 L
+350.823 325.912 L
+b
+356.24 336.495 m
+B
+U
+0 g
+1 w
+274 347.5 m
+281.5 351.5 280.229 357.581 311 338 c
+316.5 334.5 322.5 338 351 357.5 C
+282 360 l
+274 347.5 l
+f
+1 G
+0.5 w
+269.25 355.75 m
+277.75 353.25 284.25 352.5 288.75 349.75 c
+S
+353.25 358.25 m
+347.25 354 345.5 353.5 339.75 349.5 c
+S
+0.3 w
+355.25 272.75 m
+359.75 281.5 361.25 285 363.25 290.75 c
+S
+0.5 G
+0.5 w
+354 219 m
+339 195 327 176 317 166 c
+S
+323 197 m
+310 150 308 135 235 48 c
+S
+1 w
+241 241.5 m
+232 227.5 215.231 198.443 215 198 c
+192.581 155 178 110 164 71 c
+S
+0 G
+0.2 w
+265.394 600.822 m
+263.576 606.114 262.122 612.994 253.035 607.173 C
+250.126 603.468 249.763 601.704 249.763 596.589 c
+249.763 591.473 254.307 592.179 257.76 587.24 c
+261.213 582.301 266.484 579.302 267.029 588.475 c
+S
+0.3 g
+260.668 605.409 m
+262.486 601.352 261.94 599.941 257.578 597.824 c
+253.216 595.707 257.76 591.473 260.305 592.355 c
+262.849 593.237 263.394 592.532 264.303 591.65 c
+265.212 590.768 266.666 591.826 264.667 594.119 c
+262.667 596.413 259.759 593.943 261.032 597.471 c
+262.304 600.999 260.668 605.409 y
+b
+0 g
+257.578 606.644 m
+254.125 605.056 251.58 604.174 251.58 598.177 c
+251.58 592.179 258.487 590.415 259.214 588.651 c
+S
+u
+1 g
+257.397 584.594 m
+258.601 581.671 262.019 580.25 265.03 581.419 c
+268.041 582.588 269.506 585.905 268.302 588.827 c
+267.097 591.75 263.679 593.172 260.668 592.003 c
+257.657 590.833 256.192 587.516 257.397 584.594 c
+b
+262.849 586.711 m
+B
+U
+u
+0.2 g
+1 w
+258.487 586.358 m
+263.213 582.477 L
+267.211 587.063 L
+262.486 590.944 L
+258.487 586.358 L
+f
+262.849 586.711 m
+F
+U
+0 g
+309.25 579.875 m
+310.75 580.5 313.25 583.125 314.625 581 c
+F
+1 g
+307.964 565.926 m
+307.88 566.015 306.794 566.513 307.22 566.682 c
+307.647 566.851 307.68 566.599 307.935 566.639 C
+307.924 566.13 307.971 566.31 307.964 565.926 c
+f
+510 104 m
+509.564 104.895 511.5 89 495.5 74.5 C
+495.5 68 l
+506 79 518.582 86.358 510 104 c
+f
+0 g
+0.2 w
+403.75 534.25 m
+413.25 533.75 415.75 534.25 417.75 534.75 c
+S
+1 G
+0.3 w
+538.5 629 m
+542 625 547.5 620 y
+S
+548.75 629.25 m
+552.25 625.25 557.75 620.25 y
+S
+0 G
+0.2 w
+518.5 587.5 m
+522.5 586 526 587.5 527 587.5 c
+S
+514 617.5 m
+518 614 518.5 611.5 520 607.5 c
+S
+528.25 613.75 m
+533.25 615.25 532.5 615.5 538.25 614.25 c
+S
+1 g
+538 637.5 m
+537.25 618 533 617.5 531.25 617.5 c
+529.5 617.5 528.235 615.255 528.5 622.5 c
+529.25 643 528.775 643.326 534.25 642.75 c
+539 642.25 539 642.25 540.5 630.75 C
+538 631 l
+538 629 538 631.25 v
+538 633.5 538 637.5 Y
+b
+0.7 g
+507.5 650.75 m
+510 648.5 510.25 645.75 511.75 643.25 c
+513.25 640.75 508.5 638.25 508.5 638 c
+508.5 637.75 507.5 650.75 y
+b
+1 g
+529.25 639.25 m
+528.5 643 527 642.75 524 642.75 c
+521 642.75 519.75 644 519.5 632.25 C
+519.75 638 519.75 641 v
+519.75 644 518.75 644.25 515.25 644.25 c
+511.75 644.25 511.75 646 509.25 641.25 c
+506.75 636.5 505.75 633.25 506 633.25 c
+506.25 633.25 509.75 628.25 Y
+511.5 620.25 512.75 619.75 515.5 619.5 c
+518.25 619.25 520.25 618.25 519.5 623.5 C
+521 618.25 521 617.75 524.75 617 c
+528.5 616.25 528.5 618.25 528.5 622.5 c
+528.5 626.75 529.25 639.25 y
+b
+507.75 636.75 m
+512.687 638.231 515.604 641 515.25 641 C
+517.839 637.469 517.494 629.281 508.75 625.5 C
+508.75 625.25 502 635 502.25 634.75 c
+502.5 634.5 507.75 636.75 y
+b
+493.5 571.5 m
+495.171 563.425 503.634 565.498 503.5 576.25 c
+503.25 596.25 515.75 586.25 509 636.75 c
+508.301 641.977 510 650.75 506.5 651.5 c
+501.514 652.568 500.436 652.26 499.25 644.75 c
+498.5 640 496.5 646.25 496 648.5 c
+495.5 650.75 493.75 651 490.75 650.25 c
+487.75 649.5 488.253 648.665 487.5 645.5 c
+486.194 640.013 486.75 641.75 484.5 645.5 c
+482.39 649.016 481.306 648.011 477.5 647.25 c
+475 646.75 474.784 644.479 475.25 640.75 c
+475.5 638.75 474 642.25 472.5 644.5 c
+471 646.75 469.25 645.5 466.5 645.5 c
+463.75 645.5 463.25 641.003 463.5 635.5 c
+463.511 635.25 463 626.25 y
+449.75 627.25 l
+459.25 618.5 465.606 612.863 468.25 597 c
+468.75 594 468 592.25 470 592.75 C
+459.719 593.497 459.195 585.398 461 586 c
+466.25 587.75 471.75 589.25 476.75 587 c
+481.75 584.75 486.25 584.25 489.5 586.25 C
+490.25 582.75 492 578.75 493.5 571.5 c
+b
+0 g
+486.25 592.5 m
+489 595.25 492.117 593.078 492.25 592.75 c
+494.972 586.028 477 591.75 467.25 593 c
+S
+0.4 w
+470 592.75 m
+474.25 595.75 475 596 481.5 595.75 c
+S
+1 J
+2.5 w
+477.75 630 m
+478.5 620.75 l
+S
+479.25 617.5 m
+480 610.5 l
+S
+480.25 607.75 m
+481 600.25 481 600.5 v
+S
+487.5 631.75 m
+487.75 623.5 l
+S
+487.75 620.75 m
+487.75 612.5 l
+S
+488 609.25 m
+488.25 609.25 487.75 602.5 y
+S
+498 630.75 m
+497.25 623.75 l
+S
+496.75 620.75 m
+495.5 612.5 l
+S
+495.25 609.5 m
+493.75 602 l
+S
+0 J
+0.2 w
+465.5 637.25 m
+464.5 629.75 461.25 628.75 464.75 617 c
+S
+0.5 w
+502 589.25 m
+503.25 585 503.5 583.25 503.5 577 c
+S
+1 g
+1 w
+521.949 86.694 m
+521.637 87.353 523.021 75.657 511.583 64.988 C
+511.583 60.205 l
+519.089 68.299 528.083 73.713 521.949 86.694 c
+f
+553.457 99.673 m
+553.091 100.449 554.713 86.67 541.309 74.1 C
+541.309 68.465 l
+550.105 78.001 560.646 84.379 553.457 99.673 c
+f
+482.74 95.04 m
+482.429 95.699 483.812 84.003 472.375 73.334 C
+472.375 68.551 l
+479.881 76.645 488.875 82.059 482.74 95.04 c
+f
+450.924 87.63 m
+450.69 88.028 451.731 80.968 443.129 74.528 C
+443.129 71.641 l
+448.774 76.527 455.538 79.795 450.924 87.63 c
+f
+0 g
+308 61.5 m
+N
+3 w
+16.002 40.373 m
+568.002 40.127 L
+567.748 716.565 L
+S
+u
+15.815 40.248 m
+567.815 40.002 L
+567.748 716.565 L
+15.998 716.81 L
+15.815 40.248 L
+s
+U
+%%Trailer
+_E end
+showpage
diff --git a/gs/examples/grayalph.ps b/gs/examples/grayalph.ps
new file mode 100644
index 000000000..d7ed52d61
--- /dev/null
+++ b/gs/examples/grayalph.ps
@@ -0,0 +1,61 @@
+%!
+% grayscaled text test, including a trivial user bitmap font
+
+/inch {72 mul} def
+
+/BuildCharDict 10 dict def
+/$ExampleFont 7 dict def
+$ExampleFont begin
+ /FontType 3 def % user defined font.
+ /FontMatrix [1 0 0 1 0 0] def
+ /FontBBox [0 0 1 1] def
+ /Encoding 256 array def
+ 0 1 255 {Encoding exch /.notdef put} for
+ Encoding (a) 0 get /plus put
+ /CharStrings 2 dict def
+ CharStrings /.notdef {} put
+ CharStrings /plus
+ { gsave
+ 0 0 moveto
+ 32 32 true [32 0 0 -32 0 32]
+ {<0007E000 0007E000 0007E000 0007E000 0007E000 0007E000 0007E000 0007E000
+ 0007E000 0007E000 0007E000 0007E000 0007E000 FFFFFFFF FFFFFFFF FFFFFFFF
+ FFFFFFFF FFFFFFFF FFFFFFFF 0007E000 0007E000 0007E000 0007E000 0007E000
+ 0007E000 0007E000 0007E000 0007E000 0007E000 0007E000 0007E000 0007E000>
+ } imagemask
+ grestore
+ } put
+ /BuildChar
+ { BuildCharDict begin
+ /char exch def
+ /fontdict exch def
+ /charproc
+ fontdict /Encoding get char get
+ fontdict /CharStrings get
+ exch get def
+ 1 0 0 0 1 1 setcachedevice
+ charproc
+ end
+ } def
+end
+
+/MyFont $ExampleFont definefont pop
+
+ newpath
+ .5 inch 7.5 inch moveto
+ 7.5 inch 0 rlineto
+ 0 1.5 inch rlineto
+ -7.5 inch 0 rlineto
+ closepath
+ 0 setgray
+ fill
+
+ /MyFont findfont 72 scalefont setfont
+ .75 inch 7.75 inch moveto
+ 0 1 6
+ { /n exch def
+ 1 n 6 div sub setgray
+ (a) show
+ } for
+
+showpage
diff --git a/gs/lib/snowflak.ps b/gs/examples/snowflak.ps
index 1052ae75e..1052ae75e 100644
--- a/gs/lib/snowflak.ps
+++ b/gs/examples/snowflak.ps
diff --git a/gs/lib/tiger.ps b/gs/examples/tiger.ps
index 24a9dcec1..24a9dcec1 100644
--- a/gs/lib/tiger.ps
+++ b/gs/examples/tiger.ps
diff --git a/gs/lib/vasarely.ps b/gs/examples/vasarely.ps
index 4313b524e..4313b524e 100644
--- a/gs/lib/vasarely.ps
+++ b/gs/examples/vasarely.ps
diff --git a/gs/lib/waterfal.ps b/gs/examples/waterfal.ps
index bb01323ce..bb01323ce 100644
--- a/gs/lib/waterfal.ps
+++ b/gs/examples/waterfal.ps
diff --git a/gs/lib/Fontmap b/gs/lib/Fontmap
index 16cc7f959..92fb21685 100644
--- a/gs/lib/Fontmap
+++ b/gs/lib/Fontmap
@@ -1,4 +1,4 @@
-% Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -199,12 +199,17 @@
%
% BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
-% The Bitstream Charter fonts have different names (CharterBT-
-% instead of Charter-), but Ghostscript doesn't care.
-/Charter-Roman (bchr.pfa) ;
-/Charter-Italic (bchri.pfa) ;
-/Charter-Bold (bchb.pfa) ;
-/Charter-BoldItalic (bchbi.pfa) ;
+/CharterBT-Roman (bchr.pfa) ;
+/CharterBT-Italic (bchri.pfa) ;
+/CharterBT-Bold (bchb.pfa) ;
+/CharterBT-BoldItalic (bchbi.pfa) ;
+
+% Aliases
+
+/Charter-Roman /CharterBT-Roman ;
+/Charter-Italic /CharterBT-Italic ;
+/Charter-Bold /CharterBT-Bold ;
+/Charter-BoldItalic /CharterBT-BoldItalic ;
% The following notice accompanied the Utopia font:
%
diff --git a/gs/lib/Fontmap.GS b/gs/lib/Fontmap.GS
index 16cc7f959..92fb21685 100644
--- a/gs/lib/Fontmap.GS
+++ b/gs/lib/Fontmap.GS
@@ -1,4 +1,4 @@
-% Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -199,12 +199,17 @@
%
% BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
-% The Bitstream Charter fonts have different names (CharterBT-
-% instead of Charter-), but Ghostscript doesn't care.
-/Charter-Roman (bchr.pfa) ;
-/Charter-Italic (bchri.pfa) ;
-/Charter-Bold (bchb.pfa) ;
-/Charter-BoldItalic (bchbi.pfa) ;
+/CharterBT-Roman (bchr.pfa) ;
+/CharterBT-Italic (bchri.pfa) ;
+/CharterBT-Bold (bchb.pfa) ;
+/CharterBT-BoldItalic (bchbi.pfa) ;
+
+% Aliases
+
+/Charter-Roman /CharterBT-Roman ;
+/Charter-Italic /CharterBT-Italic ;
+/Charter-Bold /CharterBT-Bold ;
+/Charter-BoldItalic /CharterBT-BoldItalic ;
% The following notice accompanied the Utopia font:
%
diff --git a/gs/lib/Fontmap.Sol b/gs/lib/Fontmap.Sol
index 4b636d7af..5779db679 100644
--- a/gs/lib/Fontmap.Sol
+++ b/gs/lib/Fontmap.Sol
@@ -1,4 +1,4 @@
-% Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -238,12 +238,17 @@
%
% BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
-% The Bitstream Charter fonts have different names (CharterBT-
-% instead of Charter-), but Ghostscript doesn't care.
-/Charter-Roman (bchr.pfa) ;
-/Charter-Italic (bchri.pfa) ;
-/Charter-Bold (bchb.pfa) ;
-/Charter-BoldItalic (bchbi.pfa) ;
+/CharterBT-Roman (bchr.pfa) ;
+/CharterBT-Italic (bchri.pfa) ;
+/CharterBT-Bold (bchb.pfa) ;
+/CharterBT-BoldItalic (bchbi.pfa) ;
+
+% Aliases
+
+/Charter-Roman /CharterBT-Roman ;
+/Charter-Italic /CharterBT-Italic ;
+/Charter-Bold /CharterBT-Bold ;
+/Charter-BoldItalic /CharterBT-BoldItalic ;
% The following notice accompanied the Utopia font:
%
diff --git a/gs/lib/Fontmap.Ult b/gs/lib/Fontmap.Ult
index b21029eaa..6a9d00141 100644
--- a/gs/lib/Fontmap.Ult
+++ b/gs/lib/Fontmap.Ult
@@ -1,4 +1,4 @@
-% Copyright (C) 1990, 1995 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1990, 1995, 1999 Aladdin Enterprises. All rights reserved.
%
% Fontmap.Ult
%
@@ -36,6 +36,8 @@
% export GS_LIB_DEFAULT
%
% Peter Kaiser (kaiser@acm.org) 27 January 1995
+% Updated by L. Peter Deutsch (ghost@aladdin.com) 5 January 1999
+% to include correct aliasing for the Bitstream Charter fonts
/AvantGarde-Book (AvantGarde-Book) ;
/AvantGarde-BookOblique (AvantGarde-BookOblique) ;
@@ -75,10 +77,10 @@
/Bookman-LightItalic (pbkli.gsf) ;
/Calligraphic-Hiragana (fhirw.gsf) ;
/Calligraphic-Katakana (fkarw.gsf) ;
-/Charter-Bold (bchb.pfa) ;
-/Charter-BoldItalic (bchbi.pfa) ;
-/Charter-Italic (bchri.pfa) ;
-/Charter-Roman (bchr.pfa) ;
+/CharterBT-Bold (bchb.pfa) ;
+/CharterBT-BoldItalic (bchbi.pfa) ;
+/CharterBT-Italic (bchri.pfa) ;
+/CharterBT-Roman (bchr.pfa) ;
/Hershey-Gothic-English (hrger.pfa) ;
/Hershey-Gothic-English-Bold (hrgerb.gsf) ;
/Hershey-Gothic-English-Oblique (hrgero.gsf) ;
@@ -135,6 +137,10 @@
% Font aliases
+/Charter-Roman /CharterBT-Roman ;
+/Charter-Italic /CharterBT-Italic ;
+/Charter-Bold /CharterBT-Bold ;
+/Charter-BoldItalic /CharterBT-BoldItalic ;
/Courier-BoldItalic /Courier-BoldOblique ;
/Courier-Italic /Courier-Oblique ;
/Cyrillic /Shareware-Cyrillic-Regular ;
diff --git a/gs/lib/errpage.ps b/gs/lib/errpage.ps
new file mode 100644
index 000000000..a1034d2cb
--- /dev/null
+++ b/gs/lib/errpage.ps
@@ -0,0 +1,364 @@
+%!
+% Copyright (C) 1992, 1996, 1998 Aladdin Enterprises. All rights reserved.
+%
+% This file is part of Aladdin Ghostscript.
+%
+% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+% or distributor accepts any responsibility for the consequences of using it,
+% or for whether it serves any particular purpose or works at all, unless he
+% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+% License (the "License") for full details.
+%
+% Every copy of Aladdin Ghostscript must include a copy of the License,
+% normally in a plain ASCII text file named PUBLIC. The License grants you
+% the right to copy, modify and redistribute Aladdin Ghostscript, but only
+% under certain conditions described in the License. Among other things, the
+% License requires that the copyright notice and this notice be preserved on
+% all copies.
+
+
+% Print an informative error page if an error occurs.
+% Inspired by Adobe's `ehandler.ps' and David Holzgang's PinPoint.
+
+/EPdict 80 dict def
+EPdict begin
+
+/escale 12 def
+/efont /Helvetica findfont escale scalefont def
+/eheight escale 1.2 mul def
+
+% Miscellaneous utilities
+/xdef
+ { exch def
+ } bind def
+
+% Define `show' equivalents of = and ==
+
+/show=
+ { =string { cvs } stopped { pop pop (==unprintable==) } if show
+ } bind def
+
+/.dict 18 dict def
+.dict begin
+ /.buf =string def
+ /.cvp {.buf cvs show} bind def
+ /.nop {(-) .p type .cvp (-) .p} bind def
+ /.p {show} bind def
+ /.p1 {( ) dup 0 4 -1 roll put show} bind def
+ /.print
+ {dup type .dict exch known
+ {dup type exec} {.nop} ifelse
+ } bind def
+ /integertype /.cvp load def
+ /nulltype { pop (null) .p } bind def
+ /realtype /.cvp load def
+ /booleantype /.cvp load def
+ /nametype
+ {dup xcheck not {(/) .p} if
+ dup length .buf length gt
+ {dup length string}
+ {.buf}
+ ifelse cvs .p} bind def
+ /arraytype
+ {dup rcheck
+ {dup xcheck {(})({)} {(])([)} ifelse .p
+ exch () exch
+ {exch .p .print ( )} forall pop .p}
+ {.nop}
+ ifelse} bind def
+ /operatortype
+ {(--) .p .cvp (--) .p} bind def
+ /packedarraytype /arraytype load def
+ /stringtype
+ {dup rcheck
+ {(\() .p
+ {/.ch exch def
+ .ch 32 lt .ch 127 ge or
+ {(\\) .p .ch 8#1000 add 8 .buf cvrs 1 3 getinterval .p}
+ {.ch 40 eq .ch 41 eq or .ch 92 eq or
+ {(\\) .p} if
+ .ch .p1}
+ ifelse}
+ forall (\)) .p}
+ {.nop}
+ ifelse} bind def
+end
+/show==
+ { .dict begin .print end
+ } bind def
+
+% Printing utilities
+
+/eol
+ { /ey ey eheight sub def
+ ex ey moveto
+ } bind def
+/setx
+ { /ex xdef ex ey moveto
+ } bind def
+/setxy
+ { /ey xdef /ex xdef
+ ex ey moveto
+ } bind def
+/indent
+ { /lx ex def
+ ( ) show currentpoint setxy
+ } bind def
+/unindent
+ { lx setx
+ } bind def
+
+% Get the name of the n'th dictionary on the (saved) dictionary stack.
+/nthdictname % n -> name true | false
+ { dup dstack exch get
+ exch -1 0
+ { dstack exch get
+ { 2 index eq { exch pop exit } { pop } ifelse
+ }
+ forall
+ dup type /nametype eq { exit } if
+ }
+ for
+ dup type /nametype eq { true } { pop false } ifelse
+ } bind def
+
+% Find the name of a currently executing procedure.
+/findprocname % <proctail> findprocname <dstackindex> <procname> true
+ % <proctail> findprocname false
+ { dup length /proclength xdef
+ dup type cvlit /proctype xdef
+ dstack length 1 sub -1 0
+ { dup dstack exch get
+ { dup type proctype eq
+ { dup rcheck { dup length } { -1 } ifelse proclength gt
+ { dup length proclength sub proclength getinterval 3 index eq
+ { 3 -1 roll pop exit }
+ { pop }
+ ifelse
+ }
+ { pop pop
+ }
+ ifelse
+ }
+ { pop pop
+ }
+ ifelse
+ }
+ forall
+ dup type /nametype eq { exit } if
+ pop
+ }
+ for
+ dup type /nametype eq { true } { pop false } ifelse
+ } bind def
+
+% Error printing routine.
+% The top 2 elements of the o-stack are systemdict and EPdict.
+% For the moment, we ignore the possibility of stack overflow or VMerror.
+/showerror % <command> <countexecstack> <errorname> showerror -
+ {
+ % Restore the error handlers.
+
+ saveerrordict { errordict 3 1 roll put } forall
+ $error /recordstacks false put
+
+ % Save information from the stacks.
+
+ /saveerror xdef
+ countexecstack array execstack
+ 0 3 -1 roll 1 sub getinterval
+ /estack xdef
+ /savecommand xdef
+
+ countdictstack array dictstack
+ dup length 2 sub 0 exch getinterval
+ /dstack xdef
+
+ % Save state variables that will be reset.
+ % (We could save and print a lot more of the graphics state.)
+
+ /savefont currentfont def
+ mark { savefont /FontName get =string cvs cvn } stopped
+ { cleartomark null }
+ { exch pop dup length 0 eq { pop null } if }
+ ifelse /savefontname xdef
+ efont setfont
+
+ { currentpoint } stopped { null null } if
+ /savey xdef /savex xdef
+ 0 0
+ { pop pop }
+ { pop pop 1 add }
+ { pop pop pop pop pop pop exch 1 add exch }
+ { }
+ pathforall
+ /savelines xdef /savecurves xdef
+ /savepathbbox { [ pathbbox ] } stopped { pop null } if def
+
+ initmatrix
+
+ clippath pathbbox
+ /savecliptop xdef /saveclipright xdef
+ /saveclipbottom xdef /saveclipleft xdef
+ initclip
+
+ initgraphics
+
+ % Eject the current page.
+
+ showpage
+
+ % Print the page heading.
+
+ 18 clippath pathbbox newpath
+ 4 1 roll pop pop pop eheight sub 12 sub setxy
+ product (Product: )
+ statusdict /printername known
+ { 100 string statusdict begin printername end
+ dup length 0 gt
+ { exch pop exch pop (Printer name: ) }
+ { pop }
+ ifelse
+ }
+ if show show eol
+ (Interpreter version ) show version show eol
+ (Error: ) show saveerror show= eol
+ (Command being executed: ) show /savecommand load show= eol
+ currentfile { fileposition } stopped
+ { pop }
+ { (Position in input file: ) show show= eol }
+ ifelse eol
+
+ % Print the current graphics state.
+
+ (Page parameters:) show eol indent
+ (page size: ) show
+ gsave clippath pathbbox grestore
+ exch 3 index sub show= (pt x ) show
+ exch sub show= (pt) show pop eol
+ (current position: ) show
+ savex null eq
+ { (none) show }
+ { (x = ) show savex show= (, y = ) show savey show= }
+ ifelse eol
+ savelines savecurves add 0 eq
+ { (current path is empty) show
+ }
+ { (current path: ) show savelines show= ( line(s), ) show
+ savecurves show= ( curve(s)) show eol
+ (path bounding box: ) show savepathbbox show==
+ }
+ ifelse eol
+ (current font: ) show
+ savefontname dup null eq
+ { pop (--no name--) show }
+ { show= ( ) show
+ gsave
+ savefontname findfont /FontMatrix get matrix invertmatrix
+ grestore
+ savefont /FontMatrix get matrix concatmatrix
+ dup 1 get 0 eq 1 index 2 get 0 eq and
+ 1 index 4 get 0 eq and 1 index 5 get 0 eq and
+ 1 index 0 get 2 index 3 get eq and
+ { 0 get show= (pt) show }
+ { (scaled by ) show show= }
+ ifelse
+ }
+ ifelse eol
+ eol unindent
+
+ % Print the operand stack.
+
+ /stky ey def
+ (Operand stack:) show eol indent
+ count { show== eol } repeat
+ eol unindent
+
+ % Print the dictionary stack.
+
+ (Dictionary stack:) show eol indent
+ dstack length 1 sub -1 0
+ { nthdictname { show= } { (<unknown>) show } ifelse eol
+ } for
+ eol unindent
+
+ % Print the execution stack.
+
+ 280 stky setxy
+ (Execution stack:) show eol indent
+ estack length 1 sub -1 1
+ { estack exch get
+ dup type /operatortype eq
+ { show= eol
+ }
+ { dup type dup /arraytype eq exch /packedarraytype eq or
+ { dup xcheck
+ { dup rcheck
+ { findprocname
+ { show= nthdictname { ( in ) show show= } if eol
+ }
+ if
+ }
+ { pop
+ }
+ ifelse
+ }
+ { pop
+ }
+ ifelse
+ }
+ { pop
+ }
+ ifelse
+ }
+ ifelse
+ } for eol unindent
+
+ % Print the next few lines of input.
+ % Unfortunately, this crashes on an Adobe printer.
+
+(
+ (Next few lines of input:) show eol indent
+ /input currentfile def
+ mark { 4
+ { input ( ) readstring not { pop exit } if
+ dup 0 get dup 10 eq
+ { pop pop eol 1 sub dup 0 eq { pop exit } if }
+ { dup 13 eq { pop pop } { pop show } ifelse }
+ ifelse
+ }
+ loop } stopped cleartomark eol unindent
+) pop
+
+ % Wrap up.
+
+ showpage
+ quit
+
+ } def
+
+% Define the common procedure for handling errors.
+/doerror
+ { systemdict begin EPdict begin showerror
+ } bind def
+
+end
+
+% Install our own error handlers.
+
+/EPinstall
+ { EPdict begin
+ /saveerrordict errordict length dict def
+ errordict saveerrordict copy pop
+ errordict
+ { pop [ /countexecstack load 2 index cvlit /doerror load /exec load ] cvx
+ errordict 3 1 roll put
+ } forall
+ errordict /handleerror
+ [ /countexecstack load /handleerror /doerror load /exec load
+ ] cvx
+ put
+ end
+ } bind def
+
+EPinstall
diff --git a/gs/lib/gs_btokn.ps b/gs/lib/gs_btokn.ps
index 28b2e5d51..fb9ffc3ad 100644
--- a/gs/lib/gs_btokn.ps
+++ b/gs/lib/gs_btokn.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -139,8 +139,10 @@ mark
/CCITTFaxDecode /CCITTFaxEncode /DCTDecode /DCTEncode /LZWDecode
/LZWEncode /NullEncode /RunLengthDecode /RunLengthEncode /SubFileDecode
/CIEBasedA /CIEBasedABC /DeviceCMYK /DeviceGray /DeviceRGB
- /Indexed /Pattern /Separation
-% 478 -- end
+ /Indexed /Pattern /Separation /CIEBasedDEF /CIEBasedDEFG
+% 480
+ /DeviceN
+% 481 -- end
.packtomark
dup /SystemNames exch def .installsystemnames
diff --git a/gs/lib/gs_cff.ps b/gs/lib/gs_cff.ps
index 4e9883ab3..7ad262d04 100644
--- a/gs/lib/gs_cff.ps
+++ b/gs/lib/gs_cff.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -24,8 +24,8 @@
% 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.
+% Also, Type 2 charstrings are converted into FontType 2 fonts,
+% which may or may not be supported.
30 dict begin
@@ -216,13 +216,17 @@ mark
f cff eq { /pos pos 3 -1 roll add store } { pop } ifelse
} def
/next { % - next <byte>
- f read { 1 advance } if
+ f read {
+ 1 advance
+ DEBUG { ( ) print dup = } if
+ } if
} def
/nextstring { % <length> nextstring <string>
dup 0 eq {
pop ()
} {
string f exch readstring pop dup length advance
+ DEBUG { ( ) print dup == } if
} ifelse
} def
/card8 % - card8 <card8>
@@ -248,6 +252,7 @@ def
/tokens { % - tokens <num1> ... <op#> (op# = 12 means EOF)
{
f read not { 12 exit } if
+ DEBUG { (..) print dup = } if
1 advance
dup 12 eq { pop next 32 add exit } if
dup 28 lt { exit } if
@@ -299,7 +304,9 @@ def
} def
/Dict { % <opsdict> Dict -
/opdict exch store {
- mark tokens opdict exch .knownget { exec } if cleartomark
+ mark tokens
+ DEBUG { (tokens: ) print ] dup === mark exch aload pop } if
+ opdict exch .knownget { exec } if cleartomark
} loop cleartomark
} def
/idstring { % <sid> idstring <string|name>
@@ -308,10 +315,15 @@ def
/idname { % <sid> idname <name>
idstring dup type /nametype ne { cvn } if
} def
+/subfilefilter { % <file> <length> subfilefilter <filter>
+ % SubFileDecode interprets a length of 0 as infinite.
+ dup 0 le { pop pop () 0 } if () /SubFileDecode filter
+} def
% ------ Top dictionary ------ %
/offput { % <offset> <proc> offput -
+ DEBUG { (queued: ) print 1 index =only ( ) print dup === } if
currentdict exch aload length 1 add packedarray cvx
offsets 3 1 roll put
} def
@@ -344,7 +356,7 @@ def
35 { /UnderlinePosition putfi }
36 { /UnderlineThickness putfi }
37 { /PaintType xdef }
- 38 { /CharstringType xdef }
+ 38 { /FontType xdef } % actually CharstringType
39 { counttomark array astore /FontMatrix xdef }
13 { /UniqueID xdef }
5 { counttomark array astore /FontBBox xdef }
@@ -461,7 +473,7 @@ def
.dicttomark readonly def
/readPrivate { % <font> <size> readPrivate -
- exch 1 index f exch () /SubFileDecode filter /f exch def
+ exch 1 index f exch subfilefilter /f exch def
/Private get begin //privatedictops Dict end
/f cff def advance
} def
@@ -471,7 +483,7 @@ def
% We need to pass the file as a parameter for the sake of the PDF
% interpreter.
/StartData { % <resname> <nbytes> StartData -
- currentfile exch () /SubFileDecode filter ReadData
+ currentfile exch subfilefilter ReadData
} def
/ReadData { % <resname> <file> ReadData -
@@ -507,9 +519,8 @@ def
40 dict begin
% Preload defaults that differ from PostScript defaults,
% or that are required.
- /FontType 1 def
+ /FontType 2 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
@@ -526,8 +537,9 @@ def
% Read other tables with queued offsets.
- DEBUG { offsets length =only ( offsets) = flush } if
+ DEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
{ /f cff def
+ DEBUG { (pos=) print pos = } if
offsets pos 2 copy .knownget not { pop pop exit } if
3 1 roll undef exec
} loop
diff --git a/gs/lib/gs_cidfn.ps b/gs/lib/gs_cidfn.ps
index 978bb445b..e8fa0cfee 100644
--- a/gs/lib/gs_cidfn.ps
+++ b/gs/lib/gs_cidfn.ps
@@ -258,22 +258,32 @@ currentdict end
/.readglyphdata { % <cid> .readglyphdata <subfont> <string|null>
currentdict /GlyphDirectory .knownget {
dup type /arraytype eq {
- 1 index exch get
+ 1 index get
} {
- 1 index exch .knownget not { null } if
+ 1 index .knownget not { null } if
} ifelse
- dup null eq {
+ % Stack: cid string|null
+ dup null ne { exch pop .readgdirdata } { pop .readbytedata } ifelse
+ } {
+ % Stack: cid
+ .readbytedata
+ } ifelse
+} bind def
+/.readgdirdata { % <string|null> .readgdirdata <subfont> <string|null>
+ dup null eq {
+ FDepVector 0 get exch
+ } {
+ FDBytes 0 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
- } {
+ dup 0 get FDepVector exch get
+ exch dup length 1 sub 1 exch getinterval
+ } ifelse
+ } ifelse
+} bind def
+/.readbytedata { % <cid> .readbytedata <subfont> <string|null>
+ dup dup 0 ge exch CIDCount lt and {
FDBytes GDBytes add mul CIDMapOffset add
dup FDBytes .readint exch
FDBytes add dup GDBytes .readint
@@ -287,7 +297,9 @@ currentdict end
dup /CharStrings get gcheck .currentglobal exch .setglobal
% Stack: pos len subfont global
4 2 roll string ReadString exch .setglobal
- } ifelse
+ } ifelse
+ } {
+ pop FDepVector 0 get null
} ifelse
} bind def
@@ -309,7 +321,7 @@ currentdict end
% next dictionary on the stack.
/.loadsubrs {
currentdict /SubrMapOffset .knownget {
- Subrs 0 get null ne {
+ Subrs length 0 eq { true } { Subrs 0 get null ne } ifelse {
pop % We've already loaded the Subrs.
} {
currentglobal exch currentdict gcheck setglobal
@@ -338,10 +350,10 @@ currentdict end
(%Type9BuildGlyph) cvn { % <cidfont> <cid> %Type9BuildGlyph -
.currentglobal 3 1 roll 1 index gcheck .setglobal
1 index begin
- dup .readglyphdata dup null eq
- { %**** HANDLE NOTDEF ****
- }
- if
+ dup .readglyphdata dup null eq {
+ % Substitute CID 0. **** WRONG ****
+ pop pop 0 .readglyphdata
+ } if
% Stack: cidfont cid subfont charstring
dup null eq { pop pop pop pop } { %**** WRONG ****
4 -1 roll pop
@@ -373,23 +385,7 @@ dup null eq { pop pop pop pop } { %**** WRONG ****
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
+ 1 index exch .type42execchar
end
.setglobal
} bind def
diff --git a/gs/lib/gs_cmap.ps b/gs/lib/gs_cmap.ps
index a8325f610..81c77f887 100644
--- a/gs/lib/gs_cmap.ps
+++ b/gs/lib/gs_cmap.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -28,8 +28,11 @@
/composefont { % <name> <cmap|cmapname> <fonts> composefont <font>
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 {
+ /FDepVector 1 index cvlit def % temporarily
+ /Encoding [ 0 1 FDepVector length 1 sub { } for ] def
+ /FDepVector [ 0 1 FDepVector length 1 sub {
+ % Stack: name cmap[name] fonts /FDepVector [ fonts... i
+ FDepVector 1 index get
dup type /dicttype ne {
dup /CIDFont resourcestatus {
pop pop /CIDFont findresource
@@ -37,7 +40,12 @@
/Font findresource
} ifelse
} if
- } forall ] readonly def
+ exch CMap /FontMatrices get dup length 2 index gt {
+ exch get dup null eq { pop } { makefont } ifelse
+ } {
+ pop pop
+ } ifelse
+ } for ] readonly def
/FMapType 9 def
/FontMatrix matrix def
/FontName 3 index def
@@ -48,43 +56,48 @@
% ---------------- CMap operators ---------------- %
-30 dict begin
+40 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.
+% .FontIndices is a similar array holding the corresponding usefont values,
+% except that if the only font index is 0, the .FontIndices element is 0.
+% FontMatrices is the array of matrices defined by begin/endusematrix.
+% All of the arrays and strings 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 % <count> begincodespacerange -
- { pop mark
- } bind def
-/endcodespacerange % <code_lo> <code_hi> ... endcodespacerange -
- { counttomark 2 idiv
- { .CodeMaps { 3 copy .addcodespacerange pop } forall pop pop
- } repeat pop
- } bind def
-
-/.addcodespacerange % <code_lo> <code_hi> <map> .addcodespacerange -
- { 2 index length 1 eq
+/begincmap { % - begincmap -
+ /.CodeMaps [256 array 256 array] def
+ /.FontIndices [0 0] def
+ /FontMatrices [] def
+ /.FontIndex 0 def
+} bind def
+/endcmap { % - endcmap -
+ /.CodeMaps .CodeMaps .endmap def
+ /.FontIndices .FontIndices .endmap def
+ /FontMatrices FontMatrices .endmap def
+ /CodeMap null def % for .buildcmap
+ currentdict end .buildcmap begin
+} bind def
+
+/begincodespacerange { % <count> begincodespacerange -
+ pop mark
+} bind def
+/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange -
+ counttomark 2 idiv {
+ .CodeMaps { 3 copy .addcodespacerange pop } forall pop pop
+ } repeat pop
+} bind def
+
+/.addcodespacerange { % <code_lo> <code_hi> <map> .addcodespacerange -
+ 2 index length 1 eq
{ 2 { 3 -1 roll 0 get } repeat 1 exch
{ 2 copy 0 put pop } for pop
}
@@ -97,96 +110,144 @@
}
for pop pop pop
}
- ifelse
- } bind def
-/.endmap % <map> .endmap <map>
- { dup type /arraytype eq { dup { .endmap exch } forall astore readonly } if
- } bind def
-
-/usecmap % <CMap_name> usecmap -
- { /CMap findresource
- dup length dict .copydict
- currentdict end exch .copydict begin
- } bind def
+ ifelse
+} bind def
+/.endmap { % <map> .endmap <map>
+ dup type /arraytype eq {
+ dup { .endmap exch } forall astore readonly
+ } {
+ dup type /stringtype eq { readonly } if
+ } ifelse
+} bind def
+
+/usecmap { % <CMap_name> usecmap -
+ /CMap findresource
+ dup length dict .copydict
+ currentdict end exch .copydict begin
+} bind def
+
+/usefont { % <fontID> usefont -
+ /.FontIndex exch def
+} bind def
+
+/beginusematrix { % <fontID> beginusematrix -
+ FontMatrices wcheck not FontMatrices length 2 index le or {
+ FontMatrices length 1 index 1 add .max array
+ dup 0 FontMatrices putinterval
+ /FontMatrices exch def
+ } if
+} bind def
+/endusematrix { % <matrix> endusematrix -
+ FontMatrices 3 1 roll put
+} bind def
% ------ Rearranged font operators ------ %
-/beginrearrangedfont % <font_name> <font*> beginrearrangedfont -
- { (NOT IMPLEMENTED YET.\n) print flush
- } bind def
-/endrearrangedfont % - endrearrangedfont -
- { (NOT IMPLEMENTED YET.\n) print flush
- } bind def
-
-/usefont % <fontID> usefont -
- { (NOT IMPLEMENTED YET.\n) print flush
- } bind def
-
-/beginusematrix % <fontID> beginusematrix -
- { (NOT IMPLEMENTED YET.\n) print flush
- } bind def
-/endusematrix % <matrix> endusematrix -
- { (NOT IMPLEMENTED YET.\n) print flush
- } bind def
+/beginrearrangedfont { % <font_name> <font*> beginrearrangedfont -
+ 10 dict begin
+ /.FontNames exch def
+ /.FontName exch def
+ begincmap
+} bind def
+/endrearrangedfont { % - endrearrangedfont -
+ (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
+ FontName .FontNames 0 get findfont end definefont pop
+} bind def
% ------ Character name/code selector operators ------ %
-/beginbfchar % <count> beginbfchar -
- { pop mark
- } bind def
-/endbfchar % <code> <to_code|charname> ... endbfchar
- { 0 .getmap .endmapchar 0 .putmap
- } bind def
-
-/beginbfrange % <count> beginbfrange -
- { pop mark
- } bind def
-/endbfrange % <code_lo> <code_hi> <to_code|(charname*)> ...
+/beginbfchar { % <count> beginbfchar -
+ pop mark
+} bind def
+/endbfchar { % <code> <to_code|charname> ... endbfchar
+ .endmapchar
+} bind def
+
+/beginbfrange { % <count> beginbfrange -
+ pop mark
+} bind def
+/endbfrange { % <code_lo> <code_hi> <to_code|(charname*)> ...
% endbfrange -
- { 0 .getmap counttomark 3 idiv { .addbfrange } repeat 0 .putmap pop
- } bind def
-
-/.addbfrange % <code_lo> <code_hi> <to_code|(charname*)> <map>
- % .addbfrange <map>
- { 1 index type /stringtype eq
- { { dup length string copy dup dup length 1 sub 2 copy get 1 add put }
- exch .addmaprange
+ counttomark 3 idiv {
+ counttomark -3 roll % process in correct order
+ .addbfrange
+ } repeat pop
+} bind def
+
+/.addbfrange { % <code_lo> <code_hi> <to_code|(charname*)>
+ % .addbfrange
+ dup type /stringtype eq {
+ { dup length string copy dup dup length 1 sub 2 copy get 1 add put }
+ .addcharrange
+ } {
+ 2 dict begin /codes 1 index def 0 get
+ { pop codes dup dup length 1 sub 1 exch getinterval /codes exch def
+ dup length 0 gt { 0 get } if
}
- { 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
+ .addcharrange end
+ } ifelse
+} bind def
% ------ CID selector operators ------ %
-/begincidchar % <count> begincidchar -
- { pop mark
- } bind def
-/endcidchar % <code> <cid> ... endcidchar -
- { 0 .getmap .endmapchar 0 .putmap
- } bind def
-
-/begincidrange % <count> begincidrange -
- { pop mark
- } bind def
-/endcidrange % <code_lo> <code_hi> <cid_base> ... endcidrange -
- { 0 .getmap counttomark 3 idiv { { 1 add } exch .addmaprange exch pop } repeat
- 0 .putmap pop
- } bind def
-
-/.endmapchar % -mark- <code> <value> ... <map> .endmapchar -
- { counttomark 2 idiv
- { 2 index 3 1 roll { } exch .addmaprange exch pop
- } repeat exch pop
- } bind def
-
-/.addmaprange % <code_lo> <code_hi> <value_base> <next_proc> <map>
- % .addcidrange <value_next> <map>
- { % We may be updating a (partly) read-only map from another CMap.
+/begincidchar { % <count> begincidchar -
+ pop mark
+} bind def
+/endcidchar { % <code> <cid> ... endcidchar -
+ .endmapchar
+} bind def
+
+/begincidrange { % <count> begincidrange -
+ pop mark
+} bind def
+/endcidrange { % <code_lo> <code_hi> <cid_base> ... endcidrange -
+ counttomark 3 idiv {
+ counttomark -3 roll % process in correct order
+ { 1 add } .addcharrange
+ } repeat pop
+} bind def
+
+/.endmapchar { % -mark- <code> <value> ... .endmapchar -
+ counttomark 2 idiv {
+ counttomark -2 roll % process in correct order
+ 1 index exch { } .addcharrange
+ } repeat pop
+} bind def
+
+/.addcharrange { % <code_lo> <code_hi> <value_base> <next_proc>
+ % .addcharrange -
+ 0 .putmaprange
+} bind def
+
+/.putmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <0|1>
+ % .putmaprange -
+ 5 1 roll
+ % Most CMaps don't involve multiple fonts.
+ % For this reason, we create .FontIndices lazily.
+ .FontIndices 5 index get 0 eq .FontIndex 0 ne and {
+ % Create .FontIndices now.
+ .CodeMaps 5 index get .makecodespace
+ .FontIndices 6 index 3 -1 roll put
+ } if
+ .FontIndices 5 index get 0 ne {
+ 3 index 3 index .FontIndex { } .FontIndices 9 index get .addmaprange
+ .FontIndices 7 index 3 -1 roll put pop
+ } if
+ .CodeMaps 5 index get .addmaprange
+ .CodeMaps 3 index 3 -1 roll put pop
+ pop
+} bind def
+/.makecodespace { % <array|other> .makecodespace -
+ dup type /arraytype eq {
+ [ exch { .makecodespace } forall ]
+ } {
+ pop 0
+ } ifelse
+} bind def
+
+/.addmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <map>
+ % .addmaprange <value_next> <map>
+ % 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
@@ -209,27 +270,33 @@
for 5 -2 roll pop pop
}
ifelse exch pop
- } bind def
+} bind def
% ------ notdef operators ------ %
-/beginnotdefchar % <count> beginnotdefchar -
- { pop mark
- } bind def
-/endnotdefchar % <code> <cid> ... endnotdefchar -
- { counttomark 2 idiv { 1 index exch .addnotdefrange } repeat pop
- } bind def
-
-/beginnotdefrange % <count> beginnotdefrange -
- { pop mark
- } bind def
-/endnotdefrange % <code_lo> <code_hi> <cid> ... endnotdefrange -
- { counttomark 3 idiv { .addnotdefrange } repeat pop
- } bind def
-
-/.addnotdefrange % <code_lo> <code_hi> <cid_base> .addnotdefrange -
- { { } 1 .getmap .addmaprange 1 .putmap pop
- } bind def
+/beginnotdefchar { % <count> beginnotdefchar -
+ pop mark
+} bind def
+/endnotdefchar { % <code> <cid> ... endnotdefchar -
+ counttomark 2 idiv {
+ counttomark -2 roll % process in correct order
+ 1 index exch .addnotdefrange
+ } repeat pop
+} bind def
+
+/beginnotdefrange { % <count> beginnotdefrange -
+ pop mark
+} bind def
+/endnotdefrange { % <code_lo> <code_hi> <cid> ... endnotdefrange -
+ counttomark 3 idiv {
+ counttomark -3 roll % process in correct order
+ .addnotdefrange
+ } repeat pop
+} bind def
+
+/.addnotdefrange { % <code_lo> <code_hi> <cid_base> .addnotdefrange -
+ { } 1 .putmaprange
+} bind def
% ---------------- Resource category definition ---------------- %
diff --git a/gs/lib/gs_dps1.ps b/gs/lib/gs_dps1.ps
index 3b396814e..bad11e9be 100644
--- a/gs/lib/gs_dps1.ps
+++ b/gs/lib/gs_dps1.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -60,7 +60,9 @@ level2dict begin
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
+% Don't just copy (load) the definition of .setglobal:
+% it gets redefined for LL3.
+/setshared { /.setglobal .systemvar exec } odef
.currentglobal setshared
% See below for changes in save and restore.
diff --git a/gs/lib/gs_dps2.ps b/gs/lib/gs_dps2.ps
index daef68672..51fb6e2ce 100644
--- a/gs/lib/gs_dps2.ps
+++ b/gs/lib/gs_dps2.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1990, 1996, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1990, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -44,48 +44,80 @@ level2dict begin
}
exch get exec
} odef
-% Define sethalftone so it converts all other types to type 5.
-/.sethalftoneRGBV % <dict> <type> <keys> <keysRGBV>
- { 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
+% Define sethalftone so it converts types 1-4 to type 5.
+/.makehalftoneRGBV { % <dict> <type> <keys> <keysRGBV>
+ 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 exch pop { .sethalftone5 }
+} bind def
+
+% The value of each entry in .halftonetypes is a procedure:
+% <setdict> <htdict> <<proc>> <setdict'> <htdict'> <sethalftoneproc>
+% This allows us to use these procedures both for actually implementing
+% sethalftone and for converting subsidiary dictionaries of HalftoneType 5
+% halftones.
+systemdict begin
+15 dict /.halftonetypes 1 index def begin
+ 1 {
+ mark exch /Default exch .dicttomark { .sethalftone5 }
+ } bind def
+ 2 {
+ 1 { /Frequency /Angle /SpotFunction } {
+ /RedFrequency /RedAngle /RedSpotFunction
+ /GreenFrequency /GreenAngle /GreenSpotFunction
+ /BlueFrequency /BlueAngle /BlueSpotFunction
+ /GrayFrequency /GrayAngle /GraySpotFunction
+ } .makehalftoneRGBV
+ } bind def
+ 3 {
+ mark exch /Default exch .dicttomark { .sethalftone5 }
+ } bind def
+ 4 {
+ 3 { /Width /Height /Thresholds } {
+ /RedWidth /RedHeight /RedThresholds
+ /GreenWidth /GreenHeight /GreenThresholds
+ /BlueWidth /BlueHeight /BlueThresholds
+ /GrayWidth /GrayHeight /GrayThresholds
+ } .makehalftoneRGBV
+ } bind def
+ 5 {
+ pop dup length dict copy
+ mark 1 index {
+ % Even HalftoneType 5 dictionaries have entries other than
+ % subsidiary halftone dictionaries.
+ dup type /dicttype ne {
+ 0
+ } {
+ dup /HalftoneType .knownget not { 0 } if
+ } ifelse dup 5 gt {
+ % Stack: dict mark ... keyN dictN httypeN
+ % Assume that all HalftoneTypes > 5 convert to 5.
+ 1 index 3 1 roll
+ //.halftonetypes exch get exec pop /Default get
+ % Stack: dict mark ... keyN setdict'N htdict'N
+ counttomark 1 add index 3 index 4 -1 roll put
+ } {
+ pop
+ } ifelse
+ } forall .dicttomark { .sethalftone5 }
+ } bind def
+end
+end
/sethalftone { % <dict> 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
+ % 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 //.halftonetypes 1 index /HalftoneType get get exec exec
+ .setglobal pop
} odef
% Redefine setscreen and setcolorscreen to recognize halftone dictionaries,
% and to insert the Frequency and Angle into Type 1 halftones, per
diff --git a/gs/lib/gs_fonts.ps b/gs/lib/gs_fonts.ps
index b8de32afb..b3184934e 100644
--- a/gs/lib/gs_fonts.ps
+++ b/gs/lib/gs_fonts.ps
@@ -15,7 +15,7 @@
% License requires that the copyright notice and this notice be preserved on
% all copies.
-% $Id$
+
% Font initialization and management code.
% Define the default font.
@@ -472,7 +472,7 @@ buildfontdict 3 /.buildfont3 cvx put
] readonly def
/.substituteproperties [
[(It) 1] [(Oblique) 1]
- [(Bd) 2] [(Bold) 2] [(bold) 2] [(Demi) 2] [(Heavy) 2] [(Sb) 2]
+ [(Black) 2] [(Bd) 2] [(Bold) 2] [(bold) 2] [(Demi) 2] [(Heavy) 2] [(Sb) 2]
[(Cn) 4] [(Cond) 4] [(Narrow) 4] [(Pkg) 4]
] readonly def
/.fontnameproperties { % <string|name> .fontnameproperties <int>
diff --git a/gs/lib/gs_init.ps b/gs/lib/gs_init.ps
index d3aeee6fb..2ee2e4ddc 100644
--- a/gs/lib/gs_init.ps
+++ b/gs/lib/gs_init.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -31,7 +31,7 @@
% Check the interpreter revision. NOTE: the interpreter code requires
% that the first non-comment token in this file be an integer.
-555
+584
dup revision ne
{ (gs: Interpreter revision \() print revision 10 string cvs print
(\) does not match gs_init.ps revision \() print 10 string cvs print
@@ -56,9 +56,9 @@ if begin
systemdict /.setglobal known
{ true .setglobal
}
- { /.setglobal { pop } .bind def
- /.currentglobal { false } .bind def
- /.gcheck { pop false } .bind def
+ { /.setglobal { pop } bind def
+ /.currentglobal { false } bind def
+ /.gcheck { pop false } bind def
}
ifelse
@@ -102,6 +102,7 @@ currentdict /DEBUG known /DEBUG exch def
currentdict /BATCH known /BATCH exch def
currentdict /DELAYBIND known /DELAYBIND exch def
currentdict /DISKFONTS known /DISKFONTS exch def
+currentdict /DOINTERPOLATE .knownget { /INTERPOLATE exch def } if
currentdict /ESTACKPRINT known /ESTACKPRINT exch def
currentdict /FAKEFONTS known /FAKEFONTS exch def
currentdict /FIXEDMEDIA known /FIXEDMEDIA exch def
@@ -116,7 +117,7 @@ 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 /NOINTERPOLATE .knownget { /INTERPOLATE exch not def } if
currentdict /NOPAGEPROMPT known /NOPAGEPROMPT exch def
currentdict /NOPAUSE known /NOPAUSE exch def
currentdict /NOPLATFONTS known /NOPLATFONTS exch def
@@ -132,6 +133,7 @@ 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 /TTYPAUSE known /TTYPAUSE exch def
currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def
% Acquire environment variables.
@@ -193,15 +195,15 @@ userdict /=string 256 string put
}
ifelse
(\n) copyright
- (\)\n) revisiondate 100 mod (-)
- revisiondate 100 idiv 100 mod (-)
+ (\)\n) revisiondate 10 mod revisiondate 10 idiv 10 mod (-)
+ revisiondate 100 idiv 10 mod revisiondate 1000 idiv 10 mod (-)
revisiondate 10000 idiv ( \()
revision 10 mod
revision 100 mod dup 0 ne { 10 idiv } { pop } ifelse (.)
revision 100 idiv ( )
product
counttomark
- { (%stdout) (w) file exch false .writecvp
+ { (%stdout) (w) file exch 0 .writecvp
} repeat pop
} .bind def
@@ -276,7 +278,7 @@ currentdict /hwsizedict .undef
/min { .min } bind def
/.currentfilladjust { .currentfilladjust2 pop } bind odef
/.setfilladjust { dup .setfilladjust2 } bind odef
-/.writecvs { false .writecvp } bind odef
+/.writecvs { 0 .writecvp } bind odef
% Define predefined procedures substituting for operators,
% in alphabetical order.
@@ -293,7 +295,7 @@ userdict /#copies 1 put
% In LanguageLevel 3, copypage erases the page.
/copypage {
.languagelevel 3 ge
- 1 .endpage {
+ dup { 0 } { 1 } ifelse .endpage {
.currentnumcopies 1 index .outputpage
(>>copypage, press <return> to continue<<\n) .confirm
dup { erasepage } if
@@ -375,11 +377,13 @@ userdict /.echo.mode true put
/pathbbox
{ false .pathbbox
} odef
-/prompt { flush flushpage
- (GS) print
- count 0 ne { (<) print count =only } if
- (>) print flush
- } bind def
+% .promptmsg is redefined if the interpreter includes readline support.
+/.promptmsg {
+ (GS) print
+ count 0 ne { (<) print count =only } if
+ (>) print flush
+} bind def
+/prompt { flush flushpage .promptmsg } bind def
/pstack { 0 1 count 3 sub { index == } for } bind def
/putdeviceprops
{ .putdeviceprops { erasepage } if } odef
@@ -451,13 +455,19 @@ userdict /.echo.mode true put
/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.
+/.typenames mark .typenames counttomark packedarray exch pop def
/type {
- //typenames .type
+ //.typenames .type
} odef
+currentdict /.typenames .undef
% 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
+/.wheredict 10 dict def
+/.where /where load def
+/where {
+ //.wheredict 1 index .knownget { exec } { .where } ifelse
+} odef
% 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
@@ -577,22 +587,29 @@ currentdict /superexec .knownget {
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
+/.confirm {
+ DISPLAYING NOPAUSE not TTYPAUSE or 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
+ .confirmread
+ } {
+ pop
+ } ifelse
+} bind def
+/.confirmread {
+ TTYPAUSE {
+ (/dev/tty) (r) file dup read pop pop closefile
+ } {
+ .echo.mode false echo
+ (%stdin) (r) file dup read {
+ dup (\n) 0 get eq { pop pop } { unread } ifelse
+ } {
+ pop
+ } ifelse echo
+ } ifelse
+} bind def
% Define the procedure used by .runfile, .runstdin and .runstring
% for executing user input.
@@ -867,47 +884,15 @@ errordict begin
end
% Define the [write]==[only] procedures.
-/.dict 26 dict dup
+/.dict 8 dict dup
begin def
- /.cvp {1 index exch .writecvs} bind def
- /.nop {exch pop .p} bind def
+ /.cvp {1 index exch 1 .writecvp} 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
+ { dup type .dict exch .knownget { exec } { .cvp } 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
@@ -920,27 +905,9 @@ begin def
1 index exch .print pop ( )} forall
(])}
ifelse exch pop .p}
- {(-array-) .nop}
+ {.cvp}
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
+ /packedarraytype /arraytype load def
{//.dict begin .print pop end}
bind
end
@@ -952,7 +919,7 @@ end
% 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
+/.dict /write==only load 0 get dup length 2 add dict .copydict dup
begin def
/dicttype
{ dup rcheck
@@ -962,15 +929,12 @@ begin def
}
forall (>>) .p
}
- { (-dict-) .nop
+ { .cvp
}
ifelse
} bind def
/stringtype
- { dup rcheck
- { (\() .p1 .pstring (\)) .p }
- { (-string-) .nop }
- ifelse
+ { 1 index exch 2 .writecvp
} bind def
{//.dict begin .print pop end}
@@ -1310,8 +1274,8 @@ NOCACHE { 0 setcachelimit } if
% We make this a procedure so we can call it again when switching devices.
% Use an ordered dither for low-resolution devices.
-/.setloresscreen % <dpi> .setloresscreen -
- { % The following 'ordered dither' spot function was contributed by
+/.setloreshalftone { % <dpi> .setloreshalftone -
+ % The following 'ordered dither' spot function was contributed by
% Gregg Townsend. Thanks, Gregg!
16.001 div 0 % not 16: avoids rounding problems
{ 1 add 7.9999 mul cvi exch 1 add 7.9999 mul cvi 16 mul add <
@@ -1339,12 +1303,15 @@ NOCACHE { 0 setcachelimit } if
{ 3 copy 6 copy setcolorscreen }
{ setscreen }
ifelse
- 0 array cvx settransfer % Genoa CET won't accept a packed array!
- /setstrokeadjust where { pop true setstrokeadjust } if
- } bind def
+} bind def
+/.setloresscreen { % <dpi> .setloresscreen -
+ .setloreshalftone
+ 0 array cvx settransfer % Genoa CET won't accept a packed array!
+ /setstrokeadjust where { pop true setstrokeadjust } if
+} bind def
% Use a 45-degree spot screen for high-resolution devices.
-/.sethiresscreen % <dpi> .sethiresscreen -
- { % According to information published by Hewlett-Packard,
+/.sethireshalftone { % <dpi> .sethireshalftone <doscreen>
+ % According to information published by Hewlett-Packard,
% they use a 60 line screen on 300 DPI printers and
% an 85 line screen on 600 DPI printers.
% However, we use a 106 line screen, which produces smoother-
@@ -1412,6 +1379,9 @@ NOCACHE { 0 setcachelimit } if
{ setscreen % not high resolution
}
ifelse
+} bind def
+/.sethiresscreen { % <dpi> .sethiresscreen -
+ .sethireshalftone
% Stack: doscreen
{ % Set the transfer function to lighten up the grays.
% We correct at the high end so that very light grays
@@ -1440,21 +1410,24 @@ NOCACHE { 0 setcachelimit } if
% Increase fill adjustment so that we effectively use Adobe's
% any-part-of-pixel rule.
0.5 .setfilladjust
- } bind def
-% Set the default screen and BG/UCR based on the device resolution and
-% process color capability.
+} bind def
+% Set the default screen and BG/UCR.
/.setdefaultbgucr systemdict /setblackgeneration known { {
- processcolors 1 eq { { } } { { pop 0.0 } } ifelse
- dup setblackgeneration setundercolorremoval
+ { } dup setblackgeneration setundercolorremoval
} } { {
} } ifelse bind def
-/.setdefaultscreen
- { % Compute min(|dpi x|,|dpi y|) as the definition of the resolution.
- 72 72 matrix defaultmatrix dtransform abs exch abs .min
- dup 150 lt //systemdict /DITHERPPI known not and
- { .setloresscreen } { .sethiresscreen }
- ifelse .setdefaultbgucr
- } bind def
+/.useloresscreen { % - .useloresscreen <bool>
+ % Compute min(|dpi x|,|dpi y|) as the definition of the resolution.
+ 72 72 matrix defaultmatrix dtransform abs exch abs .min
+ dup 150 lt //systemdict /DITHERPPI known not and
+} bind def
+/.setdefaulthalftone {
+ .useloresscreen { .setloreshalftone } { .sethireshalftone pop } ifelse
+} bind def
+/.setdefaultscreen {
+ .useloresscreen { .setloresscreen } { .sethiresscreen } ifelse
+ .setdefaultbgucr
+} bind def
.setdefaultscreen
initgraphics
@@ -1560,21 +1533,60 @@ false setpacking
} 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
+% Conditionally turn image interpolation on or off.
+currentdict /INTERPOLATE known not { (%END INTERPOLATE) .skipeof } if
+/.interpolate {
+ dup /Interpolate .knownget not { false } if
+ /INTERPOLATE .systemvar ne {
+ dup gcheck .currentglobal exch .setglobal
+ exch dup length dict copy
+ dup /Interpolate /INTERPOLATE .systemvar put
+ exch .setglobal
} if
} bind odef
-/image { .nointerpolate image } bind odef
-/imagemask { .nointerpolate imagemask } bind odef
-%END NOINTERPOLATE
+/image {
+ dup type /dicttype eq {
+ .interpolate image
+ } {
+ /INTERPOLATE .systemvar {
+ 8 dict begin
+ /ImageType 1 def
+ /DataSource 1 index def
+ /ImageMatrix 2 index def
+ /BitsPerComponent 3 index def
+ /Decode {0 1} def
+ /Height 4 index def
+ /Width 5 index def
+ /Interpolate true def
+ currentdict end
+ gsave /DeviceGray setcolorspace image grestore
+ 5 { pop } repeat
+ } {
+ image
+ } ifelse
+ } ifelse
+} bind odef
+/imagemask {
+ dup type /dicttype eq {
+ .interpolate imagemask
+ } {
+ /INTERPOLATE .systemvar {
+ 8 dict begin
+ /ImageType 1 def
+ /DataSource 1 index def
+ /ImageMatrix 2 index def
+ /BitsPerComponent 1 def
+ 3 index { {1 0} } { {0 1} } ifelse /Decode exch def
+ /Height 4 index def
+ /Width 5 index def
+ /Interpolate true def
+ currentdict end imagemask 5 { pop } repeat
+ } {
+ imagemask
+ } ifelse
+ } ifelse
+} bind odef
+%END INTERPOLATE
% Establish local VM as the default.
false /setglobal where { pop setglobal } { .setglobal } ifelse
@@ -1593,15 +1605,18 @@ $error /.nosetlocal false put
.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
+% Remove systemdict entries for things that have been bound in where used
+% and that shouldn't be accessible by name, and close up systemdict.
+currentdict /filterdict .undef
+currentdict /.cidfonttypes .undef
+currentdict /.colorrenderingtypes .undef
+currentdict /.formtypes .undef
+currentdict /.halftonetypes .undef
+currentdict /.imagetypes .undef
+currentdict /.imagemasktypes .undef
+currentdict /.patterntypes .undef
+currentdict /.shadingtypes .undef
+currentdict /.wheredict .undef
end
% Clean up VM, and enable GC.
diff --git a/gs/lib/gs_lev2.ps b/gs/lib/gs_lev2.ps
index 742dc22bf..10f76989d 100644
--- a/gs/lib/gs_lev2.ps
+++ b/gs/lib/gs_lev2.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1990, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1990, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -248,6 +248,32 @@ end
setobjectformat
} if
+% Aldus Freehand versions 2.x check for the presence of the
+% setcolor operator, and if it is missing, substitute a procedure.
+% Unfortunately, the procedure takes different parameters from
+% the operator. As a result, files produced by this application
+% cause an error if the setcolor operator is actually defined
+% and 'bind' is ever used. Aldus fixed this bug in Freehand 3.0,
+% but there are a lot of files created by the older versions
+% still floating around. Therefore, at Adobe's suggestion,
+% we implement the following dreadful hack in the 'where' operator:
+% If the key is /setcolor, and
+% there is a dictionary named FreeHandDict, and
+% currentdict is that dictionary,
+% then "where" consults only that dictionary and not any other
+% dictionaries on the dictionary stack.
+.wheredict /setcolor {
+ /FreeHandDict .where {
+ /FreeHandDict get currentdict eq {
+ pop currentdict /setcolor known { currentdict true } { false } ifelse
+ } {
+ .where
+ } ifelse
+ } {
+ .where
+ } ifelse
+} bind put
+
% ------ Virtual memory ------ %
/currentglobal % - currentglobal <bool>
@@ -325,7 +351,6 @@ end % serverdict
pop
serverdict /.jobsave save put
serverdict /.jobsavelevel 1 put
- .userdict /quit /stop load put
} ifelse
% Reset the interpreter state.
clear cleardictstack
@@ -346,6 +371,9 @@ end % serverdict
} ifelse
} odef
/startjob { % <exit_bool> <password> startjob <ok_bool>
+ % This is a hack. We really need some way to indicate explicitly
+ % to the interpreter that we are under control of a job server.
+ .userdict /quit /stop load put
{ .startnewjob true } .startjob
} odef
@@ -509,9 +537,7 @@ currentdict end
dup .setpatternspace
} bind
} if
- /.setdevicenspace where
- { pop /DeviceN { dup 2 get setcolorspace dup .setdevicenspace } bind
- } if
+ % If DeviceN space is included, gs_ll3.ps registers it.
/.setdevicepixelspace where
{ pop /DevicePixel { dup .setdevicepixelspace } bind
} if
@@ -589,6 +615,12 @@ end
dup .buildcolorrendering1 .setcolorrendering1
} .bind put
+% Note: the value 101 in the next line must be the same as the value of
+% GX_DEVICE_CRD1_TYPE in gscrdp.h.
+.colorrenderingtypes 101 {
+ dup .builddevicecolorrendering1 .setdevicecolorrendering1
+} .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,
diff --git a/gs/lib/gs_ll3.ps b/gs/lib/gs_ll3.ps
index 08e0be77c..80ae53b9a 100644
--- a/gs/lib/gs_ll3.ps
+++ b/gs/lib/gs_ll3.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -17,7 +17,6 @@
% 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.
@@ -66,122 +65,114 @@ languagelevel dup 2 max .setlanguagelevel
} if
currentdict /.bindscratch .undef
-% ------ HalftoneTypes 6, 10, 16 ------ %
-
-% This code depends on one new operator:
-%
-% <dict> <Width> <Height> <Thresholds> <bits> <shift> .setstriphalftone -
-%
-% <dict> 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 { % <source> <dest> <count> .copybytes -
- { 1 index read not { /sethalftone load /rangecheck signalerror exit } if
- 1 index exch write
- } repeat pop pop
+% ------ HalftoneTypes 6, 10, 16 and HalftoneMode ------ %
+
+% This code depends on an internal HalftoneType 7 with the following keys:
+% Width, Height, Width2, Height2, TransferFunction:
+% as for HalftoneType 16.
+% Thresholds: a string or bytestring holding the thresholds,
+% (Width x Height + Width2 x Height2) x BitsPerSample / 8 bytes,
+% as for HalftoneType 16 except that the samples may be either
+% 8 or 16 bits wide.
+% BitsPerSample: 8 or 16.
+
+% Note that this HalftoneType never appears in halftone dictionaries given
+% to sethalftone, only as a component in those given to .sethalftone5,
+% so its numeric value can be chosen ad lib as long as it differs from the
+% other values that are legal in component dictionaries for .sethalftone5
+% (currently only 1 and 3).
+
+/.makehalftone7 { % <dict> <dict> <source> <Width> <Height>
+ % (<Width2> <Height2> | null) <BPS> .makehalftone7
+ % <setdict> <dict5> { .sethalftone5 }
+ 8 dict begin
+ /HalftoneType 7 def
+ /BitsPerSample exch def
+ dup null eq {
+ pop 0
+ } {
+ /Height2 1 index def /Width2 2 index def mul
+ } ifelse 3 1 roll
+ /Height 1 index def
+ /Width 2 index def
+ mul add BitsPerSample 8 idiv mul .bigstring
+ % Stack: dict source str
+ dup type /stringtype eq { readstring } { .readbytestring } ifelse
+ not { /sethalftone load /rangecheck signalerror exit } if
+ readonly /Thresholds exch def
+ /TransferFunction .knownget { /TransferFunction exch def } if
+ % If the original Thresholds was a file, replace it with
+ % a new one.
+ 1 index /Thresholds get type /filetype eq {
+ dup /Thresholds [ Thresholds ] cvx 0 () .subfiledecode put
+ } if
+ mark /HalftoneType 5 /Default currentdict end .dicttomark
+ { .sethalftone5 }
} bind def
-/.copythresholds { % <dict> <Width> <Height> <bits> .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
+/.bigstring { % <size> .bigstring <string|bytestring>
+ dup 65400 gt { .bytestring } { string } ifelse
} bind def
-/.sethalftone6 { % <dict> .sethalftone6 -
- % Keys: Width, Height, Thresholds, T'Function
- dup /Width get 1 index /Height get
- 8 .copythresholds
-} odef
-
-/.copythresholds2 { % <dict> <Width> <Height> <Width2> <Height2>
- % <bits> .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
+/.readbytestring { % <source> <bytestring> .readbytestring
+ % <bytestring> <filled>
+ % Note that since bytestrings don't implement getinterval,
+ % if filled is false, there is no way to tell how much
+ % was read.
+ true exch 0 1 2 index length 1 sub {
+ % Stack: source true str index
+ 3 index read not { pop exch not exch exit } if
+ 3 copy put pop pop
+ } for 3 -1 roll pop exch
} bind def
-% Copy a shifted rectangular threshold array into a BigStringEncode filter.
-% Note that the width and shift are in bytes, not samples.
-/.copyshifted { % <dest> <width> <B> <N> <R> <stride> <offset>
- % <source> .copyshifted -
-% Copy N blocks of <width> x B bytes from <source>.
-% 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
+/.sethalftone6 { % <dict> <dict> .sethalftone6 <setdict> <dict5>
+ % { .sethalftone5 }
+ % Keys: Width, Height, Thresholds, T'Function
+ dup /Thresholds get
+ 1 index /Width get 2 index /Height get
+ null 8 .makehalftone7
} bind def
-/.sethalftone10 { % <dict> .sethalftone10 -
- % Keys: XSquare, YSquare, Thresholds, T'Function
-% ****** DOESN'T HANDLE STRING SOURCE ******
- dup /XSquare get dup 2 index /YSquare get dup
- 8 .copythresholds2
-} odef
+/.sethalftone10 { % <dict> <dict> .sethalftone10 <setdict> <dict5>
+ % { .sethalftone5 }
+ % Keys: Xsquare, Ysquare, Thresholds, T'Function
+ % Note that this is the only one of these three HalftoneTypes
+ % that allows either a file or a string for Thresholds.
+ dup /Thresholds get dup type /stringtype eq { 0 () .subfiledecode } if
+ 1 index /Xsquare get dup 3 index /Ysquare get dup
+ 8 .makehalftone7
+} bind def
-/.sethalftone16 { % <dict> .sethalftone16 -
+/.sethalftone16 { % <dict> <dict> .sethalftone16 <setdict> <dict5>
+ % { .sethalftone5 }
% 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
+ dup /Thresholds get
+ 1 index /Width get 2 index /Height get
+ 3 index /Width2 .knownget { % 2-rectangle case
+ 4 index /Height2 get
} { % 1-rectangle case
- 16 .copythresholds
+ null
+ } ifelse 16 .makehalftone7
+} bind def
+
+.halftonetypes begin
+ 6 /.sethalftone6 load def
+ 10 /.sethalftone10 load def
+ 16 /.sethalftone16 load def
+end
+
+% Redefine sethalftone to recognize HalftoneMode.
+% We should redefine setscreen and setcolorscreen as well.
+/sethalftone {
+ /HalftoneMode getuserparam 0 eq {
+ //sethalftone
+ } {
+ pop .setdefaulthalftone
} ifelse
} odef
-{6 10 16} { dup /HalftoneType defineresource pop } forall
-
% ------ ImageTypes 3 and 4 (masked images) ------ %
.imagetypes
@@ -218,12 +209,22 @@ systemdict /.shadingtypes mark % not ll3dict
% 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
+ 1 index /ColorSpace get setcolorspace exec
} bind def
+
/.buildpattern2 { % <template> <matrix> .buildpattern2
% <template> <pattern>
- 1 index /Shading get .buildshading .buildshadingpattern
+ % We want to build the pattern without doing gsave/grestore,
+ % since we want it to load the CIE caches.
+ 1 index /Shading get
+ mark currentcolor currentcolorspace
+ counttomark 4 add -3 roll mark 4 1 roll
+ % Stack: -mark- ..color.. cspace -mark- template matrix shadingdict
+ { .buildshading } stopped {
+ cleartomark setcolorspace setcolor pop stop
+ } if
+ .buildshadingpattern
+ 3 -1 roll pop counttomark 1 add 2 roll setcolorspace setcolor pop
} bind def
.patterntypes
@@ -232,96 +233,15 @@ systemdict /.shadingtypes mark % not ll3dict
/shfill { % <shadingdict> shfill -
% Currently, .shfill requires that the color space
% in the pattern be the current color space.
- dup .buildshading
- 1 index /ColorSpace get
- gsave { setcolorspace .shfill } stopped grestore { stop } if
+ dup gsave { .buildshading .shfill } stopped grestore { stop } if
pop
} odef
% Establish an arbitrary initial smoothness value.
1 64 div setsmoothness
-% ------ Trapping ------ %
-
-% The PostScript-level trapping parameters are maintained in userdict,
-% and explicitly reinstalled upon restore.
-
-/Trapping mark
+% ------ ReusableStreamDecode filter ------ %
-/settrapparams dup { % <paramdict> settrapparams -
- /.trapparams .uservar dup length dict .copydict
- dup 2 index {
- % Stack: paramdict olddict olddict key value
- 2 index 2 index known { put dup } { pop pop } ifelse
- } forall pop
- dup .settrapparams % Let the operator check parameter validity.
- .userdict /.trapparams 3 -1 roll put pop
-} bind .makeoperator
-
-/.copyparams { % <obj> .copyparams <obj'>
- dup type /dicttype eq {
- dup length dict .copydict
- dup {
- .copyparams 3 copy put pop pop
- } forall
- } {
- dup type /arraytype eq {
- [ exch { .copyparams } forall ]
- } if
- } ifelse
-} odef
-
-/currenttrapparams dup { % - currenttrapparams <paramdict>
- /.trapparams .uservar .copyparams
-} bind .makeoperator
-
-/settrapzone dup { % - settrapzone -
- % ****** DUMMY ******
- newpath
-} bind .makeoperator
-
-% Define initial (dummy) trapping parameters.
-% These values are mostly complete guesses.
-userdict /.trapparams mark
- /BlackColorLimit 1.0
- /BlackDensityLimit 1.0
- /BlackWidth 1.0
- /ColorantZoneDetails 0 dict
- /Enabled true
- /HalftoneName null
- /ImageInternalTrapping false
- /ImageResolution 1
- /ImageToObjectTrapping true
- /ImageTrapPlacement /Center
- /SlidingTrapLimit 1.0
- /StepLimit 1.0
- /TrapColorScaling 0.0
- /TrapSetName null
- /TrapWidth 1.0
-.dicttomark readonly put
-
-.dicttomark /ProcSet defineresource pop
-
-% ------ Miscellaneous ------ %
-
-% Define additional user and system parameters.
-psuserparams begin
- /HalftoneMode 0 def
- /MaxSuperScreen 1016 def
-end
-pssystemparams begin % read-only, so use .forcedef
- /MaxDisplayAndSourceList 160000 .forcedef
-end
-
-% Define the IdiomSet, InkParams, and TrapParams resource categories.
-{ /IdiomSet /InkParams /TrapParams } {
- /Generic /Category findresource dup maxlength 3 add dict .copydict begin
- /InstanceType /dicttype def
- currentdict end /Category defineresource pop
-} forall
-
-% Define the ReusableStreamDecode filter.
-% ****** DOESN'T WORK FOR CONTENTS >64K ******
/.reusablestreamdecode { % <source> <dict> .reusablestreamdecode <file>
% <source> .reusablestreamdecode <file>
% Collect the filter parameters.
@@ -342,7 +262,7 @@ end
} {
4 index 2 index get dup null eq { pop } if
} ifelse
- 3 -1 roll pop filter
+ 3 -1 roll pop exch filter
exch pop true exch % set CloseSource for further filters
} for
% See if we can create the filter directly.
@@ -350,27 +270,150 @@ end
null 2 index { .reusablestream } .internalstopped {
pop pop
% No luck. Read the entire contents of the stream now.
+ dup type /filetype ne {
+ % Make a stream from a procedure or string data source.
+ 0 () .subfiledecode
+ } if
10 dict exch {
% Stack: dict filters parms CloseSource contdict file
dup 1000 string readstring
- 3 index dup length 4 -1 roll put not { break } if
+ 3 index dup length 4 -1 roll put not { exit } if
} loop pop
% Concatenate the contents into one big string.
% Stack: dict filters parms CloseSource contdict
- 0 1 index { length exch pop add } forall string
- exch {
+ 0 1 index { length exch pop add } forall
+ .bigstring exch {
% Stack: dict filters parms CloseSource string index substring
exch 1000 mul exch 2 index 3 1 roll putinterval
} forall
% Now create the stream on the string.
- null 3 -1 roll .reusablestream
+ null 2 index .reusablestream
} if
% We created the stream successfully: clean up.
4 { exch pop } repeat
- dup type /dicttype eq { pop } if pop
+ 1 index type /dicttype eq { exch pop } if exch pop
} odef
+
filterdict /ReusableStreamDecode /.reusablestreamdecode load put
+% ------ UseCIEColor ------ %
+
+% The library maintains and detects the UseCIEColor device parameter,
+% but it doesn't have access to the resource dictionaries. We also
+% want color space substitution to work in systems without a PostScript
+% interpreter. Therefore, we eagerly inform the library of changes in
+% the (effective) ColorSpace category that might affect the operation of
+% UseCIEColor. We must notice the following events:
+% 1) defineresource and undefineresource of the Default ColorSpaces.
+% 2) restore.
+% 3) Changes in current VM, which cause a different set of resources
+% to become visible.
+% #1 is rare. #2 is handled in C code. If checking the ColorSpace
+% category on #3 turns out to be expensive, we can cache more information
+% about whether these operations actually affect UseCIEColor.
+
+% This operator implements color space substitution in the library:
+% <index> <bool> .setsubstitutecolorspace -
+% <bool> = true means substitute the current color space for the one given
+% by <index>; <bool> = false means stop substituting. Substitution is not
+% affected by grestore/setgstate, but it is affected by restore.
+
+% ColorSpace defineresource and undefineresource for the Default keys
+% call .definedefaultcs and .undefinedefaultcs. See gs_res.ps.
+
+/.useciecolorkeydict mark
+ /UseCIEColor null
+.dicttomark readonly def
+/.definedefaultcs { % <index> <value> .definedefaultcs -
+ currentcolorspace
+ % Temporarily disable color substitution, in case the substitute
+ % color space is or mentions a color space that is currently
+ % being substituted.
+ currentdevice //.useciecolorkeydict .getdeviceparams exch pop exch pop
+ mark 5 -2 roll
+ % Stack: cspace UseCIEColor mark index value
+ { setcolorspace true .setsubstitutecolorspace }
+ stopped counttomark 1 add 1 roll cleartomark
+ % Stack: cspace UseCIEColor stopped?
+ 3 1 roll
+ currentdevice null true mark /UseCIEColor 6 -1 roll .putdeviceparams pop pop
+ setcolorspace { stop } if
+} bind def
+currentdict /.useciecolorkeydict undef
+
+/.undefinedefaultcs { % <index> .undefinedefaultcs -
+ false .setsubstitutecolorspace
+} bind def
+
+/.setdefaultcs { % <index> <value|null> .setdefaultcs -
+ dup null eq { pop .undefinedefaultcs } { .definedefaultcs } ifelse
+} bind def
+
+/.getdefaultcs { % <key> .getdefaultcs <value|null>
+ .GetInstance { 0 get } { null } ifelse
+} bind def
+
+/.setglobal { % <bool> .setglobal -
+ dup .currentglobal ne {
+ % We only want to change substitutions for color spaces
+ % whose definitions are actually changing.
+ /ColorSpace /Category findresource begin
+ % If there are no local definitions of the Default keys,
+ % changing VM can't affect the definition of any resource.
+ .LocalDefaults {
+ /DefaultGray .getdefaultcs
+ /DefaultRGB .getdefaultcs
+ /DefaultCMYK .getdefaultcs
+ end
+ 3 index .setglobal
+ /ColorSpace /Category findresource begin
+ /DefaultGray .getdefaultcs
+ /DefaultRGB .getdefaultcs
+ /DefaultCMYK .getdefaultcs
+ end
+ % Stack: bool oldgray oldrgb oldcmyk
+ % newgray newrgb newcmyk
+ dup 4 index ne { 2 exch .setdefaultcs } { pop } ifelse
+ dup 4 index ne { 1 exch .setdefaultcs } { pop } ifelse
+ dup 4 index ne { 0 exch .setdefaultcs } { pop } ifelse
+ pop pop pop pop
+ } {
+ end .setglobal
+ } ifelse
+ } {
+ .setglobal
+ } ifelse
+} .bind odef % bind in .setglobal
+
+% ------ DeviceN color space ------ %
+
+% This isn't quite right, because the ColorSpaceFamily resource will exist
+% even with languagelevel < 3, but it's close enough.
+
+/.setdevicenspace where {
+ pop colorspacedict /DeviceN {
+ dup 2 get setcolorspace dup .setdevicenspace
+ } bind put
+} if
+
+% ------ Miscellaneous ------ %
+
+% Define additional user and system parameters.
+psuserparams begin
+ /HalftoneMode 0 def
+ /MaxSuperScreen 1016 def
+end
+pssystemparams begin % read-only, so use .forcedef
+ /MaxDisplayAndSourceList 160000 .forcedef
+end
+
+% Define the IdiomSet and InkParams resource categories.
+{ /IdiomSet /InkParams } {
+ /Generic /Category findresource dup maxlength 3 add dict .copydict begin
+ /InstanceType /dicttype def
+ currentdict end /Category defineresource pop
+} forall
+
/languagelevel 3 def
% When running in LanguageLevel 3 mode, this interpreter is supposed to be
% compatible with Adobe version 3010.
diff --git a/gs/lib/gs_mro_e.ps b/gs/lib/gs_mro_e.ps
index e64b2c5fa..f5d931e31 100644
--- a/gs/lib/gs_mro_e.ps
+++ b/gs/lib/gs_mro_e.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -45,7 +45,7 @@ StandardEncoding 97 31 getinterval aload pop
/guillemotright /ellipsis /space /Agrave /Atilde /Otilde /OE /oe
/endash /emdash /quotedblleft /quotedblright
/quoteleft /quoteright /divide /.notdef
- /ydieresis /Ydieresis /fraction /currency
+ /ydieresis /Ydieresis /fraction /Euro % Euro replaces currency
/guilsingleft /guilsingright /fi /fl
% \34x
/daggerdbl /periodcentered /quotesinglbase /quotedblbase
diff --git a/gs/lib/gs_pdf_e.ps b/gs/lib/gs_pdf_e.ps
index 063bc8333..cd562a80d 100644
--- a/gs/lib/gs_pdf_e.ps
+++ b/gs/lib/gs_pdf_e.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -38,7 +38,7 @@ ISOLatin1Encoding 97 31 getinterval aload pop
/quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron
/Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron /.notdef
% \24x
- /.notdef
+ /Euro
ISOLatin1Encoding 161 12 getinterval aload pop
/.notdef
ISOLatin1Encoding 174 82 getinterval aload pop
diff --git a/gs/lib/gs_pdfwr.ps b/gs/lib/gs_pdfwr.ps
index 1c64c3dc7..ef00a3fa8 100644
--- a/gs/lib/gs_pdfwr.ps
+++ b/gs/lib/gs_pdfwr.ps
@@ -182,6 +182,19 @@ currentdict /.pdfmarkparams .undef
{ .distillerdevice //.distillerparamkeys .getdeviceparams .dicttomark
} odef
+% Patch 'where' so that the distillerparams operators are only visible
+% if the pdfwrite device is the current one, for the benefit of badly
+% designed PostScript files that "know" they have to do something different
+% if a distiller is processing them.
+.wheredict /currentdistillerparams {
+ currentdevice .devicename /pdfwrite eq {
+ .where
+ } {
+ .where pop dup //systemdict eq { pop false } { true } ifelse
+ } ifelse
+} bind put
+.wheredict /setdistillerparams .wheredict /currentdistillerparams get put
+
% Patch the 'show' operators to pass the data to the device.
% We use pseudo-parameters named /show and /showxxx to pass the data,
% as documented in gdevpdft.c. THIS IS A HACK.
@@ -338,6 +351,7 @@ currentdict /.pdfmarkparams .undef
/.pdfshow % <string> -mark- {<cx> <cy> <char>} {<ax> <ay>}
% <showproc> .pdfshow -
{ counttomark 2 add 1 roll .pdfwrite?
+ % Stack: showproc string -mark- ...params... pdfwrite?
{ .pdfdoshow }
{ cleartomark pop false }
ifelse
diff --git a/gs/lib/gs_rdlin.ps b/gs/lib/gs_rdlin.ps
new file mode 100644
index 000000000..d94111652
--- /dev/null
+++ b/gs/lib/gs_rdlin.ps
@@ -0,0 +1,22 @@
+% Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+%
+% This file is part of Aladdin Ghostscript.
+%
+% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+% or distributor accepts any responsibility for the consequences of using it,
+% or for whether it serves any particular purpose or works at all, unless he
+% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+% License (the "License") for full details.
+%
+% Every copy of Aladdin Ghostscript must include a copy of the License,
+% normally in a plain ASCII text file named PUBLIC. The License grants you
+% the right to copy, modify and redistribute Aladdin Ghostscript, but only
+% under certain conditions described in the License. Among other things, the
+% License requires that the copyright notice and this notice be preserved on
+% all copies.
+
+
+% Patch for systems with readline support in the interpreter.
+
+% Disable the prompt message, since readline will generate it.
+/.promptmsg { } def
diff --git a/gs/lib/gs_res.ps b/gs/lib/gs_res.ps
index 72c891877..21af18447 100644
--- a/gs/lib/gs_res.ps
+++ b/gs/lib/gs_res.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -431,11 +431,11 @@ pop readonly pop end
mark
% Non-Type categories with existing entries.
/ColorSpaceFamily
- mark colorspacedict { pop } forall .packtomark
+ { } % These must be deferred, because optional features may add some.
/Emulator
mark EMULATORS { cvn } forall .packtomark
/Filter
- mark filterdict { pop } forall .packtomark
+ { } % These must be deferred, because optional features may add some.
/IODevice
% Loop until the .getiodevice gets a rangecheck.
errordict /rangecheck 2 copy get
@@ -454,7 +454,7 @@ mark
/FormType
{ } % These must be deferred, because optional features may add some.
/HalftoneType
- {1 2 3 4 5}
+ { } % These must be deferred, because optional features may add some.
/ImageType
{ } % Deferred, optional features may add some.
/PatternType
@@ -520,7 +520,9 @@ counttomark 2 idiv
} bind def
/ColorRendering mark /InstanceType /dicttype .definecategory
-/ColorSpace mark /InstanceType /arraytype .definecategory
+% ColorSpace is defined below
+% Encoding is defined below
+% Font is defined below
/Form mark /InstanceType /dicttype .definecategory
/Halftone mark /InstanceType /dicttype .definecategory
/Pattern mark /InstanceType /dicttype .definecategory
@@ -537,6 +539,64 @@ counttomark 2 idiv
(END MISC) VMDEBUG
+% Define the ColorSpace category.
+
+/.defaultcsnames mark
+ /DefaultGray 0
+ /DefaultRGB 1
+ /DefaultCMYK 2
+.dicttomark readonly def
+
+% The "hooks" are no-ops here, redefined in LL3.
+/.definedefaultcs { % <index> <value> .definedefaultcs -
+ pop pop
+} bind def
+/.undefinedefaultcs { % <index> .undefinedefaultcs -
+ pop
+} bind def
+
+/ColorSpace mark
+
+/InstanceType /arraytype
+
+% We keep track of whether there are any local definitions for any of
+% the Default keys. This information must get saved and restored in
+% parallel with the local instance dictionary, so it must be stored in
+% local VM. Therefore, we use a local array (actually, a procedure)
+% to hold the flag.
+
+% We'll need to use .forceput to initialize this correctly.
+/.LocalDefaults null
+
+/DefineResource {
+ 2 copy /Generic /Category findresource /DefineResource get exec
+ exch pop
+ exch //.defaultcsnames exch .knownget {
+ 1 index .definedefaultcs
+ currentglobal not { /.LocalDefaults load 0 true put } if
+ } if
+} bind
+
+/UndefineResource {
+ dup /Generic /Category findresource /UndefineResource get exec
+ //.defaultcsnames exch .knownget {
+ .undefinedefaultcs
+ currentglobal not {
+ % Recompute .LocalDefaults by scanning. This is rarely needed.
+ /.LocalDefaults load 0 false //.defaultcsnames {
+ pop .LocalInstances exch known { pop true exit } if
+ } forall put
+ } if
+ } if
+} bind
+
+.definecategory % ColorSpace
+
+currentglobal false setglobal
+/ColorSpace /Category findresource
+ /.LocalDefaults [false] cvx .forceput % category is global, array is local
+setglobal
+
% Define the Encoding category.
/Encoding mark
@@ -668,7 +728,7 @@ end % level2dict
/.fixresources {
% Encoding resources
- EncodingDirectory
+ EncodingDirectory
{ dup length 256 eq
{ /Encoding defineresource pop }
{ pop pop }
@@ -688,6 +748,10 @@ end % level2dict
/sRGB exch /ColorSpace defineresource pop
systemdict /CIEsRGB undef
} if
+ % ColorSpaceFamily resources
+ colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall
+ % Filter resources
+ filterdict { pop dup /Filter defineresource pop } forall
% FontType and FMapType resources
buildfontdict { pop dup /FontType defineresource pop } forall
mark
@@ -696,6 +760,8 @@ end % level2dict
counttomark { dup /FMapType defineresource pop } repeat pop
% FormType resources
.formtypes { pop dup /FormType defineresource pop } forall
+ % HalftoneType resources
+ .halftonetypes { pop dup /HalftoneType defineresource pop } forall
% ColorRenderingType resources
.colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall
% ImageType resources
diff --git a/gs/lib/gs_sym_e.ps b/gs/lib/gs_sym_e.ps
index 8e143b9d6..0f2215fb9 100644
--- a/gs/lib/gs_sym_e.ps
+++ b/gs/lib/gs_sym_e.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1991, 1994, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1991, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -54,7 +54,7 @@ ifelse
% \200
StandardEncoding 0 32 getinterval aload pop % /.notdef
% \240
- /.notdef /Upsilon1 /minute /lessequal
+ /Euro /Upsilon1 /minute /lessequal
/fraction /infinity /florin /club
/diamond /heart /spade /arrowboth
/arrowleft /arrowup /arrowright /arrowdown
diff --git a/gs/lib/gs_trap.ps b/gs/lib/gs_trap.ps
new file mode 100644
index 000000000..c268fd6af
--- /dev/null
+++ b/gs/lib/gs_trap.ps
@@ -0,0 +1,104 @@
+% Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+%
+% This file is part of Aladdin Ghostscript.
+%
+% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+% or distributor accepts any responsibility for the consequences of using it,
+% or for whether it serves any particular purpose or works at all, unless he
+% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+% License (the "License") for full details.
+%
+% Every copy of Aladdin Ghostscript must include a copy of the License,
+% normally in a plain ASCII text file named PUBLIC. The License grants you
+% the right to copy, modify and redistribute Aladdin Ghostscript, but only
+% under certain conditions described in the License. Among other things, the
+% License requires that the copyright notice and this notice be preserved on
+% all copies.
+
+
+% PostScript LanguageLevel 3 in-RIP trapping support.
+
+ll3dict begin
+
+% We need LanguageLevel 2 or higher in order to have setuserparams and
+% defineresource.
+languagelevel dup 2 max .setlanguagelevel
+
+% ------ Trapping ------ %
+
+% The PostScript-level trapping parameters are maintained in userdict,
+% and explicitly reinstalled upon restore.
+
+/Trapping mark
+
+/settrapparams dup { % <paramdict> settrapparams -
+ /.trapparams .uservar dup length dict .copydict
+ dup 2 index {
+ % Stack: paramdict olddict olddict key value
+ 2 index 2 index known { put dup } { pop pop } ifelse
+ } forall pop
+ dup .settrapparams % Let the operator check parameter validity.
+ .userdict /.trapparams 3 -1 roll put pop
+} bind .makeoperator
+
+/.copyparams { % <obj> .copyparams <obj'>
+ dup type /dicttype eq {
+ dup length dict .copydict
+ dup {
+ .copyparams 3 copy put pop pop
+ } forall
+ } {
+ dup type /arraytype eq {
+ [ exch { .copyparams } forall ]
+ } if
+ } ifelse
+} odef
+
+/currenttrapparams dup { % - currenttrapparams <paramdict>
+ /.trapparams .uservar .copyparams
+} bind .makeoperator
+
+/settrapzone dup { % - settrapzone -
+ % ****** DUMMY ******
+ newpath
+} bind .makeoperator
+
+% Define initial (dummy) trapping parameters.
+% These values are mostly complete guesses.
+userdict /.trapparams mark
+ /BlackColorLimit 1.0
+ /BlackDensityLimit 1.0
+ /BlackWidth 1.0
+ /ColorantZoneDetails 0 dict
+ /Enabled true
+ /HalftoneName null
+ /ImageInternalTrapping false
+ /ImageResolution 1
+ /ImageToObjectTrapping true
+ /ImageTrapPlacement /Center
+ /SlidingTrapLimit 1.0
+ /StepLimit 1.0
+ /TrapColorScaling 0.0
+ /TrapSetName null
+ /TrapWidth 1.0
+.dicttomark readonly put
+
+.dicttomark /ProcSet defineresource pop
+
+% Define the TrapParams resource category
+{ /TrapParams } {
+ /Generic /Category findresource dup maxlength 3 add dict .copydict begin
+ /InstanceType /dicttype def
+ currentdict end /Category defineresource pop
+} forall
+
+% Define the TrappingType resource category.
+/Generic /Category findresource dup maxlength 3 add dict .copydict begin
+ /InstanceType /integertype def
+/TrappingType currentdict end /Category defineresource pop
+
+{1001} { dup /TrappingType defineresource pop } forall
+
+.setlanguagelevel
+
+end % ll3dict
diff --git a/gs/lib/gs_ttf.ps b/gs/lib/gs_ttf.ps
index 9e77ca8d4..1652098ee 100644
--- a/gs/lib/gs_ttf.ps
+++ b/gs/lib/gs_ttf.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -27,7 +27,9 @@
% Augment the FONTPATH machinery so it recognizes TrueType fonts.
/.scanfontheaders where { % only defined if DISKFONTS is recognized
- pop /.scanfontheaders [ .scanfontheaders aload pop (\000\001\000\000*) ] def
+ pop /.scanfontheaders [
+ .scanfontheaders aload pop (\000\001\000\000*) (true*)
+ ] def
} if
% <file> <key> .findfontvalue <value> true
@@ -282,6 +284,7 @@ ifelse def
0 1 255 { } for
} ifelse
DEBUG {
+ (cmap: length=) print counttomark =
([) print counttomark 1 sub -1 0 { index =only ( ) print } for (]) =
} if
} bind def
@@ -391,6 +394,19 @@ ifelse def
} for ] {
exch 8 getu32 exch 8 getu32 lt
} sort def
+ % In certain malformed TrueType fonts, tables overlap.
+ % Truncate tables if necessary.
+ 0 1 tabs length 2 sub {
+ dup tabs exch get exch 1 add tabs exch get
+ 1 index 8 getu32 2 index 12 getu32 add
+ 1 index 8 getu32 gt {
+ (**** Warning: ) print 1 index 0 4 getinterval print
+ ( overlaps ) print dup 0 4 getinterval print
+ (, truncating.) = flush
+ dup 8 getu32 2 index 8 getu32 sub
+ 2 index 12 3 -1 roll putu32
+ } if pop pop
+ } for
} bind def
% - .readttdata -
@@ -428,14 +444,14 @@ ifelse def
} bind def
% - .makesfnts -
-% Defines checksum, getloca, head, locatable, numglyphs, post, sfnts, upem
+% Defines checksum, getloca, head, locatable, numloca, post, sfnts, upem
/.makesfnts {
.readttdata
/head tabdict /head get def
/checksum head 8 getu32 def
/locatable tabdict /loca get def
/post tabdict /post .knownget not { null } if def
- /numglyphs
+ /numloca
locatable dup type /stringtype eq
{ length }
{ 0 exch { length add } forall }
@@ -455,7 +471,7 @@ ifelse def
dup add locatable exch .indexloca getu16 dup add
} def
2 idiv 1 sub
- } ifelse def % numglyphs
+ } ifelse def % numloca
% If necessary, re-partition the glyfs.
tabdict /glyf get dup type /stringtype ne {
.dividesfnts tabdict /glyf 3 -1 roll put
@@ -496,6 +512,8 @@ ifelse def
/len1 0 glyfs { length add } forall def
% Determine where to split the glyfs by scanning loca.
% The very last entry in loca may be bogus.
+ % Note that some loca entries may be odd, but we can only
+ % split at even positions.
%
% Construct splitarray, the array of final lengths of
% the sfnts entries covering the glyfs (i.e., all but
@@ -503,12 +521,12 @@ ifelse def
/prevsplit 0 def
/prevboundary 0 def
/splitarray [
- 0 1 numglyphs 1 sub {
+ 0 1 numloca 1 sub {
getloca dup prevsplit maxstring add gt {
prevboundary prevsplit sub exch
/prevsplit prevboundary def
} if
- /prevboundary exch def
+ dup 1 and 0 eq { /prevboundary exch def } { pop } ifelse
} for
len1 prevsplit sub
] def
@@ -601,12 +619,16 @@ ifelse def
} ifelse
% If necessary, fabricate additional glyphencoding entries
% to cover all of loca.
- dup length numglyphs lt {
+ dup length numloca lt {
[ exch aload pop
- counttomark 1 numglyphs 1 sub {
+ counttomark 1 numloca 1 sub {
=string cvs (_) exch concatstrings cvn
} for ]
} if def
+ DEBUG {
+ (numloca=) print numloca =
+ (glyphencoding: length=) print glyphencoding dup length = === flush
+ } if
/Encoding
cmaptab cmaparray
counttomark array astore
diff --git a/gs/lib/gs_typ32.ps b/gs/lib/gs_typ32.ps
index b395ce402..7fce6d89e 100644
--- a/gs/lib/gs_typ32.ps
+++ b/gs/lib/gs_typ32.ps
@@ -97,24 +97,25 @@ end % .cidfonttypes
(%Type32BuildGlyph) cvn { % <font> <cid> %Type32BuildGlyph -
1 index /CharStrings get
% Stack: font cid CharStrings
- dup 2 index .knownget { exch pop } { 0 get } ifelse
+ dup 2 index .knownget
+ { exch pop } { 0 get } ifelse
% Stack: font cid cstr
dup .getmetrics32
- dup 14 gt {
- 11 1 roll setcachedevice2
+ dup 14 gt {
+ 8 index 8 index 13 3 roll setcachedevice2
} {
- 7 1 roll setcachedevice
+ 4 index 4 index 9 3 roll setcachedevice
} ifelse
- % Stack: font cid cstr w h nmetrics
- 4 -1 roll exch 1 index length 1 index sub getinterval
- % Stack: font cid w h bitstr
+ % Stack: font cid cstr w h nmetrics llx lly
+ 6 -1 roll 4 -1 roll 1 index length 1 index sub getinterval
+ % Stack: font cid w h llx lly bitstr
dup () eq {
- pop
+ pop pop pop
} {
- mark /Columns 4 index /Rows 5 index /K -1 /EndOfBlock false /BlackIs1 true
- .dicttomark /CCITTFaxDecode filter 2 index 2 index true
- % Stack: font cid w h filter w h true
- [ 1 0 0 1 0 7 index ] 5 -1 roll imagemask
+ mark /Columns 6 index /Rows 7 index /K -1 /EndOfBlock false /BlackIs1 true
+ .dicttomark /CCITTFaxDecode filter 4 index 4 index true
+ % Stack: font cid w h llx lly filter w h true
+ [ 1 0 0 1 11 -2 roll exch neg exch neg ] 5 -1 roll imagemask
} ifelse
pop pop pop pop
} bind def
diff --git a/gs/lib/gs_type1.ps b/gs/lib/gs_type1.ps
index 697482617..c64be1ab4 100644
--- a/gs/lib/gs_type1.ps
+++ b/gs/lib/gs_type1.ps
@@ -107,33 +107,47 @@ ifelse
% The real work is done in an operator:
% <font> <code|name> <name> <charstring> .type1execchar -
-(%Type1BuildChar) cvn % <font> <code> %Type1BuildChar -
- { 1 index /Encoding get 1 index get .type1build
- } bind def
-(%Type1BuildGlyph) cvn % <font> <name> %Type1BuildGlyph -
- { dup .type1build
- } bind def
-/.type1build % <font> <code|name> <name> .type1build -
- { 2 index begin
- dup CharStrings exch .knownget not
- { 2 copy eq { exch pop /.notdef exch } if
+(%Type1BuildChar) cvn { % <font> <code> %Type1BuildChar -
+ 1 index /Encoding get 1 index get .type1build .type1execchar
+} bind def
+(%Type1BuildGlyph) cvn { % <font> <name> %Type1BuildGlyph -
+ dup .type1build .type1execchar
+} bind def
+% Note: this procedure is used for both Type 1 and Type 2 fonts.
+/.type1build { % <font> <code|name> <name> .type1build
+ % <font> <code|name> <name> <charstring>
+ 2 index begin
+ 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
- end .type1execchar
- } bind def
+ } if
+ end
+} bind def
% CCRun is an undocumented procedure provided for Type 4 fonts.
1183615869 internaldict begin
-/CCRun % <font> <code|name> <charstring> CCRun -
- { 1 index dup type /integertype eq
- { 3 index /Encoding get exch get }
- if exch .type1execchar
- } bind def
+/CCRun { % <font> <code|name> <charstring> CCRun -
+ 1 index dup type /integertype eq {
+ 3 index /Encoding get exch get
+ } if exch .type1execchar
+} bind def
end
% Register the font types for definefont.
buildfontdict 1 /.buildfont1 cvx put
buildfontdict 4 /.buildfont4 cvx put
+
+% Add Type 2 support if applicable.
+/.buildfont2 where not { (%END2) .skipeof } if
+pop
+(%Type2BuildChar) cvn { % <font> <code> %Type2BuildChar -
+ 1 index /Encoding get 1 index get .type1build .type2execchar
+} bind def
+(%Type2BuildGlyph) cvn { % <font> <name> %Type2BuildGlyph -
+ dup .type1build .type2execchar
+} bind def
+buildfontdict 2 /.buildfont2 cvx put
+%END2
diff --git a/gs/lib/gs_wan_e.ps b/gs/lib/gs_wan_e.ps
index 449887fd1..4e1424131 100644
--- a/gs/lib/gs_wan_e.ps
+++ b/gs/lib/gs_wan_e.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -31,7 +31,7 @@ ISOLatin1Encoding 46 50 getinterval aload pop
ISOLatin1Encoding 97 30 getinterval aload pop
/bullet
% \20x
- /bullet /bullet /quotesinglbase /florin
+ /Euro /bullet /quotesinglbase /florin
/quotedblbase /ellipsis /dagger /daggerdbl
/circumflex /perthousand /Scaron /guilsinglleft
/OE /bullet /bullet /bullet
diff --git a/gs/lib/ht_ccbnm.ps b/gs/lib/ht_ccbnm.ps
new file mode 100644
index 000000000..9d3448865
--- /dev/null
+++ b/gs/lib/ht_ccbnm.ps
@@ -0,0 +1,3137 @@
+%!
+% This file is a reformatting of data placed in the public domain by its
+% author, CalComp Technology, Inc. The original file bore this comment:
+%
+% convert 167.pat 167a360h.dat 167a360h.lin
+%
+% Aladdin Enterprises, Menlo Park, CA reformatted the original data as
+% PostScript halftone dictionaries, and hereby places this file in the
+% public domain as well.
+
+/BlueNoiseMaskBlack <<
+ /HalftoneType 3
+ /Width 167
+ /Height 167
+ /Thresholds <
+ff51ef01d993ec6bd87ae0b102f24fff9f52da29e9bbff389add8cd834f3a5cf26f879fb
+6afe32d2f8adfe79f7c760d0ea6ad87ae561f804ff53ed2dd95ec5ea52c1ff25f787ff94
+c7b3ff6cf7a7cb86f24388fecc5ce1be6bf356ffaef137cb4fd8b966c1ff43f9cb2fe4bc
+0bee36f554d969e91fed4ebffb79ff37b4f88affa501ed94e5bf0ac6fc8ef57cface63de
+7abfee7bb8fe4694ff2eed86f1a5ff70eeafd694c0f61a9cd883b6ff52affe8ef62bfec4
+93e578edc193f28609d9aee556f179ffc112fe87b9d618c89cf1b8875ac0dd49a8ff36b6
+f60affc1a1b9eda7cc93f679ff1ea7fb08a3ec5dd005e035e44ad9c00bed32d0afdd963d
+f6b215e085dcc5019ffe8dfb7ad9fa2b9fec9459ee79f8cf80d886ffa5cc95fe84ffa561
+ea89f2ca27da4fcbfb5ad83093f79a53d824dda53ef0adff29a7e0169ef2cf77d8b64ac7
+32b7db933bfb0de086cef223fdc932e0c20edd56d465ef33afd80bfe41afffcd7afa6dfe
+07c7b565e595ed39ffa5e64fd909ffe21d99f2d880e086c3dd8946fe24c84cfb0fbfe086
+edd165e5cb89db83f2b8fb87f2a15aff9af561ff0ff0acd875ffa9f92693fabe54e510f1
+45a5e6cc03d8fbacdc4cafff62e0b329f95cc0da2de0c015d453a4fe86f270aae289fec5
+48bee483ff56c4ff9013d893f868ffd834bafa19f6a5fe87f703fbc59ef176fe5b7ae4a7
+5aed79fb9ebff296e282c0ff59f296c5e12fa5ec22becfa2ed2dfaaf44d8bf64f286ff7a
+afc56bd0fe8c05f964fe52a5f9d17ae091e488d9aa38f84993ffb94ffa30fea5467bd213
+fab0d868afd990e083fc2dedc2449be7c249edd793db84d0ff875efeb98612c5fd25c0ed
+11c6eb7be00db0f35afa86ffafdd07d83cc6ff13d676eaacff1aeebf9ae669bde46eed42
+cbb57ce75ba4e081d85be09fd961e845acd833d9ff45bffa95d12ae57b3cff17b5f97bd8
+ad61fb79d3fc67b4f43bff79d98acbff79f7b025e03dcef62ffba53fe5c3aaed1abfed2a
+adf260ff2ef357ffc395bfde289fed7dd868e5b6fe93db77e22ac9fe1df347c858d0b669
+fed879ffb28628ff61f8af1ac2f0933eddff9a6ae05f9ffe934affa2fb6dcb9bd8b633ed
+64fb9df6b67aed58fb25d963d8a635fb08d7f83afd9dbefb02f48efec24bff0eedbd41b7
+ff7ec1fe67f598c7a4df14d963ffa5f9d886c9e946dc24e7bf1aed9944c2df83d893e252
+fb1da5e303ddc297fbb58ade81edbe72ff4fce9bd97cffc913daafcf84e56cdd01fe6df4
+d516feadef0ed82eec55ff8ffbaa51e078b6fa94ff1ae0a50bef3ad3fbc0a5ca35ed9ce0
+2fd5f6b64ebef388facf52f1d7af37c3ee3eff1cf7ce92e4ae48d01ef993cfa1f18cf57c
+fec293f2b250afcd1eea79e04fd91fed93ccb378fe87f21db1e417ecaf0870f486fe89ec
+b60bc361eea56bf49cfc83ffb66ef7acff15f952ef0bd26bf2bf56fd78ff6cd80de951d6
+15fab22df27afe5ee24395fb9e42fab91afe9ef1adcc4dafe29342c4ff97f679cb20d85c
+eac582ffd509e45ff27af7c766e09818ed5afeb669fa77febe6193f2d836e206a5dd8b18
+f4db7cb6d793e0874dfe24c9ff86de6bd932e04cca07da44e061ce7afed979ff57d398fe
+aad067fb2cf3d323e197c4fa7ada86cffbe026d851cc36f592feb325ffd208cb51d931cb
+e403da62ed93cba6fe87eb82de9bcab82fee5ffa7cff9fda5adfc0a0e533f4a5beea6ff0
+c667e0a5cd4bc631fb9bff5bc6f975bb45b5dd9fef94f701a5ed299feec2a5bfdc41aeff
+80f5b873d904e5cc3dd9af09fbd81d97ff7ac3fb34ffc8965afe02f550abedc681dc79ba
+f250fda6ff80fa9dff86fa96f32ae6bf0af1c2a5f22bc75ef99cc0e56193faac5eed55d4
+33ff4bbdafff80f194df5dd839e0c055affe89f793f05ea0fe86d8af2bfb46afdc37ff23
+f447f8a9cc9cc6b636ed84fe73f817c7afcc0dff52dd05a5ff28f779fb8eed86e50bb7ec
+1cc0ed93fb07ff60d981c7fa61ccfb874efe3189fbce21d94bceff90f7a279ff87f2a4c5
+85fec14ab8e66cedb64ff9d98fe479bfff0ca1fb60ee1094e8c40bc1dd22d85bd2b814b6
+ff5c9edf9337d988ff86ee0ddd40a6ffcb3cddbe06fe8bf09dea633ab8e510ff6dfb9bf2
+7efba4ed79df20d87afbc74ae038ffc09bc3f37bcda0d889d980ec1ffe45f4d493cc02d8
+87eb67fe81f193d686fecb7cd993e012d85bd877cffa6aaffe33e36fd086e638fd4bb4df
+9b3fc0dd7bd3ed9e5ff193faa02edf55c5eb15d849e058e575dda5f826afd07be09f21ce
+45fbd866cdf136e5a5fed83d9af35aaff06be539eda5dd85cbf94affaffa11acdc76b6ff
+88d808afea82ffcd6cdbad1fcafaed78d09fbfdc03d54fcd14d931d060ffa6e511b7f699
+ec79dd60e41bfe61f766fb14ff5ad890d9a51bff62f352ffa6d23ce04dd922edb65af240
+d160ffb6f526ffac39c1df81d9a5f94af4bfadd094ff0ff2afff1df6b905fec586d80ced
+c686fe3ba8f691fb7dff39f518ed80d8ff0bfa41ffaff288b424fabb7ad8b64abf6aedbe
+79fe86bdff98f679fe52ee1ab6e980d75ac1ed43f8d859b9f481fc50f227a5f442ffbf6c
+b2c3fe30fa4bb0f779ff93f687ff96edb13ec0ff5ad120aff707fd80d194ea0db6c99ec1
+e479f16afbbc7adc93e0bf22fb9fc2ff7dfabf32e7affe84eda94498dd86f19eff4cf217
+cc64d8a413fe2deb6cd879d886e59752e0a52af357ff62b3e871f2ca61de29cfacc79dcd
+62fb4688dfadcc79e85bfec6e59848f81bff93f7cc29ffd019e047cb02afd82ed876fc8f
+c622f69efe6acbaf1cfbc837e29fd96ac7e787d87fd8fb1554a5e491ed7cc5e027dc5be4
+4ad806c9fa6295ef86febf53d6a5ed32dd56d3f14ae838affe07e03fcaf22afc4086ee89
+d811afe4639cfb9308c0db24f7b8fe62d81de07bd18fff94fb27f1c97ce09cf63cfe26f9
+61d8ff79fad170e3c0a5fb10daaf24ffb99fe60ef05cfeb8a0c1f3982cedbe11dc9e3b82
+efd388de6fe004b1d958aaedb6fb6dd9fe65f286e5af3ffebe8ce42fb9ff7bed9962ffb4
+25b8fe9a3dfe0cf8459ce0ffcb66d81cfe43adefbfa2c2fb86f56da2eacc31d865f294ff
+3bbffa86ffa579ff8efa82bbd0a0fe6eb0d89dc2e5af5af897fc39c2e05dd3f29e69e47c
+d507e8b1fd5fd903eb57e07ddb6cbdfb53d686ca8ee19fc513b6ca3aafff9430dd51d87a
+ed99d154fa88ff93dc38e501e052cbfe67fdaf78f7c1ff09affe32c8a1fe79fb96f98739
+93efad43c7a5ff0fc1e07dec52cda5ed01df50d0f186db93f612e4b879e08bbaf374a90b
+f386e5c19cff883efe1eb5e037d2fb1aa8fe92e20ccf60e570b4cb2ce5c101d950e028ec
+59b7db13ff57f50affbd2bde68b5f518ffa943fbcc38ff92f39c46c2ed87f6a8c73cf4ac
+ff39b1ed08ff5deeaf45f5d96af29aec16ccfe80f498ff46fb08edc130d863bff77bff92
+f782b9dd3dd4ec1e8cd99dec52b7f35ed8b840e312d3ffbf1de597f926cba1fb5ed406ff
+6bfb84d88ffea50de546ed70d886fbcb4ceed02cd8f7bf50ffb161df09d0f480e679c5ff
+885bc0e450f577b5eda1c3f510feaf6dfb9db9f4a6ff94f631fa88bdd093dd75d2f286cd
+ed55d87bcbe578b3eb72d859c9ff9330fbbc70fe9fc50bcf9ae07bd9a4d819ffbe72b0ff
+4fdc83f8a545e0ad27c9b683e2af68f7a5fe21afd04ed92ae016a5f25fb7ffc55afb79d0
+ff85e822f1cb83f4a44ed8fb73d656ed64dc35f394f1aedc20e54ef532c0fa7bc6afff51
+f12e9fffa56afe865cec9ecf2ffb93f861abd959f20e96eeadff78d925c1ff4cfb289bd9
+80d0ed50de62c71bcd74bfd697ed4cfb33abfe41a4ff0ca0fe93f721baff0ec2fb29f8a6
+13e2afcc4ae527ee66fc5ff321fe62fa87e879d1fb03c2e923d861c6ef6ad8fa6ef3cc59
+ff94d351c4ea6beda6bffb6fffc986fb9538e0b12be4a913cb4cff64afdd6dc9f78835bf
+ff92b8fe93e579d9874dc4f87bcebc9ae03ad8fc219fde7bbedb19c6e901ddd13cfb78f1
+b949b5eacb2dffa5bfde44d801f2c499e085d87ccaff5fe51ebdf836ff7afb5af30dfe49
+aed97df1ca65e6c77ae0bc3bdc61ed519bf25ba5dd81edcf75f268ff95dd81d8a1d992d5
+a5c72ecf53fd31a3e05ea6fb92ff09b6fe1ebdd915acdd33e006f286b8ff0cf93d93eda1
+47e305beef86f4be67fa97e5abc59dfc30fe06bce7abed08e23ed114bfff2afae09544b1
+ff16f279ffaa67bff906ccfe6bf859b5fa98ff8ec2e022d997ff148aedc36af87afdb5e9
+8652fb3ef819f3af45ef87ff6ca5d894e493da85e068c1fd06e0af1cf9b726ef5ffbcb81
+fe88c4d981e1bf4eff3bb8fe1cdbaf06c1ff1ef541ff59f788ee9edd82baf286fec042ed
+76e589d0af64ff93fb79f5a4fe79e32d9fd987e5c71dd6f37dd0fe4cd817ffcc3cf251fb
+0fec53d87ee09661fe79cd9ffe7ff8a958ceb90affc1ea6dd85addc44ff4d286e4af43ed
+88e47dcb28b7e50ea4ff5eed81d8fc9f46e225d89f3b94feafd6a5bfe169dd93d0b841c4
+ed10f245d72dffc3a3e677f35aff96d078fe9ed817ade504b1fa2ff71bfc97c4e062a4ea
+7dd6f7ad5acb86ed7ae011db51ff09f7cb40d818e19ebfd951f235f7c24cea42d0ba6ac2
+da5ffcc976fe61aaff5ab8fc64a5e180ed76afd881dd92d881f9b6f258ffd01fb6f569c3
+ea44ef9efb71afd9882dfe97f6b00febb527ff60f295c9b733fe64ee4d7bfbcc79ddb636
+c552befa84fe63f1b8da29e510fe489eff31fb05f39ffd87cd7efeb6ee8742f927cea6c7
+86e952deaf4af595ff67f3d070e0a5d386ee098cf5d04ffe3487ec9bfab92ecaaffe7fd2
+93e0a969ff97f661f32eabfe83de77e19ec7a5ff0dee3a95f3ae4cf115cdf480da952ee8
+c421faa1d902fdb625ff60dea61b9cd839a1f9d849de27b4d162e01ed8f55ffbd5b73dc8
+89febd82e095d938fb11ffd693d9a2b3f2ad43f403fea5f186e007dba6cc14ff72f481ce
+93eed979cba5e077d82ce04ddca8049be1afd893ff3bed20acfb0fedc188d843c7b735fe
+c060ff48afd8ff30bee48dc9fb46dd12e5a5fb43bff023fb4bb7ed27d77bcd8fffc110cb
+a1ff02fb29ed5bd885ffcb19e9d18bddaf42e508edbf52ff95cb39feb96bebc67aef31ff
+b8fb85f3c25186ffadfa6fff93c1ff9731cba918ed86fa64d92efe5af779d0acdf844af6
+15ffd828e98ad8bf88d71fff9af6b84aecbf8fdf4eb6fc5fc007b8f566bfff5af7afff68
+fab8f64ffe15ed61d893fed781d86dff2cf9a5fd7aed9f11f195c1fb619eed930ff164b7
+d377ff6ad885e66aa5d87febc886f993fe07dc4be598f940afd990de7afa9be54ba9fb93
+28ff57fb99c2ff77f9b062ed7ae069c9f2439fe391cf6de444dc14e0afed9411bee603f3
+3a87dfb1f14fffafdf03edafd074ed0abeff569cecc1a5e586fe83bcff52f73afba8c73e
+cf79ff6afb37aefac930d8ff87e64bfe1396eac1189eed28d585dd79ca9fbdf269c037f2
+50e4aecb86e01dd852deafce38eb22e3c043fec3a5ff22ed99bdf24afe01c1ff3bfaa014
+d947df5bed6dfb79d865edca5cf23cbece11c1f8d550e0c0a5ec84d933add825dfc10dfb
+a5f62593ffd20af34ef795cd78ff61fa2fc4f280caa0cfaef954fe7de5c05f93ff9b52fb
+a5c79fe130caf31ffb51c639c1e212c99adab26ee580fe92de21d893cbed1a8ff69d42f2
+a2d485e5c54888f2cf79d95dff21b6fa46ff04b3e59fc3fa9b01ed57bff293ff87f76cfe
+86d97bf2af79e052d8b459fa19c796d0abf28ee362baf379ffc09bb8d0a5ee36ffa81cfe
+86b5ff7bf1a03187ff7bf649c511f388e469fe7af79ecf45d7aedd5ab6fe83d8af05fba8
+c890d1a3fe60e135fe5be576d80cdb9f24f8c545c0e21ddd42fe87f9b688dd7ab6ed954a
+a5fd76f11cccef47d815eb5ff27be45ba4ffd469e0afc720edb632fbafffa53afe94e888
+bfec7adf8bd1f74cff1890d3fe7affa23dd907d547e0a5ca51fe02cefb28f477fccd86e0
+66ec32de51d80dcaff30e5a81bf739ff24b6d987c5e56dd1ec18d964feb1e4b904b4d8fe
+9fbcff45efb2d93feb86ff60f114e579c1ed2cffbf5aed31e30de94cd7aff279db17eeb0
+fc78c9ed6cdda7f285ff93f1af1ad55dfe6cceff06fad1ed5add93ff65b9ff6bf5bf9dc3
+fe04f7c12fafed0efe5bfa73ffcd7ad809dfbd54f20fcbfc5bd830ef5797dd7abbef3eb8
+e026d0fb6af47efcbf17edb89de85bb6d395ed069fff3cf8a4fb81fe79f7b083d987d0ed
+6fddc38afd0ef5499ffa2da5fb91e525d851eda0fd8627f05acea0c80793feaf1ad9bd93
+fca7f73eafd97ce09ec3f86dffbf93fb1c9bd88dffc23f96e72eadfb13fe34ce60d86ecb
+ee78d90ce73ba0d96aaf30f9be3fafe60a9ae0ae35ff42a5d86ee687fb55d095e086d952
+a0e562ee70fac780ddaf36f1affe82c7ff2acffb75d9a465f787b6c6a5ea3098ff61f635
+beff86f83cc7afe56db6d60dbccb25e6c240ef65fd519ffeab58e495d67dedcd7be0c041
+cb5ef782ff6bd83bc0dd93e51cfe60f3d178dfc38cfa4bc72ed0a0fe5df21ffe4a93daaf
+42f062c0ff2dec5086fad467ffcf79d895d97df706fb4ca5ff93f481bbed7ce4ff95cb6a
+fed37dfad829fb86d1b1ed87ff4fd89fbef22bb0f414baf822fb99cb1da4ff6af99ec60a
+a1e51eb7eba542e413f3cd4ce50fff4dccb2dd83d893df70d913abe588ff4dc6f387ff79
+f493b75afb9ecc28e7c505bff93df25effaa04ff51f396ffa9c0df13affa94f578fb69d8
+81dda52efa4dff33afed86ff64e00cce95dd7abded22fb86d8a5e473f6a5bfdda408f09d
+3af286e453eca5d083eac324e04cd0ff5af72387e90de0ad2cf24ebb7fc3ee11fa53de24
+b7f409ff86cbfe63c9ed80daae45ffafed2bd84be06dffd066fb9461fec188ff82bffe79
+d893f186fb0bf341ff1ffaa0c1fe6cd81df7a124d950dd39d8ff88d80affb660fa88e07b
+cf85d82cddbd86db6bd808eb468cf2cc5ce00cd03feda7f639ffbf98ed6cbfe104d89af0
+85f962fb3bd0ff6dd39fcb08f33adac405f149ffc87ae0bf59ff0efdbf2bffb53bfa97bf
+fcae16c7a9cf60c1ff79f697caa6d9ff569fdd8bd67afbc779d958dd3993e4ab3dff4fc1
+e179d984e596fe86f32fafd943f4cd0af0b44adb25afed44de25d864e1afcd7be8c451dd
+2fee5be07ad2fe7df089feae18edabec79dbc198f030ff16fb9ff66dfbc822feb5f76dd4
+febe2bfe9dbcff8ec601b6d971e111cda9f779fe5bdd25cba5d888e5a501b4f437ffb681
+feaf5dfe97e066b7fb1df7a0ccb68d5df371e5bf85d93586ea9bfb43f0fb3db0d81feb53
+fe0293f2cf48ff1deda542fe99ee6beabc02fb9fd093fe07f73af351cf05dcc09aed6de2
+be87dd79cbf88afb7cbcfea5f97bff9f5bfdbe4696fe81f59cc7a7f154b5cb0fcfb868f9
+be3695f71cfe47afd893dfaf59b9e83e9ae3a54993dda23986edc478ec59b3fb86fe5bf8
+86f152e01fd989ed81ff54f419ff51f7c6e55bd969eccb51e993d833aef428d0af61ed3d
+d8fac59edb16f252ffc5f65ddc70e0a3d893ed67fc82dd87e3c12eafe595cb86e0afcf27
+c0f97effcb61f22ded66d8b79dc2ff7cf1a547fa11ffa525ff51fa31a8ed5ce51bcb62c0
+e831caed1ad9aced09b6d042ea04bffa2cff9ef23be1c581e5bf6bde86d0fb60ed43cff2
+0bcaafff79f2b8ff20f0b6deae4df91ac2e128eaafd420c79eff6cfba5ce34c6b2df72e3
+c086bd4493fe86fa15aadd1afb61ffcd7ce083ffd993fe8022ed45affe8ad8ac02b3d220
+ffb0065dfe15cdabc632f563faa4fe6ff25efe0af66cff9f17d149addd81e0bf90f160fb
+17afd85afeca91d87ecaed84d895e7b907d898ff8cf30d9adc51a8f886ff65d8f97bff92
+fb5cd8af6ee563fcaf23ff56fbcb3be9a611c97afe83befe61ed34d70fe088cf79fb05ff
+93d9a4fe7dd89644f2a5fe32d1aec54fffa2fa0f9efb932dd9feaded21b7c997ff79efc1
+87ba12f957ed38c101b2e2c094fbd465e02ced9dfe89f27dc7f5e2bf9ff943ff9eceb94b
+e008d832d876da93e550d9affc96f722feb00fff40bed093eb36e3b879e560f243aff619
+fe79c9ff68dc3bd95ad0fb79ffc660e02bcbaf48e027cf76e485edc242bcd18eee7bd807
+acff53f492ffb61ee54aa5dd86f966feac5afbbe51ce67f130d44aed60ffcb79e077e959
+ee0af367e56bf2d846c7f19810e080d6f643e557d8af40f7d993d3a7c98ffba5f550ff69
+c40ff7a4ff61d83bd950e5309a8427e071dc7aed1affb37cf797ff88f9bf3baff183e832
+e063d9c177eac5a5e427fe77f9a21bff33fbc29ee06ccf5ae03ca4f284faadfeb139edb6
+05f476b6f26fffc29dedb534ff12f5a5fe02e548b6f696ef77d7afe04ed8f79cc3ed21d0
+9ed981cbf41ce49be8a5c88dffba9df516bdfa04c599fb7fde92dc25ccb77dffab53facb
+6bff5a9ed984f224fe9cc632fb4dff0de060d884dd17b7ed87ca41b7dd7bee77ff86d6fb
+c4ffb7f108d393d985e4c241cd51ed229affc30ffe5dc97cf2a44cfb995afc7def95d95e
+cbee8fd8ae01ff32fb9cf293fdbb14e5c11e86e49fc77cdf93cefe12eaba1efb4cfec993
+d886db79d886ffce61e033b9fc2487ef7fbf32fb65ff54f115e642b8d886ff22fa54f30d
+e538d0af66d8a4ff2acbb638ffbfa5fe3bea07d0e67cb5ee39c1fb0afea5e06add7aeda2
+e56df1b6ff2def6bcefd34aff193f80afeafc80ef4bc45e58c4ca5fe5afb3df924f48efb
+bea5c5e04bdd87cfa5edb605ffd81fd3f331dc4dd409ffbd40da51eb88d2b579dd0cd667
+ebcc5396f7cf4aff29f951fb349bdca560e588da9f67f35efb37f860f2a51dfec19fdd67
+ccfeab04ffd88ad47fe195ff6dfd8eed5bc0d971e0afce79fe86d9fc43f36ce57bd8f487
+57f179d89bf78840ff1bd4a4eb78bace37bdf903ffb81bb2d9933e9fdd8dfaac52c1ff59
+d87ee0a334e697d967af16f8b6d979e0a8c96cd0acde16ea63fe78f4a2fb3af629fec76a
+baed86b6cc9cff84e0a86afb85febbf75ceec14eff85f72ea5ffd861bee992d8a5d887ed
+be50fdd279f20ac1e31cddb1c99adf32c6ed884cf213f9be43e5ce9351f309f9b629c6af
+c501b4fe39aafc9334ecb64fed1fb7e793da52fe169cd3e413c5fa5bb1e0a8c3f261fe27
+afe467ed80ccaf63e788fe49fbc7f554d01de59bdc80e524ff4bd0fb86fe2bccfedd6bec
+2ef2c012ef9ffe5a86ff93dc01d8b720b4d87fdd5994e59e52ff62f814aff12df6c30fe0
+a52495d912faa5bfe35fb7f08924fea208fb55f310ff45d7f39329ffbfa8fa83fea44bff
+0faffe5a94cbff83e09f71f59762ecafc0df6adaa5ef4afaa1f37ccfed15c6ff86f9c96d
+ff88c70fb6ed86c1fb42acfe932ac0fe1efb5495df84c8ff4cf696ff2ef4c241f2bd81bf
+13afe07bff64f605fb61c6abf289c143b5ef7a9c52c893feb24fff61e537f2b6c644b1f1
+57ff88f272ff90ccf81afbc20ade92e7ca6dd888e5b371f3b7ff72e658dd2893fbd04be0
+c16deed379e084ca9ae58601c4e69751e033d852cfed7abfee80d6fb08b7d83affc427d9
+ff19fb3e9ffe35fa86e06fdc2de54e93f6a54ddd06a1e2c03efba5ff3bb0e062c9ec70d9
+a9ed60da7ae2bf04f8b66ed910d05bd875de99d12cf9d895fe39edafd293b9cda0eb69d5
+10eaa6e058d5fab3ff21cf74dd87d994bed80ded9dfb79e89ee03fd709ed44afdb82f2b3
+79fe51a5fb5aff40facd39e14acc9ffe81efc4039cfe7af5b334b7fa3bbaec5eb0ffabf7
+41c0f08eff99f7bb30facd53e02ab5f26aedaf79eab359b7d893c2e473cd58d618ff97cb
+85ffd862caef7bd7ff2f9bf27ee564bffa22f19e02f54dff8bceaff536ffa0d834ed87fe
+93f29ffa14ff6deda54ee46ed89847fb29f342fe1ef596ff5ff71cffbe05d87ae8a8f702
+fbc41dff79fb60e32ccfbb1cc3fe6bfac0a4fe61d83de3c434bfed19d094dd679ffe7fb4
+fb1bafd96affafdf41d914d8fe7ccba4ff20f9c72ed966b4fe16d65ae00593e7a022ff95
+f77bd0a725fbd10dfbc887f64cff11f583ff93edae3febbf0eaffe27b7fb4487edd260d9
+27cfed6bda79ffd086e0c10af2439ad881e868fb9ee04ed824e579cbade10bceff90f807
+ffc0a5e17adc86b6cb51d9b684d99f67f33ff9be469ae556a0ed4eafd495c9a5ff70f95a
+addf9350e528f09dff6ef5a5ff7ad961f01fc1df06d4ee7dcaf243d837ea86f4afff964e
+ed18e07fd9a563f17bfbcb55dd81f47ac2fe47b8e085d861e53effc15e99e06ded28acdb
+7dd8a5e022d961c9f769fb9df155e56cccadf7be16fab6fe9508ffa5c73eaffe30a4fb82
+befe0ff746becb18aff77bff51b9fe5a89fb84be26afdd84eb68c5fe50d7ff75fa27cefe
+48f2ca94abd065ffd87ad2fa6ec2f632fe17f34be5c594ec2bceff7bd3be1eafdd0cd849
+e593fbbe9dff85f7a530e55299fe8bf9bf21cb5486e5bfa9ff5bef44cefd93de0e8cedaf
+ff25b4f26ccbfe69f303fdacd877edaafa41ff96c3fe68f2bb47b0f8befe0ab6d426e074
+d987ff09dd5393e9a74386e0afcc2cf797ed66bbdd52d2ed6ab4caa5ff7df2d23fb6c893
+df20ecc3d946eec7f35ad830fb119eeda507e0aded6eafe28726fde011edaf2ef2af27b4
+ea7bdd8bec7dd7ac06ff86f5b711aff779fcd061fe86fab603c64bf236eb53c7ff79dbc0
+0fe04ea8ff8efad106f267d09ec1fe861eeb58d0fec23f95d0eb3bd99e18d1afde952ff4
+c614dc81d9bf54e707d12cfe86eb8c44a2f27cff93bbfb1ec5b1f17dfdd051ffc4f65afb
+73ea7bd915cbf97bffaf27c2e950e029d95aa4fedc09fb64f5b4369ffe93499ffe7af186
+d9bf35c6f2933dc5fb0bc2ffd86082fec179fcb969ffd814ff53d041befe67dbbf41d861
+edc83cdd5193ed98ce2feea7fe8fd8b67ada8abaf424fbb476f1d061dc39b6fb93d92cf7
+0c95e0afc0ffa0317ef9d962a5ff86f6b0fb578dffbe5dafff52ef1aa5f387dd80e59bd9
+05ffb5e461dd37ed4bd0a0f94197e023a5e08e0ea1d834e0aefc59ffa548e41bf096fe7a
+fa8cf695ffc63286f0c0a5cf7affd102dcb7e716cda8e04dff90fa5fbfff6a9ceb9037a5
+edcbb638e6c609edbf81de86b6fa9ef224b0f079fa9afeb686ff95f3c514da5ae179d862
+e427cafb14fe43aae05fceff960df79eed7fc843fe87ddafed4dfa3a82e5b6eda614fbc7
+0be24fdd31c5e81cd8f986ccb688fec133ff4cfbb438b9f16dd82efcafcc96ff7aed64ce
+ff69c8fe38f4c6f267fec01a95d882f1c789d871db3fd816d055eb0188edd89644ff1aee
+56bef77dff6bb2f73ac1f477e824afe117ddbf45f7bafb1bf56efb5793db9f4afe3af7cb
+07e184d9fb33afd418cb4ce103d836a9ff80f7a5ff3df3b3ff5aaae569f1c686ed9e2ac7
+ea74d71cff64edafc560ff77d4a7f3d908ff5ccbe7945af07ad588ffa979ee9e42e505f7
+d449e093ceb76defa4fe4ad086ed9e4fe802c0db14e0af2ceeb884d9ab4a93dcaf52c6ed
+44e50baffe37faadf486ff94dc7cccfba75cfdd681d98de09a4bec33c1e486ff9405d298
+c2fb7bf688fea7cf5dd8984fdda0c3ff2ffac1a5e65b93ffc148b888c1ed68ff94f27cfb
+84f9cb52e0b118c3de9d0d88edd081d89f02ff3dd8fa81bafe52e092d89c16f8d831c6fb
+178ab7cc9bdb2887ffc0aafc1fed62cffb4dc7fe79d99d6bfa79ed0ff2c71ed866de93fb
+12c7ff81f8a75bfe86fba3d610f85efbb7ff21f39fff6cfbc19cf35ce7a006becd4be524
+feb52be1bf11aff463fa25fdafcba2fb20d94de6b8fd4bdd39d864d253ef03ff79e7ffb8
+0cf17ce460f20eccafed639bfed812ff4ae6a926d8b546ecbc74fb2cd2fe6188fbb8f5a2
+21fa48fed06ae8b85be534a5f371fa35ffbf5793e7b15ac2e545f867febef245d92db6de
+93f509a5e081b6f138ffc221d8affe61a5ff85f619ea59dc77bedf3ed3f273cb46f388e6
+76d706ec6bd87ae201d0b52edf85d87bc5ff65eeb66ff2c167ef74ff99ed2ccaa5db73e5
+0def60d079f2c55fa5ef7effa5ed29db94e086c72dce7ae067d897d092e073ff20d5f435
+a4e493d883cef772ffdb9f20e59af15895e5c13ae04dd9bf9bedb77bf6a715ff93ddc204
+cba8de79e2acfe03f49ffe74ee93d83b7fd19af986ff41d858c9f835ff13d0af5ae5a1fb
+5999d1eb4be0afcb7dff99f625a5fe9429bde69cc735affe8ade94d03efec293f679ff52
+f920fd42d9ae31fcd89b43faa2de41d95cb5ff50c0ff5ad882ff93faa52effd61de3be0c
+c2fe6bf53bb3eda320f6afff1ffa47fe32f394dab950c3ef52f704fe59b6c70e8bcffe65
+d988c9f905ffaf7af980fe37c912de4dd9c279ef55fc9fee4cc1f529f081dc86d724d9b0
+1cfbaeef02e553ce9ff27dffbb68dc94ed76f6bf89f23ebfe42b93fb9c39feb72ed95eed
+c66cefafff07f75dffdb26f056ff83f1af31ec5bdd87cfade08bd185ecc18d10ffafd00b
+c2fb82f7d479eb1794f3b8e240d808dec06293fb9e67f25bacd880cbfb56feddc040a5ec
+88dd86d8ae58fb79afff87d17cde9ff038fdacf43bbeee0cff43a8db72efcb1cdd5ef28f
+ff93fb83feb024d86de17bff0fafd86bcf3aff53f36bffc761e087ffa5bcec12c0e02a92
+f0b249b8de30ff09cba9ff7ef7bf03c4da79edc986feab0de14dd863de91d8bb79cda5c8
+1ce163da9bbeff13baf23ca0ef58ff1bf8b8e679df61ec932fccb704fb9fc5df8728afed
+80fe76eeace052cbfe8ccff818ffbc0ed88e5f95fdc352cb14f165e9c005c5e51ad92ffb
+bf71c4e06cd962e07cb3d878bfeb86d82dbbff95d784e063cc2ce040d0f888fe1db4cf99
+fb50ffb7ed79e0a2cd3f94f5af4dc925fb6afe78a3fad31bfea5fd68d297e06fed17d952
+e5a9ff51f80cafe039cdfb86ff93f9ac43fb15b1ff6df79fbff912fb4dcca5fa68c0fe0d
+d87ddd9646c4f534fa7bffaaf255ddac47f936fe9efa5bc79fcd3cff10f4b62ddf3d96ed
+9f61f27de9f9d206ef93ffa9bfff26f69afe66f281e0a541ff19b1f729ff9bfa4efea0f6
+1dfe56f3a34ae909fe3cbaf3a4c0f06db6ec4dbff761ed86df9f1a93fac00bfbaeec0ed0
+fc8df081d848cbed5dbee681d90cec7bf255fb94d088fe73d883ddc07bff54f176b9dc35
+d01fedc198c4e546d932ed49a8d888e079ed34afd974e5affb5cceff69acd887da4fe088
+fe7aedc16dd3b0e814b7f125f8b96db2d87bed88ffbf48c4e293ff266bafe079d835e24b
+9ed978df3dd0a4ff5cedc896ed7fd1a3cb18beed2ac762d0afe579fbc86ef7c3a6e55aff
+0e97ff08c8a5e085d922d73df2c3d933afdd7ad882fe9c2fe160db96e8ab06ff933cf95c
+c6a0fb22daaf3cf9b628ed44ec22a5e792d89ff71a9fed7ed970ff66f378faa5fd93c3ff
+61f425fe95c4ff1df5c1369cf123b5ed03fec617eec01cafe522ff93f55c85d8fe71dd55
+ecc7fb4afe01d969e5a8fb32d94fc99fff5afb99f483fdc951fbc187ec23cbb20dfa61c1
+fe51f17ae66dcca9e492ff3997d90fabdb9350ed1ad886d2e467dc7afb2eff5afa76feb9
+6cff87f755ff2be44ad9bfa5f711ff37f4b870e0c498ddff4aaed861fec67ae0c1a3fd97
+fad242fc1fe55fc8fb4cfeb7e53ad81ddfc004d058e80ce59bd2bf56e786deaa52ffc67f
+e26dd2bf63afff7799fbd061d852e00bcbff973ed0a9ff961c87e097cfa5fa1fd875ed87
+bee5f237d9b828b6d90b93edaf15ff93f372fcbf92e62aafe403fb94f459ff0bf153c2ed
+67ceff27f2bf9dfb79f7af43fa99f252d8a5cb93e0a510ea4bd3a9ed96c6b4fa79ff52c8
+b785dd7bccfb4df31fb987c1ea86e39c14f24fff0cc85aba87f36acf94ff7cbfde8a089f
+f186fcaf80ef8dfe7ab6ca4aff87f204d86cfa93d108f9a1fe51f79ee539cef34c94fe86
+f99cd9b629e5aff6058ae4b6f3af37f251bfef92ff09b0fe1a86cd7feda5fe77f9ce2ee0
+a0d843abd835e04bc6fb79d8b75fdd37d87adfbfa5fa18fdb186df5cfe32ceb630eda1cb
+28bfe689f301ee42d1f9c49ee505c94feb199ee51eee74fdd04ffe27a5eb7affd833f101
+ff37f5ce86d879e092d8ff08afe084ed06d92eacf5b4ff48b6ca31ff51dd27c6fb84edb3
+3bb7fe5ced29d978e0b138b9dc25d85bfaa526e7c406edaa3bf167fb53d886c1fb45d95d
+ffc87cfe9c35dd5db9eb69dcf74dfe01d857e0a55ef26cfa7abefe69f5a1ff68b5f24fff
+c285fe93f89e31d96addc42feb78d286e069ffc862fc82ffa916fe5fda79ffb8862eff61
+fb86fe7cf4cc69d888e028a3e592d9bf15ceaf6bfc9ecb79d8ba45ffa5f933f149a3edc0
+36ff5abefa87ec5ad86bcfed7ae093d89cf4ab3fdd15f8a5e388cd9dffb7f34cfc94f373
+ff85ed89d9bf7af2b56ed9ff91cebea0ff2feb77d782e522a8e113c2f484cdfa51d6ad9b
+df86e56df21dc4ffafdc31d0ea02ddc420c0e80bcfa925e2b015ea49c1f288ff9c5af7b8
+ff04fab3ed12a5e506dd5fe4cc7fd89fec961ef5bf92d0a6e039d9af44fba5f959b8f102
+f669ff87f244e6c362f9a5fe65afdc1eb2d882fbca6efe9ad6a9e83fcd96fd28f7a110fe
+56f519ed61ceff73d560d920fb43e07d169fe568cc12d5a3c90afe52ffac58fbc51cbc4d
+fa13ee61d0a5fe10f893d0fc61b4ff78e6a12bbffe0eff38d198ffb993e9860fc2ff9356
+f9b486ed799cfe84d9f769ffd771b6fe01e63fbde29345a5d99f4194d8f96fd0aff146bc
+f634fd4ac2e16ddd45f218bff865ff89d808bfdaff61d5ade040dd99fab60ee047ed28c0
+fb6dc7f268e6a926d951f017fb64b8ff0cc1df79e9c689d9a5cb88fb0abcea96fe80ed79
+d893f6befe2db5ff8cef3fe5bb79dd11e0c033e59ff2d578e091bff25ac2dc6aed3986e9
+d850cd1effaaf179c564bef124c649fb3bc0fb9a5eedacca49ff3bf9d15de030b6cb4096
+facd5bd880ccf612feb5f16df5baff8647b7ff3793fe9d69e086b6f15afea5fc9bec77b2
+d011edaffe823d87c6fe5793fbc12acf80ff88b5ca96e105ed994efe11bfff80e5c293cb
+a4e47af2ae4bffb75cf938ff4ada78e0a24df22ccba8ff09eb52dd85c4de47e0b6fb6af8
+94c4f472ffb062fe3793ffb33dfe20e79744ffa2bff7a508ed95d95be045afecacf979b3
+e68bd8a5ed4be4ba1bfe80e595daa619f1adff77f5a9ef1fa5ed8ffd5fa5d87dda25d650
+e323d9c1f27ceabf1ec4fa0fceff26b0ca0ad35ec3fe33ed9fc85194eecbf5972cc1ed12
+a7fe6eef3ad3f769ff86d87bffafcd94e35ff5a131f84cff20d861dd9bcc1fe196d07eed
+b8ff33f9c391bbe54bc7b673feae39f28bfa831ea5d927e944afd82aebd187cae609dc9c
+cbb66dfeb0cb18dd59c8ff6cfb88f781d0fb21e43ecffb5ff306ff72d982f3ce61d810f2
+7bc2fe9343c4dc0fe487c1ff47dd26c6ff39f460fc8df979affb8f19dc52fba5da80e4a3
+62dbf872ed86e525b6d86cff7ffbd832b117ebaff871b9dd5bd894e4a415d836ec4ce525
+d940fb89d003bfe088d87fecaffe31f687fe61f205fba41c93d86de010ff6cf486fad61b
+cffba805cbaffed060ffc09dfe86f99a16ed79baf765f379f9d803e079fa8dfe2ab5df40
+d304edb269bf86fe9e14bfd296b7cb29ff42afee91ffb129e54dbeeb935bfbb939df6bd2
+9ffa86b6e795cfafdf09cbee33c7fe95d66be62aff48f4c7934ad898fa52ff7cf6af3be0
+15a5f7c4ff62d946cfff7af608ff52c6fe86f4afd09ffa80eeb233f1acff50fb0ff3c255
+93e0bb45b6d886d96adfb1f644fca5f095d921e041a4ed934ed8ed6bdd5498f18f4fed02
+d84cc7fb5aff40a5d82fe44794edadf140d261ec7ac2f479fec134ffd8ed5cddaeff7af6
+54faa5c7a0fb25de72cbfd86d2f809feafce7afe98f207e76df251c90eff4286febd82e0
+aa4ded08f47bcd93d8af05fbbeff19c0de99d904ccf078bcea85539fe287fc9c26eda5c7
+90f1b76ddaa81cff61c1e058c6fd6beb7bda95d4a53cfbd001f0a8fa17ffaff452eb7add
+c15bd03cc2fe7dcbff62bbff7bbeff24f4c714dfc5aff679f0a96bdd88ccfb7dfec1afff
+8634c79ff3bb93fb1b9adda75ae6a01074f62de54cdb1de562de0be269d755f838a3f05e
+9cdd7fed2ae5c255b1fc93d91ee078ed9bc2f29f56ff62f5cf83ddaffe5df275ff88d932
+ade49339f362fe5abffdd23efec7fa38d20be0adcb4ee540d623fa48feca8bed0ba5ff1b
+9fdd42c92cee79ffbd78b8ff72db82e99f38bed22bfeb60dff80f7a661ee9630d8f30fe5
+3d99e47aaaff6dfb2f87e034ffbf0af5b624e09e07dd57d4fb6fff0ce447d8afff3bc7fa
+86debbc993d86cfbafd086fe94f28cfe9ded85bbdc12c9ff3ad854ffa518f9d633ce62ff
+9ffbba61e01dcde513d8a222ff9c2fc0e012d83cedc284f15efbc782d894e090229ae493
+05b5e979f288fe66fbaff381e292ed9b5bf67abdd979f3ce86fea5f959df19d8f72996ec
+3ad367c5fb79ff9bca51ed9fe02edabf01c3fbaf58cda7fdd85dfbd24be295bffe9dd380
+e2a5d86af15ec9fb87f6b81de093cfa5ff68f081e5960dee4afc19ff88f19e3bfeb635d8
+4fcd30d805c7ff68fa79b8ed88d973cbed79a3ff87edaf47d62efa93feb67bf889febf5c
+c4eb54b4fb9ff5b555fe9bd228b0ff16f445fab2ff4bd8f37ac0ff4ad72fe0c10f98fb62
+cc02bfdf3acefe2ee5bc47e10dd88ecb9efa5cabe4c765fe93f726d8b313e582faad67c0
+fb5aff9cf272e58ef12886b6ca0b93f8c11fd955dc1cee4bfa37ff86d9ab51ea2999eec1
+52f228cab612d960fecd79d9a5b857d90acbed80c6f577ff84f77afbaf44eca5e431affc
+02fa9642bfe058d90ecbf17de9c151d337ed4edd3befa8fa86ff8ac965d024e0af0ceea5
+dc6ae09fcf68dd7aedb961fe2baed96cf9b67cffc535b9ffa5f785ffaf54f26197ff7ff5
+6bff24e881cbed42a5f20fd85ee051edbf60f226c4fe0893eb86e04bd314feb9d9f742ff
+afed35a5ea88f27bffc193d09ac0e517ffcf7cbeff45a4fe8ae57cfcbfa3f330b4ff38f2
+cef76bffbc5ce003aadd18e5b1dd5ae096ce22c1f362c4e566f1affe1ff694fb79b5ff02
+9df682ffa5c77ae588d803d63ded1df996ff62f7cd7dff3df8af2dedb60cf7a41fe0c59a
+e580edc01ddd50eda7e55ad944d819e09dc7afea22caa9e051d861fe0987ffd07ae5b0fc
+95ff6dfaa5cf88e456f2d8b21db8ff88dda24880bfec6fde65cdff4efb06ccb15df70ffe
+51a5f29036fad867cbe907d95af535eb4dc6ace085d87d2298eda72ff978ffca88f1a53e
+bffe1af579fe8eb6ff46add814d986debf46c3e537c8aedd2bd9af07fbb61fff59f280e5
+79b6d841c0dd9347e96ed888cafb79ffc96ed0ff864cfa10ff419ffe93f786d917ee78fb
+95f265fa07fc79b7ed3bbffb86f2afbfdd9822fe9f46c81dafd902dd43ff97ccb746eda5
+d930ed64fab3ff039ed82efeb979ddbfa5e53ceda2e07eedc64abfe0ac13fdb56cfa83d0
+9edb93ff6dfb1ff652fee1bf42c3de8cd8a044fb53d1ff9361d9a4d856ef0cd09efb7aff
+6cf35c9dffa666fe8cf366fe71f2d561edcb73e0b5fe50cbff7ae8a513fec1a7fb01e556
+b8d73ea7e854bff2aad493cbb0f277d826d262fe9ed0be28afdc88d851cffe83f79c06d9
+a132fd4af1c268d9f978f4d081fe8ff0af1ff984ff7af76cfc9fcb20ed87c3fb79f2a411
+ed9739ff61fec46cd7b822fb96fe72f492dc2cd8afef1cff49cb02ed9cd991c8a04dff94
+f360fe21eebe7ceb9a0fc2f286ff2de07cdb86e524dfa4cb32c1e409d0ed20d840e1a1ca
+4e93ff9a4afba52795dba909f15afbce82e02cbdf279ff1df387fb2cfe9416e669ed5eda
+06e55eff7ee0af37f458fecd38ff79f8a617dd5dccfe6ae5c591e66efbb50bbee2ab4ced
+35d85ac9e969d813d03de0c251e5a5cf39e952d18ae0c366f8d583d99c28f946ffaf6de2
+0bd83fedc386ff4ba5d879e586df7bd05ef007fbd478d813e3aec967fdd62afab0e738cb
+6dea8afa3aff5bf6c03ff9a9fe87f581b9f883ffaf1afabfdb16c0da7bf0b9fa34f5c693
+deb938f05bff68c79fd9b45fe1afd976e0afc2ff22f8a5fd97c7b0f20afbc986e0a462ed
+b5de30e6c593ff2dbaef4dfa13add834ccff912cff9cc1f67bffa341fe8cf386feaf0af6
+88ff6dd999ff19f641ffb026b6f217e5b988e77bf1c153f89effb659f296c1fe3bf5aff9
+51fd28ffa5e88828f9b6ff8743eab80daedf79db85ff9ff705d0abc59cceb583e36fd823
+d560dd51a5dd6dd0ec873af7a7f237e610d383e08c4cfa239fff93d986e026f64cd0fe96
+09c3f73afe4788dcbf38ce4efa2a9edd934cff08c1fa94118ff39f56ed7adb71b4d59ac0
+ff85ed9450efce6adf0ab5e41adfc09add53e2c55dde7ad82ab5fb5daee069d97dccfb5f
+c3fb7affcd01d830dda6d079c724e4af04ec85e0bf1293d895dc83cb62ddef933ba3d1fa
+6fff93f74cfe3dd01fda5bb6fe4bf217fd48f210ff95f079ff2afbcb0efa4596fdb979d8
+65fec188ff4aafffd86bcbea4dd107eea5fe7ae69334bfed6ca4dd80cff59559ff7bde85
+ecd067f0c0d97ae841bdfed868fed201faaff61cff3df25ae163fbd8af3ff786fe78c3fb
+61f60eadff2798fbb6fe56f4c811f2cb86fe97f10893e89e4cd834a5fa85fe60ff11f35a
+f977fcd06afa5e9dd9ff34f255f719fe9e51dab9ed04bfd934e063caa5ed77fb93f1c678
+d992e079dd87d8b947b6d988e45c9bedc0ade00dcdff2cdea544f398c3ed0da1fe86bcf7
+7cfbb641bbd814f2c6f943ffcb24f0b501e1c1a0ed10feb63cffb520a5f38cd0f15eb6c9
+3cb0e29333c4e57cdd94cf26c7b716ff99beec4fd93aaad87dedcf6dbeea8636a5e6bd64
+e0af3ee829d455d8ff3cc0ed87e2bf4eecabc994e086d888dd39a5db26cdfe44b6c6a2ce
+abe279d0ff6afb7af55aaaf1c198f209afe04fd8149ff92fff51caaffe38f6a5fe03f3a5
+bfff8a61ff7bf3a05aed7bfbafcb20fb5db8db40f218a4d86add98ed80ffa55090d89d5c
+fbbe78ff61fb2cd7a8c77ae5c15ffacf4aff1d9de427ffa3f277cfff8a5bfbaf06fea5f2
+79ea61e421cba5ff8af225ffb93bd9f902c3f2d71693fa7fffa0bff76ffdbb79b1f60efe
+62f29ecc16f646afed1fff9fc0ff7bf6b087ee68fb0aff3cbff40f86e01eb3ce9bfe861a
+ff5bd8ff7bf386ffdd65eda2beed079ee57ceb67b0c83fe016d0e52fd84de9c793d702e3
+6ddf84d0fc77e562c4ff30f454ff1fe061d9b7fe1cedadd051eaafd393f279fb56f71394
+ed9c75e586c6fb79da6ed818fd48a5e0bf43c2e484dd4cfaa0d091fb79ee05cf93d7af5a
+fba779afff4a95ffd031d84ded0593dcae17c6e06adb97d01eff79e585befb64b6cb4aed
+16e052d91bc0e088d87ced5bafd8f79fc3ff47dd2ce0afcd87be42cc26c7b83bb3cc21fb
+61f7c74cd91ccdfa7efe86f553b7f795feb51cff60f299ff53edad30f3be9bd96fe0a5c9
+94ccaffb05f185e567ff10f69e1ee447bfe021d986d5ff32cafe04ddaf42f3b0ed53e698
+bfee0ef7a0ff5cf52eb6d70afe43adda62b6f54bfc86eebf2dedd868caed60b6fc9df378
+c3fe44f49efa2cfeac42fbbc93db3affd02bd8fe79f495c980fe93f2a92ef347fac296fe
+33be57e670ee93fb60f738d9fd93f8a5fc5ad8ff79e493d6b574fb99ffb64fda25d893ed
+74c605c072e08ed8b628b8d911ffa1ca04fe43f9c00efd3af64a93e4b343b9d891d97cc8
+fe80f9a560ffaff34ab0dd51a5ef6bff9fcb0e93fec360fa7bd886d923d86dcbff7af193
+c1f830ffc87ae0c10bdb6bfec01bfbaf23d986df0ec9a8e26bd987e55bd87ec9e579ed5a
+aeed6ba0f89607e2ae33fbb60ae64dffcb91dfa61ee980e58efb27d8b60cb8d87eebb104
+e04dd586e7920cf2bd40ff19eec230d683e59bef6cfe1fb0ff92d9fb3cf549fea7fa8acd
+79e07fe686edb07ded86df7ad9c468ff9ffa31f353fd32b6ed0dc4ec9335cca1fc6bf9c5
+87d82ce761fbd934a5dc22eb43fe60f387fba551e5c55fe077edaf1bfa399fffaad34a98
+dd75f4a1fe44bff859ff25f9bf1cc1ff92f106b5f82dc4fd03c0de4becc756ffd665ead0
+83db9f61fe6dc8ffb643c801aef281fe9ff349fec46af2c19fed16aff3a7d069ec83dfae
+5cf965f40bff49d09fc2e440ed5aafcf85ea78dd39f156f636ff50d3b82aff4cd0a8fe17
+f4b02bdf88cd84e096dd58cf9bfe43c0fe72ee0ae2a81dfe5af694d6b676bef886ff82c9
+a9cf9ee502edbf20acff12b4d088de82d2ed8724f9b0f288e538ce8ff16296d889de5eab
+ed953bdd54ff70d09fdf68b0fe87f373a5db7ebaf026aafb2bc5ed05d94b87efa5fee5cd
+60de36e06dd7a424ff972dfb77ffca4bfe2dfa99cf55fe93d8a4cabc93c0f837fb86cb9a
+f928febe0dcf96e57fd888dbc094ed6ce2c58bfb2fc1e35bd5f9c213ffb507f579ff8bdc
+6db2e31bd993d884cbed7dd8af12f248ffd108e450b6f413fb3bafdb71fe95f252bdfd3f
+f462feb84df3c778e00cff57b6ea05c1dcfd29ed79d0ff4efbce83ec9dd847ff1af4cc3c
+d820b9fb0ff7408bffcb79e051adf593fbd013d965a13dffafd093ff15f6ba78e2c558e5
+bf66df7edbac11f4be2fed05ff3fe15ceb7aafd60fe961d8b56beea5ff23affe15fbaf26
+f71bfeaf0be79ff2659bff9248a5e679edc0a5cb22ea3afad167f17bfb5bff2fb7f743ff
+c97de3ae67f498c2de6ae093c1ff85d038d976e5ca6bd99de32695dda55dff95d87cc6f7
+7fffa53cb6cba3fa1393dca50af5ae24fbbf93edb66ffa81ffd05ce4a1c3e09959f886ff
+ce7ae030a5ff86f7c2ed9518f94ea9d883edcf50feb68825f898ed46c8ff6be5a5ceb88c
+f2a8fb13bff168ffa2f518ffcb3ad861edc866de70eb9bd8a5ce69fabd57d6afdd03edb3
+fe61d93cff4afbbc62f2b704ff9cc727eb88e579c1e0893afabe25ddb03dfd26ffaf4ee9
+2bf261f7a2fb2c99f60ffe58bfff01fbcd31ee43faab2ad95bd0f67aff51c6aff235caff
+68d9b87ae45bce32e599eb4488febf63fe1ef4bf16edb710fe5ebae44ddc2bfc52beeb7b
+c1ed63fb31adf30bd8feacd201b0fb73b9dc43ff70fb61d82acb9ffe32ddb244bde0799c
+fa86f7ba4cf29fd051fb3fff4bf2c480ff1dfb50f56ad025ed93d686d86fdda5c887e6ac
+3ff8bca1d54dfe02afeaa6cf79fe85f9cd7ad988c7fb79d88fe0c006ccafed81d886cbf0
+6de7ba8ad984e367ccfe87ed1d99e10adb6dfe85e479bce646f3c90bfe81fbae12c8afee
+a52edc86d86cdd9fd168e897c2f16ffabe936bcfff44b2fe08ddc093dc7be9943af160ff
+cb86e2279fed92d81be697ff79dc62d879ee93fc4eb8de06e43c94ffaf02ffbd93ca89d8
+af2cdd79e086b8c796e2b77efb19f39ef70fff2efc79cced59dd13fbaad897f25cff19f1
+53e805abf242ed0da5f01afe46afff7fd954ff39faaf2bd8a246f710fea6d8159fe06fff
+c768f1aeea23d854fc2da4fb9361edb5dd4cd3ff78e006cbf951f2a7ff4cfa36feaf41fb
+1ab0cc23e1f30e86e3d56ef4ad5aff1efa51bfd986e0a438f059fec108fa58f6c44ac1ed
+21f7b7ff03e586c6f265fea5c0d927e0c286f12ff408e560ffabef41cffa29ff52fac65a
+dfbf32afed84d956e01eb7fe95ee67c63dfc31d984e09fd8b987ff5ed07dfeda59bacb97
+e75cef18e3a3ceb979f886fecb7aecc053ffb8ef3dd8af30fbbe3994f89cef86c1e01ad1
+ff982591f59f5ef28bfd6a9ae2c502beeb93da72c8e579d8f67affaad8aff8992ae5c237
+edc69dd0a5ff69fb2abffe93d57bebb581e0a67af286afe38a419ed9ad2fff20b0ce6ffb
+88f86cfd41d8a5b9fe95edc5118ffeb169d87ae90a9bffab63fecc6bd89ef986ff61d02d
+cba5ff91cfb56efbc04cfb36d9c09ce5b647c289ff67fa2fd787febf60f208e950df17af
+dd389cf29249c3fe7bf3a4cd7cffd14bdd02b6ff68f0af3dc2f9d838e9c62bd946d8ff38
+8dfb80cb24b5f806a0ff9351df9d3b75de4acafd8f61ffb463e445ed11e6c29ad962e017
+d851fecb34ffba09fe3bc5fbb5f451fbc39ac0ea4bdd1ae147cc9fed79e45bcc45b786f9
+bed915ed9fdb92caf236d0ee934ce418ed40c6a6f192fa5af20bde62f8c30f96ecc493ef
+2efb1afa86f6d636dfb6ed79ddaf3efb7dda8affc296ff67fbcf22d7fb9407e04cd910e3
+61bffe80c8f442d879fea5eb70bbfe7ab7ffa0f7b577baedae43fe9fe063edd432c6ef0b
+c8fbf193ffb61cf2b9d804fb8afe81ccaf5ef20ff9acff88f324a1d96aecd06bde9911e0
+85d387ed68f681fe99f383b6e913bfff23f87bd9fe35d24d9cf45aff23f84aa5e08b01c1
+fb98ff7fb6e507d947afda7ee59fed26ddacff801ffe66b7d493d8be0dacec93089fff25
+f79bc2ed5ad6ac37f24ae5b77be9a664ecc0a5fa81ff8af51dafe15c9feb93cf10dd51ff
+08a8e01ad052c610f4d31fddc088f046ffb786eaaf65ffb758af02d879ecc6439eed79da
+20b8f732ff84ecc5439dde79bef186fb51a5fa80ffbc6efe1ddd3cd90cd731d853c7ff77
+fa5fabdc93ed17a6f288ffc972e086cc6bbfff79fbaff22ada52cafd66f795c2ff19fbbf
+44affe7bee5ab8e2c6a5f658ff3bf39ffe4cfbc8e552d062e521a7fe1aee84d8a5c904ff
+5ff7c933ff5abded41b9d486fa36ffcd19fe5df788d893cbf35bfb84ee93e4a552ff65f2
+11c6a9cd1efc5af798d92ce5ccfb87f65e97ffd252f5c1a1e373dd52d0af69bffb34ceff
+5de617c8e527d84fedca56f27dfb89ffa6f87afea52ed993e0c23bfb64c0e654dd05b6fb
+39b9fca5ef1ed93ee571d191eaaf33d7be6ded86d86994ffd250d938cbf48d46ed11df77
+cb64e079d9bf6db2f384dc8affc968e0b1ff27fa6ee086da19b0df75dd16cb9fe555edab
+db69b9e586da78ed37e64e9fdd93d929ff61f9ca84e09bff7cfa79da80e014cf88fe649a
+49e434ddc11591e0a62eff4bfb99bef628ffd87fe4ad0dc79fd9b35af0acf71ca5e7afc6
+60ecbf47c5e007d3f257f60eff86cda2ff7ed896ec82d8a5e40fd85fe7b1ca94ff57f90b
+f397ff22fa37e14aecc40c86f5b6fc8705ffc093feba9bedb02bf5951aff3ac4fe03ec51
+9ef6944dbed093ed51fec493fb86f59afe6df924ffc60693f3a54cfb32c8afff7cfabf2f
+fe6cd482dc31affb27d056d838f24bffa4bffa40acedffc0a5fe70fbadf841fec594bcd3
+09e06ee59504f161f796fe48f98fffbf6188d2fe8e07ffd82b96f286b0ed6bb1cb77d69c
+ea08d93ef525fe4bf72dfe7cf488fe974cfe12bfe080d865e07ab5d898c0ff79f7afe99f
+1c95e5d171e05ccf43f801ffd06ae5c2a4f078add87bf9d10dd8f474fb11b5d8ad3bed4d
+d625cf4fe0b7d99661c1fc29ecc397bef91fa2d903e186c2f00dfbc1a4e079d993ed86e6
+9ad2ba2add61edca1978d920cfb92fe06cd787ed18f379ffa7fa48ccfcb4d930e088edba
+32d001dafa9e42dfc15aa4e5c313fe5dc1ff1dfbbef14abffe7ce3abcb6de0aec561ce46
+de26ceed7cdda041fea6fb3ec3f15cfe14acd82ad95cfeb8f346a5f228fbaed983dd7bbe
+fe25f959dab831fbbf42aefd8d35e4c499ff29f59fbfff7cf28efba73e88edafe07bd988
+ff0cdf6fe8ca65ffa8f741afe4954bff04f64cfd15feaf08fb61f593ffb582e0f393fa7f
+ef93c4f20ed961dd50b0d8388dd9b8864fa0ffaf21cb5df586fdaf2fc0f181fdaff76bfb
+b677e5349fda94378ffba561f3bf58eda4c71ff099ffba9ff26db5fa37f6b2c720ce9ffe
+06afd187f455fb92e32fd861c9fe7fd8a114ffb632fb4aa5de86d810ffce6ae093ed62c0
+ffa548f179e069da0eaae061d803ecb4fe13fa33ff56d56af2a2fe3e94edc11fd5a5ff5a
+bded7be59ec7b3db6acbe484dec24ed00afb5d3add57e009ff4bafff7df888fece67eec4
+fe26e4c4ed6bd4fb7be79cd86ded96ff6fd021ed32dc4cd2f092cef748ffb6e41cddc42b
+94ff12fa51ff79dd0de55bc2ff07c1d986ed79f285e873bbe43ced9fe07ad06df983ffaf
+34e564efc961f2c793eacc5cff98ed7eaff308ff2eb4db1fde86d3bb40fe80f7ce33fea5
+f96dd884dd79cdaded16dcb94ab6d8fb4c90f279de7ccef936b6cf5ff22da5ed3eb6ff20
+aded7be8a3d1b889fea8cb9ae567bee835cab520fca50f7dafff8c07f445a6d80eff3ce5
+4cd80ee152d995cc92fea526ff7ebae065d87aee51ffafdb86d580e99ed052f593fb3aa3
+e09353ff17d951ff2ccbf669fec524bfff03ebb5dc10e099beff3e94e69c53f50ab8ed28
+d950fa38cbbb9ec5e95bf0affe05f9a4c2e04b93edc558bfe539f24dbde75f98fb7cff89
+f608aae0bc55fc33ee1699d9ff1dfa93c0ff88fb79c99ff836fec127ffec11c351f939b3
+fb24d093fb79eb84e0b6f2d842bddf83c6ff79ef85ccaefe79f5affb7cff75f20addbe55
+ed03a5f315feaed070e55ced41d9af01fba9c970d5afee61feaec3e588d493dfae46d8b4
+79fb50a8f29343a4f66afa1eccaffe23d1ff8dd978aaf78cd285e668fe6ff57eff9a55c1
+e76bed2196fbb80990f126a4ffc19dff21f8cb45e226b1d07ff12affcd88d893fec75289
+eaaf63dd55d819f24be567d9b078de62be9eefd278d8f173d9a8ed02dc55f73ffe5393cf
+fb5ffe9f1fe249b8f31b9eddc235a3e016d859e87afbd06bfbcb84d9992ff9b707fcaaf8
+6afec086ee2fff1af886d921ed449cf402fc5ff887ff0eed9ac2de61cdffc34cd088ed79
+df81dba538e34cffc95fe014feafd71ce045d815d6fa9249d97dffca5bd8ffbb68fad981
+0de063d878b5f59ec2ed37feb5da9911f263e56baef5d844cbfe0bf775e286d888ffc404
+fb93f44afb2790ff9f0cbffe5c86ffa1bcc998d1adf81ba5eb37d1f686d9fe68c1fb2793
+edbe69f787fe9fc9399bdfaf3fff4df5c979edd09a25c2de33e347afdc8ae0bf42c5fb7e
+b9ff6edca9ca1de5be9fcf5cf32ffea520f086feb948fb06f361fbc37ef2a61efd93f2a1
+4bf995c2fc93e1b929c5ffb4e43ba8f38840ead29646c6fbaff393fd07d058fe86dda248
+85ebc1acff2cbfe00da4fb9369ed96ceaafe12ee4395e1b632c787d8b0e531f3aeed3bb8
+e2c34af116ff30dd62edc779dcaf50cbb40aace081cff858ffd040b7c629f9afff21f593
+c3ec68b5ff4689d8ff79b2f693ffd379f35c9affa565e2d014ebc16aed99d54dfb39ff93
+d586e8c095e218e7a7c79ecebc0fedb830c0eb66d93acbe374ed29b661fe78acf386139d
+fad819cffb9f1bffafee864bc435bfed92e019d56df2befe3efa59c9a5fa50ffc537e5d4
+af2dff41b8cfa4bff151f7a7ffea5bfe7ade65d886c8fe1d93fa88d978e97bff9f4dfe13
+fa98ff65c2f140ff60b6e5028bd9f270e062d888d670e50aa6e01eceadf32ebeed17cb53
+b909fe35cbec0dd8f13093fa9f30ff4bfa82f18ad873e00cd952fb3aaed87cff5bf740ff
+b06cfa9ffe7ad387ffae0cffbe9ff7c402c6e543d0efc05092e8af7ac1e06fd82bdea9d8
+fea05bff7af75aff0be591d878df01ec81dc965ef8b71decc39de760fa28fe83d86fd91e
+9dd005cb95ff21f94f9cf2d832e55afbafcc07c0e585ed88e023d8fa74d296ed38c9a8fe
+b01bffa5ef10e451fe9fc1fa7afe61dc75fb599ffe81d8fa99c3e57ab6f955afffc84ee0
+bb85ddb429b7db18eeaffe79f281befe61f227dd92d885e5d51cd950dd08ed52e589d03b
+e050db96f068ffaf31feaff664fe32f752f494fe62fa0186eac51fceafe886d8b322b8f3
+96fe61d626f2aecd86ff7efb6dbdf396dc62e50cfe93f267f8abfb43afda6ee6cf6cb6ff
+a5d68626f28bfa2bd7b93eb6ed932ebdfe12afff83dd52e398cb4abffc7ef2af36ed56d9
+87ee11e797c4e166f2a626ed4a96ff28cf8ce761a5f379fdce0cfea0f665ffc2449fdd1d
+c7ed01d988d172ed16f94ba5ff92f385fbc398bafb5af480ff79fa2fb8d884e578dd10cc
+9bd887ddbf15b0ec87e4bf42fba5f23b9dde52fba5ff30cf87f19fff77e907df51d83be0
+03cc4fc0ed87d2b53dc5bc38ed5ac1f583fea507ec4dc80cedbfffade05bda6dffa4f84d
+ffadeb5ae1c763eb1ef66dfb87ed79b6d122c0da90ff26c6a1feb83cff04d83fdfc091fb
+d869f0a8fe04bedf19d845a6ee6dd83ae0ad70facf7effa760e4b8ff3bfbafca79edc055
+d035e0a546fa2dd7a5c8b410e9c29ffb0af25ad894ff58f104ff42a0fcce3bd85dffb271
+dd83c7ff26ed82dd6ce652d919cb4cdabefe6df5a5f286ff91fca91cff53f8a5ffe092d6
+a3e518d137c0ff81fb7af69552cd399afeafe805d86acf7bdc86f79f48fb93d1a5d936dd
+07ff45f68eff6be174b6f74fcc86da7deda4fb79ff61be0eb8db4386d8fb7bfe8af7c65a
+dd86fec004eab726e250ccf4934ba5e09643feb32afb86f6b66bffbe7aed86fe23f2d193
+50dd80cba5fe23eb86d77ee4a5c2f26093ff9df125d0f50ffe4eafd262f815ccaffe7dfb
+8bf7a73d94d8b916b4d94dd82df6c993e07fdc156afe26fb62b6ed97e147d0a5df3eb8fb
+76d8f38646c2fb80f218e537d809cff0ae2fff5dc0fe7bd886e09fcd4ced01d7ed79e41a
+fb51f4be6cc3eb1bd1f59fff75bff2af3bcd5ae62497ff19f2b07cfbc659f085fa9a2efe
+b5f20acef17edcc499de03eccb1ff1cc14dc6dd99949fbbcff3eed69c6b661f42efbb34c
+df23e6c70bd96ce552b7cb95ed77fac09dbbed3a98e05fd822edb3fd2efa9ffe7aef87e5
+bc4af225d85bf1c7afe080c8ff50f787bbf323c2ffd219e1a50ec5ef9655dfb2fe9ff96b
+feb975ddc19af10faff343faaf13fbbc9dfeaf36ff95d3a6e09116fe35a5dc9357eb39d1
+fd1ee493eda5c9afed79b7d143e73395ffafd811c0ec7cd96afdbf64e50efe49b9ff5a9f
+df935effaef737ffafd71e87d8aff937fbcd9fdc78cbff93f979a9fa90fe82da89fb31d8
+b604ee4bff79f9c70af0a1ff67d086ed5be03dd00efe599ed97bfbaaff98eb419ff20e93
+dcaf15ff5fe5934b9ff580ffaffb30bbff933ac650b6e9983fff1bfa64cca2e688dd79c7
+ec60de2dcf65bbca61fa2bc1ffd886cef84effc986e0ad5cc767ff07fa4dff38ccfb69f9
+a3c4e0883cfda5f75dd521e99f2cffadcb93e778ceabfe3df8afd854a1e082ed69f7c2f1
+1693e09907ff51f1147fd939bdee49d72ec6f91cabe061ffc689d893e060a5feb649bae1
+0fdd76cd93eba5dd91c6ff09e6c039cc017dffd179fbcc42fdc497db74fab5ea31d861d9
+7bcfeb1dd9afed90db14cbf37fd891e033ff51cf25ff3da7fe86f292d9fb0de5afed8046
+b3e85f99e3ae31f711fb88ed9ed8b67ee090da9e0fedbe74ff08f5ca62d837dd87ff79bd
+df934cf230c1fa20ef71d980eb0bc1ed61cd06dda54b8fffd053edba7ad992c5f389fecb
+67e087eda560c2ff7af09e44fe2ef40ebed939dd93f679ffa5fb19ff75f966f235b7f45d
+a0ee8afadab521e752a6ed78e52ec1ed03d86dfe87f121e45aa0f67afa09ff6efb86bee3
+59ee7af4c293fbb583f1cb1cd953ff3aa5f2934ac5fba5f223fec105fc84d8be9fd625fe
+48f7c51ef461feafca28de5cd9bb85ed7bfeafed45d0fa5bf5d885ffa561e093d617ff62
+b6fe29f693ff7afdb6df39befe80c7f728feac44e41d9eff0ff551ffbae640d816cfe57b
+d985caff73fa7eed31d7b446b8d95ac926d89ce07ac8affe62de47bf60f49cbfff07d985
+fb4fb0fe57e0afcb50fa86ffc043cd5ce5a3d048ed23b1fd03d2b219ed61e4c04a94ea9d
+d27be7c55cd8ff8906dd6dd67bdd93b9ee4bff3cf6b780dd6ba5ec82d830e078f393fbad
+4aff1ae09f0cc1fb9704c9b716eb51d0f2af43fbbe9dc4e586d875e442cb24ed61faa20b
+e843a5e069d5fb6db7de79d9c094d8089af386fbb959f1a5fc479ae228cba3fe63f396f2
+84f488fe52fb1aff4ce415d87bf193fec334e068d059ee9fd979c6f49613eca2c6b601ed
+93feabc62de7a6c2ff51cba1ff6cf99edb06feaff567fe09f6a020feac27e0afc0ff51f4
+34fa62d0b181de78edcc14ffd05affa6f893fe52d21fe498d6be6af3cb8e5fe5a8ff71f8
+9bda8a06ffc387ed33dd3ef24efbc09ff9b384d97ae5cd6dfed186ef0fa0cfff4bf7af2e
+fd6df7c95ddbae3affbf1fd0aff367b7e806c2df1fd839d502deabed83d093d886f7b0fe
+2de50fadfb86f397feaf11ffbf2388d0fb62ff35f2d078d91be086fe7ef76094de7dec3c
+bed834c3ed5dd727dc84e06dc7ed66cbf371fd3194e1afcd9ce51ef3c102fe4d9af3bd30
+e5b60ac641b7da8bf16cfa32feb247ffb8f232dc4ce0af28febbd96de55aaafa7afe99d1
+b002e05dd5ff12f14db8f2af1dff5abfe93390edc561eca5d345afff27f4a1cb7aec5bdf
+15c7ff79f96dafff81fa9affb93ab6dc60fa32ed993fcbaa80ceed4dd81ed83be5bb6ae0
+aaed47bedf89d8994bffa8f861f042dd0ecef42bfa5bafe586fe75a5fa80ff52c8b3fc3c
+a9f79350e59dd9f9860eff4abfff58e4a5caafe08952f179d998e8aaef02ff4eceabdf75
+d0e68616c5fb7bd887fcc78342f6b223fdcf08b4c91eef86ff93ed2cafca9dff8b30e096
+caa5f97cfbc10193feb71dfb93e080d075e409f894ff87fbaa40d3afed52c0e061cb79ec
+a3f60be8afc779ffd96dfade599fff90f984f062caf841fc6bffa528f67afaafd82fc89a
+d2b99fff74b6d895c5ff1ff148b9d90fe0bfa5f91896e4d010d8ffc215ba50c2ec89ef76
+a1d87aff41f82dfcc3a3fe3af75dff85e47ab6f61293ed239ff8d869b3eb1cee3ea6fad8
+79eacb6794f6e060ffb752c534c1f563fa3ed8bffb5cf749df29d863daade53add84c3eb
+13ef61fe86d954d72cdc61ed93e5249efb10a5f01cfc58d37eff9f27feb706b4ea2089f7
+c503dd5ccb94ff1eafd093da0ae5b859dc11e864fd54f307fe66bfed47fb12ed88d96acc
+ff7bf3963ae585cfff498afba33f86ddf57ffe43de13d4f926f292d894d879dd10c0e077
+d025d844caea7bc8fb5fffc138adfe39c2ff7ccde7129dff2ea1ffd951a4d87de496d9fe
+6fb7d893e78118da86c1ed71ffb5f244ff5cf39dff497bfeb7d923eaaffe71f5afcf03fa
+5bffd87acdfe4dd894e024d950cbf36ad6ef61c0ffd93ba7f297fe2bdc6fe079ec30c2f4
+7dfecb6fffc493bfe080d88ee024d5af84e0b84cb4fb9b29e058caff6af25ba2edbf61ed
+b5fbae37d8a4cbadfeaf5fcb6de60bef5bff96fa55a9fb91f395fea42cff4aafd881de94
+ed79d955abe05c93f3b860d4f08718c1fb31f314fb499eee0dff27acfbc2a5ff04afd894
+119ee0c0a5cc0cd8afdc9351a6fb9a36c3e89b4bffa1c8b98842f5b668e57df96cfe88e5
+86bee24696fba54d7afdd672d07aedb9f64dffb6fa9e55d738aee09c45f218a5ff38f65a
+fa79ffc339fea2f20be8c0a9fb13b0d822e0b902ffd82adb62e997ff23f15185ed9afebe
+4ffb73c920e486d9bf18e166d861edbcd89de509f24eff07bff189f703febd4bd8f9bf3d
+e4b6ed6bdd90d0a7bfe07bd886c8ed5fe142d09ffe35f6b8fe8421fa69f686fd29fac8f1
+43beff8e19bfed6de43bd9f1add02ceda4c736cba9f23cfe12a1ffc728d8f3cab612ff36
+daa70a9cd8931686dfafff87fa20eeb97ffbc366eda9cb97e505f0af6bd886dd7afe62d6
+a0f57dfe88f9cd79aff794fe08c66de588fbc83ad91bddabc79eebb563f535ff86c2ff0e
+f8c1841bfd5af9af88d2a5fa28d09add69d2ff880e85fec55893ffaf4cfe24f73cfe4cf7
+a538ff93f86ae07cd488e346cfed88e0bf4cc3e2a30285d6e563e0cbfb31d893fe8215fb
+6effc007feafee0cc2dc79b9f25290e69418f96deda2e552feb6fa32f2c8fe40ef05ea96
+d26dffc852e69ad111fe44acd963ccf92bff52ce39f087ea40d050dd359cee1dc54aca84
+f6d358db06b7ff86f67afd26ff48f3ce7be0a5ed3eb0dc943fc7ecb5dc71cbed3be560b4
+ff45affb2699edb1f29e23fad601e0c195ec88ceafe479ddb2cf0bafed26f356d96ffbaf
+5bff38aeed9257f4b6ff9410f7b04886b6fd0eb1eaa7c1e05194f279dd7fff9354fbd080
+d8fa3ffeac45e0c264aff287d679e4b06cb7d393bdcb52e5ac0ae1b227fe60e493bfff7b
+f31cb5e698bbfa91c419b6fb94ed7ac8fe6cb7ff92f2b73ba5fb93f579d4af5ae093d786
+d8a502fec024d0a0f156fbaef38932a3ff17b7fb96c0dd6cebc685f0cb37da4ed0e57db9
+f564fa38ca53f2049cff1bf262fbcb88dc85ff17f2c308bbd299f811ffcc72df46edacce
+79ffc5f15ec9f84cdc349bf8d549d828ec47bfe0a533ed09b2ce61dfff9b28fbcf1bdd46
+fec259f623ff5ff779fe3bf3c179f8be82f2c24fec27d79dfb77c144ee05dcfe9fd965e0
+0bffb554e5d65fdd22d8ffc21bd04ee72bedba08f252f73bffc45e95f879fe88d424e05b
+feb9f253e47ac951ff0ef8a51ee077b6ff70fbbc62ff42a1d97ee6acff9fc1d957d68ae0
+bb50ff60cda5e9b486d9fb2bde6dd8af30fe97c75cfe35edb50593e09e76f28affc81bac
+ff86fac49ff718ff88beff72f6b78308bef1935bff80eda507e07bdb9fe218ddb7d96afb
+af4dedd834a5fb88dc5be940d8ff92d0b47f4af229ffc189d42ff5a50cf8affb8052ea86
+febba0ff6df9cf6be0afdd69ecb7d94de50ada63ff96cd04da80d893fe2aee87d883cdfe
+5dfa15c1ec930af095c3ed1effbe11d35efb87f574fd2d98e41bb6fc40c652fe6496ef7d
+fd47f3a5d020e784d599d957fed82effcf1fe15687eecc6ad9a561e66ed9afe95cd8ae2e
+edd2f3d850c9ea94d830cbff88fbbf4bc3fc8f2fa0ec26cfff0594ffce1ff46eff86c9af
+13f257fdd8adc1e0aa38fa9ee774caed86439ae0bf9ef134e360c4dc369fffc5189bfa8f
+13ffc680fb72eb86d977ed60ff27f46bd89edf62ed36abd98de2a03fc4e0af2efe5bd8a5
+50f993e526dd3aeda5c3fe6df6c87eee8ef423e6bf3dcb9ee168dd79fba7f317fb6df2c0
+62e752a4fbafd8faa03de501ffb823fe953bc1f922fec35a9e388dfeaf0dfb61f79d50ed
+2a93f3a562edb1ff7dd85ba7ddc15186e3afd201beed73dd93e09e1cff5287f780d85bbb
+fb3e99ffb8f312fc45afd87efd1795fbbf4893fec132f1bfa53eddadcb45f616feb1d1a4
+c6b0e14cf514fe9fbff128ff56f3afff6dfbd07ce086f1cb6dd87aff68b6cc06e74bd3af
+38de0ed89fd783f9a8ff1bb6ff07edc041d887cbbb2a9afa86beed7e48bc0dc0fe86f158
+d2f279c5fb669ce27cefaaffb9e52bdd86c3e077d9bfa9c5e703fed047d910b6fe92f572
+faaff29c3ffca2f837fe50f732beed84eecd04ebafff1ad0ace028d861ddc593ff03f3a5
+c1f074e5afed74e4b45adafb87f529fea5bfe09938fb49f10a9aff7cb7c752ff80cc97d6
+6bd820dc48a5f608fb36aafe17f19fc0f879ff94bcf07bff9afa72ff5ee404d85ef1c782
+d99460ff9ff844ffaced1ed0ff0ac4dbff84e95ed095dd9342b4e305f1cd43d80edc67d3
+55f999ff3ca4fe15fa43ff6dd886bcfa77f6cc3be41ae03fd80cffbe5ae081d98dd77dca
+fb61d83abcfe9443c4ef6bfe7cf290fea765ed79b6cd5be04bd80efe2dd952f4d0841ed8
+9fc889ed3086f9c193e57dfbcc39d7ed6ddc01e54ef70cfd86f881beed78cd9dc0ed87e0
+af43eb20d8ac42fb14e05acf88ec26c8a3fe7addaf4df63efbb7c60ab5e07dd874e4af68
+b3f6923fd59df436fe17fac5ff69d979afff86f791fb84e8c160abf2bf53ed7ad597e33f
+f1209ee0935ff2c096c5fe86e97ad0efb017b6f024fea50ee599ff915ad8fa7ab3dd14d8
+4fcb09e0bc2ff9d93dfa93ff85cb8cd897ff059fffaff050e60eafffcf56ed1bafdd5ca9
+f29321fba5f688d379e0b6de3acbff19b5ff5adf20d360ffc493fe5af3c392d0a8fa30db
+51b7f244b0ed27fb93d0a7cb26eb93dc5ef011fec440f9d32ae0aafb22afd97ee0be871d
+f3abfd29bbeb4ac81df59502eed724de8fcaa5ea1caffa82cbff33c7fea56bff51a9d860
+f92693fa86ff5de270deb766f11ed0f5bf23e04bc0f994ff83f75afecf9f6aedb125b7f2
+42f564e87abfed45e36cff7ffad9499ddb84ffd032fec774ffb1d05fc0ed31fea74695eb
+ac5dc2e53bf386fe7bdb06e051bfdc84e529fe62bff279fed06cffc688d86ee812fe88f3
+79fc37ffa3cd5593edbd6bfe88f164bfff6df6ae46ceec9644c6ed76d09effaf3ecfffbc
+78fb65ff0df559feca5dddaf53edb602e6d824baee15dd82cae54edbc695c2f443ffc687
+e0a5479cff88f3a558e024d69eec931be5bf11fe9fea7adaa5fc1dcafa68ce95c634d3b6
+68bff208e54e95ea9e15dd4be687fa1a9dd87ef1b9ff05f493fb6bd999cf4bf29ff783fb
+af0fff6fd99be00294e7a40be59c1ff74dffa5e068d85ae29dd2bd70e6affb17a1e24dd8
+03cbe54ad80fed9efe63b8e58f50fe12e556d9fab5874bed94cca8e06ed9ba79ff0df29f
+d286f04c9df3ce79fba3ff33bffea53bfb06a8d89c2ffd79f9b6e764d801fec88af172da
+3ac7fa79ffcc5fdd3fff0ad05fe0af28b8fe0cf9a1f321fcde79fea2c0fb65bdf089f7aa
+37d8afff4ee513d964d854dd2eedad0ffba5c837b0d82df29cc1ee53f67fffd840bdfc7d
+cdec7fd9b936b6f031ffaf19f54cfa07f286c3ff88f47afbb179ee99fe86dd25c9ff08f7
+c1a5dd86f079dc10fed8af18f84ac4fe9226edaacd79fb27ff68cafc8954e2b646b3ed93
+0df2c46cbfff78f8d05cd90bd736f27ee4af2cfb54e686ff69b2d84396f6aad56ee586f1
+7dffa5ee79d862e079ccac3ab1cb5eed28d8f942ce05c2fe7bf269caa2fe88f683fe9ed1
+75ffc462ed6ad9ff77e65dde36b5d519c94faff8ca57df37b8fb0df496fb86cf80ddc193
+e082d9bf50e03bd91eb7dd34febb2ec54fb5f8569fd978e035b7fb23bf6aadc537f5d284
+e49538c1fc9a4fe1be57e380daa52fc0f809ff97f463b9e079d99fed52e516aaf4b6ff71
+fb9fce4aed9bd3b80af4a4e320edacdf8728fbbf9dfe31cf53d83ae59bfe42b6ff6cd8f7
+1eff93cbb371afff86e057dd26b6fb36c7b52de0af0dfabc40e9b728fe941bc7a5fe93f5
+61ff8efba0ed1f93edadff76afd06ae057da01fa4bfe26b0ff349ffe97ef7ecbff67add0
+69fad993e279edd55fff93fa5ecda0ffd8f27de09d56ff21f1afde6bd4f818ff95c2f713
+ffafdf5cd97ee01fd3ff59f721fb33db86cbea893f94daae15ffbc86fb60ffa8d036c1fb
+5ef307ffc45aee15afdd91f785fdc417c0f2d704efbe81e0a846f60efeda5fee94fba5c0
+ed7be379facf61edca86e0b179f9d27cf2adfb49cc0bd886beed27e060d3ff8614c3ee3c
+febe2bff9fedb1e376d0ef6acaf321d260fba543c1f212e0a53eff06fbaf28e7c01bc4ed
+81e04fb527ff62fbc2a5d888fb04ed3cb5eb62d835afdd7ded79fe9fd067fcaf3cc8ace1
+80d56afea253fec9ed2ee5c18df31dd9bf39e56dfe7fb6cb93d16ce6b893c6fb4bea01dd
+4aaeec8a4c93dda734fe62d1ea7ae0bf27b6cf18c84bff09d951ed19a3ff9350f125fec1
+02a9e542d888ef6cffb6f847ceaf79faa748d8fa9c65d988f2a5cc79c63895f8a453dd86
+b8e883d906dfafeb86ff7bf5c29ebed051fe6aa4f29432fe03f778e599d009ed40fe4aca
+b682ff86c8a1fe93f24ad81ccb41e419edc07cd9fb884cffb8ed27f3c10385befe62f73b
+cbb175ec93c5f24fe010fe48f8af32fe4df386d5a3ffbe94f862ffc6f660ff94c3ed09b6
+ff508bd8fe7df999f087d298ff86c0dd3cc6fe80d969e498ff64b8eb15b1e0902ca4e57b
+ffc409c0edba50d7fe05e551dd16f95bffd80ec7fe13fb4aa8ff6df75cfc24d35ad828e9
+60f282db92cbfc47e4b1d19dc7fec051ebb893cf9fe569f2d051dd2bed09d260fe85fa9b
+f590ffa52dec9805c2f29510a5d871deaefa479fd87de055d9ff51f817a5d886edaddc79
+edbe7bd9ac26fe66cb5ce122d99e2cb9e315d9529ffa86c9adeda53ce352d82bde5bec38
+b5fc7af5b010ce97f34dd932ccf979ffd03ff4c7fc12d83bf297fe3193f27bb2ca7cff86
+eb88d8a266eeac7ae593edc21ce086ce93dc9fed92fe84cd16ff40f60bb6d786ff58f43b
+a51cfd81fa60f216bfff2facf97bfeba8ce5bda2e038d867d97accf950ffafe638dab6fa
+86ff5af193c3e410ffb6fa9606ce9cc0ff32f99f29c3ff1ecef205e5c197ed1bf5b6fe70
+d1fb79affa80f4d04be52dfc13f5c275ff86f6b0fd93bfe021d857eaa5fa34aeff8dedaf
+22c65295dea65486eda0e371da81d1fb1be341edbd30cdabfe23f6bb41facc5bd93af69f
+bff232ff51fa06ca4eb7fb9abaed6de17aed26afe98ddeefcb68d927dda4fa79d789e513
+b1cf65fb45f70ec2ff86f103fb5abadd74d37afe5fed45e018bacc2cff60f1a52786eeaf
+fe61ed7adf60d0fb945ce066a5ff7ef938afdb933da5ee0ebfed3fc1e023b5ff79d896d6
+83dfb301eaa549cc11fa6df395ff7edb62e6c81dd851fc9ef5affe03fab2ffbb4db7fe20
+ee53b7cc98ff6bfb9ff448c1e06de8d18927ff85d775ff45a6d88ae07cbeffa5dd35e15c
+d2a7c1ff54fbc609d84c72acf492ffb945b4e054fe9bc3ed35e1abcd95ec6db5d64fc7af
+e813a3f625f19cce7ffec39efb51e58fcf83dcbee258d879dc26d793efbf4eb7f687fbb9
+33dd62d2ff79fabbd986ff9966ffa36bfe87c0f13ff75bff31f2bf5dc3ff7bedaece4ee1
+03d046febe6cfb86e57adb39e286d968e032d993f665cba5ff86f65bd4b00ce175d97eb5
+ff09aafec0afed04e593c5fe0ff539b4e623f16df482fe20f83a98dba565f985ffc5e510
+d85be987fe07eeb929f65bff941dff5abffb21f39fff6292fdcb6ad855e008d9a62aed84
+d879fc0bf94dff8efb37f3a3ff5bfb0291ffd80ed845e9c992eaae4eca12ed53e63ac5d9
+09f2cd47e803a6e092cc95d87afb9de51dd9a429ff9cc1fb86f0af16f2a5ca09ff93d66b
+f22acb81f26de807b3e546d90fabeb2af7c493ff19fa3bc999f252e26096fbaf57ec80d9
+9bccf261d994cf0cc7afdf76eccb14f1d08bdb29a34dfe96f71eb0d497ca70df86d86ec8
+f083e53ad0af60de33d8f2bf42ff87fa83ff6bf5bc63ff1ff0a5dd74d7b21cc5afc70fb6
+e583c4e13ca5f18bff9e51fe0df49efeb586fc7aaff578e55bafdc7cfbc875fe19f04de5
+22d48af860fec96bec38afd869de9bd643eab65aee0ffec39effbe1dfb9fc1ff6dfb97c5
+fe79df58db43bfed93e586de6cd815f3ce2fddc21df968ff5493fbae4bffa6fa53a1fe95
+5effaf36fe59f5ecc96add7abef15df73cffa5fb06e6a444d8adff72d9fe8df7b62086ec
+aee433c6afdd3ee5cd94d9b53db8e92fed9ff549fe95f730affe79f4bc5ae417c0f288d0
+5ed831e0c527c1e41cfebf98ff29f3be32dd5ad8a5fe85b7ff40afd89345f6bd90ff25f8
+3dff87fd78f6d073e0b55ee43fdda5cd45f029d8ad33f24acf9ffe81f9a263d85dfe2df8
+9effb67aff6df0a3bbd62ce5c413c0e374da39edc405bfde7ce393c1d97a01a8fb36cfff
+2ee07ed9bb4bb6f17bfeaffb0297ed2fbe10ca5ec5fe950acba5ed1e9afb9307f74cfe9c
+f77bfe85e066d879e06abedd4bd520ccfe7cb3d92ede73fb84f26af8a0ff80d89337f786
+d7b168ff8bfa80dc35c6ed6acaf409edacd010e079d293ebb31fbfdd2b9afbc14bf193f8
+73fe83d993dd7eeac291bee622b9ec06c1ff27f2a5cfba4eca37ed9ad340fe5df4af7afe
+9ff729fe84d88eff86f330fb4af81cafffb9ee86e6af61c7a5fb12ed93dd5fd035dc62c6
+f77accf493ffa5e046d7f979ff67f8d04bedc888d86de013ca52d009ffa5f021cdff7df2
+9dfb943ec2fa66ffafed15db98d202dd44ed51c4e0ad4fed17e8a4cf08ec6df3a00ffab6
+7adb84ff6ff99ff158d973ccf2a253ffc41693ffae1ab8d20af362ff59f802ff61fa79f3
+68cba7e07dd9af02fc77ef87ddac0dfab779e005cbed3ddd63d09ded1bdd46b6d89ec6ac
+d299e06dcd5ad80cf29bfe51ccb163fa25ff83f98af2a553e09f4dd83aed88f26cbadf3a
+dab279ffb461ff31f3c096ffa6fab7c63ab3fc9343e519d86ae0afdc25e09f4bc0feaa47
+ffb779fab8a5ff0cf1c29efeba48f6b788ff54e0aad93bfe4fe629ddc03ac4fb0bfe4988
+fac679edabe039d0fe66ed9fc0e523b6c993d9b717dd94ff31fb4ff73aedc194e51efa51
+fec269ebc796fd74b6fa90bce95aaffb6bf7cc61ff0cf252ff42fb2df979ff89de1aec85
+ffc19fd4afe016d82dd0fc0cffaefa86c517b2fe1d9bf2c110e6c22ae07edba957ee26e5
+4691ec86de5edac0a5fe84f708ff5af279d1f48739e1be64ed99cd1edf87d96cfb3bcc68
+da7ae5c922d887ff64bfd79cbbfb5d93fea57add9be1c007e5af35fa6ded86bede4fff3b
+88d1fc6aed3fd0feaf46b6d88ed894d086ff42afd891d880f2af1aff3aace01ece50ff02
+f5c980e4a52bed93e085da88eda2e093ddbf47c2f978da09e03ff5519aeeb6ff61bcd981
+e424b8ff9ee552d5fb4b8ffd9453f1acf903fed189d97fd6f41cffa0f804f15fb9cf52ec
+93c7a3fd0694d8f76dfbca2bfe58f373fb30d093e085fa11ff40affb60ed30aff206ff66
+cdaee51eedbc30f755ffaf68fed885d55af7219bebc5affaa735d8aff75a85ed9ee469f0
+16fe58dc76c9f561ff2be548dabf64c3f65aff93ef81d6ae42ff10c1fe7ed85bfe33ca17
+bf51fe21abf09e37d893f288ea7dc7fe874899eb933df26bd0ed5ad97aefbf7bceec61d8
+fa9e5dcbb78437ff61f6be5ab5d03fc1e97bff2deda6ca67e636cbb0ff24b6ce12acd980
+e2abcb4ee779ff1fef97e4be9ded8ad37ff9ce70e093ef15f352d861ffce92d87ceeb925
+beff01dd78cdfb8710e260f196ff0c9de0c22af907ff83e5a9f21dfba512e098cca6fe79
+f79dee86d76edf27b8fe6dd9be97dd5ae61ff4c09be6aaf3d97acbfe70d1ff63fb4ac91f
+fbb804e5c8fb1cdfc1a5fe4694f601fbaf28ffaf06feb623d0ff44d9f0abc3df1293fed9
+6bfb964ccc9fd886fb14ffaff986ee5ae579f196ff3ff7c00affa0c1f45dd8b652c82ffe
+51d904e7b525fbab43d8b99bff85e7a245f017e041cef559a3f08cffb045c1fe7dd81cdf
+86c6fb3aff89cebf52cbba6dc4e064d4ffbf4cfb08bee02ed812dd35fac19ae537b4f260
+fb32f7a3ceb278f166ff8404f7a542e911b6e49bbdff9fd86af7b470bef264fb0fc9afe0
+79b7cb64de77e198c96be575beed931bfa4c99fcc53195ed0ed9bbf510fa4bb6e09647d8
+1ad0a5c3fb42e588ebb46cdd60ed14a9d981fea5f98fc4f26ffec279df86cafe61fa34cb
+b602fbc67efa99fe6f96eaca4ad828e5a5dc31edb9feab48e860d9b3ed5dfda5f520ff3f
+9eeb8d52a1ed88ec5ca5fb7bffa5e9870cff79f8cd18e08dd8bc69ff3afb12dd47d1db81
+e0c097f35dcb1ced53e538aed943ff31a5d88bdb86fa20ffd839fea8f538f24ff69ffe0e
+87fbc4a3bfe778efaefa79b0ff8761e4c2a2f161c1ed91ff6ef83186dcbf55d025fe9ef9
+93befe3cf202e64ad918ace09f38ff4cf71bbee98ae279f2d76fb5db50d22bd9fb14abfe
+93f381ff79f99d4a7bf5c493f38618a0d832d978e386beef04fdc2f826d96dffce44edbf
+51caf2aac5dc4e93ffad47fe04ed93bdd89ebffc884dff28fb52afff81fc7adb86fed079
+ed95c4e64dff2ded61cdab73edc1119cd88bd9ae36d8afe03bda54ff06d94ae021bee033
+d3fe9341ff23affe2edb4ddf9bbeffa40cfe91eec147d22edd65e0a5d093bff184ff45bf
+ea83d19bed8640d414fe4b97ed1dff87f491b85ec3e073dd5bc709cd63e5b1d905ed29af
+ffb7fb62f297fe47cffa68d0b038d884c4e52091d9af79fc932afb429ff2c062ecc59cb8
+d150e57aec2faceee1b0d093f1d931e6a7c60bf3b624fac015fe7ff393e07cb6f351fbb2
+6fd9fa4dff1afbc386f85dff7af286cd66ff82cffe5bf3a41fc6dd7ed0e579d886f2c403
+e15ad3ed79d960a8f380ff7af7c350ff2cfb54b8d293fa11b5f35bc3ffa7fb9ec7affd68
+d8a5ca0dc1f186ff43f61bb5fb9cf4b621ff88fba0c0e451de7bd9b908b6de952bb8ff79
+f496ff44aff1bff501e53fc1e07ebffe0ae4b023f558fb7ff709ff60f6c76da013ed3dc2
+87b9d045eda4cb6ceb59a5df71d906cd58fed50ee1c42bff87b8cb7bed88e514bfd399ea
+21b8fb9db9f2409ed872e8b6fb66f7b850fa0afeb36afb94f62bb2f920ffcc04e0afd61a
+95ed7cb2d787fe1ff062ccfe2adbaf09e563ed5add2cb7f33bfba6ff36e59fd591bfe062
+d93cd8eec156d038fe65cf0ced3fff8af76ffeaedd3ee0c10ddba5fb804d86ffc6a0fe61
+b2eb6fd97dfdd079d92cdd9ecb89d8a521ffd8fa7cb6fe06fa70ff84f72fff85ccff48f9
+bf9eedb54095fba466e65aed21e4b03edd61ff8df129cba5e439ed17c9aced01ffc33c90
+ed0b9aeabfa5cd3cecc176c6e962c0e0a576fb9843f0bcfe38c0e50dec98de7ad9a457e4
+79ed93cdb725ff84f7c881da78e37bd9af06fa57ff2ff87eff934ca5f27edd79f294ff83
+d0adeb4ed512ea7df2ab57fb66d416c2fed89749f214d0fa1fd795ed51a1ff87f26cff5a
+f23efecc5e934ccdf479d893dd23d860e0afd90e95e59133ff66f6c2dd27bff593da82fe
+66f3bf7febaa47affb7af470db93fe68f886d95995febf54c4ff8734ef60ffa123fe499c
+ff8c4df5d85bc7ff8f60d9a3f259fdac3ec3f82fffc095fa4cff3cf8d86be0a908ff57ee
+28d051edbf93eaa6cb97ed12b8fbc517ffabe723d84ac6f91c9be085f260cb18fe93cdac
+f288e09d25edba80e2a24cf05dff27bee70cc7a7ce17e095de79a5f2c7fe9d28e447ee5a
+f388fb9c3ffebdd862f4c6ade01588ff7fd844ff04c69fd20cffcf2afdc7e352d90cffbe
+48afdd2ee579fad017dea8e05ed4fb8de080d0e585d9be0fc4ed9616e4ad2aecc207fb70
+dd81d0ff6bb1e58aed0fd0bb9de075afcf41ed87d3b79ffe88f76bfe3bd21cf24bafd2e5
+72dd98cc42befe86e5af5abffc3bffc49efbb886ec1fe44cff3cf7c168fed85fffcb86d9
+88cefb69b2f938feb664fa1dc1e40bb638eabfa9ff9fc6aacc14edc55d87f8b31ae14ba0
+fad74db6ee9ec9abf941fbbc59abf2940284ffc19fce63fbd77dffb1c944aff574fe37f3
+af12cb47f216b8fa39f3a5fc39cafe7ef9cf79fe93b8d819f85fbbed03d64aaafc77f521
+c4fe0df395c3fb4af514c0e021d8aeda79fe6cc2fe8745ff31f96df6a256f10ffe9fef77
+d9b222da46e061baff9fc894da75e9b30babf328affb05f5ad42c2e27bed86e5c38fbaff
+69f97bdd88fb63cf1cf83bffba70fbabdd27cffb86fec35a93f2cb19fd5ce67add6eec99
+e04adab6eb9343ed28e0a212f0961ffd9dee2fd891d87ddd9ffeba99fd71afdf79d86add
+af52ed1e9edd3ae54eff9fc1e826a1fb7ffecb34d986df66b6e887ff1eafe27edd6ea8ff
+955bfba5c89de403f3bfa8d093e004d9c398df65d82fe6c06afa79ffa5f033d05ded05af
+fe31d3fb52c5e56cc1e067dd97fe12d850d324ff51ed40afd8
+> >> /Halftone defineresource
+
+/BlueNoiseMaskCyan <<
+ /HalftoneType 3
+ /Width 167
+ /Height 167
+ /Thresholds <
+7bb6c793d8a0e14ddb04d951e02dcdb901eca3c572efa5fe78b5d86adcfa3ef584d3b938
+f308ff45f9ca7ad989de80e593bfda7debc76ae0bc679dea874abeecb83af378ff9accaf
+f175d8f36bfcc2a1e5018ebef786ff51ef28d44de122ceb819c974ed86e4ac64ff9bf786
+f29f6bf95fdd20ceff4ff5cb82e0ab3fd8b352dd16e5c484e25dd8fb6087ffafd14ac1fe
+d8b34db7ffd15cf7a9ff54c3ed3aafe070c7ff7af29cffdd38fe4cfa13b0ff81f77afe93
+f95aeea8c94de5accb1cc0e527f2ad10b5cf95e855e58dd8be9be06db6fd3bf759ce0ffe
+60b5ff41affe9238f8d05bd8fb9e1189dd93d9c049fb0293deaf0ecf52ed3dcdaefb579f
+e06ada93f978ffbf98f757ff93f65cfe3ef9be38df4dcd37ffafd295c0f67ab8dd6eb6fe
+11d0f97affc86bf88cff27bffe933dc1e99530eda5e28328f27be58e3cecbf0bcba5fe78
+b8ff26f4a445e423d85188ea9dcd7cedd028e0a5cb21dd79d886fb6afe10f468fd5199ff
+7dc5fe87ff02c1f92bfe50f128c2ed12d6a7c59fedadc3f421d19fe026d6edab05feb027
+efc3fe57fa20a5e487d8ff4af886ffbe95ff60f227e6c31efbb93bb6d89442ed6bd988d8
+2ddd9ecf79f1d186fe7fd95ae006fd40afe00ca0fb38c1ed65bee82193ecb64cb7e09f15
+edb0ff0dcbf95afd12bce9adfb0ec2fb9e50f366e430d0e580d886dfbfa7fd83effbbf28
+f4b63d93fbc042feabbfff0ce636dd96d892d981ebd062e037d84bbcee6099ddafc993fb
+64a2ff72f203ff4dfb349ce779f280fba35afbcb7ae590d251a8e07fcffe34f679b6ca99
+e344eb18afde81d870ffb37aeda3ff13f3c3a7ff0af16ce5ae14fbb32498e501edb8fb79
+efc3a5ff67f1c357e679afff46a8cffe2ed9a5f171f9cd67d879e06abedd76c9ff8a43cc
+a4e078cfff86d891fa9f10f151fe14fa5ac9b60163a9e479fec2f15297e970f04789f2af
+cf7af75bff27fab809fb9df5afed78d7abff860dea5bcfafe536d097dd90d886e0bf52fb
+0ec862e5c14395de31ff78f9cb09efb970dd5eec1cfd2ad5b27bf9d036feb6ee47cef504
+d187e360de2fbccb9efb4cffbf5fe6c6ff6dd8a52899d89352ec1fd87cff93c6fc2ed89a
+f774b2f279fe08dc43abfc1ff6adfe3f93f19a52d8f479ff22f12fb1e51ced4bbfff94cc
+89d995ed32ffd9cfff47d80687d9aff311d19ec2de9b61ffbe1ee9b9dd6093edc256d218
+94fb24f23cc3fb94ff1bf252da7afe5cf91ef368ffa6cc93ffb618f5afff65f39fd8399a
+ff932ffbc197c6f28fe56efec14e93e09f0c93dd9b5abffa43aefe8cf95ced3bafdb7ad2
+f38b49b9f257feb6f435ffcb88fa97e42fdb09b9f27ae502dd4fc0e05ad37affc682eb97
+2cd3afff1cdaf7bf03dd5ed9b9fb61c1fe7cb0dc6ddf36ec63d179e052931c9fee93fab9
+31ff5db6ff37f91afec72ef1b08745a4f2cf40a5ff84f8cc65debfa4e061d880dd87fea7
+ed2bcb84d897d007ed42dc50edd183da21d8ae0cf1b3e54bc4e0ad15ff43b961c2f408ed
+a9ff6df3b8fb2cfeaad96feac921d878e080fed01df69606d8fb931de077d983e2a914dd
+47d060fa9fed69afd256fb87ff12a8fb93ed9e32dd53caf27de665ccb23a88feb6ed9749
+93df9c43c5f703fb5df5b6ff2afbc2afecf8c65add70d0e681cbe463d878ec51a5e05dd4
+feb4fa169ffed821e44aa8ff8f53fe77f730ed46d6b60ab9dc94f03bfe59d978fdaff797
+37fe6ef986edbf73fb67aff26cf891d29ed8ff37addd63d815d749d860e086f134ffb867
+eea0ff03c6b686e554b7ffa53be9c4a5f90bfd4bbff186fe92f2c14abfff27faa0c4d961
+efc93dd91acef587fea64efa0ab9ef6efbd7a53681ffb5f809ffade079d59bd8920ba5e5
+9e0efe6b3baaf323ff45a7fc1c9bfb93da85ccfb7ef79707e079bfe54a88f195c4e00dca
+ed15d99dcba5fe79fa9cf66fff62e5afee85e5c41587e1c0a5e64fc83bfed924beff0ed7
+41e052ed04b4ed5ac0fb83f6a4fe7ef7af1ac1e0930dfdbe44caaaf535fe62facb72edc0
+86ff5ece93c99eff65d832e00ea5fe81d8b46eed1d94e59f6cf985ffb963e302d9bbd89a
+ff47e5a81ff1c5d814ea61d088ef27ff4ff239fec3f97bbfdd8ed8ffcc88d884edc67aed
+bd4af209ffb112d93ccaee54d7ff69cafbaf38fe6ef5a57afabf50ff07c2e432d84de01e
+cabb119ffb2e97ffbb47ff07cf9cfeb85ca8d0e87dd987fea6f579fb63c6ff9331edba24
+c4eb38cdff9863f7aed67cfb88dd77d894dea529d94bfb0faff22eed51d926e9aef373cc
+e63ade14eac24effbe37fed024e4b34bfac193ff7f29e06bd880c7ff8652fc8acbabf43e
+bfdc93cd7ee0b361d83cf256f67aba14fb60f7a40bdb53ffc988e0c163edbbff70b9fe89
+2ff2b604dec192d959ead543a9ed88e059b0f293ff79aff86affd94fc1db5ff3d081ec6c
+f21de286ed9335f861edc52ec1da8ae49d1edcadcf78ff6ab1d9875bf2ca4cdf2aeb53f1
+18ff4ff20bc7ff82e49ac2dc6ce0affb78f6c05894ffaf5bf786ff7bf6af79d8f25aacf4
+c27ce0a42ef256c3fbaef515fe3e9ae0be9fed2dd980fea25bf614fbc025ee86ff96d42b
+e070ed9ce02fcbf386e59f1fea3f9ffa934ba5df299be5acd082ed6bfc26bafe1c97ffc5
+2afb7bf66cc816b6ecd041e0bf79b0ed74e523a5fb4db6d893c3ff02fbca88dd1894ffa1
+20fe45d0fa7bf350e297f204fdbed809a5fe79fa9ad1a5e584cd8ce2a042f3ba5eff31fa
+a015c1df9a05fbda20ed93cbb653dd32d4fb0db686de8e41f708feafcf9fee8635bfeb92
+cff607fa46c3ff59e61ec2e487d9a455ffa5c917e265feb1fbc53fafff6cb6fe38d8fb7d
+f5d425ddb6fb86f6c313f951ff3cd49aed79caafe36de793bfdb23b7fe86fa3093fcaa23
+c6fe03fa93c2df7ac8ff32fa4aa1dc79b5fe50f3bc4be3b881eda551e90bfec52dc1e093
+42ffafed3ddbb00fff3eb1f730fe69fbafce1bed93d07ad8ff873dfec579b9d563ff07fa
+d08bfe9560edc6ff16fbcd97d86fe548dd11d1ff9d5fde79b8db84e26aa5f279b5fb4aff
+31edafd26be9b582efc402ab5dfed985eb24d0ae6ab8c751afff5ff106d85bedb17bdd86
+b5f84faaff5dfa3fd803f34b9fffd340df9ec2da6bed88f457d8b54bff3ef60ca5e588f1
+bc55eb20ceb079d3fb73f7cc11ffbf94d8b658fb9f4df8cc7be077d085e7c293bfdd7ad8
+9dd725ee61feac56eabe4393ecd066e5af50f49bc1e19e41ec17c9e39d4493eabe51ff32
+f295ff8bfab142c3f221ff4aa6fe25f8bf0ec5e086d896d079fe08f446f9c03393f2dd87
+bd0ecc59fa79d9f704fe9ae083d07be66eff35cffe2bc8eb18e1cd0ddd82f186fea5c3e2
+5f93efaf55f40aff47d096e06dea9fd2b895edd65ad916c9f784fc67d8ff0999dd32afe6
+69d93afe88e577edd5a526f34ffb1fff38f261fe5afb05ed55de91d880caf902feabf323
+a4f21affc335fe4884f2be7df3a52cfbb1dc63a5ed88d85ecb1dd653eda5fe7bd86aeccc
+63d87ade96ff37f506ed60df89cb9cdc7bffafe54f27f8d895ffa5c0ed43b4e587ee16f9
+35fea4c894e165baeda162ffbe79f2afcb20bcd062fc18f7bd05ffd77de5a5befb13affe
+31f519fb52bf86fb78ff983fe0a5ee38a7e0be52ff5ec2fb86f1ac25bfff1686fcc786d8
+93da9fcb86d91ae0afc785f872ff10e549b4dd69d872cbff81d987efa4d8b8d924fed74b
+ffcf79f101fec522f976fe86ed7ade87d804e493fbbf14f19ffd44ee88d26dc9b1ff20f7
+51fc24d859d878ffcfb362e548df1595ff70c848b6d88adcaf44f01dabfb8c09fed89557
+fb9f53ff9efa47ed8fdd79cbea8738feb828df62eccb87d880e176cdff26afe930d1feb6
+0fc48dfa6ef6d084f29a2ae060d2f866caafe75ab8ff14f15bf76dffa4f59644ffbb38cb
+b1f295ff86c4f535fcb25ce02fd152e41288fbb067ace570bbe857d878e09abfda0ae0a5
+fb24ff6ef75bcb378fffb83bb5d8ad5bfba2fa3ea6d893d983e7adf20bed9ffb1af491f9
+71fec431befb99ff2df262fbd883ffcd45e5d29335c2e327d2ed33e077d9b12fb7fe5296
+faaecb59f689ffa250f161ffa5d839adf2cc7bddad53f27dfed948e528afec0fd9bfa4ff
+0198df4bf392d83bdd9fc6b605ea2dd879ceec68dca3fd297bda3bed20a1e0bf0deda5fb
+7cf793ffc133f0db06c5f91c9effb7f44bff3b93f6af42c7b74fe6c1a4edaedf72da94e9
+01ffc01aea62c0e57af031ffbf6196fec15286e1c633bfd97fe6a5f21ceb61d0a5c602ad
+e55a95f7bd60f2aff780ff86b6c793f610ffa0d93be5d220e06fdc7ad835c6fa21d9af0e
+f39ae08b07ff62f893d8af26b8cc95ff69c5f962fe38cbb0ed7efea70cffb365f978fed0
+8ae056fe22a5fa12f086e5c2a6f979c0ff4b92fac841bfde04d84aedaf79bfff945ac3e0
+8820a2ddc3afe56ccffe79f4d8872fff1afa4ef429fe86f278e4a8cc95ff11fb5ecbb61a
+fbc54193dafe4badff9e06f34dd864df93bcfc53f797ff3abfec0ea2fe4add13da68f002
+fe5fccb67dec6af3ac6dee9cff11fa99f2b686e47bfbc586fe5bfac09fed1bcf42ffe486
+fc04d8bf43ace093f086fb46db2dd0f279cced2fd94babfa7cef8ec1e479c95ed24dfe19
+d19ce868c6e66196ff719ffe83e668d4fa4186ecadfe3ff2b4fb870ff150ff2799d9099f
+fbafd48fc9b681e5af52c4d950fe31ef5ab7c7a0e46eed79e1aff229c3a0e066edcd93ff
+8bfbc13dd90ce07aed72d0fb6dc2e085d87dffa5ca4ce6a5f23bfed826fbc10affb945c4
+e8af4bd001ff5acf30ef46afda2be54dc7a5fbbd8cc44fb4f17ffb9dff17d559e273c8ac
+fa69bde421a2ff92f2c53adb0cb6f331b8ff9cf8be93f15dfe0bb5fb2ac1ed19c4f059ce
+a9ff189ad8f52bdf6bd772d83acffe83d99fc0ee58ffbe55ed69f630fcce10d6fb9925f5
+92d886d1f64afe03f799d32fff86e95afa15f6b558e02ddb0fa5f281ff9fcc2fd9af21b5
+ff38fa1cedaf2ffc9dd86bc0e4925bcfaf79e1c87ff29364d8ff78edc0a0ebbb96c2e86d
+d785fe79eb5fdf07eda0d961e434de88d87bfe27b9ff1199ec4093fbbe51e0179cff86d0
+ff62afed3add09eb43ade084cff279affe7fb1e038b6f72694cbfe61b7ce93fa09ff7ff6
+a55de8af17f96bdd86f2d00ee09dd85f93fea53ee0c177e265fe2099e086daac44fca5cd
+09bb93d788c240fe7ced86c9fe6be4ae4df4befe60f3d686d89bcb79dfc089f324ff961a
+f5a7ff4df8b252fb18bffd2fa8d99343f61dff55fb05ffb9ed13dc37fe83f46bff30f7ad
+ce79f351ebc19fdc6bf4cf83ffd661edca79fdce5be59e46c4fc88d87ffe93c4ff30d9a9
+4fd8e451d1f76cfdc772d8f24cb6ed11ff50c0ed90dd29edc932fcd17eea39cb2b95feaf
+42ffc0ee48bff885ffb50cf2bfafec38d862ffc267ec7ad9fff24dffdd95d5b661faaf46
+d024fad893108dde9f4ff167f541fe5cf854ceba51c5e072dd05edbe27e6c3a5e054c8f8
+1bfecd7ad993df80d8a43e88faafd19fc645d4afe0960dffbe24feb508ed43e5be55df19
+b5f707afdd48b5f624fbade502d954edaf5bdc77b6f725ffb703f1a329d9ac0effb57ce1
+86c8af7be5a444cc59feb67ce09649ffbc93feb0e05bc7f28707d99ee119d84cedcf9453
+f779ffafed15dfb422faae38cbb67f27fb0ef3cd20e094edb8863affcaf733ffc703d990
+e49fd909e279eea9fe3ffac194d882fe9a66ff80f39a61e0ab5cfaaf3ab2f26af8b6e098
+50f61fffa6fb2188fec75df1a1cb81fa92ffa52ffeaeee74c79efe87f283c0df7ad866fa
+73ff2acefb0ff5cb69e2c25ffb7acbff62f48bdb46fb03ff3cf7d328feaff894c705f263
+f7adcb02e463f486fa20a2e6b879ff69f37cfba160ffd607ddc02b93f983f4be6de59a19
+eed8bfa4e151abff79f65affc5eda55eb6d862affb7aff19d07effb6fb15d886d8af51ff
+34f260d1ed38d807d2f086c6e509edc6fe18cf4ded23ffcb86e279d87bcbed489fe686d9
+34e058d870ceed935cc2fb4ce538d810e33fa4ff14f196cba5e57ab9e4a940ffb085dd94
+e6189be03bcf9fec84d895dd79bef061db1ae56affa4d922dd61fbabc914d973edd44bf5
+cb31ddafca28c3e53ba5fd609bfbcb52d83bcffe56ddfd9e44f566c4fb73d8b701d99e17
+88e0c520f292e85acca5ed67e09746a3dd60e90cf286cea5c2e411a9f68efeb942fe2da3
+ff90509fe57bff93d865b4d949ef0ee75dbaf9d917fb6affa6f61bfbb805d8f93099d97c
+f6b9ff6ff9cb6cd9af42ed18c2fe3987ef96d715fe37f46dbefa7cbefe20bcf936f351fc
+1e9dd882fb9ebad84cc1fe81f29f3dedba52ffb685fe66a5fb9345ff9bf570bfed80e4c3
+46a6ef93ffa207f18c5cc9ff93e62bb2ed39cbfb7ae5b2f246fe86bffd13baf92dc0fc1f
+f4b3ff82f97aff9ce31ffb4f93fecb5ae0669fdd7ee7d06edbb6f937dcad2efac20afeb8
+85ff9cf5328fb3c851ecba7ac4e6618cffa465d6ff1ceba54795d8a932f386febf79f955
+98dfc11ffa71ea93d859cced4eb3ee65e574cba9c593d0afff3df2c252ed1ffb77b0e02d
+d0ff80f8a0cd32e513bfe005d0ef5fd910b4fa32d11bf3affe0be279edc779d8e6ab04da
+5aff6fc1fe64afef52fe6cd795ec42cba3dd50ec7cafd363ed33ca26d0be3faff488ecbf
+4497fa24bfff0ef7a648fb14e96bd886ebbd74f1ac68f3cc3cd886d0ff5ae5a5d009f24a
+97d8f23fcaf483b6cd67feb6f023fec15cde1fe0a3d6b1f26bffa5cdb649f87affa92afe
+d80cd99afb52ff14ed61dd6ee3b30aff86d399ea0fbfed934fda22e57afbc596ff77f3b8
+87e580fecb86dd94fe7bdc87d252d92db5ff347af9c682ed87d911a8de28bfd51dbaf90a
+aeff6af674ff98d93cffb993bfe593ef5afcd26edc27fface579d5ed74ce60c2ed86cb98
+fe09f75afed240e0c11baee56dfd01bff027fa6bfe86c1ff2aa8e1bc0be54ffab003d979
+d587e49dbff658ff33fc07d247ed5bfec19edf0be4c7a078ff88f12ce080da98fe0cf5c4
+79de62b6f35ac5ff9066fec1aefb62d8af48ea5ad89f41ff1ed0af2cff56ea61cd37eb6b
+fb8afa65c1f3dd419ffe21b8fa9cf577ff7bfb9bdf79cbe487d825d3af05fbc859e00dfe
+4efab0e0a201ff5bd77bd905ffaf47b6f494ff23bef33fb9cf9fe11296ff81fb9efe4ced
+afda61acd880de3bafed79cbfb5c93ff9bda7ec8f388ff60f509ff4694d987ce93e79fdd
+8fd801f231bff19262f6bf43c958d2b1f75ace86d8a534fe92f8cc31fca540f1d807e145
+99ee09ff88c1f72cfdc46cbded6de5a5d30df7a0ff82f21dcbafe512a56efbd266e4cb4d
+d838e1afce4bf23affa533fa55f17ae6c288acf779f2a5db861781f8be86e99df363f0c3
+84fbd82bde51b1e37fff75f048c7afed60cf27dd79d8962ffa88f74fff99c5e321dc9f13
+ebc049ef25fe3fa5e42add81d0a6c3fb0eed62d96dfa26fd80e688d9a553ffd01deba8f9
+95fe18a5e12ffa49ffbf51e7149cdc7de4be60b7f779ffcb70dfa5f218afe087eda5f850
+fbc179f1b666d823debfa5ff4495fecfecbc0cf3b07bff8bf29806ec8fc1da67edc683e0
+9cfe38f24ce121d9c43bc6ffb6d937edc940fb1cccaf39e01295fa7dcbfd59d81bddaefb
+63ff38b6f893c2f50effc09ed21cedbc11fb8af762febf7af8d06cd886e0bf5cfb51b9ed
+66e579cbafff1ef286c65fcc3fff6afac239affe86db05e561c3ff79eeb6e57aeda5caaf
+ff4def27d0fb9d3ad9af1dfabd3acf9eff4dcd10d836de9d01ff4ac9fb89f49b56e379d8
+ed87269959ffbf3eed1ad94fc9fe61fd10b2f81eafff08ce5fda95ff80fb9f6cfb955df0
+8dfe73afd877b5f96bfeb8edc55beca103ee91fac12f93eb83c9e558ed35afe16ff142fe
+a5ca6ee0b541b7d832f1af379ffe93f516ff9bcba5f820fe37b5f1479fe051b6ffa5f6bd
+9cdd18ed97e556d872ffc188de3dd8a70393d919fb6df184d495fe9317c2f384eda4c754
+fe79ed68dc7ef294ff62b9d98ee89e14d947cafd03f7bf39b9f8e0abcf7fdd88fbaef66b
+b6d894e679d09add6bd97fedb610b8d533edbf06c2e224d750dd13ffc1e62bd8a24c88ff
+af3cffd27ae0649affd11edda802ffbea3fb52d081df8ee756fe85f49eff79dd68d6fbc2
+1fed53d08aed0edd83d88cc8ff7dd6fb78c9e739d812e25ac4fd67d979f32defaf3afb9d
+f362fec6fb61d05ad82de009d977ebafff51e52bff80f294d928faa8fe45e47ac7f450fa
+38c1ff80f8b878ddb064ffd6794af22aeb61e5c3369fe523fa53c2ff4bfb3ef5a6fe45fa
+a5ed6adb52ffa8f470fe7df793f2924498ff86f2b4d91fe5be6cb2f433ccf15da5f652fe
+8bd069e07cd921fdc107aff21dd351d903eeb2ff0f86e4b074b7e561c0fa6dff40f3ae02
+e92ebaed0e95f47dfe93f72fb1ce0ffba3bbcb7ae0b80db3e48f4bbef094ff88f6a8ff5e
+f936d87ccf96d86add0fe85dd5b804b6d793fb1ba6e082afe45aeca92fffc225f2a518fb
+da94fdaaff1486d8fe75d09ef12ab4ed93e5bc2ac3e086d827fe86e578d843dea5ca32e0
+57d0eebb52dd0bfb6af186d8f919c2ffa20fc0d96de3b0d940f716ff95edaf5affc67ddd
+87fbade59344a2e9cb40ffc6f72fffad45d0afe166dd9dc1fa619bffcf60dab545b8eb86
+ffabc84aff1cf94df588ff27d8f29d1fdd40e5c36abdcba2e35af105fe4bf9afcb88ff85
+f69bee2dda5acdff28bbfe79d81fccee6c97e086e6c86ab602c7478dbff8af0ebeff5dac
+e061c807cd63ed9e18ff71f3a2cb16f89cffb70efbbe9efdb405face7ae89bcc48fe349e
+ed9351e6affe36fb981bf2b787d875cc32f7a4d860fb3cedc32f86fcbdf5619aed920595
+d87be096ec1aa1fe2bf65193e0c242affc25f1a5ff78df27db6ee995dd80d9a2ed5acab6
+36ffc167fab30ffb40ee1bb8fea5dc86e09e36fcbf21dd4fe187ff85f37494ecd007f190
+fe9c5fd8fb3dff4f9cfeeb84e3aff1d35de087ed44cbf97eff88f794ff84fbba5adec153
+eaaad02fc666e561ed1cd87fdc9139fec029ffb975c3db61fbcf88f37bdd87cbff70c6fe
+59f292dc6be52bec89d9689affc64ee018d8f95ad9c0fe4df30dfd87faca71d982d3fe1d
+f286df8dd66dd904d25cf293f709d75efebf21d0aafb7aeb85df9fcd71e085da8fff79ca
+47c0f36dc6f15becb679feaf42c3e00dbff659a0e06ad945c6fa0db5ce7ad9f13293ff52
+fb2999ff3bfb93d9b703db31d84cd91fd851ccf1ae03fe89f45cfd87f199d884ffad4afe
+c4f062a9e07bd9a5ed06e4b525dd43d807ed4aa5e0299fe80afe4cfbc396bfff0cf6c020
+f2b879ffb528affb72b5e9a0cdb93abf4ef2afff37b6cd9ffe09f950f59ffa86febf50c3
+fe84f2379bfa81e514da53f706fe39f3a5fe51d833e591fa9a2fff0aafd87afaca15d8f9
+a368fed631b7fe3ffba5f4b67ce98af6af09b8d243c1d97acbea7adac41bf084fea9f36d
+feb5f079e52c93fa85c93fb6d979e01eff3aee52c1f29f1987d6fb58f30ffa5dfec083ff
+79fa86ff79bfef62f9c97adda5d2b613f247a6d781eab065de9ccb6bfecf3ce01cc75aff
+79f7db93d507a5ed7be556bdcb79e3ba41b3e0329deda63ce08fc9ed48d869fe8ac7a5d4
+7fe1b724bbebaefb60d811edafd0a1fe30df469fed9327e6c14997fadb6ecabc1bd436ff
+51de2fc5ff87f8ed9f0cf4a521f254a3faab37d157c0e09c3da5fc8fffc347beed94ff0b
+f9a5d091bccd87e029d9b6eaa013ca96e080d7af4af13dc7afe045b6fc10d8af39fbbe26
+f077fe86c5f831fe4bcefe06fa3aeebe85f58eff93ed2cd8a716ff61fbc74ef813ff82ee
+af23ff94ed69cefb1ae5ba63ff12b7fe9ff143baff30eeb44aff95f78801c2f27eff6dd9
+66e582ef8bffbd61ffce77fdaeed8813b0f27aff93ed9fd681fb6be25aad28ceff70e4b8
+86ffbf4cc3ff89ee9613f7b8dd0bcf60e49ffe2eda71d7b647f55afe04f7aaff65fb40f5
+b0ff3abfff27f594cba7ec139ff6d17ee488ff9bd055ff92e55db0e07ad899dd6fa5e486
+d8a50dea49d860d77bde65f2c09aedb67add89d862e033fbd986d812ffb679d85af3cc93
+de7bd002c6aaf479e57dfbcc72d95cd2ff9e43caa5e243fb1ec757d104f2d83ba6f306d9
+4cbdffd82adc62cc84da15eda5d01dc0fee063bedb39fbcd06e799df61d926ffca7be974
+f983f110d862e5aefb36e79cbfd894eb8038c1e094d07dd86ae5a552dc67ea1cfe60fbcd
+8e22f251d621df6bed7ece34c1ed07fe53f31afbc03cf761ffcf78feb6f202fba5fe37da
+4acb1fe53bfea2f5aac78fc147f9a5c830f786ffa42cfb4df66aff86e024db52ca1b9fe6
+12eeb532e0afed25bef494b7ff97f7b36993edc75ae07dfbd0579dfc93f302fe5afabe3f
+fe99dd79a2fb4893ed9d66d978fc12f67fe5a652fe2fd74ddca5ff7df7c1159ff264ff23
+fa43afd8fa890bed50fe22f285f9c884fe9dd986debc4cffc0affe70f5affb03baf79fff
+6bd3a5c783e188d994baed2396dda72899e3af44c1e67bfb73ff88efbf22cf4dfe19f2b7
+6fe562edafd20ec0e083d9a7e83ded5ffbc099f2affe58fac179fb6cf684ff87cd61eb2a
+dd4ce5c0fe2086ffaff13393f5c240e052d873dfb272e58cf249f712d7affe17b9ff4aef
+c593bed646fad085edb2ffbe27b6e03b8dffce7ed888e07ac4ff5b9ed4ff7add88e05bcf
+18b3e009d253f22d9ded6bda369fe5933fcba5e048da1db1f22effb647f827ff4cc8afe5
+39fab8ff6dcbf38810f0a5e059d8a85cff83ed95dc7cffd006fca143e497f040fec215b8
+d89eceb40ffe43d981dda54edd9ccf19d851dd0afea5cf7aff9f37d7ace9961ccaabdd0a
+e586bfff87f8c02dffc305d8a8c7f07ddd68c9f282e0ae31fe5af491b709e09f1c8ee286
+fa55cbf3bc4ae401f34bb3ef1abbe72fb5c835f9b9a2ff96fc6df67bff92cffe01e190ed
+c10ac3ff84f365ff94fbcb57d977e9cc6ce0aff266fe7ff18ad953df2098ffd3b927b5f2
+03fac49cdd08d652ea37afdd82cbfa67ff6dd0b079ff5bfa2aff76e08bd86aef28bfff0c
+f25afe95fa79f0c142fbbb18c3f281fb52d0f965fe75ffafee22a6eb17a0f24faaf980ff
+6096ff2ef8ac40cf21fa95d9b51cecc6ff66f5c5fb58ee96d9b11d86edaffea5c0dd6bd0
+fb74f554fe9ccd02ed49e43cc7a0e73ad965afd774ff56faa6ec4dd915d8b637be77f693
+fa139ffdc2029fde15d856cd11ed84fbc34a83fa95fe80d686eb2faff46bfbbf93f15fff
+2899dc08b6f824ef93e581c796f14ef937ffc493e385d693e079e731cbb488e475ef90fa
+50d80fde78b7e641d2bd5a89fbd267c7e57aceed64e036d01fb1e586ed9efebe79ed6bd0
+ff863aa5d849af37d8af06ff75d9fb9b2cc858f914feac3ecaa5e56cee79ffbf8ad0a9ed
+20c5a5fbbb36edb626d97ae068f599fe7ae48ff1d60ee05fbfed4186ffd070fb88f679ff
+add05dedafe034db50e53dff54c0fe7be6a51efe46e4a9bff27ac8ec88d855dd34baea0d
+d0a8bfeaaf03fb5ff767fd3cc9b9a8f84aff13d93ed39be46dedaffe26c7a4f22bf8d89f
+3cfeaf33fe9b1afe86b6eafdc979d901d85be0b00efb3fa0deb3f079fec7f379fece51ec
+bf60d3fb8ae094d87ce099ed0cd6b71dafd861fb10f766fe5cf20dcaff79f7c687fe1eb5
+c92faeee1cfb4a9cffc2abff79d8f1bd51ebafdb36e0a130fcb80dff8cf5a9cb79ed8ab4
+e05dcd2adac49dbccc16e652fba54dfe6dfcc2a5fe74f761ff2186df9cd0b72eebbba4ff
+07ed8adb82f3a4b8fe01aeffc14a9eef7aff86de9711c2e081ccf45ed9bf52c3f66a9d44
+fa59ff72f333ffd996c1f85efc21e0950fa3dc619cf89339ffb854f124ff4ff228ff86f8
+5fffc5f72aeda3d893cbacd893e56195e44fa1ee61ceff79f9d051dda5bfea863bdc23e4
+a52f93fb9b26c0ff7fcaf377dba1d84cc609ffb61dc9fb12f293ff80fa69f67ffe89d82e
+e0bf1de19f04f352d79edc8ecbf441fe4bf0a5cc14f268d85cfb25bfcd65e07aedcb2c88
+f5d85fe00ccd68fcafff4df10da5e27ceda5dd0ad8eeafd095c3e8a4d387bb4ce904da93
+cd6af7b6ff26edc017c5e5a80ae672d683cb90d8b843afdd924a94dbb53fff50f327ff4a
+affad31accfe11dcad46edb770ffc461fe08cdfb93f85bb9f4ca3fd8f79450e604bee540
+fe6bfa93f17ad8f9659fd875d848e40fe034d85ff3a5ff85f7b47beecb71e01ced39fa54
+afd97ae089ff53e584dc98e57caffe4cf726ff5786f9d89517fbbca0edb539e47dd993ff
+be43ff2af989ff7a2ff517fe3cb61ffe61f5cc7bf1c043ffbe30e55bd77affa5f26dd0f4
+86da9ef709fe61f39afb22f2cafe62fb86c2e571e089c5ed2ba6fb86b8e775f389d007e5
+af2bf37cd9a264ed7bccfe0889ffa51bedd386fe9b62f286cb23de5ae84196d0f53cffaf
+f4a3ce86fd9fda01cb5ad961cfff4ca8fa92ff7fb6d186ff14f5c124d896c1fa3bff1bbc
+ed79e587d0a2bfe0a543ffadcb3bfe55f5c263fa22d652ea95c9add146c1e5d874debf90
+fbc693e4109fff5fa5e57dddaf83fb93df32d84ffe36a4ff3aec5ae0a7dd12e080d8b784
+08e9aedd159dfdaf06fb80c1e051da3c97fb2ed89afc5cdb94bfe33effc017d94595e5d8
+4bcefe6cb8ed43d9c418bcea9fb9fba5c0ff24b5ed8805c762ffb64aec79ee93fa22ed99
+0fc1de35d864c8fb06e596d8b36dfe61f71eadd98ccbfe44d80fb6fb3df21dfdc767e581
+dc93d818e09cbfed86dd6ffb13f27afea16191fea854ed66dd41c2fad82db9fe19f24bfe
+c402ef60f986e07fc1e369c793febc65c5fcbf52ff3bf6c69737f5bad931c0dda546ff91
+f47dffc459beff25aaed86ff58abf57ee6a6feb7ed60aff269afe22ab0f96fffa4f74dff
+38ce13dd62e055c2d9fb93db26f1c296ff42e076d786fbaff579ff9ced4393f2bf4efe34
+eea2becf86fe5af362a5de93ffc66ad993d87ab7f304fe61f77bff5dfb32b6fe05f09eda
+60e024b9f8d837e0c40bf77effa24b86edcf84d89dd579e191bfd09fed10b6fb20b2fa1b
+cf2fed93459eeac2a5d36dffd87f50f994ff6df2b3d816beed04e19fed79c2f841d512ed
+cb25d854f23586c5ff2cc4fa0bc5ff7dc0e030d87cd193f082fe93f7affe8432be4af8b0
+5ae11eb8d1a5fe3ddf50d829e2bf16affed967a9ed7cb7d308e94ae4b1d00dc0f925f14d
+a5f407ff52ed35d0b188ed21cba9d393e75acba5c642afff91c8ed047df35eff9ab8d023
+f1b6fba652f76afb20f43cff4efb29adfecb5eedd879e59ff979ffaff1861bfb58e523a4
+fec286e151d623e886fe6ca4d866fe17b2de6ad980faa46dfe96dd88d2f911abdd80bde7
+8b4ced0ea5f46afb07d95be0c147cd0c9bf1adffd872cafe6df586f910b9f29fff6bf0ac
+57f8c5872cd0ff18cbfa79fb92ff9f39fb9ae87bd886ccea7ed587de9ffe70fac451bae5
+43f208aff27cff67facf2ee44ca7ffddafd487ea50e5af61e014caec08e094ccbca5d8b7
+94c3dc4893f3ac43ffbf6ad9b603d834fed093db88f1cb43ec0eaff47bfe5fce35c3fb3f
+f281cbf633feafe951c7e04bec05ff4dbe8fef79ff579ffbd086fdc954ddb6ee86ff2ca7
+e97deed25ee41998ed0aa5ddbf2ec4ea6cc31ab7cf81fe93d860ddf79e5be0a43be055d8
+29c7ed79dc31ff64fbb230fc47f7af11c0e02fd99bff78fb9ec0fe40d928e0b984f388fb
+cc539f12fb34bffa79fec196ff6793ffaf3efe5af10ef65cff79f8d107df96cc11ed3dcd
+f37ee3bb4ef506fb51adde89ffcd34ddc199f8a5eb79dfa6d85393e3c0019eff1faef782
+b6c99cd9fe41e01dd6f22fa8df3a94ff9841a5e068bdfb6effa528fb93c0fa86d3fc4592
+ff9e4bffd993ed3adc03e731ffaf0cc1ef7fffba84f3a5f97cb6ff51ca9fe10bdd98bfe0
+6ccef160a5f781f20eb3cc69db84d193f7a51ae557d90f93edfecb8defa50ad82eed47af
+e6c75adcc27ce48bd887e01eedaf6cff87f65ffeb1fa5ba5fd60a0e779b7c885fe13ef4a
+9cfa9305e34edc1bffc026fab9ff4786fbd079f0c52dd8fb72f415b1cf86fbaf65c1fe7a
+f6cc1fedbbfe26c7f201d83ddcb0c739de52e55e9bf2d061e5d38733fa79ff86f4b1c677
+ed95fe44d920ecca10d851df05c6a8ed5baff383ff17a5fe3895ffd31be15bc2eb38e424
+ed60e079cdfe6cffaabff62dba47e060cdfe86db91d8f936a3f225fab317ff45fb66cebe
+32e6c428aadd9f2593e0c117c4ff2bd4ff3aedafd476bfe562b9fcaeff93d16191ed9909
+d3afeea952dd9961fea539e05aed69fab850dd9be317d94aafe080d87af69f79e588f86a
+ff82f399ff25c3ec18a6fb05a9f7afc0e053d79f5afbd44de086cea5f95e9aff87fb93f4
+60f81afdcd41d861edca86ebc14886fcbfa5fb72ff7cf7a9ff12fb4b9eddc338e079d999
+f280ff3cb3f24dff1a86cbfd79e066d9c09ee9b9a5f27bfeb85afbd53feab7ff4bf095dc
+6dedaf86d99a5ff9a1ff1ed0ee8431c957f5befb4ac3fe79dc2fc9f50dffce7ce4b986ff
+9fd829c7f503ff5bf4c493fb61ff14e64cd9ff56caafe016d862d97cb6fe77bfe086c9ed
+55dd0ba2f324fec217a7faaf1efd63c7b0e545ed34ce76e086d9be7bff93f6b851d922fb
+afee974edd29d892d5b844b6d88ec6f10195f886ff5efd16d0a1ec6ac4df6ed0eeb006d1
+9fff2ef251c933ff05d94d93eebf6eff7af285d874fb36f9ba5af61bfecb26d858f3b14b
+d8f786eb9f0ed896e535f38aff7093e5ba46f40ffccc23db7aff966aed92d5b068e405d9
+a5f293d0b41db8fb2d9ff494fe04f6d833b2f839fe4f96ff7afbcd6bd974e58af33ac0eb
+93f12eff86d7be9bfeb62bffac46e81fdf359dfe7be361d809c4ff81f859f307fe98f55b
+ed31adfebf49ed1ec571b8e523c1fb039bf8a55aff94f44bafde88fe92dd7ee5acf3c615
+9de50ada42cb0ee5bf9fcf08e07addbe6df27ae4c181ffbe11e039ffb869ff7acb5ce01a
+d5fb5b9fde88d8a56bf892e952e2d0b348f92bffb3f1b750c634fe5ff3d779edcf45e05a
+ccaf6cedd065d97cebc62bd8ae3fffb0ee45b7d982ff58de7bd9ab01f350dc12f2cb65ed
+96c4fa70bee802f2c09eff8ce03beda6c99ce862dd26d886fbcc6dde93d1a7eaaffa85fe
+7694e1be31c3e524d887c0ed73d00dea62f9c12686fbaffe86d0a5f58cfeaf48ff6bf293
+fdab4fe692ffa502de3c9ffbadd175dbf028b6ec9abff8af3ac2f226fe5fefbf4aca0afa
+b725fea5c2df9f4385fe90f9bf96e1873effb668fa90bff03bff9f11ffaff419b4e482ec
+94c71c93f8cc08e5a0d00efb66f7c493fda5ea6fafd809fe51a0d9ff5bceaf43ed30f562
+b8cf13ff46b1d886ff77e59b4df428ff65fb52df39d949c6f65aff86fb79b6f739fe15fb
+5ef4aed23897fed54bdd31f15ffc64d82ded93c5e052d726c7fb0bd841cafe78f6d6885c
+fdbf43a8cff90dff4286eea3ff6dce97e71effa5f29bc67eed61e61388fab9e51cd843ed
+09affba7c90cddb222fd78e07fc8ed8944cc9efa4afe0ef561fbd8679bffb631fe8ccbb4
+41e629d260baff48f9b681ddc11386b6fb79fe93bed0a4fe75e293c2fd1df1accf0bffaf
+d59fb9e508c179f3be9ce92bd3a4dc42f1ce6de1aadb84d89e4effafed66a3ea91cf7de0
+1de897d974fe18aff786ff9e73ef94f8af4dedb725edc71ef286fe8c55d8a5c5d961e007
+b5ed4cb1d979e036ff5afb93d979ffcd31d867ed9dff6cc3d92ce86ef77aff9ad2bc15fb
+51afd8fb69e579d99cd0afe0ae3bfedb5ced7ec2ed55fec097ff79e51ec2e07bd0f52ffe
+abf8d328e0c30fe44fea1cf2af30ed5fe09e39fab75be216ed4fcba3ffd8a50fff62b2ed
+0cbfe59612fbbe4798f231feca79db1bcbff01f753ffafca7aff52e4c19bdd3bd848ebc9
+5bd82de09acc80fe9e67e4afd804e7aff165fb21fe93c1fa7cfeca3efb8bd0abdf19d63c
+edb584f391ffad5ccba4f776fe54d0a4ed4be43eeaa5d894fe08a5d81effbf2ffc4d87ef
+7fbe28cba6f93fafdd16f051bff288fb9d27ff429cee6ce53c95f452a5f18dfe7ddb68cc
+fb87d97bffc16aecc693fe7dfa89ec256afcc48cc0f979fe5588ffacca64ffd26ae0b512
+fa93f55cbedd85d8a528fabf05f4b432fa69ffa5f3b520ff79fc89f314dd48d8ff933bfb
+be61ff30e27eedae53d937dd1294e5af01ee63bff386ffc007e053d910d0fb24dd3ae094
+bfff1fb9d893fe85f732ee82bff988ee52a5e18dc9ff02d1f287e714d995ff81d68ee0a8
+0ada4cedcf92eac75bd888c7ed77d8ff64c934d6afff4abcf603d14cdfaf1cf942add830
+db5df7dd39ed4de020d991d0eb3fd92bedb702f8c586edbb3db6e1944afd3aeeb868ed9f
+d05af18fecc402ce63e496ddc352bdff6bf7b607edcd7bdfa5c893d0b944c3ff86f6a0bf
+ff71f2c193fe329ed84aa5f596fd7cf651bef080feaf16f286e061f305c753c4b1cb3dda
+59e074c8f760f025a5e59a45ff94fb62d025f45aff33fac19ffeb576fb04a7e01dffaf06
+fcb422b7fb87f70695e570a8eb8ff281fec075c4ef68fe83d087afca96f5a5ff60ee25b4
+f780fe9979dda027fc53d9a5fe22f8aec4e579fece45ff84dabf13b75efe7bf586fa10a3
+f130d0a5c57efaa55afe19f34efa14ff9ce517edb241e057d12afb4cccaff76ffbcb79dd
+32c89eea78b5cf47c2e6aa4cc5fe7ab5fa9fff17f587ffb828fdb711db81fbbc53f9d9c0
+5ac7a5ebb47ae099d883e367c934e45cbff17af74de59fcd59edd346ecadc1dd27fec757
+ff17d933edbbff0ee5a5f205ff52fe16d876cca8c1fe6cc0e258cdfa44ffc17ae686ee70
+d962ec179bd80c95e3af1efba5ffd995c0e035d955c0fe79e55aec1ee04dc9e68ad879e0
+9feb6ef488d979c7fe80f991da98e46bed0fddbc22ff58b6fe1eafff01f588ff69d4fa9a
+2bc0e938e262eb97c661f1a3d085ff96d86aecce862daaf00bff3bf2c205f752fe1cf393
+ff85d8fa54d2a1c66dff86fa9977dd9b5aff81ee9f3ce094cca5e3934597d8b646b8e094
+ed7ee45bfb04f3479edd0aabf31eb8ed80e4af3aff0ed19eff8ac0fe62f9c66cf0d8873e
+c64df824a5ffbfa9e03ad9b6ff82f490ffaf24f745fdbb30c1dc02d451f220a6d80bea52
+ff18d884ffa562ea8bcfed80e4d361e195dc22ed9310e5aeff79d287d9af2cfed502e54f
+dd37e848fe129fffb6fc7ae286d96cfe93bbcfa4dd5ed812edaf2cb5fe24f3b63ce019bd
+ff12facb1ed866c5f47dfb64f96ffbb5f62efe7bfb35c71ef9adc798e080d2f960ffcb73
+dfa551d81cf5c599bffb2cc64cf242e0a134ff509ff5dd80e579d0ed8618fb77f7980aa6
+d861da38ed97c6a6ce85ff6aa9fc93ff85cefb65f3afca7fed9ed92ec8f23adc9b0df947
+93fbc159bff85ecbff80d94af20bfc46f8c157adf692fe7bf4abcb78c0f241de1fd54ff6
+9ecb47e730ed4bb1fb86f5c26effcb7dd987d6f866c7f26ae5b986f5a1fc0bacdb27d84a
+d007dd79ec93d287e4b39ecf2aff43afff2e93eda04efb87ffc493fe78d966ed79b9f693
+d7b679f3d37fe6c829adfb0afea03ec2e191d05de8c6f830fe9ecc79ff5aee0cdd4bedca
+5fdf2ce89f3ee09733fdb640f956fc87b7fa6dfec4a5bff22ca0ff38a5dab041ed6cd788
+e09ccf71ed93e069d927ccb806eda3e07dd893ed88ddb018feb8a0fa7affc937dba542e5
+9e0ff050ff0da4ec964ad8a52eed41d95fcfff6cf1a4f486ff9fcb55db13f24affdd79ec
+8ff0d67addbe14c1e730d90ce037bfe509ff3fafe360dd04ffcc21b6fa0e89fecb72da88
+f1b0ff66f325ffaa4193e0af0ffbb719dd6dfeb4fa991df8aecb73fec37affd766e5c686
+e079e604d1b243ec60e079d7ed7bcefd06f29fc0f92ffead26ffb912fb40ffbfa5fb70ff
+5dfa2aff58f562ff31fbd169e022cdbf0f9af879febc63f2cf89dd79bcfb32d0fe85fbca
+7aff92f39a39bdc913bfe660ef20ff77faa1d96c3afec260bc1af765fea9f479d06cf1ad
+f7985bf2a3c1fa15ffa7ef6cacfc68d9afeda545eb63d456dc0ed895d885efb7fe78caed
+69d1f286d8a02982d5e58746f6bb06f1b522bef707a6ff1eccacff67e3c093ff21fba810
+de4e97e577fe1db6e066cbed7adda7c1dd8715eb4de093bed392bbc909cfa9c557aff385
+ff53eeafdf60d802d1fc3bb8fe39f4cb81deab01e643afe059d521e0b1fb7cfead38d994
+d88fe2b05ac0f7e59307d9fe95c3e03cd95dff93fbc24f86ffafcd6be080d99434bed83a
+debf49ff30bff686ff24fb94f861fe44e402da52f328bef943b0fe3af6b7f14dbeffd869
+e4af5cd8fa6d95d9f161b7ed3f9cf11bfe35afd956c7fe85fac75ed893dd7cc1fb4ea5f6
+5bfe2a99f2ce7af3c43ce61bf068f8a5fb79e88dde03d895e080fe32f286e58eafe168ae
+d89325fe51f2c16abffe11f7a5fe7bed53e02dd0fd81f75cfb2ad8ff0ba74eb8fba338ed
+50a5f281d81fe03b9eedd729dc47fe23f452c3fe81f7b179f29dcf86e016d996e0ae3fc1
+eda4ca7aff8bd293de74a3e77cc0e065db8afb9f0eb4fe3cd1fe9837edc24792d0fe59f8
+c77bd972ccf386f77ab6ec2ab0ff26f750ff0fafe5c708d86ecffa44afff1f98f981feb2
+dc35e04dee1cff95fd61f72ad65ac6a5ff48ee23c5f918ffb7e679d88effa5f07fdb88c7
+62d908d69ceb944bc701eaaac9689aedcbffd870f2c07cffd002feb6ef85ccfe17b1f37c
+e887b5d09fed62e01ecbfe08db56f999fe77cd5bf3c784bc2ceab64ef11ffb5cffc433fb
+04adff18d839cfed79c5ed8714c0e186ffaffa2d95ddbc27fb93eea14ad513e53cd09ef2
+7ed286edc598f34090ff94ef80b6e66bd8b9dd5cd9a54994ff81c79ed8be2face57bb5fb
+94ed1dceb67bff81beed885ac2f70de33bd823d251ee2efaa4ff86f66cffb4faa5c551fe
+aff532869f19dd59e5b22c93e6a55297fa68bae868befb03c0ff4bfa09d1a8ff5ea2e584
+edc138b1ed04fe89ec1bd8ff7bf6ce6ce4add908e095c6ea70c2ee73ff5c9afb249ff4ac
+ff4ad819da5acbee13a1eb5bd80afcb0ff94c1ff67dd0ae062d9a735fb81d6f152e43aff
+0ec3fc3387ffc60cfdb8ed13b6fe42f95df4d83ed0f208cb88fe61f6d856e536abd8fb40
+b0ca62fa7ffb93ff9ecf87d85dca3cd80fdf61ed82e01dd961d0f2c1f881fd0dd7fbbf4a
+f9c8e411da48a4ff32c8a6f179e586b6ea4693edc04eff1b93fbd160dab932b5fd9d4ac8
+12abfa984abbf588ff59b7fa44afe093f3c250bfe055d879ec69fb7ef2a567fbd588ff84
+e26bdd32ed5fb5f093fbaffe17e5b962e223b7c6a4d388e0629ef1c14aa0ec68de76d0f1
+79e586afc677ffa76ab7ff4cc1e09607fbbf95ec0a9eef83ffbaa0eb4be009dd53e819ee
+8efe79f29bcc29ff78f390ffaf43e85fd0acec8754f1d98f2fbeff7af6cf8bdd75e03fd8
+2dc9ff7af6cb28fb95d0afe549a4ff80f2a3dc5ae5affb93df32d6ff85ca3caff026cf9f
+fe0cd52fdea8ff7afb2af7c494bfe50bffc6aa4de52fcba8f951ca9cfa20c04cc9379eee
+5affcc92fa6dfe15f7b547f9cb01eaaefb7bd230f6af38d905ccff14edc125edd883f29f
+33efaccb6bf779ffcc65d930f314c8b7a9f782fd79ffafe126d8af3ffb9fd5b647e00fdd
+8826bbff3e98feb88418c4fe9d40e5b708fa5afe92f796fcad50e00eb3d865ea32dd7df1
+c627d853ff71f909d85fed75febe1aed62fdd885e27edd79d986fe61f203d092d9af0cff
+449fde913dd8fe79b7ed1dc5a5fe75cfa5d9ff86f4d078d9a502ed48da86d869caeda579
+ff86d822f297ffbf5aff9df7b652dcaa5efbaf3ae013ddb977ff3bde1cdbb628fd87e579
+d986ed69cbba31d1be459ff986ffc087ee09fac883f096fea1ed6bc3de1fd2ffacf251ed
+afc988ec80d819cc5bd613ed8bbffe71f9bd9efe5cfb0ab0f493e417cbaff281ff23d0b2
+6ae07bd8a511fa50ff1df252e8a5cd93eb6de35ce986d2afed62cffc9702c1f77dfe87ef
+04e54af37a08e058befb44f7bf9bfea8f436ff9628fed837e361da55e00989e5c26bd488
+ef81fa99d179ff9ff967fcd753e986fec160e751d0a8ff47f927ff40f2a3fb72f5c561e5
+1ddd4ec2e49458fcac3dccfb03b1f87af09345e06fd98afb22ff6ddca5f095ff83f5a5d8
+27daaf42f015c7a9cc9ae16bfe7ab7ed884edec19fe647f39ffe37f7c09acca7c781fbc0
+20ff43b5f92ffe9ff550fe26f8b531f2afe043d85ad86bdd86ff8ce8c1a4fe2895d885df
+5bca1cafec86e1c065baf59cfeaffb6fcbf2a121fa49fe1ad941e00deac471becc24aff4
+a6d04798fac59fed1bc0df93d797d886e003b0d913d897f67bfea55fffd02dd8f65c7fd6
+e52fd962fabf9ffe04d360d854f335fe4dd831dfc23cfeb65fffce89dd74f239ff4cd82a
+c9fb3bd2ff9438f886ffcb0cafdd5dec2ef460edbe3a95f0c3a4dc83d8b81cb6d97bddc3
+6ed95cea89ffaff62cffafc61dd041fa62cdaff219ff3af68bffd04cd805fbaf45ce14c6
+3c94eda93efbd879e0c1a5bfff6dfbb327f543fe87e09211fbaff08805fe6ff79b5bfe7b
+f618fe5ec2ff6ab6ff52b9d331bff21ab6ed75b2e1fe4a8affa4cc11ea38c2e77fed87e0
+a0c685e57af2b375e37dcfee8605f74bff93d77cf59eee5196e5a507edadd816b88ec1ed
+87d57cfe93e401feaee2864cf610ff61f395fc38eeac0ffb84ffa63ac91294e79f42fb9d
+f1bd94ed38dc65e0afce7aed619fe57bed6ddcff86f27af9d017ffbf59afed9333f35496
+edc859d997e5abef4effc960d830e0bfabdd39b8ed07cd61e1c0a6e94ff2ca79e005ed89
+dc7ae069c2ff15becbaaedc057feb583ff79b5f930ffaa0fedb722fbbf01ff52f91894e0
+c2aae6b121edb714df87ffc060fabf79fe69c5f25ffb45ff21d9b54bb8d961d818fed06a
+e0afc946e587cb5aff96c0e019cffa7df2d661cbf379e45efe11b5ff88fa9d54febd0bc1
+fa25ff99c71ea5d84fe0b688d97ee499fe0fceff87e7c32887b7ff62ce047fd8b67aed93
+ff7bf958c3ffd06ddc8ff39e42fb23dc9a3afaa5fe9efb41f7a5fe44a9e06b34fc0f95e4
+2af3d14cdf25ceaf64d9fa6affd49d5dea86d899c8fb57fe3787d0fb6dc7fe62d80eddb4
+28f1d939b3fb32e597d079e96af2a5ff88f27ce7b988fa9934fea5d105f4b880ec4c9ff1
+79bee348b6fb0eb0da27b6d88fde79d807c7f22ed9a5e080d9af4ef2b2f979ffc128fe52
+f72bd161f2b74cdd07feacf6d819ec93ffbff71efe43df16cf3de48a24a5fb4bff2ebfed
+92d883ecafd12ac55fceaec70bd89bf985f3d977d0fa79db5b9bf786fb70f2bf3bb6ca40
+8ae5c3a5f62bf04ba5dd7bd8fa5fa5dc529fed83f86cffd08955c2eb7bdca804fabd9ffd
+0ae03bd127ffa748ed1ebee57ff271ff8de21fc4fbd853fe25aeff76d993ed6effc968f3
+30f851fcaf61e579ff58ee40cdfe68d833e00ca3ed73e5bf93eba5c76dfb80d168db4c93
+fbaf51d8329ce583cfaffb85f295fdb6ee79e5c1abd976ff61f816ff70f386f121ff66ef
+79e726dc5686f5bb4cedafc3ed1bcaabe006d7fe7af4aff81dff49b0de87ffc026f2af1a
+c0f601ffbf36cda5eb459af7abff1cd84cffc95bdf2cbfce96fb72dd5bc7fb79ccff64d8
+28e0c046c6fe9336b9e885dd67d1be34fe53d8a33cfe9fe6a6cf79ea97bcf31bc6b2fb94
+11e682f192c8fd44d8a903fb4bff1eefb4e52cf27dffc23ec0f38afbc34abef2599fd85e
+d60ed936d89810fe51e509c6a5cc94e357d893d980e03affc293c5ffdf219dff9309ff86
+befe4393ff9c4fdb09d860d97bccfd5bd209edb669ff9ded88e580f1abfe1ec6afdd03e0
+7cee87e071b7f593ff64f143afed92f79e06dfaf3eefa1fb5c93eda566efd98705f9b0f4
+08f8a5c3e618f2b0d256c517feb722ff47ce9ffd3389e3bfa9fb49d85a97ec83ffc49ce0
+85d8a4389bfebbd811e49fdf09d465eda5fe0bb9f62cff7df587ff65f9cb83f289b6ef45
+fe30c0ff0cfa4bf598d3b249fa01ae66c4e03ccde5a740e961d8ef66bbe684ed93fea4ed
+1193ec98d97bfbca4ed831d34ecc28d95de085fb69fe5ccd3efcaff816d84cade57efeca
+16d840cef381fe94c914aecffe11f6b72ec0ffabcd3d98e486dc6098fd77e201ed93dd83
+edca7fe186dd6bf1d05fff26caa3ffbafa22dd51da39aff666feb9d98647a5f573fe6af9
+7fff21dd61cae86dddaaed49c5a8ed40a1de35d0fe6ae080dda562eda0ceb818fb86edbe
+9ff1b6fe75f8b763fbd48afab915cdfb29ffac45c929aefabf38ff51e336a2e57efe79f7
+97ff8dfa77f026d2bd93e7a6c7289beb85f2cb0edcb379f985ffbc61db23e661ffd943ba
+df58d4fb9c5ef27afdc250ff22fabf48cf93fa7aff5df73ba9f50dfe42ebac03f580d96e
+ed0887d2a5c0f879fecb19de4af105ebb0e083cd35dab6e154d086edaf3efbbd04cd9fe5
+1ccaafff77f7af1ed8adf451fbb3c62eff73edc028d754fe37e80dafd825ed9e14e2349b
+f3ae5ddd6fd0f66bffce6de0b586ed79c7fe13f1a7e00cd656e215b6cb99ff4bf312fa83
+feda51ff3093fec42aed4be5b00ffba5d19cf2b683f89b77ff931ae5d042d926deb682eb
+7beea5ff33afdb2dcc9cbfe06bd8a5c97bffbfa1e551fec0aff342e77b0cedb77dea93d0
+6dff8cf822ff58faa52995f19ef934ff9ac886ff7bfa6dfe5cd902e1c264bdfa2798d810
+e886df90d95aa5ff93e58dcb87f3cf6bff5ac7fe79cbff52e593c0f910bdec9c4ef321fc
+c019fab588d9b946b6fd6bf3a0c1ff37ed88d8b89dd842bb8ad0a5c1e74999fbc0a5d56c
+edc338ff53c732dd01edcb3bd8fab67ded88ff6af4c943d80ee08ac4f671bafe06fb51ff
+8ef92cda50e031c2f09a36e06afc92ffafc92eff59fb86d8b544bed993d686efc6ff15d9
+66d779e322db51e02dd186f290fb9e4cffd96ec9ff7ada71fe55f704feca61db10fb4fff
+9541e084ddaf4bf2b685d81efe3a9fe09038c1e195d87adda3cf2df664ff95de86d8af3f
+ec70dab10ef960ff79f6d906f261fa78b9de8655ff1cfab87ee38df593fb7bffb064f3be
+8647fe0dc7afe013a9fe86f7bf5be51cb4ef6ad986d824cb59ee95fb88f89317d6ff84cf
+1fd854e086d999dc12ed2ee4a2fe61ed18e04aaf6de681fe0ff2a5fe6bf3c0a5ecb53cde
+29c7ea9315f3b646edaff23bc5a2e5b635f884f17ad81ec3eda9f72cfd97d702e761eda5
+c4f179ffaffb03ff57f53cff61e083d805eb3af820ffc493fb4ef285bfd42eeab26dffaf
+e020ceff03f6d092d99f30f24cd90aea4abed02be09f0df6c2daa5fb4e93fbcf60d9a043
+fb7cffd54de5a1f261e89edf79d40fd84ccbfba95aed94e59ff139fe5ef677c79efc61f2
+0ac9aeff6ffac5fd42cbace0b849b5d89641fb18ffbe7aeda542fbaccc83fb9924caa8eb
+79cc69edafd045d9b9affb8708c8b768ed6ffba2ffbc7afb58d225d886d07eeab0c693ed
+affe54f4accb81dc6de00abcd09efe3df0a1cb23e5c34393efab5aecb635f350fec0a6ff
+78b8cca5fe6af579feacd68959f079e9c13b9ef323ffc2afdd3d9afac532affe81fa19ff
+a5f37fffa464e8be06ff5ff776cdabed25beff4fafdd7cb6f73f97dca1018eb8f45a88ff
+93f708ffcb91d97bcefa5bffd079dd59e208d1ff61f615ff3dfa9c1affa5fa66e24ad3ff
+81f3d81db5c645ce30dd0bd993f869f046dba510fe50ca0d9edd935dffbe48fbaff062e5
+23c5e487ff67fd5a87fbd671fe9fcb6be085dd7aeb1ec9aaed5cde25e595d94cec36ffba
+1ad82bffafe587d85ce40694f2c01391fdbf09cb5cd8bd3cc2ec20e4b83ffad97cc81ab9
+fb0dc6a5df81e8cc37ffd469ebcb2df3b4edd81cfbcf20dd6deba95ee564f1119bd80dba
+f533ffafed54b9de91d887d977e0c287e62bc17ef5b757da3ba5ffdb7ef092f79bfe73eb
+3ddeaffe62face80f186fad12efbc219eda5d02e95ff7dfa58b618d994cfaaedbe17d93d
+df1fffa5fb08d366fd5ff728ff86f9c21abffb93df67cbfe8ff285db02fb6df584fecf5a
+ffade64add87edabf778fb55afd87affcd872ebffb9fdc86e16cfe3ef80296ed9326fbbf
+85e57cfe5b86e4be79f0a2d446c0f725fea0c1e585ee6aa4e09468c1fa9f29fb49f2affe
+2ff05ecc9fffdd149fee78fbca8750fa17d855e149ccb3ff9b16bee63497d925e0bc75ed
+6be5b578f67cfec342b9d693edc151f608fa339dff80f893f1be46c3ed87d993e08cd998
+d859a4ff6dc808b6fa9746e061d071eda5cb2edda526e185d86ef198ff42e429b8d093fe
+61f20c96ecacde4ced35ff4def94d3a7c0ff4bbbe09d0eff4ecf39c0ff9b51fbb639fe8c
+df82d8b131f84bff3ac2fe06d3f73088e6cf7de0a409bed593fe03ec436ec0fe28e3a60d
+f4d299e07cffc088f21f87d6f26cc8aef369feb140ffadd93bffcd08e05beda1f501ff6b
+fba4e0b47addc462ebaf5ecc7afa9852ff3af214d250ed10daf03ab2e59fed2fe7afc0f7
+38febf51ffb64cf2c763ed34fbc222d0a5c796ff01e031ddaec1fd5af58afe7ed093d8af
+29f25bdb7ad0fb74f1afd893edaad922e8ce05de86bef213ff51e487d5a9cb95da79f251
+a5d8ff0eacff58c5fb61f63eb9d894f9a8e088d07bffc1912bfe41eeaf07faa2bffd43a5
+fb1dff4de4c179e9c40f99f35a9dfb86d81ed964e0afdd31d860c9fe3ee5b60bd8ff14ed
+2dbae5aecba1fe85fa7effb878c4f352ff79d75cff06a2d99520e57ad7fa79b7fb94ccb5
+68fe7af265ec72f0bbf69b4bdf28d8b408b7d91ff963ffbd73fe14eda01ed955fe62f615
+fc71faa567ffaeed2bccaf6bedb9ff50fb19f35fe386c4fe6393f0c739e585d893b6dd86
+fb59cbff21f751d936f1b8d96fceb968e5c653dd78eaca86d88dd99802f9b762fbcf86df
+c036f1a5ff7efac14c90f37dff1e99f286fec154aedc86d7fb890ce34bafe638afce31ad
+fe84d025dd87ef7fccfb76f2acc5f10aa0ea16d850ff0bd99fe50ffe3adba84587ccff79
+f76bff9fe570edacde07e6cb86e064f9c587e527caa5c693e054c8f1934dc4fe5cfad8a0
+047be093e9aefc2db8ea21bfdc5c9df575fe1df24eff12acee2f95d86bedafe5865efb96
+f525feaf79ff2bf6b609e551ed32ffa9d228eda54bfe20edaacb50bee63895fed014e4b7
+efd14ed829eda1f76dfea55ad0ff74f9d768cbf36afbd803dc62f7affe18d9af2ce552ff
+5f93fed061ffafef91bef946b0d893d382fab6fe1fb7e9a1cf48f13affc14391f79c46fb
+afce41b1ff6cb7ef4dff34aff38d30d9f9789de0943bfdb4f6c028d14cc99fff6baff738
+fecd18ddc197d8be9ac5dc79e45baefebf069fffc314ea59bed835edc49ad05aff7afcaf
+cc64e57cfe6ac8f27bd387fe6df911accaec24a7fb965286b0fb75f661e037d923c8f43b
+beed951cfebb08e0bf7bec8ae59b3ebfe354ed99cabd12e0c14391e4993fce2ce278c8fc
+5ef767e917d861e15cc610edb686d86698fbd85dc7f3a32cff97f109ccfb7bdd86ecce0d
+ffd4a41aecbc0cf5c086d849a5ff8bf176d90cedd07be5b862eda54aff36f36afd4cf8bc
+fbda3b93fad543e0abcaa3ff85faab16fb73ee93db9e22f9b842f294d9379fdb60e017d8
+93d3ff5388f7bf49d9c5ff02c0e493cd82ff99f2b480e09f29c2e06f9eff9342f951ff21
+c2fb60a3ff81f66bfdb477f8adfb21bef76affabf41d95e026c59fff86f296f989fe7aca
+fc1df3c415bbff3588d6ee69e07dddad44d706f9b679e5ba4afec259ffd078dd27fec5ec
+57dd15fe87f9a64eff01a0fb80f8b87ae288e025afcf0ba579d2ea5791f673fe4af001d5
+6de093c1e00fd639f5c679ebd8ad1bffb0f706ffaff17ae55e9ff2ce3ce09efe3493e09f
+42ff06edaf49d110ff50f7b6fc45f5c52eedaed19ec9a7ed7df2ce39d80fd93fd0ed30da
+79cbec86df9c4cd0afff51d8fb38afd905d038d956e031afdf78e5b179dbafe610b8c823
+fd53f787ffa1c94ffe389ded7de1b38e3ffb93f09f1184fbafcd61e53dbfd992e0c146d8
+26e6c306fa5fc0ff80eec8fe1ca6ffbf1bdd93d88cdd5aed39ff4bb5fe6be2af52ff1588
+fbc777d883e0c4439fff26fbc104affe7bee6fc1ed5df9cb7add69d7fb93e979dbc46193
+d87ee9b462fd0df668fe5ada08b9fa86fe9df488afff62eea54ffe0ac1ed81d96dedb379
+bef46afb7effa5f593ff80c0fa46ffcd26fe76f884fea5d093beed2fe26ded86d0f560d8
+28fbc6ed69e55abcf3d99942f4aac793fb2af752f388ffaf6cfba5cf9fed62d8369d6cf2
+cb2fe0b55bf328ff78f786d0aef15ec3f286fe95d0b1ef49a5e62dfb5193ebc068dd87d9
+9ce44cd80db7f52cd5b324fda5f71ebc50c2fa9602fee115ff5bdbc08dd894e01ad68ae9
+79afcb58e362de1bc8b605ffd978b5f635fe02fabf13ffd252dfa4ed4acb19d851ef04a5
+d96da5f08ad75ed938e051e916d29bc0ff1fd9af16ff96ea8601a7d81cceff8833c2e580
+ff1ded6fe082cb98df0bd0ed34dd52fe11e086f5e4c24b97f862fbc781e5b0cd21befe1a
+93e49e2ad903de3fe06cccfe5df2afbffe20f8b63af557ff79f786ffd863afff84edb64b
+c287ffdd9f2ff0c678b9d69af01fff35f44db1eeacff50f82bf0bf26fe82fa7af5cf8a3a
+c3e47bd88fdda560e59b2bebb11cb8da88ed9cdd8dd0fd32f7c856de06fbabf48effa7fa
+60f23e88b7fc66bdcb44affeb6f681fea045e4adff08da5ad6a1ff16b9fe2cadfa7bb6ff
+8bf193c6b3ff5403feafed7ed99c09ffa545fb9bde66b8f83fffcb68faa6f490ff0b93de
+9c0fdc5ad879cced74d61bdda5c82793faca12d961df8ff1d83e80fbb868e5ac29fa55af
+dea5e474beff8437c2df86d86dff95b8d239e04b93f2aafb1aff5af043cff282cafe7af6
+93ff78fb61f427fe5893ed9f1cff94ecb74ac60ec443b6d97efbc7e743d8fa79f2d45bd9
+39dd60c8ef69d877ed95b8f347c9a5dd67edcc41e04fc818d74aeb29a5d9f387d212ff3c
+f4cd79dcc187eb4fedd273ddbe81e0b254c72cb6d8f536c1ff84f3acff06a5fd8af2b238
+edace73e9df17afa39ff16afedcb0ad8ff43f3c592c1fe8648c4fbd027d8f29617fea2e7
+01dd4ded9fc1fcd725d861dfa3c9afff8826fa51b6dd44d833e00aceabc67ae8c349bfe1
+83d06bff93f2a1f686fe27e5a50f93f3a404e0a520f871ffa5f307b2fe25f9bf2efc7de3
+86f23dfdbe79ff9ff996f4afff7bf9cc69bf45e5b893d8b663f931fe10c5ff9f0afea51d
+f232ff86fca4f88661b5ee6fe5c34294e7c32de062cfff5ffb81d8ff4de5a2bed093f969
+a5f284afd086ff49e705d3f1991193faa54affafcb46bafba5f387ff0b86afff7df6c041
+e91f97e4c4aded0dc1fc6df9a2bcff3ffbb60cffa8f963f13ed821dc67d85ae095cf64ff
+b6da6cffc577fec786e1bf2ed193d97adfb052e864d005fb5fd4af11e8af21d95adb37a2
+e05c95e9a8ff72fb4cee21e59ded7de2af3bc0f383cdfb6dd9bbed12e547beffd553d929
+92fbbc4bfe98bbfb0b93e1c218bf8bb8cd0bfe53e037c6fe5ae531ef13b4d96bf9bb79ff
+b5ed6ec9e567dd7af78acd5dc724aadbee5ab9ed0e9afe69f9cc56fe679fff5ba5e0c34d
+ea73dd84cae561d812daaffe7af3affe34fbaf08edbf3bed52e52a99e9329ef11198fa78
+fe3ff7c162ffc4a5febe95b7ec78dc5bf2ce8ffe7cc3fb0dc0fe1fd031ddc5a5c1ffb14a
+b9d860fa88e562d9459fe8934da0d87bceed8e19f69bfed014f0d36de450cbaff842a5da
+fb30f26de880ed99fbb623d878fec09de47deda440e029d851e004b7fb38ec10d931ff78
+f9d36bbffb3bcfaddd8cd884b7f208c0e080d0f01091f296d515ed4a9bf488fb9b31c2e2
+9f52c0e073ccff6bfab086fe7bcbfb59d1ff52cded4ddfafeb9e0ded9521e14cef38ff1e
+f79efe8845e402b6ee6db0da84ed93f99817f25688d97bfe1cf1a7d123ff93f0c107f6b7
+e33bffaf27fbc97fe062a8e07baff61bff88ed6ad0ff865ce0affe43c7ba07cd61eb94dd
+af50fa3bff21c2fe69f5adfe86ff7bcf9cc0fe84ee95e0b04afe2da7d96dff53f313ff46
+d893fb2ef73c95ffbb2cfe60f8b3ffd225e04dbeec9301ffc61aaeea2ca5da22e0c116d8
+b67feeae6ce0a96cffc31a86cffb7acbfa80d886e0c58cc13bc6b4fb79f5d73ecbf32dff
+4ee06dccff7ed0fb05f5abdf9635fcb659dd29ffb365fe71f2c479e0a04fff02bffa5aff
+38c8b660dc26e09f04c1f7961dd1a5f77aff9ff486ff10f692d8a8ca96e080da9f3bc4da
+5fe922f253a6e343d80cf298c0ed79f9be27e286d07aedb2eb5adaa6c2d96ce5cb80d9a5
+3b87bffe79ccff5bf6d06ced95fc7bf7c779f162fb9cf438de0ac5fb1ff7bf338cd9ff45
+a5e039a1ed17f4b15ad9ff82e524d8bf5093ff9b5ae0a5bf04f642abdd38a0edc44886ff
+d86ac9f87ed86de5cb20da9709fa60edafd894f230cf9ade7efccd85f37cfeafed49caff
+86e028d951dc2ed758cc64e819f35bfb4bf70ebfed9319f7a6d792ffd867fa7cff88dd1b
+d8af02ea98c5fe3df7a51d86ffbf61fe21f44ba8ed20e3b7f25695eda513dd79b5fb44d8
+59d9973eff9ec942d387ff92f34fa5d979e1affabd60d7f669fed976ffbe2bfb9d09ef98
+fa66ffabe01cd8fac061fbd9a2bee779fec02993e8c60cafed9302eaadfb46a5ee81fec0
+a7d31ff840e779db88fa0eee40a5ff56d435d871dfa55aef69fe92f178fb7ef19bfeafcf
+88d8b893ceaaff4dfbb0c964fb49b815ccabc657e575fb68ffc386fb5dafe06cd9b8e09c
+01ee7de086c7ff79fb88fe04e7c434faba87ff2ec1e582ff15edafd002ecace457bfdc67
+ffce89fe04ed4b93f1ae25c9b902afcc67e479ecafd348bbcd0ced87f7b68615ea79c356
+fe23f265e4aff360fb9df73fd9ffc23397d9ff53d131ed48ff93cabda4fe51ec72d88ec6
+e917d988f694ff29f9bf0fd5acc514cbb3e404d8327afb40ff09ed33e07cd686df33ec94
+c3ef9ffe2af7b638f4afca4af236b6de0ac2fc30ff4bf2c396cb41fab609d843cd5cd886
+ffaf68f2cf52df9c0bf1a5cb66fe86f570fe13f1a525e5a234ed5bd886c7fc14dd93f26b
+fdd83cfaa9d052fe88f87af1a1c64dce33ffd489ff98f186d894cf51ff86d93ae05ad0b7
+6191f2c50f86b7fb93bad886ed57fc0bd0b726ff9ff452b4f26fe3b811b5d87ce9a0fb44
+f37fff4ca5ff87f7c19feabb90c5fe61f225f575ffc007fe3de087d97feacea123ed95d7
+a5fe7af6519fed88d372fb30ffa4d673eb93e09ded6cde1dd9c03cadf985f3afc748f9bb
+30e04dd993c579fecc6bfac681dd9aff2ea7e55aff43ebb681f29713ffb732de1bd836fb
+81fe92edaf53f237df0fe54aff0cdeb718b3ffc285fe17fabe4afeabf6cc1bf250fa14ad
+df7de56cf2c85ed723fe86c3fb46fe9ef263fb33cf6de489d993dfc242dd52e01bd268f1
+58a5d88ecf9add5aa5e07bd86fed5bff058ffed960ff16e656d888e5cb64dd14e5afd862
+ed1bfe52f67dff29faaaf574fea0e020d85cfe89e47bdda4c1ffa92afad83bb7f20fb2ff
+25f064d0f779b6d29fc625dd51e5cb85f3c86fffb6e560dc24e464dda4cab465feafc683
+ed7bfba0ed892aedafdd79e6cf79eb5b98e37bd79cc3ff37cd9cff44a3e483e664d908af
+cf84e044dac190ffb71dfe39f923f2a0bff46fff96fa26bff903fb4ffe16bdfa4cf3afff
+1dd0a5c1f14486b6d093bdf42affa520faa2fe8e58f3bb93cfaeddbe16b7d99352c1e50d
+ef8bfd7be737d81bff52fb0a8bedc05b9bea7dd89edf54cb85e0a03ec1fe0ae37aff92fb
+ab4ce85ea1e0934aa5ee79c9aefb07fe27f8d89f5af9d03fd962d85dcef99e4694f3229f
+df2ad4ff41b2fe65ee76b8ec1fc6b0fe04f9bf96fbbb5bed21c0ffad01ed4bde9ecbbd79
+e660fc1594d8af46d9a4e56deca7e06dcbed81d9a430c799f63cdc62bfdffc31fa64c8b5
+6dcfedb348b9f1cd0fff4efb3985fe9ff378d1ff36afd858d142c5a0fa71f0afd282f2ce
+60feb1f707ff46fb72f4a5f90cfeafed83f391ef60d80fc5ff22d8fe04f7bffe10baff48
+9dd886da8a2fefbf1cadffb9f232fdbf07e4b6ff68b9fe58f7b06bedca05d93caffb7ff7
+88ed7ad8a83def2bd2ff88faa55ce593c5f779ff67eea9c793ceb0fe2beec681ff39d8b4
+3eb7f99f41ff10cdfb68e17ab6fd96f80e9dd87fe011fbd93987ff80d928a7e57bd8a8f2
+c42de54ce008c69cfb7dff85d9ff06addb9627edbe43afda1ee088d0abc793e319d862ce
+5dd92cd84ecf31de81ec9d64f1b879b1cc6ad894f286d0f63cf24fffe677fc9beb8a0897
+d9a552ff69d831cbec81dbc40cfbbd7ce588fed00dd94dd827dd5effcb7dde9938e069cc
+f33afe61afd90fe049fa0bff3bec62de86fb0dc1f284fe88d924e5b98ae37cbef10affcb
+29d859c9f34dffaff25d99e9c303bff786fd3dbeed058bdeb568fcb1f97ff15cdd1becae
+65bef43ffec26afe9af57afba840e653f12dc0ff88fb95f27cffaff76dffa6f953fcafcb
+40fbd929ed3de850de1eb6c670cba5c0d93be04ef7b6fe78f5cb83f08efba706f94393e1
+9f30ff51f2be6af4b9ff6efbaff11b9efd6df8aebff60c9dddb7ec2ec0f587d790d99dd8
+87faa94bafe09d4ddd13ed96ff55d4f561ff39aedb51a3ed89ffa878eda03ecbaeff52fb
+9eec42b6d899ff6bcbfa47ffcc9438a1e223ce96f8c131eecd86d87ae9b40fd836e254c3
+ff7cfa98d98651e53bdd1fe0bf0595e4b81bb6d830dd83e39658ffbe9ac4fd6bf97affaa
+fb016ab2ff85d56fde47e320bae516d84fe0c1a2bfff75f4cd86dda52be09636a5e8934d
+c7b6e147d811ed4c86d8ff841da5fd9451ed2efe6cf15de401d8c4f363ffbd79faaf61c6
+ed861dbfd194ea6dc6fa79de25e2c305bfe886e019d179d86fffca5de424ddaf83e08c12
+f3b9fe6db5ff46b88dfcb64bff16fa50caf781ffbf95f21bb5cb10febdf7a5d07afe9e5a
+fbcd44fb9cf27efe6df412f9aad079f30ba6d993ed13e25aedfa22c4f212fe95cf86ff6d
+a9fe94f77dff63ed19d948abeb16ccff57fbb6e012d0f682ff68f3afff92c3fdaf49c3fb
+d36dd8ffa5c682e525ffbf86fe3593d821e7cd33e0c106abfaaffe4bf823feaf13d05ef9
+6bfe93f729fe69f68af22edeaf0bfb7af454fe1eb6efd573dc51d2ed69c4e610d86fe594
+d08ce0a546e8a004df61d4ee6be0ad44c601ffbd4ac3eda878dc85d858e006c9a4d387ed
+19fe5ac1ff32cf58d689d89479da9e60eaae2bfabe3fc4f258d03ad927d893fa7ec1fe88
+f9799fda86f068fea73ed907dda530cc57e229dc7beb9345f708ba60f9da52d0b242eaa0
+bffd78f85fadff7bfc93db36e180dd9cd885f293ffabbfd944dc6fd497d941e0a4fe65ed
+93d2aac798d0a5fb3fa3ff25f7bf03acf579ff9bf224dc55f629ffbe68d8f884fea439ff
+80ed93e5b46ded93f831c8ff14f339ff96bcf74eff39b6e086afdd80e0a1fb76fe30e5ff
+46fbcb7dddb868ef9ee01ddc86edaff25de53bb5e023d85bc6ed01cf31d888cbfb94ed79
+d0fe72f4a3fa93fe13e0afc99ae6c21c89b7f571fbc55bed07b5cb98ed56d929f369ff5c
+c802ef54e435dc4eed1c87f4aefd55f17dffc311b9cd35f84bff14f160d96ae5c985d89e
+63fed834dfaf43c1fe7ceb95d97dcbfb34b6c827ebc15ad621fe5bf4d322da6de39061e0
+c2a1d061e788d8bf93fb47bdf022fa4cf125eac593bfa5e0b818f23effd004eb64fb76ff
+c102a5fe86c9ff6df6a2ff38b1fa80ff5af326b760c0fb2097dfb602c851b7ef80ff5df3
+40ffabfbcb0fdda51fff92d0f545fb16d588eca5b9cd9ff4b686fc79caa5fb95c1e59e17
+bbd808ccb066ed79ffa5c1e26ddf8fff27f8bb0aed5be5afc687fa61d0fa67b5cc01ff5a
+f2189eed6effaf78fb9ef6b786d9379ffbafff0dd1faaf51f91ffeab35fb1def6dcbff6b
+d89dca8cd9ac48f70af06186feabe079b0fd8dd4a5c94294fccf2dde9909e8bb66d895e3
+4bddafe279ebc6ff41a7e7c746ff85f1a6d961d027db86d87ae03195fe83f2ce7ae0589e
+e27cdc6affc34ce519eb42ffc12dbcff0ace3bff5bfac679ff93fb26f897dd4eea1f95fb
+c54fc0e99479fe89fa39ff17da7bec0ba2ef2bfb88c6a4d2afe087d94ce4ba0ad943c9fa
+69ffcb8642bfe9a32fed86d8b679edbf73e5add90298e55bff07f563ffbe9ac633baec93
+57c1f438c252ff12f5afe577baf86cf2aad141ee0ef876fec1199dfc930a9fd8f3845ced
+94d643fb23fe75f4aefb16f061d8ed4ec73baff719fec226ffb9f20c97fb86fe93d868e0
+a4e668f583dd92d82ce0b13ce85fb6d539bffb88d9bf2fafed9d44c4dd52d9a5ce77ee4f
+ff93c2de74e1a7ed32fe3ff74efe10f667cefe84e59715ecb608d8f0934cfec494ff49f5
+cd08ffd69743feaff639d286da7cd81ae453fcd0ff1fcdfb0d96d8f8a1bfe061d81eef4e
+9ed852fe89faacc7a4d02693f5d237dcb5f88717d5feac10e5be9aea86e4a13ab9cf9eff
+b677afff9de85ad586edb1894aa2dfbe32da5dcf79f01afb46d9aeec54f17efe6af6c09e
+c3f283ffa506f255fe87f602feaff411ffbf26f399c0e0aa2ffb41ffbf5cd886dcb67bd8
+93d096ed37a5f257ffaacb81f3a562fbd760f211adde699fe29256f9c765d879edb8fa44
+fea6ee83d88e5d9fe4ac66dbff8426ed4c98ff91fa87caff15e2c027cc7afe53efb0e04c
+bdff5ee044cbfb9935cef763ff36afd909cbff59e544c604fad226de86ff6ddd37d0f6b6
+fe6ff9c878f710feafd193f3b8249dff06c9acdb0eed4cfb17d961e5cc7bdc9de079d886
+d872e0ac7ae74cfb1c88f2cc82d99911fd96f009c8ff24f25bff80bde024d879dd51fe3a
+e4c01cafe180befa27c3fe3eb8ed26a5f22efea51496e0c235bfff24f5edc84cf2d4a544
+c4d988fbcc2bd851dd37b6f360afff5be513dd6aff82fa70a3f07dffbb6dd9ed79b0e08e
+c3fe54f87abff17bfe89eec062ed52d80bf2a2fe7f08d83ee81fafed88dda53dff61c97a
+fbd870b5e54297fe87d87ae59cfe3cb1ff1cd334f04cf92affc058f2c494d0affe55b7f7
+5cedafd644c0fb9351e59fd82eccf96afeafef1ae9afda73ff9bf235cae66fb4ea7fd1fe
+64cbff86d852ddb6f36193fb9a56dd7c0594ff8816fbafe56dec08a6e580feaced7ace96
+ed85d993fb86ca34d907e6cd11d8ac2af257b5ff48cb19e871d794ec1fa5d92ed84b9df8
+82fbb3e5be48b5f1aafb94caa2ff37d851ebc298ed0be4bf47d0f879fbd062e234ffb928
+c4ed5dc1ee80ffa9c79aebb033fbb506fe61e57add04d4b52cf481ffa564dfb979fa75f4
+af03dd9c40c1fb935dc4f62dd879fea003ffd144f81493dca10fe576ee85ff2acef208e6
+c4a5faafda3ce0c280f120ff5cbefe48f2c20d9aff2ffb04d73aed4ab8f39fbff2af55fe
+74ed9ac0fe05c586fbbf9bf52cff5bd0fc85f493ffbb15dda52291fe85da2ae04ced65d9
+7ce693ff70f925b5fe5b93ff9f2dedbc1ef2bfa5cd88f96ca2f7934be2bf6bfb16d162e5
+c56eed86d822edacfb79ffca63d91acff520fecb14dec263ff7ac6f78761d8fe05a5ec8d
+db5bcff39362efa9bfe535fbc1affc1acb5ce67ab2d769ff3ecefe75f79dfe4dbf91cea5
+e079daaf69fad36dddafe575f6c2a8e821fe5086fb93c4e41efa62d893f1b631ed4bafdc
+87dfaf47ca0ee079edcc6cffb8d83eeb99ffbc90c1ff03fa4ecb08bbd891dd81ceed1adf
+c45a93ff9e4efa01e746d7e00fd0faa50add5aed87fe9f1cd9aaf952ffc1479feb50a5fa
+8dee7ab4ec5aadff9941e7b8ed32d9baff3397f1bf50ff17e5ae3ac1e09e58ff79f35ee0
+3f8fb6f99ebffe50f8bd90f06331e9c125d886f5d944fb2ef7bf1aebb740f0c25793ff9f
+1cff83d297e0c317ed40afd086e72ee05efdd86dffcf61fb15f39affbe60f93aafe630f3
+78fac111cd55f21fa8e1bf9ff3a8fe38f54cfb32b6f468fdaedb79ccec85d87bffb87efe
+9a37d8f588ff79ca37f2bcff3b9ce0936df9c517c0db25e056ff36c389e16dd1f2881ba2
+fb9312cdaee049dd86c2ee76f987ff1efbce2ad994d47dfec6e94adf0ad9af3ae413adde
+d3b368ed97ff01afed7bd89d64ffc779fea31decc545bfe06dd960ef3bffa1bdf968ffbe
+52ff9ec90e93e4a103edaac767e273d9a5c798fe52cf96df59acf288fc79d5f7862fdd5b
+e07ae99fd3aee56fccb003ed3ae516abfe30f1af22ed51c0ff6ab6cc40bae693d54d91f1
+d90bf5d336df94ff73fd9abed19fd9fb0bed2cbdfeb2e54dd3f97cf466ffa4fa3fb0d854
+df97d871b9fa87f106ecbe2280ff93f179cdfd6ed8ff7afb0bfeba49c6e579bfff12eec3
+3a96e05dbbf980fea6f286f706fb7ed988e26bd3b30aeda4cf76f8b1fe3bc8fa9340ffb7
+28fa39fe0ae07dd987fe01c9ff63d833dea541c2fe93fb1ab7c65eff1299fa3cfec06bff
+85f6c960ddc16dfbc6a5e586f124fba5f709ff78face67b6cb5cb0fe87f35ae5af4bf702
+fe4684cea5f98149d96dffa757e028b7c808d496fc0cfeb131f5af0ae04daeff528cf6d7
+af37c2ff1e9ded9329bf52abd880f2a03ffc51a5dd86f6acfd05f4d668d90fd832ce5cdf
+a5cb1ef44dfe2af6c47efb1ff24cea82d9b95be5d379e8cb7eddb6f05ffb19f161eca52c
+e593ee7cffaff06cd984d0ff2bf278c8eb81d887dea0d0be4694ffa653e2964af217d95e
+e07dd865dcb3e013befb29ff85e89e28b8d80dcbec7ddc93eebeff4ed8bffb93f10dc9ed
+83d0fb7af067e778db7df1cb5fd9ff95c4dc6bcde49e5afad9a557eabe42f8a7eec5f35f
+e214fec193cae935d75ae074cbaf2cff9bf58aff93fcaf43ffb77ad888e092db48afe18a
+dca715f188ff24aff906a3ed9349a1d88bcb9fd681fabf6bfe16ce5ae40dd429ee52a0d9
+8be0af44ff20f34bf82bfbafe011d0f80bfebf90ffabc99efe2ff39c3d91eea053e597d8
+14faafe282efa233ffb749c72690e49513c73eb6e08f38ffaf1de09dff2ec99fe54fa9fb
+88c144f820fba52ffec11188f2d379fbcb68e07be528ffa2d061e02af287fa6eff1eb6ed
+7ae554cc39e051dc24ebc167ddfb03f1aa3fffbcd856ff34c1fbad42d89eed6dc2fe31f6
+baff22f74cff26dc50e0aec799f9bd95fb82ff93c6f746fd06ee88d0b973ec96d864ed86
+f3799ed872e036cf51fb07c1e479cbfebf61ffd8af3efeb75bed40ff60fbc16be79ff3af
+f86efeaff59fff60fbc1d961f7bf3acfaded24c0ff18d52deab17be584edb96aedacff2b
+98e002b5ff16b86cafcb4cfab27efbaa0cc1df93cefa3dfec493f2b47cfa9fd386f2ad34
+b1cb64fbd5840dfa87c89be06ed0f57afb52afdf63d779e167eda7da77f296ff0df552d9
+36ed4bc1dc61e410b5d86acba5fe5cfba5c707feb61fd85ac7ff3ff4acfa7cea87ddaf47
+f9b620f2d02f86f6d071f1c780d893d020e4b216fe5add07d839e054dd2dd8a50193eda0
+59f279fb6cf85fafedb7fe6dffce4ed801ffcb43dc86c7fe4ff47cd89efec1fb86f01feb
+bf42c5ff9a27ef5090dd9f13fb61e6be06ed5aff12d0fe79e5bf229de9c0a0ee1bf851ff
+2cb6cd10c0ff1ff3b4ff0fd0b33dbee9ae5ec5a4d889ffb67bffa431f9a5f477ff9af92e
+bfe40fdb56e279cbff88f924b6ed9213d8be29f657ff94d86de75aa5ebc105a9dd259ffe
+08fa79d986f7cd7ad884ff98ed7bd08def84f5b2fe3dccff86d813ddc593df863d97d816
+bcf58fdf7baff876ee5eaad98ee734f246e005d95dd76ffe9fdc79e5b881ffbc63f7c0ae
+d923ffca92d87be069bbee4affaff45efe3dccacd594c0ed68fea5e081d89646a5dd86fd
+94fe07cdf837fb44ea1dcfe504e0afca52d3ba38e251dc63a1f77effaef44a9fdd77e459
+c3dcfd67ff99b8d486ed03fe97c2fe77fb8aff55f8cd76dea5f24dff3aa8f130ebc047af
+ff1dfa6bdd50e280d8b60ee495fea745ff03fac8f65af29a32fe50ed1cd8b60df9d01ffe
+5bbacf9467f588ff95d90af24ef837fed602e9d029e34b94f1a54efe28f5a5fa2e99d86d
+d936d086e56aff49f207a4e54df061fa39f2b8fb76ed2ed86ddf86b7e593cbaffa5f9ef6
+79fb84ff1fed8dc5f286fec340bad63395edc039fcaff2862cb5cb45ee1dfb34ade0b044
+dc10d745e496ecb93ceec02ec5e694c1e086fb68a5fbd264e5acce17ffc022fa8dfd53d9
+34f2c09bed6489b0dd79e0c0a5d099fb59ffdd9c67edc2a4fa77ffddadce27ed7de4c093
+cdb46daef55a9dfe74ffcf6dddb784e9c23ed9c5fe0ff67efe95f101d986d879fec77dd8
+1ccb9ad584d919cd5bfab9f551ff1dd469fe6393f2c74cd927e065ddaefb02a7d81ee08b
+f065fbc916ffa5d00496ffd86ce9a4c1e06fc7f179cbff6af882d9b61cc76dffac62ff5f
+b805f44dd911c5e12993f69b52fdb76994edc55dbfec7dce85e252afd9fe0fc4ff3afa0d
+f162c8b98840c0fb934be019d82e9742fbbe51fdb062ff18f2d942c9afed84daa60cf435
+fbcd609eff934f86edaee017dd58ffa5fa28ddaf36f994fc79ff02f45aff93e09f16a5d8
+7eecafed0bddc02db3fd93d09bf2c04380beff6cf499ff26eab680e07bdb6aecc14baffa
+07fe5293ff9f40fa18a2ed93e55df387fbb210e093d6a5fdd277ffbf9efe7af3b905dcc1
+34edc4fb459ef32ba5f760ff1dfbd02ebdeb4faad87be586ff37f4d8a6e52cccff81f6b6
+edfec269e7a1d023ecade060beff80fb1bd839fac782e19a16f2be06e2b5dd9e46befa93
+d2b861c4ec7feecb6ce058ecb9de88c975eb3dfeb4f23bfbc32d96f755ffa5db15ed56ff
+1188fecbeb4cddbf59cbaad00afe52f626fa85fea5ef83d98af2cf0cf3d28dddbf39d022
+ffafe04ad8f452fb1def4b98e89035ed50dc42cdfb80ffaf870fd4afdb71ffd006d893dd
+a574fe82b5f467fcc646dbb4e28108ff61f3b30ed8a54a8612e2b20cff79f5c5478dfb97
+10e46bdd8eed53affe5cbaff82d0fb79f825fece87c542f223e69f47ff0ca9fe24d3a33a
+abfe26f9a5d07ad986e06d9dffce75d888ed6afe86d87cc6f09f2493fa9f16f879fb83e6
+93d9b0cd5ee03bd81cd05ae528a5e4bb61fe59f786fca8c83797fe7bb6cb9ee37eddc224
+fac6a5d786fea061e559f1caf765fe16e5b583fb6ef142c7ed5ae027d2bf21afed93259f
+fcafcb93d378ed5bfec7f1d87bf9c787d9589cfed832ddc1a5f746ffc4a1df20d2ed40db
+51afed56c963ec1dffb479fe6ef7bf93c2f288d97ef6b6ed52d866dd0eef4dff03bde741
+aae219fb3ecbafe638faa946e0b5da36d1ed86e02bdb4df21b87fe9dbff579ff9ef57cca
+ff4793ec2ac8a5e961e17cf2cf01ed2dfe67beff39fbaf5ff207ffb61eebc624d89341a4
+e08af2bf3bea4ccbaffe9f0af795ff86f99fff70f6b8d950ea3cfa23febde08732a550ed
+38a7f22cfbb804bcf75afe2bccb68605fe76f8a76df692fe28d59fffb896f369e3c595d9
+18e054dc3ce550ff0bdc83fb9cf291fe87d891ccf360b8fe86f279b6e4089af279cdff63
+f872fe68b7ff51c59fffa9c0ee44d912afe549db35fcb668d8fb7ab5ff08d8b413fe51a5
+d988df8cf20ca5d87be1bf93e075cbf569abff7ef8b7ff2cd85285fac3a5ee1a87e1be79
+d960e406de51d812fe6af282ddace187419ff7b7ffd386fece6cdd7fd1ed69a3e67eed61
+d8f3bf95ec3ac1e10bcb6ae75fd908e544abd905fb3bafffa5fb79fe86cb9fe860d01ae0
+35c659e52dfc4f96facf12d84bc9ff84fbd24bda1eb7ed06c8afe810ceaded61cb2ee068
+b6ff93f986cb93ebbf12f0af1bc2df6ced50ffc29cbffa69ff3dcf5bc2ed64f617ff3dad
+fa5196d5f24be00add61edacffd99724ff78d5f930ffd038f2afcc7bf186e49ac727ffbe
+5e97f2b7d903db7024e5b617ff9ef75093ffce1fd893ff9e30de5ecb98ff7ab6fca4c0ff
+78f78fc6fd79f166c1e98833d0b912bef327affa93ff7ab7ff9ebcf6a9c0dc28a4ee88e5
+9f20de61baff80fc86d4a0e54197fe7af505fe91f388fbc634d851df02ff4da3d981ff9a
+f440fb95cd78f435ef1fe5bf96f8acfe29d288dd6ac5ed27d9ff1089d0a3fe7bd89d02c5
+35bfe093d95db6ca56acfb9543febe2efbb83de7a5cd06edc41dff61fb93eeffc364e05a
+cb09e5bd3ab2f45be00cc6fb7cff14db54edd747f21b93e0c150ed29afcd9cf95cbeed80
+f2a1e26afec732d84cc8f409d94ac91ced62febf43ff67f8adc2f52aa4e05aea32ff79fb
+c25ee093d96ddf47d80aa2f295fd7bed6dc6f360e53bdd79d388d91ee684dd92d8a848ed
+18d86bdb53febf9cfb6eceb65feac1fb34afee3bfeb3f686fc4cf40cfe88f39cdf11c9ed
+6bdb9fcb79fe87f46cfe55fab17ee8c53baf518ffa95f289ff7ad8fb78c0fe85f2ac4ae3
+aff1a5fb2686e494c4fa35a5fe76bbff43e222d8ff09d852ff46d6b779ed86e4af5de67b
+f293ff87e583f195c4d936ed4e93ddbf14f7afc693d81af1ba30fb4bc8a6fa7cffce55dc
+28d09cfbac30fe96c7a7fe04f75bffa1cd5dff75fbc49fff80f594efa745eb0baffe84f7
+a64386e6c877d989d25deaaed081e76cdd1fec84ffb788f819ff4ce00cd842db8bd47ae4
+c1459efbd6edba1dde3ed860ec9e12f19b33da52d2f89336d065c6afffb132ed5eb7dd12
+d0eb86d87cfeae72b2fa90c796ef06ff99f715fea0c0fb25e053d20cd851e104b0fe7bd0
+ff61facf9865ef51f6b06fe4a5d087ff1ec2ed3cabf783ff5ed91fe0b4cd0dfa5ac1ed81
+e0aa2bfab909ed32e261bccb3be003cff790c2e248d91ce0b5fe970eff50f220dc9b16ff
+bb3bce7afbc14ad633e459c6a5ee8bf87fffadf033da17feacf10d9440ffc179fea5f62f
+bfdd66e6ca88ff991cc1fe8bf909e958d1fe81cdfb86e59e4af70eefc32ef6ce3fe628fb
+61b4d93fb0d862ee39aad87ff8b5fe6ff7b6fb78c1e80ab5ed4088d9ff0bdf7accfa4dff
+13efb6e9965bbfe219cba5f091f685ff79ee86e634b2d045f1bf51ebb087d993f20efbb3
+86ff5dba37ff87f29fff58ef2bd9f486e57dff70fbc75aeda0ffb651a5f693fe7db5e96a
+d0ba45d8bf1f9dff86ec67d876e0c0af69e4a5cc21c7acfc47ffaa17ed42e0afd959db85
+d88df49d03e0a023f056ffc891dcaa5aedb761fe94d8a5c0ea6dcbfe7bde8accff5bdca5
+3d93d9a73293de27a3fb82caacfe2cb7c89dff23bedc86d9a54380feaff479fe62e807c8
+52d838d94adea0ff69fbaf79fed669febe4fff7dd856edc779d8fba5d826ca67bed57acc
+67bcd630c7b0e043a9f77cd906edc6e515d964cbfa01fe2cf39cfb6ccaea4bcfaff533fe
+86f6d8f90bf25eff6dee88d184f3bfa2fb6dff7af529ff4cde3bc7f74fffbf79d9af1dfb
+67ff9ed283dfac18f34dff20faaa2df147fa0198f115ffc5f21effc7f462ffd15de019ed
+64e558fb3baae1932bf765fec8e533d80fd09edd88fba0fe7df2a5fcbb10d8bf21ecc50e
+addc1ae5c926e98efea32de7981bed60fd94f305fa9cfeaf45fb9af506a3f0cf23e46afa
+953986ffa2ee2898dd86d874e015b2fa63bdfb0898d95bce1a
+> >> /Halftone defineresource
+
+/BlueNoiseMaskMagenta <<
+ /HalftoneType 3
+ /Width 167
+ /Height 167
+ /Thresholds <
+d8af40ed51ff24d350d812fe97dd67e0c16ce5c552fbd331feaf05ed5dd033f0a5ff79fa
+6ac0e62fd865df98c3d904e093d0a8bff303e49dc8a5fb5b95ffa86edd7ee2af1eff87e8
+b666df86d934cbfe7ffba126e8c19fff4ee53add9e1eed52afdd6ad879dfaf71fd99bafe
+9fdd7dd891d82fee9dfd1f96f012a2e028ed4393ebb6da4ae099ec6edd7ae65cfd19cbf2
+935ac3fe86fbcf27ddabfb70baff3bf81ccf63fb88dd7bf969ffba8fc3e586ed7be2c242
+adf505fbaf28f3ab0bb3e975da94c89fffba61e046da22b2d977ef9ffe0ff156a2f66df9
+31ff4587fec26cfe79daaed821e0c014f54afbc395f30dfec421f577fcaa4ad603edbb5f
+f819d8b893fe79cff97efeca39fca5f339fab816f247cb12aff337fe74f5af44c9b1ff7d
+d7fb63ce9fc1ff840294f2ab59bcfb41f9abc99eeeb64dd7faa04be11ab3f8875dc5ed14
+ccaac69fffa9bfea38b60be4c11dfa64b6fe38f9b269fbce88d986cbff5fd8fe68c1f73c
+ff4ce41fec86b8fb9ec4ff3bfcbf5aafe586febe42cc98dd72e5d2af4bf21cd23bfe6bf7
+88fe9fb7d387ed41cfaf75e09dbbd00fed8ae5b16bffd081dd70fb07c2ec2aade41696ed
+c40fbed985e5d080e08dfbd45ee0a8de17d0fa79e52eddaf48beff0cd952e3c7fd2acfff
+0cd29fc604ff44d87fff8815e0adc6f462d8bdfe3f9cfb88f35aee47e4289dfec7f2a579
+de95e017cea7c70ce7be27ff5df04ca2e280baed259de088f2accd93fe18cb60f285e09b
+1cf9c64ad823e7abff17c5fbb812ed97cba6ea93bfed51d028ee57ff08a9e06bd8f83cff
+4cfa95c0ff2ff8c33eacfd59f2a3d9608fffc75bd8f54d8cff9c49fe23a1ff60ef3487ff
+c454bffe9559d986f868fe93db70f47afbaf47aaeb7fbff366fe82da93f5bf27ddc2f666
+ff3391e5950ed9afe060d823dd93d879f4cd4c935eccfe3ef25aff6cf287ffa151ed95d7
+1ffad014f24997d8fec216d466fb57abf27dea12d54eebadd083ff94f279dd7ef2a54c93
+ff7ef82fff57fa06afd97be378da81c8f784ff25b7cd93ed79e457a4d97ade98ec0de5c0
+38febcf04398fb76a5e0c062e9c676c1ec3ccda5bfea9a0bed903cc3ff01edacc917ed39
+e4a5cb29f18dff61dd3eb0e421ed5ae666a4fb9540b5ed9ebff948ffcc85ff2ff784ff70
+fa06feb67cfad8ff21a5d889cb9edd2cd979d0fd7dd96febb261fea0c6ff864d80fba5db
+0dc1e03eddaefe6ff78aff3fed0ccf65fe38d056c1eed83cd962e0bf91d59fe536ffa6fb
+3bf3b72cdd5aed63e509afdb2afecc62f01ffe87d7b27ced951ad6afe004ccff20f9b22b
+f694fb6ab3fe0afa50b8f766fbb6e872d89e40f2b99dfbb821ea99d3bf14e588ed7bcbb8
+87ff2bc4e10ed5fe58cd06d971dfa559eb6ccba4ed45d0b987c23ded13a06dc7f660ff09
+f77ffb58f523b0e40afebf7ee0c13fe501f5bff1af44ff96f479ffb82b95deb608b9d97b
+de51e4c0a0fb88ff21b6f49cfbb51bf643ff86f1c10dcaa5d868fdafc79efba7ffc35bf3
+b511fa93d2b854fb2cff50c3f77aff80f3a860d979edd35ae103c4f286d879e5d07eddc6
+1fa4f35bfecf82ff66cd86f27aff5df886c3fb1aff4dfad96fb2fb51f3b67ce093f37ffe
+15c0fa24b6f30bc6a7e631d9f193d0b0e1eeac2fec7ae550d1b89cc5ec62c0f29f42fb2a
+93fc79afd99120e5c484d838b0d068facf47fe97f262fbb7ffaf29ed05d9b1e563cd09c7
+5bdd73e0c35eb891f487ff1ded974bfe14d44086ed9bd183eabf45ff84f1bf93d0a5e065
+dd2ed247c1ee91fe0ca4ffbe9bdf4ddb2efeaf23ff4193fed333e0be21e04ad906ff54da
+3be0afd836aed98bd89c11c1ed73abcd61ed2dff4de6c495ed79d0fe86db7afc81ffaf52
+fb28ff4d88fcbf9ed8bd93ed04fe47adff934edcc5aaf2ca51bfed44ceff6dd926f8c2fd
+04efbe86e378d932d8a01886f393c4f57b4a9df979ff81f393feab14fbd92bd250dbb56f
+d7f279e28ae9be1bf74cff389fe0ac18d94ae602f23cfebe93f99efe25d055bfdc8631f8
+6eff91edc161f1a2c2e46187ffb079faaeef78e7bfa3c4fb870efe9ff64ff238f5a8fe39
+d8ff20fa86db8bd8a531ff43d9ae38e553ed1ccb5df397c0e081dbd147dd12fb3aff69bc
+d88de018cdf879ff0c87e9a5ff7bfba55cec88eda1528deb9e3fff20f5a5fd5dedb3d960
+e848abfeb9ed31dca5e528d84acaea966ffe99fa7ec6fb02b6cb34fa61feca86df79c2fe
+6ff2c48ff9a5fe81d9a914ed60dd6cb4eb88e542fbc3a5d01ad84796e0b64bfa10f5bbd9
+0eed9531c5fc994cfa1b93edbe75e56bc998e177de64cbb779e0afc90ffb64f2be70b4f7
+6ad89fffbd9be4b611e942a5f70484ff66f178b2cea3f732fb60f2b437e59ac1fa35dd12
+d82ee0be08fb4cbfffd464e0c46dbacb52bfce89ff3afbc686df1cd87dfec145b0ff8cf0
+a359f5ce41e017f045a2e785ff9bb9d843abfb25b5e704d951fe2fc852b6d85df4c1a0ff
+0ac0f73fff96f179e55aee86f9afff14fb86d89fcc4c96fb6bd9fe9312dfc3abf0d944ff
+d023b6fe06afff28affb01f69446fea5c1df1cfbc8e504b8fb1fc94afb63ffd170fecb7a
+d9f3aae69bc0f41fe65add97bed96dfeb827df6ed786ee9df779fea6cc98e012a5fb1df2
+a9e583ff07f92ac2e09d0cff96f160e21087fbcd78dd01ffbe25b9ee7cd892ceff61d852
+f315ef93e070cef97fd38aed9dbee497ef1fff79e74ecbabe280d9ac12ceb624ffb0cb36
+e667caa6ed2dff7be9c13fd0b55abef661ff3784b7cb5d9efad861ecce7bbfef7ad95aed
+d06bf23d93eb994887fec77dea88f293d8379ef0ab21fe51bf17ca33fe5bd87efec110ff
+42aed681ef93ff5af6c364bfda48e52bff61f5c976dc58fe16f069e49eed855af7afd835
+a7faafc5eb9b21f75ad585d8fe68afff55f730bced1ee5aecd66ff06f2af30ed60fbaf40
+ff11fa85e093d030fb73f358fe2bcafb6df7d89406fda3c793ec52cfb95ff104f8a0ff1c
+f4d67fd989d1fe03f9acf15394fd8f4bfbd552e59effb824e481d9bc61ffb6ee9a51f53f
+e009da78f9c247bfdd93e0a2ed88da85e093ed2ba5e480c9f502ff50ce1ee0ac3aff1aaf
+f280d891d8af42ff86d094d88ed8b646affed03fed6afcd1883bff4fdebe86ed6dfa35af
+e507c0e19bdd7aa5fe935dfbbb9cd7bf64ff87d822c9e57ada68cc3bfb6cd987df1ecd99
+ed64bee13987f4d179f25aff08f784fea5c0da5ede86ec9146e526ee57a9db7ee02ac2e6
+10c1f29b1dfeb217c586faaeff0cfcd02dd816e0afd49fc1ff85ec1ade89ff79f92dfb42
+ff52f20cff61ccf76bfbaf5ae9bc90fab674fd96c7eb69c2fe51fa1ee594c1ed3af74ffb
+31ff94dd17b7d993c9b623e5c09fed66fed039e0abed79c6fa8849fe0bfbc43ac0dd29e6
+4ffe3bd9aae054ff88b7f648bafe9ec2f10cffa5b8fa79b7ff47aafec04b9fe025dcafe0
+6ad819e54393fcb33ac6b7faa6ff96c0f331ff61b4ff79b2da3adfba6cf288ed3ad84d9f
+e053a5f28af983ff25fa63b1cc51fe9bf20cd85acd6de099d2acc69ed8b646dd1bed9dd0
+63dd3dedcb05e079b7fa0dacdd87ef77fc02afd97de0a7cb68f379fa61ff02f859ff62f3
+0ad2b81aaeff9316c4ff53a2f2cc73d958f19ff96fff84db7ab6fa0fa0f36dec08cfa4e8
+17ed4fade0c451ed44dd02d298db15edafff66fac23e94fb9df27dffcd21f0a5ff09d052
+ca13e06dd888c8ed4bd0f867ff79f9d746e0a5ff93f4cc7af7c662dc35d05fdd93ed12fb
+a5c761afe686eeb9ffaf1cf84afb30f386ff8ed884fe29f79ffe7aaff45dfe40d39aed37
+ca4ebacfa5f227ffc106ecb922e6be91c2ea7edd93d983fe73f893f14bc1fb9a2bddbf1f
+b3eb93d279e010d0aced09f4ca6aedc635dc80fa8bff68b1d786f73793d880ffa0f86af2
+84fb73de2ed9b37cfecc20d54bddbe6ae079d866e085fe7bf79cfe4cf70793fb9a1eeda5
+cb0a95fec55eca10be2fed9702fbaffe7bf1b64bbbd97ee02effcf36fba8017ad9c193e3
+7cdebf05c4ed39da74e3c013c4e52cd6bba3f06dff7ab6ff9ef82dfe5dd863a2f981fe9f
+cf4af233add829f045cda5dd3fe45eb5e073d0f678fd87ff3df825ff90bdf64593d8af40
+ffb785fea5d85add32bef329ff98bffe1ce4c127c5e031d85ed088f2c017e45abcf479fe
+af30f795fe49f59fed2fe9b83db5d994cde53eddafc633e4aeec8620b6f78dfed972ffad
+d844a4e606fba5ff3cf75df1be7add6ac9ecf559fe36afff5e95fea153faa6ff4baefb93
+54ff68f91dc2dd2fcef315d86cde86e593edbf43db58df79fec597fb6dffc19ffb1dbeff
+9ec3fe0fee5ab6ea43d69bde69d8af38ec6bc9fe60f88ad422e54df019fe75c8fb7cdcaf
+5be578f5af7afc86b5fe9ef40dfe519eff8bf1a53ce1c483e5b60fc7afc51cb2d774dda5
+f01fff63bcf56bff83fa87ff42bff2d833de60afd03ae583f0c86ed886df70ca97d4b01e
+f796fe4da329db8bd0f114cbec76dfafc70ccf94d961f2cc9bd980ec57affb9660e252f2
+99c93bfa19ff93c4f72aebab0fd946e5b307e86df281cb2af26bd693ff09caa5f216aff0
+86fbc19cff29a4d91de59dfb7ad895cc92e0a603e847cdf209d9c53ae653ed12ca4eaeea
+92c9e945d80ed8ff9102fb5bffa3f337fb8eff4df90bfc79d884ed2aa6d908e055d86acb
+fd9262ff9ff321fbbf5aff1d94ff5bf629b9ee07fe87e95bd810e5c5ff85f965a5db983a
+f820fe82f46df123e6b439f50ffec593e504edafc0feaa09ffb57ed975e10cb0d45bf686
+ffa5cb65f693d932e068d986e239db7ae586fb6cbefe46d003e14eceaeed7bffc35dbff2
+31ff5bf73ff1c087fe6ba3ff6699ff86d9bbfa79ffd262dd33b9fb87f6b74ebfef93d726
+dc79d858e2bedc83cf8fe551fb9ec3fe7fce9cf125f6a313e8afc74fd6b56dec95cdabe1
+35edc39bfe54e0b445b9ff92f4ac724cd809c6fb54ffc1a7d25ce135dda5ffbe7ce08ad8
+a645ff75d785ff2789d1e86de0c148f49ffb6bff98ccb753ee20feb74dbbffb2fa03feaf
+f59efc51d81dc8e662db7eff95f36dfa11cc49a5ea01b3df83d696d879ffb523e0c13fed
+bf0eeea53d93dbaf38f97effa566e05c94fbd060df7aed61feafee8627a5f160ff2cccba
+18e045ed5ffe7ad374ddba5afb03f186ffc20ef745fb65cfb113e589d779faa4dd27d968
+cbefde8de9af26ed7ae16dedba9afbb74eca06fa51ff32f2bf9ff63ad95bccfa41bbf623
+feabcd30bded41e31bfbd181da71e3a0ed8654a6de9552c622afed8dffae34faa5ea57d8
+21e0bf93fdb0f686ff75c2f513fc2de54bd0f480faaf79fbd170feb6f51bed97c1e505f2
+ce1effc3299ff932ffc09cce0696fab6ff10e4c393f15aff86fab6da38e6afff50f9cc7a
+d967d838e0a2bde58cbafe7bf9ac2fffbf16f260fa81fd1ca53bf458ff86d7b60bf640ff
+16cd84fe92ed9fdc93ce86e01cc2ed93e57aacee66a2d888eb86ff7ccab27bf29331fe97
+f23bd812fcc7f43fd0ff79f9cc32d94df397ce10b0f57afcb538ec5bde2bd852e33ca5ed
+adc986fa9f52d915e3b92c9ed922e15ccb66fe26acd97bbeed79dcaded86d8a517f851ff
+d955e07dd89f47faaede71d8a51095f2c20598ec2da5ff90f59bfa85fe60d209ed2bdd51
+d0f269e59fcf93b8eb51c0fec79dd1b1e447fccb92db82f260e928d85ad324fc5cf76dff
+a84afb13fec70ed8ff5bf916dd51e505fed750baedc009c4ff7be5a42c90e0b115ebb864
+ff98e469d980fec63cddc086ff98d287f099f97dfed88b50ffb609edc394ff60f6c6ff62
+f894beffa3d586f34dfe32aff848fe10e04ff2c593ec75b1cb3bf762febe8503c1f327ed
+b8ff4c88fbd97cc0ed19e441cb1cd84af293fea1c886ff82b6ca4afe40ed09d099e578f7
+03fe3294f2a46afe51d0be9ec2f57bff86ebafdf06d983e8b886dd53a4f89538c679cca5
+f288d9659cfad848a7fa79afce47f8b6ff6cef88d842e5a902c1fe25f15093ffa319ed51
+d909ff4bc818cfb627bfe07aead162fe34a7dd934c8aecae4add01ea4bfbc693b8e66cd1
+93cbb67ffe6de539bfd91df38dc1e52eedc9fe53a2fe6ad580e1acc83caffc67d09ffe79
+ed7dddaf35d862ebb53ced04fb88d8a5c2fb62ff27b54fe081edc41bc0e728affb06ff3e
+a5e012f2c143a5fb60d221f3ca6aefd076e3b1ed9fff2bbefe3ceec31486ffd360e027ed
+be86d80bcc49fbadf27cd2f979b1e086caed61cffa79e37bedc0a5fb94ee5fdafe0ef646
+a8e081beef04d7f2c017c4fd85f791ddaf15ee5ac4ff07f35efbc136d0a8ff60fb86bcff
+15aeda943f89eacb86db33fb21f759ffd31fe07ed95cdfafff13f7c295ff18f8d46bdeaf
+f121ff569de07df2d8ffa0cd5efa93ff5fd5ed79e293d9fa69d0ad67ffcb7eef97fe9f34
+ffb026fe4bfa01da57e06ad0af76ffaded931feda0fb8eff61f593fea5c71b94fe28b7e9
+40bcfa0dafe02db5c736fbb626dd57e086ffaf71b3cb93ff1ef7d86cffb642fe9be53ad8
+53cf31fe9dbffb2887dfaced20e3a4f40ab8d39bed4ace9ffb71ffb6f4aa16e552ed9fd9
+79e0b963f497ff09f8c02fa5da80e357bee14f9afcc13895e484d2f537c5ad6abf23fbb7
+35e078d99f56f8b54fc52ebbfe34ddb71ed93be050bfd982e093c1dd80cf86fb96f40dfb
+b837df57caf8af4fc919d5b536de5de677ffd96aed62c4ff75d19efe83f688fea2ca69f2
+7bfec205ce42f9d828ed5ecbb13aaccc79e062d879eea5ff7df186e56ed5aaf69643d8b2
+69ff86e654fb2cafe47ef236d70bd95cd0f878ffbf6cc4f20d93edb346b6e25489fcca68
+ff27fb79cdaaed2692fec44af818afd8fe10dc79f086dda5c1f708ffc925dd86fe99ee79
+b1fb7af488ffc386f207fa4cf519afff31f0b636b9d97feccd7dfcbd40d8ff7ff653eec1
+9cf22dd8b037c8a5fb0faded2edd54d864d913e54effafd837aaf789f0bd65fbc0a2fe79
+defc21f3a1f90cfeb828afe05fd00aff3fdd5fccff79fac73ada72f18ac8fe01d864e7b6
+f979fd2f9cd8a806fb3ba5febf33ffa3fb79cef39d4cf086d29ff20dff79bad96ee0a8cc
+94ed4b87b5fad956e512fe508fe5b863fe9eed0fd84ae5cb03d84de2a117fbafe670bdd2
+9de25ad868e0a5ff4df71f9ce50ba4e79402e09bd96fff0faffb83f79ff24bcf99d96bfb
+93f405ffb9f17ed89d1afa87e64bdd159eea954ee508f2bf68b6d334c695ce68faca1dfc
+a5da7aea9ffe11bfe51b93ec9ed624e058a5f388ff9c47a5e087c6ff43f4c295c6db4ee5
+ca82dd15eeba24d8e602b6ed53afdd5dcafe59f50dff65fb78bcffcf3eafff9ed076edc6
+4496ecce46aef66dffbf64f188fe6bbded9355cda3ff37fc79f388fe12e86ed888c6ff6c
+d0fe79f2bf62fe29e584dcbf51e006db7bfe86f33be5c25daceb9546a7fe31edc05fd0b1
+ff74c7fe32d0ff84db9d49d9fa7fff6ce345edbf7ae864f542f2b725b1ed6a9fcffe5af7
+83ff94f9c04be023bff5d01ef166b7de70e25dff86fa9326f960d8a951ff6ba5fec733ff
+cb82faaf1ceaa5ca8fde24d7ee0295f51dc84aebbb29fdabf31d87bee07ed9af22fbaae0
+2ad3f940c4fe11f05edc93eb26cba7d093fb27edb044f2b751db30faa8d092c3f35afe93
+c4ff60d320df5affb519ffcb3adeb6e079d388f6a5fb2193f2a95cddaf1bed56cfffaf0e
+e650f0afff9f05ff97d88ccb85ff93fa3dd9f92fbce009cb4fd814ddb37afad85a91ff99
+e50ea5fe24f0b617b0efd07ae986fec596c0f25f93e09e20f13fe397d57aed53bff2ab60
+c1e884fb91f786ffaf79d969ffc5fa17fe36f49dd53f92f6b368afe474d87de0b50ac6b7
+fb3ef64dafdd7afea3c826ec88cf5ae014fb42acd820eb43afe087edc09dcd78edbe81f8
+86fd0cf74ee501dc6dedd739ccfb7de593c1f98630ed89c89fd81e84d0f452d92dfe0ed8
+4be05bcdb679ed65a7fe90f27cfe6befc44394febc3ad861fbca7dd78dd981e05abeff0c
+d83fe01ae43bccf677fabc86d86dff43fa15fea43cff99f955d367dc0ed843cdf105e3b4
+4293dd95d05ee984ffdbc40affd01eedacff44f89fff6094d982c7f15ed804e45eff72fa
+9aff7bf0bc94ff79f8c09ff117feaa36fb08f6a548dc20d86bd697cc80ff52c7b77cff9a
+0af149fb3899e0bfa5fe29f587fbda5ab4e474edafe574f0c1a5f303ff93c5dd61d828e0
+acd01affafeb04cdee84edbe32f750fe37f8a2fc3f9cf2affa72f592feb610d947d0fe03
+e7c5a9bfd977e0c386dd2be5b9ffaaef7ce29c66fbc579f2d258f186fec00dbc487eedbe
+86fa9a2abbcb87d841c0ed07ffb61bffa8f983d79fd80ede38afd34be706ccb668ff7ad8
+6dcbf186e07cd0fb6dffaff356ff28f1bf9ffe14f54ce1b0c6a4d1b1fe16f645cbaddd3e
+a5bff132c1fe9348bffb9517fd7ed8af45fc12f3b8ff993efbbb5bd880f78752ff1c9ee0
+93dd73edbe01d2afe38651c1dda75bd87dffb1ed62a5f3932aed509df761fb0daffe8d38
+9e5ac3fe22f9c13b95fe23b8ff01e53da0fad8affba452e762c0f26dfb17f3a7fb79dd68
+e19ecb3dbfe623f48eee7ec8f66dfec3a5ed3add26e593f950a5d85bfe2eafe0c43fa0e2
+8dd9ab36ed62df9ed86bf427ff60ed77d986eb72fb80c6ff138ffa9b18c5ff9f36dcc460
+e334f19ebfe09a4386edca74e79efa38aae0c1add8fd57f213afc986ff6ef41fceff9405
+ffcf26eca02f8ffcc34bbffb88ffcb30d894eac950d8f3d2ed2eaed85ce9afd96ee661a5
+d96accee8756e11fcfff2ed8fe57d999d584e720d0a5f347fd7def9664fe52c640fcb61b
+e4982dfd74f587fb5ed311beff1eedc395f00a93ecc115fa5dfecd83d887ee2afe93d880
+da04cd96ff63da0ae54dd9b7ec69ddafe06bcff96dffa0bbfe86ea5280fbaff80ca5f52f
+d489c1ff29f24a7fb4d092ffd840e95bdc88fba534d8ed4daffb6ad9b7dd18e29fdb7be0
+07a5ed80ff5b93f1be0883b7f672ffbe88ff18f79fc4fa86ffac1bc8ff8af2769ee09305
+b5ed35fe5cc797fe30afd86dde2bfbd986b4e9a5cd60ff50bbe08ad657d9c19ffface67e
+d9a142ff62bcfb70ffb677e01ea5f80eff51c97ae453f2b9fe5be024d488fe79f8955ec4
+ff3bf752f208baed2be74ed01bc2ffd822dd5fd6e554b5ff0be065d99ffedc05ee44c177
+fb9dd727ec4fc2f282bef879c1f33bfe79f75fff23f659c2fe46dd1bcffb289bffdf61ce
+b209ed33a5e0bf47ec28d849d5f89b34dc4cf8c95ef1c5ff79ceaced46df72ccff11f899
+d2bb08c3f217ff85dc88cbfb62f21bff9c04f253ca38fa64f5b97de5d04eda37cbf085c6
+eb6cddc096fbb717ffa33289f3aefb56f1a0d024c0fe02a5d886d793e05aafd479f593fb
+a53bb7f292ffb76cfec87aed94fbb619c491fabb98e6b51cf37bffbf93e460fe27b2e10a
+ace552cbbd93d3b76cb0e479d687f2af64c2e045acfe3ffad880d0fb5493ff7fdd79f294
+51e0c1a7eab10efdb68648b0f71094ffb6f45792edae38ff5baffb6fd956f326edaf0bcf
+b2dd79e4afce88ec95c1e001d6fa239ef2b1ed9926fbaf45ffb460e53bedcb71dcb5ecc7
+3f94dcb03eeda5e07bcef348ff26fd7af686ffb706db58d3f684ca4ac51dee9c35dd50d0
+40ea87f039ce52ff2bf9cc63d9ac44fe11d19ae652c8ff6dd296ea05ef40fec8f232fab6
+fe52e5a2ed6df91894e69052f2b979dcc20ceeaffe07c0ff6efb1582fe93d831fbcbe063
+e5d68502a3e2c34cbfe088edcf46e388d47ce06af893ff38a5f74cfe3cf724fe4cafff93
+58c5fe850e88ffd269dd9ad028faa5d288aff95afd1b84c1f80effc286ff35f563b5eb9e
+c7abdd1bd93ac8fb88e56dc608fe94f7af79cdf988fe7df5a0d662fe7add86d86baff005
+e597cba9ed66c3fb7fb9ee20fa87ffafdf861693d89c0aa7da36ff12b6caf3d828c7ffa1
+12fe3cf2a9cb36c7a4ed2cd0adf1d93be46dedbf198effbe43f1c8fa29fd86f669fa2184
+feb8f635fe9fd042e15fedc886d87be0bfa7d090dd6bedb6e43dbff9d84bbdfe03f789f1
+bf07ff4ef209e59dd8bced61d866e118bfd986e420c973fb4fbefe9aed8551f123ff97e9
+62db2ad8ff02b9e022d8b013fba9c0e80bf2a2fe39c3ff79fa5af638ffa518f2459ce0ae
+38d7559efab6ff4df6b9ed7ad072d6fd7a4da5fb9646e2be86e588fe6cf97de568b6f542
+88b9c8a1ff4b9be8c3369afba65193dcafd80ccca5c0e09e1194d8af04ffa5c2fbac27ff
+0dee9e49fb14f331fbc11887f0d460b8f3935ce0ab55d979ed94de81d8af4aff2ca4fe95
+f391fba955fa96ff5bef0be66dcb5faffeadcba4d837aefbb5ed61bfeda25bf26affca58
+e0299bfbb44cb8e084afd524e08ed880e0bf93c4ff6fcbfe7df4c230ec79e06fdc2bfe97
+f2a73bd9ffc061efd66af3cb50d924e094d84dfecd7ad8ff5bfa03cfaff571feafea23d9
+b7fe7b49ff9df35cff44f2b5ff71edc186da1881e793d8b76ffed996e47dd8a451d9ffa1
+2eff9d12e7cd7cffc239fead38c1ff5ffbc87beaca44d825d077e0c010dd79d894d892f2
+26f9d413de43fe7ff5dd863fa3fb8a49ffcf85e53a96f37bffcc6ad988ed12fb47edbf66
+fe07f354fd64e811dc59b8e50ada93d0af1eff94cb5cdd03c5f78920eab406b7fe279fff
+7ed358fc1cf0a510fb9e24e593ed61dc2cd754d986fe61ef13ebc384dd3ae5adda63d829
+df49f75cfbbfd83efa63f5c134c552b7ff60e0f69467cbea79d8faa63eee1cebb369d8f8
+9f23ed9312f6b67ae485ff5df73afea3c3fc2df841ff7ad8a176ef89ecc250ba15c2ffd8
+10d0e49618f9a5bfe00fd9b948f11fffc595d8b674ff9fb9d29ac82fd8affa7af628a5ff
+6bfc41f8ca62f084f990ff9f59defa6dd9ff79c7afe80bf6a3ec79cb61e0c052edafd340
+aafb87ff94f809e475d080e093fb1db7fe9301c1fb7cf9a5ca96e0308bff9dcaaf2ced93
+ff86ef1ec9b408cffd23b2f64283c7fc87d87bfbc51686e6d075dfabce4eff02efaae898
+d979f15289e0afcaa5e458ffbf4aff0e86f9d99de55093f7a93cfcb3c852ff80faa575fe
+86e5af5bfa2bf4ce0edd42f061f8a8ff4b99d889dfbe47edaae06abbe53bd81ed84dedce
+80aacb3f99ed32fa60dcb63ab9ff9afa81ffaf6df979ffc715df5bec7acba1f427ffaf45
+d3a5ec61c5ed9033e9bf5aff1daff2b84df112ffd55de002b0d199fe7afaaa5ae56dd9bb
+fe28afe04cdc32f2b8ff47b2fe32fa6cf18bdab741c60ab6e530bdf39a4dfe02c1f31ee5
+9ccdafe19431fd71f3cb66edc76de084dc27d75dedc334d8be3cec7dde9460f77efe86e0
+1bd978d0f235ff62fbd08823bfff11affe97f386fbad0fe52dfeb0f786d893d083edabde
+02d539d81fdfc206e8b767f3afd01fbfff3aaedb5dc9f76dfd2eaff74bffcfa00fef86d1
+fe6dcde57ad984b3f99fc0fb4ef23edd33ed87c3ff068ada9bf871ffa8e55f8ecbf36abe
+d698e41fd252fe93f8a6ff5ad0ff14cced78de81b1d062fa34f451ffc0afe027acfe20a0
+f609fe67f5affe06db9ef96cffa1cb51ffc2a6e72dc6abfe93ed01b6c6a2ec1396f4c679
+d99fee59d068e034c3fe93f17bd815e44cff1afb52fe88f484f296f363fea3cb28e29a47
+fca5f159b9fb86f39a08d894c0d979deb76dfbd569e0a543e80ba2fa61ed24cb42e475d8
+86e5c49dbefb43aff2d051eb16b7c90497fbc10c9fe01aff4aadfb93f378e030d882eca5
+6bdd80b7f63cff4beeb993dd7bd66ddd0689ffd85cc5e77bd29dea944ac0e461ed19b2d2
+03fdb123ed48d0a3e55ccd43c0ff86fa50cbafe057feb04ffb85d907ffbf9cf460bf47de
+62feafc87ae09cd826c95ad9b846b4d731ed7efa73ffca85d97be5cf16d840e6baff51f5
+0fff9e1de444acfe28f7c780febe39dfb6fd7aff93f629feb662ff17d693e061a5ff85d8
+f55bfad045edaffe7bed85bbd95cde28caaffe61f41ec5f748fe25d69fbed884fc05c1fe
+23f2a5fbc54a93f2a53aff53d91ccbf183b5fb93c2f47aee59e3be86fb6eff09fa7af6a0
+5ae421f187fe6dd803edc12ee578eda652e721b5dafa8aeea05df4b735f266f975ff19fb
+a5ff79f693dd39d9be0ef42efe449ef07affc260a5ed87e067cbfe89f3c592d97abaed53
+d0ff8f4ba5dd06cd61edc10beb80d971ef20fac130f24c93dfbd79ff87dd37d862caf508
+ff74beed0f9eda90e07eb6d89eed88fb11f731aee3995fe8b34680edafe50dfbd992f286
+fea73dff25cf51ff33e091d87ff3cb14db90edafd91debcf7bd961d831eab5fa74db97c4
+fd42ccfb79d1ff7d01cc39c0e609ffc691dda5eb93cd76dd0fe1ba49b6fea560e093d889
+c6ff61e0ab1cf9c62ed749eebd39d97f14f151ff0799e09316f1c2f769ed82e0a154d8af
+f83dfeabce78e793cbadff2c9fe921d55df7a5fd3c88e0c4a3f969fbcc38ff4dfa07ff67
+c75cade086c9ff4ef8ce86d8ffc12bfa61cabb65cf2dde60ecc779dd88e6a2cc64fa1bff
+3f98e9b650c63a93ffbb30fbafff80f59f4b93e55fff15afdc930ef29f41eb98ffaafb7b
+d99e59fe0ed03de05bed86d067ffa1f00ac7f979ff4bee04b6d831fb89da82fe90faa979
+f993ffcb78dc9fcdfb37f9afd8871ed7afff37f7aeff5e93df9f5affb949fe0ee564bffd
+6ad97cecc011d8afff9533e743d1b779edafc9a5ed93e41efdd139eb5793dca535fe1691
+e0a6d395ff36affe9dbcfb13affa43f3af0ff19ac1dd75b9fe6bf99ffeb2df5596efc50e
+a5e119d2ffc223f3bb87f750ffc880e0afc7f15bd825f24abce587ef7afe9ffa2efdb3ed
+22d85fe0983aedbb9dc0fa77ed95cbb752e56cd90bc7e623df4cb3fb2ef461b6c669ed3e
+ffbcfb4999d96ddc14ccf11fcbec03de99c4dc7ef1ce0af2b5fe2e9afa85f059c6fb7cb0
+f219ff9724e65acd3baff2bf75ff9ff5d11bebc36cbef451fb1ae479edd701ed4ccd9fe0
+86d87bfec05dff2faef0cf09d837e518f280fbc24686f3d876fbb83edfa5d047e197edb6
+62fb26fe6a15dc7fe093c9f62dd84dd9b416b9d8943da7f78bfb7dfeafcc15f862d2af4e
+fe0ff5d025f19dff9360f2c2a5e47ed786eb23fea5cb80dd5093d1f223fe86ed7abeff6b
+b6f686fb2ab3fe4396e0a54b93f4cc50e226b7ea04c0fe86dd5ac6f78afe7bfbd88643db
+b80ebe61ff79fba4ed7dda86cc4ff7b674e16bff8ef645ff07dd36d9a5d193fb489ff786
+dc7bcf6ad805e8affe9a39cd5295f67afb81ffc037d118e5a3d692e0ffa5f853ff1ca9fc
+91ff86f2a5f56dfebeda4ccb19d952e66cdd82ed26ffc783dd71b2ff5dd83bcefca042ff
+04f158ff94d85af20afb9fc2e910b4c8a5d72dfa46a5e035d055c0ed79caaffb3bffb8e4
+60a7ff7ecffa70ade03ad86deea645d819dfbe04fea8f069d8fb91c0df3fd804ff3cb8fe
+a1c626ff90dac022d1b679ed87fb6df61eeb63c7e15aebadff4df8a4ff6dda5be0adffbf
+ed0cc84dec07a5fe83f5c15aed38bcc53db5d287edc04fcc03e03bd851df07e977ff9ff1
+87cf30ffa5fb52de9d3bf2a5fb42bfe487ecb015bfdd87d89bcc10dd78e584d8b82ffa79
+ff80f45afbba98c3fb85f392ffa54bf916ed72d188d901edc71ddd9f44c2ff65f6a0fe0c
+cefd79f3a561e78ccf28ff964aed26a6f266e1c497e711ee87d956ed36aff27efcbf4acb
+98e352dd83ffaf12febd2e93edb63eb9d72bfa8bf22686d6a5ffb66ccfe66edaaf43fbab
+f867f293fe0ce562dc96f3bd6dfb7eff86cdaef226d661fe96f3b822b3d886e8afce1fc5
+ea8601fa62fe94f452f732fe64f6affe31afff68f096db50e03bd089e552ed08dd50d91c
+d5e585d892dd27f261febe81f279feafee18dbb729b4dd85bbe04ec8ffaf55f9b67ae5c3
+99fad881fe9f59fb75dc61fe7afac19ffe51e410efa5ff1bb0fea8c938ed96d274fad823
+e088ed85e5c007ccaffb5ae532d8f29c4ff921ff95cb05d09d1ed96fd883fe28fa60e79d
+c3ec1db7f85e96dc81ec01df78d891e50bff5af77aff5ba0fed8a9de2bd86fe0c17aafe8
+9250c0efd043e5c602c4f79fbeff0caeff87d37afe9ffa6cb0ff40f75bff7cd8ae3afb52
+d90ce073d88af182fa4bff309ffa9330f1d80deccb35fe09b953cb17edbe2ef3adce1ee0
+a60ae570d688d862e070f2d98b02e5b660ff40f1c265ff98fa13fe4d9fff7be978d988fa
+931dfec886d865de7afe5beaffa7f751f1bfa4cfb841ff2dafd4e537c5ff50faa5c959fa
+3efebef26dd519e092edbf35c44b86eeafff1b9ffbcf19d8fa9d1386f3ac78fe61b629ed
+74e3cb3ad966ebc030b8ed0fbcce9ec7a7e718e295c0e886d593ff39fb4dd599ed6ac1eb
+14d0e265a5ff9a5cf379d3ff93f6b279ffd88946ffb568ecc393f521ffaff929c6b740d0
+ff58f8cf81e0ac0ab4cb50afdc79c7ed62dd30ff16f14ac3e2b83bedaef331e5b0d887c7
+32b6e19543ee12feaace96ed6993fba40de0bf2cffacc1eb8548a2dd86fe58d007fd93f3
+affbc64696d2ea4088f3a83be4b4ffc529b9e193fcc295f94ba1f293fd1ea6f27ec3fb61
+f306fb48b9fe86f020a5fe2ff35ccf9fbee51dcaa9dc6effb97efbc542bfe08adcaf47e3
+33dec2259ad0ed79c9f54dff3fafdf9b39c99ffe87f769beed9327fbc168fed986f6d137
+eba51bf8add198c9bca1ff865cfebf0c9fff9027fb4af493fb04c4ff88d886e275f70bfe
+cb44d8f5ae6be563f21199dab5fe37edc29ef5b578d863e00d81d9fa68bbffd85bcaff7d
+d94992fad615d845e01cd7affe14e05fc9ff4ce338a5db81df79ed88d04cc3ffcd61dec2
+9aed0eff87f85ffc02f49c44ed21d986f81aff2fee86c0fe6af8aafc07b7f92f99d984cb
+fb6bd0fb7ae859d816e0a335c2dd9e1bf3b849e21f9ffe5ffbcf9353fe3ff755dc02eda8
+d973f1d878d2ef9ebe62de78b0d967e54bf219d855dd63afea8952c7fe93d888cdff2af1
+7fd0b126e245cbf821ff9dc1ffa426f19009b8fb9621ed6be7c1559aff7ef56ffe68e685
+d28cf7aa78d98dffd123feafcc1efa6af6a44393f2a850fb79b4d846aedf93d488e5c3ae
+fe61eeafd570c9a9fb01afd941ed5ce570d0aefe15f3a503ed55bedd0af275ff7cfbaff5
+79feaecc85ef79ffc683dfbd42d8f2b6e084eb79fb93d024fbb339f951c311ecff27c1fe
+36f89fc979fb88ffc093fa1dffd99916ee33fc55bce0aa08f689ff7cfb985fe7bd4df239
+e5bf58c5ed934be0c2a4f905feaff05be9c59ebbcb38fa50d928edb80af5539ce6943eff
+be99e010dcb5eb03ffbf24c5fe69f6cb2cff51d917ff5393e0a33afb93f552d09ee980d5
+86dbafff51ee7ad865e0ba7eff26a5fe92cc95d952e10ed84ce53cff0ed8a645f4078cff
+af7d0fa5fc20b5ca35e8be67e59acba8fe89b8d1a3e87bedad20ffb63eeda52df25fcfb6
+36f9ce7cde79f2904cfbd8b64ab9dc16edadcd79dd84d86df9a5fe33cef780fe40bbd386
+de1fdbb42eff08f3af7eed98ff5cccea93c7f261c9ef64e534afff83f96dd07ae09fed3c
+e4bb73e885f279ed86d9c107ffc25be50ddd79ff51fa12ff942bc4dd1ce4b6ff48f7ce92
+f0d24cdc32ed21d06fff96ed6dd89ce77bfbd46bedc4e426fec4ee67cefe88f87dffaf4b
+ff09e057dd3a5dfb0ad04ec2de84e4cb6adbb3c79ee57bedbd5affa5d51fc1ed943efea2
+f26ad556ff33fa13feb4ec03d861e0aa0eda69e079f148a5ffc062ed93e06aceff10d886
+dea54afb32b6ff14a1d87ffec961d82fe392fb55f487d1af06fe9fce20c7b2f637fab56d
+f29fbaff99f01fc7a4ed58bff361a5fb8f3794da9f34e577b6fb6bf7affd81f1c02faffd
+86f55dcb21afffa04f86b8d98d38d8b050dd61d90ef2c493ef7ffa93f3e082b5ff93f561
+fb08affe15fd4cf604ff4b95e4af41f7a8ff65cae86fdf0cff88d97be0afed883ea7fb8e
+f27cffbf9ff529ff99c4e4358dfdae42bffb31b8da59f925febe7bdd83d9aefb28f2a546
+f3b8fe5cd92ad8ac14fe5cf1c33efba6fe41a0dd7cedce26de46ce61c5aee06dcbabe37c
+febf4af1befb1dffc15dfe13c3e5a45ac1df429efada01d032baed88e030d9b4fccc48fa
+a7ff79f318ed87d76ce02fb9cf20d97819caed61dd2abad29ae686ed93d979e0a4c1fb0d
+f0c286e103d9a21ff9be97c3ec29fcc16196d9b7e04fcf25d64ded3badd8b511fb74f4d8
+0dd1f97bd8ad78f0a4c2e56ad0ff01f843cf5ce071d1e5951c9fe9aff779ffc098d8b57a
+e065d880e0bf12fe4c97fe88f47cfe2df74bfe25f53ed908ea9cd677cbb16bedb086f296
+2bd8ff078efed28861bfff8ff948fe96f761f10495e56ee009d3bc94c5fe41f8adfb70fe
+a5c0ffedac40fabfa4ff4bf238d856d027fbaf31dc82d46cfe2fbffa7cffafc832fb4ca5
+f39306c6ff24f96dfe9af586fb93c4fe51ed93d0be4d94f69e51ec03fec43aff1a95f52b
+b0ed9bbafe93c0ff0587fcb6f5860cc4ec4ae137fa22ff97f30bf957ff94cab1e75fd80f
+e4a5d882ec96d87effa2cd86ff0ef657f2d307e0c547bfec60c6afe7a51cf7acf05ab3d9
+9fc70dade47fd8ff28f6be99fb4bff2ea6e09115c1dd34e4499a64fe88cf14e080da79fa
+7cff9be084caf961ff29d993dd9f4ee637ed78da86e5b969dbabed55e59fcb16dd75dfb0
+19da86e06efa27ffb1e068c9ff8adc84f3b26dbfd979e064cb77df11ed468df4cb38d950
+d2ff9469d886ed6dbed733afea91d171e53ed91eefa5fcb939fbb605dd54e6c064fb3bc2
+e093d92ea5fe7af8a6ff89fb7df256caed4fd827e5c817e65dffce34fbbf69afd052dd73
+e3a1c1f552d2ff975ef687fbcce52cd998f75afc1ecda9c611f265ff52a5e493ee84fb5b
+f3cb93d888f75dfe19cdff36fa86d4b941edbd5aff33c9f75fff04c9a5d884ee1afea721
+e562d052e5c8fb4cfe9ff33bff58f6a5c6e2b85aee7bfeaf44bffb19ffc295f766fdca52
+da2af2affb79ffbf6bcc86e072c9ff88f2a617ed93dcab5ffa77ffc753d831d70cd93cdd
+1dfe6ebcff80faa551fb86f1be79de9d43c5ec84ff32f7b820da79ed9e43c6ec79d802af
+58b7ff65afea86b7ff46f088c0dd1fd3f410c652d01ae0a808ff51dd10cf93eb9f5ce1af
+1df58aff81faa5c0ec64a6e97bb7e54af237acd65aedc29bf725ff9f0893ecac0dbed893
+d4b766fe1f80ffacdd26ed9fe57edaaf47d907e5b67fff98fbc1018be0a54af823ff5af4
+9c4dd235fed97bf823ffbf13e9b683f399fe81f668ed87d385e01199de6bd0ec6ad9a124
+f388ffacf90ff25eafcc81fe8afb04d8b9f21cb6ff93f1fbc80befc632d4ed63e09ffe43
+aeedba77b5f7a0ffb77afebb70eba5fe79d842f4c880febf61e310d94ce00794fbd722cf
+fb67ff96c2ff8ada7dfb3eafdd79edb6df36d6f686fa1afb2eef93c4ec960fc3f862de0b
+f25afa92f1a6c640ed18e44c93eed036f2ca92db9fed15d9bef986b745cc5be479ed9fcc
+47e11add4beac09ac3fb51f4b5fbc53bfe09baff34cbfe51d817e062d99ac2e611ed45e4
+63b4ff618ffdca4ade753b9ddf5193ffa006f8b524cb80fb8d38ffd846d92bc6e938d8f9
+c23daff068ffb602dd4bd1ff7ccda4f37bfec34992f29c38ddaf17df50e908f260bffe87
+d72ffa67ff89c247b6e59cc0d936fb4cc0fb6eb5cf91ffa5cb2dd061ff86f99ed86bccfe
+63abff9b0ae97ad869b1fe8f11c5ed95feb9a5d841fd6cf888fb6fceb020ff2fadd99e41
+8ae3af86f27aa6e081b5eb7bd593febf2afb69ffa5d09dc6ed37c2e52a99f8afd8aaff7a
+f6d879e5c872da93ebbe02c5e29a6afd8bf25e9ff5912598ffd11ae0c186ef9cf89439be
+fb30afd83defb8ff53c0ec7acbfe86f879b9cea3e318ef5ce797cbba59dafe7dd05eff87
+b9d89fe084d931fc3dc667ee95feb71ee056d984edaf32bfdf5ac6fa52ff29facf41efab
+ff60e508f42ff186c2e027d9c0a5fe65f2c686e503ffb7f721edc14ac4f658fa08c1fe59
+f038a4e086d9bf51fa1eff5aadf46ed5e3860ef3e123ccb01afb41affe36fa4cffa7f251
+f9cb06e078ffd34cddb5ed6193fba42dfc54d823eaaef168c7ff6fe09f15d8a6fe10f746
+a2d82baffa39ff54d97fffaf46fe1af0a50ded42f2ab05e853f119ff5cf297d8aafb13dd
+59edcc79fc2eff0ff79ef319fb7eb7e296c7b886e079dd2cafd889ca93bdff02afff943c
+e406deb84efc93ee79d862dc79ff97e61bd892ed9f27e286cbff60f13a94e97bdc93c0dd
+08feb244ffcf6b93befa6ff1c297e868d19fdd6cd886dc2ea5eeafc812aefb81fe0bc9f3
+46e6bc79e485fe6ddb0ae1991ded87fecc67e384d98abae76df0cb86d881edafcc06c0e0
+8fd879fbc788d97acdf985fe79cfa6eaaf02fe4dd5a1bcf83face687c8a5dd6fd886d693
+ed25d06af550fb1dff80c4f24bff3ffb51d09ff24cbaf786fa9c79e0bd44b2dd32fe9fcb
+2ad861fb70ff43dcb973fbb001d2acfed80bf3ad31fb63edc17bebbe52fc2bdc4de4ba5e
+fe10b7ed16bff41efe63bffe8844eb99e532ce5be47ab8d968ffca35f2afc651ff7af6d0
+5bd92aabfa43ee31cdfb01ffbf58fe0ff6992cfba2f761f22be94eafff26fd3db0dd25be
+fa3a89e0c179e588eb27c79cff04b7f262bcfb4aff3cd961feb3ed03ddafd657bdfa69ce
+a5d89beb70de66c8ed61d83acbff18f5a2ff68f1bf13fba8f28cb8cea5e56bffc846ed98
+f82588b6fe50cfed83d8a94ef91895edc2f786ffa530e07aceff86f85999e0c3a1e45cd0
+ff81fa6fb6ed93bffb24aef50aa5dc9313faa3cbb63ca5ff7ff7c67cd895ff5da5dd9526
+e39dd96bcae576d938d085ffc193e06adec298f467aee37dc9ff43f7b72fff5bfb7bf167
+d1fa3aea22cba5c0ed79e6a54892ff9b65f29fe70baffe1bf726affb15feaf23ffa5ee6b
+b5d861e90fd6af7aeb5ce13fff05ed2fbef411acdb7edf66bfe558c5e278baf615ff93d0
+afff3da165d913d0fb93f5ad51e079cbff8b40f70ffbb920d83cccf41aff47d89dec83ce
+fb4effd079ed29fddcc105eab657ff0ce078c7f34db8fe62f43ffdbd52f295fe71dbaf3b
+fb13f4b650e408d1ff48f212afd87dedcb84d893d91be3b26ddc8bff79f507b5ff13c2f9
+d55be3c12ffb8bc5e26ced94c0db88d87fe596cf0dbefe28f99acb86fb37f8c093bccaa4
+d893fe55cf99fa2dfe4bcaff77fb2d97ff24a4d76de036de60cde5fea5ef874bd905edc5
+2bfbaa26f0ba7edba573f387feb068df9fd070ff54dd3b95edab5ede89d89662f18fce38
+e588f2b0f92487edd282de88d0b412ffac20bfed02e59ecfa9c982ff86f8be76b6d694f6
+5afe1da8e20aee72fec043fe9bcf58dd96e084cd88df2bb0f417fea8d04cff2ab8d350ff
+36f656f139dd78ea85cfaf5aed40e4c29fd049ff0bf465f95caedf83ec69d0a7f3af16ed
+9fc1f26ac4fe49f39ffe81f2ae01c843b6ffc86dfe619fdb83d0ea65d6ff56c7ec4bdec0
+03fdc42df8b506f192ffc11cbff925ff59f8bf44fea1f475dd984ad3aaff9f39fa1bafed
+77e05fc5e551a5fb87f360fe43eb22dca534d9fb61e72cd887c5f96bfca1cc3593ecc40d
+edb632fd53f331fa9fff68c4d97adf86ed7db0ed86e67fe079cd8afaa7fe49f53cfbd992
+ffb01ffe6cef9be583d630c2ee19ff40bdf20c92e786d54de004b1eb7ed8b80cb6d827fb
+8ee580e91ea6df91cbff4de60ab6fb33aee20796f8a06bedae5aed79e5c97ed85be587d9
+6be2a8c90edf86d923affb1bc0fe6bdb0bc1e07ac8ff30f8c193f17affcb6dd823d986d8
+7bfa60c3fe930ecb9fff6befa551ddb04af3afff60a5f980fec87cd991d8b943b3e4934a
+f63afd0ec0f943fe04caa1ff11d9b828b6d88ee072c005c674ed93d825da4fb6ff99fb74
+b5d693e479ffd85afca5f893fdd938f760fb93ee70e657be33fe96c2fa47f32ea9f293fe
+80c995f479fed82bd0ff3adb93bcfb42acfe2cfa9ef444fec378f39dfcb660edca68d8ed
+2dbfee86fc4bf5b662daad43fe0ad7b62ef55cffa0f70eeebf98e653edb0f342afdd04fe
+ca32ffd586d921e0bf47e41e9ef610ff67e585f105fbafcc94c9a5e06fd99bbef330aded
+53ff99f260ff1cb5fe95f7b753f586fe7efacd1cd94cc7f761fb21ccb33bb8c726cc42be
+87cdafe02cdd47ffc39ff7d8af5bed7cd888e0c01bd952e016ed4acbb664fbbe85e579ff
+1ed097db6ae0c617aedc9305ed4dd831d0ff954affaf79a7fb5aafd793cf05ee79fb91d0
+a0fa4cdd84e4c243bfe0a548fd18d86eda79fbc686e5759ced9413f756fb79f293d3afea
+51d0aded1cfeb7d961e01fff54f430ffc462e577fcd084df6de302d793c7e94dd82fe5d0
+16e03fc8b067eb7ce59e07edbea2ed65ddff86f37bffd85bff1a86fe9bceb31ee0860ff4
+bf3cff0afb68ee87b0f67bffc09fff1fedaf46f616cc9ef262fe0ef6b179bbfd6ff7bfa0
+ff7ffa9316d7f2c302f9d93bb9ff25f28affa5cb21e461ea79f2a5fe06affb5b8affcf77
+f2a3ff27e49d1dff4acffa5fc1e57ac7a8d72cfb61ff78befb5c9dd89050a5ff80ed98dd
+6ad8a418f240dbb85dfb20cbaffb7bed5aa0f37bff618affbfa5f303fea5f638feafca51
+ff2ff99f14d84fe0af09f298c1f1aa5af57afb6affd079e2abcea2c6b644fecd26dba539
+dd88d886e094c9abec4ebfe287edc03cffd855d429e83eafe064bde6a53686eabe6dcfed
+7dd8aa3ad94fecbe99ff16b7c726cf94dd7ce5c43393e2b03cc9b65ef1d08cf3a520b5ff
+3cb6fe10eda0c1e101b5f024cbff43f9c6f214d8bb41b6fb7cf7bc86fea10dedc398f344
+a5de2cffcd0de0adc0ed9b5ce488d9b647b9d887dd79e092d978c6f193fb77eda5ca63e0
+34d9bf04edb9da519efe19f755f234ffd99d5efa6ad0fc77f95af311ff60fe85faa534d8
+4c9ee89308f197fe86cbf211c8f456feb6fb9827ffad0ef661fbc378fe86f73fafd8fb63
+e15af23dff1cf6affa01d2fe68d8febd41e87ad9c0f067d0ec85de7bff5995f5cf80dda4
+6cedbf3493e67afea5ee07d14deacb6bd8ffaf4aff88c1fe65d879b9fd9645fa0ecbfb2a
+ff79f095ff10f248fd17f24bfeb65bda1fd03dfe4cf793ff6ffad1a33b93efdd62cb83dc
+95d89312bfe085ec04afe424c779d0a6dd30d801cdff7afbc35ffbcc7dd969e0ae5dfbb5
+2ad87ade5dc5e253dd9ac0df1ae4b50adf6aceef5094ed85ffc09ad5b471db7aed569ff3
+8f1194fac108ff4c93dd9e2afa4ece38bfdc8847fe3af7c30996fed04cf626e086d993ff
+9f23fa4c8ce083d310e637f2a7f73a87ecd06ddda551dd60d523d86fe383b5ce9cc5abd0
+05f79fff85db79dfae0db8ea4387ffb6f92888e8a5ff28fd51f9aff53bfec196f259b6ff
+9ef853c1f17be788b9e517f2b626b0ff41f619ff99d96dff88f60aaffe86f38cfe41a3ff
+7bf6c19cff2c91ffcc34d8ad13fa4defba2dff93c5e630deb5ed62a4e086c9fb0af2b0c7
+97fda5f822ffc2afe076d9afe15fb4d99fc768ff5bf038b9de93c6f534fab9f07bdac016
+dbbffa1aafff83f8b981f587fea9f93fc0f65bff3afa8aea6dcb38e7b0fa2ad6fd67c9ae
+e313d878d4fb07f05ed07bdf86e579d8a54bff86c3ed3fd80be26dafff46f9289cd983d5
+f866c3e08ad152e939cfa5e551c2e03dd013d869e9c95ad835ed4cabe2be0bb5fb6ee691
+c5e56afecc5ddd17a6f879ff38cdfe58f437afe07eff5ee506da5eed69e61694fe2cfb87
+f31dff79f2bd2ce082cefb5af109a9db9527a5fb4a9aff934ecaa1e140d820edd009e4c1
+32cba4df24e586db7ce02dff86f2c20f9aeb7cbeee21fe60f394ff4da0c891d99ced02cb
+49ff1cefafd82cdc92f472fe96fb22b8d76cc4fe61ff3997ed11a4f279fbc387ed20cb9f
+fc6cf77aff84f91faff08ffe81d0f478f9d968c2f14afd32a1d9069cf783fecf51d888dc
+af28bed09efe62d226d877f2b0cb93d4aaf2bf54e8a73ed7b856e501fba7c1fe13a5e87a
+ffcb50feb5e073cbed61d5f271fe66f38cfe66a6ff9d5cf36cff7afb9ed00cef56d8a4d9
+6193ffd153fb44a0d88cdec342bfe1fe52f61ffb6dff93db9ed083fa6cb5fd13ace0bf4a
+c6ed7ee0a2ed3ce5a5bfdd79b9fe2ed89e03ffb3fa64ed30d9a5ed46b7cc97ff43dd02d9
+af1dc8469ffe2298ddbfaff286fbbf3bedb779fc07fa65f295fb78ee17d986f793fe9f41
+ff10fa4c86ffd06ec9ff79fbca88d86ee94793ddc041d8b679e580f259ff1fb6fb07afd9
+2bddaec837e5c346bfde86d914d8ad46ffb68efe79f51afebf3ea5f188caff78f92fa7ed
+98227dd885e0acc64deb35f55ad907e9cb67d8fa3690f2a551fe0ff75db1cc06fb4effcd
+65de6fecbf8048a2dd88ffb81db2d8f256e488cfa5fa6dff95fcb0e57ad0ff8709fe61d8
+51e0a9ca22eaafc79de019d844d95ae5a7ed50dd1dc0ed80e59ac5e01fa4f70cb6ed2daf
+f83dff7dcdf762ff96f91ded3dd603d888e57ac7a5ff82f69d02ffb579fb94f61ffeaff1
+66e5c462f3c122ce96e05addb1e518ddaa03e05cbcff6bf7cef238ffb430f3a3bffc7ce5
+8afea445ffbe7ccfff17e5c09ad093c1ff7bf288eaa535edafff42f7d9b9fe14d34be086
+eb9308fec426f260bfed51e05ed80ff2a542edcb81e824ff6bf57fff9761f254afff85f7
+a5ffb935c5ff7cb6f96cd9ae2bfe61b9ed7add68cf9fe06adca5ee0cafe024d065c98aff
+86faa8ef3bdd4eed37d351c1e97df1cb0ed958e0bf4296fa02fcaf31e4a5ec44affb7af7
+84ff77f5c680edcb0ad957b8a5d979cdfe60d912b6ca28f252c1ee9929ea51abd986ff37
+fa4bee1cdc55d91fc1f8930bcab68628f18ee572f29cff5afbc067adfa82e513b3d826f7
+93fe65c7e4ab5cfa9ecb8ed80de147bce52efece3adfbf02cc62fb980fc1e02fd74affc0
+7af3d84bffb2fa45f416ffb028d29bfe55b5f59ffbb454ebc45cbffe89f87bb6fe93fa2e
+d647afed87ffa379edcb73d988edb879fa68ffc705d830cd4fd835b6fe3b9ef188ff19fc
+4aee0d96e581f068ffa5cf93e01db8f687fbc95ef16ad8a5e280d39dfebf95e24bd2fb5d
+d8fda7cd58affbc301bfda2ee09fed51ca9bff79fbc567d33aec9629f7d819df59f9a5fe
+86cef379d9bd7af65b9bed92e281f3affb66fe88f279e9b50593e49a2290e094d882c7fb
+5ef184c2ed3cd812e0c02f9cff22a2d813e5cd1de061bafb9fff62ce33d6f918a5ff54d8
+3affc912dcbb85ed9dfe8cf294fe86d0affb6cd893c9bbde86fac73bffafd847e40cff6f
+fbd457dd079ee024b6f50abfff34e0872ffb6dffaa7ae4993de50ff3d83096ee61a6f780
+ff0db6fe2bd2be389fe982db72ffb878bdff79ee2cc942dd9f1bffa50bed8bcafe48fa23
+d640e54ecbade00bd238fac7fe3ed2fdbf5afe62f33993e4ad32d988ff75f25dfeafdd83
+cff562ff569ff2c29bed78e01ed993fcb155c2e52aed7fdd9c5ef0a338f855d769e20bde
+62e51ddb4ce52df67410a0e65aa7dd9a1bfb93bbf39fc73486ffafc1fe7dfbcc88dd6ba9
+f079f6afc5df14c7f424ffbe7bffbb62ffcb7dfec23cd05bc1dd7aeb52f4afff17faa8f0
+01d0fb3ca5d495da7beb6bfdc658e0c161ff1ca8da6db7f190c7a5ed269cfc87e29f5385
+eabc78f0cc04d999dec019ffbefb05afd893cd7bf408ed4daae082bdfe8642ff0ec951f2
+6de707f298fe7aceaffe09f8d286fdcb72de25fba0c7a5fa54f67affaedd5cedd8ff34c1
+fe79f4c27aec61d240f1aded9447e42fd8a540ff5afbc74cd802ed4f8ff19854dd6bedd8
+4e93eda441e021d995f0a5fc44f6b1df6ad986d8b645bbe09355c2f30ffb50ffacf133b2
+ee80fa9fd0aff486fec652ff08f67affcf46d962ffc4f7a515e03baff67cff52fa98d84a
+93c7f448ff2ae66bd695fec733eecb09dfafcf95e7b686fa9fd26bdf39b9fb5b93ebbe4d
+e529b1ff91eeaf42ff29cbb796d2bf149efe86bf69b2ed04d340dfb52afe8dfa79e003d8
+f979f365f7ba79ed169af986fe9dc0ff60d0feafcb05a8fbcf1bd6fa86f46cff10e06dd8
+931ca4fb05f261fe87f631feafec7fd888e0bf03d089fb40d925e54cec36d815a4e494d8
+5bddb971f8afeb17b132d8fb7fff6cd8b625e586ed72f8db62a3e480daa5fb52dc198ffb
+af79f98dfc60f439ffc626dd47ffc187e40fdcc44393fec27bf210d861cef382d972ff06
+f35ffbcf3ee421fbd081f788fb6cffc859dd18cbb0fe6db6cb9cdc09e6ca87d1eb2ad8af
+44e927d9a51e83fa8bf239aefe73b6c74be5bb91c3f933ffb8ed7ed096e11fcc9bdd61d8
+20ff4cf831a1f55fe394cdafff7bd886ff69f7d33aef6efea712edc12c97f5cbee9451c8
+9fed33fec35ed30acab026ffce0ffac41ebfea7cf2c1d923e350d625da7dd8a55ffd8fed
+a51fefa9f577ffadf119a6da95e580fe1bbae44beda5d88be6b379f9acecaf45e05bd995
+ed08a5f7bfa2ff4497e720fe3db3ff9337fe62b0ff72f4c494f86afbb6e047dec485dd52
+eb09ffa8cb2cf24da2e078da4aff38f95cb7ff4baef27ae4a4cb93c2e580ffbf11fe4e99
+ed05e196cab588ff80cf2ac1fb9357fec6873d82feafed11d0b277ec9bfca5fe5af1b686
+e0699dfe9337ffb74786ffbaf56df1b5fe12f6cc80d85bcdfa9640cbb630e05dd1f93bff
+49caaced5e9afbc03bfb49c624f1be64c579f1aaff1ecd50d8e98639ed6adcc25af2bf91
+e078d5f29fe533c0e011dd79bbe53fef8cffb52dfebef693d879ed80fe96eabc0afb88cb
+a5d989c6e979dfc10cffb864fb17f051d926a9e668f2c76dfbc028ed47e00eb6fa99dd40
+e0add561ffdabf08d889ff65f8bf18f245dd6de1c24afd34f6bc46f1afd06ff9d894419f
+d9a54593e2bd3fe601feb671d7ff69f7d984fe9c79ed86b4f95693ffc20f86e993b9ff98
+d138ff0efebf2ba1e678ffb461fcd093f810fea5d061ee13fa4dbc1cc5fb58acff52fe0a
+c9a3d512cc68e59f167de043fb20d960d573ffce61ed19f556fe10a1f728fd96cd3fe8a9
+d69afe6ecafb82d8b21edcaf65fea5f962c3e644f287ff69f602f1b859f9a5fb44afd939
+e0a6d092bff51e96ec9fd87fcce45fdd06e5a512edb3fa04ffb8f75a9cff88f2c149ea15
+b0e225a9cf0be8c020c4dd02ead031dcafffc41df26de586df9badd651facd84f4c213e1
+a822e582d777eb2fffa0bece91ffd96eb5f27abfd989ed85ff73f394fc4cf3b7ff9dcd88
+e3a5f815dd3fabf49cd893e07aedcf6bd85aec87fabe5aff36c0eda349f133f9a5ff45ba
+d879cb9efc6bafce15bfd992e5a328e088d869ccf47cfe86fb61ff2e86b8ff79da5ffe16
+a9ff82fc62c8ff69e086d278eb2fc4dd6ad9319ef893fe85c2ff4ff2b568ffa1f569febe
+7afa6cf25ea5e057d801fe4df7dc69ebb95ddd359cfe7cc8ff5dd945fbc186d853fb67f1
+3baaed06c4e726a5fa5bd825dcb938b1e078d929ed5cfeb73bb3ed84fbc627dd51ff31ca
+b648ffb4f5ac2ed906ed84e0af08ffd892e079d886cef537ff01f133d8ff7aeba527fe4f
+d0fd74ee1ee59e19eb4fc905e59ec4f9d142ee01f389e6bf28cba1ed30b6ce32fe5cdf86
+b1fd18faa5bfdf7ad837dd5fb7d879fbc64be035d8ab43d8a0e02ecef977fea5ed7fcd86
+1afeb009ff92efbf51f237aff3b6e48a05f6afe529b6d99cf986fe944cf3ce39e59ef751
+fea1f908d193fa6cd804f287ff4acab67afe8def80affc86f19f088adebf7cff94cf6af3
+87ba5ac80cff4ff2149ce386eac187b91ff34dfbcc7bdd85b7c852ff79fab4c696eda9d3
+4bea10a5e093cba5d852f299fa43aff779fb9dbff227ffce67edc253f10bff59f494fb03
+e4af2ae692bffc72f393ff15afed930bd9b628b8d937f2e5be87ed75d81ffaa5cf97e087
+1c96ffa9d03e97ffcb0be052d861d0fb9977ffaf63bfd26de27fc6ff52aade86e756bfd2
+9be50ce858d004c0df1dd83ae5b7fe4cfbc85fe51ffc42d2fa97fda3c1e07ac6fe61d8ae
+4affdd98c4e070b8f437ff11f7a5bfd94ae42bff55f787ff6cb9fe76fa5aff2efb7adc67
+e4d286d81aed5093dbab0fd99739ff92e4a9cc6de67af151fec161fa0db2cb23ec87c1fb
+51c9fd83f499fb5aff9fc94fd932fba8e569d901fe4afbc7ec55dd71fed8855cf593ff22
+e5af1cc0ee17c6fe03edb523f19c36c1f51dffc495fe25f461ffc393fda5fa78f366ff70
+d97eed9f1af79fd892e7a522ec44ed28b6f93cafda22fba0c65cf93c93ff06abe896db60
+e12f9cfe82d87addaf33d9c3f23dd722d985e0a5c808ff970eff5ae5a6c3f76ec8fb79e5
+afd062c72aedbe18cba3d17fed96c8ed5cffa4d03ddf78d99e4be235d879e0af6b26ff93
+e2c448bfff88ed7bd8b26db9f825f1b714e8b0d36dc1ed7afe88e04fda87d8ac69ffce5c
+fbafe574d9af34ed79e088d8a849ed32d946e5c498c1ed1fd035dcb976f154ff7bc0dd83
+d873fe88d094fb55f27bec0cd981e6be5dedcb48d881f08dfcd00eecaefb0bc0fa931a9f
+df86ed61f7bf4decb66df0c0a4f3ba3cfe09e94aa3f356fe1df6a0fe4efa9bff29f7b119
+ff41a5e081f266fe9af626ffbfa9ff93ef06d2f9e97df2619fed963ddf2db6f410ff3ccd
+9fc75bfa9efe36f947acdd55f2aaff7bfa34f5c44696dd7dd80dfec068faa5cc4dfb12f9
+bf9ff76dffb115fb43acf993ff86fbcd39e0af0cf851ffa9e552d917ed6fe097d268fda5
+fe1bd3faa378fe6afb25c94daff5943fcda2e079edb7ff50fb99cfb41dfe88f8d040e02c
+cc63e084d795ffbb2dd886ebbf78d8b37ce062d96ce0c471bffb2fd91ae5c505c0e965f1
+14cb52c3fd955f8ed80ebcff18f8cf8cfecb52e0acee76fe80edaf2887dfc59ffb04b7cc
+2f93ec61df79e6b8f81bff58efa03cf2ba13ffbe9bda63e11cc8a5cd79bbd891de63d84d
+e10dabfe86c9ed79dac403bff77effa9cb09ff30deb849b2f0922ae0c012ecbca5ff87e0
+61c7ff6bf353ff3acf6bd8af0fff7be16dd824b0fe83fb93ff8ff25edd1ccbef72dba843
+ff0ceebe3bf4acfd38f09fde7cd187ffaf79fb58aed886dd88eca540c0ddfe56fbcb80d8
+ac5bf2679efb9362c0de08d840e2b8f39417eb79d4f782fbc20bd0afff108dc1ec85d18b
+e0adcf87dd5bec31aff183ff56f026dbff5df707ffafef6cc6ed5ed92eb7fe399cfb932b
+e4bf3ef289bff676ed94dc68bbff7df29fce53e502efaefb1cb0d924d786dc81f029f5c1
+4cee9ffc55ef79c2d94dde12c937fe80f97aafff05f9c988d965fecf8b0ec7b659fe04f7
+52efc350b9da94f332fe47fa1fffaff620a3edb33bf56bfec20cbee31dd6ff2ea5fa93ff
+82d85affc050ffb55cd941dea2fa439bd8fc31aed942fd20f952ff79f693c2fe3ed094de
+8afeaf35c79ce6bd2994fea525f699ff7dcbafe04bebd19959fba1e55aafd013ff35f8c9
+58d841ff86f99ad17f3bd893ee74fe9ff403feace279dea8cb04c2dd93ff15a7f67bb7ed
+9bbfd94de03ac1e59558f19ae5209fdbff72f7ce83d893e4a435f4d520ff73e092d097d8
+67e07ace2dc786e094db29eda5ff7eefa55fc5f279d060ef0de573dba5ca2ced99ff74ef
+67c1f26fb6ee65ffc57bd885df2eb5d001e27ad86bec06d776e688f346cb73f2d33edfbe
+77dc59ea19f685ffa561feafd821c2ff38f1b681e0a509f593deb62dd945f2befe67f845
+e5c25ab1e79357bfff35fa71f3a534e55bb8e86ad0fe48fa21a2f5b8fb8861fed22cfb74
+bcec46b5d826a9e64aff12d8fe9b63edafcc0ef260e47cf10cb8ffe779ff03ef53d264d8
+39dd4bfdb8e64dd920fba2cbaffd25fa63f4af11bfe12bb5fe24e54bcdbe06a0e75cf39c
+c1fb6cff9ff321ffb7fb5ef810d6a3fb86fe5ba7f881ffc712fb93de66d81ec7f20fed79
+fa6b9dd979fec74dfbcf62ed1ffcaac0ff8728db9bccb78a17fbc631d8f8169cd892e052
+feba81fad83dff029fd881d0ed880d9ddec318b1e052cbf984fb7cf294ff68edc188b848
+c1ff935be6a5c1fa2fffc3a0dd4f98d85dcfa7fe88f67bfbc298d20594ff86e4c133ec4b
+9ae08dd981d6fd5ca7fbcc7cdc94ff86f4adfa37feaf0be544edc652afdc934aabd984b8
+ee2cafe014dbc002e84f9eed86d04afea4ef6db7ce93e049d4f705e5429eee79a9ff88d5
+7af05a94e7cb5cff08d9f3a7d477ff60c5afed64ff1cd774eac72a9eed86c6f169e5aa5a
+ffb3f33dffa5f780ffa936d803e14ccb18d4af33fbd984e107cbf73afe4a9fdb9357fb6e
+f51bfbbaf745bfdd17e1af24e877f4c13af7b26bff7df7be56ee1aff4496d8ed8801eb55
+d016d83fdb71d889c7f182d8951ac0fe67f2c6f438fec869ffce64ed7aff96ccaffc2ed8
+6df1b938b4fb4cff33c1fe88b6cc86f9d81ce8c531dd4fe20bc7fb14a6edb6e5823afa4d
+edafdd87fe43c87fed9ef70d96ffce5fe0aa43fe14fbca27e462d879e15ada14c5f395ff
+86b6fe9afa79f0b024f29efab686de81bfed09c6e638b6cbeda53790eb9c6affbf5ffa90
+ff4de0a8cd16e7b7dc02d1ff7acfa5c0f08632c6ff95f68cfa7afe96f01be448a5ff59fc
+aee034d8a10e8ee0a523e09741f9a0d04bed37dd61e4b5ff05d99be580dd87f3a51aef52
+ffaf5dbeff8d57fbb0f686ffa562d9f97e31a0ffc0afe0950cf72cd993fbb639dc61d0f1
+76b4fb24f4ba8ada7ab6d88ffea7ee2fce98ed9351dd3cc8ed61d841bfdb67febe41d053
+ff14d8ff69b9fc79c1fe8260d8ffc20bfbc53d93f2c635bfd986f17afe9f4993fe9f36b4
+f564fb09dcfea45ad929e050e9c227afff7bf9cb15d97bea73fb5af6c4ff51d0fd7df1b1
+c51efbbb93ff7cf2a2448ceb86fe2cd107e754bfd981dc14c6f42f95deafd1189ed93beb
+d0953fc2fed058eb1e86fec19ed067f206d1fa8effa84ee00fc0db79ffc753eb36f24bc6
+03b6fa86fe61d0fc79f7af11b7f586ff06acd77dec8bdd7beab427aff22eafed11e0fd26
+87e2af6eedade007a5ed9e11fb30d85af3c7ee46d9c3ec20df93c8b63fd2f27dffa5cab4
+6aedd252ddbb66ed97f72cccafe08643a7e99353dd09ff87d974e026d4b60afebef8b047
+bbf268fec396ff41faaaed77d8acfd03f369fecb6cf2b425ffafed8c0ede93fdce44ef5b
+ffa9bfe58654cb21bff98bfe9952e530a5f785ff9dbefb93e549d80cddaf1ebed37bffce
+2bec94c5e54bf317fe32f6c26efad27ad8ff65d0ab94caf248fece27fa75ffd750fec568
+eb84ddaf26be84fb895afeb951ff7bf7af18cbbe46f70ffebe82fba430feaf3ec7a5ff08
+95feb6fa16bef7adcc6ce555f19dfb69f7c961d922e0a5d87ddbac28ed6de0995ec1ff3e
+e561d885e0b847fec27af481dd55cbfb7bf163a5d97fe018ed4e96ffaff486ea37d843f2
+ca7deed406dfc11ff061d97affa5f56eff9df028e55093dfad5af970ffa5c995d4af4eed
+a056e59a46bef93ff3679fd984b6d951cbb686dc7ae1a5c0ff07f890ffce0be1adcb79e5
+24d84ee09efb68e881d89a43f20ac1e086d0ff79da6bedcf27d960d2ed8744fbb727feaf
+0ebfeb3faeed93ff83f511ff4cf687c8fb0dd1fb25a7d07bf795ff22a0e79305e05ad616
+feb466d92ec7f920ffa4cb7cfed814d941dfafff6ad9af1bfbb47ffe9f67dd94d019edbf
+34c4e33dd861fea4c0fa6bfec31cbbcf2ce360fb79ff1dc4fb02f7a8e87ad805beff1cf7
+5fff96f51efe42f329fb4798d86ee44ea5ed6dff14fa9ff293fe87ed34d8a0ff36f5afce
+8bff4df5029ef122fabf64e57ef29b2fffd77befca62d8ff85cb97ff18d658cd73e4c293
+d8b759b3ea79afed6af2b52ae053cdfa30bbf799ff8ef0c041f7abffb05eecba3bfab734
+b3f57afe9c03c4ef81fe9fcc4ae139cdfa40ff5afba551fe79b3f282dbaf44ed09d73fe0
+9ee879fb9ded0dd8be94d987dd74cf21ffb3fad558e0a6ea10d569eba0cdb993d2afed39
+fe95d8f92cd199de75d85bd010d96eb6f804bfe27ada60eda9d970ecc962e0b03bffa5fb
+3ec0e2a106dd4da5f6934ee52ddc6fe086fa35fe9f3efb19ffd927c4ff3ad8b708fbd680
+eebf7aedcf52d833e05197e6c40186e59aca84e079d3ee6dc1e04bd0fb9328dd58e672ff
+b7f371b3e588d86dcae792de0ac2fb1af8cc90ff72f288ff57f1b144c6b6f237e561ff4f
+b2fe93c8529c7aefb543c189f2abc661fb05f664ff7be0af13bf81bdf241c2f42eff96f6
+4cffc884df9554fb1efec02a93feac42fbc186edb60fc788ff6dc9f986ffc615edcf7cf3
+a1fa4aefa5da6adfc0afec6297f5719fe083ffcb945afeaf0fff4ba4fe83faa8bfff2993
+f3d745ff10f355fb08a2fe2489f0b75fe3bfa5fa12d99524a5e00fc3f62df1af14f862ff
+529ee59459dd7fd8b420b7d801dc93ff865afe9fef12c0f22eec6bddfecc2bfe86fbd04b
+ff24e580dc9be51dd054f5c7fb49fe88e763afcc80ed67e4af27fe61f2c3a8e0b15bfac5
+13e4d39c16fe52da93e7b71fed4fb6ec3493fcaa39feb401c5afc629b6f909f35193cee5
+43bef913f24c88edc632df9ac9b1dd1ce3c10af279d2fd50beed87d8a5d892e9be61d8ff
+a52ef785ff4ec1ee5cf7bbfe85fb6aa8e084ff9cccb686edba6ac7fe29f63afba2f478fe
+63ea16deacd06cc9a8e079d9b6f816af67d997e634a3e07ed859ffc152acfa8ddd9f3e93
+d9b21bb8ff03f9bd37ceba78eba4d41bff4088f79bd879f15787f4d87be56cf343fcd986
+fe79ceafe071d9c05bed8efd6dff95e17fd48ad8ff04abfecc67dd9fc1fe1da5f260f837
+fb5ef3679fda88e560a5dc9b34fb51f929ff4acff79653cceb67d60cdd79b5d288eb51da
+40bdff09d44ddc31f3d31fd8ff05b6eda5cf87dd4be0c5a5befb8ef424f93dfb5afea54c
+8ce545bcf40ec8affe0af893f1af34fdce6bef2dffb6f16de5a2ed7add6ae0a5fe0afbc1
+39eeb57ce6d007ea3bfea5bfff38b6cb2affa4d866afd038e50df354fa22ff86d8b842e6
+15f154ff65fb32bf7fef8724fcb933e061ceff86d879db86d893c9fe4cfb1ebaea12fece
+93df7cc79fe4861ec1e514bbfd93f29cfb32ff01aed88feecb5ed995ef7dfc5a99fb4ca4
+f27cc95dfe0fc3ff9a22ed51cd41c2e485d993d308f1b7ffc4fbd686ff77ee7bddb741ca
+87edb717dd84d860e00dff4dfb32c69cfe24f284d99e5aff6bcbfa53abff7db7cc25dc92
+de7ffb99c504fabd16f59dbaff8dc8a5e89be41cf4cb81d99ed021edc39cf7d84ee0afd7
+77ef96f6b648e502fea5f512ff34b5ed9dc2ff6ff2b676f405b6ed39b1feadfa84f2a43c
+e05acf6ce09ec2fb33ff1ba2f977fe27e4a5c5ea77c1d963e032e883f1af3bbff988ff97
+f77cb3ff1aed7adc71e027849a30e550d93bd861ffa4f70fc469ff50f5a5fb8fc9a7d393
+d9f740afd857e543f6d680e01098f1c746d8f26be567f30aee59e977e079cbff60ed4ad4
+30f167ce51befb5aacfe66f986dda54ae51eb6ff92f453ffac07d87bee8ed1bc42c2ed85
+e476cf27e048afcb2be060c6ff79fbd05ad93bdc68ffc979fe19f6af43f260e579b8e336
+eb93d0be40ff0fb0fe22f796fcafd950e593da76d832d808e04bb9ce9eff43f99fbfe2f5
+c77df289fe9ded2ce065d4fb94c0e2b201c138ed57f912ba87c1ef79ff97c9b721edadfe
+d92d93fb9e0ffaa2ff4fc5aed132fea5f24496d87dfea4d993ff05fb79cf88e00fd734ed
+61febe83fe7ac911a6e93bcbfb56ff23affc63e56eafd85cfb92ff7bf9d865ff86f8a851
+dc9a0df38cff98d807b9e795d884edca7ed891cafe5ad8af17fb60f190bfe081ddad49d1
+179fff6cf60afe5ef26ffea4fa63f532c6abcd15fe5d06b0ff20d2b302acd88afeaf45ed
+2280fe93d9ff83e07ccdff61fb1addaa15fa86fe9344bd86c0e372dfb2c634cea5fb6cff
+9ec720d4afea28e1c21af94daedeb6f020ffb8f279ffafca0bf2cf43ed60fbd086de6bbf
+e581c5e13bf29eff2cfabf04ea42d0b609edacd91aedca31e8c062cb1be55ceda831fa51
+ff25a5ff11fa47a5f17cffc29db7d866ed2df261cbff7ef9c027cfafe086cb95e5af2ec1
+e387dd82fc67ed93d8a3e070dc5df6c5ff52f216db9ec5fad83ded61afd028f4ae33d893
+e951cbec69d95be5c6f751ff19f454ff81ed89d91fe052f186f85bfe86fbb359ec78c4ed
+8639a2dd9349a5e39a3ee8b959afdf93d8af47fe1cf79536bef968b8cf0fcbb554f1a7c7
+9cf581fe9646befd5b9fff7bf9a5febc7cfb8af8cb79dd87bee26ded9ac0dc05cf51f33a
+f707fe93d09ffb02bcea6bee99fe42a5ed1dff48cff29302fe53eb1fd8b03dfbf043fb9b
+ea8635d985bfe571f35d8db6cca0f71dfbb766e097fe5daffe81b6ff37f4b401a5e588d8
+a5cb25dd5bfe79f7a9cd11e171d9b601c68effbc9dfe2bbefed46df7b5fe22c8fb6df69f
+fb16ff30f098c1db79ecabed18aefe89f07dfed27ae05bee2fdd51c4e87bcdafe164d825
+de44edaf25db4ab4f00acdf443d9af2ff386fe96e584d979e1c14fff3dabe49339dd58d9
+79c7fb7ad68bdd9f56ffd9a6ca97f679ffc160cfa9c716aefcbf97fa3bb5ff2bbffd0eff
+59bfe07ac8ff49f105c4da3af308cb9fd36dffd03bfb62f985f09ad804e1bf6ced98bfff
+39f6a7ed3fd00ce05cccf28c46eb08d86bdb86bddd2cd885cf7be088fa60b6ff0ad888ff
+d839dd50d924a1f71dd86cfec1a0fa1fff41f30bfb86f193d879febf82ff88c1fe6194fb
+66d0ff6de04bd82bedafff45aeda80edc963fecb86ff09f4b724de53fa11eec37fbb4ef2
+2cade00de98723f75affd04ce024c3ea83d0a5ec53e486f23a9df008a4ddbfa5f673e4a5
+d886fb22edbd7add95ce0ce064ff86edaf33ff4dfa2ea5dd81d869fb78f594faaf13dfc0
+a9ff96f351ff04aaff5ef23df9bf05c5e728cc9efb5ab793f479ff87f3c64dff88e5ab13
+d970df93d883ddb2cc4dff0fe54ccdf313e442a5ebb71ee5a10ac69ef96affa41dcb99fb
+22f8ba14f4b02bf2be9fd84fff87edb1d186fb29d8fa7dd3fe6acb95ffe47cedbb81f493
+ffa54cfb06f77dd995d879cfff67d4fa8650ec2dffc062f042afda934afe1ff25dfea0d0
+2ec74bfa8cc3df78d1f360fe1ce593ddc03bd86bff82f75ecb41c0e07bcded7dd695e458
+abfe9f51fd65ef40c2e625cbbc0dd6b66de5afc73cf886ffbe35f661ff9830eaa5c6b687
+f765a4d975fbcf2affc782feaff136afdd80c7fa70ee62e5a052d986e095d055fb87e66e
+d8a542ff35aee09a0ae6af3fbef930af6ad9a03be70cd978eecb6ed860ce34fe13fbad2e
+e7963fc2ff8dd89b1cfb93bfff6df8c39ee07cd9af3ef7a7fc93bdd91aaffe9307c8a0ce
+5af02786fda0ed51d825e591fba52dfa9f49f50efd8ac3dd6fedd087d983b0f779fe81fb
+a4f83cff9f06ed95d3b65be89db8ed17bffc7ef46afbd026e0b83eefbb7add9757ef30d8
+5bfccb0ff254bddf09d87acdff73fa5bfe0eedaf2fc1f704fec39dbff56bffb965ff93dd
+5aedd1fa06ffce6cfe5dd51aaff193ff85f2a7dd6cedc978fcb0ee17db79f2afd74ce90d
+e331ed5abfff2cedc179e514f160ff86eb3fd9b2ef45ffbc9ffed8b404b9e4b1fe64d918
+ecd16de5c587d9b624ff39f71ba8e530ffca0dd851de32ec66e086cdfc77f428fbce02fe
+51caa5e047d507d93da2ff7afed39018ff4cf7d18bdf7aecbf88e894fe3aa5ffaffb32b6
+ed20c7afe069d4ffa45be47bf25feb15d847efcc1cf176fda54a95edb67add88b6f987fe
+42dd1de2c045c5f8249fdb0cd876e55bfe35e160fea3d190c8a8fb05afd883feb65addae
+d745cf9ef77afe69e488f311c549f67bff8731a0f17bffb586fe1ca8ff36eea5d0b89bc0
+ff79f3ba62e38ef2abd096c719fa59b4d852e079aff27bd986fe6cf787ff93f2bf57ed01
+9bfac39fe5b304ff46fab621ff5dd979cff28848c5e585d4a2f2429df68f1aedcb93d821
+de92fe80e56eb2da9ac912e2c139c651fb1ff3ca30e19fc7a5fb529bff935fc0e57dfe54
+f9aecfa0ca80f2c42ffa61ff78cd95f74ef30ad2ff9325f6a5fb0dc1df25d8ad33d984ec
+a5c0e050d5f8c111cebe3cf25ccaed65d879fb6ded5bdf47d914a0fa3bffc101fe4af2bd
+99ed22ffa5c3fe43c0e322eb38ceafde52d81de086cbaee450f237c069f2bd9fca79dd85
+d528ed9e18c1ea9613fe4be687ffd830c9faae37fb6aff79cf3ec7a8fb3af752ffbc83fe
+86e5a5c1ec9c56ffbe0aed74d0afed03dfafff4ff1b1df873af303e6be1194edafe014dc
+44e46dcf91e39f43f2c969e07aed62b0f977ffc299fb57ff2893fba94be59bfa7ade90d9
+af40f998e54bdc07fe93f986c8eb7fd8a56ae685d86aff77d3b764f10f93ed9e61fbc195
+f1119fed7afda5f92cff6dd881d7fe93d861ed15fe4ff6b8fa68ffaff75affbf66f5b807
+c05ffcb64edf8fbfec4ab8f69aff1fd788bfd88ae928d8ff15f64a84dfacd079f75afe2e
+d964fa86ed18a9cb3197ffc193ff6ffaadff8651c2f385fbb8ff31ef7ac6eb6bb9fe39cb
+95ff52bfed08e542afdd8bd1e919cbff85d85bed29fb02ffa1cb10c1ff8fcd7bd727edb7
+4bfb23f0bf43fba5e512dd46fbc98de4be30ffd8af48ff60c0fe35b7c743d888c1ed0ffb
+ac20ed3bff93d8afe19b04a8dc4de02cd877e0a5cb79d9ee93ce81f472ff14cca6db07e0
+86f1a5fe03f443adf2b3a2d993d6ff11fb38d995e082bdfe89c83db7d5fb5ff5d81ee062
+d1b427de49d8f9a139d89c1ba6de60ff25b6fd02d9a1fa21c4e82e95da80f4cd15f14cae
+f3953aee0dffa5c79ee177de83feab2ef361f697ff69a9e093d27ffeafca2eb9fa9bec87
+34fe4fd0f58c09ee86d3a5e070d0f367ff95f54aafde52e986c7a6ce27f94287eeb6fe7e
+cd87fd9ff305fb31ff9e48fe10e529dab8f163fe84fabe52c536b6dd79ccfb7b4dee64fe
+33b7c995f260ff27b5eb0fb0f697fe2d88d9af71fb9eef44eac369f5b61fd0ff58f2b6f9
+81d892dd81d8af76ed80e1a564fcb85affaa61fe76c9fc5fdac26abad042ea4cc2f735f2
+51d9bf9ee118d840cbf709ff51db11e07aed86cb5aadf7d67deaa462e0c497fc1bf72ffa
+b104e5ad17d89efe78d096ff5af377e6a3c3ff2dd745f210edc441b8d093dd69e1bfa5d6
+affe943b9fd825e2469ffcd881ed5effa40ee5b728cb7de488ed43afe486d2f44fc4dd5a
+d86deac1ff0ab9ce58a9f87ffe9fcd79fe6196e07ed853ec0ffb51f23cccff17d84cfed0
+7df3d61dc7e587d99f2de379fea4f579fb93ff64afd089e576ed42c0fe86f2ba82dd9eee
+88f759ff41f51effc106afdb1cfeb83bff4ebfe181d9c488fe81cbfb5fef26b7f91cafe0
+06fdc168e085da93e494d8a56cff87ef45aff319f83efb5286e9b5fd7af86ac3ed8a14ff
+97d922e0c28eff98fab559f86bfecc06f9bf67aaff79f216ffb14495e0fa2affbf14d13e
+e208edabe7bc06fe30fc9dc5abe597fa67bef486efbe05e347a1ed933df90cffb886f206
+e033ddac15d9bd1efeb609ff92fba65ee0a331fd53cf2ec7a5d592d9a1d881dd95ff68f2
+75cfed81dda55bf29b51ed61dc3bbce07ac7e665caf17dd9ae49fe0df35afb7aff36f8bd
+1ee55fffca7cd885e099c4f201d844debfa5ff2dcbeab549b9f178fb3cd1dd01e9c619db
+be7bde9f21fcd83ae09abcce7bf8c44d87d979e593feb892ffbf3588f7c96dddaf64ff4c
+cb13a9e42bb1e03895fb86c9ff6ffbbfa6ed6beac451d394ff59ccf36efad86aefc661d8
+23e9c203fbd179e887fa62fe21f35ffc66ee27e54accafe213a6f829fbc20effba21f793
+fea00cffa441feab33fb4ced97d6bf74cd1bc762de50edd080d99b28fb4cffc125d978ff
+adee960ef259d9ab61f893fb2fcf9eec5c86fe6aa5ff9f2ef151ffafc67bfac032f54ee5
+20dcaef194f335dc64ed56d673fbd84ea4f483cbf122e885ffd079fb5ac5ffb75ff2a516
+e02ad94ed0af21fea5f768afe283b6c927ade045a5f883dc4fffb072beff19d8a4d97be0
+9acf0bc59ffe70bcfb3093ffc959d872ebb378e5cb7bd855edcd86f2d275dd93d0bd88fa
+31f694ffa6f4b99dfb6daffe10f5c3a1edb577f550e4c05b88ffc579e680f4d009df61b1
+ff50bff7d82cd0ee4ccbfb86d870ed46e50da5fe8fd884fb6bff06d45efba1cb26f997e5
+1dbfffd312e340b8d85ef3b752ec9dd98c1eecd43dddb982f792ff7bf7bf63d830c1ed08
+fb46ff98f480fecc16ec9af26ad9f545afee5dff08edb139ffacf43cc7a8f687edc2469c
+f392ff38ccfb43a9ff18f5b568de2bbdff0af557ff13dbb759ec28e050d901c1e52ccbb4
+70e560cf0ce292fea81afbd237e0b51efe3e88ff9cc1e586f30ba974f3ba8be079b8e412
+f693db86f1d050df01eda5cd52ec7de0c10fffa5c743adef933987f996fb79fea1c832fe
+af09ffc1f778affd67fecb52e001e538dc93ff88fa54d199ed7ad851dd3094ffaf3acab6
+13c59fe18eca86d653fbbd6cdb7de057eb03d95ffdb1e807d57ce4699ef2d35de0c239fc
+97f85aafe5c29dd8b06efea0d0bb82fa8eff79a5ff86fabf3bff94f265d831cceaa26df5
+86fbc2a2bfefad43fe1cd866cbffe09c45f80cfe3d9afeb825b4ff6299ed7bffb92fe48c
+befe3fafe586f265fed96dfbb6edaa58d9b104e06fde88d3ef823b9edc11beed2c98f3c1
+a0b8fe5cf00ee69fb9ff24afda10fba5c0e370d1fa79ffd861f926fe3cf69ce07cc9f127
+fb94ff8fd17be01dd862feb8f724dbc00893fb9c63e4af11d889ee8640fc2af2ca3fe007
+feaf38e84af1d356dd32eda5d653bffe86ef9562fac906d84ae45bdc27e0c57ced91e4a5
+5415fbd87fd887e7c76ad99fe237c8fb1cafcb6afe9ef622c68ffc76d82ed8af02cb47e0
+19d0ff29ccf793ff1bf84898e5c6fe5be879ccaddf8846fb62cd9dc7accf29de61caf271
+e8b362ff57f32aa5e05297e586d879d86ceb2dfe13a4d864cc17f24cff9ef186dd9844a9
+ed84feafe732bffa7dffc29ffb22bfe093dc7abcfb6af179e4c19ec9b60dea94d180fd07
+f7af20d15affc03eb1ed96ff87f693ff79f7b04bfa30fec3b26cbfff42f4a527f250fc81
+f4b959d8f843edc15ad780e9b61aee52fe79f698ffbd86fe79beed6abf4ab6d87abbfa24
+b488f2afff41fa0bffd880ed18f539ff7dfb91f6a83bfe86c6ed0cd886c5fe05b9f61dff
+aff20fff94d0adbff44af9a5d981dfc139acff26f5b6ff60d140f25ab6ed22d94de03cd2
+a6ff52f362ff1ba5d990d85aff14fb66f761fe1be460dd79ec99f6b711e5a6ff60d031d9
+14cd4fd503dcbf9fd078edfaca1faddb6ccdff82eaaf08d888ffb676dcac11faafff4af9
+cb85dda5ed39e56bf0af5af39a3dd8fea5e536f1cd66d8fb45ce219fe07bd0af26f8a5dd
+75e558e049d815ebc555df2ea0fa93f15f9eedd37bddc03f9bdfb44bfd38e686d06fe333
+feaf6afacf77d85bd812e093d97ccbfe86d693f181fe67eb87d802cc93d4f445fe1fec80
+d989d8a0cd7bf3c39bc0ff38e04ac7fb7ad820df79eda4fb7ef29bfb6dff10e5b83a63ea
+9df08bfe06bedd3ccbffa640dd0dee86ff88d93793df9e5cffb614b8d25bd822ddc10bc4
+e89410ee60fba10cffbf79e48fd9f94fb6ed6ce6b84ac1fe85c5a4f287ff79a2f790ffce
+4bd921cefb8931fe4e87fbcc61fac781d960ff07fb93edc01cecb70be586ed8efb79f728
+ffa505dd52ff0dccafc717f873fe84ed36b6c69ccca9f847f423ff37dcaf46fb2bafd886
+fea05ef093f789feaf55c0e039d85ddf94f180ffafbd4bff33d455ed5eacfa9361e5c09c
+f95ec72bf2a5c2f10abfe62af396fa86ff9dfa80ffa6fd50f2ba79dc81c6edab50f502fe
+5a96c8ff34fbc37aff971dd8fb09afd93dcce504d973b8f580ffae41dcbfa5c2ee9f29ed
+a501f794ef9fddb545bb75f9c65bff9bfb31c64bcda5e067c6f06feabea5f433e5a0c0df
+5ada9fff7cfa5fee2fb8ca9bde82eb87fea6cb93ed62da03e4cb31d951cb08d2ff25b3fe
+92f536cc51d826e0fbcf86da7afac497e123d3f32cfb67d0aafe98d357ff79d9fe7ace61
+e044da07ca4ce032d96bde86ffc924fe4d87e093d7b67cdbf4188bdda506e236d8f29361
+befe77fa69b6fe5aed1898e066c7f77af25fe409d5ff82c5ea5cd820cb79f697ffc44293
+e2af4dccadf19efe1ab9fa429efb9543e25efe7af22db2fa15d651e90dd86cff78fd56bf
+f26bd20bef52f915ffacf76eb6ff83fc9cf46ba5ee61c30bb6ec89fe86f47008afec17e4
+b11df287fe78b3cc93ed1fd94fe079ea1ecdaf50b2f293c2fe7cf58cf1a1cf93f91ed048
+aee492cef71cff3eeec337afd7f152cffa88f3be4eb6f6d52fe09ced35caa5c0fbd33aef
+0ba5e01aff94fab678e051aafb8fff55ec2ed80eefadfe16d5f46dfe01dd6ce584cfafda
+13c9ff7cd99bce4fff72beed81de8ab5fb97c2dd03e3a51dfb52e293d883dfc24499ed1a
+bfe724dc46e9c986d8f9a5ff63d914dfa4c798f567fec17effb741bded0eff4bc2fe8ef4
+02fbbe9dfd3af8d708fb35a6d863d925fb58ed7ab6f69dfb64ed33b6d89bcb6dfba2ff4a
+93fe9f5fe06a9affdd3e93f0c21aaff861ff2886b2ff79d8fe69b6d058c847f31dfec92a
+e277db93feb6e568d87ded9f28debf95c3ff57f32eff60f2ad2aedbf1aedaac3e53fa5fb
+2ff6ce3de025b0f779ffcb8ad979ff3bf4b467fcd379fb61add87bf9b517ff3c7be52ad1
+95fabf45ffd933d8ac45e861d99fe05bd881e0a45be77cb5cb42ed6ee4bd69e69abfee1a
+ffacea76d613ffc63cd807ddafff86fa5af3b00de07bebc611edc025fdc51286b9fe5e87
+ffd084db93d7ed49c2e79b44c2ed2dfc83e090d9af68d8b0fa13d27b46a5fe30fa4fb9ff
+9349f838aad988e491e07ad1f9a552fe64f9058cfed06bc5af7aff86f264bfd844affa2d
+eda2cfbe22eca52fe1c596f259ffc082e296f2bf9efb79ed5aa7e47a5bfe76f19ec5fb03
+f787fea5f619faba34d8ff68f893d81390ffc456ff83e4be48c5fe89e2aa70f286fea453
+d415c0e02ddac05cf929b3e062ffaf4cdcacfbd803cce6a545f110e554befa9326f9a9ff
+75d8acf00fff61f59aff5aa1f287fbb8f283db89cbe565d1ed86e0bf0ffb4cc824fe4689
+ddc386e080d8f2991de2ff09d94fe6a5ff39ed95e565b5c707fe6dfa7acdffaf41fe0bd8
+af33ef65d456dd0ec2e032c9fd23f2ce86e00dfb3b93dbb732c74ab6d877cff29e16e0a7
+29ffadf03ea5dd24d8539af79330d85afbcb4fda27caf289ea61a5ff84fe95cca5ff86d8
+80cff879ee5994ec9f2bfad97afb8dfe9f01c5dc85e015b2f63d96ddafd032ed0bc0d94a
+e435e005d05deca308fba71eff79f693cca7edb9a1c1ff0af6b636ffa849ddc05a87b8f1
+9cc818d6b987fe12c1ff79f156e5aed90986f293c1ed78e593c4fe2bf68efeaf52ffb683
+d89c1af6c094d6afee70ffa5f186ed2eff9446feb87beebf7ade63cefa7cf58efcc60abf
+e594ed01a5ff8af8b437ff79fbbf4eed1fe969d954f536ee0bbce42fcbf943ffc166b9d8
+4fcb37f1aeff56f36bbee15cccfe8843f286cba7f76cffb3c794ff87f725ffc152eac55e
+d92ded53ff04f861e57ad86aead060c7f779feadf8d232fe6afb79f826cfa5f334d88cdd
+9a38ffbbe929da529fff4ff202b1e07ad86bec93d901ef51ff
+> >> /Halftone defineresource
+
+/BlueNoiseMaskYellow <<
+ /HalftoneType 3
+ /Width 167
+ /Height 167
+ /Thresholds <
+1ace5bd99808fbbd63fab215e074d886dd9828eea2ff863995fa6ae423cff0a306f59afb
+45affe9cfa05f394fd60ed1b98e72da3fe8ee926c9e51adcad0ec5ec21bfd810bbfca5f2
+7dfea0fb88dd9ed00fd833e5c8fe65f72b93e1aa3bfb58e564ed19e05dd1ff62f4c7ff1e
+f2c5ff15f19801fa47f12daafa20ff4df318acdf83d29eff67fb1dafd979bfff4ff7c73b
+de4cff29f57aff6dfba2bff384d188ee6dff5ef20bf9d8f686fe33f5afcf4beaca6cfb9c
+f32cfe01facb64d915e5c6ed06d97cf7a943e0b0c730d6bc67cc7ad5be67ca26d8a5fbd8
+79c7ed56d87dff4fbefe69d6fe79affb69ffa0de4ad938d852c807e862fe79f4affe8043
+a5d986dcbe23ff9dc8b72cfeacca82fba327de9332a7d9933da5dc5bffcc8ade7bfecb6d
+eac0a5d894fe61b7ed5aaadc91c8ff56f023a0e0039df48dd885db59d9afe042ed17aaff
+47fcacc721cca5e469afc0e076d867ec86ff9d1fbfd845bad06ae9b57dfe93f6a551b6ff
+a0ed5ac7fb70ff7de586f4d92bef58ff9ff287ff37ba5dff86b3fb0ef293d987b0eb51bf
+f145d0b234e686ee79ff85f691f0a5cb19e2bf5b96e9b6ef13ff4dfacc7adf0bffd98840
+edb50ae8c178fbb6f76ffeb5f87fd8aa39ee62d8b03fd9b461fb28e63fcef62ec3ef0ef7
+4a9ee586fbcd81fed158e909f98bfec11c99ff88cae666ddbf2ff6a5fe79c1ff40940df1
+acfe17da33f0adff7ff88beea5c659e433d64ac1fb7ace3bbbff169bdc20f250ff0e97fe
+b5e01cd948e2c290f7cf03e03bcbbc61e232ed09b9fa2baae081edc15afa0dcdb4e01fd9
+5eff83f7ab3cedc21eff87d0a5e46fb0f651ef6598cffa61ffd07bfeb004e151d80cd253
+e025fbc0a0fe15f799ff06ef96c790fab272aefe7cd886ebd012ddb75eed32b1ffafc665
+d03693f8d252da339bf1129eec60d83ede1dbaedd6fb9e45c1e47ad48bdb42d80ce04cff
+19f888b7ff84ec1fdd6ce781d0aeea5dd289d977c8e68643a6f784feaf0beb45a7ef94f5
+80ff9fc4fb75ff5dcda1ff5bf704fea7c796fe30acfb9cd028dc55ceff7cfaa6c84bfb30
+baf11ad893c6aff714bfdd934eed36d9c495f183e587ff93f27be65dafe486ed79b7d646
+ff52d809ffd822e243ffbb76fea535fac494e48626fba5f1afe34aacf285fec078fbd87a
+ff89f295fa8f51af3bc5e87eb1fa55fe6cf487fe79cb9fdb6bedc911df9cf388fe0cf44c
+fc86f6b3fe3beeaf34fbc1ea5fb6ce6efb9cbffe53db6bd818ed48a8d892dd84e61ed988
+d379dd3be560f3c66ded7bfd95f2a20ad847df6dd993e05ec2fb79ff32ea5ae0a42af5c2
+adf867ff43bffe62ed1cc94ad909f4c84cd832c7fe6ae2a1f280edbe5cf99ccdaf29ed50
+c1e0931bf247d7ed54db14ff7cfbc60ce05bf4b23abde509cb5ae064c3ffee93fb61ff1d
+c4ed06cda5e73db8fb2ebefe4395fbac56cab65dd993e0bf35c5029dd87bfea3d08910ff
+d927edc56add88d229feacf896bfe51fef35f478cd95fb40f49aff81d9a34dff02df51d8
+34c6fb88f391fe05f57afe9741e5a0d486fc80ffba61de209fe588eea428dcc0a9f6bc9e
+ffb77aff93faaf27f3be12b9d03388e9c166f179fdc68ff778ffc0a4fcb67aff98cb5ede
+309eff93d81fceff9350f79eff17b6e52470db03d9b7f2975ebeff27c79ae486f17bccaf
+f238d0ff30f9d578ff2497d9ffaced61dd0ae04bf2d59651faad3dff17f664edc25bcf3d
+ff69fabf9cc2ff50ed6cdfc21baff012bfeb93cb86f993ffb668e02ecb61edadce10e8af
+c806edb71eda4bd2fb84ffc94bd812cffa964ffc2de559c635e01ad060e89fcb86fe79fb
+a5ffaf3bfb05d9ab44e508d95fe76acb0be1c13aec95bff3d861ed7ee6a369edd17fdd6c
+cefe86d3ffb7f79f4187e1acdd82f26afe12d851de06e460d979bee1871aeea5c3fa8552
+d82cffb7f87effab69f5cb75e093bfe17bd8a50cf28cdf88d9a551fe13b4d808ffb57afb
+d868b6fc35db49e5af12d944eec0a9ff9fc551ffb768fe72f863ffcd79f29a08e4b679f2
+86feb860f3cc91d887fe91f29cfb83dc0bff50e53cdc54e018d995c5e369f396b8ff9fd5
+28fe92f66da7f876fe0586b6cc2bfe5af7bc04b8fb2cf2a738ed50a53287e0bdfe23fa3c
+ea50d9b8f670ff9ff986ff95f70a9ffeafcb4cea3bbff28ae0a44193d824c6eb1eb6ff07
+f25faffb39ffbe67fe2ded01cff27ce161e9a5c82aec9347ffca7cf59eff79f5bf9dfe87
+1bf24ddb2be086edd136dab5e046a9fa38e6afcb3efb19e2aa41e7bd03ff4def0edd66d8
+52edb6f67ed988f2c293bff76efe79b4ff1dec63c956edaf51db40edd220dfa1c4ff46f7
+a5c1dd32d8fe9c58d987c7f97bd8f1c7fe5bed78d393cbaffc9f2593edaf21bfd227e05a
+edc742f16efb83b5e516fe65f7caf159e561a0fe86d7a5c6fa24c2dd7ee39ecbb67bfe97
+37c8a8fc86f759fe61bbe4a528e55ad01cd83be05ecdb0d993e683fb79f8169ffa93249f
+f0c67cd886fe6aed88d875ceff9d6de086d97ad0a5f926feab3aa3d324fea90cff479fe6
+23f242c587cefe25f879fbd082ffba5cfeaf53ed8edd6be41097fb8d47c5f579ff0cb2e2
+12864aa5d80eb3f361ff0881e2b4db46c6fc67f4b582fe74a5dd93d806d0ff71dbafd40f
+87afff80fbcd42dc50ed3590e8984bef1dfb52f4d84ae0afff22d039bfdd8dd2f30ccff2
+8ad983efa5fe85fa26f652fe0ad0aacb59bfdd4cebcbfe8811ff56ed15dba5ff55f7962d
+c3fb3bf2b4fe3deb75c988deb9ec58e06ccbee7fecc461b8d293fabe469eddb5e206bef2
+169ae182c7fa39d81bfb80ffbe60e0adec23d0a1e769c2feedb6f681ffcc2ce5a6d8f437
+ff86e57bd8aa4febbd2ed0fb1dff60f7a52bf39e45fbc4ed34c1dc05b9f37afe9ebfff77
+d2fda5d693e010b2fb87f35de593eda218fa409fff9352fe07faaf4bc1ec6adb7be080b6
+ea26ff99f46cffbe8043c0f29bd093fdb32dc0dd0bedafec7ed8a5169fe093ff5af402ff
+79fc94f936afdd28faa5ff58dd17e0aeed864f93ff9e60cdfb35f40ca6da84edafc942d9
+f218ff62b0fd51befb42972ed819e04b93fbc04088b9c862f10dfa3affc40ffed9af52e2
+85ce7decbf5dc5ed9469b7fd529bf69329e1c511d94df405b85fff62acff6dc71cb6d982
+f86affcb79f1c76fe0c1a4e96cd8ff9604d0a5ff16c9fb65f08be01ed8a702fbaedd65e0
+27d94cc7f29363fe69d41dff51f5b9fa5bcd19d984d59acb1cd87dc7fe79d886d901f195
+fe7ef60ffec5d93ec2e984b7dd6dcfff74fe9d5af5ae6db4cd93c0e47ded27ceadddff77
+faa4c2ed679cddff59fb99d0a5c0e079ddb08964ed9bc0f234d953fd8dfa22c0ff17ceac
+e564d2fba568fb86e0c194e6c52ec0ee3cb9ec96e445d710dc44b0e0ad34fb1dee45cbb5
+2c86f2affc39c0ed9533d6ba40c3fe86f2c58ded1fff84fb79f69e5ffaafcb93e5b786df
+6dd82eed76fbb8f239fa61f04de5a407f249ff6ae586d036d96dd8992efaa5f528fe4ea5
+f1944be329d0e902d6fe37f84ef20ad995ff88f56794cfba5bfe1fd0f90db6d81ced50fe
+329af25af6c8fa03ff45a7fe95e40eb6d880e250dd6bfa1dffaf47c0eb30f1a83aff4df2
+a5de76cdf855ff8afb77fec297fe03ed86d4b899ff67fddcc359e477dd9f4af4aeff7ef7
+a163dc51e238bad352caafe004e5cf1dea44fb37f8cd07fe94fd86dda54696d881e0a5fe
+68edc094d5accc3dfe5ef4afff4aeebb69e07bd892caff23d9aec0f763bcff81b8e579dc
+9ffe6fd75dd905e046f234e78ed9aa5eee76f8af7bdf8ff5bc16d8973d86df93c5dd13d8
+86ffcc3dfeb2f584ef8dd07bed98ff84d87acdf786d979fa08fe9f25dda905c1eba55ae7
+6dd894ff57f629bed81392edb624f988ffcb79e256db0fe4bf2ef99aff77f4a5f931a4ff
+7bb6ff89d8a4c55eaee9be3db3d00fffb4f31fffc010cdb62cff51f81beea0c0e99d22bf
+e579fed012ff5aed06bee661fb139fdd9050ef279affc542bfeb1ff086fbc1fe9ed87cf4
+4ffec786dc43cbff01d84eceff6dfeb7edaf5ff86cfb79f259a0ed9301a5d82ddd54e039
+d807dd5afe16b2e420d093d880c7f171d0f6862fd0f220b6f947afdd87ea7cfaacf43fff
+c75ad81fb6fe07c7a5fb5cfea5cb6ad8b510e461dcc14bed36d952f50dff96f277daa7ed
+67e179d763dfaf52fb7af5d06ee09bc887fa0d84d5fb64cbb134adf286d39ffa7cb4f293
+c4fe3dface93dfc10caafb7eb2fa4ccbaf6cb816ffb502e0982bffaced6ab9ed84e57bb1
+ea2dd518ffc024edadcf3abff761d9c1fb60ff9ff5affe6ef8aff39fe76bc1fb60ff40ed
+5bb7fe3eafd8ff61bffecb79e4c107fb51cf36e072d89e79f386ed64d896ec73b9d088ee
+06fd46f7c693ff82fb95bdf999c7aee050dc26ff4cf722ffbaf631fec26ded9ed842adfb
+c134ff56d8bcff3faaf103fbdd67c1eb24dc51e039cc54e57aedb61eff6efa87f22ae061
+d0a2ff28e57be068cbfb79d3f28811c1fe2fa5fb20f844c188fba94fe59fc92eff9de01d
+afff388fe0b63ec71395e49026c749b7ff33a2ef82e2affa14d897e553a0ee913d9cf32f
+fe9ec9abff90bffe0bf8d011e0affb2bf84bf320ff44afe08bd9a052ee29d40de45ace16
+fe6bbffa81d69fcb8bd8a14993eda306f9af24ff88f115a7dc8ae1af48db92e088d87ab7
+ff43affc93ff8af59bff2cafcb74e05ad735e9ca93c1fe14e25ff3c5eea7f842beea57a5
+d9fa5a9ee4cd6bdcc495ffd95fcbf17ddb78e767f07afbd083edc90df193fbbfd84effbe
+ee93dc7deccb0dd8b8289ee885ff29fbbe13e0b3dc65d87de05ed917f24a96e253a6ff94
+46bed0a0de87d881ebc878f22bffd084d96cf0afff7cee93e52ca5ec61f119fb5ff0b6dd
+7ecbe879d3e55bb9d982ea4cf21ffb7ec4f62afe4df41ecba5df5cce32d80fd968d6f405
+fdacf686dda551fc3fa0f280d8ab52bf2993ed9d1effc237afd7f68c52ffae4de00aaff5
+31b1fe0cfc96d408c8b728e057a7ff6dd94981f9a5ce8446fe02f74bafe55af387feb05c
+cbb667cefa78ff09f7a5fb24f186e5a5c6fb6dc1dd60c9f685ff6bc0fe3cfa9912ff5ec6
+b71afb93fec241a5de33d863ffc901fe87d97de00afe39fa28b7ff4093fac83bfeb1f876
+cfa4ed0ab3d36be288d97efb06f786f2a6fe80f9bb5de0963ac3ee12ffbf79e5c649bafe
+0bfb7affd86efdcd79f193ff8022beec06f187fab971d897df54d8b03ffaa4ff66f47cf9
+d34de5b2febd2ced0bfbd99fd1be9afd73ff94df36d3f50bd9f1914dd593e6ba40ccb66a
+ffc051ed22aff130feab16e53aed03b0cc6fe5aed39fe97ae05bdd2f86f7d579fc88f2ac
+59df96cf52fe98c7a5d973e267c7aaed03a1e4930ec99eff52beff68f9bda1ff3bef60d9
+6de0bf45c5ec1da3fe79c7ff649dd87bedaf01ff97ed68b3d3dead13e43aafd90adf4ae9
+c6fe7dd494d92acefb1eff87f976eec286dd49e0aecd1293fba21b88f2d16de189c336ff
+56e025dbc017c5f96d93e09c3bffbcf237ca79ff88f5d8379afe7eb8ff7bd885eccc79db
+aefd68f4b632fb4cf538fea8f39fbfe1a81ff255cd11c1fa78f330e6af3af960beff9af3
+15fb61cfff6dd8fd5ee02ee786d0af40ed17c3e097d283ff1c9fff9357c2f040b7eb1abf
+f72efb44d9f586d825c1e93163f090bdf850febf9ef9b68f3fe05ef379ff589ee0c13aae
+e517ff50bff19733ffbad932edb8e74199ffad5aecb47aee8dfaa550eb9f47c1ff52f9aa
+d91c9ffe87ed5add0aa5fad00fe0d746e701fa4e9eff935ac4df1aedce81dd91d8bb08cb
+4efa03ffc190bcff99eb3ed8b8ff6ccced79e00eca47afdf87dcaf4bed31b6f193d862fa
+1ee4c493fb8650fe21e8a8c2f675e5afdd6dd3fa69afda79e0a5ce91bf4dfe9df775fece
+3eff69d7b27ae65ccb1afcafc1fb35e5bfa9ef6293f3cf5bdb8deca505fed86187f7c67a
+ff63c2de14cbfe20f5cf1ad963caff79fbaced22d886ed6ec5e562d116fb6bbfe24b93f7
+a26cf988cda5bff21ebced2d9fff935bfeb525f970ff93e67cd965ed4ce02ada85fe9122
+a5dd15bbff93f485fcd05bff2cf59bbffb86c505fec09aed74fe55aff2bf9ff3b84aed3a
+d704fb2fff9a0dc2f248febe5cff20f180c2e03cdaaffaa5c4e608f2ce2aff85ee76e50f
+a1dc9314f844d1ff03a0fe79d82df6c45d93fbc1409cdd03aff475fa79b9df64a5ff81f4
+2cb5d404dd7ae561fe06b5fb33b0eb9ac7a9ff80eec15dedc428b9ff34e262d0fb79f8d0
+47bfe40bed98c2eb51d837ffa2ca94fbaaf1b548bee5b3fb82f89d4bd82ed9a51fec94d7
+71e819cb48ffb557f22aacd811cde607d934ca86fb93d985ed96ce7aedacfe80e5a608ec
+6de5affb1688ff94057cdd569afb9361f3b6dd52d886ffcb64fed17feab46fe6ca35f29b
+ff73daafe91aefaffe6af9cc2ed89fe55193fbc044d6afed5cf7b755feafd094c4f258c0
+ff2af94cf034d31cffb13cfe9ce57ad887fe9742e5b570d8fb7ac961ff3da5dd88edaf1f
+e83ed8087ffea2f20bd852ed62c0ee89fe7bf1bf7af854fec38ee0b079edd96dbbff7df0
+a370fa82ff6add13e55bffaf60f3b637dd51d82bccfb88d9c444a5d4f24cc8edf524ffbf
+35c2e09614a5fe2ef2a526edb83efec327fabe80e1af1cc0e43afe51dd79d824e0bd80ff
+5bf224ffc809f096fd1199d982ccf2881cfb4ce77aace072d886d879e09ddc7bcce561d9
+17fb4ced0edbacc906ff9d24b8f393d1affe10f778c8f96ffeb6f6d037dd6dff86de26d2
+fa04c644e559ffcb09d9af36ff63f7ce3599fbcb44e05effbd4ce0b0ef53fe7acc27c0e2
+15ffca87fa91ff984ced2684ffdb66ace49f5d8ed883eea6fe44fab8ed79d865c7f95692
+e29f69dead11f260d7fb62a5f381cbaaff57f2a537ed96d093d87bb6dc86d85cbfff41fb
+2faae0c099f326bfff11f4affe02f687fe55f206a5ff83f2c39ec0f66afe7ef154ecaed9
+46fb1af079cf5dda32bedfa24a89b1ed86d55ae89dffaf77b6ff9ecfb93aa1e486ea9abe
+e510acfed51787f8b5dc37d2f59326d0a4c7acfa89fe52d89e4eef1ed861e0bfa1f8d896
+0dfbcd1fffd0fc53e41ad87cda86d239f6affe4397d6ff08cdf549ff94c4fe4c93f0d808
+b6ec1597e584fece67f610fe4ef73ffe32eda7e174dec293ff4fee77cea5d952ddc4449d
+edaf2fbfd988fbbf39d5b65fe83cb1e02cd892dd83f568e6a4e068d893fe86fb970cf2b9
+ff26c2fe19f7af3bc74eedd861f016fbaef475fe23fb43d694ed5c84f3d89f0a93fc9d19
+c1fe76f80eee41d1aaf26cf8ba77e5aff512ff52c238f4c15793ecba33c69abeff63f507
+ff5be59802d9ade573bfed79b6d886ed2fa3e9bf4286cbff69fac943d90abae44cd987e0
+afd2a4c688fb2befa20bec7bda17ff39fa89fe7994e9c04fc5fb951fea4edd97f826fb93
+ff79c6fa5bff3bce0affbc2dc1ff42eb19e54cc3ff6adc7ce29e58e07acef283fe9531e0
+7ad886db27d061d9a6f185ff46c7e7a741ffc6eb79e2afdd4be395d866bbe80999de2dcf
+fc9442c9a5d48dfdb079e0abfe8661f00af748acd98cca9dd86bffcb6def1dfb35abfe1f
+f951affad10dffaffb9f37d986b7f69efb78afff6eed9e18f25aff01ccb567fad061fa87
+c6afe55bed0abbf827ff8fdf6de2c1a5ff79ed66b0cc08d8bb179ee5c195fba5ca79fc86
+b6f49fcdb9a5ec88d516fb45f5d092ff1fa5dd0fcbfbabff40f35dff80efb751c802b6df
+9720fbc060b726f35aff80fab138ffa2f66dffc986fea502c1ff76fb64eb04d0ff3ef218
+b8e0a5bf93c5ea25f14cfa22f0bd47fb93bfd888e761d0a1c2e06190e36dda22d3f45bfe
+21d65ac1eb27c8b634fbcb7dd995eb7cfec143afdf34d8fe639ed885c9e56ad960f114ff
+4bf835cdb911c3ff7df155fdaef4871ced4edc35e454ef02c85cff69f329d956ed98cbb5
+07ed5bc5fb71f5b7891cc2e69ac9afe013fe93faa3f472fed079ed94fbcb88d831cf01ed
+c65bd823e0b53be55df2afed86dc1de09eef68b8dd7dcbfb46ffe530fe76fba1e080ddaf
+86e0b639ff4ef7bc96ff39f314ffc831f893ed6db4e593ed80ff39a4fe84f8d868beff29
+f655dc24f29bff79f5ac03bff725ffa33ffba5d098c7aad293ed65fea4e041d997d46fdc
+44d9bfabff93f285d89cdd80e136db93fc7bffad5ff878fdbfa0ea42b2d052daf960ba08
+f74593eb7bdc29e257cc30a5dd07d93ea7fe68f086da9f79f988fec17efa93d827d93ad0
+58f2c43fbefa2baeea609eda7994d889d658cf32ffc15afe19ed87d3a4c906e058d885dc
+78a8edc34abdff01c644ade06beed461df04a0e846a5e08cd094e56fd810e6c469edd251
+dc73d5efb61efe54f47afb0bafde2ef28af669fe29f793fe6bf95ed013affe23f84bfeaf
+faab06c1e033cde721d89335fe86bfff25e582c6a5ffd86dd3fbc349affdc392ffaff368
+ff82f6d012e0b6fb57ffcc16ebab48d919ed63ff7df794fea96dff86cf95fe12f2c422fa
+ed5ae213ed93d9a60bf379d0aaf912f46dfe7ef29cfb44cdfb5a9efe7ad0a5f7bdfe10cb
+b51bf295bfff81f7ca50fa16ff4bb6fc8db846ffb56dfeb9f3128ce083afdd24e45dcaff
+6fd879d119e086e8bf05c3e225de79fac66dea94d1bf1d86edc661affa79bdff63f3c4d8
+01e45df16cfe2eed5194fda51d84ffd8864ced11d847e1b6c74d93e8a53696e02ba5dd86
+cdf475ffbfa2c1e04fd816e5ba20e347de6fd585ffb26a01fbaaff7af96bfdc49abeff58
+96e383dd30d8b61bb8e49505bfe01fdd3be55186d998fa7cffc354e236d80fb4e97ad886
+cdee31c1f896ce23e2a13894ccff47facb6bff99d8b642ec9efb52ffaecb3ea0ed78a8ff
+89eda351dbae39ff61f5d455ff96ed13dd4d9de0af4ba9fa87d89dd990d787f5c02eecb7
+dd9d0cf6bfaef86dfd9e1bf1affb6effb9f46abef251ff309fe19343f906a7fb8ef083cb
+f578feb6f74ee03bd9c0a5cb70c6b61ede50e83ded29d9fb40cbaffc53f9a6ff6df7afff
+7cf295fb88ffc02df153e640a8fb7af59afe6ac2fe3ff4be65aeec1bdd5cf17ff9b1fc68
+b5de8b05edbe3dfd86f7bf03c3e9995df2afff4df3c959d829cbff0af1be7ce38ab9e524
+d988fe84f2c10dfb86de62ec3bff0bfa49e00fd9af61fe3af3cc69e03899de7dcbff5edd
+27d84dd90dd0fe88e57cbdfb0cc4db81eccb31d869ff52a5d997088aeb9bfc77e6ff4ff2
+3cf6d086f294d86accb179b8f1649dec81de31cf4ed82cd95dce62d819e393c7abd088e0
+1edaaf43beed2796dbad06ffd985ff7dfb9cc608e04ce52dc4f2a8d87be5a728d980ff87
+39d9fb11e07fd89d0ef896fdb67ae168fbcd10ff419ff9b73eb4d839ff81c6ee2bfeb0ce
+93c7a9ee67ff79f7c593e55ca5fa88ffd22bef3da8d87aed88f77ffbaf3cd905caed6bb0
+f758feb968ffb6e407bffd32f2b9ffad1cbfef2f8ada86d89d48ffba10febff704fed822
+ffc50fd860ef91f383edaffe0cf9a5f472fb46ff07f7b1fe60cef282d2aff071faa0c542
+d158d8af36ffd178f39ffe8539fb4eff0fcdf1b948b3edcf6db5c864fa31fcdfbf62dc3c
+f699c730a4d981edcb6de0a7ec6de5a4d946afd89415fc60e679bdcb9ede4bed01adffc0
+21ed5bbbfb96bff904feb0c61fecb876ee65feb241ffd42adf9f22f394469ef9ce5dd862
+d93fd0f95a9fd8f827fe07fbaec979eea54a93e0a15ee84cabfb92ff7ae30afec13ea0e0
+85cb54df9ed87dea9b5bc0ed8b0afb52ff1bd837e77bfd8bef0de5c15293d9b716beddae
+cf93bbf3588efea2fa20a5ff2af4bd93d0b68644f1c1a5d01dffaff34cfabd16fe4ffb03
+f9bf26fa96ff6ff4bfa0f223f939fe1db7ff90c1da44e084cfaf08d964e683e4a344ff9c
+cd37ffc39cd77be3985beb79cfe679ddafed2a89eda0fb7bed83c6affe65b4caa4dd64e4
+24dc60e5b6ff6fc8f385cbe551dd25c69fd2b679f7d064f025ffb20ff2b73bd8fa2aa9ff
+c1a4dd7be489fe5cd820e0a0fe74f5aafa29ff7df652fe1bed62d8afe514dd64cbe588d8
+56e616ff60d9fe8f05ff5bed6fd87be0a55add9acf8ed8a558f168d21be052dd42c2df93
+d989e46dcf33fb63f29efe46fbc386fe23d75ec8f26ce57ddfad14fa50f21bccf6abfe4a
+befa17fe85c2ffb318b7de0cff4ae50fdf37f253afed92fe81fb36d81bde32b7ff1397f2
+81b6eb43ff5ae5a72eff9add81c6fa6bccfe79c593d94de030bbf948c7aff385f9ad3cc0
+d91dde6ced9de093eb73d6a4ff30fb72d388ed9f51f67afea5d795ed23a1ceea7fd987e0
+3dfe07c0ff75f525f261fec590bbea9fc1f787ffa54cff7ff344fba0e97cd8b511b8e36f
+f2b452f49fff26b7d00bfc57ed86d8ba93fbb7860fc5f29161b7d05ae03ad986ff51cf94
+d886f198ff89d4ff33ce4dc6a1f17af888fe52d0a9fa3cd8fd6bf293dd14fcc786d85bed
+34a2e525a5f113fe70f586fe66cba5f10b9cdf52cff268afff86d85ccd43d809b6fa41cb
+96c3f24bff30fcc20adeb636f24acaaff438b6f72afe9fefc394ec33df86d67ce033ed09
+ff40fb7a32d804e4b3cb14c5acd50fbff929ff94f688d917e9c68ed872ec51fea4bdca93
+ff48ed31d153ffd99733c2ffd93ff79dfb60f3afe465f223fe56c379ea1586b6f787ed0c
+cdbb48d3afec79e467ccaf02b9c925aef1934bed04fe89ceff67dcbf57e4acec02d0afed
+15ff82e5c12eff87bafa34c4e704fe88fb79ffc786e07dee019ce0b8d96ce0af5dfb86c3
+ff68fb75e557c6abcc15b849fb64c9b0fb4dffaace93b8d888cfaffe9bf17efb78f192fe
+69ef5aa5df71d835d456ffa540ee0efa88db79e740f81fd3a7c0fe81eea546fbadea0293
+edaf0cc6e89329c0fe79e7bea2d9fb61c0fad81ce0abff66fa98ef099dfb2bbeff76d9fe
+69f6d760bdfaafe179d9a54ff392ff87d342c99eff3e97d959d844fbb579dd13a5ed9556
+f2b7e320eda84bf421fe61bfff861da5f73dfec598ea02afd81bdd88ff7cfa67d8ff92d7
+a6f71993edbf0ef74bfb5bf319e864cc58d72edc51d928e086ffca49edaffe7cf385cdfc
+7ede9acf30f294d8afed60fa0997da20cbe56dd87ef8c96ad8ff8648c4eda038ddab42f6
+04bfa5e05a9bff9350bfd824e582ffd95ab1f417eda139e0a545ffd98c33bff71ffbc50a
+de38f49cfb62f179c7f77bfc95ed6cd0f65bffcc79febf873ba5d980cbe56cd9c2a6da5a
+ebb2ed7ad086e227bef979edc098f20cd843e3a653f222e95fdac43b9fda80e096caa8d8
+92f610ff86f49fff7af7a5d11d96f7c1049fe026dc60b6c838ff5afabf02ff4fa0e079c4
+f271fe65b3ff29dd59b6fc3596dfabf505fbd07effcc6de04eff2df3cb3ed7f579fbb4c6
+3bc18cc5e086d880facb7afbcf861ac3ff6ca9e06caeee7fb6d816c1e022daa52ceaae1a
+c6ff0193ecbe4de025d2ffb3f860fe2cbbff953cf72efb93d846ff13f353ff6dd9a72dfe
+4ab0e095ee84fec09ccf7bff86feadf569fec221ff3bfa50afdd94eb61cd07bac743feaf
+e05c86ffd06aed88ff1bf6af7be0a862e07fc9fb27afff3be3b7f607c1f093ff23d1a7f1
+1cfe7bd98856f21798f993ed84dab06deeb602e44588fe9ef71eff38ef4ce12195ed0d9e
+ebafdf4dedcd52ffd159fbcb7bfe86b0fa6bffcc73e0c0529fe2c2319bfb88f49b4aed15
+d596f29110f0d080e0c008f2b784d88cddadcf3bfbbf6bd3f978ff31d910ec38fbb704e0
+51d829e040a4ed7de49dc0fe78d823b6fb99ed80e86df230fbdaa542f8afcb50e46dd3f0
+14d0fe9bf6198eedce7bd8a04d93e89f45d962e588fa60d8b94ab1ffc1a5c5dd31d01ffe
+c00dfbc37cfe8fcef25bdc78ecb795befea5c4ff62c1f73ffe78fa9811f19e32e9992ae5
+52ed3bbfed08affb34feaff37afeafda12d861e5ca84dd73ea4dc3e0a55bff9f67fe56cc
+f969fe9a0eedb95aeedbaa24c75dcd8af77add67e5c96eedb5ff79bbf96bd9b413ef31e5
+5afec637e053fe0bcdb88bbf18c2e1930bfbbb98fe4bbcfb9229d953d5ffbe47e512edbb
+d96dfbcd83f3c03bafe27ded9de521ee4cfb72ffa8e9955ce0a237db5ad921afe811afd4
+5ffb05d064e852b0df7ad993d12ebfe186c7fe77c5ff6cdab6ff64cf95e05ad867dc21d8
+3ef163f9a8ff0cb6fb3fffbca2f96dfcc10dedadc4e4971fe941c0f67dffaf860bff87f3
+a5fbba46cbafff4aa5fa931199f1d305e749ff86d0af84f2a569f993d0bea2e54dffd881
+fb5fffcf62e02dc3e79442c3e56feeb56186f8a4fc86ff32f21da5fe0a9fffc510fe31f9
+63b6d893b8e545bf69ccf97bffaff496f99fff79befd3df286e37dfc2ebff925feb207f3
+a5ff71f820a5e004a4f3930fa5e527fe86f6a1f293ff6bd083e1bf49c3e87ac6abce0ae0
+33d844ddb651fa2688ffafc9a3df61d825d7fcc19fed4ddd01e7a2fe1796f2d827d0fbc4
+4886fec192c5f343ffd80acbedaf16ff39fa7af19d3ee7aced38b2f28afda506ffacf384
+ffc136f5d8b62cc754b2e081bedd73d2ed4feb87c1dc79cdf43cff12d287f3d9a529eb4a
+d718c84fe041cced67dda5c947f3b895ed77d869efc860dd39d95bd4f279fad843e7c7fb
+7ed9b643c40ec64ab7ec94ff1c9fed9358fe27f461fb78ff93f67afeca82f2cf43f05aff
+1afbaaf2934be039d2b895ff6dd886dfc23784ffbe74e4a5deaf55fa29ace568b8fb803e
+d8f18fdf61d912cafa9327c8a5dd1bd674edcc79d85adc0f9cde930bff90f4a6fa68cbff
+3ff8b866de9bfb45a5ff099cd97eedaffe0354ffb3c693f18bffb67bfaad2cfeb916ffa1
+d65ada08ffade445a0fe81f6b6feaf44cbbd66fcb7883ef260faa7ff8ef4abfb06de56c8
+f732fdd08ddd9ced88dab81cb1eb2b9be560a5dd8fd87be4c33a8acff57afa82fe26bff0
+2bf850ffaceeb14df435ff1ff09ad6b978c6f02f9fddff87c24bb6ed84ffaf63d8ff86f7
+79ff57f53ab6f820febfaff25dfecc6ce03fde03d92a9ee4931afebe21cdb0e581c7fb62
+f8974bc2e4f586e011fe52dd34edd00bdf98cb82e06fed1dff80e5c23388ffce1cd8a701
+86ea96ff16afd91fffc09bd216e951e038d95ed78af0a56dd9a504ef51d819cb4aeda4df
+52d2ff13bffa02fe35f6b578d9ff05b6c81bde62e358cbaf79e98ad61ae094d88dc0db5b
+ff15e1fe0296fac250bc1ef7a5fd24b3d52cf5b70dd84ce49cd987dd68c0eb9351fb2de6
+a549efb1d095fe86f2c35ef1aed086f778ff28f35bb5e02fcbf26c9d36d862ed9fcfa5fb
+6cafff88f352f72afb93c7aaf44299d9f3bc5ae569edc6fb28d860f5d086ed6de22fedbe
+93d0a5fe84f876fe26cdff46fac080ff93f5a5ff7efb6af4be79b3ed6dd981edc10afe4f
+a5ee62ffaf88f49dfe86fab908da5afe68f60dfd62b4e97ed89361c4db79e993fbd769dd
+7acbf95dedc16fee7bfeaf04c1fb26ff9f43c4e083d877c7fb8815ff52afe26bfeb54bff
+39ed5add8cd893dd1bbfffa61cfec8ee80ffc05ffa06c3e626d846c1e092d9bf3de561cd
+affb84119ff093fb3f8eb3e17ded9d38fe4fc9a1ff87f753fd23c8b810e6afdb79b1e578
+dfaf31e056d938d005d9af38fbd851ffafd04c9cdf86eccb79da30edd03fd90fd839cef2
+7deda7c99ed1aeed2ec5f545fcb6f750ff10d149afed06ff429fe09334fe9ee03ccef29f
+5ee57af1afff06f7b0ff1badd8eb79c6f539d60fe0c193e06dd501f04afe73f69157ead2
+79a50bcfaf25e088e27ab8f880fba001ff4ea6f987fe15dd57ecc5fe27dd78d0ff59c2fe
+4abae579b6f906d744addd7de069eed68835ffbb15c4f31dfcca7afe89f996f286ff9fc5
+26e0951df4abff6af7be21fbadf877b4fd6bf681ffa360fbc221ff51f94293ff9e6fe0c2
+299fe080b4f299ff82cd93e4c002ffc5d949bff78853ffd393d817e060db9f37d994f242
+b8f9229edb93ee73fb16abfa85ffa3caabe043d5fa933bdafbbcf84cfd6af336ff4aa5ed
+62b8e57bd0ed0cd976f18bffa549d886c0f50cbcec1aa4d4ff0dceec86dd7bfbcc09f197
+ff2ca3f3c75dd8fb9866d886b6ed10c65ce161d817e967f75efcc878e22cce3f99e49143
+c1e012bdca99ed54e3bf3e9be58aec7bbfe008bbfe1c95edbe3bf4c823d937e061f675fb
+b0865296fba724eccaac11f96dfe87d37bf2c86afe7ce564ccaffc7aff5ad09ac4ed35d8
+be59ea14c3ff9f06bffeae5be479dcc59abed897c1dd18cdfe38f7af6bff9fc94cd128c0
+f6b4fd3b94e09d78f9d9308df3af34ff4defb76cffb141ceaffb469cf79143c1ff3af148
+cfa1e9b71ffeb6fa82d393d8b046f9be91efafff61d0fe935fff52e52cafd918feaff762
+dc03d8fb6af3cb68d7f974ffd05aa5fe6df7a1ed29d84ed1efb7e414d0fe9538e6be50cb
+aaed20fe4ba5ed28d2a9ff32ed51e509b6f62bff79affe25f596fb5e86e5afed6bd8952f
+eeac12ff4ef21dfe75f59d5cdcbf21eab82dfcaee993e07b04a0d8fa5cfec44d93f1c854
+e093c6a5ca27e587c5f964e086cbe607deaced70e59fff6bf779ffcc8745a8db3afe0fe5
+9fd90bff50d816eaa00af1c5acf276fbcc7fef87dd25d084fead31ceaf38e6af4be30c89
+fbd786dcae54c1fe86f2991eff7df3904cc1fa7effa5f136c0df86cffb62b7f90298d98d
+d886caea78dd53c6e568b9ce6fd9b8f136d951f721ffcb59fb86ddb693d885e539c7f093
+63fec486e35ff319fb50ffb9ed6bafcc2bedaeff67a5fa71fc15f662fe55d91ea0ed14fe
+73bdff63f91fd9b708b4d828df4b9bf6bbf072ec65f27afe68b5cc94fbb779fad77ae520
+95d9a206ff5cd779ff52f3c478b8ff7efa85fea1cbaee5ba2ded14ffd80bb6e53efec960
+d831ddafe064d91ed886fb9d5af3990fc4e979c1e44dff1dfba543fdbfa2fa07afee41fe
+2b91c1ff7bd088e0a8f994d8b93ef661fbc558ffac0effd8a551f279da95cba9d587e451
+ff13f2be86de05cee822d9aaed93d8aff174fbd07adb5bf229afd893d07efe8af55afdc1
+aedd31e001ff96c7a5d022c2fb34ed63c7f24cb6ff51bffe38f7c0afe72fed9fe5b23af0
+da10ed50d214f23aff5298fa7acc5eafeb62c4dd7ab4e0a4fb6bff01f5a1ed5be008cdff
+3bd9adff40b1fe69f3aec86cf2d6871ff288c0ff7ce099d2f40da6e328fec06e43ec03fe
+93d5be09a4e07dcfe68830f7d306fec23aff4bf831b1d882df8cfe39b6fb519bffc039cf
+4eff0e9de0bb4bffc0a7d394ef4dff35ed4cdeacec960cf261fe93d0b829e442ff98f16e
+d885e126a5dd2ecba5ed71d061e04697fab608c86dffa459d898d98ce093d987edc346be
+f193f880ff9d33fa08f651c1ed93d6b942c3fe7cf678b5e56bed75bce025d99734e6be16
+9bffb3cc49e155d817fa5087cafb78ee9f14ddff9fcc5ef02ffeaff249fb299ffac16894
+e0a46aee85e5c1a0fe25f7c046d4a2f079bee4865bfe7ce585bffb2693ed9602f83efe6c
+e186dc9ffbbf2e87cdff7ad8af55fb78f7abed87dd4ae6adff5acffe84f56dfb02db85f2
+8ffecb67df93fbbf1ac2f986ff28f75ffd66d308fba5ff1fdf3dd917beedaacf94d918b6
+58fa7dff952ed0a5ed19c2fb2ed1fa86f180cefa62feafde3deb73fe9bf792f07edbffa5
+3bda57b7f57ec12be687c2e077d987d891deb954edafff33f5ba0dd89b11f164e55ea9eb
+6ddd20cffb1cd8edb4f32dcbeb69d4ff37cce881dfa5c60dfbb91ac87cd9fa3fb8e420ec
+c23cbdd85ccb09bffd9113c0f29406e45cd887e5afff2bd81abaff36ec4cd995e525de5c
+edaac91eeb7add85e06bcb9ffe71d6fb875afd67ff87e4c523e562f0affb48beff5d93dd
+9e0dca50fe10a5db46f069f893d90bdd30ce45c6b51dd8f381ffd34ae266faa5ff1a9cfa
+3dff15f661ffd108e259dd79d0ff5bface7bd991cbff08f793ff885af4b88e01a1dc973f
+f7b67cddaf4fffbe25edabcd76f75fff06bee864a4ff7ff3a5ff19fa81feaf32c5fa9a3d
+ddafc2ff23f39e3bc1e979f05989d6acfe79f56afea5ccb878ffa6c0fe50f335b6ec5aab
+ef9343c3e523cba1f03dfe9ed0bc0ae06ddc81cbacf454feafed93c6b0ea7ed086d825d2
+58fb7abcffa2fb6fed68b7c80887fbafb9d945d0afed69cc79eba8ca2499fb83ccacfb42
+a5ed7abeff18fb4196d8b549b8e0accb42fdc5fa6fffaec90af261fc9ec777f65efe39f1
+9fe594ed5aa9fbcb4cd80fd479df9ee861f2a1e54dd5ff7cfb43a0d960cffb934efba5da
+c2f60d9fe02bd0be4aea0ad94cf2309fd992d0f603ffce20e0afff6db2ea2ed4bf85f24e
+fb93c4ff20f83aeb05d883e061ff3cf557ff03fbafff79f1c4a5ed61e702d797fd2cf7a9
+edc31ed87af184f835b6e5a2c53bf2afed46b6f31593eac729de3cb5eca5c0f36bfea5f2
+0ffe81e66daf4ae018ed61fea2e42eed12dc99d986e054d81fcf84ffd61793f888fb95ee
+59cb24d886d96aefb41ce55bbff786fea913e0afc70dfe4786bef364b0ff7bfb93f58de3
+7eb8fa1cff5586deb978fa61f206d9f679ff60f90eb1da70ec3fafd886de95ff64f62dcf
+a3dd7ad895e1c13890e09f3afe1ed885b6f24bafdd84e04195ff4ffb10db61cafe04f755
+fe71da7affc96ed9ff4c9efb90f286d12de051db22e379d766d915ffc6ef86d693d9be44
+b5d886fb59ff2ec9afff92fc6ae0369af0c231e050da2cf98eff51fb06feba71f6c48ae0
+0ed843c9f46aff88ed7db6fad83bcbed01dd32c753ff38c3ed6cd5a5c0fb9949e7c1a5d0
+8abb42d89db8d888ed37ffc1a0f36bfdb646b9d988b5fa19c0fc21f34e9cecbd10f9c093
+e552ffcb79fec75aff6bcff387cb8de593ffa55ad990df86e810d89827fabd64c2e102d9
+5cfe6dfa7bff86c89aff34f99ef19529a5fa58ff22f88cff6dd093ea7db7ed0c7be742f3
+afc0fe51e5a1bfff7bc9a5d86be0bf9ccc2ddbaf33ffa5ee7beb82b6de26d942d0e51a93
+ff779bf883b6f29cd1a5fb0fb0e54bed2ac4fe9330ff51dafe83fa12f34bff99cbb615e2
+56d60ce0a7f113fec779ed86b5e06dceff6bf6d06fdd5daef39b34e2149eed25d8af0de8
+37fe54d728c0ed73ff2ec6b3fb51f4add81eaff777ffafca1ce59fcd04bdfb3eafed86d0
+54e1b6da35cd83e0b0eb05f14ade19cbfe79f8c0a5d28708ed6ed980f503aceb42fe0df5
+a93bf75dff7afa93cf48bffa22ff50c2fd7af25e9cfbd458dfba43d9ff61e623db61bcff
+85f979b3dc0ecbf285eb9b28c7a6e793bdd226f077fa8dff97f779fe7ee5a236e351ff38
+bffaae29c945acff29fbcd15b9fa8ad4fb63b7f875feb6f19fbeed86fb18b8cea0ed62a5
+dd80e06afed035dea140eda8c549edaadd6de8ca61dd21ff7ff96afe73f5a54786d9b9fe
+66f6af39da51dd22fabaffa3ca26ff5fd0f16bdd86e17fcaed83dd93ed01e277fd9860dc
+86e4983dcdabffc02eb7f611fecfae14c994fe81f3ce40d816cafe7ee5ad4cd816f8affc
+3ecd5cfe69fb85e05dd928cc4ed331d84ecafb7bd998ec9311eda4fe93ed84e6bb66efd8
+61e940a7e5cd3ce0c466ae01fa49b2d398f54bfa0cffc030fe45efb689f283cbf965ff87
+f57dff2cf6b90bfea5ed65d409df9fe411d8bbfe9b38a4d885e09cc4ff83ec975ad849fb
+a9bfe38933fd9fce47ff22b7fe17c556d2b0f218e6c3a5f808f4b0f90587d9ef66a5ed93
+5cfba1ef3eafdf069ef792edaf43f164ff93f5b771e087ee7ce003ddafc61efeabf180e5
+88ed9dff69b6ed09d25bfdcc7bd960d809db4f9cff9343febe86ff0993ff9d21dfffc593
+c2ff3ae080d993d857e394cca5c609e551fe1098d836d90ed65ed89f59f2be4ac3fb8af3
+c03ec2ff7df22ce5b4ef1eff4bfb03a9d844fdc892f182e61194fbb2c61bf3bc97ea79cf
+a6e69ffe3ca3d853fe34bed167dd85e8b93693fec646c0e028d864ffcc79fbc75bdd72fb
+96cebf2cdf5bc9ff4cd81cffabf79a45eba5cd36bfff01f6c01aaff226c0ff87deb049ff
+1df8aff47afed706e0abca1bedc3afed4cbbf58656dc26e779ef66ff21f186f370ff16f8
+61ff76d9abc1e579eeb6fd95f285fbafcf83e59c32d851affb934cdb68d180fb6dc7a5eb
+93bfe573eda30ce033d868fecd40ee58ff79e561affc51f830f368c9ff6eed93d976ffae
+25fe53d8fbc41fe28dff71f27fe5be1eed48a7ff27d13be00afd9fbdfa04a8dc7bebc255
+89d0ff6cf883ed9f52dca55ffad87bdda54bf02bf6a5c3e58a40cab63bbff270fb86f79b
+5bdb79fad077d9f385f99bd80bc7aece5fc52ad1afec83d892edbf2eff4bfba5248ae43d
+cf16df43fe1ef7bfff93ec19d8f6acfe07dd4cb7f261d12bf752fe28c1ff79f9b2f24eaf
+d980e0a5d92ef2c707d879de8fd8b627dab00efbb648e3be79f19f4cec80b8f405d1a5fe
+3499fa88b9e77cf288ffa5f26ae979d097e532fbb339d9f128b4dd0ed862fec76dfbd087
+37fe57fbc899d886ea5d9dd4ff6afad964afce25df4cd1f32ae4950ffc346be0a944fea5
+f741fb9efea5fa3a9adc23fb429ef38fdc6dd0ffc358f97bff93ed7ab6d87f04ce62ffb7
+8728c3e787ffce0ffe99e47ed988b6e04fd8a51ec799ff25fac10bbdfe549dfa88ffb511
+fe5ee479f3cb61d6f27dfacf19e0c096ff5acb87e546c9afe06ad0fe18d861d9b84bb5d9
+21ff45fb5ff2c569fe79bffa60c0ff87df14b7ed21b1e6aac2e09418f952ff01bffb22b7
+ed0faaff30f9b579ff83b5fe57c0edaacbbe15ffc269e07adc89ed05e079caf24fe9a6c0
+e161cd07edb839ddabbfe030d860c9ff4eefabe597d959c8ed9654f33393edaf59bfff17
+d0f97af286ffdc6ded7be59f61ed7aceafe065dc38ed94bdf19dfb429fe79412c93aa6ff
+84fb0facee38fc95f361ff10f64c86e2aefe01e493fe7cd587edc18eb816d8aded07a5e5
+9651ee9ef57cd793ff4bf70586eecf7de375b3f27ae585c6a0e087ed7fe7c238ea11cca4
+ff8a4afee1b275edb61af2bf31d3b952ffb66affc25efe18f67bfe5b9bf76ffe0588f0af
+fb1192e087fe43f527b3fb6dffbfa5c1e079d8fb3ea9ed943cc614ce45affb05d84cd0ff
+8bf63aff19f2afcd62fa41d01dc6afff2cf6afff89ea5cd96ec3dd7bd9b61cb8d883dca4
+c3f0953abeed60f42eec5dddaf0ccbff86f83894ffd23bfbc92ad84cff39f274dd89ceff
+5fb6fe3cc2df31d84dfe35f354d860d304fe9fbffa62d92fe5d67f5cf6d82dd0ff5fa5fe
+7bf697d813d9b003e086d897d793dfc01bed9fc5fa9847d0a6f4af24ccbe71c4ea0de041
+d91afe49fa21a1f2cb6ffbaffe9cf5ba65c0e186ecaf1cca5bdf85d89528fea4c1e88cff
+86dd6bd85ad843e0aff231b5f826fe50f59ffe2ff9b543ff20c0fb81c7a7cc9ac0f737fe
+9ff347e69fc1de4e88edb77afe6be19acca9c715f042afda27d8a5f583ff95f0a5dc6dff
+22fb8ad96fe04593f07af8b103fbcc3dacfc5894e4c24edd1de561c5f572fba3f240ff27
+f947ffa8d051e760c1fe86e953d7fc67f99fff79d199fa81ef88d46bc2e58909e055da61
+e337d8fe2896ff36f4a8fe9bbff744fbbe58e0087af34ae504ef87fe7df7c10297fccf62
+edafd286e95ce36deb93cda5e852f21dff50fa11a5d87be06ab2d023ff81f2afcb17e493
+f4b00afb5cfe9ebdf971febf8bed13d65bcc19d880ec88c9afed51f2acffd21fdec36bed
+a1fe96f083c8fa09ee87c0ff86f99f45bed131bacb69ed86d979e587fd28b6db1cde3bff
+77b9dd13e03aaffb5eaadc52b6f79dff5abfff97f222d886ff79a5edca69d886da48ed02
+a5d978d0f486ffd9a5cf75fea5c51dedb779fed83d91de9f44ff0cafd992d003f261fe86
+d979dd7ee285d8fd62ed1abefe75ed5fd809f971ff53d827c6f17ddd32ea65d8b30ee050
+adfc96f792fe5afa08b7e5409dfec41884b8fe983effbb2688dd0fe047b6d59ffb3fafd8
+26e1afff79fd82f7a9b7c814f330d965ccff79f76bcbacef339ff283d8ed25c1ed14ffcc
+05d938aff630d27bfbaeea01cbf947b5f715fe6dfa92ccff5aee9e37c94cc020fa9cca51
+f9a8cb2fe54daac6ff0be5bf94c4f72afb7affa8de2fd50cfe9fcf26f0af3cca85ffd632
+df93fbafe55adca3f280ffa449e5afd095fb28cbf67affc92dd83fe075dd8bcff67affbe
+2f8fd9f15487ecacd05fe843afff90f378ff29cc9bf279fe8eee19e853dd09e04beba0ba
+ff83ef9e0aec95bffb0796e0c14cffb76aa7ff77c6af86e579f1d076de68eca04ac1f19e
+62e088d3a4c6b723e262b9e517feaffb93f0b55fed32dd6be284ff88d5fb67a5f27efb69
+ec79d855e0bf50c2f393e0af44fab759ff88f5bb4a98faab12c84a9dfdb532b9da60d1fb
+931bff4ec0ed9346eab686e579f1a6c832ffa448da11e4c8f94abffbd70dfd81f8c1f2d0
+61d91de082ed61df0fd83cca5dd887cf9eff93fb7ffa62cab040fbd8ab36e556d8f661fe
+88cb08f2d03ed8f45df942feb613edb8fd0cc6ff8733fcc30eff3ae452f1d681fb35a7d9
+62e00add67ffc194ffb0fc0ad85beba113eecb5ada19d84affacf49f24fb9a5cff73eec2
+70eac695e008d9ade46ccef67bffd81bec89fe04edb138c1ed84e5a25effa8d109fa4bff
+c003fbbe68e8ba68fa9752a5e6932cb2e559dd199f8632f5affe51c5a5fab4ff6cf686ff
+a4fa2eee51d223d83be30df7c25a88edbe81ff7bb6ce1ded94fbb57be5ac2fbed89ec781
+ff9449a5d95cddb9d86be6b680ef94ff9040f398c5ed86d27ef29ed03ce513d54aa1ee93
+fb27bcdd952dfaafff86e1c01487edc579edcf39d818ffad04fb33c4ff5cfb1ff14eb6ea
+2cbc84c7f35bcd77fe99f956db08fecb1ee062ed9fd0b587e87cf3b117fecc85efb6fe02
+d0ff7cc0f270d8ffcbed9a68c9aaea01c74b94eb9cd608d962c788db7ff0a5ff8ed879e6
+b7ff18f9c523ee48ffa5c65ad62af761fd95ff1cee4de035dcb2fe81f9981fffaf44facf
+6ed808c7e5af0fff50f726ffb02aecb67af786f3cc72d97bc7f859fed09247c2ed3798fe
+d13cfeb40e9ffb8adb65e0c07ce7a374de93d28bff7acaa4edc13faee096d916e086cf9d
+f279b1f781fec352f423fe47dc29d7ed9e3be01fd881f2a550ed38a3fbb84ea70bffd82a
+fb5cf781fdd02de053ed7bfea5f711febf6ac1f251fe2593d8ae68e1af8ee586f232fe80
+e095d803de8de879fba5f868f01be63cc4f37acef2992afe5bf6a54efbc17cdd93d85ec7
+fa85fec756d9af35fe1bf19c3fedb761f1d9956dfad85cafe469d8ffbe4df1b7f63afeb0
+43f9be28f352da02e444fe61f894fb24ff86f6bf30ff49bfde3ad8be3494d980e06bcdaf
+ff864fc2fb93ff5dd93ce0c395fed90793e5f7c05ab0e28fd894d938adfe7cfbb1e021d5
+59e0af43e601abde81cbf439feb83bfcd102d860dfafee53ff85f3af57c5a9cf09c9bb92
+d3be93e04deb1587ddc1a7dd7aedcb66e0b61dfe77e5974ede10a8fb21ff93c0e367ffac
+cc1effa607f7be22b5f106bbf64687e5d58229a0d886f2d169edca78feb7ef85d895d80e
+dc56d463eb45a5edafd968fcac6cefa7ff15fac1a3f25b98f7adf16cd079f4a9fe65f71a
+bc60c2fe3a6cd9a1fa77ff20ef60e6bf13c9bd399af392ff7acafb85fed032fbbc79dd89
+cff263bcfe79f89a0fbfcd22e069d1fb31ff62f558ff2afa5dff70fba5bfff40fb12b9ff
+26adfe2ff9c09ff206fdce7bedd779e060ec43b2d104e679e086c6e566d7ff7ac3fe73cb
+aef81d99fab4fe6ddd19b7fb0fafe09341aaff25f366ffb0f188da72cbfe890efab621cc
+ff04dd60e3af3fff09e5bf37e00cd930e7c114bedd7ad6f08fec79ddff4af213db55cb9f
+ff86f4a4f16cffcf5fd941ed2ea5d84a96eca40dff50f00f9ee542a5db37c9ff7afaa0b8
+fe18b0dd88ed93d87de0a3ed06b8cc27d969e093ed71cf9ce088d76ced41b0daa538ffa0
+2cf2bfa5c4fe6dfab787fc56f940b6fd3397e03e9fe82cdf5fcaed4bdd0cee5aff79cc9e
+fe30f8c6e85dd091e1c23ea0fe0afbad29c8e67fd3f379b6d793f6b979ed66d978fe93c4
+ff87fb4ea0ed932effaf43ff2acf9eb3e487d293ec79dd07d04ad827dbac0bfca1f586b9
+e56af2c766f8d687d97dcbff6ec2f586fbb14bed30e747cb9ef64fd51fde41f2c078cbab
+f47bfe92f6ad57c1f846fc0bf24ad980ffcb5ef8bf59c1fb9347f90d9bdc3af2c82ed99e
+ed7fcaaff365fbce85ff93fca96aff85cea6c697ed38da61d8a60a98f777fb1886edd079
+e580ddf59f50ff34a1e042f24cc62cfbbf99c5f51cd851a5df73cbff60f9d280e098c7ad
+f91ec735fb7bfe2ef6b5fb6ff964fb7df4c566d81ecbfa12ffbd19e03cb6f324feb52caf
+ed12d85edda4cfbb93fe6cd986e27afcb6ff9f12fe48e837dd4fe502d5fe2cafd987d279
+ffaee51093ed22dc95e161d3e480edcf8bea62a5ff84d818ff52ea0bd8a620f251d402dc
+c130bbfd45f724afff90f482ffb6d93ae0a9bfffa524f84dc63e87d8f06cc6f962fec08a
+ff9ed10eff3aafe480edb81ef3ab0add9e47f304fb5be47eed94e0b846b6d8974593e3a5
+cc94e03c9fee81ff5a9bdd7799fa86ff6dc6a1d254fad885ff93f31cfe52f705c2f23bff
+0bf0aa2d86ceec6ad896ff85d0a3f161c697eb62e238e9c02b9afad469ff88f501ffaf1e
+feb658ff22bcdd0fed6be498da91f980fec779d988f46eeb9fe079d88ae6c94de01eec5a
+e579fec055d935e0c095d9ffa5fb1eafe3950cd89b17ec62d970ee86e67ac1ff44facd58
+e2c06cfec1a8cc76d816fe52ff05f2a5e50effbbed33d917ff57c7fe27ddc1adec46d3ed
+59cd9fe54df77af1bf5ce434c967e383d899e07ab4eba5c75ac0d9f953bcfb81db11b7fd
+28b8ff87f517ff9ffab57afec54caae6c247cfb578ea9ec832dd79cbfb6ff7afcc4cfb2a
+d157e041b2ed17e59cff14fa4ef319fe5aa5fa7ec5a5d030f1a310fa86f57bfe5eb713bf
+da84ff45cefe79e5c4aef822fea5d953fc27a0dd7999fe80f7b425ee60ffa5f596caaf87
+d083fe68efc475c0fe81f28feba870e59506f787fbb722b4fc06afff1de0a704fb76b5fe
+9fc1fa33ff5af425d062fb94ff459ae5a525f060f7c874e059da3dcbb1c453c705f361e0
+86f216affe80f0be51f67cfd96f5a54ad89e32fe93c1f271ffbfa0f686ffc344b9d093c8
+a5df7bcded07b6f76bffbd52c3dd96e463ce02c4ec8ff15ad09fed68b8ee3afd4a94e1b6
+3dbbed86c5f802b7ed2bd93febd091d920e04ded39ddf75ddb30d8ad42f91cafdf4cd103
+f6bc4affafd634c964ffd877edc788d85bc7ea92cfed4cda0aa8e08ed681ff95d914e787
+f2d102ffc98de1a552ee88f9bf82ee32f785fe93d8b91fffbf94e03add24fbd010d953e0
+07c0ff86f3bf63ee01afe59412dd37d953aeed7ee230ff61befb3b93ffd848dd14f389fc
+79ff20b5f3a5ff69fa32b4f405bffa28a5d885ddbe5cf593fa12b5e06ad2ff64caacff88
+55fe79f9c08cc4fc6a25ec89fa7dfe93c6ec6ac1ff7bd987fbcc68db7dfe8df1a552f495
+3ce56cee9c42ff279dfb88f2bf51f016ddaf3ff9a6cb28be7fef874dfc2fbfff1ed8a508
+fe94d8a5ea3ee44beda4d054fe76f7a4cb5cadff91f384b5ed3cd619dfabd08bfb3ecafe
+7cfac193fe21fb65f1afe704d8afe4679efe80cc9ae02dd85bc9eb48d83bdd9bc1e452ff
+7acaafff53f701ffcb1bdb79cafe31f29847befb1296e5bf0cedb262ff0fa5d8ffa3cb4f
+ed16e25bb7fa399ee05fed30aff21cea4fe40fc3e028d3f8abfe2ff5d07be0c21ee579ff
+97c0fe55edc27eed5cdbfe3baee0afd09cd979e569fbd8af51fb15bcd29aff7af76ee82c
+d9c36cff9ded67d831cdff79d993fb5aff36e079d9b14cedb507e061d9c5a5d8558cfe86
+f21ec7ed25b7ed4daff894ef739eff86f7af18fe74d997e81de07dcf91eaa366edafff4e
+9ed884dbaae16dcef142dca4d32be99cbef379c108e5b99fd5afff0bcfacf11dfdc293e2
+75fea4d0be93fe79fbb68613c1dd81b6f948ffba60d229e641b4cb8cfe31b6ff9b67d8fb
+61f50efe4afa9ecc4489edc87fe078fd22b2dd0cc9a7fbaf09ed43d81ce5b9fa8813e661
+ed7ec69bf2a5ff1ee797ce6dffa3ee8642ff0df9cfa843bffd5c88d6f678feca41d80bfb
+c726d752e0c593ed2dd864fc5ff131dd4bd5fe9738d2aef45efb15fe39f7b679fb86ff5a
+f6c649d939df52fb65ff28f44d9be577ff86d8b146ff13cfb862f530ed43afce5bffd9a0
+51fe09d8af6feaa5fd93c4f766fb0ed0a0e508ccf8931cc794ec82e4b419f4afff119fff
+3bf0bf90fa68b6ff3e87e196bff990fe85439fdfc2a5fe25b7fa0aca4abfef5ffe26f2c2
+3aaff8bf9aecb628f0db75d1adfb9f3cde02a5ff92e64fabfd93f26bff48affe8cf5a5d0
+86feaffb8626c1f962ea0dd073edc087d824e5c331bee19476fe85faafeaa7d193de6dcc
+fb86d826dd62e89cc9a6ed3be08cff9ec0f202e8be70fac496ed65cbf212dc50f301abd9
+7bde58ff82d9b745eeb0ff3faed82bc6eb7cd965d0ed6cafcc5ae045cfed79d7f35ffe34
+c650b7f1b3ff2bf948b3d0e252e992f86ba5d888de9f5bfbd51ae05ccb7aff69b8ff39e0
+11beff81c1e47af26dbedd7ae008cf9fbfe50ecb42da0ae59d15c6f3ace57edd92fe88de
+af4bf494ff5aa5f89b03fbc123e5b871c51eed49bffead31ed5bf598fe07f359f881ffc4
+09d861e37bfe9d35df1fe846acff2bb6fe9bbed786ff2ef193ebc03af38ae574d96bcdfb
+7aff964ffe39f8b233d8f604fe94f49f2dfbb81db4d093f2a5d905e468b0d592ed6a96ff
+7adb23ccfc0ff446bae59370ff8af335e596d80e9feb86f7d84bb1f358d826cbfe1bf65a
+baf936fb74d885f27aff6ebfee934dd905ff33c951f22eff9fd106b0eed06edfc46aeca1
+d016fd5eff86f89501f1c68ed8b644b8d592d829dd4e97eeaffb22d951b8f693ff7bbed9
+86e076ce34ed45e5b0c763fd1eaffaa717c2fe24f3a20bdd55edc986e0bf77feb67cd962
+d816e0afca56ffd94ce614ff61fb93c4f45bff03f5c729d89fff86b9e47cceff0df5c92f
+dc79fec34afbbef557c93184eed01effa1f95f9ad986afed6ddc95f04bffb7ea3fd5fb5a
+b8fe7bf2a5b9e99ec0d966e079fdcb861aff4df2b33cff80f299d979e038c3dd9e4bfb12
+ffa9f77cff72fba5bffc8648c1eb86caed61d841cdfd1af860f493fb87ff9a5ef9a5ce86
+e04dd4fb5a9fd753e0c0aff7a905fba618ecc325ff99f382ff6af888e5799ff67ad880e0
+af4ad917e39bdd50b8fa69ed5ae039a5fe6199dd52a9eeafd30999ed9161d193ffaefcb9
+62e5bf76d4afed3affd42bffc417c1e093259fddaa28c4e632bece66fb45ff17b3fa25f2
+a336f9d891db86fecd60e047ba2df6bfaaff6cfecd79e060ed24e438ebc25be11bd3ff95
+38fea517ff83f3af5beda8c605df51d810caec20d944fe95ed77c6b1f486ff79fa3387d3
+e561d0f29b5ee552de39c7b0dc3dd801f2c726febbed1fccf67afec165affb86cfb115f4
+72fbd82dc5f079d0fb8647ffb9fa26c0ff1bdc4ee30593fa9c4aef13fe85c8b779e7a060
+fda55bfab1fe5ff687ff6cafed1ee087d88be47cc2dc5ac7e6af47ed2ed80aa5ef8dcbfe
+ed930fd957e51aa5f793d184db69ccb30ef281f7a560f1ce6ce0bf98dd0be19fca51ffb6
+7cf9a5f384baff7fefc10cafff31e703dc3aed93d9ff4b9eff9245fcd386fac093fb28a5
+ff6efbbd68e0a54198ff943adfa82ff2d61de041fed99cc9b682f7ae1fff9e01c0e39353
+d8a6df79eba5f899c1dd34cdff89dead51fb06f54ebbe37ef3cd3ded11cc96df07d1f879
+ff5cf60ef15afe3eafff9367ff96c1fe79fabf34fb129f53ccfb88f384b9e028d940fec0
+9efb78ff9bd92fe0c011aff747fc30b2fb64ff31dc79edc729d855e03ba4e05b9ef7dd60
+d893fe81cfb71ac36ceac42ebfdda50aed9819e45ed2ee7de9a72cff86eeb6dd54c9fd86
+d0fb9f57ff79ef8fbe4dff05ec4be0c751e9affe33f6cb81f23ffbc335ce5ffe7bf4af0e
+ec43cbf188db93d0fe34d803b6d96abfff43acf39348dcc394b7d8a5bccc94e008ecca14
+e061afe550ea87d4afddffa74ce42ecffa67ff7cf2af08f243e5ba51c4fa70fe9fde87d5
+7eeacc86d87be89afb399fff92fb79facb18ffd02c87c5f857acf06bff9ff2b910f986f5
+6dfeca72d8ffadf19b0ccd47c1e05bd907fb6af4a50eed4c8be7bd80ddab11f9d288dd96
+fe6da4fa80d96adeb217fe66d8a46cfe86e823d651e186c2fea423e558fb1b86f1afff79
+f99fe579d8ed5ecbfead29fb4eff3cf420fb6af752a6fbb6f123d0b89aff5ef37d04edc8
+91ffaf42c6a5cb5ae793d3a9cb21ed88b1d035ed52ff07f4a54df125f9c00dd0b1e44ae9
+08d3b77ceda967d9feaf16bfe229d850df3dfea5d1b81ee15ab0f84abe3284feaff793fe
+82f093d17cd830e0c07dffc50bfac42cffc58635f254d825cbed12d541f8c279ed9fe104
+edbe16d8b3f26dff94f9507fd8ff6dd3a5c2ea9e4593ed2fcf1bfab220fbb610ed9fd0bf
+91e179d59dd884cfed864ba2ff7ef70bc4e037d8f8b924e060da9ef005feb632fb5dff7b
+f761fe04f3b77ad893d96ac6ff93dea562f35afe86cfbea2ee34fe4ebff29343ed9cff79
+f5affb86d776e042ff96c2f126db93fbd9c255e062dd13ce38ff4df7a4ff6ff9b02ae2af
+69f2af60edb7fea6e67ef5ab58ff86edaa25ffbe59c4ff7df491ff46a5ddc031d9baf537
+97c6f63bff52bffcc565bcfe93c769e3c17fe086f960ef02c4fe4bf219feb92dd8fac241
+dd66ed54a8fe9161a1fe7af213fb6fdd86edbf9ce018d893dc81e567c7fd1df23dfbb60f
+d844fecb8cd9ad1ef761fe6db3d896e506fbc864d835dec10f99ed22fa93ee79ec4ab6ff
+62c70588edb524ffc0a5fbb99feabc18c4d943edb86cfece4bd8e59545d917c0ff3ee3bf
+94db5cfc9ad82efb973cda51e0c180fb06affd9d15ddaee90884b7d880e012dda7e05aec
+3affa436fe4fd832df93fb83afdd7de5a55fff9f10e493c6fb90bfde74d8e5c146d1adc9
+95ea52d622fa63c2f555fe3bcbadff43a5e0bfa2d087e579edbc1bff3bfac196d824c1f5
+14ff86d1b67fff92faa84cffcf61d95acb01da9ffd86cea3f4afff3cf5d09641e85ade23
+cb86f2629bfe86d3ed1ba5ff8908fecc7bed64a2d97cf32bafe507d089f375e7b886fba6
+2bedc589e071e5c286fb62fecaf222fb9af361fe09f79eda86f4d06df2a5ff7ad75be530
+beff43c0f17bccf561fe1fb63cfe17f52f7aff89f92aff43beff93d97de439b5eda0bcfb
+1795d8f98657ff26f74cfeaf7ce598dc84e553ff89e07ad9af54fa39ed1ce071cbee7bb4
+f785ffa5f35fd834e00fe448d875d89f65f9d87af193fa6bfe40e5be04e65094f7d83fca
+f4b95bf893fbcd08fe61c4ff70b7ed46addc11fecc1ad3faaf4aff27f350ff3fb5db944a
+92ddaf43b8d890cb83d672e60aa8e5c517c0ed26ffb6f76acd93da04e94cbb87d3a4e8c3
+95d0afeed80adda5ed7ce2a50df14dffaffc68cd0ce05fd8f5882ccbed7ae065cdbf25fb
+5cd868f214cca5f04bfe41f4cb8edc9ed752f3049fe11dbfe02ed889fe7ff669fa80ff93
+f212fbc91db6ff09c64cd8a1db77f3ca7fffc0269bfb932fa5e423dc3b86eabfa5dd51d0
+f979ffce61eea14fe49561e593d8accb93d8a3ed2af7c5ff5ff886ff28f24fff24f154b8
+ff3993f89c61dca30f95e021fc5ef8c196d9ff33f372ff59fa449d6af6c352bfd95ef4cc
+81e0c21197de86ff7aef9e4ac1ffae01feb8a4f382db8aed07ffa4bbeb2eb7d09cdf8621
+ff61f774fea5c2fc6dfe4da5fb52e616ccbc9dc4da2acd5de0b48aed79cba9f58cff0db8
+fc30a1e036dbafeb51bdf1d879ffabc2ff9c4afb1ceeae2fc9b51efe87c6f779ffca0df2
+5cfe66f710fb61d8af1db7d60ced99e07cd894e08afbd360bfec51cefe79f3c7fe79f0b3
+dea03ffb0eb0e05bd801d979c9fdeab686fe1a9bfe33affe3c9fd8f82bf2a4c726feafed
+6de49bd33ed913ff4af8a8b9c93cfd67f75ffb03afeabfa8d00deaba34dd55d888ecc87a
+f2bfa9e446fe1ea5e67bfec054ff3de550db34e0afed5dd0adff79f688fb70d0ff8641ed
+bf5fe00ed6f18fe47afe99f568e07ad926b6ed36bbfba5c520eda9d08abfff79ee6ce5a5
+ca3eacfe14f958c82c9bfbd975ff06afd837af49d8a53a86ffd06bed79befe9eed86e5b1
+1fd036e064edce7ae5c767d2fb895abdd241e6b778de0fd850fa90ef75e488b4cb31e779
+e093d685e393c4ff37f94ef196c781e593ef24f8b608dc9928ff5ff193bffb6bf4af2feb
+86d680fe95fa834ac3fb84ed11cd56d815de9f02c2fd9f13fa93f677be37b6d815d94dec
+a6fa56ff74d7af65d93ae7a0c73ce449ed02cd9cfe54f574fbd06bddc0a5feafed861db1
+d996ee58fbc5f566ffc6ec1cb5d995fa21cf40acf82eff9660ff80f9aa4ff2a017eba622
+eeafff75fe65f9d052fb81f2c318bbfb42c1f079fa95fe5af20cffbf28ef6ad88be076ff
+2afa5bff79b0d06dff67facb82ddaf37ea52d608dd9cc4fa03f2b527b9d3ff9820df53d9
+8af17ffe66f2afe06ccce977d957cbfb94ff65f384ffc30ac1ed90e101fecf92ff7bf66d
+fc96ffa2b9f935c8b52fe7bb1aefb34bf301e44abcf3cb55fa86e28e1c9fe009b791f45a
+fe31aee082f2c968dd7df0c7a8d805c3ff2dc0f887ffbf86e50addabca1c96e9acd7379f
+ff7acfa5fe0add51d819cf9cdd4ea5dd81d943fe0fb4ce9ed8b815c2fe40f097e443a1fc
+06d0ff7cdc95ed83ff5ca8d859e0a5f01088f3cb6dffb8fa39e5afc84cff27f847b6ff2e
+f2b11dda48e0a5cb3f93e59f36da6bed9d2df253d209e0b318cf5be088dd7affd49e5bff
+c47ae088d87eceff8d3be0b627beffb2ed85d0fa46d6be93c5ef4affb917feafd712f749
+f28ce572b2df73d852e040c2f59333f1afff8620fec0e54cdd2aeb61cd87ff84f66cfb79
+c1fa58feaff299c0fb5fed3de8a7d983e0c00ed2afed62e56fb7f219fe4dcf22bfef88ff
+73fb7be6c144afe39928a7dd9623edba94d988e183c7a5d36bff9ff7ba03fbaff570feaf
+c0ff4cbcde86d99dfe84c8f985f222fe50ed0b89fad8af43fa23ff64f29f15c1f77dffa5
+dc4dd72ffe52a6e57ff612fc78d9669ded9348fba279dd99fe3fbefa5afe02f393fc9d57
+d0fb7de05ac7ed9369b3f797ffb794f4be25edafe032b5ee12e69f1bca52db24e086ff6a
+f64dfb2ca4ff86f730c8a5f947c18fc7aaf5a2fe3be51fcb4ada37fea5fb02f2b6fe78cf
+ff61f73cc0fb1af353fe07edc134ce7eed6bdf21d651f2228ecdfb60fe1cea67dc52a5e5
+6ad87dd094e0c13880eb94d8bf9ce736fbaee562d810f183f974e97bcaff26d961df99e7
+06cdfb39dbbe63e0fec01dd0a5ed15da84cc62dc2ad8ffbd4cd906f3a63bd8f204d157c7
+1efb43e2a5ca439effd25cd972ccfb7de579f4aac602d07bde93ccf35ad879b6ff12d886
+d9fb33e062d889dd7ab6ed9ac0f265de7bd760d849ea0da5d886e4a56fdd99d87ae0b05d
+e592ff55d09bff88e47ed1f69f13eca7cb94f527ffbf3affb0f540fb65ffaaf704fe5af5
+47b6d771da2efe9fe460cf0bddb8f71396ee89ffc34cbfff86b8e470ffce28ad5ae26bfb
+81d69fed93ff7af2b01388edaefd77ceff61bdff8bef82e566d96dff7ef2c20188f795ff
+4ab4ee30ffba43f19ffeb712ff63bae51afbce69ed94ff23afee82ff13f84ec7fb61ff16
+a7d82ced93ff8ef585beee3afa06fece4bfe31f8c586fe77f026befb39afd810fcb645e0
+afc73df14aafd780e096ca13a0eab6d929e087cdbc91d0a5f90bff94edbe47c3ff8ffca5
+3d9ce0c057d137abfaa354f221a5f40c9fedf887ffc52fde51ff36d41bbcca6edbfa9749
+c1e62793ed9f46df30fea1d0afed11d860fbaeebbb24b7e17fd4a5c78afe69d848edc98f
+e03ca6ed9d32e0b341bae379cbbd56e57beda507d593dbf779ff5ac71ce03ccffe6bcb9c
+de65b0ea81d7a647f213b6d2a5dd7ac9f962efbf79ff86fa79ff83c0fe5dfa0ff358fbd6
+87199ff2c152ee3aff1ee079d9b63fc985fa932ce579f0b5fe6df3a9fe84f01bc4da7aea
+cb7ad9c143d2b809aff68ae97cb6f4a5fb3ffeb731d6fe68a3f9d815cafa7ad8af0aff2f
+9afa91e533d851fea5f339fe06f753da14e581fa9b37f284fec350bffe86fa9ff550f909
+fe9fcdb637ffaff24ebf3ab9cda0e9b572fbaf28b5ff79b8f220c0f60cffbf96c3fb4cfe
+0ae89f29e0a54aed07d843dd25b5e406eda5d97be0a962f0c4fe4aadff84d899f187fd5c
+f489fe03aef1cc51d81fd94cd831db03b7d993fb3bff9929fb52ff9332f1d97aceb50dfa
+c645d96ae0a059f6bf0de0c342affe79b6ec5bf1c66df3c047ca79ff8fda85e071cd9fdf
+85eb7afbaad021bffe5ed709f793f25cd204d96dd68ddf86f21dfed382d971cafa87fd0d
+f34dfec0d95af9d818e04ec6ff9a68d989ec2be56bdc92f259fec670ffcb87dd7bf388cf
+fb61dbc375b9ff29c0fe3991dc7fd81ced61e566c62fd0aaea53c1de5abafb84ff94f788
+ff7ef9cb44ed87e05dd3f1afe384ebfe9c4fff3dfbd85f9cfe90f107d0ec9474f385ff87
+e14fdd21bffc369ee086dca5feb81bee40fb0fb3fa67c1ff36b6ca5aeda2d980dd95e96e
+db27df78ffa5f125fcaf42c2e09351f62bfea11aec96e07bd8950592ed9a61f5bdfc862f
+c3ed3cfb60d8a4f732cc75d887b7f21b98fb36feafe65193ed9e34fe48cc9be87acefa05
+b4fd9ebefb0eb7ff9cf816cba2f371ff189eed63cd07c861e0ac5dffbe0eaff8bf8d47c7
+02b66ac8e686e0976ceecc1fd879febb28ffcd5ada2dee9bf685ff88cbaff94bfe05f15a
+e3a2cbbd6ac3e540dd1f9df2d827ff88f54df91cff4ac8abff86ebb845b5da60cfff9b61
+fac19ddd66e1afd045adff2ff7c6ff40cbe9a24493e5adfb87dd7dc6ff5aafed95ff16f7
+40d9b0e36dd9c00fa2ffc219f9d886f16afb0bdd52bbeed057e032caa5de43d878e586fe
+27d886e0c32abce593edb42af19ed075fed88614ffaafd94dafb18a5f225c2ff2fa9ec5a
+e4af82e0a61bfb93d7b604b8d55de80fdd6ad896cf7cd836f95effa8f688ff94f0be4b8f
+e4b30db8e07acbbba3fb0fceb12ff793fe7df4950eedba2ee902aef340ff6dfac061e5b7
+74b0e4860fffb2ee03d951d31df2af07c1fd21d97ce069d08bfe52f6a55df1cc33f4b26c
+bee51fd9b4f286ff984492f293f77dfe70f4a8ff52db6aeda5fa45fea6f53efb4bffc253
+fa23e59f36c3e561eb2af24a79d6ff64b0dd78b8f880ffc138fa50f4c77ae445fea8fa28
+d994f280ff2be551ffafeb77d909e02dd85ad061fbc6fe62f39dfb3aafef2df379d967fd
+c45ae212d839e7c978fbd67dffc88cd883dd0eed8ad053ed1fc2fbd668dd79ff9ef485fe
+56e78edf81d052fba3beff02a8dd1ed1ff9a64e07ad2ff3cafff884ca2d82be6c1ff13dd
+50d724e2c206bfed33d5b810b6ed7fd96bdd9ad079e694d8b66bf6aefb88dd7fcfabe0f8
+b939bff703fdca47d9149ee88ed9b962ff94f27edc68ed79fe54c7a4ed84f3c21793fe95
+d484f16dfb19d99303a7d83dde88c1ff72d856e597ed18dd9cbdf6a5ffb651e09f47f1b5
+37fe20f8a5cb9bff16f593fe9f37aff132d8b741b5e06ecaa5fe42f16fe1af35ed58e5c9
+83eb932fc1fa91ee03a1ec5bc5edb8fe6bf9b577d8af73fe8df05d95fb6c9ffb80ff95da
+5fce08ffaf1ef8b210fd61fec94fd91aed3ebfff59992687edd879e3569bf489fbc94aff
+019dde36d810cd4dff9ecf3abdfa1dafd93a9dfbd027ef4dffafcaa5ed7ae5b6ee79ffc3
+61e505db86feaf39c2fa6aff3fcc5fc686f21effafcb79e566edb951fb5cbfe086d86cd0
+f87abffe62f78afb11bced1cd29ec0ff0ef5c293f8b638ff63fbaedd1bd859fdcb7dfa95
+12e039afcc1cfb40c9ed37d9b6ffc63bc4d921e14cf238fe9ce083c6ed67dac18fec0698
+f28bff7bb0f30cbceccffe9544ffa5bfde23d866b6f179c1fb50f8a5ed87e0af18f2a5df
+70cbff79f7b760bee47ddc9c14e751bfff49fa2fe1a518fe95f9a8eb1dd0ff53a5d988e6
+80fd26fa6dd962ed0efbc3a6d081dd2ae4a53ffe25ef49c0eb139fdc21e3c599ff4ff788
+fa2f96d879dd27cf60edafc748f075ff7fe3b151de2bd8fb84c3f063f39de986bef88117
+86dba5f279f7ac88c2e67af155fa33a5ff3af24bceafe138d84dcbe466d2fb6ea512e5af
+cb1df282ffa0f70dd3a5e56dedbd6cc4fd2cf7c188ff09ee9945e107d8f140a5fc31ccf8
+92fe34a5d886ce5af7b1d258c943bff66292f1bf31f201d88fdd9fe793ce87d99446ff09
+f560ff88f3c87eda9bff935cfbcb79edaf3bde80d8ac61daafed4cfe9efb81ff9612e19f
+cfb93ff3be23ff94f4b647afff05d97bd75bff01a2e0b0fa4efe0de059c8fb05afd325d8
+87e4cb79df9bfb7bff77f59cfab821fe9f41ddf3c165fa8afb6beb37cd61ea56ff2cafd0
+1eff419fd85aea48afd862fbaec1fe6690ffc55af3b662de79c4f50cfe98da80e02cf188
+ff78a0c7e40bdf9ec1fe5bed47d207fc33ff58f6bf9de487d579d903b0fa4fe50bbce1a8
+2affc186fe6bfa27f0bf01fd6de5ae1bc1e040d2fe5af709fe98cb86edc260ce74edd579
+e5acff27dc6ed2fc5aef93e5bf93b9ff3cd998ff74f66affae0af9ba1dd5bf28dea811d9
+87ed82c6f97a34ffb52dd952d287dc7bfe94dd86cbfe80e587b8f377ff96c5fb7ae522da
+4f93edbf0fea99d386ff0ab3e36edd61ed14ff52fb9ad90cd8fe2aa9ff7af849b6cda5ff
+6bf2b1d6a3e01fde5cc1fe23f0b6fe67cdb683f4ca3ff2d8974af209d0a5e55affd086d8
+3cccf368acf174bdeb86d86be914fb48a6f70effbf24fa9744bfec88f4af3fbed026ca33
+ed63d3af7cec50dda3cb42ec95d76cfe52efaf64fec16fff5ada04abe6d879c7ed79e20b
+feaff31bd132fab410d95fefd005e0bf13e532cda0f880ffd02de0b077fb1fed52c2f23d
+ffafd093c5a9cb74e565eeb34eedcc59d893ea71fa1fc1df9855f979bffe86f332a9d895
+47a5eb1cffd665a4ff8c61e6c47abaec51c8b38f32f59cff85b8fe0ac2fa2eaddc37f9b6
+db6ed0e77edd9f66e05acbfe934ffb1fe39cff7af982ffb3f41ffcc02df9ba13fdbf86fe
+46f2b2e57afbcb39edb22be693ffc95c8cf107a2ff93efa646c3e480edbf70f59bff4593
+fba566fe85b6ff52baed3d9ff281fec14cd8ba9efb82d89d1efc51f336f9bc20febe7cfa
+be6df437fe15d796ef8739fec218ed42afd96ccbf96fffb9f67cd99930f9d805b8fb1bf6
+a6ff6afb17d9f9ba5de70eef49d9b465d893ff7be59f5090ffa32dfe42b9fe8ef6a911e4
+c2a5ce86f20ce960dda34697e067eda5cc5ae892f220c5e088179ed901b7d873fbc466f5
+449efddd56fecf3bd852cbfb9b60fda53be5c328caafdd31cbf54bd4ed73d914c9abfb61
+dd22d9a4ff6ae51adb61f0be79dd95d884ec9fcf3be09b18e694dd85b0ff40a9e4b97ae5
+a5cb96f114ffa43fe310d838e54cfbc25c93edce70d858e034d986e69f48edcb7bd879e2
+86cbff23ed4dcf18fec6ed09e5c686f0d207d838edd160f234ff51afd886d815fbb6ff7e
+d019ff7afbaf62d8b65ea5edc5ff5af679ffab51e1a4bfd8ee199ae56dbef483f9932bc0
+dd07d6ff60a1fb7cf369ff79b8e6a220fa86f463e402cbadf763f205c794f8affe28d3f7
+3cff03fb46db8bf462ffcb7afb5fc2e269cbf50ffbce2aff73fa66d87adfc083f287fe9e
+c774eeaefe2fa5ff92fa81cba1f15dc7fe8821fba6ff1ff65098e0b6f86af2b23aaffa5c
+abe0619af380ff669afe82d894c1fa3ffea9ee79e209d99fe490d903c7ff33f7caff3a86
+b8ed94e020cdf30efb277fb6cb38aefa22b4df15edafff79f75394cfed4cd819e19ed907
+87f2c75be0b0fe93bcff4996e07cb6fe59cc44a4e57bafc886e17cb5ff0eacd929a3f103
+b7ff25f7b677dc5bafed54d902e5adfb24f6b548ddaf07f7b519df55bee543ed08b5fe24
+beff0d96e0afd445c69fd1affa883ea4d880df93d97acdfe1bf8c854e0a5c3e627beed05
+dd72e0c551bace54f85cfe41f567f14f9fde8d1093d8fa24d046affa61b6d595ddff4df2
+ffd97aec67c2ff62d838ecafbff20cb5ff85f8bf48eec0ff42affe952bcb39ea7ed1fc32
+c9ed29dd90edc050ff11edb64cf2d872c7fd6cf7d151e4d84fa9d930ffc493fe7fd888fc
+c4469ee55bcefd79caed61d6ff83cff46bdc9fc1eb51f379ceadf730ff6bf483fe37dc13
+edb9ff05fb55ff1df64393d9a82ffdbf18fb52b2f84dffa7f51a96ff24f389c0df79cb9b
+d886d6f360febef44daee46bfec986ed7cfe40c288d793bb09cda5fc44acda86e09920fe
+65e277c1e03ea5fe935fd89de00ed0f286dd6bf917afe85da5f67fff09fa93ceb761fecb
+9426f7b638e0b17ffeaf79f2cf84e0ad43eb09dd3aedaf62ffd086ff9c17e051befb9340
+ec9911ffb927fe7bd888de34e461d9a0ed07df5feb79fe85d76de8c296bbeba0c0ed78ff
+d86493f27fc8e179afcf5b92e4c06bd89dfc2fafed1cfa38ffb521afd92fcc9fff81f2a5
+0fdb2de058b5f615fa5ae986ff2fd399f703fe4af6d186d892f52599fbd610cefc30f669
+ed55beff58eec09fd983fecf3ad872d76bdf2bf5d89a18ffa9ce59f0c419edc12afbb50b
+fe5df193bef89cffb831f3b60cdb3ac5f292ffa221e4bd69faacc873e259d517ff9dfb7f
+f1b44fc48cbdfba5c74de52bdaaf46ef30cf5aff01d04bafe8c445b9ff0ac1fb26d8fe3b
+f2a5e64ccaa5ff7dd885e0c26dfbd072ed7ae00cd93dc1fb8bff93cded66e0a0c329f2af
+e179ed6ee4a0c7b75aef31fe50d9c452afe581b6c98fd4affb9f09d99927ff50f10f87fb
+b4f23ffeadec8641fad468e683fe9f71ff9661e6c668e89cd119fe4dd25ec979e4c18eef
+7cfaab4bd92fedcc79f2d02ddb46fb86f093e0ac43bfd804fc86e4ff42cf1bed9fc0fa5b
+fe86c5fb7be486b6f299fa11ff9cee6dacf36aec7db6cc5ffe02f068da13dd4afea20eec
+bf3aff97f753fcbc93df64d84df3069effad4bfeda9341c5fb1ab6cb5efb11ff95cca8e4
+78f286fe29f44efa1aff2f87d8f479fecf6ce5afc3dda22088e0c35a94ffbf79afed4ad8
+04debf41c8fa924bffc079f9a6c2e586f012faa522fe56e08ad0fe78f965b3ff0ca7fe7e
+edb0cb38fe62f9c569ff95ccb826afd893f862ff078be09af30eafd921fac635d87adc6f
+e020d2e53bd9a0ff10f693c7b686ff80f7aff260bdf7955ae5ad02c6a5d061eb1cf2a5e6
+7fd9bf33c6e18652c1fe9661bfff31f07ae5c062ea1ac0ff01e994da72dfaeeda4c1e64f
+b7c742aff6933bff4bf4b7ff9e1cf9c506dbf033c1ff93f77cfba5ed0dbfe0a120ed3bda
+7b29fda3dc68ecce79d82dea05b6c69fdd3bd892f34bdf9801ffa4bfd90fecaf28e548d9
+fe7df253addd7bccf2ad39d8a5ff61f150a2ff89f659cbaefa9652feb72fb1d977e033ed
+d227e3c23593d2e545cdff83d8fb62f22dff99fbbe31c4fe71f991f41afb9fed0bf2ade7
+83d993d8a63efaa2fb5badd8b53bb8ff8f37cb5bf76eff24fba5e00adabf9ae078d857e8
+bb70e5ac67b0fb8812e452d12fe05cb2fc35f5c486ff95f2b1cb38bbff4496f5a4ff6df7
+5bf114ffb85ae7afca66f8d260e02a9af284d0f66efa8dc40fb6fed130e9af26ffcd76e1
+80d887cbec62df28b8fe3887eacb79dd8fed47fa9eff539ffb5795d8fe098cfbab1df044
+afdc8ad8b648c870ff9515df48e562b3cfff78d859d824fc51f720ffb1c96dd288ee44fd
+9ff114bffb93e404d887de7aed86fe76f922c5fe01f179cfff4bd7fe24d9b8d8a4ef87d9
+81ffcb72d869ddb449e510ff72f885c7afe01ad986cb9fda93d886c7fc8616ffbf25acf1
+86fbc25eff52bee0a738eea5e03f98ff78fb86bf52fb19f531feaf13fbbea5e57dd7ff05
+bdf718fc62d0bc20cbaff279beff62a1edba65e194c8a4fe35f916ee87e5b443edc0a5ff
+95d8f8274fe5afff7bdc9ccb89df60ed06f537ff96de7ad863ccec6ad87bfea5ed53d61d
+cb5ed888eda563dcb1fb2ca5f37dbef28448fe35c3ff1af2a423f3abfe02f9ca80d891de
+55ed05fb5afe61f238ff1ffb4ff326a5d5ed77e588fe3ad969e6af32dd9909ffd867fc84
+f7c916d95ad6ed95b8d29fea6de096d047ff0af455afef935fe2c3a5fe86f182dd0dcde1
+18ebc82bfecf35ff6ee67bd083e09afe04f7d979fa59cc0ebd87ddf29333c0f946f408fe
+79d096d886e0c50ebff825fea64aff21f2c342b1fa8bff95f232ff51beea93449de3c917
+ec419ee1c19bf450afe566d0ec9343beea56acfe61ee25d79dd87addbf93c2e785d077e0
+7bccf84d9ffb58b6d894bfff11ccf773fbd379b0ce20eb55bcf188e5a50cf63eff4bb5d8
+57f488ed6bdac29edf40d3ff9f4bf303d83ffa5dffaa4ff8b586dd7bb1ed5bd806f15fff
+af51c7b86aaed024eb85d9fe5dab02c4ef82b5e96bd2afed31ff4afbb579f2a56ae284db
+b879de5f9dffd111dd48e56fd897cdfb16ffc6ed6095fe8bd0fa07ff63d5b979c5fe3d87
+ffd87ad093ed1bceaffb69fe30f7b13eff0fb0db3dedafff4293e0c12dc5fe0be951a5ed
+81b8e34bbcf350feb579dca14afa32ffc87adfc293fa03fec623aafc9330fa86feb723db
+bf93e76de3afca79ed9ad43cff51f913c3f686fbb6dd25d4f57dfbd838feb66cffaf3fc5
+fbb1fe65e217c9a5ff55a4d987e4c21ee659ffc346fa07f6cf92ebbf3586ee9fcfaffe08
+f7418ede86b60dfbd432dd53b6cb93ed20dafb059adfc115a0fa31ff5ebaf342a0e28ccd
+84e5a5d19afa79fea509d8befd04f297e250f37bfad045fe20a1ff9418dd88cafb02ffc3
+93d8b64dfba523e574edb079bfe041d0ecb616c86cf67bfb2ac5ff971cfeba26fc6bed82
+d0ace59b29dfa54b93fa9f3fea1f9fe586f3cb2fe09ced70e02bd496ff86ee25c0fb14f6
+5ba2fe80d92ded9fbee09a3efe15f5aefbc356f22ea4e07cc2f4ac5af2d879aff67bff86
+f75bafff9458c0f678fbafe06cdcc29ae482ffc70bf24fff18f153eb2adf4ccaf25b87d9
+b16aff78cfaddc1e9de48adac12ec5ed61f83593ed86e21df26cec81d0f35fdbc14fd9ff
+6af8af79ff93f2b059e088eda943d5ea59d992c1de04b6f22f89feb970ffbbed63c1e088
+c9ff53db0ba4f760fb14ba7af656f23cd861b3e07ecd93dcbf3ef4abcb8afc5286ffc780
+d86be0297fff93c1fa4bb3e424d0fe37beff4ec2ea14de3ae6cc73f3aee926d951ed2ef2
+af0ffb4bd929a5de94d877dd88fb7cd6aef76398ffcd38ebc424baed3193ffc663fb79f5
+a6fe87d97de8d0a85cb8fe9ccf07ff47bbff972efb9f11bbca1ee04dd832e4c207ff50bf
+fa7aa5f56efe38affbca69ffd754eeca3cd912b1ff09f24abded7ac6ed84d888ccffd88e
+ddbf7bf9c3fe39f24fff27ef88d061ea14d8c5f11fa8e547ff9ad8bbd902e363b9ff85f9
+6c9fe5941ded6eb4d881fea50ee032d865ff9ec993ce5eff86c0ed72cbfa62fe35f5aaca
+44befd0d93e0c11aaff77efea4f683fbc05aedb404ed52e041d70effbe24d9fe3bc84fe6
+a5c0e18715c4e585eeafe562ff6ff69cfa79fea5cb9dd915edca0de0c495f1884ae5bf79
+e00797f77efbcc85da93fb9b1cfca745ff23f3aa3b6bfe0e9ee5a50b92d89bd579e0adff
+09f8b5ff8136a5d7fb6eefb90afa4ea6fe87f5ce1ad93dc9ef61d9c4a0fa27ffbf4ac1f2
+92fe86f1bf4bfd0bf9a5c4e93ba5ffb754e586b6c603ffa0ee67b8ff34f186e060d849d7
+15d863ddad37ffd89ed291f86cf2af67fb73bfed86f96efe3797f7affd78d959fe3bf094
+dcb90ab6d646ed30f777fe538fffa84ae421d8fe9f16fab4fed45de0a551ec78d863e4cb
+81e6d070dd5ac6f8ecafc2fb2affb6f55dfb03f7c5439cdf934997edb6fe883ab2cc65e6
+7df2ca53dd329eed93fba812ff87fb56d2af69ed9ffa60d047dd14a9e283d977e01d93fb
+d80696f61dd0fe80e078d821c9ea6fd9aafe2cfbb8f36dffa9ed08f4c261b943ff15ade0
+c44be5b3f10caed821da83d1ed50dc42ed07d097d884cb2beda7fe87dd80d861e0a4bfde
+65ccf884ffa540cff2a44587b0f12ec7fe1af937ffb65dff31b9fa93ee9f1c9352e079d1
+63ec36df6ddcb07cfec161fbb9d95edd03bff7da1cffafd32c97eb82c6ff7ad35ae0c04f
+dd02e57af2b909db2fe497fa88cbff35f4b6fe57f2b9498bf3d27adbaf3bed5cf98cfeae
+43fabf5a9bdd930c9fe0934ec1fe6ee58ff2c697c1fb2f93ff9a39d89ff365ffaff518b6
+ff93cca6ff68f31ef95cfe7ada52f21bff94fbc33cf224fb9418d256c2ed9360ddb9e91e
+beff619bdec29ed111f3afd98706d847ffcfd9ff32ed95d989cc94ffbf4bed1ce5b12ff1
+22ff79f4d8529af1933ffeadf61ffcab43dc08fe79f2b274f79ad82efcc693ff7cd81fec
+5293d89928a5d86dffc6e65fbfff4cfb9ecbbc2fde60e387d104f5ce47eeb6fe36d0f97b
+b2d52afd1cec5edd70b9ef09cbf978ff31de9543c1e562c80efb52bfe086d890dd97d036
+e5afcf5bea0d86ffabd778edaff59dfb09b8fa27ff5bf77acfaff28947f070e99752f1c2
+fe79e4a96301b6c95afa14fe51f1109ffa91d886ffcf78e0a4cc438affc976ddbe6ae079
+d867cdf971f1a5d92efecfa846ffaf79e657c3f167ffa5c3ef79fbb8ed01e59824b3fb14
+aee56cf10affa7c3f313ffa3ed7ab3ff70d881deaf18eb44e399cab679f634fecf7fe0a8
+51d290e57acbfb5aa3fb80f279e79c34fb4dff03f272ffa264fb93c9afdd9960eebc4bd8
+37e062d0eb81d992d896dd36e60cffbfabfe42c0fb933db6f428bffbef83fda7bfdf86d8
+80e5d030e466f3509efbc20efbade9bc12fd5af9cb0dffb0ed159fe0b74cb6ec9321e8be
+65edc138fba00ce0af40fd06e05ad97ffe86d1f179cf9edd2dd888d96bed4294d8b63bb9
+fb1ec3e627f260ff95beff86f84affd887e4a520fa57fec3ef27b0fe05abedd626e09fd1
+21f4c3aded9fc5a7d612edc228f150fe2bf9c102ff87fec57dff9951fd68f410fe6afb86
+d879dd21cba5e028d0ed7ccd9dea8851d823e445a4f426ffb878fea5cb0bbfec3c8ee57b
+f22883e2a5ed3095e9c13d93febf27ff8cf86bc8ff7af9d011feb66eddb87af6c095d2af
+ff37cd4ddf38bef93efe5cf693ff57f798bfff78f993da6ae09f57fbaecd3ded52cf0eaf
+de9302fb49c0d993dd89119efbd85bd0f83892feaf41ffb560fe0fce59f73bfdb66de09b
+bed88de555e895cfb510adf227e5c01ccbace54dc9a8ee5af993fe7af781ffb013fa4cfe
+38ddff9cf27affc770e0af3aedc354ffa9f75cd1ffb74db3d8fec14ad1afff8760fbd85d
+e284c4e516dd52b3d83fabe082cbf54fffce20dd5ff96b9ff286f79bff64ace486ed74c9
+19b8ce22e14dd428ef51ff86f7be8e01e5a1c2fc6bf3d875f1afcc9aff78f33ab8ecbe4a
+87ea9d67bce06ac7eb7ddabf93e580de89d97acaf945ff08f338b9d384f53efadc6ad8b5
+78fea5ef72c5a3ec01b9cd2de051d904db4de1a0d893c7b67b
+> >> /Halftone defineresource
diff --git a/gs/lib/lp386.bat b/gs/lib/lp386.bat
new file mode 100755
index 000000000..f300095fc
--- /dev/null
+++ b/gs/lib/lp386.bat
@@ -0,0 +1,2 @@
+
+@gs386 -sDEVICE=djet500 -dNOPAUSE -- gslp.ps -fCourier9 %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/gs/lib/lp386r2.bat b/gs/lib/lp386r2.bat
new file mode 100755
index 000000000..5c403ba8e
--- /dev/null
+++ b/gs/lib/lp386r2.bat
@@ -0,0 +1,2 @@
+
+@gs386 -sDEVICE=djet500 -dNOPAUSE -- gslp.ps -2r %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/gs/lib/lpgs.bat b/gs/lib/lpgs.bat
new file mode 100755
index 000000000..ef6b1c5ff
--- /dev/null
+++ b/gs/lib/lpgs.bat
@@ -0,0 +1,2 @@
+
+@gs -sDEVICE#djet500 -dNOPAUSE -sPROGNAME=lpgs -- gslp.ps -fCourier9 %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/gs/lib/lpr2.bat b/gs/lib/lpr2.bat
new file mode 100755
index 000000000..bef670f75
--- /dev/null
+++ b/gs/lib/lpr2.bat
@@ -0,0 +1,2 @@
+
+@gs -sDEVICE#djet500 -dNOPAUSE -sPROGNAME=lpr2 -- gslp.ps -2r %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/gs/lib/pdf2dsc.ps b/gs/lib/pdf2dsc.ps
index ed8ad3d5d..3925d7d44 100644
--- a/gs/lib/pdf2dsc.ps
+++ b/gs/lib/pdf2dsc.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -27,6 +27,10 @@
% Then display the PDF file with
% gs tempfilename
%
+% Modified by Geoff Keating <geoffk@ozemail.com.au> 21/12/98:
+% Add DocumentMedia, PageMedia comments
+% Use inherited BoundingBox and Orientation
+% Reformat, add new macro 'puts', generally clean up
% Modified by Johannes Plass <plass@dipmza.physik.uni-mainz.de> 1996-11-05:
% Adds BoundingBox and Orientation if available.
% Modified by rjl/lpd 9/19/96
@@ -41,80 +45,119 @@
% Modified by L. Peter Deutsch for GS 3.33
% Originally by Russell Lang 1995-04-26
+% (str1) (str2) concatstr (str1str2)
+/concatstr {
+ 2 copy length exch length add string
+ dup dup 5 2 roll copy length
+% stack: newstring newstring str2 str1-length
+ exch putinterval
+} bind def
+
/DSCfile DSCname (w) file def
+/puts { DSCfile exch writestring } bind def
/DSCstring 255 string def
+/MediaTypes 10 dict def
+
GS_PDF_ProcSet begin
pdfdict begin
PDFname (r) file
pdfopen begin
-% setup for loop (init increment limit)
- /FirstPage where { pop FirstPage } { 1 } ifelse
- 1
- /LastPage where { pop LastPage } { pdfpagecount } ifelse
+ /FirstPage where { pop } { /FirstPage 1 def } ifelse
+ /LastPage where { pop } { /LastPage pdfpagecount def } ifelse
+
+% scan through for media sizes, keep them in the dictionary
+ FirstPage 1 LastPage {
+ pdfgetpage /MediaBox pget pop % MediaBox is a required attribute
+ aload pop
+ 3 -1 roll sub 3 1 roll exch sub exch
+ 2 array astore
+ aload 3 1 roll 10 string cvs exch 10 string cvs
+ (x) exch concatstr concatstr cvn
+ MediaTypes 3 1 roll exch put
+ } for
+
% write header and prolog
-DSCfile (%!PS-Adobe-3.0\n) writestring
-Trailer /Info knownoget
- {
- dup /Title knownoget
+ (%!PS-Adobe-3.0\n) puts
+ Trailer /Info knownoget
{
- DSCfile (%%Title: ) writestring
- DSCfile exch write==
+ dup /Title knownoget
+ {
+ (%%Title: ) puts
+ DSCfile exch write==
+ }
+ if
+ /CreationDate knownoget
+ {
+ (%%CreationDate: ) puts
+ DSCfile exch write==
+ }
+ if
}
if
- /CreationDate knownoget
- {
- DSCfile (%%CreationDate: ) writestring
- DSCfile exch write==
- }
- if
- }
-if
-DSCfile (%%Pages: ) writestring
-DSCfile 1 index 3 index sub 1 add DSCstring cvs writestring
-DSCfile (\n%%EndComments\n) writestring
-DSCfile (%%BeginProlog\n) writestring
-DSCfile (/Page null def\n/Page# 0 def\n/PDFSave null def\n/DSCPageCount 0 def\n) writestring
-DSCfile (/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def\n) writestring
-DSCfile (GS_PDF_ProcSet begin\npdfdict begin\n) writestring
-DSCfile (%%EndProlog\n) writestring
-DSCfile (%%BeginSetup\n) writestring
-DSCfile PDFname write==only
-DSCfile ( \(r\) file pdfopen begin\n) writestring
-DSCfile (%%EndSetup\n) writestring
-% process each page
- {
-DSCfile (%%Page: ) writestring
-DSCfile 1 index DSCstring cvs writestring
-DSCfile ( ) writestring
-DSCfile 1 index DSCstring cvs writestring
-DSCfile (\n) writestring
+ % This is really supposed to be sorted by frequency of usage...
+ (%%DocumentMedia: )
+ MediaTypes {
+ exch pop
+ 1 index puts
+ (y) puts dup 1 get DSCstring cvs puts
+ (x) puts dup 0 get DSCstring cvs puts
+ ( ) puts dup 0 get DSCstring cvs puts
+ ( ) puts 1 get DSCstring cvs puts
+ ( 70 white ()\n) puts
+ pop (%%+ )
+ } forall
+ pop
+
+ (%%Pages: ) puts
+ LastPage FirstPage sub 1 add DSCstring cvs puts
+ (\n%%EndComments\n) puts
+ (%%BeginProlog\n) puts
+ (/Page null def\n/Page# 0 def\n/PDFSave null def\n) puts
+ (/DSCPageCount 0 def\n) puts
+ (/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def\n) puts
+ (GS_PDF_ProcSet begin\npdfdict begin\n) puts
+ (%%EndProlog\n) puts
+ (%%BeginSetup\n) puts
+ DSCfile PDFname write==only
+ ( \(r\) file pdfopen begin\n) puts
+ (%%EndSetup\n) puts
+ % process each page
+ FirstPage 1 LastPage {
+ (%%Page: ) puts
+ dup DSCstring cvs puts
+ ( ) puts
+ dup DSCstring cvs puts
+ (\n) puts
-%BEGIN ##jp##
-dup pdfgetpage /CropBox knownoget { % file maxpage pageno cropbox
- DSCfile (%%PageBoundingBox: ) writestring
- {DSCfile exch write=only DSCfile ( ) writestring} forall
- DSCfile (\n) writestring
-} if
-dup pdfgetpage /Rotate knownoget { % file maxpage pageno angle
- DSCfile (%%PageOrientation: ) writestring
- 90 div cvi 4 mod dup 0 lt {4 add} if
- [(Portrait) (Landscape) (UpsideDown) (Seascape)] exch get
- DSCfile exch writestring
- DSCfile (\n) writestring
-} if
-%END ##jp##
+ dup pdfgetpage
+ dup /MediaBox pget pop
+ (%%PageMedia: y) puts
+ aload pop 3 -1 roll sub DSCstring cvs puts
+ (x) puts exch sub DSCstring cvs puts
+ (\n) puts
+ dup /CropBox pget {
+ (%%PageBoundingBox: ) puts
+ {DSCfile exch write=only ( ) puts} forall
+ (\n) puts
+ } if
+ /Rotate pget {
+ (%%PageOrientation: ) puts
+ 90 div cvi 4 mod dup 0 lt {4 add} if
+ [(Portrait) (Landscape) (UpsideDown) (Seascape)] exch get puts
+ (\n) puts
+ } if
-DSCfile exch DSCstring cvs writestring
-DSCfile ( DoPDFPage\n) writestring
+ DSCfile exch DSCstring cvs writestring
+ ( DoPDFPage\n) puts
} for
currentdict pdfclose
end
end
end
% write trailer
-DSCfile (%%Trailer\n) writestring
-DSCfile (currentdict pdfclose\nend\nend\nend\n) writestring
-DSCfile (%%EOF\n) writestring
+(%%Trailer\n) puts
+(currentdict pdfclose\nend\nend\nend\n) puts
+(%%EOF\n) puts
% close output file and exit
DSCfile closefile
quit
diff --git a/gs/lib/pdf_base.ps b/gs/lib/pdf_base.ps
index fcc73aa6b..90cdac638 100644
--- a/gs/lib/pdf_base.ps
+++ b/gs/lib/pdf_base.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -301,21 +301,28 @@ pdfdict begin
} ifelse
} bind def
/oforce /exec load def
-/oget % <array> <index> oget <object>
+/oget { % <array> <index> oget <object>
% <dict> <key> oget <object>
- { 2 copy get dup xcheck
- { exec dup 4 1 roll put }
- { exch pop exch pop }
- ifelse
- } bind def
+ 2 copy get dup xcheck {
+ exec dup 4 1 roll put
+ } {
+ exch pop exch pop
+ } ifelse
+} bind def
% A null value in a dictionary is equivalent to an omitted key;
% we must check for this specially.
-/knownoget
- { 2 copy known
- { oget dup null eq { pop false } { true } ifelse }
- { pop pop false }
- ifelse
- } bind def
+/knownoget {
+ 2 copy .knownget {
+ dup xcheck {
+ exec dup 4 1 roll put
+ } {
+ exch pop exch pop
+ } ifelse
+ dup null eq { pop false } { true } ifelse
+ } {
+ pop pop false
+ } ifelse
+} bind def
% PDF 1.1 defines a 'foreign file reference', but not its meaning.
% Per the specification, we convert these to nulls.
@@ -459,12 +466,21 @@ pdfdict begin
% Extract and apply filters.
/filterparms { % <dict> <DPkey> <Fkey> filterparms
% <dict> <parms> <filternames>
- exch 2 index exch .knownget not { null } if
- exch 2 index exch .knownget not { { } } if
- dup type /nametype eq {
- 1 array astore
- 1 index null ne { exch 1 array astore exch } if
- } if
+ 2 index exch .knownget {
+ exch 2 index exch .knownget {
+ % Both filters and parameters.
+ exch dup type /nametype eq {
+ 1 array astore exch 1 array astore exch
+ } if
+ } {
+ % Filters, but no parameters.
+ null exch
+ dup type /nametype eq { 1 array astore } if
+ } ifelse
+ } {
+ % No filters: ignore parameters, if any.
+ pop null { }
+ } ifelse
} bind def
/applyfilters { % <parms> <source> <filternames> applyfilters <stream>
2 index null eq {
@@ -493,7 +509,7 @@ pdfdict begin
% Stack: readdata? dict parms filternames
4 -1 roll exch
pdf_decrypt_stream
- apply_filters
+ applyfilters
} {
exch dup /FilePosition .knownget {
1 index /File get exch setfileposition
@@ -515,7 +531,7 @@ pdfdict begin
} {
dup type /filetype ne {
% Use a SubFileDecode filter to read from a string.
- 0 () SubFileDecode filter
+ 0 () /SubFileDecode filter
} if
} ifelse
} {
diff --git a/gs/lib/pdf_draw.ps b/gs/lib/pdf_draw.ps
index 1f196d94f..7d8f02fd4 100644
--- a/gs/lib/pdf_draw.ps
+++ b/gs/lib/pdf_draw.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -214,6 +214,10 @@ end
% ---------------- Color setting ---------------- %
+/01_1 [0 1] readonly def
+/01_3 [0 1 0 1 0 1] readonly def
+/01_4 [0 1 0 1 0 1 0 1] readonly def
+
% The keys here are resolved (PostScript, not PDF) color space names.
/csncompdict mark
/DeviceGray { pop 1 }
@@ -249,33 +253,37 @@ end
}
/DeviceCMYK { }
/CalGray {
- 1 oget dup /Gamma knownoget {
- exch dup length 1 add dict .copydict
- dup /DecodeA 4 -1 roll /exp load 2 packedarray cvx put
+ 1 oget 6 dict begin
+ dup /Gamma knownoget {
+ /exp load 2 packedarray cvx /DecodeA exch def
} if
- /CIEBasedA exch 2 array astore
+ dup /BlackPoint knownoget { /BlackPoint exch def } if
+ dup /WhitePoint knownoget { /WhitePoint exch def } if
+ pop [ /CIEBasedA currentdict end ]
}
/CalRGB {
- 1 oget dup /Gamma known 1 index /Matrix known or {
- dup length 2 add dict .copydict
- dup /Matrix knownoget { 1 index /MatrixABC 3 -1 roll put } if
- dup /Gamma knownoget {
- [ exch { /exp load 2 packedarray cvx } forall
- ] 1 index /DecodeABC 3 -1 roll put
- } if
- }
- if /CIEBasedABC exch 2 array astore
+ 1 oget 6 dict begin
+ dup /Gamma knownoget {
+ [ exch { /exp load 2 packedarray cvx } forall
+ ] /DecodeABC exch def
+ } if
+ dup /Matrix knownoget { /MatrixABC exch def } if
+ dup /BlackPoint knownoget { /BlackPoint exch def } if
+ dup /WhitePoint knownoget { /WhitePoint exch def } if
+ pop [ /CIEBasedABC currentdict end ]
}
/CalCMYK {
pop /DeviceCMYK % not defined by Adobe
}
/Lab {
- 1 oget dup length 3 add dict .copydict
+ 1 oget 6 dict begin
dup /Range knownoget not { [-100 100 -100 100] } if
- [-100 0 null null null null] dup 2 4 -1 roll putinterval
- 1 index /RangeABC 3 -1 roll put
- //cslabinit exch copy
- /CIEBasedABC exch 2 array astore
+ [0 100 null null null null] dup 2 4 -1 roll putinterval
+ /RangeABC exch def
+ //cslabinit { def } forall
+ dup /BlackPoint knownoget { /BlackPoint exch def } if
+ dup /WhitePoint knownoget { /WhitePoint exch def } if
+ pop [ /CIEBasedABC currentdict end ]
}
/ICCBased {
% Since the PostScript interpreter doesn't support these yet,
@@ -297,10 +305,23 @@ end
4 array astore
}
/Indexed {
- aload pop 3 -1 roll resolvecolorspace 3 1 roll
- oforce dup type /stringtype eq {
- pop
- } {
+ aload pop 3 -1 roll resolvecolorspace
+ % If the underlying space is a Lab space, we must scale
+ % the output of the lookup table as part of DecodeABC.
+ dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
+ dup 1 get /DecodeLMN known {
+ 1 get dup length dict copy
+ begin /DecodeABC [ 0 2 4 {
+ RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
+ RangeABC 3 index get /add load
+ DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
+ } for ] def
+ /RangeABC //01_3 def
+ currentdict end /CIEBasedABC exch 2 array astore
+ } if
+ } if
+ 3 1 roll
+ oforce dup type /stringtype ne {
% The color lookup table is a stream.
% Get its contents. Don't lose our place in PDFfile.
% Stack: /Indexed basespace hival lookup
@@ -315,11 +336,11 @@ end
% Stack: filepos /Indexed basespace hival table
5 -1 roll PDFfile exch setfileposition
}
- ifelse 4 array astore
+ if 4 array astore
}
/Pattern
{ dup type /nametype ne
- { dup length 1 ge
+ { dup length 1 gt
{ 1 get resolvecolorspace
/Pattern exch 2 array astore
}
@@ -361,36 +382,43 @@ end
if
count 1 gt
} bdef
-
+
/.pdfpaintproc { % <patdict> <resdict> .pdfpaintproc -
DEBUG { (%Begin PaintProc) = flush } if
+ % For uncolored patterns, we have to unbind the current
+ % color and color space before running the PaintProc.
+ % There's no harm in doing this for colored patterns,
+ % so for simplicity, we always do it.
+ q
+ null sc1 null SC1
exch false resolvestream pdfopdict .pdfruncontext
+ Q
DEBUG { (%End PaintProc) = flush } if
-} bind def
+} bdef
-/resolvepattern % <patternstreamdict> resolvepattern <patterndict>
- { % Don't do the resolvestream now: just capture the data
+/resolvepattern { % <patternstreamdict> resolvepattern <patterndict>
+ % Don't do the resolvestream now: just capture the data
% from the file if necessary.
- dup length dict copy
- dup /FilePosition .knownget
- { 1 index /File get dup fileposition 3 1 roll
+ dup length dict copy
+ dup /FilePosition .knownget {
+ 1 index /File get dup fileposition 3 1 roll
% Stack: dict savepos pos file
- dup 3 -1 roll setfileposition
- dup 3 index /Length get string readstring pop
+ dup 3 -1 roll setfileposition
+ dup 3 index /Length get string readstring pop
% Stack: dict savepos file string
- 3 1 roll exch setfileposition
- 1 index /File 3 -1 roll put
- dup /FilePosition undef
- }
- if
- dup [
- 1 index /Resources knownoget { oforce } { 0 dict } ifelse
- /.pdfpaintproc cvx
- ] cvx /PaintProc exch put
- DEBUG {
- (%Pattern: ) print dup === flush
- } if
- } bdef
+ 3 1 roll exch setfileposition
+ 1 index /File 3 -1 roll put
+ dup /FilePosition undef
+ } if
+ dup /PaintProc [
+ % Bind the resource dictionary into the PaintProc.
+ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
+ /.pdfpaintproc cvx
+ ] cvx put
+ DEBUG {
+ (%Pattern: ) print dup === flush
+ } if
+} bdef
drawopdict begin
/g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
@@ -445,9 +473,6 @@ end
% Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
% color space names.
-/01_1 [0 1] readonly def
-/01_3 [0 1 0 1 0 1] readonly def
-/01_4 [0 1 0 1 0 1 0 1] readonly def
/defaultdecodedict mark
/DeviceGray { pop //01_1 }
/DeviceRGB { pop //01_3 }
@@ -458,69 +483,78 @@ end
/DeviceN {
dup 1 oget length [ exch {0 1} repeat ] readonly
}
+ /Indexed {
+ pop [ 0 1 BitsPerComponent bitshift 1 sub ]
+ }
.dicttomark readonly def
-/makeimagedict
- { dup length dict
- 1 index /ColorSpace knownoget
- { resolvecolorspace
- dup type /arraytype eq { dup length 1 eq { 0 get } if } if
- exch begin /ColorSpace exch def
- }
- { begin
- }
- ifelse
- /ImageType 1 def
- % Always define ImageMask appropriately.
- dup /ImageMask knownoget dup { and } if
- /ImageMask exch def
- /Width 2 copy oget def
- /Height 2 copy oget def
- /BitsPerComponent 2 copy oget def
- /Decode 2 copy knownoget not
- { % Decode is required for the PostScript image operators.
- ImageMask
- { [0 1]
- }
- { ColorSpace dup type /arraytype eq { 0 get } if dup /Indexed eq
- { pop [ 0 1 BitsPerComponent bitshift 1 sub ] }
- { defaultdecodedict exch get ColorSpace exch exec }
- ifelse
- }
- ifelse
- }
- if def
- /Interpolate 2 copy knownoget { def } { pop } ifelse
- /ImageMatrix Width 0 0 Height neg 0 Height 6 array astore def
+/makeimagedict { % <resdict> <newdict> makeimagedict -
+ % On return, newdict' is currentdict
+ begin
+ /Width 2 copy oget def
+ /Height 2 copy oget def
+ /BitsPerComponent 2 copy oget def
+ /Interpolate 2 copy knownoget { def } { pop } ifelse
+ makeimagekeys
+} bdef
+/makeimagekeys { % <resdict> makeimagekeys <imagemask>
+ % newdict is currentdict
+ % Assumes Width, Height, BPC, Interpolate already copied.
+ /ImageType 1 def
+ /ImageMatrix Width 0 0 Height neg 0 Height 6 array astore def
+ dup /ImageMask knownoget dup { and } if {
+ % Image mask
+ % Decode is required for the PostScript image operators.
+ /Decode 2 copy knownoget not { //01_1 } if def
+ % BitsPerComponent may be missing for masks.
+ % The spec requires it, but some producers omit it, and
+ % Acrobat Reader doesn't care.
+ /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
+ true
+ } {
+ % Opaque image
+ dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
+ % Decode is required for the PostScript image operators.
+ /Decode 2 copy knownoget not {
+ ColorSpace //defaultdecodedict
+ ColorSpace dup type /arraytype eq { 0 get } if get exec
+ } if def
+ false
+ } ifelse
% Even though we're going to read data,
% pass false to resolvestream so that
% it doesn't try to use Length (which may not be present).
- false resolvestream
- /DataSource exch def
- currentdict end
+ exch false resolvestream /DataSource exch def
} bdef
/DoImage {
- makeimagedict
- dup /Mask knownoget {
+ dup length 6 add dict makeimagedict doimage
+} bdef
+/doimage { % <imagemask> doimage -
+ % imagedict is currentdict, gets popped from dstack
+ DataSource exch
+ currentdict /Mask knownoget {
dup type /arraytype eq {
- 1 index /ImageType 4 put
- 1 index /MaskColor 3 -1 roll put
+ /ImageType 4 def
+ /MaskColor exch def
} {
% Mask is a stream, another Image XObject.
- makeimagedict
+ dup length dict makeimagedict
+ currentdict end currentdict end
4 dict begin
/ImageType 3 def
/InterleaveType 3 def
/MaskDict exch def
/DataDict exch def
- currentdict end
} ifelse
} if
- dup /ImageMask get
- { setfillcolor imagemask }
- { dup /ColorSpace get csset setcolorspace pop image }
+ % Stack: datasource imagemask
+ { currentdict end setfillcolor imagemask }
+ { ColorSpace setcolorspace currentdict end image }
ifelse
+ % Close the input stream, unless it is PDFfile or
+ % PDFsource.
+ dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
} bdef
/DoForm {
@@ -548,46 +582,44 @@ end
% ---------------- In-line images ---------------- %
% Undo the abbreviations in an in-line image dictionary.
-% Note that these can appear as keys, values, or members of array values.
-% /I is ambiguous; we check specially for it below.
-/unabbrevdict mark
- % Top-level dictionary keys
+% Note that we must look inside array values.
+% /I is context-dependent.
+/unabbrevkeydict mark
/BPC /BitsPerComponent /CS /ColorSpace /D /Decode /DP /DecodeParms
- /F /Filter /H /Height /IM /ImageMask /W /Width
- % Values
+ /F /Filter /H /Height /I /Interpolate /IM /ImageMask /W /Width
+.dicttomark readonly def
+/unabbrevvaluedict mark
/AHx /ASCIIHexDecode /A85 /ASCII85Decode /CC /CalCMYK
/CCF /CCITTFaxDecode /CG /CalGray /CR /CalRGB
/DCT /DCTDecode /CMYK /DeviceCMYK /Fl /FlateDecode
/G /DeviceGray /RGB /DeviceRGB
/I /Indexed /LZW /LZWDecode /RL /RunLengthDecode
.dicttomark readonly def
-/unabbrev % <obj> unabbrev <obj'>
- { dup type /nametype eq
- { unabbrevdict 1 index .knownget { exch pop } if
- }
- { dup type /arraytype eq
- { dup 0 1 2 index length 1 sub
- { 2 copy get unabbrev put dup
- }
- for pop
- }
- if
- }
- ifelse
- } bdef
+/unabbrevtypedict mark
+ /nametype {
+ //unabbrevvaluedict 1 index .knownget { exch pop } if
+ }
+ /arraytype {
+ dup 0 1 2 index length 1 sub {
+ 2 copy get unabbrevvalue put dup
+ } for pop
+ }
+.dicttomark readonly def
+/unabbrevvalue { % <obj> unabbrevvalue <obj'>
+ oforce //unabbrevtypedict 1 index type .knownget { exec } if
+} bdef
drawopdict begin
/BI { mark } bdef
- /ID
- { counttomark
- { counttomark 1 roll
- dup /I eq { pop /Interpolate } { unabbrev } ifelse
- }
- repeat
- /File PDFsource
- .dicttomark DoImage
- PDFsource token pop /EI ne { /ID cvx /syntaxerror signalerror } if
- } bdef
+ /ID {
+ counttomark 2 idiv dup 6 add dict begin {
+ exch //unabbrevkeydict 1 index .knownget { exch pop } if
+ exch unabbrevvalue def
+ } repeat pop
+ /File PDFsource def
+ currentdict makeimagekeys doimage
+ PDFsource token pop /EI ne { /ID cvx /syntaxerror signalerror } if
+ } bdef
end
% ================================ Text ================================ %
diff --git a/gs/lib/pdf_font.ps b/gs/lib/pdf_font.ps
index e3182ac0a..dffcde41e 100644
--- a/gs/lib/pdf_font.ps
+++ b/gs/lib/pdf_font.ps
@@ -15,7 +15,7 @@
% License requires that the copyright notice and this notice be preserved on
% all copies.
-% $Id$
+
% pdf_font.ps
% PDF font operations.
diff --git a/gs/lib/pdf_main.ps b/gs/lib/pdf_main.ps
index 2c1884bfa..87e240db6 100644
--- a/gs/lib/pdf_main.ps
+++ b/gs/lib/pdf_main.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -15,6 +15,7 @@
% License requires that the copyright notice and this notice be preserved on
% all copies.
+
% pdf_main.ps
% PDF file- and page-level operations.
@@ -206,15 +207,15 @@ pdfdict begin
% We can't use prevline to check for the %%EOF, because if the
% %%EOF isn't followed by an EOL, prevline will read past the
% end of the file, and the file will get closed.
+ % Acrobat apparently accepts files in which the %%EOF was
+ % truncated to %%EO (!); we do the same.
5 sub 2 copy setfileposition
1 index (xxxxxx) readstring pop
- dup
- dup (\015%%EOF) eq exch (\012%%EOF) eq or
- exch 1 5 getinterval
- dup (\015%%EO) eq exch (\012%%EO) eq or
- or
- not
- { /pdfopen cvx /syntaxerror signalerror } if
+ (\015%%EO) anchorsearch { pop pop } {
+ (\012%%EO) anchorsearch { pop pop } {
+ pop /pdfopen cvx /syntaxerror signalerror
+ } ifelse
+ } ifelse
1 add setfileposition
prevline token pop dup type /integertype eq
{ exch pop cvi % xref start position
@@ -373,10 +374,11 @@ pdfdict begin
} bind def
/resolvedest { % <name|string|other> resolvedest <other|null>
dup type /nametype eq {
- Trailer /Root oget /Dests knownoget
- { exch knownoget not { null } if }
- { null }
- ifelse
+ Trailer /Root oget /Dests knownoget {
+ exch knownoget not { null } if
+ } {
+ null
+ } ifelse
} {
dup type /stringtype eq {
Trailer /Root oget /Names oget /Dests knownoget {
@@ -466,34 +468,35 @@ end readonly def
/DSCPageCount DSCPageCount 1 add store
} bind def
-/pdfshowpage_setpage % <pagedict> pdfshowpage_setpage <pagedict>
- {
- 3 dict % for setpagedevice
- % Stack: pagedict setpagedict
+/pdfshowpage_setpage { % <pagedict> pdfshowpage_setpage <pagedict>
+ 4 dict begin % for setpagedevice
+ % Stack: pagedict
% We want to look at Rotate for displays, but not for printers.
% The following is a hack, but we don't know a better way to do this.
- currentpagedevice /OutputFile known not
- { dup /Orientation 3 index /Rotate pget not { 0 } if 90 idiv
+ currentpagedevice dup /OutputFile known not {
+ /Orientation 2 index /Rotate pget not { 0 } if 90 idiv
% Rotate specifies *clockwise* rotation!
- neg 3 and put
- }
- if
- % Stack: pagedict setpagedict
- 1 index /MediaBox pget
- { % Set the page size.
- boxrect [ 2 index 2 index ]
- % Stack: pagedict setpagedict llx lly urx ury pagesize
- 5 index exch /PageSize exch put
- % Stack: pagedict contents setpagedict llx lly urx ury
- pop pop exch neg exch % only negate Y offset
- [ 3 1 roll ]
- % Stack: pagedict setpagedict pageoffset
- 1 index exch /PageOffset exch put
- }
- if
- % Stack: pagedict setpagedict
- setpagedevice
- } bind def
+ neg 3 and def
+ } if
+ % Stack: pagedict currentpagedict
+ 1 index /MediaBox pget {
+ % Set the page size.
+ boxrect [ 2 index 2 index ]
+ % Stack: pagedict currentpagedict llx lly width height pagesize
+ /PageSize exch def
+ % Set the offset on the page.
+ % Stack: pagedict currentpagedict llx lly width height
+ pop pop exch neg exch neg
+ % Stack: pagedict currentpagedict -llx -lly
+ [ 3 1 roll /translate load 4 index /Install .knownget {
+ 1 array astore 0 /get load /exec load
+ } if ] cvx
+ % Stack: pagedict currentpagedict installproc
+ /Install exch def
+ } if
+ % Stack: pagedict currentpagedict
+ pop currentdict end setpagedevice
+} bind def
/pdfshowpage_finish % <pagedict> pdfshowpage_finish -
{
diff --git a/gs/lib/pdf_ops.ps b/gs/lib/pdf_ops.ps
index 5cd9003ae..f1f81f545 100644
--- a/gs/lib/pdf_ops.ps
+++ b/gs/lib/pdf_ops.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -101,6 +101,7 @@ nodict readonly pop
/csdevgray [/DeviceGray] readonly def
/csdevrgb [/DeviceRGB] readonly def
/csdevcmyk [/DeviceCMYK] readonly def
+/cspattern [/Pattern] readonly def
/nullpattern1 mark
/PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0]
/XStep 1 /YStep 1 /PaintProc { }
@@ -122,7 +123,7 @@ nodict readonly pop
/Indexed { 0 } bind
/Pattern {
dup type /nametype eq 1 index length 1 eq or {
- //nullpattern1 matrix makepattern
+ pop //cspattern //nullpattern1 matrix makepattern
} {
//nullpattern2 matrix makepattern 1 index 1 get csset
% Stack: patternspace nullpattern basecolor basespace
@@ -168,7 +169,7 @@ nodict readonly pop
/Indexed /CIEBasedA load def
/Pattern
{ dup currentcolorspace eq { pop } { setcolorspace } ifelse
- dup /Matrix get makepattern setcolor
+ dup /Matrix .knownget not { matrix } if makepattern setcolor
} bdef
end def
/setgcolor % (null | <color...>) <colorspace> setgcolor -
diff --git a/gs/lib/pfbtopfa b/gs/lib/pfbtopfa
new file mode 100755
index 000000000..0e08436ae
--- /dev/null
+++ b/gs/lib/pfbtopfa
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Convert .pfb fonts to .pfa format
+
+exec gs -q -dNODISPLAY -- pfbtopfa.ps $1 $2
diff --git a/gs/lib/pfbtopfa.ps b/gs/lib/pfbtopfa.ps
new file mode 100644
index 000000000..4beff17e9
--- /dev/null
+++ b/gs/lib/pfbtopfa.ps
@@ -0,0 +1,36 @@
+% Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+%
+% This file is part of Aladdin Ghostscript.
+%
+% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+% or distributor accepts any responsibility for the consequences of using it,
+% or for whether it serves any particular purpose or works at all, unless he
+% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+% License (the "License") for full details.
+%
+% Every copy of Aladdin Ghostscript must include a copy of the License,
+% normally in a plain ASCII text file named PUBLIC. The License grants you
+% the right to copy, modify and redistribute Aladdin Ghostscript, but only
+% under certain conditions described in the License. Among other things, the
+% License requires that the copyright notice and this notice be preserved on
+% all copies.
+
+
+% pfbtopfa.ps
+% Convert a .pfb font to .pfa format.
+
+[ shellarguments {
+ counttomark 2 eq {
+ /pfa exch def /pfb exch def pop
+ /in1 pfb (r) file def
+ /in in1 true /PFBDecode filter def
+ /out pfa (w) file def
+ { in read not { exit } if out exch write } loop
+ out closefile in closefile in1 closefile
+ quit
+ } {
+ cleartomark (Usage: pfbtopfa input.pfb output.pfb) = flush
+ } ifelse
+} {
+ pop
+} ifelse
diff --git a/gs/lib/ps2ai.ps b/gs/lib/ps2ai.ps
index f0a7f755c..b802bb7fc 100644
--- a/gs/lib/ps2ai.ps
+++ b/gs/lib/ps2ai.ps
@@ -1,5 +1,5 @@
%!
-% Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1994 , 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -21,7 +21,13 @@
%
% ps2ai.ps - a postscript to editable adobe illustrator file filter
%
-/vers {2.13} def % April 25, 1994
+/vers {2.14} def % January 31, 1999
+
+% conditional def ( if the key is already defined before, don't
+% redefine it. This can be used by other programs to overwrite
+% some settings from externally
+%
+/cdef { 1 index where { pop pop pop } { def } ifelse } def
%
%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
%
@@ -32,26 +38,30 @@
% gs -q -dNODISPLAY ps2ai.ps file.ps
% or
% cat ps2ai.ps file.ps | lpr (then look in log file)
+%
+% or from within gsview via:
+% Edit->Convert to vector format
%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
% Options
%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
% Output Options: directly to a file or standard out
%
-/jout false def % true=file false=stdout (default=false)
-/joutput (ps2ai.out.aips) def % Name of Output file
+/jout false cdef % true=file false=stdout (default=false)
+/joutput (ps2ai.out.aips) cdef % Name of Output file
%
%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
%
% Other Options
%
-/jtxt3 true def % output text in AI3 form (false=ai88)
+/jtxt3 true cdef % output text in AI3 form (false=ai88)
% for coreldraw/photoshop readable output
-/joutln false def % use font outline instead of font
+/joutln false cdef % use font outline instead of font
/jerr false def % use error handling (ie die gracefully)
/jbiterr false def % attempt to handle bitmap fonts (kludge)
/jMacGS false def % true if using MacGS (not fully implemented yet)
/jMacfix true def % convert filled boxes to lines (only usefull with
% laserwriter 8 postscript input)
+
%
%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
% No options below here
@@ -70,6 +80,7 @@
% URL ftp://toby.princeton.edu/pub/olszewsk
%
% - Fix History -
+% 2.14 added cdef to allow overwriting of certain values from externally
% 2.13 check for bitmap fonts, work better with TeX,WinPS,etc
% 2.12 fixed initclip to US letter size page
% 2.11 added header support for *u/*U compound paths
@@ -538,5 +549,5 @@ jtxt3 {
(%%EndSetup\n) jp
0 0 0 1 oldsetcmykcolor
currentstate
-jout {(%%Note: Load Postscript file to be converted now\n) print} if
+jout {(%%Note: Load Postscript file to be converted now\n) print} if
diff --git a/gs/lib/ps2ascii.ps b/gs/lib/ps2ascii.ps
index cdc0e1794..f124a2953 100644
--- a/gs/lib/ps2ascii.ps
+++ b/gs/lib/ps2ascii.ps
@@ -165,25 +165,6 @@
%%* not specially marked.
%%*
-%%+ 1/12/99 - Fixes by Ray Johnston, Artifex Software
-%%+ I don't understand the previous comment about the fix to allow
-%%+ redirecting stdout and stderr. There does not seem to be any code
-%%+ for stderr, the the code for stdout was flawed.
-%%+
-%%+ I fixed the stdout logic, so that the output can be redirected with
-%%+ the sequence;
-%%+ /.show.stdout (outfile.txt) (w) file def
-%%+ interposed between loading (running) ps2ascii.ps and loading/running
-%%+ the file(s) to be converted. For example,
-%%+
-%%+ gs -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -dSIMPLE ps2ascii.ps
-%%+ GS>/.show.stdout (alphabet.txt) (w) file def
-%%+ GS>(alphabet.ps) run
-%%+ GS>quit
-%%+
-%%+ Also added a (\n) to the copypage output for the SIMPLE case to
-%%+ improve readability.
-
/QUIET true def
systemdict wcheck { systemdict } { userdict } ifelse begin
/.max where { pop } { /.max { 2 copy lt { exch } if pop } bind def } ifelse
@@ -208,7 +189,7 @@ ifelse
% Redefine the end-of-page operators.
/erasepage { } codef
-/copypage { SIMPLE { (\n\014) } { (P\n) } ifelse .show.stdout exch writestring } codef
+/copypage { SIMPLE { (\014) } { (P\n) } ifelse //print } codef
/showpage { copypage erasepage initgraphics } codef
% Redefine the fill operators to detect rectangles.
@@ -237,7 +218,7 @@ ifelse
pathforall cleartomark
{ .showcolor counttomark 4 idiv
{ counttomark -4 roll .orderrect
- (R ) .show.stdout exch writestring .show==4
+ (R ) //print .show==4
}
repeat pop
}
@@ -293,7 +274,7 @@ ifelse
currentlinewidth 2 div dup .dcoord add abs 1 max 5 1 roll
4 index add 4 1 roll 4 index add 4 1 roll
4 index sub 4 1 roll 5 -1 roll sub 4 1 roll
- (R ) .show.stdout exch writestring .show==4
+ (R ) //print .show==4
} odef
/.strokecomplex
{ % Do a first pass to see if the path is all horizontal and vertical
@@ -341,7 +322,7 @@ ifelse
{ COMPLEX
{ gsave setmatrix itransform 0 0 itransform
grestore .coord 4 2 roll .coord .orderrect
- (I ) .show.stdout exch writestring .show==4
+ (I ) //print .show==4
}
{ pop pop pop
}
@@ -381,11 +362,11 @@ ifelse
3 index //.color.b .iget eq and
{ pop pop pop
}
- { (C ) .show.stdout exch writestring
+ { (C ) //print
dup //.color.r exch .iput .show==only
- ( ) .show.stdout exch writestring dup //.color.g exch .iput .show==only
- ( ) .show.stdout exch writestring dup //.color.b exch .iput .show==only
- (\n) .show.stdout exch writestring
+ ( ) //print dup //.color.g exch .iput .show==only
+ ( ) //print dup //.color.b exch .iput .show==only
+ (\n) //print
}
ifelse
}
@@ -404,9 +385,14 @@ ifelse
% 0.1 0 2 index dtransform abs exch abs .max /.show.scale exch def
% 0.1 dup 3 -1 roll scale
gsave initmatrix
- % Assume the original transformation is well-behaved.
+ % Assume the original transformation is well-behaved...
0.1 0 dtransform abs exch abs .max
0.1 dup scale .show.ident.matrix currentmatrix
+ % ... but undo any rotation into landscape orientation.
+ dup 0 get 0 eq {
+ 1 get dup abs div 90 mul rotate
+ .show.ident.matrix currentmatrix
+ } if
grestore
} bind def
@@ -467,10 +453,10 @@ ifelse
//.show.=string //=string copy pop
} odef
/.show==4
- { 4 -1 roll .show==only ( ) .show.stdout exch writestring
- 3 -1 roll .show==only ( ) .show.stdout exch writestring
- exch .show==only ( ) .show.stdout exch writestring
- .show==only (\n) .show.stdout exch writestring
+ { 4 -1 roll .show==only ( ) //print
+ 3 -1 roll .show==only ( ) //print
+ exch .show==only ( ) //print
+ .show==only (\n) //print
} odef
/.showwidth % Same as stringwidth, but disable COMPLEX so that
@@ -519,11 +505,11 @@ ifelse
1 index //.font.name 0 //.font.name.length .iget getinterval eq and
{ pop pop pop
}
- { (F ) .show.stdout exch writestring
- 3 -1 roll dup //.font.height exch .iput .show==only ( ) .show.stdout exch writestring
- exch dup //.font.width exch .iput .show==only ( ) .show.stdout exch writestring
+ { (F ) //print
+ 3 -1 roll dup //.font.height exch .iput .show==only ( ) //print
+ exch dup //.font.width exch .iput .show==only ( ) //print
dup length //.font.name.length exch .iput
- //.font.name cvs .show==only (\n) .show.stdout exch writestring
+ //.font.name cvs .show==only (\n) //print
}
ifelse
}
@@ -1408,7 +1394,7 @@ userdict /start-hook {
ifelse % x y string width char
}
ifelse
- .show.stdout exch writestring
+ //print
//.show.y 3 index .iput % x y string width
//.show.x 4 index .iput % x y string width
@@ -1418,7 +1404,7 @@ userdict /start-hook {
% If the word processor split a hyphenated word within
% the same line, put out the hyphen now.
pop
- //.show.last 0 get .hyphen eq { (-) .show.stdout exch writestring } if
+ //.show.last 0 get .hyphen eq { (-) //print } if
}
ifelse
%%*
@@ -1429,14 +1415,14 @@ userdict /start-hook {
%%*
3 index % x y string width x
//.show.x .iget 10 add gt % x y string width bool
- { ( ) .show.stdout exch writestring }
+ { ( ) //print }
if
% x y string width
4 1 roll % width x y string
.show.write pop % width x
add //.show.x exch .iput % <empty>
}
- { (S ) .show.stdout exch writestring .show==4 }
+ { (S ) //print .show==4 }
ifelse
} odef
diff --git a/gs/lib/ps2pdf b/gs/lib/ps2pdf
index 0e321eb88..00420e2c7 100755
--- a/gs/lib/ps2pdf
+++ b/gs/lib/ps2pdf
@@ -6,14 +6,14 @@ OPTIONS=""
while true
do
case "$1" in
- -*) OPTIONS="$OPTIONS $1" ;;
+ -?*) OPTIONS="$OPTIONS $1" ;;
*) break ;;
esac
shift
done
if [ $# -lt 1 -o $# -gt 2 ]; then
- echo "Usage: `basename $0` [options...] input.ps [output.pdf]" 1>&2
+ echo "Usage: `basename $0` [options...] (input.ps|-) [output.pdf|-]" 1>&2
exit 1
fi
@@ -22,10 +22,10 @@ infile=$1;
if [ $# -eq 1 ]
then
case "${infile}" in
- *.ps) base=`basename ${infile} .ps` ;;
- *) base=`basename ${infile}` ;;
+ -) outfile=- ;;
+ *.ps) base=`basename ${infile} .ps; outfile=${base}.pdf` ;;
+ *) base=`basename ${infile}` ; outfile=${base}.pdf;;
esac
- outfile=${base}.pdf
else
outfile=$2
fi
diff --git a/gs/lib/t1tot2.ps b/gs/lib/t1tot2.ps
deleted file mode 100644
index 1e701d8df..000000000
--- a/gs/lib/t1tot2.ps
+++ /dev/null
@@ -1,486 +0,0 @@
-% Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
-%
-% This file is part of Aladdin Ghostscript.
-%
-% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
-% or distributor accepts any responsibility for the consequences of using it,
-% or for whether it serves any particular purpose or works at all, unless he
-% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
-% License (the "License") for full details.
-%
-% Every copy of Aladdin Ghostscript must include a copy of the License,
-% normally in a plain ASCII text file named PUBLIC. The License grants you
-% the right to copy, modify and redistribute Aladdin Ghostscript, but only
-% under certain conditions described in the License. Among other things, the
-% License requires that the copyright notice and this notice be preserved on
-% all copies.
-
-
-% t1tot2.ps
-% Convert a Type 1 font with Type 1 CharStrings to Type 2.
-% **************** THIS FILE DOES NOT WORK. ****************
-% **************** DON'T TRY TO USE IT. ****************
-
-(type1ops.ps) runlibfile
-
-% ---------------- CharString conversion ---------------- %
-
-% In the following lists, implemented conversions are marked with a +.
-% The following conversions are required for each CharString:
-% + Remove lenIV initial bytes and decrypt.
-% + Move width to first stem/moveto.
-% + Move all hstem/vstem commands to the beginning,
-% including any from subroutines.
-% Fold side bearing into first moveto.
-% + Adjust Subr indices for bias.
-% + Remove all closepath.
-% Convert Flex othersubrs to new flex commands.
-% Convert hint replacement to -hm and hintmask.
-% Convert MM blend othersubrs to new blend command.
-% For seac, convert char bodies to subrs, add hint replacement.
-% + Make width relative to nominalWidthX, or omit if equal to
-% defaultWidthX.
-% The following patterns allow shortening CharStrings:
-% + rlineto+ => rlineto
-% + rlineto+ (hlineto | vlineto) rlineto+ => rlineto
-% + vlineto (hlineto vlineto)* [hlineto] => vlineto
-% + hlineto (vlineto hlineto)* [vlineto] => hlineto
-% + rrcurveto+ => rrcurveto
-% + rrcurveto+ rlineto => rcurveline
-% + rlineto+ rrcurveto => rlinecurve
-% + (vhcurveto hvcurveto)* [vhcurveto ["hrcurveto"] | "vrcurveto"] =>
-% vhcurveto
-% + (hvcurveto vhcurveto)* [hvcurveto ["vrcurveto"] | "hrcurveto"] =>
-% hvcurveto
-% "rvcurveto" (0 y1 x2 y2 0 y3 rrcurveto)* => vvcurveto
-% "hrcurveto" (x1 0 x2 y2 x3 0 rrcurveto)* => hhcurveto
-
-% Convert a CharString from Type 1 to Type 2.
-% Free variables: font, subrmap.
-
-/t1tot2cs { % <charstring1> <forsubr> t1tot2cs <charstring2>
- 10 dict begin
- /forsubr exch def
- % Collect the hints, side bearing, and width.
- /vhints 10 dict def
- /hhints 10 dict def
- /hmcount null def
- /lsb null def
- /width null def
- forsubr not {
- dup t1hintops t1scan pop
- } if
- t1t2ops t1scan
- [
- forsubr not {
- % Insert the hints and width at the beginning.
- width dup font /nominalWidthX .knownget { sub } if
- exch font /defaultWidthX .knownget not { 0 } if
- eq { pop } if
- /hstem hhints hintlist
- /vstem vhints hintlist
- } if
- counttomark 2 add -1 roll aload pop ]
- % Convert the string back to encoded form.
- DEBUG {
- (++++ ) print [ 1 index { dup null eq { pop } if } forall ] == flush
- } if
- /lenIV 0 def % for charproc_string
- charproc_string end
-} bind def
-/hintlist { % <hintop> <dict> hintlist -
- dup length 0 eq {
- pop pop
- } {
- dup length array dup 3 -1 roll {
- exch put dup
- } forall pop
- % ****** SORT THE HINTS BY INCREASING v ******
- { dup length 24 le { exit } if
- dup 0 24 getinterval { aload pop 4 2 roll } forall
- dup length 24 sub 24 exch getinterval
- } loop
- { aload pop 3 2 roll } forall
- } ifelse
-} bind def
-/uneexec { % <string> <lenIV> uneexec <string>
- dup 0 ge {
- 2 copy mark /seed 4330 /lenIV 5 -1 roll .dicttomark /eexecDecode filter
- % Stack: string lenIV filter
- dup 4 -1 roll length 4 -1 roll sub string readstring pop
- exch closefile
- } {
- pop
- } ifelse
-} bind def
-/t1scan { % <charstring> <opsdict> t1scan <tokens>
- 5 dict begin
- /opsdict exch def
- % Remove encryption and convert to symbolic form for processing.
- font /lenIV .knownget not { 4 } if uneexec
- 0 () /SubFileDecode filter /f exch def
- /cstr [ 20 { null } repeat f charstack_read /END 20 { null } repeat ] def
- DEBUG {
- (**** ) print [ cstr { dup null eq { pop } if } forall ] == flush
- } if
- % Scan the unpacked string.
- /i 20 def {
- % The /END token will exit from this loop.
- opsdict cstr i get .knownget { exec } if
- /i i 1 add def
- } loop
- f closefile cstr end
-} bind def
-/ciget { % <di> ciget <token>
- i add cstr exch get
-} bind def
-/ciput { % <di> <token> ciput -
- exch i add exch cstr 3 1 roll put
-} bind def
-/ciswap { % <di> <dj> ciswap -
- 2 copy exch ciget exch ciget 3 1 roll ciput ciput
-} bind def
-/ciskip { % <di> ciskip -
- i add /i exch def
-} bind def
-
-% Hint scanning procedures.
-/addhint { % [<v> <dv>] <hintdict> addhint -
- dup 2 index known { pop pop } { dup length 3 -1 roll exch put } ifelse
-} bind def
-
-/t1hintops mark /END { 0 null ciput exit } bind
-
-/vstem {
- cstr i 2 sub 2 getinterval vhints addhint
-} bind
-/hstem {
- cstr i 2 sub 2 getinterval hhints addhint
-} bind
-/callsubr {
- %**** DOESN'T HANDLE FLEX YET ****
- -1 ciget /pop eq {
- % This must be a <#> 1 3 /callothersubr /pop /callsubr sequence.
- hmcount null eq { /hmcount [ vhints length hhints length ] store } if
- -5 ciget
- } {
- -1 ciget
- } ifelse
- subrmap 1 index .knownget { exch pop } if
- dup null eq { pop } {
- font /Private get /Subrs get exch get
- t1hintops t1scan pop
- } ifelse
-} bind
-/hsbw {
- /lsb -2 ciget store
- /width -1 ciget store
-} bind
-/vstem3 {
- [ -6 ciget -5 ciget ] vhints addhint
- [ -4 ciget -3 ciget ] vhints addhint
- [ -2 ciget -1 ciget ] vhints addhint
-} bind
-/hstem3 {
- [ -6 ciget -5 ciget ] hhints addhint
- [ -4 ciget -3 ciget ] hhints addhint
- [ -2 ciget -1 ciget ] hhints addhint
-} bind
-/sbw {
- %**** WHAT ABOUT Y? ****
- /lsb -4 ciget store
- /width -2 ciget store
-} bind
-
-.dicttomark readonly def % t1hintops
-
-% Conversion procedures.
-/t1t2ops mark /END { 0 null ciput exit } bind
-
-/hstem {
- % We handled the hints separately, drop them here.
- -2 1 0 { null ciput } for
-} bind
-/vstem 1 index
-/rlineto {
- 3 ciget /rlineto eq {
- 0 null ciput
- } {
- 7 ciget /rrcurveto eq {
- 0 null ciput
- 7 /rlinecurve ciput
- } {
- 5 ciget /rlineto eq {
- 2 ciget /hlineto eq {
- 0 null ciput
- 2 0 ciput
- } {
- 2 ciget /vlineto eq {
- 0 0 ciput
- 2 null ciput
- } if
- } ifelse
- } if
- } ifelse
- } ifelse
-} bind
-/vlineto {
- 2 ciget /hlineto eq {
- 0 null ciput
- 2 4 ciget /vlineto eq { null } { /vlineto } ifelse ciput
- } if
-} bind
-/hlineto {
- 2 ciget /vlineto eq {
- 0 null ciput
- 2 4 ciget /hlineto eq { null } { /hlineto } ifelse ciput
- } if
-} bind
-/rrcurveto {
- 7 ciget /rrcurveto eq {
- 0 null ciput
- } {
- 3 ciget /rlineto eq {
- 0 null ciput
- 3 /rcurveline ciput
- } {
- %**** WRONG IF MULTIPLE RRCURVETO ****
- -6 ciget 0 eq {
- -6 null ciput
- 0 /vhcurveto ciput
- } {
- -5 ciget 0 eq {
- -5 null ciput
- -1 -2 ciswap
- 0 /hvcurveto ciput
- } if
- } ifelse
- } ifelse
- } ifelse
-} bind
-/callsubr {
- -1 ciget subrmap 1 index .knownget { exch pop } if
- % If the Subr was deleted because it was empty, delete the call.
- dup null eq {
- 0 null ciput
- } {
- % Subtract the subroutineNumberBias.
- 107 sub
- } ifelse -1 exch ciput
-} bind
-/vhcurveto {
- 5 ciget /hvcurveto eq {
- 0 null ciput
- 10 ciget /vhcurveto eq {
- 5 null ciput
- } {
- 12 ciget /rrcurveto eq 6 ciget 0 eq and {
- 5 null ciput
- 6 null ciput
- 12 /vhcurveto ciput
- 12 ciskip
- } {
- 5 /vhcurveto ciput
- 5 ciskip
- } ifelse
- } ifelse
- } {
- 7 ciget /rrcurveto eq {
- 1 ciget 0 eq {
- 0 null ciput
- 1 null ciput
- 5 6 ciswap
- 7 /vhcurveto ciput
- 7 ciskip
- } if
- } if
- } ifelse
-} bind
-/hvcurveto {
- 5 ciget /vhcurveto eq {
- 0 null ciput
- 10 ciget /hvcurveto eq {
- 5 null ciput
- } {
- 12 ciget /rrcurveto eq 7 ciget 0 eq and {
- 5 null ciput
- 7 null ciput
- 10 11 ciswap
- 12 /hvcurveto ciput
- 12 ciskip
- } {
- 5 /hvcurveto ciput
- 5 ciskip
- } ifelse
- } ifelse
- } {
- 7 ciget /rrcurveto eq {
- 2 ciget 0 eq {
- 0 null ciput
- 2 null ciput
- 7 /hvcurveto ciput
- 7 ciskip
- } if
- } if
- } ifelse
-} bind
-/closepath {
- 0 null ciput
-} bind
-/hsbw {
- % We handled this separately, drop it.
- -2 1 0 { null ciput } for
-} bind
-/dotsection {
- %**************** NYI ****************
-} bind
-/vstem3 {
- % We handled the hints separately, drop them here.
- -6 1 0 { null ciput } for
-} bind
-/hstem3 1 index
-/seac {
- %**************** NYI ****************
-} bind
-/sbw {
- % We handled this separately, drop it.
- -4 1 0 { null ciput } for
-} bind
-/callothersubr {
- -1 ciget 3 eq {
- %**** HANDLE HINT REPLACEMENT ****
- -2 ciget 1 eq 1 ciget /pop eq and 2 ciget /callsubr eq and {
- 1 -3 ciget ciput
- -3 1 0 { null ciput } for
- } {
- (**************** 3 callothersubr -- invalid call\n) print
- /t1tot2cs cvx /rangecheck signalerror
- } ifelse
- } if
-} bind
-/pop {
- %**************** NYI ****************
-} bind
-/setcurrentpoint {
- %**************** NYI ****************
-} bind
-
-.dicttomark readonly def % t1t2ops
-
-% ---------------- Font conversion ---------------- %
-
-% Copy a font, and remove eexec encryption from it.
-/decryptfont { % <font> decryptfont <font'>
- % Copy the font, CharStrings, Private, and Private.Subrs
- dup length dict copy
- dup /CharStrings 2 copy get dup length dict copy put
- dup /Private 2 copy get dup length dict copy
- dup /Subrs 2 copy get dup length array copy put
- put
- dup /lenIV .knownget not { 4 } if
- 1 index /CharStrings get
- % Stack: font' lenIV chars'
- dup { 3 index uneexec 2 index 3 1 roll put } forall pop
- 1 index /Private get /Subrs get
- % Stack: font' lenIV Subrs'
- 0 1 2 index length 1 sub {
- 2 copy get dup type /stringtype eq {
- % Stack: font' lenIV Subrs' index subr
- 3 index uneexec
- } if 2 index 3 1 roll put
- } for pop pop dup /lenIV -1 put
-} def
-
-% Convert an entire font from Type 1 to Type 2.
-/t1tot2font { % <font> t1tot2font <font'>
- 10 dict begin
- /font exch def
- /niv font /lenIV .knownget not { 4 } if def
-
- % Print initial statistics.
-
- (lenIV = ) print niv =
- font /CharStrings get
- dup length =only ( CharStrings, ) print
- 0 exch { exch pop length add } forall =only ( bytes) =
- font /Private get /Subrs get
- dup length =only ( Subrs, ) print
- 0 exch { length add } forall =only ( bytes) =
- flush
-
- % Remove CharString encryption from the font.
-
- /font font decryptfont def
- /chars font /CharStrings get dup length dict copy def
- /subrs font /Private get /Subrs get def
-
- % Remove empty Subrs, including Subrs 0-3.
-
- /subrmap subrs length dict def
- 0 1 3 { subrs exch <0b> put } for
- 0 1 subrs length 1 sub {
- subrs 1 index get true t1tot2cs
- length 1 eq {
- subrs 1 index null put
- subrmap exch null put
- } {
- pop
- } ifelse
- } for
-
- % Remove duplicate Subrs (!).
-
- % Make an entry in subrdict for each distinct Subr:
- % key = Subr charstring, value = (lowest) Subr index.
- % At the same time, make entries in subrmap for any duplicates:
- % key = higher index, value = lowest index.
- /subrdict subrs length dict def
- 0 0 1 subrs length 1 sub {
- % Stack: toindex fromindex
- subrs 1 index get subrdict 1 index .knownget {
- % Stack: toindex fromindex subr firstindex
- subrmap 4 -1 roll 3 -1 roll put pop
- } {
- dup null ne {
- % Stack: toindex fromindex subr
- subrmap 3 -1 roll 3 index put % fromindex => toindex
- subrdict 1 index 3 index put % subr => toindex
- subrs 2 index 3 -1 roll put % toindex => subr
- 1 add
- } {
- pop pop
- } ifelse
- } ifelse
- } for
- /subrs1 subrs 0 4 -1 roll getinterval def
- font /Private get /Subrs subrs1 put
-
- % Convert the font.
-
- /chars2 chars length dict def
- chars { false t1tot2cs chars2 3 1 roll put } forall
- /subrs2 subrs1 length array def
- 0 1 subrs1 length 1 sub {
- subrs1 1 index get true t1tot2cs
- subrs2 3 1 roll put
- } for
- font /Private get /Subrs subrs2 put
-
- % Print final statistics.
-
- (CharStrings => ) print 0 chars2 { exch pop length add } forall =only
- ( bytes) =
- subrs2 length =only ( Subrs, ) print
- 0 subrs2 { length add } forall =only ( bytes) =
- flush
-
- % Clean up the font.
-
- font /lenIV undef
- font /UniqueID undef
- font /FID undef
- font /CharStrings chars2 put
- font /CharstringType 2 put
-
- font end
-} bind def
diff --git a/gs/lib/test.ps b/gs/lib/test.ps
deleted file mode 100644
index ef6ae2875..000000000
--- a/gs/lib/test.ps
+++ /dev/null
@@ -1,9 +0,0 @@
-186 0 0 setrgbcolor
-10 setlinewidth
-0 0 moveto 100 100 lineto stroke
-% This one gets 255 0 0 in .pmm
-
-0 153 153 setrgbcolor
-100 100 moveto 200 200 lineto stroke
-% This one gets 0 255 255 in .pmm
-showpage
diff --git a/gs/lib/traceop.ps b/gs/lib/traceop.ps
index b79f281f0..7fb2df042 100644
--- a/gs/lib/traceop.ps
+++ b/gs/lib/traceop.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1992, 1993, 1994 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1992, 1993, 1994, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -36,43 +36,48 @@ currentpacking true setpacking
% Define the default "after" action
/traceafter { } def
-/traceprint
- { dup type /integertype eq
- { 1 sub -1 0 { ( ) print index ==only } for }
- { exec }
- ifelse
- } bind def
-/traceend
- { traceflush { flush } if
- } bind def
-/traceop
- { userdict begin
- dup type dup /nametype eq exch /dicttype eq or { { tracebefore } } if
- 1 index type dup /nametype eq exch /dicttype eq or { { traceafter } } if
- /.tpost exch def /.tpre exch def
- dup type /dicttype ne
- { dup where not { userdict 1 index {} put userdict } if
- } if
- dup dup wcheck not
- { (Warning: substituting userdict for non-writable dictionary.\n) print
- pop userdict
- } if
- /.tddict exch def /.tdict exch def /.tname exch cvlit def
- [ .tname /=only cvx ( ) /print cvx
- /.tpre load /traceprint cvx /traceend cvx
- .tdict .tname get
- dup xcheck
- { dup type dup /arraytype eq exch /packedarraytype eq or
- { /exec cvx
- } if
+/traceprint {
+ dup type /integertype eq {
+ 1 sub -1 0 { ( ) print index ==only } for
+ } {
+ exec
+ } ifelse
+} bind def
+/traceend {
+ traceflush { flush } if
+} bind def
+/traceop {
+ userdict begin
+ dup type dup /nametype eq exch /dicttype eq or { { tracebefore } } if
+ 1 index type dup /nametype eq exch /dicttype eq or { { traceafter } } if
+ /.tpost exch def /.tpre exch def
+ dup type /dicttype ne {
+ dup where not { userdict 1 index {} put userdict } if
+ } if
+ dup dup wcheck not {
+ (Warning: substituting userdict for non-writable dictionary.) =
+ pop userdict
+ } if
+ /.tddict exch def /.tdict exch def /.tname exch cvlit def
+ .currentglobal [
+ .tname /=only cvx ( ) /print cvx
+ /.tpre load /traceprint cvx /traceend cvx
+ .tdict .tname get /.tdef 1 index cvlit def
+ dup xcheck {
+ dup type dup /arraytype eq exch /packedarraytype eq or {
+ /exec cvx
} if
- /.tpost load /traceprint cvx (\n) /print cvx /traceend cvx
- ] cvx
- .tdict .tname get type /operatortype eq
- { .tname exch .makeoperator
} if
- .tddict exch .tname exch put end
- } bind def
+ /.tpost load /traceprint cvx () /= cvx /traceend cvx
+ .tdef gcheck /.tpre load gcheck and /.tpost load gcheck and .setglobal
+ ] cvx
+ .tdef type /operatortype eq {
+ .tname exch .makeoperator
+ } if
+ exch .setglobal
+ .tddict exch .tname exch put
+ end % userdict
+} bind def
/tracebind /bind load def % in case someone wants to put it back
/bind { } def % disable
diff --git a/gs/lib/type1ops.ps b/gs/lib/type1ops.ps
index 91e09573e..3e0ad180c 100644
--- a/gs/lib/type1ops.ps
+++ b/gs/lib/type1ops.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1992, 1997 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1992, 1997, 1998 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -17,17 +17,12 @@
% type1ops.ps
-% Define the Type 1 font opcodes for use by Ghostscript utilities.
-% This includes both Type 1 and Type 2 CharStrings.
+% Define the Type 1 and Type 2 font opcodes for use by Ghostscript utilities.
% Define the default value of lenIV.
/lenIV 4 def
-% Define the default CharString type.
-
-/CharstringType 1 def
-
% ---------------- Encoding ---------------- %
/Type1encode 70 dict
@@ -61,7 +56,7 @@ dup /integertype {
% Operators
-% Identical or similar in Type 1 and Type 2 CharStrings.
+% Identical or similar in Type 1 and Type 2.
/c_hstem 1 def dup /hstem <01> put
/c_vstem 3 def dup /vstem <03> put
/c_vmoveto 4 def dup /vmoveto <04> put
@@ -78,7 +73,7 @@ dup /integertype {
/c_hmoveto 22 def dup /hmoveto <16> put
/c_vhcurveto 30 def dup /vhcurveto <1e> put
/c_hvcurveto 31 def dup /hvcurveto <1f> put
-% Only in Type 1 CharStrings.
+% Only in Type 1.
/c_closepath 9 def dup /closepath <09> put
/c_hsbw 13 def /s_hsbw <0d> def dup /hsbw s_hsbw put
/ce_dotsection 0 def /s_dotsection <0c06> def dup /dotsection s_dotsection put
@@ -90,7 +85,7 @@ dup /integertype {
/ce_pop 17 def /s_pop <0c11> def dup /pop s_pop put
/ce_setcurrentpoint 33 def /s_setcurrentpoint <0c21> def dup /setcurrentpoint s_setcurrentpoint put
/s_setcurrentpoint_hmoveto s_setcurrentpoint <8b16> concatstrings def
-% Only in Type 2 CharStrings.
+% Only in Type 2.
dup /blend <10> put
dup /hstemhm <12> put
dup /hintmask <13> put
@@ -149,7 +144,7 @@ dup 12 {
{ pop 2 string dup 0 12 put dup 1 4 -1 roll put }
ifelse
} put
-dup 28 { % Type 2 CharStrings only
+dup 28 { % Type 2 only
dup read pop 128 xor 128 sub 8 bitshift
1 index read pop add
} put
@@ -165,7 +160,7 @@ dup 254 { dup read pop 876 add neg } put
dup 255 { % Different for Type 1 and Type 2
dup read pop 128 xor 128 sub
3 { 8 bitshift 1 index read pop add } repeat
- CharstringType 2 eq { 65536.0 div } if
+ FontType 2 eq { 65536.0 div } if
} put
readonly def
diff --git a/gs/lib/viewcmyk.ps b/gs/lib/viewcmyk.ps
index a324313db..88820af67 100644
--- a/gs/lib/viewcmyk.ps
+++ b/gs/lib/viewcmyk.ps
@@ -16,7 +16,7 @@
% things, the copyright notice and this notice must be preserved on all
% copies.
-% $Id$
+
% viewcmyk.ps
% Display a raw CMYK file.
% Requires the colorimage operator.
diff --git a/gs/lib/viewmiff.ps b/gs/lib/viewmiff.ps
new file mode 100644
index 000000000..6ee748bba
--- /dev/null
+++ b/gs/lib/viewmiff.ps
@@ -0,0 +1,126 @@
+% Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+%
+% This file is part of Aladdin Ghostscript.
+%
+% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+% or distributor accepts any responsibility for the consequences of using it,
+% or for whether it serves any particular purpose or works at all, unless he
+% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+% License (the "License") for full details.
+%
+% Every copy of Aladdin Ghostscript must include a copy of the License,
+% normally in a plain ASCII text file named PUBLIC. The License grants you
+% the right to copy, modify and redistribute Aladdin Ghostscript, but only
+% under certain conditions described in the License. Among other things, the
+% License requires that the copyright notice and this notice be preserved on
+% all copies.
+
+
+% viewmiff.ps
+% Display a MIFF file. You would think the 'display' command would do this,
+% but many versions of 'display' either core-dump or require unacceptably
+% large amounts of memory.
+
+% Recognize MIFF keywords.
+/miffwords mark
+ /class { cvn /class exch def }
+ /colors { cvi /colors exch def }
+ /columns { cvi /Width exch def }
+ /compression { cvn /compression exch def }
+ /depth { cvi /depth exch def }
+ /packets { cvi /packets exch def }
+ /rows { cvi /Height exch def }
+.dicttomark readonly def
+
+% Recognize MIFF image classes.
+/miffclasses mark
+ /DirectClass {
+ /DeviceRGB setcolorspace
+ /BitsPerComponent depth def
+ /Decode [ 0 1 0 1 0 1 ] def
+ }
+ /PseudoClass {
+ [ /Indexed
+ % The MIFF documentation lies about the size of pixels
+ % for this case: the pixel size is determined only by
+ % the number of colors, and is not affected by the image
+ % depth. Specifically, if there are 256 or fewer colors
+ % but the depth (of color map entries) is 16, each pixel
+ % is still only 1 byte, not 2.
+ currentdict /colors known {
+ /DeviceRGB colors 1 sub
+ /BitsPerComponent colors 256 le { 8 } { 16 } ifelse def
+ colors 3 mul string depth 8 eq {
+ f exch readstring pop
+ } {
+ % 16-bit color map entries: take only the high-order byte.
+ 0 1 2 index length 1 sub {
+ f read pop 2 index 3 1 roll put f read pop pop
+ } for
+ } ifelse
+ } {
+ /colors 256 def
+ /DeviceGray 255
+ 256 string 0 1 255 { 1 index exch dup put } for
+ } ifelse
+ ] setcolorspace
+ /Decode [ 0 1 BitsPerComponent bitshift 1 sub ] def
+ }
+.dicttomark readonly def
+
+% Recognize MIFF compression methods.
+/rlstring 768 string def
+/rlread {
+ % packets is not reliable -- disregard it.
+ dup rlstring 0 3 getinterval readstring {
+ pop read pop 3 mul 3 3 2 index {
+ rlstring exch rlstring 0 3 getinterval putinterval
+ } for
+ rlstring 0 3 -1 roll 3 add getinterval
+ } {
+ pop pop ()
+ } ifelse
+} bind def
+/miffcompress mark
+ /Uncompressed { f }
+ /RunLengthEncoded { { f rlread } }
+ /Zip { [ f /FlateDecode filter cvlit /rlread cvx ] cvx }
+.dicttomark readonly def
+
+% Read a MIFF file and display the image.
+/viewmiff { % <filename> viewmiff -
+ 50 dict begin
+ /fname 1 index def
+ /f exch (r) file def
+ % Set defaults.
+ /ImageType 1 def
+ /class /DirectClass def
+ /compression /Uncompressed def
+ /depth 8 def
+ /packets 16#7fffffff def
+ % Read and parse the header.
+ { f token pop
+ dup (:) eq { pop exit } if
+ dup type /nametype eq {
+ .namestring (=) search {
+ exch pop miffwords exch .knownget { exec } { pop } ifelse
+ } {
+ pop % who knows?
+ } ifelse
+ } {
+ pop % probably a comment in braces
+ } ifelse
+ } loop
+ % Read and display the image.
+ miffclasses class get exec
+ /DataSource miffcompress compression get exec def
+ /ImageMatrix [Width 0 0 Height neg 0 Height] def
+ currentpagedevice /PageSize get
+ dup 0 get exch 1 get scale
+ gsave 0.8 setgray 0 0 1 1 rectfill grestore % provide background
+ currentdict image
+ showpage
+ % Clean up.
+ f closefile
+ end
+} bind def
diff --git a/gs/lib/viewpbm.ps b/gs/lib/viewpbm.ps
index a7545dda0..469cbd930 100644
--- a/gs/lib/viewpbm.ps
+++ b/gs/lib/viewpbm.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1992, 1995, 1996 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1992, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -23,89 +23,81 @@
% if SCALE is undefined, scales the image to fit the page.
/s 100 string def
-/readmaxv
- { f s readline pop cvx exec /maxv exch def
- } bind def
-/readrow
- { 0 1 row length 1 sub { row exch f token pop put } for
- } bind def
-/read01 % <count> read01 <byte>
- { 0 exch { f read pop 48 xor dup 1 le { exch dup add add } { pop } ifelse } repeat
- } bind def
-/P1 % ASCII 1-bit white/black
- { { /bpc 1 def /maxv 1 def /rsize w 7 add 8 idiv def
- /wrem w 8 mod def
- /ncomp 1 def /invert true def
- }
- { 0 1 w 8 idiv { row exch 8 read01 put } for
- wrem 0 ne
- { row rsize 1 sub wrem read01 8 wrem sub bitshift put
- } if
- row
- }
- runpbm
- } bind def
-/P2 % ASCII 8-bit gray
- { { /bpc 8 def readmaxv /rsize w def
- /ncomp 1 def /invert false def
- }
- { readrow row }
- runpbm
- } bind def
-/P3 % ASCII 8-bit RGB
- { { /bpc 8 def readmaxv /rsize w 3 mul def
- /ncomp 3 def /invert false def /DeviceRGB setcolorspace
- }
- { readrow row }
- runpbm
- } bind def
-/P4 % Binary 1-bit white/black
- { { /bpc 1 def /maxv 1 def /rsize w 7 add 8 idiv def
- /ncomp 1 def /invert true def
- }
- { f row readstring pop }
- runpbm
- } bind def
-/P5 % Binary 8-bit gray
- { { /bpc 8 def readmaxv /rsize w def
- /ncomp 1 def /invert false def
- }
- { f row readstring pop }
- runpbm
- } bind def
-/P6 % Binary 8-bit RGB
- { { /bpc 8 def readmaxv /rsize w 3 mul def
- /ncomp 3 def /invert false def /DeviceRGB setcolorspace
- }
- { f row readstring pop }
- runpbm
- } bind def
-/viewpbm { run } def
-/runpbm % <initproc> <readproc> runpbm -
- { /readproc exch def
- /initproc exch def
- currentfile /f exch def
- f s readline pop % check for comment
- (#) anchorsearch
- { pop pop f s readline pop }
- if
- cvx exec /h exch def /w exch def
- erasepage
- /DeviceGray setcolorspace
- initproc % sets bpc, maxv, rsize, ncomp, invert
- /row rsize string def
- /SCALE where
- { pop
- % Map pixels SCALE-for-1. Assume orthogonal transformation.
- w 1 0 dtransform add abs div SCALE mul
- h 0 1 dtransform add abs div SCALE mul
- }
- { % Scale the image (uniformly) to fit the page.
- clippath pathbbox pop pop translate
- pathbbox min exch pop exch pop ceiling
- dup h w gt { w mul h div exch } { h mul w div } ifelse
- }
- ifelse scale
+/readmaxv { % <file> readmaxv -
+ 10 string readline pop cvx exec /maxv exch def
+} bind def
+/readrow { % <file> <row> readrow <row>
+ 0 1 2 index length 1 sub {
+ 1 index exch 3 index token pop put
+ } for exch pop
+} bind def
+/read01 { % <file> <count> read01 <byte>
+ 0 exch {
+ 1 index read pop 48 xor dup 1 le { exch dup add add } { pop } ifelse
+ } repeat
+} bind def
+/readrow01 { % <file> <row> readrow01 <row>
+ 0 1 w 8 idiv {
+ 1 index exch 3 index 8 read01 put
+ } for
+ wrem 0 ne {
+ dup rsize 1 sub wrem read01 8 wrem sub bitshift put
+ } if
+ exch pop
+} bind def
+/readwh { % <file> readwh <w> <h>
+ dup s readline pop % check for comment
+ (#) anchorsearch {
+ pop pop dup s readline pop
+ } if
+ cvx exec
+} bind def
+/pbmtypes mark
+% The procedures in this dictionary are called as
+% <file> Pn <w> <h> <readproc>
+/P1 { % ASCII 1-bit white/black
+ /bpc 1 def /maxv 1 def /rsize w 7 add 8 idiv def
+ /wrem w 8 mod def
+ /ncomp 1 def /invert true def /DeviceGray setcolorspace
+ readwh
+ { readrow01 }
+} bind
+/P2 { % ASCII 8-bit gray
+ readwh
+ /bpc 8 def 2 index readmaxv /rsize 2 index def
+ /ncomp 1 def /invert false def /DeviceGray setcolorspace
+ { readrow }
+} bind
+/P3 { % ASCII 8-bit RGB
+ readwh
+ /bpc 8 def 2 index readmaxv /rsize 2 index 3 mul def
+ /ncomp 3 def /invert false def /DeviceRGB setcolorspace
+ { readrow }
+} bind
+/P4 { % Binary 1-bit white/black
+ readwh
+ /bpc 1 def /maxv 1 def /rsize 2 index 7 add 8 idiv def
+ /ncomp 1 def /invert true def /DeviceGray setcolorspace
+ { readstring pop }
+} bind
+/P5 { % Binary 8-bit gray
+ readwh
+ /bpc 8 def 2 index readmaxv /rsize 2 index def
+ /ncomp 1 def /invert false def /DeviceGray setcolorspace
+ { readstring pop }
+} bind
+/P6 { % Binary 8-bit RGB
+ readwh
+ /bpc 8 def 2 index readmaxv /rsize 2 index 3 mul def
+ /ncomp 3 def /invert false def /DeviceRGB setcolorspace
+ { readstring pop }
+} bind
+.dicttomark readonly def
+/pbmsetup { % <file> <w> <h> <readproc> runpbm -
+ /readproc exch def
+ /h exch def
+ /w exch def
+ /f exch def
20 dict begin % image dictionary
/ImageType 1 def
/Width w def
@@ -113,11 +105,70 @@
/ImageMatrix [w 0 0 h neg 0 h] def
/BitsPerComponent bpc def
/Decode [ 0 255 maxv div invert { exch } if ncomp 1 sub { 2 copy } repeat ] def
- /DataSource /readproc load def
+ /DataSource [ f rsize string /readproc load /exec load ] cvx def
currentdict end
- image
- showpage
- } def
+} def
+/imagescale { % <imagedict> imagescale -
+ begin
+ /SCALE where {
+ pop
+ % Map pixels SCALE-for-1. Assume orthogonal transformation.
+ Width 1 0 dtransform add abs div SCALE mul
+ Height 0 1 dtransform add abs div SCALE mul
+ } {
+ % Scale the image (uniformly) to fit the page.
+ clippath pathbbox pop pop translate
+ pathbbox min exch pop exch pop ceiling
+ dup Height Width gt {
+ Width mul Height div exch
+ } {
+ Height mul Width div
+ } ifelse
+ }
+ ifelse scale
+ end
+} def
+
+% Image a PBM file page by page.
+/viewpbm { % <filename> viewpbm -
+ 20 dict begin
+ (r) file /pf exch def {
+ pf token not { exit } if
+ pbmtypes exch get pf exch exec pbmsetup
+ dup imagescale image showpage
+ } loop
+ end
+} def
+
+% Reassemble a composite PBM file from the CMYK separations.
+/viewpsm {
+ 20 dict begin
+ /fname exch def
+ /sources [ 0 1 3 {
+ /plane exch def
+ /pf fname (r) file def
+ pf pbmtypes pf token pop get exec
+ % Stack: pf w h readproc
+ plane {
+ /readproc exch def /h exch def /w exch def pop
+ /row rsize string def
+ h { pf row readproc pop } repeat
+ pf pbmtypes pf token pop get exec
+ } repeat
+ pbmsetup
+ } for ] def
+ /datas [ sources { /DataSource get 0 get } forall ] def
+ /decode sources 0 get /Decode get
+ dup 0 get exch 1 get add cvi 0 exch
+ 2 copy 4 copy 8 array astore def
+ sources 0 get
+ dup /MultipleDataSources true put
+ dup /DataSource datas put
+ dup /Decode decode put
+ /DeviceCMYK setcolorspace
+ dup imagescale image showpage
+ end
+} def
% If the program was invoked from the command line, run it now.
[ shellarguments
diff --git a/gs/lib/viewpcx.ps b/gs/lib/viewpcx.ps
index bfcb9067e..cfaa894ee 100644
--- a/gs/lib/viewpcx.ps
+++ b/gs/lib/viewpcx.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+% Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
@@ -21,9 +21,27 @@
% Requires the Level 2 `image' operator (to handle variable pixel widths).
% If SCALE is defined, maps input pixels to output pixels with that scale;
% if SCALE is undefined, scales the image to fit the page.
-% ****NOTE: Requires RLE compression; does not handle multi-plane
-% ****images with palette.
+% ****NOTE: does not handle multi-plane images with palette.
+/pcxbytes [
+ 0 1 255 {
+ 64 string exch 0 1 63 {
+ 3 copy exch put pop
+ } for pop
+ } for
+] readonly def
+/readpcx { % - readpcx <str>
+ f % gets replaced
+ dup read not {
+ pop ()
+ } {
+ dup 192 lt {
+ ( ) dup 0 4 -1 roll put exch pop
+ } {
+ 192 sub //pcxbytes 3 -1 roll read pop get exch 0 exch getinterval
+ } ifelse
+ } ifelse
+} def
/get2 % <string> <index> get2 <int>
{ 2 copy get 3 1 roll 1 add get 8 bitshift add
} bind def
@@ -88,7 +106,8 @@
/wbpl w bpp mul 7 add 8 idiv def
% Define the data source procedure.
/s1 bpl wbpl sub string def
- /df f /PCXDecode filter def
+ /df /readpcx load copyarray dup 0 f put cvx bind readonly
+ 0 () /SubFileDecode filter def
/dsource [ nplanes
{ /dsproc load copyarray
dup 1 wbpl string put
diff --git a/gs/lib/writecff.ps b/gs/lib/writecff.ps
deleted file mode 100644
index b373dcddd..000000000
--- a/gs/lib/writecff.ps
+++ /dev/null
@@ -1,367 +0,0 @@
-% Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
-%
-% This file is part of Aladdin Ghostscript.
-%
-% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
-% or distributor accepts any responsibility for the consequences of using it,
-% or for whether it serves any particular purpose or works at all, unless he
-% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
-% License (the "License") for full details.
-%
-% Every copy of Aladdin Ghostscript must include a copy of the License,
-% normally in a plain ASCII text file named PUBLIC. The License grants you
-% the right to copy, modify and redistribute Aladdin Ghostscript, but only
-% under certain conditions described in the License. Among other things, the
-% License requires that the copyright notice and this notice be preserved on
-% all copies.
-
-
-% writecff.ps
-% Write out a Type 2 font as CFF.
-% **************** THIS FILE DOES NOT WORK. ****************
-% **************** DON'T TRY TO USE IT. ****************
-
-currentglobal true setglobal
-(gs_cff.ps) runlibfile
-setglobal
-
-50 dict begin
-
-% ---------------- Standard strings/names ---------------- %
-
-/FontSetInit /ProcSet findresource begin mark
-
-/StandardSIDs StandardStrings length 1.5 mul cvi dict
-dup 0 1 StandardStrings length 1 sub {
- % Stack: mark /StdSIDs dict dict index
- dup StandardStrings exch get exch put dup
-} for pop
-
-end counttomark 2 idiv { def } repeat pop
-
-% ---------------- Standard encodings ---------------- %
-
-% ---------------- Standard Charsets ---------------- %
-
-% ---------------- Output utilities ---------------- %
-
-% Free variables: f (output file), fpos (position in f).
-
-/advance { % <n> advance -
- fpos add /fpos exch store
-} def
-/next { % <byte> next -
- f exch write 1 advance
-} def
-/nextstring { % <string|name> nextstring -
- dup type /nametype eq { .namestring } if
- f 1 index writestring length advance
-} def
-/card8 % <card8> card8 -
- /next load
-def
-/card16 { % <card16> card16 -
- dup -8 bitshift next 255 and next
-} def
-/offset { % <offset> <offsize> offset -
- 1 sub -1 0 { -8 mul 2 copy bitshift 255 and next pop } for pop
-} def
-/sid % <sid> sid -
- /card16 load
-def
-/lenoffsize { % <length> lenoffsize <offsize>
- dup 255 le { pop 1 } { -8 bitshift lenoffsize 1 add } ifelse
-} def
-/Index { % [<string|name|null> ...] Index -
- % Calculate the maximum offset we need to be able to represent.
- 1 1 index { dup null eq { pop } { length add } ifelse } forall lenoffsize
- % stack: items offsize
- 1 index length card16
- dup next
- 1 2 index {
- % stack: items offsize pos item
- 1 index 3 index offset
- dup null eq { pop } { length add } ifelse
- } forall exch offset { nextstring } forall
-} def
-/idIndex { % <dict> <base> idIndex -
- 1 index length array 3 -1 roll {
- 3 index sub 2 index exch 3 -1 roll put
- } forall exch pop Index
-} def
-/stringid { % <string|name> stringid <sid>
- StandardSIDs 1 index .knownget {
- exch pop
- } {
- sids 1 index .knownget {
- exch pop
- } {
- StandardSIDs length sids length add sids 3 -1 roll 2 index put
- } ifelse
- } ifelse
-} def
-/.valuetypedict mark
- /booleantype { { 1 } { 0 } ifelse intvalue }
- /arraytype { { value } forall }
- /packedarraytype 1 index
- /stringtype { stringid intvalue }
- /nametype 1 index
- /realtype { realvalue }
- /integertype { intvalue }
-.dicttomark readonly def
-/value { % <obj> value -
- dup type .valuetypedict exch get exec
-} def
-/.realchardict mark
- 48 1 57 { dup 48 sub } for % digits
- 46 10 69 11 101 11 % . E e
- 45 { % - -- handle E- specially
- dup 15 and 11 eq { 15 or 12 } {
- dup 16#bf eq { pop 255 12 } { 14 } ifelse
- } ifelse
- }
-.dicttomark readonly def
-/realvalue { % <real> realvalue -
- =string cvs 255 exch {
- .realchardict exch get exec
- 1 index 15 and 15 ne { exch next 255 exch } if
- 1 index 240 and 240 eq { 4 bitshift 240 } { 15 } ifelse sub add
- } forall next
-} def
-/intvalue { % <int> intvalue -
- dup dup -107 ge exch 107 le and { 139 add next } {
- dup dup -1131 ge exch 0 lt and { neg 16#fa94 add card16 } {
- dup dup 1131 le exch 0 ge and { 16#f694 add card16 } {
- dup dup -32768 ge exch 32767 le and {
- 28 next 65535 and card16
- } {
- 29 next dup -16 bitshift 2 { 65535 and card16 } repeat
- } ifelse
- } ifelse
- } ifelse
- } ifelse
-} def
-/op { % <op> op -
- dup 32 ge { 12 next 32 sub } if next
-} def
-/vdef { % <obj> <op> vdef -
- exch value op
-} def
-/nedef { % <obj> <default> <op> nedef -
- exch 2 index eq { pop pop } { vdef } ifelse
-} def
-/Dict { % <dict> <opsdict> Dict -
- exch {
- % stack: opsdict key value
- 2 index 3 -1 roll .knownget {
- dup type /integertype eq { vdef } { exec } ifelse
- } {
- pop
- } ifelse
- } forall pop
-} def
-/collect { % <proc> collect <string>
- 10 dict begin
- /str 500 string def
- /spos 0 def
- /fpos 0 def
- /f {
- pop length spos add /spos exch store
- spos str length eq { /str str str concatstrings def } if
- str spos str length spos sub getinterval
- } /NullEncode filter def
- exec f closefile
- str 0 spos getinterval end
-} def
-
-% Write a forward reference in a Dict, and save its position.
-/forward { % <varname> <op> <offsize> forward -
- {null null <1c 00 00> <1d 00 00 00 00>} exch get nextstring
- exch fpos store op
-} def
-
-% ------ Top (font) dictionary ------ %
-
-/topkeyops mark
- /version 0
- /Notice 1
- /Copyright 32
- /FullName 2
- /FamilyName 3
- /Weight 4
- /isFixedPatch { false 33 nedef }
- /ItalicAngle { 0 34 nedef }
- /UnderlinePosition { -100 35 nedef }
- /UnderlineThickness { 50 36 nedef }
- /PaintType { 0 37 nedef }
- /CharstringType { 2 38 nedef }
- /FontMatrix {
- true 0 1 5 {
- 2 index 1 index get {0.001 0 0 0.001 0 0} 3 -1 roll get eq and
- } for
- { pop } { 39 vdef } ifelse
- }
- /UniqueID 13
- /FontBBox 5
- /StrokeWidth { 0 40 nedef }
- /XUID 14
- /FontInfo { topkeyops Dict }
- %**** charset, Encoding
- /CharStrings { pop /charstringsoffset 17 offsetsize forward }
- /Private { pop /privateoffset 18 offsetsize forward }
-.dicttomark readonly def
-
-% ------ Private dictionary ------ %
-
-/deltarray { % [<num> ...] <op> deltarray -
- exch 0 exch { 1 index sub dup value add } forall pop op
-} def
-/privatekeyops mark
- /BlueValues { 6 deltarray }
- /OtherBlues { 7 deltarray }
- /FamilyBlues { 8 deltarray }
- /FamilyOtherBlues { 9 deltarray }
- /BlueScale { 0.039625 41 nedef }
- /BlueShift { 7 42 nedef }
- /BlueFuzz { 1 43 nedef }
- /StdHW 10
- /StdVW 11
- /StemSnapH { 44 deltarray }
- /StemSnapV { 45 deltarray }
- /ForceBold { false 46 nedef }
- /ForceBoldThreshold { 0 47 nedef }
- % Skip lenIV, it's always -1
- /LanguageGroup { 0 49 nedef }
- /ExpansionFactor { 0.06 50 nedef }
- /initialRandomSeed { 0 51 nedef }
- /Subrs { pop /subrsoffset 19 2 forward }
- /defaultWidthX { 0 20 nedef }
- /nominalWidthX { 0 21 nedef }
-.dicttomark readonly def
-
-% ------ Main program ------ %
-
-/putoffset { % <str> <index> <offset> <offsize> putoffset -
- % The saved index points just beyond the end of the number,
- % and we wrote a zero as the placeholder.
- % Consequently, we don't need the offset size.
- pop {
- dup 0 eq { exit } if
- exch 1 sub exch 3 copy 255 and put -8 bitshift
- } loop pop pop pop
-} def
-
-/writecff { % <file> [<font> ...] writecff -
- 30 dict begin
- % The dictionary for each font contains:
- % font - the original Type 2 font
- % subrs - the Local Subrs Index
- % chars - the CharStrings Index
- % private - the Private Dict
- % top - the Top Dict
- % charspos - the offset of the CharStrings Dict relative to
- % the start of all CharStrings
- % privatepos - the offset of the Private Dict relative to
- % the start of all Private Dicts
- % subrsoffset - the offset of the Local Subrs offset
- % reference in the Private Dict
- % charstringsoffset - the offset of the CharStrings offset
- % reference in the Top dict
- % privateoffset - the offset of the Private Dict offset
- % reference in the Top dict
- [ exch { 12 dict begin /font exch cvlit def currentdict end } forall ]
- /fonts exch def
- /cff exch cvlit def
-
- /f cff def
- /fpos 0 def
-
- % We need to pre-construct all the strings so that we know
- % the offsets to fill in.
-
- /names { [ fonts { /font get /FontName get } forall ] Index } collect def
- /sids 20 dict def
- /subrslength 0 def % only for estimating size
- /charslength 0 def
- /privatelength 0 def
- fonts {
- begin
- font /Private get /Subrs .knownget {
- { Index } collect
- } {
- <00 00>
- } ifelse /subrs exch def
- /subrslength subrslength subrs length add def
- %****** FOLLOWING IS WRONG, WRONG, WRONG ******%
- font /CharStrings get [ exch { exch pop } forall ] { Index } collect
- /chars exch def
- /charspos charslength def
- /charslength charslength chars length add def
- /subrsoffset null def
- font /Private get { privatekeyops Dict } collect /private exch def
- subrsoffset null ne {
- private subrsoffset private length 2 putoffset
- } if
- /privatepos privatelength def
- /privatelength privatelength private length add subrs length add def
- } forall
- % Estimate the size of a 0-based offset for the Top Dicts.
- /offsetsize subrslength charslength add privatelength add
- 60000 ge { 3 } { 2 } ifelse def
- fonts {
- begin
- /charstringsoffset null def
- /privateoffset null def
- /top { font topkeyops Dict } collect def
- end
- } forall
- /strings { sids StandardSIDs length idIndex } collect def
-
- % Now we can write the real file.
- % Header
- DEBUG { (header ) print fpos == } if
- <01 00 04 02> nextstring
- % Name Index
- DEBUG { (names ) print fpos == } if
- names nextstring
- % Top Dicts
- DEBUG { (tops ) print fpos == } if
- /charsbase fpos fonts { /top get length add } forall strings length add def
- /privatebase charsbase charslength add def
- fonts {
- begin
- top charstringsoffset charspos charsbase add offsetsize putoffset
- top privateoffset privatepos privatebase add offsetsize putoffset
- top nextstring
- end
- } forall
- % String Index
- DEBUG { (strings ) print fpos == } if
- strings nextstring
- % Charstrings Indexes
- DEBUG { (charstrings) print } if
- /charsbase fpos def
- fonts {
- DEBUG { ( ) print fpos =only } if /chars get nextstring
- } forall
- DEBUG { () = } if
- % Private Dicts & Local Subr Indexes
- DEBUG { (privates/subrs) print } if
- fonts {
- DEBUG { ( ) print fpos =only } if dup /private get nextstring
- DEBUG { ( ) print fpos =only } if /subrs get nextstring
- } forall
- DEBUG { () = } if
-
- DEBUG { (end ) print fpos = flush } if
- end
-} def
-
-% ---------------- Wrap up ---------------- %
-
-currentdict readonly end
-/writecffdict exch def
-
-/writecff {
- writecffdict begin writecff end
-} def
diff --git a/gs/src/ansi2knr.c b/gs/src/ansi2knr.c
index 7143aad66..cff4ac330 100644
--- a/gs/src/ansi2knr.c
+++ b/gs/src/ansi2knr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1997, 1998 Aladdin Enterprises. All rights reserved. */
+/* Copyright (C) 1989, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. */
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
@@ -43,21 +43,37 @@ program under the GPL.
* (ignoring possible intervening comments), except that a line
* consisting of only
* identifier1(identifier2)
- * will not be considered a function definition. ansi2knr will
- * recognize a multi-line header provided that no intervening
- * line ends with a left or right brace or a semicolon.
+ * will not be considered a function definition unless identifier2 is
+ * the word "void", and a line consisting of
+ * identifier1(identifier2, <<arbitrary>>)
+ * will not be considered a function definition.
+ * ansi2knr will recognize a multi-line header provided
+ * that no intervening line ends with a left or right brace or a semicolon.
* These algorithms ignore whitespace and comments, except that
* the function name must be the first thing on the line.
* The following constructs will confuse it:
* - Any other construct that starts at the left margin and
* follows the above syntax (such as a macro or function call).
- * - Some macros that tinker with the syntax of the function header.
+ * - Some macros that tinker with the syntax of function headers.
*/
/*
* The original and principal author of ansi2knr is L. Peter Deutsch
* <ghost@aladdin.com>. Other authors are noted in the change history
* that follows (in reverse chronological order):
+ lpd 1999-04-12 added minor fixes from Pavel Roskin
+ <pavel_roskin@geocities.com> for clean compilation with
+ gcc -W -Wall
+ lpd 1999-03-22 added hack to recognize lines consisting of
+ identifier1(identifier2, xxx) as *not* being procedures
+ lpd 1999-02-03 made indentation of preprocessor commands consistent
+ lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
+ endless loop; quoted strings within an argument list
+ confused the parser
+ lpd 1999-01-24 added a check for write errors on the output,
+ suggested by Jim Meyering <meyering@ascend.com>
+ lpd 1998-11-09 added further hack to recognize identifier(void)
+ as being a procedure
lpd 1998-10-23 added hack to recognize lines consisting of
identifier1(identifier2) as *not* being procedures
lpd 1997-12-08 made input_file optional; only closes input and/or
@@ -151,19 +167,24 @@ program under the GPL.
#endif
+/* Define NULL (for *very* old compilers). */
+#ifndef NULL
+# define NULL (0)
+#endif
+
/*
* The ctype macros don't always handle 8-bit characters correctly.
* Compensate for this here.
*/
#ifdef isascii
-# undef HAVE_ISASCII /* just in case */
-# define HAVE_ISASCII 1
+# undef HAVE_ISASCII /* just in case */
+# define HAVE_ISASCII 1
#else
#endif
#if STDC_HEADERS || !HAVE_ISASCII
-# define is_ascii(c) 1
+# define is_ascii(c) 1
#else
-# define is_ascii(c) isascii(c)
+# define is_ascii(c) isascii(c)
#endif
#define is_space(c) (is_ascii(c) && isspace(c))
@@ -176,6 +197,7 @@ program under the GPL.
/* Forward references */
char *skipspace();
+char *scanstring();
int writeblanks();
int test1();
int convert1();
@@ -188,6 +210,8 @@ main(argc, argv)
{ FILE *in = stdin;
FILE *out = stdout;
char *filename = 0;
+ char *program_name = argv[0];
+ char *output_name = 0;
#define bufsize 5000 /* arbitrary size */
char *buf;
char *line;
@@ -203,6 +227,7 @@ main(argc, argv)
* check for this switch for backward compatibility.
*/
int convert_varargs = 1;
+ int output_error;
while ( argc > 1 && argv[1][0] == '-' ) {
if ( !strcmp(argv[1], "--varargs") ) {
@@ -217,7 +242,8 @@ main(argc, argv)
argv += 2;
continue;
}
- fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
+ fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
+ argv[1]);
fprintf(stderr, usage);
exit(1);
}
@@ -227,16 +253,19 @@ main(argc, argv)
fprintf(stderr, usage);
exit(0);
case 3:
- out = fopen(argv[2], "w");
+ output_name = argv[2];
+ out = fopen(output_name, "w");
if ( out == NULL ) {
- fprintf(stderr, "Cannot open output file %s\n", argv[2]);
+ fprintf(stderr, "%s: Cannot open output file %s\n",
+ program_name, output_name);
exit(1);
}
/* falls through */
case 2:
in = fopen(argv[1], "r");
if ( in == NULL ) {
- fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+ fprintf(stderr, "%s: Cannot open input file %s\n",
+ program_name, argv[1]);
exit(1);
}
if ( filename == 0 )
@@ -248,6 +277,11 @@ main(argc, argv)
if ( filename )
fprintf(out, "#line 1 \"%s\"\n", filename);
buf = malloc(bufsize);
+ if ( buf == NULL )
+ {
+ fprintf(stderr, "Unable to allocate read buffer!\n");
+ exit(1);
+ }
line = buf;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{
@@ -298,14 +332,24 @@ wl: fputs(buf, out);
if ( line != buf )
fputs(buf, out);
free(buf);
- if ( out != stdout )
- fclose(out);
+ if ( output_name ) {
+ output_error = ferror(out);
+ output_error |= fclose(out);
+ } else { /* out == stdout */
+ fflush(out);
+ output_error = ferror(out);
+ }
+ if ( output_error ) {
+ fprintf(stderr, "%s: error writing to %s\n", program_name,
+ (output_name ? output_name : "stdout"));
+ exit(1);
+ }
if ( in != stdin )
fclose(in);
return 0;
}
-/* Skip over space and comments, in either direction. */
+/* Skip over whitespace and comments, in either direction. */
char *
skipspace(p, dir)
register char *p;
@@ -326,6 +370,17 @@ skipspace(p, dir)
return p;
}
+/* Scan over a quoted string, in either direction. */
+char *
+scanstring(p, dir)
+ register char *p;
+ register int dir;
+{
+ for (p += dir; ; p += dir)
+ if (*p == '"' && p[-dir] != '\\')
+ return p + dir;
+}
+
/*
* Write blanks over part of a string.
* Don't overwrite end-of-line characters.
@@ -394,7 +449,7 @@ test1(buf)
};
char **key = words;
char *kp;
- int len = endfn - buf;
+ unsigned len = endfn - buf;
while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
@@ -402,12 +457,36 @@ test1(buf)
key++;
}
}
- /* Check for identifier1(identifier2). */
- while ( isidchar(*p) )
- p++;
- p = skipspace(p, 1);
- if ( *p == ')' )
- return 0; /* id1(id2), not a function */
+ {
+ char *id = p;
+ int len;
+ /*
+ * Check for identifier1(identifier2) and not
+ * identifier1(void), or identifier1(identifier2, xxxx).
+ */
+
+ while ( isidchar(*p) )
+ p++;
+ len = p - id;
+ p = skipspace(p, 1);
+ if (*p == ',' ||
+ (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
+ )
+ return 0; /* not a function */
+ }
+ /*
+ * If the last significant character was a ), we need to count
+ * parentheses, because it might be part of a formal parameter
+ * that is a procedure.
+ */
+ if (contin > 0) {
+ int level = 0;
+
+ for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
+ level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
+ if (level > 0)
+ contin = -1;
+ }
return contin;
}
@@ -437,7 +516,7 @@ convert1(buf, out, header, convert_varargs)
;
top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
- if ( breaks == 0 )
+ if ( breaks == NULL )
{ /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out);
@@ -449,7 +528,7 @@ top: p = endfn;
do
{ int level = 0;
char *lp = NULL;
- char *rp;
+ char *rp = NULL;
char *end = NULL;
if ( bp >= btop )
@@ -476,14 +555,18 @@ top: p = endfn;
else rp = p;
break;
case '/':
- p = skipspace(p, 1) - 1;
+ if (p[1] == '*')
+ p = skipspace(p, 1) - 1;
break;
+ case '"':
+ p = scanstring(p, 1) - 1;
+ break;
default:
;
}
}
/* Erase any embedded prototype parameters. */
- if ( lp )
+ if ( lp && rp )
writeblanks(lp + 1, rp);
p--; /* back up over terminator */
/* Find the name being declared. */
@@ -499,9 +582,19 @@ top: p = endfn;
while ( level )
switch ( *--p )
{
- case ']': case ')': level++; break;
- case '[': case '(': level--; break;
- case '/': p = skipspace(p, -1) + 1; break;
+ case ']': case ')':
+ level++;
+ break;
+ case '[': case '(':
+ level--;
+ break;
+ case '/':
+ if (p > buf && p[-1] == '*')
+ p = skipspace(p, -1) + 1;
+ break;
+ case '"':
+ p = scanstring(p, -1) + 1;
+ break;
default: ;
}
}
diff --git a/gs/src/bcwin32.mak b/gs/src/bcwin32.mak
index f8359ced9..879264bb9 100644
--- a/gs/src/bcwin32.mak
+++ b/gs/src/bcwin32.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1989-1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1989-1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -33,7 +33,7 @@ GS_DOCDIR=c:/gs
# initialization and font files. Separate multiple directories with \;.
# Use / to indicate directories, not a single \.
-GS_LIB_DEFAULT=.;c:/gs\;c:/gs/fonts
+GS_LIB_DEFAULT=.;c:/gs/lib\;c:/gs/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -86,13 +86,16 @@ MAKEDLL=1
MULTITHREAD=1
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
+BINDIR=bin
+GLSRCDIR=src
GLGENDIR=obj
GLOBJDIR=obj
-PSSRCDIR=.
+PSSRCDIR=src
+PSLIBDIR=lib
PSGENDIR=obj
PSOBJDIR=obj
@@ -110,21 +113,30 @@ JVERSION=6
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
ZSRCDIR=zlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# Define any other compilation flags.
CFLAGS=
+# Do not edit the next group of lines.
+
+#!include $(COMMONDIR)\bcdefs.mak
+#!include $(COMMONDIR)\pcdefs.mak
+#!include $(COMMONDIR)\generic.mak
+!include $(GLSRCDIR)\version.mak
+# The following is a hack to get around the special treatment of \ at
+# the end of a line.
+NUL=
+DD=$(GLGENDIR)\$(NUL)
+GLD=$(GLGENDIR)\$(NUL)
+PSD=$(PSGENDIR)\$(NUL)
+
# ------ Platform-specific options ------ #
# Define the drive, directory, and compiler name for the Borland C files.
@@ -177,11 +189,17 @@ CPU_TYPE=586
FPU_TYPE=387
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=winsync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -207,36 +225,41 @@ FILE_IMPLEMENTATION=stdio
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-DEVICE_DEVS=mswindll.dev mswinprn.dev mswinpr2.dev
-DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev lbp8.dev uniprint.dev
-DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev m8510.dev necp6.dev bjc600.dev bjc800.dev
-DEVICE_DEVS7=t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev
-DEVICE_DEVS8=pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
-DEVICE_DEVS14=jpeg.dev jpeggray.dev
-DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+DEVICE_DEVS=$(DD)mswindll.dev $(DD)mswinprn.dev $(DD)mswinpr2.dev
+DEVICE_DEVS2=$(DD)epson.dev $(DD)eps9high.dev $(DD)eps9mid.dev $(DD)epsonc.dev $(DD)ibmpro.dev
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev
+DEVICE_DEVS5=$(DD)djet500c.dev $(DD)declj250.dev $(DD)lj250.dev
+DEVICE_DEVS6=$(DD)st800.dev $(DD)stcolor.dev $(DD)bj10e.dev $(DD)bj200.dev
+DEVICE_DEVS7=$(DD)t4693d2.dev $(DD)t4693d4.dev $(DD)t4693d8.dev $(DD)tek4696.dev
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)bmpmono.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+# Overflow for DEVS3,4,5,6,9
+DEVICE_DEVS16=$(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS17=$(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS18=$(DD)jetp3852.dev $(DD)r4081.dev $(DD)lbp8.dev $(DD)uniprint.dev
+DEVICE_DEVS19=$(DD)m8510.dev $(DD)necp6.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS20=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
# ---------------------------- End of options ---------------------------- #
# Define the name of the makefile -- used in dependencies.
MAKEFILE=$(GLSRCDIR)\bcwin32.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\winlib.mak $(GLSRCDIR)\winint.mak
# Define the current directory prefix and shell invocations.
D=\\
EXP=
-EXPP=
SH=
-SHP=
# Define the arguments for genconf.
@@ -252,7 +275,7 @@ PCFBASM=
# Make sure we get the right default target for make.
-dosdefault: default $(GLOBJDIR)\gs16spl.exe
+dosdefault: default $(BINDIR)\gs16spl.exe
# Define the switch for output files.
@@ -351,7 +374,7 @@ CCWINFLAGS=
# so this must precede the !include statements.
# ****** HACK ****** *.tr and *.map are still created in the current directory.
-BEGINFILES2=$(GLOBJDIR)\gs16spl.exe *.tr *.map
+BEGINFILES2=$(BINDIR)\gs16spl.exe *.tr *.map
# Include the generic makefiles.
@@ -362,33 +385,37 @@ BEGINFILES2=$(GLOBJDIR)\gs16spl.exe *.tr *.map
# Compiler for auxiliary programs
-CCAUX=$(COMPAUX) -ml -I$(INCDIR) -L$(LIBDIR) -n$(AUXGENDIR) -O
+CCAUX=$(COMPAUX) -ml -I$(GLSRCDIR) -I$(INCDIR) -L$(LIBDIR) -n$(AUXGENDIR) -O
CCAUX_TAIL=
-$(GLGENDIR)\ccf32.tr: $(MAKEFILE) makefile
- echo -a1 -d -r -G -N -X -I$(INCDIR) $(CCFLAGS0) -DCHECK_INTERRUPTS > $(GLGENDIR)\ccf32.tr
+$(GLGENDIR)\ccf32.tr: $(TOP_MAKEFILES)
+ echo -a1 -d -r -w-par -w-stu -G -N -X -I$(INCDIR) > $(GLGENDIR)\ccf32.tr
+ echo $(CCFLAGS0) -DCHECK_INTERRUPTS >> $(GLGENDIR)\ccf32.tr
-$(ECHOGS_XE): $(GLSRC)echogs.c
- $(CCAUX) $(GLSRC)echogs.c $(CCAUX_TAIL)
+$(ECHOGS_XE): $(GLSRCDIR)\echogs.c
+ $(CCAUX) $(GLSRCDIR)\echogs.c $(CCAUX_TAIL)
# Since we are running in a Windows environment with a different compiler
# for the DOS utilities, we have to invoke genarch by hand.
# For unfathomable reasons, the 'win' program requires /, not \,
# in the name of the program to be run, and apparently also in any
# file names passed on the command line (?!).
-$(GENARCH_XE): $(GLSRC)genarch.c $(stdpre_h) $(iref_h) $(GLGENDIR)\ccf32.tr
- $(COMP) -I$(INCDIR) -L$(LIBDIR) -n$(AUXGENDIR) -O $(GLSRC)genarch.c
+$(GENARCH_XE): $(GLSRCDIR)\genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr
+ $(COMP) -I$(GLSRCDIR) -I$(INCDIR) -L$(LIBDIR) -n$(AUXGENDIR) -O $(GLSRCDIR)\genarch.c
echo win $(AUXGENDIR)/genarch $(GLGENDIR)/arch.h >_genarch.bat
echo ***** Run "_genarch.bat", then continue make. *****
-$(GENCONF_XE): $(GLSRC)genconf.c $(stdpre_h)
- $(CCAUX) $(GLSRC)genconf.c $(CCAUX_TAIL)
+$(GENCONF_XE): $(GLSRCDIR)\genconf.c $(GENCONF_DEPS)
+ $(CCAUX) $(GLSRCDIR)\genconf.c $(CCAUX_TAIL)
-$(GENDEV_XE): $(GLSRC)gendev.c $(stdpre_h)
- $(CCAUX) $(GLSRC)gendev.c $(CCAUX_TAIL)
+$(GENDEV_XE): $(GLSRCDIR)\gendev.c $(GENDEV_DEPS)
+ $(CCAUX) $(GLSRCDIR)\gendev.c $(CCAUX_TAIL)
-$(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
- $(CCAUX) $(PSSRC)geninit.c $(CCAUX_TAIL)
+$(GENHT_XE): $(PSSRCDIR)\genht.c $(GENHT_DEPS)
+ $(CCAUX) $(GENHT_CFLAGS) $(PSSRCDIR)\genht.c $(CCAUX_TAIL)
+
+$(GENINIT_XE): $(PSSRCDIR)\geninit.c $(GENINIT_DEPS)
+ $(CCAUX) $(PSSRCDIR)\geninit.c $(CCAUX_TAIL)
# -------------------------------- Library -------------------------------- #
@@ -396,82 +423,86 @@ $(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
# ----------------------------- Main program ------------------------------ #
-LIBCTR=libc32.tr
-GSCONSOLE_XE=$(GLOBJ)$(GSCONSOLE).exe
+LIBCTR=$(GLGEN)libc32.tr
+GSCONSOLE_XE=$(BINDIR)\$(GSCONSOLE).exe
+GSDLL_DLL=$(BINDIR)\$(GSDLL).dll
-$(LIBCTR): $(MAKEFILE) $(ECHOGS_XE)
+$(LIBCTR): $(TOP_MAKEFILES) $(ECHOGS_XE)
echo $(LIBDIR)\import32.lib $(LIBDIR)\$(CLIB) >$(LIBCTR)
!if $(MAKEDLL)
# The graphical small EXE loader
-$(GS_XE): $(GSDLL_OBJ).dll $(DWOBJ) $(GSCONSOLE_XE)\
- $(GS_OBJ).res $(GLSRC)dwmain32.def
+$(GS_XE): $(GSDLL_DLL) $(DWOBJ) $(GSCONSOLE_XE)\
+ $(GS_OBJ).res $(GLSRCDIR)\dwmain32.def
$(LINK) /Tpe $(LCT) @&&!
$(LIBDIR)\c0w32 +
$(DWOBJ) +
,$(GS_XE),$(GS), +
$(LIBDIR)\import32 +
$(LIBDIR)\cw32, +
-$(GLSRC)dwmain32.def, +
+$(GLSRCDIR)\dwmain32.def, +
$(GS_OBJ).res
!
# The console mode small EXE loader
-$(GSCONSOLE_XE): $(OBJC) $(GS_OBJ).res $(GLSRC)dw32c.def
+$(GSCONSOLE_XE): $(OBJC) $(GS_OBJ).res $(GLSRCDIR)\dw32c.def
$(LINK) /Tpe /ap $(LCT) $(DEBUGLINK) @&&!
$(LIBDIR)\c0w32 +
$(OBJC) +
,$(GSCONSOLE_XE),$(GSCONSOLE), +
$(LIBDIR)\import32 +
$(LIBDIR)\cw32, +
-$(GLSRC)dw32c.def, +
+$(GLSRCDIR)\dw32c.def, +
$(GS_OBJ).res
!
# The big DLL
-$(GSDLL_OBJ).dll: $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ)\
- $(GSDLL_OBJ).res $(GSDLL_SRC).def
- -del gswin32.tr
- copy $(ld_tr) gswin32.tr
- echo $(LIBDIR)\c0d32 $(GLOBJ)gsdll + >> gswin32.tr
- $(LINK) $(LCT) /Tpd @gswin32.tr $(INTASM) ,$(GSDLL_OBJ).dll,$(GSDLL),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GSDLL_SRC).def,$(GSDLL_OBJ).res
+$(GSDLL_DLL): $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ)\
+ $(GSDLL_OBJ).res $(GLSRCDIR)\gsdll32.def
+ -del $(GLGEN)gswin32.tr
+ copy $(ld_tr) $(GLGEN)gswin32.tr
+ echo $(LIBDIR)\c0d32 $(GLOBJ)gsdll + >> $(GLGEN)gswin32.tr
+ $(LINK) $(LCT) /Tpd @$(GLGEN)gswin32.tr $(INTASM) ,$(GSDLL_DLL),$(GSDLL),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GLSRCDIR)\gsdll32.def,$(GSDLL_OBJ).res
!else
# The big graphical EXE
$(GS_XE): $(GSCONSOLE_XE) $(GS_ALL) $(DEVS_ALL)\
- $(GLOBJ)gsdll.$(OBJ) $(DWOBJNO) $(GS_OBJ).res $(GLSRC)dwmain32.def
- -del gswin32.tr
- copy $(ld_tr) gswin32.tr
- echo $(LIBDIR)\c0w32 $(GLOBJ)gsdll + >> gswin32.tr
- echo $(DWOBJNO) $(INTASM) >> gswin32.tr
- $(LINK) $(LCT) /Tpe @gswin32.tr ,$(GS_XE),$(GS),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GLSRC)dwmain32.def,$(GS_OBJ).res
- -del gswin32.tr
+ $(GLOBJ)gsdll.$(OBJ) $(DWOBJNO) $(GS_OBJ).res $(GLSRCDIR)\dwmain32.def
+ -del $(GLGEN)gswin32.tr
+ copy $(ld_tr) $(GLGEN)gswin32.tr
+ echo $(LIBDIR)\c0w32 $(GLOBJ)gsdll + >> $(GLGEN)gswin32.tr
+ echo $(DWOBJNO) $(INTASM) >> $(GLGEN)gswin32.tr
+ $(LINK) $(LCT) /Tpe @$(GLGEN)gswin32.tr ,$(GS_XE),$(GS),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GLSRCDIR)\dwmain32.def,$(GS_OBJ).res
# The big console mode EXE
$(GSCONSOLE_XE): $(GS_ALL) $(DEVS_ALL)\
- $(GLOBJ)gsdll.$(OBJ) $(OBJCNO) $(GS_OBJ).res $(GLSRC)dw32c.def
- -del gswin32.tr
- copy $(ld_tr) gswin32.tr
- echo $(LIBDIR)\c0w32 $(GLOBJ)gsdll + >> gswin32.tr
- echo $(OBJCNO) $(INTASM) >> gswin32.tr
- $(LINK) $(LCT) /Tpe /ap @gswin32.tr ,$(GSCONSOLE_XE),$(GSCONSOLE),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GLSRC)dw32c.def,$(GS_OBJ).res
- -del gswin32.tr
+ $(GLOBJ)gsdll.$(OBJ) $(OBJCNO) $(GS_OBJ).res $(GLSRCDIR)\dw32c.def
+ -del $(GLGEN)gswin32.tr
+ copy $(ld_tr) $(GLGEN)gswin32.tr
+ echo $(LIBDIR)\c0w32 $(GLOBJ)gsdll + >> $(GLGEN)gswin32.tr
+ echo $(OBJCNO) $(INTASM) >> $(GLGEN)gswin32.tr
+ $(LINK) $(LCT) /Tpe /ap @$(GLGEN)gswin32.tr ,$(GSCONSOLE_XE),$(GSCONSOLE),@$(GLGENDIR)\lib.tr @$(LIBCTR),$(GLSRCDIR)\dw32c.def,$(GS_OBJ).res
!endif
# Access to 16 spooler from Win32s
-$(GLOBJ)gs16spl.exe: $(GLSRC)gs16spl.c $(GLSRC)gs16spl.rc
- $(CCAUX) -W -ms -v -I$(INCDIR) $(GLO_)gs16spl.obj -c $(GLSRC)gs16spl.c
- $(COMPDIR)\brcc -i$(INCDIR) -r -fo$(GLOBJ)gs16spl.res $(GLSRC)gs16spl.rc
+GSSPL_XE=$(BINDIR)\gs16spl.exe
+
+$(GSSPL_XE): $(GLSRCDIR)\gs16spl.c $(GLSRCDIR)\gs16spl.rc
+ $(ECHOGS_XE) -w $(GLGEN)_spl.rc -x 23 define -s gstext_ico $(GLGENDIR)/gstext.ico
+ $(ECHOGS_XE) -a $(GLGEN)_spl.rc -x 23 define -s gsgraph_ico $(GLGENDIR)/gsgraph.ico
+ $(ECHOGS_XE) -a $(GLGEN)_spl.rc -R $(GLSRC)gs16spl.rc
+ $(CCAUX) -W -ms -v -I$(INCDIR) $(GLO_)gs16spl.obj -c $(GLSRCDIR)\gs16spl.c
+ $(COMPDIR)\brcc -i$(INCDIR) -r -fo$(GLOBJ)gs16spl.res $(GLGEN)_spl.rc
$(COMPDIR)\tlink /Twe /c /m /s /l @&&!
$(LIBDIR)\c0ws +
-$(GLOBJ)gs16spl.obj +
-,$(GLOBJ)gs16spl.exe,$(GLOBJ)gs16spl, +
+$(GLOBJ)gs16spl.obj, +
+$(GSSPL_XE),$(GLOBJ)gs16spl, +
$(LIBDIR)\import +
$(LIBDIR)\mathws +
$(LIBDIR)\cws, +
-$(GLSRC)gs16spl.def
+$(GLSRCDIR)\gs16spl.def
!
- $(COMPDIR)\rlink -t $(GLOBJ)gs16spl.res $(GLOBJ)gs16spl.exe
+ $(COMPDIR)\rlink -t $(GLOBJ)gs16spl.res $(GSSPL_XE)
# end of makefile
diff --git a/gs/src/bfont.h b/gs/src/bfont.h
index 82eeb2549..55967ce02 100644
--- a/gs/src/bfont.h
+++ b/gs/src/bfont.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,7 +26,7 @@
#include "ifont.h"
/* In zfont.c */
-int add_FID(P2(ref * pfdict, gs_font * pfont));
+int add_FID(P3(i_ctx_t *i_ctx_p, ref * pfdict, gs_font * pfont));
font_proc_make_font(zdefault_make_font);
font_proc_make_font(zbase_make_font);
@@ -50,19 +50,19 @@ typedef enum {
bf_notdef_required = 16 /* build_gs_primitive_font */
} build_font_options_t;
-/* In zfont2.c */
+/* In zbfont.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,
+int build_gs_primitive_font(P7(i_ctx_t *, 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,
+int build_gs_simple_font(P7(i_ctx_t *, 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,
+int build_gs_font(P7(i_ctx_t *, 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 *));
diff --git a/gs/src/btoken.h b/gs/src/btoken.h
index ea2faba74..635dcddfb 100644
--- a/gs/src/btoken.h
+++ b/gs/src/btoken.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,7 +29,13 @@ extern ref binary_token_names; /* array of size 2 */
#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));
+int encode_binary_token(P5(i_ctx_t *i_ctx_p, const ref *obj, long *ref_offset,
+ long *char_offset, byte *str));
+
+/* Define the current binary object format for operators. */
+/* This is a ref so that it can be managed properly by save/restore. */
+#define ref_binary_object_format_container i_ctx_p
+#define ref_binary_object_format\
+ (ref_binary_object_format_container->binary_object_format)
#endif /* btoken_INCLUDED */
diff --git a/gs/src/bughunt.sh b/gs/src/bughunt.sh
new file mode 100755
index 000000000..b5c808acc
--- /dev/null
+++ b/gs/src/bughunt.sh
@@ -0,0 +1,120 @@
+#! /bin/sh
+
+# NB: If your sh does not support functions, then try
+# /usr/local/bin/bash or /bin/ksh, if you have them.
+#
+# Hunt down compiler bugs that break gs.
+#
+# Usage:
+# ./BUGHUNT "optimization level"
+# e.g.
+# ./BUGHUNT "-O2"
+#
+# Start with the code compiled at the lowest optimization level where
+# it works, then run this script with suitable compiler options. The
+# script will delete one object file at a time and rebuild gs at
+# a higher optimization level. This should uncover the routine(s)
+# that the compiler is generating bad code for.
+#
+# In order to make this test possible in unattended batch mode,
+# ghostscript is run with command-line options that force creation of
+# a bitmap file, rather than a window.
+#
+# The okay subdirectory should contain correct output for each
+# of the tests.
+#
+# [06-Dec-1995]
+
+OBJECTS=" adler32.o deflate.o gconfig.o gdevabuf.o gdevbit.o \
+ gdevbj10.o gdevcdj.o gdevdflt.o gdevdjet.o \
+ gdevemap.o gdevm1.o gdevm16.o gdevm2.o gdevm24.o \
+ gdevm32.o gdevm4.o gdevm8.o gdevmem.o gdevmpla.o \
+ gdevmrop.o gdevpbm.o gdevpccm.o gdevpcl.o gdevpcx.o \
+ gdevpipe.o gdevpng.o gdevprn.o gdevpsim.o gdevtfax.o \
+ gdevtfnx.o gdevtifs.o gdevx.o gdevxalt.o gdevxini.o \
+ gdevxxf.o gp_nofb.o gp_unifn.o gp_unifs.o gp_unix.o \
+ gs.o gsalloc.o gsbitops.o gsbittab.o gschar.o \
+ gschar0.o gscie.o gscolor.o gscolor1.o gscolor2.o \
+ gscoord.o gscsepr.o gsdevice.o gsdevmem.o gsdparam.o \
+ gsdps1.o gsfont.o gsfont0.o gshsb.o gsht.o gsht1.o \
+ gshtscr.o gsimage.o gsimage0.o gsimage1.o gsimage2.o \
+ gsimage3.o gsimpath.o gsinit.o gsiodev.o gsline.o \
+ gsmain.o gsmatrix.o gsmemory.o gsmisc.o gspaint.o \
+ gsparam.o gspath.o gspath1.o gspcolor.o gsrop.o \
+ gsroptab.o gsstate.o gstype1.o gsutil.o gxacpath.o \
+ gxbcache.o gxccache.o gxccman.o gxcht.o gxclbits.o \
+ gxclfile.o gxclip2.o gxclist.o gxclpath.o gxclread.o \
+ gxcmap.o gxcpath.o gxctable.o gxdcconv.o gxdither.o \
+ gxdraw.o gxfill.o gxhint1.o gxhint2.o gxhint3.o \
+ gxht.o gxpaint.o gxpath.o gxpath2.o gxpcmap.o \
+ gxpcopy.o gxstroke.o ialloc.o ibnum.o iccinit0.o \
+ iconfig.o idebug.o idict.o idparam.o igc.o igcref.o \
+ igcstr.o iinit.o ilocate.o iname.o interp.o iparam.o \
+ ireclaim.o isave.o iscan.o iscanbin.o iscannum.o \
+ iscantab.o istack.o iutil.o iutil2.o jcapimin.o \
+ jcapistd.o jccoefct.o jccolor.o jcdctmgr.o jchuff.o \
+ jcinit.o jcmainct.o jcmarker.o jcmaster.o jcomapi.o \
+ jcparam.o jcprepct.o jcsample.o jdapimin.o \
+ jdapistd.o jdcoefct.o jdcolor.o jddctmgr.o jdhuff.o \
+ jdinput.o jdmainct.o jdmarker.o jdmaster.o jdphuff.o \
+ jdpostct.o jdsample.o jfdctint.o jidctint.o jerror.o \
+ jmemmgr.o jutils.o png.o pngerror.o pngio.o pngmem.o \
+ pngtrans.o pngwrite.o pngwtran.o pngwutil.o sbcp.o \
+ sbhc.o sbwbs.o scfd.o scfdtab.o scfe.o scfetab.o \
+ sdctc.o sdctd.o sdcte.o seexec.o sfile.o sfilter1.o \
+ sfilter2.o shc.o shcgen.o siscale.o sjpegc.o \
+ sjpegd.o sjpege.o slzwc.o slzwd.o slzwe.o \
+ smtf.o spdiff.o srld.o srle.o sstring.o stream.o \
+ trees.o zarith.o zarray.o zbseq.o zchar.o zchar1.o \
+ zchar2.o zcie.o zcolor.o zcolor1.o zcolor2.o \
+ zcontrol.o zcrd.o zcsindex.o zcssepr.o zdevcal.o \
+ zdevice.o zdevice2.o zdict.o zdps1.o zfbcp.o \
+ zfdctc.o zfdctd.o zfdcte.o zfdecode.o zfile.o \
+ zfileio.o zfilter.o zfilter2.o zfilterx.o zfname.o \
+ zfont.o zfont0.o zfont1.o zfont2.o zfproc.o \
+ zgeneric.o zgstate.o zhsb.o zht.o zht1.o zht2.o \
+ zimage2.o ziodev.o ziodev2.o zmath.o zmatrix.o \
+ zmedia2.o zmisc.o zmisc1.o zmisc2.o zpacked.o \
+ zpaint.o zpath.o zpath1.o zpcolor.o zrelbit.o \
+ zstack.o zstring.o zsysvm.o ztoken.o ztype.o \
+ zupath.o zutil.o zvmem.o zvmem2.o zwppm.o"
+
+TESTS="exepsf tiger"
+
+dotest()
+{
+ # Create empty output file, so even if gs core dumps,
+ # we will have something to compare against.
+ touch $1.ljp
+ ./gs -sDEVICE=ljetplus -r75x75 -sOutputFile=$1.ljp \
+ $1.ps quit.ps < /dev/null
+ if cmp $1.ljp okay/$1.ljp
+ then
+ /bin/true
+ else
+ echo COMPARISON FAILURE: $1.ljp okay/$1.ljp
+ echo "Remaking $f and gs with lower optimization"
+ /bin/rm -f $f ./gs
+ make $f gs
+ fi
+}
+
+for f in $OBJECTS
+do
+ echo ==================== $f ====================
+
+ date
+
+ # Remove the old (good) object file and ghostscript
+ /bin/rm -f $f gs
+
+ # Rebuild gs with optimization; only one object file should be
+ # recreated.
+ make gs CC="cc $1"
+
+ # Now check this new version of gs with each test file.
+ for t in $TESTS
+ do
+ dotest $t
+ done
+done
diff --git a/gs/src/ccfont.h b/gs/src/ccfont.h
index 4fac98c9a..f700595ff 100644
--- a/gs/src/ccfont.h
+++ b/gs/src/ccfont.h
@@ -23,7 +23,7 @@
# define ccfont_INCLUDED
/* Include all the things a compiled font needs. */
-#include "std.h"
+#include "stdpre.h"
#include "gsmemory.h"
#include "iref.h"
#include "ivmspace.h" /* for avm_foreign */
@@ -86,12 +86,16 @@ typedef struct cfont_procs_s {
* a shared library, on systems that support such things), we define
* a tiny procedural interface for getting access to the compiled font table.
*/
-typedef int ccfont_fproc(P2(const cfont_procs *, ref *));
+#define ccfont_proc(proc)\
+ int proc(P2(const cfont_procs *, ref *))
+typedef ccfont_proc((*ccfont_fproc));
-/* There should be some consts in the *** below, but a number of */
-/* C compilers don't handle const properly in such situations. */
-extern int ccfont_fprocs(P2(int *, ccfont_fproc ***));
+/*
+ * There should be some consts in the *** below, but a number of
+ * C compilers don't handle const properly in such situations.
+ */
+extern int ccfont_fprocs(P2(int *, const ccfont_fproc **));
-#define ccfont_version 17 /* for checking against libraries */
+#define ccfont_version 18 /* for checking against libraries */
#endif /* ccfont_INCLUDED */
diff --git a/gs/src/ccgs b/gs/src/ccgs
index 6dcd3cded..115930351 100644
--- a/gs/src/ccgs
+++ b/gs/src/ccgs
@@ -1,20 +1,24 @@
#!/bin/sh
# Pre-process ANSI C files with ansi2knr before compiling.
-# Usage: ccgs "cc switches..." ...switches... -c inputfile ... -o outputfile
+# Usage: ccgs ansi2knr "cc switches..." ...switches... -c inputfile ... -o outputfile
CFILE=""
OFILE=""
+CSWITCH=""
+A2K=$1
+shift
CMD=$1
while [ $# -gt 1 ]
do
shift
case "$1" in
- -c) CFILE=$2; shift;;
+ -c) CSWITCH=$1;;
-o) OFILE=$2; shift;;
- *) CMD="$CMD $1";;
+ -*) CMD="$CMD $1";;
+ *) CFILE="$CFILE $1";;
esac
done
-./ansi2knr $CFILE _temp_$$.c
-$CMD -c _temp_$$.c -o $OFILE
+$A2K $CFILE _temp_$$.c
+$CMD $CSWITCH _temp_$$.c -o $OFILE
rm -f _temp_$$.c
diff --git a/gs/src/cfonts.mak b/gs/src/cfonts.mak
index bd770378c..1b3a55216 100644
--- a/gs/src/cfonts.mak
+++ b/gs/src/cfonts.mak
@@ -19,35 +19,52 @@
# Makefile for compiling PostScript Type 1 fonts into C.
# For more information about fonts, consult the Fontmap file,
# and also Fonts.htm.
+# Users of this makefile must define the following:
+# PSSRCDIR - the source directory holding ccfont.h
+# PSGENDIR - the directory for files generated during building
+# PSOBJDIR - the object code directory
-# Edit the following 2 lines to reflect your environment.
-OBJ=o
-CCCF=gcc -c -O
-
-CFONTS=.
+# Define the name for invoking the font2c program.
FONT2C=font2c
+# ---------------- End of editable definitions ---------------- #
+
+#CCFONT is defined in int.mak
+
+CFGENDIR=$(PSGENDIR)
+CFOBJDIR=$(PSOBJDIR)
+
+CFGEN=$(CFGENDIR)$(D)
+CFOBJ=$(CFOBJDIR)$(D)
+
+CFCC=$(CC_) $(I_)$(PSSRCDIR)$(_I)
+CFO_=$(O_)$(CFOBJ)
+
# ---------------------------------------------------------------- #
# This file supports two slightly different font sets:
# the de facto commercial standard set of 35 PostScript fonts, and a slightly
# larger set distributed with the free version of the software.
-fonts_standard_o: \
- AvantGarde_o Bookman_o Courier_o \
- Helvetica_o NewCenturySchlbk_o Palatino_o \
- TimesRoman_o Symbol_o ZapfChancery_o ZapfDingbats_o
+fonts_standard_o : \
+AvantGarde_o Bookman_o Courier_o \
+Helvetica_o NewCenturySchlbk_o Palatino_o \
+TimesRoman_o Symbol_o ZapfChancery_o ZapfDingbats_o
+ $(NO_OP)
-fonts_standard_c: \
- AvantGarde_c Bookman_c Courier_c \
- Helvetica_c NewCenturySchlbk_c Palatino_c \
- TimesRoman_c Symbol_c ZapfChancery_c ZapfDingbats_c
+fonts_standard_c : \
+AvantGarde_c Bookman_c Courier_c \
+Helvetica_c NewCenturySchlbk_c Palatino_c \
+TimesRoman_c Symbol_c ZapfChancery_c ZapfDingbats_c
+ $(NO_OP)
-fonts_free_o: fonts_standard_o \
- CharterBT_o Cyrillic_o Kana_o Utopia_o
+fonts_free_o : fonts_standard_o \
+CharterBT_o Cyrillic_o Kana_o Utopia_o
+ $(NO_OP)
-fonts_free_c: fonts_standard_c \
- CharterBT_c Cyrillic_c Kana_c Utopia_c
+fonts_free_c : fonts_standard_c \
+CharterBT_c Cyrillic_c Kana_c Utopia_c
+ $(NO_OP)
# ---------------------------------------------------------------- #
# #
@@ -61,282 +78,297 @@ fonts_free_c: fonts_standard_c \
# ---------------- Avant Garde ----------------
-AvantGarde_c: $(CFONTS)/0agk.c $(CFONTS)/0agko.c $(CFONTS)/0agd.c \
- $(CFONTS)/0agdo.c
+AvantGarde_c : $(CFGEN)0agk.c $(CFGEN)0agko.c $(CFGEN)0agd.c $(CFGEN)0agdo.c
+ $(NO_OP)
-$(CFONTS)/0agk.c:
- $(FONT2C) AvantGarde-Book $(CFONTS)/0agk.c agk
+$(CFGEN)0agk.c :
+ $(FONT2C) AvantGarde-Book $(CFGEN)0agk.c agk
-$(CFONTS)/0agko.c:
- $(FONT2C) AvantGarde-BookOblique $(CFONTS)/0agko.c agko
+$(CFGEN)0agko.c :
+ $(FONT2C) AvantGarde-BookOblique $(CFGEN)0agko.c agko
-$(CFONTS)/0agd.c:
- $(FONT2C) AvantGarde-Demi $(CFONTS)/0agd.c agd
+$(CFGEN)0agd.c :
+ $(FONT2C) AvantGarde-Demi $(CFGEN)0agd.c agd
-$(CFONTS)/0agdo.c:
- $(FONT2C) AvantGarde-DemiOblique $(CFONTS)/0agdo.c agdo
+$(CFGEN)0agdo.c :
+ $(FONT2C) AvantGarde-DemiOblique $(CFGEN)0agdo.c agdo
-AvantGarde_o: 0agk.$(OBJ) 0agko.$(OBJ) 0agd.$(OBJ) 0agdo.$(OBJ)
+AvantGarde_o : $(CFOBJ)0agk.$(OBJ) $(CFOBJ)0agko.$(OBJ) $(CFOBJ)0agd.$(OBJ) $(CFOBJ)0agdo.$(OBJ)
+ $(NO_OP)
-0agk.$(OBJ): $(CFONTS)/0agk.c $(CCFONT)
- $(CCCF) $(CFONTS)/0agk.c
+$(CFOBJ)0agk.$(OBJ) : $(CFGEN)0agk.c $(CCFONT)
+ $(CFCC) $(CFO_)0agk.$(OBJ) $(C_) $(CFGEN)0agk.c
-0agko.$(OBJ): $(CFONTS)/0agko.c $(CCFONT)
- $(CCCF) $(CFONTS)/0agko.c
+$(CFOBJ)0agko.$(OBJ) : $(CFGEN)0agko.c $(CCFONT)
+ $(CFCC) $(CFO_)0agko.$(OBJ) $(C_) $(CFGEN)0agko.c
-0agd.$(OBJ): $(CFONTS)/0agd.c $(CCFONT)
- $(CCCF) $(CFONTS)/0agd.c
+$(CFOBJ)0agd.$(OBJ) : $(CFGEN)0agd.c $(CCFONT)
+ $(CFCC) $(CFO_)0agd.$(OBJ) $(C_) $(CFGEN)0agd.c
-0agdo.$(OBJ): $(CFONTS)/0agdo.c $(CCFONT)
- $(CCCF) $(CFONTS)/0agdo.c
+$(CFOBJ)0agdo.$(OBJ) : $(CFGEN)0agdo.c $(CCFONT)
+ $(CFCC) $(CFO_)0agdo.$(OBJ) $(C_) $(CFGEN)0agdo.c
# ---------------- Bookman ----------------
-Bookman_c: $(CFONTS)/0bkl.c $(CFONTS)/0bkli.c $(CFONTS)/0bkd.c \
- $(CFONTS)/0bkdi.c
+Bookman_c : $(CFGEN)0bkl.c $(CFGEN)0bkli.c $(CFGEN)0bkd.c $(CFGEN)0bkdi.c
+ $(NO_OP)
-$(CFONTS)/0bkl.c:
- $(FONT2C) Bookman-Light $(CFONTS)/0bkl.c bkl
+$(CFGEN)0bkl.c :
+ $(FONT2C) Bookman-Light $(CFGEN)0bkl.c bkl
-$(CFONTS)/0bkli.c:
- $(FONT2C) Bookman-LightItalic $(CFONTS)/0bkli.c bkli
+$(CFGEN)0bkli.c :
+ $(FONT2C) Bookman-LightItalic $(CFGEN)0bkli.c bkli
-$(CFONTS)/0bkd.c:
- $(FONT2C) Bookman-Demi $(CFONTS)/0bkd.c bkd
+$(CFGEN)0bkd.c :
+ $(FONT2C) Bookman-Demi $(CFGEN)0bkd.c bkd
-$(CFONTS)/0bkdi.c:
- $(FONT2C) Bookman-DemiItalic $(CFONTS)/0bkdi.c bkdi
+$(CFGEN)0bkdi.c :
+ $(FONT2C) Bookman-DemiItalic $(CFGEN)0bkdi.c bkdi
-Bookman_o: 0bkl.$(OBJ) 0bkli.$(OBJ) 0bkd.$(OBJ) 0bkdi.$(OBJ)
+Bookman_o : $(CFOBJ)0bkl.$(OBJ) $(CFOBJ)0bkli.$(OBJ) $(CFOBJ)0bkd.$(OBJ) $(CFOBJ)0bkdi.$(OBJ)
+ $(NO_OP)
-0bkl.$(OBJ): $(CFONTS)/0bkl.c $(CCFONT)
- $(CCCF) $(CFONTS)/0bkl.c
+$(CFOBJ)0bkl.$(OBJ) : $(CFGEN)0bkl.c $(CCFONT)
+ $(CFCC) $(CFO_)0bkl.$(OBJ) $(C_) $(CFGEN)0bkl.c
-0bkli.$(OBJ): $(CFONTS)/0bkli.c $(CCFONT)
- $(CCCF) $(CFONTS)/0bkli.c
+$(CFOBJ)0bkli.$(OBJ) : $(CFGEN)0bkli.c $(CCFONT)
+ $(CFCC) $(CFO_)0bkli.$(OBJ) $(C_) $(CFGEN)0bkli.c
-0bkd.$(OBJ): $(CFONTS)/0bkd.c $(CCFONT)
- $(CCCF) $(CFONTS)/0bkd.c
+$(CFOBJ)0bkd.$(OBJ) : $(CFGEN)0bkd.c $(CCFONT)
+ $(CFCC) $(CFO_)0bkd.$(OBJ) $(C_) $(CFGEN)0bkd.c
-0bkdi.$(OBJ): $(CFONTS)/0bkdi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0bkdi.c
+$(CFOBJ)0bkdi.$(OBJ) : $(CFGEN)0bkdi.c $(CCFONT)
+ $(CFCC) $(CFO_)0bkdi.$(OBJ) $(C_) $(CFGEN)0bkdi.c
# ---------------- Courier ----------------
-Courier_c: $(CFONTS)/0crr.c $(CFONTS)/0cri.c $(CFONTS)/0crb.c \
- $(CFONTS)/0crbi.c
+Courier_c : $(CFGEN)0crr.c $(CFGEN)0cri.c $(CFGEN)0crb.c $(CFGEN)0crbi.c
+ $(NO_OP)
-$(CFONTS)/0crr.c:
- $(FONT2C) Courier $(CFONTS)/0crr.c crr
+$(CFGEN)0crr.c :
+ $(FONT2C) Courier $(CFGEN)0crr.c crr
-$(CFONTS)/0cri.c:
- $(FONT2C) Courier-Italic $(CFONTS)/0cri.c cri
+$(CFGEN)0cri.c :
+ $(FONT2C) Courier-Italic $(CFGEN)0cri.c cri
-$(CFONTS)/0crb.c:
- $(FONT2C) Courier-Bold $(CFONTS)/0crb.c crb
+$(CFGEN)0crb.c :
+ $(FONT2C) Courier-Bold $(CFGEN)0crb.c crb
-$(CFONTS)/0crbi.c:
- $(FONT2C) Courier-BoldItalic $(CFONTS)/0crbi.c crbi
+$(CFGEN)0crbi.c :
+ $(FONT2C) Courier-BoldItalic $(CFGEN)0crbi.c crbi
-Courier_o: 0crr.$(OBJ) 0cri.$(OBJ) 0crb.$(OBJ) 0crbi.$(OBJ)
+Courier_o : $(CFOBJ)0crr.$(OBJ) $(CFOBJ)0cri.$(OBJ) $(CFOBJ)0crb.$(OBJ) $(CFOBJ)0crbi.$(OBJ)
+ $(NO_OP)
-0crr.$(OBJ): $(CFONTS)/0crr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0crr.c
+$(CFOBJ)0crr.$(OBJ) : $(CFGEN)0crr.c $(CCFONT)
+ $(CFCC) $(CFO_)0crr.$(OBJ) $(C_) $(CFGEN)0crr.c
-0cri.$(OBJ): $(CFONTS)/0cri.c $(CCFONT)
- $(CCCF) $(CFONTS)/0cri.c
+$(CFOBJ)0cri.$(OBJ) : $(CFGEN)0cri.c $(CCFONT)
+ $(CFCC) $(CFO_)0cri.$(OBJ) $(C_) $(CFGEN)0cri.c
-0crb.$(OBJ): $(CFONTS)/0crb.c $(CCFONT)
- $(CCCF) $(CFONTS)/0crb.c
+$(CFOBJ)0crb.$(OBJ) : $(CFGEN)0crb.c $(CCFONT)
+ $(CFCC) $(CFO_)0crb.$(OBJ) $(C_) $(CFGEN)0crb.c
-0crbi.$(OBJ): $(CFONTS)/0crbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0crbi.c
+$(CFOBJ)0crbi.$(OBJ) : $(CFGEN)0crbi.c $(CCFONT)
+ $(CFCC) $(CFO_)0crbi.$(OBJ) $(C_) $(CFGEN)0crbi.c
# ---------------- Helvetica ----------------
-Helvetica_c: $(CFONTS)/0hvr.c $(CFONTS)/0hvro.c \
- $(CFONTS)/0hvb.c $(CFONTS)/0hvbo.c $(CFONTS)/0hvrrn.c \
- $(CFONTS)/0hvrorn.c $(CFONTS)/0hvbrn.c $(CFONTS)/0hvborn.c
+Helvetica_c : $(CFGEN)0hvr.c $(CFGEN)0hvro.c \
+$(CFGEN)0hvb.c $(CFGEN)0hvbo.c $(CFGEN)0hvrrn.c \
+$(CFGEN)0hvrorn.c $(CFGEN)0hvbrn.c $(CFGEN)0hvborn.c
+ $(NO_OP)
-$(CFONTS)/0hvr.c:
- $(FONT2C) Helvetica $(CFONTS)/0hvr.c hvr
+$(CFGEN)0hvr.c :
+ $(FONT2C) Helvetica $(CFGEN)0hvr.c hvr
-$(CFONTS)/0hvro.c:
- $(FONT2C) Helvetica-Oblique $(CFONTS)/0hvro.c hvro
+$(CFGEN)0hvro.c :
+ $(FONT2C) Helvetica-Oblique $(CFGEN)0hvro.c hvro
-$(CFONTS)/0hvb.c:
- $(FONT2C) Helvetica-Bold $(CFONTS)/0hvb.c hvb
+$(CFGEN)0hvb.c :
+ $(FONT2C) Helvetica-Bold $(CFGEN)0hvb.c hvb
-$(CFONTS)/0hvbo.c:
- $(FONT2C) Helvetica-BoldOblique $(CFONTS)/0hvbo.c hvbo
+$(CFGEN)0hvbo.c :
+ $(FONT2C) Helvetica-BoldOblique $(CFGEN)0hvbo.c hvbo
-$(CFONTS)/0hvrrn.c:
- $(FONT2C) Helvetica-Narrow $(CFONTS)/0hvrrn.c hvrrn
+$(CFGEN)0hvrrn.c :
+ $(FONT2C) Helvetica-Narrow $(CFGEN)0hvrrn.c hvrrn
-$(CFONTS)/0hvrorn.c:
- $(FONT2C) Helvetica-Narrow-Oblique $(CFONTS)/0hvrorn.c hvrorn
+$(CFGEN)0hvrorn.c :
+ $(FONT2C) Helvetica-Narrow-Oblique $(CFGEN)0hvrorn.c hvrorn
-$(CFONTS)/0hvbrn.c:
- $(FONT2C) Helvetica-Narrow-Bold $(CFONTS)/0hvbrn.c hvbrn
+$(CFGEN)0hvbrn.c :
+ $(FONT2C) Helvetica-Narrow-Bold $(CFGEN)0hvbrn.c hvbrn
-$(CFONTS)/0hvborn.c:
- $(FONT2C) Helvetica-Narrow-BoldOblique $(CFONTS)/0hvborn.c hvborn
+$(CFGEN)0hvborn.c :
+ $(FONT2C) Helvetica-Narrow-BoldOblique $(CFGEN)0hvborn.c hvborn
-Helvetica_o: 0hvr.$(OBJ) 0hvro.$(OBJ) 0hvb.$(OBJ) 0hvbo.$(OBJ) \
- 0hvrrn.$(OBJ) 0hvrorn.$(OBJ) 0hvbrn.$(OBJ) 0hvborn.$(OBJ)
+Helvetica_o : $(CFOBJ)0hvr.$(OBJ) $(CFOBJ)0hvro.$(OBJ) $(CFOBJ)0hvb.$(OBJ) $(CFOBJ)0hvbo.$(OBJ) \
+$(CFOBJ)0hvrrn.$(OBJ) $(CFOBJ)0hvrorn.$(OBJ) $(CFOBJ)0hvbrn.$(OBJ) $(CFOBJ)0hvborn.$(OBJ)
+ $(NO_OP)
-0hvr.$(OBJ): $(CFONTS)/0hvr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvr.c
+$(CFOBJ)0hvr.$(OBJ) : $(CFGEN)0hvr.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvr.$(OBJ) $(C_) $(CFGEN)0hvr.c
-0hvro.$(OBJ): $(CFONTS)/0hvro.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvro.c
+$(CFOBJ)0hvro.$(OBJ) : $(CFGEN)0hvro.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvro.$(OBJ) $(C_) $(CFGEN)0hvro.c
-0hvb.$(OBJ): $(CFONTS)/0hvb.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvb.c
+$(CFOBJ)0hvb.$(OBJ) : $(CFGEN)0hvb.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvb.$(OBJ) $(C_) $(CFGEN)0hvb.c
-0hvbo.$(OBJ): $(CFONTS)/0hvbo.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvbo.c
+$(CFOBJ)0hvbo.$(OBJ) : $(CFGEN)0hvbo.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvbo.$(OBJ) $(C_) $(CFGEN)0hvbo.c
-0hvrrn.$(OBJ): $(CFONTS)/0hvrrn.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvrrn.c
+$(CFOBJ)0hvrrn.$(OBJ) : $(CFGEN)0hvrrn.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvrrn.$(OBJ) $(C_) $(CFGEN)0hvrrn.c
-0hvrorn.$(OBJ): $(CFONTS)/0hvrorn.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvrorn.c
+$(CFOBJ)0hvrorn.$(OBJ) : $(CFGEN)0hvrorn.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvrorn.$(OBJ) $(C_) $(CFGEN)0hvrorn.c
-0hvbrn.$(OBJ): $(CFONTS)/0hvbrn.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvbrn.c
+$(CFOBJ)0hvbrn.$(OBJ) : $(CFGEN)0hvbrn.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvbrn.$(OBJ) $(C_) $(CFGEN)0hvbrn.c
-0hvborn.$(OBJ): $(CFONTS)/0hvborn.c $(CCFONT)
- $(CCCF) $(CFONTS)/0hvborn.c
+$(CFOBJ)0hvborn.$(OBJ) : $(CFGEN)0hvborn.c $(CCFONT)
+ $(CFCC) $(CFO_)0hvborn.$(OBJ) $(C_) $(CFGEN)0hvborn.c
# ---------------- New Century Schoolbook ----------------
-NewCenturySchlbk_c: $(CFONTS)/0ncr.c $(CFONTS)/0ncri.c $(CFONTS)/0ncb.c \
- $(CFONTS)/0ncbi.c
+NewCenturySchlbk_c : $(CFGEN)0ncr.c $(CFGEN)0ncri.c $(CFGEN)0ncb.c \
+$(CFGEN)0ncbi.c
+ $(NO_OP)
-$(CFONTS)/0ncr.c:
- $(FONT2C) NewCenturySchlbk-Roman $(CFONTS)/0ncr.c ncr
+$(CFGEN)0ncr.c :
+ $(FONT2C) NewCenturySchlbk-Roman $(CFGEN)0ncr.c ncr
-$(CFONTS)/0ncri.c:
- $(FONT2C) NewCenturySchlbk-Italic $(CFONTS)/0ncri.c ncri
+$(CFGEN)0ncri.c :
+ $(FONT2C) NewCenturySchlbk-Italic $(CFGEN)0ncri.c ncri
-$(CFONTS)/0ncb.c:
- $(FONT2C) NewCenturySchlbk-Bold $(CFONTS)/0ncb.c ncb
+$(CFGEN)0ncb.c :
+ $(FONT2C) NewCenturySchlbk-Bold $(CFGEN)0ncb.c ncb
-$(CFONTS)/0ncbi.c:
- $(FONT2C) NewCenturySchlbk-BoldItalic $(CFONTS)/0ncbi.c ncbi
+$(CFGEN)0ncbi.c :
+ $(FONT2C) NewCenturySchlbk-BoldItalic $(CFGEN)0ncbi.c ncbi
-NewCenturySchlbk_o: 0ncr.$(OBJ) 0ncri.$(OBJ) 0ncb.$(OBJ) 0ncbi.$(OBJ)
+NewCenturySchlbk_o : $(CFOBJ)0ncr.$(OBJ) $(CFOBJ)0ncri.$(OBJ) $(CFOBJ)0ncb.$(OBJ) $(CFOBJ)0ncbi.$(OBJ)
+ $(NO_OP)
-0ncr.$(OBJ): $(CFONTS)/0ncr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0ncr.c
+$(CFOBJ)0ncr.$(OBJ) : $(CFGEN)0ncr.c $(CCFONT)
+ $(CFCC) $(CFO_)0ncr.$(OBJ) $(C_) $(CFGEN)0ncr.c
-0ncri.$(OBJ): $(CFONTS)/0ncri.c $(CCFONT)
- $(CCCF) $(CFONTS)/0ncri.c
+$(CFOBJ)0ncri.$(OBJ) : $(CFGEN)0ncri.c $(CCFONT)
+ $(CFCC) $(CFO_)0ncri.$(OBJ) $(C_) $(CFGEN)0ncri.c
-0ncb.$(OBJ): $(CFONTS)/0ncb.c $(CCFONT)
- $(CCCF) $(CFONTS)/0ncb.c
+$(CFOBJ)0ncb.$(OBJ) : $(CFGEN)0ncb.c $(CCFONT)
+ $(CFCC) $(CFO_)0ncb.$(OBJ) $(C_) $(CFGEN)0ncb.c
-0ncbi.$(OBJ): $(CFONTS)/0ncbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0ncbi.c
+$(CFOBJ)0ncbi.$(OBJ) : $(CFGEN)0ncbi.c $(CCFONT)
+ $(CFCC) $(CFO_)0ncbi.$(OBJ) $(C_) $(CFGEN)0ncbi.c
# ---------------- Palatino ----------------
-Palatino_c: $(CFONTS)/0plr.c $(CFONTS)/0plri.c $(CFONTS)/0plb.c \
- $(CFONTS)/0plbi.c
+Palatino_c : $(CFGEN)0plr.c $(CFGEN)0plri.c $(CFGEN)0plb.c $(CFGEN)0plbi.c
+ $(NO_OP)
-$(CFONTS)/0plr.c:
- $(FONT2C) Palatino-Roman $(CFONTS)/0plr.c plr
+$(CFGEN)0plr.c :
+ $(FONT2C) Palatino-Roman $(CFGEN)0plr.c plr
-$(CFONTS)/0plri.c:
- $(FONT2C) Palatino-Italic $(CFONTS)/0plri.c plri
+$(CFGEN)0plri.c :
+ $(FONT2C) Palatino-Italic $(CFGEN)0plri.c plri
-$(CFONTS)/0plb.c:
- $(FONT2C) Palatino-Bold $(CFONTS)/0plb.c plb
+$(CFGEN)0plb.c :
+ $(FONT2C) Palatino-Bold $(CFGEN)0plb.c plb
-$(CFONTS)/0plbi.c:
- $(FONT2C) Palatino-BoldItalic $(CFONTS)/0plbi.c plbi
+$(CFGEN)0plbi.c :
+ $(FONT2C) Palatino-BoldItalic $(CFGEN)0plbi.c plbi
-Palatino_o: 0plr.$(OBJ) 0plri.$(OBJ) 0plb.$(OBJ) 0plbi.$(OBJ)
+Palatino_o : $(CFOBJ)0plr.$(OBJ) $(CFOBJ)0plri.$(OBJ) $(CFOBJ)0plb.$(OBJ) $(CFOBJ)0plbi.$(OBJ)
+ $(NO_OP)
-0plr.$(OBJ): $(CFONTS)/0plr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0plr.c
+$(CFOBJ)0plr.$(OBJ) : $(CFGEN)0plr.c $(CCFONT)
+ $(CFCC) $(CFO_)0plr.$(OBJ) $(C_) $(CFGEN)0plr.c
-0plri.$(OBJ): $(CFONTS)/0plri.c $(CCFONT)
- $(CCCF) $(CFONTS)/0plri.c
+$(CFOBJ)0plri.$(OBJ) : $(CFGEN)0plri.c $(CCFONT)
+ $(CFCC) $(CFO_)0plri.$(OBJ) $(C_) $(CFGEN)0plri.c
-0plb.$(OBJ): $(CFONTS)/0plb.c $(CCFONT)
- $(CCCF) $(CFONTS)/0plb.c
+$(CFOBJ)0plb.$(OBJ) : $(CFGEN)0plb.c $(CCFONT)
+ $(CFCC) $(CFO_)0plb.$(OBJ) $(C_) $(CFGEN)0plb.c
-0plbi.$(OBJ): $(CFONTS)/0plbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0plbi.c
+$(CFOBJ)0plbi.$(OBJ) : $(CFGEN)0plbi.c $(CCFONT)
+ $(CFCC) $(CFO_)0plbi.$(OBJ) $(C_) $(CFGEN)0plbi.c
# ---------------- Times Roman ----------------
-TimesRoman_c: $(CFONTS)/0tmr.c $(CFONTS)/0tmri.c $(CFONTS)/0tmb.c \
- $(CFONTS)/0tmbi.c
+TimesRoman_c : $(CFGEN)0tmr.c $(CFGEN)0tmri.c $(CFGEN)0tmb.c $(CFGEN)0tmbi.c
+ $(NO_OP)
-$(CFONTS)/0tmr.c:
- $(FONT2C) Times-Roman $(CFONTS)/0tmr.c tmr
+$(CFGEN)0tmr.c :
+ $(FONT2C) Times-Roman $(CFGEN)0tmr.c tmr
-$(CFONTS)/0tmri.c:
- $(FONT2C) Times-Italic $(CFONTS)/0tmri.c tmri
+$(CFGEN)0tmri.c :
+ $(FONT2C) Times-Italic $(CFGEN)0tmri.c tmri
-$(CFONTS)/0tmb.c:
- $(FONT2C) Times-Bold $(CFONTS)/0tmb.c tmb
+$(CFGEN)0tmb.c :
+ $(FONT2C) Times-Bold $(CFGEN)0tmb.c tmb
-$(CFONTS)/0tmbi.c:
- $(FONT2C) Times-BoldItalic $(CFONTS)/0tmbi.c tmbi
+$(CFGEN)0tmbi.c :
+ $(FONT2C) Times-BoldItalic $(CFGEN)0tmbi.c tmbi
-TimesRoman_o: 0tmr.$(OBJ) 0tmri.$(OBJ) 0tmb.$(OBJ) 0tmbi.$(OBJ)
+TimesRoman_o : $(CFOBJ)0tmr.$(OBJ) $(CFOBJ)0tmri.$(OBJ) $(CFOBJ)0tmb.$(OBJ) $(CFOBJ)0tmbi.$(OBJ)
+ $(NO_OP)
-0tmr.$(OBJ): $(CFONTS)/0tmr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0tmr.c
+$(CFOBJ)0tmr.$(OBJ) : $(CFGEN)0tmr.c $(CCFONT)
+ $(CFCC) $(CFO_)0tmr.$(OBJ) $(C_) $(CFGEN)0tmr.c
-0tmri.$(OBJ): $(CFONTS)/0tmri.c $(CCFONT)
- $(CCCF) $(CFONTS)/0tmri.c
+$(CFOBJ)0tmri.$(OBJ) : $(CFGEN)0tmri.c $(CCFONT)
+ $(CFCC) $(CFO_)0tmri.$(OBJ) $(C_) $(CFGEN)0tmri.c
-0tmb.$(OBJ): $(CFONTS)/0tmb.c $(CCFONT)
- $(CCCF) $(CFONTS)/0tmb.c
+$(CFOBJ)0tmb.$(OBJ) : $(CFGEN)0tmb.c $(CCFONT)
+ $(CFCC) $(CFO_)0tmb.$(OBJ) $(C_) $(CFGEN)0tmb.c
-0tmbi.$(OBJ): $(CFONTS)/0tmbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0tmbi.c
+$(CFOBJ)0tmbi.$(OBJ) : $(CFGEN)0tmbi.c $(CCFONT)
+ $(CFCC) $(CFO_)0tmbi.$(OBJ) $(C_) $(CFGEN)0tmbi.c
# ---------------- Symbol ----------------
-Symbol_c: $(CFONTS)/0syr.c
+Symbol_c : $(CFGEN)0syr.c
+ $(NO_OP)
-$(CFONTS)/0syr.c:
- $(FONT2C) Symbol $(CFONTS)/0syr.c syr
+$(CFGEN)0syr.c :
+ $(FONT2C) Symbol $(CFGEN)0syr.c syr
-Symbol_o: 0syr.$(OBJ)
+Symbol_o : $(CFOBJ)0syr.$(OBJ)
+ $(NO_OP)
-0syr.$(OBJ): $(CFONTS)/0syr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0syr.c
+$(CFOBJ)0syr.$(OBJ) : $(CFGEN)0syr.c $(CCFONT)
+ $(CFCC) $(CFO_)0syr.$(OBJ) $(C_) $(CFGEN)0syr.c
# ---------------- Zapf Chancery ----------------
-ZapfChancery_c: $(CFONTS)/0zcmi.c
+ZapfChancery_c : $(CFGEN)0zcmi.c
+ $(NO_OP)
-$(CFONTS)/0zcmi.c:
- $(FONT2C) ZapfChancery-MediumItalic $(CFONTS)/0zcmi.c zcmi
+$(CFGEN)0zcmi.c :
+ $(FONT2C) ZapfChancery-MediumItalic $(CFGEN)0zcmi.c zcmi
-ZapfChancery_o: 0zcmi.$(OBJ)
+ZapfChancery_o : $(CFOBJ)0zcmi.$(OBJ)
+ $(NO_OP)
-0zcmi.$(OBJ): $(CFONTS)/0zcmi.c $(CCFONT)
- $(CCCF) $(CFONTS)/0zcmi.c
+$(CFOBJ)0zcmi.$(OBJ) : $(CFGEN)0zcmi.c $(CCFONT)
+ $(CFCC) $(CFO_)0zcmi.$(OBJ) $(C_) $(CFGEN)0zcmi.c
# ---------------- Zapf Dingbats ----------------
-ZapfDingbats_c: $(CFONTS)/0zdr.c
+ZapfDingbats_c : $(CFGEN)0zdr.c
+ $(NO_OP)
-$(CFONTS)/0zdr.c:
- $(FONT2C) ZapfDingbats $(CFONTS)/0zdr.c zdr
+$(CFGEN)0zdr.c :
+ $(FONT2C) ZapfDingbats $(CFGEN)0zdr.c zdr
-ZapfDingbats_o: 0zdr.$(OBJ)
+ZapfDingbats_o : $(CFOBJ)0zdr.$(OBJ)
+ $(NO_OP)
-0zdr.$(OBJ): $(CFONTS)/0zdr.c $(CCFONT)
- $(CCCF) $(CFONTS)/0zdr.c
+$(CFOBJ)0zdr.$(OBJ) : $(CFGEN)0zdr.c $(CCFONT)
+ $(CFCC) $(CFO_)0zdr.$(OBJ) $(C_) $(CFGEN)0zdr.c
# ---------------------------------------------------------------- #
# #
@@ -346,98 +378,104 @@ ZapfDingbats_o: 0zdr.$(OBJ)
# ---------------- Bitstream Charter ----------------
-CharterBT_c: $(CFONTS)/bchr.c $(CFONTS)/bchri.c $(CFONTS)/bchb.c \
- $(CFONTS)/bchbi.c
+CharterBT_c : $(CFGEN)bchr.c $(CFGEN)bchri.c $(CFGEN)bchb.c $(CFGEN)bchbi.c
+ $(NO_OP)
-$(CFONTS)/bchr.c:
- $(FONT2C) Charter-Roman $(CFONTS)/bchr.c chr
+$(CFGEN)bchr.c :
+ $(FONT2C) Charter-Roman $(CFGEN)bchr.c chr
-$(CFONTS)/bchri.c:
- $(FONT2C) Charter-Italic $(CFONTS)/bchri.c chri
+$(CFGEN)bchri.c :
+ $(FONT2C) Charter-Italic $(CFGEN)bchri.c chri
-$(CFONTS)/bchb.c:
- $(FONT2C) Charter-Bold $(CFONTS)/bchb.c chb
+$(CFGEN)bchb.c :
+ $(FONT2C) Charter-Bold $(CFGEN)bchb.c chb
-$(CFONTS)/bchbi.c:
- $(FONT2C) Charter-BoldItalic $(CFONTS)/bchbi.c chbi
+$(CFGEN)bchbi.c :
+ $(FONT2C) Charter-BoldItalic $(CFGEN)bchbi.c chbi
-CharterBT_o: bchr.$(OBJ) bchri.$(OBJ) bchb.$(OBJ) bchbi.$(OBJ)
+CharterBT_o : $(CFOBJ)bchr.$(OBJ) $(CFOBJ)bchri.$(OBJ) $(CFOBJ)bchb.$(OBJ) $(CFOBJ)bchbi.$(OBJ)
+ $(NO_OP)
-bchr.$(OBJ): $(CFONTS)/bchr.c $(CCFONT)
- $(CCCF) $(CFONTS)/bchr.c
+$(CFOBJ)bchr.$(OBJ) : $(CFGEN)bchr.c $(CCFONT)
+ $(CFCC) $(CFO_)bchr.$(OBJ) $(C_) $(CFGEN)bchr.c
-bchri.$(OBJ): $(CFONTS)/bchri.c $(CCFONT)
- $(CCCF) $(CFONTS)/bchri.c
+$(CFOBJ)bchri.$(OBJ) : $(CFGEN)bchri.c $(CCFONT)
+ $(CFCC) $(CFO_)bchri.$(OBJ) $(C_) $(CFGEN)bchri.c
-bchb.$(OBJ): $(CFONTS)/bchb.c $(CCFONT)
- $(CCCF) $(CFONTS)/bchb.c
+$(CFOBJ)bchb.$(OBJ) : $(CFGEN)bchb.c $(CCFONT)
+ $(CFCC) $(CFO_)bchb.$(OBJ) $(C_) $(CFGEN)bchb.c
-bchbi.$(OBJ): $(CFONTS)/bchbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/bchbi.c
+$(CFOBJ)bchbi.$(OBJ) : $(CFGEN)bchbi.c $(CCFONT)
+ $(CFCC) $(CFO_)bchbi.$(OBJ) $(C_) $(CFGEN)bchbi.c
# ---------------- Cyrillic ----------------
-Cyrillic_c: $(CFONTS)/fcyr.c $(CFONTS)/fcyri.c
+Cyrillic_c : $(CFGEN)fcyr.c $(CFGEN)fcyri.c
+ $(NO_OP)
-$(CFONTS)/fcyr.c:
- $(FONT2C) Cyrillic $(CFONTS)/fcyr.c fcyr
+$(CFGEN)fcyr.c :
+ $(FONT2C) Cyrillic $(CFGEN)fcyr.c fcyr
-$(CFONTS)/fcyri.c:
- $(FONT2C) Cyrillic-Italic $(CFONTS)/fcyri.c fcyri
+$(CFGEN)fcyri.c :
+ $(FONT2C) Cyrillic-Italic $(CFGEN)fcyri.c fcyri
-Cyrillic_o: fcyr.$(OBJ) fcyri.$(OBJ)
+Cyrillic_o : $(CFOBJ)fcyr.$(OBJ) $(CFOBJ)fcyri.$(OBJ)
+ $(NO_OP)
-fcyr.$(OBJ): $(CFONTS)/fcyr.c $(CCFONT)
- $(CCCF) $(CFONTS)/fcyr.c
+$(CFOBJ)fcyr.$(OBJ) : $(CFGEN)fcyr.c $(CCFONT)
+ $(CFCC) $(CFO_)fcyr.$(OBJ) $(C_) $(CFGEN)fcyr.c
-fcyri.$(OBJ): $(CFONTS)/fcyri.c $(CCFONT)
- $(CCCF) $(CFONTS)/fcyri.c
+$(CFOBJ)fcyri.$(OBJ) : $(CFGEN)fcyri.c $(CCFONT)
+ $(CFCC) $(CFO_)fcyri.$(OBJ) $(C_) $(CFGEN)fcyri.c
# ---------------- Kana ----------------
-Kana_c: $(CFONTS)/fhirw.c $(CFONTS)/fkarw.c
+Kana_c : $(CFGEN)fhirw.c $(CFGEN)fkarw.c
+ $(NO_OP)
-$(CFONTS)/fhirw.c:
- $(FONT2C) Calligraphic-Hiragana $(CFONTS)/fhirw.c fhirw
+$(CFGEN)fhirw.c :
+ $(FONT2C) Calligraphic-Hiragana $(CFGEN)fhirw.c fhirw
-$(CFONTS)/fkarw.c:
- $(FONT2C) Calligraphic-Katakana $(CFONTS)/fkarw.c fkarw
+$(CFGEN)fkarw.c :
+ $(FONT2C) Calligraphic-Katakana $(CFGEN)fkarw.c fkarw
-Kana_o: fhirw.$(OBJ) fkarw.$(OBJ)
+Kana_o : $(CFOBJ)fhirw.$(OBJ) $(CFOBJ)fkarw.$(OBJ)
+ $(NO_OP)
-fhirw.$(OBJ): $(CFONTS)/fhirw.c $(CCFONT)
- $(CCCF) $(CFONTS)/fhirw.c
+$(CFOBJ)fhirw.$(OBJ) : $(CFGEN)fhirw.c $(CCFONT)
+ $(CFCC) $(CFO_)fhirw.$(OBJ) $(C_) $(CFGEN)fhirw.c
-fkarw.$(OBJ): $(CFONTS)/fkarw.c $(CCFONT)
- $(CCCF) $(CFONTS)/fkarw.c
+$(CFOBJ)fkarw.$(OBJ) : $(CFGEN)fkarw.c $(CCFONT)
+ $(CFCC) $(CFO_)fkarw.$(OBJ) $(C_) $(CFGEN)fkarw.c
# ---------------- Utopia ----------------
-Utopia_c: $(CFONTS)/putr.c $(CFONTS)/putri.c $(CFONTS)/putb.c \
- $(CFONTS)/putbi.c
+Utopia_c : $(CFGEN)putr.c $(CFGEN)putri.c $(CFGEN)putb.c $(CFGEN)putbi.c
+ $(NO_OP)
-$(CFONTS)/putr.c:
- $(FONT2C) Utopia-Regular $(CFONTS)/putr.c utr
+$(CFGEN)putr.c :
+ $(FONT2C) Utopia-Regular $(CFGEN)putr.c utr
-$(CFONTS)/putri.c:
- $(FONT2C) Utopia-Italic $(CFONTS)/putri.c utri
+$(CFGEN)putri.c :
+ $(FONT2C) Utopia-Italic $(CFGEN)putri.c utri
-$(CFONTS)/putb.c:
- $(FONT2C) Utopia-Bold $(CFONTS)/putb.c utb
+$(CFGEN)putb.c :
+ $(FONT2C) Utopia-Bold $(CFGEN)putb.c utb
-$(CFONTS)/putbi.c:
- $(FONT2C) Utopia-BoldItalic $(CFONTS)/putbi.c utbi
+$(CFGEN)putbi.c :
+ $(FONT2C) Utopia-BoldItalic $(CFGEN)putbi.c utbi
-Utopia_o: putr.$(OBJ) putri.$(OBJ) putb.$(OBJ) putbi.$(OBJ)
+Utopia_o : $(CFOBJ)putr.$(OBJ) $(CFOBJ)putri.$(OBJ) $(CFOBJ)putb.$(OBJ) $(CFOBJ)putbi.$(OBJ)
+ $(NO_OP)
-putr.$(OBJ): $(CFONTS)/putr.c $(CCFONT)
- $(CCCF) $(CFONTS)/putr.c
+$(CFOBJ)putr.$(OBJ) : $(CFGEN)putr.c $(CCFONT)
+ $(CFCC) $(CFO_)putr.$(OBJ) $(C_) $(CFGEN)putr.c
-putri.$(OBJ): $(CFONTS)/putri.c $(CCFONT)
- $(CCCF) $(CFONTS)/putri.c
+$(CFOBJ)putri.$(OBJ) : $(CFGEN)putri.c $(CCFONT)
+ $(CFCC) $(CFO_)putri.$(OBJ) $(C_) $(CFGEN)putri.c
-putb.$(OBJ): $(CFONTS)/putb.c $(CCFONT)
- $(CCCF) $(CFONTS)/putb.c
+$(CFOBJ)putb.$(OBJ) : $(CFGEN)putb.c $(CCFONT)
+ $(CFCC) $(CFO_)putb.$(OBJ) $(C_) $(CFGEN)putb.c
-putbi.$(OBJ): $(CFONTS)/putbi.c $(CCFONT)
- $(CCCF) $(CFONTS)/putbi.c
+$(CFOBJ)putbi.$(OBJ) : $(CFGEN)putbi.c $(CCFONT)
+ $(CFCC) $(CFO_)putbi.$(OBJ) $(C_) $(CFGEN)putbi.c
diff --git a/gs/src/contrib.mak b/gs/src/contrib.mak
index 49e1a3130..e6553b2c7 100644
--- a/gs/src/contrib.mak
+++ b/gs/src/contrib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -26,7 +26,8 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
# The following drivers are user-contributed, and maintained (if at all)
# by users. Please do not ask Aladdin about problems with these drivers.
-# MS-DOS displays (note: not usable with Desqview/X):
+# Displays:
+# MS-DOS (note: not usable with Desqview/X):
# * herc Hercules Graphics display [MS-DOS only]
# * pe Private Eye display
# Unix and VMS:
@@ -52,10 +53,13 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
# also good for DeskJet 510, 520, and 540C (black only)
# * cdj500 H-P DeskJet 500C (same as cdjcolor)
# * cdj550 H-P DeskJet 550C/560C/660C/660Cse
+# * coslw2p CoStar LabelWriter II II/Plus
+# * coslwxl CoStar LabelWriter XL
# * cp50 Mitsubishi CP50 color printer
# * declj250 alternate DEC LJ250 driver
# * djet500c H-P DeskJet 500C alternate driver
# (does not work on 550C or 560C)
+# * dl2100 DEC DEClaser 2100 printer
# * dnj650c H-P DesignJet 650C
# epson Epson-compatible dot matrix printers (9- or 24-pin)
# * eps9mid Epson-compatible 9-pin, interleaved lines
@@ -79,10 +83,12 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
# * lips3 Canon LIPS III laser printer in English (CaPSL) mode
# * ln03 DEC LN03 printer
# * lj250 DEC LJ250 Companion color printer
+# * lj3100sw H-P LaserJet 3100 (requires installed HP-Software)
# + lj4dith H-P LaserJet 4 with Floyd-Steinberg dithering
# * lp8000 Epson LP-8000 laser printer
# * lq850 Epson LQ850 printer at 360 x 360 DPI resolution;
# also good for Canon BJ300 with LQ850 emulation
+# * lxm5700m Lexmark 5700 monotone
# * m8510 C.Itoh M8510 printer
# * necp6 NEC P6/P6+/P60 printers at 360 x 360 DPI resolution
# * nwp533 Sony Microsystems NWP533 laser printer [Sony only]
@@ -119,6 +125,7 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
# * mgr4 4-bit (VGA) color MGR devices
# * mgr8 8-bit color MGR devices
# * sgirgb SGI RGB pixmap format
+# * sunhmono Harlequin variant of 1-bit Sun raster file
# If you add drivers, it would be nice if you kept each list
# in alphabetical order.
@@ -130,10 +137,10 @@ CONTRIB_MAK=$(GLSRC)contrib.mak
### ------------------- The Hercules Graphics display ------------------- ###
herc_=$(GLOBJ)gdevherc.$(OBJ)
-herc.dev: $(herc_)
- $(SETDEV) herc $(herc_)
+$(DD)herc.dev : $(herc_)
+ $(SETDEV) $(DD)herc $(herc_)
-$(GLOBJ)gdevherc.$(OBJ): $(GLSRC)gdevherc.c $(GDEV) $(dos__h)\
+$(GLOBJ)gdevherc.$(OBJ) : $(GLSRC)gdevherc.c $(GDEV) $(dos__h)\
$(gsmatrix_h) $(gxbitmap_h)
$(GLCC) $(GLO_)gdevherc.$(OBJ) $(C_) $(GLSRC)gdevherc.c
@@ -142,10 +149,10 @@ $(GLOBJ)gdevherc.$(OBJ): $(GLSRC)gdevherc.c $(GDEV) $(dos__h)\
### please contact narf@media-lab.media.mit.edu if you have questions. ###
pe_=$(GLOBJ)gdevpe.$(OBJ)
-pe.dev: $(pe_)
- $(SETDEV) pe $(pe_)
+$(DD)pe.dev : $(pe_)
+ $(SETDEV) $(DD)pe $(pe_)
-$(GLOBJ)gdevpe.$(OBJ): $(GLSRC)gdevpe.c $(GDEV) $(memory__h)
+$(GLOBJ)gdevpe.$(OBJ) : $(GLSRC)gdevpe.c $(GDEV) $(memory__h)
$(GLCC) $(GLO_)gdevpe.$(OBJ) $(C_) $(GLSRC)gdevpe.c
###### ----------------------- Other displays ------------------------ ######
@@ -155,10 +162,10 @@ $(GLOBJ)gdevpe.$(OBJ): $(GLSRC)gdevpe.c $(GDEV) $(memory__h)
### Andy Fyfe (andy@cs.caltech.edu) if you have questions. ###
att3b1_=$(GLOBJ)gdev3b1.$(OBJ)
-att3b1.dev: $(att3b1_)
- $(SETDEV) att3b1 $(att3b1_)
+$(DD)att3b1.dev : $(att3b1_)
+ $(SETDEV) $(DD)att3b1 $(att3b1_)
-$(GLOBJ)gdev3b1.$(OBJ): $(GLSRC)gdev3b1.c $(GDEV)
+$(GLOBJ)gdev3b1.$(OBJ) : $(GLSRC)gdev3b1.c $(GDEV)
$(GLCC) $(GLO_)gdev3b1.$(OBJ) $(C_) $(GLSRC)gdev3b1.c
### ------------------- Sony NeWS frame buffer device ------------------ ###
@@ -167,10 +174,10 @@ $(GLOBJ)gdev3b1.$(OBJ): $(GLSRC)gdev3b1.c $(GDEV)
# This is implemented as a 'printer' device.
sonyfb_=$(GLOBJ)gdevsnfb.$(OBJ)
-sonyfb.dev: $(sonyfb_) page.dev
- $(SETPDEV) sonyfb $(sonyfb_)
+$(DD)sonyfb.dev : $(sonyfb_) $(DD)page.dev
+ $(SETPDEV) $(DD)sonyfb $(sonyfb_)
-$(GLOBJ)gdevsnfb.$(OBJ): $(GLSRC)gdevsnfb.c $(PDEVH)
+$(GLOBJ)gdevsnfb.$(OBJ) : $(GLSRC)gdevsnfb.c $(PDEVH)
$(GLCC) $(GLO_)gdevsnfb.$(OBJ) $(C_) $(GLSRC)gdevsnfb.c
### ------------------------ The SunView device ------------------------ ###
@@ -178,11 +185,11 @@ $(GLOBJ)gdevsnfb.$(OBJ): $(GLSRC)gdevsnfb.c $(PDEVH)
### please contact Andreas Stolcke (stolcke@icsi.berkeley.edu). ###
sunview_=$(GLOBJ)gdevsun.$(OBJ)
-sunview.dev: $(sunview_)
- $(SETDEV) sunview $(sunview_)
- $(ADDMOD) sunview -lib suntool sunwindow pixrect
+$(DD)sunview.dev : $(sunview_)
+ $(SETDEV) $(DD)sunview $(sunview_)
+ $(ADDMOD) $(GLGEN)sunview -lib suntool sunwindow pixrect
-$(GLOBJ)gdevsun.$(OBJ): $(GLSRC)gdevsun.c $(GDEV) $(malloc__h)\
+$(GLOBJ)gdevsun.$(OBJ) : $(GLSRC)gdevsun.c $(GDEV) $(malloc__h)\
$(gscdefs_h) $(gserrors_h) $(gsmatrix_h)
$(GLCC) $(GLO_)gdevsun.$(OBJ) $(C_) $(GLSRC)gdevsun.c
@@ -193,8 +200,8 @@ $(GLOBJ)gdevsun.$(OBJ): $(GLSRC)gdevsun.c $(GDEV) $(malloc__h)\
# This is a "printer" device, but it probably shouldn't be.
# I don't know why the implementor chose to do it this way.
sxlcrt_=$(GLOBJ)gdevln03.$(OBJ)
-sxlcrt.dev: $(sxlcrt_) page.dev
- $(SETPDEV) sxlcrt $(sxlcrt_)
+$(DD)sxlcrt.dev : $(sxlcrt_) $(DD)page.dev
+ $(SETPDEV) $(DD)sxlcrt $(sxlcrt_)
###### --------------- Memory-buffered printer devices --------------- ######
@@ -209,32 +216,32 @@ sxlcrt.dev: $(sxlcrt_) page.dev
appledmp_=$(GLOBJ)gdevadmp.$(OBJ)
-$(GLOBJ)gdevadmp.$(OBJ): $(GLSRC)gdevadmp.c $(PDEVH)
+$(GLOBJ)gdevadmp.$(OBJ) : $(GLSRC)gdevadmp.c $(PDEVH)
$(GLCC) $(GLO_)gdevadmp.$(OBJ) $(C_) $(GLSRC)gdevadmp.c
-appledmp.dev: $(appledmp_) page.dev
- $(SETPDEV) appledmp $(appledmp_)
+$(DD)appledmp.dev : $(appledmp_) $(DD)page.dev
+ $(SETPDEV) $(DD)appledmp $(appledmp_)
-iwhi.dev: $(appledmp_) page.dev
- $(SETPDEV) iwhi $(appledmp_)
+$(DD)iwhi.dev : $(appledmp_) $(DD)page.dev
+ $(SETPDEV) $(DD)iwhi $(appledmp_)
-iwlo.dev: $(appledmp_) page.dev
- $(SETPDEV) iwlo $(appledmp_)
+$(DD)iwlo.dev : $(appledmp_) $(DD)page.dev
+ $(SETPDEV) $(DD)iwlo $(appledmp_)
-iwlq.dev: $(appledmp_) page.dev
- $(SETPDEV) iwlq $(appledmp_)
+$(DD)iwlq.dev : $(appledmp_) $(DD)page.dev
+ $(SETPDEV) $(DD)iwlq $(appledmp_)
### ------------ The Canon BubbleJet BJ10e and BJ200 devices ------------ ###
bj10e_=$(GLOBJ)gdevbj10.$(OBJ)
-bj10e.dev: $(bj10e_) page.dev
- $(SETPDEV) bj10e $(bj10e_)
+$(DD)bj10e.dev : $(bj10e_) $(DD)page.dev
+ $(SETPDEV) $(DD)bj10e $(bj10e_)
-bj200.dev: $(bj10e_) page.dev
- $(SETPDEV) bj200 $(bj10e_)
+$(DD)bj200.dev : $(bj10e_) $(DD)page.dev
+ $(SETPDEV) $(DD)bj200 $(bj10e_)
-$(GLOBJ)gdevbj10.$(OBJ): $(GLSRC)gdevbj10.c $(PDEVH)
+$(GLOBJ)gdevbj10.$(OBJ) : $(GLSRC)gdevbj10.c $(PDEVH)
$(GLCC) $(GLO_)gdevbj10.$(OBJ) $(C_) $(GLSRC)gdevbj10.c
### ------------- The CalComp Raster Format ----------------------------- ###
@@ -243,10 +250,10 @@ $(GLOBJ)gdevbj10.$(OBJ): $(GLSRC)gdevbj10.c $(PDEVH)
### questions. ###
ccr_=$(GLOBJ)gdevccr.$(OBJ)
-ccr.dev: $(ccr_) page.dev
- $(SETPDEV) ccr $(ccr_)
+$(DD)ccr.dev : $(ccr_) $(DD)page.dev
+ $(SETPDEV) $(DD)ccr $(ccr_)
-$(GLOBJ)gdevccr.$(OBJ): $(GLSRC)gdevccr.c $(PDEVH)
+$(GLOBJ)gdevccr.$(OBJ) : $(GLSRC)gdevccr.c $(PDEVH)
$(GLCC) $(GLO_)gdevccr.$(OBJ) $(C_) $(GLSRC)gdevccr.c
### The H-P DeskJet, PaintJet, and DesignJet family color printer devices.###
@@ -264,74 +271,111 @@ $(GLOBJ)gdevccr.$(OBJ): $(GLSRC)gdevccr.c $(PDEVH)
cdeskjet_=$(GLOBJ)gdevcdj.$(OBJ) $(HPPCL)
-cdeskjet.dev: $(cdeskjet_) page.dev
- $(SETPDEV) cdeskjet $(cdeskjet_)
+$(DD)cdeskjet.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)cdeskjet $(cdeskjet_)
-cdjcolor.dev: $(cdeskjet_) page.dev
- $(SETPDEV) cdjcolor $(cdeskjet_)
+$(DD)cdjcolor.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)cdjcolor $(cdeskjet_)
-cdjmono.dev: $(cdeskjet_) page.dev
- $(SETPDEV) cdjmono $(cdeskjet_)
+$(DD)cdjmono.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)cdjmono $(cdeskjet_)
-cdj500.dev: $(cdeskjet_) page.dev
- $(SETPDEV) cdj500 $(cdeskjet_)
+$(DD)cdj500.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)cdj500 $(cdeskjet_)
-cdj550.dev: $(cdeskjet_) page.dev
- $(SETPDEV) cdj550 $(cdeskjet_)
+$(DD)cdj550.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)cdj550 $(cdeskjet_)
-declj250.dev: $(cdeskjet_) page.dev
- $(SETPDEV) declj250 $(cdeskjet_)
+$(DD)declj250.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)declj250 $(cdeskjet_)
-dnj650c.dev: $(cdeskjet_) page.dev
- $(SETPDEV) dnj650c $(cdeskjet_)
+$(DD)dnj650c.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)dnj650c $(cdeskjet_)
-lj4dith.dev: $(cdeskjet_) page.dev
- $(SETPDEV) lj4dith $(cdeskjet_)
+$(DD)lj4dith.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)lj4dith $(cdeskjet_)
-pj.dev: $(cdeskjet_) page.dev
- $(SETPDEV) pj $(cdeskjet_)
+$(DD)pj.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)pj $(cdeskjet_)
-pjxl.dev: $(cdeskjet_) page.dev
- $(SETPDEV) pjxl $(cdeskjet_)
+$(DD)pjxl.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)pjxl $(cdeskjet_)
# Note: the pjxl300 driver also works for the CopyJet.
-pjxl300.dev: $(cdeskjet_) page.dev
- $(SETPDEV) pjxl300 $(cdeskjet_)
+$(DD)pjxl300.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)pjxl300 $(cdeskjet_)
# Note: the BJC600 driver also works for the BJC4000.
-bjc600.dev: $(cdeskjet_) page.dev
- $(SETPDEV) bjc600 $(cdeskjet_)
+$(DD)bjc600.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)bjc600 $(cdeskjet_)
-bjc800.dev: $(cdeskjet_) page.dev
- $(SETPDEV) bjc800 $(cdeskjet_)
+$(DD)bjc800.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)bjc800 $(cdeskjet_)
-escp.dev: $(cdeskjet_) page.dev
- $(SETPDEV) escp $(cdeskjet_)
+$(DD)escp.dev : $(cdeskjet_) $(DD)page.dev
+ $(SETPDEV) $(DD)escp $(cdeskjet_)
# NB: you can also customise the build if required, using
# -DBitsPerPixel=<number> if you wish the default to be other than 24
# for the generic drivers (cdj500, cdj550, pjxl300, pjtest, pjxltest).
-$(GLOBJ)gdevcdj.$(OBJ): $(GLSRC)gdevcdj.c $(std_h) $(PDEVH) $(GLSRC)gdevbjc.h\
+
+gdevbjc_h=$(GLSRC)gdevbjc.h
+
+$(GLOBJ)gdevcdj.$(OBJ) : $(GLSRC)gdevcdj.c $(std_h) $(PDEVH)\
$(gsparam_h) $(gsstate_h) $(gxlum_h)\
- $(gdevpcl_h)
+ $(gdevbjc_h) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevcdj.$(OBJ) $(C_) $(GLSRC)gdevcdj.c
djet500c_=$(GLOBJ)gdevdjtc.$(OBJ) $(HPPCL)
-djet500c.dev: $(djet500c_) page.dev
- $(SETPDEV) djet500c $(djet500c_)
+$(DD)djet500c.dev : $(djet500c_) $(DD)page.dev
+ $(SETPDEV) $(DD)djet500c $(djet500c_)
-$(GLOBJ)gdevdjtc.$(OBJ): $(GLSRC)gdevdjtc.c $(PDEVH) $(malloc__h) $(gdevpcl_h)
+$(GLOBJ)gdevdjtc.$(OBJ) : $(GLSRC)gdevdjtc.c $(PDEVH) $(malloc__h) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevdjtc.$(OBJ) $(C_) $(GLSRC)gdevdjtc.c
+### --------------- The H-P LaserJet 3100 software device --------------- ###
+
+### NOTE: This driver requires installed HP-Software to print. ###
+### It can be used with smbclient to print from an UNIX box to a ###
+### LaserJet 3100 printer attached to a MS-Windows box. ###
+### NOTE: this driver was contributed by a user: please contact ###
+### Ulrich Schmid (uschmid@mail.hh.provi.de) if you have questions. ###
+
+lj3100sw_=$(GLOBJ)gdevl31s.$(OBJ) $(GLOBJ)gdevmeds.$(OBJ)
+$(DD)lj3100sw.dev : $(lj3100sw_) $(DD)page.dev
+ $(SETPDEV) $(DD)lj3100sw $(lj3100sw_)
+
+gdevmeds_h=$(GLSRC)gdevmeds.h $(gdevprn_h)
+
+$(GLOBJ)gdevl31s.$(OBJ) : $(GLSRC)gdevl31s.c $(gdevmeds_h) $(PDEVH)
+ $(GLCC) $(GLO_)gdevl31s.$(OBJ) $(C_) $(GLSRC)gdevl31s.c
+
+$(GLOBJ)gdevmeds.$(OBJ) : $(GLSRC)gdevmeds.c $(AK) $(gdevmeds_h)
+ $(GLCC) $(GLO_)gdevmeds.$(OBJ) $(C_) $(GLSRC)gdevmeds.c
+
+### ------ CoStar LabelWriter II II/Plus device ------ ###
+### Contributed by Mike McCauley mikem@open.com.au ###
+
+coslw_=$(GLOBJ)gdevcslw.$(OBJ)
+
+$(DD)coslw2p.dev : $(coslw_) $(DD)page.dev
+ $(SETPDEV) $(DD)coslw2p $(coslw_)
+
+$(DD)coslwxl.dev : $(coslw_) page.dev
+ $(SETPDEV) ($DD)coslwxl $(coslw_)
+
+$(GLOBJ)gdevcslw.$(OBJ) : $(GLSRC)gdevcslw.c $(PDEVH)
+ $(GLCC) $(GLO_)gdevcslw.$(OBJ) $(C_) $(GLSRC)gdevcslw.c
+
### -------------------- The Mitsubishi CP50 printer -------------------- ###
### Note: this driver was contributed by a user: please contact ###
### Michael Hu (michael@ximage.com) if you have questions. ###
cp50_=$(GLOBJ)gdevcp50.$(OBJ)
-cp50.dev: $(cp50_) page.dev
- $(SETPDEV) cp50 $(cp50_)
+$(DD)cp50.dev : $(cp50_) $(DD)page.dev
+ $(SETPDEV) $(DD)cp50 $(cp50_)
-$(GLOBJ)gdevcp50.$(OBJ): $(GLSRC)gdevcp50.c $(PDEVH)
+$(GLOBJ)gdevcp50.$(OBJ) : $(GLSRC)gdevcp50.c $(PDEVH)
$(GLCC) $(GLO_)gdevcp50.$(OBJ) $(C_) $(GLSRC)gdevcp50.c
### ----------------- The generic Epson printer device ----------------- ###
@@ -343,32 +387,32 @@ $(GLOBJ)gdevcp50.$(OBJ): $(GLSRC)gdevcp50.c $(PDEVH)
epson_=$(GLOBJ)gdevepsn.$(OBJ)
-epson.dev: $(epson_) page.dev
- $(SETPDEV) epson $(epson_)
+$(DD)epson.dev : $(epson_) $(DD)page.dev
+ $(SETPDEV) $(DD)epson $(epson_)
-eps9mid.dev: $(epson_) page.dev
- $(SETPDEV) eps9mid $(epson_)
+$(DD)eps9mid.dev : $(epson_) $(DD)page.dev
+ $(SETPDEV) $(DD)eps9mid $(epson_)
-eps9high.dev: $(epson_) page.dev
- $(SETPDEV) eps9high $(epson_)
+$(DD)eps9high.dev : $(epson_) $(DD)page.dev
+ $(SETPDEV) $(DD)eps9high $(epson_)
-$(GLOBJ)gdevepsn.$(OBJ): $(GLSRC)gdevepsn.c $(PDEVH)
+$(GLOBJ)gdevepsn.$(OBJ) : $(GLSRC)gdevepsn.c $(PDEVH)
$(GLCC) $(GLO_)gdevepsn.$(OBJ) $(C_) $(GLSRC)gdevepsn.c
### ----------------- The IBM Proprinter printer device ---------------- ###
-ibmpro.dev: $(epson_) page.dev
- $(SETPDEV) ibmpro $(epson_)
+$(DD)ibmpro.dev : $(epson_) $(DD)page.dev
+ $(SETPDEV) $(DD)ibmpro $(epson_)
### -------------- The Epson LQ-2550 color printer device -------------- ###
### Note: this driver was contributed by users: please contact ###
### Dave St. Clair (dave@exlog.com) if you have questions. ###
epsonc_=$(GLOBJ)gdevepsc.$(OBJ)
-epsonc.dev: $(epsonc_) page.dev
- $(SETPDEV) epsonc $(epsonc_)
+$(DD)epsonc.dev : $(epsonc_) $(DD)page.dev
+ $(SETPDEV) $(DD)epsonc $(epsonc_)
-$(GLOBJ)gdevepsc.$(OBJ): $(GLSRC)gdevepsc.c $(PDEVH)
+$(GLOBJ)gdevepsc.$(OBJ) : $(GLSRC)gdevepsc.c $(PDEVH)
$(GLCC) $(GLO_)gdevepsc.$(OBJ) $(C_) $(GLSRC)gdevepsc.c
### ------------- The Epson ESC/P 2 language printer devices ------------- ###
@@ -380,36 +424,36 @@ $(GLOBJ)gdevepsc.$(OBJ): $(GLSRC)gdevepsc.c $(PDEVH)
ESCP2=$(GLOBJ)gdevescp.$(OBJ)
-$(GLOBJ)gdevescp.$(OBJ): $(GLSRC)gdevescp.c $(PDEVH)
+$(GLOBJ)gdevescp.$(OBJ) : $(GLSRC)gdevescp.c $(PDEVH)
$(GLCC) $(GLO_)gdevescp.$(OBJ) $(C_) $(GLSRC)gdevescp.c
-ap3250.dev: $(ESCP2) page.dev
- $(SETPDEV) ap3250 $(ESCP2)
+$(DD)ap3250.dev : $(ESCP2) $(DD)page.dev
+ $(SETPDEV) $(DD)ap3250 $(ESCP2)
-st800.dev: $(ESCP2) page.dev
- $(SETPDEV) st800 $(ESCP2)
+$(DD)st800.dev : $(ESCP2) $(DD)page.dev
+ $(SETPDEV) $(DD)st800 $(ESCP2)
stcolor1_=$(GLOBJ)gdevstc.$(OBJ) $(GLOBJ)gdevstc1.$(OBJ) $(GLOBJ)gdevstc2.$(OBJ)
stcolor2_=$(GLOBJ)gdevstc3.$(OBJ) $(GLOBJ)gdevstc4.$(OBJ)
-stcolor.dev: $(stcolor1_) $(stcolor2_) page.dev
- $(SETPDEV) stcolor $(stcolor1_)
- $(ADDMOD) stcolor -obj $(stcolor2_)
+$(DD)stcolor.dev : $(stcolor1_) $(stcolor2_) $(DD)page.dev
+ $(SETPDEV) $(DD)stcolor $(stcolor1_)
+ $(ADDMOD) $(GLGEN)stcolor -obj $(stcolor2_)
gdevstc_h=$(GLSRC)gdevstc.h $(gdevprn_h) $(gsparam_h) $(gsstate_h)
-$(GLOBJ)gdevstc.$(OBJ): $(GLSRC)gdevstc.c $(gdevstc_h) $(PDEVH)
+$(GLOBJ)gdevstc.$(OBJ) : $(GLSRC)gdevstc.c $(gdevstc_h) $(PDEVH)
$(GLCC) $(GLO_)gdevstc.$(OBJ) $(C_) $(GLSRC)gdevstc.c
-$(GLOBJ)gdevstc1.$(OBJ): $(GLSRC)gdevstc1.c $(gdevstc_h) $(PDEVH)
+$(GLOBJ)gdevstc1.$(OBJ) : $(GLSRC)gdevstc1.c $(gdevstc_h) $(PDEVH)
$(GLCC) $(GLO_)gdevstc1.$(OBJ) $(C_) $(GLSRC)gdevstc1.c
-$(GLOBJ)gdevstc2.$(OBJ): $(GLSRC)gdevstc2.c $(gdevstc_h) $(PDEVH)
+$(GLOBJ)gdevstc2.$(OBJ) : $(GLSRC)gdevstc2.c $(gdevstc_h) $(PDEVH)
$(GLCC) $(GLO_)gdevstc2.$(OBJ) $(C_) $(GLSRC)gdevstc2.c
-$(GLOBJ)gdevstc3.$(OBJ): $(GLSRC)gdevstc3.c $(gdevstc_h) $(PDEVH)
+$(GLOBJ)gdevstc3.$(OBJ) : $(GLSRC)gdevstc3.c $(gdevstc_h) $(PDEVH)
$(GLCC) $(GLO_)gdevstc3.$(OBJ) $(C_) $(GLSRC)gdevstc3.c
-$(GLOBJ)gdevstc4.$(OBJ): $(GLSRC)gdevstc4.c $(gdevstc_h) $(PDEVH)
+$(GLOBJ)gdevstc4.$(OBJ) : $(GLSRC)gdevstc4.c $(gdevstc_h) $(PDEVH)
$(GLCC) $(GLO_)gdevstc4.$(OBJ) $(C_) $(GLSRC)gdevstc4.c
### --------------- Ugly/Update -> Unified Printer Driver ---------------- ###
@@ -417,23 +461,33 @@ $(GLOBJ)gdevstc4.$(OBJ): $(GLSRC)gdevstc4.c $(gdevstc_h) $(PDEVH)
### Gunther Hess (gunther@elmos.de) ###
uniprint_=$(GLOBJ)gdevupd.$(OBJ)
-uniprint.dev: $(uniprint_) page.dev
- $(SETPDEV) uniprint $(uniprint_)
+$(DD)uniprint.dev : $(uniprint_) $(DD)page.dev
+ $(SETPDEV) $(DD)uniprint $(uniprint_)
-$(GLOBJ)gdevupd.$(OBJ): $(GLSRC)gdevupd.c $(PDEVH) $(gsparam_h)
+$(GLOBJ)gdevupd.$(OBJ) : $(GLSRC)gdevupd.c $(PDEVH) $(gsparam_h)
$(GLCC) $(GLO_)gdevupd.$(OBJ) $(C_) $(GLSRC)gdevupd.c
### -------------- cdj850 - HP 850c Driver under development ------------- ###
-### Since this driver is in the development-phase it is not distributed ###
-### with ghostscript, but it is available via anonymous ftp from: ###
-### ftp://bonk.ethz.ch ###
### For questions about this driver, please contact: ###
-### Uli Wortmann (E-Mail address inside the driver-package) ###
+### Uli Wortmann (uliw@erdw.ethz.ch) ###
cdeskjet8_=$(GLOBJ)gdevcd8.$(OBJ) $(HPPCL)
-cdj850.dev: $(cdeskjet8_) page.dev
- $(SETPDEV) cdj850 $(cdeskjet8_)
+$(DD)cdj850.dev : $(cdeskjet8_) $(DD)page.dev
+ $(SETPDEV2) $(DD)cdj850 $(cdeskjet8_)
+
+$(DD)cdj670.dev : $(cdeskjet8_) $(DD)page.dev
+ $(SETPDEV2) $(DD)cdj670 $(cdeskjet8_)
+
+$(DD)cdj890.dev : $(cdeskjet8_) $(DD)page.dev
+ $(SETPDEV2) $(DD)cdj890 $(cdeskjet8_)
+
+$(DD)cdj1600.dev : $(cdeskjet8_) $(DD)page.dev
+ $(SETPDEV2) $(DD)cdj1600 $(cdeskjet8_)
+
+$(GLOBJ)gdevcd8.$(OBJ) : $(GLSRC)gdevcd8.c $(PDEVH) $(math__h)\
+ $(gsparam_h) $(gxlum_h) $(gdevpcl_h)
+ $(GLCC) $(GLO_)gdevcd8.$(OBJ) $(C_) $(GLSRC)gdevcd8.c
### ------------ The H-P PaintJet color printer device ----------------- ###
### Note: this driver also supports the DEC LJ250 color printer, which ###
@@ -443,17 +497,17 @@ cdj850.dev: $(cdeskjet8_) page.dev
PJET=$(GLOBJ)gdevpjet.$(OBJ) $(HPPCL)
-$(GLOBJ)gdevpjet.$(OBJ): $(GLSRC)gdevpjet.c $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdevpjet.$(OBJ) : $(GLSRC)gdevpjet.c $(PDEVH) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevpjet.$(OBJ) $(C_) $(GLSRC)gdevpjet.c
-lj250.dev: $(PJET) page.dev
- $(SETPDEV) lj250 $(PJET)
+$(DD)lj250.dev : $(PJET) $(DD)page.dev
+ $(SETPDEV) $(DD)lj250 $(PJET)
-paintjet.dev: $(PJET) page.dev
- $(SETPDEV) paintjet $(PJET)
+$(DD)paintjet.dev : $(PJET) $(DD)page.dev
+ $(SETPDEV) $(DD)paintjet $(PJET)
-pjetxl.dev: $(PJET) page.dev
- $(SETPDEV) pjetxl $(PJET)
+$(DD)pjetxl.dev : $(PJET) $(DD)page.dev
+ $(SETPDEV) $(DD)pjetxl $(PJET)
###--------------------- The Brother HL 7x0 printer --------------------- ###
### This driver was contributed by a user : ###
@@ -461,10 +515,10 @@ pjetxl.dev: $(PJET) page.dev
### if you have any questions. ###
hl7x0_=$(GLOBJ)gdevhl7x.$(OBJ)
-hl7x0.dev: $(hl7x0_) page.dev
- $(SETPDEV) hl7x0 $(hl7x0_)
+$(DD)hl7x0.dev : $(hl7x0_) $(DD)page.dev
+ $(SETPDEV) $(DD)hl7x0 $(hl7x0_)
-$(GLOBJ)gdevhl7x.$(OBJ): $(GLSRC)gdevhl7x.c $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdevhl7x.$(OBJ) : $(GLSRC)gdevhl7x.c $(PDEVH) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevhl7x.$(OBJ) $(C_) $(GLSRC)gdevhl7x.c
### -------------- Imagen ImPress Laser Printer device ----------------- ###
@@ -475,13 +529,13 @@ $(GLOBJ)gdevhl7x.$(OBJ): $(GLSRC)gdevhl7x.c $(PDEVH) $(gdevpcl_h)
### You may also add -DA4 if needed for A4 paper. ###
imagen_=$(GLOBJ)gdevimgn.$(OBJ)
-imagen.dev: $(imagen_) page.dev
- $(SETPDEV) imagen $(imagen_)
+$(DD)imagen.dev : $(imagen_) $(DD)page.dev
+ $(SETPDEV) $(DD)imagen $(imagen_)
# Uncomment the first line for the ipr spooler, the second line for parallel.
IMGN_OPT=
#IMGN_OPT=-DUSE_BYTE_STREAM
-$(GLOBJ)gdevimgn.$(OBJ): $(GLSRC)gdevimgn.c $(PDEVH)
+$(GLOBJ)gdevimgn.$(OBJ) : $(GLSRC)gdevimgn.c $(PDEVH)
$(GLCC) $(IMGN_OPT) $(GLO_)gdevimgn.$(OBJ) $(C_) $(GLSRC)gdevimgn.c
### ------- The IBM 3852 JetPrinter color inkjet printer device -------- ###
@@ -492,10 +546,10 @@ $(GLOBJ)gdevimgn.$(OBJ): $(GLSRC)gdevimgn.c $(PDEVH)
### width of the jetprinter itself.) ###
jetp3852_=$(GLOBJ)gdev3852.$(OBJ)
-jetp3852.dev: $(jetp3852_) page.dev
- $(SETPDEV) jetp3852 $(jetp3852_)
+$(DD)jetp3852.dev : $(jetp3852_) $(DD)page.dev
+ $(SETPDEV) $(DD)jetp3852 $(jetp3852_)
-$(GLOBJ)gdev3852.$(OBJ): $(GLSRC)gdev3852.c $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdev3852.$(OBJ) : $(GLSRC)gdev3852.c $(PDEVH) $(gdevpcl_h)
$(GLCC) $(GLO_)gdev3852.$(OBJ) $(C_) $(GLSRC)gdev3852.c
### ---------- The Canon LBP-8II and LIPS III printer devices ---------- ###
@@ -504,18 +558,20 @@ $(GLOBJ)gdev3852.$(OBJ): $(GLSRC)gdev3852.c $(PDEVH) $(gdevpcl_h)
### Lauri Paatero, lauri.paatero@paatero.pp.fi ###
lbp8_=$(GLOBJ)gdevlbp8.$(OBJ)
-lbp8.dev: $(lbp8_) page.dev
- $(SETPDEV) lbp8 $(lbp8_)
+$(DD)lbp8.dev : $(lbp8_) $(DD)page.dev
+ $(SETPDEV) $(DD)lbp8 $(lbp8_)
-lips3.dev: $(lbp8_) page.dev
- $(SETPDEV) lips3 $(lbp8_)
+$(DD)lips3.dev : $(lbp8_) $(DD)page.dev
+ $(SETPDEV) $(DD)lips3 $(lbp8_)
-$(GLOBJ)gdevlbp8.$(OBJ): $(GLSRC)gdevlbp8.c $(PDEVH)
+$(GLOBJ)gdevlbp8.$(OBJ) : $(GLSRC)gdevlbp8.c $(PDEVH)
$(GLCC) $(GLO_)gdevlbp8.$(OBJ) $(C_) $(GLSRC)gdevlbp8.c
-### ----------- The DEC LN03/LA50/LA70/LA75 printer devices ------------ ###
+### -------- The DEC LN03/DL2100/LA50/LA70/LA75 printer devices -------- ###
### Note: this driver was contributed by users: please contact ###
### Ulrich Mueller (ulm@vsnhd1.cern.ch) if you have questions. ###
+### For questions about the DEClaser 2100, please contact ###
+### Nick Brown (nick.brown@coe.int). ###
### For questions about LA50 and LA75, please contact ###
### Ian MacPhedran (macphed@dvinci.USask.CA). ###
### For questions about the LA70, please contact ###
@@ -524,31 +580,34 @@ $(GLOBJ)gdevlbp8.$(OBJ): $(GLSRC)gdevlbp8.c $(PDEVH)
### Andre' Beck (Andre_Beck@IRS.Inf.TU-Dresden.de). ###
ln03_=$(GLOBJ)gdevln03.$(OBJ)
-ln03.dev: $(ln03_) page.dev
- $(SETPDEV) ln03 $(ln03_)
+$(DD)ln03.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)ln03 $(ln03_)
+
+$(DD)dl2100.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)dl2100 $(ln03_)
-la50.dev: $(ln03_) page.dev
- $(SETPDEV) la50 $(ln03_)
+$(DD)la50.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)la50 $(ln03_)
-la70.dev: $(ln03_) page.dev
- $(SETPDEV) la70 $(ln03_)
+$(DD)la70.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)la70 $(ln03_)
-la75.dev: $(ln03_) page.dev
- $(SETPDEV) la75 $(ln03_)
+$(DD)la75.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)la75 $(ln03_)
-la75plus.dev: $(ln03_) page.dev
- $(SETPDEV) la75plus $(ln03_)
+$(DD)la75plus.dev : $(ln03_) $(DD)page.dev
+ $(SETPDEV) $(DD)la75plus $(ln03_)
-$(GLOBJ)gdevln03.$(OBJ): $(GLSRC)gdevln03.c $(PDEVH)
+$(GLOBJ)gdevln03.$(OBJ) : $(GLSRC)gdevln03.c $(PDEVH)
$(GLCC) $(GLO_)gdevln03.$(OBJ) $(C_) $(GLSRC)gdevln03.c
# LA70 driver with low-resolution text enhancement.
la70t_=$(GLOBJ)gdevla7t.$(OBJ)
-la70t.dev: $(la70t_) page.dev
- $(SETPDEV) la70t $(la70t_)
+$(DD)la70t.dev : $(la70t_) $(DD)page.dev
+ $(SETPDEV) $(DD)la70t $(la70t_)
-$(GLOBJ)gdevla7t.$(OBJ): $(GLSRC)gdevla7t.c $(PDEVH)
+$(GLOBJ)gdevla7t.$(OBJ) : $(GLSRC)gdevla7t.c $(PDEVH)
$(GLCC) $(GLO_)gdevla7t.$(OBJ) $(C_) $(GLSRC)gdevla7t.c
### -------------- The Epson LP-8000 laser printer device -------------- ###
@@ -556,10 +615,10 @@ $(GLOBJ)gdevla7t.$(OBJ): $(GLSRC)gdevla7t.c $(PDEVH)
### Oleg Fat'yanov <faty1@rlem.titech.ac.jp> if you have questions.###
lp8000_=$(GLOBJ)gdevlp8k.$(OBJ)
-lp8000.dev: $(lp8000_) page.dev
- $(SETPDEV) lp8000 $(lp8000_)
+$(DD)lp8000.dev : $(lp8000_) $(DD)page.dev
+ $(SETPDEV) $(DD)lp8000 $(lp8000_)
-$(GLOBJ)gdevlp8k.$(OBJ): $(GLSRC)gdevlp8k.c $(PDEVH)
+$(GLOBJ)gdevlp8k.$(OBJ) : $(GLSRC)gdevlp8k.c $(PDEVH)
$(GLCC) $(GLO_)gdevlp8k.$(OBJ) $(C_) $(GLSRC)gdevlp8k.c
### -------------- The C.Itoh M8510 printer device --------------------- ###
@@ -567,10 +626,10 @@ $(GLOBJ)gdevlp8k.$(OBJ): $(GLSRC)gdevlp8k.c $(PDEVH)
### Smith <bob@snuffy.penfield.ny.us> if you have questions. ###
m8510_=$(GLOBJ)gdev8510.$(OBJ)
-m8510.dev: $(m8510_) page.dev
- $(SETPDEV) m8510 $(m8510_)
+$(DD)m8510.dev : $(m8510_) $(DD)page.dev
+ $(SETPDEV) $(DD)m8510 $(m8510_)
-$(GLOBJ)gdev8510.$(OBJ): $(GLSRC)gdev8510.c $(PDEVH)
+$(GLOBJ)gdev8510.$(OBJ) : $(GLSRC)gdev8510.c $(PDEVH)
$(GLCC) $(GLO_)gdev8510.$(OBJ) $(C_) $(GLSRC)gdev8510.c
### -------------- 24pin Dot-matrix printer with 360DPI ---------------- ###
@@ -581,24 +640,35 @@ $(GLOBJ)gdev8510.$(OBJ): $(GLSRC)gdev8510.c $(PDEVH)
### questions about the Epson LQ850. ###
dm24_=$(GLOBJ)gdevdm24.$(OBJ)
-necp6.dev: $(dm24_) page.dev
- $(SETPDEV) necp6 $(dm24_)
+$(DD)necp6.dev : $(dm24_) $(DD)page.dev
+ $(SETPDEV) $(DD)necp6 $(dm24_)
-lq850.dev: $(dm24_) page.dev
- $(SETPDEV) lq850 $(dm24_)
+$(DD)lq850.dev : $(dm24_) $(DD)page.dev
+ $(SETPDEV) $(DD)lq850 $(dm24_)
-$(GLOBJ)gdevdm24.$(OBJ): $(GLSRC)gdevdm24.c $(PDEVH)
+$(GLOBJ)gdevdm24.$(OBJ) : $(GLSRC)gdevdm24.c $(PDEVH)
$(GLCC) $(GLO_)gdevdm24.$(OBJ) $(C_) $(GLSRC)gdevdm24.c
+### ----------------- Lexmark 5700 printer ----------------------------- ###
+### Note: this driver was contributed by users. Please contact: ###
+### Stephen Taylor (setaylor@ma.ultranet.com) if you have questions. ###
+
+lxm5700m_=$(GLOBJ)gdevlxm.$(OBJ)
+$(DD)lxm5700m.dev : $(lxm5700m_) $(DD)page.dev
+ $(SETPDEV) $(DD)lxm5700m $(lxm5700m_)
+
+$(GLOBJ)gdevlxm.$(OBJ) : $(GLSRC)gdevlxm.c $(PDEVH) $(gsparams_h)
+ $(GLCC) $(GLO_)gdevlxm.$(OBJ) $(C_) $(GLSRC)gdevlxm.c
+
### ----------------- The Okidata MicroLine 182 device ----------------- ###
### Note: this driver was contributed by a user: please contact ###
### Maarten Koning (smeg@bnr.ca) if you have questions. ###
oki182_=$(GLOBJ)gdevo182.$(OBJ)
-oki182.dev: $(oki182_) page.dev
- $(SETPDEV) oki182 $(oki182_)
+$(DD)oki182.dev : $(oki182_) $(DD)page.dev
+ $(SETPDEV) $(DD)oki182 $(oki182_)
-$(GLOBJ)gdevo182.$(OBJ): $(GLSRC)gdevo182.c $(PDEVH)
+$(GLOBJ)gdevo182.$(OBJ) : $(GLSRC)gdevo182.c $(PDEVH)
$(GLCC) $(GLO_)gdevo182.$(OBJ) $(C_) $(GLSRC)gdevo182.c
### ------------- The Okidata IBM compatible printer device ------------ ###
@@ -606,10 +676,10 @@ $(GLOBJ)gdevo182.$(OBJ): $(GLSRC)gdevo182.c $(PDEVH)
### Charles Mack (chasm@netcom.com) if you have questions. ###
okiibm_=$(GLOBJ)gdevokii.$(OBJ)
-okiibm.dev: $(okiibm_) page.dev
- $(SETPDEV) okiibm $(okiibm_)
+$(DD)okiibm.dev : $(okiibm_) $(DD)page.dev
+ $(SETPDEV) $(DD)okiibm $(okiibm_)
-$(GLOBJ)gdevokii.$(OBJ): $(GLSRC)gdevokii.c $(PDEVH)
+$(GLOBJ)gdevokii.$(OBJ) : $(GLSRC)gdevokii.c $(PDEVH)
$(GLCC) $(GLO_)gdevokii.$(OBJ) $(C_) $(GLSRC)gdevokii.c
### ------------- The Ricoh 4081 laser printer device ------------------ ###
@@ -617,11 +687,11 @@ $(GLOBJ)gdevokii.$(OBJ): $(GLSRC)gdevokii.c $(PDEVH)
### please contact kdw@oasis.icl.co.uk if you have questions. ###
r4081_=$(GLOBJ)gdev4081.$(OBJ)
-r4081.dev: $(r4081_) page.dev
- $(SETPDEV) r4081 $(r4081_)
+$(DD)r4081.dev : $(r4081_) $(DD)page.dev
+ $(SETPDEV) $(DD)r4081 $(r4081_)
-$(GLOBJ)gdev4081.$(OBJ): $(GLSRC)gdev4081.c $(PDEVH)
+$(GLOBJ)gdev4081.$(OBJ) : $(GLSRC)gdev4081.c $(PDEVH)
$(GLCC) $(GLO_)gdev4081.$(OBJ) $(C_) $(GLSRC)gdev4081.c
### -------------------- Sony NWP533 printer device -------------------- ###
@@ -629,10 +699,10 @@ $(GLOBJ)gdev4081.$(OBJ): $(GLSRC)gdev4081.c $(PDEVH)
### Kivinen (kivinen@joker.cs.hut.fi) if you have questions. ###
nwp533_=$(GLOBJ)gdevn533.$(OBJ)
-nwp533.dev: $(nwp533_) page.dev
- $(SETPDEV) nwp533 $(nwp533_)
+$(DD)nwp533.dev : $(nwp533_) $(DD)page.dev
+ $(SETPDEV) $(DD)nwp533 $(nwp533_)
-$(GLOBJ)gdevn533.$(OBJ): $(GLSRC)gdevn533.c $(PDEVH)
+$(GLOBJ)gdevn533.$(OBJ) : $(GLSRC)gdevn533.c $(PDEVH)
$(GLCC) $(GLO_)gdevn533.$(OBJ) $(C_) $(GLSRC)gdevn533.c
### ------------------------- The SPARCprinter ------------------------- ###
@@ -642,10 +712,10 @@ $(GLOBJ)gdevn533.$(OBJ): $(GLSRC)gdevn533.c $(PDEVH)
### Please consult the source code for additional documentation. ###
sparc_=$(GLOBJ)gdevsppr.$(OBJ)
-sparc.dev: $(sparc_) page.dev
- $(SETPDEV) sparc $(sparc_)
+$(DD)sparc.dev : $(sparc_) $(DD)page.dev
+ $(SETPDEV) $(DD)sparc $(sparc_)
-$(GLOBJ)gdevsppr.$(OBJ): $(GLSRC)gdevsppr.c $(PDEVH)
+$(GLOBJ)gdevsppr.$(OBJ) : $(GLSRC)gdevsppr.c $(PDEVH)
$(GLCC) $(GLO_)gdevsppr.$(OBJ) $(C_) $(GLSRC)gdevsppr.c
### ----------------- The StarJet SJ48 device -------------------------- ###
@@ -654,10 +724,10 @@ $(GLOBJ)gdevsppr.$(OBJ): $(GLSRC)gdevsppr.c $(PDEVH)
### please contact Mats Akerblom (f86ma@dd.chalmers.se). ###
sj48_=$(GLOBJ)gdevsj48.$(OBJ)
-sj48.dev: $(sj48_) page.dev
- $(SETPDEV) sj48 $(sj48_)
+$(DD)sj48.dev : $(sj48_) $(DD)page.dev
+ $(SETPDEV) $(DD)sj48 $(sj48_)
-$(GLOBJ)gdevsj48.$(OBJ): $(GLSRC)gdevsj48.c $(PDEVH)
+$(GLOBJ)gdevsj48.$(OBJ) : $(GLSRC)gdevsj48.c $(PDEVH)
$(GLCC) $(GLO_)gdevsj48.$(OBJ) $(C_) $(GLSRC)gdevsj48.c
### ----------------- Tektronix 4396d color printer -------------------- ###
@@ -666,16 +736,16 @@ $(GLOBJ)gdevsj48.$(OBJ): $(GLSRC)gdevsj48.c $(PDEVH)
### if you have questions. ###
t4693d_=$(GLOBJ)gdev4693.$(OBJ)
-t4693d2.dev: $(t4693d_) page.dev
- $(SETPDEV) t4693d2 $(t4693d_)
+$(DD)t4693d2.dev : $(t4693d_) $(DD)page.dev
+ $(SETPDEV) $(DD)t4693d2 $(t4693d_)
-t4693d4.dev: $(t4693d_) page.dev
- $(SETPDEV) t4693d4 $(t4693d_)
+$(DD)t4693d4.dev : $(t4693d_) $(DD)page.dev
+ $(SETPDEV) $(DD)t4693d4 $(t4693d_)
-t4693d8.dev: $(t4693d_) page.dev
- $(SETPDEV) t4693d8 $(t4693d_)
+$(DD)t4693d8.dev : $(t4693d_) $(DD)page.dev
+ $(SETPDEV) $(DD)t4693d8 $(t4693d_)
-$(GLOBJ)gdev4693.$(OBJ): $(GLSRC)gdev4693.c $(PDEVH)
+$(GLOBJ)gdev4693.$(OBJ) : $(GLSRC)gdev4693.c $(PDEVH)
$(GLCC) $(GLO_)gdev4693.$(OBJ) $(C_) $(GLSRC)gdev4693.c
### -------------------- Tektronix ink-jet printers -------------------- ###
@@ -683,10 +753,10 @@ $(GLOBJ)gdev4693.$(OBJ): $(GLSRC)gdev4693.c $(PDEVH)
### Karsten Spang (spang@nbivax.nbi.dk) if you have questions. ###
tek4696_=$(GLOBJ)gdevtknk.$(OBJ)
-tek4696.dev: $(tek4696_) page.dev
- $(SETPDEV) tek4696 $(tek4696_)
+$(DD)tek4696.dev : $(tek4696_) $(DD)page.dev
+ $(SETPDEV) $(DD)tek4696 $(tek4696_)
-$(GLOBJ)gdevtknk.$(OBJ): $(GLSRC)gdevtknk.c $(PDEVH) $(malloc__h)
+$(GLOBJ)gdevtknk.$(OBJ) : $(GLSRC)gdevtknk.c $(PDEVH) $(malloc__h)
$(GLCC) $(GLO_)gdevtknk.$(OBJ) $(C_) $(GLSRC)gdevtknk.c
### ----------------- The Xerox XES printer device --------------------- ###
@@ -694,10 +764,10 @@ $(GLOBJ)gdevtknk.$(OBJ): $(GLSRC)gdevtknk.c $(PDEVH) $(malloc__h)
### Peter Flass (flass@lbdrscs.bitnet) if you have questions. ###
xes_=$(GLOBJ)gdevxes.$(OBJ)
-xes.dev: $(xes_) page.dev
- $(SETPDEV) xes $(xes_)
+$(DD)xes.dev : $(xes_) $(DD)page.dev
+ $(SETPDEV) $(DD)xes $(xes_)
-$(GLOBJ)gdevxes.$(OBJ): $(GLSRC)gdevxes.c $(PDEVH)
+$(GLOBJ)gdevxes.$(OBJ) : $(GLSRC)gdevxes.c $(PDEVH)
$(GLCC) $(GLO_)gdevxes.$(OBJ) $(C_) $(GLSRC)gdevxes.c
###### ------------------------- Fax devices ------------------------- ######
@@ -711,15 +781,15 @@ $(GLOBJ)gdevxes.$(OBJ): $(GLSRC)gdevxes.c $(PDEVH)
dfax_=$(GLOBJ)gdevdfax.$(OBJ)
-dfaxlow.dev: $(dfax_) tfax.dev
- $(SETDEV) dfaxlow $(dfax_)
- $(ADDMOD) dfaxlow -include tfax
+$(DD)dfaxlow.dev : $(dfax_) $(DD)tfax.dev
+ $(SETDEV) $(DD)dfaxlow $(dfax_)
+ $(ADDMOD) $(GLGEN)dfaxlow -include $(DD)tfax
-dfaxhigh.dev: $(dfax_) tfax.dev
- $(SETDEV) dfaxhigh $(dfax_)
- $(ADDMOD) dfaxhigh -include tfax
+$(DD)dfaxhigh.dev : $(dfax_) $(DD)tfax.dev
+ $(SETDEV) $(DD)dfaxhigh $(dfax_)
+ $(ADDMOD) $(GLGEN)dfaxhigh -include $(DD)tfax
-$(GLOBJ)gdevdfax.$(OBJ): $(GLSRC)gdevdfax.c $(PDEVH) $(scfx_h) $(strimpl_h)
+$(GLOBJ)gdevdfax.$(OBJ) : $(GLSRC)gdevdfax.c $(PDEVH) $(scfx_h) $(strimpl_h)
$(GLCC) $(GLO_)gdevdfax.$(OBJ) $(C_) $(GLSRC)gdevdfax.c
###### --------------------- Raster file formats --------------------- ######
@@ -729,10 +799,10 @@ $(GLOBJ)gdevdfax.$(OBJ): $(GLSRC)gdevdfax.c $(PDEVH) $(scfx_h) $(strimpl_h)
### Frederic Petrot (petrot@masi.ibp.fr) if you have questions. ###
cif_=$(GLOBJ)gdevcif.$(OBJ)
-cif.dev: $(cif_) page.dev
- $(SETPDEV) cif $(cif_)
+$(DD)cif.dev : $(cif_) $(DD)page.dev
+ $(SETPDEV) $(DD)cif $(cif_)
-$(GLOBJ)gdevcif.$(OBJ): $(GLSRC)gdevcif.c $(PDEVH)
+$(GLOBJ)gdevcif.$(OBJ) : $(GLSRC)gdevcif.c $(PDEVH)
$(GLCC) $(GLO_)gdevcif.$(OBJ) $(C_) $(GLSRC)gdevcif.c
### ------------------------- Inferno bitmaps -------------------------- ###
@@ -740,10 +810,11 @@ $(GLOBJ)gdevcif.$(OBJ): $(GLSRC)gdevcif.c $(PDEVH)
### Russ Cox <rsc@plan9.bell-labs.com> if you have questions. ###
inferno_=$(GLOBJ)gdevifno.$(OBJ)
-inferno.dev: $(inferno_) page.dev
- $(SETPDEV) inferno $(inferno_)
+$(DD)inferno.dev : $(inferno_) $(DD)page.dev
+ $(SETPDEV) $(DD)inferno $(inferno_)
-$(GLOBJ)gdevifno.$(OBJ): $(GLSRC)gdevifno.c $(PDEVH) $(gxlum_h)
+$(GLOBJ)gdevifno.$(OBJ) : $(GLSRC)gdevifno.c $(PDEVH)\
+ $(gsparam_h) $(gxlum_h)
$(GLCC) $(GLO_)gdevifno.$(OBJ) $(C_) $(GLSRC)gdevifno.c
### --------------------------- MGR devices ---------------------------- ###
@@ -752,33 +823,48 @@ $(GLOBJ)gdevifno.$(OBJ): $(GLSRC)gdevifno.c $(PDEVH) $(gxlum_h)
MGR=$(GLOBJ)gdevmgr.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-$(GLOBJ)gdevmgr.$(OBJ): $(GLSRC)gdevmgr.c $(PDEVH)\
- $(gdevpccm_h) $(GLSRC)gdevmgr.h
+gdevmgr_h= $(GLSRC)gdevmgr.h
+
+$(GLOBJ)gdevmgr.$(OBJ) : $(GLSRC)gdevmgr.c $(PDEVH)\
+ $(gdevmgr_h) $(gdevpccm_h)
$(GLCC) $(GLO_)gdevmgr.$(OBJ) $(C_) $(GLSRC)gdevmgr.c
-mgrmono.dev: $(MGR) page.dev
- $(SETPDEV) mgrmono $(MGR)
+$(DD)mgrmono.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgrmono $(MGR)
-mgrgray2.dev: $(MGR) page.dev
- $(SETPDEV) mgrgray2 $(MGR)
+$(DD)mgrgray2.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgrgray2 $(MGR)
-mgrgray4.dev: $(MGR) page.dev
- $(SETPDEV) mgrgray4 $(MGR)
+$(DD)mgrgray4.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgrgray4 $(MGR)
-mgrgray8.dev: $(MGR) page.dev
- $(SETPDEV) mgrgray8 $(MGR)
+$(DD)mgrgray8.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgrgray8 $(MGR)
-mgr4.dev: $(MGR) page.dev
- $(SETPDEV) mgr4 $(MGR)
+$(DD)mgr4.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgr4 $(MGR)
-mgr8.dev: $(MGR) page.dev
- $(SETPDEV) mgr8 $(MGR)
+$(DD)mgr8.dev : $(MGR) $(DD)page.dev
+ $(SETPDEV) $(DD)mgr8 $(MGR)
### -------------------------- SGI RGB pixmaps -------------------------- ###
sgirgb_=$(GLOBJ)gdevsgi.$(OBJ)
-sgirgb.dev: $(sgirgb_) page.dev
- $(SETPDEV) sgirgb $(sgirgb_)
+$(DD)sgirgb.dev : $(sgirgb_) $(DD)page.dev
+ $(SETPDEV) $(DD)sgirgb $(sgirgb_)
-$(GLOBJ)gdevsgi.$(OBJ): $(GLSRC)gdevsgi.c $(PDEVH) $(GLSRC)gdevsgi.h
+gdevsgi_h=$(GLSRC)gdevsgi.h
+
+$(GLOBJ)gdevsgi.$(OBJ) : $(GLSRC)gdevsgi.c $(PDEVH) $(gdevsgi_h)
$(GLCC) $(GLO_)gdevsgi.$(OBJ) $(C_) $(GLSRC)gdevsgi.c
+
+### ---------------- Sun raster files ---------------- ###
+
+sunr_=$(GLOBJ)gdevsunr.$(OBJ)
+
+# Harlequin variant, 1-bit
+$(DD)sunhmono.dev : $(sunr_) $(DD)page.dev
+ $(SETPDEV) $(DD)sunhmono $(sunr_)
+
+$(GLOBJ)gdevsunr.$(OBJ) : $(GLSRC)gdevsunr.c $(PDEVH)
+ $(GLCC) $(GLO_)gdevsunr.$(OBJ) $(C_) $(GLSRC)gdevsunr.c
diff --git a/gs/src/cp.bat b/gs/src/cp.bat
new file mode 100755
index 000000000..3d60b63af
--- /dev/null
+++ b/gs/src/cp.bat
@@ -0,0 +1,15 @@
+
+@echo off
+if "%2"=="." goto ne
+if exist _.tmp erase _.tmp
+rem Both of the following lines are necessary:
+rem the first one works on MS DOS and Windows 95/98 but not Windows NT,
+rem the second works on Windows NT but not the other MS OSs.
+rem > _.tmp
+copy nul: _.tmp > nul:
+copy /B %1+_.tmp %2
+erase _.tmp
+goto x
+:ne
+copy /B %1 %2
+:x
diff --git a/gs/src/devs.mak b/gs/src/devs.mak
index 6e69d663e..d6b092e44 100644
--- a/gs/src/devs.mak
+++ b/gs/src/devs.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -87,14 +87,15 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# x11mono X Windows masquerading as a black-and-white device
# Printers:
# * cljet5 H-P Color LaserJet 5/5M
-# * cljet5c H-P Color LaserJet 5/5M contone.
# + deskjet H-P DeskJet and DeskJet Plus
# djet500 H-P DeskJet 500; use -r600 for DJ 600 series
+# + fs600 Kyocera FS-600 (600 dpi)
# + laserjet H-P LaserJet
# + ljet2p H-P LaserJet IId/IIp/III* with TIFF compression
# + ljet3 H-P LaserJet III* with Delta Row compression
# + ljet3d H-P LaserJet IIID with duplex capability
# + ljet4 H-P LaserJet 4 (defaults to 600 dpi)
+# + ljet4d H-P LaserJet 4 (defaults to 600 dpi) with duplex
# + ljetplus H-P LaserJet Plus
# lj5mono H-P LaserJet 5 & 6 family (PCL XL), bitmap:
# see below for restrictions & advice
@@ -105,9 +106,9 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# (pxlmono) H-P black-and-white PCL XL printers (LaserJet 5 and 6 family)
# (pxlcolor) H-P color PCL XL printers (none available yet)
# Fax file format:
-# ****** NOTE: all of these drivers adjust the page size to match
+# ****** NOTE: all of these drivers normally adjust the page size to match
# ****** one of the three CCITT standard sizes (U.S. letter with A4 width,
-# ****** A4, or B4).
+# ****** A4, or B4). To suppress this, use
# faxg3 Group 3 fax, with EOLs but no header or EOD
# faxg32d Group 3 2-D fax, with EOLs but no header or EOD
# faxg4 Group 4 fax, with EOLs but no header or EOD
@@ -126,6 +127,8 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# bitrgb Plain bits, RGB
# bitcmyk Plain bits, CMYK
# bmpmono Monochrome MS Windows .BMP file format
+# bmpsep1 Separated 1-bit CMYK .BMP file format, primarily for testing
+# bmpsep8 Separated 8-bit CMYK .BMP file format, primarily for testing
# bmp16 4-bit (EGA/VGA) .BMP file format
# bmp256 8-bit (256-color) .BMP file format
# bmp16m 24-bit .BMP file format
@@ -156,6 +159,8 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# ppmraw Portable Pixmap (raw format) (RGB)
# pkm Portable inKmap (plain format) (4-bit CMYK => RGB)
# pkmraw Portable inKmap (raw format) (4-bit CMYK => RGB)
+# pksm Portable Separated map (plain format) (4-bit CMYK => 4 pages)
+# pksmraw Portable Separated map (raw format) (4-bit CMYK => 4 pages)
# * plan9bm Plan 9 bitmap format
# pngmono Monochrome Portable Network Graphics (PNG)
# pnggray 8-bit gray Portable Network Graphics (PNG)
@@ -170,7 +175,7 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# tifflzw TIFF LZW (tag = 5) (monochrome)
# tiffpack TIFF PackBits (tag = 32773) (monochrome)
-# Note that MS Windows-specific drivers are defined in msdevs.mak, not here,
+# Note that MS Windows-specific drivers are defined in pcwin.mak, not here,
# because they have special compilation requirements that require defining
# parameter macros not relevant to other platforms; the OS/2-specific
# drivers are there too, because they share some definitions.
@@ -191,7 +196,7 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# As noted in gs.mak, DEVICE_DEVS and DEVICE_DEVS1..15 select the devices
# that should be included in a given configuration. By convention, these
-# are used as follows. Each of these must be limited to about 10 devices
+# are used as follows. Each of these must be limited to about 6 devices
# so as not to overflow the 120 character limit on MS-DOS command lines.
# DEVICE_DEVS - the default device, and any display devices.
# DEVICE_DEVS1 - additional display devices if needed.
@@ -209,6 +214,11 @@ GDEV=$(AK) $(ECHOGS_XE) $(GDEVH)
# DEVICE_DEVS13 - PNG file formats.
# DEVICE_DEVS14 - CGM, JPEG, and MIFF file formats.
# DEVICE_DEVS15 - high-level (PostScript and PDF) file formats.
+# DEVICE_DEVS16 - (overflow for PC platforms)
+# DEVICE_DEVS17 - (ditto)
+# DEVICE_DEVS18 - (ditto)
+# DEVICE_DEVS19 - (ditto)
+# DEVICE_DEVS20 - (ditto)
# Feel free to disregard this convention if it gets in your way.
# If you want to add a new device driver, the examples below should be
@@ -222,6 +232,8 @@ PDEVH=$(AK) $(gdevprn_h)
# Define the header files for device drivers. Every header file used by
# more than one device driver family must be listed here.
gdev8bcm_h=$(GLSRC)gdev8bcm.h
+gdevcbjc_h=$(GLSRC)gdevcbjc.h $(stream_h)
+gdevdcrd_h=$(GLSRC)gdevdcrd.h
gdevpccm_h=$(GLSRC)gdevpccm.h
gdevpcfb_h=$(GLSRC)gdevpcfb.h $(dos__h)
gdevpcl_h=$(GLSRC)gdevpcl.h
@@ -230,15 +242,27 @@ gdevsvga_h=$(GLSRC)gdevsvga.h
###### ----------------------- Device support ----------------------- ######
# Implement dynamic color management for 8-bit mapped color displays.
-$(GLOBJ)gdev8bcm.$(OBJ): $(GLSRC)gdev8bcm.c $(AK)\
+$(GLOBJ)gdev8bcm.$(OBJ) : $(GLSRC)gdev8bcm.c $(AK)\
$(gx_h) $(gxdevice_h) $(gdev8bcm_h)
$(GLCC) $(GLO_)gdev8bcm.$(OBJ) $(C_) $(GLSRC)gdev8bcm.c
# PC display color mapping
-$(GLOBJ)gdevpccm.$(OBJ): $(GLSRC)gdevpccm.c $(AK)\
+$(GLOBJ)gdevpccm.$(OBJ) : $(GLSRC)gdevpccm.c $(AK)\
$(gx_h) $(gsmatrix_h) $(gxdevice_h) $(gdevpccm_h)
$(GLCC) $(GLO_)gdevpccm.$(OBJ) $(C_) $(GLSRC)gdevpccm.c
+# Generate Canon BJC command sequences.
+$(GLOBJ)gdevcbjc.$(OBJ) : $(GLSRC)gdevcbjc.c $(AK)\
+ $(std_h) $(stream_h) $(gdevcbjc_h)
+ $(GLCC) $(GLO_)gdevcbjc.$(OBJ) $(C_) $(GLSRC)gdevcbjc.c
+
+# Provide a sample device CRD.
+$(GLOBJ)gdevdcrd.$(OBJ) : $(GLSRC)gdevdcrd.c $(AK)\
+ $(math__h) $(memory__h) $(string__h)\
+ $(gscrd_h) $(gscrdp_h) $(gserrors_h) $(gsparam_h) $(gscspace_h)\
+ $(gx_h) $(gxdevcli_h) $(gdevdcrd_h)
+ $(GLCC) $(GLO_)gdevdcrd.$(OBJ) $(C_) $(GLSRC)gdevdcrd.c
+
###### ------------------- MS-DOS display devices ------------------- ######
# There are really only three drivers: an EGA/VGA driver (4 bit-planes,
@@ -250,36 +274,37 @@ $(GLOBJ)gdevpccm.$(OBJ): $(GLSRC)gdevpccm.c $(AK)\
# The shared MS-DOS makefile defines PCFBASM as either gdevegaa.$(OBJ)
# or an empty string.
-$(GLOBJ)gdevegaa.$(OBJ): $(GLSRC)gdevegaa.asm
+$(GLOBJ)gdevegaa.$(OBJ) : $(GLSRC)gdevegaa.asm
$(GLCC) $(GLO_)gdevegaa.$(OBJ) $(C_) $(GLSRC)gdevegaa.c
+EGAVGA_DOS=$(GLOBJ)gdevevga.$(OBJ) $(GLOBJ)gdevpcfb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) $(PCFBASM)
+EGAVGA_SCO=$(GLOBJ)gdevsco.$(OBJ) $(GLOBJ)gdevpcfb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) $(PCFBASM)
# NOTE: for direct frame buffer addressing under SCO Unix or Xenix,
-# change gdevevga to gdevsco in the following line. Also, since
-# SCO's /bin/as does not support the "out" instructions, you must build
-# the gnu assembler and have it on your path as "as".
-EGAVGA=$(GLOBJ)gdevevga.$(OBJ) $(GLOBJ)gdevpcfb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) $(PCFBASM)
-#EGAVGA=$(GLOBJ)gdevsco.$(OBJ) $(GLOBJ)gdevpcfb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) $(PCFBASM)
+# change DOS to SCO in the following line. Also, since SCO's /bin/as
+# does not support the "out" instructions, you must build the GNU
+# assembler and have it on your path as "as".
+EGAVGA=$(EGAVGA_DOS)
#**************** $(CCD) gdevevga.c
-$(GLOBJ)gdevevga.$(OBJ): $(GLSRC)gdevevga.c $(GDEV) $(memory__h) $(gdevpcfb_h)
+$(GLOBJ)gdevevga.$(OBJ) : $(GLSRC)gdevevga.c $(GDEV) $(memory__h) $(gdevpcfb_h)
$(GLCC) $(GLO_)gdevevga.$(OBJ) $(C_) $(GLSRC)gdevevga.c
-$(GLOBJ)gdevsco.$(OBJ): $(GLSRC)gdevsco.c $(GDEV) $(memory__h) $(gdevpcfb_h)
+$(GLOBJ)gdevsco.$(OBJ) : $(GLSRC)gdevsco.c $(GDEV) $(memory__h) $(gdevpcfb_h)
$(GLCC) $(GLO_)gdevsco.$(OBJ) $(C_) $(GLSRC)gdevsco.c
# Common code for MS-DOS and SCO.
#**************** $(CCD) gdevpcfb.c
-$(GLOBJ)gdevpcfb.$(OBJ): $(GLSRC)gdevpcfb.c $(GDEV) $(memory__h) $(gconfigv_h)\
+$(GLOBJ)gdevpcfb.$(OBJ) : $(GLSRC)gdevpcfb.c $(GDEV) $(memory__h) $(gconfigv_h)\
$(gdevpccm_h) $(gdevpcfb_h) $(gsparam_h)
$(GLCC) $(GLO_)gdevpcfb.$(OBJ) $(C_) $(GLSRC)gdevpcfb.c
# The EGA/VGA family includes EGA and VGA. Many SuperVGAs in 800x600,
# 16-color mode can share the same code; see the next section below.
-ega.dev: $(EGAVGA)
- $(SETDEV) ega $(EGAVGA)
+$(DD)ega.dev : $(EGAVGA)
+ $(SETDEV) $(DD)ega $(EGAVGA)
-vga.dev: $(EGAVGA)
- $(SETDEV) vga $(EGAVGA)
+$(DD)vga.dev : $(EGAVGA)
+ $(SETDEV) $(DD)vga $(EGAVGA)
### ------------------------- SuperVGA displays ------------------------ ###
@@ -290,8 +315,8 @@ vga.dev: $(EGAVGA)
# where NNN is the display mode in decimal. See Use.htm for the modes
# for some popular display chipsets.
-svga16.dev: $(EGAVGA)
- $(SETDEV) svga16 $(EGAVGA)
+$(DD)svga16.dev : $(EGAVGA)
+ $(SETDEV) $(DD)svga16 $(EGAVGA)
# More capable SuperVGAs have a wide variety of slightly differing
# interfaces, so we need a separate driver for each one.
@@ -299,40 +324,40 @@ svga16.dev: $(EGAVGA)
SVGA=$(GLOBJ)gdevsvga.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) $(PCFBASM)
#**************** $(CCD) gdevsvga.c
-$(GLOBJ)gdevsvga.$(OBJ): $(GLSRC)gdevsvga.c $(GDEV) $(memory__h) $(gconfigv_h)\
+$(GLOBJ)gdevsvga.$(OBJ) : $(GLSRC)gdevsvga.c $(GDEV) $(memory__h) $(gconfigv_h)\
$(gsparam_h) $(gxarith_h) $(gdevpccm_h) $(gdevpcfb_h) $(gdevsvga_h)
$(GLCC) $(GLO_)gdevsvga.$(OBJ) $(C_) $(GLSRC)gdevsvga.c
# The SuperVGA family includes: Avance Logic Inc., ATI Wonder, S3,
# Trident, Tseng ET3000/4000, and VESA.
-ali.dev: $(SVGA)
- $(SETDEV) ali $(SVGA)
+$(DD)ali.dev : $(SVGA)
+ $(SETDEV) $(DD)ali $(SVGA)
-atiw.dev: $(SVGA)
- $(SETDEV) atiw $(SVGA)
+$(DD)atiw.dev : $(SVGA)
+ $(SETDEV) $(DD)atiw $(SVGA)
-cirr.dev: $(SVGA)
- $(SETDEV) cirr $(SVGA)
+$(DD)cirr.dev : $(SVGA)
+ $(SETDEV) $(DD)cirr $(SVGA)
-tseng.dev: $(SVGA)
- $(SETDEV) tseng $(SVGA)
+$(DD)tseng.dev : $(SVGA)
+ $(SETDEV) $(DD)tseng $(SVGA)
-tvga.dev: $(SVGA)
- $(SETDEV) tvga $(SVGA)
+$(DD)tvga.dev : $(SVGA)
+ $(SETDEV) $(DD)tvga $(SVGA)
-vesa.dev: $(SVGA)
- $(SETDEV) vesa $(SVGA)
+$(DD)vesa.dev : $(SVGA)
+ $(SETDEV) $(DD)vesa $(SVGA)
# The S3 driver doesn't share much code with the others.
s3vga_=$(GLOBJ)gdevs3ga.$(OBJ) $(GLOBJ)gdevsvga.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-s3vga.dev: $(SVGA) $(s3vga_)
- $(SETDEV) s3vga $(SVGA)
- $(ADDMOD) s3vga -obj $(s3vga_)
+$(DD)s3vga.dev : $(SVGA) $(s3vga_)
+ $(SETDEV) $(DD)s3vga $(SVGA)
+ $(ADDMOD) $(DD)s3vga -obj $(s3vga_)
#**************** $(CCD) gdevs3ga.c
-$(GLOBJ)gdevs3ga.$(OBJ): $(GLSRC)gdevs3ga.c $(GDEV) $(gdevpcfb_h) $(gdevsvga_h)
+$(GLOBJ)gdevs3ga.$(OBJ) : $(GLSRC)gdevs3ga.c $(GDEV) $(gdevpcfb_h) $(gdevsvga_h)
$(GLCC) $(GLO_)gdevs3ga.$(OBJ) $(C_) $(GLSRC)gdevs3ga.c
###### ----------------------- Other displays ------------------------ ######
@@ -345,45 +370,58 @@ $(GLOBJ)gdevs3ga.$(OBJ): $(GLSRC)gdevs3ga.c $(GDEV) $(gdevpcfb_h) $(gdevsvga_h)
### Erik Talvola (talvola@gnu.ai.mit.edu). ###
lvga256_=$(GLOBJ)gdevl256.$(OBJ)
-lvga256.dev: $(lvga256_)
- $(SETDEV) lvga256 $(lvga256_)
- $(ADDMOD) lvga256 -lib vga vgagl
+$(DD)lvga256.dev : $(lvga256_)
+ $(SETDEV) $(DD)lvga256 $(lvga256_)
+ $(ADDMOD) $(DD)lvga256 -lib vga vgagl
-$(GLOBJ)gdevl256.$(OBJ): $(GLSRC)gdevl256.c $(GDEV)
+$(GLOBJ)gdevl256.$(OBJ) : $(GLSRC)gdevl256.c $(GDEV)
$(GLCC) $(GLO_)gdevl256.$(OBJ) $(C_) $(GLSRC)gdevl256.c
vgalib_=$(GLOBJ)gdevvglb.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-vgalib.dev: $(vgalib_)
- $(SETDEV2) vgalib $(vgalib_)
- $(ADDMOD) vgalib -lib vga
+$(DD)vgalib.dev : $(vgalib_)
+ $(SETDEV2) $(DD)vgalib $(vgalib_)
+ $(ADDMOD) $(DD)vgalib -lib vga
-$(GLOBJ)gdevvglb.$(OBJ): $(GLSRC)gdevvglb.c $(GDEV) $(gdevpccm_h) $(gsparam_h)
+$(GLOBJ)gdevvglb.$(OBJ) : $(GLSRC)gdevvglb.c $(GDEV) $(gdevpccm_h) $(gsparam_h)
$(GLCC) $(GLO_)gdevvglb.$(OBJ) $(C_) $(GLSRC)gdevvglb.c
### -------------------------- The X11 device -------------------------- ###
-# Aladdin Enterprises does not support Ghostview. For more information
-# about Ghostview, please contact Tim Theisen (ghostview@cs.wisc.edu).
+# Please note that Aladdin Enterprises does not support Ghostview.
+# For more information about Ghostview, please contact Tim Theisen
+# (ghostview@cs.wisc.edu).
-gdevx_h=$(GLSRC)gdevx.h
+x__h=$(GLSRC)x_.h
+gdevxcmp_h=$(GLSRC)gdevxcmp.h
+gdevx_h=$(GLSRC)gdevx.h $(gdevxcmp_h)
# See the main makefile for the definition of XLIBS.
-x11_=$(GLOBJ)gdevx.$(OBJ) $(GLOBJ)gdevxini.$(OBJ) $(GLOBJ)gdevxxf.$(OBJ) $(GLOBJ)gdevemap.$(OBJ)
-x11.dev: $(x11_)
- $(SETDEV2) x11 $(x11_)
- $(ADDMOD) x11 -lib $(XLIBS)
+x11_=$(GLOBJ)gdevx.$(OBJ) $(GLOBJ)gdevxcmp.$(OBJ) $(GLOBJ)gdevxini.$(OBJ) $(GLOBJ)gdevxres.$(OBJ) $(GLOBJ)gdevxxf.$(OBJ) $(GLOBJ)gdevemap.$(OBJ)
+$(DD)x11_.dev : $(x11_)
+ $(SETMOD) $(DD)x11_ $(x11_)
+ $(ADDMOD) $(DD)x11_ -lib $(XLIBS)
+
+$(DD)x11.dev : $(DD)x11_.dev
+ $(SETDEV2) $(DD)x11 -include $(DD)x11_
# See the main makefile for the definition of XINCLUDE.
-GDEVX=$(GDEV) $(GLSRC)x_.h $(GLSRC)gdevx.h $(MAKEFILE)
-$(GLOBJ)gdevx.$(OBJ): $(GLSRC)gdevx.c $(GDEVX) $(math__h) $(memory__h)\
+GDEVX=$(GDEV) $(x__h) $(gdevx_h) $(TOP_MAKEFILES)
+$(GLOBJ)gdevx.$(OBJ) : $(GLSRC)gdevx.c $(GDEVX) $(math__h) $(memory__h)\
$(gscoord_h) $(gsdevice_h) $(gsiparm2_h) $(gsmatrix_h) $(gsparam_h)\
$(gxgetbit_h) $(gxiparam_h) $(gxpath_h)
$(GLCC) $(XINCLUDE) $(GLO_)gdevx.$(OBJ) $(C_) $(GLSRC)gdevx.c
-$(GLOBJ)gdevxini.$(OBJ): $(GLSRC)gdevxini.c $(GDEVX) $(math__h) $(memory__h) $(gserrors_h)
+$(GLOBJ)gdevxcmp.$(OBJ) : $(GLSRC)gdevxcmp.c $(GDEVX) $(math__h)
+ $(GLCC) $(XINCLUDE) $(GLO_)gdevxcmp.$(OBJ) $(C_) $(GLSRC)gdevxcmp.c
+
+$(GLOBJ)gdevxini.$(OBJ) : $(GLSRC)gdevxini.c $(GDEVX) $(memory__h)\
+ $(gserrors_h)
$(GLCC) $(XINCLUDE) $(GLO_)gdevxini.$(OBJ) $(C_) $(GLSRC)gdevxini.c
-$(GLOBJ)gdevxxf.$(OBJ): $(GLSRC)gdevxxf.c $(GDEVX) $(math__h) $(memory__h)\
+$(GLOBJ)gdevxres.$(OBJ) : $(GLSRC)gdevxres.c $(GDEVX) $(std_h)
+ $(GLCC) $(XINCLUDE) $(GLO_)gdevxres.$(OBJ) $(C_) $(GLSRC)gdevxres.c
+
+$(GLOBJ)gdevxxf.$(OBJ) : $(GLSRC)gdevxxf.c $(GDEVX) $(math__h) $(memory__h)\
$(gsstruct_h) $(gsutil_h) $(gxxfont_h)
$(GLCC) $(XINCLUDE) $(GLO_)gdevxxf.$(OBJ) $(C_) $(GLSRC)gdevxxf.c
@@ -396,40 +434,37 @@ $(GLOBJ)gdevxxf.$(OBJ): $(GLSRC)gdevxxf.c $(GDEVX) $(math__h) $(memory__h)\
# x11gray2 pretends to be a 2-bit gray-scale device.
# x11gray4 pretends to be a 4-bit gray-scale device.
# x11mono pretends to be a black-and-white device.
-x11alt_=$(x11_) $(GLOBJ)gdevxalt.$(OBJ)
-x11alpha.dev: $(x11alt_)
- $(SETDEV2) x11alpha $(x11alt_)
- $(ADDMOD) x11alpha -lib $(XLIBS)
+x11alt_=$(GLOBJ)gdevxalt.$(OBJ) $(GLOBJ)gdevdcrd.$(OBJ)
+$(DD)x11alt_.dev : $(x11alt_) $(DD)x11_.dev
+ $(SETMOD) $(DD)x11alt_ $(x11alt_)
+ $(ADDMOD) $(DD)x11alt_ -include $(DD)x11_
+
+$(DD)x11alpha.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11alpha -include $(DD)x11alt_
-x11cmyk.dev: $(x11alt_)
- $(SETDEV2) x11cmyk $(x11alt_)
- $(ADDMOD) x11cmyk -lib $(XLIBS)
+$(DD)x11cmyk.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11cmyk -include $(DD)x11alt_
-x11cmyk2.dev: $(x11alt_)
- $(SETDEV2) x11cmyk2 $(x11alt_)
- $(ADDMOD) x11cmyk2 -lib $(XLIBS)
+$(DD)x11cmyk2.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11cmyk2 -include $(DD)x11alt_
-x11cmyk4.dev: $(x11alt_)
- $(SETDEV2) x11cmyk4 $(x11alt_)
- $(ADDMOD) x11cmyk4 -lib $(XLIBS)
+$(DD)x11cmyk4.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11cmyk4 -include $(DD)x11alt_
-x11cmyk8.dev: $(x11alt_)
- $(SETDEV2) x11cmyk8 $(x11alt_)
- $(ADDMOD) x11cmyk8 -lib $(XLIBS)
+$(DD)x11cmyk8.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11cmyk8 -include $(DD)x11alt_
-x11gray2.dev: $(x11alt_)
- $(SETDEV2) x11gray2 $(x11alt_)
- $(ADDMOD) x11gray2 -lib $(XLIBS)
+$(DD)x11gray2.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11gray2 -include $(DD)x11alt_
-x11gray4.dev: $(x11alt_)
- $(SETDEV2) x11gray4 $(x11alt_)
- $(ADDMOD) x11gray4 -lib $(XLIBS)
+$(DD)x11gray4.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11gray4 -include $(DD)x11alt_
-x11mono.dev: $(x11alt_)
- $(SETDEV2) x11mono $(x11alt_)
- $(ADDMOD) x11mono -lib $(XLIBS)
+$(DD)x11mono.dev : $(DD)x11alt_.dev
+ $(SETDEV2) $(DD)x11mono -include $(DD)x11alt_
-$(GLOBJ)gdevxalt.$(OBJ): $(GLSRC)gdevxalt.c $(GDEVX) $(math__h) $(memory__h) $(gsparam_h)
+$(GLOBJ)gdevxalt.$(OBJ) : $(GLSRC)gdevxalt.c $(GDEVX) $(math__h) $(memory__h)\
+ $(gsdevice_h) $(gsparam_h) $(gdevdcrd_h)
$(GLCC) $(XINCLUDE) $(GLO_)gdevxalt.$(OBJ) $(C_) $(GLSRC)gdevxalt.c
###### --------------- Memory-buffered printer devices --------------- ######
@@ -441,72 +476,89 @@ $(GLOBJ)gdevxalt.$(OBJ): $(GLSRC)gdevxalt.c $(GDEVX) $(math__h) $(memory__h) $(g
### with at least 1.5 Mb of memory. 150 DPI only requires .5 Mb.
### Note that the lj4dith driver is included with the H-P color printer
### drivers below.
+### For questions about the fs600 device, please contact ###
+### Peter Schildmann (peter.schildmann@etechnik.uni-rostock.de). ###
HPPCL=$(GLOBJ)gdevpcl.$(OBJ)
HPMONO=$(GLOBJ)gdevdjet.$(OBJ) $(HPPCL)
-$(GLOBJ)gdevpcl.$(OBJ): $(GLSRC)gdevpcl.c $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdevpcl.$(OBJ) : $(GLSRC)gdevpcl.c $(PDEVH) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevpcl.$(OBJ) $(C_) $(GLSRC)gdevpcl.c
-$(GLOBJ)gdevdjet.$(OBJ): $(GLSRC)gdevdjet.c $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdevdjet.$(OBJ) : $(GLSRC)gdevdjet.c $(PDEVH) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevdjet.$(OBJ) $(C_) $(GLSRC)gdevdjet.c
-deskjet.dev: $(HPMONO) page.dev
- $(SETPDEV2) deskjet $(HPMONO)
+$(DD)deskjet.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)deskjet $(HPMONO)
-djet500.dev: $(HPMONO) page.dev
- $(SETPDEV2) djet500 $(HPMONO)
+$(DD)djet500.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)djet500 $(HPMONO)
-laserjet.dev: $(HPMONO) page.dev
- $(SETPDEV2) laserjet $(HPMONO)
+$(DD)fs600.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)fs600 $(HPMONO)
-ljetplus.dev: $(HPMONO) page.dev
- $(SETPDEV2) ljetplus $(HPMONO)
+$(DD)laserjet.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)laserjet $(HPMONO)
+
+$(DD)ljetplus.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljetplus $(HPMONO)
### Selecting ljet2p provides TIFF (mode 2) compression on LaserJet III,
### IIIp, IIId, IIIsi, IId, and IIp.
-ljet2p.dev: $(HPMONO) page.dev
- $(SETPDEV2) ljet2p $(HPMONO)
+$(DD)ljet2p.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljet2p $(HPMONO)
### Selecting ljet3 provides Delta Row (mode 3) compression on LaserJet III,
### IIIp, IIId, IIIsi.
-ljet3.dev: $(HPMONO) page.dev
- $(SETPDEV2) ljet3 $(HPMONO)
+$(DD)ljet3.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljet3 $(HPMONO)
### Selecting ljet3d also provides duplex printing capability.
-ljet3d.dev: $(HPMONO) page.dev
- $(SETPDEV2) ljet3d $(HPMONO)
+$(DD)ljet3d.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljet3d $(HPMONO)
+
+### Selecting ljet4 or ljet4d also provides Delta Row compression on
+### LaserJet IV series.
-### Selecting ljet4 also provides Delta Row compression on LaserJet IV series.
+$(DD)ljet4.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljet4 $(HPMONO)
-ljet4.dev: $(HPMONO) page.dev
- $(SETPDEV2) ljet4 $(HPMONO)
+$(DD)ljet4d.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ljet4d $(HPMONO)
-lp2563.dev: $(HPMONO) page.dev
- $(SETPDEV2) lp2563 $(HPMONO)
+$(DD)lp2563.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)lp2563 $(HPMONO)
-oce9050.dev: $(HPMONO) page.dev
- $(SETPDEV2) oce9050 $(HPMONO)
+$(DD)oce9050.dev : $(HPMONO) $(GLD)page.dev
+ $(SETPDEV2) $(DD)oce9050 $(HPMONO)
### -------------------- The H-P Color LaserJet 5/5M -------------------- ###
-cljet5c_=$(GLOBJ)gdevcljc.$(OBJ) $(HPPCL)
-cljet5c.dev: $(cljet5c_) page.dev
- $(SETPDEV) cljet5c $(cljet5c_)
-
-$(GLOBJ)gdevcljc.$(OBJ): $(GLSRC)gdevcljc.c $(math__h) $(PDEVH) $(gdevpcl_h)
- $(GLCC) $(GLO_)gdevcljc.$(OBJ) $(C_) $(GLSRC)gdevcljc.c
+### There are two different drivers for this device: a general one that is
+### claimed not to work very well, and a more restricted one that does work.
+### For questions about the cljet5 (more general) driver, contact
+### Jan Stoeckenius <jan@orimp.com>
+### For questions about the cljet5c (simple) driver, contact
+### Henry Stiles <henrys@meerkat.dimensional.com>
cljet5_=$(GLOBJ)gdevclj.$(OBJ) $(HPPCL)
-cljet5.dev: $(cljet5_) page.dev
- $(SETPDEV) cljet5 $(cljet5_)
+$(DD)cljet5.dev : $(cljet5_) $(GLD)page.dev
+ $(SETPDEV) $(DD)cljet5 $(cljet5_)
-$(GLOBJ)gdevclj.$(OBJ): $(GLSRC)gdevclj.c $(math__h) $(PDEVH) $(gdevpcl_h)
+$(GLOBJ)gdevclj.$(OBJ) : $(GLSRC)gdevclj.c $(math__h) $(PDEVH)\
+ $(gx_h) $(gsparam_h) $(gdevpcl_h)
$(GLCC) $(GLO_)gdevclj.$(OBJ) $(C_) $(GLSRC)gdevclj.c
+cljet5c_=$(GLOBJ)gdevcljc.$(OBJ) $(HPPCL)
+$(DD)cljet5c.dev : $(cljet5c_) $(GLD)page.dev
+ $(SETPDEV) $(DD)cljet5c $(cljet5c_)
+
+$(GLOBJ)gdevcljc.$(OBJ) : $(GLSRC)gdevcljc.c $(math__h) $(PDEVH) $(gdevpcl_h)
+ $(GLCC) $(GLO_)gdevcljc.$(OBJ) $(C_) $(GLSRC)gdevcljc.c
+
### ------------------ The H-P LaserJet 5 and 6 devices ----------------- ###
### These drivers use H-P's new PCL XL printer language, like H-P's
@@ -522,13 +574,13 @@ gdevpxen_h=$(GLSRC)gdevpxen.h
gdevpxop_h=$(GLSRC)gdevpxop.h
ljet5_=$(GLOBJ)gdevlj56.$(OBJ) $(HPPCL)
-lj5mono.dev: $(ljet5_) page.dev
- $(SETPDEV) lj5mono $(ljet5_)
+$(DD)lj5mono.dev : $(ljet5_) $(GLD)page.dev
+ $(SETPDEV) $(DD)lj5mono $(ljet5_)
-lj5gray.dev: $(ljet5_) page.dev
- $(SETPDEV) lj5gray $(ljet5_)
+$(DD)lj5gray.dev : $(ljet5_) $(GLD)page.dev
+ $(SETPDEV) $(DD)lj5gray $(ljet5_)
-$(GLOBJ)gdevlj56.$(OBJ): $(GLSRC)gdevlj56.c $(PDEVH) $(gdevpcl_h)\
+$(GLOBJ)gdevlj56.$(OBJ) : $(GLSRC)gdevlj56.c $(PDEVH) $(gdevpcl_h)\
$(gdevpxat_h) $(gdevpxen_h) $(gdevpxop_h)
$(GLCC) $(GLO_)gdevlj56.$(OBJ) $(C_) $(GLSRC)gdevlj56.c
@@ -544,41 +596,42 @@ psdf_1=$(GLOBJ)gdevpsde.$(OBJ) $(GLOBJ)gdevpsdf.$(OBJ) $(GLOBJ)gdevpsdi.$(OBJ)
psdf_2=$(GLOBJ)gdevpsdp.$(OBJ) $(GLOBJ)gdevpsds.$(OBJ) $(GLOBJ)gdevpstr.$(OBJ)
psdf_3=$(GLOBJ)scfparam.$(OBJ) $(GLOBJ)sdcparam.$(OBJ) $(GLOBJ)sdeparam.$(OBJ)
psdf_=$(psdf_1) $(psdf_2) $(psdf_3)
-psdf.dev: $(ECHOGS_XE) $(psdf_) vector.dev
- $(SETMOD) psdf $(psdf_1)
- $(ADDMOD) psdf -obj $(psdf_2)
- $(ADDMOD) psdf -obj $(psdf_3)
- $(ADDMOD) psdf -include vector
+$(DD)psdf.dev : $(ECHOGS_XE) $(psdf_) $(GLD)vector.dev $(GLD)pngp.dev
+ $(SETMOD) $(DD)psdf $(psdf_1)
+ $(ADDMOD) $(DD)psdf -obj $(psdf_2)
+ $(ADDMOD) $(DD)psdf -obj $(psdf_3)
+ $(ADDMOD) $(DD)psdf -include $(GLD)vector $(GLD)pngp
-$(GLOBJ)gdevpsde.$(OBJ): $(GLSRC)gdevpsde.c $(GXERR) $(memory__h)\
+$(GLOBJ)gdevpsde.$(OBJ) : $(GLSRC)gdevpsde.c $(GXERR) $(memory__h)\
$(gsccode_h) $(gsmatrix_h) $(gxfixed_h) $(gxfont_h) $(gxfont1_h)\
$(stream_h)\
$(gdevpsdf_h) $(gdevpstr_h)
$(GLCC) $(GLO_)gdevpsde.$(OBJ) $(C_) $(GLSRC)gdevpsde.c
-$(GLOBJ)gdevpsdf.$(OBJ): $(GLSRC)gdevpsdf.c $(GXERR) $(string__h)\
+$(GLOBJ)gdevpsdf.$(OBJ) : $(GLSRC)gdevpsdf.c $(GXERR) $(string__h)\
$(sa85x_h) $(scanchar_h) $(scfx_h) $(sstring_h) $(strimpl_h)\
$(gdevpsdf_h) $(gdevpstr_h)
$(GLCC) $(GLO_)gdevpsdf.$(OBJ) $(C_) $(GLSRC)gdevpsdf.c
-$(GLOBJ)gdevpsdi.$(OBJ): $(GLSRC)gdevpsdi.c $(GXERR) $(math__h)\
+$(GLOBJ)gdevpsdi.$(OBJ) : $(GLSRC)gdevpsdi.c $(GXERR)\
+ $(math__h) $(jpeglib__h)\
$(gscspace_h)\
$(scfx_h) $(sdct_h) $(slzwx_h) $(srlx_h) $(spngpx_h)\
$(strimpl_h) $(szlibx_h)\
- $(gdevpsdf_h) $(gdevpsds_h)\
- $(GLGEN)jpeglib.h
+ $(gdevpsdf_h) $(gdevpsds_h)
$(GLJCC) $(GLO_)gdevpsdi.$(OBJ) $(C_) $(GLSRC)gdevpsdi.c
-$(GLOBJ)gdevpsdp.$(OBJ): $(GLSRC)gdevpsdp.c $(GDEVH) $(string__h)\
+$(GLOBJ)gdevpsdp.$(OBJ) : $(GLSRC)gdevpsdp.c $(GDEVH)\
+ $(string__h) $(jpeglib__h)\
$(scfx_h) $(sdct_h) $(slzwx_h) $(srlx_h) $(strimpl_h) $(szlibx_h)\
- $(gdevpsdf_h) $(gdevpstr_h) $(GLGEN)jpeglib.h
+ $(gsparamx_h) $(gdevpsdf_h) $(gdevpstr_h)
$(GLJCC) $(GLO_)gdevpsdp.$(OBJ) $(C_) $(GLSRC)gdevpsdp.c
-$(GLOBJ)gdevpsds.$(OBJ): $(GLSRC)gdevpsds.c $(GX) $(memory__h)\
+$(GLOBJ)gdevpsds.$(OBJ) : $(GLSRC)gdevpsds.c $(GX) $(memory__h)\
$(gdevpsds_h) $(gserrors_h) $(gxdcconv_h)
$(GLCC) $(GLO_)gdevpsds.$(OBJ) $(C_) $(GLSRC)gdevpsds.c
-$(GLOBJ)gdevpstr.$(OBJ): $(GLSRC)gdevpstr.c\
+$(GLOBJ)gdevpstr.$(OBJ) : $(GLSRC)gdevpstr.c\
$(math__h) $(stdio__h) $(string__h)\
$(gdevpstr_h) $(stream_h)
$(GLCC) $(GLO_)gdevpstr.$(OBJ) $(C_) $(GLSRC)gdevpstr.c
@@ -586,19 +639,19 @@ $(GLOBJ)gdevpstr.$(OBJ): $(GLSRC)gdevpstr.c\
# PostScript and EPS writers
pswrite_=$(GLOBJ)gdevps.$(OBJ) $(GLOBJ)scantab.$(OBJ) $(GLOBJ)sfilter2.$(OBJ)
-epswrite.dev: $(ECHOGS_XE) $(pswrite_) psdf.dev
- $(SETDEV2) epswrite $(pswrite_)
- $(ADDMOD) epswrite -include psdf
+$(DD)epswrite.dev : $(ECHOGS_XE) $(pswrite_) $(GLD)psdf.dev
+ $(SETDEV2) $(DD)epswrite $(pswrite_)
+ $(ADDMOD) $(DD)epswrite -include $(GLD)psdf
-pswrite.dev: $(ECHOGS_XE) $(pswrite_) psdf.dev
- $(SETDEV2) pswrite $(pswrite_)
- $(ADDMOD) pswrite -include psdf
+$(DD)pswrite.dev : $(ECHOGS_XE) $(pswrite_) $(GLD)psdf.dev
+ $(SETDEV2) $(DD)pswrite $(pswrite_)
+ $(ADDMOD) $(DD)pswrite -include $(GLD)psdf
-$(GLOBJ)gdevps.$(OBJ): $(GLSRC)gdevps.c $(GDEV)\
+$(GLOBJ)gdevps.$(OBJ) : $(GLSRC)gdevps.c $(GDEV)\
$(math__h) $(memory__h) $(time__h)\
$(gscdefs_h) $(gscspace_h) $(gsline_h) $(gsparam_h) $(gsiparam_h) $(gsmatrix_h)\
- $(gxdcolor_h) $(gzpath_h)\
- $(sa85x_h) $(strimpl_h)\
+ $(gxdcolor_h) $(gxpath_h)\
+ $(sa85x_h) $(sstring_h) $(strimpl_h)\
$(gdevpsdf_h) $(gdevpstr_h)
$(GLCC) $(GLO_)gdevps.$(OBJ) $(C_) $(GLSRC)gdevps.c
@@ -608,23 +661,25 @@ $(GLOBJ)gdevps.$(OBJ): $(GLSRC)gdevps.c $(GDEV)\
pdfwrite1_=$(GLOBJ)gdevpdf.$(OBJ) $(GLOBJ)gdevpdfd.$(OBJ) $(GLOBJ)gdevpdfi.$(OBJ)
pdfwrite2_=$(GLOBJ)gdevpdfm.$(OBJ) $(GLOBJ)gdevpdfo.$(OBJ) $(GLOBJ)gdevpdfp.$(OBJ)
-pdfwrite3_=$(GLOBJ)gdevpdft.$(OBJ) $(GLOBJ)gsflip.$(OBJ)
+pdfwrite3_=$(GLOBJ)gdevpdft.$(OBJ) $(GLOBJ)gsflip.$(OBJ) $(GLOBJ)gsparamx.$(OBJ)
pdfwrite4_=$(GLOBJ)scantab.$(OBJ) $(GLOBJ)sfilter2.$(OBJ) $(GLOBJ)sstring.$(OBJ)
pdfwrite_=$(pdfwrite1_) $(pdfwrite2_) $(pdfwrite3_) $(pdfwrite4_)
-pdfwrite.dev: $(ECHOGS_XE) $(pdfwrite_)\
- cmyklib.dev cfe.dev dcte.dev lzwe.dev rle.dev szlibe.dev psdf.dev
- $(SETDEV2) pdfwrite $(pdfwrite1_)
- $(ADDMOD) pdfwrite $(pdfwrite2_)
- $(ADDMOD) pdfwrite $(pdfwrite3_)
- $(ADDMOD) pdfwrite $(pdfwrite4_)
- $(ADDMOD) pdfwrite -ps gs_pdfwr
- $(ADDMOD) pdfwrite -include cmyklib cfe dcte lzwe rle szlibe psdf
+$(DD)pdfwrite.dev : $(ECHOGS_XE) $(pdfwrite_)\
+ $(GLD)cmyklib.dev $(GLD)cfe.dev $(GLD)dcte.dev $(GLD)lzwe.dev $(GLD)rle.dev $(GLD)szlibe.dev $(GLD)psdf.dev
+ $(SETDEV2) $(DD)pdfwrite $(pdfwrite1_)
+ $(ADDMOD) $(DD)pdfwrite $(pdfwrite2_)
+ $(ADDMOD) $(DD)pdfwrite $(pdfwrite3_)
+ $(ADDMOD) $(DD)pdfwrite $(pdfwrite4_)
+ $(ADDMOD) $(DD)pdfwrite -ps gs_pdfwr
+ $(ADDMOD) $(DD)pdfwrite -include $(GLD)cmyklib $(GLD)cfe $(GLD)dcte
+ $(ADDMOD) $(DD)pdfwrite -include $(GLD)lzwe $(GLD)rle $(GLD)szlibe
+ $(ADDMOD) $(DD)pdfwrite -include $(GLD)psdf
gdevpdfx_h=$(GLSRC)gdevpdfx.h\
$(gsparam_h) $(gxdevice_h) $(gxline_h) $(stream_h)\
$(gdevpsdf_h) $(gdevpstr_h)
-$(GLOBJ)gdevpdf.$(OBJ): $(GLSRC)gdevpdf.c $(GDEVH)\
+$(GLOBJ)gdevpdf.$(OBJ) : $(GLSRC)gdevpdf.c $(GDEVH)\
$(math__h) $(memory__h) $(string__h) $(time__h)\
$(gp_h)\
$(gdevpdfx_h) $(gscdefs_h)\
@@ -633,37 +688,37 @@ $(GLOBJ)gdevpdf.$(OBJ): $(GLSRC)gdevpdf.c $(GDEVH)\
$(scanchar_h) $(scfx_h) $(slzwx_h) $(sstring_h) $(strimpl_h) $(szlibx_h)
$(GLCC) $(GLO_)gdevpdf.$(OBJ) $(C_) $(GLSRC)gdevpdf.c
-$(GLOBJ)gdevpdfd.$(OBJ): $(GLSRC)gdevpdfd.c $(math__h)\
+$(GLOBJ)gdevpdfd.$(OBJ) : $(GLSRC)gdevpdfd.c $(math__h)\
$(gdevpdfx_h)\
$(gx_h) $(gxdevice_h) $(gxfixed_h) $(gxistate_h) $(gxpaint_h)\
$(gzcpath_h) $(gzpath_h)
$(GLCC) $(GLO_)gdevpdfd.$(OBJ) $(C_) $(GLSRC)gdevpdfd.c
-$(GLOBJ)gdevpdfi.$(OBJ): $(GLSRC)gdevpdfi.c\
- $(math__h) $(memory__h) $(string__h) $(gx_h)\
+$(GLOBJ)gdevpdfi.$(OBJ) : $(GLSRC)gdevpdfi.c\
+ $(math__h) $(memory__h) $(string__h) $(jpeglib__h) $(gx_h)\
$(gdevpdfx_h)\
$(gscie_h) $(gscolor2_h) $(gserrors_h) $(gsflip_h)\
$(gxcspace_h) $(gxistate_h)\
$(sa85x_h) $(scfx_h) $(sdct_h) $(slzwx_h) $(spngpx_h) $(srlx_h) $(strimpl_h)\
- $(szlibx_h)\
- $(GLGEN)jpeglib.h
+ $(szlibx_h)
$(GLJCC) $(GLO_)gdevpdfi.$(OBJ) $(C_) $(GLSRC)gdevpdfi.c
-$(GLOBJ)gdevpdfm.$(OBJ): $(GLSRC)gdevpdfm.c\
+$(GLOBJ)gdevpdfm.$(OBJ) : $(GLSRC)gdevpdfm.c\
$(memory__h) $(string__h) $(gx_h)\
$(gdevpdfx_h) $(gserrors_h) $(gsutil_h) $(scanchar_h)
$(GLCC) $(GLO_)gdevpdfm.$(OBJ) $(C_) $(GLSRC)gdevpdfm.c
-$(GLOBJ)gdevpdfo.$(OBJ): $(GLSRC)gdevpdfo.c $(memory__h) $(gx_h)\
+$(GLOBJ)gdevpdfo.$(OBJ) : $(GLSRC)gdevpdfo.c $(memory__h) $(string__h)\
+ $(gx_h)\
$(gdevpdfx_h) $(gserrors_h) $(gsutil_h)\
$(sstring_h) $(strimpl_h)
$(GLCC) $(GLO_)gdevpdfo.$(OBJ) $(C_) $(GLSRC)gdevpdfo.c
-$(GLOBJ)gdevpdfp.$(OBJ): $(GLSRC)gdevpdfp.c $(gx_h)\
- $(gdevpdfx_h) $(gserrors_h)
+$(GLOBJ)gdevpdfp.$(OBJ) : $(GLSRC)gdevpdfp.c $(gx_h)\
+ $(gdevpdfx_h) $(gserrors_h) $(gsparamx_h)
$(GLCC) $(GLO_)gdevpdfp.$(OBJ) $(C_) $(GLSRC)gdevpdfp.c
-$(GLOBJ)gdevpdft.$(OBJ): $(GLSRC)gdevpdft.c\
+$(GLOBJ)gdevpdft.$(OBJ) : $(GLSRC)gdevpdft.c\
$(math__h) $(memory__h) $(string__h) $(gx_h)\
$(gdevpdfx_h) $(gserrors_h) $(gsutil_h)\
$(scommon_h)
@@ -672,15 +727,15 @@ $(GLOBJ)gdevpdft.$(OBJ): $(GLSRC)gdevpdft.c\
# High-level PCL XL writer
pxl_=$(GLOBJ)gdevpx.$(OBJ)
-pxlmono.dev: $(pxl_) $(GDEV) vector.dev
- $(SETDEV2) pxlmono $(pxl_)
- $(ADDMOD) pxlmono -include vector
+$(DD)pxlmono.dev : $(pxl_) $(GDEV) $(GLD)vector.dev
+ $(SETDEV2) $(DD)pxlmono $(pxl_)
+ $(ADDMOD) $(DD)pxlmono -include $(GLD)vector
-pxlcolor.dev: $(pxl_) $(GDEV) vector.dev
- $(SETDEV2) pxlcolor $(pxl_)
- $(ADDMOD) pxlcolor -include vector
+$(DD)pxlcolor.dev : $(pxl_) $(GDEV) $(GLD)vector.dev
+ $(SETDEV2) $(DD)pxlcolor $(pxl_)
+ $(ADDMOD) $(DD)pxlcolor -include $(GLD)vector
-$(GLOBJ)gdevpx.$(OBJ): $(GLSRC)gdevpx.c\
+$(GLOBJ)gdevpx.$(OBJ) : $(GLSRC)gdevpx.c\
$(math__h) $(memory__h) $(string__h)\
$(gx_h) $(gsccolor_h) $(gsdcolor_h) $(gserrors_h)\
$(gxcspace_h) $(gxdevice_h) $(gxpath_h)\
@@ -692,19 +747,25 @@ $(GLOBJ)gdevpx.$(OBJ): $(GLSRC)gdevpx.c\
### --------------------- The "plain bits" devices ---------------------- ###
-bit_=$(GLOBJ)gdevbit.$(OBJ)
+# This device also exercises the driver CRD facilities, which is why it
+# needs some additional files.
+
+bit_=$(GLOBJ)gdevbit.$(OBJ) $(GLOBJ)gdevdcrd.$(OBJ)
-bit.dev: $(bit_) page.dev
- $(SETPDEV2) bit $(bit_)
+$(DD)bit.dev : $(bit_) $(GLD)page.dev $(GLD)cielib.dev
+ $(SETPDEV2) $(DD)bit $(bit_)
+ $(ADDMOD) $(DD)bit -include $(GLD)cielib
-bitrgb.dev: $(bit_) page.dev
- $(SETPDEV2) bitrgb $(bit_)
+$(DD)bitrgb.dev : $(bit_) $(GLD)page.dev $(GLD)cielib.dev
+ $(SETPDEV2) $(DD)bitrgb $(bit_)
+ $(ADDMOD) $(DD)bitrgb -include $(GLD)cielib
-bitcmyk.dev: $(bit_) page.dev
- $(SETPDEV2) bitcmyk $(bit_)
+$(DD)bitcmyk.dev : $(bit_) $(GLD)page.dev $(GLD)cielib.dev
+ $(SETPDEV2) $(DD)bitcmyk $(bit_)
+ $(ADDMOD) $(DD)bitcmyk -include $(GLD)cielib
-$(GLOBJ)gdevbit.$(OBJ): $(GLSRC)gdevbit.c $(PDEVH)\
- $(gscrd_h) $(gscrdp_h) $(gsparam_h) $(gxlum_h)
+$(GLOBJ)gdevbit.$(OBJ) : $(GLSRC)gdevbit.c $(PDEVH) $(math__h)\
+ $(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gsparam_h) $(gxlum_h)
$(GLCC) $(GLO_)gdevbit.$(OBJ) $(C_) $(GLSRC)gdevbit.c
### ------------------------- .BMP file formats ------------------------- ###
@@ -713,23 +774,29 @@ gdevbmp_h=$(GLSRC)gdevbmp.h
bmp_=$(GLOBJ)gdevbmp.$(OBJ) $(GLOBJ)gdevbmpc.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-$(GLOBJ)gdevbmp.$(OBJ): $(GLSRC)gdevbmp.c $(PDEVH) $(gdevbmp_h) $(gdevpccm_h)
+$(GLOBJ)gdevbmp.$(OBJ) : $(GLSRC)gdevbmp.c $(PDEVH) $(gdevbmp_h) $(gdevpccm_h)
$(GLCC) $(GLO_)gdevbmp.$(OBJ) $(C_) $(GLSRC)gdevbmp.c
-$(GLOBJ)gdevbmpc.$(OBJ): $(GLSRC)gdevbmpc.c $(PDEVH) $(gdevbmp_h)
+$(GLOBJ)gdevbmpc.$(OBJ) : $(GLSRC)gdevbmpc.c $(PDEVH) $(gdevbmp_h)
$(GLCC) $(GLO_)gdevbmpc.$(OBJ) $(C_) $(GLSRC)gdevbmpc.c
-bmpmono.dev: $(bmp_) page.dev
- $(SETPDEV) bmpmono $(bmp_)
+$(DD)bmpmono.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmpmono $(bmp_)
-bmp16.dev: $(bmp_) page.dev
- $(SETPDEV) bmp16 $(bmp_)
+$(DD)bmpsep1.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmpsep1 $(bmp_)
-bmp256.dev: $(bmp_) page.dev
- $(SETPDEV) bmp256 $(bmp_)
+$(DD)bmpsep8.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmpsep8 $(bmp_)
-bmp16m.dev: $(bmp_) page.dev
- $(SETPDEV) bmp16m $(bmp_)
+$(DD)bmp16.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmp16 $(bmp_)
+
+$(DD)bmp256.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmp256 $(bmp_)
+
+$(DD)bmp16m.dev : $(bmp_) $(GLD)page.dev
+ $(SETPDEV) $(DD)bmp16m $(bmp_)
$(DD)bmp32b.dev : $(bmp_) $(GLD)page.dev
$(SETPDEV) $(DD)bmp32b $(bmp_)
@@ -738,25 +805,34 @@ $(DD)bmp32b.dev : $(bmp_) $(GLD)page.dev
bmpa_=$(GLOBJ)gdevbmpa.$(OBJ) $(GLOBJ)gdevbmpc.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-$(GLOBJ)gdevbmpa.$(OBJ): $(GLSRC)gdevbmpa.c $(AK) $(stdio__h)\
- $(gdevbmp_h) $(gdevprna_h) $(gdevpccm_h) $(gserrors_h) $(gpsync_h)
+$(GLOBJ)gdevbmpa.$(OBJ) : $(GLSRC)gdevbmpa.c $(AK) $(stdio__h)\
+ $(gdevbmp_h) $(gdevprna_h) $(gdevpccm_h) $(gdevppla_h)\
+ $(gserrors_h) $(gpsync_h)
$(GLCC) $(GLO_)gdevbmpa.$(OBJ) $(C_) $(GLSRC)gdevbmpa.c
-bmpamono.dev: $(bmpa_) page.dev async.dev
- $(SETPDEV) bmpamono $(bmpa_)
- $(ADDMOD) bmpamono -include async
+$(DD)bmpamono.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpamono $(bmpa_)
+ $(ADDMOD) $(DD)bmpamono -include $(GLD)async
+
+$(DD)bmpasep1.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpasep1 $(bmpa_)
+ $(ADDMOD) $(DD)bmpasep1 -include $(GLD)async
-bmpa16.dev: $(bmpa_) page.dev async.dev
- $(SETPDEV) bmpa16 $(bmpa_)
- $(ADDMOD) bmpa16 -include async
+$(DD)bmpasep8.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpasep8 $(bmpa_)
+ $(ADDMOD) $(DD)bmpasep8 -include $(GLD)async
-bmpa256.dev: $(bmpa_) page.dev async.dev
- $(SETPDEV) bmpa256 $(bmpa_)
- $(ADDMOD) bmpa256 -include async
+$(DD)bmpa16.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpa16 $(bmpa_)
+ $(ADDMOD) $(DD)bmpa16 -include $(GLD)async
-bmpa16m.dev: $(bmpa_) page.dev async.dev
- $(SETPDEV) bmpa16m $(bmpa_)
- $(ADDMOD) bmpa16m -include async
+$(DD)bmpa256.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpa256 $(bmpa_)
+ $(ADDMOD) $(DD)bmpa256 -include $(GLD)async
+
+$(DD)bmpa16m.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
+ $(SETPDEV) $(DD)bmpa16m $(bmpa_)
+ $(ADDMOD) $(DD)bmpa16m -include $(GLD)async
$(DD)bmpa32b.dev : $(bmpa_) $(GLD)page.dev $(GLD)async.dev
$(SETPDEV) $(DD)bmpa32b $(bmpa_)
@@ -772,39 +848,40 @@ cgm_=$(GLOBJ)gdevcgm.$(OBJ) $(GLOBJ)gdevcgml.$(OBJ)
gdevcgml_h=$(GLSRC)gdevcgml.h
gdevcgmx_h=$(GLSRC)gdevcgmx.h $(gdevcgml_h)
-$(GLOBJ)gdevcgm.$(OBJ): $(GLSRC)gdevcgm.c $(GDEV) $(memory__h)\
+$(GLOBJ)gdevcgm.$(OBJ) : $(GLSRC)gdevcgm.c $(GDEV) $(memory__h)\
$(gsparam_h) $(gdevpccm_h) $(gdevcgml_h)
$(GLCC) $(GLO_)gdevcgm.$(OBJ) $(C_) $(GLSRC)gdevcgm.c
-$(GLOBJ)gdevcgml.$(OBJ): $(GLSRC)gdevcgml.c $(memory__h) $(stdio__h)\
+$(GLOBJ)gdevcgml.$(OBJ) : $(GLSRC)gdevcgml.c $(memory__h) $(stdio__h)\
$(gdevcgmx_h)
$(GLCC) $(GLO_)gdevcgml.$(OBJ) $(C_) $(GLSRC)gdevcgml.c
-cgmmono.dev: $(cgm_)
- $(SETDEV) cgmmono $(cgm_)
+$(DD)cgmmono.dev : $(cgm_)
+ $(SETDEV) $(DD)cgmmono $(cgm_)
-cgm8.dev: $(cgm_)
- $(SETDEV) cgm8 $(cgm_)
+$(DD)cgm8.dev : $(cgm_)
+ $(SETDEV) $(DD)cgm8 $(cgm_)
-cgm24.dev: $(cgm_)
- $(SETDEV) cgm24 $(cgm_)
+$(DD)cgm24.dev : $(cgm_)
+ $(SETDEV) $(DD)cgm24 $(cgm_)
### ------------------------- JPEG file format ------------------------- ###
jpeg_=$(GLOBJ)gdevjpeg.$(OBJ)
# RGB output
-jpeg.dev: $(jpeg_) sdcte.dev page.dev
- $(SETPDEV2) jpeg $(jpeg_)
- $(ADDMOD) jpeg -include sdcte
+$(DD)jpeg.dev : $(jpeg_) $(GLD)sdcte.dev $(GLD)page.dev
+ $(SETPDEV2) $(DD)jpeg $(jpeg_)
+ $(ADDMOD) $(DD)jpeg -include $(GLD)sdcte
# Gray output
-jpeggray.dev: $(jpeg_) sdcte.dev page.dev
- $(SETPDEV2) jpeggray $(jpeg_)
- $(ADDMOD) jpeggray -include sdcte
+$(DD)jpeggray.dev : $(jpeg_) $(GLD)sdcte.dev $(GLD)page.dev
+ $(SETPDEV2) $(DD)jpeggray $(jpeg_)
+ $(ADDMOD) $(DD)jpeggray -include $(GLD)sdcte
-$(GLOBJ)gdevjpeg.$(OBJ): $(GLSRC)gdevjpeg.c $(stdio__h) $(PDEVH)\
- $(sdct_h) $(sjpeg_h) $(stream_h) $(strimpl_h) $(GLGEN)jpeglib.h
+$(GLOBJ)gdevjpeg.$(OBJ) : $(GLSRC)gdevjpeg.c $(PDEVH)\
+ $(stdio__h) $(jpeglib__h)\
+ $(sdct_h) $(sjpeg_h) $(stream_h) $(strimpl_h)
$(GLCC) $(GLO_)gdevjpeg.$(OBJ) $(C_) $(GLSRC)gdevjpeg.c
### ------------------------- MIFF file format ------------------------- ###
@@ -813,139 +890,151 @@ $(GLOBJ)gdevjpeg.$(OBJ): $(GLSRC)gdevjpeg.c $(stdio__h) $(PDEVH)\
miff_=$(GLOBJ)gdevmiff.$(OBJ)
-miff24.dev: $(miff_) page.dev
- $(SETPDEV) miff24 $(miff_)
+$(DD)miff24.dev : $(miff_) $(GLD)page.dev
+ $(SETPDEV) $(DD)miff24 $(miff_)
-$(GLOBJ)gdevmiff.$(OBJ): $(GLSRC)gdevmiff.c $(PDEVH)
+$(GLOBJ)gdevmiff.$(OBJ) : $(GLSRC)gdevmiff.c $(PDEVH)
$(GLCC) $(GLO_)gdevmiff.$(OBJ) $(C_) $(GLSRC)gdevmiff.c
### ------------------------- PCX file formats ------------------------- ###
pcx_=$(GLOBJ)gdevpcx.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-$(GLOBJ)gdevpcx.$(OBJ): $(GLSRC)gdevpcx.c $(PDEVH) $(gdevpccm_h) $(gxlum_h)
+$(GLOBJ)gdevpcx.$(OBJ) : $(GLSRC)gdevpcx.c $(PDEVH) $(gdevpccm_h) $(gxlum_h)
$(GLCC) $(GLO_)gdevpcx.$(OBJ) $(C_) $(GLSRC)gdevpcx.c
-pcxmono.dev: $(pcx_) page.dev
- $(SETPDEV2) pcxmono $(pcx_)
+$(DD)pcxmono.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcxmono $(pcx_)
-pcxgray.dev: $(pcx_) page.dev
- $(SETPDEV2) pcxgray $(pcx_)
+$(DD)pcxgray.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcxgray $(pcx_)
-pcx16.dev: $(pcx_) page.dev
- $(SETPDEV2) pcx16 $(pcx_)
+$(DD)pcx16.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcx16 $(pcx_)
-pcx256.dev: $(pcx_) page.dev
- $(SETPDEV2) pcx256 $(pcx_)
+$(DD)pcx256.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcx256 $(pcx_)
-pcx24b.dev: $(pcx_) page.dev
- $(SETPDEV2) pcx24b $(pcx_)
+$(DD)pcx24b.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcx24b $(pcx_)
-pcxcmyk.dev: $(pcx_) page.dev
- $(SETPDEV2) pcxcmyk $(pcx_)
+$(DD)pcxcmyk.dev : $(pcx_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pcxcmyk $(pcx_)
# The 2-up PCX device is here only as an example, and for testing.
-pcx2up.dev: $(LIB_MAK) $(ECHOGS_XE) gdevp2up.$(OBJ) page.dev pcx256.dev
- $(SETPDEV) pcx2up $(GLOBJ)gdevp2up.$(OBJ)
- $(ADDMOD) pcx2up -include pcx256
+$(DD)pcx2up.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLOBJ)gdevp2up.$(OBJ) $(GLD)page.dev $(DD)pcx256.dev
+ $(SETPDEV) $(DD)pcx2up $(GLOBJ)gdevp2up.$(OBJ)
+ $(ADDMOD) $(DD)pcx2up -include $(DD)pcx256
-$(GLOBJ)gdevp2up.$(OBJ): $(GLSRC)gdevp2up.c $(AK)\
+$(GLOBJ)gdevp2up.$(OBJ) : $(GLSRC)gdevp2up.c $(AK)\
$(gdevpccm_h) $(gdevprn_h) $(gxclpage_h)
$(GLCC) $(GLO_)gdevp2up.$(OBJ) $(C_) $(GLSRC)gdevp2up.c
### ------------------- Portable Bitmap file formats ------------------- ###
### For more information, see the pbm(5), pgm(5), and ppm(5) man pages. ###
-pxm_=$(GLOBJ)gdevpbm.$(OBJ)
+pxm_=$(GLOBJ)gdevpbm.$(OBJ) $(GLOBJ)gdevppla.$(OBJ) $(GLOBJ)gdevmpla.$(OBJ)
-$(GLOBJ)gdevpbm.$(OBJ): $(GLSRC)gdevpbm.c $(PDEVH) $(gscdefs_h) $(gxlum_h)
+$(GLOBJ)gdevpbm.$(OBJ) : $(GLSRC)gdevpbm.c $(PDEVH)\
+ $(gdevmpla_h) $(gdevplnx_h) $(gdevppla_h)\
+ $(gscdefs_h) $(gxgetbit_h) $(gxlum_h)
$(GLCC) $(GLO_)gdevpbm.$(OBJ) $(C_) $(GLSRC)gdevpbm.c
### Portable Bitmap (PBM, plain or raw format, magic numbers "P1" or "P4")
-pbm.dev: $(pxm_) page.dev
- $(SETPDEV2) pbm $(pxm_)
+$(DD)pbm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pbm $(pxm_)
-pbmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) pbmraw $(pxm_)
+$(DD)pbmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pbmraw $(pxm_)
### Portable Graymap (PGM, plain or raw format, magic numbers "P2" or "P5")
-pgm.dev: $(pxm_) page.dev
- $(SETPDEV2) pgm $(pxm_)
+$(DD)pgm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pgm $(pxm_)
-pgmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) pgmraw $(pxm_)
+$(DD)pgmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pgmraw $(pxm_)
# PGM with automatic optimization to PBM if this is possible.
-pgnm.dev: $(pxm_) page.dev
- $(SETPDEV2) pgnm $(pxm_)
+$(DD)pgnm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pgnm $(pxm_)
-pgnmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) pgnmraw $(pxm_)
+$(DD)pgnmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pgnmraw $(pxm_)
### Portable Pixmap (PPM, plain or raw format, magic numbers "P3" or "P6")
-ppm.dev: $(pxm_) page.dev
- $(SETPDEV2) ppm $(pxm_)
+$(DD)ppm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ppm $(pxm_)
-ppmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) ppmraw $(pxm_)
+$(DD)ppmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)ppmraw $(pxm_)
# PPM with automatic optimization to PGM or PBM if possible.
-pnm.dev: $(pxm_) page.dev
- $(SETPDEV2) pnm $(pxm_)
+$(DD)pnm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pnm $(pxm_)
-pnmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) pnmraw $(pxm_)
+$(DD)pnmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pnmraw $(pxm_)
### Portable inKmap (CMYK internally, converted to PPM=RGB at output time)
-pkm.dev: $(pxm_) page.dev
- $(SETPDEV2) pkm $(pxm_)
+$(DD)pkm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pkm $(pxm_)
+
+$(DD)pkmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pkmraw $(pxm_)
+
+### Portable Separated map (CMYK internally, produces 4 monobit pages)
-pkmraw.dev: $(pxm_) page.dev
- $(SETPDEV2) pkmraw $(pxm_)
+$(DD)pksm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pksm $(pxm_)
+
+$(DD)pksmraw.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pksmraw $(pxm_)
### Plan 9 bitmap format
-plan9bm.dev: $(pxm_) page.dev
- $(SETPDEV2) plan9bm $(pxm_)
+$(DD)plan9bm.dev : $(pxm_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)plan9bm $(pxm_)
### --------------- Portable Network Graphics file format --------------- ###
### Requires libpng 0.81 and zlib 0.95 (or more recent versions). ###
### See libpng.mak and zlib.mak for more details. ###
+png__h=$(GLSRC)png_.h $(MAKEFILE)
+
png_=$(GLOBJ)gdevpng.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
libpng_dev=$(PNGGENDIR)$(D)libpng.dev
png_i_=-include $(PNGGENDIR)$(D)libpng
-$(GLOBJ)gdevpng.$(OBJ): $(GLSRC)gdevpng.c\
- $(gdevprn_h) $(gdevpccm_h) $(gscdefs_h) $(PNGSRC)png.h
- $(CC_) $(I_)$(GLI_) $(II)$(PI_)$(_I) $(GLF_) $(GLO_)gdevpng.$(OBJ) $(C_) $(GLSRC)gdevpng.c
+$(GLOBJ)gdevpng.$(OBJ) : $(GLSRC)gdevpng.c\
+ $(gdevprn_h) $(gdevpccm_h) $(gscdefs_h) $(png__h)
+ $(CC_) $(I_)$(GLI_) $(II)$(PI_)$(_I) $(PCF_) $(GLF_) $(GLO_)gdevpng.$(OBJ) $(C_) $(GLSRC)gdevpng.c
-pngmono.dev: $(libpng_dev) $(png_) page.dev
- $(SETPDEV2) pngmono $(png_)
- $(ADDMOD) pngmono $(png_i_)
+$(DD)pngmono.dev : $(libpng_dev) $(png_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pngmono $(png_)
+ $(ADDMOD) $(DD)pngmono $(png_i_)
-pnggray.dev: $(libpng_dev) $(png_) page.dev
- $(SETPDEV2) pnggray $(png_)
- $(ADDMOD) pnggray $(png_i_)
+$(DD)pnggray.dev : $(libpng_dev) $(png_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)pnggray $(png_)
+ $(ADDMOD) $(DD)pnggray $(png_i_)
-png16.dev: $(libpng_dev) $(png_) page.dev
- $(SETPDEV2) png16 $(png_)
- $(ADDMOD) png16 $(png_i_)
+$(DD)png16.dev : $(libpng_dev) $(png_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)png16 $(png_)
+ $(ADDMOD) $(DD)png16 $(png_i_)
-png256.dev: $(libpng_dev) $(png_) page.dev
- $(SETPDEV2) png256 $(png_)
- $(ADDMOD) png256 $(png_i_)
+$(DD)png256.dev : $(libpng_dev) $(png_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)png256 $(png_)
+ $(ADDMOD) $(DD)png256 $(png_i_)
-png16m.dev: $(libpng_dev) $(png_) page.dev
- $(SETPDEV2) png16m $(png_)
- $(ADDMOD) png16m $(png_i_)
+$(DD)png16m.dev : $(libpng_dev) $(png_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)png16m $(png_)
+ $(ADDMOD) $(DD)png16m $(png_i_)
### ---------------------- PostScript image format ---------------------- ###
### These devices make it possible to print monochrome Level 2 files on a ###
@@ -957,100 +1046,106 @@ png16m.dev: $(libpng_dev) $(png_) page.dev
psim_=$(GLOBJ)gdevpsim.$(OBJ)
-$(GLOBJ)gdevpsim.$(OBJ): $(GLSRC)gdevpsim.c $(PDEVH)
+$(GLOBJ)gdevpsim.$(OBJ) : $(GLSRC)gdevpsim.c $(PDEVH)
$(GLCC) $(GLO_)gdevpsim.$(OBJ) $(C_) $(GLSRC)gdevpsim.c
-psmono.dev: $(psim_) page.dev
- $(SETPDEV2) psmono $(psim_)
+$(DD)psmono.dev : $(psim_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)psmono $(psim_)
-psgray.dev: $(psim_) page.dev
- $(SETPDEV2) psgray $(psim_)
+$(DD)psgray.dev : $(psim_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)psgray $(psim_)
# RGB, Level 2 output
psci_=$(GLOBJ)gdevpsci.$(OBJ)
-$(GLOBJ)gdevpsci.$(OBJ): $(GLSRC)gdevpsci.c $(PDEVH)\
+$(GLOBJ)gdevpsci.$(OBJ) : $(GLSRC)gdevpsci.c $(PDEVH)\
$(srlx_h) $(stream_h) $(strimpl_h)
$(GLCC) $(GLO_)gdevpsci.$(OBJ) $(C_) $(GLSRC)gdevpsci.c
-psrgb.dev: $(psci_) page.dev
- $(SETPDEV2) psrgb $(psci_)
+$(DD)psrgb.dev : $(psci_) $(GLD)page.dev
+ $(SETPDEV2) $(DD)psrgb $(psci_)
### -------------------- Plain or TIFF fax encoding --------------------- ###
### Use -sDEVICE=tiffg3 or tiffg4 and ###
### -r204x98 for low resolution output, or ###
### -r204x196 for high resolution output ###
-### These drivers recognize 3 page sizes: letter, A4, and B4. ###
+
+# By default, these drivers recognize 3 page sizes -- (U.S.) letter, A4, and
+# B4 -- and adjust the page width to the nearest legal value for real fax
+# systems (1728 or 2048 pixels). To suppress this, set the device parameter
+# AdjustWidth to 0 (e.g., -dAdjustWidth=0 on the command line).
gdevtifs_h=$(GLSRC)gdevtifs.h
tfax_=$(GLOBJ)gdevtfax.$(OBJ)
-tfax.dev: $(tfax_) cfe.dev lzwe.dev rle.dev tiffs.dev
- $(SETMOD) tfax $(tfax_)
- $(ADDMOD) tfax -include cfe lzwe rle tiffs
+$(DD)tfax.dev : $(tfax_) $(GLD)cfe.dev $(GLD)lzwe.dev $(GLD)rle.dev $(DD)tiffs.dev
+ $(SETMOD) $(DD)tfax $(tfax_)
+ $(ADDMOD) $(DD)tfax -include $(GLD)cfe $(GLD)lzwe $(GLD)rle
+ $(ADDMOD) $(DD)tfax -include $(DD)tiffs
-$(GLOBJ)gdevtfax.$(OBJ): $(GLSRC)gdevtfax.c $(PDEVH)\
+$(GLOBJ)gdevtfax.$(OBJ) : $(GLSRC)gdevtfax.c $(PDEVH)\
$(gdevtifs_h) $(scfx_h) $(slzwx_h) $(srlx_h) $(strimpl_h)
$(GLCC) $(GLO_)gdevtfax.$(OBJ) $(C_) $(GLSRC)gdevtfax.c
### Plain G3/G4 fax with no header
-faxg3.dev: tfax.dev
- $(SETDEV2) faxg3 -include tfax
+$(DD)faxg3.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)faxg3 -include $(DD)tfax
-faxg32d.dev: tfax.dev
- $(SETDEV2) faxg32d -include tfax
+$(DD)faxg32d.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)faxg32d -include $(DD)tfax
-faxg4.dev: tfax.dev
- $(SETDEV2) faxg4 -include tfax
+$(DD)faxg4.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)faxg4 -include $(DD)tfax
### ---------------------------- TIFF formats --------------------------- ###
tiffs_=$(GLOBJ)gdevtifs.$(OBJ)
-tiffs.dev: $(tiffs_) page.dev
- $(SETMOD) tiffs $(tiffs_)
- $(ADDMOD) tiffs -include page
+$(DD)tiffs.dev : $(tiffs_) $(GLD)page.dev
+ $(SETMOD) $(DD)tiffs $(tiffs_)
+ $(ADDMOD) $(DD)tiffs -include $(GLD)page
-$(GLOBJ)gdevtifs.$(OBJ): $(GLSRC)gdevtifs.c $(PDEVH) $(stdio__h) $(time__h)\
+$(GLOBJ)gdevtifs.$(OBJ) : $(GLSRC)gdevtifs.c $(PDEVH) $(stdio__h) $(time__h)\
$(gdevtifs_h) $(gscdefs_h) $(gstypes_h)
$(GLCC) $(GLO_)gdevtifs.$(OBJ) $(C_) $(GLSRC)gdevtifs.c
# Black & white, G3/G4 fax
+# NOTE: see under faxg* above regarding page width adjustment.
-tiffcrle.dev: tfax.dev
- $(SETDEV2) tiffcrle -include tfax
+$(DD)tiffcrle.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tiffcrle -include $(DD)tfax
-tiffg3.dev: tfax.dev
- $(SETDEV2) tiffg3 -include tfax
+$(DD)tiffg3.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tiffg3 -include $(DD)tfax
-tiffg32d.dev: tfax.dev
- $(SETDEV2) tiffg32d -include tfax
+$(DD)tiffg32d.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tiffg32d -include $(DD)tfax
-tiffg4.dev: tfax.dev
- $(SETDEV2) tiffg4 -include tfax
+$(DD)tiffg4.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tiffg4 -include $(DD)tfax
# Black & white, LZW compression
-tifflzw.dev: tfax.dev
- $(SETDEV2) tifflzw -include tfax
+$(DD)tifflzw.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tifflzw -include $(DD)tfax
# Black & white, PackBits compression
-tiffpack.dev: tfax.dev
- $(SETDEV2) tiffpack -include tfax
+$(DD)tiffpack.dev : $(DD)tfax.dev
+ $(SETDEV2) $(DD)tiffpack -include $(DD)tfax
# RGB, no compression
tiffrgb_=$(GLOBJ)gdevtfnx.$(OBJ)
-tiff12nc.dev: $(tiffrgb_) tiffs.dev
- $(SETPDEV2) tiff12nc $(tiffrgb_)
- $(ADDMOD) tiff12nc -include tiffs
+$(DD)tiff12nc.dev : $(tiffrgb_) $(DD)tiffs.dev
+ $(SETPDEV2) $(DD)tiff12nc $(tiffrgb_)
+ $(ADDMOD) $(DD)tiff12nc -include $(DD)tiffs
-tiff24nc.dev: $(tiffrgb_) tiffs.dev
- $(SETPDEV2) tiff24nc $(tiffrgb_)
- $(ADDMOD) tiff24nc -include tiffs
+$(DD)tiff24nc.dev : $(tiffrgb_) $(DD)tiffs.dev
+ $(SETPDEV2) $(DD)tiff24nc $(tiffrgb_)
+ $(ADDMOD) $(DD)tiff24nc -include $(DD)tiffs
-$(GLOBJ)gdevtfnx.$(OBJ): $(GLSRC)gdevtfnx.c $(PDEVH) $(gdevtifs_h)
+$(GLOBJ)gdevtfnx.$(OBJ) : $(GLSRC)gdevtfnx.c $(PDEVH) $(gdevtifs_h)
$(GLCC) $(GLO_)gdevtfnx.$(OBJ) $(C_) $(GLSRC)gdevtfnx.c
diff --git a/gs/src/dpmainc.c b/gs/src/dpmainc.c
index 117062e93..2203078c1 100644
--- a/gs/src/dpmainc.c
+++ b/gs/src/dpmainc.c
@@ -31,6 +31,7 @@
#include "gscdefs.h"
#define GS_REVISION gs_revision
#include "gsdll.h"
+#include "gsdllos2.h"
#define MAXSTR 256
const char *szDllName = "GSDLL2.DLL";
diff --git a/gs/src/dstack.h b/gs/src/dstack.h
index 194642aec..1f089e128 100644
--- a/gs/src/dstack.h
+++ b/gs/src/dstack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,10 +23,10 @@
# define dstack_INCLUDED
#include "idstack.h"
+#include "icstate.h" /* for access to dict_stack */
-/* Define the (currently static) dictionary stack instance. */
-extern dict_stack_t idict_stack;
-
+/* Define the dictionary stack instance for operators. */
+#define idict_stack (i_ctx_p->dict_stack)
#define d_stack (idict_stack.stack)
/* Define the interpreter-specific versions of the generic dstack API. */
@@ -73,158 +73,236 @@ extern dict_stack_t idict_stack;
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 <D,M,F,E> 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 <P,E> 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 = <ptr to invalid value, 0>
- begin(D):
- *++dsp = <D, {0...}, D->F, ++Epoch>
- set D->F
- value = lookup(K):
- if K->E >= dsp->E
- value = *K->P
- else
- do lookup as usual
- *K = <ptr to value, Epoch>
- 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
+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)
+ context switch
+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 N has a pointer N.V that has one of 3 states:
+ - This name has no definitions.
+ - This name has exactly one definition, in systemdict or userdict.
+ In this case, N.V 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).
+
+Cheap shallow binding
+---------------------
+
+We define a global event counter, Event. Each name N has, in addition to
+its value pointer N.V, an associated event stamp N.E. The invariant we want
+to preserve is that N.V is valid iff N.E >= Event. Similarly, each entry B
+on the dictionary stack has, in addition to its dictionary B.D, an
+associated event stamp B.E which is the value of Event when the entry was
+made, and a slow lookup flag B.F which indicates whether any slow lookups
+have been done since the entry was made. Finally, each dictionary D has a
+counter D.N which indicates how many times it appears on the dictionary
+stack. (The counter is an optional feature of this scheme: if we omit it,
+we consider it to have a permanently non-zero value in all dictionaries.)
+
+The idea of the B.F flag is for 'end' to be able to reset Event, rather than
+incrementing it, if no names had their stamp set to the incremented Event
+value. This in turn prevents the mass invalidation of the N.V cache that
+would otherwise occur.
+
+Here are the implementations of the various operations with respect to the
+cache. We preserve the current scheme for fast implementation of 'def',
+which we don't discuss here.
+
+Initialize:
+ Event = 0
+When creating a name:
+ N.V = NULL, N.E = 0
+begin(D):
+ create B with B.D = D, B.E = Event, B.F = false
+ ++Event
+end(B):
+ if !B.F, Event = B.E; else ++Event, and set B.F in the new top entry
+readonly(D):
+ << nothing >>
+noaccess(D):
+ if D.N, ++Event
+def(D,K,V):
+ if K is already defined in D or K is not a name N, nothing to do
+ if N.V is NULL and D is systemdict,
+ set N.V to point into D, N.E = infinite
+ else
+ set N.V to point into D, N.E = Event, B.F = true in top entry
+put(D,K,V):
+ if K is already defined in D, K is not a name N, or D.N == 0,
+ nothing to do
+ if N.V is NULL and D is systemdict,
+ set N.V to point into D, N.E = infinite
+ else if D is the top dict on the dict stack
+ set N.V to point into D, N.E = Event, B.F = true in top entry
+ else
+ set N.V = invalid, N.E = 0
+undef(D,K):
+ if K is defined in D, D.N > 0, and K is a name N, clear N.E
+restore:
+ ****** TBC ******
+.setmaxlength(D):
+ for each name key N in D, if N.V points into D, repoint it
+value = lookup(N): (load and where are similar)
+ << do the fast lookup in the top dict >>
+ if N.E >= Event, use N.V
+ otherwise, do the dict stack lookup
+ set B.F in the top dict stack entry
+ set N.E = Event, N.V = the binding pointer
+context switch:
+ ++Event
+ for each B on the old dict stack, --(B.D.N)
+ for each B on the new dict stack, ++(B.D.N)
+Event counter overflow:
+ clear N.E in all names where it isn't infinite
+
+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.
+
+****** Context switching is horrendously expensive: it has to do the
+equivalent of 'end' for every dictionary on the old stack followed by
+'begin' for every dictionary on the new stack.
+
+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 <D,M,F,E> 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 <P,E> 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 = <ptr to invalid value, 0>
+begin(D):
+ *++dsp = <D, {0...}, D->F, ++Epoch>
+ set D->F
+value = lookup(K):
+ if K->E >= dsp->E
+ value = *K->P
+ else
+ do lookup as usual
+ *K = <ptr to value, Epoch>
+ 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
+
+****** Same problem for context switching as for full shallow binding.
+
*/
#endif /* dstack_INCLUDED */
diff --git a/gs/src/dvx-gcc.mak b/gs/src/dvx-gcc.mak
index 97d1cabf8..9445f1fb8 100755
--- a/gs/src/dvx-gcc.mak
+++ b/gs/src/dvx-gcc.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -50,7 +50,7 @@ GS_DOCDIR=$(docdir)
# Define the default directory/ies for the runtime
# initialization and font files. Separate multiple directories with a ;.
-GS_LIB_DEFAULT="$(gsdatadir);$(gsfontdir)"
+GS_LIB_DEFAULT="$(gsdatadir)/lib;$(gsfontdir)"
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -83,15 +83,18 @@ GENOPT=
GS=gs
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
-GLGENDIR=.
-GLOBJDIR=.
-PSSRCDIR=.
-PSGENDIR=.
-PSOBJDIR=.
+BINDIR=bin
+GLSRCDIR=src
+GLGENDIR=obj
+GLOBJDIR=obj
+PSSRCDIR=src
+PSLIBDIR=lib
+PSGENDIR=obj
+PSOBJDIR=obj
# Define the directory where the IJG JPEG library sources are stored,
# and the major version of the library that is stored there.
@@ -117,7 +120,7 @@ JPEG_NAME=jpeg
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
# Choose whether to use a shared version of the PNG library (-lpng).
# See gs.mak and Make.htm for more information.
@@ -135,10 +138,6 @@ ZSRCDIR=zlib
SHARE_ZLIB=0
ZLIB_NAME=gz
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# ------ Platform-specific options ------ #
# Define the name of the C compiler.
@@ -220,11 +219,17 @@ XLIBS=Xt Xext X11
FPU_TYPE=1
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -253,7 +258,7 @@ FILE_IMPLEMENTATION=stdio
DEVICE_DEVS=x11.dev
DEVICE_DEVS1=
DEVICE_DEVS2=
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
+DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet3d.dev ljet4.dev ljet4d.dev
DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
DEVICE_DEVS5=paintjet.dev pjetxl.dev uniprint.dev
DEVICE_DEVS6=
@@ -266,6 +271,11 @@ DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
DEVICE_DEVS13=
DEVICE_DEVS14=
DEVICE_DEVS15=pdfwrite.dev
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# ---------------------------- End of options --------------------------- #
@@ -273,6 +283,7 @@ DEVICE_DEVS15=pdfwrite.dev
# used in dependencies.
MAKEFILE=$(GLSRCDIR)/dvx-gcc.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/dvx-head.mak
# Define the ANSI-to-K&R dependency. (gcc accepts ANSI syntax.)
@@ -289,7 +300,8 @@ CC_LEAF=$(CC_) -fomit-frame-pointer
include $(GLSRCDIR)/dvx-head.mak
include $(GLSRCDIR)/gs.mak
include $(GLSRCDIR)/lib.mak
-include $(GLSRCDIR)/int.mak
+include $(PSSRCDIR)/int.mak
+include $(PSSRCDIR)/cfonts.mak
include $(GLSRCDIR)/jpeg.mak
# zlib.mak must precede libpng.mak
include $(GLSRCDIR)/zlib.mak
diff --git a/gs/src/dvx-head.mak b/gs/src/dvx-head.mak
index 1034b031b..9faabe091 100644
--- a/gs/src/dvx-head.mak
+++ b/gs/src/dvx-head.mak
@@ -29,14 +29,18 @@ PLATFORM=dvx_
# Define the syntax for command, object, and executable files.
+# Work around the fact that some `make' programs drop trailing spaces
+# or interpret == as a special definition operator.
+NULL=
+
CMD=.bat
+D_=-D
+_D_=$(NULL)=
+_D=
I_=-I
II=-I
_I=
-# There should be a <space> at the end of the definition of O_,
-# but we have to work around the fact that some `make' programs
-# drop trailing spaces in macro definitions.
-NULL=
+NO_OP=@:
O_=-o $(NULL)
OBJ=o
XE=.exe
@@ -49,7 +53,6 @@ D=\\
EXP=
SHELL=
SH=
-SHP=
# Define generic commands.
diff --git a/gs/src/dvx-tail.mak b/gs/src/dvx-tail.mak
index 63931a5e7..a0038e2df 100644
--- a/gs/src/dvx-tail.mak
+++ b/gs/src/dvx-tail.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -30,8 +30,8 @@
## The Desqview/X platform
dvx__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_dvx.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_dosfs.$(OBJ)
-dvx_.dev: $(dvx__) nosync.dev
- $(SETMOD) dvx_ $(dvx__) -include nosync
+$(GLGEN)dvx_.dev: $(dvx__) nosync.dev
+ $(SETMOD) $(GLGEN)dvx_ $(dvx__) -include nosync
$(GLOBJ)gp_dvx.$(OBJ): $(GLSRC)gp_dvx.c $(AK) $(string__h) $(gx_h) $(gsexit_h) $(gp_h) \
$(time__h) $(dos__h)
@@ -48,25 +48,31 @@ $(ECHOGS_XE): echogs.c
coff2exe echogs
del echogs
-$(GENARCH_XE): genarch.c $(stdpre_h)
+$(GENARCH_XE): genarch.c $(GENARCH_DEPS)
$(CC) -o genarch genarch.c
strip genarch
coff2exe genarch
del genarch
-$(GENCONF_XE): genconf.c $(stdpre_h)
+$(GENCONF_XE): genconf.c $(GENCONF_DEPS)
$(CC) -o genconf genconf.c
strip genconf
coff2exe genconf
del genconf
-$(GENDEV_XE): gendev.c $(stdpre_h)
+$(GENDEV_XE): gendev.c $(GENDEV_DEPS)
$(CC) -o gendev gendev.c
strip gendev
coff2exe gendev
del gendev
-$(GENINIT_XE): geninit.c $(stdio__h) $(string__h)
+$(GENHT_XE): genht.c $(GENHT_DEPS)
+ $(CC) -o genht $(GENHT_CFLAGS) genht.c
+ strip genht
+ coff2exe genht
+ del genht
+
+$(GENINIT_XE): geninit.c $(GENINIT_DEPS)
$(CC) -o geninit geninit.c
strip geninit
coff2exe geninit
diff --git a/gs/src/dwdll.cpp b/gs/src/dwdll.cpp
index 75e31ff20..943f9eb40 100644
--- a/gs/src/dwdll.cpp
+++ b/gs/src/dwdll.cpp
@@ -31,6 +31,7 @@ extern "C" {
#undef public
#include "gpgetenv.h"
#include "gsdll.h"
+#include "gsdllwin.h"
#include "gscdefs.h"
}
diff --git a/gs/src/dwdll.h b/gs/src/dwdll.h
index 946d0d00a..3fd0083bb 100644
--- a/gs/src/dwdll.h
+++ b/gs/src/dwdll.h
@@ -1,4 +1,5 @@
/* Copyright (C) 1996, Russell Lang. All rights reserved.
+ Portions Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,14 +22,13 @@
// gsdll_class for MS-Windows
-#ifndef _GSDLL_H
+#ifndef dwdll_INCLUDED
+# define dwdll_INCLUDED
+
extern "C" {
#include "gsdll.h"
+#include "gsdllwin.h"
}
-#endif
-#ifndef _GSDLL_CLASS_H
-#define _GSDLL_CLASS_H
-
class gsdll_class {
// instance of caller
@@ -113,4 +113,4 @@ class gsdll_class {
HPALETTE gsdll_class::copy_palette(const char FAR * device);
};
-#endif // _GSDLL_CLASS_H
+#endif /* dwdll_INCLUDED */
diff --git a/gs/src/dwmain.rc b/gs/src/dwmain.rc
index f4ff42d94..4fa119ca4 100644
--- a/gs/src/dwmain.rc
+++ b/gs/src/dwmain.rc
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, Russell Lang. All rights reserved.
+/* Copyright (C) 1996, 1998 Russell Lang. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,13 +18,20 @@
+
#include <windows.h>
#include "dwmain.h"
-GSTEXT_ICON ICON gstext.ico
-GSIMAGE_ICON ICON gsgraph.ico
+#ifndef gstext_ico
+#define gstext_ico gstext.ico
+#endif
+#ifndef gsgraph_ico
+#define gsgraph_ico gsgraph.ico
+#endif
+
+GSTEXT_ICON ICON gstext_ico
+GSIMAGE_ICON ICON gsgraph_ico
#ifndef DS_3DLOOK
#define DS_3DLOOK 0x0004L /* for Windows 95 look */
#endif
-
diff --git a/gs/src/dwnodll.cpp b/gs/src/dwnodll.cpp
index e396e5eb3..72e3e1428 100644
--- a/gs/src/dwnodll.cpp
+++ b/gs/src/dwnodll.cpp
@@ -34,6 +34,7 @@
extern "C" {
#include "gsdll.h"
+#include "gsdllwin.h"
}
#include "dwdll.h" // gsdll_class
diff --git a/gs/src/echogs.c b/gs/src/echogs.c
index 51e123ccb..06690d609 100644
--- a/gs/src/echogs.c
+++ b/gs/src/echogs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,6 +18,7 @@
/* 'echo'-like utility */
+#include "stdpre.h"
#include <stdio.h>
/* Some brain-damaged environments (e.g. Sun) don't include */
/* prototypes for fputc/fputs in stdio.h! */
@@ -28,14 +29,8 @@ extern int fputc(), fputs();
#include <ctype.h>
#include <string.h>
#include <time.h> /* for ctime */
-/* The VMS environment uses different values for success/failure exits: */
#ifdef VMS
#include <stdlib.h>
-# define exit_OK 1
-# define exit_FAILED 18
-#else
-# define exit_OK 0
-# define exit_FAILED 1
#endif
/*
@@ -72,7 +67,7 @@ extern int fputc(), fputs();
* -R means copy a named file with no interpretation
* (but convert to hex if -h is in effect).
* -X means treat any following literals as hex rather than string data.
- * - alone means treat the rest of the line as literal data,
+ * - or -+ alone means treat the rest of the line as literal data,
* even if the first string begins with a -.
* -+<letter> is equivalent to -<Letter>, i.e., it upper-cases the letter.
* Inserts spaces automatically between the trailing strings,
@@ -89,7 +84,7 @@ main(int argc, char *argv[])
{
FILE *out = stdout;
FILE *in;
- char *extn = "";
+ const char *extn = "";
char fmode[4];
#define FNSIZE 100
char *fnparam;
@@ -127,8 +122,14 @@ main(int argc, char *argv[])
strcpy(fname, fnparam);
strcat(fname, extn);
if (fmode[len - 2] == '-') {
+ /*
+ * The referents of argp are actually const, but they can't be
+ * declared that way, so we have to make a writable constant.
+ */
+ static char dash[2] = { '-', 0 };
+
fmode[len - 2] = 0;
- argp[i] = "-";
+ argp[i] = dash;
argp++, nargs--;
} else {
for (; i > 1; i--)
@@ -174,10 +175,6 @@ main(int argc, char *argv[])
sp = 0;
swc:switch (chr) {
- case '+': /* upper-case command */
- ++arg;
- chr = toupper(arg[1]);
- goto swc;
case 'l': /* literal string, then -s */
chr = 'Q';
/* falls through */
@@ -229,7 +226,14 @@ main(int argc, char *argv[])
case 'X': /* treat literals as hex */
hexx = 1;
break;
- case 0: /* just '-' */
+ case '+': /* upper-case command */
+ if (arg[1]) {
+ ++arg;
+ chr = toupper(arg[1]);
+ goto swc;
+ }
+ /* falls through */
+ case 0: /* just '-' */
sw = '-';
break;
}
@@ -316,7 +320,7 @@ main(int argc, char *argv[])
static int
hputc(int ch, FILE * out)
{
- static char *hex = "0123456789abcdef";
+ static const char *hex = "0123456789abcdef";
/* In environments where char is signed, ch may be negative (!). */
putc(hex[(ch >> 4) & 0xf], out);
diff --git a/gs/src/errors.h b/gs/src/errors.h
index 659bc9279..db3e991af 100644
--- a/gs/src/errors.h
+++ b/gs/src/errors.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -108,12 +108,12 @@ extern const char *const gs_error_names[];
#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.
+ * Internal code that indicates that a procedure has been stored in the
+ * remap_proc of the graphics state, and should be called 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)
+#define e_RemapColor (-103)
/*
* Internal code to indicate we have underflowed the top block
diff --git a/gs/src/estack.h b/gs/src/estack.h
index d28c44cdf..578fc63ca 100644
--- a/gs/src/estack.h
+++ b/gs/src/estack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,19 +23,18 @@
# define estack_INCLUDED
#include "iestack.h"
+#include "icstate.h" /* for access to exec_stack */
/* 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 esfile_clear_cache() estack_clear_cache(&iexec_stack)
+#define esfile_set_cache(pref) estack_set_cache(&iexec_stack, pref)
+#define esfile_check_cache() estack_check_cache(&iexec_stack)
+/* Define the execution stack pointers for operators. */
+#define iexec_stack (i_ctx_p->exec_stack)
#define e_stack (iexec_stack.stack)
+
#define esbot (e_stack.bot)
#define esp (e_stack.p)
#define estop (e_stack.top)
@@ -109,7 +108,7 @@ extern exec_stack_t iexec_stack;
* Pop a given number of elements off the execution stack,
* executing cleanup procedures as necessary.
*/
-void pop_estack(P1(uint));
+void pop_estack(P2(i_ctx_t *, uint));
/*
* The execution stack is implemented as a linked list of blocks;
diff --git a/gs/src/files.h b/gs/src/files.h
index a5ba930cc..e1f732039 100644
--- a/gs/src/files.h
+++ b/gs/src/files.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,19 +35,21 @@
/* 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 **));
+int zget_stdin(P2(i_ctx_t *, stream **));
+int zget_stdout(P2(i_ctx_t *, stream **));
+int zget_stderr(P2(i_ctx_t *, stream **));
extern bool gs_stdin_is_interactive;
+/* Test whether a stream is stdin. */
+bool zis_stdin(P1(const stream *));
-/* Export the stdio refs for switching contexts. */
-extern ref ref_stdio[3];
-
+/* Define access to the stdio refs for operators. */
+#define ref_stdio (i_ctx_p->stdio)
#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;
+#define avm_invalid_file_entry avm_foreign
+extern stream *const invalid_file_entry;
/*
* Macros for checking file validity.
@@ -78,17 +80,19 @@ int file_switch_to_read(P1(const ref *));
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 */\
+ 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 {\
+ invalid_action; /* closed or reopened file */\
}\
+ }\
END
int file_switch_to_write(P1(const ref *));
@@ -146,6 +150,7 @@ 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 *));
+int zreadline_from(P5(stream *s, gs_string *buf, gs_memory_t *bufmem,
+ uint *pcount, bool *pin_eol));
#endif /* files_INCLUDED */
diff --git a/gs/src/gconf.c b/gs/src/gconf.c
index 6ad6eda98..dc15d299a 100644
--- a/gs/src/gconf.c
+++ b/gs/src/gconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -16,7 +16,6 @@
all copies.
*/
-#define IN_GCONF_C 1 /* set for gconf.h to prevent conflict def'n */
/* Configuration tables */
#include "memory_.h"
@@ -24,6 +23,8 @@
#include "gscdefs.h" /* interface */
#include "gconf.h" /* for #defines */
#include "gxdevice.h"
+#include "gxdhtres.h"
+#include "gxiclass.h"
#include "gxiodev.h"
#include "gxiparam.h"
@@ -36,7 +37,13 @@
* for each installed device;
* emulator_("emulator", strlen("emulator"))
* for each known emulator;
- * image_type(gs_image_type_xxx)
+ * function_type_(xxx, gs_function_type_xxx)
+ * for each known function type;
+ * halftone_(gs_dht_xxx)
+ * for each known (device) halftone;
+ * image_class_(gs_image_class_xxx)
+ * for each known image class;
+ * image_type_(xxx, gs_image_type_xxx)
* for each known image type;
* init_(gs_xxx_init)
* for each initialization procedure;
@@ -57,33 +64,66 @@
/* Declare devices, image types, init procedures, and IODevices as extern. */
#define device_(dev) extern far_data gx_device dev;
#define device2_(dev) extern const gx_device dev;
-#define image_type_(type) extern const gx_image_type_t type;
+#define halftone_(dht) extern const gx_device_halftone_resource_t *dht(P0());
+#define image_class_(cls) extern iclass_proc(cls);
+#define image_type_(i,type) extern const gx_image_type_t type;
#define init_(proc) extern void proc(P1(gs_memory_t *));
#define io_device_(iodev) extern const gx_io_device iodev;
#include "gconf.h"
#undef io_device_
#undef init_
#undef image_type_
+#undef image_class_
+#undef halftone_
#undef device2_
#undef device_
+/* 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_
+
+/* Set up the (device) halftone table. */
+extern_gx_device_halftone_list();
+#define halftone_(dht) dht,
+const gx_dht_proc gx_device_halftone_list[] = {
+#include "gconf.h"
+ 0
+};
+#undef halftone_
+
+/* Set up the image class table. */
+extern_gx_image_class_table();
+#define image_class_(cls) cls,
+const gx_image_class_t gx_image_class_table[] = {
+#include "gconf.h"
+ 0
+};
+#undef image_class_
+/* We must use unsigned here, not uint. See gscdefs.h. */
+const unsigned gx_image_class_table_count = countof(gx_image_class_table) - 1;
+
/* Set up the image type table. */
extern_gx_image_type_table();
-#define image_type_(type) &type,
+#define image_type_(i,type) &type,
const gx_image_type_t *const gx_image_type_table[] = {
#include "gconf.h"
0
};
#undef image_type_
-const uint gx_image_type_table_count = countof(gx_image_type_table) - 1;
+/* We must use unsigned here, not uint. See gscdefs.h. */
+const unsigned gx_image_type_table_count = countof(gx_image_type_table) - 1;
/* 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_
@@ -99,31 +139,11 @@ const gx_io_device *const gx_io_device_table[] = {
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]);
-}
+/* We must use unsigned here, not uint. See gscdefs.h. */
+const unsigned gx_io_device_table_count = countof(gx_io_device_table) - 1;
-/* Return the list of device prototypes, the list of their structure */
-/* descriptors, and (as the value) the length of the lists. */
+/* Return the list of device prototypes, a NULL list of their structure */
+/* descriptors (no longer used), and (as the value) the length of the lists. */
extern_gs_lib_device_list();
int
gs_lib_device_list(const gx_device * const **plist,
@@ -132,6 +152,6 @@ gs_lib_device_list(const gx_device * const **plist,
if (plist != 0)
*plist = gx_device_list;
if (pst != 0)
- *pst = gx_device_st_list;
+ *pst = NULL;
return countof(gx_device_list) - 1;
}
diff --git a/gs/src/gdev3852.c b/gs/src/gdev3852.c
index 70af0431d..d93595042 100644
--- a/gs/src/gdev3852.c
+++ b/gs/src/gdev3852.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,7 +22,10 @@ Modified 3/93 to correct bug in cnt_2prn size.
Modified 3/93 to dimension page back to 8.5, which seems to
work better than the actual page width of 7.6, ie. it uses
the full printing width of the printer.
- It was modeled after the V2.4.1 HP Paintjet driver (gdevpjet.c) */
+ It was modeled after the V2.4.1 HP Paintjet driver (gdevpjet.c)
+Modified by L. Peter Deutsch <ghost@aladdin.com> 1999-01-10 to remove _ss
+ modifiers inappropriately copied from other code.
+ */
/* IBM 3852 JetPrinter color ink jet driver for Ghostscript */
@@ -78,7 +81,7 @@ jetp3852_print_page(gx_device_printer *pdev, FILE *prn_stream)
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
int num_blank_lines = 0;
for ( lnum = 0; lnum < pdev->height; lnum++ )
- { byte _ss *end_data = data + line_size;
+ { byte *end_data = data + line_size;
gdev_prn_copy_scan_lines(pdev, lnum,
(byte *)data, line_size);
/* Remove trailing 0s. */
@@ -90,8 +93,8 @@ jetp3852_print_page(gx_device_printer *pdev, FILE *prn_stream)
}
else
{ int i;
- byte _ss *odp;
- byte _ss *row;
+ byte *odp;
+ byte *row;
/* Pad with 0s to fill out the last */
/* block of 8 bytes. */
@@ -107,7 +110,7 @@ jetp3852_print_page(gx_device_printer *pdev, FILE *prn_stream)
static ulong spr40[8] = spread3(0x40);
static ulong spr8[8] = spread3(8);
static ulong spr2[8] = spread3(2);
- register byte _ss *dp = data + i;
+ register byte *dp = data + i;
register ulong pword =
(spr40[dp[0]] << 1) +
(spr40[dp[1]]) +
diff --git a/gs/src/gdevabuf.c b/gs/src/gdevabuf.c
index 4d9d97bce..0d10a0c1c 100644
--- a/gs/src/gdevabuf.c
+++ b/gs/src/gdevabuf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -39,7 +39,6 @@
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
@@ -56,7 +55,6 @@ gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem,
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);
}
@@ -91,13 +89,6 @@ mem_alpha_map_rgb_alpha_color(gx_device * dev, gx_color_value r,
(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,
@@ -175,6 +166,9 @@ gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem,
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);
+ adev->color_info.anti_alias.text_bits =
+ adev->color_info.anti_alias.graphics_bits =
+ alpha_bits;
}
/* Test whether a device is an alpha-buffering device. */
@@ -269,7 +263,7 @@ typedef struct y_transfer_s {
int transfer_y;
int transfer_height;
} y_transfer;
-private void near
+private void
y_transfer_init(y_transfer * pyt, gx_device * dev, int ty, int th)
{
gx_device_memory * const mdev = (gx_device_memory *)dev;
@@ -286,7 +280,7 @@ y_transfer_init(y_transfer * pyt, gx_device * dev, int ty, int th)
pyt->transfer_height = 0;
}
/* while ( yt.height_left > 0 ) { y_transfer_next(&yt, mdev); ... } */
-private void near
+private void
y_transfer_next(y_transfer * pyt, gx_device * dev)
{
gx_device_memory * const mdev = (gx_device_memory *)dev;
diff --git a/gs/src/gdevalph.c b/gs/src/gdevalph.c
index cccc269c6..2de5cd06b 100644
--- a/gs/src/gdevalph.c
+++ b/gs/src/gdevalph.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -138,7 +138,7 @@ dsa_open(gx_device * dev)
sadev->width = tdev->width;
sadev->height = tdev->height;
sadev->color_info = tdev->color_info;
- sadev->color_info.depth = (depth <= 4 ? 4 : round_up(depth, 8));
+ sadev->color_info.depth = (depth <= 4 ? 4 : ROUND_UP(depth, 8));
sadev->alpha_depth = adepth;
sadev->adev = 0;
return 0;
diff --git a/gs/src/gdevbbox.h b/gs/src/gdevbbox.h
index 190dae35b..79c61be15 100644
--- a/gs/src/gdevbbox.h
+++ b/gs/src/gdevbbox.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
diff --git a/gs/src/gdevbit.c b/gs/src/gdevbit.c
index e455cd554..beb3d3c95 100644
--- a/gs/src/gdevbit.c
+++ b/gs/src/gdevbit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,26 +18,13 @@
/* "Plain bits" devices to measure rendering time. */
+#include "math_.h"
#include "gdevprn.h"
#include "gsparam.h"
#include "gscrd.h"
#include "gscrdp.h"
#include "gxlum.h"
-
-/*
- * When debugging problems on large CMYK devices, we have to be able to
- * modify the output at this stage. These parameters are not set in any
- * normal configuration.
- */
-/* Define whether to trim off top and bottom white space. */
-/*#define TRIM_TOP_BOTTOM */
-/* Define left and right trimming margins. */
-/* Note that this is only approximate: we trim to byte boundaries. */
-/*#define TRIM_LEFT 400 */
-/*#define TRIM_RIGHT 400 */
-/* Define whether to expand each bit to a byte. */
-/* Also convert black-and-white to proper gray (inverting if monobit). */
-/*#define EXPAND_BITS_TO_BYTES */
+#include "gdevdcrd.h"
/* Define the device parameters. */
#ifndef X_DPI
@@ -49,7 +36,6 @@
/* The device descriptor */
private dev_proc_map_rgb_color(bit_mono_map_rgb_color);
-private dev_proc_map_rgb_color(bit_map_rgb_color);
private dev_proc_map_rgb_color(bit_forcemono_map_rgb_color);
private dev_proc_map_color_rgb(bit_map_color_rgb);
private dev_proc_map_cmyk_color(bit_map_cmyk_color);
@@ -89,7 +75,7 @@ private dev_proc_print_page(bit_print_page);
* parameter, which alters dev->num_components.
*/
#define REAL_NUM_COMPONENTS(dev) (dev->dname[3] == 'c' ? 4 : \
- dev->dname[3] == 'r' ? 3 : 1)
+ dev->dname[3] == 'r' ? 3 : 1)
private const gx_device_procs bitmono_procs =
bit_procs(bit_mono_map_rgb_color, NULL);
@@ -102,7 +88,7 @@ const gx_device_printer gs_bit_device =
};
private const gx_device_procs bitrgb_procs =
-bit_procs(bit_map_rgb_color, NULL);
+bit_procs(gx_default_rgb_map_rgb_color, NULL);
const gx_device_printer gs_bitrgb_device =
{prn_device_body(gx_device_printer, bitrgb_procs, "bitrgb",
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
@@ -139,18 +125,6 @@ bit_mono_map_rgb_color(gx_device * dev, gx_color_value red,
return (bpc == 1 ? gx_max_color_value - gray : gray) >> drop;
}
-/* Map RGB to color. */
-private gx_color_index
-bit_map_rgb_color(gx_device * dev, gx_color_value red,
- gx_color_value green, gx_color_value blue)
-{
- int bpc = dev->color_info.depth / 3;
- int drop = sizeof(gx_color_value) * 8 - bpc;
-
- return ((((red >> drop) << bpc) + (green >> drop)) << bpc) +
- (blue >> drop);
-}
-
/* Map RGB to gray shade. */
/* Only used in CMYK mode when put_params has set ForceMono=1 */
private gx_color_index
@@ -179,7 +153,7 @@ private int
bit_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value rgb[3])
{
int depth = dev->color_info.depth;
- int ncomp = dev->color_info.num_components;
+ int ncomp = REAL_NUM_COMPONENTS(dev);
int bpc = depth / ncomp;
uint mask = (1 << bpc) - 1;
@@ -242,14 +216,6 @@ bit_map_cmyk_color(gx_device * dev, gx_color_value cyan,
/* Get parameters. We provide a default CRD. */
private int
-my_tpqr(int index, floatp in, const gs_cie_wbsd * pwbsd,
- gs_cie_render * pcrd, float *out)
-{
- *out = (in < 0.5 ? in / 2 : in * 3 / 2 - 0.5);
- return 0;
-}
-
-private int
bit_get_params(gx_device * pdev, gs_param_list * plist)
{
int code, ecode;
@@ -267,50 +233,10 @@ bit_get_params(gx_device * pdev, gs_param_list * plist)
*/
pdev->color_info.num_components = real_ncomps;
- if (param_requested(plist, "CRDDefault") > 0) {
- gs_cie_render *pcrd;
-
ecode = gdev_prn_get_params(pdev, plist);
- code = gs_cie_render1_build(&pcrd, pdev->memory, "bit_get_params");
- if (code >= 0) {
- static const gs_vector3 my_white_point = {1, 1, 1};
- static const gs_cie_transform_proc3 my_TransformPQR = {
- 0, "bitTPQRDefault", {0, 0}, 0
- };
- gs_cie_transform_proc3 tpqr;
-
- tpqr = my_TransformPQR;
- tpqr.driver_name = pdev->dname;
- code = gs_cie_render1_initialize(pcrd, NULL,
- &my_white_point, NULL,
- NULL, NULL, &tpqr,
- NULL, NULL, NULL,
- NULL, NULL, NULL,
- NULL);
- if (code >= 0) {
- code = param_write_cie_render1(plist, "CRDDefault", pcrd,
- pdev->memory);
- }
- rc_decrement(pcrd, "bit_get_params"); /* release */
- }
- if (code < 0)
- ecode = code;
- }
-
- if (param_requested(plist, "bitTPQRDefault") > 0) {
- gs_cie_transform_proc my_proc = my_tpqr;
- static byte my_addr[sizeof(gs_cie_transform_proc)];
- gs_param_string as;
-
- memcpy(my_addr, &my_proc, sizeof(gs_cie_transform_proc));
- as.data = my_addr;
- as.size = sizeof(gs_cie_transform_proc);
- as.persistent = true;
- code = param_write_string(plist, "bitTPQRDefault", &as);
+ code = sample_device_crd_get_params(pdev, plist, "CRDDefault");
if (code < 0)
ecode = code;
- }
-
if ((code = param_write_int(plist, "ForceMono", &forcemono)) < 0) {
ecode = code;
}
@@ -356,11 +282,11 @@ bit_put_params(gx_device * pdev, gs_param_list * plist)
ecode = code;
else
switch (v) {
- case 2: bpc = 1; break;
- case 4: bpc = 2; break;
- case 16: bpc = 4; break;
- case 32: bpc = 5; break;
- case 256: bpc = 8; break;
+ case 2: bpc = 1; break;
+ case 4: bpc = 2; break;
+ case 16: bpc = 4; break;
+ case 32: bpc = 5; break;
+ case 256: bpc = 8; break;
default:
param_signal_error(plist, vname,
ecode = gs_error_rangecheck);
@@ -370,13 +296,13 @@ bit_put_params(gx_device * pdev, gs_param_list * plist)
switch (code = param_read_int(plist, (vname = "ForceMono"), &v)) {
case 0:
if (v == 1) {
- ncomps = 1;
+ ncomps = 1;
break;
}
- else if (v == 0) {
- ncomps = real_ncomps;
+ else if (v == 0) {
+ ncomps = real_ncomps;
break;
- }
+ }
code = gs_error_rangecheck;
default:
ecode = code;
@@ -396,7 +322,7 @@ bit_put_params(gx_device * pdev, gs_param_list * plist)
pdev->color_info.max_gray = pdev->color_info.max_color =
(pdev->color_info.dither_grays =
pdev->color_info.dither_colors =
- (1 << bpc)) - 1;
+ (1 << bpc)) - 1;
ecode = gdev_prn_put_params(pdev, plist);
if (ecode < 0) {
pdev->color_info = save_info;
@@ -405,9 +331,11 @@ bit_put_params(gx_device * pdev, gs_param_list * plist)
/* Now restore/change num_components. This is done after other */
/* processing since it is used in gx_default_put_params */
pdev->color_info.num_components = ncomps;
-
- if (pdev->color_info.depth != save_info.depth)
- gs_closedevice(pdev);
+ if (pdev->color_info.depth != save_info.depth ||
+ pdev->color_info.num_components != save_info.num_components
+ ) {
+ gs_closedevice(pdev);
+ }
/* Reset the map_cmyk_color procedure if appropriate. */
if (dev_proc(pdev, map_cmyk_color) == cmyk_1bit_map_cmyk_color ||
dev_proc(pdev, map_cmyk_color) == cmyk_8bit_map_cmyk_color ||
@@ -433,84 +361,10 @@ bit_print_page(gx_device_printer * pdev, FILE * prn_stream)
if (in == 0)
return_error(gs_error_VMerror);
-#ifdef TRIM_TOP_BOTTOM
- {
- gx_color_index white =
- (pdev->color_info.num_components == 4 ? 0 :
- (*dev_proc(pdev, map_rgb_color))
- ((gx_device *) pdev, gx_max_color_value, gx_max_color_value,
- gx_max_color_value));
-
-#define color_index_bits (sizeof(gx_color_index) * 8)
- const gx_color_index *p;
- const gx_color_index *end;
- int depth = pdev->color_info.depth;
- int end_bits = ((long)line_size * depth) % color_index_bits;
- gx_color_index end_mask =
- (end_bits == 0 ? 0 : -1 << (color_index_bits - end_bits));
- int i;
-
- for (i = depth; i < color_index_bits; i += depth)
- white |= white << depth;
- /* Remove bottom white space. */
- for (; bottom - lnum > 1; --bottom) {
- gdev_prn_get_bits(pdev, bottom - 1, in, &data);
- p = (const gx_color_index *)data;
- end = p + line_size / sizeof(gx_color_index);
- for (; p < end; ++p)
- if (*p != white)
- goto bx;
- if (end_mask != 0 && ((*end ^ white) & end_mask) != 0)
- goto bx;
- }
- /* Remove top white space. */
- bx:for (; lnum < bottom; ++lnum) {
- gdev_prn_get_bits(pdev, lnum, in, &data);
- p = (const gx_color_index *)data;
- end = p + line_size / sizeof(gx_color_index);
- for (; p < end; ++p)
- if (*p != white)
- goto tx;
- if (end_mask != 0 && ((*end ^ white) & end_mask) != 0)
- goto tx;
- }
- tx:;
- }
-#endif
for (; lnum < bottom; ++lnum) {
gdev_prn_get_bits(pdev, lnum, in, &data);
- if (!nul) {
- const byte *row = data;
- uint len = line_size;
-
-#ifdef TRIM_LEFT
- row += (TRIM_LEFT * pdev->color_info.depth) >> 3;
-#endif
-#ifdef TRIM_RIGHT
- len = data + ((TRIM_RIGHT * pdev->color_info.depth + 7) >> 3) - row;
-#endif
-#ifdef EXPAND_BITS_TO_BYTES
- {
- uint i;
- byte invert = (pdev->color_info.depth == 1 ? 0xff : 0);
-
- for (i = 0; i < len; ++i) {
- byte b = row[i] ^ invert;
-
- putc(-(b >> 7) & 0xff, prn_stream);
- putc(-((b >> 6) & 1) & 0xff, prn_stream);
- putc(-((b >> 5) & 1) & 0xff, prn_stream);
- putc(-((b >> 4) & 1) & 0xff, prn_stream);
- putc(-((b >> 3) & 1) & 0xff, prn_stream);
- putc(-((b >> 2) & 1) & 0xff, prn_stream);
- putc(-((b >> 1) & 1) & 0xff, prn_stream);
- putc(-(b & 1) & 0xff, prn_stream);
- }
- }
-#else
- fwrite(row, 1, len, prn_stream);
-#endif
- }
+ if (!nul)
+ fwrite(data, 1, line_size, prn_stream);
}
gs_free((char *)in, line_size, 1, "bit_print_page(in)");
return 0;
diff --git a/gs/src/gdevbjcl.c b/gs/src/gdevbjcl.c
new file mode 100644
index 000000000..0be4be64a
--- /dev/null
+++ b/gs/src/gdevbjcl.c
@@ -0,0 +1,252 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/* Canon BJC command generation library */
+#include "std.h"
+#include "gdevbjcl.h"
+
+/****** PRELIMINARY, SUBJECT TO CHANGE WITHOUT NOTICE. ******/
+
+/* ---------------- Utilities ---------------- */
+
+private void
+bjc_put_bytes(stream *s, const byte *data, uint count)
+{
+ uint ignore;
+
+ sputs(s, data, count, &ignore);
+}
+
+private void
+bjc_put_hi_lo(stream *s, int value)
+{
+ spputc(s, value >> 8);
+ spputc(s, value & 0xff);
+}
+
+private void
+bjc_put_lo_hi(stream *s, int value)
+{
+ spputc(s, value & 0xff);
+ spputc(s, value >> 8);
+}
+
+private void
+bjc_put_command(stream *s, int ch, int count)
+{
+ spputc(s, 033 /*ESC*/);
+ spputc(s, '(');
+ spputc(s, ch);
+ bjc_put_lo_hi(s, count);
+}
+
+/* ---------------- Commands ---------------- */
+
+/* Line feed (^J) */
+void
+bjc_put_LF(stream *s)
+{
+ spputc(s, 0x0a);
+}
+
+/* Form feed (^L) */
+void
+bjc_put_FF(stream *s)
+{
+ spputc(s, 0x0c);
+}
+
+/* Carriage return (^M) */
+void
+bjc_put_CR(stream *s)
+{
+ spputc(s, 0x0d);
+}
+
+/* Return to initial condition (ESC @) */
+void
+bjc_put_initialize(stream *s)
+{
+ bjc_put_bytes(s, (const byte *)"\033@", 2);
+}
+
+/* Set initial condition (ESC [ K <count> <init> <id> <parm1> <parm2>) */
+void
+bjc_put_set_initial(stream *s)
+{
+ bjc_put_bytes(s, (const byte *)"\033[K\002\000\000\017", 7);
+}
+
+/* Set data compression (ESC [ b <count> <state>) */
+void
+bjc_put_set_compression(stream *s, bjc_raster_compression_t compression)
+{
+ bjc_put_command(s, 'b', 1);
+ spputc(s, compression);
+}
+
+/* Select print method (ESC ( c <count> <parm1> <parm2> [<parm3>]) */
+void
+bjc_put_print_method_short(stream *s, bjc_print_color_short_t color)
+{
+ bjc_put_command(s, 'c', 1);
+ spputc(s, color);
+}
+void
+bjc_put_print_method(stream *s, bjc_print_color_t color,
+ bjc_print_media_t media, bjc_print_quality_t quality,
+ bjc_black_density_t density)
+{
+ bjc_put_command(s, 'c', 2 + (density != 0));
+ spputc(s, 0x10 | color);
+ spputc(s, (media << 4) | quality);
+ if (density)
+ spputc(s, density << 4);
+}
+
+/* Set raster resolution (ESC ( d <count> <y_res> [<x_res>]) */
+void
+bjc_put_raster_resolution(stream *s, int x_resolution, int y_resolution)
+{
+ if (x_resolution == y_resolution) {
+ bjc_put_command(s, 'd', 2);
+ } else {
+ bjc_put_command(s, 'd', 4);
+ bjc_put_hi_lo(s, y_resolution);
+ }
+ bjc_put_hi_lo(s, x_resolution);
+}
+
+/* Raster skip (ESC ( e <count> <skip>) */
+void
+bjc_put_raster_skip(stream *s, int skip)
+{
+ bjc_put_command(s, 'e', 2);
+ bjc_put_hi_lo(s, skip);
+}
+
+/* Set page margins (ESC ( g <count> <length> <lm> <rm> <top>) */
+void
+bjc_put_page_margins(stream *s, int length, int lm, int rm, int top)
+{
+ byte parms[4];
+ int count;
+
+ parms[0] = length, parms[1] = lm, parms[2] = rm, parms[3] = top;
+ count = 4; /* could be 1..3 */
+ bjc_put_command(s, 'g', count);
+ bjc_put_bytes(s, parms, count);
+}
+
+/* Set media supply method (ESC * l <count> <parm1> <parm2>) */
+void
+bjc_put_media_supply(stream *s, bjc_media_supply_t supply,
+ bjc_media_type_t type)
+{
+ bjc_put_command(s, 'l', 2);
+ spputc(s, 0x10 | supply);
+ spputc(s, type << 4);
+}
+
+/* Identify ink cartridge (ESC ( m <count> <type>) */
+void
+bjc_put_identify_cartridge(stream *s,
+ bjc_identify_cartridge_command_t command)
+{
+ bjc_put_command(s, 'm', 1);
+ spputc(s, command);
+}
+
+/* CMYK raster image (ESC ( A <count> <color>) */
+void
+bjc_put_cmyk_image(stream *s, bjc_cmyk_image_component_t component,
+ const byte *data, int count)
+{
+ bjc_put_command(s, 'A', count + 1);
+ spputc(s, component);
+ bjc_put_bytes(s, data, count);
+}
+
+/* Move by raster lines (ESC ( n <count> <lines>) */
+void
+bjc_put_move_lines(stream *s, int lines)
+{
+ bjc_put_command(s, 'n', 2);
+ bjc_put_hi_lo(s, lines);
+}
+
+/* Set unit for movement by raster lines (ESC ( o <count> <unit>) */
+void
+bjc_put_move_lines_unit(stream *s, int unit)
+{
+ bjc_put_command(s, 'o', 2);
+ bjc_put_hi_lo(s, unit);
+}
+
+/* Set extended margins (ESC ( p <count> <length60ths> <lm60ths> */
+/* <rm60ths> <top60ths>) */
+void
+bjc_put_extended_margins(stream *s, int length, int lm, int rm, int top)
+{
+ bjc_put_command(s, 'p', 8);
+ bjc_put_hi_lo(s, length);
+ bjc_put_hi_lo(s, lm);
+ bjc_put_hi_lo(s, rm);
+ bjc_put_hi_lo(s, top);
+}
+
+/* Set image format (ESC ( t <count> <depth> <format> <ink>) */
+void
+bjc_put_image_format(stream *s, int depth, bjc_image_format_t format,
+ bjc_ink_system_t ink)
+
+{
+ bjc_put_command(s, 't', 3);
+ spputc(s, depth);
+ spputc(s, format);
+ spputc(s, ink);
+}
+
+/* Page ID (ESC ( q <count> <id>) */
+void
+bjc_put_page_id(stream *s, int id)
+{
+ bjc_put_command(s, 'q', 1);
+ spputc(s, id);
+}
+
+/* Continue raster image (ESC ( F <count> <data>) */
+void
+bjc_put_continue_image(stream *s, const byte *data, int count)
+{
+ bjc_put_command(s, 'F', count);
+ bjc_put_bytes(s, data, count);
+}
+
+/* BJ indexed image (ESC ( f <count> R <dot_rows> <dot_cols> <layers> */
+/* <index>) */
+void
+bjc_put_indexed_image(stream *s, int dot_rows, int dot_cols, int layers)
+{
+ bjc_put_command(s, 'f', 5);
+ spputc(s, 'R'); /* per spec */
+ spputc(s, dot_rows);
+ spputc(s, dot_cols);
+ spputc(s, layers);
+}
diff --git a/gs/src/gdevbjcl.h b/gs/src/gdevbjcl.h
new file mode 100644
index 000000000..82c7df7be
--- /dev/null
+++ b/gs/src/gdevbjcl.h
@@ -0,0 +1,401 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/* Canon BJC command generation library interface */
+
+/****** PRELIMINARY, SUBJECT TO CHANGE WITHOUT NOTICE. ******/
+
+#ifndef gdevcbjc_INCLUDED
+# define gdevcbjc_INCLUDED
+
+#include <stdio.h> /* ****** PATCH FOR stream.h ****** */
+#include "stream.h"
+
+/*
+ * These procedures generate command strings for the Canon BJC family of
+ * printers. Note that not all printers support all commands.
+ */
+
+/* ---------------- Printer capabilities ---------------- */
+
+/*
+ * Different printer models implement different subsets of the command set.
+ * We define a mask bit for each capability, and a mask for each printer
+ * indicating which capabilities it supports. In some cases, a capability
+ * is a parameter value for a command rather than a separate command.
+ */
+
+/*
+ * Single-character commands.
+ *
+ * All BJC models implement CR and FF.
+ */
+#define BJC_OPT_NUL 0x00000001
+#define BJC_OPT_LF 0x00000002
+
+/*
+ * Session commands.
+ *
+ * All BJC models implement Set initial condition, Initialize,
+ * Print method, and Media Supply.
+ */
+#define BJC_OPT_IDENTIFY_CARTRIDGE 0x00000004
+#define BJC_OPT_MONOCHROME_SMOOTHING 0x00000008 /* for bjc_print_color_t */
+
+/*
+ * Page commands.
+ *
+ * All BJC models implement Page margins.
+ */
+#define BJC_OPT_EXTENDED_MARGINS 0x00000010
+#define BJC_OPT_PAGE_ID 0x00000020
+
+/*
+ * Resolution. This varies considerably from model to model.
+ * The _300 or _360 option gives the base resolution; the other options
+ * indicate which multiples of the base are available.
+ * Note that the resolution multipliers are specified as X, then Y.
+ */
+#define BJC_OPT_RESOLUTION_360 0x00000040
+#define BJC_OPT_RESOLUTION_300 0x00000080
+#define BJC_OPT_RESOLUTION_HALF 0x00000100 /* 180 or 150 */
+#define BJC_OPT_RESOLUTION_QUARTER 0x00000200 /* 90 or 75 */
+#define BJC_OPT_RESOLUTION_2X 0x00000400 /* 720 or 600 */
+#define BJC_OPT_RESOLUTION_2X_1X 0x00000800
+#define BJC_OPT_RESOLUTION_4X_2X 0x00001000
+
+/*
+ * Image commands.
+ *
+ * All BJC models implement Raster resolution, Raster skip, CMYK image,
+ * and Data compression.
+ */
+#define BJC_OPT_X_Y_RESOLUTION 0x00002000 /* for raster_resolution */
+#define BJC_OPT_MOVE_LINES 0x00004000
+#define BJC_OPT_IMAGE_FORMAT 0x00008000
+#define BJC_OPT_CONTINUE_IMAGE 0x00010000
+#define BJC_OPT_INDEXED_IMAGE 0x00020000
+#define BJC_OPT_SET_COLOR_COMPONENT 0x00040000
+
+/*
+ * Define the capabilities of the models that we know about.
+ */
+/*
+ * We don't have the documentation for the 50, but Canon says it's the
+ * same as the 80.
+ */
+#define BJC_OPT_50\
+ (BJC_OPT_NUL | BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE |\
+ BJC_OPT_EXTENDED_MARGINS | BJC_OPT_PAGE_ID |\
+ BJC_OPT_RESOLUTION_360 | BJC_OPT_RESOLUTION_HALF |\
+ BJC_OPT_RESOLUTION_QUARTER | BJC_OPT_RESOLUTION_2X_1X |\
+ BJC_OPT_X_Y_RESOLUTION | BJC_OPT_MOVE_LINES | BJC_OPT_IMAGE_FORMAT |\
+ BJC_OPT_CONTINUE_IMAGE)
+#define BJC_OPT_70\
+ (BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE | BJC_OPT_MONOCHROME_SMOOTHING |\
+ BJC_OPT_RESOLUTION_360)
+#define BJC_OPT_80\
+ BJC_OPT_50
+#define BJC_OPT_210\
+ (BJC_OPT_IDENTIFY_CARTRIDGE | BJC_OPT_MONOCHROME_SMOOTHING |\
+ BJC_OPT_EXTENDED_MARGINS |\
+ BJC_OPT_RESOLUTION_360 |\
+ BJC_OPT_X_Y_RESOLUTION | BJC_OPT_MOVE_LINES | BJC_OPT_CONTINUE_IMAGE)
+#define BJC_OPT_250\
+ (BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE | BJC_OPT_MONOCHROME_SMOOTHING |\
+ BJC_OPT_EXTENDED_MARGINS | BJC_OPT_PAGE_ID |\
+ BJC_OPT_RESOLUTION_360 | BJC_OPT_RESOLUTION_HALF |\
+ BJC_OPT_RESOLUTION_QUARTER | BJC_OPT_RESOLUTION_2X_1X |\
+ BJC_OPT_X_Y_RESOLUTION | BJC_OPT_MOVE_LINES | BJC_OPT_IMAGE_FORMAT |\
+ BJC_OPT_CONTINUE_IMAGE)
+#define BJC_OPT_610\
+ (BJC_OPT_LF |\
+ BJC_OPT_RESOLUTION_360)
+#define BJC_OPT_620\
+ BJC_OPT_610
+#define BJC_OPT_4000\
+ (BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE | BJC_OPT_MONOCHROME_SMOOTHING |\
+ BJC_OPT_RESOLUTION_360 | BJC_OPT_RESOLUTION_HALF |\
+ BJC_OPT_RESOLUTION_QUARTER)
+#define BJC_OPT_4100\
+ (BJC_OPT_IDENTIFY_CARTRIDGE |\
+ BJC_OPT_EXTENDED_MARGINS |\
+ BJC_OPT_RESOLUTION_360 |\
+ BJC_OPT_MOVE_LINES | BJC_OPT_CONTINUE_IMAGE)
+#define BJC_OPT_4200\
+ (BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE |\
+ BJC_OPT_EXTENDED_MARGINS | BJC_OPT_PAGE_ID |\
+ BJC_OPT_RESOLUTION_360 |\
+ BJC_OPT_MOVE_LINES | BJC_OPT_IMAGE_FORMAT | BJC_OPT_CONTINUE_IMAGE)
+#define BJC_OPT_4300\
+ BJC_OPT_250
+#define BJC_OPT_4550\
+ BJC_OPT_250
+#define BJC_OPT_4650\
+ BJC_OPT_250
+#define BJC_OPT_5500\
+ (BJC_OPT_IDENTIFY_CARTRIDGE | BJC_OPT_MONOCHROME_SMOOTHING |\
+ BJC_OPT_EXTENDED_MARGINS |\
+ BJC_OPT_RESOLUTION_360 |\
+ BJC_OPT_MOVE_LINES | BJC_OPT_CONTINUE_IMAGE)
+/* The 7000 is not well documented. The following is a semi-guess. */
+#define BJC_OPT_7000\
+ (BJC_OPT_NUL | BJC_OPT_LF |\
+ BJC_OPT_IDENTIFY_CARTRIDGE |\
+ BJC_OPT_EXTENDED_MARGINS | BJC_OPT_PAGE_ID |\
+ BJC_OPT_RESOLUTION_300 | BJC_OPT_RESOLUTION_2X_1X |\
+ BJC_OPT_RESOLUTION_4X_2X |\
+ BJC_OPT_MOVE_LINES | BJC_OPT_IMAGE_FORMAT | BJC_OPT_CONTINUE_IMAGE |\
+ BJC_OPT_INDEXED_IMAGE | BJC_OPT_SET_COLOR_COMPONENT)
+
+/*
+ * Enumerate the options for all the printer models we know about.
+ * m(x, y) will normally be {x, y}, to generate a table.
+ */
+#define BJC_ENUMERATE_OPTIONS(m)\
+ m(50, BJC_OPT_50)\
+ m(70, BJC_OPT_70)\
+ m(80, BJC_OPT_80)\
+ m(210, BJC_OPT_210)\
+ m(250, BJC_OPT_250)\
+ m(610, BJC_OPT_610)\
+ m(620, BJC_OPT_620)\
+ m(4000, BJC_OPT_4000)\
+ m(4100, BJC_OPT_4100)\
+ m(4200, BJC_OPT_4200)\
+ m(4300, BJC_OPT_4300)\
+ m(4550, BJC_OPT_4550)\
+ m(4650, BJC_OPT_4650)\
+ m(5500, BJC_OPT_5500)\
+ m(7000, BJC_OPT_7000)
+
+/* ---------------- Command generation ---------------- */
+
+/*
+ * Single-character commands.
+ */
+
+/* Carriage return (^M) */
+void bjc_put_CR(P1(stream *s));
+
+/* Form feed (^L) */
+void bjc_put_FF(P1(stream *s));
+
+/* Line feed (^J) */
+void bjc_put_LF(P1(stream *s));
+
+/*
+ * Session commands.
+ */
+
+/* Set initial condition */
+void bjc_put_initial_condition(P1(stream *s));
+
+/* Return to initial condition */
+void bjc_put_initialize(P1(stream *s));
+
+/* Select print method */
+/****** DIFFERENT FOR 7000 ******/
+typedef enum {
+ BJC_PRINT_COLOR_COLOR = 0x0,
+ BJC_PRINT_COLOR_MONOCHROME = 0x1,
+ BJC_PRINT_COLOR_MONOCHROME_WITH_SMOOTHING = 0x2 /* option */
+} bjc_print_color_t;
+typedef enum {
+ BJC_PRINT_MEDIA_PLAIN_PAPER = 0x0,
+ BJC_PRINT_MEDIA_COATED_PAPER = 0x1,
+ BJC_PRINT_MEDIA_TRANSPARENCY_FILM = 0x2,
+ BJC_PRINT_MEDIA_BACK_PRINT_FILM = 0x3,
+ BJC_PRINT_MEDIA_TEXTILE_SHEET = 0x4,
+ BJC_PRINT_MEDIA_GLOSSY_PAPER = 0x5,
+ BJC_PRINT_MEDIA_HIGH_GLOSS_FILM = 0x6,
+ BJC_PRINT_MEDIA_HIGH_RESOLUTION_PAPER = 0x7 /* BJC-80 only */
+} bjc_print_media_t;
+typedef enum {
+ BJC_PRINT_QUALITY_NORMAL = 0x0,
+ BJC_PRINT_QUALITY_HIGH = 0x1,
+ BJC_PRINT_QUALITY_DRAFT = 0x2,
+ BJC_PRINT_QUALITY_COLOR_NON_BLEED = 0x8 /* not 6x0 */
+} bjc_print_quality_t;
+typedef enum {
+ /* 6x0 only */
+ BJC_BLACK_DENSITY_NORMAL = 0x0,
+ BJC_BLACK_DENSITY_HIGH = 0x1
+} bjc_black_density_t;
+void bjc_put_print_method(P5(stream *s, bjc_print_color_t color,
+ bjc_print_media_t media,
+ bjc_print_quality_t quality,
+ bjc_black_density_t density));
+typedef enum {
+ /* 70, 4000, 4550, 4650 */
+ BJC_70_PRINT_COLOR_SHORT_FINE = 0x0, /* also 0x1, 0x2 */
+ BJC_70_PRINT_COLOR_SHORT_HQ = 0x3,
+ BJC_70_PRINT_COLOR_SHORT_ECO = 0x4,
+ /* 80, 250, 4200, 4300 */
+ BJC_80_PRINT_COLOR_SHORT_STD = 0x0,
+ BJC_80_PRINT_COLOR_SHORT_STD_SPECIALTY = 0x1,
+ BJC_80_PRINT_COLOR_SHORT_HQ_SPECIALTY = 0x2,
+ BJC_80_PRINT_COLOR_SHORT_HQ = 0x3,
+ BJC_80_PRINT_COLOR_SHORT_HIGH_SPEED = 0x4,
+ /* 210, 4100 */
+ BJC_210_PRINT_COLOR_SHORT_HQ = 0x0, /* also 0x1 */
+ BJC_210_PRINT_COLOR_SHORT_FINE = 0x2, /* also 0x3 */
+ BJC_210_PRINT_COLOR_SHORT_HIGH_SPEED = 0x4,
+ /* 5500 */
+ BJC_5500_PRINT_COLOR_SHORT_COATED = 0x0,
+ BJC_5500_PRINT_COLOR_SHORT_TRANSPARENCY = 0x1,
+ BJC_5500_PRINT_COLOR_SHORT_PLAIN = 0x2,
+ BJC_5500_PRINT_COLOR_SHORT_HQ_NON_BLEED = 0x3,
+ BJC_5500_PRINT_COLOR_SHORT_HIGH_SPEED = 0x4
+} bjc_print_color_short_t;
+void bjc_put_print_method_short(P2(stream *s, bjc_print_color_short_t color));
+
+/* Set media supply method */
+/****** DIFFERENT FOR 7000 ******/
+typedef enum {
+ /* 70, 210, 250, 6x0, 4100 */
+ BJC_70_MEDIA_SUPPLY_MANUAL_1 = 0x0,
+ BJC_70_MEDIA_SUPPLY_MANUAL_2 = 0x1,
+ BJC_70_MEDIA_SUPPLY_ASF = 0x4,
+ /* 250, 4000, 4300, 4650, 5500 */
+ BJC_250_MEDIA_SUPPLY_CONTINUOUS_FORM = 0x2,
+ BJC_250_MEDIA_SUPPLY_ASF_BIN_2 = 0x5,
+ /* 250, 4650, 5500 */
+ BJC_250_MEDIA_SUPPLY_AUTO_SWITCH = 0xf,
+ /* 4000, 4300, 4650 */
+ BJC_4000_MEDIA_SUPPLY_CASSETTE = 0x8,
+ /* 80 */
+ BJC_80_MEDIA_SUPPLY_ASF_OFFLINE = 0x0,
+ BJC_80_MEDIA_SUPPLY_ASF_ONLINE = 0x1 /* also 0x4 */
+} bjc_media_supply_t;
+typedef enum {
+ BJC_MEDIA_TYPE_PLAIN_PAPER = 0x0,
+ BJC_MEDIA_TYPE_COATED_PAPER = 0x1,
+ BJC_MEDIA_TYPE_TRANSPARENCY_FILM = 0x2,
+ BJC_MEDIA_TYPE_BACK_PRINT_FILM = 0x3,
+ BJC_MEDIA_TYPE_PAPER_WITH_LEAD = 0x4,
+ BJC_MEDIA_TYPE_TEXTILE_SHEET = 0x5,
+ BJC_MEDIA_TYPE_GLOSSY_PAPER = 0x6,
+ BJC_MEDIA_TYPE_HIGH_GLOSS_FILM = 0x7,
+ BJC_MEDIA_TYPE_ENVELOPE = 0x8,
+ BJC_MEDIA_TYPE_CARD = 0x9,
+ BJC_MEDIA_TYPE_HIGH_RESOLUTION_6X0 = 0xa, /* 6x0 only */
+ BJC_MEDIA_TYPE_HIGH_RESOLUTION = 0xb, /* 720x720, other models */
+ BJC_MEDIA_TYPE_FULL_BLEED = 0xc,
+ BJC_MEDIA_TYPE_BANNER = 0xd
+} bjc_media_type_t;
+void bjc_put_media_supply(P3(stream *s, bjc_media_supply_t supply,
+ bjc_media_type_t type));
+
+/* Identify ink cartridge */
+typedef enum {
+ BJC_IDENTIFY_CARTRIDGE_PREPARE = 0x0,
+ BJC_IDENTIFY_CARTRIDGE_REQUEST = 0x1
+} bjc_identify_cartridge_command_t;
+void bjc_put_identify_cartridge(P2(stream *s,
+ bjc_identify_cartridge_command_t command));
+
+/*
+ * Page commands.
+ */
+
+/* Set page margins */
+/* Left margin is 1-origin; margins are both from left edge; indent <= 8 */
+void bjc_put_page_margins(P5(stream *s, int length10ths, int lm10ths,
+ int rm10ths, int indent60ths));
+
+/* Set extended margins */
+/* All values are 0-origin; margins are both from left edge; indent <= 8 */
+void bjc_put_extended_margins(P5(stream *s, int length60ths, int lm60ths,
+ int rm60ths, int indent60ths));
+
+/* Page ID */
+/* 0 <= id <= 127 */
+void bjc_put_page_id(P2(stream *s, int id));
+
+/*
+ * Image commands.
+ */
+
+/* Set raster compression */
+typedef enum {
+ BJC_RASTER_COMPRESSION_NONE = 0x0,
+ BJC_RASTER_COMPRESSION_PACKBITS = 0x1
+} bjc_raster_compression_t;
+void bjc_put_compression(P2(stream *s, bjc_raster_compression_t compression));
+
+/* Set raster resolution */
+void bjc_put_raster_resolution(P3(stream *s, int x_resolution,
+ int y_resolution));
+
+/* Raster skip */
+/* Maximum skip on 6x0 and 4000 is 0x17ff */
+void bjc_put_raster_skip(P2(stream *s, int skip));
+
+/* CMYK raster image */
+typedef enum {
+ BJC_CMYK_IMAGE_CYAN = 'C',
+ BJC_CMYK_IMAGE_MAGENTA = 'M',
+ BJC_CMYK_IMAGE_YELLOW = 'Y',
+ BJC_CMYK_IMAGE_BLACK = 'K',
+} bjc_cmyk_image_component_t;
+void bjc_put_cmyk_image(P4(stream *s, bjc_cmyk_image_component_t component,
+ const byte *data, int count));
+
+/* Move by raster lines */
+/* Distance must be a multiple of the raster resolution */
+void bjc_put_move_lines(P2(stream *s, int lines));
+
+/* Set unit for movement by raster lines */
+/* unit = 360 for printers other than 7000 */
+/* unit = 300 or 600 for 7000 */
+void bjc_put_move_lines_unit(P2(stream *s, int unit));
+
+/* Set image format */
+/* depth is 1 or 2 */
+/****** DIFFERENT FOR 7000 ******/
+typedef enum {
+ BJC_IMAGE_FORMAT_REGULAR = 0x00,
+ BJC_IMAGE_FORMAT_INDEXED = 0x80
+} bjc_image_format_t;
+typedef enum {
+ BJC_INK_SYSTEM_REGULAR = 0x01,
+ BJC_INK_SYSTEM_PHOTO = 0x02,
+ BJC_INK_SYSTEM_REGULAR_DVM = 0x09, /* drop volume modulation */
+ BJC_INK_SYSTEM_PHOTO_DVM = 0x0a /* drop volume modulation */
+} bjc_ink_system_t;
+void bjc_put_image_format(P4(stream *s, int depth,
+ bjc_image_format_t format,
+ bjc_ink_system_t ink));
+/* 4550 only */
+void bjc_put_photo_image(P2(stream *s, bool photo));
+
+/* Continue raster image */
+void bjc_put_continue_image(P3(stream *s, const byte *data, int count));
+
+/* BJ indexed image */
+void bjc_put_indexed_image(P4(stream *s, int dot_rows, int dot_cols,
+ int layers));
+
+#endif /* gdevcbjc_INCLUDED */
diff --git a/gs/src/gdevbmp.c b/gs/src/gdevbmp.c
index 810e662e2..88bf208fa 100644
--- a/gs/src/gdevbmp.c
+++ b/gs/src/gdevbmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,15 +22,10 @@
#include "gdevpccm.h"
#include "gdevbmp.h"
-#define bmp_cmyk_procs(p_map_color_rgb, p_map_cmyk_color)\
- gdev_prn_open, NULL, NULL, gdev_prn_output_page, gdev_prn_close,\
- NULL, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\
- gdev_prn_get_params, gdev_prn_put_params,\
- p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device
-
/* ------ The device descriptors ------ */
private dev_proc_print_page(bmp_print_page);
+private dev_proc_print_page(bmp_cmyk_print_page);
/* Monochrome. */
@@ -41,6 +36,38 @@ prn_device(prn_std_procs, "bmpmono",
0, 0, 0, 0, /* margins */
1, bmp_print_page);
+/* 1-bit-per-plane separated CMYK color. */
+
+#define bmp_cmyk_procs(p_map_color_rgb, p_map_cmyk_color)\
+ gdev_prn_open, NULL, NULL, gdev_prn_output_page, gdev_prn_close,\
+ NULL, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\
+ gdev_prn_get_params, gdev_prn_put_params,\
+ p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device
+
+private gx_device_procs bmpsep1_procs = {
+ bmp_cmyk_procs(cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color)
+};
+gx_device_printer far_data gs_bmpsep1_device = {
+ prn_device_body(gx_device_printer, bmpsep1_procs, "bmpsep1",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0,0,0,0, /* margins */
+ 4, 4, 1, 1, 2, 2, bmp_cmyk_print_page)
+};
+
+/* 8-bit-per-plane separated CMYK color. */
+
+private gx_device_procs bmpsep8_procs = {
+ bmp_cmyk_procs(cmyk_8bit_map_color_rgb, cmyk_8bit_map_cmyk_color)
+};
+gx_device_printer far_data gs_bmpsep8_device = {
+ prn_device_body(gx_device_printer, bmpsep8_procs, "bmpsep8",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0,0,0,0, /* margins */
+ 4, 32, 255, 255, 256, 256, bmp_cmyk_print_page)
+};
+
/* 4-bit planar (EGA/VGA-style) color. */
private const gx_device_procs bmp16_procs =
@@ -78,10 +105,11 @@ prn_device(bmp16m_procs, "bmp16m",
0, 0, 0, 0, /* margins */
24, bmp_print_page);
+/* 32-bit CMYK color (outside the BMP specification). */
+
private const gx_device_procs bmp32b_procs = {
bmp_cmyk_procs(cmyk_8bit_map_color_rgb, gx_default_cmyk_map_cmyk_color)
};
-
gx_device_printer far_data gs_bmp32b_device =
prn_device(bmp32b_procs, "bmp32b",
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
@@ -92,7 +120,7 @@ prn_device(bmp32b_procs, "bmp32b",
/* ------ Private definitions ------ */
/* Write out a page in BMP format. */
-/* This routine is used for all formats. */
+/* This routine is used for all non-separated formats. */
private int
bmp_print_page(gx_device_printer * pdev, FILE * file)
{
@@ -125,3 +153,52 @@ done:
return code;
}
+
+/* Write out a page in separated CMYK format. */
+/* This routine is used for all formats. */
+private int
+bmp_cmyk_print_page(gx_device_printer * pdev, FILE * file)
+{
+ int plane_depth = pdev->color_info.depth / 4;
+ uint raster = bitmap_raster(pdev->width * plane_depth);
+ /* BMP scan lines are padded to 32 bits. */
+ uint bmp_raster = raster + (-raster & 3);
+ byte *row = (byte *)gs_malloc(bmp_raster, 1, "bmp file buffer");
+ int y;
+ int code = 0; /* return code */
+ int plane;
+
+ if (row == 0) /* can't allocate row buffer */
+ return_error(gs_error_VMerror);
+
+ for (plane = 0; plane <= 3; ++plane) {
+ gx_render_plane_t render_plane;
+
+ /* Write the page header. */
+
+ code = write_bmp_separated_header(pdev, file);
+ if (code < 0)
+ break;
+
+ /* Write the contents of the image. */
+ /* BMP files want the image in bottom-to-top order! */
+
+ gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
+ for (y = pdev->height - 1; y >= 0; y--) {
+ byte *actual_data;
+ uint actual_raster;
+
+ code = gdev_prn_get_lines(pdev, y, 1, row, bmp_raster,
+ &actual_data, &actual_raster,
+ &render_plane);
+ if (code < 0)
+ goto done;
+ fwrite((const char *)actual_data, bmp_raster, 1, file);
+ }
+ }
+
+done:
+ gs_free((char *)row, bmp_raster, 1, "bmp file buffer");
+
+ return code;
+}
diff --git a/gs/src/gdevbmp.h b/gs/src/gdevbmp.h
index 4bcba54c3..487523c82 100644
--- a/gs/src/gdevbmp.h
+++ b/gs/src/gdevbmp.h
@@ -29,6 +29,9 @@
/* Write the BMP file header. This procedure is used for all formats. */
int write_bmp_header(P2(gx_device_printer *pdev, FILE *file));
+/* Write a BMP header for separated CMYK output. */
+int write_bmp_separated_header(P2(gx_device_printer *pdev, FILE *file));
+
/* 24-bit color mappers */
dev_proc_map_rgb_color(bmp_map_16m_rgb_color);
dev_proc_map_color_rgb(bmp_map_16m_color_rgb);
diff --git a/gs/src/gdevbmpa.c b/gs/src/gdevbmpa.c
index a80f45d5d..6f18bc856 100644
--- a/gs/src/gdevbmpa.c
+++ b/gs/src/gdevbmpa.c
@@ -1,13 +1,13 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
-
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
+
This file is part of Aladdin Ghostscript.
-
+
Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
or distributor accepts any responsibility for the consequences of using it,
or for whether it serves any particular purpose or works at all, unless he
or she says so in writing. Refer to the Aladdin Ghostscript Free Public
License (the "License") for full details.
-
+
Every copy of Aladdin Ghostscript must include a copy of the License,
normally in a plain ASCII text file named PUBLIC. The License grants you
the right to copy, modify and redistribute Aladdin Ghostscript, but only
@@ -20,48 +20,66 @@
/* .BMP file format output drivers: Demo of ASYNC rendering */
/* Initial version 2/2/98 by John Desrosiers (soho@crl.com) */
-/* 7/28/98 ghost@aladdin.com - Factored out common BMP format code. */
-/* 12/1/98 soho@crl.com - Commented manual override of put_params procedure */
-/* - Incr'd image source row components from 3 -> 4 */
+/* 1998/7/28 ghost@aladdin.com - Factored out common BMP format code
+ to gdevbmpc.c */
+/* 1992/11/23 ghost@aladdin.com - Removed pointless restriction to
+ single-page output */
+/* 1998/12/29 ghost@aladdin.com - Modified to use gdev_prn_render_lines,
+ which replaces the former "overlay" calls */
+
#include "stdio_.h"
#include "gserrors.h"
#include "gdevprna.h"
#include "gdevpccm.h"
#include "gdevbmp.h"
+#include "gdevppla.h"
#include "gpsync.h"
+/*
+ * The original version of this driver was restricted to producing a single
+ * page per file. If for some reason you want to reinstate this
+ * restriction, uncomment the next line. Unfortunately, this seems to be
+ * necessary: even though the logic for multi-page files is straightforward,
+ * it doesn't work.
+ */
+#define SINGLE_PAGE
+
/* ------ The device descriptors ------ */
/* Define data type for this device based on prn_device */
typedef struct gx_device_async_s {
gx_device_common;
gx_prn_device_common;
+ bool UsePlanarBuffer;
int buffered_page_exists;
- long file_offset_to_data;
+ long file_offset_to_data[4];
+ long file_offset_to_page;
+#ifdef SINGLE_PAGE
int copies_printed;
+#endif
} gx_device_async;
/* Define initializer for device */
#define async_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\
{ prn_device_std_margins_body(gx_device_async, procs, dname,\
w10, h10, xdpi, ydpi, lm, tm, lm, bm, rm, tm, color_bits, print_page),\
- 0, 0L\
+ 0, 0, { 0 }, 0, 0\
}
private dev_proc_open_device(bmpa_writer_open);
+private dev_proc_open_device(bmpa_cmyk_writer_open);
private prn_dev_proc_open_render_device(bmpa_reader_open_render_device);
private dev_proc_print_page_copies(bmpa_reader_print_page_copies);
+/* VMS limits procedure names to 31 characters. */
+private dev_proc_print_page_copies(bmpa_cmyk_reader_print_copies);
private prn_dev_proc_buffer_page(bmpa_reader_buffer_page);
+private prn_dev_proc_buffer_page(bmpa_cmyk_reader_buffer_page);
private dev_proc_output_page(bmpa_reader_output_page);
-private dev_proc_put_params(bmpa_put_params);
private dev_proc_get_params(bmpa_get_params);
+private dev_proc_put_params(bmpa_put_params);
private dev_proc_get_hardware_params(bmpa_get_hardware_params);
private prn_dev_proc_start_render_thread(bmpa_reader_start_render_thread);
private prn_dev_proc_get_space_params(bmpa_get_space_params);
-private dev_proc_map_rgb_color(bmpa_forcemono_map_rgb_color);
-private dev_proc_map_color_rgb(bmpa_cmyk_map_color_rgb);
-private dev_proc_map_cmyk_color(bmpa_map_cmyk_color);
-
#define default_print_page 0 /* not needed becoz print_page_copies def'd */
/* Monochrome. */
@@ -75,7 +93,41 @@ gx_device_async far_data gs_bmpamono_device =
0,0,0,0, /* margins */
1, default_print_page);
-/* 4-bit planar (EGA/VGA-style) color. */
+/* 1-bit-per-plane separated CMYK color. */
+
+#define bmpa_cmyk_procs(p_open, p_map_color_rgb, p_map_cmyk_color)\
+ p_open, NULL, NULL, gdev_prn_output_page, gdev_prn_close,\
+ NULL, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\
+ bmpa_get_params, bmpa_put_params,\
+ p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device
+
+private gx_device_procs bmpasep1_procs = {
+ bmpa_cmyk_procs(bmpa_cmyk_writer_open, cmyk_1bit_map_color_rgb,
+ cmyk_1bit_map_cmyk_color)
+};
+gx_device_async far_data gs_bmpasep1_device = {
+ prn_device_body(gx_device_async, bmpasep1_procs, "bmpasep1",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0,0,0,0, /* margins */
+ 4, 4, 1, 1, 2, 2, default_print_page)
+};
+
+/* 8-bit-per-plane separated CMYK color. */
+
+private gx_device_procs bmpasep8_procs = {
+ bmpa_cmyk_procs(bmpa_cmyk_writer_open, cmyk_8bit_map_color_rgb,
+ cmyk_8bit_map_cmyk_color)
+};
+gx_device_printer far_data gs_bmpasep8_device = {
+ prn_device_body(gx_device_printer, bmpasep8_procs, "bmpasep8",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0,0,0,0, /* margins */
+ 4, 32, 255, 255, 256, 256, default_print_page)
+};
+
+/* 4-bit (EGA/VGA-style) color. */
private gx_device_procs bmpa16_procs =
prn_color_procs(bmpa_writer_open, gdev_prn_output_page, gdev_prn_close,
@@ -112,32 +164,18 @@ gx_device_async far_data gs_bmpa16m_device =
0,0,0,0, /* margins */
24, default_print_page);
-private const gx_device_procs bmpacmyk_procs =
-{ bmpa_writer_open, gx_default_get_initial_matrix, NULL,
- gdev_prn_output_page, gdev_prn_close,
- bmpa_forcemono_map_rgb_color, bmpa_cmyk_map_color_rgb,
- NULL, NULL, NULL, NULL, NULL, NULL,
- bmpa_get_params, bmpa_put_params,
- bmpa_map_cmyk_color,
- NULL, NULL, NULL,
- gx_page_device_get_page_device
-};
+/* 32-bit CMYK color (outside the BMP specification). */
-const gx_device_printer gs_bmpacmyk_device =
-{prn_device_body(gx_device_printer, bmpacmyk_procs, "bmpacmyk",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 4, 4, 1, 1, 2, 2, default_print_page)
+private const gx_device_procs bmpa32b_procs = {
+ bmpa_cmyk_procs(bmpa_writer_open, gx_default_map_color_rgb,
+ gx_default_cmyk_map_cmyk_color)
};
-
-/* 32-bit CMYK color (outside the BMP specification). */
gx_device_async far_data gs_bmpa32b_device =
-async_device(bmpacmyk_procs, "bmpa32b",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 32, default_print_page);
+ async_device(bmpa32b_procs, "bmpa32b",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 32, default_print_page);
/* --------- Forward declarations ---------- */
@@ -147,7 +185,9 @@ private void bmpa_reader_thread(P1(void *));
/* Writer's open procedure */
private int
-bmpa_writer_open(gx_device *pdev /* Driver instance to open */)
+bmpa_open_writer(gx_device *pdev /* Driver instance to open */,
+ dev_proc_print_page_copies((*reader_print_page_copies)),
+ prn_dev_proc_buffer_page((*reader_buffer_page)))
{
gx_device_async * const pwdev = (gx_device_async *)pdev;
int max_width;
@@ -160,9 +200,10 @@ bmpa_writer_open(gx_device *pdev /* Driver instance to open */)
* there are no convenient macros for setting them up in static template.
*/
init_async_render_procs(pwdev, bmpa_reader_start_render_thread,
- bmpa_reader_buffer_page,
- bmpa_reader_print_page_copies);
- set_dev_proc(pdev, put_params, bmpa_put_params); /* because not all device-init macros allow this to be defined */
+ reader_buffer_page,
+ reader_print_page_copies);
+ set_dev_proc(pdev, get_params, bmpa_get_params); /* because not all device-init macros allow this to be defined */
+ set_dev_proc(pdev, put_params, bmpa_put_params); /* ibid. */
set_dev_proc(pdev, get_hardware_params, bmpa_get_hardware_params);
set_dev_proc(pdev, output_page, bmpa_reader_output_page); /* hack */
pwdev->printer_procs.get_space_params = bmpa_get_space_params;
@@ -178,17 +219,39 @@ bmpa_writer_open(gx_device *pdev /* Driver instance to open */)
max_raster = bitmap_raster(max_width * pwdev->color_info.depth); /* doesn't need to be super accurate */
max_src_image_row = max_width * 4 * 2;
+ /* Set to planar buffering mode if appropriate. */
+ if (pwdev->UsePlanarBuffer)
+ gdev_prn_set_procs_planar(pdev);
+
/* Special writer open routine for async interpretation */
/* Starts render thread */
return gdev_prn_async_write_open((gx_device_printer *)pdev,
max_raster, min_band_height,
max_src_image_row);
}
+private int
+bmpa_writer_open(gx_device *pdev /* Driver instance to open */)
+{
+ return bmpa_open_writer(pdev, bmpa_reader_print_page_copies,
+ bmpa_reader_buffer_page);
+}
+private int
+bmpa_cmyk_writer_open(gx_device *pdev /* Driver instance to open */)
+{
+ return bmpa_open_writer(pdev, bmpa_cmyk_reader_print_copies,
+ bmpa_cmyk_reader_buffer_page);
+}
/* -------------- Renderer instance procedures ----------*/
+/* Forward declarations */
+private int
+ bmpa_reader_buffer_planes(P6(gx_device_printer *pdev, FILE *prn_stream,
+ int num_copies, int first_plane,
+ int last_plane, int raster));
+
/* Thread to do rendering, started by bmpa_reader_start_render_thread */
-private void
+private void
bmpa_reader_thread(void *params)
{
gdev_prn_async_render_thread((gdev_prn_start_render_params *)params);
@@ -203,6 +266,14 @@ bmpa_reader_start_render_thread(gdev_prn_start_render_params *params)
private int
bmpa_reader_open_render_device(gx_device_printer *ppdev)
{
+ gx_device_async * const prdev = (gx_device_async *)ppdev;
+
+ /* Do anything that needs to be done at open time here... */
+#ifdef SINGLE_PAGE
+ prdev->copies_printed = 0;
+#endif
+ prdev->file_offset_to_page = 0;
+
/* Cascade down to the default handler */
return gdev_prn_async_render_open(ppdev);
}
@@ -225,20 +296,33 @@ bmpa_reader_output_page(gx_device *pdev, int num_copies, int flush)
}
private int
-bmpa_reader_print_page(gx_device_printer *pdev, FILE *prn_stream, int num_copies)
+bmpa_reader_print_planes(gx_device_printer *pdev, FILE *prn_stream,
+ int num_copies, int first_plane, int last_plane,
+ int raster)
{
gx_device_async * const prdev = (gx_device_async *)pdev;
- gx_device * const dev = (gx_device *)pdev;
- uint raster = gdev_prn_raster(pdev);
/* BMP scan lines are padded to 32 bits. */
uint bmp_raster = raster + (-raster & 3);
int code = 0;
int y;
byte *row = 0;
byte *raster_data;
+ int plane;
+#ifdef SINGLE_PAGE
+ /*
+ * BMP format is single page, so discard all but 1st printable page
+ * This logic isn't quite right, since we can't truncate file if
+ * num_pages == 0.
+ */
+ if (prdev->copies_printed > 0)
+ return 0;
+#endif
+
+ /* If there's data in buffer, need to process w/overlays */
if (prdev->buffered_page_exists) {
- code = bmpa_reader_buffer_page(pdev, prn_stream, num_copies);
+ code = bmpa_reader_buffer_planes(pdev, prn_stream, num_copies,
+ first_plane, last_plane, raster);
goto done;
}
@@ -246,137 +330,246 @@ bmpa_reader_print_page(gx_device_printer *pdev, FILE *prn_stream, int num_copies
if (row == 0) /* can't allocate row buffer */
return_error(gs_error_VMerror);
- /* Write header & seek to its end */
- fseek(prn_stream, 0L, SEEK_SET);
- code = write_bmp_header(pdev, prn_stream);
- if (code < 0)
- goto done;
- /* Save the file offset where data begins */
- if ((prdev->file_offset_to_data = ftell(prn_stream)) == -1L) {
- code = gs_note_error(gs_error_ioerror);
- goto done;
- }
+ fseek(prn_stream, prdev->file_offset_to_page, SEEK_SET);
- /*
- * Write out the bands top to bottom.
- */
- for (y = prdev->height - 1; y >= 0; y--) {
- if ((code = dev_proc(dev, get_bits)(dev, y, row, &raster_data)) < 0)
+ for (plane = first_plane; plane <= last_plane; ++plane) {
+ gx_render_plane_t render_plane;
+
+ /* Write header & seek to its end */
+ code =
+ (first_plane < 0 ? write_bmp_header(pdev, prn_stream) :
+ write_bmp_separated_header(pdev, prn_stream));
+ if (code < 0)
goto done;
- if (fwrite((const char *)raster_data, bmp_raster, 1, prn_stream) < 1) {
- code = gs_error_ioerror;
+ /* Save the file offset where data begins */
+ if ((prdev->file_offset_to_data[plane - first_plane] =
+ ftell(prn_stream)) == -1L) {
+ code = gs_note_error(gs_error_ioerror);
goto done;
}
+
+ /*
+ * Write out the bands top to bottom. Finish the job even if
+ * num_copies == 0, to avoid invalid output file.
+ */
+ if (plane >= 0)
+ gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
+ for (y = prdev->height - 1; y >= 0; y--) {
+ uint actual_raster;
+
+ code = gdev_prn_get_lines(pdev, y, 1, row, bmp_raster,
+ &raster_data, &actual_raster,
+ (plane < 0 ? NULL : &render_plane));
+ if (code < 0)
+ goto done;
+ if (fwrite((const char *)raster_data, actual_raster, 1, prn_stream) < 1) {
+ code = gs_error_ioerror;
+ goto done;
+ }
+ }
}
done:
gs_free((char *)row, bmp_raster, 1, "bmp file buffer");
+#ifdef SINGLE_PAGE
+ if (code >= 0 && prdev->copies_printed > 0)
+ prdev->copies_printed = num_copies;
+#else
+ /* Save the file offset of the start of the next page. */
+ {
+ long offset = ftell(prn_stream);
+
+ if (offset == -1)
+ code = gs_note_error(gs_error_ioerror);
+ else
+ prdev->file_offset_to_page = offset;
+ }
+#endif
prdev->buffered_page_exists = 0;
return code;
}
-
private int
bmpa_reader_print_page_copies(gx_device_printer *pdev, FILE *prn_stream,
- int num_copies)
+ int num_copies)
{
- int code = 0;
- while ( num_copies-- ) {
- code = bmpa_reader_print_page(pdev, prn_stream, num_copies);
- if ( code < 0 )
- return (code);
- }
- return code;
+ return bmpa_reader_print_planes(pdev, prn_stream, num_copies, -1, -1,
+ gdev_prn_raster(pdev));
+}
+private int
+bmpa_cmyk_plane_raster(gx_device_printer *pdev)
+{
+ return bitmap_raster(pdev->width * (pdev->color_info.depth / 4));
+}
+private int
+bmpa_cmyk_reader_print_copies(gx_device_printer *pdev, FILE *prn_stream,
+ int num_copies)
+{
+ return bmpa_reader_print_planes(pdev, prn_stream, num_copies, 0, 3,
+ bmpa_cmyk_plane_raster(pdev));
}
/* Buffer a (partial) rasterized page & optionally print result multiple times. */
private int
-bmpa_reader_buffer_page(gx_device_printer *pdev, FILE *file, int num_copies)
+bmpa_reader_buffer_planes(gx_device_printer *pdev, FILE *file, int num_copies,
+ int first_plane, int last_plane, int raster)
{
gx_device_async * const prdev = (gx_device_async *)pdev;
gx_device * const dev = (gx_device *)pdev;
int code = 0;
+#ifdef SINGLE_PAGE
+ /* BMP format is single page, so discard all but 1st page */
+ if (prdev->copies_printed > 0)
+ return 0;
+#endif
+
/* If there's no data in buffer, no need to do any overlays */
if (!prdev->buffered_page_exists) {
- code = bmpa_reader_print_page_copies(pdev, file, num_copies);
+ code = bmpa_reader_print_planes(pdev, file, num_copies,
+ first_plane, last_plane, raster);
goto done;
}
/*
- * Overlay file's bits on top of existing file There are two choices for
- * doing this: get_overlay_bits vs. the combination of
- * locate_overlay_buffer and get_bits. If you already have a buffer in a
- * format compatible with GS's format, use get_overlay_bits. If you'd
- * rather use the buffer already in the device, use
- * locate_overlay_buffer, copy the bits into the returned buffer, then
- * get_bits.
+ * Continue rendering on top of the existing file. This requires setting
+ * up a buffer of the existing bits in GS's format (except for optional
+ * extra padding bytes at the end of each scan line, provided the scan
+ * lines are still correctly memory-aligned) and then calling
+ * gdev_prn_render_lines. If the device already provides a band buffer
+ * -- which currently is always the case -- we can use it if we want;
+ * but if a device stores partially rendered pages in memory in a
+ * compatible format (e.g., a printer with a hardware page buffer), it
+ * can render directly on top of the stored bits.
*
- * Either way, try to do entire bands at a shot for much greater
- * efficiency.
+ * If we can render exactly one band (or N bands) at a time, this is
+ * more efficient, since otherwise (a) band(s) will have to be rendered
+ * more than once.
*/
- /* Seek to beginning of data portion of file */
- if (fseek(file, prdev->file_offset_to_data, SEEK_SET)) {
- code = gs_note_error(gs_error_ioerror);
- goto done;
- }
-
{
byte *raster_data;
+ gx_device_clist_reader *const crdev =
+ (gx_device_clist_reader *)pdev;
int raster = gx_device_raster(dev, 1);
- ulong bmp_raster = raster + (-raster & 3); /* BMP scan lines are padded to 32 bits. */
- int max_band_height =
- (*pdev->printer_procs.locate_overlay_buffer)(pdev, 0, &raster_data);
- int band;
- int file_raster_good = min(raster, bmp_raster);
- long file_raster_slop = bmp_raster - file_raster_good;
+ int padding = -raster & 3; /* BMP scan lines are padded to 32 bits. */
+ int bmp_raster = raster + padding;
+ int plane;
/*
- * iterate thru bands from top to bottom.
- * Do this an entire band at a time for efficiency.
+ * Get the address of the renderer's band buffer. In the future,
+ * it will be possible to suppress the allocation of this buffer,
+ * and to use only buffers provided the driver itself (e.g., a
+ * hardware buffer).
*/
- for (band = (pdev->height - 1) / max_band_height; band >= 0; --band) {
- int band_base_line = max_band_height * band;
- int band_height = (*pdev->printer_procs.locate_overlay_buffer)
- (pdev, band_base_line, &raster_data);
- int line;
-
- /* Fill in overlay buffer with a band from the BMP file. */
- /* Need to do this backward since BMP is top to bottom */
- for (line = band_height - 1; line >= 0; --line)
- if (fread(raster_data + line * bmp_raster,
- file_raster_good, 1, file) < 1 ||
- fseek(file, file_raster_slop, SEEK_CUR)
- ) {
- code = gs_note_error(gs_error_ioerror);
- goto done;
- }
+ if (!pdev->buffer_space) {
+ /* Not banding. Can't happen. */
+ code = gs_note_error(gs_error_Fatal);
+ goto done;
+ }
+ raster_data = crdev->data;
+
+ for (plane = first_plane; plane <= last_plane; ++plane) {
+ gx_render_plane_t render_plane;
+ gx_device *bdev;
+ int y, band_base_line;
- /* Rewind & write out buffer with contents of get_bits */
- if (fseek(file,
- -(file_raster_good + file_raster_slop) * band_height,
- SEEK_CUR)) {
+ /* Seek to beginning of data portion of file */
+ if (fseek(file, prdev->file_offset_to_data[plane - first_plane],
+ SEEK_SET)) {
code = gs_note_error(gs_error_ioerror);
goto done;
}
- for (line = band_height - 1; line >= 0; --line) {
- if ((code = dev_proc(dev, get_bits)
- (dev, line + band_base_line, 0, &raster_data)) < 0
- )
- goto done;
- if (fwrite(raster_data, file_raster_good, 1, file) < 1 ||
- fseek(file, file_raster_slop, SEEK_CUR)
- ) {
+
+ if (plane >= 0)
+ gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
+ else
+ render_plane.index = -1;
+
+ /* Set up the buffer device. */
+ code = gdev_create_buf_device(crdev->buf_procs.create_buf_device,
+ &bdev, crdev->target, &render_plane,
+ dev->memory, true);
+ if (code < 0)
+ goto done;
+
+ /*
+ * Iterate thru bands from top to bottom. As noted above, we
+ * do this an entire band at a time for efficiency.
+ */
+ for (y = dev->height - 1; y >= 0; y = band_base_line - 1) {
+ int band_height =
+ dev_proc(dev, get_band)(dev, y, &band_base_line);
+ int line;
+ gs_int_rect band_rect;
+
+ /* Set up the buffer device for this band. */
+ code = crdev->buf_procs.setup_buf_device
+ (bdev, raster_data, bmp_raster, NULL, 0, band_height,
+ band_height);
+ if (code < 0)
+ goto done;
+
+ /* Fill in the buffer with a band from the BMP file. */
+ /* Need to do this backward since BMP is top to bottom. */
+ for (line = band_height - 1; line >= 0; --line)
+ if (fread(raster_data + line * bmp_raster,
+ raster, 1, file) < 1 ||
+ fseek(file, padding, SEEK_CUR)
+ ) {
+ code = gs_note_error(gs_error_ioerror);
+ goto done;
+ }
+
+ /* Continue rendering on top of the existing bits. */
+ band_rect.p.x = 0;
+ band_rect.p.y = band_base_line;
+ band_rect.q.x = pdev->width;
+ band_rect.q.y = band_base_line + band_height;
+ if ((code = clist_render_rectangle((gx_device_clist *)pdev,
+ &band_rect, bdev,
+ &render_plane, false)) < 0)
+ goto done;
+
+ /* Rewind & write out the updated buffer. */
+ if (fseek(file, -bmp_raster * band_height, SEEK_CUR)) {
code = gs_note_error(gs_error_ioerror);
goto done;
}
+ for (line = band_height - 1; line >= 0; --line) {
+ if (fwrite(raster_data + line * bmp_raster,
+ bmp_raster, 1, file) < 1 ||
+ fseek(file, padding, SEEK_CUR)
+ ) {
+ code = gs_note_error(gs_error_ioerror);
+ goto done;
+ }
+ }
+ crdev->buf_procs.destroy_buf_device(bdev);
}
}
}
done:
+#ifdef SINGLE_PAGE
+ if (code >= 0 && prdev->copies_printed > 0)
+ prdev->copies_printed = num_copies;
+#endif
prdev->buffered_page_exists = (code >= 0);
return code;
}
+private int
+bmpa_reader_buffer_page(gx_device_printer *pdev, FILE *prn_stream,
+ int num_copies)
+{
+ return bmpa_reader_buffer_planes(pdev, prn_stream, num_copies, -1, -1,
+ gdev_prn_raster(pdev));
+}
+private int
+bmpa_cmyk_reader_buffer_page(gx_device_printer *pdev, FILE *prn_stream,
+ int num_copies)
+{
+ return bmpa_reader_buffer_planes(pdev, prn_stream, num_copies, 0, 3,
+ bmpa_cmyk_plane_raster(pdev));
+}
/*------------ Procedures common to writer & renderer -------- */
@@ -404,7 +597,7 @@ bmpa_get_space_params(const gx_device_printer *pdev,
* other parts are redivided and used differently writing and
* rasterizing. The limiting factor dictating memory requirements is the
* rasterizer's render buffer. This buffer needs to be able to contain
- * a bitmap that covers an entire band. Memory consumption is whatever
+ * a pixmap that covers an entire band. Memory consumption is whatever
* is needed to hold N rows of data aligned on word boundaries, +
* sizeof(pointer) for each of N rows. Whatever is left over in the
* rasterized is allocated to a tile cache. You want to make sure that
@@ -443,7 +636,7 @@ bmpa_get_space_params(const gx_device_printer *pdev,
*
* The moral of the story is that you should never make a band
* so small that its buffer limits the command buffer excessively.
- * Again, Max image row bytes = band buffer size - # bands * 72.
+ * Again, Max image row bytes = band buffer size - # bands * 72.
*
* In the overlapped case, everything is exactly as above, except that
* two identical devices, each with an identical buffer, are allocated:
@@ -477,10 +670,10 @@ bmpa_get_space_params(const gx_device_printer *pdev,
* Note: per the comments in gxclmem.c, the banding logic will perform
* better with 1MB or better for the command list.
*/
-
+
/* This will give us a very "ungenerous" buffer. */
/* Here, my arbitrary rule for min image row is: twice the dest width */
- /* in full RGB. */
+ /* in full CMYK. */
int render_space;
int writer_space;
const int tile_cache_space = 50 * 1024;
@@ -498,121 +691,47 @@ bmpa_get_space_params(const gx_device_printer *pdev,
/* need to include minimal writer requirements to satisfy rasterizer init */
writer_space = /* add 5K slop for good measure */
5000 + (72 + 8) * ( (pdev->height / space_params->band.BandHeight) + 1 );
-
- /* Force reader & writer to match until other logic is changed to */
- /* allow these values to differ. Include the min_row_space in the */
- /* calculation of the write space needed */
+ space_params->band.BandBufferSpace =
+ max(render_space, writer_space) + tile_cache_space;
space_params->BufferSpace =
max(render_space, writer_space + min_row_space) + tile_cache_space;
- space_params->band.BandBufferSpace = space_params->BufferSpace;
-
+ /**************** HACK HACK HACK ****************/
+ /* Override this computation to force reader & writer to match */
+ space_params->BufferSpace = space_params->band.BandBufferSpace;
}
-
-/* The following macro is used in get_params and put_params to determine */
-/* the num_components for the current device. It works using the device */
-/* name character after "bmpa" which is 'm' for monochrome, 'c' or '3' */
-/* CMYK, and '1', or '2' for RGB. Any devices that are added to this */
-/* module must modify this macro to return the correct num_components. */
-/* This is needed to support the ForceMono parameter which alters */
-/* dev->num_components. */
-#define REAL_NUM_COMPONENTS(dev) \
- ((dev->dname[4]=='c' || dev->dname[4]=='3') ? 4 : \
- (dev->dname[4]=='m') ? 1 : 3)
-
-/* The only non-standard parameter is ForceMono */
+/* Get device parameters. */
private int
bmpa_get_params(gx_device * pdev, gs_param_list * plist)
{
- /*
- * The following is a hack to get the original num_components.
- * See comment above.
- */
- int real_ncomps = REAL_NUM_COMPONENTS(pdev);
- int code, ecode;
- int ncomps = pdev->color_info.num_components;
- int forcemono = (ncomps == real_ncomps) ? 0 : 1;
-
- /*
- * Temporarily set num_components back to the "real" value to avoid
- * confusing those that rely on it.
- */
- pdev->color_info.num_components = real_ncomps;
- ecode = gdev_prn_get_params(pdev, plist);
+ gx_device_async * const bdev = (gx_device_async *)pdev;
- if ((code = param_write_int(plist, "ForceMono", &forcemono)) < 0) {
- ecode = code;
- }
-
- /* Restore the working num_components */
- pdev->color_info.num_components = ncomps;
-
- return ecode;
+ return gdev_prn_get_params_planar(pdev, plist, &bdev->UsePlanarBuffer);
}
/* Put device parameters. */
/* IMPORTANT: async drivers must NOT CLOSE the device while doing put_params.*/
-
+/* IMPORTANT: async drivers must NOT CLOSE the device while doing put_params.*/
+/* IMPORTANT: async drivers must NOT CLOSE the device while doing put_params.*/
+/* IMPORTANT: async drivers must NOT CLOSE the device while doing put_params.*/
private int
bmpa_put_params(gx_device *pdev, gs_param_list *plist)
-/* ForceMono=1 forces monochrome output from RGB/CMYK devices. */
{
- gx_device_color_info save_info;
- int real_ncomps = REAL_NUM_COMPONENTS(pdev);
- int ncomps = pdev->color_info.num_components;
- int v;
- int ecode = 0;
- int code;
- const char *vname;
-
/*
- * Temporarily set num_components back to the "real" value to avoid
- * confusing those that rely on it.
+ * This driver does nothing interesting except cascade down to
+ * gdev_prn_put_params_planar, which is something it would have to do
+ * even if it did do something interesting here.
+ *
+ * Note that gdev_prn_put_params[_planar] does not close the device.
*/
- pdev->color_info.num_components = real_ncomps;
-
- switch (code = param_read_int(plist, (vname = "ForceMono"), &v)) {
- case 0:
- if (v == 1) {
- ncomps = 1;
- break;
- }
- else if (v == 0)
- break;
- code = gs_error_rangecheck;
- default:
- ecode = code;
- param_signal_error(plist, vname, ecode);
- case 1:
- break;
- }
- if (ecode < 0)
- return ecode;
+ gx_device_async * const bdev = (gx_device_async *)pdev;
- ecode = gdev_prn_put_params(pdev, plist);
- if (ecode < 0)
- return ecode;
-
- /* Now change num_components -- couldn't above because */
- /* '1' is special in gx_default_put_params */
- pdev->color_info.num_components = ncomps;
-
-
- /* Reset the map_cmyk_color procedure if appropriate. */
- if (dev_proc(pdev, map_cmyk_color) == cmyk_1bit_map_cmyk_color ||
- dev_proc(pdev, map_cmyk_color) == cmyk_8bit_map_cmyk_color ||
- dev_proc(pdev, map_cmyk_color) == bmpa_map_cmyk_color) {
- set_dev_proc(pdev, map_cmyk_color,
- pdev->color_info.depth == 4 ? cmyk_1bit_map_cmyk_color :
- pdev->color_info.depth == 32 ? cmyk_8bit_map_cmyk_color :
- bmpa_map_cmyk_color);
- }
- return 0;
+ return gdev_prn_put_params_planar(pdev, plist, &bdev->UsePlanarBuffer);
}
/* Get hardware-detected parameters. */
/* This proc defines a only one param: a useless value for testing */
-int
+private int
bmpa_get_hardware_params(gx_device *dev, gs_param_list *plist)
{
static const char *const test_value = "Test value";
@@ -627,64 +746,3 @@ bmpa_get_hardware_params(gx_device *dev, gs_param_list *plist)
}
return code;
}
-
-/* Map CMYK to color. */
-private gx_color_index
-bmpa_map_cmyk_color(gx_device * dev, gx_color_value cyan,
- gx_color_value magenta, gx_color_value yellow, gx_color_value black)
-{
- int bpc = dev->color_info.depth / 4;
- int drop = sizeof(gx_color_value) * 8 - bpc;
- gx_color_index color =
- ((((((cyan >> drop) << bpc) +
- (magenta >> drop)) << bpc) +
- (yellow >> drop)) << bpc) +
- (black >> drop);
-
- return (color == gx_no_color_index ? color ^ 1 : color);
-}
-
-/* Map RGB to gray shade. */
-/* Only used in CMYK mode when put_params has set ForceMono=1 */
-private gx_color_index
-bmpa_forcemono_map_rgb_color(gx_device * dev, gx_color_value red,
- gx_color_value green, gx_color_value blue)
-{
- gx_color_value color;
- int bpc = dev->color_info.depth / 4; /* This function is used in CMYK mode */
- int drop = sizeof(gx_color_value) * 8 - bpc;
- gx_color_value gray = red;
-
- if ((red != green) || (green != blue))
- gray = (red*30 + green*59 + blue*11 + 50) / 100;
-
- color = (gx_max_color_value - gray) >> drop; /* color is in K channel */
- return color;
-}
-
-/* Map CMYK to RGB. */
-private int
-bmpa_cmyk_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value rgb[3])
-{
- int depth = dev->color_info.depth;
- int bpc = depth / 4;
- uint mask = (1 << bpc) - 1;
- gx_color_index cshift = color;
- uint c, m, y, k;
-
-#define cvalue(c) ((gx_color_value)((ulong)(c) * gx_max_color_value / mask))
-
- k = cshift & mask;
- cshift >>= bpc;
- y = cshift & mask;
- cshift >>= bpc;
- m = cshift & mask;
- c = cshift >> bpc;
- /* We use our improved conversion rule.... */
- rgb[0] = cvalue((mask - c) * (mask - k) / mask);
- rgb[1] = cvalue((mask - m) * (mask - k) / mask);
- rgb[2] = cvalue((mask - y) * (mask - k) / mask);
- return 0;
-#undef cvalue
-}
-
diff --git a/gs/src/gdevbmpc.c b/gs/src/gdevbmpc.c
index 7e287836c..3633d1649 100644
--- a/gs/src/gdevbmpc.c
+++ b/gs/src/gdevbmpc.c
@@ -95,14 +95,14 @@ typedef struct bmp_quad_s {
} bmp_quad;
/* Write the BMP file header. */
-int
-write_bmp_header(gx_device_printer *pdev, FILE *file)
+private int
+write_bmp_depth_header(gx_device_printer *pdev, FILE *file, int depth,
+ const byte *palette /* [4 << depth] */,
+ int raster)
{
- int raster = gdev_prn_raster(pdev);
/* BMP scan lines are padded to 32 bits. */
ulong bmp_raster = raster + (-raster & 3);
int height = pdev->height;
- int depth = pdev->color_info.depth;
int quads = (depth <= 8 ? sizeof(bmp_quad) << depth : 0);
/* Write the file header. */
@@ -151,6 +151,19 @@ write_bmp_header(gx_device_printer *pdev, FILE *file)
/* Write the palette. */
+ if (depth <= 8)
+ fwrite(palette, sizeof(bmp_quad), 1 << depth, file);
+
+ return 0;
+}
+
+/* Write the BMP file header. */
+int
+write_bmp_header(gx_device_printer *pdev, FILE *file)
+{
+ int depth = pdev->color_info.depth;
+ bmp_quad palette[256];
+
if (depth <= 8) {
int i;
gx_color_value rgb[3];
@@ -163,11 +176,32 @@ write_bmp_header(gx_device_printer *pdev, FILE *file)
q.red = gx_color_value_to_byte(rgb[0]);
q.green = gx_color_value_to_byte(rgb[1]);
q.blue = gx_color_value_to_byte(rgb[2]);
- fwrite((const char *)&q, sizeof(q), 1, file);
+ palette[i] = q;
}
}
+ return write_bmp_depth_header(pdev, file, depth, (const byte *)palette,
+ gdev_prn_raster(pdev));
+}
- return 0;
+/* Write a BMP header for separated CMYK output. */
+int
+write_bmp_separated_header(gx_device_printer *pdev, FILE *file)
+{
+ int depth = pdev->color_info.depth;
+ int plane_depth = depth / 4;
+ bmp_quad palette[256];
+ bmp_quad q;
+ int i;
+
+ q.reserved = 0;
+ for (i = 0; i < 1 << plane_depth; i++) {
+ q.red = q.green = q.blue =
+ 255 - i * 255 / ((1 << plane_depth) - 1);
+ palette[i] = q;
+ }
+ return write_bmp_depth_header(pdev, file, plane_depth,
+ (const byte *)palette,
+ bitmap_raster(pdev->width * plane_depth));
}
/* 24-bit color mappers (taken from gdevmem2.c). */
diff --git a/gs/src/gdevcd8.c b/gs/src/gdevcd8.c
new file mode 100644
index 000000000..14377be65
--- /dev/null
+++ b/gs/src/gdevcd8.c
@@ -0,0 +1,2852 @@
+/*
+ Copyright (C) 1996-1998 <Uli Wortmann uliw@erdw.ethz.ch>
+ Portions Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ 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.
+
+ This program may also be distributed as part of Aladdin Ghostscript,
+ under the terms of the Aladdin Free Public License (the "License").
+
+ Every copy of Aladdin Ghostscript must include a copy of the
+ License, normally in a plain ASCII text file named PUBLIC. The
+ License grants you the right to copy, modify and redistribute
+ Aladdin Ghostscript, but only under certain conditions described in
+ the License. Among other things, the License requires that the
+ copyright notice and this notice be preserved on all copies.
+ */
+
+
+/* gdevcd8.c */
+
+/*----------------------------------------------------------------
+
+ A printer driver for the HP670, HP690, HP850, HP855
+ HP870, HP890, HP1100 and HP1600 color printers.
+ To be used with the Ghostscript printing system.
+ Please report all problems to uliw@erdw.ethz.ch
+
+ CREDITS: Much of the driver is based on ideas derived
+ from the cdj550 driver of George Cameron.
+
+ The support for the hp670, hp690, hp890
+ and hp1600 was added by Martin Gerbershagen.
+
+-------------------------------------------------------------------*/
+
+/* Note: Depending on how you transfered the files,
+ you might need to remove some CR-codes used on intel-based machines:
+
+ simply type: unzip -a hp850.zip
+
+ to compile with gs5.x, simply add
+
+ DEVICE_DEVS4=cdj850.dev cdj670.dev cdj890.dev cdj1600.dev
+
+ to your makefile.
+
+ BTW, it is always a good idea to read Make.htm found in the
+ gs-distrib before attempting to recompile.....
+
+ */
+
+/* 1999-01-07 edited by L. Peter Deutsch <ghost@aladdin.com> to eliminate
+ non-const statics and otherwise bring up to date with Ghostscript coding
+ style guidelines. */
+
+/* 01.06.98 Version 1.3 Due to the most welcome contribution
+ of Martin Gerbershagen (ger@ulm.temic.de),
+ support for the hp670, hp690 and hp890
+ and hp1600 has been added. Martin has also
+ resolved all known bugs.
+
+ Problems : Dark colors are still pale.
+
+
+ The driver no longer needs special switches to be invoked
+ except -sDEVICE=cdj850, or -sDEVICE=CDJ890, or sDEVICE=CDJ670
+ or -sDEVICE=CDJ1600
+
+ The hp690 is supported through the hp670 device, the hp855, hp870
+ and the hp1100 through the hp850 device.
+
+ The driver implements the following switches:
+
+ -dPapertype= 0 plain paper [default]
+ 1 bond paper
+ 2 special paper
+ 3 glossy film
+ 4 transparency film
+
+ Note, currently the lookuptables are not suited
+ for printing on special paper or transperencies.
+ Please revert to the gamma functions in this case.
+
+ -dQuality= -1 draft
+ 0 normal [default]
+ 1 presentation
+
+ -dRetStatus= 0 C-RET off
+ 1 C-RET on [default]
+
+ -dMasterGamma= 3.0 [default = 1.0]
+ __Note__: To take advantage of the calibrated color-transfer
+ functions, be sure not to have any Gamma-Statements
+ left! If you need to (i.e. overhead sheets),
+ you still can use the gamma-functions, but they will
+ override the built-in calibration. To use gamma in the
+ traditional way, set MasterGamma to any value greater
+ 1.0 and less 10.0. To adjust individual gamma-values,
+ you have to additionally set MasterGamma to a value
+ greater 1.0 and less 10.0
+
+ With the next release, gamma functions will be dropped.
+
+ When using the driver, be aware that printing in 600dpi involves
+ processing of large amounts of data (> 188MB !). Therefore, the
+ driver is not what you would expect to be a fast driver ;-)
+ This is no problem when printing a full sized color page (because
+ printing itself is slow), but it's really annoying if yoy print only
+ text pages. Maybe I can optimize the code for text-only pages in a
+ later release. Right now, it is recommended to use the highest
+ possible optimisation level your compiler offers....
+ For the time beeing, use the cdj550 device with -sBitsPerPixel=3
+ for fast proof-prints. If you simply want to print 600dpi b/w data,
+ use the cdj550 device with -sBitsPerPixel=8 (or 1).
+
+ Since the printer itself is slow, it may help to set the
+ process-priority of the gs-process to regular or even less. On a
+ 486/100MHZ this is still sufficient to maintain a continuos
+ data-flow.
+ Note to OS/2 users: Simply put the gs-window into the background,
+ or minimize it. Also make sure, that print01.sys is invoked without
+ the /irq switch (great speed improvement under warp4).
+
+ The printer default settings compensate for dot-gain by a
+ calibrated color-transfer function. If this appears to be to light
+ for your business-graphs, or for overhead-sheets, feel free to set
+ -dMasterGamma=1.7.
+
+ Furthermore, you may tweak the gammavalues independently by setting
+ -dGammaValC, -dGammaValM, -dGammaValY or -dGammaValK (if not set,
+ the values default to MasterGamma). This will only work, when
+ -dMasterGamma is set to a value greater than 1.0.
+
+ If you want to learn more about gamma, see:
+
+ http://www.erdw.ethz.ch/~bonk/ftp/misc/gammafaq.pdf
+ http://www.erdw.ethz.ch/~bonk/ftp/misc/colorfaq.pdf
+
+ Further information, bugs, tips etc, can be found
+ at my website.
+
+ Have fun!
+
+ Uli
+
+ uliw@erdw.ethz.ch
+ http://www.erdw.ethz.ch/~bonk/bonk.html
+
+ */
+
+/* 25.08.97 Version 1.2. Resolved all but one of the
+ known bugs, introduced a couple
+ of perfomance improvements. Complete
+ new color-transfer-function handling.
+ (see gamma). */
+
+/* 04.05.97 Version 1.1. For added features, */
+/* resolved bugs and so forth, please see */
+/* http://bonk.ethz.ch */
+
+/* 11.11.96. Initial release of the driver */
+
+#include "math_.h"
+#include <stdlib.h> /* for rand() */
+#include <assert.h>
+#include "gdevprn.h"
+#include "gdevpcl.h"
+#include "gsparam.h"
+
+/* Conversion stuff. */
+#include "gxlum.h"
+
+/* this holds the initialisation data of the hp850 */
+typedef struct hp850_cmyk_init_s {
+ byte a[26];
+} hp850_cmyk_init_t;
+private const hp850_cmyk_init_t hp850_cmyk_init =
+{
+ {
+ 0x02, /* format */
+ 0x04, /* number of components */
+ /* black */
+ 0x01, /* MSB x resolution */
+ 0x2c, /* LSB x resolution */
+ 0x01, /* MSB y resolution */
+ 0x2c, /* LSB y resolution */
+ 0x00, /* MSB intensity levels */
+ 0x02, /* LSB intensity levels */
+
+ /* cyan */
+ 0x01, /* MSB x resolution */
+ 0x2c, /* LSB x resolution */
+ 0x01, /* MSB y resolution */
+ 0x2c, /* LSB y resolution */
+ 0x00, /* MSB intensity levels */
+ 0x02, /* LSB intensity levels */
+
+ /* magenta */
+ 0x01, /* MSB x resolution */
+ 0x2c, /* LSB x resolution */
+ 0x01, /* MSB y resolution */
+ 0x2c, /* LSB y resolution */
+ 0x00, /* MSB intensity levels */
+ 0x02, /* LSB intensity levels */
+
+ /* yellow */
+ 0x01, /* MSB x resolution */
+ 0x2c, /* LSB x resolution */
+ 0x01, /* MSB y resolution */
+ 0x2c, /* LSB y resolution */
+ 0x00, /* MSB intensity levels */
+ 0x02 /* LSB intensity levels */
+ }
+};
+
+/* this holds the color lookuptable data of the hp850 */
+typedef struct {
+ byte c[256]; /* Lookuptable for cyan */
+ byte m[256]; /* dito for magenta */
+ byte y[256]; /* dito for yellow */
+ byte k[256]; /* dito for black */
+ int correct[256]; /* potential undercolor black correction */
+} Gamma;
+
+private const Gamma gammat850 =
+{
+ /* Lookup values for cyan */
+ {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 12, 12, 12,
+ 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 16, 16, 17, 17,
+ 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 22,
+ 22, 23, 23, 23, 23, 23, 24, 24, 25, 25, 26, 26, 26, 26, 26, 27, 27,
+ 27, 27, 28, 28, 29, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 34,
+ 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 42,
+ 43, 43, 43, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 51,
+ 52, 52, 53, 54, 54, 54, 55, 55, 56, 57, 58, 58, 59, 60, 60, 61, 62,
+ 62, 63, 65, 65, 66, 67, 67, 68, 69, 69, 70, 72, 73, 73, 74, 75, 75,
+ 76, 77, 79, 79, 80, 81, 82, 83, 83, 84, 86, 87, 88, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 97, 99, 100, 101, 102, 103, 104, 105, 106,
+ 108, 109, 110, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, 127,
+ 129, 131, 132, 135, 136, 138, 140, 142, 144, 146, 147, 150, 152, 154,
+ 157, 159, 162, 164, 166, 168, 171, 174, 176, 180, 182, 187, 192, 197,
+ 204, 215, 255},
+ /* Lookup values for magenta */
+ {0, 0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7,
+ 7, 8, 8, 8, 9, 9, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12,
+ 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17,
+ 17, 17, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22,
+ 23, 23, 24, 24, 25, 25, 25, 26, 26, 27, 27, 28, 29, 29, 29, 29, 30,
+ 30, 31, 30, 31, 31, 32, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36,
+ 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44,
+ 45, 45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54,
+ 54, 55, 55, 56, 57, 57, 58, 58, 59, 60, 60, 61, 61, 62, 63, 64, 65,
+ 66, 66, 67, 68, 68, 70, 71, 71, 72, 73, 73, 74, 76, 77, 77, 78, 79,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 100, 101, 102, 103, 105, 106, 107, 108,
+ 109, 112, 113, 114, 115, 116, 118, 119, 121, 123, 124, 125, 128, 129,
+ 130, 133, 134, 135, 138, 139, 142, 144, 145, 148, 150, 152, 154, 157,
+ 159, 162, 164, 168, 169, 170, 172, 175, 177, 179, 182, 185, 189, 193,
+ 198, 204, 215, 255},
+ /* Lookup values for yellow */
+ {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11,
+ 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 17, 17, 18, 18,
+ 18, 19, 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 22, 22, 23,
+ 23, 24, 24, 25, 25, 25, 26, 27, 28, 28, 29, 29, 29, 30, 30, 30, 30,
+ 31, 31, 32, 32, 33, 33, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37,
+ 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45,
+ 45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54, 54,
+ 55, 55, 56, 57, 58, 59, 59, 60, 61, 61, 62, 62, 63, 64, 65, 66, 67,
+ 67, 68, 69, 69, 70, 71, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 93, 94, 95,
+ 96, 97, 98, 100, 101, 102, 102, 103, 104, 106, 107, 108, 109, 110,
+ 111, 113, 114, 115, 116, 117, 118, 119, 121, 123, 124, 126, 128, 130,
+ 131, 134, 135, 137, 139, 140, 143, 145, 146, 148, 150, 152, 154, 156,
+ 158, 160, 163, 166, 167, 169, 171, 173, 176, 178, 181, 184, 188, 192,
+ 198, 204, 215, 255},
+ /* Lookup values for black */
+ {0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
+ 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
+ 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
+ 16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
+ 21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
+ 26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
+ 32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
+ 41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
+ 52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
+ 82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
+ 103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
+ 127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
+ 166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
+};
+
+private const Gamma gammat890 =
+{
+/* Lookup values for cyan */
+ {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, 229, 230, 231, 232, 233, 234, 235, 236, 237,
+ 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
+ 254, 255},
+
+/* Lookup values for magenta */
+ {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, 229, 230, 231, 232, 233, 234, 235, 236, 237,
+ 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
+ 254, 255},
+
+/* Lookup values for yellow */
+ {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, 229, 230, 231, 232, 233, 234, 235, 236, 237,
+ 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
+ 254, 255},
+
+ /* Lookup values for black */
+ {0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
+ 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
+ 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
+ 16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
+ 21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
+ 26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
+ 32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
+ 41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
+ 52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
+ 82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
+ 103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
+ 127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
+ 166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
+};
+
+private const Gamma * const gammat[] =
+{
+ &gammat850, /* CDJ670 */
+ &gammat850, /* CDJ850 */
+ &gammat890, /* CDJ890 */
+ &gammat850 /* CDJ1600 */
+};
+
+private int
+ rescale_byte_wise1x1(P4(int bytecount, const byte * inbytea,
+ const byte * inbyteb, byte * outbyte));
+private int
+ rescale_byte_wise2x1(P4(int bytecount, const byte * inbytea,
+ const byte * inbyteb, byte * outbyte));
+private int
+ rescale_byte_wise1x2(P4(int bytecount, const byte * inbytea,
+ const byte * inbyteb, byte * outbyte));
+private int
+ rescale_byte_wise2x2(P4(int bytecount, const byte * inbytea,
+ const byte * inbyteb, byte * outbyte));
+
+private int (* const rescale_color_plane[2][2]) (P4(int, const byte *, const byte *, byte *)) = {
+ {
+ rescale_byte_wise1x1, rescale_byte_wise1x2
+ },
+ {
+ rescale_byte_wise2x1, rescale_byte_wise2x2
+ }
+};
+
+/*
+ * Drivers stuff.
+ *
+ */
+#define DESKJET_PRINT_LIMIT 0.04 /* 'real' top margin? */
+/* Margins are left, bottom, right, top. */
+#define DESKJET_MARGINS_LETTER 0.25, 0.50, 0.25, 0.167
+#define DESKJET_MARGINS_A4 0.13, 0.46, 0.13, 0.04
+/* Define bits-per-pixel - default is 32-bit cmyk-mode */
+#ifndef BITSPERPIXEL
+# define BITSPERPIXEL 32
+#endif
+#define DOFFSET (dev_t_margin(pdev) - DESKJET_PRINT_LIMIT) /* Print position */
+
+
+#define W sizeof(word)
+#define I sizeof(int)
+
+/* paper types */
+typedef enum {
+ PLAIN_PAPER, BOND_PAPER, SPECIAL_PAPER, GLOSSY_FILM, TRANSPARENCY_FILM
+} cdj_paper_type_t;
+
+/* quality */
+typedef enum {
+ DRAFT = -1, NORMAL = 0, PRESENTATION = 1
+} cdj_quality_t;
+
+/* Printer types */
+typedef enum {
+ DJ670C, DJ850C, DJ890C, DJ1600C
+} cdj_printer_type_t;
+
+/* No. of ink jets (used to minimise head movements) */
+#define HEAD_ROWS_MONO 50
+#define HEAD_ROWS_COLOUR 16
+
+/* Colour mapping procedures */
+private dev_proc_map_cmyk_color(gdev_cmyk_map_cmyk_color);
+private dev_proc_map_rgb_color(gdev_cmyk_map_rgb_color);
+private dev_proc_map_color_rgb(gdev_cmyk_map_color_rgb);
+
+private dev_proc_map_rgb_color(gdev_pcl_map_rgb_color);
+private dev_proc_map_color_rgb(gdev_pcl_map_color_rgb);
+
+/* Print-page, parameters and miscellaneous procedures */
+private dev_proc_open_device(hp_colour_open);
+
+private dev_proc_get_params(cdj850_get_params);
+private dev_proc_put_params(cdj850_put_params);
+
+private dev_proc_print_page(cdj850_print_page);
+
+/* The device descriptors */
+
+/* The basic structure for all printers. Note the presence of the cmyk, depth
+ and correct fields even if some are not used by all printers. */
+
+#define prn_colour_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, cmyk, correct)\
+ prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page), cmyk, depth /* default */, correct
+
+
+
+#define gx_prn_colour_device_common \
+ gx_prn_device_common; \
+ int cmyk; /* 0: not CMYK-capable, > 0: printing CMYK, */ \
+ /* < 0 : CMYK-capable, not printing CMYK */ \
+ uint default_depth; /* Used only for CMYK-capable printers now. */ \
+ uint correction
+
+
+/* some definitions needed later */
+struct error_val_field {
+ int c; /* Current value of Cyan error during dithering */
+ int m; /* Current value of Magenta error during dithering */
+ int y; /* Current value of Yellow error during dithering */
+ int k; /* Current value of Black error during dithering */
+};
+
+/* this structure holds all the pointers to the different values
+ in all those data fields */
+ /*
+ * The principal data pointers are stored as pairs of values, with
+ * the selection being made by the 'scan' variable. The function of the
+ * scan variable is overloaded, as it controls both the alternating
+ * raster scan direction used in the Floyd-Steinberg dithering and also
+ * the buffer alternation required for line-difference compression.
+ *
+ * Thus, the number of pointers required is as follows:
+ */
+
+struct ptr_arrays {
+ byte *data[4]; /* 4 600dpi data, scan direction and alternating buffers */
+ byte *data_c[4]; /* 4 300dpi data, as above, */
+ byte *plane_data[4][4]; /*4 b/w-planes, scan direction and alternating buffers */
+ byte *plane_data_c[4][8]; /* as above, but for 8 planes */
+ byte *out_data; /* output buffer for the b/w data, one 600dpi plane */
+ byte *test_data[4]; /* holds a copy of the last plane */
+ int *errors[2]; /* 2 b/w dithering erros (scan direction only) */
+ int *errors_c[2]; /* 2 color dithering errors (scan direction only) */
+ word *storage; /* pointer to the beginning of the b/w-buffer */
+ word *storage_start; /* used for debugging */
+ word *storage_end; /* used for debugging */
+ word *storage_size; /* used for debugging */
+};
+
+/* Some miscellaneous variables */
+struct misc_struct {
+ int line_size; /* size of scan_line */
+ int line_size_c; /* size of rescaled scan_line */
+ int line_size_words; /* size of scan_line in words */
+ int paper_size; /* size of paper */
+ int num_comps; /* number of color components (1 - 4) */
+ int bits_per_pixel; /* bits per pixel 1,4,8,16,24,32 */
+ int storage_bpp; /* = bits_per_pixel */
+ int expanded_bpp; /* = bits_per_pixel */
+ int plane_size; /* size of b/w bit plane */
+ int plane_size_c; /* size of color bit plane */
+ int databuff_size; /* size of databuffer for b/w data */
+ int databuff_size_c; /* size of databuffer for color data */
+ int errbuff_size; /* size of error buffer b/w -data */
+ int errbuff_size_c; /* size of error buffer color -data */
+ int outbuff_size; /* size of output buffer for b/w data */
+ int scan; /* scan-line variable [0,1] */
+ int cscan; /* dito for the color-planes */
+ int is_two_pass; /* checks if b/w data has already been printed */
+ int zero_row_count; /* How many empty lines */
+ uint storage_size_words; /* size of storage in words for b/w data */
+ uint storage_size_words_c; /* size of storage in words for c-data */
+ int is_color_data; /* indicates whether there is color data */
+};
+
+ /* function pointer typedefs for device driver struct */
+typedef void (*StartRasterMode) (P3(gx_device_printer * pdev, int paper_size,
+ FILE * prn_stream));
+typedef void (*PrintNonBlankLines) (P6(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream));
+
+typedef void (*TerminatePage) (P2(gx_device_printer * pdev, FILE * prn_stream));
+
+typedef struct gx_device_cdj850_s {
+ gx_device_common;
+ gx_prn_colour_device_common;
+ int /*cdj_quality_t*/ quality; /* -1 draft, 0 normal, 1 best */
+ int /*cdj_paper_type_t*/ papertype; /* papertype [0,4] */
+ int intensities; /* intensity values per pixel [2,4] */
+ int xscal; /* boolean to indicate x scaling by 2 */
+ int yscal; /* boolean to indicate y scaling by 2 */
+ int /*cdj_printer_type_t*/ ptype; /* printer type, one of DJ670C, DJ850C, DJ890C, DJ1600C */
+ int compression; /* compression level */
+ float mastergamma; /* Gammavalue applied to all colors */
+ float gammavalc; /* range to which gamma-correction is
+ applied to bw values */
+ float gammavalm; /* amount of gamma correction for bw */
+ float gammavaly; /* range to which gamma-correction i
+ applied to color values */
+ float gammavalk; /* amount of gamma correction for color */
+ float blackcorrect; /* amount of gamma correction for color */
+ StartRasterMode start_raster_mode; /* output function to start raster mode */
+ PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */
+ TerminatePage terminate_page; /* page termination output function */
+} gx_device_cdj850;
+
+typedef struct {
+ gx_device_common;
+ gx_prn_colour_device_common;
+} gx_device_colour_prn;
+
+
+/* Use the cprn_device macro to access generic fields (like cmyk,
+ default_depth and correction), and specific macros for specific
+ devices. */
+
+#define cprn_device ((gx_device_colour_prn*) pdev)
+#define cdj850 ((gx_device_cdj850 *)pdev)
+
+#define prn_cmyk_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
+ prn_colour_device_body(dtype, procs, dev_name,\
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
+ ((bpp == 1 || bpp == 4) ? 1 : 4), bpp,\
+ (bpp > 8 ? 255 : 1), (1 << (bpp >> 2)) - 1, /* max_gray, max_color */\
+ (bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
+ print_page, 1 /* cmyk */, correct)
+
+
+#define prn_cmy_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
+ prn_colour_device_body(dtype, procs, dev_name,\
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
+ ((bpp == 1 || bpp == 4) ? 1 : 3), bpp,\
+ (bpp > 8 ? 255 : 1), (bpp > 8 ? 255 : 1), /* max_gray, max_color */\
+ (bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
+ print_page, -1 /* cmyk */, correct)
+
+
+#define cdj_850_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
+{ prn_cmyk_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
+ quality,\
+ papertype,\
+ intensities,\
+ 0, 0, /* xscal, yscal */\
+ ptype,\
+ compression,\
+ mastergamma,\
+ gammavalc,\
+ gammavalm,\
+ gammavaly,\
+ gammavalk,\
+ blackcorrect,\
+ start_raster_mode,\
+ print_non_blank_line,\
+ terminate_page\
+}
+
+#define cdj_1600_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
+{ prn_cmy_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
+ quality,\
+ papertype,\
+ intensities,\
+ 0, 0, /* xscal, yscal */\
+ ptype,\
+ compression,\
+ mastergamma,\
+ gammavalc,\
+ gammavalm,\
+ gammavaly,\
+ gammavalk,\
+ blackcorrect,\
+ start_raster_mode,\
+ print_non_blank_line,\
+ terminate_page\
+}
+
+#define cmyk_colour_procs(proc_colour_open, proc_get_params, proc_put_params, \
+ map_rgb_color, map_color_rgb, map_cmyk_color) {\
+ proc_colour_open,\
+ gx_default_get_initial_matrix,\
+ gx_default_sync_output,\
+ gdev_prn_output_page,\
+ gdev_prn_close,\
+ map_rgb_color,\
+ map_color_rgb,\
+ NULL /* fill_rectangle */,\
+ NULL /* tile_rectangle */,\
+ NULL /* copy_mono */,\
+ NULL /* copy_color */,\
+ NULL /* draw_line */,\
+ gx_default_get_bits,\
+ proc_get_params,\
+ proc_put_params,\
+ map_cmyk_color\
+}
+
+private void
+ cdj850_start_raster_mode(P3(gx_device_printer * pdev,
+ int papersize, FILE * prn_stream));
+
+private void
+ cdj850_print_non_blank_lines(P6(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream));
+private void
+ cdj850_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
+
+private void
+ cdj1600_start_raster_mode(P3(gx_device_printer * pdev,
+ int papersize, FILE * prn_stream));
+private void
+ cdj1600_print_non_blank_lines(P6(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream));
+private void
+ cdj1600_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
+
+
+
+private const gx_device_procs cdj670_procs =
+cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
+ NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
+
+private const gx_device_procs cdj850_procs =
+cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
+ NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
+
+private const gx_device_procs cdj890_procs =
+cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
+ NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
+
+private const gx_device_procs cdj1600_procs =
+cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
+ gdev_pcl_map_rgb_color, gdev_pcl_map_color_rgb, NULL);
+
+const gx_device_cdj850 gs_cdj670_device =
+cdj_850_device(cdj670_procs, "cdj670", 600, 600, 32, cdj850_print_page, 0,
+ PRESENTATION, PLAIN_PAPER, 2, DJ670C, 9,
+ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+ cdj850_start_raster_mode, cdj850_print_non_blank_lines,
+ cdj850_terminate_page);
+
+const gx_device_cdj850 gs_cdj850_device =
+cdj_850_device(cdj850_procs, "cdj850", 600, 600, 32, cdj850_print_page, 0,
+ PRESENTATION, PLAIN_PAPER, 4, DJ850C, 9,
+ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+ cdj850_start_raster_mode, cdj850_print_non_blank_lines,
+ cdj850_terminate_page);
+
+const gx_device_cdj850 gs_cdj890_device =
+cdj_850_device(cdj890_procs, "cdj890", 600, 600, 32, cdj850_print_page, 0,
+ PRESENTATION, PLAIN_PAPER, 4, DJ890C, 9,
+ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+ cdj850_start_raster_mode, cdj850_print_non_blank_lines,
+ cdj850_terminate_page);
+
+const gx_device_cdj850 gs_cdj1600_device =
+cdj_1600_device(cdj1600_procs, "cdj1600", 300, 300, 24, cdj850_print_page, 0,
+ PRESENTATION, PLAIN_PAPER, 2, DJ1600C, 3,
+ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+ cdj1600_start_raster_mode, cdj1600_print_non_blank_lines,
+ cdj1600_terminate_page);
+
+/* Forward references */
+private int cdj_put_param_int(P6(gs_param_list *, gs_param_name,
+ int *, int, int, int));
+private int cdj_put_param_float(P6(gs_param_list *, gs_param_name, float
+ *, float, float, int));
+private int cdj_put_param_bpp(P5(gx_device *, gs_param_list *, int, int, int));
+private int cdj_set_bpp(P3(gx_device *, int, int));
+
+
+/* Open the printer and set up the margins. */
+private int
+hp_colour_open(gx_device * pdev)
+{ /* Change the margins if necessary. */
+ static const float dj_a4[4] = {
+ DESKJET_MARGINS_A4
+ };
+ static const float dj_letter[4] = {
+ DESKJET_MARGINS_LETTER
+ };
+
+ /* margins for DJ1600C from manual */
+ static const float m_cdj1600[4] = {
+ 0.25, 0.5, 0.25, 0.5
+ };
+
+ const float *m = (float *)0;
+
+ /* Set up colour params if put_params has not already done so */
+ if (pdev->color_info.num_components == 0) {
+ int code = cdj_set_bpp(pdev, pdev->color_info.depth,
+ pdev->color_info.num_components);
+
+ if (code < 0)
+ return code;
+ }
+ /* assign printer type and set resolution dependent on printer type */
+ switch (cdj850->ptype) {
+ case DJ670C:
+ if (cdj850->papertype <= SPECIAL_PAPER) { /* paper */
+ if (cdj850->quality == DRAFT) {
+ gx_device_set_resolution(pdev, 300.0, 300.0);
+ cdj850->xscal = 0;
+ cdj850->yscal = 0;
+ } else if (cdj850->quality == NORMAL) {
+ gx_device_set_resolution(pdev, 600.0, 300.0);
+ cdj850->xscal = 1;
+ cdj850->yscal = 0;
+ } else { /* quality == PRESENTATION */
+ gx_device_set_resolution(pdev, 600.0, 600.0);
+ cdj850->xscal = 1;
+ cdj850->yscal = 1;
+ }
+ } else { /* film */
+ gx_device_set_resolution(pdev, 600.0, 300.0);
+ cdj850->xscal = 0;
+ cdj850->yscal = 0;
+ }
+ m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
+ break;
+ case DJ850C:
+ case DJ890C:
+ if (cdj850->quality == DRAFT) {
+ gx_device_set_resolution(pdev, 300.0, 300.0);
+ cdj850->xscal = 0;
+ cdj850->yscal = 0;
+ cdj850->intensities = 2;
+ } else if (cdj850->quality == NORMAL) {
+ gx_device_set_resolution(pdev, 600.0, 300.0);
+ cdj850->xscal = 1;
+ cdj850->yscal = 0;
+ /* only 3 intensities for normal paper */
+ if (cdj850->papertype <= PLAIN_PAPER) {
+ cdj850->intensities = 3;
+ } /* else cdj850->intensities = 4 from initialization */
+ } else { /* quality == PRESENTATION */
+ gx_device_set_resolution(pdev, 600.0, 600.0);
+ cdj850->xscal = 1;
+ cdj850->yscal = 1;
+ /* intensities = 4 from initialization */
+ }
+ m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
+ break;
+ case DJ1600C:
+ gx_device_set_resolution(pdev, 300.0, 300.0);
+ m = m_cdj1600;
+ break;
+ default:
+ assert(0);
+ }
+ gx_device_set_margins(pdev, m, true);
+ return gdev_prn_open(pdev);
+}
+
+/* Added parameters for DeskJet 850C */
+private int
+cdj850_get_params(gx_device * pdev, gs_param_list * plist)
+{
+ int code = gdev_prn_get_params(pdev, plist);
+
+ if (code < 0 ||
+ (code = param_write_int(plist, "Quality", &cdj850->quality)) < 0 ||
+ (code = param_write_int(plist, "Papertype", &cdj850->papertype)) < 0 ||
+ (code = param_write_float(plist, "MasterGamma", &cdj850->gammavalc))
+ < 0 ||
+ (code = param_write_float(plist, "GammaValC", &cdj850->gammavalc)) <
+ 0 ||
+ (code = param_write_float(plist, "GammaValM", &cdj850->gammavalm)) <
+ 0 ||
+ (code = param_write_float(plist, "GammaValY", &cdj850->gammavaly)) <
+ 0 ||
+ (code = param_write_float(plist, "GammaValK", &cdj850->gammavalk)) <
+ 0 ||
+ (code = param_write_float(plist, "BlackCorrect",
+ &cdj850->blackcorrect)) < 0
+ )
+ return code;
+
+ return code;
+}
+
+private int
+cdj850_put_params(gx_device * pdev, gs_param_list * plist)
+{
+ int quality = cdj850->quality;
+ int papertype = cdj850->papertype;
+ float mastergamma = cdj850->mastergamma;
+ float gammavalc = cdj850->gammavalc;
+ float gammavalm = cdj850->gammavalm;
+ float gammavaly = cdj850->gammavaly;
+ float gammavalk = cdj850->gammavalk;
+ float blackcorrect = cdj850->blackcorrect;
+ int bpp = 0;
+ int code = 0;
+
+ code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code);
+ code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code);
+ code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code);
+ code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code);
+ code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code);
+ code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code);
+ code = cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code);
+ code = cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code);
+ code = cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0,
+ 9.0, code);
+
+
+ if (code < 0)
+ return code;
+ code = cdj_put_param_bpp(pdev, plist, bpp, bpp, 0);
+ if (code < 0)
+ return code;
+
+ cdj850->quality = quality;
+ cdj850->papertype = papertype;
+ cdj850->mastergamma = mastergamma;
+ cdj850->gammavalc = gammavalc;
+ cdj850->gammavalm = gammavalm;
+ cdj850->gammavaly = gammavaly;
+ cdj850->gammavalk = gammavalk;
+ cdj850->blackcorrect = blackcorrect;
+ return 0;
+}
+
+/* ------ Internal routines ------ */
+/* The DeskJet850C can compress (mode 9) */
+
+
+/* Some convenient shorthand .. */
+#define x_dpi (pdev->x_pixels_per_inch)
+#define y_dpi (pdev->y_pixels_per_inch)
+
+/* To calculate buffer size as next greater multiple of both parameter and W */
+#define calc_buffsize(a, b) (((((a) + ((b) * W) - 1) / ((b) * W))) * W)
+
+/* internal functions */
+private void
+ FSDlinebw(P7(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * kP,
+ int n, int *ep, byte * dp));
+private void
+ FSDlinec2(P9(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa, int n,
+ byte * dp, int *ep));
+private void
+ FSDlinec3(P12(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa,
+ byte * cPb, byte * mPb, byte * yPb,
+ int n, byte * dp, int *ep));
+private void
+ FSDlinec4(P12(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa,
+ byte * cPb, byte * mPb, byte * yPb,
+ int n, byte * dp, int *ep));
+private void
+ init_error_buffer(struct misc_struct *misc_vars,
+ struct ptr_arrays *data_ptrs);
+private void
+ do_floyd_steinberg(P8(int scan, int cscan, int plane_size,
+ int plane_size_c, int n,
+ struct ptr_arrays *data_ptrs,
+ gx_device_printer * pdev,
+ struct error_val_field *error_values));
+private int
+ do_gcr(P7(int bytecount, byte * inbyte, const byte * kvalues,
+ const byte * cvalues, const byte * mvalues,
+ const byte * yvalues, const int *kcorrect));
+
+/* UNUSED
+ *private int
+ *test_scan (P4(int size,
+ * byte * current,
+ * byte * last,
+ * byte * control));
+ *private void
+ *save_color_data(P3(int size,
+ * byte * current,
+ * byte * saved));
+ *
+ */
+private void
+ send_scan_lines(P6(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream));
+private void
+ do_gamma(P3(float mastergamma, float gammaval, byte * values));
+private void
+ do_black_correction(P2(float kvalue, int *kcorrect));
+
+private void
+ init_data_structure(P3(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars));
+private void
+ calculate_memory_size(P2(gx_device_printer * pdev,
+ struct misc_struct *misc_vars));
+
+
+private void
+assign_dpi(int dpi, byte * msb)
+{
+ if (dpi == 600) {
+ msb[0] = 0x02;
+ msb[1] = 0x58;
+ } else {
+ msb[0] = 0x01;
+ msb[1] = 0x2c;
+ }
+}
+
+private void
+cdj850_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ fputs("0M", prn_stream); /* Reset compression */
+ fputs("\033*rC\033E", prn_stream); /* End Graphics, Reset */
+ fputs("\033&l0H", prn_stream); /* eject page */
+}
+
+/* Here comes the hp850 output routine -------------------- */
+private int
+cdj850_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+
+ struct error_val_field error_values;
+ struct ptr_arrays data_ptrs;
+ struct misc_struct misc_vars;
+
+ Gamma gamma;
+
+ /* make a local writable copy of the Gamma tables */
+ memcpy(&gamma, gammat[cdj850->ptype], sizeof(Gamma));
+ /* if mastergamma, don't use the built in functions */
+ if (cdj850->mastergamma > 1.0) {
+ /* prepare the bw lookup table */
+ do_gamma(cdj850->mastergamma, cdj850->gammavalk, gamma.k);
+ /* prepare the color lookup table */
+ do_gamma(cdj850->mastergamma, cdj850->gammavalc, gamma.c);
+ do_gamma(cdj850->mastergamma, cdj850->gammavalm, gamma.m);
+ do_gamma(cdj850->mastergamma, cdj850->gammavaly, gamma.y);
+ }
+ /* prepare the black correction table for the unbunt mask */
+ do_black_correction(cdj850->blackcorrect, gamma.correct);
+
+ /* Calculate the needed memory */
+ calculate_memory_size(pdev, &misc_vars);
+
+ /* and allocate the memory */
+
+ /* Since we need 600 and 300 dpi, we set up several buffers:
+ storage contains the data as copied from gs, as well as the
+ plane-data and the out_row buffer.
+ storagec will contain the rescaled color data. It also contains the
+ plane_data for the color-planes - these are needed by the
+ compression routine, but would be overwritten by the
+ b/w-dithering. The color planes allow for overwriting the
+ color-data by the error-data. Since we might use the
+ 2bpp feature of the hp850 someday, it is sized like storage.
+ storagee contains the errors from b/w fs-ditherng */
+
+ data_ptrs.storage = (ulong *) gs_malloc(misc_vars.storage_size_words, W,
+ "cdj850_print_page");
+
+ /* if we can't allocate working area */
+ if (data_ptrs.storage == 0) {
+ return_error(gs_error_VMerror);
+ }
+ /* Initialise the needed pointers */
+ init_data_structure(pdev, &data_ptrs, &misc_vars);
+
+ /* Start Raster mode */
+ (*cdj850->start_raster_mode) (pdev, misc_vars.paper_size, prn_stream);
+
+ /* Send each scan line in turn */
+ send_scan_lines(pdev, &data_ptrs, &misc_vars,
+ &error_values, &gamma, prn_stream);
+
+ /* terminate page and eject paper */
+ (*cdj850->terminate_page) (pdev, prn_stream);
+
+ /* Free Memory */
+ gs_free((char *)data_ptrs.storage, misc_vars.storage_size_words, W,
+ "hp850_print_page");
+
+ return 0;
+}
+
+#define odd(i) ((i & 01) != 0)
+
+private int
+GetScanLine(gx_device_printer * pdev, int *lnum,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ word rmask)
+{
+ word *data_words = (word *) data_ptrs->data[misc_vars->scan];
+ register word *end_data = data_words + misc_vars->line_size_words;
+
+ ++(*lnum);
+ gdev_prn_copy_scan_lines(pdev, *lnum, (byte *) data_words, misc_vars->line_size);
+
+ misc_vars->scan = 1 - misc_vars->scan; /* toggle scan direction */
+ misc_vars->is_two_pass = odd(*lnum); /* color output for odd lines */
+
+ /* Mask off 1-bits beyond the line width. */
+ end_data[-1] &= rmask;
+
+ /* Remove trailing 0s. */
+ while (end_data > data_words && end_data[-1] == 0)
+ end_data--;
+
+ return end_data - data_words;
+}
+
+/* Send the scan lines to the printer */
+private void
+send_scan_lines(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream)
+{
+ int lnum, lend, llen;
+ int num_blank_lines = 0;
+
+ word rmask =
+ ~(word) 0 << ((-pdev->width * misc_vars->storage_bpp) & (W * 8 - 1));
+
+ lend = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * y_dpi;
+
+ error_values->c = error_values->m = error_values->y =
+ error_values->k = 0;
+
+ /* init the error buffer */
+ init_error_buffer(misc_vars, data_ptrs);
+
+ misc_vars->zero_row_count = 0;
+ lnum = -1;
+ llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
+ while (lnum < lend) {
+ num_blank_lines = 0;
+ while (lnum < lend && llen == 0) {
+ ++num_blank_lines;
+ llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
+ }
+ if (lnum >= lend) {
+ break;
+ }
+ /* Skip blank lines if any */
+ if (num_blank_lines > 0) {
+ fprintf(prn_stream, "%dy", num_blank_lines / (cdj850->yscal + 1));
+ memset(data_ptrs->plane_data[0][0], 0,
+ (misc_vars->plane_size * 2 * misc_vars->num_comps));
+ memset(data_ptrs->plane_data_c[0][0], 0,
+ (misc_vars->plane_size_c * 2 * misc_vars->num_comps));
+
+ }
+ /* all blank lines printed, now for the non-blank lines */
+ if (cdj850->yscal && odd(lnum)) {
+ /* output a blank black plane for odd lines */
+ putc('v', prn_stream);
+ }
+ /* now output all non blank lines */
+ while (lnum < lend && llen != 0) {
+ misc_vars->is_color_data = 0; /* maybe we have color ? */
+ (*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
+ error_values, gamma, prn_stream);
+ llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
+ }
+ if (cdj850->yscal && odd(lnum)) { /* output empty line for odd lines */
+ (*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
+ error_values, gamma, prn_stream);
+ }
+ /* the current line is empty => run the next iteration */
+ }
+}
+
+/* print_line compresses (mode 9) and outputs one plane */
+private void
+print_c9plane(FILE * prn_stream, char plane_code, int plane_size,
+ const byte * curr, const byte * prev, byte * out_data)
+{
+ /* Compress the output data */
+ int out_count = gdev_pcl_mode9compress(plane_size, curr, prev, out_data);
+
+ /* and output the data */
+ if (out_count > 0) {
+ fprintf(prn_stream, "%d%c", out_count, plane_code);
+ fwrite(out_data, sizeof(byte), out_count, prn_stream);
+ } else {
+ putc(plane_code, prn_stream);
+ }
+}
+
+/* Printing non-blank lines */
+private void
+cdj850_print_non_blank_lines(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream)
+{
+ static const char *const plane_code[2] =
+ {"wvvv", "vvvv"};
+
+ int i;
+ byte *kP = data_ptrs->plane_data[misc_vars->scan + 2][3];
+ byte *dp = data_ptrs->data[misc_vars->scan + 2];
+ int *ep = data_ptrs->errors[misc_vars->scan];
+
+ /* we need cmyk color separation befor all the rest, since
+ black may be contained in the color fields. This needs to
+ be done on all pixel-rows, since even unused color-bytes
+ might generate black */
+
+ misc_vars->is_color_data =
+ do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
+ gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct);
+
+ /* dithering the black-plane */
+ FSDlinebw(misc_vars->scan, misc_vars->plane_size,
+ error_values, kP, misc_vars->num_comps, ep, dp);
+
+ /* output the black plane */
+ print_c9plane(prn_stream, 'v', misc_vars->plane_size,
+ data_ptrs->plane_data[misc_vars->scan][3],
+ data_ptrs->plane_data[1 - misc_vars->scan][3],
+ data_ptrs->out_data);
+
+ /* since color resolution is only half of the b/w-resolution,
+ we only output every second row */
+ if (!cdj850->yscal || misc_vars->is_two_pass) {
+
+ int plane_size_c = (*rescale_color_plane[cdj850->xscal][cdj850->yscal])
+ (misc_vars->databuff_size,
+ data_ptrs->data[misc_vars->scan],
+ data_ptrs->data[1 - misc_vars->scan],
+ data_ptrs->data_c[misc_vars->cscan]) / misc_vars->storage_bpp;
+
+ /* dither the color planes */
+ do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
+ misc_vars->plane_size, plane_size_c,
+ misc_vars->num_comps, data_ptrs, pdev, error_values);
+
+ /* Transfer raster graphics in the order C, M, Y, that is
+ planes 2,1,0 */
+ for (i = misc_vars->num_comps - 2; i >= 0; i--) {
+
+ /* output the lower color planes */
+ print_c9plane(prn_stream, plane_code[cdj850->intensities > 2][i],
+ plane_size_c,
+ data_ptrs->plane_data_c[misc_vars->cscan][i],
+ data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
+ data_ptrs->out_data);
+
+ /* output the upper color planes */
+ if (cdj850->intensities > 2) {
+ print_c9plane(prn_stream, plane_code[0][i], plane_size_c,
+ data_ptrs->plane_data_c[misc_vars->cscan][i + 4],
+ data_ptrs->plane_data_c[1 -
+ misc_vars->cscan][i
+ + 4],
+ data_ptrs->out_data);
+ } /* end cdj850->intensities > 2 */
+ } /* End For i = num_comps */
+ misc_vars->cscan = 1 - misc_vars->cscan;
+ } /* End of is_two_pass */
+ return;
+}
+
+/* moved that code into his own subroutine, otherwise things get
+ somewhat clumsy */
+private void
+do_floyd_steinberg(int scan, int cscan, int plane_size,
+ int plane_size_c, int n,
+ struct ptr_arrays *data_ptrs,
+ gx_device_printer * pdev,
+ struct error_val_field *error_values)
+{
+ /* the color pointers */
+ byte *cPa, *mPa, *yPa, *cPb, *mPb, *yPb;
+ byte *dpc;
+ int *epc;
+
+ /* the b/w pointers */
+ byte *kP, *dp;
+ int *ep;
+
+ /* the color pointers, lower byte */
+ cPa = data_ptrs->plane_data_c[cscan + 2][2];
+ mPa = data_ptrs->plane_data_c[cscan + 2][1];
+ yPa = data_ptrs->plane_data_c[cscan + 2][0];
+ /* upper byte */
+ cPb = data_ptrs->plane_data_c[cscan + 2][6];
+ mPb = data_ptrs->plane_data_c[cscan + 2][5];
+ yPb = data_ptrs->plane_data_c[cscan + 2][4];
+ /* data and error */
+ dpc = data_ptrs->data_c[cscan + 2];
+ epc = data_ptrs->errors_c[cscan];
+ /* the b/w pointers */
+ kP = data_ptrs->plane_data[scan + 2][3];
+ dp = data_ptrs->data[scan + 2];
+ ep = data_ptrs->errors[scan];
+
+ switch (cdj850->intensities) {
+ case 2:
+ FSDlinec2(cscan, plane_size_c, error_values,
+ cPa, mPa, yPa, n, dpc, epc);
+ break;
+ case 3:
+ FSDlinec3(cscan, plane_size_c, error_values,
+ cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
+ break;
+ case 4:
+ FSDlinec4(cscan, plane_size_c, error_values,
+ cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
+ break;
+ default:
+ assert(0);
+ }
+ return;
+}
+
+/* here we do our own gamma-correction */
+private void
+do_gamma(float mastergamma, float gammaval, byte values[256])
+{
+ int i;
+ float gamma;
+
+ if (gammaval > 0.0) {
+ gamma = gammaval;
+ } else {
+ gamma = mastergamma;
+ }
+
+ for (i = 0; i < 256; i++) {
+ values[i] = (byte) (255.0 *
+ (1.0 - pow(((double)(255.0 - (float)i) / 255.0),
+ (double)(1.0 / gamma))));
+ }
+
+ return;
+}
+
+/* here we calculate a lookup-table which is used to compensate the
+ relativ loss of color due to undercolor-removal */
+private void
+do_black_correction(float kvalue, int kcorrect[256])
+{
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ kcorrect[i] = (int)
+ (100.0 * kvalue * (
+ pow(10.0,
+ pow((i / 255.0), 3.0)
+ )
+ - 1.0
+ )
+ );
+ }
+
+ return;
+}
+
+/* For Better Performance we use a macro here */
+#define DOUCR(col1, col2, col3, col4)\
+{\
+ /* determine how far we are from the grey axis. This is */\
+ /* traditionally done by computing MAX(CMY)-MIN(CMY). */\
+ /* However, if two colors are very similar, we could */\
+ /* as either CMYRGB and K. Therefore we calculate the */\
+ /* the distance col1-col2 and col2-col3, and use the */\
+ /* smaller one. */\
+ a = *col1 - *col2;\
+ b = *col2 - *col3;\
+ if (a >= b) {\
+ grey_distance = 1.0 - (b/255.0);\
+ } else {\
+ grey_distance = 1.0 - (a/255.0);\
+ }\
+ ucr = (byte) (*col3 * grey_distance); \
+ *col4 = *col4 + ucr; /* add removed black to black */\
+ /* remove only as much color as black is surviving the */\
+ /* gamma correction */\
+ ucr = *(kvalues + ucr);\
+ *col1 = *col1 - ucr ;\
+ *col2 = *col2 - ucr ;\
+ *col3 = *col3 - ucr ;\
+}
+
+/* For Better Performance we use a macro here */
+#define DOGCR(col1, col2, col3, col4)\
+{\
+ ucr = (int) *col3;\
+ *col1 -= ucr ;\
+ *col2 -= ucr ;\
+ *col3 -= ucr ;\
+ *col4 += ucr; /* add removed black to black */\
+ kadd = ucr + *(kcorrect + ucr);\
+ uca_fac = 1.0 + (kadd/255.0);\
+ *col1 *= uca_fac;\
+ *col2 *= uca_fac;\
+}
+
+/* Since resolution can be different on different planes, we need to
+ do real color separation, here we try a real grey component
+ replacement */
+private int
+do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
+ const byte cvalues[256], const byte mvalues[256],
+ const byte yvalues[256], const int kcorrect[256])
+{
+ int i, ucr, kadd, is_color = 0;
+ byte *black, *cyan, *magenta, *yellow;
+ float uca_fac;
+
+ /* Grey component replacement */
+ for (i = 0; i < bytecount; i += 4) {
+ black = inbyte++; /* Assign to black the current address of inbyte */
+ cyan = inbyte++;
+ magenta = inbyte++;
+ yellow = inbyte++;
+
+ if (*magenta + *yellow + *cyan > 0) { /* if any color at all */
+
+ is_color = 1;
+
+ if ((*cyan >= *magenta)
+ && (*magenta >= *yellow)
+ && (*yellow > 0)) { /* if any grey component */
+ DOGCR(cyan, magenta, yellow, black);
+ } else if ((*cyan >= *yellow)
+ && (*yellow >= *magenta)
+ && (*magenta > 0)) {
+ DOGCR(cyan, yellow, magenta, black);
+ } else if ((*yellow >= *magenta)
+ && (*magenta >= *cyan)
+ && (*cyan > 0)) {
+ DOGCR(yellow, magenta, cyan, black);
+ } else if ((*yellow >= *cyan)
+ && (*cyan >= *magenta)
+ && (*magenta > 0)) {
+ DOGCR(yellow, cyan, magenta, black);
+ } else if ((*magenta >= *yellow)
+ && (*yellow >= *cyan)
+ && (*cyan > 0)) {
+ DOGCR(magenta, yellow, cyan, black);
+ } else if ((*magenta >= *cyan)
+ && (*cyan >= *yellow)
+ && (*yellow > 0)) {
+ DOGCR(magenta, cyan, yellow, black);
+ } else { /* do gamma only if no black */
+ }
+ *cyan = *(cvalues + *cyan);
+ *magenta = *(mvalues + *magenta);
+ *yellow = *(yvalues + *yellow);
+ } /* end of if c+m+y > 0 */
+ *black = *(kvalues + *black);
+ } /* end of for bytecount */
+ return is_color;
+}
+
+/* Since resolution can be different on different planes, we need to
+ rescale the data byte by byte */
+private int
+rescale_byte_wise2x2(int bytecount, const byte * inbytea, const byte * inbyteb,
+ byte * outbyte)
+{
+ register int i, j;
+ int max = bytecount / 2;
+
+ for (i = 0; i < max; i += 4) {
+ j = 2 * i;
+ /* cyan */
+ outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] +
+ inbyteb[j + 5]) / 4;
+ /* magenta */
+ outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] +
+ inbyteb[j + 6]) / 4;
+ /* yellow */
+ outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] +
+ inbyteb[j + 7]) / 4;
+ }
+ return max;
+}
+
+/* Since resolution can be different on different planes, we need to
+ rescale the data byte by byte */
+private int
+rescale_byte_wise2x1(int bytecount, const byte * inbytea, const byte * inbyteb,
+ byte * outbyte)
+{
+ register int i, j;
+ int max = bytecount / 2;
+
+ for (i = 0; i < max; i += 4) {
+ j = 2 * i;
+ /* cyan */
+ outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2;
+ /* magenta */
+ outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2;
+ /* yellow */
+ outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2;
+ }
+ return max;
+}
+
+/* Since resolution can be different on different planes, we need to
+ rescale the data byte by byte */
+private int
+rescale_byte_wise1x2(int bytecount, const byte * inbytea, const byte * inbyteb,
+ byte * outbyte)
+{
+ register int i;
+
+ for (i = 0; i < bytecount; i += 4) {
+ /* cyan */
+ outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2;
+ /* magenta */
+ outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2;
+ /* yellow */
+ outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2;
+ }
+ return bytecount;
+}
+
+/* Since resolution can be different on different planes, we need to
+ rescale the data byte by byte */
+private int
+rescale_byte_wise1x1(int bytecount, const byte * inbytea, const byte * inbyteb,
+ byte * outbyte)
+{
+ register int i;
+
+ for (i = 0; i < bytecount; i += 4) {
+ /* cyan */
+ outbyte[i + 1] = inbytea[i + 1];
+ /* magenta */
+ outbyte[i + 2] = inbytea[i + 2];
+ /* yellow */
+ outbyte[i + 3] = inbytea[i + 3];
+ }
+ return bytecount;
+}
+
+/* MACROS FOR DITHERING (we use macros for compact source and faster code) */
+/* Floyd-Steinberg dithering. Often results in a dramatic improvement in
+ * subjective image quality, but can also produce dramatic increases in
+ * amount of printer data generated and actual printing time!! Mode 9 2D
+ * compression is still useful for fairly flat colour or blank areas but its
+ * compression is much less effective in areas where the dithering has
+ * effectively randomised the dot distribution. */
+
+#define RSHIFT ((I * 8) - 16)
+#define SHIFT ((I * 8) - 13)
+#define MAXVALUE (255 << SHIFT)
+#define RANDOM (((rand() << RSHIFT) % (MAXVALUE / 2)) - MAXVALUE /4);
+#define MINVALUE 0
+#define C 8
+
+#define THRESHOLD (128 << SHIFT)
+
+/* --- needed for the hp850 -- */
+#define SHIFTS ((I * 8) - 14)
+#define SHIFTM ((I * 8) - 13)
+#define SHIFTL ((I * 8) - 12)
+
+#define MAXVALUES (160 << SHIFTM)
+#define MAXVALUEM (226 << SHIFTM)
+#define MAXVALUEL (255 << SHIFTM)
+
+#define THRESHOLDS (128 << SHIFTM)
+#define THRESHOLDM (192 << SHIFTM)
+#define THRESHOLDL (226 << SHIFTM)
+/* --------------------------- */
+
+/* initialise the error_buffer */
+private void
+init_error_buffer(struct misc_struct *misc_vars,
+ struct ptr_arrays *data_ptrs)
+{
+ int i;
+ int *ep;
+ int *epc;
+
+ ep = data_ptrs->errors[0];
+ epc = data_ptrs->errors_c[0];
+
+ if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error
+ buffer */
+ /* Otherwise, the first dithered rows would look rather uniform */
+ for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */
+ *ep++ = RANDOM;
+ }
+
+ /* Now for the 2 * 300dpi color planes */
+ for (i = 0; i < misc_vars->databuff_size_c; i++) {
+ *epc++ = RANDOM;
+ }
+ }
+ return;
+}
+
+#define FSdither(inP, out, errP, Err, Bit, Offset, Element)\
+{\
+ oldErr = Err;\
+ Err = (*(errP + Element)\
+ + ((Err * 7 + C) >> 4)\
+ + ((int)*(inP + Element) << SHIFT));\
+ if (Err > THRESHOLD) {\
+ out |= Bit;\
+ Err -= MAXVALUE;\
+ }\
+ *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
+ *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
+}
+
+/* The hp850c has 600dpi black and 300 dpi color. Therefore, we need
+ an adapted dither algorythm */
+private void
+FSDlinebw(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * kP, int n, int *ep, byte * dp)
+{
+ if (scan == 0) { /* going_up */
+ byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the
+
+ bit to be set within k */
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x80;
+ for (k = 0; bitmask != 0; bitmask >>= 1) {
+ /* dp points to the first word of the input data which is in
+ kcmy-format */
+ /* k points to the beginning of the first outbut byte, which
+ is filled up, bit by bit while looping over bytemask */
+ /* ep points to the first word of the error-plane which
+ contains the errors kcmy format */
+ /* err_values->k tempararily holds the error-value */
+ /* bitmask selects the bit to be set in the outbyte */
+ /* n gives the offset for the byte selection within
+ words. With simple cmyk-printing, this should be 4 */
+ /* 0 points to the active color within the input-word, i.e. 0
+ = black, 1 = cyan, 2 = yellow, 3 = magenta */
+
+ FSdither(dp, k, ep, error_values->k, bitmask, -n, 0);
+ dp += n, ep += n; /* increment the input and error pointer one
+ word (=4 byte) further, in order to
+ convert the next word into an bit */
+ }
+ *kP++ = k; /* fill the output-plane byte with the computet byte
+ and increment the output plane pointer one byte */
+ }
+
+ } else { /* going_down */
+ byte k, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x01;
+ for (k = 0; bitmask != 0; bitmask <<= 1) {
+ dp -= n, ep -= n;
+ FSdither(dp, k, ep, error_values->k, bitmask, n, 0);
+ }
+ *--kP = k;
+ }
+ }
+ return;
+}
+
+/* Since bw has already been dithered for the hp850c, we need
+ an adapted dither algorythm */
+private void
+FSDlinec2(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa, int n,
+ byte * dp, int *ep)
+{
+ if (scan == 0) { /* going_up */
+ int oldErr, i;
+ byte ca, ya, ma, bitmask;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x80;
+ ca = ya = ma = 0;
+ for (ca = 0; bitmask != 0; bitmask >>= 1) {
+ FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3);
+ FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2);
+ FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1);
+ dp += n, ep += n;
+ }
+ *cPa++ = ca;
+ *mPa++ = ma;
+ *yPa++ = ya;
+ }
+
+ } else { /* going_down */
+ byte ca, ya, ma, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x01;
+ ca = ya = ma = 0;
+ for (ca = 0; bitmask != 0; bitmask <<= 1) {
+ dp -= n, ep -= n;
+ FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1);
+ FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2);
+ FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3);
+ }
+ *--yPa = ya;
+ *--mPa = ma;
+ *--cPa = ca;
+ }
+ }
+ return;
+}
+
+/* while printing on paper, we only use 3 -intensities */
+#define FSdither8503(inP, outa, outb, errP, Err, Bit, Offset, Element)\
+{\
+ oldErr = Err;\
+ Err = (*(errP + Element)\
+ + ((Err * 7 + C) >> 4)\
+ + ((int) *(inP + Element) << SHIFT));\
+ if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
+ outa |= Bit;\
+ Err -= MAXVALUES;\
+ }\
+ if (Err > THRESHOLDM) {\
+ outb |= Bit;\
+ Err -= MAXVALUEM;\
+ }\
+ *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
+ *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
+}
+
+/* On ordinary paper, we'll only use 3 intensities with the hp850 */
+private void
+FSDlinec3(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa,
+ byte * cPb, byte * mPb, byte * yPb,
+ int n, byte * dp, int *ep)
+{
+ if (scan == 0) { /* going_up */
+ byte ca, ya, ma, cb, yb, mb, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x80;
+ ca = ya = ma = cb = yb = mb = 0;
+ for (ca = 0; bitmask != 0; bitmask >>= 1) {
+ FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, -n, n
+ - 3);
+ FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, -n, n
+ - 2);
+ FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, -n, n
+ - 1);
+ dp += n, ep += n;
+ }
+ *cPa++ = ca;
+ *mPa++ = ma;
+ *yPa++ = ya;
+ *cPb++ = cb;
+ *mPb++ = mb;
+ *yPb++ = yb;
+ }
+ } else { /* going_down */
+ byte ca, ya, ma, cb, yb, mb, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x01;
+ ca = ya = ma = cb = yb = mb = 0;
+ for (ca = 0; bitmask != 0; bitmask <<= 1) {
+ dp -= n, ep -= n;
+ FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, n, n
+ - 1);
+ FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, n, n
+ - 2);
+ FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, n, n
+ - 3);
+ }
+ *--yPa = ya;
+ *--mPa = ma;
+ *--cPa = ca;
+ *--yPb = yb;
+ *--mPb = mb;
+ *--cPb = cb;
+ }
+ }
+ return;
+}
+
+
+/* the hp850 knows about 4 different color intensities per color */
+#define FSdither8504(inP, outa, outb, errP, Err, Bit, Offset, Element)\
+{\
+ oldErr = Err;\
+ Err = (*(errP + Element)\
+ + ((Err * 7 + C) >> 4)\
+ + ((int) *(inP + Element) << SHIFT));\
+ if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
+ outa |= Bit;\
+ Err -= MAXVALUES;\
+ }\
+ if ((Err > THRESHOLDM) && (Err <= THRESHOLDL)) {\
+ outb |= Bit;\
+ Err -= MAXVALUEM;\
+ }\
+ if (Err > THRESHOLDL) {\
+ outa |= Bit;\
+ outb |= Bit;\
+ Err -= MAXVALUEL;\
+ }\
+ *(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
+ *(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
+}
+
+/* The hp850c knows about 4 intensity levels per color. Once more, we need
+ an adapted dither algorythm */
+private void
+FSDlinec4(int scan, int plane_size,
+ struct error_val_field *error_values,
+ byte * cPa, byte * mPa, byte * yPa,
+ byte * cPb, byte * mPb, byte * yPb,
+ int n, byte * dp, int *ep)
+{
+ if (scan == 0) { /* going_up */
+ byte ca, ya, ma, cb, yb, mb, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x80;
+ ca = ya = ma = cb = yb = mb = 0;
+ for (ca = 0; bitmask != 0; bitmask >>= 1) {
+ FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, -n, n
+ - 3);
+ FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, -n, n
+ - 2);
+ FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, -n, n
+ - 1);
+ dp += n, ep += n;
+ }
+ *cPa++ = ca;
+ *mPa++ = ma;
+ *yPa++ = ya;
+ *cPb++ = cb;
+ *mPb++ = mb;
+ *yPb++ = yb;
+ }
+ } else { /* going_down */
+ byte ca, ya, ma, cb, yb, mb, bitmask;
+ int oldErr, i;
+
+ for (i = 0; i < plane_size; i++) {
+ bitmask = 0x01;
+ ca = ya = ma = cb = yb = mb = 0;
+ for (ca = 0; bitmask != 0; bitmask <<= 1) {
+ dp -= n, ep -= n;
+ FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, n, n
+ - 1);
+ FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, n, n
+ - 2);
+ FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, n, n
+ - 3);
+ }
+ *--yPa = ya;
+ *--mPa = ma;
+ *--cPa = ca;
+ *--yPb = yb;
+ *--mPb = mb;
+ *--cPb = cb;
+ }
+ }
+ return;
+}
+
+
+/* calculate the needed memory */
+private void
+calculate_memory_size(gx_device_printer * pdev,
+ struct misc_struct *misc_vars)
+{
+ int xfac = cdj850->xscal ? 2 : 1;
+
+ misc_vars->line_size = gdev_prn_raster(pdev);
+ misc_vars->line_size_c = misc_vars->line_size / xfac;
+ misc_vars->line_size_words = (misc_vars->line_size + W - 1) / W;
+ misc_vars->paper_size = gdev_pcl_paper_size((gx_device *) pdev);
+ misc_vars->num_comps = pdev->color_info.num_components;
+ misc_vars->bits_per_pixel = pdev->color_info.depth;
+ misc_vars->storage_bpp = misc_vars->num_comps * 8;
+ misc_vars->expanded_bpp = misc_vars->num_comps * 8;
+ misc_vars->errbuff_size = 0;
+ misc_vars->errbuff_size_c = 0;
+
+ misc_vars->plane_size = calc_buffsize(misc_vars->line_size, misc_vars->storage_bpp);
+
+ /* plane_size_c is dependedend on the bits used for
+ dithering. Currently 2 bits are sufficient */
+ misc_vars->plane_size_c = 2 * misc_vars->plane_size / xfac;
+
+ /* 4n extra values for line ends */
+ /* might be wrong, see gdevcdj.c */
+ misc_vars->errbuff_size =
+ calc_buffsize((misc_vars->plane_size * misc_vars->expanded_bpp +
+ misc_vars->num_comps * 4) * I, 1);
+
+ /* 4n extra values for line ends */
+ misc_vars->errbuff_size_c =
+ calc_buffsize((misc_vars->plane_size_c / 2 * misc_vars->expanded_bpp
+ + misc_vars->num_comps * 4) * I, 1);
+
+ misc_vars->databuff_size =
+ misc_vars->plane_size * misc_vars->storage_bpp;
+
+ misc_vars->databuff_size_c =
+ misc_vars->plane_size_c / 2 * misc_vars->storage_bpp;
+
+
+ misc_vars->outbuff_size = misc_vars->plane_size * 4;
+
+ misc_vars->storage_size_words = (((misc_vars->plane_size)
+ * 2
+ * misc_vars->num_comps)
+ + misc_vars->databuff_size
+ + misc_vars->errbuff_size
+ + misc_vars->outbuff_size
+ + ((misc_vars->plane_size_c)
+ * 2
+ * misc_vars->num_comps)
+ + misc_vars->databuff_size_c
+ + misc_vars->errbuff_size_c
+ + (4 * misc_vars->plane_size_c))
+ / W;
+
+ return;
+}
+
+
+/* Initialise the needed pointers */
+private void
+init_data_structure(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars)
+{
+ int i;
+ byte *p = (byte *) data_ptrs->storage;
+
+ misc_vars->scan = 0;
+ misc_vars->cscan = 0;
+ misc_vars->is_two_pass = 1;
+
+ /* the b/w pointer */
+ data_ptrs->data[0] = data_ptrs->data[1] = data_ptrs->data[2] = p;
+ data_ptrs->data[3] = p + misc_vars->databuff_size;
+ /* Note: The output data will overwrite part of the input-data */
+
+ if (misc_vars->bits_per_pixel > 1) {
+ p += misc_vars->databuff_size;
+ }
+ if (misc_vars->bits_per_pixel > 4) {
+ data_ptrs->errors[0] = (int *)p + misc_vars->num_comps * 2;
+ data_ptrs->errors[1] = data_ptrs->errors[0] + misc_vars->databuff_size;
+ p += misc_vars->errbuff_size;
+ }
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data[0][i] = data_ptrs->plane_data[2][i] = p;
+ p += misc_vars->plane_size;
+ }
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data[1][i] = p;
+ data_ptrs->plane_data[3][i] = p + misc_vars->plane_size;
+ p += misc_vars->plane_size;
+ }
+ data_ptrs->out_data = p;
+ p += misc_vars->outbuff_size;
+
+ /* ---------------------------------------------------------
+ now for the color pointers
+ --------------------------------------------------------- */
+
+ data_ptrs->data_c[0] = data_ptrs->data_c[1] = data_ptrs->data_c[2] = p;
+ data_ptrs->data_c[3] = p + misc_vars->databuff_size_c;
+ /* Note: The output data will overwrite part of the input-data */
+
+ if (misc_vars->bits_per_pixel > 1) {
+ p += misc_vars->databuff_size_c;
+ }
+ if (misc_vars->bits_per_pixel > 4) {
+ data_ptrs->errors_c[0] = (int *)p + misc_vars->num_comps * 2;
+ data_ptrs->errors_c[1] = data_ptrs->errors_c[0] + misc_vars->databuff_size_c;
+ p += misc_vars->errbuff_size_c;
+ }
+ /* pointer for the lower bits of the output data */
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data_c[0][i] = data_ptrs->plane_data_c[2][i] = p;
+ p += misc_vars->plane_size_c / 2;
+ }
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data_c[1][i] = p;
+ data_ptrs->plane_data_c[3][i] = p + misc_vars->plane_size_c / 2;
+ p += misc_vars->plane_size_c / 2;
+ }
+
+ /* pointer for the upper bits of the output data */
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data_c[0][i + 4] = data_ptrs->plane_data_c[2][i +
+ 4] = p;
+ p += misc_vars->plane_size_c / 2;
+ }
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->plane_data_c[1][i + 4] = p;
+ data_ptrs->plane_data_c[3][i + 4] = p + misc_vars->plane_size_c / 2;
+ p += misc_vars->plane_size_c / 2;
+ }
+
+ for (i = 0; i < misc_vars->num_comps; i++) {
+ data_ptrs->test_data[i] = p;
+ p += misc_vars->plane_size_c / 2;
+ }
+
+ /* Clear temp storage */
+ memset(data_ptrs->storage, 0, misc_vars->storage_size_words * W);
+
+ return;
+} /* end init_data_structure */
+
+/* Configure the printer and start Raster mode */
+private void
+cdj850_start_raster_mode(gx_device_printer * pdev, int paper_size,
+ FILE * prn_stream)
+{
+ int xres, yres; /* x,y resolution for color planes */
+ hp850_cmyk_init_t init;
+
+ init = hp850_cmyk_init;
+ init.a[13] = cdj850->intensities; /* Intensity levels cyan */
+ init.a[19] = cdj850->intensities; /* Intensity levels magenta */
+ init.a[25] = cdj850->intensities; /* Intensity levels yellow */
+
+ /* black plane resolution */
+ assign_dpi(cdj850->x_pixels_per_inch, init.a + 2);
+ assign_dpi(cdj850->y_pixels_per_inch, init.a + 4);
+ /* color plane resolution */
+ xres = cdj850->x_pixels_per_inch / (cdj850->xscal + 1);
+ yres = cdj850->y_pixels_per_inch / (cdj850->yscal + 1);
+ /* cyan */
+ assign_dpi(xres, init.a + 8);
+ assign_dpi(yres, init.a + 10);
+ /* magenta */
+ assign_dpi(xres, init.a + 14);
+ assign_dpi(yres, init.a + 16);
+ /* yellow */
+ assign_dpi(xres, init.a + 20);
+ assign_dpi(yres, init.a + 22);
+
+ fputs("\033*rbC", prn_stream); /* End raster graphics */
+ fputs("\033E", prn_stream); /* Reset */
+ /* Page size, orientation, top margin & perforation skip */
+ fprintf(prn_stream, "\033&l%daolE", paper_size);
+
+ /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
+ fprintf(prn_stream, "\033*o%dM", cdj850->quality);
+ /* Media Type,0 = plain paper, 1 = bond paper, 2 = special
+ paper, 3 = glossy film, 4 = transparency film */
+ fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
+
+ /* Move to top left of printed area */
+ fprintf(prn_stream, "\033*p%dY", (int)(600 * DOFFSET));
+
+ /* This will start and configure the raster-mode */
+ fprintf(prn_stream, "\033*g%dW", (int)sizeof(init.a)); /* The new configure
+ raster data comand */
+ fwrite(init.a, sizeof(byte), sizeof(init.a),
+ prn_stream); /* Transmit config
+ data */
+ /* From now on, all escape commands start with \033*b, so we
+ * combine them (if the printer supports this). */
+ fputs("\033*b", prn_stream);
+ /* Set compression if the mode has been defined. */
+ if (cdj850->compression)
+ fprintf(prn_stream, "%dm", cdj850->compression);
+
+ return;
+} /* end configure raster-mode */
+
+private int
+cdj_put_param_int(gs_param_list * plist, gs_param_name pname, int *pvalue,
+ int minval, int maxval, int ecode)
+{
+ int code, value;
+
+ switch (code = param_read_int(plist, pname, &value)) {
+ default:
+ return code;
+ case 1:
+ return ecode;
+ case 0:
+ if (value < minval || value > maxval)
+ param_signal_error(plist, pname, gs_error_rangecheck);
+ *pvalue = value;
+ return (ecode < 0 ? ecode : 1);
+ }
+}
+
+private int
+cdj_put_param_float(gs_param_list * plist, gs_param_name pname, float *pvalue,
+ float minval, float maxval, int ecode)
+{
+ int code;
+ float value;
+
+ switch (code = param_read_float(plist, pname, &value)) {
+ default:
+ return code;
+ case 1:
+ return ecode;
+ case 0:
+ if (value < minval || value > maxval)
+ param_signal_error(plist, pname, gs_error_rangecheck);
+ *pvalue = value;
+ return (ecode < 0 ? ecode : 1);
+ }
+}
+
+private int
+cdj_set_bpp(gx_device * pdev, int bpp, int ccomps)
+{
+ gx_device_color_info *ci = &pdev->color_info;
+
+ if (ccomps && bpp == 0) {
+ if (cprn_device->cmyk) {
+ switch (ccomps) {
+ default:
+ return gs_error_rangecheck;
+ /*NOTREACHED */
+ break;
+
+ case 1:
+ bpp = 1;
+ break;
+
+ case 3:
+ bpp = 24;
+ break;
+
+ case 4:
+ switch (ci->depth) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+
+ default:
+ bpp = cprn_device->default_depth;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ if (bpp == 0) {
+ bpp = ci->depth; /* Use the current setting. */
+ }
+ if (cprn_device->cmyk < 0) {
+
+ /* Reset procedures because we may have been in another mode. */
+
+ dev_proc(pdev, map_cmyk_color) = gdev_cmyk_map_cmyk_color;
+ dev_proc(pdev, map_rgb_color) = NULL;
+ dev_proc(pdev, map_color_rgb) = gdev_cmyk_map_color_rgb;
+
+ if (pdev->is_open)
+ gs_closedevice(pdev);
+ }
+ /* Check for valid bpp values */
+
+ switch (bpp) {
+ case 16:
+ case 32:
+ if (cprn_device->cmyk && ccomps && ccomps != 4)
+ goto bppe;
+ break;
+
+ case 24:
+ if (!cprn_device->cmyk || ccomps == 0 || ccomps == 4) {
+ break;
+ } else if (ccomps == 1) {
+ goto bppe;
+ } else {
+
+ /* 3 components 24 bpp printing for CMYK device. */
+
+ cprn_device->cmyk = -1;
+ }
+ break;
+
+ case 8:
+ if (cprn_device->cmyk) {
+ if (ccomps) {
+ if (ccomps == 3) {
+ cprn_device->cmyk = -1;
+ bpp = 3;
+ } else if (ccomps != 1 && ccomps != 4) {
+ goto bppe;
+ }
+ }
+ if (ccomps != 1)
+ break;
+ } else {
+ break;
+ }
+
+ case 1:
+ if (ccomps != 1)
+ goto bppe;
+
+ if (cprn_device->cmyk && bpp != pdev->color_info.depth) {
+ dev_proc(pdev, map_cmyk_color) = NULL;
+ dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color;
+
+ if (pdev->is_open) {
+ gs_closedevice(pdev);
+ }
+ }
+ break;
+
+ case 3:
+ if (!cprn_device->cmyk) {
+ break;
+ }
+ default:
+ bppe:return gs_error_rangecheck;
+ }
+
+
+ if (cprn_device->cmyk == -1) {
+ dev_proc(pdev, map_cmyk_color) = NULL;
+ dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color;
+ dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb;
+
+ if (pdev->is_open) {
+ gs_closedevice(pdev);
+ }
+ }
+ switch (ccomps) {
+ case 0:
+ break;
+
+ case 1:
+ if (bpp != 1 && bpp != 8)
+ goto cce;
+ break;
+
+ case 4:
+ if (cprn_device->cmyk) {
+ if (bpp >= 8)
+ break;
+ }
+ case 3:
+ if (bpp == 1 || bpp == 3 || bpp == 8 || bpp == 16
+ || bpp == 24 || bpp == 32) {
+ break;
+ }
+ cce: default:
+ return gs_error_rangecheck;
+ }
+
+ if (cprn_device->cmyk) {
+ if (cprn_device->cmyk > 0) {
+ ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4);
+ } else {
+ ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3);
+ }
+ if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */
+ bpp = bpp < 8 ? 8 : bpp;
+ }
+ ci->max_color = (1 << (bpp >> 2)) - 1;
+ ci->max_gray = (bpp >= 8 ? 255 : 1);
+
+ if (ci->num_components == 1) {
+ ci->dither_grays = (bpp >= 8 ? 5 : 2);
+ ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
+ } else {
+ ci->dither_grays = (bpp > 8 ? 5 : 2);
+ ci->dither_colors = (bpp > 8 ? 5 : bpp > 1 ? 2 : 0);
+ }
+ } else {
+ ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3);
+ ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
+ ci->max_gray = (bpp >= 8 ? 255 : 1);
+ ci->dither_grays = (bpp >= 8 ? 5 : 2);
+ ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
+ }
+
+ ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp);
+
+ return 0;
+}
+
+/*
+ * Map a CMYK color to a color index. We just use depth / 4 bits per color
+ * to produce the color index.
+ *
+ * Important note: CMYK values are stored in the order K, C, M, Y because of
+ * the way the HP drivers work.
+ *
+ */
+
+#define gx_color_value_to_bits(cv, b) \
+ ((cv) >> (gx_color_value_bits - (b)))
+#define gx_bits_to_color_value(cv, b) \
+ ((cv) << (gx_color_value_bits - (b)))
+
+#define gx_cmyk_value_bits(c, m, y, k, b) \
+ ((gx_color_value_to_bits((k), (b)) << (3 * (b))) | \
+ (gx_color_value_to_bits((c), (b)) << (2 * (b))) | \
+ (gx_color_value_to_bits((m), (b)) << (b)) | \
+ (gx_color_value_to_bits((y), (b))))
+
+#define gx_value_cmyk_bits(v, c, m, y, k, b) \
+ (k) = gx_bits_to_color_value(((v) >> (3 * (b))) & ((1 << (b)) - 1), (b)), \
+ (c) = gx_bits_to_color_value(((v) >> (2 * (b))) & ((1 << (b)) - 1), (b)), \
+ (m) = gx_bits_to_color_value(((v) >> (b)) & ((1 << (b)) - 1), (b)), \
+ (y) = gx_bits_to_color_value((v) & ((1 << (b)) - 1), (b))
+
+private gx_color_index
+gdev_cmyk_map_cmyk_color(gx_device * pdev,
+ gx_color_value cyan, gx_color_value magenta,
+ gx_color_value yellow,
+ gx_color_value black)
+{
+
+ gx_color_index color;
+
+ switch (pdev->color_info.depth) {
+ case 1:
+ color = (cyan | magenta | yellow | black) > gx_max_color_value / 2 ?
+ (gx_color_index) 1 : (gx_color_index) 0;
+ break;
+
+ default:{
+ int nbits = pdev->color_info.depth;
+
+ if (cyan == magenta && magenta == yellow) {
+ /* Convert CMYK to gray -- Red Book 6.2.2 */
+ float bpart = ((float)cyan) * (lum_red_weight / 100.) +
+ ((float)magenta) * (lum_green_weight / 100.) +
+ ((float)yellow) * (lum_blue_weight / 100.) +
+ (float)black;
+
+ cyan = magenta = yellow = (gx_color_index) 0;
+ black = (gx_color_index) (bpart > gx_max_color_value ?
+ gx_max_color_value : bpart);
+ }
+ color = gx_cmyk_value_bits(cyan, magenta, yellow, black,
+ nbits >> 2);
+ }
+ }
+
+ return color;
+}
+
+/* Mapping of RGB colors to gray values. */
+
+private gx_color_index
+gdev_cmyk_map_rgb_color(gx_device * pdev, gx_color_value r, gx_color_value
+ g, gx_color_value b)
+{
+ if (gx_color_value_to_byte(r & g & b) == 0xff) {
+ return (gx_color_index) 0; /* White */
+ } else {
+ gx_color_value c = gx_max_color_value - r;
+ gx_color_value m = gx_max_color_value - g;
+ gx_color_value y = gx_max_color_value - b;
+
+ switch (pdev->color_info.depth) {
+ case 1:
+ return (c | m | y) > gx_max_color_value / 2 ?
+ (gx_color_index) 1 : (gx_color_index) 0;
+ /*NOTREACHED */
+ break;
+
+ case 8:
+ return ((ulong) c * lum_red_weight * 10
+ + (ulong) m * lum_green_weight * 10
+ + (ulong) y * lum_blue_weight * 10)
+ >> (gx_color_value_bits + 2);
+ /*NOTREACHED */
+ break;
+ }
+ }
+
+ return (gx_color_index) 0; /* This should never happen. */
+}
+
+/* Mapping of CMYK colors. */
+private int
+gdev_cmyk_map_color_rgb(gx_device * pdev, gx_color_index color,
+ gx_color_value prgb[3])
+{
+ switch (pdev->color_info.depth) {
+ case 1:
+ prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color);
+ break;
+
+ case 8:
+ if (pdev->color_info.num_components == 1) {
+ gx_color_value value = (gx_color_value) color ^ 0xff;
+
+ prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
+
+ break;
+ }
+ default:{
+ unsigned long bcyan, bmagenta, byellow, black;
+ int nbits = pdev->color_info.depth;
+
+ gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black,
+ nbits >> 2);
+
+#ifdef USE_ADOBE_CMYK_RGB
+
+ /* R = 1.0 - min(1.0, C + K), etc. */
+
+ bcyan += black, bmagenta += black, byellow += black;
+ prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 :
+ gx_max_color_value - bcyan);
+ prgb[1] = (bmagenta > gx_max_color_value ? (gx_color_value) 0 :
+ gx_max_color_value - bmagenta);
+ prgb[2] = (byellow > gx_max_color_value ? (gx_color_value) 0 :
+ gx_max_color_value - byellow);
+
+#else
+
+ /* R = (1.0 - C) * (1.0 - K), etc. */
+
+ prgb[0] = (gx_color_value)
+ ((ulong) (gx_max_color_value - bcyan) *
+ (gx_max_color_value - black) / gx_max_color_value);
+ prgb[1] = (gx_color_value)
+ ((ulong) (gx_max_color_value - bmagenta) *
+ (gx_max_color_value - black) / gx_max_color_value);
+ prgb[2] = (gx_color_value)
+ ((ulong) (gx_max_color_value - byellow) *
+ (gx_max_color_value - black) / gx_max_color_value);
+
+#endif
+
+ }
+ }
+
+ return 0;
+}
+
+private gx_color_index
+gdev_pcl_map_rgb_color(gx_device * pdev, gx_color_value r,
+ gx_color_value g, gx_color_value b)
+{
+ if (gx_color_value_to_byte(r & g & b) == 0xff)
+ return (gx_color_index) 0; /* white */
+ else {
+ gx_color_value c = gx_max_color_value - r;
+ gx_color_value m = gx_max_color_value - g;
+ gx_color_value y = gx_max_color_value - b;
+
+ switch (pdev->color_info.depth) {
+ case 1:
+ return ((c | m | y) > gx_max_color_value / 2 ?
+ (gx_color_index) 1 : (gx_color_index) 0);
+ case 8:
+ if (pdev->color_info.num_components >= 3)
+#define gx_color_value_to_1bit(cv) ((cv) >> (gx_color_value_bits - 1))
+ return (gx_color_value_to_1bit(c) +
+ (gx_color_value_to_1bit(m) << 1) +
+ (gx_color_value_to_1bit(y) << 2));
+ else
+#define red_weight 306
+#define green_weight 601
+#define blue_weight 117
+ return ((((ulong) c * red_weight +
+ (ulong) m * green_weight +
+ (ulong) y * blue_weight)
+ >> (gx_color_value_bits + 2)));
+ case 16:
+#define gx_color_value_to_5bits(cv) ((cv) >> (gx_color_value_bits - 5))
+#define gx_color_value_to_6bits(cv) ((cv) >> (gx_color_value_bits - 6))
+ return (gx_color_value_to_5bits(y) +
+ (gx_color_value_to_6bits(m) << 5) +
+ (gx_color_value_to_5bits(c) << 11));
+ case 24:
+ return (gx_color_value_to_byte(y) +
+ (gx_color_value_to_byte(m) << 8) +
+ ((ulong) gx_color_value_to_byte(c) << 16));
+ case 32:
+ {
+ return ((c == m && c == y) ? ((ulong)
+ gx_color_value_to_byte(c) << 24)
+ : (gx_color_value_to_byte(y) +
+ (gx_color_value_to_byte(m) << 8) +
+ ((ulong) gx_color_value_to_byte(c) << 16)));
+ }
+ }
+ }
+ return (gx_color_index) 0; /* This never happens */
+}
+
+/* Map a color index to a r-g-b color. */
+private int
+gdev_pcl_map_color_rgb(gx_device * pdev, gx_color_index color,
+ gx_color_value prgb[3])
+{
+ /* For the moment, we simply ignore any black correction */
+ switch (pdev->color_info.depth) {
+ case 1:
+ prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
+ break;
+ case 8:
+ if (pdev->color_info.num_components >= 3) {
+ gx_color_value c = (gx_color_value) color ^ 7;
+
+ prgb[0] = -(c & 1);
+ prgb[1] = -((c >> 1) & 1);
+ prgb[2] = -(c >> 2);
+ } else {
+ gx_color_value value = (gx_color_value) color ^ 0xff;
+
+ prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
+ }
+ break;
+ case 16:
+ {
+ gx_color_value c = (gx_color_value) color ^ 0xffff;
+ ushort value = c >> 11;
+
+ prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
+ (value >> 4)) >> (16 - gx_color_value_bits);
+ value = (c >> 6) & 0x3f;
+ prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
+ >> (16 - gx_color_value_bits);
+ value = c & 0x1f;
+ prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
+ (value >> 4)) >> (16 - gx_color_value_bits);
+ }
+ break;
+ case 24:
+ {
+ gx_color_value c = (gx_color_value) color ^ 0xffffff;
+
+ prgb[0] = gx_color_value_from_byte(c >> 16);
+ prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff);
+ prgb[2] = gx_color_value_from_byte(c & 0xff);
+ }
+ break;
+ case 32:
+#define gx_maxcol gx_color_value_from_byte(gx_color_value_to_byte(gx_max_color_value))
+ {
+ gx_color_value w = gx_maxcol - gx_color_value_from_byte(color >> 24);
+
+ prgb[0] = w - gx_color_value_from_byte((color >> 16) & 0xff);
+ prgb[1] = w - gx_color_value_from_byte((color >> 8) & 0xff);
+ prgb[2] = w - gx_color_value_from_byte(color & 0xff);
+ }
+ break;
+ }
+ return 0;
+}
+
+/* new_bpp == save_bpp or new_bpp == 0 means don't change bpp.
+ ccomps == 0 means don't change number of color comps.
+ If new_bpp != 0, it must be the value of the BitsPerPixel element of
+ the plist; real_bpp may differ from new_bpp.
+ */
+private int
+cdj_put_param_bpp(gx_device * pdev, gs_param_list * plist, int new_bpp,
+ int real_bpp, int ccomps)
+{
+ if (new_bpp == 0 && ccomps == 0)
+ return gdev_prn_put_params(pdev, plist);
+ else {
+ gx_device_color_info save_info;
+ int save_bpp;
+ int code;
+
+ save_info = pdev->color_info;
+ save_bpp = save_info.depth;
+#define save_ccomps save_info.num_components
+ if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk)
+ save_bpp = 3;
+ code = cdj_set_bpp(pdev, real_bpp, ccomps);
+ if (code < 0) {
+ param_signal_error(plist, "BitsPerPixel", code);
+ param_signal_error(plist, "ProcessColorModel", code);
+ return code;
+ }
+ pdev->color_info.depth = new_bpp; /* cdj_set_bpp maps 3/6 to 8 */
+ code = gdev_prn_put_params(pdev, plist);
+ if (code < 0) {
+ cdj_set_bpp(pdev, save_bpp, save_ccomps);
+ return code;
+ }
+ cdj_set_bpp(pdev, real_bpp, ccomps); /* reset depth if needed */
+ if ((cdj850->color_info.depth != save_bpp ||
+ (ccomps != 0 && ccomps != save_ccomps))
+ && pdev->is_open)
+ return gs_closedevice(pdev);
+ return 0;
+#undef save_ccomps
+ }
+}
+
+/* the following code was in the original driver but is unused
+
+ * private int
+ * x_mul_div (int a, int b, int c)
+ * {
+ * int result;
+ *
+ * result = (int) ((a * b) / c) ;
+ * return result;
+ * }
+ *
+ * private void
+ * save_color_data(int size,
+ * byte * current,
+ * byte * saved)
+ * {
+ * int i;
+ * for (i=0;i<size;i++){
+ * *saved++ = *current++;
+ * }
+ * return;
+ * }
+ *
+ * private int
+ * test_scan (int size,
+ * byte * current,
+ * byte * last,
+ * byte * control)
+ * {
+ * int error = 0;
+ * int i;
+ *
+ * for (i=0;i<size;i++){
+ * if (*control != *last){
+ * error = 1;
+ * }
+ * *control = *current;
+ *
+ * control++;
+ * last++;
+ * current++;
+ * }
+ * return error;
+ * }
+ *
+ * * Transform from cmy into hsv
+ * private void
+ * cmy2hsv(int *c, int *m, int *y, int *h, int *s, int *v)
+ * {
+ * int hue;
+ * int r, g, b;
+ * int r1, g1, b1;
+ * int maxValue, minValue, diff;
+ *
+ * r = 255 - *c;
+ * g = 255 - *m;
+ * b = 255 - *y;
+ *
+ * maxValue = max(r, max(g,b));
+ * minValue = min(r,min(g,b));
+ * diff = maxValue - minValue;
+ * *v = maxValue;
+ *
+ * if (maxValue != 0)
+ * *s = x_mul_div(diff,255,maxValue);
+ * else
+ * *s = 0;
+ *
+ * if (*s == 0)
+ * {
+ * hue = 0;
+ * }
+ * else
+ * {
+ * r1 = x_mul_div(maxValue - r,255,diff);
+ * g1 = x_mul_div(maxValue - g,255,diff);
+ * b1 = x_mul_div(maxValue - b,255,diff);
+ *
+ * if (r == maxValue)
+ * hue = b1 - g1;
+ * else if (g == maxValue)
+ * hue = 510 + r1 - b1;
+ * else
+ * hue = 1020 + g1 - r1;
+ *
+ * if (hue < 0)
+ * hue += 1530;
+ * }
+ *
+ * *h = (hue + 3) / 6;
+ *
+ * return;
+ * }
+ * end of unused code */
+
+
+/************************ the routines for the cdj1600 printer ***************/
+
+/* Configure the printer and start Raster mode */
+private void
+cdj1600_start_raster_mode(gx_device_printer * pdev, int paper_size,
+ FILE * prn_stream)
+{
+ uint raster_width = pdev->width -
+ pdev->x_pixels_per_inch * (dev_l_margin(pdev) + dev_r_margin(pdev));
+
+ /* switch to PCL control language */
+ fputs("\033%-12345X@PJL enter language = PCL\n", prn_stream);
+
+ fputs("\033*rbC", prn_stream); /* End raster graphics */
+ fputs("\033E", prn_stream); /* Reset */
+
+ /* resolution */
+ fprintf(prn_stream, "\033*t%dR", (int)cdj850->x_pixels_per_inch);
+
+ /* Page size, orientation, top margin & perforation skip */
+ fprintf(prn_stream, "\033&l%daolE", paper_size);
+
+ /* no negative motion */
+ fputs("\033&a1N", prn_stream);
+
+ /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
+ fprintf(prn_stream, "\033*o%dQ", cdj850->quality);
+
+ /* Media Type,0 = plain paper, 1 = bond paper, 2 = special
+ paper, 3 = glossy film, 4 = transparency film */
+ fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
+
+ /* Move to top left of printed area */
+ fprintf(prn_stream, "\033*p%dY", (int)(300.0 * DOFFSET));
+
+ /* raster width and number of planes */
+ fprintf(prn_stream, "\033*r%ds-%du0A",
+ raster_width, pdev->color_info.num_components);
+
+ /* start raster graphics */
+ fputs("\033*r1A", prn_stream);
+
+ /* From now on, all escape commands start with \033*b, so we
+ * combine them (if the printer supports this). */
+ fputs("\033*b", prn_stream);
+
+ /* Set compression if the mode has been defined. */
+ if (cdj850->compression)
+ fprintf(prn_stream, "%dm", cdj850->compression);
+
+ return;
+} /* end configure raster-mode */
+
+/* print_plane compresses (mode 3) and outputs one plane */
+private void
+print_c3plane(FILE * prn_stream, char plane_code, int plane_size,
+ const byte * curr, byte * prev, byte * out_data)
+{
+ /* Compress the output data */
+ int out_count = gdev_pcl_mode3compress(plane_size, curr, prev, out_data);
+
+ /* and output the data */
+ if (out_count > 0) {
+ fprintf(prn_stream, "%d%c", out_count, plane_code);
+ fwrite(out_data, sizeof(byte), out_count, prn_stream);
+ } else {
+ putc(plane_code, prn_stream);
+ }
+}
+
+private int
+copy_color_data(byte * dest, const byte * src, int n)
+{
+ /* copy word by word */
+ register int i = n / 4;
+ register word *d = (word *) dest;
+ register const word *s = (const word *)src;
+
+ while (i-- > 0) {
+ *d++ = *s++;
+ }
+ return n;
+}
+
+/* Printing non-blank lines */
+private void
+cdj1600_print_non_blank_lines(gx_device_printer * pdev,
+ struct ptr_arrays *data_ptrs,
+ struct misc_struct *misc_vars,
+ struct error_val_field *error_values,
+ const Gamma *gamma,
+ FILE * prn_stream)
+{
+ int i, plane_size_c;
+
+ /* copy data to data_c in order to make do_floyd_steinberg work */
+ plane_size_c = copy_color_data
+ (data_ptrs->data_c[misc_vars->cscan],
+ data_ptrs->data[misc_vars->scan],
+ misc_vars->databuff_size) / misc_vars->storage_bpp;
+
+ /* dither the color planes */
+ do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
+ misc_vars->plane_size, plane_size_c,
+ misc_vars->num_comps, data_ptrs, pdev, error_values);
+
+ /* Transfer raster graphics in the order C, M, Y, that is
+ planes 2,1,0 */
+ for (i = misc_vars->num_comps - 1; i >= 0; i--) {
+
+ /* output the lower color planes */
+ print_c3plane(prn_stream, "wvv"[i], plane_size_c,
+ data_ptrs->plane_data_c[misc_vars->cscan][i],
+ data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
+ data_ptrs->out_data);
+ } /* End For i = num_comps */
+ misc_vars->cscan = 1 - misc_vars->cscan;
+}
+
+private void
+cdj1600_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ cdj850_terminate_page(pdev, prn_stream);
+ fputs("\033%-12345X", prn_stream);
+}
diff --git a/gs/src/gdevcdj.c b/gs/src/gdevcdj.c
index f58315372..e187e7972 100644
--- a/gs/src/gdevcdj.c
+++ b/gs/src/gdevcdj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,13 +20,15 @@
/* H-P and Canon colour printer drivers */
/****************************************************************
- * The code in this file has gotten completely out of hand.
- * Too many users have made too many "improvements" without
- * regard to the overall structure; the last three "improvements"
- * required me to spend several hours fixing each one so that
- * the code worked again at all. For this reason, no further
- * changes to this file will be accepted. I am planning eventually
- * to get these drivers rewritten from scratch.
+ * The code in this file was contributed by the authors whose names and/or
+ * e-mail addresses appear below: Aladdin Enterprises takes no
+ * responsibility for it. In the past, we have tried to keep it working,
+ * but too many users have made too many "improvements" without regard to
+ * the overall structure; the last three "improvements" required me to spend
+ * several hours fixing each one so that the code worked again at all. For
+ * this reason, no further changes to this file will be accepted. We are
+ * planning eventually to get these drivers rewritten from scratch.
+ *
* L. Peter Deutsch
* Aladdin Enterprises
* February 28, 1996
@@ -594,10 +596,9 @@ gx_device_bjc800 far_data gs_bjc800_device =
/* Forward references */
private int gdev_pcl_mode1compress(P3(const byte *, const byte *, byte *));
-private int gdev_pcl_mode9compress(P4(int, const byte *, const byte *, byte *));
private int hp_colour_open(P2(gx_device *, int));
private int hp_colour_print_page(P3(gx_device_printer *, FILE *, int));
-private int near cdj_put_param_int(P6(gs_param_list *, gs_param_name, int *, int, int, int));
+private int cdj_put_param_int(P6(gs_param_list *, gs_param_name, int *, int, int, int));
private uint gdev_prn_rasterwidth(P2(const gx_device_printer *, int));
private int cdj_put_param_bpp(P5(gx_device *, gs_param_list *, int, int, int));
private int cdj_set_bpp(P3(gx_device *, int, int));
@@ -681,7 +682,7 @@ hp_colour_open(gx_device *pdev, int ptype)
static float bjc_letter[4] = { BJC_MARGINS_LETTER }; /* Not const! */
static float bjc_a4[4] = { BJC_MARGINS_A4 }; /* Not const! */
- const float _ds *m = (float _ds*) 0;
+ const float *m = (float *) 0;
/* Set up colour params if put_params has not already done so */
if (pdev->color_info.num_components == 0)
@@ -732,7 +733,7 @@ hp_colour_open(gx_device *pdev, int ptype)
#ifndef USE_FIXED_MARGINS
if (ptype == BJC800) {
- ((float _ds*) m)[1] = BJC_HARD_LOWER_LIMIT;
+ ((float *) m)[1] = BJC_HARD_LOWER_LIMIT;
}
#endif
@@ -740,9 +741,9 @@ hp_colour_open(gx_device *pdev, int ptype)
#ifdef BJC_DEFAULT_CENTEREDAREA
if (m[3] < m[1]) {
- ((float _ds*) m)[3] = m[1]; /* Top margin = bottom one. */
+ ((float *) m)[3] = m[1]; /* Top margin = bottom one. */
} else {
- ((float _ds*) m)[1] = m[3]; /* Bottom margin = top one. */
+ ((float *) m)[1] = m[3]; /* Bottom margin = top one. */
}
#endif
@@ -757,7 +758,7 @@ hp_colour_open(gx_device *pdev, int ptype)
*/
/**/ {
- float _ds *bjcm = (float _ds*) m;
+ float *bjcm = (float *) m;
byte pdimen = (byte)
(pdev->height / pdev->y_pixels_per_inch * 10.
@@ -2102,6 +2103,10 @@ hp_colour_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype)
compression = 9;
break;
case DNJ650C:
+ if (pdev->x_pixels_per_inch == 600) {
+ /* set resolution to 600dpi 1st through PJL command */
+ fprintf(prn_stream,"\033%%-12345X@PJL SET RESOLUTION = 600\n");
+ }
fprintf (prn_stream, "\033%%0B"); /* Enter HPGL/2 mode */
fprintf (prn_stream, "BP5,1"); /* Turn off autorotation */
fprintf (prn_stream, "PS%d,%d",
@@ -2112,6 +2117,8 @@ hp_colour_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype)
fprintf (prn_stream, "\033%%1A"); /* Enter HP-RTL mode */
fprintf (prn_stream, "\033&a1N"); /* No negative motion - allow plotting
while receiving */
+ if (pdev->x_pixels_per_inch == 600)
+ fprintf (prn_stream, "\033*t600R"); /* request 600dpi via HP RTL */
{ static const char temp[] = {
033, '*', 'v', '6', 'W',
000 /* color model */,
@@ -2608,132 +2615,6 @@ hp_colour_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype)
}
/*
- * Mode 9 2D compression for the HP DeskJet 5xxC. This mode can give
- * very good compression ratios, especially if there are areas of flat
- * colour (or blank areas), and so is 'highly recommended' for colour
- * printing in particular because of the very large amounts of data which
- * can be generated
- */
-private int
-gdev_pcl_mode9compress(int bytecount, const byte * current, const byte * previous, byte * compressed)
-{
- register const byte *cur = current;
- register const byte *prev = previous;
- register byte *out = compressed;
- const byte *end = current + bytecount;
-
- while (cur < end) { /* Detect a run of unchanged bytes. */
- const byte *run = cur;
- register const byte *diff;
- int offset;
- while (cur < end && *cur == *prev) {
- cur++, prev++;
- }
- if (cur == end)
- break; /* rest of row is unchanged */
- /* Detect a run of changed bytes. */
- /* We know that *cur != *prev. */
- diff = cur;
- do {
- prev++;
- cur++;
- }
- while (cur < end && *cur != *prev);
- /* Now [run..diff) are unchanged, and */
- /* [diff..cur) are changed. */
- offset = diff - run;
- {
- const byte *stop_test = cur - 4;
- int dissimilar, similar;
-
- while (diff < cur) {
- const byte *compr = diff;
- const byte *next; /* end of run */
- byte value = 0;
- while (diff <= stop_test &&
- ((value = *diff) != diff[1] ||
- value != diff[2] ||
- value != diff[3]))
- diff++;
-
- /* Find out how long the run is */
- if (diff > stop_test) /* no run */
- next = diff = cur;
- else {
- next = diff + 4;
- while (next < cur && *next == value)
- next++;
- }
-
-#define MAXOFFSETU 15
-#define MAXCOUNTU 7
- /* output 'dissimilar' bytes, uncompressed */
- if ((dissimilar = diff - compr)) {
- int temp, i;
-
- if ((temp = --dissimilar) > MAXCOUNTU)
- temp = MAXCOUNTU;
- if (offset < MAXOFFSETU)
- *out++ = (offset << 3) | (byte) temp;
- else {
- *out++ = (MAXOFFSETU << 3) | (byte) temp;
- offset -= MAXOFFSETU;
- while (offset >= 255) {
- *out++ = 255;
- offset -= 255;
- }
- *out++ = offset;
- }
- if (temp == MAXCOUNTU) {
- temp = dissimilar - MAXCOUNTU;
- while (temp >= 255) {
- *out++ = 255;
- temp -= 255;
- }
- *out++ = (byte) temp;
- }
- for (i = 0; i <= dissimilar; i++)
- *out++ = *compr++;
- offset = 0;
- } /* end uncompressed */
-#define MAXOFFSETC 3
-#define MAXCOUNTC 31
- /* output 'similar' bytes, run-length encoded */
- if ((similar = next - diff)) {
- int temp;
-
- if ((temp = (similar -= 2)) > MAXCOUNTC)
- temp = MAXCOUNTC;
- if (offset < MAXOFFSETC)
- *out++ = 0x80 | (offset << 5) | (byte) temp;
- else {
- *out++ = 0x80 | (MAXOFFSETC << 5) | (byte) temp;
- offset -= MAXOFFSETC;
- while (offset >= 255) {
- *out++ = 255;
- offset -= 255;
- }
- *out++ = offset;
- }
- if (temp == MAXCOUNTC) {
- temp = similar - MAXCOUNTC;
- while (temp >= 255) {
- *out++ = 255;
- temp -= 255;
- }
- *out++ = (byte) temp;
- }
- *out++ = value;
- offset = 0;
- } /* end compressed */
- diff = next;
- }
- }
- }
- return out - compressed;
-}
-
-/*
* Row compression for the H-P PaintJet.
* Compresses data from row up to end_row, storing the result
* starting at compressed. Returns the number of bytes stored.
@@ -3186,7 +3067,7 @@ cdj_expand_line(word *line, int linesize, short cmyk, int bpp, int ebpp)
}
}
-private int near
+private int
cdj_put_param_int(gs_param_list *plist, gs_param_name pname, int *pvalue,
int minval, int maxval, int ecode)
{ int code, value;
diff --git a/gs/src/gdevcgm.c b/gs/src/gdevcgm.c
index 45a3c1b86..124c12e07 100644
--- a/gs/src/gdevcgm.c
+++ b/gs/src/gdevcgm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -127,7 +127,7 @@ cgm_gs_free(void *private_data, void *obj)
/* ---------------- Utilities ---------------- */
/* Convert a CGM result code to our error values. */
-private int near
+private int
cgm_error_code(cgm_result result)
{
switch (result) {
diff --git a/gs/src/gdevclj.c b/gs/src/gdevclj.c
index c29503034..7c8f2ddc3 100644
--- a/gs/src/gdevclj.c
+++ b/gs/src/gdevclj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
diff --git a/gs/src/gdevcljc.c b/gs/src/gdevcljc.c
index be32b1e80..ec4555adb 100644
--- a/gs/src/gdevcljc.c
+++ b/gs/src/gdevcljc.c
@@ -23,7 +23,6 @@
#include "math_.h"
#include "gdevprn.h"
#include "gdevpcl.h"
-#include "gxdevice.h"
/* X_DPI and Y_DPI must be the same */
#define X_DPI 300
@@ -63,7 +62,7 @@ cljc_print_page(gx_device_printer * pdev, FILE * prn_stream)
technical reference manual for other possible encodings. */
fprintf(prn_stream, "\033*v6W%c%c%c%c%c%c", 0, 3, 0, 8, 8, 8);
/* set up raster width and height, compression mode 3 */
- fprintf(prn_stream, "\033&l-60u-240Z\033*p0x0Y\033*r1A\033*b3M");
+ fprintf(prn_stream, "\033&l-90u-360Z\033*r1A\033*b3M");
/* initialize the seed row */
memset(prow, 0, worst_case_comp_size);
/* process each scanline */
diff --git a/gs/src/gdevcmap.c b/gs/src/gdevcmap.c
index 6ab1604c9..2990f3bcf 100644
--- a/gs/src/gdevcmap.c
+++ b/gs/src/gdevcmap.c
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Special color mapping device */
#include "gx.h"
#include "gserrors.h"
@@ -133,7 +133,7 @@ gdev_cmap_init(gx_device_cmap * dev, gx_device * target,
gx_device_init((gx_device *) dev, (const gx_device *)&gs_cmap_device,
target->memory, true);
- dev->target = target;
+ gx_device_set_target((gx_device_forward *)dev, target);
gx_device_copy_params((gx_device *)dev, target);
gx_device_forward_fill_in_procs((gx_device_forward *) dev);
code = gdev_cmap_set_method(dev, method);
diff --git a/gs/src/gdevcmap.h b/gs/src/gdevcmap.h
index 6adb9b3f0..940013051 100644
--- a/gs/src/gdevcmap.h
+++ b/gs/src/gdevcmap.h
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Interface to special color mapping device */
#ifndef gdevcmap_INCLUDED
diff --git a/gs/src/gdevcslw.c b/gs/src/gdevcslw.c
new file mode 100644
index 000000000..c6b7192d4
--- /dev/null
+++ b/gs/src/gdevcslw.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* CoStar LabelWriter II, II Plus driver for Ghostscript */
+/* Contributed by Mike McCauley mikem@open.com.au */
+
+#include "gdevprn.h"
+
+/* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */
+typedef ulong word;
+#define W sizeof(word)
+
+/* Printer types */
+#define LW 0
+
+/* The device descriptors */
+
+private dev_proc_print_page(coslw_print_page);
+
+const gx_device_printer gs_coslw2p_device =
+prn_device(prn_std_procs, "coslw2p",
+ 200, 400, /* 2 inches wide */
+ 128, 128, /* 5 dots per mm */
+ 0, 0, 0, 0,
+ 1, coslw_print_page);
+
+const gx_device_printer gs_coslwxl_device =
+prn_device(prn_std_procs, "coslwxl",
+ 200, 400, /* 2 inches wide */
+ 204, 204, /* 8 dots per mm */
+ 0, 0, 0, 0,
+ 1, coslw_print_page);
+
+/* ------ Internal routines ------ */
+
+/* Send the page to the printer. */
+private int
+coslw_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
+ int line_size_words = (line_size + W - 1) / W;
+ uint storage_size_words = line_size_words * 8; /* data, out_row, out_row_alt, prev_row */
+ word *storage = (ulong *) gs_malloc(storage_size_words, W,
+ "coslw_print_page");
+
+ word *data_words;
+#define data ((byte *)data_words)
+
+ byte *out_data;
+ int num_rows = dev_print_scan_lines(pdev);
+ int bytes_per_line = 0;
+ int out_count;
+ int code = 0;
+
+ if (storage == 0) /* can't allocate working area */
+ return_error(gs_error_VMerror);
+ data_words = storage;
+
+ /* Clear temp storage */
+ memset(data, 0, storage_size_words * W);
+
+ /* Initialize printer. */
+ if (pdev->PageCount == 0) {
+ }
+
+ /* Put out per-page initialization. */
+
+ /* End raster graphics, position cursor at top. */
+
+ /* Send each scan line in turn */
+ {
+ int lnum;
+ int num_blank_lines = 0;
+ word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1));
+
+ /* Transfer raster graphics. */
+ for (lnum = 0; lnum < num_rows; lnum++) {
+ register word *end_data =
+ data_words + line_size_words;
+
+ code = gdev_prn_copy_scan_lines(pdev, lnum,
+ (byte *) data, line_size);
+ if (code < 0)
+ break;
+ /* Mask off 1-bits beyond the line width. */
+ end_data[-1] &= rmask;
+ /* Remove trailing 0s. */
+ while (end_data > data_words && end_data[-1] == 0)
+ end_data--;
+ if (end_data == data_words) { /* Blank line */
+ num_blank_lines++;
+ continue;
+ }
+
+ /* We've reached a non-blank line. */
+ /* Put out a spacing command if necessary. */
+ while (num_blank_lines > 0)
+ {
+ int this_blank = 255;
+ if (num_blank_lines < this_blank)
+ this_blank = num_blank_lines;
+ fprintf(prn_stream, "\033f\001%c", this_blank);
+ num_blank_lines -= this_blank;
+ }
+
+ /* Perhaps add compression here later? */
+ out_data = data;
+ out_count = (byte *) end_data - data;
+
+ /* For 2 inch model, max width is 56 bytes */
+ if (out_count > 56)
+ out_count = 56;
+ /* Possible change the bytes per line */
+ if (bytes_per_line != out_count)
+ {
+ fprintf(prn_stream, "\033D%c", out_count);
+ bytes_per_line = out_count;
+ }
+
+ /* Transfer the data */
+ fputs("\026", prn_stream);
+ fwrite(out_data, sizeof(byte), out_count, prn_stream);
+ }
+ }
+
+ /* eject page */
+ fputs("\033E", prn_stream);
+
+ /* free temporary storage */
+ gs_free((char *)storage, storage_size_words, W, "coslw_print_page");
+
+ return code;
+}
diff --git a/gs/src/gdevdbit.c b/gs/src/gdevdbit.c
index a330ff8ad..16604b304 100644
--- a/gs/src/gdevdbit.c
+++ b/gs/src/gdevdbit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -192,7 +192,7 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x,
byte *line;
int sx, rx;
- declare_line_accum(lout, bpp, x);
+ DECLARE_LINE_ACCUM_COPY(lout, bpp, x);
code = (*dev_proc(dev, get_bits)) (dev, ry, lin, &line);
if (code < 0)
@@ -264,9 +264,9 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x,
}
}
}
- line_accum(composite, bpp);
+ LINE_ACCUM(composite, bpp);
}
- line_accum_copy(dev, lout, bpp, x, rx, raster, ry);
+ 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)");
@@ -490,13 +490,13 @@ gx_default_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
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)
+#define copy_tile(srcx, tx, ty, tw, th)\
+ if_debug5('t', " copy sx=%d => x=%d y=%d w=%d h=%d\n",\
+ srcx, tx, ty, tw, th);\
+ real_copy_tile(srcx, tx, ty, tw, th)
#else
-#define copy_tile(sx, tx, ty, tw, th)\
- real_copy_tile(sx, tx, ty, tw, th)
+#define copy_tile(srcx, tx, ty, tw, th)\
+ real_copy_tile(srcx, tx, ty, tw, th)
#endif
if (ch >= h) { /* Shallow operation */
if (icw >= w) { /* Just one (partial) tile to transfer. */
@@ -589,7 +589,7 @@ gx_copy_mono_unaligned(gx_device * dev, const byte * data,
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);
+ uint offset = ALIGNMENT_MOD(data, align_bitmap_mod);
int step = raster & (align_bitmap_mod - 1);
/* Adjust the origin. */
diff --git a/gs/src/gdevdcrd.c b/gs/src/gdevdcrd.c
new file mode 100644
index 000000000..6548f9d72
--- /dev/null
+++ b/gs/src/gdevdcrd.c
@@ -0,0 +1,178 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Create a sample device CRD */
+#include "math_.h"
+#include "memory_.h"
+#include "string_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gsparam.h"
+#include "gscspace.h" /* for gscie.h */
+#include "gscrd.h"
+#include "gscrdp.h"
+#include "gxdevcli.h"
+#include "gdevdcrd.h"
+
+/*
+ * The parameters in this driver CRD are the default PostScript values,
+ * except for the optional 'dented' procedures.
+ */
+#define DENT(v, f)\
+ (v <= 0.5 ? v * f : (v - 0.5) * (1 - (0.5 * f)) / 0.5 + 0.5 * f)
+private const gs_vector3 bit_WhitePoint = {0.9505, 1, 1.0890};
+private const gs_range3 bit_RangePQR = {
+ {{0, 0.9505}, {0, 1}, {0, 1.0890}}
+};
+private const float dent_PQR = 1.0;
+private int
+bit_TransformPQR_proc(int index, floatp in, const gs_cie_wbsd * pwbsd,
+ gs_cie_render * pcrd, float *out)
+{
+ *out = DENT(in, dent_PQR);
+ return 0;
+}
+private const gs_cie_transform_proc3 bit_TransformPQR = {
+ bit_TransformPQR_proc, "bitTPQRDefault", {0, 0}, 0
+};
+private const float dent_LMN = 1.0;
+private float
+bit_EncodeLMN_proc(floatp in, const gs_cie_render * pcrd)
+{
+ return DENT(in, dent_LMN);
+}
+private const gs_cie_render_proc3 bit_EncodeLMN = { /* dummy */
+ {bit_EncodeLMN_proc, bit_EncodeLMN_proc, bit_EncodeLMN_proc}
+};
+private const gs_range3 bit_RangeLMN = {
+ {{0, 0.9505}, {0, 1}, {0, 1.0890}}
+};
+private const gs_matrix3 bit_MatrixABC = {
+ { 3.24063, -0.96893, 0.05571},
+ {-1.53721, 1.87576, -0.20402},
+ {-0.49863, 0.04152, 1.05700}
+};
+private float
+bit_EncodeABC_proc(floatp in, const gs_cie_render * pcrd)
+{
+ return pow(max(in, 0.0), 0.45);
+}
+private const gs_cie_render_proc3 bit_EncodeABC = {
+ {bit_EncodeABC_proc, bit_EncodeABC_proc, bit_EncodeABC_proc}
+};
+/* These RenderTables are no-ops. */
+private const byte bit_rtt0[2*2*3] = {
+ /*0,0,0*/ 0,0,0,
+ /*0,0,1*/ 0,0,255,
+ /*0,1,0*/ 0,255,0,
+ /*0,1,1*/ 0,255,255
+};
+private const byte bit_rtt1[2*2*3] = {
+ /*1,0,0*/ 255,0,0,
+ /*1,0,1*/ 255,0,255,
+ /*1,1,0*/ 255,255,0,
+ /*1,1,1*/ 255,255,255
+};
+private const gs_const_string bit_rt_data[2] = {
+ {bit_rtt0, 2*2*3}, {bit_rtt1, 2*2*3}
+};
+private frac
+bit_rt_proc(byte in, const gs_cie_render *pcrd)
+{
+ return frac_1 * in / 255;
+}
+private const gs_cie_render_table_t bit_RenderTable = { /* dummy */
+ {3, {2, 2, 2}, 3, bit_rt_data},
+ {{bit_rt_proc, bit_rt_proc, bit_rt_proc}}
+};
+
+/*
+ * Implement get_params for a sample device CRD. A useful convention,
+ * for devices that can provide more than one CRD, is to have a settable
+ * parameter CRDName, which gives the name of the CRD in use. This sample
+ * code provides a constant CRDName: making it settable is left as an
+ * exercise to the reader.
+ */
+int
+sample_device_crd_get_params(gx_device *pdev, gs_param_list *plist,
+ const char *crd_param_name)
+{
+ int ecode = 0;
+
+ if (param_requested(plist, "CRDName") > 0) {
+ gs_param_string cns;
+ int code;
+
+ cns.data = (const byte *)crd_param_name;
+ cns.size = strlen(crd_param_name);
+ cns.persistent = true;
+ code = param_write_string(plist, "CRDName", &cns);
+ if (code < 0)
+ ecode = code;
+ }
+ if (param_requested(plist, crd_param_name) > 0) {
+ gs_cie_render *pcrd;
+ int code = gs_cie_render1_build(&pcrd, pdev->memory,
+ "sample_device_crd_get_params");
+ if (code >= 0) {
+ gs_cie_transform_proc3 tpqr;
+
+ tpqr = bit_TransformPQR;
+ tpqr.driver_name = pdev->dname;
+ code = gs_cie_render1_initialize(pcrd, NULL,
+ &bit_WhitePoint, NULL /*BlackPoint*/,
+ NULL /*MatrixPQR*/, &bit_RangePQR, &tpqr,
+ NULL /*MatrixLMN*/, &bit_EncodeLMN, &bit_RangeLMN,
+ &bit_MatrixABC, &bit_EncodeABC, NULL /*RangeABC*/,
+ &bit_RenderTable);
+ if (code >= 0) {
+ code = param_write_cie_render1(plist, crd_param_name, pcrd,
+ pdev->memory);
+ }
+ rc_decrement(pcrd, "sample_device_crd_get_params"); /* release */
+ }
+ if (code < 0)
+ ecode = code;
+ }
+ if (param_requested(plist, bit_TransformPQR.proc_name) > 0) {
+ /*
+ * We definitely do not recommend the following use of a static
+ * to hold the address: this is a shortcut.
+ */
+ gs_cie_transform_proc my_proc = bit_TransformPQR_proc;
+ byte *my_addr = gs_alloc_string(pdev->memory, sizeof(my_proc),
+ "sd_crd_get_params(proc)");
+ int code;
+
+ if (my_addr == 0)
+ code = gs_note_error(gs_error_VMerror);
+ else {
+ gs_param_string as;
+
+ memcpy(my_addr, &my_proc, sizeof(my_proc));
+ as.data = my_addr;
+ as.size = sizeof(my_proc);
+ as.persistent = true;
+ code = param_write_string(plist, bit_TransformPQR.proc_name, &as);
+ }
+ if (code < 0)
+ ecode = code;
+ }
+ return ecode;
+}
diff --git a/gs/src/gdevdcrd.h b/gs/src/gdevdcrd.h
new file mode 100644
index 000000000..ddd8ed1dc
--- /dev/null
+++ b/gs/src/gdevdcrd.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface for creating a sample device CRD */
+
+#ifndef gdevdcrd_INCLUDED
+#define gdevdcrd_INCLUDED
+
+/* Implement get_params for a sample device CRD. */
+int sample_device_crd_get_params(P3(gx_device *pdev, gs_param_list *plist,
+ const char *crd_param_name));
+
+#endif /* gdevdcrd_INCLUDED */
diff --git a/gs/src/gdevddrw.c b/gs/src/gdevddrw.c
index 01782d877..cec212eec 100644
--- a/gs/src/gdevddrw.c
+++ b/gs/src/gdevddrw.c
@@ -37,28 +37,110 @@
private fixed
fixed_mult_rem(fixed a, fixed b, fixed c)
{
- double prod = (double)a * b;
+ /* All kinds of truncation may happen here, but it's OK. */
+ return a * b - fixed_mult_quo(a, b, c) * c;
+}
+
+/*
+ * The trapezoid fill algorithm uses trap_line structures to keep track of
+ * the left and right edges during the Bresenham loop.
+ */
+typedef struct trap_line_s {
+ /*
+ * h is the y extent of the line (edge.end.y - edge.start.y).
+ * We know h > 0.
+ */
+ fixed h;
+ /*
+ * The dx/dy ratio for the line is di + df/h.
+ * (The quotient refers to the l.s.b. of di, not fixed_1.)
+ * We know 0 <= df < h.
+ */
+ int di;
+ fixed df;
+ /*
+ * The current position within the scan line is x + xf/h + 1.
+ * (The 1 refers to the least significant bit of x, not fixed_1;
+ * similarly, the quotient refers to the l.s.b. of x.)
+ * We know -h <= xf < 0.
+ */
+ fixed x, xf;
+ /*
+ * We increment (x,xf) by (ldi,ldf) after each scan line.
+ * (ldi,ldf) is just (di,df) converted to fixed point.
+ * We know 0 <= ldf < h.
+ */
+ fixed ldi, ldf;
+} trap_line;
+
+/*
+ * Compute the di and df members of a trap_line structure. The x extent
+ * (edge.end.x - edge.start.x) is a parameter; the y extent (h member)
+ * has already been set. Also adjust x for the initial y.
+ */
+inline private void
+compute_dx(trap_line *tl, fixed xd, fixed ys)
+{
+ fixed h = tl->h;
+ int di;
+
+ if (xd >= 0) {
+ if (xd < h)
+ tl->di = 0, tl->df = xd;
+ else {
+ tl->di = di = (int)(xd / h);
+ tl->df = xd - di * h;
+ tl->x += ys * di;
+ }
+ } else {
+ if ((tl->df = xd + h) >= 0 /* xd >= -h */)
+ tl->di = -1, tl->x -= ys;
+ else {
+ tl->di = di = (int)-((h - 1 - xd) / h);
+ tl->df = xd - di * h;
+ tl->x += ys * di;
+ }
+ }
+}
+
+#define YMULT_LIMIT (max_fixed / fixed_1)
- return (fixed) (prod - floor(prod / c) * c);
+/* Compute ldi, ldf, and xf similarly. */
+inline private void
+compute_ldx(trap_line *tl, fixed ys)
+{
+ int di = tl->di;
+ fixed df = tl->df;
+ fixed h = tl->h;
+
+ if ( df < YMULT_LIMIT ) {
+ if ( df == 0 ) /* vertical edge, worth checking for */
+ tl->ldi = int2fixed(di), tl->ldf = 0, tl->xf = -h;
+ else {
+ tl->ldi = int2fixed(di) + int2fixed(df) / h;
+ tl->ldf = int2fixed(df) % h;
+ tl->xf =
+ (ys < fixed_1 ? ys * df % h : fixed_mult_rem(ys, df, h)) - h;
+ }
+ }
+ else {
+ tl->ldi = int2fixed(di) + fixed_mult_quo(fixed_1, df, h);
+ tl->ldf = fixed_mult_rem(fixed_1, df, h);
+ tl->xf = fixed_mult_rem(ys, df, h) - h;
+ }
}
/*
- * Fill a trapezoid. Requires:
+ * Fill a trapezoid. left.start => left.end and right.start => right.end
+ * define the sides; ybot and ytop define the top and bottom. 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 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);
@@ -71,59 +153,48 @@ gx_default_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left,
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;
+ 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 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) :\
+/*
+ * Free variables of FILL_TRAP_RECT:
+ * swap_axes, pdevc, dev, lop
+ * Free variables of FILL_TRAP_RECT_DIRECT:
+ * swap_axes, fill_rect, dev, cindex
+ */
+#define FILL_TRAP_RECT(x,y,w,h)\
+ (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))
+#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
+ (swap_axes ? (*fill_rect)(dev, y, x, h, w, cindex) :\
+ (*fill_rect)(dev, x, y, w, h, cindex))
/* 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 :\
+
+ /*
+ * 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 less than 1 (as
+ * a fixed, of course); this gives us a cheap conservative check for
+ * overflow in the multiplication.
+ */
+#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))
/*
@@ -131,35 +202,39 @@ gx_default_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left,
* 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. */
+ 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);
+ 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, */
+ 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. */
+ /*
+ * 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);
+ compute_dx(&r, dxr, ysr);
if (ysr == ysl && r.h == l.h)
r.x += fxl;
else
- r.x += ymult_quo(ysr, r);
+ r.x += YMULT_QUO(ysr, r);
} else {
- compute_dx(r, dxr, ysr);
- r.x += ymult_quo(ysr, r);
+ compute_dx(&r, dxr, ysr);
+ r.x += YMULT_QUO(ysr, r);
}
rxl = fixed2int_var(l.x);
rxr = fixed2int_var(r.x);
@@ -169,56 +244,57 @@ gx_default_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left,
* or if we have a rectangle.
*/
if (iy1 - iy <= max_rect_height) {
- iy = iy1;
+ iy = iy1 - 1;
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);
+ } else {
+ /* Compute one line's worth of dx/dy. */
+ 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)\
+#define STEP_LINE(ix, 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;
+ if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
+ ix = fixed2int_var(tl.x)
+
+ if (fill_direct) {
+ gx_color_index cindex = pdevc->colors.pure;
+ dev_proc_fill_rectangle((*fill_rect)) =
+ dev_proc(dev, fill_rectangle);
+
+ while (++iy != iy1) {
+ int ixl, ixr;
+
+ STEP_LINE(ixl, l);
+ STEP_LINE(ixr, r);
+ if (ixl != rxl || ixr != rxr) {
+ code = FILL_TRAP_RECT_DIRECT(rxl, ry, rxr - rxl, iy - ry);
+ if (code < 0)
+ goto xit;
+ rxl = ixl, rxr = ixr, ry = iy;
+ }
+ }
+ code = FILL_TRAP_RECT_DIRECT(rxl, ry, rxr - rxl, iy - ry);
+ } else {
+ while (++iy != iy1) {
+ int ixl, ixr;
+
+ STEP_LINE(ixl, l);
+ STEP_LINE(ixr, r);
+ 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;
+ }
}
+ code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
}
- last:code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry);
- xit:if (code < 0 && fill_direct)
+#undef STEP_LINE
+xit: if (code < 0 && fill_direct)
return_error(code);
return_if_interrupt();
return code;
@@ -258,9 +334,7 @@ gx_default_fill_parallelogram(gx_device * dev,
if (by < 0)
px += bx, py += by, bx = -bx, by = -by;
qx = px + ax + bx;
-
#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);
@@ -341,6 +415,7 @@ gx_default_fill_triangle(gx_device * dev,
{
fixed t;
fixed ym;
+
dev_proc_fill_trapezoid((*fill_trapezoid)) =
dev_proc(dev, fill_trapezoid);
gs_fixed_edge left, right;
@@ -569,42 +644,6 @@ gx_default_begin_typed_image(gx_device * dev,
(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_planes];
- int i;
-
-#ifdef DEBUG
- if (num_planes > gs_image_max_planes) {
- lprintf2("num_planes=%d > gs_image_max_planes=%d!\n",
- num_planes, gs_image_max_planes);
- 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
diff --git a/gs/src/gdevdflt.c b/gs/src/gdevdflt.c
index b346ba774..0ea15bf82 100644
--- a/gs/src/gdevdflt.c
+++ b/gs/src/gdevdflt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,8 +23,6 @@
#include "gsropt.h"
#include "gxcomp.h"
#include "gxdevice.h"
-#include "gxdevmem.h"
-#undef mdev
/* ---------------- Default device procedures ---------------- */
@@ -66,9 +64,9 @@ gx_device_fill_in_procs(register gx_device * dev)
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.
+ * We always replace get_alpha_bits, 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)\
@@ -81,6 +79,9 @@ gx_device_fill_in_procs(register gx_device * dev)
# define CHECK_NON_DEFAULT(proc, default, procname)\
DO_NOTHING
#endif
+ CHECK_NON_DEFAULT(get_alpha_bits, gx_default_get_alpha_bits,
+ "get_alpha_bits");
+ set_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
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");
@@ -112,8 +113,8 @@ gx_default_get_initial_matrix(gx_device * dev, register gs_matrix * pmat)
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 ******/
+ /****** tx/y is WRONG for devices with ******/
+ /****** arbitrary initial matrix ******/
pmat->tx = 0;
pmat->ty = dev->height;
}
@@ -126,8 +127,8 @@ gx_upright_get_initial_matrix(gx_device * dev, register gs_matrix * pmat)
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 ******/
+ /****** tx/y is WRONG for devices with ******/
+ /****** arbitrary initial matrix ******/
pmat->tx = 0;
pmat->ty = 0;
}
@@ -141,7 +142,7 @@ gx_default_sync_output(gx_device * dev)
int
gx_default_output_page(gx_device * dev, int num_copies, int flush)
{
- int code = (*dev_proc(dev, sync_output))(dev);
+ int code = dev_proc(dev, sync_output)(dev);
if (code >= 0)
code = gx_finish_output_page(dev, num_copies, flush);
@@ -180,7 +181,8 @@ gx_page_device_get_page_device(gx_device * dev)
int
gx_default_get_alpha_bits(gx_device * dev, graphics_object_type type)
{
- return 1;
+ return (type == go_text ? dev->color_info.anti_alias.text_bits :
+ dev->color_info.anti_alias.graphics_bits);
}
int
@@ -208,45 +210,28 @@ gx_get_largest_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
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)
+ 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)
+ const gs_composite_t * pcte,
+ const gs_imager_state * pis, gs_memory_t * memory)
{
- return (*pcte->type->procs.create_default_compositor)
+ 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)
+gx_null_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
diff --git a/gs/src/gdevdgbr.c b/gs/src/gdevdgbr.c
index 6009c8e12..b5e5973b8 100644
--- a/gs/src/gdevdgbr.c
+++ b/gs/src/gdevdgbr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,6 +18,7 @@
/* Default implementation of device get_bits[_rectangle] */
+#include "memory_.h"
#include "gx.h"
#include "gserrors.h"
#include "gxdevice.h"
@@ -63,16 +64,34 @@ gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
/*
* Determine whether we can satisfy a request by simply using the stored
- * representation.
+ * representation. dev is used only for color_info.{num_components, depth}.
*/
private bool
-requested_includes_stored(gs_get_bits_options_t requested,
- gs_get_bits_options_t stored)
+requested_includes_stored(const gx_device *dev,
+ const gs_get_bits_params_t *requested,
+ const gs_get_bits_params_t *stored)
{
- gs_get_bits_options_t both = requested & stored;
+ gs_get_bits_options_t both = requested->options & stored->options;
if (!(both & GB_PACKING_ALL))
return false;
+ if (stored->options & GB_SELECT_PLANES) {
+ /*
+ * The device only provides a subset of the planes.
+ * Make sure it provides all the requested ones.
+ */
+ int i;
+ int n = (stored->options & GB_PACKING_BIT_PLANAR ?
+ dev->color_info.depth : dev->color_info.num_components);
+
+ if (!(requested->options & GB_SELECT_PLANES) ||
+ !(both & (GB_PACKING_PLANAR || GB_PACKING_BIT_PLANAR))
+ )
+ return false;
+ for (i = 0; i < n; ++i)
+ if (requested->data[i] && !stored->data[i])
+ return false;
+ }
if (both & GB_COLORS_NATIVE)
return true;
if (both & GB_COLORS_STANDARD_ALL) {
@@ -90,40 +109,57 @@ requested_includes_stored(gs_get_bits_options_t requested,
*/
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,
+ gs_get_bits_params_t *params,
+ const gs_get_bits_params_t *stored,
byte * stored_base)
{
gs_get_bits_options_t options = params->options;
+ gs_get_bits_options_t both = options & stored->options;
if (!(options & GB_RETURN_POINTER) ||
- !requested_includes_stored(options, stored)
+ !requested_includes_stored(dev, params, 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
+ * 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.
+ * 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);
+ /*
+ * For PLANAR devices, we assume that each plane consists of
+ * depth/num_components bits. This is wrong in general, but if
+ * the device wants something else, it should implement
+ * get_bits_rectangle itself.
+ */
+ uint dev_raster =
+ (both & GB_PACKING_CHUNKY ?
+ gx_device_raster(dev, true) :
+ both & GB_PACKING_PLANAR ?
+ bitmap_raster(dev->color_info.depth /
+ dev->color_info.num_components * dev->width) :
+ both & GB_PACKING_BIT_PLANAR ?
+ bitmap_raster(dev->width) :
+ 0 /* not possible */);
uint raster =
- (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
- params->raster);
+ (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
+ params->raster);
+ byte *base;
if (h <= 1 || raster == dev_raster) {
int x_offset =
- (options & GB_OFFSET_ANY ? x :
- options & GB_OFFSET_0 ? 0 : params->x_offset);
+ (options & GB_OFFSET_ANY ? x :
+ options & GB_OFFSET_0 ? 0 : params->x_offset);
if (x_offset == x) {
- params->data[0] = stored_base;
+ base = stored_base;
params->x_offset = x;
} else {
uint align_mod =
- (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
+ (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
int bit_offset = x - x_offset;
int bytes;
@@ -138,13 +174,31 @@ gx_get_bits_return_pointer(gx_device * dev, int x, int h,
/* 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);
+ base = 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 |
+ (stored->options & ~GB_PACKING_ALL) /*see below for PACKING*/ |
(params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED);
+ if (both & GB_PACKING_CHUNKY) {
+ params->options |= GB_PACKING_CHUNKY;
+ params->data[0] = base;
+ } else {
+ int n =
+ (stored->options & GB_PACKING_BIT_PLANAR ?
+ (params->options |= GB_PACKING_BIT_PLANAR,
+ dev->color_info.depth) :
+ (params->options |= GB_PACKING_PLANAR,
+ dev->color_info.num_components));
+ int i;
+
+ for (i = 0; i < n; ++i)
+ if (!(both & GB_SELECT_PLANES) || stored->data[i] != 0) {
+ params->data[i] = base;
+ base += dev_raster * dev->height;
+ }
+ }
return 0;
}
}
@@ -193,41 +247,62 @@ gx_get_bits_copy_cmyk_1bit(byte *dest_line, uint dest_raster,
* the stored data are aligned.
*
* Note: this routine does not check x, w, h for validity.
+ *
+ * The code for converting between standard and native colors has been
+ * factored out into single-use procedures strictly for readability.
+ * A good optimizing compiler would compile them in-line.
*/
+private int
+ gx_get_bits_std_to_native(P10(gx_device * dev, int x, int w, int h,
+ gs_get_bits_params_t * params,
+ const gs_get_bits_params_t *stored,
+ const byte * src_base, uint dev_raster,
+ int x_offset, uint raster)),
+ gx_get_bits_native_to_std(P11(gx_device * dev, int x, int w, int h,
+ gs_get_bits_params_t * params,
+ const gs_get_bits_params_t *stored,
+ const byte * src_base, uint dev_raster,
+ int x_offset, uint raster, uint std_raster));
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,
+ gs_get_bits_params_t * params,
+ const gs_get_bits_params_t *stored,
const byte * src_base, uint dev_raster)
{
gs_get_bits_options_t options = params->options;
- byte *data = params->data[0];
+ gs_get_bits_options_t stored_options = stored->options;
+ int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset);
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);
+ bool direct_copy = requested_includes_stored(dev, params, stored);
+ int code = 0;
/*
- * The request must include GB_PACKING_CHUNKY, GB_RETURN_COPY,
- * and an offset and raster specification.
+ * The request must include either GB_PACKING_CHUNKY or
+ * GB_PACKING_PLANAR + GB_SELECT_PLANES, GB_RETURN_COPY,
+ * and an offset and raster specification. In the planar case,
+ * the request must include GB_ALIGN_STANDARD, the stored
+ * representation must include GB_PACKING_CHUNKY, and both must
+ * include GB_COLORS_NATIVE.
*/
- if ((~options & (GB_PACKING_CHUNKY | GB_RETURN_COPY)) ||
+ if ((~options & 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);
+ if (options & GB_PACKING_CHUNKY) {
+ byte *data = params->data[0];
int end_bit = (x_offset + w) * depth;
uint std_raster =
- (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
- (end_bit + 7) >> 3);
+ (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
+ (end_bit + 7) >> 3);
uint raster =
- (options & GB_RASTER_STANDARD ? std_raster : params->raster);
+ (options & GB_RASTER_STANDARD ? std_raster : params->raster);
int dest_bit_x = x_offset * depth;
int skew = bit_x - dest_bit_x;
@@ -255,7 +330,7 @@ gx_get_bits_copy(gx_device * dev, int x, int w, int h,
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);
+ int align = ALIGNMENT_MOD(line_ptr, align_bitmap_mod);
tdev.base = line_ptr - align;
(*dev_proc(&mem_mono_device, copy_mono))
@@ -263,199 +338,267 @@ gx_get_bits_copy(gx_device * dev, int x, int w, int h,
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;
+ } else if (options & ~stored_options & GB_COLORS_NATIVE) {
+ /* Convert standard colors to native. */
+ code = gx_get_bits_std_to_native(dev, x, w, h, params, stored,
+ src_base, dev_raster,
+ x_offset, raster);
+ options = params->options;
+ } else {
+ /* Convert native colors to standard. */
+ code = gx_get_bits_native_to_std(dev, x, w, h, params, stored,
+ src_base, dev_raster,
+ x_offset, raster, std_raster);
+ options = params->options;
+ }
+ 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);
+ } else if (!(~options &
+ (GB_PACKING_PLANAR | GB_SELECT_PLANES | GB_ALIGN_STANDARD)) &&
+ (stored_options & GB_PACKING_CHUNKY) &&
+ ((options & stored_options) & GB_COLORS_NATIVE)
+ ) {
+ int num_planes = dev->color_info.num_components;
+ int dest_depth = depth / num_planes;
+ bits_plane_t source, dest;
+ int plane = -1;
+ int i;
-#define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
- gx_color_value alpha_default = src_max;
+ /* Make sure only one plane is being requested. */
+ for (i = 0; i < num_planes; ++i)
+ if (params->data[i] != 0) {
+ if (plane >= 0)
+ return_error(gs_error_rangecheck); /* > 1 plane */
+ plane = i;
+ }
+ source.data.read = src_base;
+ source.raster = dev_raster;
+ source.depth = depth;
+ source.x = x;
+ dest.data.write = params->data[plane];
+ dest.raster =
+ (options & GB_RASTER_STANDARD ?
+ bitmap_raster((x_offset + w) * dest_depth) : params->raster);
+ dest.depth = dest_depth;
+ dest.x = x_offset;
+ return bits_extract_plane(&dest, &source,
+ (num_planes - 1 - plane) * dest_depth,
+ w, h);
+ } else
+ return_error(gs_error_rangecheck);
+ return code;
+}
- options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
- for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
- int i;
+/*
+ * Convert standard colors to native. Note that the source
+ * may have depths other than 8 bits per component.
+ */
+private int
+gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
+ gs_get_bits_params_t * params,
+ const gs_get_bits_params_t *stored,
+ const byte * src_base, uint dev_raster,
+ int x_offset, uint raster)
+{
+ int depth = dev->color_info.depth;
+ int dest_bit_offset = x_offset * depth;
+ byte *dest_line = params->data[0] + (dest_bit_offset >> 3);
+ int ncolors =
+ (stored->options & GB_COLORS_RGB ? 3 :
+ stored->options & GB_COLORS_CMYK ? 4 :
+ stored->options & GB_COLORS_GRAY ? 1 : -1);
+ int ncomp = ncolors +
+ ((stored->options & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0);
+ int src_depth = GB_OPTIONS_DEPTH(stored->options);
+ 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;
- 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);
+ params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
+ for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
+ int i;
- for (i = 0; i < w; ++i) {
- int j;
- gx_color_value v[4], va = alpha_default;
- gx_color_index pixel;
+ 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);
- /* 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;
+ for (i = 0; i < w; ++i) {
+ int j;
+ gx_color_value v[4], va = alpha_default;
+ gx_color_index pixel;
- 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);
+ /* Fetch the source data. */
+ if (stored->options & GB_ALPHA_FIRST) {
+ sample_load_next16(va, src, sbit, src_depth);
+ va = v2cv(va);
}
- } 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 {
- /*
- * Convert native colors to standard.
- */
- 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;
- byte *mapped[16];
- int dest_bytes;
- int i;
-
- /* Pick the representation that's most likely to be useful. */
- if (options & GB_COLORS_RGB)
- options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB,
- dest_bytes = 3;
- else if (options & GB_COLORS_CMYK)
- options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK,
- dest_bytes = 4;
- else if (options & GB_COLORS_GRAY)
- options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY,
- dest_bytes = 1;
- else
- return_error(gs_error_rangecheck);
- /* Recompute the destination raster based on the color space. */
- if (options & GB_RASTER_STANDARD) {
- uint end_byte = (x_offset + w) * dest_bytes;
+ for (j = 0; j < ncolors; ++j) {
+ gx_color_value vj;
- raster = std_raster =
- (options & GB_ALIGN_STANDARD ?
- bitmap_raster(end_byte << 3) : end_byte);
+ sample_load_next16(vj, src, sbit, src_depth);
+ v[j] = v2cv(vj);
}
- /* Check for the one special case we care about. */
- if (((options & (GB_COLORS_RGB | GB_ALPHA_FIRST | GB_ALPHA_LAST))
- == GB_COLORS_RGB) &&
- dev_proc(dev, map_color_rgb) ==
- cmyk_1bit_map_color_rgb) {
- gx_get_bits_copy_cmyk_1bit(dest_line, raster,
- src_line, dev_raster,
- src_bit_offset & 7, w, h);
- goto done;
+ if (stored->options & GB_ALPHA_LAST) {
+ sample_load_next16(va, src, sbit, src_depth);
+ va = v2cv(va);
}
- if (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST))
- ++dest_bytes;
- /* Clear the color translation cache. */
- for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; )
- mapped[i] = 0;
- for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
- 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);
- if (pixel < 16) {
- if (mapped[pixel]) {
- /* Use the value from the cache. */
- memcpy(dest, mapped[pixel], dest_bytes);
- dest += dest_bytes;
- continue;
- }
- mapped[pixel] = dest;
- }
- (*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]);
+ /* 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);
+ }
+ return 0;
+}
+
+/*
+ * Convert native colors to standard. Only GB_DEPTH_8 is supported.
+ */
+private int
+gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
+ gs_get_bits_params_t * params,
+ const gs_get_bits_params_t *stored,
+ const byte * src_base, uint dev_raster,
+ int x_offset, uint raster, uint std_raster)
+{
+ int depth = dev->color_info.depth;
+ int src_bit_offset = x * depth;
+ const byte *src_line = src_base + (src_bit_offset >> 3);
+ gs_get_bits_options_t options = params->options;
+ int ncomp =
+ (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3);
+ byte *dest_line = params->data[0] + x_offset * ncomp;
+ byte *mapped[16];
+ int dest_bytes;
+ int i;
+
+ if (!(options & GB_DEPTH_8)) {
+ /*
+ * We don't support general depths yet, or conversion between
+ * different formats. Punt.
+ */
+ return_error(gs_error_rangecheck);
+ }
+
+ /* Pick the representation that's most likely to be useful. */
+ if (options & GB_COLORS_RGB)
+ params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB,
+ dest_bytes = 3;
+ else if (options & GB_COLORS_CMYK)
+ params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK,
+ dest_bytes = 4;
+ else if (options & GB_COLORS_GRAY)
+ params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY,
+ dest_bytes = 1;
+ else
+ return_error(gs_error_rangecheck);
+ /* Recompute the destination raster based on the color space. */
+ if (options & GB_RASTER_STANDARD) {
+ uint end_byte = (x_offset + w) * dest_bytes;
+
+ raster = std_raster =
+ (options & GB_ALIGN_STANDARD ?
+ bitmap_raster(end_byte << 3) : end_byte);
+ }
+ /* Check for the one special case we care about. */
+ if (((options & (GB_COLORS_RGB | GB_ALPHA_FIRST | GB_ALPHA_LAST))
+ == GB_COLORS_RGB) &&
+ dev_proc(dev, map_color_rgb) == cmyk_1bit_map_color_rgb) {
+ gx_get_bits_copy_cmyk_1bit(dest_line, raster,
+ src_line, dev_raster,
+ src_bit_offset & 7, w, h);
+ return 0;
+ }
+ if (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST))
+ ++dest_bytes;
+ /* Clear the color translation cache. */
+ for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; )
+ mapped[i] = 0;
+ for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
+ 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);
+ if (pixel < 16) {
+ if (mapped[pixel]) {
+ /* Use the value from the cache. */
+ memcpy(dest, mapped[pixel], dest_bytes);
+ dest += dest_bytes;
+ continue;
}
+ mapped[pixel] = dest;
}
+ (*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]);
}
-done:
- 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;
}
+/* ------ Default implementations of get_bits_rectangle ------ */
+
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)
@@ -569,11 +712,12 @@ gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
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;
+ (GB_ALIGN_STANDARD | 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;
@@ -591,7 +735,7 @@ gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
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,
+ params, &copy_params,
copy_params.data[0], dev_raster);
if (code < 0)
break;
@@ -611,8 +755,7 @@ gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
void
debug_print_gb_options(gx_bitmap_format_t options)
{
- static const char *const option_names[] =
- {
+ static const char *const option_names[] = {
GX_BITMAP_FORMAT_NAMES
};
const char *prev = " ";
@@ -630,17 +773,26 @@ debug_print_gb_options(gx_bitmap_format_t options)
}
void
-debug_print_gb_params(gs_get_bits_params_t * params)
+debug_print_gb_planes(const gs_get_bits_params_t * params, int num_planes)
{
gs_get_bits_options_t options = params->options;
+ int i;
debug_print_gb_options(options);
- dprintf1("data[0]=0x%lx", (ulong) params->data[0]);
+ for (i = 0; i < num_planes; ++i)
+ dprintf2("data[%d]=0x%lx ", i, (ulong)params->data[i]);
if (options & GB_OFFSET_SPECIFIED)
- dprintf1(" x_offset=%d", params->x_offset);
+ dprintf1("x_offset=%d ", params->x_offset);
if (options & GB_RASTER_SPECIFIED)
- dprintf1(" raster=%u", params->raster);
+ dprintf1("raster=%u", params->raster);
dputc('\n');
}
+void
+debug_print_gb_params(const gs_get_bits_params_t * params)
+{
+ debug_print_gb_planes(params, 1);
+}
+
+
#endif /* DEBUG */
diff --git a/gs/src/gdevdjet.c b/gs/src/gdevdjet.c
index e91522822..3e21a9423 100644
--- a/gs/src/gdevdjet.c
+++ b/gs/src/gdevdjet.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,10 +28,14 @@
* Frans van Hoesel (hoesel@chem.rug.nl)
* George Cameron (g.cameron@biomed.abdn.ac.uk)
* Nick Duffek (nsd@bbc.com)
+ * Thanks for the FS-600 driver to:
+ * Peter Schildmann (peter.schildmann@etechnik.uni-rostock.de)
* Thanks for the LJIIID duplex capability to:
* PDP (Philip) Brown (phil@3soft-uk.com)
* Thanks for the OCE 9050 driver to:
* William Bader (wbader@EECS.Lehigh.Edu)
+ * Thanks for the LJ4D duplex capability to:
+ * Les Johnson <les@infolabs.com>
*/
/*
@@ -106,10 +110,11 @@
#define LJ3 3
#define DJ 4
#define DJ500 5
-#define LJ4 6
+#define LJ4 6 /* also Kyocera FS-600 */
#define LP2563B 7
#define LJ3D 8
#define OCE9050 9
+#define LJ4D 10
/*
* The notion that there is such a thing as a "PCL printer" is a fiction:
@@ -136,12 +141,14 @@ private dev_proc_open_device(hpjet_open);
private dev_proc_close_device(hpjet_close);
private dev_proc_print_page(djet_print_page);
private dev_proc_print_page(djet500_print_page);
+private dev_proc_print_page(fs600_print_page);
private dev_proc_print_page(ljet_print_page);
private dev_proc_print_page(ljetplus_print_page);
private dev_proc_print_page(ljet2p_print_page);
private dev_proc_print_page(ljet3_print_page);
private dev_proc_print_page(ljet3d_print_page);
private dev_proc_print_page(ljet4_print_page);
+private dev_proc_print_page(ljet4d_print_page);
private dev_proc_print_page(lp2563_print_page);
private dev_proc_print_page(oce9050_print_page);
@@ -163,6 +170,13 @@ prn_device(prn_hp_procs, "djet500",
0, 0, 0, 0, /* margins filled in by hpjet_open */
1, djet500_print_page);
+const gx_device_printer gs_fs600_device =
+prn_device(prn_hp_procs, "fs600",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI2, Y_DPI2,
+ 0.23, 0.0, 0.23, 0.04, /* margins */
+ 1, fs600_print_page);
+
const gx_device_printer gs_laserjet_device =
prn_device(prn_hp_procs, "laserjet",
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
@@ -205,6 +219,13 @@ prn_device(prn_hp_procs, "ljet4",
0, 0, 0, 0, /* margins */
1, ljet4_print_page);
+const gx_device_printer gs_ljet4d_device =
+prn_device(prn_hp_procs, "ljet4d",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI2, Y_DPI2,
+ 0, 0, 0, 0, /* margins */
+ 1, ljet4d_print_page);
+
const gx_device_printer gs_lp2563_device =
prn_device(prn_hp_procs, "lp2563",
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
@@ -262,6 +283,8 @@ hpjet_open(gx_device * pdev)
/* If this is a LJIIID, enable Duplex. */
if (ppdev->printer_procs.print_page == ljet3d_print_page)
ppdev->Duplex = true, ppdev->Duplex_set = 0;
+ if (ppdev->printer_procs.print_page == ljet4d_print_page)
+ ppdev->Duplex = true, ppdev->Duplex_set = 0;
return gdev_prn_open(pdev);
}
@@ -270,7 +293,10 @@ hpjet_open(gx_device * pdev)
private int
hpjet_close(gx_device * pdev)
{
- gdev_prn_open_printer(pdev, 1);
+ int code =gdev_prn_open_printer(pdev, 1);
+
+ if (code < 0)
+ return code;
if (ppdev->Duplex_set >= 0 && ppdev->Duplex)
fputs("\033&l0H", ppdev->file);
fputs("\033E", ppdev->file);
@@ -295,6 +321,19 @@ djet500_print_page(gx_device_printer * pdev, FILE * prn_stream)
return hpjet_print_page(pdev, prn_stream, DJ500, 300, mode_3,
"\033&k1W");
}
+/* The Kyocera FS-600 laser printer (and perhaps other printers */
+/* which use the PeerlessPrint5 firmware) doesn't handle */
+/* ESC&l#u and ESC&l#Z correctly. */
+private int
+fs600_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ int dots_per_inch = (int)pdev->y_pixels_per_inch;
+ char real_init[60];
+
+ sprintf(real_init, "\033*r0F\033&u%dD", dots_per_inch);
+ return hpjet_print_page(pdev, prn_stream, LJ4, dots_per_inch, mode_3,
+ real_init);
+}
/* The LaserJet series II can't compress */
private int
ljet_print_page(gx_device_printer * pdev, FILE * prn_stream)
@@ -345,6 +384,16 @@ ljet4_print_page(gx_device_printer * pdev, FILE * prn_stream)
return hpjet_print_page(pdev, prn_stream, LJ4, dots_per_inch, mode_3,
real_init);
}
+private int
+ljet4d_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ int dots_per_inch = (int)pdev->y_pixels_per_inch;
+ char real_init[60];
+
+ sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
+ return hpjet_print_page(pdev, prn_stream, LJ4D, dots_per_inch, mode_3,
+ real_init);
+}
/* The 2563B line printer can't compress */
/* and doesn't support *p+ or *b vertical spacing. */
private int
@@ -436,7 +485,7 @@ hpjet_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype,
fprintf(prn_stream, "\033&l%dA", paper_size);
}
/* If printer can duplex, set duplex mode appropriately. */
- if (ptype == LJ3D) {
+ if (ptype == LJ3D || ptype == LJ4D) {
if (dupset && dup)
fputs("\033&l1S", prn_stream);
else if (dupset && !dup)
diff --git a/gs/src/gdevdrop.c b/gs/src/gdevdrop.c
index 94d4e30fb..c17283981 100644
--- a/gs/src/gdevdrop.c
+++ b/gs/src/gdevdrop.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -366,14 +366,21 @@ mem_default_strip_copy_rop(gx_device * dev,
gs_memory_t *mem = (dev->memory ? dev->memory : &gs_memory_default);
const gx_device_memory *mdproto = gdev_mem_device_for_bits(rop_depth);
gx_device_memory mdev;
+ union { long l; void *p; } mdev_storage[20];
uint row_raster = bitmap_raster(width * depth);
- bool uses_d = rop3_uses_D(gs_transparent_rop(lop));
+ gs_rop3_t trans_rop = gs_transparent_rop(lop);
+ bool uses_d = rop3_uses_D(trans_rop);
+ bool uses_s = rop3_uses_S(trans_rop);
+ bool uses_t = rop3_uses_T(trans_rop);
bool expand_s, expand_t;
byte *row = 0;
+ union { long l; void *p; } dest_buffer[16];
byte *source_row = 0;
uint source_row_raster;
+ union { long l; void *p; } source_buffer[16];
byte *texture_row = 0;
uint texture_row_raster;
+ union { long l; void *p; } texture_buffer[16];
gx_color_index source_colors[2];
const gx_color_index *real_scolors = scolors;
gx_color_index texture_colors[2];
@@ -383,6 +390,7 @@ mem_default_strip_copy_rop(gx_device * dev,
gs_int_rect rect;
gs_get_bits_params_t bit_params;
gs_get_bits_params_t expand_params;
+ gs_get_bits_params_t no_expand_params;
int max_height;
int block_height, loop_height;
int code;
@@ -392,12 +400,18 @@ mem_default_strip_copy_rop(gx_device * dev,
* Allocate a temporary row buffer. Free variables: mem, block_height.
* Labels used: out.
*/
-#define ALLOC_BUF(buf, size, cname)\
+#define ALLOC_BUF(buf, prebuf, size, cname)\
BEGIN\
- buf = gs_alloc_bytes(mem, size * block_height, cname);\
- if ( buf == 0 ) {\
- code = gs_note_error(gs_error_VMerror);\
- goto out;\
+ uint num_bytes = (size) * block_height;\
+\
+ if (num_bytes <= sizeof(prebuf))\
+ buf = (byte *)prebuf;\
+ else {\
+ buf = gs_alloc_bytes(mem, num_bytes, cname);\
+ if (buf == 0) {\
+ code = gs_note_error(gs_error_VMerror);\
+ goto out;\
+ }\
}\
END
@@ -420,8 +434,9 @@ mem_default_strip_copy_rop(gx_device * dev,
if (max_height == 0)
max_height = 1;
block_height = min(height, max_height);
- expand_s = scolors == 0 && rop3_uses_S(gs_transparent_rop(lop));
- expand_t = tcolors == 0 && rop3_uses_T(gs_transparent_rop(lop));
+ expand_s = scolors == 0 && uses_s;
+ expand_t = tcolors == 0 && uses_t;
+ no_expand_params.options = no_expand_options;
if (expand_t) {
/*
* We don't want to wrap around more than once in Y when
@@ -433,24 +448,33 @@ mem_default_strip_copy_rop(gx_device * dev,
gs_make_mem_device(&mdev, mdproto, 0, -1, NULL);
mdev.width = width;
mdev.height = block_height;
- mdev.bitmap_memory = mem;
mdev.color_info.num_components = rop_depth >> 3;
+ if (gdev_mem_data_size(&mdev, width, block_height) <= sizeof(mdev_storage)) {
+ /* Use the locally allocated storage. */
+ mdev.base = (byte *)mdev_storage;
+ mdev.line_ptrs = (byte **)
+ (mdev.base + gdev_mem_bits_size(&mdev, mdev.width, mdev.height));
+ } else {
+ mdev.bitmap_memory = mem;
+ }
code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev);
if (code < 0)
return code;
- ALLOC_BUF(row, row_raster, "copy_rop row");
+ ALLOC_BUF(row, dest_buffer, row_raster, "copy_rop row");
/* We may need intermediate buffers for all 3 operands. */
if (expand_s) {
source_row_raster = bitmap_raster(width * rop_depth);
- ALLOC_BUF(source_row, source_row_raster, "copy_rop source_row");
+ ALLOC_BUF(source_row, source_buffer, source_row_raster,
+ "copy_rop source_row");
}
- if (scolors) {
+ if (scolors && uses_s) {
unpack_colors_to_standard(dev, source_colors, scolors, rop_depth);
real_scolors = source_colors;
}
if (expand_t) {
texture_row_raster = bitmap_raster(textures->rep_width * rop_depth);
- ALLOC_BUF(texture_row, texture_row_raster, "copy_rop texture_row");
+ ALLOC_BUF(texture_row, texture_buffer, texture_row_raster,
+ "copy_rop texture_row");
rop_texture = *textures;
rop_texture.data = texture_row;
rop_texture.raster = texture_row_raster;
@@ -458,7 +482,7 @@ mem_default_strip_copy_rop(gx_device * dev,
rop_texture.id = gs_no_bitmap_id;
real_texture = &rop_texture;
}
- if (tcolors) {
+ if (tcolors && uses_t) {
unpack_colors_to_standard(dev, texture_colors, tcolors, rop_depth);
real_tcolors = texture_colors;
}
@@ -481,7 +505,7 @@ mem_default_strip_copy_rop(gx_device * dev,
rect.q.y = py + loop_height;
expand_params.data[0] = texture_row;
gx_get_bits_copy(dev, 0, textures->rep_width, loop_height,
- &expand_params, no_expand_options,
+ &expand_params, &no_expand_params,
textures->data + rep_y * textures->raster,
textures->raster);
/*
@@ -506,8 +530,7 @@ mem_default_strip_copy_rop(gx_device * dev,
if (expand_s) {
expand_params.data[0] = source_row;
gx_get_bits_copy(dev, sx, width, loop_height, &expand_params,
- no_expand_options, source_data,
- sraster);
+ &no_expand_params, source_data, sraster);
sx = 0;
source_data = source_row;
source_raster = source_row_raster;
@@ -519,25 +542,28 @@ mem_default_strip_copy_rop(gx_device * dev,
if (code < 0)
break;
{
- /* Convert the result back to the device's format. */
+ /*
+ * Convert the result back to the device's format. We know
+ * the device is a memory device, so we can store the result
+ * directly into its scan lines.
+ */
int i;
- byte *packed = row;
const byte *unpacked = scan_line_base(&mdev, 0);
- for (i = 0; i < loop_height;
- packed += row_raster, unpacked += mdev.raster, ++i)
- pack(dev, packed, 0, unpacked, width, depth, rop_depth);
+ for (i = 0; i < loop_height; unpacked += mdev.raster, ++i) {
+ byte *packed = scan_line_base((gx_device_memory *)dev, py + i);
+
+ pack(dev, packed, x, unpacked, width, depth, rop_depth);
+ }
}
- code = (*dev_proc(dev, copy_color))
- (dev, row, 0, row_raster, gx_no_bitmap_id,
- x, py, width, loop_height);
- if (code < 0)
- break;
}
out:
- gs_free_object(mem, texture_row, "copy_rop texture_row");
- gs_free_object(mem, source_row, "copy_rop source_row");
- gs_free_object(mem, row, "copy_rop row");
+ if (texture_row != 0 && texture_row != (byte *)texture_buffer)
+ gs_free_object(mem, texture_row, "copy_rop texture_row");
+ if (source_row != 0 && source_row != (byte *)source_buffer)
+ gs_free_object(mem, source_row, "copy_rop source_row");
+ if (row != 0 && row != (byte *)dest_buffer)
+ gs_free_object(mem, row, "copy_rop row");
(*dev_proc(&mdev, close_device)) ((gx_device *) & mdev);
return code;
}
@@ -691,4 +717,3 @@ gs_transparent_rop(gs_logical_operation_t lop)
#undef MPo
return (rop & mask) | (rop3_D & ~mask);
}
-
diff --git a/gs/src/gdevhit.c b/gs/src/gdevhit.c
index 780ddb58a..0113edbe9 100644
--- a/gs/src/gdevhit.c
+++ b/gs/src/gdevhit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,8 +33,8 @@ const int gs_hit_detected = gs_error_hit_detected;
* 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",
+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 */
diff --git a/gs/src/gdevhl7x.c b/gs/src/gdevhl7x.c
index 68b3dd723..e46571645 100644
--- a/gs/src/gdevhl7x.c
+++ b/gs/src/gdevhl7x.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -273,10 +273,6 @@ gx_device_printer far_data gs_hl7x0_device =
0, 0, 0, 0, /* margins filled in by hl7x0_open */
1, hl720_print_page); /* The hl720 and hl730 can both use the same print method */
-
-
-#define ppdev ((gx_device_printer *) pdev )
-
/* Open the printer, adjusting the margins if necessary. */
private int
@@ -284,7 +280,7 @@ hl7x0_open(gx_device *pdev)
{ /* Change the margins if necessary. */
static const float m_a4[4] = { HL7X0_MARGINS_A4 };
static const float m_letter[4] = { HL7X0_MARGINS_LETTER };
- const float _ds *m =
+ const float *m =
(gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 : m_letter);
gx_device_set_margins(pdev, m, true);
@@ -296,12 +292,14 @@ hl7x0_open(gx_device *pdev)
private int
hl7x0_close(gx_device *pdev)
{
- gdev_prn_open_printer(pdev, 1);
- fputs("@N@N@N@N@X", ppdev->file) ;
- return gdev_prn_close_printer(pdev);
-}
+ gx_device_printer *const ppdev = (gx_device_printer *)pdev;
+ int code = gdev_prn_open_printer(pdev, 1);
-#undef ppdev
+ if (code < 0)
+ return code;
+ fputs("@N@N@N@N@X", ppdev->file) ;
+ return gdev_prn_close_printer(pdev);
+}
/* ------ Internal routines ------ */
diff --git a/gs/src/gdevifno.c b/gs/src/gdevifno.c
index 05ed8d39e..0cd2cf325 100644
--- a/gs/src/gdevifno.c
+++ b/gs/src/gdevifno.c
@@ -18,6 +18,7 @@
*/
#include "gdevprn.h"
+#include "gsparam.h"
#include "gxlum.h"
#include <stdlib.h>
@@ -49,7 +50,7 @@ private WImage* initwriteimage(FILE *f, Rectangle r, int ldepth);
private int writeimageblock(WImage *w, uchar *data, int ndata);
private int bytesperline(Rectangle, int);
private int rgb2cmap(int, int, int);
-/*private long cmap2rgb(int);*/ /* not used, commented out */
+private long cmap2rgb(int);
#define X_DPI 100
#define Y_DPI 100
@@ -94,7 +95,7 @@ inferno_device far_data gs_inferno_device =
* ghostscript asks us how to convert between
* rgb and color map entries
*/
-gx_color_index
+private gx_color_index
inferno_rgb2cmap(P4(gx_device *dev, gx_color_value red,
gx_color_value green, gx_color_value blue)) {
int shift;
@@ -144,7 +145,7 @@ inferno_rgb2cmap(P4(gx_device *dev, gx_color_value red,
return ((((blue<<4)|green)<<4)|red);
}
-int
+private int
inferno_cmap2rgb(P3(gx_device *dev, gx_color_index color,
gx_color_value rgb[3])) {
int shift, i;
@@ -218,7 +219,7 @@ void init_p9color(void) /* init at run time since p9color[] is so big */
* inferno_open() is supposed to initialize the device.
* there's not much to do.
*/
-int
+private int
inferno_open(P1(gx_device *dev))
{
inferno_device *bdev = (inferno_device*) dev;
@@ -236,7 +237,7 @@ inferno_open(P1(gx_device *dev))
* inferno_close() is called at the end, once everything
* is finished. we have nothing to do.
*/
-int
+private int
inferno_close(P1(gx_device *dev))
{
int code;
@@ -251,7 +252,7 @@ inferno_close(P1(gx_device *dev))
* (actually once for each copy of each page, but we won't
* worry about that).
*/
-int
+private int
inferno_print_page(P2(gx_device_printer *pdev, FILE *f))
{
uchar buf[16384]; /* == 8192 dots across */
@@ -782,3 +783,4 @@ cmap2rgb(int c)
*
*
*/
+
diff --git a/gs/src/gdevjpeg.c b/gs/src/gdevjpeg.c
index 17ef198bb..d080c9646 100644
--- a/gs/src/gdevjpeg.c
+++ b/gs/src/gdevjpeg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,7 +19,7 @@
/* JPEG output driver */
#include "stdio_.h" /* for jpeglib.h */
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "gdevprn.h"
#include "stream.h"
#include "strimpl.h"
diff --git a/gs/src/gdevl256.c b/gs/src/gdevl256.c
index 8824d3791..e6c8eedda 100644
--- a/gs/src/gdevl256.c
+++ b/gs/src/gdevl256.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -162,7 +162,7 @@ lvga256_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g,
uint cx = ((uint) cube_bits[r5] << 2) + ((uint) cube_bits[g5] << 1) +
(uint) cube_bits[b5];
ushort rgb;
- register dc_entry _ds *pdc;
+ register dc_entry *pdc;
/* Check for a color on the cube. */
if (cx < 64)
diff --git a/gs/src/gdevl31s.c b/gs/src/gdevl31s.c
new file mode 100644
index 000000000..5fe275e69
--- /dev/null
+++ b/gs/src/gdevl31s.c
@@ -0,0 +1,280 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/*
+ * This is a driver for use with the H-P LaserJet 3100 Software.
+ * It requires installed H-P LaserJet 3100 Software to print.
+ * It can be used with smbclient to print from an UNIX box
+ * to a LaserJet 3100 printer attached to a MS-Windows box.
+ *
+ * Written by Ulrich Schmid, uschmid@mail.hh.provi.de.
+ */
+
+#include "gdevprn.h"
+#include "gdevmeds.h"
+
+#define XCORRECTION 0.11
+#define YCORRECTION 0.12
+
+/* order matters! 0 1 2 3 4 5 6 7 8 */
+const char *media[10] = {"a4", "letter", "legal", "com10", "c5", "dl", "b5", "monarch", "executive", 0};
+const int height[2][10] = {{3447, 3240, 4140, 5587, 2644, 5083, 2975, 4387, 3090, 0},
+ {6894, 6480, 8280, 11167, 5288, 10159, 5950, 8767, 6180, 0}};
+const int width[2] = {2528,
+ 5056};
+#define LARGEST_MEDIUM 2 /* legal */
+
+/* These codes correspond to sequences of pixels with the same color.
+ * After the code for a sequence < 64 pixels the color changes.
+ * After the code for a sequence with 64 pixels the previous color continues. */
+private struct {
+ uint bits;
+ uint length; /* number of valid bits */
+} code[2][65] =
+/* White */
+{{{0x0ac, 8}, {0x038, 6}, {0x00e, 4}, {0x001, 4}, {0x00d, 4}, {0x003, 4}, {0x007, 4}, {0x00f, 4},
+ {0x019, 5}, {0x005, 5}, {0x01c, 5}, {0x002, 5}, {0x004, 6}, {0x030, 6}, {0x00b, 6}, {0x02b, 6},
+ {0x015, 6}, {0x035, 6}, {0x072, 7}, {0x018, 7}, {0x008, 7}, {0x074, 7}, {0x060, 7}, {0x010, 7},
+ {0x00a, 7}, {0x06a, 7}, {0x064, 7}, {0x012, 7}, {0x00c, 7}, {0x040, 8}, {0x0c0, 8}, {0x058, 8},
+ {0x0d8, 8}, {0x048, 8}, {0x0c8, 8}, {0x028, 8}, {0x0a8, 8}, {0x068, 8}, {0x0e8, 8}, {0x014, 8},
+ {0x094, 8}, {0x054, 8}, {0x0d4, 8}, {0x034, 8}, {0x0b4, 8}, {0x020, 8}, {0x0a0, 8}, {0x050, 8},
+ {0x0d0, 8}, {0x04a, 8}, {0x0ca, 8}, {0x02a, 8}, {0x0aa, 8}, {0x024, 8}, {0x0a4, 8}, {0x01a, 8},
+ {0x09a, 8}, {0x05a, 8}, {0x0da, 8}, {0x052, 8}, {0x0d2, 8}, {0x04c, 8}, {0x0cc, 8}, {0x02c, 8},
+ {0x01b, 5}},
+/* Black */
+ {{0x3b0, 10}, {0x002, 3}, {0x003, 2}, {0x001, 2}, {0x006, 3}, {0x00c, 4}, {0x004, 4}, {0x018, 5},
+ {0x028, 6}, {0x008, 6}, {0x010, 7}, {0x050, 7}, {0x070, 7}, {0x020, 8}, {0x0e0, 8}, {0x030, 9},
+ {0x3a0, 10}, {0x060, 10}, {0x040, 10}, {0x730, 11}, {0x0b0, 11}, {0x1b0, 11}, {0x760, 11}, {0x0a0, 11},
+ {0x740, 11}, {0x0c0, 11}, {0x530, 12}, {0xd30, 12}, {0x330, 12}, {0xb30, 12}, {0x160, 12}, {0x960, 12},
+ {0x560, 12}, {0xd60, 12}, {0x4b0, 12}, {0xcb0, 12}, {0x2b0, 12}, {0xab0, 12}, {0x6b0, 12}, {0xeb0, 12},
+ {0x360, 12}, {0xb60, 12}, {0x5b0, 12}, {0xdb0, 12}, {0x2a0, 12}, {0xaa0, 12}, {0x6a0, 12}, {0xea0, 12},
+ {0x260, 12}, {0xa60, 12}, {0x4a0, 12}, {0xca0, 12}, {0x240, 12}, {0xec0, 12}, {0x1c0, 12}, {0xe40, 12},
+ {0x140, 12}, {0x1a0, 12}, {0x9a0, 12}, {0xd40, 12}, {0x340, 12}, {0x5a0, 12}, {0x660, 12}, {0xe60, 12},
+ {0x3c0, 10}}};
+
+/* Define the default, maximum resolutions. */
+#ifndef X_DPI
+# define X_DPI 600
+#endif
+#ifndef Y_DPI
+# define Y_DPI 600
+#endif
+
+/* The device descriptors */
+private dev_proc_print_page_copies(lj3100sw_print_page_copies);
+private dev_proc_close_device(lj3100sw_close);
+
+private gx_device_procs prn_lj3100sw_procs =
+ prn_params_procs(gdev_prn_open, gdev_prn_output_page, lj3100sw_close,
+ gdev_prn_get_params, gdev_prn_put_params);
+
+/* workaround to emulate the missing prn_device_margins_copies macro */
+#define gx_default_print_page_copies lj3100sw_print_page_copies
+gx_device_printer far_data gs_lj3100sw_device =
+ prn_device_margins/*_copies*/(prn_lj3100sw_procs, "lj3100sw",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ XCORRECTION, YCORRECTION,
+ 0.25, 0.2, 0.25, 0.2,
+ 1, 0 /* lj3100sw_print_page_copies */);
+#undef gx_default_print_page_copies
+
+#define ppdev ((gx_device_printer *)pdev)
+
+#define BUFFERSIZE 0x1000
+
+private void
+lj3100sw_output_section_header(FILE *prn_stream, int type, int arg1, int arg2)
+{
+ fputc(type & 0xff, prn_stream);
+ fputc(type >> 8 & 0xff, prn_stream);
+ fputc(arg1 & 0xff, prn_stream);
+ fputc(arg1 >> 8 & 0xff, prn_stream);
+ fputc(arg2 & 0xff, prn_stream);
+ fputc(arg2 >> 8 & 0xff, prn_stream);
+}
+
+private void
+lj3100sw_flush_buffer(FILE *prn_stream, char *buffer, char **pptr)
+{
+ int size = *pptr - buffer;
+ if (size) {
+ lj3100sw_output_section_header(prn_stream, 0, size, 0);
+ fwrite(buffer, 1, size, prn_stream);
+ *pptr = buffer;
+ }
+}
+
+private void
+lj3100sw_output_data_byte(FILE *prn_stream, char *buffer, char **pptr, int val)
+{
+ if (*pptr >= buffer + BUFFERSIZE)
+ lj3100sw_flush_buffer(prn_stream, buffer, pptr);
+ *(*pptr)++ = val;
+}
+
+private void
+lj3100sw_output_repeated_data_bytes(FILE *prn_stream, char *buffer, char **pptr, int val, int num)
+{
+ int size;
+ while (num) {
+ if (*pptr >= buffer + BUFFERSIZE)
+ lj3100sw_flush_buffer(prn_stream, buffer, pptr);
+ size = min(num, buffer + BUFFERSIZE - *pptr);
+ memset(*pptr, val, size);
+ *pptr += size;
+ num -= size;
+ }
+}
+
+private void
+lj3100sw_output_newline(FILE *prn_stream, char *buffer, char **pptr)
+{
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
+}
+
+private void
+lj3100sw_output_empty_line(FILE *prn_stream, char *buffer, char **pptr, bool high_resolution)
+{
+ if (high_resolution) {
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0f);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x78);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0xac);
+ } else {
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x87);
+ lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0d);
+ }
+}
+
+private int
+lj3100sw_print_page_copies(gx_device_printer *pdev, FILE *prn_stream, int num_copies /* ignored */)
+{
+ int i, j;
+ char buffer[BUFFERSIZE], *ptr = buffer;
+ int medium_index = select_medium(pdev, media, LARGEST_MEDIUM);
+ bool high_resolution = (pdev->x_pixels_per_inch > 300);
+ int printer_height = height[high_resolution ? 1 : 0][medium_index];
+ int printer_width = width[high_resolution ? 1 : 0];
+ int paper_height = pdev->height;
+ int paper_width = pdev->width;
+ int line_size = gdev_prn_raster(pdev);
+ byte *in = (byte *)gs_malloc(line_size, 1, "lj3100sw_print_page");
+ byte *data;
+ if (in == 0)
+ return_error(gs_error_VMerror);
+ if (gdev_prn_file_is_new(pdev)) {
+ lj3100sw_output_section_header(prn_stream, 1, 0, 0);
+ lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12);
+ ptr += sprintf(ptr, "\r\nBD");
+ lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520);
+ ptr += sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n",
+ "NJ",
+ "PQ", -1,
+ "RE", high_resolution ? 6 : 2,
+ "SL", printer_width,
+ "LM", 0,
+ "PS", medium_index,
+ "PC", 0);
+ lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
+ }
+
+ lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0);
+ ptr += sprintf(ptr, "%s %d\r\n%s\r\n",
+ "CM", 1,
+ "PD");
+ *ptr++ = 0;
+ lj3100sw_output_newline(prn_stream, buffer, &ptr);
+
+ for (i = 0; i < printer_height; i++) {
+ if (i < paper_height) {
+ int color = 0; /* white */
+ int count = 0;
+ int bit_index = 0;
+ uint tmp = 0;
+ gdev_prn_get_bits(pdev, i, in, &data);
+ for (j = 0; j <= printer_width; j++) {
+ int xoffset = (printer_width - paper_width) / 2;
+ int newcolor = 0;
+ if (j >= xoffset && j < xoffset + paper_width)
+ newcolor = (data[(j - xoffset) / 8] >> (7 - (j - xoffset) % 8)) & 1;
+ if (j == printer_width)
+ newcolor = !color; /* force output */
+ if (newcolor == color)
+ count++;
+ else if (count == printer_width && color == 0) /* implies j == printer_width */
+ lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
+ else /* print a sequence of pixels with a uniform color */
+ while (newcolor != color) {
+ int size = min(count, 64);
+ tmp |= code[color][size].bits << bit_index;
+ bit_index += code[color][size].length;
+ while (bit_index >= 8) {
+ lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
+ tmp >>= 8;
+ bit_index -= 8;
+ }
+ if (size == 64)
+ count -= 64;
+ else {
+ color = newcolor;
+ count = 1;
+ }
+ }
+ }
+ if (bit_index)
+ lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
+ }
+ else
+ lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
+ lj3100sw_output_newline(prn_stream, buffer, &ptr);
+ }
+
+ for (i = 0; i < 3; i++ ) {
+ lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x00);
+ lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x08);
+ lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x80);
+ }
+ lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 520);
+ lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
+
+ lj3100sw_output_section_header(prn_stream, 4, 0, 0);
+ for (i = 0; i < 4 * ppdev->NumCopies; i++)
+ lj3100sw_output_section_header(prn_stream, 54, 0, 0);
+
+ gs_free((char *)in, line_size, 1, "lj3100sw_print_page");
+ return 0;
+}
+
+private int
+lj3100sw_close(gx_device *pdev)
+{
+ int i;
+ FILE *prn_stream = ((gx_device_printer *)pdev)->file;
+
+ lj3100sw_output_section_header(prn_stream, 0, 4, 0);
+ fputs("XX\r\n", prn_stream);
+ for (i = 0; i < 4 * ppdev->NumCopies; i++)
+ lj3100sw_output_section_header(prn_stream, 54, 0, 0);
+ lj3100sw_output_section_header(prn_stream, 2, 0, 0);
+
+ return gdev_prn_close(pdev);
+}
diff --git a/gs/src/gdevlj56.c b/gs/src/gdevlj56.c
index 647426661..c36cab761 100644
--- a/gs/src/gdevlj56.c
+++ b/gs/src/gdevlj56.c
@@ -265,7 +265,8 @@ ljet5_print_page(gx_device_printer * pdev, FILE * prn_stream)
goto fin;
put_us(lnum, prn_stream);
fwrite_bytes(line_header, prn_stream);
- ncompr = gdev_pcl_mode2compress(line, line + line_size_words, out);
+ ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words,
+ out, true);
if (ncompr <= 255) {
fputc(pxt_dataLengthByte, prn_stream);
fputc(ncompr, prn_stream);
diff --git a/gs/src/gdevlxm.c b/gs/src/gdevlxm.c
new file mode 100644
index 000000000..c3f0384fa
--- /dev/null
+++ b/gs/src/gdevlxm.c
@@ -0,0 +1,423 @@
+/* Copyright (C) 1989-1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/*
+ * Lexmark 5700 ink-jet printer driver for Ghostscript
+ *
+ * defines the lxm5700m device for printing in black-and-white at 1200 dpi
+ * doesn't handle color or any other resolution.
+ * Native resolution appears to be 600 x 1200, but print bands are overlapped.
+ *
+ * I use the command
+ * gs -sOutputFile=/dev/lp0 -sDevice=lxm5700m -dHeadSeparation=15 file.ps
+ *
+ * where HeadSeparation varies from print-cartridge to print-cartridge and
+ * 16 (the default) usually works fine.
+ *
+ * Stephen Taylor setaylor@ma.ultranet.com staylor@cs.wpi.edu
+ */
+
+#include "gdevprn.h"
+#include "gsparams.h"
+
+/* The procedure descriptors */
+/* declare functions */
+private dev_proc_print_page(lxm5700m_print_page);
+private dev_proc_get_params(lxm_get_params);
+private dev_proc_put_params(lxm_put_params);
+
+/* set up dispatch table. I follow gdevdjet in using gdev_prn_output_page */
+static const gx_device_procs lxm5700m_procs =
+ prn_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
+ lxm_get_params, lxm_put_params);
+
+/* The device descriptors */
+
+/* define a subclass with useful state in it. */
+typedef struct lxm_device_s { /* a sub-class of gx_device_printer */
+ gx_device_common;
+ gx_prn_device_common;
+ int headSeparation;
+} lxm_device;
+
+/* Standard lxm5700m device */
+lxm_device far_data gs_lxm5700m_device = {
+ prn_device_std_body(lxm_device, lxm5700m_procs, "lxm5700m",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ 600, 600, /* x dpi, y dpi */
+ 0.2, 0.0, 0.0, 0.0, /* margins */
+ 1, lxm5700m_print_page),
+ 16 /* default headSeparation value */
+};
+
+/* I don't know the whole protocol for the printer, but let me tell
+ * you about the fraction I use.
+ * Each page begins with a header, which I describe as init1, init2, init3 --
+ * (I separate them, because I've seen output in which those sections
+ * seemed to appear independently, but I've deleted the only code I
+ * had that actually used them separately.)
+ * Then there are a number of swipe commands, each of which describes one
+ * swipe of the printhead. Each swipe command begins with a fixed
+ * header, which gives the number of bytes in the command,
+ * left and right margins,
+ * a vertical offset, some noise characters I don't know the meaning of,
+ * and the table of bits. The bits are given one column at a time, using a
+ * simple compression scheme: a directory, consisting of two bytes, tells
+ * which sixteen-bit intervals of the 208-bit column contain 1-bits; then
+ * the appropriate number of sixteen-bit bit-maps follow. (A zero-bit in the
+ * directory indicates that a bitmap for that sector follows.) In the worst case,
+ * this scheme would be bigger than the uncompressed bitmap, but it seems to
+ * usually save 80-90%. The biggest complication of the bitmap scheme is this:
+ * There are two print-heads on the black cartridge, and they are 16 pixels
+ * (or headSeparation) apart. Odd columns of the swipe address one printhead,
+ * and even columns the other. On the following swipe, the printheads
+ * addressed by even and odd columns are reversed. I think the printheads might be
+ * staggered, but the output I've seen staggers things in software;
+ * adjacent vertical bits on the same head are not addressed; the missing
+ * bits are written in by the second head when it passes (16 columns later.)
+ * In my code, I call the state of addressing one head or the other "direction".
+ * Originally I thought that the printhead was writing on both leftward and
+ * rightward motion, and that which head was addressed by odd columns changed
+ * accordingly. I'm no longer sure this is true, but the head addressed by the
+ * even columns does alternate with each swipe.
+ */
+/*
+ * various output shorthands
+ */
+
+#define init1() \
+ top(), \
+ 0xA5,0, 3, 0x40,4,5, \
+ 0xA5,0, 3, 0x40,4,6, \
+ 0xA5,0, 3, 0x40,4,7, \
+ 0xA5,0, 3, 0x40,4,8, \
+ 0xA5,0, 4, 0x40,0xe0,0x0b, 3
+
+#define init2() \
+ 0xA5,0, 11, 0x40,0xe0,0x41, 0,0,0,0,0,0,0, 2, \
+ 0xA5,0, 6, 0x40, 5, 0,0,0x80,0 \
+
+#define init3() \
+ 0x1b,'*', 7,0x73,0x30, \
+ 0x1b,'*', 'm', 0, 0x14, 3, 0x84, 2, 0, 1, 0xf4, \
+ 0x1b,'*', 7,0x63, \
+ 0x1b,'*', 'm', 0, 0x42, 0, 0, \
+ 0xA5,0, 5, 0x40,0xe0,0x80, 8, 7, \
+ 0x1b,'*', 'm', 0, 0x40, 0x15, 7, 0x0f, 0x0f \
+
+#define top() \
+ 0xA5,0, 6, 0x40, 3,3,0xc0,0x0f,0x0f \
+
+#define fin() \
+ 0x1b,'*', 7, 0x65 \
+
+
+#define outByte(b) putc(b, prn_stream)
+
+#define RIGHTWARD 0
+#define LEFTWARD 1
+/* number of pixels between even columns in output and odd ones*/
+/* #define headSeparation 16 */
+/* overlap between successive swipes of the print head */
+#define overLap 104
+/* height of printhead in pixels */
+#define swipeHeight 208
+/* number of shorts described by each column directory */
+#define directorySize 13
+
+/* ------ Driver procedures ------ */
+
+
+/* Send the page to the printer. */
+private int
+lxm5700m_print_page(gx_device_printer *pdev, FILE *prn_stream)
+{
+ int lnum,minX, maxX, i, l, highestX, leastX, extent;
+ int direction = RIGHTWARD;
+ int lastY = 0;
+
+ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
+ /* Note that in_size is a multiple of 8. */
+ int in_size = line_size * (swipeHeight);
+ int swipeBuf_size = in_size;
+ byte *buf1 = (byte *)gs_malloc(in_size, 1, "lxm_print_page(buf1)");
+ byte *swipeBuf =
+ (byte *)gs_malloc(swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
+ byte *in = buf1;
+
+ /* Check allocations */
+ if ( buf1 == 0 || swipeBuf == 0 ) {
+ if ( buf1 )
+quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
+ gs_free((char *)buf1, in_size, 1, "lxm_print_page(buf1)");
+ if ( swipeBuf )
+ gs_free((char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
+ return_error(gs_error_VMerror);
+ }
+
+ { /* Initialize the printer and reset the margins. */
+ static const char init_string[] = {
+ init1(),
+ init2(),
+ init3()
+ };
+ fwrite(init_string, 1, sizeof(init_string), prn_stream);
+ }
+ /* Print lines of graphics */
+ for (lnum=0; lnum < pdev->height-swipeHeight ; ) { /* increment in body */
+ byte *in_data;
+ register byte *outp;
+ int lcnt;
+
+ { /* test for blank scan lines. We maintain the */
+ /* loop invariant lnum <pdev->height, but modify lnum */
+ int l;
+
+ for (l=lnum; l<pdev->height; l++) {
+ /* Copy 1 scan line and test for all zero. */
+ gdev_prn_get_bits(pdev, l, in, &in_data);
+ if ( in_data[0] != 0 ||
+ memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
+ ) {
+ break;
+ }
+ }/* end for l */
+
+ /* now l is the next non-blank scan line */
+ if (l >= pdev->height) {/* if there are no more bits on this page */
+ lnum = l;
+ break; /* end the loop and eject the page*/
+ }
+
+ /* leave room for following swipe to reinforce these bits */
+ if (l-lnum > overLap) lnum = l - overLap;
+
+ /* if the first non-blank near bottom of page */
+ if (lnum >=pdev->height - swipeHeight) {
+ /* don't move the printhead over empty air*/
+ lnum = pdev->height - swipeHeight;
+ }
+ }
+
+
+ /* Copy the the scan lines. */
+ lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if ( lcnt < swipeHeight ) {
+ /* Pad with lines of zeros. */
+ memset(in + lcnt * line_size, 0,
+ in_size - lcnt * line_size);
+ }
+
+ /* compute right and left margin for this swipe */
+ minX = line_size;
+ maxX = 0;
+ for (l=0; l<swipeHeight; l++) {/* for each line of swipe */
+ for (i=0; i<minX; i++) {/* look for left-most non-zero byte*/
+ if (in[l*line_size+i] !=0) {
+ minX = i;
+ break;
+ }
+ }
+ for (i=line_size-1; i>=maxX; i--) {/* look for right-most */
+ if (in[l*line_size+i] !=0) {
+ maxX = i;
+ break;
+ }
+ }
+ }
+ minX = (minX&(-2)); /* truncate to even */
+ maxX = (maxX+3)&-2; /* raise to even */
+
+ highestX = maxX*8-1;
+ leastX = minX*8;
+ extent = highestX -leastX +1;
+
+ outp = swipeBuf;
+
+ /* macro, not fcn call. Space penalty is modest, speed helps */
+#define buffer_store(x) if(outp-swipeBuf>=swipeBuf_size) {\
+ gs_free((char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");\
+ swipeBuf_size*=2;\
+ swipeBuf = (byte *)gs_malloc(swipeBuf_size, 1, "lxm_print_page(swipeBuf)");\
+ if (swipeBuf == 0) goto quit_ignomiously;\
+ break;}\
+ else *outp++ = (x)
+
+ {/* work out the bytes to store for this swipe*/
+
+ int sx, sxBy8, sxMask;
+ int words[directorySize];
+ bool f, sum;
+ int retval=0;
+ int j,c,y;
+ int j1,c1;
+ int i,b,x, directory ;
+
+ /* want to set up pointers for (upto two) stripes covered by the output*/
+
+ /* now for each column covered by output: */
+ for (x=leastX; x<=highestX; x++) {
+ for (i=0; i<directorySize; i++) {
+ words[i] = 0;
+ }
+ directory = 0x2000; /* empty directory != 0 */
+
+ /* prime loops: make comparisons here */
+ switch (direction) {
+ case(RIGHTWARD):
+ sx = (x&1)==1 ? x : x-(((lxm_device*)pdev)->headSeparation);
+ j1 = (x&1); /* even if x even, odd if x odd */
+ break;
+ default: /* shouldn't happen ... but compilation checks */
+ case(LEFTWARD):
+ sx = (x&1)==0 ? x : x-((lxm_device*)pdev)->headSeparation;
+ j1 = 1-(x&1); /* odd if x even, even if x odd */
+ }
+ c1 = 0x8000 >> j1;
+
+ sxBy8 = sx/8;
+ sxMask = 0x80>>(sx%8);
+
+ /* loop through all the swipeHeight bits of this column */
+ for (i = 0, b=1, y= sxBy8+j1*line_size; i < directorySize; i++,b<<=1) {
+ sum = false;
+ for (j=j1,c=c1 /*,y=i*16*line_size+sxBy8*/; j<16; j+=2, y+=2*line_size, c>>=2) {
+ f = (in[y]&sxMask);
+ if (f) {
+ words[i] |= c;
+ sum |= f;
+ }
+ }
+ if (!sum) directory |=b;
+ }
+ retval+=2;
+ buffer_store(directory>>8); buffer_store(directory&0xff);
+ if (directory != 0x3fff) {
+ for (i=0; i<directorySize; i++) {
+ if (words[i] !=0) {
+ buffer_store(words[i]>>8) ; buffer_store(words[i]&0xff);
+ retval += 2;
+ }
+ }
+ }
+ }
+#undef buffer_store
+ }
+ {/* now write out header, then buffered bits */
+ int leastY = lnum;
+
+ /* compute size of swipe, needed for header */
+ int sz = 0x1a + outp - swipeBuf;
+
+ /* put out header*/
+ int deltaY = 2*(leastY - lastY); /* vert coordinates here are 1200 dpi */
+ lastY = leastY;
+ outByte(0x1b); outByte('*'); outByte(3);
+ outByte(deltaY>>8); outByte(deltaY&0xff);
+ outByte(0x1b); outByte('*'); outByte(4); outByte(0); outByte(0);
+ outByte(sz>>8); outByte(sz&0xff); outByte(0); outByte(3);
+ outByte(1); outByte(1); outByte(0x1a);
+ outByte(0);
+ outByte(extent>>8); outByte(extent&0xff);
+ outByte(leastX>>8); outByte(leastX&0xff);
+ outByte(highestX>>8); outByte(highestX&0xff);
+ outByte(0); outByte(0);
+ outByte(0x22); outByte(0x33); outByte(0x44);
+ outByte(0x55); outByte(1);
+ /* put out bytes */
+ fwrite(swipeBuf,1,outp-swipeBuf,prn_stream);
+ }
+ lnum += overLap;
+ direction ^= 1;
+ }/* ends the loop for swipes of the print head.*/
+
+ /* Eject the page and reinitialize the printer */
+ {
+ static const char bottom[] = {
+ fin() /*, looks like I can get away with only this much ...
+ init1(),
+ init3(),
+ fin() ,
+ top(),
+ fin() */
+ };
+ fwrite(bottom, 1, sizeof(bottom), prn_stream);
+ }
+ fflush(prn_stream);
+
+ gs_free((char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
+ gs_free((char *)buf1, in_size, 1, "lxm_print_page(buf1)");
+ return 0;
+}
+
+/*
+ * There are a number of parameters which can differ between ink cartridges.
+ * The Windows driver asks you to recalibrate every time you load a new
+ * cartridge.
+ * most of the parameters adjusted there relate to color, and so this
+ * monotone driver doesn't need them. However, the Lexmark 5700 black
+ * cartridge has two columns of dots, separated by about 16 pixels.
+ * This `head separation' distance can vary between cartridges, so
+ * we provide a parameter to set it. In my small experience I've not
+ * set the corresponding parameter in windows to anything greater than 17
+ * or smaller than 15, but it would seem that it can vary from 1 to 32,
+ * based on the calibration choices offered.
+ *
+ * As I understand the rules laid out in gsparams.h,
+ * lxm_get_params is supposed to return the current values of parameters
+ * and lxm_put_params is supposed to set up values in the lxm_device
+ * structure which can be used by the lxm5700m_print_page routine.
+ * I've copied my routines from gdevcdj.c
+ */
+
+private int
+lxm_get_params(gx_device *pdev, gs_param_list *plist)
+{
+ lxm_device* const ldev = (lxm_device*)pdev;
+ int code = gdev_prn_get_params(pdev, plist);
+
+ if ( code < 0 ) return code;
+ code = param_write_int(plist,
+ "HeadSeparation",
+ (int *)&(ldev->headSeparation));
+
+ return code;
+}
+
+/* put_params is supposed to check all the parameters before setting any. */
+private int
+lxm_put_params(gx_device *pdev, gs_param_list *plist)
+{
+ int ecode;
+ lxm_device* const ldev = (lxm_device*)pdev;
+ int trialHeadSeparation=ldev->headSeparation;
+ int code = param_read_int(plist, "HeadSeparation", &trialHeadSeparation);
+
+ if ( trialHeadSeparation < 1 || trialHeadSeparation > 32 )
+ param_signal_error(plist, "HeadSeparation", gs_error_rangecheck);
+ /* looks like param_signal_error is not expected to return */
+ ecode = gdev_prn_put_params(pdev, plist); /* call super class put_params */
+ if ( code < 0 ) return code;
+ if (ecode < 0) return ecode;
+
+ /* looks like everything okay; go ahead and set headSeparation */
+ ldev->headSeparation = trialHeadSeparation;
+ if ( code == 1) return ecode; /* I guess this means there is no "HeadSeparation" parameter */
+ return 0;
+}
diff --git a/gs/src/gdevm1.c b/gs/src/gdevm1.c
index eb7b6621d..06c53d9a7 100644
--- a/gs/src/gdevm1.c
+++ b/gs/src/gdevm1.c
@@ -132,6 +132,7 @@ mem_mono_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
(CFETCH_ALIGNED(cptr) >> shift)
# define CFETCH_LEFT(cptr, shift, cshift)\
(CFETCH_ALIGNED(cptr) << shift)
+# define CFETCH_USES_CSKEW 0
/* Fetch a chunk that straddles a chunk boundary. */
# define CFETCH2(cptr, cskew, skew)\
(CFETCH_LEFT(cptr, cskew, skew) +\
@@ -158,6 +159,7 @@ private const bits16 left_masks2[9] =
((CCONT(cptr, 0) << (shift)) & left_masks2[shift]) +\
(CCONT(cptr, 0) >> (cshift)) :\
((CCONT(cptr, 0) & 0xff00) >> (cshift)) & 0xff)
+# define CFETCH_USES_CSKEW 1
/* 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. */
@@ -175,7 +177,7 @@ typedef enum {
COPY_OR = 0, COPY_STORE, COPY_AND, COPY_FUNNY
} copy_function;
typedef struct {
- uint invert;
+ int invert;
copy_function op;
} copy_mode;
@@ -183,8 +185,7 @@ typedef struct {
* Map from <color0,color1> to copy_mode.
* Logically, this is a 2-D array.
* The indexing is (transparent, 0, 1, unused). */
-private const copy_mode copy_modes[16] =
-{
+private const copy_mode copy_modes[16] = {
{~0, COPY_FUNNY}, /* NN */
{~0, COPY_AND}, /* N0 */
{0, COPY_OR}, /* N1 */
@@ -242,7 +243,7 @@ mem_mono_copy_mono(gx_device * dev,
color1 = -1;
#endif
mode = copy_modes[((int)color0 << 2) + (int)color1 + 5];
- invert = mode.invert; /* load register */
+ invert = (uint)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;
@@ -292,12 +293,16 @@ mem_mono_copy_mono(gx_device * dev,
if (skew == 0) { /* no shift */
WRITE1_LOOP(CFETCH_ALIGNED(bptr));
} else { /* right shift */
+#if CFETCH_USES_CSKEW
int cskew = chunk_bits - skew;
+#endif
WRITE1_LOOP(CFETCH_RIGHT(bptr, skew, cskew));
}
} else if (wleft <= skew) { /* single -> single, left shift */
+#if CFETCH_USES_CSKEW
int cskew = chunk_bits + skew;
+#endif
skew = -skew;
WRITE1_LOOP(CFETCH_LEFT(bptr, skew, cskew));
@@ -551,12 +556,16 @@ int tx, int y, int tw, int th, gx_color_index color0, gx_color_index color1,
if (skew == 0) { /* no shift */
WRITE1_LOOP(CFETCH_ALIGNED(bptr));
} else { /* right shift */
+#if CFETCH_USES_CSKEW
int cskew = chunk_bits - skew;
+#endif
WRITE1_LOOP(CFETCH_RIGHT(bptr, skew, cskew));
}
} else if (wleft <= skew) { /* single -> single, left shift */
+#if CFETCH_USES_CSKEW
int cskew = chunk_bits + skew;
+#endif
skew = -skew;
WRITE1_LOOP(CFETCH_LEFT(bptr, skew, cskew));
diff --git a/gs/src/gdevm2.c b/gs/src/gdevm2.c
index 8146c4048..08fbe793f 100644
--- a/gs/src/gdevm2.c
+++ b/gs/src/gdevm2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -39,16 +39,16 @@ declare_mem_procs(mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fil
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);
+ 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)
+static const mono_fill_chunk tile_patterns[4] = {
+ fpat(0x00), fpat(0x55), fpat(0xaa), fpat(0xff)
};
/* Fill a rectangle with a color. */
@@ -67,19 +67,17 @@ mem_mapped2_fill_rectangle(gx_device * dev,
/* 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)
+ 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};
+ 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);
@@ -90,7 +88,7 @@ mem_mapped2_copy_mono(gx_device * dev,
first_mask = bmask[x & 3];
left_mask = lmask[x & 3];
right_mask = ~lmask[(x + w) & 3];
- if ((x & 3) + w <= 4)
+ if ((x & 3) + w <= 3)
left_mask = right_mask = left_mask | right_mask;
b0 = btab[zero & 3];
b1 = btab[one & 3];
@@ -106,44 +104,46 @@ mem_mapped2_copy_mono(gx_device * dev,
/* 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);
+ byte data = (*pptr & left_mask) | (b0 & ~left_mask);
- do {
+ for ( ; ; ) {
if (sbyte & bit)
data ^= bxor & mask;
+ if (--count <= 0)
+ break;
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 {
+ for ( ; ; ) {
if (sbyte & bit)
*pptr = (*pptr & ~mask) + (b1 & mask);
+ if (--count <= 0)
+ break;
if ((bit >>= 1) == 0)
bit = 0x80, sbyte = *sptr++;
if ((mask >>= 2) == 0)
mask = 0xc0, pptr++;
}
- while (--count > 0);
}
} else { /* Some other case. */
- do {
+ for ( ; ; ) {
if (!(sbyte & bit)) {
if (zero != gx_no_color_index)
*pptr = (*pptr & ~mask) + (b0 & mask);
}
+ if (--count <= 0)
+ break;
if ((bit >>= 1) == 0)
bit = 0x80, sbyte = *sptr++;
if ((mask >>= 2) == 0)
mask = 0xc0, pptr++;
}
- while (--count > 0);
}
line += sraster;
inc_ptr(dest, draster);
@@ -154,8 +154,8 @@ mem_mapped2_copy_mono(gx_device * dev,
/* 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)
+ const byte * base, int sourcex, int sraster,
+ gx_bitmap_id id, int x, int y, int w, int h)
{
int code;
@@ -185,9 +185,10 @@ declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rect
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);
+ 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
@@ -211,8 +212,9 @@ mem2_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
/* 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)
+ 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;
@@ -233,8 +235,8 @@ mem2_word_copy_mono(gx_device * dev,
/* 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)
+ const byte * base, int sourcex, int sraster,
+ gx_bitmap_id id, int x, int y, int w, int h)
{
int code;
diff --git a/gs/src/gdevm24.c b/gs/src/gdevm24.c
index 8f182205c..f1b0f9bfd 100644
--- a/gs/src/gdevm24.c
+++ b/gs/src/gdevm24.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,9 +25,35 @@
#include "gdevmem.h" /* private definitions */
extern dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop);
-
#define mem_true24_strip_copy_rop mem_gray8_rgb24_strip_copy_rop
+/*
+ * Define whether to use the library's memset.
+ */
+/*#define USE_MEMSET*/
+/*
+ * Define whether to use memcpy for very wide fills. We thought this
+ * made a big difference, but it turned out to be an artifact of the
+ * profiler.
+ */
+/*#define USE_MEMCPY*/
+
+/* Define debugging statistics. */
+#ifdef DEBUG
+struct stats_mem24_s {
+ long
+ fill, fwide, fgray[101], fsetc, fcolor[101], fnarrow[5],
+ fprevc[257];
+ double ftotal;
+} stats_mem24;
+static int prev_count;
+static uint prev_colors[256];
+# define INCR(v) (++(stats_mem24.v))
+#else
+# define INCR(v) DO_NOTHING
+#endif
+
+
/* ================ Standard (byte-oriented) device ================ */
#undef chunk
@@ -94,16 +120,22 @@ mem_true24_fill_rectangle(gx_device * dev,
* fit_fill.
*/
fit_fill_xywh(dev, x, y, w, h);
+ INCR(fill);
+#ifdef DEBUG
+ stats_mem24.ftotal += w;
+#endif
if (w >= 5) {
if (h <= 0)
return 0;
+ INCR(fwide);
setup_rect(dest);
if (r == g && r == b) {
-#if 1
+#ifndef USE_MEMSET
/* We think we can do better than the library's memset.... */
int bcntm7 = w * 3 - 7;
register bits32 cword = color | (color << 24);
+ INCR(fgray[min(w, 100)]);
while (h-- > 0) {
register byte *pptr = dest;
byte *limit = pptr + bcntm7;
@@ -153,6 +185,7 @@ mem_true24_fill_rectangle(gx_device * dev,
#else
int bcnt = w * 3;
+ INCR(fgray[min(w, 100)]);
while (h-- > 0) {
memset(dest, r, bcnt);
inc_ptr(dest, draster);
@@ -162,12 +195,35 @@ mem_true24_fill_rectangle(gx_device * dev,
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
+ if (mdev->color24.rgb == color) {
+ rgbr = mdev->color24.rgbr;
+ gbrg = mdev->color24.gbrg;
+ brgb = mdev->color24.brgb;
+ } else {
+ INCR(fsetc);
set_color24_cache(color, r, g, b);
+ }
+#ifdef DEBUG
+ {
+ int ci;
+ for (ci = 0; ci < prev_count; ++ci)
+ if (prev_colors[ci] == color)
+ break;
+ INCR(fprevc[ci]);
+ if (ci == prev_count) {
+ if (ci < countof(prev_colors))
+ ++prev_count;
+ else
+ --ci;
+ }
+ if (ci) {
+ memmove(&prev_colors[1], &prev_colors[0],
+ ci * sizeof(prev_colors[0]));
+ prev_colors[0] = color;
+ }
+ }
+#endif
+ INCR(fcolor[min(w, 100)]);
while (h-- > 0) {
register byte *pptr = dest;
int w1 = ww;
@@ -192,6 +248,31 @@ mem_true24_fill_rectangle(gx_device * dev,
case 0:
;
}
+#ifdef USE_MEMCPY
+ /*
+ * For very wide fills, it's most efficient to fill a few
+ * pixels and then use memcpy to fill the rest.
+ */
+ if (w1 > 16) {
+#define PUTW4(ptr, w)\
+ BEGIN\
+ putw(ptr, w); putw((ptr)+12, w); putw((ptr)+24, w); putw((ptr)+36, w);\
+ END
+ PUTW4(pptr, rgbr);
+ PUTW4(pptr + 4, gbrg);
+ PUTW4(pptr + 8, brgb);
+#undef PUTW4
+ if (w1 > 64) {
+ memcpy(pptr + 48, pptr, 48);
+ memcpy(pptr + 96, pptr, 96);
+ for (pptr += 192; (w1 -= 64) >= 64; pptr += 192)
+ memcpy(pptr, pptr - 192, 192);
+ } else
+ pptr += 48;
+ for (; (w1 -= 16) >= 16; pptr += 48)
+ memcpy(pptr, pptr - 48, 48);
+ }
+#endif
while (w1 >= 4) {
putw(pptr, rgbr);
putw(pptr + 4, gbrg);
@@ -220,6 +301,7 @@ mem_true24_fill_rectangle(gx_device * dev,
}
}
} else if (h > 0) { /* w < 5 */
+ INCR(fnarrow[max(w, 0)]);
setup_rect(dest);
switch (w) {
case 4:
diff --git a/gs/src/gdevm32.c b/gs/src/gdevm32.c
index 325c4493f..8d4e29760 100644
--- a/gs/src/gdevm32.c
+++ b/gs/src/gdevm32.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -137,35 +137,88 @@ mem_true32_copy_mono(gx_device * 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;
+ if (zero == gx_no_color_index) {
+ int first_bit = sourcex & 7;
+ int w_first = min(w, 8 - first_bit);
+ int w_rest = w - w_first;
- do {
- if (sbyte & bit) {
- if (one != gx_no_color_index)
- *pptr = a_one;
- } else {
- if (zero != gx_no_color_index)
+ if (one == gx_no_color_index)
+ return 0;
+ /*
+ * There are no halftones, so this case -- characters --
+ * is the only common one.
+ */
+ while (h-- > 0) {
+ bits32 *pptr = (bits32 *) dest;
+ const byte *sptr = line;
+ int sbyte = (*sptr++ << first_bit) & 0xff;
+ int count = w_first;
+
+ if (sbyte)
+ do {
+ if (sbyte & 0x80)
+ *pptr = a_one;
+ sbyte <<= 1;
+ pptr++;
+ }
+ while (--count > 0);
+ else
+ pptr += count;
+ for (count = w_rest; count >= 8; count -= 8, pptr += 8) {
+ sbyte = *sptr++;
+ if (sbyte) {
+ if (sbyte & 0x80) pptr[0] = a_one;
+ if (sbyte & 0x40) pptr[1] = a_one;
+ if (sbyte & 0x20) pptr[2] = a_one;
+ if (sbyte & 0x10) pptr[3] = a_one;
+ if (sbyte & 0x08) pptr[4] = a_one;
+ if (sbyte & 0x04) pptr[5] = a_one;
+ if (sbyte & 0x02) pptr[6] = a_one;
+ if (sbyte & 0x01) pptr[7] = a_one;
+ }
+ }
+ if (count) {
+ sbyte = *sptr;
+ do {
+ if (sbyte & 0x80)
+ *pptr = a_one;
+ sbyte <<= 1;
+ pptr++;
+ }
+ while (--count > 0);
+ }
+ line += sraster;
+ inc_ptr(dest, draster);
+ }
+ } else { /* zero != gx_no_color_index */
+ int first_bit = 0x80 >> (sourcex & 7);
+
+ while (h-- > 0) {
+ bits32 *pptr = (bits32 *) dest;
+ const byte *sptr = line;
+ int sbyte = *sptr++;
+ int bit = first_bit;
+ int count = w;
+
+ do {
+ if (sbyte & bit) {
+ if (one != gx_no_color_index)
+ *pptr = a_one;
+ } else
*pptr = a_zero;
+ if ((bit >>= 1) == 0)
+ bit = 0x80, sbyte = *sptr++;
+ pptr++;
}
- if ((bit >>= 1) == 0)
- bit = 0x80, sbyte = *sptr++;
- pptr++;
+ while (--count > 0);
+ line += sraster;
+ inc_ptr(dest, draster);
}
- while (--count > 0);
- line += sraster;
- inc_ptr(dest, draster);
}
return 0;
}
diff --git a/gs/src/gdevmeds.c b/gs/src/gdevmeds.c
new file mode 100644
index 000000000..5ab9b0d2f
--- /dev/null
+++ b/gs/src/gdevmeds.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/*
+ * Select from a NULL terminated list of media the smallest medium which is
+ * allmost equal or larger then the actual imagesize.
+ *
+ * Written by Ulrich Schmid, uschmid@mail.hh.provi.de.
+ */
+
+#include "gdevmeds.h"
+
+#define CM * 0.01
+#define INCH * 0.0254
+#define TOLERANCE 0.1 CM
+
+private const struct {
+ const char* name;
+ float width;
+ float height;
+ float priority;
+} media[] = {
+#define X(name, width, height) {name, width, height, 1 / (width * height)}
+ X("a0", 83.9611 CM, 118.816 CM),
+ X("a1", 59.4078 CM, 83.9611 CM),
+ X("a2", 41.9806 CM, 59.4078 CM),
+ X("a3", 29.7039 CM, 41.9806 CM),
+ X("a4", 20.9903 CM, 29.7039 CM),
+ X("a5", 14.8519 CM, 20.9903 CM),
+ X("a6", 10.4775 CM, 14.8519 CM),
+ X("a7", 7.40833 CM, 10.4775 CM),
+ X("a8", 5.22111 CM, 7.40833 CM),
+ X("a9", 3.70417 CM, 5.22111 CM),
+ X("a10", 2.61056 CM, 3.70417 CM),
+ X("archA", 9 INCH, 12 INCH),
+ X("archB", 12 INCH, 18 INCH),
+ X("archC", 18 INCH, 24 INCH),
+ X("archD", 24 INCH, 36 INCH),
+ X("archE", 36 INCH, 48 INCH),
+ X("b0", 100.048 CM, 141.393 CM),
+ X("b1", 70.6967 CM, 100.048 CM),
+ X("b2", 50.0239 CM, 70.6967 CM),
+ X("b3", 35.3483 CM, 50.0239 CM),
+ X("b4", 25.0119 CM, 35.3483 CM),
+ X("b5", 17.6742 CM, 25.0119 CM),
+ X("flsa", 8.5 INCH, 13 INCH),
+ X("flse", 8.5 INCH, 13 INCH),
+ X("halfletter", 5.5 INCH, 8.5 INCH),
+ X("ledger", 17 INCH, 11 INCH),
+ X("legal", 8.5 INCH, 14 INCH),
+ X("letter", 8.5 INCH, 11 INCH),
+ X("note", 7.5 INCH, 10 INCH),
+ X("executive", 7.25 INCH, 10.5 INCH),
+ X("com10", 4.125 INCH, 9.5 INCH),
+ X("dl", 11 CM, 22 CM),
+ X("c5", 16.2 CM, 22.9 CM),
+ X("monarch", 3.875 INCH, 7.5 INCH)};
+
+int select_medium(gx_device_printer *pdev, const char **available, int default_index)
+{
+ int i, j, index = default_index;
+ float priority = 0;
+ float width = pdev->width / pdev->x_pixels_per_inch INCH;
+ float height = pdev->height / pdev->y_pixels_per_inch INCH;
+
+ for (i = 0; available[i]; i++) {
+ for (j = 0; j < sizeof(media) / sizeof(media[0]); j++) {
+ if (!strcmp(available[i], media[j].name) &&
+ media[j].width + TOLERANCE > width &&
+ media[j].height + TOLERANCE > height &&
+ media[j].priority > priority) {
+ index = i;
+ priority = media[j].priority;
+ }
+ }
+ }
+ return index;
+}
diff --git a/gs/src/gdevmeds.h b/gs/src/gdevmeds.h
new file mode 100644
index 000000000..0f6e34389
--- /dev/null
+++ b/gs/src/gdevmeds.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/* Interface for gdevmeds.c */
+
+#ifndef gdevmeds_INCLUDED
+# define gdevmeds_INCLUDED
+
+#include "gdevprn.h"
+
+int select_medium(P3(gx_device_printer *pdev, const char **available,
+ int default_index));
+
+#endif /* gdevmeds_INCLUDED */
diff --git a/gs/src/gdevmem.c b/gs/src/gdevmem.c
index a9d5b7f2e..ccb8b4836 100644
--- a/gs/src/gdevmem.c
+++ b/gs/src/gdevmem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,17 +33,17 @@
public_st_device_memory();
/* GC procedures */
-#define mptr ((gx_device_memory *)vptr)
private
-ENUM_PTRS_BEGIN(device_memory_enum_ptrs)
+ENUM_PTRS_WITH(device_memory_enum_ptrs, gx_device_memory *mptr)
{
- return ENUM_USING(st_device_forward, vptr, sizeof(gx_device_forward), index - 2);
+ return ENUM_USING(st_device_forward, vptr, sizeof(gx_device_forward), index - 3);
}
-case 0:
-ENUM_RETURN((mptr->foreign_bits ? NULL : (void *)mptr->base));
-ENUM_STRING_PTR(1, gx_device_memory, palette);
+case 0: ENUM_RETURN((mptr->foreign_bits ? NULL : (void *)mptr->base));
+case 1: ENUM_RETURN((mptr->foreign_line_pointers ? NULL : (void *)mptr->line_ptrs));
+ENUM_STRING_PTR(2, gx_device_memory, palette);
ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(device_memory_reloc_ptrs)
+private
+RELOC_PTRS_WITH(device_memory_reloc_ptrs, gx_device_memory *mptr)
{
if (!mptr->foreign_bits) {
byte *base_old = mptr->base;
@@ -56,69 +56,78 @@ private RELOC_PTRS_BEGIN(device_memory_reloc_ptrs)
mptr->line_ptrs[y] -= reloc;
/* Relocate line_ptrs, which also points into the data area. */
mptr->line_ptrs = (byte **) ((byte *) mptr->line_ptrs - reloc);
+ } else if (!mptr->foreign_line_pointers) {
+ RELOC_PTR(gx_device_memory, line_ptrs);
}
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};
+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). */
+private const gx_device_memory *const mem_devices[33] = {
+ 0, &mem_mono_device, &mem_mapped2_device, 0, &mem_mapped4_device,
+ 0, 0, 0, &mem_mapped8_device,
+ 0, 0, 0, 0, 0, 0, 0, &mem_true16_device,
+ 0, 0, 0, 0, 0, 0, 0, &mem_true24_device,
+ 0, 0, 0, 0, 0, 0, 0, &mem_true32_device
+};
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;
- }
+ return ((uint)bits_per_pixel > 32 ? (const gx_device_memory *)0 :
+ mem_devices[bits_per_pixel]);
}
/* Do the same for a word-oriented device. */
+private const gx_device_memory *const mem_word_devices[33] = {
+ 0, &mem_mono_device, &mem_mapped2_word_device, 0, &mem_mapped4_word_device,
+ 0, 0, 0, &mem_mapped8_word_device,
+ 0, 0, 0, 0, 0, 0, 0, 0 /*no 16-bit word device*/,
+ 0, 0, 0, 0, 0, 0, 0, &mem_true24_word_device,
+ 0, 0, 0, 0, 0, 0, 0, &mem_true32_word_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;
- }
+ return ((uint)bits_per_pixel > 32 ? (const gx_device_memory *)0 :
+ mem_word_devices[bits_per_pixel]);
+}
+
+/* Test whether a device is a memory device */
+bool
+gs_device_is_memory(const gx_device * dev)
+{
+ /*
+ * We use the draw_thin_line procedure to mark memory devices.
+ * See gdevmem.h.
+ */
+ int bits_per_pixel = dev->color_info.depth;
+ const gx_device_memory *mdproto;
+
+ if ((uint)bits_per_pixel > 32)
+ return false;
+ mdproto = mem_devices[bits_per_pixel];
+ if (mdproto != 0 && dev_proc(dev, draw_thin_line) == dev_proc(mdproto, draw_thin_line))
+ return true;
+ mdproto = mem_word_devices[bits_per_pixel];
+ return (mdproto != 0 && dev_proc(dev, draw_thin_line) == dev_proc(mdproto, draw_thin_line));
}
/* Make a memory device. */
@@ -138,7 +147,6 @@ gs_make_mem_device(gx_device_memory * dev, const gx_device_memory * mdproto,
set_dev_proc(dev, get_page_device, gx_page_device_get_page_device);
break;
}
- dev->target = target;
/* Preload the black and white cache. */
if (target == 0) {
if (dev->color_info.depth == 1) {
@@ -150,6 +158,7 @@ gs_make_mem_device(gx_device_memory * dev, const gx_device_memory * mdproto,
dev->cached_colors.white = (1 << dev->color_info.depth) - 1;
}
} else {
+ gx_device_set_target((gx_device_forward *)dev, target);
/* Forward the color mapping operations to the target. */
gx_device_forward_color_procs((gx_device_forward *) dev);
gx_device_copy_color_procs((gx_device *)dev, target);
@@ -168,17 +177,13 @@ 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;
+ gx_device_init((gx_device *)dev, (const gx_device *)&mem_mono_device,
+ mem, true);
set_dev_proc(dev, get_page_device, gx_default_get_page_device);
- mdev->target = target;
+ gx_device_set_target((gx_device_forward *)dev, 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)
@@ -189,24 +194,43 @@ gdev_mem_mono_set_inverted(gx_device_memory * dev, bool black_is_1)
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)
+/*
+ * 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.
+ *
+ * The computation for planar devices is a little messier. Each plane
+ * must pad its scan lines, and then we must pad again for the pointer
+ * tables (one table per plane).
+ */
+ulong
+gdev_mem_bits_size(const gx_device_memory * dev, int width, int height)
+{
+ int num_planes = dev->num_planes;
+ gx_render_plane_t plane1;
+ const gx_render_plane_t *planes;
+ ulong size;
+ int pi;
+
+ if (num_planes)
+ planes = dev->planes;
+ else
+ planes = &plane1, plane1.depth = dev->color_info.depth, num_planes = 1;
+ for (size = 0, pi = 0; pi < num_planes; ++pi)
+ size += bitmap_raster(width * planes[pi].depth);
+ return ROUND_UP(size * height, ARCH_ALIGN_PTR_MOD);
+}
+ulong
+gdev_mem_line_ptrs_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));
+ return (ulong)height * sizeof(byte *) * max(dev->num_planes, 1);
}
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 *);
-
+ return gdev_mem_bits_size(dev, width, height) +
+ gdev_mem_line_ptrs_size(dev, width, height);
}
/*
* Do the inverse computation: given a width (in pixels) and a buffer size,
@@ -216,7 +240,8 @@ 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 *));
+ (bitmap_raster(width * dev->color_info.depth) +
+ sizeof(byte *) * max(dev->num_planes, 1));
int height = (int)min(max_height, max_int);
/*
@@ -230,18 +255,25 @@ gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size)
/* 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);
+ gx_device_memory *const mdev = (gx_device_memory *)dev;
+
+ /* Check that we aren't trying to open a planar device as chunky. */
+ if (mdev->num_planes)
+ return_error(gs_error_rangecheck);
+ return gdev_mem_open_scan_lines(mdev, dev->height);
}
int
gdev_mem_open_scan_lines(gx_device_memory *mdev, int setup_height)
{
+ bool line_pointers_adjacent = true;
+
if (setup_height < 0 || setup_height > mdev->height)
return_error(gs_error_rangecheck);
- if (mdev->bitmap_memory != 0) { /* Allocate the data now. */
+ if (mdev->bitmap_memory != 0) {
+ /* Allocate the data now. */
ulong size = gdev_mem_bitmap_size(mdev);
if ((uint) size != size)
@@ -251,36 +283,69 @@ gdev_mem_open_scan_lines(gx_device_memory *mdev, int setup_height)
if (mdev->base == 0)
return_error(gs_error_VMerror);
mdev->foreign_bits = false;
+ } else if (mdev->line_pointer_memory != 0) {
+ /* Allocate the line pointers now. */
+
+ mdev->line_ptrs = (byte **)
+ gs_alloc_byte_array(mdev->line_pointer_memory, mdev->height,
+ sizeof(byte *) * max(mdev->num_planes, 1),
+ "gdev_mem_open_scan_lines");
+ if (mdev->line_ptrs == 0)
+ return_error(gs_error_VMerror);
+ mdev->foreign_line_pointers = false;
+ line_pointers_adjacent = false;
}
+ if (line_pointers_adjacent)
+ mdev->line_ptrs = (byte **)
+ (mdev->base + gdev_mem_bits_size(mdev, mdev->width, mdev->height));
+ mdev->raster = gdev_mem_raster(mdev);
+ return gdev_mem_set_line_ptrs(mdev, NULL, 0, NULL, setup_height);
+}
/*
- * 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.
+ * Set up the scan line pointers of a memory device.
+ * See gxdevmem.h for the detailed specification.
+ * Sets or uses line_ptrs, base, raster; uses width, color_info.depth,
+ * num_planes, plane_depths, plane_depth.
*/
-#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 */)
+int
+gdev_mem_set_line_ptrs(gx_device_memory * mdev, byte * base, int raster,
+ byte **line_ptrs, int setup_height)
{
- 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);
+ int num_planes = mdev->num_planes;
+ gx_render_plane_t plane1;
+ const gx_render_plane_t *planes;
+ byte **pline =
+ (line_ptrs ? (mdev->line_ptrs = line_ptrs) : mdev->line_ptrs);
+ byte *data =
+ (base ? (mdev->raster = raster, mdev->base = base) :
+ (raster = mdev->raster, mdev->base));
+ int pi;
+
+ if (num_planes) {
+ if (base && !mdev->plane_depth)
+ return_error(gs_error_rangecheck);
+ planes = mdev->planes;
+ } else {
+ planes = &plane1;
+ plane1.depth = mdev->color_info.depth;
+ num_planes = 1;
}
+
+ for (pi = 0; pi < num_planes; ++pi) {
+ int raster = bitmap_raster(mdev->width * planes[pi].depth);
+ byte **pptr = pline;
+ byte **pend = pptr + setup_height;
+ byte *scan_line = data;
+
+ while (pptr < pend) {
+ *pptr++ = scan_line;
+ scan_line += raster;
+ }
+ data += raster * mdev->height;
+ pline += setup_height; /* not mdev->height, see gxdevmem.h */
+ }
+
+ return 0;
}
/* Return the initial transformation matrix */
@@ -297,21 +362,6 @@ mem_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
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)
@@ -325,6 +375,10 @@ mem_close(gx_device * dev)
* client that is sloppy about using is_open properly.
*/
mdev->base = 0;
+ } else if (mdev->line_pointer_memory != 0) {
+ gs_free_object(mdev->line_pointer_memory, mdev->line_ptrs,
+ "mem_close");
+ mdev->line_ptrs = 0; /* ibid. */
}
return 0;
}
@@ -359,16 +413,21 @@ mem_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
)
return_error(gs_error_rangecheck);
{
+ gs_get_bits_params_t copy_params;
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);
-
+ int code;
+
+ copy_params.options =
+ GB_COLORS_NATIVE | GB_PACKING_CHUNKY | GB_ALPHA_NONE |
+ (mdev->raster ==
+ bitmap_raster(mdev->width * mdev->color_info.depth) ?
+ GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
+ copy_params.raster = mdev->raster;
+ code = gx_get_bits_return_pointer(dev, x, h, params,
+ &copy_params, 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,
+ return gx_get_bits_copy(dev, x, w, h, params, &copy_params, base,
gx_device_raster(dev, true));
}
}
@@ -508,3 +567,15 @@ mem_mapped_map_color_rgb(gx_device * dev, gx_color_index color,
prgb[2] = gx_color_value_from_byte(pptr[2]);
return 0;
}
+
+/*
+ * Implement draw_thin_line using a distinguished procedure that serves
+ * as the common marker for all memory devices.
+ */
+int
+mem_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 gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop);
+}
diff --git a/gs/src/gdevmem.h b/gs/src/gdevmem.h
index 2eb72f394..3b349387e 100644
--- a/gs/src/gdevmem.h
+++ b/gs/src/gdevmem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -84,6 +84,12 @@ dev_proc_close_device(mem_close);
private dev_proc_copy_mono(copy_mono);\
private dev_proc_copy_color(copy_color);\
private dev_proc_fill_rectangle(fill_rectangle)
+/*
+ * We define one relatively low-usage drawing procedure that is common to
+ * all memory devices so that we have a reliable way to implement
+ * gs_is_memory_device. It is equivalent to gx_default_draw_thin_line.
+ */
+dev_proc_draw_thin_line(mem_draw_thin_line);
/* The following are used for all except planar or word-oriented devices. */
dev_proc_open_device(mem_open);
@@ -155,7 +161,7 @@ dev_proc_strip_copy_rop(mem_default_strip_copy_rop);
gx_default_fill_trapezoid,\
gx_default_fill_parallelogram,\
gx_default_fill_triangle,\
- gx_default_draw_thin_line,\
+ mem_draw_thin_line, /* see above */\
gx_default_begin_image,\
gx_default_image_data,\
gx_default_end_image,\
diff --git a/gs/src/gdevmgr.c b/gs/src/gdevmgr.c
index e5e3c3a7d..83af43fb3 100644
--- a/gs/src/gdevmgr.c
+++ b/gs/src/gdevmgr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -105,7 +105,7 @@ typedef struct mgr_cursor_s {
/* Begin an MGR output page. */
/* Write the header information and initialize the cursor. */
private int
-mgr_begin_page(gx_device_mgr *bdev, FILE *pstream, mgr_cursor _ss *pcur)
+mgr_begin_page(gx_device_mgr *bdev, FILE *pstream, mgr_cursor *pcur)
{ struct b_header head;
uint line_size =
gdev_prn_raster((gx_device_printer *)bdev) + 3;
@@ -131,7 +131,7 @@ mgr_begin_page(gx_device_mgr *bdev, FILE *pstream, mgr_cursor _ss *pcur)
/* Advance to the next row. Return 0 if more, 1 if done. */
private int
-mgr_next_row(mgr_cursor _ss *pcur)
+mgr_next_row(mgr_cursor *pcur)
{ if ( pcur->lnum >= pcur->dev->height )
{ gs_free((char *)pcur->data, pcur->line_size, 1,
"mgr_next_row(done)");
diff --git a/gs/src/gdevmpla.c b/gs/src/gdevmpla.c
index aa14e08c0..c3869edf7 100644
--- a/gs/src/gdevmpla.c
+++ b/gs/src/gdevmpla.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,178 +17,568 @@
*/
-/* Any-depth planar "memory" (stored bitmap) devices */
+/* Any-depth planar "memory" (stored bitmap) device */
#include "memory_.h"
#include "gx.h"
+#include "gserrors.h"
+#include "gsbitops.h"
#include "gxdevice.h"
#include "gxdevmem.h" /* semi-public definitions */
+#include "gxgetbit.h"
#include "gdevmem.h" /* private definitions */
+#include "gdevmpla.h" /* interface */
+
+/* procedures */
+private dev_proc_open_device(mem_planar_open);
+declare_mem_procs(mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle);
+private dev_proc_strip_tile_rectangle(mem_planar_strip_tile_rectangle);
+private dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle);
/*
- * 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.
+ * Set up a planar memory device, after calling gs_make_mem_device but
+ * before opening the device. The pre-existing device provides the color
+ * mapping procedures, but not the drawing procedures. Requires: num_planes
+ * > 0, plane_depths[0 .. num_planes - 1] > 0, sum of plane depths =
+ * mdev->color_info.depth.
*
- * The current implementations are quite inefficient.
- * We may improve them someday if anyone cares.
+ * Note that this is the only public procedure in this file, and the only
+ * sanctioned way to set up a planar memory device.
*/
+int
+gdev_mem_set_planar(gx_device_memory * mdev, int num_planes,
+ const gx_render_plane_t *planes /*[num_planes]*/)
+{
+ int total_depth;
+ int same_depth = planes[0].depth;
+ gx_color_index covered = 0;
+ int pi;
-/* 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);
+ if (num_planes < 1 || num_planes > GX_DEVICE_COLOR_MAX_COMPONENTS)
+ return_error(gs_error_rangecheck);
+ for (pi = 0, total_depth = 0; pi < num_planes; ++pi) {
+ int shift = planes[pi].shift;
+ int plane_depth = planes[pi].depth;
+ gx_color_index mask;
-/* 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);
+ if (shift < 0 || plane_depth > 16 ||
+ !gdev_mem_device_for_bits(plane_depth))
+ return_error(gs_error_rangecheck);
+ mask = (((gx_color_index)1 << plane_depth) - 1) << shift;
+ if (covered & mask)
+ return_error(gs_error_rangecheck);
+ covered |= mask;
+ if (plane_depth != same_depth)
+ same_depth = 0;
+ total_depth += plane_depth;
+ }
+ if (total_depth > mdev->color_info.depth)
+ return_error(gs_error_rangecheck);
+ mdev->num_planes = num_planes;
+ memcpy(mdev->planes, planes, num_planes * sizeof(planes[0]));
+ mdev->plane_depth = same_depth;
+ /* Change the drawing procedures. */
+ set_dev_proc(mdev, open_device, mem_planar_open);
+ set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle);
+ set_dev_proc(mdev, copy_mono, mem_planar_copy_mono);
+ set_dev_proc(mdev, copy_color, mem_planar_copy_color);
+ set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha);
+ set_dev_proc(mdev, strip_tile_rectangle, mem_planar_strip_tile_rectangle);
+ set_dev_proc(mdev, strip_copy_rop, gx_default_strip_copy_rop);
+ set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle);
+ return 0;
+}
/* 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;
+{
+ gx_device_memory *const mdev = (gx_device_memory *)dev;
- dev->height *= depth;
- dev->color_info.depth = 1;
- code = mem_open(dev);
- dev->height = height;
- dev->color_info.depth = depth;
- return code;
+ /* Check that we aren't trying to open a chunky device as planar. */
+ if (mdev->num_planes == 0)
+ return_error(gs_error_rangecheck);
+ return gdev_mem_open_scan_lines(mdev, dev->height);
}
-/* 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)
+/*
+ * We execute drawing operations by patching a few parameters in the
+ * device structure and then calling the procedure appropriate to the
+ * plane depth.
+ */
+typedef struct mem_save_params_s {
+ int depth; /* color_info.depth */
+ byte *base;
+ byte **line_ptrs;
+} mem_save_params_t;
+#define MEM_SAVE_PARAMS(mdev, msp)\
+ (msp.depth = mdev->color_info.depth,\
+ msp.base = mdev->base,\
+ msp.line_ptrs = mdev->line_ptrs)
+#define MEM_SET_PARAMS(mdev, plane_depth)\
+ (mdev->color_info.depth = plane_depth, /* maybe not needed */\
+ mdev->base = mdev->line_ptrs[0],\
+ mdev->raster = bitmap_raster(mdev->width * plane_depth))
+#define MEM_RESTORE_PARAMS(mdev, msp)\
+ (mdev->color_info.depth = msp.depth,\
+ mdev->base = msp.base,\
+ mdev->line_ptrs = msp.line_ptrs)
+
+/* 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)
{
- int depth = dev->color_info.depth;
+ gx_device_memory * const mdev = (gx_device_memory *)dev;
+ mem_save_params_t save;
+ int pi;
+
+ MEM_SAVE_PARAMS(mdev, save);
+ for (pi = 0; pi < mdev->num_planes; ++pi) {
+ int plane_depth = mdev->planes[pi].depth;
+ gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1;
+ const gx_device_memory *mdproto =
+ gdev_mem_device_for_bits(plane_depth);
- return (*dev_proc(gdev_mem_device_for_bits(depth), map_rgb_color))
- (dev, r, g, b);
+ MEM_SET_PARAMS(mdev, plane_depth);
+ dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h,
+ (color >> mdev->planes[pi].shift) &
+ mask);
+ mdev->line_ptrs += mdev->height;
+ }
+ MEM_RESTORE_PARAMS(mdev, save);
+ return 0;
}
-/* Map a color index to a r-g-b color. */
+/* Copy a bitmap. */
private int
-mem_planar_map_color_rgb(gx_device * dev, gx_color_index color,
- gx_color_value prgb[3])
+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 color0, gx_color_index color1)
{
- int depth = dev->color_info.depth;
+ gx_device_memory * const mdev = (gx_device_memory *)dev;
+ mem_save_params_t save;
+ int pi;
+
+ MEM_SAVE_PARAMS(mdev, save);
+ for (pi = 0; pi < mdev->num_planes; ++pi) {
+ int plane_depth = mdev->planes[pi].depth;
+ int shift = mdev->planes[pi].shift;
+ gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1;
+ const gx_device_memory *mdproto =
+ gdev_mem_device_for_bits(plane_depth);
+ gx_color_index c0 =
+ (color0 == gx_no_color_index ? gx_no_color_index :
+ (color0 >> shift) & mask);
+ gx_color_index c1 =
+ (color1 == gx_no_color_index ? gx_no_color_index :
+ (color1 >> shift) & mask);
- return (*dev_proc(gdev_mem_device_for_bits(depth), map_color_rgb))
- (dev, color, prgb);
+ MEM_SET_PARAMS(mdev, plane_depth);
+ if (c0 == c1)
+ dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, c0);
+ else
+ dev_proc(mdproto, copy_mono)
+ (dev, base, sourcex, sraster, id, x, y, w, h, c0, c1);
+ mdev->line_ptrs += mdev->height;
+ }
+ MEM_RESTORE_PARAMS(mdev, save);
+ return 0;
}
-/* Fill a rectangle with a color. */
+/* Copy a color bitmap. */
+/* This is slow and messy. */
private int
-mem_planar_fill_rectangle(gx_device * dev,
- int x, int y, int w, int h, gx_color_index color)
+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 i;
+#define BUF_LONGS 100 /* arbitrary, >= 1 */
+#define BUF_BYTES (BUF_LONGS * ARCH_SIZEOF_LONG)
+ union b_ {
+ ulong l[BUF_LONGS];
+ byte b[BUF_BYTES];
+ } buf;
+ int source_depth = dev->color_info.depth;
+ mem_save_params_t save;
+ int pi;
- 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;
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ MEM_SAVE_PARAMS(mdev, save);
+ for (pi = 0; pi < mdev->num_planes; ++pi) {
+ int plane_depth = mdev->planes[pi].depth;
+ int shift = mdev->planes[pi].shift;
+ gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1;
+ const gx_device_memory *mdproto =
+ gdev_mem_device_for_bits(plane_depth);
+ /*
+ * Divide up the transfer into chunks that can be assembled
+ * within the fixed-size buffer. This code can be simplified
+ * a lot if all planes have the same depth, by simply using
+ * copy_color to transfer one column at a time, but it might
+ * be very inefficient.
+ */
+ uint plane_raster = bitmap_raster(plane_depth * w);
+ int br, bw, bh, cx, cy, cw, ch, ix, iy;
+
+ MEM_SET_PARAMS(mdev, plane_depth);
+ if (plane_raster > BUF_BYTES) {
+ br = BUF_BYTES;
+ bw = BUF_BYTES * 8 / plane_depth;
+ bh = 1;
+ } else {
+ br = plane_raster;
+ bw = w;
+ bh = BUF_BYTES / plane_raster;
+ }
+ /*
+ * We could do the extraction with get_bits_rectangle
+ * selecting a single plane, but this is critical enough
+ * code that we more or less replicate it here.
+ */
+ for (cy = y; cy < y + h; cy += ch) {
+ ch = min(bh, y + h - cy);
+ for (cx = x; cx < x + w; cx += cw) {
+ int sx = sourcex + cx - x;
+ const byte *source_base = base + sraster * (cy - y);
+ int source_bit = 0;
+
+ cw = min(bw, x + w - cx);
+ if (sx) {
+ int xbit = sx * source_depth;
+
+ source_base += xbit >> 3;
+ source_bit = xbit & 7;
+ }
+ for (iy = 0; iy < ch; ++iy) {
+ sample_load_declare_setup(sptr, sbit, source_base,
+ source_bit, source_depth);
+ sample_store_declare_setup(dptr, dbit, dbbyte,
+ buf.b + br * iy,
+ 0, plane_depth);
+
+ for (ix = 0; ix < cw; ++ix) {
+ gx_color_index value;
+
+ sample_load_next32(value, sptr, sbit, source_depth);
+ value = (value >> shift) & mask;
+ sample_store_next16(value, dptr, dbit, plane_depth,
+ dbbyte);
+ }
+ sample_store_flush(dptr, dbit, plane_depth, dbbyte);
+ source_base += sraster;
+ }
+ /*
+ * Detect and bypass the possibility that copy_color is
+ * defined in terms of copy_mono.
+ */
+ if (plane_depth == 1)
+ dev_proc(mdproto, copy_mono)
+ (dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
+ (gx_color_index)0, (gx_color_index)1);
+ else
+ dev_proc(mdproto, copy_color)
+ (dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch);
+ }
+ }
+ mdev->line_ptrs += mdev->height;
+ }
+ MEM_RESTORE_PARAMS(mdev, save);
return 0;
+#undef BUF_BYTES
+#undef BUF_LONGS
}
-/* 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)
+mem_planar_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_memory * const mdev = (gx_device_memory *)dev;
- byte **ptrs = mdev->line_ptrs;
- int i;
+ mem_save_params_t save;
+ int pi;
- 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;
+ /* We can't split up the transfer if the tile is colored. */
+ if (color0 == gx_no_color_index && color1 == gx_no_color_index)
+ return gx_default_strip_tile_rectangle
+ (dev, tiles, x, y, w, h, color0, color1, px, py);
+ MEM_SAVE_PARAMS(mdev, save);
+ for (pi = 0; pi < mdev->num_planes; ++pi) {
+ int plane_depth = mdev->planes[pi].depth;
+ int shift = mdev->planes[pi].shift;
+ gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1;
+ const gx_device_memory *mdproto =
+ gdev_mem_device_for_bits(plane_depth);
+ gx_color_index c0 =
+ (color0 == gx_no_color_index ? gx_no_color_index :
+ (color0 >> shift) & mask);
+ gx_color_index c1 =
+ (color1 == gx_no_color_index ? gx_no_color_index :
+ (color1 >> shift) & mask);
+
+ MEM_SET_PARAMS(mdev, plane_depth);
+ if (c0 == c1)
+ dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, c0);
+ else {
+ /*
+ * Temporarily replace copy_mono in case strip_tile_rectangle is
+ * defined in terms of it.
+ */
+ set_dev_proc(dev, copy_mono, dev_proc(mdproto, copy_mono));
+ dev_proc(mdproto, strip_tile_rectangle)
+ (dev, tiles, x, y, w, h, c0, c1, px, py);
+ }
+ mdev->line_ptrs += mdev->height;
+ }
+ MEM_RESTORE_PARAMS(mdev, save);
+ set_dev_proc(dev, copy_mono, mem_planar_copy_mono);
return 0;
}
-/* Copy a color bitmap. */
-/* This is very slow and messy. */
+/*
+ * Repack planar into chunky format. This is an internal procedure that
+ * implements the straightforward chunky case of get_bits_rectangle, and
+ * is also used for the general cases.
+ */
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)
+planar_to_chunky(gx_device_memory *mdev, int x, int y, int w, int h,
+ int offset, uint draster, byte *dest)
{
- 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;
+ int num_planes = mdev->num_planes;
+ sample_load_declare(sptr[GX_DEVICE_COLOR_MAX_COMPONENTS],
+ sbit[GX_DEVICE_COLOR_MAX_COMPONENTS]);
+ sample_store_declare(dptr, dbit, dbbyte);
+ int ddepth = mdev->color_info.depth;
+ int direct =
+ (mdev->color_info.depth != num_planes * mdev->plane_depth ? 0 :
+ mdev->planes[0].shift == 0 ? -mdev->plane_depth : mdev->plane_depth);
+ int pi, ix, iy;
- 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;
+ /* Check whether the planes are of equal size and sequential. */
+ /* If direct != 0, we already know they exactly fill the depth. */
+ if (direct < 0) {
+ for (pi = 0; pi < num_planes; ++pi)
+ if (mdev->planes[pi].shift != pi * -direct) {
+ direct = 0; break;
+ }
+ } else if (direct > 0) {
+ for (pi = 0; pi < num_planes; ++pi)
+ if (mdev->planes[num_planes - 1 - pi].shift != pi * direct) {
+ direct = 0; break;
+ }
}
- 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);
+ for (iy = y; iy < y + h; ++iy) {
+ byte **line_ptr = mdev->line_ptrs + iy;
+
+ for (pi = 0; pi < num_planes; ++pi, line_ptr += mdev->height) {
+ int plane_depth = mdev->planes[pi].depth;
+ int xbit = x * plane_depth;
+
+ sptr[pi] = *line_ptr + (xbit >> 3);
+ sample_load_setup(sbit[pi], xbit & 7, plane_depth);
+ }
+ {
+ int xbit = offset * ddepth;
+
+ dptr = dest + (iy - y) * draster + (xbit >> 3);
+ sample_store_setup(dbit, xbit & 7, ddepth);
+ }
+ if (direct == -8) {
+ /* 1 byte per component, lsb first. */
+ switch (num_planes) {
+ case 3: {
+ const byte *p0 = sptr[2];
+ const byte *p1 = sptr[1];
+ const byte *p2 = sptr[0];
+
+ for (ix = w; ix > 0; --ix, dptr += 3) {
+ dptr[0] = *p0++;
+ dptr[1] = *p1++;
+ dptr[2] = *p2++;
+ }
+ }
+ continue;
+ case 4:
+ for (ix = w; ix > 0; --ix, dptr += 4) {
+ dptr[0] = *sptr[3]++;
+ dptr[1] = *sptr[2]++;
+ dptr[2] = *sptr[1]++;
+ dptr[3] = *sptr[0]++;
+ }
+ continue;
+ default:
+ break;
+ }
}
- mdev->line_ptrs = ptrs;
+ sample_store_preload(dbbyte, dptr, dbit, ddepth);
+ for (ix = w; ix > 0; --ix) {
+ gx_color_index color = 0;
+
+ for (pi = 0; pi < num_planes; ++pi) {
+ int plane_depth = mdev->planes[pi].depth;
+ uint value;
+
+ sample_load_next16(value, sptr[pi], sbit[pi], plane_depth);
+ color |= (gx_color_index)value << mdev->planes[pi].shift;
+ }
+ sample_store_next32(color, dptr, dbit, ddepth, dbbyte);
+ }
+ sample_store_flush(dptr, dbit, ddepth, dbbyte);
}
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)
+ gs_get_bits_params_t * params,
+ gs_int_rect ** unread)
{
- return_error(-1);
+ /* This duplicates most of mem_get_bits_rectangle. Tant pis. */
+ 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;
+ int num_planes = mdev->num_planes;
+ gs_get_bits_params_t copy_params;
+ int code;
+
+ if (options == 0) {
+ /*
+ * Unfortunately, as things stand, we have to support
+ * GB_PACKING_CHUNKY. In fact, we can't even claim to support
+ * GB_PACKING_PLANAR, because there is currently no way to
+ * describe the particular planar packing format that the device
+ * actually stores.
+ */
+ 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) |
+ /*
+ (mdev->num_planes == mdev->color_info.depth ?
+ GB_PACKING_CHUNKY | GB_PACKING_PLANAR | GB_PACKING_BIT_PLANAR :
+ GB_PACKING_CHUNKY | GB_PACKING_PLANAR)
+ */
+ 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);
+
+ /*
+ * If the request is for exactly one plane, hand it off to a device
+ * temporarily tweaked to return just that plane.
+ */
+ if (!(~options & (GB_PACKING_PLANAR | GB_SELECT_PLANES))) {
+ /* Check that only a single plane is being requested. */
+ int pi;
+
+ for (pi = 0; pi < num_planes; ++pi)
+ if (params->data[pi] != 0)
+ break;
+ if (pi < num_planes) {
+ int plane = pi++;
+
+ for (; pi < num_planes; ++pi)
+ if (params->data[pi] != 0)
+ break;
+ if (pi == num_planes) {
+ mem_save_params_t save;
+
+ copy_params = *params;
+ copy_params.options =
+ (options & ~(GB_PACKING_ALL | GB_SELECT_PLANES)) |
+ GB_PACKING_CHUNKY;
+ copy_params.data[0] = copy_params.data[plane];
+ MEM_SAVE_PARAMS(mdev, save);
+ mdev->line_ptrs += mdev->height * plane;
+ MEM_SET_PARAMS(mdev, mdev->planes[plane].depth);
+ code = mem_get_bits_rectangle(dev, prect, &copy_params,
+ unread);
+ MEM_RESTORE_PARAMS(mdev, save);
+ if (code >= 0) {
+ params->data[plane] = copy_params.data[0];
+ return code;
+ }
+ }
+ }
+ }
+ /*
+ * We can't return the requested plane by itself. Fall back to
+ * chunky format. This is somewhat painful.
+ *
+ * The code here knows how to produce just one chunky format:
+ * GB_COLORS_NATIVE, GB_ALPHA_NONE, GB_RETURN_COPY.
+ * For any other format, we generate this one in a buffer and
+ * hand it off to gx_get_bits_copy. This is *really* painful.
+ */
+ if (!(~options & (GB_COLORS_NATIVE | GB_ALPHA_NONE |
+ GB_PACKING_CHUNKY | GB_RETURN_COPY))) {
+ int offset = (options & GB_OFFSET_SPECIFIED ? params->x_offset : 0);
+ uint draster =
+ (options & GB_RASTER_SPECIFIED ? params->raster :
+ bitmap_raster((offset + w) * mdev->color_info.depth));
+
+ planar_to_chunky(mdev, x, y, w, h, offset, draster, params->data[0]);
+ } else {
+ /*
+ * Do the transfer through an intermediate buffer.
+ * The buffer must be large enough to hold at least one pixel,
+ * i.e., GX_DEVICE_COLOR_MAX_COMPONENTS 16-bit values.
+ * The algorithms are very similar to those in copy_color.
+ */
+#define BUF_LONGS\
+ max(100, (GX_DEVICE_COLOR_MAX_COMPONENTS * 2 + sizeof(long) - 1) /\
+ sizeof(long))
+#define BUF_BYTES (BUF_LONGS * ARCH_SIZEOF_LONG)
+ union b_ {
+ ulong l[BUF_LONGS];
+ byte b[BUF_BYTES];
+ } buf;
+ int br, bw, bh, cx, cy, cw, ch;
+ int ddepth = mdev->color_info.depth;
+ uint raster = bitmap_raster(ddepth * mdev->width);
+ gs_get_bits_params_t dest_params;
+
+ if (raster > BUF_BYTES) {
+ br = BUF_BYTES;
+ bw = BUF_BYTES * 8 / ddepth;
+ bh = 1;
+ } else {
+ br = raster;
+ bw = w;
+ bh = BUF_BYTES / raster;
+ }
+ copy_params.options =
+ GB_COLORS_NATIVE | GB_PACKING_CHUNKY | GB_ALPHA_NONE |
+ GB_RASTER_STANDARD;
+ copy_params.raster = raster;
+ dest_params = *params;
+ for (cy = y; cy < y + h; cy += ch) {
+ ch = min(bh, y + h - cy);
+ for (cx = x; cx < x + w; cx += cw) {
+ cw = min(bw, x + w - cx);
+ planar_to_chunky(mdev, cx, cy, cw, ch, 0, br, buf.b);
+ dest_params.x_offset = params->x_offset + cx - x;
+ code = gx_get_bits_copy(dev, 0, cw, ch, &dest_params,
+ &copy_params, buf.b, br);
+ if (code < 0)
+ return code;
+ }
+ dest_params.data[0] += ch * raster;
+ }
+#undef BUF_BYTES
+#undef BUF_LONGS
+ }
+ return 0;
}
diff --git a/gs/src/gdevmpla.h b/gs/src/gdevmpla.h
new file mode 100644
index 000000000..031442428
--- /dev/null
+++ b/gs/src/gdevmpla.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface to planar memory devices. */
+
+#ifndef gdevmpla_INCLUDED
+# define gdevmpla_INCLUDED
+
+/*
+ * Planar memory devices store the bits by planes instead of by chunks.
+ * The plane corresponding to the least significant bits of the color index
+ * is stored first. Each plane may store a different number of bits,
+ * but the depth of each plane must be an allowable one for a memory
+ * device and not greater than 16 (currently, 1, 2, 4, 8, or 16), and the
+ * total must not exceed the size of gx_color_index.
+ *
+ * Planar devices store the data for each plane contiguously, as though
+ * each plane were a separate device. There is an array of line pointers
+ * for each plane (num_planes arrays in all).
+ */
+
+/*
+ * Set up a planar memory device, after calling gs_make_mem_device but
+ * before opening the device. The pre-existing device provides the color
+ * mapping procedures, but not the drawing procedures. Requires: num_planes
+ * > 0, plane_depths[0 .. num_planes - 1] > 0, sum of plane_depths <=
+ * mdev->color_info.depth.
+ */
+int gdev_mem_set_planar(P3(gx_device_memory * mdev, int num_planes,
+ const gx_render_plane_t *planes /*[num_planes]*/));
+
+#endif /* gdevmpla_INCLUDED */
diff --git a/gs/src/gdevmr2n.c b/gs/src/gdevmr2n.c
index e5d9e2809..aee1eef40 100644
--- a/gs/src/gdevmr2n.c
+++ b/gs/src/gdevmr2n.c
@@ -28,6 +28,7 @@
#include "gxdevice.h"
#include "gxdevmem.h"
#include "gxdevrop.h"
+#include "gdevmem.h"
#include "gdevmrop.h"
extern dev_proc_strip_copy_rop(mem_mono_strip_copy_rop);
diff --git a/gs/src/gdevmr8n.c b/gs/src/gdevmr8n.c
index f07f3840f..342ae7ecf 100644
--- a/gs/src/gdevmr8n.c
+++ b/gs/src/gdevmr8n.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -68,31 +68,34 @@ mem_gray8_rgb24_strip_copy_rop(gx_device * dev,
(lop & lop_S_transparent ? all_ones : gx_no_color_index);
gx_color_index ttrans =
(lop & lop_T_transparent ? all_ones : gx_no_color_index);
- gx_color_index black = gx_device_black(dev);
- gx_color_index white = gx_device_white(dev);
/* Check for constant source. */
- if (scolors != 0 && scolors[0] == scolors[1]) { /* Constant source */
+ if (!rop3_uses_S(rop))
+ const_source = 0; /* arbitrary */
+ else if (scolors != 0 && scolors[0] == scolors[1]) {
+ /* Constant source */
const_source = scolors[0];
- if (const_source == black)
+ if (const_source == gx_device_black(dev))
rop = rop3_know_S_0(rop);
- else if (const_source == white)
+ else if (const_source == gx_device_white(dev))
rop = rop3_know_S_1(rop);
- } else if (!rop3_uses_S(rop))
- const_source = 0; /* arbitrary */
+ }
/* Check for constant texture. */
- if (tcolors != 0 && tcolors[0] == tcolors[1]) { /* Constant texture */
+ if (!rop3_uses_T(rop))
+ const_texture = 0; /* arbitrary */
+ else if (tcolors != 0 && tcolors[0] == tcolors[1]) {
+ /* Constant texture */
const_texture = tcolors[0];
- if (const_texture == black)
+ if (const_texture == gx_device_black(dev))
rop = rop3_know_T_0(rop);
- else if (const_texture == white)
+ else if (const_texture == gx_device_white(dev))
rop = rop3_know_T_1(rop);
- } else if (!rop3_uses_T(rop))
- const_texture = 0; /* arbitrary */
+ }
if (bpp == 1 &&
- (black != 0 || white != all_ones || gx_device_has_color(dev))
+ (gx_device_has_color(dev) ||
+ (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones))
) {
/*
* This is an 8-bit device but not gray-scale. Except in a few
@@ -103,20 +106,16 @@ mem_gray8_rgb24_strip_copy_rop(gx_device * dev,
switch (rop) {
case rop3_0:
- bw_pixel = black;
+ bw_pixel = gx_device_black(dev);
goto bw;
case rop3_1:
- bw_pixel = white;
-bw: switch (bw_pixel) {
- case 0x00:
+ bw_pixel = gx_device_white(dev);
+bw: if (bw_pixel == 0x00)
rop = rop3_0;
- break;
- case 0xff:
+ else if (bw_pixel == 0xff)
rop = rop3_1;
- break;
- default:
+ else
goto df;
- }
break;
case rop3_D:
break;
diff --git a/gs/src/gdevmrop.c b/gs/src/gdevmrop.c
deleted file mode 100644
index 985ba1c74..000000000
--- a/gs/src/gdevmrop.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
-
-/* RasterOp / transparency implementation for memory devices */
-#include "memory_.h"
-#include "gx.h"
-#include "gsbittab.h"
-#include "gserrors.h"
-#include "gsropt.h"
-#include "gxcindex.h"
-#include "gxdcolor.h"
-#include "gxdevice.h"
-#include "gxdevmem.h"
-#include "gxdevrop.h"
-#include "gdevmrop.h"
-
-/* Define whether we implement transparency correctly, or whether we */
-/* implement it as documented in the H-P manuals. */
-#define TRANSPARENCY_PER_H_P
-
-/*
- * NOTE: The 16- and 32-bit cases aren't implemented: they just fall back to
- * the default implementation. This is very slow and will be fixed someday.
- */
-
-#define chunk byte
-
-/* Calculate the X offset for a given Y value, */
-/* taking shift into account if necessary. */
-#define x_offset(px, ty, textures)\
- ((textures)->shift == 0 ? (px) :\
- (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
-
-/* ---------------- Monobit RasterOp ---------------- */
-
-int
-mem_mono_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_memory *mdev = (gx_device_memory *) dev;
- gs_rop3_t rop = gs_transparent_rop(lop); /* handle transparency */
- gx_strip_bitmap no_texture;
- bool invert;
- uint draster = mdev->raster;
- uint traster;
- int line_count;
- byte *drow;
- const byte *srow;
- int ty;
-
- /* If map_rgb_color isn't the default one for monobit memory */
- /* devices, palette might not be set; set it now if needed. */
- if (mdev->palette.data == 0)
- gdev_mem_mono_set_inverted(mdev,
- (*dev_proc(dev, map_rgb_color))
- (dev, (gx_color_value) 0,
- (gx_color_value) 0, (gx_color_value) 0)
- != 0);
- invert = mdev->palette.data[0] != 0;
-
-#ifdef DEBUG
- if (gs_debug_c('b'))
- trace_copy_rop("mem_mono_strip_copy_rop",
- dev, sdata, sourcex, sraster,
- id, scolors, textures, tcolors,
- x, y, width, height, phase_x, phase_y, lop);
- if (gs_debug_c('B'))
- debug_dump_bitmap(scan_line_base(mdev, y), mdev->raster,
- height, "initial dest bits");
-#endif
-
- /*
- * RasterOp is defined as operating in RGB space; in the monobit
- * case, this means black = 0, white = 1. However, most monobit
- * devices use the opposite convention. To make this work,
- * we must precondition the Boolean operation by swapping the
- * order of bits end-for-end and then inverting.
- */
-
- if (invert)
- rop = byte_reverse_bits[rop] ^ 0xff;
-
- /*
- * From this point on, rop works in terms of device pixel values,
- * not RGB-space values.
- */
-
- /* Modify the raster operation according to the source palette. */
- if (scolors != 0) { /* Source with palette. */
- switch ((int)((scolors[1] << 1) + scolors[0])) {
- case 0:
- rop = rop3_know_S_0(rop);
- break;
- case 1:
- rop = rop3_invert_S(rop);
- break;
- case 2:
- break;
- case 3:
- rop = rop3_know_S_1(rop);
- break;
- }
- }
- /* Modify the raster operation according to the texture palette. */
- if (tcolors != 0) { /* Texture with palette. */
- switch ((int)((tcolors[1] << 1) + tcolors[0])) {
- case 0:
- rop = rop3_know_T_0(rop);
- break;
- case 1:
- rop = rop3_invert_T(rop);
- break;
- case 2:
- break;
- case 3:
- rop = rop3_know_T_1(rop);
- break;
- }
- }
- /* Handle constant source and/or texture, and other special cases. */
- {
- gx_color_index color0, color1;
-
- switch (rop_usage_table[rop]) {
- case rop_usage_none:
- /* We're just filling with a constant. */
- return (*dev_proc(dev, fill_rectangle))
- (dev, x, y, width, height, (gx_color_index) (rop & 1));
- case rop_usage_D:
- /* This is either D (no-op) or ~D. */
- if (rop == rop3_D)
- return 0;
- /* Code no_S inline, then finish with no_T. */
- fit_fill(dev, x, y, width, height);
- sdata = mdev->base;
- sourcex = x;
- sraster = 0;
- goto no_T;
- case rop_usage_S:
- /* This is either S or ~S, which copy_mono can handle. */
- if (rop == rop3_S)
- color0 = 0, color1 = 1;
- else
- color0 = 1, color1 = 0;
- do_copy:return (*dev_proc(dev, copy_mono))
- (dev, sdata, sourcex, sraster, id, x, y, width, height,
- color0, color1);
- case rop_usage_DS:
- /* This might be a case that copy_mono can handle. */
-#define copy_case(c0, c1) color0 = c0, color1 = c1; goto do_copy;
- switch ((uint) rop) { /* cast shuts up picky compilers */
- case rop3_D & rop3_not(rop3_S):
- copy_case(gx_no_color_index, 0);
- case rop3_D | rop3_S:
- copy_case(gx_no_color_index, 1);
- case rop3_D & rop3_S:
- copy_case(0, gx_no_color_index);
- case rop3_D | rop3_not(rop3_S):
- copy_case(1, gx_no_color_index);
- default:;
- }
-#undef copy_case
- fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
- no_T: /* Texture is not used; textures may be garbage. */
- no_texture.data = mdev->base; /* arbitrary */
- no_texture.raster = 0;
- no_texture.size.x = width;
- no_texture.size.y = height;
- no_texture.rep_width = no_texture.rep_height = 1;
- no_texture.rep_shift = no_texture.shift = 0;
- textures = &no_texture;
- break;
- case rop_usage_T:
- /* This is either T or ~T, which tile_rectangle can handle. */
- if (rop == rop3_T)
- color0 = 0, color1 = 1;
- else
- color0 = 1, color1 = 0;
- do_tile:return (*dev_proc(dev, strip_tile_rectangle))
- (dev, textures, x, y, width, height, color0, color1,
- phase_x, phase_y);
- case rop_usage_DT:
- /* This might be a case that tile_rectangle can handle. */
-#define tile_case(c0, c1) color0 = c0, color1 = c1; goto do_tile;
- switch ((uint) rop) { /* cast shuts up picky compilers */
- case rop3_D & rop3_not(rop3_T):
- tile_case(gx_no_color_index, 0);
- case rop3_D | rop3_T:
- tile_case(gx_no_color_index, 1);
- case rop3_D & rop3_T:
- tile_case(0, gx_no_color_index);
- case rop3_D | rop3_not(rop3_T):
- tile_case(1, gx_no_color_index);
- default:;
- }
-#undef tile_case
- fit_fill(dev, x, y, width, height);
- /* Source is not used; sdata et al may be garbage. */
- sdata = mdev->base; /* arbitrary, as long as all */
- /* accesses are valid */
- sourcex = x; /* guarantee no source skew */
- sraster = 0;
- break;
- default: /* rop_usage_[D]ST */
- fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
- }
- }
-
-#ifdef DEBUG
- if_debug1('b', "final rop=0x%x\n", rop);
-#endif
-
- /* Set up transfer parameters. */
- line_count = height;
- srow = sdata;
- drow = scan_line_base(mdev, y);
- traster = textures->raster;
- ty = y + phase_y;
-
- /* Loop over scan lines. */
- for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {
- int sx = sourcex;
- int dx = x;
- int w = width;
- const byte *trow =
- textures->data + (ty % textures->rep_height) * traster;
- int xoff = x_offset(phase_x, ty, textures);
- int nw;
-
- /* Loop over (horizontal) copies of the tile. */
- for (; w > 0; sx += nw, dx += nw, w -= nw) {
- int dbit = dx & 7;
- int sbit = sx & 7;
- int sskew = sbit - dbit;
- int tx = (dx + xoff) % textures->rep_width;
- int tbit = tx & 7;
- int tskew = tbit - dbit;
- int left = nw = min(w, textures->size.x - tx);
- byte lmask = 0xff >> dbit;
- byte rmask = 0xff << (~(dbit + nw - 1) & 7);
- byte mask = lmask;
- int nx = 8 - dbit;
- byte *dptr = drow + (dx >> 3);
- const byte *sptr = srow + (sx >> 3);
- const byte *tptr = trow + (tx >> 3);
-
- if (sskew < 0)
- --sptr, sskew += 8;
- if (tskew < 0)
- --tptr, tskew += 8;
- for (; left > 0;
- left -= nx, mask = 0xff, nx = 8,
- ++dptr, ++sptr, ++tptr
- ) {
- byte dbyte = *dptr;
-
-#define fetch1(ptr, skew)\
- (skew ? (ptr[0] << skew) + (ptr[1] >> (8 - skew)) : *ptr)
- byte sbyte = fetch1(sptr, sskew);
- byte tbyte = fetch1(tptr, tskew);
-
-#undef fetch1
- byte result =
- (*rop_proc_table[rop]) (dbyte, sbyte, tbyte);
-
- if (left <= nx)
- mask &= rmask;
- *dptr = (mask == 0xff ? result :
- (result & mask) | (dbyte & ~mask));
- }
- }
- }
-#ifdef DEBUG
- if (gs_debug_c('B'))
- debug_dump_bitmap(scan_line_base(mdev, y), mdev->raster,
- height, "final dest bits");
-#endif
- return 0;
-}
-
-/* ---------------- Fake RasterOp for 2- and 4-bit devices ---------------- */
-
-/*
- * Define patched versions of the driver procedures that may be called
- * by mem_mono_strip_copy_rop (see below). Currently we just punt to
- * the slow, general case; we could do a lot better.
- */
-private int
-mem_gray_rop_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
- gx_color_index color)
-{
- return -1;
-}
-private int
-mem_gray_rop_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 -1;
-}
-private int
-mem_gray_rop_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)
-{
- return -1;
-}
-
-int
-mem_gray_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_color_index scolors2[2];
- const gx_color_index *real_scolors = scolors;
- gx_color_index tcolors2[2];
- const gx_color_index *real_tcolors = tcolors;
- gx_strip_bitmap texture2;
- const gx_strip_bitmap *real_texture = textures;
- long tdata;
- int depth = dev->color_info.depth;
- int log2_depth = depth >> 1; /* works for 2, 4 */
- gx_color_index max_pixel = (1 << depth) - 1;
- int code;
-
-#ifdef DEBUG
- if (gs_debug_c('b'))
- trace_copy_rop("mem_gray_strip_copy_rop",
- dev, sdata, sourcex, sraster,
- id, scolors, textures, tcolors,
- x, y, width, height, phase_x, phase_y, lop);
-#endif
- if (gx_device_has_color(dev) ||
- (lop & (lop_S_transparent | lop_T_transparent)) ||
- (scolors && /* must be (0,0) or (max,max) */
- ((scolors[0] | scolors[1]) != 0) &&
- ((scolors[0] & scolors[1]) != max_pixel)) ||
- (tcolors && (tcolors[0] != tcolors[1]))
- ) {
- /* We can't fake it: do it the slow, painful way. */
- return gx_default_strip_copy_rop(dev,
- sdata, sourcex, sraster, id, scolors, textures, tcolors,
- x, y, width, height, phase_x, phase_y, lop);
- }
- if (scolors) { /* Must be a solid color: see above. */
- scolors2[0] = scolors2[1] = scolors[0] & 1;
- real_scolors = scolors2;
- }
- if (textures) {
- texture2 = *textures;
- texture2.size.x <<= log2_depth;
- texture2.rep_width <<= log2_depth;
- texture2.shift <<= log2_depth;
- texture2.rep_shift <<= log2_depth;
- real_texture = &texture2;
- }
- if (tcolors) {
- /* For polybit textures with colors other than */
- /* all 0s or all 1s, fabricate the data. */
- if (tcolors[0] != 0 && tcolors[0] != max_pixel) {
- real_tcolors = 0;
- *(byte *) & tdata = (byte) tcolors[0] << (8 - depth);
- texture2.data = (byte *) & tdata;
- texture2.raster = align_bitmap_mod;
- texture2.size.x = texture2.rep_width = depth;
- texture2.size.y = texture2.rep_height = 1;
- texture2.id = gx_no_bitmap_id;
- texture2.shift = texture2.rep_shift = 0;
- real_texture = &texture2;
- } else {
- tcolors2[0] = tcolors2[1] = tcolors[0] & 1;
- real_tcolors = tcolors2;
- }
- }
- /*
- * mem_mono_strip_copy_rop may call fill_rectangle, copy_mono, or
- * strip_tile_rectangle for special cases. Patch those procedures
- * temporarily so they will either do the right thing or return
- * an error.
- */
- {
- dev_proc_fill_rectangle((*fill_rectangle)) =
- dev_proc(dev, fill_rectangle);
- dev_proc_copy_mono((*copy_mono)) =
- dev_proc(dev, copy_mono);
- dev_proc_strip_tile_rectangle((*strip_tile_rectangle)) =
- dev_proc(dev, strip_tile_rectangle);
-
- set_dev_proc(dev, fill_rectangle, mem_gray_rop_fill_rectangle);
- set_dev_proc(dev, copy_mono, mem_gray_rop_copy_mono);
- set_dev_proc(dev, strip_tile_rectangle,
- mem_gray_rop_strip_tile_rectangle);
- dev->width <<= log2_depth;
- code = mem_mono_strip_copy_rop(dev, sdata,
- (real_scolors == NULL ?
- sourcex << log2_depth : sourcex),
- sraster, id, real_scolors,
- real_texture, real_tcolors,
- x << log2_depth, y,
- width << log2_depth, height,
- phase_x << log2_depth, phase_y, lop);
- set_dev_proc(dev, fill_rectangle, fill_rectangle);
- set_dev_proc(dev, copy_mono, copy_mono);
- set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle);
- dev->width >>= log2_depth;
- }
- /* If we punted, use the general procedure. */
- if (code < 0)
- return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
- scolors, textures, tcolors,
- x, y, width, height,
- phase_x, phase_y, lop);
- return code;
-}
-
-/* ---------------- RasterOp with 8-bit gray / 24-bit RGB ---------------- */
-
-int
-mem_gray8_rgb24_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_memory *mdev = (gx_device_memory *) dev;
- gs_rop3_t rop = lop_rop(lop);
- gx_color_index const_source = gx_no_color_index;
- gx_color_index const_texture = gx_no_color_index;
- uint draster = mdev->raster;
- int line_count;
- byte *drow;
- int depth = dev->color_info.depth;
- int bpp = depth >> 3; /* bytes per pixel, 1 or 3 */
- gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1;
- gx_color_index strans =
- (lop & lop_S_transparent ? all_ones : gx_no_color_index);
- gx_color_index ttrans =
- (lop & lop_T_transparent ? all_ones : gx_no_color_index);
- gx_color_index black = gx_device_black(dev);
- gx_color_index white = gx_device_white(dev);
-
- /* Check for constant source. */
- if (scolors != 0 && scolors[0] == scolors[1]) { /* Constant source */
- const_source = scolors[0];
- if (const_source == black)
- rop = rop3_know_S_0(rop);
- else if (const_source == white)
- rop = rop3_know_S_1(rop);
- } else if (!rop3_uses_S(rop))
- const_source = 0; /* arbitrary */
-
- /* Check for constant texture. */
- if (tcolors != 0 && tcolors[0] == tcolors[1]) { /* Constant texture */
- const_texture = tcolors[0];
- if (const_texture == black)
- rop = rop3_know_T_0(rop);
- else if (const_texture == white)
- rop = rop3_know_T_1(rop);
- } else if (!rop3_uses_T(rop))
- const_texture = 0; /* arbitrary */
-
- if (bpp == 1 &&
- (black != 0 || white != all_ones || gx_device_has_color(dev))
- ) {
- /*
- * This is an 8-bit device but not gray-scale. Except in a few
- * simple cases, we have to use the slow algorithm that converts
- * values to and from RGB.
- */
- gx_color_index bw_pixel;
-
- switch (rop) {
- case rop3_0:
- bw_pixel = black;
- goto bw;
- case rop3_1:
- bw_pixel = white;
-bw: switch (bw_pixel) {
- case 0x00:
- rop = rop3_0;
- break;
- case 0xff:
- rop = rop3_1;
- break;
- default:
- goto df;
- }
- break;
- case rop3_D:
- break;
- case rop3_S:
- if (lop & lop_S_transparent)
- goto df;
- break;
- case rop3_T:
- if (lop & lop_T_transparent)
- goto df;
- break;
- default:
-df: return gx_default_strip_copy_rop(dev,
- sdata, sourcex, sraster, id, scolors,
- textures, tcolors, x, y, width, height,
- phase_x, phase_y, lop);
- }
- }
-
- /* Adjust coordinates to be in bounds. */
- if (const_source == gx_no_color_index) {
- fit_copy(dev, sdata, sourcex, sraster, id,
- x, y, width, height);
- } else {
- fit_fill(dev, x, y, width, height);
- }
-
- /* Set up transfer parameters. */
- line_count = height;
- drow = scan_line_base(mdev, y) + x * bpp;
-
- /*
- * There are 18 cases depending on whether each of the source and
- * texture is constant, 1-bit, or multi-bit, and on whether the
- * depth is 8 or 24 bits. We divide first according to constant
- * vs. non-constant, and then according to 1- vs. multi-bit, and
- * finally according to pixel depth. This minimizes source code,
- * but not necessarily time, since we do some of the divisions
- * within 1 or 2 levels of loop.
- */
-
-#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
-/* 8-bit */
-#define cbit8(base, i, colors)\
- (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
-#define rop_body_8(s_pixel, t_pixel)\
- if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\
- (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\
- )\
- continue;\
- *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
-/* 24-bit */
-#define get24(ptr)\
- (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
-#define put24(ptr, pixel)\
- (ptr)[0] = (byte)((pixel) >> 16),\
- (ptr)[1] = (byte)((uint)(pixel) >> 8),\
- (ptr)[2] = (byte)(pixel)
-#define cbit24(base, i, colors)\
- (dbit(base, i) ? colors[1] : colors[0])
-#define rop_body_24(s_pixel, t_pixel)\
- if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\
- (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\
- )\
- continue;\
- { gx_color_index d_pixel = get24(dptr);\
- d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
- put24(dptr, d_pixel);\
- }
-
- if (const_texture != gx_no_color_index) {
-/**** Constant texture ****/
- if (const_source != gx_no_color_index) {
-/**** Constant source & texture ****/
- for (; line_count-- > 0; drow += draster) {
- byte *dptr = drow;
- int left = width;
-
- if (bpp == 1)
-/**** 8-bit destination ****/
- for (; left > 0; ++dptr, --left) {
- rop_body_8((byte)const_source, (byte)const_texture);
- }
- else
-/**** 24-bit destination ****/
- for (; left > 0; dptr += 3, --left) {
- rop_body_24(const_source, const_texture);
- }
- }
- } else {
-/**** Data source, const texture ****/
- const byte *srow = sdata;
-
- for (; line_count-- > 0; drow += draster, srow += sraster) {
- byte *dptr = drow;
- int left = width;
-
- if (scolors) {
-/**** 1-bit source ****/
- int sx = sourcex;
-
- if (bpp == 1)
-/**** 8-bit destination ****/
- for (; left > 0; ++dptr, ++sx, --left) {
- byte s_pixel = cbit8(srow, sx, scolors);
-
- rop_body_8(s_pixel, (byte)const_texture);
- }
- else
-/**** 24-bit destination ****/
- for (; left > 0; dptr += 3, ++sx, --left) {
- bits32 s_pixel = cbit24(srow, sx, scolors);
-
- rop_body_24(s_pixel, const_texture);
- }
- } else if (bpp == 1) {
-/**** 8-bit source & dest ****/
- const byte *sptr = srow + sourcex;
-
- for (; left > 0; ++dptr, ++sptr, --left) {
- byte s_pixel = *sptr;
-
- rop_body_8(s_pixel, (byte)const_texture);
- }
- } else {
-/**** 24-bit source & dest ****/
- const byte *sptr = srow + sourcex * 3;
-
- for (; left > 0; dptr += 3, sptr += 3, --left) {
- bits32 s_pixel = get24(sptr);
-
- rop_body_24(s_pixel, const_texture);
- }
- }
- }
- }
- } else if (const_source != gx_no_color_index) {
-/**** Const source, data texture ****/
- uint traster = textures->raster;
- int ty = y + phase_y;
-
- for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */
- int dx = x, w = width, nw;
- byte *dptr = drow;
- const byte *trow =
- textures->data + (ty % textures->size.y) * traster;
- int xoff = x_offset(phase_x, ty, textures);
-
- for (; w > 0; dx += nw, w -= nw) {
- int tx = (dx + xoff) % textures->rep_width;
- int left = nw = min(w, textures->size.x - tx);
- const byte *tptr = trow;
-
- if (tcolors) {
-/**** 1-bit texture ****/
- if (bpp == 1)
-/**** 8-bit dest ****/
- for (; left > 0; ++dptr, ++tx, --left) {
- byte t_pixel = cbit8(tptr, tx, tcolors);
-
- rop_body_8((byte)const_source, t_pixel);
- }
- else
-/**** 24-bit dest ****/
- for (; left > 0; dptr += 3, ++tx, --left) {
- bits32 t_pixel = cbit24(tptr, tx, tcolors);
-
- rop_body_24(const_source, t_pixel);
- }
- } else if (bpp == 1) {
-/**** 8-bit T & D ****/
- tptr += tx;
- for (; left > 0; ++dptr, ++tptr, --left) {
- byte t_pixel = *tptr;
-
- rop_body_8((byte)const_source, t_pixel);
- }
- } else {
-/**** 24-bit T & D ****/
- tptr += tx * 3;
- for (; left > 0; dptr += 3, tptr += 3, --left) {
- bits32 t_pixel = get24(tptr);
-
- rop_body_24(const_source, t_pixel);
- }
- }
- }
- }
- } else {
-/**** Data source & texture ****/
- uint traster = textures->raster;
- int ty = y + phase_y;
- const byte *srow = sdata;
-
- /* Loop over scan lines. */
- for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */
- int sx = sourcex;
- int dx = x;
- int w = width;
- int nw;
- byte *dptr = drow;
- const byte *trow =
- textures->data + (ty % textures->size.y) * traster;
- int xoff = x_offset(phase_x, ty, textures);
-
- for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */
- int tx = (dx + xoff) % textures->rep_width;
- int left = nw = min(w, textures->size.x - tx);
- const byte *tptr = trow;
-
- /*
- * For maximum speed, we should split this loop
- * into 7 cases depending on source & texture
- * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
- * (24,1), (24,24). But since we expect these
- * cases to be relatively uncommon, we just
- * divide on the destination depth.
- */
- if (bpp == 1) {
-/**** 8-bit destination ****/
- const byte *sptr = srow + sx;
-
- tptr += tx;
- for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
- byte s_pixel =
- (scolors ? cbit8(srow, sx, scolors) : *sptr);
- byte t_pixel =
- (tcolors ? cbit8(tptr, tx, tcolors) : *tptr);
-
- rop_body_8(s_pixel, t_pixel);
- }
- } else {
-/**** 24-bit destination ****/
- const byte *sptr = srow + sx * 3;
-
- tptr += tx * 3;
- for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
- bits32 s_pixel =
- (scolors ? cbit24(srow, sx, scolors) :
- get24(sptr));
- bits32 t_pixel =
- (tcolors ? cbit24(tptr, tx, tcolors) :
- get24(tptr));
-
- rop_body_24(s_pixel, t_pixel);
- }
- }
- }
- }
- }
-#undef rop_body_8
-#undef rop_body_24
-#undef dbit
-#undef cbit8
-#undef cbit24
- return 0;
-}
diff --git a/gs/src/gdevmrop.h b/gs/src/gdevmrop.h
index eecf5338f..800373957 100644
--- a/gs/src/gdevmrop.h
+++ b/gs/src/gdevmrop.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -72,8 +72,10 @@ struct gx_device_rop_texture_s {
};
#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)
+ gs_private_st_composite_use_final(st_device_rop_texture,\
+ gx_device_rop_texture, "gx_device_rop_texture",\
+ device_rop_texture_enum_ptrs, device_rop_texture_reloc_ptrs,\
+ gx_device_finalize)
/* Create a RasterOp source device. */
int gx_alloc_rop_texture_device(P3(gx_device_rop_texture ** prsdev,
diff --git a/gs/src/gdevmrun.c b/gs/src/gdevmrun.c
new file mode 100644
index 000000000..35cf5dbbf
--- /dev/null
+++ b/gs/src/gdevmrun.c
@@ -0,0 +1,657 @@
+/* Copyright (C) 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Run-length encoded memory device */
+#include "memory_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gdevmrun.h"
+
+/*
+ * NOTE: THIS CODE HAS NOT BEEN TESTED. IF YOU WANT TO USE IT, PLEASE
+ * TEST IT CAREFULLY AND REPORT ANY PROBLEMS.
+ */
+
+/*
+ * Define the representation of each run. We store runs in a doubly-linked
+ * list. Run 0 is a dummy end-of-line run; run 1 is a dummy start-of-line
+ * run. The dummy runs have length MAX_RUN_LENGTH to prevent merging.
+ *
+ * We limit the number of runs per line for two reasons: if there are many
+ * runs, the run-length representation probably isn't buying us much; and
+ * we need to allocate temporary space on the stack for the runs when we
+ * expand a line to uncompressed form.
+ */
+typedef gx_color_index run_value;
+typedef uint run_index;
+#define RUN_INDEX_BITS 10 /* see above */
+#define MAX_RUNS (1 << RUN_INDEX_BITS)
+#define MAX_RUN_INDEX (MAX_RUNS - 1)
+typedef uint run_length;
+#define RUN_LENGTH_BITS (32 - 2 * RUN_INDEX_BITS)
+#define MAX_RUN_LENGTH ((1 << RUN_LENGTH_BITS) - 1)
+typedef struct run_s {
+ run_value value;
+ run_length length : RUN_LENGTH_BITS;
+ run_index next : RUN_INDEX_BITS;
+ run_index prev : RUN_INDEX_BITS; /* 0 iff free run */
+} run;
+
+/*
+ * Define a pointer into a run list.
+ * For speed, we keep both the index of and the pointer to the current run.
+ */
+typedef struct run_ptr_s {
+ run *ptr;
+ run_index index; /* index of current run */
+} run_ptr;
+typedef struct const_run_ptr_s {
+ const run *ptr;
+ run_index index; /* index of current run */
+} const_run_ptr;
+
+/* Accessors */
+#define RP_LENGTH(rp) ((rp).ptr->length)
+#define RP_VALUE(rp) ((rp).ptr->value)
+#define RP_NEXT(rp) ((rp).ptr->next)
+#define RP_PREV(rp) ((rp).ptr->prev)
+#define RL_DATA(line) ((run *)((line) + 1))
+#define CONST_RL_DATA(line) ((const run *)((line) + 1))
+#define RDEV_LINE(rdev, y) ((run_line *)scan_line_base(&(rdev)->md, y))
+/* Traversers */
+#define RP_AT_START(rp) ((rp).index == 1)
+#define RP_AT_END(rp) ((rp).index == 0)
+#define RP_TO_START(rp, data)\
+ ((rp).index = (data)[1].next,\
+ (rp).ptr = (data) + (rp).index)
+/* Note that RP_TO_NEXT and RP_TO_PREV allow rpn == rpc. */
+#define RP_TO_NEXT(rpc, data, rpn)\
+ ((rpn).ptr = (data) + ((rpn).index = RP_NEXT(rpc)))
+#define RP_TO_PREV(rpc, data, rpp)\
+ ((rpp).ptr = (data) + ((rpp).index = RP_PREV(rpc)))
+
+/*
+ * Define the state of a single scan line.
+ *
+ * We maintain the following invariant: if two adjacent runs have the
+ * same value, the sum of their lengths is greater than MAX_RUN_LENGTH.
+ * This may miss optimality by nearly a factor of 2, but it's far easier
+ * to maintain than a true optimal representation.
+ *
+ * For speed in the common case where nothing other than white is ever stored,
+ * we initially don't bother to construct the runs (or the free run list)
+ * for a line at all.
+ */
+typedef struct run_line_s {
+ gx_color_index zero; /* device white if line not initialized, */
+ /* gx_no_color_index if initialized */
+ uint xcur; /* x value at cursor position */
+ run_ptr rpcur; /* cursor */
+ run_index free; /* head of free list */
+} run_line;
+
+/* Insert/delete */
+private void
+rp_delete_next(run_ptr *prpc, run *data, run_line *line)
+{
+ run_ptr rpn, rpn2;
+
+ RP_TO_NEXT(*prpc, data, rpn);
+ RP_TO_NEXT(rpn, data, rpn2);
+ RP_NEXT(*prpc) = rpn2.index;
+ RP_PREV(rpn2) = prpc->index;
+ RP_NEXT(rpn) = line->free;
+ RP_PREV(rpn) = 0;
+ line->free = rpn.index;
+}
+private int
+rp_insert_next(run_ptr *prpc, run *data, run_line *line, run_ptr *prpn)
+{
+ run_index new = line->free;
+ run *prnew = data + new;
+
+ if (new == 0)
+ return -1;
+ RP_TO_NEXT(*prpc, data, *prpn);
+ RP_NEXT(*prpc) = new;
+ RP_PREV(*prpn) = new;
+ line->free = prnew->next;
+ prnew->prev = prpc->index;
+ prnew->next = prpn->index;
+ prpn->index = new;
+ prpn->ptr = prnew;
+ return 0;
+}
+private int
+rp_insert_prev(run_ptr *prpc, run *data, run_line *line, run_ptr *prpp)
+{
+ run_index new = line->free;
+ run *prnew = data + new;
+
+ if (new == 0)
+ return -1;
+ RP_TO_PREV(*prpc, data, *prpp);
+ RP_NEXT(*prpp) = new;
+ RP_PREV(*prpc) = new;
+ line->free = prnew->next;
+ prnew->prev = prpp->index;
+ prnew->next = prpc->index;
+ prpp->index = new;
+ prpp->ptr = prnew;
+ return 0;
+}
+
+/* Define the run-oriented device procedures. */
+private dev_proc_copy_mono(run_copy_mono);
+private dev_proc_copy_color(run_copy_color);
+private dev_proc_fill_rectangle(run_fill_rectangle);
+private dev_proc_copy_alpha(run_copy_alpha);
+private dev_proc_strip_tile_rectangle(run_strip_tile_rectangle);
+private dev_proc_strip_copy_rop(run_strip_copy_rop);
+private dev_proc_get_bits_rectangle(run_get_bits_rectangle);
+
+/*
+ * Convert a memory device to run-length form. The mdev argument should be
+ * const, but it isn't because we need to call gx_device_white.
+ */
+int
+gdev_run_from_mem(gx_device_run *rdev, gx_device_memory *mdev)
+{
+ int runs_per_line =
+ (bitmap_raster(mdev->width * mdev->color_info.depth) -
+ sizeof(run_line)) / sizeof(run);
+ /*
+ * We use the scan lines of the memory device for storing runs. We need
+ * ceil(width / MAX_RUN_LENGTH) runs to represent a line where all
+ * elements have the same value, +2 for the start and end runs.
+ */
+ int min_runs = (mdev->width + (MAX_RUN_LENGTH - 1)) / MAX_RUN_LENGTH + 2;
+ int i;
+ gx_color_index white = gx_device_white((gx_device *)mdev);
+
+ rdev->md = *mdev;
+ if (runs_per_line > MAX_RUNS)
+ runs_per_line = MAX_RUNS;
+ if (runs_per_line < min_runs)
+ return 0; /* just use the memory device as-is */
+ for (i = 0; i < mdev->height; ++i) {
+ run_line *line = RDEV_LINE(rdev, i);
+
+ line->zero = white;
+ }
+ rdev->runs_per_line = runs_per_line;
+ rdev->umin = 0;
+ rdev->umax1 = mdev->height;
+ rdev->smin = mdev->height;
+ rdev->smax1 = 0;
+ /* Save and replace the representation-aware rendering procedures. */
+#define REPLACE(proc, rproc)\
+ (rdev->save_procs.proc = dev_proc(&rdev->md, proc),\
+ set_dev_proc(&rdev->md, proc, rproc))
+ REPLACE(copy_mono, run_copy_mono);
+ REPLACE(copy_color, run_copy_color);
+ REPLACE(fill_rectangle, run_fill_rectangle);
+ REPLACE(copy_alpha, run_copy_alpha);
+ REPLACE(strip_tile_rectangle, run_strip_tile_rectangle);
+ REPLACE(strip_copy_rop, run_strip_copy_rop);
+ REPLACE(get_bits_rectangle, run_get_bits_rectangle);
+#undef REPLACE
+ return 0;
+}
+
+/* Convert a scan line to expanded form in place. */
+private int
+run_expand(gx_device_run *rdev, int y)
+{
+ const run_line *line = RDEV_LINE(rdev, y);
+ const run *const data = CONST_RL_DATA(line);
+ const_run_ptr rp;
+ int n, x, w;
+#if RUN_LENGTH_BITS <= 8
+ byte length[MAX_RUNS];
+#else
+# if RUN_LENGTH_BITS <= 16
+ ushort length[MAX_RUNS];
+# else
+ uint length[MAX_RUNS];
+# endif
+#endif
+ gx_color_index value[MAX_RUNS];
+
+ if (line->zero != gx_no_color_index) {
+ rdev->save_procs.fill_rectangle((gx_device *)&rdev->md,
+ 0, y, rdev->md.width, 1, line->zero);
+ return 0;
+ }
+ /* Copy the runs into local storage to avoid stepping on our own toes. */
+ for (n = 0, RP_TO_START(rp, data); !RP_AT_END(rp);
+ ++n, RP_TO_NEXT(rp, data, rp)
+ ) {
+ length[n] = RP_LENGTH(rp);
+ value[n] = RP_VALUE(rp);
+ }
+ for (x = 0, n = 0; x < rdev->md.width; x += w, ++n) {
+ w = length[n];
+ rdev->save_procs.fill_rectangle((gx_device *)&rdev->md,
+ x, y, w, 1, value[n]);
+ }
+ return 0;
+}
+
+/*
+ * Convert a range of scan lines to standard form.
+ */
+private int
+run_standardize(gx_device_run *rdev, int y, int h)
+{
+ int ye, iy;
+
+ fit_fill_y(&rdev->md, y, h);
+ fit_fill_h(&rdev->md, y, h);
+ ye = y + h;
+ if (y < rdev->smin) {
+ if (ye > rdev->smax1)
+ run_standardize(rdev, rdev->smax1, ye - rdev->smax1);
+ if (ye < rdev->smin)
+ ye = rdev->smin;
+ rdev->smin = y;
+ } else if (ye > rdev->smax1) {
+ if (y > rdev->smax1)
+ y = rdev->smax1;
+ rdev->smax1 = ye;
+ } else
+ return 0;
+ for (iy = y; iy < ye; ++iy)
+ run_expand(rdev, iy);
+ return 0;
+}
+
+/* Trampoline rendering procedures */
+private int
+run_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_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, y, h);
+ return rdev->save_procs.copy_mono((gx_device *)&rdev->md,
+ data, dx, raster, id,
+ x, y, w, h, zero, one);
+}
+private int
+run_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)
+{
+ gx_device_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, y, h);
+ return rdev->save_procs.copy_color((gx_device *)&rdev->md,
+ data, data_x, raster, id,
+ x, y, w, h);
+}
+private int
+run_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_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, y, h);
+ return rdev->save_procs.copy_alpha((gx_device *)&rdev->md,
+ data, data_x, raster, id,
+ x, y, w, h, color, depth);
+}
+private int
+run_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_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, y, h);
+ return rdev->save_procs.strip_tile_rectangle((gx_device *)&rdev->md,
+ tiles, x, y, w, h,
+ color0, color1, px, py);
+}
+private int
+run_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 px, int py,
+ gs_logical_operation_t lop)
+{
+ gx_device_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, y, h);
+ return rdev->save_procs.strip_copy_rop((gx_device *)&rdev->md,
+ sdata, sourcex, sraster,
+ id, scolors, textures, tcolors,
+ x, y, w, h, px, py, lop);
+}
+private int
+run_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
+ gs_get_bits_params_t * params, gs_int_rect **unread)
+{
+ gx_device_run *const rdev = (gx_device_run *)dev;
+
+ run_standardize(rdev, prect->p.y, prect->q.y - prect->p.y);
+ return rdev->save_procs.get_bits_rectangle((gx_device *)&rdev->md,
+ prect, params, unread);
+}
+
+/* Finish initializing a line. This is a separate procedure only */
+/* for readability. */
+private void
+run_line_initialize(gx_device_run *rdev, int y)
+{
+ run_line *line = RDEV_LINE(rdev, y);
+ run *data = RL_DATA(line);
+ int left = rdev->md.width;
+ run_index index = 2;
+ run *rcur;
+
+ line->zero = gx_no_color_index;
+ data[0].length = MAX_RUN_LENGTH; /* see above */
+ data[0].value = gx_no_color_index; /* shouldn't matter */
+ data[1].length = MAX_RUN_LENGTH;
+ data[1].value = gx_no_color_index;
+ data[1].next = 2;
+ rcur = data + index;
+ for (; left > 0; index++, rcur++, left -= MAX_RUN_LENGTH) {
+ rcur->length = min(left, MAX_RUN_LENGTH);
+ rcur->value = 0;
+ rcur->prev = index - 1;
+ rcur->next = index + 1;
+ }
+ rcur->next = 0;
+ data[0].prev = index - 1;
+ line->xcur = 0;
+ line->rpcur.ptr = data + 2;
+ line->rpcur.index = 2;
+ line->free = index;
+ for (; index < rdev->runs_per_line; ++index)
+ data[index].next = index + 1;
+ data[index - 1].next = 0;
+ if (y >= rdev->umin && y < rdev->umax1) {
+ if (y > (rdev->umin + rdev->umax1) >> 1)
+ rdev->umax1 = y;
+ else
+ rdev->umin = y + 1;
+ }
+}
+
+/*
+ * Replace an interval of a line with a new value. This is the procedure
+ * that does all the interesting work. We assume the line has been
+ * initialized, and that 0 <= xo < xe <= dev->width.
+ */
+private int
+run_fill_interval(run_line *line, int xo, int xe, run_value new)
+{
+ run *data = RL_DATA(line);
+ int xc = line->xcur;
+ run_ptr rpc;
+ int x0, x1;
+ run_ptr rp0;
+ int code;
+
+ rpc = line->rpcur;
+
+ /* Find the run that contains xo. */
+
+ if (xo < xc) {
+ while (xo < xc)
+ RP_TO_PREV(rpc, data, rpc), xc -= RP_LENGTH(rpc);
+ } else {
+ while (xo >= xc + RP_LENGTH(rpc))
+ xc += RP_LENGTH(rpc), RP_TO_NEXT(rpc, data, rpc);
+ }
+
+ /*
+ * Skip runs above xo that already contain the new value.
+ * If the entire interval already has the correct value, exit.
+ * If we skip any such runs, set xo to just above them.
+ */
+
+ for (; !RP_AT_END(rpc) && RP_VALUE(rpc) == new;
+ RP_TO_NEXT(rpc, data, rpc)
+ )
+ if ((xo = xc += RP_LENGTH(rpc)) >= xe)
+ return 0;
+ x0 = xc, rp0 = rpc;
+
+ /* Find the run that contains xe-1. */
+
+ while (xe > xc + RP_LENGTH(rpc))
+ xc += RP_LENGTH(rpc), RP_TO_NEXT(rpc, data, rpc);
+
+ /*
+ * Skip runs below xe that already contain the new value.
+ * (We know that some run between xo and xe doesn't.)
+ * If we skip any such runs, set xe to just below them.
+ */
+
+ while (RP_TO_PREV(rpc, data, rpc), RP_VALUE(rpc) == new)
+ xe = xc -= RP_LENGTH(rpc);
+ RP_TO_NEXT(rpc, data, rpc);
+
+ /*
+ * At this point, we know the following:
+ * x0 <= xo < x0 + RP_LENGTH(rp0).
+ * RP_VALUE(rp0) != new.
+ * xc <= xe-1 < xc + RP_LENGTH(rpc).
+ * RP_VALUE(rpc) != new.
+ * Note that rp0 and rpc may point to the same run.
+ */
+
+ /* Split off any unaffected prefix of the run at rp0. */
+
+ if (x0 < xo) {
+ uint diff = xo - x0;
+ run_value v0 = RP_VALUE(rp0);
+ run_ptr rpp;
+
+ RP_TO_PREV(rp0, data, rpp);
+ if (RP_VALUE(rpp) == v0 && RP_LENGTH(rpp) + diff <= MAX_RUN_LENGTH)
+ RP_LENGTH(rpp) += diff;
+ else {
+ code = rp_insert_prev(&rp0, data, line, &rpp);
+ if (code < 0)
+ return code;
+ RP_LENGTH(rpp) = diff;
+ RP_VALUE(rpp) = v0;
+ }
+ RP_LENGTH(rp0) -= diff;
+ }
+
+ /* Split off any unaffected suffix of the run at rpc. */
+
+ x1 = xc + RP_LENGTH(rpc);
+ if (x1 > xe) {
+ uint diff = x1 - xe;
+ run_value vc = RP_VALUE(rpc);
+ run_ptr rpn;
+
+ RP_TO_NEXT(rpc, data, rpn);
+ if (RP_VALUE(rpn) == vc && RP_LENGTH(rpn) + diff <= MAX_RUN_LENGTH)
+ RP_LENGTH(rpn) += diff;
+ else {
+ code = rp_insert_next(&rpc, data, line, &rpn);
+ if (code < 0)
+ return code;
+ RP_LENGTH(rpn) = diff;
+ RP_VALUE(rpn) = vc;
+ }
+ RP_LENGTH(rpc) -= diff;
+ }
+
+ /* Delete all runs from rp0 through rpc. */
+
+ RP_TO_PREV(rp0, data, rp0);
+ while (RP_NEXT(rp0) != RP_NEXT(rpc))
+ rp_delete_next(&rp0, data, line);
+
+ /*
+ * Finally, insert new runs with the new value.
+ * We need to check for one boundary case, namely,
+ * xo == x0 and the next lower run has the new value.
+ * (There's probably a way to structure the code just slightly
+ * differently to avoid this test.)
+ */
+
+ {
+ uint left = xe - xo;
+
+ if (xo == x0 && RP_VALUE(rp0) == new &&
+ RP_LENGTH(rp0) + left <= MAX_RUN_LENGTH
+ )
+ RP_LENGTH(rp0) += left;
+ else {
+ /*
+ * If we need more than one run, we divide up the length to
+ * create more runs with length less than MAX_RUN_LENGTH in
+ * order to improve the chances of a later merge. However,
+ * we still guarantee that we won't create more runs than
+ * the minimum number required to represent the length.
+ */
+ run_length len;
+
+ if (left <= MAX_RUN_LENGTH)
+ len = left;
+ else {
+ /*len = ceil(left / ceil(left / MAX_RUN_LENGTH))*/
+ int pieces = left + (MAX_RUN_LENGTH - 1) / MAX_RUN_LENGTH;
+
+ len = (left + pieces - 1) / pieces;
+ }
+ do {
+ run_ptr rpn;
+
+ /*
+ * The allocation in rp_insert_next can't fail, because
+ * we just deleted at least as many runs as we're going
+ * to insert.
+ */
+ rp_insert_next(&rp0, data, line, &rpn);
+ RP_LENGTH(rpn) = min(left, len);
+ RP_VALUE(rpn) = new;
+ }
+ while ((left -= len) > 0);
+ }
+ }
+
+ return 0;
+}
+
+/* Replace a rectangle with a new value. */
+private int
+run_fill_rectangle(gx_device *dev, int x, int y, int w, int h,
+ gx_color_index color)
+{
+ gx_device_run *const rdev = (gx_device_run *)dev;
+ int xe, ye;
+ int iy;
+
+ fit_fill(dev, x, y, w, h);
+ ye = y + h;
+ /*
+ * If the new value is white and the rectangle falls entirely within
+ * the uninitialized region that we're keeping track of,
+ * we can skip the entire operation.
+ */
+ if (y >= rdev->umin && ye <= rdev->umax1 &&
+ color == RDEV_LINE(rdev, y)->zero
+ )
+ return 0;
+
+ /*
+ * Hand off any parts of the operation that fall within the area
+ * already in standard form.
+ */
+ if (y < rdev->smax1 && ye > rdev->smin) {
+ /* Some part of the operation must be handed off. */
+ if (y < rdev->smin) {
+ run_fill_rectangle(dev, x, y, w, rdev->smin - y, color);
+ y = rdev->smin;
+ }
+ /* Now rdev->smin <= y < ye. */
+ rdev->save_procs.fill_rectangle((gx_device *)&rdev->md,
+ x, y, w, min(ye, rdev->smax1) - y,
+ color);
+ if (ye <= rdev->smax1)
+ return 0;
+ y = rdev->smax1;
+ }
+ xe = x + w;
+ for (iy = y; iy < ye; ++iy) {
+ run_line *line = RDEV_LINE(rdev, iy);
+
+ if (color != line->zero) {
+ if (line->zero != gx_no_color_index)
+ run_line_initialize(rdev, iy);
+ if (run_fill_interval(line, x, xe, color) < 0) {
+ /* We ran out of runs. Convert to expanded form. */
+ run_standardize(rdev, iy, 1);
+ rdev->save_procs.fill_rectangle((gx_device *)&rdev->md,
+ x, iy, w, 1, color);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Debugging code */
+
+#ifdef DEBUG
+
+void
+debug_print_run(const run *data, run_index index, const char *prefix)
+{
+ const run *pr = data + index;
+
+ dlprintf6("%s%5d: length = %3d, value = 0x%lx, prev = %5u, next = %5u\n",
+ prefix, index, pr->length, (ulong)pr->value, pr->prev, pr->next);
+}
+
+void
+debug_print_run_line(const run_line *line, const char *prefix)
+{
+ const run *data = CONST_RL_DATA(line);
+
+ dlprintf5("%sruns at 0x%lx: zero = 0x%lx, free = %u, xcur = %u,\n",
+ prefix, (ulong)data, (ulong)line->zero, line->free, line->xcur);
+ dlprintf3("%s rpcur = {ptr = 0x%lx, index = %u}\n",
+ prefix, (ulong)line->rpcur.ptr, line->rpcur.index);
+ {
+ const_run_ptr rpc;
+
+ RP_TO_START(rpc, data);
+ while (!RP_AT_END(rpc)) {
+ debug_print_run(data, rpc.index, prefix);
+ RP_TO_NEXT(rpc, data, rpc);
+ }
+ }
+}
+
+#endif /* DEBUG */
diff --git a/gs/src/gdevmrun.h b/gs/src/gdevmrun.h
new file mode 100644
index 000000000..8dac8d254
--- /dev/null
+++ b/gs/src/gdevmrun.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definition of run-length encoded memory device */
+
+#ifndef gdevmrun_INCLUDED
+# define gdevmrun_INCLUDED
+
+/*
+ * This memory device stores full-size pixels with run-length
+ * encoding if possible, switching to the standard uncompressed
+ * representation if necessary.
+ */
+
+#include "gxdevmem.h"
+
+/*
+ * Define the device, built on a memory device.
+ */
+typedef struct gx_device_run_s {
+ gx_device_memory md; /* must be first */
+ uint runs_per_line;
+ int umin, umax1; /* some range of uninitialized lines */
+ int smin, smax1; /* some range in standard (not run) form */
+ /*
+ * Save memory device procedures that we replace with run-oriented
+ * ones, for use with the uncompressed representation.
+ */
+ struct sp_ {
+ dev_proc_copy_mono((*copy_mono));
+ dev_proc_copy_color((*copy_color));
+ dev_proc_fill_rectangle((*fill_rectangle));
+ dev_proc_copy_alpha((*copy_alpha));
+ dev_proc_strip_tile_rectangle((*strip_tile_rectangle));
+ dev_proc_strip_copy_rop((*strip_copy_rop));
+ dev_proc_get_bits_rectangle((*get_bits_rectangle));
+ } save_procs;
+} gx_device_run;
+
+/*
+ * Convert a memory device to run-length form. The mdev argument should be
+ * const, but it isn't because we need to call gx_device_white.
+ */
+int gdev_run_from_mem(P2(gx_device_run *rdev, gx_device_memory *mdev));
+
+#endif /* gdevmrun_INCLUDED */
diff --git a/gs/src/gdevmswn.c b/gs/src/gdevmswn.c
index 5bd6600c3..f313ca9b5 100644
--- a/gs/src/gdevmswn.c
+++ b/gs/src/gdevmswn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,6 +30,7 @@
#include "gsparam.h"
#include "gdevpccm.h"
#include "gsdll.h"
+#include "gsdllwin.h"
/* Forward references */
private int win_set_bits_per_pixel(P2(gx_device_win *, int));
@@ -53,11 +54,13 @@ win_open(gx_device * dev)
/* Set parameters that were unknown before opening device */
/* Find out if the device supports color */
- /* We recognize 1, 4, 8, 24 bit/pixel devices */
+ /* We recognize 1, 4, 8, 16, 24 bit/pixel devices */
hdc = GetDC(NULL); /* get hdc for desktop */
depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
- if (depth > 8) {
+ if (depth > 16) {
wdev->BitsPerPixel = 24;
+ } else if (depth > 8) {
+ wdev->BitsPerPixel = 16;
} else if (depth >= 8) {
wdev->BitsPerPixel = 8;
} else if (depth >= 4) {
@@ -94,7 +97,7 @@ int
win_output_page(gx_device * dev, int copies, int flush)
{
(*pgsdll_callback) (GSDLL_PAGE, (unsigned char *)wdev, 0);
- return 0;
+ return gx_finish_output_page(dev, copies, flush);;
}
/* Close the win driver */
@@ -122,6 +125,28 @@ win_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g,
return (((unsigned long)b >> (gx_color_value_bits - 8)) << 16) +
(((unsigned long)g >> (gx_color_value_bits - 8)) << 8) +
(((unsigned long)r >> (gx_color_value_bits - 8)));
+ case 16:{
+ gx_color_index color = ((r >> (gx_color_value_bits - 5)) << 11) +
+ ((g >> (gx_color_value_bits - 6)) << 5) +
+ (b >> (gx_color_value_bits - 5));
+#if arch_is_big_endian
+ ushort color16 = (ushort)color;
+#else
+ ushort color16 = (ushort)((color << 8) | (color >> 8));
+#endif
+ return color16;
+ }
+ case 15:{
+ gx_color_index color = ((r >> (gx_color_value_bits - 5)) << 10) +
+ ((g >> (gx_color_value_bits - 5)) << 5) +
+ (b >> (gx_color_value_bits - 5));
+#if arch_is_big_endian
+ ushort color15 = (ushort)color;
+#else
+ ushort color15 = (ushort)((color << 8) | (color >> 8));
+#endif
+ return color15;
+ }
case 8:{
int i;
LPLOGPALETTE lpal = wdev->limgpalette;
@@ -204,6 +229,7 @@ win_map_color_rgb(gx_device * dev, gx_color_index color,
gx_color_value prgb[3])
{
gx_color_value one;
+ ushort value;
switch (wdev->BitsPerPixel) {
case 24:
@@ -212,6 +238,22 @@ win_map_color_rgb(gx_device * dev, gx_color_index color,
prgb[1] = ((color >> 8) & 255) * one;
prgb[2] = ((color >> 16) & 255) * one;
break;
+ case 16:
+ value = (color >> 11) & 0x1f;
+ 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);
+ break;
+ case 15:
+ value = (color >> 10) & 0x1f;
+ prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
+ value = (color >> 5) & 0x1f;
+ prgb[1] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
+ value = (color) & 0x1f;
+ prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
+ break;
case 8:
if (!dev->is_open)
return -1;
@@ -243,32 +285,6 @@ win_get_params(gx_device * dev, gs_param_list * plist)
}
/* Put parameters. */
-private int
-win_put_alpha_param(gs_param_list * plist, gs_param_name param_name, int *pa,
- bool alpha_ok)
-{
- int code = param_read_int(plist, param_name, pa);
-
- switch (code) {
- case 0:
- switch (*pa) {
- case 1:
- return 0;
- case 2:
- case 4:
- if (alpha_ok)
- return 0;
- default:
- code = gs_error_rangecheck;
- }
- default:
- param_signal_error(plist, param_name, code);
- case 1:
- ;
- }
- return code;
-}
-
/* Set window parameters -- size and resolution. */
/* We implement this ourselves so that we can do it without */
/* closing and opening the device. */
@@ -282,8 +298,6 @@ win_put_params(gx_device * dev, gs_param_list * plist)
int old_bpp = dev->color_info.depth;
int bpp = old_bpp;
byte *old_flags = wdev->mapped_color_flags;
- int atext = wdev->alpha_text, agraphics = wdev->alpha_graphics;
- bool alpha_ok;
/* Handle extra parameters */
@@ -308,12 +322,6 @@ win_put_params(gx_device * dev, gs_param_list * plist)
break;
}
- alpha_ok = wdev->color_info.depth >= 8;
- if ((code = win_put_alpha_param(plist, "TextAlphaBits", &wdev->alpha_text, alpha_ok)) < 0)
- ecode = code;
- if ((code = win_put_alpha_param(plist, "GraphicsAlphaBits", &wdev->alpha_graphics, alpha_ok)) < 0)
- ecode = code;
-
if (ecode >= 0) { /* Prevent gx_default_put_params from closing the device. */
dev->is_open = false;
ecode = gx_default_put_params(dev, plist);
@@ -326,8 +334,6 @@ win_put_params(gx_device * dev, gs_param_list * plist)
wdev->mapped_color_flags = old_flags;
if (bpp != old_bpp)
win_set_bits_per_pixel(wdev, old_bpp);
- wdev->alpha_text = atext;
- wdev->alpha_graphics = agraphics;
return ecode;
}
if (wdev->mapped_color_flags == 0 && old_flags != 0) { /* Release old mapped_color_flags. */
@@ -347,8 +353,6 @@ win_put_params(gx_device * dev, gs_param_list * plist)
dev->width = width;
dev->height = height;
win_set_bits_per_pixel(wdev, old_bpp);
- wdev->alpha_text = atext;
- wdev->alpha_graphics = agraphics;
(*wdev->alloc_bitmap) (wdev, dev);
return ccode;
}
@@ -356,13 +360,6 @@ win_put_params(gx_device * dev, gs_param_list * plist)
return 0;
}
-/* Get the number of alpha bits. */
-int
-win_get_alpha_bits(gx_device * dev, graphics_object_type type)
-{
- return (type == go_text ? wdev->alpha_text : wdev->alpha_graphics);
-}
-
/* ------ Internal routines ------ */
#undef wdev
@@ -427,6 +424,7 @@ private int
win_set_bits_per_pixel(gx_device_win * wdev, int bpp)
{
static const gx_device_color_info win_24bit_color = dci_color(24, 255, 255);
+ static const gx_device_color_info win_16bit_color = dci_color(16, 255, 255);
static const gx_device_color_info win_8bit_color = dci_color(8, 31, 4);
static const gx_device_color_info win_ega_color = dci_pc_4bit;
static const gx_device_color_info win_vga_color = dci_pc_4bit;
@@ -438,6 +436,11 @@ win_set_bits_per_pixel(gx_device_win * wdev, int bpp)
wdev->color_info = win_24bit_color;
wdev->nColors = -1;
break;
+ case 16:
+ case 15:
+ wdev->color_info = win_16bit_color;
+ wdev->nColors = -1;
+ break;
case 8:
/* use 64 static colors and 166 dynamic colors from 8 planes */
wdev->color_info = win_8bit_color;
diff --git a/gs/src/gdevmswn.h b/gs/src/gdevmswn.h
index a4e90f34f..d53fe1617 100644
--- a/gs/src/gdevmswn.h
+++ b/gs/src/gdevmswn.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -73,8 +73,6 @@ dev_proc_get_alpha_bits(win_get_alpha_bits);
#define gx_device_win_common\
int BitsPerPixel;\
int nColors;\
- int alpha_text;\
- int alpha_graphics;\
byte *mapped_color_flags;\
/* Implementation-specific procedures */\
win_proc_alloc_bitmap((*alloc_bitmap));\
diff --git a/gs/src/gdevmsxf.c b/gs/src/gdevmsxf.c
index 7827f0d70..ac28ffa71 100644
--- a/gs/src/gdevmsxf.c
+++ b/gs/src/gdevmsxf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -369,7 +369,7 @@ win_render_char(gx_xfont * xf, gx_xglyph xg, gx_device * dev,
return code;
w = bbox.q.x - bbox.p.x;
h = bbox.q.y - bbox.p.y;
- wbm = round_up(w, align_bitmap_mod * 8);
+ wbm = ROUND_UP(w, align_bitmap_mod * 8);
raster = wbm >> 3;
bits = gs_malloc(h, raster, "win_render_char");
if (bits == 0)
diff --git a/gs/src/gdevnfwd.c b/gs/src/gdevnfwd.c
index b8334f277..f12a9c9da 100644
--- a/gs/src/gdevnfwd.c
+++ b/gs/src/gdevnfwd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,28 @@
/* ---------------- Forwarding procedures ---------------- */
+/* Additional finalization for forwarding devices. */
+private void
+gx_device_forward_finalize(gx_device *dev)
+{
+ gx_device *target = ((gx_device_forward *)dev)->target;
+
+ rc_decrement(target, "gx_device_forward_finalize");
+}
+
+/* Set the target of a forwarding device. */
+void
+gx_device_set_target(gx_device_forward *fdev, gx_device *target)
+{
+ /*
+ * ****** HACK: if this device doesn't have special finalization yet,
+ * make it decrement the reference count of the target.
+ */
+ if (target && !fdev->finalize)
+ fdev->finalize = gx_device_forward_finalize;
+ rc_assign(fdev->target, target, "gx_device_set_target");
+}
+
/* 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. */
@@ -51,7 +73,7 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev)
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 get_alpha_bits (OBSOLETE) */
/* NOT copy_alpha */
fill_dev_proc(dev, get_band, gx_forward_get_band);
fill_dev_proc(dev, copy_rop, gx_forward_copy_rop);
@@ -97,7 +119,7 @@ gx_forward_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
if (tdev == 0)
gx_default_get_initial_matrix(dev, pmat);
else
- (*dev_proc(tdev, get_initial_matrix)) (tdev, pmat);
+ dev_proc(tdev, get_initial_matrix)(tdev, pmat);
}
int
@@ -107,7 +129,7 @@ gx_forward_sync_output(gx_device * dev)
gx_device *tdev = fdev->target;
return (tdev == 0 ? gx_default_sync_output(dev) :
- (*dev_proc(tdev, sync_output)) (tdev));
+ dev_proc(tdev, sync_output)(tdev));
}
int
@@ -117,7 +139,7 @@ gx_forward_output_page(gx_device * dev, int num_copies, int flush)
gx_device *tdev = fdev->target;
int code =
(tdev == 0 ? gx_default_output_page(dev, num_copies, flush) :
- (*dev_proc(tdev, output_page)) (tdev, num_copies, flush));
+ dev_proc(tdev, output_page)(tdev, num_copies, flush));
if (code >= 0 && tdev != 0)
dev->PageCount = tdev->PageCount;
@@ -132,7 +154,7 @@ gx_forward_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g,
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));
+ dev_proc(tdev, map_rgb_color)(tdev, r, g, b));
}
int
@@ -143,7 +165,7 @@ gx_forward_map_color_rgb(gx_device * dev, gx_color_index color,
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));
+ dev_proc(tdev, map_color_rgb)(tdev, color, prgb));
}
int
@@ -155,29 +177,27 @@ gx_forward_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
if (tdev == 0)
return_error(gs_error_Fatal);
- return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, w, h, color);
+ 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)
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_tile_rectangle) :
+ dev_proc(tdev, tile_rectangle));
- 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);
+ 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,
+ 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;
@@ -185,20 +205,21 @@ gx_forward_copy_mono(gx_device * dev, const byte * data,
if (tdev == 0)
return_error(gs_error_Fatal);
- return (*dev_proc(tdev, copy_mono))
+ 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)
+ 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))
+ return dev_proc(tdev, copy_color)
(tdev, data, dx, raster, id, x, y, w, h);
}
@@ -209,7 +230,7 @@ gx_forward_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
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));
+ dev_proc(tdev, get_bits)(tdev, y, data, actual_data));
}
int
@@ -219,7 +240,7 @@ gx_forward_get_params(gx_device * dev, gs_param_list * plist)
gx_device *tdev = fdev->target;
return (tdev == 0 ? gx_default_get_params(dev, plist) :
- (*dev_proc(tdev, get_params)) (tdev, plist));
+ dev_proc(tdev, get_params)(tdev, plist));
}
int
@@ -231,7 +252,7 @@ gx_forward_put_params(gx_device * dev, gs_param_list * plist)
if (tdev == 0)
return gx_default_put_params(dev, plist);
- code = (*dev_proc(tdev, put_params))(tdev, plist);
+ code = dev_proc(tdev, put_params)(tdev, plist);
if (code >= 0)
gx_device_decache_colors(dev);
return code;
@@ -245,7 +266,7 @@ gx_forward_map_cmyk_color(gx_device * dev, gx_color_value c, gx_color_value m,
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));
+ dev_proc(tdev, map_cmyk_color)(tdev, c, m, y, k));
}
const gx_xfont_procs *
@@ -255,7 +276,7 @@ gx_forward_get_xfont_procs(gx_device * dev)
gx_device *tdev = fdev->target;
return (tdev == 0 ? gx_default_get_xfont_procs(dev) :
- (*dev_proc(tdev, get_xfont_procs)) (tdev));
+ dev_proc(tdev, get_xfont_procs)(tdev));
}
gx_device *
@@ -265,19 +286,20 @@ gx_forward_get_xfont_device(gx_device * dev)
gx_device *tdev = fdev->target;
return (tdev == 0 ? gx_default_get_xfont_device(dev) :
- (*dev_proc(tdev, get_xfont_device)) (tdev));
+ 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_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));
+ dev_proc(tdev, map_rgb_alpha_color)(tdev, r, g, b, alpha));
}
gx_device *
@@ -289,22 +311,11 @@ gx_forward_get_page_device(gx_device * dev)
if (tdev == 0)
return gx_default_get_page_device(dev);
- pdev = (*dev_proc(tdev, get_page_device)) (tdev);
+ 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;
@@ -312,63 +323,57 @@ gx_forward_get_band(gx_device * dev, int y, int *band_start)
return (tdev == 0 ?
gx_default_get_band(dev, y, band_start) :
- (*dev_proc(tdev, get_band)) (tdev, 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,
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_copy_rop) :
+ dev_proc(tdev, copy_rop));
- 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);
+ 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)
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_fill_path) :
+ dev_proc(tdev, fill_path));
- 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);
+ 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)
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_stroke_path) :
+ dev_proc(tdev, stroke_path));
- 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);
+ return proc(tdev, pis, ppath, params, pdcolor, pcpath);
}
int
@@ -380,33 +385,29 @@ gx_forward_fill_mask(gx_device * dev,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_fill_mask((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_fill_mask) :
+ dev_proc(tdev, fill_mask));
- 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);
+ 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,
+ 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)
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_fill_trapezoid) :
+ dev_proc(tdev, fill_trapezoid));
- 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);
+ return proc(tdev, left, right, ybot, ytop, swap_axes, pdcolor, lop);
}
int
@@ -416,14 +417,11 @@ gx_forward_fill_parallelogram(gx_device * dev,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_fill_parallelogram((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_fill_parallelogram) :
+ dev_proc(tdev, fill_parallelogram));
- 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);
+ return proc(tdev, px, py, ax, ay, bx, by, pdcolor, lop);
}
int
@@ -433,14 +431,11 @@ gx_forward_fill_triangle(gx_device * dev,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_fill_triangle((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_fill_triangle) :
+ dev_proc(tdev, fill_triangle));
- 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);
+ return proc(tdev, px, py, ax, ay, bx, by, pdcolor, lop);
}
int
@@ -450,34 +445,29 @@ gx_forward_draw_thin_line(gx_device * dev,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_draw_thin_line((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_draw_thin_line) :
+ dev_proc(tdev, draw_thin_line));
- 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);
+ 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,
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_begin_image) :
+ dev_proc(tdev, begin_image));
- 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);
+ return proc(tdev, pis, pim, format, prect, pdcolor, pcpath,
+ memory, pinfo);
}
int
@@ -487,36 +477,31 @@ gx_forward_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_strip_tile_rectangle((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_strip_tile_rectangle) :
+ dev_proc(tdev, strip_tile_rectangle));
- 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);
+ 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,
+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,
+ 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)
+ 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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_strip_copy_rop) :
+ dev_proc(tdev, strip_copy_rop));
- 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);
+ return proc(tdev, sdata, sourcex, sraster, id, scolors,
+ textures, tcolors, x, y, width, height,
+ phase_x, phase_y, lop);
}
void
@@ -528,27 +513,27 @@ gx_forward_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
if (tdev == 0)
gx_default_get_clipping_box(dev, pbox);
else
- (*dev_proc(tdev, get_clipping_box)) (tdev, pbox);
+ 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_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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_begin_typed_image) :
+ dev_proc(tdev, begin_typed_image));
- 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);
+ return proc(tdev, pis, pmat, pim, prect, pdcolor, pcpath,
+ memory, pinfo);
}
int
@@ -557,14 +542,11 @@ gx_forward_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
{
gx_device_forward * const fdev = (gx_device_forward *)dev;
gx_device *tdev = fdev->target;
+ dev_proc_get_bits_rectangle((*proc)) =
+ (tdev == 0 ? (tdev = dev, gx_default_get_bits_rectangle) :
+ dev_proc(tdev, get_bits_rectangle));
- 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);
+ return proc(tdev, prect, params, unread);
}
int
@@ -575,7 +557,7 @@ gx_forward_map_color_rgb_alpha(gx_device * dev, gx_color_index color,
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));
+ dev_proc(tdev, map_color_rgb_alpha)(tdev, color, prgba));
}
int
@@ -585,26 +567,24 @@ gx_forward_get_hardware_params(gx_device * dev, gs_param_list * plist)
gx_device *tdev = fdev->target;
return (tdev == 0 ? gx_default_get_hardware_params(dev, plist) :
- (*dev_proc(tdev, get_hardware_params)) (tdev, 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_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)) =
+ (tdev == 0 ? (tdev = dev, gx_default_text_begin) :
+ dev_proc(tdev, text_begin));
- 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);
+ return proc(tdev, pis, text, font, path, pdcolor, pcpath,
+ memory, ppenum);
}
/* ---------------- The null device(s) ---------------- */
@@ -621,7 +601,6 @@ 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. */
@@ -648,7 +627,7 @@ private dev_proc_strip_copy_rop(null_strip_copy_rop);
gx_forward_get_xfont_device,\
gx_forward_map_rgb_alpha_color,\
get_page_device, /* differs */\
- gx_forward_get_alpha_bits,\
+ gx_default_get_alpha_bits,\
null_copy_alpha,\
gx_forward_get_band,\
null_copy_rop,\
@@ -673,16 +652,14 @@ private dev_proc_strip_copy_rop(null_strip_copy_rop);
gx_default_text_begin\
}
-const gx_device_null gs_null_device =
-{
+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 =
-{
+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 */ ),
@@ -696,8 +673,8 @@ null_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
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,
+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;
@@ -718,14 +695,14 @@ null_put_params(gx_device * dev, gs_param_list * plist)
*/
int code = gx_forward_put_params(dev, plist);
- if (code < 0 || (*dev_proc(dev, get_page_device))(dev) == dev)
+ 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,
+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;
@@ -750,7 +727,7 @@ null_fill_path(gx_device * dev, const gs_imager_state * pis,
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)
+ const gx_drawing_color * pdcolor, const gx_clip_path * pcpath)
{
return 0;
}
@@ -758,36 +735,41 @@ 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)
+ 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)
+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)
+ 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)
+ 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,
+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,
+ 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)
{
diff --git a/gs/src/gdevpbm.c b/gs/src/gdevpbm.c
index 4725f71b1..f8df447de 100644
--- a/gs/src/gdevpbm.c
+++ b/gs/src/gdevpbm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,7 +20,11 @@
/* Portable Bit/Gray/PixMap drivers */
#include "gdevprn.h"
#include "gscdefs.h"
+#include "gxgetbit.h"
#include "gxlum.h"
+#include "gdevmpla.h"
+#include "gdevplnx.h"
+#include "gdevppla.h"
/*
* Thanks are due to Jos Vos (jos@bull.nl) for an earlier P*M driver,
@@ -29,7 +33,7 @@
*/
/*
- * There are 6 (pairs of) drivers here, plus one less related one:
+ * There are 7 (families of) drivers here, plus one less related one:
* pbm[raw] - outputs PBM (black and white).
* pgm[raw] - outputs PGM (gray-scale).
* pgnm[raw] - outputs PBM if the page contains only black and white,
@@ -39,6 +43,7 @@
* otherwise PGM if the page contains only gray shades,
* otherwise PPM.
* pkm[raw] - computes internally in CMYK, outputs PPM (RGB).
+ * pksm[raw] - computes internally in CMYK, outputs 4 PBM pages.
* plan9bm - outputs Plan 9 bitmap format.
*/
@@ -47,11 +52,12 @@
* The code will work with any of the values in brackets, but the
* Ghostscript imager requires that depth be a power of 2 or be 24,
* so the actual allowed values are more limited.
- * pgm,pgnm: 1, 2, 4, 8, 16. [1-16]
- * pgmraw,pgnmraw: 1, 2, 4, 8. [1-8]
- * ppm,pnm: 4(3x1), 8(3x2), 16(3x5), 24(3x8), 32(3x10). [3-32]
- * ppmraw,pnmraw: 4(3x1), 8(3x2), 16(3x5), 24(3x8). [3-24]
+ * pgm, pgnm: 1, 2, 4, 8, 16. [1-16]
+ * pgmraw, pgnmraw: 1, 2, 4, 8. [1-8]
+ * ppm, pnm: 4(3x1), 8(3x2), 16(3x5), 24(3x8), 32(3x10). [3-32]
+ * ppmraw, pnmraw: 4(3x1), 8(3x2), 16(3x5), 24(3x8). [3-24]
* pkm, pkmraw: 4(4x1), 8(4x2), 16(4x4), 32(4x8). [4-32]
+ * pksm, pksmraw: ibid.
*/
/* Structure for P*M devices, which extend the generic printer device. */
@@ -66,16 +72,13 @@ struct gx_device_pbm_s {
byte is_raw; /* 1 if raw format, 0 if plain */
byte optimize; /* 1 if optimization OK, 0 if not */
byte uses_color; /* 0 if image is black and white, */
- /* 1 if gray (PGM or PPM only), */
- /* 2 or 3 if colored (PPM only) */
- int alpha_text; /* # of alpha bits for text (1,2,4) */
- int alpha_graphics; /* ditto for graphics (1,2,4) */
- dev_proc_copy_alpha((*save_copy_alpha));
+ /* 1 if gray (PGM or PPM only), */
+ /* 2 or 3 if colored (PPM only) */
+ bool UsePlanarBuffer; /* 0 if chunky buffer, 1 if planar */
+ dev_proc_copy_alpha((*save_copy_alpha));
};
typedef struct gx_device_pbm_s gx_device_pbm;
-#define bdev ((gx_device_pbm *)pdev)
-
/* ------ The device descriptors ------ */
/*
@@ -95,7 +98,7 @@ typedef struct gx_device_pbm_s gx_device_pbm;
{ 0 },\
is_raw,\
optimize,\
- 0, 1, 1, 0\
+ 0, 0, 0\
}
/* For all but PBM, we need our own color mapping and alpha procedures. */
@@ -105,8 +108,8 @@ private dev_proc_map_color_rgb(pgm_map_color_rgb);
private dev_proc_map_color_rgb(ppm_map_color_rgb);
private dev_proc_map_cmyk_color(pkm_map_cmyk_color);
private dev_proc_map_color_rgb(pkm_map_color_rgb);
+private dev_proc_get_params(ppm_get_params);
private dev_proc_put_params(ppm_put_params);
-private dev_proc_get_alpha_bits(ppm_get_alpha_bits);
private dev_proc_copy_alpha(pnm_copy_alpha);
/* We need to initialize uses_color when opening the device, */
@@ -119,27 +122,33 @@ private dev_proc_print_page(pbm_print_page);
private dev_proc_print_page(pgm_print_page);
private dev_proc_print_page(ppm_print_page);
private dev_proc_print_page(pkm_print_page);
+private dev_proc_print_page(psm_print_page);
/* The device procedures */
-private const gx_device_procs pbm_procs =
-prn_procs(gdev_prn_open, ppm_output_page, gdev_prn_close);
-
/* See gdevprn.h for the template for the following. */
-#define pgpm_procs(p_map_rgb_color, p_map_color_rgb, p_map_cmyk_color) {\
- ppm_open, NULL, NULL, ppm_output_page, gdev_prn_close,\
+#define pgpm_procs(p_open, p_get_params, p_map_rgb_color, p_map_color_rgb, p_map_cmyk_color) {\
+ p_open, NULL, NULL, ppm_output_page, gdev_prn_close,\
p_map_rgb_color, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\
- gdev_prn_get_params, ppm_put_params,\
- p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device,\
- ppm_get_alpha_bits\
+ p_get_params, ppm_put_params,\
+ p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device\
}
+private const gx_device_procs pbm_procs =
+ pgpm_procs(gdev_prn_open, gdev_prn_get_params,
+ gdev_prn_map_rgb_color, gdev_prn_map_color_rgb, NULL);
private const gx_device_procs pgm_procs =
-pgpm_procs(pgm_map_rgb_color, pgm_map_color_rgb, NULL);
+ pgpm_procs(ppm_open, gdev_prn_get_params,
+ pgm_map_rgb_color, pgm_map_color_rgb, NULL);
private const gx_device_procs ppm_procs =
-pgpm_procs(ppm_map_rgb_color, ppm_map_color_rgb, NULL);
+ pgpm_procs(ppm_open, ppm_get_params,
+ gx_default_rgb_map_rgb_color, ppm_map_color_rgb, NULL);
+private const gx_device_procs pnm_procs =
+ pgpm_procs(ppm_open, ppm_get_params,
+ ppm_map_rgb_color, ppm_map_color_rgb, NULL);
private const gx_device_procs pkm_procs =
-pgpm_procs(NULL, cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color);
+ pgpm_procs(ppm_open, ppm_get_params,
+ NULL, cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color);
/* The device descriptors themselves */
const gx_device_pbm gs_pbm_device =
@@ -167,10 +176,10 @@ const gx_device_pbm gs_ppmraw_device =
pbm_prn_device(ppm_procs, "ppmraw", '6', 1, 3, 24, 255, 255, 0,
X_DPI, Y_DPI, ppm_print_page);
const gx_device_pbm gs_pnm_device =
-pbm_prn_device(ppm_procs, "pnm", '3', 0, 3, 24, 255, 255, 1,
+pbm_prn_device(pnm_procs, "pnm", '3', 0, 3, 24, 255, 255, 1,
X_DPI, Y_DPI, ppm_print_page);
const gx_device_pbm gs_pnmraw_device =
-pbm_prn_device(ppm_procs, "pnmraw", '6', 1, 3, 24, 255, 255, 1,
+pbm_prn_device(pnm_procs, "pnmraw", '6', 1, 3, 24, 255, 255, 1,
X_DPI, Y_DPI, ppm_print_page);
const gx_device_pbm gs_pkm_device =
pbm_prn_device(pkm_procs, "pkm", '3', 0, 4, 4, 1, 1, 0,
@@ -178,6 +187,12 @@ pbm_prn_device(pkm_procs, "pkm", '3', 0, 4, 4, 1, 1, 0,
const gx_device_pbm gs_pkmraw_device =
pbm_prn_device(pkm_procs, "pkmraw", '6', 1, 4, 4, 1, 1, 0,
X_DPI, Y_DPI, pkm_print_page);
+const gx_device_pbm gs_pksm_device =
+pbm_prn_device(pkm_procs, "pksm", '1', 0, 4, 4, 1, 1, 0,
+ X_DPI, Y_DPI, psm_print_page);
+const gx_device_pbm gs_pksmraw_device =
+pbm_prn_device(pkm_procs, "pksmraw", '4', 1, 4, 4, 1, 1, 0,
+ X_DPI, Y_DPI, psm_print_page);
/* Plan 9 bitmaps default to 100 dpi. */
const gx_device_pbm gs_plan9bm_device =
@@ -190,6 +205,8 @@ pbm_prn_device(pbm_procs, "plan9bm", '9', 1, 1, 1, 1, 1, 1,
private void
ppm_set_dev_procs(gx_device * pdev)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
if (dev_proc(pdev, copy_alpha) != pnm_copy_alpha) {
bdev->save_copy_alpha = dev_proc(pdev, copy_alpha);
if (pdev->color_info.depth > 4)
@@ -206,10 +223,16 @@ ppm_set_dev_procs(gx_device * pdev)
}
}
+/*
+ * Define a special open procedure that changes create_buf_device to use
+ * a planar device.
+ */
+
private int
ppm_open(gx_device * pdev)
{
- int code = gdev_prn_open(pdev);
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+ int code = gdev_prn_open_planar(pdev, bdev->UsePlanarBuffer);
if (code < 0)
return code;
@@ -223,6 +246,7 @@ private int
ppm_output_page(gx_device * pdev, int num_copies, int flush)
{
int code = gdev_prn_output_page(pdev, num_copies, flush);
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
if (code < 0)
return code;
@@ -236,7 +260,8 @@ ppm_output_page(gx_device * pdev, int num_copies, int flush)
/* Map an RGB color to a PGM gray value. */
/* Keep track of whether the image is black-and-white or gray. */
private gx_color_index
-pgm_map_rgb_color(gx_device * pdev, ushort r, ushort g, ushort b)
+pgm_map_rgb_color(gx_device * pdev, gx_color_value r, gx_color_value g,
+ gx_color_value b)
{ /* We round the value rather than truncating it. */
gx_color_value gray =
((r * (ulong) lum_red_weight) +
@@ -245,14 +270,18 @@ pgm_map_rgb_color(gx_device * pdev, ushort r, ushort g, ushort b)
(lum_all_weights / 2)) / lum_all_weights
* pdev->color_info.max_gray / gx_max_color_value;
- if (!(gray == 0 || gray == pdev->color_info.max_gray))
+ if (!(gray == 0 || gray == pdev->color_info.max_gray)) {
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
bdev->uses_color = 1;
+ }
return gray;
}
/* Map a PGM gray value back to an RGB color. */
private int
-pgm_map_color_rgb(gx_device * dev, gx_color_index color, ushort prgb[3])
+pgm_map_color_rgb(gx_device * dev, gx_color_index color,
+ gx_color_value prgb[3])
{
gx_color_value gray =
color * gx_max_color_value / dev->color_info.max_gray;
@@ -266,25 +295,27 @@ pgm_map_color_rgb(gx_device * dev, gx_color_index color, ushort prgb[3])
/* Map an RGB color to a PPM color tuple. */
/* Keep track of whether the image is black-and-white, gray, or colored. */
private gx_color_index
-ppm_map_rgb_color(gx_device * pdev, ushort r, ushort g, ushort b)
+ppm_map_rgb_color(gx_device * pdev, gx_color_value r, gx_color_value g,
+ gx_color_value b)
{
- uint bitspercolor = pdev->color_info.depth / 3;
- ulong max_value = pdev->color_info.max_color;
- gx_color_value rc = r * max_value / gx_max_color_value;
- gx_color_value gc = g * max_value / gx_max_color_value;
- gx_color_value bc = b * max_value / gx_max_color_value;
-
- if (rc == gc && gc == bc) { /* black-and-white or gray */
- if (!(rc == 0 || rc == max_value))
- bdev->uses_color |= 1; /* gray */
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+ gx_color_index color = gx_default_rgb_map_rgb_color(pdev, r, g, b);
+ int bpc = pdev->color_info.depth / 3;
+ gx_color_index mask =
+ ((gx_color_index)1 << (pdev->color_info.depth - bpc)) - 1;
+
+ if (!(((color >> bpc) ^ color) & mask)) { /* gray shade */
+ if (color != 0 && (~color & mask))
+ bdev->uses_color |= 1;
} else /* color */
bdev->uses_color = 2;
- return ((((ulong) rc << bitspercolor) + gc) << bitspercolor) + bc;
+ return color;
}
/* Map a PPM color tuple back to an RGB color. */
private int
-ppm_map_color_rgb(gx_device * dev, gx_color_index color, ushort prgb[3])
+ppm_map_color_rgb(gx_device * dev, gx_color_index color,
+ gx_color_value prgb[3])
{
uint bitspercolor = dev->color_info.depth / 3;
uint colormask = (1 << bitspercolor) - 1;
@@ -301,7 +332,8 @@ ppm_map_color_rgb(gx_device * dev, gx_color_index color, ushort prgb[3])
/* Map a CMYK color to a pixel value. */
private gx_color_index
-pkm_map_cmyk_color(gx_device * pdev, ushort c, ushort m, ushort y, ushort k)
+pkm_map_cmyk_color(gx_device * pdev, gx_color_value c, gx_color_value m,
+ gx_color_value y, gx_color_value k)
{
uint bpc = pdev->color_info.depth >> 2;
uint max_value = pdev->color_info.max_color;
@@ -339,44 +371,25 @@ pkm_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value rgb[3])
return 0;
}
-/* ------ Alpha capability ------ */
+/* Augment get/put_params to add UsePlanarBuffer */
-/* Put parameters. */
private int
-ppm_put_alpha_param(gs_param_list * plist, gs_param_name param_name, int *pa,
- bool alpha_ok)
+ppm_get_params(gx_device * pdev, gs_param_list * plist)
{
- int code = param_read_int(plist, param_name, pa);
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
- switch (code) {
- case 0:
- switch (*pa) {
- case 1:
- return 0;
- case 2:
- case 4:
- if (alpha_ok)
- return 0;
- default:
- code = gs_error_rangecheck;
- }
- default:
- param_signal_error(plist, param_name, code);
- case 1:
- ;
- }
- return code;
+ return gdev_prn_get_params_planar(pdev, plist, &bdev->UsePlanarBuffer);
}
+
private int
ppm_put_params(gx_device * pdev, gs_param_list * plist)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
gx_device_color_info save_info;
int ncomps = pdev->color_info.num_components;
int bpc = pdev->color_info.depth / ncomps;
int ecode = 0;
int code;
- int atext = bdev->alpha_text, agraphics = bdev->alpha_graphics;
- bool alpha_ok;
long v;
const char *vname;
@@ -418,29 +431,14 @@ ppm_put_params(gx_device * pdev, gs_param_list * plist)
pdev->color_info.dither_colors = (int)v) - 1;
}
}
- alpha_ok = bpc >= 5;
- if ((code = ppm_put_alpha_param(plist, "TextAlphaBits", &bdev->alpha_text, alpha_ok)) < 0)
- ecode = code;
- if ((code = ppm_put_alpha_param(plist, "GraphicsAlphaBits", &bdev->alpha_graphics, alpha_ok)) < 0)
- ecode = code;
if ((code = ecode) < 0 ||
- (code = gdev_prn_put_params(pdev, plist)) < 0
- ) {
- bdev->alpha_text = atext;
- bdev->alpha_graphics = agraphics;
+ (code = gdev_prn_put_params_planar(pdev, plist, &bdev->UsePlanarBuffer)) < 0
+ )
pdev->color_info = save_info;
- }
ppm_set_dev_procs(pdev);
return code;
}
-/* Get the number of alpha bits. */
-private int
-ppm_get_alpha_bits(gx_device * pdev, graphics_object_type type)
-{
- return (type == go_text ? bdev->alpha_text : bdev->alpha_graphics);
-}
-
/* Copy an alpha map, noting whether we may generate some non-black/white */
/* colors through blending. */
private int
@@ -448,6 +446,8 @@ pnm_copy_alpha(gx_device * pdev, 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)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
if (pdev->color_info.depth < 24 ||
(color >> 8) == (color & 0xffff)
)
@@ -465,8 +465,9 @@ private int
pbm_print_page_loop(gx_device_printer * pdev, char magic, FILE * pstream,
int (*row_proc) (P4(gx_device_printer *, byte *, int, FILE *)))
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
uint raster = gdev_prn_raster(pdev);
- byte *data = (byte *) gs_malloc(raster, 1, "pbm_begin_page");
+ byte *data = (byte *) gs_malloc(raster, 1, "pbm_print_page_loop");
int lnum = 0;
int code = 0;
@@ -514,6 +515,8 @@ private int
pbm_print_row(gx_device_printer * pdev, byte * data, int depth,
FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
if (bdev->is_raw)
fwrite(data, 1, (pdev->width + 7) >> 3, pstream);
else {
@@ -533,6 +536,8 @@ pbm_print_row(gx_device_printer * pdev, byte * data, int depth,
private int
pbm_print_page(gx_device_printer * pdev, FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
return pbm_print_page_loop(pdev, bdev->magic, pstream, pbm_print_row);
}
@@ -541,14 +546,24 @@ private int
pgm_print_row(gx_device_printer * pdev, byte * data, int depth,
FILE * pstream)
{ /* Note that bpp <= 8 for raw format, bpp <= 16 for plain. */
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
uint mask = (1 << depth) - 1;
+ /*
+ * If we're writing planes for a CMYK device, we have 0 = white,
+ * mask = black, which is the opposite of the pgm convention.
+ */
+ uint invert = (pdev->color_info.num_components == 4 ? mask : 0);
byte *bp;
uint x;
int shift;
- if (bdev->is_raw && depth == 8)
- fwrite(data, 1, pdev->width, pstream);
- else
+ if (bdev->is_raw && depth == 8) {
+ if (invert) {
+ for (bp = data, x = 0; x < pdev->width; bp++, x++)
+ putc((byte)~*bp, pstream);
+ } else
+ fwrite(data, 1, pdev->width, pstream);
+ } else
for (bp = data, x = 0, shift = 8 - depth; x < pdev->width;) {
uint pixel;
@@ -561,6 +576,7 @@ pgm_print_row(gx_device_printer * pdev, byte * data, int depth,
bp++, shift += 8;
}
++x;
+ pixel ^= invert;
if (bdev->is_raw)
putc(pixel, pstream);
else
@@ -616,6 +632,8 @@ pxm_pbm_print_row(gx_device_printer * pdev, byte * data, int depth,
private int
pgm_print_page(gx_device_printer * pdev, FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
return (bdev->uses_color == 0 && bdev->optimize ?
pbm_print_page_loop(pdev, bdev->magic - 1, pstream,
pxm_pbm_print_row) :
@@ -630,6 +648,7 @@ ppgm_print_row(gx_device_printer * pdev, byte * data, int depth,
{ /* If color=false, write only one value per pixel; */
/* if color=true, write 3 values per pixel. */
/* Note that depth <= 24 for raw format, depth <= 32 for plain. */
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
uint bpe = depth / 3; /* bits per r/g/b element */
uint mask = (1 << bpe) - 1;
byte *bp;
@@ -704,6 +723,8 @@ ppm_pgm_print_row(gx_device_printer * pdev, byte * data, int depth,
private int
ppm_print_page(gx_device_printer * pdev, FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
return (bdev->uses_color >= 2 || !bdev->optimize ?
pbm_print_page_loop(pdev, bdev->magic, pstream,
ppm_print_row) :
@@ -721,6 +742,7 @@ private int
pkm_print_row_4(gx_device_printer * pdev, byte * data, int depth,
FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
byte *bp;
uint x;
byte rv[16], gv[16], bv[16], i;
@@ -779,6 +801,7 @@ private int
pkm_print_row(gx_device_printer * pdev, byte * data, int depth,
FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
byte *bp;
uint x;
ulong max_value = pdev->color_info.max_color;
@@ -825,8 +848,103 @@ pkm_print_row(gx_device_printer * pdev, byte * data, int depth,
private int
pkm_print_page(gx_device_printer * pdev, FILE * pstream)
{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+
return pbm_print_page_loop(pdev, bdev->magic, pstream,
(pdev->color_info.depth < 8 ?
pkm_print_row_4 :
pkm_print_row));
}
+
+/* Print individual separations on a single file. */
+private int
+psm_print_page(gx_device_printer * pdev, FILE * pstream)
+{
+ gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
+ /*
+ * Allocate a large enough buffer for full pixels, on the theory that we
+ * don't know how many bits will be allocated to each component. (This
+ * is for didactic purposes only: we know perfectly well that each
+ * component will have 1/N of the bits.)
+ */
+ uint max_raster = bitmap_raster(pdev->width * pdev->color_info.depth);
+ byte *data = (byte *)gs_malloc(max_raster, 1, "pksm_print_page");
+ int code = 0;
+ int plane;
+
+ if (data == 0)
+ return_error(gs_error_VMerror);
+ for (plane = 0; plane < pdev->color_info.num_components; ++plane) {
+ int lnum, band_end;
+ /*
+ * The following initialization is unnecessary: lnum == band_end on
+ * the first pass through the loop below, so marked will always be
+ * set before it is used. We initialize marked solely to suppress
+ * bogus warning messages from certain compilers.
+ */
+ gx_color_index marked = 0;
+ gx_render_plane_t render_plane;
+ int plane_depth;
+ int plane_shift;
+ gx_color_index plane_mask;
+ int raster;
+
+ gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
+ plane_depth = render_plane.depth;
+ plane_shift = render_plane.shift;
+ plane_mask = (1 << plane_depth) - 1;
+ raster = bitmap_raster(pdev->width * plane_depth);
+ fprintf(pstream, "P%c\n", bdev->magic + (plane_depth > 1));
+ if (bdev->comment[0])
+ fprintf(pstream, "# %s\n", bdev->comment);
+ else
+ fprintf(pstream, "# Image generated by %s (device=%s)\n",
+ gs_product, pdev->dname);
+ fprintf(pstream, "%d %d\n", pdev->width, pdev->height);
+ if (plane_depth > 1)
+ fprintf(pstream, "%d\n", pdev->color_info.max_gray);
+ for (lnum = band_end = 0; lnum < pdev->height; lnum++) {
+ byte *row;
+
+ if (lnum == band_end) {
+ gx_colors_used_t colors_used;
+ int band_start;
+ int band_height =
+ gdev_prn_colors_used((gx_device *)pdev, lnum, 1,
+ &colors_used, &band_start);
+
+ band_end = band_start + band_height;
+ marked = colors_used.or & (plane_mask << plane_shift);
+ if (!marked)
+ memset(data, 0, raster);
+#ifdef DEBUG
+ if (plane == 0)
+ if_debug4(':',
+ "[:]%4d - %4d mask = 0x%lx, slow_rop = %d\n",
+ lnum, band_end - 1, (ulong)colors_used.or,
+ colors_used.slow_rop);
+#endif
+ }
+ if (marked) {
+ gx_render_plane_t render_plane;
+ uint actual_raster;
+
+ render_plane.index = plane;
+ code = gdev_prn_get_lines(pdev, lnum, 1, data, raster,
+ &row, &actual_raster,
+ &render_plane);
+ if (code < 0)
+ break;
+ } else
+ row = data;
+ code =
+ (plane_depth == 1 ?
+ pbm_print_row(pdev, row, plane_depth, pstream) :
+ pgm_print_row(pdev, row, plane_depth, pstream));
+ if (code < 0)
+ break;
+ }
+ }
+ gs_free((char *)data, max_raster, 1, "pksm_print_page");
+ return (code < 0 ? code : 0);
+}
diff --git a/gs/src/gdevpcfb.c b/gs/src/gdevpcfb.c
index daad7ea38..5e4afbedf 100644
--- a/gs/src/gdevpcfb.c
+++ b/gs/src/gdevpcfb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,6 +26,11 @@
#include "gxdevice.h"
#include "gdevpccm.h"
#include "gdevpcfb.h"
+
+/* We may compile this in a non-segmented environment.... */
+#ifndef _ss
+#define _ss
+#endif
/* Macro for casting gx_device argument */
#define fb_dev ((gx_device_ega *)dev)
@@ -33,10 +38,8 @@
/* Procedure record */
private dev_proc_map_rgb_color(ega0_map_rgb_color);
private dev_proc_map_rgb_color(ega1_map_rgb_color);
-
#define ega2_map_rgb_color pc_4bit_map_rgb_color
private dev_proc_map_color_rgb(ega01_map_color_rgb);
-
#define ega2_map_color_rgb pc_4bit_map_color_rgb
#if ega_bits_of_color == 0
# define ega_map_rgb_color ega0_map_rgb_color
@@ -230,7 +233,6 @@ typedef rop_params _ss *rop_ptr;
#if USE_ASM
void memsetcol(P1(rop_ptr)); /* dest, draster, height, data */
-
#else
#define memsetcol cmemsetcol
private void
@@ -251,7 +253,6 @@ cmemsetcol(rop_ptr rop)
#if USE_ASM
void memsetrect(P1(rop_ptr)); /* dest, draster, width, height, data */
-
#else
#define memsetrect cmemsetrect
private void
@@ -293,7 +294,6 @@ cmemsetrect(rop_ptr rop)
#if USE_ASM
void memrwcol(P1(rop_ptr)); /* dest, draster, src, sraster, height, shift, invert */
-
# define memrwcol0(rop) memrwcol(rop) /* same except shift = 0 */
#else
# define memrwcol cmemrwcol
@@ -335,7 +335,6 @@ cmemrwcol0(rop_ptr rop)
#if USE_ASM
void memrwcol2(P1(rop_ptr)); /* dest, draster, src, sraster, height, shift, invert */
-
#else
#define memrwcol2 cmemrwcol2
private void
@@ -358,8 +357,8 @@ cmemrwcol2(rop_ptr rop)
/* Forward definitions */
int ega_write_dot(P4(gx_device *, int, int, gx_color_index));
-private void near fill_rectangle(P4(rop_ptr, int, int, int));
-private void near fill_row_only(P4(byte *, int, int, int));
+private void fill_rectangle(P4(rop_ptr, int, int, int));
+private void fill_row_only(P4(byte *, int, int, int));
/* Clean up after writing */
#define dot_end()\
@@ -843,7 +842,7 @@ static const byte rmask_tab[9] =
/* Fill a rectangle specified by pointer into frame buffer, */
/* starting bit within byte, width, and height. */
/* Smashes rop->dest. */
-private void near
+private void
fill_rectangle(register rop_ptr rop, int bit, int w, int color)
/* rop: dest, draster, height */
{
@@ -880,7 +879,7 @@ fill_rectangle(register rop_ptr rop, int bit, int w, int color)
/* Fill a single row specified by pointer into frame buffer, */
/* starting bit within byte, and width; clean up afterwards. */
#define r_m_w(ptr) (*(ptr))++ /* read & write, data irrelevant */
-private void near
+private void
fill_row_only(byte * dest, int bit, int w, int color)
/* rop: dest */
{
diff --git a/gs/src/gdevpcl.c b/gs/src/gdevpcl.c
index dd4cc321d..80f7be869 100644
--- a/gs/src/gdevpcl.c
+++ b/gs/src/gdevpcl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -83,7 +83,8 @@ gdev_pcl_3bit_map_color_rgb(gx_device * dev, gx_color_index color,
* We will miss a few blocks of identical bytes; tant pis.
*/
int
-gdev_pcl_mode2compress(const word * row, const word * end_row, byte * compressed)
+gdev_pcl_mode2compress_padded(const word * row, const word * end_row,
+ byte * compressed, bool pad)
{
register const word *exam = row; /* word being examined in the row to compress */
register byte *cptr = compressed; /* output pointer into compressed bytes */
@@ -103,8 +104,9 @@ gdev_pcl_mode2compress(const word * row, const word * end_row, byte * compressed
/* Find out how long the run is */
end_dis = (const byte *)exam;
- if (exam == end_row) { /* no run *//* See if any of the last 3 "dissimilar" bytes are 0. */
- if (end_dis > compr && end_dis[-1] == 0) {
+ if (exam == end_row) { /* no run */
+ /* See if any of the last 3 "dissimilar" bytes are 0. */
+ if (!pad && end_dis > compr && end_dis[-1] == 0) {
if (end_dis[-2] != 0)
end_dis--;
else if (end_dis[-3] != 0)
@@ -180,6 +182,12 @@ gdev_pcl_mode2compress(const word * row, const word * end_row, byte * compressed
}
return (cptr - compressed);
}
+int
+gdev_pcl_mode2compress(const word * row, const word * end_row,
+ byte * compressed)
+{
+ return gdev_pcl_mode2compress_padded(row, end_row, compressed, false);
+}
/*
* Mode 3 compression routine for the HP LaserJet III family.
@@ -235,3 +243,138 @@ gdev_pcl_mode3compress(int bytecount, const byte * current, byte * previous, byt
}
return out - compressed;
}
+
+/*
+ * Mode 9 2D compression for the HP DeskJets . This mode can give
+ * very good compression ratios, especially if there are areas of flat
+ * colour (or blank areas), and so is 'highly recommended' for colour
+ * printing in particular because of the very large amounts of data which
+ * can be generated
+ */
+int
+gdev_pcl_mode9compress(int bytecount, const byte *current,
+ const byte *previous, byte *compressed)
+{
+ register const byte *cur = current;
+ register const byte *prev = previous;
+ register byte *out = compressed;
+ const byte *end = current + bytecount;
+
+ while (cur < end) { /* Detect a run of unchanged bytes. */
+ const byte *run = cur;
+ register const byte *diff;
+ int offset;
+
+ while (cur < end && *cur == *prev) {
+ cur++, prev++;
+ }
+ if (cur == end)
+ break; /* rest of row is unchanged */
+ /* Detect a run of changed bytes. */
+ /* We know that *cur != *prev. */
+ diff = cur;
+ do {
+ prev++;
+ cur++;
+ }
+ while (cur < end && *cur != *prev);
+ /* Now [run..diff) are unchanged, and */
+ /* [diff..cur) are changed. */
+ offset = diff - run;
+ {
+ const byte *stop_test = cur - 4;
+ int dissimilar, similar;
+
+ while (diff < cur) {
+ const byte *compr = diff;
+ const byte *next; /* end of run */
+ byte value = 0;
+
+ while (diff <= stop_test &&
+ ((value = *diff) != diff[1] ||
+ value != diff[2] ||
+ value != diff[3]))
+ diff++;
+
+ /* Find out how long the run is */
+ if (diff > stop_test) /* no run */
+ next = diff = cur;
+ else {
+ next = diff + 4;
+ while (next < cur && *next == value)
+ next++;
+ }
+
+#define MAXOFFSETU 15
+#define MAXCOUNTU 7
+ /* output 'dissimilar' bytes, uncompressed */
+ if ((dissimilar = diff - compr)) {
+ int temp, i;
+
+ if ((temp = --dissimilar) > MAXCOUNTU)
+ temp = MAXCOUNTU;
+ if (offset < MAXOFFSETU)
+ *out++ = (offset << 3) | (byte) temp;
+ else {
+ *out++ = (MAXOFFSETU << 3) | (byte) temp;
+ offset -= MAXOFFSETU;
+ while (offset >= 255) {
+ *out++ = 255;
+ offset -= 255;
+ }
+ *out++ = offset;
+ }
+ if (temp == MAXCOUNTU) {
+ temp = dissimilar - MAXCOUNTU;
+ while (temp >= 255) {
+ *out++ = 255;
+ temp -= 255;
+ }
+ *out++ = (byte) temp;
+ }
+ for (i = 0; i <= dissimilar; i++)
+ *out++ = *compr++;
+ offset = 0;
+ } /* end uncompressed */
+#undef MAXOFFSETU
+#undef MAXCOUNTU
+
+#define MAXOFFSETC 3
+#define MAXCOUNTC 31
+ /* output 'similar' bytes, run-length encoded */
+ if ((similar = next - diff)) {
+ int temp;
+
+ if ((temp = (similar -= 2)) > MAXCOUNTC)
+ temp = MAXCOUNTC;
+ if (offset < MAXOFFSETC)
+ *out++ = 0x80 | (offset << 5) | (byte) temp;
+ else {
+ *out++ = 0x80 | (MAXOFFSETC << 5) | (byte) temp;
+ offset -= MAXOFFSETC;
+ while (offset >= 255) {
+ *out++ = 255;
+ offset -= 255;
+ }
+ *out++ = offset;
+ }
+ if (temp == MAXCOUNTC) {
+ temp = similar - MAXCOUNTC;
+ while (temp >= 255) {
+ *out++ = 255;
+ temp -= 255;
+ }
+ *out++ = (byte) temp;
+ }
+ *out++ = value;
+ offset = 0;
+ } /* end compressed */
+#undef MAXOFFSETC
+#undef MAXCOUNTC
+
+ diff = next;
+ }
+ }
+ }
+ return out - compressed;
+}
diff --git a/gs/src/gdevpcl.h b/gs/src/gdevpcl.h
index a81b5710c..52c8bb716 100644
--- a/gs/src/gdevpcl.h
+++ b/gs/src/gdevpcl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,7 +40,10 @@ 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));
+int
+ gdev_pcl_mode2compress(P3(const word * row, const word * end_row, byte * compressed)),
+ gdev_pcl_mode2compress_padded(P4(const word * row, const word * end_row, byte * compressed, bool pad)),
+ gdev_pcl_mode3compress(P4(int bytecount, const byte * current, byte * previous, byte * compressed)),
+ gdev_pcl_mode9compress(P4(int bytecount, const byte * current, const byte * previous, byte * compressed));
#endif /* gdevpcl_INCLUDED */
diff --git a/gs/src/gdevpcx.c b/gs/src/gdevpcx.c
index 99fccee41..6c8f1cbc6 100644
--- a/gs/src/gdevpcx.c
+++ b/gs/src/gdevpcx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -321,7 +321,7 @@ pcx_write_page(gx_device_printer * pdev, FILE * file, pcx_header * phdr,
bool planar)
{
int raster = gdev_prn_raster(pdev);
- uint rsize = round_up((pdev->width * phdr->bpp + 7) >> 3, 2); /* PCX format requires even */
+ uint rsize = ROUND_UP((pdev->width * phdr->bpp + 7) >> 3, 2); /* PCX format requires even */
int height = pdev->height;
int depth = pdev->color_info.depth;
uint lsize = raster + rsize;
diff --git a/gs/src/gdevpdf.c b/gs/src/gdevpdf.c
index 3347c3b4f..90342c3e3 100644
--- a/gs/src/gdevpdf.c
+++ b/gs/src/gdevpdf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -151,6 +151,7 @@ extern dev_proc_fill_path(gdev_pdf_fill_path); /* in gdevpdfd.c */
extern dev_proc_stroke_path(gdev_pdf_stroke_path); /* in gdevpdfd.c */
extern dev_proc_fill_mask(gdev_pdf_fill_mask); /* in gdevpdfi.c */
extern dev_proc_begin_image(gdev_pdf_begin_image); /* in gdevpdfi.c */
+extern dev_proc_strip_tile_rectangle(gdev_pdf_strip_tile_rectangle); /* in gdevpdfi.c */
#ifndef X_DPI
# define X_DPI 720
@@ -198,7 +199,8 @@ const gx_device_pdf gs_pdfwrite_device =
NULL, /* draw_thin_line */
gdev_pdf_begin_image,
NULL, /* image_data */
- NULL /* end_image */
+ NULL, /* end_image */
+ gdev_pdf_strip_tile_rectangle
},
psdf_initial_values(psdf_version_level2, 0 /*false */ ), /* (!ASCII85EncodePages) */
1.2, /* CompatibilityLevel */
@@ -236,6 +238,7 @@ const gx_device_pdf gs_pdfwrite_device =
{
{
{0}}}, /* resources */
+ 0 /*false*/, /* have_patterns */
0, /* annots */
0, /* last_resource */
{0, 0}, /* catalog_string */
@@ -740,20 +743,24 @@ pdf_begin_aside(gx_device_pdf * pdev, pdf_resource ** plist,
/* Begin a resource of a given type. */
int
-pdf_begin_resource(gx_device_pdf * pdev, pdf_resource_type type, gs_id rid,
- pdf_resource ** ppres)
+pdf_begin_resource_body(gx_device_pdf * pdev, pdf_resource_type type,
+ gs_id rid, pdf_resource ** ppres)
{
- int code = pdf_begin_aside(pdev,
+ return pdf_begin_aside(pdev,
&pdev->resources[type].chains[gs_id_hash(rid) % num_resource_chains],
resource_structs[type], ppres);
+}
+int
+pdf_begin_resource(gx_device_pdf * pdev, pdf_resource_type type, gs_id rid,
+ pdf_resource ** ppres)
+{
+ int code = pdf_begin_resource_body(pdev, type, rid, ppres);
- if (code < 0)
- return code;
- if (resource_names[type] != 0) {
+ if (code >= 0 && resource_names[type] != 0) {
stream *s = pdev->strm;
- pprints1(s, "<< /Type /%s", resource_names[type]);
- pprintld1(s, " /Name /R%ld", (*ppres)->id);
+ pprints1(s, "<</Type/%s", resource_names[type]);
+ pprintld1(s, "/Name/R%ld", (*ppres)->id);
}
return code;
}
@@ -808,6 +815,7 @@ pdf_reset_page(gx_device_pdf * pdev, bool first_page)
for (j = 0; j < num_resource_chains; ++j)
pdev->resources[i].chains[j] = 0;
}
+ pdev->cs_Pattern = 0; /* simplest to create one for each page */
pdev->page_string.data = 0;
{
static const pdf_text_state text_default =
diff --git a/gs/src/gdevpdfd.c b/gs/src/gdevpdfd.c
index 3a4f614d0..5f55d406d 100644
--- a/gs/src/gdevpdfd.c
+++ b/gs/src/gdevpdfd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -54,107 +54,39 @@ gdev_pdf_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
/* ---------------- Path drawing ---------------- */
-/* ------ Utilities ------ */
-
-/*
- * Put a segment of an enumerated path on the output file.
- * pe_op is assumed to be valid.
- */
+/* ------ Vector device implementation ------ */
private int
-pdf_put_path_segment(gx_device_pdf * pdev, int pe_op, gs_fixed_point vs[3],
- const gs_matrix * pmat)
+pdf_endpath(gx_device_vector * vdev, gx_path_type_t type)
{
- stream *s = pdev->strm;
- const char *format;
- gs_point vp[3];
-
- switch (pe_op) {
- case gs_pe_moveto:
- format = "%g %g m\n";
- goto do1;
- case gs_pe_lineto:
- format = "%g %g l\n";
- do1:vp[0].x = fixed2float(vs[0].x), vp[0].y = fixed2float(vs[0].y);
- if (pmat)
- gs_point_transform_inverse(vp[0].x, vp[0].y, pmat, &vp[0]);
- pprintg2(s, format, vp[0].x, vp[0].y);
- break;
- case gs_pe_curveto:
- vp[0].x = fixed2float(vs[0].x), vp[0].y = fixed2float(vs[0].y);
- vp[1].x = fixed2float(vs[1].x), vp[1].y = fixed2float(vs[1].y);
- vp[2].x = fixed2float(vs[2].x), vp[2].y = fixed2float(vs[2].y);
- if (pmat) {
- gs_point_transform_inverse(vp[0].x, vp[0].y, pmat, &vp[0]);
- gs_point_transform_inverse(vp[1].x, vp[1].y, pmat, &vp[1]);
- gs_point_transform_inverse(vp[2].x, vp[2].y, pmat, &vp[2]);
- }
- pprintg6(s, "%g %g %g %g %g %g c\n",
- vp[0].x, vp[0].y, vp[1].x, vp[1].y, vp[2].x, vp[2].y);
- break;
- case gs_pe_closepath:
- pputs(s, "h\n");
- break;
- default: /* can't happen */
- return -1;
- }
- return 0;
+ return 0; /* always handled by caller */
}
-
-/* Put a path on the output file. If do_close is false and the last */
-/* path component is a closepath, omit it and return 1. */
-private int
-pdf_put_path(gx_device_pdf * pdev, const gx_path * ppath, bool do_close,
- const gs_matrix * pmat)
+private const gx_device_vector_procs pdf_vector_procs =
{
- stream *s = pdev->strm;
- gs_fixed_rect rbox;
- gx_path_rectangular_type rtype = gx_path_is_rectangular(ppath, &rbox);
- gs_path_enum cenum;
-
- /*
- * If do_close is false (fill), we recognize all rectangles;
- * if do_close is true (stroke), we only recognize closed
- * rectangles.
- */
- if (rtype != prt_none &&
- !(do_close && rtype == prt_open) &&
- (pmat == 0 || is_xxyy(pmat) || is_xyyx(pmat))
- ) {
- gs_point p, q;
+ /* Page management */
+ NULL,
+ /* Imager state */
+ psdf_setlinewidth,
+ psdf_setlinecap,
+ psdf_setlinejoin,
+ psdf_setmiterlimit,
+ psdf_setdash,
+ psdf_setflat,
+ psdf_setlogop,
+ /* Other state */
+ psdf_setfillcolor,
+ psdf_setstrokecolor,
+ /* Paths */
+ psdf_dopath,
+ psdf_dorect,
+ psdf_beginpath,
+ psdf_moveto,
+ psdf_lineto,
+ psdf_curveto,
+ psdf_closepath,
+ pdf_endpath
+};
- p.x = fixed2float(rbox.p.x), p.y = fixed2float(rbox.p.y);
- q.x = fixed2float(rbox.q.x), q.y = fixed2float(rbox.q.y);
- if (pmat) {
- gs_point_transform_inverse(p.x, p.y, pmat, &p);
- gs_point_transform_inverse(q.x, q.y, pmat, &q);
- }
- pprintg4(s, "%g %g %g %g re\n",
- p.x, p.y, q.x - p.x, q.y - p.y);
- return 0;
- }
- gx_path_enum_init(&cenum, ppath);
- for (;;) {
- gs_fixed_point vs[3];
- int pe_op = gx_path_enum_next(&cenum, vs);
-
- sw:switch (pe_op) {
- case 0: /* done */
- return 0;
- case gs_pe_closepath:
- if (!do_close) {
- pe_op = gx_path_enum_next(&cenum, vs);
- if (pe_op != 0) {
- pputs(s, "h\n");
- goto sw;
- }
- return 1;
- }
- /* falls through */
- default:
- pdf_put_path_segment(pdev, pe_op, vs, pmat);
- }
- }
-}
+/* ------ Utilities ------ */
/* Test whether we will need to put the clipping path. */
bool
@@ -178,6 +110,7 @@ pdf_put_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
{
stream *s = pdev->strm;
+ pdev->vec_procs = &pdf_vector_procs;
if (pcpath == NULL) {
if (pdev->clip_path_id == pdev->no_clip_path_id)
return 0;
@@ -195,11 +128,14 @@ pdf_put_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
pputs(s, "Q\nq\n");
pdev->clip_path_id = pdev->no_clip_path_id;
} else {
+ gdev_vector_dopath_state_t state;
gs_cpath_enum cenum;
gs_fixed_point vs[3];
int pe_op;
- pputs(s, "Q\nq\nW\n");
+ pprints1(s, "Q\nq\n%s\n", (pcpath->rule <= 0 ? "W" : "W*"));
+ gdev_vector_dopath_init(&state, (gx_device_vector *)pdev,
+ gx_path_type_fill, NULL);
/*
* We have to break 'const' here because the clip path
* enumeration logic uses some internal mark bits.
@@ -208,7 +144,7 @@ pdf_put_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
*/
gx_cpath_enum_init(&cenum, (gx_clip_path *) pcpath);
while ((pe_op = gx_cpath_enum_next(&cenum, vs)) > 0)
- pdf_put_path_segment(pdev, pe_op, vs, NULL);
+ gdev_vector_dopath_segment(&state, pe_op, vs);
pputs(s, "n\n");
if (pe_op < 0)
return pe_op;
@@ -232,7 +168,6 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
{
gx_device_pdf *pdev = (gx_device_pdf *) dev;
int code;
-
/*
* HACK: we fill an empty path in order to set the clipping path
* and the color for writing text. If it weren't for this, we
@@ -243,6 +178,7 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
*/
bool have_path;
+ pdev->vec_procs = &pdf_vector_procs;
/*
* Check for an empty clipping path.
*/
@@ -279,24 +215,13 @@ gdev_pdf_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath
pprintg1(s, "%g i\n", params->flatness);
pdev->flatness = params->flatness;
}
- pdf_put_path(pdev, ppath, false, NULL);
+ gdev_vector_dopath((gx_device_vector *)pdev, ppath,
+ gx_path_type_fill, NULL);
pputs(s, (params->rule < 0 ? "f\n" : "f*\n"));
}
return 0;
}
-/* Compare two dash patterns. */
-private bool
-pdf_dash_pattern_eq(const float *stored, const gx_dash_params * set, float scale)
-{
- int i;
-
- for (i = 0; i < set->pattern_size; ++i)
- if (stored[i] != (float)(set->pattern[i] * scale))
- return false;
- return true;
-}
-
/* Stroke a path. */
int
gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
@@ -306,18 +231,16 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
gx_device_pdf *pdev = (gx_device_pdf *) dev;
stream *s;
int code;
- int pattern_size = pis->line_params.dash.pattern_size;
double scale;
bool set_ctm;
gs_matrix mat;
- const gs_matrix *pmat;
- int i;
if (gx_path_is_void(ppath))
return 0; /* won't mark the page */
if (!gx_dc_is_pure(pdcolor))
return gx_default_stroke_path(dev, pis, ppath, params, pdcolor,
pcpath);
+ pdev->vec_procs = &pdf_vector_procs;
code = pdf_open_page(pdev, pdf_in_stream);
if (code < 0)
return code;
@@ -331,80 +254,19 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_imager_state * pis,
* do it before constructing the path, and inverse-transform all
* the coordinates.
*/
- if (pis->ctm.xy == 0 && pis->ctm.yx == 0) {
- scale = fabs(pis->ctm.xx);
- set_ctm = fabs(pis->ctm.yy) != scale;
- } else if (pis->ctm.xx == 0 && pis->ctm.yy == 0) {
- scale = fabs(pis->ctm.xy);
- set_ctm = fabs(pis->ctm.yx) != scale;
- } else if ((pis->ctm.xx == pis->ctm.yy && pis->ctm.xy == -pis->ctm.yx) ||
- (pis->ctm.xx == -pis->ctm.yy && pis->ctm.xy == pis->ctm.yx)
- ) {
- scale = hypot(pis->ctm.xx, pis->ctm.xy);
- set_ctm = false;
- } else
- set_ctm = true;
- if (set_ctm) {
- scale = 1;
- mat.xx = pis->ctm.xx / pdev->scale.x;
- mat.xy = pis->ctm.xy / pdev->scale.y;
- mat.yx = pis->ctm.yx / pdev->scale.x;
- mat.yy = pis->ctm.yy / pdev->scale.y;
- mat.tx = mat.ty = 0;
- pmat = &mat;
- } else {
- pmat = 0;
- }
-
+ set_ctm = (bool)gdev_vector_stroke_scaling((gx_device_vector *)pdev,
+ pis, &scale, &mat);
pdf_put_clip_path(pdev, pcpath);
- pdf_set_color(pdev, gx_dc_pure_color(pdcolor), &pdev->stroke_color, "RG");
- s = pdev->strm;
- if ((float)(pis->line_params.dash.offset * scale) != pdev->line_params.dash.offset ||
- pattern_size != pdev->line_params.dash.pattern_size ||
- pattern_size > max_dash ||
- (pattern_size != 0 &&
- !pdf_dash_pattern_eq(pdev->dash_pattern, &pis->line_params.dash,
- scale))
- ) {
- pputs(s, "[ ");
- pdev->line_params.dash.pattern_size = pattern_size;
- for (i = 0; i < pattern_size; ++i) {
- float element = pis->line_params.dash.pattern[i] * scale;
-
- if (i < max_dash)
- pdev->dash_pattern[i] = element;
- pprintg1(s, "%g ", element);
- }
- pdev->line_params.dash.offset =
- pis->line_params.dash.offset * scale;
- pprintg1(s, "] %g d\n", pdev->line_params.dash.offset);
- }
- if (params->flatness != pdev->flatness) {
- pprintg1(s, "%g i\n", params->flatness);
- pdev->flatness = params->flatness;
- }
- if ((float)(pis->line_params.half_width * scale) != pdev->line_params.half_width) {
- pdev->line_params.half_width = pis->line_params.half_width * scale;
- pprintg1(s, "%g w\n", pdev->line_params.half_width * 2);
- }
- if (pis->line_params.miter_limit != pdev->line_params.miter_limit) {
- pprintg1(s, "%g M\n", pis->line_params.miter_limit);
- gx_set_miter_limit(&pdev->line_params,
- pis->line_params.miter_limit);
- }
- if (pis->line_params.cap != pdev->line_params.cap) {
- pprintd1(s, "%d J\n", pis->line_params.cap);
- pdev->line_params.cap = pis->line_params.cap;
- }
- if (pis->line_params.join != pdev->line_params.join) {
- pprintd1(s, "%d j\n", pis->line_params.join);
- pdev->line_params.join = pis->line_params.join;
- }
+ gdev_vector_prepare_stroke((gx_device_vector *)pdev, pis, params,
+ pdcolor, scale);
if (set_ctm)
pdf_put_matrix(pdev, "q ", &mat, "cm\n");
- code = pdf_put_path(pdev, ppath, true, pmat);
+ code = gdev_vector_dopath((gx_device_vector *)pdev, ppath,
+ gx_path_type_stroke,
+ (set_ctm ? &mat : (const gs_matrix *)0));
if (code < 0)
return code;
+ s = pdev->strm;
pputs(s, (code ? "s" : "S"));
pputs(s, (set_ctm ? " Q\n" : "\n"));
return 0;
diff --git a/gs/src/gdevpdfi.c b/gs/src/gdevpdfi.c
index fe7f09cb7..e54beb7a3 100644
--- a/gs/src/gdevpdfi.c
+++ b/gs/src/gdevpdfi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "math_.h"
#include "memory_.h"
#include "string_.h"
+#include "jpeglib_.h" /* for sdct.h */
#include "gx.h"
#include "gserrors.h"
#include "gsflip.h"
@@ -29,7 +30,6 @@
#include "gscolor2.h" /* for gscie.h */
#include "gscie.h" /* requires gscspace.h */
#include "gxistate.h"
-#include "jpeglib.h" /* for sdct.h */
#include "strimpl.h"
#include "sa85x.h"
#include "scfx.h"
@@ -39,10 +39,8 @@
#include "srlx.h"
#include "szlibx.h"
-/* We need color space types for constructing temporary color spaces. */
-extern const gs_color_space_type
- gs_color_space_type_DeviceGray, gs_color_space_type_DeviceRGB, gs_color_space_type_DeviceCMYK,
- gs_color_space_type_Indexed;
+/* We need this color space type for constructing temporary color spaces. */
+extern const gs_color_space_type gs_color_space_type_Indexed;
/* Import procedures for writing filter parameters. */
extern stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state);
@@ -459,19 +457,19 @@ pdf_make_bitmap_image(gs_image_t * pim, int x, int y, int w, int h)
private void
pdf_put_image_matrix(gx_device_pdf * pdev, const gs_matrix * pmat)
{
- pdf_put_matrix(pdev, "q\n", pmat, "cm\n");
+ pdf_put_matrix(pdev, "q ", pmat, "cm\n");
}
/* ------ Image writing ------ */
/* Forward references */
private image_enum_proc_plane_data(pdf_image_plane_data);
-private dev_proc_end_image(pdf_end_image);
+private image_enum_proc_end_image(pdf_image_end_image);
private const gx_image_enum_procs_t pdf_image_enum_procs =
{
pdf_image_plane_data,
- pdf_end_image
+ pdf_image_end_image
};
/* Define the structure for writing an image. */
@@ -546,7 +544,7 @@ pdf_end_write_image(gx_device_pdf * pdev, pdf_image_writer * piw)
pdf_end_separate(pdev);
return 0;
} else { /* in-line image */
- pputs(s, "\nEI\nQ\n");
+ pputs(s, "\nEI Q\n");
return 1;
}
}
@@ -571,12 +569,12 @@ pdf_do_image(gx_device_pdf * pdev, const pdf_resource * pres,
/* ------ Low-level calls ------ */
/* Copy a monochrome bitmap or mask. */
-int
-gdev_pdf_copy_mono(gx_device * dev,
- const byte * base, int sourcex, int raster, gx_bitmap_id id,
- int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
+private int
+pdf_copy_mono(gx_device_pdf *pdev,
+ const byte *base, int sourcex, int raster, gx_bitmap_id id,
+ int x, int y, int w, int h, gx_color_index zero,
+ gx_color_index one, const gx_clip_path *pcpath)
{
- gx_device_pdf *pdev = (gx_device_pdf *) dev;
int code;
gs_color_space cs;
byte palette[6];
@@ -587,14 +585,12 @@ gdev_pdf_copy_mono(gx_device * dev,
pdf_resource *pres = 0;
byte invert = 0;
- if (w <= 0 || h <= 0)
- return 0;
- /* Make sure we aren't being clipped. */
- if (pdf_must_put_clip_path(pdev, NULL)) {
+ /* Update clipping. */
+ if (pdf_must_put_clip_path(pdev, pcpath)) {
code = pdf_open_page(pdev, pdf_in_stream);
if (code < 0)
return code;
- pdf_put_clip_path(pdev, NULL);
+ pdf_put_clip_path(pdev, pcpath);
}
/* We have 3 cases: mask, inverse mask, and solid. */
if (zero == gx_no_color_index) {
@@ -754,68 +750,106 @@ gdev_pdf_copy_mono(gx_device * dev,
return pdf_do_char_image(pdev, (const pdf_char_proc *)pres, &imat);
}
}
-
-/* Copy a color bitmap. */
int
-gdev_pdf_copy_color(gx_device * dev,
- const byte * base, int sourcex, int raster, gx_bitmap_id id,
- int x, int y, int w, int h)
+gdev_pdf_copy_mono(gx_device * dev,
+ const byte * base, int sourcex, int raster, gx_bitmap_id id,
+ int x, int y, int w, int h, gx_color_index zero,
+ gx_color_index one)
{
gx_device_pdf *pdev = (gx_device_pdf *) dev;
- int depth = dev->color_info.depth;
+
+ if (w <= 0 || h <= 0)
+ return 0;
+ return pdf_copy_mono(pdev, base, sourcex, raster, id, x, y, w, h,
+ zero, one, NULL);
+}
+
+/* Copy a color bitmap. */
+private int
+pdf_copy_color_data(gx_device_pdf * pdev, const byte * base, int sourcex,
+ int raster, int x, int y, int w, int h,
+ gs_image_t *pim, pdf_image_writer *piw, bool for_pattern)
+{
+ int depth = pdev->color_info.depth;
int bytes_per_pixel = depth >> 3;
- int code = pdf_open_page(pdev, pdf_in_stream);
int yi;
- gs_image_t image;
gs_color_space cs;
- pdf_image_writer writer;
ulong nbytes;
+ int code;
+ const byte *row_base;
+ int row_step;
- if (code < 0)
- return code;
- if (w <= 0 || h <= 0)
- return 0;
- /* Make sure we aren't being clipped. */
- pdf_put_clip_path(pdev, NULL);
switch(bytes_per_pixel) {
case 3: gs_cspace_init_DeviceRGB(&cs); break;
case 4: gs_cspace_init_DeviceCMYK(&cs); break;
default: gs_cspace_init_DeviceGray(&cs);
}
- gs_image_t_init(&image, &cs);
- pdf_make_bitmap_image(&image, x, y, w, h);
- image.BitsPerComponent = 8;
- nbytes = (ulong) w *bytes_per_pixel * h;
+ gs_image_t_init(pim, &cs);
+ pdf_make_bitmap_image(pim, x, y, w, h);
+ pim->BitsPerComponent = 8;
+ nbytes = (ulong)w * bytes_per_pixel * h;
- pdf_put_image_matrix(pdev, &image.ImageMatrix);
- code = pdf_begin_write_image(pdev, &writer, nbytes <= 4000);
+ if (for_pattern) {
+ /*
+ * Patterns must be emitted in order of increasing user Y, i.e.,
+ * the opposite of PDF's standard image order.
+ */
+ row_base = base + (h - 1) * raster;
+ row_step = -raster;
+ pputs(pdev->strm, "q ");
+ } else {
+ row_base = base;
+ row_step = raster;
+ pdf_put_image_matrix(pdev, &pim->ImageMatrix);
+ }
+ code = pdf_begin_write_image(pdev, piw, nbytes <= 4000);
if (code < 0)
return code;
- psdf_begin_binary((gx_device_psdf *) pdev, &writer.binary);
+ psdf_begin_binary((gx_device_psdf *) pdev, &piw->binary);
code = psdf_setup_image_filters((gx_device_psdf *) pdev,
- &writer.binary, &image, NULL, NULL);
+ &piw->binary, pim, NULL, NULL);
if (code < 0)
return code;
- code = pdf_begin_image_data(pdev, &writer, &image);
+ code = pdf_begin_image_data(pdev, piw, pim);
if (code < 0)
return code;
for (yi = 0; yi < h; ++yi) {
uint ignore;
- sputs(writer.binary.strm,
- base + sourcex * bytes_per_pixel + yi * raster,
+ sputs(piw->binary.strm,
+ row_base + sourcex * bytes_per_pixel + yi * row_step,
w * bytes_per_pixel, &ignore);
}
- psdf_end_binary(&writer.binary);
- code = pdf_end_write_image(pdev, &writer);
+ psdf_end_binary(&piw->binary);
+ return pdf_end_write_image(pdev, piw);
+}
+
+int
+gdev_pdf_copy_color(gx_device * dev, const byte * base, int sourcex,
+ int raster, gx_bitmap_id id, int x, int y, int w, int h)
+{
+ gx_device_pdf *pdev = (gx_device_pdf *) dev;
+ gs_image_t image;
+ pdf_image_writer writer;
+ int code;
+
+ if (w <= 0 || h <= 0)
+ return 0;
+ code = pdf_open_page(pdev, pdf_in_stream);
+ if (code < 0)
+ return code;
+ /* Make sure we aren't being clipped. */
+ pdf_put_clip_path(pdev, NULL);
+ code = pdf_copy_color_data(pdev, base, sourcex, raster, x, y, w, h,
+ &image, &writer, false);
switch (code) {
default:
return code; /* error */
case 1:
return 0;
- case 0:;
+ case 0:
+ return pdf_do_image(pdev, writer.pres, &image.ImageMatrix);
}
- return pdf_do_image(pdev, writer.pres, &image.ImageMatrix);
}
/* Fill a mask. */
@@ -827,7 +861,6 @@ gdev_pdf_fill_mask(gx_device * dev,
gs_logical_operation_t lop, const gx_clip_path * pcpath)
{
gx_device_pdf *pdev = (gx_device_pdf *) dev;
- int code;
if (width <= 0 || height <= 0)
return 0;
@@ -835,16 +868,100 @@ gdev_pdf_fill_mask(gx_device * dev,
return gx_default_fill_mask(dev, data, data_x, raster, id,
x, y, width, height, pdcolor, depth, lop,
pcpath);
- if (pdf_must_put_clip_path(pdev, pcpath)) {
- code = pdf_open_page(pdev, pdf_in_stream);
+ return pdf_copy_mono(pdev, data, data_x, raster, id, x, y, width, height,
+ gx_no_color_index, gx_dc_pure_color(pdcolor),
+ pcpath);
+}
+
+/* Tile with a bitmap. This is important for pattern fills. */
+int
+gdev_pdf_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_pdf *const pdev = (gx_device_pdf *) dev;
+ int tw = tiles->rep_width, th = tiles->rep_height;
+ pdf_resource *pres;
+
+ if (tiles->id == gx_no_bitmap_id || tiles->shift != 0 ||
+ w < tw || h < th ||
+ /* We only handle full colored patterns right now. */
+ color0 != gx_no_color_index || color1 != gx_no_color_index ||
+ /* Pattern fills are only available starting in PDF 1.2. */
+ pdev->CompatibilityLevel < 1.2)
+ goto use_default;
+ if (!pdev->cs_Pattern) {
+ /* Create a single Pattern color space resource named Pattern. */
+ int code = pdf_begin_resource_body(pdev, resourceColorSpace, gs_no_id,
+ &pdev->cs_Pattern);
+
if (code < 0)
- return code;
- pdf_put_clip_path(pdev, pcpath);
+ goto use_default;
+ pputs(pdev->strm, "[/Pattern]\n");
+ pdf_end_resource(pdev);
+ }
+ pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, tiles->id);
+ if (!pres) {
+ /* Create the Pattern resource. */
+ int code = pdf_begin_resource(pdev, resourcePattern, tiles->id, &pres);
+ long length_id, start, end;
+ stream *s;
+ gs_image_t image;
+ pdf_image_writer writer;
+
+ if (code < 0)
+ goto use_default;
+ s = pdev->strm;
+ length_id = pdf_obj_ref(pdev);
+ pputs(s, "/PatternType 1/PaintType 1/TilingType 1\n");
+ pputs(s, "/Resources<</ProcSet[/PDF/ImageC]>>\n");
+ /*
+ * Because of bugs in Acrobat Reader's Print function, we can't use
+ * the natural BBox and Step here: they have to be 1.
+ */
+ pprintld1(s, "/BBox[0 0 1 1]/XStep 1/YStep 1/Length %ld 0 R>>stream\n", length_id);
+ start = pdf_stell(pdev);
+ code = pdf_copy_color_data(pdev, tiles->data, 0, tiles->raster,
+ 0, 0, tw, th, &image, &writer, true);
+ switch (code) {
+ default:
+ return code; /* error */
+ case 1:
+ break;
+ case 0:
+ pdf_do_image(pdev, writer.pres, &image.ImageMatrix);
+ }
+ end = pdf_stell(pdev);
+ pputs(s, "endstream\n");
+ pdf_end_resource(pdev);
+ pdf_open_separate(pdev, length_id);
+ pprintld1(pdev->strm, "%ld\n", end - start);
+ pdf_end_separate(pdev);
+ }
+ /* Fill the rectangle with the Pattern. */
+ {
+ int code = pdf_open_page(pdev, pdf_in_stream);
+ double xscale = pdev->HWResolution[0] / 72.0,
+ yscale = pdev->HWResolution[1] / 72.0;
+ stream *s;
+
+ if (code < 0)
+ goto use_default;
+ s = pdev->strm;
+ /*
+ * Because of bugs in Acrobat Reader's Print function, we can't
+ * leave the CTM alone here: we have to reset it to the default.
+ */
+ pprintg2(s, "q %g 0 0 %g 0 0 cm", xscale, yscale);
+ pprintld2(s, "/R%ld cs/R%ld scn ", pdev->cs_Pattern->id, pres->id);
+ pprintg4(s, "%g %g %g %g re f Q\n",
+ x / xscale, y / yscale, w / xscale, h / xscale);
}
- return gdev_pdf_copy_mono(dev, data, data_x, raster, id,
- x, y, width, height,
- gx_no_color_index,
- gx_dc_pure_color(pdcolor));
+ return 0;
+use_default:
+ return gx_default_strip_tile_rectangle(dev, tiles, x, y, w, h,
+ color0, color1, px, py);
}
/* ------ High-level calls ------ */
@@ -853,7 +970,6 @@ gdev_pdf_fill_mask(gx_device * dev,
typedef struct pdf_image_enum_s {
gx_image_enum_common;
gs_memory_t *memory;
- gx_image_enum_common_t *default_info;
int width;
int bits_per_pixel; /* bits per pixel (per plane) */
int rows_left;
@@ -862,8 +978,7 @@ typedef struct pdf_image_enum_s {
/* We can disregard the pointers in the writer by allocating */
/* the image enumerator as immovable. This is a hack, of course. */
-gs_private_st_ptrs1(st_pdf_image_enum, pdf_image_enum, "pdf_image_enum",
- pdf_image_enum_enum_ptrs, pdf_image_enum_reloc_ptrs, default_info);
+gs_private_st_simple(st_pdf_image_enum, pdf_image_enum, "pdf_image_enum");
/* Test whether we can handle a given color space. */
private bool
@@ -963,24 +1078,18 @@ gdev_pdf_begin_image(gx_device * dev,
if (pie == 0)
return_error(gs_error_VMerror);
*pinfo = (gx_image_enum_common_t *) pie;
- gx_image_enum_common_init(*pinfo, (gs_image_common_t *) pim,
+ gx_image_enum_common_init(*pinfo, (gs_data_image_t *) pim,
&pdf_image_enum_procs, dev,
- pim->BitsPerComponent, num_components,
- format);
+ num_components, format);
pie->memory = mem;
- pie->default_info = 0;
if ((pim->ImageMask ?
(!gx_dc_is_pure(pdcolor) || pim->CombineWithColor) :
!pdf_can_handle_color_space(pim->ColorSpace)) ||
prect != 0
) {
- int code = gx_default_begin_image(dev, pis, pim, format, prect,
- pdcolor, pcpath, mem,
- &pie->default_info);
-
- if (code < 0)
- gs_free_object(mem, pie, "pdf_begin_image");
- return code;
+ gs_free_object(mem, pie, "pdf_begin_image");
+ return gx_default_begin_image(dev, pis, pim, format, prect,
+ pdcolor, pcpath, mem, pinfo);
}
pie->width = rect.q.x - rect.p.x;
pie->bits_per_pixel =
@@ -1027,44 +1136,58 @@ gdev_pdf_begin_image(gx_device * dev,
/* Process the next piece of an image. */
private int
-pdf_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
- const gx_image_plane_t * planes, int height)
+pdf_image_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
{
pdf_image_enum *pie = (pdf_image_enum *) info;
int h = height;
int y;
- uint bcount;
+ /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
+ uint width_bits = pie->width * pie->plane_depths[0];
+ /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
+ uint bcount = (width_bits + 7) >> 3;
uint ignore;
int nplanes = pie->num_planes;
-#define row_bytes 180 /* must be 0 mod 3, 4, 6, 9 */
- byte row[row_bytes];
-
- if (pie->default_info)
- return gx_image_plane_data(pie->default_info, planes, height);
if (h > pie->rows_left)
h = pie->rows_left;
pie->rows_left -= h;
-/****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
- bcount =
- ((planes[0].data_x + pie->width) * pie->plane_depths[0] + 7) >> 3;
for (y = 0; y < h; ++y) {
if (nplanes > 1) {
- /* Flip the data in blocks before writing. */
+ /*
+ * We flip images in blocks, and each block except the last one
+ * must contain an integral number of pixels. The easiest way
+ * to meet this condition is for all blocks except the last to
+ * be a multiple of 3 source bytes (guaranteeing an integral
+ * number of 1/2/4/8/12-bit samples), i.e., 3*nplanes flipped
+ * bytes. This requires a buffer of at least
+ * 3*GS_IMAGE_MAX_COMPONENTS bytes.
+ */
int pi;
uint count = bcount;
uint offset = 0;
- const byte *bit_planes[gs_image_max_components];
+#define ROW_BYTES max(200 /*arbitrary*/, 3 * GS_IMAGE_MAX_COMPONENTS)
+ const byte *bit_planes[GS_IMAGE_MAX_COMPONENTS];
+ int block_bytes = ROW_BYTES / (3 * nplanes) * 3;
+ byte row[ROW_BYTES];
for (pi = 0; pi < nplanes; ++pi)
bit_planes[pi] = planes[pi].data + planes[pi].raster * y;
while (count) {
- uint flip_count = min(count, row_bytes / nplanes);
-
+ uint flip_count;
+ uint flipped_count;
+
+ if (count >= block_bytes)
+ flip_count = flipped_count = block_bytes;
+ else {
+ flip_count = count;
+ flipped_count =
+ (width_bits % (block_bytes * 8) * nplanes + 7) >> 3;
+ }
image_flip_planes(row, bit_planes, offset, flip_count,
nplanes, pie->plane_depths[0]);
- sputs(pie->writer.binary.strm, row, flip_count * nplanes,
- &ignore);
+ sputs(pie->writer.binary.strm, row, flipped_count, &ignore);
offset += flip_count;
count -= flip_count;
}
@@ -1073,34 +1196,30 @@ pdf_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
planes[0].data + planes[0].raster * y, bcount, &ignore);
}
}
+ *rows_used = h;
return !pie->rows_left;
-#undef row_bytes
+#undef ROW_BYTES
}
/* Clean up by releasing the buffers. */
private int
-pdf_end_image(gx_device * dev, gx_image_enum_common_t * info, bool draw_last)
+pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
{
- gx_device_pdf *pdev = (gx_device_pdf *) dev;
- pdf_image_enum *pie = (pdf_image_enum *) info;
- int code;
+ gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
+ pdf_image_enum *pie = (pdf_image_enum *)info;
+ int code = psdf_end_binary(&pie->writer.binary);
- if (pie->default_info)
- code = gx_default_end_image(dev, pie->default_info, draw_last);
- else {
- code = psdf_end_binary(&pie->writer.binary);
- if (code < 0)
- return code;
- code = pdf_end_write_image(pdev, &pie->writer);
- switch (code) {
- default:
- return code; /* error */
- case 1:
- return 0;
- case 0:;
- }
- code = pdf_do_image(pdev, pie->writer.pres, NULL);
+ if (code < 0)
+ return code;
+ code = pdf_end_write_image(pdev, &pie->writer);
+ switch (code) {
+ default:
+ return code; /* error */
+ case 1:
+ return 0;
+ case 0:;
}
+ code = pdf_do_image(pdev, pie->writer.pres, NULL);
gs_free_object(pie->memory, pie, "pdf_end_image");
return code;
}
diff --git a/gs/src/gdevpdfm.c b/gs/src/gdevpdfm.c
index 9814faa2c..5d481b9e8 100644
--- a/gs/src/gdevpdfm.c
+++ b/gs/src/gdevpdfm.c
@@ -131,7 +131,9 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
for (pmn = mark_name_tables[n]; pmn->mname != 0; ++pmn)
if (pdf_key_eq(pts, pmn->mname)) {
+ gs_memory_t *mem = pdev->pdf_memory;
int odd_ok = (pmn->options & pdfmark_odd_ok) != 0;
+ gs_param_string *pairs;
int j;
if (size & !odd_ok)
@@ -145,38 +147,41 @@ pdfmark_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
objname->size)
)
return_error(gs_error_rangecheck);
- break;
+ /* Save the pairs without the name. */
+ size -= 2;
+ pairs = (gs_param_string *)
+ gs_alloc_byte_array(mem, size,
+ sizeof(gs_param_string),
+ "pdfmark_process(pairs)");
+ if (!pairs)
+ return_error(gs_error_VMerror);
+ memcpy(pairs, data, j * sizeof(*data));
+ memcpy(pairs + j, data + j + 2,
+ (size - j) * sizeof(*data));
+ goto copied;
}
}
}
- /* Copy the pairs to a writable array. */
- {
- uint count = (objname ? size - 2 : size);
- gs_memory_t *mem = pdev->pdf_memory;
- gs_param_string *pairs = (gs_param_string *)
- gs_alloc_byte_array(mem, count, sizeof(gs_param_string),
+ /* Save all the pairs. */
+ pairs = (gs_param_string *)
+ gs_alloc_byte_array(mem, size,
+ sizeof(gs_param_string),
"pdfmark_process(pairs)");
-
- if (objname) {
- memcpy(pairs, data, j * sizeof(*data));
- memcpy(pairs + j, data + j + 2, (count - j) * sizeof(*data));
- size -= 2;
- } else {
- memcpy(pairs, data, count * sizeof(*data));
- }
- /* Substitute object references for names. */
- for (j = (pmn->options & pdfmark_keep_name ? 1 : 1 - odd_ok);
- j < size; j += 2 - odd_ok
- ) {
- code = pdfmark_replace_names(pdev, &pairs[j], &pairs[j]);
- if (code < 0) {
- gs_free_object(mem, pairs, "pdfmark_process(pairs)");
- goto out;
- }
+ if (!pairs)
+ return_error(gs_error_VMerror);
+ memcpy(pairs, data, size * sizeof(*data));
+copied: /* Substitute object references for names. */
+ for (j = (pmn->options & pdfmark_keep_name ? 1 : 1 - odd_ok);
+ j < size; j += 2 - odd_ok
+ ) {
+ code = pdfmark_replace_names(pdev, &pairs[j], &pairs[j]);
+ if (code < 0) {
+ gs_free_object(mem, pairs, "pdfmark_process(pairs)");
+ goto out;
}
- code = (*pmn->proc) (pdev, pairs, size, &ctm, objname);
- gs_free_object(mem, pairs, "pdfmark_process(pairs)");
}
+ code = (*pmn->proc) (pdev, pairs, size, &ctm, objname);
+ gs_free_object(mem, pairs, "pdfmark_process(pairs)");
goto out;
}
}
diff --git a/gs/src/gdevpdfo.c b/gs/src/gdevpdfo.c
index 5684adc69..86b4cf13e 100644
--- a/gs/src/gdevpdfo.c
+++ b/gs/src/gdevpdfo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,6 +19,7 @@
/* Named object pdfmark processing */
#include "memory_.h"
+#include "string_.h"
#include "gx.h"
#include "gserrors.h"
#include "gsutil.h" /* for bytes_compare */
@@ -186,10 +187,11 @@ pdfmark_next_object(const byte * scan, const byte * end, const byte ** pname,
const byte *right;
*ppno = 0;
- top:left = memchr(scan, '{', end - scan);
+top:
+ left = (const byte *)memchr(scan, '{', end - scan);
if (left == 0)
return (*pname = end);
- lit = memchr(scan, '(', left - scan);
+ lit = (const byte *)memchr(scan, '(', left - scan);
if (lit) {
/* Skip over the string. */
byte buf[50]; /* size is arbitrary */
@@ -211,7 +213,7 @@ pdfmark_next_object(const byte * scan, const byte * end, const byte ** pname,
scan = r.ptr + 1;
goto top;
}
- right = memchr(left + 1, '}', end - (left + 1));
+ right = (const byte *)memchr(left + 1, '}', end - (left + 1));
if (right == 0) /* malformed name */
return (*pname = end);
*pname = left;
diff --git a/gs/src/gdevpdfp.c b/gs/src/gdevpdfp.c
index cdea186df..000de4c3a 100644
--- a/gs/src/gdevpdfp.c
+++ b/gs/src/gdevpdfp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "gx.h"
#include "gserrors.h"
#include "gdevpdfx.h"
+#include "gsparamx.h"
/*
* The pdfwrite device supports the following "real" parameters:
@@ -135,13 +136,13 @@ gdev_pdf_put_params(gx_device * dev, gs_param_list * plist)
{
int cdv = CoreDistVersion;
- ecode = psdf_put_int_param(plist, (param_name = "CoreDistVersion"), &cdv, ecode);
+ ecode = param_put_int(plist, (param_name = "CoreDistVersion"), &cdv, ecode);
if (cdv != CoreDistVersion)
param_signal_error(plist, param_name, ecode = gs_error_rangecheck);
}
- ecode = psdf_put_bool_param(plist, "ReAssignCharacters", &rac, ecode);
- ecode = psdf_put_bool_param(plist, "ReEncodeCharacters", &rec, ecode);
+ ecode = param_put_bool(plist, "ReAssignCharacters", &rac, ecode);
+ ecode = param_put_bool(plist, "ReEncodeCharacters", &rec, ecode);
switch (code = param_read_long(plist, (param_name = "FirstObjectNumber"), &fon)) {
case 0:
/*
diff --git a/gs/src/gdevpdfx.h b/gs/src/gdevpdfx.h
index c8d5573d4..6718fe210 100644
--- a/gs/src/gdevpdfx.h
+++ b/gs/src/gdevpdfx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -53,6 +53,7 @@ typedef enum {
resourceFontDescriptor,
resourceColorSpace,
resourceImageXObject,
+ resourcePattern,
/* Internally used resources. */
resourceCharProc,
resourceNamedObject,
@@ -61,10 +62,10 @@ typedef enum {
#define pdf_resource_type_names\
"Font", "Encoding", "FontDescriptor", "ColorSpace", "XObject",\
- 0, 0, 0
+ "Pattern", 0, 0, 0
#define pdf_resource_type_structs\
&st_pdf_font, &st_pdf_resource, &st_pdf_resource, &st_pdf_resource,\
- &st_pdf_resource, &st_pdf_char_proc, &st_pdf_named_object
+ &st_pdf_resource, &st_pdf_resource, &st_pdf_char_proc, &st_pdf_named_object
#define pdf_resource_common(typ)\
typ *next; /* next resource of this type */\
@@ -321,6 +322,7 @@ typedef struct gx_device_pdf_s {
int num_page_ids;
int pages_referenced;
pdf_resource_list resources[num_resource_types];
+ pdf_resource *cs_Pattern;
pdf_resource *annots; /* rid = page # */
pdf_resource *last_resource;
gs_string catalog_string;
@@ -438,6 +440,10 @@ int pdf_begin_aside(P4(gx_device_pdf * pdev, pdf_resource ** plist,
int pdf_begin_resource(P4(gx_device_pdf * pdev, pdf_resource_type type,
gs_id rid, pdf_resource ** ppres));
+/* Begin a resource body of a given type. */
+int pdf_begin_resource_body(P4(gx_device_pdf * pdev, pdf_resource_type type,
+ gs_id rid, pdf_resource ** ppres));
+
/* Allocate a resource, but don't open the stream. */
int pdf_alloc_resource(P4(gx_device_pdf * pdev, pdf_resource_type type,
gs_id rid, pdf_resource ** ppres));
@@ -515,7 +521,7 @@ int pdfmark_write_article(P2(gx_device_pdf * pdev, const pdf_article * part));
/* Define the syntax of object names. */
#define pdfmark_objname_is_valid(data, size)\
((size) >= 2 && (data)[0] == '{' &&\
- memchr(data, '}', size) == (data) + (size) - 1)
+ (const byte *)memchr(data, '}', size) == (data) + (size) - 1)
/* Define the table of named-object pdfmark types. */
extern const pdfmark_name pdfmark_names_named[];
diff --git a/gs/src/gdevplnx.c b/gs/src/gdevplnx.c
new file mode 100644
index 000000000..4a240a406
--- /dev/null
+++ b/gs/src/gdevplnx.c
@@ -0,0 +1,1106 @@
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/* Plane extraction device */
+#include "gx.h"
+#include "gserrors.h"
+#include "gsbitops.h"
+#include "gsrop.h" /* for logical op access */
+#include "gsstruct.h"
+#include "gsutil.h"
+#include "gxdcolor.h"
+#include "gxcmap.h" /* requires gxdcolor.h */
+#include "gxdevice.h"
+#include "gxdevmem.h"
+#include "gxdither.h"
+#include "gxgetbit.h"
+#include "gxiparam.h"
+#include "gxistate.h"
+#include "gdevplnx.h"
+
+/* Define the size of the locally allocated bitmap buffers. */
+#define COPY_COLOR_BUF_SIZE 100
+#define TILE_RECTANGLE_BUF_SIZE 100
+#define COPY_ROP_SOURCE_BUF_SIZE 100
+#define COPY_ROP_TEXTURE_BUF_SIZE 100
+
+/* GC procedures */
+#define edev ((gx_device_plane_extract *)vptr)
+private
+ENUM_PTRS_BEGIN(device_plane_extract_enum_ptrs) ENUM_PREFIX(st_device_forward, 1);
+case 0:
+ENUM_RETURN(gx_device_enum_ptr(edev->target));
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(device_plane_extract_reloc_ptrs)
+{
+ RELOC_PREFIX(st_device_forward);
+ edev->plane_dev = gx_device_reloc_ptr(edev->plane_dev, gcst);
+}
+RELOC_PTRS_END
+#undef edev
+public_st_device_plane_extract();
+
+/* Driver procedures */
+private dev_proc_open_device(plane_open_device);
+private dev_proc_fill_rectangle(plane_fill_rectangle);
+private dev_proc_copy_mono(plane_copy_mono);
+private dev_proc_copy_color(plane_copy_color);
+private dev_proc_copy_alpha(plane_copy_alpha);
+private dev_proc_fill_path(plane_fill_path);
+private dev_proc_stroke_path(plane_stroke_path);
+private dev_proc_fill_mask(plane_fill_mask);
+private dev_proc_fill_parallelogram(plane_fill_parallelogram);
+private dev_proc_fill_triangle(plane_fill_triangle);
+private dev_proc_strip_tile_rectangle(plane_strip_tile_rectangle);
+private dev_proc_strip_copy_rop(plane_strip_copy_rop);
+private dev_proc_begin_typed_image(plane_begin_typed_image);
+private dev_proc_get_bits_rectangle(plane_get_bits_rectangle);
+
+/* Device prototype */
+private const gx_device_plane_extract gs_plane_extract_device = {
+ std_device_std_body(gx_device_plane_extract, 0, "plane_extract",
+ 0, 0, 72, 72),
+ {
+ plane_open_device,
+ NULL,
+ NULL,
+ NULL,
+ gx_default_close_device,
+ NULL,
+ NULL,
+ plane_fill_rectangle,
+ gx_default_tile_rectangle,
+ plane_copy_mono,
+ plane_copy_color,
+ gx_default_draw_line,
+ gx_default_get_bits,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ plane_copy_alpha,
+ NULL,
+ gx_default_copy_rop,
+ plane_fill_path,
+ plane_stroke_path,
+ plane_fill_mask,
+ gx_default_fill_trapezoid,
+ plane_fill_parallelogram,
+ plane_fill_triangle,
+ gx_default_draw_thin_line,
+ gx_default_begin_image,
+ gx_default_image_data,
+ gx_default_end_image,
+ plane_strip_tile_rectangle,
+ plane_strip_copy_rop,
+ NULL,
+ plane_begin_typed_image,
+ plane_get_bits_rectangle,
+ NULL,
+ gx_no_create_compositor, /* WRONG */
+ NULL,
+ gx_default_text_begin
+ },
+ /* device-specific members */
+ NULL, /* target */
+ NULL, /* plane_dev */
+ { 0 }, /* plane */
+ 0, /* plane_white */
+ 0, /* plane_mask */
+ 0, /* plane_dev_is_memory */
+ 1 /*true*/ /* any_marks */
+};
+
+/* ---------------- Utilities ---------------- */
+
+/* Extract the selected plane from a color (gx_color_index). */
+#define COLOR_PIXEL(edev, color)\
+ ( ((color) >> (edev)->plane.shift) & (edev)->plane_mask )
+/* Do the same if the color might be transparent. */
+#define TRANS_COLOR_PIXEL(edev, color)\
+ ((color) == gx_no_color_index ? gx_no_color_index : COLOR_PIXEL(edev, color))
+
+/*
+ * Reduce the drawing color to one for the selected plane.
+ * All we care about is whether the drawing operation should be skipped.
+ */
+typedef enum {
+ REDUCE_SKIP,
+ REDUCE_DRAW,
+ REDUCE_FAILED /* couldn't reduce */
+} reduced_color_t;
+#define REDUCE_PURE(edev, pixel)\
+ ((pixel) == (edev)->plane_white && !(edev)->any_marks ? REDUCE_SKIP :\
+ ((edev)->any_marks = true, REDUCE_DRAW))
+private reduced_color_t
+reduce_drawing_color(gx_device_color *ppdc, gx_device_plane_extract *edev,
+ const gx_drawing_color *pdevc,
+ gs_logical_operation_t *plop)
+{
+ reduced_color_t reduced;
+
+ if (gx_dc_is_pure(pdevc)) {
+ gx_color_index pixel = COLOR_PIXEL(edev, gx_dc_pure_color(pdevc));
+
+ color_set_pure(ppdc, pixel);
+ reduced = REDUCE_PURE(edev, pixel);
+ } else if (gx_dc_is_binary_halftone(pdevc)) {
+ gx_color_index pixel0 =
+ TRANS_COLOR_PIXEL(edev, gx_dc_binary_color0(pdevc));
+ gx_color_index pixel1 =
+ TRANS_COLOR_PIXEL(edev, gx_dc_binary_color1(pdevc));
+
+ if (pixel0 == pixel1) {
+ color_set_pure(ppdc, pixel0);
+ reduced = REDUCE_PURE(edev, pixel0);
+ } else {
+ *ppdc = *pdevc;
+ ppdc->colors.binary.color[0] = pixel0;
+ ppdc->colors.binary.color[1] = pixel1;
+ edev->any_marks = true;
+ reduced = REDUCE_DRAW;
+ }
+ } else if (color_is_colored_halftone(pdevc)) {
+ int plane = edev->plane.index;
+ int i;
+
+ *ppdc = *pdevc;
+ for (i = 0; i < countof(ppdc->colors.colored.c_base); ++i)
+ if (i != edev->plane.index) {
+ ppdc->colors.colored.c_base[i] = 0;
+ ppdc->colors.colored.c_level[i] = 0;
+ }
+ ppdc->colors.colored.plane_mask &= 1 << plane;
+ if (ppdc->colors.colored.c_level[plane] == 0) {
+ gx_reduce_colored_halftone(ppdc, (gx_device *)edev, true);
+ ppdc->colors.pure = COLOR_PIXEL(edev, ppdc->colors.pure);
+ reduced = REDUCE_PURE(edev, gx_dc_pure_color(ppdc));
+ } else if (ppdc->colors.colored.alpha != gx_max_color_value)
+ return REDUCE_FAILED; /* can't reduce */
+ else {
+ gx_reduce_colored_halftone(ppdc, (gx_device *)edev, true);
+ ppdc->colors.binary.color[0] =
+ COLOR_PIXEL(edev, ppdc->colors.binary.color[0]);
+ ppdc->colors.binary.color[1] =
+ COLOR_PIXEL(edev, ppdc->colors.binary.color[1]);
+ gx_color_load(ppdc, NULL, (gx_device *)edev);
+ edev->any_marks = true;
+ reduced = REDUCE_DRAW;
+ }
+ } else
+ return REDUCE_FAILED; /* can't handle it */
+ if (*plop & lop_T_transparent) {
+ /*
+ * If the logical operation invokes transparency for the texture, we
+ * must do some extra work, since a color that was originally opaque
+ * may become transparent (white) if reduced to a single plane. If
+ * RasterOp transparency were calculated before halftoning, life
+ * would be easy: we would simply turn off texture transparency in
+ * the logical operation iff the original (not reduced) color was
+ * not white. Unfortunately, RasterOp transparency is calculated
+ * after halftoning. (This is arguably wrong, but it's how we've
+ * defined it.) Therefore, if transparency is involved with a
+ * white color or a halftone that can include white, we must keep
+ * the entire pixel together for the RasterOp.
+ */
+ gx_color_index white = gx_device_white((gx_device *)edev);
+
+ /*
+ * Given that we haven't failed, the only possible colors at this
+ * point are pure or binary halftone.
+ */
+ if (gx_dc_is_pure(ppdc)) {
+ if (gx_dc_pure_color(pdevc) != white)
+ *plop &= ~lop_T_transparent;
+ else if (!gx_dc_is_pure(pdevc))
+ return REDUCE_FAILED;
+ } else {
+ if (gx_dc_binary_color0(pdevc) != white &&
+ gx_dc_binary_color1(pdevc) != white) {
+ *plop &= ~lop_T_transparent;
+ } else
+ return REDUCE_FAILED;
+ }
+ }
+ return reduced;
+}
+
+/*
+ * Set up to create the plane-extracted bitmap corresponding to a
+ * source or halftone pixmap. If the bitmap doesn't fit in the locally
+ * allocated buffer, we may either do the operation in pieces, or allocate
+ * a buffer on the heap. The control structure is:
+ * begin_tiling(&state, ...);
+ * do {
+ * extract_partial_tile(&state);
+ * ... process tile in buffer ...
+ * } while (next_tile(&state));
+ * end_tiling(&state);
+ * If partial_ok is false, there is only a single tile, so the do ... while
+ * is not used.
+ */
+typedef struct tiling_state_s {
+ /* Save the original operands. */
+ const gx_device_plane_extract *edev;
+ const byte *data;
+ int data_x;
+ uint raster;
+ int width, height;
+ int dest_x; /* only for copy_color, defaults to 0 */
+ /* Define the (aligned) buffer for doing the operation. */
+ struct tsb_ {
+ byte *data;
+ uint size;
+ uint raster;
+ bool on_heap;
+ } buffer;
+ /* Record the current tile available for processing. */
+ /* The client may read these out. */
+ gs_int_point offset;
+ gs_int_point size;
+ /* Record private tiling parameters. */
+ int per_tile_width;
+} tiling_state_t;
+
+/*
+ * Extract the plane's data from one subrectangle of a source tile.
+ */
+inline private int /* ignore the return value */
+extract_partial_tile(const tiling_state_t *pts)
+{
+ const gx_device_plane_extract * const edev = pts->edev;
+ bits_plane_t dest, source;
+
+ dest.data.write = pts->buffer.data + pts->offset.y * pts->buffer.raster;
+ dest.raster = pts->buffer.raster;
+ dest.depth = edev->plane.depth;
+ dest.x = pts->dest_x;
+
+ source.data.read = pts->data + pts->offset.y * pts->raster;
+ source.raster = pts->raster;
+ source.depth = edev->color_info.depth;
+ source.x = pts->data_x + pts->offset.x;
+
+ bits_extract_plane(&dest, &source, edev->plane.shift,
+ pts->size.x, pts->size.y);
+ return 0;
+}
+
+/*
+ * Set up to start (possibly) tiling. Return 0 if the entire tile fit,
+ * 1 if a partial tile fit, or a negative error code.
+ */
+private int
+begin_tiling(tiling_state_t *pts, gx_device_plane_extract *edev,
+ const byte *data, int data_x, uint raster, int width, int height,
+ byte *local_buffer, uint buffer_size, bool partial_ok)
+{
+ uint width_raster =
+ bitmap_raster(width * edev->plane_dev->color_info.depth);
+ uint full_size = width_raster * height;
+
+ pts->edev = edev;
+ pts->data = data, pts->data_x = data_x, pts->raster = raster;
+ pts->width = width, pts->height = height;
+ pts->dest_x = 0;
+ if (full_size <= buffer_size) {
+ pts->buffer.data = local_buffer;
+ pts->buffer.size = buffer_size;
+ pts->buffer.raster = width_raster;
+ pts->buffer.on_heap = false;
+ pts->size.x = width, pts->size.y = height;
+ } else if (partial_ok) {
+ pts->buffer.data = local_buffer;
+ pts->buffer.size = buffer_size;
+ pts->buffer.on_heap = false;
+ if (buffer_size >= width_raster) {
+ pts->buffer.raster = width_raster;
+ pts->size.x = width;
+ pts->size.y = buffer_size / width_raster;
+ } else {
+ pts->buffer.raster = buffer_size & -align_bitmap_mod;
+ pts->size.x =
+ pts->buffer.raster * (8 / edev->plane_dev->color_info.depth);
+ pts->size.y = 1;
+ }
+ } else {
+ pts->buffer.data =
+ gs_alloc_bytes(edev->memory, full_size, "begin_tiling");
+ if (!pts->buffer.data)
+ return_error(gs_error_VMerror);
+ pts->buffer.size = full_size;
+ pts->buffer.raster = width_raster;
+ pts->buffer.on_heap = true;
+ pts->size.x = width, pts->size.y = height;
+ }
+ pts->buffer.raster = width_raster;
+ pts->offset.x = pts->offset.y = 0;
+ pts->per_tile_width = pts->size.x;
+ return pts->buffer.size < full_size;
+}
+
+/*
+ * Advance to the next tile. Return true if there are more tiles to do.
+ */
+private bool
+next_tile(tiling_state_t *pts)
+{
+ if ((pts->offset.x += pts->size.x) >= pts->width) {
+ if ((pts->offset.y += pts->size.y) >= pts->height)
+ return false;
+ pts->offset.x = 0;
+ pts->size.x = pts->per_tile_width;
+ if (pts->offset.y + pts->size.y >= pts->height)
+ pts->size.y = pts->height - pts->offset.y;
+ } else if (pts->offset.x + pts->size.x >= pts->width)
+ pts->size.x = pts->width - pts->offset.x;
+ return true;
+}
+
+/*
+ * Finish tiling by freeing the buffer if necessary.
+ */
+private void
+end_tiling(tiling_state_t *pts)
+{
+ if (pts->buffer.on_heap)
+ gs_free_object(pts->edev->memory, pts->buffer.data, "end_tiling");
+}
+
+/* ---------------- Initialization ---------------- */
+
+int
+plane_device_init(gx_device_plane_extract *edev, gx_device *target,
+ gx_device *plane_dev, const gx_render_plane_t *render_plane, bool clear)
+{
+ /* Check for compatibility of the plane specification. */
+ if (render_plane->depth > plane_dev->color_info.depth)
+ return_error(gs_error_rangecheck);
+ gx_device_init((gx_device *)edev,
+ (const gx_device *)&gs_plane_extract_device,
+ edev->memory, true);
+ gx_device_forward_fill_in_procs((gx_device_forward *)edev);
+ gx_device_set_target((gx_device_forward *)edev, target);
+ gx_device_copy_params((gx_device *)edev, target);
+ edev->plane_dev = plane_dev;
+ edev->plane = *render_plane;
+ plane_open_device((gx_device *)edev);
+ if (clear) {
+ dev_proc(plane_dev, fill_rectangle)
+ (plane_dev, 0, 0, plane_dev->width, plane_dev->height,
+ edev->plane_white);
+ edev->any_marks = false;
+ }
+ return 0;
+}
+
+/* ---------------- Driver procedures ---------------- */
+
+private int
+plane_open_device(gx_device *dev)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ int plane_depth = plane_dev->color_info.depth;
+ const gx_device_memory * const mdproto =
+ gdev_mem_device_for_bits(plane_depth);
+
+ edev->plane_white = gx_device_white(plane_dev);
+ edev->plane_mask = (1 << plane_depth) - 1;
+ edev->plane_dev_is_memory = mdproto != 0 &&
+ dev_proc(plane_dev, copy_color) == dev_proc(mdproto, copy_color);
+ /* We don't set or clear any_marks here: see ...init above. */
+ return 0;
+}
+
+private int
+plane_fill_rectangle(gx_device *dev,
+ int x, int y, int w, int h, gx_color_index color)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_color_index pixel = COLOR_PIXEL(edev, color);
+
+ if (pixel != edev->plane_white)
+ edev->any_marks = true;
+ else if (!edev->any_marks)
+ return 0;
+ return dev_proc(plane_dev, fill_rectangle)
+ (plane_dev, x, y, w, h, pixel);
+}
+
+private int
+plane_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 color0, gx_color_index color1)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_color_index pixel0 = TRANS_COLOR_PIXEL(edev, color0);
+ gx_color_index pixel1 = TRANS_COLOR_PIXEL(edev, color1);
+
+ if (pixel0 == pixel1)
+ return plane_fill_rectangle(dev, x, y, w, h, color0);
+ if ((pixel0 == edev->plane_white || pixel0 == gx_no_color_index) &&
+ (pixel1 == edev->plane_white || pixel1 == gx_no_color_index)) {
+ /* This operation will only write white. */
+ if (!edev->any_marks)
+ return 0;
+ } else
+ edev->any_marks = true;
+ return dev_proc(plane_dev, copy_mono)
+ (plane_dev, data, data_x, raster, id, x, y, w, h, pixel0, pixel1);
+}
+
+private int
+plane_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)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ tiling_state_t state;
+ long buf[COPY_COLOR_BUF_SIZE / sizeof(long)];
+ int code;
+
+ if (edev->plane_dev_is_memory) {
+ /* Reduce the source directly into the plane device. */
+ gx_device_memory * const mdev = (gx_device_memory *)plane_dev;
+
+ fit_copy(edev, data, data_x, raster, id, x, y, w, h);
+ code = begin_tiling(&state, edev, data, data_x, raster, w, h,
+ scan_line_base(mdev, y), max_uint, false);
+ if (code < 0)
+ return code;
+ state.dest_x = x;
+ state.buffer.raster = mdev->raster;
+ extract_partial_tile(&state);
+ end_tiling(&state);
+ edev->any_marks = true;
+ return 0;
+ }
+ code = begin_tiling(&state, edev, data, data_x, raster,
+ w, h, (byte *)buf, sizeof(buf), true);
+ if (code < 0)
+ return code;
+ do {
+ extract_partial_tile(&state);
+ code = dev_proc(plane_dev, copy_color)
+ (plane_dev, state.buffer.data, 0, state.buffer.raster,
+ gx_no_bitmap_id, x + state.offset.x, y + state.offset.y,
+ state.size.x, state.size.y);
+ } while (code >= 0 && next_tile(&state));
+ end_tiling(&state);
+ edev->any_marks = true;
+ return code;
+}
+
+private int
+plane_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_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_color_index pixel = COLOR_PIXEL(edev, color);
+
+ if (pixel != edev->plane_white)
+ edev->any_marks = true;
+ else if (!edev->any_marks)
+ return 0;
+ return dev_proc(plane_dev, copy_alpha)
+ (plane_dev, data, data_x, raster, id, x, y, w, h, pixel, depth);
+}
+
+private int
+plane_fill_path(gx_device *dev,
+ const gs_imager_state *pis, gx_path *ppath,
+ const gx_fill_params *params,
+ const gx_drawing_color *pdevc, const gx_clip_path *pcpath)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gs_logical_operation_t lop_orig =
+ gs_current_logical_op((const gs_state *)pis);
+ gs_logical_operation_t lop = lop_orig;
+ gx_device_color dcolor;
+
+ switch (reduce_drawing_color(&dcolor, edev, pdevc, &lop)) {
+ case REDUCE_SKIP:
+ return 0;
+ case REDUCE_DRAW: {
+ gs_imager_state lopis;
+ const gs_imager_state *pis_draw = pis;
+
+ if (lop != lop_orig) {
+ lopis = *pis;
+ gs_set_logical_op((gs_state *)&lopis, lop);
+ pis_draw = &lopis;
+ }
+ return dev_proc(plane_dev, fill_path)
+ (plane_dev, pis_draw, ppath, params, &dcolor, pcpath);
+ }
+ default /*REDUCE_FAILED*/:
+ return gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath);
+ }
+}
+
+private int
+plane_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_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gs_logical_operation_t lop_orig =
+ gs_current_logical_op((const gs_state *)pis);
+ gs_logical_operation_t lop = lop_orig;
+ gx_device_color dcolor;
+
+ switch (reduce_drawing_color(&dcolor, edev, pdevc, &lop)) {
+ case REDUCE_SKIP:
+ return 0;
+ case REDUCE_DRAW: {
+ gs_imager_state lopis;
+ const gs_imager_state *pis_draw = pis;
+
+ if (lop != lop_orig) {
+ lopis = *pis;
+ gs_set_logical_op((gs_state *)&lopis, lop);
+ pis_draw = &lopis;
+ }
+ return dev_proc(plane_dev, stroke_path)
+ (plane_dev, pis_draw, ppath, params, &dcolor, pcpath);
+ }
+ default /*REDUCE_FAILED*/:
+ return gx_default_stroke_path(dev, pis, ppath, params, pdevc, pcpath);
+ }
+}
+
+private int
+plane_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)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_device_color dcolor;
+
+ switch (reduce_drawing_color(&dcolor, edev, pdcolor, &lop)) {
+ case REDUCE_SKIP:
+ return 0;
+ case REDUCE_DRAW:
+ return dev_proc(plane_dev, fill_mask)
+ (plane_dev, data, data_x, raster, gx_no_bitmap_id, x, y, w, h,
+ &dcolor, depth, lop, pcpath);
+ default /*REDUCE_FAILED*/:
+ return gx_default_fill_mask(dev, data, data_x, raster, gx_no_bitmap_id,
+ x, y, w, h, &dcolor, depth, lop, pcpath);
+ }
+}
+
+private int
+plane_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_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_device_color dcolor;
+
+ switch (reduce_drawing_color(&dcolor, edev, pdcolor, &lop)) {
+ case REDUCE_SKIP:
+ return 0;
+ case REDUCE_DRAW:
+ return dev_proc(plane_dev, fill_parallelogram)
+ (plane_dev, px, py, ax, ay, bx, by, &dcolor, lop);
+ default /*REDUCE_FAILED*/:
+ return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by,
+ pdcolor, lop);
+ }
+}
+
+private int
+plane_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_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_device_color dcolor;
+
+ switch (reduce_drawing_color(&dcolor, edev, pdcolor, &lop)) {
+ case REDUCE_SKIP:
+ return 0;
+ case REDUCE_DRAW:
+ return dev_proc(plane_dev, fill_triangle)
+ (plane_dev, px, py, ax, ay, bx, by, &dcolor, lop);
+ default /*REDUCE_FAILED*/:
+ return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by,
+ pdcolor, lop);
+ }
+}
+
+private int
+plane_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 phase_x, int phase_y)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gx_color_index pixel0 = TRANS_COLOR_PIXEL(edev, color0);
+ gx_color_index pixel1 = TRANS_COLOR_PIXEL(edev, color1);
+
+ if (pixel0 == pixel1) {
+ if (pixel0 != gx_no_color_index)
+ return plane_fill_rectangle(dev, x, y, w, h, color0);
+ /* The tile is a pixmap rather than a bitmap. */
+ /* We should use the default implementation if it is small.... */
+ {
+ gx_strip_bitmap plane_tile;
+ tiling_state_t state;
+ long buf[TILE_RECTANGLE_BUF_SIZE / sizeof(long)];
+ int code = begin_tiling(&state, edev, tiles->data, 0, tiles->raster,
+ tiles->size.x, tiles->size.y,
+ (byte *)buf, sizeof(buf), false);
+
+ if (code < 0)
+ return gx_default_strip_tile_rectangle(dev, tiles, x, y, w, h,
+ color0, color1, phase_x, phase_y);
+ extract_partial_tile(&state);
+ plane_tile = *tiles;
+ plane_tile.data = state.buffer.data;
+ plane_tile.raster = state.buffer.raster;
+ plane_tile.id = gx_no_bitmap_id;
+ code = dev_proc(plane_dev, strip_tile_rectangle)
+ (plane_dev, &plane_tile, x, y, w, h, pixel0, pixel1,
+ phase_x, phase_y);
+ end_tiling(&state);
+ edev->any_marks = true;
+ return code;
+ }
+ }
+ if ((pixel0 == edev->plane_white || pixel0 == gx_no_color_index) &&
+ (pixel1 == edev->plane_white || pixel1 == gx_no_color_index)) {
+ /* This operation will only write white. */
+ if (!edev->any_marks)
+ return 0;
+ } else
+ edev->any_marks = true;
+ return dev_proc(plane_dev, strip_tile_rectangle)
+ (plane_dev, tiles, x, y, w, h, pixel0, pixel1, phase_x, phase_y);
+}
+
+private int
+plane_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_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ gs_rop3_t rop = lop_rop(lop);
+ struct crp_ {
+ gx_color_index pixels[2];
+ gx_color_index *colors;
+ tiling_state_t state;
+ } source, texture;
+ long sbuf[COPY_ROP_SOURCE_BUF_SIZE / sizeof(long)];
+ long tbuf[COPY_ROP_TEXTURE_BUF_SIZE / sizeof(long)];
+ const byte *plane_source;
+ uint plane_raster;
+ gx_strip_bitmap plane_texture;
+ const gx_strip_bitmap *plane_textures;
+ int code;
+
+ /* We should do better than this on transparency.... */
+ if (lop & (lop_S_transparent | lop_T_transparent))
+ return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
+ scolors, textures, tcolors,
+ x, y, w, h, phase_x, phase_y, lop);
+ if (!rop3_uses_S(rop)) {
+ sdata = 0;
+ source.colors = 0;
+ } else if (scolors) {
+ source.pixels[0] = COLOR_PIXEL(edev, scolors[0]);
+ source.pixels[1] = COLOR_PIXEL(edev, scolors[1]);
+ if (source.pixels[0] == source.pixels[1])
+ sdata = 0;
+ source.colors = source.pixels;
+ }
+ else
+ source.colors = 0;
+ if (!rop3_uses_T(rop)) {
+ textures = 0;
+ texture.colors = 0;
+ } else if (tcolors) {
+ texture.pixels[0] = COLOR_PIXEL(edev, tcolors[0]);
+ texture.pixels[1] = COLOR_PIXEL(edev, tcolors[1]);
+ if (texture.pixels[0] == texture.pixels[1])
+ textures = 0;
+ texture.colors = texture.pixels;
+ }
+ else
+ texture.colors = 0;
+ if (sdata) {
+ code = begin_tiling(&source.state, edev, sdata, sourcex, sraster, w, y,
+ (byte *)sbuf, sizeof(sbuf), true);
+ if (code < 0)
+ return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
+ scolors, textures, tcolors,
+ x, y, w, h, phase_x, phase_y, lop);
+ plane_source = source.state.buffer.data;
+ plane_raster = source.state.buffer.raster;
+ } else
+ plane_source = 0;
+ if (textures) {
+ code = begin_tiling(&texture.state, edev, textures->data, 0,
+ textures->raster, textures->size.x,
+ textures->size.y, (byte *)tbuf, sizeof(tbuf),
+ false);
+ if (code < 0) {
+ if (plane_source)
+ end_tiling(&source.state);
+ return code;
+ }
+ plane_texture = *textures;
+ plane_texture.data = texture.state.buffer.data;
+ plane_texture.raster = texture.state.buffer.raster;
+ plane_textures = &plane_texture;
+ }
+ if (textures)
+ extract_partial_tile(&texture.state);
+ do {
+ if (sdata)
+ extract_partial_tile(&source.state);
+ code = dev_proc(plane_dev, strip_copy_rop)
+ (plane_dev, plane_source, sourcex, plane_raster, gx_no_bitmap_id,
+ source.colors, plane_textures, texture.colors,
+ x, y, w, h, phase_x, phase_y, lop);
+ } while (code >= 0 && sdata && next_tile(&source.state));
+ if (textures)
+ end_tiling(&texture.state);
+ if (sdata)
+ end_tiling(&source.state);
+ return code;
+}
+
+/* ---------------- Images ---------------- */
+
+/* Define the state for image rendering. */
+typedef struct plane_image_enum_s {
+ gx_image_enum_common;
+ gs_memory_t *memory;
+ gx_image_enum_common_t *info; /* plane device enumerator */
+ const gs_imager_state *pis; /* original imager state */
+ gs_imager_state *pis_image; /* modified imager state */
+} plane_image_enum_t;
+extern_st(st_gx_image_enum_common);
+gs_private_st_suffix_add3(st_plane_image_enum, plane_image_enum_t,
+ "plane_image_enum_t", plane_image_enum_enum_ptrs,
+ plane_image_enum_reloc_ptrs, st_gx_image_enum_common, info, pis, pis_image);
+
+/*
+ * Reduce drawing colors returned by color mapping. Note that these
+ * assume that the call of reduce_drawing_color will not fail:
+ * plane_begin_typed_image must ensure this.
+ *
+ * In the imager state passed to these procedures, the client data is
+ * the plane_image_enum_t.
+ */
+
+private void
+plane_cmap_gray(frac gray, gx_device_color * pdc,
+ const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select)
+{
+ const plane_image_enum_t *ppie =
+ (const plane_image_enum_t *)pis_image->client_data;
+ gx_device_plane_extract * const edev =
+ (gx_device_plane_extract *)ppie->dev;
+ gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image);
+ gx_device_color dcolor;
+
+ gx_remap_concrete_gray(gray, &dcolor, ppie->pis,
+ (gx_device *)edev, select);
+ reduce_drawing_color(pdc, edev, &dcolor, &lop);
+}
+private void
+plane_cmap_rgb(frac r, frac g, frac b, gx_device_color * pdc,
+ const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select)
+{
+ const plane_image_enum_t *ppie =
+ (const plane_image_enum_t *)pis_image->client_data;
+ gx_device_plane_extract * const edev =
+ (gx_device_plane_extract *)ppie->dev;
+ gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image);
+ gx_device_color dcolor;
+
+ gx_remap_concrete_rgb(r, g, b, &dcolor, ppie->pis,
+ (gx_device *)edev, select);
+ reduce_drawing_color(pdc, edev, &dcolor, &lop);
+}
+private void
+plane_cmap_cmyk(frac c, frac m, frac y, frac k, gx_device_color * pdc,
+ const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select)
+{
+ const plane_image_enum_t *ppie =
+ (const plane_image_enum_t *)pis_image->client_data;
+ gx_device_plane_extract * const edev =
+ (gx_device_plane_extract *)ppie->dev;
+ gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image);
+ gx_device_color dcolor;
+
+ gx_remap_concrete_cmyk(c, m, y, k, &dcolor, ppie->pis,
+ (gx_device *)edev, select);
+ reduce_drawing_color(pdc, edev, &dcolor, &lop);
+}
+private void
+plane_cmap_rgb_alpha(frac r, frac g, frac b, frac alpha, gx_device_color * pdc,
+ const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select)
+{
+ const plane_image_enum_t *ppie =
+ (const plane_image_enum_t *)pis_image->client_data;
+ gx_device_plane_extract * const edev =
+ (gx_device_plane_extract *)ppie->dev;
+ gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image);
+ gx_device_color dcolor;
+
+ gx_remap_concrete_rgb_alpha(r, g, b, alpha, &dcolor, ppie->pis,
+ (gx_device *)edev, select);
+ reduce_drawing_color(pdc, edev, &dcolor, &lop);
+}
+private const gx_color_map_procs plane_color_map_procs = {
+ plane_cmap_gray, plane_cmap_rgb, plane_cmap_cmyk, plane_cmap_rgb_alpha
+};
+private const gx_color_map_procs *
+plane_get_cmap_procs(const gs_imager_state *pis, const gx_device *dev)
+{
+ return &plane_color_map_procs;
+}
+
+/* Define the image processing procedures. */
+private image_enum_proc_plane_data(plane_image_plane_data);
+private image_enum_proc_end_image(plane_image_end_image);
+private const gx_image_enum_procs_t plane_image_enum_procs = {
+ plane_image_plane_data, plane_image_end_image
+};
+
+private int
+plane_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)
+{
+ /*
+ * For images, we intercept the imager state's cmap_procs and apply
+ * reduce_drawing_color to the colors as they are returned to the image
+ * processing code. For reasons explained above, we can't do this in
+ * some cases of RasterOp that include transparency.
+ */
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gs_logical_operation_t lop = gs_current_logical_op((const gs_state *)pis);
+ const gs_pixel_image_t *pim;
+ plane_image_enum_t *info = 0;
+ gs_imager_state *pis_image = 0;
+ gx_device_color dcolor;
+ bool uses_color = false;
+ int code;
+
+ /* We can only handle a limited set of image types. */
+ switch (pic->type->index) {
+ case 1: {
+ const gs_image1_t * const pim1 = (const gs_image1_t *)pic;
+
+ if (pim1->Alpha != gs_image_alpha_none)
+ goto fail;
+ uses_color = pim1->ImageMask;
+ break;
+ }
+ case 3:
+ case 4:
+ break;
+ default:
+ goto fail;
+ }
+ pim = (const gs_pixel_image_t *)pic;
+ if ((lop & lop_S_transparent) ||
+ ((uses_color || pim->CombineWithColor) && (lop & lop_T_transparent))
+ )
+ goto fail;
+ if (uses_color || (pim->CombineWithColor && lop_uses_T(lop))) {
+ if (reduce_drawing_color(&dcolor, edev, pdcolor, &lop) ==
+ REDUCE_FAILED)
+ goto fail;
+ } else {
+ /*
+ * The drawing color won't be used, but if RasterOp is involved,
+ * it may still be accessed in some anomalous cases.
+ */
+ color_set_pure(&dcolor, (gx_color_index)0);
+ }
+ info = gs_alloc_struct(memory, plane_image_enum_t, &st_plane_image_enum,
+ "plane_image_begin_typed(info)");
+ pis_image = gs_imager_state_copy(pis, memory);
+ if (pis_image == 0 || info == 0)
+ goto fail;
+ *pis_image = *pis;
+ pis_image->client_data = info;
+ pis_image->get_cmap_procs = plane_get_cmap_procs;
+ code = dev_proc(edev->plane_dev, begin_typed_image)
+ (edev->plane_dev, pis_image, pmat, pic, prect,
+ &dcolor, pcpath, memory, &info->info);
+ if (code < 0)
+ goto fail;
+ *((gx_image_enum_common_t *)info) = *info->info;
+ info->procs = &plane_image_enum_procs;
+ info->dev = (gx_device *)edev;
+ info->id = gs_next_ids(1);
+ info->memory = memory;
+ info->pis = pis;
+ info->pis_image = pis_image;
+ *pinfo = (gx_image_enum_common_t *)info;
+ return code;
+fail:
+ gs_free_object(memory, pis_image, "plane_image_begin_typed(pis_image)");
+ gs_free_object(memory, info, "plane_image_begin_typed(info)");
+ return gx_default_begin_typed_image(dev, pis, pmat, pic, prect,
+ pdcolor, pcpath, memory, pinfo);
+}
+
+private int
+plane_image_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
+{
+ plane_image_enum_t * const ppie = (plane_image_enum_t *)info;
+
+ return gx_image_plane_data_rows(ppie->info, planes, height, rows_used);
+}
+
+private int
+plane_image_end_image(gx_image_enum_common_t * info, bool draw_last)
+{
+ plane_image_enum_t * const ppie = (plane_image_enum_t *)info;
+ int code = gx_image_end(ppie->info, draw_last);
+
+ gs_free_object(ppie->memory, ppie->pis_image,
+ "plane_image_end_image(pis_image)");
+ gs_free_object(ppie->memory, info, "plane_image_end_image(info)");
+ return code;
+}
+
+/* ---------------- Reading back bits ---------------- */
+
+private int
+plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
+ gs_get_bits_params_t * params, gs_int_rect ** unread)
+{
+ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev;
+ gx_device * const plane_dev = edev->plane_dev;
+ int plane_index = edev->plane.index;
+ gs_get_bits_options_t options = params->options;
+ gs_get_bits_params_t plane_params;
+ int plane;
+ int code;
+
+ /*
+ * The only real option that this device supports is single-plane
+ * retrieval. However, for the default case of RasterOp, it must be
+ * able to return chunky pixels in which the other components are
+ * arbitrary (but might as well be zero).
+ */
+ if ((options & GB_PACKING_PLANAR) && (options & GB_SELECT_PLANES)) {
+ if (params->data[plane_index] == 0)
+ return gx_default_get_bits_rectangle(dev, prect, params, unread);
+ /* If the caller wants any other plane(s), punt. */
+ for (plane = 0; plane < dev->color_info.num_components; ++plane)
+ if (plane != plane_index && params->data[plane] != 0)
+ return gx_default_get_bits_rectangle(dev, prect, params, unread);
+ /* Pass the request on to the plane device. */
+ plane_params = *params;
+ plane_params.options =
+ (options & ~(GB_PACKING_ALL | GB_SELECT_PLANES)) |
+ GB_PACKING_CHUNKY;
+ plane_params.data[0] = params->data[plane_index];
+ code = dev_proc(plane_dev, get_bits_rectangle)
+ (plane_dev, prect, &plane_params, unread);
+ if (code >= 0) {
+ *params = plane_params;
+ params->options = (params->options & ~GB_PACKING_ALL) |
+ (GB_PACKING_PLANAR | GB_SELECT_PLANES);
+ params->data[plane_index] = params->data[0];
+ for (plane = 0; plane < dev->color_info.num_components; ++plane)
+ if (plane != plane_index)
+ params->data[plane] = 0;
+ }
+ } else if (!(~options & (GB_COLORS_NATIVE | GB_ALPHA_NONE |
+ GB_PACKING_CHUNKY | GB_RETURN_COPY |
+ GB_ALIGN_STANDARD | GB_OFFSET_0 |
+ GB_RASTER_STANDARD))) {
+ /* Expand the plane into chunky pixels. */
+ bits_plane_t dest, source;
+
+ dest.data.write = params->data[0];
+ dest.raster =
+ bitmap_raster((prect->q.x - prect->p.x) * dev->color_info.depth);
+ dest.depth = edev->color_info.depth;
+ dest.x = 0;
+
+ /* not source.data, source.raster, source.x */
+ source.depth = plane_dev->color_info.depth;
+
+ plane_params = *params;
+ plane_params.options = options &=
+ (~(GB_COLORS_ALL | GB_ALPHA_ALL | GB_PACKING_ALL |
+ GB_RETURN_ALL | GB_ALIGN_ALL | GB_OFFSET_ALL | GB_RASTER_ALL) |
+ GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_PACKING_CHUNKY |
+ /* Try for a pointer return the first time. */
+ GB_RETURN_POINTER |
+ GB_ALIGN_STANDARD |
+ (GB_OFFSET_0 | GB_OFFSET_ANY) |
+ (GB_RASTER_STANDARD | GB_RASTER_ANY));
+ plane_params.raster = gx_device_raster(plane_dev, true);
+ code = dev_proc(plane_dev, get_bits_rectangle)
+ (plane_dev, prect, &plane_params, unread);
+ if (code >= 0) {
+ /* Success, expand the plane into pixels. */
+ source.data.read = plane_params.data[0];
+ source.raster = plane_params.raster;
+ source.x = params->x_offset;
+ code = bits_expand_plane(&dest, &source, edev->plane.shift,
+ prect->q.x - prect->p.x,
+ prect->q.y - prect->p.y);
+ }
+ params->options = (options & ~GB_RETURN_POINTER) | GB_RETURN_COPY;
+ } else
+ return gx_default_get_bits_rectangle(dev, prect, params, unread);
+ return code;
+}
diff --git a/gs/src/gdevplnx.h b/gs/src/gdevplnx.h
new file mode 100644
index 000000000..ce4d64e60
--- /dev/null
+++ b/gs/src/gdevplnx.h
@@ -0,0 +1,75 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+/* Definitions and API for plane extraction device */
+/* Requires gxdevcli.h */
+
+#ifndef gdevplnx_INCLUDED
+# define gdevplnx_INCLUDED
+
+#include "gxrplane.h"
+
+/*
+ * A plane-extraction device appears to its client to be a color-capable
+ * device, like its target; but it actually extracts a single color plane
+ * for rendering to yet another device, called the plane device (normally,
+ * but not necessarily, a memory device). Clients must know the pixel
+ * representation in detail, since the plane is specified as a particular
+ * group of bits within the pixel.
+ *
+ * The original purpose of plane-extraction devices is for band list
+ * rendering for plane-oriented color printers. Each per-plane rasterizing
+ * pass over the band list sends the output to a plane-extraction device for
+ * the plane being printed. There is one special optimization to support
+ * this: on the theory that even bands containing output for multiple bands
+ * are likely to have many objects that only write white into that band, we
+ * remember whether any (non-white) marks have been made on the page so far,
+ * and if not, we simply skip any rendering operations that write white.
+ *
+ * The depth of the plane_extract device and its target are limited to 32
+ * bits; the depth of each plane is limited to 8 bits. We could raise these
+ * without too much trouble if necessary, as long as each plane didn't
+ * exceed 32 bits.
+ */
+
+typedef struct gx_device_plane_extract_s {
+ gx_device_forward_common;
+ /* The following are set by the client before opening the device. */
+ gx_device *plane_dev; /* the drawing device for the plane */
+ gx_render_plane_t plane;
+ /* The following are set by open_device. */
+ gx_color_index plane_white;
+ uint plane_mask;
+ bool plane_dev_is_memory;
+ /* The following change dynamically. */
+ bool any_marks;
+} gx_device_plane_extract;
+extern_st(st_device_plane_extract);
+#define public_st_device_plane_extract() /* in gdevplnx.c */\
+ gs_public_st_complex_only(st_device_plane_extract, gx_device_plane_extract,\
+ "gx_device_plane_extract", 0, device_plane_extract_enum_ptrs,\
+ device_plane_extract_reloc_ptrs, gx_device_finalize)
+
+/* Initialize a plane extraction device. */
+int plane_device_init(P5(gx_device_plane_extract *edev, gx_device *target,
+ gx_device *plane_dev,
+ const gx_render_plane_t *render_plane,
+ bool clear));
+
+#endif /* gdevplnx_INCLUDED */
diff --git a/gs/src/gdevpm.c b/gs/src/gdevpm.c
index 772a1f7ba..a70cd2213 100644
--- a/gs/src/gdevpm.c
+++ b/gs/src/gdevpm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -63,6 +63,7 @@
#include "gdevpm.h"
#ifdef __DLL__
#include "gsdll.h"
+#include "gsdllwin.h"
#endif
#define MIN_COMMIT 4096 /* memory is committed in these size chunks */
@@ -82,8 +83,6 @@ typedef struct gx_device_pm_s gx_device_pm;
#define gx_device_pm_common\
int BitsPerPixel;\
- int alpha_text;\
- int alpha_graphics;\
int UpdateInterval;\
char GSVIEW[pm_gsview_sizeof];\
BOOL dll;\
@@ -125,7 +124,6 @@ private dev_proc_copy_color(pm_copy_color);
private dev_proc_get_bits(pm_get_bits);
private dev_proc_get_params(pm_get_params);
private dev_proc_put_params(pm_put_params);
-private dev_proc_get_alpha_bits(pm_get_alpha_bits);
private gx_device_procs pm_procs =
{
@@ -148,8 +146,7 @@ private gx_device_procs pm_procs =
gx_default_get_xfont_procs,
NULL, /* get_xfont_device */
NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device,
- pm_get_alpha_bits
+ gx_page_device_get_page_device
};
#ifdef __DLL__
@@ -160,7 +157,6 @@ gx_device_pm far_data gs_os2dll_device =
INITIAL_RESOLUTION, INITIAL_RESOLUTION),
{0}, /* std_procs */
8, /* BitsPerPixel */
- 1, 1, /* alpha */
5000, /* UpdateInterval */
"\0", /* GSVIEW */
1 /* is DLL device */
@@ -738,32 +734,6 @@ pm_get_params(gx_device * dev, gs_param_list * plist)
}
/* Put parameters. */
-private int
-pm_put_alpha_param(gs_param_list * plist, gs_param_name param_name, int *pa,
- bool alpha_ok)
-{
- int code = param_read_int(plist, param_name, pa);
-
- switch (code) {
- case 0:
- switch (*pa) {
- case 1:
- return 0;
- case 2:
- case 4:
- if (alpha_ok)
- return 0;
- default:
- code = gs_error_rangecheck;
- }
- default:
- param_signal_error(plist, param_name, code);
- case 1:
- ;
- }
- return code;
-}
-
/* Set PM parameters -- size and resolution. */
/* We implement this ourselves so that we can do it without */
@@ -781,8 +751,6 @@ pm_put_params(gx_device * dev, gs_param_list * plist)
int bpp = old_bpp;
int uii = pmdev->UpdateInterval;
gs_param_string gsvs;
- int atext = pmdev->alpha_text, agraphics = pmdev->alpha_graphics;
- bool alpha_ok;
/* Handle extra parameters */
switch (code = param_read_string(plist, "GSVIEW", &gsvs)) {
@@ -841,12 +809,6 @@ pm_put_params(gx_device * dev, gs_param_list * plist)
break;
}
- alpha_ok = pmdev->color_info.depth >= 8;
- if ((code = pm_put_alpha_param(plist, "TextAlphaBits", &pmdev->alpha_text, alpha_ok)) < 0)
- ecode = code;
- if ((code = pm_put_alpha_param(plist, "GraphicsAlphaBits", &pmdev->alpha_graphics, alpha_ok)) < 0)
- ecode = code;
-
if (ecode >= 0) { /* Prevent gx_default_put_params from closing the device. */
dev->is_open = false;
ecode = gx_default_put_params(dev, plist);
@@ -855,8 +817,6 @@ pm_put_params(gx_device * dev, gs_param_list * plist)
if (ecode < 0) {
if (bpp != old_bpp)
pm_set_bits_per_pixel(pmdev, old_bpp);
- pmdev->alpha_text = atext;
- pmdev->alpha_graphics = agraphics;
return ecode;
}
/* Hand off the change to the implementation. */
@@ -876,8 +836,6 @@ pm_put_params(gx_device * dev, gs_param_list * plist)
dev->width = width;
dev->height = height;
pm_set_bits_per_pixel(pmdev, old_bpp);
- pmdev->alpha_text = atext;
- pmdev->alpha_graphics = agraphics;
pm_alloc_bitmap(pmdev, dev);
DosReleaseMutexSem(pmdev->bmp_mutex);
return ccode;
@@ -919,15 +877,6 @@ pm_put_params(gx_device * dev, gs_param_list * plist)
return 0;
}
-
-/* Get the number of alpha bits. */
-int
-pm_get_alpha_bits(gx_device * dev, graphics_object_type type)
-{
- return (type == go_text ? pmdev->alpha_text : pmdev->alpha_graphics);
-}
-
-
#ifdef __DLL__
/* ------ DLL routines ------ */
/* store at pbitmap the address of the bitmap */
diff --git a/gs/src/gdevpng.c b/gs/src/gdevpng.c
index 29d7898e4..1c2132b6e 100644
--- a/gs/src/gdevpng.c
+++ b/gs/src/gdevpng.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,6 +18,8 @@
/* PNG (Portable Network Graphics) Format. Pronounced "ping". */
+/* lpd 1999-03-08: changed png.h to png_.h to allow compiling with only
+ headers in /usr/include, no source code. */
/* lpd 1997-07-20: changed from using gs_malloc/png_xxx_int to png_create_xxx
* for allocating structures, and from gs_free to png_write_destroy for
* freeing them. */
@@ -36,7 +38,7 @@
#define PNG_INTERNAL
#define PNG_NO_STDIO
-#include "png.h"
+#include "png_.h"
/* ------ The device descriptors ------ */
diff --git a/gs/src/gdevppla.c b/gs/src/gdevppla.c
new file mode 100644
index 000000000..fd6893617
--- /dev/null
+++ b/gs/src/gdevppla.c
@@ -0,0 +1,134 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Support for printer devices with planar buffering. */
+#include "gdevprn.h"
+#include "gdevmpla.h"
+#include "gdevppla.h"
+
+
+/* Set the buf_procs in a printer device to planar mode. */
+int
+gdev_prn_set_procs_planar(gx_device *dev)
+{
+ gx_device_printer * const pdev = (gx_device_printer *)dev;
+
+ pdev->printer_procs.buf_procs.create_buf_device =
+ gdev_prn_create_buf_planar;
+ pdev->printer_procs.buf_procs.size_buf_device =
+ gdev_prn_size_buf_planar;
+ return 0;
+}
+
+/* Open a printer device, conditionally setting it to be planar. */
+int
+gdev_prn_open_planar(gx_device *dev, bool upb)
+{
+ if (upb)
+ gdev_prn_set_procs_planar(dev);
+ return gdev_prn_open(dev);
+}
+
+/* Augment get/put_params to add UsePlanarBuffer. */
+int
+gdev_prn_get_params_planar(gx_device * pdev, gs_param_list * plist,
+ bool *pupb)
+{
+ int ecode = gdev_prn_get_params(pdev, plist);
+
+ if (ecode < 0)
+ return ecode;
+ return param_write_bool(plist, "UsePlanarBuffer", pupb);
+}
+int
+gdev_prn_put_params_planar(gx_device * pdev, gs_param_list * plist,
+ bool *pupb)
+{
+ bool upb = *pupb;
+ int ecode = 0, code;
+ const char *vname;
+
+ if (pdev->color_info.num_components > 1)
+ ecode = param_read_bool(plist, (vname = "UsePlanarBuffer"), &upb);
+ code = gdev_prn_put_params(pdev, plist);
+ if (ecode >= 0)
+ ecode = code;
+ if (ecode >= 0)
+ *pupb = upb;
+ return ecode;
+}
+
+/* Set the buffer device to planar mode. */
+private int
+gdev_prn_set_planar(gx_device_memory *mdev, const gx_device *tdev)
+{
+ int num_comp = tdev->color_info.num_components;
+ gx_render_plane_t planes[4];
+ int depth = tdev->color_info.depth / num_comp;
+
+ if (num_comp < 3 || num_comp > 4)
+ return_error(gs_error_rangecheck);
+ /* Round up the depth per plane to a power of 2. */
+ while (depth & (depth - 1))
+ --depth, depth = (depth | (depth >> 1)) + 1;
+ planes[3].depth = planes[2].depth = planes[1].depth = planes[0].depth =
+ depth;
+ /* We want the most significant plane to come out first. */
+ planes[0].shift = depth * (num_comp - 1);
+ planes[1].shift = planes[0].shift - depth;
+ planes[2].shift = planes[1].shift - depth;
+ planes[3].shift = 0;
+ return gdev_mem_set_planar(mdev, num_comp, planes);
+}
+
+/* Create a planar buffer device. */
+int
+gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target,
+ const gx_render_plane_t *render_plane,
+ gs_memory_t *mem, bool for_band)
+{
+ int code = gx_default_create_buf_device(pbdev, target, render_plane, mem,
+ for_band);
+
+ if (code < 0)
+ return code;
+ if (gs_device_is_memory(*pbdev) /* == render_plane->index < 0 */) {
+ code = gdev_prn_set_planar((gx_device_memory *)*pbdev, *pbdev);
+ }
+ return code;
+}
+
+/* Determine the space needed by a planar buffer device. */
+int
+gdev_prn_size_buf_planar(gx_device_buf_space_t *space, gx_device *target,
+ const gx_render_plane_t *render_plane,
+ int height, bool for_band)
+{
+ gx_device_memory mdev;
+
+ if (render_plane && render_plane->index >= 0)
+ return gx_default_size_buf_device(space, target, render_plane,
+ height, for_band);
+ mdev.color_info = target->color_info;
+ gdev_prn_set_planar(&mdev, target);
+ space->bits = gdev_mem_bits_size(&mdev, target->width, height);
+ space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height);
+ space->raster = bitmap_raster(target->width * mdev.planes[0].depth);
+ return 0;
+}
diff --git a/gs/src/gdevppla.h b/gs/src/gdevppla.h
new file mode 100644
index 000000000..807fb47e6
--- /dev/null
+++ b/gs/src/gdevppla.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Support for printer devices with planar buffering. */
+/* Requires gdevprn.h */
+
+#ifndef gdevppla_INCLUDED
+# define gdevppla_INCLUDED
+
+/* Set the buf_procs in a printer device to planar mode. */
+int gdev_prn_set_procs_planar(P1(gx_device *pdev));
+
+/* Open a printer device, conditionally setting it to be planar. */
+int gdev_prn_open_planar(P2(gx_device *pdev, bool upb));
+
+/* Augment get/put_params to add UsePlanarBuffer. */
+int gdev_prn_get_params_planar(P3(gx_device * pdev, gs_param_list * plist,
+ bool *pupb));
+int gdev_prn_put_params_planar(P3(gx_device * pdev, gs_param_list * plist,
+ bool *pupb));
+
+/* Create a planar buffer device. */
+/* Use this instead of the default if UsePlanarBuffer is true. */
+int gdev_prn_create_buf_planar(P5(gx_device **pbdev, gx_device *target,
+ const gx_render_plane_t *render_plane,
+ gs_memory_t *mem, bool for_band));
+
+/* Determine the space needed by a planar buffer device. */
+/* Use this instead of the default if UsePlanarBuffer is true. */
+int gdev_prn_size_buf_planar(P5(gx_device_buf_space_t *space,
+ gx_device *target,
+ const gx_render_plane_t *render_plane,
+ int height, bool for_band));
+
+#endif /* gdevppla_INCLUDED */
diff --git a/gs/src/gdevprn.c b/gs/src/gdevprn.c
index 37f136604..019f38b6b 100644
--- a/gs/src/gdevprn.c
+++ b/gs/src/gdevprn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,8 +21,32 @@
#include "ctype_.h"
#include "gdevprn.h"
#include "gp.h"
+#include "gsdevice.h" /* for gs_deviceinitialmatrix */
#include "gsparam.h"
#include "gxclio.h"
+#include "gxgetbit.h"
+#include "gdevplnx.h"
+
+/*#define DEBUGGING_HACKS*/
+
+/* GC information */
+#define PRINTER_IS_CLIST(pdev) ((pdev)->buffer_space != 0)
+public
+ENUM_PTRS_WITH(device_printer_enum_ptrs, gx_device_printer *pdev)
+ if (PRINTER_IS_CLIST(pdev))
+ ENUM_PREFIX(st_device_clist, 0);
+ else
+ ENUM_PREFIX(st_device_forward, 0);
+ENUM_PTRS_END
+public
+RELOC_PTRS_WITH(device_printer_reloc_ptrs, gx_device_printer *pdev)
+{
+ if (PRINTER_IS_CLIST(pdev))
+ RELOC_PREFIX(st_device_clist);
+ else
+ RELOC_PREFIX(st_device_forward);
+} RELOC_PTRS_END
+public_st_device_printer();
/* ---------------- Standard device procedures ---------------- */
@@ -31,9 +55,9 @@ 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));
+int gdev_prn_maybe_realloc_memory(P4(gx_device_printer *pdev,
+ gdev_prn_space_params *old_space,
+ int old_width, int old_height));
/* ------ Open/close ------ */
@@ -84,27 +108,23 @@ gdev_prn_setup_as_command_list(gx_device *pdev, gs_memory_t *buffer_memory,
bool reallocate = *the_memory != 0;
byte *base;
- space = space_params->BufferSpace;
- /* Adjust existing size (reallocate) or get new Buffer. If can't get */
- /* requested size, and not constrained to 'exact', reduce space till */
- /* allocation succeeds. */
- for ( ; ; ) {
- if (reallocate)
-#if DO_NOT_REDUCE_BUFFER_SPACE
- /* If 'reallocate' to smaller size, don't free up memory to */
- /* avoid creating sandbar that wouldn't allow the resize */
- /* back to larger size */
- base = (space <= gs_object_size(buffer_memory, *the_memory)) ?
- *the_memory : /* just reuse the space */
- gs_resize_object(buffer_memory, *the_memory, space,
- "cmd list buffer");
-#else /* free up any space beyond what is needed */
- base = gs_resize_object(buffer_memory, *the_memory, space,
- "cmd list buffer");
-#endif
- else
- base = gs_alloc_bytes(buffer_memory, space,
- "cmd list buffer");
+ /* Try to allocate based simply on param-requested buffer size */
+#ifdef DEBUGGING_HACKS
+#define BACKTRACE(first_arg)\
+ BEGIN\
+ ulong *fp_ = (ulong *)&first_arg - 2;\
+ for (; fp_ && (fp_[1] & 0xff000000) == 0x08000000; fp_ = (ulong *)*fp_)\
+ dprintf2(" fp=0x%lx ip=0x%lx\n", (ulong)fp_, fp_[1]);\
+ END
+dputs("alloc buffer:\n");
+BACKTRACE(pdev);
+#endif /*DEBUGGING_HACKS*/
+ for ( space = space_params->BufferSpace; ; ) {
+ base = (reallocate ?
+ (byte *)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)
@@ -120,7 +140,7 @@ open_c:
ppdev->buf = base;
ppdev->buffer_space = space;
clist_init_params(pclist_dev, base, space, pdev,
- ppdev->printer_procs.make_buffer_device,
+ ppdev->printer_procs.buf_procs,
space_params->band, ppdev->is_async_renderer,
(ppdev->bandlist_memory == 0 ? &gs_memory_default :
ppdev->bandlist_memory),
@@ -136,7 +156,7 @@ open_c:
) {
space <<= 1;
if (reallocate) {
- base = gs_resize_object(buffer_memory,
+ base = gs_resize_object(buffer_memory,
*the_memory, space,
"cmd list buf(retry open)");
if (base != 0)
@@ -220,8 +240,10 @@ gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params,
ulong mem_space;
byte *base = 0;
bool bufferSpace_is_default = false;
- gdev_prn_space_params space_params = ppdev->space_params;
+ gdev_prn_space_params space_params;
+ gx_device_buf_space_t buf_space;
+ space_params = ppdev->space_params;
if (reallocate)
switch (pass)
{
@@ -244,7 +266,9 @@ gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params,
/* Init clist/mem device-specific fields */
memset(ppdev->skip, 0, sizeof(ppdev->skip));
- mem_space = gdev_mem_bitmap_size(pmemdev);
+ ppdev->printer_procs.buf_procs.size_buf_device
+ (&buf_space, pdev, NULL, pdev->height, false);
+ mem_space = buf_space.bits + buf_space.line_ptrs;
/* Compute desired space params: never use the space_params as-is. */
/* Rather, give the dev-specific driver a chance to adjust them. */
@@ -271,11 +295,12 @@ gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params,
}
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" );
+ base =
+ (reallocate ?
+ (byte *)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
@@ -315,12 +340,19 @@ gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params,
ppdev->procs = gs_clist_device_procs;
} else {
/* Render entirely in memory. */
+ gx_device *bdev = (gx_device *)pmemdev;
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 */
+ if ((code = gdev_create_buf_device
+ (ppdev->printer_procs.buf_procs.create_buf_device,
+ &bdev, pdev, NULL, NULL, false)) < 0 ||
+ (code = ppdev->printer_procs.buf_procs.setup_buf_device
+ (bdev, base, buf_space.raster,
+ (byte **)(base + buf_space.bits), 0, pdev->height,
+ pdev->height)) < 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 */
@@ -351,7 +383,6 @@ gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params,
/* 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);
@@ -649,7 +680,7 @@ label:\
/* 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);
+ code = gdev_prn_maybe_realloc_memory(ppdev, &save_sp, width, height);
if (code < 0)
return code;
@@ -680,8 +711,8 @@ label:\
/* Default routine to (not) override current space_params. */
void
-gdev_prn_default_get_space_params(const gx_device_printer *printer_dev,
- gdev_prn_space_params *space_params)
+gx_default_get_space_params(const gx_device_printer *printer_dev,
+ gdev_prn_space_params *space_params)
{
return;
}
@@ -719,8 +750,8 @@ gdev_prn_output_page(gx_device * pdev, int num_copies, int flush)
if (!upgraded_copypage)
closecode = gdev_prn_close_printer(pdev);
}
- endcode = (ppdev->buffer_space && !ppdev->is_async_renderer
- ? clist_finish_page(pdev, flush) : 0);
+ endcode = (ppdev->buffer_space && !ppdev->is_async_renderer ?
+ clist_finish_page(pdev, flush) : 0);
if (outcode < 0)
return outcode;
@@ -761,6 +792,38 @@ gx_default_buffer_page(gx_device_printer *pdev, FILE *prn_stream,
/* ---------------- Driver services ---------------- */
+/* Initialize a rendering plane specification. */
+int
+gx_render_plane_init(gx_render_plane_t *render_plane, const gx_device *dev,
+ int index)
+{
+ /*
+ * Eventually the computation of shift and depth from dev and index
+ * will be made device-dependent.
+ */
+ int num_planes = dev->color_info.num_components;
+ int plane_depth = dev->color_info.depth / num_planes;
+
+ if (index < 0 || index >= num_planes)
+ return_error(gs_error_rangecheck);
+ render_plane->index = index;
+ render_plane->depth = plane_depth;
+ render_plane->shift = plane_depth * (num_planes - 1 - index);
+ return 0;
+}
+
+/* Clear trailing bits in the last byte of (a) scan line(s). */
+void
+gdev_prn_clear_trailing_bits(byte *data, uint raster, int height,
+ const gx_device *dev)
+{
+ int first_bit = dev->width * dev->color_info.depth;
+
+ if (first_bit & 7)
+ bits_fill_rectangle(data, first_bit, raster, mono_fill_make_pattern(0),
+ -first_bit & 7, height);
+}
+
/* Return the number of scan lines that should actually be passed */
/* to the device. */
int
@@ -786,8 +849,8 @@ gdev_prn_print_scan_lines(gx_device * pdev)
/* Open the current page for printing. */
int
-gdev_prn_open_printer_positionable(gx_device *pdev, bool binary_mode,
- bool positionable)
+gdev_prn_open_printer_seekable(gx_device *pdev, bool binary_mode,
+ bool seekable)
{
gx_device_printer * const ppdev = (gx_device_printer *)pdev;
@@ -797,7 +860,7 @@ gdev_prn_open_printer_positionable(gx_device *pdev, bool binary_mode,
}
{
int code = gx_device_open_output_file(pdev, ppdev->fname,
- binary_mode, positionable,
+ binary_mode, seekable,
&ppdev->file);
if (code < 0)
return code;
@@ -808,9 +871,273 @@ gdev_prn_open_printer_positionable(gx_device *pdev, bool binary_mode,
int
gdev_prn_open_printer(gx_device *pdev, bool binary_mode)
{
- return gdev_prn_open_printer_positionable(pdev, binary_mode, false);
+ return gdev_prn_open_printer_seekable(pdev, binary_mode, false);
+}
+
+/* Determine the colors used in a range of lines. */
+int
+gx_page_info_colors_used(const gx_device *dev,
+ const gx_band_page_info_t *page_info,
+ int y, int height,
+ gx_colors_used_t *colors_used, int *range_start)
+{
+ int start, end, i;
+ int num_lines = page_info->scan_lines_per_colors_used;
+ gx_color_index or = 0;
+ bool slow_rop = false;
+
+ if (y < 0 || height < 0 || height > dev->height - y)
+ return -1;
+ start = y / num_lines;
+ end = (y + height + num_lines - 1) / num_lines;
+ for (i = start; i < end; ++i) {
+ or |= page_info->band_colors_used[i].or;
+ slow_rop |= page_info->band_colors_used[i].slow_rop;
+ }
+ colors_used->or = or;
+ colors_used->slow_rop = slow_rop;
+ *range_start = start * num_lines;
+ return min(end * num_lines, dev->height) - *range_start;
+}
+int
+gdev_prn_colors_used(gx_device *dev, int y, int height,
+ gx_colors_used_t *colors_used, int *range_start)
+{
+ gx_device_clist_writer *cldev;
+
+ /* If this isn't a banded device, return default values. */
+ if (dev_proc(dev, get_bits_rectangle) !=
+ gs_clist_device_procs.get_bits_rectangle
+ ) {
+ *range_start = 0;
+ colors_used->or = ((gx_color_index)1 << dev->color_info.depth) - 1;
+ return dev->height;
+ }
+ cldev = (gx_device_clist_writer *)dev;
+ if (cldev->page_info.scan_lines_per_colors_used == 0) /* not set yet */
+ clist_compute_colors_used(cldev);
+ return
+ gx_page_info_colors_used(dev, &cldev->page_info,
+ y, height, colors_used, range_start);
+}
+
+/*
+ * Create the buffer device for a printer device. Clients should always
+ * call this, and never call the device procedure directly.
+ */
+int
+gdev_create_buf_device(create_buf_device_proc_t cbd_proc, gx_device **pbdev,
+ gx_device *target,
+ const gx_render_plane_t *render_plane,
+ gs_memory_t *mem, bool for_band)
+{
+ int code = cbd_proc(pbdev, target, render_plane, mem, for_band);
+
+ if (code < 0)
+ return code;
+ /* Retain this device -- it will be freed explicitly. */
+ gx_device_retain(*pbdev, true);
+ return code;
}
+/*
+ * Create an ordinary memory device for page or band buffering,
+ * possibly preceded by a plane extraction device.
+ */
+int
+gx_default_create_buf_device(gx_device **pbdev, gx_device *target,
+ const gx_render_plane_t *render_plane, gs_memory_t *mem, bool for_band)
+{
+ int plane_index = (render_plane ? render_plane->index : -1);
+ int depth;
+ const gx_device_memory *mdproto;
+ gx_device_memory *mdev;
+ gx_device *bdev;
+
+ if (plane_index >= 0)
+ depth = render_plane->depth;
+ else
+ depth = target->color_info.depth;
+ mdproto = gdev_mem_device_for_bits(depth);
+ if (mdproto == 0)
+ return_error(gs_error_rangecheck);
+ if (mem) {
+ mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
+ "create_buf_device");
+ if (mdev == 0)
+ return_error(gs_error_VMerror);
+ } else {
+ mdev = (gx_device_memory *)*pbdev;
+ }
+ if (target == (gx_device *)mdev) {
+ /* The following is a special hack for setting up printer devices. */
+ assign_dev_procs(mdev, mdproto);
+ } else
+ gs_make_mem_device(mdev, mdproto, mem, (for_band ? 1 : 0),
+ (target == (gx_device *)mdev ? NULL : target));
+ mdev->width = target->width;
+ /*
+ * The matrix in the memory device is irrelevant,
+ * because all we do with the device is call the device-level
+ * output procedures, but we may as well set it to
+ * something halfway reasonable.
+ */
+ gs_deviceinitialmatrix(target, &mdev->initial_matrix);
+ if (plane_index >= 0) {
+ gx_device_plane_extract *edev =
+ gs_alloc_struct(mem, gx_device_plane_extract,
+ &st_device_plane_extract, "create_buf_device");
+
+ if (edev == 0) {
+ gx_default_destroy_buf_device((gx_device *)mdev);
+ return_error(gs_error_VMerror);
+ }
+ edev->memory = mem;
+ plane_device_init(edev, target, (gx_device *)mdev, render_plane,
+ false);
+ bdev = (gx_device *)edev;
+ } else
+ bdev = (gx_device *)mdev;
+ /****** QUESTIONABLE, BUT BETTER THAN OMITTING ******/
+ bdev->color_info = target->color_info;
+ *pbdev = bdev;
+ return 0;
+}
+
+/* Determine the space needed by the buffer device. */
+int
+gx_default_size_buf_device(gx_device_buf_space_t *space, gx_device *target,
+ const gx_render_plane_t *render_plane,
+ int height, bool for_band)
+{
+ gx_device_memory mdev;
+
+ mdev.color_info.depth =
+ (render_plane && render_plane->index >= 0 ? render_plane->depth :
+ target->color_info.depth);
+ mdev.width = target->width;
+ mdev.num_planes = 0;
+ space->bits = gdev_mem_bits_size(&mdev, target->width, height);
+ space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height);
+ space->raster = gdev_mem_raster(&mdev);
+ return 0;
+}
+
+/* Set up the buffer device. */
+int
+gx_default_setup_buf_device(gx_device *bdev, byte *buffer, int bytes_per_line,
+ byte **line_ptrs, int y, int setup_height,
+ int full_height)
+{
+ gx_device_memory *mdev =
+ (gs_device_is_memory(bdev) ? (gx_device_memory *)bdev :
+ (gx_device_memory *)(((gx_device_plane_extract *)bdev)->plane_dev));
+ byte **ptrs = line_ptrs;
+ int raster = bytes_per_line;
+ int code;
+
+ /****** HACK ******/
+ if ((gx_device *)mdev == bdev && mdev->num_planes)
+ raster = bitmap_raster(mdev->planes[0].depth * mdev->width);
+ if (ptrs == 0) {
+ /*
+ * Allocate line pointers now; free them when we close the device.
+ * Note that for multi-planar devices, we have to allocate using
+ * full_height rather than setup_height.
+ */
+ ptrs = (byte **)
+ gs_alloc_byte_array(mdev->memory,
+ (mdev->num_planes ?
+ full_height * mdev->num_planes :
+ setup_height),
+ sizeof(byte *), "setup_buf_device");
+ if (ptrs == 0)
+ return_error(gs_error_VMerror);
+ mdev->line_pointer_memory = mdev->memory;
+ mdev->foreign_line_pointers = false;
+ }
+ mdev->height = full_height;
+ code = gdev_mem_set_line_ptrs(mdev, buffer + raster * y, bytes_per_line,
+ ptrs, setup_height);
+ mdev->height = setup_height;
+ bdev->height = setup_height; /* do here in case mdev == bdev */
+ return code;
+}
+
+/* Destroy the buffer device. */
+void
+gx_default_destroy_buf_device(gx_device *bdev)
+{
+ gx_device *mdev = bdev;
+
+ if (!gs_device_is_memory(bdev)) {
+ /* bdev must be a plane extraction device. */
+ mdev = ((gx_device_plane_extract *)bdev)->plane_dev;
+ gs_free_object(bdev->memory, bdev, "destroy_buf_device");
+ }
+ dev_proc(mdev, close_device)(mdev);
+ gs_free_object(mdev->memory, mdev, "destroy_buf_device");
+}
+
+/*
+ * Copy one or more rasterized scan lines to a buffer, or return a pointer
+ * to them. See gdevprn.h for detailed specifications.
+ */
+int
+gdev_prn_get_lines(gx_device_printer *pdev, int y, int height,
+ byte *buffer, uint bytes_per_line,
+ byte **actual_buffer, uint *actual_bytes_per_line,
+ const gx_render_plane_t *render_plane)
+{
+ int code;
+ gs_int_rect rect;
+ gs_get_bits_params_t params;
+ int plane;
+
+ if (y < 0 || height < 0 || y + height > pdev->height)
+ return_error(gs_error_rangecheck);
+ rect.p.x = 0, rect.p.y = y;
+ rect.q.x = pdev->width, rect.q.y = y + height;
+ params.options =
+ GB_RETURN_POINTER | GB_ALIGN_STANDARD | GB_OFFSET_0 |
+ GB_RASTER_ANY |
+ /* No depth specified, we always use native colors. */
+ GB_COLORS_NATIVE | GB_ALPHA_NONE;
+ if (render_plane) {
+ params.options |= GB_PACKING_PLANAR | GB_SELECT_PLANES;
+ memset(params.data, 0,
+ sizeof(params.data[0]) * pdev->color_info.num_components);
+ plane = render_plane->index;
+ params.data[plane] = buffer;
+ } else {
+ params.options |= GB_PACKING_CHUNKY;
+ params.data[0] = buffer;
+ plane = 0;
+ }
+ params.x_offset = 0;
+ params.raster = bytes_per_line;
+ code = dev_proc(pdev, get_bits_rectangle)
+ ((gx_device *)pdev, &rect, &params, NULL);
+ if (code < 0 && actual_buffer) {
+ /*
+ * RETURN_POINTER might not be implemented for this
+ * combination of parameters: try RETURN_COPY.
+ */
+ params.options &= ~(GB_RETURN_POINTER | GB_RASTER_ALL);
+ params.options |= GB_RETURN_COPY | GB_RASTER_SPECIFIED;
+ code = dev_proc(pdev, get_bits_rectangle)
+ ((gx_device *)pdev, &rect, &params, NULL);
+ }
+ if (code < 0)
+ return code;
+ if (actual_buffer)
+ *actual_buffer = params.data[plane];
+ if (actual_bytes_per_line)
+ *actual_bytes_per_line = params.raster;
+ return code;
+}
+
+
/* 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)
@@ -829,7 +1156,7 @@ gdev_prn_get_bits(gx_device_printer * pdev, int y, byte * str, byte ** actual_da
return 0;
}
/* Copy scan lines to a buffer. Return the number of scan lines, */
-/* or <0 if error. */
+/* or <0 if error. This procedure is DEPRECATED. */
int
gdev_prn_copy_scan_lines(gx_device_printer * pdev, int y, byte * str, uint size)
{
@@ -848,36 +1175,6 @@ gdev_prn_copy_scan_lines(gx_device_printer * pdev, int y, byte * str, uint size)
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)
@@ -895,22 +1192,37 @@ gdev_prn_close_printer(gx_device * pdev)
/* 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)
+gdev_prn_maybe_realloc_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;
-
- if (prdev->is_open != 0 &&
+ /*gx_device_memory * const mdev = (gx_device_memory *)prdev;*/
+
+ /*
+ * The first test was changed to mdev->base != 0 in 5.50 (per Artifex).
+ * Not only was this test wrong logically, it was incorrect in that
+ * casting pdev to a (gx_device_memory *) is only meaningful if banding
+ * is not being used. The test was changed back to prdev->is_open in
+ * 5.67 (also per Artifex). For more information, see the News items
+ * for these filesets.
+ */
+ if (prdev->is_open &&
(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;
-
+ gdev_prn_space_params new_sp;
+
+#ifdef DEBUGGING_HACKS
+debug_dump_bytes((const byte *)old_sp, (const byte *)(old_sp + 1), "old");
+debug_dump_bytes((const byte *)&prdev->space_params,
+ (const byte *)(&prdev->space_params + 1), "new");
+dprintf4("w=%d/%d, h=%d/%d\n", old_width, new_width, old_height, new_height);
+#endif /*DEBUGGING_HACKS*/
+ new_sp = prdev->space_params;
prdev->width = old_width;
prdev->height = old_height;
prdev->space_params = *old_sp;
diff --git a/gs/src/gdevprn.h b/gs/src/gdevprn.h
index 6b475e062..16527f25c 100644
--- a/gs/src/gdevprn.h
+++ b/gs/src/gdevprn.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,6 +32,7 @@
#include "gxdevice.h"
#include "gxdevmem.h"
#include "gxclist.h"
+#include "gxrplane.h"
#include "gsparam.h"
/*
@@ -121,10 +122,12 @@ typedef struct gx_printer_device_procs_s {
/* 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.) */
+ /*
+ * Define buffer device management procedures.
+ * See gxdevcli.h for the definitions.
+ */
- dev_proc_make_buffer_device((*make_buffer_device));
+ gx_device_buf_procs_t buf_procs;
/*
* Compute effective space params. These results effectively override
@@ -182,52 +185,21 @@ typedef struct gx_printer_device_procs_s {
* 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.
+ * buffer. Note that, after the first buffer_page, the driver must call
+ * the lower-level gdev_prn_render_lines procedure instead of
+ * get_bits. The difference is that gdev_prn_render_lines requires the
+ * caller to supply the same buffered bitmap that was computed as a
+ * result of a previous buffer_page, so that gdev_prn_render_lines 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.
- */
+ * 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 ------ */
@@ -286,6 +258,12 @@ struct gx_device_printer_s {
gx_prn_device_common;
};
+extern_st(st_device_printer);
+#define public_st_device_printer() /* in gdevprn.c */\
+ gs_public_st_complex_only(st_device_printer, gx_device_printer,\
+ "gx_device_printer", 0, device_printer_enum_ptrs,\
+ device_printer_reloc_ptrs, gx_device_finalize)
+
/* Define a typedef for the sake of ansi2knr. */
typedef dev_proc_print_page((*dev_proc_print_page_t));
@@ -299,13 +277,14 @@ 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);
+/* VMS limits procedure names to 31 characters. */
+prn_dev_proc_get_space_params(gx_default_get_space_params);
+/* BACKWARD COMPATIBILITY */
+#define gdev_prn_default_get_space_params gx_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)\
@@ -381,14 +360,16 @@ extern const gx_device_procs prn_std_procs;
{ 0 }, /* skip */\
{ print_page,\
gx_default_print_page_copies,\
- gx_default_make_buffer_device,\
+ { gx_default_create_buf_device,\
+ gx_default_size_buf_device,\
+ gx_default_setup_buf_device,\
+ gx_default_destroy_buf_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\
+ gx_default_buffer_page\
},\
{ PRN_MAX_BITMAP, PRN_BUFFER_SPACE,\
{ BAND_PARAMS_INITIAL_VALUES },\
@@ -406,7 +387,7 @@ extern const gx_device_procs prn_std_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,\
+ std_device_full_body_type(dtype, &procs, dname, &st_device_printer,\
(int)((long)(w10) * (xdpi) / 10),\
(int)((long)(h10) * (ydpi) / 10),\
xdpi, ydpi,\
@@ -422,7 +403,7 @@ extern const gx_device_procs prn_std_procs;
lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)
#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,\
+ std_device_std_color_full_body_type(dtype, &procs, dname, &st_device_printer,\
(int)((long)(w10) * (xdpi) / 10),\
(int)((long)(h10) * (ydpi) / 10),\
xdpi, ydpi, color_bits,\
@@ -448,22 +429,143 @@ extern const gx_device_procs prn_std_procs;
/* ------ Utilities ------ */
/* These are defined in gdevprn.c. */
-int gdev_prn_open_printer_positionable(P3(gx_device *dev, bool binary_mode,
- bool positionable));
+/*
+ * Open the printer's output file if necessary.
+ */
+/* VMS limits procedure names to 31 characters. */
+int gdev_prn_open_printer_seekable(P3(gx_device *dev, bool binary_mode,
+ bool seekable));
+/* BACKWARD COMPATIBILITY */
+#define gdev_prn_open_printer_positionable gdev_prn_open_printer_seekable
/* open_printer defaults positionable = false */
int gdev_prn_open_printer(P2(gx_device * dev, bool binary_mode));
+/*
+ * Test whether the printer's output file was just opened, i.e., whether
+ * this is the first page being written to this file. The result is only
+ * valid immediately after calling open_printer[_positionable].
+ */
#define gdev_prn_file_is_new(pdev) ((pdev)->file_is_new)
+
+/*
+ * Determine the number of bytes required for one scan line of output to
+ * a printer device, without any padding.
+ */
#define gdev_prn_raster(pdev) gx_device_raster((gx_device *)(pdev), 0)
-int gdev_prn_get_bits(P4(gx_device_printer *, int, byte *, byte **));
+
+/*
+ * Determine (conservatively) what colors are used in a given range of scan
+ * lines, and return the actual range of scan lines to which the result
+ * applies. (Currently, the result will always actually apply to one or
+ * more full bands.) In the non-banded case, this information is currently
+ * not available, so we return all-1s (i.e., any color may appear) as the
+ * 'or', and the entire page as the range; we may improve this someday.
+ *
+ * The return value is like get_band: the first Y value of the actual range
+ * is stored in *range_start, and the height of the range is returned.
+ * If the parameters are invalid, the procedure returns -1.
+ */
+int gdev_prn_colors_used(P5(gx_device *dev, int y, int height,
+ gx_colors_used_t *colors_used,
+ int *range_start));
+/*
+ * Determine the colors used in a saved page. We still need the device
+ * in order to know the total page height.
+ */
+int gx_page_info_colors_used(P6(const gx_device *dev,
+ const gx_band_page_info_t *page_info,
+ int y, int height,
+ gx_colors_used_t *colors_used,
+ int *range_start));
+
+/*
+ * Render a subrectangle of the page into a target device provided by the
+ * caller, optionally clearing the device before rendering. The rectangle
+ * need not coincide exactly with band boundaries, but it will be most
+ * efficient if they do, since it is necessary to render every band that
+ * even partly falls within the rectangle. This is the lowest-level
+ * rendering procedure: the other procedures for reading rasterized lines,
+ * defined below, ultimately call this one.
+ *
+ * render_plane is used only for internal cache bookkeeping: it doesn't
+ * affect what is passed to the buffer device. It is the client's
+ * responsibility to set up a plane extraction device, if required, to
+ * select an individual plane for rendering.
+ *
+ * Note that it may be necessary to render more than one plane even if the
+ * caller only requests a single plane. Currently this only occurs for
+ * non-trivial RasterOps on CMYK devices. If this is the case, it is the
+ * client's responsibility to provide a target device that accumulates full
+ * pixels rather than a single plane: if the plane extraction device is
+ * asked to execute an operation that requires full pixels, it will return
+ * an error.
+ */
+int gdev_prn_render_rectangle(P5(gx_device_printer *pdev,
+ const gs_int_rect *prect,
+ gx_device *target,
+ const gx_render_plane_t *render_plane,
+ bool clear));
+
+/*
+ * Read one or more rasterized scan lines for printing.
+ * The procedure either copies the scan lines into the buffer and
+ * sets *actual_buffer = buffer and *actual_bytes_per_line = bytes_per_line,
+ * or sets *actual_buffer and *actual_bytes_per_line to reference
+ * already-rasterized scan lines.
+ *
+ * For non-banded devices, copying is never necessary. For banded devices,
+ * if the client's buffer is at least as large as the single preallocated
+ * one (if any), the band will be rasterized directly into the client's
+ * buffer, again avoiding copying. Alternatively, if there is a
+ * preallocated buffer and the call asks for no more data than will fit
+ * in that buffer, buffer may be NULL: any necessary rasterizing will
+ * occur in the preallocated buffer, and a pointer into the buffer will be
+ * returned.
+ */
+int gdev_prn_get_lines(P8(gx_device_printer *pdev, int y, int height,
+ byte *buffer, uint bytes_per_line,
+ byte **actual_buffer, uint *actual_bytes_per_line,
+ const gx_render_plane_t *render_plane));
+
+/*
+ * Read a rasterized scan line for sending to the printer.
+ * This is essentially a simplified form of gdev_prn_get_lines,
+ * except that it also calls gdev_prn_clear_trailing_bits.
+ */
+int gdev_prn_get_bits(P4(gx_device_printer *pdev, int y, byte *buffer,
+ byte **actual_buffer));
+
+/*
+ * Copy scan lines to send to the printer. This is now DEPRECATED,
+ * because it copies the data even if the data are already available in
+ * the right form in the rasterizer buffer. Use gdev_prn_get_bits
+ * instead. For documentation, see the implementation in gdevprn.c.
+ */
int gdev_prn_copy_scan_lines(P4(gx_device_printer *, int, byte *, uint));
+
+/*
+ * Clear any trailing bits in the last byte of one or more scan lines
+ * returned from the calls for reading out rasterized data. Note that
+ * the device is only used to get the width and depth, and need not be
+ * a printer device.
+ */
+void gdev_prn_clear_trailing_bits(P4(byte *data, uint raster, int height,
+ const gx_device *dev));
+
+/*
+ * Close the printer's output file.
+ */
int gdev_prn_close_printer(P1(gx_device *));
-/* The default print_page_copies procedure just calls print_page */
-/* the given number of times. */
+/*
+ * Define a 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. */
+/*
+ * Determine 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. */
@@ -475,6 +577,18 @@ int gdev_prn_reallocate_memory(P4(gx_device *pdev,
int new_width, int new_height));
int gdev_prn_free_memory(P1(gx_device *pdev));
+/*
+ * Create the buffer device for a printer device. Clients should always
+ * call this, and never call the device procedure directly. The actual
+ * create_buf_device procedure is passed as an argument because the banding
+ * code needs this: normally it is dev_proc(some_dev, create_buf_device).
+ */
+typedef dev_proc_create_buf_device((*create_buf_device_proc_t));
+int gdev_create_buf_device(P6(create_buf_device_proc_t cbd_proc,
+ gx_device **pbdev, gx_device *target,
+ const gx_render_plane_t *render_plane,
+ gs_memory_t *mem, bool for_band));
+
/* BACKWARD COMPATIBILITY */
#define dev_print_scan_lines(dev)\
gdev_prn_print_scan_lines((gx_device *)(dev))
@@ -487,7 +601,6 @@ int gdev_prn_free_memory(P1(gx_device *pdev));
/**************** 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((*))));
diff --git a/gs/src/gdevprna.h b/gs/src/gdevprna.h
index bb05d0437..c8ea45210 100644
--- a/gs/src/gdevprna.h
+++ b/gs/src/gdevprna.h
@@ -122,17 +122,15 @@
* 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.
+ * 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. 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 --------------- */
diff --git a/gs/src/gdevps.c b/gs/src/gdevps.c
index 7154c10b9..2ae268164 100644
--- a/gs/src/gdevps.c
+++ b/gs/src/gdevps.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,15 +31,15 @@
#include "gxdevice.h"
#include "gscspace.h"
#include "gxdcolor.h"
-#include "gzpath.h"
+#include "gxpath.h"
#include "gdevpsdf.h"
#include "gdevpstr.h"
+#include "sstring.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.
****************************************************************/
@@ -64,7 +64,7 @@ private dev_proc_begin_image(psw_begin_image);
typedef struct psw_path_state_s {
int num_points; /* # of points since last non-lineto */
- bool move; /* true iff last non-lineto was moveto */
+ int move; /* 1 iff last non-lineto was moveto, else 0 */
gs_point dprev[2]; /* line deltas before previous point, */
/* if num_points - move >= 2 */
} psw_path_state_t;
@@ -161,7 +161,7 @@ const gx_device_pswrite gs_epswrite_device =
/* Vector device implementation */
private int
- psw_beginpage(P1(gx_device_vector * vdev)), psw_setlinewidth(P2(gx_device_vector * vdev, floatp width)),
+ psw_beginpage(P1(gx_device_vector * vdev)),
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)),
@@ -178,7 +178,7 @@ private const gx_device_vector_procs psw_vector_procs =
/* Page management */
psw_beginpage,
/* Imager state */
- psw_setlinewidth,
+ psdf_setlinewidth,
psdf_setlinecap,
psdf_setlinejoin,
psdf_setmiterlimit,
@@ -244,16 +244,19 @@ private const char *const psw_prolog[] =
"/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}!",
/* <x> <y> <dx> <dy> re - */
"/re{4 -2 roll m exch dup lx exch ly neg lx h}!",
- /* <x> <y> <a> <b> ^ <x> <y> <a> <b> <-a> <-y> */
+ /* <x> <y> <a> <b> ^ <x> <y> <a> <b> <-x> <-y> */
"/^{3 index neg 3 index neg}!",
/* <x> <y> <dx1> <dy1> ... <dxn> <dyn> P - */
"/P{count 0 gt{count -2 roll moveto p}if}!",
/* <dx1> <dy1> ... <dxn> <dyn> 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}!",
+ "/f{P fill}!/f*{P eofill}!/s{H stroke}!/S{P stroke}!",
+ "/q/gsave #/Q/grestore #/rf{re fill}!",
"/Y{initclip P clip newpath}!/Y*{initclip P eoclip newpath}!/rY{re Y}!",
+ /* <w> <h> <name> <data> <?> |= <w> <h> <data> */
+ "/|={pop exch 4 1 roll 3 array astore cvx exch 1 index def exec}!",
/* <w> <h> <name> <length> <src> | <w> <h> <data> */
- "/|{exch string readstring pop exch 4 1 roll 3 packedarray cvx exch 1 index def exec}!",
+ "/|{exch string readstring |=}!",
/* <w> <?> <name> (<length>|) + <w> <?> <name> <length> */
"/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}!",
/* <w> <h> <name> (<length>|) $ <w> <h> <data> */
@@ -272,6 +275,19 @@ private const char *const psw_1_prolog[] =
0
};
+private const char *const psw_1_x_prolog[] =
+{
+ /* <w> <h> <name> <length> <src> |X <w> <h> <data> */
+ /* <w> <h> <name> (<length>|) $X <w> <h> <data> */
+ "/|X{exch string readhexstring |=}!/$X{+ @ |X}!",
+ /* - @X <hexsrc> */
+ "/@X{{currentfile ( ) readhexstring pop}}!",
+ /* <w> <h> <sizename> PS - */
+ "/PS{1 index where{pop cvx exec pop pop}{pop/setpage where",
+ "{pop pageparams 3{exch pop}repeat setpage}{pop pop}ifelse}ifelse}!",
+ 0
+};
+
private const char *const psw_1_5_prolog[] =
{
"/Ic{exch Ix false 3 colorimage}!",
@@ -361,16 +377,37 @@ image_cache_lookup(gx_device_pswrite * pdev, gx_bitmap_id id,
}
/* Prepare the encoding stream for image data. */
-/* Return 1 if we are using ASCII85 encoding. */
+/* Return 1 if we are using ASCII85 (or, for Level 1, ASCIIHex) encoding. */
private int
psw_image_stream_setup(gx_device_pswrite * pdev)
{
- int code =
- psdf_begin_binary((gx_device_psdf *) pdev, &pdev->image_writer);
+ int code, encode;
- return
- (code < 0 ? code :
- pdev->image_stream->state->template == &s_A85E_template ? 1 : 0);
+ if (pdev->LanguageLevel >= 2 || pdev->binary_ok) {
+ code = psdf_begin_binary((gx_device_psdf *)pdev, &pdev->image_writer);
+ encode =
+ (pdev->image_stream->state->template == &s_A85E_template ? 1 : 0);
+ } else {
+ pdev->binary_ok = true;
+ code = psdf_begin_binary((gx_device_psdf *)pdev, &pdev->image_writer);
+ pdev->binary_ok = false;
+ if (code >= 0) {
+ stream_state *st =
+ s_alloc_state(pdev->v_memory, s_AXE_template.stype,
+ "psw_image_stream_setup");
+
+ if (st == 0)
+ code = gs_note_error(gs_error_VMerror);
+ else {
+ code = psdf_encode_binary(&pdev->image_writer,
+ &s_AXE_template, st);
+ if (code >= 0)
+ ((stream_AXE_state *)st)->EndOfData = false; /* no > */
+ }
+ }
+ encode = 1;
+ }
+ return (code < 0 ? code : encode);
}
/* Clean up after writing an image. */
@@ -384,16 +421,27 @@ psw_image_cleanup(gx_device_pswrite * pdev)
}
/* 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)
{
+ const byte *row = data + (data_x_bit >> 3);
+ int shift = data_x_bit & 7;
int y;
- for (y = 0; y < height; ++y)
- pwrite(s, data + (data_x_bit >> 3) + y * raster,
- (width_bits + 7) >> 3);
+ for (y = 0; y < height; ++y, row += raster)
+ if (shift == 0)
+ pwrite(s, row, (width_bits + 7) >> 3);
+ else {
+ const byte *src = row;
+ int wleft = width_bits;
+ int cshift = 8 - shift;
+
+ for (; wleft + shift > 8; ++src, wleft -= 8)
+ pputc(s, (*src << shift) + (src[1] >> cshift));
+ if (wleft > 0)
+ pputc(s, (*src << shift) & (byte)(0xff00 >> wleft));
+ }
}
private int
psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
@@ -417,7 +465,7 @@ psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
encode = code = psw_image_stream_setup(pdev);
if (code < 0)
return code;
- if (depth == 1 && width > 16) {
+ if (depth == 1 && width > 16 && pdev->LanguageLevel >= 2) {
/*
* We should really look at the statistics of the image before
* committing to using G4 encoding....
@@ -428,8 +476,7 @@ psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
encode += 2;
}
if (id == gx_no_bitmap_id || width_bits * (ulong) height > 8000) {
- const char *const uncached[4] =
- {
+ static const char *const uncached[4] = {
"@", "@X", "@F", "@C"
};
@@ -439,8 +486,7 @@ psw_image_write(gx_device_pswrite * pdev, const char *imagestr,
psw_image_cleanup(pdev);
spputc(s, '\n');
} else {
- const char *const cached[4] =
- {
+ static const char *const cached[4] = {
"$", "$X", "$F", "$C"
};
@@ -512,41 +558,58 @@ psw_beginpage(gx_device_vector * vdev)
psw_put_lines(s, psw_header);
pprints1(s, "%% %s\n", gs_copyright);
psw_put_lines(s, psw_prolog);
- if (pdev->LanguageLevel < 1.5)
+ if (pdev->LanguageLevel < 1.5) {
+ psw_put_lines(s, psw_1_x_prolog);
psw_put_lines(s, psw_1_prolog);
- else {
+ } else if (pdev->LanguageLevel > 1.5) {
psw_put_lines(s, psw_1_5_prolog);
if (pdev->LanguageLevel > 1.5)
psw_put_lines(s, psw_2_prolog);
+ } else {
+ psw_put_lines(s, psw_1_x_prolog);
+ psw_put_lines(s, psw_1_5_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)
- pprintd2(s,
- (pdev->LanguageLevel > 1.5 ?
- "<< /PageSize [%d %d] >> setpagedevice\n" :
- "%d %d pageparams 3{exch pop}repeat setpage\n"),
- (int)(vdev->width * 72.0 / vdev->HWResolution[0] + 0.5),
- (int)(vdev->height * 72.0 / vdev->HWResolution[1] + 0.5));
+ 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))
@@ -610,7 +673,7 @@ private int
psw_beginpath(gx_device_vector * vdev, gx_path_type_t type)
{
pdev->path_state.num_points = 0;
- pdev->path_state.move = false;
+ pdev->path_state.move = 0;
return 0;
}
@@ -620,11 +683,18 @@ psw_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
{
stream *s = gdev_vector_stream(vdev);
- if (pdev->path_state.num_points > 1)
+ if (pdev->path_state.num_points > pdev->path_state.move)
pputs(s, (pdev->path_state.move ? "P\n" : "p\n"));
+ else if (pdev->path_state.move) {
+ /*
+ * Two consecutive movetos -- possible only if a zero-length line
+ * was discarded.
+ */
+ pputs(s, "pop pop\n");
+ }
print_coord2(s, x, y, NULL);
pdev->path_state.num_points = 1;
- pdev->path_state.move = true;
+ pdev->path_state.move = 1;
return 0;
}
@@ -682,7 +752,7 @@ psw_curveto(gx_device_vector * vdev, floatp x0, floatp y0,
print_coord2(s, dx3, dy3, "c\n");
}
pdev->path_state.num_points = 0;
- pdev->path_state.move = false;
+ pdev->path_state.move = 0;
return 0;
}
@@ -694,7 +764,7 @@ psw_closepath(gx_device_vector * vdev, floatp x0, floatp y0,
(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;
+ pdev->path_state.move = 0;
return 0;
}
@@ -704,7 +774,7 @@ 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 > 1 && !pdev->path_state.move)
+ 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))
@@ -773,6 +843,7 @@ psw_output_page(gx_device * dev, int num_copies, int flush)
/* 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 void psw_print_bbox(P2(FILE *, const gs_rect *));
private int
psw_close(gx_device * dev)
{
@@ -781,28 +852,33 @@ psw_close(gx_device * dev)
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);
+ long 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) {
+ psw_print_bbox(f, &bbox);
fputc('%', f);
fseek(f, save_pos, SEEK_SET);
- }
+ } else
+ psw_print_bbox(f, &bbox);
}
if (!pdev->ProduceEPS)
fputs("%%EOF\n", f);
gdev_vector_close_file(vdev);
return 0;
}
+private void
+psw_print_bbox(FILE *f, const gs_rect *pbbox)
+{
+ fprintf(f, "%%%%BoundingBox: %d %d %d %d\n",
+ (int)floor(pbbox->p.x), (int)floor(pbbox->p.y),
+ (int)ceil(pbbox->q.x), (int)ceil(pbbox->q.y));
+ fprintf(f, "%%%%HiResBoundingBox: %f %f %f %f\n",
+ pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y);
+
+}
/* ---------------- Get/put parameters ---------------- */
@@ -950,14 +1026,46 @@ psw_fill_path(gx_device * dev, const gs_imager_state * pis,
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)
+ const gx_device_color * pdcolor, 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);
+ /* Do the right thing for oddly transformed coordinate systems.... */
+ {
+ stream *s;
+ int code;
+ double scale;
+ bool set_ctm;
+ gs_matrix mat;
+
+ if (!gx_dc_is_pure(pdcolor))
+ return gx_default_stroke_path(dev, pis, ppath, params, pdcolor,
+ pcpath);
+ set_ctm = (bool)gdev_vector_stroke_scaling(vdev, pis, &scale, &mat);
+ gdev_vector_update_clip_path(vdev, pcpath);
+ gdev_vector_prepare_stroke((gx_device_vector *)pdev, pis, params,
+ pdcolor, scale);
+ s = pdev->strm;
+ if (set_ctm) {
+ pputs(s, "q");
+ if (is_fzero2(mat.xy, mat.yx) && is_fzero2(mat.tx, mat.ty))
+ pprintg2(s, " %g %g scale\n", mat.xx, mat.yy);
+ else {
+ psw_put_matrix(s, &mat);
+ pputs(s, "concat\n");
+ }
+ }
+ code = gdev_vector_dopath(vdev, ppath, gx_path_type_stroke,
+ (set_ctm ? &mat : (const gs_matrix *)0));
+ if (code < 0)
+ return code;
+ if (set_ctm)
+ pputs(s, "Q\n");
+ }
+ return 0;
}
/* Fill a mask. */
@@ -1002,8 +1110,8 @@ psw_begin_image(gx_device * dev,
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");
+ 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;
@@ -1015,42 +1123,50 @@ psw_begin_image(gx_device * dev,
if (pie == 0)
return_error(gs_error_VMerror);
pie->memory = mem;
- *pinfo = (gx_image_enum_common_t *) pie;
- if (!pim->ImageMask) {
+ pie->default_info = 0; /* not used */
+ if (pim->ImageMask) {
+ index = -1; /* bogus, not used */
+ num_components = 1;
+ } else {
index = gs_color_space_get_index(pcs);
num_components = gs_color_space_num_components(pcs);
- }
- if (pdev->LanguageLevel < 2 && !pim->ImageMask) {
+ if (pim->CombineWithColor)
+ can_do = false;
/*
- * Restrict ourselves to Level 1 images: device color spaces, [0
- * 1] decode, bits per component <= 8, no CombineWithColor.
+ * We can only handle Device color spaces right now, and only the
+ * default Decode [0 1 ...].
*/
- if (pim->BitsPerComponent > 8 || pim->CombineWithColor)
- can_do = false;
- else {
+ switch (index) {
+ case gs_color_space_index_DeviceGray:
+ case gs_color_space_index_DeviceRGB:
+ case gs_color_space_index_DeviceCMYK: {
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:
+ for (i = 0; i < num_components * 2; ++i)
+ if (pim->Decode[i] != (i & 1))
can_do = false;
- }
+ break;
+ }
+ default:
+ can_do = false;
}
}
+ if (pdev->LanguageLevel < 2 && !pim->ImageMask) {
+ /*
+ * Restrict ourselves to Level 1 images: bits per component <= 8.
+ */
+ if (pim->BitsPerComponent > 8)
+ 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
- )
+ ) {
+ gs_free_object(mem, pie, "psw_begin_image");
return gx_default_begin_image(dev, pis, pim, format, prect,
- pdcolor, pcpath, mem,
- &pie->default_info);
+ pdcolor, pcpath, mem, pinfo);
+ }
/* Write the image/colorimage/imagemask preamble. */
{
stream *s = gdev_vector_stream((gx_device_vector *) pdev);
@@ -1084,37 +1200,37 @@ psw_begin_image(gx_device * dev,
}
}
}
+ *pinfo = (gx_image_enum_common_t *) pie;
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)
+psw_image_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
{
+ gx_device *dev = info->dev;
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;
+ int code =
+ gx_image_plane_data_rows(pie->bbox_info, planes, height, rows_used);
+ 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],
+ *rows_used);
+ pie->y += *rows_used;
+ return code;
}
/* Clean up by releasing the buffers. */
private int
-psw_image_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
+psw_image_end_image(gx_image_enum_common_t * info, bool draw_last)
{
+ gx_device *dev = info->dev;
gdev_vector_image_enum_t *pie = (gdev_vector_image_enum_t *) info;
int code;
diff --git a/gs/src/gdevpsdf.c b/gs/src/gdevpsdf.c
index 9b660d38c..e09d5572c 100644
--- a/gs/src/gdevpsdf.c
+++ b/gs/src/gdevpsdf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -125,7 +125,7 @@ psdf_beginpath(gx_device_vector * vdev, gx_path_type_t type)
int
psdf_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
- bool first, gx_path_type_t type)
+ gx_path_type_t type)
{
pprintg2(gdev_vector_stream(vdev), "%g %g m\n", x, y);
return 0;
@@ -198,8 +198,15 @@ 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);
+ if (!pdev->binary_ok) {
+ stream_state *st =
+ s_alloc_state(pdev->v_memory, s_A85E_template.stype,
+ "psdf_begin_binary");
+
+ if (st == 0)
+ return_error(gs_error_VMerror);
+ psdf_encode_binary(pbw, &s_A85E_template, st);
+ }
return 0;
}
@@ -244,8 +251,8 @@ psdf_CFE_binary(psdf_binary_writer * pbw, int w, int h, bool invert)
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");
+ gs_alloc_struct(mem, stream_CFE_state, template->stype,
+ "psdf_CFE_binary");
int code;
if (st == 0)
@@ -253,8 +260,9 @@ psdf_CFE_binary(psdf_binary_writer * pbw, int w, int h, bool invert)
(*template->set_defaults) ((stream_state *) st);
st->K = -1;
st->Columns = w;
- st->Rows = h;
+ st->Rows = 0;
st->BlackIs1 = !invert;
+ st->EndOfBlock = true;
code = psdf_encode_binary(pbw, template, (stream_state *) st);
if (code < 0)
gs_free_object(mem, st, "psdf_CFE_binary");
@@ -270,9 +278,16 @@ psdf_end_binary(psdf_binary_writer * pbw)
/* 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);
+ stream *s = pbw->strm;
+ gs_memory_t *mem = s->state->memory;
+ byte *sbuf = s->cbuf;
+ stream *next = s->strm;
+
+ sclose(s);
+ if (s->state != (stream_state *)s)
+ gs_free_object(mem, s->state, "psdf_end_binary(state)");
+ gs_free_object(mem, s, "psdf_end_binary(stream)");
+ gs_free_object(mem, sbuf, "psdf_end_binary(buf)");
pbw->strm = next;
}
return 0;
diff --git a/gs/src/gdevpsdf.h b/gs/src/gdevpsdf.h
index 71baffa62..d4232248f 100644
--- a/gs/src/gdevpsdf.h
+++ b/gs/src/gdevpsdf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -167,12 +167,6 @@ extern_st(st_device_psdf);
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 */
@@ -195,8 +189,8 @@ int psdf_setstrokecolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc
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_moveto(P6(gx_device_vector * vdev, floatp x0, floatp y0,
+ floatp x, floatp y, 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,
diff --git a/gs/src/gdevpsdi.c b/gs/src/gdevpsdi.c
index f66fafe24..0ed4ee310 100644
--- a/gs/src/gdevpsdi.c
+++ b/gs/src/gdevpsdi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,12 +19,12 @@
/* Image compression for PostScript and PDF writers */
#include "math_.h"
+#include "jpeglib_.h" /* for sdct.h */
#include "gx.h"
#include "gserrors.h"
#include "gscspace.h"
#include "gdevpsdf.h"
#include "gdevpsds.h"
-#include "jpeglib.h" /* for sdct.h */
#include "strimpl.h"
#include "scfx.h"
#include "sdct.h"
@@ -35,8 +35,11 @@
/* ---------------- 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. */
+/*
+ * 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,
+ * except if bpc_out is 8, bpc_in may be 12.
+ */
private int
pixel_resize(psdf_binary_writer * pbw, int width, int num_components,
int bpc_in, int bpc_out)
@@ -48,16 +51,15 @@ pixel_resize(psdf_binary_writer * pbw, int width, int num_components,
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
+ if (bpc_in != 8) {
+ static const stream_template *const exts[13] = {
+ 0, &s_1_8_template, &s_2_8_template, 0, &s_4_8_template,
+ 0, 0, 0, 0, 0, 0, 0, &s_12_8_template
};
template = exts[bpc_in];
} else {
- static const stream_template *const rets[5] =
- {
+ static const stream_template *const rets[5] = {
0, &s_8_1_template, &s_8_2_template, 0, &s_8_4_template
};
@@ -78,7 +80,7 @@ pixel_resize(psdf_binary_writer * pbw, int width, int num_components,
/* Add the appropriate image compression filter, if any. */
private int
-setup_image_compression(psdf_binary_writer * pbw, const psdf_image_params * pdip,
+setup_image_compression(psdf_binary_writer *pbw, const psdf_image_params *pdip,
const gs_image_t * pim)
{
gx_device_psdf *pdev = pbw->dev;
@@ -130,8 +132,9 @@ setup_image_compression(psdf_binary_writer * pbw, const psdf_image_params * pdip
}
ss->Columns = pim->Width;
ss->Rows = (ss->EndOfBlock ? 0 : pim->Height);
- } else if (template == &s_LZWE_template ||
- template == &s_zlibE_template) {
+ } else if ((template == &s_LZWE_template ||
+ template == &s_zlibE_template) &&
+ pdev->version >= psdf_version_ll3) {
/* Add a PNGPredictor filter. */
int code = psdf_encode_binary(pbw, template, st);
@@ -226,14 +229,15 @@ 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.
- */
+{
+ /*
+ * 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;
@@ -243,6 +247,7 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
} else {
int ncomp = gs_color_space_num_components(pim->ColorSpace);
int bpc = pim->BitsPerComponent;
+ int bpc_out = pim->BitsPerComponent = min(bpc, 8);
/*
* We can compute the image resolution by:
@@ -286,6 +291,9 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
} else {
code = setup_image_compression(pbw, &params, pim);
}
+ if (code < 0)
+ return code;
+ code = pixel_resize(pbw, pim->Width, ncomp, bpc, bpc_out);
} else {
/* Color */
bool cmyk_to_rgb =
@@ -298,7 +306,7 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
pim->ColorSpace = gs_cspace_DeviceRGB(pis);
params = pdev->params.ColorImage;
if (params.Depth == -1)
- params.Depth = (cmyk_to_rgb ? 8 : bpc);
+ params.Depth = (cmyk_to_rgb ? 8 : bpc_out);
if (params.Downsample && params.Resolution <= resolution / 2) {
code = setup_downsampling(pbw, &params, pim, resolution);
} else {
@@ -308,8 +316,8 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
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);
-
+ int code = pixel_resize(pbw, pim->Width, 3, 8, bpc_out);
+
if (code < 0 ||
(code = psdf_encode_binary(pbw, &s_C2R_template,
(stream_state *) ss)) < 0 ||
@@ -317,6 +325,10 @@ psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
)
return code;
s_C2R_init(ss, pis);
+ } else {
+ code = pixel_resize(pbw, pim->Width, ncomp, bpc, bpc_out);
+ if (code < 0)
+ return code;
}
}
}
diff --git a/gs/src/gdevpsdp.c b/gs/src/gdevpsdp.c
index 74c882754..ecd123b20 100644
--- a/gs/src/gdevpsdp.c
+++ b/gs/src/gdevpsdp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,14 +19,15 @@
/* (Distiller) parameter handling for PostScript and PDF writers */
#include "string_.h"
+#include "jpeglib_.h" /* for sdct.h */
#include "gx.h"
#include "gserrors.h"
#include "gxdevice.h"
+#include "gsparamx.h"
#include "gdevpsdf.h"
#include "gdevpstr.h"
#include "strimpl.h" /* for short-sighted compilers */
#include "scfx.h"
-#include "jpeglib.h" /* for sdct.h */
#include "sdct.h"
#include "slzwx.h"
#include "srlx.h"
@@ -57,61 +58,51 @@ typedef struct psdf_image_param_names_s {
const char *Filter;
const char *Resolution;
} psdf_image_param_names;
-private const psdf_image_param_names Color_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[] =
-{
+private const psdf_image_filter_name Poly_filters[] = {
{"DCTEncode", &s_DCTE_template},
{"FlateEncode", &s_zlibE_template, psdf_version_ll3},
{"LZWEncode", &s_LZWE_template},
{0, 0}
};
-private const psdf_image_param_names Gray_names =
-{
+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 =
-{
+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[] =
-{
+private const psdf_image_filter_name Mono_filters[] = {
{"CCITTFaxEncode", &s_CFE_template},
{"FlateEncode", &s_zlibE_template, psdf_version_ll3},
{"LZWEncode", &s_LZWE_template},
{"RunLengthEncode", &s_RLE_template},
{0, 0}
};
-private const char *const AutoRotatePages_names[] =
-{
+private const char *const AutoRotatePages_names[] = {
"None", "All", "PageByPage", 0
};
-private const char *const ColorConversionStrategy_names[] =
-{
+private const char *const ColorConversionStrategy_names[] = {
"LeaveColorUnchanged", "UseDeviceDependentColor",
"UseDeviceIndependentColor", 0
};
-private const char *const DownsampleType_names[] =
-{
+private const char *const DownsampleType_names[] = {
"Average", "Subsample", 0
};
-private const char *const TransferFunctionInfo_names[] =
-{
+private const char *const TransferFunctionInfo_names[] = {
"Preserve", "Apply", "Remove", 0
};
-private const char *const UCRandBGInfo_names[] =
-{
+private const char *const UCRandBGInfo_names[] = {
"Preserve", "Remove", 0
};
@@ -305,77 +296,6 @@ psdf_DCT_put_params(gs_param_list * plist, stream_state * ss)
return s_DCTE_put_params(plist, (stream_DCT_state *) ss);
}
-/* 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,
@@ -482,12 +402,12 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
if (code < 0)
ecode = code;
}
- ecode = psdf_put_bool_param(plist, pnames->AntiAlias,
+ ecode = param_put_bool(plist, pnames->AntiAlias,
&params->AntiAlias, ecode);
if (pnames->AutoFilter)
- ecode = psdf_put_bool_param(plist, pnames->AutoFilter,
+ ecode = param_put_bool(plist, pnames->AutoFilter,
&params->AutoFilter, ecode);
- ecode = psdf_put_int_param(plist, pnames->Depth,
+ ecode = param_put_int(plist, pnames->Depth,
&params->Depth, ecode);
if ((pname = pnames->Dict) != 0) {
const stream_template *template;
@@ -505,21 +425,21 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
if (code < 0)
ecode = code;
}
- ecode = psdf_put_bool_param(plist, pnames->Downsample,
+ ecode = param_put_bool(plist, pnames->Downsample,
&params->Downsample, ecode);
- if ((ecode = psdf_put_enum_param(plist, pnames->DownsampleType,
+ if ((ecode = param_put_enum(plist, pnames->DownsampleType,
&dsti, DownsampleType_names,
ecode)) >= 0
)
params->DownsampleType = (enum psdf_downsample_type)dsti;
- ecode = psdf_put_bool_param(plist, pnames->Encode,
+ ecode = param_put_bool(plist, pnames->Encode,
&params->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))
+ while (pn->pname != 0 && !gs_param_string_eq(&fs, pn->pname))
pn++;
if (pn->pname == 0 || pn->min_version > pdev->version) {
ecode = gs_error_rangecheck;
@@ -535,7 +455,7 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
case 1:
break;
}
- ecode = psdf_put_int_param(plist, pnames->Resolution,
+ ecode = param_put_int(plist, pnames->Resolution,
&params->Resolution, ecode);
if (ecode >= 0) { /* Force parameters to acceptable values. */
if (params->Resolution < 1)
@@ -568,16 +488,16 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
params = pdev->params;
- ecode = psdf_put_bool_param(plist, "ASCII85EncodePages",
+ ecode = param_put_bool(plist, "ASCII85EncodePages",
&params.ASCII85EncodePages, ecode);
{
int arpi = params.AutoRotatePages;
- ecode = psdf_put_enum_param(plist, "AutoRotatePages", &arpi,
+ ecode = param_put_enum(plist, "AutoRotatePages", &arpi,
AutoRotatePages_names, ecode);
params.AutoRotatePages = (enum psdf_auto_rotate_pages)arpi;
}
- ecode = psdf_put_bool_param(plist, "CompressPages",
+ ecode = param_put_bool(plist, "CompressPages",
&params.CompressPages, ecode);
switch (code = param_read_long(plist, (param_name = "ImageMemory"), &params.ImageMemory)) {
default:
@@ -587,29 +507,29 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
case 1:
break;
}
- ecode = psdf_put_bool_param(plist, "LZWEncodePages",
+ ecode = param_put_bool(plist, "LZWEncodePages",
&params.LZWEncodePages, ecode);
- ecode = psdf_put_bool_param(plist, "PreserveHalftoneInfo",
+ ecode = param_put_bool(plist, "PreserveHalftoneInfo",
&params.PreserveHalftoneInfo, ecode);
- ecode = psdf_put_bool_param(plist, "PreserveOPIComments",
+ ecode = param_put_bool(plist, "PreserveOPIComments",
&params.PreserveOPIComments, ecode);
- ecode = psdf_put_bool_param(plist, "PreserveOverprintSettings",
+ ecode = param_put_bool(plist, "PreserveOverprintSettings",
&params.PreserveOverprintSettings, ecode);
{
int tfii = params.TransferFunctionInfo;
- ecode = psdf_put_enum_param(plist, "TransferFunctionInfo", &tfii,
+ ecode = param_put_enum(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,
+ ecode = param_put_enum(plist, "UCRandBGInfo", &ucrbgi,
UCRandBGInfo_names, ecode);
params.UCRandBGInfo = (enum psdf_ucr_and_bg_info)ucrbgi;
}
- ecode = psdf_put_bool_param(plist, "UseFlateCompression",
+ ecode = param_put_bool(plist, "UseFlateCompression",
&params.UseFlateCompression, ecode);
/* Color sampled image parameters */
@@ -619,14 +539,14 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
{
int ccsi = params.ColorConversionStrategy;
- ecode = psdf_put_enum_param(plist, "ColorConversionStrategy", &ccsi,
+ ecode = param_put_enum(plist, "ColorConversionStrategy", &ccsi,
ColorConversionStrategy_names, ecode);
params.ColorConversionStrategy =
(enum psdf_color_conversion_strategy)ccsi;
}
- ecode = psdf_put_bool_param(plist, "ConvertCMYKImagesToRGB",
+ ecode = param_put_bool(plist, "ConvertCMYKImagesToRGB",
&params.ConvertCMYKImagesToRGB, ecode);
- ecode = psdf_put_bool_param(plist, "ConvertImagesToIndexed",
+ ecode = param_put_bool(plist, "ConvertImagesToIndexed",
&params.ConvertImagesToIndexed, ecode);
/* Gray sampled image parameters */
@@ -645,11 +565,11 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
&params.AlwaysEmbed, ecode);
ecode = psdf_put_embed_param(plist, "~NeverEmbed",
&params.NeverEmbed, ecode);
- ecode = psdf_put_bool_param(plist, "EmbedAllFonts",
+ ecode = param_put_bool(plist, "EmbedAllFonts",
&params.EmbedAllFonts, ecode);
- ecode = psdf_put_bool_param(plist, "SubsetFonts",
+ ecode = param_put_bool(plist, "SubsetFonts",
&params.SubsetFonts, ecode);
- ecode = psdf_put_int_param(plist, "MaxSubsetPct",
+ ecode = param_put_int(plist, "MaxSubsetPct",
&params.MaxSubsetPct, ecode);
if (ecode < 0)
diff --git a/gs/src/gdevpsds.c b/gs/src/gdevpsds.c
index 3906f2d74..e119a4d62 100644
--- a/gs/src/gdevpsds.c
+++ b/gs/src/gdevpsds.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,7 +24,8 @@
#include "gxdcconv.h"
#include "gdevpsds.h"
-/* ---------------- Convert between 1/2/4 and 8 bits ---------------- */
+/* ---------------- Convert between 1/2/4/12 and 8 bits ---------------- */
+
gs_private_st_simple(st_1248_state, stream_1248_state, "stream_1248_state");
/* Initialize the state. */
@@ -55,6 +56,15 @@ s_4_init(stream_state * st)
ss->bits_per_sample = 4;
return 0;
}
+private int
+s_12_init(stream_state * st)
+{
+ stream_1248_state *const ss = (stream_1248_state *) st;
+
+ ss->left = ss->samples_per_row;
+ ss->bits_per_sample = 12; /* not needed */
+ return 0;
+}
/* Process one buffer. */
#define BEGIN_1248\
@@ -157,6 +167,36 @@ s_N_8_process(stream_state * st, stream_cursor_read * pr,
END_1248;
}
+/* 12-to-8 "expansion" */
+private int
+s_12_8_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ BEGIN_1248;
+
+ n = ss->samples_per_row; /* misuse n to avoid a compiler warning */
+ status = 0;
+ for (; rlimit - p >= 2; ++q) {
+ if (q >= wlimit) {
+ status = 1;
+ break;
+ }
+ if (left == 0)
+ left = n;
+ if ((n - left) & 1) {
+ q[1] = (byte)((p[1] << 4) | (p[2] >> 4));
+ p += 2, --left;
+ } else {
+ q[1] = *++p;
+ if (!--left)
+ ++p;
+ }
+ }
+
+ END_1248;
+}
+
+
/* 8-to-N reduction */
#define FOREACH_8_N(out, nin)\
byte out;\
@@ -235,29 +275,26 @@ s_8_N_process(stream_state * st, stream_cursor_read * pr,
END_1248;
}
-const stream_template s_1_8_template =
-{
+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 =
-{
+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 =
-{
+const stream_template s_4_8_template = {
&st_1248_state, s_4_init, s_N_8_process, 1, 2
};
+const stream_template s_12_8_template = {
+ &st_1248_state, s_12_init, s_12_8_process, 1, 2
+};
-const stream_template s_8_1_template =
-{
+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 =
-{
+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 =
-{
+const stream_template s_8_4_template = {
&st_1248_state, s_4_init, s_8_N_process, 2, 1
};
diff --git a/gs/src/gdevpsds.h b/gs/src/gdevpsds.h
index 73f191211..78b95079f 100644
--- a/gs/src/gdevpsds.h
+++ b/gs/src/gdevpsds.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,22 +24,24 @@
#include "strimpl.h"
-/* Convert between 1/2/4 bits and 8 bits. */
+/* Convert between 1/2/4/12 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 */
+ int bits_per_sample; /* 1, 2, 4, 12 */
/* The following are updated dynamically. */
uint left; /* # of samples left in current row */
} stream_1248_state;
-/* Expand N (1, 2, 4) bits to 8. */
+/* Convert N (1, 2, 4, 12) 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;
+extern const stream_template s_12_8_template;
-/* Reduce 8 bits to N (1, 2, 4) */
+/* Reduce 8 bits to N (1, 2, 4). */
+/* We do not currently support converting 8 bits to 12. */
extern const stream_template s_8_1_template;
extern const stream_template s_8_2_template;
extern const stream_template s_8_4_template;
diff --git a/gs/src/gdevpx.c b/gs/src/gdevpx.c
index 03c7e567d..c3dd6a9f8 100644
--- a/gs/src/gdevpx.c
+++ b/gs/src/gdevpx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -46,11 +46,11 @@
#endif
/* Structure definition */
-#define num_points 100 /* must be >= 3 and <= 255 */
+#define NUM_POINTS 40 /* must be >= 3 and <= 255 */
typedef enum {
- points_none,
- points_lines,
- points_curves
+ POINTS_NONE,
+ POINTS_LINES,
+ POINTS_CURVES
} point_type_t;
typedef struct gx_device_pclxl_s {
gx_device_vector_common;
@@ -67,18 +67,18 @@ typedef struct gx_device_pclxl_s {
gs_int_point current; /* current point as of start of data */
point_type_t type;
int count;
- gs_int_point data[num_points];
+ gs_int_point data[NUM_POINTS];
} points;
struct ch_ { /* cache for downloaded characters */
-#define max_cached_chars 400
-#define max_char_data 500000
-#define max_char_size 5000
-#define char_hash_factor 247
- ushort table[max_cached_chars * 3 / 2];
+#define MAX_CACHED_CHARS 400
+#define MAX_CHAR_DATA 500000
+#define MAX_CHAR_SIZE 5000
+#define CHAR_HASH_FACTOR 247
+ ushort table[MAX_CACHED_CHARS * 3 / 2];
struct cd_ {
gs_id id; /* key */
uint size;
- } data[max_cached_chars];
+ } data[MAX_CACHED_CHARS];
int next_in; /* next data element to fill in */
int next_out; /* next data element to discard */
int count; /* of occupied data elements */
@@ -88,7 +88,8 @@ typedef struct gx_device_pclxl_s {
} gx_device_pclxl;
gs_public_st_suffix_add0_final(st_device_pclxl, gx_device_pclxl,
- "gx_device_pclxl", device_pclxl_enum_ptrs, device_pclxl_reloc_ptrs,
+ "gx_device_pclxl",
+ device_pclxl_enum_ptrs, device_pclxl_reloc_ptrs,
gx_device_finalize, st_device_vector);
#define pclxl_device_body(dname, depth)\
@@ -113,52 +114,51 @@ private dev_proc_begin_image(pclxl_begin_image);
private dev_proc_strip_copy_rop(pclxl_strip_copy_rop);
#define pclxl_device_procs(map_rgb_color, map_color_rgb)\
- { pclxl_open_device,\
- NULL, /* get_initial_matrix */\
- NULL, /* sync_output */\
- pclxl_output_page,\
- pclxl_close_device,\
- map_rgb_color, /* differs */\
- map_color_rgb, /* differs */\
- gdev_vector_fill_rectangle,\
- NULL, /* tile_rectangle */\
- pclxl_copy_mono,\
- pclxl_copy_color,\
- NULL, /* draw_line */\
- NULL, /* get_bits */\
- gdev_vector_get_params,\
- gdev_vector_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 */\
- gdev_vector_fill_path,\
- gdev_vector_stroke_path,\
- pclxl_fill_mask,\
- gdev_vector_fill_trapezoid,\
- gdev_vector_fill_parallelogram,\
- gdev_vector_fill_triangle,\
- NULL /****** WRONG ******/, /* draw_thin_line */\
- pclxl_begin_image,\
- NULL, /* image_data */\
- NULL, /* end_image */\
- NULL, /* strip_tile_rectangle */\
- pclxl_strip_copy_rop\
- }
+{\
+ pclxl_open_device,\
+ NULL, /* get_initial_matrix */\
+ NULL, /* sync_output */\
+ pclxl_output_page,\
+ pclxl_close_device,\
+ map_rgb_color, /* differs */\
+ map_color_rgb, /* differs */\
+ gdev_vector_fill_rectangle,\
+ NULL, /* tile_rectangle */\
+ pclxl_copy_mono,\
+ pclxl_copy_color,\
+ NULL, /* draw_line */\
+ NULL, /* get_bits */\
+ gdev_vector_get_params,\
+ gdev_vector_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 */\
+ gdev_vector_fill_path,\
+ gdev_vector_stroke_path,\
+ pclxl_fill_mask,\
+ gdev_vector_fill_trapezoid,\
+ gdev_vector_fill_parallelogram,\
+ gdev_vector_fill_triangle,\
+ NULL /****** WRONG ******/, /* draw_thin_line */\
+ pclxl_begin_image,\
+ NULL, /* image_data */\
+ NULL, /* end_image */\
+ NULL, /* strip_tile_rectangle */\
+ pclxl_strip_copy_rop\
+}
-const gx_device_pclxl gs_pxlmono_device =
-{
+const gx_device_pclxl gs_pxlmono_device = {
pclxl_device_body("pxlmono", 8),
pclxl_device_procs(gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb)
};
-const gx_device_pclxl gs_pxlcolor_device =
-{
+const gx_device_pclxl gs_pxlcolor_device = {
pclxl_device_body("pxlcolor", 24),
pclxl_device_procs(gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb)
};
@@ -166,7 +166,7 @@ const gx_device_pclxl gs_pxlcolor_device =
/* ---------------- Output utilities ---------------- */
/* Write a sequence of bytes. */
-#define put_lit(s, bytes) px_put_bytes(s, bytes, sizeof(bytes))
+#define PX_PUT_LIT(s, bytes) px_put_bytes(s, bytes, sizeof(bytes))
private void
px_put_bytes(stream * s, const byte * data, uint count)
{
@@ -177,89 +177,105 @@ px_put_bytes(stream * s, const byte * data, uint count)
/* Utilities for writing data values. */
/* H-P printers only support little-endian data, so that's what we emit. */
-#define da(a) pxt_attr_ubyte, (a)
+#define DA(a) pxt_attr_ubyte, (a)
private void
-put_a(stream * s, px_attribute_t a)
+px_put_a(stream * s, px_attribute_t a)
{
sputc(s, pxt_attr_ubyte);
sputc(s, a);
}
-#define dub(b) pxt_ubyte, (byte)(b)
private void
-put_ub(stream * s, byte b)
+px_put_ac(stream *s, px_attribute_t a, px_tag_t op)
+{
+ px_put_a(s, a);
+ sputc(s, op);
+}
+
+#define DUB(b) pxt_ubyte, (byte)(b)
+private void
+px_put_ub(stream * s, byte b)
{
sputc(s, pxt_ubyte);
sputc(s, b);
}
-#define put_uba(s, b, a)\
- (put_ub(s, b), put_a(s, a))
-#define ds(i) (byte)(i), (byte)((i) >> 8)
private void
-put_s(stream * s, uint i)
+px_put_uba(stream *s, byte b, px_attribute_t a)
+{
+ px_put_ub(s, b);
+ px_put_a(s, a);
+}
+
+#define DS(i) (byte)(i), (byte)((i) >> 8)
+private void
+px_put_s(stream * s, uint i)
{
sputc(s, (byte) i);
sputc(s, (byte) (i >> 8));
}
-#define dus(i) pxt_uint16, ds(i)
+#define DUS(i) pxt_uint16, DS(i)
private void
-put_us(stream * s, uint i)
+px_put_us(stream * s, uint i)
{
sputc(s, pxt_uint16);
- put_s(s, i);
+ px_put_s(s, i);
+}
+private void
+px_put_usa(stream *s, uint i, px_attribute_t a)
+{
+ px_put_us(s, i);
+ px_put_a(s, a);
}
-#define put_usa(s, i, a)\
- (put_us(s, i), put_a(s, a))
private void
-put_u(stream * s, uint i)
+px_put_u(stream * s, uint i)
{
if (i <= 255)
- put_ub(s, i);
+ px_put_ub(s, i);
else
- put_us(s, i);
+ px_put_us(s, i);
}
-#define dusp(ix,iy) pxt_uint16_xy, ds(ix), ds(iy)
+
private void
-put_usp(stream * s, uint ix, uint iy)
+px_put_usp(stream * s, uint ix, uint iy)
{
- sputc(s, pxt_uint16_xy);
- put_s(s, ix);
- put_s(s, iy);
+ spputc(s, pxt_uint16_xy);
+ px_put_s(s, ix);
+ px_put_s(s, iy);
}
private void
-put_usq_fixed(stream * s, fixed x0, fixed y0, fixed x1, fixed y1)
+px_put_usq_fixed(stream * s, fixed x0, fixed y0, fixed x1, fixed y1)
{
- sputc(s, pxt_uint16_box);
- put_s(s, fixed2int(x0));
- put_s(s, fixed2int(y0));
- put_s(s, fixed2int(x1));
- put_s(s, fixed2int(y1));
+ spputc(s, pxt_uint16_box);
+ px_put_s(s, fixed2int(x0));
+ px_put_s(s, fixed2int(y0));
+ px_put_s(s, fixed2int(x1));
+ px_put_s(s, fixed2int(y1));
}
-#define dss(i) pxt_sint16, ds(i)
+
#if 0 /* NOT CURRENTLY USED */
private void
-put_ss(stream * s, int i)
+px_put_ss(stream * s, int i)
{
sputc(s, pxt_sint16);
- put_s(s, (uint) i);
+ px_put_s(s, (uint) i);
}
#endif
-#define dssp(ix,iy) pxt_sint16_xy, ds(ix), ds(iy)
private void
-put_ssp(stream * s, int ix, int iy)
+px_put_ssp(stream * s, int ix, int iy)
{
sputc(s, pxt_sint16_xy);
- put_s(s, (uint) ix);
- put_s(s, (uint) iy);
+ px_put_s(s, (uint) ix);
+ px_put_s(s, (uint) iy);
}
-#define dl(l) ds(l), ds((l) >> 16)
+
private void
-put_l(stream * s, ulong l)
+px_put_l(stream * s, ulong l)
{
- put_s(s, (uint) l);
- put_s(s, (uint) (l >> 16));
+ px_put_s(s, (uint) l);
+ px_put_s(s, (uint) (l >> 16));
}
+
private void
-put_r(stream * s, floatp r)
+px_put_r(stream * s, floatp r)
{ /* Convert to single-precision IEEE float. */
int exp;
long mantissa = (long)(frexp(r, &exp) * 0x1000000);
@@ -275,37 +291,37 @@ put_r(stream * s, floatp r)
spputc(s, (exp + 127) >> 1);
}
private void
-put_rl(stream * s, floatp r)
+px_put_rl(stream * s, floatp r)
{
- sputc(s, pxt_real32);
- put_r(s, r);
+ spputc(s, pxt_real32);
+ px_put_r(s, r);
}
+
private void
-put_data_length(stream * s, uint num_bytes)
+px_put_data_length(stream * s, uint num_bytes)
{
if (num_bytes > 255) {
spputc(s, pxt_dataLength);
- put_l(s, (ulong) num_bytes);
+ px_put_l(s, (ulong) num_bytes);
} else {
spputc(s, pxt_dataLengthByte);
spputc(s, (byte) num_bytes);
}
}
-#define put_ac(s, a, op)\
-BEGIN static const byte ac_[] = { da(a), op }; put_lit(s, ac_); END
-#define return_put_ac(s, a, op)\
-BEGIN put_ac(s, a, op); return 0; END
-
/* ---------------- Other utilities ---------------- */
-#define vxdev ((gx_device_vector *)xdev)
+inline private stream *
+pclxl_stream(gx_device_pclxl *xdev)
+{
+ return gdev_vector_stream((gx_device_vector *)xdev);
+}
/* Initialize for a page. */
private void
pclxl_page_init(gx_device_pclxl * xdev)
{
- gdev_vector_init(vxdev);
+ gdev_vector_init((gx_device_vector *)xdev);
xdev->in_page = false;
xdev->fill_rule = gx_path_type_winding_number;
xdev->clip_rule = gx_path_type_winding_number;
@@ -315,17 +331,17 @@ pclxl_page_init(gx_device_pclxl * xdev)
}
/* Test whether a RGB color is actually a gray shade. */
-#define rgb_is_gray(ci) ((ci) >> 8 == ((ci) & 0xffff))
+#define RGB_IS_GRAY(ci) ((ci) >> 8 == ((ci) & 0xffff))
/* Set the color space and (optionally) palette. */
private void
pclxl_set_color_space(gx_device_pclxl * xdev, pxeColorSpace_t color_space)
{
if (xdev->color_space != color_space) {
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
- put_ub(s, color_space);
- put_ac(s, pxaColorSpace, pxtSetColorSpace);
+ px_put_ub(s, color_space);
+ px_put_ac(s, pxaColorSpace, pxtSetColorSpace);
xdev->color_space = color_space;
}
}
@@ -337,19 +353,18 @@ pclxl_set_color_palette(gx_device_pclxl * xdev, pxeColorSpace_t color_space,
xdev->palette.size != palette_size ||
memcmp(xdev->palette.data, palette, palette_size)
) {
- stream *s = gdev_vector_stream(vxdev);
- static const byte csp_[] =
- {
- da(pxaColorSpace),
- dub(e8Bit), da(pxaPaletteDepth),
+ stream *s = pclxl_stream(xdev);
+ static const byte csp_[] = {
+ DA(pxaColorSpace),
+ DUB(e8Bit), DA(pxaPaletteDepth),
pxt_ubyte_array
};
- put_ub(s, color_space);
- put_lit(s, csp_);
- put_u(s, palette_size);
+ px_put_ub(s, color_space);
+ PX_PUT_LIT(s, csp_);
+ px_put_u(s, palette_size);
px_put_bytes(s, palette, palette_size);
- put_ac(s, pxaPaletteData, pxtSetColorSpace);
+ px_put_ac(s, pxaPaletteData, pxtSetColorSpace);
xdev->color_space = color_space;
xdev->palette.size = palette_size;
memcpy(xdev->palette.data, palette, palette_size);
@@ -361,25 +376,25 @@ private int
pclxl_set_color(gx_device_pclxl * xdev, const gx_drawing_color * pdc,
px_attribute_t null_source, px_tag_t op)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
if (gx_dc_is_pure(pdc)) {
gx_color_index color = gx_dc_pure_color(pdc);
- if (xdev->color_info.num_components == 1 || rgb_is_gray(color)) {
+ if (xdev->color_info.num_components == 1 || RGB_IS_GRAY(color)) {
pclxl_set_color_space(xdev, eGray);
- put_uba(s, (byte) color, pxaGrayLevel);
+ px_put_uba(s, (byte) color, pxaGrayLevel);
} else {
pclxl_set_color_space(xdev, eRGB);
spputc(s, pxt_ubyte_array);
- put_ub(s, 3);
+ px_put_ub(s, 3);
spputc(s, (byte) (color >> 16));
spputc(s, (byte) (color >> 8));
spputc(s, (byte) color);
- put_a(s, pxaRGBColor);
+ px_put_a(s, pxaRGBColor);
}
} else if (gx_dc_is_null(pdc))
- put_uba(s, 0, null_source);
+ px_put_uba(s, 0, null_source);
else
return_error(gs_error_rangecheck);
spputc(s, op);
@@ -406,35 +421,33 @@ pclxl_can_handle_color_space(const gs_color_space * pcs)
private void
pclxl_set_paints(gx_device_pclxl * xdev, gx_path_type_t type)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
gx_path_type_t rule = type & gx_path_type_rule;
if (!(type & gx_path_type_fill) &&
!gx_dc_is_null(&xdev->fill_color)
) {
- static const byte nac_[] =
- {
- dub(0), da(pxaNullBrush), pxtSetBrushSource
+ static const byte nac_[] = {
+ DUB(0), DA(pxaNullBrush), pxtSetBrushSource
};
- put_lit(s, nac_);
+ PX_PUT_LIT(s, nac_);
color_set_null(&xdev->fill_color);
if (rule != xdev->fill_rule) {
- put_ub(s, (rule == gx_path_type_even_odd ? eEvenOdd :
+ px_put_ub(s, (rule == gx_path_type_even_odd ? eEvenOdd :
eNonZeroWinding));
- put_ac(s, pxaFillMode, pxtSetFillMode);
+ px_put_ac(s, pxaFillMode, pxtSetFillMode);
xdev->fill_rule = rule;
}
}
if (!(type & gx_path_type_stroke) &&
!gx_dc_is_null(&xdev->stroke_color)
) {
- static const byte nac_[] =
- {
- dub(0), da(pxaNullPen), pxtSetPenSource
+ static const byte nac_[] = {
+ DUB(0), DA(pxaNullPen), pxtSetPenSource
};
- put_lit(s, nac_);
+ PX_PUT_LIT(s, nac_);
color_set_null(&xdev->stroke_color);
}
}
@@ -443,20 +456,21 @@ pclxl_set_paints(gx_device_pclxl * xdev, gx_path_type_t type)
private int
pclxl_set_cursor(gx_device_pclxl * xdev, int x, int y)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
- put_ssp(s, x, y);
- return_put_ac(s, pxaPoint, pxtSetCursor);
+ px_put_ssp(s, x, y);
+ px_put_ac(s, pxaPoint, pxtSetCursor);
+ return 0;
}
/* ------ Paths ------ */
/* Flush any buffered path points. */
private void
-put_np(stream * s, int count, pxeDataType_t dtype)
+px_put_np(stream * s, int count, pxeDataType_t dtype)
{
- put_uba(s, count, pxaNumberOfPoints);
- put_uba(s, dtype, pxaPointType);
+ px_put_uba(s, count, pxaNumberOfPoints);
+ px_put_uba(s, dtype, pxaPointType);
}
private int
pclxl_flush_points(gx_device_pclxl * xdev)
@@ -464,13 +478,13 @@ pclxl_flush_points(gx_device_pclxl * xdev)
int count = xdev->points.count;
if (count) {
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
px_tag_t op;
int x = xdev->points.current.x, y = xdev->points.current.y;
int uor = 0, sor = 0;
pxeDataType_t data_type;
int i, di;
- byte diffs[num_points * 2];
+ byte diffs[NUM_POINTS * 2];
/*
* Writing N lines using a point list requires 11 + 4*N or 11 +
@@ -484,15 +498,15 @@ pclxl_flush_points(gx_device_pclxl * xdev)
* coordinates).
*/
switch (xdev->points.type) {
- case points_none:
+ case POINTS_NONE:
return 0;
- case points_lines:
+ case POINTS_LINES:
op = pxtLinePath;
if (count < 3) {
for (i = 0; i < count; ++i) {
- put_ssp(s, xdev->points.data[i].x,
+ px_put_ssp(s, xdev->points.data[i].x,
xdev->points.data[i].y);
- put_a(s, pxaEndPoint);
+ px_put_a(s, pxaEndPoint);
spputc(s, op);
}
goto zap;
@@ -516,12 +530,12 @@ pclxl_flush_points(gx_device_pclxl * xdev)
break;
op = pxtLineRelPath;
/* Use byte values. */
- useb:put_np(s, count, data_type);
+ useb:px_put_np(s, count, data_type);
spputc(s, op);
- put_data_length(s, count * 2); /* 2 bytes per point */
+ px_put_data_length(s, count * 2); /* 2 bytes per point */
px_put_bytes(s, diffs, count * 2);
goto zap;
- case points_curves:
+ case POINTS_CURVES:
op = pxtBezierPath;
/* See if we can use byte values. */
for (i = di = 0; i < count; i += 3, di += 6) {
@@ -555,14 +569,14 @@ pclxl_flush_points(gx_device_pclxl * xdev)
default: /* can't happen */
return_error(gs_error_unknownerror);
}
- put_np(s, count, eSInt16);
+ px_put_np(s, count, eSInt16);
spputc(s, op);
- put_data_length(s, count * 4); /* 2 UInt16s per point */
+ px_put_data_length(s, count * 4); /* 2 UInt16s per point */
for (i = 0; i < count; ++i) {
- put_s(s, xdev->points.data[i].x);
- put_s(s, xdev->points.data[i].y);
+ px_put_s(s, xdev->points.data[i].x);
+ px_put_s(s, xdev->points.data[i].y);
}
- zap:xdev->points.type = points_none;
+ zap:xdev->points.type = POINTS_NONE;
xdev->points.count = 0;
}
return 0;
@@ -572,8 +586,7 @@ pclxl_flush_points(gx_device_pclxl * xdev)
private image_enum_proc_plane_data(pclxl_image_plane_data);
private image_enum_proc_end_image(pclxl_image_end_image);
-private const gx_image_enum_procs_t pclxl_image_enum_procs =
-{
+private const gx_image_enum_procs_t pclxl_image_enum_procs = {
pclxl_image_plane_data, pclxl_image_end_image
};
@@ -582,12 +595,12 @@ private void
pclxl_write_begin_image(gx_device_pclxl * xdev, uint width, uint height,
uint dest_width, uint dest_height)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
- put_usa(s, width, pxaSourceWidth);
- put_usa(s, height, pxaSourceHeight);
- put_usp(s, dest_width, dest_height);
- put_ac(s, pxaDestinationSize, pxtBeginImage);
+ px_put_usa(s, width, pxaSourceWidth);
+ px_put_usa(s, height, pxaSourceHeight);
+ px_put_usp(s, dest_width, dest_height);
+ px_put_ac(s, pxaDestinationSize, pxtBeginImage);
}
/* Write rows of an image. */
@@ -596,21 +609,21 @@ private void
pclxl_write_image_data(gx_device_pclxl * xdev, const byte * data, int data_bit,
uint raster, uint width_bits, int y, int height)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
uint width_bytes = (width_bits + 7) >> 3;
- bool compress = width_bytes >= 8;
- uint num_bytes = round_up(width_bytes, 4) * height;
+ uint num_bytes = ROUND_UP(width_bytes, 4) * height;
+ bool compress = num_bytes >= 8;
int i;
- put_usa(s, y, pxaStartLine);
- put_usa(s, height, pxaBlockHeight);
+ px_put_usa(s, y, pxaStartLine);
+ px_put_usa(s, height, pxaBlockHeight);
if (compress) {
stream_RLE_state rlstate;
stream_cursor_write w;
stream_cursor_read r;
/*
- * H-P printers required that all the data for an operator be
+ * H-P printers require that all the data for an operator be
* contained in a single data block. Thus, we must allocate
* a temporary buffer for the compressed data. Currently we
* don't go to the trouble of breaking the data up into scan
@@ -656,9 +669,9 @@ pclxl_write_image_data(gx_device_pclxl * xdev, const byte * data, int data_bit,
{
uint count = w.ptr + 1 - buf;
- put_ub(s, eRLECompression);
- put_ac(s, pxaCompressMode, pxtReadImage);
- put_data_length(s, count);
+ px_put_ub(s, eRLECompression);
+ px_put_ac(s, pxaCompressMode, pxtReadImage);
+ px_put_data_length(s, count);
px_put_bytes(s, buf, count);
}
return;
@@ -666,9 +679,9 @@ pclxl_write_image_data(gx_device_pclxl * xdev, const byte * data, int data_bit,
nc:;
}
/* Write the data uncompressed. */
- put_ub(s, eNoCompression);
- put_ac(s, pxaCompressMode, pxtReadImage);
- put_data_length(s, num_bytes);
+ px_put_ub(s, eNoCompression);
+ px_put_ac(s, pxaCompressMode, pxtReadImage);
+ px_put_data_length(s, num_bytes);
for (i = 0; i < height; ++i) {
px_put_bytes(s, data + i * raster, width_bytes);
px_put_bytes(s, (const byte *)"\000\000\000\000", -width_bytes & 3);
@@ -686,95 +699,92 @@ pclxl_write_end_image(gx_device_pclxl * xdev)
/* Write a string (single- or double-byte). */
private void
-put_string(stream * s, const byte * data, uint len, bool wide)
+px_put_string(stream * s, const byte * data, uint len, bool wide)
{
if (wide) {
spputc(s, pxt_uint16_array);
- put_u(s, len);
+ px_put_u(s, len);
px_put_bytes(s, data, len * 2);
} else {
spputc(s, pxt_ubyte_array);
- put_u(s, len);
+ px_put_u(s, len);
px_put_bytes(s, data, len);
}
}
/* Write a 16-bit big-endian value. */
private void
-put_us_be(stream * s, uint i)
+px_put_us_be(stream * s, uint i)
{
spputc(s, (byte) (i >> 8));
spputc(s, (byte) i);
}
-/* Define a bitmap font. The client must call put_string */
+/* Define a bitmap font. The client must call px_put_string */
/* with the font name immediately before calling this procedure. */
private void
pclxl_define_bitmap_font(gx_device_pclxl * xdev)
{
- stream *s = gdev_vector_stream(vxdev);
- static const byte bfh_[] =
- {
- da(pxaFontName), dub(0), da(pxaFontFormat),
+ stream *s = pclxl_stream(xdev);
+ static const byte bfh_[] = {
+ DA(pxaFontName), DUB(0), DA(pxaFontFormat),
pxtBeginFontHeader,
- dus(8 + 6 + 4 + 6), da(pxaFontHeaderLength),
+ DUS(8 + 6 + 4 + 6), DA(pxaFontHeaderLength),
pxtReadFontHeader,
pxt_dataLengthByte, 8 + 6 + 4 + 6,
0, 0, 0, 0,
- 254, 0, (max_cached_chars + 255) >> 8, 0,
+ 254, 0, (MAX_CACHED_CHARS + 255) >> 8, 0,
'B', 'R', 0, 0, 0, 4
};
- static const byte efh_[] =
- {
+ static const byte efh_[] = {
0xff, 0xff, 0, 0, 0, 0,
pxtEndFontHeader
};
- put_lit(s, bfh_);
- put_us_be(s, (uint) (xdev->HWResolution[0] + 0.5));
- put_us_be(s, (uint) (xdev->HWResolution[1] + 0.5));
- put_lit(s, efh_);
+ PX_PUT_LIT(s, bfh_);
+ px_put_us_be(s, (uint) (xdev->HWResolution[0] + 0.5));
+ px_put_us_be(s, (uint) (xdev->HWResolution[1] + 0.5));
+ PX_PUT_LIT(s, efh_);
}
-/* Set the font. The client must call put_string */
+/* Set the font. The client must call px_put_string */
/* with the font name immediately before calling this procedure. */
private void
pclxl_set_font(gx_device_pclxl * xdev)
{
- stream *s = gdev_vector_stream(vxdev);
- static const byte sf_[] =
- {
- da(pxaFontName), dub(1), da(pxaCharSize), dus(0), da(pxaSymbolSet),
+ stream *s = pclxl_stream(xdev);
+ static const byte sf_[] = {
+ DA(pxaFontName), DUB(1), DA(pxaCharSize), DUS(0), DA(pxaSymbolSet),
pxtSetFont
};
- put_lit(s, sf_);
+ PX_PUT_LIT(s, sf_);
}
-/* Define a character in a bitmap font. The client must call put_string */
+/* Define a character in a bitmap font. The client must call px_put_string */
/* with the font name immediately before calling this procedure. */
private void
pclxl_define_bitmap_char(gx_device_pclxl * xdev, uint ccode,
const byte * data, uint raster, uint width_bits, uint height)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
uint width_bytes = (width_bits + 7) >> 3;
uint size = 10 + width_bytes * height;
uint i;
- put_ac(s, pxaFontName, pxtBeginChar);
- put_u(s, ccode);
- put_a(s, pxaCharCode);
+ px_put_ac(s, pxaFontName, pxtBeginChar);
+ px_put_u(s, ccode);
+ px_put_a(s, pxaCharCode);
if (size > 0xffff) {
spputc(s, pxt_uint32);
- put_l(s, (ulong) size);
+ px_put_l(s, (ulong) size);
} else
- put_us(s, size);
- put_ac(s, pxaCharDataSize, pxtReadChar);
- put_data_length(s, size);
+ px_put_us(s, size);
+ px_put_ac(s, pxaCharDataSize, pxtReadChar);
+ px_put_data_length(s, size);
px_put_bytes(s, (const byte *)"\000\000\000\000\000\000", 6);
- put_us_be(s, width_bits);
- put_us_be(s, height);
+ px_put_us_be(s, width_bits);
+ px_put_us_be(s, height);
for (i = 0; i < height; ++i)
px_put_bytes(s, data + i * raster, width_bytes);
spputc(s, pxtEndChar);
@@ -784,9 +794,9 @@ pclxl_define_bitmap_char(gx_device_pclxl * xdev, uint ccode,
private void
pclxl_write_font_name(gx_device_pclxl * xdev)
{
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
- put_string(s, (const byte *)"@", 1, false);
+ px_put_string(s, (const byte *)"@", 1, false);
}
/* Look up a bitmap id, return the index in the character table. */
@@ -797,7 +807,7 @@ pclxl_char_index(gx_device_pclxl * xdev, gs_id id)
int i, i_empty = -1;
uint ccode;
- for (i = (id * char_hash_factor) % countof(xdev->chars.table);;
+ for (i = (id * CHAR_HASH_FACTOR) % countof(xdev->chars.table);;
i = (i == 0 ? countof(xdev->chars.table) : i) - 1
) {
ccode = xdev->chars.table[i];
@@ -847,21 +857,21 @@ pclxl_copy_text_char(gx_device_pclxl * xdev, const byte * data,
uint size = width_bytes * h;
int index;
uint ccode;
- stream *s = gdev_vector_stream(vxdev);
+ stream *s = pclxl_stream(xdev);
- if (size > max_char_size)
+ if (size > MAX_CHAR_SIZE)
return -1;
index = pclxl_char_index(xdev, id);
if ((ccode = xdev->chars.table[index]) < 2) {
/* Enter the character in the table. */
- while (xdev->chars.used + size > max_char_data ||
- xdev->chars.count >= max_cached_chars - 2
+ while (xdev->chars.used + size > MAX_CHAR_DATA ||
+ xdev->chars.count >= MAX_CACHED_CHARS - 2
) {
ccode = xdev->chars.next_out;
index = pclxl_char_index(xdev, xdev->chars.data[ccode].id);
pclxl_remove_char(xdev, index);
xdev->chars.next_out =
- (ccode == max_cached_chars - 1 ? 2 : ccode + 1);
+ (ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
}
index = pclxl_char_index(xdev, id);
ccode = xdev->chars.next_in;
@@ -869,7 +879,7 @@ pclxl_copy_text_char(gx_device_pclxl * xdev, const byte * data,
xdev->chars.data[ccode].size = size;
xdev->chars.table[index] = ccode;
xdev->chars.next_in =
- (ccode == max_cached_chars - 1 ? 2 : ccode + 1);
+ (ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
if (!xdev->chars.count++) {
/* This is the very first character. */
pclxl_write_font_name(xdev);
@@ -888,44 +898,44 @@ pclxl_copy_text_char(gx_device_pclxl * xdev, const byte * data,
cc_bytes[0] = (byte) ccode;
cc_bytes[1] = ccode >> 8;
- put_string(s, cc_bytes, 1, cc_bytes[1] != 0);
+ px_put_string(s, cc_bytes, 1, cc_bytes[1] != 0);
}
- put_ac(s, pxaTextData, pxtText);
+ px_put_ac(s, pxaTextData, pxtText);
return 0;
}
/* ---------------- Vector implementation procedures ---------------- */
-#define xvdev ((gx_device_pclxl *)vdev)
-
private int
pclxl_beginpage(gx_device_vector * vdev)
-{ /*
- * We can't use gdev_vector_stream here, because this may be called
- * from there before in_page is set.
- */
+{
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+ /*
+ * We can't use gdev_vector_stream here, because this may be called
+ * from there before in_page is set.
+ */
stream *s = vdev->strm;
{
- static const byte page_header_1[] =
- {
- dub(ePortraitOrientation), da(pxaOrientation),
+ static const byte page_header_1[] = {
+ DUB(ePortraitOrientation), DA(pxaOrientation),
};
- put_lit(s, page_header_1);
+ PX_PUT_LIT(s, page_header_1);
}
{
-#define msd(ms, res, w, h)\
+#define MSD(ms, res, w, h)\
{ ms, (w) * 1.0 / (res), (h) * 1.0 / res },
static const struct {
pxeMediaSize_t ms;
float width, height;
} media_sizes[] = {
- px_enumerate_media(msd) {
- pxeMediaSize_next
- }
+ px_enumerate_media(MSD)
+ { pxeMediaSize_next }
};
- float w = vdev->width / vdev->HWResolution[0], h = vdev->height / vdev->HWResolution[1];
+#undef MSD
+ float w = vdev->width / vdev->HWResolution[0],
+ h = vdev->height / vdev->HWResolution[1];
int i;
pxeMediaSize_t size;
@@ -940,15 +950,14 @@ pclxl_beginpage(gx_device_vector * vdev)
* According to the PCL XL documentation, MediaSize must always
* be specified, but MediaSource is optional.
*/
- put_uba(s, size, pxaMediaSize);
- if (size != xvdev->media_size) {
- static const byte page_header_2[] =
- {
- dub(eAutoSelect), da(pxaMediaSource)
+ px_put_uba(s, size, pxaMediaSize);
+ if (size != xdev->media_size) {
+ static const byte page_header_2[] = {
+ DUB(eAutoSelect), DA(pxaMediaSource)
};
- put_lit(s, page_header_2);
- xvdev->media_size = size;
+ PX_PUT_LIT(s, page_header_2);
+ xdev->media_size = size;
}
}
spputc(s, pxtBeginPage);
@@ -960,8 +969,9 @@ pclxl_setlinewidth(gx_device_vector * vdev, floatp width)
{
stream *s = gdev_vector_stream(vdev);
- put_us(s, (uint) width);
- return_put_ac(s, pxaPenWidth, pxtSetPenWidth);
+ px_put_us(s, (uint) width);
+ px_put_ac(s, pxaPenWidth, pxtSetPenWidth);
+ return 0;
}
private int
@@ -970,8 +980,9 @@ pclxl_setlinecap(gx_device_vector * vdev, gs_line_cap cap)
stream *s = gdev_vector_stream(vdev);
/* The PCL XL cap styles just happen to be identical to PostScript. */
- put_ub(s, (byte) cap);
- return_put_ac(s, pxaLineCapStyle, pxtSetLineCap);
+ px_put_ub(s, (byte) cap);
+ px_put_ac(s, pxaLineCapStyle, pxtSetLineCap);
+ return 0;
}
private int
@@ -980,23 +991,24 @@ pclxl_setlinejoin(gx_device_vector * vdev, gs_line_join join)
stream *s = gdev_vector_stream(vdev);
/* The PCL XL join styles just happen to be identical to PostScript. */
- put_ub(s, (byte) join);
- return_put_ac(s, pxaLineJoinStyle, pxtSetLineJoin);
+ px_put_ub(s, (byte) join);
+ px_put_ac(s, pxaLineJoinStyle, pxtSetLineJoin);
+ return 0;
}
private int
pclxl_setmiterlimit(gx_device_vector * vdev, floatp limit)
{
stream *s = gdev_vector_stream(vdev);
-
/*
* Amazingly enough, the PCL XL specification doesn't allow real
* numbers for the miter limit.
*/
int i_limit = (int)(limit + 0.5);
- put_u(s, max(i_limit, 1));
- return_put_ac(s, pxaMiterLength, pxtSetMiterLimit);
+ px_put_u(s, max(i_limit, 1));
+ px_put_ac(s, pxaMiterLength, pxtSetMiterLimit);
+ return 0;
}
private int
@@ -1006,23 +1018,28 @@ pclxl_setdash(gx_device_vector * vdev, const float *pattern, uint count,
stream *s = gdev_vector_stream(vdev);
if (count == 0) {
- static const byte nac_[] =
- {dub(0), da(pxaSolidLine)};
+ static const byte nac_[] = {
+ DUB(0), DA(pxaSolidLine)
+ };
- put_lit(s, nac_);
+ PX_PUT_LIT(s, nac_);
} else if (count > 255)
return_error(gs_error_limitcheck);
else {
uint i;
- spputc(s, pxt_real32_array);
- put_ub(s, count);
+ /*
+ * Astoundingly, PCL XL doesn't allow real numbers here.
+ * Do the best we can.
+ */
+ spputc(s, pxt_uint16_array);
+ px_put_ub(s, count);
for (i = 0; i < count; ++i)
- put_r(s, pattern[i]);
- put_a(s, pxaLineDashStyle);
+ px_put_s(s, (uint)pattern[i]);
+ px_put_a(s, pxaLineDashStyle);
if (offset != 0) {
- put_rl(s, offset);
- put_a(s, pxaDashOffset);
+ px_put_rl(s, offset);
+ px_put_a(s, pxaDashOffset);
}
}
spputc(s, pxtSetLineDash);
@@ -1036,16 +1053,16 @@ pclxl_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
stream *s = gdev_vector_stream(vdev);
if (diff & lop_S_transparent) {
- put_ub(s, (lop & lop_S_transparent ? 1 : 0));
- put_ac(s, pxaTxMode, pxtSetSourceTxMode);
+ px_put_ub(s, (lop & lop_S_transparent ? 1 : 0));
+ px_put_ac(s, pxaTxMode, pxtSetSourceTxMode);
}
if (diff & lop_T_transparent) {
- put_ub(s, (lop & lop_T_transparent ? 1 : 0));
- put_ac(s, pxaTxMode, pxtSetPaintTxMode);
+ px_put_ub(s, (lop & lop_T_transparent ? 1 : 0));
+ px_put_ac(s, pxaTxMode, pxtSetPaintTxMode);
}
if (lop_rop(diff)) {
- put_ub(s, lop_rop(lop));
- put_ac(s, pxaROP3, pxtSetROP);
+ px_put_ub(s, lop_rop(lop));
+ px_put_ac(s, pxaROP3, pxtSetROP);
}
return 0;
}
@@ -1053,36 +1070,40 @@ pclxl_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
private int
pclxl_setfillcolor(gx_device_vector * vdev, const gx_drawing_color * pdc)
{
- return pclxl_set_color(xvdev, pdc, pxaNullBrush, pxtSetBrushSource);
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+
+ return pclxl_set_color(xdev, pdc, pxaNullBrush, pxtSetBrushSource);
}
private int
pclxl_setstrokecolor(gx_device_vector * vdev, const gx_drawing_color * pdc)
{
- return pclxl_set_color(xvdev, pdc, pxaNullPen, pxtSetPenSource);
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+
+ return pclxl_set_color(xdev, pdc, pxaNullPen, pxtSetPenSource);
}
private int
pclxl_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1,
fixed y1, gx_path_type_t type)
{
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
stream *s = gdev_vector_stream(vdev);
if (type & (gx_path_type_fill | gx_path_type_stroke)) {
- pclxl_set_paints(xvdev, type);
- put_usq_fixed(s, x0, y0, x1, y1);
- put_ac(s, pxaBoundingBox, pxtRectangle);
+ pclxl_set_paints(xdev, type);
+ px_put_usq_fixed(s, x0, y0, x1, y1);
+ px_put_ac(s, pxaBoundingBox, pxtRectangle);
}
if (type & gx_path_type_clip) {
- static const byte cr_[] =
- {
- da(pxaBoundingBox),
- dub(eInterior), da(pxaClipRegion),
+ static const byte cr_[] = {
+ DA(pxaBoundingBox),
+ DUB(eInterior), DA(pxaClipRegion),
pxtSetClipRectangle
};
- put_usq_fixed(s, x0, y0, x1, y1);
- put_lit(s, cr_);
+ px_put_usq_fixed(s, x0, y0, x1, y1);
+ PX_PUT_LIT(s, cr_);
}
return 0;
}
@@ -1090,11 +1111,12 @@ pclxl_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1,
private int
pclxl_beginpath(gx_device_vector * vdev, gx_path_type_t type)
{
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
stream *s = gdev_vector_stream(vdev);
spputc(s, pxtNewPath);
- xvdev->points.type = points_none;
- xvdev->points.count = 0;
+ xdev->points.type = POINTS_NONE;
+ xdev->points.count = 0;
return 0;
}
@@ -1102,33 +1124,36 @@ private int
pclxl_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
gx_path_type_t type)
{
- int code = pclxl_flush_points(xvdev);
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+ int code = pclxl_flush_points(xdev);
if (code < 0)
return code;
- return pclxl_set_cursor(xvdev,
- xvdev->points.current.x = (int)x,
- xvdev->points.current.y = (int)y);
+ return pclxl_set_cursor(xdev,
+ xdev->points.current.x = (int)x,
+ xdev->points.current.y = (int)y);
}
private int
pclxl_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
gx_path_type_t type)
{
- if (xvdev->points.type != points_lines ||
- xvdev->points.count >= num_points
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+
+ if (xdev->points.type != POINTS_LINES ||
+ xdev->points.count >= NUM_POINTS
) {
- if (xvdev->points.type != points_none) {
- int code = pclxl_flush_points(xvdev);
+ if (xdev->points.type != POINTS_NONE) {
+ int code = pclxl_flush_points(xdev);
if (code < 0)
return code;
}
- xvdev->points.current.x = (int)x0;
- xvdev->points.current.y = (int)y0;
- xvdev->points.type = points_lines;
+ xdev->points.current.x = (int)x0;
+ xdev->points.current.y = (int)y0;
+ xdev->points.type = POINTS_LINES;
} {
- gs_int_point *ppt = &xvdev->points.data[xvdev->points.count++];
+ gs_int_point *ppt = &xdev->points.data[xdev->points.count++];
ppt->x = (int)x, ppt->y = (int)y;
}
@@ -1140,26 +1165,29 @@ pclxl_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 (xvdev->points.type != points_curves ||
- xvdev->points.count >= num_points - 2
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
+
+ if (xdev->points.type != POINTS_CURVES ||
+ xdev->points.count >= NUM_POINTS - 2
) {
- if (xvdev->points.type != points_none) {
- int code = pclxl_flush_points(xvdev);
+ if (xdev->points.type != POINTS_NONE) {
+ int code = pclxl_flush_points(xdev);
if (code < 0)
return code;
}
- xvdev->points.current.x = (int)x0;
- xvdev->points.current.y = (int)y0;
- xvdev->points.type = points_curves;
- } {
- gs_int_point *ppt = &xvdev->points.data[xvdev->points.count];
+ xdev->points.current.x = (int)x0;
+ xdev->points.current.y = (int)y0;
+ xdev->points.type = POINTS_CURVES;
+ }
+ {
+ gs_int_point *ppt = &xdev->points.data[xdev->points.count];
ppt->x = (int)x1, ppt->y = (int)y1, ++ppt;
ppt->x = (int)x2, ppt->y = (int)y2, ++ppt;
ppt->x = (int)x3, ppt->y = (int)y3;
}
- xvdev->points.count += 3;
+ xdev->points.count += 3;
return 0;
}
@@ -1167,51 +1195,51 @@ private int
pclxl_closepath(gx_device_vector * vdev, floatp x, floatp y,
floatp x_start, floatp y_start, gx_path_type_t type)
{
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
stream *s = gdev_vector_stream(vdev);
- int code = pclxl_flush_points(xvdev);
+ int code = pclxl_flush_points(xdev);
if (code < 0)
return code;
spputc(s, pxtCloseSubPath);
- xvdev->points.current.x = (int)x_start;
- xvdev->points.current.y = (int)y_start;
+ xdev->points.current.x = (int)x_start;
+ xdev->points.current.y = (int)y_start;
return 0;
}
private int
pclxl_endpath(gx_device_vector * vdev, gx_path_type_t type)
{
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
stream *s = gdev_vector_stream(vdev);
- int code = pclxl_flush_points(xvdev);
+ int code = pclxl_flush_points(xdev);
gx_path_type_t rule = type & gx_path_type_rule;
if (code < 0)
return code;
if (type & (gx_path_type_fill | gx_path_type_stroke)) {
- pclxl_set_paints(xvdev, type);
+ pclxl_set_paints(xdev, type);
spputc(s, pxtPaintPath);
}
if (type & gx_path_type_clip) {
- static const byte scr_[] =
- {
- dub(eInterior), da(pxaClipRegion), pxtSetClipReplace
+ static const byte scr_[] = {
+ DUB(eInterior), DA(pxaClipRegion), pxtSetClipReplace
};
- if (rule != xvdev->clip_rule) {
- put_ub(s, (rule == gx_path_type_even_odd ? eEvenOdd :
+ if (rule != xdev->clip_rule) {
+ px_put_ub(s, (rule == gx_path_type_even_odd ? eEvenOdd :
eNonZeroWinding));
- put_ac(s, pxaClipMode, pxtSetClipMode);
- xvdev->clip_rule = rule;
+ px_put_ac(s, pxaClipMode, pxtSetClipMode);
+ xdev->clip_rule = rule;
}
- put_lit(s, scr_);
+ PX_PUT_LIT(s, scr_);
}
return 0;
}
/* Vector implementation procedures */
-private const gx_device_vector_procs pclxl_vector_procs =
-{
+private const gx_device_vector_procs pclxl_vector_procs = {
/* Page management */
pclxl_beginpage,
/* Imager state */
@@ -1238,27 +1266,25 @@ private const gx_device_vector_procs pclxl_vector_procs =
/* ---------------- Driver procedures ---------------- */
-#define vdev ((gx_device_vector *)dev)
-#define xdev ((gx_device_pclxl *)dev)
-
/* ------ Open/close/page ------ */
/* Open the device. */
private int
pclxl_open_device(gx_device * dev)
{
+ gx_device_vector *const vdev = (gx_device_vector *)dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
int code;
static const char *const file_header =
- "\033%-12345X@PJL ENTER LANGUAGE = PCLXL\n\
+ "\033%-12345X@PJL ENTER LANGUAGE = PCLXL\n\
) HP-PCL XL;1;1;Comment Copyright Aladdin Enterprises 1996\000\n";
- static const byte stream_header[] =
- {
- da(pxaUnitsPerMeasure),
- dub(0), da(pxaMeasure),
- dub(eBackChAndErrPage), da(pxaErrorReport),
+ static const byte stream_header[] = {
+ DA(pxaUnitsPerMeasure),
+ DUB(0), DA(pxaMeasure),
+ DUB(eBackChAndErrPage), DA(pxaErrorReport),
pxtBeginSession,
- dub(0), da(pxaSourceType),
- dub(eBinaryLowByteFirst), da(pxaDataOrg),
+ DUB(0), DA(pxaSourceType),
+ DUB(eBinaryLowByteFirst), DA(pxaDataOrg),
pxtOpenDataSource
};
@@ -1275,10 +1301,10 @@ pclxl_open_device(gx_device * dev)
/* We have to add 2 to the strlen because the next-to-last */
/* character is a null. */
px_put_bytes(s, (const byte *)file_header,
- strlen(file_header) + 2);
- put_usp(s, (uint) (dev->HWResolution[0] + 0.5),
- (uint) (dev->HWResolution[1] + 0.5));
- put_lit(s, stream_header);
+ strlen(file_header) + 2);
+ px_put_usp(s, (uint) (dev->HWResolution[0] + 0.5),
+ (uint) (dev->HWResolution[1] + 0.5));
+ PX_PUT_LIT(s, stream_header);
}
xdev->media_size = pxeMediaSize_next; /* no size selected */
memset(&xdev->chars, 0, sizeof(xdev->chars));
@@ -1291,15 +1317,17 @@ pclxl_open_device(gx_device * dev)
private int
pclxl_output_page(gx_device * dev, int num_copies, int flush)
{
- if (xdev->in_page) {
- stream *s = vdev->strm;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
+ stream *s;
- spputc(s, pxtEndPage);
- sflush(s);
- pclxl_page_init(xdev);
- return gx_finish_output_page(dev, num_copies, flush);
- }
- return 0;
+ /* Note that unlike close_device, end_page must not omit blank pages. */
+ if (!xdev->in_page)
+ pclxl_beginpage((gx_device_vector *)dev);
+ s = xdev->strm;
+ spputc(s, pxtEndPage);
+ sflush(s);
+ pclxl_page_init(xdev);
+ return gx_finish_output_page(dev, num_copies, flush);
}
/* Close the device. */
@@ -1308,13 +1336,13 @@ pclxl_output_page(gx_device * dev, int num_copies, int flush)
private int
pclxl_close_device(gx_device * dev)
{
- FILE *file = vdev->file;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
+ FILE *file = xdev->file;
if (xdev->in_page)
fputc(pxtEndPage, file);
{
- static const byte file_trailer[] =
- {
+ static const byte file_trailer[] = {
pxtCloseDataSource,
pxtEndSession,
033, '%', '-', '1', '2', '3', '4', '5', 'X'
@@ -1323,23 +1351,24 @@ pclxl_close_device(gx_device * dev)
/* The stream may no longer exist: see above. */
fwrite(file_trailer, 1, sizeof(file_trailer), file);
}
- gdev_vector_close_file(vdev);
+ gdev_vector_close_file((gx_device_vector *)dev);
return 0;
}
/* ------ One-for-one images ------ */
-private const byte eBit_values[] =
-{
+private const byte eBit_values[] = {
0, e1Bit, 0, 0, e4Bit, 0, 0, 0, e8Bit
};
/* Copy a monochrome bitmap. */
private int
-pclxl_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,
+pclxl_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_device_vector *const vdev = (gx_device_vector *)dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
int code;
stream *s;
gx_color_index color0 = zero, color1 = one;
@@ -1359,7 +1388,7 @@ pclxl_copy_mono(gx_device * dev, const byte * data,
gx_drawing_color dcolor;
color_set_pure(&dcolor, one);
- pclxl_setfillcolor(vxdev, &dcolor);
+ pclxl_setfillcolor(vdev, &dcolor);
if (pclxl_copy_text_char(xdev, data, raster, id, w, h) >= 0)
return 0;
}
@@ -1379,7 +1408,7 @@ pclxl_copy_mono(gx_device * dev, const byte * data,
lop = rop3_S;
}
if (dev->color_info.num_components == 1 ||
- (rgb_is_gray(color0) && rgb_is_gray(color1))
+ (RGB_IS_GRAY(color0) && RGB_IS_GRAY(color1))
) {
palette[0] = (byte) color0;
palette[1] = (byte) color1;
@@ -1399,15 +1428,14 @@ pclxl_copy_mono(gx_device * dev, const byte * data,
if (code < 0)
return 0;
pclxl_set_color_palette(xdev, color_space, palette, palette_size);
- s = gdev_vector_stream(vxdev);
+ s = pclxl_stream(xdev);
{
- static const byte mi_[] =
- {
- dub(e1Bit), da(pxaColorDepth),
- dub(eIndexedPixel), da(pxaColorMapping)
+ static const byte mi_[] = {
+ DUB(e1Bit), DA(pxaColorDepth),
+ DUB(eIndexedPixel), DA(pxaColorMapping)
};
- put_lit(s, mi_);
+ PX_PUT_LIT(s, mi_);
}
pclxl_write_begin_image(xdev, w, h, w, h);
pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h);
@@ -1421,6 +1449,8 @@ pclxl_copy_color(gx_device * dev,
const byte * base, int sourcex, int raster, gx_bitmap_id id,
int x, int y, int w, int h)
{
+ gx_device_vector *const vdev = (gx_device_vector *)dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
stream *s;
uint source_bit;
int code;
@@ -1435,16 +1465,16 @@ pclxl_copy_color(gx_device * dev,
x, y, w, h);
gdev_vector_update_log_op(vdev, rop3_S);
pclxl_set_cursor(xdev, x, y);
- s = gdev_vector_stream(vxdev);
+ s = pclxl_stream(xdev);
{
- static const byte ci_[] =
- {
- da(pxaColorDepth),
- dub(eDirectPixel), da(pxaColorMapping)
+ static const byte ci_[] = {
+ DA(pxaColorDepth),
+ DUB(eDirectPixel), DA(pxaColorMapping)
};
- put_ub(s, eBit_values[dev->color_info.depth / dev->color_info.num_components]);
- put_lit(s, ci_);
+ px_put_ub(s, eBit_values[dev->color_info.depth /
+ dev->color_info.num_components]);
+ PX_PUT_LIT(s, ci_);
}
pclxl_write_begin_image(xdev, w, h, w, h);
pclxl_write_image_data(xdev, base, source_bit, raster,
@@ -1461,6 +1491,8 @@ pclxl_fill_mask(gx_device * dev,
const gx_drawing_color * pdcolor, int depth,
gs_logical_operation_t lop, const gx_clip_path * pcpath)
{
+ gx_device_vector *const vdev = (gx_device_vector *)dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
int code;
stream *s;
@@ -1488,15 +1520,14 @@ pclxl_fill_mask(gx_device * dev,
if (code < 0)
return 0;
pclxl_set_color_palette(xdev, eGray, (const byte *)"\377\000", 2);
- s = gdev_vector_stream(vxdev);
+ s = pclxl_stream(xdev);
{
- static const byte mi_[] =
- {
- dub(e1Bit), da(pxaColorDepth),
- dub(eIndexedPixel), da(pxaColorMapping)
+ static const byte mi_[] = {
+ DUB(e1Bit), DA(pxaColorDepth),
+ DUB(eIndexedPixel), DA(pxaColorMapping)
};
- put_lit(s, mi_);
+ PX_PUT_LIT(s, mi_);
}
pclxl_write_begin_image(xdev, w, h, w, h);
pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h);
@@ -1506,10 +1537,11 @@ pclxl_fill_mask(gx_device * dev,
/* Do a RasterOp. */
private int
-pclxl_strip_copy_rop(gx_device * dev,
- const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
+pclxl_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,
+ 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)
{ /* We can't do general RasterOps yet. */
@@ -1520,7 +1552,6 @@ pclxl_strip_copy_rop(gx_device * dev,
/* ------ High-level images ------ */
typedef gdev_vector_image_enum_t pclxl_image_enum_t;
-
#define st_pclxl_image_enum st_vector_image_enum
/* Start processing an image. */
@@ -1528,26 +1559,28 @@ private int
pclxl_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)
+ const gx_drawing_color * pdcolor,
+ const gx_clip_path * pcpath, gs_memory_t * mem,
+ gx_image_enum_common_t ** pinfo)
{
+ gx_device_vector *const vdev = (gx_device_vector *)dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
const gs_color_space *pcs = pim->ColorSpace;
pclxl_image_enum_t *pie;
- int bits_per_pixel;
+ /*
+ * Following should divide by num_planes, but we only handle chunky
+ * images, i.e., num_planes = 1.
+ */
+ int bits_per_pixel =
+ (pim->ImageMask ? 1 :
+ pim->BitsPerComponent * gs_color_space_num_components(pcs));
gs_matrix mat;
int code;
- pie = gs_alloc_struct(mem, pclxl_image_enum_t, &st_pclxl_image_enum,
- "pclxl_begin_image");
- if (pie == 0)
- return_error(gs_error_VMerror);
- code = gdev_vector_begin_image(vdev, pis, pim, format, prect,
- pdcolor, pcpath, mem,
- &pclxl_image_enum_procs, pie);
- if (code < 0)
- return code;
- bits_per_pixel = pie->bits_per_pixel;
- *pinfo = (gx_image_enum_common_t *) pie;
+ /*
+ * Check whether we can handle this image. PCL XL 1.0 and 2.0 only
+ * handle orthogonal transformations.
+ */
gs_matrix_invert(&pim->ImageMatrix, &mat);
gs_matrix_multiply(&mat, &ctm_only(pis), &mat);
/* Currently we only handle portrait transformations. */
@@ -1559,70 +1592,89 @@ pclxl_begin_image(gx_device * dev,
bits_per_pixel != 8))) ||
format != gs_image_format_chunky ||
prect
- ) {
- int code = gx_default_begin_image(dev, pis, pim, format, prect,
- pdcolor, pcpath, mem,
- &pie->default_info);
-
- if (code < 0)
- gs_free_object(mem, pie, "pclxl_begin_image");
+ )
+ return gx_default_begin_image(dev, pis, pim, format, prect,
+ pdcolor, pcpath, mem, pinfo);
+ pie = gs_alloc_struct(mem, pclxl_image_enum_t, &st_pclxl_image_enum,
+ "pclxl_begin_image");
+ if (pie == 0)
+ return_error(gs_error_VMerror);
+ code = gdev_vector_begin_image(vdev, pis, pim, format, prect,
+ pdcolor, pcpath, mem,
+ &pclxl_image_enum_procs, pie);
+ if (code < 0)
return code;
- } {
- stream *s = gdev_vector_stream(vxdev);
+ *pinfo = (gx_image_enum_common_t *) pie;
+ pclxl_set_cursor(xdev, (int)((mat.tx + 0.5) / xdev->scale.x),
+ (int)((mat.ty + 0.5) / xdev->scale.y));
+ {
+ stream *s = pclxl_stream(xdev);
gs_logical_operation_t lop = pis->log_op;
- int code = gdev_vector_update_log_op
- (vdev, (pim->ImageMask || pim->CombineWithColor ? lop :
- rop3_know_T_0(lop)));
- int bpc = pim->BitsPerComponent;
- int num_components = pie->plane_depths[0] * pie->num_planes / bpc;
- int sample_max = (1 << bpc) - 1;
- byte palette[256 * 3];
- int i;
- if (code < 0)
- return code;
- pclxl_set_cursor(xdev, (int)((mat.tx + 0.5) / xdev->scale.x),
- (int)((mat.ty + 0.5) / xdev->scale.y));
- for (i = 0; i < 1 << bits_per_pixel; ++i) {
- gs_client_color cc;
- gx_device_color devc;
- int cv = i, j;
-
- for (j = num_components - 1; j >= 0; cv >>= bpc, --j)
- cc.paint.values[j] = pim->Decode[j * 2] +
- (cv & sample_max) *
- (pim->Decode[j * 2 + 1] - pim->Decode[j * 2]) /
- sample_max;
- (*pcs->type->remap_color)
- (&cc, pcs, &devc, pis, dev, gs_color_select_source);
- if (!gx_dc_is_pure(&devc))
- return_error(gs_error_Fatal);
- if (dev->color_info.num_components == 1)
- palette[i] = (byte) gx_dc_pure_color(&devc);
- else {
- gx_color_index ci = gx_dc_pure_color(&devc);
- byte *ppal = &palette[i * 3];
-
- ppal[0] = (byte) (ci >> 16);
- ppal[1] = (byte) (ci >> 8);
- ppal[2] = (byte) ci;
+ if (pim->ImageMask) {
+ code = gdev_vector_update_fill_color(vdev, pdcolor);
+ if (code < 0)
+ return 0;
+ code = gdev_vector_update_log_op
+ (vdev, lop | rop3_S | lop_S_transparent);
+ if (code < 0)
+ return 0;
+ pclxl_set_color_palette(xdev, eGray,
+ (pim->Decode[0] ?
+ (const byte *)"\377\000" :
+ (const byte *)"\000\377"),
+ 2);
+ } else {
+ int bpc = pim->BitsPerComponent;
+ int num_components = pie->plane_depths[0] * pie->num_planes / bpc;
+ int sample_max = (1 << bpc) - 1;
+ byte palette[256 * 3];
+ int i;
+
+ code = gdev_vector_update_log_op
+ (vdev, (pim->CombineWithColor ? lop : rop3_know_T_0(lop)));
+ if (code < 0)
+ return code;
+ for (i = 0; i < 1 << bits_per_pixel; ++i) {
+ gs_client_color cc;
+ gx_device_color devc;
+ int cv = i, j;
+
+ for (j = num_components - 1; j >= 0; cv >>= bpc, --j)
+ cc.paint.values[j] = pim->Decode[j * 2] +
+ (cv & sample_max) *
+ (pim->Decode[j * 2 + 1] - pim->Decode[j * 2]) /
+ sample_max;
+ (*pcs->type->remap_color)
+ (&cc, pcs, &devc, pis, dev, gs_color_select_source);
+ if (!gx_dc_is_pure(&devc))
+ return_error(gs_error_Fatal);
+ if (dev->color_info.num_components == 1)
+ palette[i] = (byte) gx_dc_pure_color(&devc);
+ else {
+ gx_color_index ci = gx_dc_pure_color(&devc);
+ byte *ppal = &palette[i * 3];
+
+ ppal[0] = (byte) (ci >> 16);
+ ppal[1] = (byte) (ci >> 8);
+ ppal[2] = (byte) ci;
+ }
}
+ if (dev->color_info.num_components == 1)
+ pclxl_set_color_palette(xdev, eGray, palette,
+ 1 << bits_per_pixel);
+ else
+ pclxl_set_color_palette(xdev, eRGB, palette,
+ 3 << bits_per_pixel);
}
- if (dev->color_info.num_components == 1)
- pclxl_set_color_palette(xdev, eGray, palette,
- 1 << bits_per_pixel);
- else
- pclxl_set_color_palette(xdev, eRGB, palette,
- 3 << bits_per_pixel);
{
- static const byte ii_[] =
- {
- da(pxaColorDepth),
- dub(eIndexedPixel), da(pxaColorMapping)
+ static const byte ii_[] = {
+ DA(pxaColorDepth),
+ DUB(eIndexedPixel), DA(pxaColorMapping)
};
- put_ub(s, eBit_values[bits_per_pixel]);
- put_lit(s, ii_);
+ px_put_ub(s, eBit_values[bits_per_pixel]);
+ PX_PUT_LIT(s, ii_);
}
pclxl_write_begin_image(xdev, pim->Width, pim->Height,
(uint) (pim->Width * mat.xx),
@@ -1633,13 +1685,14 @@ pclxl_begin_image(gx_device * dev,
/* Process the next piece of an image. */
private int
-pclxl_image_plane_data(gx_device * dev,
- gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height)
+pclxl_image_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
{
+ gx_device *dev = info->dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
pclxl_image_enum_t *pie = (pclxl_image_enum_t *) info;
- if (pie->default_info)
- return gx_image_plane_data(pie->default_info, planes, height);
if (height > pie->height - pie->y)
height = pie->height - pie->y;
pclxl_write_image_data(xdev, planes[0].data,
@@ -1647,38 +1700,35 @@ pclxl_image_plane_data(gx_device * dev,
planes[0].raster,
pie->width * info->plane_depths[0],
pie->y, height);
+ *rows_used = height;
return (pie->y += height) >= pie->height;
}
/* Clean up by releasing the buffers. */
private int
-pclxl_image_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
+pclxl_image_end_image(gx_image_enum_common_t * info, bool draw_last)
{
+ gx_device *dev = info->dev;
+ gx_device_pclxl *const xdev = (gx_device_pclxl *)dev;
pclxl_image_enum_t *pie = (pclxl_image_enum_t *) info;
int code = 0;
- if (pie->default_info)
- code = gx_default_end_image(dev, pie->default_info, draw_last);
- else { /* Fill out to the full image height. */
-/****** WRONG -- REST OF IMAGE SHOULD BE TRANSPARENT ******/
- if (pie->height > pie->y) {
- uint bytes_per_row = (pie->bits_per_row + 7) >> 3;
- byte *row = gs_alloc_bytes(pie->memory, bytes_per_row,
- "pclxl_end_image(fill)");
-
- if (row == 0)
- return_error(gs_error_VMerror);
- memset(row, 0, bytes_per_row);
- for (; pie->y < pie->height; pie->y++)
- pclxl_write_image_data(xdev, row, 0, bytes_per_row,
- pie->bits_per_row, pie->y, 1);
- gs_free_object(pie->memory, row, "pclxl_end_image(fill)");
- }
- pclxl_write_end_image(xdev);
+ /* Fill out to the full image height. */
+ /****** WRONG -- REST OF IMAGE SHOULD BE TRANSPARENT ******/
+ if (pie->height > pie->y) {
+ uint bytes_per_row = (pie->bits_per_row + 7) >> 3;
+ byte *row = gs_alloc_bytes(pie->memory, bytes_per_row,
+ "pclxl_end_image(fill)");
+
+ if (row == 0)
+ return_error(gs_error_VMerror);
+ memset(row, 0, bytes_per_row);
+ for (; pie->y < pie->height; pie->y++)
+ pclxl_write_image_data(xdev, row, 0, bytes_per_row,
+ pie->bits_per_row, pie->y, 1);
+ gs_free_object(pie->memory, row, "pclxl_end_image(fill)");
}
+ pclxl_write_end_image(xdev);
gs_free_object(pie->memory, pie, "pclxl_end_image");
return code;
}
-
-#undef vdev
diff --git a/gs/src/gdevrops.c b/gs/src/gdevrops.c
index 44538123f..675a38c77 100644
--- a/gs/src/gdevrops.c
+++ b/gs/src/gdevrops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,7 +26,6 @@
/* GC procedures */
private_st_device_rop_texture();
-#define rtdev ((gx_device_rop_texture *)vptr)
private ENUM_PTRS_BEGIN(device_rop_texture_enum_ptrs) {
if (index < st_device_color_max_ptrs) {
gs_ptr_type_t ptype =
@@ -42,7 +41,6 @@ private RELOC_PTRS_BEGIN(device_rop_texture_reloc_ptrs) {
RELOC_PREFIX(st_device_forward);
RELOC_SUPER(gx_device_rop_texture, st_device_color, texture);
} RELOC_PTRS_END
-#undef rtdev
/* Device for providing source data for RasterOp. */
private dev_proc_fill_rectangle(rop_texture_fill_rectangle);
@@ -120,12 +118,10 @@ gx_make_rop_texture_device(gx_device_rop_texture * dev, gx_device * target,
gx_device_init((gx_device *) dev,
(const gx_device *)&gs_rop_texture_device,
NULL, true);
+ gx_device_set_target((gx_device_forward *)dev, target);
/* Drawing operations are defaulted, non-drawing are forwarded. */
gx_device_fill_in_procs((gx_device *) dev);
- dev->width = target->width;
- dev->height = target->height;
- dev->color_info = target->color_info;
- dev->target = target;
+ gx_device_copy_params((gx_device *)dev, target);
dev->log_op = log_op;
dev->texture = *texture;
}
diff --git a/gs/src/gdevrun.c b/gs/src/gdevrun.c
deleted file mode 100644
index adabe42e0..000000000
--- a/gs/src/gdevrun.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/* Copyright (C) 1995, 1998 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
-
-/* Run-length encoded "device" */
-#include "memory_.h"
-#include "gx.h"
-#include "gserrors.h"
-#include "gxdevice.h"
-#include "gxdevmem.h"
-
-/*
- * The pseudo-device in this file stores 8-bit "pixels" with run-length
- * encoding. Since it may allocate less space than is required to
- * store all possible values, it may have to discard some update requests.
- */
-
-/*
- * Define the representation of each run. We store runs in a doubly-
- * linked list using the old trick of storing only a single pointer which
- * is the xor of the successor and predecessor indices.
- * Run 0 is a dummy end-of-line run; run 1 is a dummy start-of-line run.
- * The dummy runs have length 255 to prevent merging.
- */
-typedef byte run_length;
-typedef byte run_value;
-typedef ushort run_index;
-typedef struct run_s {
- run_length length;
- run_value value;
- run_index nix; /* for allocated runs, xor of successor and */
- /* predecessor indices; for free runs, */
- /* index of next free run */
-} run;
-
-/*
- * Define a pointer into a run list. The xor trick requires that we
- * store both the current index and the next (or previous) one.
- * For speed, we keep both the index of and the pointer to the current run.
- */
-typedef struct run_ptr_s {
- run *ptr;
- run_index index; /* index of current run */
- run_index next; /* index of next run */
-} run_ptr;
-typedef struct const_run_ptr_s {
- const run *ptr;
- run_index index; /* index of current run */
- run_index next; /* index of next run */
-} const_run_ptr;
-
-/* Accessors */
-#define rp_length(rp) ((rp).ptr->length)
-#define rp_value(rp) ((rp).ptr->value)
-#define rp_nix(rp) ((rp).ptr->nix)
-/* Traversers */
-#define rp_at_start(rp) ((rp).index == 1)
-#define rp_at_end(rp) ((rp).index == 0)
-#define rp_start(rp, data)\
- ((rp).index = (data)[1].nix,\
- (rp).ptr = (data) + (rp).index,\
- (rp).next = rp_nix(rp) ^ 1)
-/* Note that rp_next and rp_prev allow rpn == rpc. */
-#define rp_next(rpc, data, rpn, itemp)\
- (itemp = (rpc).index,\
- (rpn).ptr = (data) + ((rpn).index = (rpc).next),\
- (rpn).next = itemp ^ rp_nix(rpn))
-#define rp_prev(rpc, data, rpp, itemp)\
- (itemp = (rpc).next ^ rp_nix(rpc),\
- (rpp).next = (rpc).index,\
- (rpp).ptr = (data) + ((rpp).index = itemp))
-/* Insert/delete */
-#define rp_delete_next(rpc, data, line, rpn, rpn2, itemp)\
- (rp_next(rpc, data, rpn, itemp),\
- rp_next(rpn, data, rpn2, itemp),\
- rp_nix(rpc) ^= (rpn).index ^ (rpn2).index,\
- rp_nix(rpn2) ^= (rpn).index ^ (rpc).index,\
- rp_nix(rpn) = (line)->free,\
- (line)->free = (rpn).index)
-#define rp_insert_next(rpc, data, line, rpn, itemp)\
- (rp_next(rpc, data, rpn, itemp),\
- itemp = (line)->free,\
- rp_nix(rpc) ^= (rpn).index ^ itemp,\
- rp_nix(rpn) ^= (rpc).index ^ itemp,\
- (rpn).next = (rpn).index,\
- (rpn).index = itemp,\
- (rpn).ptr = (data) + itemp,\
- (line)->free = rp_nix(rpn),\
- rp_nix(rpn) = (rpc).index ^ (rpn).next)
-#define rp_insert_prev(rpc, data, line, rpp, itemp)\
- (rp_prev(rpc, data, rpp, itemp),\
- itemp = (line)->free,\
- rp_nix(rpc) ^= (rpp).index ^ itemp,\
- rp_nix(rpp) ^= (rpc).index ^ itemp,\
- (rpp).ptr = (data) + itemp,\
- rp_nix(rpp) = (rpp).index ^ (rpc).index,\
- (rpp).index = itemp,\
- (line)->free = rp_nix(rpp))
-
-/*
- * Define the state of a single scan line.
- *
- * We maintain the following invariant: if two adjacent runs have the
- * same value, the sum of their lengths is at least 256. This may miss
- * optimality by nearly a factor of 2, but it's far easier to maintain
- * than a true optimal representation.
- *
- * For speed in the common case where nothing other than 0 is ever stored,
- * we initially don't bother to construct the runs (or the free run list)
- * for a line at all.
- */
-typedef struct run_line_s {
- run *data; /* base of runs */
- int zero; /* 0 if line not initialized, -1 if initialized */
- uint xcur; /* x value at cursor position */
- run_ptr rpcur; /* cursor */
- run_index free; /* head of free list */
-} run_line;
-
-/*
- * Define the device, built on an 8-bit memory device.
- */
-typedef struct gx_device_run_s {
- gx_device_memory md;
- uint runs_per_line;
- run_line *lines;
- int umin, umax1; /* some range of uninitialized lines */
-} gx_device_run;
-
-#define rdev ((gx_device_run *)dev)
-
-/* Open the device. */
-private int
-run_open(gx_device * dev)
-{
- run_line *line = rdev->lines;
- run *data = (run *) rdev->md.base;
- int i;
-
- /*
- * We need ceil(width / 255) runs to represent a line where all
- * elements have the same value, +2 for the start and end runs,
- * +2 for the check for 2 free runs when doing a replacement.
- */
- if (rdev->runs_per_line < (dev->width + 254) / 255 + 4)
- return_error(gs_error_rangecheck);
- for (i = 0; i < dev->height; ++line, data += rdev->runs_per_line, ++i) {
- line->data = data;
- line->zero = 0;
- }
- rdev->umin = 0;
- rdev->umax1 = dev->height;
- return 0;
-}
-
-/* Finish initializing a line. This is a separate procedure only */
-/* for readability. */
-private void
-run_line_initialize(gx_device * dev, int y)
-{
- run_line *line = &rdev->lines[y];
- run *data = line->data;
- int left = dev->width;
- run_index index = 2;
- run *rcur;
-
- line->zero = -1;
- data[0].length = 255; /* see above */
- data[0].value = 0; /* shouldn't matter */
- data[1].length = 255;
- data[1].value = 0;
- data[1].nix = 2;
- rcur = data + index;
- for (; left > 0; index++, rcur++, left -= 255) {
- rcur->length = min(left, 255);
- rcur->value = 0;
- rcur->nix = (index - 1) ^ (index + 1);
- }
- rcur->nix = index - 2;
- data[0].nix = index - 1;
- line->xcur = 0;
- line->rpcur.ptr = data + 2;
- line->rpcur.index = 2;
- line->rpcur.next = data[2].nix ^ 1;
- line->free = index;
- for (; index < rdev->runs_per_line; ++index)
- data[index].nix = index + 1;
- data[index - 1].nix = 0;
- if (y >= rdev->umin && y < rdev->umax1) {
- if (y > (rdev->umin + rdev->umax1) >> 1)
- rdev->umax1 = y;
- else
- rdev->umin = y + 1;
- }
-}
-
-/* Replace an interval of a line with a new value. This is the procedure */
-/* that does all the interesting work. We assume the line has been */
-/* initialized, and that 0 <= xo < xe <= dev->width. */
-private int
-run_fill_interval(run_line * line, int xo, int xe, run_value new)
-{
- run *data = line->data;
- int xc = line->xcur;
- run_ptr rpc;
- run_index itemp;
- int x0, x1;
- run_ptr rp0;
-
- rpc = line->rpcur;
-
- /* Find the run that contains xo. */
-
- if (xo < xc) {
- while (xo < xc)
- rp_prev(rpc, data, rpc, itemp), xc -= rp_length(rpc);
- } else {
- while (xo >= xc + rp_length(rpc))
- xc += rp_length(rpc), rp_next(rpc, data, rpc, itemp);
- }
-
- /*
- * Skip runs above xo that already contain the new value.
- * If the entire interval already has the correct value, exit.
- * If we skip any such runs, set xo to just above them.
- */
-
- for (; !rp_at_end(rpc) && rp_value(rpc) == new;
- rp_next(rpc, data, rpc, itemp)
- )
- if ((xo = xc += rp_length(rpc)) >= xe)
- return 0;
- x0 = xc, rp0 = rpc;
-
- /* Find the run that contains xe-1. */
-
- while (xe > xc + rp_length(rpc))
- xc += rp_length(rpc), rp_next(rpc, data, rpc, itemp);
-
- /*
- * Skip runs below xe that already contain the new value.
- * (We know that some run between xo and xe doesn't.)
- * If we skip any such runs, set xe to just below them.
- */
-
- while (rp_prev(rpc, data, rpc, itemp), rp_value(rpc) == new)
- xe = xc -= rp_length(rpc);
- rp_next(rpc, data, rpc, itemp);
-
- /*
- * At this point, we know the following:
- * x0 <= xo < x0 + rp_length(rp0).
- * rp_value(rp0) != new.
- * xc <= xe-1 < xc + rp_length(rpc).
- * rp_value(rpc) != new.
- * Note that rp0 and rpc may point to the same run.
- */
-
- /*
- * Check that we have enough free runs to do the replacement.
- * In the worst case, where we have to split existing runs
- * at both ends of the interval, two new runs are required.
- * We just check for having at least two free runs, since this
- * is simple and wastes at most 2 runs.
- */
-
- if (line->free == 0 || data[line->free].nix == 0)
- return_error(-1);
-
- /* Split off any unaffected prefix of the run at rp0. */
-
- if (x0 < xo) {
- uint diff = xo - x0;
- run_value v0 = rp_value(rp0);
- run_ptr rpp;
-
- rp_prev(rp0, data, rpp, itemp);
- if (rp_value(rpp) == v0 && rp_length(rpp) + diff <= 255)
- rp_length(rpp) += diff;
- else {
- rp_insert_prev(rp0, data, line, rpp, itemp);
- rp_length(rpp) = diff;
- rp_value(rpp) = v0;
- }
- }
- /* Split off any unaffected suffix of the run at rpc. */
-
- x1 = xc + rp_length(rpc);
- if (x1 > xe) {
- uint diff = x1 - xe;
- run_value vc = rp_value(rpc);
- run_ptr rpn;
-
- rp_next(rpc, data, rpn, itemp);
- if (rp_value(rpn) == vc && rp_length(rpn) + diff <= 255)
- rp_length(rpn) += diff;
- else {
- rp_insert_next(rpc, data, line, rpn, itemp);
- rp_length(rpn) = diff;
- rp_value(rpn) = vc;
- }
- }
- /* Delete all runs from rp0 through rpc. */
-
- rp_prev(rp0, data, rp0, itemp);
- {
- run_ptr rpn, rpn2;
-
- while (rp0.next != rpc.next)
- rp_delete_next(rp0, data, line, rpn, rpn2, itemp);
- }
-
- /*
- * Finally, insert new runs with the new value.
- * We need to check for one boundary case, namely,
- * xo == x0 and the next lower run has the new value.
- * (There's probably a way to structure the code just slightly
- * differently to avoid this test.)
- */
-
- {
- uint left = xe - xo;
-
- if (xo == x0 && rp_value(rp0) == new &&
- rp_length(rp0) + left <= 255
- )
- rp_length(rp0) += left;
- else { /*
- * If we need more than one run, we probably should
- * divide up the length to create more runs with length
- * less than 255 in order to improve the chances of
- * a later merge, but we won't bother right now.
- */
- do {
- run_ptr rpn;
-
- rp_insert_next(rp0, data, line, rpn, itemp);
- rp_length(rpn) = min(left, 255);
- rp_value(rpn) = new;
- }
- while ((left -= 255) > 0);
- }
- }
-
- return 0;
-}
-
-/* Replace a rectangle with a new value. */
-private int
-run_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
- gx_color_index color)
-{
- int xe;
- run_line *line;
- int ny;
-
- fit_fill(dev, x, y, w, h);
- /*
- * If the new value is 0 and the rectangle falls entirely within
- * the uninitialized region that we're keeping track of,
- * we can skip the entire operation.
- */
- if ((byte) color == 0 && y >= rdev->umin && y + h <= rdev->umax1)
- return 0;
-
- xe = x + w;
- for (line = &rdev->lines[y], ny = h; ny > 0; ++line, --ny)
- if ((byte) color != line->zero) {
- if (line->zero == 0)
- run_line_initialize(dev, y + h - ny);
- run_fill_interval(line, x, xe, (byte) color);
- }
- return 0;
-}
-
-/* Get a fully expanded scan line. */
-private int
-run_get_bits(gx_device * dev, int y, byte * row, byte ** actual_row)
-{
- const run_line *line = &rdev->lines[y];
- const run *data = line->data;
- const_run_ptr rp;
- byte *q = *actual_row = row;
- run_index itemp;
-
- if (line->zero == 0) {
- memset(row, 0, dev->width);
- return 0;
- }
- for (rp_start(rp, data); !rp_at_end(rp);
- rp_next(rp, data, rp, itemp)
- ) {
- memset(q, rp_value(rp), rp_length(rp));
- q += rp_length(rp);
- }
- return 0;
-}
-
-/* Debugging code */
-
-#ifdef DEBUG
-
-void
-debug_print_run(const run * data, run_index index, const char *prefix)
-{
- const run *pr = data + index;
-
- dlprintf5("%s%5d: length = %3d, value = %3d, nix = %5u\n",
- prefix, index, pr->length, pr->value, pr->nix);
-}
-
-void
-debug_print_run_line(const run_line * line, const char *prefix)
-{
- const run *data = line->data;
-
- dlprintf5("%sruns at 0x%lx: zero = %d, free = %u, xcur = %u,\n",
- prefix, (ulong) data, line->zero, line->free, line->xcur);
- dlprintf4("%s rpcur = {ptr = 0x%lx, index = %u, next = %u}\n",
- prefix, (ulong) line->rpcur.ptr, line->rpcur.index,
- line->rpcur.next);
- {
- const_run_ptr rpc;
- uint itemp;
-
- rp_start(rpc, data);
- while (!rp_at_end(rpc)) {
- debug_print_run(data, rpc.index, prefix);
- rp_next(rpc, data, rpc, itemp);
- }
- }
-}
-
-#endif /* DEBUG */
diff --git a/gs/src/gdevsgi.c b/gs/src/gdevsgi.c
index e0e12b97a..035257edf 100644
--- a/gs/src/gdevsgi.c
+++ b/gs/src/gdevsgi.c
@@ -63,7 +63,7 @@ typedef struct sgi_cursor_s {
} sgi_cursor;
private int
-sgi_begin_page(gx_device_printer *bdev, FILE *pstream, sgi_cursor _ss *pcur)
+sgi_begin_page(gx_device_printer *bdev, FILE *pstream, sgi_cursor *pcur)
{
uint line_size = gdev_mem_bytes_per_scan_line((gx_device_printer*)bdev);
byte *data = (byte*)gs_malloc(line_size, 1, "sgi_begin_page");
@@ -96,7 +96,7 @@ sgi_begin_page(gx_device_printer *bdev, FILE *pstream, sgi_cursor _ss *pcur)
}
private int
-sgi_next_row(sgi_cursor _ss *pcur)
+sgi_next_row(sgi_cursor *pcur)
{ if (pcur->lnum < 0)
return 1;
gdev_prn_copy_scan_lines((gx_device_printer*)pcur->dev,
diff --git a/gs/src/gdevsppr.c b/gs/src/gdevsppr.c
index 79513670d..a95da6ee2 100644
--- a/gs/src/gdevsppr.c
+++ b/gs/src/gdevsppr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -65,7 +65,7 @@ prn_device(prn_sparc_procs,
private int
sparc_open(gx_device *pdev)
{ /* Change the margins according to the paper size. */
- const float _ds *m;
+ const float *m;
static const float m_a4[4] = { SPARC_MARGINS_A4 };
static const float m_letter[4] = { SPARC_MARGINS_LETTER };
@@ -126,7 +126,7 @@ sparc_print_page(gx_device_printer *pdev, FILE *prn)
lpvipage.bitmap_width=gdev_mem_bytes_per_scan_line((gx_device *)pdev);
lpvipage.page_width=lpvipage.bitmap_width*8;
lpvipage.page_length=pdev->height;
- lpvipage.resolution= (pdev->x_pixels_per_inch == 300 ? 300 : 400);
+ lpvipage.resolution = (pdev->x_pixels_per_inch == 300 ? DPI300 : DPI400);
if (ioctl(fileno(prn),LPVIIOC_SETPAGE,&lpvipage)!=0)
{
fprintf(stderr,"sparc_print_page: LPVIIOC_SETPAGE failed\n");
diff --git a/gs/src/gdevsunr.c b/gs/src/gdevsunr.c
new file mode 100644
index 000000000..4543da6b8
--- /dev/null
+++ b/gs/src/gdevsunr.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Sun raster file driver */
+#include "gdevprn.h"
+
+/*
+ * Currently, the only variety of this format supported in this file is
+ * Harlequin's 1-bit "SUN_RAS" with no colormap and odd "};\n" at tail.
+ */
+
+#define RAS_MAGIC 0x59a66a95
+#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
+#define RMT_NONE 0 /* ras_maplength is expected to be 0 */
+typedef struct sun_rasterfile_s {
+ int ras_magic; /* magic number */
+ int ras_width; /* width (pixels) of image */
+ int ras_height; /* height (pixels) of image */
+ int ras_depth; /* depth (1, 8, or 24 bits) of pixel */
+ int ras_length; /* length (bytes) of image */
+ int ras_type; /* type of file; see RT_* below */
+ int ras_maptype; /* type of colormap; see RMT_* below */
+ int ras_maplength; /* length (bytes) of following map */
+} sun_rasterfile_t;
+
+#ifndef X_DPI
+# define X_DPI 72
+#endif
+#ifndef Y_DPI
+# define Y_DPI 72
+#endif
+
+private dev_proc_print_page(sunhmono_print_page);
+
+gx_device_printer gs_sunhmono_device =
+ prn_device(prn_std_procs, "sunhmono",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, sunhmono_print_page);
+
+private int
+sunhmono_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+ int gsLineBytes = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
+ /* Output bytes have to be padded to 16 bits. */
+ int rasLineBytes = ROUND_UP(gsLineBytes, 2);
+ int lineCnt;
+ char *lineStorage; /* Allocated for passing storage to gdev_prn_get_bits() */
+ byte *data;
+ sun_rasterfile_t ras;
+ int code = 0;
+
+ /*
+ fprintf(stderr,"pdev->width:%d (%d/%d) gsLineBytes:%d rasLineBytes:%d\n",
+ pdev->width, pdev->width/8, pdev->width%8,gsLineBytes,rasLineBytes);
+ */
+ lineStorage = gs_malloc(gsLineBytes, 1, "rasterfile_print_page(in)");
+ if (lineStorage == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ goto out;
+ }
+ /* Setup values in header */
+ ras.ras_magic = RAS_MAGIC;
+ ras.ras_width = pdev->width;
+ ras.ras_height = pdev->height;
+ ras.ras_depth = 1;
+ ras.ras_length = (rasLineBytes * pdev->height);
+ ras.ras_type = RT_STANDARD;
+ ras.ras_maptype = RMT_NONE;
+ ras.ras_maplength = 0;
+ /* Write header */
+ fwrite(&ras, 1, sizeof(ras), prn_stream);
+ /* For each raster line */
+ for (lineCnt = 0; lineCnt < pdev->height; ++lineCnt) {
+ gdev_prn_get_bits(pdev, lineCnt, lineStorage, &data);
+ fwrite(data, 1, gsLineBytes, prn_stream);
+ if (gsLineBytes % 2)
+ fputc(0, prn_stream); /* pad to even # of bytes with a 0 */
+ }
+ /* The weird file terminator */
+ fwrite("};\n", 1, 3, prn_stream);
+out:
+ /* Clean up... */
+ gs_free(lineStorage, gsLineBytes, 1, "rasterfile_print_page(in)");
+ return code;
+}
diff --git a/gs/src/gdevsvga.c b/gs/src/gdevsvga.c
index 8c632d8f8..665fdb019 100644
--- a/gs/src/gdevsvga.c
+++ b/gs/src/gdevsvga.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -54,7 +54,8 @@ private dc_entry dynamic_colors[dc_hash_size + 1];
svga_get_bits, NULL /*get_params*/, svga_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, svga_get_alpha_bits, svga_copy_alpha\
+ gx_page_device_get_page_device, NULL /*get_alpha_bits*/,\
+ svga_copy_alpha\
}
/* Save the controller mode */
@@ -457,38 +458,11 @@ svga_put_params(gx_device * dev, gs_param_list * plist)
{
int ecode = 0;
int code;
- int atext = fb_dev->alpha_text, agraphics = fb_dev->alpha_graphics;
const char *param_name;
- switch (code = param_read_int(plist, (param_name = "TextAlphaBits"), &fb_dev->alpha_text)) {
- case 0:
- if (atext == 1 || atext == 2 || atext == 4)
- break;
- code = gs_error_rangecheck;
- default:
- ecode = code;
- param_signal_error(plist, param_name, ecode);
- case 1:
- ;
- }
-
- switch (code = param_read_int(plist, (param_name = "GraphicsAlphaBits"), &fb_dev->alpha_graphics)) {
- case 0:
- if (agraphics == 1 || agraphics == 2 || agraphics == 4)
- break;
- code = gs_error_rangecheck;
- default:
- ecode = code;
- param_signal_error(plist, param_name, ecode);
- case 1:
- ;
- }
-
if ((code = ecode) < 0 ||
(code = gx_default_put_params(dev, plist)) < 0
) {
- fb_dev->alpha_text = atext;
- fb_dev->alpha_graphics = agraphics;
}
return code;
}
@@ -519,14 +493,6 @@ svga_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
return 0;
}
-/* Get the number of alpha bits. */
-private int
-svga_get_alpha_bits(gx_device * dev, graphics_object_type type)
-{
- return (type == go_text ? fb_dev->alpha_text :
- fb_dev->alpha_graphics);
-}
-
/* Copy an alpha-map to the screen. */
/* Depth is 1, 2, or 4. */
private int
@@ -760,7 +726,7 @@ vesa_find_mode(gx_device * dev, const mode_info * mode_table)
fb_dev->mode = mip;
gx_device_adjust_resolution(dev, mip->width, mip->height, 1);
fb_dev->info.vesa.bios_set_page = info.win_func_ptr;
- fb_dev->info.vesa.pn_shift = small_exact_log2(64 / info.win_granularity);
+ fb_dev->info.vesa.pn_shift = ilog2(64 / info.win_granularity);
/* Reset the raster per the VESA info. */
fb_dev->raster = info.bytes_per_line;
return 0;
diff --git a/gs/src/gdevsvga.h b/gs/src/gdevsvga.h
index 3c0fe16e3..fa8fbe169 100644
--- a/gs/src/gdevsvga.h
+++ b/gs/src/gdevsvga.h
@@ -35,7 +35,6 @@ dev_proc_copy_color(svga_copy_color);
dev_proc_get_params(svga_get_params);
dev_proc_put_params(svga_put_params);
dev_proc_get_bits(svga_get_bits);
-dev_proc_get_alpha_bits(svga_get_alpha_bits);
dev_proc_copy_alpha(svga_copy_alpha);
/* Table structure for looking up graphics modes. */
@@ -52,7 +51,6 @@ struct gx_device_svga_s {
void (*set_mode) (P1(int));
void (*set_page) (P3(gx_device_svga * fbdev, int pnum, int wnum));
bool fixed_colors; /* if true, used a fixed palette */
- int alpha_text, alpha_graphics; /* if >1, map alpha to saturation */
const mode_info *mode; /* BIOS display mode info */
uint raster; /* frame buffer bytes per line */
int current_page; /* current page */
@@ -83,7 +81,7 @@ struct gx_device_svga_s {
/*dci_color(*/depth, maxv, dither/*)*/),\
{ 0 }, /* std_procs */\
get_mode, set_mode, set_page,\
- 0 /*fixed_colors*/, 1 /*alpha_text*/, 1 /*alpha_graphics*/\
+ 0 /*fixed_colors*/\
}
#define svga_device(procs, name, get_mode, set_mode, set_page)\
svga_color_device(procs, name, 8, 31, 4, get_mode, set_mode, set_page)
diff --git a/gs/src/gdevtfax.c b/gs/src/gdevtfax.c
index cd98247c9..5bb1e224c 100644
--- a/gs/src/gdevtfax.c
+++ b/gs/src/gdevtfax.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,7 +30,8 @@
/* The device descriptors */
-dev_proc_open_device(gdev_fax_open);
+private dev_proc_get_params(tfax_get_params);
+private dev_proc_put_params(tfax_put_params);
private dev_proc_print_page(faxg3_print_page);
private dev_proc_print_page(faxg32d_print_page);
private dev_proc_print_page(faxg4_print_page);
@@ -42,110 +43,187 @@ private dev_proc_print_page(tiffg4_print_page);
struct gx_device_tfax_s {
gx_device_common;
gx_prn_device_common;
+ int adjust_width; /* 0 = no adjust, 1 = adjust to fax values */
gdev_tiff_state tiff; /* for TIFF output only */
};
typedef struct gx_device_tfax_s gx_device_tfax;
-#define tfdev ((gx_device_tfax *)dev)
-
/* Define procedures that adjust the paper size. */
private const gx_device_procs gdev_fax_std_procs =
-prn_procs(gdev_fax_open, gdev_prn_output_page, gdev_prn_close);
-
-const gx_device_tfax gs_faxg3_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg3",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, faxg3_print_page)
+ prn_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
+ tfax_get_params, tfax_put_params);
+
+const gx_device_tfax gs_faxg3_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg3",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, faxg3_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_faxg32d_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg32d",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, faxg32d_print_page)
+const gx_device_tfax gs_faxg32d_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg32d",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, faxg32d_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_faxg4_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg4",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, faxg4_print_page)
+const gx_device_tfax gs_faxg4_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "faxg4",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, faxg4_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_tiffcrle_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffcrle",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, tiffcrle_print_page)
+const gx_device_tfax gs_tiffcrle_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffcrle",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, tiffcrle_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_tiffg3_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg3",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, tiffg3_print_page)
+const gx_device_tfax gs_tiffg3_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg3",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, tiffg3_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_tiffg32d_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg32d",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, tiffg32d_print_page)
+const gx_device_tfax gs_tiffg32d_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg32d",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, tiffg32d_print_page),
+ 1 /* adjust_width */
};
-const gx_device_tfax gs_tiffg4_device =
-{prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg4",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, tiffg4_print_page)
+const gx_device_tfax gs_tiffg4_device = {
+ prn_device_std_body(gx_device_tfax, gdev_fax_std_procs, "tiffg4",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ X_DPI, Y_DPI,
+ 0, 0, 0, 0, /* margins */
+ 1, tiffg4_print_page),
+ 1 /* adjust_width */
};
-/* Open the device, adjusting the paper size. */
+/* Open the device. */
+/* This is no longer needed: we retain it for client backward compatibility. */
int
gdev_fax_open(gx_device * dev)
{
- if (dev->width >= 1680 && dev->width <= 1736) { /* Adjust width for A4 paper. */
- dev->width = 1728;
- } else if (dev->width >= 2000 && dev->width <= 2056) { /* Adjust width for B4 paper. */
- dev->width = 2048;
- }
return gdev_prn_open(dev);
}
+/* Get/put the AdjustWidth parameter. */
+private int
+tfax_get_params(gx_device * dev, gs_param_list * plist)
+{
+ gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
+ int code = gdev_prn_get_params(dev, plist);
+
+ if (code < 0)
+ return code;
+ return param_write_int(plist, "AdjustWidth", &tfdev->adjust_width);
+}
+private int
+tfax_put_params(gx_device * dev, gs_param_list * plist)
+{
+ gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
+ int ecode = 0;
+ int code;
+ int aw = tfdev->adjust_width;
+ const char *param_name;
+
+ switch (code = param_read_int(plist, (param_name = "AdjustWidth"), &aw)) {
+ case 0:
+ if (aw >= 0 && aw <= 1)
+ break;
+ code = gs_error_rangecheck;
+ default:
+ ecode = code;
+ param_signal_error(plist, param_name, ecode);
+ case 1:
+ break;
+ }
+
+ if (ecode < 0)
+ return ecode;
+ code = gdev_prn_put_params(dev, plist);
+ if (code < 0)
+ return code;
+
+ tfdev->adjust_width = aw;
+ return code;
+}
+
/* Initialize the stream state with a set of default parameters. */
/* These select the same defaults as the CCITTFaxEncode filter, */
/* except we set BlackIs1 = true. */
-void
-gdev_fax_init_state(stream_CFE_state * ss, const gx_device_printer * pdev)
+private void
+gdev_fax_init_state_adjust(stream_CFE_state * ss,
+ const gx_device_printer * pdev,
+ int adjust_width)
{
(*s_CFE_template.set_defaults) ((stream_state *) ss);
ss->Columns = pdev->width;
ss->Rows = pdev->height;
ss->BlackIs1 = true;
+ if (adjust_width > 0) {
+ /* Adjust the page width to a legal value for fax systems. */
+ if (ss->Columns >= 1680 && ss->Columns <= 1736) {
+ /* Adjust width for A4 paper. */
+ ss->Columns = 1728;
+ } else if (ss->Columns >= 2000 && ss->Columns <= 2056) {
+ /* Adjust width for B4 paper. */
+ ss->Columns = 2048;
+ }
+ }
+}
+void
+gdev_fax_init_state(stream_CFE_state * ss, const gx_device_printer * pdev)
+{
+ gdev_fax_init_state_adjust(ss, pdev, 1);
+}
+private void
+gdev_fax_init_fax_state(stream_CFE_state * ss, const gx_device_printer * pdev)
+{
+ gdev_fax_init_state_adjust(ss, pdev,
+ ((const gx_device_tfax *)pdev)->adjust_width);
}
/* Send the page to the printer. */
+/* Print a page with a specified width, which may differ from the */
+/* width stored in the device. */
int
-gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
- const stream_template * temp, stream_state * ss)
+gdev_stream_print_page_width(gx_device_printer * pdev, FILE * prn_stream,
+ const stream_template * temp, stream_state * ss,
+ int width)
{
gs_memory_t *mem = &gs_memory_default;
int code;
stream_cursor_read r;
stream_cursor_write w;
int in_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
+ /*
+ * Because of the width adjustment for fax systems, width may
+ * be different from (either greater than or less than) pdev->width.
+ * Allocate a large enough buffer to account for this.
+ */
+ int col_size = (width * pdev->color_info.depth + 7) >> 3;
+ int max_size = max(in_size, col_size);
int lnum;
byte *in;
byte *out;
-
/* If the file is 'nul', don't even do the writes. */
bool nul = !strcmp(pdev->fname, "nul");
@@ -158,9 +236,10 @@ gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
return_error(gs_error_limitcheck); /* bogus, but as good as any */
/* Allocate the buffers. */
- in = gs_alloc_bytes(mem, temp->min_in_size + in_size + 1, "gdev_stream_print_page(in)");
-#define out_size 1000
- out = gs_alloc_bytes(mem, out_size, "gdev_stream_print_page(out)");
+ in = gs_alloc_bytes(mem, temp->min_in_size + max_size + 1,
+ "gdev_stream_print_page(in)");
+#define OUT_SIZE 1000
+ out = gs_alloc_bytes(mem, OUT_SIZE, "gdev_stream_print_page(out)");
if (in == 0 || out == 0) {
code = gs_note_error(gs_error_VMerror);
goto done;
@@ -169,7 +248,8 @@ gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
lnum = 0;
r.ptr = r.limit = in - 1;
w.ptr = out - 1;
- w.limit = w.ptr + out_size;
+ w.limit = w.ptr + OUT_SIZE;
+#undef OUT_SIZE
/* Process the image. */
for (;;) {
@@ -192,7 +272,11 @@ gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
left = r.limit - r.ptr;
memcpy(in, r.ptr + 1, left);
gdev_prn_copy_scan_lines(pdev, lnum++, in + left, in_size);
- r.limit = in + left + in_size - 1;
+ /* Note: we use col_size here, not in_size. */
+ if (col_size > in_size) {
+ memset(in + left + in_size, 0, col_size - in_size);
+ }
+ r.limit = in + left + col_size - 1;
r.ptr = in - 1;
}
break;
@@ -216,13 +300,20 @@ gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
(*temp->release) (ss);
return code;
}
+int
+gdev_stream_print_page(gx_device_printer * pdev, FILE * prn_stream,
+ const stream_template * temp, stream_state * ss)
+{
+ return gdev_stream_print_page_width(pdev, prn_stream, temp, ss,
+ pdev->width);
+}
/* Print a fax page. Other fax drivers use this. */
int
gdev_fax_print_page(gx_device_printer * pdev, FILE * prn_stream,
stream_CFE_state * ss)
{
- return gdev_stream_print_page(pdev, prn_stream, &s_CFE_template,
- (stream_state *) ss);
+ return gdev_stream_print_page_width(pdev, prn_stream, &s_CFE_template,
+ (stream_state *)ss, ss->Columns);
}
/* Print a 1-D Group 3 page. */
@@ -231,7 +322,7 @@ faxg3_print_page(gx_device_printer * pdev, FILE * prn_stream)
{
stream_CFE_state state;
- gdev_fax_init_state(&state, pdev);
+ gdev_fax_init_fax_state(&state, pdev);
state.EndOfLine = true;
state.EndOfBlock = false;
return gdev_fax_print_page(pdev, prn_stream, &state);
@@ -243,7 +334,7 @@ faxg32d_print_page(gx_device_printer * pdev, FILE * prn_stream)
{
stream_CFE_state state;
- gdev_fax_init_state(&state, pdev);
+ gdev_fax_init_fax_state(&state, pdev);
state.K = (pdev->y_pixels_per_inch < 100 ? 2 : 4);
state.EndOfLine = true;
state.EndOfBlock = false;
@@ -256,7 +347,7 @@ faxg4_print_page(gx_device_printer * pdev, FILE * prn_stream)
{
stream_CFE_state state;
- gdev_fax_init_state(&state, pdev);
+ gdev_fax_init_fax_state(&state, pdev);
state.K = -1;
state.EndOfBlock = false;
return gdev_fax_print_page(pdev, prn_stream, &state);
@@ -311,16 +402,18 @@ private const tiff_mono_directory dir_mono_template =
};
/* Forward references */
-private int tfax_begin_page(P3(gx_device_tfax *, FILE *, const tiff_mono_directory *));
+private int tfax_begin_page(P4(gx_device_tfax *, FILE *,
+ const tiff_mono_directory *, int));
/* Print a fax-encoded page. */
private int
tifff_print_page(gx_device_printer * dev, FILE * prn_stream,
stream_CFE_state * pstate, tiff_mono_directory * pdir)
{
+ gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
int code;
- tfax_begin_page(tfdev, prn_stream, pdir);
+ tfax_begin_page(tfdev, prn_stream, pdir, pstate->Columns);
pstate->FirstBitLowOrder = true; /* decoders prefer this */
code = gdev_fax_print_page(dev, prn_stream, pstate);
gdev_tiff_end_page(&tfdev->tiff, prn_stream);
@@ -332,7 +425,7 @@ tiffcrle_print_page(gx_device_printer * dev, FILE * prn_stream)
stream_CFE_state state;
tiff_mono_directory dir;
- gdev_fax_init_state(&state, dev);
+ gdev_fax_init_fax_state(&state, dev);
state.EndOfLine = false;
state.EncodedByteAlign = true;
dir = dir_mono_template;
@@ -347,7 +440,7 @@ tiffg3_print_page(gx_device_printer * dev, FILE * prn_stream)
stream_CFE_state state;
tiff_mono_directory dir;
- gdev_fax_init_state(&state, dev);
+ gdev_fax_init_fax_state(&state, dev);
state.EndOfLine = true;
state.EncodedByteAlign = true;
dir = dir_mono_template;
@@ -391,6 +484,7 @@ tiffg4_print_page(gx_device_printer * dev, FILE * prn_stream)
private int
tifflzw_print_page(gx_device_printer * dev, FILE * prn_stream)
{
+ gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
tiff_mono_directory dir;
stream_LZW_state state;
int code;
@@ -398,12 +492,11 @@ tifflzw_print_page(gx_device_printer * dev, FILE * prn_stream)
dir = dir_mono_template;
dir.Compression.value = Compression_LZW;
dir.FillOrder.value = FillOrder_MSB2LSB;
- tfax_begin_page(tfdev, prn_stream, &dir);
+ tfax_begin_page(tfdev, prn_stream, &dir, dev->width);
state.InitialCodeLength = 8;
state.FirstBitLowOrder = false;
state.BlockData = false;
- state.EarlyChange = 0;
-/****** CHECK THIS ******/
+ state.EarlyChange = 0; /****** CHECK THIS ******/
code = gdev_stream_print_page(dev, prn_stream, &s_LZWE_template,
(stream_state *) & state);
gdev_tiff_end_page(&tfdev->tiff, prn_stream);
@@ -414,6 +507,7 @@ tifflzw_print_page(gx_device_printer * dev, FILE * prn_stream)
private int
tiffpack_print_page(gx_device_printer * dev, FILE * prn_stream)
{
+ gx_device_tfax *const tfdev = (gx_device_tfax *)dev;
tiff_mono_directory dir;
stream_RLE_state state;
int code;
@@ -421,7 +515,7 @@ tiffpack_print_page(gx_device_printer * dev, FILE * prn_stream)
dir = dir_mono_template;
dir.Compression.value = Compression_PackBits;
dir.FillOrder.value = FillOrder_MSB2LSB;
- tfax_begin_page(tfdev, prn_stream, &dir);
+ tfax_begin_page(tfdev, prn_stream, &dir, dev->width);
state.EndOfData = false;
state.record_size = gdev_mem_bytes_per_scan_line((gx_device *) dev);
code = gdev_stream_print_page(dev, prn_stream, &s_RLE_template,
@@ -430,16 +524,21 @@ tiffpack_print_page(gx_device_printer * dev, FILE * prn_stream)
return code;
}
-#undef tfdev
-
/* Begin a TIFF fax page. */
private int
tfax_begin_page(gx_device_tfax * tfdev, FILE * fp,
- const tiff_mono_directory * pdir)
+ const tiff_mono_directory * pdir, int width)
{
- return gdev_tiff_begin_page((gx_device_printer *) tfdev,
+ /* Patch the width to reflect fax page width adjustment. */
+ int save_width = tfdev->width;
+ int code;
+
+ tfdev->width = width;
+ code = gdev_tiff_begin_page((gx_device_printer *) tfdev,
&tfdev->tiff, fp,
(const TIFF_dir_entry *)pdir,
sizeof(*pdir) / sizeof(TIFF_dir_entry),
NULL, 0);
+ tfdev->width = save_width;
+ return code;
}
diff --git a/gs/src/gdevvec.c b/gs/src/gdevvec.c
index 04e117dd1..c6f398527 100644
--- a/gs/src/gdevvec.c
+++ b/gs/src/gdevvec.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,11 +34,6 @@
#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();
@@ -51,77 +46,71 @@ gdev_vector_setflat(gx_device_vector * vdev, floatp flatness)
return 0;
}
+/*
+ * Put a path on the output file. If type is stroke and the last
+ * path component is a closepath, omit it and return 1.
+ */
int
-gdev_vector_dopath(gx_device_vector * vdev, const gx_path * ppath,
- gx_path_type_t type)
+gdev_vector_dopath(gx_device_vector *vdev, const gx_path * ppath,
+ gx_path_type_t type, const gs_matrix *pmat)
{
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_fixed_rect rbox;
+ gx_path_rectangular_type rtype = gx_path_is_rectangular(ppath, &rbox);
gs_path_enum cenum;
+ gdev_vector_dopath_state_t state;
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);
+ gdev_vector_dopath_init(&state, vdev, type, pmat);
+ /*
+ * if the path type is stroke, we only recognize closed
+ * rectangles; otherwise, we recognize all rectangles.
+ */
+ if (rtype != prt_none &&
+ !((type & gx_path_type_stroke) && rtype == prt_open) &&
+ (pmat == 0 || is_xxyy(pmat) || is_xyyx(pmat))
+ ) {
+ gs_point p, q;
+
+ gs_point_transform_inverse((floatp)rbox.p.x, (floatp)rbox.p.y,
+ &state.scale_mat, &p);
+ gs_point_transform_inverse((floatp)rbox.q.x, (floatp)rbox.q.y,
+ &state.scale_mat, &q);
+ return vdev_proc(vdev, dorect)(vdev, (fixed)p.x, (fixed)p.y,
+ (fixed)q.x, (fixed)q.y, type);
+ }
+ code = vdev_proc(vdev, beginpath)(vdev, type);
+ if (code < 0)
+ return code;
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;
+ gs_fixed_point vs[3];
+ int pe_op = gx_path_enum_next(&cenum, vs);
- sw:switch (pe_op) {
+ 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;
+ code = vdev_proc(vdev, endpath)(vdev, type);
+ return (code < 0 ? code : 0);
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;
+ if (!do_close) {
+ pe_op = gx_path_enum_next(&cenum, vs);
+ if (pe_op != 0) {
+ code = gdev_vector_dopath_segment(&state,
+ gs_pe_closepath, vs);
+ if (code < 0)
+ return code;
+ goto sw;
+ }
+ code = vdev_proc(vdev, endpath)(vdev, type);
+ return (code < 0 ? code : 1);
}
- return (*vdev_proc(vdev, endpath)) (vdev, type);
- default: /* can't happen */
- return_error(gs_error_unknownerror);
+ /* falls through */
+ default:
+ code = gdev_vector_dopath_segment(&state, pe_op, vs);
+ if (code < 0)
+ return code;
}
- if (code < 0)
- return code;
- x_prev = x, y_prev = y;
}
}
@@ -369,7 +358,7 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis,
}
if (half_width != vdev->state.line_params.half_width) {
int code = (*vdev_proc(vdev, setlinewidth))
- (vdev, pis->line_params.half_width * 2);
+ (vdev, half_width * 2);
if (code < 0)
return code;
@@ -377,7 +366,7 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis,
}
if (pis->line_params.miter_limit != vdev->state.line_params.miter_limit) {
int code = (*vdev_proc(vdev, setmiterlimit))
- (vdev, pis->line_params.miter_limit);
+ (vdev, pis->line_params.miter_limit);
if (code < 0)
return code;
@@ -386,7 +375,7 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis,
}
if (pis->line_params.cap != vdev->state.line_params.cap) {
int code = (*vdev_proc(vdev, setlinecap))
- (vdev, pis->line_params.cap);
+ (vdev, pis->line_params.cap);
if (code < 0)
return code;
@@ -394,7 +383,7 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis,
}
if (pis->line_params.join != vdev->state.line_params.join) {
int code = (*vdev_proc(vdev, setlinejoin))
- (vdev, pis->line_params.join);
+ (vdev, pis->line_params.join);
if (code < 0)
return code;
@@ -415,6 +404,141 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis,
return 0;
}
+/*
+ * Compute the scale or transformation matrix for transforming the line
+ * width and dash pattern for a stroke operation. Return 0 if scaling,
+ * 1 if a full matrix is needed.
+ */
+int
+gdev_vector_stroke_scaling(const gx_device_vector *vdev,
+ const gs_imager_state *pis,
+ double *pscale, gs_matrix *pmat)
+{
+ bool set_ctm = true;
+ double scale = 1;
+
+ /*
+ * If the CTM is not uniform, stroke width depends on angle.
+ * We'd like to avoid resetting the CTM, so we check for uniform
+ * CTMs explicitly. Note that in PDF, unlike PostScript, it is
+ * the CTM at the time of the stroke operation, not the CTM at
+ * the time the path was constructed, that is used for transforming
+ * the points of the path; so if we have to reset the CTM, we must
+ * do it before constructing the path, and inverse-transform all
+ * the coordinates.
+ */
+ if (is_xxyy(&pis->ctm)) {
+ scale = fabs(pis->ctm.xx);
+ set_ctm = fabs(pis->ctm.yy) != scale;
+ } else if (is_xyyx(&pis->ctm)) {
+ scale = fabs(pis->ctm.xy);
+ set_ctm = fabs(pis->ctm.yx) != scale;
+ } else if ((pis->ctm.xx == pis->ctm.yy && pis->ctm.xy == -pis->ctm.yx) ||
+ (pis->ctm.xx == -pis->ctm.yy && pis->ctm.xy == pis->ctm.yx)
+ ) {
+ scale = hypot(pis->ctm.xx, pis->ctm.xy);
+ set_ctm = false;
+ }
+ if (set_ctm) {
+ /*
+ * Adobe Acrobat Reader can't handle user coordinates larger than
+ * 32K. If we scale the matrix down too far, the coordinates will
+ * get too big: don't allow this to happen. (This does no harm
+ * for other output formats.)
+ */
+ double
+ mxx = pis->ctm.xx / vdev->scale.x,
+ mxy = pis->ctm.xy / vdev->scale.y,
+ myx = pis->ctm.yx / vdev->scale.x,
+ myy = pis->ctm.yy / vdev->scale.y;
+
+ scale = 0.5 * (fabs(mxx) + fabs(mxy) + fabs(myx) + fabs(myy));
+ pmat->xx = mxx / scale, pmat->xy = mxy / scale;
+ pmat->yx = myx / scale, pmat->yy = myy / scale;
+ pmat->tx = pmat->ty = 0;
+ }
+ *pscale = scale;
+ return (int)set_ctm;
+}
+
+/* Initialize for writing a path using the default implementation. */
+void
+gdev_vector_dopath_init(gdev_vector_dopath_state_t *state,
+ gx_device_vector *vdev, gx_path_type_t type,
+ const gs_matrix *pmat)
+{
+ state->vdev = vdev;
+ state->type = type;
+ if (pmat) {
+ state->scale_mat = *pmat;
+ /*
+ * The path element writing procedures all divide the coordinates
+ * by the scale, so we must compensate for that here.
+ */
+ gs_matrix_scale(&state->scale_mat, 1.0 / vdev->scale.x,
+ 1.0 / vdev->scale.y, &state->scale_mat);
+ } else {
+ gs_make_scaling(vdev->scale.x, vdev->scale.y, &state->scale_mat);
+ }
+ state->first = true;
+}
+
+/*
+ * Put a segment of an enumerated path on the output file.
+ * pe_op is assumed to be valid and non-zero.
+ */
+int
+gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op,
+ gs_fixed_point vs[3])
+{
+ gx_device_vector *vdev = state->vdev;
+ const gs_matrix *const pmat = &state->scale_mat;
+ gs_point vp[3];
+ int code;
+
+ switch (pe_op) {
+ case gs_pe_moveto:
+ gs_point_transform_inverse(fixed2float(vs[0].x),
+ fixed2float(vs[0].y), pmat, &vp[0]);
+ if (state->first)
+ state->start = vp[0], state->first = false;
+ code = vdev_proc(vdev, moveto)
+ (vdev, state->prev.x, state->prev.y, vp[0].x, vp[0].y,
+ state->type);
+ state->prev = vp[0];
+ break;
+ case gs_pe_lineto:
+ gs_point_transform_inverse(fixed2float(vs[0].x),
+ fixed2float(vs[0].y), pmat, &vp[0]);
+ code = vdev_proc(vdev, lineto)
+ (vdev, state->prev.x, state->prev.y, vp[0].x, vp[0].y,
+ state->type);
+ state->prev = vp[0];
+ break;
+ case gs_pe_curveto:
+ gs_point_transform_inverse(fixed2float(vs[0].x),
+ fixed2float(vs[0].y), pmat, &vp[0]);
+ gs_point_transform_inverse(fixed2float(vs[1].x),
+ fixed2float(vs[1].y), pmat, &vp[1]);
+ gs_point_transform_inverse(fixed2float(vs[2].x),
+ fixed2float(vs[2].y), pmat, &vp[2]);
+ code = vdev_proc(vdev, curveto)
+ (vdev, state->prev.x, state->prev.y, vp[0].x, vp[0].y,
+ vp[1].x, vp[1].y, vp[2].x, vp[2].y, state->type);
+ state->prev = vp[2];
+ break;
+ case gs_pe_closepath:
+ code = vdev_proc(vdev, closepath)
+ (vdev, state->prev.x, state->prev.y, state->start.x,
+ state->start.y, state->type);
+ state->prev = state->start;
+ break;
+ default: /* can't happen */
+ return -1;
+ }
+ return code;
+}
+
/* Write a polygon as part of a path. */
/* May call beginpath, moveto, lineto, closepath, endpath. */
int
@@ -473,23 +597,29 @@ gdev_vector_write_rectangle(gx_device_vector * vdev, fixed x0, fixed y0,
/* Write a clipping path by calling the path procedures. */
int
-gdev_vector_write_clip_path(gx_device_vector * vdev, const gx_clip_path * pcpath)
+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. */
+ 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 {
+ } else if (pcpath->path_valid) {
+ return (*vdev_proc(vdev, dopath))
+ (vdev, &pcpath->path,
+ (pcpath->rule <= 0 ?
+ gx_path_type_clip | gx_path_type_winding_number :
+ gx_path_type_clip | gx_path_type_even_odd),
+ NULL);
+ } else {
const gx_clip_list *list = gx_cpath_list(pcpath);
prect = list->head;
@@ -572,10 +702,9 @@ gdev_vector_begin_image(gx_device_vector * vdev,
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,
+ (const gs_data_image_t *)pim,
pprocs, (gx_device *) vdev,
- bits_per_pixel, num_components,
- format);
+ num_components, format);
if (code < 0)
return code;
pie->bits_per_pixel = bits_per_pixel * num_components /
@@ -766,7 +895,8 @@ gdev_vector_fill_path(gx_device * dev, const gs_imager_state * pis,
(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
+ gx_path_type_winding_number) | gx_path_type_fill,
+ NULL)) < 0
)
return gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath);
return code;
@@ -778,17 +908,19 @@ gdev_vector_stroke_path(gx_device * dev, const gs_imager_state * pis,
const gx_drawing_color * pdcolor, const gx_clip_path * pcpath)
{
int code;
+ double scale;
+ int set_ctm;
+ gs_matrix mat;
-/****** HANDLE SCALE ******/
- if ((code = gdev_vector_prepare_stroke(vdev, pis, params, pdcolor,
- dev->HWResolution[0])) < 0 ||
+ if ((set_ctm = gdev_vector_stroke_scaling(vdev, pis, &scale, &mat)) != 0 ||
+ (code = gdev_vector_prepare_stroke(vdev, pis, params, pdcolor, scale)) < 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
+ (vdev, ppath, gx_path_type_stroke, NULL)) < 0
)
return gx_default_stroke_path(dev, pis, ppath, params, pdcolor, pcpath);
return code;
@@ -864,7 +996,7 @@ gdev_vector_fill_parallelogram(gx_device * dev,
return code;
}
points[0].x = px, points[0].y = py;
- points[1].x = pax, points[0].y = pay;
+ points[1].x = pax, points[1].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,
diff --git a/gs/src/gdevvec.h b/gs/src/gdevvec.h
index 981f44910..283ed66ce 100644
--- a/gs/src/gdevvec.h
+++ b/gs/src/gdevvec.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,11 +30,6 @@
#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
@@ -118,8 +113,8 @@ typedef struct gx_device_vector_procs_s {
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 (*dopath) (P4(gx_device_vector * vdev, const gx_path * ppath,
+ gx_path_type_t type, const gs_matrix *pmat));
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));
@@ -141,8 +136,8 @@ 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));
+int gdev_vector_dopath(P4(gx_device_vector * vdev, const gx_path * ppath,
+ gx_path_type_t type, const gs_matrix *pmat));
/* dorect may call beginpath, moveto, lineto, closepath */
int gdev_vector_dorect(P6(gx_device_vector * vdev, fixed x0, fixed y0,
@@ -253,6 +248,34 @@ int gdev_vector_prepare_stroke(P5(gx_device_vector * vdev,
const gx_drawing_color * pdcolor,
floatp scale));
+/*
+ * Compute the scale or transformation matrix for transforming the line
+ * width and dash pattern for a stroke operation. Return 0 if scaling,
+ * 1 if a full matrix is needed.
+ */
+int gdev_vector_stroke_scaling(P4(const gx_device_vector *vdev,
+ const gs_imager_state *pis,
+ double *pscale, gs_matrix *pmat));
+
+/* Prepare to write a path using the default implementation. */
+typedef struct gdev_vector_dopath_state_s {
+ /* Initialized by _init */
+ gx_device_vector *vdev;
+ gx_path_type_t type;
+ bool first;
+ gs_matrix scale_mat;
+ /* Change dynamically */
+ gs_point start;
+ gs_point prev;
+} gdev_vector_dopath_state_t;
+void gdev_vector_dopath_init(P4(gdev_vector_dopath_state_t *state,
+ gx_device_vector *vdev,
+ gx_path_type_t type, const gs_matrix *pmat));
+
+/* Write a segment of a path using the default implementation. */
+int gdev_vector_dopath_segment(P3(gdev_vector_dopath_state_t *state, int pe_op,
+ gs_fixed_point vs[3]));
+
/* Write a polygon as part of a path (type = gx_path_type_none) */
/* or as a path. */
/* May call moveto, lineto, closepath (if close); */
diff --git a/gs/src/gdevvglb.c b/gs/src/gdevvglb.c
index 6f1a19d60..5e6d700dd 100644
--- a/gs/src/gdevvglb.c
+++ b/gs/src/gdevvglb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -349,7 +349,7 @@ vgalib_put_params(gx_device * dev, gs_param_list * plist)
int ecode = 0;
int code;
int imode = vga_dev->display_mode;
- const char _ds *param_name;
+ const char *param_name;
switch (code = param_read_int(plist, (param_name = "DisplayMode"), &imode)) {
default:
diff --git a/gs/src/gdevwdib.c b/gs/src/gdevwdib.c
index 29517490a..fc8335397 100644
--- a/gs/src/gdevwdib.c
+++ b/gs/src/gdevwdib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "gdevmswn.h"
#include "gxdevmem.h"
#include "gsdll.h"
+#include "gsdllwin.h"
#ifdef __WIN32__
# define USE_SEGMENTS 0
@@ -95,8 +96,7 @@ private const gx_device_procs win_dib_procs =
win_get_xfont_procs,
NULL, /* get_xfont_device */
NULL, /* map_rgb_alpha_color */
- gx_page_device_get_page_device,
- win_get_alpha_bits
+ gx_page_device_get_page_device
};
gx_device_win_dib far_data gs_mswindll_device =
{
@@ -107,8 +107,6 @@ gx_device_win_dib far_data gs_mswindll_device =
{0}, /* std_procs */
0, /* BitsPerPixel */
2, /* nColors */
- 1, /* Text Alpha bits */
- 1, /* Graphics Alpha bits */
0, /* mapped_color_flags */
win_dib_alloc_bitmap,
win_dib_free_bitmap
@@ -363,6 +361,8 @@ win_dib_repaint(gx_device_win * dev, HDC hdc, int dx, int dy, int wx, int wy,
int i;
UINT which_colors;
+ memset(&bmi.h, 0, sizeof(bmi.h));
+
bmi.h.biSize = sizeof(bmi.h);
bmi.h.biWidth = wdev->mdev.width;
bmi.h.biHeight = wy;
@@ -372,12 +372,27 @@ win_dib_repaint(gx_device_win * dev, HDC hdc, int dx, int dy, int wx, int wy,
bmi.h.biSizeImage = 0; /* default */
bmi.h.biXPelsPerMeter = 0; /* default */
bmi.h.biYPelsPerMeter = 0; /* default */
+
if (dev->BitsPerPixel <= 8) {
bmi.h.biClrUsed = wdev->nColors;
bmi.h.biClrImportant = wdev->nColors;
for (i = 0; i < wdev->nColors; i++)
bmi.pal_index[i] = i;
which_colors = DIB_PAL_COLORS;
+ } else if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
+ bmi.h.biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0x7c00;
+ bmi_colors[1] = 0x03e0;
+ bmi_colors[2] = 0x001f;
+ which_colors = DIB_RGB_COLORS;
+ } else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
+ bmi.h.biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0xf800;
+ bmi_colors[1] = 0x07e0;
+ bmi_colors[2] = 0x001f;
+ which_colors = DIB_RGB_COLORS;
} else {
bmi.h.biClrUsed = 0;
bmi.h.biClrImportant = 0;
@@ -416,8 +431,8 @@ win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy)
BYTE FAR *pDIB;
BITMAPINFOHEADER FAR *pbmih;
RGBQUAD FAR *pColors;
- BYTE huge *pBits;
- BYTE huge *pLine;
+ BYTE FAR *pBits;
+ BYTE FAR *pLine;
ulong bitmapsize;
int palcount;
int i;
@@ -438,8 +453,10 @@ win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy)
lwidth = ((wx * wdev->color_info.depth + 31) & ~31) >> 3;
bitmapsize = (long)lwidth *wy;
- if (wdev->color_info.depth == 24)
+ if (wdev->color_info.depth > 16)
palcount = 0;
+ else if (wdev->color_info.depth > 8)
+ palcount = 3; // 16-bit BI_BITFIELDS
else
palcount = wdev->nColors;
@@ -456,7 +473,7 @@ win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy)
}
pbmih = (BITMAPINFOHEADER FAR *) (pDIB);
pColors = (RGBQUAD FAR *) (pDIB + sizeof(BITMAPINFOHEADER));
- pBits = (BYTE huge *) (pDIB + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * palcount);
+ pBits = (BYTE FAR *) (pDIB + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * palcount);
pbmih->biSize = sizeof(BITMAPINFOHEADER);
pbmih->biWidth = wx;
@@ -469,6 +486,22 @@ win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy)
pbmih->biYPelsPerMeter = (DWORD) (dev->y_pixels_per_inch / 25.4 * 1000);
pbmih->biClrUsed = palcount;
pbmih->biClrImportant = palcount;
+
+ if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(pColors);
+ pbmih->biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0x7c00;
+ bmi_colors[1] = 0x03e0;
+ bmi_colors[2] = 0x001f;
+ }
+ else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(pColors);
+ pbmih->biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0xf800;
+ bmi_colors[1] = 0x07e0;
+ bmi_colors[2] = 0x001f;
+ }
+ else {
for (i = 0; i < palcount; i++) {
win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
pColors[i].rgbRed = win_color_value(prgb[0]);
@@ -476,6 +509,7 @@ win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy)
pColors[i].rgbBlue = win_color_value(prgb[2]);
pColors[i].rgbReserved = 0;
}
+ }
pLine = pBits;
for (i = orgy; i < orgy + wy; i++) {
@@ -506,8 +540,8 @@ win_dib_alloc_bitmap(gx_device_win * dev, gx_device * param_dev)
int width;
gx_device_memory mdev;
HGLOBAL hmdata;
- byte huge *base;
- byte huge *ptr_base;
+ byte FAR *base;
+ byte FAR *ptr_base;
uint ptr_size;
uint raster;
@@ -656,6 +690,9 @@ gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
pbmih->biHeight = dev->mdev.height;
pbmih->biPlanes = 1;
pbmih->biBitCount = dev->color_info.depth;
+ if ((dev->BitsPerPixel == 15) || (dev->BitsPerPixel == 16))
+ pbmih->biCompression = BI_BITFIELDS;
+ else
pbmih->biCompression = 0;
pbmih->biSizeImage = 0; /* default */
pbmih->biXPelsPerMeter = (DWORD) (dev->x_pixels_per_inch / 25.4 * 1000);
@@ -667,12 +704,28 @@ gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
int i;
gx_color_value prgb[3];
+ if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(prgbquad);
+ pbmih->biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0x7c00;
+ bmi_colors[1] = 0x03e0;
+ bmi_colors[2] = 0x001f;
+ }
+ else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
+ DWORD* bmi_colors = (DWORD*)(prgbquad);
+ pbmih->biCompression = BI_BITFIELDS;
+ bmi_colors[0] = 0xf800;
+ bmi_colors[1] = 0x07e0;
+ bmi_colors[2] = 0x001f;
+ }
+ else {
for (i = 0; i < palcount; i++) {
win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
prgbquad[i].rgbRed = win_color_value(prgb[0]);
prgbquad[i].rgbGreen = win_color_value(prgb[1]);
prgbquad[i].rgbBlue = win_color_value(prgb[2]);
prgbquad[i].rgbReserved = 0;
+ }
}
}
if (ppbyte) {
diff --git a/gs/src/gdevwpr2.c b/gs/src/gdevwpr2.c
index 8101630b9..aa25dae4a 100644
--- a/gs/src/gdevwpr2.c
+++ b/gs/src/gdevwpr2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,8 @@
* Original version by Russell Lang and
* L. Peter Deutsch, Aladdin Enterprises.
* Modified by rjl 1995-03-29 to use BMP printer code
+ * Modified by Pierre Arnaud 1999-02-18 (see description below)
+ * Modified by lpd 1999-04-03 for compatibility with Borland C++ 4.5.
*/
/* This driver uses the printer default size and resolution and
@@ -31,20 +33,68 @@
* The code in win_pr2_getdc() does try to set the printer page
* size from the PostScript PageSize, but it isn't working
* reliably at the moment.
- *
+ *
* This driver doesn't work with some Windows printer drivers.
* The reason is unknown. All printers to which I have access
- * work.
+ * work.
*
* rjl 1997-11-20
*/
-/* Supported printer parameters are
+/* Additions by Pierre Arnaud (Pierre.Arnaud@iname.com) 1992-02-18
+ *
+ * The driver has been extended in order to provide some run-time
+ * feed-back about the default Windows printer and to give the user
+ * the opportunity to select the printer's properties before the
+ * device gets opened (and any spooling starts).
+ *
+ * The driver returns an additional property named "UserSettings".
+ * This is a dictionary which contens are valid only after setting
+ * the QueryUser property (see below). The UserSettings dict contains
+ * the following keys:
+ *
+ * DocumentRange [begin end] (int array, can be set)
+ * Defines the range of pages in the document; [1 10] would
+ * describe a document starting at page 1 and ending at page 10.
+ *
+ * SelectedRange [begin end] (int array, can be set)
+ * Defines the pages the user wants to print.
+ *
+ * MediaSize [width height] (float array, read only)
+ * Current printer's media size.
+ *
+ * Copies n (integer, can be set)
+ * User selected number of copies.
+ *
+ * PrintCopies n (integer, read only)
+ * Number of copies which must be printed by Ghostscript itself.
+ * This is still experimental.
+ *
+ * DocumentName name (string, can be set)
+ * Name to be associated with the print job.
+ *
+ * UserChangedSettings (bool, read only)
+ * Set to 'true' if the last QueryUser operation succeeded.
+ */
+
+/* Supported printer parameters are :
+ *
* -dBitsPerPixel=n
* Override what the Window printer driver returns.
+ *
* -dNoCancel
* Don't display cancel dialog box. Useful for unattended or
* console EXE operation.
+ *
+ * -dQueryUser=n
+ * Query user interactively for the destination printer, before
+ * the device gets opened. This fills in the UserSettings dict
+ * and the OutputFile name properties. The following values are
+ * supported for n:
+ * 1 => show standard Print dialog
+ * 2 => show Print Setup dialog instead
+ * 3 => select default printer
+ * other, does nothing
*/
#include "gdevprn.h"
@@ -90,8 +140,24 @@ struct gx_device_win_pr2_s {
gx_prn_device_common;
HDC hdcprn;
bool nocancel;
+
+ int doc_page_begin; /* first page number in document */
+ int doc_page_end; /* last page number in document */
+ int user_page_begin; /* user's choice: first page to print */
+ int user_page_end; /* user's choice: last page to print */
+ int user_copies; /* user's choice: number of copies */
+ int print_copies; /* number of times GS should print each page */
+ float user_media_size[2]; /* width/height of media selected by user */
+ char doc_name[200]; /* name of document for the spooler */
+ bool user_changed_settings; /* true if user validated dialog */
+
+ HANDLE win32_hdevmode; /* handle to device mode information */
+ HANDLE win32_hdevnames; /* handle to device names information */
+
DLGPROC lpfnAbortProc;
DLGPROC lpfnCancelProc;
+
+ gx_device_win_pr2* original_device; /* used to detect copies */
};
gx_device_win_pr2 far_data gs_mswinpr2_device =
@@ -102,11 +168,31 @@ gx_device_win_pr2 far_data gs_mswinpr2_device =
0, win_pr2_print_page), /* depth = 0 */
0, /* hdcprn */
0, /* nocancel */
+ 0, /* doc_page_begin */
+ 0, /* doc_page_end */
+ 0, /* user_page_begin */
+ 0, /* user_page_end */
+ 1, /* user_copies */
+ 1, /* print_copies */
+ { 0.0, 0.0 }, /* user_media_size */
+ { 0 }, /* doc_name */
+ 0, /* user_changed_settings */
+ NULL, /* win32_hdevmode */
+ NULL, /* win32_hdevnames */
NULL, /* lpfnAbortProc */
- NULL /* lpfnCancelProc */
+ NULL, /* lpfnCancelProc */
+ NULL /* original_device */
};
+/********************************************************************************/
+
private int win_pr2_getdc(gx_device_win_pr2 *);
+private int win_pr2_print_setup_interaction(gx_device_win_pr2 *, int mode);
+private int win_pr2_write_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
+private int win_pr2_read_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
+private void win_pr2_copy_check(gx_device_win_pr2 * dev);
+
+/********************************************************************************/
/* Open the win_pr2 driver */
private int
@@ -119,27 +205,58 @@ win_pr2_open(gx_device * dev)
POINT size;
float m[4];
FILE *pfile;
+ DOCINFO docinfo;
+
+ win_pr2_copy_check(wdev);
if ((!wdev->nocancel) && (hDlgModeless)) {
/* device cannot opened twice since only one hDlgModeless */
fprintf(stderr, "Can't open mswinpr2 device twice\n");
return gs_error_limitcheck;
}
+
/* get a HDC for the printer */
- if (!win_pr2_getdc(wdev)) {
+ if ((wdev->win32_hdevmode) &&
+ (wdev->win32_hdevnames)) {
+ /* The user has already had the opportunity to choose the output */
+ /* file interactively. Just use the specified parameters. */
+
+ LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
+ LPDEVNAMES devnames = (LPDEVNAMES) GlobalLock(wdev->win32_hdevnames);
+
+ const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
+ const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
+ const char* output = (char*)(devnames)+(devnames->wOutputOffset);
+
+ wdev->hdcprn = CreateDC(driver, device, output, devmode);
+
+ GlobalUnlock(wdev->win32_hdevmode);
+ GlobalUnlock(wdev->win32_hdevnames);
+
+ if (wdev->hdcprn == NULL) {
+ return gs_error_Fatal;
+ }
+
+ } else if (!win_pr2_getdc(wdev)) {
/* couldn't get a printer from -sOutputFile= */
/* Prompt with dialog box */
memset(&pd, 0, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner = hwndtext;
- pd.Flags = PD_PRINTSETUP | PD_RETURNDC;
+ pd.Flags = PD_RETURNDC;
+ pd.nMinPage = wdev->doc_page_begin;
+ pd.nMaxPage = wdev->doc_page_end;
+ pd.nFromPage = wdev->user_page_begin;
+ pd.nToPage = wdev->user_page_end;
+ pd.nCopies = wdev->user_copies;
if (!PrintDlg(&pd)) {
/* device not opened - exit ghostscript */
return gs_error_Fatal; /* exit Ghostscript cleanly */
}
GlobalFree(pd.hDevMode);
GlobalFree(pd.hDevNames);
- pd.hDevMode = pd.hDevNames = NULL;
+ pd.hDevMode = NULL;
+ pd.hDevNames = NULL;
wdev->hdcprn = pd.hDC;
}
if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_DIBTODEV)) {
@@ -157,9 +274,26 @@ win_pr2_open(gx_device * dev)
wdev->lpfnAbortProc = (DLGPROC) MakeProcInstance((FARPROC) AbortProc, phInstance);
#endif
#endif
- Escape(wdev->hdcprn, SETABORTPROC, 0, (LPSTR) wdev->lpfnAbortProc, NULL);
- if (Escape(wdev->hdcprn, STARTDOC, lstrlen(szAppName), szAppName, NULL) <= 0) {
- fprintf(stderr, "Printer Escape STARTDOC failed\n");
+ SetAbortProc(wdev->hdcprn, (ABORTPROC) wdev->lpfnAbortProc);
+
+ /*
+ * Some versions of the Windows headers include lpszDatatype and fwType,
+ * and some don't. Since we want to set these fields to zero anyway,
+ * we just start by zeroing the whole structure.
+ */
+ memset(&docinfo, 0, sizeof(docinfo));
+ docinfo.cbSize = sizeof(docinfo);
+ docinfo.lpszDocName = wdev->doc_name;
+ /*docinfo.lpszOutput = NULL;*/
+ /*docinfo.lpszDatatype = NULL;*/
+ /*docinfo.fwType = 0;*/
+
+ if (docinfo.lpszDocName[0] == 0) {
+ docinfo.lpszDocName = "Ghostscript output";
+ }
+
+ if (StartDoc(wdev->hdcprn, &docinfo) <= 0) {
+ fprintf(stderr, "Printer StartDoc failed (error %08x)\n", GetLastError());
#if !defined(__WIN32__) && !defined(__DLL__)
FreeProcInstance((FARPROC) wdev->lpfnAbortProc);
#endif
@@ -168,9 +302,17 @@ win_pr2_open(gx_device * dev)
}
dev->x_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSX);
dev->y_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSY);
+#if 1
+ size.x = GetDeviceCaps(wdev->hdcprn, PHYSICALWIDTH);
+ size.y = GetDeviceCaps(wdev->hdcprn, PHYSICALHEIGHT);
+ gx_device_set_width_height(dev, (int)size.x, (int)size.y);
+ offset.x = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETX);
+ offset.y = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETY);
+#else
Escape(wdev->hdcprn, GETPHYSPAGESIZE, 0, NULL, (LPPOINT) & size);
gx_device_set_width_height(dev, (int)size.x, (int)size.y);
Escape(wdev->hdcprn, GETPRINTINGOFFSET, 0, NULL, (LPPOINT) & offset);
+#endif
/* m[] gives margins in inches */
m[0] /*left */ = offset.x / dev->x_pixels_per_inch;
m[3] /*top */ = offset.y / dev->y_pixels_per_inch;
@@ -225,6 +367,8 @@ win_pr2_close(gx_device * dev)
int code;
int aborted = FALSE;
+ win_pr2_copy_check(wdev);
+
/* Free resources */
if (!wdev->nocancel) {
@@ -238,14 +382,24 @@ win_pr2_close(gx_device * dev)
#endif
}
if (aborted)
- Escape(wdev->hdcprn, ABORTDOC, 0, NULL, NULL);
+ AbortDoc(wdev->hdcprn);
else
- Escape(wdev->hdcprn, ENDDOC, 0, NULL, NULL);
+ EndDoc(wdev->hdcprn);
#if !defined(__WIN32__) && !defined(__DLL__)
FreeProcInstance((FARPROC) wdev->lpfnAbortProc);
#endif
DeleteDC(wdev->hdcprn);
+
+ if (wdev->win32_hdevmode != NULL) {
+ GlobalFree(wdev->win32_hdevmode);
+ wdev->win32_hdevmode = NULL;
+ }
+ if (wdev->win32_hdevnames != NULL) {
+ GlobalFree(wdev->win32_hdevnames);
+ wdev->win32_hdevnames = NULL;
+ }
+
code = gdev_prn_close(dev);
return code;
}
@@ -256,8 +410,7 @@ win_pr2_close(gx_device * dev)
#undef wdev
#define wdev ((gx_device_win_pr2 *)pdev)
-/************************************************/
-
+/********************************************************************************/
/* ------ Private definitions ------ */
@@ -290,8 +443,8 @@ win_pr2_print_page(gx_device_printer * pdev, FILE * file)
} bmi;
scan_lines = dev_print_scan_lines(pdev);
- width = pdev->width - ((dev_l_margin(pdev) + dev_r_margin(pdev) -
- dev_x_offset(pdev)) * pdev->x_pixels_per_inch);
+ width = (int)(pdev->width - ((dev_l_margin(pdev) + dev_r_margin(pdev) -
+ dev_x_offset(pdev)) * pdev->x_pixels_per_inch));
yslice = 65535 / bmp_raster; /* max lines in 64k */
bmp_raster_multi = bmp_raster * yslice;
@@ -380,7 +533,7 @@ win_pr2_print_page(gx_device_printer * pdev, FILE * file)
if (!wdev->nocancel)
SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE),
"Ejecting page...");
- Escape(wdev->hdcprn, NEWFRAME, 0, NULL, NULL);
+ EndPage(wdev->hdcprn);
if (!wdev->nocancel)
ShowWindow(hDlgModeless, SW_HIDE);
}
@@ -475,34 +628,47 @@ win_pr2_set_bpp(gx_device * dev, int depth)
}
}
+/********************************************************************************/
+
/* Get device parameters */
int
-win_pr2_get_params(gx_device * dev, gs_param_list * plist)
+win_pr2_get_params(gx_device * pdev, gs_param_list * plist)
{
- int code = gdev_prn_get_params(dev, plist);
+ int code = gdev_prn_get_params(pdev, plist);
+
+ win_pr2_copy_check(wdev);
if (code >= 0)
code = param_write_bool(plist, "NoCancel",
- &(((gx_device_win_pr2 *) dev)->nocancel));
+ &(wdev->nocancel));
+ if (code >= 0)
+ code = win_pr2_write_user_settings(wdev, plist);
+
return code;
}
+
/* We implement this ourselves so that we can change BitsPerPixel */
/* before the device is opened */
int
-win_pr2_put_params(gx_device * dev, gs_param_list * plist)
+win_pr2_put_params(gx_device * pdev, gs_param_list * plist)
{
int ecode = 0, code;
- int old_bpp = dev->color_info.depth;
+ int old_bpp = pdev->color_info.depth;
int bpp = old_bpp;
- bool nocancel = ((gx_device_win_pr2 *) dev)->nocancel;
+ bool nocancel = wdev->nocancel;
+ int queryuser = 0;
+
+ win_pr2_copy_check(wdev);
+
+ code = win_pr2_read_user_settings(wdev, plist);
switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) {
case 0:
- if (dev->is_open)
+ if (pdev->is_open)
ecode = gs_error_rangecheck;
else { /* change dev->color_info is valid before device is opened */
- win_pr2_set_bpp(dev, bpp);
+ win_pr2_set_bpp(pdev, bpp);
break;
}
goto bppe;
@@ -515,10 +681,10 @@ win_pr2_put_params(gx_device * dev, gs_param_list * plist)
switch (code = param_read_bool(plist, "NoCancel", &nocancel)) {
case 0:
- if (dev->is_open)
+ if (pdev->is_open)
ecode = gs_error_rangecheck;
else {
- ((gx_device_win_pr2 *) dev)->nocancel = nocancel;
+ wdev->nocancel = nocancel;
break;
}
goto nocancele;
@@ -529,18 +695,33 @@ win_pr2_put_params(gx_device * dev, gs_param_list * plist)
break;
}
+ switch (code = param_read_int(plist, "QueryUser", &queryuser)) {
+ case 0:
+ if ((queryuser > 0) &&
+ (queryuser < 4)) {
+ win_pr2_print_setup_interaction(wdev, queryuser);
+ }
+ break;
+ default:
+ ecode = code;
+ param_signal_error(plist, "QueryUser", ecode);
+ case 1:
+ break;
+ }
+
if (ecode >= 0)
- ecode = gdev_prn_put_params(dev, plist);
+ ecode = gdev_prn_put_params(pdev, plist);
return ecode;
}
#undef wdev
+/********************************************************************************/
+
#ifndef __WIN32__
#include <print.h>
#endif
-
/* Get Device Context for printer */
private int
win_pr2_getdc(gx_device_win_pr2 * wdev)
@@ -573,7 +754,6 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
#endif
-
/* first try to derive the printer name from -sOutputFile= */
/* is printer if name prefixed by \\spool\ */
if (is_spool(wdev->fname))
@@ -665,8 +845,8 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
if ((devcap = gs_malloc(devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
return FALSE;
n = pfnDeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL);
- paperwidth = wdev->MediaSize[0] * 254 / 72;
- paperheight = wdev->MediaSize[1] * 254 / 72;
+ paperwidth = (int)(wdev->MediaSize[0] * 254 / 72);
+ paperheight = (int)(wdev->MediaSize[1] * 254 / 72);
papername[0] = '\0';
papersize = 0;
paperindex = -1;
@@ -800,3 +980,300 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
/* fall back to prompting user */
return FALSE;
}
+
+/********************************************************************************/
+
+#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
+ switch ( code = pread(dict.list, (param_name = pname), &(pa)) )\
+ {\
+ case 0:\
+ if ( (pa).size != psize )\
+ ecode = gs_note_error(gs_error_rangecheck);\
+ else {
+/* The body of the processing code goes here. */
+/* If it succeeds, it should do a 'break'; */
+/* if it fails, it should set ecode and fall through. */
+#define END_ARRAY_PARAM(pa, e)\
+ }\
+ goto e;\
+ default:\
+ ecode = code;\
+e: param_signal_error(dict.list, param_name, ecode);\
+ case 1:\
+ (pa).data = 0; /* mark as not filled */\
+ }
+
+
+/* Put the user params from UserSettings into our */
+/* internal variables. */
+private int
+win_pr2_read_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
+{
+ gs_param_dict dict;
+ gs_param_string docn = { 0 };
+ const char* dict_name = "UserSettings";
+ const char* param_name = "";
+ int code = 0;
+ int ecode = 0;
+
+ switch (code = param_begin_read_dict(plist, dict_name, &dict, false)) {
+ default:
+ param_signal_error(plist, dict_name, code);
+ return code;
+ case 1:
+ break;
+ case 0:
+ {
+ gs_param_int_array ia;
+
+ BEGIN_ARRAY_PARAM(param_read_int_array, "DocumentRange", ia, 2, ia)
+ if ((ia.data[0] < 0) ||
+ (ia.data[1] < 0) ||
+ (ia.data[0] > ia.data[1]))
+ ecode = gs_note_error(gs_error_rangecheck);
+ wdev->doc_page_begin = ia.data[0];
+ wdev->doc_page_end = ia.data[1];
+ END_ARRAY_PARAM(ia, doc_range_error)
+
+ BEGIN_ARRAY_PARAM(param_read_int_array, "SelectedRange", ia, 2, ia)
+ if ((ia.data[0] < 0) ||
+ (ia.data[1] < 0) ||
+ (ia.data[0] > ia.data[1]))
+ ecode = gs_note_error(gs_error_rangecheck);
+ wdev->user_page_begin = ia.data[0];
+ wdev->user_page_end = ia.data[1];
+ END_ARRAY_PARAM(ia, sel_range_error)
+
+ param_read_int(dict.list, "Copies", &wdev->user_copies);
+
+ switch (code = param_read_string(dict.list, (param_name = "DocumentName"), &docn)) {
+ case 0:
+ if (docn.size < sizeof(wdev->doc_name))
+ break;
+ code = gs_error_rangecheck;
+ /* fall through */
+ default:
+ ecode = code;
+ param_signal_error(plist, param_name, ecode);
+ /* fall through */
+ case 1:
+ docn.data = 0;
+ break;
+ }
+
+ param_end_read_dict(plist, dict_name, &dict);
+
+ if (docn.data) {
+ memcpy(wdev->doc_name, docn.data, docn.size);
+ wdev->doc_name[docn.size] = 0;
+ }
+
+ wdev->print_copies = 1;
+
+ if (wdev->win32_hdevmode) {
+ LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
+ if (devmode) {
+ devmode->dmCopies = wdev->user_copies;
+ GlobalUnlock(wdev->win32_hdevmode);
+ }
+ }
+ }
+ break;
+ }
+
+ return code;
+}
+
+
+private int
+win_pr2_write_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
+{
+ gs_param_dict dict;
+ gs_param_int_array range;
+ gs_param_float_array box;
+ gs_param_string docn;
+ int array[2];
+ const char* pname = "UserSettings";
+ int code;
+
+ dict.size = 7;
+ code = param_begin_write_dict(plist, pname, &dict, false);
+ if (code < 0) return code;
+
+ array[0] = wdev->doc_page_begin;
+ array[1] = wdev->doc_page_end;
+ range.data = array;
+ range.size = 2;
+ range.persistent = false;
+ code = param_write_int_array(dict.list, "DocumentRange", &range);
+ if (code < 0) goto error;
+
+ array[0] = wdev->user_page_begin;
+ array[1] = wdev->user_page_end;
+ range.data = array;
+ range.size = 2;
+ range.persistent = false;
+ code = param_write_int_array(dict.list, "SelectedRange", &range);
+ if (code < 0) goto error;
+
+ box.data = wdev->user_media_size;
+ box.size = 2;
+ box.persistent = false;
+ code = param_write_float_array(dict.list, "MediaSize", &box);
+ if (code < 0) goto error;
+
+ code = param_write_int(dict.list, "Copies", &wdev->user_copies);
+ if (code < 0) goto error;
+
+ code = param_write_int(dict.list, "PrintCopies", &wdev->print_copies);
+ if (code < 0) goto error;
+
+ docn.data = (const byte*)wdev->doc_name;
+ docn.size = strlen(wdev->doc_name);
+ docn.persistent = false;
+
+ code = param_write_string(dict.list, "DocumentName", &docn);
+ if (code < 0) goto error;
+
+ code = param_write_bool(dict.list, "UserChangedSettings", &wdev->user_changed_settings);
+
+error:
+ param_end_write_dict(plist, pname, &dict);
+ return code;
+}
+
+/********************************************************************************/
+
+/* Show up a dialog for the user to choose a printer and a paper size.
+ * If mode == 3, then automatically select the default Windows printer
+ * instead of asking the user.
+ */
+
+private int
+win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev, int mode)
+{
+ PRINTDLG pd;
+ LPDEVMODE devmode;
+ LPDEVNAMES devnames;
+
+ wdev->user_changed_settings = FALSE;
+
+ memset(&pd, 0, sizeof(pd));
+ pd.lStructSize = sizeof(pd);
+ pd.hwndOwner = hwndtext;
+
+ switch (mode) {
+ case 2: pd.Flags = PD_PRINTSETUP; break;
+ case 3: pd.Flags = PD_RETURNDEFAULT; break;
+ default: pd.Flags = 0; break;
+ }
+
+ pd.Flags |= PD_USEDEVMODECOPIES;
+
+ pd.nMinPage = wdev->doc_page_begin;
+ pd.nMaxPage = wdev->doc_page_end;
+ pd.nFromPage = wdev->user_page_begin;
+ pd.nToPage = wdev->user_page_end;
+ pd.nCopies = wdev->user_copies;
+
+ /* Show the Print Setup dialog and let the user choose a printer
+ * and a paper size/orientation.
+ */
+
+ if (!PrintDlg(&pd)) return FALSE;
+
+ devmode = (LPDEVMODE) GlobalLock(pd.hDevMode);
+ devnames = (LPDEVNAMES) GlobalLock(pd.hDevNames);
+
+ wdev->user_changed_settings = TRUE;
+ sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
+
+ if (mode == 3) {
+ devmode->dmCopies = wdev->user_copies * wdev->print_copies;
+ pd.nCopies = 1;
+ }
+
+ wdev->user_page_begin = pd.nFromPage;
+ wdev->user_page_end = pd.nToPage;
+ wdev->user_copies = devmode->dmCopies;
+ wdev->print_copies = pd.nCopies;
+ wdev->user_media_size[0] = devmode->dmPaperWidth / 254.0 * 72.0;
+ wdev->user_media_size[1] = devmode->dmPaperLength / 254.0 * 72.0;
+
+ {
+ float xppinch = 0;
+ float yppinch = 0;
+ const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
+ const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
+ const char* output = (char*)(devnames)+(devnames->wOutputOffset);
+
+ HDC hic = CreateIC(driver, device, output, devmode);
+
+ if (hic) {
+ xppinch = (float)GetDeviceCaps(hic, LOGPIXELSX);
+ yppinch = (float)GetDeviceCaps(hic, LOGPIXELSY);
+ wdev->user_media_size[0] = GetDeviceCaps(hic, PHYSICALWIDTH) * 72.0 / xppinch;
+ wdev->user_media_size[1] = GetDeviceCaps(hic, PHYSICALHEIGHT) * 72.0 / yppinch;
+ DeleteDC(hic);
+ }
+ }
+
+ devmode = NULL;
+ devnames = NULL;
+
+ GlobalUnlock(pd.hDevMode);
+ GlobalUnlock(pd.hDevNames);
+
+ if (wdev->win32_hdevmode != NULL) {
+ GlobalFree(wdev->win32_hdevmode);
+ }
+ if (wdev->win32_hdevnames != NULL) {
+ GlobalFree(wdev->win32_hdevnames);
+ }
+
+ wdev->win32_hdevmode = pd.hDevMode;
+ wdev->win32_hdevnames = pd.hDevNames;
+
+ return TRUE;
+}
+
+/* Check that we are dealing with an original device. If this
+ * happens to be a copy made by "copydevice", we will have to
+ * copy the original's handles to the associated Win32 params.
+ */
+
+private void
+win_pr2_copy_check(gx_device_win_pr2 * wdev)
+{
+ HGLOBAL hdevmode = wdev->win32_hdevmode;
+ HGLOBAL hdevnames = wdev->win32_hdevnames;
+ DWORD devmode_len = (hdevmode) ? GlobalSize(hdevmode) : 0;
+ DWORD devnames_len = (hdevnames) ? GlobalSize(hdevnames) : 0;
+
+ if (wdev->original_device == wdev)
+ return;
+
+ wdev->hdcprn = NULL;
+ wdev->win32_hdevmode = NULL;
+ wdev->win32_hdevnames = NULL;
+
+ wdev->original_device = wdev;
+
+ if (devmode_len) {
+ wdev->win32_hdevmode = GlobalAlloc(0, devmode_len);
+ if (wdev->win32_hdevmode) {
+ memcpy(GlobalLock(wdev->win32_hdevmode), GlobalLock(hdevmode), devmode_len);
+ GlobalUnlock(wdev->win32_hdevmode);
+ GlobalUnlock(hdevmode);
+ }
+ }
+
+ if (devnames_len) {
+ wdev->win32_hdevnames = GlobalAlloc(0, devnames_len);
+ if (wdev->win32_hdevnames) {
+ memcpy(GlobalLock(wdev->win32_hdevnames), GlobalLock(hdevnames), devnames_len);
+ GlobalUnlock(wdev->win32_hdevnames);
+ GlobalUnlock(hdevnames);
+ }
+ }
+}
diff --git a/gs/src/gdevx.c b/gs/src/gdevx.c
index 953dd8b9d..e97af25b9 100644
--- a/gs/src/gdevx.c
+++ b/gs/src/gdevx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -49,6 +49,10 @@ private int X_MAX_TEMP_PIXMAP = 20000;
/* for get_bits_rectangle. */
private int X_MAX_TEMP_IMAGE = 5000;
+/* Define whether to try to read back exposure events after XGetImage. */
+/****** THIS IS USELESS. XGetImage DOES NOT GENERATE EXPOSURE EVENTS. ******/
+#define GET_IMAGE_EXPOSURES 0
+
/* Forward references */
private int set_tile(P2(gx_device *, const gx_strip_bitmap *));
private void free_cp(P1(gx_device *));
@@ -73,15 +77,16 @@ private dev_proc_open_device(x_open);
private dev_proc_get_initial_matrix(x_get_initial_matrix);
private dev_proc_sync_output(x_sync);
private dev_proc_output_page(x_output_page);
+extern void gdev_x_free_dynamic_colors(P1(gx_device_X *));
+extern void gdev_x_free_colors(P1(gx_device_X *));
private dev_proc_close_device(x_close);
-private dev_proc_map_rgb_color(x_map_rgb_color);
-private dev_proc_map_color_rgb(x_map_color_rgb);
+extern dev_proc_map_rgb_color(gdev_x_map_rgb_color);
+extern dev_proc_map_color_rgb(gdev_x_map_color_rgb);
private dev_proc_fill_rectangle(x_fill_rectangle);
private dev_proc_copy_mono(x_copy_mono);
private dev_proc_copy_color(x_copy_color);
private dev_proc_get_params(x_get_params);
private dev_proc_put_params(x_put_params);
-
dev_proc_get_xfont_procs(x_get_xfont_procs);
private dev_proc_get_page_device(x_get_page_device);
private dev_proc_strip_tile_rectangle(x_strip_tile_rectangle);
@@ -96,8 +101,8 @@ private const gx_device_procs x_procs =
x_sync,
x_output_page,
x_close,
- x_map_rgb_color,
- x_map_color_rgb,
+ gdev_x_map_rgb_color,
+ gdev_x_map_color_rgb,
x_fill_rectangle,
NULL, /* tile_rectangle */
x_copy_mono,
@@ -144,7 +149,7 @@ const gx_device_X gs_x11_device =
{ /* image */
0, 0, /* width, height */
0, XYBitmap, NULL, /* xoffset, format, data */
- LSBFirst, 8, /* byte-order, bitmap-unit */
+ MSBFirst, 8, /* byte-order, bitmap-unit */
MSBFirst, 8, 1, /* bitmap-bit-order, bitmap-pad, depth */
0, 1, /* bytes_per_line, bits_per_pixel */
0, 0, 0, /* red_mask, green_mask, blue_mask */
@@ -167,9 +172,6 @@ const gx_device_X gs_x11_device =
(Pixmap) 0, /* bpixmap */
0, /* ghostview */
(Window) None, /* mwin */
-#if HaveStdCMap
- NULL, /* std_cmap */
-#endif
{identity_matrix_body}, /* initial matrix (filled in) */
(Atom) 0, (Atom) 0, (Atom) 0, /* Atoms: NEXT, PAGE, DONE */
{0, 0, 0, 0}, 0, 0, /* update, up_area, up_count */
@@ -192,11 +194,7 @@ const gx_device_X gs_x11_device =
0, /* font */
0, 0, /* back_color, fore_color */
0, 0, /* background, foreground */
- NULL, /* dither_colors */
- 0, 0, /* color_mask, num_rgb */
- NULL, 0, /* dynamic_colors, max_dynamic_colors */
- 0, 0, /* dynamic_size, dynamic_allocs */
- NULL, 0, /* color_to_rgb, color_to_rgb_size */
+ { 0 }, /* cman */
0, 0, /* borderColor, borderWidth */
NULL, /* geometry */
128, 5, /* maxGrayRamp, maxRGBRamp */
@@ -248,482 +246,45 @@ x_open(gx_device * dev)
return 0;
}
-/* Close the device. */
-private int
-x_close(gx_device * dev)
+/* Free fonts when closing the device. */
+private void
+free_x_fontmaps(x11fontmap **pmaps)
{
- gx_device_X *xdev = (gx_device_X *) dev;
-
- if (xdev->ghostview)
- x_send_event(dev, xdev->DONE);
- if (xdev->vinfo) {
- XFree((char *)xdev->vinfo);
- xdev->vinfo = NULL;
- }
- if (xdev->dither_colors) {
- if (gx_device_has_color(xdev))
-#define cube(r) (r*r*r)
- gs_free((char *)xdev->dither_colors, sizeof(x_pixel),
- cube(xdev->color_info.dither_colors), "x11_rgb_cube");
-#undef cube
- else
- gs_free((char *)xdev->dither_colors, sizeof(x_pixel),
- xdev->color_info.dither_grays, "x11_gray_ramp");
- xdev->dither_colors = NULL;
- }
- if (xdev->dynamic_colors) {
- int i;
-
- for (i = 0; i < xdev->dynamic_size; i++) {
- x11color *xcp = (*xdev->dynamic_colors)[i];
- x11color *next;
-
- while (xcp) {
- next = xcp->next;
- gs_free((char *)xcp, sizeof(x11color), 1, "x11_dynamic_color");
- xcp = next;
- }
- }
- gs_free((char *)xdev->dynamic_colors, sizeof(x11color *),
- xdev->dynamic_size, "x11_dynamic_colors");
- xdev->dynamic_colors = NULL;
- }
- if (xdev->color_to_rgb) {
- gs_free((char *)xdev->color_to_rgb, sizeof(x11_rgb_t),
- xdev->color_to_rgb_size, "color_to_rgb");
- xdev->color_to_rgb = NULL;
- xdev->color_to_rgb_size = 0;
- }
- while (xdev->regular_fonts) {
- x11fontmap *font = xdev->regular_fonts;
-
- xdev->regular_fonts = font->next;
- if (font->std_names)
- XFreeFontNames(font->std_names);
- if (font->iso_names)
- XFreeFontNames(font->iso_names);
- gs_free(font->x11_name, sizeof(char), strlen(font->x11_name) + 1,
- "x11_font_x11name");
- gs_free(font->ps_name, sizeof(char), strlen(font->ps_name) + 1,
- "x11_font_psname");
-
- gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");
- }
- while (xdev->symbol_fonts) {
- x11fontmap *font = xdev->symbol_fonts;
-
- xdev->symbol_fonts = font->next;
- if (font->std_names)
- XFreeFontNames(font->std_names);
- if (font->iso_names)
- XFreeFontNames(font->iso_names);
- gs_free(font->x11_name, sizeof(char), strlen(font->x11_name) + 1,
- "x11_font_x11name");
- gs_free(font->ps_name, sizeof(char), strlen(font->ps_name) + 1,
- "x11_font_psname");
-
- gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");
- }
- while (xdev->dingbat_fonts) {
- x11fontmap *font = xdev->dingbat_fonts;
-
- xdev->dingbat_fonts = font->next;
- if (font->std_names)
- XFreeFontNames(font->std_names);
- if (font->iso_names)
- XFreeFontNames(font->iso_names);
+ while (*pmaps) {
+ x11fontmap *font = *pmaps;
+
+ *pmaps = font->next;
+ if (font->std.names)
+ XFreeFontNames(font->std.names);
+ if (font->iso.names)
+ XFreeFontNames(font->iso.names);
gs_free(font->x11_name, sizeof(char), strlen(font->x11_name) + 1,
"x11_font_x11name");
gs_free(font->ps_name, sizeof(char), strlen(font->ps_name) + 1,
"x11_font_psname");
- gs_free((char *)font, sizeof(x11fontmap), 1, "x11_fontmap");
- }
- XCloseDisplay(xdev->dpy);
- return 0;
-}
-
-/* Define a table for computing N * X_max_color_value / D for 0 <= N <= D, */
-/* 1 <= D <= 7. */
-/* This requires a multiply and a divide otherwise; */
-/* integer multiply and divide are slow on all platforms. */
-#define cv_fraction(n, d) ((ushort)(X_max_color_value * (n) / (d)))
-#define nd(n, d) cv_fraction(n, d)
-private const ushort cv_tab1[] =
-{
- nd(0, 1), nd(1, 1)
-};
-private const ushort cv_tab2[] =
-{
- nd(0, 2), nd(1, 2), nd(2, 2)
-};
-private const ushort cv_tab3[] =
-{
- nd(0, 3), nd(1, 3), nd(2, 3), nd(3, 3)
-};
-private const ushort cv_tab4[] =
-{
- nd(0, 4), nd(1, 4), nd(2, 4), nd(3, 4), nd(4, 4)
-};
-private const ushort cv_tab5[] =
-{
- nd(0, 5), nd(1, 5), nd(2, 5), nd(3, 5), nd(4, 5), nd(5, 5)
-};
-private const ushort cv_tab6[] =
-{
- nd(0, 6), nd(1, 6), nd(2, 6), nd(3, 6), nd(4, 6), nd(5, 6), nd(6, 6)
-};
-private const ushort cv_tab7[] =
-{
- nd(0, 7), nd(1, 7), nd(2, 7), nd(3, 7), nd(4, 7), nd(5, 7), nd(6, 7), nd(7, 7)
-};
-private const ushort *const cv_tables[] =
-{
- 0, cv_tab1, cv_tab2, cv_tab3, cv_tab4, cv_tab5, cv_tab6, cv_tab7
-};
-
-/* Map a color. The "device colors" are just r,g,b packed together. */
-private gx_color_index
-x_map_rgb_color(register gx_device * dev,
- gx_color_value r, gx_color_value g, gx_color_value b)
-{
- gx_device_X *xdev = (gx_device_X *) dev;
-
- /* X and ghostscript both use shorts for color values */
- unsigned short dr = r & xdev->color_mask; /* Nearest color that */
- unsigned short dg = g & xdev->color_mask; /* the X device can */
- unsigned short db = b & xdev->color_mask; /* represent */
- unsigned short cv_max = X_max_color_value & xdev->color_mask;
-
-#define cv_denom (gx_max_color_value + 1)
-
- /* Foreground and background get special treatment: */
- /* They may be mapped to other colors. */
- if ((dr | dg | db) == 0) { /* i.e., all 0 */
- if_debug4('C', "[cX]%u,%u,%u => foreground = %lu\n",
- r, g, b, (ulong) xdev->foreground);
- return xdev->foreground;
- }
- if ((dr & dg & db) == cv_max) { /* i.e., all max value */
- if_debug4('C', "[cX]%u,%u,%u => background = %lu\n",
- r, g, b, (ulong) xdev->background);
- return xdev->background;
- }
-#if HaveStdCMap
- /* check the standard colormap first */
- if (xdev->std_cmap) {
- XStandardColormap *cmap = xdev->std_cmap;
-
- if (gx_device_has_color(xdev)) {
- unsigned short cr, cg, cb; /* rgb cube indices */
- unsigned short cvr, cvg, cvb; /* color value on cube */
-
- cr = r * (cmap->red_max + 1) / cv_denom;
- cg = g * (cmap->green_max + 1) / cv_denom;
- cb = b * (cmap->blue_max + 1) / cv_denom;
- cvr = X_max_color_value * cr / cmap->red_max;
- cvg = X_max_color_value * cg / cmap->green_max;
- cvb = X_max_color_value * cb / cmap->blue_max;
- if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0 &&
- (abs((int)g - (int)cvg) & xdev->color_mask) == 0 &&
- (abs((int)b - (int)cvb) & xdev->color_mask) == 0) {
- gx_color_index pixel =
- cr * cmap->red_mult + cg * cmap->green_mult +
- cb * cmap->blue_mult + cmap->base_pixel;
-
- if_debug4('C', "[cX]%u,%u,%u (std cmap) => %lu\n",
- r, g, b, pixel);
- return pixel;
- }
- if_debug3('C', "[cX]%u,%u,%u (std cmap fails)\n", r, g, b);
- } else {
- unsigned short cr;
- unsigned short cvr;
- int dither_grays = xdev->color_info.dither_grays;
-
- cr = r * dither_grays / cv_denom;
- cvr = X_max_color_value * cr / cmap->red_max;
- if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0) {
- gx_color_index pixel = cr * cmap->red_mult + cmap->base_pixel;
-
- if_debug2('C', "[cX]%u (std cmap) => %lu\n", r, pixel);
- return pixel;
- }
- if_debug1('C', "[cX]%u (std cmap fails)\n", r);
- }
- } else
-#endif
- /* If there is no standard colormap, check the dither cube/ramp */
- if (xdev->dither_colors) {
- if (gx_device_has_color(xdev)) {
- unsigned short cr, cg, cb; /* rgb cube indices */
- unsigned short cvr, cvg, cvb; /* color value on cube */
- int dither_rgb = xdev->color_info.dither_colors;
- unsigned short max_rgb = dither_rgb - 1;
-
- cr = r * dither_rgb / cv_denom;
- cg = g * dither_rgb / cv_denom;
- cb = b * dither_rgb / cv_denom;
- if (max_rgb < countof(cv_tables)) {
- const ushort *cv_tab = cv_tables[max_rgb];
-
- cvr = cv_tab[cr];
- cvg = cv_tab[cg];
- cvb = cv_tab[cb];
- } else {
- cvr = cv_fraction(cr, max_rgb);
- cvg = cv_fraction(cg, max_rgb);
- cvb = cv_fraction(cb, max_rgb);
- }
- if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0 &&
- (abs((int)g - (int)cvg) & xdev->color_mask) == 0 &&
- (abs((int)b - (int)cvb) & xdev->color_mask) == 0) {
- gx_color_index pixel =
- xdev->dither_colors[cube_index(cr, cg, cb)];
-
- if_debug4('C', "[cX]%u,%u,%u (dither cube) => %lu\n",
- r, g, b, pixel);
- return pixel;
- }
- if_debug3('C', "[cX]%u,%u,%u (dither cube fails)\n", r, g, b);
- } else {
- unsigned short cr;
- unsigned short cvr;
- int dither_grays = xdev->color_info.dither_grays;
- unsigned short max_gray = dither_grays - 1;
-
- cr = r * dither_grays / cv_denom;
- cvr = (X_max_color_value * cr / max_gray);
- if ((abs((int)r - (int)cvr) & xdev->color_mask) == 0) {
- gx_color_index pixel = xdev->dither_colors[cr];
-
- if_debug2('C', "[cX]%u (dither ramp) => %lu\n", r, pixel);
- return pixel;
- }
- if_debug1('C', "[cX]%u (dither ramp fails)\n", r);
- }
- }
- /* Finally look through the list of dynamic colors */
- if (xdev->dynamic_colors) {
- int i = (dr ^ dg ^ db) >> (16 - xdev->vinfo->bits_per_rgb);
- x11color *xcp = (*xdev->dynamic_colors)[i];
- x11color *last = NULL;
- XColor xc;
-
- while (xcp) {
- if (xcp->color.red == dr && xcp->color.green == dg &&
- xcp->color.blue == db) {
- if (last) {
- last->next = xcp->next;
- xcp->next = (*xdev->dynamic_colors)[i];
- (*xdev->dynamic_colors)[i] = xcp;
- }
- if (xcp->color.pad) {
- if_debug4('C', "[cX]%u,%u,%u (dynamic) => %lu\n",
- r, g, b, (ulong) xcp->color.pixel);
- return xcp->color.pixel;
- } else {
- if_debug3('C', "[cX]%u,%u,%u (dynamic) => missing\n",
- r, g, b);
- return gx_no_color_index;
- }
- }
- last = xcp;
- xcp = xcp->next;
- }
-
- /* If not in our list of dynamic colors, */
- /* ask the X server and add an entry. */
- /* First check if dynamic table is exhausted */
- if (xdev->dynamic_allocs > xdev->max_dynamic_colors) {
- if_debug3('C', "[cX]%u,%u,%u (dynamic) => full\n", r, g, b);
- return gx_no_color_index;
- }
- xcp = (x11color *) gs_malloc(sizeof(x11color), 1, "x11_dynamic_color");
- if (!xcp)
- return gx_no_color_index;
- xc.red = xcp->color.red = dr;
- xc.green = xcp->color.green = dg;
- xc.blue = xcp->color.blue = db;
- xcp->next = (*xdev->dynamic_colors)[i];
- (*xdev->dynamic_colors)[i] = xcp;
- xdev->dynamic_allocs++;
- if (XAllocColor(xdev->dpy, xdev->cmap, &xc)) {
- xcp->color.pixel = xc.pixel;
- xcp->color.pad = True;
- if_debug4('C', "[cX]%u,%u,%u (dynamic) => added %lu\n",
- r, g, b, (ulong) xc.pixel);
- return xc.pixel;
- } else {
- xcp->color.pad = False;
- if_debug3('C', "[cX]%u,%u,%u (dynamic) => can't alloc\n", r, g, b);
- return gx_no_color_index;
- }
+ gs_free(font, sizeof(x11fontmap), 1, "x11_fontmap");
}
- if_debug3('C', "[cX]%u,%u,%u fails\n", r, g, b);
- return gx_no_color_index;
}
-
-/*
- * Map a "device color" back to r-g-b. This happens surprisingly often, so
- * we go to some trouble to make it efficient. Foreground and background
- * may be mapped to other colors, so they are handled specially.
- */
+/* Close the device. */
private int
-x_map_color_rgb(register gx_device * dev, gx_color_index color,
- gx_color_value prgb[3])
+x_close(gx_device * dev)
{
gx_device_X *xdev = (gx_device_X *) dev;
-#if HaveStdCMap
- const XStandardColormap *cmap = xdev->std_cmap;
-
-#endif
-#define cv_denom (gx_max_color_value + 1)
-
- if (color == xdev->foreground) {
- prgb[0] = prgb[1] = prgb[2] = 0;
- return 0;
- }
- if (color == xdev->background) {
- prgb[0] = prgb[1] = prgb[2] = gx_max_color_value;
- return 0;
- }
- if (color < xdev->color_to_rgb_size) {
- x11_rgb_t *pxrgb = &xdev->color_to_rgb[color];
-
- if (pxrgb->defined) {
- prgb[0] = pxrgb->rgb[0];
- prgb[1] = pxrgb->rgb[1];
- prgb[2] = pxrgb->rgb[2];
- return 0;
- }
- }
-#if HaveStdCMap
- /* Check the standard colormap first. */
- if (cmap) {
- if (color >= cmap->base_pixel) {
- x_pixel value = color - cmap->base_pixel;
- unsigned long mult[3];
- unsigned long rgb[3];
-
-#define R 0
-#define G 1
-#define B 2
- mult[R] = cmap->red_mult;
- mult[G] = cmap->green_mult;
- mult[B] = cmap->blue_mult;
- /* Get the multipliers in the right order. */
- {
- static const byte order[8][3] =
- {
- {0, 0, 0}, /* not possible */
- {B, G, R},
- {G, R, B},
- {G, B, R},
- {R, B, G},
- {B, R, G},
- {R, G, B},
- {0, 0, 0} /* not possible */
- };
- const byte *indices =
- order[((mult[R] > mult[G]) << 2) + ((mult[G] > mult[B]) << 1) +
- (mult[B] > mult[R])];
-
- rgb[indices[0]] = value / mult[indices[0]];
- value %= mult[indices[0]];
- rgb[indices[1]] = value / mult[indices[1]];
- value %= mult[indices[1]];
- rgb[indices[2]] = value / mult[indices[2]];
- value %= mult[indices[2]];
- if (value == 0 && rgb[R] <= cmap->red_max &&
- rgb[G] <= cmap->green_max && rgb[B] <= cmap->blue_max
- ) {
- /*
- * When mapping color buckets back to specific colors, we can
- * choose to map them to the darkest shades (e.g., 0, 1/3, 2/3),
- * to the lightest shades (e.g., 1/3-epsilon, 2/3-epsilon,
- * 1-epsilon), to the middle shades (e.g., 1/6, 1/2, 5/6),
- * or for maximum contrast (e.g., 0, 1/2, 1). The last of these
- * matches the assumptions of the halftoning code, so that is
- * what we choose.
- */
- prgb[0] = rgb[R] * gx_max_color_value / cmap->red_max;
- prgb[1] = rgb[G] * gx_max_color_value / cmap->green_max;
- prgb[2] = rgb[B] * gx_max_color_value / cmap->blue_max;
- goto found;
- }
- }
-#undef R
-#undef G
-#undef B
- }
- }
-#endif
- /* Check the dither cube/ramp. */
- if (xdev->dither_colors) {
- if (gx_device_has_color(xdev)) {
- int size = xdev->color_info.dither_colors;
- int size3 = size * size * size;
- int i;
-
- for (i = 0; i < size3; ++i)
- if (xdev->dither_colors[i] == color) {
- uint max_rgb = size - 1;
- unsigned long
- r = i / (size * size),
- g = (i / size) % size,
- b = i % size;
-
- /*
- * See above regarding the choice of color mapping
- * algorithm.
- */
- prgb[0] = r * gx_max_color_value / max_rgb;
- prgb[1] = g * gx_max_color_value / max_rgb;
- prgb[2] = b * gx_max_color_value / max_rgb;
- goto found;
- }
- }
- } else {
- int size = xdev->color_info.dither_grays;
- int i;
-
- for (i = 0; i < size; ++i)
- if (xdev->dither_colors[i] == color) {
- prgb[0] = prgb[1] = prgb[2] =
- i * gx_max_color_value / (size - 1);
- goto found;
- }
- }
- /* Finally, search the list of dynamic colors. */
- if (xdev->dynamic_colors) {
- int i;
- const x11color *xcp;
-
- for (i = 1 << xdev->vinfo->bits_per_rgb; --i >= 0;)
- for (xcp = (*xdev->dynamic_colors)[i]; xcp; xcp = xcp->next)
- if (xcp->color.pad && xcp->color.pixel == color) {
- prgb[0] = xcp->color.red;
- prgb[1] = xcp->color.green;
- prgb[2] = xcp->color.blue;
- goto found;
- }
- }
- /* Not found -- not possible! */
- return_error(gs_error_unknownerror);
- found:
- if (color < xdev->color_to_rgb_size) {
- x11_rgb_t *pxrgb = &xdev->color_to_rgb[color];
-
- pxrgb->rgb[0] = prgb[0];
- pxrgb->rgb[1] = prgb[1];
- pxrgb->rgb[2] = prgb[2];
- pxrgb->defined = true;
+ if (xdev->ghostview)
+ x_send_event(dev, xdev->DONE);
+ if (xdev->vinfo) {
+ XFree((char *)xdev->vinfo);
+ xdev->vinfo = NULL;
}
+ gdev_x_free_colors(xdev);
+ free_x_fontmaps(&xdev->dingbat_fonts);
+ free_x_fontmaps(&xdev->symbol_fonts);
+ free_x_fontmaps(&xdev->regular_fonts);
+ XCloseDisplay(xdev->dpy);
return 0;
-#undef cv_denom
}
/* Get initial matrix for X device. */
@@ -812,35 +373,12 @@ x_fill_rectangle(register gx_device * dev,
set_function(GXcopy);
XFillRectangle(xdev->dpy, xdev->dest, xdev->gc, x, y, w, h);
/* If we are filling the entire screen, reset */
- /* colors_or and colors_and. It's wasteful to do this */
+ /* colors_or and colors_and. It's wasteful to test this */
/* on every operation, but there's no separate driver routine */
/* for erasepage (yet). */
if (x == 0 && y == 0 && w == xdev->width && h == xdev->height) {
- if (color == xdev->foreground || color == xdev->background) {
- if (xdev->dynamic_colors) {
- int i;
-
- for (i = 0; i < xdev->dynamic_size; i++) {
- x11color *xcp = (*xdev->dynamic_colors)[i];
- x11color *next;
-
- while (xcp) {
- next = xcp->next;
- if (xcp->color.pad) {
- XFreeColors(xdev->dpy, xdev->cmap,
- &xcp->color.pixel, 1, 0);
- }
- gs_free((char *)xcp, sizeof(x11color), 1,
- "x11_dynamic_color");
- xcp = next;
- }
- (*xdev->dynamic_colors)[i] = NULL;
- }
- xdev->dynamic_allocs = 0;
- for (i = 0; i < xdev->color_to_rgb_size; ++i)
- xdev->color_to_rgb[i].defined = false;
- }
- }
+ if (color == xdev->foreground || color == xdev->background)
+ gdev_x_free_dynamic_colors(xdev);
xdev->colors_or = xdev->colors_and = color;
}
if (xdev->bpixmap != (Pixmap) 0) {
@@ -1369,7 +907,9 @@ x_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
int y, h;
XImage *image;
int code = 0;
+#if GET_IMAGE_EXPOSURES
XWindowAttributes attributes;
+#endif /* GET_IMAGE_EXPOSURES */
if (x0 < 0 || y0 < 0 || x1 > dev->width || y1 > dev->height)
return_error(gs_error_rangecheck);
@@ -1401,46 +941,103 @@ x_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
****** FOLLOWING IS WRONG. XGetImage DOES NOT GENERATE
****** EXPOSURE EVENTS.
******/
-#if 0 /*************** */
+#if GET_IMAGE_EXPOSURES
if (unread) {
XSetGraphicsExposures(xdev->dpy, xdev->gc, True);
XGetWindowAttributes(xdev->dpy, xdev->win, &attributes);
XSelectInput(xdev->dpy, xdev->win,
attributes.your_event_mask | ExposureMask);
}
-#endif /*************** */
+#endif /* GET_IMAGE_EXPOSURES */
/*
* The X library doesn't provide any way to specify the desired
- * bit or byte ordering for the result, so we just hope for the best
- * (big-endian).
+ * bit or byte ordering for the result, so we may have to swap the
+ * bit or byte order.
*/
if (band == 0)
band = 1;
for (y = y0; y < y1; y += h) {
+ int cy;
+
h = min(band, y1 - y);
image = XGetImage(xdev->dpy, xdev->dest, x0, y, x1 - x0, h,
plane_mask, ZPixmap);
- {
- int cy;
-
- for (cy = y; cy < y + h; ++cy)
- memcpy(params->data[0] + (cy - y0) * raster,
- image->data + (cy - y) * image->bytes_per_line,
- width_bytes);
+ for (cy = y; cy < y + h; ++cy) {
+ const byte *source =
+ (const byte *)image->data + (cy - y) * image->bytes_per_line;
+ byte *dest = params->data[0] + (cy - y0) * raster;
+
+ /*
+ * XGetImage can return an image with any bit order, byte order,
+ * unit size (for bitmaps), and bits_per_pixel it wants: it's up
+ * to us to convert the results. (It's a major botch in the X
+ * design that even though the server has to have the ability to
+ * convert images from any format to any format, there's no way
+ * to specify a requested format for XGetImage.)
+ */
+ if (image->bits_per_pixel == image->depth &&
+ (image->depth > 1 || image->bitmap_bit_order == MSBFirst) &&
+ (image->byte_order == MSBFirst || image->depth <= 8)
+ ) {
+ /*
+ * The server has been nice enough to return an image in the
+ * format we use.
+ */
+ memcpy(dest, source, width_bytes);
+ } else {
+ /*
+ * We need to swap byte order and/or bit order. What a
+ * totally unnecessary nuisance! For the moment, the only
+ * cases we deal with are 16- and 24-bit images with padding
+ * and/or byte swapping.
+ */
+ if (image->depth == 24) {
+ int cx;
+ const byte *p = source;
+ byte *q = dest;
+ int step = image->bits_per_pixel >> 3;
+
+ if (image->byte_order == MSBFirst) {
+ p += step - 3;
+ for (cx = x0; cx < x1; p += step, q += 3, ++cx)
+ q[0] = p[0], q[1] = p[1], q[2] = p[2];
+ } else {
+ for (cx = x0; cx < x1; p += step, q += 3, ++cx)
+ q[0] = p[2], q[1] = p[1], q[2] = p[0];
+ }
+ } else if (image->depth == 16) {
+ int cx;
+ const byte *p = source;
+ byte *q = dest;
+ int step = image->bits_per_pixel >> 3;
+
+ if (image->byte_order == MSBFirst) {
+ p += step - 2;
+ for (cx = x0; cx < x1; p += step, q += 2, ++cx)
+ q[0] = p[0], q[1] = p[1];
+ } else {
+ for (cx = x0; cx < x1; p += step, q += 2, ++cx)
+ q[0] = p[1], q[1] = p[0];
+ }
+ } else
+ code = gs_note_error(gs_error_rangecheck);
+ }
}
XDestroyImage(image);
}
if (unread) {
+#if GET_IMAGE_EXPOSURES
XEvent event;
+#endif /* GET_IMAGE_EXPOSURES */
*unread = 0;
-#if 0 /*************** */
+#if GET_IMAGE_EXPOSURES
/* Read any exposure events. */
XWindowEvent(xdev->dpy, xdev->win, ExposureMask, &event);
if (event.type == GraphicsExpose) {
gs_int_rect *rects = (gs_int_rect *)
- gs_alloc_bytes(dev->memory, sizeof(gs_int_rect),
- "x_get_bits_rectangle");
+ gs_alloc_bytes(dev->memory, sizeof(gs_int_rect),
+ "x_get_bits_rectangle");
int num_rects = 0;
for (;;) {
@@ -1458,7 +1055,7 @@ x_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
break;
#undef xevent
rects = gs_resize_object(dev->memory, rects,
- (num_rects + 1) * sizeof(gs_int_rect),
+ (num_rects + 1) * sizeof(gs_int_rect),
"x_get_bits_rectangle");
}
if (code >= 0) {
@@ -1469,7 +1066,7 @@ x_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
/* Restore the window state. */
XSetGraphicsExposures(xdev->dpy, xdev->gc, False);
XSelectInput(xdev->dpy, xdev->win, attributes.your_event_mask);
-#endif /*************** */
+#endif /* GET_IMAGE_EXPOSURES */
}
return code;
}
@@ -1575,7 +1172,7 @@ x_update_add(gx_device * dev, int xo, int yo, int w, int h)
/* would result in too much being copied unnecessarily. */
long old_area = xdev->up_area;
long new_up_area;
- rect u;
+ x_rect u;
u.xo = min(xo, xdev->update.xo);
u.yo = min(yo, xdev->update.yo);
diff --git a/gs/src/gdevx.h b/gs/src/gdevx.h
index b0606b569..266d77191 100644
--- a/gs/src/gdevx.h
+++ b/gs/src/gdevx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,37 +25,31 @@
/* Define the type of an X pixel. */
typedef unsigned long x_pixel;
+#include "gdevxcmp.h"
+
+/* Declare the X resource tables compiled separately in gdevxres.c. */
+extern XtResource gdev_x_resources[];
+extern const int gdev_x_resource_count;
+extern String gdev_x_fallback_resources[];
+
/* Define a rectangle structure for update bookkeeping */
-typedef struct rect_s {
+typedef struct x_rect_s {
int xo, yo, xe, ye;
-} rect;
-
-/* Define dynamic color hash table structure */
-struct x11color_s;
-typedef struct x11color_s x11color;
-struct x11color_s {
- XColor color;
- x11color *next;
-};
+} x_rect;
/* Define PostScript to X11 font name mapping */
-struct x11fontmap_s;
+typedef struct x11fontlist_s {
+ char **names;
+ int count;
+} x11fontlist;
typedef struct x11fontmap_s x11fontmap;
struct x11fontmap_s {
char *ps_name;
char *x11_name;
- char **std_names;
- char **iso_names;
- int std_count, iso_count;
+ x11fontlist std, iso;
x11fontmap *next;
};
-/* Define pixel value to RGB mapping */
-typedef struct x11_rgb_s {
- gx_color_value rgb[3];
- bool defined;
-} x11_rgb_t;
-
/* Define the X Windows device */
typedef struct gx_device_X_s {
gx_device_common;
@@ -80,15 +74,11 @@ typedef struct gx_device_X_s {
/* or if it can't be allocated */
int ghostview; /* flag to tell if ghostview is in control */
Window mwin; /* window to receive ghostview messages */
-/* Don't include standard colormap stuff for X11R3 and earlier */
-#if HaveStdCMap
- XStandardColormap *std_cmap; /* standard color map if available */
-#endif
gs_matrix initial_matrix; /* the initial transformation */
Atom NEXT, PAGE, DONE; /* Atoms used to talk to ghostview */
- rect update; /* region needing updating */
+ x_rect update; /* region needing updating */
long up_area; /* total area of update */
- /* (always 0 if no backing pixmap) */
+ /* (always 0 if no backing pixmap) */
int up_count; /* # of updates since flush */
Pixmap dest; /* bpixmap if non-0, else win */
x_pixel colors_or; /* 'or' of all device colors used so far */
@@ -129,16 +119,12 @@ typedef struct gx_device_X_s {
x_pixel back_color, fore_color;
Pixel background, foreground;
-#define X_max_color_value 0xffff
-#define cube_index(r,g,b) (((r) * xdev->color_info.dither_colors + (g)) * \
- xdev->color_info.dither_colors + (b))
- x_pixel *dither_colors;
- ushort color_mask;
- int num_rgb;
- x11color *(*dynamic_colors)[];
- int max_dynamic_colors, dynamic_size, dynamic_allocs;
- x11_rgb_t *color_to_rgb; /* [256] */
- int color_to_rgb_size;
+
+ /*
+ * The color management structure is defined in gdevxcmp.h and is
+ * managed by the code in gdevxcmp.c.
+ */
+ x11_cman_t cman;
#define note_color(pixel)\
xdev->colors_or |= pixel,\
diff --git a/gs/src/gdevxalt.c b/gs/src/gdevxalt.c
index 16bfd1d52..9e93b885d 100644
--- a/gs/src/gdevxalt.c
+++ b/gs/src/gdevxalt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,9 +25,11 @@
#include "gserrors.h"
#include "gsparam.h"
#include "gxdevice.h"
+#include "gsdevice.h" /* for gs_copydevice */
#include "gdevx.h"
+#include "gdevdcrd.h"
-extern gx_device_X gs_x11_device;
+extern const gx_device_X gs_x11_device;
/*
* Define a forwarding device with a cache for the first 16 colors,
@@ -260,11 +262,18 @@ x_wrap_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
byte *base;
int code;
gx_color_index pixel_in = gx_no_color_index;
- gx_color_index pixel_out;
+ /*
+ * The following initialization is unnecessary: since no pixel has a
+ * value of gx_no_color_index, the test pixel != pixel_in will always
+ * succeed the first time through the loop below, so pixel_out will
+ * always be set before it is used. We initialize pixel_out solely to
+ * suppress bogus warning messages from certain compilers.
+ */
+ gx_color_index pixel_out = 0;
int xi;
int sbit;
- declare_line_accum(str, depth, 0);
+ DECLARE_LINE_ACCUM(str, depth, 0);
set_dev_target(tdev, dev);
width = tdev->width;
@@ -287,13 +296,13 @@ x_wrap_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
pixel = (*sptr >> (8 - sdepth - (sbit & 7))) & smask;
else {
pixel = 0;
- for (i = 0; i < depth; i += 8, ++sptr)
+ for (i = 0; i < sdepth; i += 8, ++sptr)
pixel = (pixel << 8) + *sptr;
}
if (pixel != pixel_in) {
(*dev_proc(tdev, map_color_rgb))(tdev, pixel, rgb);
pixel_in = pixel;
- if (tdev->color_info.num_components <= 3)
+ if (dev->color_info.num_components <= 3)
pixel_out = (*dev_proc(dev, map_rgb_color))
(dev, rgb[0], rgb[1], rgb[2]);
else {
@@ -307,9 +316,9 @@ x_wrap_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
(dev, c - k, m - k, y - k, k);
}
}
- line_accum(pixel_out, depth);
+ LINE_ACCUM(pixel_out, depth);
}
- line_accum_store(depth);
+ LINE_ACCUM_STORE(depth);
gx:gs_free_object(mem, row, "x_wrap_get_bits");
*actual_data = str;
return code;
@@ -319,19 +328,21 @@ private int
x_wrap_get_params(gx_device * dev, gs_param_list * plist)
{
gx_device *tdev;
-
/* We assume that a get_params call has no side effects.... */
gx_device_X save_dev;
- int code;
+ int ecode, code;
set_dev_target(tdev, dev);
save_dev = *(gx_device_X *) tdev;
if (tdev->is_open)
tdev->color_info = dev->color_info;
tdev->dname = dev->dname;
- code = (*dev_proc(tdev, get_params)) (tdev, plist);
+ ecode = (*dev_proc(tdev, get_params)) (tdev, plist);
*(gx_device_X *) tdev = save_dev;
- return code;
+ code = sample_device_crd_get_params(dev, plist, "CRDDefault");
+ if (code < 0)
+ ecode = code;
+ return ecode;
}
private int
@@ -368,21 +379,15 @@ get_dev_target(gx_device ** ptdev, gx_device * dev)
{
gx_device *tdev = ((gx_device_forward *) dev)->target;
- if (tdev == 0) { /* Create or link to an X device instance. */
- if (dev->memory == 0) /* static instance */
- tdev = (gx_device *) & gs_x11_device;
- else {
- tdev = (gx_device *) gs_alloc_bytes(dev->memory,
- (gs_x11_device).params_size,
- "dev_target");
- if (tdev == 0)
- return_error(gs_error_VMerror);
- *(gx_device_X *) tdev = gs_x11_device;
- tdev->memory = dev->memory;
- tdev->is_open = false;
- }
+ if (tdev == 0) {
+ /* Create an X device instance. */
+ int code = gs_copydevice(&tdev, (const gx_device *)&gs_x11_device,
+ dev->memory);
+
+ if (code < 0)
+ return 0;
gx_device_fill_in_procs(tdev);
- ((gx_device_forward *) dev)->target = tdev;
+ gx_device_set_target((gx_device_forward *)dev, tdev);
x_clear_color_cache(dev);
}
*ptdev = tdev;
@@ -410,8 +415,14 @@ get_target_info(gx_device * dev)
copy2(MarginsHWResolution);
copy2(Margins);
copy4(HWMargins);
- if (dev->color_info.num_components == 3)
+ if (dev->color_info.num_components == 3) {
+ /* Leave the anti-aliasing information alone. */
+ gx_device_anti_alias_info aa;
+
+ aa = dev->color_info.anti_alias;
copy(color_info);
+ dev->color_info.anti_alias = aa;
+ }
#undef copy4
#undef copy2
@@ -680,7 +691,6 @@ const gx_device_X_wrapper gs_x11gray4_device =
/* Device procedures */
private dev_proc_map_color_rgb(x_alpha_map_color_rgb);
private dev_proc_map_rgb_alpha_color(x_alpha_map_rgb_alpha_color);
-private dev_proc_get_alpha_bits(x_alpha_get_alpha_bits);
private dev_proc_copy_alpha(x_alpha_copy_alpha);
/* The device descriptor */
@@ -706,17 +716,18 @@ private const gx_device_procs x_alpha_procs =
gx_forward_get_xfont_device,
x_alpha_map_rgb_alpha_color,
gx_forward_get_page_device,
- x_alpha_get_alpha_bits,
+ gx_default_get_alpha_bits,
/*gx_default_copy_alpha */ x_alpha_copy_alpha
};
/* The instance is public. */
const gx_device_X_wrapper gs_x11alpha_device =
{
- std_device_dci_body(gx_device_X_wrapper, &x_alpha_procs, "x11alpha",
+ std_device_dci_alpha_type_body(gx_device_X_wrapper, &x_alpha_procs,
+ "x11alpha", 0,
FAKE_RES * 85 / 10, FAKE_RES * 11, /* x and y extent (nominal) */
FAKE_RES, FAKE_RES, /* x and y density (nominal) */
- 3, 32, 255, 255, 256, 256),
+ 3, 32, 255, 255, 256, 256, 4, 4),
{0}, /* std_procs */
0 /* target */
};
@@ -738,17 +749,11 @@ x_alpha_map_rgb_alpha_color(gx_device * dev,
gx_color_index color = gx_forward_map_rgb_color(dev, r, g, b);
byte abyte = alpha >> (gx_color_value_bits - 8);
- return (abyte == 0 ? 0xff000000 :
+ return (abyte == 0 ? (gx_color_index)0xff << 24 :
((gx_color_index) (abyte ^ 0xff) << 24) + color);
}
private int
-x_alpha_get_alpha_bits(gx_device * dev, graphics_object_type type)
-{
- return 4;
-}
-
-private int
x_alpha_copy_alpha(gx_device * dev, const unsigned char *base, int sourcex,
int raster, gx_bitmap_id id, int x, int y, int w, int h,
gx_color_index color, int depth)
diff --git a/gs/src/gdevxcmp.c b/gs/src/gdevxcmp.c
new file mode 100644
index 000000000..6d042a248
--- /dev/null
+++ b/gs/src/gdevxcmp.c
@@ -0,0 +1,806 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* X Windows color mapping */
+#include "math_.h"
+#include "x_.h"
+#include "gx.h" /* for gx_bitmap; includes std.h */
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gdevx.h"
+
+/* ---------------- Utilities ---------------- */
+
+private void
+gs_x_free(void *obj, client_name_t cname)
+{
+ gs_free(obj, 0 /*ignored*/, 0 /*ignored*/, cname);
+}
+
+/* ---------------- Color mapping setup / cleanup ---------------- */
+
+#if HaveStdCMap
+/* Get the Standard colormap if available. */
+/* Uses: dpy, scr, cmap. */
+private XStandardColormap *
+x_get_std_cmap(gx_device_X * xdev, Atom prop)
+{
+ int i;
+ XStandardColormap *scmap, *sp;
+ int nitems;
+
+ if (XGetRGBColormaps(xdev->dpy, RootWindowOfScreen(xdev->scr),
+ &scmap, &nitems, prop))
+ for (i = 0, sp = scmap; i < nitems; i++, sp++)
+ if (xdev->cmap == sp->colormap)
+ return sp;
+
+ return NULL;
+}
+
+/* Create a Standard colormap for a TrueColor or StaticGray display. */
+/* Return true if the allocation was successful. */
+/* Uses: vinfo. Sets: std_cmap, free_std_cmap. */
+private bool
+alloc_std_cmap(gx_device_X *xdev, bool colored)
+{
+ XStandardColormap *cmap = XAllocStandardColormap();
+
+ if (cmap == 0)
+ return false; /* can't allocate */
+ /*
+ * Some buggy X servers (including XFree86) don't set any of the
+ * _mask values for StaticGray visuals. Compensate for that here.
+ */
+ if ((cmap->red_max = xdev->vinfo->red_mask) == 0) {
+ cmap->red_max = (1 << xdev->vinfo->depth) - 1;
+ cmap->red_mult = 1;
+ } else {
+ for (cmap->red_mult = 1; (cmap->red_max & 1) == 0;) {
+ cmap->red_max >>= 1;
+ cmap->red_mult <<= 1;
+ }
+ }
+ if (colored) {
+ for (cmap->green_max = xdev->vinfo->green_mask, cmap->green_mult = 1;
+ (cmap->green_max & 1) == 0;
+ ) {
+ cmap->green_max >>= 1;
+ cmap->green_mult <<= 1;
+ }
+ for (cmap->blue_max = xdev->vinfo->blue_mask, cmap->blue_mult = 1;
+ (cmap->blue_max & 1) == 0;
+ ) {
+ cmap->blue_max >>= 1;
+ cmap->blue_mult <<= 1;
+ }
+ }
+ xdev->cman.std_cmap = cmap;
+ xdev->cman.free_std_cmap = true;
+ return true;
+}
+#endif
+
+/* Allocate the dynamic color table, if needed and possible. */
+/* Uses: vinfo, cman.num_rgb. Sets: cman.dynamic.*. */
+private void
+alloc_dynamic_colors(gx_device_X * xdev, int num_colors)
+{
+ if (num_colors > 0) {
+ xdev->cman.dynamic.colors = (x11_color_t **)
+ gs_malloc(sizeof(x11_color_t *), xdev->cman.num_rgb,
+ "x11 cman.dynamic.colors");
+ if (xdev->cman.dynamic.colors) {
+ int i;
+
+ xdev->cman.dynamic.size = xdev->cman.num_rgb;
+ xdev->cman.dynamic.shift = 16 - xdev->vinfo->bits_per_rgb;
+ for (i = 0; i < xdev->cman.num_rgb; i++)
+ xdev->cman.dynamic.colors[i] = NULL;
+ xdev->cman.dynamic.max_used = min(256, num_colors);
+ xdev->cman.dynamic.used = 0;
+ }
+ }
+}
+
+/* Allocate an X color, updating the reverse map. */
+/* Return true if the allocation was successful. */
+private bool
+x_alloc_color(gx_device_X *xdev, XColor *xcolor)
+{
+ x11_rgb_t rgb;
+
+ rgb.rgb[0] = xcolor->red;
+ rgb.rgb[1] = xcolor->green;
+ rgb.rgb[2] = xcolor->blue;
+ if (!XAllocColor(xdev->dpy, xdev->cmap, xcolor))
+ return false;
+ if (xcolor->pixel < xdev->cman.color_to_rgb.size) {
+ x11_rgb_t *pxrgb = &xdev->cman.color_to_rgb.values[xcolor->pixel];
+
+ memcpy(pxrgb->rgb, rgb.rgb, sizeof(rgb.rgb));
+ pxrgb->defined = true;
+ }
+ return true;
+}
+
+/* Free X colors, updating the reverse map. */
+private void
+x_free_colors(gx_device_X *xdev, x_pixel *pixels /*[count]*/, int count)
+{
+ int i;
+ x_pixel pixel;
+
+ XFreeColors(xdev->dpy, xdev->cmap, pixels, count, 0);
+ for (i = 0; i < count; ++i)
+ if ((pixel = pixels[i]) < xdev->cman.color_to_rgb.size)
+ xdev->cman.color_to_rgb.values[pixel].defined = false;
+}
+
+/* Free a partially filled color cube or ramp. */
+/* Uses: dpy, cmap. Uses and sets: cman.dither_ramp. */
+private void
+free_ramp(gx_device_X * xdev, int num_used, int size)
+{
+ if (num_used - 1 > 0)
+ x_free_colors(xdev, xdev->cman.dither_ramp + 1, num_used - 1);
+ gs_x_free(xdev->cman.dither_ramp, "x11_setup_colors");
+ xdev->cman.dither_ramp = NULL;
+}
+
+/* Allocate and fill in a color cube or ramp. */
+/* Return true if the operation succeeded. */
+/* Uses: dpy, cmap, foreground, background, cman.color_mask. */
+/* Sets: cman.dither_ramp. */
+private bool
+setup_cube(gx_device_X * xdev, int ramp_size, bool colors)
+{
+ int step, num_entries;
+ int max_rgb = ramp_size - 1;
+ int index;
+
+ if (colors) {
+ num_entries = ramp_size * ramp_size * ramp_size;
+ step = 1; /* all colors */
+ } else {
+ num_entries = ramp_size;
+ step = (ramp_size + 1) * ramp_size + 1; /* gray only */
+ }
+
+ xdev->cman.dither_ramp =
+ (x_pixel *) gs_malloc(sizeof(x_pixel), num_entries,
+ "gdevx setup_cube");
+ if (xdev->cman.dither_ramp == NULL)
+ return false;
+
+ xdev->cman.dither_ramp[0] = xdev->foreground;
+ xdev->cman.dither_ramp[num_entries - 1] = xdev->background;
+ for (index = 1; index < num_entries - 1; index++) {
+ int rgb_index = index * step;
+ int q = rgb_index / ramp_size,
+ r = q / ramp_size,
+ g = q % ramp_size,
+ b = rgb_index % ramp_size;
+ XColor xc;
+
+ xc.red = (X_max_color_value * r / max_rgb) & xdev->cman.color_mask.red;
+ xc.green = (X_max_color_value * g / max_rgb) & xdev->cman.color_mask.green;
+ xc.blue = (X_max_color_value * b / max_rgb) & xdev->cman.color_mask.blue;
+ if (!x_alloc_color(xdev, &xc)) {
+ free_ramp(xdev, index, num_entries);
+ return false;
+ }
+ xdev->cman.dither_ramp[index] = xc.pixel;
+ }
+
+ return true;
+}
+
+/* Setup color mapping. */
+int
+gdev_x_setup_colors(gx_device_X * xdev)
+{
+ char palette =
+ ((xdev->vinfo->class != StaticGray) &&
+ (xdev->vinfo->class != GrayScale) ? 'C' : /* Color */
+ (xdev->vinfo->colormap_size > 2) ? 'G' : /* GrayScale */
+ 'M'); /* MonoChrome */
+
+ if (xdev->ghostview) {
+ Atom gv_colors = XInternAtom(xdev->dpy, "GHOSTVIEW_COLORS", False);
+ Atom type;
+ int format;
+ unsigned long nitems, bytes_after;
+ char *buf;
+
+ /* Delete property if explicit dest is given */
+ if (XGetWindowProperty(xdev->dpy, xdev->win, gv_colors, 0,
+ 256, (xdev->dest != 0), XA_STRING,
+ &type, &format, &nitems, &bytes_after,
+ (unsigned char **)&buf) == 0 &&
+ type == XA_STRING) {
+ nitems = sscanf(buf, "%*s %ld %ld", &(xdev->foreground),
+ &(xdev->background));
+ if (nitems != 2 || (*buf != 'M' && *buf != 'G' && *buf != 'C')) {
+ eprintf("Malformed GHOSTVIEW_COLOR property.\n");
+ return_error(gs_error_rangecheck);
+ }
+ palette = max(palette, *buf);
+ }
+ } else {
+ if (xdev->palette[0] == 'c')
+ xdev->palette[0] = 'C';
+ else if (xdev->palette[0] == 'g')
+ xdev->palette[0] = 'G';
+ else if (xdev->palette[0] == 'm')
+ xdev->palette[0] = 'M';
+ palette = max(palette, xdev->palette[0]);
+ }
+
+ /* set up color mappings here */
+ xdev->cman.color_mask.red = xdev->cman.color_mask.green =
+ xdev->cman.color_mask.blue = X_max_color_value -
+ (X_max_color_value >> xdev->vinfo->bits_per_rgb);
+ xdev->cman.num_rgb = 1 << xdev->vinfo->bits_per_rgb;
+
+#if HaveStdCMap
+ xdev->cman.std_cmap = NULL;
+ xdev->cman.free_std_cmap = false;
+#endif
+ xdev->cman.dither_ramp = NULL;
+ xdev->cman.dynamic.colors = NULL;
+ xdev->cman.dynamic.size = 0;
+ xdev->cman.dynamic.used = 0;
+ switch (xdev->vinfo->depth) {
+ case 1: case 2: case 4: case 8: case 16: case 24: case 32:
+ xdev->color_info.depth = xdev->vinfo->depth;
+ break;
+ case 15:
+ xdev->color_info.depth = 16;
+ break;
+ default:
+ eprintf1("Unsupported X visual depth: %d\n", xdev->vinfo->depth);
+ return_error(gs_error_rangecheck);
+ }
+ switch ((int)palette) {
+ case 'C':
+ xdev->color_info.num_components = 3;
+ xdev->color_info.max_gray =
+ xdev->color_info.max_color = xdev->cman.num_rgb - 1;
+#if HaveStdCMap
+ /* Get a standard color map if available */
+ if (xdev->vinfo->visual == DefaultVisualOfScreen(xdev->scr)) {
+ xdev->cman.std_cmap = x_get_std_cmap(xdev, XA_RGB_DEFAULT_MAP);
+ } else {
+ xdev->cman.std_cmap = x_get_std_cmap(xdev, XA_RGB_BEST_MAP);
+ }
+ if (xdev->cman.std_cmap ||
+ (xdev->vinfo->class == TrueColor && alloc_std_cmap(xdev, true))
+ ) {
+ xdev->color_info.dither_grays = xdev->color_info.dither_colors =
+ min(xdev->cman.std_cmap->red_max,
+ min(xdev->cman.std_cmap->green_max,
+ xdev->cman.std_cmap->blue_max)) + 1;
+ } else
+#endif
+ /* Otherwise set up a rgb cube of our own */
+ /* The color cube is limited to about 1/2 of the available */
+ /* colormap, the user specified maxRGBRamp (usually 5), */
+ /* or the number of representable colors */
+#define CUBE(r) (r*r*r)
+#define CBRT(r) pow(r, 1.0/3.0)
+ {
+ int ramp_size =
+ min((int)CBRT(xdev->vinfo->colormap_size / 2.0),
+ min(xdev->maxRGBRamp, xdev->cman.num_rgb));
+
+ while (!xdev->cman.dither_ramp && ramp_size >= 2) {
+ xdev->color_info.dither_grays =
+ xdev->color_info.dither_colors = ramp_size;
+ if (!setup_cube(xdev, ramp_size, true)) {
+#ifdef DEBUG
+ eprintf3("Warning: failed to allocate %dx%dx%d RGB cube.\n",
+ ramp_size, ramp_size, ramp_size);
+#endif
+ ramp_size--;
+ continue;
+ }
+ }
+
+ if (!xdev->cman.dither_ramp) {
+ goto grayscale;
+ }
+ }
+
+ /* Allocate the dynamic color table. */
+ alloc_dynamic_colors(xdev, CUBE(xdev->cman.num_rgb) -
+ CUBE(xdev->color_info.dither_colors));
+#undef CUBE
+#undef CBRT
+ break;
+ case 'G':
+grayscale:
+ xdev->color_info.num_components = 1;
+ xdev->color_info.max_gray = xdev->cman.num_rgb - 1;
+#if HaveStdCMap
+ /* Get a standard color map if available */
+ xdev->cman.std_cmap = x_get_std_cmap(xdev, XA_RGB_GRAY_MAP);
+ if (xdev->cman.std_cmap ||
+ (xdev->vinfo->class == StaticGray && alloc_std_cmap(xdev, false))
+ ) {
+ xdev->color_info.dither_grays = xdev->cman.std_cmap->red_max + 1;
+ } else
+#endif
+ /* Otherwise set up a gray ramp of our own */
+ /* The gray ramp is limited to about 1/2 of the available */
+ /* colormap, the user specified maxGrayRamp (usually 128), */
+ /* or the number of representable grays */
+ {
+ int ramp_size = min(xdev->vinfo->colormap_size / 2,
+ min(xdev->maxGrayRamp, xdev->cman.num_rgb));
+
+ while (!xdev->cman.dither_ramp && ramp_size >= 3) {
+ xdev->color_info.dither_grays = ramp_size;
+ if (!setup_cube(xdev, ramp_size, false)) {
+#ifdef DEBUG
+ eprintf1("Warning: failed to allocate %d level gray ramp.\n",
+ ramp_size);
+#endif
+ ramp_size /= 2;
+ continue;
+ }
+ }
+ if (!xdev->cman.dither_ramp) {
+ goto monochrome;
+ }
+ }
+
+ /* Allocate the dynamic color table. */
+ alloc_dynamic_colors(xdev, xdev->cman.num_rgb -
+ xdev->color_info.dither_grays);
+ break;
+ case 'M':
+monochrome:
+ xdev->color_info.num_components = 1;
+ xdev->color_info.max_gray = 1;
+ xdev->color_info.dither_grays = 2;
+ break;
+ default:
+ eprintf1("Unknown palette: %s\n", xdev->palette);
+ return_error(gs_error_rangecheck);
+ }
+ { /* Set up the reverse map from pixel values to RGB. */
+ int count = 1 << min(xdev->color_info.depth, 8);
+
+ xdev->cman.color_to_rgb.values =
+ (x11_rgb_t *)gs_malloc(sizeof(x11_rgb_t), count,
+ "gdevx color_to_rgb");
+ if (xdev->cman.color_to_rgb.values) {
+ int i;
+
+ for (i = 0; i < count; ++i)
+ xdev->cman.color_to_rgb.values[i].defined = false;
+ xdev->cman.color_to_rgb.size = count;
+ } else
+ xdev->cman.color_to_rgb.size = 0;
+ }
+ return 0;
+}
+
+/* Free the dynamic colors when doing an erasepage. */
+/* Uses: cman.dynamic.*. Sets: cman.dynamic.used. */
+void
+gdev_x_free_dynamic_colors(gx_device_X *xdev)
+{
+ if (xdev->cman.dynamic.colors) {
+ int i;
+ x11_color_t *xcp;
+ x11_color_t *next;
+
+ for (i = 0; i < xdev->cman.dynamic.size; i++) {
+ for (xcp = xdev->cman.dynamic.colors[i]; xcp; xcp = next) {
+ next = xcp->next;
+ if (xcp->color.pad)
+ x_free_colors(xdev, &xcp->color.pixel, 1);
+ gs_x_free(xcp, "x11_dynamic_color");
+ }
+ xdev->cman.dynamic.colors[i] = NULL;
+ }
+ xdev->cman.dynamic.used = 0;
+ }
+}
+
+/* Free storage and color map entries when closing the device. */
+/* Uses and sets: cman.{std_cmap, dither_ramp, dynamic.colors, color_to_rgb.*}. */
+/* Uses: cman.free_std_cmap. */
+void
+gdev_x_free_colors(gx_device_X *xdev)
+{
+ if (xdev->cman.free_std_cmap) {
+ /* XFree is declared as taking a char *, not a void *! */
+ XFree((void *)xdev->cman.std_cmap);
+ xdev->cman.free_std_cmap = false;
+ }
+ xdev->cman.std_cmap = 0;
+ if (xdev->cman.dither_ramp)
+ gs_x_free(xdev->cman.dither_ramp, "x11 dither_colors");
+ if (xdev->cman.dynamic.colors) {
+ gdev_x_free_dynamic_colors(xdev);
+ gs_x_free(xdev->cman.dynamic.colors, "x11 cman.dynamic.colors");
+ xdev->cman.dynamic.colors = NULL;
+ }
+ if (xdev->cman.color_to_rgb.values) {
+ gs_x_free(xdev->cman.color_to_rgb.values, "x11 color_to_rgb");
+ xdev->cman.color_to_rgb.values = NULL;
+ xdev->cman.color_to_rgb.size = 0;
+ }
+}
+
+/* ---------------- Driver color mapping calls ---------------- */
+
+/* Define a table for computing N * X_max_color_value / D for 0 <= N <= D, */
+/* 1 <= D <= 7. */
+/* This requires a multiply and a divide otherwise; */
+/* integer multiply and divide are slow on all platforms. */
+#define CV_FRACTION(n, d) ((X_color_value)(X_max_color_value * (n) / (d)))
+#define ND(n, d) CV_FRACTION(n, d)
+private const X_color_value cv_tab1[] = {
+ ND(0,1), ND(1,1)
+};
+private const X_color_value cv_tab2[] = {
+ ND(0,2), ND(1,2), ND(2,2)
+};
+private const X_color_value cv_tab3[] = {
+ ND(0,3), ND(1,3), ND(2,3), ND(3,3)
+};
+private const X_color_value cv_tab4[] = {
+ ND(0,4), ND(1,4), ND(2,4), ND(3,4), ND(4,4)
+};
+private const X_color_value cv_tab5[] = {
+ ND(0,5), ND(1,5), ND(2,5), ND(3,5), ND(4,5), ND(5,5)
+};
+private const X_color_value cv_tab6[] = {
+ ND(0,6), ND(1,6), ND(2,6), ND(3,6), ND(4,6), ND(5,6), ND(6,6)
+};
+private const X_color_value cv_tab7[] = {
+ ND(0,7), ND(1,7), ND(2,7), ND(3,7), ND(4,7), ND(5,7), ND(6,7), ND(7,7)
+};
+#undef ND
+private const X_color_value *const cv_tables[] =
+{
+ 0, cv_tab1, cv_tab2, cv_tab3, cv_tab4, cv_tab5, cv_tab6, cv_tab7
+};
+
+/* Some C compilers don't declare the abs function in math.h. */
+/* Provide one of our own. */
+private inline int
+iabs(int x)
+{
+ return (x < 0 ? -x : x);
+}
+
+/* Map RGB values to a pixel value. */
+gx_color_index
+gdev_x_map_rgb_color(gx_device * dev,
+ gx_color_value r, gx_color_value g, gx_color_value b)
+{
+ gx_device_X *const xdev = (gx_device_X *) dev;
+
+ /* X and ghostscript both use shorts for color values */
+ X_color_value dr = r & xdev->cman.color_mask.red; /* Nearest color that */
+ X_color_value dg = g & xdev->cman.color_mask.green;/* the X device can */
+ X_color_value db = b & xdev->cman.color_mask.blue; /* represent */
+
+ /* Foreground and background get special treatment: */
+ /* They may be mapped to other colors. */
+ if ((dr | dg | db) == 0) { /* i.e., all 0 */
+ if_debug4('C', "[cX]%u,%u,%u => foreground = %lu\n",
+ r, g, b, (ulong) xdev->foreground);
+ return xdev->foreground;
+ }
+ if (dr == xdev->cman.color_mask.red &&
+ dg == xdev->cman.color_mask.green &&
+ db == xdev->cman.color_mask.blue
+ ) {
+ if_debug4('C', "[cX]%u,%u,%u => background = %lu\n",
+ r, g, b, (ulong) xdev->background);
+ return xdev->background;
+ }
+
+#define CV_DENOM (gx_max_color_value + 1)
+
+#if HaveStdCMap
+ /* check the standard colormap first */
+ if (xdev->cman.std_cmap) {
+ const XStandardColormap *cmap = xdev->cman.std_cmap;
+
+ if (gx_device_has_color(xdev)) {
+ uint cr, cg, cb; /* rgb cube indices */
+ X_color_value cvr, cvg, cvb; /* color value on cube */
+
+ cr = r * (cmap->red_max + 1) / CV_DENOM;
+ cg = g * (cmap->green_max + 1) / CV_DENOM;
+ cb = b * (cmap->blue_max + 1) / CV_DENOM;
+ cvr = X_max_color_value * cr / cmap->red_max;
+ cvg = X_max_color_value * cg / cmap->green_max;
+ cvb = X_max_color_value * cb / cmap->blue_max;
+ if ((iabs((int)r - (int)cvr) & xdev->cman.color_mask.red) == 0 &&
+ (iabs((int)g - (int)cvg) & xdev->cman.color_mask.green) == 0 &&
+ (iabs((int)b - (int)cvb) & xdev->cman.color_mask.blue) == 0) {
+ gx_color_index pixel =
+ cr * cmap->red_mult + cg * cmap->green_mult +
+ cb * cmap->blue_mult + cmap->base_pixel;
+
+ if_debug4('C', "[cX]%u,%u,%u (std cmap) => %lu\n",
+ r, g, b, pixel);
+ return pixel;
+ }
+ if_debug3('C', "[cX]%u,%u,%u (std cmap fails)\n", r, g, b);
+ } else {
+ uint cr;
+ X_color_value cvr;
+
+ cr = r * (cmap->red_max + 1) / CV_DENOM;
+ cvr = X_max_color_value * cr / cmap->red_max;
+ if ((iabs((int)r - (int)cvr) & xdev->cman.color_mask.red) == 0) {
+ gx_color_index pixel = cr * cmap->red_mult + cmap->base_pixel;
+
+ if_debug2('C', "[cX]%u (std cmap) => %lu\n", r, pixel);
+ return pixel;
+ }
+ if_debug1('C', "[cX]%u (std cmap fails)\n", r);
+ }
+ } else
+#endif
+
+ /* If there is no standard colormap, check the dither cube/ramp */
+ if (xdev->cman.dither_ramp) {
+ if (gx_device_has_color(xdev)) {
+ uint cr, cg, cb; /* rgb cube indices */
+ X_color_value cvr, cvg, cvb; /* color value on cube */
+ int dither_rgb = xdev->color_info.dither_colors;
+ uint max_rgb = dither_rgb - 1;
+
+ cr = r * dither_rgb / CV_DENOM;
+ cg = g * dither_rgb / CV_DENOM;
+ cb = b * dither_rgb / CV_DENOM;
+ if (max_rgb < countof(cv_tables)) {
+ const ushort *cv_tab = cv_tables[max_rgb];
+
+ cvr = cv_tab[cr];
+ cvg = cv_tab[cg];
+ cvb = cv_tab[cb];
+ } else {
+ cvr = CV_FRACTION(cr, max_rgb);
+ cvg = CV_FRACTION(cg, max_rgb);
+ cvb = CV_FRACTION(cb, max_rgb);
+ }
+ if ((iabs((int)r - (int)cvr) & xdev->cman.color_mask.red) == 0 &&
+ (iabs((int)g - (int)cvg) & xdev->cman.color_mask.green) == 0 &&
+ (iabs((int)b - (int)cvb) & xdev->cman.color_mask.blue) == 0) {
+ gx_color_index pixel =
+ xdev->cman.dither_ramp[CUBE_INDEX(cr, cg, cb)];
+
+ if_debug4('C', "[cX]%u,%u,%u (dither cube) => %lu\n",
+ r, g, b, pixel);
+ return pixel;
+ }
+ if_debug3('C', "[cX]%u,%u,%u (dither cube fails)\n", r, g, b);
+ } else {
+ uint cr;
+ X_color_value cvr;
+ int dither_grays = xdev->color_info.dither_grays;
+ uint max_gray = dither_grays - 1;
+
+ cr = r * dither_grays / CV_DENOM;
+ cvr = (X_max_color_value * cr / max_gray);
+ if ((iabs((int)r - (int)cvr) & xdev->cman.color_mask.red) == 0) {
+ gx_color_index pixel = xdev->cman.dither_ramp[cr];
+
+ if_debug2('C', "[cX]%u (dither ramp) => %lu\n", r, pixel);
+ return pixel;
+ }
+ if_debug1('C', "[cX]%u (dither ramp fails)\n", r);
+ }
+ }
+
+ /* Finally look through the list of dynamic colors */
+ if (xdev->cman.dynamic.colors) {
+ int i = (dr ^ dg ^ db) >> xdev->cman.dynamic.shift;
+ x11_color_t *xcp = xdev->cman.dynamic.colors[i];
+ x11_color_t *prev = NULL;
+ XColor xc;
+
+ for (; xcp; prev = xcp, xcp = xcp->next)
+ if (xcp->color.red == dr && xcp->color.green == dg &&
+ xcp->color.blue == db) {
+ /* Promote the found entry to the front of the list. */
+ if (prev) {
+ prev->next = xcp->next;
+ xcp->next = xdev->cman.dynamic.colors[i];
+ xdev->cman.dynamic.colors[i] = xcp;
+ }
+ if (xcp->color.pad) {
+ if_debug4('C', "[cX]%u,%u,%u (dynamic) => %lu\n",
+ r, g, b, (ulong) xcp->color.pixel);
+ return xcp->color.pixel;
+ } else {
+ if_debug3('C', "[cX]%u,%u,%u (dynamic) => missing\n",
+ r, g, b);
+ return gx_no_color_index;
+ }
+ }
+
+ /* If not in our list of dynamic colors, */
+ /* ask the X server and add an entry. */
+ /* First check if dynamic table is exhausted */
+ if (xdev->cman.dynamic.used > xdev->cman.dynamic.max_used) {
+ if_debug3('C', "[cX]%u,%u,%u (dynamic) => full\n", r, g, b);
+ return gx_no_color_index;
+ }
+ xcp = (x11_color_t *)
+ gs_malloc(sizeof(x11_color_t), 1, "x11_dynamic_color");
+ if (!xcp)
+ return gx_no_color_index;
+ xc.red = xcp->color.red = dr;
+ xc.green = xcp->color.green = dg;
+ xc.blue = xcp->color.blue = db;
+ xcp->next = xdev->cman.dynamic.colors[i];
+ xdev->cman.dynamic.colors[i] = xcp;
+ xdev->cman.dynamic.used++;
+ if (x_alloc_color(xdev, &xc)) {
+ xcp->color.pixel = xc.pixel;
+ xcp->color.pad = true;
+ if_debug5('c', "[cX]0x%x,0x%x,0x%x (dynamic) => added [%d]%lu\n",
+ dr, dg, db, xdev->cman.dynamic.used - 1,
+ (ulong)xc.pixel);
+ return xc.pixel;
+ } else {
+ xcp->color.pad = false;
+ if_debug3('c', "[cX]0x%x,0x%x,0x%x (dynamic) => can't alloc\n",
+ dr, dg, db);
+ return gx_no_color_index;
+ }
+ }
+ if_debug3('C', "[cX]%u,%u,%u fails\n", r, g, b);
+ return gx_no_color_index;
+#undef CV_DENOM
+}
+
+
+/* Map a pixel value back to r-g-b. */
+int
+gdev_x_map_color_rgb(gx_device * dev, gx_color_index color,
+ gx_color_value prgb[3])
+{
+ const gx_device_X *const xdev = (const gx_device_X *) dev;
+#if HaveStdCMap
+ const XStandardColormap *cmap = xdev->cman.std_cmap;
+#endif
+
+ if (color == xdev->foreground) {
+ prgb[0] = prgb[1] = prgb[2] = 0;
+ return 0;
+ }
+ if (color == xdev->background) {
+ prgb[0] = prgb[1] = prgb[2] = gx_max_color_value;
+ return 0;
+ }
+ if (color < xdev->cman.color_to_rgb.size) {
+ const x11_rgb_t *pxrgb = &xdev->cman.color_to_rgb.values[color];
+
+ if (pxrgb->defined) {
+ prgb[0] = pxrgb->rgb[0];
+ prgb[1] = pxrgb->rgb[1];
+ prgb[2] = pxrgb->rgb[2];
+ return 0;
+ }
+#if HaveStdCMap
+ }
+
+ /* Check the standard colormap. */
+ if (cmap) {
+ if (color >= cmap->base_pixel) {
+ x_pixel value = color - cmap->base_pixel;
+ uint r = (value / cmap->red_mult) % (cmap->red_max + 1);
+ uint g = (value / cmap->green_mult) % (cmap->green_max + 1);
+ uint b = (value / cmap->blue_mult) % (cmap->blue_max + 1);
+
+ if (value == r * cmap->red_mult + g * cmap->green_mult +
+ b * cmap->blue_mult) {
+ /* When mapping color buckets back to specific colors,
+ * we can choose to map them to the darkest shades
+ * (e.g., 0, 1/3, 2/3), to the lightest shades (e.g.,
+ * 1/3-epsilon, 2/3-epsilon, 1-epsilon), to the middle
+ * shades (e.g., 1/6, 1/2, 5/6), or for maximum contrast
+ * (e.g., 0, 1/2, 1). The last of these matches the
+ * assumptions of the halftoning code, so that is what
+ * we choose.
+ */
+ prgb[0] = r * gx_max_color_value / cmap->red_max;
+ prgb[1] = g * gx_max_color_value / cmap->green_max;
+ prgb[2] = b * gx_max_color_value / cmap->blue_max;
+ return 0;
+ }
+ }
+ }
+ if (color < xdev->cman.color_to_rgb.size) {
+#endif
+ /* Error -- undefined pixel value. */
+ return_error(gs_error_unknownerror);
+ }
+ /*
+ * Check the dither cube/ramp. This is hardly ever used, since if
+ * there are few enough colors to require dithering, the pixel values
+ * are likely to be small enough to index color_to_rgb.
+ */
+ if (xdev->cman.dither_ramp) {
+ if (gx_device_has_color(xdev)) {
+ int size = xdev->color_info.dither_colors;
+ int size3 = size * size * size;
+ int i;
+
+ for (i = 0; i < size3; ++i)
+ if (xdev->cman.dither_ramp[i] == color) {
+ uint max_rgb = size - 1;
+ uint q = i / size,
+ r = q / size,
+ g = q % size,
+ b = i % size;
+
+ /*
+ * See above regarding the choice of color mapping
+ * algorithm.
+ */
+ prgb[0] = r * gx_max_color_value / max_rgb;
+ prgb[1] = g * gx_max_color_value / max_rgb;
+ prgb[2] = b * gx_max_color_value / max_rgb;
+ return 0;
+ }
+ } else {
+ int size = xdev->color_info.dither_grays;
+ int i;
+
+ for (i = 0; i < size; ++i)
+ if (xdev->cman.dither_ramp[i] == color) {
+ prgb[0] = prgb[1] = prgb[2] =
+ i * gx_max_color_value / (size - 1);
+ return 0;
+ }
+ }
+ }
+
+ /* Finally, search the list of dynamic colors. */
+ if (xdev->cman.dynamic.colors) {
+ int i;
+ const x11_color_t *xcp;
+
+ for (i = xdev->cman.dynamic.size; --i >= 0;)
+ for (xcp = xdev->cman.dynamic.colors[i]; xcp; xcp = xcp->next)
+ if (xcp->color.pixel == color && xcp->color.pad) {
+ prgb[0] = xcp->color.red;
+ prgb[1] = xcp->color.green;
+ prgb[2] = xcp->color.blue;
+ return 0;
+ }
+ }
+
+ /* Not found -- not possible! */
+ return_error(gs_error_unknownerror);
+}
diff --git a/gs/src/gdevxcmp.h b/gs/src/gdevxcmp.h
new file mode 100644
index 000000000..6d0eb5636
--- /dev/null
+++ b/gs/src/gdevxcmp.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* X driver color mapping structure */
+
+#ifndef gdevxcmp_INCLUDED
+# define gdevxcmp_INCLUDED
+
+/*
+ * The structure defined in this file is used in only one place, in the
+ * gx_device_X structure defined in gdevx.h. We define it as a separate
+ * structure because its function is logically separate from the rest of the
+ * X driver, and because this function (color mapping / management) accounts
+ * for the single largest piece of the driver.
+ */
+
+/* Define pixel value to RGB mapping */
+typedef struct x11_rgb_s {
+ gx_color_value rgb[3];
+ bool defined;
+} x11_rgb_t;
+
+/* Define dynamic color hash table structure */
+typedef struct x11_color_s x11_color_t;
+struct x11_color_s {
+ XColor color;
+ x11_color_t *next;
+};
+
+/*
+ * Define X color values. Fortuitously, these are the same as Ghostscript
+ * color values; in gdevxcmap.c, we are pretty sloppy about aliasing the
+ * two.
+ */
+typedef ushort X_color_value;
+#define X_max_color_value 0xffff
+
+typedef struct x11_cman_s {
+
+ /*
+ * num_rgb is the number of possible R/G/B values, i.e.,
+ * 1 << the bits_per_rgb of the X visual.
+ */
+ int num_rgb;
+
+ /*
+ * color_mask is a mask that selects the high-order N bits of an
+ * X color value, where N may be the mask width for TrueColor or
+ * StaticGray and is bits_per_rgb for the other visual classes.
+ */
+ struct cmm_ {
+ X_color_value red, green, blue;
+ } color_mask;
+
+#if HaveStdCMap /* Standard colormap stuff is only in X11R4 and later. */
+
+ /*
+ * std_cmap is the X standard colormap for the display and screen,
+ * if one is available.
+ */
+
+ XStandardColormap *std_cmap;
+
+ /*
+ * If free_std_cmap is true, we allocated std_cmap ourselves (to
+ * represent a TrueColor or Static Gray visual), and must free it when
+ * closing the device.
+ */
+ bool free_std_cmap;
+
+#endif /* HaveStdCmap */
+
+ /*
+ * color_to_rgb is a reverse map from pixel values to RGB values. It
+ * only maps pixels values up to 255: pixel values above this must go
+ * through the standard colormap or query the server.
+ */
+ struct cmc_ {
+ int size; /* min(1 << depth, 256) */
+ x11_rgb_t *values; /* [color_to_rgb.size] */
+ } color_to_rgb;
+
+ /*
+ * For systems with writable colormaps and no suitable standard
+ * colormap, dither_ramp is a preallocated ramp or cube used for
+ * dithering.
+ */
+#define CUBE_INDEX(r,g,b) (((r) * xdev->color_info.dither_colors + (g)) * \
+ xdev->color_info.dither_colors + (b))
+ x_pixel *dither_ramp; /* [color_info.dither_colors^3] if color,
+ [color_info.dither_grays] if gray */
+
+ /*
+ * For systems with writable colormaps, dynamic.colors is a chained
+ * hash table that maps RGB values (masked with color_mask) to
+ * pixel values. Entries are added dynamically.
+ */
+ struct cmd_ {
+ int size;
+ x11_color_t **colors; /* [size] */
+ int shift; /* 16 - log2(size) */
+ int used;
+ int max_used;
+ } dynamic;
+
+} x11_cman_t;
+
+#endif /* gdevxcmp_INCLUDED */
diff --git a/gs/src/gdevxini.c b/gs/src/gdevxini.c
index abba969ae..abf4132db 100644
--- a/gs/src/gdevxini.c
+++ b/gs/src/gdevxini.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,7 +18,6 @@
/* X Windows driver initialization for Ghostscript library */
-#include "math_.h"
#include "memory_.h"
#include "x_.h"
#include "gx.h"
@@ -28,110 +27,6 @@
extern char *getenv(P1(const char *));
-private XtResource resources[] =
-{
-
-/* (String) casts are here to suppress warnings about discarding `const' */
-#define RINIT(a,b,t,s,o,it,n)\
- {(String)(a), (String)(b), (String)t, sizeof(s),\
- XtOffsetOf(gx_device_X, o), (String)it, (n)}
-#define rpix(a,b,o,n)\
- RINIT(a,b,XtRPixel,Pixel,o,XtRString,(XtPointer)(n))
-#define rdim(a,b,o,n)\
- RINIT(a,b,XtRDimension,Dimension,o,XtRImmediate,(XtPointer)(n))
-#define rstr(a,b,o,n)\
- RINIT(a,b,XtRString,String,o,XtRString,(char*)(n))
-#define rint(a,b,o,n)\
- RINIT(a,b,XtRInt,int,o,XtRImmediate,(XtPointer)(n))
-#define rbool(a,b,o,n)\
- RINIT(a,b,XtRBoolean,Boolean,o,XtRImmediate,(XtPointer)(n))
-#define rfloat(a,b,o,n)\
- RINIT(a,b,XtRFloat,float,o,XtRString,(XtPointer)(n))
-
- rpix(XtNbackground, XtCBackground, background, "XtDefaultBackground"),
- rpix(XtNborderColor, XtCBorderColor, borderColor, "XtDefaultForeground"),
- rdim(XtNborderWidth, XtCBorderWidth, borderWidth, 1),
- rstr("dingbatFonts", "DingbatFonts", dingbatFonts,
- "ZapfDingbats: -Adobe-ITC Zapf Dingbats-Medium-R-Normal--"),
- rpix(XtNforeground, XtCForeground, foreground, "XtDefaultForeground"),
- rstr(XtNgeometry, XtCGeometry, geometry, NULL),
- rbool("logExternalFonts", "LogExternalFonts", logXFonts, False),
- rint("maxGrayRamp", "MaxGrayRamp", maxGrayRamp, 128),
- rint("maxRGBRamp", "MaxRGBRamp", maxRGBRamp, 5),
- rstr("palette", "Palette", palette, "Color"),
-
- /*
- * I had to compress the whitespace out of the default string to
- * satisfy certain balky compilers.
- */
- rstr("regularFonts", "RegularFonts", regularFonts, "\
-AvantGarde-Book:-Adobe-ITC Avant Garde Gothic-Book-R-Normal--\n\
-AvantGarde-BookOblique:-Adobe-ITC Avant Garde Gothic-Book-O-Normal--\n\
-AvantGarde-Demi:-Adobe-ITC Avant Garde Gothic-Demi-R-Normal--\n\
-AvantGarde-DemiOblique:-Adobe-ITC Avant Garde Gothic-Demi-O-Normal--\n\
-Bookman-Demi:-Adobe-ITC Bookman-Demi-R-Normal--\n\
-Bookman-DemiItalic:-Adobe-ITC Bookman-Demi-I-Normal--\n\
-Bookman-Light:-Adobe-ITC Bookman-Light-R-Normal--\n\
-Bookman-LightItalic:-Adobe-ITC Bookman-Light-I-Normal--\n\
-Courier:-Adobe-Courier-Medium-R-Normal--\n\
-Courier-Bold:-Adobe-Courier-Bold-R-Normal--\n\
-Courier-BoldOblique:-Adobe-Courier-Bold-O-Normal--\n\
-Courier-Oblique:-Adobe-Courier-Medium-O-Normal--\n\
-Helvetica:-Adobe-Helvetica-Medium-R-Normal--\n\
-Helvetica-Bold:-Adobe-Helvetica-Bold-R-Normal--\n\
-Helvetica-BoldOblique:-Adobe-Helvetica-Bold-O-Normal--\n\
-Helvetica-Narrow:-Adobe-Helvetica-Medium-R-Narrow--\n\
-Helvetica-Narrow-Bold:-Adobe-Helvetica-Bold-R-Narrow--\n\
-Helvetica-Narrow-BoldOblique:-Adobe-Helvetica-Bold-O-Narrow--\n\
-Helvetica-Narrow-Oblique:-Adobe-Helvetica-Medium-O-Narrow--\n\
-Helvetica-Oblique:-Adobe-Helvetica-Medium-O-Normal--\n\
-NewCenturySchlbk-Bold:-Adobe-New Century Schoolbook-Bold-R-Normal--\n\
-NewCenturySchlbk-BoldItalic:-Adobe-New Century Schoolbook-Bold-I-Normal--\n\
-NewCenturySchlbk-Italic:-Adobe-New Century Schoolbook-Medium-I-Normal--\n\
-NewCenturySchlbk-Roman:-Adobe-New Century Schoolbook-Medium-R-Normal--\n\
-Palatino-Bold:-Adobe-Palatino-Bold-R-Normal--\n\
-Palatino-BoldItalic:-Adobe-Palatino-Bold-I-Normal--\n\
-Palatino-Italic:-Adobe-Palatino-Medium-I-Normal--\n\
-Palatino-Roman:-Adobe-Palatino-Medium-R-Normal--\n\
-Times-Bold:-Adobe-Times-Bold-R-Normal--\n\
-Times-BoldItalic:-Adobe-Times-Bold-I-Normal--\n\
-Times-Italic:-Adobe-Times-Medium-I-Normal--\n\
-Times-Roman:-Adobe-Times-Medium-R-Normal--\n\
-Utopia-Bold:-Adobe-Utopia-Bold-R-Normal--\n\
-Utopia-BoldItalic:-Adobe-Utopia-Bold-I-Normal--\n\
-Utopia-Italic:-Adobe-Utopia-Regular-I-Normal--\n\
-Utopia-Regular:-Adobe-Utopia-Regular-R-Normal--\n\
-ZapfChancery-MediumItalic:-Adobe-ITC Zapf Chancery-Medium-I-Normal--"),
-
- rstr("symbolFonts", "SymbolFonts", symbolFonts,
- "Symbol: -Adobe-Symbol-Medium-R-Normal--"),
-
- rbool("useBackingPixmap", "UseBackingPixmap", useBackingPixmap, True),
- rbool("useExternalFonts", "UseExternalFonts", useXFonts, True),
- rbool("useFontExtensions", "UseFontExtensions", useFontExtensions, True),
- rbool("useScalableFonts", "UseScalableFonts", useScalableFonts, True),
- rbool("useXPutImage", "UseXPutImage", useXPutImage, True),
- rbool("useXSetTile", "UseXSetTile", useXSetTile, True),
- rfloat("xResolution", "Resolution", xResolution, "0.0"),
- rfloat("yResolution", "Resolution", yResolution, "0.0"),
-
-#undef RINIT
-#undef rpix
-#undef rdim
-#undef rstr
-#undef rint
-#undef rbool
-#undef rfloat
-};
-
-private String
- fallback_resources[] =
-{
- (String) "Ghostscript*Background: white",
- (String) "Ghostscript*Foreground: black",
- NULL
-};
-
/* Define constants for orientation from ghostview */
/* Number represents clockwise rotation of the paper in degrees */
typedef enum {
@@ -141,26 +36,32 @@ typedef enum {
Seascape = 270 /* Landscape rotated the wrong way */
} orientation;
-/* Forward references */
-private int gdev_x_setup_colors(P1(gx_device_X *));
+/* Forward/external references */
+int gdev_x_setup_colors(P1(gx_device_X *));
private void gdev_x_setup_fontmap(P1(gx_device_X *));
/* Catch the alloc error when there is not enough resources for the
* backing pixmap. Automatically shut off backing pixmap and let the
* user know when this happens.
+ *
+ * Because the X API was designed without adequate thought to reentrancy,
+ * these variables must be allocated statically. We do not see how this
+ * code can work reliably in the presence of multi-threading.
*/
-private Boolean alloc_error;
-private XErrorHandler orighandler;
-private XErrorHandler oldhandler;
+private struct xv_ {
+ Boolean alloc_error;
+ XErrorHandler orighandler;
+ XErrorHandler oldhandler;
+} x_error_handler;
private int
x_catch_alloc(Display * dpy, XErrorEvent * err)
{
if (err->error_code == BadAlloc)
- alloc_error = True;
- if (alloc_error)
+ x_error_handler.alloc_error = True;
+ if (x_error_handler.alloc_error)
return 0;
- return oldhandler(dpy, err);
+ return x_error_handler.oldhandler(dpy, err);
}
int
@@ -168,7 +69,7 @@ x_catch_free_colors(Display * dpy, XErrorEvent * err)
{
if (err->request_code == X_FreeColors)
return 0;
- return orighandler(dpy, err);
+ return x_error_handler.orighandler(dpy, err);
}
/* Open the X device */
@@ -354,18 +255,19 @@ gdev_x_open(register gx_device_X * xdev)
return_error(gs_error_ioerror);
}
/* Buggy X servers may cause a Bad Access on XFreeColors. */
- orighandler = XSetErrorHandler(x_catch_free_colors);
+ x_error_handler.orighandler = XSetErrorHandler(x_catch_free_colors);
/* Get X Resources. Use the toolkit for this. */
XtToolkitInitialize();
app_con = XtCreateApplicationContext();
- XtAppSetFallbackResources(app_con, fallback_resources);
+ XtAppSetFallbackResources(app_con, gdev_x_fallback_resources);
dpy = XtOpenDisplay(app_con, NULL, "ghostscript", "Ghostscript",
NULL, 0, &zero, NULL);
toplevel = XtAppCreateShell(NULL, "Ghostscript",
applicationShellWidgetClass, dpy, NULL, 0);
XtGetApplicationResources(toplevel, (XtPointer) xdev,
- resources, XtNumber(resources), NULL, 0);
+ gdev_x_resources, gdev_x_resource_count,
+ NULL, 0);
/* Reserve foreground and background colors under the regular connection. */
xc.pixel = xdev->foreground;
@@ -580,14 +482,14 @@ gdev_x_clear_window(gx_device_X * xdev)
{
if (!xdev->ghostview) {
if (xdev->useBackingPixmap) {
- oldhandler = XSetErrorHandler(x_catch_alloc);
- alloc_error = False;
+ x_error_handler.oldhandler = XSetErrorHandler(x_catch_alloc);
+ x_error_handler.alloc_error = False;
xdev->bpixmap =
XCreatePixmap(xdev->dpy, xdev->win,
xdev->width, xdev->height,
xdev->vinfo->depth);
XSync(xdev->dpy, False); /* Force the error */
- if (alloc_error) {
+ if (x_error_handler.alloc_error) {
xdev->useBackingPixmap = False;
#ifdef DEBUG
eprintf("Warning: Failed to allocated backing pixmap.\n");
@@ -598,7 +500,8 @@ gdev_x_clear_window(gx_device_X * xdev)
XSync(xdev->dpy, False); /* Force the error */
}
}
- oldhandler = XSetErrorHandler(oldhandler);
+ x_error_handler.oldhandler =
+ XSetErrorHandler(x_error_handler.oldhandler);
} else
xdev->bpixmap = (Pixmap) 0;
}
@@ -628,291 +531,6 @@ gdev_x_clear_window(gx_device_X * xdev)
xdev->colors_or = xdev->colors_and = xdev->background;
}
-/* ------ Initialize color mapping ------ */
-
-#if HaveStdCMap
-/* Get the Standard colormap if available. */
-private XStandardColormap *
-x_get_std_cmap(gx_device_X * xdev, Atom prop)
-{
- int i;
- XStandardColormap *scmap, *sp;
- int nitems;
-
- if (XGetRGBColormaps(xdev->dpy, RootWindowOfScreen(xdev->scr),
- &scmap, &nitems, prop))
- for (i = 0, sp = scmap; i < nitems; i++, sp++)
- if (xdev->cmap == sp->colormap)
- return sp;
-
- return NULL;
-}
-#endif
-
-/* Allocate the dynamic color table, if needed and possible. */
-private void
-alloc_dynamic_colors(gx_device_X * xdev, int reserved_colors)
-{
- /* Allocate space for dynamic colors hash table */
- xdev->dynamic_colors =
- (x11color * (*)[])gs_malloc(sizeof(x11color *), xdev->num_rgb,
- "x11_dynamic_colors");
-
- if (xdev->dynamic_colors) {
- int i;
-
- xdev->dynamic_size = xdev->num_rgb;
- for (i = 0; i < xdev->num_rgb; i++) {
- (*xdev->dynamic_colors)[i] = NULL;
- }
- xdev->max_dynamic_colors = min(256, xdev->vinfo->colormap_size -
- reserved_colors);
- }
-}
-
-/* Free a partially filled color ramp. */
-private void
-free_ramp(gx_device_X * xdev, int num_used, int size)
-{
- if (num_used - 1 > 0) {
- XFreeColors(xdev->dpy, xdev->cmap,
- xdev->dither_colors + 1,
- num_used - 1, 0);
- }
- gs_free((char *)xdev->dither_colors, sizeof(x_pixel), size,
- "x11_setup_colors");
- xdev->dither_colors = NULL;
-}
-
-/* Allocate and fill in a color cube or ramp. */
-/* Return true if the operation succeeded. */
-private bool
-setup_cube(gx_device_X * xdev, int ramp_size, bool colors)
-{
- int step, num_entries;
- int max_rgb = ramp_size - 1;
- int index;
-
- if (colors) {
- num_entries = ramp_size * ramp_size * ramp_size;
- step = 1; /* all colors */
- } else {
- num_entries = ramp_size;
- step = (ramp_size + 1) * ramp_size + 1; /* gray only */
- }
-
- xdev->dither_colors =
- (x_pixel *) gs_malloc(sizeof(x_pixel), num_entries,
- "gdevx setup_cube");
- if (xdev->dither_colors == NULL)
- return false;
-
- xdev->dither_colors[0] = xdev->foreground;
- xdev->dither_colors[num_entries - 1] = xdev->background;
- for (index = 1; index < num_entries - 1; index++) {
- int rgb_index = index * step;
- int r = rgb_index / (ramp_size * ramp_size);
- int g = (rgb_index / ramp_size) % ramp_size;
- int b = rgb_index % ramp_size;
- XColor xc;
-
- xc.red = (X_max_color_value * r / max_rgb) & xdev->color_mask;
- xc.green = (X_max_color_value * g / max_rgb) & xdev->color_mask;
- xc.blue = (X_max_color_value * b / max_rgb) & xdev->color_mask;
- if (XAllocColor(xdev->dpy, xdev->cmap, &xc)) {
- xdev->dither_colors[index] = xc.pixel;
- } else {
- free_ramp(xdev, index, num_entries);
- return false;
- }
- }
-
- return true;
-}
-
-/* Setup color mapping. */
-private int
-gdev_x_setup_colors(gx_device_X * xdev)
-{
- char palette;
-
- palette = ((xdev->vinfo->class != StaticGray) &&
- (xdev->vinfo->class != GrayScale) ? 'C' : /* Color */
- (xdev->vinfo->colormap_size > 2) ? 'G' : /* GrayScale */
- 'M'); /* MonoChrome */
- if (xdev->ghostview) {
- Atom gv_colors = XInternAtom(xdev->dpy, "GHOSTVIEW_COLORS", False);
- Atom type;
- int format;
- unsigned long nitems, bytes_after;
- char *buf;
-
- /* Delete property if explicit dest is given */
- if (XGetWindowProperty(xdev->dpy, xdev->win, gv_colors, 0,
- 256, (xdev->dest != 0), XA_STRING,
- &type, &format, &nitems, &bytes_after,
- (unsigned char **)&buf) == 0 &&
- type == XA_STRING) {
- nitems = sscanf(buf, "%*s %ld %ld", &(xdev->foreground),
- &(xdev->background));
- if (nitems != 2 || (*buf != 'M' && *buf != 'G' && *buf != 'C')) {
- eprintf("Malformed ghostview color property.\n");
- return_error(gs_error_rangecheck);
- }
- palette = max(palette, *buf);
- }
- } else {
- if (xdev->palette[0] == 'c')
- xdev->palette[0] = 'C';
- else if (xdev->palette[0] == 'g')
- xdev->palette[0] = 'G';
- else if (xdev->palette[0] == 'm')
- xdev->palette[0] = 'M';
- palette = max(palette, xdev->palette[0]);
- }
-
- /* set up color mappings here */
- xdev->color_mask = X_max_color_value -
- (X_max_color_value >> xdev->vinfo->bits_per_rgb);
- xdev->num_rgb = 1 << xdev->vinfo->bits_per_rgb;
-
-#if HaveStdCMap
- xdev->std_cmap = NULL;
-#endif
- xdev->dither_colors = NULL;
- xdev->dynamic_colors = NULL;
- xdev->dynamic_size = 0;
- xdev->dynamic_allocs = 0;
- switch (xdev->vinfo->depth) {
- case 1: case 2: case 4: case 8: case 16: case 24: case 32:
- xdev->color_info.depth = xdev->vinfo->depth;
- break;
- case 15:
- xdev->color_info.depth = 16;
- break;
- default:
- eprintf1("Unsupported X visual depth: %d\n", xdev->vinfo->depth);
- return_error(gs_error_rangecheck);
- }
- if (palette == 'C') {
- xdev->color_info.num_components = 3;
- xdev->color_info.max_gray =
- xdev->color_info.max_color = xdev->num_rgb - 1;
-#if HaveStdCMap
- /* Get a standard color map if available */
- if (xdev->vinfo->visual == DefaultVisualOfScreen(xdev->scr)) {
- xdev->std_cmap = x_get_std_cmap(xdev, XA_RGB_DEFAULT_MAP);
- } else {
- xdev->std_cmap = x_get_std_cmap(xdev, XA_RGB_BEST_MAP);
- }
- if (xdev->std_cmap) {
- xdev->color_info.dither_grays =
- xdev->color_info.dither_colors =
- min(xdev->std_cmap->red_max,
- min(xdev->std_cmap->green_max,
- xdev->std_cmap->blue_max)) + 1;
- } else
-#endif
- /* Otherwise set up a rgb cube of our own */
- /* The color cube is limited to about 1/2 of the available */
- /* colormap, the user specified maxRGBRamp (usually 5), */
- /* or the number of representable colors */
-#define cube(r) (r*r*r)
-#define cbrt(r) pow(r, 1.0/3.0)
- {
- int ramp_size =
- min((int)cbrt((double)xdev->vinfo->colormap_size / 2.0),
- min(xdev->maxRGBRamp, xdev->num_rgb));
-
- while (!xdev->dither_colors && ramp_size >= 2) {
- xdev->color_info.dither_grays =
- xdev->color_info.dither_colors = ramp_size;
- if (!setup_cube(xdev, ramp_size, true)) {
-#ifdef DEBUG
- eprintf3("Warning: failed to allocate %dx%dx%d RGB cube.\n",
- ramp_size, ramp_size, ramp_size);
-#endif
- ramp_size--;
- continue;
- }
- }
-
- if (!xdev->dither_colors) {
- goto grayscale;
- }
- }
-
- /* Allocate the dynamic color table. */
- alloc_dynamic_colors(xdev, cube(xdev->color_info.dither_colors));
-
-#undef cube
-#undef cbrt
- } else if (palette == 'G') {
- grayscale:
- xdev->color_info.num_components = 1;
- xdev->color_info.max_gray = xdev->num_rgb - 1;
-#if HaveStdCMap
- /* Get a standard color map if available */
- xdev->std_cmap = x_get_std_cmap(xdev, XA_RGB_GRAY_MAP);
- if (xdev->std_cmap != 0) {
- xdev->color_info.dither_grays = xdev->std_cmap->red_max +
- xdev->std_cmap->green_max +
- xdev->std_cmap->blue_max + 1;
- } else
-#endif
- /* Otherwise set up a gray ramp of our own */
- /* The gray ramp is limited to about 1/2 of the available */
- /* colormap, the user specified maxGrayRamp (usually 128), */
- /* or the number of representable grays */
- {
- int ramp_size = min(xdev->vinfo->colormap_size / 2,
- min(xdev->maxGrayRamp, xdev->num_rgb));
-
- while (!xdev->dither_colors && ramp_size >= 3) {
- xdev->color_info.dither_grays = ramp_size;
- if (!setup_cube(xdev, ramp_size, false)) {
-#ifdef DEBUG
- eprintf1("Warning: failed to allocate %d level gray ramp.\n",
- ramp_size);
-#endif
- ramp_size /= 2;
- continue;
- }
- }
- if (!xdev->dither_colors) {
- goto monochrome;
- }
- }
-
- /* Allocate the dynamic color table. */
- alloc_dynamic_colors(xdev, xdev->color_info.dither_grays);
-
- } else if (palette == 'M') {
- monochrome:
- xdev->color_info.num_components = 1;
- xdev->color_info.max_gray = 1;
- xdev->color_info.dither_grays = 2;
- } else {
- eprintf1("Unknown palette: %s\n", xdev->palette);
- return_error(gs_error_rangecheck);
- }
- {
- int count = 1 << min(xdev->color_info.depth, 8);
-
- xdev->color_to_rgb_size = count;
- xdev->color_to_rgb =
- (x11_rgb_t *) gs_malloc(sizeof(x11_rgb_t), count, "gdevx color_to_rgb");
- if (xdev->color_to_rgb) {
- int i;
-
- for (i = 0; i < count; ++i)
- xdev->color_to_rgb[i].defined = false;
- } else
- xdev->color_to_rgb_size = 0;
- }
- return 0;
-}
-
/* ------ Initialize font mapping ------ */
/* Extract the PostScript font name from the font map resource. */
@@ -1012,10 +630,10 @@ scan_font_resource(const char *resource, x11fontmap ** pmaps)
}
strncpy(font->x11_name, x11_name, x11_name_len - 1);
font->x11_name[x11_name_len - 1] = '\0';
- font->std_names = NULL;
- font->iso_names = NULL;
- font->std_count = -1;
- font->iso_count = -1;
+ font->std.names = NULL;
+ font->std.count = -1;
+ font->iso.names = NULL;
+ font->iso.count = -1;
font->next = *pmaps;
*pmaps = font;
}
@@ -1026,6 +644,14 @@ scan_font_resource(const char *resource, x11fontmap ** pmaps)
private void
gdev_x_setup_fontmap(gx_device_X * xdev)
{
+ /*
+ * If this device is a copy of another one, the *_fonts lists
+ * might be dangling references. Clear them before scanning.
+ */
+ xdev->regular_fonts = 0;
+ xdev->symbol_fonts = 0;
+ xdev->dingbat_fonts = 0;
+
if (!xdev->useXFonts)
return; /* If no external fonts, don't bother */
diff --git a/gs/src/gdevxres.c b/gs/src/gdevxres.c
new file mode 100644
index 000000000..5e543da83
--- /dev/null
+++ b/gs/src/gdevxres.c
@@ -0,0 +1,138 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* X Windows driver resource tables */
+#include "std.h" /* must precede any file that includes <sys/types.h> */
+#include "x_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gdevx.h"
+
+/*
+ * We segregate these tables into their own file because the definition of
+ * the XtResource structure is botched -- it declares the strings as char *
+ * rather than const char * -- and so compiling the statically initialized
+ * tables with gcc -Wcast-qual produces dozens of bogus warnings.
+ */
+
+XtResource gdev_x_resources[] =
+{
+
+/* (String) casts are here to suppress warnings about discarding `const' */
+#define RINIT(a,b,t,s,o,it,n)\
+ {(String)(a), (String)(b), (String)t, sizeof(s),\
+ XtOffsetOf(gx_device_X, o), (String)it, (n)}
+#define rpix(a,b,o,n)\
+ RINIT(a,b,XtRPixel,Pixel,o,XtRString,(XtPointer)(n))
+#define rdim(a,b,o,n)\
+ RINIT(a,b,XtRDimension,Dimension,o,XtRImmediate,(XtPointer)(n))
+#define rstr(a,b,o,n)\
+ RINIT(a,b,XtRString,String,o,XtRString,(char*)(n))
+#define rint(a,b,o,n)\
+ RINIT(a,b,XtRInt,int,o,XtRImmediate,(XtPointer)(n))
+#define rbool(a,b,o,n)\
+ RINIT(a,b,XtRBoolean,Boolean,o,XtRImmediate,(XtPointer)(n))
+#define rfloat(a,b,o,n)\
+ RINIT(a,b,XtRFloat,float,o,XtRString,(XtPointer)(n))
+
+ rpix(XtNbackground, XtCBackground, background, "XtDefaultBackground"),
+ rpix(XtNborderColor, XtCBorderColor, borderColor, "XtDefaultForeground"),
+ rdim(XtNborderWidth, XtCBorderWidth, borderWidth, 1),
+ rstr("dingbatFonts", "DingbatFonts", dingbatFonts,
+ "ZapfDingbats: -Adobe-ITC Zapf Dingbats-Medium-R-Normal--"),
+ rpix(XtNforeground, XtCForeground, foreground, "XtDefaultForeground"),
+ rstr(XtNgeometry, XtCGeometry, geometry, NULL),
+ rbool("logExternalFonts", "LogExternalFonts", logXFonts, False),
+ rint("maxGrayRamp", "MaxGrayRamp", maxGrayRamp, 128),
+ rint("maxRGBRamp", "MaxRGBRamp", maxRGBRamp, 5),
+ rstr("palette", "Palette", palette, "Color"),
+
+ /*
+ * I had to compress the whitespace out of the default string to
+ * satisfy certain balky compilers.
+ */
+ rstr("regularFonts", "RegularFonts", regularFonts, "\
+AvantGarde-Book:-Adobe-ITC Avant Garde Gothic-Book-R-Normal--\n\
+AvantGarde-BookOblique:-Adobe-ITC Avant Garde Gothic-Book-O-Normal--\n\
+AvantGarde-Demi:-Adobe-ITC Avant Garde Gothic-Demi-R-Normal--\n\
+AvantGarde-DemiOblique:-Adobe-ITC Avant Garde Gothic-Demi-O-Normal--\n\
+Bookman-Demi:-Adobe-ITC Bookman-Demi-R-Normal--\n\
+Bookman-DemiItalic:-Adobe-ITC Bookman-Demi-I-Normal--\n\
+Bookman-Light:-Adobe-ITC Bookman-Light-R-Normal--\n\
+Bookman-LightItalic:-Adobe-ITC Bookman-Light-I-Normal--\n\
+Courier:-Adobe-Courier-Medium-R-Normal--\n\
+Courier-Bold:-Adobe-Courier-Bold-R-Normal--\n\
+Courier-BoldOblique:-Adobe-Courier-Bold-O-Normal--\n\
+Courier-Oblique:-Adobe-Courier-Medium-O-Normal--\n\
+Helvetica:-Adobe-Helvetica-Medium-R-Normal--\n\
+Helvetica-Bold:-Adobe-Helvetica-Bold-R-Normal--\n\
+Helvetica-BoldOblique:-Adobe-Helvetica-Bold-O-Normal--\n\
+Helvetica-Narrow:-Adobe-Helvetica-Medium-R-Narrow--\n\
+Helvetica-Narrow-Bold:-Adobe-Helvetica-Bold-R-Narrow--\n\
+Helvetica-Narrow-BoldOblique:-Adobe-Helvetica-Bold-O-Narrow--\n\
+Helvetica-Narrow-Oblique:-Adobe-Helvetica-Medium-O-Narrow--\n\
+Helvetica-Oblique:-Adobe-Helvetica-Medium-O-Normal--\n\
+NewCenturySchlbk-Bold:-Adobe-New Century Schoolbook-Bold-R-Normal--\n\
+NewCenturySchlbk-BoldItalic:-Adobe-New Century Schoolbook-Bold-I-Normal--\n\
+NewCenturySchlbk-Italic:-Adobe-New Century Schoolbook-Medium-I-Normal--\n\
+NewCenturySchlbk-Roman:-Adobe-New Century Schoolbook-Medium-R-Normal--\n\
+Palatino-Bold:-Adobe-Palatino-Bold-R-Normal--\n\
+Palatino-BoldItalic:-Adobe-Palatino-Bold-I-Normal--\n\
+Palatino-Italic:-Adobe-Palatino-Medium-I-Normal--\n\
+Palatino-Roman:-Adobe-Palatino-Medium-R-Normal--\n\
+Times-Bold:-Adobe-Times-Bold-R-Normal--\n\
+Times-BoldItalic:-Adobe-Times-Bold-I-Normal--\n\
+Times-Italic:-Adobe-Times-Medium-I-Normal--\n\
+Times-Roman:-Adobe-Times-Medium-R-Normal--\n\
+Utopia-Bold:-Adobe-Utopia-Bold-R-Normal--\n\
+Utopia-BoldItalic:-Adobe-Utopia-Bold-I-Normal--\n\
+Utopia-Italic:-Adobe-Utopia-Regular-I-Normal--\n\
+Utopia-Regular:-Adobe-Utopia-Regular-R-Normal--\n\
+ZapfChancery-MediumItalic:-Adobe-ITC Zapf Chancery-Medium-I-Normal--"),
+
+ rstr("symbolFonts", "SymbolFonts", symbolFonts,
+ "Symbol: -Adobe-Symbol-Medium-R-Normal--"),
+
+ rbool("useBackingPixmap", "UseBackingPixmap", useBackingPixmap, True),
+ rbool("useExternalFonts", "UseExternalFonts", useXFonts, True),
+ rbool("useFontExtensions", "UseFontExtensions", useFontExtensions, True),
+ rbool("useScalableFonts", "UseScalableFonts", useScalableFonts, True),
+ rbool("useXPutImage", "UseXPutImage", useXPutImage, True),
+ rbool("useXSetTile", "UseXSetTile", useXSetTile, True),
+ rfloat("xResolution", "Resolution", xResolution, "0.0"),
+ rfloat("yResolution", "Resolution", yResolution, "0.0"),
+
+#undef RINIT
+#undef rpix
+#undef rdim
+#undef rstr
+#undef rint
+#undef rbool
+#undef rfloat
+};
+
+const int gdev_x_resource_count = XtNumber(gdev_x_resources);
+
+String gdev_x_fallback_resources[] =
+{
+ (String) "Ghostscript*Background: white",
+ (String) "Ghostscript*Foreground: black",
+ NULL
+};
diff --git a/gs/src/gdevxxf.c b/gs/src/gdevxxf.c
index 981b1bf6a..675eca66c 100644
--- a/gs/src/gdevxxf.c
+++ b/gs/src/gdevxxf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -75,6 +75,62 @@ struct x_xfont_s {
gs_private_st_dev_ptrs1(st_x_xfont, x_xfont, "x_xfont",
x_xfont_enum_ptrs, x_xfont_reloc_ptrs, xdev);
+/* ---------------- Utilities ---------------- */
+
+/* Search one set of font maps for a font with a given name. */
+private x11fontmap *
+find_fontmap(x11fontmap *fmps, const byte *fname, uint len)
+{
+ x11fontmap *fmp = fmps;
+
+ while (fmp) {
+ if (len == strlen(fmp->ps_name) &&
+ strncmp(fmp->ps_name, (const char *)fname, len) == 0)
+ break;
+ fmp = fmp->next;
+ }
+ return fmp;
+}
+
+/* Find an X font with a given name, encoding, and size. */
+private char *
+find_x_font(gx_device_X *xdev, char x11template[256], x11fontmap *fmp,
+ const char *encoding_name, x11fontlist *fls, int xheight,
+ bool *scalable_font)
+{
+ int i;
+ char *x11fontname = 0;
+ int len1 = strlen(fmp->x11_name) + 1;
+
+ if (fls->count == -1) {
+ sprintf(x11template, "%s-*-*-*-*-*-*-%s", fmp->x11_name,
+ encoding_name);
+ fls->names = XListFonts(xdev->dpy, x11template, 32, &fls->count);
+ }
+ *scalable_font = false;
+ for (i = 0; i < fls->count; i++) {
+ const char *szp = fls->names[i] + len1;
+ int size = 0;
+
+ while (*szp >= '0' && *szp <= '9')
+ size = size * 10 + *szp++ - '0';
+ if (size == 0) {
+ *scalable_font = true;
+ continue;
+ }
+ if (size == xheight)
+ return fls->names[i];
+ }
+ if (*scalable_font && xdev->useScalableFonts) {
+ sprintf(x11template, "%s-%d-0-0-0-*-0-%s", fmp->x11_name,
+ xheight, encoding_name);
+ x11fontname = x11template;
+ }
+ return x11fontname;
+}
+
+/* ---------------- xfont procedures ---------------- */
+
/* Look up a font. */
private gx_xfont *
x_lookup_font(gx_device * dev, const byte * fname, uint len,
@@ -87,12 +143,10 @@ x_lookup_font(gx_device * dev, const byte * fname, uint len,
char *x11fontname = NULL;
XFontStruct *x11font;
x11fontmap *fmp;
- int i;
double height;
- int size;
int xwidth, xheight, angle;
Boolean My;
- Boolean scalable_font = False;
+ bool scalable_font;
if (!xdev->useXFonts)
return NULL;
@@ -101,19 +155,13 @@ x_lookup_font(gx_device * dev, const byte * fname, uint len,
xwidth = fabs(pmat->xx * 1000) + 0.5;
xheight = fabs(pmat->yy * 1000) + 0.5;
height = fabs(pmat->yy * 1000);
- if (pmat->xx > 0)
- angle = 0;
- else
- angle = 180;
+ angle = (pmat->xx > 0 ? 0 : 180);
My = (pmat->xx > 0 && pmat->yy > 0) || (pmat->xx < 0 && pmat->yy < 0);
} else if (pmat->xx == 0 && pmat->yy == 0) {
xwidth = fabs(pmat->xy * 1000) + 0.5;
xheight = fabs(pmat->yx * 1000) + 0.5;
height = fabs(pmat->yx * 1000);
- if (pmat->yx < 0)
- angle = 90;
- else
- angle = 270;
+ angle = (pmat->yx < 0 ? 90 : 270);
My = (pmat->yx > 0 && pmat->xy < 0) || (pmat->yx < 0 && pmat->xy > 0);
} else {
return NULL;
@@ -132,150 +180,59 @@ x_lookup_font(gx_device * dev, const byte * fname, uint len,
if (!xdev->useFontExtensions && (My || angle != 0))
return NULL;
- if (encoding_index == 0 || encoding_index == 1) {
- int tried_other_encoding = 0;
-
- fmp = xdev->regular_fonts;
- while (fmp) {
- if (len == strlen(fmp->ps_name) &&
- strncmp(fmp->ps_name, (const char *)fname, len) == 0)
- break;
- fmp = fmp->next;
- }
+ switch (encoding_index) {
+ case 0:
+ fmp = find_fontmap(xdev->regular_fonts, fname, len);
if (fmp == NULL)
return NULL;
- while (True) {
- if (encoding_index == 0) {
- if (fmp->std_count == -1) {
- sprintf(x11template, "%s%s", fmp->x11_name,
- "-*-*-*-*-*-*-Adobe-fontspecific");
- fmp->std_names = XListFonts(xdev->dpy, x11template, 32,
- &fmp->std_count);
- }
- if (fmp->std_count) {
- for (i = 0; i < fmp->std_count; i++) {
- char *szp = fmp->std_names[i] + strlen(fmp->x11_name) + 1;
-
- size = 0;
- while (*szp >= '0' && *szp <= '9')
- size = size * 10 + *szp++ - '0';
- if (size == 0) {
- scalable_font = True;
- continue;
- }
- if (size == xheight) {
- x11fontname = fmp->std_names[i];
- break;
- }
- }
- if (!x11fontname && scalable_font &&
- xdev->useScalableFonts) {
- sprintf(x11template, "%s-%d%s", fmp->x11_name,
- xheight, "-0-0-0-*-0-Adobe-fontspecific");
- x11fontname = x11template;
- }
- if (x11fontname)
- break;
- }
- if (tried_other_encoding)
- return NULL;
- encoding_index = 1;
- tried_other_encoding = 1;
- } else if (encoding_index == 1) {
- if (fmp->iso_count == -1) {
- sprintf(x11template, "%s%s", fmp->x11_name,
- "-*-*-*-*-*-*-ISO8859-1");
- fmp->iso_names = XListFonts(xdev->dpy, x11template, 32,
- &fmp->iso_count);
- }
- if (fmp->iso_count) {
- for (i = 0; i < fmp->iso_count; i++) {
- char *szp = fmp->iso_names[i] + strlen(fmp->x11_name) + 1;
-
- size = 0;
- while (*szp >= '0' && *szp <= '9')
- size = size * 10 + *szp++ - '0';
- if (size == 0) {
- scalable_font = True;
- continue;
- }
- if (size == xheight) {
- x11fontname = fmp->iso_names[i];
- break;
- }
- }
- if (!x11fontname && scalable_font &&
- xdev->useScalableFonts) {
- sprintf(x11template, "%s-%d%s", fmp->x11_name,
- xheight, "-0-0-0-*-0-ISO8859-1");
- x11fontname = x11template;
- }
- if (x11fontname)
- break;
- }
- if (tried_other_encoding)
- return NULL;
- encoding_index = 0;
- tried_other_encoding = 1;
- }
- }
- } else if (encoding_index == 2 || encoding_index == 3) {
- if (encoding_index == 2)
- fmp = xdev->symbol_fonts;
- if (encoding_index == 3)
- fmp = xdev->dingbat_fonts;
- while (fmp) {
- if (len == strlen(fmp->ps_name) &&
- strncmp(fmp->ps_name, (const char *)fname, len) == 0)
- break;
- fmp = fmp->next;
+ x11fontname =
+ find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
+ &fmp->std, xheight, &scalable_font);
+ if (!x11fontname) {
+ x11fontname =
+ find_x_font(xdev, x11template, fmp, "ISO8859-1",
+ &fmp->iso, xheight, &scalable_font);
+ encoding_index = 1;
}
+ break;
+ case 1:
+ fmp = find_fontmap(xdev->regular_fonts, fname, len);
if (fmp == NULL)
return NULL;
- if (fmp->std_count == -1) {
- sprintf(x11template, "%s%s", fmp->x11_name,
- "-*-*-*-*-*-*-Adobe-fontspecific");
- fmp->std_names = XListFonts(xdev->dpy, x11template, 32,
- &fmp->std_count);
+ x11fontname =
+ find_x_font(xdev, x11template, fmp, "ISO8859-1",
+ &fmp->iso, xheight, &scalable_font);
+ if (!x11fontname) {
+ x11fontname =
+ find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
+ &fmp->std, xheight, &scalable_font);
+ encoding_index = 0;
}
- if (fmp->std_count) {
- for (i = 0; i < fmp->std_count; i++) {
- char *szp = fmp->std_names[i] + strlen(fmp->x11_name) + 1;
-
- size = 0;
- while (*szp >= '0' && *szp <= '9')
- size = size * 10 + *szp++ - '0';
- if (size == 0) {
- scalable_font = True;
- continue;
- }
- if (size == xheight) {
- x11fontname = fmp->std_names[i];
- break;
- }
- }
- if (!x11fontname && scalable_font && xdev->useScalableFonts) {
- sprintf(x11template, "%s-%d%s", fmp->x11_name, xheight,
- "-0-0-0-*-0-Adobe-fontspecific");
- x11fontname = x11template;
- }
- if (!x11fontname)
- return NULL;
- } else {
+ break;
+ case 2:
+ fmp = xdev->symbol_fonts;
+ goto sym;
+ case 3:
+ fmp = xdev->dingbat_fonts;
+sym: fmp = find_fontmap(fmp, fname, len);
+ if (fmp == NULL)
return NULL;
- }
- } else {
+ x11fontname =
+ find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
+ &fmp->std, xheight, &scalable_font);
+ default:
return NULL;
}
+ if (!x11fontname)
+ return NULL;
if (xwidth != xheight || angle != 0 || My) {
if (!xdev->useScalableFonts || !scalable_font)
return NULL;
- sprintf(x11template, "%s%s+%d-%d+%d%s",
- fmp->x11_name, My ? "+My" : "",
+ sprintf(x11template, "%s%s+%d-%d+%d-0-0-0-*-0-%s",
+ fmp->x11_name, (My ? "+My" : ""),
angle * 64, xheight, xwidth,
- encoding_index == 1 ? "-0-0-0-*-0-ISO8859-1" :
- "-0-0-0-*-0-Adobe-fontspecific");
+ (encoding_index == 1 ? "ISO8859-1" : "Adobe-fontspecific"));
x11fontname = x11template;
}
x11font = XLoadQueryFont(xdev->dpy, x11fontname);
@@ -293,7 +250,7 @@ x_lookup_font(gx_device * dev, const byte * fname, uint len,
xxf->xdev = xdev;
xxf->font = x11font;
xxf->encoding_index = encoding_index;
- xxf->My = My ? -1 : 1;
+ xxf->My = (My ? -1 : 1);
xxf->angle = angle;
if (xdev->logXFonts) {
fprintf(stdout, "Using %s\n", x11fontname);
@@ -308,7 +265,7 @@ private gx_xglyph
x_char_xglyph(gx_xfont * xf, gs_char chr, int encoding_index,
gs_glyph glyph, gs_proc_glyph_name_t glyph_name_proc)
{
- x_xfont *xxf = (x_xfont *) xf;
+ const x_xfont *xxf = (x_xfont *) xf;
if (chr == gs_no_char)
return gx_no_xglyph; /* can't look up names yet */
@@ -327,7 +284,7 @@ x_char_xglyph(gx_xfont * xf, gs_char chr, int encoding_index,
return gx_no_xglyph;
if (xxf->font->per_char) {
int i = chr - xxf->font->min_char_or_byte2;
- XCharStruct *xc = &(xxf->font->per_char[i]);
+ const XCharStruct *xc = &xxf->font->per_char[i];
if ((xc->lbearing == 0) && (xc->rbearing == 0) &&
(xc->ascent == 0) && (xc->descent == 0))
@@ -341,48 +298,36 @@ private int
x_char_metrics(gx_xfont * xf, gx_xglyph xg, int wmode,
gs_point * pwidth, gs_int_rect * pbbox)
{
- x_xfont *xxf = (x_xfont *) xf;
+ const x_xfont *xxf = (const x_xfont *) xf;
+ int width;
if (wmode != 0)
return gs_error_undefined;
if (xxf->font->per_char == NULL) {
- if (xxf->angle == 0) {
- pwidth->x = xxf->font->max_bounds.width;
- pwidth->y = 0;
- } else if (xxf->angle == 90) {
- pwidth->x = 0;
- pwidth->y = -xxf->My * xxf->font->max_bounds.width;
- } else if (xxf->angle == 180) {
- pwidth->x = -xxf->font->max_bounds.width;
- pwidth->y = 0;
- } else if (xxf->angle == 270) {
- pwidth->x = 0;
- pwidth->y = xxf->My * xxf->font->max_bounds.width;
- }
+ width = xxf->font->max_bounds.width;
pbbox->p.x = xxf->font->max_bounds.lbearing;
pbbox->q.x = xxf->font->max_bounds.rbearing;
pbbox->p.y = -xxf->font->max_bounds.ascent;
pbbox->q.y = xxf->font->max_bounds.descent;
} else {
int i = xg - xxf->font->min_char_or_byte2;
+ const XCharStruct *xc = &xxf->font->per_char[i];
- if (xxf->angle == 0) {
- pwidth->x = xxf->font->per_char[i].width;
- pwidth->y = 0;
- } else if (xxf->angle == 90) {
- pwidth->x = 0;
- pwidth->y = -xxf->My * xxf->font->per_char[i].width;
- } else if (xxf->angle == 180) {
- pwidth->x = -xxf->font->per_char[i].width;
- pwidth->y = 0;
- } else if (xxf->angle == 270) {
- pwidth->x = 0;
- pwidth->y = xxf->My * xxf->font->per_char[i].width;
- }
- pbbox->p.x = xxf->font->per_char[i].lbearing;
- pbbox->q.x = xxf->font->per_char[i].rbearing;
- pbbox->p.y = -xxf->font->per_char[i].ascent;
- pbbox->q.y = xxf->font->per_char[i].descent;
+ width = xc->width;
+ pbbox->p.x = xc->lbearing;
+ pbbox->q.x = xc->rbearing;
+ pbbox->p.y = -xc->ascent;
+ pbbox->q.y = xc->descent;
+ }
+ switch (xxf->angle) {
+ case 0:
+ pwidth->x = width, pwidth->y = 0; break;
+ case 90:
+ pwidth->x = 0, pwidth->y = -xxf->My * width; break;
+ case 180:
+ pwidth->x = -width, pwidth->y = 0; break;
+ case 270:
+ pwidth->x = 0, pwidth->y = xxf->My * width; break;
}
return 0;
}
@@ -474,7 +419,7 @@ x_render_char(gx_xfont * xf, gx_xglyph xg, gx_device * dev,
return code;
w = bbox.q.x - bbox.p.x;
h = bbox.q.y - bbox.p.y;
- wbm = round_up(w, align_bitmap_mod * 8);
+ wbm = ROUND_UP(w, align_bitmap_mod * 8);
raster = wbm >> 3;
bits = (byte *) gs_malloc(h, raster, "x_render_char");
if (bits == 0)
diff --git a/gs/src/genarch.c b/gs/src/genarch.c
index 55f5d439c..b6aadb52a 100644
--- a/gs/src/genarch.c
+++ b/gs/src/genarch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,24 +21,57 @@
/* reflecting the machine architecture and compiler characteristics. */
#include "stdpre.h"
+#include <ctype.h>
#include <stdio.h>
+#include <time.h>
/* 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)
+section(FILE * f, const char *str)
{
fprintf(f, "\n\t /* ---------------- %s ---------------- */\n\n", str);
}
+private clock_t
+time_clear(char *buf, int bsize, int nreps)
+{
+ clock_t t = clock();
+ int i;
+
+ for (i = 0; i < nreps; ++i)
+ memset(buf, 0, bsize);
+ return clock() - t;
+}
+
+private void
+define(FILE *f, const char *str)
+{
+ char upstr[50];
+ int i, c;
+
+ for (i = 0; (c = str[i]) != 0; ++i)
+ upstr[i] = toupper(str[i]);
+ upstr[i] = 0;
+ fprintf(f, "#define %s ", upstr);
+}
+
+private void
+define_int(FILE *f, const char *str, int value)
+{
+ define(f, str);
+ fprintf(f, "%d\n", value);
+}
+
+const char ff_str[] = "ffffffffffffffff"; /* 8 bytes */
+
int
main(int argc, char *argv[])
{
char *fname = argv[1];
long one = 1;
- char *ffs = "ffffffffffffffff"; /* 8 bytes */
- int ffs_strlen = strlen(ffs);
+ int ff_strlen = sizeof(ff_str) - 1;
struct {
char c;
short s;
@@ -81,6 +114,7 @@ main(int argc, char *argv[])
int i;
long l;
} f0 , f1, fm1;
+ int floats_are_IEEE;
FILE *f = fopen(fname, "w");
if (f == NULL) {
@@ -88,54 +122,134 @@ main(int argc, char *argv[])
return exit_FAILED;
}
fprintf(f, "/* Parameters derived from machine and compiler architecture */\n");
+ /* We have to test the size dynamically here, */
+ /* because the preprocessor can't evaluate sizeof. */
+ f0.f = 0.0, f1.f = 1.0, fm1.f = -1.0;
+ floats_are_IEEE =
+ (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);
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));
+ define_int(f, "arch_align_short_mod", OFFSET_IN(ss, s));
+ define_int(f, "arch_align_int_mod", OFFSET_IN(si, i));
+ define_int(f, "arch_align_long_mod", OFFSET_IN(sl, l));
+ define_int(f, "arch_align_ptr_mod", OFFSET_IN(sp, p));
+ define_int(f, "arch_align_float_mod", OFFSET_IN(sf, f));
+ define_int(f, "arch_align_double_mod", 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));
+ define_int(f, "arch_log2_sizeof_short", log2s[size_of(short)]);
+ define_int(f, "arch_log2_sizeof_int", log2s[size_of(int)]);
+ define_int(f, "arch_log2_sizeof_long", log2s[size_of(long)]);
+ define_int(f, "arch_sizeof_ptr", size_of(char *));
+ define_int(f, "arch_sizeof_float", size_of(float));
+ define_int(f, "arch_sizeof_double", size_of(double));
+ if (floats_are_IEEE) {
+ define_int(f, "arch_float_mantissa_bits", 24);
+ define_int(f, "arch_double_mantissa_bits", 53);
+ } else {
+ /*
+ * There isn't any general way to compute the number of mantissa
+ * bits accurately, especially if the machine uses hex rather
+ * than binary exponents. Use conservative values, assuming
+ * the exponent is stored in a 16-bit word of its own.
+ */
+ define_int(f, "arch_float_mantissa_bits", sizeof(float) * 8 - 17);
+ define_int(f, "arch_double_mantissa_bits", sizeof(double) * 8 - 17);
+ }
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");
+ define(f, str);\
+ fprintf(f, "((%s)0x%s%s + (%s)0)\n",\
+ tstr, ff_str + ff_strlen - size_of(typ) * 2, l, tstr)
+ PRINT_MAX("arch_max_uchar", unsigned char, "unsigned char", "");
+ PRINT_MAX("arch_max_ushort", unsigned short, "unsigned short", "");
+ /*
+ * For uint and ulong, a different approach is required to keep gcc
+ * with -Wtraditional from spewing out pointless warnings.
+ */
+ define(f, "arch_max_uint");
+ fprintf(f, "((unsigned int)~0 + (unsigned int)0)\n");
+ define(f, "arch_max_ulong");
+ fprintf(f, "((unsigned long)~0L + (unsigned long)0)\n");
#undef PRINT_MAX
+ section(f, "Cache sizes");
+
+ /*
+ * Determine the primary and secondary cache sizes by looking for a
+ * non-linearity in the time required to fill blocks with memset.
+ */
+ {
+#define MAX_BLOCK (1 << 20)
+ static char buf[MAX_BLOCK];
+ int bsize = 1 << 10;
+ int nreps = 1;
+ clock_t t = 0;
+ clock_t t_eps;
+
+ /*
+ * Increase the number of repetitions until the time is
+ * long enough to exceed the likely uncertainty.
+ */
+
+ while ((t = time_clear(buf, bsize, nreps)) == 0)
+ nreps <<= 1;
+ t_eps = t;
+ while ((t = time_clear(buf, bsize, nreps)) < t_eps * 10)
+ nreps <<= 1;
+
+ /*
+ * Increase the block size until the time jumps non-linearly.
+ */
+ for (; bsize <= MAX_BLOCK;) {
+ clock_t dt = time_clear(buf, bsize, nreps);
+
+ if (dt > t + (t >> 1)) {
+ t = dt;
+ break;
+ }
+ bsize <<= 1;
+ nreps >>= 1;
+ if (nreps == 0)
+ nreps = 1, t <<= 1;
+ }
+ define_int(f, "arch_cache1_size", bsize >> 1);
+ /*
+ * Do the same thing a second time for the secondary cache.
+ */
+ if (nreps > 1)
+ nreps >>= 1, t >>= 1;
+ for (; bsize <= MAX_BLOCK;) {
+ clock_t dt = time_clear(buf, bsize, nreps);
+
+ if (dt > t * 1.25) {
+ t = dt;
+ break;
+ }
+ bsize <<= 1;
+ nreps >>= 1;
+ if (nreps == 0)
+ nreps = 1, t <<= 1;
+ }
+ define_int(f, "arch_cache2_size", bsize >> 1);
+ }
+
section(f, "Miscellaneous");
- fprintf(f, "#define arch_is_big_endian %d\n", 1 - *(char *)&one);
+ define_int(f, "arch_is_big_endian", 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));
+ define_int(f, "arch_ptrs_are_signed", (pl1.p < pl0.p));
+ define_int(f, "arch_floats_are_IEEE", (floats_are_IEEE ? 1 : 0));
/* There are three cases for arithmetic right shift: */
/* always correct, correct except for right-shifting a long by 1 */
@@ -144,11 +258,10 @@ main(int argc, char *argv[])
ars = (lr2 != -1 || ir1 != -1 || ir2 != -1 ? 0 :
lr1 != -1 ? 1 : /* Turbo C problem */
2);
- fprintf(f, "#define arch_arith_rshift %d\n", ars);
+ define_int(f, "arch_arith_rshift", 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);
+ define_int(f, "arch_can_shift_full_long", um1 >> lwidth == 0);
/* ---------------- Done. ---------------- */
diff --git a/gs/src/genconf.c b/gs/src/genconf.c
index 5c0aa802f..f6f1125e7 100644
--- a/gs/src/genconf.c
+++ b/gs/src/genconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,8 +25,11 @@
#include <stdlib.h> /* for calloc */
#include <string.h>
-/* We would like to use the real realloc, but it doesn't work on all systems */
-/* (e.g., some Linux versions). */
+/*
+ * We would like to use the real realloc, but it doesn't work on all systems
+ * (e.g., some Linux versions). Also, this procedure does the right thing
+ * if old_ptr = NULL.
+ */
void *
mrealloc(void *old_ptr, size_t old_size, size_t new_size)
{
@@ -36,31 +39,26 @@ mrealloc(void *old_ptr, size_t old_size, size_t new_size)
return NULL;
/* We have to pass in the old size, since we have no way to */
/* determine it otherwise. */
- memcpy(new_ptr, old_ptr, min(old_size, new_size));
+ if (old_ptr)
+ memcpy(new_ptr, old_ptr, min(old_size, new_size));
return new_ptr;
}
/*
* This program generates a set of configuration files.
- * Almost everything it does could be done by a shell program, except that
- * (1) Unix shells are not compatible from one system to another,
- * (2) the DOS shell is not equal to the task,
- * (3) the VMS shell is radically different from all others.
- *
* Usage:
* genconf [-Z] [-e escapechar] [-n [name_prefix | -]] [@]xxx.dev*
* [-f gconfigf.h] [-h gconfig.h]
* [-p[l|L][u][e] pattern] [-l|o|lo|ol out.tr]
* The default escape character is &. When this character appears in the
* pattern, it acts as follows:
- * &p produces a %;
- * &s produces a space;
+ * &p produces a %;
+ * &s produces a space;
* && (i.e., the escape character twice) produces a \;
- * &- produces a -;
- * &x, for any other character x, is an error.
+ * &- produces a -;
+ * &x, for any other character x, is an error.
*/
-/* DEFAULT_NAME_PREFIX should be DEFAULT_NAME_PREFIX. */
#define DEFAULT_NAME_PREFIX "gs_"
#define MAX_STR 120
@@ -105,14 +103,14 @@ typedef struct config_s {
/* Real resources */
union ru_ {
struct nu_ {
+ string_list sorted_resources;
+#define c_sorted_resources lists.named.sorted_resources
string_list resources;
#define c_resources lists.named.resources
string_list devs; /* also includes devs2 */
#define c_devs lists.named.devs
string_list fonts;
#define c_fonts lists.named.fonts
- string_list headers;
-#define c_headers lists.named.headers
string_list libs;
#define c_libs lists.named.libs
string_list libpaths;
@@ -142,10 +140,9 @@ static const config init_config =
static const string_list init_config_lists[] =
{
{"resource", 100, uniq_first},
+ {"sorted_resource", 20, uniq_first},
{"-dev", 100, uniq_first},
- {"-dev2", 100, uniq_first},
{"-font", 50, uniq_first},
- {"-header", 20, uniq_first},
{"-lib", 20, uniq_last},
{"-libpath", 10, uniq_first},
{"-obj", 500, uniq_first}
@@ -153,20 +150,24 @@ static const string_list init_config_lists[] =
/* Forward definitions */
int alloc_list(P1(string_list *));
+void dev_file_name(P1(char *));
int process_replaces(P1(config *));
int read_dev(P2(config *, const char *));
int read_token(P3(char *, int, const char **));
int add_entry(P4(config *, char *, const char *, int));
string_item *add_item(P3(string_list *, const char *, int));
-void sort_uniq(P1(string_list *));
+void sort_uniq(P2(string_list *, bool));
void write_list(P3(FILE *, const string_list *, const char *));
void write_list_pattern(P3(FILE *, const string_list *, const string_pattern *));
+bool var_expand(P3(char *, char [MAX_STR], const config *));
+void add_definition(P4(const char *, const char *, string_list *, bool));
+string_item *lookup(P2(const char *, const string_list *));
main(int argc, char *argv[])
{
config conf;
- int i;
char escape = '&';
+ int i;
/* Allocate string lists. */
conf = init_config;
@@ -206,10 +207,10 @@ main(int argc, char *argv[])
(argv[i + 1][0] == '-' ? "" : argv[i + 1]);
++i;
continue;
- case 'e':
- escape = argv[i + 1][0];
- ++i;
- continue;
+ case 'e':
+ escape = argv[i + 1][0];
+ ++i;
+ continue;
case 'n':
conf.name_prefix =
(argv[i + 1][0] == '-' ? "" : argv[i + 1]);
@@ -243,22 +244,14 @@ main(int argc, char *argv[])
if (p[-1] == escape)
switch (*q) {
case 'p':
- p[-1] = '%';
- q++;
- break;
+ p[-1] = '%'; q++; break;
case 's':
- p[-1] = ' ';
- q++;
- break;
+ p[-1] = ' '; q++; break;
case '-':
- p[-1] = '-';
- q++;
- break;
+ p[-1] = '-'; q++; break;
default:
- if (*q == escape ) {
- p[-1] = '\\';
- q++;
- break;
+ if (*q == escape) {
+ p[-1] = '\\'; q++; break;
}
fprintf(stderr,
"%c not followed by p|s|%c|-: &%c\n",
@@ -318,9 +311,10 @@ main(int argc, char *argv[])
process_replaces(&conf);
fputs("/* This file was generated automatically by genconf.c. */\n", out);
write_list(out, &conf.c_devs, "%s\n");
- sort_uniq(&conf.c_resources);
+ sort_uniq(&conf.c_resources, true);
write_list(out, &conf.c_resources, "%s\n");
- write_list(out, &conf.c_headers, "#include \"%s\"\n");
+ sort_uniq(&conf.c_sorted_resources, false);
+ write_list(out, &conf.c_sorted_resources, "%s\n");
break;
case 'l':
lib = 1;
@@ -331,11 +325,11 @@ main(int argc, char *argv[])
lib = arg[2] == 'l';
lo:process_replaces(&conf);
if (obj) {
- sort_uniq(&conf.c_objs);
+ sort_uniq(&conf.c_objs, true);
write_list_pattern(out, &conf.c_objs, &conf.obj_p);
}
if (lib) {
- sort_uniq(&conf.c_libs);
+ sort_uniq(&conf.c_libs, true);
write_list_pattern(out, &conf.c_libpaths, &conf.libpath_p);
write_list_pattern(out, &conf.c_libs, &conf.lib_p);
}
@@ -362,6 +356,16 @@ alloc_list(string_list * list)
return 0;
}
+/* If necessary, convert a .dev name to its file name. */
+void
+dev_file_name(char *str)
+{
+ int len = strlen(str);
+
+ if (len <= 4 || strcmp(".dev", str + len - 4))
+ strcat(str, ".dev");
+}
+
/* Delete any files that are named as -replace "resources". */
int
process_replaces(config * pconf)
@@ -370,20 +374,17 @@ process_replaces(config * pconf)
int i;
for (i = 0; i < pconf->replaces.count; ++i) {
- int len;
int j;
strcpy(bufname, pconf->replaces.items[i].str);
/* See if the file being replaced was included. */
- len = strlen(bufname);
- if (len < 5 || strcmp(bufname + len - 4, ".dev"))
- strcat(bufname, ".dev");
+ dev_file_name(bufname);
for (j = 0; j < pconf->file_names.count; ++j) {
const char *fname = pconf->file_names.items[j].str;
if (!strcmp(fname, bufname)) {
if (pconf->debug)
- printf("Deleting file %s.\n", fname);
+ printf("Replacing file %s.\n", fname);
/* Delete all resources associated with this file. */
{
int rn;
@@ -398,7 +399,7 @@ process_replaces(config * pconf)
/* Delete the item. Since we haven't sorted the items */
/* yet, just replace this item with the last one. */
if (pconf->debug)
- printf("Deleting %s %s.\n",
+ printf("Replacing %s %s.\n",
pconf->lists.indexed[rn].list_name,
items[tn].str);
items[tn] = items[--count];
@@ -481,9 +482,9 @@ read_dev(config * pconf, const char *arg)
string_item *item;
const char *in;
-#define max_token 256
- char *token = malloc(max_token + 1);
- char *category = malloc(max_token + 1);
+#define MAX_TOKEN 256
+ char *token = malloc(MAX_TOKEN + 1);
+ char *category = malloc(MAX_TOKEN + 1);
int file_index;
int len;
@@ -498,10 +499,10 @@ read_dev(config * pconf, const char *arg)
in = item->str;
file_index = item - pconf->file_contents.items;
strcpy(category, "obj");
- while ((len = read_token(token, max_token, &in)) > 0)
+ while ((len = read_token(token, MAX_TOKEN, &in)) > 0)
item->index |= add_entry(pconf, category, token, file_index);
free(category);
-#undef max_token
+#undef MAX_TOKEN
if (len < 0) {
fprintf(stderr, "Token too long: %s.\n", token);
exit(1);
@@ -555,20 +556,20 @@ add_entry(config * pconf, char *category, const char *item, int file_index)
printf("Adding %s %s;\n", category, item);
/* Handle a few resources specially; just queue the rest. */
switch (category[0]) {
-#define is_cat(str) !strcmp(category, str)
+#define IS_CAT(str) !strcmp(category, str)
case 'd':
- if (is_cat("dev"))
+ if (IS_CAT("dev"))
pat = "device_(%s%%s_device)";
- else if (is_cat("dev2"))
+ else if (IS_CAT("dev2"))
pat = "device2_(%s%%s_device)";
else
goto err;
- sprintf(template, pat, pconf->name_prefix);
- pat = template;
list = &pconf->c_devs;
+pre: sprintf(template, pat, pconf->name_prefix);
+ pat = template;
break;
case 'e':
- if (is_cat("emulator")) {
+ if (IS_CAT("emulator")) {
sprintf(str, "emulator_(\"%s\",%d)",
item, strlen(item));
item = str;
@@ -576,61 +577,62 @@ add_entry(config * pconf, char *category, const char *item, int file_index)
}
goto err;
case 'f':
- if (is_cat("font")) {
+ if (IS_CAT("font")) {
list = &pconf->c_fonts;
break;
- }
- goto err;
+ } else if (IS_CAT("functiontype")) {
+ pat = "function_type_(%%s,%sbuild_function_%%s)";
+ } else
+ goto err;
+ goto pre;
case 'h':
- if (is_cat("header")) {
- list = &pconf->c_headers;
- break;
- }
- goto err;
+ if (IS_CAT("halftone")) {
+ pat = "halftone_(%sdht_%%s)";
+ } else
+ goto err;
+ goto pre;
case 'i':
- if (is_cat("imagetype")) {
- pat = "image_type_(%simage_type_%%s)";
- } else if (is_cat("include")) {
- int len = strlen(item);
-
+ if (IS_CAT("imageclass")) {
+ list = &pconf->c_sorted_resources;
+ pat = "image_class_(%simage_class_%%s)";
+ } else if (IS_CAT("imagetype")) {
+ pat = "image_type_(%%s,%simage_type_%%s)";
+ } else if (IS_CAT("include")) {
strcpy(str, item);
- if (len < 5 || strcmp(str + len - 4, ".dev"))
- strcat(str, ".dev");
+ dev_file_name(str);
return read_dev(pconf, str);
- } else if (is_cat("init")) {
+ } else if (IS_CAT("init")) {
pat = "init_(%s%%s_init)";
- } else if (is_cat("iodev")) {
+ } else if (IS_CAT("iodev")) {
pat = "io_device_(%siodev_%%s)";
} else
goto err;
- sprintf(template, pat, pconf->name_prefix);
- pat = template;
- break;
+ goto pre;
case 'l':
- if (is_cat("lib")) {
+ if (IS_CAT("lib")) {
list = &pconf->c_libs;
break;
}
- if (is_cat("libpath")) {
+ if (IS_CAT("libpath")) {
list = &pconf->c_libpaths;
break;
}
goto err;
case 'o':
- if (is_cat("obj")) {
+ if (IS_CAT("obj")) {
list = &pconf->c_objs;
strcpy(template, pconf->file_prefix);
strcat(template, "%s");
pat = template;
break;
}
- if (is_cat("oper")) {
+ if (IS_CAT("oper")) {
pat = "oper_(%s_op_defs)";
break;
}
goto err;
case 'p':
- if (is_cat("ps")) {
+ if (IS_CAT("ps")) {
sprintf(str, "psfile_(\"%s.ps\",%d)",
item, strlen(item) + 3);
item = str;
@@ -638,18 +640,19 @@ add_entry(config * pconf, char *category, const char *item, int file_index)
}
goto err;
case 'r':
- if (is_cat("replace")) {
+ if (IS_CAT("replace")) {
list = &pconf->replaces;
break;
}
goto err;
-#undef is_cat
+#undef IS_CAT
default:
- err:fprintf(stderr, "Unknown category %s.\n", category);
+err: fprintf(stderr, "Definition not recognized: %s %s.\n",
+ category, item);
exit(1);
}
if (pat) {
- sprintf(str, pat, item);
+ sprintf(str, pat, item, item);
assert(strlen(str) < MAX_STR);
add_item(list, str, file_index);
} else
@@ -666,9 +669,10 @@ add_item(string_list * list, const char *str, int file_index)
int count = list->count;
string_item *item;
- strcpy(rstr, str);
if (count >= list->max_count) {
list->max_count <<= 1;
+ if (list->max_count < 20)
+ list->max_count = 20;
list->items =
(string_item *) mrealloc(list->items,
(list->max_count >> 1) *
@@ -678,9 +682,10 @@ add_item(string_list * list, const char *str, int file_index)
assert(list->items != NULL);
}
item = &list->items[count];
- item->index = count;
item->str = rstr;
+ item->index = count;
item->file_index = file_index;
+ strcpy(rstr, str);
list->count++;
return item;
}
@@ -705,7 +710,7 @@ cmp_str(const void *p1, const void *p2)
#undef psi1
#undef psi2
void
-sort_uniq(string_list * list)
+sort_uniq(string_list * list, bool by_index)
{
string_item *strlist = list->items;
int count = list->count;
@@ -726,7 +731,8 @@ sort_uniq(string_list * list)
to[-1] = *from;
count = to - strlist;
list->count = count;
- qsort((char *)strlist, count, sizeof(string_item), cmp_index);
+ if (by_index)
+ qsort((char *)strlist, count, sizeof(string_item), cmp_index);
}
/* Write a list of strings using a template. */
diff --git a/gs/src/genht.c b/gs/src/genht.c
new file mode 100644
index 000000000..32ca07a5e
--- /dev/null
+++ b/gs/src/genht.c
@@ -0,0 +1,333 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Generate C code for compiling halftones into ROM. */
+#include "malloc_.h"
+#include "stdio_.h"
+#include "string_.h"
+#include "gscdefs.h"
+#include "gsmemory.h"
+#include "gxbitmap.h"
+#include "gxhttile.h"
+#include "gxtmap.h"
+#include "gxdht.h"
+#include "gxdhtres.h"
+#include "strimpl.h"
+#include "sstring.h"
+
+extern_gx_device_halftone_list();
+
+/*
+ * This program translates PostScript halftone resources into C data
+ * structures that can then be compiled into executables and put in shared,
+ * read-only memory. The syntax of the resource file is a subset of
+ * PostScript, tightly constrained so that it can be parsed easily. Blank
+ * lines and PostScript comments are ignored, but otherwise each halftone
+ * in the file (there may be more than one) must follow this format,
+ * where ... indicates arbitrary text:
+ /halftone_name ...
+ /HalftoneType 3
+ /Width xxx
+ /Height xxx
+ /Thresholds ...
+ --hex data terminated by a >--
+ ... defineresource
+ * Lines that don't follow the above syntax may appear anywhere in the file
+ * except in the middle of the hex data. Width and Height must precede
+ * Thresholds, but otherwise the 4 parameters may appear in any order.
+ * White space at the beginning or end of a line is ignored, and any
+ * amount of white space may separate the parameter name from its value.
+ *
+ * We envision that this format will eventually be extended to cover
+ * HalftoneType 16 halftones with a single rectangle, allowing 16-bit
+ * threshold values.
+ */
+
+/* Read a source file into memory. */
+private char *
+read_file(FILE *in, char *cname)
+{
+ int len, nread;
+ char *cont;
+
+ fseek(in, 0L, 2 /*SEEK_END*/);
+ len = ftell(in);
+ cont = malloc(len + 1);
+ if (cont == 0) {
+ fprintf(stderr, "Can't allocate %d bytes to read %s.\n",
+ len + 1, cname);
+ return 0;
+ }
+ rewind(in);
+ nread = fread(cont, 1, len, in);
+ cont[nread] = 0;
+ return cont;
+}
+
+/* Parse a Halftone resource file into memory. */
+private bool
+parse_line(char **pstr, char **pline)
+{
+ char *str = *pstr;
+
+top:
+ while (*str && strchr(" \t\r\n", *str)) /* trim leading space */
+ ++str;
+ if (*str == 0) {
+ *pline = 0;
+ return false;
+ }
+ *pline = str;
+ while (*str && !strchr("\r\n", *str)) /* find EOL */
+ ++str;
+ while (str > *pline && strchr(" \t", str[-1])) /* trim trailing space */
+ --str;
+ *str = 0;
+ *pstr = str + 1;
+ return true;
+}
+int
+parse_halftone(gx_device_halftone_resource_t *phtr, byte **pThresholds,
+ char **pcont)
+{
+ char *str;
+ char *line;
+ char *rname = 0;
+ int HalftoneType = -1;
+ int Width = -1, Height = -1;
+ byte *Thresholds = 0;
+ stream_AXD_state ss;
+
+ /* Parse the file. */
+ for (str = *pcont; parse_line(&str, &line);) {
+ char *end;
+
+ if (line[0] == '%')
+ continue;
+ if (strlen(line) >= 14 &&
+ !strcmp(line + strlen(line) - 14, "defineresource")
+ )
+ break;
+ if (line[0] != '/')
+ continue;
+ end = ++line;
+ while (*end && !strchr(" \t<", *end)) /* find end of name */
+ ++end;
+ if (rname == 0) { /* first name is halftone name */
+ *end = 0;
+ rname = malloc(strlen(line) + 1);
+ strcpy(rname, line);
+ continue;
+ }
+ if (*end == 0) /* name alone */
+ continue;
+ *end++ = 0;
+ if (!strcmp(line, "HalftoneType")) {
+ if (sscanf(end, "%d", &HalftoneType) != 1 ||
+ HalftoneType != 3
+ ) {
+ fprintf(stderr, "Invalid HalftoneType: %s\n", end);
+ return -1;
+ }
+ } else if (!strcmp(line, "Width")) {
+ if (sscanf(end, "%d", &Width) != 1 ||
+ Width <= 0 || Width > 0x4000
+ ) {
+ fprintf(stderr, "Invalid Width: %s\n", end);
+ return -1;
+ }
+ } else if (!strcmp(line, "Height")) {
+ if (sscanf(end, "%d", &Height) != 1 ||
+ Height <= 0 || Height > 0x4000
+ ) {
+ fprintf(stderr, "Invalid Height: %s\n", end);
+ return -1;
+ }
+ } else if (!strcmp(line, "Thresholds")) {
+ uint ignore;
+ uint num_levels = 256;
+ uint num_bits = Width * Height;
+ stream_cursor_read r;
+ stream_cursor_write w;
+
+ if (Width < 0 || Height < 0) {
+ fprintf(stderr, "Width and Height must precede Thresholds.\n");
+ return -1;
+ }
+ phtr->num_levels = num_levels;
+ phtr->levels =
+ malloc(num_levels * sizeof(*phtr->levels));
+ phtr->bit_data =
+ malloc(num_bits * sizeof(ushort));
+ Thresholds = malloc(num_bits);
+ s_AXD_init_inline(&ss);
+ r.ptr = end + strlen(end); /* skip rest of line */
+ r.limit = r.ptr + strlen(r.ptr + 1);
+ w.ptr = Thresholds - 1;
+ w.limit = w.ptr + num_bits;
+ s_AXD_template.process((stream_state *)&ss, &r, &w, true);
+ str = (char *)r.ptr + 1;
+ }
+ }
+
+ /* Check for successful parsing. */
+ if (rname == 0)
+ return 1; /* end of definitions */
+ if (HalftoneType < 0)
+ fprintf(stderr, "HalftoneType not found.\n");
+ if (Width < 0)
+ fprintf(stderr, "Width not found.\n");
+ if (Height < 0)
+ fprintf(stderr, "Height not found.\n");
+ if (Thresholds == 0)
+ fprintf(stderr, "Thresholds not found.\n");
+ if (rname == 0 || Thresholds == 0)
+ return -1;
+ phtr->rname = rname;
+ phtr->HalftoneType = HalftoneType;
+ phtr->Width = Width;
+ phtr->Height = Height;
+ *pThresholds = Thresholds;
+ *pcont = str;
+ return 0;
+}
+
+/* Write a halftone as a C procedure. */
+int
+write_halftone(FILE *out, gx_device_halftone_resource_t *phtr)
+{
+ const char *rname = phtr->rname;
+ int num_bits = phtr->Width * phtr->Height;
+ int i;
+
+ /* Write the procedure prologue. */
+ fprintf(out, "const gx_device_halftone_resource_t *\ngs_dht_%s(void)\n{\n",
+ rname);
+
+ /* Write the levels array. */
+ fprintf(out, "static const unsigned int levels[] = {");
+ for (i = 0; i < phtr->num_levels; ++i) {
+ if (i % 10 == 0)
+ fputs("\n", out);
+ fprintf(out, "%5u,", phtr->levels[i]);
+ }
+ fputs("\n0};\n", out);
+
+ /* Write the bit_data array. */
+ fprintf(out, "static const unsigned short bit_data[] = {");
+ for (i = 0; i < num_bits; ++i) {
+ if (i % 10 == 0)
+ fputs("\n", out);
+ fprintf(out, "%5u,", ((const ushort *)phtr->bit_data)[i]);
+ }
+ fputs("\n0};\n", out);
+
+ /* Write the top-level structure and the procedure body and epilogue. */
+ fprintf(out, "static const gx_device_halftone_resource_t res = {\n \"%s\", %d, %d, %d, %d, levels, bit_data, %u\n};\n return &res;\n}\n",
+ rname, phtr->HalftoneType, phtr->Width, phtr->Height,
+ phtr->num_levels, ht_order_procs_short.bit_data_elt_size);
+}
+
+/* Main program */
+main(int argc, char *argv[])
+{
+ char *iname;
+ FILE *in;
+ char *oname;
+ FILE *out;
+ int code;
+ char *cont;
+ char *line;
+ gx_device_halftone_resource_t res;
+ byte *Thresholds;
+ gx_ht_order order;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: genht ht_res.ps ht_data.c\n");
+ exit(1);
+ }
+ iname = argv[1];
+ oname = argv[2];
+ in = fopen(iname, "rb");
+ if (in == 0) {
+ in = fopen(iname, "r");
+ if (in == 0) {
+ fprintf(stderr, "Can't read %s.\n", iname);
+ exit(1);
+ }
+ }
+ cont = read_file(in, iname);
+ if (cont == 0)
+ exit(1);
+ fclose(in);
+ out = fopen(oname, "w");
+ if (out == 0) {
+ fprintf(stderr, "Can't open %s for output.\n", oname);
+ exit(1);
+ }
+ fprintf(out, "/* %s generated from %s by genht. Do not edit this file. */\n\n", oname, iname);
+ /* Copy initial comments from the input file. */
+ while (parse_line(&cont, &line) && line[0] == '%')
+ if (line[1] != '!')
+ fprintf(out, "/*%s */\n", line + 1);
+ cont[-1] = '\n';
+ cont = line;
+ fputs("#include \"gxdhtres.h\"\n\n", out);
+ while ((code = parse_halftone(&res, &Thresholds, &cont)) == 0) {
+ order.width = res.Width;
+ order.num_levels = res.num_levels;
+ order.levels = (uint *)res.levels;
+ order.num_bits = res.Width * res.Height;
+ order.bit_data = (void *)res.bit_data;
+ ht_order_procs_short.construct_order(&order, Thresholds);
+ write_halftone(out, &res);
+ }
+ fclose(out);
+ if (code < 0)
+ exit(1);
+ return 0;
+}
+
+/* Stubs */
+const gs_ptr_procs_t ptr_struct_procs = {NULL, NULL, NULL};
+const gs_ptr_procs_t ptr_string_procs = {NULL, NULL, NULL};
+const gs_ptr_procs_t ptr_const_string_procs = {NULL, NULL, NULL};
+ENUM_PTRS_BEGIN_PROC(gs_no_struct_enum_ptrs)
+{
+ return 0;
+ ENUM_PTRS_END_PROC
+}
+RELOC_PTRS_BEGIN(gs_no_struct_reloc_ptrs)
+{
+}
+RELOC_PTRS_END
+public_st_stream_state();
+void
+gx_ht_complete_threshold_order(gx_ht_order *porder)
+{
+}
+const gx_dht_proc gx_device_halftone_list[] = { 0 };
+
+/*
+ * In order to avoid a linking step, we #include the required files here
+ * rather than compiling them separately.
+ */
+#include "gxhtbit.c"
+#include "scantab.c"
+#include "sstring.c"
diff --git a/gs/src/geninit.c b/gs/src/geninit.c
index 2b3efb32f..9f9ed5fda 100644
--- a/gs/src/geninit.c
+++ b/gs/src/geninit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,40 +24,49 @@
#include <string.h>
/* Usage:
- * geninit <init-file.ps> <gconfig.h> <merged-init-file.ps>
- * geninit <init-file.ps> <gconfig.h> -c <merged-init-file.c>
+ * geninit [-I <prefix>] <init-file.ps> <gconfig.h> <merged-init-file.ps>
+ * geninit [-I <prefix>] <init-file.ps> <gconfig.h> -c <merged-init-file.c>
*/
/* Forward references */
-private void merge_to_c(P4(const char *inname, FILE * in, FILE * config,
- FILE * out));
-private void merge_to_ps(P4(const char *inname, FILE * in, FILE * config,
- FILE * out));
+private FILE *prefix_open(P2(const char *prefix, const char *inname));
+private void merge_to_c(P5(const char *prefix, const char *inname, FILE * in,
+ FILE * config, FILE * out));
+private void merge_to_ps(P5(const char *prefix, const char *inname, FILE * in,
+ FILE * config, FILE * out));
#define LINE_SIZE 128
int
main(int argc, char *argv[])
{
+ int arg_c = argc;
+ char **arg_v = argv;
const char *fin;
FILE *in;
const char *fconfig;
FILE *config;
const char *fout;
FILE *out;
+ const char *prefix = "";
bool to_c = false;
- if (argc == 4)
- fin = argv[1], fconfig = argv[2], fout = argv[3];
- else if (argc == 5 && !strcmp(argv[3], "-c"))
- fin = argv[1], fconfig = argv[2], fout = argv[4], to_c = true;
+ if (arg_c >= 2 && !strcmp(arg_v[1], "-I")) {
+ prefix = arg_v[2];
+ arg_c -= 2;
+ arg_v += 2;
+ }
+ if (arg_c == 4)
+ fin = arg_v[1], fconfig = arg_v[2], fout = arg_v[3];
+ else if (arg_c == 5 && !strcmp(arg_v[3], "-c"))
+ fin = arg_v[1], fconfig = arg_v[2], fout = arg_v[4], to_c = true;
else {
fprintf(stderr, "\
-Usage: geninit gs_init.ps gconfig.h gs_xinit.ps\n\
-or geninit gs_init.ps gconfig.h -c gs_init.c\n");
+Usage: geninit [-I lib/] gs_init.ps gconfig.h gs_xinit.ps\n\
+or geninit [-I lib/] gs_init.ps gconfig.h -c gs_init.c\n");
exit(1);
}
- in = fopen(fin, "r");
+ in = prefix_open(prefix, fin);
if (in == 0) {
fprintf(stderr, "Cannot open %s for reading.\n", fin);
exit(1);
@@ -76,20 +85,55 @@ or geninit gs_init.ps gconfig.h -c gs_init.c\n");
exit(1);
}
if (to_c)
- merge_to_c(fin, in, config, out);
+ merge_to_c(prefix, fin, in, config, out);
else
- merge_to_ps(fin, in, config, out);
+ merge_to_ps(prefix, fin, in, config, out);
fclose(out);
return 0;
}
+/* Open a file with a name prefix. */
+private FILE *
+prefix_open(const char *prefix, const char *inname)
+{
+ char fname[LINE_SIZE + 1];
+
+ if (strlen(prefix) + strlen(inname) > LINE_SIZE) {
+ fprintf(stderr, "File name > %d characters, too long.\n",
+ LINE_SIZE);
+ exit(1);
+ }
+ strcpy(fname, prefix);
+ strcat(fname, inname);
+ return fopen(fname, "r");
+}
+
/* Read a line from the input. */
private bool
rl(FILE * in, char *str, int len)
{
- if (fgets(str, len, in) == NULL)
+ /*
+ * Unfortunately, we can't use fgets here, because the typical
+ * implementation only recognizes the EOL convention of the current
+ * platform.
+ */
+ int i = 0, c = getc(in);
+
+ if (c < 0)
return false;
- str[strlen(str) - 1] = 0; /* remove newline */
+ while (i < len - 1) {
+ if (c < 0 || c == 10) /* ^J, Unix EOL */
+ break;
+ if (c == 13) { /* ^M, Mac EOL */
+ c = getc(in);
+ if (c != 10 && c >= 0) /* ^M^J, PC EOL */
+ ungetc(c, in);
+ break;
+ }
+ str[i++] = c;
+ c = getc(in);
+ }
+ str[i] = 0;
return true;
}
@@ -204,7 +248,8 @@ flush_buf(FILE * out, char *buf, bool to_c)
}
}
private void
-mergefile(const char *inname, FILE * in, FILE * config, FILE * out, bool to_c)
+mergefile(const char *prefix, const char *inname, FILE * in, FILE * config,
+ FILE * out, bool to_c)
{
char line[LINE_SIZE + 1];
char buf[LINE_SIZE + 1];
@@ -225,12 +270,12 @@ mergefile(const char *inname, FILE * in, FILE * config, FILE * out, bool to_c)
FILE *ps;
psname[strlen(psname) - 1] = 0;
- ps = fopen(psname + 1, "r");
+ ps = prefix_open(prefix, psname + 1);
if (ps == 0) {
fprintf(stderr, "Cannot open %s for reading.\n", psname + 1);
exit(1);
}
- mergefile(psname + 1, ps, config, out, to_c);
+ mergefile(prefix, psname + 1, ps, config, out, to_c);
} else if (!strcmp(psname, "INITFILES")) {
/*
* We don't want to bind config.h into geninit, so
@@ -243,12 +288,12 @@ mergefile(const char *inname, FILE * in, FILE * config, FILE * out, bool to_c)
char *quote = strchr(psname + 9, '"');
*quote = 0;
- ps = fopen(psname + 9, "r");
+ ps = prefix_open(prefix, psname + 9);
if (ps == 0) {
fprintf(stderr, "Cannot open %s for reading.\n", psname + 9);
exit(1);
}
- mergefile(psname + 9, ps, config, out, to_c);
+ mergefile(prefix, psname + 9, ps, config, out, to_c);
}
} else {
fprintf(stderr, "Unknown %%%% Replace %d %s\n",
@@ -282,7 +327,8 @@ mergefile(const char *inname, FILE * in, FILE * config, FILE * out, bool to_c)
/* Merge and produce a C file. */
private void
-merge_to_c(const char *inname, FILE * in, FILE * config, FILE * out)
+merge_to_c(const char *prefix, const char *inname, FILE * in, FILE * config,
+ FILE * out)
{
char line[LINE_SIZE + 1];
@@ -294,18 +340,19 @@ merge_to_c(const char *inname, FILE * in, FILE * config, FILE * out)
fputs("/* Pre-compiled interpreter initialization string. */\n", out);
fputs("\n", out);
fputs("const unsigned char gs_init_string[] = {\n", out);
- mergefile(inname, in, config, out, true);
+ mergefile(prefix, inname, in, config, out, true);
fputs("10};\n", out);
fputs("const unsigned int gs_init_string_sizeof = sizeof(gs_init_string);\n", out);
}
/* Merge and produce a PostScript file. */
private void
-merge_to_ps(const char *inname, FILE * in, FILE * config, FILE * out)
+merge_to_ps(const char *prefix, const char *inname, FILE * in, FILE * config,
+ FILE * out)
{
char line[LINE_SIZE + 1];
while ((rl(in, line, LINE_SIZE), line[0]))
fprintf(out, "%s\n", line);
- mergefile(inname, in, config, out, false);
+ mergefile(prefix, inname, in, config, out, false);
}
diff --git a/gs/src/gp.h b/gs/src/gp.h
index 6467e5735..f0f3fab1d 100644
--- a/gs/src/gp.h
+++ b/gs/src/gp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,11 +18,12 @@
/* Interface to platform-specific routines */
-/* Requires gsmemory.h, gstypes.h */
+/* Requires gsmemory.h */
#ifndef gp_INCLUDED
# define gp_INCLUDED
+#include "gstypes.h"
/*
* This file defines the interface to ***ALL*** platform-specific routines,
* with the exception of the thread/synchronization interface (gpsync.h).
@@ -34,6 +35,11 @@
* and don't want to include any of the other gs definitions.
*/
#include "gpgetenv.h"
+/*
+ * The prototype for gp_readline is in srdline.h, since it is shared with
+ * stream.h.
+ */
+#include "srdline.h"
/* ------ Initialization/termination ------ */
@@ -80,6 +86,34 @@ void gp_get_realtime(P1(long ptm[2]));
*/
void gp_get_usertime(P1(long ptm[2]));
+/* ------ Reading lines from stdin ------ */
+
+/*
+ * These routines are intended to provide an abstract interface to GNU
+ * readline or to other packages that offer enhanced line-reading
+ * capability.
+ */
+
+/*
+ * Allocate a state structure for line reading. This is called once at
+ * initialization. *preadline_data is an opaque pointer that is passed
+ * back to gp_readline and gp_readline_finit.
+ */
+int gp_readline_init(P2(void **preadline_data, gs_memory_t *mem));
+
+/*
+ * See srdline.h for the definition of sreadline_proc.
+ */
+int gp_readline(P9(stream *s_in, stream *s_out, void *readline_data,
+ gs_const_string *prompt, gs_string *buf,
+ gs_memory_t *bufmem, uint *pcount, bool *pin_eol,
+ bool (*is_stdin)(P1(const stream *))));
+
+/*
+ * Free a readline state.
+ */
+void gp_readline_finit(P1(void *readline_data));
+
/* ------ Screen management ------ */
/*
@@ -91,7 +125,6 @@ void gp_get_usertime(P1(long ptm[2]));
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
/* Initialize the console. */
@@ -190,7 +223,6 @@ void gp_close_printer(P2(FILE * pfile, const char *fname));
# define file_enum_DEFINED
struct file_enum_s; /* opaque to client, defined by implementor */
typedef struct file_enum_s file_enum;
-
#endif
/*
diff --git a/gs/src/gp_gnrdl.c b/gs/src/gp_gnrdl.c
new file mode 100644
index 000000000..e9bb66b59
--- /dev/null
+++ b/gs/src/gp_gnrdl.c
@@ -0,0 +1,363 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* GNU readline implementation */
+#include "ctype_.h"
+#include "string_.h"
+#include "malloc_.h"
+#include "memory_.h"
+#include <readline/readline.h>
+#include <readline/history.h>
+#include "ghost.h"
+#include "errors.h"
+#include "gp.h"
+#include "gsmalloc.h"
+#include "gsmemory.h"
+#include "gsstruct.h"
+#include "stream.h"
+#include "gxiodev.h"
+#include "idict.h"
+#include "iname.h"
+#include "iutil.h"
+#include "dstack.h"
+#include "ostack.h"
+
+/*
+ * Note: This code was contributed by a user: please contact
+ * Alexey Subbotin <A.Subbotin@lpi.ru> if you have questions.
+ */
+
+#define DEFAULT_BUFFER_SIZE 256
+#define BUFSIZE_INCR 128
+
+/* The file names can be set in the makefile if desired. */
+/*
+ * The prototypes for read_history and write_history are broken (they don't
+ * specify the file name strings as const), so we have to omit the const
+ * here too, or else add casts that will cause some compilers to complain.
+ */
+#ifndef GS_HISTFILE
+# define GS_HISTFILE ".gs_history"
+#endif
+private /*const*/ char *const GS_histfile = GS_HISTFILE;
+#ifndef RL_INITFILE
+# define RL_INITFILE "~/.inputrc"
+#endif
+private /*const*/ char *const RL_initfile = RL_INITFILE;
+
+/* initial key codes to make dictionary current_completion_dict
+ (may be changed to any key sequences by settings in init file) */
+#define RL_systemdict_keycode ('s' | 0x80 ) /* Alt-s */
+#define RL_userdict_keycode ('u' | 0x80 ) /* Alt-u */
+#define RL_currentdict_keycode ('c' | 0x80 ) /* Alt-c */
+#define RL_filenames_keycode ('f' | 0x80 ) /* Alt-f */
+#define RL_show_value_keycode ('i' | 0x80 ) /* Alt-i ( = info) */
+/* e.g.: "\C-x\C-u": complete-from-userdict */
+#define RL_systemdict_func "gs-complete-from-systemdict"
+#define RL_userdict_func "gs-complete-from-userdict"
+#define RL_currentdict_func "gs-complete-from-currentdict"
+#define RL_filenames_func "gs-complete-filenames"
+#define RL_show_value_func "gs-show-name-value"
+
+#define RL_init_buffsz DEFAULT_BUFFER_SIZE
+
+private const char *const ps_delimiters = " \n\t{}[]()/";
+
+#define is_regular(A) (strchr(ps_delimiters,(A)) == NULL)
+
+typedef enum {
+ compl_systemdict,
+ compl_userdict,
+ compl_currentdict,
+ compl_filenames
+} compl_t;
+
+typedef struct readline_data_s {
+ compl_t completion_type;
+ gs_memory_t *mem;
+ i_ctx_t *i_ctx_p;
+ /* current completion state */
+ int c_idx, c_len;
+} readline_data_t;
+gs_private_st_ptrs1(st_readline_data, readline_data_t, "readline_data_t",
+ readline_data_enum_ptrs, readline_data_reloc_ptrs, i_ctx_p);
+
+private readline_data_t *the_readline_data;
+
+private char *
+gs_readline_complete(char *text, int state)
+{
+ readline_data_t *const p = the_readline_data;
+ i_ctx_t *i_ctx_p = p->i_ctx_p;
+ ref *cdict;
+ ref eltp[2];
+
+ switch (p->completion_type) {
+ case compl_systemdict:
+ cdict = systemdict;
+ break;
+ case compl_userdict:
+ cdict = idict_stack.stack.bot + dstack_userdict_index;
+ break;
+ case compl_currentdict:
+ cdict = idict_stack.stack.p;
+ break;
+ case compl_filenames:
+ return (*filename_completion_function) (text, state);
+ default:
+ return NULL;
+ }
+ if (!state) {
+ p->c_len = strlen(text);
+ if (!(p->c_idx = dict_first(cdict)))
+ return NULL;
+ }
+ while ((p->c_idx = dict_next(cdict, p->c_idx, eltp)) >= 0) {
+ const byte *rname = eltp->value.refs->value.const_bytes;
+ uint rlen = eltp->value.refs->tas.rsize >> 2;
+
+ if (rname && !strncmp((const char *)rname, text, p->c_len)) {
+ char *name = (char *)malloc(rlen + 1);
+
+ memcpy(name, rname, rlen);
+ name[rlen] = 0;
+ return name;
+ }
+ }
+ return NULL;
+}
+
+private int
+rl_systemdict_compl(int count, int key)
+{
+ readline_data_t *const p = the_readline_data;
+
+ p->completion_type = compl_systemdict;
+ return 0;
+}
+private int
+rl_userdict_compl(int count, int key)
+{
+ readline_data_t *const p = the_readline_data;
+
+ p->completion_type = compl_userdict;
+ return 0;
+}
+private int
+rl_currentdict_compl(int count, int key)
+{
+ readline_data_t *const p = the_readline_data;
+
+ p->completion_type = compl_currentdict;
+ return 0;
+}
+private int
+rl_filenames_compl(int count, int key)
+{
+ readline_data_t *const p = the_readline_data;
+
+ p->completion_type = compl_filenames;
+ return 0;
+}
+
+private int
+rl_show_name_value(int count, int key)
+{
+ readline_data_t *const p = the_readline_data;
+ i_ctx_t *i_ctx_p = p->i_ctx_p;
+ int i = rl_point;
+ char *c = rl_line_buffer + rl_point;
+ ref nref;
+ ref *pvref;
+
+ while (is_regular(*c) && i < rl_end) {
+ c++;
+ i++;
+ }
+ while (!is_regular(*c) && i) {
+ c--;
+ i--;
+ }
+ if (!is_regular(*c))
+ return 0;
+ while (is_regular(*c) && c > rl_line_buffer)
+ c--;
+ if (!is_regular(*c))
+ c++;
+ i += ((rl_line_buffer - c) + 1);
+ /*
+ * Now the name to be looked up extends from c through c + i - 1.
+ */
+ if (name_ref((const byte *)c, (uint)i, &nref, -1) < 0 ||
+ (pvref = dict_find_name(&nref)) == 0
+ )
+ puts("\nnot found");
+ else {
+#define MAX_CVS 128
+ char str[MAX_CVS];
+ const byte *pchars = (const byte *)str;
+ uint len;
+ int code = obj_cvp(pvref, (byte *)str, MAX_CVS, &len, 1, 0);
+
+ putchar('\n');
+ if (code < 0) {
+ code = obj_string_data(pvref, &pchars, &len);
+ if (code >= 0)
+ switch (r_type(pvref)) {
+ case t_string:
+ putchar('(');
+ fwrite(pchars, 1, len, stdout);
+ pchars = (const byte *)")", len = 1;
+ break;
+ case t_name:
+ if (!r_has_attr(pvref, a_executable))
+ putchar('/');
+ break;
+ default:
+ code = obj_cvs(pvref, (byte *)str, MAX_CVS, &len, &pchars);
+ }
+ }
+ if (code < 0)
+ puts("-error-");
+ else {
+ fwrite(pchars, 1, len, stdout);
+ putchar('\n');
+ }
+ }
+ rl_on_new_line();
+ rl_forced_update_display();
+ return 0;
+}
+
+
+int
+gp_readline_init(void **preadline_data, gs_memory_t * mem)
+{
+ readline_data_t *p;
+
+ using_history();
+ read_history(GS_histfile);
+
+ p = (readline_data_t *)
+ gs_alloc_struct_immovable(mem, readline_data_t, &st_readline_data,
+ "gp_readline_init(readline structure)");
+ if (!p)
+ return_error(e_VMerror);
+ gs_register_struct_root(mem, NULL, (void **)&the_readline_data,
+ "the_readline_data");
+
+ p->mem = mem;
+ p->i_ctx_p = 0; /* only meaningful when reading a line */
+ p->c_idx = p->c_len = 0;
+ p->completion_type = compl_systemdict;
+
+ rl_add_defun(RL_systemdict_func, rl_systemdict_compl, RL_systemdict_keycode);
+ rl_add_defun(RL_userdict_func, rl_userdict_compl, RL_userdict_keycode);
+ rl_add_defun(RL_currentdict_func, rl_currentdict_compl, RL_currentdict_keycode);
+ rl_add_defun(RL_filenames_func, rl_filenames_compl, RL_filenames_keycode);
+ rl_add_defun(RL_show_value_func, rl_show_name_value, RL_show_value_keycode);
+
+ rl_read_init_file(RL_initfile);
+
+ /*
+ * The GNU readline API is pretty badly broken, as indicated in the
+ * following comments about the following statics that it declares.
+ * (Just to begin with, using statics at all is broken design.)
+ */
+ /*
+ * rl_completion_entry_function should be declared with the same
+ * prototype as gs_readline_complete; however, it's declared as
+ * Function *, where Function is int ()();
+ */
+ rl_completion_entry_function = (Function *)gs_readline_complete;
+ /*
+ * rl_basic_word_break_characters should declared as const char *;
+ * however, it's declared as char *.
+ */
+ rl_basic_word_break_characters = (char *)ps_delimiters;
+
+ *preadline_data = p;
+ the_readline_data = p; /* HACK */
+ return 0;
+}
+
+void
+gp_readline_finit(void *data)
+{
+ readline_data_t *dp = (readline_data_t *)data;
+
+ if (dp)
+ gs_free_object(dp->mem, dp, "gp_readline_finit(readline structure)");
+ write_history(GS_histfile);
+ clear_history();
+}
+
+int
+gp_readline(stream *ignore_s_in, stream *ignore_s_out,
+ void *readline_data,
+ gs_const_string *ignore_prompt, gs_string * buf,
+ gs_memory_t * bufmem, uint * pcount, bool *pin_eol,
+ bool (*is_stdin)(P1(const stream *)))
+{
+ /* HACK: ignore readline_data, which is currently not supplied. */
+ readline_data_t *p = the_readline_data;
+ char *c;
+ char prompt[64];
+ uint count;
+ gx_io_device *indev = gs_findiodevice((const byte *)"%stdin", 6);
+ /* HACK: get the context pointer from the IODevice. See ziodev.c. */
+ i_ctx_t *i_ctx_p = (i_ctx_t *)indev->state;
+
+ p->i_ctx_p = i_ctx_p;
+ count = ref_stack_count(&o_stack);
+ if (count > 2)
+ sprintf(prompt, "GS<%d>", count - 2);
+ else
+ strcpy(prompt, "GS>");
+
+ if ((c = readline(prompt)) == NULL) {
+ *pcount = 0;
+ *pin_eol = false;
+ return EOFC;
+ } else {
+ count = strlen(c) + 1;
+ if (*c)
+ add_history(c);
+ if (count >= buf->size) {
+ if (!bufmem)
+ return ERRC; /* no better choice */
+ {
+ uint nsize = count + BUFSIZE_INCR;
+ byte *nbuf = gs_resize_string(bufmem, buf->data, buf->size,
+ nsize,
+ "gp_readline(resize buffer)");
+
+ if (nbuf == 0)
+ return ERRC; /* no better choice */
+ buf->data = nbuf;
+ buf->size = nsize;
+ }
+ }
+ memcpy(buf->data, c, count);
+ free(c);
+ *pin_eol = true;
+ *pcount = count;
+ return 0;
+ }
+}
diff --git a/gs/src/gp_iwatc.c b/gs/src/gp_iwatc.c
index 2609853af..6f6f54539 100644
--- a/gs/src/gp_iwatc.c
+++ b/gs/src/gp_iwatc.c
@@ -176,4 +176,3 @@ gp_fopen(const char *fname, const char *mode)
{
return fopen(fname, mode);
}
-
diff --git a/gs/src/gp_msio.c b/gs/src/gp_msio.c
index 7a4663f69..1049939ed 100644
--- a/gs/src/gp_msio.c
+++ b/gs/src/gp_msio.c
@@ -54,6 +54,7 @@ int gp_file_is_console(P1(FILE *));
private void win_std_init(void);
private stream_proc_process(win_std_read_process);
private stream_proc_process(win_std_write_process);
+private stream_proc_available(win_std_available);
/* Use a pseudo IODevice to get win_stdio_init called at the right time. */
/* This is bad architecture; we'll fix it later. */
@@ -90,6 +91,7 @@ win_stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
if (code != 1)
return code;
s->procs.process = win_std_read_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -106,6 +108,7 @@ win_stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
if (code != 1)
return code;
s->procs.process = win_std_write_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -122,6 +125,7 @@ win_stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
if (code != 1)
return code;
s->procs.process = win_std_write_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -166,6 +170,13 @@ win_std_read_process(stream_state * st, stream_cursor_read * ignore_pr,
return 1;
}
+private int
+win_std_available(register stream * s, long *pl)
+{
+ *pl = -1; // EOF, since we can't do it
+ return 0; // OK
+}
+
private int
win_std_write_process(stream_state * st, stream_cursor_read * pr,
diff --git a/gs/src/gp_nsync.c b/gs/src/gp_nsync.c
index 7210aeb05..83fa9ae20 100644
--- a/gs/src/gp_nsync.c
+++ b/gs/src/gp_nsync.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -51,7 +51,7 @@ int
gp_semaphore_wait(gp_semaphore * sema)
{
if (*(int *)sema == 0)
- return_error(gs_error_unknownerror);
+ return_error(gs_error_unknownerror); /* no real waiting */
--(*(int *)sema);
return 0;
}
@@ -90,14 +90,14 @@ gp_monitor_enter(gp_monitor * mon)
{
if (mon->dummy_ != 0)
return_error(gs_error_unknownerror);
- mon->dummy_ = &mon;
+ mon->dummy_ = mon;
return 0;
}
int
gp_monitor_leave(gp_monitor * mon)
{
- if (mon->dummy_ != &mon)
+ if (mon->dummy_ != mon)
return_error(gs_error_unknownerror);
mon->dummy_ = 0;
return 0;
@@ -108,7 +108,5 @@ gp_monitor_leave(gp_monitor * mon)
int
gp_create_thread(gp_thread_creation_callback_t proc, void *proc_data)
{
- /* Just call the procedure now. */
- (*proc)(proc_data);
- return 0;
+ return_error(gs_error_unknownerror);
}
diff --git a/gs/src/gp_ntfs.c b/gs/src/gp_ntfs.c
index cc5901d8d..64ed26fdb 100644
--- a/gs/src/gp_ntfs.c
+++ b/gs/src/gp_ntfs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -51,14 +51,16 @@ gp_set_file_binary(int prnfno, int binary)
int
gp_setmode_binary(FILE * pfile, bool binary)
{
- /* Use non-standard setmode & fileno fn's that all NT compilers offer */
+ /*
+ * Use non-standard setmode & fileno fn's that almost all NT compilers
+ * offer.
+ */
#if defined(__STDC__) && !defined(__WATCOMC__)
int code = _setmode(_fileno(pfile), binary == 0 ? _O_TEXT : _O_BINARY);
-
#else
int code = setmode(fileno(pfile), binary == 0 ? O_TEXT : O_BINARY);
-
#endif
+
return (code == -1 ? -1 : 0);
}
diff --git a/gs/src/gp_os2.c b/gs/src/gp_os2.c
index 7d3645531..3da014af7 100644
--- a/gs/src/gp_os2.c
+++ b/gs/src/gp_os2.c
@@ -794,6 +794,7 @@ gp_fopen(const char *fname, const char *mode)
/* Forward references */
private stream_proc_process(pm_std_read_process);
private stream_proc_process(pm_std_write_process);
+private stream_proc_available(pm_std_available);
/* Use a pseudo IODevice to get pm_stdio_init called at the right time. */
/* This is bad architecture; we'll fix it later. */
@@ -831,6 +832,7 @@ pm_stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
return code;
s->procs.reset = pm_std_read_reset;
s->procs.process = pm_std_read_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -847,6 +849,7 @@ pm_stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
if (code != 1)
return code;
s->procs.process = pm_std_write_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -863,6 +866,7 @@ pm_stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
if (code != 1)
return code;
s->procs.process = pm_std_write_process;
+ s->procs.available = win_std_available;
s->file = NULL;
return 0;
}
@@ -913,6 +917,14 @@ pm_std_read_process(stream_state * st, stream_cursor_read * ignore_pr,
}
private int
+pm_std_available(register stream * s, long *pl)
+{
+ *pl = -1; // EOF, since we can't do it
+ return 0; // OK
+}
+
+
+private int
pm_std_write_process(stream_state * st, stream_cursor_read * pr,
stream_cursor_write * ignore_pw, bool last)
{
diff --git a/gs/src/gp_strdl.c b/gs/src/gp_strdl.c
new file mode 100644
index 000000000..80188f4f6
--- /dev/null
+++ b/gs/src/gp_strdl.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Default, stream-based readline implementation */
+#include "std.h"
+#include "gstypes.h"
+#include "gsmemory.h"
+#include "gp.h"
+
+int
+gp_readline_init(void **preadline_data, gs_memory_t * mem)
+{
+ return 0;
+}
+
+int
+gp_readline(stream *s_in, stream *s_out, void *readline_data,
+ gs_const_string *prompt, gs_string * buf,
+ gs_memory_t * bufmem, uint * pcount, bool *pin_eol,
+ bool (*is_stdin)(P1(const stream *)))
+{
+ return sreadline(s_in, s_out, readline_data, prompt, buf, bufmem, pcount,
+ pin_eol, is_stdin);
+}
+
+void
+gp_readline_finit(void *readline_data)
+{
+}
diff --git a/gs/src/gp_vms.c b/gs/src/gp_vms.c
index 30eec3c9d..ac6dbe949 100644
--- a/gs/src/gp_vms.c
+++ b/gs/src/gp_vms.c
@@ -21,8 +21,10 @@
#include "string_.h"
#include "gx.h"
#include "gp.h"
+#include "gsstruct.h"
#include <stat.h>
-#include <stdlib.h> /* for exit() */
+#include <stdlib.h> /* for exit() with some compiler versions */
+#include <errno.h> /* for exit() with other compiler versions */
#include <unixio.h>
extern char *getenv(P1(const char *));
@@ -338,8 +340,7 @@ gp_free_enumeration(file_enum * pfen)
/* Begin an enumeration. See gp.h for details. */
file_enum *
-gp_enumerate_files_init(const char *pat, uint patlen,
- gs_memory_t * memory)
+gp_enumerate_files_init(const char *pat, uint patlen, gs_memory_t * mem)
{
file_enum *pfen;
uint i, len;
diff --git a/gs/src/gp_win32.c b/gs/src/gp_win32.c
index 3b14e033b..5ec1dc09f 100644
--- a/gs/src/gp_win32.c
+++ b/gs/src/gp_win32.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,7 +19,7 @@
/* Common platform-specific routines for MS-Windows WIN32 */
/* originally hacked from gp_msdos.c by Russell Lang */
-/* original multi-threading code by John Desrosiers */
+#include "malloc_.h"
#include "stdio_.h"
#include "string_.h" /* for strerror */
#include "dos_.h"
@@ -28,7 +28,6 @@
#include "gserror.h"
#include "gserrors.h"
#include "gp.h"
-#include "gpsync.h"
#include "windows_.h"
/* ------ Miscellaneous ------ */
@@ -119,194 +118,3 @@ const char gp_null_file_name[] = "nul";
/* Define the name that designates the current directory. */
const char gp_current_directory_name[] = ".";
-
-/* ------- Synchronization primitives -------- */
-
-/* Semaphore supports wait/signal semantics */
-
-typedef struct win32_semaphore_s {
- HANDLE handle; /* returned from CreateSemaphore */
-} win32_semaphore;
-
-uint
-gp_semaphore_sizeof(void)
-{
- return sizeof(win32_semaphore);
-}
-
-int /* if sema <> 0 rets -ve error, 0 ok; if sema == 0, 0 movable, 1 fixed */
-gp_semaphore_open(
- gp_semaphore * sema /* create semaphore here */
-)
-{
- win32_semaphore *const winSema = (win32_semaphore *)sema;
-
- if (winSema) {
- winSema->handle = CreateSemaphore(NULL, 0, max_int, NULL);
- return
- (winSema->handle != NULL ? 0 :
- gs_note_error(gs_error_unknownerror));
- } else
- return 0; /* Win32 semaphores handles may be moved */
-}
-
-int
-gp_semaphore_close(
- gp_semaphore * sema /* semaphore to affect */
-)
-{
- win32_semaphore *const winSema = (win32_semaphore *)sema;
-
- if (winSema->handle != NULL)
- CloseHandle(winSema->handle);
- winSema->handle = NULL;
- return 0;
-}
-
-int /* rets 0 ok, -ve error */
-gp_semaphore_wait(
- gp_semaphore * sema /* semaphore to affect */
-)
-{
- win32_semaphore *const winSema = (win32_semaphore *)sema;
-
- return
- (WaitForSingleObject(winSema->handle, INFINITE) == WAIT_OBJECT_0
- ? 0 : gs_error_unknownerror);
-}
-
-int /* rets 0 ok, -ve error */
-gp_semaphore_signal(
- gp_semaphore * sema /* semaphore to affect */
-)
-{
- win32_semaphore *const winSema = (win32_semaphore *)sema;
-
- return
- (ReleaseSemaphore(winSema->handle, 1, NULL) ? 0 :
- gs_error_unknownerror);
-}
-
-
-/* Monitor supports enter/leave semantics */
-
-typedef struct win32_monitor_s {
- CRITICAL_SECTION lock; /* critical section lock */
-} win32_monitor;
-
-uint
-gp_monitor_sizeof(void)
-{
- return sizeof(win32_monitor);
-}
-
-int /* if sema <> 0 rets -ve error, 0 ok; if sema == 0, 0 movable, 1 fixed */
-gp_monitor_open(
- gp_monitor * mon /* create monitor here */
-)
-{
- win32_monitor *const winMon = (win32_monitor *)mon;
-
- if (mon) {
- InitializeCriticalSection(&winMon->lock); /* returns no status */
- return 0;
- } else
- return 1; /* Win32 critical sections mutsn't be moved */
-}
-
-int
-gp_monitor_close(
- gp_monitor * mon /* monitor to affect */
-)
-{
- win32_monitor *const winMon = (win32_monitor *)mon;
-
- DeleteCriticalSection(&winMon->lock); /* rets no status */
- return 0;
-}
-
-int /* rets 0 ok, -ve error */
-gp_monitor_enter(
- gp_monitor * mon /* monitor to affect */
-)
-{
- win32_monitor *const winMon = (win32_monitor *)mon;
-
- EnterCriticalSection(&winMon->lock); /* rets no status */
- return 0;
-}
-
-int /* rets 0 ok, -ve error */
-gp_monitor_leave(
- gp_monitor * mon /* monitor to affect */
-)
-{
- win32_monitor *const winMon = (win32_monitor *)mon;
-
- LeaveCriticalSection(&winMon->lock); /* rets no status */
- return 0;
-}
-
-/* --------- Thread primitives ---------- */
-
-typedef struct gp_thread_creation_closure_s {
- gp_thread_creation_callback_t function; /* function to start */
- void *data; /* magic data to pass to thread */
-} gp_thread_creation_closure;
-
-/* Origin of new threads started by gp_create_thread */
-#ifndef __WATCOMC__
-private DWORD WINAPI
-#else
-private void
-#endif
-gp_thread_begin_wrapper(
- void *thread_data /* gp_thread_creation_closure passed as magic data */
-)
-{
- gp_thread_creation_closure closure =
- *(gp_thread_creation_closure *)thread_data;
-
- free(thread_data);
- (*closure.function)(closure.data);
- _endthread();
-#ifndef __WATCOMC__
- return 0;
-#endif
-}
-
-/* Call a function on a brand new thread */
-int /* 0 ok, -ve error */
-gp_create_thread(
- gp_thread_creation_callback_t function, /* function to start */
- void *data /* magic data to pass to thread fn */
-)
-{
- /* Create the magic closure that thread_wrapper gets passed */
- gp_thread_creation_closure *closure =
- (gp_thread_creation_closure *)malloc(sizeof(*closure));
-
- if (!closure)
- return gs_error_VMerror;
- closure->function = function;
- closure->data = data;
-
- /*
- * Start thread_wrapper.
- * The Watcom _beginthread returns (int)(-1) if the call fails.
- * The Microsoft _beginthread returns -1 (according to the doc, even
- * though the return type is "unsigned long" !!!) if the call fails;
- * we aren't sure what the Borland _beginthread returns.
- * The hack with ~ avoids a source code commitment as to whether the
- * return type is [u]int or [u]long.
- */
-#ifndef __WATCOMC__
- if (~_beginthread(gp_thread_begin_wrapper, 0, closure) != 0)
- return 0;
-#else /* for Watcom there is an extra (optional) stack base parameter == NULL */
- if (_beginthread(gp_thread_begin_wrapper, NULL, 0, closure) != -1)
- return 0;
-#endif
-
- return_error(gs_error_unknownerror);
-}
diff --git a/gs/src/gp_wsync.c b/gs/src/gp_wsync.c
new file mode 100644
index 000000000..e56131de0
--- /dev/null
+++ b/gs/src/gp_wsync.c
@@ -0,0 +1,208 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* MS Windows (Win32) thread / semaphore / monitor implementation */
+/* original multi-threading code by John Desrosiers */
+#include "malloc_.h"
+#include "gserror.h"
+#include "gserrors.h"
+#include "gpsync.h"
+#include "windows_.h"
+#include <process.h>
+
+/* ------- Synchronization primitives -------- */
+
+/* Semaphore supports wait/signal semantics */
+
+typedef struct win32_semaphore_s {
+ HANDLE handle; /* returned from CreateSemaphore */
+} win32_semaphore;
+
+uint
+gp_semaphore_sizeof(void)
+{
+ return sizeof(win32_semaphore);
+}
+
+int /* if sema <> 0 rets -ve error, 0 ok; if sema == 0, 0 movable, 1 fixed */
+gp_semaphore_open(
+ gp_semaphore * sema /* create semaphore here */
+)
+{
+ win32_semaphore *const winSema = (win32_semaphore *)sema;
+
+ if (winSema) {
+ winSema->handle = CreateSemaphore(NULL, 0, max_int, NULL);
+ return
+ (winSema->handle != NULL ? 0 :
+ gs_note_error(gs_error_unknownerror));
+ } else
+ return 0; /* Win32 semaphores handles may be moved */
+}
+
+int
+gp_semaphore_close(
+ gp_semaphore * sema /* semaphore to affect */
+)
+{
+ win32_semaphore *const winSema = (win32_semaphore *)sema;
+
+ if (winSema->handle != NULL)
+ CloseHandle(winSema->handle);
+ winSema->handle = NULL;
+ return 0;
+}
+
+int /* rets 0 ok, -ve error */
+gp_semaphore_wait(
+ gp_semaphore * sema /* semaphore to affect */
+)
+{
+ win32_semaphore *const winSema = (win32_semaphore *)sema;
+
+ return
+ (WaitForSingleObject(winSema->handle, INFINITE) == WAIT_OBJECT_0
+ ? 0 : gs_error_unknownerror);
+}
+
+int /* rets 0 ok, -ve error */
+gp_semaphore_signal(
+ gp_semaphore * sema /* semaphore to affect */
+)
+{
+ win32_semaphore *const winSema = (win32_semaphore *)sema;
+
+ return
+ (ReleaseSemaphore(winSema->handle, 1, NULL) ? 0 :
+ gs_error_unknownerror);
+}
+
+
+/* Monitor supports enter/leave semantics */
+
+typedef struct win32_monitor_s {
+ CRITICAL_SECTION lock; /* critical section lock */
+} win32_monitor;
+
+uint
+gp_monitor_sizeof(void)
+{
+ return sizeof(win32_monitor);
+}
+
+int /* if sema <> 0 rets -ve error, 0 ok; if sema == 0, 0 movable, 1 fixed */
+gp_monitor_open(
+ gp_monitor * mon /* create monitor here */
+)
+{
+ win32_monitor *const winMon = (win32_monitor *)mon;
+
+ if (mon) {
+ InitializeCriticalSection(&winMon->lock); /* returns no status */
+ return 0;
+ } else
+ return 1; /* Win32 critical sections mutsn't be moved */
+}
+
+int
+gp_monitor_close(
+ gp_monitor * mon /* monitor to affect */
+)
+{
+ win32_monitor *const winMon = (win32_monitor *)mon;
+
+ DeleteCriticalSection(&winMon->lock); /* rets no status */
+ return 0;
+}
+
+int /* rets 0 ok, -ve error */
+gp_monitor_enter(
+ gp_monitor * mon /* monitor to affect */
+)
+{
+ win32_monitor *const winMon = (win32_monitor *)mon;
+
+ EnterCriticalSection(&winMon->lock); /* rets no status */
+ return 0;
+}
+
+int /* rets 0 ok, -ve error */
+gp_monitor_leave(
+ gp_monitor * mon /* monitor to affect */
+)
+{
+ win32_monitor *const winMon = (win32_monitor *)mon;
+
+ LeaveCriticalSection(&winMon->lock); /* rets no status */
+ return 0;
+}
+
+/* --------- Thread primitives ---------- */
+
+typedef struct gp_thread_creation_closure_s {
+ gp_thread_creation_callback_t function; /* function to start */
+ void *data; /* magic data to pass to thread */
+} gp_thread_creation_closure;
+
+/* Origin of new threads started by gp_create_thread */
+private void
+gp_thread_begin_wrapper(
+ void *thread_data /* gp_thread_creation_closure passed as magic data */
+)
+{
+ gp_thread_creation_closure closure;
+
+ closure = *(gp_thread_creation_closure *)thread_data;
+ free(thread_data);
+ (*closure.function)(closure.data);
+ _endthread();
+}
+
+/* Call a function on a brand new thread */
+int /* 0 ok, -ve error */
+gp_create_thread(
+ gp_thread_creation_callback_t function, /* function to start */
+ void *data /* magic data to pass to thread fn */
+)
+{
+ /* Create the magic closure that thread_wrapper gets passed */
+ gp_thread_creation_closure *closure =
+ (gp_thread_creation_closure *)malloc(sizeof(*closure));
+
+ if (!closure)
+ return gs_error_VMerror;
+ closure->function = function;
+ closure->data = data;
+
+ /*
+ * Start thread_wrapper. The Watcom _beginthread returns (int)(-1) if
+ * the call fails. The Microsoft _beginthread returns -1 (according to
+ * the doc, even though the return type is "unsigned long" !!!) if the
+ * call fails; we aren't sure what the Borland _beginthread returns.
+ * The hack with ~ avoids a source code commitment as to whether the
+ * return type is [u]int or [u]long.
+ *
+ * BEGIN_THREAD is a macro (defined in windows_.h) because _beginthread
+ * takes different arguments in Watcom C.
+ */
+ if (~BEGIN_THREAD(gp_thread_begin_wrapper, 0, closure) != 0)
+ return 0;
+ return_error(gs_error_unknownerror);
+}
+
diff --git a/gs/src/gpsync.h b/gs/src/gpsync.h
index 589e2c4be..bce2bb2f2 100644
--- a/gs/src/gpsync.h
+++ b/gs/src/gpsync.h
@@ -20,7 +20,7 @@
/* Interface to platform-dependent synchronization primitives */
#if !defined(gpsync_INCLUDED)
- #define 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
diff --git a/gs/src/gs.c b/gs/src/gs.c
index 09e022a1e..fde1a60ce 100644
--- a/gs/src/gs.c
+++ b/gs/src/gs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -60,8 +60,11 @@ main(int argc, char *argv[])
zflush(osp);
fprintf(stdout, " => code = %d\n", code);
fflush(stdout);
- if (code < 0)
+ if (code < 0) {
gs_exit(1);
+ /* NOTREACHED */
+ return 1; /* pacify compilers */
+ }
}
}
#endif
@@ -71,4 +74,5 @@ main(int argc, char *argv[])
gs_exit(0); /* exit */
/* NOTREACHED */
+ return 0; /* pacify compilers */
}
diff --git a/gs/src/gs.mak b/gs/src/gs.mak
index d10c41f3d..6e3ea09f9 100644
--- a/gs/src/gs.mak
+++ b/gs/src/gs.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -41,9 +41,9 @@
# PSRCDIR, PVERSION - the same for libpng.
# ZSRCDIR - the same for zlib.
# SHARE_JPEG - normally 0; if set to 1, asks the linker to use
-# an existing compiled libpng (-ljpeg) instead of compiling and
-# linking libpng explicitly. (We strongly recommend against
-# doing this: see make.txt details.)
+# an existing compiled libjpeg (-ljpeg) instead of compiling and
+# linking libjpeg explicitly. (We strongly recommend against
+# doing this: see Make.htm details.)
# JPEG_NAME - the name of the shared library, currently always
# jpeg (libjpeg, -lpjeg).
# SHARE_LIBPNG - normally 0; if set to 1, asks the linker to use
@@ -56,19 +56,15 @@
# and linking libgz/libz explicitly.
# ZLIB_NAME - the name of the shared zlib, either gz (for libgz, -lgz)
# or z (for libz, -lz).
-# CONFIG - a configuration ID, added at the request of a customer,
-# that is supposed to help in maintaining multiple variants in
-# a single directory. Normally this is an empty string;
-# it may be any string that is legal as part of a file name.
# DEVICE_DEVS - the devices to include in the executable.
# See devs.mak for details.
-# DEVICE_DEVS1...DEVICE_DEVS15 - additional devices, if the definition
+# DEVICE_DEVS1...DEVICE_DEVS20 - additional devices, if the definition
# of DEVICE_DEVS doesn't fit on one line. See devs.mak for details.
# FEATURE_DEVS - what features to include in the executable.
# Normally this is one of:
-# psl1 - a PostScript Level 1 language interpreter.
-# psl2 - a PostScript Level 2 language interpreter.
-# psl3 - a PostScript LanguageLevel 3 language
+# $(PSD)psl1.dev - a PostScript Level 1 language interpreter.
+# $(PSD)psl2.dev - a PostScript Level 2 language interpreter.
+# $(PSD)psl3.dev - a PostScript LanguageLevel 3 language
# interpreter.
# and/or
# pdf - a PDF 1.2 interpreter.
@@ -78,7 +74,7 @@
# The following feature may be added to any of the standard
# configurations:
# ccfonts - precompile fonts into C, and link them
-# with the executable. See fonts.txt for details.
+# with the executable. See Fonts.htm for details.
# The remaining features are of interest primarily to developers
# who want to "mix and match" features to create custom
# configurations:
@@ -92,7 +88,7 @@
# dct - support for DCTEncode/Decode filters.
# Included automatically in the psl2 feature.
# dps - (partial) support for Display PostScript extensions:
-# see language.txt for details.
+# see Language.htm for details.
# dpsnext - (partial) support for Display PostScript
# extensions with NeXT's additions.
# epsf - support for recognizing and skipping the binary
@@ -146,7 +142,7 @@
# CMD - the suffix for shell command files (e.g., null or .bat).
# (This is only needed in a few places.)
# D - the directory separator character (\ for MS-DOS, / for Unix).
-# O - the string for specifying the output file from the C compiler
+# O_ - the string for specifying the output file from the C compiler
# (-o for MS-DOS, -o ./ for Unix).
# OBJ - the extension for relocatable object files (e.g., o or obj).
# XE - the extension for executable files (e.g., null or .exe).
@@ -159,7 +155,7 @@
# one that doesn't use ANSI C syntax. (It is only needed if
# the main C compiler also isn't an ANSI compiler.)
# CCAUX - the C invocation for auxiliary programs (echogs, genarch,
-# genconf, gendev, geninit).
+# genconf, gendev, genht, geninit).
# CC_ - the C invocation for normal compilation.
# CCD - the C invocation for files that store into frame buffers or
# device registers. Needed because some optimizing compilers
@@ -176,10 +172,8 @@
# this is $(ANSI2KNR_XE); if not, it is null.
# If a particular platform requires other utility programs
# to be built, AK must include them too.
-# SHP - the prefix for invoking a shell script in the current directory
-# (null for MS-DOS, $(SH) ./ for Unix).
-# EXPP, EXP - the prefix for invoking an executable program in the
-# current directory (null for MS-DOS, ./ for Unix).
+# EXP - the prefix for invoking an executable program in a specified
+# directory (MCR on OpenVMS, null on all other platforms).
# SH - the shell for scripts (null on MS-DOS, sh on Unix).
# CONFILES - the arguments for genconf to generate the appropriate
# linker control files (various).
@@ -211,16 +205,18 @@ PNGGENDIR=$(GLGENDIR)
PNGOBJDIR=$(GLOBJDIR)
ZGENDIR=$(GLGENDIR)
ZOBJDIR=$(GLOBJDIR)
-GLSRC=$(GLSRCDIR)$(D)
-GLGEN=$(GLGENDIR)$(D)
-GLOBJ=$(GLOBJDIR)$(D)
#**************** END PATCHES
+GSGEN=$(GLGENDIR)$(D)
+GSOBJ=$(GLOBJDIR)$(D)
+# All top-level makefiles define DD.
+#DD=$(GLGEN)
+
# Define the name of this makefile.
-GS_MAK=$(GLSRC)gs.mak
+GS_MAK=$(GLSRCDIR)$(D)gs.mak
# Define the names of the executables.
-GS_XE=$(GLOBJ)$(GS)$(XE)
+GS_XE=$(BINDIR)$(D)$(GS)$(XE)
AUXGENDIR=$(GLGENDIR)
AUXGEN=$(AUXGENDIR)$(D)
ANSI2KNR_XE=$(AUXGEN)ansi2knr$(XEAUX)
@@ -228,81 +224,84 @@ ECHOGS_XE=$(AUXGEN)echogs$(XEAUX)
GENARCH_XE=$(AUXGEN)genarch$(XEAUX)
GENCONF_XE=$(AUXGEN)genconf$(XEAUX)
GENDEV_XE=$(AUXGEN)gendev$(XEAUX)
+GENHT_XE=$(AUXGEN)genht$(XEAUX)
GENINIT_XE=$(AUXGEN)geninit$(XEAUX)
-# Define the names of the CONFIG-dependent header files.
+# Define the names of the generated header files.
# gconfig*.h and gconfx*.h are generated dynamically.
-gconfig_h=$(GLGEN)gconfxx$(CONFIG).h
-gconfigf_h=$(GLGEN)gconfxc$(CONFIG).h
+gconfig_h=$(GLGENDIR)$(D)gconfxx.h
+gconfigf_h=$(GLGENDIR)$(D)gconfxc.h
-# Watcom make insists that rules have a non-empty body!
-all default: $(GS_XE)
- $(RM_) _temp_*
+all default : $(GS_XE)
+ $(NO_OP)
-distclean maintainer-clean realclean: clean
- $(RM_) makefile
+#****** ON UNIX PLATFORMS, SHOULD REMOVE `makefile' ******
+distclean maintainer-clean realclean : clean
+ $(NO_OP)
-clean: mostlyclean
- $(RM_) $(GLGEN)arch.h
+clean : mostlyclean
+ $(RM_) $(GSGEN)arch.h
$(RM_) $(GS_XE)
#****** FOLLOWING IS WRONG, NEEDS TO BE PER-SUBSYSTEM ******
-mostlyclean: config-clean
- $(RMN_) $(GLOBJ)*.$(OBJ) $(GLOBJ)*.a $(GLOBJ)core $(GLOBJ)gmon.out
- $(RMN_) $(GLGEN)deflate.h $(GLGEN)zutil.h
- $(RMN_) $(GLGEN)gconfig*.c $(GLGEN)gscdefs*.c $(GLGEN)iconfig*.c
- $(RMN_) $(GLGEN)_temp_* $(GLGEN)_temp_*.* $(GLOBJ)*.map $(GLOBJ)*.sym
+mostlyclean : config-clean
+ $(RMN_) $(GSOBJ)*.$(OBJ) $(GSOBJ)*.a $(GSOBJ)core $(GSOBJ)gmon.out
+ $(RMN_) $(GSGEN)deflate.h $(GSGEN)zutil.h
+ $(RMN_) $(GSGEN)gconfig*.c $(GSGEN)gscdefs*.c $(GSGEN)iconfig*.c
+ $(RMN_) $(GSGEN)_temp_* $(GSGEN)_temp_*.* $(GSOBJ)*.map $(GSOBJ)*.sym
$(RMN_) $(ANSI2KNR_XE) $(ECHOGS_XE)
- $(RMN_) $(GENARCH_XE) $(GENCONF_XE) $(GENDEV_XE) $(GENINIT_XE)
- $(RMN_) $(GLGEN)gs_init.c $(BEGINFILES)
+ $(RMN_) $(GENARCH_XE) $(GENCONF_XE) $(GENDEV_XE) $(GENHT_XE) $(GENINIT_XE)
+ $(RMN_) $(GSGEN)gs_init.c $(BEGINFILES)
# Remove only configuration-dependent information.
#****** FOLLOWING IS WRONG, NEEDS TO BE PER-SUBSYSTEM ******
-#****** rm *.dev IS WRONG ******
-config-clean:
- $(RMN_) *.dev
- $(RMN_) $(GLGEN)*.dev $(GLGEN)devs*.tr $(GLGEN)gconfig*.h
- $(RMN_) $(GLGEN)gconfx*.h $(GLGEN)j*.h
- $(RMN_) $(GLGEN)c*.tr $(GLGEN)o*.tr $(GLGEN)l*.tr
+config-clean :
+ $(RMN_) $(GSGEN)*.dev $(GSGEN)devs*.tr $(GSGEN)gconfig*.h
+ $(RMN_) $(GSGEN)gconfx*.h $(GSGEN)j*.h
+ $(RMN_) $(GSGEN)c*.tr $(GSGEN)o*.tr $(GSGEN)l*.tr
# A rule to do a quick and dirty compilation attempt when first installing
# the interpreter. Many of the compilations will fail:
# follow this with 'make'.
#****** FOLLOWING IS WRONG, TIED TO INTERPRETER ******
-begin:
- $(RMN_) $(GLGEN)arch.h $(GLGEN)gconfig*.h $(GLGEN)gconfx*.h
+begin :
+ $(RMN_) $(GSGEN)arch.h $(GSGEN)gconfig*.h $(GSGEN)gconfx*.h
$(RMN_) $(GENARCH_XE) $(GS_XE)
- $(RMN_) $(GLGEN)gconfig*.c $(GLGEN)gscdefs*.c $(GLGEN)iconfig*.c
- $(RMN_) $(GLGEN)gs_init.c $(BEGINFILES)
- make $(GLGEN)arch.h $(GLGEN)gconfigv.h
+ $(RMN_) $(GSGEN)gconfig*.c $(GSGEN)gscdefs*.c $(GSGEN)iconfig*.c
+ $(RMN_) $(GSGEN)gs_init.c $(BEGINFILES)
+ make $(GSGEN)arch.h $(GSGEN)gconfigv.h
- $(CCBEGIN)
- $(RMN_) $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gdev*.$(OBJ)
- $(RMN_) $(GLOBJ)gp_*.$(OBJ) $(GLOBJ)gscdefs.$(OBJ) $(GLOBJ)gsmisc.$(OBJ)
+ $(RMN_) $(GSOBJ)gconfig.$(OBJ) $(GSOBJ)gdev*.$(OBJ)
+ $(RMN_) $(GSOBJ)gp_*.$(OBJ) $(GSOBJ)gscdefs.$(OBJ) $(GSOBJ)gsmisc.$(OBJ)
$(RMN_) $(PSOBJ)icfontab.$(OBJ) $(PSOBJ)iconfig.$(OBJ)
$(RMN_) $(PSOBJ)iinit.$(OBJ) $(PSOBJ)interp.$(OBJ)
# Macros for constructing the *.dev files that describe features and
# devices.
-SETDEV=$(ECHOGS_XE) -e .dev -w- -l-dev -F -s -l-obj
-SETPDEV=$(ECHOGS_XE) -e .dev -w- -l-dev -F -s -l-include -lpage -l-obj
-SETDEV2=$(ECHOGS_XE) -e .dev -w- -l-dev2 -F -s -l-obj
-SETPDEV2=$(ECHOGS_XE) -e .dev -w- -l-dev2 -F -s -l-include -lpage -l-obj
-SETMOD=$(ECHOGS_XE) -e .dev -w- -l-obj
-ADDMOD=$(ECHOGS_XE) -e .dev -a-
+SETDEV=$(EXP)$(ECHOGS_XE) -e .dev -w- -l-dev -b -s -l-obj
+SETPDEV=$(EXP)$(ECHOGS_XE) -e .dev -w- -l-dev -b -s -l-include -l$(GLGENDIR)$(D)page -l-obj
+SETDEV2=$(EXP)$(ECHOGS_XE) -e .dev -w- -l-dev2 -b -s -l-obj
+SETPDEV2=$(EXP)$(ECHOGS_XE) -e .dev -w- -l-dev2 -b -s -l-include -l$(GLGENDIR)$(D)page -l-obj
+SETMOD=$(EXP)$(ECHOGS_XE) -e .dev -w- -l-obj
+ADDMOD=$(EXP)$(ECHOGS_XE) -e .dev -a- $(NULL)
# Define the search lists and compilation switches for the third-party
-# libraries. The search lists must be enclosed in $(I_) and $(_I).
+# libraries, and the compilation switches for their clients.
+# The search lists must be enclosed in $(I_) and $(_I).
# Note that we can't define the entire compilation command,
# because this must include $(GLSRCDIR), which isn't defined yet.
JI_=$(JSRCDIR)
JF_=
+JCF_=$(D_)SHARE_JPEG=$(SHARE_JPEG)
PI_=$(PSRCDIR) $(II)$(ZSRCDIR)
# PF_ should include PNG_USE_CONST, but this doesn't work.
#PF_=-DPNG_USE_CONST
PF_=
+PCF_=$(D_)SHARE_LIBPNG=$(SHARE_LIBPNG)
ZI_=$(ZSRCDIR)
ZF_=
+ZCF_=$(D_)SHARE_ZLIB=$(SHARE_ZLIB)
######################## How to define new 'features' #######################
#
@@ -311,20 +310,23 @@ ZF_=
# gs.mak:
#
# abc_=abc1.$(OBJ) ...
-# abc.dev: $(GS_MAK) $(ECHOGS_XE) $(abc_)
-# $(SETMOD) abc $(abc_)
-# $(ADDMOD) abc -obj ... [if needed]
-# $(ADDMOD) abc -oper ... [if appropriate]
-# $(ADDMOD) abc -ps ... [if appropriate]
+# $(PSD)abc.dev : $(GS_MAK) $(ECHOGS_XE) $(abc_)
+# $(SETMOD) $(PSD)abc $(abc_)
+# $(ADDMOD) $(PSD)abc -obj ... [if needed]
+# $(ADDMOD) $(PSD)abc -oper ... [if appropriate]
+# $(ADDMOD) $(PSD)abc -ps ... [if appropriate]
#
+# Use PSD for interpreter-related features, GLD for library-related.
# If the abc feature requires the presence of some other features jkl and
# pqr, then the rules must look like this:
#
# abc_=abc1.$(OBJ) ...
-# abc.dev: $(GS_MAK) $(ECHOGS_XE) $(abc_) jkl.dev pqr.dev
-# $(SETMOD) abc $(abc_)
+# $(PSD)abc.dev : $(GS_MAK) $(ECHOGS_XE) $(abc_)\
+# $(PSD)jkl.dev $(PSD)pqr.dev
+# $(SETMOD) $(PSD)abc $(abc_)
# ...
-# $(ADDMOD) abc -include jkl pqr
+# $(ADDMOD) $(PSD)abc -include $(PSD)jkl
+# $(ADDMOD) $(PSD)abc -include $(PSD)pqr
# --------------------- Configuration-dependent files --------------------- #
@@ -334,47 +336,62 @@ ZF_=
# FEATURE_DEVS must precede DEVICE_DEVS so that devices can override
# features in obscure cases.
-DEVS_ALL=$(PLATFORM).dev $(FEATURE_DEVS) \
- $(DEVICE_DEVS) $(DEVICE_DEVS1) \
- $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5) \
- $(DEVICE_DEVS6) $(DEVICE_DEVS7) $(DEVICE_DEVS8) $(DEVICE_DEVS9) \
- $(DEVICE_DEVS10) $(DEVICE_DEVS11) $(DEVICE_DEVS12) $(DEVICE_DEVS13) \
- $(DEVICE_DEVS14) $(DEVICE_DEVS15)
+# FEATURE_DEVS_EXTRA and DEVICE_DEVS_EXTRA are explicitly reserved
+# to be set from the command line.
+FEATURE_DEVS_EXTRA=
+DEVICE_DEVS_EXTRA=
+
+DEVS_ALL=$(GLGENDIR)$(D)$(PLATFORM).dev\
+ $(FEATURE_DEVS) $(FEATURE_DEVS_EXTRA) \
+ $(DEVICE_DEVS) $(DEVICE_DEVS1) \
+ $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5) \
+ $(DEVICE_DEVS6) $(DEVICE_DEVS7) $(DEVICE_DEVS8) $(DEVICE_DEVS9) \
+ $(DEVICE_DEVS10) $(DEVICE_DEVS11) $(DEVICE_DEVS12) $(DEVICE_DEVS13) \
+ $(DEVICE_DEVS14) $(DEVICE_DEVS15) $(DEVICE_DEVS16) $(DEVICE_DEVS17) \
+ $(DEVICE_DEVS18) $(DEVICE_DEVS19) $(DEVICE_DEVS20) $(DEVICE_DEVS_EXTRA)
-devs_tr=$(GLGEN)devs.tr$(CONFIG)
-$(devs_tr): $(GS_MAK) $(MAKEFILE) $(ECHOGS_XE)
- $(ECHOGS_XE) -w $(devs_tr) - -include $(PLATFORM).dev
- $(ECHOGS_XE) -a $(devs_tr) - $(FEATURE_DEVS)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS1)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS2)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS3)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS4)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS5)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS6)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS7)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS8)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS9)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS10)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS11)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS12)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS13)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS14)
- $(ECHOGS_XE) -a $(devs_tr) - $(DEVICE_DEVS15)
+devs_tr=$(GLGENDIR)$(D)devs.tr
+$(devs_tr) : $(GS_MAK) $(TOP_MAKEFILES) $(ECHOGS_XE)
+ $(EXP)$(ECHOGS_XE) -w $(devs_tr) - -include $(GLGENDIR)$(D)$(PLATFORM)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(FEATURE_DEVS)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(FEATURE_DEVS_EXTRA)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS1)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS2)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS3)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS4)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS5)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS6)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS7)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS8)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS9)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS10)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS11)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS12)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS13)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS14)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS15)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS16)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS17)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS18)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS19)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS20)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS_EXTRA)
+ $(EXP)$(ECHOGS_XE) -a $(devs_tr) - $(GLGENDIR)$(D)libcore
# GCONFIG_EXTRAS can be set on the command line.
# Note that it consists of arguments for echogs, i.e.,
# it isn't just literal text.
GCONFIG_EXTRAS=
-ld_tr=$(GLGEN)ld$(CONFIG).tr
-$(gconfig_h) $(ld_tr) $(GLGEN)lib.tr: \
- $(GS_MAK) $(MAKEFILE) $(GLSRC)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(devs_tr) $(DEVS_ALL) libcore.dev
- $(GENCONF_XE) $(devs_tr) libcore.dev -h $(gconfig_h) $(CONFILES) $(CONFLDTR) $(ld_tr)
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_LIB_DEFAULT -x 2022 $(GS_LIB_DEFAULT) -x 22
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u SEARCH_HERE_FIRST -s $(SEARCH_HERE_FIRST)
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_DOCDIR -x 2022 $(GS_DOCDIR) -x 22
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_INIT -x 2022 $(GS_INIT) -x 22
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_REVISION -s $(GS_REVISION)
- $(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_REVISIONDATE -s $(GS_REVISIONDATE)
- $(ECHOGS_XE) -a $(gconfig_h) $(GCONFIG_EXTRAS)
+ld_tr=$(GLGENDIR)$(D)ld.tr
+$(gconfig_h) $(ld_tr) $(GLGENDIR)$(D)lib.tr : \
+ $(GS_MAK) $(TOP_MAKEFILES) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(devs_tr) $(DEVS_ALL) $(GLGENDIR)$(D)libcore.dev
+ $(EXP)$(GENCONF_XE) $(devs_tr) -h $(gconfig_h) $(CONFILES) $(CONFLDTR) $(ld_tr)
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_LIB_DEFAULT -x 2022 $(GS_LIB_DEFAULT) -x 22
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u SEARCH_HERE_FIRST -s $(SEARCH_HERE_FIRST)
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_DOCDIR -x 2022 $(GS_DOCDIR) -x 22
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_INIT -x 2022 $(GS_INIT) -x 22
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_REVISION -s $(GS_REVISION)
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) -x 23 define -s -u GS_REVISIONDATE -s $(GS_REVISIONDATE)
+ $(EXP)$(ECHOGS_XE) -a $(gconfig_h) $(GCONFIG_EXTRAS)
diff --git a/gs/src/gs16spl.rc b/gs/src/gs16spl.rc
index 2513a0dc7..eb7693f16 100644
--- a/gs/src/gs16spl.rc
+++ b/gs/src/gs16spl.rc
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, Russell Lang. All rights reserved.
+/* Copyright (C) 1995, 1999, Russell Lang. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,7 +24,11 @@
#define ID_TEXT 100
-1 ICON "gstext.ico"
+#ifndef gstext_ico
+#define gstext_ico gstext.ico
+#endif
+
+1 ICON gstext_ico
SpoolDlgBox DIALOG 20, 32, 158, 56
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
diff --git a/gs/src/gsalloc.c b/gs/src/gsalloc.c
index 4fda3e84e..01d11b807 100644
--- a/gs/src/gsalloc.c
+++ b/gs/src/gsalloc.c
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Standard memory allocator */
#include "gx.h"
#include "memory_.h"
@@ -1121,14 +1121,15 @@ ialloc_consolidate_free(gs_ref_memory_t *mem)
/* The entire chunk is free. */
chunk_t *cnext = cp->cnext;
- if (!mem->is_controlled)
+ if (!mem->is_controlled) {
alloc_free_chunk(cp, mem);
- if (mem->pcc == cp)
- mem->pcc =
- (cnext == 0 ? cprev : cprev == 0 ? cnext :
- cprev->cbot - cprev->ctop >
- cnext->cbot - cnext->ctop ? cprev :
- cnext);
+ if (mem->pcc == cp)
+ mem->pcc =
+ (cnext == 0 ? cprev : cprev == 0 ? cnext :
+ cprev->cbot - cprev->ctop >
+ cnext->cbot - cnext->ctop ? cprev :
+ cnext);
+ }
}
}
alloc_open_chunk(mem);
@@ -1413,10 +1414,11 @@ alloc_init_chunk(chunk_t * cp, byte * bot, byte * top, bool has_strings,
cp->inner_count = 0;
cp->has_refs = false;
cp->sbase = cdata;
- if (has_strings && top - cdata >= string_space_quantum + sizeof(long) - 1) { /*
- * We allocate a large enough string marking and reloc table
- * to cover the entire chunk.
- */
+ if (has_strings && top - cdata >= string_space_quantum + sizeof(long) - 1) {
+ /*
+ * We allocate a large enough string marking and reloc table
+ * to cover the entire chunk.
+ */
uint nquanta = string_space_quanta(top - cdata);
cp->climit = cdata + nquanta * string_data_quantum;
@@ -1424,8 +1426,9 @@ alloc_init_chunk(chunk_t * cp, byte * bot, byte * top, bool has_strings,
cp->smark_size = string_quanta_mark_size(nquanta);
cp->sreloc =
(string_reloc_offset *) (cp->smark + cp->smark_size);
- cp->sfree1 = (ushort *) cp->sreloc;
- } else { /* No strings, don't need the string GC tables. */
+ cp->sfree1 = (uint *) cp->sreloc;
+ } else {
+ /* No strings, don't need the string GC tables. */
cp->climit = cp->cend;
cp->sfree1 = 0;
cp->smark = 0;
@@ -1441,9 +1444,7 @@ void
alloc_init_free_strings(chunk_t * cp)
{
if (cp->sfree1)
- memset(cp->sfree1, 0,
- ((cp->climit - csbase(cp) + 255) >> 8) *
- sizeof(*cp->sfree1));
+ memset(cp->sfree1, 0, STRING_FREELIST_SPACE(cp));
cp->sfree = 0;
}
diff --git a/gs/src/gsalphac.c b/gs/src/gsalphac.c
index e031c90f0..24840da98 100644
--- a/gs/src/gsalphac.c
+++ b/gs/src/gsalphac.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -261,7 +261,7 @@ private const gx_device_composite_alpha gs_composite_alpha_device =
};
/* Create an alpha compositor. */
-int
+private int
c_alpha_create_default_compositor(const gs_composite_t * pcte,
gx_device ** pcdev, gx_device * dev, const gs_imager_state * pis,
gs_memory_t * mem)
@@ -301,7 +301,7 @@ c_alpha_create_default_compositor(const gs_composite_t * pcte,
* the device to the specific num_components, but for simplicity,
* we'll defer considering that until there is a demonstrated need.
*/
- cdev->target = dev;
+ gx_device_set_target((gx_device_forward *)cdev, dev);
cdev->params = pacte->params;
return 0;
}
@@ -505,7 +505,7 @@ dca_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
GB_OFFSET_0 | GB_RASTER_ALL | GB_ALIGN_STANDARD);
native_params.data[0] = native_row;
code = gx_get_bits_copy(target, 0, w, 1, &native_params,
- std_params.options, std_row,
+ &std_params, std_row,
0 /* raster is irrelevant */ );
if (code < 0)
break;
diff --git a/gs/src/gsargs.c b/gs/src/gsargs.c
index 117547d49..346bfe796 100644
--- a/gs/src/gsargs.c
+++ b/gs/src/gsargs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,7 +41,7 @@ arg_init(arg_list * pal, const char **argv, int argc,
/* Push a string onto an arg list. */
void
-arg_push_memory_string(arg_list * pal, const char *str, gs_memory_t * mem)
+arg_push_memory_string(arg_list * pal, char *str, gs_memory_t * mem)
{
arg_source *pas;
@@ -67,7 +67,7 @@ arg_finit(arg_list * pal)
if (pas->is_file)
fclose(pas->u.file);
else if (pas->u.s.memory)
- gs_free_object(pas->u.s.memory, (void *)pas->u.s.chars, "arg_finit");
+ gs_free_object(pas->u.s.memory, pas->u.s.chars, "arg_finit");
}
}
@@ -116,7 +116,7 @@ arg_next(arg_list * pal)
if (f != NULL)
fclose(f);
else if (pas->u.s.memory)
- gs_free_object(pas->u.s.memory, (void *)pas->u.s.chars,
+ gs_free_object(pas->u.s.memory, pas->u.s.chars,
"arg_next");
pal->depth--;
goto top;
diff --git a/gs/src/gsargs.h b/gs/src/gsargs.h
index 472fb963f..e67122ea5 100644
--- a/gs/src/gsargs.h
+++ b/gs/src/gsargs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,8 @@ typedef struct arg_source_s {
bool is_file;
union _u {
struct _su {
- const char *chars; /* original string */
- gs_memory_t *memory; /* if non-0, free chars when done with it */
+ char *chars; /* original string */
+ gs_memory_t *memory; /* if non-0, free chars when done with it */
const char *str; /* string being read */
} s;
FILE *file;
@@ -62,8 +62,7 @@ void arg_init(P5(arg_list * pal, const char **argv, int argc,
* This may also be used (once) to "unread" the last argument.
* If mem != 0, it is used to free the string when we are done with it.
*/
-void arg_push_memory_string(P3(arg_list * pal, const char *str,
- gs_memory_t * mem));
+void arg_push_memory_string(P3(arg_list * pal, char *str, gs_memory_t * mem));
#define arg_push_string(pal, str)\
arg_push_memory_string(pal, str, (gs_memory_t *)0);
diff --git a/gs/src/gsbitmap.h b/gs/src/gsbitmap.h
index dd791b24b..aa829f4a6 100644
--- a/gs/src/gsbitmap.h
+++ b/gs/src/gsbitmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,7 +22,7 @@
#ifndef gsbitmap_INCLUDED
#define gsbitmap_INCLUDED
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
/*
* The Ghostscript library stores all bitmaps bit-big-endian (i.e., the 0x80
@@ -69,15 +69,18 @@ typedef gs_id gs_bitmap_id;
* If size.y > 1,
* raster >= (size.x * depth + 7) / 8
*/
-#define gs_bitmap_common \
- byte * data; /* pointer to the data */ \
+#define gs_bitmap_common(data_type) \
+ data_type * data; /* pointer to the data */ \
int raster; /* increment between scanlines, bytes */ \
gs_int_point size; /* width and height */ \
gs_bitmap_id id /* usually unused */
typedef struct gs_bitmap_s {
- gs_bitmap_common;
+ gs_bitmap_common(byte);
} gs_bitmap;
+typedef struct gs_const_bitmap_s {
+ gs_bitmap_common(const byte);
+} gs_const_bitmap;
/*
* For bitmaps used as halftone tiles, we may replicate the tile in
@@ -89,13 +92,16 @@ typedef struct gs_bitmap_s {
* since most of the library procedures that replicate tiles expect them
* to be aligned.
*/
-#define gs_tile_bitmap_common \
- gs_bitmap_common; \
+#define gs_tile_bitmap_common(data_type) \
+ gs_bitmap_common(data_type); \
ushort rep_width, rep_height /* true size of tile */
typedef struct gs_tile_bitmap_s {
- gs_tile_bitmap_common;
+ gs_tile_bitmap_common(byte);
} gs_tile_bitmap;
+typedef struct gs_const_tile_bitmap_s {
+ gs_tile_bitmap_common(const byte);
+} gs_const_tile_bitmap;
/*
* There is no "strip" version for client bitmaps, as the strip structure is
@@ -113,23 +119,29 @@ typedef struct gs_tile_bitmap_s {
* space is almost always derived from context, and to provide such a feature
* would involve additional memory-management complexity.
*/
-#define gs_depth_bitmap_common \
- gs_bitmap_common; \
+#define gs_depth_bitmap_common(data_type) \
+ gs_bitmap_common(data_type); \
byte pix_depth; /* bits per sample */ \
byte num_comps /* number of interleaved components */ \
typedef struct gs_depth_bitmap_s {
- gs_depth_bitmap_common;
+ gs_depth_bitmap_common(byte);
} gs_depth_bitmap;
+typedef struct gs_const_depth_bitmap_s {
+ gs_depth_bitmap_common(const byte);
+} gs_const_depth_bitmap;
-#define gs_tile_depth_bitmap_common \
- gs_tile_bitmap_common; \
+#define gs_tile_depth_bitmap_common(data_type) \
+ gs_tile_bitmap_common(data_type); \
byte pix_depth; /* bits per sample */ \
byte num_comps /* number of interleaved components */ \
typedef struct gs_tile_depth_bitmap_s {
- gs_tile_depth_bitmap_common;
+ gs_tile_depth_bitmap_common(byte);
} gs_tile_depth_bitmap;
+typedef struct gs_const_tile_depth_bitmap_s {
+ gs_tile_depth_bitmap_common(const byte);
+} gs_const_tile_depth_bitmap;
/*
* For reasons that are no entirely clear, no memory management routines were
diff --git a/gs/src/gsbitops.c b/gs/src/gsbitops.c
index 0a7b6b0ea..3698105a1 100644
--- a/gs/src/gsbitops.c
+++ b/gs/src/gsbitops.c
@@ -21,7 +21,10 @@
#include "stdio_.h"
#include "memory_.h"
#include "gdebug.h"
+#include "gserror.h"
+#include "gserrors.h"
#include "gstypes.h"
+#include "gsbittab.h"
#include "gxbitops.h"
/*
@@ -51,15 +54,14 @@ const bits16 mono_copy_masks[17] =
# if arch_sizeof_int > 2
const bits32 mono_fill_masks[33] =
{
- 0xffffffff, 0xffffff7f, 0xffffff3f, 0xffffff1f,
- 0xffffff0f, 0xffffff07, 0xffffff03, 0xffffff01,
- 0xffffff00, 0xffff7f00, 0xffff3f00, 0xffff1f00,
- 0xffff0f00, 0xffff0700, 0xffff0300, 0xffff0100,
- 0xffff0000, 0xff7f0000, 0xff3f0000, 0xff1f0000,
- 0xff0f0000, 0xff070000, 0xff030000, 0xff010000,
- 0xff000000, 0x7f000000, 0x3f000000, 0x1f000000,
- 0x0f000000, 0x07000000, 0x03000000, 0x01000000,
- 0x00000000
+#define mask(n)\
+ ((~0xff | (0xff >> (n & 7))) << (n & -8))
+ mask( 0),mask( 1),mask( 2),mask( 3),mask( 4),mask( 5),mask( 6),mask( 7),
+ mask( 8),mask( 9),mask(10),mask(11),mask(12),mask(13),mask(14),mask(15),
+ mask(16),mask(17),mask(18),mask(19),mask(20),mask(21),mask(22),mask(23),
+ mask(24),mask(25),mask(26),mask(27),mask(28),mask(29),mask(30),mask(31),
+ 0
+#undef mask
};
# endif
@@ -460,10 +462,16 @@ bits_compress_scaled(const byte * src, int srcx, uint width, uint height,
int xscale = 1 << log2_x;
int yscale = 1 << log2_y;
int out_bits = 1 << log2_out_bits;
- int input_byte_out_bits;
- byte input_byte_out_mask;
+ /*
+ * The following two initializations are only needed (and the variables
+ * are only used) if out_bits <= xscale. We do them in all cases only
+ * to suppress bogus "possibly uninitialized variable" warnings from
+ * certain compilers.
+ */
+ int input_byte_out_bits = out_bits << (3 - log2_x);
+ byte input_byte_out_mask = (1 << input_byte_out_bits) - 1;
const byte *table =
- compress_tables[log2_out_bits][log2_x + log2_y - 1];
+ compress_tables[log2_out_bits][log2_x + log2_y - 1];
uint sskip = sraster << log2_y;
uint dwidth = (width >> log2_x) << log2_out_bits;
uint dskip = draster - ((dwidth + 7) >> 3);
@@ -480,9 +488,6 @@ bits_compress_scaled(const byte * src, int srcx, uint width, uint height,
byte *d = dest;
uint h;
- if (out_bits <= xscale)
- input_byte_out_bits = out_bits << (3 - log2_x),
- input_byte_out_mask = (1 << input_byte_out_bits) - 1;
for (h = height; h; srow += sskip, h -= yscale) {
const byte *s = srow;
@@ -654,6 +659,199 @@ bits_compress_scaled(const byte * src, int srcx, uint width, uint height,
}
}
+/* Extract a plane from a pixmap. */
+int
+bits_extract_plane(const bits_plane_t *dest /*write*/,
+ const bits_plane_t *source /*read*/, int shift, int width, int height)
+{
+ int source_depth = source->depth;
+ int source_bit = source->x * source_depth;
+ const byte *source_row = source->data.read + (source_bit >> 3);
+ int dest_depth = dest->depth;
+ uint plane_mask = (1 << dest_depth) - 1;
+ int dest_bit = dest->x * dest_depth;
+ byte *dest_row = dest->data.write + (dest_bit >> 3);
+ enum {
+ EXTRACT_SLOW = 0,
+ EXTRACT_4_TO_1,
+ EXTRACT_32_TO_8
+ } loop_case = EXTRACT_SLOW;
+ int y;
+
+ source_bit &= 7;
+ dest_bit &= 7;
+ /* Check for the fast CMYK cases. */
+ if (!(source_bit | dest_bit)) {
+ switch (source_depth) {
+ case 4:
+ loop_case =
+ (dest_depth == 1 && !(source->raster & 3) &&
+ !(source->x & 1) ? EXTRACT_4_TO_1 :
+ EXTRACT_SLOW);
+ break;
+ case 32:
+ if (dest_depth == 8 && !(shift & 7)) {
+ loop_case = EXTRACT_32_TO_8;
+ source_row += 3 - (shift >> 3);
+ }
+ break;
+ }
+ }
+ for (y = 0; y < height;
+ ++y, source_row += source->raster, dest_row += dest->raster
+ ) {
+ int x;
+
+ switch (loop_case) {
+ case EXTRACT_4_TO_1: {
+ const byte *source = source_row;
+ byte *dest = dest_row;
+
+ /* Do groups of 8 pixels. */
+ for (x = width; x >= 8; source += 4, x -= 8) {
+ bits32 sword =
+ (*(const bits32 *)source >> shift) & 0x11111111;
+
+ *dest++ =
+ byte_acegbdfh_to_abcdefgh[(
+#if arch_is_big_endian
+ (sword >> 21) | (sword >> 14) | (sword >> 7) | sword
+#else
+ (sword << 3) | (sword >> 6) | (sword >> 15) | (sword >> 24)
+#endif
+ ) & 0xff];
+ }
+ if (x) {
+ /* Do the final 1-7 pixels. */
+ uint test = 0x10 << shift, store = 0x80;
+
+ do {
+ *dest = (*source & test ? *dest | store : *dest & ~store);
+ if (test >= 0x10)
+ test >>= 4;
+ else
+ test <<= 4, ++source;
+ store >>= 1;
+ } while (--x > 0);
+ }
+ break;
+ }
+ case EXTRACT_32_TO_8: {
+ const byte *source = source_row;
+ byte *dest = dest_row;
+
+ for (x = width; x > 0; source += 4, --x)
+ *dest++ = *source;
+ break;
+ }
+ default: {
+ sample_load_declare_setup(sptr, sbit, source_row, source_bit,
+ source_depth);
+ sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
+ dest_depth);
+
+ sample_store_preload(dbbyte, dptr, dbit, dest_depth);
+ for (x = width; x > 0; --x) {
+ bits32 color;
+ uint pixel;
+
+ sample_load_next32(color, sptr, sbit, source_depth);
+ pixel = (color >> shift) & plane_mask;
+ sample_store_next8(pixel, dptr, dbit, dest_depth, dbbyte);
+ }
+ sample_store_flush(dptr, dbit, dest_depth, dbbyte);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Expand a plane into a pixmap. */
+int
+bits_expand_plane(const bits_plane_t *dest /*write*/,
+ const bits_plane_t *source /*read*/, int shift, int width, int height)
+{
+ /*
+ * Eventually we will optimize this just like bits_extract_plane.
+ */
+ int source_depth = source->depth;
+ int source_bit = source->x * source_depth;
+ const byte *source_row = source->data.read + (source_bit >> 3);
+ int dest_depth = dest->depth;
+ int dest_bit = dest->x * dest_depth;
+ byte *dest_row = dest->data.write + (dest_bit >> 3);
+ enum {
+ EXPAND_SLOW = 0,
+ EXPAND_1_TO_4,
+ EXPAND_8_TO_32
+ } loop_case = EXPAND_SLOW;
+ int y;
+
+ source_bit &= 7;
+ /* Check for the fast CMYK cases. */
+ if (!(source_bit || (dest_bit & 31) || (dest->raster & 3))) {
+ switch (dest_depth) {
+ case 4:
+ if (source_depth == 1)
+ loop_case = EXPAND_1_TO_4;
+ break;
+ case 32:
+ if (source_depth == 8 && !(shift & 7))
+ loop_case = EXPAND_8_TO_32;
+ break;
+ }
+ }
+ dest_bit &= 7;
+ switch (loop_case) {
+
+ case EXPAND_8_TO_32: {
+#if arch_is_big_endian
+# define word_shift (shift)
+#else
+ int word_shift = 24 - shift;
+#endif
+ for (y = 0; y < height;
+ ++y, source_row += source->raster, dest_row += dest->raster
+ ) {
+ int x;
+ const byte *source = source_row;
+ bits32 *dest = (bits32 *)dest_row;
+
+ for (x = width; x > 0; --x)
+ *dest++ = (bits32)(*source++) << word_shift;
+ }
+#undef word_shift
+ }
+ break;
+
+ case EXPAND_1_TO_4:
+ default:
+ for (y = 0; y < height;
+ ++y, source_row += source->raster, dest_row += dest->raster
+ ) {
+ int x;
+ sample_load_declare_setup(sptr, sbit, source_row, source_bit,
+ source_depth);
+ sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
+ dest_depth);
+
+ sample_store_preload(dbbyte, dptr, dbit, dest_depth);
+ for (x = width; x > 0; --x) {
+ uint color;
+ bits32 pixel;
+
+ sample_load_next8(color, sptr, sbit, source_depth);
+ pixel = color << shift;
+ sample_store_next32(pixel, dptr, dbit, dest_depth, dbbyte);
+ }
+ sample_store_flush(dptr, dbit, dest_depth, dbbyte);
+ }
+ break;
+
+ }
+ return 0;
+}
+
/* ---------------- Byte-oriented operations ---------------- */
/* Fill a rectangle of bytes. */
diff --git a/gs/src/gsbitops.h b/gs/src/gsbitops.h
index 5c7034e98..f4c636cff 100644
--- a/gs/src/gsbitops.h
+++ b/gs/src/gsbitops.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,8 +29,8 @@
* more accurate, packed arrays of values -- they may be complete pixels
* or individual components of pixels).
*
- * Supported #s of bits per value (bpv) are 1, 2, 4, 8, 12[, 16[, 24, 32]].
- * The suffix 12, 16, or 32 on a macro name indicates the maximum value
+ * Supported #s of bits per value (bpv) are 1, 2, 4, 8, 12, 16, 24, 32.
+ * The suffix 8, 12, 16, or 32 on a macro name indicates the maximum value
* of bpv that the macro is prepared to handle.
*
* The setup macros number bits within a byte in big-endian order, i.e.,
@@ -55,12 +55,20 @@
sbit = (bitno)
/* Load a value from memory, without incrementing. */
-#define sample_load12_(value, sptr, sbit, sbpv)\
+#define sample_load8_(value, sptr, sbit, sbpv)\
BEGIN\
switch ( (sbpv) >> 2 ) {\
- case 0: value = (*(sptr) >> (8 - (sbit) - (sbpv))) & ((sbpv) - 1); break;\
+ case 0: value = (*(sptr) >> (8 - (sbit) - (sbpv))) & ((sbpv) | 1); break;\
case 1: value = (*(sptr) >> (4 - (sbit))) & 0xf; break;\
- case 2: value = *(sptr); break;\
+ case 2: value = *(sptr); break;
+#define sample_load8(value, sptr, sbit, sbpv)\
+ sample_load8_(value, sptr, sbit, sbpv)\
+ sample_end_
+#define sample_load_next8(value, sptr, sbit, sbpv)\
+ sample_load8(value, sptr, sbit, sbpv);\
+ sample_next(sptr, sbit, sbpv)
+#define sample_load12_(value, sptr, sbit, sbpv)\
+ sample_load8_(value, sptr, sbit, sbpv)\
case 3:\
value = ((sbit) ? ((*(sptr) & 0xf) << 8) | (sptr)[1] :\
(*(sptr) << 4) | ((sptr)[1] >> 4));\
@@ -111,7 +119,7 @@
dbbyte = ((dbit) ? (byte)(*(dptr) & (0xff00 >> (dbit))) : 0)
/* Store a value and increment the pointer. */
-#define sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\
+#define sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\
BEGIN\
switch ( (dbpv) >> 2 ) {\
case 0:\
@@ -123,12 +131,21 @@
if ( dbit ^= 4 ) dbbyte = (byte)((value) << 4);\
else *(dptr)++ = dbbyte | (value);\
break;\
- /* case 2 is deliberately omitted */\
- case 3:\
+ /* case 2 is deliberately omitted */
+#define sample_store_next8(value, dptr, dbit, dbpv, dbbyte)\
+ sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\
+ case 2: *(dptr)++ = (byte)(value); break;\
+ sample_end_
+#define sample_store_next_12_(value, dptr, dbit, dbbyte)\
if ( dbit ^= 4 ) *(dptr)++ = (value) >> 4, dbbyte = (byte)((value) << 4);\
else\
- *(dptr) = dbbyte | ((value) >> 8), (dptr)[1] = (byte)(value), dptr += 2;\
- break;
+ *(dptr) = dbbyte | ((value) >> 8), (dptr)[1] = (byte)(value), dptr += 2;
+#define sample_store_next_12(value, dptr, dbit, dbbyte)\
+ BEGIN sample_store_next_12_(value, dptr, dbit, dbbyte) END
+#define sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\
+ sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\
+ /* case 2 is deliberately omitted */\
+ case 3: sample_store_next_12_(value, dptr, dbit, dbbyte) break;
#define sample_store_next12(value, dptr, dbit, dbpv, dbbyte)\
sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\
case 2: *(dptr)++ = (byte)(value); break;\
@@ -192,18 +209,35 @@ void bits_replicate_horizontally(P6(byte * data, uint width, uint height,
/* Replicate a bitmap vertically in place. */
void bits_replicate_vertically(P4(byte * data, uint height, uint raster,
- uint replicated_height));
+ uint replicated_height));
/* Find the bounding box of a bitmap. */
void bits_bounding_box(P4(const byte * data, uint height, uint raster,
- gs_int_rect * pbox));
+ gs_int_rect * pbox));
/* Compress an oversampled image, possibly in place. */
/* The width and height must be multiples of the respective scale factors. */
/* The source must be an aligned bitmap, as usual. */
void bits_compress_scaled(P9(const byte * src, int srcx, uint width,
- uint height, uint sraster, byte * dest, uint draster,
- const gs_log2_scale_point * plog2_scale, int log2_out_bits));
+ uint height, uint sraster, byte * dest, uint draster,
+ const gs_log2_scale_point * plog2_scale, int log2_out_bits));
+
+/* Extract a plane from a pixmap. */
+typedef struct bits_plane_s {
+ union bpd_ { /* Bit planes must be aligned. */
+ byte *write;
+ const byte *read;
+ } data;
+ int raster;
+ int depth;
+ int x; /* starting x */
+} bits_plane_t;
+int bits_extract_plane(P5(const bits_plane_t *dest /*write*/,
+ const bits_plane_t *source /*read*/, int shift, int width, int height));
+
+/* Expand a plane into a pixmap. */
+int bits_expand_plane(P5(const bits_plane_t *dest /*write*/,
+ const bits_plane_t *source /*read*/, int shift, int width, int height));
/* Fill a rectangle of bytes. */
void bytes_fill_rectangle(P5(byte * dest, uint raster,
diff --git a/gs/src/gsbittab.c b/gs/src/gsbittab.c
index d8e6c15b4..ab23374fb 100644
--- a/gs/src/gsbittab.c
+++ b/gs/src/gsbittab.c
@@ -131,6 +131,15 @@ const byte *const byte_bit_run_length_neg[8] =
byte_bit_run_length_2, byte_bit_run_length_1
};
+/*
+ * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters
+ * denote the individual bits of the byte.
+ */
+const byte byte_acegbdfh_to_abcdefgh[256] =
+{
+ bit_table_8(0, 0x80, 0x20, 0x08, 0x02, 0x40, 0x10, 0x04, 0x01)
+};
+
/* Some C compilers insist on having executable code in every file.... */
void
gsbittab_dummy(void)
diff --git a/gs/src/gsbittab.h b/gs/src/gsbittab.h
index b7d6896f6..b8fae448d 100644
--- a/gs/src/gsbittab.h
+++ b/gs/src/gsbittab.h
@@ -75,4 +75,10 @@ extern const byte
extern const byte *const byte_bit_run_length[8];
extern const byte *const byte_bit_run_length_neg[8];
+/*
+ * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters
+ * denote the individual bits of the byte.
+ */
+extern const byte byte_acegbdfh_to_abcdefgh[256];
+
#endif /* gsbittab_INCLUDED */
diff --git a/gs/src/gsccode.h b/gs/src/gsccode.h
index 0152cdfc2..2e2813633 100644
--- a/gs/src/gsccode.h
+++ b/gs/src/gsccode.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -39,7 +39,12 @@ typedef ulong gs_char;
typedef ulong gs_glyph;
#define gs_no_glyph ((gs_glyph)0x7fffffff)
-#define gs_min_cid_glyph ((gs_glyph)0x80000000)
+#if arch_sizeof_long > 4
+# define gs_min_cid_glyph ((gs_glyph)0x80000000)
+#else
+/* Avoid compiler warnings about signed/unsigned constants. */
+# define gs_min_cid_glyph ((gs_glyph)~0x7fffffff)
+#endif
#define gs_max_glyph max_ulong
/* Define a procedure for marking a gs_glyph during garbage collection. */
diff --git a/gs/src/gsccolor.h b/gs/src/gsccolor.h
index 6e006f181..ca23ea95e 100644
--- a/gs/src/gsccolor.h
+++ b/gs/src/gsccolor.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,14 +22,24 @@
#ifndef gsccolor_INCLUDED
# define gsccolor_INCLUDED
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
/* Pattern instance, usable in color. */
-typedef struct gs_pattern_instance_s gs_pattern_instance;
+#ifndef gs_pattern_instance_DEFINED
+# define gs_pattern_instance_DEFINED
+typedef struct gs_pattern_instance_s gs_pattern_instance_t;
+#endif
+
+/*
+ * Define the maximum number of components in a client color.
+ * This must be at least 4, and should be at least 6 to accommodate
+ * hexachrome DeviceN color spaces.
+ */
+#define GS_CLIENT_COLOR_MAX_COMPONENTS 6
-/* Paint (non-pattern) colors (Device, CIE, Indexed, Separation) */
+/* Paint (non-Pattern) colors */
typedef struct gs_paint_color_s {
- float values[4];
+ float values[GS_CLIENT_COLOR_MAX_COMPONENTS];
} gs_paint_color;
/* General colors */
@@ -40,7 +50,7 @@ typedef struct gs_client_color_s gs_client_color;
#endif
struct gs_client_color_s {
gs_paint_color paint; /* also color for uncolored pattern */
- gs_pattern_instance *pattern;
+ gs_pattern_instance_t *pattern;
};
extern_st(st_client_color);
diff --git a/gs/src/gscdef.c b/gs/src/gscdef.c
index 44a8b412a..e8b20e938 100644
--- a/gs/src/gscdef.c
+++ b/gs/src/gscdef.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,13 +35,13 @@ CONFIG_CONST long gs_buildtime = GS_BUILDTIME;
#ifndef GS_COPYRIGHT
# define GS_COPYRIGHT\
- "Copyright (C) 1998 Aladdin Enterprises, Menlo Park, CA. All rights reserved."
+ "Copyright (C) 1999 Aladdin Enterprises, Menlo Park, CA. All rights reserved."
#endif
const char *CONFIG_CONST gs_copyright = GS_COPYRIGHT;
#ifndef GS_PRODUCT
# define GS_PRODUCT\
- "Aladdin Ghostscript"
+ "Aladdin Ghostscript TESTER RELEASE"
#endif
const char *CONFIG_CONST gs_product = GS_PRODUCT;
@@ -54,6 +54,12 @@ gs_program_name(void)
/* GS_REVISION must be defined in the makefile. */
CONFIG_CONST long gs_revision = GS_REVISION;
+long
+gs_revision_number(void)
+{
+ return gs_revision;
+}
+
/* GS_REVISIONDATE must be defined in the makefile. */
CONFIG_CONST long gs_revisiondate = GS_REVISIONDATE;
diff --git a/gs/src/gscdefs.h b/gs/src/gscdefs.h
index 5304aeafe..5b6afccbd 100644
--- a/gs/src/gscdefs.h
+++ b/gs/src/gscdefs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -54,13 +54,19 @@ extern const char *const gs_lib_default_path;
extern const char *const gs_init_file;
/* Resource tables. In order to avoid importing a large number of types, */
-/* we only provide macros for the externs, not the externs themselves. */
+/* we only provide macros for some externs, not the externs themselves. */
+
+#define extern_gx_device_halftone_list()\
+ typedef const gx_device_halftone_resource_t *(*gx_dht_proc)(P0());\
+ extern const gx_dht_proc gx_device_halftone_list[]
+
+#define extern_gx_image_class_table()\
+ extern const gx_image_class_t gx_image_class_table[]
+extern const unsigned gx_image_class_table_count;
#define extern_gx_image_type_table()\
extern const gx_image_type_t * const gx_image_type_table[]
-#ifndef IN_GCONF_C
extern const unsigned gx_image_type_table_count;
-#endif
/* We need the extra typedef so that the const will apply to the table. */
#define extern_gx_init_table()\
@@ -69,12 +75,10 @@ extern const unsigned gx_image_type_table_count;
#define extern_gx_io_device_table()\
extern const gx_io_device * const gx_io_device_table[]
-#ifndef IN_GCONF_C
extern const unsigned gx_io_device_table_count;
-#endif
-/* Return the list of device prototypes, the list of their structure */
-/* descriptors, and (as the value) the length of the lists. */
+/* Return the list of device prototypes, a NULL list of their structure */
+/* descriptors (no longer used), and (as the value) the length of the lists. */
#define extern_gs_lib_device_list()\
int gs_lib_device_list(P2(const gx_device * const **plist,\
gs_memory_struct_type_t **pst))
diff --git a/gs/src/gscdevn.c b/gs/src/gscdevn.c
index 221593940..8c259f73c 100644
--- a/gs/src/gscdevn.c
+++ b/gs/src/gscdevn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,10 +22,14 @@
#include "gserrors.h"
#include "gsrefct.h"
#include "gsmatrix.h" /* for gscolor2.h */
+#include "gsstruct.h"
#include "gxcspace.h"
+#include "gxcdevn.h"
+/* GC descriptors */
gs_private_st_composite(st_color_space_DeviceN, gs_paint_color_space,
"gs_color_space_DeviceN", cs_DeviceN_enum_ptrs, cs_DeviceN_reloc_ptrs);
+private_st_device_n_map();
/* Define the DeviceN color space type. */
private cs_proc_num_components(gx_num_components_DeviceN);
@@ -48,7 +52,48 @@ const gs_color_space_type gs_color_space_type_DeviceN = {
gx_adjust_cspace_DeviceN, gx_no_adjust_color_count
};
-/* ------ Internal routines ------ */
+/* GC procedures */
+
+private
+ENUM_PTRS_WITH(cs_DeviceN_enum_ptrs, gs_color_space *pcs)
+{
+ return ENUM_USING(*pcs->params.device_n.alt_space.type->stype,
+ &pcs->params.device_n.alt_space,
+ sizeof(pcs->params.device_n.alt_space), index - 2);
+}
+ENUM_PTR(0, gs_color_space, params.device_n.names);
+ENUM_PTR(1, gs_color_space, params.device_n.map);
+ENUM_PTRS_END
+private RELOC_PTRS_WITH(cs_DeviceN_reloc_ptrs, gs_color_space *pcs)
+{
+ RELOC_PTR(gs_color_space, params.device_n.names);
+ RELOC_PTR(gs_color_space, params.device_n.map);
+ RELOC_USING(*pcs->params.device_n.alt_space.type->stype,
+ &pcs->params.device_n.alt_space,
+ sizeof(gs_base_color_space));
+}
+RELOC_PTRS_END
+
+/* ------ Public procedures ------ */
+
+
+/* Allocate and initialize a DeviceN map. */
+int
+alloc_device_n_map(gs_device_n_map ** ppmap, gs_memory_t * mem,
+ client_name_t cname)
+{
+ gs_device_n_map *pimap;
+
+ rc_alloc_struct_1(pimap, gs_device_n_map, &st_device_n_map, mem,
+ return_error(gs_error_VMerror), cname);
+ pimap->tint_transform = 0;
+ pimap->tint_transform_data = 0;
+ pimap->cache_valid = false;
+ *ppmap = pimap;
+ return 0;
+}
+
+/* ------ Color space implementation ------ */
/* Return the number of components of a DeviceN space. */
private int
@@ -65,7 +110,6 @@ gx_alt_space_DeviceN(const gs_color_space * pcs)
}
/* Initialize a DeviceN color. */
-/****** DOESN'T WORK IF num_components > 4 ******/
private void
gx_init_DeviceN(gs_client_color * pcc, const gs_color_space * pcs)
{
@@ -92,9 +136,10 @@ gx_restrict_DeviceN(gs_client_color * pcc, const gs_color_space * pcs)
private const gs_color_space *
gx_concrete_space_DeviceN(const gs_color_space * pcs,
const gs_imager_state * pis)
-{ /* We don't support concrete DeviceN spaces yet. */
+{
+ /* We don't support concrete DeviceN spaces yet. */
const gs_color_space *pacs =
- (const gs_color_space *)&pcs->params.device_n.alt_space;
+ (const gs_color_space *)&pcs->params.device_n.alt_space;
return cs_concrete_space(pacs, pis);
}
@@ -103,35 +148,58 @@ private int
gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs,
frac * pconc, const gs_imager_state * pis)
{
- int code;
+ int code, tcode;
gs_client_color cc;
const gs_color_space *pacs =
- (const gs_color_space *)&pcs->params.device_n.alt_space;
-
- /* We always map into the alternate color space. */
- code = (*pcs->params.device_n.tint_transform)
+ (const gs_color_space *)&pcs->params.device_n.alt_space;
+ gs_device_n_map *map = pcs->params.device_n.map;
+
+ /* Check the 1-element cache first. */
+ if (map->cache_valid) {
+ int i;
+
+ for (i = pcs->params.device_n.num_components; --i >= 0;) {
+ if (map->tint[i] != pc->paint.values[i])
+ break;
+ }
+ if (i < 0) {
+ int num_out = gs_color_space_num_components(pacs);
+
+ for (i = 0; i < num_out; ++i)
+ pconc[i] = map->conc[i];
+ return 0;
+ }
+ }
+ /*
+ * We always map into the alternate color space. We must preserve
+ * tcode for implementing a semi-hack in the interpreter.
+ */
+ tcode = (*pcs->params.device_n.map->tint_transform)
(&pcs->params.device_n, pc->paint.values, &cc.paint.values[0],
- pcs->params.device_n.tint_transform_data);
- if (code < 0)
- return code;
- return (*pacs->type->concretize_color) (&cc, pacs, pconc, pis);
+ pis, pcs->params.device_n.map->tint_transform_data);
+ if (tcode < 0)
+ return tcode;
+ code = (*pacs->type->concretize_color) (&cc, pacs, pconc, pis);
+ return (code < 0 || tcode == 0 ? code : tcode);
}
private int
gx_remap_concrete_DeviceN(const frac * pconc,
gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
gs_color_select_t select)
-{ /* We don't support concrete DeviceN colors yet. */
+{
+ /* We don't support concrete DeviceN colors yet. */
return_error(gs_error_rangecheck);
}
/* Install a DeviceN color space. */
private int
-gx_install_DeviceN(gs_color_space * pcs, gs_state * pgs)
-{ /*
- * Give an error if any of the separation names are duplicated.
- * We can't check this any earlier.
- */
+gx_install_DeviceN(const gs_color_space * pcs, gs_state * pgs)
+{
+ /*
+ * Give an error if any of the separation names are duplicated.
+ * We can't check this any earlier.
+ */
const gs_separation_name *names = pcs->params.device_n.names;
uint i, j;
@@ -140,39 +208,16 @@ gx_install_DeviceN(gs_color_space * pcs, gs_state * pgs)
if (names[i] == names[j])
return_error(gs_error_rangecheck);
return (*pcs->params.device_n.alt_space.type->install_cspace)
- ((gs_color_space *) & pcs->params.device_n.alt_space, pgs);
+ ((const gs_color_space *) & pcs->params.device_n.alt_space, pgs);
}
/* Adjust the reference count of a DeviceN color space. */
private void
gx_adjust_cspace_DeviceN(const gs_color_space * pcs, int delta)
{
+ rc_adjust_const(pcs->params.device_n.map, delta, "gx_adjust_DeviceN");
(*pcs->params.device_n.alt_space.type->adjust_cspace_count)
((const gs_color_space *)&pcs->params.device_n.alt_space, delta);
}
-/* GC procedures */
-
-#define pcs ((gs_color_space *)vptr)
-
-private
-ENUM_PTRS_BEGIN(cs_DeviceN_enum_ptrs)
-{
- return ENUM_USING(*pcs->params.device_n.alt_space.type->stype,
- &pcs->params.device_n.alt_space,
- sizeof(pcs->params.device_n.alt_space), index - 2);
-}
-ENUM_PTR(0, gs_color_space, params.device_n.names);
-ENUM_PTR(1, gs_color_space, params.device_n.tint_transform_data);
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(cs_DeviceN_reloc_ptrs)
-{
- RELOC_PTR(gs_color_space, params.device_n.names);
- RELOC_PTR(gs_color_space, params.device_n.tint_transform_data);
- RELOC_USING(*pcs->params.device_n.alt_space.type->stype,
- &pcs->params.device_n.alt_space,
- sizeof(gs_base_color_space));
-}
-RELOC_PTRS_END
-
#undef pcs
diff --git a/gs/src/gschar.c b/gs/src/gschar.c
index caafa3530..87016c476 100644
--- a/gs/src/gschar.c
+++ b/gs/src/gschar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -235,7 +235,7 @@ gs_awidthshow_n_init(gs_show_enum * penum, gs_state * pgs,
/* kshow[_n] */
int
-gs_kshow_n_init(register gs_show_enum * penum,
+gs_kshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
if (pgs->font->FontType == ft_composite)
@@ -248,14 +248,20 @@ gs_kshow_n_init(register gs_show_enum * penum,
/* xyshow[_n] */
int
-gs_xyshow_n_init(register gs_show_enum * penum,
+gs_xyshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
- return show_setup(penum, pgs, str, size,
- TEXT_FROM_STRING |
- TEXT_REPLACE_X_WIDTHS | TEXT_REPLACE_Y_WIDTHS |
- TEXT_DO_DRAW | TEXT_INTERVENE | TEXT_RETURN_WIDTH,
- true);
+ int code = show_setup(penum, pgs, str, size,
+ TEXT_FROM_STRING |
+ TEXT_REPLACE_X_WIDTHS | TEXT_REPLACE_Y_WIDTHS |
+ TEXT_DO_DRAW | TEXT_INTERVENE | TEXT_RETURN_WIDTH,
+ true);
+
+ if (code < 0)
+ return code;
+ /* Initialize the pointers for the GC. */
+ penum->text.x_widths = penum->text.y_widths = 0;
+ return code;
}
/* glyphshow */
@@ -286,9 +292,10 @@ setup_glyph(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph,
if (pgs->font->FontType == ft_composite)
return_error(gs_error_invalidfont);
- code = show_setup(penum, pgs, "\000" /* arbitrary char */ , 1,
- TEXT_FROM_GLYPHS | TEXT_RETURN_WIDTH | operation,
+ code = show_setup(penum, pgs, NULL, 1,
+ TEXT_FROM_SINGLE_GLYPH | TEXT_RETURN_WIDTH | operation,
true);
+ penum->text.data.d_glyph = glyph;
penum->current_glyph = glyph;
penum->encode_char = gs_glyphshow_encode_char;
return code;
@@ -305,7 +312,7 @@ gs_glyphshow_encode_char(gs_show_enum * penum, gs_font * pfont, gs_char * pchr)
/* cshow[_n] */
int
-gs_cshow_n_init(register gs_show_enum * penum,
+gs_cshow_n_init(gs_show_enum * penum,
gs_state * pgs, const char *str, uint size)
{
return show_setup(penum, pgs, str, size,
@@ -346,8 +353,8 @@ stringwidth_setup(gs_show_enum * penum, gs_state * pgs, const char *str,
gs_make_null_device(dev_null, gs_currentdevice_inline(pgs), mem);
pgs->ctm_default_set = false;
penum->dev_null = dev_null;
- /* Account for the extra reference from the enumerator. */
- rc_increment(dev_null);
+ /* Retain this device, since it is referenced from the enumerator. */
+ gx_device_retain((gx_device *)dev_null, true);
gs_setdevice_no_init(pgs, (gx_device *) dev_null);
/* Establish an arbitrary translation and current point. */
gs_newpath(pgs);
@@ -477,7 +484,7 @@ set_cache_device(gs_show_enum * penum, gs_state * pgs, floatp llx, floatp lly,
/* See if we want to cache this character. */
if (pgs->in_cachedevice) /* no recursion! */
return 0;
- pgs->in_cachedevice = 1; /* disable color/gray/image operators */
+ pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING; /* disable color/gray/image operators */
/* We can only use the cache if we know the glyph. */
glyph = gs_show_current_glyph(penum);
if (glyph == gs_no_glyph)
@@ -644,7 +651,7 @@ set_cache_device(gs_show_enum * penum, gs_state * pgs, floatp llx, floatp lly,
if ((code = gx_clip_to_rectangle(pgs, &clip_box)) < 0)
return code;
gx_set_device_color_1(pgs); /* write 1's */
- pgs->in_cachedevice = 2; /* we are caching */
+ pgs->in_cachedevice = CACHE_DEVICE_CACHING;
}
penum->width_status = sws_cache;
return 1;
@@ -654,7 +661,7 @@ set_cache_device(gs_show_enum * penum, gs_state * pgs, floatp llx, floatp lly,
/* Note that this returns 1 if the current show operation is */
/* non-displaying (stringwidth or cshow). */
int
-gs_setcharwidth(register gs_show_enum * penum, gs_state * pgs,
+gs_setcharwidth(gs_show_enum * penum, gs_state * pgs,
floatp wx, floatp wy)
{
int code;
@@ -674,6 +681,13 @@ gs_setcharwidth(register gs_show_enum * penum, gs_state * pgs,
return !SHOW_IS_DRAWING(penum);
}
+/* Return the cache device status. */
+gs_in_cache_device_t
+gs_incachedevice(const gs_state *pgs)
+{
+ return pgs->in_cachedevice;
+}
+
/* ------ Enumerator ------ */
/* Do the next step of a show (or stringwidth) operation */
@@ -689,7 +703,7 @@ private int show_move(P1(gs_show_enum * penum));
private int show_proceed(P1(gs_show_enum * penum));
private int show_finish(P1(gs_show_enum * penum));
private int
-continue_show_update(register gs_show_enum * penum)
+continue_show_update(gs_show_enum * penum)
{
int code = show_update(penum);
@@ -701,14 +715,14 @@ continue_show_update(register gs_show_enum * penum)
return show_proceed(penum);
}
private int
-continue_show(register gs_show_enum * penum)
+continue_show(gs_show_enum * penum)
{
return show_proceed(penum);
}
/* For kshow, the CTM or font may have changed, so we have to reestablish */
/* the cached values in the enumerator. */
private int
-continue_kshow(register gs_show_enum * penum)
+continue_kshow(gs_show_enum * penum)
{
int code = show_state_setup(penum);
@@ -719,9 +733,9 @@ continue_kshow(register gs_show_enum * penum)
/* Update position */
private int
-show_update(register gs_show_enum * penum)
+show_update(gs_show_enum * penum)
{
- register gs_state *pgs = penum->pgs;
+ gs_state *pgs = penum->pgs;
cached_char *cc = penum->cc;
int code;
@@ -790,9 +804,9 @@ show_fast_move(gs_state * pgs, gs_fixed_point * pwxy)
return code;
}
private int
-show_move(register gs_show_enum * penum)
+show_move(gs_show_enum * penum)
{
- register gs_state *pgs = penum->pgs;
+ gs_state *pgs = penum->pgs;
if (SHOW_IS_XYCSHOW(penum)) {
penum->continue_proc = continue_show;
@@ -801,7 +815,7 @@ show_move(register gs_show_enum * penum)
if (SHOW_IS_ADD_TO_ALL(penum))
gs_rmoveto(pgs, penum->text.delta_all.x, penum->text.delta_all.y);
if (SHOW_IS_ADD_TO_SPACE(penum)) {
- gs_char chr = penum->current_char;
+ gs_char chr = penum->current_char & 0xff;
int fdepth = penum->fstack.depth;
if (fdepth > 0) {
@@ -809,12 +823,17 @@ show_move(register gs_show_enum * penum)
uint fidx = penum->fstack.items[fdepth].index;
switch (((gs_font_type0 *) (penum->fstack.items[fdepth - 1].font))->data.FMapType) {
- case fmap_1_7:
- case fmap_9_7:
- chr += fidx << 7;
+ case fmap_1_7:
+ case fmap_9_7:
+ chr += fidx << 7;
+ break;
+ case fmap_CMap:
+ chr = penum->current_char; /* the full character */
+ if (!penum->cmap_code)
break;
- default:
- chr += fidx << 8;
+ /* falls through */
+ default:
+ chr += fidx << 8;
}
}
if (chr == penum->text.space.s_char)
@@ -837,9 +856,9 @@ show_move(register gs_show_enum * penum)
}
/* Process next character */
private int
-show_proceed(register gs_show_enum * penum)
+show_proceed(gs_show_enum * penum)
{
- register gs_state *pgs = penum->pgs;
+ gs_state *pgs = penum->pgs;
gs_font *pfont;
cached_fm_pair *pair = 0;
gs_font *rfont =
@@ -1025,7 +1044,7 @@ show_proceed(register gs_show_enum * penum)
pgs->font = pfont;
/* Reset the in_cachedevice flag, so that a recursive show */
/* will use the cache properly. */
- pgs->in_cachedevice = 0;
+ pgs->in_cachedevice = CACHE_DEVICE_NONE;
/* Reset the sampling scale. */
penum->log2_current_scale.x = penum->log2_current_scale.y = 0;
/* Set the charpath data in the graphics context if necessary, */
@@ -1229,7 +1248,7 @@ gs_show_width_only(const gs_show_enum * penum)
/* Initialize a show enumerator. */
private int
-show_setup(register gs_show_enum * penum, gs_state * pgs, const char *str,
+show_setup(gs_show_enum * penum, gs_state * pgs, const char *str,
uint size, uint operation, bool propagate_charpath)
{
int code;
@@ -1408,11 +1427,11 @@ show_cache_setup(gs_show_enum * penum)
gs_state *pgs = penum->pgs;
gs_memory_t *mem = pgs->memory;
gx_device_memory *dev =
- gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
- "show_cache_setup(dev_cache)");
+ gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
+ "show_cache_setup(dev_cache)");
gx_device_memory *dev2 =
- gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
- "show_cache_setup(dev_cache2)");
+ gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
+ "show_cache_setup(dev_cache2)");
if (dev == 0 || dev2 == 0) {
gs_free_object(mem, dev2, "show_cache_setup(dev_cache2)");
@@ -1420,19 +1439,18 @@ show_cache_setup(gs_show_enum * penum)
return_error(gs_error_VMerror);
}
/*
- * We only initialize the device for the sake of the GC,
- * (since we have to re-initialize it as either a mem_mono
+ * We only initialize the devices for the sake of the GC,
+ * (since we have to re-initialize dev as either a mem_mono
* or a mem_abuf device before actually using it) and also
* to set its memory pointer.
*/
gs_make_mem_mono_device(dev, mem, gs_currentdevice_inline(pgs));
penum->dev_cache = dev;
+ gs_make_mem_mono_device(dev2, mem, gs_currentdevice_inline(pgs));
penum->dev_cache2 = dev2;
- /* Initialize dev2 for the sake of the GC. */
- *dev2 = *dev;
- /* Account for the extra references from the enumerator. */
- rc_increment(dev);
- rc_increment(dev2);
+ /* Retain these devices, since they are referenced from the enumerator. */
+ gx_device_retain((gx_device *)dev, true);
+ gx_device_retain((gx_device *)dev2, true);
return 0;
}
@@ -1479,7 +1497,14 @@ gs_default_next_glyph(gs_show_enum * penum, gs_char * pchr, gs_glyph * pglyph)
{
if (penum->index == penum->text.size)
return 2;
- *pchr = penum->text.data.bytes[penum->index++];
- *pglyph = gs_no_glyph;
+ if (penum->text.operation & TEXT_FROM_SINGLE_GLYPH) {
+ /* glyphshow or glyphpath */
+ *pchr = gs_no_char;
+ *pglyph = penum->text.data.d_glyph;
+ } else {
+ *pchr = penum->text.data.bytes[penum->index];
+ *pglyph = gs_no_glyph;
+ }
+ penum->index++;
return 0;
}
diff --git a/gs/src/gschar.h b/gs/src/gschar.h
index a4099358e..2744c55b8 100644
--- a/gs/src/gschar.h
+++ b/gs/src/gschar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,14 +30,12 @@
#ifndef gs_show_enum_DEFINED
# define gs_show_enum_DEFINED
typedef struct gs_show_enum_s gs_show_enum;
-
#endif
/* Define an opaque type for fonts if necessary. */
#ifndef gs_font_DEFINED
# define gs_font_DEFINED
typedef struct gs_font_s gs_font;
-
#endif
/* Allocate an enumerator. */
@@ -50,16 +48,16 @@ void gs_show_enum_release(P2(gs_show_enum *, gs_memory_t *));
/* Initialize a text enumeration. */
int gs_show_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
- gs_ashow_n_init(P6(gs_show_enum *, gs_state *, floatp, floatp, const char *, uint)),
- gs_widthshow_n_init(P7(gs_show_enum *, gs_state *, floatp, floatp, gs_char, const char *, uint)),
- gs_awidthshow_n_init(P9(gs_show_enum *, gs_state *, floatp, floatp, gs_char, floatp, floatp, const char *, uint)),
- gs_kshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
- gs_xyshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
- gs_glyphshow_init(P3(gs_show_enum *, gs_state *, gs_glyph)), gs_cshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
- gs_stringwidth_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
- gs_charpath_n_init(P5(gs_show_enum *, gs_state *, const char *, uint, bool)),
- gs_glyphpath_init(P4(gs_show_enum *, gs_state *, gs_glyph, bool)),
- gs_charboxpath_n_init(P5(gs_show_enum *, gs_state *, const char *, uint, bool));
+ gs_ashow_n_init(P6(gs_show_enum *, gs_state *, floatp, floatp, const char *, uint)),
+ gs_widthshow_n_init(P7(gs_show_enum *, gs_state *, floatp, floatp, gs_char, const char *, uint)),
+ gs_awidthshow_n_init(P9(gs_show_enum *, gs_state *, floatp, floatp, gs_char, floatp, floatp, const char *, uint)),
+ gs_kshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
+ gs_xyshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
+ gs_glyphshow_init(P3(gs_show_enum *, gs_state *, gs_glyph)), gs_cshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
+ gs_stringwidth_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
+ gs_charpath_n_init(P5(gs_show_enum *, gs_state *, const char *, uint, bool)),
+ gs_glyphpath_init(P4(gs_show_enum *, gs_state *, gs_glyph, bool)),
+ gs_charboxpath_n_init(P5(gs_show_enum *, gs_state *, const char *, uint, bool));
/* After setting up the enumeration, all the string-related routines */
/* work the same way. The client calls gs_show_next until it returns */
@@ -86,33 +84,33 @@ int gs_show_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)),
int gs_show_next(P1(gs_show_enum *));
gs_char
-gs_show_current_char(P1(const gs_show_enum *)), gs_kshow_previous_char(P1(const gs_show_enum *)),
- gs_kshow_next_char(P1(const gs_show_enum *));
+ gs_show_current_char(P1(const gs_show_enum *)),
+ gs_kshow_previous_char(P1(const gs_show_enum *)),
+ gs_kshow_next_char(P1(const gs_show_enum *));
gs_font *
- gs_show_current_font(P1(const gs_show_enum *));
+ gs_show_current_font(P1(const gs_show_enum *));
int gs_show_restore_font(P1(const gs_show_enum *));
gs_glyph
-gs_show_current_glyph(P1(const gs_show_enum *));
+ gs_show_current_glyph(P1(const gs_show_enum *));
int gs_show_current_width(P2(const gs_show_enum *, gs_point *));
-void gs_show_width(P2(const gs_show_enum *, gs_point *)); /* cumulative width */
+void gs_show_width(P2(const gs_show_enum *, gs_point *)); /* cumulative width */
gs_char_path_mode
-gs_show_in_charpath(P1(const gs_show_enum *)); /* return charpath flag */
+ gs_show_in_charpath(P1(const gs_show_enum *)); /* return charpath flag */
/* Character cache and metrics operators. */
/* gs_setcachedevice* return 1 iff the cache device was just installed. */
int gs_setcachedevice_float(P3(gs_show_enum *, gs_state *, const float * /*[6] */ ));
int gs_setcachedevice_double(P3(gs_show_enum *, gs_state *, const double * /*[6] */ ));
-
#define gs_setcachedevice(penum, pgs, pw)\
gs_setcachedevice_float(penum, pgs, pw)
int gs_setcachedevice2_float(P3(gs_show_enum *, gs_state *, const float * /*[10] */ ));
int gs_setcachedevice2_double(P3(gs_show_enum *, gs_state *, const double * /*[10] */ ));
-
#define gs_setcachedevice2(penum, pgs, pw2)\
gs_setcachedevice2_float(penum, pgs, pw2)
int gs_setcharwidth(P4(gs_show_enum *, gs_state *, floatp, floatp));
+gs_in_cache_device_t gs_incachedevice(P1(const gs_state *));
/* Return true if we only need the width from the rasterizer */
/* and can short-circuit the full rendering of the character, */
diff --git a/gs/src/gschar0.c b/gs/src/gschar0.c
index 44f932c76..b4c2941a5 100644
--- a/gs/src/gschar0.c
+++ b/gs/src/gschar0.c
@@ -364,6 +364,7 @@ gs_type0_next_glyph(register gs_show_enum * penum, gs_char * pchr,
&fidx, &chr, &glyph);
if (code < 0)
return code;
+ penum->cmap_code = code; /* hack for widthshow */
p = str + mindex;
if_debug3('J', "[J]CMap returns %d, chr=0x%lx, glyph=0x%lx\n",
code, (ulong) chr, (ulong) glyph);
@@ -375,7 +376,7 @@ gs_type0_next_glyph(register gs_show_enum * penum, gs_char * pchr,
}
} else
chr = (gs_char) glyph, glyph = gs_no_glyph;
-/****** RESCAN chr IF DESCENDANT IS CMAP'ED ******/
+ /****** RESCAN chr IF DESCENDANT IS CMAP'ED ******/
break;
}
diff --git a/gs/src/gscie.c b/gs/src/gscie.c
index 8c6cb8173..577f31988 100644
--- a/gs/src/gscie.c
+++ b/gs/src/gscie.c
@@ -15,7 +15,7 @@
License requires that the copyright notice and this notice be preserved on
all copies.
*/
-/* $Id$ */
+
/* CIE color rendering cache management */
#include "math_.h"
@@ -609,8 +609,7 @@ gx_currentciecaches(gs_state * pgs)
rc_unshare_struct(pgs->cie_joint_caches, gx_cie_joint_caches,
&st_joint_caches, pgs->memory,
return 0, "gx_currentciecaches");
- if (pjc != pgs->cie_joint_caches) {
- /* if unshare did alloction of new cache */
+ if (pgs->cie_joint_caches != pjc) {
pjc = pgs->cie_joint_caches;
pjc->cspace_id = pjc->render_id = gs_no_id;
pjc->id_status = pjc->status = CIE_JC_STATUS_BUILT;
diff --git a/gs/src/gscie.h b/gs/src/gscie.h
index 3fb818577..c5b21a98c 100644
--- a/gs/src/gscie.h
+++ b/gs/src/gscie.h
@@ -16,6 +16,7 @@
all copies.
*/
+
/* Structures for CIE color algorithms */
/* (requires gscspace.h, gscolor2.h) */
@@ -24,7 +25,7 @@
#include "gconfigv.h" /* for USE_FPU */
#include "gsrefct.h"
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
#include "gxctable.h"
/* ---------------- Configuration parameters ---------------- */
@@ -561,11 +562,27 @@ typedef enum {
typedef struct gx_cie_joint_caches_s {
/*
- * The next two items are the "key" in the cache. id_status refers to
- * the cache status with respect to these keys; status refers to the
- * status with respect to the graphics state. The cache is valid iff
- * status and id_status are both COMPLETED and the ids here are equal
- * to those in the graphics state.
+ * The first 4 members are the "key" in the cache. They behave as
+ * follows:
+ *
+ * If id_status = COMPLETED, the cache is valid with respect to the
+ * color space and CRD identified by cspace_id and render_id.
+ *
+ * If status = COMPLETED, then id_status = COMPLETED also, and for
+ * every gstate pgs that references this cache, pgs->color_space->id =
+ * cspace_id and pgs->cie_render->id = render_id; hence the cache is
+ * valid with respect to that gstate.
+ *
+ * This invariant is maintained because the PostScript CRD-setting
+ * operators, the library's CRD-setting procedure, and the library's
+ * procedures for setting CIE color spaces all unshare the joint caches
+ * and set status in the new copy to something other than COMPLETED.
+ *
+ * The only reason for id_status is that certain client code often
+ * resets the CRD and/or color space and then sets it back to its
+ * original value, and we want to detect that and not invalidate the
+ * caches. If it weren't for that, setcolorspace and setcolorrendering
+ * could simply invalidate the caches.
*/
gs_id cspace_id;
gs_id render_id;
diff --git a/gs/src/gsciemap.c b/gs/src/gsciemap.c
index a0324da8d..9f9a8127f 100644
--- a/gs/src/gsciemap.c
+++ b/gs/src/gsciemap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* CIE color rendering */
#include "math_.h"
#include "gx.h"
diff --git a/gs/src/gsclipsr.c b/gs/src/gsclipsr.c
index d4e3d9742..052c1aa63 100644
--- a/gs/src/gsclipsr.c
+++ b/gs/src/gsclipsr.c
@@ -21,19 +21,82 @@
#include "gx.h"
#include "gserrors.h"
#include "gsclipsr.h"
+#include "gsstruct.h"
+#include "gxclipsr.h"
+#include "gxfixed.h" /* for gxpath.h */
+#include "gxpath.h"
+#include "gzstate.h"
+
+/* Structure descriptors */
+private_st_clip_stack();
+
+/*
+ * When we free a clip stack entry, free the associated clip path,
+ * and iterate down the list. We do this iteratively so that we don't
+ * take a level of recursion for each node on the list.
+ */
+private void
+rc_free_clip_stack(gs_memory_t * mem, void *vstack, client_name_t cname)
+{
+ gx_clip_stack_t *stack = (gx_clip_stack_t *)vstack;
+ gx_clip_stack_t *next;
+
+ do {
+ gx_clip_path *pcpath = stack->clip_path;
+
+ next = stack->next;
+ gs_free_object(stack->rc.memory, stack, cname);
+ gx_cpath_free(pcpath, "rc_free_clip_stack");
+ } while ((stack = next) != 0 && !--(stack->rc.ref_count));
+}
/* clipsave */
int
gs_clipsave(gs_state *pgs)
{
- /****** NYI ******/
- return_error(gs_error_undefined);
+ gs_memory_t *mem = pgs->memory;
+ gx_clip_path *copy =
+ gx_cpath_alloc_shared(pgs->clip_path, mem, "gs_clipsave(clip_path)");
+ gx_clip_stack_t *stack =
+ gs_alloc_struct(mem, gx_clip_stack_t, &st_clip_stack,
+ "gs_clipsave(stack)");
+
+ if (copy == 0 || stack == 0) {
+ gs_free_object(mem, stack, "gs_clipsave(stack)");
+ gs_free_object(mem, copy, "gs_clipsave(clip_path)");
+ return_error(gs_error_VMerror);
+ }
+ rc_init_free(stack, mem, 1, rc_free_clip_stack);
+ stack->clip_path = copy;
+ stack->next = pgs->clip_stack;
+ pgs->clip_stack = stack;
+ return 0;
}
/* cliprestore */
int
gs_cliprestore(gs_state *pgs)
{
- /****** NYI ******/
- return_error(gs_error_undefined);
+ gx_clip_stack_t *stack = pgs->clip_stack;
+
+ if (stack) {
+ gx_clip_stack_t *next = stack->next;
+ gx_clip_path *pcpath = stack->clip_path;
+ int code;
+
+ if (stack->rc.ref_count == 1) {
+ /* Use assign_free rather than assign_preserve. */
+ gs_free_object(stack->rc.memory, stack, "cliprestore");
+ code = gx_cpath_assign_free(pgs->clip_path, pcpath);
+ } else {
+ code = gx_cpath_assign_preserve(pgs->clip_path, pcpath);
+ if (code < 0)
+ return code;
+ --(stack->rc.ref_count);
+ }
+ pgs->clip_stack = next;
+ return code;
+ } else {
+ return gx_cpath_assign_preserve(pgs->clip_path, pgs->saved->clip_path);
+ }
}
diff --git a/gs/src/gscolor.c b/gs/src/gscolor.c
index f24dc3990..27b844ef5 100644
--- a/gs/src/gscolor.c
+++ b/gs/src/gscolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,7 @@
#include "gsstruct.h"
#include "gsutil.h" /* for gs_next_ids */
#include "gsccolor.h"
+#include "gscssub.h"
#include "gxcspace.h"
#include "gxdcconv.h"
#include "gxdevice.h" /* for gx_color_index */
@@ -111,11 +112,15 @@ void load_transfer_map(P3(gs_state *, gx_transfer_map *, floatp));
int
gs_setgray(gs_state * pgs, floatp gray)
{
+ gs_client_color *pcc = pgs->ccolor;
+
if (pgs->in_cachedevice)
return_error(gs_error_undefined);
- cs_adjust_counts(pgs, -1);
- pgs->ccolor->paint.values[0] = FORCE_UNIT(gray);
- pgs->color_space->type = &gs_color_space_type_DeviceGray;
+ gs_cspace_assign(pgs->color_space, gs_current_DeviceGray_space(pgs));
+ pgs->orig_cspace_index = pgs->orig_base_cspace_index =
+ gs_color_space_index_DeviceGray;
+ pcc->paint.values[0] = FORCE_UNIT(gray);
+ pcc->pattern = 0; /* for GC */
gx_unset_dev_color(pgs);
return 0;
}
@@ -127,7 +132,7 @@ gs_currentgray(const gs_state * pgs)
const gs_client_color *pcc = pgs->ccolor;
const gs_imager_state *const pis = (const gs_imager_state *)pgs;
- switch (pgs->color_space->type->index) {
+ switch (pgs->orig_cspace_index) {
case gs_color_space_index_DeviceGray:
return pcc->paint.values[0];
case gs_color_space_index_DeviceRGB:
@@ -170,12 +175,13 @@ gs_setrgbcolor(gs_state * pgs, floatp r, floatp g, floatp b)
if (pgs->in_cachedevice)
return_error(gs_error_undefined);
- cs_adjust_counts(pgs, -1);
+ gs_cspace_assign(pgs->color_space, gs_current_DeviceRGB_space(pgs));
+ pgs->orig_cspace_index = pgs->orig_base_cspace_index =
+ gs_color_space_index_DeviceRGB;
pcc->paint.values[0] = FORCE_UNIT(r);
pcc->paint.values[1] = FORCE_UNIT(g);
pcc->paint.values[2] = FORCE_UNIT(b);
pcc->pattern = 0; /* for GC */
- pgs->color_space->type = &gs_color_space_type_DeviceRGB;
gx_unset_dev_color(pgs);
return 0;
}
@@ -188,10 +194,11 @@ gs_currentrgbcolor(const gs_state * pgs, float pr3[3])
const gs_color_space *pcs = pgs->color_space;
const gs_color_space *pbcs = pcs;
const gs_imager_state *const pis = (const gs_imager_state *)pgs;
+ gs_color_space_index csi = pgs->orig_cspace_index;
frac fcc[4];
gs_client_color cc;
- sw:switch (pbcs->type->index) {
+ sw:switch (csi) {
case gs_color_space_index_DeviceGray:
pr3[0] = pr3[1] = pr3[2] = pcc->paint.values[0];
return 0;
@@ -233,6 +240,7 @@ gs_currentrgbcolor(const gs_state * pgs, float pr3[3])
cc.paint.values[3] = frac2float(fcc[3]);
pcc = &cc;
pcs = pbcs;
+ csi = pgs->orig_base_cspace_index;
goto sw;
default:
break;
@@ -309,12 +317,14 @@ gx_set_device_color_1(gs_state * pgs)
gx_device_color *pdc = pgs->dev_color;
gs_client_color *pcc = pgs->ccolor;
- cs_adjust_counts(pgs, -1);
pcc->paint.values[0] = 0.0;
pcc->pattern = 0; /* for GC */
- pgs->color_space->type = &gs_color_space_type_DeviceGray;
color_set_pure(pdc, 1);
pgs->log_op = lop_default;
+ gs_cspace_assign(pgs->color_space,
+ gs_cspace_DeviceGray((const gs_imager_state *)pgs));
+ pgs->orig_cspace_index = pgs->orig_base_cspace_index =
+ gs_color_space_index_DeviceGray;
}
/* ------ Internal routines ------ */
diff --git a/gs/src/gscolor1.c b/gs/src/gscolor1.c
index 50cabbf3e..59256bb74 100644
--- a/gs/src/gscolor1.c
+++ b/gs/src/gscolor1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,7 @@
#include "gsstruct.h"
#include "gsutil.h" /* for gs_next_ids */
#include "gsccolor.h"
+#include "gscssub.h"
#include "gxcspace.h"
#include "gxdcconv.h"
#include "gxdevice.h" /* for gx_color_index */
@@ -39,21 +40,6 @@ void gx_set_effective_transfer(P1(gs_state *));
/* Force a parameter into the range [0.0..1.0]. */
#define FORCE_UNIT(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p)
-/* Define the CMYK color space type. */
-extern cs_proc_remap_color(gx_remap_DeviceCMYK);
-extern cs_proc_concretize_color(gx_concretize_DeviceCMYK);
-extern cs_proc_remap_concrete_color(gx_remap_concrete_DCMYK);
-const gs_color_space_type gs_color_space_type_DeviceCMYK = {
- gs_color_space_index_DeviceCMYK, true, true,
- &st_base_color_space, gx_num_components_4,
- gx_no_base_space,
- gx_init_paint_4, gx_restrict01_paint_4,
- gx_same_concrete_space,
- gx_concretize_DeviceCMYK, gx_remap_concrete_DCMYK,
- gx_remap_DeviceCMYK, gx_no_install_cspace,
- gx_no_adjust_cspace_count, gx_no_adjust_color_count
-};
-
/* setcmykcolor */
int
gs_setcmykcolor(gs_state * pgs, floatp c, floatp m, floatp y, floatp k)
@@ -62,13 +48,14 @@ gs_setcmykcolor(gs_state * pgs, floatp c, floatp m, floatp y, floatp k)
if (pgs->in_cachedevice)
return_error(gs_error_undefined);
- cs_adjust_counts(pgs, -1);
+ gs_cspace_assign(pgs->color_space, gs_current_DeviceCMYK_space(pgs));
+ pgs->orig_cspace_index = pgs->orig_base_cspace_index =
+ gs_color_space_index_DeviceCMYK;
pcc->paint.values[0] = FORCE_UNIT(c);
pcc->paint.values[1] = FORCE_UNIT(m);
pcc->paint.values[2] = FORCE_UNIT(y);
pcc->paint.values[3] = FORCE_UNIT(k);
pcc->pattern = 0; /* for GC */
- pgs->color_space->type = &gs_color_space_type_DeviceCMYK;
gx_unset_dev_color(pgs);
return 0;
}
@@ -81,10 +68,11 @@ gs_currentcmykcolor(const gs_state * pgs, float pr4[4])
const gs_color_space *pcs = pgs->color_space;
const gs_color_space *pbcs = pcs;
const gs_imager_state *const pis = (const gs_imager_state *)pgs;
+ gs_color_space_index csi = pgs->orig_cspace_index;
frac fcc[4];
gs_client_color cc;
- sw:switch (pbcs->type->index) {
+ sw:switch (csi) {
case gs_color_space_index_DeviceGray:
pr4[0] = pr4[1] = pr4[2] = 0.0;
pr4[3] = 1.0 - pcc->paint.values[0];
@@ -127,6 +115,7 @@ gs_currentcmykcolor(const gs_state * pgs, float pr4[4])
cc.paint.values[3] = frac2float(fcc[3]);
pcc = &cc;
pcs = pbcs;
+ csi = pgs->orig_base_cspace_index;
goto sw;
default:
break;
diff --git a/gs/src/gscolor2.c b/gs/src/gscolor2.c
index 845c8287c..c73467a8a 100644
--- a/gs/src/gscolor2.c
+++ b/gs/src/gscolor2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,7 +32,7 @@
/* setcolorspace */
int
-gs_setcolorspace(gs_state * pgs, gs_color_space * pcs)
+gs_setcolorspace(gs_state * pgs, const gs_color_space * pcs)
{
int code;
gs_color_space cs_old;
@@ -53,6 +53,15 @@ gs_setcolorspace(gs_state * pgs, gs_color_space * pcs)
cs_full_init_color(pgs->ccolor, pcs);
(*cs_old.type->adjust_color_count)(&cc_old, &cs_old, -1);
(*cs_old.type->adjust_cspace_count)(&cs_old, -1);
+ pgs->orig_cspace_index = pcs->type->index;
+ {
+ const gs_color_space *pccs = pcs;
+ const gs_color_space *pbcs;
+
+ while ((pbcs = gs_cspace_base_space(pccs)) != 0)
+ pccs = pbcs;
+ pgs->orig_base_cspace_index = pccs->type->index;
+ }
gx_unset_dev_color(pgs);
return code;
/* Restore the color space if installation failed. */
@@ -67,6 +76,11 @@ gs_currentcolorspace(const gs_state * pgs)
{
return pgs->color_space;
}
+gs_color_space_index
+gs_currentcolorspace_index(const gs_state *pgs)
+{
+ return pgs->orig_cspace_index;
+}
/* setcolor */
int
@@ -96,6 +110,17 @@ gs_currentcolor(const gs_state * pgs)
/* GC descriptors */
public_st_indexed_map();
+/* Define a lookup_index procedure that just returns the map values. */
+int
+lookup_indexed_map(const gs_indexed_params * params, int index, float *values)
+{
+ int m = cs_num_components((const gs_color_space *)&params->base_space);
+ const float *pv = &params->lookup.map->values[index * m];
+
+ memcpy(values, pv, sizeof(*values) * m);
+ return 0;
+}
+
/* Free an indexed map and its values when the reference count goes to 0. */
void
free_indexed_map(gs_memory_t * pmem, void *pmap, client_name_t cname)
@@ -200,10 +225,10 @@ gx_base_space_Indexed(const gs_color_space * pcs)
/* Color space installation ditto. */
private int
-gx_install_Indexed(gs_color_space * pcs, gs_state * pgs)
+gx_install_Indexed(const gs_color_space * pcs, gs_state * pgs)
{
return (*pcs->params.indexed.base_space.type->install_cspace)
- ((gs_color_space *) & pcs->params.indexed.base_space, pgs);
+ ((const gs_color_space *) & pcs->params.indexed.base_space, pgs);
}
/* Color space reference count adjustment ditto. */
@@ -372,8 +397,8 @@ gs_cspace_indexed_value_array(const gs_color_space * pcspace)
*/
int
gs_cspace_indexed_set_proc(
- gs_color_space * pcspace,
- int (*proc) (P3(const gs_indexed_params *, int, float *))
+ gs_color_space * pcspace,
+ int (*proc)(P3(const gs_indexed_params *, int, float *))
)
{
if ((gs_color_space_get_index(pcspace) != gs_color_space_index_Indexed) ||
@@ -417,17 +442,17 @@ gx_concretize_Indexed(const gs_client_color * pc, const gs_color_space * pcs,
{
float value = pc->paint.values[0];
int index =
- (is_fneg(value) ? 0 :
- value >= pcs->params.indexed.hival ? pcs->params.indexed.hival :
- (int)value);
+ (is_fneg(value) ? 0 :
+ value >= pcs->params.indexed.hival ? pcs->params.indexed.hival :
+ (int)value);
gs_client_color cc;
const gs_color_space *pbcs =
- (const gs_color_space *)&pcs->params.indexed.base_space;
+ (const gs_color_space *)&pcs->params.indexed.base_space;
if (pcs->params.indexed.use_proc) {
int code =
- (*pcs->params.indexed.lookup.map->proc.lookup_index)
- (&pcs->params.indexed, index, &cc.paint.values[0]);
+ (*pcs->params.indexed.lookup.map->proc.lookup_index)
+ (&pcs->params.indexed, index, &cc.paint.values[0]);
if (code < 0)
return code;
@@ -438,12 +463,18 @@ gx_concretize_Indexed(const gs_client_color * pc, const gs_color_space * pcs,
pcs->params.indexed.lookup.table.data + m * index;
switch (m) {
- default:
- return_error(gs_error_rangecheck);
+ default: { /* DeviceN */
+ int i;
+
+ for (i = 0; i < m; ++i)
+ cc.paint.values[i] = pcomp[i] * (1.0 / 255.0);
+ }
+ break;
case 4:
cc.paint.values[3] = pcomp[3] * (1.0 / 255.0);
case 3:
cc.paint.values[2] = pcomp[2] * (1.0 / 255.0);
+ case 2:
cc.paint.values[1] = pcomp[1] * (1.0 / 255.0);
case 1:
cc.paint.values[0] = pcomp[0] * (1.0 / 255.0);
diff --git a/gs/src/gscolor2.h b/gs/src/gscolor2.h
index 66344b3f5..8d2e9fc1e 100644
--- a/gs/src/gscolor2.h
+++ b/gs/src/gscolor2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,10 +35,16 @@
/* General color routines */
const gs_color_space *gs_currentcolorspace(P1(const gs_state *));
-int gs_setcolorspace(P2(gs_state *, gs_color_space *));
+int gs_setcolorspace(P2(gs_state *, const gs_color_space *));
const gs_client_color *gs_currentcolor(P1(const gs_state *));
int gs_setcolor(P2(gs_state *, const gs_client_color *));
+/*
+ * gs_currentcolorspace_index returns the index of the current color space
+ * *before* any substitution.
+ */
+gs_color_space_index gs_currentcolorspace_index(P1(const gs_state *));
+
/* CIE-specific routines */
#ifndef gs_cie_render_DEFINED
# define gs_cie_render_DEFINED
@@ -72,13 +78,13 @@ int gs_setcolorrendering(P2(gs_state *, gs_cie_render *));
* procedures provided by the client are fairly efficient, and there are
* few instances in which the client would need to replace them.
*/
-extern int gs_cspace_build_Indexed(
+extern int gs_cspace_build_Indexed(P5(
gs_color_space ** ppcspace,
const gs_color_space * pbase_cspace,
uint num_entries,
const gs_const_string * ptbl,
gs_memory_t * pmem
-);
+ ));
/* Return the number of entries in the palette of an indexed color space. */
extern int gs_cspace_indexed_num_entries(P1(
diff --git a/gs/src/gscolor3.c b/gs/src/gscolor3.c
index 5424fb41a..37a6b968f 100644
--- a/gs/src/gscolor3.c
+++ b/gs/src/gscolor3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,8 +24,8 @@
#include "gsmatrix.h" /* for gscolor2.h */
#include "gscolor2.h"
#include "gscolor3.h"
-#include "gspath.h"
#include "gzstate.h"
+#include "gzpath.h"
#include "gxshade.h"
/* setsmoothness */
@@ -48,17 +48,15 @@ gs_currentsmoothness(const gs_state * pgs)
int
gs_shfill(gs_state * pgs, const gs_shading_t * psh)
{
- int code = gs_gsave(pgs);
+ gx_path cpath;
+ int code;
+ gx_path_init_local(&cpath, pgs->memory);
+ code = gx_cpath_to_path(pgs->clip_path, &cpath);
if (code < 0)
return code;
- if ((code = gs_setcolorspace(pgs, psh->params.ColorSpace)) < 0 ||
- (code = gs_clippath(pgs)) < 0 ||
- (code = gs_shading_fill_path(psh, pgs->path,
- gs_currentdevice(pgs),
- (gs_imager_state *)pgs)) < 0
- )
- DO_NOTHING;
- gs_grestore(pgs);
+ code = gs_shading_fill_path(psh, &cpath, NULL, gs_currentdevice(pgs),
+ (gs_imager_state *)pgs, false);
+ gx_path_free(&cpath, "gs_shfill");
return code;
}
diff --git a/gs/src/gscparam.c b/gs/src/gscparam.c
index 349e3a19d..b8f2d3dfb 100644
--- a/gs/src/gscparam.c
+++ b/gs/src/gscparam.c
@@ -65,7 +65,7 @@ gs_private_st_ptrs2(st_c_param, gs_c_param, "gs_c_param",
/* ---------------- Utilities ---------------- */
private gs_c_param *
-c_param_find(const gs_c_param_list * plist, gs_param_name pkey, bool any)
+c_param_find(const gs_c_param_list *plist, gs_param_name pkey, bool any)
{
gs_c_param *pparam = plist->head;
@@ -99,7 +99,7 @@ gs_c_param_list_write(gs_c_param_list * plist, gs_memory_t * mem)
plist->procs = &c_write_procs;
plist->memory = mem;
plist->head = 0;
- plist->target = 0; /* not used for writing */
+ plist->target = 0; /* not used for writing */
plist->count = 0;
plist->any_requested = false;
plist->coll_type = gs_param_collection_dict_any;
@@ -134,8 +134,9 @@ gs_c_param_list_release(gs_c_param_list * plist)
case gs_param_type_string_array:
case gs_param_type_name_array:
if (!pparam->value.s.persistent)
- gs_free_object(plist->memory, (void *)pparam->value.s.data,
- "gs_c_param_list_release data");
+ gs_free_const_object(plist->memory,
+ pparam->value.s.data,
+ "gs_c_param_list_release data");
break;
default:
break;
@@ -430,11 +431,11 @@ c_param_begin_read_collection(gs_param_list * plist, gs_param_name pkey,
gs_c_param *pparam = c_param_find(cplist, pkey, false);
if (pparam == 0)
- return
- (cplist->target ?
- param_begin_read_collection(cplist->target,
- pkey, pvalue, coll_type) :
- 1);
+ return
+ (cplist->target ?
+ param_begin_read_collection(cplist->target,
+ pkey, pvalue, coll_type) :
+ 1);
switch (pparam->type) {
case gs_param_type_dict:
if (coll_type != gs_param_collection_dict_any)
diff --git a/gs/src/gscpm.h b/gs/src/gscpm.h
index fac9be2ca..a50b922d6 100644
--- a/gs/src/gscpm.h
+++ b/gs/src/gscpm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,7 +17,7 @@
*/
-/* Charpath mode definitions */
+/* Charpath mode and cache device status definitions */
#ifndef gscpm_INCLUDED
# define gscpm_INCLUDED
@@ -30,4 +30,10 @@ typedef enum {
cpm_true_charboxpath /* true charboxpath (ditto) */
} gs_char_path_mode;
+typedef enum {
+ CACHE_DEVICE_NONE = 0, /* default, must be 0 */
+ CACHE_DEVICE_NOT_CACHING, /* setcachedevice done but not caching */
+ CACHE_DEVICE_CACHING /* setcachedevice done and caching */
+} gs_in_cache_device_t;
+
#endif /* gscpm_INCLUDED */
diff --git a/gs/src/gscrd.c b/gs/src/gscrd.c
index 77f0751bd..83511db75 100644
--- a/gs/src/gscrd.c
+++ b/gs/src/gscrd.c
@@ -16,6 +16,7 @@
all copies.
*/
+
/* CIE color rendering dictionary creation */
#include "math_.h"
#include "memory_.h"
@@ -26,6 +27,7 @@
#include "gserrors.h"
#include "gsmatrix.h" /* for gscolor2.h */
#include "gsparam.h"
+#include "gsstruct.h"
#include "gsutil.h"
#include "gxcspace.h"
#include "gscolor2.h" /* for gs_set/currentcolorrendering */
diff --git a/gs/src/gscrd.h b/gs/src/gscrd.h
index 653add9ff..980dec0b9 100644
--- a/gs/src/gscrd.h
+++ b/gs/src/gscrd.h
@@ -16,6 +16,7 @@
all copies.
*/
+
/* Interface for CIE color rendering dictionary creation */
#ifndef gscrd_INCLUDED
diff --git a/gs/src/gscrdp.c b/gs/src/gscrdp.c
index 2df599c8f..f25494daa 100644
--- a/gs/src/gscrdp.c
+++ b/gs/src/gscrdp.c
@@ -16,13 +16,16 @@
all copies.
*/
+
/* CIE color rendering dictionary creation */
#include "math_.h"
#include "memory_.h"
+#include "string_.h"
#include "gx.h"
#include "gsdevice.h"
#include "gserrors.h"
#include "gsmatrix.h" /* for gscolor2.h */
+#include "gsstruct.h"
#include "gxcspace.h"
#include "gscolor2.h" /* for gs_set/currentcolorrendering */
#include "gscrdp.h"
diff --git a/gs/src/gscrdp.h b/gs/src/gscrdp.h
index 19f0ff0e3..83b75de59 100644
--- a/gs/src/gscrdp.h
+++ b/gs/src/gscrdp.h
@@ -16,6 +16,7 @@
all copies.
*/
+
/* Interface for device-specified CRDs */
#ifndef gscrdp_INCLUDED
diff --git a/gs/src/gscscie.c b/gs/src/gscscie.c
index 98be525e0..b5c83995f 100644
--- a/gs/src/gscscie.c
+++ b/gs/src/gscscie.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -144,7 +144,7 @@ gx_concrete_space_CIE(const gs_color_space * pcs, const gs_imager_state * pis)
/* We go through an extra level of procedure so that */
/* interpreters can substitute their own installer. */
private int
-gx_install_CIE(gs_color_space * pcs, gs_state * pgs)
+gx_install_CIE(const gs_color_space * pcs, gs_state * pgs)
{
return (*pcs->params.a->common.install_cspace) (pcs, pgs);
}
diff --git a/gs/src/gscsepr.c b/gs/src/gscsepr.c
index 8b15723b9..689a8cd93 100644
--- a/gs/src/gscsepr.c
+++ b/gs/src/gscsepr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -98,10 +98,10 @@ gx_concrete_space_Separation(const gs_color_space * pcs,
/* Install a Separation color space. */
private int
-gx_install_Separation(gs_color_space * pcs, gs_state * pgs)
+gx_install_Separation(const gs_color_space * pcs, gs_state * pgs)
{
return (*pcs->params.separation.alt_space.type->install_cspace)
- ((gs_color_space *) & pcs->params.separation.alt_space, pgs);
+ ((const gs_color_space *) & pcs->params.separation.alt_space, pgs);
}
/* Adjust the reference count of a Separation color space. */
@@ -234,7 +234,7 @@ gs_cspace_build_Separation(
* the separation color space has a cache size of 0.
*/
float *
-gs_cspace_get_separation_value_array(const gs_color_space * pcspace)
+gs_cspace_get_sepr_value_array(const gs_color_space * pcspace)
{
if (gs_color_space_get_index(pcspace) != gs_color_space_index_Separation)
return 0;
@@ -245,7 +245,7 @@ gs_cspace_get_separation_value_array(const gs_color_space * pcspace)
* Set the tint transformation procedure used by a Separation color space.
*/
int
-gs_cspace_set_tint_transform_proc(gs_color_space * pcspace,
+gs_cspace_set_tint_xform_proc(gs_color_space * pcspace,
int (*proc) (P3(const gs_separation_params *, floatp, float *)))
{
if (gs_color_space_get_index(pcspace) != gs_color_space_index_Separation)
diff --git a/gs/src/gscsepr.h b/gs/src/gscsepr.h
index 00e12fbc7..c569a0e47 100644
--- a/gs/src/gscsepr.h
+++ b/gs/src/gscsepr.h
@@ -43,26 +43,32 @@ void gs_setoverprint(P2(gs_state *, bool));
* entries in the cache. If this function is called when the cache size is
* 0, all color components in the alternative color space will be set to 0.
*/
-extern int gs_cspace_build_Separation(
+extern int gs_cspace_build_Separation(P5(
gs_color_space ** ppcspace,
gs_separation_name sname,
const gs_color_space * palt_cspace,
int cache_size,
gs_memory_t * pmem
-);
+ ));
/* Get the cached value array for a Separation color space. */
-extern float *gs_separation_value_array(P1(
- const gs_color_space * pcspace
- ));
+/* VMS limits procedure names to 31 characters. */
+extern float *gs_cspace_get_sepr_value_array(P1(
+ const gs_color_space * pcspace
+ ));
+/* BACKWARD COMPATIBILITY */
+#define gs_cspace_get_separation_value_array gs_cspace_get_sepr_value_array
/* Set the tint transformation procedure for a separation color space. */
-extern int gs_cspace_set_tint_transform_proc(P2(
- gs_color_space * pcspace,
+/* VMS limits procedure names to 31 characters. */
+extern int gs_cspace_set_tint_xform_proc(P2(
+ gs_color_space * pcspace,
int (*proc) (P3(const gs_separation_params *,
floatp,
float *
- ))
- ));
+ ))
+ ));
+/* BACKWARD COMPATIBILITY */
+#define gs_cspace_set_tint_transform_proc gs_cspace_set_tint_xform_proc
#endif /* gscsepr_INCLUDED */
diff --git a/gs/src/gscspace.c b/gs/src/gscspace.c
index b03571f35..548b6015b 100644
--- a/gs/src/gscspace.c
+++ b/gs/src/gscspace.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,14 +27,22 @@
#include "gxcspace.h"
#include "gxistate.h"
-/* Define the standard color space types. */
+/*
+ * Define the standard color space types. We include DeviceCMYK in the base
+ * build because it's too awkward to omit it, but we don't provide any of
+ * the PostScript operator procedures (setcmykcolor, etc.) for dealing with
+ * it.
+ */
extern cs_proc_remap_color(gx_remap_DeviceGray);
extern cs_proc_concretize_color(gx_concretize_DeviceGray);
extern cs_proc_remap_concrete_color(gx_remap_concrete_DGray);
extern cs_proc_remap_color(gx_remap_DeviceRGB);
extern cs_proc_concretize_color(gx_concretize_DeviceRGB);
extern cs_proc_remap_concrete_color(gx_remap_concrete_DRGB);
-const gs_color_space_type gs_color_space_type_DeviceGray = {
+extern cs_proc_remap_color(gx_remap_DeviceCMYK);
+extern cs_proc_concretize_color(gx_concretize_DeviceCMYK);
+extern cs_proc_remap_concrete_color(gx_remap_concrete_DCMYK);
+private const gs_color_space_type gs_color_space_type_DeviceGray = {
gs_color_space_index_DeviceGray, true, true,
&st_base_color_space, gx_num_components_1,
gx_no_base_space,
@@ -44,7 +52,7 @@ const gs_color_space_type gs_color_space_type_DeviceGray = {
gx_remap_DeviceGray, gx_no_install_cspace,
gx_no_adjust_cspace_count, gx_no_adjust_color_count
};
-const gs_color_space_type gs_color_space_type_DeviceRGB = {
+private const gs_color_space_type gs_color_space_type_DeviceRGB = {
gs_color_space_index_DeviceRGB, true, true,
&st_base_color_space, gx_num_components_3,
gx_no_base_space,
@@ -54,6 +62,16 @@ const gs_color_space_type gs_color_space_type_DeviceRGB = {
gx_remap_DeviceRGB, gx_no_install_cspace,
gx_no_adjust_cspace_count, gx_no_adjust_color_count
};
+private const gs_color_space_type gs_color_space_type_DeviceCMYK = {
+ gs_color_space_index_DeviceCMYK, true, true,
+ &st_base_color_space, gx_num_components_4,
+ gx_no_base_space,
+ gx_init_paint_4, gx_restrict01_paint_4,
+ gx_same_concrete_space,
+ gx_concretize_DeviceCMYK, gx_remap_concrete_DCMYK,
+ gx_remap_DeviceCMYK, gx_no_install_cspace,
+ gx_no_adjust_cspace_count, gx_no_adjust_color_count
+};
/* Structure descriptors */
public_st_color_space();
@@ -63,17 +81,17 @@ public_st_base_color_space();
const gs_color_space *
gs_cspace_DeviceGray(const gs_imager_state * pis)
{
- return gs_imager_state_shared(pis, cs_DeviceGray);
+ return pis->shared->device_color_spaces.named.Gray;
}
const gs_color_space *
gs_cspace_DeviceRGB(const gs_imager_state * pis)
{
- return gs_imager_state_shared(pis, cs_DeviceRGB);
+ return pis->shared->device_color_spaces.named.RGB;
}
const gs_color_space *
gs_cspace_DeviceCMYK(const gs_imager_state * pis)
{
- return gs_imager_state_shared(pis, cs_DeviceCMYK);
+ return pis->shared->device_color_spaces.named.CMYK;
}
/* ------ Create/copy/destroy ------ */
@@ -231,7 +249,7 @@ gx_no_base_space(const gs_color_space * pcspace)
/* Null color space installation procedure. */
int
-gx_no_install_cspace(gs_color_space * pcs, gs_state * pgs)
+gx_no_install_cspace(const gs_color_space * pcs, gs_state * pgs)
{
return 0;
}
diff --git a/gs/src/gscspace.h b/gs/src/gscspace.h
index 4e246b861..29c107ece 100644
--- a/gs/src/gscspace.h
+++ b/gs/src/gscspace.h
@@ -135,7 +135,11 @@
* Pattern colored: (none) dictionary
* uncolored: base_space dictionary + base space params */
-/* Color space type indices */
+/*
+ * Define color space type indices. NOTE: PostScript code (gs_res.ps,
+ * gs_ll3.ps) and the color space substitution code (gscssub.[hc] and its
+ * clients) assumes values 0-2 for DeviceGray/RGB/CMYK respectively.
+ */
typedef enum {
/* Supported in all configurations */
@@ -220,16 +224,16 @@ typedef struct gs_separation_params_s {
gs_indexed_map *map;
} gs_separation_params;
-typedef struct gs_device_n_params_s gs_device_n_params;
-struct gs_device_n_params_s {
+#ifndef gs_device_n_map_DEFINED
+# define gs_device_n_map_DEFINED
+typedef struct gs_device_n_map_s gs_device_n_map;
+#endif
+typedef struct gs_device_n_params_s {
gs_separation_name *names;
uint num_components;
gs_base_color_space alt_space;
- int (*tint_transform)
- (P4(const gs_device_n_params * params, const float *in, float *out,
- void *data));
- void *tint_transform_data;
-};
+ gs_device_n_map *map;
+} gs_device_n_params;
#define gs_direct_cspace_params \
gs_base_cspace_params; \
@@ -375,7 +379,7 @@ void gs_cspace_init_from(P2(gs_color_space * pcsto,
const gs_color_space * pcsfrom));
/* Assign a color space into a previously initialized one. */
-void cs_cspace_assign(P2(gs_color_space * pdest, const gs_color_space * psrc));
+void gs_cspace_assign(P2(gs_color_space * pdest, const gs_color_space * psrc));
/* Prepare to free a color space. */
void gs_cspace_release(P1(gs_color_space * pcs));
diff --git a/gs/src/gscssub.c b/gs/src/gscssub.c
new file mode 100644
index 000000000..b87d6e7ea
--- /dev/null
+++ b/gs/src/gscssub.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Color space substitution "operators" */
+#include "gx.h"
+#include "gserrors.h"
+#include "gscssub.h"
+#include "gxcspace.h" /* for st_color_space */
+#include "gxdevcli.h"
+#include "gzstate.h"
+
+/* .setsubstitutecolorspace */
+int
+gs_setsubstitutecolorspace(gs_state *pgs, gs_color_space_index csi,
+ const gs_color_space *pcs)
+{
+ int index = (int)csi;
+ static const uint masks[3] = {
+ (1 << gs_color_space_index_DeviceGray) |
+ (1 << gs_color_space_index_CIEA),
+ (1 << gs_color_space_index_DeviceRGB) |
+ (1 << gs_color_space_index_CIEABC) |
+ (1 << gs_color_space_index_CIEDEF),
+ (1 << gs_color_space_index_DeviceCMYK) |
+ (1 << gs_color_space_index_CIEDEFG)
+ };
+ const gs_color_space *pcs_old;
+
+ if (index < 0 || index > 2)
+ return_error(gs_error_rangecheck);
+ if (pcs) {
+ if (!masks[index] & (1 << gs_color_space_get_index(pcs)))
+ return_error(gs_error_rangecheck);
+ }
+ pcs_old = pgs->device_color_spaces.indexed[index];
+ if (pcs_old == 0) {
+ gs_color_space *pcs_new;
+
+ if (pcs == 0 || gs_color_space_get_index(pcs) == csi)
+ return 0;
+ pcs_new = gs_alloc_struct(pgs->memory, gs_color_space, &st_color_space,
+ "gs_setsubstitutecolorspace");
+ if (pcs_new == 0)
+ return_error(gs_error_VMerror);
+ gs_cspace_init_from(pcs_new, pcs);
+ pgs->device_color_spaces.indexed[index] = pcs_new;
+ } else {
+ gs_cspace_assign(pgs->device_color_spaces.indexed[index],
+ (pcs ? pcs :
+ pgs->shared->device_color_spaces.indexed[index]));
+ }
+ return 0;
+}
+
+/* Possibly-substituted color space accessors. */
+const gs_color_space *
+gs_current_DeviceGray_space(const gs_state *pgs)
+{
+ const gs_color_space *pcs;
+
+ return (!pgs->device->UseCIEColor ||
+ (pcs = pgs->device_color_spaces.named.Gray) == 0 ?
+ pgs->shared->device_color_spaces.named.Gray : pcs);
+}
+const gs_color_space *
+gs_current_DeviceRGB_space(const gs_state *pgs)
+{
+ const gs_color_space *pcs;
+
+ return (!pgs->device->UseCIEColor ||
+ (pcs = pgs->device_color_spaces.named.RGB) == 0 ?
+ pgs->shared->device_color_spaces.named.RGB : pcs);
+}
+const gs_color_space *
+gs_current_DeviceCMYK_space(const gs_state *pgs)
+{
+ const gs_color_space *pcs;
+
+ return (!pgs->device->UseCIEColor ||
+ (pcs = pgs->device_color_spaces.named.CMYK) == 0 ?
+ pgs->shared->device_color_spaces.named.CMYK : pcs);
+}
+
+/* .currentsubstitutecolorspace */
+const gs_color_space *
+gs_currentsubstitutecolorspace(const gs_state *pgs, gs_color_space_index csi)
+{
+ switch (csi) {
+ case gs_color_space_index_DeviceGray:
+ return gs_current_DeviceGray_space(pgs);
+ case gs_color_space_index_DeviceRGB:
+ return gs_current_DeviceRGB_space(pgs);
+ case gs_color_space_index_DeviceCMYK:
+ return gs_current_DeviceCMYK_space(pgs);
+ default:
+ return 0;
+ }
+}
diff --git a/gs/src/gscssub.h b/gs/src/gscssub.h
new file mode 100644
index 000000000..fee6cb8e8
--- /dev/null
+++ b/gs/src/gscssub.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Client interface to color space substitution */
+
+#ifndef gscssub_INCLUDED
+# define gscssub_INCLUDED
+
+#include "gscspace.h"
+
+/*
+ * Color space substitution at the library level is similar to, but not
+ * identical to, the operation of UseCIEColor in the PostScript language.
+ * When the Boolean UseCIEColor parameter of the current device is false,
+ * everything operates as normal. When UseCIEColor is true, the following
+ * procedures may substitute another color space for the implied one:
+ *
+ * gs_setgray, gs_setrgbcolor, gs_sethsbcolor, gs_setcmykcolor
+ * gs_current_Device{Gray,RGB,CMYK}_space
+ *
+ * Unlike the PostScript facility, the substitution *is* visible to
+ * gs_currentcolorspace, and does *not* affect gs_setcolorspace, or the
+ * ColorSpace members of images or shadings. However, the following
+ * procedures recognize when substitution has occurred and return the
+ * value(s) appropriate for the pre-substitution space:
+ *
+ * gs_currentgray, gs_currentrgbcolor, gs_currenthsbcolor,
+ * gs_currentcmykcolor
+ *
+ * Thus gs_{current,set}{gray,{rgb,hsb,cmyk}color} are always mutually
+ * consistent, concealing any substitution, and gs_{current,set}{colorspace}
+ * are mutually consistent, reflecting any substitution.
+ * gs_{current,set}color are consistent with the other color accessors,
+ * since color space substitution doesn't affect color values.
+ *
+ * As in PostScript, color space substitutions are not affected by
+ * (ordinary) grestore or by setgstate. Graphics states created by gsave or
+ * gstate, or overwritten by currentgstate or copygstate, share
+ * substitutions with the state from which they were copied.
+ */
+
+/* If pcs is NULL, it means undo any substitution. */
+int gs_setsubstitutecolorspace(P3(gs_state *pgs, gs_color_space_index csi,
+ const gs_color_space *pcs));
+const gs_color_space *
+ gs_currentsubstitutecolorspace(P2(const gs_state *pgs,
+ gs_color_space_index csi));
+
+/*
+ * The following procedures are primarily for internal use, to provide
+ * fast access to specific color spaces.
+ */
+const gs_color_space *gs_current_DeviceGray_space(P1(const gs_state *pgs));
+const gs_color_space *gs_current_DeviceRGB_space(P1(const gs_state *pgs));
+const gs_color_space *gs_current_DeviceCMYK_space(P1(const gs_state *pgs));
+
+#endif /* gscssub_INCLUDED */
diff --git a/gs/src/gsdcolor.h b/gs/src/gsdcolor.h
index c0076497d..bd031102a 100644
--- a/gs/src/gsdcolor.h
+++ b/gs/src/gsdcolor.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -131,7 +131,7 @@ typedef struct gx_device_halftone_s gx_device_halftone;
((pdc)->colors.colored.c_base[i] = (b),\
(pdc)->colors.colored.c_level[i] = (l))
void gx_complete_rgb_halftone(P2(gx_device_color *pdevc,
- const gx_device_halftone *pdht));
+ gx_device_halftone *pdht));
#define color_set_rgb_halftone(pdc, ht, br, lr, bg, lg, bb, lb, a)\
(_color_set_c(pdc, 0, br, lr),\
_color_set_c(pdc, 1, bg, lg),\
@@ -140,7 +140,7 @@ void gx_complete_rgb_halftone(P2(gx_device_color *pdevc,
gx_complete_rgb_halftone(pdc, ht))
/* Some special clients set the individual components separately. */
void gx_complete_cmyk_halftone(P2(gx_device_color *pdevc,
- const gx_device_halftone *pdht));
+ gx_device_halftone *pdht));
#define color_finish_set_cmyk_halftone(pdc, ht)\
gx_complete_cmyk_halftone(pdc, ht)
#define color_set_cmyk_halftone(pdc, ht, bc, lc, bm, lm, by, ly, bk, lk)\
@@ -205,12 +205,13 @@ typedef struct gx_color_tile_s gx_color_tile;
* colors.colored.c_level[0..N-1] = the halftone levels,
* like b_level;
* colors.colored.c_base[0..N-1] = the base colors;
- * N=3 for RGB devices, 4 for CMYK devices;
+ * N = the device color_info.num_components
+ * (3 for RGB devices, 4 for CMYK devices, ? for DeviceN);
* 0 <= c_level[i] < P;
* 0 <= c_base[i] <= dither_rgb;
* colors.colored.alpha = the opacity.
* colors.colored.plane_mask: bit 2^i = 1 iff c_level[i] != 0
- * Colored pattern (gx_dc_pattern):
+ * Colored PatternType 1 pattern (gx_dc_pattern):
* (mask is also set, see below)
* @ colors.pattern.p_tile points to a gx_color_tile in
* the pattern cache, or is NULL for a null pattern.
@@ -219,12 +220,14 @@ typedef struct gx_color_tile_s gx_color_tile;
* negative of the graphics state halftone phase, modulo the halftone tile
* size.
*
- * The mask elements of a device color are only used for patterns:
+ * The ccolor element is used for all kinds of patterns. It is needed for
+ * rendering the pattern.
+ *
+ * The mask elements of a device color are only used for PatternType 1
+ * patterns:
* Non-pattern:
* mask is unused.
* Pattern:
- * mask.ccolor gives the original Pattern color (needed for
- * reloading the pattern cache);
* mask.id gives the ID of the pattern (and its mask);
* mask.m_phase holds the negative of the graphics state
* halftone phase;
@@ -266,18 +269,27 @@ struct gx_device_color_s {
} binary;
struct _col {
gx_device_halftone *c_ht; /* non-const for setting cache ptr */
- byte c_base[4];
- uint c_level[4];
+ byte c_base[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ uint c_level[GX_DEVICE_COLOR_MAX_COMPONENTS];
ushort /*gx_color_value */ alpha;
+#if GX_DEVICE_COLOR_MAX_COMPONENTS <= arch_sizeof_short
ushort plane_mask;
+#else
+#if GX_DEVICE_COLOR_MAX_COMPONENTS <= arch_sizeof_int
+ uint plane_mask;
+#else
+ gx_color_index plane_mask;
+#endif
+#endif
} colored;
struct _pat {
gx_color_tile *p_tile;
} /*(colored) */ pattern;
} colors;
gs_int_point phase;
+ gs_client_color ccolor; /* needed for remapping patterns, */
+ /* not set for non-pattern colors */
struct _mask {
- gs_client_color ccolor; /* needed for remapping pattern */
struct mp_ {
short x, y;
} m_phase;
@@ -290,7 +302,7 @@ struct gx_device_color_s {
#define public_st_device_color() /* in gxcmap.c */\
gs_public_st_composite(st_device_color, gx_device_color, "gx_device_color",\
device_color_enum_ptrs, device_color_reloc_ptrs)
-#define st_device_color_max_ptrs 2
+#define st_device_color_max_ptrs (st_client_color_max_ptrs + 2)
/*
* Define the standard device color types.
diff --git a/gs/src/gsdevice.c b/gs/src/gsdevice.c
index f31cb4d4f..ace76786b 100644
--- a/gs/src/gsdevice.c
+++ b/gs/src/gsdevice.c
@@ -38,11 +38,29 @@
/* Include the extern for the device list. */
extern_gs_lib_device_list();
-/* Finalization for devices: close the device if it is open. */
+/*
+ * Finalization for devices: do any special finalization first, then
+ * close the device if it is open, and finally free the structure
+ * descriptor if it is dynamic.
+ */
void
gx_device_finalize(void *vptr)
{
- discard(gs_closedevice((gx_device *) vptr));
+ gx_device * const dev = (gx_device *)vptr;
+
+ if (dev->finalize)
+ dev->finalize(dev);
+ discard(gs_closedevice(dev));
+ if (dev->stype_is_dynamic)
+ gs_free_const_object(&gs_memory_default, dev->stype,
+ "gx_device_finalize");
+}
+
+/* "Free" a device locally allocated on the stack, by finalizing it. */
+void
+gx_device_free_local(gx_device *dev)
+{
+ gx_device_finalize(dev);
}
/* GC procedures */
@@ -198,28 +216,24 @@ gs_getdevice(int index)
}
/* Fill in the GC structure descriptor for a device. */
-/* This is only called during initialization. */
-void
+private void
gx_device_make_struct_type(gs_memory_struct_type_t *st,
const gx_device *dev)
{
const gx_device_procs *procs = dev->static_procs;
- bool forward = false;
/*
- * Try to figure out whether this is a forwarding device. All
- * printer devices, and no other devices, have a null fill_rectangle
- * procedure; for other devices, we look for a likely forwarding
- * procedure in the vector. The algorithm isn't foolproof, but it's
- * the best we can come up with.
+ * Try to figure out whether this is a forwarding device. For printer
+ * devices, we rely on the prototype referencing the correct structure
+ * descriptor; for other devices, we look for a likely forwarding
+ * procedure in the vector. The algorithm isn't foolproof, but it's the
+ * best we can come up with.
*/
if (procs == 0)
procs = &dev->procs;
- if (procs->fill_rectangle == 0 ||
- procs->get_xfont_procs == gx_forward_get_xfont_procs
- )
- forward = true;
- if (forward)
+ if (dev->stype)
+ *st = *dev->stype;
+ else if (procs->get_xfont_procs == gx_forward_get_xfont_procs)
*st = st_device_forward;
else
*st = st_device;
@@ -232,43 +246,46 @@ gs_copydevice(gx_device ** pnew_dev, const gx_device * dev, gs_memory_t * mem)
{
gx_device *new_dev;
const gs_memory_struct_type_t *std = dev->stype;
+ const gs_memory_struct_type_t *new_std;
+ if (dev->stype_is_dynamic) {
+ /*
+ * We allocated the stype for this device previously.
+ * Just allocate a new stype and copy the old one into it.
+ */
+ gs_memory_struct_type_t *a_std = (gs_memory_struct_type_t *)
+ gs_alloc_bytes_immovable(&gs_memory_default, sizeof(*std),
+ "gs_copydevice(stype)");
+
+ if (!a_std)
+ return_error(gs_error_VMerror);
+ *a_std = *std;
+ new_std = a_std;
+ } else if (std != 0 && std->ssize == dev->params_size) {
+ /* Use the static stype. */
+ new_std = std;
+ } else {
+ /* We need to figure out or adjust the stype. */
+ gs_memory_struct_type_t *a_std = (gs_memory_struct_type_t *)
+ gs_alloc_bytes_immovable(&gs_memory_default, sizeof(*std),
+ "gs_copydevice(stype)");
+
+ if (!a_std)
+ return_error(gs_error_VMerror);
+ gx_device_make_struct_type(a_std, dev);
+ new_std = a_std;
+ }
/*
* Because command list devices have complicated internal pointer
* structures, we allocate all device instances as immovable.
*/
- if (std == 0) {
- /*
- * This is the statically allocated prototype. Find its
- * structure descriptor.
- */
- const gx_device *const *list;
- gs_memory_struct_type_t *st;
- int count = gs_lib_device_list(&list, &st);
- int i;
-
- for (i = 0; list[i] != dev; ++i)
- if (i == count) {
- /*
- * We can't find a structure descriptor for this device.
- * Allocate it as bytes and hope for the best.
- */
- std = &st_device_unknown;
- new_dev =
- gs_alloc_struct_array_immovable(mem, dev->params_size,
- gx_device, std,
- "gs_copydevice(unknown)");
- goto out;
- }
- std = st + i;
- }
- new_dev = gs_alloc_struct_immovable(mem, gx_device, std,
- "gs_copydevice");
-out:
+ new_dev = gs_alloc_struct_immovable(mem, gx_device, new_std,
+ "gs_copydevice(device)");
if (new_dev == 0)
return_error(gs_error_VMerror);
gx_device_init(new_dev, dev, mem, false);
- new_dev->stype = std;
+ new_dev->stype = new_std;
+ new_dev->stype_is_dynamic = new_std != std;
new_dev->is_open = false;
*pnew_dev = new_dev;
return 0;
@@ -281,6 +298,7 @@ gs_opendevice(gx_device *dev)
{
if (dev->is_open)
return 0;
+ gx_device_fill_in_procs(dev);
{
int code = (*dev_proc(dev, open_device))(dev);
@@ -294,12 +312,12 @@ gs_opendevice(gx_device *dev)
/* Set device parameters, updating a graphics state or imager state. */
int
gs_imager_putdeviceparams(gs_imager_state *pis, gx_device *dev,
- gs_param_list *plist)
+ gs_param_list *plist)
{
int code = gs_putdeviceparams(dev, plist);
if (code >= 0)
- gx_set_cmap_procs(pis, dev);
+ gx_set_cmap_procs(pis, dev);
return code;
}
private void
@@ -314,7 +332,7 @@ gs_state_putdeviceparams(gs_state *pgs, gs_param_list *plist)
int code = gs_putdeviceparams(pgs->device, plist);
if (code >= 0)
- gs_state_update_device(pgs);
+ gs_state_update_device(pgs);
return code;
}
@@ -331,7 +349,7 @@ gs_setdevice(gs_state * pgs, gx_device * dev)
int
gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
{
- int code = 0;
+ int open_code = 0, code;
/* Initialize the device */
if (!dev->is_open) {
@@ -342,10 +360,9 @@ gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
while (odev != 0 && gs_device_is_memory(odev))
odev = ((gx_device_memory *)odev)->target;
- rc_assign(((gx_device_memory *)dev)->target, odev,
- "set memory device(target)");
+ gx_device_set_target(((gx_device_forward *)dev), odev);
}
- code = gs_opendevice(dev);
+ code = open_code = gs_opendevice(dev);
if (code < 0)
return code;
}
@@ -359,7 +376,7 @@ gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
/* we aren't any longer. */
pgs->in_cachedevice = 0;
pgs->in_charpath = (gs_char_path_mode) 0;
- return code;
+ return open_code;
}
int
gs_setdevice_no_init(gs_state * pgs, gx_device * dev)
@@ -380,28 +397,41 @@ gx_device_init(gx_device * dev, const gx_device * proto, gs_memory_t * mem,
{
memcpy(dev, proto, proto->params_size);
dev->memory = mem;
+ dev->retained = !internal;
rc_init(dev, mem, (internal ? 0 : 1));
}
/* Make a null device. */
void
-gs_make_null_device(gx_device_null *dev_null, const gx_device *dev,
+gs_make_null_device(gx_device_null *dev_null, gx_device *dev,
gs_memory_t * mem)
{
gx_device_init((gx_device *)dev_null, (const gx_device *)&gs_null_device,
mem, true);
- dev_null->target = dev;
+ gx_device_set_target((gx_device_forward *)dev_null, dev);
if (dev)
gx_device_copy_color_params((gx_device *)dev_null, dev);
}
+/* Mark a device as retained or not retained. */
+void
+gx_device_retain(gx_device *dev, bool retained)
+{
+ int delta = (int)retained - (int)dev->retained;
+
+ if (delta) {
+ dev->retained = retained; /* do first in case dev is freed */
+ rc_adjust_only(dev, delta, "gx_device_retain");
+ }
+}
+
/* Select a null device. */
int
gs_nulldevice(gs_state * pgs)
{
if (pgs->device == 0 || !gx_device_is_null(pgs->device)) {
gx_device *ndev;
- int code = gs_copydevice(&ndev, (gx_device *) & gs_null_device,
+ int code = gs_copydevice(&ndev, (const gx_device *)&gs_null_device,
pgs->memory);
if (code < 0)
@@ -424,7 +454,7 @@ gs_closedevice(gx_device * dev)
int code = 0;
if (dev->is_open) {
- code = (*dev_proc(dev, close_device)) (dev);
+ code = (*dev_proc(dev, close_device))(dev);
if (code < 0)
return_error(code);
dev->is_open = false;
@@ -528,6 +558,8 @@ gx_device_copy_color_procs(gx_device *dev, const gx_device *target)
{
dev_proc_map_cmyk_color((*from_cmyk)) =
dev_proc(dev, map_cmyk_color);
+ dev_proc_map_rgb_color((*from_rgb)) =
+ dev_proc(dev, map_rgb_color);
dev_proc_map_color_rgb((*to_rgb)) =
dev_proc(dev, map_color_rgb);
@@ -540,6 +572,13 @@ gx_device_copy_color_procs(gx_device *dev, const gx_device *target)
from_cmyk == cmyk_8bit_map_cmyk_color ?
from_cmyk : gx_forward_map_cmyk_color));
}
+ if (from_rgb == gx_forward_map_rgb_color ||
+ from_rgb == gx_default_rgb_map_rgb_color) {
+ from_rgb = dev_proc(target, map_rgb_color);
+ set_dev_proc(dev, map_rgb_color,
+ (from_rgb == gx_default_rgb_map_rgb_color ?
+ from_rgb : gx_forward_map_rgb_color));
+ }
if (to_rgb == gx_forward_map_color_rgb ||
to_rgb == cmyk_1bit_map_color_rgb ||
to_rgb == cmyk_8bit_map_color_rgb) {
diff --git a/gs/src/gsdevice.h b/gs/src/gsdevice.h
index 93271da07..fb84cc320 100644
--- a/gs/src/gsdevice.h
+++ b/gs/src/gsdevice.h
@@ -65,15 +65,17 @@ int gs_initialize_wordimagedevice(P9(gx_device_memory * new_dev,
const byte * colors, int colors_size,
bool word_oriented, bool page_device,
gs_memory_t * mem));
-
const char *gs_devicename(P1(const gx_device *));
void gs_deviceinitialmatrix(P2(gx_device *, gs_matrix *));
-int gs_get_device_or_hardware_params(P3(gx_device *, gs_param_list *, bool));
+/* VMS limits identifiers to 31 characters. */
+int gs_get_device_or_hw_params(P3(gx_device *, gs_param_list *, bool));
#define gs_getdeviceparams(dev, plist)\
- gs_get_device_or_hardware_params(dev, plist, false)
+ gs_get_device_or_hw_params(dev, plist, false)
#define gs_gethardwareparams(dev, plist)\
- gs_get_device_or_hardware_params(dev, plist, true)
+ gs_get_device_or_hw_params(dev, plist, true)
+/* BACKWARD COMPATIBILITY */
+#define gs_get_device_or_hardware_params gs_get_device_or_hw_params
int gs_putdeviceparams(P2(gx_device *, gs_param_list *));
int gs_closedevice(P1(gx_device *));
@@ -86,13 +88,13 @@ typedef struct gs_imager_state_s gs_imager_state;
#endif
int gs_imager_putdeviceparams(P3(gs_imager_state *pis, gx_device *dev,
- gs_param_list *plist));
+ gs_param_list *plist));
/* Device procedures involving a graphics state. */
#ifndef gs_state_DEFINED
# define gs_state_DEFINED
- typedef struct gs_state_s gs_state;
+typedef struct gs_state_s gs_state;
#endif
int gs_flushpage(P1(gs_state *));
@@ -100,8 +102,8 @@ int gs_copypage(P1(gs_state *));
int gs_output_page(P3(gs_state *, int, int));
int gs_nulldevice(P1(gs_state *));
int gs_setdevice(P2(gs_state *, gx_device *));
-int gs_setdevice_no_erase(P2(gs_state *, gx_device *)); /* returns 1 */
- /* if erasepage required */
+int gs_setdevice_no_erase(P2(gs_state *, gx_device *)); /* returns 1 */
+ /* if erasepage required */
int gs_setdevice_no_init(P2(gs_state *, gx_device *));
gx_device *gs_currentdevice(P1(const gs_state *));
@@ -111,5 +113,5 @@ gx_device *gs_currentdevice(P1(const gs_state *));
#endif
int gs_state_putdeviceparams(P2(gs_state *pgs, gs_param_list *plist));
-
+
#endif /* gsdevice_INCLUDED */
diff --git a/gs/src/gsdll.c b/gs/src/gsdll.c
index 09716c8d9..6efd9de67 100644
--- a/gs/src/gsdll.c
+++ b/gs/src/gsdll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -46,16 +46,39 @@
#include "store.h"
#include "files.h" /* requires stream.h */
#include "interp.h"
+
+/*
+ * The following block of platform-specific conditionals is contrary to
+ * Ghostscript's portability policy. It is here because it doesn't
+ * represent any useful abstraction, so isn't a good candidate for
+ * encapsulation in a header file either.
+ */
+
#ifdef _Windows
#include "windows_.h"
#ifndef __WIN32__
#define GSDLLEXPORT _export
#endif
-#else
+#else /* !_Windows */
+
+#ifdef __OS2__
#define INCL_DOS
#define INCL_WIN
#include <os2.h>
-#endif
+#else /* !__OS2__ */
+
+#ifdef __MACINTOSH__
+/* Nothing special for the Mac. */
+#endif /* !__MACINTOSH__ */
+
+#endif /* !__OS2__ */
+
+#endif /* !_Windows */
+
+/*
+ * End of platform-specific conditionals.
+ */
+
#include "gsdll.h" /* header for DLLs */
#include <setjmp.h>
@@ -65,8 +88,7 @@ private int gsdll_usage; /* should be needed only for 16-bit SHARED DATA */
/****** SINGLE-INSTANCE HACK ******/
private gs_main_instance *gsdll_minst; /* instance data */
-extern HWND hwndtext; /* in gp_mswin.h */
-
+extern HWND hwndtext; /* in gp_mswin.c, gp_os2.c, or gp_mac.c */
GSDLL_CALLBACK pgsdll_callback; /* callback for messages and stdio to caller */
diff --git a/gs/src/gsdll.h b/gs/src/gsdll.h
index 858c0e071..d962e32ec 100644
--- a/gs/src/gsdll.h
+++ b/gs/src/gsdll.h
@@ -1,4 +1,5 @@
/* Copyright (C) 1994-1996, Russell Lang. All rights reserved.
+ Portions Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,9 +22,15 @@
#ifndef gsdll_INCLUDED
# define gsdll_INCLUDED
+
+#ifdef __MACINTOSH__
-#ifndef _GSDLL_H
-#define _GSDLL_H
+#define HWND char *
+#define GSFAR
+#include <QDOffscreen.h>
+#pragma export on
+
+#endif
#ifndef GSDLLEXPORT
#define GSDLLEXPORT
@@ -100,18 +107,6 @@ int GSDLLAPI gsdll_execute_end(void);
int GSDLLAPI gsdll_exit(void);
int GSDLLAPI gsdll_lock_device(unsigned char *device, int flag);
-#ifdef _Windows
-HGLOBAL GSDLLAPI gsdll_copy_dib(unsigned char GSFAR * device);
-HPALETTE GSDLLAPI gsdll_copy_palette(unsigned char GSFAR * device);
-void GSDLLAPI gsdll_draw(unsigned char GSFAR * device, HDC hdc, LPRECT dest, LPRECT src);
-int GSDLLAPI gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
- LPRGBQUAD prgbquad, LPBYTE * ppbyte, unsigned int row);
-
-#else
-unsigned long gsdll_get_bitmap(unsigned char *device, unsigned char **pbitmap);
-
-#endif
-
/* Function pointer typedefs */
/* for run time dynamic linking */
typedef int (GSDLLAPI * PFN_gsdll_revision) (char GSFAR * GSFAR *, char GSFAR * GSFAR *, long GSFAR *, long GSFAR *);
@@ -122,18 +117,8 @@ typedef int (GSDLLAPI * PFN_gsdll_execute_end) (void);
typedef int (GSDLLAPI * PFN_gsdll_exit) (void);
typedef int (GSDLLAPI * PFN_gsdll_lock_device) (unsigned char GSFAR *, int);
-#ifdef _Windows
-typedef HGLOBAL(GSDLLAPI * PFN_gsdll_copy_dib) (unsigned char GSFAR *);
-typedef HPALETTE(GSDLLAPI * PFN_gsdll_copy_palette) (unsigned char GSFAR *);
-typedef void (GSDLLAPI * PFN_gsdll_draw) (unsigned char GSFAR *, HDC, LPRECT, LPRECT);
-typedef int (GSDLLAPI * PFN_gsdll_get_bitmap_row) (unsigned char *device, LPBITMAPINFOHEADER pbmih,
- LPRGBQUAD prgbquad, LPBYTE * ppbyte, unsigned int row);
-
-#else
-typedef long (*GSDLLAPI PFN_gsdll_get_bitmap) (unsigned char *, unsigned char **);
-
-#endif
-
+#ifdef __MACINTOSH__
+#pragma export off
#endif
#endif /* gsdll_INCLUDED */
diff --git a/gs/src/gsdll16.def b/gs/src/gsdll16.def
deleted file mode 100644
index 218b44775..000000000
--- a/gs/src/gsdll16.def
+++ /dev/null
@@ -1,20 +0,0 @@
-LIBRARY GSDLL16
-DESCRIPTION 'Ghostscript Interpreter DLL'
-CODE PRELOAD DISCARDABLE
-DATA SINGLE SHARED PRELOAD
-SEGMENTS GSDLL_TEXT PRELOAD NONDISCARDABLE
- GDEVMSWN_TEXT PRELOAD NONDISCARDABLE
- GDEVWDIB_TEXT PRELOAD NONDISCARDABLE
- GP_MSWIN_TEXT PRELOAD NONDISCARDABLE
-EXPORTS
- gsdll_revision @1
- gsdll_init @2
- gsdll_execute_begin @3
- gsdll_execute_cont @4
- gsdll_execute_end @5
- gsdll_exit @6
- gsdll_lock_device @7
- gsdll_copy_dib @8
- gsdll_copy_palette @9
- gsdll_draw @10
- gsdll_get_bitmap_row @11
diff --git a/gs/src/gsdll16.rc b/gs/src/gsdll16.rc
deleted file mode 100644
index 252a350ff..000000000
--- a/gs/src/gsdll16.rc
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <windows.h>
-#include "gp_mswin.h"
-
-GSTEXT_ICON ICON gstext.ico
-GSIMAGE_ICON ICON gsgraph.ico
-
-#ifndef DS_3DLOOK
-#define DS_3DLOOK 0x0004L /* for Windows 95 look */
-#endif
-
-SpoolDlgBox DIALOG 32, 40, 110, 63
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_3DLOOK
-CAPTION "Select Printer Port"
-BEGIN
- CONTROL "&Ok", IDOK, "button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 72, 14, 32, 14
- CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 72, 36, 32, 14
- CONTROL "", SPOOL_PORT, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 8, 8, 56, 50
-END
-
-CancelDlgBox DIALOG 32, 40, 120, 48
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_3DLOOK
-BEGIN
- CTEXT "Printing", -1, 8, 4, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
- CTEXT "", CANCEL_PCDONE, 8, 16, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
- CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 44, 30, 32, 14
-END
diff --git a/gs/src/gsdll32.rc b/gs/src/gsdll32.rc
index 252a350ff..91ec73ad5 100644
--- a/gs/src/gsdll32.rc
+++ b/gs/src/gsdll32.rc
@@ -1,8 +1,36 @@
+/* Copyright (C) 1996, 1998 Russell Lang. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+
+
#include <windows.h>
#include "gp_mswin.h"
-GSTEXT_ICON ICON gstext.ico
-GSIMAGE_ICON ICON gsgraph.ico
+#ifndef gstext_ico
+#define gstext_ico gstext.ico
+#endif
+#ifndef gsgraph_ico
+#define gsgraph_ico gsgraph.ico
+#endif
+
+GSTEXT_ICON ICON gstext_ico
+GSIMAGE_ICON ICON gsgraph_ico
#ifndef DS_3DLOOK
#define DS_3DLOOK 0x0004L /* for Windows 95 look */
diff --git a/gs/src/gsdllos2.h b/gs/src/gsdllos2.h
new file mode 100644
index 000000000..60624210d
--- /dev/null
+++ b/gs/src/gsdllos2.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 1994-1996, Russell Lang. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* gsdll extension for OS/2 platforms */
+
+#ifndef gsdllos2_INCLUDED
+# define gsdllos2_INCLUDED
+
+/* DLL exported functions */
+/* for load time dynamic linking */
+unsigned long gsdll_get_bitmap(unsigned char *device, unsigned char **pbitmap);
+
+/* Function pointer typedefs */
+/* for run time dynamic linking */
+typedef long (*GSDLLAPI PFN_gsdll_get_bitmap) (unsigned char *, unsigned char **);
+
+#endif /* gsdllos2_INCLUDED */
diff --git a/gs/src/gsdllwin.h b/gs/src/gsdllwin.h
new file mode 100644
index 000000000..311f50975
--- /dev/null
+++ b/gs/src/gsdllwin.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 1994-1996, Russell Lang. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* gsdll extension for Microsoft Windows platforms */
+
+#ifndef gsdllwin_INCLUDED
+# define gsdllwin_INCLUDED
+
+/* DLL exported functions */
+/* for load time dynamic linking */
+HGLOBAL GSDLLAPI gsdll_copy_dib(unsigned char GSFAR * device);
+HPALETTE GSDLLAPI gsdll_copy_palette(unsigned char GSFAR * device);
+void GSDLLAPI gsdll_draw(unsigned char GSFAR * device, HDC hdc, LPRECT dest,
+ LPRECT src);
+int GSDLLAPI gsdll_get_bitmap_row(unsigned char *device,
+ LPBITMAPINFOHEADER pbmih,
+ LPRGBQUAD prgbquad, LPBYTE * ppbyte,
+ unsigned int row);
+
+/* Function pointer typedefs */
+/* for run time dynamic linking */
+typedef HGLOBAL (GSDLLAPI * PFN_gsdll_copy_dib)(unsigned char GSFAR *);
+typedef HPALETTE (GSDLLAPI * PFN_gsdll_copy_palette)(unsigned char GSFAR *);
+typedef void (GSDLLAPI * PFN_gsdll_draw) (unsigned char GSFAR *, HDC, LPRECT,
+ LPRECT);
+typedef int (GSDLLAPI * PFN_gsdll_get_bitmap_row)
+ (unsigned char *device, LPBITMAPINFOHEADER pbmih, LPRGBQUAD prgbquad,
+ LPBYTE * ppbyte, unsigned int row);
+
+#endif /* gsdllwin_INCLUDED */
diff --git a/gs/src/gsdparam.c b/gs/src/gsdparam.c
index 5851122a7..d872f9d88 100644
--- a/gs/src/gsdparam.c
+++ b/gs/src/gsdparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -37,8 +37,8 @@ private bool param_HWColorMap(P2(gx_device *, byte *));
/* Get the device parameters. */
int
-gs_get_device_or_hardware_params(gx_device * dev, gs_param_list * plist,
- bool is_hardware)
+gs_get_device_or_hw_params(gx_device * dev, gs_param_list * plist,
+ bool is_hardware)
{
gx_device_set_procs(dev);
fill_dev_proc(dev, get_params, gx_default_get_params);
@@ -63,8 +63,11 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist)
/* Standard page device parameters: */
+ int mns = 1;
+ bool seprs = false;
gs_param_string dns, pcms;
gs_param_float_array msa, ibba, hwra, ma;
+ gs_param_string_array scna;
#define set_param_array(a, d, s)\
(a.data = d, a.size = s, a.persistent = false);
@@ -95,6 +98,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist)
set_param_array(msa, dev->MediaSize, 2);
set_param_array(ibba, dev->ImagingBBox, 4);
set_param_array(ma, dev->Margins, 2);
+ set_param_array(scna, NULL, 0);
/* Fill in non-standard parameters. */
@@ -107,37 +111,47 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist)
/* Transmit the values. */
if (
- /* Standard parameters */
- (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
+ /* Standard parameters */
+
+ (code = param_write_name(plist, "OutputDevice", &dns)) < 0 ||
#ifdef PAGESIZE_IS_MEDIASIZE
- (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
+ (code = param_write_float_array(plist, "PageSize", &msa)) < 0 ||
#endif
- (code = (pcms.data == 0 ? 0 :
- param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
- (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
- (code = (dev->ImagingBBox_set ?
- param_write_float_array(plist, "ImagingBBox", &ibba) :
- param_write_null(plist, "ImagingBBox"))) < 0 ||
- (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
- (code = (dev->NumCopies_set < 0 ||
- (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
- dev->NumCopies_set ?
- param_write_int(plist, "NumCopies", &dev->NumCopies) :
- param_write_null(plist, "NumCopies"))) < 0 ||
-
- /* Non-standard parameters */
-
- (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
- (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
- (code = param_write_float_array(plist, ".MarginsHWResolution", &mhwra)) < 0 ||
- (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
- (code = param_write_string(plist, "Name", &dns)) < 0 ||
- (code = param_write_int(plist, "Colors", &colors)) < 0 ||
- (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
- (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
- (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
- (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0
+ (code = (pcms.data == 0 ? 0 :
+ param_write_name(plist, "ProcessColorModel", &pcms))) < 0 ||
+ (code = param_write_float_array(plist, "HWResolution", &hwra)) < 0 ||
+ (code = (dev->ImagingBBox_set ?
+ param_write_float_array(plist, "ImagingBBox", &ibba) :
+ param_write_null(plist, "ImagingBBox"))) < 0 ||
+ (code = param_write_float_array(plist, "Margins", &ma)) < 0 ||
+ (code = param_write_int(plist, "MaxSeparations", &mns)) < 0 ||
+ (code = (dev->NumCopies_set < 0 ||
+ (*dev_proc(dev, get_page_device))(dev) == 0 ? 0:
+ dev->NumCopies_set ?
+ param_write_int(plist, "NumCopies", &dev->NumCopies) :
+ param_write_null(plist, "NumCopies"))) < 0 ||
+ (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 ||
+ (code = param_write_bool(plist, "Separations", &seprs)) < 0 ||
+ (code = param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor)) < 0 ||
+
+ /* Non-standard parameters */
+
+ (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 ||
+ (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 ||
+ (code = param_write_float_array(plist, ".MarginsHWResolution", &mhwra)) < 0 ||
+ (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 ||
+ (code = param_write_string(plist, "Name", &dns)) < 0 ||
+ (code = param_write_int(plist, "Colors", &colors)) < 0 ||
+ (code = param_write_int(plist, "BitsPerPixel", &depth)) < 0 ||
+ (code = param_write_int(plist, "GrayValues", &GrayValues)) < 0 ||
+ (code = param_write_long(plist, "PageCount", &dev->PageCount)) < 0 ||
+ (code = param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies)) < 0 ||
+ (code = param_write_int(plist, "TextAlphaBits",
+ &dev->color_info.anti_alias.text_bits)) < 0 ||
+ (code = param_write_int(plist, "GraphicsAlphaBits",
+ &dev->color_info.anti_alias.graphics_bits)) < 0
+
)
return code;
@@ -165,14 +179,6 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist)
if ((code = param_write_string(plist, "HWColorMap", &hwcms)) < 0)
return code;
}
- } {
- int tab = (*dev_proc(dev, get_alpha_bits)) (dev, go_text);
- int gab = (*dev_proc(dev, get_alpha_bits)) (dev, go_graphics);
-
- if ((code = param_write_int(plist, "TextAlphaBits", &tab)) < 0 ||
- (code = param_write_int(plist, "GraphicsAlphaBits", &gab)) < 0
- )
- return code;
}
return 0;
@@ -360,13 +366,11 @@ gdev_end_output_media(gs_param_list * mlist, gs_param_dict * pdict)
/* ================ Putting parameters ================ */
/* Forward references */
+private int param_anti_alias_bits(P3(gs_param_list *, gs_param_name, int *));
private int param_MediaSize(P4(gs_param_list *, gs_param_name,
const float *, gs_param_float_array *));
-#if 0 /****** not used ***** */
private int param_check_bool(P4(gs_param_list *, gs_param_name, bool, bool));
-
-#endif /****** not used ***** */
private int param_check_long(P4(gs_param_list *, gs_param_name, long, bool));
#define param_check_int(plist, pname, ival, defined)\
@@ -409,10 +413,11 @@ gx_default_put_params(gx_device * dev, gs_param_list * plist)
gs_param_float_array ma;
gs_param_float_array hwma;
gs_param_float_array mhwra;
+ gs_param_string_array scna;
int nci = dev->NumCopies;
int ncset = dev->NumCopies_set;
-
bool ignc = dev->IgnoreNumCopies;
+ bool ucc = dev->UseCIEColor;
gs_param_float_array ibba;
bool ibbnull = false;
int colors = dev->color_info.num_components;
@@ -420,27 +425,36 @@ gx_default_put_params(gx_device * dev, gs_param_list * plist)
int GrayValues = dev->color_info.max_gray + 1;
int RGBValues = dev->color_info.max_color + 1;
long ColorValues = 1L << depth;
+ int tab = dev->color_info.anti_alias.text_bits;
+ int gab = dev->color_info.anti_alias.graphics_bits;
gs_param_string cms;
+ /*
+ * Template:
+ * BEGIN_ARRAY_PARAM(param_read_xxx_array, "pname", pxxa, size, pxxe) {
+ * ... check value if desired ...
+ * if (success)
+ * break;
+ * ... set ecode ...
+ * } END_ARRAY_PARAM(pxxa, pxxe);
+ */
+
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
- switch ( code = pread(plist, (param_name = pname), &(pa)) )\
- {\
- case 0:\
+ BEGIN\
+ switch (code = pread(plist, (param_name = pname), &(pa))) {\
+ case 0:\
if ( (pa).size != psize )\
ecode = gs_note_error(gs_error_rangecheck);\
- else {
-/* The body of the processing code goes here. */
-/* If it succeeds, it should do a 'break'; */
-/* if it fails, it should set ecode and fall through. */
+ else
#define END_ARRAY_PARAM(pa, e)\
- }\
goto e;\
- default:\
+ default:\
ecode = code;\
e: param_signal_error(plist, param_name, ecode);\
- case 1:\
+ case 1:\
(pa).data = 0; /* mark as not filled */\
- }
+ }\
+ END
/*
* The HWResolution, HWSize, and MediaSize parameters interact in
@@ -454,28 +468,29 @@ e: param_signal_error(plist, param_name, ecode);\
* setting both HWResolution and HWSize.
*/
- BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre)
+ BEGIN_ARRAY_PARAM(param_read_float_array, "HWResolution", hwra, 2, hwre) {
if (hwra.data[0] <= 0 || hwra.data[1] <= 0)
- ecode = gs_note_error(gs_error_rangecheck);
- else
- break;
- END_ARRAY_PARAM(hwra, hwre)
- BEGIN_ARRAY_PARAM(param_read_int_array, "HWSize", hwsa, 2, hwsa)
- /* We need a special check to handle the nullpage device, */
- /* whose size is legitimately [0 0]. */
+ ecode = gs_note_error(gs_error_rangecheck);
+ else
+ break;
+ } END_ARRAY_PARAM(hwra, hwre);
+ BEGIN_ARRAY_PARAM(param_read_int_array, "HWSize", hwsa, 2, hwsa) {
+ /* We need a special check to handle the nullpage device, */
+ /* whose size is legitimately [0 0]. */
if ((hwsa.data[0] <= 0 && hwsa.data[0] != dev->width) ||
(hwsa.data[1] <= 0 && hwsa.data[1] != dev->height)
)
- ecode = gs_note_error(gs_error_rangecheck);
+ ecode = gs_note_error(gs_error_rangecheck);
#define max_coord (max_fixed / fixed_1)
#if max_coord < max_int
- else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
- ecode = gs_note_error(gs_error_limitcheck);
+ else if (hwsa.data[0] > max_coord || hwsa.data[1] > max_coord)
+ ecode = gs_note_error(gs_error_limitcheck);
#endif
#undef max_coord
- else
- break;
- END_ARRAY_PARAM(hwsa, hwse) {
+ else
+ break;
+ } END_ARRAY_PARAM(hwsa, hwse);
+ {
const float *res = (hwra.data == 0 ? dev->HWResolution : hwra.data);
#ifdef PAGESIZE_IS_MEDIASIZE
@@ -501,22 +516,22 @@ e: param_signal_error(plist, param_name, ecode);\
#endif
}
- BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me)
+ BEGIN_ARRAY_PARAM(param_read_float_array, "Margins", ma, 2, me) {
break;
- END_ARRAY_PARAM(ma, me)
- BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme)
+ } END_ARRAY_PARAM(ma, me);
+ BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) {
break;
- END_ARRAY_PARAM(hwma, hwme)
+ } END_ARRAY_PARAM(hwma, hwme);
/* MarginsHWResolution cannot be changed, only checked. */
- BEGIN_ARRAY_PARAM(param_read_float_array, ".MarginsHWResolution", mhwra, 2, mhwre)
+ BEGIN_ARRAY_PARAM(param_read_float_array, ".MarginsHWResolution", mhwra, 2, mhwre) {
if (mhwra.data[0] != dev->MarginsHWResolution[0] ||
mhwra.data[1] != dev->MarginsHWResolution[1]
)
- ecode = gs_note_error(gs_error_rangecheck);
- else
- break;
- END_ARRAY_PARAM(mhwra, mhwre)
- switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
+ ecode = gs_note_error(gs_error_rangecheck);
+ else
+ break;
+ } END_ARRAY_PARAM(mhwra, mhwre);
+ switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) {
default:
ecode = code;
param_signal_error(plist, param_name, ecode);
@@ -548,7 +563,14 @@ nce:
break;
}
}
-
+ if ((code = param_read_bool(plist, (param_name = "UseCIEColor"), &ucc)) < 0) {
+ ecode = code;
+ param_signal_error(plist, param_name, ecode);
+ }
+ if ((code = param_anti_alias_bits(plist, "TextAlphaBits", &tab)) < 0)
+ ecode = code;
+ if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0)
+ ecode = code;
/* Ignore parameters that only have meaning for printers. */
#define IGNORE_INT_PARAM(pname)\
@@ -591,6 +613,13 @@ nce:
ecode = code;
if ((code = param_check_string(plist, "ProcessColorModel", pcmsa[colors], colors != 0)) < 0)
ecode = code;
+ if ((code = param_check_int(plist, "MaxSeparations", 1, true)) < 0)
+ ecode = code;
+ if ((code = param_check_bool(plist, "Separations", false, true)) < 0)
+ ecode = code;
+ BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", scna, 0, scne) {
+ break;
+ } END_ARRAY_PARAM(scna, scne);
if ((code = param_check_string(plist, "Name", dev->dname, true)) < 0)
ecode = code;
if ((code = param_check_int(plist, "Colors", colors, true)) < 0)
@@ -599,11 +628,8 @@ nce:
ecode = code;
if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0)
ecode = code;
-#if 0
-/* taken out to fix problem with multipage PCL files in async mode */
if ((code = param_check_long(plist, "PageCount", dev->PageCount, true)) < 0)
ecode = code;
-#endif
if ((code = param_check_int(plist, "RedValues", RGBValues, colors > 1)) < 0)
ecode = code;
if ((code = param_check_int(plist, "GreenValues", RGBValues, colors > 1)) < 0)
@@ -623,18 +649,6 @@ nce:
if (code < 0)
ecode = code;
}
- if ((code =
- param_check_int(plist, "TextAlphaBits",
- (*dev_proc(dev, get_alpha_bits)) (dev, go_text),
- true)) < 0
- )
- ecode = code;
- if ((code =
- param_check_int(plist, "GraphicsAlphaBits",
- (*dev_proc(dev, get_alpha_bits)) (dev, go_graphics),
- true)) < 0
- )
- ecode = code;
/* We must 'commit', in order to detect unknown parameters, */
/* even if there were errors. */
@@ -696,10 +710,36 @@ nce:
} else if (ibbnull) {
dev->ImagingBBox_set = false;
}
+ dev->UseCIEColor = ucc;
+ dev->color_info.anti_alias.text_bits = tab;
+ dev->color_info.anti_alias.graphics_bits = gab;
gx_device_decache_colors(dev);
return 0;
}
+/* Read TextAlphaBits or GraphicsAlphaBits. */
+private int
+param_anti_alias_bits(gs_param_list * plist, gs_param_name param_name, int *pa)
+{
+ int code = param_read_int(plist, param_name, pa);
+
+ switch (code) {
+ case 0:
+ switch (*pa) {
+ case 1: case 2: case 4:
+ return 0;
+ default:
+ code = gs_error_rangecheck;
+ }
+ default:
+ param_signal_error(plist, param_name, code);
+ case 1:
+ ;
+ }
+ return code;
+}
+
+
/* Read .MediaSize or, if supported as a synonym, PageSize. */
private int
param_MediaSize(gs_param_list * plist, gs_param_name pname,
@@ -709,25 +749,24 @@ param_MediaSize(gs_param_list * plist, gs_param_name pname,
int ecode = 0;
int code;
- BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse)
+ BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) {
float width_new = pa->data[0] * res[0] / 72;
- float height_new = pa->data[1] * res[1] / 72;
+ float height_new = pa->data[1] * res[1] / 72;
- if (width_new < 0 || height_new < 0)
- ecode = gs_note_error(gs_error_rangecheck);
+ if (width_new < 0 || height_new < 0)
+ ecode = gs_note_error(gs_error_rangecheck);
#define max_coord (max_fixed / fixed_1)
#if max_coord < max_int
- else if (width_new > max_coord || height_new > max_coord)
- ecode = gs_note_error(gs_error_limitcheck);
+ else if (width_new > max_coord || height_new > max_coord)
+ ecode = gs_note_error(gs_error_limitcheck);
#endif
#undef max_coord
- else
- break;
- END_ARRAY_PARAM(*pa, mse)
- return ecode;
+ else
+ break;
+ } END_ARRAY_PARAM(*pa, mse);
+ return ecode;
}
-#if 0 /****** not used ***** */
/* Check that a nominally read-only parameter is being set to */
/* its existing value. */
private int
@@ -752,7 +791,6 @@ param_check_bool(gs_param_list * plist, gs_param_name pname, bool value,
}
return code;
}
-#endif /****** not used ***** */
private int
param_check_long(gs_param_list * plist, gs_param_name pname, long value,
bool defined)
diff --git a/gs/src/gsfcmap.c b/gs/src/gsfcmap.c
index a279716ee..a2f447a27 100644
--- a/gs/src/gsfcmap.c
+++ b/gs/src/gsfcmap.c
@@ -58,16 +58,18 @@ RELOC_PTR(gx_code_map, cmap);
RELOC_PTRS_END
#undef pcmap
-/* CIDSystemInfo structure */
-public_st_cid_system_info();
+/* CIDSystemInfo structure descriptors */
+private_st_cid_system_info();
+public_st_cid_system_info_element();
/* ---------------- Procedures ---------------- */
/*
* Decode a character from a string using a code map, updating the index.
* Return 0 for a CID or name, N > 0 for a character code where N is the
- * number of bytes in the code, or an error. For undefined characters,
- * we set *pglyph = gs_no_glyph and return 0.
+ * number of bytes in the code, or an error. In the case of a character
+ * code, shift the bytes into *pchr. For undefined characters, we set
+ * *pglyph = gs_no_glyph and return 0.
*/
private int
code_map_decode_next(const gx_code_map * pcmap, const gs_const_string * str,
@@ -91,7 +93,6 @@ leaf: if (chr > map->last)
if (map->add_offset)
*pglyph += chr - map->first;
*pfidx = map->byte_data.font_index;
- *pchr = chr & 0xff;
if_debug3('J', " 0x%lx, fidx %u, result %d\n",
*pglyph, *pfidx, result);
return result;
@@ -118,6 +119,7 @@ leaf: if (chr > map->last)
else
hi = mid;
}
+ *pchr = (*pchr << 8) | chr;
map = &map[lo];
continue;
}
@@ -142,9 +144,11 @@ gs_cmap_decode_next(const gs_cmap * pcmap, const gs_const_string * str,
gs_char * pchr, gs_glyph * pglyph)
{
uint save_index = *pindex;
- int code =
- code_map_decode_next(&pcmap->def, str, pindex, pfidx, pchr, pglyph);
+ int code;
+ *pchr = 0;
+ code =
+ code_map_decode_next(&pcmap->def, str, pindex, pfidx, pchr, pglyph);
if (code != 0 || *pglyph != gs_no_glyph)
return code;
/* This is an undefined character. Use the notdef map. */
@@ -152,6 +156,7 @@ gs_cmap_decode_next(const gs_cmap * pcmap, const gs_const_string * str,
uint next_index = *pindex;
*pindex = save_index;
+ *pchr = 0;
code =
code_map_decode_next(&pcmap->notdef, str, pindex, pfidx,
pchr, pglyph);
diff --git a/gs/src/gsfcmap.h b/gs/src/gsfcmap.h
index 8c15700d1..0c2bdb39a 100644
--- a/gs/src/gsfcmap.h
+++ b/gs/src/gsfcmap.h
@@ -29,25 +29,8 @@
#ifndef gs_cmap_DEFINED
# define gs_cmap_DEFINED
typedef struct gs_cmap_s gs_cmap;
-
#endif
-/* We only need the structure descriptor for testing. */
-extern_st(st_cmap);
-
-/* Define the structure for CIDSystemInfo. */
-typedef struct gs_cid_system_info_s {
- gs_const_string Registry;
- gs_const_string Ordering;
- int Supplement;
-} gs_cid_system_info;
-/* We only need the structure descriptor for embedding. */
-extern_st(st_cid_system_info);
-#define public_st_cid_system_info() /* in gsfcmap.c */\
- gs_public_st_const_strings2(st_cid_system_info, gs_cid_system_info,\
- "gs_cid_system_info", cid_si_enum_ptrs, cid_si_reloc_ptrs,\
- Registry, Ordering)
-
/* ---------------- Procedural interface ---------------- */
/*
diff --git a/gs/src/gsflip.c b/gs/src/gsflip.c
index 21185de71..ab6c28163 100644
--- a/gs/src/gsflip.c
+++ b/gs/src/gsflip.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,86 +19,84 @@
/* Routines for "flipping" image data */
#include "gx.h"
+#include "gserrors.h" /* for rangecheck in sample macros */
+#include "gsbitops.h"
#include "gsbittab.h"
#include "gsflip.h"
-#define arch_has_byte_regs 1
+#define ARCH_HAS_BYTE_REGS 1
/* Transpose a block of bits between registers. */
-#define transpose(r,s,mask,shift)\
- r ^= (temp = ((s << shift) ^ r) & mask);\
- s ^= temp >> shift
+#define TRANSPOSE(r,s,mask,shift)\
+ r ^= (temp = ((s >> shift) ^ r) & mask);\
+ s ^= temp << shift
/* Define the size of byte temporaries. On Intel CPUs, this should be */
/* byte, but on all other CPUs, it should be uint. */
-#if arch_has_byte_regs
+#if ARCH_HAS_BYTE_REGS
typedef byte byte_var;
-
#else
typedef uint byte_var;
-
#endif
-#define vtab(v80,v40,v20,v10,v8,v4,v2,v1)\
+#define VTAB(v80,v40,v20,v10,v8,v4,v2,v1)\
bit_table_8(0,v80,v40,v20,v10,v8,v4,v2,v1)
/* Convert 3Mx1 to 3x1. */
-private void
-flip3x1(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip3x1(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
- uint n = nbytes;
- static const bits32 tab3x1[256] =
- {
- vtab(0x800000, 0x100000, 0x20000, 0x4000, 0x800, 0x100, 0x20, 4)
+ int n = nbytes;
+ static const bits32 tab3x1[256] = {
+ VTAB(0x800000, 0x100000, 0x20000, 0x4000, 0x800, 0x100, 0x20, 4)
};
for (; n > 0; out += 3, ++in1, ++in2, ++in3, --n) {
- bits32 b24 =
- tab3x1[*in1] | (tab3x1[*in2] >> 1) | (tab3x1[*in3] >> 2);
+ bits32 b24 = tab3x1[*in1] | (tab3x1[*in2] >> 1) | (tab3x1[*in3] >> 2);
out[0] = (byte) (b24 >> 16);
out[1] = (byte) (b24 >> 8);
out[2] = (byte) b24;
}
+ return 0;
}
/* Convert 3Mx2 to 3x2. */
-private void
-flip3x2(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip3x2(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
- uint n = nbytes;
- static const bits32 tab3x2[256] =
- {
- vtab(0x800000, 0x400000, 0x20000, 0x10000, 0x800, 0x400, 0x20, 0x10)
+ int n = nbytes;
+ static const bits32 tab3x2[256] = {
+ VTAB(0x800000, 0x400000, 0x20000, 0x10000, 0x800, 0x400, 0x20, 0x10)
};
for (; n > 0; out += 3, ++in1, ++in2, ++in3, --n) {
- bits32 b24 =
- tab3x2[*in1] | (tab3x2[*in2] >> 2) | (tab3x2[*in3] >> 4);
+ bits32 b24 = tab3x2[*in1] | (tab3x2[*in2] >> 2) | (tab3x2[*in3] >> 4);
out[0] = (byte) (b24 >> 16);
out[1] = (byte) (b24 >> 8);
out[2] = (byte) b24;
}
+ return 0;
}
/* Convert 3Mx4 to 3x4. */
-private void
-flip3x4(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip3x4(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 3, ++in1, ++in2, ++in3, --n) {
byte_var b1 = *in1, b2 = *in2, b3 = *in3;
@@ -107,38 +105,41 @@ flip3x4(byte * buffer, const byte ** planes, uint offset, uint nbytes)
out[1] = (b3 & 0xf0) | (b1 & 0xf);
out[2] = (byte) (b2 << 4) | (b3 & 0xf);
}
+ return 0;
}
/* Convert 3Mx8 to 3x8. */
-private void
-flip3x8(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip3x8(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 3, ++in1, ++in2, ++in3, --n) {
out[0] = *in1;
out[1] = *in2;
out[2] = *in3;
}
+ return 0;
}
/* Convert 3Mx12 to 3x12. */
-private void
-flip3x12(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip3x12(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *pa = planes[0] + offset;
const byte *pb = planes[1] + offset;
const byte *pc = planes[2] + offset;
- uint n = nbytes;
-
- /* We are guaranteed that the input is an integral number of pixels. */
- /* This implies that n = 0 mod 3. */
+ int n = nbytes;
+ /*
+ * We assume that the input is an integral number of pixels, and
+ * round up n to a multiple of 3.
+ */
for (; n > 0; out += 9, pa += 3, pb += 3, pc += 3, n -= 3) {
byte_var a1 = pa[1], b0 = pb[0], b1 = pb[1], b2 = pb[2], c1 = pc[1];
@@ -152,75 +153,78 @@ flip3x12(byte * buffer, const byte ** planes, uint offset, uint nbytes)
out[7] = (byte) ((b2 << 4) | (c1 & 0xf));
out[8] = pc[2];
}
+ return 0;
}
/* Convert 4Mx1 to 4x1. */
-private void
-flip4x1(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip4x1(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
const byte *in4 = planes[3] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 4, ++in1, ++in2, ++in3, ++in4, --n) {
byte_var b1 = *in1, b2 = *in2, b3 = *in3, b4 = *in4;
byte_var temp;
/* Transpose blocks of 1 */
- transpose(b1, b2, 0x55, 1);
- transpose(b3, b4, 0x55, 1);
+ TRANSPOSE(b1, b2, 0x55, 1);
+ TRANSPOSE(b3, b4, 0x55, 1);
/* Transpose blocks of 2 */
- transpose(b1, b3, 0x33, 2);
- transpose(b2, b4, 0x33, 2);
+ TRANSPOSE(b1, b3, 0x33, 2);
+ TRANSPOSE(b2, b4, 0x33, 2);
/* There's probably a faster way to do this.... */
out[0] = (b1 & 0xf0) | (b2 >> 4);
out[1] = (b3 & 0xf0) | (b4 >> 4);
out[2] = (byte) ((b1 << 4) | (b2 & 0xf));
out[3] = (byte) ((b3 << 4) | (b4 & 0xf));
}
+ return 0;
}
/* Convert 4Mx2 to 4x2. */
-private void
-flip4x2(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip4x2(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
const byte *in4 = planes[3] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 4, ++in1, ++in2, ++in3, ++in4, --n) {
byte_var b1 = *in1, b2 = *in2, b3 = *in3, b4 = *in4;
byte_var temp;
/* Transpose blocks of 4x2 */
- transpose(b1, b3, 0x0f, 4);
- transpose(b2, b4, 0x0f, 4);
+ TRANSPOSE(b1, b3, 0x0f, 4);
+ TRANSPOSE(b2, b4, 0x0f, 4);
/* Transpose blocks of 2x1 */
- transpose(b1, b2, 0x33, 2);
- transpose(b3, b4, 0x33, 2);
+ TRANSPOSE(b1, b2, 0x33, 2);
+ TRANSPOSE(b3, b4, 0x33, 2);
out[0] = b1;
out[1] = b2;
out[2] = b3;
out[3] = b4;
}
+ return 0;
}
/* Convert 4Mx4 to 4x4. */
-private void
-flip4x4(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip4x4(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
const byte *in4 = planes[3] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 4, ++in1, ++in2, ++in3, ++in4, --n) {
byte_var b1 = *in1, b2 = *in2, b3 = *in3, b4 = *in4;
@@ -230,18 +234,19 @@ flip4x4(byte * buffer, const byte ** planes, uint offset, uint nbytes)
out[2] = (byte) ((b1 << 4) | (b2 & 0xf));
out[3] = (byte) ((b3 << 4) | (b4 & 0xf));
}
+ return 0;
}
/* Convert 4Mx8 to 4x8. */
-private void
-flip4x8(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip4x8(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *in1 = planes[0] + offset;
const byte *in2 = planes[1] + offset;
const byte *in3 = planes[2] + offset;
const byte *in4 = planes[3] + offset;
- uint n = nbytes;
+ int n = nbytes;
for (; n > 0; out += 4, ++in1, ++in2, ++in3, ++in4, --n) {
out[0] = *in1;
@@ -249,22 +254,24 @@ flip4x8(byte * buffer, const byte ** planes, uint offset, uint nbytes)
out[2] = *in3;
out[3] = *in4;
}
+ return 0;
}
/* Convert 4Mx12 to 4x12. */
-private void
-flip4x12(byte * buffer, const byte ** planes, uint offset, uint nbytes)
+private int
+flip4x12(byte * buffer, const byte ** planes, int offset, int nbytes)
{
byte *out = buffer;
const byte *pa = planes[0] + offset;
const byte *pb = planes[1] + offset;
const byte *pc = planes[2] + offset;
const byte *pd = planes[3] + offset;
- uint n = nbytes;
-
- /* We are guaranteed that the input is an integral number of pixels. */
- /* This implies that n = 0 mod 3. */
+ int n = nbytes;
+ /*
+ * We assume that the input is an integral number of pixels, and
+ * round up n to a multiple of 3.
+ */
for (; n > 0; out += 12, pa += 3, pb += 3, pc += 3, pd += 3, n -= 3) {
byte_var a1 = pa[1], b1 = pb[1], c1 = pc[1], d1 = pd[1];
@@ -293,28 +300,103 @@ flip4x12(byte * buffer, const byte ** planes, uint offset, uint nbytes)
out[11] = pd[2];
}
}
+ return 0;
+}
+
+/* Convert NMx{1,2,4,8} to Nx{1,2,4,8}. */
+private int
+flipNx1to8(byte * buffer, const byte ** planes, int offset, int nbytes,
+ int num_planes, int bits_per_sample)
+{
+ /* This is only needed for DeviceN colors, so it can be slow. */
+ uint mask = (1 << bits_per_sample) - 1;
+ int bi, pi;
+ sample_store_declare_setup(dptr, dbit, dbbyte, buffer, 0, bits_per_sample);
+
+ for (bi = 0; bi < nbytes * 8; bi += bits_per_sample) {
+ for (pi = 0; pi < num_planes; ++pi) {
+ const byte *sptr = planes[pi] + offset + (bi >> 3);
+ uint value = (*sptr >> (8 - (bi & 7) - bits_per_sample)) & mask;
+
+ sample_store_next8(value, dptr, dbit, bits_per_sample, dbbyte);
+ }
+ }
+ sample_store_flush(dptr, dbit, bits_per_sample, dbbyte);
+ return 0;
+}
+
+/* Convert NMx12 to Nx12. */
+private int
+flipNx12(byte * buffer, const byte ** planes, int offset, int nbytes,
+ int num_planes, int ignore_bits_per_sample)
+{
+ /* This is only needed for DeviceN colors, so it can be slow. */
+ int bi, pi;
+ sample_store_declare_setup(dptr, dbit, dbbyte, buffer, 0, 12);
+
+ for (bi = 0; bi < nbytes * 8; bi += 12) {
+ for (pi = 0; pi < num_planes; ++pi) {
+ const byte *sptr = planes[pi] + offset + (bi >> 3);
+ uint value =
+ (bi & 4 ? ((*sptr & 0xf) << 8) | sptr[1] :
+ (*sptr << 4) | (sptr[1] >> 4));
+
+ sample_store_next_12(value, dptr, dbit, dbbyte);
+ }
+ }
+ sample_store_flush(dptr, dbit, 12, dbbyte);
+ return 0;
}
/* Flip data given number of planes and bits per pixel. */
-typedef void (*image_flip_proc) (P4(byte *, const byte **, uint, uint));
-private const image_flip_proc image_flip_procs[2][13] =
+typedef int (*image_flip_proc) (P4(byte *, const byte **, int, int));
+private int
+flip_fail(byte * buffer, const byte ** planes, int offset, int nbytes)
{
- {0, flip3x1, flip3x2, 0, flip3x4, 0, 0, 0, flip3x8, 0, 0, 0, flip3x12},
- {0, flip4x1, flip4x2, 0, flip4x4, 0, 0, 0, flip4x8, 0, 0, 0, flip4x12}
+ return -1;
+}
+private const image_flip_proc image_flip3_procs[13] = {
+ flip_fail, flip3x1, flip3x2, flip_fail, flip3x4,
+ flip_fail, flip_fail, flip_fail, flip3x8,
+ flip_fail, flip_fail, flip_fail, flip3x12
+};
+private const image_flip_proc image_flip4_procs[13] = {
+ flip_fail, flip4x1, flip4x2, flip_fail, flip4x4,
+ flip_fail, flip_fail, flip_fail, flip4x8,
+ flip_fail, flip_fail, flip_fail, flip4x12
+};
+typedef int (*image_flipN_proc) (P6(byte *, const byte **, int, int, int, int));
+private int
+flipN_fail(byte * buffer, const byte ** planes, int offset, int nbytes,
+ int num_planes, int bits_per_sample)
+{
+ return -1;
+}
+private const image_flipN_proc image_flipN_procs[13] = {
+ flipN_fail, flipNx1to8, flipNx1to8, flipN_fail, flipNx1to8,
+ flipN_fail, flipN_fail, flipN_fail, flipNx1to8,
+ flipN_fail, flipN_fail, flipN_fail, flipNx12
};
/* Here is the public interface to all of the above. */
int
-image_flip_planes(byte * buffer, const byte ** planes, uint offset, uint nbytes,
+image_flip_planes(byte * buffer, const byte ** planes, int offset, int nbytes,
int num_planes, int bits_per_sample)
{
- void (*proc) (P4(byte * buffer, const byte ** planes, uint offset, uint nbytes));
-
- if (num_planes < 3 || num_planes > 4 ||
- bits_per_sample < 1 || bits_per_sample > 12 ||
- (proc = image_flip_procs[num_planes - 3][bits_per_sample]) == 0
- )
+ if (bits_per_sample < 1 || bits_per_sample > 12)
return -1;
- (*proc) (buffer, planes, offset, nbytes);
- return 0;
+ switch (num_planes) {
+
+ case 3:
+ return image_flip3_procs[bits_per_sample]
+ (buffer, planes, offset, nbytes);
+ case 4:
+ return image_flip4_procs[bits_per_sample]
+ (buffer, planes, offset, nbytes);
+ default:
+ if (num_planes < 0)
+ return -1;
+ return image_flipN_procs[bits_per_sample]
+ (buffer, planes, offset, nbytes, num_planes, bits_per_sample);
+ }
}
diff --git a/gs/src/gsflip.h b/gs/src/gsflip.h
index 87b1bdef3..d87aa6f43 100644
--- a/gs/src/gsflip.h
+++ b/gs/src/gsflip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,18 +23,16 @@
# define gsflip_INCLUDED
/*
- * Convert line-based (MultipleDataSource) input to the chunky format
- * used everywhere else.
- *
- * We store the output at buffer.
- * Each row of input must consist of an integral number of pixels.
- * In particular, for 12-bit input, nbytes must be 0 mod 3.
- * offset is the amount to be added to each plane pointer.
- * num_planes must be 3 or 4; bits_per_sample must be 1, 2, 4, 8, or 12.
- * Returns -1 if num_planes or bits_per_sample is invalid, otherwise 0.
+ * Convert planar (MultipleDataSource) input to chunky format. The input
+ * data starts at planes[0] + offset ... planes[num_planes-1] + offset; the
+ * output is stored at buffer. This procedure assumes that the input
+ * consists of an integral number of pixels; in particular, for 12-bit
+ * input, nbytes is rounded up to a multiple of 3. num_planes must be >=0;
+ * bits_per_sample must be 1, 2, 4, 8, or 12. Returns -1 if num_planes or
+ * bits_per_sample is invalid, otherwise 0.
*/
extern int image_flip_planes(P6(byte * buffer, const byte ** planes,
- uint offset, uint nbytes,
+ int offset, int nbytes,
int num_planes, int bits_per_sample));
#endif /* gsflip_INCLUDED */
diff --git a/gs/src/gsfont.c b/gs/src/gsfont.c
index fde96c899..54b397e87 100644
--- a/gs/src/gsfont.c
+++ b/gs/src/gsfont.c
@@ -139,8 +139,8 @@ RELOC_PTRS_END
* when we finalize a scaled font, we unlink it from scaled_fonts.
* See above for more information.
*/
- void
- gs_font_finalize(void *vptr)
+void
+gs_font_finalize(void *vptr)
{
gs_font **ppfirst;
gs_font *next = pfont->next;
diff --git a/gs/src/gsfunc.c b/gs/src/gsfunc.c
index 29491d25c..49dbcff9e 100644
--- a/gs/src/gsfunc.c
+++ b/gs/src/gsfunc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,8 +29,8 @@ public_st_function();
void
fn_common_free_params(gs_function_params_t * params, gs_memory_t * mem)
{
- gs_free_object(mem, (void *)params->Range, "Range"); /* break const */
- gs_free_object(mem, (void *)params->Domain, "Domain"); /* break const */
+ gs_free_const_object(mem, params->Range, "Range");
+ gs_free_const_object(mem, params->Domain, "Domain");
}
/* Generic free implementation. */
@@ -42,17 +42,6 @@ fn_common_free(gs_function_t * pfn, bool free_params, gs_memory_t * mem)
gs_free_object(mem, pfn, "fn_xxx_free");
}
-/* Free an array of subsidiary Functions. */
-void
-fn_free_functions(gs_function_t ** Functions, int count, gs_memory_t * mem)
-{
- int i;
-
- for (i = count; --i >= 0;)
- gs_function_free(Functions[i], true, mem);
- gs_free_object(mem, Functions, "Functions");
-}
-
/* Check the values of m, n, Domain, and (if supplied) Range. */
int
fn_check_mnDR(const gs_function_params_t * params, int m, int n)
diff --git a/gs/src/gsfunc0.c b/gs/src/gsfunc0.c
index 788e89e40..a015a9dd3 100644
--- a/gs/src/gsfunc0.c
+++ b/gs/src/gsfunc0.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -74,7 +74,7 @@ fn_gets_4(const gs_function_Sd_t * pfn, ulong offset, uint * samples)
{
SETUP_SAMPLES(4, (((offset & 7) >> 2) + n + 1) >> 1);
for (i = 0; i < n; ++i) {
- samples[i] = (offset & 4 ? *p++ & 0xf : *p >> 4);
+ samples[i] = ((offset ^= 4) & 4 ? *p >> 4 : *p++ & 0xf);
}
return 0;
}
@@ -271,9 +271,9 @@ fn_Sd_is_monotonic(const gs_function_t * pfn_common,
void
gs_function_Sd_free_params(gs_function_Sd_params_t * params, gs_memory_t * mem)
{
- gs_free_object(mem, (void *)params->Size, "Size"); /* break const */
- gs_free_object(mem, (void *)params->Decode, "Decode"); /* break const */
- gs_free_object(mem, (void *)params->Encode, "Encode"); /* break const */
+ gs_free_const_object(mem, params->Size, "Size");
+ gs_free_const_object(mem, params->Decode, "Decode");
+ gs_free_const_object(mem, params->Encode, "Encode");
fn_common_free_params((gs_function_params_t *) params, mem);
}
diff --git a/gs/src/gsfunc3.c b/gs/src/gsfunc3.c
index c8d850712..6806a9336 100644
--- a/gs/src/gsfunc3.c
+++ b/gs/src/gsfunc3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,27 @@
#include "gsfunc3.h"
#include "gxfunc.h"
+
+/* ---------------- Utilities ---------------- */
+
+/*
+ * Free an array of subsidiary Functions. Note that this may be called
+ * before the Functions array has been fully initialized. Note also that
+ * its argument conforms to the Functions array in the parameter structure,
+ * but it (necessarily) deconstifies it.
+ */
+private void
+fn_free_functions(const gs_function_t *const * Functions, int count,
+ gs_memory_t * mem)
+{
+ int i;
+
+ for (i = count; --i >= 0;)
+ if (Functions[i])
+ gs_function_free((gs_function_t *)Functions[i], true, mem);
+ gs_free_const_object(mem, Functions, "Functions");
+}
+
/* ---------------- Exponential Interpolation functions ---------------- */
typedef struct gs_function_ElIn_s {
@@ -86,8 +107,8 @@ void
gs_function_ElIn_free_params(gs_function_ElIn_params_t * params,
gs_memory_t * mem)
{
- gs_free_object(mem, (void *)params->C1, "C1"); /* break const */
- gs_free_object(mem, (void *)params->C0, "C0"); /* break const */
+ gs_free_const_object(mem, params->C1, "C1");
+ gs_free_const_object(mem, params->C0, "C0");
fn_common_free_params((gs_function_params_t *) params, mem);
}
@@ -196,10 +217,9 @@ void
gs_function_1ItSg_free_params(gs_function_1ItSg_params_t * params,
gs_memory_t * mem)
{
- gs_free_object(mem, (void *)params->Encode, "Encode"); /* break const */
- gs_free_object(mem, (void *)params->Bounds, "Bounds"); /* break const */
- fn_free_functions((gs_function_t **) params->Functions, /* break const */
- params->k, mem);
+ gs_free_const_object(mem, params->Encode, "Encode");
+ gs_free_const_object(mem, params->Bounds, "Bounds");
+ fn_free_functions(params->Functions, params->k, mem);
fn_common_free_params((gs_function_params_t *) params, mem);
}
@@ -308,8 +328,7 @@ void
gs_function_AdOt_free_params(gs_function_AdOt_params_t * params,
gs_memory_t * mem)
{
- fn_free_functions((gs_function_t **) params->Functions, /* break const */
- params->n, mem);
+ fn_free_functions(params->Functions, params->n, mem);
fn_common_free_params((gs_function_params_t *) params, mem);
}
diff --git a/gs/src/gsgc.h b/gs/src/gsgc.h
index 96ca59e55..dabb023d2 100644
--- a/gs/src/gsgc.h
+++ b/gs/src/gsgc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -49,7 +49,6 @@ typedef enum {
#ifndef gs_ref_memory_DEFINED
# define gs_ref_memory_DEFINED
typedef struct gs_ref_memory_s gs_ref_memory_t;
-
#endif
/*
* r_space_bits is only defined in PostScript interpreters, but if it is
@@ -60,26 +59,41 @@ typedef struct gs_ref_memory_s gs_ref_memory_t;
Error_r_space_bits_is_not_2;
# endif
#endif
-typedef union vm_spaces_s {
- gs_ref_memory_t *indexed[4 /*1 << r_space_bits */ ];
- struct _ssn {
- gs_ref_memory_t *foreign;
- gs_ref_memory_t *system;
- gs_ref_memory_t *global;
- gs_ref_memory_t *local;
- } named;
-} vm_spaces;
+typedef struct vm_spaces_s vm_spaces;
+/*
+ * The garbage collection procedure is named vm_reclaim so as not to
+ * collide with the reclaim member of gs_dual_memory_t.
+ */
+#define vm_reclaim_proc(proc)\
+ void proc(P2(vm_spaces *pspaces, bool global))
+struct vm_spaces_s {
+ vm_reclaim_proc((*vm_reclaim));
+ union {
+ gs_ref_memory_t *indexed[4 /*1 << r_space_bits */ ];
+ struct _ssn {
+ gs_ref_memory_t *foreign;
+ gs_ref_memory_t *system;
+ gs_ref_memory_t *global;
+ gs_ref_memory_t *local;
+ } named;
+ } memories;
+};
-/* By convention, the vm_spaces member of structures, and local variables */
-/* of type vm_spaces, are named spaces. */
-#define space_foreign spaces.named.foreign
-#define space_system spaces.named.system
-#define space_global spaces.named.global
-#define space_local spaces.named.local
+/*
+ * By convention, the vm_spaces member of structures, and local variables
+ * of type vm_spaces, are named spaces.
+ */
+#define space_foreign spaces.memories.named.foreign
+#define space_system spaces.memories.named.system
+#define space_global spaces.memories.named.global
+#define space_local spaces.memories.named.local
+#define spaces_indexed spaces.memories.indexed
/*
- * Define the top-level entry to the garbage collector.
+ * Define the top-level entry to the garbage collectors.
*/
-void gs_reclaim(P2(vm_spaces * pspaces, bool global));
+#define GS_RECLAIM(pspaces, global) ((pspaces)->vm_reclaim(pspaces, global))
+/* Backward compatibility */
+#define gs_reclaim(pspaces, global) GS_RECLAIM(pspaces, global)
#endif /* gsgc_INCLUDED */
diff --git a/gs/src/gsht.c b/gs/src/gsht.c
index 820c96b7e..8c2cf72a3 100644
--- a/gs/src/gsht.c
+++ b/gs/src/gsht.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,29 +41,47 @@ public_st_device_halftone();
/* GC procedures */
-#define hptr ((gs_halftone *)vptr)
+private
+ENUM_PTRS_WITH(ht_order_enum_ptrs, gx_ht_order *porder) return 0;
+case 0: ENUM_RETURN((porder->data_memory ? porder->levels : 0));
+case 1: ENUM_RETURN((porder->data_memory ? porder->bit_data : 0));
+case 2: ENUM_RETURN(porder->cache);
+case 3: ENUM_RETURN(porder->transfer);
+ENUM_PTRS_END
+private
+RELOC_PTRS_WITH(ht_order_reloc_ptrs, gx_ht_order *porder)
+{
+ if (porder->data_memory) {
+ RELOC_VAR(porder->levels);
+ RELOC_VAR(porder->bit_data);
+ }
+ RELOC_VAR(porder->cache);
+ RELOC_VAR(porder->transfer);
+}
+RELOC_PTRS_END
private
-ENUM_PTRS_BEGIN(halftone_enum_ptrs) return 0;
-
+ENUM_PTRS_WITH(halftone_enum_ptrs, gs_halftone *hptr) return 0;
case 0:
switch (hptr->type)
{
case ht_type_spot:
-ENUM_RETURN((hptr->params.spot.transfer == 0 ?
- hptr->params.spot.transfer_closure.data :
- 0));
+ ENUM_RETURN((hptr->params.spot.transfer == 0 ?
+ hptr->params.spot.transfer_closure.data :
+ 0));
case ht_type_threshold:
-ENUM_RETURN_CONST_STRING_PTR(gs_halftone, params.threshold.thresholds);
+ ENUM_RETURN_CONST_STRING_PTR(gs_halftone, params.threshold.thresholds);
+ case ht_type_threshold2:
+ return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds);
case ht_type_client_order:
-ENUM_RETURN(hptr->params.client_order.client_data);
+ ENUM_RETURN(hptr->params.client_order.client_data);
case ht_type_multiple:
case ht_type_multiple_colorscreen:
-ENUM_RETURN(hptr->params.multiple.components);
+ ENUM_RETURN(hptr->params.multiple.components);
case ht_type_none:
case ht_type_screen:
case ht_type_colorscreen:
-return 0;
+ return 0;
}
case 1:
switch (hptr->type) {
@@ -71,14 +89,16 @@ switch (hptr->type) {
ENUM_RETURN((hptr->params.threshold.transfer == 0 ?
hptr->params.threshold.transfer_closure.data :
0));
+ case ht_type_threshold2:
+ ENUM_RETURN(hptr->params.threshold2.transfer_closure.data);
case ht_type_client_order:
- ENUM_RETURN(hptr->params.threshold.transfer_closure.data);
+ ENUM_RETURN(hptr->params.client_order.transfer_closure.data);
default:
return 0;
}
ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(halftone_reloc_ptrs)
+private RELOC_PTRS_WITH(halftone_reloc_ptrs, gs_halftone *hptr)
{
switch (hptr->type) {
case ht_type_spot:
@@ -90,6 +110,10 @@ private RELOC_PTRS_BEGIN(halftone_reloc_ptrs)
if (hptr->params.threshold.transfer == 0)
RELOC_PTR(gs_halftone, params.threshold.transfer_closure.data);
break;
+ case ht_type_threshold2:
+ RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds);
+ RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data);
+ break;
case ht_type_client_order:
RELOC_PTR(gs_halftone, params.client_order.client_data);
RELOC_PTR(gs_halftone, params.client_order.transfer_closure.data);
@@ -106,8 +130,6 @@ private RELOC_PTRS_BEGIN(halftone_reloc_ptrs)
}
RELOC_PTRS_END
-#undef hptr
-
/* setscreen */
int
gs_setscreen(gs_state * pgs, gs_screen_halftone * phsp)
@@ -216,13 +238,16 @@ gx_ht_process_screen_memory(gs_screen_enum * penum, gs_state * pgs,
return 0;
}
-/* Internal procedure to allocate and initialize either an internally */
-/* generated or a client-defined halftone order. */
-private int
+/*
+ * Internal procedure to allocate and initialize either an internally
+ * generated or a client-defined halftone order. For spot halftones,
+ * the client is responsible for calling gx_compute_cell_values.
+ */
+int
gx_ht_alloc_ht_order(gx_ht_order * porder, uint width, uint height,
- uint num_levels, uint num_bits, uint strip_shift, gs_memory_t * mem)
+ uint num_levels, uint num_bits, uint strip_shift,
+ const gx_ht_order_procs_t *procs, gs_memory_t * mem)
{
- gx_compute_cell_values(&porder->params);
porder->width = width;
porder->height = height;
porder->raster = bitmap_raster(width);
@@ -232,15 +257,20 @@ gx_ht_alloc_ht_order(gx_ht_order * porder, uint width, uint height,
porder->full_height = ht_order_full_height(porder);
porder->num_levels = num_levels;
porder->num_bits = num_bits;
+ porder->procs = procs;
+ porder->data_memory = mem;
porder->levels =
- (uint *) gs_alloc_byte_array(mem, num_levels, sizeof(uint),
- "ht order(levels)");
- porder->bits =
- (gx_ht_bit *) gs_alloc_byte_array(mem, num_bits, sizeof(gx_ht_bit),
- "ht order(bits)");
- if (porder->levels == 0 || porder->bits == 0) {
- gs_free_object(mem, porder->bits, "ht order(bits)");
- gs_free_object(mem, porder->levels, "ht order(levels)");
+ (uint *)gs_alloc_byte_array(mem, porder->num_levels, sizeof(uint),
+ "alloc_ht_order_data(levels)");
+ porder->bit_data =
+ gs_alloc_byte_array(mem, porder->num_bits,
+ porder->procs->bit_data_elt_size,
+ "alloc_ht_order_data(bit_data)");
+ if (porder->levels == 0 || porder->bit_data == 0) {
+ gs_free_object(mem, porder->bit_data, "alloc_ht_order_data(bit_data)");
+ porder->bit_data = 0;
+ gs_free_object(mem, porder->levels, "alloc_ht_order_data(levels)");
+ porder->levels = 0;
return_error(gs_error_VMerror);
}
porder->cache = 0;
@@ -260,7 +290,33 @@ gx_ht_alloc_order(gx_ht_order * porder, uint width, uint height,
order = *porder;
gx_compute_cell_values(&order.params);
code = gx_ht_alloc_ht_order(&order, width, height, num_levels,
- width * height, strip_shift, mem);
+ width * height, strip_shift,
+ &ht_order_procs_default, mem);
+ if (code < 0)
+ return code;
+ *porder = order;
+ return 0;
+}
+
+/*
+ * Allocate and initialize a threshold order, which may use the short
+ * representation.
+ */
+int
+gx_ht_alloc_threshold_order(gx_ht_order * porder, uint width, uint height,
+ uint num_levels, gs_memory_t * mem)
+{
+ gx_ht_order order;
+ uint num_bits = width * height;
+ const gx_ht_order_procs_t *procs =
+ (num_bits > 2000 && num_bits <= max_ushort ?
+ &ht_order_procs_short : &ht_order_procs_default);
+ int code;
+
+ order = *porder;
+ gx_compute_cell_values(&order.params);
+ code = gx_ht_alloc_ht_order(&order, width, height, num_levels,
+ width * height, 0, procs, mem);
if (code < 0)
return code;
*porder = order;
@@ -282,7 +338,7 @@ gx_ht_alloc_client_order(gx_ht_order * porder, uint width, uint height,
order.params.R1 = 1;
gx_compute_cell_values(&order.params);
code = gx_ht_alloc_ht_order(&order, width, height, num_levels,
- num_bits, 0, mem);
+ num_bits, 0, &ht_order_procs_default, mem);
if (code < 0)
return code;
*porder = order;
@@ -332,7 +388,7 @@ gx_ht_construct_spot_order(gx_ht_order * porder)
uint width = porder->width;
uint num_levels = porder->num_levels; /* = width x strip */
uint strip = num_levels / width;
- gx_ht_bit *bits = porder->bits;
+ gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
uint *levels = porder->levels;
uint shift = porder->orig_shift;
uint full_height = porder->full_height;
@@ -401,12 +457,16 @@ gx_ht_construct_bits(gx_ht_order * porder)
uint i;
gx_ht_bit *phb;
- for (i = 0, phb = porder->bits; i < porder->num_bits; i++, phb++)
+ for (i = 0, phb = (gx_ht_bit *)porder->bit_data;
+ i < porder->num_bits;
+ i++, phb++)
gx_ht_construct_bit(phb, porder->width, phb->offset);
#ifdef DEBUG
if (gs_debug_c('H')) {
- dlprintf1("[H]Halftone order bits 0x%lx:\n", (ulong) porder->bits);
- for (i = 0, phb = porder->bits; i < porder->num_bits; i++, phb++)
+ dlprintf1("[H]Halftone order bits 0x%lx:\n", (ulong)porder->bit_data);
+ for (i = 0, phb = (gx_ht_bit *)porder->bit_data;
+ i < porder->num_bits;
+ i++, phb++)
dlprintf3("%4d: %u:0x%lx\n", i, phb->offset,
(ulong) phb->mask);
}
@@ -421,8 +481,12 @@ gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache)
if (free_cache && porder->cache)
gx_ht_free_cache(mem, porder->cache);
gs_free_object(mem, porder->transfer, "gx_ht_order_release(transfer)");
- gs_free_object(mem, porder->bits, "gx_ht_order_release(bits)");
- gs_free_object(mem, porder->levels, "gx_ht_order_release(levels)");
+ if (porder->data_memory) {
+ gs_free_object(porder->data_memory, porder->bit_data,
+ "gx_ht_order_release(bit_data)");
+ gs_free_object(porder->data_memory, porder->levels,
+ "gx_ht_order_release(levels)");
+ }
}
void
gx_device_halftone_release(gx_device_halftone * pdht, gs_memory_t * mem)
@@ -433,8 +497,8 @@ gx_device_halftone_release(gx_device_halftone * pdht, gs_memory_t * mem)
/* One of the components might be the same as the default */
/* order, so check that we don't free it twice. */
for (i = 0; i < pdht->num_comp; ++i)
- if (pdht->components[i].corder.bits !=
- pdht->order.bits
+ if (pdht->components[i].corder.bit_data !=
+ pdht->order.bit_data
) { /* Currently, all orders except the default one */
/* own their caches. */
gx_ht_order_release(&pdht->components[i].corder, mem, true);
@@ -447,21 +511,28 @@ gx_device_halftone_release(gx_device_halftone * pdht, gs_memory_t * mem)
gx_ht_order_release(&pdht->order, mem, false);
}
-/* Install a device halftone in an imager state. */
-/* Note that this does not read or update the client halftone. */
+/*
+ * Install a device halftone in an imager state. Note that this does not
+ * read or update the client halftone. There is a special check for pdht ==
+ * pis->dev_ht, for the benefit of the band rendering code.
+ */
int
gx_imager_dev_ht_install(gs_imager_state * pis,
- const gx_device_halftone * pdht, gs_halftone_type type, const gx_device * dev)
+ const gx_device_halftone * pdht,
+ gs_halftone_type type, const gx_device * dev)
{
gx_device_halftone *pgdht = pis->dev_ht;
- if ((ulong) pdht->order.raster * (pdht->order.num_bits /
- pdht->order.width) > pis->ht_cache->bits_size
+ if ((ulong) pdht->order.raster *
+ (pdht->order.num_bits / pdht->order.width) > pis->ht_cache->bits_size
)
return_error(gs_error_limitcheck);
- if (pgdht != 0 && pgdht->rc.ref_count == 1 &&
+ if (pdht == pgdht)
+ DO_NOTHING; /* special hack for band renderer */
+ else if (pgdht != 0 && pgdht->rc.ref_count == 1 &&
pgdht->rc.memory == pdht->rc.memory
- ) { /* The current device halftone isn't shared. */
+ ) {
+ /* The current device halftone isn't shared. */
/* Just release its components. */
gx_device_halftone_release(pgdht, pgdht->rc.memory);
} else { /* The device halftone is shared or not yet allocated. */
diff --git a/gs/src/gsht1.c b/gs/src/gsht1.c
index 748aa8b42..fba3478d8 100644
--- a/gs/src/gsht1.c
+++ b/gs/src/gsht1.c
@@ -45,6 +45,9 @@ private int process_spot(P4(gx_ht_order *, gs_state *,
gs_spot_halftone *, gs_memory_t *));
private int process_threshold(P4(gx_ht_order *, gs_state *,
gs_threshold_halftone *, gs_memory_t *));
+private int process_threshold2(P4(gx_ht_order *, gs_state *,
+ gs_threshold2_halftone *,
+ gs_memory_t *));
private int process_client_order(P4(gx_ht_order *, gs_state *,
gs_client_order_halftone *, gs_memory_t *));
@@ -69,6 +72,8 @@ ENUM_RETURN((hptr->params.spot.transfer == 0 ?
case ht_type_threshold:
ENUM_RETURN_CONST_STRING_PTR(gs_halftone_component,
params.threshold.thresholds);
+ case ht_type_threshold2:
+return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds);
case ht_type_client_order:
ENUM_RETURN(hptr->params.client_order.client_data);
default: /* not possible */
@@ -80,8 +85,10 @@ switch (hptr->type) {
ENUM_RETURN((hptr->params.threshold.transfer == 0 ?
hptr->params.threshold.transfer_closure.data :
0));
+ case ht_type_threshold2:
+ ENUM_RETURN(hptr->params.threshold2.transfer_closure.data);
case ht_type_client_order:
- ENUM_RETURN(hptr->params.threshold.transfer_closure.data);
+ ENUM_RETURN(hptr->params.client_order.transfer_closure.data);
default:
return 0;
}
@@ -99,6 +106,10 @@ private RELOC_PTRS_BEGIN(halftone_component_reloc_ptrs)
if (hptr->params.threshold.transfer == 0)
RELOC_VAR(hptr->params.threshold.transfer_closure.data);
break;
+ case ht_type_threshold2:
+ RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds);
+ RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data);
+ break;
case ht_type_client_order:
RELOC_VAR(hptr->params.client_order.client_data);
RELOC_VAR(hptr->params.client_order.transfer_closure.data);
@@ -244,6 +255,13 @@ gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht,
return code;
pdht->components = 0;
break;
+ case ht_type_threshold2:
+ code = process_threshold2(&pdht->order, pgs,
+ &pht->params.threshold2, mem);
+ if (code < 0)
+ return code;
+ pdht->components = 0;
+ break;
case ht_type_client_order:
code = process_client_order(&pdht->order, pgs,
&pht->params.client_order, mem);
@@ -292,7 +310,11 @@ gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht,
break;
case ht_type_threshold:
code = process_threshold(&poc->corder, pgs,
- &phc->params.threshold, mem);
+ &phc->params.threshold, mem);
+ break;
+ case ht_type_threshold2:
+ code = process_threshold2(&poc->corder, pgs,
+ &phc->params.threshold2, mem);
break;
case ht_type_client_order:
code = process_client_order(&poc->corder, pgs,
@@ -382,6 +404,38 @@ process_spot(gx_ht_order * porder, gs_state * pgs,
&phsp->transfer_closure, mem);
}
+/* Construct the halftone order from a threshold array. */
+void
+gx_ht_complete_threshold_order(gx_ht_order * porder)
+{
+ int num_levels = porder->num_levels;
+ uint *levels = porder->levels;
+ uint size = porder->num_bits;
+ gx_ht_bit *bits = porder->bit_data;
+ uint i, j;
+
+ /* The caller has set bits[i] = max(1, thresholds[i]). */
+ gx_sort_ht_order(bits, size);
+ /* We want to set levels[j] to the lowest value of i */
+ /* such that bits[i].mask > j. */
+ for (i = 0, j = 0; i < size; i++) {
+ if (bits[i].mask != j) {
+ if_debug3('h', "[h]levels[%u..%u] = %u\n",
+ j, (uint) bits[i].mask, i);
+ while (j < bits[i].mask)
+ levels[j++] = i;
+ }
+ }
+ while (j < num_levels)
+ levels[j++] = size;
+ gx_ht_construct_bits(porder);
+}
+int
+gx_ht_construct_threshold_order(gx_ht_order * porder, const byte * thresholds)
+{
+ return porder->procs->construct_order(porder, thresholds);
+}
+
/* Process a threshold plane. */
private int
process_threshold(gx_ht_order * porder, gs_state * pgs,
@@ -393,8 +447,8 @@ process_threshold(gx_ht_order * porder, gs_state * pgs,
porder->params.R = 1;
porder->params.M1 = phtp->height, porder->params.N1 = 0;
porder->params.R1 = 1;
- code = gx_ht_alloc_order(porder, phtp->width, phtp->height,
- 0, 256, mem);
+ code = gx_ht_alloc_threshold_order(porder, phtp->width, phtp->height,
+ 256, mem);
if (code < 0)
return code;
gx_ht_construct_threshold_order(porder, phtp->thresholds.data);
@@ -402,31 +456,120 @@ process_threshold(gx_ht_order * porder, gs_state * pgs,
&phtp->transfer_closure, mem);
}
-/* Construct the halftone order from a threshold array. */
-void
-gx_ht_construct_threshold_order(gx_ht_order * porder, const byte * thresholds)
+/* Process an extended threshold plane. */
+private int
+process_threshold2(gx_ht_order * porder, gs_state * pgs,
+ gs_threshold2_halftone * phtp, gs_memory_t * mem)
{
- uint size = porder->num_bits;
- uint *levels = porder->levels;
- gx_ht_bit *bits = porder->bits;
- uint i, j;
-
- for (i = 0; i < size; i++)
- bits[i].mask = max(1, thresholds[i]);
- gx_sort_ht_order(bits, size);
- /* We want to set levels[j] to the lowest value of i */
- /* such that bits[i].mask > j. */
- for (i = 0, j = 0; i < size; i++) {
- if (bits[i].mask != j) {
- if_debug3('h', "[h]levels[%u..%u] = %u\n",
- j, (uint) bits[i].mask, i);
- while (j < bits[i].mask)
- levels[j++] = i;
+ int code;
+ /*
+ * There are potentially 64K different levels for this plane, but this
+ * is more than we're willing to handle. Try to reduce the number of
+ * levels by dropping leading or trailing zero bits from the thresholds;
+ * as a last resort, drop (possibly significant) trailing bits.
+ */
+#define LOG2_MAX_HT_LEVELS 14
+#define MAX_HT_LEVELS (1 << LOG2_MAX_HT_LEVELS)
+ int bps = phtp->bytes_per_sample;
+ const byte *data = phtp->thresholds.data;
+ const int w1 = phtp->width, h1 = phtp->height, size1 = w1 * h1;
+ const int w2 = phtp->width2, h2 = phtp->height2, size2 = w2 * h2;
+ const uint size = size1 + size2;
+ const int d = (h2 == 0 ? h1 : igcd(h1, h2));
+ const int sod = size / d;
+ uint num_levels;
+ uint i;
+ int rshift = 0;
+ int shift;
+
+ {
+ uint mask = 0, max_thr = 0;
+
+ for (i = 0; i < size; ++i) {
+ uint thr =
+ (bps == 1 ? data[i] : (data[i * 2] << 8) + data[i * 2 + 1]);
+
+ mask |= thr;
+ max_thr = max(max_thr, thr);
}
+ if (mask == 0)
+ mask = 1, max_thr = 1;
+ while (!(mask & 1) || max_thr > MAX_HT_LEVELS)
+ mask >>= 1, max_thr >>= 1, rshift++;
+ num_levels = max_thr + 1;
}
- while (j < 256)
- levels[j++] = size;
- gx_ht_construct_bits(porder);
+ /*
+ * Set nominal values for the params, and don't bother to call
+ * gx_compute_cell_values -- the values are only needed for spot
+ * halftones.
+ */
+ porder->params.M = sod, porder->params.N = d;
+ porder->params.R = 1;
+ porder->params.M1 = d, porder->params.N1 = sod;
+ porder->params.R1 = 1;
+ /*
+ * Determine the shift between strips. We don't know a closed formula
+ * for this, so we do it by enumeration.
+ */
+ shift = 0;
+ {
+ int x = 0, y = 0;
+
+ do {
+ if (y < h1)
+ x += w1, y += h2;
+ else
+ x += w2, y -= h1;
+ } while (y > d);
+ if (y)
+ shift = x;
+ }
+ code = gx_ht_alloc_ht_order(porder, sod, d, num_levels, size, shift,
+ &ht_order_procs_default, mem);
+ if (code < 0)
+ return code;
+ {
+ gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
+ int row, di;
+
+ if_debug7('h', "[h]rect1=(%d,%d), rect2=(%d,%d), strip=(%d,%d), shift=%d\n",
+ w1, h1, w2, h2, sod, d, shift);
+ for (row = 0, di = 0; row < d; ++row) {
+ /* Iterate over destination rows. */
+ int dx, sy = row; /* sy = row mod d */
+ int w;
+
+ for (dx = 0; dx < sod; dx += w) {
+ /* Iterate within a destination row, over source rows. */
+ int si, j;
+
+ if (sy < h1) {
+ /* Copy a row from rect1. */
+ si = sy * w1;
+ w = w1;
+ sy += h2;
+ } else {
+ /* Copy a row from rect2. */
+ si = size1 + (sy - h1) * w2;
+ w = w2;
+ sy -= h1;
+ }
+ for (j = 0; j < w; ++j, ++si, ++di) {
+ uint thr =
+ (bps == 1 ? data[si] :
+ (data[si * 2] << 8) + data[si * 2 + 1])
+ >> rshift;
+
+ if_debug3('H', "[H]sy=%d, si=%d, di=%d\n", sy, si, di);
+ bits[di].mask = max(thr, 1);
+ }
+ }
+ }
+ }
+ gx_ht_complete_threshold_order(porder);
+ return process_transfer(porder, pgs, NULL, &phtp->transfer_closure, mem);
+#undef LOG2_MAX_HT_LEVELS
+#undef MAX_HT_LEVELS
}
/* Process a client-order plane. */
diff --git a/gs/src/gshtscr.c b/gs/src/gshtscr.c
index 182ad77fa..ac69c90a2 100644
--- a/gs/src/gshtscr.c
+++ b/gs/src/gshtscr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,7 +29,7 @@
/* Define whether to force all halftones to be strip halftones, */
/* for debugging. */
-#define FORCE_STRIP_HALFTONES 0
+static bool FORCE_STRIP_HALFTONES = false;
/* Structure descriptors */
private_st_gs_screen_enum();
@@ -128,11 +128,10 @@ gx_compute_cell_values(gx_ht_cell_params_t * phcp)
const int M = phcp->M, N = phcp->N, M1 = phcp->M1, N1 = phcp->N1;
const uint m = any_abs(M), n = any_abs(N);
const uint m1 = any_abs(M1), n1 = any_abs(N1);
- const ulong C = phcp->C = (ulong) m * m1 + (ulong) n * n1;
- const int D = igcd(m1, n);
- const int D1 = igcd(m, n1);
+ const ulong C = phcp->C = (ulong)m * m1 + (ulong)n * n1;
+ const int D = phcp->D = igcd(m1, n);
+ const int D1 = phcp->D1 = igcd(m, n1);
- phcp->D = D, phcp->D1 = D1;
phcp->W = C / D, phcp->W1 = C / D1;
/* Compute the shift value. */
/* If M1 or N is zero, the shift is zero. */
@@ -224,10 +223,10 @@ gs_screen_order_init_memory(gx_ht_order * porder, const gs_state * pgs,
return code;
gx_compute_cell_values(&porder->params);
num_levels = porder->params.W * porder->params.D;
-#if !FORCE_STRIP_HALFTONES
- if (((ulong)porder->params.W1 * bitmap_raster(porder->params.W) +
- num_levels * sizeof(*porder->levels) +
- porder->params.W * porder->params.W1 * sizeof(*porder->bits)) <=
+ if (!FORCE_STRIP_HALFTONES &&
+ ((ulong)porder->params.W1 * bitmap_raster(porder->params.W) +
+ num_levels * sizeof(*porder->levels) +
+ porder->params.W * porder->params.W1 * sizeof(gx_ht_bit)) <=
max_size) {
/*
* Allocate an order for the entire tile, but only sample one
@@ -240,9 +239,8 @@ gs_screen_order_init_memory(gx_ht_order * porder, const gs_state * pgs,
num_levels, mem);
porder->height = porder->orig_height = porder->params.D;
porder->shift = porder->orig_shift = porder->params.S;
- } else
-#endif
- { /* Just allocate the order for a single strip. */
+ } else {
+ /* Just allocate the order for a single strip. */
code = gx_ht_alloc_order(porder, porder->params.W,
porder->params.D, porder->params.S,
num_levels, mem);
@@ -415,7 +413,11 @@ pick_cell_size(gs_screen_halftone * ph, const gs_matrix * pmat, ulong max_size,
better = true;
if_debug3('h', "*** best wt_size=%ld, f_diff=%g, a_diff=%g\n",
wt_size, f_diff, a_diff);
- if (f_err <= 0.01 && a_err <= 0.01)
+ /*
+ * We want a maximum relative frequency error of 1% and a
+ * maximum angle error of 1% (of 90 degrees).
+ */
+ if (f_err <= 0.01 && a_err <= 0.9 /*degrees*/)
goto done;
}
}
@@ -533,6 +535,7 @@ gs_screen_next(gs_screen_enum * penum, floatp value)
{
ht_sample_t sample;
int width = penum->order.width;
+ gx_ht_bit *bits = (gx_ht_bit *)penum->order.bit_data;
if (value < -1.0 || value > 1.0)
return_error(gs_error_rangecheck);
@@ -549,7 +552,7 @@ gs_screen_next(gs_screen_enum * penum, floatp value)
penum->x, penum->y, pt.x, pt.y, value, sample);
}
#endif
- penum->order.bits[penum->y * width + penum->x].mask = sample;
+ bits[penum->y * width + penum->x].mask = sample;
if (++(penum->x) >= width)
penum->x = 0, ++(penum->y);
return 0;
diff --git a/gs/src/gshtx.c b/gs/src/gshtx.c
index 381f20ec7..2359bef00 100644
--- a/gs/src/gshtx.c
+++ b/gs/src/gshtx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -120,8 +120,8 @@ gs_ht_set_spot_comp(
gs_ht * pht,
int comp,
gs_ht_separation_name sepname,
- float freq,
- float angle,
+ floatp freq,
+ floatp angle,
float (*spot_func) (floatp, floatp),
bool accurate,
gs_ht_transfer_proc transfer,
@@ -323,14 +323,14 @@ alloc_ht_order(
pmap->id = gs_next_ids(1);
if (phtc->cname == gs_ht_separation_Default) {
pocs->corder.levels = 0;
- pocs->corder.bits = 0;
+ pocs->corder.bit_data = 0;
pocs->corder.cache = 0;
pocs->corder.transfer = pmap;
pocs->cname = gs_ht_separation_Default;
comp2order[i] = 0;
} else {
pocs[inext].corder.levels = 0;
- pocs[inext].corder.bits = 0;
+ pocs[inext].corder.bit_data = 0;
pocs[inext].corder.cache = 0;
pocs[inext].corder.transfer = pmap;
pocs[inext].cname = phtc->cname;
@@ -379,18 +379,17 @@ build_component(
porder->params.M1 = phtc->params.ht_threshold.height;
porder->params.N1 = 0;
porder->params.R1 = 1;
- code = gx_ht_alloc_order(porder,
- phtc->params.ht_threshold.width,
- phtc->params.ht_threshold.height,
- 0,
- 256,
- pmem
+ code = gx_ht_alloc_threshold_order(porder,
+ phtc->params.ht_threshold.width,
+ phtc->params.ht_threshold.height,
+ 256,
+ pmem
);
if (code < 0)
return code;
gx_ht_construct_threshold_order(
- porder,
- phtc->params.ht_threshold.thresholds.data
+ porder,
+ phtc->params.ht_threshold.thresholds.data
);
/*
* gx_ht_construct_threshold_order wipes out transfer map pointer,
@@ -561,7 +560,8 @@ create_mask_order(gx_ht_order * porder, gs_state * pgs,
porder->levels[i] = num_bits;
num_bits += create_mask_bits(prev_mask, prev_mask + bytes_per_mask,
phcop->width, phcop->height,
- porder->bits + num_bits);
+ ((gx_ht_bit *)porder->bit_data) +
+ num_bits);
}
porder->levels[num_levels - 1] = num_bits;
return 0;
diff --git a/gs/src/gshtx.h b/gs/src/gshtx.h
index 7d2a36cf4..7208f4dc7 100644
--- a/gs/src/gshtx.h
+++ b/gs/src/gshtx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -93,8 +93,8 @@ extern int gs_ht_set_spot_comp(P9(
gs_ht * pht,
int component_index,
gs_ht_separation_name sepr_name,
- float freq,
- float angle,
+ floatp freq,
+ floatp angle,
float (*spot_func) (P2(floatp, floatp)),
bool accurate,
gs_ht_transfer_proc transfer,
diff --git a/gs/src/gsimage.c b/gs/src/gsimage.c
index b1c7cb76a..91866e97c 100644
--- a/gs/src/gsimage.c
+++ b/gs/src/gsimage.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,22 +32,27 @@
#include "gzstate.h"
/* Define the enumeration state for this interface layer. */
- /*typedef struct gs_image_enum_s gs_image_enum; *//* in gsimage.h */
+/*typedef struct gs_image_enum_s gs_image_enum; *//* in gsimage.h */
+typedef struct image_enum_plane_s {
+ /* Change dynamically */
+ uint pos; /* byte position within the scan line */
+ gs_const_string source; /* source data, [0 .. plane_index - 1] */
+ gs_string row; /* row buffers, [0 .. num_planes - 1] */
+} image_enum_plane_t;
struct gs_image_enum_s {
/* The following are set at initialization time. */
gs_memory_t *memory;
gx_device *dev; /* if 0, just skip over the data */
gx_image_enum_common_t *info; /* driver bookkeeping structure */
int num_planes;
- int width, height;
- uint raster; /* bytes per row (per plane), no padding */
+ int height;
+ bool wanted_varies;
/* The following are updated dynamically. */
int plane_index; /* index of next plane of data */
int y;
- uint pos; /* byte position within the scan line */
- gs_const_string sources[gs_image_max_planes]; /* source data */
- gs_string rows[gs_image_max_planes]; /* row buffers */
bool error;
+ byte wanted[gs_image_max_planes];
+ image_enum_plane_t planes[gs_image_max_planes];
};
gs_private_st_composite(st_gs_image_enum, gs_image_enum, "gs_image_enum",
@@ -62,10 +67,10 @@ ENUM_PTRS_BEGIN(gs_image_enum_enum_ptrs)
/* Enumerate the data planes. */
index -= gs_image_enum_num_ptrs;
if (index < eptr->plane_index)
- ENUM_RETURN_STRING_PTR(gs_image_enum, sources[index]);
+ ENUM_RETURN_STRING_PTR(gs_image_enum, planes[index].source);
index -= eptr->plane_index;
if (index < eptr->num_planes)
- ENUM_RETURN_STRING_PTR(gs_image_enum, rows[index]);
+ ENUM_RETURN_STRING_PTR(gs_image_enum, planes[index].row);
return 0;
}
ENUM_PTR(0, gs_image_enum, dev);
@@ -78,9 +83,9 @@ private RELOC_PTRS_BEGIN(gs_image_enum_reloc_ptrs)
RELOC_PTR(gs_image_enum, dev);
RELOC_PTR(gs_image_enum, info);
for (i = 0; i < eptr->plane_index; i++)
- RELOC_CONST_STRING_PTR(gs_image_enum, sources[i]);
+ RELOC_CONST_STRING_PTR(gs_image_enum, planes[i].source);
for (i = 0; i < eptr->num_planes; i++)
- RELOC_STRING_PTR(gs_image_enum, rows[i]);
+ RELOC_STRING_PTR(gs_image_enum, planes[i].row);
}
RELOC_PTRS_END
#undef eptr
@@ -105,21 +110,18 @@ gs_image_begin_typed(const gs_image_common_t * pic, gs_state * pgs,
/* Allocate an image enumerator. */
private void
image_enum_init(gs_image_enum * penum)
-{ /* Clean pointers for GC. */
- int i;
-
+{
+ /* Clean pointers for GC. */
penum->info = 0;
penum->dev = 0;
- for (i = 0; i < countof(penum->sources); ++i) {
- penum->sources[i].data = 0, penum->sources[i].size = 0;
- penum->rows[i].data = 0, penum->rows[i].size = 0;
- }
+ penum->plane_index = 0;
+ penum->num_planes = 0;
}
gs_image_enum *
gs_image_enum_alloc(gs_memory_t * mem, client_name_t cname)
{
gs_image_enum *penum =
- gs_alloc_struct(mem, gs_image_enum, &st_gs_image_enum, cname);
+ gs_alloc_struct(mem, gs_image_enum, &st_gs_image_enum, cname);
if (penum != 0) {
penum->memory = mem;
@@ -154,17 +156,41 @@ gs_image_init(gs_image_enum * penum, const gs_image_t * pim, bool multi,
&pie);
if (code < 0)
return code;
- return gs_image_common_init(penum, pie,
- (const gs_data_image_t *)&image,
- pgs->memory,
+ return gs_image_enum_init(penum, pie, (const gs_data_image_t *)&image,
+ pgs);
+}
+/* Start processing a general image. */
+private void
+begin_planes(gs_image_enum *penum)
+{
+ /*
+ * Initialize plane_index and (if appropriate) wanted and
+ * wanted_varies at the beginning of a group of planes.
+ */
+ int px = 0;
+
+ if (penum->wanted_varies) {
+ penum->wanted_varies =
+ !gx_image_planes_wanted(penum->info, penum->wanted);
+ }
+ while (!penum->wanted[px])
+ ++px;
+ penum->plane_index = px;
+}
+int
+gs_image_enum_init(gs_image_enum * penum, gx_image_enum_common_t * pie,
+ const gs_data_image_t * pim, gs_state *pgs)
+{
+ return gs_image_common_init(penum, pie, pim, pgs->memory,
(pgs->in_charpath ? NULL :
gs_currentdevice_inline(pgs)));
}
-/* Start processing a general image. */
int
gs_image_common_init(gs_image_enum * penum, gx_image_enum_common_t * pie,
const gs_data_image_t * pim, gs_memory_t * mem, gx_device * dev)
{
+ int i;
+
if (pim->Width == 0 || pim->Height == 0) {
gx_image_end(pie, false);
return 1;
@@ -174,50 +200,78 @@ gs_image_common_init(gs_image_enum * penum, gx_image_enum_common_t * pie,
penum->dev = dev;
penum->info = pie;
penum->num_planes = pie->num_planes;
- penum->width = pim->Width;
penum->height = pim->Height;
-/****** ALL PLANES MUST HAVE SAME DEPTH FOR NOW ******/
- penum->raster = (pim->Width * pie->plane_depths[0] + 7) >> 3;
+ for (i = 0; i < pie->num_planes; ++i) {
+ penum->planes[i].pos = 0;
+ penum->planes[i].row.data = 0; /* for GC */
+ penum->planes[i].row.size = 0; /* ditto */
+ }
/* Initialize the dynamic part of the state. */
- penum->plane_index = 0;
penum->y = 0;
- penum->pos = 0;
penum->error = false;
+ penum->wanted_varies = true;
+ begin_planes(penum);
return 0;
}
/*
- * Return the number of bytes of data per row per plane.
+ * Return the number of bytes of data per row for a given plane.
*/
-uint
+inline uint
gs_image_bytes_per_plane_row(const gs_image_enum * penum, int plane)
{
-/****** IGNORE PLANE FOR NOW ******/
- return penum->raster;
+ const gx_image_enum_common_t *pie = penum->info;
+
+ return (pie->plane_widths[plane] * pie->plane_depths[plane] + 7) >> 3;
+}
+
+/* Return the set of planes wanted. */
+const byte *
+gs_image_planes_wanted(const gs_image_enum *penum)
+{
+ return penum->wanted;
+}
+
+/* Free the row buffers when cleaning up. */
+private void
+free_row_buffers(gs_image_enum *penum, int num_planes, client_name_t cname)
+{
+ int i;
+
+ for (i = num_planes - 1; i >= 0; --i) {
+ gs_free_string(penum->memory, penum->planes[i].row.data,
+ penum->planes[i].row.size, cname);
+ penum->planes[i].row.data = 0;
+ penum->planes[i].row.size = 0;
+ }
}
/* Process the next piece of an image. */
private int
-copy_planes(gx_device * dev, gs_image_enum * penum, const byte ** planes,
- int h)
+copy_planes(gx_device * dev, gs_image_enum * penum,
+ const gx_image_plane_t *planes, int h, int *rows_used)
{
- int code =
- (penum->dev == 0 ? (penum->y + h < penum->height ? 0 : 1) :
- gx_image_data(penum->info, planes, 0, penum->raster, h));
+ int code;
- if (code < 0)
- penum->error = true;
+ if (penum->dev == 0) {
+ if (penum->y + h < penum->height)
+ *rows_used = h, code = 0;
+ else
+ *rows_used = penum->height - penum->y, code = 1;
+ } else {
+ code = gx_image_plane_data_rows(penum->info, planes, h, rows_used);
+ penum->error = code < 0;
+ }
return code;
}
int
gs_image_next(gs_image_enum * penum, const byte * dbytes, uint dsize,
uint * pused)
{
+ const gx_image_enum_common_t *pie = penum->info;
+ int px = penum->plane_index;
gx_device *dev;
- uint left;
- int num_planes;
- uint raster;
- uint pos;
+ int num_planes = penum->num_planes;
int code;
/*
@@ -230,78 +284,142 @@ gs_image_next(gs_image_enum * penum, const byte * dbytes, uint dsize,
* - image_data requires that each call pass entire rows;
* gs_image_next allows arbitrary amounts of data.
*/
- if (penum->plane_index != 0)
- if (dsize != penum->sources[0].size)
+ if (penum->error) {
+ /*
+ * We were interrupted by an error. The current data are the
+ * same as the data presented at the last call.
+ */
+ penum->error = false;
+ } else {
+ if (px != 0 && dsize != penum->planes[0].source.size &&
+ pie->plane_depths[px] == pie->plane_depths[0] &&
+ pie->plane_widths[px] == pie->plane_widths[0])
return_error(gs_error_rangecheck);
- penum->sources[penum->plane_index].data = dbytes;
- penum->sources[penum->plane_index].size = dsize;
- if (++(penum->plane_index) != penum->num_planes)
- return 0;
+ penum->planes[px].source.data = dbytes;
+ penum->planes[px].source.size = dsize;
+ while (++px < num_planes && !penum->wanted[px])
+ DO_NOTHING;
+ if (px < num_planes) {
+ /* We need more planes. */
+ penum->plane_index = px;
+ return 0;
+ }
+ }
/* We have a full set of planes. */
dev = penum->dev;
- left = dsize;
- num_planes = penum->num_planes;
- raster = penum->raster;
- pos = penum->pos;
code = 0;
- while (left && penum->y < penum->height) {
- const byte *planes[gs_image_max_planes];
+ /****** HOW TO STOP IN TIME IF TOO MUCH DATA? ******/
+ while (!code) {
+ gx_image_plane_t planes[gs_image_max_planes];
int i;
+ int direct = max_int;
+ bool filled = true;
- for (i = 0; i < num_planes; ++i)
- planes[i] = penum->sources[i].data + dsize - left;
- if (pos == 0 && left >= raster) { /* Pass (a) row(s) directly from the source. */
- int h = left / raster;
+ for (i = 0; i < num_planes; ++i) {
+ if (!penum->wanted[i])
+ planes[i].data = 0;
+ else {
+ planes[i].data_x = 0;
+ planes[i].raster = gs_image_bytes_per_plane_row(penum, i);
+ if (penum->planes[i].pos == 0)
+ direct = min(direct, penum->planes[i].source.size /
+ planes[i].raster);
+ else
+ direct = 0;
+ }
+ }
+ if (direct) {
+ /*
+ * Pass (a) row(s) directly from the source. If wanted_varies,
+ * we can only safely pass 1 scan line at a time.
+ */
+ if (penum->wanted_varies)
+ direct = 1;
+ for (i = 0; i < num_planes; ++i)
+ if (penum->wanted[i])
+ planes[i].data = penum->planes[i].source.data;
+ code = copy_planes(dev, penum, planes, direct, &direct);
+ for (i = 0; i < num_planes; ++i)
+ if (planes[i].data) {
+ uint used = direct * planes[i].raster;
- if (h > penum->height - penum->y)
- h = penum->height - penum->y;
- code = copy_planes(dev, penum, planes, h);
+ penum->planes[i].source.data += used;
+ penum->planes[i].source.size -= used;
+ }
+ penum->y += direct;
if (code < 0)
break;
- left -= raster * h;
- penum->y += h;
} else { /* Buffer a partial row. */
- uint count = min(left, raster - pos);
+ bool empty = false;
+ uint count[gs_image_max_planes];
+
+ /* Make sure the row buffers are allocated. */
+ for (i = 0; i < num_planes; ++i)
+ if (penum->wanted[i]) {
+ uint raster = planes[i].raster;
+ uint old_size = penum->planes[i].row.size;
- if (penum->rows[0].data == 0) { /* Allocate the row buffers. */
- for (i = 0; i < num_planes; ++i) {
- byte *row = gs_alloc_string(penum->memory, raster,
- "gs_image_next(row)");
+ if (raster > old_size) {
+ byte *old_data = penum->planes[i].row.data;
+ byte *row =
+ (old_data == 0 ?
+ gs_alloc_string(penum->memory, raster,
+ "gs_image_next(row)") :
+ gs_resize_string(penum->memory, old_data,
+ old_size, raster,
+ "gs_image_next(row)"));
- if (row == 0) {
- code = gs_note_error(gs_error_VMerror);
- while (--i >= 0) {
- gs_free_string(penum->memory, penum->rows[i].data,
- raster, "gs_image_next(row)");
- penum->rows[i].data = 0;
- penum->rows[i].size = 0;
+ if (row == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ free_row_buffers(penum, i, "gs_image_next(row)");
+ break;
}
- break;
+ penum->planes[i].row.data = row;
+ penum->planes[i].row.size = raster;
+ }
+ count[i] = min(raster - penum->planes[i].pos,
+ penum->planes[i].source.size);
+ memcpy(penum->planes[i].row.data + penum->planes[i].pos,
+ penum->planes[i].source.data, count[i]);
+ if ((penum->planes[i].pos += count[i]) < raster) {
+ filled = false;
+ empty |= count[i] == 0;
}
- penum->rows[i].data = row;
- penum->rows[i].size = raster;
}
- if (code < 0)
- break;
- }
- for (i = 0; i < num_planes; ++i)
- memcpy(penum->rows[i].data + pos, planes[i], count);
- pos += count;
- left -= count;
- if (pos == raster) {
+ if (code < 0)
+ break;
+ if (filled) {
for (i = 0; i < num_planes; ++i)
- planes[i] = penum->rows[i].data;
- code = copy_planes(dev, penum, planes, 1);
- if (code < 0)
+ if (penum->wanted[i])
+ planes[i].data = penum->planes[i].row.data;
+ code = copy_planes(dev, penum, planes, 1, &direct);
+ if (code < 0) {
+ /* Undo the incrementing of pos. */
+ for (i = 0; i < num_planes; ++i)
+ if (penum->wanted[i])
+ penum->planes[i].pos -= count[i];
break;
- pos = 0;
+ }
+ for (i = 0; i < num_planes; ++i)
+ penum->planes[i].pos = 0;
penum->y++;
}
+ for (i = 0; i < num_planes; ++i)
+ if (penum->wanted[i]) {
+ penum->planes[i].source.data += count[i];
+ penum->planes[i].source.size -= count[i];
+ }
+ if (empty)
+ break;
}
+ if (filled & !code)
+ begin_planes(penum);
}
- penum->pos = pos;
- penum->plane_index = 0;
- *pused = dsize - left;
+ /*
+ * We only set *pused for the last plane of a group. We will have to
+ * rethink this in order to handle varying-size planes.
+ */
+ *pused = penum->planes[penum->plane_index].source.data - dbytes;
return code;
}
@@ -309,11 +427,7 @@ gs_image_next(gs_image_enum * penum, const byte * dbytes, uint dsize,
void
gs_image_cleanup(gs_image_enum * penum)
{
- int i;
-
- for (i = 0; i < penum->num_planes; ++i)
- gs_free_string(penum->memory, penum->rows[i].data,
- penum->rows[i].size, "gs_image_cleanup(row)");
+ free_row_buffers(penum, penum->num_planes, "gs_image_cleanup(row)");
if (penum->dev != 0)
gx_image_end(penum->info, !penum->error);
/* Don't free the local enumerator -- the client does that. */
diff --git a/gs/src/gsimage.h b/gs/src/gsimage.h
index 207eb856d..463da7a84 100644
--- a/gs/src/gsimage.h
+++ b/gs/src/gsimage.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,8 @@
#ifndef gx_image_enum_common_t_DEFINED
# define gx_image_enum_common_t_DEFINED
typedef struct gx_image_enum_common_s gx_image_enum_common_t;
-
#endif
+
int gs_image_begin_typed(P4(const gs_image_common_t * pic, gs_state * pgs,
bool uses_color, gx_image_enum_common_t ** ppie));
@@ -54,11 +54,15 @@ gs_image_enum *gs_image_enum_alloc(P2(gs_memory_t *, client_name_t));
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
-int gs_image_common_init(P5(gs_image_enum * penum, gx_image_enum_common_t * pie,
+
+int gs_image_common_init(P5(gs_image_enum * penum,
+ gx_image_enum_common_t * pie,
const gs_data_image_t * pim,
gs_memory_t * mem, gx_device * dev));
+int gs_image_enum_init(P4(gs_image_enum * penum,
+ gx_image_enum_common_t * pie,
+ const gs_data_image_t * pim, gs_state *pgs));
int gs_image_init(P4(gs_image_enum * penum, const gs_image_t * pim,
bool MultipleDataSources, gs_state * pgs));
int gs_image_next(P4(gs_image_enum * penum, const byte * dbytes,
@@ -72,6 +76,13 @@ uint gs_image_bytes_per_plane_row(P2(const gs_image_enum * penum, int plane));
#define gs_image_bytes_per_row(penum)\
gs_image_bytes_per_plane_row(penum, 0)
+
+/*
+ * Return a byte vector indicating which planes are wanted for the current
+ * row of data.
+ */
+const byte *gs_image_planes_wanted(P1(const gs_image_enum *penum));
+
/* Clean up after processing an image. */
void gs_image_cleanup(P1(gs_image_enum * penum));
diff --git a/gs/src/gsio.h b/gs/src/gsio.h
index a6f374f7c..bfd7b6fba 100644
--- a/gs/src/gsio.h
+++ b/gs/src/gsio.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1990, 1993, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1990, 1993, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,7 +23,10 @@
# define gsio_INCLUDED
/* The library and interpreter never use stdin/out/err directly. */
-extern FILE *gs_stdin, *gs_stdout, *gs_stderr;
+extern FILE *gs_stdio[3];
+#define gs_stdin (gs_stdio[0])
+#define gs_stdout (gs_stdio[1])
+#define gs_stderr (gs_stdio[2])
/* Redefine all the relevant stdio functions to use the above. */
/* Some functions we make illegal, rather than redefining them. */
diff --git a/gs/src/gsiodev.c b/gs/src/gsiodev.c
index f95396c43..70f559bc3 100644
--- a/gs/src/gsiodev.c
+++ b/gs/src/gsiodev.c
@@ -234,15 +234,16 @@ gs_getiodevice(int index)
gx_io_device *
gs_findiodevice(const byte * str, uint len)
{
- gx_io_device **pftab;
+ int i;
if (len > 1 && str[len - 1] == '%')
len--;
- for (pftab = io_device_table; *pftab != NULL; pftab++) {
- const char *dname = (*pftab)->dname;
+ for (i = 0; i < gx_io_device_table_count; ++i) {
+ gx_io_device *iodev = io_device_table[i];
+ const char *dname = iodev->dname;
if (strlen(dname) == len + 1 && !memcmp(str, dname, len))
- return *pftab;
+ return iodev;
}
return 0;
}
diff --git a/gs/src/gsiparam.h b/gs/src/gsiparam.h
index 4bc9fcc4c..84c582f37 100644
--- a/gs/src/gsiparam.h
+++ b/gs/src/gsiparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#ifndef gsiparam_INCLUDED
# define gsiparam_INCLUDED
+#include "gsccolor.h" /* for GS_CLIENT_COLOR_MAX_COMPONENTS */
#include "gsmatrix.h"
/* ---------------- Image parameters ---------------- */
@@ -61,11 +62,13 @@ typedef struct gs_image_common_s {
"gs_image_common_t")
/*
- * Define the maximum number of components in image data. When we
- * support DeviceN color spaces, we will have to rethink this.
- * 5 is either CMYK + alpha or mask + CMYK.
+ * Define the maximum number of components in image data.
+ * The +1 is for either color + alpha or mask + color.
*/
-#define gs_image_max_components 5
+#define GS_IMAGE_MAX_COLOR_COMPONENTS GS_CLIENT_COLOR_MAX_COMPONENTS
+#define GS_IMAGE_MAX_COMPONENTS (GS_IMAGE_MAX_COLOR_COMPONENTS + 1)
+/* Backward compatibility */
+#define gs_image_max_components GS_IMAGE_MAX_COMPONENTS
/*
* Define the maximum number of planes in image data. Since we support
@@ -74,7 +77,9 @@ typedef struct gs_image_common_s {
* (currently 8 for multi-component bit-planar images, but could be 16
* someday; 32 or maybe 64 for DevicePixel images).
*/
-#define gs_image_max_planes (gs_image_max_components * 8)
+#define GS_IMAGE_MAX_PLANES (GS_IMAGE_MAX_COMPONENTS * 8)
+/* Backward compatibility */
+#define gs_image_max_planes GS_IMAGE_MAX_PLANES
/*
* Define the structure for defining data common to ImageType 1 images,
@@ -111,7 +116,7 @@ typedef struct gs_image_common_s {
* For masks, only the first two entries are used;\
* they must be 1,0 for write-0s masks, 0,1 for write-1s.\
*/\
- float Decode[gs_image_max_components * 2];\
+ float Decode[GS_IMAGE_MAX_COMPONENTS * 2];\
/*\
* Define whether to smooth the image.\
*/\
@@ -256,9 +261,21 @@ void
* adjust, and Alpha, and the image type. For masks, write_1s = false
* paints 0s, write_1s = true paints 1s. This is consistent with the
* "polarity" operand of the PostScript imagemask operator.
+ *
+ * init and init_mask initialize adjust to true. This is a bad decision
+ * which unfortunately we can't undo without breaking backward
+ * compatibility. That is why we added init_adjust and init_mask_adjust.
+ * Note that for init and init_adjust, adjust is only relevant if
+ * pim->ImageMask is true.
*/
-void gs_image_t_init(P2(gs_image_t * pim, const gs_color_space * pcs));
-void gs_image_t_init_mask(P2(gs_image_t * pim, bool write_1s));
+void gs_image_t_init_adjust(P3(gs_image_t * pim, const gs_color_space * pcs,
+ bool adjust));
+#define gs_image_t_init(pim, pcs)\
+ gs_image_t_init_adjust(pim, pcs, true)
+void gs_image_t_init_mask_adjust(P3(gs_image_t * pim, bool write_1s,
+ bool adjust));
+#define gs_image_t_init_mask(pim, write_1s)\
+ gs_image_t_init_mask_adjust(pim, write_1s, true)
/* init_gray and init_color require a (const) imager state. */
#define gs_image_t_init_gray(pim, pis)\
@@ -282,13 +299,14 @@ void gs_image_t_init_mask(P2(gs_image_t * pim, bool write_1s));
int gx_map_image_color(P5(gx_device * dev,
const gs_image_t * pim,
const gx_color_rendering_info * pcri,
- const uint components[4],
+ const uint components[GS_IMAGE_MAX_COMPONENTS],
gx_drawing_color * pdcolor));
/*
- Map a source color to a drawing color. The components are simply the pixel
- component values from the input data, i.e., 1 to 4 B-bit numbers from the
- source data. Return 0 if the operation succeeded, or a negative error code.
+ Map a source color to a drawing color. The components are simply the
+ pixel component values from the input data, i.e., 1 to
+ GS_IMAGE_MAX_COMPONENTS B-bit numbers from the source data. Return 0 if
+ the operation succeeded, or a negative error code.
*/
#endif /*************************************************************** */
diff --git a/gs/src/gsiparm4.h b/gs/src/gsiparm4.h
index 42e36f9d5..b0ffb7729 100644
--- a/gs/src/gsiparm4.h
+++ b/gs/src/gsiparm4.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,7 +41,7 @@ typedef struct gs_image4_s {
* samples up to 32 bits as well.
*/
bool MaskColor_is_range;
- uint MaskColor[gs_image_max_components * 2];
+ uint MaskColor[GS_IMAGE_MAX_COMPONENTS * 2];
} gs_image4_t;
#define private_st_gs_image4() /* in gximage4.c */\
diff --git a/gs/src/gsistate.c b/gs/src/gsistate.c
new file mode 100644
index 000000000..586db23e5
--- /dev/null
+++ b/gs/src/gsistate.c
@@ -0,0 +1,266 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Imager state housekeeping */
+#include "gx.h"
+#include "gserrors.h"
+#include "gscspace.h"
+#include "gscie.h"
+#include "gsstruct.h"
+#include "gsutil.h" /* for gs_next_ids */
+#include "gxbitmap.h"
+#include "gxcmap.h"
+#include "gxdht.h"
+#include "gxistate.h"
+#include "gzht.h"
+#include "gzline.h"
+
+/******************************************************************************
+ * See gsstate.c for a discussion of graphics/imager state memory management. *
+ ******************************************************************************/
+
+/* Imported values */
+/* The following should include a 'const', but for some reason */
+/* the Watcom compiler won't accept it, even though it happily accepts */
+/* the same construct everywhere else. */
+extern /*const*/ gx_color_map_procs *const cmap_procs_default;
+
+/* Structure descriptors */
+private_st_imager_state_shared();
+
+/* GC procedures for gx_line_params */
+private
+ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0;
+ case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ?
+ NULL : plp->dash.pattern));
+ENUM_PTRS_END
+private RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp)
+{
+ if (plp->dash.pattern_size)
+ RELOC_VAR(plp->dash.pattern);
+} RELOC_PTRS_END
+private_st_line_params();
+
+/* GC procedures for gs_imager_state */
+public_st_imager_state();
+private
+ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
+ ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
+ ENUM_PTR(0, gs_imager_state, shared);
+ ENUM_PTR(1, gs_imager_state, client_data);
+#define E1(i,elt) ENUM_PTR(i+2,gs_imager_state,elt);
+ gs_cr_state_do_ptrs(E1)
+#undef E1
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
+{
+ RELOC_SUPER(gs_imager_state, st_line_params, line_params);
+ RELOC_PTR(gs_imager_state, shared);
+ RELOC_PTR(gs_imager_state, client_data);
+#define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
+ gs_cr_state_do_ptrs(R1)
+#undef R1
+} RELOC_PTRS_END
+
+/* Free device color spaces. */
+void
+gx_device_color_spaces_free(gx_device_color_spaces_t *pdcs, gs_memory_t *mem,
+ client_name_t cname)
+{
+ int i;
+
+ for (i = countof(pdcs->indexed); --i >= 0; ) {
+ gs_color_space *pcs = pdcs->indexed[i];
+
+ if (pcs) {
+ gs_cspace_release(pcs);
+ gs_free_object(mem, pcs, cname);
+ }
+ }
+}
+
+/* Initialize an imager state, other than the parts covered by */
+/* gs_imager_state_initial. */
+private float
+imager_null_transfer(floatp gray, const gx_transfer_map * pmap)
+{
+ return gray;
+}
+private void
+rc_free_imager_shared(gs_memory_t * mem, void *data, client_name_t cname)
+{
+ gs_imager_state_shared_t * const shared =
+ (gs_imager_state_shared_t *)data;
+
+ gx_device_color_spaces_free(&shared->device_color_spaces, mem,
+ "shared device color space");
+ rc_free_struct_only(mem, data, cname);
+}
+
+int
+gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
+{
+ pis->memory = mem;
+ pis->client_data = 0;
+ /* Preallocate color spaces. */
+ {
+ int code;
+ gs_imager_state_shared_t *shared;
+
+ rc_alloc_struct_1(shared, gs_imager_state_shared_t,
+ &st_imager_state_shared, mem,
+ return_error(gs_error_VMerror),
+ "gs_imager_state_init(shared)");
+ shared->device_color_spaces.named.Gray =
+ shared->device_color_spaces.named.RGB =
+ shared->device_color_spaces.named.CMYK = 0; /* in case we bail out */
+ shared->rc.free = rc_free_imager_shared;
+ if ((code = gs_cspace_build_DeviceGray(&shared->device_color_spaces.named.Gray, mem)) < 0 ||
+ (code = gs_cspace_build_DeviceRGB(&shared->device_color_spaces.named.RGB, mem)) < 0 ||
+ (code = gs_cspace_build_DeviceCMYK(&shared->device_color_spaces.named.CMYK, mem)) < 0
+ ) {
+ rc_free_imager_shared(mem, shared, "gs_imager_state_init(shared)");
+ return code;
+ }
+ pis->shared = shared;
+ }
+ pis->halftone = 0;
+ {
+ int i;
+
+ for (i = 0; i < gs_color_select_count; ++i)
+ pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
+ }
+ pis->dev_ht = 0;
+ pis->ht_cache = 0;
+ pis->cie_render = 0;
+ pis->black_generation = 0;
+ pis->undercolor_removal = 0;
+ /* Allocate an initial transfer map. */
+ rc_alloc_struct_n(pis->set_transfer.colored.gray,
+ gx_transfer_map, &st_transfer_map,
+ mem, return_error(gs_error_VMerror),
+ "gs_imager_state_init(transfer)", 4);
+ pis->set_transfer.colored.gray->proc = imager_null_transfer;
+ pis->set_transfer.colored.gray->id = gs_next_ids(1);
+ pis->set_transfer.colored.gray->values[0] = frac_0;
+ pis->set_transfer.colored.red =
+ pis->set_transfer.colored.green =
+ pis->set_transfer.colored.blue =
+ pis->set_transfer.colored.gray;
+ pis->effective_transfer = pis->set_transfer;
+ pis->cie_joint_caches = 0;
+ pis->cmap_procs = cmap_procs_default;
+ pis->pattern_cache = 0;
+ return 0;
+}
+
+/*
+ * Make a temporary copy of a gs_imager_state. Note that this does not
+ * do all the necessary reference counting, etc.
+ */
+gs_imager_state *
+gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem)
+{
+ gs_imager_state *pis_copy =
+ gs_alloc_struct(mem, gs_imager_state, &st_imager_state,
+ "gs_imager_state_copy");
+
+ if (pis_copy)
+ *pis_copy = *pis;
+ return pis_copy;
+}
+
+/* Increment reference counts to note that an imager state has been copied. */
+void
+gs_imager_state_copied(gs_imager_state * pis)
+{
+ rc_increment(pis->shared);
+ rc_increment(pis->halftone);
+ rc_increment(pis->dev_ht);
+ rc_increment(pis->cie_render);
+ rc_increment(pis->black_generation);
+ rc_increment(pis->undercolor_removal);
+ rc_increment(pis->set_transfer.colored.gray);
+ rc_increment(pis->set_transfer.colored.red);
+ rc_increment(pis->set_transfer.colored.green);
+ rc_increment(pis->set_transfer.colored.blue);
+ rc_increment(pis->cie_joint_caches);
+}
+
+/* Adjust reference counts before assigning one imager state to another. */
+void
+gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
+{
+ const char *const cname = "gs_imager_state_pre_assign";
+
+#define RCCOPY(element)\
+ rc_pre_assign(pto->element, pfrom->element, cname)
+
+ RCCOPY(cie_joint_caches);
+ RCCOPY(set_transfer.colored.blue);
+ RCCOPY(set_transfer.colored.green);
+ RCCOPY(set_transfer.colored.red);
+ RCCOPY(set_transfer.colored.gray);
+ RCCOPY(undercolor_removal);
+ RCCOPY(black_generation);
+ RCCOPY(cie_render);
+ RCCOPY(dev_ht);
+ RCCOPY(halftone);
+ RCCOPY(shared);
+#undef RCCOPY
+}
+
+/* Release an imager state. */
+void
+gs_imager_state_release(gs_imager_state * pis)
+{
+ const char *const cname = "gs_imager_state_release";
+ gx_device_halftone *pdht = pis->dev_ht;
+
+#define RCDECR(element)\
+ rc_decrement(pis->element, cname)
+
+ RCDECR(cie_joint_caches);
+ RCDECR(set_transfer.colored.gray);
+ RCDECR(set_transfer.colored.blue);
+ RCDECR(set_transfer.colored.green);
+ RCDECR(set_transfer.colored.red);
+ RCDECR(undercolor_removal);
+ RCDECR(black_generation);
+ RCDECR(cie_render);
+ /*
+ * If we're going to free the device halftone, make sure we free the
+ * dependent structures as well.
+ */
+ if (pdht != 0 && pdht->rc.ref_count == 1) {
+ /* Make sure we don't leave dangling pointers in the cache. */
+ gx_ht_cache *pcache = pis->ht_cache;
+
+ if (pcache->order.bit_data == pdht->order.bit_data ||
+ pcache->order.levels == pdht->order.levels
+ )
+ gx_ht_clear_cache(pcache);
+ gx_device_halftone_release(pdht, pdht->rc.memory);
+ }
+ RCDECR(dev_ht);
+ RCDECR(halftone);
+ RCDECR(shared);
+#undef RCDECR
+}
diff --git a/gs/src/gsjconf.h b/gs/src/gsjconf.h
index 6d6be0e21..54e67d072 100644
--- a/gs/src/gsjconf.h
+++ b/gs/src/gsjconf.h
@@ -25,7 +25,7 @@
/*
* We should have the following here:
- #include "stdpre.h"
+#include "stdpre.h"
* But because of the directory structure used to build the IJG library, we
* actually concatenate stdpre.h on the front of this file instead to
@@ -57,14 +57,14 @@
#undef INCOMPLETE_TYPES_BROKEN
/* The following is documented in jmemsys.h, not jconfig.doc. */
-#if arch_ints_are_short
+#if ARCH_SIZEOF_INT <= 2
# undef MAX_ALLOC_CHUNK
# define MAX_ALLOC_CHUNK 0xfff0
#endif
#ifdef JPEG_INTERNALS
-#if arch_arith_rshift == 0
+#if ARCH_ARITH_RSHIFT == 0
# define RIGHT_SHIFT_IS_UNSIGNED
#else
# undef RIGHT_SHIFT_IS_UNSIGNED
diff --git a/gs/src/gslib.c b/gs/src/gslib.c
index 4a4e20719..ec366a340 100644
--- a/gs/src/gslib.c
+++ b/gs/src/gslib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,6 +36,7 @@ get_real(void)
#include "gsmatrix.h"
#include "gsstate.h"
#include "gscspace.h"
+#include "gscssub.h"
#include "gscolor2.h"
#include "gscoord.h"
#include "gscie.h"
@@ -590,8 +591,7 @@ test5(gs_state * pgs, gs_memory_t * mem)
0x66
};
- gs_image3_t_init(&image3,
- gs_cspace_DeviceGray((const gs_imager_state *)pgs),
+ gs_image3_t_init(&image3, gs_current_DeviceGray_space(pgs),
interleave_scan_lines);
/* image */
image3.ImageMatrix.xx = W;
@@ -663,8 +663,7 @@ test5(gs_state * pgs, gs_memory_t * mem)
gs_image4_t image4;
const byte *data4 = data3;
- gs_image4_t_init(&image4,
- gs_cspace_DeviceGray((const gs_imager_state *)pgs));
+ gs_image4_t_init(&image4, gs_current_DeviceGray_space(pgs));
/* image */
image4.ImageMatrix.xx = W;
image4.ImageMatrix.yy = -H;
@@ -698,7 +697,6 @@ test5(gs_state * pgs, gs_memory_t * mem)
/* ---------------- Test program 6 ---------------- */
/* Test the C API for CIE CRDs, and color snapping. */
-extern const gs_color_space_type gs_color_space_type_CIEABC;
private void
spectrum(gs_state * pgs, int n)
{
@@ -728,6 +726,21 @@ render_abc(floatp v, const gs_cie_render * ignore_crd)
return v / 2;
}
private int
+set_cmap_method(gx_device_cmap *cmdev, gx_device_color_mapping_method_t method,
+ gs_state *pgs, gs_memory_t *mem)
+{
+ gs_c_param_list list;
+ int cmm = method;
+
+ gs_c_param_list_write(&list, mem);
+ param_write_int((gs_param_list *)&list, "ColorMappingMethod", &cmm);
+ gs_c_param_list_read(&list);
+ gs_putdeviceparams((gx_device *)cmdev, (gs_param_list *)&list);
+ gs_c_param_list_release(&list);
+ gs_setdevice_no_init(pgs, (gx_device *)cmdev);
+ return 0;
+}
+private int
test6(gs_state * pgs, gs_memory_t * mem)
{
gs_color_space *pcs;
@@ -744,8 +757,7 @@ test6(gs_state * pgs, gs_memory_t * mem)
gs_scale(pgs, 150.0, 150.0);
gs_translate(pgs, 0.5, 0.5);
- gs_setcolorspace(pgs,
- gs_cspace_DeviceRGB((const gs_imager_state *)pgs));
+ gs_setcolorspace(pgs, gs_current_DeviceRGB_space(pgs));
spectrum(pgs, 5);
gs_translate(pgs, 1.2, 0.0);
/* We must set the CRD before the color space. */
@@ -777,7 +789,10 @@ test6(gs_state * pgs, gs_memory_t * mem)
gs_translate(pgs, -1.2, 1.2);
spectrum(pgs, 5);
gs_translate(pgs, 1.2, 0.0);
- gdev_cmap_set_method(cmdev, device_cmap_monochrome);
+ set_cmap_method(cmdev, device_cmap_monochrome, pgs, mem);
+ spectrum(pgs, 5);
+ gs_translate(pgs, -1.2, 1.2);
+ set_cmap_method(cmdev, device_cmap_color_to_black_over_white, pgs, mem);
spectrum(pgs, 5);
return 0;
}
@@ -857,7 +872,7 @@ test8(gs_state * pgs, gs_memory_t * mem)
(const byte *)"\377\377\377\377\000\000\000\377\000\000\000\000";
table.size = 12;
gs_cspace_build_Indexed(&pcs,
- gs_cspace_DeviceRGB((const gs_imager_state *)pgs),
+ gs_current_DeviceRGB_space(pgs),
4,
&table,
mem);
diff --git a/gs/src/gsline.c b/gs/src/gsline.c
index 20522d419..80a6991b5 100644
--- a/gs/src/gsline.c
+++ b/gs/src/gsline.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
diff --git a/gs/src/gsline.h b/gs/src/gsline.h
index e07bdd9ca..fade79cf0 100644
--- a/gs/src/gsline.h
+++ b/gs/src/gsline.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,19 +28,14 @@
int gs_setlinewidth(P2(gs_state *, floatp));
float gs_currentlinewidth(P1(const gs_state *));
int gs_setlinecap(P2(gs_state *, gs_line_cap));
-
-gs_line_cap
-gs_currentlinecap(P1(const gs_state *));
+gs_line_cap gs_currentlinecap(P1(const gs_state *));
int gs_setlinejoin(P2(gs_state *, gs_line_join));
-
-gs_line_join
-gs_currentlinejoin(P1(const gs_state *));
+gs_line_join gs_currentlinejoin(P1(const gs_state *));
int gs_setmiterlimit(P2(gs_state *, floatp));
float gs_currentmiterlimit(P1(const gs_state *));
int gs_setdash(P4(gs_state *, const float *, uint, floatp));
uint gs_currentdash_length(P1(const gs_state *));
-const float *
- gs_currentdash_pattern(P1(const gs_state *));
+const float *gs_currentdash_pattern(P1(const gs_state *));
float gs_currentdash_offset(P1(const gs_state *));
int gs_setflat(P2(gs_state *, floatp));
float gs_currentflat(P1(const gs_state *));
diff --git a/gs/src/gsmalloc.c b/gs/src/gsmalloc.c
index 037653ba2..af6212337 100644
--- a/gs/src/gsmalloc.c
+++ b/gs/src/gsmalloc.c
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+/*$Id: gsmalloc.c */
/* C heap allocator */
#include "malloc_.h"
#include "gdebug.h"
@@ -27,7 +27,8 @@
#include "gsmdebug.h"
#include "gsstruct.h" /* for st_bytes */
#include "gsmalloc.h"
-#include "gsmemlok.h"
+#include "gsmemlok.h" /* locking (multithreading) wrapper */
+#include "gsmemret.h" /* retrying wrapper */
/* ------ Heap allocator ------ */
@@ -404,26 +405,45 @@ gs_heap_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname)
free(mem);
}
-/* ------ Locking ------ */
+/* ------ Wrapping ------ */
-/* Create the locked wrapper for the heap allocator. */
+/* Create the retrying and the locked wrapper for the heap allocator. */
int
gs_malloc_wrap(gs_memory_t **wrapped, gs_malloc_memory_t *contents)
{
gs_memory_t *cmem = (gs_memory_t *)contents;
gs_memory_locked_t *lmem = (gs_memory_locked_t *)
gs_alloc_bytes_immovable(cmem, sizeof(gs_memory_locked_t),
- "gs_malloc_wrap");
+ "gs_malloc_wrap(locked)");
+ gs_memory_retrying_t *rmem;
int code;
if (lmem == 0)
return_error(gs_error_VMerror);
code = gs_memory_locked_init(lmem, cmem);
if (code < 0) {
- gs_free_object(cmem, lmem, "gs_malloc_wrap");
+ gs_free_object(cmem, lmem, "gs_malloc_wrap(locked)");
return code;
}
- *wrapped = (gs_memory_t *)lmem;
+
+ rmem = (gs_memory_retrying_t *)
+ gs_alloc_bytes_immovable((gs_memory_t *)lmem,
+ sizeof(gs_memory_retrying_t),
+ "gs_malloc_wrap(retrying)");
+ if (rmem == 0) {
+ gs_memory_locked_release(lmem);
+ gs_free_object(cmem, lmem, "gs_malloc_wrap(locked)");
+ return_error(gs_error_VMerror);
+ }
+ code = gs_memory_retrying_init(rmem, (gs_memory_t *)lmem);
+ if (code < 0) {
+ gs_free_object((gs_memory_t *)lmem, rmem, "gs_malloc_wrap(retrying)");
+ gs_memory_locked_release(lmem);
+ gs_free_object(cmem, lmem, "gs_malloc_wrap(locked)");
+ return code;
+ }
+
+ *wrapped = (gs_memory_t *)rmem;
return 0;
}
@@ -431,7 +451,9 @@ gs_malloc_wrap(gs_memory_t **wrapped, gs_malloc_memory_t *contents)
gs_malloc_memory_t *
gs_malloc_wrapped_contents(gs_memory_t *wrapped)
{
- gs_memory_locked_t *lmem = (gs_memory_locked_t *)wrapped;
+ gs_memory_retrying_t *rmem = (gs_memory_retrying_t *)wrapped;
+ gs_memory_locked_t *lmem =
+ (gs_memory_locked_t *)gs_memory_retrying_target(rmem);
return (gs_malloc_memory_t *)gs_memory_locked_target(lmem);
}
@@ -440,11 +462,14 @@ gs_malloc_wrapped_contents(gs_memory_t *wrapped)
gs_malloc_memory_t *
gs_malloc_unwrap(gs_memory_t *wrapped)
{
- gs_memory_locked_t *lmem = (gs_memory_locked_t *)wrapped;
+ gs_memory_retrying_t *rmem = (gs_memory_retrying_t *)wrapped;
+ gs_memory_locked_t *lmem =
+ (gs_memory_locked_t *)gs_memory_retrying_target(rmem);
gs_memory_t *contents = gs_memory_locked_target(lmem);
+ gs_free_object((gs_memory_t *)lmem, rmem, "gs_malloc_unwrap(retrying)");
gs_memory_locked_release(lmem);
- gs_free_object(contents, lmem, "gs_malloc_unwrap");
+ gs_free_object(contents, lmem, "gs_malloc_unwrap(locked)");
return (gs_malloc_memory_t *)contents;
}
diff --git a/gs/src/gsmalloc.h b/gs/src/gsmalloc.h
index 3c12bc9e9..999eb7b6b 100644
--- a/gs/src/gsmalloc.h
+++ b/gs/src/gsmalloc.h
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Client interface to default (C heap) allocator */
/* Requires gsmemory.h */
diff --git a/gs/src/gsmatrix.c b/gs/src/gsmatrix.c
index cba495cf0..6b7e5c167 100644
--- a/gs/src/gsmatrix.c
+++ b/gs/src/gsmatrix.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,6 +19,7 @@
/* Matrix operators for Ghostscript library */
#include "math_.h"
+#include "memory_.h"
#include "gx.h"
#include "gserrors.h"
#include "gxfarith.h"
@@ -375,7 +376,7 @@ gs_point_transform2fixed(const gs_matrix_fixed * pmat,
floatp x, floatp y, gs_fixed_point * ppt)
{
fixed px, py, t;
- double dtemp;
+ double xtemp, ytemp;
int code;
if (!pmat->txy_fixed_valid) { /* The translation is out of range. Do the */
@@ -391,28 +392,35 @@ gs_point_transform2fixed(const gs_matrix_fixed * pmat,
return 0;
}
if (!is_fzero(pmat->xy)) { /* Hope for 90 degree rotation */
- if ((code = set_dfmul2fixed_vars(px, y, pmat->yx, dtemp)) < 0 ||
- (code = set_dfmul2fixed_vars(py, x, pmat->xy, dtemp)) < 0
+ if ((code = CHECK_DFMUL2FIXED_VARS(px, y, pmat->yx, xtemp)) < 0 ||
+ (code = CHECK_DFMUL2FIXED_VARS(py, x, pmat->xy, ytemp)) < 0
)
return code;
+ FINISH_DFMUL2FIXED_VARS(px, xtemp);
+ FINISH_DFMUL2FIXED_VARS(py, ytemp);
if (!is_fzero(pmat->xx)) {
- if ((code = set_dfmul2fixed_vars(t, x, pmat->xx, dtemp)) < 0)
+ if ((code = CHECK_DFMUL2FIXED_VARS(t, x, pmat->xx, xtemp)) < 0)
return code;
+ FINISH_DFMUL2FIXED_VARS(t, xtemp);
px += t; /* should check for overflow */
}
if (!is_fzero(pmat->yy)) {
- if ((code = set_dfmul2fixed_vars(t, y, pmat->yy, dtemp)) < 0)
+ if ((code = CHECK_DFMUL2FIXED_VARS(t, y, pmat->yy, ytemp)) < 0)
return code;
+ FINISH_DFMUL2FIXED_VARS(t, ytemp);
py += t; /* should check for overflow */
}
} else {
- if ((code = set_dfmul2fixed_vars(px, x, pmat->xx, dtemp)) < 0 ||
- (code = set_dfmul2fixed_vars(py, y, pmat->yy, dtemp)) < 0
+ if ((code = CHECK_DFMUL2FIXED_VARS(px, x, pmat->xx, xtemp)) < 0 ||
+ (code = CHECK_DFMUL2FIXED_VARS(py, y, pmat->yy, ytemp)) < 0
)
return code;
+ FINISH_DFMUL2FIXED_VARS(px, xtemp);
+ FINISH_DFMUL2FIXED_VARS(py, ytemp);
if (!is_fzero(pmat->yx)) {
- if ((code = set_dfmul2fixed_vars(t, y, pmat->yx, dtemp)) < 0)
+ if ((code = CHECK_DFMUL2FIXED_VARS(t, y, pmat->yx, ytemp)) < 0)
return code;
+ FINISH_DFMUL2FIXED_VARS(t, ytemp);
px += t; /* should check for overflow */
}
}
@@ -427,21 +435,25 @@ gs_distance_transform2fixed(const gs_matrix_fixed * pmat,
floatp dx, floatp dy, gs_fixed_point * ppt)
{
fixed px, py, t;
- double dtemp;
+ double xtemp, ytemp;
int code;
- if ((code = set_dfmul2fixed_vars(px, dx, pmat->xx, dtemp)) < 0 ||
- (code = set_dfmul2fixed_vars(py, dy, pmat->yy, dtemp)) < 0
+ if ((code = CHECK_DFMUL2FIXED_VARS(px, dx, pmat->xx, xtemp)) < 0 ||
+ (code = CHECK_DFMUL2FIXED_VARS(py, dy, pmat->yy, ytemp)) < 0
)
return code;
+ FINISH_DFMUL2FIXED_VARS(px, xtemp);
+ FINISH_DFMUL2FIXED_VARS(py, ytemp);
if (!is_fzero(pmat->yx)) {
- if ((code = set_dfmul2fixed_vars(t, dy, pmat->yx, dtemp)) < 0)
+ if ((code = CHECK_DFMUL2FIXED_VARS(t, dy, pmat->yx, ytemp)) < 0)
return code;
+ FINISH_DFMUL2FIXED_VARS(t, ytemp);
px += t; /* should check for overflow */
}
if (!is_fzero(pmat->xy)) {
- if ((code = set_dfmul2fixed_vars(t, dx, pmat->xy, dtemp)) < 0)
+ if ((code = CHECK_DFMUL2FIXED_VARS(t, dx, pmat->xy, xtemp)) < 0)
return code;
+ FINISH_DFMUL2FIXED_VARS(t, xtemp);
py += t; /* should check for overflow */
}
ppt->x = px;
diff --git a/gs/src/gsmemlok.c b/gs/src/gsmemlok.c
index 1f25919da..4274c1611 100644
--- a/gs/src/gsmemlok.c
+++ b/gs/src/gsmemlok.c
@@ -16,12 +16,13 @@
all copies.
*/
-/*$Id$ */
+
/* Monitor-locked heap memory allocator */
/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
/* Revised 8/6/98 by L. Peter Deutsch (ghost@aladdin.com) for changes */
/* in memory manager API */
+/* Edited 3/23/1999 by L. Peter Deutsch to remove compiler warnings. */
#include "gx.h"
#include "gsmemlok.h"
@@ -52,7 +53,7 @@ private gs_memory_proc_free_string(gs_locked_free_string);
private gs_memory_proc_register_root(gs_locked_register_root);
private gs_memory_proc_unregister_root(gs_locked_unregister_root);
private gs_memory_proc_enable_free(gs_locked_enable_free);
-private gs_memory_procs_t locked_procs =
+private const gs_memory_procs_t locked_procs =
{
/* Raw memory procedures */
gs_locked_alloc_bytes_immovable,
@@ -119,25 +120,26 @@ gs_memory_locked_target(const gs_memory_locked_t *lmem)
/* -------- Private members just wrap a monitor around a gs_memory_heap --- */
+/*
+ * Contrary to our usual practice, we don't use BEGIN/END here, because
+ * that causes some compilers to give bogus error messages.
+ */
+
#define DO_MONITORED(call_target)\
- BEGIN\
gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem;\
\
gx_monitor_enter(lmem->monitor);\
call_target;\
- gx_monitor_leave(lmem->monitor);\
- END
+ gx_monitor_leave(lmem->monitor)
#define RETURN_MONITORED(result_type, call_target)\
- BEGIN\
gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem;\
result_type temp;\
\
gx_monitor_enter(lmem->monitor);\
temp = call_target;\
gx_monitor_leave(lmem->monitor);\
- return temp;\
- END
+ return temp
/* Procedures */
private void
diff --git a/gs/src/gsmemlok.h b/gs/src/gsmemlok.h
index c4c6700f8..90bb7a36c 100644
--- a/gs/src/gsmemlok.h
+++ b/gs/src/gsmemlok.h
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Interface to monitor-locked heap memory allocator */
/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
diff --git a/gs/src/gsmemory.c b/gs/src/gsmemory.c
index 6d5186931..2ee34ff32 100644
--- a/gs/src/gsmemory.c
+++ b/gs/src/gsmemory.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,6 +19,7 @@
/* Generic allocator support */
#include "memory_.h"
+#include "gdebug.h"
#include "gstypes.h"
#include "gsmemory.h"
#include "gsmdebug.h"
@@ -45,6 +46,42 @@ public_st_gc_root_t();
private_st_const_string();
public_st_const_string_element();
+/* GC procedures for bytestrings */
+gs_ptr_type_t
+enum_bytestring(const void **pep, const gs_bytestring *pbs)
+{
+ return (pbs->bytes ? ENUM_OBJ(pbs->bytes) : ENUM_STRING(pbs));
+}
+gs_ptr_type_t
+enum_const_bytestring(const void **pep, const gs_const_bytestring *pbs)
+{
+ return (pbs->bytes ? ENUM_OBJ(pbs->bytes) : ENUM_CONST_STRING(pbs));
+}
+void
+reloc_bytestring(gs_bytestring *pbs, gc_state_t *gcst)
+{
+ if (pbs->bytes) {
+ byte *bytes = pbs->bytes;
+ long offset = pbs->data - bytes;
+
+ pbs->bytes = bytes = RELOC_OBJ(bytes);
+ pbs->data = bytes + offset;
+ } else
+ RELOC_STRING_VAR(*(gs_string *)pbs);
+}
+void
+reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst)
+{
+ if (pbs->bytes) {
+ const byte *bytes = pbs->bytes;
+ long offset = pbs->data - bytes;
+
+ pbs->bytes = bytes = RELOC_OBJ(bytes);
+ pbs->data = bytes + offset;
+ } else
+ RELOC_CONST_STRING_VAR(*(gs_const_string *)pbs);
+}
+
/* Fill an unoccupied block with a pattern. */
/* Note that the block size may be too large for a single memset. */
void
@@ -80,6 +117,26 @@ gs_ignore_free_string(gs_memory_t * mem, byte * data, uint nbytes,
{
}
+/* Deconstifying freeing procedures. */
+/* These procedures rely on a severely deprecated pun. */
+void
+gs_free_const_object(gs_memory_t * mem, const void *data, client_name_t cname)
+{
+ union { const void *r; void *w; } u;
+
+ u.r = data;
+ gs_free_object(mem, u.w, cname);
+}
+void
+gs_free_const_string(gs_memory_t * mem, const byte * data, uint nbytes,
+ client_name_t cname)
+{
+ union { const byte *r; byte *w; } u;
+
+ u.r = data;
+ gs_free_string(mem, u.w, nbytes, cname);
+}
+
/* No-op consolidation procedure */
void
gs_ignore_consolidate_free(gs_memory_t *mem)
@@ -121,6 +178,37 @@ gs_register_struct_root(gs_memory_t *mem, gs_gc_root_t *root,
return gs_register_root(mem, root, ptr_struct_type, pp, cname);
}
+/* ---------------- Reference counting ---------------- */
+
+#ifdef DEBUG
+
+const char *
+rc_object_type_name(const void *vp, const rc_header *prc)
+{
+ gs_memory_type_ptr_t pstype;
+
+ if (prc->memory == 0)
+ return "(unknown)";
+ pstype = gs_object_type(prc->memory, vp);
+ if (prc->free != rc_free_struct_only) {
+ /*
+ * This object might be stack-allocated or have other unusual memory
+ * management properties. Make some reasonableness checks.
+ * ****** THIS IS A HACK. ******
+ */
+ long dist;
+
+ dist = (const char *)&dist - (const char *)vp;
+ if (dist < 10000 && dist > -10000)
+ return "(on stack)";
+ if ((ulong)pstype < 0x10000 || (long)pstype < 0)
+ return "(anomalous)";
+ }
+ return client_name_string(gs_struct_type_name(pstype));
+}
+
+#endif /* DEBUG */
+
/* Normal freeing routine for reference-counted structures. */
void
rc_free_struct_only(gs_memory_t * mem, void *data, client_name_t cname)
@@ -147,7 +235,6 @@ ENUM_PTRS_BEGIN_PROC(basic_enum_ptrs)
return ENUM_STRING((gs_string *) pptr);
case GC_ELT_CONST_STRING:
return ENUM_CONST_STRING((gs_string *) pptr);
- /****** WHAT ABOUT REFS? ******/
}
}
if (!psd->super_type)
@@ -178,7 +265,6 @@ RELOC_PTRS_BEGIN(basic_reloc_ptrs)
case GC_ELT_CONST_STRING:
RELOC_CONST_STRING_VAR(*(gs_const_string *)pptr);
break;
- /****** WHAT ABOUT REFS? ******/
}
}
if (psd->super_type)
diff --git a/gs/src/gsmemory.h b/gs/src/gsmemory.h
index b5334dd4f..c2c913b1f 100644
--- a/gs/src/gsmemory.h
+++ b/gs/src/gsmemory.h
@@ -238,6 +238,17 @@ typedef struct gs_memory_procs_s {
} gs_memory_procs_t;
+/*
+ * Define versions of the freeing procedures that are applicable even if the
+ * pointer is declared as const T *. These are intended for use where a
+ * structure contains a pointer member whose referent is declared as const
+ * because it is const for all ordinary clients.
+ */
+void gs_free_const_object(P3(gs_memory_t *mem, const void *data,
+ client_name_t cname));
+void gs_free_const_string(P4(gs_memory_t *mem, const byte *data, uint nbytes,
+ client_name_t cname));
+
/* Register a structure root. This just calls gs_register_root. */
int gs_register_struct_root(P4(gs_memory_t *mem, gs_gc_root_t *root,
void **pp, client_name_t cname));
diff --git a/gs/src/gsmemraw.h b/gs/src/gsmemraw.h
index 94349875d..ba6998b71 100644
--- a/gs/src/gsmemraw.h
+++ b/gs/src/gsmemraw.h
@@ -81,11 +81,11 @@ typedef struct gs_raw_memory_s gs_raw_memory_t;
* Resize an object to a new number of elements. At the raw
* memory level, the "element" is a byte; for object memory
* (gsmemory.h), the object may be an an array of either
- * bytes or structures. The new size may be larger than,
- * the same as, or smaller than the old. If the new size is
- * the same as the old, resize_object returns the same
- * object; otherwise, it preserves the first min(old_size,
- * new_size) bytes of the object's contents.
+ * bytes or structures. The new size may be larger than,
+ * the same as, or smaller than the old. If the new size is
+ * the same as the old, resize_object returns the same
+ * object; otherwise, it preserves the first min(old_size,
+ * new_size) bytes of the object's contents.
*/
#define gs_memory_t_proc_resize_object(proc, mem_t)\
diff --git a/gs/src/gsmemret.c b/gs/src/gsmemret.c
new file mode 100644
index 000000000..403559a08
--- /dev/null
+++ b/gs/src/gsmemret.c
@@ -0,0 +1,332 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Retrying memory allocator */
+
+#include "gx.h"
+#include "gsmemret.h"
+#include "gserrors.h"
+
+/* Raw memory procedures */
+private gs_memory_proc_alloc_bytes(gs_retrying_alloc_bytes_immovable);
+private gs_memory_proc_resize_object(gs_retrying_resize_object);
+private gs_memory_proc_free_object(gs_forward_free_object);
+private gs_memory_proc_status(gs_forward_status);
+private gs_memory_proc_free_all(gs_forward_free_all);
+private gs_memory_proc_consolidate_free(gs_forward_consolidate_free);
+
+/* Object memory procedures */
+private gs_memory_proc_alloc_bytes(gs_retrying_alloc_bytes);
+private gs_memory_proc_alloc_struct(gs_retrying_alloc_struct);
+private gs_memory_proc_alloc_struct(gs_retrying_alloc_struct_immovable);
+private gs_memory_proc_alloc_byte_array(gs_retrying_alloc_byte_array);
+private gs_memory_proc_alloc_byte_array(gs_retrying_alloc_byte_array_immovable);
+private gs_memory_proc_alloc_struct_array(gs_retrying_alloc_struct_array);
+private gs_memory_proc_alloc_struct_array(gs_retrying_alloc_struct_array_immovable);
+private gs_memory_proc_object_size(gs_forward_object_size);
+private gs_memory_proc_object_type(gs_forward_object_type);
+private gs_memory_proc_alloc_string(gs_retrying_alloc_string);
+private gs_memory_proc_alloc_string(gs_retrying_alloc_string_immovable);
+private gs_memory_proc_resize_string(gs_retrying_resize_string);
+private gs_memory_proc_free_string(gs_forward_free_string);
+private gs_memory_proc_register_root(gs_retrying_register_root);
+private gs_memory_proc_unregister_root(gs_forward_unregister_root);
+private gs_memory_proc_enable_free(gs_forward_enable_free);
+private const gs_memory_procs_t retrying_procs = {
+ /* Raw memory procedures */
+ gs_retrying_alloc_bytes_immovable,
+ gs_retrying_resize_object,
+ gs_forward_free_object,
+ gs_forward_status,
+ gs_forward_free_all,
+ gs_forward_consolidate_free,
+ /* Object memory procedures */
+ gs_retrying_alloc_bytes,
+ gs_retrying_alloc_struct,
+ gs_retrying_alloc_struct_immovable,
+ gs_retrying_alloc_byte_array,
+ gs_retrying_alloc_byte_array_immovable,
+ gs_retrying_alloc_struct_array,
+ gs_retrying_alloc_struct_array_immovable,
+ gs_forward_object_size,
+ gs_forward_object_type,
+ gs_retrying_alloc_string,
+ gs_retrying_alloc_string_immovable,
+ gs_retrying_resize_string,
+ gs_forward_free_string,
+ gs_retrying_register_root,
+ gs_forward_unregister_root,
+ gs_forward_enable_free
+};
+
+/* Define a vacuous recovery procedure. */
+private gs_memory_recover_status_t
+no_recover_proc(gs_memory_retrying_t *rmem, void *proc_data)
+{
+ return RECOVER_STATUS_NO_RETRY;
+}
+
+/* ---------- Public constructors/destructors ---------- */
+
+/* Initialize a gs_memory_retrying_t */
+int /* -ve error code or 0 */
+gs_memory_retrying_init(
+ gs_memory_retrying_t * rmem, /* allocator to init */
+ gs_memory_t * target /* allocator to wrap */
+)
+{
+ rmem->procs = retrying_procs;
+ rmem->target = target;
+ gs_memory_retrying_set_recover(rmem, no_recover_proc, NULL);
+ return 0;
+}
+
+/* Set the recovery closure of a retrying memory manager. */
+void
+gs_memory_retrying_set_recover(gs_memory_retrying_t *rmem,
+ gs_memory_recover_proc_t recover_proc,
+ void *recover_proc_data)
+{
+ rmem->recover_proc = recover_proc;
+ rmem->recover_proc_data = recover_proc_data;
+}
+
+/* Release a retrying memory manager. */
+/* Note that this has no effect on the target. */
+void
+gs_memory_retrying_release(gs_memory_retrying_t *rmem)
+{
+ gs_memory_free_all((gs_memory_t *)rmem, FREE_ALL_STRUCTURES,
+ "gs_memory_retrying_release");
+}
+
+/* ---------- Accessors ------------- */
+
+/* Retrieve this allocator's target */
+gs_memory_t *
+gs_memory_retrying_target(const gs_memory_retrying_t *rmem)
+{
+ return rmem->target;
+}
+
+/* -------- Private members just wrap retrying around a gs_memory --- */
+
+/*
+ * Contrary to our usual practice, we don't use BEGIN/END here, because
+ * that causes some compilers to give bogus error messages.
+ */
+
+#define DO_FORWARD(call_target)\
+ gs_memory_retrying_t * const rmem = (gs_memory_retrying_t *)mem;\
+ gs_memory_t *const target = rmem->target;\
+\
+ call_target
+
+#define RETURN_RETRYING(result_type, call_target)\
+ gs_memory_retrying_t * const rmem = (gs_memory_retrying_t *)mem;\
+ gs_memory_t *const target = rmem->target;\
+ result_type temp;\
+ gs_memory_recover_status_t retry = RECOVER_STATUS_RETRY_OK;\
+\
+ for (;;) {\
+ temp = call_target;\
+ if (temp != 0 || retry != RECOVER_STATUS_RETRY_OK)\
+ break;\
+ retry = rmem->recover_proc(rmem, rmem->recover_proc_data);\
+ }\
+ return temp
+
+/* Procedures */
+private void
+gs_forward_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname)
+{
+ gs_memory_retrying_t * const rmem = (gs_memory_retrying_t *)mem;
+ gs_memory_t * const target = rmem->target;
+
+ /* Only free the structures and the allocator itself. */
+ rmem->target = 0;
+ if (free_mask & FREE_ALL_ALLOCATOR)
+ gs_free_object(target, rmem, cname);
+}
+private void
+gs_forward_consolidate_free(gs_memory_t * mem)
+{
+ DO_FORWARD(target->procs.consolidate_free(target));
+}
+private byte *
+gs_retrying_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_bytes(target, size, cname)
+ );
+}
+private byte *
+gs_retrying_alloc_bytes_immovable(gs_memory_t * mem, uint size,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_bytes_immovable(target, size, cname)
+ );
+}
+private void *
+gs_retrying_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ void *,
+ target->procs.alloc_struct(target, pstype, cname)
+ );
+}
+private void *
+gs_retrying_alloc_struct_immovable(gs_memory_t * mem,
+ gs_memory_type_ptr_t pstype, client_name_t cname)
+{
+ RETURN_RETRYING(
+ void *,
+ target->procs.alloc_struct_immovable(target, pstype, cname)
+ );
+}
+private byte *
+gs_retrying_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_byte_array(target, num_elements,
+ elt_size, cname)
+ );
+}
+private byte *
+gs_retrying_alloc_byte_array_immovable(gs_memory_t * mem, uint num_elements,
+ uint elt_size, client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_byte_array_immovable(target,
+ num_elements, elt_size,
+ cname)
+ );
+}
+private void *
+gs_retrying_alloc_struct_array(gs_memory_t * mem, uint num_elements,
+ gs_memory_type_ptr_t pstype, client_name_t cname)
+{
+ RETURN_RETRYING(
+ void *,
+ target->procs.alloc_struct_array(target, num_elements,
+ pstype, cname)
+ );
+}
+private void *
+gs_retrying_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements,
+ gs_memory_type_ptr_t pstype, client_name_t cname)
+{
+ RETURN_RETRYING(
+ void *,
+ target->procs.alloc_struct_array_immovable(target,
+ num_elements, pstype,
+ cname)
+ );
+}
+private void *
+gs_retrying_resize_object(gs_memory_t * mem, void *obj, uint new_num_elements,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ void *,
+ target->procs.resize_object(target, obj, new_num_elements,
+ cname)
+ );
+}
+private uint
+gs_forward_object_size(gs_memory_t * mem, const void *ptr)
+{
+ DO_FORWARD(return target->procs.object_size(target, ptr));
+}
+private gs_memory_type_ptr_t
+gs_forward_object_type(gs_memory_t * mem, const void *ptr)
+{
+ DO_FORWARD(return target->procs.object_type(target, ptr));
+}
+private void
+gs_forward_free_object(gs_memory_t * mem, void *ptr, client_name_t cname)
+{
+ DO_FORWARD(target->procs.free_object(target, ptr, cname));
+}
+private byte *
+gs_retrying_alloc_string(gs_memory_t * mem, uint nbytes, client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_string(target, nbytes, cname)
+ );
+}
+private byte *
+gs_retrying_alloc_string_immovable(gs_memory_t * mem, uint nbytes,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.alloc_string_immovable(target, nbytes, cname)
+ );
+}
+private byte *
+gs_retrying_resize_string(gs_memory_t * mem, byte * data, uint old_num,
+ uint new_num,
+ client_name_t cname)
+{
+ RETURN_RETRYING(
+ byte *,
+ target->procs.resize_string(target, data, old_num, new_num,
+ cname)
+ );
+}
+private void
+gs_forward_free_string(gs_memory_t * mem, byte * data, uint nbytes,
+ client_name_t cname)
+{
+ DO_FORWARD(target->procs.free_string(target, data, nbytes, cname));
+}
+private int
+gs_retrying_register_root(gs_memory_t * mem, gs_gc_root_t * rp,
+ gs_ptr_type_t ptype, void **up, client_name_t cname)
+{
+ RETURN_RETRYING(
+ int,
+ target->procs.register_root(target, rp, ptype, up, cname)
+ );
+}
+private void
+gs_forward_unregister_root(gs_memory_t * mem, gs_gc_root_t * rp,
+ client_name_t cname)
+{
+ DO_FORWARD(target->procs.unregister_root(target, rp, cname));
+}
+private void
+gs_forward_status(gs_memory_t * mem, gs_memory_status_t * pstat)
+{
+ DO_FORWARD(target->procs.status(target, pstat));
+}
+private void
+gs_forward_enable_free(gs_memory_t * mem, bool enable)
+{
+ DO_FORWARD(target->procs.enable_free(target, enable));
+}
diff --git a/gs/src/gsmemret.h b/gs/src/gsmemret.h
new file mode 100644
index 000000000..c8d5ff633
--- /dev/null
+++ b/gs/src/gsmemret.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface to retrying memory allocator */
+
+#if !defined(gsmemret_INCLUDED)
+# define gsmemret_INCLUDED
+
+#include "gsmemory.h"
+
+/*
+ * This allocator encapsulates another allocator with a closure that is
+ * called to attempt to free up memory if an allocation fails.
+ * Note that it does not keep track of memory that it acquires:
+ * thus free_all with FREE_ALL_DATA is a no-op.
+ */
+typedef struct gs_memory_retrying_s gs_memory_retrying_t;
+
+/*
+ * Define the procedure type for the recovery closure.
+ */
+typedef enum {
+ RECOVER_STATUS_NO_RETRY,
+ RECOVER_STATUS_RETRY_OK
+} gs_memory_recover_status_t;
+typedef gs_memory_recover_status_t (*gs_memory_recover_proc_t)
+ (P2(gs_memory_retrying_t *rmem, void *proc_data));
+
+struct gs_memory_retrying_s {
+ gs_memory_common; /* interface outside world sees */
+ gs_memory_t *target; /* allocator to front */
+ gs_memory_recover_proc_t recover_proc;
+ void *recover_proc_data;
+};
+
+/* ---------- Public constructors/destructors ---------- */
+
+/* Initialize a retrying memory manager. */
+int gs_memory_retrying_init(P2(
+ gs_memory_retrying_t * rmem, /* allocator to init */
+ gs_memory_t * target /* allocator to wrap */
+ ));
+
+/* Release a retrying memory manager. */
+/* Note that this has no effect on the target. */
+void gs_memory_retrying_release(P1(gs_memory_retrying_t *rmem));
+
+/* Set the recovery closure of a retrying memory manager. */
+void gs_memory_retrying_set_recover(P3(gs_memory_retrying_t *rmem,
+ gs_memory_recover_proc_t recover_proc,
+ void *recover_proc_data));
+
+/* Get the target of a retrying memory manager. */
+gs_memory_t * gs_memory_retrying_target(P1(const gs_memory_retrying_t *rmem));
+
+#endif /*!defined(gsmemret_INCLUDED) */
diff --git a/gs/src/gsmisc.c b/gs/src/gsmisc.c
index f6c34b71b..820196333 100644
--- a/gs/src/gsmisc.c
+++ b/gs/src/gsmisc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,7 +31,9 @@
#include "gxfixed.h"
/* Define private replacements for stdin, stdout, and stderr. */
-FILE *gs_stdin, *gs_stdout, *gs_stderr;
+FILE *gs_stdio[3];
+
+/* ------ Debugging ------ */
/* Ghostscript writes debugging output to gs_debug_out. */
/* We define gs_debug and gs_debug_out even if DEBUG isn't defined, */
@@ -81,10 +83,27 @@ dprintf_file(FILE * f, const char *file)
fprintf(f, dprintf_file_only_format, dprintf_file_tail(file));
}
void
-eprintf_program_name(FILE * f, const char *program_name)
+printf_program_ident(FILE * f, const char *program_name,
+ long revision_number)
+{
+ if (program_name) {
+ fputs(program_name, f);
+ if (revision_number)
+ fputc(' ', f);
+ }
+ if (revision_number)
+ fprintf(f, "%d.%02d",
+ (int)(revision_number / 100),
+ (int)(revision_number % 100));
+}
+void
+eprintf_program_ident(FILE * f, const char *program_name,
+ long revision_number)
{
- if (program_name)
- fprintf(f, "%s: ", program_name);
+ if (program_name) {
+ printf_program_ident(f, program_name, revision_number);
+ fputs(": ", f);
+ }
}
void
lprintf_file_and_line(FILE * f, const char *file, int line)
@@ -129,7 +148,7 @@ gs_return_check_interrupt(int code)
/* ------ Substitutes for missing C library functions ------ */
-#ifdef memory__need_memmove /* see memory_.h */
+#ifdef MEMORY__NEED_MEMMOVE /* see memory_.h */
/* Copy bytes like memcpy, guaranteed to handle overlap correctly. */
/* ANSI C defines the returned value as being the src argument, */
/* but with the const restriction removed! */
@@ -142,10 +161,11 @@ gs_memmove(void *dest, const void *src, size_t len)
#define bsrc ((const byte *)src)
/* We use len-1 for comparisons because adding len */
/* might produce an offset overflow on segmented systems. */
- if (ptr_le(bdest, bsrc)) {
+ if (PTR_LE(bdest, bsrc)) {
register byte *end = bdest + (len - 1);
- if (ptr_le(bsrc, end)) { /* Source overlaps destination from above. */
+ if (PTR_LE(bsrc, end)) {
+ /* Source overlaps destination from above. */
register const byte *from = bsrc;
register byte *to = bdest;
@@ -160,7 +180,8 @@ gs_memmove(void *dest, const void *src, size_t len)
} else {
register const byte *from = bsrc + (len - 1);
- if (ptr_le(bdest, from)) { /* Source overlaps destination from below. */
+ if (PTR_LE(bdest, from)) {
+ /* Source overlaps destination from below. */
register const byte *end = bsrc;
register byte *to = bdest + (len - 1);
@@ -181,11 +202,37 @@ gs_memmove(void *dest, const void *src, size_t len)
}
#endif
-#ifdef memory__need_memchr /* see memory_.h */
+#ifdef MEMORY__NEED_MEMCPY /* see memory_.h */
+void *
+gs_memcpy(void *dest, const void *src, size_t len)
+{
+ if (len > 0) {
+#define bdest ((byte *)dest)
+#define bsrc ((const byte *)src)
+ /* We can optimize this much better later on. */
+ register byte *end = bdest + (len - 1);
+ register const byte *from = bsrc;
+ register byte *to = bdest;
+
+ for (;;) {
+ *to = *from;
+ if (to >= end) /* faster than = */
+ break;
+ to++;
+ from++;
+ }
+ }
+#undef bdest
+#undef bsrc
+ return (void *)src;
+}
+#endif
+
+#ifdef MEMORY__NEED_MEMCHR /* see memory_.h */
/* ch should obviously be char rather than int, */
/* but the ANSI standard declaration uses int. */
-const char *
-gs_memchr(const char *ptr, int ch, size_t len)
+void *
+gs_memchr(const void *ptr, int ch, size_t len)
{
if (len > 0) {
register const char *p = ptr;
@@ -193,7 +240,7 @@ gs_memchr(const char *ptr, int ch, size_t len)
do {
if (*p == (char)ch)
- return p;
+ return (void *)p;
p++;
} while (--count);
}
@@ -201,22 +248,46 @@ gs_memchr(const char *ptr, int ch, size_t len)
}
#endif
-#ifdef memory__need_memset /* see memory_.h */
+#ifdef MEMORY__NEED_MEMSET /* see memory_.h */
/* ch should obviously be char rather than int, */
/* but the ANSI standard declaration uses int. */
void *
gs_memset(void *dest, register int ch, size_t len)
{
- if (ch == 0)
- bzero(dest, len);
- else if (len > 0) {
- register char *p = dest;
- register uint count = len;
-
- do {
- *p++ = (char)ch;
- } while (--count);
+ /*
+ * This procedure is used a lot to fill large regions of images,
+ * so we take some trouble to optimize it.
+ */
+ register char *p = dest;
+ register size_t count = len;
+
+ ch &= 255;
+ if (len >= sizeof(long) * 3) {
+ long wd = (ch << 24) | (ch << 16) | (ch << 8) | ch;
+
+ while (ALIGNMENT_MOD(p, sizeof(long)))
+ *p++ = (char)ch, --count;
+ for (; count >= sizeof(long) * 4;
+ p += sizeof(long) * 4, count -= sizeof(long) * 4
+ )
+ ((long *)p)[3] = ((long *)p)[2] = ((long *)p)[1] =
+ ((long *)p)[0] = wd;
+ switch (count >> ARCH_LOG2_SIZEOF_LONG) {
+ case 3:
+ ((long *)p)[2] = wd; p += sizeof(long);
+ case 2:
+ ((long *)p)[1] = wd; p += sizeof(long);
+ case 1:
+ ((long *)p)[0] = wd; p += sizeof(long);
+ count &= sizeof(long) - 1;
+ case 0:
+ default: /* can't happen */
+ DO_NOTHING;
+ }
}
+ /* Do any leftover bytes. */
+ for (; count > 0; --count)
+ *p++ = (char)ch;
return dest;
}
#endif
@@ -287,6 +358,22 @@ debug_print_string(const byte * chrs, uint len)
fflush(dstderr);
}
+/*
+ * The following code prints a hex stack backtrace on Linux/Intel systems.
+ * It is here to be patched into places where we need to print such a trace
+ * because of gdb's inability to put breakpoints in dynamically created
+ * threads.
+ *
+ * first_arg is the first argument of the procedure into which this code
+ * is patched.
+ */
+#define BACKTRACE(first_arg)\
+ BEGIN\
+ ulong *fp_ = (ulong *)&first_arg - 2;\
+ for (; fp_ && (fp_[1] & 0xff000000) == 0x08000000; fp_ = (ulong *)*fp_)\
+ dprintf2(" fp=0x%lx ip=0x%lx\n", (ulong)fp_, fp_[1]);\
+ END
+
/* ------ Arithmetic ------ */
/* Compute M modulo N. Requires N > 0; guarantees 0 <= imod(M,N) < N, */
@@ -323,7 +410,45 @@ igcd(int x, int y)
return d + c; /* at most one is non-zero */
}
-#if defined(set_fmul2fixed_vars) && !USE_ASM
+/* Compute X such that A*X = B mod M. See gxarith.h for details. */
+int
+idivmod(int a, int b, int m)
+{
+ /*
+ * Use the approach indicated in Knuth vol. 2, section 4.5.2, Algorithm
+ * X (p. 302) and exercise 15 (p. 315, solution p. 523).
+ */
+ int u1 = 0, u3 = m;
+ int v1 = 1, v3 = a;
+ /*
+ * The following loop will terminate with a * u1 = gcd(a, m) mod m.
+ * Then x = u1 * b / gcd(a, m) mod m. Since we require that
+ * gcd(a, m) | gcd(a, b), it follows that gcd(a, m) | b, so the
+ * division is exact.
+ */
+ while (v3) {
+ int q = u3 / v3, t;
+
+ t = u1 - v1 * q, u1 = v1, v1 = t;
+ t = u3 - v3 * q, u3 = v3, v3 = t;
+ }
+ return imod(u1 * b / igcd(a, m), m);
+}
+
+/* Compute floor(log2(N)). Requires N > 0. */
+int
+ilog2(int n)
+{
+ int m = n, l = 0;
+
+ while (m >= 16)
+ m >>= 4, l += 4;
+ return
+ (m <= 1 ? 0 :
+ "\000\000\001\001\002\002\002\002\003\003\003\003\003\003\003\003"[m] + l);
+}
+
+#if defined(CHECK_FMUL2FIXED_VARS) && !USE_ASM
/*
* Floating multiply with fixed result, for avoiding floating point in
@@ -370,7 +495,7 @@ int
set_dfmul2fixed_(fixed * pr, ulong /*double lo */ xalo, long /*float */ b, long /*double hi */ xahi)
{
return set_fmul2fixed_(pr,
- (xahi & 0xc0000000) +
+ (xahi & (3L << 30)) +
((xahi << 3) & 0x3ffffff8) +
(xalo >> 29),
b);
@@ -483,36 +608,50 @@ set_fixed2double_(double *pd, fixed x, int frac_bits)
}
}
+#endif /* USE_FPU_FIXED */
+
/*
* Compute A * B / C when 0 <= B < C and A * B exceeds (or might exceed)
* the capacity of a long.
+ * Note that this procedure takes the floor, rather than truncating
+ * towards zero, if A < 0. This ensures that 0 <= R < C.
*/
+
+#define num_bits (sizeof(fixed) * 8)
+#define half_bits (num_bits / 2)
+#define half_mask ((1L << half_bits) - 1)
+
+/*
+ * If doubles aren't wide enough, we lose too much precision by using double
+ * arithmetic: we have to use the slower, accurate fixed-point algorithm.
+ */
+#if USE_FPU_FIXED || (arch_double_mantissa_bits < arch_sizeof_long * 12)
+
#ifdef DEBUG
struct {
long mnanb, mnab, manb, mab, mnc, mdq, mde, mds, mqh, mql;
} fmq_stat;
-
# define mincr(x) ++fmq_stat.x
#else
# define mincr(x) DO_NOTHING
#endif
fixed
fixed_mult_quo(fixed signed_A, fixed B, fixed C)
-{ /* First compute A * B in double-fixed precision. */
+{
+ /* First compute A * B in double-fixed precision. */
ulong A = (signed_A < 0 ? -signed_A : signed_A);
long msw;
ulong lsw;
ulong p1;
-#define num_bits (sizeof(fixed) * 8)
-#define half_bits (num_bits / 2)
-#define half_mask ((1L << half_bits) - 1)
if (B <= half_mask) {
if (A <= half_mask) {
- fixed Q = (ulong) (A * B) / (ulong) C;
+ ulong P = A * B;
+ fixed Q = P / (ulong)C;
mincr(mnanb);
- return (signed_A < 0 ? -Q : Q);
+ /* If A < 0 and the division isn't exact, take the floor. */
+ return (signed_A >= 0 ? Q : Q * C == P ? -Q : ~Q /* -Q - 1 */);
}
/*
* We might still have C <= half_mask, which we can
@@ -521,12 +660,14 @@ fixed_mult_quo(fixed signed_A, fixed B, fixed C)
lsw = (A & half_mask) * B;
p1 = (A >> half_bits) * B;
if (C <= half_mask) {
- ulong q0 = (p1 += lsw >> half_bits) / C;
+ fixed q0 = (p1 += lsw >> half_bits) / C;
ulong rem = ((p1 - C * q0) << half_bits) + (lsw & half_mask);
- ulong Q = (q0 << half_bits) + rem / C;
+ ulong q1 = rem / (ulong)C;
+ fixed Q = (q0 << half_bits) + q1;
mincr(mnc);
- return (signed_A < 0 ? -Q : Q);
+ /* If A < 0 and the division isn't exact, take the floor. */
+ return (signed_A >= 0 ? Q : q1 * C == rem ? -Q : ~Q);
}
msw = p1 >> half_bits;
mincr(manb);
@@ -634,16 +775,48 @@ fixed_mult_quo(fixed signed_A, fixed B, fixed C)
mincr(mql);
}
Q = (hi_Q << half_bits) + lo_Q;
- return (signed_A < 0 ? -Q : Q);
+ return (signed_A >= 0 ? Q : p0 | p1 ? ~Q /* -Q - 1 */ : -Q);
}
}
}
-#undef half_bits
-#undef half_mask
+}
+
+#else /* can approximate using doubles */
+
+/*
+ * Compute A * B / C as above. Since a double doesn't have enough bits to
+ * represent the product of two longs, we have to do it in two steps.
+ */
+fixed
+fixed_mult_quo(fixed signed_A, fixed B, fixed C)
+{
+#define MAX_OTHER_FACTOR\
+ (1L << (arch_double_mantissa_bits - sizeof(fixed) * 8))
+ if (B < MAX_OTHER_FACTOR || any_abs(signed_A) < MAX_OTHER_FACTOR) {
+ /* The double computation will be exact. */
+ return (fixed)floor((double)signed_A * B / C);
+ }
+#undef MAX_OTHER_FACTOR
+ {
+ /* Use 2 double steps. */
+ fixed bhi = B >> half_bits;
+ fixed qhi = (fixed)floor((double)signed_A * bhi / C);
+ fixed rhi = signed_A * bhi - qhi * C;
+ fixed blo = B & half_mask;
+ fixed qlo =
+ (fixed)floor(((double)rhi * (1L << half_bits) +
+ (double)signed_A * blo) / C);
+
+ return (qhi << half_bits) + qlo;
+ }
}
#endif
+#undef num_bits
+#undef half_bits
+#undef half_mask
+
/* Trace calls on sqrt when debugging. */
#undef sqrt
extern double sqrt(P1(double));
diff --git a/gs/src/gsnogc.c b/gs/src/gsnogc.c
index 7ff6b4ddd..13028048e 100644
--- a/gs/src/gsnogc.c
+++ b/gs/src/gsnogc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,8 +19,8 @@
/* String freelist implementation and ersatz garbage collector */
#include "gx.h"
-#include "gsgc.h"
#include "gsmdebug.h"
+#include "gsnogc.h"
#include "gsstruct.h"
#include "gxalloc.h"
@@ -29,8 +29,26 @@
* in non-garbage-collected environments.
*/
-#define GET2(ptr) (((ptr)[0] << 8) + (ptr)[1])
-#define PUT2(ptr, val) ((ptr)[0] = (val) >> 8, (ptr)[1] = (byte)(val))
+/*
+ * Get and put unaligned 32-bit values. NOTE: these procedures must match
+ * the value of SFREE_NB defined in gxalloc.h.
+ */
+#define NB SFREE_NB
+#if NB == 4
+private uint
+get_uu32(const byte *ptr)
+{
+ return (ptr[0] << 24) + (ptr[1] << 16) + (ptr[2] << 8) + ptr[3];
+}
+private void
+put_uu32(byte *ptr, uint val)
+{
+ ptr[0] = val >> 24;
+ ptr[1] = (byte)(val >> 16);
+ ptr[2] = (byte)(val >> 8);
+ ptr[3] = (byte)val;
+}
+#endif /* otherwise, undefined procedures will give an error */
/* Allocate a string. */
/* Scan the current chunk's free list if the request is large enough. */
@@ -49,14 +67,14 @@ sf_alloc_string(gs_memory_t * mem, uint nbytes, client_name_t cname)
for (; offset != 0; prev = ptr, offset = next) {
ptr = base + offset;
- next = GET2(ptr + 2);
- if (GET2(ptr) != nbytes)
+ next = get_uu32(ptr + NB);
+ if (get_uu32(ptr) != nbytes)
continue;
/* Take this block. */
if (prev == 0)
imem->cc.sfree = next;
else
- PUT2(prev + 2, next);
+ put_uu32(prev + NB, next);
if_debug4('A', "[a%d:+>F]%s(%u) = 0x%lx\n", imem->space,
client_name_string(cname), nbytes, (ulong) ptr);
gs_alloc_fill(ptr, gs_alloc_fill_alloc, nbytes);
@@ -102,14 +120,14 @@ sf_free_string(gs_memory_t * mem, byte * str, uint size, client_name_t cname)
}
}
str_offset = str - csbase(cp);
- if (size >= 4) {
+ if (size >= 2 * NB) {
byte *prev;
uint next;
- PUT2(str, size);
+ put_uu32(str, size);
if (cp->sfree == 0 || str_offset < cp->sfree) {
/* Put the string at the head of the free list. */
- PUT2(str + 2, cp->sfree);
+ put_uu32(str + NB, cp->sfree);
cp->sfree = str_offset;
return;
}
@@ -117,22 +135,22 @@ sf_free_string(gs_memory_t * mem, byte * str, uint size, client_name_t cname)
prev = csbase(cp) + cp->sfree;
#ifdef DEBUG
if (gs_debug_c('?')) {
- if (prev < str + size && prev + GET2(prev) > str) {
+ if (prev < str + size && prev + get_uu32(prev) > str) {
lprintf4("freeing string 0x%lx(%u), overlaps 0x%lx(%u)!\n",
- (ulong) str, size, (ulong) prev, GET2(prev));
+ (ulong) str, size, (ulong) prev, get_uu32(prev));
return;
}
}
#endif
for (;;) {
- next = GET2(prev + 2);
+ next = get_uu32(prev + NB);
#ifdef DEBUG
if (gs_debug_c('?') && next != 0) {
byte *pnext = csbase(cp) + next;
- if (pnext < str + size && pnext + GET2(pnext) > str) {
+ if (pnext < str + size && pnext + get_uu32(pnext) > str) {
lprintf4("freeing string 0x%lx(%u), overlaps 0x%lx(%u)!\n",
- (ulong) str, size, (ulong) pnext, GET2(pnext));
+ (ulong) str, size, (ulong) pnext, get_uu32(pnext));
return;
}
}
@@ -141,15 +159,15 @@ sf_free_string(gs_memory_t * mem, byte * str, uint size, client_name_t cname)
break;
prev = csbase(cp) + next;
}
- PUT2(str + 2, next);
- PUT2(prev + 2, str_offset);
- gs_alloc_fill(str + 4, gs_alloc_fill_free, size - 4);
+ put_uu32(str + NB, next);
+ put_uu32(prev + NB, str_offset);
+ gs_alloc_fill(str + 2 * NB, gs_alloc_fill_free, size - 2 * NB);
} else {
/*
* Insert the string in the 1-byte free list(s). Note that
* if it straddles a 256-byte block, we need to do this twice.
*/
- ushort *pfree1 = &cp->sfree1[str_offset >> 8];
+ uint *pfree1 = &cp->sfree1[str_offset >> 8];
uint count = size;
byte *prev;
byte *ptr = str;
@@ -210,11 +228,11 @@ sf_merge_strings(chunk_t * cp)
for (;;) {
byte *ctop = cp->ctop;
uint top_offset = ctop - csbase(cp);
- ushort *pfree1;
+ uint *pfree1;
if (cp->sfree == top_offset) { /* Merge a large free block. */
- cp->sfree = GET2(ctop + 2);
- cp->ctop += GET2(ctop);
+ cp->sfree = get_uu32(ctop + NB);
+ cp->ctop += get_uu32(ctop);
continue;
}
if (!cp->sfree1)
@@ -235,12 +253,35 @@ sf_consolidate_free(gs_memory_t *mem)
gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
chunk_t *cp;
+ alloc_close_chunk(imem);
for (cp = imem->clast; cp != 0; cp = cp->cprev) {
byte *top = cp->ctop;
sf_merge_strings(cp);
imem->lost.strings -= cp->ctop - top;
+ if (cp->ctop == cp->climit && cp->smark_size != 0) {
+ /*
+ * No string space is being used. Since we are not using the
+ * 'string marking table' for GC, we can recover its space by
+ * deleting the smark area, setting smark_size = 0, and sliding
+ * up ctop and climit. We also need to recompute the size of
+ * the string freelist area (it will be larger, since the
+ * space potentially allocated to strings is larger).
+ */
+ cp->smark_size = 0;
+ cp->smark = 0;
+ /*
+ * Reserve enough space for the string freelist all the way to
+ * cend even though the climit will be moved to before the
+ * freelist area. This recovers most of the space.
+ */
+ cp->climit = cp->cend;
+ cp->climit -= STRING_FREELIST_SPACE(cp);
+ cp->ctop = cp->climit;
+ alloc_init_free_strings(cp);
+ }
}
+ alloc_open_chunk(imem);
/* Merge free objects, detecting entirely free chunks. */
ialloc_consolidate_free(imem);
@@ -251,18 +292,21 @@ sf_consolidate_free(gs_memory_t *mem)
* PostScript interpreter, but it is designed to be used in environments
* that don't need garbage collection and don't use save/restore. All it
* does is coalesce free blocks at the high end of the object area of each
- * chunk, and free strings at the low end of the string area, and then free
- * completely empty chunks.
+ * chunk, and free strings at the low end of the string area, and then if
+ * not 'controlled' memory, free completely empty chunks.
+ *
+ * Note that any string marking area will be added to the free space
+ * within the chunk if possible.
*/
void
-gs_reclaim(vm_spaces * pspaces, bool global)
+gs_nogc_reclaim(vm_spaces * pspaces, bool global)
{
int space;
gs_ref_memory_t *mem_prev = 0;
- for (space = 0; space < countof(pspaces->indexed); ++space) {
- gs_ref_memory_t *mem = pspaces->indexed[space];
+ for (space = 0; space < countof(pspaces->memories.indexed); ++space) {
+ gs_ref_memory_t *mem = pspaces->memories.indexed[space];
if (mem == 0 || mem == mem_prev)
continue;
diff --git a/gs/src/gsnogc.h b/gs/src/gsnogc.h
new file mode 100644
index 000000000..38d015ab4
--- /dev/null
+++ b/gs/src/gsnogc.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface to non-tracing GC */
+
+#ifndef gsnogc_INCLUDED
+# define gsnogc_INCLUDED
+
+#include "gsgc.h" /* for vm_reclaim_proc */
+
+/* Declare the vm_reclaim procedure for the non-tracing GC. */
+extern vm_reclaim_proc(gs_nogc_reclaim);
+
+#endif /* gsnogc_INCLUDED */
diff --git a/gs/src/gspaint.c b/gs/src/gspaint.c
index 3ad13abeb..94ae2c098 100644
--- a/gs/src/gspaint.c
+++ b/gs/src/gspaint.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,7 +32,7 @@
#include "gzstate.h"
#include "gxdevice.h"
#include "gxdevmem.h"
-#include "gxcpath.h"
+#include "gzcpath.h"
/* Define the nominal size for alpha buffers. */
#define abuf_nominal_SMALL 500
@@ -102,7 +102,8 @@ alpha_buffer_bits(gs_state * pgs)
/* We're already writing into an alpha buffer. */
return 0;
}
- return (*dev_proc(dev, get_alpha_bits)) (dev, go_graphics);
+ return (*dev_proc(dev, get_alpha_bits))
+ (dev, (pgs->in_cachedevice ? go_text : go_graphics));
}
/*
* Set up an alpha buffer for a stroke or fill operation. Return 0
@@ -118,16 +119,53 @@ alpha_buffer_bits(gs_state * pgs)
private int
scale_paths(gs_state * pgs, int log2_scale_x, int log2_scale_y, bool do_path)
{
- if (do_path)
- gx_path_scale_exp2(pgs->path, log2_scale_x, log2_scale_y);
- gx_cpath_scale_exp2(pgs->clip_path, log2_scale_x, log2_scale_y);
- if (pgs->view_clip != 0)
- gx_cpath_scale_exp2(pgs->view_clip, log2_scale_x, log2_scale_y);
+ /*
+ * Because of clip and clippath, any of path, clip_path, and view_clip
+ * may be aliases for each other. The only reliable way to detect
+ * this is by comparing the segments pointers. Note that we must
+ * scale the non-segment parts of the paths even if the segments are
+ * aliased.
+ */
+ const gx_path_segments *seg_clip =
+ (pgs->clip_path->path_valid ? pgs->clip_path->path.segments : 0);
+ const gx_clip_rect_list *list_clip = pgs->clip_path->rect_list;
+ const gx_path_segments *seg_view_clip;
+ const gx_clip_rect_list *list_view_clip;
+ const gx_path_segments *seg_effective_clip =
+ (pgs->effective_clip_path->path_valid ?
+ pgs->effective_clip_path->path.segments : 0);
+ const gx_clip_rect_list *list_effective_clip =
+ pgs->effective_clip_path->rect_list;
+
+ gx_cpath_scale_exp2_shared(pgs->clip_path, log2_scale_x, log2_scale_y,
+ false, false);
+ if (pgs->view_clip != 0 && pgs->view_clip != pgs->clip_path) {
+ seg_view_clip =
+ (pgs->view_clip->path_valid ? pgs->view_clip->path.segments : 0);
+ list_view_clip = pgs->view_clip->rect_list;
+ gx_cpath_scale_exp2_shared(pgs->view_clip, log2_scale_x, log2_scale_y,
+ list_view_clip == list_clip,
+ seg_view_clip && seg_view_clip == seg_clip);
+ } else
+ seg_view_clip = 0, list_view_clip = 0;
if (pgs->effective_clip_path != pgs->clip_path &&
pgs->effective_clip_path != pgs->view_clip
)
- gx_cpath_scale_exp2(pgs->effective_clip_path,
- log2_scale_x, log2_scale_y);
+ gx_cpath_scale_exp2_shared(pgs->effective_clip_path, log2_scale_x,
+ log2_scale_y,
+ list_effective_clip == list_clip ||
+ list_effective_clip == list_view_clip,
+ seg_effective_clip &&
+ (seg_effective_clip == seg_clip ||
+ seg_effective_clip == seg_view_clip));
+ if (do_path) {
+ const gx_path_segments *seg_path = pgs->path->segments;
+
+ gx_path_scale_exp2_shared(pgs->path, log2_scale_x, log2_scale_y,
+ seg_path == seg_clip ||
+ seg_path == seg_view_clip ||
+ seg_path == seg_effective_clip);
+ }
return 0;
}
private void
@@ -147,7 +185,7 @@ private int
alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits)
{
gx_device *dev = gs_currentdevice_inline(pgs);
- int log2_alpha_bits;
+ int log2_alpha_bits = ilog2(alpha_bits);
gs_fixed_rect bbox;
gs_int_rect ibox;
uint width, raster, band_space;
@@ -156,7 +194,6 @@ alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits)
gs_memory_t *mem;
gx_device_memory *mdev;
- log2_alpha_bits = alpha_bits >> 1; /* works for 1,2,4 */
log2_scale.x = log2_scale.y = log2_alpha_bits;
gx_path_bbox(pgs->path, &bbox);
ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1;
diff --git a/gs/src/gsparam.h b/gs/src/gsparam.h
index aac5cb903..2ac968256 100644
--- a/gs/src/gsparam.h
+++ b/gs/src/gsparam.h
@@ -35,7 +35,6 @@
#ifndef gs_param_list_DEFINED
# define gs_param_list_DEFINED
typedef struct gs_param_list_s gs_param_list;
-
#endif
/* Define the type for a parameter key name. */
@@ -457,9 +456,7 @@ param_proc_requested(gs_param_requested_default); /* always returns true */
* Define a default implementation, intended to be usable easily
* from C code. The intended usage pattern is:
gs_c_param_list list;
-
[... other code here ...]
-
gs_c_param_list_write(&list, mem);
[As many as needed:]
code = param_write_XXX(&list, "ParamName", &param_value);
@@ -473,11 +470,12 @@ param_proc_requested(gs_param_requested_default); /* always returns true */
code = (*dev_proc(dev, open_device))(dev);
[Check code for <0]
}
- *
- * The default implementation also has the special property that it can
- * forward unrecognized param_read_ calls to another parameter list,
- * called the target. This allows constructing incrementally modified
- * parameter lists.
+ *
+ * The default implementation also has the special property that it can
+ * forward unrecognized param_read_ calls to another parameter list,
+ * called the target. This allows constructing incrementally modified
+ * parameter lists. Note that this is only relevant for put_params
+ * (reading from the parameter list).
*/
typedef struct gs_c_param_s gs_c_param; /* opaque here */
@@ -496,7 +494,6 @@ typedef struct gs_c_param_list_s {
/* Set the target of a C parameter list. */
void gs_c_param_list_set_target(P2(gs_c_param_list *, gs_param_list *));
-
/* Clients normally allocate the gs_c_param_list on the stack. */
void gs_c_param_list_write(P2(gs_c_param_list *, gs_memory_t *));
void gs_c_param_list_read(P1(gs_c_param_list *)); /* switch to reading */
diff --git a/gs/src/gsparams.c b/gs/src/gsparams.c
index 6e40f06d6..80fdbd6ad 100644
--- a/gs/src/gsparams.c
+++ b/gs/src/gsparams.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,6 +20,8 @@
/* Generic parameter list serializer & expander */
/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
+/* 11/16/98 L. Peter Deutsch (ghost@aladdin.com) edited to remove names
+ put_bytes, put_word which conflicted with other modules */
#include "gx.h"
#include "memory_.h"
@@ -35,32 +37,32 @@ typedef struct {
/* ---------- Forward refs ----------- */
private void
- align_to(P2(
- const byte ** src, /* pointer to align */
- unsigned alignment /* alignment, must be power of 2 */
- ));
+ptr_align_to(P2(
+ const byte ** src, /* pointer to align */
+ unsigned alignment /* alignment, must be power of 2 */
+ ));
private void
- put_word(P2(
- unsigned source, /* number to put to buffer */
- WriteBuffer * dest /* destination descriptor */
- ));
+wb_put_word(P2(
+ unsigned source, /* number to put to buffer */
+ WriteBuffer * dest /* destination descriptor */
+ ));
private void
- put_bytes(P3(
- const byte * source, /* bytes to put to buffer */
- unsigned source_sizeof, /* # bytes to put */
- WriteBuffer * dest /* destination descriptor */
- ));
+wb_put_bytes(P3(
+ const byte * source, /* bytes to put to buffer */
+ unsigned source_sizeof, /* # bytes to put */
+ WriteBuffer * dest /* destination descriptor */
+ ));
private void
- put_alignment(P2(
- unsigned alignment, /* alignment to match, must be power 2 */
- WriteBuffer * dest /* destination descriptor */
- ));
+wb_put_alignment(P2(
+ unsigned alignment, /* alignment to match, must be power 2 */
+ WriteBuffer * dest /* destination descriptor */
+ ));
-/* Get word compressed with put_word */
+/* Get word compressed with wb_put_word */
private unsigned /* decompressed word */
- get_word(P1(
- const byte ** src /* UPDATES: ptr to src buf ptr */
- ));
+buf_get_word(P1(
+ const byte ** src /* UPDATES: ptr to src buf ptr */
+ ));
/* ------------ Serializer ------------ */
@@ -131,9 +133,9 @@ gs_param_list_serialize(
code = code > 0 ? gs_note_error(gs_error_unknownerror) : code;
break;
}
- put_word((unsigned)key.size + 1, &write_buf);
- put_word((unsigned)value.type, &write_buf);
- put_bytes((byte *) string_key, key.size + 1, &write_buf);
+ wb_put_word((unsigned)key.size + 1, &write_buf);
+ wb_put_word((unsigned)value.type, &write_buf);
+ wb_put_bytes((byte *) string_key, key.size + 1, &write_buf);
/* Put value & its size to buffer */
value_top_sizeof = gs_param_type_sizes[value.type];
@@ -144,26 +146,26 @@ gs_param_list_serialize(
case gs_param_type_int:
case gs_param_type_long:
case gs_param_type_float:
- put_bytes((byte *) & value.value, value_top_sizeof, &write_buf);
+ wb_put_bytes((byte *) & value.value, value_top_sizeof, &write_buf);
break;
case gs_param_type_string:
case gs_param_type_name:
case gs_param_type_int_array:
case gs_param_type_float_array:
- put_bytes((byte *) & value.value, value_top_sizeof, &write_buf);
- put_alignment(value_base_sizeof, &write_buf);
+ wb_put_bytes((byte *) & value.value, value_top_sizeof, &write_buf);
+ wb_put_alignment(value_base_sizeof, &write_buf);
value_base_sizeof *= value.value.s.size;
- put_bytes(value.value.s.data, value_base_sizeof, &write_buf);
+ wb_put_bytes(value.value.s.data, value_base_sizeof, &write_buf);
break;
case gs_param_type_string_array:
case gs_param_type_name_array:
value_base_sizeof *= value.value.sa.size;
- put_bytes((const byte *)&value.value, value_top_sizeof, &write_buf);
- put_alignment(sizeof(void *), &write_buf);
+ wb_put_bytes((const byte *)&value.value, value_top_sizeof, &write_buf);
+ wb_put_alignment(sizeof(void *), &write_buf);
- put_bytes((const byte *)value.value.sa.data, value_base_sizeof,
+ wb_put_bytes((const byte *)value.value.sa.data, value_base_sizeof,
&write_buf);
{
int str_count;
@@ -171,14 +173,14 @@ gs_param_list_serialize(
for (str_count = value.value.sa.size,
sa = value.value.sa.data; str_count-- > 0; ++sa)
- put_bytes(sa->data, sa->size, &write_buf);
+ wb_put_bytes(sa->data, sa->size, &write_buf);
}
break;
case gs_param_type_dict:
case gs_param_type_dict_int_keys:
- put_word(value.value.d.size, &write_buf);
- put_alignment(sizeof(void *), &write_buf);
+ wb_put_word(value.value.d.size, &write_buf);
+ wb_put_alignment(sizeof(void *), &write_buf);
{
int bytes_written =
@@ -194,7 +196,7 @@ gs_param_list_serialize(
else {
code = temp_code;
if (bytes_written)
- put_bytes(write_buf.buf, bytes_written, &write_buf);
+ wb_put_bytes(write_buf.buf, bytes_written, &write_buf);
}
}
break;
@@ -209,7 +211,7 @@ gs_param_list_serialize(
/* Write end marker, which is an (illegal) 0 key length */
if (code >= 0) {
- put_word(0, &write_buf);
+ wb_put_word(0, &write_buf);
code = write_buf.total_sizeof;
}
return code;
@@ -238,12 +240,12 @@ gs_param_list_unserialize(
gs_param_type type;
/* key length, 0 indicates end of data */
- key_sizeof = get_word(&buf);
+ key_sizeof = buf_get_word(&buf);
if (key_sizeof == 0) /* end of data */
break;
/* data type */
- type = (gs_param_type) get_word(&buf);
+ type = (gs_param_type) buf_get_word(&buf);
/* key */
key = (gs_param_name) buf;
@@ -269,7 +271,7 @@ gs_param_list_unserialize(
case gs_param_type_name:
case gs_param_type_int_array:
case gs_param_type_float_array:
- align_to(&buf, value_base_sizeof);
+ ptr_align_to(&buf, value_base_sizeof);
typed.value.s.data = buf;
typed.value.s.persistent = false;
buf += typed.value.s.size * value_base_sizeof;
@@ -277,7 +279,7 @@ gs_param_list_unserialize(
case gs_param_type_string_array:
case gs_param_type_name_array:
- align_to(&buf, sizeof(void *));
+ ptr_align_to(&buf, sizeof(void *));
typed.value.sa.data = (const gs_param_string *)buf;
typed.value.sa.persistent = false;
@@ -298,12 +300,12 @@ gs_param_list_unserialize(
case gs_param_type_dict:
case gs_param_type_dict_int_keys:
- typed.value.d.size = get_word(&buf);
+ typed.value.d.size = buf_get_word(&buf);
code = param_begin_write_dict
(list, key, &typed.value.d, type == gs_param_type_dict_int_keys);
if (code < 0)
break;
- align_to(&buf, sizeof(void *));
+ ptr_align_to(&buf, sizeof(void *));
code = gs_param_list_unserialize(typed.value.d.list, buf);
temp_code = param_end_write_dict(list, key, &typed.value.d);
@@ -332,17 +334,17 @@ gs_param_list_unserialize(
/* Align a byte pointer on the next Nth byte */
private void
-align_to(
+ptr_align_to(
const byte ** src, /* pointer to align */
unsigned alignment /* alignment, must be power of 2 */
)
{
- *src += -(int)alignment_mod(*src, alignment) & (alignment - 1);
+ *src += -(int)ALIGNMENT_MOD(*src, alignment) & (alignment - 1);
}
/* Put compressed word repr to a buffer */
private void
-put_word(
+wb_put_word(
unsigned source, /* number to put to buffer */
WriteBuffer * dest /* destination descriptor */
)
@@ -362,7 +364,7 @@ put_word(
/* Put array of bytes to buffer */
private void
-put_bytes(
+wb_put_bytes(
const byte * source, /* bytes to put to buffer */
unsigned source_sizeof, /* # bytes to put */
WriteBuffer * dest /* destination descriptor */
@@ -378,7 +380,7 @@ put_bytes(
/* Pad destination out to req'd alignment w/zeros */
private void
-put_alignment(
+wb_put_alignment(
unsigned alignment, /* alignment to match, must be power 2 */
WriteBuffer * dest /* destination descriptor */
)
@@ -387,12 +389,12 @@ put_alignment(
{0};
while ((dest->total_sizeof & (alignment - 1)) != 0)
- put_bytes(&zero, 1, dest);
+ wb_put_bytes(&zero, 1, dest);
}
-/* Get word compressed with put_word */
+/* Get word compressed with wb_put_word */
private unsigned /* decompressed word */
-get_word(
+buf_get_word(
const byte ** src /* UPDATES: ptr to src buf ptr */
)
{
diff --git a/gs/src/gsparamx.c b/gs/src/gsparamx.c
new file mode 100644
index 000000000..97afd0933
--- /dev/null
+++ b/gs/src/gsparamx.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Extended parameter dictionary utilities */
+#include "string_.h"
+#include "gserror.h"
+#include "gserrors.h"
+#include "gstypes.h"
+#include "gsmemory.h"
+#include "gsparam.h"
+#include "gsparamx.h"
+
+/* Compare a C string and a gs_param_string. */
+bool
+gs_param_string_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. */
+int
+param_put_enum(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 (gs_param_string_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 value. */
+int
+param_put_bool(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;
+}
+
+/* Put an integer value. */
+int
+param_put_int(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;
+}
diff --git a/gs/src/gsparamx.h b/gs/src/gsparamx.h
new file mode 100644
index 000000000..89ea85a15
--- /dev/null
+++ b/gs/src/gsparamx.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface to extended parameter dictionary utilities */
+
+#ifndef gsparamx_INCLUDED
+# define gsparamx_INCLUDED
+
+/* Test whether a parameter's string value is equal to a C string. */
+bool gs_param_string_eq(P2(const gs_param_string *pcs, const char *str));
+
+/*
+ * Put parameters of various types. These propagate ecode, presumably
+ * the previous accumulated error code.
+ */
+int param_put_enum(P5(gs_param_list * plist, gs_param_name param_name,
+ int *pvalue, const char *const pnames[], int ecode));
+int param_put_bool(P4(gs_param_list * plist, gs_param_name param_name,
+ bool * pval, int ecode));
+int param_put_int(P4(gs_param_list * plist, gs_param_name param_name,
+ int * pval, int ecode));
+
+#endif /* gsparamx_INCLUDED */
diff --git a/gs/src/gspath.c b/gs/src/gspath.c
index a208f7030..c2051f8b2 100644
--- a/gs/src/gspath.c
+++ b/gs/src/gspath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -86,21 +86,19 @@ clamp_point(gs_fixed_point * ppt, floatp x, floatp y)
}
int
-gs_currentpoint(const gs_state * pgs, gs_point * ppt)
+gs_currentpoint(gs_state * pgs, gs_point * ppt)
{
gx_path *ppath = pgs->path;
int code;
gs_fixed_point pt;
if (path_outside_range(ppath))
- return gs_itransform((gs_state *) pgs,
- ppath->outside_position.x,
+ return gs_itransform(pgs, ppath->outside_position.x,
ppath->outside_position.y, ppt);
code = gx_path_current_point(pgs->path, &pt);
if (code < 0)
return code;
- return gs_itransform((gs_state *) pgs,
- fixed2float(pt.x), fixed2float(pt.y), ppt);
+ return gs_itransform(pgs, fixed2float(pt.x), fixed2float(pt.y), ppt);
}
int
@@ -426,18 +424,6 @@ common_clip(gs_state * pgs, int rule)
return 0;
}
-int
-gs_setclipoutside(gs_state * pgs, bool outside)
-{
- return gx_cpath_set_outside(pgs->clip_path, outside);
-}
-
-bool
-gs_currentclipoutside(const gs_state * pgs)
-{
- return gx_cpath_is_outside(pgs->clip_path);
-}
-
/* Establish a rectangle as the clipping path. */
/* Used by initclip and by the character and Pattern cache logic. */
int
diff --git a/gs/src/gspath.h b/gs/src/gspath.h
index cdd1e6423..0e0e453b0 100644
--- a/gs/src/gspath.h
+++ b/gs/src/gspath.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -62,8 +62,11 @@ int gs_imager_arc_add(P9(gx_path * ppath, gs_imager_state * pis,
int gs_upmergepath(P1(gs_state *));
/* Path accessors and transformers */
-int gs_currentpoint(P2(const gs_state *, gs_point *)), gs_upathbbox(P3(gs_state *, gs_rect *, bool)),
- gs_dashpath(P1(gs_state *)), gs_flattenpath(P1(gs_state *)), gs_reversepath(P1(gs_state *)),
+int gs_currentpoint(P2(gs_state *, gs_point *)),
+ gs_upathbbox(P3(gs_state *, gs_rect *, bool)),
+ gs_dashpath(P1(gs_state *)),
+ gs_flattenpath(P1(gs_state *)),
+ gs_reversepath(P1(gs_state *)),
gs_strokepath(P1(gs_state *));
/* The extra argument for gs_upathbbox controls whether to include */
@@ -84,9 +87,9 @@ int gs_path_enum_next(P2(gs_path_enum *, gs_point[3])); /* 0 when done */
void gs_path_enum_cleanup(P1(gs_path_enum *));
/* Clipping */
-int gs_clippath(P1(gs_state *)), gs_initclip(P1(gs_state *)), gs_clip(P1(gs_state *)),
+int gs_clippath(P1(gs_state *)),
+ gs_initclip(P1(gs_state *)),
+ gs_clip(P1(gs_state *)),
gs_eoclip(P1(gs_state *));
-int gs_setclipoutside(P2(gs_state *, bool));
-bool gs_currentclipoutside(P1(const gs_state *));
#endif /* gspath_INCLUDED */
diff --git a/gs/src/gspath1.c b/gs/src/gspath1.c
index a23929d83..1d7fb3baf 100644
--- a/gs/src/gspath1.c
+++ b/gs/src/gspath1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -53,10 +53,15 @@ typedef struct arc_curve_params_s {
gs_point p0, p3, pt;
gs_sincos_t sincos; /* (not used by arc_add) */
fixed angle; /* (not used by arc_add) */
+ int fast_quadrant; /* 0 = not calculated, -1 = not fast, */
+ /* 1 = fast (only used for quadrants) */
+ /* The following are set once iff fast_quadrant > 0. */
+ fixed scaled_radius; /* radius * CTM scale */
+ fixed quadrant_delta; /* scaled_radius * quarter_arc_fraction */
} arc_curve_params_t;
/* Forward declarations */
-private int arc_add(P1(const arc_curve_params_t *));
+private int arc_add(P2(const arc_curve_params_t *arc, bool is_quadrant));
int
gs_arc(gs_state * pgs,
@@ -84,34 +89,83 @@ gs_arc_add(gs_state * pgs, bool clockwise, floatp axc, floatp ayc,
private int
next_arc_curve(arc_curve_params_t * arc, fixed anext)
{
- bool ortho = arc->sincos.orthogonal;
- double sin0 = arc->sincos.sin, cos0 = arc->sincos.cos;
double x0 = arc->p0.x = arc->p3.x;
double y0 = arc->p0.y = arc->p3.y;
- double x3, y3;
-
- gs_sincos_degrees(fixed2float(anext), &arc->sincos);
- arc->p3.x = x3 =
- arc->center.x + arc->radius * arc->sincos.cos;
- arc->p3.y = y3 =
- arc->center.y + arc->radius * arc->sincos.sin;
- if (ortho && arc->sincos.orthogonal) {
- /* The common tangent point is easy to compute. */
- if (x0 == arc->center.x)
- arc->pt.x = x3, arc->pt.y = y0;
- else
- arc->pt.x = x0, arc->pt.y = y3;
- } else {
- /* Do it the hard way. */
- double trad = arc->radius *
+ double trad = arc->radius *
tan(fixed2float(anext - arc->angle) *
(degrees_to_radians / 2));
- arc->pt.x = x0 - trad * sin0;
- arc->pt.y = y0 + trad * cos0;
+ arc->pt.x = x0 - trad * arc->sincos.sin;
+ arc->pt.y = y0 + trad * arc->sincos.cos;
+ gs_sincos_degrees(fixed2float(anext), &arc->sincos);
+ arc->p3.x = arc->center.x + arc->radius * arc->sincos.cos;
+ arc->p3.y = arc->center.y + arc->radius * arc->sincos.sin;
+ arc->angle = anext;
+ return arc_add(arc, false);
+}
+/*
+ * Use this when both arc.angle and anext are multiples of 90 degrees,
+ * and anext = arc.angle +/- 90.
+ */
+private int
+next_arc_quadrant(arc_curve_params_t * arc, fixed anext)
+{
+ double x0 = arc->p0.x = arc->p3.x;
+ double y0 = arc->p0.y = arc->p3.y;
+
+ if (!arc->fast_quadrant) {
+ /*
+ * If the CTM is well-behaved, we can pre-calculate the delta
+ * from the arc points to the control points.
+ */
+ const gs_imager_state *pis = arc->pis;
+ double scale;
+
+ if (is_fzero2(pis->ctm.xy, pis->ctm.yx) ?
+ (scale = fabs(pis->ctm.xx)) == fabs(pis->ctm.yy) :
+ is_fzero2(pis->ctm.xx, pis->ctm.yy) ?
+ (scale = fabs(pis->ctm.xy)) == fabs(pis->ctm.yx) :
+ 0
+ ) {
+ double scaled_radius = arc->radius * scale;
+
+ arc->scaled_radius = float2fixed(scaled_radius);
+ arc->quadrant_delta =
+ float2fixed(scaled_radius * quarter_arc_fraction);
+ arc->fast_quadrant = 1;
+ } else {
+ arc->fast_quadrant = -1;
+ }
}
+ /*
+ * We know that anext is a multiple of 90 (as a fixed); we want
+ * (anext / 90) & 3. The following is much faster than a division.
+ */
+ switch ((fixed2int(anext) >> 1) & 3) {
+ case 0:
+ arc->sincos.sin = 0, arc->sincos.cos = 1;
+ arc->p3.x = x0 = arc->center.x + arc->radius;
+ arc->p3.y = arc->center.y;
+ break;
+ case 1:
+ arc->sincos.sin = 1, arc->sincos.cos = 0;
+ arc->p3.x = arc->center.x;
+ arc->p3.y = y0 = arc->center.y + arc->radius;
+ break;
+ case 2:
+ arc->sincos.sin = 0, arc->sincos.cos = -1;
+ arc->p3.x = x0 = arc->center.x - arc->radius;
+ arc->p3.y = arc->center.y;
+ break;
+ case 3:
+ arc->sincos.sin = -1, arc->sincos.cos = 0;
+ arc->p3.x = arc->center.x;
+ arc->p3.y = y0 = arc->center.y - arc->radius;
+ break;
+ }
+ arc->pt.x = x0, arc->pt.y = y0;
arc->angle = anext;
- return arc_add(arc);
+ return arc_add(arc, true);
}
int
@@ -140,6 +194,7 @@ gs_imager_arc_add(gx_path * ppath, gs_imager_state * pis, bool clockwise,
arc.radius = ar;
arc.action = (add_line ? arc_lineto : arc_moveto);
arc.notes = sn_none;
+ arc.fast_quadrant = 0;
ang1r = fixed2float(ang1 % fixed_360);
gs_sincos_degrees(ang1r, &arc.sincos);
arc.p3.x = axc + ar * arc.sincos.cos;
@@ -148,46 +203,69 @@ gs_imager_arc_add(gx_path * ppath, gs_imager_state * pis, bool clockwise,
while (ang1 < ang2)
ang2 -= fixed_360;
if (ang2 < 0) {
- fixed adjust = round_up(-ang2, fixed_360);
+ fixed adjust = ROUND_UP(-ang2, fixed_360);
ang1 += adjust, ang2 += adjust;
}
arc.angle = ang1;
- /*
- * Cut at multiples of 90 degrees. Invariant: ang1 >= ang2 >= 0.
- */
- while ((anext = round_down(arc.angle - fixed_epsilon, fixed_90)) > ang2) {
+ if (ang1 == ang2)
+ goto last;
+ /* Do the first part, up to a multiple of 90 degrees. */
+ if (!arc.sincos.orthogonal) {
+ anext = ROUND_DOWN(arc.angle - fixed_epsilon, fixed_90);
+ if (anext < ang2)
+ goto last;
code = next_arc_curve(&arc, anext);
if (code < 0)
return code;
arc.action = arc_nothing;
arc.notes = sn_not_first;
+ }
+ /* Do multiples of 90 degrees. Invariant: ang1 >= ang2 >= 0. */
+ while ((anext = arc.angle - fixed_90) >= ang2) {
+ code = next_arc_quadrant(&arc, anext);
+ if (code < 0)
+ return code;
+ arc.action = arc_nothing;
+ arc.notes = sn_not_first;
}
} else {
while (ang2 < ang1)
ang2 += fixed_360;
if (ang1 < 0) {
- fixed adjust = round_up(-ang1, fixed_360);
+ fixed adjust = ROUND_UP(-ang1, fixed_360);
ang1 += adjust, ang2 += adjust;
}
arc.angle = ang1;
- /*
- * Cut at multiples of 90 degrees. Invariant: 0 <= ang1 <= ang2.
- * We can't use round_up because of the inchoate definition of
- * % and / for negative numbers.
- */
- while ((anext = round_up(arc.angle + fixed_epsilon, fixed_90)) < ang2) {
+ if (ang1 == ang2)
+ return next_arc_curve(&arc, ang2);
+ /* Do the first part, up to a multiple of 90 degrees. */
+ if (!arc.sincos.orthogonal) {
+ anext = ROUND_UP(arc.angle + fixed_epsilon, fixed_90);
+ if (anext > ang2)
+ goto last;
code = next_arc_curve(&arc, anext);
if (code < 0)
return code;
arc.action = arc_nothing;
arc.notes = sn_not_first;
+ }
+ /* Do multiples of 90 degrees. Invariant: 0 <= ang1 <= ang2. */
+ while ((anext = arc.angle + fixed_90) <= ang2) {
+ code = next_arc_quadrant(&arc, anext);
+ if (code < 0)
+ return code;
+ arc.action = arc_nothing;
+ arc.notes = sn_not_first;
}
}
/*
- * Do the last curve of the arc.
+ * Do the last curve of the arc, if any.
*/
+ if (arc.angle == ang2)
+ return 0;
+last:
return next_arc_curve(&arc, ang2);
}
@@ -244,7 +322,7 @@ floatp ax1, floatp ay1, floatp ax2, floatp ay2, floatp arad, float retxy[4])
arc.p3.y = yt2 = ay1 + dy2 * l2;
arc.pt.x = ax1;
arc.pt.y = ay1;
- code = arc_add(&arc);
+ code = arc_add(&arc, false);
}
}
if (retxy != 0) {
@@ -258,45 +336,75 @@ floatp ax1, floatp ay1, floatp ax2, floatp ay2, floatp arad, float retxy[4])
/* Internal routine for adding an arc to the path. */
private int
-arc_add(const arc_curve_params_t * arc)
+arc_add(const arc_curve_params_t * arc, bool is_quadrant)
{
gx_path *path = arc->ppath;
gs_imager_state *pis = arc->pis;
- double r = arc->radius;
double x0 = arc->p0.x, y0 = arc->p0.y;
- double x3 = arc->p3.x, y3 = arc->p3.y;
double xt = arc->pt.x, yt = arc->pt.y;
- floatp dx = xt - x0, dy = yt - y0;
- double dist = dx * dx + dy * dy;
- double r2 = r * r;
floatp fraction;
- gs_fixed_point p0, p3, pt, cpt;
+ gs_fixed_point p0, p2, p3, pt;
int code;
- /* Compute the fraction coefficient for the curve. */
- /* See gx_path_add_partial_arc for details. */
- if (dist >= r2 * 1.0e8) /* almost zero radius; */
- /* the >= catches dist == r == 0 */
- fraction = 0.0;
- else
- fraction = (4.0 / 3.0) / (1 + sqrt(1 + dist / r2));
- if_debug8('r',
- "[r]Arc f=%f p0=(%f,%f) pt=(%f,%f) p3=(%f,%f) action=%d\n",
- fraction, x0, y0, xt, yt, x3, y3, (int)arc->action);
- if ((code = gs_point_transform2fixed(&pis->ctm, x0, y0, &p0)) < 0 ||
- (code = gs_point_transform2fixed(&pis->ctm, x3, y3, &p3)) < 0 ||
+ if ((arc->action != arc_nothing &&
+ (code = gs_point_transform2fixed(&pis->ctm, x0, y0, &p0)) < 0) ||
(code = gs_point_transform2fixed(&pis->ctm, xt, yt, &pt)) < 0 ||
+ (code = gs_point_transform2fixed(&pis->ctm, arc->p3.x, arc->p3.y, &p3)) < 0 ||
(code =
- (arc->action == arc_nothing ? 0 :
- arc->action == arc_lineto &&
- gx_path_current_point(path, &cpt) >= 0 ?
+ (arc->action == arc_nothing ?
+ (p0.x = path->position.x, p0.y = path->position.y, 0) :
+ arc->action == arc_lineto && path_position_valid(path) ?
gx_path_add_line(path, p0.x, p0.y) :
- /* action == arc_moveto */
+ /* action == arc_moveto, or lineto with no current point */
gx_path_add_point(path, p0.x, p0.y))) < 0
)
return code;
- return gx_path_add_partial_arc_notes(path, p3.x, p3.y, pt.x, pt.y,
- fraction, arc->notes);
+ /* Compute the fraction coefficient for the curve. */
+ /* See gx_path_add_partial_arc for details. */
+ if (is_quadrant) {
+ /* one of |dx| and |dy| is r, the other is zero */
+ fraction = quarter_arc_fraction;
+ if (arc->fast_quadrant > 0) {
+ /*
+ * The CTM is well-behaved, and we have pre-calculated the delta
+ * from the circumference points to the control points.
+ */
+ fixed delta = arc->quadrant_delta;
+
+ if (pt.x != p0.x)
+ p0.x = (pt.x > p0.x ? p0.x + delta : p0.x - delta);
+ if (pt.y != p0.y)
+ p0.y = (pt.y > p0.y ? p0.y + delta : p0.y - delta);
+ p2.x = (pt.x == p3.x ? p3.x :
+ pt.x > p3.x ? p3.x + delta : p3.x - delta);
+ p2.y = (pt.y == p3.y ? p3.y :
+ pt.y > p3.y ? p3.y + delta : p3.y - delta);
+ goto add;
+ }
+ } else {
+ double r = arc->radius;
+ floatp dx = xt - x0, dy = yt - y0;
+ double dist = dx * dx + dy * dy;
+ double r2 = r * r;
+
+ if (dist >= r2 * 1.0e8) /* almost zero radius; */
+ /* the >= catches dist == r == 0 */
+ fraction = 0.0;
+ else
+ fraction = (4.0 / 3.0) / (1 + sqrt(1 + dist / r2));
+ }
+ p0.x += (fixed)((pt.x - p0.x) * fraction);
+ p0.y += (fixed)((pt.y - p0.y) * fraction);
+ p2.x = p3.x + (fixed)((pt.x - p3.x) * fraction);
+ p2.y = p3.y + (fixed)((pt.y - p3.y) * fraction);
+add:
+ if_debug8('r',
+ "[r]Arc f=%f p0=(%f,%f) pt=(%f,%f) p3=(%f,%f) action=%d\n",
+ fraction, x0, y0, xt, yt, arc->p3.x, arc->p3.y,
+ (int)arc->action);
+ /* Open-code gx_path_add_partial_arc_notes */
+ return gx_path_add_curve_notes(path, p0.x, p0.y, p2.x, p2.y, p3.x, p3.y,
+ arc->notes | sn_from_arc);
}
/* ------ Path transformers ------ */
diff --git a/gs/src/gspcolor.c b/gs/src/gspcolor.c
index 35d72b20a..c5cbcc7b5 100644
--- a/gs/src/gspcolor.c
+++ b/gs/src/gspcolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -43,19 +43,15 @@
#include "gsiparm4.h"
/* GC descriptors */
-private_st_pattern1_template();
+public_st_pattern_template();
public_st_pattern_instance();
-/* Import the Pattern reloading procedure from gxpcmap.c. */
-int gx_pattern_load(P4(gx_device_color *, const gs_imager_state *,
- gx_device *, gs_color_select_t));
-
/* Define the Pattern color space. */
gs_private_st_composite(st_color_space_Pattern, gs_paint_color_space,
"gs_color_space_Pattern", cs_Pattern_enum_ptrs, cs_Pattern_reloc_ptrs);
private cs_proc_num_components(gx_num_components_Pattern);
private cs_proc_base_space(gx_base_space_Pattern);
-extern cs_proc_remap_color(gx_remap_Pattern);
+private cs_proc_remap_color(gx_remap_Pattern);
private cs_proc_init_color(gx_init_Pattern);
private cs_proc_restrict_color(gx_restrict_Pattern);
private cs_proc_install_cspace(gx_install_Pattern);
@@ -72,204 +68,63 @@ const gs_color_space_type gs_color_space_type_Pattern = {
gx_adjust_cspace_Pattern, gx_adjust_color_Pattern
};
-/*
- * Build a PatternType 1 Pattern color space.
- */
-int
-gs_cspace_build_Pattern1(gs_color_space ** ppcspace,
- const gs_color_space * pbase_cspace, gs_memory_t * pmem)
-{
- gs_color_space *pcspace = 0;
- int code;
-
- if (pbase_cspace != 0) {
- if (gs_color_space_num_components(pcspace) < 0) /* Pattern space */
- return_error(gs_error_rangecheck);
- }
- code = gs_cspace_alloc(&pcspace, &gs_color_space_type_Pattern, pmem);
- if (code < 0)
- return code;
- if (pbase_cspace != 0) {
- pcspace->params.pattern.has_base_space = true;
- gs_cspace_init_from((gs_color_space *) & (pcspace->params.pattern.base_space),
- pbase_cspace
- );
- } else
- pcspace->params.pattern.has_base_space = false;
- *ppcspace = pcspace;
- return 0;
-}
-
-/* Initialize a PatternType 1 pattern template. */
+/* Initialize a generic pattern template. */
void
-gs_pattern1_init(gs_pattern1_template_t * ppat)
+gs_pattern_common_init(gs_pattern_template_t * ppat,
+ const gs_pattern_type_t *type)
{
+ ppat->type = type;
+ ppat->PatternType = type->PatternType;
uid_set_invalid(&ppat->uid);
- ppat->PaintType = 0; /* mark as PatternType 1 but invalid */
ppat->client_data = 0; /* for GC */
}
-/* makepattern */
-private int compute_inst_matrix(P3(gs_pattern_instance * pinst,
- const gs_state * saved,
- gs_rect * pbbox));
-private rc_free_proc(rc_free_pattern_instance);
+/* Generic makepattern */
int
-gs_makepattern(gs_client_color * pcc, const gs_client_pattern * pcp,
- const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
+gs_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * pcp,
+ const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
{
- gs_pattern_instance inst;
- gs_pattern_instance *pinst;
+ return pcp->type->procs.make_pattern(pcc, pcp, pmat, pgs, mem);
+}
+
+/*
+ * Do the generic work for makepattern: allocate the instance and the
+ * saved graphics state, and fill in the common members.
+ */
+int
+gs_make_pattern_common(gs_client_color *pcc,
+ const gs_pattern_template_t *ptemp,
+ const gs_matrix *pmat, gs_state *pgs, gs_memory_t *mem,
+ gs_memory_type_ptr_t pstype)
+{
+ gs_pattern_instance_t *pinst;
gs_state *saved;
- gs_rect bbox;
- gs_fixed_rect cbox;
- int code;
if (mem == 0)
mem = gs_state_memory(pgs);
- rc_alloc_struct_1(pinst, gs_pattern_instance, &st_pattern_instance,
- mem, return_error(gs_error_VMerror),
- "gs_makepattern");
+ rc_alloc_struct_1(pinst, gs_pattern_instance_t, pstype, mem,
+ return_error(gs_error_VMerror),
+ "gs_make_pattern_common");
pinst->rc.free = rc_free_pattern_instance;
- inst.rc = pinst->rc;
+ pinst->type = ptemp->type;
saved = gs_state_copy(pgs, mem);
if (saved == 0) {
- code = gs_note_error(gs_error_VMerror);
- goto finst;
+ gs_free_object(mem, pinst, "gs_make_pattern_common");
+ return_error(gs_error_VMerror);
}
gs_concat(saved, pmat);
gs_newpath(saved);
- switch (pcp->PaintType) {
- case 1: /* colored */
- gs_set_logical_op(saved, lop_default);
- break;
- case 2: /* uncolored */
- gx_set_device_color_1(saved);
- break;
- default:
- code = gs_note_error(gs_error_rangecheck);
- goto fsaved;
- }
- inst.template = *pcp;
- inst.saved = saved;
- code = compute_inst_matrix(&inst, saved, &bbox);
- if (code < 0)
- goto fsaved;
-#define mat inst.step_matrix
- if_debug6('t', "[t]step_matrix=[%g %g %g %g %g %g]\n",
- mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
- if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
- bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
- {
- float bbw = bbox.q.x - bbox.p.x;
- float bbh = bbox.q.y - bbox.p.y;
-
- /* If the step and the size agree to within 1/2 pixel, */
- /* make them the same. */
- inst.size.x = (int)(bbw + 0.8); /* 0.8 is arbitrary */
- inst.size.y = (int)(bbh + 0.8);
-
- if (inst.size.x == 0 || inst.size.y == 0) {
- /*
- * The pattern is empty: the stepping matrix doesn't matter.
- */
- gs_make_identity(&mat);
- bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0;
- } else {
- /* Check for singular stepping matrix. */
- if (fabs(mat.xx * mat.yy - mat.xy * mat.yx) < 1.0e-6) {
- code = gs_note_error(gs_error_rangecheck);
- goto fsaved;
- }
- if (mat.xy == 0 && mat.yx == 0 &&
- fabs(fabs(mat.xx) - bbw) < 0.5 &&
- fabs(fabs(mat.yy) - bbh) < 0.5
- ) {
- gs_scale(saved, fabs(inst.size.x / mat.xx),
- fabs(inst.size.y / mat.yy));
- code = compute_inst_matrix(&inst, saved, &bbox);
- if (code < 0)
- goto fsaved;
- if_debug2('t',
- "[t]adjusted XStep & YStep to size=(%d,%d)\n",
- inst.size.x, inst.size.y);
- if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
- bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
- }
- }
- }
- if ((code = gs_bbox_transform_inverse(&bbox, &mat, &inst.bbox)) < 0)
- goto fsaved;
- if_debug4('t', "[t]ibbox=(%g,%g),(%g,%g)\n",
- inst.bbox.p.x, inst.bbox.p.y, inst.bbox.q.x, inst.bbox.q.y);
- inst.is_simple = (fabs(mat.xx) == inst.size.x && mat.xy == 0 &&
- mat.yx == 0 && fabs(mat.yy) == inst.size.y);
- if_debug6('t',
- "[t]is_simple? xstep=(%g,%g) ystep=(%g,%g) size=(%d,%d)\n",
- inst.step_matrix.xx, inst.step_matrix.xy,
- inst.step_matrix.yx, inst.step_matrix.yy,
- inst.size.x, inst.size.y);
- /* Absent other information, instances always require a mask. */
- inst.uses_mask = true;
- gx_translate_to_fixed(saved, float2fixed(mat.tx - bbox.p.x),
- float2fixed(mat.ty - bbox.p.y));
- mat.tx = bbox.p.x;
- mat.ty = bbox.p.y;
-#undef mat
- cbox.p.x = fixed_0;
- cbox.p.y = fixed_0;
- cbox.q.x = int2fixed(inst.size.x);
- cbox.q.y = int2fixed(inst.size.y);
- code = gx_clip_to_rectangle(saved, &cbox);
- if (code < 0)
- goto fsaved;
- inst.id = gs_next_ids(1);
- *pinst = inst;
+ pinst->saved = saved;
pcc->pattern = pinst;
return 0;
-#undef mat
- fsaved:gs_state_free(saved);
- finst:gs_free_object(mem, pinst, "gs_makepattern");
- return code;
}
-/* Compute the stepping matrix and device space instance bounding box */
-/* from the step values and the saved matrix. */
-private int
-compute_inst_matrix(gs_pattern_instance * pinst, const gs_state * saved,
- gs_rect * pbbox)
-{
- double xx = pinst->template.XStep * saved->ctm.xx;
- double xy = pinst->template.XStep * saved->ctm.xy;
- double yx = pinst->template.YStep * saved->ctm.yx;
- double yy = pinst->template.YStep * saved->ctm.yy;
-
- /* Adjust the stepping matrix so all coefficients are >= 0. */
- if (xx == 0 || yy == 0) { /* We know that both xy and yx are non-zero. */
- double temp;
- temp = xx, xx = yx, yx = temp;
- temp = xy, xy = yy, yy = temp;
- }
- if (xx < 0)
- xx = -xx, xy = -xy;
- if (yy < 0)
- yx = -yx, yy = -yy;
- /* Now xx > 0, yy > 0. */
- pinst->step_matrix.xx = xx;
- pinst->step_matrix.xy = xy;
- pinst->step_matrix.yx = yx;
- pinst->step_matrix.yy = yy;
- pinst->step_matrix.tx = saved->ctm.tx;
- pinst->step_matrix.ty = saved->ctm.ty;
- return gs_bbox_transform(&pinst->template.BBox, &ctm_only(saved),
- pbbox);
-}
/* Free the saved gstate when freeing a Pattern instance. */
-private void
+void
rc_free_pattern_instance(gs_memory_t * mem, void *pinst_void,
client_name_t cname)
{
- gs_pattern_instance *pinst = pinst_void;
+ gs_pattern_instance_t *pinst = pinst_void;
gs_state_free(pinst->saved);
rc_free_struct_only(mem, pinst_void, cname);
@@ -299,10 +154,13 @@ gs_setpatternspace(gs_state * pgs)
gs_color_space cs;
gs_cspace_init(&cs, &gs_color_space_type_Pattern, NULL);
+ /**************** base_space SETTING IS WRONG ****************/
cs.params.pattern.base_space =
*(gs_paint_color_space *) pgs->color_space;
cs.params.pattern.has_base_space = true;
*pgs->color_space = cs;
+ /* Don't change orig_base_cspace_index. */
+ pgs->orig_cspace_index = gs_color_space_index_Pattern;
cs_full_init_color(pgs->ccolor, &cs);
gx_unset_dev_color(pgs);
}
@@ -325,529 +183,12 @@ gs_pattern_reference(gs_client_color * pcc, int delta)
/* getpattern */
/* This is only intended for the benefit of pattern PaintProcs. */
-const gs_client_pattern *
-gs_getpattern(const gs_client_color * pcc)
+const gs_pattern_template_t *
+gs_get_pattern(const gs_client_color * pcc)
{
- return &pcc->pattern->template;
-}
-
-/*
- * Code for generating patterns from bitmaps and pixmaps.
- */
-
-/*
- * The following structures are realized here only because this is the
- * first location in which they were needed. Otherwise, there is nothing
- * about them that is specific to patterns.
- */
-public_st_gs_bitmap();
-public_st_gs_tile_bitmap();
-public_st_gs_depth_bitmap();
-public_st_gs_tile_depth_bitmap();
-public_st_gx_strip_bitmap();
+ const gs_pattern_instance_t *pinst = pcc->pattern;
-/*
- * Structure for holding a gs_depth_bitmap and the corresponding depth and
- * colorspace information.
- *
- * The free_proc pointer is needed to hold the original value of the pattern
- * instance free structure. This pointer in the pattern instance will be
- * overwritten with free_pixmap_pattern, which will free the pixmap info
- * structure when it is freed.
- */
-typedef struct pixmap_info_s {
- gs_depth_bitmap bitmap; /* must be first */
- const gs_color_space *pcspace;
- uint white_index;
- void (*free_proc)( gs_memory_t *, void *, client_name_t );
-} pixmap_info;
-
-gs_private_st_suffix_add1(st_pixmap_info,
- pixmap_info,
- "pixmap info. struct",
- pixmap_enum_ptr,
- pixmap_reloc_ptr,
- st_gs_depth_bitmap,
- pcspace
-);
-
-#define st_pixmap_info_max_ptrs (1 + st_tile_bitmap_max_ptrs)
-
-/*
- * Free routine for pattern instances created from pixmaps. This overwrites
- * the free procedure originally stored in the pattern instance, and stores
- * the pointer to that procedure in the pixmap_info structure. This procedure
- * will call the original procedure, then free the pixmap_info structure.
- *
- * Note that this routine does NOT release the data in the original pixmap;
- * that remains the responsibility of the client.
- */
- void
-free_pixmap_pattern(
- gs_memory_t * pmem,
- void * pvpinst,
- client_name_t cname
-)
-{
- gs_pattern_instance * pinst = (gs_pattern_instance *)pvpinst;
- const pixmap_info * ppmap = pinst->template.client_data;
-
- ppmap->free_proc(pmem, pvpinst, cname);
- gs_free_object(pmem, (void *)ppmap, cname);
-}
-
-/*
- * PaintProcs for bitmap and pixmap patterns.
- */
-private int bitmap_paint(P4(gs_image_enum * pen, gs_data_image_t * pim,
- const gs_depth_bitmap * pbitmap, gs_state * pgs));
-private int
-mask_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
-{
- const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
- const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
- gs_image_enum *pen =
- gs_image_enum_alloc(gs_state_memory(pgs), "mask_PaintProc");
- gs_image1_t mask;
-
- if (pen == 0)
- return_error(gs_error_VMerror);
- gs_image_t_init_mask(&mask, true);
- mask.Width = pbitmap->size.x;
- mask.Height = pbitmap->size.y;
- gs_image_init(pen, &mask, false, pgs);
- return bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs);
-}
-private int
-image_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
-{
- const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
- const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
- gs_image_enum *pen =
- gs_image_enum_alloc(gs_state_memory(pgs), "image_PaintProc");
- const gs_color_space *pcspace =
- (ppmap->pcspace == 0 ?
- gs_cspace_DeviceGray((const gs_imager_state *)pgs) :
- ppmap->pcspace);
- gx_image_enum_common_t *pie;
- gs_image4_t image;
- int code;
-
- if (pen == 0)
- return_error(gs_error_VMerror);
- gs_image4_t_init(&image, pcspace);
- image.Width = pbitmap->size.x;
- image.Height = pbitmap->size.y;
- image.MaskColor_is_range = false;
- image.MaskColor[0] = ppmap->white_index;
- image.Decode[0] = 0;
- image.Decode[1] = (1 << pbitmap->pix_depth) - 1;
- image.BitsPerComponent = pbitmap->pix_depth;
- /* backwards compatibility */
- if (ppmap->pcspace == 0) {
- image.Decode[0] = 1.0;
- image.Decode[1] = 0.0;
- }
- code = gs_image_begin_typed((const gs_image_common_t *)&image, pgs,
- false, &pie);
- if (code < 0)
- return code;
- code = gs_image_common_init(pen, pie, (gs_data_image_t *) & image,
- gs_state_memory(pgs),
- (pgs->in_charpath ? NULL :
- gs_currentdevice_inline(pgs)));
- if (code < 0)
- return code;
- return bitmap_paint(pen, (gs_data_image_t *) & image, pbitmap, pgs);
-}
-/* Finish painting any kind of bitmap pattern. */
-private int
-bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim,
- const gs_depth_bitmap * pbitmap, gs_state * pgs)
-{
- uint raster = pbitmap->raster;
- uint nbytes = (pim->Width * pbitmap->pix_depth + 7) >> 3;
- uint used;
- const byte *dp = pbitmap->data;
- int n;
- int code = 0;
-
- if (nbytes == raster)
- code = gs_image_next(pen, dp, nbytes * pim->Height, &used);
- else
- for (n = pim->Height; n > 0 && code >= 0; dp += raster, --n)
- code = gs_image_next(pen, dp, nbytes, &used);
- gs_image_cleanup(pen);
- gs_free_object(gs_state_memory(pgs), pen, "bitmap_paint");
- return code;
-}
-
-/*
- * Make a pattern from a bitmap or pixmap. The pattern may be colored or
- * uncolored, as determined by the mask operand. This code is intended
- * primarily for use by PCL.
- *
- * See the comment prior to the declaration of this function in gscolor2.h
- * for further information.
- */
-int
-gs_makepixmappattern(
- gs_client_color * pcc,
- const gs_depth_bitmap * pbitmap,
- bool mask,
- const gs_matrix * pmat,
- long id,
- const gs_color_space * pcspace,
- uint white_index,
- gs_state * pgs,
- gs_memory_t * mem
-)
-{
-
- gs_client_pattern pat;
- pixmap_info *ppmap;
- gs_matrix mat, smat;
- int code;
-
- /* check that the data is legitimate */
- if ((mask) || (pcspace == 0)) {
- if (pbitmap->pix_depth != 1)
- return_error(gs_error_rangecheck);
- pcspace = 0;
- } else if (gs_color_space_get_index(pcspace) != gs_color_space_index_Indexed)
- return_error(gs_error_rangecheck);
- if (pbitmap->num_comps != 1)
- return_error(gs_error_rangecheck);
-
- /* allocate and initialize a pixmap_info structure for the paint proc */
- if (mem == 0)
- mem = gs_state_memory(pgs);
- ppmap = gs_alloc_struct(mem,
- pixmap_info,
- &st_pixmap_info,
- "makepximappattern"
- );
- if (ppmap == 0)
- return_error(gs_error_VMerror);
- ppmap->bitmap = *pbitmap;
- ppmap->pcspace = pcspace;
- ppmap->white_index = white_index;
-
- /* set up the client pattern structure */
- uid_set_UniqueID(&pat.uid, (id == no_UniqueID) ? gs_next_ids(1) : id);
- pat.PaintType = (mask ? 2 : 1);
- pat.TilingType = 1;
- pat.BBox.p.x = 0;
- pat.BBox.p.y = 0;
- pat.BBox.q.x = pbitmap->size.x;
- pat.BBox.q.y = pbitmap->size.y;
- pat.XStep = pbitmap->size.x;
- pat.YStep = pbitmap->size.y;
- pat.PaintProc = (mask ? mask_PaintProc : image_PaintProc);
- pat.client_data = ppmap;
-
- /* set the ctm to be the identity */
- gs_currentmatrix(pgs, &smat);
- gs_make_identity(&mat);
- gs_setmatrix(pgs, &mat);
-
- /* build the pattern, restore the previous matrix */
- if (pmat == NULL)
- pmat = &mat;
- if ((code = gs_makepattern(pcc, &pat, pmat, pgs, mem)) != 0)
- gs_free_object(mem, ppmap, "makebitmappattern_xform");
- else {
- /*
- * If this is not a masked pattern and if the white pixel index
- * is outside of the representable range, we don't need to go to
- * the trouble of accumulating a mask that will just be all 1s.
- */
- if (!mask && (white_index >= (1 << pbitmap->pix_depth)))
- pcc->pattern->uses_mask = false;
-
- /* overwrite the free procedure for the pattern instance */
- ppmap->free_proc = pcc->pattern->rc.free;
- pcc->pattern->rc.free = free_pixmap_pattern;
- }
- gs_setmatrix(pgs, &smat);
- return code;
-}
-
-/*
- * Backwards compatibility.
- */
-int
-gs_makebitmappattern_xform(
- gs_client_color * pcc,
- const gx_tile_bitmap * ptile,
- bool mask,
- const gs_matrix * pmat,
- long id,
- gs_state * pgs,
- gs_memory_t * mem
-)
-{
- gs_depth_bitmap bitmap;
-
- /* build the bitmap the size of one repetition */
- bitmap.data = ptile->data;
- bitmap.raster = ptile->raster;
- bitmap.size.x = ptile->rep_width;
- bitmap.size.y = ptile->rep_height;
- bitmap.id = ptile->id; /* shouldn't matter */
- bitmap.pix_depth = 1;
- bitmap.num_comps = 1;
-
- return gs_makepixmappattern(pcc, &bitmap, mask, pmat, id, 0, 0, pgs, mem);
-}
-
-
-/* ------ Color space implementation ------ */
-
-/*
- * Defined the Pattern device color types. We need a masked analogue of
- * each of the non-pattern types, to handle uncolored patterns. We use
- * 'masked_fill_rect' instead of 'masked_fill_rectangle' in order to limit
- * identifier lengths to 32 characters.
- */
-private dev_color_proc_load(gx_dc_pattern_load);
-/*dev_color_proc_fill_rectangle(gx_dc_pattern_fill_rectangle); *//*gxp1fill.h */
-private dev_color_proc_equal(gx_dc_pattern_equal);
-private dev_color_proc_load(gx_dc_pure_masked_load);
-
-/*dev_color_proc_fill_rectangle(gx_dc_pure_masked_fill_rect); *//*gxp1fill.h */
-private dev_color_proc_equal(gx_dc_pure_masked_equal);
-private dev_color_proc_load(gx_dc_binary_masked_load);
-
-/*dev_color_proc_fill_rectangle(gx_dc_binary_masked_fill_rect); *//*gxp1fill.h */
-private dev_color_proc_equal(gx_dc_binary_masked_equal);
-private dev_color_proc_load(gx_dc_colored_masked_load);
-
-/*dev_color_proc_fill_rectangle(gx_dc_colored_masked_fill_rect); *//*gxp1fill.h */
-private dev_color_proc_equal(gx_dc_colored_masked_equal);
-
-/* The device color types are exported for gxpcmap.c. */
-gs_private_st_composite(st_dc_pattern, gx_device_color, "dc_pattern",
- dc_pattern_enum_ptrs, dc_pattern_reloc_ptrs);
-const gx_device_color_type_t gx_dc_pattern = {
- &st_dc_pattern,
- gx_dc_pattern_load, gx_dc_pattern_fill_rectangle,
- gx_dc_default_fill_masked, gx_dc_pattern_equal
-};
-
-extern_st(st_dc_ht_binary);
-gs_private_st_composite(st_dc_pure_masked, gx_device_color, "dc_pure_masked",
- dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
-const gx_device_color_type_t gx_dc_pure_masked = {
- &st_dc_pure_masked,
- gx_dc_pure_masked_load, gx_dc_pure_masked_fill_rect,
- gx_dc_default_fill_masked, gx_dc_pure_masked_equal
-};
-
-gs_private_st_composite(st_dc_binary_masked, gx_device_color,
- "dc_binary_masked", dc_binary_masked_enum_ptrs,
- dc_binary_masked_reloc_ptrs);
-const gx_device_color_type_t gx_dc_binary_masked = {
- &st_dc_binary_masked,
- gx_dc_binary_masked_load, gx_dc_binary_masked_fill_rect,
- gx_dc_default_fill_masked, gx_dc_binary_masked_equal
-};
-
-gs_private_st_composite_only(st_dc_colored_masked, gx_device_color,
- "dc_colored_masked",
- dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
-const gx_device_color_type_t gx_dc_colored_masked = {
- &st_dc_colored_masked,
- gx_dc_colored_masked_load, gx_dc_colored_masked_fill_rect,
- gx_dc_default_fill_masked, gx_dc_colored_masked_equal
-};
-
-#undef gx_dc_type_pattern
-const gx_device_color_type_t *const gx_dc_type_pattern = &gx_dc_pattern;
-#define gx_dc_type_pattern (&gx_dc_pattern)
-
-/* GC procedures */
-#define cptr ((gx_device_color *)vptr)
-private
-ENUM_PTRS_BEGIN(dc_pattern_enum_ptrs)
-{
- return ENUM_USING(st_dc_pure_masked, vptr, size, index - 1);
-}
-case 0:
-{
- gx_color_tile *tile = cptr->colors.pattern.p_tile;
-
- ENUM_RETURN((tile == 0 ? tile : tile - tile->index));
-}
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(dc_pattern_reloc_ptrs)
-{
- gx_color_tile *tile = cptr->colors.pattern.p_tile;
-
- if (tile != 0) {
- uint index = tile->index;
-
- RELOC_TYPED_OFFSET_PTR(gx_device_color, colors.pattern.p_tile, index);
- }
- RELOC_USING(st_dc_pure_masked, vptr, size);
-}
-RELOC_PTRS_END
-private ENUM_PTRS_BEGIN(dc_masked_enum_ptrs) ENUM_SUPER(gx_device_color, st_client_color, mask.ccolor, 1);
-case 0:
-{
- gx_color_tile *mask = cptr->mask.m_tile;
-
- ENUM_RETURN((mask == 0 ? mask : mask - mask->index));
-}
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(dc_masked_reloc_ptrs)
-{
- gx_color_tile *mask = cptr->mask.m_tile;
-
- RELOC_SUPER(gx_device_color, st_client_color, mask.ccolor);
- if (mask != 0) {
- uint index = mask->index;
-
- RELOC_TYPED_OFFSET_PTR(gx_device_color, mask.m_tile, index);
- }
-}
-RELOC_PTRS_END
-private ENUM_PTRS_BEGIN(dc_binary_masked_enum_ptrs)
-{
- return ENUM_USING(st_dc_ht_binary, vptr, size, index - 2);
-}
-case 0:
-case 1:
-return ENUM_USING(st_dc_pure_masked, vptr, size, index);
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(dc_binary_masked_reloc_ptrs)
-{
- RELOC_USING(st_dc_pure_masked, vptr, size);
- RELOC_USING(st_dc_ht_binary, vptr, size);
-}
-RELOC_PTRS_END
-#undef cptr
-
-/* Macros for pattern loading */
-#define FINISH_PATTERN_LOAD\
- while ( !gx_pattern_cache_lookup(pdevc, pis, dev, select) )\
- { code = gx_pattern_load(pdevc, pis, dev, select);\
- if ( code < 0 ) break;\
- }\
- return code;
-
-/* Ensure that a colored Pattern is loaded in the cache. */
-private int
-gx_dc_pattern_load(gx_device_color * pdevc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
-{
- int code = 0;
-
- FINISH_PATTERN_LOAD
-}
-/* Ensure that an uncolored Pattern is loaded in the cache. */
-private int
-gx_dc_pure_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
-{
- int code = (*gx_dc_type_data_pure.load) (pdevc, pis, dev, select);
-
- if (code < 0)
- return code;
- FINISH_PATTERN_LOAD
-}
-private int
-gx_dc_binary_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
-{
- int code = (*gx_dc_type_data_ht_binary.load) (pdevc, pis, dev, select);
-
- if (code < 0)
- return code;
- FINISH_PATTERN_LOAD
-}
-private int
-gx_dc_colored_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
-{
- int code = (*gx_dc_type_data_ht_colored.load) (pdevc, pis, dev, select);
-
- if (code < 0)
- return code;
- FINISH_PATTERN_LOAD
-}
-
-/* Look up a pattern color in the cache. */
-bool
-gx_pattern_cache_lookup(gx_device_color * pdevc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
-{
- gx_pattern_cache *pcache = pis->pattern_cache;
- gx_bitmap_id id = pdevc->mask.id;
-
- if (id == gx_no_bitmap_id) {
- color_set_null_pattern(pdevc);
- return true;
- }
- if (pcache != 0) {
- gx_color_tile *ctile = &pcache->tiles[id % pcache->num_tiles];
-
- if (ctile->id == id &&
- (pdevc->type != &gx_dc_pattern ||
- ctile->depth == dev->color_info.depth)
- ) {
- int px = pis->screen_phase[select].x;
- int py = pis->screen_phase[select].y;
-
- if (pdevc->type == &gx_dc_pattern) { /* colored */
- pdevc->colors.pattern.p_tile = ctile;
- color_set_phase_mod(pdevc, px, py,
- ctile->tbits.rep_width,
- ctile->tbits.rep_height);
- }
- pdevc->mask.m_tile =
- (ctile->tmask.data == 0 ? (gx_color_tile *) 0 :
- ctile);
- pdevc->mask.m_phase.x = -px;
- pdevc->mask.m_phase.y = -py;
- return true;
- }
- }
- return false;
-}
-
-#undef FINISH_PATTERN_LOAD
-
-/* Compare two Pattern colors for equality. */
-private bool
-gx_dc_pattern_equal(const gx_device_color * pdevc1,
- const gx_device_color * pdevc2)
-{
- return pdevc2->type == pdevc1->type &&
- pdevc1->phase.x == pdevc2->phase.x &&
- pdevc1->phase.y == pdevc2->phase.y &&
- pdevc1->mask.id == pdevc2->mask.id;
-}
-private bool
-gx_dc_pure_masked_equal(const gx_device_color * pdevc1,
- const gx_device_color * pdevc2)
-{
- return (*gx_dc_type_pure->equal) (pdevc1, pdevc2) &&
- pdevc1->mask.id == pdevc2->mask.id;
-}
-private bool
-gx_dc_binary_masked_equal(const gx_device_color * pdevc1,
- const gx_device_color * pdevc2)
-{
- return (*gx_dc_type_ht_binary->equal) (pdevc1, pdevc2) &&
- pdevc1->mask.id == pdevc2->mask.id;
-}
-private bool
-gx_dc_colored_masked_equal(const gx_device_color * pdevc1,
- const gx_device_color * pdevc2)
-{
- return (*gx_dc_type_ht_colored->equal) (pdevc1, pdevc2) &&
- pdevc1->mask.id == pdevc2->mask.id;
+ return (pinst == 0 ? 0 : pinst->type->procs.get_pattern(pinst));
}
/*
@@ -875,6 +216,16 @@ gx_base_space_Pattern(const gs_color_space * pcs)
NULL);
}
+/* Remap a Pattern color. */
+private int
+gx_remap_Pattern(const gs_client_color * pc, const gs_color_space * pcs,
+ gx_device_color * pdc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ return
+ pc->pattern->type->procs.remap_color(pc, pcs, pdc, pis, dev, select);
+}
+
/* Initialize a Pattern color. */
private void
gx_init_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
@@ -896,7 +247,7 @@ gx_init_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
private void
gx_restrict_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
{
- if (pcc->pattern->template.PaintType == 2 &&
+ if (pcc->pattern->type->procs.uses_base_space(gs_get_pattern(pcc)) &&
pcs->params.pattern.has_base_space
) {
const gs_color_space *pbcs =
@@ -908,12 +259,12 @@ gx_restrict_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
/* Install a Pattern color space. */
private int
-gx_install_Pattern(gs_color_space * pcs, gs_state * pgs)
+gx_install_Pattern(const gs_color_space * pcs, gs_state * pgs)
{
if (!pcs->params.pattern.has_base_space)
return 0;
return (*pcs->params.pattern.base_space.type->install_cspace)
- ((gs_color_space *) & pcs->params.pattern.base_space, pgs);
+ ((const gs_color_space *) & pcs->params.pattern.base_space, pgs);
}
/* Adjust the reference counts for Pattern color spaces or colors. */
@@ -929,7 +280,7 @@ private void
gx_adjust_color_Pattern(const gs_client_color * pcc,
const gs_color_space * pcs, int delta)
{
- gs_pattern_instance *pinst = pcc->pattern;
+ gs_pattern_instance_t *pinst = pcc->pattern;
rc_adjust_only(pinst, delta, "gx_adjust_color_Pattern");
if (pcs && pcs->params.pattern.has_base_space)
diff --git a/gs/src/gspcolor.h b/gs/src/gspcolor.h
index a0599f069..ab600f10e 100644
--- a/gs/src/gspcolor.h
+++ b/gs/src/gspcolor.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,37 +23,78 @@
# define gspcolor_INCLUDED
#include "gsccolor.h"
+#include "gsrefct.h"
#include "gsuid.h"
/* ---------------- Types and structures ---------------- */
/*
- * Unfortunately, we defined the gs_client_pattern structure before we
+ * We originally defined the gs_client_pattern structure before we
* realized that we would have to accommodate multiple PatternTypes.
- * Consequently, we distinguish the different PatternTypes with a hack.
- * We know that PatternType 1 patterns always have a positive PaintType.
- * Therefore, we overlay the PaintType field of PatternType 1 patterns
- * with the negative of the PatternType for generalized patterns.
- * This allows us to distinguish PatternType 1 patterns from all others.
- * This is a really bad hack, but doing anything else would require
- * a non-backward-compatible change for clients, since we didn't
- * require clients to use a procedure to initialize Patterns (another
- * mistake, in retrospect, which we've now also fixed).
+ * In version 5.68, we bit the bullet and made an incompatible change
+ * to this structure so that multiple PatternTypes could be supported.
+ * In order to make this work:
+ *
+ * Clients creating instances of any Pattern template structure
+ * (gs_patternN_template_t) must call gs_patternN_init to
+ * initialize all the members, before filling in any of the
+ * members themselves.
+ *
+ * This is a non-backward-compatible requirement relative to previous
+ * versions, but it was unavoidable.
*/
-/* General pattern template (called "prototype pattern" in Red Book) */
+/*
+ * Define the abstract pattern template (called "prototype pattern" in Red
+ * Book).
+ */
+
+#ifndef gs_pattern_type_DEFINED
+# define gs_pattern_type_DEFINED
typedef struct gs_pattern_type_s gs_pattern_type_t;
+#endif
#define gs_pattern_template_common\
- gs_uid uid; /* must be first in case we ever subclass properly */\
- int negPatternType; /* overlays PaintType, see above */\
- const gs_pattern_type_t *type
-#define PatternType(ppt)\
- ((ppt)->negPatternType < 0 ? -(ppt)->negPatternType : 1)
+ const gs_pattern_type_t *type;\
+ int PatternType; /* copied from the type structure */\
+ gs_uid uid;\
+ void *client_data /* additional data for rendering */
+
typedef struct gs_pattern_template_s {
gs_pattern_template_common;
} gs_pattern_template_t;
+/* The descriptor is public for subclassing. */
+extern_st(st_pattern_template);
+#define public_st_pattern_template() /* in gspcolor.c */\
+ gs_public_st_ptrs2(st_pattern_template, gs_pattern_template_t,\
+ "gs_pattern_template_t", pattern_template_enum_ptrs,\
+ pattern_template_reloc_ptrs, uid.xvalues, client_data)
+#define st_pattern_template_max_ptrs 2
+
+/* Definition of Pattern instances. */
+#ifndef gs_pattern_instance_DEFINED
+# define gs_pattern_instance_DEFINED
+typedef struct gs_pattern_instance_s gs_pattern_instance_t;
+#endif
+
+#define gs_pattern_instance_common\
+ rc_header rc;\
+ /* Following are set by makepattern */\
+ const gs_pattern_type_t *type; /* from template */\
+ gs_state *saved
+struct gs_pattern_instance_s {
+ gs_pattern_instance_common;
+};
+
+/* The following is public for subclassing. */
+extern_st(st_pattern_instance);
+#define public_st_pattern_instance() /* in gspcolor.c */\
+ gs_public_st_ptrs1(st_pattern_instance, gs_pattern_instance_t,\
+ "gs_pattern_instance_t", pattern_instance_enum_ptrs,\
+ pattern_instance_reloc_ptrs, saved)
+#define st_pattern_instance_max_ptrs 1
+
/* ---------------- Procedures ---------------- */
/* Set a Pattern color or a Pattern color space. */
@@ -61,6 +102,7 @@ int gs_setpattern(P2(gs_state *, const gs_client_color *));
int gs_setpatternspace(P1(gs_state *));
/*
+ * Construct a Pattern color of any PatternType.
* The gs_memory_t argument for gs_make_pattern may be NULL, meaning use the
* same allocator as for the gs_state argument. Note that gs_make_pattern
* uses rc_alloc_struct_1 to allocate pattern instances.
diff --git a/gs/src/gsptype1.c b/gs/src/gsptype1.c
new file mode 100644
index 000000000..41068ed17
--- /dev/null
+++ b/gs/src/gsptype1.c
@@ -0,0 +1,817 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* PatternType 1 pattern implementation */
+#include "math_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gsrop.h"
+#include "gsstruct.h"
+#include "gsutil.h" /* for gs_next_ids */
+#include "gxarith.h"
+#include "gxfixed.h"
+#include "gxmatrix.h"
+#include "gxcoord.h" /* for gs_concat, gx_tr'_to_fixed */
+#include "gxcspace.h" /* for gscolor2.h */
+#include "gxcolor2.h"
+#include "gxdcolor.h"
+#include "gxdevice.h"
+#include "gxdevmem.h"
+#include "gxclip2.h"
+#include "gspath.h"
+#include "gxpath.h"
+#include "gxp1fill.h"
+#include "gxpcolor.h"
+#include "gzstate.h"
+#include "gsimage.h"
+#include "gsiparm4.h"
+
+/* GC descriptors */
+private_st_pattern1_template();
+private_st_pattern1_instance();
+
+/* GC procedures */
+private ENUM_PTRS_BEGIN(pattern1_instance_enum_ptrs) {
+ if (index < st_pattern1_template_max_ptrs) {
+ gs_ptr_type_t ptype =
+ ENUM_SUPER_ELT(gs_pattern1_instance_t, st_pattern1_template,
+ template, 0);
+
+ if (ptype)
+ return ptype;
+ return ENUM_OBJ(NULL); /* don't stop early */
+ }
+ ENUM_PREFIX(st_pattern_instance, st_pattern1_template_max_ptrs);
+} ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(pattern1_instance_reloc_ptrs) {
+ RELOC_PREFIX(st_pattern_instance);
+ RELOC_SUPER(gs_pattern1_instance_t, st_pattern1_template, template);
+} RELOC_PTRS_END
+
+/* Import the Pattern reloading procedure from gxpcmap.c. */
+int gx_pattern_load(P4(gx_device_color *, const gs_imager_state *,
+ gx_device *, gs_color_select_t));
+
+/* Define a PatternType 1 pattern. */
+private pattern_proc_uses_base_space(gs_pattern1_uses_base_space);
+private pattern_proc_make_pattern(gs_pattern1_make_pattern);
+private pattern_proc_get_pattern(gs_pattern1_get_pattern);
+extern pattern_proc_remap_color(gs_pattern1_remap_color);
+private const gs_pattern_type_t gs_pattern1_type = {
+ 1, {
+ gs_pattern1_uses_base_space, gs_pattern1_make_pattern,
+ gs_pattern1_get_pattern, gs_pattern1_remap_color
+ }
+};
+
+/*
+ * Build a PatternType 1 Pattern color space.
+ */
+int
+gs_cspace_build_Pattern1(gs_color_space ** ppcspace,
+ const gs_color_space * pbase_cspace, gs_memory_t * pmem)
+{
+ gs_color_space *pcspace = 0;
+ int code;
+
+ if (pbase_cspace != 0) {
+ if (gs_color_space_num_components(pcspace) < 0) /* Pattern space */
+ return_error(gs_error_rangecheck);
+ }
+ code = gs_cspace_alloc(&pcspace, &gs_color_space_type_Pattern, pmem);
+ if (code < 0)
+ return code;
+ if (pbase_cspace != 0) {
+ pcspace->params.pattern.has_base_space = true;
+ gs_cspace_init_from((gs_color_space *) & (pcspace->params.pattern.base_space),
+ pbase_cspace
+ );
+ } else
+ pcspace->params.pattern.has_base_space = false;
+ *ppcspace = pcspace;
+ return 0;
+}
+
+/* Initialize a PatternType 1 pattern template. */
+void
+gs_pattern1_init(gs_pattern1_template_t * ppat)
+{
+ gs_pattern_common_init((gs_pattern_template_t *)ppat, &gs_pattern1_type);
+}
+
+/* Make an instance of a PatternType 1 pattern. */
+private int compute_inst_matrix(P3(gs_pattern1_instance_t * pinst,
+ const gs_state * saved, gs_rect * pbbox));
+int
+gs_makepattern(gs_client_color * pcc, const gs_pattern1_template_t * pcp,
+ const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
+{
+ return gs_pattern1_make_pattern(pcc, (const gs_pattern_template_t *)pcp,
+ pmat, pgs, mem);
+}
+private int
+gs_pattern1_make_pattern(gs_client_color * pcc,
+ const gs_pattern_template_t * ptemp,
+ const gs_matrix * pmat, gs_state * pgs,
+ gs_memory_t * mem)
+{
+ const gs_pattern1_template_t *pcp = (const gs_pattern1_template_t *)ptemp;
+ gs_pattern1_instance_t inst;
+ gs_pattern1_instance_t *pinst;
+ gs_state *saved;
+ gs_rect bbox;
+ gs_fixed_rect cbox;
+ int code = gs_make_pattern_common(pcc, (const gs_pattern_template_t *)pcp,
+ pmat, pgs, mem,
+ &st_pattern1_instance);
+
+ if (code < 0)
+ return code;
+ if (mem == 0)
+ mem = gs_state_memory(pgs);
+ pinst = (gs_pattern1_instance_t *)pcc->pattern;
+ *(gs_pattern_instance_t *)&inst = *(gs_pattern_instance_t *)pinst;
+ saved = inst.saved;
+ switch (pcp->PaintType) {
+ case 1: /* colored */
+ gs_set_logical_op(saved, lop_default);
+ break;
+ case 2: /* uncolored */
+ gx_set_device_color_1(saved);
+ break;
+ default:
+ code = gs_note_error(gs_error_rangecheck);
+ goto fsaved;
+ }
+ inst.template = *pcp;
+ code = compute_inst_matrix(&inst, saved, &bbox);
+ if (code < 0)
+ goto fsaved;
+#define mat inst.step_matrix
+ if_debug6('t', "[t]step_matrix=[%g %g %g %g %g %g]\n",
+ mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
+ if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
+ bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
+ {
+ float bbw = bbox.q.x - bbox.p.x;
+ float bbh = bbox.q.y - bbox.p.y;
+
+ /* If the step and the size agree to within 1/2 pixel, */
+ /* make them the same. */
+ inst.size.x = (int)(bbw + 0.8); /* 0.8 is arbitrary */
+ inst.size.y = (int)(bbh + 0.8);
+
+ if (inst.size.x == 0 || inst.size.y == 0) {
+ /*
+ * The pattern is empty: the stepping matrix doesn't matter.
+ */
+ gs_make_identity(&mat);
+ bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0;
+ } else {
+ /* Check for singular stepping matrix. */
+ if (fabs(mat.xx * mat.yy - mat.xy * mat.yx) < 1.0e-6) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto fsaved;
+ }
+ if (mat.xy == 0 && mat.yx == 0 &&
+ fabs(fabs(mat.xx) - bbw) < 0.5 &&
+ fabs(fabs(mat.yy) - bbh) < 0.5
+ ) {
+ gs_scale(saved, fabs(inst.size.x / mat.xx),
+ fabs(inst.size.y / mat.yy));
+ code = compute_inst_matrix(&inst, saved, &bbox);
+ if (code < 0)
+ goto fsaved;
+ if_debug2('t',
+ "[t]adjusted XStep & YStep to size=(%d,%d)\n",
+ inst.size.x, inst.size.y);
+ if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
+ bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
+ }
+ }
+ }
+ if ((code = gs_bbox_transform_inverse(&bbox, &mat, &inst.bbox)) < 0)
+ goto fsaved;
+ if_debug4('t', "[t]ibbox=(%g,%g),(%g,%g)\n",
+ inst.bbox.p.x, inst.bbox.p.y, inst.bbox.q.x, inst.bbox.q.y);
+ inst.is_simple = (fabs(mat.xx) == inst.size.x && mat.xy == 0 &&
+ mat.yx == 0 && fabs(mat.yy) == inst.size.y);
+ if_debug6('t',
+ "[t]is_simple? xstep=(%g,%g) ystep=(%g,%g) size=(%d,%d)\n",
+ inst.step_matrix.xx, inst.step_matrix.xy,
+ inst.step_matrix.yx, inst.step_matrix.yy,
+ inst.size.x, inst.size.y);
+ /* Absent other information, instances always require a mask. */
+ inst.uses_mask = true;
+ gx_translate_to_fixed(saved, float2fixed(mat.tx - bbox.p.x),
+ float2fixed(mat.ty - bbox.p.y));
+ mat.tx = bbox.p.x;
+ mat.ty = bbox.p.y;
+#undef mat
+ cbox.p.x = fixed_0;
+ cbox.p.y = fixed_0;
+ cbox.q.x = int2fixed(inst.size.x);
+ cbox.q.y = int2fixed(inst.size.y);
+ code = gx_clip_to_rectangle(saved, &cbox);
+ if (code < 0)
+ goto fsaved;
+ inst.id = gs_next_ids(1);
+ *pinst = inst;
+ return 0;
+#undef mat
+ fsaved:gs_state_free(saved);
+ gs_free_object(mem, pinst, "gs_makepattern");
+ return code;
+}
+/* Compute the stepping matrix and device space instance bounding box */
+/* from the step values and the saved matrix. */
+private int
+compute_inst_matrix(gs_pattern1_instance_t * pinst, const gs_state * saved,
+ gs_rect * pbbox)
+{
+ double xx = pinst->template.XStep * saved->ctm.xx;
+ double xy = pinst->template.XStep * saved->ctm.xy;
+ double yx = pinst->template.YStep * saved->ctm.yx;
+ double yy = pinst->template.YStep * saved->ctm.yy;
+
+ /* Adjust the stepping matrix so all coefficients are >= 0. */
+ if (xx == 0 || yy == 0) { /* We know that both xy and yx are non-zero. */
+ double temp;
+
+ temp = xx, xx = yx, yx = temp;
+ temp = xy, xy = yy, yy = temp;
+ }
+ if (xx < 0)
+ xx = -xx, xy = -xy;
+ if (yy < 0)
+ yx = -yx, yy = -yy;
+ /* Now xx > 0, yy > 0. */
+ pinst->step_matrix.xx = xx;
+ pinst->step_matrix.xy = xy;
+ pinst->step_matrix.yx = yx;
+ pinst->step_matrix.yy = yy;
+ pinst->step_matrix.tx = saved->ctm.tx;
+ pinst->step_matrix.ty = saved->ctm.ty;
+ return gs_bbox_transform(&pinst->template.BBox, &ctm_only(saved),
+ pbbox);
+}
+
+/* Test whether a PatternType 1 pattern uses a base space. */
+private bool
+gs_pattern1_uses_base_space(const gs_pattern_template_t *ptemp)
+{
+ return ((const gs_pattern1_template_t *)ptemp)->PaintType == 2;
+}
+
+/* getpattern for PatternType 1 */
+/* This is only intended for the benefit of pattern PaintProcs. */
+private const gs_pattern_template_t *
+gs_pattern1_get_pattern(const gs_pattern_instance_t *pinst)
+{
+ return (const gs_pattern_template_t *)
+ &((const gs_pattern1_instance_t *)pinst)->template;
+}
+const gs_pattern1_template_t *
+gs_getpattern(const gs_client_color * pcc)
+{
+ const gs_pattern_instance_t *pinst = pcc->pattern;
+
+ return (pinst == 0 || pinst->type != &gs_pattern1_type ? 0 :
+ &((const gs_pattern1_instance_t *)pinst)->template);
+}
+
+/*
+ * Code for generating patterns from bitmaps and pixmaps.
+ */
+
+/*
+ * The following structures are realized here only because this is the
+ * first location in which they were needed. Otherwise, there is nothing
+ * about them that is specific to patterns.
+ */
+public_st_gs_bitmap();
+public_st_gs_tile_bitmap();
+public_st_gs_depth_bitmap();
+public_st_gs_tile_depth_bitmap();
+public_st_gx_strip_bitmap();
+
+/*
+ * Structure for holding a gs_depth_bitmap and the corresponding depth and
+ * colorspace information.
+ *
+ * The free_proc pointer is needed to hold the original value of the pattern
+ * instance free structure. This pointer in the pattern instance will be
+ * overwritten with free_pixmap_pattern, which will free the pixmap info
+ * structure when it is freed.
+ */
+typedef struct pixmap_info_s {
+ gs_depth_bitmap bitmap; /* must be first */
+ const gs_color_space *pcspace;
+ uint white_index;
+ void (*free_proc)(P3(gs_memory_t *, void *, client_name_t));
+} pixmap_info;
+
+gs_private_st_suffix_add1(st_pixmap_info,
+ pixmap_info,
+ "pixmap info. struct",
+ pixmap_enum_ptr,
+ pixmap_reloc_ptr,
+ st_gs_depth_bitmap,
+ pcspace
+);
+
+#define st_pixmap_info_max_ptrs (1 + st_tile_bitmap_max_ptrs)
+
+/*
+ * Free routine for pattern instances created from pixmaps. This overwrites
+ * the free procedure originally stored in the pattern instance, and stores
+ * the pointer to that procedure in the pixmap_info structure. This procedure
+ * will call the original procedure, then free the pixmap_info structure.
+ *
+ * Note that this routine does NOT release the data in the original pixmap;
+ * that remains the responsibility of the client.
+ */
+ void
+free_pixmap_pattern(
+ gs_memory_t * pmem,
+ void * pvpinst,
+ client_name_t cname
+)
+{
+ gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pvpinst;
+ pixmap_info *ppmap = pinst->template.client_data;
+
+ ppmap->free_proc(pmem, pvpinst, cname);
+ gs_free_object(pmem, ppmap, cname);
+}
+
+/*
+ * PaintProcs for bitmap and pixmap patterns.
+ */
+private int bitmap_paint(P4(gs_image_enum * pen, gs_data_image_t * pim,
+ const gs_depth_bitmap * pbitmap, gs_state * pgs));
+private int
+mask_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
+{
+ const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
+ const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
+ gs_image_enum *pen =
+ gs_image_enum_alloc(gs_state_memory(pgs), "mask_PaintProc");
+ gs_image1_t mask;
+
+ if (pen == 0)
+ return_error(gs_error_VMerror);
+ gs_image_t_init_mask(&mask, true);
+ mask.Width = pbitmap->size.x;
+ mask.Height = pbitmap->size.y;
+ gs_image_init(pen, &mask, false, pgs);
+ return bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs);
+}
+private int
+image_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
+{
+ const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
+ const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
+ gs_image_enum *pen =
+ gs_image_enum_alloc(gs_state_memory(pgs), "image_PaintProc");
+ const gs_color_space *pcspace =
+ (ppmap->pcspace == 0 ?
+ gs_cspace_DeviceGray((const gs_imager_state *)pgs) :
+ ppmap->pcspace);
+ gx_image_enum_common_t *pie;
+ gs_image4_t image;
+ int code;
+
+ if (pen == 0)
+ return_error(gs_error_VMerror);
+ gs_image4_t_init(&image, pcspace);
+ image.Width = pbitmap->size.x;
+ image.Height = pbitmap->size.y;
+ image.MaskColor_is_range = false;
+ image.MaskColor[0] = ppmap->white_index;
+ image.Decode[0] = 0;
+ image.Decode[1] = (1 << pbitmap->pix_depth) - 1;
+ image.BitsPerComponent = pbitmap->pix_depth;
+ /* backwards compatibility */
+ if (ppmap->pcspace == 0) {
+ image.Decode[0] = 1.0;
+ image.Decode[1] = 0.0;
+ }
+ code = gs_image_begin_typed((const gs_image_common_t *)&image, pgs,
+ false, &pie);
+ if (code < 0)
+ return code;
+ code = gs_image_enum_init(pen, pie, (gs_data_image_t *)&image, pgs);
+ if (code < 0)
+ return code;
+ return bitmap_paint(pen, (gs_data_image_t *) & image, pbitmap, pgs);
+}
+/* Finish painting any kind of bitmap pattern. */
+private int
+bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim,
+ const gs_depth_bitmap * pbitmap, gs_state * pgs)
+{
+ uint raster = pbitmap->raster;
+ uint nbytes = (pim->Width * pbitmap->pix_depth + 7) >> 3;
+ uint used;
+ const byte *dp = pbitmap->data;
+ int n;
+ int code = 0;
+
+ if (nbytes == raster)
+ code = gs_image_next(pen, dp, nbytes * pim->Height, &used);
+ else
+ for (n = pim->Height; n > 0 && code >= 0; dp += raster, --n)
+ code = gs_image_next(pen, dp, nbytes, &used);
+ gs_image_cleanup(pen);
+ gs_free_object(gs_state_memory(pgs), pen, "bitmap_paint");
+ return code;
+}
+
+/*
+ * Make a pattern from a bitmap or pixmap. The pattern may be colored or
+ * uncolored, as determined by the mask operand. This code is intended
+ * primarily for use by PCL.
+ *
+ * See the comment prior to the declaration of this function in gscolor2.h
+ * for further information.
+ */
+int
+gs_makepixmappattern(
+ gs_client_color * pcc,
+ const gs_depth_bitmap * pbitmap,
+ bool mask,
+ const gs_matrix * pmat,
+ long id,
+ const gs_color_space * pcspace,
+ uint white_index,
+ gs_state * pgs,
+ gs_memory_t * mem
+)
+{
+
+ gs_pattern1_template_t pat;
+ pixmap_info *ppmap;
+ gs_matrix mat, smat;
+ int code;
+
+ /* check that the data is legitimate */
+ if ((mask) || (pcspace == 0)) {
+ if (pbitmap->pix_depth != 1)
+ return_error(gs_error_rangecheck);
+ pcspace = 0;
+ } else if (gs_color_space_get_index(pcspace) != gs_color_space_index_Indexed)
+ return_error(gs_error_rangecheck);
+ if (pbitmap->num_comps != 1)
+ return_error(gs_error_rangecheck);
+
+ /* allocate and initialize a pixmap_info structure for the paint proc */
+ if (mem == 0)
+ mem = gs_state_memory(pgs);
+ ppmap = gs_alloc_struct(mem,
+ pixmap_info,
+ &st_pixmap_info,
+ "makepximappattern"
+ );
+ if (ppmap == 0)
+ return_error(gs_error_VMerror);
+ ppmap->bitmap = *pbitmap;
+ ppmap->pcspace = pcspace;
+ ppmap->white_index = white_index;
+
+ /* set up the client pattern structure */
+ gs_pattern1_init(&pat);
+ uid_set_UniqueID(&pat.uid, (id == no_UniqueID) ? gs_next_ids(1) : id);
+ pat.PaintType = (mask ? 2 : 1);
+ pat.TilingType = 1;
+ pat.BBox.p.x = 0;
+ pat.BBox.p.y = 0;
+ pat.BBox.q.x = pbitmap->size.x;
+ pat.BBox.q.y = pbitmap->size.y;
+ pat.XStep = pbitmap->size.x;
+ pat.YStep = pbitmap->size.y;
+ pat.PaintProc = (mask ? mask_PaintProc : image_PaintProc);
+ pat.client_data = ppmap;
+
+ /* set the ctm to be the identity */
+ gs_currentmatrix(pgs, &smat);
+ gs_make_identity(&mat);
+ gs_setmatrix(pgs, &mat);
+
+ /* build the pattern, restore the previous matrix */
+ if (pmat == NULL)
+ pmat = &mat;
+ if ((code = gs_makepattern(pcc, &pat, pmat, pgs, mem)) != 0)
+ gs_free_object(mem, ppmap, "makebitmappattern_xform");
+ else {
+ /*
+ * If this is not a masked pattern and if the white pixel index
+ * is outside of the representable range, we don't need to go to
+ * the trouble of accumulating a mask that will just be all 1s.
+ */
+ gs_pattern1_instance_t *pinst =
+ (gs_pattern1_instance_t *)pcc->pattern;
+
+ if (!mask && (white_index >= (1 << pbitmap->pix_depth)))
+ pinst->uses_mask = false;
+
+ /* overwrite the free procedure for the pattern instance */
+ ppmap->free_proc = pinst->rc.free;
+ pinst->rc.free = free_pixmap_pattern;
+ }
+ gs_setmatrix(pgs, &smat);
+ return code;
+}
+
+/*
+ * Backwards compatibility.
+ */
+int
+gs_makebitmappattern_xform(
+ gs_client_color * pcc,
+ const gx_tile_bitmap * ptile,
+ bool mask,
+ const gs_matrix * pmat,
+ long id,
+ gs_state * pgs,
+ gs_memory_t * mem
+)
+{
+ gs_depth_bitmap bitmap;
+
+ /* build the bitmap the size of one repetition */
+ bitmap.data = ptile->data;
+ bitmap.raster = ptile->raster;
+ bitmap.size.x = ptile->rep_width;
+ bitmap.size.y = ptile->rep_height;
+ bitmap.id = ptile->id; /* shouldn't matter */
+ bitmap.pix_depth = 1;
+ bitmap.num_comps = 1;
+
+ return gs_makepixmappattern(pcc, &bitmap, mask, pmat, id, 0, 0, pgs, mem);
+}
+
+
+/* ------ Color space implementation ------ */
+
+/*
+ * Defined the Pattern device color types. We need a masked analogue of
+ * each of the non-pattern types, to handle uncolored patterns. We use
+ * 'masked_fill_rect' instead of 'masked_fill_rectangle' in order to limit
+ * identifier lengths to 32 characters.
+ */
+private dev_color_proc_load(gx_dc_pattern_load);
+/*dev_color_proc_fill_rectangle(gx_dc_pattern_fill_rectangle); *//*gxp1fill.h */
+private dev_color_proc_equal(gx_dc_pattern_equal);
+private dev_color_proc_load(gx_dc_pure_masked_load);
+
+/*dev_color_proc_fill_rectangle(gx_dc_pure_masked_fill_rect); *//*gxp1fill.h */
+private dev_color_proc_equal(gx_dc_pure_masked_equal);
+private dev_color_proc_load(gx_dc_binary_masked_load);
+
+/*dev_color_proc_fill_rectangle(gx_dc_binary_masked_fill_rect); *//*gxp1fill.h */
+private dev_color_proc_equal(gx_dc_binary_masked_equal);
+private dev_color_proc_load(gx_dc_colored_masked_load);
+
+/*dev_color_proc_fill_rectangle(gx_dc_colored_masked_fill_rect); *//*gxp1fill.h */
+private dev_color_proc_equal(gx_dc_colored_masked_equal);
+
+/* The device color types are exported for gxpcmap.c. */
+gs_private_st_composite(st_dc_pattern, gx_device_color, "dc_pattern",
+ dc_pattern_enum_ptrs, dc_pattern_reloc_ptrs);
+const gx_device_color_type_t gx_dc_pattern = {
+ &st_dc_pattern,
+ gx_dc_pattern_load, gx_dc_pattern_fill_rectangle,
+ gx_dc_default_fill_masked, gx_dc_pattern_equal
+};
+
+extern_st(st_dc_ht_binary);
+gs_private_st_composite(st_dc_pure_masked, gx_device_color, "dc_pure_masked",
+ dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
+const gx_device_color_type_t gx_dc_pure_masked = {
+ &st_dc_pure_masked,
+ gx_dc_pure_masked_load, gx_dc_pure_masked_fill_rect,
+ gx_dc_default_fill_masked, gx_dc_pure_masked_equal
+};
+
+gs_private_st_composite(st_dc_binary_masked, gx_device_color,
+ "dc_binary_masked", dc_binary_masked_enum_ptrs,
+ dc_binary_masked_reloc_ptrs);
+const gx_device_color_type_t gx_dc_binary_masked = {
+ &st_dc_binary_masked,
+ gx_dc_binary_masked_load, gx_dc_binary_masked_fill_rect,
+ gx_dc_default_fill_masked, gx_dc_binary_masked_equal
+};
+
+gs_private_st_composite_only(st_dc_colored_masked, gx_device_color,
+ "dc_colored_masked",
+ dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
+const gx_device_color_type_t gx_dc_colored_masked = {
+ &st_dc_colored_masked,
+ gx_dc_colored_masked_load, gx_dc_colored_masked_fill_rect,
+ gx_dc_default_fill_masked, gx_dc_colored_masked_equal
+};
+
+#undef gx_dc_type_pattern
+const gx_device_color_type_t *const gx_dc_type_pattern = &gx_dc_pattern;
+#define gx_dc_type_pattern (&gx_dc_pattern)
+
+/* GC procedures */
+#define cptr ((gx_device_color *)vptr)
+private
+ENUM_PTRS_BEGIN(dc_pattern_enum_ptrs)
+{
+ return ENUM_USING(st_dc_pure_masked, vptr, size, index - 1);
+}
+case 0:
+{
+ gx_color_tile *tile = cptr->colors.pattern.p_tile;
+
+ ENUM_RETURN((tile == 0 ? tile : tile - tile->index));
+}
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(dc_pattern_reloc_ptrs)
+{
+ gx_color_tile *tile = cptr->colors.pattern.p_tile;
+
+ if (tile != 0) {
+ uint index = tile->index;
+
+ RELOC_TYPED_OFFSET_PTR(gx_device_color, colors.pattern.p_tile, index);
+ }
+ RELOC_USING(st_dc_pure_masked, vptr, size);
+}
+RELOC_PTRS_END
+private ENUM_PTRS_BEGIN(dc_masked_enum_ptrs) ENUM_SUPER(gx_device_color, st_client_color, ccolor, 1);
+case 0:
+{
+ gx_color_tile *mask = cptr->mask.m_tile;
+
+ ENUM_RETURN((mask == 0 ? mask : mask - mask->index));
+}
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(dc_masked_reloc_ptrs)
+{
+ gx_color_tile *mask = cptr->mask.m_tile;
+
+ RELOC_SUPER(gx_device_color, st_client_color, ccolor);
+ if (mask != 0) {
+ uint index = mask->index;
+
+ RELOC_TYPED_OFFSET_PTR(gx_device_color, mask.m_tile, index);
+ }
+}
+RELOC_PTRS_END
+private ENUM_PTRS_BEGIN(dc_binary_masked_enum_ptrs)
+{
+ return ENUM_USING(st_dc_ht_binary, vptr, size, index - 2);
+}
+case 0:
+case 1:
+return ENUM_USING(st_dc_pure_masked, vptr, size, index);
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(dc_binary_masked_reloc_ptrs)
+{
+ RELOC_USING(st_dc_pure_masked, vptr, size);
+ RELOC_USING(st_dc_ht_binary, vptr, size);
+}
+RELOC_PTRS_END
+#undef cptr
+
+/* Macros for pattern loading */
+#define FINISH_PATTERN_LOAD\
+ while ( !gx_pattern_cache_lookup(pdevc, pis, dev, select) )\
+ { code = gx_pattern_load(pdevc, pis, dev, select);\
+ if ( code < 0 ) break;\
+ }\
+ return code;
+
+/* Ensure that a colored Pattern is loaded in the cache. */
+private int
+gx_dc_pattern_load(gx_device_color * pdevc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ int code = 0;
+
+ FINISH_PATTERN_LOAD
+}
+/* Ensure that an uncolored Pattern is loaded in the cache. */
+private int
+gx_dc_pure_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ int code = (*gx_dc_type_data_pure.load) (pdevc, pis, dev, select);
+
+ if (code < 0)
+ return code;
+ FINISH_PATTERN_LOAD
+}
+private int
+gx_dc_binary_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ int code = (*gx_dc_type_data_ht_binary.load) (pdevc, pis, dev, select);
+
+ if (code < 0)
+ return code;
+ FINISH_PATTERN_LOAD
+}
+private int
+gx_dc_colored_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ int code = (*gx_dc_type_data_ht_colored.load) (pdevc, pis, dev, select);
+
+ if (code < 0)
+ return code;
+ FINISH_PATTERN_LOAD
+}
+
+/* Look up a pattern color in the cache. */
+bool
+gx_pattern_cache_lookup(gx_device_color * pdevc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ gx_pattern_cache *pcache = pis->pattern_cache;
+ gx_bitmap_id id = pdevc->mask.id;
+
+ if (id == gx_no_bitmap_id) {
+ color_set_null_pattern(pdevc);
+ return true;
+ }
+ if (pcache != 0) {
+ gx_color_tile *ctile = &pcache->tiles[id % pcache->num_tiles];
+
+ if (ctile->id == id &&
+ (pdevc->type != &gx_dc_pattern ||
+ ctile->depth == dev->color_info.depth)
+ ) {
+ int px = pis->screen_phase[select].x;
+ int py = pis->screen_phase[select].y;
+
+ if (pdevc->type == &gx_dc_pattern) { /* colored */
+ pdevc->colors.pattern.p_tile = ctile;
+ color_set_phase_mod(pdevc, px, py,
+ ctile->tbits.rep_width,
+ ctile->tbits.rep_height);
+ }
+ pdevc->mask.m_tile =
+ (ctile->tmask.data == 0 ? (gx_color_tile *) 0 :
+ ctile);
+ pdevc->mask.m_phase.x = -px;
+ pdevc->mask.m_phase.y = -py;
+ return true;
+ }
+ }
+ return false;
+}
+
+#undef FINISH_PATTERN_LOAD
+
+/* Compare two Pattern colors for equality. */
+private bool
+gx_dc_pattern_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ return pdevc2->type == pdevc1->type &&
+ pdevc1->phase.x == pdevc2->phase.x &&
+ pdevc1->phase.y == pdevc2->phase.y &&
+ pdevc1->mask.id == pdevc2->mask.id;
+}
+private bool
+gx_dc_pure_masked_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ return (*gx_dc_type_pure->equal) (pdevc1, pdevc2) &&
+ pdevc1->mask.id == pdevc2->mask.id;
+}
+private bool
+gx_dc_binary_masked_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ return (*gx_dc_type_ht_binary->equal) (pdevc1, pdevc2) &&
+ pdevc1->mask.id == pdevc2->mask.id;
+}
+private bool
+gx_dc_colored_masked_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ return (*gx_dc_type_ht_colored->equal) (pdevc1, pdevc2) &&
+ pdevc1->mask.id == pdevc2->mask.id;
+}
diff --git a/gs/src/gsptype1.h b/gs/src/gsptype1.h
index 51404016e..7bc371f0b 100644
--- a/gs/src/gsptype1.h
+++ b/gs/src/gsptype1.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,21 +28,28 @@
/* ---------------- Types and structures ---------------- */
/* PatternType 1 template */
+
typedef struct gs_pattern1_template_s {
- gs_uid uid; /* must be first, see gspcolor.h */
- int PaintType; /* must be second, ditto */
+ /*
+ * The common template must come first. It defines type, uid,
+ * PatternType, and client_data.
+ */
+ gs_pattern_template_common;
+ int PaintType;
int TilingType;
gs_rect BBox;
float XStep;
float YStep;
int (*PaintProc) (P2(const gs_client_color *, gs_state *));
- void *client_data; /* additional client data */
} gs_pattern1_template_t;
#define private_st_pattern1_template() /* in gspcolor.c */\
- gs_private_st_ptrs2(st_pattern1_template, gs_pattern1_template_t,\
- "PatternType 1 template", pattern_template_enum_ptrs,\
- pattern1_template_reloc_ptrs, uid.xvalues, client_data)
+ gs_private_st_suffix_add0(st_pattern1_template,\
+ gs_pattern1_template_t, "gs_pattern1_template_t",\
+ pattern1_template_enum_ptrs, pattern1_template_reloc_ptrs,\
+ st_pattern_template)
+#define st_pattern1_template_max_ptrs st_pattern_template_max_ptrs
+
/* Backward compatibility */
typedef gs_pattern1_template_t gs_client_pattern;
@@ -52,15 +59,16 @@ typedef gs_pattern1_template_t gs_client_pattern;
* Construct a PatternType 1 Pattern color space. If the base space is
* NULL, the color space can only be used with colored patterns.
*/
-extern int gs_cspace_build_Pattern1(
+extern int gs_cspace_build_Pattern1(P3(
gs_color_space ** ppcspace,
const gs_color_space * pbase_cspace,
gs_memory_t * pmem
-);
+ ));
/* Initialize a PatternType 1 pattern. */
void gs_pattern1_init(P1(gs_pattern1_template_t *));
+/* Backward compatibility */
#define gs_client_pattern_init(ppat) gs_pattern1_init(ppat)
/*
@@ -107,29 +115,31 @@ const gs_client_pattern *gs_getpattern(P1(const gs_client_color *));
* ensure that all white indices are mapped to the single, given white
* index.
*/
-extern int gs_makepixmappattern(gs_client_color * pcc,
- const gs_depth_bitmap * pbitmap,
- bool mask,
- const gs_matrix * pmat,
- long id,
- const gs_color_space * pcspace,
- uint white_index,
- gs_state * pgs,
- gs_memory_t * mem
-);
+extern int gs_makepixmappattern(P9(
+ gs_client_color * pcc,
+ const gs_depth_bitmap * pbitmap,
+ bool mask,
+ const gs_matrix * pmat,
+ long id,
+ const gs_color_space * pcspace,
+ uint white_index,
+ gs_state * pgs,
+ gs_memory_t * mem
+ ));
/*
* Backwards compatibility feature, to allow the existing
* gs_makebitmappattern operation to still function.
*/
-extern int gs_makebitmappattern_xform(gs_client_color * pcc,
- const gx_tile_bitmap * ptile,
- bool mask,
- const gs_matrix * pmat,
- long id,
- gs_state * pgs,
- gs_memory_t * mem
-);
+extern int gs_makebitmappattern_xform(P7(
+ gs_client_color * pcc,
+ const gx_tile_bitmap * ptile,
+ bool mask,
+ const gs_matrix * pmat,
+ long id,
+ gs_state * pgs,
+ gs_memory_t * mem
+ ));
#define gs_makebitmappattern(pcc, tile, mask, pgs, mem) \
gs_makebitmappattern_xform(pcc, tile, mask, 0, no_UniqueID, pgs, mem)
diff --git a/gs/src/gsptype2.c b/gs/src/gsptype2.c
new file mode 100644
index 000000000..d75103860
--- /dev/null
+++ b/gs/src/gsptype2.c
@@ -0,0 +1,181 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* PatternType 2 implementation */
+#include "gx.h"
+#include "gscspace.h"
+#include "gsshade.h"
+#include "gsmatrix.h" /* for gspcolor.h */
+#include "gsstate.h" /* for set/currentfilladjust */
+#include "gxcolor2.h"
+#include "gxdcolor.h"
+#include "gsptype2.h"
+#include "gxpcolor.h"
+#include "gxstate.h" /* for gs_state_memory */
+#include "gzpath.h"
+
+/* GC descriptors */
+private_st_pattern2_template();
+private_st_pattern2_instance();
+
+/* GC procedures */
+private ENUM_PTRS_BEGIN(pattern2_instance_enum_ptrs) {
+ if (index < st_pattern2_template_max_ptrs) {
+ gs_ptr_type_t ptype =
+ ENUM_SUPER_ELT(gs_pattern2_instance_t, st_pattern2_template,
+ template, 0);
+
+ if (ptype)
+ return ptype;
+ return ENUM_OBJ(NULL); /* don't stop early */
+ }
+ ENUM_PREFIX(st_pattern_instance, st_pattern2_template_max_ptrs);
+}
+ENUM_PTRS_END
+private RELOC_PTRS_BEGIN(pattern2_instance_reloc_ptrs) {
+ RELOC_PREFIX(st_pattern_instance);
+ RELOC_SUPER(gs_pattern2_instance_t, st_pattern2_template, template);
+} RELOC_PTRS_END
+
+/* Define a PatternType 2 pattern. */
+private pattern_proc_uses_base_space(gs_pattern2_uses_base_space);
+private pattern_proc_make_pattern(gs_pattern2_make_pattern);
+private pattern_proc_get_pattern(gs_pattern2_get_pattern);
+private pattern_proc_remap_color(gs_pattern2_remap_color);
+private const gs_pattern_type_t gs_pattern2_type = {
+ 2, {
+ gs_pattern2_uses_base_space, gs_pattern2_make_pattern,
+ gs_pattern2_get_pattern, gs_pattern2_remap_color
+ }
+};
+
+/* Initialize a PatternType 2 pattern. */
+void
+gs_pattern2_init(gs_pattern2_template_t * ppat)
+{
+ gs_pattern_common_init((gs_pattern_template_t *)ppat, &gs_pattern2_type);
+}
+
+/* Test whether a PatternType 2 pattern uses a base space. */
+private bool
+gs_pattern2_uses_base_space(const gs_pattern_template_t *ptemp)
+{
+ return false;
+}
+
+/* Make an instance of a PatternType 2 pattern. */
+private int
+gs_pattern2_make_pattern(gs_client_color * pcc,
+ const gs_pattern_template_t * pcp,
+ const gs_matrix * pmat, gs_state * pgs,
+ gs_memory_t * mem)
+{
+ const gs_pattern2_template_t *ptemp =
+ (const gs_pattern2_template_t *)pcp;
+ int code = gs_make_pattern_common(pcc, pcp, pmat, pgs, mem,
+ &st_pattern2_instance);
+ gs_pattern2_instance_t *pinst;
+
+ if (code < 0)
+ return code;
+ pinst = (gs_pattern2_instance_t *)pcc->pattern;
+ pinst->template = *ptemp;
+ return 0;
+}
+
+/* Get the template of a PatternType 2 pattern instance. */
+private const gs_pattern_template_t *
+gs_pattern2_get_pattern(const gs_pattern_instance_t *pinst)
+{
+ return (const gs_pattern_template_t *)
+ &((const gs_pattern2_instance_t *)pinst)->template;
+}
+
+/* ---------------- Rendering ---------------- */
+
+/* GC descriptor */
+gs_private_st_ptrs_add0(st_dc_pattern2, gx_device_color, "dc_pattern2",
+ dc_pattern2_enum_ptrs, dc_pattern2_reloc_ptrs,
+ st_client_color, ccolor);
+
+private dev_color_proc_load(gx_dc_pattern2_load);
+private dev_color_proc_fill_rectangle(gx_dc_pattern2_fill_rectangle);
+private dev_color_proc_equal(gx_dc_pattern2_equal);
+private const gx_device_color_type_t gx_dc_pattern2 = {
+ &st_dc_pattern2,
+ gx_dc_pattern2_load, gx_dc_pattern2_fill_rectangle,
+ gx_dc_default_fill_masked, gx_dc_pattern2_equal
+};
+
+/* Load a PatternType 2 color into the cache. (No effect.) */
+private int
+gx_dc_pattern2_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
+ gx_device *ignore_dev, gs_color_select_t ignore_select)
+{
+ return 0;
+}
+
+/* Remap a PatternType 2 color. */
+private int
+gs_pattern2_remap_color(const gs_client_color * pc, const gs_color_space * pcs,
+ gx_device_color * pdc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
+{
+ /* We don't do any actual color mapping now. */
+ pdc->type = &gx_dc_pattern2;
+ pdc->ccolor = *pc;
+ return 0;
+}
+
+/* Fill a rectangle with a PatternType 2 color. Glacially slow! */
+private int
+gx_dc_pattern2_fill_rectangle(const gx_device_color * pdevc, int x, int y,
+ int w, int h, gx_device * dev,
+ gs_logical_operation_t lop,
+ const gx_rop_source_t * source)
+{
+ gs_pattern2_instance_t *pinst =
+ (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
+ gs_state *pgs = pinst->saved;
+ gs_fixed_rect rect;
+ gs_point save_adjust;
+ int code;
+
+ rect.p.x = int2fixed(x);
+ rect.p.y = int2fixed(y);
+ rect.q.x = int2fixed(x + w);
+ rect.q.y = int2fixed(y + h);
+ /* We don't want any adjustment of the box. */
+ gs_currentfilladjust(pgs, &save_adjust);
+ gs_setfilladjust(pgs, 0.0, 0.0);
+ /****** DOESN'T HANDLE RASTER OP ******/
+ code = gs_shading_fill_path(pinst->template.Shading, NULL, &rect, dev,
+ (gs_imager_state *)pgs, true);
+ gs_setfilladjust(pgs, save_adjust.x, save_adjust.y);
+ return code;
+}
+
+/* Compare two PatternType 2 colors for equality. */
+private bool
+gx_dc_pattern2_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ return pdevc2->type == pdevc1->type &&
+ pdevc1->ccolor.pattern == pdevc2->ccolor.pattern;
+}
diff --git a/gs/src/gsptype2.h b/gs/src/gsptype2.h
index 2959e19b4..f98c81cd0 100644
--- a/gs/src/gsptype2.h
+++ b/gs/src/gsptype2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,20 +26,49 @@
/* ---------------- Types and structures ---------------- */
+/* PatternType 2 template */
+
#ifndef gs_shading_t_DEFINED
# define gs_shading_t_DEFINED
typedef struct gs_shading_s gs_shading_t;
-
#endif
-/* PatternType 2 template */
typedef struct gs_pattern2_template_s {
gs_pattern_template_common;
const gs_shading_t *Shading;
} gs_pattern2_template_t;
+#define private_st_pattern2_template() /* in gsptype2.c */\
+ gs_private_st_suffix_add1(st_pattern2_template,\
+ gs_pattern2_template_t, "gs_pattern2_template_t",\
+ pattern2_template_enum_ptrs, pattern2_template_reloc_ptrs,\
+ st_pattern_template, Shading)
+#define st_pattern2_template_max_ptrs (st_pattern_template_max_ptrs + 1)
+
+/* PatternType 2 instance */
+
+#ifndef gx_device_color_DEFINED
+# define gx_device_color_DEFINED
+typedef struct gx_device_color_s gx_device_color;
+#endif
+
+typedef struct gs_pattern2_instance_s {
+ gs_pattern_instance_common;
+ gs_pattern2_template_t template;
+} gs_pattern2_instance_t;
+
+#define private_st_pattern2_instance() /* in gsptype2.c */\
+ gs_private_st_composite(st_pattern2_instance, gs_pattern2_instance_t,\
+ "gs_pattern2_instance_t", pattern2_instance_enum_ptrs,\
+ pattern2_instance_reloc_ptrs)
+
/* ---------------- Procedures ---------------- */
+/*
+ * We should provide a gs_cspace_build_Pattern2 procedure to construct
+ * the color space, but we don't.
+ */
+
/* Initialize a PatternType 2 pattern. */
void gs_pattern2_init(P1(gs_pattern2_template_t *));
diff --git a/gs/src/gsrect.h b/gs/src/gsrect.h
index ff7b0f040..4d29d3c8f 100644
--- a/gs/src/gsrect.h
+++ b/gs/src/gsrect.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,8 +26,8 @@
/* Check whether one rectangle is included entirely within another. */
#define rect_within(inner, outer)\
- (inner.q.y <= outer.q.y && inner.q.x <= outer.q.x &&\
- inner.p.y >= outer.p.y && inner.p.x >= outer.p.x)
+ ((inner).q.y <= (outer).q.y && (inner).q.x <= (outer).q.x &&\
+ (inner).p.y >= (outer).p.y && (inner).p.x >= (outer).p.x)
/*
* Intersect two rectangles, replacing the first. The result may be
@@ -35,10 +35,10 @@
*/
#define rect_intersect(to, from)\
BEGIN\
- if ( from.p.x > to.p.x ) to.p.x = from.p.x;\
- if ( from.q.x < to.q.x ) to.q.x = from.q.x;\
- if ( from.p.y > to.p.y ) to.p.y = from.p.y;\
- if ( from.q.y < to.q.y ) to.q.y = from.q.y;\
+ if ((from).p.x > (to).p.x) (to).p.x = (from).p.x;\
+ if ((from).q.x < (to).q.x) (to).q.x = (from).q.x;\
+ if ((from).p.y > (to).p.y) (to).p.y = (from).p.y;\
+ if ((from).q.y < (to).q.y) (to).q.y = (from).q.y;\
END
/*
@@ -47,10 +47,10 @@
*/
#define rect_merge(to, from)\
BEGIN\
- if ( from.p.x < to.p.x ) to.p.x = from.p.x;\
- if ( from.q.x > to.q.x ) to.q.x = from.q.x;\
- if ( from.p.y < to.p.y ) to.p.y = from.p.y;\
- if ( from.q.y > to.q.y ) to.q.y = from.q.y;\
+ if ((from).p.x < (to).p.x) (to).p.x = (from).p.x;\
+ if ((from).q.x > (to).q.x) (to).q.x = (from).q.x;\
+ if ((from).p.y < (to).p.y) (to).p.y = (from).p.y;\
+ if ((from).q.y > (to).q.y) (to).q.y = (from).q.y;\
END
/*
diff --git a/gs/src/gsrefct.h b/gs/src/gsrefct.h
index 995b43fb6..a188cea71 100644
--- a/gs/src/gsrefct.h
+++ b/gs/src/gsrefct.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,17 +33,25 @@ struct rc_header_s {
gs_memory_t *memory;
#define rc_free_proc(proc)\
void proc(P3(gs_memory_t *, void *, client_name_t))
- rc_free_proc((*free));
+ rc_free_proc((*free));
};
+#ifdef DEBUG
+const char *rc_object_type_name(P2(const void *vp, const rc_header *prc));
+#endif
+
/* ------ Allocate/free ------ */
rc_free_proc(rc_free_struct_only);
/* rc_init[_free] is only used to initialize stack-allocated structures. */
#define rc_init_free(vp, mem, rcinit, proc)\
- ((vp)->rc.ref_count = rcinit,\
- (vp)->rc.memory = mem,\
- (vp)->rc.free = proc)
+ BEGIN\
+ (vp)->rc.ref_count = rcinit;\
+ (vp)->rc.memory = mem;\
+ (vp)->rc.free = proc;\
+ if_debug3('^', "[^]%s 0x%lx init = %d\n",\
+ rc_object_type_name(vp, &(vp)->rc), (ulong)vp, rcinit);\
+ END
#define rc_init(vp, mem, rcinit)\
rc_init_free(vp, mem, rcinit, rc_free_struct_only)
@@ -61,30 +69,51 @@ rc_free_proc(rc_free_struct_only);
rc_alloc_struct_n(vp, typ, pstype, mem, errstat, cname, 1)
#define rc_free_struct(vp, cname)\
- (*(vp)->rc.free)((vp)->rc.memory, (void *)(vp), cname)
+ BEGIN\
+ if_debug3('^', "[^]%s 0x%lx => free (%s)\n",\
+ rc_object_type_name(vp, &(vp)->rc),\
+ (ulong)vp, client_name_string(cname));\
+ (vp)->rc.free((vp)->rc.memory, (void *)(vp), cname);\
+ END
/* ------ Reference counting ------ */
/* Increment a reference count. */
+#define RC_DO_INCREMENT(vp)\
+ BEGIN\
+ (vp)->rc.ref_count++;\
+ if_debug3('^', "[^]%s 0x%lx ++ => %ld\n",\
+ rc_object_type_name(vp, &(vp)->rc),\
+ (ulong)vp, (long)(vp)->rc.ref_count);\
+ END
#define rc_increment(vp)\
- BEGIN if ( (vp) != 0 ) (vp)->rc.ref_count++; END
+ BEGIN\
+ if (vp) RC_DO_INCREMENT(vp);\
+ END
/* Increment a reference count, allocating the structure if necessary. */
#define rc_allocate_struct(vp, typ, pstype, mem, errstat, cname)\
BEGIN\
- if ( (vp) != 0 )\
- (vp)->rc.ref_count++;\
+ if (vp)\
+ RC_DO_INCREMENT(vp);\
else\
rc_alloc_struct_1(vp, typ, pstype, mem, errstat, cname);\
END
/* Guarantee that a structure is allocated and is not shared. */
+#define RC_DO_ADJUST(vp, delta)\
+ BEGIN\
+ if_debug4('^', "[^]%s 0x%lx %+d => %ld\n",\
+ rc_object_type_name(vp, &(vp)->rc),\
+ (ulong)vp, delta, (long)((vp)->rc.ref_count + (delta)));\
+ (vp)->rc.ref_count += (delta);\
+ END
#define rc_unshare_struct(vp, typ, pstype, mem, errstat, cname)\
BEGIN\
if ( (vp) == 0 || (vp)->rc.ref_count > 1 || (vp)->rc.memory != (mem) ) {\
typ *new;\
rc_alloc_struct_1(new, typ, pstype, mem, errstat, cname);\
- if ( vp ) (vp)->rc.ref_count--;\
+ if ( vp ) RC_DO_ADJUST(vp, -1);\
(vp) = new;\
}\
END
@@ -93,7 +122,7 @@ rc_free_proc(rc_free_struct_only);
#ifdef DEBUG
# define rc_check_(vp)\
BEGIN\
- if ( gs_debug_c('?') && (vp) != 0 && (vp)->rc.ref_count < 0 )\
+ if (gs_debug_c('?') && (vp)->rc.ref_count < 0)\
lprintf2("0x%lx has ref_count of %ld!\n", (ulong)(vp),\
(vp)->rc.ref_count);\
END
@@ -102,11 +131,14 @@ rc_free_proc(rc_free_struct_only);
#endif
#define rc_adjust_(vp, delta, cname, body)\
BEGIN\
- if ( (vp) != 0 && !((vp)->rc.ref_count += delta) ) {\
- rc_free_struct(vp, cname);\
- body;\
- } else\
- rc_check_(vp);\
+ if (vp) {\
+ RC_DO_ADJUST(vp, delta);\
+ if (!(vp)->rc.ref_count) {\
+ rc_free_struct(vp, cname);\
+ body;\
+ } else\
+ rc_check_(vp);\
+ }\
END
#define rc_adjust(vp, delta, cname)\
rc_adjust_(vp, delta, cname, (vp) = 0)
@@ -119,23 +151,30 @@ rc_free_proc(rc_free_struct_only);
#define rc_decrement_only(vp, cname)\
rc_adjust_only(vp, -1, cname)
-/* Assign a pointer, adjusting reference counts. */
+/*
+ * Assign a pointer, adjusting reference counts. vpfrom might be a local
+ * variable with a copy of the last reference to the object, and freeing
+ * vpto might decrement the object's reference count and cause it to be
+ * freed (incorrectly); for that reason, we do the increment first.
+ */
#define rc_assign(vpto, vpfrom, cname)\
BEGIN\
- if ( (vpto) != (vpfrom) ) {\
+ if ((vpto) != (vpfrom)) {\
+ rc_increment(vpfrom);\
rc_decrement_only(vpto, cname);\
(vpto) = (vpfrom);\
- rc_increment(vpto);\
}\
END
-/* Adjust reference counts for assigning a pointer, */
-/* but don't do the assignment. We use this before assigning */
-/* an entire structure containing reference-counted pointers. */
+/*
+ * Adjust reference counts for assigning a pointer,
+ * but don't do the assignment. We use this before assigning
+ * an entire structure containing reference-counted pointers.
+ */
#define rc_pre_assign(vpto, vpfrom, cname)\
BEGIN\
- if ( (vpto) != (vpfrom) ) {\
- rc_decrement_only(vpto, cname);\
+ if ((vpto) != (vpfrom)) {\
rc_increment(vpfrom);\
+ rc_decrement_only(vpto, cname);\
}\
END
diff --git a/gs/src/gsropc.c b/gs/src/gsropc.c
index ba1adf2c3..ef690bea8 100644
--- a/gs/src/gsropc.c
+++ b/gs/src/gsropc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -192,7 +192,7 @@ c_rop_create_default_compositor(const gs_composite_t * pcte,
* implementation based on depth and device color space.
****** NYI ******
*/
- cdev->target = dev;
+ gx_device_set_target((gx_device_forward *)cdev, dev);
cdev->params = prcte->params;
return 0;
}
diff --git a/gs/src/gsropt.h b/gs/src/gsropt.h
index 723ba2c2d..3f3bb3f5e 100644
--- a/gs/src/gsropt.h
+++ b/gs/src/gsropt.h
@@ -170,6 +170,19 @@ typedef uint gs_logical_operation_t;
/* Test whether a logical operation is idempotent. */
#define lop_is_idempotent(lop) rop3_is_idempotent(lop)
+/*
+ * Define the logical operation versions of some RasterOp transformations.
+ * Note that these also affect the transparency flags.
+ */
+#define lop_know_S_0(lop)\
+ (rop3_know_S_0(lop) & ~lop_S_transparent)
+#define lop_know_T_0(lop)\
+ (rop3_know_T_0(lop) & ~lop_T_transparent)
+#define lop_know_S_1(lop)\
+ (lop & lop_S_transparent ? rop3_D : rop3_know_S_1(lop))
+#define lop_know_T_1(lop)\
+ (lop & lop_T_transparent ? rop3_D : rop3_know_T_1(lop))
+
/* Define the interface to the table of 256 RasterOp procedures. */
typedef unsigned long rop_operand;
typedef rop_operand (*rop_proc)(P3(rop_operand D, rop_operand S, rop_operand T));
diff --git a/gs/src/gsshade.c b/gs/src/gsshade.c
index 1957e4d84..e9ea9192f 100644
--- a/gs/src/gsshade.c
+++ b/gs/src/gsshade.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,10 +21,13 @@
#include "gx.h"
#include "gscspace.h"
#include "gserrors.h"
-#include "gsstruct.h" /* for extern_st */
+#include "gsstruct.h"
#include "gxdevcli.h"
#include "gxcpath.h"
+#include "gxcspace.h"
+#include "gxdcolor.h" /* for filling background rectangle */
#include "gxistate.h"
+#include "gxpaint.h"
#include "gxpath.h"
#include "gxshade.h"
#include "gzpath.h"
@@ -382,68 +385,134 @@ gs_shading_Tpp_init(gs_shading_t ** ppsh,
/* ================ Shading rendering ================ */
+/* Add a user-space rectangle to a path. */
+private int
+shading_path_add_box(gx_path *ppath, const gs_rect *pbox,
+ const gs_matrix_fixed *pmat)
+{
+ gs_fixed_point pt;
+ gs_fixed_point pts[3];
+ int code;
+
+ if ((code = gs_point_transform2fixed(pmat, pbox->p.x, pbox->p.y,
+ &pt)) < 0 ||
+ (code = gx_path_add_point(ppath, pt.x, pt.y)) < 0 ||
+ (code = gs_point_transform2fixed(pmat, pbox->q.x, pbox->p.y,
+ &pts[0])) < 0 ||
+ (code = gs_point_transform2fixed(pmat, pbox->q.x, pbox->q.y,
+ &pts[1])) < 0 ||
+ (code = gs_point_transform2fixed(pmat, pbox->p.x, pbox->q.y,
+ &pts[2])) < 0 ||
+ (code = gx_path_add_lines(ppath, pts, 3)) < 0
+ )
+ DO_NOTHING;
+ return code;
+}
+
/* Fill a path with a shading. */
int
-gs_shading_fill_path(const gs_shading_t *psh, const gx_path *ppath,
- gx_device *orig_dev, gs_imager_state *pis)
+gs_shading_fill_path(const gs_shading_t *psh, /*const*/ gx_path *ppath,
+ const gs_fixed_rect *prect, gx_device *orig_dev,
+ gs_imager_state *pis, bool fill_background)
{
gs_memory_t *mem = pis->memory;
+ const gs_matrix_fixed *pmat = &pis->ctm;
gx_device *dev = orig_dev;
gs_fixed_rect path_box;
gs_rect rect;
- gx_clip_path *box_clip = 0;
gx_clip_path *path_clip = 0;
- gx_device_clip box_dev, path_dev;
- int code;
-
- if (psh->params.have_BBox) {
- /****** NOT IMPLEMENTED YET *****/
- box_clip = gx_cpath_alloc(mem, "shading_fill_path(box_clip)");
- if (box_clip == 0)
- return_error(gs_error_VMerror);
- /****** APPEND TRANSFORMED BOX ******/
- gx_make_clip_device(&box_dev, &box_dev, &box_clip->rect_list->list);
- box_dev.target = dev;
-#if 0
- dev = &box_dev;
- dev_proc(dev, open_device)(dev);
-#endif
+ bool path_clip_set = false;
+ gx_device_clip path_dev;
+ int code = 0;
+
+ path_clip = gx_cpath_alloc(mem, "shading_fill_path(path_clip)");
+ if (path_clip == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ goto out;
}
dev_proc(dev, get_clipping_box)(dev, &path_box);
- if (ppath) {
- /****** NOT IMPLEMENTED YET *****/
- if (psh->params.Background) {
- /****** FILL BOX WITH BACKGROUND ******/
+ if (prect)
+ rect_intersect(path_box, *prect);
+ if (psh->params.have_BBox) {
+ gs_fixed_rect bbox_fixed;
+
+ if ((is_xxyy(pmat) || is_xyyx(pmat)) &&
+ (code = shade_bbox_transform2fixed(&psh->params.BBox, pis,
+ &bbox_fixed)) >= 0
+ ) {
+ /* We can fold BBox into the clipping rectangle. */
+ rect_intersect(path_box, bbox_fixed);
+ } else
+ {
+ gx_path *box_path;
+
+ if (path_box.p.x >= path_box.q.x || path_box.p.y >= path_box.q.y)
+ goto out; /* empty rectangle */
+ box_path = gx_path_alloc(mem, "shading_fill_path(box_path)");
+ if (box_path == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ goto out;
+ }
+ if ((code = gx_cpath_from_rectangle(path_clip, &path_box)) < 0 ||
+ (code = shading_path_add_box(box_path, &psh->params.BBox,
+ pmat)) < 0 ||
+ (code = gx_cpath_intersect(path_clip, box_path,
+ gx_rule_winding_number, pis)) < 0
+ )
+ DO_NOTHING;
+ gx_path_free(box_path, "shading_fill_path(box_path)");
+ if (code < 0)
+ goto out;
+ path_clip_set = true;
}
- path_clip = gx_cpath_alloc(mem, "shading_fill_path(path_clip)");
- if (path_clip == 0) {
- code = gs_note_error(gs_error_VMerror);
+ }
+ if (!path_clip_set) {
+ if (path_box.p.x >= path_box.q.x || path_box.p.y >= path_box.q.y)
+ goto out; /* empty rectangle */
+ if ((code = gx_cpath_from_rectangle(path_clip, &path_box)) < 0)
+ goto out;
+ }
+ if (ppath &&
+ (code =
+ gx_cpath_intersect(path_clip, ppath, gx_rule_winding_number, pis)) < 0
+ )
+ goto out;
+ gx_make_clip_device(&path_dev, &path_dev, &path_clip->rect_list->list);
+ path_dev.target = dev;
+ dev = (gx_device *)&path_dev;
+ dev_proc(dev, open_device)(dev);
+ dev_proc(dev, get_clipping_box)(dev, &path_box);
+ if (psh->params.Background && fill_background) {
+ int x0 = fixed2int(path_box.p.x);
+ int y0 = fixed2int(path_box.p.y);
+ int x1 = fixed2int(path_box.q.x);
+ int y1 = fixed2int(path_box.q.y);
+ const gs_color_space *pcs = psh->params.ColorSpace;
+ gs_client_color cc;
+ gx_device_color dev_color;
+
+ cc = *psh->params.Background;
+ (*pcs->type->restrict_color)(&cc, pcs);
+ (*pcs->type->remap_color)(&cc, pcs, &dev_color, pis,
+ dev, gs_color_select_texture);
+ /****** WRONG IF NON-IDEMPOTENT RasterOp ******/
+ code = gx_fill_rectangle_device_rop(x0, y0, x1 - x0, y1 - y0,
+ &dev_color, dev, pis->log_op);
+ if (code < 0)
goto out;
- }
- /****** SET CLIP PATH ******/
- gx_make_clip_device(&path_dev, &path_dev, &path_clip->rect_list->list);
- path_dev.target = dev;
-#if 0
- dev = &path_dev;
- dev_proc(dev, open_device)(dev);
- dev_proc(dev, get_clipping_box)(dev, &path_box);
-#endif
}
{
gs_rect path_rect;
- const gs_matrix *pmat = &ctm_only(pis);
path_rect.p.x = fixed2float(path_box.p.x);
path_rect.p.y = fixed2float(path_box.p.y);
path_rect.q.x = fixed2float(path_box.q.x);
path_rect.q.y = fixed2float(path_box.q.y);
- gs_bbox_transform_inverse(&path_rect, pmat, &rect);
+ gs_bbox_transform_inverse(&path_rect, (const gs_matrix *)pmat, &rect);
}
code = psh->head.fill_rectangle(psh, &rect, dev, pis);
out:
if (path_clip)
gx_cpath_free(path_clip, "shading_fill_path(path_clip)");
- if (box_clip)
- gx_cpath_free(box_clip, "shading_fill_path(box_clip)");
return code;
}
diff --git a/gs/src/gsshade.h b/gs/src/gsshade.h
index 162fe65fc..6a7a2abf0 100644
--- a/gs/src/gsshade.h
+++ b/gs/src/gsshade.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,6 +27,7 @@
#include "gsdsrc.h"
#include "gsfunc.h"
#include "gsmatrix.h"
+#include "gxfixed.h"
/* ---------------- Types and structures ---------------- */
@@ -235,15 +236,20 @@ int gs_shading_Tpp_init(P3(gs_shading_t ** ppsh,
gs_memory_t * mem));
/*
- * Fill a path with a shading. This is the only externally accessible
- * procedure for rendering a shading. A NULL path means fill the
- * shading's geometry (shfill).
+ * Fill a path or a (device-space) rectangle with a shading. Both the path
+ * and the rectangle are optional, but at least one must be non-NULL; if
+ * both are specified, the filled region is their intersection. This is the
+ * only externally accessible procedure for rendering a shading.
+ * fill_background indicates whether to fill portions of the path outside
+ * the shading's geometry: it is true for filling with a pattern, false for
+ * shfill.
*/
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
#endif
-int gs_shading_fill_path(P4(const gs_shading_t *psh, const gx_path *ppath,
- gx_device *dev, gs_imager_state *pis));
+int gs_shading_fill_path(P6(const gs_shading_t *psh, /*const*/ gx_path *ppath,
+ const gs_fixed_rect *prect, gx_device *dev,
+ gs_imager_state *pis, bool fill_background));
#endif /* gsshade_INCLUDED */
diff --git a/gs/src/gsstate.c b/gs/src/gsstate.c
index 84c18560f..67febe37d 100644
--- a/gs/src/gsstate.c
+++ b/gs/src/gsstate.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,6 +29,8 @@
#include "gscolor2.h"
#include "gscoord.h" /* for gs_initmatrix */
#include "gscie.h"
+#include "gscssub.h"
+#include "gxclipsr.h"
#include "gxcmap.h"
#include "gxdevice.h"
#include "gxpcache.h"
@@ -38,12 +40,6 @@
#include "gzpath.h"
#include "gzcpath.h"
-/* Imported values */
-/* The following should include a 'const', but for some reason */
-/* the Watcom compiler won't accept it, even though it happily accepts */
-/* the same construct everywhere else. */
-extern /*const */ gx_color_map_procs *const cmap_procs_default;
-
/* Forward references */
private gs_state *gstate_alloc(P3(gs_memory_t *, client_name_t,
const gs_state *));
@@ -77,7 +73,8 @@ private int gstate_copy(P4(gs_state *, const gs_state *,
* (3a) Objects that are logically connected to individual gstates.
* We use reference counting to manage these. Currently these are:
* halftone, dev_ht, cie_render, black_generation,
- * undercolor_removal, set_transfer.*, cie_joint_caches
+ * undercolor_removal, set_transfer.*, cie_joint_caches,
+ * clip_stack
* effective_transfer.* may point to some of the same objects as
* set_transfer.*, but don't contribute to the reference count.
* Similarly, dev_color may point to the dev_ht object. For
@@ -142,10 +139,10 @@ private int gstate_copy(P4(gs_state *, const gs_state *,
* imager state, and device, which must be handled specially.
*/
#define gs_state_do_ptrs(m)\
- m(0,saved) m(1,path) m(2,clip_path) m(3,view_clip) m(4,effective_clip_path)\
- m(5,color_space) m(6,ccolor) m(7,dev_color)\
- m(8,font) m(9,root_font) m(10,show_gstate) /*m(---,device)*/\
- m(11,client_data)
+ m(0,saved) m(1,path) m(2,clip_path) m(3,clip_stack)\
+ m(4,view_clip) m(5,effective_clip_path)\
+ m(6,color_space) m(7,ccolor) m(8,dev_color)\
+ m(9,font) m(10,root_font) m(11,show_gstate) /*m(---,device)*/
#define gs_state_num_ptrs 12
/*
@@ -169,31 +166,9 @@ typedef struct gs_state_parts_s {
(pto)->ccolor = (pfrom)->ccolor, (pto)->dev_color = (pfrom)->dev_color)
/* GC descriptors */
-private_st_line_params();
-private_st_imager_state();
-private_st_imager_state_shared();
+extern_st(st_imager_state);
private_st_gs_state();
-/* GC procedures for gs_imager_state */
-#define pis ((gs_imager_state *)vptr)
-private
-ENUM_PTRS_BEGIN(imager_state_enum_ptrs) ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
-
-ENUM_PTR(0, gs_imager_state, shared);
-#define e1(i,elt) ENUM_PTR(i+1,gs_imager_state,elt);
-gs_cr_state_do_ptrs(e1)
-#undef e1
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
-{
- RELOC_SUPER(gs_imager_state, st_line_params, line_params);
- RELOC_PTR(gs_imager_state, shared);
-#define r1(i,elt) RELOC_PTR(gs_imager_state,elt);
- gs_cr_state_do_ptrs(r1)
-#undef r1
-} RELOC_PTRS_END
-#undef pis
-
/* GC procedures for gs_state */
#define gsvptr ((gs_state *)vptr)
private ENUM_PTRS_BEGIN(gs_state_enum_ptrs) ENUM_PREFIX(st_imager_state, gs_state_num_ptrs + 1);
@@ -210,7 +185,7 @@ private RELOC_PTRS_BEGIN(gs_state_reloc_ptrs)
#define r1(i,elt) RELOC_PTR(gs_state,elt);
gs_state_do_ptrs(r1)
#undef r1
- gsvptr->device = gx_device_reloc_ptr(gsvptr->device, gcst);
+ gsvptr->device = gx_device_reloc_ptr(gsvptr->device, gcst);
}
}
RELOC_PTRS_END
@@ -229,150 +204,47 @@ gstate_copy_client_data(gs_state * pgs, void *dto, void *dfrom,
/* ------ Operations on the entire graphics state ------ */
-/* Initialize an imager state, other than the parts covered by */
-/* gs_imager_state_initial. */
-/* The halftone, dev_ht, and ht_cache elements are not set or used. */
-private float
-null_transfer(floatp gray, const gx_transfer_map * pmap)
-{
- return gray;
-}
-private void
-rc_free_imager_shared(gs_memory_t * mem, void *data, client_name_t cname)
-{
- gs_imager_state_shared_t * const shared =
- (gs_imager_state_shared_t *)data;
-
- if (shared->cs_DeviceCMYK) {
- gs_cspace_release(shared->cs_DeviceCMYK);
- gs_free_object(mem, shared->cs_DeviceCMYK, "shared DeviceCMYK");
- }
- if (shared->cs_DeviceRGB) {
- gs_cspace_release(shared->cs_DeviceRGB);
- gs_free_object(mem, shared->cs_DeviceRGB, "shared DeviceRGB");
- }
- if (shared->cs_DeviceGray) {
- gs_cspace_release(shared->cs_DeviceGray);
- gs_free_object(mem, shared->cs_DeviceGray, "shared DeviceGray");
- }
- rc_free_struct_only(mem, data, cname);
-}
-
-int
-gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
-{
- pis->memory = mem;
- /* Preallocate color spaces. */
- {
- int code;
- gs_imager_state_shared_t *shared;
-
- rc_alloc_struct_1(shared, gs_imager_state_shared_t,
- &st_imager_state_shared, mem,
- return_error(gs_error_VMerror),
- "gs_imager_state_init(shared)");
- shared->cs_DeviceGray = shared->cs_DeviceRGB =
- shared->cs_DeviceCMYK = 0; /* in case we bail out */
- shared->rc.free = rc_free_imager_shared;
- if ((code = gs_cspace_build_DeviceGray(&shared->cs_DeviceGray, mem)) < 0 ||
- (code = gs_cspace_build_DeviceRGB(&shared->cs_DeviceRGB, mem)) < 0 ||
- (code = gs_cspace_build_DeviceCMYK(&shared->cs_DeviceCMYK, mem)) < 0
- ) {
- rc_free_imager_shared(mem, shared, "gs_imager_state_init(shared)");
- return code;
- }
- pis->shared = shared;
- }
- /* Skip halftone */
- {
- int i;
-
- for (i = 0; i < gs_color_select_count; ++i)
- pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
- }
- /* Skip dev_ht */
- /* Skip ht_cache */
- pis->cie_render = 0;
- pis->black_generation = 0;
- pis->undercolor_removal = 0;
- /* Allocate an initial transfer map. */
- rc_alloc_struct_n(pis->set_transfer.colored.gray,
- gx_transfer_map, &st_transfer_map,
- mem, return_error(gs_error_VMerror),
- "gs_imager_state_init(transfer)", 4);
- pis->set_transfer.colored.gray->proc = null_transfer;
- pis->set_transfer.colored.gray->id = gs_next_ids(1);
- pis->set_transfer.colored.gray->values[0] = frac_0;
- pis->set_transfer.colored.red =
- pis->set_transfer.colored.green =
- pis->set_transfer.colored.blue =
- pis->set_transfer.colored.gray;
- pis->effective_transfer = pis->set_transfer;
- pis->cie_joint_caches = 0;
- pis->cmap_procs = cmap_procs_default;
- pis->pattern_cache = 0;
- return 0;
-}
-
-/* Release an imager state. */
-void
-gs_imager_state_release(gs_imager_state * pis)
-{
- const char *const cname = "gs_imager_state_release";
-
-#define RCDECR(element)\
- rc_decrement(pis->element, cname)
-
- RCDECR(cie_joint_caches);
- RCDECR(set_transfer.colored.gray);
- RCDECR(set_transfer.colored.blue);
- RCDECR(set_transfer.colored.green);
- RCDECR(set_transfer.colored.red);
- RCDECR(undercolor_removal);
- RCDECR(black_generation);
- RCDECR(cie_render);
- RCDECR(shared);
-#undef RCDECR
-}
-
/* Allocate and initialize a graphics state. */
gs_state *
gs_state_alloc(gs_memory_t * mem)
{
gs_state *pgs = gstate_alloc(mem, "gs_state_alloc", NULL);
+ int code;
if (pgs == 0)
return 0;
+ pgs->saved = 0;
{
- static const gs_imager_state gstate_initial =
- {
+ static const gs_imager_state gstate_initial = {
gs_imager_state_initial(1.0)
};
*(gs_imager_state *) pgs = gstate_initial;
}
+
/*
* Just enough of the state is initialized at this point
* that it's OK to call gs_state_free if an allocation fails.
*/
- rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem,
- goto fail, "gs_state_alloc(halftone)");
- pgs->saved = 0;
- /* Initialize the color rendering state. */
+ code = gs_imager_state_initialize((gs_imager_state *) pgs, mem);
+ if (code < 0)
+ goto fail;
+
+ /* Finish initializing the color rendering state. */
+ rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem,
+ goto fail, "gs_state_alloc(halftone)");
pgs->halftone->type = ht_type_none;
- pgs->dev_ht = 0;
pgs->ht_cache = gx_ht_alloc_cache(mem,
gx_ht_cache_default_tiles(),
gx_ht_cache_default_bits());
- gs_imager_state_initialize((gs_imager_state *) pgs, mem);
- pgs->client_data = 0;
/* Initialize other things not covered by initgraphics */
pgs->path = gx_path_alloc(mem, "gs_state_alloc(path)");
pgs->clip_path = gx_cpath_alloc(mem, "gs_state_alloc(clip_path)");
+ pgs->clip_stack = 0;
pgs->view_clip = gx_cpath_alloc(mem, "gs_state_alloc(view_clip)");
pgs->view_clip->rule = 0; /* no clipping */
pgs->effective_clip_id = pgs->clip_path->id;
@@ -381,12 +253,18 @@ gs_state_alloc(gs_memory_t * mem)
pgs->effective_clip_shared = true;
/* Initialize things so that gx_remap_color won't crash. */
gs_cspace_init_DeviceGray(pgs->color_space);
+ {
+ int i;
+
+ for (i = 0; i < countof(pgs->device_color_spaces.indexed); ++i)
+ pgs->device_color_spaces.indexed[i] = 0;
+ }
gx_set_device_color_1(pgs);
pgs->overprint = false;
pgs->device = 0; /* setting device adjusts refcts */
gs_nulldevice(pgs);
gs_setalpha(pgs, 1.0);
- gs_settransfer(pgs, null_transfer);
+ gs_settransfer(pgs, gs_identity_transfer);
gs_setflat(pgs, 1.0);
gs_setfilladjust(pgs, 0.25, 0.25);
gs_setlimitclamp(pgs, false);
@@ -398,13 +276,10 @@ gs_state_alloc(gs_memory_t * mem)
pgs->in_charpath = (gs_char_path_mode) 0;
pgs->show_gstate = 0;
pgs->level = 0;
- pgs->client_data = 0;
- if (gs_initgraphics(pgs) < 0) {
- /* Something went very wrong */
- return 0;
- }
- return pgs;
- fail:
+ if (gs_initgraphics(pgs) >= 0)
+ return pgs;
+ /* Something went very wrong. */
+fail:
gs_state_free(pgs);
return 0;
}
@@ -445,6 +320,13 @@ gs_gsave(gs_state * pgs)
if (pnew == 0)
return_error(gs_error_VMerror);
+ /*
+ * It isn't clear from the Adobe documentation whether gsave retains
+ * the current clip stack or clears it. The following statement
+ * bets on the latter. If it's the former, this should become
+ * rc_increment(pnew->clip_stack);
+ */
+ pnew->clip_stack = 0;
pgs->saved = pnew;
if (pgs->show_gstate == pgs)
pgs->show_gstate = pnew->show_gstate = pnew;
@@ -454,15 +336,19 @@ gs_gsave(gs_state * pgs)
return 0;
}
-/* Save the graphics state for a 'save'. */
-/* We cut the stack below the new gstate, and return the old one. */
-/* In addition to an ordinary gsave, we create a new view clip path. */
+/*
+ * Save the graphics state for a 'save'.
+ * We cut the stack below the new gstate, and return the old one.
+ * In addition to an ordinary gsave, we create a new view clip path.
+ */
int
gs_gsave_for_save(gs_state * pgs, gs_state ** psaved)
{
int code;
gx_clip_path *old_cpath = pgs->view_clip;
gx_clip_path *new_cpath;
+ gx_device_color_spaces_t save_spaces;
+ int i;
if (old_cpath) {
new_cpath =
@@ -474,10 +360,28 @@ gs_gsave_for_save(gs_state * pgs, gs_state ** psaved)
new_cpath = 0;
}
code = gs_gsave(pgs);
- if (code < 0) {
- if (new_cpath)
- gx_cpath_free(new_cpath, "gs_gsave_for_save(view_clip)");
- return code;
+ if (code < 0)
+ goto fail;
+ for (i = 0; i < countof(save_spaces.indexed); ++i) {
+ gs_color_space *pcs = pgs->device_color_spaces.indexed[i];
+
+ if (pcs) {
+ pgs->device_color_spaces.indexed[i] = 0;
+ code = gs_setsubstitutecolorspace(pgs, (gs_color_space_index)i,
+ pcs);
+ if (code < 0) {
+ /*
+ * Patch the second saved pointer so we won't try to
+ * gsave after the grestore.
+ */
+ if (pgs->saved->saved == 0)
+ pgs->saved->saved = pgs;
+ gs_grestore(pgs);
+ if (pgs->saved == pgs)
+ pgs->saved = 0;
+ goto fail;
+ }
+ }
}
if (pgs->effective_clip_path == pgs->view_clip)
pgs->effective_clip_path = new_cpath;
@@ -486,6 +390,10 @@ gs_gsave_for_save(gs_state * pgs, gs_state ** psaved)
*psaved = pgs->saved;
pgs->saved = 0;
return code;
+fail:
+ if (new_cpath)
+ gx_cpath_free(new_cpath, "gs_gsave_for_save(view_clip)");
+ return code;
}
/* Restore the graphics state. */
@@ -524,6 +432,7 @@ int
gs_grestoreall_for_restore(gs_state * pgs, gs_state * saved)
{
int code;
+ gx_device_color_spaces_t freed_spaces;
while (pgs->saved->saved) {
code = gs_grestore(pgs);
@@ -535,9 +444,12 @@ gs_grestoreall_for_restore(gs_state * pgs, gs_state * saved)
if (pgs->pattern_cache)
(*pgs->pattern_cache->free_all) (pgs->pattern_cache);
pgs->saved->saved = saved;
+ freed_spaces = pgs->device_color_spaces;
code = gs_grestore(pgs);
if (code < 0)
return code;
+ gx_device_color_spaces_free(&freed_spaces, pgs->memory,
+ "gs_grestoreall_for_restore");
if (pgs->view_clip) {
gx_cpath_free(pgs->view_clip, "gs_grestoreall_for_restore");
pgs->view_clip = 0;
@@ -550,37 +462,41 @@ gs_grestoreall_for_restore(gs_state * pgs, gs_state * saved)
int
gs_grestoreall(gs_state * pgs)
{
- int code;
-
if (!pgs->saved) /* shouldn't happen */
return gs_gsave(pgs);
while (pgs->saved->saved) {
- code = gs_grestore(pgs);
+ int code = gs_grestore(pgs);
+
if (code < 0)
return code;
}
- code = gs_grestore(pgs);
- if (code < 0)
- return code;
- return code;
+ return gs_grestore(pgs);
}
/* Allocate and return a new graphics state. */
gs_state *
gs_gstate(gs_state * pgs)
{
- return gs_state_copy(pgs, pgs->memory);
+ gs_state *copied = gs_state_copy(pgs, pgs->memory);
+ int i;
+
+ if (copied == 0)
+ return 0;
+ /* Don't capture the substituted color spaces. */
+ for (i = 0; i < countof(copied->device_color_spaces.indexed); ++i)
+ copied->device_color_spaces.indexed[i] = 0;
+ return copied;
}
gs_state *
gs_state_copy(gs_state * pgs, gs_memory_t * mem)
{
gs_state *pnew;
-
/* Prevent 'capturing' the view clip path. */
gx_clip_path *view_clip = pgs->view_clip;
pgs->view_clip = 0;
pnew = gstate_clone(pgs, mem, "gs_gstate", copy_for_gstate);
+ rc_increment(pnew->clip_stack);
pgs->view_clip = view_clip;
if (pnew == 0)
return 0;
@@ -608,7 +524,7 @@ int
gs_currentgstate(gs_state * pto, const gs_state * pgs)
{
int code =
- gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate");
+ gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate");
if (code >= 0)
pto->view_clip = 0;
@@ -807,7 +723,7 @@ private gs_state *
gstate_alloc(gs_memory_t * mem, client_name_t cname, const gs_state * pfrom)
{
gs_state *pgs =
- gs_alloc_struct(mem, gs_state, &st_gs_state, cname);
+ gs_alloc_struct(mem, gs_state, &st_gs_state, cname);
if (pgs == 0)
return 0;
@@ -860,16 +776,8 @@ gstate_clone(gs_state * pfrom, gs_memory_t * mem, client_name_t cname,
)
goto fail;
}
- rc_increment(pgs->set_transfer.colored.gray);
- rc_increment(pgs->set_transfer.colored.red);
- rc_increment(pgs->set_transfer.colored.green);
- rc_increment(pgs->set_transfer.colored.blue);
- rc_increment(pgs->halftone);
- rc_increment(pgs->dev_ht);
- rc_increment(pgs->cie_render);
- rc_increment(pgs->black_generation);
- rc_increment(pgs->undercolor_removal);
- rc_increment(pgs->cie_joint_caches);
+ gs_imager_state_copied((gs_imager_state *)pgs);
+ /* Don't do anything to clip_stack. */
rc_increment(pgs->device);
*parts.color_space = *pfrom->color_space;
*parts.ccolor = *pfrom->ccolor;
@@ -900,39 +808,16 @@ private void
gstate_free_contents(gs_state * pgs)
{
gs_memory_t *mem = pgs->memory;
- gx_device_halftone *pdht = pgs->dev_ht;
const char *const cname = "gstate_free_contents";
-#define RCDECR(element)\
- rc_decrement(pgs->element, cname)
-
- RCDECR(device);
- RCDECR(cie_joint_caches);
- RCDECR(set_transfer.colored.gray);
- RCDECR(set_transfer.colored.blue);
- RCDECR(set_transfer.colored.green);
- RCDECR(set_transfer.colored.red);
- RCDECR(undercolor_removal);
- RCDECR(black_generation);
- RCDECR(cie_render);
- if (pdht != 0 && pdht->rc.ref_count == 1) {
- /* Make sure we don't leave dangling pointers in the cache. */
- gx_ht_cache *pcache = pgs->ht_cache;
-
- if (pcache->order.bits == pdht->order.bits ||
- pcache->order.levels == pdht->order.levels
- )
- gx_ht_clear_cache(pcache);
- gx_device_halftone_release(pdht, pdht->rc.memory);
- }
- RCDECR(dev_ht);
- RCDECR(halftone);
+ rc_decrement(pgs->device, cname);
+ rc_decrement(pgs->clip_stack, cname);
cs_adjust_counts(pgs, -1);
if (pgs->client_data != 0)
(*pgs->client_procs.free) (pgs->client_data, mem);
gs_free_object(mem, pgs->line_params.dash.pattern, cname);
gstate_free_parts(pgs, mem, cname);
-#undef RCDECR
+ gs_imager_state_release((gs_imager_state *)pgs);
}
/* Copy one gstate to another. */
@@ -941,8 +826,10 @@ gstate_copy(gs_state * pto, const gs_state * pfrom,
gs_state_copy_reason_t reason, client_name_t cname)
{
gs_state_parts parts;
+ gx_device_color_spaces_t saved_spaces;
GSTATE_ASSIGN_PARTS(&parts, pto);
+ saved_spaces = pto->device_color_spaces;
/* Copy the dash pattern if necessary. */
if (pfrom->line_params.dash.pattern || pto->line_params.dash.pattern) {
int code = gstate_copy_dash(pto, pfrom);
@@ -982,16 +869,7 @@ gstate_copy(gs_state * pto, const gs_state * pfrom,
#define RCCOPY(element)\
rc_pre_assign(pto->element, pfrom->element, cname)
RCCOPY(device);
- RCCOPY(cie_joint_caches);
- RCCOPY(set_transfer.colored.gray);
- RCCOPY(set_transfer.colored.blue);
- RCCOPY(set_transfer.colored.green);
- RCCOPY(set_transfer.colored.red);
- RCCOPY(undercolor_removal);
- RCCOPY(black_generation);
- RCCOPY(cie_render);
- RCCOPY(dev_ht);
- RCCOPY(halftone);
+ RCCOPY(clip_stack);
{
struct gx_pattern_cache_s *pcache = pto->pattern_cache;
void *pdata = pto->client_data;
@@ -999,6 +877,8 @@ gstate_copy(gs_state * pto, const gs_state * pfrom,
gs_state *saved = pto->saved;
float *pattern = pto->line_params.dash.pattern;
+ gs_imager_state_pre_assign((gs_imager_state *)pto,
+ (gs_imager_state *)pfrom);
*pto = *pfrom;
pto->client_data = pdata;
pto->memory = mem;
@@ -1013,6 +893,7 @@ gstate_copy(gs_state * pto, const gs_state * pfrom,
}
}
GSTATE_ASSIGN_PARTS(pto, &parts);
+ pto->device_color_spaces = saved_spaces;
#undef RCCOPY
pto->show_gstate =
(pfrom->show_gstate == pfrom ? pto : 0);
diff --git a/gs/src/gsstruct.h b/gs/src/gsstruct.h
index b63880a72..0632f2351 100644
--- a/gs/src/gsstruct.h
+++ b/gs/src/gsstruct.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,8 @@
#ifndef gsstruct_INCLUDED
# define gsstruct_INCLUDED
+#include "gsstype.h"
+
/*
* Ghostscript structures are defined with names of the form (gs_)xxx_s,
* with a corresponding typedef of the form (gs_)xxx or (gs_)xxx_t.
@@ -46,13 +48,7 @@
* structure descriptors; if the definer of a structure wants to make
* available the ability to create an instance but does not want to
* expose the structure definition, it must export a creator procedure.
- *
- * Because of bugs in some compilers' bookkeeping for undefined structure
- * types, any file that uses extern_st must include gsstruct.h.
- * (If it weren't for these bugs, the definition of extern_st could
- * go in gsmemory.h.)
*/
-#define extern_st(st) extern const gs_memory_struct_type_t st
/*
* If the structure is defined in a .c file, we require that the following
* appear together:
@@ -90,12 +86,8 @@
#ifndef obj_header_DEFINED
# define obj_header_DEFINED
typedef struct obj_header_s obj_header_t;
-
#endif
-/* Define an opaque type for the garbage collector state. */
-typedef struct gc_state_s gc_state_t;
-
/*
* Define pointer types, which define how to mark the referent of the
* pointer.
@@ -186,80 +178,9 @@ typedef struct gc_procs_common_s {
#define gc_proc(gcst, proc) ((*(const gc_procs_common_t **)(gcst))->proc)
-/*
- * The first argument of enum_ptrs procedures is logically const *.
- * Unfortunately, actually declaring it as such would produce many compiler
- * warnings from places that cast this argument to a non-const non-void
- * pointer type. For the moment, we define EV_CONST as empty, with the
- * intention of changing it to const at some future time.
- */
-/*#define EV_CONST const */
-#define EV_CONST /* */
-
-/* Define the procedures for structure types. */
-
- /* Clear the marks of a structure. */
-
-#define struct_proc_clear_marks(proc)\
- void proc(P3(void /*obj_header_t*/ *pre, uint size,\
- const gs_memory_struct_type_t *pstype))
-
- /* Enumerate the pointers in a structure. */
-
-#define struct_proc_enum_ptrs(proc)\
- gs_ptr_type_t proc(P6(EV_CONST void /*obj_header_t*/ *ptr, uint size,\
- int index, const void **pep, const gs_memory_struct_type_t *pstype,\
- gc_state_t *gcst))
-
- /* Relocate all the pointers in this structure. */
-
-#define struct_proc_reloc_ptrs(proc)\
- void proc(P4(void /*obj_header_t*/ *ptr, uint size,\
- const gs_memory_struct_type_t *pstype, gc_state_t *gcst))
-
- /*
- * Finalize this structure just before freeing it.
- * Finalization procedures must not allocate or resize
- * any objects in any space managed by the allocator,
- * and must not assume that any objects in such spaces
- * referenced by this structure still exist. However,
- * finalization procedures may free such objects, and
- * may allocate, free, and reference objects allocated
- * in other ways, such as objects allocated with malloc
- * by libraries.
- */
-
-#define struct_proc_finalize(proc)\
- void proc(P1(void /*obj_header_t*/ *ptr))
-
-/*
- * A descriptor for an object (structure) type.
- */
-typedef struct struct_shared_procs_s struct_shared_procs_t;
-
-struct gs_memory_struct_type_s {
- uint ssize;
- struct_name_t sname;
-
- /* ------ Procedures shared among many structure types. ------ */
- /* Note that this pointer is usually 0. */
-
- const struct_shared_procs_t *shared;
-
- /* ------ Procedures specific to this structure type. ------ */
-
- struct_proc_clear_marks((*clear_marks));
- struct_proc_enum_ptrs((*enum_ptrs));
- struct_proc_reloc_ptrs((*reloc_ptrs));
- struct_proc_finalize((*finalize));
-
- /* A pointer to additional data for the above procedures. */
-
- const void *proc_data;
-
-};
-
+/* Define the accessor for structure type names. */
#define struct_type_name_string(pstype) ((const char *)((pstype)->sname))
+
/* Default pointer processing */
struct_proc_enum_ptrs(gs_no_struct_enum_ptrs);
struct_proc_reloc_ptrs(gs_no_struct_reloc_ptrs);
@@ -311,8 +232,7 @@ extern_st(st_const_string_element);
typedef enum {
GC_ELT_OBJ, /* obj * or const obj * */
GC_ELT_STRING, /* gs_string */
- GC_ELT_CONST_STRING, /* gs_const_string */
- GC_ELT_REF
+ GC_ELT_CONST_STRING /* gs_const_string */
} gc_ptr_type_index_t;
typedef struct gc_ptr_element_s {
@@ -330,8 +250,6 @@ typedef struct gc_ptr_element_s {
{ GC_ELT_STRING, offset_of(typ, elt) }
#define GC_CONST_STRING_ELT(typ, elt)\
{ GC_ELT_CONST_STRING, offset_of(typ, elt) }
-#define GC_REF_ELT(typ, elt)\
- { GC_ELT_REF, offset_of(typ, elt) }
/* Define the complete table of descriptor data. */
@@ -384,12 +302,15 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
* defining this kind of structure conveniently, either all at once in
* the structure definition macro, or using the following template:
- ENUM_PTRS_BEGIN(xxx_enum_ptrs) return 0;
+ ENUM_PTRS_WITH(xxx_enum_ptrs, stype *myptr) return 0;
... ENUM_PTR(i, xxx, elt); ...
ENUM_PTRS_END
- RELOC_PTRS_BEGIN(xxx_reloc_ptrs) ;
- ... RELOC_PTR(xxx, elt) ...
- RELOC_PTRS_END
+ RELOC_PTRS_WITH(xxx_reloc_ptrs, stype *myptr)
+ {
+ ...
+ RELOC_VAR(myptr->elt);
+ ...
+ }
*/
/*
@@ -409,7 +330,11 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
gs_ptr_type_t proc(vptr, size, index, pep, pstype, gcst) EV_CONST void *vptr; uint size; int index; const void **pep; const gs_memory_struct_type_t *pstype; gc_state_t *gcst;
#endif
#define ENUM_PTRS_BEGIN(proc)\
- ENUM_PTRS_BEGIN_PROC(proc) { switch ( index ) { default:
+ ENUM_PTRS_BEGIN_PROC(proc)\
+ { switch ( index ) { default:
+#define ENUM_PTRS_WITH(proc, stype_ptr)\
+ ENUM_PTRS_BEGIN_PROC(proc)\
+ { EV_CONST stype_ptr = vptr; switch ( index ) { default:
/* Enumerate elements */
@@ -419,6 +344,14 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
(*pep = (const void *)(ptr), ptr_string_type)
#define ENUM_CONST_STRING(ptr) /* pointer to gs_const_string */\
(*pep = (const void *)(ptr), ptr_const_string_type)
+extern gs_ptr_type_t
+ enum_bytestring(P2(const void **pep, const gs_bytestring *pbs));
+#define ENUM_BYTESTRING(ptr) /* pointer to gs_bytestring */\
+ enum_bytestring(pep, ptr)
+extern gs_ptr_type_t
+ enum_const_bytestring(P2(const void **pep, const gs_const_bytestring *pbs));
+#define ENUM_CONST_BYTESTRING(ptr) /* pointer to gs_const_bytestring */\
+ enum_const_bytestring(pep, ptr)
#define ENUM_OBJ_ELT(typ, elt)\
ENUM_OBJ(((const typ *)vptr)->elt)
@@ -451,6 +384,8 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
# define RELOC_PTRS_BEGIN(proc)\
void proc(vptr, size, pstype, gcst) void *vptr; uint size; const gs_memory_struct_type_t *pstype; gc_state_t *gcst; {
#endif
+#define RELOC_PTRS_WITH(proc, stype_ptr)\
+ RELOC_PTRS_BEGIN(proc) stype_ptr = vptr;
/* Relocate elements */
@@ -458,10 +393,18 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
(gc_proc(gcst, reloc_struct_ptr)((const void *)(ptr), gcst))
#define RELOC_OBJ_VAR(ptrvar)\
(ptrvar = RELOC_OBJ(ptrvar))
+#define RELOC_VAR(ptrvar) /* a handy abbreviation */\
+ RELOC_OBJ_VAR(ptrvar)
#define RELOC_STRING_VAR(ptrvar)\
(gc_proc(gcst, reloc_string)(&(ptrvar), gcst))
#define RELOC_CONST_STRING_VAR(ptrvar)\
(gc_proc(gcst, reloc_const_string)(&(ptrvar), gcst))
+extern void reloc_bytestring(P2(gs_bytestring *pbs, gc_state_t *gcst));
+#define RELOC_BYTESTRING_VAR(ptrvar)\
+ reloc_bytestring(&(ptrvar), gcst)
+extern void reloc_const_bytestring(P2(gs_const_bytestring *pbs, gc_state_t *gcst));
+#define RELOC_CONST_BYTESTRING_VAR(ptrvar)\
+ reloc_const_bytestring(&(ptrvar), gcst)
#define RELOC_OBJ_ELT(typ, elt)\
RELOC_VAR(((typ *)vptr)->elt)
@@ -482,8 +425,6 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
/* Backward compatibility */
-#define RELOC_VAR(ptrvar)\
- RELOC_OBJ_VAR(ptrvar)
#define RELOC_PTR(typ, elt)\
RELOC_OBJ_ELT(typ, elt)
#define RELOC_PTR3(typ, e1, e2, e3) /* just an abbreviation */\
@@ -515,8 +456,11 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
* 'by hand' may use this also.
*/
+#define ENUM_USING_PREFIX(supst, n)\
+ ENUM_USING(supst, vptr, size, index-(n))
+
#define ENUM_PREFIX(supst, n)\
- return ENUM_USING(supst, vptr, size, index-(n))
+ return ENUM_USING_PREFIX(supst, n)
#define RELOC_PREFIX(supst)\
RELOC_USING(supst, vptr, size)
@@ -597,13 +541,22 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs);
#define gs_private_st_composite(stname, stype, sname, penum, preloc)\
gs__st_composite(private_st, stname, stype, sname, penum, preloc)
- /* Composite structures with finalization. */
+ /* Composite structures with inherited finalization. */
-#define gs__st_composite_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
+#define gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
private struct_proc_enum_ptrs(penum);\
private struct_proc_reloc_ptrs(preloc);\
- private struct_proc_finalize(pfinal);\
gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, pfinal)
+#define gs_public_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
+ gs__st_composite_use_final(public_st, stname, stype, sname, penum, preloc, pfinal)
+#define gs_private_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
+ gs__st_composite_use_final(private_st, stname, stype, sname, penum, preloc, pfinal)
+
+ /* Composite structures with finalization. */
+
+#define gs__st_composite_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
+ private struct_proc_finalize(pfinal);\
+ gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)
#define gs_public_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
gs__st_composite_final(public_st, stname, stype, sname, penum, preloc, pfinal)
#define gs_private_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
diff --git a/gs/src/gsstype.h b/gs/src/gsstype.h
new file mode 100644
index 000000000..23e822a24
--- /dev/null
+++ b/gs/src/gsstype.h
@@ -0,0 +1,108 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definition of structure type descriptors and extern_st */
+
+#ifndef gsstype_INCLUDED
+# define gsstype_INCLUDED
+
+/* Define an opaque type for the garbage collector state. */
+typedef struct gc_state_s gc_state_t;
+
+/*
+ * The first argument of enum_ptrs procedures is logically const *.
+ * Unfortunately, actually declaring it as such would produce many compiler
+ * warnings from places that cast this argument to a non-const non-void
+ * pointer type. For the moment, we define EV_CONST as empty, with the
+ * intention of changing it to const at some future time.
+ */
+/*#define EV_CONST const */
+#define EV_CONST /* */
+
+/* Define the procedures for structure types. */
+
+ /* Clear the marks of a structure. */
+
+#define struct_proc_clear_marks(proc)\
+ void proc(P3(void /*obj_header_t*/ *pre, uint size,\
+ const gs_memory_struct_type_t *pstype))
+
+ /* Enumerate the pointers in a structure. */
+
+#define struct_proc_enum_ptrs(proc)\
+ gs_ptr_type_t proc(P6(EV_CONST void /*obj_header_t*/ *ptr, uint size,\
+ int index, const void **pep, const gs_memory_struct_type_t *pstype,\
+ gc_state_t *gcst))
+
+ /* Relocate all the pointers in this structure. */
+
+#define struct_proc_reloc_ptrs(proc)\
+ void proc(P4(void /*obj_header_t*/ *ptr, uint size,\
+ const gs_memory_struct_type_t *pstype, gc_state_t *gcst))
+
+ /*
+ * Finalize this structure just before freeing it.
+ * Finalization procedures must not allocate or resize
+ * any objects in any space managed by the allocator,
+ * and must not assume that any objects in such spaces
+ * referenced by this structure still exist. However,
+ * finalization procedures may free such objects, and
+ * may allocate, free, and reference objects allocated
+ * in other ways, such as objects allocated with malloc
+ * by libraries.
+ */
+
+#define struct_proc_finalize(proc)\
+ void proc(P1(void /*obj_header_t*/ *ptr))
+
+/*
+ * A descriptor for an object (structure) type.
+ */
+typedef struct struct_shared_procs_s struct_shared_procs_t;
+
+struct gs_memory_struct_type_s {
+ uint ssize;
+ struct_name_t sname;
+
+ /* ------ Procedures shared among many structure types. ------ */
+ /* Note that this pointer is usually 0. */
+
+ const struct_shared_procs_t *shared;
+
+ /* ------ Procedures specific to this structure type. ------ */
+
+ struct_proc_clear_marks((*clear_marks));
+ struct_proc_enum_ptrs((*enum_ptrs));
+ struct_proc_reloc_ptrs((*reloc_ptrs));
+ struct_proc_finalize((*finalize));
+
+ /* A pointer to additional data for the above procedures. */
+
+ const void *proc_data;
+};
+
+/*
+ * Because of bugs in some compilers' bookkeeping for undefined structure
+ * types, any file that uses extern_st must include this file.
+ * (If it weren't for these bugs, the definition of extern_st could
+ * go in gsmemory.h.)
+ */
+#define extern_st(st) extern const gs_memory_struct_type_t st
+
+#endif /* gsstype_INCLUDED */
diff --git a/gs/src/gstext.c b/gs/src/gstext.c
index a008e2db1..a4a419c3b 100644
--- a/gs/src/gstext.c
+++ b/gs/src/gstext.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -92,15 +92,18 @@ RELOC_PTRS_END
#define eptr ((gs_text_enum_t *)vptr)
-private ENUM_PTRS_BEGIN(text_enum_enum_ptrs) ENUM_USING(st_gs_text_params, &eptr->text, sizeof(eptr->text), index - 1);
-case 0:
-return ENUM_OBJ(gx_device_enum_ptr(eptr->dev));
+private ENUM_PTRS_BEGIN(text_enum_enum_ptrs) ENUM_USING(st_gs_text_params, &eptr->text, sizeof(eptr->text), index - 7);
+case 0: return ENUM_OBJ(gx_device_enum_ptr(eptr->dev));
+ENUM_PTR3(1, gs_text_enum_t, pis, orig_font, path);
+ENUM_PTR3(4, gs_text_enum_t, pdcolor, pcpath, current_font);
ENUM_PTRS_END
private RELOC_PTRS_BEGIN(text_enum_reloc_ptrs)
{
RELOC_USING(st_gs_text_params, &eptr->text, sizeof(eptr->text));
gx_device_reloc_ptr(eptr->dev, gcst);
+ RELOC_PTR3(gs_text_enum_t, pis, orig_font, path);
+ RELOC_PTR3(gs_text_enum_t, pdcolor, pcpath, current_font);
}
RELOC_PTRS_END
@@ -121,18 +124,27 @@ gx_device_text_begin(gx_device * dev, gs_imager_state * pis,
gx_path *tpath =
((text->operation & TEXT_DO_NONE) &&
!(text->operation & TEXT_RETURN_WIDTH) ? 0 : path);
- int code =
- (*dev_proc(dev, text_begin))
- (dev, pis, text, font, tpath,
- (text->operation & TEXT_DO_DRAW ? pdcolor : 0),
- (text->operation & TEXT_DO_DRAW ? pcpath : 0),
- mem, ppte);
+ const gx_device_color *tcolor =
+ (text->operation & TEXT_DO_DRAW ? pdcolor : 0);
+ const gx_clip_path *tcpath =
+ (text->operation & TEXT_DO_DRAW ? pcpath : 0);
+ int code = dev_proc(dev, text_begin)
+ (dev, pis, text, font, tpath, tcolor, tcpath, mem, ppte);
gs_text_enum_t *pte = *ppte;
if (code < 0)
return code;
pte->text = *text;
pte->dev = dev;
+ pte->pis = pis;
+ pte->orig_font = font;
+ pte->path = tpath;
+ pte->pdcolor = tcolor;
+ pte->pcpath = tcpath;
+ pte->memory = mem;
+ /* text_begin procedure sets procs, rc */
+ pte->current_font = font;
+ pte->scale.x = pte->scale.y = 0;
pte->index = 0;
return code;
}
@@ -228,16 +240,17 @@ gs_kshow_begin(gs_state * pgs, const byte * str, uint size,
int
gs_xyshow_begin(gs_state * pgs, const byte * str, uint size,
const float *x_widths, const float *y_widths,
- gs_memory_t * mem, gs_text_enum_t ** ppte)
+ uint widths_size, gs_memory_t * mem, gs_text_enum_t ** ppte)
{
gs_text_params_t text;
text.operation = TEXT_FROM_STRING |
TEXT_REPLACE_X_WIDTHS | TEXT_REPLACE_Y_WIDTHS |
- TEXT_DO_DRAW | TEXT_INTERVENE | TEXT_RETURN_WIDTH;
+ TEXT_DO_DRAW | TEXT_RETURN_WIDTH;
text.data.bytes = str, text.size = size;
text.x_widths = x_widths;
text.y_widths = y_widths;
+ text.widths_size = widths_size;
return gs_text_begin(pgs, &text, mem, ppte);
}
int
@@ -246,9 +259,9 @@ gs_glyphshow_begin(gs_state * pgs, gs_glyph glyph,
{
gs_text_params_t text;
- /****** SET glyphs ******/
+ text.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_DO_DRAW | TEXT_RETURN_WIDTH;
+ text.data.d_glyph = glyph;
text.size = 1;
- text.operation = TEXT_FROM_GLYPHS | TEXT_DO_DRAW | TEXT_RETURN_WIDTH;
return gs_text_begin(pgs, &text, mem, ppte);
}
int
@@ -299,9 +312,9 @@ gs_glyphpath_begin(gs_state * pgs, gs_glyph glyph, bool stroke_path,
{
gs_text_params_t text;
- text.operation = TEXT_FROM_GLYPHS | TEXT_RETURN_WIDTH |
+ text.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_RETURN_WIDTH |
(stroke_path ? TEXT_DO_TRUE_CHARPATH : TEXT_DO_FALSE_CHARPATH);
- /****** SET glyphs ******/
+ text.data.d_glyph = glyph;
text.size = 1;
return gs_text_begin(pgs, &text, mem, ppte);
}
diff --git a/gs/src/gstext.h b/gs/src/gstext.h
index 7e84d7a51..57e954ffb 100644
--- a/gs/src/gstext.h
+++ b/gs/src/gstext.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,8 +25,6 @@
#include "gsccode.h"
#include "gsrefct.h"
-/* EVERYTHING IN THIS FILE IS SUBJECT TO CHANGE WITHOUT NOTICE. */
-
/*
* Note that like get_params and get_hardware_params, but unlike all other
* driver procedures, text display must return information to the generic
@@ -41,8 +39,8 @@
* a bit mask for convenience in testing, only certain combinations are
* meaningful. Specifically, the following are errors:
* - No FROM or DO.
- * The following are undefined:
* - More than one FROM or DO.
+ * - FROM_SINGLE with size != 1.
* - Both ADD_TO and REPLACE.
*/
#define TEXT_HAS_MORE_THAN_ONE_(op, any_)\
@@ -54,30 +52,39 @@
TEXT_HAS_MORE_THAN_ONE_(op, TEXT_DO_ANY_) ||\
(((op) & TEXT_ADD_ANY_) && ((op) & TEXT_REPLACE_ANY_))\
)
+#define TEXT_PARAMS_ARE_INVALID(params)\
+ (TEXT_OPERATION_IS_INVALID(op) ||\
+ ( ((op) & TEXT_FROM_ANY_SINGLE_) && ((params)->size != 1) )\
+ )
/* Define the representation of the text itself. */
#define TEXT_FROM_STRING 0x00001
#define TEXT_FROM_BYTES 0x00002
#define TEXT_FROM_CHARS 0x00004
#define TEXT_FROM_GLYPHS 0x00008
+#define TEXT_FROM_SINGLE_CHAR 0x00010
+#define TEXT_FROM_SINGLE_GLYPH 0x00020
+#define TEXT_FROM_ANY_SINGLE_ /* internal use only, see above */\
+ (TEXT_FROM_SINGLE_CHAR | TEXT_FROM_SINGLE_GLYPH)
#define TEXT_FROM_ANY_ /* internal use only, see above */\
- (TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS)
+ (TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS |\
+ TEXT_FROM_ANY_SINGLE_)
/* Define how to compute escapements. */
-#define TEXT_ADD_TO_ALL_WIDTHS 0x00010
-#define TEXT_ADD_TO_SPACE_WIDTH 0x00020
+#define TEXT_ADD_TO_ALL_WIDTHS 0x00040
+#define TEXT_ADD_TO_SPACE_WIDTH 0x00080
#define TEXT_ADD_ANY_ /* internal use only, see above */\
(TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH)
-#define TEXT_REPLACE_X_WIDTHS 0x00040
-#define TEXT_REPLACE_Y_WIDTHS 0x00080
+#define TEXT_REPLACE_X_WIDTHS 0x00100
+#define TEXT_REPLACE_Y_WIDTHS 0x00200
#define TEXT_REPLACE_ANY_ /* internal use only, see above */\
(TEXT_REPLACE_X_WIDTHS | TEXT_REPLACE_Y_WIDTHS)
/* Define what result should be produced. */
-#define TEXT_DO_NONE 0x00100 /* stringwidth or cshow only */
-#define TEXT_DO_DRAW 0x00200
-#define TEXT_DO_FALSE_CHARPATH 0x00400
-#define TEXT_DO_TRUE_CHARPATH 0x00800
-#define TEXT_DO_FALSE_CHARBOXPATH 0x01000
-#define TEXT_DO_TRUE_CHARBOXPATH 0x02000
+#define TEXT_DO_NONE 0x00400 /* stringwidth or cshow only */
+#define TEXT_DO_DRAW 0x00800
+#define TEXT_DO_FALSE_CHARPATH 0x01000
+#define TEXT_DO_TRUE_CHARPATH 0x02000
+#define TEXT_DO_FALSE_CHARBOXPATH 0x04000
+#define TEXT_DO_TRUE_CHARBOXPATH 0x08000
#define TEXT_DO_ANY_CHARPATH\
(TEXT_DO_FALSE_CHARPATH | TEXT_DO_TRUE_CHARPATH |\
TEXT_DO_FALSE_CHARBOXPATH | TEXT_DO_TRUE_CHARBOXPATH)
@@ -100,6 +107,8 @@ typedef struct gs_text_params_s {
const byte *bytes; /* FROM_STRING, FROM_BYTES */
const gs_char *chars; /* FROM_CHARS */
const gs_glyph *glyphs; /* FROM_GLYPHS */
+ gs_char d_char; /* FROM_SINGLE_CHAR */
+ gs_glyph d_glyph; /* FROM_SINGLE_GLYPH */
} data;
uint size; /* number of data elements */
/* The following are used only in the indicated cases. */
@@ -113,6 +122,7 @@ typedef struct gs_text_params_s {
/* Either one may be NULL, meaning widths = 0. */
const float *x_widths; /* REPLACE_X_WIDTHS */
const float *y_widths; /* REPLACE_Y_WIDTHS */
+ uint widths_size; /* REPLACE_X_WIDTHS, REPLACE_Y_WIDTHS */
/* The following are for internal use only, not by clients. */
gs_const_string gc_string; /* for use only during GC */
} gs_text_params_t;
@@ -123,44 +133,64 @@ typedef struct gs_text_params_s {
gs_public_st_composite(st_gs_text_params, gs_text_params_t,\
"gs_text_params", text_params_enum_ptrs, text_params_reloc_ptrs)
-/* Define the abstract type for the object procedures. */
-typedef struct gs_text_enum_procs_s gs_text_enum_procs_t;
-
/*
- * Define the common part of the structure that tracks the state of text
- * display. All implementations of text_begin must allocate one of these
- * using rc_alloc_struct_1; implementations may subclass and extend it.
- * Note that it includes a copy of the text parameters.
+ * Define the abstract type for the structure that tracks the state of text
+ * processing.
*/
+typedef struct gs_text_enum_s gs_text_enum_t;
+
+/* Abstract types */
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
-#define gs_text_enum_common\
- /* The following are set at initialization, and const thereafter. */\
- gs_text_params_t text;\
- const gs_text_enum_procs_t *procs;\
- gx_device *dev;\
- /* The following change dynamically. */\
- rc_header rc;\
- uint index /* index within string */
-typedef struct gs_text_enum_s {
- gs_text_enum_common;
-} gs_text_enum_t;
-
-#define st_gs_text_enum_max_ptrs st_gs_text_params_max_ptrs
-/*extern_st(st_gs_text_enum); */
-#define public_st_gs_text_enum() /* in gstext.c */\
- gs_public_st_composite(st_gs_text_enum, gs_text_enum_t, "gs_text_enum_t",\
- text_enum_enum_ptrs, text_enum_reloc_ptrs)
-
-/* Begin processing text. */
-/* Note that these take a graphics state argument. */
+#ifndef gs_imager_state_DEFINED
+# define gs_imager_state_DEFINED
+typedef struct gs_imager_state_s gs_imager_state;
+#endif
+#ifndef gx_device_color_DEFINED
+# define gx_device_color_DEFINED
+typedef struct gx_device_color_s gx_device_color;
+#endif
+#ifndef gs_font_DEFINED
+# define gs_font_DEFINED
+typedef struct gs_font_s gs_font;
+#endif
+#ifndef gx_path_DEFINED
+# define gx_path_DEFINED
+typedef struct gx_path_s gx_path;
+#endif
+#ifndef gx_clip_path_DEFINED
+# define gx_clip_path_DEFINED
+typedef struct gx_clip_path_s gx_clip_path;
+#endif
+
+/*
+ * Define the driver procedure for text.
+ */
+#define dev_t_proc_text_begin(proc, dev_t)\
+ int proc(P9(dev_t *dev,\
+ gs_imager_state *pis,\
+ const gs_text_params_t *text,\
+ const gs_font *font,\
+ gx_path *path, /* unless DO_NONE & !RETURN_WIDTH */\
+ const gx_device_color *pdcolor, /* if DO_DRAW */\
+ const gx_clip_path *pcpath, /* if DO_DRAW */\
+ gs_memory_t *memory,\
+ gs_text_enum_t **ppenum))
+#define dev_proc_text_begin(proc)\
+ dev_t_proc_text_begin(proc, gx_device)
+
+/*
+ * Begin processing text. This calls the device procedure, and also
+ * initializes the common parts of the enumerator.
+ */
+dev_proc_text_begin(gx_device_text_begin);
+
+/* Begin processing text with a graphics state. */
#ifndef gs_state_DEFINED
# define gs_state_DEFINED
typedef struct gs_state_s gs_state;
-
#endif
int gs_text_begin(P4(gs_state * pgs, const gs_text_params_t * text,
gs_memory_t * mem, gs_text_enum_t ** ppenum));
@@ -168,26 +198,32 @@ int gs_text_begin(P4(gs_state * pgs, const gs_text_params_t * text,
/* Begin the PostScript-equivalent text operators. */
int
gs_show_begin(P5(gs_state *, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)), gs_ashow_begin(P7(gs_state *, floatp, floatp, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)),
- gs_widthshow_begin(P8(gs_state *, floatp, floatp, gs_char,
- const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)), gs_awidthshow_begin(P10(gs_state *, floatp, floatp, gs_char,
- floatp, floatp, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)),
- gs_kshow_begin(P5(gs_state *, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)), gs_xyshow_begin(P7(gs_state *, const byte *, uint,
- const float *, const float *,
- gs_memory_t *, gs_text_enum_t **)),
- gs_glyphshow_begin(P4(gs_state *, gs_glyph,
- gs_memory_t *, gs_text_enum_t **)), gs_cshow_begin(P5(gs_state *, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)),
- gs_stringwidth_begin(P5(gs_state *, const byte *, uint,
- gs_memory_t *, gs_text_enum_t **)), gs_charpath_begin(P6(gs_state *, const byte *, uint, bool,
- gs_memory_t *, gs_text_enum_t **)),
- gs_glyphpath_begin(P5(gs_state *, gs_glyph, bool,
- gs_memory_t *, gs_text_enum_t **)), gs_charboxpath_begin(P6(gs_state *, const byte *, uint, bool,
- gs_memory_t *, gs_text_enum_t **));
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_ashow_begin(P7(gs_state *, floatp, floatp, const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_widthshow_begin(P8(gs_state *, floatp, floatp, gs_char,
+ const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_awidthshow_begin(P10(gs_state *, floatp, floatp, gs_char,
+ floatp, floatp, const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_kshow_begin(P5(gs_state *, const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_xyshow_begin(P8(gs_state *, const byte *, uint,
+ const float *, const float *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_glyphshow_begin(P4(gs_state *, gs_glyph,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_cshow_begin(P5(gs_state *, const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_stringwidth_begin(P5(gs_state *, const byte *, uint,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_charpath_begin(P6(gs_state *, const byte *, uint, bool,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_glyphpath_begin(P5(gs_state *, gs_glyph, bool,
+ gs_memory_t *, gs_text_enum_t **)),
+ gs_charboxpath_begin(P6(gs_state *, const byte *, uint, bool,
+ gs_memory_t *, gs_text_enum_t **));
/*
* Define the possible return values from gs_text_process. The client
@@ -197,15 +233,15 @@ int
/*
* The client must render a character: obtain the code from
- * gs_show_current_char, do whatever is necessary, and then
+ * gs_text_current_char, do whatever is necessary, and then
* call gs_text_process again.
*/
#define TEXT_PROCESS_RENDER 1
/*
* The client has asked to intervene between characters.
- * Obtain the previous and next codes from gs_show_previous_char
- * and gs_kshow_next_char, do whatever is necessary, and then
+ * Obtain the current and next codes from gs_text_current_char
+ * and gs_text_next_char, do whatever is necessary, and then
* call gs_text_process again.
*/
#define TEXT_PROCESS_INTERVENE 2
@@ -213,11 +249,14 @@ int
/* Process text after 'begin'. */
int gs_text_process(P1(gs_text_enum_t * penum));
-/* Set text metrics and optionally enable caching. */
+/*
+ * Set text metrics and optionally enable caching. Return 1 iff the
+ * cache device was just installed.
+ */
int
gs_text_setcharwidth(P2(gs_text_enum_t * penum, const double wxy[2])),
- gs_text_setcachedevice(P2(gs_text_enum_t * penum, const double wbox[6])),
- gs_text_setcachedevice2(P2(gs_text_enum_t * penum, const double wbox2[10]));
+ gs_text_setcachedevice(P2(gs_text_enum_t * penum, const double wbox[6])),
+ gs_text_setcachedevice2(P2(gs_text_enum_t * penum, const double wbox2[10]));
/* Release the text processing structures. */
void gs_text_release(P2(gs_text_enum_t * penum, client_name_t cname));
diff --git a/gs/src/gstrap.c b/gs/src/gstrap.c
index faaf68576..416a07881 100644
--- a/gs/src/gstrap.c
+++ b/gs/src/gstrap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,80 +22,9 @@
#include "gx.h"
#include "gserrors.h"
#include "gstrap.h"
+#include "gsparamx.h"
-/* Parameter utilities, copied from gdevpsdf.c. */
-/* These should be merged.... */
-
-/* Compare a C string and a gs_param_string. */
-private bool
-trap_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
-trap_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 (trap_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, integer, or float parameter. */
-private int
-trap_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;
-}
-private int
-trap_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 a float parameter. */
private bool
check_unit(float *pval)
{
@@ -133,50 +62,44 @@ gs_settrapparams(gs_trap_params_t * pparams, gs_param_list * plist)
{
gs_trap_params_t params;
int ecode = 0;
- static const char *const trap_placement_names[] =
- {
+ static const char *const trap_placement_names[] = {
gs_trap_placement_names, 0
};
params = *pparams;
ecode = trap_put_float_param(plist, "BlackColorLimit",
- &params.BlackColorLimit,
- check_unit, ecode);
+ &params.BlackColorLimit, check_unit, ecode);
ecode = trap_put_float_param(plist, "BlackDensityLimit",
&params.BlackDensityLimit,
check_positive, ecode);
ecode = trap_put_float_param(plist, "BlackWidth",
- &params.BlackWidth,
- check_positive, ecode);
- ecode = trap_put_bool_param(plist, "Enabled",
- &params.Enabled, ecode);
- ecode = trap_put_bool_param(plist, "ImageInternalTrapping",
- &params.ImageInternalTrapping, ecode);
- ecode = trap_put_int_param(plist, "ImageResolution",
- &params.ImageResolution, ecode);
+ &params.BlackWidth, check_positive, ecode);
+ ecode = param_put_bool(plist, "Enabled",
+ &params.Enabled, ecode);
+ ecode = param_put_bool(plist, "ImageInternalTrapping",
+ &params.ImageInternalTrapping, ecode);
+ ecode = param_put_int(plist, "ImageResolution",
+ &params.ImageResolution, ecode);
if (params.ImageResolution <= 0)
param_signal_error(plist, "ImageResolution",
ecode = gs_error_rangecheck);
- ecode = trap_put_bool_param(plist, "ImageToObjectTrapping",
- &params.ImageToObjectTrapping, ecode);
+ ecode = param_put_bool(plist, "ImageToObjectTrapping",
+ &params.ImageToObjectTrapping, ecode);
{
int placement = params.ImageTrapPlacement;
- ecode = trap_put_enum_param(plist, "ImageTrapPlacement",
- &placement, trap_placement_names, ecode);
+ ecode = param_put_enum(plist, "ImageTrapPlacement",
+ &placement, trap_placement_names, ecode);
params.ImageTrapPlacement = placement;
}
ecode = trap_put_float_param(plist, "SlidingTrapLimit",
- &params.SlidingTrapLimit,
- check_unit, ecode);
+ &params.SlidingTrapLimit, check_unit, ecode);
ecode = trap_put_float_param(plist, "StepLimit",
&params.StepLimit, check_unit, ecode);
ecode = trap_put_float_param(plist, "TrapColorScaling",
- &params.TrapColorScaling,
- check_unit, ecode);
+ &params.TrapColorScaling, check_unit, ecode);
ecode = trap_put_float_param(plist, "TrapWidth",
- &params.TrapWidth,
- check_positive, ecode);
+ &params.TrapWidth, check_positive, ecode);
if (ecode < 0)
return ecode;
*pparams = params;
diff --git a/gs/src/gstype1.c b/gs/src/gstype1.c
index 8e1b86950..e0a7281fc 100644
--- a/gs/src/gstype1.c
+++ b/gs/src/gstype1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -53,9 +53,9 @@ typedef fixed *cs_ptr;
* error, or >0 when client intervention is required (or allowed). The int*
* argument is where the othersubr # is stored for callothersubr.
*/
-private int
-gs_type1_charstring_interpret(gs_type1_state * pcis,
- const gs_const_string * str, int *pindex)
+int
+gs_type1_interpret(gs_type1_state * pcis, const gs_const_string * str,
+ int *pindex)
{
gs_font_type1 *pfont = pcis->pfont;
gs_type1_data *pdata = &pfont->data;
@@ -528,7 +528,8 @@ rsbw: /* Give the caller the opportunity to intervene. */
)
return_error(gs_error_invalidfont);
n = fixed2int_var(csp[-1]);
- code = (*pdata->procs->push) (pfont, csp - (n + 1), n);
+ code = (*pdata->procs->push_values)
+ (pcis->callback_data, csp - (n + 1), n);
if (code < 0)
return_error(code);
scount -= n + 1;
@@ -551,7 +552,8 @@ rsbw: /* Give the caller the opportunity to intervene. */
inext;
}
++csp;
- code = (*pdata->procs->pop) (pfont, csp);
+ code = (*pdata->procs->pop_value)
+ (pcis->callback_data, csp);
if (code < 0)
return_error(code);
goto pushed;
@@ -574,10 +576,3 @@ rsbw: /* Give the caller the opportunity to intervene. */
}
}
}
-
-/* Register the interpreter. */
-void
-gs_gstype1_init(gs_memory_t * mem)
-{
- gs_charstring_interpreter[1] = gs_type1_charstring_interpret;
-}
diff --git a/gs/src/gstype1.h b/gs/src/gstype1.h
index e1ada2c5a..8b322b3bb 100644
--- a/gs/src/gstype1.h
+++ b/gs/src/gstype1.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,25 +30,22 @@ typedef struct gs_type1_state_s gs_type1_state;
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
-
#endif
#ifndef gs_show_enum_s_DEFINED
struct gs_show_enum_s;
-
#endif
#ifndef gs_font_type1_DEFINED
# define gs_font_type1_DEFINED
typedef struct gs_font_type1_s gs_font_type1;
-
#endif
#ifndef gs_type1_data_s_DEFINED
struct gs_type1_data_s;
-
#endif
int gs_type1_interp_init(P7(gs_type1_state * pcis, gs_imager_state * pis,
gx_path * ppath, const gs_log2_scale_point * pscale,
bool charpath_flag, int paint_type,
gs_font_type1 * pfont));
+void gs_type1_set_callback_data(P2(gs_type1_state *pcis, void *callback_data));
void gs_type1_set_lsb(P2(gs_type1_state * pcis, const gs_point * psbpt));
void gs_type1_set_width(P2(gs_type1_state * pcis, const gs_point * pwpt));
@@ -59,7 +56,7 @@ void gs_type1_set_width(P2(gs_type1_state * pcis, const gs_point * pwpt));
charpath_flag, paint_type, pfont) |\
((psbpt) == 0 ? 0 : (gs_type1_set_lsb(pcis, psbpt), 0)))
/*
- * Continue interpreting a Type 1 CharString. If str != 0, it is taken as
+ * Continue interpreting a (Type 1) CharString. If str != 0, it is taken as
* the byte string to interpret. Return 0 on successful completion, <0 on
* error, or >0 when client intervention is required (or allowed). The int*
* argument is where the othersubr # is stored for callothersubr.
@@ -67,7 +64,13 @@ void gs_type1_set_width(P2(gs_type1_state * pcis, const gs_point * pwpt));
#define type1_result_sbw 1 /* allow intervention after [h]sbw */
#define type1_result_callothersubr 2
-int gs_type1_interpret(P3(gs_type1_state *, const gs_const_string *, int *));
+/* Define the generic procedure type for a CharString interpreter. */
+#define charstring_interpret_proc(proc)\
+ int proc(P3(gs_type1_state *, const gs_const_string *, int *))
+typedef charstring_interpret_proc((*charstring_interpret_proc_t));
+
+/* Define the Type 1 interpreter. */
+charstring_interpret_proc(gs_type1_interpret);
/* ------ CharString number representation ------ */
diff --git a/gs/src/gstype2.c b/gs/src/gstype2.c
index 2a18c2938..ec4b5da43 100644
--- a/gs/src/gstype2.c
+++ b/gs/src/gstype2.c
@@ -123,9 +123,9 @@ enable_hints(stem_hint_table * psht, const byte * mask)
* error, or >0 when client intervention is required (or allowed). The int*
* argument is only for compatibility with the Type 1 charstring interpreter.
*/
-private int
-gs_type2_charstring_interpret(gs_type1_state * pcis,
- const gs_const_string * str, int *ignore_pindex)
+int
+gs_type2_interpret(gs_type1_state * pcis, const gs_const_string * str,
+ int *ignore_pindex)
{
gs_font_type1 *pfont = pcis->pfont;
gs_type1_data *pdata = &pfont->data;
@@ -757,10 +757,3 @@ flex: {
}
}
}
-
-/* Register the interpreter. */
-void
-gs_gstype2_init(gs_memory_t * mem)
-{
- gs_charstring_interpreter[2] = gs_type2_charstring_interpret;
-}
diff --git a/gs/src/gstype42.c b/gs/src/gstype42.c
index 9d3625983..620ab8072 100644
--- a/gs/src/gstype42.c
+++ b/gs/src/gstype42.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,31 +30,27 @@
#include "gxfont42.h"
#include "gxistate.h"
-/*
- * This Type 42 / TrueType rasterizer is about as primitive as it can be
- * and still produce useful output. Here are some things it doesn't handle:
- * - left side bearings;
- * and, of course, instructions (hints).
- */
-
/* Structure descriptor */
public_st_gs_font_type42();
/* Set up a pointer to a substring of the font data. */
/* Free variables: pfont, string_proc. */
-#define access(base, length, vptr)\
+#define ACCESS(base, length, vptr)\
BEGIN\
code = (*string_proc)(pfont, (ulong)(base), length, &vptr);\
if ( code < 0 ) return code;\
END
/* Get 2- or 4-byte quantities from a table. */
-#define u8(p) ((uint)((p)[0]))
-#define s8(p) (int)((u8(p) ^ 0x80) - 0x80)
-#define u16(p) (((uint)((p)[0]) << 8) + (p)[1])
-#define s16(p) (int)((u16(p) ^ 0x8000) - 0x8000)
-#define u32(p) (((ulong)u16(p) << 16) + u16((p) + 2))
-#define s32(p) (long)((u32(p) ^ 0x80000000) - 0x80000000)
+#define U8(p) ((uint)((p)[0]))
+#define S8(p) (int)((U8(p) ^ 0x80) - 0x80)
+#define U16(p) (((uint)((p)[0]) << 8) + (p)[1])
+#define S16(p) (int)((U16(p) ^ 0x8000) - 0x8000)
+private ulong
+u32(const byte *p)
+{
+ return ((ulong)U16(p) << 16) + U16((p) + 2);
+}
/* Define the default implementation for getting the outline data for */
/* a glyph, using indexToLocFormat and the loca and glyf tables. */
@@ -76,21 +72,21 @@ default_get_outline(gs_font_type42 * pfont, uint glyph_index,
* individually.
*/
if (pfont->data.indexToLocFormat) {
- access(pfont->data.loca + glyph_index * 4, 4, ploca);
+ ACCESS(pfont->data.loca + glyph_index * 4, 4, ploca);
glyph_start = u32(ploca);
- access(pfont->data.loca + glyph_index * 4 + 4, 4, ploca);
+ ACCESS(pfont->data.loca + glyph_index * 4 + 4, 4, ploca);
glyph_length = u32(ploca) - glyph_start;
} else {
- access(pfont->data.loca + glyph_index * 2, 2, ploca);
- glyph_start = (ulong) u16(ploca) << 1;
- access(pfont->data.loca + glyph_index * 2 + 2, 2, ploca);
- glyph_length = ((ulong) u16(ploca) << 1) - glyph_start;
+ ACCESS(pfont->data.loca + glyph_index * 2, 2, ploca);
+ glyph_start = (ulong) U16(ploca) << 1;
+ ACCESS(pfont->data.loca + glyph_index * 2 + 2, 2, ploca);
+ glyph_length = ((ulong) U16(ploca) << 1) - glyph_start;
}
pglyph->size = glyph_length;
if (glyph_length == 0)
pglyph->data = 0;
else
- access(pfont->data.glyf + glyph_start, glyph_length, pglyph->data);
+ ACCESS(pfont->data.glyf + glyph_start, glyph_length, pglyph->data);
return 0;
}
@@ -99,8 +95,8 @@ default_get_outline(gs_font_type42 * pfont, uint glyph_index,
int
gs_type42_font_init(gs_font_type42 * pfont)
{
- int (*string_proc) (P4(gs_font_type42 *, ulong, uint, const byte **)) =
- pfont->data.string_proc;
+ int (*string_proc)(P4(gs_font_type42 *, ulong, uint, const byte **)) =
+ pfont->data.string_proc;
const byte *OffsetTable;
uint numTables;
const byte *TableDirectory;
@@ -108,17 +104,17 @@ gs_type42_font_init(gs_font_type42 * pfont)
int code;
byte head_box[8];
- access(0, 12, OffsetTable);
+ ACCESS(0, 12, OffsetTable);
{
- static const byte version1_0[4] =
- {0, 1, 0, 0};
- static const byte version_true[] = "true";
- if ( memcmp(OffsetTable, version1_0, 4) &&
- memcmp(OffsetTable, version_true, 4) )
+ static const byte version1_0[4] = {0, 1, 0, 0};
+ static const byte * const version_true = (const byte *)"true";
+
+ if (memcmp(OffsetTable, version1_0, 4) &&
+ memcmp(OffsetTable, version_true, 4))
return_error(gs_error_invalidfont);
}
- numTables = u16(OffsetTable + 4);
- access(12, numTables * 16, TableDirectory);
+ numTables = U16(OffsetTable + 4);
+ ACCESS(12, numTables * 16, TableDirectory);
/* Clear optional entries. */
pfont->data.numLongMetrics = 0;
for (i = 0; i < numTables; ++i) {
@@ -130,15 +126,15 @@ gs_type42_font_init(gs_font_type42 * pfont)
else if (!memcmp(tab, "head", 4)) {
const byte *head;
- access(offset, 54, head);
- pfont->data.unitsPerEm = u16(head + 18);
+ ACCESS(offset, 54, head);
+ pfont->data.unitsPerEm = U16(head + 18);
memcpy(head_box, head + 36, 8);
- pfont->data.indexToLocFormat = u16(head + 50);
+ pfont->data.indexToLocFormat = U16(head + 50);
} else if (!memcmp(tab, "hhea", 4)) {
const byte *hhea;
- access(offset, 36, hhea);
- pfont->data.numLongMetrics = u16(hhea + 34);
+ ACCESS(offset, 36, hhea);
+ pfont->data.numLongMetrics = U16(hhea + 34);
} else if (!memcmp(tab, "hmtx", 4))
pfont->data.hmtx = offset,
pfont->data.hmtx_length = (uint) u32(tab + 12);
@@ -158,23 +154,98 @@ gs_type42_font_init(gs_font_type42 * pfont)
) {
float upem = pfont->data.unitsPerEm;
- pfont->FontBBox.p.x = s16(head_box) / upem;
- pfont->FontBBox.p.y = s16(head_box + 2) / upem;
- pfont->FontBBox.q.x = s16(head_box + 4) / upem;
- pfont->FontBBox.q.y = s16(head_box + 6) / upem;
+ pfont->FontBBox.p.x = S16(head_box) / upem;
+ pfont->FontBBox.p.y = S16(head_box + 2) / upem;
+ pfont->FontBBox.q.x = S16(head_box + 4) / upem;
+ pfont->FontBBox.q.y = S16(head_box + 6) / upem;
}
pfont->data.get_outline = default_get_outline;
return 0;
}
-/* Get the metrics of a glyph. */
-int
-gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
- float psbw[4])
+/* Define the bits in the component glyph flags. */
+#define cg_argsAreWords 1
+#define cg_argsAreXYValues 2
+#define cg_haveScale 8
+#define cg_moreComponents 32
+#define cg_haveXYScale 64
+#define cg_have2x2 128
+#define cg_useMyMetrics 512
+
+/*
+ * Parse the definition of one component of a composite glyph. We don't
+ * bother to parse the component index, since the caller can do this so
+ * easily.
+ */
+private void
+parse_component(const byte **pdata, uint *pflags, gs_matrix_fixed *psmat,
+ const gs_font_type42 *pfont, const gs_matrix_fixed *pmat)
{
- int (*string_proc) (P4(gs_font_type42 *, ulong, uint, const byte **)) =
- pfont->data.string_proc;
- float scale = pfont->data.unitsPerEm;
+ const byte *glyph = *pdata;
+ uint flags;
+ double factor = 1.0 / pfont->data.unitsPerEm;
+ gs_matrix_fixed mat;
+ gs_matrix scale_mat;
+
+ flags = U16(glyph);
+ glyph += 4;
+ mat = *pmat;
+ if (flags & cg_argsAreXYValues) {
+ int arg1, arg2;
+ gs_fixed_point pt;
+
+ if (flags & cg_argsAreWords)
+ arg1 = S16(glyph), arg2 = S16(glyph + 2), glyph += 4;
+ else
+ arg1 = S8(glyph), arg2 = S8(glyph + 1), glyph += 2;
+ gs_point_transform2fixed(pmat, arg1 * factor,
+ arg2 * factor, &pt);
+ /****** HACK: WE KNOW ABOUT FIXED MATRICES ******/
+ mat.tx = fixed2float(mat.tx_fixed = pt.x);
+ mat.ty = fixed2float(mat.ty_fixed = pt.y);
+ } else {
+ /****** WE DON'T HANDLE POINT MATCHING YET ******/
+ glyph += (flags & cg_argsAreWords ? 4 : 2);
+ }
+#define S2_14(p) (S16(p) / 16384.0)
+ if (flags & cg_haveScale) {
+ scale_mat.xx = scale_mat.yy = S2_14(glyph);
+ scale_mat.xy = scale_mat.yx = 0;
+ glyph += 2;
+ } else if (flags & cg_haveXYScale) {
+ scale_mat.xx = S2_14(glyph);
+ scale_mat.yy = S2_14(glyph + 2);
+ scale_mat.xy = scale_mat.yx = 0;
+ glyph += 4;
+ } else if (flags & cg_have2x2) {
+ scale_mat.xx = S2_14(glyph);
+ scale_mat.xy = S2_14(glyph + 2);
+ scale_mat.yx = S2_14(glyph + 4);
+ scale_mat.yy = S2_14(glyph + 6);
+ glyph += 8;
+ } else
+ goto no_scale;
+#undef S2_14
+ scale_mat.tx = 0;
+ scale_mat.ty = 0;
+ /* The scale doesn't affect mat.t{x,y}, so we don't */
+ /* need to update the fixed components. */
+ gs_matrix_multiply(&scale_mat, (const gs_matrix *)&mat,
+ (gs_matrix *)&mat);
+no_scale:
+ *pdata = glyph;
+ *pflags = flags;
+ *psmat = mat;
+}
+
+/* Get the metrics of a simple glyph. */
+private int
+simple_glyph_metrics(gs_font_type42 * pfont, uint glyph_index,
+ float sbw[4])
+{
+ int (*string_proc)(P4(gs_font_type42 *, ulong, uint, const byte **)) =
+ pfont->data.string_proc;
+ double factor = 1.0 / pfont->data.unitsPerEm;
uint widthx;
int lsbx;
int code;
@@ -184,29 +255,59 @@ gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
const byte *hmetrics;
if (glyph_index < num_metrics) {
- access(pfont->data.hmtx + glyph_index * 4, 4, hmetrics);
- widthx = u16(hmetrics);
- lsbx = s16(hmetrics + 2);
+ ACCESS(pfont->data.hmtx + glyph_index * 4, 4, hmetrics);
+ widthx = U16(hmetrics);
+ lsbx = S16(hmetrics + 2);
} else {
- uint offset = pfont->data.hmtx + (num_metrics - 1) * 4;
+ uint offset = pfont->data.hmtx + num_metrics * 4;
+ uint glyph_offset = (glyph_index - num_metrics) * 2;
const byte *lsb;
- access(offset, 4, hmetrics);
- widthx = u16(hmetrics);
- offset += 4 + (glyph_index - num_metrics) * 2;
- if (offset >= pfont->data.hmtx_length)
- offset = pfont->data.hmtx_length - 2;
- access(offset, 2, lsb);
- lsbx = s16(lsb);
+ ACCESS(offset - 4, 4, hmetrics);
+ widthx = U16(hmetrics);
+ if (glyph_offset >= pfont->data.hmtx_length)
+ glyph_offset = pfont->data.hmtx_length - 2;
+ ACCESS(offset + glyph_offset, 2, lsb);
+ lsbx = S16(lsb);
}
}
- psbw[0] = lsbx / scale;
- psbw[1] = 0;
- psbw[2] = widthx / scale;
- psbw[3] = 0;
+ sbw[0] = lsbx * factor;
+ sbw[1] = 0;
+ sbw[2] = widthx * factor;
+ sbw[3] = 0;
return 0;
}
+/* Get the metrics of a glyph. */
+int
+gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
+ float sbw[4])
+{
+ gs_const_string glyph_string;
+ int code = pfont->data.get_outline(pfont, glyph_index, &glyph_string);
+
+ if (code < 0)
+ return code;
+ if (glyph_string.size != 0 && S16(glyph_string.data) == -1) {
+ /* This is a composite glyph. */
+ uint flags;
+ const byte *glyph = glyph_string.data + 10;
+ gs_matrix_fixed mat;
+
+ memset(&mat, 0, sizeof(mat)); /* arbitrary */
+ do {
+ uint comp_index = U16(glyph + 2);
+
+ parse_component(&glyph, &flags, &mat, pfont, &mat);
+ if (flags & cg_useMyMetrics) {
+ return simple_glyph_metrics(pfont, comp_index, sbw);
+ }
+ }
+ while (flags & cg_moreComponents);
+ }
+ return simple_glyph_metrics(pfont, glyph_index, sbw);
+}
+
/* Define the bits in the glyph flags. */
#define gf_OnCurve 1
#define gf_xShort 2
@@ -217,14 +318,6 @@ gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,
#define gf_yPos 32 /* yShort */
#define gf_ySame 32 /* !yShort */
-/* Define the bits in the component glyph flags. */
-#define cg_argsAreWords 1
-#define cg_argsAreXYValues 2
-#define cg_haveScale 8
-#define cg_moreComponents 32
-#define cg_haveXYScale 64
-#define cg_have2x2 128
-
/* Forward references */
private int append_outline(P4(uint glyph_index, const gs_matrix_fixed * pmat,
gx_path * ppath, gs_font_type42 * pfont));
@@ -233,26 +326,18 @@ private int append_outline(P4(uint glyph_index, const gs_matrix_fixed * pmat,
/* Note that this does not append the final moveto for the width. */
int
gs_type42_append(uint glyph_index, gs_imager_state * pis,
- gx_path * ppath, const gs_log2_scale_point * pscale, bool charpath_flag,
- int paint_type, gs_font_type42 * pfont)
+ gx_path * ppath, const gs_log2_scale_point * pscale,
+ bool charpath_flag, int paint_type, gs_font_type42 * pfont)
{
- float sbw[4];
-
- gs_type42_get_metrics(pfont, glyph_index, sbw);
- /*
- * This is where we should do something about the l.s.b., but I
- * can't figure out from the TrueType documentation what it should
- * be.
- */
return append_outline(glyph_index, &pis->ctm, ppath, pfont);
}
/* Append a simple glyph outline. */
private int
-append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
- gs_font_type42 * pfont)
+append_simple(const byte *glyph, float sbw[4], const gs_matrix_fixed *pmat,
+ gx_path *ppath, gs_font_type42 * pfont)
{
- int numContours = s16(glyph);
+ int numContours = S16(glyph);
const byte *pends = glyph + 10;
const byte *pinstr = pends + numContours * 2;
const byte *pflags;
@@ -268,8 +353,8 @@ append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
* incredible piece of bad design.
*/
{
- const byte *pf = pflags = pinstr + 2 + u16(pinstr);
- uint xbytes = npoints = u16(pinstr - 2) + 1;
+ const byte *pf = pflags = pinstr + 2 + U16(pinstr);
+ uint xbytes = npoints = U16(pinstr - 2) + 1;
uint np = npoints;
while (np > 0) {
@@ -293,7 +378,7 @@ append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
{
uint i, np;
gs_fixed_point pt;
- float scale = pfont->data.unitsPerEm;
+ double factor = 1.0 / pfont->data.unitsPerEm;
/*
* Decode the first flag byte outside the loop, to avoid a
* compiler warning about uninitialized variables.
@@ -301,10 +386,16 @@ append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
byte flags = *pflags++;
uint reps = (flags & gf_Repeat ? *pflags++ + 1 : 1);
- gs_point_transform2fixed(pmat, 0.0, 0.0, &pt);
+ /*
+ * The TrueType documentation gives no clue as to how the lsb
+ * should affect placement of the outline. Our best guess is
+ * that the outline should be translated by lsb - xMin.
+ */
+ gs_point_transform2fixed(pmat, sbw[0] - S16(glyph + 2) * factor,
+ 0.0, &pt);
for (i = 0, np = 0; i < numContours; ++i) {
bool move = true;
- uint last_point = u16(pends + i * 2);
+ uint last_point = U16(pends + i * 2);
float dx, dy;
int off_curve = 0;
gs_fixed_point start;
@@ -317,24 +408,27 @@ append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
flags = *pflags++;
reps = (flags & gf_Repeat ? *pflags++ + 1 : 1);
}
- if (flags & gf_xShort)
- {
- dx = *pxc++ / scale;
- if ( !(flags & gf_xPos) )
- dx = -dx;
- }
- else if (!(flags & gf_xSame))
- dx = s16(pxc) / scale, pxc += 2;
+ if (flags & gf_xShort) {
+ /*
+ * A bug in the Watcom compiler prevents us from doing
+ * the following with the obvious conditional expression.
+ */
+ if (flags & gf_xPos)
+ dx = *pxc++ * factor;
+ else
+ dx = -(int)*pxc++ * factor;
+ } else if (!(flags & gf_xSame))
+ dx = S16(pxc) * factor, pxc += 2;
else
dx = 0;
- if (flags & gf_yShort)
- {
- dy = *pyc++ / scale;
- if ( !(flags & gf_yPos) )
- dy = -dy;
- }
- else if ( !(flags & gf_ySame) )
- dy = s16(pyc) / scale, pyc += 2;
+ if (flags & gf_yShort) {
+ /* See above under dx. */
+ if (flags & gf_yPos)
+ dy = *pyc++ * factor;
+ else
+ dy = -(int)*pyc++ * factor;
+ } else if (!(flags & gf_ySame))
+ dy = S16(pyc) * factor, pyc += 2;
else
dy = 0;
code = gs_distance_transform2fixed(pmat, dx, dy, &dpt);
@@ -401,87 +495,43 @@ append_simple(const byte * glyph, const gs_matrix_fixed * pmat, gx_path * ppath,
/* Append a glyph outline. */
private int
-append_outline(uint glyph_index, const gs_matrix_fixed * pmat, gx_path * ppath,
- gs_font_type42 * pfont)
+append_outline(uint glyph_index, const gs_matrix_fixed * pmat,
+ gx_path * ppath, gs_font_type42 * pfont)
{
gs_const_string glyph_string;
-
-#define glyph glyph_string.data
+ const byte *glyph;
+ float sbw[4];
int numContours;
int code;
code = (*pfont->data.get_outline) (pfont, glyph_index, &glyph_string);
if (code < 0)
return code;
+ glyph = glyph_string.data;
if (glyph == 0 || glyph_string.size == 0) /* empty glyph */
return 0;
- numContours = s16(glyph);
- if (numContours >= 0)
- return append_simple(glyph, pmat, ppath, pfont);
+ numContours = S16(glyph);
+ if (numContours >= 0) {
+ simple_glyph_metrics(pfont, glyph_index, sbw);
+ return append_simple(glyph, sbw, pmat, ppath, pfont);
+ }
if (numContours != -1)
return_error(gs_error_rangecheck);
- /* This is a component glyph. Things get messy. */
+ /* This is a composite glyph. */
{
uint flags;
- float scale = pfont->data.unitsPerEm;
glyph += 10;
do {
- uint comp_index = u16(glyph + 2);
+ uint comp_index = U16(glyph + 2);
gs_matrix_fixed mat;
- gs_matrix scale_mat;
-
- flags = u16(glyph);
- glyph += 4;
- mat = *pmat;
- if (flags & cg_argsAreXYValues) {
- int arg1, arg2;
- gs_fixed_point pt;
- if (flags & cg_argsAreWords)
- arg1 = s16(glyph), arg2 = s16(glyph + 2), glyph += 4;
- else
- arg1 = s8(glyph), arg2 = s8(glyph + 1), glyph += 2;
- gs_point_transform2fixed(pmat, arg1 / scale,
- arg2 / scale, &pt);
-/****** HACK: WE KNOW ABOUT FIXED MATRICES ******/
- mat.tx = fixed2float(mat.tx_fixed = pt.x);
- mat.ty = fixed2float(mat.ty_fixed = pt.y);
- } else {
-/****** WE DON'T HANDLE POINT MATCHING YET ******/
- glyph += (flags & cg_argsAreWords ? 4 : 2);
- }
-#define s2_14(p) (s16(p) / 16384.0)
- if (flags & cg_haveScale) {
- scale_mat.xx = scale_mat.yy = s2_14(glyph);
- scale_mat.xy = scale_mat.yx = 0;
- glyph += 2;
- } else if (flags & cg_haveXYScale) {
- scale_mat.xx = s2_14(glyph);
- scale_mat.yy = s2_14(glyph + 2);
- scale_mat.xy = scale_mat.yx = 0;
- glyph += 4;
- } else if (flags & cg_have2x2) {
- scale_mat.xx = s2_14(glyph);
- scale_mat.xy = s2_14(glyph + 2);
- scale_mat.yx = s2_14(glyph + 4);
- scale_mat.yy = s2_14(glyph + 6);
- glyph += 8;
- } else
- goto no_scale;
-#undef s2_14
- scale_mat.tx = 0;
- scale_mat.ty = 0;
- /* The scale doesn't affect mat.t{x,y}, so we don't */
- /* need to update the fixed components. */
- gs_matrix_multiply(&scale_mat, (const gs_matrix *)&mat,
- (gs_matrix *) & mat);
- no_scale:code = append_outline(comp_index, &mat, ppath, pfont);
+ parse_component(&glyph, &flags, &mat, pfont, pmat);
+ code = append_outline(comp_index, &mat, ppath, pfont);
if (code < 0)
return code;
}
while (flags & cg_moreComponents);
}
return 0;
-#undef glyph
}
diff --git a/gs/src/gstypes.h b/gs/src/gstypes.h
index 921eef04e..d3447efb3 100644
--- a/gs/src/gstypes.h
+++ b/gs/src/gstypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -37,16 +37,42 @@ typedef ulong gs_id;
* the C char * type (which can't store arbitrary data, represent
* substrings, or perform concatenation without destroying aliases).
*/
+#define GS_STRING_COMMON\
+ byte *data;\
+ uint size
typedef struct gs_string_s {
- byte *data;
- uint size;
+ GS_STRING_COMMON;
} gs_string;
+#define GS_CONST_STRING_COMMON\
+ const byte *data;\
+ uint size
typedef struct gs_const_string_s {
- const byte *data;
- uint size;
+ GS_CONST_STRING_COMMON;
} gs_const_string;
/*
+ * Since strings are allocated differently from ordinary objects, define a
+ * structure that can reference either a string (if bytes == 0) or a byte
+ * object (if bytes != 0, in which case data+size point within the object).
+ *
+ * Note: for garbage collection purposes, the string_common members must
+ * come first.
+ */
+typedef struct gs_bytestring_s {
+ GS_STRING_COMMON;
+ byte *bytes; /* see above */
+} gs_bytestring;
+typedef struct gs_const_bytestring_s {
+ GS_CONST_STRING_COMMON;
+ const byte *bytes; /* see above */
+} gs_const_bytestring;
+
+#define gs_bytestring_from_string(pbs, dat, siz)\
+ ((pbs)->data = (dat), (pbs)->size = (siz), (pbs)->bytes = 0)
+#define gs_bytestring_from_bytes(pbs, byts, offset, siz)\
+ ((pbs)->data = ((pbs)->bytes = (byts)) + (offset), (pbs)->size = (siz))
+
+/*
* Define types for Cartesian points.
*/
typedef struct gs_point_s {
diff --git a/gs/src/gx.h b/gs/src/gx.h
index ac80f795d..1ec7f6a2f 100644
--- a/gs/src/gx.h
+++ b/gs/src/gx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1991, 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1991, 1994 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
diff --git a/gs/src/gxacpath.c b/gs/src/gxacpath.c
index 6c20e4922..8eeeb76e6 100644
--- a/gs/src/gxacpath.c
+++ b/gs/src/gxacpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,14 +26,13 @@
#include "gsdcolor.h"
#include "gxdevice.h"
#include "gxfixed.h"
+#include "gxistate.h"
#include "gzpath.h"
#include "gxpaint.h"
#include "gzcpath.h"
#include "gzacpath.h"
/* Imported procedures */
-extern gx_device *gs_currentdevice(P1(const gs_state *));
-extern float gs_currentflat(P1(const gs_state *));
extern bool clip_list_validate(P1(const gx_clip_list *));
/* Device procedures */
@@ -160,11 +159,10 @@ gx_cpath_accum_discard(gx_device_cpath_accum * padev)
/* Intersect two clipping paths using an accumulator. */
int
-gx_cpath_intersect_slow(gs_state * pgs, gx_clip_path * pcpath, gx_path * ppath,
- int rule)
+gx_cpath_intersect_path_slow(gx_clip_path * pcpath, gx_path * ppath,
+ int rule, gs_imager_state *pis)
{
- bool outside = gx_cpath_is_outside(pcpath);
- gs_logical_operation_t save_lop = gs_current_logical_op(pgs);
+ gs_logical_operation_t save_lop = gs_current_logical_op_inline(pis);
gx_device_cpath_accum adev;
gx_device_color devc;
gx_fill_params params;
@@ -172,18 +170,16 @@ gx_cpath_intersect_slow(gs_state * pgs, gx_clip_path * pcpath, gx_path * ppath,
gx_cpath_accum_begin(&adev, pcpath->path.memory);
color_set_pure(&devc, 0); /* arbitrary, but not transparent */
- gs_set_logical_op(pgs, lop_default);
+ gs_set_logical_op_inline(pis, lop_default);
params.rule = rule;
params.adjust.x = params.adjust.y = fixed_half;
- params.flatness = gs_currentflat(pgs);
+ params.flatness = gs_currentflat_inline(pis);
params.fill_zero_width = true;
- code = gx_fill_path_only(ppath, (gx_device *) & adev,
- (const gs_imager_state *)pgs,
+ code = gx_fill_path_only(ppath, (gx_device *)&adev, pis,
&params, &devc, pcpath);
if (code < 0 || (code = gx_cpath_accum_end(&adev, pcpath)) < 0)
gx_cpath_accum_discard(&adev);
- gx_cpath_set_outside(pcpath, outside);
- gs_set_logical_op(pgs, save_lop);
+ gs_set_logical_op_inline(pis, save_lop);
return code;
}
@@ -207,16 +203,19 @@ accum_open(register gx_device * dev)
private int
accum_close(gx_device * dev)
{
-#ifdef DEBUG
gx_device_cpath_accum * const adev = (gx_device_cpath_accum *)dev;
+ adev->list.xmin = adev->bbox.p.x;
+ adev->list.xmax = adev->bbox.q.x;
+#ifdef DEBUG
if (gs_debug_c('q')) {
gx_clip_rect *rp =
(adev->list.count <= 1 ? &adev->list.single : adev->list.head);
- dlprintf4("[q]list at 0x%lx, count=%d, head=0x%lx, tail=0x%lx:\n",
+ dlprintf6("[q]list at 0x%lx, count=%d, head=0x%lx, tail=0x%lx, xrange=(%d,%d):\n",
(ulong) & adev->list, adev->list.count,
- (ulong) adev->list.head, (ulong) adev->list.tail);
+ (ulong) adev->list.head, (ulong) adev->list.tail,
+ adev->list.xmin, adev->list.xmax);
while (rp != 0) {
clip_rect_print('q', " ", rp);
rp = rp->next;
@@ -231,12 +230,13 @@ accum_close(gx_device * dev)
}
/* Accumulate one rectangle. */
-#undef adev
/* Allocate a rectangle to be added to the list. */
-static const gx_clip_rect clip_head_rect =
-{0, 0, min_int, min_int, min_int, min_int};
-static const gx_clip_rect clip_tail_rect =
-{0, 0, max_int, max_int, max_int, max_int};
+static const gx_clip_rect clip_head_rect = {
+ 0, 0, min_int, min_int, min_int, min_int
+};
+static const gx_clip_rect clip_tail_rect = {
+ 0, 0, max_int, max_int, max_int, max_int
+};
private gx_clip_rect *
accum_alloc_rect(gx_device_cpath_accum * adev)
{
@@ -246,15 +246,16 @@ accum_alloc_rect(gx_device_cpath_accum * adev)
if (ar == 0)
return 0;
- if (adev->list.count == 2) { /* We're switching from a single rectangle to a list. */
+ if (adev->list.count == 2) {
+ /* We're switching from a single rectangle to a list. */
/* Allocate the head and tail entries. */
gx_clip_rect *head = ar;
gx_clip_rect *tail =
- gs_alloc_struct(mem, gx_clip_rect, &st_clip_rect,
- "accum_alloc_rect(tail)");
+ gs_alloc_struct(mem, gx_clip_rect, &st_clip_rect,
+ "accum_alloc_rect(tail)");
gx_clip_rect *single =
- gs_alloc_struct(mem, gx_clip_rect, &st_clip_rect,
- "accum_alloc_rect(single)");
+ gs_alloc_struct(mem, gx_clip_rect, &st_clip_rect,
+ "accum_alloc_rect(single)");
ar = gs_alloc_struct(mem, gx_clip_rect, &st_clip_rect,
"accum_alloc_rect(head)");
@@ -277,32 +278,32 @@ accum_alloc_rect(gx_device_cpath_accum * adev)
}
return ar;
}
-#define accum_alloc(s, ar, px, py, qx, qy)\
- if ( ++(adev->list.count) == 1 )\
+#define ACCUM_ALLOC(s, ar, px, py, qx, qy)\
+ if (++(adev->list.count) == 1)\
ar = &adev->list.single;\
- else if ( (ar = accum_alloc_rect(adev)) == 0 )\
+ else if ((ar = accum_alloc_rect(adev)) == 0)\
return_error(gs_error_VMerror);\
- accum_set(s, ar, px, py, qx, qy)
-#define accum_set(s, ar, px, py, qx, qy)\
+ ACCUM_SET(s, ar, px, py, qx, qy)
+#define ACCUM_SET(s, ar, px, py, qx, qy)\
(ar)->xmin = px, (ar)->ymin = py, (ar)->xmax = qx, (ar)->ymax = qy;\
clip_rect_print('Q', s, ar)
/* Link or unlink a rectangle in the list. */
-#define accum_add_last(ar)\
- accum_add_before(ar, adev->list.tail)
-#define accum_add_after(ar, rprev)\
+#define ACCUM_ADD_LAST(ar)\
+ ACCUM_ADD_BEFORE(ar, adev->list.tail)
+#define ACCUM_ADD_AFTER(ar, rprev)\
ar->prev = (rprev), (ar->next = (rprev)->next)->prev = ar,\
(rprev)->next = ar
-#define accum_add_before(ar, rnext)\
+#define ACCUM_ADD_BEFORE(ar, rnext)\
(ar->prev = (rnext)->prev)->next = ar, ar->next = (rnext),\
(rnext)->prev = ar
-#define accum_remove(ar)\
+#define ACCUM_REMOVE(ar)\
ar->next->prev = ar->prev, ar->prev->next = ar->next
/* Free a rectangle that was removed from the list. */
-#define accum_free(s, ar)\
- if ( --(adev->list.count) )\
- { clip_rect_print('Q', s, ar);\
- gs_free_object(adev->list_memory, ar, "accum_rect");\
- }
+#define ACCUM_FREE(s, ar)\
+ if (--(adev->list.count)) {\
+ clip_rect_print('Q', s, ar);\
+ gs_free_object(adev->list_memory, ar, "accum_rect");\
+ }
/*
* Add a rectangle to the list. It would be wonderful if rectangles
* were always disjoint and always presented in the correct order,
@@ -350,31 +351,48 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
if (ye > adev->bbox.q.y)
adev->bbox.q.y = ye;
- top:if (adev->list.count == 0) { /* very first rectangle */
+top:
+ if (adev->list.count == 0) { /* very first rectangle */
adev->list.count = 1;
- accum_set("single", &adev->list.single, x, y, xe, ye);
+ ACCUM_SET("single", &adev->list.single, x, y, xe, ye);
return 0;
}
- if (adev->list.count == 1) /* check for Y merging */
-
- {
+ if (adev->list.count == 1) { /* check for Y merging */
rptr = &adev->list.single;
if (x == rptr->xmin && xe == rptr->xmax &&
- y <= rptr->ymax && y >= rptr->ymin
+ y <= rptr->ymax && ye >= rptr->ymin
) {
+ if (y < rptr->ymin)
+ rptr->ymin = y;
if (ye > rptr->ymax)
rptr->ymax = ye;
return 0;
}
}
- accum_alloc("accum", nr, x, y, xe, ye);
- rptr = adev->list.tail->prev;
- if (y >= rptr->ymax ||
- (y == rptr->ymin && ye == rptr->ymax && x >= rptr->xmax)
- ) {
- accum_add_last(nr);
+ else
+ rptr = adev->list.tail->prev;
+ if (y >= rptr->ymax) {
+ if (y == rptr->ymax && x == rptr->xmin && xe == rptr->xmax &&
+ (rptr->prev == 0 || y != rptr->prev->ymax)
+ ) {
+ rptr->ymax = ye;
+ return 0;
+ }
+ ACCUM_ALLOC("app.y", nr, x, y, xe, ye);
+ ACCUM_ADD_LAST(nr);
+ return 0;
+ } else if (y == rptr->ymin && ye == rptr->ymax && x >= rptr->xmin) {
+ if (x <= rptr->xmax) {
+ if (xe > rptr->xmax)
+ rptr->xmax = xe;
+ return 0;
+ }
+ ACCUM_ALLOC("app.x", nr, x, y, xe, ye);
+ ACCUM_ADD_LAST(nr);
return 0;
}
+ ACCUM_ALLOC("accum", nr, x, y, xe, ye);
+ rptr = adev->list.tail->prev;
/* Work backwards till we find the insertion point. */
while (ye <= rptr->ymin)
rptr = rptr->prev;
@@ -382,12 +400,12 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
ymax = rptr->ymax;
if (ye > ymax) {
if (y >= ymax) { /* Insert between two bands. */
- accum_add_after(nr, rptr);
+ ACCUM_ADD_AFTER(nr, rptr);
return 0;
}
/* Split off the top part of the new rectangle. */
- accum_alloc("a.top", ar, x, ymax, xe, ye);
- accum_add_after(ar, rptr);
+ ACCUM_ALLOC("a.top", ar, x, ymax, xe, ye);
+ ACCUM_ADD_AFTER(ar, rptr);
ye = nr->ymax = ymax;
clip_rect_print('Q', " ymax", nr);
}
@@ -399,8 +417,8 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
gx_clip_rect *rsplit = rptr;
while (rsplit->ymax == ymax) {
- accum_alloc("s.top", ar, rsplit->xmin, ye, rsplit->xmax, ymax);
- accum_add_after(ar, rptr);
+ ACCUM_ALLOC("s.top", ar, rsplit->xmin, ye, rsplit->xmax, ymax);
+ ACCUM_ADD_AFTER(ar, rptr);
rsplit->ymax = ye;
rsplit = rsplit->prev;
}
@@ -414,8 +432,8 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
while (rbot->prev->ymin == ymin)
rbot = rbot->prev;
for (rsplit = rbot;;) {
- accum_alloc("s.bot", ar, rsplit->xmin, ymin, rsplit->xmax, y);
- accum_add_before(ar, rbot);
+ ACCUM_ALLOC("s.bot", ar, rsplit->xmin, ymin, rsplit->xmax, y);
+ ACCUM_ADD_BEFORE(ar, rbot);
rsplit->ymin = y;
if (rsplit == rptr)
break;
@@ -437,18 +455,20 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
/* we already did a merge */
clip_rect_print('Q', "widen", rptr);
}
- accum_free("free", nr);
+ ACCUM_FREE("free", nr);
if (x >= rptr->xmin)
goto out;
/* Might overlap other rectangles to the left. */
rptr->xmin = x;
nr = rptr;
- accum_remove(rptr);
+ ACCUM_REMOVE(rptr);
clip_rect_print('Q', "merge", nr);
}
- accum_add_after(nr, rptr);
- out: /* Check whether there are only 0 or 1 rectangles left. */
- if (adev->list.count <= 1) { /* We're switching from a list to at most 1 rectangle. */
+ ACCUM_ADD_AFTER(nr, rptr);
+out:
+ /* Check whether there are only 0 or 1 rectangles left. */
+ if (adev->list.count <= 1) {
+ /* We're switching from a list to at most 1 rectangle. */
/* Free the head and tail entries. */
gs_memory_t *mem = adev->list_memory;
gx_clip_rect *single = adev->list.head->next;
@@ -464,7 +484,8 @@ accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
adev->list.tail = 0;
}
/* Check whether there is still more of the new band to process. */
- if (y < ymin) { /* Continue with the bottom part of the new rectangle. */
+ if (y < ymin) {
+ /* Continue with the bottom part of the new rectangle. */
clip_rect_print('Q', " ymin", nr);
ye = ymin;
goto top;
diff --git a/gs/src/gxalloc.h b/gs/src/gxalloc.h
index b15714cab..2b2fb2df7 100644
--- a/gs/src/gxalloc.h
+++ b/gs/src/gxalloc.h
@@ -16,7 +16,7 @@
all copies.
*/
-/*$Id$ */
+
/* Requires gsmemory.h, gsstruct.h */
#ifndef gxalloc_INCLUDED
@@ -117,12 +117,17 @@ typedef uint string_reloc_offset;
*/
#define string_quanta_mark_size(nquanta)\
((nquanta) * (string_data_quantum / 8))
+/*
+ * Compute the size of the string freelists for a chunk.
+ */
+#define STRING_FREELIST_SPACE(cp)\
+ (((cp->climit - csbase(cp) + 255) >> 8) * sizeof(*cp->sfree1))
/*
* To allow the garbage collector to combine chunks, we store in the
* head of each chunk the address to which its contents will be moved.
*/
- /*typedef struct chunk_head_s chunk_head_t; *//* in gxobj.h */
+/*typedef struct chunk_head_s chunk_head_t; *//* in gxobj.h */
/* Structure for a chunk. */
typedef struct chunk_s chunk_t;
@@ -153,22 +158,24 @@ struct chunk_s {
/* the outer chunk, if any */
bool has_refs; /* true if any refs in chunk */
/*
- * Free lists for single bytes in blocks of 1-3 bytes,
- * one per 256 bytes in [csbase..climit). The chain
- * pointer is a (1-byte) self-relative offset,
- * terminated by a 0; obviously, the chain is sorted by
- * increasing address. The free list pointers themselves
- * are offsets relative to csbase.
+ * Free lists for single bytes in blocks of 1 to 2*N-1 bytes, one per
+ * 256 bytes in [csbase..climit), where N is sizeof(uint). The chain
+ * pointer is a (1-byte) self-relative offset, terminated by a 0;
+ * obviously, the chain is sorted by increasing address. The free list
+ * pointers themselves are offsets relative to csbase.
*
- * Note that these lists overlay the GC relocation table.
+ * Note that these lists overlay the GC relocation table, and that
+ * sizeof(*sfree1) / 256 must be less than sizeof(string_reloc_offset) /
+ * string_data_quantum (as real numbers).
*/
- ushort *sfree1;
+#define SFREE_NB 4 /* # of bytes for values on sfree list */
+ uint *sfree1;
/*
- * Free list for blocks of >= 4 bytes. Each block begins
- * with a 2-byte size and a 2-byte next block pointer,
+ * Free list for blocks of >= 2*N bytes. Each block begins
+ * with a N-byte size and a N-byte next block pointer,
* both big-endian. This too is sorted in increasing address order.
*/
- ushort sfree;
+ uint sfree;
/* The remaining members are for the GC. */
byte *odest; /* destination for objects */
byte *smark; /* mark bits for strings */
diff --git a/gs/src/gxarith.h b/gs/src/gxarith.h
index 37e55df8c..d862b1152 100644
--- a/gs/src/gxarith.h
+++ b/gs/src/gxarith.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1993, 1994, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1993, 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,6 +32,17 @@ int imod(P2(int m, int n));
/* Compute the GCD of two integers. */
int igcd(P2(int x, int y));
+/*
+ * Given A, B, and M, compute X such that A*X = B mod M, 0 < X < M.
+ * Requires: M > 0, 0 < A < M, 0 < B < M, gcd(A, M) | gcd(A, B).
+ */
+int idivmod(P3(int a, int b, int m));
+
+/*
+ * Compute floor(log2(N)). Requires N > 0.
+ */
+int ilog2(P1(int n));
+
/* Test whether an integral value fits in a given number of bits. */
/* This works for all integral types. */
#define fits_in_bits(i, n)\
diff --git a/gs/src/gxband.h b/gs/src/gxband.h
index b5b845fcd..db11138e1 100644
--- a/gs/src/gxband.h
+++ b/gs/src/gxband.h
@@ -36,6 +36,28 @@ typedef struct gx_band_params_s {
#define BAND_PARAMS_INITIAL_VALUES 0, 0, 0
/*
+ * Define information about the colors used on a page.
+ */
+typedef struct gx_colors_used_s {
+ gx_color_index or; /* the "or" of all the used colors */
+ bool slow_rop; /* true if any RasterOps that can't be */
+ /* executed plane-by-plane on CMYK devices */
+} gx_colors_used_t;
+
+/*
+ * We want to store color usage information for each band in the page_info
+ * structure, but we also want this structure to be of a fixed (and
+ * reasonable) size. We do this by allocating a fixed number of colors_used
+ * structures in the page_info structure, and if there are more bands than
+ * we have allocated, we simply reduce the precision of the information by
+ * letting each colors_used structure cover multiple bands.
+ *
+ * 30 entries would be large enough to cover A4 paper (11.3") at 600 dpi
+ * with 256-scan-line bands. We pick 50 somewhat arbitrarily.
+ */
+#define PAGE_INFO_NUM_COLORS_USED 50
+
+/*
* Define the information for a saved page.
*/
typedef struct gx_band_page_info_s {
@@ -47,9 +69,13 @@ typedef struct gx_band_page_info_s {
long bfile_end_pos; /* ftell at end of bfile */
gx_band_params_t band_params; /* parameters used when writing band list */
/* (actual values, no 0s) */
+ int scan_lines_per_colors_used; /* number of scan lines per colors_used */
+ /* entry (a multiple of the band height) */
+ gx_colors_used_t band_colors_used[PAGE_INFO_NUM_COLORS_USED]; /* colors used on the page */
} gx_band_page_info_t;
#define PAGE_INFO_NULL_VALUES\
- { 0 }, 0, { 0 }, 0, 0, 0, { BAND_PARAMS_INITIAL_VALUES }
+ { 0 }, 0, { 0 }, 0, 0, 0, { BAND_PARAMS_INITIAL_VALUES },\
+ 0x3fffffff, { { 0 } }
/*
* By convention, the structure member containing the above is called
diff --git a/gs/src/gxbitfmt.h b/gs/src/gxbitfmt.h
index b09afa754..8749385ac 100644
--- a/gs/src/gxbitfmt.h
+++ b/gs/src/gxbitfmt.h
@@ -68,6 +68,9 @@ typedef ulong gx_bitmap_format_t;
/*
* Define the supported depths per component for GB_COLORS_STANDARD.
+ * For GB_COLORS_NATIVE with planar packing, it is the client's
+ * responsibility to know how the device divides up the bits of the
+ * pixel.
*/
#define GB_DEPTH_1 (1L<<8)
@@ -108,12 +111,25 @@ typedef ulong gx_bitmap_format_t;
#define GB_PACKING_CHUNKY (1L<<16)
#define GB_PACKING_PLANAR (1L<<17) /* 1 plane per component */
#define GB_PACKING_BIT_PLANAR (1L<<18) /* 1 plane per bit */
- /*unused*/ /*(1L<<19)*/
#define GB_PACKING_ALL\
(GB_PACKING_CHUNKY | GB_PACKING_PLANAR | GB_PACKING_BIT_PLANAR)
#define GB_PACKING_NAMES\
- "packing_chunky", "packing_planar", "packing_bit_planar", "?packing_unused?"
+ "packing_chunky", "packing_planar", "packing_bit_planar"
+
+ /*
+ * Define whether to return a subset of the planes. With planar packing
+ * formats, if this is set, only those planes that had non-zero data
+ * pointers originally will be returned (either by copying or by
+ * pointer). With chunky packing, if this is set, only an undefined
+ * subset of the returned bits may be valid.
+ */
+
+#define GB_SELECT_PLANES (1L<<19)
+#define GB_SELECT_ALL\
+ (GB_SELECT_PLANES)
+#define GB_SELECT_NAMES\
+ "select_planes"
/*
* Define the possible methods of returning data.
@@ -129,7 +145,8 @@ typedef ulong gx_bitmap_format_t;
/*
* Define the allowable alignments. This is only relevant for
- * GB_RETURN_POINTER: for GB_RETURN_COPY, any alignment is acceptable.
+ * GB_RETURN_POINTER: for GB_RETURN_COPY, any alignment is
+ * acceptable.
*/
#define GB_ALIGN_STANDARD (1L<<22) /* require standard bitmap alignment */
@@ -138,18 +155,18 @@ typedef ulong gx_bitmap_format_t;
#define GB_ALIGN_ALL\
(GB_ALIGN_ANY | GB_ALIGN_STANDARD)
#define GB_ALIGN_NAMES\
- "align_any", "align_standard"
+ "align_standard", "align_any"
/*
* Define the allowable X offsets. GB_OFFSET_ANY is only relevant for
- * GB_RETURN_POINTER: for GB_RETURN_COPY, clients must specify the
- * offset so they know how much space to allocate.
+ * GB_RETURN_POINTER: for GB_RETURN_COPY, clients must specify
+ * the offset so they know how much space to allocate.
*/
#define GB_OFFSET_0 (1L<<24) /* no offsetting */
#define GB_OFFSET_SPECIFIED (1L<<25) /* client-specified offset */
#define GB_OFFSET_ANY (1L<<26) /* any offset is acceptable */
- /* (for GB_RETURN_POINTER only) */
+ /* (for GB_RETURN_POINTER only) */
/*unused*/ /*(1L<<27)*/
#define GB_OFFSET_ALL\
@@ -174,7 +191,7 @@ typedef ulong gx_bitmap_format_t;
#define GB_RASTER_STANDARD (1L<<28)
#define GB_RASTER_SPECIFIED (1L<<29) /* any client-specified raster */
#define GB_RASTER_ANY (1L<<30) /* any raster is acceptable (for */
- /* GB_RETURN_POINTER only) */
+ /* GB_RETURN_POINTER only) */
#define GB_RASTER_ALL\
(GB_RASTER_STANDARD | GB_RASTER_SPECIFIED | GB_RASTER_ANY)
@@ -184,6 +201,7 @@ typedef ulong gx_bitmap_format_t;
/* Define names for debugging printout. */
#define GX_BITMAP_FORMAT_NAMES\
GB_COLORS_NAMES, GB_ALPHA_NAMES, GB_DEPTH_NAMES, GB_PACKING_NAMES,\
- GB_RETURN_NAMES, GB_ALIGN_NAMES, GB_OFFSET_NAMES, GB_RASTER_NAMES
+ GB_SELECT_NAMES, GB_RETURN_NAMES, GB_ALIGN_NAMES, GB_OFFSET_NAMES,\
+ GB_RASTER_NAMES
#endif /* gxbitfmt_INCLUDED */
diff --git a/gs/src/gxbitmap.h b/gs/src/gxbitmap.h
index af46af903..446c2e47e 100644
--- a/gs/src/gxbitmap.h
+++ b/gs/src/gxbitmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -57,20 +57,26 @@ typedef gs_bitmap_id gx_bitmap_id;
* raster >= bitmap_raster(size.x * depth)
* raster % align_bitmap_mod = 0
*/
-#define gx_bitmap_common gs_bitmap_common
+#define gx_bitmap_common(data_type) gs_bitmap_common(data_type)
typedef struct gx_bitmap_s {
- gx_bitmap_common;
+ gx_bitmap_common(byte);
} gx_bitmap;
+typedef struct gx_const_bitmap_s {
+ gx_bitmap_common(const byte);
+} gx_const_bitmap;
/*
* Define the gx analogue of the tile bitmap structure. Note that if
* shift != 0 (for strip bitmaps, see below), size.y and rep_height
* mean something slightly different: see below for details.
*/
-#define gx_tile_bitmap_common gs_tile_bitmap_common
+#define gx_tile_bitmap_common(data_type) gs_tile_bitmap_common(data_type)
typedef struct gx_tile_bitmap_s {
- gx_tile_bitmap_common;
+ gx_tile_bitmap_common(byte);
} gx_tile_bitmap;
+typedef struct gx_const_tile_bitmap_s {
+ gx_tile_bitmap_common(const byte);
+} gx_const_tile_bitmap;
/*
* For halftones at arbitrary angles, we provide for storing the halftone
@@ -109,13 +115,16 @@ typedef struct gx_tile_bitmap_s {
* rep_shift < rep_width
* shift = (rep_shift * (size.y / rep_height)) % rep_width
*/
-#define gx_strip_bitmap_common\
- gx_tile_bitmap_common;\
+#define gx_strip_bitmap_common(data_type)\
+ gx_tile_bitmap_common(data_type);\
ushort rep_shift;\
ushort shift
typedef struct gx_strip_bitmap_s {
- gx_strip_bitmap_common;
+ gx_strip_bitmap_common(byte);
} gx_strip_bitmap;
+typedef struct gx_const_strip_bitmap_s {
+ gx_strip_bitmap_common(const byte);
+} gx_const_strip_bitmap;
extern_st(st_gx_strip_bitmap);
#define public_st_gx_strip_bitmap() /* in gspcolor.c */\
diff --git a/gs/src/gxccman.c b/gs/src/gxccman.c
index 11bcc60fe..0e8e09fda 100644
--- a/gs/src/gxccman.c
+++ b/gs/src/gxccman.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,7 +28,7 @@
#include "gxfixed.h"
#include "gxmatrix.h"
#include "gzstate.h"
-#include "gzpath.h"
+#include "gxpath.h"
#include "gxdevice.h"
#include "gxdevmem.h"
#include "gxchar.h"
@@ -39,9 +39,14 @@
/* Define the descriptors for the cache structures. */
private_st_cached_fm_pair();
private_st_cached_fm_pair_elt();
- /*private_st_cached_char(); *//* unused */
+/*private_st_cached_char(); *//* unused */
private_st_cached_char_ptr(); /* unused */
private_st_cached_char_ptr_elt();
+/*
+ * Define a descriptor for the cache data. This is equivalent to st_bytes,
+ * but it identifies the cache data as such in a memory dump.
+ */
+gs_private_st_simple(st_font_cache_bytes, byte, "font cache bytes");
/* GC procedures */
/* We do all the work in font_dir_enum/reloc_ptrs in gsfont.c. */
/* See gxfcache.h for details. */
@@ -349,7 +354,7 @@ gx_alloc_char_bits(gs_font_dir * dir, gx_device_memory * dev,
{
int log2_xscale = pscale->x;
int log2_yscale = pscale->y;
- int log2_depth = depth >> 1; /* works for 1,2,4 */
+ int log2_depth = ilog2(depth);
uint nwidth_bits = (iwidth >> log2_xscale) << log2_depth;
ulong isize, icdsize;
uint iraster;
@@ -379,20 +384,22 @@ gx_alloc_char_bits(gs_font_dir * dir, gx_device_memory * dev,
if (dev2 == 0) {
/* Render to a full (possibly oversampled) bitmap; */
/* compress (if needed) when done. */
+ /* Preserve the reference count, if any, and target. */
rc_header rc;
+ gx_device *target = pdev->target;
- /* Preserve the reference count, if any. */
rc = pdev->rc;
- gs_make_mem_mono_device(pdev, pdev->memory, pdev->target);
+ gs_make_mem_mono_device(pdev, pdev->memory, NULL);
pdev->rc = rc;
+ pdev->target = target;
pdev->width = iwidth;
pdev->height = iheight;
isize = gdev_mem_bitmap_size(pdev);
} else {
/* Use an alpha-buffer device to compress as we go. */
+ /* Preserve the reference counts, if any. */
rc_header rc;
- /* Preserve the reference counts, if any. */
rc = dev2->rc;
gs_make_mem_alpha_device(dev2, dev2->memory, NULL, depth);
dev2->rc = rc;
@@ -515,7 +522,7 @@ gx_add_char_bits(gs_font_dir * dir, cached_char * cc,
uint raster = cc_raster(cc);
byte *bits = cc_bits(cc);
int depth = cc_depth(cc);
- int log2_depth = depth >> 1; /* works for 1,2,4 */
+ int log2_depth = ilog2(depth);
uint nwidth_bits, nraster;
gs_int_rect bbox;
@@ -580,24 +587,19 @@ gx_add_char_bits(gs_font_dir * dir, cached_char * cc,
bits, nraster, plog2_scale, log2_depth);
bbox.p.x >>= log2_x;
bbox.p.y >>= log2_y;
- } else { /* No oversampling, just remove white space. */
+ } else {
+ /* No oversampling, just remove white space on all 4 sides. */
const byte *from = bits + raster * bbox.p.y + (bbox.p.x >> 3);
cc->height = bbox.q.y - bbox.p.y;
- /*
- * We'd like to trim off left and right blank space,
- * but currently we're only willing to move bytes, not bits.
- * (If we ever want to do better, we must remember that
- * we can only trim whole pixels, and a pixel may occupy
- * more than one bit.)
- */
bbox.p.x &= ~7; /* adjust to byte boundary */
bbox.p.x >>= log2_depth; /* bits => pixels */
bbox.q.x = (bbox.q.x + depth - 1) >> log2_depth; /* ditto */
cc->width = bbox.q.x - bbox.p.x;
nwidth_bits = cc->width << log2_depth;
nraster = bitmap_raster(nwidth_bits);
- if (bbox.p.x != 0 || nraster != raster) { /* Move the bits down and over. */
+ if (bbox.p.x != 0 || nraster != raster) {
+ /* Move the bits down and over. */
byte *to = bits;
uint n = cc->height;
@@ -624,7 +626,7 @@ gx_add_char_bits(gs_font_dir * dir, cached_char * cc,
cc_set_raster(cc, nraster);
{
- uint diff = round_down(cc->head.size - sizeof_cached_char -
+ uint diff = ROUND_DOWN(cc->head.size - sizeof_cached_char -
nraster * cc->height,
align_cached_char_mod);
@@ -691,8 +693,9 @@ alloc_char(gs_font_dir * dir, ulong icdsize)
if (cck == 0)
return 0;
cdata =
- gs_alloc_bytes_immovable(mem, cksize,
- "char cache chunk(data)");
+ gs_alloc_struct_array_immovable(mem, cksize, byte,
+ &st_font_cache_bytes,
+ "char cache chunk(data)");
if (cdata == 0) {
gs_free_object(mem, cck, "char cache chunk");
return 0;
diff --git a/gs/src/gxcdevn.h b/gs/src/gxcdevn.h
new file mode 100644
index 000000000..4a9ce84ab
--- /dev/null
+++ b/gs/src/gxcdevn.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Internal definitions for DeviceN color spaces */
+
+#ifndef gxcdevn_INCLUDED
+# define gxcdevn_INCLUDED
+
+#include "gsrefct.h"
+#include "gxcindex.h"
+
+/* Cache for DeviceN color. Note that currently this is a 1-entry cache. */
+#ifndef gs_device_n_map_DEFINED
+# define gs_device_n_map_DEFINED
+typedef struct gs_device_n_map_s gs_device_n_map;
+#endif
+struct gs_device_n_map_s {
+ rc_header rc;
+ int (*tint_transform)(P5(const gs_device_n_params * params,
+ const float *in, float *out,
+ const gs_imager_state *pis, void *data));
+ void *tint_transform_data;
+ bool cache_valid;
+ float tint[GS_CLIENT_COLOR_MAX_COMPONENTS];
+ frac conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
+};
+#define private_st_device_n_map() /* in gscdevn.c */\
+ gs_private_st_ptrs1(st_device_n_map, gs_device_n_map, "gs_device_n_map",\
+ device_n_map_enum_ptrs, device_n_map_reloc_ptrs, tint_transform_data)
+
+/* Allocate and initialize a DeviceN map. */
+int alloc_device_n_map(P3(gs_device_n_map ** ppmap, gs_memory_t * mem,
+ client_name_t cname));
+
+#endif /* gxcdevn_INCLUDED */
diff --git a/gs/src/gxchar.h b/gs/src/gxchar.h
index 6b1c3951a..8eef4d3e5 100644
--- a/gs/src/gxchar.h
+++ b/gs/src/gxchar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -123,33 +123,35 @@ struct gs_show_enum_s {
int level; /* save the level of pgs */
gs_char_path_mode charpath_flag;
gs_state *show_gstate; /* for setting pgs->show_gstate */
- /* at returns/callouts */
+ /* at returns/callouts */
int can_cache; /* -1 if can't use cache at all, */
- /* 0 if can read but not load, */
- /* 1 if can read and load */
+ /* 0 if can read but not load, */
+ /* 1 if can read and load */
gs_int_rect ibox; /* int version of quick-check */
- /* (inner) clipping box */
+ /* (inner) clipping box */
gs_int_rect obox; /* int version of (outer) clip box */
int ftx, fty; /* transformed font translation */
/* Following are updated dynamically */
- gs_glyph(*encode_char) (P3(gs_show_enum *, gs_font *, gs_char *));
- /* copied from font, */
- /* except for glyphshow */
+ gs_glyph(*encode_char) (P3(gs_show_enum *, gs_font *, gs_char *));
+ /* copied from font, */
+ /* except for glyphshow */
gs_log2_scale_point log2_suggested_scale; /* suggested scaling */
- /* factors for oversampling, */
- /* based on FontBBox and CTM */
+ /* factors for oversampling, */
+ /* based on FontBBox and CTM */
gx_device_memory *dev_cache; /* cache device */
gx_device_memory *dev_cache2; /* underlying alpha memory device, */
- /* if dev_cache is an alpha buffer */
+ /* if dev_cache is an alpha buffer */
gx_device_null *dev_null; /* null device for stringwidth */
- /*uint index; *//* index within string */
+ /*uint index; */ /* index within string */
gs_char current_char; /* current char for render or move */
gs_glyph current_glyph; /* current glyph ditto */
+ int cmap_code; /* for FMapType 9 composite fonts, */
+ /* the value returned by decode_next */
gs_fixed_point wxy; /* width of current char */
- /* in device coords */
+ /* in device coords */
gs_fixed_point origin; /* unrounded origin of current char */
- /* in device coords, needed for */
- /* charpath and WMode=1 */
+ /* in device coords, needed for */
+ /* charpath and WMode=1 */
cached_char *cc; /* being accumulated */
gs_point width; /* total width of string, set at end */
show_width_status width_status;
diff --git a/gs/src/gxcht.c b/gs/src/gxcht.c
index 60439fad4..f0058179c 100644
--- a/gs/src/gxcht.c
+++ b/gs/src/gxcht.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,6 +31,9 @@
#include "gxistate.h"
#include "gzht.h"
+/* Define whether to force use of the slow code, for testing. */
+#define USE_SLOW_CODE 0
+
/* Define the size of the tile buffer allocated on the stack. */
#define tile_longs_LARGE 256
#define tile_longs_SMALL 64
@@ -63,28 +66,76 @@ const gx_device_color_type_t *const gx_dc_type_ht_colored =
&gx_dc_type_data_ht_colored;
#define gx_dc_type_ht_colored (&gx_dc_type_data_ht_colored)
+/* Compare two colored halftones for equality. */
+private bool
+gx_dc_ht_colored_equal(const gx_device_color * pdevc1,
+ const gx_device_color * pdevc2)
+{
+ uint num_comp;
+
+ if (pdevc2->type != pdevc1->type ||
+ pdevc1->colors.colored.c_ht != pdevc2->colors.colored.c_ht ||
+ pdevc1->colors.colored.alpha != pdevc2->colors.colored.alpha ||
+ pdevc1->phase.x != pdevc2->phase.x ||
+ pdevc1->phase.y != pdevc2->phase.y
+ )
+ return false;
+ num_comp = pdevc1->colors.colored.c_ht->num_comp;
+ return
+ !memcmp(pdevc1->colors.colored.c_base,
+ pdevc2->colors.colored.c_base,
+ num_comp * sizeof(pdevc1->colors.colored.c_base[0])) &&
+ !memcmp(pdevc1->colors.colored.c_level,
+ pdevc2->colors.colored.c_level,
+ num_comp * sizeof(pdevc1->colors.colored.c_level[0]));
+}
+
+/* Define an abbreviation for a heavily used value. */
+#define MAX_DCC GX_DEVICE_COLOR_MAX_COMPONENTS
+
/* Forward references. */
-private int set_ht_colors(P6(gx_color_index[16], gx_strip_bitmap *[4],
- const gx_device_color *, gx_device *,
- gx_ht_cache *[4], int));
-private int set_cmyk_1bit_colors(P6(gx_color_index[16], gx_strip_bitmap *[4],
- const gx_device_color *, gx_device *,
- gx_ht_cache *[4], int));
-private void set_color_ht(P11(byte *, uint, int, int, int, int, int, int, int,
- const gx_color_index[16],
- const gx_strip_bitmap *[4]));
+/* Use a typedef to attempt to work around overly picky compilers. */
+typedef gx_color_value gx_color_value_array[MAX_DCC];
+typedef struct color_values_pair_s {
+ gx_color_value_array values[2];
+} color_values_pair_t;
+#define SET_HT_COLORS_PROC(proc)\
+ int proc(P7(\
+ color_values_pair_t *pvp,\
+ gx_color_index colors[1 << MAX_DCC],\
+ const gx_const_strip_bitmap *sbits[MAX_DCC],\
+ const gx_device_color *pdevc,\
+ gx_device *dev,\
+ gx_ht_cache *caches[MAX_DCC],\
+ int nplanes\
+ ))
-/* Define a table for expanding 8x1 bits to 8x4. */
-private const bits32 expand_8x1_to_8x4[256] = {
-#define x16(c)\
- c+0, c+1, c+0x10, c+0x11, c+0x100, c+0x101, c+0x110, c+0x111,\
- c+0x1000, c+0x1001, c+0x1010, c+0x1011, c+0x1100, c+0x1101, c+0x1110, c+0x1111
- x16(0x00000000), x16(0x00010000), x16(0x00100000), x16(0x00110000),
- x16(0x01000000), x16(0x01010000), x16(0x01100000), x16(0x01110000),
- x16(0x10000000), x16(0x10010000), x16(0x10100000), x16(0x10110000),
- x16(0x11000000), x16(0x11010000), x16(0x11100000), x16(0x11110000)
-#undef x16
-};
+private SET_HT_COLORS_PROC(set_ht_colors_le_4);
+private SET_HT_COLORS_PROC(set_cmyk_1bit_colors);
+private SET_HT_COLORS_PROC(set_ht_colors_gt_4);
+
+#define SET_COLOR_HT_PROC(proc)\
+ void proc(P14(\
+ byte *dest_data, /* the output tile */\
+ uint dest_raster, /* ibid. */\
+ int px, /* the initial phase of the output tile */\
+ int py,\
+ int w, /* how much of the tile to set */\
+ int h,\
+ int depth, /* depth of tile (4, 8, 16, 24, 32) */\
+ int special, /* >0 means special 1-bit CMYK */\
+ int nplanes,\
+ gx_color_index plane_mask, /* which planes are halftoned */\
+ gx_device *dev, /* in case we are mapping lazily */\
+ const color_values_pair_t *pvp, /* color values ditto */\
+ gx_color_index colors[1 << MAX_DCC], /* the actual colors for the tile, */\
+ /* actually [1 << nplanes] */\
+ const gx_const_strip_bitmap * sbits[MAX_DCC] /* the bitmaps for the planes, */\
+ /* actually [nplanes] */\
+ ))
+
+private SET_COLOR_HT_PROC(set_color_ht_le_4);
+private SET_COLOR_HT_PROC(set_color_ht_gt_4);
/* Prepare to use a colored halftone, by loading the default cache. */
private int
@@ -95,7 +146,7 @@ gx_dc_ht_colored_load(gx_device_color * pdevc, const gs_imager_state * pis,
gx_ht_order *porder = &pdht->components[0].corder;
gx_ht_cache *pcache = pis->ht_cache;
- if (pcache->order.bits != porder->bits)
+ if (pcache->order.bit_data != porder->bit_data)
gx_ht_init_cache(pcache, porder);
/* Set the cache pointers in the default order. */
pdht->order.cache = porder->cache = pcache;
@@ -117,9 +168,17 @@ gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc,
const gx_device_halftone *pdht = pdevc->colors.colored.c_ht;
int depth = dev->color_info.depth;
int nplanes = dev->color_info.num_components;
- gx_color_index colors[16];
- gx_strip_bitmap *sbits[4];
- gx_ht_cache *caches[4];
+ SET_COLOR_HT_PROC((*set_color_ht)) =
+ (
+#if !USE_SLOW_CODE
+ !(pdevc->colors.colored.plane_mask & ~(gx_color_index)15) ?
+ set_color_ht_le_4 :
+#endif
+ set_color_ht_gt_4);
+ color_values_pair_t vp;
+ gx_color_index colors[1 << MAX_DCC];
+ const gx_const_strip_bitmap *sbits[MAX_DCC];
+ gx_ht_cache *caches[MAX_DCC];
int special;
int code = 0;
int raster;
@@ -127,24 +186,59 @@ gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc,
int dw, dh;
int lw = pdht->lcm_width, lh = pdht->lcm_height;
bool no_rop;
+ int i;
if (w <= 0 || h <= 0)
return 0;
+ if ((w | h) >= 16) {
+ /* It's worth taking the trouble to check the clipping box. */
+ gs_fixed_rect cbox;
+ int t;
+
+ dev_proc(dev, get_clipping_box)(dev, &cbox);
+ if ((t = fixed2int(cbox.p.x)) > x) {
+ if ((w += x - t) <= 0)
+ return 0;
+ x = t;
+ }
+ if ((t = fixed2int(cbox.p.y)) > y) {
+ if ((h += y - t) <= 0)
+ return 0;
+ y = t;
+ }
+ if ((t = fixed2int(cbox.q.x)) < x + w)
+ if ((w = t - x) <= 0)
+ return 0;
+ if ((t = fixed2int(cbox.q.y)) < y + h)
+ if ((h = t - y) <= 0)
+ return 0;
+ }
/* Colored halftone patterns are unconditionally opaque. */
lop &= ~lop_T_transparent;
- if (pdht->components == 0)
+ if (pdht->components == 0) {
caches[0] = caches[1] = caches[2] = caches[3] = pdht->order.cache;
- else {
+ for (i = 4; i < nplanes; ++i)
+ caches[i] = pdht->order.cache;
+ } else {
gx_ht_order_component *pocs = pdht->components;
caches[0] = pocs[pdht->color_indices[0]].corder.cache;
caches[1] = pocs[pdht->color_indices[1]].corder.cache;
caches[2] = pocs[pdht->color_indices[2]].corder.cache;
caches[3] = pocs[pdht->color_indices[3]].corder.cache;
+ for (i = 4; i < nplanes; ++i)
+ caches[i] = pocs[pdht->color_indices[i]].corder.cache;
}
- special = (dev_proc(dev, map_cmyk_color) == cmyk_1bit_map_cmyk_color ?
- set_cmyk_1bit_colors : set_ht_colors)
- (colors, sbits, pdevc, dev, caches, nplanes);
+ special =
+#if USE_SLOW_CODE
+ set_ht_colors_gt_4
+#else
+ (dev_proc(dev, map_cmyk_color) == cmyk_1bit_map_cmyk_color ?
+ set_cmyk_1bit_colors :
+ nplanes < 4 ? set_ht_colors_le_4 :
+ set_ht_colors_gt_4)
+#endif
+ (&vp, colors, sbits, pdevc, dev, caches, nplanes);
no_rop = source == NULL && lop_no_S_is_T(lop);
/*
* If the LCM of the plane cell sizes is smaller than the rectangle
@@ -169,10 +263,9 @@ gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc,
tiles.rep_height = tiles.size.y = lh;
tiles.id = gs_next_ids(1);
tiles.rep_shift = tiles.shift = 0;
- /* See below for why we need to cast bits. */
set_color_ht((byte *)tbits, raster, 0, 0, lw, lh, depth,
- special, pdevc->colors.colored.plane_mask, colors,
- (const gx_strip_bitmap **)sbits);
+ special, nplanes, pdevc->colors.colored.plane_mask,
+ dev, &vp, colors, sbits);
if (no_rop)
return (*dev_proc(dev, strip_tile_rectangle)) (dev, &tiles,
x, y, w, h,
@@ -230,16 +323,11 @@ fit: /* Now the tile will definitely fit. */
int cy = y, ch = dh, left = h;
for (;;) {
- /*
- * The cast in the following statement is bogus,
- * but some compilers won't accept an array type,
- * and won't accept the ** type without a cast.
- */
set_color_ht((byte *)tbits, raster,
x + pdevc->phase.x, cy + pdevc->phase.y,
- dw, ch, depth, special,
+ dw, ch, depth, special, nplanes,
pdevc->colors.colored.plane_mask,
- colors, (const gx_strip_bitmap **)sbits);
+ dev, &vp, colors, sbits);
if (no_rop) {
code = (*dev_proc(dev, copy_color))
(dev, (byte *)tbits, 0, raster, gx_no_bitmap_id,
@@ -272,70 +360,87 @@ fit: /* Now the tile will definitely fit. */
return code;
}
+/* ---------------- Color table setup ---------------- */
+
/*
- * We construct color halftone tiles out of 3 or 4 "planes".
- * Each plane specifies halftoning for one component (R/G/B or C/M/Y/K).
+ * We could cache this if we had a place to store it. Even a 1-element
+ * cache would help performance substantially.
+ * Key: device + c_base/c_level of device color
+ * Value: colors table
*/
-private const ulong ht_no_bitmap_data[] = {
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-private gx_strip_bitmap ht_no_bitmap;
-private const gx_strip_bitmap ht_no_bitmap_init = {
- 0, sizeof(ulong),
- {sizeof(ulong) * 8, countof(ht_no_bitmap_data)},
+/*
+ * We construct color halftone tiles out of multiple "planes".
+ * Each plane specifies halftoning for one component (R/G/B, C/M/Y/K,
+ * or DeviceN components).
+ */
+
+private const struct {
+ ulong pad; /* to get bytes aligned properly */
+ byte bytes[sizeof(ulong) * 8]; /* 8 is arbitrary */
+} ht_no_bitmap_data = { 0 };
+private const gx_const_strip_bitmap ht_no_bitmap = {
+ &ht_no_bitmap_data.bytes[0], sizeof(ulong),
+ {sizeof(ulong) * 8, sizeof(ht_no_bitmap_data.bytes) / sizeof(ulong)},
gx_no_bitmap_id, 1, 1, 0, 0
};
-void
-gs_gxcht_init(gs_memory_t *mem)
-{
- ht_no_bitmap = ht_no_bitmap_init;
- ht_no_bitmap.data = (byte *)ht_no_bitmap_data; /* actually const */
-}
+/* Set the color value(s) and halftone mask for one plane. */
-/* Set up the colors and the individual plane halftone bitmaps. */
-private int
-set_ht_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
- const gx_device_color * pdc, gx_device * dev,
- gx_ht_cache * caches[4], int nplanes)
-{
- gx_color_value v[2][4];
- gx_color_value max_color = dev->color_info.dither_colors - 1;
- /*
- * NB: the halftone orders are all set up for an additive color space.
- * To use these work with a cmyk color space, it is necessary to
- * invert both the color level and the color pair. Note that if the
- * original color was provided an additive space, this will reverse
- * (in an approximate sense) the color conversion performed to
- * express the color in cmyk space.
- */
- bool invert = dev->color_info.num_components == 4; /****** HACK ******/
+/* Free variables: pvp, pdc, sbits */
+#define SET_PLANE_COLOR_CONSTANT(i)\
+ BEGIN\
+ pvp->values[1][i] = pvp->values[0][i] = pdc->colors.colored.c_base[i];\
+ sbits[i] = &ht_no_bitmap;\
+ END
-#define set_plane_color(i)\
+/* Free variables: pvp, pdc, sbits, caches, invert, max_color */
+#define SET_PLANE_COLOR(i)\
BEGIN\
uint q = pdc->colors.colored.c_base[i];\
uint r = pdc->colors.colored.c_level[i];\
\
- v[0][i] = fractional_color(q, max_color);\
+ pvp->values[0][i] = fractional_color(q, max_color);\
if (r == 0)\
- v[1][i] = v[0][i], sbits[i] = &ht_no_bitmap;\
+ pvp->values[1][i] = pvp->values[0][i], sbits[i] = &ht_no_bitmap;\
else if (!invert) {\
- v[1][i] = fractional_color(q + 1, max_color);\
- sbits[i] = &gx_render_ht(caches[i], r)->tiles;\
+ pvp->values[1][i] = fractional_color(q + 1, max_color);\
+ sbits[i] = (const gx_const_strip_bitmap *)\
+ &gx_render_ht(caches[i], r)->tiles;\
} else { \
const gx_device_halftone *pdht = pdc->colors.colored.c_ht; \
int nlevels =\
pdht->components[pdht->color_indices[i]].corder.num_levels;\
\
- v[1][i] = v[0][i]; \
- v[0][i] = fractional_color(q + 1, max_color); \
- sbits[i] = &gx_render_ht(caches[i], nlevels - r)->tiles; \
+ pvp->values[1][i] = pvp->values[0][i]; \
+ pvp->values[0][i] = fractional_color(q + 1, max_color); \
+ sbits[i] = (const gx_const_strip_bitmap *)\
+ &gx_render_ht(caches[i], nlevels - r)->tiles; \
}\
END
- set_plane_color(0);
- set_plane_color(1);
- set_plane_color(2);
+
+/* Set up the colors and the individual plane halftone bitmaps. */
+private int
+set_ht_colors_le_4(color_values_pair_t *pvp /* only used internally */,
+ gx_color_index colors[1 << MAX_DCC],
+ const gx_const_strip_bitmap * sbits[MAX_DCC],
+ const gx_device_color * pdc, gx_device * dev,
+ gx_ht_cache * caches[MAX_DCC], int nplanes)
+{
+ gx_color_value max_color = dev->color_info.dither_colors - 1;
+ /*
+ * NB: the halftone orders are all set up for an additive color space.
+ * To make these work with a subtractive device space such as CMYK,
+ * it is necessary to invert both the color level and the color
+ * pair. Note that if the original color was provided an additive
+ * space, this will reverse (in an approximate sense) the color
+ * conversion performed to express the color in the device space.
+ */
+ bool invert = dev->color_info.num_components >= 4; /****** HACK ******/
+
+ SET_PLANE_COLOR(0);
+ SET_PLANE_COLOR(1);
+ SET_PLANE_COLOR(2);
if (nplanes == 3) {
gx_color_value alpha = pdc->colors.colored.alpha;
@@ -345,30 +450,45 @@ set_ht_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
dev_proc_map_rgb_color((*gx_map_rgb_color)) =
dev_proc(dev, map_rgb_color);
#endif
-#define m(i)\
- colors[i] = gx_map_rgb_color(dev, v[(i) & 1][0], v[((i) & 2) >> 1][1],\
- v[(i) >> 2][2])
- m(0); m(1); m(2); m(3); m(4); m(5); m(6); m(7);
-#undef m
+#define M(i)\
+ colors[i] = gx_map_rgb_color(dev, pvp->values[(i) & 1][0],\
+ pvp->values[((i) & 2) >> 1][1],\
+ pvp->values[(i) >> 2][2])
+ M(0); M(1); M(2); M(3); M(4); M(5); M(6); M(7);
+#undef M
} else {
#ifndef DEBUG
# undef gx_map_rgb_alpha_color
dev_proc_map_rgb_alpha_color((*gx_map_rgb_alpha_color)) =
dev_proc(dev, map_rgb_alpha_color);
#endif
-#define m(i)\
- colors[i] = gx_map_rgb_alpha_color(dev, v[(i) & 1][0], v[((i) & 2) >> 1][1],\
- v[(i) >> 2][2], alpha)
- m(0); m(1); m(2); m(3); m(4); m(5); m(6); m(7);
-#undef m
+#define M(i)\
+ colors[i] = gx_map_rgb_alpha_color(dev, pvp->values[(i) & 1][0],\
+ pvp->values[((i) & 2) >> 1][1],\
+ pvp->values[(i) >> 2][2], alpha)
+ M(0); M(1); M(2); M(3); M(4); M(5); M(6); M(7);
+#undef M
}
} else {
-#ifndef DEBUG
-# undef gx_map_cmyk_color
- dev_proc_map_cmyk_color((*gx_map_cmyk_color)) =
+#ifdef DEBUG
+# define do_map_cmyk_color(dev, c, m, y, k) gx_map_cmyk_color(dev, c, m, y, k)
+#else
+ dev_proc_map_cmyk_color((*do_map_cmyk_color)) =
dev_proc(dev, map_cmyk_color);
#endif
- set_plane_color(3);
+ SET_PLANE_COLOR(3);
+ if (nplanes > 4) {
+ /*
+ * Set colors for any planes beyond the 4th. Since this code
+ * only handles the case of at most 4 active planes, we know
+ * that any further planes are constant.
+ */
+ /****** DOESN'T MAP COLORS RIGHT, DOESN'T HANDLE ALPHA ******/
+ int pi;
+
+ for (pi = 4; pi < nplanes; ++pi)
+ SET_PLANE_COLOR_CONSTANT(pi);
+ }
/*
* For CMYK output, especially if the input was RGB, it's
* common for one or more of the components to be zero.
@@ -376,63 +496,71 @@ set_ht_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
* half, so it's worth doing a little checking here.
*/
-#define m(i)\
- colors[i] = gx_map_cmyk_color(dev, v[(i) & 1][0], v[((i) & 2) >> 1][1],\
- v[((i) & 4) >> 2][2], v[(i) >> 3][3])
- switch (pdc->colors.colored.plane_mask) {
+#define M(i)\
+ colors[i] = do_map_cmyk_color(dev, pvp->values[(i) & 1][0],\
+ pvp->values[((i) & 2) >> 1][1],\
+ pvp->values[((i) & 4) >> 2][2],\
+ pvp->values[(i) >> 3][3])
+
+ /* We know that plane_mask <= 15. */
+ switch ((int)pdc->colors.colored.plane_mask) {
case 15:
- m(15); m(14); m(13); m(12);
- m(11); m(10); m(9); m(8);
+ M(15); M(14); M(13); M(12);
+ M(11); M(10); M(9); M(8);
case 7:
- m(7); m(6); m(5); m(4);
+ M(7); M(6); M(5); M(4);
c3: case 3:
- m(3); m(2);
+ M(3); M(2);
c1: case 1:
- m(1);
+ M(1);
break;
case 14:
- m(14); m(12); m(10); m(8);
+ M(14); M(12); M(10); M(8);
case 6:
- m(6); m(4);
+ M(6); M(4);
c2: case 2:
- m(2);
+ M(2);
break;
case 13:
- m(13); m(12); m(9); m(8);
+ M(13); M(12); M(9); M(8);
case 5:
- m(5); m(4);
+ M(5); M(4);
goto c1;
case 12:
- m(12); m(8);
+ M(12); M(8);
case 4:
- m(4);
+ M(4);
break;
case 11:
- m(11); m(10); m(9); m(8);
+ M(11); M(10); M(9); M(8);
goto c3;
case 10:
- m(10); m(8);
+ M(10); M(8);
goto c2;
case 9:
- m(9); m(8);
+ M(9); M(8);
goto c1;
case 8:
- m(8);
+ M(8);
break;
case 0:;
}
- m(0);
-#undef m
+ M(0);
+
+#undef M
+
}
-#undef set_plane_color
return 0;
}
/* Set up colors using the standard 1-bit CMYK mapping. */
private int
-set_cmyk_1bit_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
+set_cmyk_1bit_colors(color_values_pair_t *ignore_pvp,
+ gx_color_index colors[1 << MAX_DCC /*16 used*/],
+ const gx_const_strip_bitmap * sbits[MAX_DCC /*4 used*/],
const gx_device_color * pdc, gx_device * dev,
- gx_ht_cache * caches[4], int nplanes /*4*/)
+ gx_ht_cache * caches[MAX_DCC /*4 used*/],
+ int nplanes /*4*/)
{
const gx_device_halftone *pdht = pdc->colors.colored.c_ht;
/*
@@ -447,7 +575,7 @@ set_cmyk_1bit_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
* the values in all the nibbles so we can do several pixels at a time.
*/
bits32 mask0 = 0, mask1 = 0;
-#define set_plane_color(i, mask)\
+#define SET_PLANE_COLOR_CMYK(i, mask)\
BEGIN\
uint r = pdc->colors.colored.c_level[i];\
\
@@ -460,14 +588,16 @@ set_cmyk_1bit_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
pdht->components[pdht->color_indices[i]].corder.num_levels;\
\
mask0 |= mask;\
- sbits[3 - i] = &gx_render_ht(caches[i], nlevels - r)->tiles;\
+ sbits[3 - i] = (const gx_const_strip_bitmap *)\
+ &gx_render_ht(caches[i], nlevels - r)->tiles;\
}\
END
- set_plane_color(0, 0x88888888);
- set_plane_color(1, 0x44444444);
- set_plane_color(2, 0x22222222);
- set_plane_color(3, 0x11111111);
-#undef set_plane_color
+ /* Suppress a compiler warning about signed/unsigned constants. */
+ SET_PLANE_COLOR_CMYK(0, /*0x88888888*/ (bits32)~0x77777777);
+ SET_PLANE_COLOR_CMYK(1, 0x44444444);
+ SET_PLANE_COLOR_CMYK(2, 0x22222222);
+ SET_PLANE_COLOR_CMYK(3, 0x11111111);
+#undef SET_PLANE_COLOR_CMYK
{
gx_ht_cache *ctemp;
@@ -479,6 +609,46 @@ set_cmyk_1bit_colors(gx_color_index colors[16], gx_strip_bitmap * sbits[4],
return 1;
}
+/*
+ * Set up colors for >4 planes. In this case, we compute the colors
+ * themselves lazily.
+ */
+private int
+set_ht_colors_gt_4(color_values_pair_t *pvp,
+ gx_color_index colors[1 << MAX_DCC],
+ const gx_const_strip_bitmap * sbits[MAX_DCC],
+ const gx_device_color * pdc, gx_device * dev,
+ gx_ht_cache * caches[MAX_DCC], int nplanes)
+{
+ gx_color_value max_color = dev->color_info.dither_colors - 1;
+ /* See set_ht_color_le_4 for invert. */
+ bool invert = true; /****** HACK ******/
+ gx_color_index plane_mask = pdc->colors.colored.plane_mask;
+ int i;
+ gx_color_index ci;
+
+ /* Set the color values and halftone caches. */
+ for (i = 0; i < nplanes; ++i)
+ if ((plane_mask >> i) & 1)
+ SET_PLANE_COLOR(i);
+ else
+ SET_PLANE_COLOR_CONSTANT(i);
+
+ /*
+ * Clear the color table entries that will actually be used, namely,
+ * those whose indices are either 0 or 1 in bits selected by plane_mask
+ * and 0 in all other bits.
+ */
+ ci = 0;
+ do {
+ colors[ci] = gx_no_color_index;
+ } while ((ci = ((ci | ~plane_mask) + 1) & plane_mask) != 0);
+
+ return 0;
+}
+
+/* ---------------- Color rendering ---------------- */
+
/* Define the bookkeeping structure for each plane of halftone rendering. */
typedef struct tile_cursor_s {
int tile_shift; /* X shift per copy of tile */
@@ -498,7 +668,7 @@ typedef struct tile_cursor_s {
* (data and bit_shift).
*/
private void
-init_tile_cursor(int i, tile_cursor_t *ptc, const gx_strip_bitmap *btile,
+init_tile_cursor(int i, tile_cursor_t *ptc, const gx_const_strip_bitmap *btile,
int endx, int lasty)
{
int tw = btile->size.x;
@@ -519,30 +689,66 @@ init_tile_cursor(int i, tile_cursor_t *ptc, const gx_strip_bitmap *btile,
i, tw, btile->size.y, btile->shift, bx, by);
}
-/* Render the combined halftone. */
+/* Step a cursor to the next row. */
+private void
+wrap_shifted_cursor(tile_cursor_t *ptc, const gx_const_strip_bitmap *psbit)
+{
+ ptc->row += ptc->raster * (psbit->size.y - 1);
+ if (ptc->tile_shift) {
+ if ((ptc->xshift += ptc->tile_shift) >= 8) {
+ if ((ptc->xoffset -= ptc->xshift >> 3) < 0) {
+ /* wrap around in X */
+ int bx = (ptc->xoffset << 3) + 8 - (ptc->xshift & 7) +
+ psbit->size.x;
+
+ ptc->xoffset = bx >> 3;
+ ptc->xshift = 8 - (bx & 7);
+ } else
+ ptc->xshift &= 7;
+ }
+ }
+}
+#define STEP_ROW(c, i)\
+ BEGIN\
+ if (c.row > c.tdata)\
+ c.row -= c.raster;\
+ else { /* wrap around to end of tile */\
+ wrap_shifted_cursor(&c, sbits[i]);\
+ }\
+ c.data = c.row + c.xoffset;\
+ c.bit_shift = c.xshift;\
+ END
+
+/* Define a table for expanding 8x1 bits to 8x4. */
+private const bits32 expand_8x1_to_8x4[256] = {
+#define X16(c)\
+ c+0, c+1, c+0x10, c+0x11, c+0x100, c+0x101, c+0x110, c+0x111,\
+ c+0x1000, c+0x1001, c+0x1010, c+0x1011, c+0x1100, c+0x1101, c+0x1110, c+0x1111
+ X16(0x00000000), X16(0x00010000), X16(0x00100000), X16(0x00110000),
+ X16(0x01000000), X16(0x01010000), X16(0x01100000), X16(0x01110000),
+ X16(0x10000000), X16(0x10010000), X16(0x10100000), X16(0x10110000),
+ X16(0x11000000), X16(0x11010000), X16(0x11100000), X16(0x11110000)
+#undef X16
+};
+
+/*
+ * Render the combined halftone for nplanes <= 4.
+ */
private void
-set_color_ht(
- byte *dest_data, /* the output tile */
- uint dest_raster, /* ibid. */
- int px, /* the initial phase of the output tile */
- int py,
- int w, /* how much of the tile to set */
- int h,
- int depth, /* depth of tile (4, 8, 16, 24, 32) */
- int special, /* >0 means special 1-bit CMYK */
- int plane_mask, /* which planes are halftoned */
- const gx_color_index colors[16], /* the actual colors for the tile, */
- /* actually [1 << nplanes] */
- const gx_strip_bitmap * sbits[4] /* the bitmaps for the planes, */
- /* actually [nplanes] */
-) {
+set_color_ht_le_4(byte *dest_data, uint dest_raster, int px, int py,
+ int w, int h, int depth, int special, int nplanes,
+ gx_color_index plane_mask, gx_device *ignore_dev,
+ const color_values_pair_t *ignore_pvp,
+ gx_color_index colors[1 << MAX_DCC],
+ const gx_const_strip_bitmap * sbits[MAX_DCC])
+{
/*
* Note that the planes are specified in the order RGB or CMYK, but
* the indices used for the internal colors array are BGR or KYMC,
* except for the special 1-bit CMYK case.
*/
int x, y;
- tile_cursor_t cursor[4];
+ tile_cursor_t cursor[MAX_DCC];
int dbytes = depth >> 3;
byte *dest_row =
dest_data + dest_raster * (h - 1) + (w * depth) / 8;
@@ -553,8 +759,8 @@ set_color_ht(
"\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017"[plane_mask];
}
if_debug6('h',
- "[h]color_ht: x=%d y=%d w=%d h=%d plane_mask=%d depth=%d\n",
- px, py, w, h, plane_mask, depth);
+ "[h]color_ht: x=%d y=%d w=%d h=%d plane_mask=0x%lu depth=%d\n",
+ px, py, w, h, (ulong)plane_mask, depth);
/* Do one-time cursor initialization. */
{
@@ -583,7 +789,7 @@ set_color_ht(
/* Get the next byte's worth of bits. Note that there may be */
/* excess bits set beyond the 8th. */
-#define next_bits(c)\
+#define NEXT_BITS(c)\
BEGIN\
if (c.data > c.row) {\
bits = ((c.data[-1] << 8) | *c.data) >> c.bit_shift;\
@@ -601,23 +807,23 @@ set_color_ht(
}\
END
if (plane_mask & 1) {
- next_bits(cursor[0]);
+ NEXT_BITS(cursor[0]);
indices = expand_8x1_to_8x4[bits & 0xff];
} else
indices = 0;
if (plane_mask & 2) {
- next_bits(cursor[1]);
+ NEXT_BITS(cursor[1]);
indices |= expand_8x1_to_8x4[bits & 0xff] << 1;
}
if (plane_mask & 4) {
- next_bits(cursor[2]);
+ NEXT_BITS(cursor[2]);
indices |= expand_8x1_to_8x4[bits & 0xff] << 2;
}
if (plane_mask & 8) {
- next_bits(cursor[3]);
+ NEXT_BITS(cursor[3]);
indices |= expand_8x1_to_8x4[bits & 0xff] << 3;
}
-#undef next_bits
+#undef NEXT_BITS
nx = min(x, 8); /* 1 <= nx <= 8 */
x -= nx;
switch (dbytes) {
@@ -703,61 +909,116 @@ set_color_ht(
if (y == 0)
break;
-#define step_row(c, i)\
- BEGIN\
- if (c.row > c.tdata)\
- c.row -= c.raster;\
- else { /* wrap around to end of tile, taking shift into account */\
- c.row += c.raster * (sbits[i]->size.y - 1);\
- if (c.tile_shift) {\
- if ((c.xshift += c.tile_shift) >= 8) {\
- if ((c.xoffset -= c.xshift >> 3) < 0) {\
- /* wrap around in X */\
- int bx = (c.xoffset << 3) + 8 - (c.xshift & 7) +\
- sbits[i]->size.x;\
- c.xoffset = bx >> 3;\
- c.xshift = 8 - (bx & 7);\
- } else\
- c.xshift &= 7;\
- }\
- }\
- }\
- c.data = c.row + c.xoffset;\
- c.bit_shift = c.xshift;\
- END
-
if (plane_mask & 1)
- step_row(cursor[0], 0);
+ STEP_ROW(cursor[0], 0);
if (plane_mask & 2)
- step_row(cursor[1], 1);
+ STEP_ROW(cursor[1], 1);
if (plane_mask & 4)
- step_row(cursor[2], 2);
+ STEP_ROW(cursor[2], 2);
if (plane_mask & 8)
- step_row(cursor[3], 3);
-#undef step_row
+ STEP_ROW(cursor[3], 3);
}
}
-/* Compare two colored halftones for equality. */
-private bool
-gx_dc_ht_colored_equal(const gx_device_color * pdevc1,
- const gx_device_color * pdevc2)
+/*
+ * Render the combined halftone for nplanes > 4. We haven't made any
+ * attempt to optimize this code.
+ */
+private void
+set_color_ht_gt_4(byte *dest_data, uint dest_raster, int px, int py,
+ int w, int h, int depth, int special, int nplanes,
+ gx_color_index plane_mask, gx_device *dev,
+ const color_values_pair_t *pvp,
+ gx_color_index colors[1 << MAX_DCC],
+ const gx_const_strip_bitmap * sbits[MAX_DCC])
{
- uint num_comp;
+ int x, y;
+ tile_cursor_t cursor[MAX_DCC];
+ int dbytes = depth >> 3;
+ byte *dest_row =
+ dest_data + dest_raster * (h - 1) + (w * depth) / 8;
- if (pdevc2->type != pdevc1->type ||
- pdevc1->colors.colored.c_ht != pdevc2->colors.colored.c_ht ||
- pdevc1->colors.colored.alpha != pdevc2->colors.colored.alpha ||
- pdevc1->phase.x != pdevc2->phase.x ||
- pdevc1->phase.y != pdevc2->phase.y
- )
- return false;
- num_comp = pdevc1->colors.colored.c_ht->num_comp;
- return
- !memcmp(pdevc1->colors.colored.c_base,
- pdevc2->colors.colored.c_base,
- num_comp * sizeof(pdevc1->colors.colored.c_base[0])) &&
- !memcmp(pdevc1->colors.colored.c_level,
- pdevc2->colors.colored.c_level,
- num_comp * sizeof(pdevc1->colors.colored.c_level[0]));
+ /* Compute the number of active planes. */
+ for (nplanes = 0; (plane_mask >> nplanes) != 0; )
+ ++nplanes;
+
+ /* Do one-time cursor initialization. */
+ {
+ int endx = w + px;
+ int lasty = h - 1 + py;
+ int i;
+
+ for (i = 0; i < nplanes; ++i)
+ if ((plane_mask >> i) & 1)
+ init_tile_cursor(i, &cursor[i], sbits[i], endx, lasty);
+ }
+
+ /* Now compute the actual tile. */
+ for (y = h; ; dest_row -= dest_raster) {
+ byte *dest = dest_row;
+ int i;
+
+ --y;
+ for (x = w; x > 0;) {
+ gx_color_index index = 0;
+ gx_color_index tcolor;
+
+ for (i = 0; i < nplanes; ++i)
+ if ((plane_mask >> i) & 1) {
+ /* Get the next bit from an individual mask. */
+ tile_cursor_t *ptc = &cursor[i];
+ byte tile_bit;
+
+b: if (ptc->bit_shift < 8)
+ tile_bit = *ptc->data >> ptc->bit_shift++;
+ else if (ptc->data > ptc->row) {
+ tile_bit = *--(ptc->data);
+ ptc->bit_shift = 1;
+ } else {
+ /* Wrap around. */
+ ptc->data += ptc->xbytes;
+ ptc->bit_shift = 8 - ptc->xbits;
+ goto b;
+ }
+ index |= (gx_color_index)(tile_bit & 1) << i;
+ }
+ tcolor = colors[index];
+ if (tcolor == gx_no_color_index) {
+ /* Map the color value now. */
+ gx_color_value cv[MAX_DCC];
+ int i;
+
+ for (i = 0; i < nplanes; ++i)
+ cv[i] = pvp->values[(index >> i) & 1][i];
+ /****** HACK -- NO WAY TO MAP GENERAL COLORS ******/
+ tcolor = colors[index] =
+ gx_map_cmyk_color(dev, cv[0], cv[1], cv[2], cv[3]);
+ }
+ --x;
+ switch (dbytes) {
+ case 0: /* 4 -- might be 2, but we don't support this */
+ if (x & 1) { /* odd nibble */
+ *--dest = (byte)tcolor;
+ } else { /* even nibble */
+ *dest = (*dest & 0xf) + ((byte)tcolor << 4);
+ }
+ break;
+ case 4: /* 32 */
+ dest[-4] = (byte)(tcolor >> 24);
+ case 3: /* 24 */
+ dest[-3] = (byte)(tcolor >> 16);
+ case 2: /* 16 */
+ dest[-2] = (byte)(tcolor >> 8);
+ case 1: /* 8 */
+ dest[-1] = (byte)tcolor;
+ dest -= dbytes;
+ break;
+ }
+ }
+ if (y == 0)
+ break;
+ for (i = 0; i < nplanes; ++i)
+ if ((plane_mask >> i) & 1)
+ STEP_ROW(cursor[i], i);
+ }
}
diff --git a/gs/src/gxcindex.h b/gs/src/gxcindex.h
index 8c63143ae..0eca0c803 100644
--- a/gs/src/gxcindex.h
+++ b/gs/src/gxcindex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,6 +25,22 @@
#include "gsbitops.h" /* for sample_store macros */
/*
+ * Define the maximum number of components in a device color.
+ * The minimum value is 4, to handle CMYK; the maximum value is
+ * sizeof(gx_color_index) * 8, since for larger values, there aren't enough
+ * bits in a gx_color_index to have even 1 bit per component.
+ */
+#define GX_DEVICE_COLOR_MAX_COMPONENTS 6
+
+/*
+ * We might change gx_color_index to a pointer or a structure in the
+ * future. These disabled options help us assess how much disruption
+ * such a change might cause.
+ */
+/*#define TEST_CINDEX_POINTER*/
+/*#define TEST_CINDEX_STRUCT*/
+
+/*
* Internally, a (pure) device color is represented by opaque values of
* type gx_color_index, which are tied to the specific device. The driver
* maps between these values and RGB[alpha] or CMYK values. In this way,
@@ -32,10 +48,32 @@
* and have the graphics library cache the result.
*/
-/* Define the type for device color indices. */
-typedef unsigned long gx_color_index;
+#ifdef TEST_CINDEX_STRUCT
+
+/* Define the type for device color index (pixel value) data. */
+typedef struct { ulong value[2]; } gx_color_index_data;
+
+#else /* !TEST_CINDEX_STRUCT */
+
+/* Define the type for device color index (pixel value) data. */
+typedef ulong gx_color_index_data;
+
+#endif /* (!)TEST_CINDEX_STRUCT */
-#define arch_log2_sizeof_color_index arch_log2_sizeof_long
+#ifdef TEST_CINDEX_POINTER
+
+/* Define the type for device color indices (pixel values). */
+typedef gx_color_index_data * gx_color_index;
+#define arch_sizeof_color_index arch_sizeof_ptr
+
+extern const gx_color_index_data gx_no_color_index_data;
+#define gx_no_color_index_values (&gx_no_color_index_data)
+#define gx_no_color_index (&gx_no_color_index_data)
+
+#else /* !TEST_CINDEX_POINTER */
+
+/* Define the type for device color indices (pixel values). */
+typedef gx_color_index_data gx_color_index;
#define arch_sizeof_color_index arch_sizeof_long
/* Define the 'transparent' color index. */
@@ -47,39 +85,47 @@ typedef unsigned long gx_color_index;
/* Instead, we must spell out the typedef: */
#define gx_no_color_index ((unsigned long)gx_no_color_index_value)
+#endif /* (!)TEST_CINDEX_POINTER */
+
/*
* Define macros for accumulating a scan line of a colored image.
* The usage is as follows:
- * declare_line_accum(line, bpp, xo);
- * for ( x = xo; x < xe; ++x )
- * { << compute color at x >>
- * line_accum(color, bpp);
- * }
- * line_accum_copy(dev, line, bpp, xo, xe, raster, y);
- * This code must be enclosed in { }, since declare_line_accum declares
+ * DECLARE_LINE_ACCUM(line, bpp, xo);
+ * for ( x = xo; x < xe; ++x ) {
+ * << compute color at x >>
+ * LINE_ACCUM(color, bpp);
+ * }
+ * This code must be enclosed in { }, since DECLARE_LINE_ACCUM declares
* variables. Supported values of bpp are 1, 2, 4, 8, 12, 16, 24, 32.
*
- * Note that declare_line_accum declares the variables l_dptr, l_dbyte, l_dbit,
- * and l_xprev. Other code in the loop may use these variables.
+ * Note that DECLARE_LINE_ACCUM declares the variables l_dptr, l_dbyte, and
+ * l_dbit. Other code in the loop may use these variables.
*/
-#define declare_line_accum(line, bpp, xo)\
- sample_store_declare_setup(l_dptr, l_dbit, l_dbyte, line, 0, bpp);\
- int l_xprev = (xo)
-#define line_accum(color, bpp)\
+#define DECLARE_LINE_ACCUM(line, bpp, xo)\
+ sample_store_declare_setup(l_dptr, l_dbit, l_dbyte, line, 0, bpp)
+#define LINE_ACCUM(color, bpp)\
sample_store_next32(color, l_dptr, l_dbit, bpp, l_dbyte)
-#define line_accum_skip(bpp)\
+#define LINE_ACCUM_SKIP(bpp)\
sample_store_skip_next(l_dptr, l_dbit, bpp, l_dbyte)
-#define line_accum_store(bpp)\
+#define LINE_ACCUM_STORE(bpp)\
sample_store_flush(l_dptr, l_dbit, bpp, l_dbyte)
-#define line_accum_copy(dev, line, bpp, xo, xe, raster, y)\
- if ( (xe) > l_xprev )\
- { int code;\
- line_accum_store(bpp);\
+/*
+ * Declare additional macros for accumulating a scan line with copying
+ * to a device. Note that DECLARE_LINE_ACCUM_COPY also declares l_xprev.
+ * LINE_ACCUM_COPY is called after the accumulation loop.
+ */
+#define DECLARE_LINE_ACCUM_COPY(line, bpp, xo)\
+ DECLARE_LINE_ACCUM(line, bpp, xo);\
+ int l_xprev = (xo)
+#define LINE_ACCUM_COPY(dev, line, bpp, xo, xe, raster, y)\
+ if ( (xe) > l_xprev ) {\
+ int code;\
+ LINE_ACCUM_STORE(bpp);\
code = (*dev_proc(dev, copy_color))\
(dev, line, l_xprev - (xo), raster,\
gx_no_bitmap_id, l_xprev, y, (xe) - l_xprev, 1);\
if ( code < 0 )\
return code;\
- }
+ }
#endif /* gxcindex_INCLUDED */
diff --git a/gs/src/gxclbits.c b/gs/src/gxclbits.c
index f370a1a54..2a8bfd547 100644
--- a/gs/src/gxclbits.c
+++ b/gs/src/gxclbits.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -313,18 +313,25 @@ cmd_put_color_map(gx_device_clist_writer * cldev, cmd_map_index map_index,
code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc, 2);
if (code < 0)
return code;
- dp[1] = cmd_set_misc_map + map_index;
+ dp[1] = cmd_set_misc_map + (cmd_map_none << 4) + map_index;
if (pid)
*pid = gs_no_id;
} else {
if (pid && map->id == *pid)
return 0; /* no need to write */
- code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc,
- 2 + sizeof(map->values));
- if (code < 0)
- return code;
- dp[1] = cmd_set_misc_map + 0x20 + map_index;
- memcpy(dp + 2, map->values, sizeof(map->values));
+ if (map->proc == gs_identity_transfer) {
+ code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc, 2);
+ if (code < 0)
+ return code;
+ dp[1] = cmd_set_misc_map + (cmd_map_identity << 4) + map_index;
+ } else {
+ code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc,
+ 2 + sizeof(map->values));
+ if (code < 0)
+ return code;
+ dp[1] = cmd_set_misc_map + (cmd_map_other << 4) + map_index;
+ memcpy(dp + 2, map->values, sizeof(map->values));
+ }
if (pid)
*pid = map->id;
}
diff --git a/gs/src/gxcldev.h b/gs/src/gxcldev.h
index a6edfd399..630e454ad 100644
--- a/gs/src/gxcldev.h
+++ b/gs/src/gxcldev.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -101,15 +101,16 @@ typedef enum {
cmd_opv_set_misc = 0x06,
#define cmd_set_misc_lop (0 << 6) /* 00: lop_lsb(6), lop_msb# */
#define cmd_set_misc_data_x (1 << 6) /* 01: more(1)dx_lsb(5)[, dx_msb#] */
-#define cmd_set_misc_map (2 << 6) /* 10: non-0(1)map_index(5) */
- /* [, n x frac] */
+#define cmd_set_misc_map (2 << 6) /* 10: contents(2)map_index(4) */
+ /* [, n x frac] */
#define cmd_set_misc_halftone (3 << 6) /* 11: type(6), num_comp# */
cmd_opv_enable_lop = 0x07, /* (nothing) */
cmd_opv_disable_lop = 0x08, /* (nothing) */
cmd_opv_set_ht_order = 0x09, /* component+1#[, cname#], */
/* width#, height#, raster#, */
- /* shift#, num_levels#, num_bits# */
- cmd_opv_set_ht_data = 0x0a, /* n, n x (uint|gx_ht_bit) */
+ /* shift#, num_levels#, num_bits#, */
+ /* order_procs_index */
+ cmd_opv_set_ht_data = 0x0a, /* n, n x (uint|gx_ht_bit|ushort) */
cmd_opv_end_page = 0x0b, /* (nothing) */
cmd_opv_delta2_color0 = 0x0c, /* dr5dg6db5 or dc4dm4dy4dk4 */
#define cmd_delta2_24_bias 0x00102010
@@ -271,9 +272,9 @@ struct gx_clist_state_s {
#define initial_known 0x3fff /* exclude tile & image params */
/* Following are only used when writing */
cmd_list list; /* list of commands for band */
- /* Following is set when writing, read when reading */
+ /* Following are set when writing, read when reading */
ulong cost; /* cost of rendering the band */
- gx_color_index colors_used; /* 'or' of all colors written */
+ gx_colors_used_t colors_used;
};
/* The initial values for a band state */
@@ -283,7 +284,7 @@ struct gx_clist_state_s {
0, gx_no_bitmap_id,\
{ 0, 0 }, { gx_no_color_index, gx_no_color_index },\
{ 0, 0, 0, 0 }, lop_default, 0, 0, 0, initial_known,\
- { 0, 0 }, 0, 0
+ { 0, 0 }, 0, { 0 }
/* Define the size of the command buffer used for reading. */
/* This is needed to split up operations with a large amount of data, */
@@ -553,6 +554,11 @@ int cmd_update_lop(P3(gx_device_clist_writer *, gx_clist_state *,
* permanent_error, which prevents writing to the command list.
*/
+/*
+ * The "if (1)" statements in the following macros are there to prevent
+ * stupid compilers from giving "statement not reached" warnings.
+ */
+
#define FOR_RECTS_NO_ERROR\
BEGIN\
int yend = y + height;\
@@ -589,14 +595,14 @@ retry_rect:\
#define ERROR_RECT(code_value)\
BEGIN\
band_code = (code_value);\
- goto error_in_rect;\
+ if (1) goto error_in_rect;\
END
#define TRY_RECT\
BEGIN\
do
#define HANDLE_RECT_UNLESS(codevar, unless_clause)\
while (codevar < 0 &&\
- ((codevar = clist_VMerror_recover(cdev, (codevar))) >= 0)\
+ (codevar = clist_VMerror_recover(cdev, codevar)) >= 0\
);\
if (codevar < 0 && !(unless_clause))\
ERROR_RECT(codevar);\
@@ -616,7 +622,7 @@ error_in_rect:\
)\
goto retry_rect;\
}\
- return band_code;\
+ if (1) return band_code;\
} while ((y += height) < yend);\
END
#define END_RECTS END_RECTS_ON_ERROR(DO_NOTHING, 1, 1)
@@ -675,6 +681,11 @@ typedef enum {
cmd_map_black_generation,
cmd_map_undercolor_removal
} cmd_map_index;
+typedef enum {
+ cmd_map_none = 0, /* no map, use default */
+ cmd_map_identity, /* identity map */
+ cmd_map_other /* other map */
+} cmd_map_contents;
int cmd_put_color_map(P4(gx_device_clist_writer * cldev,
cmd_map_index map_index,
const gx_transfer_map * map, gs_id * pid));
diff --git a/gs/src/gxclimag.c b/gs/src/gxclimag.c
index da84dc2d0..59007ff63 100644
--- a/gs/src/gxclimag.c
+++ b/gs/src/gxclimag.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,8 @@
#include "gxiparam.h"
#include "gxpath.h"
#include "stream.h"
-#include "strimpl.h" /* for siscale.h */
-#include "siscale.h"
+#include "strimpl.h" /* for sisparam.h */
+#include "sisparam.h"
extern_gx_image_type_table();
@@ -44,6 +44,8 @@ extern_gx_image_type_table();
static bool USE_HL_IMAGES = true;
/* Forward references */
+private int cmd_put_set_data_x(P3(gx_device_clist_writer * cldev,
+ gx_clist_state * pcls, int data_x));
private int cmd_put_color_mapping(P3(gx_device_clist_writer * cldev,
const gs_imager_state * pis,
bool write_rgb_to_cmyk));
@@ -68,20 +70,23 @@ clist_fill_mask(gx_device * dev,
int orig_x = x; /* ditto */
int orig_width = width; /* ditto */
int orig_height = height; /* ditto */
- int log2_depth = depth >> 1; /* works for 1,2,4 */
+ int log2_depth = ilog2(depth);
int y0;
int data_x_bit;
byte copy_op =
(depth > 1 ? cmd_op_copy_color_alpha :
gx_dc_is_pure(pdcolor) ? cmd_op_copy_mono :
cmd_op_copy_mono + cmd_copy_ht_color);
-
+ bool slow_rop =
+ cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor) ||
+ cmd_slow_rop(dev, lop_know_S_1(lop), pdcolor);
fit_copy(dev, data, data_x, raster, id, x, y, width, height);
y0 = y; /* must do after fit_copy */
/* If non-trivial clipping & complex clipping disabled, default */
- if ((cdev->disable_mask & clist_disable_complex_clip) &&
- !check_rect_for_trivial_clip(pcpath, x, y, x + width, y + height)
+ if (((cdev->disable_mask & clist_disable_complex_clip) &&
+ !check_rect_for_trivial_clip(pcpath, x, y, x + width, y + height)) ||
+ gs_debug_c('`')
)
return gx_default_fill_mask(dev, data, data_x, raster, id,
x, y, width, height, pdcolor, depth,
@@ -114,6 +119,7 @@ clist_fill_mask(gx_device * dev,
TRY_RECT {
code = cmd_put_drawing_color(cdev, pcls, pdcolor);
} HANDLE_RECT(code);
+ pcls->colors_used.slow_rop |= slow_rop;
/*
* Unfortunately, painting a character with a halftone requires the
* use of two bitmaps, a situation that we can neither represent in
@@ -150,7 +156,6 @@ clist_fill_mask(gx_device * dev,
gx_cmd_rect rect;
int rsize;
byte op = copy_op + cmd_copy_use_tile;
- byte *dp;
/* Output a command to copy the entire character. */
/* It will be truncated properly per band. */
@@ -158,26 +163,26 @@ clist_fill_mask(gx_device * dev,
rect.width = orig_width, rect.height = yend - y0;
rsize = 1 + cmd_sizexy(rect);
TRY_RECT {
- code = 0;
- if (orig_data_x) {
- int dx_msb = orig_data_x >> 5;
+ code = (orig_data_x ?
+ cmd_put_set_data_x(cdev, pcls, orig_data_x) : 0);
+ if (code >= 0) {
+ byte *dp;
- code = set_cmd_put_op(dp, cdev, pcls, cmd_opv_set_misc,
- 2 + cmd_size_w(dx_msb));
+ code = set_cmd_put_op(dp, cdev, pcls, op, rsize);
+ /*
+ * The following conditional is unnecessary: the two
+ * statements inside it should go outside the
+ * HANDLE_RECT. They are here solely to pacify
+ * stupid compilers that don't understand that dp
+ * will always be set if control gets past the
+ * HANDLE_RECT.
+ */
if (code >= 0) {
- if (dx_msb) {
- dp[1] = cmd_set_misc_data_x + 0x20 +
- (orig_data_x & 0x1f);
- cmd_put_w(dx_msb, dp + 2);
- } else
- dp[1] = cmd_set_misc_data_x + orig_data_x;
+ dp++;
+ cmd_putxy(rect, dp);
}
}
- if (code >= 0)
- code = set_cmd_put_op(dp, cdev, pcls, op, rsize);
} HANDLE_RECT(code);
- dp++;
- cmd_putxy(rect, dp);
pcls->rect = rect;
goto end;
}
@@ -215,25 +220,30 @@ typedef struct clist_image_enum_s {
const gs_imager_state *pis;
const gx_clip_path *pcpath;
/* Set at creation time */
- gx_image_enum_common_t *default_info;
gs_image_format_t format;
gs_int_point support; /* extra source pixels for interpolation */
int bits_per_plane; /* bits per pixel per plane */
gs_matrix matrix; /* image space -> device space */
bool uses_color;
byte color_space;
+ gs_id color_space_id;
int ymin, ymax;
bool map_rgb_to_cmyk;
- gx_color_index colors_used;
+ gx_colors_used_t colors_used;
/* begin_image command prepared & ready to output */
/****** SIZE COMPUTATION IS WRONG, TIED TO gximage.c, gsmatrix.c ******/
- byte begin_image_command[3 + 2 * cmd_sizew_max + 1 + 6 * sizeof(float) +
- /****** Decode, ASSUME 5 COMPONENTS MAX ******/
- 1 + 8 * sizeof(float) + 1 + 2 * sizeof(float) +
- /****** MaskColor, DITTO ******/
- 10 * cmd_sizew_max +
+ byte begin_image_command[3 +
+ /* Width, Height */
+ 2 * cmd_sizew_max +
+ /* ImageMatrix */
+ 1 + 6 * sizeof(float) +
+ /* Decode */
+ (GS_IMAGE_MAX_COMPONENTS + 3) / 4 +
+ GS_IMAGE_MAX_COMPONENTS * 2 * sizeof(float) +
+ /* MaskColors */
+ GS_IMAGE_MAX_COMPONENTS * cmd_sizew_max +
/* rect */
- 4 * cmd_sizew_max];
+ 4 * cmd_sizew_max];
int begin_image_command_length;
/* Updated dynamically */
int y;
@@ -242,8 +252,7 @@ typedef struct clist_image_enum_s {
/* We can disregard the pointers in the writer by allocating */
/* the image enumerator as immovable. This is a hack, of course. */
-gs_private_st_ptrs1(st_clist_image_enum, clist_image_enum, "clist_image_enum",
- clist_image_enum_enum_ptrs, clist_image_enum_reloc_ptrs, default_info);
+gs_private_st_simple(st_clist_image_enum, clist_image_enum, "clist_image_enum");
private image_enum_proc_plane_data(clist_image_plane_data);
private image_enum_proc_end_image(clist_image_end_image);
@@ -302,7 +311,7 @@ clist_begin_typed_image(gx_device * dev,
const gs_pixel_image_t * const pim = (const gs_pixel_image_t *)pic;
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
- clist_image_enum *pie;
+ clist_image_enum *pie = 0;
int base_index;
bool indexed;
bool masked = false;
@@ -313,13 +322,12 @@ clist_begin_typed_image(gx_device * dev,
bool varying_depths = false;
gs_matrix mat;
gs_rect sbox, dbox;
- bool use_default_image;
gs_image_format_t format;
gx_color_index colors_used = 0;
int code;
/* We can only handle a limited set of image types. */
- switch (pic->type->index) {
+ switch ((gs_debug_c('`') ? -1 : pic->type->index)) {
case 1:
masked = ((const gs_image1_t *)pim)->ImageMask;
has_alpha = ((const gs_image1_t *)pim)->Alpha != 0;
@@ -327,8 +335,7 @@ clist_begin_typed_image(gx_device * dev,
if (pmat == 0)
break;
default:
- return gx_default_begin_typed_image(dev, pis, pmat, pic, prect,
- pdcolor, pcpath, mem, pinfo);
+ goto use_default;
}
format = pim->format;
/* See above for why we allocate the enumerator as immovable. */
@@ -365,9 +372,8 @@ clist_begin_typed_image(gx_device * dev,
uses_color = pim->CombineWithColor && rop3_uses_T(pis->log_op);
}
code = gx_image_enum_common_init((gx_image_enum_common_t *) pie,
- (const gs_image_common_t *) pim,
+ (const gs_data_image_t *) pim,
&clist_image_enum_procs, dev,
- pim->BitsPerComponent,
num_components, format);
{
int i;
@@ -375,32 +381,29 @@ clist_begin_typed_image(gx_device * dev,
for (i = 1; i < pie->num_planes; ++i)
varying_depths |= pie->plane_depths[i] != pie->plane_depths[0];
}
- use_default_image =
- (code < 0 ||
- !USE_HL_IMAGES || /* Always use the default. */
- (cdev->disable_mask & clist_disable_hl_image) ||
- cdev->image_enum_id != gs_no_id || /* Can't handle nested images */
- /****** CAN'T HANDLE CIE COLOR YET ******/
- base_index > gs_color_space_index_DeviceCMYK ||
- /****** CAN'T HANDLE INDEXED COLOR (READING MAP) ******/
- indexed ||
- /****** CAN'T HANDLE NON-PURE COLORS YET ******/
- (uses_color && !gx_dc_is_pure(pdcolor)) ||
- /****** CAN'T HANDLE IMAGES WITH ALPHA YET ******/
- has_alpha ||
- /****** CAN'T HANDLE IMAGES WITH IRREGULAR DEPTHS ******/
- varying_depths ||
- (code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
- (code = gs_matrix_multiply(&mat, &ctm_only(pis), &mat)) < 0 ||
- !(cdev->disable_mask & clist_disable_nonrect_hl_image ?
- (is_xxyy(&mat) || is_xyyx(&mat)) :
- image_matrix_ok_to_band(&mat))
- );
- if (!use_default_image) {
+ if (code < 0 ||
+ !USE_HL_IMAGES || /* Always use the default. */
+ (cdev->disable_mask & clist_disable_hl_image) ||
+ cdev->image_enum_id != gs_no_id || /* Can't handle nested images */
+ /****** CAN'T HANDLE CIE COLOR YET ******/
+ base_index > gs_color_space_index_DeviceCMYK ||
+ /****** CAN'T HANDLE NON-PURE COLORS YET ******/
+ (uses_color && !gx_dc_is_pure(pdcolor)) ||
+ /****** CAN'T HANDLE IMAGES WITH ALPHA YET ******/
+ has_alpha ||
+ /****** CAN'T HANDLE IMAGES WITH IRREGULAR DEPTHS ******/
+ varying_depths ||
+ (code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
+ (code = gs_matrix_multiply(&mat, &ctm_only(pis), &mat)) < 0 ||
+ !(cdev->disable_mask & clist_disable_nonrect_hl_image ?
+ (is_xxyy(&mat) || is_xyyx(&mat)) :
+ image_matrix_ok_to_band(&mat))
+ )
+ goto use_default;
+ {
int bytes_per_plane, bytes_per_row;
bits_per_pixel = pim->BitsPerComponent * num_components;
- pie->default_info = 0;
pie->image = *pim;
pie->dcolor = *pdcolor;
if (prect)
@@ -417,6 +420,7 @@ clist_begin_typed_image(gx_device * dev,
pie->uses_color = uses_color;
pie->color_space = (base_index << 4) |
(indexed ? (pim->ColorSpace->params.indexed.use_proc ? 12 : 8) : 0);
+ pie->color_space_id = (masked ? gs_no_id : pim->ColorSpace->id);
pie->y = pie->rect.p.y;
/* Image row has to fit in cmd writer's buffer */
@@ -424,40 +428,29 @@ clist_begin_typed_image(gx_device * dev,
(pim->Width * pie->bits_per_plane + 7) >> 3;
bytes_per_row = bytes_per_plane * pie->num_planes;
bytes_per_row = max(bytes_per_row, 1);
- use_default_image = cmd_largest_size + bytes_per_row >
- cdev->cend - cdev->cbuf;
+ if (cmd_largest_size + bytes_per_row > cdev->cend - cdev->cbuf)
+ goto use_default;
}
- if (!use_default_image) {
- if (pim->Interpolate)
- pie->support.x = pie->support.y = max_support + 1;
- else
- pie->support.x = pie->support.y = 0;
- sbox.p.x = pie->rect.p.x - pie->support.x;
- sbox.p.y = pie->rect.p.y - pie->support.y;
- sbox.q.x = pie->rect.q.x + pie->support.x;
- sbox.q.y = pie->rect.q.y + pie->support.y;
- gs_bbox_transform(&sbox, &mat, &dbox);
-
- if (cdev->disable_mask & clist_disable_complex_clip)
- use_default_image =
- !check_rect_for_trivial_clip( pcpath,
+ if (pim->Interpolate)
+ pie->support.x = pie->support.y = MAX_ISCALE_SUPPORT + 1;
+ else
+ pie->support.x = pie->support.y = 0;
+ sbox.p.x = pie->rect.p.x - pie->support.x;
+ sbox.p.y = pie->rect.p.y - pie->support.y;
+ sbox.q.x = pie->rect.q.x + pie->support.x;
+ sbox.q.y = pie->rect.q.y + pie->support.y;
+ gs_bbox_transform(&sbox, &mat, &dbox);
+
+ if (cdev->disable_mask & clist_disable_complex_clip)
+ if (!check_rect_for_trivial_clip(pcpath,
(int)floor(dbox.p.x), (int)floor(dbox.p.y),
- (int)ceil(dbox.q.x), (int)ceil(dbox.q.y) );
- }
+ (int)ceil(dbox.q.x), (int)ceil(dbox.q.y)))
+ goto use_default;
/* Create the begin_image command. */
if ((pie->begin_image_command_length =
begin_image_command(pie->begin_image_command,
sizeof(pie->begin_image_command), pic)) < 0)
- use_default_image = true;
- if (use_default_image) {
- int code = gx_default_begin_typed_image(dev, pis, pmat, pic, prect,
- pdcolor, pcpath, mem,
- &pie->default_info);
-
- if (code < 0)
- gs_free_object(mem, pie, "clist_begin_typed_image");
- return code;
- }
+ goto use_default;
if (!masked) {
/*
* Calculate (conservatively) the set of colors that this image
@@ -502,7 +495,9 @@ clist_begin_typed_image(gx_device * dev,
pie->map_rgb_to_cmyk = dev->color_info.num_components == 4 &&
base_index == gs_color_space_index_DeviceRGB;
- pie->colors_used = colors_used;
+ pie->colors_used.or = colors_used;
+ pie->colors_used.slow_rop =
+ cmd_slow_rop(dev, pis->log_op, (uses_color ? pdcolor : NULL));
pie->color_map_is_known = false;
/*
* Calculate a (slightly conservative) Y bounding interval for the image
@@ -525,27 +520,38 @@ clist_begin_typed_image(gx_device * dev,
cdev->image_enum_id = pie->id;
return 0;
+
+ /*
+ * We couldn't handle the image. Use the default algorithms, which
+ * break the image up into rectangles or small pixmaps.
+ */
+use_default:
+ gs_free_object(mem, pie, "clist_begin_typed_image");
+ return gx_default_begin_typed_image(dev, pis, pmat, pic, prect,
+ pdcolor, pcpath, mem, pinfo);
}
/* Process the next piece of an image. */
private int
-clist_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
- const gx_image_plane_t * planes, int yh)
+clist_image_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int yh,
+ int *rows_used)
{
+ gx_device *dev = info->dev;
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
clist_image_enum *pie = (clist_image_enum *) info;
gs_rect sbox, dbox;
+ int y_orig = pie->y;
int y0, y1;
int y, height; /* for BEGIN/END_RECT */
int code;
- if (pie->default_info)
- return gx_image_plane_data(pie->default_info, planes, yh);
#ifdef DEBUG
if (pie->id != cdev->image_enum_id) {
lprintf2("end_image id = %lu != clist image id = %lu!\n",
(ulong) pie->id, (ulong) cdev->image_enum_id);
+ *rows_used = 0;
return_error(gs_error_Fatal);
}
#endif
@@ -554,11 +560,13 @@ clist_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
int i;
for (i = 1; i < info->num_planes; ++i)
- if (planes[i].data_x != planes[0].data_x)
+ if (planes[i].data_x != planes[0].data_x) {
+ *rows_used = 0;
return_error(gs_error_rangecheck);
+ }
}
sbox.p.x = pie->rect.p.x - pie->support.x;
- sbox.p.y = (y0 = pie->y) - pie->support.y;
+ sbox.p.y = (y0 = y_orig) - pie->support.y;
sbox.q.x = pie->rect.q.x + pie->support.x;
sbox.q.y = (y1 = pie->y += yh) + pie->support.y;
gs_bbox_transform(&sbox, &pie->matrix, &dbox);
@@ -584,9 +592,15 @@ clist_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
ry0 = pie->ymin;
if (ry1 > pie->ymax)
ry1 = pie->ymax;
+ /*
+ * If the image extends off the page in the Y direction,
+ * we may have ry0 > ry1. Check for this here.
+ */
+ if (ry0 >= ry1)
+ goto done;
/* Expand the range out to band boundaries. */
y = ry0 / band_height * band_height;
- height = min(round_up(ry1, band_height), dev->height) - y;
+ height = min(ROUND_UP(ry1, band_height), dev->height) - y;
}
FOR_RECTS {
@@ -605,7 +619,8 @@ clist_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
if (!image_band_box(dev, pie, y, height, &ibox))
continue;
- pcls->colors_used |= pie->colors_used;
+ pcls->colors_used.or |= pie->colors_used.or;
+ pcls->colors_used.slow_rop |= pie->colors_used.slow_rop;
/*
* The transmitted subrectangle has to be computed at the time
* we write the begin_image command; this in turn controls how
@@ -709,64 +724,62 @@ clist_image_plane_data(gx_device * dev, gx_image_enum_common_t * info,
#undef by0
#undef bx1
#undef by1
- } END_RECTS_ON_ERROR(\
- BEGIN\
- ++cdev->ignore_lo_mem_warnings;\
- NEST_RECT {\
- code = write_image_end_all(dev, pie);\
- } UNNEST_RECT;\
- --cdev->ignore_lo_mem_warnings;\
- END,\
- (code < 0 ? (band_code = code) : code) >= 0,\
- (cmd_clear_known(cdev,\
- clist_image_unknowns(dev, pie) | begin_image_known),\
- pie->color_map_is_known = false,\
- cdev->image_enum_id = pie->id, true)\
+ } END_RECTS_ON_ERROR(
+ BEGIN
+ ++cdev->ignore_lo_mem_warnings;
+ NEST_RECT {
+ code = write_image_end_all(dev, pie);
+ } UNNEST_RECT;
+ --cdev->ignore_lo_mem_warnings;
+ /* Update sub-rect */
+ if (!pie->image.Interpolate)
+ pie->rect.p.y += yh; /* interpolate & mem recovery currently incompat */
+ END,
+ (code < 0 ? (band_code = code) : code) >= 0,
+ (cmd_clear_known(cdev,
+ clist_image_unknowns(dev, pie) | begin_image_known),
+ pie->color_map_is_known = false,
+ cdev->image_enum_id = pie->id, true)
);
- /* Update sub-rect in case memory exhaustion forced end_image */
- if (!pie->image.Interpolate)
- pie->rect.p.y += yh; /* interpolate & mem recovery currently incompat */
+ done:
+ *rows_used = pie->y - y_orig;
return pie->y >= pie->rect.q.y;
}
/* Clean up by releasing the buffers. */
private int
-clist_image_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
+clist_image_end_image(gx_image_enum_common_t * info, bool draw_last)
{
+ gx_device *dev = info->dev;
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
clist_image_enum *pie = (clist_image_enum *) info;
int code;
- if (pie->default_info)
- code = gx_default_end_image(dev, pie->default_info, draw_last);
- else {
#ifdef DEBUG
- if (pie->id != cdev->image_enum_id) {
- lprintf2("end_image id = %lu != clist image id = %lu!\n",
- (ulong) pie->id, (ulong) cdev->image_enum_id);
- return_error(gs_error_Fatal);
- }
-#endif
- NEST_RECT {
- do {
- code = write_image_end_all(dev, pie);
- } while (code < 0 && cdev->error_is_retryable &&
- (code = clist_VMerror_recover(cdev, code)) >= 0
- );
- /* if couldn't write successsfully, do a hard flush */
- if (code < 0 && cdev->error_is_retryable) {
- int retry_code;
- ++cdev->ignore_lo_mem_warnings;
- retry_code = write_image_end_all(dev, pie); /* force it out */
- --cdev->ignore_lo_mem_warnings;
- if (retry_code >= 0 && cdev->driver_call_nesting == 0)
- code = clist_VMerror_recover_flush(cdev, code);
- }
- } UNNEST_RECT;
- cdev->image_enum_id = gs_no_id;
+ if (pie->id != cdev->image_enum_id) {
+ lprintf2("end_image id = %lu != clist image id = %lu!\n",
+ (ulong) pie->id, (ulong) cdev->image_enum_id);
+ return_error(gs_error_Fatal);
}
+#endif
+ NEST_RECT {
+ do {
+ code = write_image_end_all(dev, pie);
+ } while (code < 0 && cdev->error_is_retryable &&
+ (code = clist_VMerror_recover(cdev, code)) >= 0
+ );
+ /* if couldn't write successsfully, do a hard flush */
+ if (code < 0 && cdev->error_is_retryable) {
+ int retry_code;
+ ++cdev->ignore_lo_mem_warnings;
+ retry_code = write_image_end_all(dev, pie); /* force it out */
+ --cdev->ignore_lo_mem_warnings;
+ if (retry_code >= 0 && cdev->driver_call_nesting == 0)
+ code = clist_VMerror_recover_flush(cdev, code);
+ }
+ } UNNEST_RECT;
+ cdev->image_enum_id = gs_no_id;
gs_free_object(pie->memory, pie, "clist_image_end_image");
return code;
}
@@ -783,6 +796,26 @@ clist_create_compositor(gx_device * dev,
/* ------ Utilities ------ */
+/* Add a command to set data_x. */
+private int
+cmd_put_set_data_x(gx_device_clist_writer * cldev, gx_clist_state * pcls,
+ int data_x)
+{
+ int dx_msb = data_x >> 5;
+ byte *dp;
+ int code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc,
+ 2 + cmd_size_w(dx_msb));
+
+ if (code >= 0) {
+ if (dx_msb) {
+ dp[1] = cmd_set_misc_data_x + 0x20 + (data_x & 0x1f);
+ cmd_put_w(dx_msb, dp + 2);
+ } else
+ dp[1] = cmd_set_misc_data_x + data_x;
+ }
+ return code;
+}
+
/* Add commands to represent a halftone order. */
private int
cmd_put_ht_order(gx_device_clist_writer * cldev, const gx_ht_order * porder,
@@ -795,7 +828,13 @@ cmd_put_ht_order(gx_device_clist_writer * cldev, const gx_ht_order * porder,
byte *dp;
uint i, n;
int code;
+ int pi = porder->procs - ht_order_procs_table;
+ uint elt_size = porder->procs->bit_data_elt_size;
+ const uint nlevels = min((cbuf_size - 2) / sizeof(*porder->levels), 255);
+ const uint nbits = min((cbuf_size - 2) / elt_size, 255);
+ if (pi < 0 || pi > countof(ht_order_procs_table))
+ return_error(gs_error_unregistered);
/* Put out the order parameters. */
cp = cmd_put_w(component + 1, command);
if (component >= 0)
@@ -806,6 +845,7 @@ cmd_put_ht_order(gx_device_clist_writer * cldev, const gx_ht_order * porder,
cp = cmd_put_w(porder->shift, cp);
cp = cmd_put_w(porder->num_levels, cp);
cp = cmd_put_w(porder->num_bits, cp);
+ *cp++ = (byte)pi;
len = cp - command;
code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_ht_order, len + 1);
if (code < 0)
@@ -819,7 +859,6 @@ cmd_put_ht_order(gx_device_clist_writer * cldev, const gx_ht_order * porder,
return code;
/* Put out the levels array. */
-#define nlevels min((cbuf_size - 2) / sizeof(*porder->levels), 255)
for (i = 0; i < porder->num_levels; i += n) {
n = porder->num_levels - i;
if (n > nlevels)
@@ -831,22 +870,20 @@ cmd_put_ht_order(gx_device_clist_writer * cldev, const gx_ht_order * porder,
dp[1] = n;
memcpy(dp + 2, porder->levels + i, n * sizeof(*porder->levels));
}
-#undef nlevels
/* Put out the bits array. */
-#define nbits min((cbuf_size - 2) / sizeof(*porder->bits), 255)
for (i = 0; i < porder->num_bits; i += n) {
n = porder->num_bits - i;
if (n > nbits)
n = nbits;
code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_ht_data,
- 2 + n * sizeof(*porder->bits));
+ 2 + n * elt_size);
if (code < 0)
return code;
dp[1] = n;
- memcpy(dp + 2, porder->bits + i, n * sizeof(*porder->bits));
+ memcpy(dp + 2, (const byte *)porder->bit_data + i * elt_size,
+ n * elt_size);
}
-#undef nbits
return 0;
}
@@ -1158,16 +1195,14 @@ clist_image_unknowns(gx_device *dev, const clist_image_enum *pie)
unknown |= ctm_known;
cdev->imager_state.ctm = pis->ctm;
}
- /****** hival CHECK IS NOT SUFFICIENT ******/
- if (cdev->color_space != pie->color_space ||
- ((cdev->color_space & 8) != 0 &&
- cdev->indexed_params.hival !=
- pie->image.ColorSpace->params.indexed.hival)
- ) {
- unknown |= color_space_known;
- cdev->color_space = pie->color_space;
- if (cdev->color_space & 8)
- cdev->indexed_params = pie->image.ColorSpace->params.indexed;
+ if (pie->color_space_id != gs_no_id /* i.e., not masked */) {
+ if (cdev->color_space_id != pie->color_space_id) {
+ unknown |= color_space_known;
+ cdev->color_space = pie->color_space;
+ cdev->color_space_id = pie->color_space_id;
+ if (cdev->color_space & 8)
+ cdev->indexed_params = pie->image.ColorSpace->params.indexed;
+ }
}
if (cmd_check_clip_path(cdev, pie->pcpath))
unknown |= clip_path_known;
@@ -1210,10 +1245,9 @@ cmd_image_plane_data(gx_device_clist_writer * cldev, gx_clist_state * pcls,
int code;
if (data_x) {
- code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc, 2);
+ code = cmd_put_set_data_x(cldev, pcls, data_x);
if (code < 0)
return code;
- dp[1] = cmd_set_misc_data_x + (data_x & 7);
offset = ((data_x & ~7) * cldev->color_info.depth) >> 3;
}
code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_image_data, len);
@@ -1242,6 +1276,12 @@ write_image_end_all(gx_device *dev, const clist_image_enum *pie)
int y = pie->ymin;
int height = pie->ymax - y;
+ /*
+ * We need to check specially for images lying entirely outside the
+ * page, since FOR_RECTS doesn't do this.
+ */
+ if (height <= 0)
+ return 0;
FOR_RECTS {
byte *dp;
diff --git a/gs/src/gxclip.c b/gs/src/gxclip.c
index c362d4edf..1831c3a68 100644
--- a/gs/src/gxclip.c
+++ b/gs/src/gxclip.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,8 +21,8 @@
#include "gx.h"
#include "gxdevice.h"
#include "gxclip.h"
-#include "gzpath.h"
-#include "gzcpath.h"
+#include "gxpath.h"
+#include "gxcpath.h"
/* Define whether to look for vertical clipping regions. */
#define CHECK_VERTICAL_CLIPPING
@@ -98,7 +98,7 @@ void
gx_make_clip_translate_device(gx_device_clip * dev, void *container,
const gx_clip_list * list, int tx, int ty)
{
- gx_device_init((gx_device *) dev, (gx_device *) & gs_clip_device,
+ gx_device_init((gx_device *)dev, (const gx_device *)&gs_clip_device,
NULL, true);
dev->list = *list;
dev->translation.x = tx;
@@ -114,7 +114,7 @@ gx_make_clip_path_device(gx_device_clip * dev, const gx_clip_path * pcpath)
#ifdef DEBUG
struct stats_clip_s {
long
- loops, in, down, up, x, no_x;
+ loops, out, in_y, in, in1, down, up, x, no_x;
} stats_clip;
private uint clip_interval = 10000;
@@ -130,34 +130,28 @@ private uint clip_interval = 10000;
* the clipping region.
*/
private int
-clip_enumerate(gx_device_clip * rdev,
- int (*process) (P5(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec)),
- clip_callback_data_t * pccd)
+clip_enumerate_rest(gx_device_clip * rdev,
+ int x, int y, int xe, int ye,
+ int (*process)(P5(clip_callback_data_t * pccd,
+ int xc, int yc, int xec, int yec)),
+ clip_callback_data_t * pccd)
{
gx_clip_rect *rptr = rdev->current; /* const within algorithm */
- const int x = pccd->x, y = pccd->y;
- const int xe = x + pccd->w, ye = y + pccd->h;
- int xc, xec, yc, yec, yep;
+ int yc;
int code;
#ifdef DEBUG
- if (INCR(loops) % clip_interval == 0)
- if_debug6('q',
- "[q]loops=%ld in=%ld down=%ld up=%ld x=%ld no_x=%ld\n", \
- stats_clip.loops, stats_clip.in,
- stats_clip.down, stats_clip.up,
- stats_clip.x, stats_clip.no_x);
-#endif
- if (pccd->w <= 0 || pccd->h <= 0)
- return 0;
- /* Check for the region being entirely within the current rectangle. */
- if (!rdev->list.outside) {
- if (y >= rptr->ymin && ye <= rptr->ymax &&
- x >= rptr->xmin && xe <= rptr->xmax
- ) {
- return INCR_THEN(in, (*process) (pccd, x, y, xe, ye));
- }
+ if (INCR(loops) % clip_interval == 0 && gs_debug_c('q')) {
+ dprintf5("[q]loops=%ld out=%ld in_y=%ld in=%ld in1=%ld\n",
+ stats_clip.loops, stats_clip.out, stats_clip.in,
+ stats_clip.in_y, stats_clip.in1);
+ dprintf4("[q] down=%ld up=%ld x=%ld no_x=%ld\n",
+ stats_clip.down, stats_clip.up, stats_clip.x,
+ stats_clip.no_x);
}
+#endif
+ pccd->x = x, pccd->y = y;
+ pccd->w = xe - x, pccd->h = ye - y;
/*
* Warp the cursor forward or backward to the first rectangle row
* that could include a given y value. Assumes rptr is set, and
@@ -178,85 +172,35 @@ clip_enumerate(gx_device_clip * rdev,
while (rptr->prev != 0 && y < rptr->prev->ymax)
INCR_THEN(down, rptr = rptr->prev);
if (rptr == 0 || (yc = rptr->ymin) >= ye) {
+ INCR(out);
if (rdev->list.count > 1)
rdev->current =
(rptr != 0 ? rptr :
y >= rdev->current->ymax ? rdev->list.tail :
rdev->list.head);
- if (rdev->list.outside) {
- return (*process) (pccd, x, y, xe, ye);
- } else
- return 0;
+ return 0;
}
rdev->current = rptr;
if (yc < y)
yc = y;
- if (rdev->list.outside) {
- for (yep = y;;) {
- const int ymax = rptr->ymax;
- xc = x;
- if (yc > yep) {
- yec = yc, yc = yep;
- xec = xe;
- code = (*process) (pccd, xc, yc, xec, yec);
- if (code < 0)
- return code;
- yc = yec;
- }
- yec = min(ymax, ye);
- do {
- xec = rptr->xmin;
- if (xec > xc) {
- if (xec > xe)
- xec = xe;
- code = (*process) (pccd, xc, yc, xec, yec);
- if (code < 0)
- return code;
- xc = rptr->xmax;
- if (xc >= xe)
- xc = max_int;
- } else {
- xec = rptr->xmax;
- if (xec > xc)
- xc = xec;
- }
- }
- while ((rptr = rptr->next) != 0 && rptr->ymax == ymax);
- if (xc < xe) {
+ do {
+ const int ymax = rptr->ymax;
+ int yec = min(ymax, ye);
+
+ if_debug2('Q', "[Q]yc=%d yec=%d\n", yc, yec);
+ do {
+ int xc = rptr->xmin;
+ int xec = rptr->xmax;
+
+ if (xc < x)
+ xc = x;
+ if (xec > xe)
xec = xe;
- code = (*process) (pccd, xc, yc, xec, yec);
- if (code < 0)
- return code;
- }
- yep = yec;
- if (rptr == 0 || (yc = rptr->ymin) >= ye)
- break;
- }
- if (yep < ye) {
- xc = x, xec = xe, yc = yep, yec = ye;
- code = (*process) (pccd, xc, yc, xec, yec);
- if (code < 0)
- return code;
- }
- } else /* !outside */
- for (;;) {
- const int ymax = rptr->ymax;
- gx_clip_rect *nptr;
-
- yec = min(ymax, ye);
- if_debug2('Q', "[Q]yc=%d yec=%d\n", yc, yec);
- do {
- xc = rptr->xmin;
- xec = rptr->xmax;
- if (xc < x)
- xc = x;
- if (xec > xe)
- xec = xe;
- if (xec > xc) {
- clip_rect_print('Q', "match", rptr);
- if_debug2('Q', "[Q]xc=%d xec=%d\n", xc, xec);
- INCR(x);
+ if (xec > xc) {
+ clip_rect_print('Q', "match", rptr);
+ if_debug2('Q', "[Q]xc=%d xec=%d\n", xc, xec);
+ INCR(x);
/*
* Conditionally look ahead to detect unclipped vertical strips. This is
* really only valuable for 90 degree rotated images or (nearly-)vertical
@@ -265,35 +209,60 @@ clip_enumerate(gx_device_clip * rdev,
* take out the code here with no adverse effects.
*/
#ifdef CHECK_VERTICAL_CLIPPING
- if (xec - xc == pccd->w) { /* full width */
- /* Look ahead for a vertical swath. */
- while ((nptr = rptr->next) != 0 &&
- nptr->ymin == yec &&
- nptr->ymax <= ye &&
- nptr->xmin <= x &&
- nptr->xmax >= xe
- )
- yec = nptr->ymax, rptr = nptr;
- } else
- nptr = rptr->next;
+ if (xec - xc == pccd->w) { /* full width */
+ /* Look ahead for a vertical swath. */
+ while ((rptr = rptr->next) != 0 &&
+ rptr->ymin == yec &&
+ rptr->ymax <= ye &&
+ rptr->xmin <= x &&
+ rptr->xmax >= xe
+ )
+ yec = rptr->ymax;
+ } else
+ rptr = rptr->next;
#else
- nptr = rptr->next;
+ rptr = rptr->next;
#endif
- code = (*process) (pccd, xc, yc, xec, yec);
- if (code < 0)
- return code;
- } else {
- INCR_THEN(no_x, nptr = rptr->next);
- }
+ code = process(pccd, xc, yc, xec, yec);
+ if (code < 0)
+ return code;
+ } else {
+ INCR_THEN(no_x, rptr = rptr->next);
}
- while ((rptr = nptr) != 0 && rptr->ymax == ymax);
- if (rptr == 0 || (yec = rptr->ymin) >= ye)
- break;
- yc = yec;
+ if (rptr == 0)
+ return 0;
}
+ while (rptr->ymax == ymax);
+ } while ((yc = rptr->ymin) < ye);
return 0;
}
+private int
+clip_enumerate(gx_device_clip * rdev, int x, int y, int w, int h,
+ int (*process)(P5(clip_callback_data_t * pccd,
+ int xc, int yc, int xec, int yec)),
+ clip_callback_data_t * pccd)
+{
+ int xe, ye;
+ const gx_clip_rect *rptr = rdev->current;
+
+ if (w <= 0 || h <= 0)
+ return 0;
+ pccd->tdev = rdev->target;
+ x += rdev->translation.x;
+ xe = x + w;
+ y += rdev->translation.y;
+ ye = y + h;
+ /* Check for the region being entirely within the current rectangle. */
+ if (y >= rptr->ymin && ye <= rptr->ymax &&
+ x >= rptr->xmin && xe <= rptr->xmax
+ ) {
+ pccd->x = x, pccd->y = y, pccd->w = w, pccd->h = h;
+ return INCR_THEN(in, process(pccd, x, y, xe, ye));
+ }
+ return clip_enumerate_rest(rdev, x, y, xe, ye, process, pccd);
+}
+
/* Open a clipping device */
private int
clip_open(gx_device * dev)
@@ -309,6 +278,7 @@ clip_open(gx_device * dev)
rdev->width = tdev->width;
rdev->height = tdev->height;
gx_device_copy_color_procs(dev, tdev);
+ rdev->clipping_box_set = false;
return 0;
}
@@ -325,13 +295,45 @@ clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
{
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
+ /* We handle the fastest cases in-line here. */
+ gx_device *tdev = rdev->target;
+ /*const*/ gx_clip_rect *rptr = rdev->current;
+ int xe, ye;
+ if (w <= 0 || h <= 0)
+ return 0;
x += rdev->translation.x;
+ xe = x + w;
y += rdev->translation.y;
- ccdata.tdev = rdev->target;
+ ye = y + h;
+ /* We open-code the most common cases here. */
+ if ((y >= rptr->ymin && ye <= rptr->ymax) ||
+ ((rptr = rptr->next) != 0 &&
+ y >= rptr->ymin && ye <= rptr->ymax)
+ ) {
+ rdev->current = rptr; /* may be redundant, but awkward to avoid */
+ INCR(in_y);
+ if (x >= rptr->xmin && xe <= rptr->xmax) {
+ INCR(in);
+ return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color);
+ }
+ else if ((rptr->prev == 0 || rptr->prev->ymax != rptr->ymax) &&
+ (rptr->next == 0 || rptr->next->ymax != rptr->ymax)
+ ) {
+ INCR(in1);
+ if (x < rptr->xmin)
+ x = rptr->xmin;
+ if (xe > rptr->xmax)
+ xe = rptr->xmax;
+ return
+ (x >= xe ? 0 :
+ dev_proc(tdev, fill_rectangle)(tdev, x, y, xe - x, h, color));
+ }
+ }
+ ccdata.tdev = tdev;
ccdata.color[0] = color;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
- return clip_enumerate(rdev, clip_call_fill_rectangle, &ccdata);
+ return clip_enumerate_rest(rdev, x, y, xe, ye,
+ clip_call_fill_rectangle, &ccdata);
}
/* Copy a monochrome rectangle */
@@ -351,14 +353,30 @@ clip_copy_mono(gx_device * dev,
{
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
+ /* We handle the fastest case in-line here. */
+ gx_device *tdev = rdev->target;
+ const gx_clip_rect *rptr = rdev->current;
+ int xe, ye;
+ if (w <= 0 || h <= 0)
+ return 0;
x += rdev->translation.x;
+ xe = x + w;
y += rdev->translation.y;
- ccdata.tdev = rdev->target;
+ ye = y + h;
+ if (y >= rptr->ymin && ye <= rptr->ymax) {
+ INCR(in_y);
+ if (x >= rptr->xmin && xe <= rptr->xmax) {
+ INCR(in);
+ return dev_proc(tdev, copy_mono)
+ (tdev, data, sourcex, raster, id, x, y, w, h, color0, color1);
+ }
+ }
+ ccdata.tdev = tdev;
ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
ccdata.color[0] = color0, ccdata.color[1] = color1;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
- return clip_enumerate(rdev, clip_call_copy_mono, &ccdata);
+ return clip_enumerate_rest(rdev, x, y, xe, ye,
+ clip_call_copy_mono, &ccdata);
}
/* Copy a color rectangle */
@@ -378,12 +396,8 @@ clip_copy_color(gx_device * dev,
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
- x += rdev->translation.x;
- y += rdev->translation.y;
- ccdata.tdev = rdev->target;
ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
- return clip_enumerate(rdev, clip_call_copy_color, &ccdata);
+ return clip_enumerate(rdev, x, y, w, h, clip_call_copy_color, &ccdata);
}
/* Copy a rectangle with alpha */
@@ -404,13 +418,9 @@ clip_copy_alpha(gx_device * dev,
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
- x += rdev->translation.x;
- y += rdev->translation.y;
- ccdata.tdev = rdev->target;
ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
ccdata.color[0] = color, ccdata.depth = depth;
- return clip_enumerate(rdev, clip_call_copy_alpha, &ccdata);
+ return clip_enumerate(rdev, x, y, w, h, clip_call_copy_alpha, &ccdata);
}
/* Fill a region defined by a mask. */
@@ -437,13 +447,9 @@ clip_fill_mask(gx_device * dev,
return gx_default_fill_mask(dev, data, sourcex, raster, id,
x, y, w, h, pdcolor, depth, lop,
pcpath);
- x += rdev->translation.x;
- y += rdev->translation.y;
- ccdata.tdev = rdev->target;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
ccdata.pdcolor = pdcolor, ccdata.depth = depth, ccdata.lop = lop;
- return clip_enumerate(rdev, clip_call_fill_mask, &ccdata);
+ return clip_enumerate(rdev, x, y, w, h, clip_call_fill_mask, &ccdata);
}
/* Strip-tile a rectangle. */
@@ -462,14 +468,10 @@ clip_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
- x += rdev->translation.x;
- y += rdev->translation.y;
- ccdata.tdev = rdev->target;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
ccdata.tiles = tiles;
ccdata.color[0] = color0, ccdata.color[1] = color1;
ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
- return clip_enumerate(rdev, clip_call_strip_tile_rectangle, &ccdata);
+ return clip_enumerate(rdev, x, y, w, h, clip_call_strip_tile_rectangle, &ccdata);
}
/* Copy a rectangle with RasterOp and strip texture. */
@@ -494,59 +496,58 @@ clip_strip_copy_rop(gx_device * dev,
gx_device_clip *rdev = (gx_device_clip *) dev;
clip_callback_data_t ccdata;
- x += rdev->translation.x;
- y += rdev->translation.y;
- ccdata.tdev = rdev->target;
- ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
ccdata.data = sdata, ccdata.sourcex = sourcex, ccdata.raster = raster;
ccdata.scolors = scolors, ccdata.textures = textures,
ccdata.tcolors = tcolors;
ccdata.phase.x = phase_x, ccdata.phase.y = phase_y, ccdata.lop = lop;
- return clip_enumerate(rdev, clip_call_strip_copy_rop, &ccdata);
+ return clip_enumerate(rdev, x, y, w, h, clip_call_strip_copy_rop, &ccdata);
}
/* Get the (outer) clipping box, in client coordinates. */
private void
clip_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
{
- gx_device_clip *rdev = (gx_device_clip *) dev;
- gx_device *tdev = rdev->target;
- gs_fixed_rect tbox, cbox;
- fixed tx = int2fixed(rdev->translation.x), ty = int2fixed(rdev->translation.y);
+ gx_device_clip *const rdev = (gx_device_clip *) dev;
- (*dev_proc(tdev, get_clipping_box)) (tdev, &tbox);
- /*
- * To get an accurate clipping box quickly in all cases, we should
- * save the outer box from the clipping path. However,
- * this is not currently (or even always guaranteed to be)
- * available. Instead, we compromise: if there is more than one
- * rectangle in the list, we return accurate Y values (which are
- * easy to obtain, because the list is Y-sorted) but copy the
- * X values from the target.
- */
- if (rdev->list.outside || rdev->list.count == 0) {
- cbox = tbox;
- } else if (rdev->list.count == 1) {
- cbox.p.x = int2fixed(rdev->list.single.xmin);
- cbox.p.y = int2fixed(rdev->list.single.ymin);
- cbox.q.x = int2fixed(rdev->list.single.xmax);
- cbox.q.y = int2fixed(rdev->list.single.ymax);
- } else { /* The head and tail elements are dummies.... */
- cbox.p.x = tbox.p.x;
- cbox.p.y = int2fixed(rdev->list.head->next->ymin);
- cbox.q.x = tbox.q.x;
- cbox.q.y = int2fixed(rdev->list.tail->prev->ymax);
+ if (!rdev->clipping_box_set) {
+ gx_device *tdev = rdev->target;
+ gs_fixed_rect tbox;
+
+ (*dev_proc(tdev, get_clipping_box)) (tdev, &tbox);
+ if (rdev->list.count != 0) {
+ gs_fixed_rect cbox;
+
+ if (rdev->list.count == 1) {
+ cbox.p.x = int2fixed(rdev->list.single.xmin);
+ cbox.p.y = int2fixed(rdev->list.single.ymin);
+ cbox.q.x = int2fixed(rdev->list.single.xmax);
+ cbox.q.y = int2fixed(rdev->list.single.ymax);
+ } else {
+ /* The head and tail elements are dummies.... */
+ cbox.p.x = int2fixed(rdev->list.xmin);
+ cbox.p.y = int2fixed(rdev->list.head->next->ymin);
+ cbox.q.x = int2fixed(rdev->list.xmax);
+ cbox.q.y = int2fixed(rdev->list.tail->prev->ymax);
+ }
+ rect_intersect(tbox, cbox);
+ }
+ if (rdev->translation.x | rdev->translation.y) {
+ fixed tx = int2fixed(rdev->translation.x),
+ ty = int2fixed(rdev->translation.y);
+
+ if (tbox.p.x != min_fixed)
+ tbox.p.x -= tx;
+ if (tbox.p.y != min_fixed)
+ tbox.p.y -= ty;
+ if (tbox.q.x != max_fixed)
+ tbox.q.x -= tx;
+ if (tbox.q.y != max_fixed)
+ tbox.q.y -= ty;
+ }
+ rdev->clipping_box = tbox;
+ rdev->clipping_box_set = true;
}
- rect_intersect(tbox, cbox);
- if (tbox.p.x != min_fixed)
- tbox.p.x -= tx;
- if (tbox.p.y != min_fixed)
- tbox.p.y -= ty;
- if (tbox.q.x != max_fixed)
- tbox.q.x -= tx;
- if (tbox.q.y != max_fixed)
- tbox.q.y -= ty;
- *pbox = tbox;
+ *pbox = rdev->clipping_box;
}
/* Get bits back from the device. */
diff --git a/gs/src/gxclip.h b/gs/src/gxclip.h
index 53d4fdafa..891e186ee 100644
--- a/gs/src/gxclip.h
+++ b/gs/src/gxclip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -55,14 +55,17 @@ typedef struct clip_callback_data_s {
/* Declare the callback procedures. */
int
clip_call_fill_rectangle(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)), clip_call_copy_mono(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)),
+ int xc, int yc, int xec, int yec)),
+ clip_call_copy_mono(P5(clip_callback_data_t * pccd,
+ int xc, int yc, int xec, int yec)),
clip_call_copy_color(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)), clip_call_copy_alpha(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)),
+ int xc, int yc, int xec, int yec)),
+ clip_call_copy_alpha(P5(clip_callback_data_t * pccd,
+ int xc, int yc, int xec, int yec)),
clip_call_fill_mask(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)), clip_call_strip_tile_rectangle(P5(clip_callback_data_t * pccd,
- int xc, int yc, int xec, int yec)),
+ int xc, int yc, int xec, int yec)),
+ clip_call_strip_tile_rectangle(P5(clip_callback_data_t * pccd,
+ int xc, int yc, int xec, int yec)),
clip_call_strip_copy_rop(P5(clip_callback_data_t * pccd,
int xc, int yc, int xec, int yec));
diff --git a/gs/src/gxclip2.h b/gs/src/gxclip2.h
index 1a32425ae..27c31a5ec 100644
--- a/gs/src/gxclip2.h
+++ b/gs/src/gxclip2.h
@@ -26,11 +26,15 @@
/* The structure for tile clipping is the same as for simple mask clipping. */
typedef gx_device_mask_clip gx_device_tile_clip;
-
+#define st_device_tile_clip st_device_mask_clip
+/*
+ * We can't just make this macro empty, since it is processed as a top-level
+ * declaration and would lead to an extraneous semicolon. The least damage
+ * we can do is make it declare a constant (and not static, since static
+ * would lead to a compiler warning about an unreferenced variable).
+ */
#define private_st_device_tile_clip() /* in gxclip2.c */\
- gs_private_st_suffix_add0(st_device_tile_clip, gx_device_tile_clip,\
- "gx_device_tile_clip", device_tile_clip_enum_ptrs,\
- device_tile_clip_reloc_ptrs, st_device_mask_clip)
+ const byte gxclip2_dummy = 0
/*
* Initialize a tile clipping device from a mask.
diff --git a/gs/src/gxclipsr.h b/gs/src/gxclipsr.h
new file mode 100644
index 000000000..d2ab408d3
--- /dev/null
+++ b/gs/src/gxclipsr.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Internals of clipsave/cliprestore */
+
+#ifndef gxclipsr_INCLUDED
+# define gxclipsr_INCLUDED
+
+#include "gsrefct.h"
+
+/*
+ * Unlike the graphics state stack, which is threaded through the actual
+ * gstate objects, the clipping path stack is implemented with separate,
+ * small objects. These are reference-counted, because they may be
+ * shared by off-stack graphics states.
+ */
+
+#ifndef gx_clip_path_DEFINED
+# define gx_clip_path_DEFINED
+typedef struct gx_clip_path_s gx_clip_path;
+#endif
+#ifndef gx_clip_stack_DEFINED
+# define gx_clip_stack_DEFINED
+typedef struct gx_clip_stack_s gx_clip_stack_t;
+#endif
+
+struct gx_clip_stack_s {
+ rc_header rc;
+ gx_clip_path *clip_path;
+ gx_clip_stack_t *next;
+};
+
+#define private_st_clip_stack() /* in gsclipsr.c */\
+ gs_private_st_ptrs2(st_clip_stack, gx_clip_stack_t,\
+ "gx_clip_stack_t", clip_stack_enum_ptrs, clip_stack_reloc_ptrs,\
+ clip_path, next)
+
+#endif /* gxclipsr_INCLUDED */
diff --git a/gs/src/gxclist.c b/gs/src/gxclist.c
index d9cba1862..3fadbd3d3 100644
--- a/gs/src/gxclist.c
+++ b/gs/src/gxclist.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,6 +30,40 @@
#include "gxclpath.h"
#include "gsparams.h"
+/* GC information */
+#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
+extern_st(st_imager_state);
+public
+ENUM_PTRS_WITH(device_clist_enum_ptrs, gx_device_clist *cdev)
+ if (index < st_device_forward_max_ptrs) {
+ gs_ptr_type_t ret = ENUM_USING_PREFIX(st_device_forward, 0);
+
+ return (ret ? ret : ENUM_OBJ(0));
+ }
+ if (!CLIST_IS_WRITER(cdev))
+ return 0;
+ index -= st_device_forward_max_ptrs;
+ switch (index) {
+ case 0: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
+ cdev->writer.clip_path : 0));
+ default:
+ return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
+ sizeof(gs_imager_state), index - 1);
+ }
+ENUM_PTRS_END
+public
+RELOC_PTRS_WITH(device_clist_reloc_ptrs, gx_device_clist *cdev)
+{
+ RELOC_PREFIX(st_device_forward);
+ if (!CLIST_IS_WRITER(cdev))
+ return;
+ if (cdev->writer.image_enum_id != gs_no_id)
+ RELOC_VAR(cdev->writer.clip_path);
+ RELOC_USING(st_imager_state, &cdev->writer.imager_state,
+ sizeof(gs_imager_state));
+} RELOC_PTRS_END
+public_st_device_clist();
+
/* Forward declarations of driver procedures */
private dev_proc_open_device(clist_open);
private dev_proc_output_page(clist_output_page);
@@ -198,25 +232,22 @@ clist_init_tile_cache(gx_device * dev, byte * init_data, ulong data_size)
* page_band_height (=page_info.band_params.BandHeight), nbands.
*/
private int
-clist_init_bands(gx_device * dev, uint data_size, int band_width,
- int band_height)
+clist_init_bands(gx_device * dev, gx_device_memory *bdev, uint data_size,
+ int band_width, int band_height)
{
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
- gx_device *target = cdev->target;
int nbands;
- if (gdev_mem_data_size((gx_device_memory *) target, band_width,
- band_height) > data_size
- )
+ if (gdev_mem_data_size(bdev, band_width, band_height) > data_size)
return_error(gs_error_rangecheck);
cdev->page_band_height = band_height;
- nbands = (target->height + band_height - 1) / band_height;
+ nbands = (cdev->target->height + band_height - 1) / band_height;
cdev->nbands = nbands;
#ifdef DEBUG
if (gs_debug_c('l') | gs_debug_c(':'))
dlprintf4("[:]width=%d, band_width=%d, band_height=%d, nbands=%d\n",
- target->width, band_width, band_height, nbands);
+ bdev->width, band_width, band_height, nbands);
#endif
return 0;
}
@@ -257,38 +288,42 @@ clist_init_data(gx_device * dev, byte * init_data, uint data_size)
&((gx_device_clist *)dev)->writer;
gx_device *target = cdev->target;
const int band_width =
- cdev->page_info.band_params.BandWidth =
- (cdev->band_params.BandWidth ? cdev->band_params.BandWidth :
- target->width);
+ cdev->page_info.band_params.BandWidth =
+ (cdev->band_params.BandWidth ? cdev->band_params.BandWidth :
+ target->width);
int band_height = cdev->band_params.BandHeight;
const uint band_space =
cdev->page_info.band_params.BandBufferSpace =
- (cdev->band_params.BandBufferSpace ?
- cdev->band_params.BandBufferSpace : data_size);
+ (cdev->band_params.BandBufferSpace ?
+ cdev->band_params.BandBufferSpace : data_size);
byte *data = init_data;
uint size = band_space;
uint bits_size;
+ gx_device_memory bdev;
+ gx_device *pbdev = (gx_device *)&bdev;
int code;
- if (band_height) { /*
- * The band height is fixed, so the band buffer requirement
- * is completely determined.
- */
+ /* Call create_buf_device to get the memory planarity set up. */
+ cdev->buf_procs.create_buf_device(&pbdev, target, NULL, NULL, true);
+ if (band_height) {
+ /*
+ * The band height is fixed, so the band buffer requirement
+ * is completely determined.
+ */
uint band_data_size =
- gdev_mem_data_size((gx_device_memory *) target,
- band_width, band_height);
+ gdev_mem_data_size(&bdev, band_width, band_height);
if (band_data_size >= band_space)
return_error(gs_error_rangecheck);
bits_size = min(band_space - band_data_size, data_size >> 1);
- } else { /*
- * Choose the largest band height that will fit in the
- * rendering-time buffer.
- */
+ } else {
+ /*
+ * Choose the largest band height that will fit in the
+ * rendering-time buffer.
+ */
bits_size = clist_tile_cache_size(target, band_space);
bits_size = min(bits_size, data_size >> 1);
- band_height = gdev_mem_max_height((gx_device_memory *) target,
- band_width,
+ band_height = gdev_mem_max_height(&bdev, band_width,
band_space - bits_size);
if (band_height == 0)
return_error(gs_error_rangecheck);
@@ -299,7 +334,7 @@ clist_init_data(gx_device * dev, byte * init_data, uint data_size)
cdev->page_tile_cache_size = bits_size;
data += bits_size;
size -= bits_size;
- code = clist_init_bands(dev, size, band_width, band_height);
+ code = clist_init_bands(dev, &bdev, size, band_width, band_height);
if (code < 0)
return code;
return clist_init_states(dev, data, data_size - bits_size);
@@ -359,6 +394,7 @@ clist_reset(gx_device * dev)
cdev->clip_path = NULL;
cdev->clip_path_id = gs_no_id;
cdev->color_space = 0;
+ cdev->color_space_id = gs_no_id;
{
int i;
@@ -397,26 +433,26 @@ clist_reinit_output_file(gx_device *dev)
&((gx_device_clist *)dev)->writer;
int code = 0;
- /* bfile needs to guarantee cmd_blocks for: 1 band range, nbands */
- /* & terminating entry */
- int b_block = sizeof(cmd_block) * (cdev->nbands + 2);
-
- /* cfile needs to guarantee one writer buffer */
- /* + one end_clip cmd (if during image's clip path setup) */
- /* + an end_image cmd for each band (if during image) */
- /* + end_cmds for each band and one band range */
- int c_block
- = cdev->cend - cdev->cbuf + 2 + cdev->nbands * 2 + (cdev->nbands + 1);
-
- /* All this is for partial page rendering's benefit, do only */
- /* if partial page rendering is available */
- if ( clist_test_VMerror_recoverable(cdev) )
- { if (cdev->page_bfile != 0)
- code = clist_set_memory_warning(cdev->page_bfile, b_block);
- if (code >= 0 && cdev->page_cfile != 0)
- code = clist_set_memory_warning(cdev->page_cfile, c_block);
- }
- return code;
+ /* bfile needs to guarantee cmd_blocks for: 1 band range, nbands */
+ /* & terminating entry */
+ int b_block = sizeof(cmd_block) * (cdev->nbands + 2);
+
+ /* cfile needs to guarantee one writer buffer */
+ /* + one end_clip cmd (if during image's clip path setup) */
+ /* + an end_image cmd for each band (if during image) */
+ /* + end_cmds for each band and one band range */
+ int c_block =
+ cdev->cend - cdev->cbuf + 2 + cdev->nbands * 2 + (cdev->nbands + 1);
+
+ /* All this is for partial page rendering's benefit, do only */
+ /* if partial page rendering is available */
+ if ( clist_test_VMerror_recoverable(cdev) )
+ { if (cdev->page_bfile != 0)
+ code = clist_set_memory_warning(cdev->page_bfile, b_block);
+ if (code >= 0 && cdev->page_cfile != 0)
+ code = clist_set_memory_warning(cdev->page_cfile, c_block);
+ }
+ return code;
}
/* Write out the current parameters that must be at the head of each page */
@@ -428,18 +464,29 @@ clist_emit_page_header(gx_device *dev)
&((gx_device_clist *)dev)->writer;
int code = 0;
- if ( (cdev->disable_mask & clist_disable_pass_thru_params) )
- { do
+ if ((cdev->disable_mask & clist_disable_pass_thru_params)) {
+ do
if ((code = clist_put_current_params(cdev)) >= 0)
break;
- while ((code = clist_VMerror_recover(cdev, code)) >= 0);
- cdev->permanent_error = (code < 0) ? code : 0;
+ while ((code = clist_VMerror_recover(cdev, code)) >= 0);
+ cdev->permanent_error = (code < 0 ? code : 0);
if (cdev->permanent_error < 0)
cdev->error_is_retryable = 0;
- }
+ }
return code;
}
+/* Reset parameters for the beginning of a page. */
+private void
+clist_reset_page(gx_device_clist_writer *cwdev)
+{
+ cwdev->page_bfile_end_pos = 0;
+ /* Indicate that the colors_used information hasn't been computed. */
+ cwdev->page_info.scan_lines_per_colors_used = 0;
+ memset(cwdev->page_info.band_colors_used, 0,
+ sizeof(cwdev->page_info.band_colors_used));
+}
+
/* Open the device's bandfiles */
private int
clist_open_output_file(gx_device *dev)
@@ -460,7 +507,7 @@ clist_open_output_file(gx_device *dev)
strcat(fmode, gp_fmode_binary_suffix);
cdev->page_cfname[0] = 0; /* create a new file */
cdev->page_bfname[0] = 0; /* ditto */
- cdev->page_bfile_end_pos = 0;
+ clist_reset_page(cdev);
if ((code = clist_fopen(cdev->page_cfname, fmode, &cdev->page_cfile,
cdev->bandlist_memory, cdev->bandlist_memory,
true)) < 0 ||
@@ -553,7 +600,7 @@ clist_finish_page(gx_device *dev, bool flush)
clist_rewind(cdev->page_cfile, true, cdev->page_cfname);
if (cdev->page_bfile != 0)
clist_rewind(cdev->page_bfile, true, cdev->page_bfname);
- cdev->page_bfile_end_pos = 0;
+ clist_reset_page(cdev);
} else {
if (cdev->page_cfile != 0)
clist_fseek(cdev->page_cfile, 0L, SEEK_END, cdev->page_cfname);
@@ -586,10 +633,12 @@ clist_end_page(gx_device_clist_writer * cldev)
*/
cb.band_min = cb.band_max = cmd_band_end;
cb.pos = (cldev->page_cfile == 0 ? 0 : clist_ftell(cldev->page_cfile));
- clist_fwrite_chars(&cb, sizeof(cb), cldev->page_bfile);
- cldev->page_bfile_end_pos = clist_ftell(cldev->page_bfile);
+ code = clist_fwrite_chars(&cb, sizeof(cb), cldev->page_bfile);
+ if (code > 0)
+ code = 0;
}
if (code >= 0) {
+ clist_compute_colors_used(cldev);
ecode |= code;
cldev->page_bfile_end_pos = clist_ftell(cldev->page_bfile);
}
@@ -610,6 +659,30 @@ clist_end_page(gx_device_clist_writer * cldev)
return 0;
}
+/* Compute the set of used colors in the page_info structure. */
+void
+clist_compute_colors_used(gx_device_clist_writer *cldev)
+{
+ int nbands = cldev->nbands;
+ int bands_per_colors_used =
+ (nbands + PAGE_INFO_NUM_COLORS_USED - 1) /
+ PAGE_INFO_NUM_COLORS_USED;
+ int band;
+
+ cldev->page_info.scan_lines_per_colors_used =
+ cldev->page_band_height * bands_per_colors_used;
+ memset(cldev->page_info.band_colors_used, 0,
+ sizeof(cldev->page_info.band_colors_used));
+ for (band = 0; band < nbands; ++band) {
+ int entry = band / bands_per_colors_used;
+
+ cldev->page_info.band_colors_used[entry].or |=
+ cldev->states[band].colors_used.or;
+ cldev->page_info.band_colors_used[entry].slow_rop |=
+ cldev->states[band].colors_used.slow_rop;
+ }
+}
+
/* Recover recoverable VM error if possible without flushing */
int /* ret -ve err, >= 0 if recovered w/# = cnt pages left in page queue */
clist_VMerror_recover(gx_device_clist_writer *cldev,
diff --git a/gs/src/gxclist.h b/gs/src/gxclist.h
index 73f71bacd..9a1b39b68 100644
--- a/gs/src/gxclist.h
+++ b/gs/src/gxclist.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,7 +27,9 @@
#include "gxband.h"
#include "gxbcache.h"
#include "gxclio.h"
+#include "gxdevbuf.h"
#include "gxistate.h"
+#include "gxrplane.h"
/*
* A command list is essentially a compressed list of driver calls.
@@ -160,7 +162,7 @@ typedef struct gx_clist_state_s gx_clist_state;
/* See gx_device_clist_writer, below, for more that must be init'd */\
/* gx_device *target; */ /* device for which commands */\
/* are being buffered */\
- dev_proc_make_buffer_device((*make_buffer_device));\
+ gx_device_buf_procs_t buf_procs;\
gs_memory_t *bandlist_memory; /* allocator for in-memory bandlist files */\
byte *data; /* buffer area */\
uint data_size; /* size of buffer */\
@@ -217,7 +219,8 @@ typedef struct gx_device_clist_writer_s {
const gx_clip_path *clip_path; /* current clip path */
gs_id clip_path_id; /* id of current clip path */
byte color_space; /* current color space identifier */
- /* (only used for images) */
+ /* (only used for images) */
+ gs_id color_space_id; /* ditto */
gs_indexed_params indexed_params; /* current indexed space parameters */
/* (ditto) */
gs_id transfer_ids[4]; /* ids of transfer maps */
@@ -249,6 +252,8 @@ typedef struct gx_device_clist_writer_s {
/* For normal rasterizing, pages and num_pages are both 0. */
typedef struct gx_device_clist_reader_s {
gx_device_clist_common_members; /* (must be first) */
+ gx_render_plane_t yplane; /* current plane, index = -1 */
+ /* means all planes */
const gx_placed_page *pages;
int num_pages;
} gx_device_clist_reader;
@@ -259,17 +264,27 @@ typedef union gx_device_clist_s {
gx_device_clist_writer writer;
} gx_device_clist;
+extern_st(st_device_clist);
+#define public_st_device_clist() /* in gxclist.c */\
+ gs_public_st_complex_only(st_device_clist, gx_device_clist,\
+ "gx_device_clist", 0, device_clist_enum_ptrs, device_clist_reloc_ptrs,\
+ gx_device_finalize)
+#define st_device_clist_max_ptrs\
+ (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
+
/* setup before opening clist device */
-#define clist_init_params(xclist, xdata, xdata_size, xtarget, xmake_buffer, xband_params, xexternal, xmemory, xfree_bandlist, xdisable)\
+#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable)\
+ BEGIN\
(xclist)->common.data = (xdata);\
(xclist)->common.data_size = (xdata_size);\
(xclist)->common.target = (xtarget);\
- (xclist)->common.make_buffer_device = (xmake_buffer);\
+ (xclist)->common.buf_procs = (xbuf_procs);\
(xclist)->common.band_params = (xband_params);\
(xclist)->common.do_not_open_or_close_bandfiles = (xexternal);\
(xclist)->common.bandlist_memory = (xmemory);\
(xclist)->writer.free_up_bandlist_memory = (xfree_bandlist);\
- (xclist)->writer.disable_mask = (xdisable)
+ (xclist)->writer.disable_mask = (xdisable);\
+ END
/* Determine whether this clist device is able to recover VMerrors */
#define clist_test_VMerror_recoverable(cldev)\
@@ -290,6 +305,14 @@ int clist_close_output_file(P1(gx_device *dev));
*/
int clist_close_page_info(P1(gx_band_page_info_t *ppi));
+/*
+ * Compute the colors-used information in the page_info structure from the
+ * information in the individual writer bands. This is only useful at the
+ * end of a page. gdev_prn_colors_used calls this procedure if it hasn't
+ * been called since the page was started. clist_end_page also calls it.
+ */
+void clist_compute_colors_used(P1(gx_device_clist_writer *cldev));
+
/* Define the abstract type for a printer device. */
#ifndef gx_device_printer_DEFINED
# define gx_device_printer_DEFINED
@@ -299,13 +322,13 @@ typedef struct gx_device_printer_s gx_device_printer;
/* Do device setup from params passed in the command list. */
int clist_setup_params(P1(gx_device *dev));
-/* Do more rendering to a client-supplied memory image, return results */
-int clist_get_overlay_bits(P4(gx_device_printer *pdev, int y, int line_count,
- byte *data));
-
-/* Find out where the band buffer for a given line is going to fall on the */
-/* next call to get_bits. */
-int clist_locate_overlay_buffer(P3(gx_device_printer *pdev, int y,
- byte **pdata));
+/*
+ * Render a rectangle to a client-supplied image. This implements
+ * gdev_prn_render_rectangle for devices that are using banding.
+ */
+int clist_render_rectangle(P5(gx_device_clist *cdev,
+ const gs_int_rect *prect, gx_device *bdev,
+ const gx_render_plane_t *render_plane,
+ bool clear));
#endif /* gxclist_INCLUDED */
diff --git a/gs/src/gxclmem.c b/gs/src/gxclmem.c
index 487e0ffed..ed85beb67 100644
--- a/gs/src/gxclmem.c
+++ b/gs/src/gxclmem.c
@@ -21,7 +21,6 @@
#include "memory_.h"
#include "gx.h"
#include "gserrors.h"
-#include "gsmalloc.h" /* for gs_memory_default */
#include "gxclmem.h"
/*
@@ -91,10 +90,10 @@ DECOMPRESSION.
decompression buffer list in order to keep the tail of the list as the
"least recently used".
- There are some DEBUG_MEMFILE global static variables used to count the
- number of cache hits "tot_cache_hits" and the number of times a logical
- block is decompressed "tot_cache_miss". Note that the actual number of cache
- miss events is 'f->log_length/MEMFILE_DATA_SIZE - tot_cache_miss' since we
+ There are some DEBUG global static variables used to count the number of
+ cache hits "tot_cache_hits" and the number of times a logical block is
+ decompressed "tot_cache_miss". Note that the actual number of cache miss
+ events is 'f->log_length/MEMFILE_DATA_SIZE - tot_cache_miss' since we
assume that every logical block must be decmpressed at least once.
Empirical results so far indicate that if one cache raw buffer for every
@@ -160,10 +159,10 @@ private void memfile_free_mem(P1(MEMFILE * f));
private int memfile_init_empty(P1(MEMFILE * f));
/************************************************/
-/* #define DEBUG_MEMFILE /- force statistics -/ */
+/* #define DEBUG /- force statistics -/ */
/************************************************/
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
long tot_compressed;
long tot_raw;
long tot_cache_miss;
@@ -302,7 +301,7 @@ memfile_fopen(char fname[gp_file_name_sizeof], const char *fmode,
}
f->total_space = 0;
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
/* If this is the start, init some statistics. */
/* Hack: we know the 'a' file is opened first. */
if (*fname == 'a') {
@@ -499,7 +498,7 @@ compress_log_blk(MEMFILE * f, LOG_MEMFILE_BLK * bp)
eprintf2("\nCompression didn't - raw=%d, compressed=%ld\n",
MEMFILE_DATA_SIZE, compressed_size);
}
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
tot_compressed += compressed_size;
#endif
return (status < 0 ? gs_note_error(gs_error_ioerror) : ecode);
@@ -659,7 +658,7 @@ memfile_fwrite_chars(const void *data, uint len, clist_file_ptr cf)
}
f->log_curr_pos += len;
f->log_length = f->log_curr_pos; /* truncate length to here */
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
tot_raw += len;
#endif
return (len);
@@ -732,13 +731,13 @@ memfile_get_pdata(MEMFILE * f)
num_raw_buffers);
} /* end allocating the raw buffer pool (first time only) */
if (bp->raw_block == NULL) {
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
tot_cache_miss++; /* count every decompress */
#endif
/* find a raw buffer and decompress */
if (f->raw_tail->log_blk != NULL) {
/* This block was in use, grab it */
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
tot_swap_out++;
#endif
f->raw_tail->log_blk->raw_block = NULL; /* data no longer here */
@@ -762,7 +761,7 @@ memfile_get_pdata(MEMFILE * f)
f->wt.limit = f->wt.ptr + MEMFILE_DATA_SIZE;
f->rd.ptr = (const byte *)(bp->phys_pdata) - 1;
f->rd.limit = (const byte *)bp->phys_blk->data_limit;
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
decomp_wt_ptr0 = f->wt.ptr;
decomp_wt_limit0 = f->wt.limit;
decomp_rd_ptr0 = f->rd.ptr;
@@ -782,7 +781,7 @@ memfile_get_pdata(MEMFILE * f)
}
f->rd.ptr = (const byte *)bp->phys_blk->link->data - back_up - 1;
f->rd.limit = (const byte *)bp->phys_blk->link->data_limit;
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
decomp_wt_ptr1 = f->wt.ptr;
decomp_wt_limit1 = f->wt.limit;
decomp_rd_ptr1 = f->rd.ptr;
@@ -813,7 +812,7 @@ memfile_get_pdata(MEMFILE * f)
bp->raw_block->fwd = f->raw_head; /* this.fwd = orig head */
f->raw_head = bp->raw_block; /* head = this */
f->raw_head->back = NULL; /* this.back = NULL */
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
tot_cache_hits++; /* counting here prevents repeats since */
/* won't count if already at head */
#endif
@@ -942,7 +941,7 @@ memfile_free_mem(MEMFILE * f)
{
LOG_MEMFILE_BLK *bp, *tmpbp;
-#ifdef DEBUG_MEMFILE
+#ifdef DEBUG
/* output some diagnostics about the effectiveness */
if (tot_raw > 100) {
if_debug2(':', "[:]tot_raw=%ld, tot_compressed=%ld\n",
diff --git a/gs/src/gxclpath.c b/gs/src/gxclpath.c
index 23082bb7e..e306863e8 100644
--- a/gs/src/gxclpath.c
+++ b/gs/src/gxclpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -58,11 +58,11 @@ colored_halftone_colors_used(gx_device_clist_writer *cldev,
*/
if (dev_proc(cldev, map_cmyk_color) != cmyk_1bit_map_cmyk_color)
return ((gx_color_index)1 << cldev->color_info.depth) - 1;
- /*
- * Note that c_base[0], and the low-order bit of plane_mask,
- * correspond to cyan: this requires reversing the bit order of
- * the plane mask.
- */
+ /*
+ * Note that c_base[0], and the low-order bit of plane_mask,
+ * correspond to cyan: this requires reversing the bit order of
+ * the plane mask.
+ */
return
((pdcolor->colors.colored.c_base[0] << 3) |
(pdcolor->colors.colored.c_base[1] << 2) |
@@ -71,6 +71,29 @@ colored_halftone_colors_used(gx_device_clist_writer *cldev,
(byte_reverse_bits[pdcolor->colors.colored.plane_mask] >> 4));
}
+/*
+ * Compute whether a drawing operation will require the slow (full-pixel)
+ * RasterOp implementation. If pdcolor is not NULL, it is the texture for
+ * the RasterOp.
+ */
+bool
+cmd_slow_rop(gx_device *dev, gs_logical_operation_t lop,
+ const gx_drawing_color *pdcolor)
+{
+ gs_rop3_t rop = lop_rop(lop);
+
+ if (pdcolor != 0 && gx_dc_is_pure(pdcolor)) {
+ gx_color_index color = gx_dc_pure_color(pdcolor);
+
+ if (color == gx_device_black(dev))
+ rop = rop3_know_T_0(rop);
+ else if (color == gx_device_white(dev))
+ rop = rop3_know_T_1(rop);
+ }
+ return !(rop == rop3_0 || rop == rop3_1 ||
+ rop == rop3_D || rop == rop3_S || rop == rop3_T);
+}
+
/* Write out the color for filling, stroking, or masking. */
/* We should be able to share this with clist_tile_rectangle, */
/* but I don't see how to do it without adding a level of procedure. */
@@ -84,7 +107,7 @@ cmd_put_drawing_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
if (gx_dc_is_pure(pdcolor)) {
gx_color_index color1 = gx_dc_pure_color(pdcolor);
- pcls->colors_used |= color1;
+ pcls->colors_used.or |= color1;
if (color1 != pcls->colors[1]) {
int code = cmd_set_color1(cldev, pcls, color1);
@@ -98,7 +121,7 @@ cmd_put_drawing_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
gx_color_index color0 = gx_dc_binary_color0(pdcolor);
gx_color_index color1 = gx_dc_binary_color1(pdcolor);
- pcls->colors_used |= color0 | color1;
+ pcls->colors_used.or |= color0 | color1;
/* Set up tile and colors as for clist_tile_rectangle. */
if (!cls_has_tile_id(cldev, pcls, tile->id, offset_temp)) {
int depth =
@@ -126,12 +149,14 @@ cmd_put_drawing_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
byte buf[4 + 4 * cmd_max_intsize(sizeof(pdcolor->colors.colored.c_level[0]))];
byte *bp = buf;
int i;
+ byte cmd;
uint short_bases = 0;
ulong bases = 0;
+ byte flags = 0;
byte *dp;
int code;
- pcls->colors_used |=
+ pcls->colors_used.or |=
colored_halftone_colors_used(cldev, pdcolor);
/****** HOW TO TELL IF COLOR IS ALREADY SET? ******/
if (pdht->id != cldev->device_halftone_id) {
@@ -148,20 +173,25 @@ cmd_put_drawing_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
return_error(gs_error_rangecheck);
bases |= base << ((3 - i) * 5);
short_bases |= base << (3 - i);
+ if (pdcolor->colors.colored.c_level[i])
+ flags |= 0x80 >> i;
}
if (bases & 0xf7bde) {
/* Some base value requires more than 1 bit. */
- *bp++ = 0x10 + (byte) (bases >> 16);
+ cmd = cmd_opv_set_color;
+ *bp++ = flags | (byte)(bases >> 16);
*bp++ = (byte) (bases >> 8);
*bp++ = (byte) bases;
} else {
/* The bases all fit in 1 bit each. */
- *bp++ = 0x00 + (byte) short_bases;
+ cmd = cmd_opv_set_color_short;
+ *bp++ = flags | (byte)short_bases;
}
for (i = 0; i < num_comp; ++i)
- bp = cmd_put_w((uint) pdcolor->colors.colored.c_level[i], bp);
+ if (flags & (0x80 >> i))
+ bp = cmd_put_w((uint)pdcolor->colors.colored.c_level[i], bp);
/****** IGNORE alpha ******/
- code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_color, bp - buf + 1);
+ code = set_cmd_put_op(dp, cldev, pcls, cmd, bp - buf + 1);
if (code < 0)
return code;
memcpy(dp + 1, buf, bp - buf);
@@ -412,7 +442,7 @@ cmd_write_unknown(gx_device_clist_writer * cldev, gx_clist_state * pcls,
}
{
int end_code =
- set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 2);
+ set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 1);
if (code >= 0)
code = end_code; /* take the first failure seen */
@@ -424,11 +454,9 @@ cmd_write_unknown(gx_device_clist_writer * cldev, gx_clist_state * pcls,
*/
++cldev->ignore_lo_mem_warnings;
end_code =
- set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 2);
+ set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 1);
--cldev->ignore_lo_mem_warnings;
}
- if (end_code >= 0)
- dp[1] = (gx_cpath_is_outside(pcpath) ? 1 : 0);
}
if (code < 0)
return code;
@@ -440,8 +468,8 @@ cmd_write_unknown(gx_device_clist_writer * cldev, gx_clist_state * pcls,
if (cldev->color_space & 8) { /* indexed */
uint num_values = (cldev->indexed_params.hival + 1) *
- gs_color_space_num_components(
- (const gs_color_space *)&cldev->indexed_params.base_space);
+ gs_color_space_num_components(
+ (const gs_color_space *)&cldev->indexed_params.base_space);
bool use_proc = cldev->color_space & 4;
const void *map_data;
uint map_size;
@@ -487,6 +515,7 @@ clist_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
(params->rule == gx_rule_even_odd ?
cmd_opv_eofill : cmd_opv_fill);
gs_fixed_point adjust;
+ bool slow_rop = cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor);
if ( (cdev->disable_mask & clist_disable_fill_path) ||
gs_debug_c(',')
@@ -540,10 +569,12 @@ clist_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
)
return code;
code = cmd_put_drawing_color(cdev, pcls, pdcolor);
- if (code < 0) { /* Something went wrong, use the default implementation. */
+ if (code < 0) {
+ /* Something went wrong, use the default implementation. */
return gx_default_fill_path(dev, pis, ppath, params, pdcolor,
pcpath);
}
+ pcls->colors_used.slow_rop |= slow_rop;
code = cmd_put_path(cdev, pcls, ppath,
int2fixed(max(y - 1, y0)),
int2fixed(min(y + height + 1, y1)),
@@ -569,6 +600,7 @@ clist_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
int adjust_y;
int y, height, y0, y1;
gs_logical_operation_t lop = pis->log_op;
+ bool slow_rop = cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor);
if ((cdev->disable_mask & clist_disable_stroke_path) ||
gs_debug_c(',')
@@ -688,6 +720,7 @@ clist_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath,
return gx_default_stroke_path(dev, pis, ppath, params, pdcolor,
pcpath);
}
+ pcls->colors_used.slow_rop |= slow_rop;
{
fixed ymin, ymax;
@@ -731,6 +764,7 @@ clist_put_polyfill(gx_device *dev, fixed px, fixed py,
&((gx_device_clist *)dev)->writer;
gs_fixed_rect bbox;
int y, height, y0, y1;
+ bool slow_rop = cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor);
if (gs_debug_c(','))
return -1; /* path-based banding is disabled */
@@ -752,6 +786,7 @@ clist_put_polyfill(gx_device *dev, fixed px, fixed py,
if ((code = cmd_update_lop(cdev, pcls, lop)) < 0 ||
(code = cmd_put_drawing_color(cdev, pcls, pdcolor)) < 0)
goto out;
+ pcls->colors_used.slow_rop |= slow_rop;
code = cmd_put_path(cdev, pcls, &path,
int2fixed(max(y - 1, y0)),
int2fixed(min(y + height + 1, y1)),
@@ -771,8 +806,6 @@ clist_fill_parallelogram(gx_device *dev, fixed px, fixed py,
const gx_drawing_color *pdcolor,
gs_logical_operation_t lop)
{
- gx_device_clist_writer * const cdev =
- &((gx_device_clist *)dev)->writer;
gs_fixed_point pts[3];
int code;
@@ -783,13 +816,6 @@ clist_fill_parallelogram(gx_device *dev, fixed px, fixed py,
return gx_fill_rectangle_device_rop(r.p.x, r.p.y, r.q.x - r.p.x,
r.q.y - r.p.y, pdcolor, dev, lop);
}
- if ( (cdev->disable_mask & clist_disable_fill_path) ||
- gs_debug_c(',')
- ) {
- /* Disable path-based banding. */
- return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by,
- pdcolor, lop);
- }
pts[0].x = px + ax, pts[0].y = py + ay;
pts[1].x = pts[0].x + bx, pts[1].y = pts[0].y + by;
pts[2].x = px + bx, pts[2].y = py + by;
@@ -805,18 +831,9 @@ clist_fill_triangle(gx_device *dev, fixed px, fixed py,
const gx_drawing_color *pdcolor,
gs_logical_operation_t lop)
{
- gx_device_clist_writer * const cdev =
- &((gx_device_clist *)dev)->writer;
gs_fixed_point pts[2];
int code;
- if ( (cdev->disable_mask & clist_disable_fill_path) ||
- gs_debug_c(',')
- ) {
- /* Disable path-based banding. */
- return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by,
- pdcolor, lop);
- }
pts[0].x = px + ax, pts[0].y = py + ay;
pts[1].x = px + bx, pts[1].y = py + by;
code = clist_put_polyfill(dev, px, py, pts, 2, pdcolor, lop);
@@ -1057,6 +1074,7 @@ cmd_put_path(gx_device_clist_writer * cldev, gx_clist_state * pcls,
set_first_point();
for (;;) {
fixed vs[6];
+ struct { fixed vs[6]; } prev;
#define A vs[0]
#define B vs[1]
@@ -1272,7 +1290,16 @@ cmd_put_path(gx_device_clist_writer * cldev, gx_clist_state * pcls,
E -= C, F -= D;
C -= A, D -= B;
A -= px, B -= py;
- if (B == 0 && E == 0) {
+ if (*writer.dp >= cmd_opv_min_curveto &&
+ *writer.dp <= cmd_opv_max_curveto &&
+ ((prev.A == 0 &&
+ A == prev.E && C == prev.C && E == prev.A &&
+ B == -prev.F && D == -prev.D && F == -prev.B) ||
+ (A == -prev.E && C == -prev.C && E == -prev.A &&
+ B == prev.F && D == prev.D && F == prev.B))
+ )
+ op = cmd_opv_scurveto;
+ else if (B == 0 && E == 0) {
B = A, E = F, optr++, op = cmd_opv_hvcurveto;
if ((B ^ D) >= 0) {
if (C == D && E == B)
@@ -1292,6 +1319,7 @@ cmd_put_path(gx_device_clist_writer * cldev, gx_clist_state * pcls,
op = cmd_opv_rncurveto;
else
op = cmd_opv_rrcurveto;
+ memcpy(prev.vs, vs, sizeof(prev.vs));
px = nx, py = ny;
open = 1;
code = cmd_put_segment(&writer, op, optr, notes);
diff --git a/gs/src/gxclpath.h b/gs/src/gxclpath.h
index ee7767f2d..76f42b328 100644
--- a/gs/src/gxclpath.h
+++ b/gs/src/gxclpath.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,8 +22,6 @@
#ifndef gxclpath_INCLUDED
# define gxclpath_INCLUDED
-#include "gxfixed.h" /* for gzpath.h */
-
/* Define the flags indicating whether a band knows the current values of */
/* various miscellaneous parameters (pcls->known). */
#define flatness_known (1<<0)
@@ -51,15 +49,16 @@ typedef enum {
/* Extend the command set. See gxcldev.h for more information. */
typedef enum {
cmd_op_misc2 = 0xd0, /* (see below) */
- cmd_opv_set_color = 0xd0, /* (0000abcd | */
- /* 0001aaaa abbbbbcc cccddddd), */
- /* (3|4) x level#: colored halftone */
- /* with base colors a,b,c,d */
- cmd_opv_set_fill_adjust = 0xd1, /* adjust_x/y(fixed) */
- cmd_opv_set_ctm = 0xd2, /* [per sput/sget_matrix] */
- cmd_opv_set_color_space = 0xd3, /* base(4)Indexed?(2)0(3) */
+ cmd_opv_set_color = 0xd0, /* pqrsaaaa abbbbbcc cccddddd */
+ /* (level[0] if p) (level[1] if q) */
+ /* (level[2] if r) (level[3] if s) */
+ /* colored halftone with base colors a,b,c,d */
+ cmd_opv_set_color_short = 0xd1, /* pqrsabcd, level[i] as above */
+ cmd_opv_set_fill_adjust = 0xd2, /* adjust_x/y(fixed) */
+ cmd_opv_set_ctm = 0xd3, /* [per sput/sget_matrix] */
+ cmd_opv_set_color_space = 0xd4, /* base(4)Indexed?(2)0(2) */
/* [, hival#, table|map] */
- cmd_opv_set_misc2 = 0xd4,
+ cmd_opv_set_misc2 = 0xd5,
#define cmd_set_misc2_cap_join (0x00) /* 00: cap(3)join(3) */
#define cmd_set_misc2_ac_op_sa (0x40) /* 01: 0(3)acc.curves(1)overprint(1) */
/* stroke_adj(1) */
@@ -75,7 +74,7 @@ typedef enum {
cmd_opv_enable_clip = 0xd7, /* (nothing) */
cmd_opv_disable_clip = 0xd8, /* (nothing) */
cmd_opv_begin_clip = 0xd9, /* (nothing) */
- cmd_opv_end_clip = 0xda, /* outside? */
+ cmd_opv_end_clip = 0xda, /* (nothing) */
cmd_opv_begin_image_rect = 0xdb, /* same as begin_image, followed by */
/* x0#, w-x1#, y0#, h-y1# */
cmd_opv_begin_image = 0xdc, /* image_type_table index, */
@@ -92,21 +91,27 @@ typedef enum {
cmd_opv_rlineto = 0xe1, /* dx%, dy% */
cmd_opv_hlineto = 0xe2, /* dx% */
cmd_opv_vlineto = 0xe3, /* dy% */
- cmd_opv_rrcurveto = 0xe4, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
- cmd_opv_hvcurveto = 0xe5, /* dx1%, dx2%,dy2%, dy3% */
- cmd_opv_vhcurveto = 0xe6, /* dy1%, dx2%,dy2%, dx3% */
- cmd_opv_nrcurveto = 0xe7, /* dx2%,dy2%, dx3%,dy3% */
- cmd_opv_rncurveto = 0xe8, /* dx1%,dy1%, dx2%,dy2% */
- cmd_opv_rmlineto = 0xe9, /* dx1%,dy1%, dx2%,dy2% */
- cmd_opv_rm2lineto = 0xea, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
- cmd_opv_rm3lineto = 0xeb, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3%, */
+ cmd_opv_rmlineto = 0xe4, /* dx1%,dy1%, dx2%,dy2% */
+ cmd_opv_rm2lineto = 0xe5, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
+ cmd_opv_rm3lineto = 0xe6, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3%, */
/* [-dx2,-dy2 implicit] */
+ cmd_opv_rrcurveto = 0xe7, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
+ cmd_opv_min_curveto = cmd_opv_rrcurveto,
+ cmd_opv_hvcurveto = 0xe8, /* dx1%, dx2%,dy2%, dy3% */
+ cmd_opv_vhcurveto = 0xe9, /* dy1%, dx2%,dy2%, dx3% */
+ cmd_opv_nrcurveto = 0xea, /* dx2%,dy2%, dx3%,dy3% */
+ cmd_opv_rncurveto = 0xeb, /* dx1%,dy1%, dx2%,dy2% */
cmd_opv_vqcurveto = 0xec, /* dy1%, dx2%[,dy2=dx2 with sign */
/* of dy1, dx3=dy1 with sign of dx2] */
cmd_opv_hqcurveto = 0xed, /* dx1%, [dx2=dy2 with sign */
/* of dx1,]%dy2, [dy3=dx1 with sign */
/* of dy2] */
- cmd_opv_closepath = 0xee, /* (nothing) */
+ cmd_opv_scurveto = 0xee, /* all implicit: previous op must have been */
+ /* *curveto with one or more of dx/y1/3 = 0. */
+ /* If h*: -dx3,dy3, -dx2,dy2, -dx1,dy1. */
+ /* If v*: dx3,-dy3, dx2,-dy2, dx1,-dy1. */
+ cmd_opv_max_curveto = cmd_opv_scurveto,
+ cmd_opv_closepath = 0xef, /* (nothing) */
cmd_op_path = 0xf0, /* (see below) */
/* The path drawing commands come in groups: */
/* each group consists of a base command plus an offset */
@@ -126,19 +131,19 @@ typedef enum {
} gx_cmd_xop;
#define cmd_segment_op_num_operands_values\
- 2, 2, 1, 1, 6, 4, 4, 4, 4, 4, 6, 6, 2, 2, 0
+ 2, 2, 1, 1, 4, 6, 6, 6, 4, 4, 4, 4, 2, 2, 0, 0
#define cmd_misc2_op_name_strings\
- "set_color", "set_fill_adjust", "set_ctm", "set_color_space",\
- "set_misc2", "?d5?", "set_dash", "enable_clip",\
+ "set_color", "set_color_short", "set_fill_adjust", "set_ctm",\
+ "set_color_space", "set_misc2", "set_dash", "enable_clip",\
"disable_clip", "begin_clip", "end_clip", "begin_image_rect",\
"begin_image", "image_data", "image_plane_data", "put_params"
#define cmd_segment_op_name_strings\
"rmoveto", "rlineto", "hlineto", "vlineto",\
- "rrcurveto", "hvcurveto", "vhcurveto", "nrcurveto",\
- "rncurveto", "rmlineto", "rm2lineto", "rm3lineto",\
- "vqcurveto", "hqcurveto", "closepath", "?ef?"
+ "rmlineto", "rm2lineto", "rm3lineto", "rrcurveto",\
+ "hvcurveto", "vhcurveto", "nrcurveto", "rncurveto",\
+ "vqcurveto", "hqcurveto", "scurveto", "closepath"
#define cmd_path_op_name_strings\
"fill", "htfill", "colorfill", "eofill",\
@@ -170,16 +175,24 @@ typedef enum {
/* ------ Exported by gxclpath.c ------ */
+/* Compute the colors used by a drawing color. */
+gx_color_index cmd_drawing_colors_used(P2(gx_device_clist_writer *cldev,
+ const gx_drawing_color *pdcolor));
+
+/*
+ * Compute whether a drawing operation will require the slow (full-pixel)
+ * RasterOp implementation. If pdcolor is not NULL, it is the texture for
+ * the RasterOp.
+ */
+bool cmd_slow_rop(P3(gx_device *dev, gs_logical_operation_t lop,
+ const gx_drawing_color *pdcolor));
+
/* Write out the color for filling, stroking, or masking. */
/* Return a cmd_dc_type. */
int cmd_put_drawing_color(P3(gx_device_clist_writer * cldev,
gx_clist_state * pcls,
const gx_drawing_color * pdcolor));
-/* Compute the colors used by a drawing color. */
-gx_color_index cmd_drawing_colors_used(P2(gx_device_clist_writer *cldev,
- const gx_drawing_color *pdcolor));
-
/* Clear (a) specific 'known' flag(s) for all bands. */
/* We must do this whenever the value of a 'known' parameter changes. */
void cmd_clear_known(P2(gx_device_clist_writer * cldev, uint known));
diff --git a/gs/src/gxclrast.c b/gs/src/gxclrast.c
index 7fe177369..1ed931b58 100644
--- a/gs/src/gxclrast.c
+++ b/gs/src/gxclrast.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,7 +36,9 @@
#include "gxcldev.h"
#include "gxclpath.h"
#include "gxcmap.h"
+#include "gxcolor2.h"
#include "gxcspace.h" /* for gs_color_space_type */
+#include "gxdhtres.h"
#include "gxgetbit.h"
#include "gxpaint.h" /* for gx_fill/stroke_params */
#include "gxhttile.h"
@@ -48,6 +50,7 @@
#include "stream.h"
#include "strimpl.h"
+extern_gx_device_halftone_list();
extern_gx_image_type_table();
/* We need color space types for constructing temporary color spaces. */
@@ -177,16 +180,21 @@ private int read_set_bits(P8(command_buf_t *pcb, tile_slot *bits,
int compress, gx_clist_state *pcls,
gx_strip_bitmap *tile, tile_slot **pslot,
gx_device_clist_reader *cdev, gs_memory_t *mem));
-private int read_set_ht_order(P4(command_buf_t *pcb, gx_device_halftone *pdht,
+private int read_set_ht_order(P4(command_buf_t *pcb,
+ gx_device_halftone **ppdht,
gx_ht_order **pporder, gs_memory_t *mem));
-private int read_set_ht_data(P8(command_buf_t *pcb, uint *pdata_index,
- gx_ht_order *porder, gx_device_halftone *pdht,
+private int read_set_ht_data(P7(command_buf_t *pcb, uint *pdata_index,
+ gx_ht_order *porder,
gs_halftone_type halftone_type,
gs_imager_state *pis,
gx_device_clist_reader *cdev,
gs_memory_t *mem));
private int read_set_misc2(P3(command_buf_t *pcb, gs_imager_state *pis,
segment_notes *pnotes));
+private int read_set_color_space(P5(command_buf_t *pcb, gs_imager_state *pis,
+ const gs_color_space **ppcs,
+ gs_color_space *pcolor_space,
+ gs_memory_t *mem));
private int read_begin_image(P3(command_buf_t *pcb, gs_image_common_t *pic,
const gs_color_space *pcs));
private int read_put_params(P4(command_buf_t *pcb, gs_imager_state *pis,
@@ -198,9 +206,12 @@ private const byte *cmd_read_matrix(P2(gs_matrix *, const byte *));
private const byte *cmd_read_short_bits(P6(command_buf_t *pcb, byte *data,
int width_bytes, int height,
uint raster, const byte *cbp));
-private int cmd_select_map(P7(cmd_map_index, bool, gs_imager_state *,
- gx_ht_order *, frac **, uint *, gs_memory_t *));
-private int cmd_resize_halftone(P3(gx_device_halftone *, uint, gs_memory_t *));
+private int cmd_select_map(P7(cmd_map_index, cmd_map_contents,
+ gs_imager_state *, gx_ht_order *, frac **,
+ uint *, gs_memory_t *));
+private int cmd_create_dev_ht(P2(gx_device_halftone **, gs_memory_t *));
+private int cmd_resize_halftone(P3(gx_device_halftone **, uint,
+ gs_memory_t *));
private int clist_decode_segment(P7(gx_path *, int, fixed[6],
gs_fixed_point *, int, int,
segment_notes));
@@ -248,7 +259,6 @@ clist_playback_band(clist_playback_action playback_action,
float dash_pattern[cmd_max_dash];
gx_fill_params fill_params;
gx_stroke_params stroke_params;
- gx_device_halftone dev_ht;
gs_halftone_type halftone_type;
gx_ht_order *porder;
uint ht_data_index;
@@ -266,6 +276,7 @@ clist_playback_band(clist_playback_action playback_action,
uint data_height;
uint data_size;
byte *data_on_heap;
+ fixed vs[6];
segment_notes notes;
int data_x;
int code = 0;
@@ -311,24 +322,18 @@ in: /* Initialize for a new page. */
if (target != 0)
(*dev_proc(target, get_clipping_box))(target, &target_box);
imager_state = clist_imager_state_initial;
- imager_state.line_params.dash.pattern = dash_pattern;
code = gs_imager_state_initialize(&imager_state, mem);
if (code < 0)
goto out;
- imager_state.halftone = 0; /* never referenced */
- memset(&dev_ht, 0, sizeof(dev_ht));
- dev_ht.order.levels = 0; /* clear pointers explicitly, just in case */
- dev_ht.order.bits = 0;
- dev_ht.order.transfer = 0;
- dev_ht.components = 0;
- imager_state.dev_ht = &dev_ht;
- imager_state.ht_cache = 0;
+ imager_state.line_params.dash.pattern = dash_pattern;
if (tdev != 0)
gx_set_cmap_procs(&imager_state, tdev);
gx_imager_setscreenphase(&imager_state, -x0, -y0, gs_color_select_all);
halftone_type = ht_type_none;
fill_params.fill_zero_width = false;
pcs = gs_cspace_DeviceGray(&imager_state);
+ color_space.params.indexed.use_proc = 0;
+ color_space.params.indexed.lookup.table.size = 0;
data_bits = gs_alloc_bytes(mem, data_bits_size,
"clist_playback_band(data_bits)");
if (data_bits == 0) {
@@ -440,17 +445,18 @@ in: /* Initialize for a new page. */
{
frac *mdata;
uint count;
+ cmd_map_contents cont =
+ (cmd_map_contents)(cb & 0x30) >> 4;
- code = cmd_select_map(cb & 0x1f,
- cb & 0x20,
+ code = cmd_select_map(cb & 0xf, cont,
&imager_state,
porder, &mdata,
&count, mem);
if (code < 0)
goto out;
- if (mdata) {
- cmd_read((byte *) mdata, count, cbp);
+ if (cont == cmd_map_other) {
+ cmd_read((byte *)mdata, count, cbp);
#ifdef DEBUG
if (gs_debug_c('L')) {
uint i;
@@ -469,20 +475,20 @@ in: /* Initialize for a new page. */
gx_imager_set_effective_xfer(
&imager_state);
break;
- case cmd_set_misc_halftone >> 6:
- halftone_type = cb & 0x3f;
- {
- uint num_comp;
+ case cmd_set_misc_halftone >> 6: {
+ uint num_comp;
- cmd_getw(num_comp, cbp);
- if_debug2('L', " halftone type=%d num_comp=%u\n",
- halftone_type, num_comp);
- code = cmd_resize_halftone(&dev_ht,
- num_comp, mem);
- if (code < 0)
- goto out;
- }
+ halftone_type = cb & 0x3f;
+ cmd_getw(num_comp, cbp);
+ if_debug2('L', " halftone type=%d num_comp=%u\n",
+ halftone_type, num_comp);
+ code = cmd_resize_halftone(
+ &imager_state.dev_ht,
+ num_comp, mem);
+ if (code < 0)
+ goto out;
break;
+ }
default:
goto bad_op;
}
@@ -500,7 +506,8 @@ in: /* Initialize for a new page. */
continue;
case cmd_opv_set_ht_order:
cbuf.ptr = cbp;
- code = read_set_ht_order(&cbuf, &dev_ht, &porder, mem);
+ code = read_set_ht_order(&cbuf, &imager_state.dev_ht,
+ &porder, mem);
cbp = cbuf.ptr;
if (code < 0)
goto out;
@@ -522,7 +529,7 @@ in: /* Initialize for a new page. */
case cmd_opv_set_ht_data:
cbuf.ptr = cbp;
code = read_set_ht_data(&cbuf, &ht_data_index, porder,
- &dev_ht, halftone_type,
+ halftone_type,
&imager_state, cdev, mem);
cbp = cbuf.ptr;
if (code < 0)
@@ -823,9 +830,10 @@ set_phase: /*
if (state_tile.size.x)
tile_phase.x =
(state.tile_phase.x + x0) % state_tile.size.x;
- if (dev_ht.lcm_width)
+ if (imager_state.dev_ht && imager_state.dev_ht->lcm_width)
color_phase.x =
- (state.tile_phase.x + x0) % dev_ht.lcm_width;
+ (state.tile_phase.x + x0) %
+ imager_state.dev_ht->lcm_width;
/*
* The true tile height for shifted tiles is not
* size.y: see gxbitmap.h for the computation.
@@ -843,9 +851,10 @@ set_phase: /*
tile_phase.y =
(state.tile_phase.y + y0) % full_height;
}
- if (dev_ht.lcm_height)
+ if (imager_state.dev_ht && imager_state.dev_ht->lcm_height)
color_phase.y =
- (state.tile_phase.y + y0) % dev_ht.lcm_height;
+ (state.tile_phase.y + y0) %
+ imager_state.dev_ht->lcm_height;
gx_imager_setscreenphase(&imager_state,
-(state.tile_phase.x + x0),
-(state.tile_phase.y + y0),
@@ -856,9 +865,9 @@ set_phase: /*
case cmd_opv_set_fill_adjust:
cmd_get_value(imager_state.fill_adjust.x, cbp);
cmd_get_value(imager_state.fill_adjust.y, cbp);
- if_debug2('L', " (%d,%d)\n",
- fixed2int(imager_state.fill_adjust.x),
- fixed2int(imager_state.fill_adjust.y));
+ if_debug2('L', " (%g,%g)\n",
+ fixed2float(imager_state.fill_adjust.x),
+ fixed2float(imager_state.fill_adjust.y));
continue;
case cmd_opv_set_ctm:
{
@@ -868,9 +877,9 @@ set_phase: /*
mat.tx -= x0;
mat.ty -= y0;
gs_imager_setmatrix(&imager_state, &mat);
- if_debug6('L', " [%d %d %d %d %d %d]\n",
- (int)mat.xx, (int)mat.xy, (int)mat.yx, (int)mat.yy,
- (int)mat.tx, (int)mat.ty);
+ if_debug6('L', " [%g %g %g %g %g %g]\n",
+ mat.xx, mat.xy, mat.yx, mat.yy,
+ mat.tx, mat.ty);
}
continue;
case cmd_opv_set_misc2:
@@ -902,12 +911,12 @@ set_phase: /*
if (gs_debug_c('L')) {
int i;
- dprintf4(" dot=%d(mode %d) adapt=%d offset=%d [",
- (int)dot_length,
+ dprintf4(" dot=%g(mode %d) adapt=%d offset=%g [",
+ dot_length,
(nb & 0x40) != 0,
- (nb & 0x80) != 0, (int)offset);
+ (nb & 0x80) != 0, offset);
for (i = 0; i < n; ++i)
- dprintf1("%d ", (int)dash_pattern[i]);
+ dprintf1("%g ", dash_pattern[i]);
dputs("]\n");
}
#endif
@@ -943,7 +952,6 @@ set_phase: /*
case cmd_opv_end_clip:
if_debug0('L', "\n");
gx_cpath_accum_end(&clip_accum, &clip_path);
- gx_cpath_set_outside(&clip_path, *cbp++);
tdev = target;
/*
* If the entire band falls within the clip
@@ -968,42 +976,14 @@ set_phase: /*
clip_save.fill_adjust;
break;
case cmd_opv_set_color_space:
- {
- byte b = *cbp++;
- int index = b >> 4;
-
- if_debug2('L', " %d%s\n", index,
- (b & 8 ? " (indexed)" : ""));
- switch (index) {
- case gs_color_space_index_DeviceGray:
- pcs = gs_cspace_DeviceGray(&imager_state);
- break;
- case gs_color_space_index_DeviceRGB:
- pcs = gs_cspace_DeviceRGB(&imager_state);
- break;
- case gs_color_space_index_DeviceCMYK:
- pcs = gs_cspace_DeviceCMYK(&imager_state);
- break;
- default:
- goto bad_op; /* others are NYI */
- }
- if (b & 8) {
-#if 0 /****************/
- int num_comp =
- gs_color_space_num_components(pcs);
-
- /****** SET map ******/
-#endif /****************/
- color_space.type =
- &gs_color_space_type_Indexed;
- color_space.params.indexed.base_space.type =
- pcs->type;
- cmd_getw(color_space.params.indexed.hival,
- cbp);
- color_space.params.indexed.use_proc =
- (b & 4) != 0;
- pcs = &color_space;
- }
+ cbuf.ptr = cbp;
+ code = read_set_color_space(&cbuf, &imager_state,
+ &pcs, &color_space, mem);
+ cbp = cbuf.ptr;
+ if (code < 0) {
+ if (code == gs_error_rangecheck)
+ goto bad_op;
+ goto out;
}
break;
case cmd_opv_begin_image_rect:
@@ -1036,6 +1016,8 @@ set_phase: /*
image_rect.p.y = 0;
image_rect.q.x = image.d.Width;
image_rect.q.y = image.d.Height;
+ if_debug2('L', " size=(%d,%d)",
+ image.d.Width, image.d.Height);
ibegin: if_debug0('L', "\n");
{
gx_drawing_color devc;
@@ -1185,33 +1167,30 @@ idata: data_size = 0;
goto out;
continue;
case cmd_opv_set_color:
- {
+ op = *cbp++;
#define dcb dev_color.colors.colored.c_base
#define dcl dev_color.colors.colored.c_level
- byte b = *cbp++;
+ dcb[0] = ((op & 0xf) << 1) + (*cbp >> 7);
+ dcb[1] = (*cbp >> 2) & 0x1f;
+ dcb[2] = ((*cbp & 3) << 3) + (cbp[1] >> 5);
+ dcb[3] = cbp[1] & 0x1f;
+ cbp += 2;
+ goto setcc;
+ case cmd_opv_set_color_short:
+ op = *cbp++;
+ dcb[0] = (op >> 3) & 1;
+ dcb[1] = (op >> 2) & 1;
+ dcb[2] = (op >> 1) & 1;
+ dcb[3] = op & 1;
+setcc: {
int i;
- switch (b >> 4) {
- case 0:
- dcb[0] = (b >> 3) & 1;
- dcb[1] = (b >> 2) & 1;
- dcb[2] = (b >> 1) & 1;
- dcb[3] = b & 1;
- break;
- case 1:
- dcb[0] = ((b & 0xf) << 1) + (*cbp >> 7);
- dcb[1] = (*cbp >> 2) & 0x1f;
- dcb[2] = ((*cbp & 3) << 3) + (cbp[1] >> 5);
- dcb[3] = cbp[1] & 0x1f;
- cbp += 2;
- break;
- default:
- goto bad_op;
- }
for (i = 0; i < imager_state.dev_ht->num_comp; ++i)
- cmd_getw(dcl[i], cbp);
- if_debug10('L', " format %d num_comp=%d base=(%u,%u,%u,%u) level=(%u,%u,%u,%u)\n",
- b >> 4,
+ if (op & (0x80 >> i))
+ cmd_getw(dcl[i], cbp);
+ else
+ dcl[i] = 0;
+ if_debug9('L', " num_comp=%d base=(%u,%u,%u,%u) level=(%u,%u,%u,%u)\n",
imager_state.dev_ht->num_comp,
dcb[0], dcb[1], dcb[2], dcb[3],
dcl[0], dcl[1], dcl[2], dcl[3]);
@@ -1224,7 +1203,7 @@ idata: data_size = 0;
case cmd_opv_put_params:
cbuf.ptr = cbp;
code = read_put_params(&cbuf, &imager_state, cdev,
- mem);
+ mem);
cbp = cbuf.ptr;
if (code > 0)
break; /* empty list */
@@ -1239,7 +1218,6 @@ idata: data_size = 0;
continue;
case cmd_op_segment >> 4:
{
- fixed vs[6];
int i, code;
static const byte op_num_operands[] = {
cmd_segment_op_num_operands_values
@@ -1263,7 +1241,7 @@ idata: data_size = 0;
vs[i++] =
((fixed) ((b ^ 0x20) - 0x20) << 13) +
((int)cbp[1] << 5) + (cbp[2] >> 3);
- if_debug1('L', " %d", fixed2int(vs[i - 1]));
+ if_debug1('L', " %g", fixed2float(vs[i - 1]));
cbp += 2;
v = (int)((*cbp & 7) ^ 4) - 4;
break;
@@ -1286,7 +1264,7 @@ idata: data_size = 0;
v = (b ^ 0xd0) - 0x10;
vs[i] =
((v << 8) + cbp[1]) << (_fixed_shift - 2);
- if_debug1('L', " %d", fixed2int(vs[i]));
+ if_debug1('L', " %g", fixed2float(vs[i]));
cbp += 2;
continue;
default /*case 7 */ :
@@ -1300,7 +1278,7 @@ idata: data_size = 0;
/* the Borland C++ 4.5 compiler incorrectly */
/* sign-extends the result of the shift. */
vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
- if_debug1('L', " %d", fixed2int(vs[i]));
+ if_debug1('L', " %g", fixed2float(vs[i]));
}
if_debug0('L', "\n");
code = clist_decode_segment(&path, op, vs, &ppos,
@@ -1540,10 +1518,9 @@ poly: code = clist_do_polyfill(tdev, &path, pdevc,
/* Clean up before we exit. */
out:gx_cpath_free(&clip_path, "clist_render_band exit");
gx_path_free(&path, "clist_render_band exit");
+ gs_imager_state_release(&imager_state);
if (imager_state.ht_cache)
gx_ht_free_cache(mem, imager_state.ht_cache);
- gx_device_halftone_release(&dev_ht, mem);
- gs_imager_state_release(&imager_state);
gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
if (code < 0)
return_error(code);
@@ -1719,16 +1696,22 @@ read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
}
private int
-read_set_ht_order(command_buf_t *pcb, gx_device_halftone *pdht,
+read_set_ht_order(command_buf_t *pcb, gx_device_halftone **ppdht,
gx_ht_order **pporder, gs_memory_t *mem)
{
const byte *cbp = pcb->ptr;
gx_ht_order *porder;
+ uint old_num_levels;
uint *levels;
- gx_ht_bit *bits;
+ uint old_num_bits;
+ void *bit_data;
int index;
gx_ht_order new_order;
+ int code = cmd_create_dev_ht(ppdht, mem);
+ gx_device_halftone *pdht = *ppdht;
+ if (code < 0)
+ return code;
cmd_getw(index, cbp);
if (index == 0)
porder = &pdht->order;
@@ -1747,18 +1730,30 @@ read_set_ht_order(command_buf_t *pcb, gx_device_halftone *pdht,
cmd_getw(new_order.shift, cbp);
cmd_getw(new_order.num_levels, cbp);
cmd_getw(new_order.num_bits, cbp);
+ new_order.procs = &ht_order_procs_table[*cbp++];
pcb->ptr = cbp;
- if_debug7('L', " index=%d size=(%d,%d) raster=%d shift=%d num_levels=%d num_bits=%d\n",
+ if_debug8('L', " index=%d size=(%d,%d) raster=%d shift=%d num_levels=%d num_bits=%d procs=%d\n",
index, new_order.width, new_order.height,
new_order.raster, new_order.shift,
- new_order.num_levels, new_order.num_bits);
- levels = porder->levels;
- bits = porder->bits;
+ new_order.num_levels, new_order.num_bits, cbp[-1]);
+ if (new_order.data_memory == 0) {
+ /* levels and bit_data point into ROM. */
+ old_num_levels = 0;
+ levels = 0;
+ old_num_bits = 0;
+ bit_data = 0;
+ } else {
+ old_num_levels = porder->num_levels;
+ levels = porder->levels;
+ old_num_bits = porder->num_bits;
+ bit_data = porder->bit_data;
+ }
+ new_order.data_memory = mem;
/*
* Note that for resizing a byte array, the element size is 1 byte,
* not the element size given to alloc_byte_array!
*/
- if (new_order.num_levels > porder->num_levels) {
+ if (new_order.num_levels > old_num_levels) {
if (levels == 0)
levels = (uint *) gs_alloc_byte_array(mem, new_order.num_levels,
sizeof(*levels),
@@ -1773,31 +1768,35 @@ read_set_ht_order(command_buf_t *pcb, gx_device_halftone *pdht,
porder->levels = levels;
porder->num_levels = new_order.num_levels;
}
- if (new_order.num_bits > porder->num_bits) {
- if (bits == 0)
- bits = (gx_ht_bit *) gs_alloc_byte_array(mem, new_order.num_bits,
- sizeof(*bits),
- "ht order(bits)");
+ if (new_order.num_bits != old_num_bits ||
+ new_order.procs != porder->procs
+ ) {
+ if (bit_data == 0)
+ bit_data = gs_alloc_byte_array(mem, new_order.num_bits,
+ new_order.procs->bit_data_elt_size,
+ "ht order(bit_data)");
else
- bits = gs_resize_object(mem, bits,
- new_order.num_bits * sizeof(*bits),
- "ht order(bits)");
- if (bits == 0)
+ bit_data = gs_resize_object(mem, bit_data,
+ new_order.num_bits *
+ new_order.procs->bit_data_elt_size,
+ "ht order(bit_data)");
+ if (bit_data == 0)
return_error(gs_error_VMerror);
}
*porder = new_order;
porder->levels = levels;
- porder->bits = bits;
+ porder->bit_data = bit_data;
porder->full_height = ht_order_full_height(porder);
return 0;
}
private int
read_set_ht_data(command_buf_t *pcb, uint *pdata_index, gx_ht_order *porder,
- gx_device_halftone *pdht, gs_halftone_type halftone_type,
- gs_imager_state *pis, gx_device_clist_reader *cdev,
- gs_memory_t *mem)
+ gs_halftone_type halftone_type, gs_imager_state *pis,
+ gx_device_clist_reader *cdev, gs_memory_t *mem)
{
+ gx_device_halftone *pdht = pis->dev_ht;
+ uint elt_size = porder->procs->bit_data_elt_size;
const byte *cbp = pcb->ptr;
int n = *cbp++;
@@ -1817,69 +1816,116 @@ read_set_ht_data(command_buf_t *pcb, uint *pdata_index, gx_ht_order *porder,
}
#endif
} else { /* Setting bits */
- byte *bptr = (byte *)
- (porder->bits + (*pdata_index - porder->num_levels));
+ byte *bptr =
+ (byte *)porder->bit_data +
+ (*pdata_index - porder->num_levels) * elt_size;
- cbp = cmd_read_data(pcb, bptr, n * sizeof(*porder->bits), cbp);
+ cbp = cmd_read_data(pcb, bptr, n * elt_size, cbp);
#ifdef DEBUG
if (gs_debug_c('L')) {
int i;
dprintf1(" bits[%u]", *pdata_index - porder->num_levels);
for (i = 0; i < n; ++i) {
- const gx_ht_bit *pb =
- &porder->bits[*pdata_index - porder->num_levels + i];
+ const byte *pb = (byte *)porder->bit_data +
+ (*pdata_index - porder->num_levels + i) * elt_size;
- dprintf2(" (%u,0x%lx)",
- pb->offset,
- (ulong) pb->mask);
+ if (porder->procs == &ht_order_procs_default) {
+ const gx_ht_bit *pbit = (const gx_ht_bit *)pb;
+
+ dprintf2(" (%u,0x%lx)", pbit->offset, (ulong)pbit->mask);
+ } else {
+ debug_dump_bytes(pb, pb + elt_size, NULL);
+ }
}
dputc('\n');
}
#endif
}
*pdata_index += n;
- /* If this is the end of the data, */
- /* install the (device) halftone. */
- if (porder ==
- (pdht->components != 0 ?
- &pdht->components[0].corder :
- &pdht->order) &&
- *pdata_index == porder->num_levels + porder->num_bits
- ) { /* Make sure we have a halftone cache. */
- uint i;
-
- if (pis->ht_cache == 0) {
- gx_ht_cache *pcache =
- gx_ht_alloc_cache(mem,
- porder->num_levels + 2,
- gx_ht_cache_default_bits());
-
- if (pcache == 0)
- return_error(gs_error_VMerror);
- pis->ht_cache = pcache;
+ /*
+ * If this is the end of a component, check whether a copy of its data
+ * exists in ROM.
+ */
+ if (*pdata_index == porder->num_levels + porder->num_bits) {
+ const gx_dht_proc *phtrp = gx_device_halftone_list;
+
+ for (; *phtrp; ++phtrp) {
+ const gx_device_halftone_resource_t *phtr = (*phtrp)();
+
+ if (phtr->Width == porder->width &&
+ phtr->Height == porder->height &&
+ phtr->num_levels == porder->num_levels &&
+ !memcmp(phtr->levels, porder->levels,
+ phtr->num_levels * sizeof(*phtr->levels)) &&
+ !memcmp(phtr->bit_data, porder->bit_data,
+ phtr->Width * phtr->Height * elt_size)
+ ) {
+ /*
+ * This is a predefined halftone. Free the levels and
+ * bit_data arrays, replacing them with the built-in ones.
+ */
+ if (porder->data_memory) {
+ gs_free_object(porder->data_memory, porder->bit_data,
+ "construct_ht_order_short(bit_data)");
+ gs_free_object(porder->data_memory, porder->levels,
+ "construct_ht_order_short(levels)");
+ }
+ porder->data_memory = 0;
+ porder->levels = (uint *)phtr->levels; /* actually const */
+ porder->bit_data = (void *)phtr->bit_data; /* actually const */
+ }
}
- for (i = 1; i < pdht->num_comp; ++i) {
- gx_ht_order *pco = &pdht->components[i].corder;
+ /*
+ * If this is the end of the data, install the (device) halftone.
+ */
+ if (porder ==
+ (pdht->components != 0 ?
+ &pdht->components[0].corder :
+ &pdht->order)) {
+ /* Make sure we have a halftone cache. */
+ uint i;
- if (!pco->cache) {
+ if (pis->ht_cache == 0) {
gx_ht_cache *pcache =
- gx_ht_alloc_cache(mem, 4,
- pco->raster *
- (pco->num_bits / pco->width) * 4);
+ gx_ht_alloc_cache(mem,
+ porder->num_levels + 2,
+ gx_ht_cache_default_bits());
if (pcache == 0)
return_error(gs_error_VMerror);
- pco->cache = pcache;
- gx_ht_init_cache(pco->cache, pco);
+ pis->ht_cache = pcache;
}
+ for (i = 1; i < pdht->num_comp; ++i) {
+ gx_ht_order *pco = &pdht->components[i].corder;
+
+ if (!pco->cache) {
+ gx_ht_cache *pcache =
+ gx_ht_alloc_cache(mem, 4,
+ pco->raster *
+ (pco->num_bits / pco->width) * 4);
+
+ if (pcache == 0)
+ return_error(gs_error_VMerror);
+ pco->cache = pcache;
+ gx_ht_init_cache(pco->cache, pco);
+ }
+ }
+ if (pdht->num_comp) {
+ pdht->components[0].corder.cache = pis->ht_cache;
+ pdht->order = pdht->components[0].corder;
+ }
+ /*
+ * Normally, the following procedure releases the existing
+ * device halftone and assumes ownership of everything in the
+ * new one except the top-level structure. However, there is a
+ * special check for the case where pdht == pis->dev_ht, solely
+ * so that we can avoid the sleazy things we would otherwise
+ * have to do here.
+ */
+ gx_imager_dev_ht_install(pis, pdht, halftone_type,
+ (const gx_device *)cdev);
}
- if (pdht->num_comp) {
- pdht->components[0].corder.cache = pis->ht_cache;
- pdht->order = pdht->components[0].corder;
- }
- gx_imager_dev_ht_install(pis, pdht, halftone_type,
- (const gx_device *)cdev);
}
pcb->ptr = cbp;
return 0;
@@ -1918,14 +1964,14 @@ read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, segment_notes *pnotes)
case cmd_set_misc2_flatness:
cmd_get_value(pis->flatness, cbp);
- if_debug1('L', " %d\n", (int)(pis->flatness));
+ if_debug1('L', " %g\n", pis->flatness);
break;
case cmd_set_misc2_line_width: {
float width;
cmd_get_value(width, cbp);
- if_debug1('L', " %d\n", (int)width);
+ if_debug1('L', " %g\n", width);
gx_set_line_width(&pis->line_params, width);
}
break;
@@ -1934,7 +1980,7 @@ read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, segment_notes *pnotes)
float limit;
cmd_get_value(limit, cbp);
- if_debug1('L', " %d\n", (int)limit);
+ if_debug1('L', " %g\n", limit);
gx_set_miter_limit(&pis->line_params, limit);
}
break;
@@ -1957,6 +2003,110 @@ read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, segment_notes *pnotes)
}
private int
+read_set_color_space(command_buf_t *pcb, gs_imager_state *pis,
+ const gs_color_space **ppcs, gs_color_space *pcolor_space,
+ gs_memory_t *mem)
+{
+ const byte *cbp = pcb->ptr;
+ byte b = *cbp++;
+ int index = b >> 4;
+ const gs_color_space *pcs;
+ int code = 0;
+
+ if_debug3('L', " %d%s%s\n", index,
+ (b & 8 ? " (indexed)" : ""),
+ (b & 4 ? "(proc)" : ""));
+ switch (index) {
+ case gs_color_space_index_DeviceGray:
+ pcs = gs_cspace_DeviceGray(pis);
+ break;
+ case gs_color_space_index_DeviceRGB:
+ pcs = gs_cspace_DeviceRGB(pis);
+ break;
+ case gs_color_space_index_DeviceCMYK:
+ pcs = gs_cspace_DeviceCMYK(pis);
+ break;
+ default:
+ code = gs_note_error(gs_error_rangecheck); /* others are NYI */
+ goto out;
+ }
+ /* Free any old indexed color space data. */
+ if (pcolor_space->params.indexed.use_proc) {
+ if (pcolor_space->params.indexed.lookup.map)
+ gs_free_object(mem,
+ pcolor_space->params.indexed.lookup.map->values,
+ "old indexed map values");
+ gs_free_object(mem, pcolor_space->params.indexed.lookup.map,
+ "old indexed map");
+ pcolor_space->params.indexed.lookup.map = 0;
+ } else {
+ if (pcolor_space->params.indexed.lookup.table.size)
+ gs_free_const_string(mem,
+ pcolor_space->params.indexed.lookup.table.data,
+ pcolor_space->params.indexed.lookup.table.size,
+ "old indexed table");
+ pcolor_space->params.indexed.lookup.table.size = 0;
+ }
+ if (b & 8) {
+ bool use_proc = (b & 4) != 0;
+ int hival;
+ int num_values;
+ byte *data;
+ uint data_size;
+
+ cmd_getw(hival, cbp);
+ num_values = (hival + 1) * gs_color_space_num_components(pcs);
+ if (use_proc) {
+ void *map_values =
+ gs_alloc_byte_array(mem, num_values,
+ sizeof(pcolor_space->params.indexed.lookup.map->values[0]),
+ "indexed map values");
+ gs_indexed_map *map =
+ gs_alloc_struct(mem, gs_indexed_map, &st_indexed_map,
+ "indexed map");
+
+ if (map_values == 0 || map == 0) {
+ gs_free_object(mem, map, "indexed map");
+ gs_free_object(mem, map_values, "indexed map values");
+ code = gs_note_error(gs_error_VMerror);
+ goto out;
+ }
+ rc_init(map, mem, 1);
+ map->proc.lookup_index = lookup_indexed_map;
+ map->num_values = num_values; /* (maybe not needed) */
+ map->values = map_values;
+ pcolor_space->params.indexed.lookup.map = map;
+ data = (byte *)map_values;
+ data_size = num_values *
+ sizeof(pcolor_space->params.indexed.lookup.map->values[0]);
+ } else {
+ byte *table = gs_alloc_string(mem, num_values, "indexed table");
+
+ if (table == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ goto out;
+ }
+ pcolor_space->params.indexed.lookup.table.data = table;
+ pcolor_space->params.indexed.lookup.table.size = num_values;
+ data = table;
+ data_size = num_values;
+ }
+ cbp = cmd_read_data(pcb, data, data_size, cbp);
+ pcolor_space->type =
+ &gs_color_space_type_Indexed;
+ memmove(&pcolor_space->params.indexed.base_space, pcs,
+ sizeof(pcolor_space->params.indexed.base_space));
+ pcolor_space->params.indexed.hival = hival;
+ pcolor_space->params.indexed.use_proc = use_proc;
+ pcs = pcolor_space;
+ }
+ *ppcs = pcs;
+out:
+ pcb->ptr = cbp;
+ return code;
+}
+
+private int
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
const gs_color_space *pcs)
{
@@ -2110,10 +2260,10 @@ cmd_read_matrix(gs_matrix * pmat, const byte * cbp)
}
/* Select a map for loading with data. */
-/* load = false is not possible for cmd_map_transfer*. */
private int
-cmd_select_map(cmd_map_index map_index, bool load, gs_imager_state * pis,
- gx_ht_order * porder, frac ** pmdata, uint * pcount, gs_memory_t * mem)
+cmd_select_map(cmd_map_index map_index, cmd_map_contents cont,
+ gs_imager_state * pis, gx_ht_order * porder, frac ** pmdata,
+ uint * pcount, gs_memory_t * mem)
{
gx_transfer_map *map;
gx_transfer_map **pmap;
@@ -2128,7 +2278,7 @@ cmd_select_map(cmd_map_index map_index, bool load, gs_imager_state * pis,
pis->effective_transfer.indexed[2] =
pis->effective_transfer.indexed[3] =
map;
- break;
+ goto transfer;
case cmd_map_transfer_0:
case cmd_map_transfer_1:
case cmd_map_transfer_2:
@@ -2144,6 +2294,12 @@ cmd_select_map(cmd_map_index map_index, bool load, gs_imager_state * pis,
map = pis->set_transfer.indexed[i];
pis->effective_transfer.indexed[i] = map;
}
+transfer: if (cont != cmd_map_other) {
+ map->proc = gs_identity_transfer;
+ *pmdata = 0;
+ *pcount = 0;
+ return 0;
+ }
break;
case cmd_map_ht_transfer:
if_debug0('L', " ht transfer");
@@ -2162,7 +2318,7 @@ cmd_select_map(cmd_map_index map_index, bool load, gs_imager_state * pis,
if_debug0('L', " undercolor removal");
pmap = &pis->undercolor_removal;
cname = "cmd_select_map(undercolor removal)";
-alloc: if (!load) {
+alloc: if (cont == cmd_map_none) {
rc_decrement(*pmap, cname);
*pmap = 0;
*pmdata = 0;
@@ -2172,6 +2328,12 @@ alloc: if (!load) {
rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
mem, return_error(gs_error_VMerror), cname);
map = *pmap;
+ if (cont == cmd_map_identity) {
+ map->proc = gs_identity_transfer;
+ *pmdata = 0;
+ *pcount = 0;
+ return 0;
+ }
break;
default:
*pmdata = 0;
@@ -2183,11 +2345,36 @@ alloc: if (!load) {
return 0;
}
+/* Create a device halftone for the imager if necessary. */
+private int
+cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
+{
+ gx_device_halftone *pdht = *ppdht;
+
+ if (pdht == 0) {
+ rc_header rc;
+
+ rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
+ return_error(gs_error_VMerror),
+ "cmd_create_dev_ht");
+ rc = pdht->rc;
+ memset(pdht, 0, sizeof(*pdht));
+ pdht->rc = rc;
+ *ppdht = pdht;
+ }
+ return 0;
+}
+
/* Resize the halftone components array if necessary. */
private int
-cmd_resize_halftone(gx_device_halftone * pdht, uint num_comp,
+cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
gs_memory_t * mem)
{
+ int code = cmd_create_dev_ht(ppdht, mem);
+ gx_device_halftone *pdht = *ppdht;
+
+ if (code < 0)
+ return code;
if (num_comp != pdht->num_comp) {
gx_ht_order_component *pcomp;
@@ -2200,7 +2387,7 @@ cmd_resize_halftone(gx_device_halftone * pdht, uint num_comp,
/* Don't release the default order. */
for (i = pdht->num_comp; i-- > num_comp;)
- if (pdht->components[i].corder.bits != pdht->order.bits)
+ if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
gx_ht_order_release(&pdht->components[i].corder, mem, true);
if (num_comp == 0) {
gs_free_object(mem, pdht->components, "cmd_resize_halftone");
@@ -2265,8 +2452,31 @@ clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
case cmd_opv_vlineto:
code = gx_path_add_line_notes(ppath, px, py += A, notes);
break;
+ case cmd_opv_rmlineto:
+ if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
+ break;
+ code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
+ break;
+ case cmd_opv_rm2lineto:
+ if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
+ (code = gx_path_add_line_notes(ppath, px += C, py += D,
+ notes)) < 0
+ )
+ break;
+ code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
+ break;
+ case cmd_opv_rm3lineto:
+ if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
+ (code = gx_path_add_line_notes(ppath, px += C, py += D,
+ notes)) < 0 ||
+ (code = gx_path_add_line_notes(ppath, px += E, py += F,
+ notes)) < 0
+ )
+ break;
+ code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
+ break;
case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
- E += (C += A);
+rrc: E += (C += A);
F += (D += B);
curve: code = gx_path_add_curve_notes(ppath, px + A, py + B,
px + C, py + D,
@@ -2285,19 +2495,6 @@ vhc: E = B + D, F = D = A + C, C = B, B = A, A = 0;
case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
F = D += B, E = C += A;
goto curve;
- case cmd_opv_rmlineto:
- if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
- break;
- code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
- break;
- case cmd_opv_rm2lineto:
- if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
- (code = gx_path_add_line_notes(ppath, px += C, py += D,
- notes)) < 0
- )
- break;
- code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
- break;
case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
if ((A ^ B) < 0)
C = -B, D = -A;
@@ -2310,16 +2507,20 @@ vhc: E = B + D, F = D = A + C, C = B, B = A, A = 0;
else
D = A, C = B;
goto hvc;
- case cmd_opv_rm3lineto:
- if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
- (code = gx_path_add_line_notes(ppath, px += C, py += D,
- notes)) < 0 ||
- (code = gx_path_add_line_notes(ppath, px += E, py += F,
- notes)) < 0
- )
- break;
- code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
- break;
+ case cmd_opv_scurveto: /* (a b c d e f) => */
+ {
+ fixed a = A, b = B;
+
+ /* See gxclpath.h for details on the following. */
+ if (A == 0) {
+ /* Previous curve was vh */
+ A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
+ } else {
+ /* Previous curve was hv */
+ A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
+ }
+ }
+ goto rrc;
case cmd_opv_closepath:
code = gx_path_close_subpath(ppath);
gx_path_current_point(ppath, (gs_fixed_point *) vs);
diff --git a/gs/src/gxclread.c b/gs/src/gxclread.c
index 97712605f..3eeaddc88 100644
--- a/gs/src/gxclread.c
+++ b/gs/src/gxclread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,6 +31,14 @@
#include "gxgetbit.h"
#include "gxhttile.h"
#include "gdevht.h"
+#include "gdevplnx.h"
+/*
+ * We really don't like the fact that gdevprn.h is included here, since
+ * command lists are supposed to be usable for purposes other than printer
+ * devices; but gdev_prn_colors_used and gdev_create_buf_device are
+ * currently only applicable to printer devices.
+ */
+#include "gdevprn.h"
#include "stream.h"
#include "strimpl.h"
@@ -40,13 +48,13 @@
* To separate banding per se from command list interpretation,
* we make the command list interpreter simply read from a stream.
* When we are actually doing banding, the stream filters the band file
- * and only passes through the commands for the current band (or band
- * ranges that include the current band).
+ * and only passes through the commands for the current bands (or band
+ * ranges that include a current band).
*/
typedef struct stream_band_read_state_s {
stream_state_common;
gx_band_page_info_t page_info;
- int band;
+ int band_first, band_last;
uint left; /* amount of data left in this run */
cmd_block b_this;
} stream_band_read_state;
@@ -91,8 +99,11 @@ s_band_read_process(stream_state * st, stream_cursor_read * ignore_pr,
process_interrupts();
continue;
}
- rb: /* Scan for the next run for this band (or a band range */
- /* that includes the current band). */
+rb:
+ /*
+ * Scan for the next run for the current bands (or a band range
+ * that includes a current band).
+ */
if (ss->b_this.band_min == cmd_band_end &&
clist_ftell(bfile) == ss->page_bfile_end_pos
) {
@@ -104,7 +115,7 @@ s_band_read_process(stream_state * st, stream_cursor_read * ignore_pr,
long pos = ss->b_this.pos;
clist_fread_chars(&ss->b_this, sizeof(ss->b_this), bfile);
- if (!(ss->band >= bmin && ss->band <= bmax))
+ if (!(ss->band_last >= bmin && ss->band_first <= bmax))
goto rb;
clist_fseek(cfile, pos, SEEK_SET, ss->page_cfname);
left = (uint) (ss->b_this.pos - pos);
@@ -120,7 +131,7 @@ s_band_read_process(stream_state * st, stream_cursor_read * ignore_pr,
}
/* Stream template */
-const stream_template s_band_read_template = {
+private const stream_template s_band_read_template = {
&st_stream_state, s_band_read_init, s_band_read_process, 1, cbuf_size
};
@@ -130,15 +141,45 @@ const stream_template s_band_read_template = {
/* Forward references */
private int clist_render_init(P1(gx_device_clist *));
-private int clist_playback_file_band(P7(clist_playback_action action,
- gx_device_clist_reader *cdev,
- gx_band_page_info_t *page_info,
- gx_device *target,
- int band, int x0, int y0));
+private int clist_playback_file_bands(P8(clist_playback_action action,
+ gx_device_clist_reader *cdev,
+ gx_band_page_info_t *page_info,
+ gx_device *target,
+ int band_first, int band_last,
+ int x0, int y0));
private int clist_rasterize_lines(P6(gx_device *dev, int y, int lineCount,
- byte *data_in, gx_device_memory *mdev,
+ gx_device *bdev,
+ const gx_render_plane_t *render_plane,
int *pmy));
+/* Calculate the raster for a chunky or planar device. */
+private int
+clist_plane_raster(const gx_device *dev, const gx_render_plane_t *render_plane)
+{
+ return bitmap_raster(dev->width *
+ (render_plane && render_plane->index >= 0 ?
+ render_plane->depth : dev->color_info.depth));
+}
+
+/* Select full-pixel rendering if required for RasterOp. */
+private void
+clist_select_render_plane(gx_device *dev, int y, int height,
+ gx_render_plane_t *render_plane, int index)
+{
+ if (index >= 0) {
+ gx_colors_used_t colors_used;
+ int ignore_start;
+
+ gdev_prn_colors_used(dev, y, height, &colors_used, &ignore_start);
+ if (colors_used.slow_rop)
+ index = -1;
+ }
+ if (index < 0)
+ render_plane->index = index;
+ else
+ gx_render_plane_init(render_plane, dev, index);
+}
+
/*
* Do device setup from params stored in command list. This is only for
* async rendering & assumes that the first command in every command list
@@ -151,11 +192,11 @@ clist_setup_params(gx_device *dev)
gx_device_clist_reader * const crdev =
&((gx_device_clist *)dev)->reader;
int code = clist_render_init((gx_device_clist *)dev);
- if ( code < 0 )
+ if (code < 0)
return code;
- code = clist_playback_file_band(playback_action_setup,
- crdev, &crdev->page_info, 0, 0, 0, 0);
+ code = clist_playback_file_bands(playback_action_setup,
+ crdev, &crdev->page_info, 0, 0, 0, 0, 0);
/* put_params may have reinitialized device into a writer */
clist_render_init((gx_device_clist *)dev);
@@ -163,83 +204,26 @@ clist_setup_params(gx_device *dev)
return code;
}
-/* Find out where the band buffer for a given line is going to fall on the */
-/* next call to get_bits. */
-/****** THIS IS WRONG: IT DUPLICATES CODE INSIDE make_buffer_device
- ****** AND ASSUMES THAT make_buffer_device JUST SETS UP A MEMORY DEVICE.
- ******/
-int /* rets # lines from y till end of buffer, or -ve error code */
-clist_locate_overlay_buffer(gx_device_printer *pdev, int y, byte **data)
-{
- gx_device_clist_reader * const crdev =
- &((gx_device_clist *)pdev)->reader;
- gx_device * const dev = (gx_device *)pdev;
- gx_device *target = crdev->target;
-
- uint raster = gdev_mem_raster(target);
- byte *mdata = crdev->data + crdev->page_tile_cache_size;
- int band_height = crdev->page_band_height;
- int band = y / band_height;
- int band_begin_line = band * band_height;
- int bytes_from_band_begin_to_line = (y - band_begin_line) * raster;
- int band_end_line = band_begin_line + band_height;
-
- if (band_end_line > dev->height)
- band_end_line = dev->height;
-
- /* Make sure device will rasterize on next get_bits or get_overlay_bits */
- if ( crdev->ymin >= 0 )
- crdev->ymin = crdev->ymax = 0;
-
- *data = mdata + bytes_from_band_begin_to_line;
- return band_end_line - y; /* # lines remaining in this band */
-}
-
-/* Do more rendering to a client-supplied memory image, return results */
-int
-clist_get_overlay_bits(gx_device_printer *pdev, int y, int line_count,
- byte *data)
-{
- gx_device_clist_reader * const crdev =
- &((gx_device_clist *)pdev)->reader;
- byte *data_orig = data;
- gx_device * const dev = (gx_device *)pdev;
- gx_device *target = crdev->target;
- uint raster = gdev_mem_raster(target);
- int lines_left = line_count;
-
- /* May have to render more than once to cover requested line range */
- while (lines_left > 0) {
- gx_device_memory mdev;
- int my;
- byte *data_transformed;
- int line_count_rasterized =
- clist_rasterize_lines(dev, y, lines_left, data_orig, &mdev, &my);
- uint byte_count_rasterized = raster * line_count_rasterized;
-
- if (line_count_rasterized < 0)
- return line_count_rasterized;
- data_transformed = mdev.base + raster * my;
- if (data_orig != data_transformed)
- memcpy(data_orig, data_transformed, byte_count_rasterized);
- data_orig += byte_count_rasterized;
- lines_left -= line_count_rasterized;
- }
- return 0;
-}
-
/* Copy a rasterized rectangle to the client, rasterizing if needed. */
int
clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect,
gs_get_bits_params_t *params, gs_int_rect **unread)
{
+ gx_device_clist_common *cdev = (gx_device_clist_common *)dev;
gs_get_bits_options_t options = params->options;
int y = prect->p.y;
int end_y = prect->q.y;
int line_count = end_y - y;
gs_int_rect band_rect;
int lines_rasterized;
- gx_device_memory mdev;
+ gx_device *bdev;
+ int num_planes =
+ (options & GB_PACKING_CHUNKY ? 1 :
+ options & GB_PACKING_PLANAR ? dev->color_info.num_components :
+ options & GB_PACKING_BIT_PLANAR ? dev->color_info.depth :
+ 0 /****** NOT POSSIBLE ******/);
+ gx_render_plane_t render_plane;
+ int plane_index;
int my;
int code;
@@ -249,7 +233,31 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect,
return_error(gs_error_rangecheck);
if (line_count <= 0 || prect->p.x >= prect->q.x)
return 0;
- code = clist_rasterize_lines(dev, y, line_count, NULL, &mdev, &my);
+
+ /*
+ * Calculate the render_plane from the params. There are two cases:
+ * full pixels, or a single plane.
+ */
+ plane_index = -1;
+ if (options & GB_SELECT_PLANES) {
+ /* Look for the one selected plane. */
+ int i;
+
+ for (i = 0; i < num_planes; ++i)
+ if (params->data[i]) {
+ if (plane_index >= 0) /* >1 plane requested */
+ return gx_default_get_bits_rectangle(dev, prect, params,
+ unread);
+ plane_index = i;
+ }
+ }
+ clist_select_render_plane(dev, y, line_count, &render_plane, plane_index);
+ code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
+ &bdev, cdev->target, &render_plane,
+ dev->memory, true);
+ if (code < 0)
+ return code;
+ code = clist_rasterize_lines(dev, y, line_count, bdev, &render_plane, &my);
if (code < 0)
return code;
lines_rasterized = min(code, line_count);
@@ -257,8 +265,9 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect,
band_rect = *prect;
band_rect.p.y = my;
band_rect.q.y = my + lines_rasterized;
- code = (*dev_proc(&mdev, get_bits_rectangle))
- ((gx_device *)&mdev, &band_rect, params, unread);
+ code = dev_proc(bdev, get_bits_rectangle)
+ (bdev, &band_rect, params, unread);
+ cdev->buf_procs.destroy_buf_device(bdev);
if (code < 0 || lines_rasterized == line_count)
return code;
/*
@@ -279,196 +288,205 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect,
}
{
gs_get_bits_params_t band_params;
- int num_planes =
- (options & GB_PACKING_CHUNKY ? 1 :
- options & GB_PACKING_PLANAR ? mdev.color_info.num_components :
- options & GB_PACKING_BIT_PLANAR ? mdev.color_info.depth :
- 0 /****** NOT POSSIBLE ******/);
- uint raster = gdev_mem_raster(&mdev);
+ uint raster = gx_device_raster(bdev, true);
+ code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
+ &bdev, cdev->target, &render_plane,
+ dev->memory, true);
+ if (code < 0)
+ return code;
band_params = *params;
while ((y += lines_rasterized) < end_y) {
int i;
/* Increment data pointers by lines_rasterized. */
for (i = 0; i < num_planes; ++i)
- band_params.data[i] += raster * lines_rasterized;
+ if (band_params.data[i])
+ band_params.data[i] += raster * lines_rasterized;
line_count = end_y - y;
- code = clist_rasterize_lines(dev, y, line_count, NULL, &mdev, &my);
+ code = clist_rasterize_lines(dev, y, line_count, bdev,
+ &render_plane, &my);
if (code < 0)
- return code;
+ break;
lines_rasterized = min(code, line_count);
band_rect.p.y = my;
band_rect.q.y = my + lines_rasterized;
- code = (*dev_proc(&mdev, get_bits_rectangle))
- ((gx_device *)&mdev, &band_rect, &band_params, unread);
+ code = dev_proc(bdev, get_bits_rectangle)
+ (bdev, &band_rect, &band_params, unread);
if (code < 0)
- return code;
+ break;
params->options = options = band_params.options;
if (lines_rasterized == line_count)
- return code;
+ break;
}
+ cdev->buf_procs.destroy_buf_device(bdev);
}
- return 0;
+ return code;
}
/* Copy scan lines to the client. This is where rendering gets done. */
/* Processes min(requested # lines, # lines available thru end of band) */
private int /* returns -ve error code, or # scan lines copied */
-clist_rasterize_lines(gx_device *dev, int y, int line_count, byte *data_in,
- gx_device_memory *mdev, int *pmy)
+clist_rasterize_lines(gx_device *dev, int y, int line_count,
+ gx_device *bdev, const gx_render_plane_t *render_plane,
+ int *pmy)
{
- gx_device_clist_reader * const crdev =
- &((gx_device_clist *)dev)->reader;
+ gx_device_clist * const cdev = (gx_device_clist *)dev;
+ gx_device_clist_reader * const crdev = &cdev->reader;
gx_device *target = crdev->target;
- uint raster = gx_device_raster(target, true);
+ uint raster = clist_plane_raster(target, render_plane);
byte *mdata = crdev->data + crdev->page_tile_cache_size;
- gx_device *tdev = (gx_device *)mdev;
+ int plane_index = (render_plane ? render_plane->index : -1);
int code;
- /* Initialize for rendering if we haven't done so yet. */
- if (crdev->ymin < 0) {
- code = clist_end_page(&((gx_device_clist *)crdev)->writer);
- if ( code < 0 )
- return code;
- code = clist_render_init((gx_device_clist *)dev);
- if ( code < 0 )
- return code;
-#if 0 /* **************** */
- gx_device_ht hdev;
-
- code = clist_render_init((gx_device_clist *) dev, &hdev);
- if (code < 0)
- return code;
- if (code != 0) {
- hdev.target = tdev;
- tdev = (gx_device *) & hdev;
- }
-#endif /* **************** */
- }
-
/* Render a band if necessary, and copy it incrementally. */
- code = (*crdev->make_buffer_device)(mdev, target, crdev->memory, true);
- if (code < 0)
- return code;
- mdev->width = target->width;
- mdev->raster = raster;
- if (data_in || !(y >= crdev->ymin && y < crdev->ymax)) {
- const gx_placed_page *ppages = crdev->pages;
- int num_pages = crdev->num_pages;
- gx_saved_page current_page;
- gx_placed_page placed_page;
+ if (crdev->ymin < 0 || crdev->yplane.index != plane_index ||
+ !(y >= crdev->ymin && y < crdev->ymax)
+ ) {
int band_height = crdev->page_band_height;
int band = y / band_height;
int band_begin_line = band * band_height;
int band_end_line = band_begin_line + band_height;
- int i;
+ int band_num_lines;
+ gs_int_rect band_rect;
if (band_end_line > dev->height)
band_end_line = dev->height;
/* Clip line_count to current band */
if (line_count > band_end_line - y)
line_count = band_end_line - y;
+ band_num_lines = band_end_line - band_begin_line;
if (y < 0 || y > dev->height)
return_error(gs_error_rangecheck);
- /****** QUESTIONABLE, BUT BETTER THAN OMITTING ******/
- mdev->color_info = dev->color_info;
- mdev->base = mdata;
- /*
- * The matrix in the memory device is irrelevant,
- * because all we do with the device is call the device-level
- * output procedures, but we may as well set it to
- * something halfway reasonable.
- */
- gs_deviceinitialmatrix(target, &mdev->initial_matrix);
- mdev->height = band_height;
- (*dev_proc(mdev, open_device))((gx_device *)mdev);
- if_debug1('l', "[l]rendering band %d\n", band);
- /*
- * Unfortunately, there is currently no way to get a mem
- * device to rasterize into a given memory space, since
- * a mem device's memory space must also contain internal
- * structures.
- */
- if (data_in)
- memcpy(mdev->base + (y - band_begin_line) * raster,
- data_in, line_count * raster);
- /*
- * If we aren't rendering saved pages, do the current one.
- * Note that this is the only case in which we may encounter
- * a gx_saved_page with non-zero cfile or bfile.
- */
- if (ppages == 0) {
- current_page.info = crdev->page_info;
- placed_page.page = &current_page;
- placed_page.offset.x = placed_page.offset.y = 0;
- ppages = &placed_page;
- num_pages = 1;
- }
- for (i = 0; i < num_pages; ++i) {
- const gx_placed_page *ppage = &ppages[i];
-
- code = clist_playback_file_band(playback_action_render,
- crdev, &ppage->page->info, tdev,
- band, -ppage->offset.x,
- band * mdev->height);
- if ( code < 0 )
- break;
- }
+ code = crdev->buf_procs.setup_buf_device
+ (bdev, mdata, raster, NULL, 0, band_num_lines, band_num_lines);
+ band_rect.p.x = 0;
+ band_rect.p.y = band_begin_line;
+ band_rect.q.x = dev->width;
+ band_rect.q.y = band_end_line;
+ if (code >= 0)
+ code = clist_render_rectangle(cdev, &band_rect, bdev, render_plane,
+ true);
/* Reset the band boundaries now, so that we don't get */
/* an infinite loop. */
crdev->ymin = band_begin_line;
crdev->ymax = band_end_line;
if (code < 0)
return code;
- *pmy = y - crdev->ymin;
- } else {
- /* Just fill in enough of the memory device to access the
- * already-rasterized scan lines; in particular, only set up scan
- * line pointers for the requested Y range.
- */
- mdev->base = mdata + (y - crdev->ymin) * raster;
- mdev->height = crdev->ymax - y;
- gdev_mem_open_scan_lines(mdev, min(line_count, mdev->height));
- *pmy = 0;
}
- return (line_count > crdev->ymax - y ? crdev->ymax - y : line_count);
+
+ if (line_count > crdev->ymax - y)
+ line_count = crdev->ymax - y;
+ code = crdev->buf_procs.setup_buf_device
+ (bdev, mdata, raster, NULL, y - crdev->ymin, line_count,
+ crdev->ymax - crdev->ymin);
+ if (code < 0)
+ return code;
+
+ *pmy = 0;
+ return line_count;
}
/* Initialize for reading. */
private int
-clist_render_init(gx_device_clist *dev /******, gx_device_ht *hdev ******/)
+clist_render_init(gx_device_clist *dev)
{
gx_device_clist_reader * const crdev = &dev->reader;
crdev->ymin = crdev->ymax = 0;
+ crdev->yplane.index = -1;
/* For normal rasterizing, pages and num_pages are zero. */
crdev->pages = 0;
crdev->num_pages = 0;
return 0;
}
+/*
+ * Render a rectangle to a client-supplied device. There is no necessary
+ * relationship between band boundaries and the region being rendered.
+ */
+int
+clist_render_rectangle(gx_device_clist *cdev, const gs_int_rect *prect,
+ gx_device *bdev,
+ const gx_render_plane_t *render_plane, bool clear)
+{
+ gx_device_clist_reader * const crdev = &cdev->reader;
+ const gx_placed_page *ppages;
+ int num_pages = crdev->num_pages;
+ int band_height = crdev->page_band_height;
+ int band_first = prect->p.y / band_height;
+ int band_last = (prect->q.y - 1) / band_height;
+ gx_saved_page current_page;
+ gx_placed_page placed_page;
+ int code = 0;
+ int i;
+
+ /* Initialize for rendering if we haven't done so yet. */
+ if (crdev->ymin < 0) {
+ code = clist_end_page(&cdev->writer);
+ if (code < 0)
+ return code;
+ code = clist_render_init(cdev);
+ if (code < 0)
+ return code;
+ }
+ if (render_plane)
+ crdev->yplane = *render_plane;
+ else
+ crdev->yplane.index = -1;
+ if_debug2('l', "[l]rendering bands (%d,%d)\n", band_first, band_last);
+ if (clear)
+ dev_proc(bdev, fill_rectangle)
+ (bdev, 0, 0, bdev->width, bdev->height, gx_device_white(bdev));
+
+ /*
+ * If we aren't rendering saved pages, do the current one.
+ * Note that this is the only case in which we may encounter
+ * a gx_saved_page with non-zero cfile or bfile.
+ */
+ ppages = crdev->pages;
+ if (ppages == 0) {
+ current_page.info = crdev->page_info;
+ placed_page.page = &current_page;
+ placed_page.offset.x = placed_page.offset.y = 0;
+ ppages = &placed_page;
+ num_pages = 1;
+ }
+ for (i = 0; i < num_pages && code >= 0; ++i) {
+ const gx_placed_page *ppage = &ppages[i];
+
+ code = clist_playback_file_bands(playback_action_render,
+ crdev, &ppage->page->info,
+ bdev, band_first, band_last,
+ prect->p.x - ppage->offset.x,
+ prect->p.y);
+ }
+ return code;
+}
+
/* Playback the band file, taking the indicated action w/ its contents. */
private int
-clist_playback_file_band(clist_playback_action action,
- gx_device_clist_reader *cdev,
- gx_band_page_info_t *page_info, gx_device *target,
- int band, int x0, int y0)
+clist_playback_file_bands(clist_playback_action action,
+ gx_device_clist_reader *cdev,
+ gx_band_page_info_t *page_info, gx_device *target,
+ int band_first, int band_last, int x0, int y0)
{
int code = 0;
- int opened_bfile = 0;
- int opened_cfile = 0;
+ bool opened_bfile = false;
+ bool opened_cfile = false;
/* We have to pick some allocator for rendering.... */
gs_memory_t *mem =
(cdev->memory != 0 ? cdev->memory : &gs_memory_default);
- /* setup stream */
stream_band_read_state rs;
+
+ /* setup stream */
rs.template = &s_band_read_template;
rs.memory = 0;
- rs.band = band;
+ rs.band_first = band_first;
+ rs.band_last = band_last;
rs.page_info = *page_info;
/* If this is a saved page, open the files. */
diff --git a/gs/src/gxclrect.c b/gs/src/gxclrect.c
index 4d72a8fc3..723c51e76 100644
--- a/gs/src/gxclrect.c
+++ b/gs/src/gxclrect.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -149,7 +149,7 @@ clist_fill_rectangle(gx_device * dev, int x, int y, int width, int height,
fit_fill(dev, x, y, width, height);
FOR_RECTS {
- pcls->colors_used |= color;
+ pcls->colors_used.or |= color;
TRY_RECT {
code = cmd_disable_lop(cdev, pcls);
if (code >= 0 && color != pcls->colors[1])
@@ -185,7 +185,7 @@ clist_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tile,
FOR_RECTS {
ulong offset_temp;
- pcls->colors_used |= colors_used;
+ pcls->colors_used.or |= colors_used;
TRY_RECT {
code = cmd_disable_lop(cdev, pcls);
} HANDLE_RECT(code);
@@ -248,7 +248,7 @@ clist_copy_mono(gx_device * dev,
const byte *row = data + (y - y0) * raster + (data_x >> 3);
int code;
- pcls->colors_used |= colors_used;
+ pcls->colors_used.or |= colors_used;
TRY_RECT {
code = cmd_disable_lop(cdev, pcls);
if (code >= 0)
@@ -344,7 +344,7 @@ clist_copy_color(gx_device * dev,
const byte *row = data + (y - y0) * raster + (data_x_bit >> 3);
int code;
- pcls->colors_used |= colors_used;
+ pcls->colors_used.or |= colors_used;
TRY_RECT {
code = cmd_disable_lop(cdev, pcls);
if (code >= 0)
@@ -427,7 +427,7 @@ clist_copy_alpha(gx_device * dev, const byte * data, int data_x,
/* just to change 2 arguments and 1 opcode, */
/* but I don't see any alternative that doesn't require */
/* another level of procedure call even in the common case. */
- int log2_depth = depth >> 1; /* works for 1,2,4 */
+ int log2_depth = ilog2(depth);
int y0;
int data_x_bit;
@@ -440,7 +440,7 @@ clist_copy_alpha(gx_device * dev, const byte * data, int data_x,
const byte *row = data + (y - y0) * raster + (data_x_bit >> 3);
int code;
- pcls->colors_used |= color;
+ pcls->colors_used.or |= color;
TRY_RECT {
code = cmd_disable_lop(cdev, pcls);
if (code >= 0)
@@ -535,16 +535,42 @@ clist_strip_copy_rop(gx_device * dev,
int y0;
/* Compute the set of possible colors that this operation can generate. */
gx_color_index all = ((gx_color_index)1 << dev->color_info.depth) - 1;
+ bool subtractive = dev->color_info.num_components == 4; /****** HACK ******/
gx_color_index S =
(scolors ? scolors[0] | scolors[1] : sdata ? all : 0);
gx_color_index T =
(tcolors ? tcolors[0] | tcolors[1] : textures ? all : 0);
+ gs_rop3_t color_rop =
+ (subtractive ? byte_reverse_bits[rop ^ 0xff] : rop);
+ bool slow_rop;
if (scolors != 0 && scolors[0] != scolors[1]) {
fit_fill(dev, x, y, width, height);
} else {
fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
}
+ /*
+ * On CMYK devices, RasterOps must be executed with complete pixels
+ * if the operation involves the destination.
+ * This is because the black plane interacts with the other planes
+ * in the conversion between RGB and CMYK. Check for this now.
+ */
+ {
+ gs_rop3_t rop_used = rop;
+
+ if (scolors && (scolors[0] == scolors[1]))
+ rop_used = (scolors[0] == gx_device_black(dev) ?
+ rop3_know_S_0(rop_used) :
+ scolors[0] == gx_device_white(dev) ?
+ rop3_know_S_1(rop_used) : rop_used);
+ if (tcolors && (tcolors[0] == tcolors[1]))
+ rop_used = (tcolors[0] == gx_device_black(dev) ?
+ rop3_know_T_0(rop_used) :
+ tcolors[0] == gx_device_white(dev) ?
+ rop3_know_T_1(rop_used) : rop_used);
+ slow_rop = !(rop == rop3_0 || rop == rop3_1 ||
+ rop == rop3_D || rop == rop3_S || rop == rop3_T);
+ }
y0 = y;
/*
* We shouldn't need to put the logic below inside FOR/END_RECTS,
@@ -552,10 +578,12 @@ clist_strip_copy_rop(gx_device * dev,
*/
FOR_RECTS {
const byte *row = sdata + (y - y0) * sraster;
- gx_color_index D = pcls->colors_used;
+ gx_color_index D = pcls->colors_used.or;
int code;
- pcls->colors_used = (rop_proc_table[rop])(D, S, T) | D;
+ pcls->colors_used.or =
+ ((rop_proc_table[color_rop])(D, S, T) & all) | D;
+ pcls->colors_used.slow_rop |= slow_rop;
if (rop3_uses_T(rop)) {
if (tcolors == 0 || tcolors[0] != tcolors[1]) {
ulong offset_temp;
diff --git a/gs/src/gxcmap.c b/gs/src/gxcmap.c
index bead0d704..ecec4f298 100644
--- a/gs/src/gxcmap.c
+++ b/gs/src/gxcmap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -151,8 +151,14 @@ private const gx_color_map_procs *const cmap_many[] =
};
/* Determine the color mapping procedures for a device. */
+/* Note that the default procedure doesn't consult the imager state. */
const gx_color_map_procs *
-gx_device_cmap_procs(const gx_device * dev)
+gx_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev)
+{
+ return (pis->get_cmap_procs)(pis, dev);
+}
+const gx_color_map_procs *
+gx_default_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev)
{
return (gx_device_must_halftone(dev) ? cmap_few : cmap_many)
[dev->color_info.num_components];
@@ -162,7 +168,7 @@ gx_device_cmap_procs(const gx_device * dev)
void
gx_set_cmap_procs(gs_imager_state * pis, const gx_device * dev)
{
- pis->cmap_procs = gx_device_cmap_procs(dev);
+ pis->cmap_procs = gx_get_cmap_procs(pis, dev);
}
/* Remap the color in the graphics state. */
@@ -207,15 +213,14 @@ gx_default_remap_color(const gs_client_color * pcc, const gs_color_space * pcs,
gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
gs_color_select_t select)
{
- frac conc[4];
+ frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
const gs_color_space *pconcs;
- int code = (*pcs->type->concretize_color) (pcc, pcs, conc, pis);
+ int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pis);
if (code < 0)
return code;
pconcs = cs_concrete_space(pcs, pis);
- return (*pconcs->type->remap_concrete_color) (conc, pdc, pis, dev,
- select);
+ return (*pconcs->type->remap_concrete_color)(conc, pdc, pis, dev, select);
}
/* Color remappers for the standard color spaces. */
@@ -691,6 +696,13 @@ cmap_rgb_alpha_to_cmyk(frac r, frac g, frac b, frac alpha,
/* ------ Transfer function mapping ------ */
+/* Define an identity transfer function. */
+float
+gs_identity_transfer(floatp value, const gx_transfer_map * pmap)
+{
+ return value;
+}
+
/* Define the generic transfer function for the library layer. */
/* This just returns what's already in the map. */
float
@@ -805,12 +817,10 @@ gx_default_rgb_map_rgb_color(gx_device * dev,
((uint) gx_color_value_to_byte(g) << 8) +
((ulong) gx_color_value_to_byte(r) << 16);
else {
- uint bits_per_color = dev->color_info.depth / 3;
- ulong max_value = (1 << bits_per_color) - 1;
+ int bpc = dev->color_info.depth / 3;
+ int drop = sizeof(gx_color_value) * 8 - bpc;
- return ((r * max_value / gx_max_color_value) << (bits_per_color * 2)) +
- ((g * max_value / gx_max_color_value) << (bits_per_color)) +
- (b * max_value / gx_max_color_value);
+ return ((((r >> drop) << bpc) + (g >> drop)) << bpc) + (b >> drop);
}
}
diff --git a/gs/src/gxcmap.h b/gs/src/gxcmap.h
index 2ba95992b..ce1380a75 100644
--- a/gs/src/gxcmap.h
+++ b/gs/src/gxcmap.h
@@ -17,7 +17,7 @@
*/
-/* Requires gxdcolor.h, gxdevice.h. */
+/* Requires gxdcolor.h. */
#ifndef gxcmap_INCLUDED
# define gxcmap_INCLUDED
@@ -25,6 +25,15 @@
#include "gscsel.h"
#include "gxfmap.h"
+#ifndef gx_device_DEFINED
+# define gx_device_DEFINED
+typedef struct gx_device_s gx_device;
+#endif
+#ifndef gx_device_color_DEFINED
+# define gx_device_color_DEFINED
+typedef struct gx_device_color_s gx_device_color;
+#endif
+
/* Procedures for rendering colors specified by fractions. */
#define cmap_proc_gray(proc)\
@@ -50,25 +59,38 @@ struct gx_color_map_procs_s {
};
typedef struct gx_color_map_procs_s gx_color_map_procs;
-/* Determine the color mapping procedures for a device. */
-const gx_color_map_procs *gx_device_cmap_procs(P1(const gx_device *));
-
-/* Set the color mapping procedures in the graphics state. */
-/* This is only needed when switching devices. */
+/*
+ * Determine the color mapping procedures for a device. Even though this
+ * does not currently use information from the imager state, it must be
+ * a virtual procedure of the state for internal reasons.
+ */
+const gx_color_map_procs *
+ gx_get_cmap_procs(P2(const gs_imager_state *, const gx_device *));
+const gx_color_map_procs *
+ gx_default_get_cmap_procs(P2(const gs_imager_state *, const gx_device *));
+
+/*
+ * Set the color mapping procedures in the graphics state. This is
+ * currently only needed when switching devices, but might be used more
+ * often in the future.
+ */
void gx_set_cmap_procs(P2(gs_imager_state *, const gx_device *));
-/* Remap a concrete (frac) RGB or CMYK color. */
+/* Remap a concrete (frac) gray, RGB or CMYK color. */
/* These cannot fail, and do not return a value. */
-#define gx_remap_concrete_rgb(cr, cg, cb, pdc, pgs, dev, select)\
- (*pgs->cmap_procs->map_rgb)(cr, cg, cb, pdc, pgs, dev, select)
-#define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pgs, dev, select)\
- (*pgs->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pgs, dev, select)
-#define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pgs, dev, select)\
- (*pgs->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pgs, dev, select)
+#define gx_remap_concrete_gray(cgray, pdc, pis, dev, select)\
+ ((pis)->cmap_procs->map_gray)(cgray, pdc, pis, dev, select)
+#define gx_remap_concrete_rgb(cr, cg, cb, pdc, pis, dev, select)\
+ ((pis)->cmap_procs->map_rgb)(cr, cg, cb, pdc, pis, dev, select)
+#define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pis, dev, select)\
+ ((pis)->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pis, dev, select)
+#define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pis, dev, select)\
+ ((pis)->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pis, dev, select)
/* Map a color, with optional tracing if we are debugging. */
#ifdef DEBUG
/* Use procedures in gxcmap.c */
+#include "gxcindex.h"
#include "gxcvalue.h"
gx_color_index gx_proc_map_rgb_color(P4(gx_device *,
gx_color_value, gx_color_value, gx_color_value));
diff --git a/gs/src/gxcolor2.h b/gs/src/gxcolor2.h
index e26c28482..668a82631 100644
--- a/gs/src/gxcolor2.h
+++ b/gs/src/gxcolor2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,11 +31,11 @@
struct gs_indexed_map_s {
rc_header rc;
union {
- int (*lookup_index) (P3(const gs_indexed_params *, int, float *));
- int (*tint_transform) (P3(const gs_separation_params *, floatp, float *));
+ int (*lookup_index)(P3(const gs_indexed_params *, int, float *));
+ int (*tint_transform)(P3(const gs_separation_params *, floatp, float *));
} proc;
- uint num_values; /* base_space->type->num_components * (hival + 1) */
- float *values; /* actually [num_values] */
+ uint num_values; /* base_space->type->num_components * (hival + 1) */
+ float *values; /* actually [num_values] */
};
extern_st(st_indexed_map);
@@ -43,6 +43,9 @@ extern_st(st_indexed_map);
gs_public_st_ptrs1(st_indexed_map, gs_indexed_map, "gs_indexed_map",\
indexed_map_enum_ptrs, indexed_map_reloc_ptrs, values)
+/* Define a lookup_index procedure that just returns the map values. */
+int lookup_indexed_map(P3(const gs_indexed_params *, int, float *));
+
/* Allocate an indexed map and its values. */
int alloc_indexed_map(P4(gs_indexed_map ** ppmap, int num_values,
gs_memory_t * mem, client_name_t cname));
@@ -50,6 +53,8 @@ int alloc_indexed_map(P4(gs_indexed_map ** ppmap, int num_values,
/* Free an indexed map and its values when the reference count goes to 0. */
rc_free_proc(free_indexed_map);
+/**************** TO gxptype1.h ****************/
+
/*
* We define 'tiling space' as the space in which (0,0) is the origin of
* the key pattern cell and in which coordinate (i,j) is displaced by
@@ -62,12 +67,10 @@ rc_free_proc(free_indexed_map);
* arrange it so that all 4 transformation factors are non-negative.
*/
-/* Implementation of Pattern instances. */
-struct gs_pattern_instance_s {
- rc_header rc;
- gs_client_pattern template;
+typedef struct gs_pattern1_instance_s {
+ gs_pattern_instance_common; /* must be first */
+ gs_pattern1_template_t template;
/* Following are created by makepattern */
- gs_state *saved;
gs_matrix step_matrix; /* tiling space -> device space */
gs_rect bbox; /* bbox of tile in tiling space */
bool is_simple; /* true if xstep/ystep = tile size */
@@ -77,16 +80,12 @@ struct gs_pattern_instance_s {
*/
bool uses_mask; /* if true, pattern mask must be created */
gs_int_point size; /* in device coordinates */
- gx_bitmap_id id; /* key for cached bitmap */
- /* (= id of mask) */
-};
+ gx_bitmap_id id; /* key for cached bitmap (= id of mask) */
+} gs_pattern1_instance_t;
-/* The following is only public for a type test in the interpreter */
-/* (.buildpattern operator). */
-extern_st(st_pattern_instance);
-#define public_st_pattern_instance() /* in gspcolor.c */\
- gs_public_st_ptrs_add1(st_pattern_instance, gs_pattern_instance,\
- "pattern instance", pattern_instance_enum_ptrs,\
- pattern_instance_reloc_ptrs, st_pattern1_template, template, saved)
+#define private_st_pattern1_instance() /* in gsptype1.c */\
+ gs_private_st_composite(st_pattern1_instance, gs_pattern1_instance_t,\
+ "gs_pattern1_instance_t", pattern1_instance_enum_ptrs,\
+ pattern1_instance_reloc_ptrs)
#endif /* gxcolor2_INCLUDED */
diff --git a/gs/src/gxcpath.c b/gs/src/gxcpath.c
index c8bbb90c4..5202ddd89 100644
--- a/gs/src/gxcpath.c
+++ b/gs/src/gxcpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,13 +26,13 @@
#include "gxdevice.h"
#include "gxfixed.h"
#include "gscoord.h" /* needs gsmatrix.h */
-#include "gxstate.h"
+#include "gxistate.h"
#include "gzpath.h"
#include "gzcpath.h"
/* Imported from gxacpath.c */
-extern int gx_cpath_intersect_slow(P4(gs_state *, gx_clip_path *,
- gx_path *, int));
+extern int gx_cpath_intersect_path_slow(P4(gx_clip_path *, gx_path *, int,
+ gs_imager_state *));
/* Forward references */
private void gx_clip_list_from_rectangle(P2(gx_clip_list *, gs_fixed_rect *));
@@ -46,26 +46,25 @@ public_st_device_clip();
private_st_cpath_enum();
/* GC procedures for gx_clip_path */
-#define cptr ((gx_clip_path *)vptr)
private
-ENUM_PTRS_BEGIN(clip_path_enum_ptrs) return ENUM_USING(st_path, &cptr->path, sizeof(cptr->path), index - 1);
+ENUM_PTRS_WITH(clip_path_enum_ptrs, gx_clip_path *cptr) return ENUM_USING(st_path, &cptr->path, sizeof(cptr->path), index - 1);
case 0:
ENUM_RETURN((cptr->rect_list == &cptr->local_list ? 0 :
cptr->rect_list));
ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(clip_path_reloc_ptrs)
+private
+RELOC_PTRS_WITH(clip_path_reloc_ptrs, gx_clip_path *cptr)
{
if (cptr->rect_list != &cptr->local_list)
RELOC_VAR(cptr->rect_list);
RELOC_USING(st_path, &cptr->path, sizeof(gx_path));
}
RELOC_PTRS_END
-#undef cptr
/* GC procedures for gx_device_clip */
-#define cptr ((gx_device_clip *)vptr)
-private ENUM_PTRS_BEGIN(device_clip_enum_ptrs)
+private
+ENUM_PTRS_WITH(device_clip_enum_ptrs, gx_device_clip *cptr)
{
if (index < st_clip_list_max_ptrs + 1)
return ENUM_USING(st_clip_list, &cptr->list,
@@ -78,7 +77,8 @@ case 0:
ENUM_RETURN((cptr->current == &cptr->list.single ? NULL :
(void *)cptr->current));
ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(device_clip_reloc_ptrs)
+private
+RELOC_PTRS_WITH(device_clip_reloc_ptrs, gx_device_clip *cptr)
{
if (cptr->current == &cptr->list.single)
cptr->current = &((gx_device_clip *)RELOC_OBJ(vptr))->list.single;
@@ -88,13 +88,12 @@ private RELOC_PTRS_BEGIN(device_clip_reloc_ptrs)
RELOC_USING(st_device_forward, vptr, sizeof(gx_device_forward));
}
RELOC_PTRS_END
-#undef cptr
/* Define an empty clip list. */
private const gx_clip_list clip_list_empty =
{
{0, 0, min_int, max_int, 0, 0},
- 0, 0, 0, 0 /*false */
+ 0, 0, 0, 0, 0
};
/* Debugging */
@@ -414,30 +413,17 @@ gx_cpath_to_path(gx_clip_path * pcpath, gx_path * ppath)
/* Return the inner and outer check rectangles for a clipping path. */
/* Return true iff the path is a rectangle. */
-/* Note that these must return something strange if we are using */
-/* outside clipping. */
bool
gx_cpath_inner_box(const gx_clip_path * pcpath, gs_fixed_rect * pbox)
{
- if (gx_cpath_is_outside(pcpath)) {
- pbox->p.x = pbox->p.y = pbox->q.x = pbox->q.y = 0;
- return false;
- } else {
- *pbox = pcpath->inner_box;
- return clip_list_is_rectangle(gx_cpath_list(pcpath));
- }
+ *pbox = pcpath->inner_box;
+ return clip_list_is_rectangle(gx_cpath_list(pcpath));
}
bool
gx_cpath_outer_box(const gx_clip_path * pcpath, gs_fixed_rect * pbox)
{
- if (gx_cpath_is_outside(pcpath)) {
- pbox->p.x = pbox->p.y = min_fixed;
- pbox->q.x = pbox->q.y = max_fixed;
- return false;
- } else {
- *pbox = pcpath->outer_box;
- return clip_list_is_rectangle(gx_cpath_list(pcpath));
- }
+ *pbox = pcpath->outer_box;
+ return clip_list_is_rectangle(gx_cpath_list(pcpath));
}
/* Test if a clipping path includes a rectangle. */
@@ -455,24 +441,6 @@ gx_cpath_includes_rectangle(register const gx_clip_path * pcpath,
(pcpath->inner_box.p.y <= y1 && y0 <= pcpath->inner_box.q.y));
}
-/* Set the current outsideness of a clipping path. */
-int
-gx_cpath_set_outside(gx_clip_path * pcpath, bool outside)
-{
- if (outside != gx_cpath_list(pcpath)->outside) {
- pcpath->id = gs_next_ids(1); /* path changed => change id */
- gx_cpath_list(pcpath)->outside = outside;
- }
- return 0;
-}
-
-/* Return the current outsideness of a clipping path. */
-bool
-gx_cpath_is_outside(const gx_clip_path * pcpath)
-{
- return gx_cpath_list(pcpath)->outside;
-}
-
/* Set the outer clipping box to the path bounding box, */
/* expanded to pixel boundaries. */
void
@@ -484,6 +452,20 @@ gx_cpath_set_outer_box(gx_clip_path * pcpath)
pcpath->outer_box.q.y = fixed_ceiling(pcpath->path.bbox.q.y);
}
+/* Return the rectangle list of a clipping path (for local use only). */
+const gx_clip_list *
+gx_cpath_list(const gx_clip_path *pcpath)
+{
+ return &pcpath->rect_list->list;
+}
+/* Internal non-const version of the same accessor. */
+inline private gx_clip_list *
+gx_cpath_list_private(gx_clip_path *pcpath)
+{
+ return &pcpath->rect_list->list;
+}
+
+
/* ------ Clipping path setting ------ */
/* Create a rectangular clipping path. */
@@ -529,20 +511,27 @@ gx_cpath_reset(gx_clip_path * pcpath)
/* Intersect a new clipping path with an old one. */
/* Flatten the new path first (in a copy) if necessary. */
int
-gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath_orig,
- int rule)
+gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath,
+ /*const*/ gx_path *ppath_orig, int rule)
+{
+ return gx_cpath_intersect(pcpath, ppath_orig, rule,
+ (gs_imager_state *)pgs);
+}
+int
+gx_cpath_intersect(gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig,
+ int rule, gs_imager_state *pis)
{
gx_path fpath;
- gx_path *ppath = ppath_orig;
+ /*const*/ gx_path *ppath = ppath_orig;
gs_fixed_rect old_box, new_box;
int code;
/* Flatten the path if necessary. */
if (gx_path_has_curves_inline(ppath)) {
- gx_path_init_local(&fpath, gs_state_memory(pgs));
+ gx_path_init_local(&fpath, pis->memory);
code = gx_path_add_flattened_accurate(ppath, &fpath,
- gs_currentflat(pgs),
- gs_currentaccuratecurves(pgs));
+ gs_currentflat_inline(pis),
+ pis->accurate_curves);
if (code < 0)
return code;
ppath = &fpath;
@@ -553,17 +542,13 @@ gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath_orig,
gx_path_is_void(ppath))
) {
bool changed = false;
- bool outside = gx_cpath_is_outside(pcpath);
if (!code) {
/* The new path is void. */
if (gx_path_current_point(ppath, &new_box.p) < 0) {
/* Use the user space origin (arbitrarily). */
- gs_point origin;
-
- gs_transform(pgs, 0.0, 0.0, &origin);
- new_box.p.x = float2fixed(origin.x);
- new_box.p.y = float2fixed(origin.y);
+ new_box.p.x = float2fixed(pis->ctm.tx);
+ new_box.p.y = float2fixed(pis->ctm.ty);
changed = true;
}
new_box.q = new_box.p;
@@ -593,7 +578,6 @@ gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath_orig,
}
ppath->bbox = new_box;
cpath_set_rectangle(pcpath, &new_box);
- pcpath->rect_list->list.outside = outside;
} else {
/* Existing clip path is not a rectangle. Intersect the slow way. */
bool path_valid =
@@ -603,7 +587,7 @@ gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath_orig,
new_box.p.x, new_box.p.y,
new_box.q.x, new_box.q.y);
- code = gx_cpath_intersect_slow(pgs, pcpath, ppath, rule);
+ code = gx_cpath_intersect_path_slow(pcpath, ppath, rule, pis);
if (code >= 0 && path_valid) {
gx_path_assign_preserve(&pcpath->path, ppath_orig);
pcpath->path_valid = true;
@@ -616,11 +600,16 @@ gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath_orig,
/* Scale a clipping path by a power of 2. */
int
-gx_cpath_scale_exp2(gx_clip_path * pcpath, int log2_scale_x, int log2_scale_y)
+gx_cpath_scale_exp2_shared(gx_clip_path * pcpath, int log2_scale_x,
+ int log2_scale_y, bool list_shared,
+ bool segments_shared)
{
int code =
- gx_path_scale_exp2(&pcpath->path, log2_scale_x, log2_scale_y);
- gx_clip_list *list = gx_cpath_list(pcpath);
+ (pcpath->path_valid ?
+ gx_path_scale_exp2_shared(&pcpath->path, log2_scale_x, log2_scale_y,
+ segments_shared) :
+ 0);
+ gx_clip_list *list = gx_cpath_list_private(pcpath);
gx_clip_rect *pr;
if (code < 0)
@@ -628,21 +617,25 @@ gx_cpath_scale_exp2(gx_clip_path * pcpath, int log2_scale_x, int log2_scale_y)
/* Scale the fixed entries. */
gx_rect_scale_exp2(&pcpath->inner_box, log2_scale_x, log2_scale_y);
gx_rect_scale_exp2(&pcpath->outer_box, log2_scale_x, log2_scale_y);
- /* Scale the clipping list. */
- pr = list->head;
- if (pr == 0)
- pr = &list->single;
- for (; pr != 0; pr = pr->next)
- if (pr != list->head && pr != list->tail) {
-#define scale_v(v, s)\
+ if (!list_shared) {
+ /* Scale the clipping list. */
+ pr = list->head;
+ if (pr == 0)
+ pr = &list->single;
+ for (; pr != 0; pr = pr->next)
+ if (pr != list->head && pr != list->tail) {
+
+#define SCALE_V(v, s)\
if ( pr->v != min_int && pr->v != max_int )\
pr->v = (s >= 0 ? pr->v << s : pr->v >> -s)
- scale_v(xmin, log2_scale_x);
- scale_v(xmax, log2_scale_x);
- scale_v(ymin, log2_scale_y);
- scale_v(ymax, log2_scale_y);
-#undef scale_v
- }
+
+ SCALE_V(xmin, log2_scale_x);
+ SCALE_V(xmax, log2_scale_x);
+ SCALE_V(ymin, log2_scale_y);
+ SCALE_V(ymax, log2_scale_y);
+#undef SCALE_V
+ }
+ }
pcpath->id = gs_next_ids(1); /* path changed => change id */
return 0;
}
@@ -676,12 +669,11 @@ gx_clip_list_from_rectangle(register gx_clip_list * clp,
rp->p.y = rp->q.y;
rp->q.y = t;
}
- clp->single.xmin = fixed2int_var(rp->p.x);
+ clp->single.xmin = clp->xmin = fixed2int_var(rp->p.x);
clp->single.ymin = fixed2int_var(rp->p.y);
- clp->single.xmax = fixed2int_var_ceiling(rp->q.x);
+ clp->single.xmax = clp->xmax = fixed2int_var_ceiling(rp->q.x);
clp->single.ymax = fixed2int_var_ceiling(rp->q.y);
clp->count = 1;
- clp->outside = false;
}
/* Start enumerating a clipping path. */
@@ -693,7 +685,7 @@ gx_cpath_enum_init(gs_cpath_enum * penum, gx_clip_path * pcpath)
penum->rp = penum->visit = 0;
} else {
gx_path empty_path;
- gx_clip_list *clp = gx_cpath_list(pcpath);
+ gx_clip_list *clp = gx_cpath_list_private(pcpath);
gx_clip_rect *head = (clp->count <= 1 ? &clp->single : clp->head);
gx_clip_rect *rp;
@@ -914,13 +906,33 @@ gx_clip_list_free(gx_clip_list * clp, gs_memory_t * mem)
#ifdef DEBUG
-/* Print a clipping path */
+/* Print a clipping list. */
void
-gx_cpath_print(const gx_clip_path * pcpath)
+gx_clip_list_print(const gx_clip_list *list)
{
const gx_clip_rect *pr;
- const gx_clip_list *list = gx_cpath_list(pcpath);
+ dlprintf3(" list count=%d xmin=%d xmax=%d\n",
+ list->count, list->xmin, list->xmax);
+ switch (list->count) {
+ case 0:
+ pr = 0;
+ break;
+ case 1:
+ pr = &list->single;
+ break;
+ default:
+ pr = list->head;
+ }
+ for (; pr != 0; pr = pr->next)
+ dlprintf4(" rect: (%d,%d),(%d,%d)\n",
+ pr->xmin, pr->ymin, pr->xmax, pr->ymax);
+}
+
+/* Print a clipping path */
+void
+gx_cpath_print(const gx_clip_path * pcpath)
+{
if (pcpath->path_valid)
gx_path_print(&pcpath->path);
else
@@ -935,22 +947,9 @@ gx_cpath_print(const gx_clip_path * pcpath)
fixed2float(pcpath->outer_box.p.y),
fixed2float(pcpath->outer_box.q.x),
fixed2float(pcpath->outer_box.q.y));
- dprintf4(" rule=%d outside=%d count=%d list.refct=%ld\n",
- pcpath->rule, list->outside, list->count,
- pcpath->rect_list->rc.ref_count);
- switch (list->count) {
- case 0:
- pr = 0;
- break;
- case 1:
- pr = &list->single;
- break;
- default:
- pr = list->head;
- }
- for (; pr != 0; pr = pr->next)
- dlprintf4(" rect: (%d,%d),(%d,%d)\n",
- pr->xmin, pr->ymin, pr->xmax, pr->ymax);
+ dprintf2(" rule=%d list.refct=%ld\n",
+ pcpath->rule, pcpath->rect_list->rc.ref_count);
+ gx_clip_list_print(gx_cpath_list(pcpath));
}
#endif /* DEBUG */
diff --git a/gs/src/gxcpath.h b/gs/src/gxcpath.h
index f6e64880e..802656037 100644
--- a/gs/src/gxcpath.h
+++ b/gs/src/gxcpath.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -73,10 +73,9 @@ struct gx_clip_list_s {
gx_clip_rect single; /* (has next = prev = 0) */
gx_clip_rect *head;
gx_clip_rect *tail;
+ int xmin, xmax; /* min and max X over all but head/tail */
int count; /* # of rectangles not counting */
- /* head or tail */
- bool outside; /* if true, clip to outside of list */
- /* rather than inside */
+ /* head or tail */
};
#define private_st_clip_list() /* in gxcpath.c */\
@@ -90,6 +89,10 @@ struct gx_clip_list_s {
* This ability, a late addition, currently is used only in a few
* situations that require breaking up a transfer into pieces,
* but we suspect it could be used more widely.
+ *
+ * Note that clipping devices cache their clipping box, so the target's
+ * clipping box and the clip list must be const after the clipping device
+ * is opened.
*/
#ifndef gx_device_clip_DEFINED
# define gx_device_clip_DEFINED
@@ -100,12 +103,15 @@ struct gx_device_clip_s {
gx_clip_list list; /* set by client */
gx_clip_rect *current; /* cursor in list */
gs_int_point translation;
+ gs_fixed_rect clipping_box;
+ bool clipping_box_set;
};
extern_st(st_device_clip);
#define public_st_device_clip() /* in gxcpath.c */\
- gs_public_st_composite(st_device_clip, gx_device_clip,\
- "gx_device_clip", device_clip_enum_ptrs, device_clip_reloc_ptrs)
+ gs_public_st_composite_use_final(st_device_clip, gx_device_clip,\
+ "gx_device_clip", device_clip_enum_ptrs, device_clip_reloc_ptrs,\
+ gx_device_finalize)
void gx_make_clip_translate_device(P5(gx_device_clip * dev, void *container,
const gx_clip_list * list, int tx, int ty));
@@ -117,7 +123,7 @@ void gx_make_clip_path_device(P2(gx_device_clip *, const gx_clip_path *));
if_debug7(ch, "[%c]%s 0x%lx: (%d,%d),(%d,%d)\n", ch, str, (ulong)ar,\
(ar)->xmin, (ar)->ymin, (ar)->xmax, (ar)->ymax)
-/* Routines exported from gxcpath.c for gxacpath.c */
+/* Exported by gxcpath.c for gxacpath.c */
/* Initialize a clip list. */
void gx_clip_list_init(P1(gx_clip_list *));
@@ -128,4 +134,9 @@ void gx_clip_list_free(P2(gx_clip_list *, gs_memory_t *));
/* Set the outer box for a clipping path from its bounding box. */
void gx_cpath_set_outer_box(P1(gx_clip_path *));
+/* Exported by gxcpath.c for gxclip.c */
+
+/* Return the rectangle list of a clipping path (for local use only). */
+const gx_clip_list *gx_cpath_list(P1(const gx_clip_path *pcpath));
+
#endif /* gxcpath_INCLUDED */
diff --git a/gs/src/gxcspace.h b/gs/src/gxcspace.h
index 2c9ea5173..05dff50f4 100644
--- a/gs/src/gxcspace.h
+++ b/gs/src/gxcspace.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,13 +33,11 @@
#ifndef gx_device_color_DEFINED
# define gx_device_color_DEFINED
typedef struct gx_device_color_s gx_device_color;
-
#endif
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
/* Color space types (classes): */
@@ -152,7 +150,7 @@ struct gs_color_space_type_s {
/* Install the color space in a graphics state. */
#define cs_proc_install_cspace(proc)\
- int proc(P2(gs_color_space *, gs_state *))
+ int proc(P2(const gs_color_space *, gs_state *))
cs_proc_install_cspace((*install_cspace));
/* Adjust reference counts of indirect color space components. */
@@ -210,12 +208,6 @@ cs_proc_install_cspace(gx_no_install_cspace);
cs_proc_adjust_cspace_count(gx_no_adjust_cspace_count);
cs_proc_adjust_color_count(gx_no_adjust_color_count);
-/* Standard color space types */
-extern const gs_color_space_type
- gs_color_space_type_DeviceGray,
- gs_color_space_type_DeviceRGB,
- gs_color_space_type_DeviceCMYK;
-
/* Define the allocator type for color spaces. */
extern_st(st_color_space);
diff --git a/gs/src/gxctable.c b/gs/src/gxctable.c
index e2bb964c0..be792ea10 100644
--- a/gs/src/gxctable.c
+++ b/gs/src/gxctable.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -55,20 +55,18 @@ gx_color_interpolate_nearest(const fixed * pi,
/*
* Define an implementation that uses trilinear interpolation.
*/
-void
-gx_color_interpolate_linear(const fixed * pi,
- const gx_color_lookup_table * pclt, frac * pv)
+private void
+interpolate_accum(const fixed * pi, const gx_color_lookup_table * pclt,
+ frac * pv, fixed factor)
{
const int *pdim = pclt->dims;
int m = pclt->m;
- if (pclt->n > 3) { /* Do two 3-D interpolations, */
- /* and then interpolate between them. */
+ if (pclt->n > 3) {
+ /* Do two 3-D interpolations, interpolating between them. */
gx_color_lookup_table clt3;
- frac vx[4];
int ix = fixed2int_var(pi[0]);
fixed fx = fixed_fraction(pi[0]);
- int j;
clt3.n = 3;
/*clt3.dims[0] = pdim[1]; *//* not used */
@@ -76,14 +74,11 @@ gx_color_interpolate_linear(const fixed * pi,
clt3.dims[2] = pdim[3];
clt3.m = m;
clt3.table = pclt->table + ix * pdim[1];
- gx_color_interpolate_linear(pi + 1, &clt3, pv);
+ interpolate_accum(pi + 1, &clt3, pv, fixed_1);
if (ix == pdim[0] - 1)
return;
clt3.table += pdim[1];
- gx_color_interpolate_linear(pi + 1, &clt3, vx);
- for (j = 0; j < m; ++j)
- pv[j] += (frac) arith_rshift((long)fx * (vx[j] - pv[j]),
- _fixed_shift);
+ interpolate_accum(pi + 1, &clt3, pv, fx);
} else {
int ic = fixed2int_var(pi[2]);
fixed fc = fixed_fraction(pi[2]);
@@ -97,7 +92,7 @@ gx_color_interpolate_linear(const fixed * pi,
fixed fa = fixed_fraction(pi[0]);
const byte *pa0 = pclt->table[ia].data + dbc;
const byte *pa1 =
- (ia == pdim[0] - 1 ? pa0 : pclt->table[ia + 1].data + dbc);
+ (ia == pdim[0] - 1 ? pa0 : pclt->table[ia + 1].data + dbc);
int j;
/* The values to be interpolated are */
@@ -111,30 +106,42 @@ gx_color_interpolate_linear(const fixed * pi,
frac v101 = byte2frac(pa1[dc1]);
frac v110 = byte2frac(pa1[db1]);
frac v111 = byte2frac(pa1[dbc1]);
+ frac rv;
frac v00 = v000 +
- (frac) arith_rshift((long)fc * (v001 - v000),
- _fixed_shift);
+ (frac) arith_rshift((long)fc * (v001 - v000),
+ _fixed_shift);
frac v01 = v010 +
- (frac) arith_rshift((long)fc * (v011 - v010),
- _fixed_shift);
+ (frac) arith_rshift((long)fc * (v011 - v010),
+ _fixed_shift);
frac v10 = v100 +
- (frac) arith_rshift((long)fc * (v101 - v100),
- _fixed_shift);
+ (frac) arith_rshift((long)fc * (v101 - v100),
+ _fixed_shift);
frac v11 = v110 +
- (frac) arith_rshift((long)fc * (v111 - v110),
- _fixed_shift);
+ (frac) arith_rshift((long)fc * (v111 - v110),
+ _fixed_shift);
frac v0 = v00 +
- (frac) arith_rshift((long)fb * (v01 - v00),
- _fixed_shift);
+ (frac) arith_rshift((long)fb * (v01 - v00),
+ _fixed_shift);
frac v1 = v10 +
- (frac) arith_rshift((long)fb * (v11 - v10),
- _fixed_shift);
+ (frac) arith_rshift((long)fb * (v11 - v10),
+ _fixed_shift);
- pv[j] = v0 +
+ rv = v0 +
(frac) arith_rshift((long)fa * (v1 - v0),
_fixed_shift);
+ if (factor == fixed_1)
+ pv[j] = rv;
+ else
+ pv[j] += (frac) arith_rshift((long)factor * (rv - pv[j]),
+ _fixed_shift);
}
}
}
+void
+gx_color_interpolate_linear(const fixed * pi,
+ const gx_color_lookup_table * pclt, frac * pv)
+{
+ interpolate_accum(pi, pclt, pv, fixed_1);
+}
diff --git a/gs/src/gxctable.h b/gs/src/gxctable.h
index 37c11d669..0bf19a05b 100644
--- a/gs/src/gxctable.h
+++ b/gs/src/gxctable.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,7 +29,7 @@
* Define a 3- or 4-D color lookup table.
* n is the number of dimensions (input indices), 3 or 4.
* dims[0..n-1] are the table dimensions.
- * m is the number of output values, 3 or 4.
+ * m is the number of output values, typically 3 (RGB) or 4 (CMYK).
* For n = 3:
* table[i], 0 <= i < dims[0], point to strings of length
* dims[1] x dims[2] x m.
diff --git a/gs/src/gxdcconv.c b/gs/src/gxdcconv.c
index e5cbb1c9c..41ea0d5f3 100644
--- a/gs/src/gxdcconv.c
+++ b/gs/src/gxdcconv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,7 +31,7 @@
* The CMYK to RGB algorithms specified by Adobe are, e.g.,
* R = 1.0 - min(1.0, C + K)
* C = max(0.0, min(1.0, 1 - R - UCR))
- * but we get much better results with
+ * We got better results on displays with
* R = (1.0 - C) * (1.0 - K)
* C = max(0.0, min(1.0, 1 - R / (1 - UCR)))
* For utmost compatibility, we offer the Adobe algorithms as an option:
@@ -63,13 +63,16 @@ color_rgb_to_cmyk(frac r, frac g, frac b, const gs_imager_state * pis,
frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b;
frac k = (c < m ? min(c, y) : min(m, y));
- /* The default UCR and BG functions are pretty arbitrary.... */
+ /*
+ * The default UCR and BG functions are pretty arbitrary,
+ * but they must agree with the ones in gs_init.ps.
+ */
frac bg =
- (pis->black_generation == NULL ? frac_0 :
- gx_map_color_frac(pis, k, black_generation));
+ (pis->black_generation == NULL ? k :
+ gx_map_color_frac(pis, k, black_generation));
signed_frac ucr =
- (pis->undercolor_removal == NULL ? frac_0 :
- gx_map_color_frac(pis, k, undercolor_removal));
+ (pis->undercolor_removal == NULL ? k :
+ gx_map_color_frac(pis, k, undercolor_removal));
if (ucr == frac_1)
cmyk[0] = cmyk[1] = cmyk[2] = 0;
diff --git a/gs/src/gxdcolor.c b/gs/src/gxdcolor.c
index 471ce4ff4..1d1c4fa06 100644
--- a/gs/src/gxdcolor.c
+++ b/gs/src/gxdcolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -114,20 +114,20 @@ void
gx_set_rop_no_source(const gx_rop_source_t **psource,
gx_rop_source_t *pno_source, gx_device *dev)
{
+ gx_color_index black;
+
top:
- switch (dev->cached_colors.black) {
- case 0:
+ black = dev->cached_colors.black;
+ if (black == 0)
*psource = &gx_rop_no_source_0;
- break;
- case 1:
+ else if (black == 1)
*psource = &gx_rop_no_source_1;
- break;
- case gx_no_color_index: /* cache not loaded */
+ else if (black == gx_no_color_index) { /* cache not loaded */
discard(gx_device_black(dev));
goto top;
- default:
+ } else {
*pno_source = gx_rop_no_source_0;
- gx_rop_source_set_color(pno_source, dev->cached_colors.black);
+ gx_rop_source_set_color(pno_source, black);
*psource = pno_source;
}
}
@@ -280,8 +280,7 @@ gx_dc_pure_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2)
/* ------ Halftone color initialization ------ */
void
-gx_complete_rgb_halftone(gx_device_color *pdevc,
- const gx_device_halftone *pdht)
+gx_complete_rgb_halftone(gx_device_color *pdevc, gx_device_halftone *pdht)
{
pdevc->type = gx_dc_type_ht_colored;
pdevc->colors.colored.c_ht = pdht;
@@ -298,8 +297,7 @@ gx_complete_rgb_halftone(gx_device_color *pdevc,
}
void
-gx_complete_cmyk_halftone(gx_device_color *pdevc,
- const gx_device_halftone *pdht)
+gx_complete_cmyk_halftone(gx_device_color *pdevc, gx_device_halftone *pdht)
{
pdevc->type = gx_dc_type_ht_colored;
pdevc->colors.colored.c_ht = pdht;
diff --git a/gs/src/gxdcolor.h b/gs/src/gxdcolor.h
index 73321f712..b581d7069 100644
--- a/gs/src/gxdcolor.h
+++ b/gs/src/gxdcolor.h
@@ -150,10 +150,6 @@ extern const gx_device_color_type_t
/* (e.g., the character cache). */
void gx_set_device_color_1(P1(gs_state * pgs));
-/* Get the black and white pixel values of a device. */
-gx_color_index gx_device_black(P1(gx_device *dev));
-gx_color_index gx_device_white(P1(gx_device *dev));
-
/* Remap the color if necessary. */
int gx_remap_color(P1(gs_state *));
diff --git a/gs/src/gxdevbuf.h b/gs/src/gxdevbuf.h
new file mode 100644
index 000000000..52afa68a9
--- /dev/null
+++ b/gs/src/gxdevbuf.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definitions for device buffer management */
+
+#ifndef gxdevbuf_INCLUDED
+# define gxdevbuf_INCLUDED
+
+#include "gxrplane.h" /* for _buf_device procedures */
+
+/*
+ * Define the procedures for managing rendering buffers. These are
+ * currently associated with printer and/or banded devices, but they
+ * might have broader applicability in the future.
+ *
+ * For "async" devices, size_buf_device may be called by either the
+ * writer or the reader thread; the other procedures may be called only
+ * by the reader thread.
+ */
+
+#ifndef gx_device_DEFINED
+# define gx_device_DEFINED
+typedef struct gx_device_s gx_device;
+#endif
+
+/* Define the structure for returning buffer space requirements. */
+typedef struct gx_device_buf_space_s {
+ ulong bits;
+ ulong line_ptrs;
+ uint raster;
+} gx_device_buf_space_t;
+
+typedef struct gx_device_buf_procs_s {
+
+ /*
+ * Create the buffer device(s) for the pixels or a plane of a page
+ * or band. We use 'buf' instead of buffer because VMS limits
+ * procedure names to 31 characters. Note that the client must
+ * fully initialize the render_plane using gx_render_plane_init.
+ *
+ * If mem is NULL, *pbdev must already point to a gx_device_memory,
+ * and this procedure must initialize it. If this isn't possible
+ * (e.g., if render_plane calls for a single plane),
+ * create_buf_device must return an error.
+ */
+
+#define dev_proc_create_buf_device(proc)\
+ int proc(P5(gx_device **pbdev, gx_device *target,\
+ const gx_render_plane_t *render_plane, gs_memory_t *mem,\
+ bool for_band))
+
+ dev_proc_create_buf_device((*create_buf_device));
+
+ /*
+ * Return the amount of buffer space needed by setup_buf_device.
+ */
+
+#define dev_proc_size_buf_device(proc)\
+ int proc(P5(gx_device_buf_space_t *space, gx_device *target,\
+ const gx_render_plane_t *render_plane,\
+ int height, bool for_band))
+
+ dev_proc_size_buf_device((*size_buf_device));
+
+ /*
+ * Set up the buffer device with a specific buffer.
+ * If line_ptrs is not NULL, it points to an allocated area for
+ * the scan line pointers of an eventual memory device.
+ *
+ * Note that this procedure is used for two different purposes:
+ * setting up a full band buffer for rendering, and setting up a
+ * partial-band buffer device for reading out selected scan lines.
+ * The latter case requires that we also pass the full height of the
+ * buffer, for multi-planar memory devices; in the former case,
+ * y = 0 and setup_height = full_height.
+ */
+
+#define dev_proc_setup_buf_device(proc)\
+ int proc(P7(gx_device *bdev, byte *buffer, int bytes_per_line,\
+ byte **line_ptrs /*[height]*/, int y, int setup_height,\
+ int full_height))
+
+ dev_proc_setup_buf_device((*setup_buf_device));
+
+ /*
+ * Destroy the buffer device and all associated structures.
+ * Note that this does *not* destroy the buffered data.
+ */
+
+#define dev_proc_destroy_buf_device(proc)\
+ void proc(P1(gx_device *bdev))
+
+ dev_proc_destroy_buf_device((*destroy_buf_device));
+
+} gx_device_buf_procs_t;
+
+/* Define default buffer device management procedures. */
+dev_proc_create_buf_device(gx_default_create_buf_device);
+dev_proc_size_buf_device(gx_default_size_buf_device);
+dev_proc_setup_buf_device(gx_default_setup_buf_device);
+dev_proc_destroy_buf_device(gx_default_destroy_buf_device);
+
+#endif /* gxdevbuf_INCLUDED */
diff --git a/gs/src/gxdevcli.h b/gs/src/gxdevcli.h
index 0223c764f..0ab6f07fa 100644
--- a/gs/src/gxdevcli.h
+++ b/gs/src/gxdevcli.h
@@ -42,9 +42,67 @@
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
+/* ---------------- Memory management ---------------- */
+
+/*
+ * NOTE: if you write code that creates device instances (either with
+ * gs_copydevice or by allocating them explicitly), allocates device
+ * instances as either local or static variables (actual instances, not
+ * pointers to instances), or sets the target of forwarding devices, please
+ * read the following documentation carefully. The rules for doing these
+ * things changed substantially in release 5.68, in a
+ * non-backward-compatible way, and unfortunately we could not find a way to
+ * make the compiler give an error at places that need changing.
+ */
+
+/*
+ * Device instances are managed with reference counting: when the last
+ * reference to a device from a graphics state or the target field of a
+ * forwarding device is removed, the device is normally freed. However,
+ * some device instances are referenced in other ways (for example, from
+ * objects in the PostScript interpreter, or from library client code) and
+ * will be freed by the garbage collector (if any) or explicitly: they
+ * should not be freed by reference counting. These are called "retained"
+ * device instances. Every device instance remembers whether or not it is
+ * retained, and an instance is freed iff its reference count is zero and it
+ * is not retained.
+ *
+ * Normally devices are initialized as not retained. However, devices
+ * initialized by calling gx_device_init(pdev, proto, memory, false), or
+ * created by gs_copydevice are marked as retained. You can also set the
+ * retention status of a device explicitly with gx_device_retain(pdev,
+ * true-or-false). Note that if you change a retained device to
+ * non-retained, if there are no references to it from graphics states or
+ * targets, it will be freed immediately.
+ *
+ * There are 3 ways that a device structure might be allocated:
+ * 1) Allocated dynamically, e.g.,
+ * gx_device *pdev_new;
+ * gs_copydevice(&pdev_new, pdev_old, memory);
+ * 2) Declared as a local or static variable, e.g.,
+ * gx_device devv;
+ * or
+ * const gx_device devc = ...;
+ * 3) Embedded in an object allocated in one of the above ways.
+ * If you allocate a device using #2 or #3, you MUST mark it as retained
+ * by calling gx_device_retain(pdev, true). If you do not do this, an
+ * attempt will be made to free the device, corrupting memory. */
+
+/*
+ * Do not set the target of a forwarding device with an assignment like
+ * fdev->target = tdev;
+ * You must use the procedure
+ * gx_device_set_target(fdev, tdev);
+ * Note that the first argument is a gx_device_forward *, not a gx_device *.
+ *
+ * We could have changed the member name "target" when this became
+ * necessary, so the compiler would flag places that needed editing, but
+ * there were literally hundreds of places that only read the target member
+ * that we would have had to change, so we decided to leave the name alone.
+ */
+
/* ---------------- Auxiliary types and structures ---------------- */
/* We need at least an abstract type for a graphics state, */
@@ -52,7 +110,6 @@ typedef struct gx_device_s gx_device;
#ifndef gs_state_DEFINED
# define gs_state_DEFINED
typedef struct gs_state_s gs_state;
-
#endif
/* We need abstract types for paths and fill/stroke parameters, */
@@ -60,34 +117,29 @@ typedef struct gs_state_s gs_state;
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
-
#endif
#ifndef gx_clip_path_DEFINED
# define gx_clip_path_DEFINED
typedef struct gx_clip_path_s gx_clip_path;
-
#endif
#ifndef gx_fill_params_DEFINED
# define gx_fill_params_DEFINED
typedef struct gx_fill_params_s gx_fill_params;
-
#endif
#ifndef gx_stroke_params_DEFINED
# define gx_stroke_params_DEFINED
typedef struct gx_stroke_params_s gx_stroke_params;
-
#endif
#ifndef gs_imager_state_DEFINED
# define gs_imager_state_DEFINED
typedef struct gs_imager_state_s gs_imager_state;
-
#endif
+
/* We need an abstract type for the image enumeration state, */
/* for begin[_typed]_image. */
#ifndef gx_image_enum_common_t_DEFINED
# define gx_image_enum_common_t_DEFINED
typedef struct gx_image_enum_common_s gx_image_enum_common_t;
-
#endif
/* Define the type for colors passed to the higher-level procedures. */
@@ -113,20 +165,28 @@ typedef struct gs_get_bits_params_s gs_get_bits_params_t;
#endif
/* Define the structure for device color capabilities. */
+typedef struct gx_device_anti_alias_info_s {
+ int text_bits; /* 1,2,4 */
+ int graphics_bits; /* ditto */
+} gx_device_anti_alias_info;
typedef struct gx_device_color_info_s {
int num_components; /* doesn't include alpha: */
- /* 0 = alpha only, 1 = gray only, */
- /* 3 = RGB, 4 = CMYK */
+ /* 0 = alpha only, 1 = gray only, */
+ /* 3 = RGB, 4 = CMYK */
int depth; /* # of bits per pixel */
gx_color_value max_gray; /* # of distinct gray levels -1 */
gx_color_value max_color; /* # of distinct color levels -1 */
- /* (only relevant if num_comp. > 1) */
+ /* (only relevant if num_comp. > 1) */
gx_color_value dither_grays; /* size of gray ramp for dithering */
gx_color_value dither_colors; /* size of color cube ditto */
- /* (only relevant if num_comp. > 1) */
+ /* (only relevant if num_comp. > 1) */
+ gx_device_anti_alias_info anti_alias;
} gx_device_color_info;
-#define dci_values(nc,depth,mg,mc,dg,dc) { nc, depth, mg, mc, dg, dc }
+#define dci_alpha_values(nc,depth,mg,mc,dg,dc,ta,ga)\
+ { nc, depth, mg, mc, dg, dc, { ta, ga } }
+#define dci_values(nc,depth,mg,mc,dg,dc)\
+ dci_alpha_values(nc, depth, mg, mc, dg, dc, 1, 1)
#define dci_std_color(color_bits)\
dci_values(\
(color_bits == 32 ? 4 : color_bits > 1 ? 3 : 1),\
@@ -206,9 +266,14 @@ typedef struct gx_device_cached_colors_s {
const char *dname; /* the device name */\
gs_memory_t *memory; /* (0 iff static prototype) */\
gs_memory_type_ptr_t stype; /* memory manager structure type, */\
- /* 0 iff static prototype */\
- rc_header rc; /* reference count from gstates, */\
- /* +1 if not internal device */\
+ /* may be 0 if static prototype */\
+ bool stype_is_dynamic; /* if true, free the stype when */\
+ /* freeing the device */\
+ void (*finalize)(P1(gx_device *)); /* finalization to execute */\
+ /* before closing device, if any */\
+ rc_header rc; /* reference count from gstates */\
+ /* and targets, +1 if retained */\
+ bool retained; /* true if retained */\
bool is_open; /* true if device has been opened */\
int max_fill_band; /* limit on band size for fill, */\
/* must be 0 or a power of 2 */\
@@ -232,6 +297,7 @@ typedef struct gx_device_cached_colors_s {
int NumCopies;\
bool NumCopies_set;\
bool IgnoreNumCopies; /* if true, force num_copies = 1 */\
+ bool UseCIEColor; /* for PS LL3 */\
gx_page_device_procs page_procs; /* must be last */\
/* end of std_device_body */\
gx_device_procs procs /* object procedures */
@@ -274,7 +340,6 @@ typedef struct gx_device_cached_colors_s {
#ifndef gs_param_list_DEFINED
# define gs_param_list_DEFINED
typedef struct gs_param_list_s gs_param_list;
-
#endif
/*
@@ -420,13 +485,15 @@ typedef struct gs_param_list_s gs_param_list;
#define dev_proc_get_page_device(proc)\
dev_t_proc_get_page_device(proc, gx_device)
- /* Added in release 3.20 */
+ /* Added in release 3.20, OBSOLETED in 5.65 */
#define dev_t_proc_get_alpha_bits(proc, dev_t)\
int proc(P2(dev_t *dev, graphics_object_type type))
#define dev_proc_get_alpha_bits(proc)\
dev_t_proc_get_alpha_bits(proc, gx_device)
+ /* Added in release 3.20 */
+
#define dev_t_proc_copy_alpha(proc, dev_t)\
int proc(P11(dev_t *dev, const byte *data, int data_x,\
int raster, gx_bitmap_id id, int x, int y, int width, int height,\
@@ -674,10 +741,6 @@ typedef struct gx_image_plane_s {
uint raster;
} gx_image_plane_t;
-#define image_enum_proc_plane_data(proc)\
- int proc(P4(gx_device *dev,\
- gx_image_enum_common_t *info, const gx_image_plane_t *planes,\
- int height))
#define gx_device_begin_image(dev, pis, pim, format, prect, pdcolor, pcpath, memory, pinfo)\
((*dev_proc(dev, begin_image))\
(dev, pis, pim, format, prect, pdcolor, pcpath, memory, pinfo))
@@ -692,8 +755,17 @@ typedef struct gx_image_plane_s {
*/
int gx_image_data(P5(gx_image_enum_common_t *info, const byte **planes,
int data_x, uint raster, int height));
+/*
+ * Solely for backward compatibility, gx_image_plane_data doesn't return
+ * rows_used.
+ */
int gx_image_plane_data(P3(gx_image_enum_common_t *info,
const gx_image_plane_t *planes, int height));
+int gx_image_plane_data_rows(P4(gx_image_enum_common_t *info,
+ const gx_image_plane_t *planes, int height,
+ int *rows_used));
+int gx_image_flush(P1(gx_image_enum_common_t *info));
+bool gx_image_planes_wanted(P2(const gx_image_enum_common_t *info, byte *wanted));
int gx_image_end(P2(gx_image_enum_common_t *info, bool draw_last));
#define gx_device_image_data(dev, info, planes, data_x, raster, height)\
@@ -703,24 +775,15 @@ int gx_image_end(P2(gx_image_enum_common_t *info, bool draw_last));
#define gx_device_end_image(dev, info, draw_last)\
gx_image_end(info, draw_last)
-/* A generic device procedure record. */
-struct gx_device_procs_s gx_device_proc_struct(gx_device);
-
/*
- * Define a procedure for setting up a memory device for buffering output
- * for a given device. This is only used by band devices, but we define it
- * here for convenience. The default implementation just calls
- * gs_make_mem_device. Possibly this should be a generic device
- * procedure....
+ * Get the anti-aliasing parameters for a device. This replaces the
+ * obsolete get_alpha_bits device procedure.
*/
-#ifndef gx_device_memory_DEFINED
-# define gx_device_memory_DEFINED
-typedef struct gx_device_memory_s gx_device_memory;
+#define gx_device_get_alpha_bits(dev, type)\
+ gx_default_get_alpha_bits(dev, type)
-#endif
-#define dev_proc_make_buffer_device(proc)\
- int proc(P4(gx_device_memory *, gx_device *, gs_memory_t *, bool))
-dev_proc_make_buffer_device(gx_default_make_buffer_device);
+/* A generic device procedure record. */
+struct gx_device_procs_s gx_device_proc_struct(gx_device);
/*
* Define unaligned analogues of the copy_xxx procedures.
@@ -790,7 +853,6 @@ extern_st(st_device_forward);
#ifndef gx_device_null_DEFINED
# define gx_device_null_DEFINED
typedef struct gx_device_null_s gx_device_null;
-
#endif
struct gx_device_null_s {
gx_device_forward_common;
@@ -807,9 +869,11 @@ extern_st(st_device_null);
#define st_device_null_max_ptrs st_device_forward_max_ptrs
/*
- * Initialize a just-allocated device from a prototype.
- * internal = true means initialize the reference count to 0,
- * false means initialize to 1.
+ * Initialize a just-allocated device from a prototype. If internal =
+ * false, the device is marked retained; if internal = true, the device is
+ * not marked retained. See the beginning of this file for more information
+ * about what this means. Normally, devices created for temporary use have
+ * internal = true (retained = false).
*/
void gx_device_init(P4(gx_device * dev, const gx_device * proto,
gs_memory_t * mem, bool internal));
@@ -817,8 +881,14 @@ void gx_device_init(P4(gx_device * dev, const gx_device * proto,
/* Make a null device. */
/* The gs_memory_t argument is 0 if the device is temporary and local, */
/* or the allocator that was used to allocate it if it is a real object. */
-void gs_make_null_device(P3(gx_device_null *, const gx_device *,
- gs_memory_t *));
+void gs_make_null_device(P3(gx_device_null *dev_null, gx_device *target,
+ gs_memory_t *mem));
+
+/* Set the target of a (forwarding) device. */
+void gx_device_set_target(P2(gx_device_forward *fdev, gx_device *target));
+
+/* Mark a device as retained or not retained. */
+void gx_device_retain(P2(gx_device *dev, bool retained));
/* Calculate the raster (number of bytes in a scan line), */
/* with byte or word padding. */
@@ -857,6 +927,9 @@ void gx_set_device_only(P2(gs_state *, gx_device *));
/* Close a device. */
int gs_closedevice(P1(gx_device *));
+/* "Free" a device locally allocated on the stack, by finalizing it. */
+void gx_device_free_local(P1(gx_device *));
+
/* ------ Device types (an unused concept right now) ------ */
#define dev_type_proc_initialize(proc)\
diff --git a/gs/src/gxdevice.h b/gs/src/gxdevice.h
index e004edf0c..b3f82129b 100644
--- a/gs/src/gxdevice.h
+++ b/gs/src/gxdevice.h
@@ -26,11 +26,22 @@
#include "gxdevcli.h"
#include "gsparam.h"
/*
- * Drivers still use gs_malloc and gs_free, so include the interface for
- * these. (Eventually they should go away.)
+ * Many drivers still use gs_malloc and gs_free, so include the interface
+ * for these. (Eventually they should go away.)
*/
#include "gsmalloc.h"
+/*
+ * NOTE: if you write code that creates device instances (either with
+ * gs_copydevice or by allocating them explicitly), allocates device
+ * instances as either local or static variables (actual instances, not
+ * pointers to instances), or sets the target of forwarding devices, please
+ * read the documentation in gxdevcli.h about memory management for devices.
+ * The rules for doing these things changed substantially in release 5.68,
+ * in a non-backward-compatible way, and unfortunately we could not find a
+ * way to make the compiler give an error at places that need changing.
+ */
+
/* ---------------- Auxiliary types and structures ---------------- */
/* Define default pages sizes. */
@@ -69,9 +80,9 @@
*/
#define std_device_part1_(devtype, ptr_procs, dev_name, stype, open_init)\
sizeof(devtype), ptr_procs, dev_name,\
- 0 /*memory*/, stype, { 0 } /*rc*/,\
- open_init() /*is_open, max_fill_band */
-/* color_info goes here */
+ 0 /*memory*/, stype, 0 /*stype_is_dynamic*/, 0 /*finalize*/,\
+ { 0 } /*rc*/, 0 /*retained*/, open_init() /*is_open, max_fill_band*/
+ /* color_info goes here */
/*
* The MetroWerks compiler has some bizarre bug that produces a spurious
* error message if the width and/or height are defined as 0 below,
@@ -84,7 +95,7 @@
{ 0, 0, 0, 0 }, 0/*false*/, { x_dpi, y_dpi }, { x_dpi, y_dpi }
/* offsets and margins go here */
#define std_device_part3_()\
- 0, 0, 1, 0/*false*/, 0/*false*/,\
+ 0, 0, 1, 0/*false*/, 0/*false*/, 0/*false*/,\
{ gx_default_install, gx_default_begin_page, gx_default_end_page }
/*
* We need a number of different variants of the std_device_ macro simply
@@ -108,11 +119,14 @@
margins_macro(),\
std_device_part3_()
-#define std_device_std_body(dtype, pprocs, dname, w, h, xdpi, ydpi)\
- std_device_body_with_macros_(dtype, pprocs, dname, 0,\
+#define std_device_std_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi)\
+ std_device_body_with_macros_(dtype, pprocs, dname, stype,\
w, h, xdpi, ydpi,\
open_init_closed, dci_black_and_white_, no_margins_)
+#define std_device_std_body(dtype, pprocs, dname, w, h, xdpi, ydpi)\
+ std_device_std_body_type(dtype, pprocs, dname, 0, w, h, xdpi, ydpi)
+
#define std_device_std_body_type_open(dtype, pprocs, dname, stype, w, h, xdpi, ydpi)\
std_device_body_with_macros_(dtype, pprocs, dname, stype,\
w, h, xdpi, ydpi,\
@@ -121,20 +135,28 @@
#define std_device_std_body_open(dtype, pprocs, dname, w, h, xdpi, ydpi)\
std_device_std_body_type_open(dtype, pprocs, dname, 0, w, h, xdpi, ydpi)
-#define std_device_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\
- std_device_part1_(dtype, pprocs, dname, 0, open_init_closed),\
+#define std_device_full_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\
+ std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\
dci_values(ncomp, depth, mg, mc, dg, dc),\
std_device_part2_(w, h, xdpi, ydpi),\
offset_margin_values(xoff, yoff, lm, bm, rm, tm),\
std_device_part3_()
-#define std_device_dci_type_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\
+#define std_device_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\
+ std_device_full_body_type(dtype, pprocs, dname, 0, w, h, xdpi, ydpi,\
+ ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)
+
+#define std_device_dci_alpha_type_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, ta, ga)\
std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\
- dci_values(ncomp, depth, mg, mc, dg, dc),\
+ dci_alpha_values(ncomp, depth, mg, mc, dg, dc, ta, ga),\
std_device_part2_(w, h, xdpi, ydpi),\
offset_margin_values(0, 0, 0, 0, 0, 0),\
std_device_part3_()
+#define std_device_dci_type_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\
+ std_device_dci_alpha_type_body(dtype, pprocs, dname, stype, w, h,\
+ xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, 1, 1)
+
#define std_device_dci_body(dtype, pprocs, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\
std_device_dci_type_body(dtype, pprocs, dname, 0,\
w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)
@@ -159,13 +181,17 @@
offset_margin_values(0, 0, 0, 0, 0, 0),\
std_device_part3_()
-#define std_device_std_color_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\
- std_device_part1_(dtype, pprocs, dname, 0, open_init_closed),\
+#define std_device_std_color_full_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\
+ std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\
dci_std_color(depth),\
std_device_part2_(w, h, xdpi, ydpi),\
offset_margin_values(xoff, yoff, lm, bm, rm, tm),\
std_device_part3_()
+#define std_device_std_color_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\
+ std_device_std_color_full_body_type(dtype, pprocs, dname, 0,\
+ w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)
+
/* ---------------- Default implementations ---------------- */
/* Default implementations of optional procedures. */
@@ -220,12 +246,14 @@ dev_proc_get_bits_rectangle(gx_no_get_bits_rectangle); /* gives error */
dev_proc_get_bits_rectangle(gx_default_get_bits_rectangle);
dev_proc_map_color_rgb_alpha(gx_default_map_color_rgb_alpha);
dev_proc_create_compositor(gx_no_create_compositor);
-/* default is for ordinary "leaf" devices, non_imaging is for */
+/* default is for ordinary "leaf" devices, null is for */
/* devices that only care about coverage and not contents. */
dev_proc_create_compositor(gx_default_create_compositor);
-dev_proc_create_compositor(gx_non_imaging_create_compositor);
+dev_proc_create_compositor(gx_null_create_compositor);
dev_proc_get_hardware_params(gx_default_get_hardware_params);
dev_proc_text_begin(gx_default_text_begin);
+/* BACKWARD COMPATIBILITY */
+#define gx_non_imaging_create_compositor gx_null_create_compositor
/* Color mapping routines for black-on-white, gray scale, true RGB, */
/* true CMYK, and 1-bit CMYK color. */
@@ -233,7 +261,6 @@ dev_proc_map_rgb_color(gx_default_b_w_map_rgb_color);
dev_proc_map_color_rgb(gx_default_b_w_map_color_rgb);
dev_proc_map_rgb_color(gx_default_gray_map_rgb_color);
dev_proc_map_color_rgb(gx_default_gray_map_color_rgb);
-dev_proc_map_rgb_color(gx_default_rgb_map_rgb_color);
dev_proc_map_color_rgb(gx_default_rgb_map_color_rgb);
#define gx_default_cmyk_map_cmyk_color cmyk_8bit_map_cmyk_color /*see below*/
/*
@@ -241,6 +268,7 @@ dev_proc_map_color_rgb(gx_default_rgb_map_color_rgb);
* that can be propagated through device pipelines and that color
* processing code can test for.
*/
+dev_proc_map_rgb_color(gx_default_rgb_map_rgb_color);
dev_proc_map_cmyk_color(cmyk_1bit_map_cmyk_color);
dev_proc_map_color_rgb(cmyk_1bit_map_color_rgb);
dev_proc_map_cmyk_color(cmyk_8bit_map_cmyk_color);
@@ -264,7 +292,7 @@ dev_proc_get_xfont_procs(gx_forward_get_xfont_procs);
dev_proc_get_xfont_device(gx_forward_get_xfont_device);
dev_proc_map_rgb_alpha_color(gx_forward_map_rgb_alpha_color);
dev_proc_get_page_device(gx_forward_get_page_device);
-dev_proc_get_alpha_bits(gx_forward_get_alpha_bits);
+#define gx_forward_get_alpha_bits gx_default_get_alpha_bits
dev_proc_copy_alpha(gx_forward_copy_alpha);
dev_proc_get_band(gx_forward_get_band);
dev_proc_copy_rop(gx_forward_copy_rop);
@@ -290,11 +318,6 @@ dev_proc_text_begin(gx_forward_text_begin);
/* ---------------- Implementation utilities ---------------- */
-/* Fill in the GC structure descriptor for a device. */
-/* This is only called during initialization. */
-void gx_device_make_struct_type(P2(gs_memory_struct_type_t *,
- const gx_device *));
-
/* Convert the device procedures to the proper form (see above). */
void gx_device_set_procs(P1(gx_device *));
@@ -311,6 +334,16 @@ void gx_device_forward_color_procs(P1(gx_device_forward *));
*/
void gx_device_copy_color_procs(P2(gx_device *dev, const gx_device *target));
+/* Get the black and white pixel values of a device. */
+gx_color_index gx_device_black(P1(gx_device *dev));
+#define gx_device_black_inline(dev)\
+ ((dev)->cached_colors.black != gx_no_color_index ?\
+ gx_device_black(dev) : (dev)->cached_colors.black)
+gx_color_index gx_device_white(P1(gx_device *dev));
+#define gx_device_white_inline(dev)\
+ ((dev)->cached_colors.white != gx_no_color_index ?\
+ gx_device_white(dev) : (dev)->cached_colors.white)
+
/* Clear the black/white pixel cache. */
void gx_device_decache_colors(P1(gx_device *dev));
@@ -376,13 +409,13 @@ dev_proc_output_page(gx_finish_output_page);
END
#define fit_fill_w(dev, x, w)\
BEGIN\
- if ( w > dev->width - x )\
- w = dev->width - x;\
+ if ( w > (dev)->width - x )\
+ w = (dev)->width - x;\
END
#define fit_fill_h(dev, y, h)\
BEGIN\
- if ( h > dev->height - y )\
- h = dev->height - y;\
+ if ( h > (dev)->height - y )\
+ h = (dev)->height - y;\
END
#define fit_fill_xywh(dev, x, y, w, h)\
BEGIN\
@@ -417,8 +450,8 @@ dev_proc_output_page(gx_finish_output_page);
if ( y < 0 )\
h += y, data -= y * raster, id = gx_no_bitmap_id, y = 0;\
}\
- if ( w > dev->width - x )\
- w = dev->width - x;\
+ if ( w > (dev)->width - x )\
+ w = (dev)->width - x;\
END
/*
* Clip all edges, and return from the procedure if the result is empty.
@@ -426,8 +459,8 @@ dev_proc_output_page(gx_finish_output_page);
#define fit_copy(dev, data, data_x, raster, id, x, y, w, h)\
BEGIN\
fit_copy_xyw(dev, data, data_x, raster, id, x, y, w, h);\
- if ( h > dev->height - y )\
- h = dev->height - y;\
+ if ( h > (dev)->height - y )\
+ h = (dev)->height - y;\
if ( w <= 0 || h <= 0 )\
return 0;\
END
diff --git a/gs/src/gxdevmem.h b/gs/src/gxdevmem.h
index fa8deb345..fdd6955d1 100644
--- a/gs/src/gxdevmem.h
+++ b/gs/src/gxdevmem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,8 @@
#ifndef gxdevmem_INCLUDED
# define gxdevmem_INCLUDED
+#include "gxrplane.h"
+
/*
* A 'memory' device is essentially a stored bitmap.
* There are several different kinds: 1-bit black and white,
@@ -39,27 +41,70 @@
* to copy_mono or copy_color operations. This is not true of word-oriented
* memory devices, which are provided only in response to a request by
* a customer with their own image processing library that uses this format.
+ *
+ * In addition to the device structure itself, memory devices require two
+ * other pieces of storage: the bitmap, and a table of pointers to the scan
+ * lines of the bitmap. Clients have several options for allocating these:
+ *
+ * 1) Set bitmap_memory to an allocator before opening the device.
+ * With this option, opening the device allocates the bitmap and the
+ * line pointer table (contiguously), and closing the device frees
+ * them.
+ *
+ * 2) Set line_pointer_memory to an allocator, base to the base address
+ * of the bitmap, and raster to the length of each scan line (distance
+ * from one scan line to the next) before opening the device. With
+ * this option, opening the device allocates the line table, but not
+ * the bitmap; closing the device frees the table.
+ *
+ * 3) Set line_pointer_memory but not base or raster. Opening /
+ * closing the device will allocate / free the line pointer table, but
+ * the client must set the pointers with a subsequent call of
+ * gdev_mem_set_line_ptrs.
+ *
+ * 4) Set neither _memory field. In this case, it's up to the client
+ * to call gdev_mem_set_line_ptrs and to manage storage for the
+ * line pointers and the bitmap.
+ *
+ * In cases (2) through (4), it is the client's responsibility to set
+ * foreign_bits (and foreign_line_pointers, if the line pointers are not
+ * contiguous with the bits) to tell the GC whether to trace the pointers.
+ * By default, anything allocated by bitmap_memory or line_pointer_memory is
+ * assumed GC'able (i.e., case (1) assumes that the bits + line pointers are
+ * GC'able, and cases (2) and (3) assume that the line pointers are GC'able,
+ * but not the bits), but the client can change the foreign_* flag(s) after
+ * opening the device if this is not the case.
*/
#ifndef gx_device_memory_DEFINED
# define gx_device_memory_DEFINED
typedef struct gx_device_memory_s gx_device_memory;
-
#endif
struct gx_device_memory_s {
gx_device_forward_common; /* (see gxdevice.h) */
- gs_matrix initial_matrix; /* the initial transformation */
- uint raster; /* bytes per scan line, */
- /* filled in by 'open' */
- bool foreign_bits; /* if true, bits are not in */
- /* GC-able space */
+ /*
+ * The following may be set by the client before or just after
+ * opening the device. See above.
+ */
+ uint raster; /* bytes per scan line */
byte *base;
- byte **line_ptrs; /* scan line pointers */
#define scan_line_base(dev,y) ((dev)->line_ptrs[y])
- /* If the bitmap_memory pointer is non-zero, it is used for */
- /* allocating the bitmap when the device is opened, */
- /* and freeing it when the device is closed. */
- gs_memory_t *bitmap_memory;
+ gs_memory_t *bitmap_memory; /* allocator for bits + line pointers */
+ bool foreign_bits; /* if true, bits are not in GC-able space */
+ gs_memory_t *line_pointer_memory; /* allocate for line pointers */
+ bool foreign_line_pointers; /* if true, line_ptrs are not in GC-able space */
+ /*
+ * The following are only used for planar devices. num_planes == 0
+ * means this is a chunky device. Note that for planar devices, we
+ * require color_info.depth = the sum of the individual plane depths.
+ */
+ int num_planes;
+ gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ /*
+ * End of client-initializable fields.
+ */
+ gs_matrix initial_matrix; /* the initial transformation */
+ byte **line_ptrs; /* scan line pointers */
/* Following is used for mapped color, */
/* including 1-bit devices (to specify polarity). */
gs_const_string palette; /* RGB triples */
@@ -78,20 +123,27 @@ struct gx_device_memory_s {
int mapped_height; /* # of Y values mapped to buffer */
int mapped_start; /* local Y value corresponding to mapped_y */
gx_color_index save_color; /* last (only) color displayed */
+ /* Following are used only for planar devices. */
+ int plane_depth; /* if non-zero, depth of all planes */
};
extern_st(st_device_memory);
#define public_st_device_memory() /* in gdevmem.c */\
- gs_public_st_composite(st_device_memory, gx_device_memory,\
- "gx_device_memory", device_memory_enum_ptrs, device_memory_reloc_ptrs)
+ gs_public_st_composite_use_final(st_device_memory, gx_device_memory,\
+ "gx_device_memory", device_memory_enum_ptrs, device_memory_reloc_ptrs,\
+ gx_device_finalize)
#define st_device_memory_max_ptrs (st_device_forward_max_ptrs + 2)
#define mem_device_init_private\
- { identity_matrix_body }, /* initial matrix (filled in) */\
- 0, /* raster (filled in) */\
+ 0, /* raster */\
+ (byte *)0, /* base */\
+ 0, /* bitmap_memory */\
true, /* foreign_bits (default) */\
- (byte *)0, /* base (filled in) */\
+ 0, /* line_pointer_memory */\
+ true, /* foreign_line_pointers (default) */\
+ 0, /* num_planes (default) */\
+ { { 0 } }, /* planes (only used for planar) */\
+ { identity_matrix_body }, /* initial matrix (filled in) */\
(byte **)0, /* line_ptrs (filled in by mem_open) */\
- 0, /* bitmap_memory */\
{ (byte *)0, 0 }, /* palette (filled in for color) */\
{ gx_no_color_index }, /* color24 */\
{ 0, 0 }, 0, /* scale, log2_alpha_bits */\
@@ -99,15 +151,24 @@ extern_st(st_device_memory);
gx_no_color_index /* save_color */
/*
- * Memory devices may have special setup requirements.
- * In particular, it may not be obvious how much space to allocate
- * for the bitmap. Here is the routine that computes this
- * from the width and height.
+ * Memory devices may have special setup requirements. In particular, it
+ * may not be obvious how much space to allocate for the bitmap. Here is
+ * the routine that computes this from the width and height. Note that this
+ * size includes both the bitmap and the line pointers.
*/
-ulong gdev_mem_data_size(P3(const gx_device_memory *, int, int));
+/* bits only */
+ulong gdev_mem_bits_size(P3(const gx_device_memory *mdev, int width,
+ int height));
+/* line pointers only */
+ulong gdev_mem_line_ptrs_size(P3(const gx_device_memory *mdev, int width,
+ int height));
+/* bits + line pointers */
+ulong gdev_mem_data_size(P3(const gx_device_memory *mdev, int width,
+ int height));
#define gdev_mem_bitmap_size(mdev)\
gdev_mem_data_size(mdev, (mdev)->width, (mdev)->height)
+
/*
* Do the inverse computation: given the device width and a buffer size,
* compute the maximum height.
@@ -115,7 +176,7 @@ ulong gdev_mem_data_size(P3(const gx_device_memory *, int, int));
int gdev_mem_max_height(P3(const gx_device_memory *, int, ulong));
/*
- * Compute the raster (data bytes per line) similarly.
+ * Compute the standard raster (data bytes per line) similarly.
*/
#define gdev_mem_raster(mdev)\
gx_device_raster((const gx_device *)(mdev), true)
@@ -152,6 +213,23 @@ void gs_make_mem_alpha_device(P4(gx_device_memory * adev, gs_memory_t * mem,
*/
int gdev_mem_open_scan_lines(P2(gx_device_memory *mdev, int setup_height));
+/*
+ * Initialize the line pointers of a memory device. base and/or line_ptrs
+ * may be NULL, in which case the value already stored in the device is
+ * used; if base is NULL, raster is also ignored and the existing value is
+ * used. Note that this takes raster and setup_height arguments.
+ * If the base is not NULL and the device is planar, all planes must have
+ * the same depth, since otherwise a single raster value is not sufficient.
+ *
+ * Note that setup_height may be less than height. In this case, for
+ * planar devices, only setup_height * num_planes line pointers are set,
+ * in the expectation that the device's height will be reset to
+ * setup_height.
+ */
+int gdev_mem_set_line_ptrs(P5(gx_device_memory *mdev,
+ byte *base, int raster, byte **line_ptrs,
+ int setup_height));
+
/* Define whether a monobit memory device is inverted (black=1). */
void gdev_mem_mono_set_inverted(P2(gx_device_memory * mdev, bool black_is_1));
diff --git a/gs/src/gxdht.h b/gs/src/gxdht.h
index 90fdd8121..168b533f3 100644
--- a/gs/src/gxdht.h
+++ b/gs/src/gxdht.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -91,18 +91,23 @@ void gx_compute_cell_values(P1(gx_ht_cell_params_t *));
/*
* The whitening order is represented by a pair of arrays.
- * The levels array contains an integer (an index into the bits array)
+ * The levels array contains an integer (an index into the bit_data array)
* for each distinct halftone level, indicating how many pixels should be
* whitened for that level; levels[0] = 0, levels[i] <= levels[i+1], and
- * levels[num_levels-1] <= num_bits.
- * The bits array contains an (offset,mask) pair for each pixel in the tile.
- * bits[i].offset is the (properly aligned) byte index of a pixel
- * in the tile; bits[i].mask is the mask to be or'ed into this byte and
- * following ones. This is arranged so it will work properly on
+ * levels[num_levels-1] <= num_bits. The bit_data array contains data to
+ * specify which bits should be set for each level: it has several
+ * different representations depending on space/time tradeoffs.
+ *
+ * The default bit_data representation is an (offset,mask) pair for each
+ * pixel in the tile. bits[i].offset is the (properly aligned) byte index
+ * of a pixel in the tile; bits[i].mask is the mask to be or'ed into this
+ * byte and following ones. This is arranged so it will work properly on
* either big- or little-endian machines, and with different mask widths.
*/
-/* The mask width must be at least as wide as uint, */
-/* and must not be wider than the width implied by align_bitmap_mod. */
+/*
+ * The mask width must be at least as wide as uint,
+ * and must not be wider than the width implied by align_bitmap_mod.
+ */
typedef uint ht_mask_t;
#define ht_mask_bits (sizeof(ht_mask_t) * 8)
@@ -148,12 +153,39 @@ typedef ht_mask_t ht_sample_t;
* See gxbitmap.h for more details about strip halftones.
*/
typedef struct gx_ht_cache_s gx_ht_cache;
-
#ifndef gx_ht_order_DEFINED
# define gx_ht_order_DEFINED
typedef struct gx_ht_order_s gx_ht_order;
-
#endif
+#ifndef gx_ht_tile_DEFINED
+# define gx_ht_tile_DEFINED
+typedef struct gx_ht_tile_s gx_ht_tile;
+#endif
+typedef struct gx_ht_order_procs_s {
+
+ /* Define the size of each element of bit_data. */
+
+ uint bit_data_elt_size;
+
+ /* Construct the order from the threshold array. */
+ /* Note that for 16-bit threshold values (not supported yet), */
+ /* each value is 2 bytes in big-endian order (Adobe spec). */
+
+ int (*construct_order)(P2(gx_ht_order *order, const byte *thresholds));
+
+ /* Update a halftone cache tile to match this order. */
+
+ int (*render)(P3(gx_ht_tile *tile, int new_bit_level,
+ const gx_ht_order *order));
+
+} gx_ht_order_procs_t;
+/*
+ * Define the procedure vectors for the supported implementations
+ * (in gxhtbit.c).
+ */
+extern const gx_ht_order_procs_t ht_order_procs_table[2];
+#define ht_order_procs_default ht_order_procs_table[0] /* bit_data is gx_ht_bit[] */
+#define ht_order_procs_short ht_order_procs_table[1] /* bit_data is ushort[] */
struct gx_ht_order_s {
gx_ht_cell_params_t params; /* parameters defining the cells */
ushort width;
@@ -164,9 +196,11 @@ struct gx_ht_order_s {
ushort orig_shift;
uint full_height;
uint num_levels; /* = levels size */
- uint num_bits; /* = bits size = width * height */
+ uint num_bits; /* = countof(bit_data) = width * height */
+ const gx_ht_order_procs_t *procs;
+ gs_memory_t *data_memory; /* for levels and bit_data, may be 0 */
uint *levels;
- gx_ht_bit *bits;
+ void *bit_data;
gx_ht_cache *cache; /* cache to use */
gx_transfer_map *transfer; /* TransferFunction or 0 */
};
@@ -181,8 +215,8 @@ struct gx_ht_order_s {
/* We only export st_ht_order for use in st_screen_enum. */
extern_st(st_ht_order);
#define public_st_ht_order() /* in gsht.c */\
- gs_public_st_ptrs4(st_ht_order, gx_ht_order, "gx_ht_order",\
- ht_order_enum_ptrs, ht_order_reloc_ptrs, levels, bits, cache, transfer)
+ gs_public_st_composite(st_ht_order, gx_ht_order, "gx_ht_order",\
+ ht_order_enum_ptrs, ht_order_reloc_ptrs)
#define st_ht_order_max_ptrs 4
/*
@@ -199,9 +233,10 @@ extern_st(st_ht_order);
* because they are needed for setcolorscreen.
*
* NOTE: it is assumed that all subsidiary structures of device halftones
- * (the components array, and the bits, levels, cache, and transfer members
- * of any gx_ht_orders, both the default order and any component orders) are
- * allocated with the same allocator as the device halftone itself.
+ * (the components array, and the bit_data, levels, cache, and transfer
+ * members of any gx_ht_orders, both the default order and any component
+ * orders) are allocated with the same allocator as the device halftone
+ * itself.
*/
typedef struct gx_ht_order_component_s {
gx_ht_order corder;
@@ -223,7 +258,6 @@ extern_st(st_ht_order_component_element);
#ifndef gx_device_halftone_DEFINED
# define gx_device_halftone_DEFINED
typedef struct gx_device_halftone_s gx_device_halftone;
-
#endif
/*
@@ -258,6 +292,9 @@ extern_st(st_device_halftone);
device_halftone_reloc_ptrs, st_ht_order, order, components)
#define st_device_halftone_max_ptrs (st_ht_order_max_ptrs + 1)
+/* Complete a halftone order defined by a threshold array. */
+void gx_ht_complete_threshold_order(P1(gx_ht_order *porder));
+
/* Release a gx_device_halftone by freeing its components. */
/* (Don't free the gx_device_halftone itself.) */
void gx_device_halftone_release(P2(gx_device_halftone * pdht,
diff --git a/gs/src/gxdhtres.h b/gs/src/gxdhtres.h
new file mode 100644
index 000000000..f66f52823
--- /dev/null
+++ b/gs/src/gxdhtres.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definitions for precompiled halftone resources */
+
+#ifndef gxdhtres_INCLUDED
+# define gxdhtres_INCLUDED
+
+/*
+ * Precompiled halftones generated by genht #include this file.
+ */
+#ifndef gx_device_halftone_resource_DEFINED
+# define gx_device_halftone_resource_DEFINED
+typedef struct gx_device_halftone_resource_s gx_device_halftone_resource_t;
+#endif
+
+struct gx_device_halftone_resource_s {
+ const char *rname;
+ int HalftoneType;
+ int Width;
+ int Height;
+ int num_levels;
+ const unsigned int *levels;
+ const void *bit_data;
+ int elt_size;
+};
+
+#endif /* gxdhtres_INCLUDED */
diff --git a/gs/src/gxdither.c b/gs/src/gxdither.c
index b69c04b91..ee2300130 100644
--- a/gs/src/gxdither.c
+++ b/gs/src/gxdither.c
@@ -79,7 +79,7 @@ const gx_color_value *const fc_color_quo[8] = {
/* Render a gray, possibly by halftoning. */
int
gx_render_device_gray(frac gray, gx_color_value alpha, gx_device_color * pdevc,
- gx_device * dev, const gx_device_halftone * pdht,
+ gx_device * dev, gx_device_halftone * pdht,
const gs_int_point * ht_phase)
{
bool cmyk = dev->color_info.num_components == 4;
@@ -118,7 +118,7 @@ gx_render_device_gray(frac gray, gx_color_value alpha, gx_device_color * pdevc,
/* The following should be a conditional expression, */
/* but the DECStation 3100 Ultrix 4.3 compiler */
/* generates bad code for it. */
-#define set_color_lum(col, lum)\
+#define SET_COLOR_LUM(col, lum)\
if ( cmyk )\
col = gx_map_cmyk_color(dev, 0, 0, 0,\
gx_max_color_value - lum);\
@@ -126,7 +126,7 @@ gx_render_device_gray(frac gray, gx_color_value alpha, gx_device_color * pdevc,
col = gx_map_rgb_color(dev, lum, lum, lum);\
else\
col = gx_map_rgb_alpha_color(dev, lum, lum, lum, alpha)
- set_color_lum(color1, lum);
+ SET_COLOR_LUM(color1, lum);
if_debug5('c', "[c]gray=0x%x --> (%d+%d/%lu)/%d\n",
(unsigned)gray, v, level, hsize, max_value + 1);
if (level == 0) { /* Close enough to a pure color, */
@@ -138,7 +138,7 @@ gx_render_device_gray(frac gray, gx_color_value alpha, gx_device_color * pdevc,
v++;
lum = fractional_color(v, max_value);
- set_color_lum(color2, lum);
+ SET_COLOR_LUM(color2, lum);
color_set_binary_halftone(pdevc, pdht,
color1, color2, level);
color_set_phase_mod(pdevc, ht_phase->x, ht_phase->y,
@@ -146,6 +146,7 @@ gx_render_device_gray(frac gray, gx_color_value alpha, gx_device_color * pdevc,
pdht->order.full_height);
return 1;
}
+#undef SET_COLOR_LUM
}
}
@@ -234,12 +235,10 @@ private const unsigned short lum_w[16] =
* white is ignored. If we are rendering CMYK, red/green/blue/white are
* actually cyan/magenta/yellow/black.
*/
-private int gx_reduce_colored_dither(P3(gx_device_color *pdevc,
- gx_device *dev, bool cmyk));
int
gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
- gx_color_value alpha, gx_device_color * pdevc, gx_device * dev,
- const gx_device_halftone * pdht, const gs_int_point * ht_phase)
+ gx_color_value alpha, gx_device_color * pdevc, gx_device * dev,
+ gx_device_halftone * pdht, const gs_int_point * ht_phase)
{
uint max_value = dev->color_info.dither_colors - 1;
uint num_levels = pdht->order.num_levels;
@@ -247,14 +246,14 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
uint r, g, b, w;
gx_color_value vr, vg, vb, vw;
-#define map_color_rgb()\
+#define MAP_COLOR_RGB()\
(alpha == gx_max_color_value ?\
gx_map_rgb_color(dev, vr, vg, vb) :\
gx_map_rgb_alpha_color(dev, vr, vg, vb, alpha))
-#define map_color_cmyk()\
+#define MAP_COLOR_CMYK()\
gx_map_cmyk_color(dev, vr, vg, vb, vw)
-#define map_color()\
- (cmyk ? map_color_cmyk() : map_color_rgb())
+#define MAP_COLOR()\
+ (cmyk ? MAP_COLOR_CMYK() : MAP_COLOR_RGB())
/* Compute the quotient and remainder of each color component */
/* with the actual number of available colors. */
@@ -280,20 +279,20 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
default:
{
ulong want_r, want_g, want_b, want_w;
- want_r = (ulong) max_value *red;
+ want_r = (ulong) max_value * red;
r = frac_1_quo(want_r);
rem_r = frac_1_rem(want_r, r);
- want_g = (ulong) max_value *green;
+ want_g = (ulong) max_value * green;
g = frac_1_quo(want_g);
rem_g = frac_1_rem(want_g, g);
- want_b = (ulong) max_value *blue;
+ want_b = (ulong) max_value * blue;
b = frac_1_quo(want_b);
rem_b = frac_1_rem(want_b, b);
- want_w = (ulong) max_value *white;
+ want_w = (ulong) max_value * white;
w = frac_1_quo(want_w);
rem_w = frac_1_rem(want_w, w);
}
@@ -305,7 +304,7 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
vg = fractional_color(g, max_value);
vb = fractional_color(b, max_value);
vw = fractional_color(w, max_value);
- color_set_pure(pdevc, map_color());
+ color_set_pure(pdevc, MAP_COLOR());
return 0;
}
if_debug12('c', "[c]rgbw=0x%x,0x%x,0x%x,0x%x -->\n %x+0x%x,%x+0x%x,%x+0x%x,%x+0x%x -->\n",
@@ -319,22 +318,23 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
/* Someone went to the trouble of setting different */
/* screens for the different components. */
/* Use the slow, general colored halftone algorithm. */
-#define rgb_rem(rem_v, i)\
+#define RGB_REM(rem_v, i)\
(rem_v * (ulong)(pdht->components[pdht->color_indices[i]].corder.num_levels) / frac_1)
- uint lr = rgb_rem(rem_r, 0), lg = rgb_rem(rem_g, 1), lb = rgb_rem(rem_b, 2);
+ uint lr = RGB_REM(rem_r, 0), lg = RGB_REM(rem_g, 1),
+ lb = RGB_REM(rem_b, 2);
if (cmyk)
color_set_cmyk_halftone(pdevc, pdht, r, lr, g, lg, b, lb,
- w, rgb_rem(rem_w, 3));
+ w, RGB_REM(rem_w, 3));
else
color_set_rgb_halftone(pdevc, pdht, r, lr, g, lg, b, lb, alpha);
-#undef rgb_rem
+#undef RGB_REM
color_set_phase_mod(pdevc, ht_phase->x, ht_phase->y,
pdht->lcm_width, pdht->lcm_height);
if (!(pdevc->colors.colored.plane_mask &
(pdevc->colors.colored.plane_mask - 1))) {
/* We can reduce this color to a binary halftone or pure color. */
- return gx_reduce_colored_dither(pdevc, dev, cmyk);
+ return gx_reduce_colored_halftone(pdevc, dev, cmyk);
}
return 1;
}
@@ -380,9 +380,9 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
else
adjust_w = 1;
vw = fractional_color(w, max_value);
- color1 = map_color_cmyk();
+ color1 = MAP_COLOR_CMYK();
} else
- color1 = map_color_rgb();
+ color1 = MAP_COLOR_RGB();
/*
* Dot the color with each axis to find the best one of 15;
@@ -483,9 +483,9 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
if (diagc & DIAG_W)
w += adjust_w;
vw = fractional_color(w, max_value);
- color2 = map_color_cmyk();
+ color2 = MAP_COLOR_CMYK();
} else
- color2 = map_color_rgb();
+ color2 = MAP_COLOR_RGB();
if (level == num_levels) { /* This can only happen through rounding.... */
color_set_pure(pdevc, color2);
code = 0;
@@ -510,8 +510,8 @@ gx_render_device_color(frac red, frac green, frac blue, frac white, bool cmyk,
}
/* Reduce a colored halftone to a binary halftone or pure color. */
-private int
-gx_reduce_colored_dither(gx_device_color *pdevc, gx_device *dev, bool cmyk)
+int
+gx_reduce_colored_halftone(gx_device_color *pdevc, gx_device *dev, bool cmyk)
{
int planes = pdevc->colors.colored.plane_mask;
gx_color_value max_color = dev->color_info.dither_colors - 1;
diff --git a/gs/src/gxdither.h b/gs/src/gxdither.h
index 2049503cb..145c6b331 100644
--- a/gs/src/gxdither.h
+++ b/gs/src/gxdither.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,10 +22,11 @@
#ifndef gxdither_INCLUDED
# define gxdither_INCLUDED
+#include "gxfrac.h"
+
#ifndef gx_device_halftone_DEFINED
# define gx_device_halftone_DEFINED
typedef struct gx_device_halftone_s gx_device_halftone;
-
#endif
/*
@@ -38,7 +39,7 @@ typedef struct gx_device_halftone_s gx_device_halftone;
/* Return 0 if complete, 1 if caller must do gx_color_load, <0 on error. */
int gx_render_device_gray(P6(frac gray, gx_color_value alpha,
gx_device_color * pdevc, gx_device * dev,
- const gx_device_halftone * dev_ht,
+ gx_device_halftone * dev_ht,
const gs_int_point * ht_phase));
#define gx_render_gray_alpha(gray, alpha, pdevc, pis, dev, select)\
@@ -52,7 +53,7 @@ int gx_render_device_gray(P6(frac gray, gx_color_value alpha,
int gx_render_device_color(P10(frac red, frac green, frac blue, frac white,
bool cmyk, gx_color_value alpha,
gx_device_color * pdevc, gx_device * dev,
- const gx_device_halftone * pdht,
+ gx_device_halftone * pdht,
const gs_int_point * ht_phase));
#define gx_render_color_alpha(r, g, b, w, a, cmyk, pdevc, pis, dev, select)\
@@ -67,4 +68,11 @@ int gx_render_device_color(P10(frac red, frac green, frac blue, frac white,
#define gx_render_rgb_alpha(r, g, b, a, pdevc, pis, dev, select)\
gx_render_color_alpha(r, g, b, frac_0, a, false, pdevc, pis, dev, select)
+/*
+ * Reduce a colored halftone with 0 or 1 varying plane(s) to a pure color
+ * or a binary halftone.
+ */
+int gx_reduce_colored_halftone(P3(gx_device_color *pdevc, gx_device *dev,
+ bool cmyk));
+
#endif /* gxdither_INCLUDED */
diff --git a/gs/src/gxfcache.h b/gs/src/gxfcache.h
index 5b9f0409b..dc54a4e1a 100644
--- a/gs/src/gxfcache.h
+++ b/gs/src/gxfcache.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -179,7 +179,7 @@ struct cached_char_s {
*/
#define align_cached_char_mod align_cached_bits_mod
#define sizeof_cached_char\
- round_up(sizeof(cached_char), align_cached_char_mod)
+ ROUND_UP(sizeof(cached_char), align_cached_char_mod)
#define cc_bits(cc) ((byte *)(cc) + sizeof_cached_char)
#define cc_const_bits(cc) ((const byte *)(cc) + sizeof_cached_char)
diff --git a/gs/src/gxfcmap.h b/gs/src/gxfcmap.h
index 747d7c2eb..5154da9eb 100644
--- a/gs/src/gxfcmap.h
+++ b/gs/src/gxfcmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,6 +27,23 @@
#include "gsfcmap.h"
#include "gsuid.h"
+/* Define the structure for CIDSystemInfo. */
+typedef struct gs_cid_system_info_s {
+ gs_const_string Registry;
+ gs_const_string Ordering;
+ int Supplement;
+} gs_cid_system_info;
+/*extern_st(st_cid_system_info);*/
+extern_st(st_cid_system_info_element);
+#define private_st_cid_system_info() /* in gsfcmap.c */\
+ gs_public_st_const_strings2(st_cid_system_info, gs_cid_system_info,\
+ "gs_cid_system_info", cid_si_enum_ptrs, cid_si_reloc_ptrs,\
+ Registry, Ordering)
+#define public_st_cid_system_info_element() /* in gsfcmap.c */\
+ gs_public_st_element(st_cid_system_info_element, gs_cid_system_info,\
+ "gs_cid_system_info[]", cid_si_elt_enum_ptrs, cid_si_elt_reloc_ptrs,\
+ st_cid_system_info)
+
/*
* The main body of data in a CMap is two code maps, one for defined
* characters, one for notdefs. Each code map is a multi-level tree,
@@ -77,8 +94,9 @@ extern_st(st_code_map_element);
/* A CMap proper is relatively simple. */
struct gs_cmap_s {
- gs_cid_system_info CIDSystemInfo; /* must be first */
gs_uid uid;
+ gs_cid_system_info *CIDSystemInfo;
+ int num_fonts;
int WMode;
gx_code_map def; /* defined characters (cmap_subtree) */
gx_code_map notdef; /* notdef characters (cmap_subtree) */
@@ -86,10 +104,10 @@ struct gs_cmap_s {
void *mark_glyph_data; /* closure data */
};
-/*extern_st(st_cmap); */
+extern_st(st_cmap);
#define public_st_cmap() /* in gsfcmap.c */\
- gs_public_st_suffix_add4(st_cmap, gs_cmap, "gs_cmap",\
- cmap_enum_ptrs, cmap_reloc_ptrs, st_cid_system_info,\
+ gs_public_st_ptrs5(st_cmap, gs_cmap, "gs_cmap",\
+ cmap_enum_ptrs, cmap_reloc_ptrs, CIDSystemInfo,\
uid.xvalues, def.data.subtree, notdef.data.subtree, mark_glyph_data)
#endif /* gxfcmap_INCLUDED */
diff --git a/gs/src/gxfixed.h b/gs/src/gxfixed.h
index fc34566c4..44d4b464f 100644
--- a/gs/src/gxfixed.h
+++ b/gs/src/gxfixed.h
@@ -136,19 +136,15 @@ typedef ulong ufixed; /* only used in a very few places */
/*
* Define a procedure for computing a * b / c when b and c are non-negative,
* b < c, and a * b exceeds (or might exceed) the capacity of a long.
+ * Note that this procedure takes the floor, rather than truncating
+ * towards zero, if a < 0: this ensures 0 <= R < c, where R is the remainder.
+ *
* It's really annoying that C doesn't provide any way to get at
* the double-length multiply/divide instructions that almost all hardware
* provides....
*/
-
-#if USE_FPU_FIXED
fixed fixed_mult_quo(P3(fixed A, fixed B, fixed C));
-#else
-# define fixed_mult_quo(fixed_a, fixed_b, fixed_c)\
- ((fixed)floor((double)(fixed_a) * (fixed_b) / (fixed_c)))
-#endif
-
/*
* Transforming coordinates involves multiplying two floats, or a float
* and a double, and then converting the result to a fixed. Since this
@@ -159,38 +155,55 @@ fixed fixed_mult_quo(P3(fixed A, fixed B, fixed C));
*/
/*
- * set_fmul2fixed_vars(R, FA, FB, dtemp) computes R = FA * FB:
- * R is a fixed, FA and FB are floats (not doubles), and
- * dtemp is a temporary double.
- * set_dfmul2fixed_vars(R, DA, FB, dtemp) computes R = DA * FB:
- * R is a fixed, DA is a double, FB is a float, and
- * dtemp is a temporary double.
- * R, FA, FB, and DA must be variables, not expressions.
+ * The macros all use R for the (fixed) result, FB for the second (float)
+ * operand, and dtemp for a temporary double variable. The work is divided
+ * between the two macros of each set in order to avoid bogus "possibly
+ * uninitialized variable" messages from slow-witted compilers.
+ *
+ * For the case where the first operand is a float (FA):
+ * code = CHECK_FMUL2FIXED_VARS(R, FA, FB, dtemp);
+ * if (code < 0) ...
+ * FINISH_FMUL2FIXED_VARS(R, dtemp);
+ *
+ * For the case where the first operand is a double (DA):
+ * code = CHECK_DFMUL2FIXED_VARS(R, DA, FB, dtemp);
+ * if (code < 0) ...;
+ * FINISH_DFMUL2FIXED_VARS(R, dtemp);
*/
#if USE_FPU_FIXED && arch_sizeof_short == 2
-int set_fmul2fixed_(P3(fixed *, long, long));
-#define set_fmul2fixed_vars(vr,vfa,vfb,dtemp)\
+int set_fmul2fixed_(P3(fixed *, long, long));
+#define CHECK_FMUL2FIXED_VARS(vr, vfa, vfb, dtemp)\
set_fmul2fixed_(&vr, *(long *)&vfa, *(long *)&vfb)
-int set_dfmul2fixed_(P4(fixed *, ulong, long, long));
+#define FINISH_FMUL2FIXED_VARS(vr, dtemp)\
+ DO_NOTHING
+int set_dfmul2fixed_(P4(fixed *, ulong, long, long));
# if arch_is_big_endian
-# define set_dfmul2fixed_vars(vr,vda,vfb,dtemp)\
+# define CHECK_DFMUL2FIXED_VARS(vr, vda, vfb, dtemp)\
set_dfmul2fixed_(&vr, ((ulong *)&vda)[1], *(long *)&vfb, *(long *)&vda)
# else
-# define set_dfmul2fixed_vars(vr,vda,vfb,dtemp)\
+# define CHECK_DFMUL2FIXED_VARS(vr, vda, vfb, dtemp)\
set_dfmul2fixed_(&vr, *(ulong *)&vda, *(long *)&vfb, ((long *)&vda)[1])
# endif
+#define FINISH_DFMUL2FIXED_VARS(vr, dtemp)\
+ DO_NOTHING
+
#else /* don't bother */
-# define set_fmul2fixed_vars(vr,vfa,vfb,dtemp)\
- (dtemp = (vfa) * (vfb),\
- (f_fits_in_bits(dtemp, fixed_int_bits) ? (vr = float2fixed(dtemp), 0) :\
- gs_note_error(gs_error_limitcheck)))
-# define set_dfmul2fixed_vars(vr,vda,vfb,dtemp)\
- (dtemp = (vda) * (vfb),\
- (f_fits_in_bits(dtemp, fixed_int_bits) ? (vr = float2fixed(dtemp), 0) :\
- gs_note_error(gs_error_limitcheck)))
+
+#define CHECK_FMUL2FIXED_VARS(vr, vfa, vfb, dtemp)\
+ (dtemp = (vfa) * (vfb),\
+ (f_fits_in_bits(dtemp, fixed_int_bits) ? 0 :\
+ gs_note_error(gs_error_limitcheck)))
+#define FINISH_FMUL2FIXED_VARS(vr, dtemp)\
+ vr = float2fixed(dtemp)
+#define CHECK_DFMUL2FIXED_VARS(vr, vda, vfb, dtemp)\
+ CHECK_FMUL2FIXED_VARS(vr, vda, vfb, dtemp)
+#define FINISH_DFMUL2FIXED_VARS(vr, dtemp)\
+ FINISH_FMUL2FIXED_VARS(vr, dtemp)
+
#endif
+
/*
* set_float2fixed_vars(R, F) does the equivalent of R = float2fixed(F):
* R is a fixed, F is a float or a double.
diff --git a/gs/src/gxfmap.h b/gs/src/gxfmap.h
index 439c14370..776a9f9ac 100644
--- a/gs/src/gxfmap.h
+++ b/gs/src/gxfmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,7 @@
# define gxfmap_INCLUDED
#include "gsrefct.h"
+#include "gsstype.h"
#include "gxfrac.h"
#include "gxtmap.h"
@@ -64,7 +65,8 @@ extern_st(st_transfer_map);
frac gx_color_frac_map(P2(frac, const frac *)); /* in gxcmap.c */
# define gx_map_color_frac(pgs,cf,m)\
- gx_color_frac_map(cf, &pgs->m->values[0])
+ (pgs->m->proc == gs_identity_transfer ? cf :\
+ gx_color_frac_map(cf, &pgs->m->values[0]))
#else /* !FRAC_MAP_INTERPOLATE */
@@ -96,4 +98,7 @@ frac gx_color_frac_map(P2(frac, const frac *)); /* in gxcmap.c */
/* (It is equivalent to gx_map_color_float with the arguments swapped.) */
float gs_mapped_transfer(P2(floatp, const gx_transfer_map *));
+/* Define an identity mapping procedure. */
+float gs_identity_transfer(P2(floatp, const gx_transfer_map *));
+
#endif /* gxfmap_INCLUDED */
diff --git a/gs/src/gxfont.h b/gs/src/gxfont.h
index 78953029f..f360b0e56 100644
--- a/gs/src/gxfont.h
+++ b/gs/src/gxfont.h
@@ -25,7 +25,7 @@
#include "gsccode.h"
#include "gsfont.h"
#include "gsuid.h"
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
#include "gxftype.h"
/* A font object as seen by clients. */
diff --git a/gs/src/gxfont1.h b/gs/src/gxfont1.h
index 14d68bcf8..62b983199 100644
--- a/gs/src/gxfont1.h
+++ b/gs/src/gxfont1.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,22 +17,22 @@
*/
-/* Type 1 font data definition (including Type 2 charstrings) */
+/* Type 1 / Type 2 font data definition */
#ifndef gxfont1_INCLUDED
# define gxfont1_INCLUDED
+#include "gstype1.h" /* for charstring_interpret_proc */
/*
- * This is the type-specific information for an Adobe Type 1 font.
- * It also includes the information for Type 2 charstrings, because
+ * This is the type-specific information for Adobe Type 1 fonts.
+ * It also includes the information for Type 2 fonts, because
* there isn't very much of it and it's less trouble to include here.
*/
#ifndef gs_font_type1_DEFINED
# define gs_font_type1_DEFINED
typedef struct gs_font_type1_s gs_font_type1;
-
#endif
/*
@@ -72,20 +72,25 @@ typedef struct gs_type1_data_procs_s {
gs_const_string * pcdata));
/*
- * Get the next glyph. index = 0 means return the first one; a
- * returned index of 0 means the enumeration is finished.
+ * Get the next glyph in an enumeration. index = 0 means return the
+ * first one; a returned index of 0 means the enumeration is finished.
*/
- int (*next_glyph) (P3(gs_font_type1 * pfont, int *pindex,
- gs_glyph * pglyph));
+ int (*next_glyph)(P3(gs_font_type1 *pfont, int *pindex,
+ gs_glyph * pglyph));
- /* Push (a) value(s) onto the client ('PostScript') stack. */
+ /*
+ * Push (a) value(s) onto the client ('PostScript') stack during
+ * interpretation. Note that this procedure and the next one take a
+ * closure pointer, not the font pointer, as the first argument.
+ */
- int (*push) (P3(gs_font_type1 * pfont, const fixed * values, int count));
+ int (*push_values)(P3(void *callback_data, const fixed *values,
+ int count));
/* Pop a value from the client stack. */
- int (*pop) (P2(gs_font_type1 * pfont, fixed * value));
+ int (*pop_value)(P2(void *callback_data, fixed *value));
} gs_type1_data_procs_t;
@@ -97,18 +102,19 @@ typedef struct gs_type1_data_procs_s {
*/
struct gs_type1_data_s {
/*int PaintType; *//* in gs_font_common */
- int CharstringType; /* 1 or 2 */
const gs_type1_data_procs_t *procs;
+ charstring_interpret_proc((*interpret));
void *proc_data; /* data for procs */
int lenIV; /* -1 means no encryption */
- /* (undocumented feature!) */
+ /* (undocumented feature!) */
uint subroutineNumberBias; /* added to operand of callsubr */
- /* (undocumented feature!) */
- /* Type 2 charstring additions */
+ /* (undocumented feature!) */
+ /* Type 2 additions */
uint gsubrNumberBias; /* added to operand of callgsubr */
long initialRandomSeed;
fixed defaultWidthX;
fixed nominalWidthX;
+ /* End of Type 2 additions */
/* For a description of the following hint information, */
/* see chapter 5 of the "Adobe Type 1 Font Format" book. */
int BlueFuzz;
@@ -119,21 +125,21 @@ struct gs_type1_data_s {
float ExpansionFactor;
bool ForceBold;
#define max_FamilyBlues 7
- zone_table(max_FamilyBlues) FamilyBlues;
+ zone_table(max_FamilyBlues) FamilyBlues;
#define max_FamilyOtherBlues 5
- zone_table(max_FamilyOtherBlues) FamilyOtherBlues;
+ zone_table(max_FamilyOtherBlues) FamilyOtherBlues;
int LanguageGroup;
#define max_OtherBlues 5
- zone_table(max_OtherBlues) OtherBlues;
+ zone_table(max_OtherBlues) OtherBlues;
bool RndStemUp;
- stem_table(1) StdHW;
- stem_table(1) StdVW;
+ stem_table(1) StdHW;
+ stem_table(1) StdVW;
#define max_StemSnap 12
- stem_table(max_StemSnap) StemSnapH;
- stem_table(max_StemSnap) StemSnapV;
+ stem_table(max_StemSnap) StemSnapH;
+ stem_table(max_StemSnap) StemSnapV;
/* Additional information for Multiple Master fonts */
#define max_WeightVector 16
- float_array(max_WeightVector) WeightVector;
+ float_array(max_WeightVector) WeightVector;
};
#define gs_type1_data_s_DEFINED
diff --git a/gs/src/gxftype.h b/gs/src/gxftype.h
index cb9aec1d5..1aa55e5cf 100644
--- a/gs/src/gxftype.h
+++ b/gs/src/gxftype.h
@@ -28,7 +28,7 @@
typedef enum {
ft_composite = 0,
ft_encrypted = 1,
- ft_CFF = 2,
+ ft_encrypted2 = 2,
ft_user_defined = 3,
ft_disk_based = 4,
ft_CID_encrypted = 9, /* CIDFontType 0 */
diff --git a/gs/src/gxfunc.h b/gs/src/gxfunc.h
index f9d64a727..9a16cd16d 100644
--- a/gs/src/gxfunc.h
+++ b/gs/src/gxfunc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,9 +41,6 @@ void fn_common_free_params(P2(gs_function_params_t * params, gs_memory_t * mem))
/* Generic free implementation. */
void fn_common_free(P3(gs_function_t * pfn, bool free_params, gs_memory_t * mem));
-/* Free an array of subsidiary Functions. */
-void fn_free_functions(P3(gs_function_t ** Functions, int count, gs_memory_t * mem));
-
/* Check the values of m, n, Domain, and (if supplied) Range. */
int fn_check_mnDR(P3(const gs_function_params_t * params, int m, int n));
diff --git a/gs/src/gxgetbit.h b/gs/src/gxgetbit.h
index ccd309af3..497864645 100644
--- a/gs/src/gxgetbit.h
+++ b/gs/src/gxgetbit.h
@@ -83,13 +83,13 @@ struct gs_get_bits_params_s {
/* Try to implement get_bits_rectangle by returning a pointer. */
int gx_get_bits_return_pointer(P6(gx_device * dev, int x, int h,
gs_get_bits_params_t * params,
- gs_get_bits_options_t stored,
+ const gs_get_bits_params_t *stored,
byte * stored_base));
/* Implement get_bits_rectangle by copying. */
int gx_get_bits_copy(P8(gx_device * dev, int x, int w, int h,
gs_get_bits_params_t * params,
- gs_get_bits_options_t stored,
+ const gs_get_bits_params_t *stored,
const byte * src_base, uint dev_raster));
#endif /* gxgetbit_INCLUDED */
diff --git a/gs/src/gxht.c b/gs/src/gxht.c
index c76b68b3a..8b458a501 100644
--- a/gs/src/gxht.c
+++ b/gs/src/gxht.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,7 +17,7 @@
*/
-/* Halftone rendering routines for Ghostscript imaging library */
+/* Halftone rendering for imaging library */
#include "memory_.h"
#include "gx.h"
#include "gserrors.h"
@@ -141,10 +141,10 @@ gx_ht_alloc_cache(gs_memory_t * mem, uint max_tiles, uint max_bits)
gs_alloc_struct(mem, gx_ht_cache, &st_ht_cache,
"alloc_ht_cache(struct)");
byte *tbits =
- gs_alloc_bytes(mem, max_bits, "alloc_ht_cache(bits)");
+ gs_alloc_bytes(mem, max_bits, "alloc_ht_cache(bits)");
gx_ht_tile *ht_tiles =
- gs_alloc_struct_array(mem, max_tiles, gx_ht_tile, &st_ht_tiles,
- "alloc_ht_cache(ht_tiles)");
+ gs_alloc_struct_array(mem, max_tiles, gx_ht_tile, &st_ht_tiles,
+ "alloc_ht_cache(ht_tiles)");
if (pcache == 0 || tbits == 0 || ht_tiles == 0) {
gs_free_object(mem, ht_tiles, "alloc_ht_cache(ht_tiles)");
@@ -181,9 +181,37 @@ gx_check_tile_cache(const gs_imager_state * pis)
if (pcache == 0 || pis->dev_ht == 0)
return false; /* no halftone or cache */
- if (pcache->order.bits != porder->bits)
+ if (pcache->order.bit_data != porder->bit_data)
gx_ht_init_cache(pcache, porder);
- return pcache->levels_per_tile == 1;
+ if (pcache->tiles_fit >= 0)
+ return (bool)pcache->tiles_fit;
+ {
+ bool fit = false;
+ int bits_per_level;
+
+ if (pcache->num_cached < porder->num_levels)
+ DO_NOTHING;
+ else if (pcache->levels_per_tile == 1)
+ fit = true;
+ /*
+ * All the tiles fit iff bits and levels are exactly N-for-1, where
+ * N is a multiple of levels_per_tile.
+ */
+ else if (porder->num_bits % porder->num_levels == 0 &&
+ (bits_per_level = porder->num_bits / porder->num_levels) %
+ pcache->levels_per_tile == 0) {
+ /* Check the N-for-1 property. */
+ const uint *level = porder->levels;
+ int i = porder->num_levels, j = 0;
+
+ for (; i > 0; --i, j += bits_per_level, ++level)
+ if (*level != j)
+ break;
+ fit = i == 0;
+ }
+ pcache->tiles_fit = (int)fit;
+ return fit;
+ }
}
/*
@@ -279,7 +307,7 @@ gx_dc_ht_binary_load(gx_device_color * pdevc, const gs_imager_state * pis,
gx_ht_cache *pcache =
(porder->cache == 0 ? pis->ht_cache : porder->cache);
- if (pcache->order.bits != porder->bits)
+ if (pcache->order.bit_data != porder->bit_data)
gx_ht_init_cache(pcache, porder);
/* Expand gx_render_ht inline for speed. */
{
@@ -411,6 +439,7 @@ gx_ht_init_cache(gx_ht_cache * pcache, const gx_ht_order * porder)
pcache->order = *porder;
pcache->num_cached = num_cached;
pcache->levels_per_tile = (size + num_cached - 1) / num_cached;
+ pcache->tiles_fit = -1;
memset(tbits, 0, pcache->bits_size);
for (i = 0; i < num_cached; i++, tbits += tile_bytes) {
register gx_ht_tile *bt = &pcache->ht_tiles[i];
@@ -444,90 +473,23 @@ private int
render_ht(gx_ht_tile * pbt, int level /* [1..num_bits-1] */ ,
const gx_ht_order * porder, gx_bitmap_id new_id)
{
- int old_level = pbt->level;
- register gx_ht_bit *p = &porder->bits[old_level];
- register byte *data = pbt->tiles.data;
+ byte *data = pbt->tiles.data;
+ int code;
if_debug7('H', "[H]Halftone cache slot 0x%lx: old=%d, new=%d, w=%d(%d), h=%d(%d):\n",
- (ulong) data, old_level, level,
+ (ulong) data, pbt->level, level,
pbt->tiles.size.x, porder->width,
pbt->tiles.size.y, porder->num_bits / porder->width);
#ifdef DEBUG
if (level < 0 || level > porder->num_bits) {
- lprintf3("Error in render_ht: level=%d, old_level=%d, num_bits=%d\n", level, old_level, porder->num_bits);
+ lprintf3("Error in render_ht: level=%d, old level=%d, num_bits=%d\n",
+ level, pbt->level, porder->num_bits);
return_error(gs_error_Fatal);
}
#endif
- /* Invert bits between the two pointers. */
- /* Note that we can use the same loop to turn bits either */
- /* on or off, using xor. */
- /* The Borland compiler generates truly dreadful code */
- /* if we don't assign the offset to a temporary. */
-#if arch_ints_are_short
-# define invert_data(i)\
- { uint off = p[i].offset; *(ht_mask_t *)&data[off] ^= p[i].mask; }
-#else
-# define invert_data(i) *(ht_mask_t *)&data[p[i].offset] ^= p[i].mask
-#endif
-#ifdef DEBUG
-# define invert(i)\
- { if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\
- (int)(p + i - porder->bits), p[i].offset, p[i].mask);\
- invert_data(i);\
- }
-#else
-# define invert(i) invert_data(i)
-#endif
- sw:switch (level - old_level) {
- default:
- if (level > old_level) {
- invert(0);
- invert(1);
- invert(2);
- invert(3);
- p += 4;
- old_level += 4;
- } else {
- invert(-1);
- invert(-2);
- invert(-3);
- invert(-4);
- p -= 4;
- old_level -= 4;
- }
- goto sw;
- case 7:
- invert(6);
- case 6:
- invert(5);
- case 5:
- invert(4);
- case 4:
- invert(3);
- case 3:
- invert(2);
- case 2:
- invert(1);
- case 1:
- invert(0);
- case 0:
- break; /* Shouldn't happen! */
- case -7:
- invert(-7);
- case -6:
- invert(-6);
- case -5:
- invert(-5);
- case -4:
- invert(-4);
- case -3:
- invert(-3);
- case -2:
- invert(-2);
- case -1:
- invert(-1);
- }
-#undef invert
+ code = porder->procs->render(pbt, level, porder);
+ if (code < 0)
+ return code;
pbt->level = level;
pbt->tiles.id = new_id;
/*
diff --git a/gs/src/gxht.h b/gs/src/gxht.h
index 3f09090e2..8b170b5a7 100644
--- a/gs/src/gxht.h
+++ b/gs/src/gxht.h
@@ -79,24 +79,39 @@ typedef struct gs_spot_halftone_s {
#define st_spot_halftone_max_ptrs st_screen_halftone_max_ptrs + 1
+/* Define common elements for Type 3 and extended Type 3 halftones. */
+#define GS_THRESHOLD_HALFTONE_COMMON\
+ int width;\
+ int height;\
+ gs_mapping_closure_t transfer_closure
+typedef struct gs_threshold_halftone_common_s {
+ GS_THRESHOLD_HALFTONE_COMMON;
+} gs_threshold_halftone_common;
+
/* Type 3 halftone. */
typedef struct gs_threshold_halftone_s {
- int width;
- int height;
+ GS_THRESHOLD_HALFTONE_COMMON; /* must be first */
gs_const_string thresholds;
gs_mapping_proc transfer; /* OBSOLETE */
- gs_mapping_closure_t transfer_closure;
} gs_threshold_halftone;
#define st_threshold_halftone_max_ptrs 2
+/* Extended Type 3 halftone. */
+typedef struct gs_threshold2_halftone_s {
+ GS_THRESHOLD_HALFTONE_COMMON; /* must be first */
+ int width2;
+ int height2;
+ int bytes_per_sample; /* 1 or 2 */
+ gs_const_bytestring thresholds; /* nota bene */
+} gs_threshold2_halftone;
+
/* Client-defined halftone that generates a halftone order. */
typedef struct gs_client_order_halftone_s gs_client_order_halftone;
#ifndef gx_ht_order_DEFINED
# define gx_ht_order_DEFINED
typedef struct gx_ht_order_s gx_ht_order;
-
#endif
typedef struct gs_client_order_ht_procs_s {
@@ -129,6 +144,7 @@ typedef struct gs_halftone_component_s {
union {
gs_spot_halftone spot; /* Type 1 */
gs_threshold_halftone threshold; /* Type 3 */
+ gs_threshold2_halftone threshold2; /* Extended Type 3 */
gs_client_order_halftone client_order; /* client order */
} params;
} gs_halftone_component;
@@ -172,6 +188,7 @@ struct gs_halftone_s {
gs_colorscreen_halftone colorscreen; /* setcolorscreen */
gs_spot_halftone spot; /* Type 1 */
gs_threshold_halftone threshold; /* Type 3 */
+ gs_threshold2_halftone threshold2; /* Extended Type 3 */
gs_client_order_halftone client_order; /* client order */
gs_multiple_halftone multiple; /* Type 5 */
} params;
diff --git a/gs/src/gxhtbit.c b/gs/src/gxhtbit.c
new file mode 100644
index 000000000..a3ba9aa73
--- /dev/null
+++ b/gs/src/gxhtbit.c
@@ -0,0 +1,243 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Halftone bit updating for imaging library */
+#include "memory_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gsbitops.h"
+#include "gscdefs.h"
+#include "gxbitmap.h"
+#include "gxhttile.h"
+#include "gxtmap.h"
+#include "gxdht.h"
+#include "gxdhtres.h"
+
+extern_gx_device_halftone_list();
+
+/*
+ * Construct a standard-representation order from a threshold array.
+ */
+private int
+construct_ht_order_default(gx_ht_order *porder, const byte *thresholds)
+{
+ gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
+ uint i;
+
+ for (i = 0; i < porder->num_bits; i++)
+ bits[i].mask = max(1, thresholds[i]);
+ gx_ht_complete_threshold_order(porder);
+ return 0;
+}
+
+/*
+ * Construct a short-representation order from a threshold array.
+ * Uses porder->width, num_levels, num_bits, levels, bit_data;
+ * sets porder->levels[], bit_data[].
+ */
+private int
+construct_ht_order_short(gx_ht_order *porder, const byte *thresholds)
+{
+ uint size = porder->num_bits;
+ uint i;
+ ushort *bits = (ushort *)porder->bit_data;
+ uint *levels = porder->levels;
+ uint num_levels = porder->num_levels;
+
+ memset(levels, 0, num_levels * sizeof(*levels));
+ /* Count the number of threshold elements with each value. */
+ for (i = 0; i < size; i++) {
+ uint value = max(1, thresholds[i]);
+
+ if (value + 1 < num_levels)
+ levels[value + 1]++;
+ }
+ for (i = 2; i < num_levels; ++i)
+ levels[i] += levels[i - 1];
+ /* Now construct the actual order. */
+ {
+ uint width = porder->width;
+ uint padding = bitmap_raster(width) * 8 - width;
+
+ for (i = 0; i < size; i++) {
+ uint value = max(1, thresholds[i]);
+
+ /* Adjust the bit index to account for padding. */
+ bits[levels[value]++] = i + (i / width * padding);
+ }
+ }
+
+ /* Check whether this is a predefined halftone. */
+ {
+ const gx_dht_proc *phtrp = gx_device_halftone_list;
+
+ for (; *phtrp; ++phtrp) {
+ const gx_device_halftone_resource_t *phtr = (*phtrp)();
+
+ if (phtr->Width == porder->width &&
+ phtr->Height == porder->height &&
+ phtr->elt_size == sizeof(ushort) &&
+ !memcmp(phtr->levels, levels, num_levels * sizeof(*levels)) &&
+ !memcmp(phtr->bit_data, porder->bit_data,
+ size * phtr->elt_size)
+ ) {
+ /*
+ * This is a predefined halftone. Free the levels and
+ * bit_data arrays, replacing them with the built-in ones.
+ */
+ if (porder->data_memory) {
+ gs_free_object(porder->data_memory, porder->bit_data,
+ "construct_ht_order_short(bit_data)");
+ gs_free_object(porder->data_memory, porder->levels,
+ "construct_ht_order_short(levels)");
+ }
+ porder->data_memory = 0;
+ porder->levels = (uint *)phtr->levels; /* actually const */
+ porder->bit_data = (void *)phtr->bit_data; /* actually const */
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Update a halftone tile using the default order representation. */
+private int
+render_ht_default(gx_ht_tile *pbt, int level, const gx_ht_order *porder)
+{
+ int old_level = pbt->level;
+ register const gx_ht_bit *p =
+ (const gx_ht_bit *)porder->bit_data + old_level;
+ register byte *data = pbt->tiles.data;
+
+ /*
+ * Invert bits between the two levels. Note that we can use the same
+ * loop to turn bits either on or off, using xor. The Borland compiler
+ * generates truly dreadful code if we don't use a temporary, and it
+ * doesn't hurt better compilers, so we always use one.
+ */
+#define INVERT_DATA(i)\
+ BEGIN\
+ ht_mask_t *dp = (ht_mask_t *)&data[p[i].offset];\
+ *dp ^= p[i].mask;\
+ END
+#ifdef DEBUG
+# define INVERT(i)\
+ BEGIN\
+ if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\
+ (int)(p + i - (const gx_ht_bit *)porder->bit_data),\
+ p[i].offset, p[i].mask);\
+ INVERT_DATA(i);\
+ END
+#else
+# define INVERT(i) INVERT_DATA(i)
+#endif
+ sw:switch (level - old_level) {
+ default:
+ if (level > old_level) {
+ INVERT(0); INVERT(1); INVERT(2); INVERT(3);
+ p += 4; old_level += 4;
+ } else {
+ INVERT(-1); INVERT(-2); INVERT(-3); INVERT(-4);
+ p -= 4; old_level -= 4;
+ }
+ goto sw;
+ case 7: INVERT(6);
+ case 6: INVERT(5);
+ case 5: INVERT(4);
+ case 4: INVERT(3);
+ case 3: INVERT(2);
+ case 2: INVERT(1);
+ case 1: INVERT(0);
+ case 0: break; /* Shouldn't happen! */
+ case -7: INVERT(-7);
+ case -6: INVERT(-6);
+ case -5: INVERT(-5);
+ case -4: INVERT(-4);
+ case -3: INVERT(-3);
+ case -2: INVERT(-2);
+ case -1: INVERT(-1);
+ }
+#undef INVERT_DATA
+#undef INVERT
+ return 0;
+}
+
+/* Update a halftone tile using the short representation. */
+private int
+render_ht_short(gx_ht_tile *pbt, int level, const gx_ht_order *porder)
+{
+ int old_level = pbt->level;
+ register const ushort *p = (const ushort *)porder->bit_data + old_level;
+ register byte *data = pbt->tiles.data;
+
+ /* Invert bits between the two levels. */
+#define INVERT_DATA(i)\
+ BEGIN\
+ uint bit_index = p[i];\
+ byte *dp = &data[bit_index >> 3];\
+ *dp ^= 0x80 >> (bit_index & 7);\
+ END
+#ifdef DEBUG
+# define INVERT(i)\
+ BEGIN\
+ if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\
+ (int)(p + i - (const ushort *)porder->bit_data),\
+ p[i] >> 3, 0x80 >> (p[i] & 7));\
+ INVERT_DATA(i);\
+ END
+#else
+# define INVERT(i) INVERT_DATA(i)
+#endif
+ sw:switch (level - old_level) {
+ default:
+ if (level > old_level) {
+ INVERT(0); INVERT(1); INVERT(2); INVERT(3);
+ p += 4; old_level += 4;
+ } else {
+ INVERT(-1); INVERT(-2); INVERT(-3); INVERT(-4);
+ p -= 4; old_level -= 4;
+ }
+ goto sw;
+ case 7: INVERT(6);
+ case 6: INVERT(5);
+ case 5: INVERT(4);
+ case 4: INVERT(3);
+ case 3: INVERT(2);
+ case 2: INVERT(1);
+ case 1: INVERT(0);
+ case 0: break; /* Shouldn't happen! */
+ case -7: INVERT(-7);
+ case -6: INVERT(-6);
+ case -5: INVERT(-5);
+ case -4: INVERT(-4);
+ case -3: INVERT(-3);
+ case -2: INVERT(-2);
+ case -1: INVERT(-1);
+ }
+#undef INVERT_DATA
+#undef INVERT
+ return 0;
+}
+
+/* Define the procedure vectors for the order data implementations. */
+const gx_ht_order_procs_t ht_order_procs_table[2] = {
+ { sizeof(gx_ht_bit), construct_ht_order_default, render_ht_default },
+ { sizeof(ushort), construct_ht_order_short, render_ht_short }
+};
diff --git a/gs/src/gxhttype.h b/gs/src/gxhttype.h
index 241b5d645..369b57513 100644
--- a/gs/src/gxhttype.h
+++ b/gs/src/gxhttype.h
@@ -29,10 +29,14 @@ typedef enum {
ht_type_colorscreen, /* set by setcolorscreen */
ht_type_spot, /* Type 1 halftone dictionary */
ht_type_threshold, /* Type 3 halftone dictionary */
+ ht_type_threshold2, /* Extended Type 3 halftone dictionary */
+ /* (Type 3 with either 8- or 16-bit */
+ /* samples, bytestring instead of string */
+ /* thresholds, and 1 or 2 rectangles) */
ht_type_multiple, /* Type 5 halftone dictionary */
- ht_type_multiple_colorscreen, /* Type 5 halftone dictionary */
- /* created from Type 2 or Type 4 */
- /* halftone dictionary */
+ ht_type_multiple_colorscreen, /* Type 5 halftone dictionary */
+ /* created from Type 2 or Type 4 */
+ /* halftone dictionary */
ht_type_client_order /* client-defined, creating a gx_ht_order */
} gs_halftone_type;
diff --git a/gs/src/gxi12bit.c b/gs/src/gxi12bit.c
index 2ed6e34ac..9388b6a8e 100644
--- a/gs/src/gxi12bit.c
+++ b/gs/src/gxi12bit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,7 +32,6 @@
#include "gxcmap.h"
#include "gxdcolor.h"
#include "gxistate.h"
-#include "gzpath.h"
#include "gxdevmem.h"
#include "gxcpath.h"
#include "gximage.h"
@@ -94,12 +93,14 @@ sample_unpack_12(byte * bptr, int *pdata_x, const byte * data,
return bptr;
}
+const sample_unpack_proc_t sample_unpack_12_proc = sample_unpack_12;
+
/* ------ Strategy procedure ------ */
/* Use special (slow) logic for 12-bit source values. */
private irender_proc(image_render_frac);
-private irender_proc_t
-image_strategy_frac(gx_image_enum * penum)
+irender_proc_t
+gs_image_class_2_fracs(gx_image_enum * penum)
{
if (penum->bps > 8) {
if (penum->use_mask_color) {
@@ -116,29 +117,25 @@ image_strategy_frac(gx_image_enum * penum)
return 0;
}
-void
-gs_gxi12bit_init(gs_memory_t * mem)
-{
- image_strategies.fracs = image_strategy_frac;
- sample_unpack_12_proc = sample_unpack_12;
-}
-
/* ---------------- Rendering procedures ---------------- */
/* ------ Rendering for 12-bit samples ------ */
-#define longs_per_4_fracs (arch_sizeof_frac * 4 / arch_sizeof_long)
+#define FRACS_PER_LONG (arch_sizeof_long / arch_sizeof_frac)
typedef union {
- frac v[4];
- long all[longs_per_4_fracs]; /* for fast comparison */
+ frac v[GS_IMAGE_MAX_COLOR_COMPONENTS];
+#define LONGS_PER_COLOR_FRACS\
+ ((GS_IMAGE_MAX_COLOR_COMPONENTS + FRACS_PER_LONG - 1) / FRACS_PER_LONG)
+ long all[LONGS_PER_COLOR_FRACS]; /* for fast comparison */
} color_fracs;
-#if longs_per_4_fracs == 1
-# define color_frac_eq(f1, f2)\
+#define LONGS_PER_4_FRACS ((FRACS_PER_LONG + 3) / 4)
+#if LONGS_PER_4_FRACS == 1
+# define COLOR_FRACS_4_EQ(f1, f2)\
((f1).all[0] == (f2).all[0])
#else
-#if longs_per_4_fracs == 2
-# define color_frac_eq(f1, f2)\
+#if LONGS_PER_4_FRACS == 2
+# define COLOR_FRACS_4_EQ(f1, f2)\
((f1).all[0] == (f2).all[0] && (f1).all[1] == (f2).all[1])
#endif
#endif
@@ -174,8 +171,8 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x,
const gs_color_space *pcs = penum->pcs;
cs_proc_remap_color((*remap_color)) = pcs->type->remap_color;
gs_client_color cc;
- int device_color = penum->device_color;
- const gx_color_map_procs *cmap_procs = gx_device_cmap_procs(dev);
+ bool device_color = penum->device_color;
+ const gx_color_map_procs *cmap_procs = gx_get_cmap_procs(pis, dev);
cmap_proc_rgb((*map_rgb)) = cmap_procs->map_rgb;
cmap_proc_cmyk((*map_cmyk)) = cmap_procs->map_cmyk;
bool use_mask_color = penum->use_mask_color;
@@ -202,23 +199,20 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x,
pdyy = dda_current(penum->dda.row.y) - penum->cur.y;
if_debug4('b', "[b]y=%d w=%d xt=%f yt=%f\n",
penum->y, w, fixed2float(xl), fixed2float(ytf));
- run.v[0] = run.v[1] = run.v[2] = run.v[3] = 0;
- next.v[0] = next.v[1] = next.v[2] = next.v[3] = 0;
- cc.paint.values[0] = cc.paint.values[1] =
- cc.paint.values[2] = cc.paint.values[3] = 0;
- cc.pattern = 0;
- (*remap_color) (&cc, pcs, pdevc, pis, dev, gs_color_select_source);
+ memset(&run, 0, sizeof(run));
+ memset(&next, 0, sizeof(next));
+ cs_full_init_color(&cc, pcs);
run.v[0] = ~psrc[0]; /* force remap */
while (psrc < bufend) {
next.v[0] = psrc[0];
switch (spp) {
- case 4: /* cmyk */
+ case 4: /* may be CMYK */
next.v[1] = psrc[1];
next.v[2] = psrc[2];
next.v[3] = psrc[3];
psrc += 4;
- if (color_frac_eq(next, run))
+ if (COLOR_FRACS_4_EQ(next, run))
goto inc;
if (use_mask_color && mask_color12_matches(next.v, penum, 4)) {
color_set_null(pdevc_next);
@@ -241,11 +235,11 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x,
if_debug1('B', "[B]cc[3]=%g\n",
cc.paint.values[3]);
break;
- case 3: /* rgb */
+ case 3: /* may be RGB */
next.v[1] = psrc[1];
next.v[2] = psrc[2];
psrc += 3;
- if (color_frac_eq(next, run))
+ if (COLOR_FRACS_4_EQ(next, run))
goto inc;
if (use_mask_color && mask_color12_matches(next.v, penum, 3)) {
color_set_null(pdevc_next);
@@ -264,7 +258,7 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x,
cc.paint.values[0], cc.paint.values[1],
cc.paint.values[2]);
break;
- case 1: /* gray */
+ case 1: /* may be Gray */
psrc++;
if (next.v[0] == run.v[0])
goto inc;
@@ -282,9 +276,39 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x,
if_debug1('B', "[B]cc[0]=%g\n",
cc.paint.values[0]);
break;
+ default: /* DeviceN */
+ {
+ int i;
+
+ for (i = 1; i < spp; ++i)
+ next.v[i] = psrc[i];
+ psrc += spp;
+ if (!memcmp(next.v, run.v, spp * sizeof(next.v[0])))
+ goto inc;
+ if (use_mask_color &&
+ mask_color12_matches(next.v, penum, spp)
+ ) {
+ color_set_null(pdevc_next);
+ goto f;
+ }
+ for (i = 0; i < spp; ++i)
+ decode_frac(next.v[i], cc, i);
+#ifdef DEBUG
+ if (gs_debug_c('B')) {
+ dprintf2("[B]cc[0..%d]=%g", spp - 1,
+ cc.paint.values[0]);
+ for (i = 1; i < spp; ++i)
+ dprintf1(",%g", cc.paint.values[i]);
+ dputs("\n");
+ }
+#endif
+ }
+ break;
}
- (*remap_color) (&cc, pcs, pdevc_next, pis, dev,
- gs_color_select_source);
+ code = remap_color(&cc, pcs, pdevc_next, pis, dev,
+ gs_color_select_source);
+ if (code < 0)
+ return code;
f:
if_debug7('B', "[B]0x%x,0x%x,0x%x,0x%x -> %ld,%ld,0x%lx\n",
next.v[0], next.v[1], next.v[2], next.v[3],
diff --git a/gs/src/gxiclass.h b/gs/src/gxiclass.h
new file mode 100644
index 000000000..da0921038
--- /dev/null
+++ b/gs/src/gxiclass.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Define image rendering algorithm classes */
+
+#ifndef gxiclass_INCLUDED
+# define gxiclass_INCLUDED
+
+/* Define the abstract type for the image enumerator state. */
+typedef struct gx_image_enum_s gx_image_enum;
+
+#ifndef gx_device_DEFINED
+# define gx_device_DEFINED
+typedef struct gx_device_s gx_device;
+#endif
+
+/*
+ * Define the interface for routines used to render a (source) scan line.
+ * If the buffer is the original client's input data, it may be unaligned;
+ * otherwise, it will always be aligned.
+ *
+ * The image_render procedures work on fully expanded, complete rows. These
+ * take a height argument, which is an integer >= 0; they return a negative
+ * code, or the number of rows actually processed (which may be less than
+ * the height). height = 0 is a special call to indicate that there is no
+ * more input data; this is necessary because the last scan lines of the
+ * source data may not produce any output.
+ */
+#define irender_proc(proc)\
+ int proc(P6(gx_image_enum *penum, const byte *buffer, int data_x,\
+ uint w, int h, gx_device *dev))
+typedef irender_proc((*irender_proc_t));
+
+/*
+ * Define procedures for selecting imaging methods according to the class of
+ * the image. Image class procedures are called in alphabetical order, so
+ * their names begin with a digit that indicates their priority
+ * (0_interpolate, etc.): each one may assume that all the previous ones
+ * failed. If a class procedure succeeds, it may update the enumerator
+ * structure as well as returning the rendering procedure.
+ */
+#define iclass_proc(proc)\
+ irender_proc_t proc(P1(gx_image_enum *penum))
+typedef iclass_proc((*gx_image_class_t));
+
+#endif /* gxiclass_INCLUDED */
diff --git a/gs/src/gxicolor.c b/gs/src/gxicolor.c
index e9285dd6f..295051f98 100644
--- a/gs/src/gxicolor.c
+++ b/gs/src/gxicolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,47 +34,50 @@
#include "gxdcconv.h"
#include "gxdcolor.h"
#include "gxistate.h"
-#include "gzpath.h"
#include "gxdevmem.h"
#include "gxcpath.h"
#include "gximage.h"
typedef union {
- byte v[4];
- bits32 all; /* for fast comparison & clearing */
+ byte v[GS_IMAGE_MAX_COLOR_COMPONENTS];
+#define BYTES_PER_BITS32 4
+#define BITS32_PER_COLOR_SAMPLES\
+ ((GS_IMAGE_MAX_COLOR_COMPONENTS + BYTES_PER_BITS32 - 1) / BYTES_PER_BITS32)
+ bits32 all[BITS32_PER_COLOR_SAMPLES]; /* for fast comparison */
} color_samples;
/* ------ Strategy procedure ------ */
private irender_proc(image_render_color);
-private irender_proc_t
-image_strategy_color(gx_image_enum * penum)
+irender_proc_t
+gs_image_class_4_color(gx_image_enum * penum)
{
if (penum->use_mask_color) {
/*
* Scale the mask colors to match the scaling of each sample to
* a full byte, and set up the quick-filter parameters.
*/
- uint scale = 255 / ((1 << penum->bps) - 1);
int i;
color_samples mask, test;
- bool exact = true;
+ bool exact = penum->spp <= BYTES_PER_BITS32;
- mask.all = 0;
- test.all = 0;
+ memset(&mask, 0, sizeof(mask));
+ memset(&test, 0, sizeof(test));
for (i = 0; i < penum->spp; ++i) {
- byte v0 = (byte)(penum->mask_color.values[2 * i] *= scale);
- byte v1 = (byte)(penum->mask_color.values[2 * i + 1] *= scale);
+ byte v0, v1;
byte match = 0xff;
+ gx_image_scale_mask_colors(penum, i);
+ v0 = (byte)penum->mask_color.values[2 * i];
+ v1 = (byte)penum->mask_color.values[2 * i + 1];
while ((v0 & match) != (v1 & match))
match <<= 1;
mask.v[i] = match;
test.v[i] = v0 & match;
exact &= (v0 == match && (v1 | match) == 0xff);
}
- penum->mask_color.mask = mask.all;
- penum->mask_color.test = test.all;
+ penum->mask_color.mask = mask.all[0];
+ penum->mask_color.test = test.all[0];
penum->mask_color.exact = exact;
} else {
penum->mask_color.mask = 0;
@@ -83,12 +86,6 @@ image_strategy_color(gx_image_enum * penum)
return image_render_color;
}
-void
-gs_gxicolor_init(gs_memory_t * mem)
-{
- image_strategies.color = image_strategy_color;
-}
-
/* ------ Rendering procedures ------ */
/* Test whether a color is transparent. */
@@ -108,9 +105,11 @@ mask_color_matches(const byte *v, const gx_image_enum *penum,
/* Render a color image with 8 or fewer bits per sample. */
private int
-image_render_color(gx_image_enum * penum, const byte * buffer, int data_x,
+image_render_color(gx_image_enum *penum_orig, const byte *buffer, int data_x,
uint w, int h, gx_device * dev)
{
+ const gx_image_enum *const penum = penum_orig; /* const within proc */
+ gx_image_clue *const clues = penum_orig->clues; /* not const */
const gs_imager_state *pis = penum->pis;
gs_logical_operation_t lop = penum->log_op;
gx_dda_fixed_point pnext;
@@ -122,28 +121,30 @@ image_render_color(gx_image_enum * penum, const byte * buffer, int data_x,
cs_proc_remap_color((*remap_color)) = pcs->type->remap_color;
gs_client_color cc;
bool device_color = penum->device_color;
- const gx_color_map_procs *cmap_procs = gx_device_cmap_procs(dev);
+ const gx_color_map_procs *cmap_procs = gx_get_cmap_procs(pis, dev);
cmap_proc_rgb((*map_3)) = cmap_procs->map_rgb;
cmap_proc_cmyk((*map_4)) =
(penum->alpha ? cmap_procs->map_rgb_alpha : cmap_procs->map_cmyk);
bits32 mask = penum->mask_color.mask;
bits32 test = penum->mask_color.test;
- gx_image_clue *pic = &penum->clues[0];
+ gx_image_clue *pic = &clues[0];
#define pdevc (&pic->dev_color)
- gx_image_clue *pic_next = &penum->clues[1];
+ gx_image_clue *pic_next = &clues[1];
#define pdevc_next (&pic_next->dev_color)
gx_image_clue empty_clue;
gx_image_clue clue_temp;
int spp = penum->spp;
- const byte *psrc = buffer + data_x * spp;
- fixed xrun; /* x at start of run */
+ const byte *psrc_initial = buffer + data_x * spp;
+ const byte *psrc = psrc_initial;
+ const byte *rsrc = psrc + spp; /* psrc + spp at start of run */
+ fixed xrun; /* x ditto */
fixed yrun; /* y ditto */
int irun; /* int x/rrun */
color_samples run; /* run value */
color_samples next; /* next sample value */
const byte *bufend = psrc + w;
bool use_cache = spp * penum->bps <= 12;
- int code = 0;
+ int code = 0, mcode = 0;
if (h == 0)
return 0;
@@ -167,37 +168,35 @@ image_render_color(gx_image_enum * penum, const byte * buffer, int data_x,
if_debug4('b', "[b]y=%d w=%d xt=%f yt=%f\n",
penum->y, w, fixed2float(xprev), fixed2float(yprev));
- run.all = 0;
- next.all = 0;
+ memset(&run, 0, sizeof(run));
+ memset(&next, 0, sizeof(next));
/* Ensure that we don't get any false dev_color_eq hits. */
if (use_cache) {
color_set_pure(&empty_clue.dev_color, gx_no_color_index);
pic = &empty_clue;
}
- cc.paint.values[0] = cc.paint.values[1] =
- cc.paint.values[2] = cc.paint.values[3] = 0;
- cc.pattern = 0;
+ cs_full_init_color(&cc, pcs);
run.v[0] = ~psrc[0]; /* force remap */
while (psrc < bufend) {
dda_next(pnext.x);
dda_next(pnext.y);
#define CLUE_HASH3(penum, next)\
- &penum->clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4)) & 255];
+ &clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4)) & 255];
#define CLUE_HASH4(penum, next)\
- &penum->clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4) +\
+ &clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4) +\
(next.v[3] << 6)) & 255]
- if (spp == 4) { /* cmyk or rgba */
+ if (spp == 4) { /* may be CMYK or RGBA */
next.v[0] = psrc[0];
next.v[1] = psrc[1];
next.v[2] = psrc[2];
next.v[3] = psrc[3];
psrc += 4;
-map4: if (next.all == run.all)
+map4: if (next.all[0] == run.all[0])
goto inc;
if (use_cache) {
pic_next = CLUE_HASH4(penum, next);
- if (pic_next->key == next.all)
+ if (pic_next->key == next.all[0])
goto f;
/*
* If we are really unlucky, pic_next == pic,
@@ -208,10 +207,10 @@ map4: if (next.all == run.all)
clue_temp = *pic;
pic = &clue_temp;
}
- pic_next->key = next.all;
+ pic_next->key = next.all[0];
}
/* Check for transparent color. */
- if ((next.all & mask) == test &&
+ if ((next.all[0] & mask) == test &&
(penum->mask_color.exact ||
mask_color_matches(next.v, penum, 4))
) {
@@ -227,26 +226,32 @@ map4: if (next.all == run.all)
}
decode_sample(next.v[3], cc, 3);
if_debug1('B', "[B]cc[3]=%g\n", cc.paint.values[3]);
- } else if (spp == 3) { /* rgb */
+do3: decode_sample(next.v[0], cc, 0);
+ decode_sample(next.v[1], cc, 1);
+ decode_sample(next.v[2], cc, 2);
+ if_debug3('B', "[B]cc[0..2]=%g,%g,%g\n",
+ cc.paint.values[0], cc.paint.values[1],
+ cc.paint.values[2]);
+ } else if (spp == 3) { /* may be RGB */
next.v[0] = psrc[0];
next.v[1] = psrc[1];
next.v[2] = psrc[2];
psrc += 3;
- if (next.all == run.all)
+ if (next.all[0] == run.all[0])
goto inc;
if (use_cache) {
pic_next = CLUE_HASH3(penum, next);
- if (pic_next->key == next.all)
+ if (pic_next->key == next.all[0])
goto f;
/* See above re the following check. */
if (pic_next == pic) {
clue_temp = *pic;
pic = &clue_temp;
}
- pic_next->key = next.all;
+ pic_next->key = next.all[0];
}
/* Check for transparent color. */
- if ((next.all & mask) == test &&
+ if ((next.all[0] & mask) == test &&
(penum->mask_color.exact ||
mask_color_matches(next.v, penum, 3))
) {
@@ -260,38 +265,65 @@ map4: if (next.all == run.all)
gs_color_select_source);
goto mapped;
}
- } else if (spp == 2) { /* gray+alpha */
- next.v[2] = next.v[1] = next.v[0] = psrc[0];
- next.v[3] = psrc[1];
- psrc += 2;
- goto map4;
- } else { /* spp == 5, cmyk+alpha */
- /* Convert CMYK to RGB. */
- frac rgb[3];
+ goto do3;
+ } else if (penum->alpha) {
+ if (spp == 2) { /* might be Gray + alpha */
+ next.v[2] = next.v[1] = next.v[0] = psrc[0];
+ next.v[3] = psrc[1];
+ psrc += 2;
+ goto map4;
+ } else if (spp == 5) { /* might be CMYK + alpha */
+ /* Convert CMYK to RGB. */
+ frac rgb[3];
+
+ color_cmyk_to_rgb(byte2frac(psrc[0]), byte2frac(psrc[1]),
+ byte2frac(psrc[2]), byte2frac(psrc[3]),
+ pis, rgb);
+ /*
+ * It seems silly to do all this converting between
+ * fracs and bytes, but that's what the current
+ * APIs require.
+ */
+ next.v[0] = frac2byte(rgb[0]);
+ next.v[1] = frac2byte(rgb[1]);
+ next.v[2] = frac2byte(rgb[2]);
+ next.v[3] = psrc[4];
+ psrc += 5;
+ goto map4;
+ }
+ } else { /* DeviceN */
+ int i;
- color_cmyk_to_rgb(byte2frac(psrc[0]), byte2frac(psrc[1]),
- byte2frac(psrc[2]), byte2frac(psrc[3]),
- pis, rgb);
- /*
- * It seems silly to do all this converting between
- * fracs and bytes, but that's what the current
- * APIs require.
- */
- next.v[0] = frac2byte(rgb[0]);
- next.v[1] = frac2byte(rgb[1]);
- next.v[2] = frac2byte(rgb[2]);
- next.v[3] = psrc[4];
- psrc += 5;
- goto map4;
+ use_cache = false; /* should do in initialization */
+ if (!memcmp(psrc, run.v, spp)) {
+ psrc += spp;
+ goto inc;
+ }
+ memcpy(next.v, psrc, spp);
+ psrc += spp;
+ if ((next.all[0] & mask) == test &&
+ (penum->mask_color.exact ||
+ mask_color_matches(next.v, penum, spp))
+ ) {
+ color_set_null(pdevc_next);
+ goto mapped;
+ }
+ for (i = 0; i < spp; ++i)
+ decode_sample(next.v[i], cc, i);
+#ifdef DEBUG
+ if (gs_debug_c('B')) {
+ dprintf2("[B]cc[0..%d]=%g", spp - 1,
+ cc.paint.values[0]);
+ for (i = 1; i < spp; ++i)
+ dprintf1(",%g", cc.paint.values[i]);
+ dputs("\n");
+ }
+#endif
}
- decode_sample(next.v[0], cc, 0);
- decode_sample(next.v[1], cc, 1);
- decode_sample(next.v[2], cc, 2);
- if_debug3('B', "[B]cc[0..2]=%g,%g,%g\n",
- cc.paint.values[0], cc.paint.values[1],
- cc.paint.values[2]);
- (*remap_color) (&cc, pcs, pdevc_next, pis, dev,
- gs_color_select_source);
+ mcode = remap_color(&cc, pcs, pdevc_next, pis, dev,
+ gs_color_select_source);
+ if (mcode < 0)
+ goto fill;
mapped: if (pic == pic_next)
goto fill;
f: if_debug7('B', "[B]0x%x,0x%x,0x%x,0x%x -> %ld,%ld,0x%lx\n",
@@ -345,7 +377,10 @@ fill: /* Fill the region between */
}
}
if (code < 0)
- return code;
+ goto err;
+ rsrc = psrc;
+ if ((code = mcode) < 0)
+ goto err;
if (use_cache)
pic = pic_next;
else {
@@ -354,7 +389,7 @@ fill: /* Fill the region between */
pic = pic_next;
pic_next = ptemp;
}
-set: run.all = next.all;
+set: run = next;
inc: xprev = dda_current(pnext.x);
yprev = dda_current(pnext.y); /* harmless if no skew */
}
@@ -362,4 +397,9 @@ inc: xprev = dda_current(pnext.x);
code = (*dev_proc(dev, fill_parallelogram))
(dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy, pdevc, lop);
return (code < 0 ? code : 1);
+ /* Save position if error, in case we resume. */
+err:
+ penum_orig->used.x = (rsrc - spp - psrc_initial) / spp;
+ penum_orig->used.y = 0;
+ return code;
}
diff --git a/gs/src/gxidata.c b/gs/src/gxidata.c
index ece6b4b66..b86fb0e4b 100644
--- a/gs/src/gxidata.c
+++ b/gs/src/gxidata.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,11 +33,13 @@ private void repack_bit_planes(P7(const gx_image_plane_t *src_planes,
/* Process the next piece of an ImageType 1 image. */
int
-gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
- const gx_image_plane_t * planes, int height)
+gx_image1_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
{
+ gx_device *dev = info->dev;
gx_image_enum *penum = (gx_image_enum *) info;
- int y = penum->y;
+ const int y = penum->y;
int y_end = min(y + height, penum->rect.h);
int width_spp = penum->rect.w * penum->spp;
int num_planes = penum->num_planes;
@@ -52,30 +54,44 @@ gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
bool bit_planar = penum->num_planes > penum->spp;
int code;
- if (height == 0)
+ if (height == 0) {
+ *rows_used = 0;
return 0;
+ }
/* Set up the clipping and/or RasterOp device if needed. */
if (penum->clip_dev) {
gx_device_clip *cdev = penum->clip_dev;
- cdev->target = dev;
+ gx_device_set_target((gx_device_forward *)cdev, dev);
dev = (gx_device *) cdev;
}
if (penum->rop_dev) {
gx_device_rop_texture *rtdev = penum->rop_dev;
- ((gx_device_forward *) rtdev)->target = dev;
+ gx_device_set_target((gx_device_forward *)rtdev, dev);
dev = (gx_device *) rtdev;
}
/* Now render complete rows. */
- memset(offsets, 0, num_planes * sizeof(offsets[0]));
+ if (penum->used.y) {
+ /*
+ * Processing was interrupted by an error. Skip over rows
+ * already processed.
+ */
+ int px;
+
+ for (px = 0; px < num_planes; ++px)
+ offsets[px] = planes[px].raster * penum->used.y;
+ penum->used.y = 0;
+ } else
+ memset(offsets, 0, num_planes * sizeof(offsets[0]));
for (; penum->y < y_end; penum->y++) {
int px;
const byte *buffer;
int sourcex;
+ int x_used = penum->used.x;
if (bit_planar) {
/* Repack the bit planes into byte-wide samples. */
@@ -115,6 +131,10 @@ gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
if (gs_debug_c('B')) {
int i, n = width_spp;
+ if (penum->bps > 8)
+ n *= 2;
+ else if (penum->bps == 1 && penum->unpack_bps == 8)
+ n = (n + 7) / 8;
dlputs("[B]row:");
for (i = 0; i < n; i++)
dprintf1(" %02x", buffer[i]);
@@ -130,7 +150,8 @@ gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
case image_portrait:
{ /* Precompute integer y and height, */
/* and check for clipping. */
- fixed yc = penum->cur.y, yn = dda_current(penum->dda.row.y);
+ fixed yc = penum->cur.y,
+ yn = dda_current(penum->dda.row.y);
if (yn < yc) {
fixed temp = yn;
@@ -148,11 +169,14 @@ gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
penum->hci = fixed2int_pixround(yn) - penum->yci;
if (penum->hci == 0)
goto mt;
+ if_debug2('b', "[b]yci=%d, hci=%d\n",
+ penum->yci, penum->hci);
}
break;
case image_landscape:
{ /* Check for no pixel centers in x. */
- fixed xc = penum->cur.x, xn = dda_current(penum->dda.row.x);
+ fixed xc = penum->cur.x,
+ xn = dda_current(penum->dda.row.x);
if (xn < xc) {
fixed temp = xn;
@@ -170,43 +194,61 @@ gx_image1_plane_data(gx_device * dev, gx_image_enum_common_t * info,
penum->wci = fixed2int_pixround(xn) - penum->xci;
if (penum->wci == 0)
goto mt;
+ if_debug2('b', "[b]xci=%d, wci=%d\n",
+ penum->xci, penum->wci);
}
break;
case image_skewed:
;
}
- dda_translate(penum->dda.pixel0.x,
+ dda_translate(penum->dda.strip.x,
penum->cur.x - penum->prev.x);
- dda_translate(penum->dda.pixel0.y,
+ dda_translate(penum->dda.strip.y,
penum->cur.y - penum->prev.y);
+ penum->dda.pixel0 = penum->dda.strip;
+ if (x_used) {
+ /*
+ * Processing was interrupted by an error. Skip over pixels
+ * already processed.
+ */
+ dda_advance(penum->dda.pixel0.x, penum->used.x);
+ dda_advance(penum->dda.pixel0.y, penum->used.x);
+ penum->used.x = 0;
+ }
+ if_debug2('b', "[b]pixel0 x=%g, y=%g\n",
+ fixed2float(dda_current(penum->dda.pixel0.x)),
+ fixed2float(dda_current(penum->dda.pixel0.y)));
+ code = (*penum->render)(penum, buffer, sourcex + x_used,
+ width_spp - x_used * penum->spp, 1, dev);
+ if (code < 0) {
+ /* Error or interrupt, restore original state. */
+ penum->used.x += x_used;
+ if (!penum->used.y) {
+ dda_previous(penum->dda.row.x);
+ dda_previous(penum->dda.row.y);
+ dda_translate(penum->dda.strip.x,
+ penum->prev.x - penum->cur.x);
+ dda_translate(penum->dda.strip.y,
+ penum->prev.y - penum->cur.y);
+ }
+ goto out;
+ }
penum->prev = penum->cur;
- code = (*penum->render) (penum, buffer, sourcex, width_spp, 1,
- dev);
- if (code < 0)
- goto err;
mt:;
}
if (penum->y < penum->rect.h) {
code = 0;
- goto out;
- }
- /* End of data. Render any left-over buffered data. */
- code = gx_image1_flush(info);
- if (code < 0) {
- penum->y--;
- goto err;
- }
- code = 1;
- goto out;
- err: /* Error or interrupt, restore original state. */
- while (penum->y > y) {
- dda_previous(penum->dda.row.x);
- dda_previous(penum->dda.row.y);
- --(penum->y);
+ } else {
+ /* End of input data. Render any left-over buffered data. */
+ code = gx_image1_flush(info);
+ if (code >= 0)
+ code = 1;
}
+out:
/* Note that caller must call end_image */
/* for both error and normal termination. */
- out:return code;
+ *rows_used = penum->y - y;
+ return code;
}
/* Flush any buffered data. */
@@ -353,23 +395,26 @@ repack_bit_planes(const gx_image_plane_t *src_planes, const ulong *offsets,
}
/* Clean up by releasing the buffers. */
+/* Currently we ignore draw_last. */
int
-gx_image1_end_image(gx_device *ignore_dev, gx_image_enum_common_t * info,
- bool draw_last)
+gx_image1_end_image(gx_image_enum_common_t * info, bool draw_last)
{
gx_image_enum *penum = (gx_image_enum *) info;
gs_memory_t *mem = penum->memory;
- stream_IScale_state *scaler = penum->scaler;
-
- if (draw_last)
- gx_image1_flush(info);
+ stream_image_scale_state *scaler = penum->scaler;
if_debug2('b', "[b]%send_image, y=%d\n",
(penum->y < penum->rect.h ? "premature " : ""), penum->y);
+ if (draw_last) {
+ int code = gx_image_flush(info);
+
+ if (code < 0)
+ return code;
+ }
gs_free_object(mem, penum->rop_dev, "image RasterOp");
gs_free_object(mem, penum->clip_dev, "image clipper");
if (scaler != 0) {
- (*s_IScale_template.release) ((stream_state *) scaler);
+ (*scaler->template->release) ((stream_state *) scaler);
gs_free_object(mem, scaler, "image scaler state");
}
gs_free_object(mem, penum->line, "image line");
diff --git a/gs/src/gxifast.c b/gs/src/gxifast.c
index 536ab3a86..3b04fc583 100644
--- a/gs/src/gxifast.c
+++ b/gs/src/gxifast.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,7 +33,6 @@
#include "gxcmap.h"
#include "gxdcolor.h"
#include "gxistate.h"
-#include "gzpath.h"
#include "gxdevmem.h"
#include "gdevmem.h" /* for mem_mono_device */
#include "gxcpath.h"
@@ -51,8 +50,8 @@
private irender_proc(image_render_skip);
private irender_proc(image_render_simple);
private irender_proc(image_render_landscape);
-private irender_proc_t
-image_strategy_simple(gx_image_enum * penum)
+irender_proc_t
+gs_image_class_1_simple(gx_image_enum * penum)
{
irender_proc_t rproc;
fixed ox = dda_current(penum->dda.pixel0.x);
@@ -102,7 +101,7 @@ image_strategy_simple(gx_image_enum * penum)
long line_size =
(dev_width = any_abs(dev_width),
bitmap_raster(dev_width) * 8 +
- round_up(dev_width, 8) * align_bitmap_mod);
+ ROUND_UP(dev_width, 8) * align_bitmap_mod);
if ((dev_width != penum->rect.w && penum->adjust != 0) ||
line_size > max_uint
@@ -167,12 +166,6 @@ image_strategy_simple(gx_image_enum * penum)
return rproc;
}
-void
-gs_gxifast_init(gs_memory_t * mem)
-{
- image_strategies.simple = image_strategy_simple;
-}
-
/* ------ Rendering procedures ------ */
/* Skip over a completely transparent image. */
@@ -472,7 +465,7 @@ copy_portrait(gx_image_enum * penum, const byte * data, int dx, int raster,
{
const gx_device_color *pdc0;
const gx_device_color *pdc1;
- uint align = alignment_mod(data, align_bitmap_mod);
+ uint align = ALIGNMENT_MOD(data, align_bitmap_mod);
/*
* We know that the lookup table maps 1 bit to 1 bit,
@@ -543,6 +536,7 @@ image_render_simple(gx_image_enum * penum, const byte * buffer, int data_x,
int line_x;
fixed xcur = dda_current(penum->dda.pixel0.x);
int ix = fixed2int_pixround(xcur);
+ int ixr;
const int iy = penum->yci, ih = penum->hci;
const gx_device_color * const pdc0 = &penum->icolor0;
const gx_device_color * const pdc1 = &penum->icolor1;
@@ -557,12 +551,20 @@ image_render_simple(gx_image_enum * penum, const byte * buffer, int data_x,
line_x = 0;
} else if (copy_mono == dev_proc(&mem_mono_device, copy_mono) &&
dxx > 0 && gx_dc_is_pure(pdc1) && gx_dc_is_pure(pdc0) &&
- /* We know the colors must be (0,1) or (1,0). */
+ /* We know the colors must be (0,1) or (1,0). */
(pdc0->colors.pure ^ pdc1->colors.pure) == 1 &&
- !penum->clip_image
+ !penum->clip_image &&
+ /*
+ * Even if clip_image is false, the clipping rectangle
+ * might lie partly outside the device coordinate space
+ * if the Margins values are non-zero.
+ */
+ ix >= 0 &&
+ (ixr = fixed2int_pixround(xcur + penum->x_extent.x) - 1) <
+ dev->width &&
+ iy >= 0 && iy + ih <= dev->height
) {
/* Do the operation directly into the memory device bitmap. */
- int ixr = fixed2int_pixround(xcur + penum->x_extent.x) - 1;
int line_ix;
int ib_left = ix >> 3, ib_right = ixr >> 3;
byte *scan_line = scan_line_base((gx_device_memory *) dev, iy);
diff --git a/gs/src/gxiinit.c b/gs/src/gxiinit.c
deleted file mode 100644
index 1c39cc92a..000000000
--- a/gs/src/gxiinit.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
-
-/* Image setup procedures for Ghostscript library */
-#include "gx.h"
-#include "math_.h"
-#include "memory_.h"
-#include "gpcheck.h"
-#include "gserrors.h"
-#include "gsstruct.h"
-#include "gsutil.h"
-#include "gxfixed.h"
-#include "gxfrac.h"
-#include "gxarith.h"
-#include "gxmatrix.h"
-#include "gsccolor.h"
-#include "gspaint.h"
-#include "gzstate.h"
-#include "gxdevice.h"
-#include "gzpath.h"
-#include "gzcpath.h"
-#include "gxdevmem.h"
-#include "gximage.h"
-#include "gxiparam.h"
-#include "gdevmrop.h"
-
-/* ---------------- Generic image support ---------------- */
-
-/* Initialize the common parts of image structures. */
-void
-gs_image_common_t_init(gs_image_common_t * pic)
-{
- gs_make_identity(&pic->ImageMatrix);
-}
-void
-gs_data_image_t_init(gs_data_image_t * pim, int num_components)
-{
- int i;
-
- gs_image_common_t_init((gs_image_common_t *) pim);
- pim->Width = pim->Height = 0;
- pim->BitsPerComponent = 1;
- if (num_components >= 0) {
- for (i = 0; i < num_components * 2; i += 2)
- pim->Decode[i] = 0, pim->Decode[i + 1] = 1;
- } else {
- for (i = 0; i < num_components * -2; i += 2)
- pim->Decode[i] = 1, pim->Decode[i + 1] = 0;
- }
- pim->Interpolate = false;
-}
-void
-gs_pixel_image_t_init(gs_pixel_image_t * pim, const gs_color_space * color_space)
-{
- int num_components;
-
- if (color_space == 0 ||
- (num_components =
- gs_color_space_num_components(color_space)) < 0
- )
- num_components = 0;
- gs_data_image_t_init((gs_data_image_t *) pim, num_components);
- pim->format = gs_image_format_chunky;
- pim->ColorSpace = color_space;
- pim->CombineWithColor = false;
-}
-
-/* Initialize the common part of an image-processing enumerator. */
-int
-gx_image_enum_common_init(gx_image_enum_common_t * piec,
- const gs_image_common_t * pic, const gx_image_enum_procs_t * piep,
- gx_device * dev, int bits_per_component, int num_components,
- gs_image_format_t format)
-{
- piec->image_type = pic->type;
- piec->procs = piep;
- piec->dev = dev;
- piec->id = gs_next_ids(1);
- switch (format) {
- case gs_image_format_chunky:
- piec->num_planes = 1;
- piec->plane_depths[0] = bits_per_component * num_components;
- break;
- case gs_image_format_component_planar:
- piec->num_planes = num_components;
- {
- int i;
-
- for (i = 0; i < num_components; ++i)
- piec->plane_depths[i] = bits_per_component;
- }
- break;
- case gs_image_format_bit_planar:
- piec->num_planes = bits_per_component * num_components;
- {
- int i;
-
- for (i = 0; i < piec->num_planes; ++i)
- piec->plane_depths[i] = 1;
- }
-#if 0 /* **************** */
- break;
-#endif /* **************** */
- default:
- return_error(gs_error_rangecheck);
- }
- return 0;
-}
-
-/* ---------------- ImageType 1 images ---------------- */
-
-/* Structure descriptors */
-private_st_gx_image_enum();
-public_st_gs_image_common();
-public_st_gs_data_image();
-public_st_gs_pixel_image();
-
-/* Strategy procedures */
-gx_image_strategies_t image_strategies;
-
-/* Define the image type for ImageType 1 images. */
-private const gx_image_type_t image1_type = {
- gx_begin_image1, gx_data_image_source_size, 1
-};
-private const gx_image_enum_procs_t image1_enum_procs = {
- gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
-};
-
-/* Define the procedures for initializing gs_image_ts to default values. */
-void
-gs_image_t_init(gs_image_t * pim, const gs_color_space * color_space)
-{
- gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
- pim->type = &image1_type;
- pim->ImageMask = pim->adjust = (color_space == NULL);
- pim->Alpha = gs_image_alpha_none;
-}
-void
-gs_image_t_init_mask(gs_image_t * pim, bool write_1s)
-{
- gs_image_t_init(pim, NULL);
- if (write_1s)
- pim->Decode[0] = 1, pim->Decode[1] = 0;
- else
- pim->Decode[0] = 0, pim->Decode[1] = 1;
-}
-
-/* Compute the source size of an ordinary image with explicit data. */
-int
-gx_data_image_source_size(const gs_imager_state * pis,
- const gs_image_common_t * pim, gs_int_point * psize)
-{
- const gs_data_image_t *pdi = (const gs_data_image_t *)pim;
-
- psize->x = pdi->Width;
- psize->y = pdi->Height;
- return 0;
-}
-
-/* Process the next piece of an image with no source data. */
-/* This procedure should never be called. */
-int
-gx_no_image_plane_data(gx_device * dev,
- gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height)
-{
- return_error(gs_error_Fatal);
-}
-
-/* Clean up after processing an image with no source data. */
-/* This procedure may be called, but should do nothing. */
-int
-gx_ignore_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
-{
- return 0;
-}
-
-/* GC procedures */
-#define eptr ((gx_image_enum *)vptr)
-private
-ENUM_PTRS_BEGIN(image_enum_enum_ptrs)
-{
- int bps;
- gs_ptr_type_t ret;
-
- /* Enumerate the used members of clues.dev_color. */
- index -= gx_image_enum_num_ptrs;
- bps = eptr->unpack_bps;
- if (eptr->spp != 1)
- bps = 8;
- else if (bps > 8 || eptr->unpack == sample_unpack_copy)
- bps = 1;
- if (index >= (1 << bps) * st_device_color_max_ptrs) /* done */
- return 0;
- ret = ENUM_USING(st_device_color,
- &eptr->clues[(index / st_device_color_max_ptrs) *
- (255 / ((1 << bps) - 1))].dev_color,
- sizeof(eptr->clues[0].dev_color),
- index % st_device_color_max_ptrs);
- if (ret == 0) /* don't stop early */
- ENUM_RETURN(0);
- return ret;
-}
-#define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
-gx_image_enum_do_ptrs(e1)
-#undef e1
-ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(image_enum_reloc_ptrs)
-{
- int i;
-
-#define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
- gx_image_enum_do_ptrs(r1)
-#undef r1
- {
- int bps = eptr->unpack_bps;
-
- if (eptr->spp != 1)
- bps = 8;
- else if (bps > 8 || eptr->unpack == sample_unpack_copy)
- bps = 1;
- for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
- RELOC_USING(st_device_color,
- &eptr->clues[i].dev_color, sizeof(gx_device_color));
- }
-}
-RELOC_PTRS_END
-#undef eptr
-
-/* Forward declarations */
-private int color_draws_b_w(P2(gx_device * dev,
- const gx_drawing_color * pdcolor));
-private void image_init_map(P3(byte * map, int map_size, const float *decode));
-private void image_init_colors(P9(gx_image_enum * penum, int bps, int spp,
- bool multi, const float *decode,
- const gs_imager_state * pis, gx_device * dev,
- const gs_color_space * pcs, bool * pdcb));
-
-/* Procedures for unpacking the input data into bytes or fracs. */
- /*extern sample_unpack_proc(sample_unpack_copy); *//* declared above */
-extern sample_unpack_proc(sample_unpack_1);
-extern sample_unpack_proc(sample_unpack_2);
-extern sample_unpack_proc(sample_unpack_4);
-extern sample_unpack_proc(sample_unpack_8);
-
-sample_unpack_proc((*sample_unpack_12_proc)); /* optional */
-
-/* Start processing an ImageType 1 image. */
-/* Note that since this is actually a begin_typed_image procedure, */
-/* the type of pim is the more abstract one. */
-int
-gx_begin_image1(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 * mem, gx_image_enum_common_t ** pinfo)
-{
- const gs_image_t *pim = (const gs_image_t *)pic;
- gs_image_format_t format = pim->format;
- gx_image_enum *penum;
- const int width = pim->Width;
- const int height = pim->Height;
- const int bps = pim->BitsPerComponent;
- bool masked = pim->ImageMask;
- const float *decode = pim->Decode;
- bool multi;
- int index_bps;
- const gs_color_space *pcs = pim->ColorSpace;
- gs_logical_operation_t lop = (pis ? pis->log_op : lop_default);
- int code;
- gs_matrix mat;
- int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
- int spp, nplanes, spread;
- uint bsize;
- byte *buffer;
- fixed mtx, mty;
- gs_fixed_point row_extent, col_extent, x_extent, y_extent;
- bool device_color;
- gs_fixed_rect obox, cbox;
- fixed adjust;
-
- if (width < 0 || height < 0)
- return_error(gs_error_rangecheck);
- switch (format) {
- case gs_image_format_chunky:
- multi = false;
- break;
- case gs_image_format_component_planar:
- multi = true;
- break;
- default:
- return_error(gs_error_rangecheck);
- }
- switch (bps) {
- case 1:
- index_bps = 0;
- break;
- case 2:
- index_bps = 1;
- break;
- case 4:
- index_bps = 2;
- break;
- case 8:
- index_bps = 3;
- break;
- case 12:
- index_bps = 4;
- break;
- default:
- return_error(gs_error_rangecheck);
- }
- if (prect) {
- if (prect->p.x < 0 || prect->p.y < 0 ||
- prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
- prect->q.x > width || prect->q.y > height
- )
- return_error(gs_error_rangecheck);
- }
- if (pmat == 0)
- pmat = &ctm_only(pis);
- if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
- (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0 ||
- (code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
- (floatp) width, (floatp) 0,
- &row_extent)) < 0 ||
- (code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
- (floatp) 0, (floatp) height,
- &col_extent)) < 0
- )
- return code;
- penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
- "gx_default_begin_image");
- if (penum == 0)
- return_error(gs_error_VMerror);
- gx_image_enum_common_init((gx_image_enum_common_t *) penum, pic,
- &image1_enum_procs, dev, bps,
- (masked ? 1 : cs_num_components(pcs)),
- format);
- if (prect) {
- penum->rect.x = prect->p.x, penum->rect.y = prect->p.y;
- penum->rect.w = prect->q.x - prect->p.x,
- penum->rect.h = prect->q.y - prect->p.y;
- if ((code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
- (floatp) penum->rect.w, (floatp) 0,
- &x_extent)) < 0 ||
- (code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
- (floatp) 0, (floatp) penum->rect.h,
- &y_extent)) < 0
- ) {
- gs_free_object(mem, penum, "gx_default_begin_image");
- return code;
- }
- } else {
- penum->rect.x = 0, penum->rect.y = 0;
- penum->rect.w = width, penum->rect.h = height;
- x_extent = row_extent;
- y_extent = col_extent;
- }
- if ((penum->masked = masked)) { /* This is imagemask. */
- if (bps != 1 || multi || pcs != NULL || pim->Alpha ||
- !((decode[0] == 0.0 && decode[1] == 1.0) ||
- (decode[0] == 1.0 && decode[1] == 0.0))
- ) {
- gs_free_object(mem, penum, "gx_default_begin_image");
- return_error(gs_error_rangecheck);
- }
- /* Initialize color entries 0 and 255. */
- color_set_pure(&penum->icolor0, gx_no_color_index);
- penum->icolor1 = *pdcolor;
- memcpy(&penum->map[0].table.lookup4x1to32[0],
- (decode[0] == 0 ? lookup4x1to32_inverted :
- lookup4x1to32_identity),
- 16 * 4);
- penum->map[0].decoding = sd_none;
- spp = 1;
- adjust = (pim->adjust ? float2fixed(0.25) : fixed_0);
- lop = rop3_know_S_0(lop);
- } else { /* This is image, not imagemask. */
- const gs_color_space_type *pcst = pcs->type;
- int b_w_color;
-
- spp = cs_num_components(pcs);
- if (spp < 0) { /* Pattern not allowed */
- gs_free_object(mem, penum, "gx_default_begin_image");
- return_error(gs_error_rangecheck);
- }
- if (pim->Alpha)
- ++spp;
- if (spp == 1)
- multi = false;
- device_color = (*pcst->concrete_space) (pcs, pis) == pcs;
- image_init_colors(penum, bps, spp, multi, decode, pis, dev,
- pcs, &device_color);
- adjust = fixed_0;
- /* Try to transform non-default RasterOps to something */
- /* that we implement less expensively. */
- if (!pim->CombineWithColor)
- lop = rop3_know_T_0(lop) & ~lop_T_transparent;
- else {
- if (rop3_uses_T(lop))
- switch (color_draws_b_w(dev, pdcolor)) {
- case 0:
- lop = rop3_know_T_0(lop);
- break;
- case 1:
- lop = rop3_know_T_1(lop);
- break;
- default:
- ;
- }
- }
- if (lop != rop3_S && /* if best case, no more work needed */
- !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
- (b_w_color =
- color_draws_b_w(dev, &penum->icolor0)) >= 0 &&
- color_draws_b_w(dev, &penum->icolor1) == (b_w_color ^ 1)
- ) {
- if (b_w_color) { /* Swap the colors and invert the RasterOp source. */
- gx_device_color dcolor;
-
- dcolor = penum->icolor0;
- penum->icolor0 = penum->icolor1;
- penum->icolor1 = dcolor;
- lop = rop3_invert_S(lop);
- }
- /*
- * At this point, we know that the source pixels
- * correspond directly to the S input for the raster op,
- * i.e., icolor0 is black and icolor1 is white.
- */
- switch (lop) {
- case rop3_D & rop3_S:
- /* Implement this as an inverted mask writing 0s. */
- penum->icolor1 = penum->icolor0;
- /* (falls through) */
- case rop3_D | rop3_not(rop3_S):
- /* Implement this as an inverted mask writing 1s. */
- memcpy(&penum->map[0].table.lookup4x1to32[0],
- lookup4x1to32_inverted, 16 * 4);
- rmask: /* Fill in the remaining parameters for a mask. */
- penum->masked = masked = true;
- color_set_pure(&penum->icolor0, gx_no_color_index);
- penum->map[0].decoding = sd_none;
- lop = rop3_T;
- break;
- case rop3_D & rop3_not(rop3_S):
- /* Implement this as a mask writing 0s. */
- penum->icolor1 = penum->icolor0;
- /* (falls through) */
- case rop3_D | rop3_S:
- /* Implement this as a mask writing 1s. */
- memcpy(&penum->map[0].table.lookup4x1to32[0],
- lookup4x1to32_identity, 16 * 4);
- goto rmask;
- default:
- ;
- }
- }
- }
- penum->device_color = device_color;
- /*
- * Adjust width upward for unpacking up to 7 trailing bits in
- * the row, plus 1 byte for end-of-run, plus up to 7 leading
- * bits for data_x offset within a packed byte.
- */
- bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
- buffer = gs_alloc_bytes(mem, bsize, "image buffer");
- if (buffer == 0) {
- gs_free_object(mem, penum, "gx_default_begin_image");
- return_error(gs_error_VMerror);
- }
- penum->bps = bps;
- penum->unpack_bps = bps;
- penum->log2_xbytes = log2_xbytes;
- penum->spp = spp;
- penum->alpha = pim->Alpha;
- nplanes = (multi ? spp : 1);
- penum->num_planes = nplanes;
- spread = nplanes << log2_xbytes;
- penum->spread = spread;
- penum->matrix = mat;
- penum->x_extent = x_extent;
- penum->y_extent = y_extent;
- penum->posture =
- ((x_extent.y | y_extent.x) == 0 ? image_portrait :
- (x_extent.x | y_extent.y) == 0 ? image_landscape :
- image_skewed);
- mtx = float2fixed(mat.tx);
- mty = float2fixed(mat.ty);
- penum->pis = pis;
- penum->pcs = pcs;
- penum->memory = mem;
- penum->buffer = buffer;
- penum->buffer_size = bsize;
- penum->line = 0;
- penum->line_size = 0;
- /*
- * If we're asked to interpolate in a partial image, we have to
- * assume that the client either really only is interested in
- * the given sub-image, or else is constructing output out of
- * overlapping pieces.
- */
- penum->interpolate = pim->Interpolate;
- penum->use_rop = lop != (masked ? rop3_T : rop3_S);
-#ifdef DEBUG
- if (gs_debug_c('*')) {
- if (penum->use_rop)
- dprintf1("[%03x]", lop);
- dprintf5("%c%d%c%dx%d ",
- (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
- bps,
- (penum->posture == image_portrait ? ' ' :
- penum->posture == image_landscape ? 'L' : 'T'),
- width, height);
- }
-#endif
- penum->slow_loop = 0;
- if (pcpath == 0) {
- (*dev_proc(dev, get_clipping_box)) (dev, &obox);
- cbox = obox;
- penum->clip_image = 0;
- } else
- penum->clip_image =
- (gx_cpath_outer_box(pcpath, &obox) | /* not || */
- gx_cpath_inner_box(pcpath, &cbox) ?
- 0 : image_clip_region);
- penum->clip_outer = obox;
- penum->clip_inner = cbox;
- penum->log_op = rop3_T; /* rop device takes care of this */
- penum->clip_dev = 0; /* in case we bail out */
- penum->rop_dev = 0; /* ditto */
- penum->scaler = 0; /* ditto */
- /*
- * If all four extrema of the image fall within the clipping
- * rectangle, clipping is never required. When making this check,
- * we must carefully take into account the fact that we only care
- * about pixel centers.
- */
- {
- fixed
- epx = min(row_extent.x, 0) + min(col_extent.x, 0),
- eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
- epy = min(row_extent.y, 0) + min(col_extent.y, 0),
- eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
-
- {
- int hwx, hwy;
-
- switch (penum->posture) {
- case image_portrait:
- hwx = width, hwy = height;
- break;
- case image_landscape:
- hwx = height, hwy = width;
- break;
- default:
- hwx = hwy = 0;
- }
- /*
- * If the image is only 1 sample wide or high,
- * and is less than 1 device pixel wide or high,
- * move it slightly so that it covers pixel centers.
- * This is a hack to work around a bug in some old
- * versions of TeX/dvips, which use 1-bit-high images
- * to draw horizontal and vertical lines without
- * positioning them properly.
- */
- if (hwx == 1 && eqx - epx < fixed_1) {
- fixed diff =
- arith_rshift_1(row_extent.x + col_extent.x);
-
- mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
- }
- if (hwy == 1 && eqy - epy < fixed_1) {
- fixed diff =
- arith_rshift_1(row_extent.y + col_extent.y);
-
- mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
- }
- }
- if_debug5('b', "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
- (masked? "masked, " : ""), spp, bps,
- fixed2float(mtx), fixed2float(mty));
- if_debug9('b',
- "[b] cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
- fixed2float(cbox.p.x), fixed2float(cbox.p.y),
- fixed2float(cbox.q.x), fixed2float(cbox.q.y),
- fixed2float(obox.p.x), fixed2float(obox.p.y),
- fixed2float(obox.q.x), fixed2float(obox.q.y),
- penum->clip_image);
- dda_init(penum->dda.row.x, mtx, col_extent.x, height);
- dda_init(penum->dda.row.y, mty, col_extent.y, height);
- if (penum->rect.y) {
- dda_advance(penum->dda.row.x, penum->rect.y);
- dda_advance(penum->dda.row.y, penum->rect.y);
- }
- penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
- penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
- dda_init(penum->dda.pixel0.x, penum->cur.x, row_extent.x,
- width);
- dda_init(penum->dda.pixel0.y, penum->cur.y, row_extent.y,
- width);
- if (penum->rect.x) {
- dda_advance(penum->dda.pixel0.x, penum->rect.x);
- dda_advance(penum->dda.pixel0.y, penum->rect.x);
- } {
- fixed ox = dda_current(penum->dda.pixel0.x);
- fixed oy = dda_current(penum->dda.pixel0.y);
-
- if (!penum->clip_image) /* i.e., not clip region */
- penum->clip_image =
- (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
- image_clip_xmin : 0) +
- (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
- image_clip_xmax : 0) +
- (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
- image_clip_ymin : 0) +
- (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
- image_clip_ymax : 0);
- }
- }
- penum->y = 0;
- penum->adjust = adjust;
- {
- static const sample_unpack_proc_t procs[4] =
- {
- sample_unpack_1, sample_unpack_2,
- sample_unpack_4, sample_unpack_8
- };
-
- if (index_bps == 4) {
- if ((penum->unpack = sample_unpack_12_proc) == 0) { /* 12-bit samples are not supported. */
- gx_default_end_image(dev,
- (gx_image_enum_common_t *) penum,
- false);
- return_error(gs_error_rangecheck);
- }
- } else {
- penum->unpack = procs[index_bps];
- if_debug1('b', "[b]unpack=%d\n", bps);
- }
-#define use_strategy(sp)\
- (image_strategies.sp != 0 &&\
- (penum->render = (*image_strategies.sp)(penum)) != 0)
- if (
- use_strategy(interpolate) ||
- use_strategy(simple) ||
- use_strategy(fracs) ||
- use_strategy(mono) ||
- use_strategy(color)
- )
- DO_NOTHING;
-#undef use_strategy
- else { /* No available strategy can handle this image. */
- gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
- false);
- return_error(gs_error_rangecheck);
- }
- }
- if (penum->clip_image && pcpath) { /* Set up the clipping device. */
- gx_device_clip *cdev =
- gs_alloc_struct(mem, gx_device_clip,
- &st_device_clip, "image clipper");
-
- if (cdev == 0) {
- gx_default_end_image(dev,
- (gx_image_enum_common_t *) penum,
- false);
- return_error(gs_error_VMerror);
- }
- gx_make_clip_device(cdev, cdev, gx_cpath_list(pcpath));
- cdev->target = dev;
- (*dev_proc(cdev, open_device)) ((gx_device *) cdev);
- penum->clip_dev = cdev;
- }
- if (penum->use_rop) { /* Set up the RasterOp source device. */
- gx_device_rop_texture *rtdev;
-
- code = gx_alloc_rop_texture_device(&rtdev, mem,
- "image RasterOp");
- if (code < 0) {
- gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
- false);
- return code;
- }
- gx_make_rop_texture_device(rtdev,
- (penum->clip_dev != 0 ?
- (gx_device *) penum->clip_dev :
- dev), lop, pdcolor);
- penum->rop_dev = rtdev;
- }
-#ifdef DEBUG
- if (gs_debug_c('b')) {
- dlprintf2("[b]Image: w=%d h=%d", width, height);
- if (prect)
- dprintf4(" ((%d,%d),(%d,%d))",
- prect->p.x, prect->p.y, prect->q.x, prect->q.y);
- dprintf6(" [%g %g %g %g %g %g]\n",
- mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
- }
-#endif
- *pinfo = (gx_image_enum_common_t *) penum;
- return 0;
-}
-
-/* If a drawing color is black or white, return 0 or 1 respectively, */
-/* otherwise return -1. */
-private int
-color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
-{
- if (color_is_pure(pdcolor)) {
- gx_color_value rgb[3];
-
- (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
- rgb);
- if (!(rgb[0] | rgb[1] | rgb[2]))
- return 0;
- if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
- return 1;
- }
- return -1;
-}
-
-/* Initialize the color mapping tables for a non-mask image. */
-private void
-image_init_colors(gx_image_enum * penum, int bps, int spp, bool multi,
- const float *decode /*[spp*2] */ , const gs_imager_state * pis, gx_device * dev,
- const gs_color_space * pcs, bool * pdcb)
-{
- int ci;
- static const float default_decode[] =
- {
- 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
- };
-
- /* Initialize the color table */
-
-#define ictype(i)\
- penum->clues[i].dev_color.type
- switch ((spp == 1 ? bps : 8)) {
- case 8: /* includes all color images */
- {
- register gx_image_clue *pcht = &penum->clues[0];
- register int n = 64;
-
- do {
- pcht[0].dev_color.type =
- pcht[1].dev_color.type =
- pcht[2].dev_color.type =
- pcht[3].dev_color.type =
- gx_dc_type_none;
- pcht[0].key = pcht[1].key =
- pcht[2].key = pcht[3].key = 0;
- pcht += 4;
- }
- while (--n > 0);
- penum->clues[0].key = 1; /* guarantee no hit */
- break;
- }
- case 4:
- ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
- ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
- ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
- ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
- gx_dc_type_none;
- /* falls through */
- case 2:
- ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
-#undef ictype
- }
-
- /* Initialize the maps from samples to intensities. */
-
- for (ci = 0; ci < spp; ci++) {
- sample_map *pmap = &penum->map[ci];
-
- /* If the decoding is [0 1] or [1 0], we can fold it */
- /* into the expansion of the sample values; */
- /* otherwise, we have to use the floating point method. */
-
- const float *this_decode = &decode[ci * 2];
- const float *map_decode; /* decoding used to */
-
- /* construct the expansion map */
-
- const float *real_decode; /* decoding for */
-
- /* expanded samples */
-
- bool no_decode;
-
- map_decode = real_decode = this_decode;
- if (map_decode[0] == 0.0 && map_decode[1] == 1.0)
- no_decode = true;
- else if (map_decode[0] == 1.0 && map_decode[1] == 0.0)
- no_decode = true,
- real_decode = default_decode;
- else
- no_decode = false,
- *pdcb = false,
- map_decode = default_decode;
- if (bps > 2 || multi) {
- if (bps <= 8)
- image_init_map(&pmap->table.lookup8[0], 1 << bps,
- map_decode);
- } else { /* The map index encompasses more than one pixel. */
- byte map[4];
- register int i;
-
- image_init_map(&map[0], 1 << bps, map_decode);
- switch (bps) {
- case 1:
- {
- register bits32 *p = &pmap->table.lookup4x1to32[0];
-
- if (map[0] == 0 && map[1] == 0xff)
- memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
- else if (map[0] == 0xff && map[1] == 0)
- memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
- else
- for (i = 0; i < 16; i++, p++)
- ((byte *) p)[0] = map[i >> 3],
- ((byte *) p)[1] = map[(i >> 2) & 1],
- ((byte *) p)[2] = map[(i >> 1) & 1],
- ((byte *) p)[3] = map[i & 1];
- }
- break;
- case 2:
- {
- register bits16 *p = &pmap->table.lookup2x2to16[0];
-
- for (i = 0; i < 16; i++, p++)
- ((byte *) p)[0] = map[i >> 2],
- ((byte *) p)[1] = map[i & 3];
- }
- break;
- }
- }
- pmap->decode_base /* = decode_lookup[0] */ = real_decode[0];
- pmap->decode_factor =
- (real_decode[1] - real_decode[0]) /
- (bps <= 8 ? 255.0 : (float)frac_1);
- pmap->decode_max /* = decode_lookup[15] */ = real_decode[1];
- if (no_decode)
- pmap->decoding = sd_none;
- else if (bps <= 4) {
- int step = 15 / ((1 << bps) - 1);
- int i;
-
- pmap->decoding = sd_lookup;
- for (i = 15 - step; i > 0; i -= step)
- pmap->decode_lookup[i] = pmap->decode_base +
- i * (255.0 / 15) * pmap->decode_factor;
- } else
- pmap->decoding = sd_compute;
- if (spp == 1) { /* and ci == 0 *//* Pre-map entries 0 and 255. */
- gs_client_color cc;
-
- cc.paint.values[0] = real_decode[0];
- (*pcs->type->remap_color) (&cc, pcs, &penum->icolor0,
- pis, dev, gs_color_select_source);
- cc.paint.values[0] = real_decode[1];
- (*pcs->type->remap_color) (&cc, pcs, &penum->icolor1,
- pis, dev, gs_color_select_source);
- }
- }
-
-}
-/* Construct a mapping table for sample values. */
-/* map_size is 2, 4, 16, or 256. Note that 255 % (map_size - 1) == 0, */
-/* so the division 0xffffL / (map_size - 1) is always exact. */
-private void
-image_init_map(byte * map, int map_size, const float *decode)
-{
- float min_v = decode[0];
- float diff_v = decode[1] - min_v;
-
- if (diff_v == 1 || diff_v == -1) { /* We can do the stepping with integers, without overflow. */
- byte *limit = map + map_size;
- uint value = min_v * 0xffffL;
- int diff = diff_v * (0xffffL / (map_size - 1));
-
- for (; map != limit; map++, value += diff)
- *map = value >> 8;
- } else { /* Step in floating point, with clamping. */
- int i;
-
- for (i = 0; i < map_size; ++i) {
- int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
-
- map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
- }
- }
-}
diff --git a/gs/src/gximage.c b/gs/src/gximage.c
index ef93e8347..7d2bc4a49 100644
--- a/gs/src/gximage.c
+++ b/gs/src/gximage.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,6 +18,7 @@
/* Generic image support */
+#include "memory_.h"
#include "gx.h"
#include "gscspace.h"
#include "gserrors.h"
@@ -77,11 +78,14 @@ gs_pixel_image_t_init(gs_pixel_image_t * pim,
/* Initialize the common part of an image-processing enumerator. */
int
gx_image_enum_common_init(gx_image_enum_common_t * piec,
- const gs_image_common_t * pic,
+ const gs_data_image_t * pic,
const gx_image_enum_procs_t * piep,
- gx_device * dev, int bits_per_component,
- int num_components, gs_image_format_t format)
+ gx_device * dev, int num_components,
+ gs_image_format_t format)
{
+ int bpc = pic->BitsPerComponent;
+ int i;
+
piec->image_type = pic->type;
piec->procs = piep;
piec->dev = dev;
@@ -89,29 +93,23 @@ gx_image_enum_common_init(gx_image_enum_common_t * piec,
switch (format) {
case gs_image_format_chunky:
piec->num_planes = 1;
- piec->plane_depths[0] = bits_per_component * num_components;
+ piec->plane_depths[0] = bpc * num_components;
break;
case gs_image_format_component_planar:
piec->num_planes = num_components;
- {
- int i;
-
- for (i = 0; i < num_components; ++i)
- piec->plane_depths[i] = bits_per_component;
- }
+ for (i = 0; i < num_components; ++i)
+ piec->plane_depths[i] = bpc;
break;
case gs_image_format_bit_planar:
- piec->num_planes = bits_per_component * num_components;
- {
- int i;
-
- for (i = 0; i < piec->num_planes; ++i)
- piec->plane_depths[i] = 1;
- }
+ piec->num_planes = bpc * num_components;
+ for (i = 0; i < piec->num_planes; ++i)
+ piec->plane_depths[i] = 1;
break;
default:
return_error(gs_error_rangecheck);
}
+ for (i = 0; i < piec->num_planes; ++i)
+ piec->plane_widths[i] = pic->Width;
return 0;
}
@@ -130,9 +128,9 @@ gx_data_image_source_size(const gs_imager_state * pis,
/* Process the next piece of an image with no source data. */
/* This procedure should never be called. */
int
-gx_no_image_plane_data(gx_device * dev,
- gx_image_enum_common_t * info,
- const gx_image_plane_t * planes, int height)
+gx_no_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *height_used)
{
return_error(gs_error_Fatal);
}
@@ -140,12 +138,81 @@ gx_no_image_plane_data(gx_device * dev,
/* Clean up after processing an image with no source data. */
/* This procedure may be called, but should do nothing. */
int
-gx_ignore_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
+gx_ignore_end_image(gx_image_enum_common_t * info, bool draw_last)
{
return 0;
}
+/* ---------------- Client procedures ---------------- */
+
+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_planes];
+ int i;
+
+#ifdef DEBUG
+ if (num_planes > gs_image_max_planes) {
+ lprintf2("num_planes=%d > gs_image_max_planes=%d!\n",
+ num_planes, gs_image_max_planes);
+ 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)
+{
+ int ignore_rows_used;
+
+ return gx_image_plane_data_rows(info, planes, height, &ignore_rows_used);
+}
+
+int
+gx_image_plane_data_rows(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
+{
+ return info->procs->plane_data(info, planes, height, rows_used);
+}
+
+int
+gx_image_flush(gx_image_enum_common_t * info)
+{
+ int (*flush)(P1(gx_image_enum_common_t *)) = info->procs->flush;
+
+ return (flush ? flush(info) : 0);
+}
+
+bool
+gx_image_planes_wanted(const gx_image_enum_common_t *info, byte *wanted)
+{
+ bool (*planes_wanted)(P2(const gx_image_enum_common_t *, byte *)) =
+ info->procs->planes_wanted;
+
+ if (planes_wanted)
+ return planes_wanted(info, wanted);
+ else {
+ memset(wanted, 0xff, info->num_planes);
+ return true;
+ }
+}
+
+int
+gx_image_end(gx_image_enum_common_t * info, bool draw_last)
+{
+ return info->procs->end_image(info, draw_last);
+}
+
/* ---------------- Serialization ---------------- */
/*
@@ -403,12 +470,12 @@ gx_pixel_image_sget(gs_pixel_image_t *pim, stream *s,
pim->ColorSpace = pcs;
num_components = gs_color_space_num_components(pcs);
num_decode = num_components * 2;
+ if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
+ decode_default_1 = pcs->params.indexed.hival;
if (control & PI_Decode) {
uint dflags = 0x10000;
float *dp = pim->Decode;
- if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
- decode_default_1 = pcs->params.indexed.hival;
for (i = 0; i < num_decode; i += 2, dp += 2, dflags <<= 2) {
if (dflags >= 0x10000) {
dflags = sgetc(s) + 0x100;
diff --git a/gs/src/gximage.h b/gs/src/gximage.h
index 58b19b8a9..aec940503 100644
--- a/gs/src/gximage.h
+++ b/gs/src/gximage.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,14 +24,15 @@
#include "gsiparam.h"
#include "gxcspace.h"
-#include "strimpl.h" /* for siscale.h */
-#include "siscale.h"
+#include "strimpl.h" /* for sisparam.h */
+#include "sisparam.h"
#include "gxdda.h"
+#include "gxiclass.h"
#include "gxiparam.h"
#include "gxsample.h"
/* Define the abstract type for the image enumerator state. */
-typedef struct gx_image_enum_s gx_image_enum;
+/*typedef struct gx_image_enum_s gx_image_enum;*/ /* in gxiclass.h */
/*
* Incoming samples may go through two different transformations:
@@ -81,6 +82,14 @@ typedef struct sample_map_s {
sample_decoding decoding;
+ /*
+ * If decoding is sd_none for a non-mask image, we still need to know
+ * whether the table includes an inversion, so that we can transform
+ * mask values correctly.
+ */
+
+ bool inverted;
+
} sample_map;
/* Decode an 8-bit sample into a floating point color component. */
@@ -106,49 +115,10 @@ typedef struct sample_map_s {
penum->map[i].decode_base + (frac_value) * penum->map[i].decode_factor
/*
- * Declare the variable that holds the 12-bit unpacking procedure
- * if 12-bit samples are supported.
- */
-extern sample_unpack_proc((*sample_unpack_12_proc));
-
-/*
- * Define the interface for routines used to render a (source) scan line.
- * If the buffer is the original client's input data, it may be unaligned;
- * otherwise, it will always be aligned.
- *
- * The image_render procedures work on fully expanded, complete rows. These
- * take a height argument, which is an integer >= 0; they return a negative
- * code, or the number of rows actually processed (which may be less than
- * the height). height = 0 is a special call to indicate that there is no
- * more input data; this is necessary because the last scan lines of the
- * source data may not produce any output.
- */
-#define irender_proc(proc)\
- int proc(P6(gx_image_enum *penum, const byte *buffer, int data_x,\
- uint w, int h, gx_device *dev))
-typedef irender_proc((*irender_proc_t));
-
-/*
- * Define 'strategy' procedures for selecting imaging methods. Strategies
- * are called in the order in which they are declared below, so each one may
- * assume that all the previous ones failed. If a strategy succeeds, it may
- * update the enumerator structure as well as returning the rendering
- * procedure.
- *
- * Note that strategies are defined by procedure members of a structure, so
- * that they may be omitted from configurations where they are not desired.
+ * Declare the pointer that holds the 12-bit unpacking procedure
+ * if 12-bit samples are supported, 0 otherwise.
*/
-#define image_strategy_proc(proc)\
- irender_proc_t proc(P1(gx_image_enum *penum))
-typedef image_strategy_proc((*image_strategy_proc_t));
-typedef struct gx_image_strategies_s {
- image_strategy_proc_t interpolate;
- image_strategy_proc_t simple;
- image_strategy_proc_t fracs;
- image_strategy_proc_t mono;
- image_strategy_proc_t color;
-} gx_image_strategies_t;
-extern gx_image_strategies_t image_strategies;
+extern const sample_unpack_proc_t sample_unpack_12_proc;
/* Define the distinct postures of an image. */
/* Each posture includes its reflected variant. */
@@ -193,11 +163,10 @@ struct gx_image_enum_s {
byte log2_xbytes; /* log2(bytes per expanded sample): */
/* 0 if bps <= 8, log2(sizeof(frac)) */
/* if bps > 8 */
- byte spp; /* samples per pixel: 1, 3, or 4 */
- /* (1, 2, 3, 4, or 5 if alpha is allowed) */
+ byte spp; /* samples per pixel */
gs_image_alpha_t alpha; /* Alpha from image structure */
struct mc_ {
- uint values[gs_image_max_components * 2]; /* MaskColor values, */
+ uint values[GS_IMAGE_MAX_COMPONENTS * 2]; /* MaskColor values, */
/* always as ranges, guaranteed in range */
/* and in order (v0 <= v1) */
bits32 mask, test; /* (if spp > 1, bps <= 8) */
@@ -216,7 +185,7 @@ struct gx_image_enum_s {
int x, y, w, h; /* subrectangle being rendered */
} rect;
gs_fixed_point x_extent, y_extent; /* extent of one row of rect */
- sample_unpack_proc((*unpack));
+ SAMPLE_UNPACK_PROC((*unpack));
irender_proc((*render));
const gs_imager_state *pis;
const gs_color_space *pcs; /* color space of image */
@@ -252,16 +221,20 @@ struct gx_image_enum_s {
/* components (as needed) */
gx_device_clip *clip_dev; /* clipping device (if needed) */
gx_device_rop_texture *rop_dev; /* RasterOp device (if needed) */
- stream_IScale_state *scaler; /* scale state for */
- /* Interpolate (if needed) */
+ stream_image_scale_state *scaler; /* scale state for Interpolate */
+ /* (if needed) */
/* Following are updated dynamically */
int y; /* next source y */
+ gs_int_point used; /* amount of data already used, if */
+ /* interrupted by error */
gs_fixed_point cur, prev; /* device x, y of current & */
/* previous row */
struct dd_ {
gx_dda_fixed_point row; /* DDA for row origin, has been */
/* advanced when render proc called */
- gx_dda_fixed_point pixel0; /* DDA for first pixel of row */
+ gx_dda_fixed_point strip; /* row + rect.x */
+ gx_dda_fixed_point pixel0; /* DDA for first pixel to render, */
+ /* strip + used.x */
} dda;
int line_xy; /* x or y value at start of buffered line */
int xi_next; /* expected xci of next row */
@@ -272,7 +245,7 @@ struct gx_image_enum_s {
int xci, wci; /* integer x & w of row (landscape) */
/* The maps are set at initialization. We put them here */
/* so that the scalars will have smaller offsets. */
- sample_map map[5]; /* 4 colors + alpha */
+ sample_map map[GS_IMAGE_MAX_COMPONENTS];
/* Entries 0 and 255 of the following are set at initialization */
/* for monochrome images; other entries are updated dynamically. */
gx_image_clue clues[256];
@@ -295,6 +268,14 @@ struct gx_image_enum_s {
gx_device_color_equal(&(devc1), &(devc2))
/*
+ * Scale a pair of mask_color values to match the scaling of each sample to
+ * a full byte, and complement and swap them if the map incorporates
+ * a Decode = [1 0] inversion.
+ */
+void gx_image_scale_mask_colors(P2(gx_image_enum *penum,
+ int component_index));
+
+/*
* Do common initialization for processing an ImageType 1 or 4 image.
* Allocate the enumerator and fill in the following members:
* rect
diff --git a/gs/src/gximage1.c b/gs/src/gximage1.c
index d3d1d77bf..f85a96557 100644
--- a/gs/src/gximage1.c
+++ b/gs/src/gximage1.c
@@ -52,21 +52,24 @@ const gx_image_type_t gs_image_type_mask1 = {
/* Define the procedures for initializing gs_image_ts to default values. */
void
-gs_image_t_init(gs_image_t * pim, const gs_color_space * color_space)
+gs_image_t_init_adjust(gs_image_t * pim, const gs_color_space * color_space,
+ bool adjust)
{
gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
- pim->ImageMask = pim->adjust = (color_space == NULL);
+ pim->ImageMask = (color_space == NULL);
+ pim->adjust = adjust;
pim->type = (pim->ImageMask ? &gs_image_type_mask1 : &gs_image_type_1);
pim->Alpha = gs_image_alpha_none;
}
void
-gs_image_t_init_mask(gs_image_t * pim, bool write_1s)
+gs_image_t_init_mask_adjust(gs_image_t * pim, bool write_1s, bool adjust)
{
gs_image_t_init(pim, NULL);
if (write_1s)
pim->Decode[0] = 1, pim->Decode[1] = 0;
else
pim->Decode[0] = 0, pim->Decode[1] = 1;
+ pim->adjust = adjust;
}
/* Start processing an ImageType 1 image. */
diff --git a/gs/src/gximage2.c b/gs/src/gximage2.c
index e22d5a1a7..661fe27e8 100644
--- a/gs/src/gximage2.c
+++ b/gs/src/gximage2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -87,7 +87,7 @@ image2_set_data(const gs_image2_t * pim, image2_data_t * pid)
}
/* Compute the source size of an ImageType 2 image. */
-int
+private int
gx_image2_source_size(const gs_imager_state * pis, const gs_image_common_t * pim,
gs_int_point * psize)
{
@@ -313,5 +313,5 @@ gx_begin_image2(gx_device * dev,
}
}
gs_free_object(mem, row, "gx_begin_image2");
- return code;
+ return (code < 0 ? code : 1);
}
diff --git a/gs/src/gximage3.c b/gs/src/gximage3.c
index 7724cfa38..93a5d7c14 100644
--- a/gs/src/gximage3.c
+++ b/gs/src/gximage3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,6 +36,8 @@
private dev_proc_begin_typed_image(gx_begin_image3);
private image_enum_proc_plane_data(gx_image3_plane_data);
private image_enum_proc_end_image(gx_image3_end_image);
+private image_enum_proc_flush(gx_image3_flush);
+private image_enum_proc_planes_wanted(gx_image3_planes_wanted);
/* GC descriptor */
extern_st(st_gs_pixel_image);
@@ -47,7 +49,8 @@ const gx_image_type_t gs_image_type_3 = {
gx_image_no_sput, gx_image_no_sget, gx_image_default_release, 3
};
private const gx_image_enum_procs_t image3_enum_procs = {
- gx_image3_plane_data, gx_image3_end_image
+ gx_image3_plane_data, gx_image3_end_image,
+ gx_image3_flush, gx_image3_planes_wanted
};
/* Initialize an ImageType 3 image. */
@@ -70,19 +73,19 @@ typedef struct gx_image3_enum_s {
gx_image_enum_common;
gx_device_memory *mdev;
gx_device_mask_clip *pcdev;
- gx_image_enum_common_t *pixel_info;
gx_image_enum_common_t *mask_info;
+ gx_image_enum_common_t *pixel_info;
gs_image3_interleave_type_t InterleaveType;
int num_components; /* (not counting mask) */
int bpc; /* BitsPerComponent */
gs_memory_t *memory;
- int mask_width;
- int pixel_width;
- byte *pixel_data; /* (if chunky) */
+ int mask_width, mask_height, mask_full_height;
+ int pixel_width, pixel_height, pixel_full_height;
byte *mask_data; /* (if chunky) */
- int y; /* counts up to max(p'height, m'height) */
- int pixel_height;
- int mask_height;
+ byte *pixel_data; /* (if chunky) */
+ /* The following are the only members that change dynamically. */
+ int mask_y;
+ int pixel_y;
} gx_image3_enum_t;
gs_private_st_ptrs6(st_image3_enum, gx_image3_enum_t, "gx_image3_enum_t",
@@ -90,6 +93,7 @@ gs_private_st_ptrs6(st_image3_enum, gx_image3_enum_t, "gx_image3_enum_t",
mdev, pcdev, pixel_info, mask_info, pixel_data, mask_data);
/* Begin an ImageType 3 image. */
+private bool check_image3_extent(P2(floatp mask_coeff, floatp data_coeff));
private int
gx_begin_image3(gx_device * dev,
const gs_imager_state * pis, const gs_matrix * pmat,
@@ -99,10 +103,11 @@ gx_begin_image3(gx_device * dev,
{
const gs_image3_t *pim = (const gs_image3_t *)pic;
gx_image3_enum_t *penum;
+ gs_int_rect mask_rect, data_rect;
gx_device_memory *mdev;
gx_device_mask_clip *pcdev;
gs_image_t i_pixel, i_mask;
- gs_matrix mat;
+ gs_matrix mi_pixel, mi_mask, mat;
gs_rect mrect;
gs_int_point origin;
int code;
@@ -131,7 +136,37 @@ gx_begin_image3(gx_device * dev,
if (pim->MaskDict.BitsPerComponent != 1)
return_error(gs_error_rangecheck);
}
- /****** CHECK FOR COMPATIBLE ImageMatrix ******/
+ if (!check_image3_extent(pim->ImageMatrix.xx,
+ pim->MaskDict.ImageMatrix.xx) ||
+ !check_image3_extent(pim->ImageMatrix.xy,
+ pim->MaskDict.ImageMatrix.xy) ||
+ !check_image3_extent(pim->ImageMatrix.yx,
+ pim->MaskDict.ImageMatrix.yx) ||
+ !check_image3_extent(pim->ImageMatrix.yy,
+ pim->MaskDict.ImageMatrix.yy)
+ )
+ return_error(gs_error_rangecheck);
+ if ((code = gs_matrix_invert(&pim->ImageMatrix, &mi_pixel)) < 0 ||
+ (code = gs_matrix_invert(&pim->MaskDict.ImageMatrix, &mi_mask)) < 0
+ )
+ return code;
+ if (fabs(mi_pixel.tx - mi_mask.tx) >= 0.5 ||
+ fabs(mi_pixel.ty - mi_mask.ty) >= 0.5
+ )
+ return_error(gs_error_rangecheck);
+ {
+ gs_point ep, em;
+
+ if ((code = gs_point_transform(pim->Width, pim->Height, &mi_pixel,
+ &ep)) < 0 ||
+ (code = gs_point_transform(pim->MaskDict.Width,
+ pim->MaskDict.Height, &mi_mask,
+ &em)) < 0
+ )
+ return code;
+ if (fabs(ep.x - em.x) >= 0.5 || fabs(ep.y - em.y) >= 0.5)
+ return_error(gs_error_rangecheck);
+ }
penum = gs_alloc_struct(mem, gx_image3_enum_t, &st_image3_enum,
"gx_begin_image3");
if (penum == 0)
@@ -139,20 +174,39 @@ gx_begin_image3(gx_device * dev,
penum->num_components =
gs_color_space_num_components(pim->ColorSpace);
gx_image_enum_common_init((gx_image_enum_common_t *) penum,
- pic, &image3_enum_procs, dev,
- pim->BitsPerComponent,
+ (const gs_data_image_t *)pim,
+ &image3_enum_procs, dev,
1 + penum->num_components,
pim->format);
- if (prect)
- penum->pixel_width = prect->q.x - prect->p.x,
- penum->y = prect->p.y,
- penum->pixel_height = prect->q.y - prect->p.y;
- else
- penum->pixel_width = pim->Width,
- penum->y = 0,
- penum->pixel_height = pim->Height;
- penum->mask_width = pim->MaskDict.Width;
- penum->mask_height = pim->MaskDict.Height;
+ /* Initialize pointers now in case we bail out. */
+ penum->mask_data = 0;
+ penum->pixel_data = 0;
+ if (prect) {
+ long lmw = pim->MaskDict.Width, lmh = pim->MaskDict.Height;
+
+ data_rect = *prect;
+ mask_rect.p.x = (int)(data_rect.p.x * lmw / pim->Width);
+ mask_rect.p.y = (int)(data_rect.p.y * lmh / pim->Height);
+ mask_rect.q.x = (int)((data_rect.q.x + pim->Width - 1) * lmw /
+ pim->Width);
+ mask_rect.q.y = (int)((data_rect.q.y + pim->Height - 1) * lmh /
+ pim->Height);
+ } else {
+ mask_rect.p.x = mask_rect.p.y = 0;
+ mask_rect.q.x = pim->MaskDict.Width;
+ mask_rect.q.y = pim->MaskDict.Height;
+ data_rect.p.x = data_rect.p.y = 0;
+ data_rect.q.x = pim->Width;
+ data_rect.q.y = pim->Height;
+ }
+ penum->mask_width = mask_rect.q.x - mask_rect.p.x;
+ penum->mask_height = mask_rect.q.y - mask_rect.p.y;
+ penum->mask_full_height = pim->MaskDict.Height;
+ penum->mask_y = 0;
+ penum->pixel_width = data_rect.q.x - data_rect.p.x;
+ penum->pixel_height = data_rect.q.y - data_rect.p.y;
+ penum->pixel_full_height = pim->Height;
+ penum->pixel_y = 0;
penum->mdev = mdev =
gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
"gx_begin_image3(mdev)");
@@ -165,8 +219,6 @@ gx_begin_image3(gx_device * dev,
goto out2;
penum->mask_info = 0;
penum->pixel_info = 0;
- penum->mask_data = 0;
- penum->pixel_data = 0;
if (pim->InterleaveType == interleave_chunky) {
/* Allocate row buffers for the mask and pixel data. */
penum->pixel_data =
@@ -190,8 +242,7 @@ gx_begin_image3(gx_device * dev,
mrect.q.y = pim->MaskDict.Height;
if (pmat == 0)
pmat = &ctm_only(pis);
- if ((code = gs_matrix_invert(&pim->MaskDict.ImageMatrix, &mat)) < 0 ||
- (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0 ||
+ if ((code = gs_matrix_multiply(&mi_mask, pmat, &mat)) < 0 ||
(code = gs_bbox_transform(&mrect, &mat, &mrect)) < 0
)
return code;
@@ -226,6 +277,7 @@ gx_begin_image3(gx_device * dev,
*(gs_data_image_t *)&i_mask = pim->MaskDict;
i_mask.type = type1;
+ i_mask.BitsPerComponent = 1;
}
{
gx_drawing_color dcolor;
@@ -248,7 +300,7 @@ gx_begin_image3(gx_device * dev,
*/
code = gx_device_begin_typed_image((gx_device *)mdev, NULL, &m_mat,
(const gs_image_common_t *)&i_mask,
- prect, &dcolor, NULL, mem,
+ &mask_rect, &dcolor, NULL, mem,
&penum->mask_info);
if (code < 0)
goto out5;
@@ -266,21 +318,38 @@ gx_begin_image3(gx_device * dev,
if (code < 0)
goto out6;
/*
- * Compute num_planes and plane_depths from the values in the
+ * Set num_planes, plane_widths, and plane_depths from the values in the
* enumerators for the mask and the image data.
*/
- if (pim->InterleaveType == interleave_chunky) {
+ switch (pim->InterleaveType) {
+ case interleave_chunky:
/* Add the mask data to the depth of the image data. */
penum->num_planes = 1;
+ penum->plane_widths[0] = pim->Width;
penum->plane_depths[0] =
penum->pixel_info->plane_depths[0] *
(penum->num_components + 1) / penum->num_components;
- } else {
+ break;
+ case interleave_scan_lines:
+ /*
+ * There is only 1 plane, with dynamically changing width & depth.
+ * Initialize it for the mask data, since that is what will be
+ * read first.
+ */
+ penum->num_planes = 1;
+ penum->plane_depths[0] = 1;
+ penum->plane_widths[0] = pim->MaskDict.Width;
+ break;
+ case interleave_separate_source:
/* Insert the mask data as a separate plane before the image data. */
penum->num_planes = penum->pixel_info->num_planes + 1;
+ penum->plane_widths[0] = pim->MaskDict.Width;
penum->plane_depths[0] = 1;
+ memcpy(&penum->plane_widths[1], &penum->pixel_info->plane_widths[0],
+ (penum->num_planes - 1) * sizeof(penum->plane_widths[0]));
memcpy(&penum->plane_depths[1], &penum->pixel_info->plane_depths[0],
(penum->num_planes - 1) * sizeof(penum->plane_depths[0]));
+ break;
}
*pinfo = (gx_image_enum_common_t *) penum;
return 0;
@@ -294,17 +363,40 @@ gx_begin_image3(gx_device * dev,
gs_free_object(mem, penum, "gx_begin_image3");
return_error(gs_error_VMerror);
}
+private bool
+check_image3_extent(floatp mask_coeff, floatp data_coeff)
+{
+ if (mask_coeff == 0)
+ return data_coeff == 0;
+ if (data_coeff == 0 || (mask_coeff > 0) != (data_coeff > 0))
+ return false;
+ return true;
+}
+
+/*
+ * Return > 0 if we want more mask now, < 0 if we want more data now,
+ * 0 if we want both.
+ */
+inline private long
+planes_next(const gx_image3_enum_t *penum)
+{
+ return (penum->pixel_y * (long)penum->mask_full_height -
+ penum->mask_y * (long)penum->pixel_full_height);
+}
/* Process the next piece of an ImageType 3 image. */
private int
-gx_image3_plane_data(gx_device * dev,
- gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height)
+gx_image3_plane_data(gx_image_enum_common_t * info,
+ const gx_image_plane_t * planes, int height,
+ int *rows_used)
{
gx_image3_enum_t *penum = (gx_image3_enum_t *) info;
int pixel_height = penum->pixel_height;
+ int pixel_used = -1;
int mask_height = penum->mask_height;
- int image_height = max(pixel_height, mask_height);
- int h = min(height, image_height - penum->y);
+ int mask_used = -1;
+ int h1 = max(pixel_height - penum->pixel_y, mask_height - penum->mask_y);
+ int h = min(height, h1);
const gx_image_plane_t *pixel_planes;
gx_image_plane_t pixel_plane, mask_plane;
@@ -314,11 +406,15 @@ gx_image3_plane_data(gx_device * dev,
return 0;
if (h > 1) {
/* Do the operation one row at a time. */
+ int h_orig = h;
+
mask_plane = planes[0];
do {
- int code = gx_image3_plane_data(dev, info, &mask_plane, 1);
+ int code = gx_image3_plane_data(info, &mask_plane, 1,
+ rows_used);
- if (code < 0)
+ *rows_used += h_orig - h;
+ if (code)
return code;
mask_plane.data += mask_plane.raster;
} while (--h);
@@ -335,10 +431,10 @@ gx_image3_plane_data(gx_device * dev,
sample_load_declare_setup(sptr, sbit,
planes[0].data + (bit_x >> 3),
bit_x & 7, bpc);
- sample_store_declare_setup(mptr, mbit, mbbyte, penum->mask_data,
- 0, 1);
- sample_store_declare_setup(pptr, pbit, pbbyte, penum->pixel_data,
- 0, bpc);
+ sample_store_declare_setup(mptr, mbit, mbbyte,
+ penum->mask_data, 0, 1);
+ sample_store_declare_setup(pptr, pbit, pbbyte,
+ penum->pixel_data, 0, bpc);
int x;
mask_plane.data = mptr;
@@ -364,11 +460,23 @@ gx_image3_plane_data(gx_device * dev,
}
break;
case interleave_scan_lines:
+ if (planes_next(penum) >= 0) {
+ /* This is mask data. */
+ mask_plane = planes[0];
+ pixel_planes = &pixel_plane;
+ pixel_plane.data = 0;
+ } else {
+ /* This is pixel data. */
+ mask_plane.data = 0;
+ pixel_planes = planes;
+ }
+ break;
case interleave_separate_source:
mask_plane = planes[0];
pixel_planes = planes + 1;
break;
default: /* not possible */
+ *rows_used = 0;
return_error(gs_error_rangecheck);
}
/*
@@ -376,7 +484,8 @@ gx_image3_plane_data(gx_device * dev,
* device for clipping the pixel data.
*/
if (mask_plane.data) {
- int code = gx_image_plane_data(penum->mask_info, &mask_plane, h);
+ int code = gx_image_plane_data_rows(penum->mask_info, &mask_plane, h,
+ &mask_used);
if (code < 0)
return code;
@@ -388,20 +497,87 @@ gx_image3_plane_data(gx_device * dev,
* If necessary, flush any buffered mask data to the mask clipping
* device.
*/
- if (penum->mask_info->procs->flush)
- (*penum->mask_info->procs->flush)(penum->mask_info);
- code = gx_image_plane_data(penum->pixel_info, pixel_planes, h);
+ gx_image_flush(penum->mask_info);
+ code = gx_image_plane_data_rows(penum->pixel_info, pixel_planes, h,
+ &pixel_used);
if (code < 0)
return code;
- penum->y += h;
+ penum->pixel_y += pixel_used;
+ }
+ if (mask_plane.data)
+ penum->mask_y += mask_used;
+ if_debug5('b', "[b]image3 h=%d %smask_y=%d %spixel_y=%d\n",
+ h, (mask_plane.data ? "+" : ""), penum->mask_y,
+ (pixel_planes[0].data ? "+" : ""), penum->pixel_y);
+ /*
+ * There isn't any way to set rows_used if different amounts of
+ * the mask and pixel data were used. Fake it.
+ */
+ *rows_used = (pixel_used < 0 ? mask_used : pixel_used);
+ if (penum->mask_y >= penum->mask_height &&
+ penum->pixel_y >= penum->pixel_height)
+ return 1;
+ if (penum->InterleaveType == interleave_scan_lines) {
+ /* Update the width and depth in the enumerator. */
+ if (planes_next(penum) >= 0) { /* want mask data next */
+ penum->plane_widths[0] = penum->mask_width;
+ penum->plane_depths[0] = 1;
+ } else { /* want pixel data next */
+ penum->plane_widths[0] = penum->pixel_width;
+ penum->plane_depths[0] = penum->pixel_info->plane_depths[0];
+ }
+ }
+ return 0;
+}
+
+/* Flush buffered data. */
+private int
+gx_image3_flush(gx_image_enum_common_t * info)
+{
+ gx_image3_enum_t * const penum = (gx_image3_enum_t *) info;
+ int code = gx_image_flush(penum->mask_info);
+
+ if (code >= 0)
+ code = gx_image_flush(penum->pixel_info);
+ return code;
+}
+
+/* Determine which data planes are wanted. */
+private bool
+gx_image3_planes_wanted(const gx_image_enum_common_t * info, byte *wanted)
+{
+ const gx_image3_enum_t * const penum = (const gx_image3_enum_t *) info;
+
+ switch (penum->InterleaveType) {
+ case interleave_chunky: /* only 1 plane */
+ wanted[0] = 0xff;
+ return true;
+ case interleave_scan_lines: /* only 1 plane, but varying width/depth */
+ wanted[0] = 0xff;
+ return false;
+ case interleave_separate_source: {
+ /*
+ * We always want at least as much of the mask to be filled as the
+ * pixel data. more_data > 0 iff we've processed more data than
+ * mask. Plane 0 is the mask, planes [1 .. num_planes - 1] are
+ * pixel data.
+ */
+ long next = planes_next(penum);
+
+ wanted[0] = (next >= 0 ? 0xff : 0);
+ memset(wanted + 1, (next <= 0 ? 0xff : 0), info->num_planes - 1);
+ return (next == 0 &&
+ penum->mask_full_height == penum->pixel_full_height);
+ }
+ default: /* can't happen */
+ memset(wanted, 0, info->num_planes);
+ return false;
}
- return penum->y >= image_height;
}
/* Clean up after processing an ImageType 3 image. */
private int
-gx_image3_end_image(gx_device * dev, gx_image_enum_common_t * info,
- bool draw_last)
+gx_image3_end_image(gx_image_enum_common_t * info, bool draw_last)
{
gx_image3_enum_t *penum = (gx_image3_enum_t *) info;
gs_memory_t *mem = penum->memory;
diff --git a/gs/src/gximage4.c b/gs/src/gximage4.c
index 7f7e09fe4..8d7bf72a2 100644
--- a/gs/src/gximage4.c
+++ b/gs/src/gximage4.c
@@ -42,10 +42,15 @@ const gx_image_type_t gs_image_type_4 = {
&st_gs_image4, gx_begin_image4, gx_data_image_source_size,
gx_image4_sput, gx_image4_sget, gx_image4_release, 4
};
-/* The implementation is shared with ImageType 1. */
-private const gx_image_enum_procs_t image4_enum_procs = {
+/*
+ * The implementation is shared with ImageType 1, so we don't need our own
+ * enum_procs.
+ */
+/*
+ private const gx_image_enum_procs_t image4_enum_procs = {
gx_image1_plane_data, gx_image1_end_image
-};
+ };
+*/
/* Initialize an ImageType 4 image. */
void
@@ -57,7 +62,7 @@ gs_image4_t_init(gs_image4_t * pim, const gs_color_space * color_space)
}
/* Start processing an ImageType 4 image. */
-int
+private int
gx_begin_image4(gx_device * dev,
const gs_imager_state * pis, const gs_matrix * pmat,
const gs_image_common_t * pic, const gs_int_rect * prect,
diff --git a/gs/src/gximono.c b/gs/src/gximono.c
index 89d4f17c1..6ccae20bc 100644
--- a/gs/src/gximono.c
+++ b/gs/src/gximono.c
@@ -32,7 +32,6 @@
#include "gxcmap.h"
#include "gxdcolor.h"
#include "gxistate.h"
-#include "gzpath.h"
#include "gxdevmem.h"
#include "gdevmem.h" /* for mem_mono_device */
#include "gxcpath.h"
@@ -42,8 +41,8 @@
/* ------ Strategy procedure ------ */
private irender_proc(image_render_mono);
-private irender_proc_t
-image_strategy_mono(gx_image_enum * penum)
+irender_proc_t
+gs_image_class_3_mono(gx_image_enum * penum)
{
if (penum->spp == 1) {
/*
@@ -66,11 +65,10 @@ image_strategy_mono(gx_image_enum * penum)
* or icolor1, which are used directly in the fast case loop.
*/
if (penum->use_mask_color) {
- uint scale = 255 / ((1 << penum->bps) - 1);
-
- if ((penum->mask_color.values[0] *= scale) <= 0)
+ gx_image_scale_mask_colors(penum, 0);
+ if (penum->mask_color.values[0] <= 0)
color_set_null(&penum->icolor0);
- if ((penum->mask_color.values[1] *= scale) >= 255)
+ if (penum->mask_color.values[1] >= 255)
color_set_null(&penum->icolor1);
}
return image_render_mono;
@@ -78,12 +76,6 @@ image_strategy_mono(gx_image_enum * penum)
return 0;
}
-void
-gs_gximono_init(gs_memory_t * mem)
-{
- image_strategies.mono = image_strategy_mono;
-}
-
/* ------ Rendering procedure ------ */
/* Provide a fake map_gray procedure for the DevicePixel color space. */
@@ -139,12 +131,15 @@ image_render_mono(gx_image_enum * penum, const byte * buffer, int data_x,
(*map_gray)(byte2frac(sample_value), pdevc, pis, dev, gs_color_select_source);\
else {\
decode_sample(sample_value, cc, 0);\
- (*remap_color)(&cc, pcs, pdevc, pis, dev, gs_color_select_source);\
+ code = (*remap_color)(&cc, pcs, pdevc, pis, dev, gs_color_select_source);\
+ if (code < 0)\
+ return code;\
}\
} else if (!color_is_pure(pdevc)) {\
if (!tiles_fit) {\
code = gx_color_load_select(pdevc, pis, dev, gs_color_select_source);\
- if ( code < 0 ) return code;\
+ if (code < 0)\
+ return code;\
}\
}\
END
@@ -168,7 +163,7 @@ image_render_mono(gx_image_enum * penum, const byte * buffer, int data_x,
map_gray =
(gs_color_space_get_index(pcs) ==
gs_color_space_index_DeviceGray ?
- gx_device_cmap_procs(dev)->map_gray :
+ gx_get_cmap_procs(pis, dev)->map_gray :
no_map_gray /*DevicePixel */ );
else
remap_color = pcs->type->remap_color;
diff --git a/gs/src/spcxx.h b/gs/src/gxino12b.c
index d4b1ad458..67e800af7 100644
--- a/gs/src/spcxx.h
+++ b/gs/src/gxino12b.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,13 +17,9 @@
*/
-/* Requires scommon.h; strimpl.h if any templates are referenced */
+/* Dummy 12-bit image procedure */
+#include "std.h"
+#include "gstypes.h"
+#include "gxsample.h"
-#ifndef spcxx_INCLUDED
-# define spcxx_INCLUDED
-
-/* PCXDecode */
-/* (no state) */
-extern const stream_template s_PCXD_template;
-
-#endif /* spcxx_INCLUDED */
+const sample_unpack_proc_t sample_unpack_12_proc = 0;
diff --git a/gs/src/gxiparam.h b/gs/src/gxiparam.h
index 1d5c348ee..c1bdf8812 100644
--- a/gs/src/gxiparam.h
+++ b/gs/src/gxiparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -138,33 +138,28 @@ typedef struct gx_image_enum_common_s gx_image_enum_common_t;
/*
* Define the procedures associated with an image enumerator.
- *
- * Note that image_plane_data and end_image used to be device procedures;
- * they still take the device argument first for compatibility. However, in
- * order to make forwarding begin_image work, the intermediary routines
- * gx_image_[plane_]data and gx_image_end substitute the device from the
- * enumerator for the explicit device argument, which is ignored.
- * Eventually we should fix this by removing the device argument from
- * gx_device..., just as we have done for text enumeration; but this would
- * have caused major difficulties with 5.1x retrofitting of this code, and
- * it's too much work to fix right now. ****** FIX THIS SOMEDAY ******
*/
typedef struct gx_image_enum_procs_s {
/*
- * Pass the next batch of data for processing.
- * image_enum_proc_plane_data is defined in gxdevcli.h.
+ * Pass the next batch of data for processing. *rows_used is set
+ * even in the case of an error.
*/
+#define image_enum_proc_plane_data(proc)\
+ int proc(P4(gx_image_enum_common_t *info, const gx_image_plane_t *planes,\
+ int height, int *rows_used))
+
image_enum_proc_plane_data((*plane_data));
/*
- * End processing an image. We keep this procedure as the last one that
- * requires initialization, so that we can detect obsolete static
- * initializers. dev_proc_end_image is defined in gxdevcli.h.
+ * End processing an image, freeing the enumerator. We keep this
+ * procedure as the last required one, so that we can detect obsolete
+ * static initializers.
*/
+
#define image_enum_proc_end_image(proc)\
- dev_proc_end_image(proc)
+ int proc(P2(gx_image_enum_common_t *info, bool draw_last))
image_enum_proc_end_image((*end_image));
@@ -174,11 +169,29 @@ typedef struct gx_image_enum_procs_s {
* (currently, only the mask and the data of ImageType 3).
* This procedure is optional (may be 0).
*/
+
#define image_enum_proc_flush(proc)\
int proc(P1(gx_image_enum_common_t *info))
image_enum_proc_flush((*flush));
+ /*
+ * Determine which data planes should be passed on the next call to the
+ * plane_data procedure, by filling wanted[0 .. num_planes - 1] with 0
+ * for unwanted planes and non-0 for wanted planes. The procedure
+ * returns true if the returned vector will always be the same *and* if
+ * the plane widths remain constant, false if the wanted planes *or*
+ * plane widths may vary over the course of the image. By default, all
+ * data planes are always wanted; however, ImageType 3 images with
+ * separate mask and image data sources may want mask data before image
+ * data or vice versa. This procedure is optional (may be 0).
+ */
+
+#define image_enum_proc_planes_wanted(proc)\
+ bool proc(P2(const gx_image_enum_common_t *info, byte *wanted))
+
+ image_enum_proc_planes_wanted((*planes_wanted));
+
} gx_image_enum_procs_t;
/*
@@ -189,15 +202,15 @@ typedef struct gx_image_enum_procs_s {
*
* Note that the structure includes a unique ID, so that the banding
* machinery could in principle keep track of multiple enumerations that may
- * be in progress simultaneously.
- */
+ * be in progress simultaneously. */
#define gx_image_enum_common\
const gx_image_type_t *image_type;\
const gx_image_enum_procs_t *procs;\
gx_device *dev;\
gs_id id;\
int num_planes;\
- int plane_depths[gs_image_max_planes] /* [num_planes] */
+ int plane_depths[gs_image_max_planes]; /* [num_planes] */\
+ int plane_widths[gs_image_max_planes] /* [num_planes] */
struct gx_image_enum_common_s {
gx_image_enum_common;
};
@@ -211,11 +224,10 @@ struct gx_image_enum_common_s {
/*
* Initialize the common part of an image enumerator.
*/
-int gx_image_enum_common_init(P7(gx_image_enum_common_t * piec,
- const gs_image_common_t * pic,
+int gx_image_enum_common_init(P6(gx_image_enum_common_t * piec,
+ const gs_data_image_t * pic,
const gx_image_enum_procs_t * piep,
- gx_device * dev,
- int bits_per_component, int num_components,
+ gx_device * dev, int num_components,
gs_image_format_t format));
/*
diff --git a/gs/src/gxipixel.c b/gs/src/gxipixel.c
index 45feb7fe1..b9bad8ba0 100644
--- a/gs/src/gxipixel.c
+++ b/gs/src/gxipixel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#include "math_.h"
#include "memory_.h"
#include "gpcheck.h"
+#include "gscdefs.h" /* for image class table */
#include "gserrors.h"
#include "gsstruct.h"
#include "gsutil.h"
@@ -43,8 +44,8 @@
/* Structure descriptors */
private_st_gx_image_enum();
-/* Strategy procedures */
-gx_image_strategies_t image_strategies;
+/* Image class procedures */
+extern_gx_image_class_table();
/* Enumerator procedures */
private const gx_image_enum_procs_t image1_enum_procs = {
@@ -114,12 +115,7 @@ private void image_init_colors(P9(gx_image_enum * penum, int bps, int spp,
const gs_color_space * pcs, bool * pdcb));
/* Procedures for unpacking the input data into bytes or fracs. */
-/*extern sample_unpack_proc(sample_unpack_copy); *//* declared above */
-extern sample_unpack_proc(sample_unpack_1);
-extern sample_unpack_proc(sample_unpack_2);
-extern sample_unpack_proc(sample_unpack_4);
-extern sample_unpack_proc(sample_unpack_8);
-sample_unpack_proc((*sample_unpack_12_proc)); /* optional */
+/*extern SAMPLE_UNPACK_PROC(sample_unpack_copy); *//* declared above */
/*
* Do common initialization for processing an ImageType 1 or 4 image.
@@ -229,38 +225,35 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
/* following works for 1, 2, 4, 8, 12 */
index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
- if ((code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&penum->matrix,
- (floatp) width, (floatp) 0,
- &row_extent)) < 0 ||
- (code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&penum->matrix,
- (floatp) 0, (floatp) height,
- &col_extent)) < 0
- ) {
- gs_free_object(mem, penum, "gx_default_begin_image");
- return code;
- }
- gx_image_enum_common_init((gx_image_enum_common_t *) penum, pic,
- &image1_enum_procs, dev, bps,
+ mtx = float2fixed(mat.tx);
+ mty = float2fixed(mat.ty);
+ row_extent.x = float2fixed(width * mat.xx + mat.tx) - mtx;
+ row_extent.y =
+ (is_fzero(mat.xy) ? fixed_0 :
+ float2fixed(width * mat.xy + mat.ty) - mty);
+ col_extent.x =
+ (is_fzero(mat.yx) ? fixed_0 :
+ float2fixed(height * mat.yx + mat.tx) - mtx);
+ col_extent.y = float2fixed(height * mat.yy + mat.ty) - mty;
+ gx_image_enum_common_init((gx_image_enum_common_t *)penum,
+ (const gs_data_image_t *)pim,
+ &image1_enum_procs, dev,
(masked ? 1 : cs_num_components(pcs)),
format);
if (penum->rect.w == width && penum->rect.h == height) {
x_extent = row_extent;
y_extent = col_extent;
} else {
- if ((code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&penum->matrix,
- (floatp) penum->rect.w, (floatp) 0,
- &x_extent)) < 0 ||
- (code =
- gs_distance_transform2fixed((const gs_matrix_fixed *)&penum->matrix,
- (floatp) 0, (floatp) penum->rect.h,
- &y_extent)) < 0
- ) {
- gs_free_object(mem, penum, "gx_default_begin_image");
- return code;
- }
+ int rw = penum->rect.w, rh = penum->rect.h;
+
+ x_extent.x = float2fixed(rw * mat.xx + mat.tx) - mtx;
+ x_extent.y =
+ (is_fzero(mat.xy) ? fixed_0 :
+ float2fixed(rw * mat.xy + mat.ty) - mty);
+ y_extent.x =
+ (is_fzero(mat.yx) ? fixed_0 :
+ float2fixed(rh * mat.yx + mat.tx) - mtx);
+ y_extent.y = float2fixed(rh * mat.yy + mat.ty) - mty;
}
if (masked) { /* This is imagemask. */
if (bps != 1 || pcs != NULL || penum->alpha ||
@@ -400,7 +393,9 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
nplanes = spp * bps;
spread = spp << log2_xbytes;
break;
- /* No other cases are possible (checked by gx_image_enum_alloc). */
+ default:
+ /* No other cases are possible (checked by gx_image_enum_alloc). */
+ return_error(gs_error_Fatal);
}
penum->num_planes = nplanes;
penum->spread = spread;
@@ -417,8 +412,6 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
((x_extent.y | y_extent.x) == 0 ? image_portrait :
(x_extent.x | y_extent.y) == 0 ? image_landscape :
image_skewed);
- mtx = float2fixed(penum->matrix.tx);
- mty = float2fixed(penum->matrix.ty);
penum->pis = pis;
penum->pcs = pcs;
penum->memory = mem;
@@ -521,16 +514,14 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
}
penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
- dda_init(penum->dda.pixel0.x, penum->cur.x, row_extent.x,
- width);
- dda_init(penum->dda.pixel0.y, penum->cur.y, row_extent.y,
- width);
+ dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
+ dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
if (penum->rect.x) {
- dda_advance(penum->dda.pixel0.x, penum->rect.x);
- dda_advance(penum->dda.pixel0.y, penum->rect.x);
+ dda_advance(penum->dda.strip.x, penum->rect.x);
+ dda_advance(penum->dda.strip.y, penum->rect.x);
} {
- fixed ox = dda_current(penum->dda.pixel0.x);
- fixed oy = dda_current(penum->dda.pixel0.y);
+ fixed ox = dda_current(penum->dda.strip.x);
+ fixed oy = dda_current(penum->dda.strip.y);
if (!penum->clip_image) /* i.e., not clip region */
penum->clip_image =
@@ -545,12 +536,14 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
}
}
penum->y = 0;
+ penum->used.x = 0;
+ penum->used.y = 0;
{
- static const sample_unpack_proc_t procs[4] =
- {
+ static const sample_unpack_proc_t procs[4] = {
sample_unpack_1, sample_unpack_2,
sample_unpack_4, sample_unpack_8
};
+ int i;
if (index_bps == 4) {
if ((penum->unpack = sample_unpack_12_proc) == 0) { /* 12-bit samples are not supported. */
@@ -563,19 +556,13 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
penum->unpack = procs[index_bps];
if_debug1('b', "[b]unpack=%d\n", bps);
}
-#define use_strategy(sp)\
- (image_strategies.sp != 0 &&\
- (penum->render = (*image_strategies.sp)(penum)) != 0)
- if (
- use_strategy(interpolate) ||
- use_strategy(simple) ||
- use_strategy(fracs) ||
- use_strategy(mono) ||
- use_strategy(color)
- )
- DO_NOTHING;
-#undef use_strategy
- else { /* No available strategy can handle this image. */
+ /* Set up pixel0 for image class procedures. */
+ penum->dda.pixel0 = penum->dda.strip;
+ for (i = 0; i < gx_image_class_table_count; ++i)
+ if ((penum->render = gx_image_class_table[i](penum)) != 0)
+ break;
+ if (i == gx_image_class_table_count) {
+ /* No available class can handle this image. */
gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
false);
return_error(gs_error_rangecheck);
@@ -593,7 +580,7 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
return_error(gs_error_VMerror);
}
gx_make_clip_device(cdev, cdev, gx_cpath_list(pcpath));
- cdev->target = dev;
+ gx_device_set_target((gx_device_forward *)cdev, dev);
(*dev_proc(cdev, open_device)) ((gx_device *) cdev);
penum->clip_dev = cdev;
}
@@ -751,9 +738,10 @@ image_init_colors(gx_image_enum * penum, int bps, int spp,
(real_decode[1] - real_decode[0]) /
(bps <= 8 ? 255.0 : (float)frac_1);
pmap->decode_max /* = decode_lookup[15] */ = real_decode[1];
- if (no_decode)
+ if (no_decode) {
pmap->decoding = sd_none;
- else if (bps <= 4) {
+ pmap->inverted = map_decode[0] != 0;
+ } else if (bps <= 4) {
int step = 15 / ((1 << bps) - 1);
int i;
@@ -802,3 +790,24 @@ image_init_map(byte * map, int map_size, const float *decode)
}
}
}
+
+/*
+ * Scale a pair of mask_color values to match the scaling of each sample to
+ * a full byte, and complement and swap them if the map incorporates
+ * a Decode = [1 0] inversion.
+ */
+void
+gx_image_scale_mask_colors(gx_image_enum *penum, int component_index)
+{
+ uint scale = 255 / ((1 << penum->bps) - 1);
+ uint *values = &penum->mask_color.values[component_index * 2];
+ uint v0 = values[0] *= scale;
+ uint v1 = values[1] *= scale;
+
+ if (penum->map[component_index].decoding == sd_none &&
+ penum->map[component_index].inverted
+ ) {
+ values[0] = 255 - v1;
+ values[1] = 255 - v0;
+ }
+}
diff --git a/gs/src/gxiscale.c b/gs/src/gxiscale.c
index 76fdf774d..76be0041c 100644
--- a/gs/src/gxiscale.c
+++ b/gs/src/gxiscale.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,22 +33,31 @@
#include "gxcmap.h"
#include "gxdcolor.h"
#include "gxistate.h"
-#include "gzpath.h"
#include "gxdevmem.h"
#include "gxcpath.h"
#include "gximage.h"
+#include "stream.h" /* for s_alloc_state */
+#include "siinterp.h" /* for spatial interpolation */
+#include "siscale.h" /* for Mitchell filtering */
+
+/*
+ * Define whether we are using Mitchell filtering or spatial
+ * interpolation to implement Interpolate. (The latter doesn't work yet.)
+ */
+#define USE_MITCHELL_FILTER
/* ------ Strategy procedure ------ */
/* If we're interpolating, use special logic. */
private irender_proc(image_render_interpolate);
-private irender_proc_t
-image_strategy_interpolate(gx_image_enum * penum)
+irender_proc_t
+gs_image_class_0_interpolate(gx_image_enum * penum)
{
const gs_imager_state *pis = penum->pis;
gs_memory_t *mem = penum->memory;
- stream_IScale_state iss;
- stream_IScale_state *pss;
+ stream_image_scale_params_t iss;
+ stream_image_scale_state *pss;
+ const stream_template *template;
byte *line;
const gs_color_space *pcs = penum->pcs;
const gs_color_space *pccs;
@@ -56,14 +65,29 @@ image_strategy_interpolate(gx_image_enum * penum)
if (!penum->interpolate || penum->use_mask_color)
return 0;
- if (penum->posture != image_portrait || penum->masked ||
- penum->alpha
- ) {
+ if (penum->posture != image_portrait || penum->masked || penum->alpha) {
/* We can't handle these cases yet. Punt. */
penum->interpolate = false;
return 0;
}
- iss.memory = mem;
+ /*
+ * We used to interpolate using a digital filter, rather than Adobe's
+ * spatial interpolation algorithm: this produced very bad-looking
+ * results if the input resolution was close to the output resolution,
+ * especially if the input had low color resolution, and we resorted to
+ * some hack tests on the input color resolution and scale to suppress
+ * interpolation if we thought the result would look especially bad.
+ * If we use Adobe's spatial interpolation approach, we don't need
+ * to do this.
+ */
+#ifdef USE_MITCHELL_FILTER
+ if (penum->bps < 4 || penum->bps * penum->spp < 8 ||
+ (fabs(penum->matrix.xx) <= 5 && fabs(penum->matrix.yy <= 5))
+ ) {
+ penum->interpolate = false;
+ return 0;
+ }
+#endif
/* Non-ANSI compilers require the following casts: */
gs_distance_transform((float)penum->rect.w, (float)penum->rect.h,
&penum->matrix, &dst_xy);
@@ -85,19 +109,24 @@ image_strategy_interpolate(gx_image_enum * penum)
/* Allocate a buffer for one source/destination line. */
{
uint in_size =
- iss.WidthIn * iss.Colors * (iss.BitsPerComponentIn / 8);
+ iss.WidthIn * iss.Colors * (iss.BitsPerComponentIn / 8);
uint out_size =
- iss.WidthOut * iss.Colors *
- max(iss.BitsPerComponentOut / 8, sizeof(gx_color_index));
+ iss.WidthOut * iss.Colors *
+ max(iss.BitsPerComponentOut / 8, sizeof(gx_color_index));
line = gs_alloc_bytes(mem, max(in_size, out_size),
"image scale src line");
}
- pss = gs_alloc_struct(mem, stream_IScale_state,
- &st_IScale_state, "image scale state");
+#ifdef USE_MITCHELL_FILTER
+ template = &s_IScale_template;
+#else
+ template = &s_IIEncode_template;
+#endif
+ pss = (stream_image_scale_state *)
+ s_alloc_state(mem, template->stype, "image scale state");
if (line == 0 || pss == 0 ||
- (*pss = iss,
- (*s_IScale_template.init) ((stream_state *) pss) < 0)
+ (pss->params = iss, pss->template = template,
+ (*pss->template->init) ((stream_state *) pss) < 0)
) {
gs_free_object(mem, pss, "image scale state");
gs_free_object(mem, line, "image scale src line");
@@ -121,33 +150,28 @@ image_strategy_interpolate(gx_image_enum * penum)
return image_render_interpolate;
}
-void
-gs_gxiscale_init(gs_memory_t * mem)
-{
- image_strategies.interpolate = image_strategy_interpolate;
-}
-
/* ------ Rendering for interpolated images ------ */
private int
image_render_interpolate(gx_image_enum * penum, const byte * buffer,
int data_x, uint iw, int h, gx_device * dev)
{
- stream_IScale_state *pss = penum->scaler;
+ stream_image_scale_state *pss = penum->scaler;
const gs_imager_state *pis = penum->pis;
const gs_color_space *pcs = penum->pcs;
gs_logical_operation_t lop = penum->log_op;
- int c = pss->Colors;
+ int c = pss->params.Colors;
stream_cursor_read r;
stream_cursor_write w;
if (h != 0) {
/* Convert the unpacked data to concrete values in */
/* the source buffer. */
- uint row_size = pss->WidthIn * c * pss->sizeofPixelIn;
- const byte *bdata = buffer + data_x * c * pss->sizeofPixelIn;
+ int sizeofPixelIn = pss->params.BitsPerComponentIn / 8;
+ uint row_size = pss->params.WidthIn * c * sizeofPixelIn;
+ const byte *bdata = buffer + data_x * c * sizeofPixelIn;
- if (pss->sizeofPixelIn == 1) {
+ if (sizeofPixelIn == 1) {
/* Easy case: 8-bit device color values. */
r.ptr = bdata - 1;
} else {
@@ -160,7 +184,7 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
int i;
r.ptr = (byte *) psrc - 1;
- for (i = 0; i < pss->WidthIn; i++, psrc += c) {
+ for (i = 0; i < pss->params.WidthIn; i++, psrc += c) {
int j;
if (bps <= 8)
@@ -170,8 +194,7 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
for (j = 0; j < dc; pdata += sizeof(frac), ++j) {
decode_frac(*(const frac *)pdata, cc, j);
}
- (*pcs->type->concretize_color) (&cc, pcs, psrc,
- pis);
+ (*pcs->type->concretize_color) (&cc, pcs, psrc, pis);
}
}
r.limit = r.ptr + row_size;
@@ -186,7 +209,8 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
{
int xo = penum->xyi.x;
int yo = penum->xyi.y;
- int width = pss->WidthOut;
+ int width = pss->params.WidthOut;
+ int sizeofPixelOut = pss->params.BitsPerComponentOut / 8;
int dy;
const gs_color_space *pconcs = cs_concrete_space(pcs, pis);
int bpp = dev->color_info.depth;
@@ -203,41 +227,56 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
gx_device_color devc;
int code;
- declare_line_accum(penum->line, bpp, xo);
+ DECLARE_LINE_ACCUM_COPY(penum->line, bpp, xo);
w.limit = penum->line + width * c *
sizeof(gx_color_index) - 1;
w.ptr = w.limit - width * c *
- (sizeof(gx_color_index) - pss->sizeofPixelOut);
+ (sizeof(gx_color_index) - sizeofPixelOut);
psrc = (const frac *)(w.ptr + 1);
- code = (*s_IScale_template.process)
+ code = (*pss->template->process)
((stream_state *) pss, &r, &w, h == 0);
if (code < 0 && code != EOFC)
return_error(gs_error_ioerror);
if (w.ptr == w.limit) {
- for (x = xo; x < xo + width; x++, psrc += c) {
- (*pconcs->type->remap_concrete_color)
- (psrc, &devc, pis, dev,
- gs_color_select_source);
+ int xe = xo + width;
+
+ for (x = xo; x < xe;) {
+ code = (*pconcs->type->remap_concrete_color)
+ (psrc, &devc, pis, dev, gs_color_select_source);
+ if (code < 0)
+ return code;
if (color_is_pure(&devc)) {
/* Just pack colors into a scan line. */
gx_color_index color = devc.colors.pure;
- line_accum(color, bpp);
+ /* Skip RGB runs quickly. */
+ if (c == 3) {
+ do {
+ LINE_ACCUM(color, bpp);
+ x++, psrc += 3;
+ } while (x < xe && psrc[-3] == psrc[0] &&
+ psrc[-2] == psrc[1] &&
+ psrc[-1] == psrc[2]);
+ } else {
+ LINE_ACCUM(color, bpp);
+ x++, psrc += c;
+ }
} else {
int rcode;
- line_accum_copy(dev, penum->line, bpp,
+ LINE_ACCUM_COPY(dev, penum->line, bpp,
xo, x, raster, ry);
rcode = gx_fill_rectangle_device_rop(x, ry,
1, 1, &devc, dev, lop);
if (rcode < 0)
return rcode;
- line_accum_skip(bpp);
+ LINE_ACCUM_SKIP(bpp);
l_xprev = x + 1;
+ x++, psrc += c;
}
}
- line_accum_copy(dev, penum->line, bpp,
+ LINE_ACCUM_COPY(dev, penum->line, bpp,
xo, x, raster, ry);
penum->line_xy++;
}
diff --git a/gs/src/gxistate.h b/gs/src/gxistate.h
index 2c8c3d4d9..b66ece79e 100644
--- a/gs/src/gxistate.h
+++ b/gs/src/gxistate.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,6 +26,7 @@
#include "gsrefct.h"
#include "gsropt.h"
#include "gxcvalue.h"
+#include "gxcmap.h"
#include "gxfixed.h"
#include "gxline.h"
#include "gxmatrix.h"
@@ -50,12 +51,13 @@
* black generation, undercolor removal
* CIE rendering tables
* halftone and pattern caches
+ * shared (constant) device color spaces
* The imager state currently EXCLUDES the following:
* graphics state stack
* default CTM
* path
- * clipping path
- * color specification: color, color space
+ * clipping path and stack
+ * color specification: color, color space, substitute color spaces
* font
* device
* caches for many of the above
@@ -64,24 +66,21 @@
/*
* Define the color rendering state information.
* This should be a separate object (or at least a substructure),
- * but doing this would require editing too much code.
+ * but making this change would require editing too much code.
*/
/* Opaque types referenced by the color rendering state. */
#ifndef gs_halftone_DEFINED
# define gs_halftone_DEFINED
typedef struct gs_halftone_s gs_halftone;
-
#endif
#ifndef gx_device_color_DEFINED
# define gx_device_color_DEFINED
typedef struct gx_device_color_s gx_device_color;
-
#endif
#ifndef gx_device_halftone_DEFINED
# define gx_device_halftone_DEFINED
typedef struct gx_device_halftone_s gx_device_halftone;
-
#endif
/*
@@ -115,7 +114,7 @@ typedef union gx_transfer_s {
gs_halftone *halftone; /* (RC) */\
gs_int_point screen_phase[gs_color_select_count];\
/* dev_ht depends on halftone and device resolution. */\
- gx_device_halftone *dev_ht; /* (Owned) */\
+ gx_device_halftone *dev_ht; /* (RC) */\
/* The contents of ht_cache depend on dev_ht. */\
struct gx_ht_cache_s *ht_cache; /* (Shared) by all gstates */\
\
@@ -151,7 +150,8 @@ typedef union gx_transfer_s {
* structure that someone else worries about.
*/
#define gs_cr_state_do_rc_ptrs(m)\
- m(halftone) m(cie_render) m(black_generation) m(undercolor_removal)\
+ m(halftone) m(dev_ht) m(cie_render)\
+ m(black_generation) m(undercolor_removal)\
m(set_transfer.colored.red) m(set_transfer.colored.green)\
m(set_transfer.colored.blue) m(set_transfer.colored.gray)\
m(cie_joint_caches)
@@ -174,23 +174,30 @@ typedef union gx_transfer_s {
#ifndef gs_color_space_DEFINED
# define gs_color_space_DEFINED
typedef struct gs_color_space_s gs_color_space;
-
#endif
+typedef union gx_device_color_spaces_s {
+ struct dcn_ {
+ gs_color_space *Gray;
+ gs_color_space *RGB;
+ gs_color_space *CMYK;
+ } named;
+ gs_color_space *indexed[3];
+} gx_device_color_spaces_t;
typedef struct gs_imager_state_shared_s {
rc_header rc;
- gs_color_space *cs_DeviceGray;
- gs_color_space *cs_DeviceRGB;
- gs_color_space *cs_DeviceCMYK;
+ gx_device_color_spaces_t device_color_spaces;
} gs_imager_state_shared_t;
-#define private_st_imager_state_shared() /* in gsstate.c */\
+#define private_st_imager_state_shared() /* in gsistate.c */\
gs_private_st_ptrs3(st_imager_state_shared, gs_imager_state_shared_t,\
"gs_imager_state_shared", imager_state_shared_enum_ptrs,\
- imager_state_shared_reloc_ptrs, cs_DeviceGray, cs_DeviceRGB, cs_DeviceCMYK)
+ imager_state_shared_reloc_ptrs, device_color_spaces.named.Gray,\
+ device_color_spaces.named.RGB, device_color_spaces.named.CMYK)
/* Define the imager state structure itself. */
#define gs_imager_state_common\
gs_memory_t *memory;\
+ void *client_data;\
gs_imager_state_shared_t *shared;\
gx_line_params line_params;\
gs_matrix_fixed ctm;\
@@ -202,21 +209,24 @@ typedef struct gs_imager_state_shared_s {
bool stroke_adjust;\
bool accurate_curves;\
float smoothness;\
+ const gx_color_map_procs *\
+ (*get_cmap_procs)(P2(const gs_imager_state *, const gx_device *));\
gs_color_rendering_state_common
-#define gs_imager_state_shared(pis, elt) ((pis)->shared->elt)
#define st_imager_state_num_ptrs\
- (st_line_params_num_ptrs + st_cr_state_num_ptrs + 1)
+ (st_line_params_num_ptrs + st_cr_state_num_ptrs + 2)
/* Access macros */
#define ctm_only(pis) (*(const gs_matrix *)&(pis)->ctm)
#define ctm_only_writable(pis) (*(gs_matrix *)&(pis)->ctm)
#define set_ctm_only(pis, mat) (*(gs_matrix *)&(pis)->ctm = (mat))
#define gs_init_rop(pis) ((pis)->log_op = lop_default)
+#define gs_currentflat_inline(pis) ((pis)->flatness)
#define gs_currentlineparams_inline(pis) (&(pis)->line_params)
+#define gs_current_logical_op_inline(pis) ((pis)->log_op)
+#define gs_set_logical_op_inline(pis, lop) ((pis)->log_op = (lop))
#ifndef gs_imager_state_DEFINED
# define gs_imager_state_DEFINED
typedef struct gs_imager_state_s gs_imager_state;
-
#endif
struct gs_imager_state_s {
@@ -225,20 +235,37 @@ struct gs_imager_state_s {
/* Initialization for gs_imager_state */
#define gs_imager_state_initial(scale)\
- 0, 0, { gx_line_params_initial },\
+ 0, 0, 0, { gx_line_params_initial },\
{ scale, 0.0, 0.0, -(scale), 0.0, 0.0 },\
lop_default, gx_max_color_value, 0/*false*/, 1.0,\
- { fixed_half, fixed_half }, 0/*false*/, 0/*false*/, 1.0
+ { fixed_half, fixed_half }, 0/*false*/, 0/*false*/, 1.0,\
+ gx_default_get_cmap_procs
-#define private_st_imager_state() /* in gsstate.c */\
- gs_private_st_composite(st_imager_state, gs_imager_state, "gs_imager_state",\
+/* The imager state structure is public only for subclassing. */
+#define public_st_imager_state() /* in gsistate.c */\
+ gs_public_st_composite(st_imager_state, gs_imager_state, "gs_imager_state",\
imager_state_enum_ptrs, imager_state_reloc_ptrs)
/* Initialize an imager state, other than the parts covered by */
/* gs_imager_state_initial. */
-/* The halftone, dev_ht, and ht_cache elements are not set or used. */
int gs_imager_state_initialize(P2(gs_imager_state * pis, gs_memory_t * mem));
+/* Make a temporary copy of a gs_imager_state. Note that this does not */
+/* do all the necessary reference counting, etc. */
+gs_imager_state *
+ gs_imager_state_copy(P2(const gs_imager_state * pis, gs_memory_t * mem));
+
+/* Increment reference counts to note that an imager state has been copied. */
+void gs_imager_state_copied(P1(gs_imager_state * pis));
+
+/* Adjust reference counts before assigning one imager state to another. */
+void gs_imager_state_pre_assign(P2(gs_imager_state *to,
+ const gs_imager_state *from));
+
+/* Free device color spaces. Perhaps this should be declared elsewhere? */
+void gx_device_color_spaces_free(P3(gx_device_color_spaces_t *pdcs,
+ gs_memory_t *mem, client_name_t cname));
+
/* Release an imager state. */
void gs_imager_state_release(P1(gs_imager_state * pis));
diff --git a/gs/src/gxmclip.c b/gs/src/gxmclip.c
index de9a45132..8da49e98c 100644
--- a/gs/src/gxmclip.c
+++ b/gs/src/gxmclip.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -84,7 +84,7 @@ gx_mask_clip_initialize(gx_device_mask_clip * cdev,
cdev->width = tdev->width;
cdev->height = tdev->height;
cdev->color_info = tdev->color_info;
- cdev->target = tdev;
+ gx_device_set_target((gx_device_forward *)cdev, tdev);
cdev->phase.x = -tx;
cdev->phase.y = -ty;
if (buffer_height > bits->size.y)
diff --git a/gs/src/gxmclip.h b/gs/src/gxmclip.h
index 19f2b1bec..7959fb2c9 100644
--- a/gs/src/gxmclip.h
+++ b/gs/src/gxmclip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -55,9 +55,9 @@ typedef struct gx_device_mask_clip_s {
extern_st(st_device_mask_clip);
#define public_st_device_mask_clip() /* in gxmclip.c */\
- gs_public_st_composite(st_device_mask_clip, gx_device_mask_clip,\
+ gs_public_st_composite_use_final(st_device_mask_clip, gx_device_mask_clip,\
"gx_device_mask_clip", device_mask_clip_enum_ptrs,\
- device_mask_clip_reloc_ptrs)
+ device_mask_clip_reloc_ptrs, gx_device_finalize)
/*
* Internal routine to initialize a mask clipping device.
diff --git a/gs/src/gxobj.h b/gs/src/gxobj.h
index b6daf0aa2..9c1758d8d 100644
--- a/gs/src/gxobj.h
+++ b/gs/src/gxobj.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -78,8 +78,10 @@
#define o_l_unmarked (o_unmarked & 3)
#define o_set_unmarked_large(pp) (pp)->o_lmark = o_l_unmarked
#define o_set_unmarked(pp)\
- if ( (pp)->o_large ) o_set_unmarked_large(pp);\
- else (pp)->o_smark = o_unmarked
+ BEGIN\
+ if ((pp)->o_large) o_set_unmarked_large(pp);\
+ else (pp)->o_smark = o_unmarked;\
+ END
#define o_is_unmarked_large(pp) ((pp)->o_lmark == o_l_unmarked)
#define o_is_unmarked(pp)\
((pp)->o_large ? o_is_unmarked_large(pp) :\
@@ -87,16 +89,20 @@
#define o_untraced (((uint)1 << obj_mb_bits) - 2)
#define o_l_untraced (o_untraced & 3)
#define o_set_untraced(pp)\
- if ( (pp)->o_large ) (pp)->o_lmark = o_l_untraced;\
- else (pp)->o_smark = o_untraced
+ BEGIN\
+ if ((pp)->o_large) (pp)->o_lmark = o_l_untraced;\
+ else (pp)->o_smark = o_untraced;\
+ END
#define o_is_untraced(pp)\
((pp)->o_large ? (pp)->o_lmark == o_l_untraced :\
((pp)->o_smark == o_untraced))
#define o_marked 0
#define o_mark_large(pp) (pp)->o_lmark = o_marked
#define o_mark(pp)\
- if ( (pp)->o_large ) o_mark_large(pp);\
- else (pp)->o_smark = o_marked
+ BEGIN\
+ if ((pp)->o_large) o_mark_large(pp);\
+ else (pp)->o_smark = o_marked;\
+ END
#define obj_back_shift obj_flag_bits
#define obj_back_scale (1 << obj_back_shift)
typedef struct obj_header_data_s {
@@ -153,7 +159,7 @@ typedef struct obj_header_data_s {
struct obj_header_s { /* must be a struct because of forward reference */
union _d {
obj_header_data_t o;
- byte _pad[round_up(sizeof(obj_header_data_t), obj_align_mod)];
+ byte _pad[ROUND_UP(sizeof(obj_header_data_t), obj_align_mod)];
}
d;
};
diff --git a/gs/src/gxp1fill.c b/gs/src/gxp1fill.c
index b3ac280ea..b417064f0 100644
--- a/gs/src/gxp1fill.c
+++ b/gs/src/gxp1fill.c
@@ -85,9 +85,9 @@ tile_fill_init(tile_fill_state_t * ptfs, const gx_device_color * pdevc,
*/
if (set_mask_phase && m_tile->is_simple) {
px = imod(-(int)(m_tile->step_matrix.tx - ptfs->phase.x + 0.5),
- m_tile->tmask.rep_width);
+ m_tile->tmask.rep_width);
py = imod(-(int)(m_tile->step_matrix.ty - ptfs->phase.y + 0.5),
- m_tile->tmask.rep_height);
+ m_tile->tmask.rep_height);
} else
px = py = 0;
return tile_clip_initialize(&ptfs->cdev, ptfs->tmask, dev, px, py);
@@ -122,6 +122,7 @@ tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
gs_rect ibbox; /* bounding box in stepping space */
double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
+ double u0, v0, u1, v1;
bbox.p.x = x0, bbox.p.y = y0;
bbox.q.x = x1, bbox.q.y = y1;
@@ -131,14 +132,26 @@ tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
x0, y0, w0, h0,
ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
step_matrix.tx, step_matrix.ty);
- i0 = (int)ceil(ibbox.p.x - bbw - 0.000001);
- i1 = (int)floor(ibbox.q.x + 0.000001);
- j0 = (int)ceil(ibbox.p.y - bbh - 0.000001);
- j1 = (int)floor(ibbox.q.y + 0.000001);
+ /*
+ * If the pattern is partly transparent and XStep/YStep is smaller
+ * than the device space BBox, we need to ensure that we cover
+ * each pixel of the rectangle being filled with *every* pattern
+ * that overlaps it, not just *some* pattern copy.
+ */
+ u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
+ v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
+ u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
+ v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
+ if (!ptile->is_simple)
+ u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
+ i0 = (int)floor(u0);
+ j0 = (int)floor(v0);
+ i1 = (int)ceil(u1);
+ j1 = (int)ceil(v1);
}
if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
- for (i = i0; i <= i1; i++)
- for (j = j0; j <= j1; j++) {
+ for (i = i0; i < i1; i++)
+ for (j = j0; j < j1; j++) {
int x = (int)(step_matrix.xx * i +
step_matrix.yx * j + step_matrix.tx);
int y = (int)(step_matrix.xy * i +
@@ -250,11 +263,10 @@ gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y,
if (ptile->is_simple) {
int px =
imod(-(int)(ptile->step_matrix.tx - state.phase.x + 0.5),
- bits->rep_width);
+ bits->rep_width);
int py =
imod(-(int)(ptile->step_matrix.ty - state.phase.y + 0.5),
- bits->rep_height);
-
+ bits->rep_height);
if (state.pcdev != dev)
tile_clip_set_phase(&state.cdev, px, py);
diff --git a/gs/src/gxpageq.c b/gs/src/gxpageq.c
index 9de5c1256..8888f360d 100644
--- a/gs/src/gxpageq.c
+++ b/gs/src/gxpageq.c
@@ -130,6 +130,7 @@ gx_page_queue_init(
queue->render_done_sema = gx_semaphore_alloc(memory);
queue->first_in = queue->last_in = 0;
queue->reserve_entry = gx_page_queue_entry_alloc(queue);
+
if (queue->monitor && queue->render_req_sema && queue->render_done_sema
&& queue->reserve_entry)
return 0;
diff --git a/gs/src/gxpageq.h b/gs/src/gxpageq.h
index b56c88190..47e5431ce 100644
--- a/gs/src/gxpageq.h
+++ b/gs/src/gxpageq.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -235,7 +235,7 @@ int gx_page_queue_add_page(P4(
gx_page_queue_t * queue, /* page queue to add to */
gx_page_queue_action_t action, /* action code to queue */
const gx_band_page_info_t * page_info, /* bandinfo incl. bandlist */
- int page_count /* # of copies to print if final "print,"
+ int page_count /* # of copies to print if final "print," */
/* 0 if partial page, -1 if cancel */
));
diff --git a/gs/src/gxpaint.c b/gs/src/gxpaint.c
index 4bf7f9e16..b659778ae 100644
--- a/gs/src/gxpaint.c
+++ b/gs/src/gxpaint.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -64,7 +64,8 @@ gx_stroke_fill(gx_path * ppath, gs_state * pgs)
}
int
-gx_stroke_add(gx_path * ppath, gx_path * to_path, gs_state * pgs)
+gx_stroke_add(gx_path * ppath, gx_path * to_path,
+ const gs_state * pgs)
{
gx_stroke_params params;
@@ -73,3 +74,14 @@ gx_stroke_add(gx_path * ppath, gx_path * to_path, gs_state * pgs)
(const gs_imager_state *)pgs,
&params, NULL, NULL);
}
+
+int
+gx_imager_stroke_add(gx_path *ppath, gx_path *to_path,
+ const gs_imager_state *pis)
+{
+ gx_stroke_params params;
+
+ params.flatness = pis->flatness;
+ return gx_stroke_path_only(ppath, to_path, (gx_device *)0, pis,
+ &params, NULL, NULL);
+}
diff --git a/gs/src/gxpaint.h b/gs/src/gxpaint.h
index cb8751f19..47d5a6990 100644
--- a/gs/src/gxpaint.h
+++ b/gs/src/gxpaint.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,25 +25,21 @@
#ifndef gs_imager_state_DEFINED
# define gs_imager_state_DEFINED
typedef struct gs_imager_state_s gs_imager_state;
-
#endif
#ifndef gs_state_DEFINED
# define gs_state_DEFINED
typedef struct gs_state_s gs_state;
-
#endif
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
#ifndef gx_device_color_DEFINED
# define gx_device_color_DEFINED
typedef struct gx_device_color_s gx_device_color;
-
#endif
/* ------ Graphics-state-aware procedures ------ */
@@ -56,7 +52,9 @@ typedef struct gx_device_color_s gx_device_color;
int gx_fill_path(P6(gx_path * ppath, gx_device_color * pdevc, gs_state * pgs,
int rule, fixed adjust_x, fixed adjust_y));
int gx_stroke_fill(P2(gx_path * ppath, gs_state * pgs));
-int gx_stroke_add(P3(gx_path * ppath, gx_path * to_path, gs_state * pgs));
+int gx_stroke_add(P3(gx_path *ppath, gx_path *to_path, const gs_state * pgs));
+int gx_imager_stroke_add(P3(gx_path *ppath, gx_path *to_path,
+ const gs_imager_state *pis));
/* ------ Imager procedures ------ */
@@ -68,11 +66,16 @@ void gx_adjust_if_empty(P2(const gs_fixed_rect *, gs_fixed_point *));
/*
* Compute the amount by which to expand a stroked bounding box to account
- * for line width, caps and joins. If the amount is too large to fit in
- * a gs_fixed_point, return gs_error_limitcheck.
+ * for line width, caps and joins. If the amount is too large to fit in a
+ * gs_fixed_point, return gs_error_limitcheck. Return 0 if the result is
+ * exact, 1 if it is conservative.
+ *
+ * This procedure is fast, but the result may be conservative by a large
+ * amount if the miter limit is large. If this matters, use strokepath +
+ * pathbbox.
*/
-int gx_stroke_path_expansion(P3(const gs_imager_state *,
- const gx_path *, gs_fixed_point *));
+int gx_stroke_path_expansion(P3(const gs_imager_state *pis,
+ const gx_path *ppath, gs_fixed_point *ppt));
/* Backward compatibility */
#define gx_stroke_expansion(pis, ppt)\
@@ -87,7 +90,6 @@ int gx_stroke_path_expansion(P3(const gs_imager_state *,
#ifndef gx_fill_params_DEFINED
# define gx_fill_params_DEFINED
typedef struct gx_fill_params_s gx_fill_params;
-
#endif
struct gx_fill_params_s {
int rule; /* -1 = winding #, 1 = even/odd */
diff --git a/gs/src/gxpath.c b/gs/src/gxpath.c
index 4f95d737b..0ab418c99 100644
--- a/gs/src/gxpath.c
+++ b/gs/src/gxpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -253,11 +253,11 @@ gx_path_assign_preserve(gx_path * ppto, gx_path * ppfrom)
*/
int
gx_path_assign_free(gx_path * ppto, gx_path * ppfrom)
-{ /*
- * Detect the special case where both paths have non-shared local
- * segments, since we can avoid allocating new segments in this
- * case.
- */
+{
+ /*
+ * Detect the special case where both paths have non-shared local
+ * segments, since we can avoid allocating new segments in this case.
+ */
if (ppto->segments == &ppto->local_segments &&
ppfrom->segments == &ppfrom->local_segments &&
!gx_path_is_shared(ppto)
@@ -474,7 +474,7 @@ gx_path_add_line_notes(gx_path * ppath, fixed x, fixed y, segment_notes notes)
/* Add multiple lines to the current path. */
/* Note that all lines have the same notes. */
int
-gx_path_add_lines_notes(gx_path * ppath, const gs_fixed_point * ppts, int count,
+gx_path_add_lines_notes(gx_path *ppath, const gs_fixed_point *ppts, int count,
segment_notes notes)
{
subpath *psub;
@@ -489,10 +489,12 @@ gx_path_add_lines_notes(gx_path * ppath, const gs_fixed_point * ppts, int count,
path_open();
psub = ppath->current_subpath;
prev = psub->last;
- /* We could do better than the following, but this is a start. */
- /* Note that we don't make any attempt to undo partial additions */
- /* if we fail partway through; this is equivalent to what would */
- /* happen with multiple calls on gx_path_add_line. */
+ /*
+ * We could do better than the following, but this is a start.
+ * Note that we don't make any attempt to undo partial additions
+ * if we fail partway through; this is equivalent to what would
+ * happen with multiple calls on gx_path_add_line.
+ */
for (i = 0; i < count; i++) {
fixed x = ppts[i].x;
fixed y = ppts[i].y;
@@ -686,7 +688,8 @@ gx_path_close_subpath_notes(gx_path * ppath, segment_notes notes)
if (!path_subpath_open(ppath))
return 0;
- if (path_last_is_moveto(ppath)) { /* The last operation was a moveto: create a subpath. */
+ if (path_last_is_moveto(ppath)) {
+ /* The last operation was a moveto: create a subpath. */
code = gx_path_new_subpath(ppath);
if (code < 0)
return code;
diff --git a/gs/src/gxpath.h b/gs/src/gxpath.h
index 71718450e..75494dfef 100644
--- a/gs/src/gxpath.h
+++ b/gs/src/gxpath.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,7 +35,6 @@
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
-
#endif
/* Define the two insideness rules */
@@ -54,7 +53,6 @@ typedef enum {
#ifdef DEBUG
void gx_dump_path(P2(const gx_path *, const char *));
void gx_path_print(P1(const gx_path *));
-
#endif
/* Path memory management */
@@ -148,10 +146,12 @@ int gx_path_new(P1(gx_path *)),
/* to keep it unique in the first 23 characters. */
gx_path_pop_close_notes(P2(gx_path *, segment_notes));
-/* The last argument to gx_path_add_partial_arc is a fraction for computing */
-/* the curve parameters. Here is the correct value for quarter-circles. */
-/* (stroke uses this to draw round caps and joins.) */
-#define quarter_arc_fraction 0.552285
+/*
+ * The last argument to gx_path_add_partial_arc is a fraction for computing
+ * the curve parameters. Here is the correct value for quarter-circles.
+ * (stroke uses this to draw round caps and joins.)
+ */
+#define quarter_arc_fraction 0.55228474983079334
/*
* Backward-compatible constructors that don't take a notes argument.
*/
@@ -200,26 +200,39 @@ gx_path_is_rectangular(P2(const gx_path *, gs_fixed_rect *));
typedef enum {
pco_none = 0,
pco_monotonize = 1, /* make curves monotonic */
- pco_accurate = 2 /* flatten with accurate tangents at ends */
+ pco_accurate = 2, /* flatten with accurate tangents at ends */
+ pco_for_stroke = 4 /* flatten taking line width into account */
} gx_path_copy_options;
-int gx_path_copy_reducing(P4(const gx_path * ppath_old, gx_path * ppath_new,
- fixed fixed_flatness,
+/* The imager state is only needed when flattening for stroke. */
+#ifndef gs_imager_state_DEFINED
+# define gs_imager_state_DEFINED
+typedef struct gs_imager_state_s gs_imager_state;
+#endif
+int gx_path_copy_reducing(P5(const gx_path * ppath_old, gx_path * ppath_new,
+ fixed fixed_flatness, const gs_imager_state *pis,
gx_path_copy_options options));
#define gx_path_copy(old, new)\
- gx_path_copy_reducing(old, new, max_fixed, pco_none)
+ gx_path_copy_reducing(old, new, max_fixed, NULL, pco_none)
#define gx_path_add_flattened(old, new, flatness)\
- gx_path_copy_reducing(old, new, float2fixed(flatness), pco_none)
+ gx_path_copy_reducing(old, new, float2fixed(flatness), NULL, pco_none)
#define gx_path_add_flattened_accurate(old, new, flatness, accurate)\
- gx_path_copy_reducing(old, new, float2fixed(flatness),\
+ gx_path_copy_reducing(old, new, float2fixed(flatness), NULL,\
(accurate ? pco_accurate : pco_none))
+#define gx_path_add_flattened_for_stroke(old, new, flatness, pis)\
+ gx_path_copy_reducing(old, new, float2fixed(flatness), pis,\
+ (pis->accurate_curves ?\
+ pco_accurate | pco_for_stroke : pco_for_stroke))
#define gx_path_add_monotonized(old, new)\
- gx_path_copy_reducing(old, new, max_fixed, pco_monotonize)
-int gx_path_add_dash_expansion(P3(const gx_path * /*old */ , gx_path * /*new */ , const gs_imager_state *)),
- gx_path_copy_reversed(P2(const gx_path * /*old */ , gx_path * /*new */ )),
+ gx_path_copy_reducing(old, new, max_fixed, NULL, pco_monotonize)
+int gx_path_add_dash_expansion(P3(const gx_path * /*old*/, gx_path * /*new*/,
+ const gs_imager_state *)),
+ gx_path_copy_reversed(P2(const gx_path * /*old*/, gx_path * /*new*/)),
gx_path_translate(P3(gx_path *, fixed, fixed)),
- gx_path_scale_exp2(P3(gx_path *, int, int));
-void gx_point_scale_exp2(P3(gs_fixed_point *, int, int)), gx_rect_scale_exp2(P3(gs_fixed_rect *, int, int));
+ gx_path_scale_exp2_shared(P4(gx_path *ppath, int log2_scale_x,
+ int log2_scale_y, bool segments_shared));
+void gx_point_scale_exp2(P3(gs_fixed_point *, int, int)),
+ gx_rect_scale_exp2(P3(gs_fixed_rect *, int, int));
/* Path enumerator */
@@ -238,7 +251,6 @@ bool gx_path_enum_backup(P1(gs_path_enum *));
#ifndef gx_clip_path_DEFINED
# define gx_clip_path_DEFINED
typedef struct gx_clip_path_s gx_clip_path;
-
#endif
/* Graphics state clipping */
@@ -251,7 +263,6 @@ int gx_effective_clip_path(P2(gs_state *, gx_clip_path **));
#ifndef gx_clip_list_DEFINED
# define gx_clip_list_DEFINED
typedef struct gx_clip_list_s gx_clip_list;
-
#endif
/* Opaque type for a clipping path enumerator. */
@@ -290,16 +301,18 @@ int gx_cpath_assign_free(P2(gx_clip_path * pcpto, gx_clip_path * pcpfrom));
int
gx_cpath_reset(P1(gx_clip_path *)), /* from_rectangle ((0,0),(0,0)) */
gx_cpath_from_rectangle(P2(gx_clip_path *, gs_fixed_rect *)),
- gx_cpath_clip(P4(gs_state *, gx_clip_path *, gx_path *, int)),
- gx_cpath_scale_exp2(P3(gx_clip_path *, int, int)),
+ gx_cpath_clip(P4(gs_state *, gx_clip_path *, /*const*/ gx_path *, int)),
+ gx_cpath_intersect(P4(gx_clip_path *, /*const*/ gx_path *, int,
+ gs_imager_state *)),
+ gx_cpath_scale_exp2_shared(P5(gx_clip_path *pcpath, int log2_scale_x,
+ int log2_scale_y, bool list_shared,
+ bool segments_shared)),
gx_cpath_to_path(P2(gx_clip_path *, gx_path *));
bool
gx_cpath_inner_box(P2(const gx_clip_path *, gs_fixed_rect *)),
gx_cpath_outer_box(P2(const gx_clip_path *, gs_fixed_rect *)),
gx_cpath_includes_rectangle(P5(const gx_clip_path *, fixed, fixed,
fixed, fixed));
-int gx_cpath_set_outside(P2(gx_clip_path *, bool));
-bool gx_cpath_is_outside(P1(const gx_clip_path *));
/* Enumerate a clipping path. This interface does not copy the path. */
/* However, it does write into the path's "visited" flags. */
diff --git a/gs/src/gxpath2.c b/gs/src/gxpath2.c
index 82f0347e3..8c101be34 100644
--- a/gs/src/gxpath2.c
+++ b/gs/src/gxpath2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "math_.h"
#include "gx.h"
#include "gserrors.h"
+#include "gsstruct.h"
#include "gxfixed.h"
#include "gxarith.h"
#include "gzpath.h"
@@ -59,17 +60,20 @@ gx_path_subpath_start_point(const gx_path * ppath, gs_fixed_point * ppt)
int
gx_path_bbox(gx_path * ppath, gs_fixed_rect * pbox)
{
- if (ppath->bbox_set) { /* The bounding box was set by setbbox. */
+ if (ppath->bbox_set) {
+ /* The bounding box was set by setbbox. */
*pbox = ppath->bbox;
return 0;
}
- if (ppath->first_subpath == 0) { /* The path is empty, use the current point if any. */
+ if (ppath->first_subpath == 0) {
+ /* The path is empty, use the current point if any. */
int code = gx_path_current_point(ppath, &pbox->p);
- if (code < 0) { /*
- * Don't return garbage, in case the caller doesn't
- * check the return code.
- */
+ if (code < 0) {
+ /*
+ * Don't return garbage, in case the caller doesn't
+ * check the return code.
+ */
pbox->p.x = pbox->p.y = 0;
}
pbox->q = pbox->p;
@@ -80,40 +84,44 @@ gx_path_bbox(gx_path * ppath, gs_fixed_rect * pbox)
if (ppath->box_last == ppath->current_subpath->last) { /* Box is up to date */
*pbox = ppath->bbox;
} else {
- gs_fixed_rect box;
+ fixed px, py, qx, qy;
const segment *pseg = ppath->box_last;
if (pseg == 0) { /* box is uninitialized */
pseg = (const segment *)ppath->first_subpath;
- box.p.x = box.q.x = pseg->pt.x;
- box.p.y = box.q.y = pseg->pt.y;
+ px = qx = pseg->pt.x;
+ py = qy = pseg->pt.y;
} else {
- box = ppath->bbox;
- pseg = pseg->next;
+ px = ppath->bbox.p.x, py = ppath->bbox.p.y;
+ qx = ppath->bbox.q.x, qy = ppath->bbox.q.y;
}
+
/* Macro for adjusting the bounding box when adding a point */
-#define adjust_bbox(pt)\
- if ( (pt).x < box.p.x ) box.p.x = (pt).x;\
- else if ( (pt).x > box.q.x ) box.q.x = (pt).x;\
- if ( (pt).y < box.p.y ) box.p.y = (pt).y;\
- else if ( (pt).y > box.q.y ) box.q.y = (pt).y
- while (pseg) {
+#define ADJUST_BBOX(pt)\
+ if ((pt).x < px) px = (pt).x;\
+ else if ((pt).x > qx) qx = (pt).x;\
+ if ((pt).y < py) py = (pt).y;\
+ else if ((pt).y > qy) qy = (pt).y
+
+ while ((pseg = pseg->next) != 0) {
switch (pseg->type) {
case s_curve:
-#define pcurve ((const curve_segment *)pseg)
- adjust_bbox(pcurve->p1);
- adjust_bbox(pcurve->p2);
-#undef pcurve
+ ADJUST_BBOX(((const curve_segment *)pseg)->p1);
+ ADJUST_BBOX(((const curve_segment *)pseg)->p2);
/* falls through */
default:
- adjust_bbox(pseg->pt);
+ ADJUST_BBOX(pseg->pt);
}
- pseg = pseg->next;
}
-#undef adjust_bbox
- ppath->bbox = box;
+#undef ADJUST_BBOX
+
+#define STORE_BBOX(b)\
+ (b).p.x = px, (b).p.y = py, (b).q.x = qx, (b).q.y = qy;
+ STORE_BBOX(*pbox);
+ STORE_BBOX(ppath->bbox);
+#undef STORE_BBOX
+
ppath->box_last = ppath->current_subpath->last;
- *pbox = box;
}
return 0;
}
@@ -270,26 +278,27 @@ gx_rect_scale_exp2(gs_fixed_rect * pr, int sx, int sy)
gx_point_scale_exp2(&pr->q, sx, sy);
}
int
-gx_path_scale_exp2(gx_path * ppath, int log2_scale_x, int log2_scale_y)
+gx_path_scale_exp2_shared(gx_path * ppath, int log2_scale_x, int log2_scale_y,
+ bool segments_shared)
{
segment *pseg;
gx_rect_scale_exp2(&ppath->bbox, log2_scale_x, log2_scale_y);
-#define update_xy(pt) gx_point_scale_exp2(&pt, log2_scale_x, log2_scale_y)
- update_xy(ppath->position);
- for (pseg = (segment *) (ppath->first_subpath); pseg != 0;
- pseg = pseg->next
- )
- switch (pseg->type) {
+#define SCALE_XY(pt) gx_point_scale_exp2(&pt, log2_scale_x, log2_scale_y)
+ SCALE_XY(ppath->position);
+ if (!segments_shared) {
+ for (pseg = (segment *) (ppath->first_subpath); pseg != 0;
+ pseg = pseg->next
+ )
+ switch (pseg->type) {
case s_curve:
-#define pcseg ((curve_segment *)pseg)
- update_xy(pcseg->p1);
- update_xy(pcseg->p2);
-#undef pcseg
+ SCALE_XY(((curve_segment *)pseg)->p1);
+ SCALE_XY(((curve_segment *)pseg)->p2);
default:
- update_xy(pseg->pt);
- }
-#undef update_xy
+ SCALE_XY(pseg->pt);
+ }
+ }
+#undef SCALE_XY
return 0;
}
@@ -324,7 +333,11 @@ gx_path_copy_reversed(const gx_path * ppath_old, gx_path * ppath)
if (code < 0)
return code;
}
- for (;; pseg = prev, prev_notes = notes) {
+ /*
+ * The odd '1' in the next statement suppresses a "statement not
+ * reached" warning at the end of the loop from certain compilers.
+ */
+ for (; 1; pseg = prev, prev_notes = notes) {
int code;
prev = pseg->prev;
diff --git a/gs/src/gxpcmap.c b/gs/src/gxpcmap.c
index b6a892729..179b65ba9 100644
--- a/gs/src/gxpcmap.c
+++ b/gs/src/gxpcmap.c
@@ -33,8 +33,6 @@
#include "gxdevmem.h"
#include "gxpcolor.h"
#include "gzstate.h"
-#include "gzpath.h" /* for tweaking sharing flags */
-#include "gzcpath.h" /* ditto */
/* Define the default size of the Pattern cache. */
#define max_cached_patterns_LARGE 50
@@ -140,15 +138,15 @@ gx_device_pattern_accum *
gx_pattern_accum_alloc(gs_memory_t * mem, client_name_t cname)
{
gx_device_pattern_accum *adev =
- gs_alloc_struct(mem, gx_device_pattern_accum,
- &st_device_pattern_accum, cname);
+ gs_alloc_struct(mem, gx_device_pattern_accum,
+ &st_device_pattern_accum, cname);
if (adev == 0)
return 0;
- gx_device_init((gx_device *) adev,
+ gx_device_init((gx_device *)adev,
(const gx_device *)&gs_pattern_accum_device,
mem, true);
- gx_device_forward_fill_in_procs((gx_device_forward *) adev); /* (should only do once) */
+ gx_device_forward_fill_in_procs((gx_device_forward *)adev);
return adev;
}
@@ -162,7 +160,7 @@ private int
pattern_accum_open(gx_device * dev)
{
gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- const gs_pattern_instance *pinst = padev->instance;
+ const gs_pattern1_instance_t *pinst = padev->instance;
gs_memory_t *mem = padev->bitmap_memory;
gx_device_memory *mask = 0;
gx_device_memory *bits = 0;
@@ -209,7 +207,7 @@ pattern_accum_open(gx_device * dev)
if (code >= 0) {
switch (pinst->template.PaintType) {
case 2: /* uncolored */
- padev->target = target;
+ gx_device_set_target((gx_device_forward *)padev, target);
break;
case 1: /* colored */
bits = gs_alloc_struct(mem, gx_device_memory,
@@ -218,7 +216,6 @@ pattern_accum_open(gx_device * dev)
if (bits == 0)
code = gs_note_error(gs_error_VMerror);
else {
- padev->target = (gx_device *) bits;
gs_make_mem_device(bits,
gdev_mem_device_for_bits(target->color_info.depth),
mem, -1, target);
@@ -227,6 +224,8 @@ pattern_accum_open(gx_device * dev)
bits->color_info = target->color_info;
bits->bitmap_memory = mem;
code = (*dev_proc(bits, open_device)) ((gx_device *) bits);
+ gx_device_set_target((gx_device_forward *)padev,
+ (gx_device *)bits);
}
}
}
@@ -256,6 +255,8 @@ pattern_accum_close(gx_device * dev)
(*dev_proc(padev->bits, close_device)) ((gx_device *) padev->bits);
gs_free_object(mem, padev->bits, "pattern_accum_close(bits)");
padev->bits = 0;
+ /* target also points to bits: we mustn't let it be finalized. */
+ padev->target = 0;
}
if (padev->mask != 0) {
(*dev_proc(padev->mask, close_device)) ((gx_device *) padev->mask);
@@ -422,15 +423,21 @@ gstate_set_pattern_cache(gs_state * pgs, gx_pattern_cache * pcache)
private void
gx_pattern_cache_free_entry(gx_pattern_cache * pcache, gx_color_tile * ctile)
{
- gx_device_memory mdev;
-
if (ctile->id != gx_no_bitmap_id) {
+ gs_memory_t *mem = pcache->memory;
+ gx_device_memory mdev;
+
+ /*
+ * We must initialize the memory device properly, even though
+ * we aren't using it for drawing.
+ */
+ gs_make_mem_mono_device(&mdev, mem, NULL);
if (ctile->tmask.data != 0) {
mdev.width = ctile->tmask.size.x;
mdev.height = ctile->tmask.size.y;
- mdev.color_info.depth = 1;
+ /*mdev.color_info.depth = 1;*/
pcache->bits_used -= gdev_mem_bitmap_size(&mdev);
- gs_free_object(pcache->memory, ctile->tmask.data,
+ gs_free_object(mem, ctile->tmask.data,
"free_pattern_cache_entry(mask data)");
ctile->tmask.data = 0; /* for GC */
}
@@ -439,7 +446,7 @@ gx_pattern_cache_free_entry(gx_pattern_cache * pcache, gx_color_tile * ctile)
mdev.height = ctile->tbits.size.y;
mdev.color_info.depth = ctile->depth;
pcache->bits_used -= gdev_mem_bitmap_size(&mdev);
- gs_free_object(pcache->memory, ctile->tbits.data,
+ gs_free_object(mem, ctile->tbits.data,
"free_pattern_cache_entry(bits data)");
ctile->tbits.data = 0; /* for GC */
}
@@ -459,7 +466,7 @@ gx_pattern_cache_add_entry(gs_imager_state * pis,
{
gx_device_memory *mbits = padev->bits;
gx_device_memory *mmask = padev->mask;
- const gs_pattern_instance *pinst = padev->instance;
+ const gs_pattern1_instance_t *pinst = padev->instance;
gx_pattern_cache *pcache;
ulong used = 0;
gx_bitmap_id id = pinst->id;
@@ -560,8 +567,9 @@ int
gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis,
gx_device * dev, gs_color_select_t select)
{
- gx_device_pattern_accum adev;
- gs_pattern_instance *pinst = pdc->mask.ccolor.pattern;
+ gx_device_pattern_accum *adev;
+ gs_pattern1_instance_t *pinst =
+ (gs_pattern1_instance_t *)pdc->ccolor.pattern;
gs_state *saved;
gx_color_tile *ctile;
gs_memory_t *mem = pis->memory;
@@ -573,31 +581,36 @@ gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis,
code = ensure_pattern_cache((gs_imager_state *) pis);
if (code < 0)
return code;
- gx_device_init((gx_device *) & adev,
- (const gx_device *)&gs_pattern_accum_device,
- NULL, true);
- gx_device_forward_fill_in_procs((gx_device_forward *) & adev); /* (should only do once) */
- adev.target = dev;
- adev.instance = pinst;
- adev.bitmap_memory = mem;
- code = (*dev_proc(&adev, open_device)) ((gx_device *) & adev);
+ /*
+ * Note that adev is an internal device, so it will be freed when the
+ * last reference to it from a graphics state is deleted.
+ */
+ adev = gx_pattern_accum_alloc(mem, "gx_pattern_load");
+ if (adev == 0)
+ return_error(gs_error_VMerror);
+ gx_device_set_target((gx_device_forward *)adev, dev);
+ adev->instance = pinst;
+ adev->bitmap_memory = mem;
+ code = dev_proc(adev, open_device)((gx_device *)adev);
if (code < 0)
- return code;
+ goto fail;
saved = gs_gstate(pinst->saved);
- if (saved == 0)
- return_error(gs_error_VMerror);
+ if (saved == 0) {
+ code = gs_note_error(gs_error_VMerror);
+ goto fail;
+ }
if (saved->pattern_cache == 0)
saved->pattern_cache = pis->pattern_cache;
- gs_setdevice_no_init(saved, (gx_device *) & adev);
- code = (*pinst->template.PaintProc) (&pdc->mask.ccolor, saved);
+ gs_setdevice_no_init(saved, (gx_device *)adev);
+ code = (*pinst->template.PaintProc)(&pdc->ccolor, saved);
if (code < 0) {
- (*dev_proc(&adev, close_device)) ((gx_device *) & adev);
+ dev_proc(adev, close_device)((gx_device *)adev);
+ /* Freeing the state will free the device. */
gs_state_free(saved);
return code;
}
/* We REALLY don't like the following cast.... */
- code = gx_pattern_cache_add_entry((gs_imager_state *) pis, &adev,
- &ctile);
+ code = gx_pattern_cache_add_entry((gs_imager_state *)pis, adev, &ctile);
if (code >= 0) {
if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
lprintf("Pattern cache lookup failed after insertion!\n");
@@ -606,33 +619,37 @@ gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis,
}
/* Free the bookkeeping structures, except for the bits and mask */
/* iff they are still needed. */
- (*dev_proc(&adev, close_device)) ((gx_device *) & adev);
+ dev_proc(adev, close_device)((gx_device *)adev);
#ifdef DEBUG
if (gs_debug_c('B')) {
- if (adev.mask)
- debug_dump_bitmap(adev.mask->base, adev.mask->raster,
- adev.mask->height, "[B]Pattern mask");
- if (adev.bits)
- debug_dump_bitmap(((gx_device_memory *) adev.target)->base,
- ((gx_device_memory *) adev.target)->raster,
- adev.target->height, "[B]Pattern bits");
+ if (adev->mask)
+ debug_dump_bitmap(adev->mask->base, adev->mask->raster,
+ adev->mask->height, "[B]Pattern mask");
+ if (adev->bits)
+ debug_dump_bitmap(((gx_device_memory *) adev->target)->base,
+ ((gx_device_memory *) adev->target)->raster,
+ adev->target->height, "[B]Pattern bits");
}
#endif
+ /* Freeing the state will free the device. */
gs_state_free(saved);
return code;
+fail:
+ gs_free_object(mem, adev, "gx_pattern_load");
+ return code;
}
-/* Remap a Pattern color. */
+/* Remap a PatternType 1 color. */
cs_proc_remap_color(gx_remap_Pattern); /* check the prototype */
int
-gx_remap_Pattern(const gs_client_color * pc, const gs_color_space * pcs,
- gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
- gs_color_select_t select)
+gs_pattern1_remap_color(const gs_client_color * pc, const gs_color_space * pcs,
+ gx_device_color * pdc, const gs_imager_state * pis,
+ gx_device * dev, gs_color_select_t select)
{
- gs_pattern_instance *pinst = pc->pattern;
+ gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pc->pattern;
int code;
- pdc->mask.ccolor = *pc;
+ pdc->ccolor = *pc;
if (pinst == 0) {
/* Null pattern */
color_set_null_pattern(pdc);
diff --git a/gs/src/gxpcolor.h b/gs/src/gxpcolor.h
index ccbb8e391..617af17f3 100644
--- a/gs/src/gxpcolor.h
+++ b/gs/src/gxpcolor.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,20 +17,101 @@
*/
-/* Requires gsmatrix.h, gxdevice.h, gxdevmem.h, gxcolor2.h, gxdcolor.h */
+/* Requires gsmatrix.h, gxcolor2.h, gxdcolor.h */
#ifndef gxpcolor_INCLUDED
# define gxpcolor_INCLUDED
+#include "gspcolor.h"
+#include "gxcspace.h"
+#include "gxdevice.h"
+#include "gxdevmem.h"
#include "gxpcache.h"
/*
- * Define the Pattern device color types. There is one type for
- * colored patterns, and one uncolored pattern type for each non-Pattern
+ * Define the type of a Pattern, also used with Pattern instances.
+ */
+#ifndef gs_pattern_type_DEFINED
+# define gs_pattern_type_DEFINED
+typedef struct gs_pattern_type_s gs_pattern_type_t;
+#endif
+struct gs_pattern_type_s {
+ int PatternType;
+ struct pp_ {
+
+ /*
+ * Define whether a Pattern uses the base color space in its color
+ * space, requiring setcolor to provide values for the base color
+ * space. Currently this is true for uncolored PatternType 1
+ * patterns, false for all others.
+ */
+
+#define pattern_proc_uses_base_space(proc)\
+ bool proc(P1(const gs_pattern_template_t *))
+
+ pattern_proc_uses_base_space((*uses_base_space));
+
+ /*
+ * Make an instance of a Pattern.
+ */
+
+#define pattern_proc_make_pattern(proc)\
+ int proc(P5(gs_client_color *, const gs_pattern_template_t *,\
+ const gs_matrix *, gs_state *, gs_memory_t *))
+
+ pattern_proc_make_pattern((*make_pattern));
+
+ /*
+ * Get the template from a Pattern instance.
+ */
+
+#define pattern_proc_get_pattern(proc)\
+ const gs_pattern_template_t *proc(P1(const gs_pattern_instance_t *))
+
+ pattern_proc_get_pattern((*get_pattern));
+
+ /*
+ * Remap a Pattern color to a device color.
+ * cs_proc_remap_color is defined in gxcspace.h.
+ */
+
+#define pattern_proc_remap_color(proc)\
+ cs_proc_remap_color(proc)
+
+ pattern_proc_remap_color((*remap_color));
+
+ } procs;
+};
+
+/*
+ * Initialize the common part of a pattern template. This procedure is for
+ * the use of gs_pattern*_init implementations, not clients.
+ */
+void gs_pattern_common_init(P2(gs_pattern_template_t *,
+ const gs_pattern_type_t *));
+
+/*
+ * Do the generic work for makepattern: allocate the instance and the
+ * saved graphics state, and fill in the common members.
+ */
+int gs_make_pattern_common(P6(gs_client_color *, const gs_pattern_template_t *,
+ const gs_matrix *, gs_state *, gs_memory_t *,
+ gs_memory_type_ptr_t));
+
+/* Declare the freeing procedure for Pattern instances. */
+extern rc_free_proc(rc_free_pattern_instance);
+
+/* Declare the Pattern color space type. */
+extern const gs_color_space_type gs_color_space_type_Pattern;
+
+/*
+ * Define the (PatternType 1) Pattern device color types. There is one type
+ * for colored patterns, and one uncolored pattern type for each non-Pattern
* device color type.
*/
extern const gx_device_color_type_t
- gx_dc_pattern, gx_dc_pure_masked, gx_dc_binary_masked, gx_dc_colored_masked;
+ gx_dc_pattern,
+ gx_dc_pure_masked, gx_dc_binary_masked, gx_dc_colored_masked;
#define gx_dc_type_pattern (&gx_dc_pattern)
@@ -76,7 +157,7 @@ struct gx_color_tile_s {
st_color_tile)
/* Define the Pattern cache. */
- /*#include "gxpcache.h" *//* (above) */
+/*#include "gxpcache.h" *//* (above) */
/* Allocate a Pattern cache. */
/* We shorten the procedure names because some VMS compilers */
@@ -99,16 +180,17 @@ typedef struct gx_device_pattern_accum_s {
gx_device_forward_common;
/* Client sets these before opening */
gs_memory_t *bitmap_memory;
- const gs_pattern_instance *instance;
+ const gs_pattern1_instance_t *instance;
/* open sets these */
gx_device_memory *bits; /* target also points to bits */
gx_device_memory *mask;
} gx_device_pattern_accum;
#define private_st_device_pattern_accum() /* in gxpcmap.c */\
- gs_private_st_suffix_add3(st_device_pattern_accum, gx_device_pattern_accum,\
- "pattern accumulator", pattern_accum_enum, pattern_accum_reloc,\
- st_device_forward, instance, bits, mask)
+ gs_private_st_suffix_add3_final(st_device_pattern_accum,\
+ gx_device_pattern_accum, "pattern accumulator", pattern_accum_enum,\
+ pattern_accum_reloc, gx_device_finalize, st_device_forward,\
+ instance, bits, mask)
/* Allocate a pattern accumulator. */
gx_device_pattern_accum *gx_pattern_accum_alloc(P2(gs_memory_t * memory, client_name_t));
diff --git a/gs/src/gxpcopy.c b/gs/src/gxpcopy.c
index 6df95a3e7..b5bc2e82b 100644
--- a/gs/src/gxpcopy.c
+++ b/gs/src/gxpcopy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,7 @@
#include "gconfigv.h" /* for USE_FPU */
#include "gxfixed.h"
#include "gxfarith.h"
+#include "gxistate.h" /* for access to line params */
#include "gzpath.h"
/* Forward declarations */
@@ -34,11 +35,13 @@ private int monotonize_internal(P2(gx_path *, const curve_segment *));
/* Copy a path, optionally flattening or monotonizing it. */
/* If the copy fails, free the new path. */
int
-gx_path_copy_reducing(const gx_path * ppath_old, gx_path * ppath,
- fixed fixed_flatness, gx_path_copy_options options)
+gx_path_copy_reducing(const gx_path *ppath_old, gx_path *ppath,
+ fixed fixed_flatness, const gs_imager_state *pis,
+ gx_path_copy_options options)
{
const segment *pseg;
-
+ fixed flat = fixed_flatness;
+ gs_fixed_point expansion;
/*
* Since we're going to be adding to the path, unshare it
* before we start.
@@ -51,6 +54,15 @@ gx_path_copy_reducing(const gx_path * ppath_old, gx_path * ppath,
if (gs_debug_c('P'))
gx_dump_path(ppath_old, "before reducing");
#endif
+ if (options & pco_for_stroke) {
+ /* Precompute the maximum expansion of the bounding box. */
+ double width = pis->line_params.half_width;
+
+ expansion.x =
+ float2fixed((fabs(pis->ctm.xx) + fabs(pis->ctm.yx)) * width) * 2;
+ expansion.y =
+ float2fixed((fabs(pis->ctm.xy) + fabs(pis->ctm.yy)) * width) * 2;
+ }
pseg = (const segment *)(ppath_old->first_subpath);
while (pseg) {
switch (pseg->type) {
@@ -72,11 +84,42 @@ gx_path_copy_reducing(const gx_path * ppath_old, gx_path * ppath,
} else {
fixed x0 = ppath->position.x;
fixed y0 = ppath->position.y;
- int k = gx_curve_log2_samples(x0, y0, pc,
- fixed_flatness);
segment_notes notes = pseg->notes;
curve_segment cseg;
+ int k;
+ if (options & pco_for_stroke) {
+ /*
+ * When flattening for stroking, the flatness
+ * must apply to the outside of the resulting
+ * stroked region. We approximate this by
+ * dividing the flatness by the ratio of the
+ * expanded bounding box to the original
+ * bounding box. This is crude, but pretty
+ * simple to calculate, and produces reasonably
+ * good results.
+ */
+ fixed min01, max01, min23, max23;
+ fixed ex, ey, flat_x, flat_y;
+
+#define SET_EXTENT(r, c0, c1, c2, c3)\
+ BEGIN\
+ if (c0 < c1) min01 = c0, max01 = c1;\
+ else min01 = c1, max01 = c0;\
+ if (c2 < c3) min23 = c2, max23 = c3;\
+ else min23 = c3, max23 = c2;\
+ r = max(max01, max23) - min(min01, min23);\
+ END
+ SET_EXTENT(ex, x0, pc->p1.x, pc->p2.x, pc->pt.x);
+ SET_EXTENT(ey, y0, pc->p1.y, pc->p2.y, pc->pt.y);
+#undef SET_EXTENT
+ flat_x = fixed_mult_quo(fixed_flatness, ex,
+ ex + expansion.x);
+ flat_y = fixed_mult_quo(fixed_flatness, ey,
+ ey + expansion.y);
+ flat = min(flat_x, flat_y);
+ }
+ k = gx_curve_log2_samples(x0, y0, pc, flat);
if (options & pco_accurate) {
segment *start;
segment *end;
diff --git a/gs/src/gxrplane.h b/gs/src/gxrplane.h
new file mode 100644
index 000000000..b2304b9f9
--- /dev/null
+++ b/gs/src/gxrplane.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definitions for planar rendering */
+
+#ifndef gxrplane_INCLUDED
+# define gxrplane_INCLUDED
+
+#ifndef gx_device_DEFINED
+# define gx_device_DEFINED
+typedef struct gx_device_s gx_device;
+#endif
+
+/*
+ * Define the parameters for extracting a single plane from chunky pixels.
+ * This structure should be considered opaque, and should only be
+ * initialized with the procedure.
+ */
+typedef struct gx_render_plane_s {
+ int depth;
+ int shift; /* bit position of l.s.b. from low end */
+ int index; /* index within multi-screen halftone */
+} gx_render_plane_t;
+
+/*
+ * Initialize a rendering plane specification for a device. Note that it is
+ * up to the device to decide which bits constitute a given plane identified
+ * by index. (Currently this is done with a fixed procedure, but eventually
+ * it will be made a property of the device somehow, perhaps in the
+ * color_info.)
+ */
+int gx_render_plane_init(P3(gx_render_plane_t *render_plane,
+ const gx_device *dev, int index));
+
+#endif /* gxrplane_INCLUDED */
diff --git a/gs/src/gxsample.c b/gs/src/gxsample.c
index b6d91dc89..459231313 100644
--- a/gs/src/gxsample.c
+++ b/gs/src/gxsample.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,23 +30,56 @@
* they might not wind up properly long- or short-aligned.
*/
#define map4tox(z,a,b,c,d)\
- z, z^a, z^b, z^(a+b),\
- z^c, z^(a+c), z^(b+c), z^(a+b+c),\
- z^d, z^(a+d), z^(b+d), z^(a+b+d),\
- z^(c+d), z^(a+c+d), z^(b+c+d), z^(a+b+c+d)
+ z, z^a, z^b, z^(a+b),\
+ z^c, z^(a+c), z^(b+c), z^(a+b+c),\
+ z^d, z^(a+d), z^(b+d), z^(a+b+d),\
+ z^(c+d), z^(a+c+d), z^(b+c+d), z^(a+b+c+d)
+/* Work around warnings from really picky compilers. */
+#ifdef __STDC__
+# define n0L 0xffffffffU
+# define ffL8 0x0000ff00U
+# define ffL16 0x00ff0000U
+# define ffL24 0xff000000U
+#else
+#if arch_sizeof_long == 4
+/*
+ * The compiler evaluates long expressions mod 2^32. Even very picky
+ * compilers allow assigning signed longs to unsigned longs, so we use
+ * signed constants.
+ */
+# define n0L (-1)
+# define ffL8 0x0000ff00
+# define ffL16 0x00ff0000
+# define ffL24 (-0x01000000)
+#else
+/*
+ * The compiler evaluates long expressions mod 2^64.
+ */
+# define n0L 0xffffffffL
+# define ffL8 0x0000ff00L
+# define ffL16 0x00ff0000L
+# define ffL24 0xff000000L
+#endif
+#endif
#if arch_is_big_endian
-const bits32 lookup4x1to32_identity[16] =
-{map4tox(0L, 0xffL, 0xff00L, 0xff0000L, 0xff000000L)};
-const bits32 lookup4x1to32_inverted[16] =
-{map4tox(0xffffffffL, 0xffL, 0xff00L, 0xff0000L, 0xff000000L)};
-
+const bits32 lookup4x1to32_identity[16] = {
+ map4tox(0, 0xff, ffL8, ffL16, ffL24)
+};
+const bits32 lookup4x1to32_inverted[16] = {
+ map4tox(n0L, 0xff, ffL8, ffL16, ffL24)
+};
#else /* !arch_is_big_endian */
-const bits32 lookup4x1to32_identity[16] =
-{map4tox(0L, 0xff000000L, 0xff0000L, 0xff00L, 0xffL)};
-const bits32 lookup4x1to32_inverted[16] =
-{map4tox(0xffffffffL, 0xff000000L, 0xff0000L, 0xff00L, 0xffL)};
-
+const bits32 lookup4x1to32_identity[16] = {
+ map4tox(0, ffL24, ffL16, ffL8, 0xff)
+};
+const bits32 lookup4x1to32_inverted[16] = {
+ map4tox(n0L, ffL24, ffL16, ffL8, 0xff)
+};
#endif
+#undef n0L
+#undef ffL8
+#undef ffL16
+#undef ffL24
/* ---------------- Unpacking procedures ---------------- */
diff --git a/gs/src/gxsample.h b/gs/src/gxsample.h
index 94f14114d..95c87eda3 100644
--- a/gs/src/gxsample.h
+++ b/gs/src/gxsample.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,14 +40,8 @@ typedef union sample_lookup_s {
* These can be cast to a const sample_lookup_t.
*/
extern const bits32 lookup4x1to32_identity[16];
-
-#define sample_lookup_1_identity\
- ((const sample_lookup_t *)lookup4x1to32_identity)
extern const bits32 lookup4x1to32_inverted[16];
-#define sample_lookup_1_inverted\
- ((const sample_lookup_t *)lookup4x1to32_inverted)
-
/*
* Define procedures to unpack and shuffle image data samples. The Unix C
* compiler can't handle typedefs for procedure (as opposed to
@@ -60,22 +54,22 @@ extern const bits32 lookup4x1to32_inverted[16];
* Note that this procedure may return either a pointer to the buffer, or
* a pointer to the original data.
*/
-#define sample_unpack_proc(proc)\
+#define SAMPLE_UNPACK_PROC(proc)\
const byte *proc(P7(byte *bptr, int *pdata_x, const byte *data, int data_x,\
uint dsize, const sample_lookup_t *ptab, int spread))
-typedef sample_unpack_proc((*sample_unpack_proc_t));
+typedef SAMPLE_UNPACK_PROC((*sample_unpack_proc_t));
/*
* Declare the 1-for-1 unpacking procedure.
*/
-sample_unpack_proc(sample_unpack_copy);
+SAMPLE_UNPACK_PROC(sample_unpack_copy);
/*
* Declare unpacking procedures for 1, 2, 4, and 8 bits per pixel,
* with optional spreading of the result.
*/
-sample_unpack_proc(sample_unpack_1);
-sample_unpack_proc(sample_unpack_2);
-sample_unpack_proc(sample_unpack_4);
-sample_unpack_proc(sample_unpack_8);
+SAMPLE_UNPACK_PROC(sample_unpack_1);
+SAMPLE_UNPACK_PROC(sample_unpack_2);
+SAMPLE_UNPACK_PROC(sample_unpack_4);
+SAMPLE_UNPACK_PROC(sample_unpack_8);
#endif /* gxsample_INCLUDED */
diff --git a/gs/src/gxshade.c b/gs/src/gxshade.c
index ae5c24471..3b100aeab 100644
--- a/gs/src/gxshade.c
+++ b/gs/src/gxshade.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -181,7 +181,7 @@ shade_next_coords(shade_coord_stream_t * cs, gs_fixed_point * ppt,
float x, y;
if ((code = cs->get_decoded(cs, num_bits, decode, &x)) < 0 ||
- (code = cs->get_decoded(cs, num_bits, decode, &y)) < 0 ||
+ (code = cs->get_decoded(cs, num_bits, decode + 2, &y)) < 0 ||
(code = gs_point_transform2fixed(cs->pctm, x, y, &ppt[i])) < 0
)
break;
diff --git a/gs/src/gxshade.h b/gs/src/gxshade.h
index 2d134a71d..d041e130c 100644
--- a/gs/src/gxshade.h
+++ b/gs/src/gxshade.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -108,9 +108,6 @@ typedef struct gs_shading_Tpp_s {
} gs_shading_Tpp_t;
shading_fill_rectangle_proc(gs_shading_Tpp_fill_rectangle);
-/* We should probably get this from somewhere else.... */
-#define max_color_components 4
-
/* Define a stream for decoding packed coordinate values. */
typedef struct shade_coord_stream_s shade_coord_stream_t;
struct shade_coord_stream_s {
@@ -129,7 +126,7 @@ struct shade_coord_stream_s {
/* Define one vertex of a mesh. */
typedef struct mesh_vertex_s {
gs_fixed_point p;
- float cc[max_color_components];
+ float cc[GS_CLIENT_COLOR_MAX_COMPONENTS];
} mesh_vertex_t;
/* Initialize a packed value stream. */
@@ -183,7 +180,7 @@ int shade_next_vertex(P2(shade_coord_stream_t * cs, mesh_vertex_t * vertex));
gx_device *dev;\
gs_imager_state *pis;\
int num_components; /* # of color components */\
- float cc_max_error[max_color_components]
+ float cc_max_error[GS_CLIENT_COLOR_MAX_COMPONENTS]
typedef struct shading_fill_state_s {
shading_fill_state_common;
} shading_fill_state_t;
@@ -211,31 +208,3 @@ int shade_fill_path(P3(const shading_fill_state_t * pfs, gx_path * ppath,
gx_device_color * pdevc));
#endif /* gxshade_INCLUDED */
-
-#if 0 /*************************************************************** */
-
-/*
- * Here is a sketch of what will be needed to generalize Patterns for
- * (the) new PatternType(s).
- */
-typedef struct gs_pattern_instance_s {
- rc_header rc; /* ?? */
- const gs_pattern_type_t *type;
- gs_uid XUID; /* ?? */
- gs_state *saved; /* ?? */
- void *data;
-} gs_pattern_instance_t;
-typedef struct gs_pattern1_instance_data_s {
- ...
-} gs_pattern1_instance_data_t;
-
-#define gs_pattern2_instance_data_common\
- const gs_shading_t *shading;\
- gx_device_color *background;\
- const gs_color_space *color_space;\
- gs_matrix param_to_device_matrix
-typedef struct gs_pattern2_instance_data_common_s {
- gs_pattern2_instance_data_common;
-} gs_pattern2_instance_data_common_t;
-
-#endif /*************************************************************** */
diff --git a/gs/src/gxshade1.c b/gs/src/gxshade1.c
index 608da146d..ade7f6f85 100644
--- a/gs/src/gxshade1.c
+++ b/gs/src/gxshade1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,6 +19,7 @@
/* Rendering for non-mesh shadings */
#include "math_.h"
+#include "memory_.h"
#include "gx.h"
#include "gserrors.h"
#include "gsmatrix.h" /* for gscoord.h */
@@ -86,148 +87,160 @@ shade_fill_device_rectangle(const shading_fill_state_t * pfs,
/* ---------------- Function-based shading ---------------- */
+#define Fb_max_depth 32 /* 16 bits each in X and Y */
+typedef struct Fb_frame_s { /* recursion frame */
+ gs_rect region;
+ gs_client_color cc[4]; /* colors at 4 corners */
+} Fb_frame_t;
+
typedef struct Fb_fill_state_s {
shading_fill_state_common;
const gs_shading_Fb_t *psh;
gs_matrix_fixed ptm; /* parameter space -> device space */
bool orthogonal; /* true iff ptm is xxyy or xyyx */
+ int depth; /* 1 <= depth < Fb_max_depth */
+ Fb_frame_t frames[Fb_max_depth];
} Fb_fill_state_t;
+/****** NEED GC DESCRIPTOR ******/
private int
-Fb_fill_region(const Fb_fill_state_t * pfs, gs_client_color cc[4],
- floatp x0, floatp y0, floatp x1, floatp y1)
+Fb_fill_region(Fb_fill_state_t * pfs)
{
const gs_shading_Fb_t * const psh = pfs->psh;
gs_imager_state *pis = pfs->pis;
+ Fb_frame_t *fp = &pfs->frames[pfs->depth - 1];
-top:
- if (!shade_colors4_converge(cc, (const shading_fill_state_t *)pfs)) {
- /*
- * The colors don't converge. Does the region color more than
- * a single pixel?
- */
- gs_rect region;
+ for (;;) {
+ const double
+ x0 = fp->region.p.x, y0 = fp->region.p.y,
+ x1 = fp->region.q.x, y1 = fp->region.q.y;
- region.p.x = x0, region.p.y = y0;
- region.q.x = x1, region.q.y = y1;
- gs_bbox_transform(&region, (const gs_matrix *)&pfs->ptm, &region);
- if (region.q.x - region.p.x > 1 || region.q.y - region.p.y > 1)
- goto recur;
- {
+ if (!shade_colors4_converge(fp->cc,
+ (const shading_fill_state_t *)pfs) &&
+ fp < &pfs->frames[countof(pfs->frames) - 1]
+ ) {
/*
- * More precisely, does the bounding box of the region,
- * taking fill adjustment into account, span more than 1
- * pixel center in either X or Y?
+ * The colors don't converge. Does the region color more than
+ * a single pixel?
*/
- fixed ax = pis->fill_adjust.x;
- int nx =
- fixed2int_pixround(float2fixed(region.q.x) + ax) -
- fixed2int_pixround(float2fixed(region.p.x) - ax);
- fixed ay = pis->fill_adjust.y;
- int ny =
- fixed2int_pixround(float2fixed(region.q.y) + ay) -
- fixed2int_pixround(float2fixed(region.p.y) - ay);
-
- if ((nx > 1 && ny != 0) || (ny > 1 && nx != 0))
+ gs_rect region;
+
+ gs_bbox_transform(&fp->region, (const gs_matrix *)&pfs->ptm,
+ &region);
+ if (region.q.x - region.p.x > 1 || region.q.y - region.p.y > 1)
goto recur;
+ {
+ /*
+ * More precisely, does the bounding box of the region,
+ * taking fill adjustment into account, span more than 1
+ * pixel center in either X or Y?
+ */
+ fixed ax = pis->fill_adjust.x;
+ int nx =
+ fixed2int_pixround(float2fixed(region.q.x) + ax) -
+ fixed2int_pixround(float2fixed(region.p.x) - ax);
+ fixed ay = pis->fill_adjust.y;
+ int ny =
+ fixed2int_pixround(float2fixed(region.q.y) + ay) -
+ fixed2int_pixround(float2fixed(region.p.y) - ay);
+
+ if ((nx > 1 && ny != 0) || (ny > 1 && nx != 0))
+ goto recur;
+ }
+ /* We could do the 1-pixel case a lot faster! */
}
- /* We could do the 1-pixel case a lot faster! */
- }
- /* Fill the region with the color. */
- {
- gx_device_color dev_color;
- const gs_color_space *pcs = psh->params.ColorSpace;
- gs_fixed_point pts[4];
- int code;
-
- if_debug0('|', "[|]... filling region\n");
- (*pcs->type->restrict_color)(&cc[0], pcs);
- (*pcs->type->remap_color)(&cc[0], pcs, &dev_color, pis,
- pfs->dev, gs_color_select_texture);
- gs_point_transform2fixed(&pfs->ptm, x0, y0, &pts[0]);
- gs_point_transform2fixed(&pfs->ptm, x1, y1, &pts[2]);
- if (pfs->orthogonal) {
- code =
- shade_fill_device_rectangle((const shading_fill_state_t *)pfs,
- &pts[0], &pts[2], &dev_color);
- } else {
- gx_path *ppath = gx_path_alloc(pis->memory, "Fb_fill");
-
- gs_point_transform2fixed(&pfs->ptm, x1, y0, &pts[1]);
- gs_point_transform2fixed(&pfs->ptm, x0, y1, &pts[3]);
- gx_path_add_point(ppath, pts[0].x, pts[0].y);
- gx_path_add_lines(ppath, pts + 1, 3);
- code = shade_fill_path((const shading_fill_state_t *)pfs,
- ppath, &dev_color);
- gx_path_free(ppath, "Fb_fill");
- }
- return code;
- }
-
- /*
- * No luck. Subdivide the region and recur.
- *
- * We should subdivide on the axis that has the largest color
- * discrepancy, but for now we subdivide on the axis with the
- * largest coordinate difference.
- */
-recur:
- {
- gs_client_color mid[2];
- gs_client_color rcc[4];
- gs_function_t *pfn = psh->params.Function;
- float v[2];
- int code;
-
- if (y1 - y0 > x1 - x0) {
- /* Subdivide in Y. */
- float ym = (y0 + y1) * 0.5;
-
- if_debug1('|', "[|]dividing at y=%g\n", ym);
- v[1] = ym;
- v[0] = x0;
- code = gs_function_evaluate(pfn, v, mid[0].paint.values);
- if (code < 0)
- return code;
- v[0] = x1;
- code = gs_function_evaluate(pfn, v, mid[1].paint.values);
- if (code < 0)
+ /* Fill the region with the color. */
+ {
+ gx_device_color dev_color;
+ const gs_color_space *pcs = psh->params.ColorSpace;
+ gs_client_color cc;
+ gs_fixed_point pts[4];
+ int code;
+
+ if_debug0('|', "[|]... filling region\n");
+ cc = fp->cc[0];
+ (*pcs->type->restrict_color)(&cc, pcs);
+ (*pcs->type->remap_color)(&cc, pcs, &dev_color, pis,
+ pfs->dev, gs_color_select_texture);
+ gs_point_transform2fixed(&pfs->ptm, x0, y0, &pts[0]);
+ gs_point_transform2fixed(&pfs->ptm, x1, y1, &pts[2]);
+ if (pfs->orthogonal) {
+ code =
+ shade_fill_device_rectangle((const shading_fill_state_t *)pfs,
+ &pts[0], &pts[2], &dev_color);
+ } else {
+ gx_path *ppath = gx_path_alloc(pis->memory, "Fb_fill");
+
+ gs_point_transform2fixed(&pfs->ptm, x1, y0, &pts[1]);
+ gs_point_transform2fixed(&pfs->ptm, x0, y1, &pts[3]);
+ gx_path_add_point(ppath, pts[0].x, pts[0].y);
+ gx_path_add_lines(ppath, pts + 1, 3);
+ code = shade_fill_path((const shading_fill_state_t *)pfs,
+ ppath, &dev_color);
+ gx_path_free(ppath, "Fb_fill");
+ }
+ if (code < 0 || fp == &pfs->frames[0])
return code;
- rcc[0].paint = cc[0].paint;
- rcc[1].paint = cc[1].paint;
- rcc[2].paint = mid[0].paint;
- rcc[3].paint = mid[1].paint;
- code = Fb_fill_region(pfs, rcc, x0, y0, x1, ym);
- cc[0].paint = mid[0].paint;
- cc[1].paint = mid[1].paint;
- y0 = ym;
- } else {
- /* Subdivide in X. */
- float xm = (x0 + x1) * 0.5;
+ --fp;
+ continue;
+ }
- if_debug1('|', "[|]dividing at x=%g\n", xm);
- v[0] = xm;
- v[1] = y0;
- code = gs_function_evaluate(pfn, v, mid[0].paint.values);
- if (code < 0)
- return code;
- v[1] = y1;
- code = gs_function_evaluate(pfn, v, mid[2].paint.values);
+ /*
+ * No luck. Subdivide the region and recur.
+ *
+ * We should subdivide on the axis that has the largest color
+ * discrepancy, but for now we subdivide on the axis with the
+ * largest coordinate difference.
+ */
+ recur:
+ {
+ gs_function_t *pfn = psh->params.Function;
+ float v[2];
+ int code;
+
+ if (fabs(y1 - y0) > fabs(x1 - x0)) {
+ /* Subdivide in Y. */
+ double ym = (y0 + y1) * 0.5;
+
+ if_debug1('|', "[|]dividing at y=%g\n", ym);
+ v[1] = ym;
+ v[0] = x0;
+ code = gs_function_evaluate(pfn, v, fp[1].cc[2].paint.values);
+ if (code < 0)
+ return code;
+ v[0] = x1;
+ code = gs_function_evaluate(pfn, v, fp[1].cc[3].paint.values);
+ fp[1].region.q.x = x1;
+ fp[1].region.q.y = fp->region.p.y = ym;
+ fp[1].cc[0].paint = fp->cc[0].paint;
+ fp[1].cc[1].paint = fp->cc[1].paint;
+ fp->cc[0].paint = fp[1].cc[2].paint;
+ fp->cc[1].paint = fp[1].cc[3].paint;
+ } else {
+ /* Subdivide in X. */
+ double xm = (x0 + x1) * 0.5;
+
+ if_debug1('|', "[|]dividing at x=%g\n", xm);
+ v[0] = xm;
+ v[1] = y0;
+ code = gs_function_evaluate(pfn, v, fp[1].cc[1].paint.values);
+ if (code < 0)
+ return code;
+ v[1] = y1;
+ code = gs_function_evaluate(pfn, v, fp[1].cc[3].paint.values);
+ fp[1].region.q.x = fp->region.p.x = xm;
+ fp[1].region.q.y = y1;
+ fp[1].cc[0].paint = fp->cc[0].paint;
+ fp[1].cc[2].paint = fp->cc[2].paint;
+ fp->cc[0].paint = fp[1].cc[1].paint;
+ fp->cc[2].paint = fp[1].cc[3].paint;
+ }
if (code < 0)
return code;
- rcc[0].paint = cc[0].paint;
- rcc[1].paint = mid[0].paint;
- rcc[2].paint = cc[2].paint;
- rcc[3].paint = mid[1].paint;
- code = Fb_fill_region(pfs, rcc, x0, y0, xm, y1);
- cc[0].paint = mid[0].paint;
- cc[2].paint = mid[1].paint;
- x0 = xm;
+ fp[1].region.p.x = x0, fp[1].region.p.y = y0;
+ ++fp;
}
- if (code < 0)
- return code;
}
- goto top;
}
int
@@ -236,10 +249,9 @@ gs_shading_Fb_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
{
const gs_shading_Fb_t * const psh = (const gs_shading_Fb_t *)psh0;
gs_matrix save_ctm;
- int xi, yi, code;
+ int xi, yi;
float x[2], y[2];
Fb_fill_state_t state;
- gs_client_color cc[4];
shade_init_fill_state((shading_fill_state_t *) & state, psh0, dev, pis);
state.psh = psh;
@@ -265,112 +277,142 @@ gs_shading_Fb_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
v[0] = x[xi], v[1] = y[yi];
gs_function_evaluate(psh->params.Function, v,
- cc[yi * 2 + xi].paint.values);
+ state.frames[0].cc[yi * 2 + xi].paint.values);
}
- code = Fb_fill_region(&state, cc, x[0], y[0], x[1], y[1]);
- return code;
+ state.frames[0].region.p.x = x[0];
+ state.frames[0].region.p.y = y[0];
+ state.frames[0].region.q.x = x[1];
+ state.frames[0].region.q.y = y[1];
+ state.depth = 1;
+ return Fb_fill_region(&state);
}
/* ---------------- Axial shading ---------------- */
+/*
+ * Note that the max recursion depth and the frame structure are shared
+ * with radial shading.
+ */
+#define AR_max_depth 16
+typedef struct AR_frame_s { /* recursion frame */
+ double t0, t1;
+ gs_client_color cc[2]; /* color at t0, t1 */
+} AR_frame_t;
+
+#define A_max_depth AR_max_depth
+typedef AR_frame_t A_frame_t;
+
typedef struct A_fill_state_s {
shading_fill_state_common;
const gs_shading_A_t *psh;
gs_rect rect;
gs_point delta;
double length, dd;
+ int depth;
+ A_frame_t frames[A_max_depth];
} A_fill_state_t;
+/****** NEED GC DESCRIPTOR ******/
/* Note t0 and t1 vary over [0..1], not the Domain. */
+
private int
-A_fill_region(const A_fill_state_t * pfs, gs_client_color cc[2],
+A_fill_stripe(const A_fill_state_t * pfs, gs_client_color *pcc,
floatp t0, floatp t1)
{
const gs_shading_A_t * const psh = pfs->psh;
-
-top:
- if (!shade_colors2_converge(cc, (const shading_fill_state_t *)pfs)) {
+ gx_device_color dev_color;
+ const gs_color_space *pcs = psh->params.ColorSpace;
+ gs_imager_state *pis = pfs->pis;
+ double
+ x0 = psh->params.Coords[0] + pfs->delta.x * t0,
+ y0 = psh->params.Coords[1] + pfs->delta.y * t0;
+ double
+ x1 = psh->params.Coords[0] + pfs->delta.x * t1,
+ y1 = psh->params.Coords[1] + pfs->delta.y * t1;
+ gs_fixed_point pts[4];
+ int code;
+
+ (*pcs->type->restrict_color)(pcc, pcs);
+ (*pcs->type->remap_color)(pcc, pcs, &dev_color, pis,
+ pfs->dev, gs_color_select_texture);
+ if (x0 == x1) {
+ /* Stripe is horizontal. */
+ x0 = pfs->rect.p.x;
+ x1 = pfs->rect.q.x;
+ } else if (y0 == y1) {
+ /* Stripe is vertical. */
+ y0 = pfs->rect.p.y;
+ y1 = pfs->rect.q.y;
+ } else {
/*
- * The colors don't converge. Is the stripe less than 1 pixel wide?
+ * Stripe is neither horizontal nor vertical.
+ * Extend it to the edges of the rectangle.
*/
- if (pfs->length * (t1 - t0) > 1)
- goto recur;
+ gx_path *ppath = gx_path_alloc(pis->memory, "A_fill");
+ double dist = max(pfs->rect.q.x - pfs->rect.p.x,
+ pfs->rect.q.y - pfs->rect.p.y);
+ double denom = hypot(pfs->delta.x, pfs->delta.y);
+ double dx = dist * pfs->delta.y / denom,
+ dy = -dist * pfs->delta.x / denom;
+
+ if_debug6('|', "[|]p0=(%g,%g), p1=(%g,%g), dxy=(%g,%g)\n",
+ x0, y0, x1, y1, dx, dy);
+ gs_point_transform2fixed(&pis->ctm, x0 - dx, y0 - dy, &pts[0]);
+ gs_point_transform2fixed(&pis->ctm, x0 + dx, y0 + dy, &pts[1]);
+ gs_point_transform2fixed(&pis->ctm, x1 + dx, y1 + dy, &pts[2]);
+ gs_point_transform2fixed(&pis->ctm, x1 - dx, y1 - dy, &pts[3]);
+ gx_path_add_point(ppath, pts[0].x, pts[0].y);
+ gx_path_add_lines(ppath, pts + 1, 3);
+ code = shade_fill_path((const shading_fill_state_t *)pfs,
+ ppath, &dev_color);
+ gx_path_free(ppath, "A_fill");
+ return code;
}
- /* Fill the region with the color. */
- {
- gx_device_color dev_color;
- const gs_color_space *pcs = psh->params.ColorSpace;
- gs_imager_state *pis = pfs->pis;
- double
- x0 = psh->params.Coords[0] + pfs->delta.x * t0,
- y0 = psh->params.Coords[1] + pfs->delta.y * t0;
- double
- x1 = psh->params.Coords[0] + pfs->delta.x * t1,
- y1 = psh->params.Coords[1] + pfs->delta.y * t1;
- gs_fixed_point pts[4];
- int code;
-
- (*pcs->type->restrict_color)(&cc[0], pcs);
- (*pcs->type->remap_color)(&cc[0], pcs, &dev_color, pis,
- pfs->dev, gs_color_select_texture);
- if (x0 == x1) {
- /* Stripe is horizontal. */
- x0 = pfs->rect.p.x;
- x1 = pfs->rect.q.x;
- } else if (y0 == y1) {
- /* Stripe is vertical. */
- y0 = pfs->rect.p.y;
- y1 = pfs->rect.q.y;
- } else {
+ /* Stripe is horizontal or vertical. */
+ gs_point_transform2fixed(&pis->ctm, x0, y0, &pts[0]);
+ gs_point_transform2fixed(&pis->ctm, x1, y1, &pts[1]);
+ return
+ shade_fill_device_rectangle((const shading_fill_state_t *)pfs,
+ &pts[0], &pts[1], &dev_color);
+}
+
+private int
+A_fill_region(A_fill_state_t * pfs)
+{
+ const gs_shading_A_t * const psh = pfs->psh;
+ gs_function_t * const pfn = psh->params.Function;
+ A_frame_t *fp = &pfs->frames[pfs->depth - 1];
+
+ for (;;) {
+ double t0 = fp->t0, t1 = fp->t1;
+
+ if (!shade_colors2_converge(fp->cc,
+ (const shading_fill_state_t *)pfs) &&
/*
- * Stripe is neither horizontal nor vertical.
- * Extend it to the edges of the rectangle.
+ * The colors don't converge. Is the stripe less than 1
+ * pixel wide?
*/
- gx_path *ppath = gx_path_alloc(pis->memory, "A_fill");
- double dist = max(pfs->rect.q.x - pfs->rect.p.x,
- pfs->rect.q.y - pfs->rect.p.y);
- double denom = hypot(pfs->delta.x, pfs->delta.y);
- double dx = dist * pfs->delta.y / denom,
- dy = -dist * pfs->delta.x / denom;
-
- if_debug6('|', "[|]p0=(%g,%g), p1=(%g,%g), dxy=(%g,%g)\n",
- x0, y0, x1, y1, dx, dy);
- gs_point_transform2fixed(&pis->ctm, x0 - dx, y0 - dy, &pts[0]);
- gs_point_transform2fixed(&pis->ctm, x0 + dx, y0 + dy, &pts[1]);
- gs_point_transform2fixed(&pis->ctm, x1 + dx, y1 + dy, &pts[2]);
- gs_point_transform2fixed(&pis->ctm, x1 - dx, y1 - dy, &pts[3]);
- gx_path_add_point(ppath, pts[0].x, pts[0].y);
- gx_path_add_lines(ppath, pts + 1, 3);
- code = shade_fill_path((const shading_fill_state_t *)pfs,
- ppath, &dev_color);
- gx_path_free(ppath, "A_fill");
- return code;
- }
- /* Stripe is horizontal or vertical. */
- gs_point_transform2fixed(&pis->ctm, x0, y0, &pts[0]);
- gs_point_transform2fixed(&pis->ctm, x1, y1, &pts[1]);
- return
- shade_fill_device_rectangle((const shading_fill_state_t *)pfs,
- &pts[0], &pts[1], &dev_color);
- }
-
- /*
- * No luck. Subdivide the interval and recur.
- */
-recur:
- {
- gs_client_color ccm, rcc[2];
- gs_function_t *pfn = psh->params.Function;
- float tm = (t0 + t1) * 0.5;
- float dm = tm * pfs->dd + psh->params.Domain[0];
+ pfs->length * (t1 - t0) > 1 &&
+ fp < &pfs->frames[countof(pfs->frames) - 1]
+ ) {
+ /* Subdivide the interval and recur. */
+ double tm = (t0 + t1) * 0.5;
+ float dm = tm * pfs->dd + psh->params.Domain[0];
+
+ gs_function_evaluate(pfn, &dm, fp[1].cc[1].paint.values);
+ fp[1].cc[0].paint = fp->cc[0].paint;
+ fp[1].t0 = t0;
+ fp[1].t1 = fp->t0 = tm;
+ fp->cc[0].paint = fp[1].cc[1].paint;
+ ++fp;
+ } else {
+ /* Fill the region with the color. */
+ int code = A_fill_stripe(pfs, &fp->cc[0], t0, t1);
- gs_function_evaluate(pfn, &dm, ccm.paint.values);
- rcc[0].paint = cc[0].paint;
- rcc[1].paint = ccm.paint;
- A_fill_region(pfs, rcc, t0, tm);
- cc[0].paint = ccm.paint;
- t0 = tm;
- goto top;
+ if (code < 0 || fp == &pfs->frames[0])
+ return code;
+ --fp;
+ }
}
}
@@ -379,134 +421,197 @@ gs_shading_A_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
gx_device * dev, gs_imager_state * pis)
{
const gs_shading_A_t *const psh = (const gs_shading_A_t *)psh0;
+ gs_matrix cmat;
+ gs_rect t_rect;
A_fill_state_t state;
- gs_client_color cc[2];
- float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1], dd = d1 - d0;
+ gs_client_color rcc[2];
+ float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1];
+ float dd = d1 - d0;
+ float t0, t1;
float t[2];
gs_point dist;
int i;
+ int code;
- shade_init_fill_state((shading_fill_state_t *) & state, psh0, dev, pis);
+ shade_init_fill_state((shading_fill_state_t *)&state, psh0, dev, pis);
state.psh = psh;
state.rect = *rect;
- /* Compute the parameter range. */
- t[0] = d0;
- t[1] = d1;
-/****** INTERSECT Domain WITH rect ******/
- for (i = 0; i < 2; ++i)
- gs_function_evaluate(psh->params.Function, &t[i],
- cc[i].paint.values);
+ /*
+ * Compute the parameter range. We construct a matrix in which
+ * (0,0) corresponds to t = 0 and (0,1) corresponds to t = 1,
+ * and use it to inverse-map the rectangle to be filled.
+ */
+ cmat.tx = psh->params.Coords[0];
+ cmat.ty = psh->params.Coords[1];
state.delta.x = psh->params.Coords[2] - psh->params.Coords[0];
state.delta.y = psh->params.Coords[3] - psh->params.Coords[1];
+ cmat.yx = state.delta.x;
+ cmat.yy = state.delta.y;
+ cmat.xx = cmat.yy;
+ cmat.xy = -cmat.yx;
+ gs_bbox_transform_inverse(rect, &cmat, &t_rect);
+ state.frames[0].t0 = t0 = max(t_rect.p.y, 0);
+ t[0] = t0 * dd + d0;
+ state.frames[0].t1 = t1 = min(t_rect.q.y, 1);
+ t[1] = t1 * dd + d0;
+ for (i = 0; i < 2; ++i) {
+ gs_function_evaluate(psh->params.Function, &t[i],
+ rcc[i].paint.values);
+ }
+ memcpy(state.frames[0].cc, rcc, sizeof(rcc[0]) * 2);
gs_distance_transform(state.delta.x, state.delta.y, &ctm_only(pis),
&dist);
state.length = hypot(dist.x, dist.y); /* device space line length */
state.dd = dd;
-/****** DOESN'T HANDLE Extend ******/
- return A_fill_region(&state, cc, (t[0] - d0) / dd, (t[1] - d0) / dd);
+ state.depth = 1;
+ code = A_fill_region(&state);
+ if (psh->params.Extend[0] && t0 > t_rect.p.y) {
+ if (code < 0)
+ return code;
+ code = A_fill_stripe(&state, &rcc[0], t_rect.p.y, t0);
+ }
+ if (psh->params.Extend[1] && t1 < t_rect.q.y) {
+ if (code < 0)
+ return code;
+ code = A_fill_stripe(&state, &rcc[1], t1, t_rect.q.y);
+ }
+ return code;
}
/* ---------------- Radial shading ---------------- */
+#define R_max_depth AR_max_depth
+typedef AR_frame_t R_frame_t;
+
typedef struct R_fill_state_s {
shading_fill_state_common;
const gs_shading_R_t *psh;
gs_rect rect;
gs_point delta;
double dr, width, dd;
+ int depth;
+ R_frame_t frames[R_max_depth];
} R_fill_state_t;
+/****** NEED GC DESCRIPTOR ******/
/* Note t0 and t1 vary over [0..1], not the Domain. */
+
private int
-R_fill_region(const R_fill_state_t * pfs, gs_client_color cc[2],
- floatp t0, floatp t1)
+R_fill_annulus(const R_fill_state_t * pfs, gs_client_color *pcc,
+ floatp t0, floatp t1, floatp r0, floatp r1)
{
const gs_shading_R_t * const psh = pfs->psh;
-
-top:
- if (!shade_colors2_converge(cc, (const shading_fill_state_t *)pfs)) {
- /*
- * The colors don't converge. Is the annulus less than 1 pixel wide?
- */
- if (pfs->width * (t1 - t0) > 1)
- goto recur;
- /* We could do the 1-pixel case a lot faster! */
- }
- /* Fill the region with the color. */
- {
- gx_device_color dev_color;
- const gs_color_space *pcs = psh->params.ColorSpace;
- gs_imager_state *pis = pfs->pis;
- double
- x0 = psh->params.Coords[0] + pfs->delta.x * t0,
- y0 = psh->params.Coords[1] + pfs->delta.y * t0,
- r0 = psh->params.Coords[2] + pfs->dr * t0;
- double
- x1 = psh->params.Coords[0] + pfs->delta.x * t1,
- y1 = psh->params.Coords[1] + pfs->delta.y * t1,
- r1 = psh->params.Coords[2] + pfs->dr * t1;
- gx_path *ppath = gx_path_alloc(pis->memory, "R_fill");
- int code;
-
- (*pcs->type->restrict_color)(&cc[0], pcs);
- (*pcs->type->remap_color)(&cc[0], pcs, &dev_color, pis,
- pfs->dev, gs_color_select_texture);
- if ((code = gs_imager_arc_add(ppath, pis, false, x0, y0, r0,
- 0.0, 360.0, false)) >= 0 &&
- (code = gs_imager_arc_add(ppath, pis, true, x1, y1, r1,
- 0.0, 360.0, false)) >= 0
- ) {
- code = shade_fill_path((const shading_fill_state_t *)pfs,
- ppath, &dev_color);
- }
- gx_path_free(ppath, "R_fill");
- return code;
+ gx_device_color dev_color;
+ const gs_color_space *pcs = psh->params.ColorSpace;
+ gs_imager_state *pis = pfs->pis;
+ double
+ x0 = psh->params.Coords[0] + pfs->delta.x * t0,
+ y0 = psh->params.Coords[1] + pfs->delta.y * t0;
+ double
+ x1 = psh->params.Coords[0] + pfs->delta.x * t1,
+ y1 = psh->params.Coords[1] + pfs->delta.y * t1;
+ gx_path *ppath = gx_path_alloc(pis->memory, "R_fill");
+ int code;
+
+ (*pcs->type->restrict_color)(pcc, pcs);
+ (*pcs->type->remap_color)(pcc, pcs, &dev_color, pis,
+ pfs->dev, gs_color_select_texture);
+ if ((code = gs_imager_arc_add(ppath, pis, false, x0, y0, r0,
+ 0.0, 360.0, false)) >= 0 &&
+ (code = gs_imager_arc_add(ppath, pis, true, x1, y1, r1,
+ 360.0, 0.0, false)) >= 0
+ ) {
+ code = shade_fill_path((const shading_fill_state_t *)pfs,
+ ppath, &dev_color);
}
+ gx_path_free(ppath, "R_fill");
+ return code;
+}
- /*
- * No luck. Subdivide the interval and recur.
- */
-recur:
- {
- gs_client_color ccm, rcc[2];
- gs_function_t *pfn = psh->params.Function;
+private int
+R_fill_region(R_fill_state_t * pfs)
+{
+ const gs_shading_R_t * const psh = pfs->psh;
+ gs_function_t *pfn = psh->params.Function;
+ R_frame_t *fp = &pfs->frames[pfs->depth - 1];
+
+ for (;;) {
+ double t0 = fp->t0, t1 = fp->t1;
+
+ if (!shade_colors2_converge(fp->cc,
+ (const shading_fill_state_t *)pfs) &&
+ /*
+ * The colors don't converge. Is the annulus less than 1 pixel
+ * wide?
+ */
+ pfs->width * (t1 - t0) > 1 &&
+ fp < &pfs->frames[countof(pfs->frames) - 1]
+ ) {
+ /* Subdivide the interval and recur. */
float tm = (t0 + t1) * 0.5;
float dm = tm * pfs->dd + psh->params.Domain[0];
- gs_function_evaluate(pfn, &dm, ccm.paint.values);
- rcc[0].paint = cc[0].paint;
- rcc[1].paint = ccm.paint;
- R_fill_region(pfs, rcc, t0, tm);
- cc[0].paint = ccm.paint;
- t0 = tm;
- goto top;
+ gs_function_evaluate(pfn, &dm, fp[1].cc[1].paint.values);
+ fp[1].cc[0].paint = fp->cc[0].paint;
+ fp[1].t0 = t0;
+ fp[1].t1 = fp->t0 = tm;
+ fp->cc[0].paint = fp[1].cc[1].paint;
+ ++fp;
+ } else {
+ /* Fill the region with the color. */
+ int code = R_fill_annulus(pfs, &fp->cc[0], t0, t1,
+ psh->params.Coords[2] + pfs->dr * t0,
+ psh->params.Coords[2] + pfs->dr * t1);
+
+ if (code < 0 || fp == &pfs->frames[0])
+ return code;
+ --fp;
+ }
}
}
+private double
+R_compute_radius(floatp x, floatp y, const gs_rect *rect)
+{
+ double x0 = rect->p.x - x, y0 = rect->p.y - y,
+ x1 = rect->q.x - x, y1 = rect->q.y - y;
+ double r00 = hypot(x0, y0), r01 = hypot(x0, y1),
+ r10 = hypot(x1, y0), r11 = hypot(x1, y1);
+ double rm0 = max(r00, r01), rm1 = max(r10, r11);
+
+ return max(rm0, rm1);
+}
+
int
gs_shading_R_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
gx_device * dev, gs_imager_state * pis)
{
const gs_shading_R_t *const psh = (const gs_shading_R_t *)psh0;
R_fill_state_t state;
- gs_client_color cc[2];
- float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1], dd = d1 - d0;
+ gs_client_color rcc[2];
+ float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1];
+ float dd = d1 - d0;
+ float x0 = psh->params.Coords[0], y0 = psh->params.Coords[1];
+ floatp r0 = psh->params.Coords[2];
+ float x1 = psh->params.Coords[3], y1 = psh->params.Coords[4];
+ floatp r1 = psh->params.Coords[5];
float t[2];
int i;
+ int code;
- shade_init_fill_state((shading_fill_state_t *) & state, psh0, dev, pis);
+ shade_init_fill_state((shading_fill_state_t *)&state, psh0, dev, pis);
state.psh = psh;
state.rect = *rect;
/* Compute the parameter range. */
t[0] = d0;
t[1] = d1;
-/****** INTERSECT Domain WITH rect ******/
for (i = 0; i < 2; ++i)
gs_function_evaluate(psh->params.Function, &t[i],
- cc[i].paint.values);
- state.delta.x = psh->params.Coords[3] - psh->params.Coords[0];
- state.delta.y = psh->params.Coords[4] - psh->params.Coords[1];
- state.dr = psh->params.Coords[5] - psh->params.Coords[2];
+ rcc[i].paint.values);
+ memcpy(state.frames[0].cc, rcc, sizeof(rcc[0]) * 2);
+ state.delta.x = x1 - x0;
+ state.delta.y = y1 - y0;
+ state.dr = r1 - r0;
/*
* Compute the annulus width in its thickest direction. This is
* only used for a conservative check, so it can be pretty crude
@@ -516,6 +621,27 @@ gs_shading_R_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
(fabs(pis->ctm.xx) + fabs(pis->ctm.xy) + fabs(pis->ctm.yx) +
fabs(pis->ctm.yy)) * fabs(state.dr);
state.dd = dd;
-/****** DOESN'T HANDLE Extend ******/
- return R_fill_region(&state, cc, (t[0] - d0) / dd, (t[1] - d0) / dd);
+ if (psh->params.Extend[0]) {
+ if (r0 < r1)
+ code = R_fill_annulus(&state, &rcc[0], 0.0, 0.0, 0.0, r0);
+ else
+ code = R_fill_annulus(&state, &rcc[0], 0.0, 0.0, r0,
+ R_compute_radius(x0, y0, rect));
+ if (code < 0)
+ return code;
+ }
+ state.depth = 1;
+ state.frames[0].t0 = (t[0] - d0) / dd;
+ state.frames[0].t1 = (t[1] - d0) / dd;
+ code = R_fill_region(&state);
+ if (psh->params.Extend[1]) {
+ if (code < 0)
+ return code;
+ if (r0 < r1)
+ code = R_fill_annulus(&state, &rcc[1], 1.0, 1.0, r1,
+ R_compute_radius(x1, y1, rect));
+ else
+ code = R_fill_annulus(&state, &rcc[1], 1.0, 1.0, 0.0, r1);
+ }
+ return code;
}
diff --git a/gs/src/gxshade4.c b/gs/src/gxshade4.c
index 0b16dab3f..56959a32a 100644
--- a/gs/src/gxshade4.c
+++ b/gs/src/gxshade4.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -45,124 +45,190 @@ mesh_init_fill_state(mesh_fill_state_t * pfs, const gs_shading_mesh_t * psh,
shade_bbox_transform2fixed(rect, pis, &pfs->rect);
}
+/* Initialize the recursion state for filling one triangle. */
+void
+mesh_init_fill_triangle(mesh_fill_state_t * pfs,
+ const mesh_vertex_t *va, const mesh_vertex_t *vb, const mesh_vertex_t *vc,
+ bool check_clipping)
+{
+ pfs->depth = 1;
+ pfs->frames[0].va = *va;
+ pfs->frames[0].vb = *vb;
+ pfs->frames[0].vc = *vc;
+ pfs->frames[0].check_clipping = check_clipping;
+}
+
#define SET_MIN_MAX_3(vmin, vmax, a, b, c)\
if ( a < b ) vmin = a, vmax = b; else vmin = b, vmax = a;\
if ( c < vmin ) vmin = c; else if ( c > vmax ) vmax = c
int
-mesh_fill_triangle(const mesh_fill_state_t * pfs, const mesh_vertex_t *va,
- const mesh_vertex_t *vb, const mesh_vertex_t *vc,
- bool check)
+mesh_fill_triangle(mesh_fill_state_t * pfs)
{
const gs_shading_mesh_t *psh = pfs->pshm;
+ gs_imager_state *pis = pfs->pis;
+ mesh_frame_t *fp = &pfs->frames[pfs->depth - 1];
int ci;
- /*
- * Fill the triangle with vertices at va->p, vb->p, and vc->p
- * with color va->cc.
- * If check is true, check for whether the triangle is entirely
- * inside the rectangle, entirely outside, or partly inside;
- * if check is false, assume the triangle is entirely inside.
- */
- if (check) {
- fixed xmin, ymin, xmax, ymax;
+ for (;;) {
+ bool check = fp->check_clipping;
- SET_MIN_MAX_3(xmin, xmax, va->p.x, vb->p.x, vc->p.x);
- SET_MIN_MAX_3(ymin, ymax, va->p.y, vb->p.y, vc->p.y);
- if (xmin >= pfs->rect.p.x && xmax <= pfs->rect.q.x &&
- ymin >= pfs->rect.p.y && ymax <= pfs->rect.q.y
- ) {
- /* The triangle is entirely inside the rectangle. */
- check = false;
- } else if (xmin >= pfs->rect.q.x || xmax <= pfs->rect.p.x ||
- ymin >= pfs->rect.q.y || ymax <= pfs->rect.p.y
- ) {
- /* The triangle is entirely outside the rectangle. */
- return 0;
+ /*
+ * Fill the triangle with vertices at fp->va.p, fp->vb.p, and
+ * fp->vc.p with color fp->va.cc. If check is true, check for
+ * whether the triangle is entirely inside the rectangle, entirely
+ * outside, or partly inside; if check is false, assume the triangle
+ * is entirely inside.
+ */
+ if (check) {
+ fixed xmin, ymin, xmax, ymax;
+
+ SET_MIN_MAX_3(xmin, xmax, fp->va.p.x, fp->vb.p.x, fp->vc.p.x);
+ SET_MIN_MAX_3(ymin, ymax, fp->va.p.y, fp->vb.p.y, fp->vc.p.y);
+ if (xmin >= pfs->rect.p.x && xmax <= pfs->rect.q.x &&
+ ymin >= pfs->rect.p.y && ymax <= pfs->rect.q.y
+ ) {
+ /* The triangle is entirely inside the rectangle. */
+ check = false;
+ } else if (xmin >= pfs->rect.q.x || xmax <= pfs->rect.p.x ||
+ ymin >= pfs->rect.q.y || ymax <= pfs->rect.p.y
+ ) {
+ /* The triangle is entirely outside the rectangle. */
+ goto next;
+ }
}
- }
- /* Check whether the colors fall within the smoothness criterion. */
- for (ci = 0; ci < pfs->num_components; ++ci) {
- float c0 = va->cc[ci], c1 = vb->cc[ci], c2 = vc->cc[ci];
- float cmin, cmax;
+ if (fp < &pfs->frames[countof(pfs->frames) - 3]) {
+ /* Check whether the colors fall within the smoothness criterion. */
+ for (ci = 0; ci < pfs->num_components; ++ci) {
+ float
+ c0 = fp->va.cc[ci], c1 = fp->vb.cc[ci], c2 = fp->vc.cc[ci];
+ float cmin, cmax;
- SET_MIN_MAX_3(cmin, cmax, c0, c1, c2);
- if (cmax - cmin > pfs->cc_max_error[ci])
- goto recur;
- }
- /* Fill the triangle with the color. */
- {
- gx_device_color dev_color;
- const gs_color_space *pcs = psh->params.ColorSpace;
- gs_imager_state *pis = pfs->pis;
- gs_client_color fcc;
- int code;
+ SET_MIN_MAX_3(cmin, cmax, c0, c1, c2);
+ if (cmax - cmin > pfs->cc_max_error[ci])
+ goto nofill;
+ }
+ }
+ fill:
+ /* Fill the triangle with the color. */
+ {
+ gx_device_color dev_color;
+ const gs_color_space *pcs = psh->params.ColorSpace;
+ gs_client_color fcc;
+ int code;
- memcpy(&fcc.paint, va->cc, sizeof(fcc.paint));
- (*pcs->type->restrict_color)(&fcc, pcs);
- (*pcs->type->remap_color)(&fcc, pcs, &dev_color, pis,
- pfs->dev, gs_color_select_texture);
-/****** SHOULD ADD adjust ON ANY OUTSIDE EDGES ******/
+ memcpy(&fcc.paint, fp->va.cc, sizeof(fcc.paint));
+ (*pcs->type->restrict_color)(&fcc, pcs);
+ (*pcs->type->remap_color)(&fcc, pcs, &dev_color, pis,
+ pfs->dev, gs_color_select_texture);
+ /****** SHOULD ADD adjust ON ANY OUTSIDE EDGES ******/
#if 0
- {
- gx_path *ppath = gx_path_alloc(pis->memory, "Gt_fill");
+ {
+ gx_path *ppath = gx_path_alloc(pis->memory, "Gt_fill");
- gx_path_add_point(ppath, va->p.x, va->p.y);
- gx_path_add_line(ppath, vb->p.x, vb->p.y);
- gx_path_add_line(ppath, vc->p.x, vc->p.y);
- code = shade_fill_path((const shading_fill_state_t *)pfs,
- ppath, &dev_color);
- gx_path_free(ppath, "Gt_fill");
- }
+ gx_path_add_point(ppath, fp->va.p.x, fp->va.p.y);
+ gx_path_add_line(ppath, fp->vb.p.x, fp->vb.p.y);
+ gx_path_add_line(ppath, fp->vc.p.x, fp->vc.p.y);
+ code = shade_fill_path((const shading_fill_state_t *)pfs,
+ ppath, &dev_color);
+ gx_path_free(ppath, "Gt_fill");
+ }
#else
- code = (*dev_proc(pfs->dev, fill_triangle))
- (pfs->dev, va->p.x, va->p.y,
- vb->p.x - va->p.x, vb->p.y - va->p.y,
- vc->p.x - va->p.x, vc->p.y - va->p.y,
- &dev_color, pis->log_op);
+ code = (*dev_proc(pfs->dev, fill_triangle))
+ (pfs->dev, fp->va.p.x, fp->va.p.y,
+ fp->vb.p.x - fp->va.p.x, fp->vb.p.y - fp->va.p.y,
+ fp->vc.p.x - fp->va.p.x, fp->vc.p.y - fp->va.p.y,
+ &dev_color, pis->log_op);
#endif
- return code;
- }
- /*
- * Subdivide the triangle and recur. The only subdivision method
- * that doesn't seem to create anomalous shapes divides the
- * triangle in 4, using the midpoints of each side.
- */
-recur:
- {
- mesh_vertex_t vab, vac, vbc;
- int i;
- int code;
+ if (code < 0)
+ return code;
+ }
+ next:
+ if (fp == &pfs->frames[0])
+ return 0;
+ --fp;
+ continue;
+ nofill:
+ /*
+ * The colors don't converge. Does the region color more than
+ * a single pixel?
+ */
+ {
+ gs_fixed_rect region;
+
+ SET_MIN_MAX_3(region.p.x, region.q.x,
+ fp->va.p.x, fp->vb.p.x, fp->vc.p.x);
+ SET_MIN_MAX_3(region.p.y, region.q.y,
+ fp->va.p.y, fp->vb.p.y, fp->vc.p.y);
+ if (region.q.x - region.p.x <= fixed_1 &&
+ region.q.y - region.p.y <= fixed_1) {
+ /*
+ * More precisely, does the bounding box of the region,
+ * taking fill adjustment into account, span more than 1
+ * pixel center in either X or Y?
+ */
+ fixed ax = pis->fill_adjust.x;
+ int nx =
+ fixed2int_pixround(region.q.x + ax) -
+ fixed2int_pixround(region.p.x - ax);
+ fixed ay = pis->fill_adjust.y;
+ int ny =
+ fixed2int_pixround(region.q.y + ay) -
+ fixed2int_pixround(region.p.y - ay);
+
+ if (!(nx > 1 && ny != 0) || (ny > 1 && nx != 0))
+ goto fill;
+ }
+ }
+ /*
+ * Subdivide the triangle and recur. The only subdivision method
+ * that doesn't seem to create anomalous shapes divides the
+ * triangle in 4, using the midpoints of each side.
+ *
+ * If the original vertices are A, B, C, we fill the sub-triangles
+ * in the following order:
+ * (A, AB, AC) - fp[3]
+ * (AB, AC, BC) - fp[2]
+ * (AC, BC, C) - fp[1]
+ * (AB, B, BC) - fp[0]
+ */
+ {
+#define VAB fp[3].vb
+#define VAC fp[2].vb
+#define VBC fp[1].vb
+ int i;
#define MIDPOINT_FAST(a,b) arith_rshift_1((a) + (b) + 1)
- vab.p.x = MIDPOINT_FAST(va->p.x, vb->p.x);
- vab.p.y = MIDPOINT_FAST(va->p.y, vb->p.y);
- vac.p.x = MIDPOINT_FAST(va->p.x, vc->p.x);
- vac.p.y = MIDPOINT_FAST(va->p.y, vc->p.y);
- vbc.p.x = MIDPOINT_FAST(vb->p.x, vc->p.x);
- vbc.p.y = MIDPOINT_FAST(vb->p.y, vc->p.y);
+ VAB.p.x = MIDPOINT_FAST(fp->va.p.x, fp->vb.p.x);
+ VAB.p.y = MIDPOINT_FAST(fp->va.p.y, fp->vb.p.y);
+ VAC.p.x = MIDPOINT_FAST(fp->va.p.x, fp->vc.p.x);
+ VAC.p.y = MIDPOINT_FAST(fp->va.p.y, fp->vc.p.y);
+ VBC.p.x = MIDPOINT_FAST(fp->vb.p.x, fp->vc.p.x);
+ VBC.p.y = MIDPOINT_FAST(fp->vb.p.y, fp->vc.p.y);
#undef MIDPOINT_FAST
- for (i = 0; i < pfs->num_components; ++i) {
- float ta = va->cc[i], tb = vb->cc[i], tc = vc->cc[i];
+ for (i = 0; i < pfs->num_components; ++i) {
+ float ta = fp->va.cc[i], tb = fp->vb.cc[i], tc = fp->vc.cc[i];
- vab.cc[i] = (ta + tb) * 0.5;
- vac.cc[i] = (ta + tc) * 0.5;
- vbc.cc[i] = (tb + tc) * 0.5;
+ VAB.cc[i] = (ta + tb) * 0.5;
+ VAC.cc[i] = (ta + tc) * 0.5;
+ VBC.cc[i] = (tb + tc) * 0.5;
+ }
+ /* Fill in the rest of the triangles. */
+ fp[3].va = fp->va;
+ fp[3].vc = VAC;
+ fp[2].va = VAB;
+ fp[2].vc = VBC;
+ fp[1].va = VAC;
+ fp[1].vc = fp->vc;
+ fp->va = VAB;
+ fp->vc = VBC;
+ fp[3].check_clipping = fp[2].check_clipping =
+ fp[1].check_clipping = fp->check_clipping = check;
+#undef VAB
+#undef VAC
+#undef VBC
+ fp += 3;
}
- /* Do the "A" triangle. */
- code = mesh_fill_triangle(pfs, va, &vab, &vac, check);
- if (code < 0)
- return code;
- /* Do the central triangle. */
- code = mesh_fill_triangle(pfs, &vab, &vac, &vbc, check);
- if (code < 0)
- return code;
- /* Do the "C" triangle. */
- code = mesh_fill_triangle(pfs, &vac, &vbc, vc, check);
- if (code < 0)
- return code;
- /* Do the "B" triangle. */
- return mesh_fill_triangle(pfs, &vab, vb, &vbc, check);
}
}
@@ -183,10 +249,11 @@ Gt_next_vertex(const gs_shading_mesh_t * psh, shade_coord_stream_t * cs,
}
inline private int
-Gt_fill_triangle(const mesh_fill_state_t * pfs, const mesh_vertex_t * va,
+Gt_fill_triangle(mesh_fill_state_t * pfs, const mesh_vertex_t * va,
const mesh_vertex_t * vb, const mesh_vertex_t * vc)
{
- return mesh_fill_triangle(pfs, va, vb, vc, true);
+ mesh_init_fill_triangle(pfs, va, vb, vc, true);
+ return mesh_fill_triangle(pfs);
}
int
diff --git a/gs/src/gxshade4.h b/gs/src/gxshade4.h
index 9045951ae..a11db019f 100644
--- a/gs/src/gxshade4.h
+++ b/gs/src/gxshade4.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,13 @@
#ifndef gxshade4_INCLUDED
# define gxshade4_INCLUDED
+#define mesh_max_depth (16 * 3 + 1) /* each recursion adds 3 entries */
+typedef struct mesh_frame_s { /* recursion frame */
+ mesh_vertex_t va, vb, vc; /* current vertices */
+ bool check_clipping;
+} mesh_frame_t;
+/****** NEED GC DESCRIPTOR ******/
+
/*
* Define the fill state structure for triangle shadings. This is used
* both for the Gouraud triangle shading types and for the Coons and
@@ -33,10 +40,13 @@
#define mesh_fill_state_common\
shading_fill_state_common;\
const gs_shading_mesh_t *pshm;\
- gs_fixed_rect rect
+ gs_fixed_rect rect;\
+ int depth;\
+ mesh_frame_t frames[mesh_max_depth]
typedef struct mesh_fill_state_s {
mesh_fill_state_common;
} mesh_fill_state_t;
+/****** NEED GC DESCRIPTOR ******/
/* Initialize the fill state for triangle shading. */
void mesh_init_fill_state(P5(mesh_fill_state_t * pfs,
@@ -45,8 +55,10 @@ void mesh_init_fill_state(P5(mesh_fill_state_t * pfs,
gx_device * dev, gs_imager_state * pis));
/* Fill one triangle in a mesh. */
-int mesh_fill_triangle(P5(const mesh_fill_state_t * pfs,
- const mesh_vertex_t *va, const mesh_vertex_t *vb,
- const mesh_vertex_t *vc, bool check_clipping));
+void mesh_init_fill_triangle(P5(mesh_fill_state_t * pfs,
+ const mesh_vertex_t *va,
+ const mesh_vertex_t *vb,
+ const mesh_vertex_t *vc, bool check_clipping));
+int mesh_fill_triangle(P1(mesh_fill_state_t * pfs));
#endif /* gxshade4_INCLUDED */
diff --git a/gs/src/gxshade6.c b/gs/src/gxshade6.c
index 310f1e478..5d1a44e53 100644
--- a/gs/src/gxshade6.c
+++ b/gs/src/gxshade6.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -255,7 +255,7 @@ split2_xy(double out[8], const patch_curve_t * curve1,
}
private int
-patch_fill(const patch_fill_state_t * pfs, const patch_curve_t curve[4],
+patch_fill(patch_fill_state_t * pfs, const patch_curve_t curve[4],
const gs_fixed_point interior[4],
void (*transform) (P5(gs_fixed_point *, const patch_curve_t[4],
const gs_fixed_point[4], floatp, floatp)))
@@ -407,16 +407,18 @@ patch_fill(const patch_fill_state_t * pfs, const patch_curve_t curve[4],
(*transform)(&mv[1].p, curve, interior, u1, v0);
(*transform)(&mv[2].p, curve, interior, u1, v1);
(*transform)(&mv[3].p, curve, interior, u0, v1);
- memcpy(&mv[0].cc, cu[0].cc.paint.values, sizeof(mv[0].cc));
- memcpy(&mv[1].cc, cu[1].cc.paint.values, sizeof(mv[1].cc));
- memcpy(&mv[2].cc, cu[2].cc.paint.values, sizeof(mv[2].cc));
- memcpy(&mv[3].cc, cu[3].cc.paint.values, sizeof(mv[3].cc));
- code = mesh_fill_triangle((const mesh_fill_state_t *)pfs,
- &mv[0], &mv[1], &mv[2], check);
+ memcpy(mv[0].cc, cu[0].cc.paint.values, sizeof(mv[0].cc));
+ memcpy(mv[1].cc, cu[1].cc.paint.values, sizeof(mv[1].cc));
+ memcpy(mv[2].cc, cu[2].cc.paint.values, sizeof(mv[2].cc));
+ memcpy(mv[3].cc, cu[3].cc.paint.values, sizeof(mv[3].cc));
+ mesh_init_fill_triangle((mesh_fill_state_t *)pfs,
+ &mv[0], &mv[1], &mv[2], check);
+ code = mesh_fill_triangle((mesh_fill_state_t *)pfs);
if (code < 0)
return code;
- code = mesh_fill_triangle((const mesh_fill_state_t *)pfs,
- &mv[2], &mv[3], &mv[0], check);
+ mesh_init_fill_triangle((mesh_fill_state_t *)pfs,
+ &mv[2], &mv[3], &mv[0], check);
+ code = mesh_fill_triangle((mesh_fill_state_t *)pfs);
if (code < 0)
return code;
}
diff --git a/gs/src/gxstroke.c b/gs/src/gxstroke.c
index f244e9bd7..8746a89b6 100644
--- a/gs/src/gxstroke.c
+++ b/gs/src/gxstroke.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -62,20 +62,29 @@
/*
* Compute the amount by which to expand a stroked bounding box to account
- * for line width, caps and joins. Because of square caps and miter and
- * triangular joins, the maximum expansion on each side (in user space) is
+ * for line width, caps and joins. Return 0 if the result is exact, 1 if
+ * it may be conservative, or gs_error_limitcheck if the result is too
+ * large to fit in a gs_fixed_point.
+ *
+ * Because of square caps and miter and triangular joins, the maximum
+ * expansion on each side (in user space) is
* K * line_width/2
* where K is determined as follows:
* If the path is only a single line segment, K = 1;
* if triangular joins, K = 2;
* if miter joins, K = miter_limit;
* otherwise, K = 1.
- * If the amount is too large to fit in a gs_fixed_point, return
- * gs_error_limitcheck.
*
- * If the miter limit is very large, the foregoing computation will produce
- * a result that is much too large; we would like to tighten this up at
- * some point in the future.
+ * If the following conditions apply, K = 1 yields an exact result:
+ * - The CTM is of the form [X 0 0 Y] or [0 X Y 0].
+ * - Square or round caps are used, or all subpaths are closed.
+ * - All segments (including the implicit segment created by
+ * closepath) are vertical or horizontal lines.
+ *
+ * Note that these conditions are sufficient, but not necessary, to get an
+ * exact result. We choose this set of conditions because it is easy to
+ * check and covers many common cases. Clients that care always have the
+ * option of using strokepath to get an exact result.
*/
int
gx_stroke_path_expansion(const gs_imager_state * pis, const gx_path * ppath,
@@ -83,38 +92,64 @@ gx_stroke_path_expansion(const gs_imager_state * pis, const gx_path * ppath,
{
const subpath *psub = ppath->first_subpath;
const segment *pseg;
- double expand =
- (!gx_path_has_curves(ppath) && gx_path_subpath_count(ppath) <= 1 &&
- (psub == 0 || (pseg = psub->next) == 0 ||
- (pseg = pseg->next) == 0 || pseg->type == s_line_close) ? 1.0 :
- pis->line_params.join == gs_join_miter ?
- pis->line_params.miter_limit :
- pis->line_params.join == gs_join_triangle ? 2.0 : 1.0) *
- pis->line_params.half_width;
-
+ double cx = fabs(pis->ctm.xx) + fabs(pis->ctm.yx);
+ double cy = fabs(pis->ctm.xy) + fabs(pis->ctm.yy);
+ double expand = pis->line_params.half_width;
+ int result = 1;
+
+ /* Check for whether an exact result can be computed easily. */
+ if (is_fzero2(pis->ctm.xy, pis->ctm.yx) ||
+ is_fzero2(pis->ctm.xx, pis->ctm.yy)
+ ) {
+ bool must_be_closed =
+ !(pis->line_params.cap == gs_cap_square ||
+ pis->line_params.cap == gs_cap_round);
+ gs_fixed_point prev;
+
+ for (pseg = (const segment *)psub; pseg;
+ prev = pseg->pt, pseg = pseg->next
+ )
+ switch (pseg->type) {
+ case s_start:
+ if (((const subpath *)pseg)->curve_count ||
+ (must_be_closed && !((const subpath *)pseg)->is_closed)
+ )
+ goto not_exact;
+ break;
+ case s_line:
+ case s_line_close:
+ if (!(pseg->pt.x == prev.x || pseg->pt.y == prev.y))
+ goto not_exact;
+ break;
+ default: /* other/unknown segment type */
+ goto not_exact;
+ }
+ result = 0; /* exact result */
+ }
+not_exact:
+ if (result)
+ expand *=
+ (!gx_path_has_curves(ppath) && gx_path_subpath_count(ppath) <= 1 &&
+ (psub == 0 || (pseg = psub->next) == 0 ||
+ (pseg = pseg->next) == 0 || pseg->type == s_line_close) ? 1.0 :
+ pis->line_params.join == gs_join_miter ?
+ pis->line_params.miter_limit :
+ pis->line_params.join == gs_join_triangle ? 2.0 : 1.0);
+
/* Short-cut gs_bbox_transform. */
- float cx1 = pis->ctm.xx + pis->ctm.yx;
- float cy1 = pis->ctm.xy + pis->ctm.yy;
- float cx2 = pis->ctm.xx - pis->ctm.yx;
- float cy2 = pis->ctm.xy - pis->ctm.yy;
-
- if (cx1 < 0)
- cx1 = -cx1;
- if (cy1 < 0)
- cy1 = -cy1;
- if (cx2 < 0)
- cx2 = -cx2;
- if (cy2 < 0)
- cy2 = -cy2;
{
- float exx = expand * max(cx1, cx2);
- float exy = expand * max(cy1, cy2);
+ float exx = expand * cx;
+ float exy = expand * cy;
int code = set_float2fixed_vars(ppt->x, exx);
if (code < 0)
return code;
- return set_float2fixed_vars(ppt->y, exy);
+ code = set_float2fixed_vars(ppt->y, exy);
+ if (code < 0)
+ return code;
}
+
+ return result;
}
/*
@@ -205,8 +240,8 @@ gx_default_stroke_path(gx_device * dev, const gs_imager_state * pis,
*/
#define stroke_line_proc(proc)\
int proc(P10(gx_path *, int, pl_ptr, pl_ptr, const gx_device_color *,\
- gx_device *, const gs_imager_state *,\
- const gx_stroke_params *, const gs_fixed_rect *, int))
+ gx_device *, const gs_imager_state *,\
+ const gx_stroke_params *, const gs_fixed_rect *, int))
typedef stroke_line_proc((*stroke_line_proc_t));
private stroke_line_proc(stroke_add);
@@ -233,7 +268,7 @@ gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * pdev,
const gx_device_color * pdevc, const gx_clip_path * pcpath)
{
stroke_line_proc_t line_proc =
- (to_path == 0 ? stroke_fill : stroke_add);
+ (to_path == 0 ? stroke_fill : stroke_add);
gs_fixed_rect ibox, cbox;
gx_device_clip cdev;
gx_device *dev = pdev;
@@ -246,33 +281,32 @@ gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * pdev,
const gx_path *spath;
float xx = pis->ctm.xx, xy = pis->ctm.xy;
float yx = pis->ctm.yx, yy = pis->ctm.yy;
-
/*
- * We are dealing with a reflected coordinate system
- * if transform(1,0) is counter-clockwise from transform(0,1).
- * See the note in stroke_add for the algorithm.
+ * We are dealing with a reflected coordinate system
+ * if transform(1,0) is counter-clockwise from transform(0,1).
+ * See the note in stroke_add for the algorithm.
*/
int uniform;
bool reflected;
orientation orient =
- (
+ (
#ifdef OPTIMIZE_ORIENTATION
- is_fzero2(xy, yx) ?
- (uniform = (xx == yy ? 1 : xx == -yy ? -1 : 0),
- reflected = (uniform ? uniform < 0 : (xx < 0) != (yy < 0)),
- orient_portrait) :
- is_fzero2(xx, yy) ?
- (uniform = (xy == yx ? -1 : xy == -yx ? 1 : 0),
- reflected = (uniform ? uniform < 0 : (xy < 0) == (yx < 0)),
- orient_landscape) :
+ is_fzero2(xy, yx) ?
+ (uniform = (xx == yy ? 1 : xx == -yy ? -1 : 0),
+ reflected = (uniform ? uniform < 0 : (xx < 0) != (yy < 0)),
+ orient_portrait) :
+ is_fzero2(xx, yy) ?
+ (uniform = (xy == yx ? -1 : xy == -yx ? 1 : 0),
+ reflected = (uniform ? uniform < 0 : (xy < 0) == (yx < 0)),
+ orient_landscape) :
/* We should optimize uniform rotated coordinate systems */
/* here as well, but we don't. */
#endif
- (uniform = 0,
- reflected = xy * yx > xx * yy,
- orient_other));
+ (uniform = 0,
+ reflected = xy * yx > xx * yy,
+ orient_other));
segment_notes not_first =
- (!is_fzero(pis->line_params.dot_length) ? sn_not_first : sn_none);
+ (!is_fzero(pis->line_params.dot_length) ? sn_not_first : sn_none);
float line_width = pgs_lp->half_width; /* (*half* the line width) */
bool always_thin;
double line_width_and_scale, device_line_width_scale;
@@ -438,8 +472,8 @@ gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * pdev,
spath = ppath;
} else {
gx_path_init_local(&fpath, ppath->memory);
- if ((code = gx_path_add_flattened_accurate(ppath, &fpath,
- params->flatness, pis->accurate_curves)) < 0
+ if ((code = gx_path_add_flattened_for_stroke(ppath, &fpath,
+ params->flatness, pis)) < 0
)
return code;
spath = &fpath;
@@ -652,11 +686,11 @@ gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * pdev,
/* For some reason, the Borland compiler requires the cast */
/* in the following statement. */
pl_ptr lptr =
- (!is_closed ||
- (pgs_lp->join == gs_join_none &&
- !((pseg == 0 ? (const segment *)spath->first_subpath :
- pseg)->notes & not_first)) ?
- (pl_ptr) 0 : (pl_ptr) & pl_first);
+ (!is_closed ||
+ (pgs_lp->join == gs_join_none &&
+ !((pseg == 0 ? (const segment *)spath->first_subpath :
+ pseg)->notes & not_first)) ?
+ (pl_ptr) 0 : (pl_ptr) & pl_first);
code = (*line_proc) (to_path, index - 1, &pl_prev, lptr,
pdevc, dev, pis, params, &cbox, uniform);
@@ -926,17 +960,17 @@ const gx_device_color * pdevc, gx_device * dev, const gs_imager_state * pis,
++bevel;
/* Fill the bevel. */
code = (*dev_proc(dev, fill_triangle)) (dev,
- bevel[0].x, bevel[0].y,
- bevel[1].x - bevel[0].x, bevel[1].y - bevel[0].y,
- bevel[2].x - bevel[0].x, bevel[2].y - bevel[0].y,
- pdevc, pis->log_op);
- if (code < 0)
- return code;
+ bevel->x, bevel->y,
+ bevel[1].x - bevel->x, bevel[1].y - bevel->y,
+ bevel[2].x - bevel->x, bevel[2].y - bevel->y,
+ pdevc, pis->log_op);
+ if (code < 0)
+ return code;
}
}
/* Fill the body of the stroke. */
return (*dev_proc(dev, fill_parallelogram)) (dev,
- points[1].x, points[1].y,
+ points[1].x, points[1].y,
points[0].x - points[1].x,
points[0].y - points[1].y,
points[2].x - points[1].x,
@@ -956,7 +990,7 @@ const gx_device_color * pdevc, gx_device * dev, const gs_imager_state * pis,
/* Add a segment to the path. This handles all the complex cases. */
private int
-stroke_add(gx_path * ppath, int first, register pl_ptr plp, pl_ptr nplp,
+stroke_add(gx_path * ppath, int first, pl_ptr plp, pl_ptr nplp,
const gx_device_color * pdevc, gx_device * dev, const gs_imager_state * pis,
const gx_stroke_params * params, const gs_fixed_rect * ignore_pbbox,
int uniform)
@@ -1078,10 +1112,8 @@ line_join_points(const gx_line_params * pgs_lp, pl_ptr plp, pl_ptr nplp,
* that almost all CPUs provide!
*/
bool ccw =
- (double)(plp->width.x) * /* x1 */
- (nplp->width.y) > /* y2 */
- (double)(nplp->width.x) * /* x2 */
- (plp->width.y);
+ (double)(plp->width.x) /* x1 */ * (nplp->width.y) /* y2 */ >
+ (double)(nplp->width.x) /* x2 */ * (plp->width.y) /* y1 */;
p_ptr outp, np;
/* Initialize for a bevel join. */
@@ -1240,7 +1272,7 @@ line_join_points(const gx_line_params * pgs_lp, pl_ptr plp, pl_ptr nplp,
/* Compute the endpoints of the two caps of a segment. */
/* Only o.p, e.p, width, and cdelta have been set. */
private void
-compute_caps(register pl_ptr plp)
+compute_caps(pl_ptr plp)
{
fixed wx2 = plp->width.x;
fixed wy2 = plp->width.y;
@@ -1275,26 +1307,27 @@ compute_caps(register pl_ptr plp)
/* Add a round cap to a path. */
/* Assume the current point is the cap origin (endp->co). */
-/* Leave with the current point at [xe, ye] */
private int
add_round_cap(gx_path * ppath, const_ep_ptr endp)
{
- fixed xm = px + cdx;
- fixed ym = py + cdy;
- fixed xmm = px - cdx;
- fixed ymm = py - cdy;
int code;
- if ((code = gx_path_add_partial_arc(ppath, xm, ym,
- xo + cdx, yo + cdy, quarter_arc_fraction)) < 0 ||
- (code = gx_path_add_partial_arc(ppath, xe, ye,
- xe + cdx, ye + cdy, quarter_arc_fraction)) < 0 ||
- (code = gx_path_add_partial_arc(ppath, xmm, ymm,
- xe - cdx, ye - cdy, quarter_arc_fraction)) < 0 ||
- (code = gx_path_add_partial_arc(ppath, xo, yo,
- xo - cdx, yo - cdy, quarter_arc_fraction)) < 0 ||
- /* The final point must be (xe,ye) */
- (code = gx_path_add_line(ppath, xe, ye))
+ /*
+ * Per the Red Book, we draw a full circle, even though a semicircle
+ * is sufficient for the join.
+ */
+ if ((code = gx_path_add_partial_arc(ppath, px + cdx, py + cdy,
+ xo + cdx, yo + cdy,
+ quarter_arc_fraction)) < 0 ||
+ (code = gx_path_add_partial_arc(ppath, xe, ye, xe + cdx, ye + cdy,
+ quarter_arc_fraction)) < 0 ||
+ (code = gx_path_add_partial_arc(ppath, px - cdx, py - cdy,
+ xe - cdx, ye - cdy,
+ quarter_arc_fraction)) < 0 ||
+ (code = gx_path_add_partial_arc(ppath, xo, yo, xo - cdx, yo - cdy,
+ quarter_arc_fraction)) < 0 ||
+ /* The final point must be (xe,ye). */
+ (code = gx_path_add_line(ppath, xe, ye)) < 0
)
return code;
return 0;
diff --git a/gs/src/gxsync.h b/gs/src/gxsync.h
index 8a471e38d..766f383ea 100644
--- a/gs/src/gxsync.h
+++ b/gs/src/gxsync.h
@@ -22,7 +22,7 @@
/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */
#if !defined(gxsync_INCLUDED)
- #define gxsync_INCLUDED
+# define gxsync_INCLUDED
#include "gpsync.h"
#include "gsmemory.h"
@@ -40,16 +40,16 @@ typedef struct gx_semaphore_s {
} gx_semaphore_t;
gx_semaphore_t * /* returns a new semaphore, 0 if error */
- gx_semaphore_alloc(P1(
- gs_memory_t * memory /* memory allocator to use */
- ));
+ gx_semaphore_alloc(P1(
+ gs_memory_t * memory /* memory allocator to use */
+ ));
void
- gx_semaphore_free(P1(
- gx_semaphore_t * sema /* semaphore to delete */
- ));
+ gx_semaphore_free(P1(
+ gx_semaphore_t * sema /* semaphore to delete */
+ ));
- #define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native)
- #define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native)
+#define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native)
+#define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native)
/* ----- Monitor interface ----- */
@@ -61,15 +61,15 @@ typedef struct gx_monitor_s {
} gx_monitor_t;
gx_monitor_t * /* returns a new monitor, 0 if error */
- gx_monitor_alloc(P1(
- gs_memory_t * memory /* memory allocator to use */
- ));
+ gx_monitor_alloc(P1(
+ gs_memory_t * memory /* memory allocator to use */
+ ));
void
- gx_monitor_free(P1(
- gx_monitor_t * mon /* monitor to delete */
- ));
+ gx_monitor_free(P1(
+ gx_monitor_t * mon /* monitor to delete */
+ ));
- #define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native)
- #define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native)
+#define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native)
+#define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native)
#endif /* !defined(gxsync_INCLUDED) */
diff --git a/gs/src/gxtext.h b/gs/src/gxtext.h
index 1e6a0a317..997dd317e 100644
--- a/gs/src/gxtext.h
+++ b/gs/src/gxtext.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,7 +24,56 @@
#include "gstext.h"
-/* EVERYTHING IN THIS FILE IS SUBJECT TO CHANGE WITHOUT NOTICE. */
+/* Define the abstract type for the object procedures. */
+typedef struct gs_text_enum_procs_s gs_text_enum_procs_t;
+
+/*
+ * Define values returned by text_process to the client.
+ */
+typedef struct gs_text_returned_s {
+ gs_char current_char; /* INTERVENE */
+ gs_glyph current_glyph; /* INTERVENE */
+ gs_point current_width; /* INTERVENE & RETURN_WIDTH */
+ gs_point total_width; /* RETURN_WIDTH */
+} gs_text_returned_t;
+/*
+ * Define the common part of the structure that tracks the state of text
+ * processing. All implementations of text_begin must allocate one of these
+ * using rc_alloc_struct_1; implementations may subclass and extend it.
+ * Note that it includes a copy of the text parameters.
+ */
+#define gs_text_enum_common\
+ /*\
+ * The following copies of the arguments of text_begin are set at\
+ * initialization, and const thereafter.\
+ */\
+ gs_text_params_t text; /* must be first for subclassing */\
+ gx_device *dev;\
+ gs_imager_state *pis;\
+ const gs_font *orig_font;\
+ gx_path *path; /* unless DO_NONE & !RETURN_WIDTH */\
+ const gx_device_color *pdcolor; /* if DO_DRAW */\
+ const gx_clip_path *pcpath; /* if DO_DRAW */\
+ gs_memory_t *memory;\
+ /* The following additional members are set at initialization. */\
+ const gs_text_enum_procs_t *procs;\
+ /* The following change dynamically. */\
+ rc_header rc;\
+ const gs_font *current_font; /* changes for composite fonts */\
+ gs_log2_scale_point scale; /* for oversampling */\
+ uint index; /* index within string */\
+ /* The following are used to return information to the client. */\
+ gs_text_returned_t returned
+/* The typedef is in gstext.h. */
+/*typedef*/ struct gs_text_enum_s {
+ gs_text_enum_common;
+} /*gs_text_enum_t*/;
+
+#define st_gs_text_enum_max_ptrs st_gs_text_params_max_ptrs
+/*extern_st(st_gs_text_enum); */
+#define public_st_gs_text_enum() /* in gstext.c */\
+ gs_public_st_composite(st_gs_text_enum, gs_text_enum_t, "gs_text_enum_t",\
+ text_enum_enum_ptrs, text_enum_reloc_ptrs)
/*
* Define the control parameter for setting text metrics.
@@ -36,7 +85,7 @@ typedef enum {
} gs_text_cache_control_t;
/*
- * Define the procedures associated with text display.
+ * Define the procedures associated with text processing.
*/
struct gs_text_enum_procs_s {
@@ -51,8 +100,8 @@ struct gs_text_enum_procs_s {
text_enum_proc_process((*process));
/*
- * Set the character width and optionally bounding box,
- * and enable caching.
+ * Set the character width and optionally the bounding box,
+ * and optionally enable caching.
*/
#define text_enum_proc_set_cache(proc)\
@@ -63,53 +112,4 @@ struct gs_text_enum_procs_s {
};
-/* Abstract types */
-#ifndef gs_imager_state_DEFINED
-# define gs_imager_state_DEFINED
-typedef struct gs_imager_state_s gs_imager_state;
-
-#endif
-#ifndef gx_device_color_DEFINED
-# define gx_device_color_DEFINED
-typedef struct gx_device_color_s gx_device_color;
-
-#endif
-#ifndef gs_font_DEFINED
-# define gs_font_DEFINED
-typedef struct gs_font_s gs_font;
-
-#endif
-#ifndef gx_path_DEFINED
-# define gx_path_DEFINED
-typedef struct gx_path_s gx_path;
-
-#endif
-#ifndef gx_clip_path_DEFINED
-# define gx_clip_path_DEFINED
-typedef struct gx_clip_path_s gx_clip_path;
-
-#endif
-
-/*
- * Define the driver procedure for text.
- */
-#define dev_t_proc_text_begin(proc, dev_t)\
- int proc(P9(dev_t *dev,\
- gs_imager_state *pis,\
- const gs_text_params_t *text,\
- const gs_font *font,\
- gx_path *path, /* unless DO_NONE & !RETURN_WIDTH */\
- const gx_device_color *pdcolor, /* DO_DRAW */\
- const gx_clip_path *pcpath, /* DO_DRAW */\
- gs_memory_t *memory,\
- gs_text_enum_t **ppenum))
-#define dev_proc_text_begin(proc)\
- dev_t_proc_text_begin(proc, gx_device)
-
-/*
- * Begin processing text. This calls the device procedure, and also
- * initializes the common parts of the enumerator.
- */
-dev_proc_text_begin(gx_device_text_begin);
-
#endif /* gxtext_INCLUDED */
diff --git a/gs/src/gxtype1.c b/gs/src/gxtype1.c
index c08069190..6c1d61ac9 100644
--- a/gs/src/gxtype1.c
+++ b/gs/src/gxtype1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -93,15 +93,14 @@ public_st_gs_type1_state();
private
ENUM_PTRS_BEGIN(gs_type1_state_enum_ptrs)
{
- if (index < pcis->ips_count + 3) {
+ if (index < pcis->ips_count + 4) {
ENUM_RETURN_CONST_STRING_PTR(gs_type1_state,
- ipstack[index - 3].char_string);
+ ipstack[index - 4].char_string);
}
return 0;
}
-ENUM_PTR(0, gs_type1_state, pfont);
-ENUM_PTR(1, gs_type1_state, pis);
-ENUM_PTR(2, gs_type1_state, path);
+ENUM_PTR3(0, gs_type1_state, pfont, pis, path);
+ENUM_PTR(3, gs_type1_state, callback_data);
ENUM_PTRS_END
private RELOC_PTRS_BEGIN(gs_type1_state_reloc_ptrs)
{
@@ -110,6 +109,7 @@ private RELOC_PTRS_BEGIN(gs_type1_state_reloc_ptrs)
RELOC_PTR(gs_type1_state, pfont);
RELOC_PTR(gs_type1_state, pis);
RELOC_PTR(gs_type1_state, path);
+ RELOC_PTR(gs_type1_state, callback_data);
for (i = 0; i < pcis->ips_count; i++) {
ip_state *ipsp = &pcis->ipstack[i];
int diff = ipsp->ip - ipsp->char_string.data;
@@ -120,35 +120,6 @@ private RELOC_PTRS_BEGIN(gs_type1_state_reloc_ptrs)
} RELOC_PTRS_END
#undef pcis
-/* ------ Interpreter entry point ------ */
-
-private int
-gs_no_charstring_interpret(gs_type1_state * pcis, const gs_const_string * str,
- int *pindex)
-{
- return_error(gs_error_rangecheck);
-}
-int (*gs_charstring_interpreter[3])
- (P3(gs_type1_state * pcis, const gs_const_string * str, int *pindex)) = {
- gs_no_charstring_interpret,
- gs_no_charstring_interpret,
- gs_no_charstring_interpret
-};
-
-/*
- * Continue interpreting a Type 1 charstring. If str != 0, it is taken as
- * the byte string to interpret. Return 0 on successful completion, <0 on
- * error, or >0 when client intervention is required (or allowed). The int*
- * argument is where the othersubr # is stored for callothersubr.
- */
-int
-gs_type1_interpret(gs_type1_state * pcis, const gs_const_string * str,
- int *pindex)
-{
- return (*gs_charstring_interpreter[pcis->pfont->data.CharstringType])
- (pcis, str, pindex);
-}
-
/* ------ Interpreter services ------ */
#define s (*ps)
@@ -179,6 +150,7 @@ gs_type1_interp_init(register gs_type1_state * pcis, gs_imager_state * pis,
pcis->pfont = pfont;
pcis->pis = pis;
pcis->path = ppath;
+ pcis->callback_data = pfont; /* default callback data */
/*
* charpath_flag controls coordinate rounding, hinting, and
* flatness enhancement. If we allow it to be set to true,
@@ -205,6 +177,15 @@ gs_type1_interp_init(register gs_type1_state * pcis, gs_imager_state * pis,
return 0;
}
+
+/* Set the push/pop callback data. */
+void
+gs_type1_set_callback_data(gs_type1_state *pcis, void *callback_data)
+{
+ pcis->callback_data = callback_data;
+}
+
+
/* Preset the left side bearing and/or width. */
void
gs_type1_set_lsb(gs_type1_state * pcis, const gs_point * psbpt)
@@ -220,6 +201,7 @@ gs_type1_set_width(gs_type1_state * pcis, const gs_point * pwpt)
pcis->width.y = float2fixed(pwpt->y);
pcis->width_set = true;
}
+
/* Finish initializing the interpreter if we are actually rasterizing */
/* the character, as opposed to just computing the side bearing and width. */
void
@@ -273,14 +255,14 @@ gs_type1_finish_init(gs_type1_state * pcis, gs_op1_state * ps)
{
float cxx = fabs(pis->ctm.xx), cyy = fabs(pis->ctm.yy);
- if (cyy < cxx)
+ if (is_fzero(cxx) || (cyy < cxx && !is_fzero(cyy)))
cxx = cyy;
if (!is_xxyy(&pis->ctm)) {
float cxy = fabs(pis->ctm.xy), cyx = fabs(pis->ctm.yx);
- if (cxy < cxx)
+ if (is_fzero(cxx) || (cxy < cxx && !is_fzero(cxy)))
cxx = cxy;
- if (cyx < cxx)
+ if (is_fzero(cxx) || (cyx < cxx && !is_fzero(cyx)))
cxx = cyx;
}
/* Don't let the flatness be worse than the default. */
diff --git a/gs/src/gxtype1.h b/gs/src/gxtype1.h
index f29b64d92..00723e6de 100644
--- a/gs/src/gxtype1.h
+++ b/gs/src/gxtype1.h
@@ -149,13 +149,11 @@ typedef struct {
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
-
#endif
#ifndef segment_DEFINED
# define segment_DEFINED
typedef struct segment_s segment;
-
#endif
/* This is the full state of the Type 1 interpreter. */
@@ -168,6 +166,7 @@ struct gs_type1_state_s {
gx_path *path; /* path for appending */
bool charpath_flag; /* false if show, true if charpath */
int paint_type; /* 0/3 for fill, 1/2 for stroke */
+ void *callback_data;
fixed_coeff fc; /* cached fixed coefficients */
float flatness; /* flatness for character curves */
point_scale scale; /* oversampling scale */
@@ -229,16 +228,12 @@ struct gs_type1_state_s {
};
extern_st(st_gs_type1_state);
-#define public_st_gs_type1_state() /* in gstype1.c */\
+#define public_st_gs_type1_state() /* in gxtype1.c */\
gs_public_st_composite(st_gs_type1_state, gs_type1_state, "gs_type1_state",\
gs_type1_state_enum_ptrs, gs_type1_state_reloc_ptrs)
/* ------ Shared Type 1 / Type 2 interpreter fragments ------ */
-/* Declare the array of charstring interpreters, indexed by CharstringType. */
-extern int (*gs_charstring_interpreter[3])
- (P3(gs_type1_state * pcis, const gs_const_string * str, int *pindex));
-
/* Copy the operand stack out of the saved state. */
#define init_cstack(cstack, csp, pcis)\
BEGIN\
diff --git a/gs/src/gxxfont.h b/gs/src/gxxfont.h
index b2fc100d9..27f2e0f3f 100644
--- a/gs/src/gxxfont.h
+++ b/gs/src/gxxfont.h
@@ -165,8 +165,8 @@ struct gx_xfont_procs_s {
gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)
/*
* We probably don't ever want xfont descriptors to be public....
- #define gs_public_st_dev_ptrs1(stname, stype, sname, penum, preloc, de)\
- gs__st_dev_ptrs1(public_st, stname, stype, sname, penum, preloc, de)
+#define gs_public_st_dev_ptrs1(stname, stype, sname, penum, preloc, de)\
+ gs__st_dev_ptrs1(public_st, stname, stype, sname, penum, preloc, de)
*/
#define gs_private_st_dev_ptrs1(stname, stype, sname, penum, preloc, de)\
gs__st_dev_ptrs1(private_st, stname, stype, sname, penum, preloc, de)
diff --git a/gs/src/gzcpath.h b/gs/src/gzcpath.h
index 94f057b43..60577ff35 100644
--- a/gs/src/gzcpath.h
+++ b/gs/src/gzcpath.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -68,8 +68,6 @@ extern_st(st_clip_path);
/* Inline accessors. */
#define gx_cpath_is_shared(pcpath)\
((pcpath)->rect_list->rc.ref_count > 1)
-#define gx_cpath_list(pcpath)\
- (&(pcpath)->rect_list->list)
/* Define the structure for enumerating a clipping list. */
typedef enum {
diff --git a/gs/src/gzline.h b/gs/src/gzline.h
index ab95cf071..9333febdc 100644
--- a/gs/src/gzline.h
+++ b/gs/src/gzline.h
@@ -24,9 +24,13 @@
#include "gxline.h"
-#define private_st_line_params() /* in gsstate.c */\
- gs_private_st_ptrs1(st_line_params, gx_line_params, "line_params",\
- line_params_enum_ptrs, line_params_reloc_ptrs, dash.pattern)
+/*
+ * The GC procedures are complex because we must not attempt to follow
+ * the pattern pointer iff the pattern size is 0.
+ */
+#define private_st_line_params() /* in gsistate.c */\
+ gs_private_st_complex_only(st_line_params, gx_line_params, "line_params",\
+ 0, line_params_enum_ptrs, line_params_reloc_ptrs, 0)
#define st_line_params_num_ptrs 1
/* Internal accessor for line parameters in graphics state */
diff --git a/gs/src/gzpath.h b/gs/src/gzpath.h
index f210fe2a2..7ac54bf2b 100644
--- a/gs/src/gzpath.h
+++ b/gs/src/gzpath.h
@@ -25,7 +25,7 @@
#include "gxpath.h"
#include "gsmatrix.h"
#include "gsrefct.h"
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
/*
* Paths are represented as a linked list of line or curve segments,
diff --git a/gs/src/gzstate.h b/gs/src/gzstate.h
index 423f3ff6c..30a7474fc 100644
--- a/gs/src/gzstate.h
+++ b/gs/src/gzstate.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,7 @@
# define gzstate_INCLUDED
#include "gscpm.h"
+#include "gscspace.h"
#include "gsrefct.h"
#include "gxdcolor.h"
#include "gxistate.h"
@@ -33,27 +34,26 @@
#ifndef gx_path_DEFINED
# define gx_path_DEFINED
typedef struct gx_path_s gx_path;
-
#endif
#ifndef gx_clip_path_DEFINED
# define gx_clip_path_DEFINED
typedef struct gx_clip_path_s gx_clip_path;
-
+#endif
+#ifndef gx_clip_stack_DEFINED
+# define gx_clip_stack_DEFINED
+typedef struct gx_clip_stack_s gx_clip_stack_t;
#endif
#ifndef gs_color_space_DEFINED
# define gs_color_space_DEFINED
typedef struct gs_color_space_s gs_color_space;
-
#endif
#ifndef gs_client_color_DEFINED
# define gs_client_color_DEFINED
typedef struct gs_client_color_s gs_client_color;
-
#endif
#ifndef gs_font_DEFINED
# define gs_font_DEFINED
typedef struct gs_font_s gs_font;
-
#endif
/* Graphics state structure. */
@@ -68,26 +68,30 @@ struct gs_state_s {
bool ctm_inverse_valid; /* true if ctm_inverse = ctm^-1 */
gs_matrix ctm_default;
bool ctm_default_set; /* if true, use ctm_default; */
- /* if false, ask device */
+ /* if false, ask device */
/* Paths: */
gx_path *path;
gx_clip_path *clip_path;
+ gx_clip_stack_t *clip_stack; /* (LanguageLevel 3 only) */
gx_clip_path *view_clip; /* (may be 0, or have rule = 0) */
bool clamp_coordinates; /* if true, clamp out-of-range */
- /* coordinates; if false, */
- /* report a limitcheck */
+ /* coordinates; if false, */
+ /* report a limitcheck */
/* Effective clip path cache */
gs_id effective_clip_id; /* (key) clip path id */
gs_id effective_view_clip_id; /* (key) view clip path id */
gx_clip_path *effective_clip_path; /* (value) effective clip path, */
- /* possibly = clip_path or view_clip */
+ /* possibly = clip_path or view_clip */
bool effective_clip_shared; /* true iff e.c.p. = c.p. or v.c. */
/* Color (device-independent): */
- gs_color_space *color_space;
+ gs_color_space_index /* before substitution */
+ orig_cspace_index, orig_base_cspace_index;
+ gs_color_space *color_space; /* after substitution */
+ gx_device_color_spaces_t device_color_spaces; /* substituted spaces */
gs_client_color *ccolor;
/* Color caches: */
@@ -101,14 +105,10 @@ struct gs_state_s {
gs_matrix_fixed char_tm; /* font matrix * ctm */
#define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm
bool char_tm_valid; /* true if char_tm is valid */
- byte in_cachedevice; /* 0 if not in setcachedevice, */
- /* 1 if in setcachedevice but not */
- /* actually caching, */
- /* 2 if in setcachedevice and */
- /* actually caching */
+ gs_in_cache_device_t in_cachedevice; /* (see gschar.h) */
gs_char_path_mode in_charpath; /* (see gscpm.h) */
gs_state *show_gstate; /* gstate when show was invoked */
- /* (so charpath can append to path) */
+ /* (so charpath can append to path) */
/* Other stuff: */
@@ -119,7 +119,7 @@ struct gs_state_s {
/* Client data: */
- void *client_data;
+ /*void *client_data;*/ /* in imager state */
#define gs_state_client_data(pgs) ((pgs)->client_data)
gs_state_client_procs client_procs;
};
diff --git a/gs/src/ialloc.c b/gs/src/ialloc.c
index e62d7d771..6063967d5 100644
--- a/gs/src/ialloc.c
+++ b/gs/src/ialloc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,9 +22,9 @@
#include "memory_.h"
#include "errors.h"
#include "gsstruct.h"
-#include "gxarith.h" /* for small_exact_log2 */
#include "iref.h" /* must precede iastate.h */
#include "iastate.h"
+#include "igc.h" /* for gs_gc_reclaim */
#include "ipacked.h"
#include "iutil.h"
#include "ivmspace.h"
@@ -33,33 +33,34 @@
/*
* Define global and local instances.
*/
+public_st_gs_dual_memory();
gs_dual_memory_t gs_imemory;
/* Initialize the allocator */
void
-ialloc_init(gs_raw_memory_t * rmem, uint chunk_size, bool level2)
+ialloc_init(gs_dual_memory_t *dmem, gs_raw_memory_t * rmem, uint chunk_size,
+ bool level2)
{
gs_ref_memory_t *ilmem = ialloc_alloc_state(rmem, chunk_size);
gs_ref_memory_t *igmem =
- (level2 ?
- ialloc_alloc_state(rmem, chunk_size) :
- ilmem);
+ (level2 ? ialloc_alloc_state(rmem, chunk_size) : ilmem);
gs_ref_memory_t *ismem = ialloc_alloc_state(rmem, chunk_size);
int i;
- for (i = 0; i < countof(gs_imemory.spaces.indexed); i++)
- gs_imemory.spaces.indexed[i] = 0;
- gs_imemory.space_local = ilmem;
- gs_imemory.space_global = igmem;
- gs_imemory.space_system = ismem;
- gs_imemory.reclaim = 0;
+ for (i = 0; i < countof(dmem->spaces_indexed); i++)
+ dmem->spaces_indexed[i] = 0;
+ dmem->space_local = ilmem;
+ dmem->space_global = igmem;
+ dmem->space_system = ismem;
+ dmem->spaces.vm_reclaim = gs_gc_reclaim; /* real GC */
+ dmem->reclaim = 0; /* no interpreter GC yet */
+ dmem->reclaim_data = 0;
/* Level 1 systems have only local VM. */
igmem->space = avm_global;
ilmem->space = avm_local; /* overrides if ilmem == igmem */
igmem->global = ilmem->global = igmem;
-
ismem->space = avm_system;
- ialloc_set_space(&gs_imemory, avm_global);
+ ialloc_set_space(dmem, avm_global);
}
/* ================ Local/global VM ================ */
@@ -75,7 +76,7 @@ imemory_space(gs_ref_memory_t * iimem)
void
ialloc_set_space(gs_dual_memory_t * dmem, uint space)
{
- gs_ref_memory_t *mem = dmem->spaces.indexed[space >> r_space_shift];
+ gs_ref_memory_t *mem = dmem->spaces_indexed[space >> r_space_shift];
dmem->current = mem;
dmem->current_space = mem->space;
diff --git a/gs/src/ialloc.h b/gs/src/ialloc.h
index 02b743b5c..a42e8da36 100644
--- a/gs/src/ialloc.h
+++ b/gs/src/ialloc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -52,17 +52,19 @@ extern gs_dual_memory_t gs_imemory;
gs_alloc_struct_array(imemory, nelts, typ, pstype, cname)
#define ifree_object(data, cname)\
gs_free_object(imemory, data, cname)
+#define ifree_const_object(data, cname)\
+ gs_free_const_object(imemory, data, cname)
#define ialloc_string(nbytes, cname)\
gs_alloc_string(imemory, nbytes, cname)
+#define iresize_string(data, oldn, newn, cname)\
+ gs_resize_string(imemory, data, oldn, newn, cname)
#define ifree_string(data, nbytes, cname)\
gs_free_string(imemory, data, nbytes, cname)
+#define ifree_const_string(data, nbytes, cname)\
+ gs_free_const_string(imemory, data, nbytes, cname)
/* Initialize the interpreter's allocator. */
-void ialloc_init(P3(gs_raw_memory_t *, uint, bool));
-
-/* Resize a string. */
-#define iresize_string(data, oldn, newn, cname)\
- gs_resize_string(imemory, data, oldn, newn, cname)
+void ialloc_init(P4(gs_dual_memory_t *, gs_raw_memory_t *, uint, bool));
/* ------ Internal routines ------ */
diff --git a/gs/src/ibnum.c b/gs/src/ibnum.c
index 0ac388e40..df48606f2 100644
--- a/gs/src/ibnum.c
+++ b/gs/src/ibnum.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -179,11 +179,11 @@ sdecodelong(const byte * p, int format)
((long)d << 24) + ((long)c << 16) + (b << 8) + a :
((long)a << 24) + ((long)b << 16) + (c << 8) + d);
- /*
- * The following is only needed if sizeof(long) > 4, but it does
- * no harm if sizeof(long) == 4.
- */
- return (v ^ 0x80000000L) - 0x80000000L;
+#if arch_sizeof_long > 4
+ /* Propagate bit 31 as the sign. */
+ v = (v ^ 0x80000000L) - 0x80000000L;
+#endif
+ return v;
}
/* Decode a float. We assume that native floats occupy 32 bits. */
diff --git a/gs/src/iccfont.c b/gs/src/iccfont.c
index f4a225d55..62453f8bb 100644
--- a/gs/src/iccfont.c
+++ b/gs/src/iccfont.c
@@ -318,7 +318,7 @@ private int
zgetccfont(register os_ptr op)
{
int code;
- ccfont_fproc **fprocs;
+ const ccfont_fproc *fprocs;
int nfonts;
int index;
diff --git a/gs/src/icfontab.c b/gs/src/icfontab.c
index bcfc711a1..b2ff878f8 100644
--- a/gs/src/icfontab.c
+++ b/gs/src/icfontab.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,21 +20,22 @@
/* Table of compiled fonts */
#include "ccfont.h"
-/* This is compiled separately and linked with the fonts themselves, */
-/* in a shared library when applicable. */
+/*
+ * This is compiled separately and linked with the fonts themselves,
+ * in a shared library when applicable.
+ */
#undef font_
-#define font_(fname, fproc, zfproc) extern ccfont_fproc fproc;
+#define font_(fname, fproc, zfproc) extern ccfont_proc(fproc);
#ifndef GCONFIGF_H
# include "gconfigf.h"
#else
# include GCONFIGF_H
#endif
-private ccfont_fproc *fprocs[] =
-{
+private const ccfont_fproc fprocs[] = {
#undef font_
-#define font_(fname, fproc, zfproc) &fproc, /* fname, zfproc are not needed */
+#define font_(fname, fproc, zfproc) fproc, /* fname, zfproc are not needed */
#ifndef GCONFIGF_H
# include "gconfigf.h"
#else
@@ -44,7 +45,7 @@ private ccfont_fproc *fprocs[] =
};
int
-ccfont_fprocs(int *pnum_fprocs, ccfont_fproc *** pfprocs)
+ccfont_fprocs(int *pnum_fprocs, const ccfont_fproc ** pfprocs)
{
*pnum_fprocs = countof(fprocs) - 1;
*pfprocs = &fprocs[0];
diff --git a/gs/src/ichar.h b/gs/src/ichar.h
index 22c95f3a7..bf389c07a 100644
--- a/gs/src/ichar.h
+++ b/gs/src/ichar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -55,12 +55,13 @@
#define seproc eseproc(esp)
/* Procedures exported by zchar.c for zchar1.c, zchar2.c, and/or zcharcid.c. */
-gs_show_enum *op_show_find(P0());
-int op_show_setup(P2(os_ptr, gs_show_enum **));
-int op_show_enum_setup(P2(os_ptr, gs_show_enum **));
-void op_show_finish_setup(P3(gs_show_enum *, int, op_proc_p));
-int op_show_continue(P1(os_ptr));
-int op_show_continue_dispatch(P2(os_ptr, int));
-int op_show_free(P1(int));
+gs_show_enum *op_show_find(P1(i_ctx_t *));
+int op_show_setup(P3(i_ctx_t *, os_ptr, gs_show_enum **));
+int op_show_enum_setup(P2(i_ctx_t *, gs_show_enum **));
+void op_show_finish_setup(P4(i_ctx_t *, gs_show_enum *, int, op_proc_t));
+int op_show_continue(P1(i_ctx_t *));
+int op_show_continue_pop(P2(i_ctx_t *, int));
+int op_show_continue_dispatch(P3(i_ctx_t *, int, int));
+int op_show_free(P2(i_ctx_t *, int));
#endif /* ichar_INCLUDED */
diff --git a/gs/src/ichar1.h b/gs/src/ichar1.h
new file mode 100644
index 000000000..8b580e203
--- /dev/null
+++ b/gs/src/ichar1.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Type 1 / Type 2 character rendering operator entry */
+
+#ifndef ichar1_INCLUDED
+# define ichar1_INCLUDED
+
+/* Render a Type 1 or Type 2 outline. */
+/* This is the entire implementation of the .type1/2execchar operators. */
+int charstring_execchar(P2(i_ctx_t *i_ctx_p, int font_type_mask));
+
+#endif /* ichar1_INCLUDED */
diff --git a/gs/src/icharout.h b/gs/src/icharout.h
index 780e474da..1688c6f6f 100644
--- a/gs/src/icharout.h
+++ b/gs/src/icharout.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,7 +23,7 @@
# define icharout_INCLUDED
/* Execute an outline defined by a PostScript procedure. */
-int zchar_exec_char_proc(P1(os_ptr));
+int zchar_exec_char_proc(P1(i_ctx_t *));
/*
* Get the metrics for a character from the Metrics dictionary of a base
@@ -44,10 +44,10 @@ int /*metrics_present*/
* o_push_estack if we had to call a CDevProc, or if we are skipping the
* rendering process (only getting the metrics).
*/
-int zchar_set_cache(P8(os_ptr op, const gs_font_base * pbfont,
+int zchar_set_cache(P8(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
const ref * pcnref, const double psb[2],
const double pwidth[2], const gs_rect * pbbox,
- int (*cont_fill) (P1(os_ptr)),
- int (*cont_stroke) (P1(os_ptr))));
+ int (*cont_fill) (P1(i_ctx_t *)),
+ int (*cont_stroke) (P1(i_ctx_t *))));
#endif /* icharout_INCLUDED */
diff --git a/gs/src/icie.h b/gs/src/icie.h
index 73b0ff6ab..1f61b3d06 100644
--- a/gs/src/icie.h
+++ b/gs/src/icie.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,14 +35,12 @@ int dict_ranges_param(P4(const ref * pdref, const char *kstr, int count,
gs_range * prange));
/* Get 3 ranges from a dictionary. */
-#define dict_range3_param(pdref, kstr, prange3)\
- dict_ranges_param(pdref, kstr, 3, (prange3)->ranges)
+int dict_range3_param(P3(const ref *pdref, const char *kstr,
+ gs_range3 *prange3));
/* Get a 3x3 matrix parameter from a dictionary. */
-#define dict_matrix3_param(op, kstr, pmat)\
- dict_float_array_param(op, kstr, 9, (float *)pmat,\
- (const float *)&Matrix3_default)
-#define matrix3_ok 9
+int dict_matrix3_param(P3(const ref *pdref, const char *kstr,
+ gs_matrix3 *pmat3));
/* Get an array of procedures from a dictionary. */
/* We know count <= countof(empty_procs). */
@@ -50,8 +48,7 @@ int dict_proc_array_param(P4(const ref * pdict, const char *kstr,
uint count, ref * pparray));
/* Get 3 procedures from a dictionary. */
-#define dict_proc3_param(op, kstr, pparray)\
- dict_proc_array_param(op, kstr, 3, pparray)
+int dict_proc3_param(P3(const ref *pdref, const char *kstr, ref proc3[3]));
/* Get WhitePoint and BlackPoint values. */
int cie_points_param(P2(const ref * pdref, gs_cie_wb * pwb));
@@ -64,27 +61,30 @@ int cie_table_param(P3(const ref * ptable, gx_color_lookup_table * pclt,
/* ------ Internal routines ------ */
-int cie_cache_push_finish(P3(int (*finish_proc) (P1(os_ptr)),
+int cie_cache_push_finish(P4(i_ctx_t *i_ctx_p, op_proc_t finish_proc,
gs_ref_memory_t * imem, void *data));
-int cie_prepare_cache(P6(const gs_range * domain, const ref * proc,
- cie_cache_floats * pcache, void *container,
- gs_ref_memory_t * imem, client_name_t cname));
-int cie_prepare_caches_4(P9(const gs_range * domains, const ref * procs,
- cie_cache_floats * pc0,
- cie_cache_floats * pc1,
- cie_cache_floats * pc2,
- cie_cache_floats * pc3 /* may be 0 */,
- void *container,
- gs_ref_memory_t * imem, client_name_t cname));
-#define cie_prepare_cache3(d3,p3,c3,pcie,imem,cname)\
- cie_prepare_caches_4((d3)->ranges, p3,\
+int cie_prepare_cache(P7(i_ctx_t *i_ctx_p, const gs_range * domain,
+ const ref * proc, cie_cache_floats * pcache,
+ void *container, gs_ref_memory_t * imem,
+ client_name_t cname));
+int cie_prepare_caches_4(P10(i_ctx_t *i_ctx_p, const gs_range * domains,
+ const ref * procs,
+ cie_cache_floats * pc0,
+ cie_cache_floats * pc1,
+ cie_cache_floats * pc2,
+ cie_cache_floats * pc3 /* may be 0 */,
+ void *container,
+ gs_ref_memory_t * imem, client_name_t cname));
+#define cie_prepare_cache3(p,d3,p3,c3,pcie,imem,cname)\
+ cie_prepare_caches_4(p, (d3)->ranges, p3,\
&(c3)->floats, &(c3)[1].floats, &(c3)[2].floats,\
NULL, pcie, imem, cname)
-#define cie_prepare_cache4(d4,p4,c4,pcie,imem,cname)\
- cie_prepare_caches_4((d4)->ranges, p4,\
+#define cie_prepare_cache4(p,d4,p4,c4,pcie,imem,cname)\
+ cie_prepare_caches_4(p, (d4)->ranges, p4,\
&(c4)->floats, &(c4)[1].floats, &(c4)[2].floats,\
&(c4)[3].floats, pcie, imem, cname)
-int cie_cache_joint(P2(const ref_cie_render_procs *, gs_state *));
+int cie_cache_joint(P4(i_ctx_t *, const ref_cie_render_procs *,
+ const gs_cie_common *, gs_state *));
#endif /* icie_INCLUDED */
diff --git a/gs/src/icolor.h b/gs/src/icolor.h
index 351ef3048..dc7e58f20 100644
--- a/gs/src/icolor.h
+++ b/gs/src/icolor.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,27 +22,33 @@
#ifndef icolor_INCLUDED
# define icolor_INCLUDED
-/* Define the number of stack slots needed for zcolor_remap_one. */
-/* The client is responsible for doing check_e/ostack or the equivalent */
-/* before calling zcolor_remap_one. */
+/*
+ * Define the number of stack slots needed for zcolor_remap_one.
+ * The client is responsible for doing check_e/ostack or the equivalent
+ * before calling zcolor_remap_one.
+ */
extern const int zcolor_remap_one_ostack;
extern const int zcolor_remap_one_estack;
-/* Schedule the sampling and reloading of a cache. */
-int zcolor_remap_one(P5(const ref *, os_ptr, gx_transfer_map *,
- const gs_state *, int (*)(P1(os_ptr))));
+/*
+ * Schedule the sampling and reloading of a cache. Note that if
+ * zcolor_remap_one recognize the procedure as being of a special form,
+ * it may return 0 and not schedule anything.
+ */
+int zcolor_remap_one(P5(i_ctx_t *, const ref *, gx_transfer_map *,
+ const gs_state *, op_proc_t));
/* Reload a cache with entries in [0..1] after sampling. */
-int zcolor_remap_one_finish(P1(os_ptr));
+int zcolor_remap_one_finish(P1(i_ctx_t *));
/* Reload a cache with entries in [-1..1] after sampling. */
-int zcolor_remap_one_signed_finish(P1(os_ptr));
+int zcolor_remap_one_signed_finish(P1(i_ctx_t *));
/* Recompute the effective transfer functions and invalidate the current */
/* color after cache reloading. */
-int zcolor_reset_transfer(P1(os_ptr));
+int zcolor_reset_transfer(P1(i_ctx_t *));
/* Invalidate the current color after cache reloading. */
-int zcolor_remap_color(P1(os_ptr));
+int zcolor_remap_color(P1(i_ctx_t *));
#endif /* icolor_INCLUDED */
diff --git a/gs/src/iconf.c b/gs/src/iconf.c
index fdc6a7648..7dd08925c 100644
--- a/gs/src/iconf.c
+++ b/gs/src/iconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,6 +25,7 @@
#include "iref.h"
#include "ivmspace.h"
#include "opdef.h"
+#include "ifunc.h"
#include "iminst.h"
/* Define the default values for an interpreter instance. */
@@ -51,18 +52,31 @@ const ref_(const char *) gs_emulator_name_array[] = {
};
#undef emulator_
+/* Set up the function type table similarly. */
+#define function_type_(i,proc) extern build_function_proc(proc);
+#include "gconf.h"
+#undef function_type_
+#define function_type_(i,proc) {i,proc},
+const build_function_type_t build_function_type_table[] = {
+#include "gconf.h"
+ {0}
+};
+#undef function_type_
+const uint build_function_type_table_count =
+ countof(build_function_type_table) - 1;
+
/* Initialize the operators. */
/* Declare the externs. */
#define oper_(xx_op_defs) extern const op_def xx_op_defs[];
-#include "gconf.h"
oper_(interp_op_defs) /* Interpreter operators */
+#include "gconf.h"
#undef oper_
const op_def *const op_defs_all[] = {
- /* Create the table. */
#define oper_(defs) defs,
-#include "gconf.h"
oper_(interp_op_defs) /* Interpreter operators */
+#include "gconf.h"
#undef oper_
- 0
+ 0
};
+const uint op_def_count = (countof(op_defs_all) - 1) * OP_DEFS_MAX_SIZE;
diff --git a/gs/src/icontext.c b/gs/src/icontext.c
index c3f4eaf5a..5bae357e1 100644
--- a/gs/src/icontext.c
+++ b/gs/src/icontext.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,55 +31,71 @@
#include "isave.h"
#include "dstack.h"
#include "estack.h"
-#include "ostack.h"
#include "store.h"
-/* Define the initial stack sizes. */
-#define DSTACK_INITIAL 20
-#define ESTACK_INITIAL 250
-#define OSTACK_INITIAL 200
-
-/* Per-context state stored in statics */
-extern ref ref_array_packing;
-extern ref ref_binary_object_format;
-extern long zrand_state;
-
- /*extern ref ref_stdio[3]; *//* in files.h */
+/* Declare the GC descriptors for embedded objects. */
+extern_st(st_gs_dual_memory);
+extern_st(st_ref_stack);
+extern_st(st_dict_stack);
+extern_st(st_exec_stack);
+extern_st(st_op_stack);
/* Initialization procedures */
void zrand_state_init(P1(long *));
/* GC descriptors */
-extern_st(st_ref_stack);
#define pcst ((gs_context_state_t *)vptr)
private
CLEAR_MARKS_PROC(context_state_clear_marks)
{
+ r_clear_attrs(&pcst->stdio[0], l_mark);
+ r_clear_attrs(&pcst->stdio[1], l_mark);
+ r_clear_attrs(&pcst->stdio[2], l_mark);
r_clear_attrs(&pcst->userparams, l_mark);
}
private
-ENUM_PTRS_BEGIN(context_state_enum_ptrs) return 0;
-
-ENUM_PTR3(0, gs_context_state_t, dstack, estack, ostack);
-ENUM_PTR3(3, gs_context_state_t, pgs, stdio[0].value.pstruct,
- stdio[1].value.pstruct);
-case 6:
-ENUM_RETURN_REF(&pcst->userparams);
+ENUM_PTRS_BEGIN(context_state_enum_ptrs) {
+ index -= 5;
+ if (index < st_gs_dual_memory_num_ptrs)
+ return ENUM_USING(st_gs_dual_memory, &pcst->memory,
+ sizeof(pcst->memory), index);
+ index -= st_gs_dual_memory_num_ptrs;
+ if (index < st_dict_stack_num_ptrs)
+ return ENUM_USING(st_dict_stack, &pcst->dict_stack,
+ sizeof(pcst->dict_stack), index);
+ index -= st_dict_stack_num_ptrs;
+ if (index < st_exec_stack_num_ptrs)
+ return ENUM_USING(st_exec_stack, &pcst->exec_stack,
+ sizeof(pcst->exec_stack), index);
+ index -= st_dict_stack_num_ptrs;
+ return ENUM_USING(st_op_stack, &pcst->op_stack,
+ sizeof(pcst->op_stack), index);
+ }
+ ENUM_PTR(0, gs_context_state_t, pgs);
+ case 1: ENUM_RETURN_REF(&pcst->stdio[0]);
+ case 2: ENUM_RETURN_REF(&pcst->stdio[1]);
+ case 3: ENUM_RETURN_REF(&pcst->stdio[2]);
+ case 4: ENUM_RETURN_REF(&pcst->userparams);
ENUM_PTRS_END
private RELOC_PTRS_BEGIN(context_state_reloc_ptrs);
-RELOC_PTR3(gs_context_state_t, dstack, estack, ostack);
-RELOC_PTR3(gs_context_state_t, pgs, stdio[0].value.pstruct,
- stdio[1].value.pstruct);
-RELOC_REF_VAR(pcst->userparams);
-r_clear_attrs(&pcst->userparams, l_mark);
+ RELOC_PTR(gs_context_state_t, pgs);
+ RELOC_USING(st_gs_dual_memory, &pcst->memory, sizeof(pcst->memory));
+ RELOC_REF_VAR(pcst->stdio[0]);
+ RELOC_REF_VAR(pcst->stdio[1]);
+ RELOC_REF_VAR(pcst->stdio[2]);
+ RELOC_REF_VAR(pcst->userparams);
+ r_clear_attrs(&pcst->userparams, l_mark);
+ RELOC_USING(st_dict_stack, &pcst->dict_stack, sizeof(pcst->dict_stack));
+ RELOC_USING(st_exec_stack, &pcst->exec_stack, sizeof(pcst->exec_stack));
+ RELOC_USING(st_op_stack, &pcst->op_stack, sizeof(pcst->op_stack));
RELOC_PTRS_END
#undef pcst
public_st_context_state();
/* Allocate the state of a context. */
- int
- context_state_alloc(gs_context_state_t ** ppcst,
- const gs_dual_memory_t * dmem)
+int
+context_state_alloc(gs_context_state_t ** ppcst,
+ const gs_dual_memory_t * dmem)
{
gs_ref_memory_t *mem = dmem->space_local;
gs_context_state_t *pcst = *ppcst;
@@ -95,25 +111,27 @@ public_st_context_state();
code = gs_interp_alloc_stacks(mem, pcst);
if (code < 0)
goto x0;
- pcst->pgs = int_gstate_alloc(mem);
+ pcst->pgs = int_gstate_alloc(dmem);
if (pcst->pgs == 0) {
code = gs_note_error(e_VMerror);
goto x1;
}
pcst->memory = *dmem;
+ pcst->language_level = 1;
make_false(&pcst->array_packing);
make_int(&pcst->binary_object_format, 0);
zrand_state_init(&pcst->rand_state);
pcst->usertime_total = 0;
pcst->keep_usertime = false;
- { /*
- * Create an empty userparams dictionary of the right size.
- * If we can't determine the size, pick an arbitrary one.
- */
+ { /*
+ * Create an empty userparams dictionary of the right size.
+ * If we can't determine the size, pick an arbitrary one.
+ */
ref *puserparams;
uint size;
+ ref *system_dict = &pcst->dict_stack.system_dict;
- if (dict_find_string(systemdict, "userparams", &puserparams) >= 0)
+ if (dict_find_string(system_dict, "userparams", &puserparams) >= 0)
size = dict_length(puserparams);
else
size = 20;
@@ -123,11 +141,15 @@ public_st_context_state();
/* PostScript code initializes the user parameters. */
}
/* The initial stdio values are bogus.... */
- make_file(&pcst->stdio[0], 0, 1, invalid_file_entry);
- make_file(&pcst->stdio[1], 0, 1, invalid_file_entry);
- for (i = countof(pcst->memory.spaces.indexed); --i >= 0;)
- if (dmem->spaces.indexed[i] != 0)
- ++(dmem->spaces.indexed[i]->num_contexts);
+ make_file(&pcst->stdio[0], a_readonly | avm_invalid_file_entry, 1,
+ invalid_file_entry);
+ make_file(&pcst->stdio[1], a_all | avm_invalid_file_entry, 1,
+ invalid_file_entry);
+ make_file(&pcst->stdio[2], a_all | avm_invalid_file_entry, 1,
+ invalid_file_entry);
+ for (i = countof(pcst->memory.spaces_indexed); --i >= 0;)
+ if (dmem->spaces_indexed[i] != 0)
+ ++(dmem->spaces_indexed[i]->num_contexts);
*ppcst = pcst;
return 0;
x2:gs_state_free(pcst->pgs);
@@ -139,53 +161,48 @@ public_st_context_state();
/* Load the interpreter state from a context. */
int
-context_state_load(const gs_context_state_t * pcst)
+context_state_load(gs_context_state_t * pcst)
{
gs_ref_memory_t *lmem = iimemory_local;
- uint space = r_space(systemdict);
+ ref *system_dict = &pcst->dict_stack.system_dict;
+ uint space = r_space(system_dict);
int code;
- d_stack = *pcst->dstack;
- e_stack = *pcst->estack;
- o_stack = *pcst->ostack;
- igs = pcst->pgs;
gs_imemory = pcst->memory;
- ref_array_packing = pcst->array_packing;
- ref_binary_object_format = pcst->binary_object_format;
- zrand_state = pcst->rand_state;
/*
* Set systemdict.userparams to the saved copy, and then
* set the actual user parameters. Be careful to disable both
* space checking and save checking while we do this.
*/
- r_set_space(systemdict, avm_max);
+ r_set_space(system_dict, avm_max);
alloc_set_not_in_save(idmemory);
- code = dict_put_string(systemdict, "userparams", &pcst->userparams);
+ code = dict_put_string(system_dict, "userparams", &pcst->userparams,
+ &pcst->dict_stack);
if (code >= 0)
- code = set_user_params(&pcst->userparams);
- ref_stdio[0] = pcst->stdio[0];
- ref_stdio[1] = pcst->stdio[1];
+ code = set_user_params(pcst, &pcst->userparams);
if (iimemory_local != lmem) {
/*
* Switch references in systemdict to local objects.
* userdict.localdicts holds these objects.
*/
+ dict_stack_t *dstack = &pcst->dict_stack;
+ ref_stack_t *rdstack = &dstack->stack;
const ref *puserdict =
- ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 1 -
- dstack_userdict_index);
+ ref_stack_index(rdstack, ref_stack_count(rdstack) - 1 -
+ dstack->userdict_index);
ref *plocaldicts;
if (dict_find_string(puserdict, "localdicts", &plocaldicts) > 0 &&
r_has_type(plocaldicts, t_dictionary)
) {
- dict_copy(plocaldicts, systemdict);
+ dict_copy(plocaldicts, system_dict, dstack);
}
}
- r_set_space(systemdict, space);
+ r_set_space(system_dict, space);
if (idmemory->save_level > 0)
alloc_set_in_save(idmemory);
- esfile_clear_cache();
- dict_set_top(); /* reload dict stack cache */
+ estack_clear_cache(&pcst->exec_stack);
+ dstack_set_top(&pcst->dict_stack);
return code;
}
@@ -193,17 +210,10 @@ context_state_load(const gs_context_state_t * pcst)
int
context_state_store(gs_context_state_t * pcst)
{
- ref_stack_cleanup(&d_stack);
- ref_stack_cleanup(&e_stack);
- ref_stack_cleanup(&o_stack);
- *pcst->dstack = d_stack;
- *pcst->estack = e_stack;
- *pcst->ostack = o_stack;
- pcst->pgs = igs;
+ ref_stack_cleanup(&pcst->dict_stack.stack);
+ ref_stack_cleanup(&pcst->exec_stack.stack);
+ ref_stack_cleanup(&pcst->op_stack.stack);
pcst->memory = gs_imemory;
- pcst->array_packing = ref_array_packing;
- pcst->binary_object_format = ref_binary_object_format;
- pcst->rand_state = zrand_state;
/*
* The user parameters in systemdict.userparams are kept
* up to date by PostScript code, but we still need to save
@@ -211,13 +221,13 @@ context_state_store(gs_context_state_t * pcst)
*/
{
ref *puserparams;
+ /* We need i_ctx_p for access to the d_stack. */
+ i_ctx_t *i_ctx_p = pcst;
if (dict_find_string(systemdict, "userparams", &puserparams) < 0)
return_error(e_Fatal);
pcst->userparams = *puserparams;
}
- pcst->stdio[0] = ref_stdio[0];
- pcst->stdio[1] = ref_stdio[1];
return 0;
}
@@ -234,9 +244,9 @@ context_state_free(gs_context_state_t * pcst)
* (local / global / system), free the entire VM space;
* otherwise, just free the context-related structures.
*/
- for (i = countof(pcst->memory.spaces.indexed); --i >= 0;) {
- if (pcst->memory.spaces.indexed[i] != 0 &&
- !--(pcst->memory.spaces.indexed[i]->num_contexts)
+ for (i = countof(pcst->memory.spaces_indexed); --i >= 0;) {
+ if (pcst->memory.spaces_indexed[i] != 0 &&
+ !--(pcst->memory.spaces_indexed[i]->num_contexts)
) {
/****** FREE THE ENTIRE SPACE ******/
freed |= 1 << i;
diff --git a/gs/src/icontext.h b/gs/src/icontext.h
index 604e8e293..5b2988aae 100644
--- a/gs/src/icontext.h
+++ b/gs/src/icontext.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,7 +23,7 @@
#ifndef icontext_INCLUDED
# define icontext_INCLUDED
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
#include "icstate.h"
/* Declare the GC descriptor for context states. */
@@ -33,7 +33,7 @@ extern_st(st_context_state);
* Define the procedure for resetting user parameters when switching
* contexts. This is defined in either zusparam.c or inouparm.c.
*/
-extern int set_user_params(P1(const ref * paramdict));
+extern int set_user_params(P2(i_ctx_t *i_ctx_p, const ref * paramdict));
/* Allocate the state of a context, always in local VM. */
/* If *ppcst == 0, allocate the state object as well. */
@@ -41,7 +41,8 @@ int context_state_alloc(P2(gs_context_state_t ** ppcst,
const gs_dual_memory_t * dmem));
/* Load the state of the interpreter from a context. */
-int context_state_load(P1(const gs_context_state_t *));
+/* The argument is not const because caches may be updated. */
+int context_state_load(P1(gs_context_state_t *));
/* Store the state of the interpreter into a context. */
int context_state_store(P1(gs_context_state_t *));
diff --git a/gs/src/icremap.h b/gs/src/icremap.h
new file mode 100644
index 000000000..385284340
--- /dev/null
+++ b/gs/src/icremap.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interpreter color remapping structure */
+
+#ifndef icremap_INCLUDED
+# define icremap_INCLUDED
+
+#include "gsccolor.h"
+
+/*
+ * Define the structure used to communicate information back to the
+ * interpreter for color remapping. Pattern remapping doesn't use the
+ * tint values, DeviceN remapping does.
+ */
+#ifndef int_remap_color_info_DEFINED
+# define int_remap_color_info_DEFINED
+typedef struct int_remap_color_info_s int_remap_color_info_t;
+#endif
+struct int_remap_color_info_s {
+ op_proc_t proc; /* remapping procedure */
+ float tint[GS_CLIENT_COLOR_MAX_COMPONENTS];
+};
+
+#define private_st_int_remap_color_info() /* in zgstate.c */\
+ gs_private_st_simple(st_int_remap_color_info, int_remap_color_info_t,\
+ "int_remap_color_info_t")
+
+#endif /* icremap_INCLUDED */
diff --git a/gs/src/icsmap.h b/gs/src/icsmap.h
index 1042f8e0e..476d624fd 100644
--- a/gs/src/icsmap.h
+++ b/gs/src/icsmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,7 +33,14 @@
# define csme_proc (-2) /* -procedure- */
# define csme_hival (-1) /* t_integer */
# define csme_index 0 /* t_integer */
-int zcs_begin_map(P5(gs_indexed_map ** pmap, const ref * pproc, int num_entries,
- const gs_base_color_space * base_space, int (*map1) (P1(os_ptr))));
+/*
+ * Note that the underlying color space parameter is a direct space, not a
+ * base space, since the underlying space of an Indexed color space may be
+ * a Separation or DeviceN space.
+ */
+int zcs_begin_map(P6(i_ctx_t *i_ctx_p, gs_indexed_map ** pmap,
+ const ref * pproc, int num_entries,
+ const gs_direct_color_space * base_space,
+ op_proc_t map1));
#endif /* icsmap_INCLUDED */
diff --git a/gs/src/icstate.h b/gs/src/icstate.h
index fde04e218..2abbb6f6f 100644
--- a/gs/src/icstate.h
+++ b/gs/src/icstate.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,12 +18,15 @@
/* Externally visible context state */
-/* Requires iref.h */
#ifndef icstate_INCLUDED
# define icstate_INCLUDED
#include "imemory.h"
+#include "iref.h"
+#include "idsdata.h"
+#include "iesdata.h"
+#include "iosdata.h"
/*
* Define the externally visible state of an interpreter context.
@@ -34,30 +37,27 @@
# define gs_context_state_t_DEFINED
typedef struct gs_context_state_s gs_context_state_t;
#endif
-#ifndef ref_stack_DEFINED
-# define ref_stack_DEFINED
-typedef struct ref_stack_s ref_stack;
-#endif
struct gs_context_state_s {
- ref_stack *dstack;
- ref_stack *estack;
- ref_stack *ostack;
gs_state *pgs;
gs_dual_memory_t memory;
+ int language_level;
ref array_packing; /* t_boolean */
ref binary_object_format; /* t_integer */
long rand_state; /* (not in Red Book) */
long usertime_total; /* total accumulated usertime, */
- /* not counting current time if running */
+ /* not counting current time if running */
bool keep_usertime; /* true if context ever executed usertime */
/* View clipping is handled in the graphics state. */
ref userparams; /* t_dictionary */
- ref stdio[2]; /* t_file */
+ ref stdio[3]; /* t_file */
+ /* Put the stacks at the end to minimize other offsets. */
+ dict_stack_t dict_stack;
+ exec_stack_t exec_stack;
+ op_stack_t op_stack;
};
/*
- * We make st_context_state public because interp.c must allocate one,
- * and zcontext.c must subclass it.
+ * We make st_context_state public because zcontext.c must subclass it.
*/
/*extern_st(st_context_state); *//* in icontext.h */
#define public_st_context_state() /* in icontext.c */\
diff --git a/gs/src/iddict.h b/gs/src/iddict.h
new file mode 100644
index 000000000..1229e40fb
--- /dev/null
+++ b/gs/src/iddict.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Dictionary API with implicit dict_stack argument */
+
+#ifndef iddict_INCLUDED
+# define iddict_INCLUDED
+
+#include "idict.h"
+#include "icstate.h" /* for access to dict_stack */
+
+/* Define the dictionary stack instance for operators. */
+#define idict_stack (i_ctx_p->dict_stack)
+
+#define idict_put(pdref, key, pvalue)\
+ dict_put(pdref, key, pvalue, &idict_stack)
+#define idict_put_string(pdref, kstr, pvalue)\
+ dict_put_string(pdref, kstr, pvalue, &idict_stack)
+#define idict_undef(pdref, key)\
+ dict_undef(pdref, key, &idict_stack)
+#define idict_copy(dfrom, dto)\
+ dict_copy(dfrom, dto, &idict_stack)
+#define idict_copy_new(dfrom, dto)\
+ dict_copy_new(dfrom, dto, &idict_stack)
+#define idict_resize(pdref, newmax)\
+ dict_resize(pdref, newmax, &idict_stack)
+#define idict_grow(pdref)\
+ dict_grow(pdref, &idict_stack)
+#define idict_unpack(pdref)\
+ dict_unpack(pdref, &idict_stack)
+
+#endif /* iddict_INCLUDED */
diff --git a/gs/src/iddstack.h b/gs/src/iddstack.h
new file mode 100644
index 000000000..3a3aa1415
--- /dev/null
+++ b/gs/src/iddstack.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Dictionary stack API subset needed by idict.h */
+
+#ifndef iddstack_INCLUDED
+# define iddstack_INCLUDED
+
+#ifndef dict_stack_DEFINED
+# define dict_stack_DEFINED
+typedef struct dict_stack_s dict_stack_t;
+#endif
+
+/*
+ * Reset the cached top values. Every routine that alters the
+ * dictionary stack (including changing the protection or size of the
+ * top dictionary on the stack) must call this.
+ */
+void dstack_set_top(P1(dict_stack_t *));
+
+/* Check whether a dictionary is one of the permanent ones on the d-stack. */
+bool dstack_dict_is_permanent(P2(const dict_stack_t *, const ref *));
+
+#endif /* iddstack_INCLUDED */
diff --git a/gs/src/idebug.c b/gs/src/idebug.c
index 8ebbb6f8a..8b2c89354 100644
--- a/gs/src/idebug.c
+++ b/gs/src/idebug.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,9 @@
#include "opdef.h"
/* Table of type name strings */
-static const char *const type_strings[] =
-{type_print_strings};
+static const char *const type_strings[] = {
+ REF_TYPE_DEBUG_PRINT_STRINGS
+};
/* First unassigned type index */
extern const int tx_next_index; /* in interp.c */
@@ -54,7 +55,7 @@ debug_print_name(const ref * pnref)
private void
debug_print_full_ref(const ref * pref)
{
- unsigned size = r_size(pref);
+ uint size = r_size(pref);
ref nref;
dprintf1("(%x)", r_type_attrs(pref));
@@ -110,7 +111,7 @@ debug_print_full_ref(const ref * pref)
case t_operator:
dprintf1("op(%u", size);
if (size > 0 && size < op_def_count) /* just in case */
- dprintf1(":%s", (const char *)(op_def_table[size]->oname + 1));
+ dprintf1(":%s", (const char *)(op_index_def(size)->oname + 1));
dprintf1(")0x%lx", (ulong) pref->value.opproc);
break;
case t_real:
@@ -179,20 +180,18 @@ debug_print_ref(const ref * pref)
}
/* Dump one ref. */
+private void print_ref_data(P1(const ref *));
void
debug_dump_one_ref(const ref * p)
{
uint attrs = r_type_attrs(p);
uint type = r_type(p);
- static const attr_print_mask apm[] =
- {attr_print_masks,
- {0, 0, 0}};
+ static const attr_print_mask apm[] = {
+ attr_print_masks,
+ {0, 0, 0}
+ };
const attr_print_mask *ap = apm;
-#define buf_size 30
- char buf[buf_size + 1];
- uint plen;
-
if (type >= tx_next_index)
dprintf1("0x%02x?? ", type);
else if (type >= t_next_index)
@@ -203,12 +202,24 @@ debug_dump_one_ref(const ref * p)
if ((attrs & ap->mask) == ap->value)
dputc(ap->print);
dprintf2(" 0x%04x 0x%08lx", r_size(p), *(const ulong *)&p->value);
- if (obj_cvs(p, (byte *) buf, countof(buf) - 1, &plen, NULL) >= 0 &&
- ((buf[plen] = 0), strcmp(buf, "--nostringval--"))
- )
- dprintf1(" = %s", buf);
+ print_ref_data(p);
fflush(dstderr);
}
+private void
+print_ref_data(const ref *p)
+{
+#define BUF_SIZE 30
+ byte buf[BUF_SIZE + 1];
+ const byte *pchars;
+ uint plen;
+
+ if (obj_cvs(p, buf, countof(buf) - 1, &plen, &pchars) >= 0 &&
+ pchars == buf &&
+ ((buf[plen] = 0), strcmp((char *)buf, "--nostringval--"))
+ )
+ dprintf1(" = %s", (char *)buf);
+#undef BUF_SIZE
+}
/* Dump a region of memory containing refs. */
void
@@ -219,10 +230,8 @@ debug_dump_refs(const ref * from, uint size, const char *msg)
if (size && msg)
dprintf2("%s at 0x%lx:\n", msg, (ulong) from);
- while (count--) { /* The double cast in the next line is to pacify some */
- /* unreasonably picky compilers. */
- dprintf2("..%04x: 0x%04x ", (uint) (ulong) p & 0xffff,
- r_type_attrs(p));
+ while (count--) {
+ dprintf2("0x%lx: 0x%04x ", (ulong)p, r_type_attrs(p));
debug_dump_one_ref(p);
dputc('\n');
p++;
@@ -231,7 +240,7 @@ debug_dump_refs(const ref * from, uint size, const char *msg)
/* Dump a stack. */
void
-debug_dump_stack(const ref_stack * pstack, const char *msg)
+debug_dump_stack(const ref_stack_t * pstack, const char *msg)
{
uint i;
const char *m = msg;
@@ -239,10 +248,11 @@ debug_dump_stack(const ref_stack * pstack, const char *msg)
for (i = ref_stack_count(pstack); i != 0;) {
const ref *p = ref_stack_index(pstack, --i);
- if (m)
- dprintf2("%s at 0x%lx:\n", m, (ulong) pstack),
- m = NULL;
- dprintf2("0x%lx: 0x%02x ", (ulong) p, r_type(p));
+ if (m) {
+ dprintf2("%s at 0x%lx:\n", m, (ulong) pstack);
+ m = NULL;
+ }
+ dprintf2("0x%lx: 0x%02x ", (ulong)p, r_type(p));
debug_dump_one_ref(p);
dputc('\n');
}
@@ -253,7 +263,7 @@ void
debug_dump_array(const ref * array)
{
const ref_packed *pp;
- unsigned int type = r_type(array);
+ uint type = r_type(array);
uint len;
switch (type) {
@@ -281,13 +291,13 @@ debug_dump_array(const ref * array)
ref temp;
packed_get(pp, &temp);
- /* The double cast in the next line is to pacify some */
- /* unreasonably picky compilers. */
- dprintf3("..%04x%c 0x%02x ",
- (uint) (ulong) pp & 0xffff,
- ((r_is_packed(pp)) ? '*' : ':'),
- r_type(&temp));
- debug_dump_one_ref(&temp);
+ if (r_is_packed(pp)) {
+ dprintf2("0x%lx* 0x%04x", (ulong)pp, (uint)*pp);
+ print_ref_data(&temp);
+ } else {
+ dprintf2("0x%lx: 0x%02x", (ulong)pp, r_type(&temp));
+ debug_dump_one_ref(&temp);
+ }
dputc('\n');
}
}
diff --git a/gs/src/idebug.h b/gs/src/idebug.h
index ea445a6c6..aea97de4f 100644
--- a/gs/src/idebug.h
+++ b/gs/src/idebug.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,10 +33,9 @@ void debug_dump_array(P1(const ref * array));
/* Dump a stack. Using this requires istack.h. */
#ifndef ref_stack_DEFINED
-typedef struct ref_stack_s ref_stack; /* also defined in istack.h */
-
+typedef struct ref_stack_s ref_stack_t; /* also defined in istack.h */
# define ref_stack_DEFINED
#endif
-void debug_dump_stack(P2(const ref_stack * pstack, const char *msg));
+void debug_dump_stack(P2(const ref_stack_t * pstack, const char *msg));
#endif /* idebug_INCLUDED */
diff --git a/gs/src/idict.c b/gs/src/idict.c
index 20cbb6d5b..ceacd4b09 100644
--- a/gs/src/idict.c
+++ b/gs/src/idict.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,17 +41,10 @@
* (requiring updating when that dictionary grows or is unpacked),
* and names may cache a pointer to their definition (requiring a
* check whether a dictionary appears on the dictionary stack).
- * Therefore, we patch in a few relevant definitions here.
- ****** WE'D REALLY LIKE TO FIX THIS, BUT WE DON'T SEE HOW. ******
+ * Therefore, we need iddstack.h here.
+ * We'd really like to fix this, but we don't see how.
*/
-#include "idstack.h"
-/* The following are copied from dstack.h. */
-extern dict_stack_t idict_stack;
-
-#define systemdict (&idict_stack.system_dict)
-#define dict_set_top() dstack_set_top(&idict_stack);
-#define dict_is_permanent_on_dstack(pdict)\
- dstack_dict_is_permanent(&idict_stack, pdict)
+#include "iddstack.h"
/*
* Define the size of the largest valid dictionary.
@@ -73,9 +66,11 @@ private int dict_create_contents(P3(uint size, const ref * pdref, bool pack));
/* Debugging statistics */
#ifdef DEBUG
-long dn_lookups; /* total lookups */
-long dn_1probe; /* successful lookups on only 1 probe */
-long dn_2probe; /* successful lookups on 2 probes */
+struct stats_dict_s {
+ long lookups; /* total lookups */
+ long probe1; /* successful lookups on only 1 probe */
+ long probe2; /* successful lookups on 2 probes */
+} stats_dict;
/* Wrapper for dict_find */
int real_dict_find(P3(const ref * pdref, const ref * key, ref ** ppvalue));
@@ -85,7 +80,7 @@ dict_find(const ref * pdref, const ref * pkey, ref ** ppvalue)
dict *pdict = pdref->value.pdict;
int code = real_dict_find(pdref, pkey, ppvalue);
- dn_lookups++;
+ stats_dict.lookups++;
if (r_has_type(pkey, t_name) && dict_is_packed(pdict)) {
uint nidx = name_index(pkey);
uint hash =
@@ -94,16 +89,16 @@ dict_find(const ref * pdref, const ref * pkey, ref ** ppvalue)
if (pdict->keys.value.packed[hash] ==
pt_tag(pt_literal_name) + nidx
)
- dn_1probe++;
+ stats_dict.probe1++;
else if (pdict->keys.value.packed[hash - 1] ==
pt_tag(pt_literal_name) + nidx
)
- dn_2probe++;
+ stats_dict.probe2++;
}
/* Do the cheap flag test before the expensive remainder test. */
- if (gs_debug_c('d') && !(dn_lookups % 1000))
- dlprintf3("[d]lookups=%ld 1probe=%ld 2probe=%ld\n",
- dn_lookups, dn_1probe, dn_2probe);
+ if (gs_debug_c('d') && !(stats_dict.lookups % 1000))
+ dlprintf3("[d]lookups=%ld probe1=%ld probe2=%ld\n",
+ stats_dict.lookups, stats_dict.probe1, stats_dict.probe2);
return code;
}
#define dict_find real_dict_find
@@ -226,7 +221,7 @@ dict_create_contents(uint size, const ref * pdref, bool pack)
* We can't just use dict_resize, because the values slots mustn't move.
*/
int
-dict_unpack(ref * pdref)
+dict_unpack(ref * pdref, dict_stack_t *pds)
{
dict *pdict = pdref->value.pdict;
@@ -254,7 +249,8 @@ dict_unpack(ref * pdref)
if (!ref_must_save(&old_keys))
gs_free_ref_array(dict_memory(pdict), &old_keys,
"dict_unpack(old keys)");
- dict_set_top(); /* just in case */
+ if (pds)
+ dstack_set_top(pds); /* just in case */
}
return 0;
}
@@ -330,12 +326,12 @@ dict_find(const ref * pdref, const ref * pkey,
* we must return dictfull if length = maxlength.
*/
if (pslot == 0 || d_length(pdict) == d_maxlength(pdict))
- return (e_dictfull);
+ return_error(e_dictfull);
*ppvalue = pdict->values.value.refs + (pslot - kbot);
return 0;
miss: /* Key is missing, not double wrap. See above re dictfull. */
if (d_length(pdict) == d_maxlength(pdict))
- return (e_dictfull);
+ return_error(e_dictfull);
if (pslot == 0)
pslot = kp;
*ppvalue = pdict->values.value.refs + (pslot - kbot);
@@ -358,7 +354,7 @@ dict_find(const ref * pdref, const ref * pkey,
if (kp == kbot) { /* wrap */
if (wrap++) { /* wrapped twice */
if (pslot == 0)
- return (e_dictfull);
+ return_error(e_dictfull);
break;
}
kp += size + 1;
@@ -375,7 +371,7 @@ dict_find(const ref * pdref, const ref * pkey,
}
}
if (d_length(pdict) == d_maxlength(pdict))
- return (e_dictfull);
+ return_error(e_dictfull);
*ppvalue = pdict->values.value.refs +
((pslot != 0 ? pslot : kp) - kbot);
return 0;
@@ -402,7 +398,8 @@ dict_find_string(const ref * pdref, const char *kstr, ref ** ppvalue)
* See idict.h for the possible return values.
*/
int
-dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue)
+dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue,
+ dict_stack_t *pds)
{
int rcode = 0;
int code;
@@ -421,7 +418,7 @@ dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue)
case e_dictfull:
if (!dict_auto_expand)
return_error(e_dictfull);
- code = dict_grow(pdref);
+ code = dict_grow(pdref, pds);
if (code < 0)
return code;
goto top; /* keep things simple */
@@ -446,13 +443,13 @@ dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue)
if (!r_has_type(pkey, t_name) ||
name_index(pkey) > packed_name_max_index
) { /* Change to unpacked representation. */
- int code = dict_unpack(pdref);
+ int code = dict_unpack(pdref, pds);
if (code < 0)
return code;
goto top;
}
- kp = (ref_packed *) (pdict->keys.value.packed + index);
+ kp = pdict->keys.value.writable_packed + index;
if (ref_must_save(&pdict->keys)) { /* See initial comment for why it is safe */
/* not to save the change if the keys */
/* array itself is new. */
@@ -475,11 +472,11 @@ dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue)
name *pname = pkey->value.pname;
if (pname->pvalue == pv_no_defn &&
- (pdict == systemdict->value.pdict ||
- dict_is_permanent_on_dstack(pdref)) &&
- /* Only set the cache if we aren't inside */
- /* a save. This way, we never have to */
- /* undo setting the cache. */
+ pds && dstack_dict_is_permanent(pds, pdref) &&
+ /*
+ * Only set the cache if we aren't inside a save.
+ * This way, we never have to undo setting the cache.
+ */
alloc_save_level(idmemory) == 0
) { /* Set the cache. */
if_debug0('d', "[d]set cache\n");
@@ -506,19 +503,20 @@ dict_put(ref * pdref /* t_dictionary */ , const ref * pkey, const ref * pvalue)
* Enter a key-value pair where the key is a (constant) C string.
*/
int
-dict_put_string(ref * pdref, const char *kstr, const ref * pvalue)
+dict_put_string(ref * pdref, const char *kstr, const ref * pvalue,
+ dict_stack_t *pds)
{
int code;
ref kname;
if ((code = name_ref((const byte *)kstr, strlen(kstr), &kname, 0)) < 0)
return code;
- return dict_put(pdref, &kname, pvalue);
+ return dict_put(pdref, &kname, pvalue, pds);
}
/* Remove an element from a dictionary. */
int
-dict_undef(ref * pdref, const ref * pkey)
+dict_undef(ref * pdref, const ref * pkey, dict_stack_t *pds)
{
ref *pvslot;
dict *pdict;
@@ -530,29 +528,44 @@ dict_undef(ref * pdref, const ref * pkey)
pdict = pdref->value.pdict;
index = pvslot - pdict->values.value.refs;
if (dict_is_packed(pdict)) {
- ref_packed *pkp =
- (ref_packed *) (pdict->keys.value.packed + index);
+ ref_packed *pkp = pdict->keys.value.writable_packed + index;
+ if_debug3('d', "[d]0x%lx: removing key at 0%lx: 0x%x\n",
+ (ulong)pdict, (ulong)pkp, (uint)*pkp);
/* See the initial comment for why it is safe not to save */
/* the change if the keys array itself is new. */
if (ref_must_save(&pdict->keys))
ref_do_save(&pdict->keys, pkp, "dict_undef(key)");
- /* Accumulating deleted entries slows down lookup. */
- /* Detect the easy case where we can use an empty entry */
- /* rather than a deleted one, namely, when the next entry */
- /* in the probe order is empty. */
- if (pkp[-1] == packed_key_empty)
+ /*
+ * Accumulating deleted entries slows down lookup.
+ * Detect the easy case where we can use an empty entry
+ * rather than a deleted one, namely, when the next entry
+ * in the probe order is empty.
+ */
+ if (pkp[-1] == packed_key_empty) {
+ /*
+ * In this case we can replace any preceding deleted keys with
+ * empty ones as well.
+ */
+ uint end = nslots(pdict);
+
*pkp = packed_key_empty;
- else
+ while (++index < end && *++pkp == packed_key_deleted)
+ *pkp = packed_key_empty;
+ } else
*pkp = packed_key_deleted;
} else { /* not packed */
ref *kp = pdict->keys.value.refs + index;
+ if_debug4('d', "[d]0x%lx: removing key at 0%lx: 0x%lx 0x%lx\n",
+ (ulong)pdict, (ulong)kp, ((ulong *)kp)[0], ((ulong *)kp)[1]);
make_null_old(&pdict->keys, kp, "dict_undef(key)");
- /* Accumulating deleted entries slows down lookup. */
- /* Detect the easy case where we can use an empty entry */
- /* rather than a deleted one, namely, when the next entry */
- /* in the probe order is empty. */
+ /*
+ * Accumulating deleted entries slows down lookup.
+ * Detect the easy case where we can use an empty entry
+ * rather than a deleted one, namely, when the next entry
+ * in the probe order is empty.
+ */
if (!r_has_type(kp - 1, t_null) || /* full entry */
r_has_attr(kp - 1, a_executable) /* deleted or wraparound */
)
@@ -567,7 +580,7 @@ dict_undef(ref * pdref, const ref * pkey)
if (pv_valid(pname->pvalue)) {
#ifdef DEBUG
/* Check the the cache is correct. */
- if (!dict_is_permanent_on_dstack(pdref))
+ if (!(pds && dstack_dict_is_permanent(pds, pdref)))
lprintf1("dict_undef: cached name value pointer 0x%lx is incorrect!\n",
(ulong) pname->pvalue);
#endif
@@ -605,7 +618,8 @@ dict_max_index(const ref * pdref /* t_dictionary */ )
/* aren't already present in the destination. */
int
dict_copy_entries(const ref * pdrfrom /* t_dictionary */ ,
- ref * pdrto /* t_dictionary */ , bool new_only)
+ ref * pdrto /* t_dictionary */ , bool new_only,
+ dict_stack_t *pds)
{
int space = r_space(pdrto);
int index;
@@ -626,7 +640,7 @@ dict_copy_entries(const ref * pdrfrom /* t_dictionary */ ,
while ((index = dict_next(pdrfrom, index, elt)) >= 0) {
if (new_only && dict_find(pdrto, &elt[0], &pvslot) > 0)
continue;
- if ((code = dict_put(pdrto, &elt[0], &elt[1])) < 0)
+ if ((code = dict_put(pdrto, &elt[0], &elt[1], pds)) < 0)
return code;
}
return 0;
@@ -634,7 +648,7 @@ dict_copy_entries(const ref * pdrfrom /* t_dictionary */ ,
/* Resize a dictionary. */
int
-dict_resize(ref * pdref, uint new_size)
+dict_resize(ref * pdref, uint new_size, dict_stack_t *pds)
{
dict *pdict = pdref->value.pdict;
gs_ref_memory_t *mem = dict_memory(pdict);
@@ -656,7 +670,7 @@ dict_resize(ref * pdref, uint new_size)
/* systemdict or another global dictionary that is allowed */
/* to reference local objects. */
r_set_space(&drto, avm_local);
- dict_copy(pdref, &drto); /* can't fail */
+ dict_copy(pdref, &drto, pds); /* can't fail */
/* Save or free the old dictionary. */
if (ref_must_save(&pdict->values))
ref_do_save(pdref, &pdict->values, "dict_resize(values)");
@@ -670,13 +684,14 @@ dict_resize(ref * pdref, uint new_size)
ref_assign(&pdict->values, &dnew.values);
ref_save(pdref, &pdict->maxlength, "dict_resize(maxlength)");
d_set_maxlength(pdict, new_size);
- dict_set_top(); /* just in case this is the top dict */
+ if (pds)
+ dstack_set_top(pds); /* just in case this is the top dict */
return 0;
}
/* Grow a dictionary for dict_put. */
int
-dict_grow(ref * pdref)
+dict_grow(ref * pdref, dict_stack_t *pds)
{
dict *pdict = pdref->value.pdict;
@@ -689,13 +704,13 @@ dict_grow(ref * pdref)
new_size = max_uint;
#endif
if (new_size > npairs(pdict)) {
- int code = dict_resize(pdref, (uint) new_size);
+ int code = dict_resize(pdref, (uint) new_size, pds);
if (code >= 0)
return code;
/* new_size was too big. */
if (npairs(pdict) < dict_max_size) {
- code = dict_resize(pdref, dict_max_size);
+ code = dict_resize(pdref, dict_max_size, pds);
if (code >= 0)
return code;
}
diff --git a/gs/src/idict.h b/gs/src/idict.h
index 6777b28ec..9b0d119cc 100644
--- a/gs/src/idict.h
+++ b/gs/src/idict.h
@@ -22,6 +22,8 @@
#ifndef idict_INCLUDED
# define idict_INCLUDED
+#include "iddstack.h"
+
/*
* Contrary to our usual practice, we expose the (first-level)
* representation of a dictionary in the interface file,
@@ -59,7 +61,6 @@ extern bool dict_auto_expand;
#ifndef gs_ref_memory_DEFINED
# define gs_ref_memory_DEFINED
typedef struct gs_ref_memory_s gs_ref_memory_t;
-
#endif
int dict_alloc(P3(gs_ref_memory_t *, uint maxlength, ref * pdref));
@@ -105,22 +106,31 @@ int dict_find_string(P3(const ref * pdref, const char *kstr, ref ** ppvalue));
* Failure returns are as for dict_find, except that e_dictfull doesn't
* occur if the dictionary is full but expandable, plus:
* e_invalidaccess for an attempt to store a younger key or value into
- * an older dictionary;
+ * an older dictionary, or as described just below;
* e_VMerror if a VMerror occurred while trying to expand the
* dictionary.
+ * Note that this procedure, and all procedures that may change the
+ * contents of a dictionary, take a pointer to a dictionary stack,
+ * so they can update the cached 'top' values and also update the cached
+ * value pointer in names. A NULL pointer for the dictionary stack is
+ * allowed, but in this case, if the dictionary is present on any dictionary
+ * stack, an e_invalidaccess error will occur if cached values need updating.
+ * THIS ERROR CHECK IS NOT IMPLEMENTED YET.
*/
-int dict_put(P3(ref * pdref, const ref * key, const ref * pvalue));
+int dict_put(P4(ref * pdref, const ref * key, const ref * pvalue,
+ dict_stack_t *pds));
/*
* Enter a key-value pair where the key is a (constant) C string.
*/
-int dict_put_string(P3(ref * pdref, const char *kstr, const ref * pvalue));
+int dict_put_string(P4(ref * pdref, const char *kstr, const ref * pvalue,
+ dict_stack_t *pds));
/*
* Remove a key-value pair from a dictionary.
* Return 0 or e_undefined.
*/
-int dict_undef(P2(ref * pdref, const ref * key));
+int dict_undef(P3(ref * pdref, const ref * key, dict_stack_t *pds));
/*
* Return the number of elements in a dictionary.
@@ -144,28 +154,29 @@ uint dict_max_index(P1(const ref * pdref));
* If new_only is true, only copy entries whose keys
* aren't already present in the destination.
*/
-int dict_copy_entries(P3(const ref * dfrom, ref * dto, bool new_only));
+int dict_copy_entries(P4(const ref * dfrom, ref * dto, bool new_only,
+ dict_stack_t *pds));
-#define dict_copy(dfrom, dto) dict_copy_entries(dfrom, dto, false)
-#define dict_copy_new(dfrom, dto) dict_copy_entries(dfrom, dto, true)
+#define dict_copy(dfrom, dto, pds) dict_copy_entries(dfrom, dto, false, pds)
+#define dict_copy_new(dfrom, dto, pds) dict_copy_entries(dfrom, dto, true, pds)
/*
* Grow or shrink a dictionary.
* Return 0, e_dictfull, or e_VMerror.
*/
-int dict_resize(P2(ref * pdref, uint newmaxlength));
+int dict_resize(P3(ref * pdref, uint newmaxlength, dict_stack_t *pds));
/*
* Grow a dictionary in the same way as dict_put does.
* We export this for some special-case code in zop_def.
*/
-int dict_grow(P1(ref * pdref));
+int dict_grow(P2(ref * pdref, dict_stack_t *pds));
/*
* Ensure that a dictionary uses the unpacked representation for keys.
* (This is of no interest to ordinary clients.)
*/
-int dict_unpack(P1(ref * pdref));
+int dict_unpack(P2(ref * pdref, dict_stack_t *pds));
/*
* Prepare to enumerate a dictionary.
diff --git a/gs/src/idparam.c b/gs/src/idparam.c
index 04f65710b..a9a121c90 100644
--- a/gs/src/idparam.c
+++ b/gs/src/idparam.c
@@ -269,7 +269,7 @@ dict_matrix_param(const ref * pdict, const char *kstr, gs_matrix * pmat)
/* If there is no uid, return default. */
int
dict_uid_param(const ref * pdict, gs_uid * puid, int defaultval,
- gs_memory_t * mem)
+ gs_memory_t * mem, const i_ctx_t *i_ctx_p)
{
ref *puniqueid;
diff --git a/gs/src/idparam.h b/gs/src/idparam.h
index 2f2d5a50e..4175f2516 100644
--- a/gs/src/idparam.h
+++ b/gs/src/idparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,13 +25,11 @@
#ifndef gs_matrix_DEFINED
# define gs_matrix_DEFINED
typedef struct gs_matrix_s gs_matrix;
-
#endif
#ifndef gs_uid_DEFINED
# define gs_uid_DEFINED
typedef struct gs_uid_s gs_uid;
-
#endif
/*
@@ -75,8 +73,8 @@ int dict_proc_param(P4(const ref * pdict, const char *kstr, ref * pproc,
bool defaultval));
int dict_matrix_param(P3(const ref * pdict, const char *kstr,
gs_matrix * pmat));
-int dict_uid_param(P4(const ref * pdict, gs_uid * puid, int defaultval,
- gs_memory_t * mem));
+int dict_uid_param(P5(const ref * pdict, gs_uid * puid, int defaultval,
+ gs_memory_t * mem, const i_ctx_t *i_ctx_p));
/* Check that a UID in a dictionary is equal to an existing, valid UID. */
bool dict_check_uid_param(P2(const ref * pdict, const gs_uid * puid));
diff --git a/gs/src/idsdata.h b/gs/src/idsdata.h
new file mode 100644
index 000000000..b50052e61
--- /dev/null
+++ b/gs/src/idsdata.h
@@ -0,0 +1,86 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Generic dictionary stack structure definition */
+
+#ifndef idsdata_INCLUDED
+# define idsdata_INCLUDED
+
+#include "isdata.h"
+
+/* Define the dictionary stack structure. */
+#ifndef dict_stack_DEFINED
+# define dict_stack_DEFINED
+typedef struct dict_stack_s dict_stack_t;
+#endif
+struct dict_stack_s {
+
+ ref_stack_t stack; /* the actual stack of dictionaries */
+
+/*
+ * Switching between Level 1 and Level 2 involves inserting and removing
+ * globaldict on the dictionary stack. Instead of truly inserting and
+ * removing entries, we replace globaldict by a copy of systemdict in
+ * Level 1 mode. min_dstack_size, the minimum number of entries, does not
+ * change depending on language level; the countdictstack and dictstack
+ * operators must take this into account.
+ */
+ uint min_size; /* size of stack after clearing */
+
+ int userdict_index; /* index of userdict on stack */
+
+/*
+ * Cache a value for fast checking of def operations.
+ * If the top entry on the dictionary stack is a writable dictionary,
+ * dsspace is the space of the dictionary; if it is a non-writable
+ * dictionary, dsspace = -1. Then def is legal precisely if
+ * r_space(pvalue) <= dsspace. Note that in order for this trick to work,
+ * the result of r_space must be a signed integer; some compilers treat
+ * enums as unsigned, probably in violation of the ANSI standard.
+ */
+ int def_space;
+
+/*
+ * Cache values for fast name lookup. If the top entry on the dictionary
+ * stack is a readable dictionary with packed keys, dtop_keys, dtop_npairs,
+ * and dtop_values are keys.value.packed, npairs, and values.value.refs
+ * for that dictionary; otherwise, these variables point to a dummy
+ * empty dictionary.
+ */
+ const ref_packed *top_keys;
+ uint top_npairs;
+ ref *top_values;
+
+/*
+ * Cache a copy of the bottom entry on the stack, which is never deleted.
+ */
+ ref system_dict;
+
+};
+
+/*
+ * The top-entry pointers are recomputed after garbage collection, so we
+ * don't declare them as pointers.
+ */
+#define public_st_dict_stack() /* in interp.c */\
+ gs_public_st_suffix_add0(st_dict_stack, dict_stack_t, "dict_stack_t",\
+ dict_stack_enum_ptrs, dict_stack_reloc_ptrs, st_ref_stack)
+#define st_dict_stack_num_ptrs st_ref_stack_num_ptrs
+
+#endif /* idsdata_INCLUDED */
diff --git a/gs/src/idstack.c b/gs/src/idstack.c
index a073fe530..67b66d96e 100644
--- a/gs/src/idstack.c
+++ b/gs/src/idstack.c
@@ -31,10 +31,18 @@
/* Debugging statistics */
#ifdef DEBUG
#include "idebug.h"
-long ds_lookups; /* total lookups */
-long ds_1probe; /* successful lookups on only 1 probe */
-long ds_2probe; /* successful lookups on 2 probes */
+#define MAX_STATS_DEPTH 6
+struct stats_dstack_s {
+ long lookups; /* total lookups */
+ long probes[2]; /* successful lookups on 1 or 2 probes */
+ long depth[MAX_STATS_DEPTH + 1]; /* stack depth of lookups requiring search */
+} stats_dstack;
+# define INCR(v) (++stats_dstack.v)
+#else
+# define INCR(v) DO_NOTHING
+#endif
+#ifdef DEBUG
/* Wrapper for dstack_find_name_by_index */
ref *real_dstack_find_name_by_index(P2(dict_stack_t * pds, uint nidx));
ref *
@@ -43,7 +51,7 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
ref *pvalue = real_dstack_find_name_by_index(pds, nidx);
dict *pdict = pds->stack.p->value.pdict;
- ds_lookups++;
+ INCR(lookups);
if (dict_is_packed(pdict)) {
uint hash =
dict_hash_mod(dict_name_index_hash(nidx), npairs(pdict)) + 1;
@@ -51,16 +59,16 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
if (pdict->keys.value.packed[hash] ==
pt_tag(pt_literal_name) + nidx
)
- ds_1probe++;
+ INCR(probes[0]);
else if (pdict->keys.value.packed[hash - 1] ==
pt_tag(pt_literal_name) + nidx
)
- ds_2probe++;
+ INCR(probes[1]);
}
- /* Do the cheap flag test before the expensive remainder test. */
- if (gs_debug_c('d') && !(ds_lookups % 1000))
- dlprintf3("[d]lookups=%ld 1probe=%ld 2probe=%ld\n",
- ds_lookups, ds_1probe, ds_2probe);
+ if (gs_debug_c('d') && !(stats_dstack.lookups % 1000))
+ dlprintf3("[d]lookups=%ld probe1=%ld probe2=%ld\n",
+ stats_dstack.lookups, stats_dstack.probes[0],
+ stats_dstack.probes[1]);
return pvalue;
}
#define dstack_find_name_by_index real_dstack_find_name_by_index
@@ -117,11 +125,13 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
dict_maxlength(pdref));
}
#endif
+#define INCR_DEPTH(pdref)\
+ INCR(depth[min(MAX_STATS_DEPTH, pds->stack.p - pdref)])
if (dict_is_packed(pdict)) {
- packed_search_1(DO_NOTHING,
+ packed_search_1(INCR_DEPTH(pdref),
return packed_search_value_pointer,
DO_NOTHING, goto miss);
- packed_search_2(DO_NOTHING,
+ packed_search_2(INCR_DEPTH(pdref),
return packed_search_value_pointer,
DO_NOTHING, break);
miss:;
@@ -134,9 +144,10 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
for (kp = kbot + dict_hash_mod(hash, size) + 2;;) {
--kp;
if (r_has_type(kp, t_name)) {
- if (name_index(kp) == nidx)
- return pdict->values.value.refs +
- (kp - kbot);
+ if (name_index(kp) == nidx) {
+ INCR_DEPTH(pdref);
+ return pdict->values.value.refs + (kp - kbot);
+ }
} else if (r_has_type(kp, t_null)) { /* Empty, deleted, or wraparound. */
/* Figure out which. */
if (!r_has_attr(kp, a_executable))
@@ -149,6 +160,7 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
}
}
}
+#undef INCR_DEPTH
}
while (pdref-- > pds->stack.bot);
/* The name isn't in the top dictionary block. */
@@ -166,8 +178,10 @@ dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
for (; i < size; i++) {
if (dict_find(ref_stack_index(&pds->stack, i),
&key, &pvalue) > 0
- )
+ ) {
+ INCR(depth[min(MAX_STATS_DEPTH, i)]);
return pvalue;
+ }
}
}
return (ref *) 0;
diff --git a/gs/src/idstack.h b/gs/src/idstack.h
index 4bc55b533..1a6dc6fed 100644
--- a/gs/src/idstack.h
+++ b/gs/src/idstack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,64 +22,10 @@
#ifndef idstack_INCLUDED
# define idstack_INCLUDED
+#include "iddstack.h"
+#include "idsdata.h"
#include "istack.h"
-/* Define the dictionary stack structure. */
-typedef struct dict_stack_s {
-
- ref_stack stack; /* the actual stack of dictionaries */
-
-/*
- * Switching between Level 1 and Level 2 involves inserting and removing
- * globaldict on the dictionary stack. Instead of truly inserting and
- * removing entries, we replace globaldict by a copy of systemdict in
- * Level 1 mode. min_dstack_size, the minimum number of entries, does not
- * change depending on language level; the countdictstack and dictstack
- * operators must take this into account.
- */
- uint min_size; /* size of stack after clearing */
-
- int userdict_index; /* index of userdict on stack */
-
-/*
- * Cache a value for fast checking of def operations.
- * If the top entry on the dictionary stack is a writable dictionary,
- * dsspace is the space of the dictionary; if it is a non-writable
- * dictionary, dsspace = -1. Then def is legal precisely if
- * r_space(pvalue) <= dsspace. Note that in order for this trick to work,
- * the result of r_space must be a signed integer; some compilers treat
- * enums as unsigned, probably in violation of the ANSI standard.
- */
- int def_space;
-
-/*
- * Cache values for fast name lookup. If the top entry on the dictionary
- * stack is a readable dictionary with packed keys, dtop_keys, dtop_npairs,
- * and dtop_values are keys.value.packed, npairs, and values.value.refs
- * for that dictionary; otherwise, these variables point to a dummy
- * empty dictionary.
- */
- const ref_packed *top_keys;
- uint top_npairs;
- ref *top_values;
-
-/*
- * Cache a copy of the bottom entry on the stack, which is never deleted.
- */
- ref system_dict;
-
-} dict_stack_t;
-
-/*
- * Reset the cached top values. Every routine that alters the
- * dictionary stack (including changing the protection or size of the
- * top dictionary on the stack) must call this.
- */
-void dstack_set_top(P1(dict_stack_t *));
-
-/* Check whether a dictionary is one of the permanent ones on the d-stack. */
-bool dstack_dict_is_permanent(P2(const dict_stack_t *, const ref *));
-
/* Define the type of pointers into the dictionary stack. */
typedef s_ptr ds_ptr;
typedef const_s_ptr const_ds_ptr;
diff --git a/gs/src/iesdata.h b/gs/src/iesdata.h
new file mode 100644
index 000000000..7ce915950
--- /dev/null
+++ b/gs/src/iesdata.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Generic execution stack structure definition */
+
+#ifndef iesdata_INCLUDED
+# define iesdata_INCLUDED
+
+#include "isdata.h"
+
+/* Define the execution stack structure. */
+typedef struct exec_stack_s {
+
+ ref_stack_t stack; /* the actual execution stack */
+
+/*
+ * To improve performance, we cache the currentfile pointer
+ * (i.e., `shallow-bind' it in Lisp terminology). The invariant is as
+ * follows: either esfile points to the currentfile slot on the estack
+ * (i.e., the topmost slot with an executable file), or it is 0.
+ * To maintain the invariant, it is sufficient that whenever a routine
+ * pushes or pops anything on the estack, if the object *might* be
+ * an executable file, invoke esfile_clear_cache(); alternatively,
+ * immediately after pushing an object, invoke esfile_check_cache().
+ */
+ ref *current_file;
+
+} exec_stack_t;
+
+/*
+ * current_file is cleared by garbage collection, so we don't declare it
+ * as a pointer.
+ */
+#define public_st_exec_stack() /* in interp.c */\
+ gs_public_st_suffix_add0(st_exec_stack, exec_stack_t, "exec_stack_t",\
+ exec_stack_enum_ptrs, exec_stack_reloc_ptrs, st_ref_stack)
+#define st_exec_stack_num_ptrs st_ref_stack_num_ptrs
+
+#endif /* iesdata_INCLUDED */
diff --git a/gs/src/iestack.h b/gs/src/iestack.h
index 8553918b7..982e79a5c 100644
--- a/gs/src/iestack.h
+++ b/gs/src/iestack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,29 +22,20 @@
#ifndef iestack_INCLUDED
# define iestack_INCLUDED
+#include "iesdata.h"
#include "istack.h"
-/* Define the execution stack structure. */
-typedef struct exec_stack_s {
-
- ref_stack stack; /* the actual execution stack */
-
-/*
- * To improve performance, we cache the currentfile pointer
- * (i.e., `shallow-bind' it in Lisp terminology). The invariant is as
- * follows: either esfile points to the currentfile slot on the estack
- * (i.e., the topmost slot with an executable file), or it is 0.
- * To maintain the invariant, it is sufficient that whenever a routine
- * pushes or pops anything on the estack, if the object *might* be
- * an executable file, invoke esfile_clear_cache(); alternatively,
- * immediately after pushing an object, invoke esfile_check_cache().
- */
- ref *current_file;
-
-} exec_stack_t;
-
/* Define pointers into the execution stack. */
typedef s_ptr es_ptr;
typedef const_s_ptr const_es_ptr;
+/* Manage the current_file cache. */
+#define estack_clear_cache(pes) ((pes)->current_file = 0)
+#define estack_set_cache(pes,pref) ((pes)->current_file = (pref))
+#define estack_check_cache(pes)\
+ BEGIN\
+ if (r_has_type_attrs((pes)->stack.p, t_file, a_executable))\
+ estack_set_cache(pes, (pes)->stack.p);\
+ END
+
#endif /* iestack_INCLUDED */
diff --git a/gs/src/ifilter.h b/gs/src/ifilter.h
index 53fabdce3..e1612d798 100644
--- a/gs/src/ifilter.h
+++ b/gs/src/ifilter.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,28 +31,31 @@
* and all relevant parameters (if any) are in global VM.
*/
int filter_read(P5(
- /* Operand stack pointer that was passed to zfxxx operator */
- os_ptr op,
+ /* Operator arguments that were passed to zfxxx operator */
+ i_ctx_t *i_ctx_p,
/* # of parameters to pop off o-stack, */
/* not counting the source/target */
- int npop,
+ int npop,
/* Template for stream */
- const stream_template * template,
+ const stream_template * template,
/* Initialized s_xxx_state, 0 if no separate state */
- stream_state * st,
+ stream_state * st,
/* Max of space attributes of all parameters referenced by */
/* the state, 0 if no such parameters */
- uint space
+ uint space
));
-int filter_write(P5(os_ptr op, int npop, const stream_template * template,
+int filter_write(P5(i_ctx_t *i_ctx_p, int npop,
+ const stream_template * template,
stream_state * st, uint space));
/*
* Define a simplified interface for streams with no parameters or state.
* These procedures also pop the top o-stack element if it is a dictionary.
*/
-int filter_read_simple(P2(os_ptr op, const stream_template * template));
-int filter_write_simple(P2(os_ptr op, const stream_template * template));
+int filter_read_simple(P2(i_ctx_t *i_ctx_p,
+ const stream_template * template));
+int filter_write_simple(P2(i_ctx_t *i_ctx_p,
+ const stream_template * template));
/* Mark a filter stream as temporary. */
/* See stream.h for the meaning of is_temp. */
diff --git a/gs/src/ifont.h b/gs/src/ifont.h
index d587379b2..16fbd41af 100644
--- a/gs/src/ifont.h
+++ b/gs/src/ifont.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1991, 1993, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1991, 1993, 1994, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,7 +23,7 @@
# define ifont_INCLUDED
#include "gsccode.h" /* for gs_glyph */
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
/* The external definition of fonts is given in the PostScript manual, */
/* pp. 91-93. */
@@ -60,7 +60,7 @@ typedef struct font_data_s {
*/
/* st_font_data is exported for zdefault_make_font in zfont.c. */
extern_st(st_font_data);
-#define public_st_font_data() /* in zfont2.c */\
+#define public_st_font_data() /* in zbfont.c */\
gs_public_st_ref_struct(st_font_data, font_data, "font_data")
#define pfont_data(pfont) ((font_data *)((pfont)->client_data))
#define pfont_dict(pfont) (&pfont_data(pfont)->dict)
diff --git a/gs/src/ifont1.h b/gs/src/ifont1.h
new file mode 100644
index 000000000..a83b5452f
--- /dev/null
+++ b/gs/src/ifont1.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Type 1 font utilities shared with Type 2 */
+
+#ifndef ifont1_INCLUDED
+# define ifont1_INCLUDED
+
+/*
+ * Define the temporary structure for holding pointers to substructures of a
+ * CharString-based font. This is used for parsing Type 1, 2, and 4 fonts.
+ */
+typedef struct charstring_font_refs_s {
+ ref *Private;
+ ref no_subrs;
+ ref *OtherSubrs;
+ ref *Subrs;
+ ref *GlobalSubrs;
+} charstring_font_refs_t;
+
+/*
+ * Parse the substructures of a CharString-based font.
+ */
+int charstring_font_get_refs(P2(os_ptr op, charstring_font_refs_t *pfr));
+
+/*
+ * Finish building a CharString-based font. The client has filled in
+ * pdata1->interpret, subroutineNumberBias, lenIV, and (if applicable)
+ * the Type 2 elements.
+ */
+int build_charstring_font(P7(i_ctx_t *i_ctx_p, os_ptr op,
+ build_proc_refs * pbuild, font_type ftype,
+ charstring_font_refs_t *pfr,
+ gs_type1_data *pdata1,
+ build_font_options_t options));
+
+#endif /* ifont1_INCLUDED */
diff --git a/gs/src/ifunc.h b/gs/src/ifunc.h
index 949e494ba..88d46270e 100644
--- a/gs/src/ifunc.h
+++ b/gs/src/ifunc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,14 +22,21 @@
#ifndef ifunc_INCLUDED
# define ifunc_INCLUDED
+#include "gsfunc.h"
+
/* Define build procedures for the various function types. */
#define build_function_proc(proc)\
- int proc(P4(const_os_ptr op, const gs_function_params_t *params, int depth,\
+ int proc(P4(const ref *op, const gs_function_params_t *params, int depth,\
gs_function_t **ppfn))
-build_function_proc(build_function_undefined);
+typedef build_function_proc((*build_function_proc_t));
/* Define the table of build procedures, indexed by FunctionType. */
-extern build_function_proc((*build_function_procs[5]));
+typedef struct build_function_type_s {
+ int type;
+ build_function_proc_t proc;
+} build_function_type_t;
+extern const build_function_type_t build_function_type_table[];
+extern const uint build_function_type_table_count;
/* Build a function structure from a PostScript dictionary. */
int fn_build_sub_function(P3(const ref * op, gs_function_t ** ppfn, int depth));
diff --git a/gs/src/igc.c b/gs/src/igc.c
index 831446d34..2c407d62b 100644
--- a/gs/src/igc.c
+++ b/gs/src/igc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -150,7 +150,7 @@ depth_dots(const ms_entry * sp, const gc_mark_stack * pms)
# define end_phase(str) DO_NOTHING
#endif
void
-gs_reclaim(vm_spaces * pspaces, bool global)
+gs_gc_reclaim(vm_spaces * pspaces, bool global)
{
vm_spaces spaces;
@@ -186,7 +186,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
#define for_collected_spaces(i)\
for ( i = min_collect; i <= max_trace; ++i )
#define for_space_mems(i, mem)\
- for ( mem = spaces.indexed[i]; mem != 0; mem = &mem->saved->state )
+ for ( mem = spaces_indexed[i]; mem != 0; mem = &mem->saved->state )
#define for_mem_chunks(mem, cp)\
for ( cp = (mem)->cfirst; cp != 0; cp = cp->cnext )
#define for_space_chunks(i, mem, cp)\
@@ -197,11 +197,11 @@ gs_reclaim(vm_spaces * pspaces, bool global)
for_collected_spaces(ispace) for_space_chunks(ispace, mem, cp)
#define for_roots(n, mem, rp)\
for_spaces(ispace, n)\
- for ( mem = spaces.indexed[ispace], rp = mem->roots; rp != 0; rp = rp->next )
+ for ( mem = spaces_indexed[ispace], rp = mem->roots; rp != 0; rp = rp->next )
/* Initialize the state. */
state.procs = &igc_procs;
- state.loc.memory = spaces.named.global; /* any one will do */
+ state.loc.memory = space_global; /* any one will do */
state.loc.cp = 0;
state.spaces = spaces;
@@ -214,9 +214,9 @@ gs_reclaim(vm_spaces * pspaces, bool global)
/* so we mark and relocate the change and save lists properly. */
for_spaces(ispace, max_trace)
- gs_register_struct_root((gs_memory_t *) spaces.indexed[ispace],
+ gs_register_struct_root((gs_memory_t *) spaces_indexed[ispace],
&space_roots[ispace],
- (void **)&spaces.indexed[ispace],
+ (void **)&spaces_indexed[ispace],
"gc_top_level");
end_phase("register space roots");
@@ -226,7 +226,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
/* Pre-validate the state. This shouldn't be necessary.... */
for_spaces(ispace, max_trace)
- ialloc_validate_memory(spaces.indexed[ispace], &state);
+ ialloc_validate_memory(spaces_indexed[ispace], &state);
end_phase("pre-validate pointers");
@@ -376,7 +376,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
int i;
for_collected_spaces(i)
- gs_enable_free((gs_memory_t *) spaces.indexed[i], false);
+ gs_enable_free((gs_memory_t *) spaces_indexed[i], false);
}
/* Compute relocation based on marks, in the spaces */
@@ -392,7 +392,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
int i;
for_collected_spaces(i)
- gs_enable_free((gs_memory_t *) spaces.indexed[i], true);
+ gs_enable_free((gs_memory_t *) spaces_indexed[i], true);
}
end_phase("set reloc");
@@ -467,7 +467,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
alloc_save_t *next;
gs_memory_status_t total;
- for (curr = spaces.indexed[ispace]->saved; curr != 0;
+ for (curr = spaces_indexed[ispace]->saved; curr != 0;
prev = curr, curr = next
) {
next = curr->state.saved;
@@ -489,7 +489,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
mem->gc_allocated = mem->allocated + total.allocated;
mem->inherited = -mem->allocated;
}
- mem = spaces.indexed[ispace];
+ mem = spaces_indexed[ispace];
mem->previous_status = total;
mem->gc_allocated = mem->allocated + total.allocated;
if_debug3('6', "[6]0x%lx previous allocated=%lu, used=%lu\n",
@@ -503,7 +503,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
/* Unregister the allocator roots. */
for_spaces(ispace, max_trace)
- gs_unregister_root((gs_memory_t *) spaces.indexed[ispace],
+ gs_unregister_root((gs_memory_t *) spaces_indexed[ispace],
&space_roots[ispace], "gc_top_level");
end_phase("unregister space roots");
@@ -513,7 +513,7 @@ gs_reclaim(vm_spaces * pspaces, bool global)
/* Validate the state. This shouldn't be necessary.... */
for_spaces(ispace, max_trace)
- ialloc_validate_memory(spaces.indexed[ispace], &state);
+ ialloc_validate_memory(spaces_indexed[ispace], &state);
end_phase("validate pointers");
@@ -913,14 +913,23 @@ gc_trace(gs_gc_root_t * rp, gc_state_t * pstate, gc_mark_stack * pmstack)
}
rrp:
rrc:sp[1].is_refs = true;
- if (sp == stop)
+ if (sp == stop) {
+ /*
+ * The following initialization is unnecessary:
+ * ptp will not be used if sp[1].is_refs = true.
+ * We put this here solely to get rid of bogus
+ * "possibly uninitialized variable" warnings
+ * from certain compilers.
+ */
+ ptp = ptr_ref_type;
break;
+ }
new |= 1;
(++sp)->ptr = nptr;
goto do_refs;
case t_mixedarray:
case t_shortarray:
- nptr = (void *)rptr->value.packed; /* discard const */
+ nptr = rptr->value.writable_packed;
goto rr;
case t_name:
mark_name(names_index(nt, rptr), rptr->value.pname);
@@ -931,7 +940,7 @@ gc_trace(gs_gc_root_t * rp, gc_state_t * pstate, gc_mark_stack * pmstack)
new |= 1;
goto nr;
case t_oparray:
- nptr = (void *)rptr->value.const_refs; /* discard const */
+ nptr = rptr->value.refs; /* discard const */
sp[1].index = 1;
goto rrc;
default:
@@ -1185,11 +1194,11 @@ gc_do_reloc(chunk_t * cp, gs_ref_memory_t * mem, gc_state_t * pstate)
/* Print pointer relocation if debugging. */
/* We have to provide this procedure even if DEBUG is not defined, */
/* in case one of the other GC modules was compiled with DEBUG. */
-void *
-print_reloc_proc(const void *obj, const char *cname, void *robj)
+const void *
+print_reloc_proc(const void *obj, const char *cname, const void *robj)
{
if_debug3('9', " [9]relocate %s * 0x%lx to 0x%lx\n",
- cname, (ulong) obj, (ulong) robj);
+ cname, (ulong)obj, (ulong)robj);
return robj;
}
@@ -1201,8 +1210,10 @@ igc_reloc_struct_ptr(const void /*obj_header_t */ *obj, gc_state_t * gcst)
const obj_header_t *const optr = (const obj_header_t *)obj;
const void *robj;
- if (obj == 0)
- return print_reloc(obj, "NULL", 0);
+ if (obj == 0) {
+ discard(print_reloc(obj, "NULL", 0));
+ return 0;
+ }
debug_check_object(optr - 1, NULL, gcst);
/* The following should be a conditional expression, */
/* but Sun's cc compiler can't handle it. */
@@ -1236,9 +1247,13 @@ igc_reloc_struct_ptr(const void /*obj_header_t */ *obj, gc_state_t * gcst)
}
}
}
- return print_reloc(obj,
- struct_type_name_string(optr[-1].o_type),
- (void *)robj); /* discard const */
+ /* Use a severely deprecated pun to remove the const property. */
+ {
+ union { const void *r; void *w; } u;
+
+ u.r = print_reloc(obj, struct_type_name_string(optr[-1].o_type), robj);
+ return u.w;
+ }
}
/* ------ Compaction phase ------ */
diff --git a/gs/src/igc.h b/gs/src/igc.h
index 55cccdf01..565432b94 100644
--- a/gs/src/igc.h
+++ b/gs/src/igc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,9 @@
#include "istruct.h"
+/* Declare the vm_reclaim procedure for the real GC. */
+extern vm_reclaim_proc(gs_gc_reclaim);
+
/* Define the procedures shared among a "genus" of structures. */
/* Currently there are only two genera: refs, and all other structures. */
struct struct_shared_procs_s {
@@ -52,11 +55,10 @@ struct struct_shared_procs_s {
};
/* Define the structure for holding GC state. */
- /*typedef struct gc_state_s gc_state_t; *//* in gsstruct.h */
+/*typedef struct gc_state_s gc_state_t; *//* in gsstruct.h */
#ifndef name_table_DEFINED
# define name_table_DEFINED
typedef struct name_table_s name_table;
-
#endif
struct gc_state_s {
const gc_procs_with_refs_t *procs; /* must be first */
@@ -83,14 +85,12 @@ void ialloc_validate_object(P3(const obj_header_t *, const chunk_t *,
/* Macro for returning a relocated pointer */
#ifdef DEBUG
-void *print_reloc_proc(P3(const void *obj, const char *cname, void *robj));
-
+const void *print_reloc_proc(P3(const void *obj, const char *cname,
+ const void *robj));
# define print_reloc(obj, cname, nobj)\
- (gs_debug_c('9') ? print_reloc_proc(obj, cname, nobj) :\
- (void *)(nobj))
+ (gs_debug_c('9') ? print_reloc_proc(obj, cname, nobj) : nobj)
#else
-# define print_reloc(obj, cname, nobj)\
- (void *)(nobj)
+# define print_reloc(obj, cname, nobj) (nobj)
#endif
#endif /* igc_INCLUDED */
diff --git a/gs/src/igcref.c b/gs/src/igcref.c
index 78f4fc24c..1ed921859 100644
--- a/gs/src/igcref.c
+++ b/gs/src/igcref.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -221,10 +221,10 @@ refs_set_reloc(obj_header_t * hdr, uint reloc, uint size)
*/
#define all_marked (align_packed_per_ref * lp_mark)
# if align_packed_per_ref == 2
-# if arch_sizeof_long == arch_sizeof_short * 2
+# if arch_sizeof_int == arch_sizeof_short * 2
# undef all_marked
-# define all_marked ( ((long)lp_mark << (sizeof(short) * 8)) + lp_mark )
-# define marked (*(long *)rp & all_marked)
+# define all_marked ( (lp_mark << (sizeof(short) * 8)) + lp_mark )
+# define marked (*(int *)rp & all_marked)
# else
# define marked ((*rp & lp_mark) + (rp[1] & lp_mark))
# endif
@@ -233,7 +233,12 @@ refs_set_reloc(obj_header_t * hdr, uint reloc, uint size)
# define marked ((*rp & lp_mark) + (rp[1] & lp_mark) +\
(rp[2] & lp_mark) + (rp[3] & lp_mark))
# else
- uint marked = *rp & lp_mark;
+ /*
+ * The value of marked is logically a uint, not an int:
+ * we declare it as int only to avoid a compiler warning
+ * message about using a non-int value in a switch statement.
+ */
+ int marked = *rp & lp_mark;
for (i = 1; i < align_packed_per_ref; i++)
marked += rp[i] & lp_mark;
@@ -511,11 +516,11 @@ igc_reloc_refs(ref_packed * from, ref_packed * to, gc_state_t * gcst)
/* See gsmemory.h for why the argument is const and the result is not. */
ref_packed *
igc_reloc_ref_ptr(const ref_packed * prp, gc_state_t * ignored)
-{ /*
- * Search forward for relocation. This algorithm is intrinsically
- * very inefficient; we hope eventually to replace it with a better
- * one.
- */
+{
+ /*
+ * Search forward for relocation. This algorithm is intrinsically very
+ * inefficient; we hope eventually to replace it with a better one.
+ */
register const ref_packed *rp = prp;
uint dec = 0;
@@ -526,28 +531,30 @@ igc_reloc_ref_ptr(const ref_packed * prp, gc_state_t * ignored)
*/
if (r_is_packed(rp)) {
if (!r_has_pmark(rp))
- return (ref_packed *) rp;
+ goto ret_rp;
} else {
if (!r_has_attr((const ref *)rp, l_mark))
- return (ref_packed *) rp;
+ goto ret_rp;
}
for (;;) {
- if (r_is_packed(rp)) { /*
- * Normally, an unmarked packed ref will be an
- * integer whose value is the amount of relocation.
- * However, the relocation value might have been
- * too large to fit. If this is the case, for
- * each such unmarked packed ref we pass over,
- * we have to decrement the final relocation.
- */
+ if (r_is_packed(rp)) {
+ /*
+ * Normally, an unmarked packed ref will be an
+ * integer whose value is the amount of relocation.
+ * However, the relocation value might have been
+ * too large to fit. If this is the case, for
+ * each such unmarked packed ref we pass over,
+ * we have to decrement the final relocation.
+ */
rputc((*rp & lp_mark ? '1' : '0'));
if (!(*rp & lp_mark)) {
if (*rp != pt_tag(pt_integer) + packed_max_value) { /* This is a stored relocation value. */
rputc('\n');
- return print_reloc(prp, "ref",
- (ref_packed *)
- ((const char *)prp -
- (*rp & packed_value_mask) + dec));
+ rp = print_reloc(prp, "ref",
+ (const ref_packed *)
+ ((const char *)prp -
+ (*rp & packed_value_mask) + dec));
+ break;
}
/*
* We know this is the first of an aligned block
@@ -562,14 +569,23 @@ igc_reloc_ref_ptr(const ref_packed * prp, gc_state_t * ignored)
}
if (!ref_type_uses_size_or_null(r_type((const ref *)rp))) { /* reloc is in r_size */
rputc('\n');
- return print_reloc(prp, "ref",
- (ref_packed *)
- (r_size((const ref *)rp) == 0 ? prp :
- (const ref_packed *)((const char *)prp - r_size((const ref *)rp) + dec)));
+ rp = print_reloc(prp, "ref",
+ (const ref_packed *)
+ (r_size((const ref *)rp) == 0 ? prp :
+ (const ref_packed *)((const char *)prp - r_size((const ref *)rp) + dec)));
+ break;
}
rputc('u');
rp += packed_per_ref;
}
+ret_rp:
+ /* Use a severely deprecated pun to remove the const property. */
+ {
+ union { const ref_packed *r; ref_packed *w; } u;
+
+ u.r = rp;
+ return u.w;
+ }
}
/* ------ Compaction phase ------ */
diff --git a/gs/src/igcstr.c b/gs/src/igcstr.c
index 66f04b4d6..74a6a44c0 100644
--- a/gs/src/igcstr.c
+++ b/gs/src/igcstr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -313,7 +313,7 @@ gc_strings_compact(chunk_t * cp)
if (gs_debug_c('4') || gs_debug_c('5')) {
byte *base = cp->sbase;
uint i = (lo - base) & -string_data_quantum;
- uint n = round_up(hi - base, string_data_quantum);
+ uint n = ROUND_UP(hi - base, string_data_quantum);
#define R 16
for (; i < n; i += R) {
diff --git a/gs/src/igstate.h b/gs/src/igstate.h
index 7dfcd2e28..85246b4d8 100644
--- a/gs/src/igstate.h
+++ b/gs/src/igstate.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,7 @@
#include "gsstate.h"
#include "gxstate.h" /* for 'client data' access */
+#include "imemory.h"
#include "istruct.h" /* for gstate obj definition */
/*
@@ -99,14 +100,21 @@ typedef struct ref_color_procs_s {
} special;
} ref_color_procs;
typedef struct ref_colorspace_s {
- ref array; /* color space (array), */
- /* only relevant if the current */
- /* color space has parameters associated with it. */
+ ref array; /* color space (array), only relevant if */
+ /* the current color space has parameters */
+ /* associated with it. */
ref_color_procs procs; /* associated procedures/parameters, */
- /* only relevant for DeviceN, CIE, Separation, Indexed/CIE, */
- /* Indexed with procedure, or a Pattern with one of these. */
+ /* only relevant for DeviceN, CIE, */
+ /* Separation, Indexed/CIE, */
+ /* Indexed with procedure, or a Pattern */
+ /* with one of these. */
} ref_colorspace;
+#ifndef int_remap_color_info_DEFINED
+# define int_remap_color_info_DEFINED
+typedef struct int_remap_color_info_s int_remap_color_info_t;
+#endif
+
typedef struct int_gstate_s {
ref dash_pattern; /* (array) */
/* Screen_procs are only relevant if setscreen was */
@@ -123,23 +131,40 @@ typedef struct int_gstate_s {
ref black_generation; /* (procedure) */
ref undercolor_removal; /* (procedure) */
ref_colorspace colorspace;
- /* Pattern is only relevant if the current color space */
- /* is a pattern space. */
+ /*
+ * Pattern is relevant only if the current color space
+ * is a pattern space.
+ */
ref pattern; /* pattern (dictionary) */
struct {
ref dict; /* CIE color rendering dictionary */
ref_cie_render_procs procs; /* (see above) */
} colorrendering;
- /* Halftone is only relevant if sethalftone was executed */
- /* more recently than setscreen for this graphics context. */
- /* setscreen sets it to null. */
+ /*
+ * Halftone is relevant only if sethalftone was executed
+ * more recently than setscreen for this graphics context.
+ * setscreen sets it to null.
+ */
ref halftone; /* halftone (dictionary) */
- /* Pagedevice is only relevant if setpagedevice was */
- /* executed more recently than nulldevice, setcachedevice, */
- /* or setdevice with a non-page device (for this */
- /* graphics context). If the current device is not a */
- /* page device, pagedevice is null. */
+ /*
+ * Pagedevice is only relevant if setpagedevice was executed more
+ * recently than nulldevice, setcachedevice, or setdevice with a
+ * non-page device (for this graphics context). If the current device
+ * is not a page device, pagedevice is null.
+ */
ref pagedevice; /* page device (dictionary|null) */
+ /*
+ * Remap_color_info is used temporarily to communicate the need for
+ * Pattern or DeviceNcolor remapping to the interpreter. See
+ * e_RemapColor in errors.h. The extra level of indirection through a
+ * structure is needed because the gstate passed to the PaintProc is
+ * different from the current gstate in the graphics state, and because
+ * the DeviceN color being remapped is not necessarily the current color
+ * in the graphics state (for shading or images): the structure is
+ * shared, so that the interpreter can get its hands on the remapping
+ * procedure.
+ */
+ ref remap_color_info; /* t_struct (int_remap_color_info_t) */
} int_gstate;
#define clear_pagedevice(pigs) make_null(&(pigs)->pagedevice)
@@ -162,14 +187,13 @@ typedef struct int_gstate_s {
/* Create the gstate for a new context. */
/* We export this so that fork can use it. */
-gs_state *int_gstate_alloc(P1(gs_ref_memory_t * mem));
+gs_state *int_gstate_alloc(P1(const gs_dual_memory_t * dmem));
/* Get the int_gstate from a gs_state. */
#define gs_int_gstate(pgs) ((int_gstate *)gs_state_client_data(pgs))
-/* The current instances. */
-extern gs_state *igs;
-
+/* The current instances for operators. */
+#define igs (i_ctx_p->pgs)
#define istate gs_int_gstate(igs)
#endif /* igstate_INCLUDED */
diff --git a/gs/src/iht.h b/gs/src/iht.h
index 6e7937ce5..ab3bbeb05 100644
--- a/gs/src/iht.h
+++ b/gs/src/iht.h
@@ -24,8 +24,8 @@
int zscreen_params(P2(os_ptr op, gs_screen_halftone * phs));
-int zscreen_enum_init(P7(os_ptr op, const gx_ht_order * porder,
+int zscreen_enum_init(P7(i_ctx_t *i_ctx_p, const gx_ht_order * porder,
gs_screen_halftone * phs, ref * pproc, int npop,
- int (*finish_proc) (P1(os_ptr)), gs_memory_t * mem));
+ op_proc_t finish_proc, gs_memory_t * mem));
#endif /* iht_INCLUDED */
diff --git a/gs/src/iimage.h b/gs/src/iimage.h
index f444230ac..4636fc5c0 100644
--- a/gs/src/iimage.h
+++ b/gs/src/iimage.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,15 +25,16 @@
/* These procedures are exported by zimage.c for other modules. */
/* Exported for zcolor1.c and zdpnext.c */
-int zimage_opaque_setup(P5(os_ptr op, bool multi, gs_image_alpha_t alpha,
- const gs_color_space * pcs, int npop));
+int zimage_opaque_setup(P6(i_ctx_t *i_ctx_p, os_ptr op, bool multi,
+ gs_image_alpha_t alpha, const gs_color_space * pcs,
+ int npop));
/* Exported for zimage2.c */
-int zimage_setup(P4(const gs_pixel_image_t * pim, const ref * sources,
- bool uses_color, int npop));
+int zimage_setup(P5(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
+ const ref * sources, bool uses_color, int npop));
/* Exported for zcolor3.c */
-int zimage_data_setup(P4(const gs_pixel_image_t * pim,
+int zimage_data_setup(P5(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
gx_image_enum_common_t * pie,
const ref * sources, int npop));
diff --git a/gs/src/iimage2.h b/gs/src/iimage2.h
index 56094c15b..e8e5969f1 100644
--- a/gs/src/iimage2.h
+++ b/gs/src/iimage2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,10 +35,11 @@ typedef struct image_params_s {
} image_params;
/* Extract and check parameters for an image. */
-int data_image_params(P6(const ref * op, gs_data_image_t * pim,
- image_params * pip, bool require_DataSource,
+int data_image_params(P6(const ref *op, gs_data_image_t *pim,
+ image_params *pip, bool require_DataSource,
int num_components, int max_bits_per_component));
-int pixel_image_params(P4(const ref * op, gs_pixel_image_t * pim,
- image_params * pip, int max_bits_per_component));
+int pixel_image_params(P5(i_ctx_t *i_ctx_p, const ref *op,
+ gs_pixel_image_t *pim, image_params * pip,
+ int max_bits_per_component));
#endif /* iimage2_INCLUDED */
diff --git a/gs/src/iinit.c b/gs/src/iinit.c
index dc0c13641..5814d9484 100644
--- a/gs/src/iinit.c
+++ b/gs/src/iinit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,7 +25,7 @@
#include "gsstruct.h"
#include "errors.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "dstack.h"
#include "ilevel.h"
#include "iname.h"
@@ -48,10 +48,10 @@
*/
/* The size of systemdict can be set in the makefile. */
#ifndef SYSTEMDICT_SIZE
-# define SYSTEMDICT_SIZE 601
+# define SYSTEMDICT_SIZE 631
#endif
#ifndef SYSTEMDICT_LEVEL2_SIZE
-# define SYSTEMDICT_LEVEL2_SIZE 941
+# define SYSTEMDICT_LEVEL2_SIZE 983
#endif
/* The size of level2dict, if applicable, can be set in the makefile. */
#ifndef LEVEL2DICT_SIZE
@@ -85,15 +85,14 @@ const char *const gs_error_names[] =
};
/* The operator tables */
-const op_def **op_def_table;
-uint op_def_count;
op_array_table op_array_table_global, op_array_table_local; /* definitions of `operator' procedures */
/* Enter a name and value into a dictionary. */
void
-initial_enter_name_in(const char *nstr, const ref * pref, ref * pdict)
+i_initial_enter_name_in(i_ctx_t *i_ctx_p, ref *pdict, const char *nstr,
+ const ref * pref)
{
- int code = dict_put_string(pdict, nstr, pref);
+ int code = idict_put_string(pdict, nstr, pref);
if (code < 0) {
lprintf4("initial_enter failed (%d), entering /%s in -dict:%u/%u-\n",
@@ -102,19 +101,19 @@ initial_enter_name_in(const char *nstr, const ref * pref, ref * pdict)
}
}
void
-initial_enter_name(const char *nstr, const ref * pref)
+i_initial_enter_name(i_ctx_t *i_ctx_p, const char *nstr, const ref * pref)
{
- initial_enter_name_in(nstr, pref, systemdict);
+ i_initial_enter_name_in(i_ctx_p, systemdict, nstr, pref);
}
/* Remove a name from systemdict. */
void
-initial_remove_name(const char *nstr)
+i_initial_remove_name(i_ctx_t *i_ctx_p, const char *nstr)
{
ref nref;
if (name_ref((const byte *)nstr, strlen(nstr), &nref, -1) >= 0)
- dict_undef(systemdict, &nref);
+ idict_undef(systemdict, &nref);
}
/* Create a name. Fatal error if it fails. */
@@ -190,7 +189,7 @@ gs_have_level2(void)
/* Create an initial dictionary if necessary. */
private ref *
-make_initial_dict(const char *iname, ref idicts[])
+make_initial_dict(i_ctx_t *i_ctx_p, const char *iname, ref idicts[])
{
int i;
@@ -206,8 +205,8 @@ make_initial_dict(const char *iname, ref idicts[])
if (r_has_type(dref, t_null)) {
gs_ref_memory_t *mem =
- (initial_dictionaries[i].local ?
- iimemory_local : iimemory_global);
+ (initial_dictionaries[i].local ?
+ iimemory_local : iimemory_global);
int code = dict_alloc(mem, dsize, dref);
if (code < 0)
@@ -227,12 +226,11 @@ make_initial_dict(const char *iname, ref idicts[])
/* Initialize objects other than operators. In particular, */
/* initialize the dictionaries that hold operator definitions. */
void
-obj_init(void)
+obj_init(i_ctx_t **pi_ctx_p)
{
bool level2 = gs_have_level2();
-
- /* Initialize the language level. */
- make_int(&ref_language_level, 1);
+ ref system_dict;
+ i_ctx_t *i_ctx_p;
/*
* Create systemdict. The context machinery requires that
@@ -240,10 +238,11 @@ obj_init(void)
*/
dict_alloc(iimemory_global,
(level2 ? SYSTEMDICT_LEVEL2_SIZE : SYSTEMDICT_SIZE),
- systemdict);
+ &system_dict);
/* Initialize the interpreter. */
- gs_interp_init();
+ gs_interp_init(pi_ctx_p, &system_dict);
+ i_ctx_p = *pi_ctx_p;
{
#define icount countof(initial_dictionaries)
@@ -261,12 +260,12 @@ obj_init(void)
/*
* For the moment, let globaldict be an alias for systemdict.
*/
- dsp[-1] = *systemdict;
+ dsp[-1] = system_dict;
min_dstack_size++;
} else {
++dsp;
}
- *dsp = *systemdict;
+ *dsp = system_dict;
/* Create dictionaries which are to be homes for operators. */
for (tptr = op_defs_all; *tptr != 0; tptr++) {
@@ -274,7 +273,7 @@ obj_init(void)
for (def = *tptr; def->oname != 0; def++)
if (op_def_is_begin_dict(def))
- make_initial_dict(def->oname, idicts);
+ make_initial_dict(i_ctx_p, def->oname, idicts);
}
/* Set up the initial dstack. */
@@ -284,7 +283,7 @@ obj_init(void)
++dsp;
if (!strcmp(dname, "userdict"))
dstack_userdict_index = dsp - dsbot;
- ref_assign(dsp, make_initial_dict(dname, idicts));
+ ref_assign(dsp, make_initial_dict(i_ctx_p, dname, idicts));
}
/* Enter names of referenced initial dictionaries into systemdict. */
@@ -292,15 +291,16 @@ obj_init(void)
for (i = 0; i < icount; i++) {
ref *idict = &idicts[i];
- if (!r_has_type(idict, t_null)) { /*
- * Note that we enter the dictionary in systemdict
- * even if it is in local VM. There is a special
- * provision in the garbage collector for this:
- * see ivmspace.h for more information.
- * In order to do this, we must temporarily
- * identify systemdict as local, so that the
- * store check in dict_put won't fail.
- */
+ if (!r_has_type(idict, t_null)) {
+ /*
+ * Note that we enter the dictionary in systemdict
+ * even if it is in local VM. There is a special
+ * provision in the garbage collector for this:
+ * see ivmspace.h for more information.
+ * In order to do this, we must temporarily
+ * identify systemdict as local, so that the
+ * store check in dict_put won't fail.
+ */
uint save_space = r_space(systemdict);
r_set_space(systemdict, avm_local);
@@ -312,7 +312,7 @@ obj_init(void)
#undef icount
}
- gs_interp_reset();
+ gs_interp_reset(i_ctx_p);
{
ref vtemp;
@@ -341,7 +341,7 @@ obj_init(void)
/* Run the initialization procedures of the individual operator files. */
void
-zop_init(void)
+zop_init(i_ctx_t *i_ctx_p)
{
const op_def *const *tptr;
@@ -352,8 +352,15 @@ zop_init(void)
for (tptr = op_defs_all; *tptr != 0; tptr++) {
for (def = *tptr; def->oname != 0; def++)
DO_NOTHING;
- if (def->proc != 0)
- ((void (*)(P0()))(def->proc)) ();
+ if (def->proc != 0) {
+ int code = def->proc(i_ctx_p);
+
+ if (code < 0) {
+ lprintf2("op_init proc 0x%lx returned error %d!\n",
+ (ulong)def->proc, code);
+ gs_exit(1);
+ }
+ }
}
/* Initialize the predefined names other than operators. */
@@ -403,36 +410,16 @@ alloc_op_array_table(uint size, uint space, op_array_table * opt)
/* Initialize the operator table. */
void
-op_init(void)
+op_init(i_ctx_t *i_ctx_p)
{
- int count = 1;
const op_def *const *tptr;
- const op_def *def;
- const char *nstr;
-
- /* Do a first pass just to count the operators. */
-
- for (tptr = op_defs_all; *tptr != 0; tptr++) {
- for (def = *tptr; def->oname != 0; def++)
- if (!op_def_is_begin_dict(def))
- count++;
- }
- /* Do a second pass to construct the operator table, */
- /* and enter the operators into the appropriate dictionary. */
+ /* Enter each operator into the appropriate dictionary. */
- /* Because of a bug in Sun's SC1.0 compiler, */
- /* we have to spell out the typedef for op_def_ptr here: */
- op_def_table =
- (const op_def **)ialloc_byte_array(count, sizeof(const op_def *),
- "op_init(op_def_table)");
-
- op_def_count = count;
- for (count = 0; count <= gs_interp_num_special_ops; count++)
- op_def_table[count] = 0;
- count = gs_interp_num_special_ops + 1; /* leave space for magic entries */
for (tptr = op_defs_all; *tptr != 0; tptr++) {
ref *pdict = systemdict;
+ const op_def *def;
+ const char *nstr;
for (def = *tptr; (nstr = def->oname) != 0; def++)
if (op_def_is_begin_dict(def)) {
@@ -448,33 +435,27 @@ op_init(void)
gs_abort();
} else {
ref oper;
- uint opidx;
+ uint index_in_table = def - *tptr;
+ uint opidx = (tptr - op_defs_all) * OP_DEFS_MAX_SIZE +
+ index_in_table;
- gs_interp_make_oper(&oper, def->proc, count);
- opidx = r_size(&oper);
+ if (index_in_table >= OP_DEFS_MAX_SIZE)
+ dprintf1("opdef overrun: %s\n", def->oname);
+ gs_interp_make_oper(&oper, def->proc, opidx);
/* The first character of the name is a digit */
/* giving the minimum acceptable number of operands. */
/* Check to make sure it's within bounds. */
if (*nstr - '0' > gs_interp_max_op_num_args)
gs_abort();
nstr++;
- /* Don't enter internal operators into */
- /* the dictionary. */
- if (*nstr != '%')
- initial_enter_name_in(nstr, &oper, pdict);
- op_def_table[opidx] = def;
- if (opidx == count)
- count++;
+ /*
+ * Skip internal operators, and the second occurrence of
+ * operators with special indices.
+ */
+ if (*nstr != '%' && r_size(&oper) == opidx)
+ i_initial_enter_name_in(i_ctx_p, pdict, nstr, &oper);
}
}
- /* All of the built-ins had better be defined somewhere, */
- /* or things like op_find_index will choke. */
- for (count = 1; count <= gs_interp_num_special_ops; count++)
- if (op_def_table[count] == 0)
- gs_abort();
- gs_register_struct_root(imemory, NULL, (void **)&op_def_table,
- "op_def_table");
-
/* Allocate the tables for `operator' procedures. */
/* Make one of them local so we can have local operators. */
diff --git a/gs/src/ilevel.h b/gs/src/ilevel.h
index 521295b59..cb96df982 100644
--- a/gs/src/ilevel.h
+++ b/gs/src/ilevel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,9 +23,7 @@
# define ilevel_INCLUDED
/* The current interpreter language level */
-extern ref ref_language_level;
-
-#define LANGUAGE_LEVEL ((int)ref_language_level.value.intval)
+#define LANGUAGE_LEVEL (i_ctx_p->language_level)
#define LL2_ENABLED (LANGUAGE_LEVEL >= 2)
#define LL3_ENABLED (LANGUAGE_LEVEL >= 3)
#define level2_enabled LL2_ENABLED /* backward compatibility */
diff --git a/gs/src/ilocate.c b/gs/src/ilocate.c
index 06751eb20..b469ef0e2 100644
--- a/gs/src/ilocate.c
+++ b/gs/src/ilocate.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -117,17 +117,17 @@ ialloc_validate_spaces(const gs_dual_memory_t * dmem)
chunk_t cc;
uint rsize;
ref rlast;
- } save[countof(dmem->spaces.indexed)];
+ } save[countof(dmem->spaces_indexed)];
state.spaces = dmem->spaces;
- state.loc.memory = state.spaces.named.local;
+ state.loc.memory = state.space_local;
state.loc.cp = 0;
/* Save everything we need to reset temporarily. */
for (i = 0; i < countof(save); i++)
- if (dmem->spaces.indexed[i] != 0) {
- gs_ref_memory_t *mem = dmem->spaces.indexed[i];
+ if (dmem->spaces_indexed[i] != 0) {
+ gs_ref_memory_t *mem = dmem->spaces_indexed[i];
chunk_t *pcc = mem->pcc;
obj_header_t *rcur = mem->cc.rcur;
@@ -147,14 +147,14 @@ ialloc_validate_spaces(const gs_dual_memory_t * dmem)
/* Validate memory. */
for (i = 0; i < countof(save); i++)
- if (dmem->spaces.indexed[i] != 0)
- ialloc_validate_memory(dmem->spaces.indexed[i], &state);
+ if (dmem->spaces_indexed[i] != 0)
+ ialloc_validate_memory(dmem->spaces_indexed[i], &state);
/* Undo temporary changes. */
for (i = 0; i < countof(save); i++)
- if (dmem->spaces.indexed[i] != 0) {
- gs_ref_memory_t *mem = dmem->spaces.indexed[i];
+ if (dmem->spaces_indexed[i] != 0) {
+ gs_ref_memory_t *mem = dmem->spaces_indexed[i];
chunk_t *pcc = mem->pcc;
obj_header_t *rcur = mem->cc.rcur;
diff --git a/gs/src/imain.c b/gs/src/imain.c
index 5ca807087..75095ec1e 100644
--- a/gs/src/imain.c
+++ b/gs/src/imain.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -96,10 +96,6 @@ private void print_resource_usage(P3(const gs_main_instance *,
/* ------ Initialization ------ */
-/* A handy way to declare and execute an initialization procedure: */
-#define call_init(proc)\
-BEGIN extern void proc(P0()); proc(); END
-
/* Initialization to be done before anything else. */
void
gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err,
@@ -141,15 +137,15 @@ gs_main_init1(gs_main_instance * minst)
{
extern bool gs_have_level2(P0());
- ialloc_init((gs_raw_memory_t *) & gs_memory_default,
- minst->memory_chunk_size,
- gs_have_level2());
+ ialloc_init(idmemory, (gs_raw_memory_t *)&gs_memory_default,
+ minst->memory_chunk_size, gs_have_level2());
gs_lib_init1((gs_memory_t *) imemory_system);
alloc_save_init(idmemory);
}
{
gs_memory_t *mem = imemory_system;
- name_table *nt = names_init(minst->name_table_size, mem);
+ name_table *nt = names_init(minst->name_table_size,
+ iimemory_system);
if (nt == 0) {
puts("name_init failed");
@@ -159,14 +155,18 @@ gs_main_init1(gs_main_instance * minst)
gs_register_struct_root(mem, NULL, (void **)&the_gs_name_table,
"the_gs_name_table");
}
- call_init(obj_init); /* requires name_init */
+ {
+ extern void obj_init(P1(i_ctx_t **));
+
+ obj_init(&minst->i_ctx_p); /* requires name_init */
+ }
minst->init_done = 1;
}
}
/* Initialization to be done before running any files. */
private void
-init2_make_string_array(const ref * srefs, const char *aname)
+init2_make_string_array(i_ctx_t *i_ctx_p, const ref * srefs, const char *aname)
{
const ref *ifp = srefs;
ref ifa;
@@ -181,22 +181,30 @@ gs_main_init2(gs_main_instance * minst)
{
gs_main_init1(minst);
if (minst->init_done < 2) {
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
int code, exit_code;
ref error_object;
- call_init(igs_init);
- call_init(zop_init);
+ {
+ extern void zop_init(P1(i_ctx_t *));
+
+ zop_init(i_ctx_p);
+ }
{
extern void gs_iodev_init(P1(gs_memory_t *));
gs_iodev_init(imemory);
}
- call_init(op_init); /* requires obj_init */
+ {
+ extern void op_init(P1(i_ctx_t *));
+
+ op_init(i_ctx_p); /* requires obj_init */
+ }
/* Set up the array of additional initialization files. */
- init2_make_string_array(gs_init_file_array, "INITFILES");
+ init2_make_string_array(i_ctx_p, gs_init_file_array, "INITFILES");
/* Set up the array of emulator names. */
- init2_make_string_array(gs_emulator_name_array, "EMULATORS");
+ init2_make_string_array(i_ctx_p, gs_emulator_name_array, "EMULATORS");
/* Pass the search path. */
initial_enter_name("LIBPATH", &minst->lib_path.list);
@@ -204,13 +212,14 @@ gs_main_init2(gs_main_instance * minst)
code = gs_run_init_file(minst, &exit_code, &error_object);
if (code < 0) {
if (code != e_Fatal)
- gs_debug_dump_stack(code, &error_object);
+ gs_main_dump_stack(minst, code, &error_object);
gs_exit_with_code((exit_code ? exit_code : 2), code);
}
minst->init_done = 2;
}
if (gs_debug_c(':'))
print_resource_usage(minst, &gs_imemory, "Start");
+ gp_readline_init(&minst->readline_data, imemory_system);
}
/* ------ Search paths ------ */
@@ -324,7 +333,8 @@ gs_main_run_file(gs_main_instance * minst, const char *file_name, int user_error
if (code < 0)
return code;
- return gs_interpret(&initial_file, user_errors, pexit_code, perror_object);
+ return gs_interpret(&minst->i_ctx_p, &initial_file, user_errors,
+ pexit_code, perror_object);
}
int
gs_main_run_file_open(gs_main_instance * minst, const char *file_name, ref * pfref)
@@ -342,6 +352,7 @@ gs_main_run_file_open(gs_main_instance * minst, const char *file_name, ref * pfr
private int
gs_run_init_file(gs_main_instance * minst, int *pexit_code, ref * perror_object)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
ref ifile;
ref first_token;
int code;
@@ -361,7 +372,8 @@ gs_run_init_file(gs_main_instance * minst, int *pexit_code, ref * perror_object)
/* Check to make sure the first token is an integer */
/* (for the version number check.) */
scanner_state_init(&state, false);
- code = scan_token(ifile.value.pfile, &first_token, &state);
+ code = scan_token(i_ctx_p, ifile.value.pfile, &first_token,
+ &state);
if (code != 0 || !r_has_type(&first_token, t_integer)) {
eprintf1("Initialization file %s does not begin with an integer.\n", gs_init_file);
*pexit_code = 255;
@@ -369,7 +381,7 @@ gs_run_init_file(gs_main_instance * minst, int *pexit_code, ref * perror_object)
}
*++osp = first_token;
r_set_attrs(&ifile, a_executable);
- return gs_interpret(&ifile, minst->user_errors,
+ return gs_interpret(&minst->i_ctx_p, &ifile, minst->user_errors,
pexit_code, perror_object);
}
@@ -412,7 +424,8 @@ gs_main_run_string_begin(gs_main_instance * minst, int user_errors,
gs_main_set_lib_paths(minst);
make_const_string(&rstr, avm_foreign | a_readonly | a_executable,
strlen(setup), (const byte *)setup);
- code = gs_interpret(&rstr, user_errors, pexit_code, perror_object);
+ code = gs_interpret(&minst->i_ctx_p, &rstr, user_errors, pexit_code,
+ perror_object);
return (code == e_NeedInput ? 0 : code == 0 ? e_Fatal : code);
}
/* Continue running a string with the option of suspending. */
@@ -426,7 +439,8 @@ gs_main_run_string_continue(gs_main_instance * minst, const char *str,
return 0; /* empty string signals EOF */
make_const_string(&rstr, avm_foreign | a_readonly, length,
(const byte *)str);
- return gs_interpret(&rstr, user_errors, pexit_code, perror_object);
+ return gs_interpret(&minst->i_ctx_p, &rstr, user_errors, pexit_code,
+ perror_object);
}
/* Signal EOF when suspended. */
int
@@ -436,7 +450,8 @@ gs_main_run_string_end(gs_main_instance * minst, int user_errors,
ref rstr;
make_empty_const_string(&rstr, avm_foreign | a_readonly);
- return gs_interpret(&rstr, user_errors, pexit_code, perror_object);
+ return gs_interpret(&minst->i_ctx_p, &rstr, user_errors, pexit_code,
+ perror_object);
}
/* ------ Operand stack access ------ */
@@ -444,8 +459,9 @@ gs_main_run_string_end(gs_main_instance * minst, int user_errors,
/* These are built for comfort, not for speed. */
private int
-push_value(ref * pvalue)
+push_value(gs_main_instance *minst, ref * pvalue)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
int code = ref_stack_push(&o_stack, 1);
if (code < 0)
@@ -460,7 +476,7 @@ gs_push_boolean(gs_main_instance * minst, bool value)
ref vref;
make_bool(&vref, value);
- return push_value(&vref);
+ return push_value(minst, &vref);
}
int
@@ -469,7 +485,7 @@ gs_push_integer(gs_main_instance * minst, long value)
ref vref;
make_int(&vref, value);
- return push_value(&vref);
+ return push_value(minst, &vref);
}
int
@@ -478,7 +494,7 @@ gs_push_real(gs_main_instance * minst, floatp value)
ref vref;
make_real(&vref, value);
- return push_value(&vref);
+ return push_value(minst, &vref);
}
int
@@ -489,11 +505,11 @@ gs_push_string(gs_main_instance * minst, byte * chars, uint length,
make_string(&vref, avm_foreign | (read_only ? a_readonly : a_all),
length, (byte *) chars);
- return push_value(&vref);
+ return push_value(minst, &vref);
}
private int
-pop_value(ref * pvalue)
+pop_value(i_ctx_t *i_ctx_p, ref * pvalue)
{
if (!ref_stack_count(&o_stack))
return_error(e_stackunderflow);
@@ -504,8 +520,9 @@ pop_value(ref * pvalue)
int
gs_pop_boolean(gs_main_instance * minst, bool * result)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
ref vref;
- int code = pop_value(&vref);
+ int code = pop_value(i_ctx_p, &vref);
if (code < 0)
return code;
@@ -518,8 +535,9 @@ gs_pop_boolean(gs_main_instance * minst, bool * result)
int
gs_pop_integer(gs_main_instance * minst, long *result)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
ref vref;
- int code = pop_value(&vref);
+ int code = pop_value(i_ctx_p, &vref);
if (code < 0)
return code;
@@ -532,8 +550,9 @@ gs_pop_integer(gs_main_instance * minst, long *result)
int
gs_pop_real(gs_main_instance * minst, float *result)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
ref vref;
- int code = pop_value(&vref);
+ int code = pop_value(i_ctx_p, &vref);
if (code < 0)
return code;
@@ -554,8 +573,9 @@ gs_pop_real(gs_main_instance * minst, float *result)
int
gs_pop_string(gs_main_instance * minst, gs_string * result)
{
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
ref vref;
- int code = pop_value(&vref);
+ int code = pop_value(i_ctx_p, &vref);
if (code < 0)
return code;
@@ -588,7 +608,7 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code)
* alloc_restore_all will close dynamically allocated devices.
*/
gs_exit_status = exit_status; /* see above */
-
+ gp_readline_finit(minst->readline_data);
if (gs_debug_c(':'))
print_resource_usage(minst, &gs_imemory, "Final");
/* Do the equivalent of a restore "past the bottom". */
@@ -623,10 +643,10 @@ print_resource_usage(const gs_main_instance * minst, gs_dual_memory_t * dmem,
{
int i;
- for (i = 0; i < countof(dmem->spaces.indexed); ++i) {
- gs_ref_memory_t *mem = dmem->spaces.indexed[i];
+ for (i = 0; i < countof(dmem->spaces_indexed); ++i) {
+ gs_ref_memory_t *mem = dmem->spaces_indexed[i];
- if (mem != 0 && (i == 0 || mem != dmem->spaces.indexed[i - 1])) {
+ if (mem != 0 && (i == 0 || mem != dmem->spaces_indexed[i - 1])) {
gs_memory_status_t status;
gs_memory_status((gs_memory_t *) mem, &status);
@@ -643,9 +663,11 @@ print_resource_usage(const gs_main_instance * minst, gs_dual_memory_t * dmem,
/* Dump the stacks after interpretation */
void
-gs_debug_dump_stack(int code, ref * perror_object)
+gs_main_dump_stack(gs_main_instance *minst, int code, ref * perror_object)
{
- zflush(osp); /* force out buffered output */
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
+
+ zflush(i_ctx_p); /* force out buffered output */
dprintf1("\nUnexpected interpreter error %d.\n", code);
if (perror_object != 0) {
dputs("Error object: ");
@@ -656,3 +678,9 @@ gs_debug_dump_stack(int code, ref * perror_object)
debug_dump_stack(&e_stack, "Execution stack");
debug_dump_stack(&d_stack, "Dictionary stack");
}
+/* Backward compatibility */
+void
+gs_debug_dump_stack(int code, ref * perror_object)
+{
+ gs_main_dump_stack(gs_main_instance_default(), code, perror_object);
+}
diff --git a/gs/src/imain.h b/gs/src/imain.h
index 6d148e471..3ced68f2b 100644
--- a/gs/src/imain.h
+++ b/gs/src/imain.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -96,7 +96,7 @@ void gs_main_init2(P1(gs_main_instance * minst));
/*
* The runlibfile operator uses a search path, as described in
- * use.doc, for looking up file names. Each interpreter instance has
+ * Use.htm, for looking up file names. Each interpreter instance has
* its own search path. The following call adds a directory or set of
* directories to the search path; it is equivalent to the -I command
* line switch. It may be called any time after init0.
@@ -121,7 +121,7 @@ int gs_main_lib_open(P3(gs_main_instance * minst, const char *fname,
/*
* Here we summarize the C API calls that correspond to some of the
- * most common command line switches documented in use.doc, to help
+ * most common command line switches documented in Use.htm, to help
* clients who are familiar with the command line and are starting to
* use the API.
*
@@ -242,7 +242,8 @@ int gs_pop_string(P2(gs_main_instance * minst, gs_string * result));
* and operand and execution stacks in hex. Clients will probably
* never call this.
*/
-void gs_debug_dump_stack(P2(int code, ref * perror_object));
+void gs_main_dump_stack(P3(gs_main_instance *minst, int code,
+ ref * perror_object));
/* ---------------- Termination ---------------- */
@@ -264,7 +265,7 @@ void gs_main_finit(P3(gs_main_instance * minst, int exit_status, int code));
* Define an internal interface to the interpreter. Clients do not
* normally use this.
*/
-int gs_interpret(P4(ref * pref, int user_errors, int *pexit_code,
- ref * perror_object));
+int gs_interpret(P5(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
+ int *pexit_code, ref * perror_object));
#endif /* imain_INCLUDED */
diff --git a/gs/src/imainarg.c b/gs/src/imainarg.c
index 59d8719f5..fd9a08ce0 100644
--- a/gs/src/imainarg.c
+++ b/gs/src/imainarg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -49,8 +49,8 @@
#include "ivmspace.h"
/* Import operator procedures */
-extern int zflush(P1(os_ptr));
-extern int zflushpage(P1(os_ptr));
+extern int zflush(P1(i_ctx_t *));
+extern int zflushpage(P1(i_ctx_t *));
#ifndef GS_LIB
# define GS_LIB "GS_LIB"
@@ -65,7 +65,7 @@ extern int zflushpage(P1(os_ptr));
#endif
#ifndef GS_BUG_MAILBOX
-# define GS_BUG_MAILBOX "ghost@aladdin.com"
+# define GS_BUG_MAILBOX "bug-gs@aladdin.com"
#endif
#define MAX_BUFFERED_SIZE 1024
@@ -98,7 +98,7 @@ private int esc_strlen(P1(const char *));
private void esc_strcat(P2(char *, const char *));
private void runarg(P5(gs_main_instance *, const char *, const char *, const char *, int));
private void run_string(P3(gs_main_instance *, const char *, int));
-private void run_finish(P3(int, int, ref *));
+private void run_finish(P4(gs_main_instance *, int, int, ref *));
/* Forward references for help printout */
private void print_help(P1(gs_main_instance *));
@@ -151,7 +151,8 @@ gs_main_init_with_args(gs_main_instance * minst, int argc, char *argv[])
bool helping = false;
for (i = 1; i < argc; ++i)
- if (!strcmp(argv[i], "--")) { /* A PostScript program will be interpreting all the */
+ if (!strcmp(argv[i], "--")) {
+ /* A PostScript program will be interpreting all the */
/* remaining switches, so stop scanning. */
helping = false;
break;
@@ -215,20 +216,27 @@ swproc(gs_main_instance * minst, const char *arg, arg_list * pal)
{
char sw = arg[1];
ref vtrue;
+#undef initial_enter_name
+#define initial_enter_name(nstr, pvalue)\
+ i_initial_enter_name(minst->i_ctx_p, nstr, pvalue)
make_true(&vtrue);
arg += 2; /* skip - and letter */
switch (sw) {
default:
return -1;
- case 0: /* read stdin as a file */
+ case 0: /* read stdin as a file char-by-char */
+ /* This is a ******HACK****** for Ghostview. */
+ minst->stdin_is_interactive = true;
+ goto run_stdin;
+ case '_': /* read stdin with normal buffering */
+ minst->stdin_is_interactive = false;
+run_stdin:
minst->run_start = false; /* don't run 'start' */
/* Set NOPAUSE so showpage won't try to read from stdin. */
swproc(minst, "-dNOPAUSE", pal);
gs_main_init2(minst); /* Finish initialization */
- /* We delete this only to make Ghostview work properly. */
-/**************** This is WRONG. ****************/
- /*gs_stdin_is_interactive = false; */
+ gs_stdin_is_interactive = minst->stdin_is_interactive;
run_string(minst, ".runstdin", runFlush);
break;
case '-': /* run with command line args */
@@ -466,7 +474,8 @@ swproc(gs_main_instance * minst, const char *arg, arg_list * pal)
sread_string(&astream,
(const byte *)eqp, strlen(eqp));
scanner_state_init(&state, false);
- code = scan_token(&astream, &value, &state);
+ code = scan_token(minst->i_ctx_p, &astream, &value,
+ &state);
if (code) {
puts("-dname= must be followed by a valid token");
gs_exit(1);
@@ -518,7 +527,7 @@ swproc(gs_main_instance * minst, const char *arg, arg_list * pal)
gs_exit(1);
}
gs_main_init1(minst);
- initial_remove_name(arg);
+ i_initial_remove_name(minst->i_ctx_p, arg);
break;
case 'v': /* print revision */
print_revision();
@@ -631,9 +640,9 @@ run_buffered(gs_main_instance * minst, const char *arg)
}
}
fclose(in);
- zflush(osp);
- zflushpage(osp);
- run_finish(code, exit_code, &error_object);
+ zflush(minst->i_ctx_p);
+ zflushpage(minst->i_ctx_p);
+ run_finish(minst, code, exit_code, &error_object);
}
private void
runarg(gs_main_instance * minst, const char *pre, const char *arg,
@@ -663,13 +672,14 @@ run_string(gs_main_instance * minst, const char *str, int options)
&exit_code, &error_object);
if ((options & runFlush) || code != 0) {
- zflush(osp); /* flush stdout */
- zflushpage(osp); /* force display update */
+ zflush(minst->i_ctx_p); /* flush stdout */
+ zflushpage(minst->i_ctx_p); /* force display update */
}
- run_finish(code, exit_code, &error_object);
+ run_finish(minst, code, exit_code, &error_object);
}
private void
-run_finish(int code, int exit_code, ref * perror_object)
+run_finish(gs_main_instance *minst, int code, int exit_code,
+ ref * perror_object)
{
switch (code) {
case 0:
@@ -680,7 +690,7 @@ run_finish(int code, int exit_code, ref * perror_object)
eprintf1("Unrecoverable error, exit code %d\n", exit_code);
gs_exit(exit_code);
default:
- gs_debug_dump_stack(code, perror_object);
+ gs_main_dump_stack(minst, code, perror_object);
gs_exit_with_code(255, code);
}
}
@@ -724,9 +734,8 @@ print_help(gs_main_instance * minst)
private void
print_revision(void)
{
- fprintf(stdout, "%s ", gs_product);
- print_version();
- fprintf(stdout, " (%d-%d-%d)\n%s\n",
+ printf_program_ident(stdout, gs_product, gs_revision);
+ fprintf(stdout, " (%d-%02d-%02d)\n%s\n",
(int)(gs_revisiondate / 10000),
(int)(gs_revisiondate / 100 % 100),
(int)(gs_revisiondate % 100),
@@ -737,9 +746,7 @@ print_revision(void)
private void
print_version(void)
{
- fprintf(stdout, "%d.%02d",
- (int)(gs_revision / 100),
- (int)(gs_revision % 100));
+ printf_program_ident(stdout, NULL, gs_revision);
}
/* Print usage information. */
diff --git a/gs/src/imemory.h b/gs/src/imemory.h
index d6d9180bf..5e7289b50 100644
--- a/gs/src/imemory.h
+++ b/gs/src/imemory.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -85,9 +85,15 @@ struct gs_dual_memory_s {
int save_level;
/* Garbage collection hook */
int (*reclaim) (P2(gs_dual_memory_t *, int));
+ void *reclaim_data;
/* Masks for store checking, see isave.h. */
uint test_mask;
uint new_mask;
};
+#define public_st_gs_dual_memory() /* in ialloc.c */\
+ gs_public_st_ptrs1(st_gs_dual_memory, gs_dual_memory_t, "gs_dual_memory_t",\
+ dual_memory_enum_ptrs, dual_memory_reloc_ptrs, reclaim_data)
+#define st_gs_dual_memory_num_ptrs 1
+
#endif /* imemory_INCLUDED */
diff --git a/gs/src/iminst.h b/gs/src/iminst.h
index 6d426cab4..9f55a87ad 100644
--- a/gs/src/iminst.h
+++ b/gs/src/iminst.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,7 +26,6 @@
#ifndef gs_main_instance_DEFINED
# define gs_main_instance_DEFINED
typedef struct gs_main_instance_s gs_main_instance;
-
#endif
/*
@@ -55,13 +54,16 @@ typedef struct gs_file_path_s {
/*
* Here is where we actually define the structure of interpreter instances.
- * Clients should not reference any of the members.
+ * Clients should not reference any of the members. Note that in order to
+ * be able to initialize this structure statically, members including
+ * unions must come last (and be initialized to 0 by default).
*/
struct gs_main_instance_s {
/* The following are set during initialization. */
FILE *fstdin;
FILE *fstdout;
FILE *fstderr;
+ bool stdin_is_interactive;
gs_memory_t *heap; /* (C) heap allocator */
uint memory_chunk_size; /* 'wholesale' allocation unit */
ulong name_table_size;
@@ -70,9 +72,12 @@ struct gs_main_instance_s {
int user_errors; /* define what to do with errors */
bool search_here_first; /* if true, make '.' first lib dir */
bool run_start; /* if true, run 'start' after */
- /* processing command line */
+ /* processing command line */
gs_file_path lib_path; /* library search list (GS_LIB) */
long base_time[2]; /* starting usertime */
+ void *readline_data; /* data for gp_readline */
+ /* The following are updated dynamically. */
+ i_ctx_t *i_ctx_p; /* current interpreter context state */
};
/*
@@ -80,7 +85,7 @@ struct gs_main_instance_s {
* must include gconfig.h, because of SEARCH_HERE_FIRST.
*/
#define gs_main_instance_default_init_values\
- 0, 0, 0, 0, 20000, 0, 0, -1, 0, SEARCH_HERE_FIRST, 1
+ 0, 0, 0, 1 /*true*/, 0, 20000, 0, 0, -1, 0, SEARCH_HERE_FIRST, 1
extern const gs_main_instance gs_main_instance_init_values;
#endif /* iminst_INCLUDED */
diff --git a/gs/src/iname.c b/gs/src/iname.c
index 950a1c486..9623d1239 100644
--- a/gs/src/iname.c
+++ b/gs/src/iname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -45,15 +45,15 @@ private const byte hash_permutation[256] =
110, 177, 104, 103, 141, 253, 255, 50, 77, 101, 81, 18, 45, 96, 31, 222,
25, 107, 190, 70, 86, 237, 240, 34, 72, 242, 20, 214, 244, 227, 149, 235,
97, 234, 57, 22, 60, 250, 82, 175, 208, 5, 127, 199, 111, 62, 135, 248,
- 174, 169, 211, 58, 66, 154, 106, 195, 245, 171, 17, 187, 182, 179, 0, 243,
- 132, 56, 148, 75, 128, 133, 158, 100, 130, 126, 91, 13, 153, 246, 216, 219,
+ 174, 169, 211, 58, 66, 154, 106, 195, 245, 171, 17, 187, 182, 179, 0, 243,
+ 132, 56, 148, 75, 128, 133, 158, 100, 130, 126, 91, 13, 153, 246, 216, 219,
119, 68, 223, 78, 83, 88, 201, 99, 122, 11, 92, 32, 136, 114, 52, 10,
138, 30, 48, 183, 156, 35, 61, 26, 143, 74, 251, 94, 129, 162, 63, 152,
170, 7, 115, 167, 241, 206, 3, 150, 55, 59, 151, 220, 90, 53, 23, 131,
125, 173, 15, 238, 79, 95, 89, 16, 105, 137, 225, 224, 217, 160, 37, 123,
118, 73, 2, 157, 46, 116, 9, 145, 134, 228, 207, 212, 202, 215, 69, 229,
27, 188, 67, 124, 168, 252, 42, 4, 29, 108, 21, 247, 19, 205, 39, 203,
- 233, 40, 186, 147, 198, 192, 155, 33, 164, 191, 98, 204, 165, 180, 117, 76,
+ 233, 40, 186, 147, 198, 192, 155, 33, 164, 191, 98, 204, 165, 180, 117, 76,
140, 36, 210, 172, 41, 54, 159, 8, 185, 232, 113, 196, 231, 47, 146, 120,
51, 65, 28, 144, 254, 221, 93, 189, 194, 139, 112, 43, 71, 109, 184, 209
};
@@ -66,8 +66,7 @@ private const byte hash_permutation[256] =
*/
#define nt_1char_size 128
#define nt_1char_first 2
-private const byte nt_1char_names[128] =
-{
+private const byte nt_1char_names[128] = {
#define q8(n) n,n+1,n+2,n+3,n+4,n+5,n+6,n+7
#define q32(n) q8(n),q8(n+8),q8(n+16),q8(n+24)
q32(0), q32(32), q32(64), q32(96)
@@ -106,8 +105,9 @@ name_print(const char *msg, name * pname, uint nidx, const int *pflag)
/* Initialize a name table */
name_table *
-names_init(ulong count, gs_memory_t * mem)
+names_init(ulong count, gs_ref_memory_t *imem)
{
+ gs_memory_t *mem = (gs_memory_t *)imem;
register int i;
name_table *nt;
@@ -120,6 +120,7 @@ names_init(ulong count, gs_memory_t * mem)
memset(nt, 0, sizeof(name_table));
nt->max_sub_count =
((count - 1) | nt_sub_index_mask) >> nt_log2_sub_size;
+ nt->name_string_attrs = imemory_space(imem) | a_readonly;
nt->memory = mem;
/* Initialize the one-character names. */
/* Start by creating the necessary sub-tables. */
@@ -244,12 +245,11 @@ void
names_string_ref(const name_table * nt, const ref * pnref /* t_name */ ,
ref * psref /* result, t_string */ )
{
- name *pname = pnref->value.pname;
+ const name *pname = pnref->value.pname;
make_const_string(psref,
- (pname->foreign_string ? avm_foreign :
- imemory_space((gs_ref_memory_t *) nt->memory))
- | a_readonly,
+ (pname->foreign_string ? avm_foreign | a_readonly :
+ nt->name_string_attrs),
pname->string_size,
(const byte *)pname->string_bytes);
}
diff --git a/gs/src/inamedef.h b/gs/src/inamedef.h
index fa169f127..50b8bcca4 100644
--- a/gs/src/inamedef.h
+++ b/gs/src/inamedef.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -101,7 +101,7 @@ struct name_s {
*
* First we define the name sub-table structure.
*/
-#define nt_log2_sub_size (7 + (EXTEND_NAMES / 2))
+#define nt_log2_sub_size (8 + (EXTEND_NAMES / 2))
# define nt_sub_size (1 << nt_log2_sub_size)
# define nt_sub_index_mask (nt_sub_size - 1)
typedef struct name_sub_table_s {
@@ -136,17 +136,17 @@ typedef struct name_sub_table_s {
#define nt_hash_size (1024 << (EXTEND_NAMES / 2)) /* must be a power of 2 */
struct name_table_s {
uint free; /* head of free list, which is sorted in */
- /* increasing count (not index) order */
+ /* increasing count (not index) order */
uint sub_next; /* index of next sub-table to allocate */
- /* if not already allocated */
+ /* if not already allocated */
uint sub_count; /* index of highest allocated sub-table +1 */
uint max_sub_count; /* max allowable value of sub_count */
+ uint name_string_attrs; /* imemory_space(memory) | a_readonly */
gs_memory_t *memory;
uint hash[nt_hash_size];
name_sub_table *sub_tables[max_name_index / nt_sub_size + 1];
};
-
- /*typedef struct name_table_s name_table; *//* in inames.h */
+/*typedef struct name_table_s name_table; *//* in inames.h */
/* ---------------- Procedural interface ---------------- */
@@ -193,7 +193,6 @@ void names_trace_finish(P2(name_table * nt, gc_state_t * gcst));
/* by removing names whose count is less than old_count. */
#ifndef alloc_save_t_DEFINED /* also in isave.h */
typedef struct alloc_save_s alloc_save_t;
-
# define alloc_save_t_DEFINED
#endif
void names_restore(P2(name_table * nt, alloc_save_t * save));
@@ -209,16 +208,19 @@ void names_restore(P2(name_table * nt, alloc_save_t * save));
* - It must be a permutation on the sub-table index.
* Something very simple works just fine.
*/
+#define NAME_COUNT_TO_INDEX_FACTOR 23
#define name_count_to_index(cnt)\
(((cnt) & (-nt_sub_size)) +\
- (((cnt) * 59) & nt_sub_index_mask))
+ (((cnt) * NAME_COUNT_TO_INDEX_FACTOR) & nt_sub_index_mask))
/*
* The reverse permutation requires finding a number R such that
- * 59*R = 1 mod nt_sub_size. For nt_sub_size any power of 2 up to 2048,
- * R = 243 will work. Currently, this is only needed for debugging printout.
+ * NAME_COUNT_TO_INDEX_FACTOR * R = 1 mod nt_sub_size.
+ * The value given below works for nt_sub_size any power of 2 up to 4096.
+ * Currently, this is only needed for debugging printout.
*/
+#define NAME_INDEX_TO_COUNT_FACTOR 1959
#define name_index_to_count(nidx)\
(((nidx) & (-nt_sub_size)) +\
- (((nidx) * 243) & nt_sub_index_mask))
+ (((nidx) * NAME_INDEX_TO_COUNT_FACTOR) & nt_sub_index_mask))
#endif /* inamedef_INCLUDED */
diff --git a/gs/src/inames.h b/gs/src/inames.h
index 345a3408b..bc3499d91 100644
--- a/gs/src/inames.h
+++ b/gs/src/inames.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,7 +33,6 @@
#ifndef name_table_DEFINED
# define name_table_DEFINED
typedef struct name_table_s name_table;
-
#endif
typedef uint name_index_t;
@@ -44,8 +43,13 @@ extern const uint name_max_string;
/* ---------------- Procedural interface ---------------- */
+#ifndef gs_ref_memory_DEFINED
+# define gs_ref_memory_DEFINED
+typedef struct gs_ref_memory_s gs_ref_memory_t;
+#endif
+
/* Allocate and initialize a name table. */
-name_table *names_init(P2(ulong size, gs_memory_t * mem));
+name_table *names_init(P2(ulong size, gs_ref_memory_t *imem));
/* Get the allocator for a name table. */
gs_memory_t *names_memory(P1(const name_table * nt));
diff --git a/gs/src/inobtokn.c b/gs/src/inobtokn.c
new file mode 100644
index 000000000..e585ab9e1
--- /dev/null
+++ b/gs/src/inobtokn.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Dummy scan_binary_token for Level 1 systems */
+#include "ghost.h"
+#include "errors.h"
+#include "stream.h"
+#include "iscan.h"
+
+int
+scan_binary_token(i_ctx_t *i_ctx_p, stream *s, ref *pref,
+ scanner_state *pstate)
+{
+ return_error(e_unregistered);
+}
diff --git a/gs/src/inouparm.c b/gs/src/inouparm.c
index b345ad6a1..4e37b5917 100644
--- a/gs/src/inouparm.c
+++ b/gs/src/inouparm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,7 +22,7 @@
#include "icontext.h" /* for set_user_params prototype */
int
-set_user_params(const ref * op)
+set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
{
return 0;
}
diff --git a/gs/src/int.mak b/gs/src/int.mak
index 9a4efd229..d09b10050 100644
--- a/gs/src/int.mak
+++ b/gs/src/int.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -26,6 +26,7 @@
# PSOBJDIR - the object code directory
PSSRC=$(PSSRCDIR)$(D)
+PSLIB=$(PSLIBDIR)$(D)
PSGEN=$(PSGENDIR)$(D)
PSOBJ=$(PSOBJDIR)$(D)
PSO_=$(O_)$(PSOBJ)
@@ -33,6 +34,8 @@ PSI_=$(PSSRCDIR) $(II)$(PSGENDIR) $(II)$(GLI_)
PSF_=
PSCC=$(CC_) $(I_)$(PSI_)$(_I) $(PSF_)
PSCCLEAF=$(CC_LEAF) $(I_)$(PSI_)$(_I) $(PSF_)
+# All top-level makefiles define PSD.
+#PSD=$(PSGEN)
# Define the name of this makefile.
INT_MAK=$(PSSRC)int.mak
@@ -45,7 +48,9 @@ INT_MAK=$(PSSRC)int.mak
errors_h=$(PSSRC)errors.h
idebug_h=$(PSSRC)idebug.h
-idict_h=$(PSSRC)idict.h
+# Having iddstack.h at this level is unfortunate, but unavoidable.
+iddstack_h=$(PSSRC)iddstack.h
+idict_h=$(PSSRC)idict.h $(iddstack_h)
idictdef_h=$(PSSRC)idictdef.h
igcstr_h=$(PSSRC)igcstr.h
inames_h=$(PSSRC)inames.h
@@ -73,46 +78,47 @@ GH=$(AK) $(ghost_h)
isupport1_=$(PSOBJ)ialloc.$(OBJ) $(PSOBJ)igc.$(OBJ) $(PSOBJ)igcref.$(OBJ) $(PSOBJ)igcstr.$(OBJ)
isupport2_=$(PSOBJ)ilocate.$(OBJ) $(PSOBJ)iname.$(OBJ) $(PSOBJ)isave.$(OBJ)
isupport_=$(isupport1_) $(isupport2_)
-isupport.dev: $(INT_MAK) $(ECHOGS_XE) $(isupport_)
- $(SETMOD) isupport $(isupport1_)
- $(ADDMOD) isupport -obj $(isupport2_)
+$(PSD)isupport.dev : $(INT_MAK) $(ECHOGS_XE) $(isupport_)
+ $(SETMOD) $(PSD)isupport $(isupport1_)
+ $(ADDMOD) $(PSD)isupport -obj $(isupport2_)
-$(PSOBJ)ialloc.$(OBJ): $(PSSRC)ialloc.c $(AK) $(memory__h) $(gx_h)\
- $(errors_h) $(gsstruct_h) $(gxarith_h)\
- $(iastate_h) $(ipacked_h) $(iref_h) $(iutil_h) $(ivmspace_h) $(store_h)
+$(PSOBJ)ialloc.$(OBJ) : $(PSSRC)ialloc.c $(AK) $(memory__h) $(gx_h)\
+ $(errors_h) $(gsstruct_h)\
+ $(iastate_h) $(igc_h) $(ipacked_h) $(iref_h) $(iutil_h) $(ivmspace_h)\
+ $(store_h)
$(PSCC) $(PSO_)ialloc.$(OBJ) $(C_) $(PSSRC)ialloc.c
# igc.c, igcref.c, and igcstr.c should really be in the dpsand2 list,
# but since all the GC enumeration and relocation routines refer to them,
# it's too hard to separate them out from the Level 1 base.
-$(PSOBJ)igc.$(OBJ): $(PSSRC)igc.c $(GH) $(memory__h)\
+$(PSOBJ)igc.$(OBJ) : $(PSSRC)igc.c $(GH) $(memory__h)\
$(errors_h) $(gsexit_h) $(gsmdebug_h) $(gsstruct_h) $(gsutil_h)\
$(iastate_h) $(idict_h) $(igc_h) $(igcstr_h) $(inamedef_h)\
$(ipacked_h) $(isave_h) $(isstate_h) $(istruct_h) $(opdef_h)
$(PSCC) $(PSO_)igc.$(OBJ) $(C_) $(PSSRC)igc.c
-$(PSOBJ)igcref.$(OBJ): $(PSSRC)igcref.c $(GH) $(memory__h)\
+$(PSOBJ)igcref.$(OBJ) : $(PSSRC)igcref.c $(GH) $(memory__h)\
$(gsexit_h) $(gsstruct_h)\
$(iastate_h) $(idebug_h) $(igc_h) $(iname_h) $(ipacked_h) $(store_h)
$(PSCC) $(PSO_)igcref.$(OBJ) $(C_) $(PSSRC)igcref.c
-$(PSOBJ)igcstr.$(OBJ): $(PSSRC)igcstr.c $(GH) $(memory__h)\
+$(PSOBJ)igcstr.$(OBJ) : $(PSSRC)igcstr.c $(GH) $(memory__h)\
$(gsmdebug_h) $(gsstruct_h) $(iastate_h) $(igcstr_h)
$(PSCC) $(PSO_)igcstr.$(OBJ) $(C_) $(PSSRC)igcstr.c
-$(PSOBJ)ilocate.$(OBJ): $(PSSRC)ilocate.c $(GH) $(memory__h)\
+$(PSOBJ)ilocate.$(OBJ) : $(PSSRC)ilocate.c $(GH) $(memory__h)\
$(errors_h) $(gsexit_h) $(gsstruct_h)\
$(iastate_h) $(idict_h) $(igc_h) $(igcstr_h) $(iname_h)\
$(ipacked_h) $(isstate_h) $(iutil_h) $(ivmspace_h)\
$(store_h)
$(PSCC) $(PSO_)ilocate.$(OBJ) $(C_) $(PSSRC)ilocate.c
-$(PSOBJ)iname.$(OBJ): $(PSSRC)iname.c $(GH) $(memory__h) $(string__h)\
+$(PSOBJ)iname.$(OBJ) : $(PSSRC)iname.c $(GH) $(memory__h) $(string__h)\
$(gsstruct_h) $(gxobj_h)\
$(errors_h) $(imemory_h) $(inamedef_h) $(isave_h) $(store_h)
$(PSCC) $(PSO_)iname.$(OBJ) $(C_) $(PSSRC)iname.c
-$(PSOBJ)isave.$(OBJ): $(PSSRC)isave.c $(GH) $(memory__h)\
+$(PSOBJ)isave.$(OBJ) : $(PSSRC)isave.c $(GH) $(memory__h)\
$(errors_h) $(gsexit_h) $(gsstruct_h) $(gsutil_h)\
$(iastate_h) $(iname_h) $(inamedef_h) $(isave_h) $(isstate_h) $(ivmspace_h)\
$(ipacked_h) $(store_h) $(stream_h)
@@ -122,54 +128,64 @@ $(PSOBJ)isave.$(OBJ): $(PSSRC)isave.c $(GH) $(memory__h)\
idparam_h=$(PSSRC)idparam.h
ilevel_h=$(PSSRC)ilevel.h
+interp_h=$(PSSRC)interp.h
iparam_h=$(PSSRC)iparam.h $(gsparam_h)
-istack_h=$(PSSRC)istack.h
+isdata_h=$(PSSRC)isdata.h
+istack_h=$(PSSRC)istack.h $(isdata_h)
iutil2_h=$(PSSRC)iutil2.h
opcheck_h=$(PSSRC)opcheck.h
opextern_h=$(PSSRC)opextern.h
# Nested include files
-idstack_h=$(PSSRC)idstack.h $(istack_h)
-dstack_h=$(PSSRC)dstack.h $(idstack_h)
-iestack_h=$(PSSRC)iestack.h $(istack_h)
-estack_h=$(PSSRC)estack.h $(iestack_h)
-iostack_h=$(PSSRC)iostack.h $(istack_h)
-ostack_h=$(PSSRC)ostack.h $(iostack_h)
+idsdata_h=$(PSSRC)idsdata.h $(isdata_h)
+idstack_h=$(PSSRC)idstack.h $(iddstack_h) $(idsdata_h) $(istack_h)
+iesdata_h=$(PSSRC)iesdata.h $(isdata_h)
+iestack_h=$(PSSRC)iestack.h $(istack_h) $(iesdata_h)
+iosdata_h=$(PSSRC)iosdata.h $(isdata_h)
+iostack_h=$(PSSRC)iostack.h $(istack_h) $(iosdata_h)
+icstate_h=$(PSSRC)icstate.h $(imemory_h) $(iref_h) $(idsdata_h) $(iesdata_h) $(iosdata_h)
+iddict_h=$(PSSRC)iddict.h $(icstate_h) $(idict_h)
+dstack_h=$(PSSRC)dstack.h $(icstate_h) $(idstack_h)
+estack_h=$(PSSRC)estack.h $(icstate_h) $(iestack_h)
+ostack_h=$(PSSRC)ostack.h $(icstate_h) $(iostack_h)
oper_h=$(PSSRC)oper.h $(errors_h) $(iutil_h) $(opcheck_h) $(opdef_h) $(opextern_h) $(ostack_h)
-$(PSOBJ)idebug.$(OBJ): $(PSSRC)idebug.c $(GH) $(string__h)\
+$(PSOBJ)idebug.$(OBJ) : $(PSSRC)idebug.c $(GH) $(string__h)\
$(ialloc_h) $(idebug_h) $(idict_h) $(iname_h) $(istack_h) $(iutil_h) $(ivmspace_h)\
$(opdef_h) $(ipacked_h)
$(PSCC) $(PSO_)idebug.$(OBJ) $(C_) $(PSSRC)idebug.c
-$(PSOBJ)idict.$(OBJ): $(PSSRC)idict.c $(GH) $(string__h) $(errors_h)\
- $(idebug_h) $(idict_h) $(idictdef_h) $(idstack_h) $(imemory_h) $(iname_h)\
- $(inamedef_h) $(ipacked_h) $(isave_h) $(iutil_h) $(ivmspace_h) $(store_h)
+$(PSOBJ)idict.$(OBJ) : $(PSSRC)idict.c $(GH) $(string__h)\
+ $(errors_h)\
+ $(iddstack_h) $(idebug_h) $(idict_h) $(idictdef_h)\
+ $(imemory_h) $(iname_h) $(inamedef_h) $(ipacked_h) $(isave_h)\
+ $(iutil_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)idict.$(OBJ) $(C_) $(PSSRC)idict.c
-$(PSOBJ)idparam.$(OBJ): $(PSSRC)idparam.c $(GH) $(memory__h) $(string__h) $(errors_h)\
+$(PSOBJ)idparam.$(OBJ) : $(PSSRC)idparam.c $(GH) $(memory__h) $(string__h) $(errors_h)\
$(gsmatrix_h) $(gsuid_h)\
$(idict_h) $(idparam_h) $(ilevel_h) $(imemory_h) $(iname_h) $(iutil_h)\
$(oper_h) $(store_h)
$(PSCC) $(PSO_)idparam.$(OBJ) $(C_) $(PSSRC)idparam.c
-$(PSOBJ)idstack.$(OBJ): $(PSSRC)idstack.c $(GH)\
+$(PSOBJ)idstack.$(OBJ) : $(PSSRC)idstack.c $(GH)\
$(idebug_h) $(idict_h) $(idictdef_h) $(idstack_h) $(iname_h) $(inamedef_h)\
$(ipacked_h) $(iutil_h) $(ivmspace_h)
$(PSCC) $(PSO_)idstack.$(OBJ) $(C_) $(PSSRC)idstack.c
-$(PSOBJ)iparam.$(OBJ): $(PSSRC)iparam.c $(GH)\
+$(PSOBJ)iparam.$(OBJ) : $(PSSRC)iparam.c $(GH)\
$(memory__h) $(string__h) $(errors_h)\
$(ialloc_h) $(idict_h) $(iname_h) $(imemory_h) $(iparam_h) $(istack_h) $(iutil_h) $(ivmspace_h)\
$(opcheck_h) $(oper_h) $(store_h)
$(PSCC) $(PSO_)iparam.$(OBJ) $(C_) $(PSSRC)iparam.c
-$(PSOBJ)istack.$(OBJ): $(PSSRC)istack.c $(GH) $(memory__h)\
+$(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\
$(errors_h) $(gsstruct_h) $(gsutil_h)\
$(ialloc_h) $(istack_h) $(istruct_h) $(iutil_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c
-$(PSOBJ)iutil.$(OBJ): $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\
+$(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\
$(gsccode_h) $(gsmatrix_h) $(gsutil_h) $(gxfont_h)\
+ $(sstring_h) $(strimpl_h)\
$(errors_h) $(idict_h) $(imemory_h) $(iutil_h) $(ivmspace_h)\
$(iname_h) $(ipacked_h) $(oper_h) $(store_h)
$(PSCC) $(PSO_)iutil.$(OBJ) $(C_) $(PSSRC)iutil.c
@@ -178,20 +194,24 @@ $(PSOBJ)iutil.$(OBJ): $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)
###### Include files
+# Binary tokens are a Level 2 feature, but we need to refer to them
+# in the scanner.
+btoken_h=$(PSSRC)btoken.h
files_h=$(PSSRC)files.h
fname_h=$(PSSRC)fname.h
ichar_h=$(PSSRC)ichar.h
+ichar1_h=$(PSSRC)ichar1.h
icharout_h=$(PSSRC)icharout.h
icolor_h=$(PSSRC)icolor.h
+icremap_h=$(PSSRC)icremap.h $(gsccolor_h)
icsmap_h=$(PSSRC)icsmap.h
-icstate_h=$(PSSRC)icstate.h $(imemory_h)
-ifont_h=$(PSSRC)ifont.h $(gsccode_h) $(gsstruct_h)
+ifont_h=$(PSSRC)ifont.h $(gsccode_h) $(gsstype_h)
+ifont1_h=$(PSSRC)ifont1.h
iht_h=$(PSSRC)iht.h
iimage_h=$(PSSRC)iimage.h
imain_h=$(PSSRC)imain.h $(gsexit_h)
imainarg_h=$(PSSRC)imainarg.h
iminst_h=$(PSSRC)iminst.h
-interp_h=$(PSSRC)interp.h
iparray_h=$(PSSRC)iparray.h
iscannum_h=$(PSSRC)iscannum.h
istream_h=$(PSSRC)istream.h
@@ -202,9 +222,9 @@ shcgen_h=$(PSSRC)shcgen.h
smtf_h=$(PSSRC)smtf.h
# Nested include files
bfont_h=$(PSSRC)bfont.h $(ifont_h)
-icontext_h=$(PSSRC)icontext.h $(gsstruct_h) $(icstate_h)
+icontext_h=$(PSSRC)icontext.h $(gsstype_h) $(icstate_h)
ifilter_h=$(PSSRC)ifilter.h $(istream_h) $(ivmspace_h)
-igstate_h=$(PSSRC)igstate.h $(gsstate_h) $(gxstate_h) $(istruct_h)
+igstate_h=$(PSSRC)igstate.h $(gsstate_h) $(gxstate_h) $(imemory_h) $(istruct_h)
iscan_h=$(PSSRC)iscan.h $(sa85x_h) $(sstring_h)
sbhc_h=$(PSSRC)sbhc.h $(shc_h)
# Include files for optional features
@@ -212,143 +232,163 @@ ibnum_h=$(PSSRC)ibnum.h
### Initialization and scanning
-iconfig=iconfig$(CONFIG)
-$(PSOBJ)$(iconfig).$(OBJ): $(PSSRC)iconf.c $(stdio__h)\
+$(PSOBJ)iconfig.$(OBJ) : $(PSSRC)iconf.c $(stdio__h)\
$(gconf_h) $(gsmemory_h) $(gstypes_h)\
$(iminst_h) $(iref_h) $(ivmspace_h) $(opdef_h)
- $(RM_) $(PSGEN)$(iconfig).c
+ $(RM_) $(PSGEN)iconfig.c
$(CP_) $(gconfig_h) $(PSGEN)gconfig.h
- $(CP_) $(PSSRC)iconf.c $(PSGEN)$(iconfig).c
- $(PSCC) $(PSO_)$(iconfig).$(OBJ) $(C_) $(PSGEN)$(iconfig).c
+ $(CP_) $(PSSRC)iconf.c $(PSGEN)iconfig.c
+ $(PSCC) $(PSO_)iconfig.$(OBJ) $(C_) $(PSGEN)iconfig.c
-$(PSOBJ)iinit.$(OBJ): $(PSSRC)iinit.c $(GH) $(string__h)\
+$(PSOBJ)iinit.$(OBJ) : $(PSSRC)iinit.c $(GH) $(string__h)\
$(gscdefs_h) $(gsexit_h) $(gsstruct_h)\
- $(ialloc_h) $(idict_h) $(dstack_h) $(errors_h)\
+ $(ialloc_h) $(iddict_h) $(dstack_h) $(errors_h)\
$(ilevel_h) $(iname_h) $(interp_h) $(opdef_h)\
$(ipacked_h) $(iparray_h) $(iutil_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)iinit.$(OBJ) $(C_) $(PSSRC)iinit.c
-$(PSOBJ)iscan.$(OBJ): $(PSSRC)iscan.c $(GH) $(memory__h)\
- $(ialloc_h) $(idict_h) $(dstack_h) $(errors_h) $(files_h)\
- $(ilevel_h) $(iutil_h) $(iscan_h) $(iscannum_h) $(istruct_h) $(ivmspace_h)\
- $(iname_h) $(ipacked_h) $(iparray_h) $(istream_h) $(ostack_h) $(store_h)\
- $(stream_h) $(strimpl_h) $(sfilter_h) $(scanchar_h)
+$(PSOBJ)iscan.$(OBJ) : $(PSSRC)iscan.c $(GH) $(memory__h)\
+ $(btoken_h) $(dstack_h) $(errors_h) $(files_h)\
+ $(ialloc_h) $(idict_h) $(ilevel_h) $(iutil_h) $(iscan_h) $(iscannum_h)\
+ $(istruct_h) $(ivmspace_h) $(iname_h) $(ipacked_h) $(iparray_h) $(istream_h)\
+ $(ostack_h) $(store_h)\
+ $(sa85d_h) $(stream_h) $(strimpl_h) $(sfilter_h) $(scanchar_h)
$(PSCC) $(PSO_)iscan.$(OBJ) $(C_) $(PSSRC)iscan.c
-$(PSOBJ)iscannum.$(OBJ): $(PSSRC)iscannum.c $(GH) $(math__h)\
+$(PSOBJ)iscannum.$(OBJ) : $(PSSRC)iscannum.c $(GH) $(math__h)\
$(errors_h) $(iscannum_h) $(scanchar_h) $(scommon_h) $(store_h)
$(PSCC) $(PSO_)iscannum.$(OBJ) $(C_) $(PSSRC)iscannum.c
### Streams
-$(PSOBJ)sfilter1.$(OBJ): $(PSSRC)sfilter1.c $(AK) $(stdio__h) $(memory__h)\
+$(PSOBJ)sfilter1.$(OBJ) : $(PSSRC)sfilter1.c $(AK) $(stdio__h) $(memory__h)\
$(sfilter_h) $(strimpl_h)
$(PSCC) $(PSO_)sfilter1.$(OBJ) $(C_) $(PSSRC)sfilter1.c
+# GNU readline. This code was contributed by a user: please contact
+# Alexey Subbotin <A.Subbotin@lpi.ru> if you have questions.
+# The references from a gp_ module to the interpreter are a bug,
+# but they are intrinsic to what this implementation does.
+gnrdline_=$(PSOBJ)gp_gnrdl.$(OBJ)
+$(PSD)gnrdline.dev : $(INT_MAK) $(ECHOGS_XE) $(gnrdline_)
+ $(SETMOD) $(PSD)gnrdline $(gnrdline_)
+ $(ADDMOD) $(PSD)gnrdline -lib readline termcap
+ $(ADDMOD) $(PSD)gnrdline -replace $(GLD)strdline
+ $(ADDMOD) $(PSD)gnrdline -ps gs_rdlin
+
+$(PSOBJ)gp_gnrdl.$(OBJ) : $(PSSRC)gp_gnrdl.c $(AK)\
+ $(ctype__h) $(malloc__h) $(memory__h) $(string__h)\
+ $(gp_h) $(gsmalloc_h) $(gsmemory_h) $(gsstruct_h) $(gxiodev_h) $(stream_h)\
+ $(ghost_h) $(dstack_h) $(errors_h) $(idict_h) $(iname_h) $(iutil_h)\
+ $(ostack_h)
+ $(PSCC) $(PSO_)gp_gnrdl.$(OBJ) $(C_) $(PSSRC)gp_gnrdl.c
+
###### Operators
OP=$(GH) $(oper_h)
### Non-graphics operators
-$(PSOBJ)zarith.$(OBJ): $(PSSRC)zarith.c $(OP) $(math__h) $(store_h)
+$(PSOBJ)zarith.$(OBJ) : $(PSSRC)zarith.c $(OP) $(math__h) $(store_h)
$(PSCC) $(PSO_)zarith.$(OBJ) $(C_) $(PSSRC)zarith.c
-$(PSOBJ)zarray.$(OBJ): $(PSSRC)zarray.c $(OP) $(memory__h)\
+$(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\
$(ialloc_h) $(ipacked_h) $(store_h)
$(PSCC) $(PSO_)zarray.$(OBJ) $(C_) $(PSSRC)zarray.c
-$(PSOBJ)zcontrol.$(OBJ): $(PSSRC)zcontrol.c $(OP) $(string__h)\
+$(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\
$(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)
$(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c
-$(PSOBJ)zdict.$(OBJ): $(PSSRC)zdict.c $(OP)\
- $(dstack_h) $(idict_h) $(ilevel_h) $(iname_h) $(ipacked_h) $(ivmspace_h)\
+$(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\
+ $(dstack_h) $(iddict_h) $(ilevel_h) $(iname_h) $(ipacked_h) $(ivmspace_h)\
$(store_h)
$(PSCC) $(PSO_)zdict.$(OBJ) $(C_) $(PSSRC)zdict.c
-$(PSOBJ)zfile.$(OBJ): $(PSSRC)zfile.c $(OP) $(memory__h) $(string__h) $(gp_h)\
+$(PSOBJ)zfile.$(OBJ) : $(PSSRC)zfile.c $(OP) $(memory__h) $(string__h) $(gp_h)\
$(gscdefs_h) $(gsstruct_h) $(gxalloc_h) $(gxiodev_h)\
$(ialloc_h) $(estack_h) $(files_h) $(fname_h) $(ilevel_h) $(interp_h) $(iutil_h)\
$(isave_h) $(main_h) $(sfilter_h) $(stream_h) $(strimpl_h) $(store_h)
$(PSCC) $(PSO_)zfile.$(OBJ) $(C_) $(PSSRC)zfile.c
-$(PSOBJ)zfileio.$(OBJ): $(PSSRC)zfileio.c $(OP) $(gp_h)\
- $(files_h) $(ifilter_h) $(store_h) $(stream_h) $(strimpl_h)\
+$(PSOBJ)zfileio.$(OBJ) : $(PSSRC)zfileio.c $(OP) $(gp_h)\
+ $(estack_h) $(files_h) $(ifilter_h) $(interp_h) $(store_h)\
+ $(stream_h) $(strimpl_h)\
$(gsmatrix_h) $(gxdevice_h) $(gxdevmem_h)
$(PSCC) $(PSO_)zfileio.$(OBJ) $(C_) $(PSSRC)zfileio.c
-$(PSOBJ)zfilter.$(OBJ): $(PSSRC)zfilter.c $(OP) $(memory__h)\
+$(PSOBJ)zfilter.$(OBJ) : $(PSSRC)zfilter.c $(OP) $(memory__h)\
$(gsstruct_h)\
$(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h) $(ilevel_h)\
$(sfilter_h) $(srlx_h) $(sstring_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)zfilter.$(OBJ) $(C_) $(PSSRC)zfilter.c
-$(PSOBJ)zfname.$(OBJ): $(PSSRC)zfname.c $(OP) $(memory__h)\
+$(PSOBJ)zfname.$(OBJ) : $(PSSRC)zfname.c $(OP) $(memory__h)\
$(fname_h) $(gxiodev_h) $(ialloc_h) $(stream_h)
$(PSCC) $(PSO_)zfname.$(OBJ) $(C_) $(PSSRC)zfname.c
-$(PSOBJ)zfproc.$(OBJ): $(PSSRC)zfproc.c $(GH) $(memory__h)\
+$(PSOBJ)zfproc.$(OBJ) : $(PSSRC)zfproc.c $(GH) $(memory__h)\
$(oper_h)\
$(estack_h) $(files_h) $(gsstruct_h) $(ialloc_h) $(ifilter_h) $(istruct_h)\
$(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)zfproc.$(OBJ) $(C_) $(PSSRC)zfproc.c
-$(PSOBJ)zgeneric.$(OBJ): $(PSSRC)zgeneric.c $(OP) $(memory__h)\
- $(idict_h) $(estack_h) $(ivmspace_h) $(iname_h) $(ipacked_h) $(store_h)
+$(PSOBJ)zgeneric.$(OBJ) : $(PSSRC)zgeneric.c $(OP) $(memory__h)\
+ $(gsstruct_h)\
+ $(iddict_h) $(estack_h) $(ivmspace_h) $(iname_h) $(ipacked_h) $(store_h)
$(PSCC) $(PSO_)zgeneric.$(OBJ) $(C_) $(PSSRC)zgeneric.c
-$(PSOBJ)ziodev.$(OBJ): $(PSSRC)ziodev.c $(OP)\
+$(PSOBJ)ziodev.$(OBJ) : $(PSSRC)ziodev.c $(OP)\
$(memory__h) $(stdio__h) $(string__h)\
$(gp_h) $(gpcheck_h)\
- $(gsstruct_h) $(gxiodev_h)\
+ $(gxiodev_h)\
$(files_h) $(ialloc_h) $(iscan_h) $(ivmspace_h)\
$(scanchar_h) $(store_h) $(stream_h)
$(PSCC) $(PSO_)ziodev.$(OBJ) $(C_) $(PSSRC)ziodev.c
-$(PSOBJ)zmath.$(OBJ): $(PSSRC)zmath.c $(OP) $(math__h) $(gxfarith_h) $(store_h)
+$(PSOBJ)zmath.$(OBJ) : $(PSSRC)zmath.c $(OP) $(math__h) $(gxfarith_h) $(store_h)
$(PSCC) $(PSO_)zmath.$(OBJ) $(C_) $(PSSRC)zmath.c
-$(PSOBJ)zmisc.$(OBJ): $(PSSRC)zmisc.c $(OP) $(gscdefs_h) $(gp_h)\
+$(PSOBJ)zmisc.$(OBJ) : $(PSSRC)zmisc.c $(OP) $(gscdefs_h) $(gp_h)\
$(errno__h) $(memory__h) $(string__h)\
$(ialloc_h) $(idict_h) $(dstack_h) $(iname_h) $(ivmspace_h) $(ipacked_h) $(store_h)
$(PSCC) $(PSO_)zmisc.$(OBJ) $(C_) $(PSSRC)zmisc.c
-$(PSOBJ)zpacked.$(OBJ): $(PSSRC)zpacked.c $(OP)\
+$(PSOBJ)zpacked.$(OBJ) : $(PSSRC)zpacked.c $(OP)\
$(ialloc_h) $(idict_h) $(ivmspace_h) $(iname_h) $(ipacked_h) $(iparray_h)\
$(istack_h) $(store_h)
$(PSCC) $(PSO_)zpacked.$(OBJ) $(C_) $(PSSRC)zpacked.c
-$(PSOBJ)zrelbit.$(OBJ): $(PSSRC)zrelbit.c $(OP)\
+$(PSOBJ)zrelbit.$(OBJ) : $(PSSRC)zrelbit.c $(OP)\
$(gsutil_h) $(store_h) $(idict_h)
$(PSCC) $(PSO_)zrelbit.$(OBJ) $(C_) $(PSSRC)zrelbit.c
-$(PSOBJ)zstack.$(OBJ): $(PSSRC)zstack.c $(OP) $(memory__h)\
+$(PSOBJ)zstack.$(OBJ) : $(PSSRC)zstack.c $(OP) $(memory__h)\
$(ialloc_h) $(istack_h) $(store_h)
$(PSCC) $(PSO_)zstack.$(OBJ) $(C_) $(PSSRC)zstack.c
-$(PSOBJ)zstring.$(OBJ): $(PSSRC)zstring.c $(OP) $(memory__h)\
+$(PSOBJ)zstring.$(OBJ) : $(PSSRC)zstring.c $(OP) $(memory__h)\
$(gsutil_h)\
$(ialloc_h) $(iname_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)zstring.$(OBJ) $(C_) $(PSSRC)zstring.c
-$(PSOBJ)zsysvm.$(OBJ): $(PSSRC)zsysvm.c $(GH)\
+$(PSOBJ)zsysvm.$(OBJ) : $(PSSRC)zsysvm.c $(GH)\
$(ialloc_h) $(ivmspace_h) $(oper_h) $(store_h)
$(PSCC) $(PSO_)zsysvm.$(OBJ) $(C_) $(PSSRC)zsysvm.c
-$(PSOBJ)ztoken.$(OBJ): $(PSSRC)ztoken.c $(OP)\
+$(PSOBJ)ztoken.$(OBJ) : $(PSSRC)ztoken.c $(OP)\
$(estack_h) $(files_h) $(gsstruct_h) $(iscan_h)\
$(sfilter_h) $(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)ztoken.$(OBJ) $(C_) $(PSSRC)ztoken.c
-$(PSOBJ)ztype.$(OBJ): $(PSSRC)ztype.c $(OP)\
+$(PSOBJ)ztype.$(OBJ) : $(PSSRC)ztype.c $(OP)\
$(math__h) $(memory__h) $(string__h)\
$(gsexit_h)\
$(dstack_h) $(idict_h) $(imemory_h) $(iname_h)\
$(iscan_h) $(iutil_h) $(sfilter_h) $(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)ztype.$(OBJ) $(C_) $(PSSRC)ztype.c
-$(PSOBJ)zvmem.$(OBJ): $(PSSRC)zvmem.c $(OP)\
+$(PSOBJ)zvmem.$(OBJ) : $(PSSRC)zvmem.c $(OP)\
$(dstack_h) $(estack_h) $(files_h)\
$(ialloc_h) $(idict_h) $(igstate_h) $(isave_h) $(store_h) $(stream_h)\
$(gsmalloc_h) $(gsmatrix_h) $(gsstate_h) $(gsstruct_h)
@@ -356,67 +396,69 @@ $(PSOBJ)zvmem.$(OBJ): $(PSSRC)zvmem.c $(OP)\
### Graphics operators
-$(PSOBJ)zchar.$(OBJ): $(PSSRC)zchar.c $(OP)\
+$(PSOBJ)zbfont.$(OBJ) : $(PSSRC)zbfont.c $(OP) $(memory__h) $(string__h)\
+ $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h)\
+ $(bfont_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ilevel_h)\
+ $(iname_h) $(interp_h) $(istruct_h) $(ipacked_h) $(store_h)
+ $(PSCC) $(PSO_)zbfont.$(OBJ) $(C_) $(PSSRC)zbfont.c
+
+$(PSOBJ)zchar.$(OBJ) : $(PSSRC)zchar.c $(OP)\
$(gsstruct_h) $(gxarith_h) $(gxfixed_h) $(gxmatrix_h)\
- $(gxchar_h) $(gxdevice_h) $(gxfont_h) $(gzpath_h) $(gzstate_h)\
+ $(gxchar_h) $(gxdevice_h) $(gxfont_h) $(gzstate_h)\
$(dstack_h) $(estack_h) $(ialloc_h) $(ichar_h) $(idict_h) $(ifont_h)\
$(ilevel_h) $(iname_h) $(igstate_h) $(ipacked_h) $(store_h)
$(PSCC) $(PSO_)zchar.$(OBJ) $(C_) $(PSSRC)zchar.c
# zcharout is used for Type 1 and Type 42 fonts only.
-$(PSOBJ)zcharout.$(OBJ): $(PSSRC)zcharout.c $(OP)\
+$(PSOBJ)zcharout.$(OBJ) : $(PSSRC)zcharout.c $(OP)\
$(gschar_h) $(gxdevice_h) $(gxfont_h)\
$(dstack_h) $(estack_h) $(ichar_h) $(icharout_h)\
$(idict_h) $(ifont_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zcharout.$(OBJ) $(C_) $(PSSRC)zcharout.c
-$(PSOBJ)zcolor.$(OBJ): $(PSSRC)zcolor.c $(OP)\
+$(PSOBJ)zcolor.$(OBJ) : $(PSSRC)zcolor.c $(OP)\
$(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gxdevice_h) $(gxcmap_h)\
$(ialloc_h) $(icolor_h) $(estack_h) $(iutil_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zcolor.$(OBJ) $(C_) $(PSSRC)zcolor.c
-$(PSOBJ)zdevice.$(OBJ): $(PSSRC)zdevice.c $(OP) $(string__h)\
+$(PSOBJ)zdevice.$(OBJ) : $(PSSRC)zdevice.c $(OP) $(string__h)\
$(ialloc_h) $(idict_h) $(igstate_h) $(iname_h) $(interp_h) $(iparam_h) $(ivmspace_h)\
$(gsmatrix_h) $(gsstate_h) $(gxdevice_h) $(gxgetbit_h) $(store_h)
$(PSCC) $(PSO_)zdevice.$(OBJ) $(C_) $(PSSRC)zdevice.c
-$(PSOBJ)zfont.$(OBJ): $(PSSRC)zfont.c $(OP)\
+$(PSOBJ)zfont.$(OBJ) : $(PSSRC)zfont.c $(OP)\
$(gschar_h) $(gsstruct_h) $(gxdevice_h) $(gxfont_h) $(gxfcache_h)\
$(gzstate_h)\
- $(ialloc_h) $(idict_h) $(igstate_h) $(iname_h) $(isave_h) $(ivmspace_h)\
+ $(ialloc_h) $(iddict_h) $(igstate_h) $(iname_h) $(isave_h) $(ivmspace_h)\
$(bfont_h) $(store_h)
$(PSCC) $(PSO_)zfont.$(OBJ) $(C_) $(PSSRC)zfont.c
-$(PSOBJ)zfont2.$(OBJ): $(PSSRC)zfont2.c $(OP) $(memory__h) $(string__h)\
- $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h)\
- $(bfont_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ilevel_h)\
- $(iname_h) $(interp_h) $(istruct_h) $(ipacked_h) $(store_h)
- $(PSCC) $(PSO_)zfont2.$(OBJ) $(C_) $(PSSRC)zfont2.c
-
-$(PSOBJ)zgstate.$(OBJ): $(PSSRC)zgstate.c $(OP) $(math__h)\
- $(gsmatrix_h) $(ialloc_h) $(idict_h) $(igstate_h) $(istruct_h) $(store_h)
+$(PSOBJ)zgstate.$(OBJ) : $(PSSRC)zgstate.c $(OP) $(math__h)\
+ $(gsmatrix_h)\
+ $(ialloc_h) $(icremap_h) $(idict_h) $(igstate_h) $(istruct_h) $(store_h)
$(PSCC) $(PSO_)zgstate.$(OBJ) $(C_) $(PSSRC)zgstate.c
-$(PSOBJ)zht.$(OBJ): $(PSSRC)zht.c $(OP) $(memory__h)\
+$(PSOBJ)zht.$(OBJ) : $(PSSRC)zht.c $(OP) $(memory__h)\
$(gsmatrix_h) $(gsstate_h) $(gsstruct_h) $(gxdevice_h) $(gzht_h)\
$(ialloc_h) $(estack_h) $(igstate_h) $(iht_h) $(store_h)
$(PSCC) $(PSO_)zht.$(OBJ) $(C_) $(PSSRC)zht.c
-$(PSOBJ)zimage.$(OBJ): $(PSSRC)zimage.c $(OP)\
- $(gscspace_h) $(gsimage_h) $(gsmatrix_h) $(gsstruct_h) $(gxiparam_h)\
+$(PSOBJ)zimage.$(OBJ) : $(PSSRC)zimage.c $(OP)\
+ $(gschar_h) $(gscspace_h) $(gscssub_h) $(gsimage_h) $(gsmatrix_h) $(gsstruct_h)\
+ $(gxiparam_h)\
$(estack_h) $(ialloc_h) $(ifilter_h) $(igstate_h) $(iimage_h) $(ilevel_h)\
$(store_h) $(stream_h)
$(PSCC) $(PSO_)zimage.$(OBJ) $(C_) $(PSSRC)zimage.c
-$(PSOBJ)zmatrix.$(OBJ): $(PSSRC)zmatrix.c $(OP)\
+$(PSOBJ)zmatrix.$(OBJ) : $(PSSRC)zmatrix.c $(OP)\
$(gsmatrix_h) $(igstate_h) $(gscoord_h) $(store_h)
$(PSCC) $(PSO_)zmatrix.$(OBJ) $(C_) $(PSSRC)zmatrix.c
-$(PSOBJ)zpaint.$(OBJ): $(PSSRC)zpaint.c $(OP)\
+$(PSOBJ)zpaint.$(OBJ) : $(PSSRC)zpaint.c $(OP)\
$(gspaint_h) $(igstate_h)
$(PSCC) $(PSO_)zpaint.$(OBJ) $(C_) $(PSSRC)zpaint.c
-$(PSOBJ)zpath.$(OBJ): $(PSSRC)zpath.c $(OP) $(math__h)\
+$(PSOBJ)zpath.$(OBJ) : $(PSSRC)zpath.c $(OP) $(math__h)\
$(gsmatrix_h) $(gspath_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zpath.$(OBJ) $(C_) $(PSSRC)zpath.c
@@ -428,8 +470,8 @@ INT2=$(PSOBJ)idparam.$(OBJ) $(PSOBJ)idstack.$(OBJ) $(PSOBJ)iinit.$(OBJ)
INT3=$(PSOBJ)interp.$(OBJ)
INT4=$(PSOBJ)iparam.$(OBJ) $(PSOBJ)ireclaim.$(OBJ)
INT5=$(PSOBJ)iscan.$(OBJ) $(PSOBJ)iscannum.$(OBJ) $(PSOBJ)istack.$(OBJ)
-INT6=$(PSOBJ)iutil.$(OBJ) $(GLOBJ)scantab.$(OBJ) $(PSOBJ)sfilter1.$(OBJ)
-INT7=$(GLOBJ)sstring.$(OBJ) $(GLOBJ)stream.$(OBJ)
+INT6=$(PSOBJ)iutil.$(OBJ) $(GLOBJ)sa85d.$(OBJ) $(GLOBJ)scantab.$(OBJ)
+INT7=$(PSOBJ)sfilter1.$(OBJ) $(GLOBJ)sstring.$(OBJ) $(GLOBJ)stream.$(OBJ)
Z1=$(PSOBJ)zarith.$(OBJ) $(PSOBJ)zarray.$(OBJ) $(PSOBJ)zcontrol.$(OBJ)
Z2=$(PSOBJ)zdict.$(OBJ) $(PSOBJ)zfile.$(OBJ) $(PSOBJ)zfileio.$(OBJ)
Z3=$(PSOBJ)zfilter.$(OBJ) $(PSOBJ)zfname.$(OBJ) $(PSOBJ)zfproc.$(OBJ)
@@ -437,15 +479,17 @@ Z4=$(PSOBJ)zgeneric.$(OBJ) $(PSOBJ)ziodev.$(OBJ) $(PSOBJ)zmath.$(OBJ)
Z5=$(PSOBJ)zmisc.$(OBJ) $(PSOBJ)zpacked.$(OBJ) $(PSOBJ)zrelbit.$(OBJ)
Z6=$(PSOBJ)zstack.$(OBJ) $(PSOBJ)zstring.$(OBJ) $(PSOBJ)zsysvm.$(OBJ)
Z7=$(PSOBJ)ztoken.$(OBJ) $(PSOBJ)ztype.$(OBJ) $(PSOBJ)zvmem.$(OBJ)
-Z8=$(PSOBJ)zchar.$(OBJ) $(PSOBJ)zcolor.$(OBJ) $(PSOBJ)zdevice.$(OBJ)
-Z9=$(PSOBJ)zfont.$(OBJ) $(PSOBJ)zfont2.$(OBJ) $(PSOBJ)zgstate.$(OBJ)
+Z8=$(PSOBJ)zbfont.$(OBJ) $(PSOBJ)zchar.$(OBJ) $(PSOBJ)zcolor.$(OBJ)
+Z9=$(PSOBJ)zdevice.$(OBJ) $(PSOBJ)zfont.$(OBJ) $(PSOBJ)zgstate.$(OBJ)
Z10=$(PSOBJ)zht.$(OBJ) $(PSOBJ)zimage.$(OBJ) $(PSOBJ)zmatrix.$(OBJ)
Z11=$(PSOBJ)zpaint.$(OBJ) $(PSOBJ)zpath.$(OBJ)
-Z1_2OPS=zarith zarray zcontrol zdict zfile zfileio
+Z1OPS=zarith zarray zcontrol1 zcontrol2 zcontrol3
+Z2OPS=zdict1 zdict2 zfile zfileio1 zfileio2
Z3_4OPS=zfilter zfproc zgeneric ziodev zmath
Z5_6OPS=zmisc zpacked zrelbit zstack zstring zsysvm
-Z7_8OPS=ztoken ztype zvmem zchar zcolor zdevice
-Z9_10OPS=zfont zfont2 zgstate zht zimage zmatrix
+Z7_8OPS=ztoken ztype zvmem zbfont zchar zcolor
+Z9OPS=zdevice zfont zgstate1 zgstate2
+Z10OPS=zht zimage zmatrix
Z11OPS=zpaint zpath
# We have to be a little underhanded with *config.$(OBJ) so as to avoid
# circular definitions.
@@ -453,8 +497,8 @@ INT_MAIN=$(PSOBJ)imain.$(OBJ) $(PSOBJ)imainarg.$(OBJ) $(GLOBJ)gsargs.$(OBJ)
INT_OBJS=$(INT_MAIN)\
$(INT1) $(INT2) $(INT3) $(INT4) $(INT5) $(INT6) $(INT7)\
$(Z1) $(Z2) $(Z3) $(Z4) $(Z5) $(Z6) $(Z7) $(Z8) $(Z9) $(Z10) $(Z11)
-INT_CONFIG=$(GLOBJ)$(gconfig).$(OBJ) $(GLOBJ)$(gscdefs).$(OBJ)\
- $(PSOBJ)$(iconfig).$(OBJ) $(PSOBJ)iccinit$(COMPILE_INITS).$(OBJ)
+INT_CONFIG=$(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)\
+ $(PSOBJ)iconfig.$(OBJ) $(PSOBJ)iccinit$(COMPILE_INITS).$(OBJ)
INT_ALL=$(INT_OBJS) $(INT_CONFIG)
# We omit libcore.dev, which should be included here, because problems
# with the Unix linker require libcore to appear last in the link list
@@ -463,67 +507,72 @@ INT_ALL=$(INT_OBJS) $(INT_CONFIG)
# dependency requirements and are added to the link list at the very end.
# zfilter.c shouldn't include the RLE and RLD filters, but we don't want to
# change this now.
-psbase.dev: $(INT_MAK) $(ECHOGS_XE) $(INT_OBJS)\
- isupport.dev nousparm.dev rld.dev rle.dev sfile.dev
- $(SETMOD) psbase $(INT_MAIN)
- $(ADDMOD) psbase -obj $(INT_CONFIG)
- $(ADDMOD) psbase -obj $(INT1)
- $(ADDMOD) psbase -obj $(INT2)
- $(ADDMOD) psbase -obj $(INT3)
- $(ADDMOD) psbase -obj $(INT4)
- $(ADDMOD) psbase -obj $(INT5)
- $(ADDMOD) psbase -obj $(INT6)
- $(ADDMOD) psbase -obj $(INT7)
- $(ADDMOD) psbase -obj $(Z1)
- $(ADDMOD) psbase -obj $(Z2)
- $(ADDMOD) psbase -obj $(Z3)
- $(ADDMOD) psbase -obj $(Z4)
- $(ADDMOD) psbase -obj $(Z5)
- $(ADDMOD) psbase -obj $(Z6)
- $(ADDMOD) psbase -obj $(Z7)
- $(ADDMOD) psbase -obj $(Z8)
- $(ADDMOD) psbase -obj $(Z9)
- $(ADDMOD) psbase -obj $(Z10)
- $(ADDMOD) psbase -obj $(Z11)
- $(ADDMOD) psbase -oper $(Z1_2OPS)
- $(ADDMOD) psbase -oper $(Z3_4OPS)
- $(ADDMOD) psbase -oper $(Z5_6OPS)
- $(ADDMOD) psbase -oper $(Z7_8OPS)
- $(ADDMOD) psbase -oper $(Z9_10OPS)
- $(ADDMOD) psbase -oper $(Z11OPS)
- $(ADDMOD) psbase -iodev stdin stdout stderr lineedit statementedit
- $(ADDMOD) psbase -include isupport nousparm rld rle sfile
+$(PSD)psbase.dev : $(INT_MAK) $(ECHOGS_XE) $(INT_OBJS)\
+ $(PSD)isupport.dev $(PSD)nobtoken.dev $(PSD)nousparm.dev\
+ $(GLD)rld.dev $(GLD)rle.dev $(GLD)sfile.dev
+ $(SETMOD) $(PSD)psbase $(INT_MAIN)
+ $(ADDMOD) $(PSD)psbase -obj $(INT_CONFIG)
+ $(ADDMOD) $(PSD)psbase -obj $(INT1)
+ $(ADDMOD) $(PSD)psbase -obj $(INT2)
+ $(ADDMOD) $(PSD)psbase -obj $(INT3)
+ $(ADDMOD) $(PSD)psbase -obj $(INT4)
+ $(ADDMOD) $(PSD)psbase -obj $(INT5)
+ $(ADDMOD) $(PSD)psbase -obj $(INT6)
+ $(ADDMOD) $(PSD)psbase -obj $(INT7)
+ $(ADDMOD) $(PSD)psbase -obj $(Z1)
+ $(ADDMOD) $(PSD)psbase -obj $(Z2)
+ $(ADDMOD) $(PSD)psbase -obj $(Z3)
+ $(ADDMOD) $(PSD)psbase -obj $(Z4)
+ $(ADDMOD) $(PSD)psbase -obj $(Z5)
+ $(ADDMOD) $(PSD)psbase -obj $(Z6)
+ $(ADDMOD) $(PSD)psbase -obj $(Z7)
+ $(ADDMOD) $(PSD)psbase -obj $(Z8)
+ $(ADDMOD) $(PSD)psbase -obj $(Z9)
+ $(ADDMOD) $(PSD)psbase -obj $(Z10)
+ $(ADDMOD) $(PSD)psbase -obj $(Z11)
+ $(ADDMOD) $(PSD)psbase -oper $(Z1OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z2OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z3_4OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z5_6OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z7_8OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z9OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z10OPS)
+ $(ADDMOD) $(PSD)psbase -oper $(Z11OPS)
+ $(ADDMOD) $(PSD)psbase -iodev stdin stdout stderr lineedit statementedit
+ $(ADDMOD) $(PSD)psbase -include $(PSD)isupport $(PSD)nobtoken $(PSD)nousparm
+ $(ADDMOD) $(PSD)psbase -include $(GLD)rld $(GLD)rle $(GLD)sfile
# -------------------------- Feature definitions -------------------------- #
# ---------------- Full Level 1 interpreter ---------------- #
# We keep the old name for backward compatibility.
-level1.dev: psl1.dev
- $(CP_) psl1.dev level1.dev
+$(PSD)level1.dev : $(PSD)psl1.dev
+ $(CP_) $(PSD)psl1.dev $(PSD)level1.dev
-psl1.dev: $(INT_MAK) $(ECHOGS_XE) psbase.dev bcp.dev hsb.dev path1.dev type1.dev
- $(SETMOD) psl1 -include psbase bcp hsb path1 type1
- $(ADDMOD) psl1 -emulator PostScript PostScriptLevel1
+$(PSD)psl1.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)psbase.dev $(PSD)bcp.dev $(PSD)hsb.dev $(PSD)path1.dev $(PSD)type1.dev
+ $(SETMOD) $(PSD)psl1 -include $(PSD)psbase $(PSD)bcp $(PSD)hsb $(PSD)path1 $(PSD)type1
+ $(ADDMOD) $(PSD)psl1 -emulator PostScript PostScriptLevel1
# -------- Level 1 color extensions (CMYK color and colorimage) -------- #
-color.dev: $(INT_MAK) $(ECHOGS_XE) cmyklib.dev colimlib.dev cmykread.dev
- $(SETMOD) color -include cmyklib colimlib cmykread
+$(PSD)color.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)cmyklib.dev $(GLD)colimlib.dev $(PSD)cmykread.dev
+ $(SETMOD) $(PSD)color -include $(GLD)cmyklib $(GLD)colimlib $(PSD)cmykread
cmykread_=$(PSOBJ)zcolor1.$(OBJ) $(PSOBJ)zht1.$(OBJ)
-cmykread.dev: $(INT_MAK) $(ECHOGS_XE) $(cmykread_)
- $(SETMOD) cmykread $(cmykread_)
- $(ADDMOD) cmykread -oper zcolor1 zht1
+$(PSD)cmykread.dev : $(INT_MAK) $(ECHOGS_XE) $(cmykread_)
+ $(SETMOD) $(PSD)cmykread $(cmykread_)
+ $(ADDMOD) $(PSD)cmykread -oper zcolor1 zht1
-$(PSOBJ)zcolor1.$(OBJ): $(PSSRC)zcolor1.c $(OP)\
- $(gscolor1_h)\
+$(PSOBJ)zcolor1.$(OBJ) : $(PSSRC)zcolor1.c $(OP)\
+ $(gscolor1_h) $(gscssub_h)\
$(gxcmap_h) $(gxcspace_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h)\
$(gzstate_h)\
$(ialloc_h) $(icolor_h) $(iimage_h) $(estack_h) $(iutil_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zcolor1.$(OBJ) $(C_) $(PSSRC)zcolor1.c
-$(PSOBJ)zht1.$(OBJ): $(PSSRC)zht1.c $(OP) $(memory__h)\
+$(PSOBJ)zht1.$(OBJ) : $(PSSRC)zht1.c $(OP) $(memory__h)\
$(gsmatrix_h) $(gsstate_h) $(gsstruct_h) $(gxdevice_h) $(gzht_h)\
$(ialloc_h) $(estack_h) $(igstate_h) $(iht_h) $(store_h)
$(PSCC) $(PSO_)zht1.$(OBJ) $(C_) $(PSSRC)zht1.c
@@ -531,24 +580,24 @@ $(PSOBJ)zht1.$(OBJ): $(PSSRC)zht1.c $(OP) $(memory__h)\
# ---------------- HSB color ---------------- #
hsb_=$(PSOBJ)zhsb.$(OBJ)
-hsb.dev: $(INT_MAK) $(ECHOGS_XE) $(hsb_) hsblib.dev
- $(SETMOD) hsb $(hsb_)
- $(ADDMOD) hsb -include hsblib
- $(ADDMOD) hsb -oper zhsb
+$(PSD)hsb.dev : $(INT_MAK) $(ECHOGS_XE) $(hsb_) $(GLD)hsblib.dev
+ $(SETMOD) $(PSD)hsb $(hsb_)
+ $(ADDMOD) $(PSD)hsb -include $(GLD)hsblib
+ $(ADDMOD) $(PSD)hsb -oper zhsb
-$(PSOBJ)zhsb.$(OBJ): $(PSSRC)zhsb.c $(OP)\
+$(PSOBJ)zhsb.$(OBJ) : $(PSSRC)zhsb.c $(OP)\
$(gshsb_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zhsb.$(OBJ) $(C_) $(PSSRC)zhsb.c
# ---- Level 1 path miscellany (arcs, pathbbox, path enumeration) ---- #
path1_=$(PSOBJ)zpath1.$(OBJ)
-path1.dev: $(INT_MAK) $(ECHOGS_XE) $(path1_) path1lib.dev
- $(SETMOD) path1 $(path1_)
- $(ADDMOD) path1 -include path1lib
- $(ADDMOD) path1 -oper zpath1
+$(PSD)path1.dev : $(INT_MAK) $(ECHOGS_XE) $(path1_) $(GLD)path1lib.dev
+ $(SETMOD) $(PSD)path1 $(path1_)
+ $(ADDMOD) $(PSD)path1 -include $(GLD)path1lib
+ $(ADDMOD) $(PSD)path1 -oper zpath1
-$(PSOBJ)zpath1.$(OBJ): $(PSSRC)zpath1.c $(OP) $(memory__h)\
+$(PSOBJ)zpath1.$(OBJ) : $(PSSRC)zpath1.c $(OP) $(memory__h)\
$(ialloc_h) $(estack_h) $(gspath_h) $(gsstruct_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zpath1.$(OBJ) $(C_) $(PSSRC)zpath1.c
@@ -557,15 +606,15 @@ $(PSOBJ)zpath1.$(OBJ): $(PSSRC)zpath1.c $(OP) $(memory__h)\
# ---------------- BCP filters ---------------- #
bcp_=$(PSOBJ)sbcp.$(OBJ) $(PSOBJ)zfbcp.$(OBJ)
-bcp.dev: $(INT_MAK) $(ECHOGS_XE) $(bcp_)
- $(SETMOD) bcp $(bcp_)
- $(ADDMOD) bcp -oper zfbcp
+$(PSD)bcp.dev : $(INT_MAK) $(ECHOGS_XE) $(bcp_)
+ $(SETMOD) $(PSD)bcp $(bcp_)
+ $(ADDMOD) $(PSD)bcp -oper zfbcp
-$(PSOBJ)sbcp.$(OBJ): $(PSSRC)sbcp.c $(AK) $(stdio__h)\
+$(PSOBJ)sbcp.$(OBJ) : $(PSSRC)sbcp.c $(AK) $(stdio__h)\
$(sfilter_h) $(strimpl_h)
$(PSCC) $(PSO_)sbcp.$(OBJ) $(C_) $(PSSRC)sbcp.c
-$(PSOBJ)zfbcp.$(OBJ): $(PSSRC)zfbcp.c $(OP) $(memory__h)\
+$(PSOBJ)zfbcp.$(OBJ) : $(PSSRC)zfbcp.c $(OP) $(memory__h)\
$(gsstruct_h) $(ialloc_h) $(ifilter_h)\
$(sfilter_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)zfbcp.$(OBJ) $(C_) $(PSSRC)zfbcp.c
@@ -573,77 +622,76 @@ $(PSOBJ)zfbcp.$(OBJ): $(PSSRC)zfbcp.c $(OP) $(memory__h)\
# ---------------- Incremental font loading ---------------- #
# (This only works for Type 1 fonts without eexec encryption.)
-diskfont.dev: $(INT_MAK) $(ECHOGS_XE)
- $(SETMOD) diskfont -ps gs_diskf
+$(PSD)diskfont.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(PSD)diskfont -ps gs_diskf
# ---------------- Double-precision floats ---------------- #
double_=$(PSOBJ)zdouble.$(OBJ)
-double.dev: $(INT_MAK) $(ECHOGS_XE) $(double_)
- $(SETMOD) double $(double_)
- $(ADDMOD) double -oper zdouble
+$(PSD)double.dev : $(INT_MAK) $(ECHOGS_XE) $(double_)
+ $(SETMOD) $(PSD)double $(double_)
+ $(ADDMOD) $(PSD)double -oper zdouble1 zdouble2
-$(PSOBJ)zdouble.$(OBJ): $(PSSRC)zdouble.c $(OP)\
+$(PSOBJ)zdouble.$(OBJ) : $(PSSRC)zdouble.c $(OP)\
$(ctype__h) $(math__h) $(memory__h) $(string__h)\
$(gxfarith_h) $(store_h)
$(PSCC) $(PSO_)zdouble.$(OBJ) $(C_) $(PSSRC)zdouble.c
# ---------------- EPSF files with binary headers ---------------- #
-epsf.dev: $(INT_MAK) $(ECHOGS_XE)
- $(SETMOD) epsf -ps gs_epsf
+$(PSD)epsf.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(PSD)epsf -ps gs_epsf
# ---------------- RasterOp ---------------- #
# This should be a separable feature in the core also....
-rasterop.dev: $(INT_MAK) $(ECHOGS_XE) roplib.dev ropread.dev
- $(SETMOD) rasterop -include roplib ropread
+$(PSD)rasterop.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)roplib.dev $(PSD)ropread.dev
+ $(SETMOD) $(PSD)rasterop -include $(GLD)roplib $(PSD)ropread
ropread_=$(PSOBJ)zrop.$(OBJ)
-ropread.dev: $(INT_MAK) $(ECHOGS_XE) $(ropread_)
- $(SETMOD) ropread $(ropread_)
- $(ADDMOD) ropread -oper zrop
+$(PSD)ropread.dev : $(INT_MAK) $(ECHOGS_XE) $(ropread_)
+ $(SETMOD) $(PSD)ropread $(ropread_)
+ $(ADDMOD) $(PSD)ropread -oper zrop
-$(PSOBJ)zrop.$(OBJ): $(PSSRC)zrop.c $(OP) $(memory__h)\
+$(PSOBJ)zrop.$(OBJ) : $(PSSRC)zrop.c $(OP) $(memory__h)\
$(gsrop_h) $(gsutil_h) $(gxdevice_h)\
$(idict_h) $(idparam_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zrop.$(OBJ) $(C_) $(PSSRC)zrop.c
# ---------------- PostScript Type 1 (and Type 4) fonts ---------------- #
-type1.dev: $(INT_MAK) $(ECHOGS_XE) psf1lib.dev psf1read.dev
- $(SETMOD) type1 -include psf1lib psf1read
+$(PSD)type1.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)psf1lib.dev $(PSD)psf1read.dev
+ $(SETMOD) $(PSD)type1 -include $(GLD)psf1lib $(PSD)psf1read
psf1read_1=$(PSOBJ)seexec.$(OBJ) $(PSOBJ)zchar1.$(OBJ) $(PSOBJ)zcharout.$(OBJ)
psf1read_2=$(PSOBJ)zfont1.$(OBJ) $(PSOBJ)zmisc1.$(OBJ)
psf1read_=$(psf1read_1) $(psf1read_2)
-psf1read.dev: $(INT_MAK) $(ECHOGS_XE) $(psf1read_)
- $(SETMOD) psf1read $(psf1read_1)
- $(ADDMOD) psf1read -obj $(psf1read_2)
- $(ADDMOD) psf1read -oper zchar1 zfont1 zmisc1
- $(ADDMOD) psf1read -ps gs_type1
+$(PSD)psf1read.dev : $(INT_MAK) $(ECHOGS_XE) $(psf1read_)
+ $(SETMOD) $(PSD)psf1read $(psf1read_1)
+ $(ADDMOD) $(PSD)psf1read -obj $(psf1read_2)
+ $(ADDMOD) $(PSD)psf1read -oper zchar1 zfont1 zmisc1
+ $(ADDMOD) $(PSD)psf1read -ps gs_type1
-$(PSOBJ)seexec.$(OBJ): $(PSSRC)seexec.c $(AK) $(stdio__h)\
+$(PSOBJ)seexec.$(OBJ) : $(PSSRC)seexec.c $(AK) $(stdio__h)\
$(gscrypt1_h) $(scanchar_h) $(sfilter_h) $(strimpl_h)
$(PSCC) $(PSO_)seexec.$(OBJ) $(C_) $(PSSRC)seexec.c
-$(PSOBJ)zchar1.$(OBJ): $(PSSRC)zchar1.c $(OP)\
- $(gspaint_h) $(gspath_h) $(gsstruct_h)\
+$(PSOBJ)zchar1.$(OBJ) : $(PSSRC)zchar1.c $(OP) $(memory__h)\
+ $(gspaint_h) $(gspath_h) $(gsrect_h) $(gsstruct_h)\
$(gxchar_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h)\
$(gxfont_h) $(gxfont1_h) $(gxtype1_h) $(gzstate_h)\
- $(estack_h) $(ialloc_h) $(ichar_h) $(icharout_h)\
+ $(estack_h) $(ialloc_h) $(ichar_h) $(ichar1_h) $(icharout_h)\
$(idict_h) $(ifont_h) $(igstate_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zchar1.$(OBJ) $(C_) $(PSSRC)zchar1.c
-# The last line of dependencies is only for a debugging operator.
-$(PSOBJ)zfont1.$(OBJ): $(PSSRC)zfont1.c $(OP)\
+$(PSOBJ)zfont1.$(OBJ) : $(PSSRC)zfont1.c $(OP)\
$(gsmatrix_h) $(gxdevice_h) $(gschar_h)\
$(gxfixed_h) $(gxfont_h) $(gxfont1_h)\
- $(bfont_h) $(ialloc_h) $(idict_h) $(idparam_h) $(store_h)\
- $(files_h) $(igstate_h) $(stream_h)
+ $(bfont_h) $(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifont1_h)\
+ $(igstate_h) $(store_h) $(stream_h)
$(PSCC) $(PSO_)zfont1.$(OBJ) $(C_) $(PSSRC)zfont1.c
-$(PSOBJ)zmisc1.$(OBJ): $(PSSRC)zmisc1.c $(OP) $(memory__h)\
+$(PSOBJ)zmisc1.$(OBJ) : $(PSSRC)zmisc1.c $(OP) $(memory__h)\
$(gscrypt1_h)\
$(idict_h) $(idparam_h) $(ifilter_h)\
$(sfilter_h) $(stream_h) $(strimpl_h)
@@ -651,48 +699,62 @@ $(PSOBJ)zmisc1.$(OBJ): $(PSSRC)zmisc1.c $(OP) $(memory__h)\
# -------------- Compact Font Format and Type 2 charstrings ------------- #
-cff.dev: $(INT_MAK) $(ECHOGS_XE) $(PSSRC)gs_cff.ps psl2int.dev
- $(SETMOD) cff -ps gs_cff
+$(PSD)cff.dev : $(INT_MAK) $(ECHOGS_XE) $(PSD)psl2int.dev
+ $(SETMOD) $(PSD)cff -include $(PSD)psl2int -ps gs_cff
+
+$(PSOBJ)zchar2.$(OBJ) : $(PSSRC)zchar2.c $(OP)\
+ $(gxfixed_h) $(gxmatrix_h) $(gxfont_h) $(gxfont1_h) $(gxtype1_h)\
+ $(ichar1_h)
+ $(PSCC) $(PSO_)zchar2.$(OBJ) $(C_) $(PSSRC)zchar2.c
+
+$(PSOBJ)zfont2.$(OBJ) : $(PSSRC)zfont2.c $(OP)\
+ $(gsmatrix_h) $(gxfixed_h) $(gxfont_h) $(gxfont1_h)\
+ $(bfont_h) $(idict_h) $(idparam_h) $(ifont1_h)
+ $(PSCC) $(PSO_)zfont2.$(OBJ) $(C_) $(PSSRC)zfont2.c
-type2.dev: $(INT_MAK) $(ECHOGS_XE) type1.dev psf2lib.dev
- $(SETMOD) type2 -include psf2lib
+type2_=$(PSOBJ)zchar2.$(OBJ) $(PSOBJ)zfont2.$(OBJ)
+$(PSD)type2.dev : $(INT_MAK) $(ECHOGS_XE) $(type2_)\
+ $(PSD)type1.dev $(GLD)psf2lib.dev
+ $(SETMOD) $(PSD)type2 $(type2_)
+ $(ADDMOD) $(PSD)type2 -oper zchar2 zfont2
+ $(ADDMOD) $(PSD)type2 -include $(PSD)type1 $(GLD)psf2lib
# ---------------- Type 32 (downloaded bitmap) fonts ---------------- #
-$(PSOBJ)zchar32.$(OBJ): $(PSSRC)zchar32.c $(OP)\
+$(PSOBJ)zchar32.$(OBJ) : $(PSSRC)zchar32.c $(OP)\
$(gsccode_h) $(gsmatrix_h) $(gsutil_h)\
$(gxchar_h) $(gxfcache_h) $(gxfixed_h) $(gxfont_h)\
$(ifont_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zchar32.$(OBJ) $(C_) $(PSSRC)zchar32.c
-$(PSOBJ)zfont32.$(OBJ): $(PSSRC)zfont32.c $(OP)\
+$(PSOBJ)zfont32.$(OBJ) : $(PSSRC)zfont32.c $(OP)\
$(gsccode_h) $(gsmatrix_h) $(gsutil_h)\
$(gxchar_h) $(gxfixed_h) $(gxfont_h)\
$(bfont_h) $(store_h)
$(PSCC) $(PSO_)zfont32.$(OBJ) $(C_) $(PSSRC)zfont32.c
type32_=$(PSOBJ)zchar32.$(OBJ) $(PSOBJ)zfont32.$(OBJ)
-type32.dev: $(INT_MAK) $(ECHOGS_XE) $(type32_)
- $(SETMOD) type32 $(type32_)
- $(ADDMOD) type32 -oper zchar32 zfont32
- $(ADDMOD) type32 -ps gs_res gs_typ32
+$(PSD)type32.dev : $(INT_MAK) $(ECHOGS_XE) $(type32_)
+ $(SETMOD) $(PSD)type32 $(type32_)
+ $(ADDMOD) $(PSD)type32 -oper zchar32 zfont32
+ $(ADDMOD) $(PSD)type32 -ps gs_res gs_typ32
# ---------------- TrueType and PostScript Type 42 fonts ---------------- #
# Native TrueType support
-ttfont.dev: $(INT_MAK) $(ECHOGS_XE) type42.dev
- $(SETMOD) ttfont -include type42
- $(ADDMOD) ttfont -ps gs_mro_e gs_wan_e gs_ttf
+$(PSD)ttfont.dev : $(INT_MAK) $(ECHOGS_XE) $(PSD)type42.dev
+ $(SETMOD) $(PSD)ttfont -include $(PSD)type42
+ $(ADDMOD) $(PSD)ttfont -ps gs_mro_e gs_wan_e gs_ttf
# Type 42 (embedded TrueType) support
type42read_=$(PSOBJ)zchar42.$(OBJ) $(PSOBJ)zcharout.$(OBJ) $(PSOBJ)zfont42.$(OBJ)
-type42.dev: $(INT_MAK) $(ECHOGS_XE) $(type42read_) ttflib.dev
- $(SETMOD) type42 $(type42read_)
- $(ADDMOD) type42 -include ttflib
- $(ADDMOD) type42 -oper zchar42 zfont42
- $(ADDMOD) type42 -ps gs_typ42
+$(PSD)type42.dev : $(INT_MAK) $(ECHOGS_XE) $(type42read_) $(GLD)ttflib.dev
+ $(SETMOD) $(PSD)type42 $(type42read_)
+ $(ADDMOD) $(PSD)type42 -include $(GLD)ttflib
+ $(ADDMOD) $(PSD)type42 -oper zchar42 zfont42
+ $(ADDMOD) $(PSD)type42 -ps gs_typ42
-$(PSOBJ)zchar42.$(OBJ): $(PSSRC)zchar42.c $(OP)\
+$(PSOBJ)zchar42.$(OBJ) : $(PSSRC)zchar42.c $(OP)\
$(gsmatrix_h) $(gspaint_h) $(gspath_h)\
$(gxfixed_h) $(gxchar_h) $(gxfont_h) $(gxfont42_h)\
$(gxistate_h) $(gxpath_h) $(gzstate_h)\
@@ -700,7 +762,7 @@ $(PSOBJ)zchar42.$(OBJ): $(PSSRC)zchar42.c $(OP)\
$(ifont_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zchar42.$(OBJ) $(C_) $(PSSRC)zchar42.c
-$(PSOBJ)zfont42.$(OBJ): $(PSSRC)zfont42.c $(OP) $(memory__h)\
+$(PSOBJ)zfont42.$(OBJ) : $(PSSRC)zfont42.c $(OP) $(memory__h)\
$(gsccode_h) $(gsmatrix_h) $(gxfont_h) $(gxfont42_h)\
$(bfont_h) $(idict_h) $(idparam_h) $(store_h)
$(PSCC) $(PSO_)zfont42.$(OBJ) $(C_) $(PSSRC)zfont42.c
@@ -710,7 +772,8 @@ $(PSOBJ)zfont42.$(OBJ): $(PSSRC)zfont42.c $(OP) $(memory__h)\
# ---------------- Precompiled fonts ---------------- #
# See Fonts.htm for more information.
-ccfont_h=$(PSSRC)ccfont.h $(std_h) $(gsmemory_h) $(iref_h) $(ivmspace_h) $(store_h)
+ccfont_h=$(PSSRC)ccfont.h $(stdpre_h) $(gsmemory_h)\
+ $(iref_h) $(ivmspace_h) $(store_h)
CCFONT=$(OP) $(ccfont_h)
@@ -722,35 +785,35 @@ CCFONT=$(OP) $(ccfont_h)
# The rules for constructing the .c files from the fonts themselves,
# and for compiling the .c files, are in cfonts.mak, not here.
# For example, to compile the Courier fonts, you should invoke
-# make -f cfonts.mak Courier_o
+# make Courier_o
# By convention, the names of the 35 standard compiled fonts use '0' for
# the foundry name. This allows users to substitute different foundries
# without having to change this makefile.
ccfonts_ps=gs_ccfnt
-ccfonts1_=0agk.$(OBJ) 0agko.$(OBJ) 0agd.$(OBJ) 0agdo.$(OBJ)
+ccfonts1_=$(PSOBJ)0agk.$(OBJ) $(PSOBJ)0agko.$(OBJ) $(PSOBJ)0agd.$(OBJ) $(PSOBJ)0agdo.$(OBJ)
ccfonts1=agk agko agd agdo
-ccfonts2_=0bkl.$(OBJ) 0bkli.$(OBJ) 0bkd.$(OBJ) 0bkdi.$(OBJ)
+ccfonts2_=$(PSOBJ)0bkl.$(OBJ) $(PSOBJ)0bkli.$(OBJ) $(PSOBJ)0bkd.$(OBJ) $(PSOBJ)0bkdi.$(OBJ)
ccfonts2=bkl bkli bkd bkdi
-ccfonts3_=0crr.$(OBJ) 0cri.$(OBJ) 0crb.$(OBJ) 0crbi.$(OBJ)
+ccfonts3_=$(PSOBJ)0crr.$(OBJ) $(PSOBJ)0cri.$(OBJ) $(PSOBJ)0crb.$(OBJ) $(PSOBJ)0crbi.$(OBJ)
ccfonts3=crr cri crb crbi
-ccfonts4_=0hvr.$(OBJ) 0hvro.$(OBJ) 0hvb.$(OBJ) 0hvbo.$(OBJ)
+ccfonts4_=$(PSOBJ)0hvr.$(OBJ) $(PSOBJ)0hvro.$(OBJ) $(PSOBJ)0hvb.$(OBJ) $(PSOBJ)0hvbo.$(OBJ)
ccfonts4=hvr hvro hvb hvbo
-ccfonts5_=0hvrrn.$(OBJ) 0hvrorn.$(OBJ) 0hvbrn.$(OBJ) 0hvborn.$(OBJ)
+ccfonts5_=$(PSOBJ)0hvrrn.$(OBJ) $(PSOBJ)0hvrorn.$(OBJ) $(PSOBJ)0hvbrn.$(OBJ) $(PSOBJ)0hvborn.$(OBJ)
ccfonts5=hvrrn hvrorn hvbrn hvborn
-ccfonts6_=0ncr.$(OBJ) 0ncri.$(OBJ) 0ncb.$(OBJ) 0ncbi.$(OBJ)
+ccfonts6_=$(PSOBJ)0ncr.$(OBJ) $(PSOBJ)0ncri.$(OBJ) $(PSOBJ)0ncb.$(OBJ) $(PSOBJ)0ncbi.$(OBJ)
ccfonts6=ncr ncri ncb ncbi
-ccfonts7_=0plr.$(OBJ) 0plri.$(OBJ) 0plb.$(OBJ) 0plbi.$(OBJ)
+ccfonts7_=$(PSOBJ)0plr.$(OBJ) $(PSOBJ)0plri.$(OBJ) $(PSOBJ)0plb.$(OBJ) $(PSOBJ)0plbi.$(OBJ)
ccfonts7=plr plri plb plbi
-ccfonts8_=0tmr.$(OBJ) 0tmri.$(OBJ) 0tmb.$(OBJ) 0tmbi.$(OBJ)
+ccfonts8_=$(PSOBJ)0tmr.$(OBJ) $(PSOBJ)0tmri.$(OBJ) $(PSOBJ)0tmb.$(OBJ) $(PSOBJ)0tmbi.$(OBJ)
ccfonts8=tmr tmri tmb tmbi
-ccfonts9_=0syr.$(OBJ) 0zcmi.$(OBJ) 0zdr.$(OBJ)
+ccfonts9_=$(PSOBJ)0syr.$(OBJ) $(PSOBJ)0zcmi.$(OBJ) $(PSOBJ)0zdr.$(OBJ)
ccfonts9=syr zcmi zdr
# The free distribution includes Bitstream Charter, Utopia, and
# freeware Cyrillic and Kana fonts. We only provide for compiling
# Charter and Utopia.
-ccfonts10free_=bchr.$(OBJ) bchri.$(OBJ) bchb.$(OBJ) bchbi.$(OBJ)
+ccfonts10free_=$(PSOBJ)bchr.$(OBJ) $(PSOBJ)bchri.$(OBJ) $(PSOBJ)bchb.$(OBJ) $(PSOBJ)bchbi.$(OBJ)
ccfonts10free=chr chri chb chbi
-ccfonts11free_=putr.$(OBJ) putri.$(OBJ) putb.$(OBJ) putbi.$(OBJ)
+ccfonts11free_=$(PSOBJ)putr.$(OBJ) $(PSOBJ)putri.$(OBJ) $(PSOBJ)putb.$(OBJ) $(PSOBJ)putbi.$(OBJ)
ccfonts11free=utr utri utb utbi
# Uncomment the alternatives in the next 4 lines if you want
# Charter and Utopia compiled in.
@@ -772,75 +835,71 @@ ccfonts14=
ccfonts15_=
ccfonts15=
-# It's OK for ccfonts_.dev not to be CONFIG-dependent, because it only
-# exists during the execution of the following rule.
# font2c has the prefix "gs" built into it, so we need to instruct
# genconf to use the same one.
-$(gconfigf_h): $(MAKEFILE) $(INT_MAK) $(ECHOGS_XE) $(GENCONF_XE)
- $(SETMOD) ccfonts_ -font $(ccfonts1)
- $(ADDMOD) ccfonts_ -font $(ccfonts2)
- $(ADDMOD) ccfonts_ -font $(ccfonts3)
- $(ADDMOD) ccfonts_ -font $(ccfonts4)
- $(ADDMOD) ccfonts_ -font $(ccfonts5)
- $(ADDMOD) ccfonts_ -font $(ccfonts6)
- $(ADDMOD) ccfonts_ -font $(ccfonts7)
- $(ADDMOD) ccfonts_ -font $(ccfonts8)
- $(ADDMOD) ccfonts_ -font $(ccfonts9)
- $(ADDMOD) ccfonts_ -font $(ccfonts10)
- $(ADDMOD) ccfonts_ -font $(ccfonts11)
- $(ADDMOD) ccfonts_ -font $(ccfonts12)
- $(ADDMOD) ccfonts_ -font $(ccfonts13)
- $(ADDMOD) ccfonts_ -font $(ccfonts14)
- $(ADDMOD) ccfonts_ -font $(ccfonts15)
- $(GENCONF_XE) ccfonts_.dev -n gs -f $(gconfigf_h)
+$(gconfigf_h) : $(TOP_MAKEFILES) $(INT_MAK) $(ECHOGS_XE) $(GENCONF_XE)
+ $(SETMOD) $(PSD)ccfonts_ -font $(ccfonts1)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts2)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts3)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts4)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts5)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts6)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts7)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts8)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts9)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts10)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts11)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts12)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts13)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts14)
+ $(ADDMOD) $(PSD)ccfonts_ -font $(ccfonts15)
+ $(GENCONF_XE) $(PSGEN)ccfonts_.dev -n gs -f $(gconfigf_h)
# We separate icfontab.dev from ccfonts.dev so that a customer can put
# compiled fonts into a separate shared library.
-icfontab=icfontab$(CONFIG)
-
# Define ccfont_table separately, so it can be set from the command line
# to select an alternate compiled font table.
-ccfont_table=$(icfontab)
+ccfont_table=icfontab
-$(icfontab).dev: $(MAKEFILE) $(INT_MAK) $(ECHOGS_XE) $(icfontab).$(OBJ)\
+$(PSD)icfontab.dev : $(TOP_MAKEFILES) $(INT_MAK) $(ECHOGS_XE)\
+ $(PSOBJ)icfontab.$(OBJ)\
$(ccfonts1_) $(ccfonts2_) $(ccfonts3_) $(ccfonts4_) $(ccfonts5_)\
$(ccfonts6_) $(ccfonts7_) $(ccfonts8_) $(ccfonts9_) $(ccfonts10_)\
$(ccfonts11_) $(ccfonts12_) $(ccfonts13_) $(ccfonts14_) $(ccfonts15_)
- $(SETMOD) $(icfontab) -obj $(icfontab).$(OBJ)
- $(ADDMOD) $(icfontab) -obj $(ccfonts1_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts2_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts3_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts4_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts5_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts6_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts7_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts8_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts9_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts10_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts11_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts12_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts13_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts14_)
- $(ADDMOD) $(icfontab) -obj $(ccfonts15_)
-
-$(PSOBJ)$(icfontab).$(OBJ): $(PSSRC)icfontab.c $(AK) $(ccfont_h) $(gconfigf_h)
- $(CP_) $(gconfigf_h) gconfigf.h
+ $(SETMOD) $(PSD)icfontab -obj $(PSOBJ)icfontab.$(OBJ)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts1_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts2_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts3_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts4_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts5_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts6_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts7_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts8_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts9_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts10_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts11_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts12_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts13_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts14_)
+ $(ADDMOD) $(PSD)icfontab -obj $(ccfonts15_)
+
+$(PSOBJ)icfontab.$(OBJ) : $(PSSRC)icfontab.c $(AK) $(ccfont_h) $(gconfigf_h)
+ $(CP_) $(gconfigf_h) $(PSGEN)gconfigf.h
$(PSCC) $(PSO_)icfontab.$(OBJ) $(C_) $(PSSRC)icfontab.c
# Strictly speaking, ccfonts shouldn't need to include type1,
# since one could choose to precompile only Type 0 fonts,
# but getting this exactly right would be too much work.
-ccfonts=ccfonts$(CONFIG)
-$(ccfonts).dev: $(MAKEFILE) $(INT_MAK) type1.dev iccfont.$(OBJ)\
- $(ccfont_table).dev
- $(SETMOD) $(ccfonts) -include type1
- $(ADDMOD) $(ccfonts) -include $(ccfont_table)
- $(ADDMOD) $(ccfonts) -obj iccfont.$(OBJ)
- $(ADDMOD) $(ccfonts) -oper ccfonts
- $(ADDMOD) $(ccfonts) -ps $(ccfonts_ps)
-
-$(PSOBJ)iccfont.$(OBJ): $(PSSRC)iccfont.c $(GH) $(string__h)\
+$(PSD)ccfonts.dev : $(TOP_MAKEFILES) $(INT_MAK)\
+ $(PSD)type1.dev $(PSOBJ)iccfont.$(OBJ) $(PSD)$(ccfont_table).dev
+ $(SETMOD) $(PSD)ccfonts -include $(PSD)type1
+ $(ADDMOD) $(PSD)ccfonts -include $(PSD)$(ccfont_table)
+ $(ADDMOD) $(PSD)ccfonts -obj $(PSOBJ)iccfont.$(OBJ)
+ $(ADDMOD) $(PSD)ccfonts -oper ccfonts
+ $(ADDMOD) $(PSD)ccfonts -ps $(ccfonts_ps)
+
+$(PSOBJ)iccfont.$(OBJ) : $(PSSRC)iccfont.c $(GH) $(string__h)\
$(gsstruct_h) $(ccfont_h) $(errors_h)\
$(ialloc_h) $(idict_h) $(ifont_h) $(iname_h) $(isave_h) $(iutil_h)\
$(oper_h) $(ostack_h) $(store_h) $(stream_h) $(strimpl_h) $(sfilter_h) $(iscan_h)
@@ -850,54 +909,71 @@ $(PSOBJ)iccfont.$(OBJ): $(PSSRC)iccfont.c $(GH) $(string__h)\
# We select either iccinit0 or iccinit1 depending on COMPILE_INITS.
-$(PSOBJ)iccinit0.$(OBJ): $(PSSRC)iccinit0.c $(stdpre_h)
+$(PSOBJ)iccinit0.$(OBJ) : $(PSSRC)iccinit0.c $(stdpre_h)
$(PSCC) $(PSO_)iccinit0.$(OBJ) $(C_) $(PSSRC)iccinit0.c
-$(PSOBJ)iccinit1.$(OBJ): $(PSOBJ)gs_init.$(OBJ)
+$(PSOBJ)iccinit1.$(OBJ) : $(PSOBJ)gs_init.$(OBJ)
$(CP_) $(PSOBJ)gs_init.$(OBJ) $(PSOBJ)iccinit1.$(OBJ)
# All the gs_*.ps files should be prerequisites of gs_init.c,
# but we don't have any convenient list of them.
-$(PSGEN)gs_init.c: $(GS_INIT) $(GENINIT_XE) $(gconfig_h)
- $(GENINIT_XE) $(GS_INIT) $(gconfig_h) -c $(PSGEN)gs_init.c
+$(PSGEN)gs_init.c : $(PSLIB)$(GS_INIT) $(GENINIT_XE) $(gconfig_h)
+ $(GENINIT_XE) -I $(PSLIB) $(GS_INIT) $(gconfig_h) -c $(PSGEN)gs_init.c
-$(PSOBJ)gs_init.$(OBJ): $(PSGEN)gs_init.c $(stdpre_h)
+$(PSOBJ)gs_init.$(OBJ) : $(PSGEN)gs_init.c $(stdpre_h)
$(PSCC) $(PSO_)gs_init.$(OBJ) $(C_) $(PSGEN)gs_init.c
+# ---------------- Compiled halftone ---------------- #
+
+compht_=$(PSOBJ)ht_ccbnm.$(OBJ)
+
+$(PSD)compht.dev : $(compht_) $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(PSD)compht $(compht_)
+ $(ADDMOD) $(PSD)compht -halftone BlueNoiseMaskBlack BlueNoiseMaskCyan
+ $(ADDMOD) $(PSD)compht -halftone BlueNoiseMaskMagenta BlueNoiseMaskYellow
+
+$(PSOBJ)ht_ccbnm.$(OBJ) : $(PSGEN)ht_ccbnm.c $(gxdhtres_h)
+ $(PSCC) $(PSO_)ht_ccbnm.$(OBJ) $(C_) $(PSGEN)ht_ccbnm.c
+
+$(PSGEN)ht_ccbnm.c : $(PSLIB)ht_ccbnm.ps $(GENHT_XE)
+ $(GENHT_XE) $(PSLIB)ht_ccbnm.ps $(PSGEN)ht_ccbnm.c
+
# ======================== PostScript Level 2 ======================== #
# We keep the old name for backward compatibility.
-level2.dev: psl2.dev
- $(CP_) psl2.dev level2.dev
-
-psl2.dev: $(INT_MAK) $(ECHOGS_XE)\
- cidfont.dev cie.dev cmapread.dev compfont.dev dct.dev dpsand2.dev\
- filter.dev iodevice.dev pagedev.dev pattern.dev\
- psl1.dev psl2lib.dev psl2read.dev\
- sepr.dev type32.dev type42.dev xfilter.dev
- $(SETMOD) psl2 -include cidfont cie cmapread compfont
- $(ADDMOD) psl2 -include dct dpsand2 filter iodevice
- $(ADDMOD) psl2 -include pagedev pattern psl1 psl2lib psl2read
- $(ADDMOD) psl2 -include sepr type32 type42 xfilter
- $(ADDMOD) psl2 -emulator PostScript PostScriptLevel2
+$(PSD)level2.dev : $(PSD)psl2.dev
+ $(CP_) $(PSD)psl2.dev $(PSD)level2.dev
+
+$(PSD)psl2.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)cidfont.dev $(PSD)cie.dev $(PSD)cmapread.dev $(PSD)compfont.dev\
+ $(PSD)dct.dev $(PSD)dpsand2.dev\
+ $(PSD)filter.dev $(PSD)iodevice.dev $(PSD)pagedev.dev $(PSD)pattern.dev\
+ $(PSD)psl1.dev $(GLD)psl2lib.dev $(PSD)psl2read.dev\
+ $(PSD)sepr.dev $(PSD)type32.dev $(PSD)type42.dev
+ $(SETMOD) $(PSD)psl2 -include $(PSD)cidfont $(PSD)cie $(PSD)cmapread $(PSD)compfont
+ $(ADDMOD) $(PSD)psl2 -include $(PSD)dct $(PSD)dpsand2 $(PSD)filter $(PSD)iodevice
+ $(ADDMOD) $(PSD)psl2 -include $(PSD)pagedev $(PSD)pattern $(PSD)psl1 $(GLD)psl2lib $(PSD)psl2read
+ $(ADDMOD) $(PSD)psl2 -include $(PSD)sepr $(PSD)type32 $(PSD)type42
+ $(ADDMOD) $(PSD)psl2 -emulator PostScript PostScriptLevel2
# Define basic Level 2 language support.
# This is the minimum required for CMap and CIDFont support.
psl2int_=$(PSOBJ)iutil2.$(OBJ) $(PSOBJ)zmisc2.$(OBJ)
-psl2int.dev: $(INT_MAK) $(ECHOGS_XE) $(psl2int_) dps2int.dev usparam.dev
- $(SETMOD) psl2int $(psl2int_)
- $(ADDMOD) psl2int -include dps2int usparam
- $(ADDMOD) psl2int -oper zmisc2
- $(ADDMOD) psl2int -ps gs_lev2 gs_res
-
-$(PSOBJ)iutil2.$(OBJ): $(PSSRC)iutil2.c $(GH) $(memory__h) $(string__h)\
+$(PSD)psl2int.dev : $(INT_MAK) $(ECHOGS_XE) $(psl2int_)\
+ $(PSD)dps2int.dev $(PSD)usparam.dev
+ $(SETMOD) $(PSD)psl2int $(psl2int_)
+ $(ADDMOD) $(PSD)psl2int -include $(PSD)dps2int $(PSD)usparam
+ $(ADDMOD) $(PSD)psl2int -oper zmisc2
+ $(ADDMOD) $(PSD)psl2int -ps gs_lev2 gs_res
+
+$(PSOBJ)iutil2.$(OBJ) : $(PSSRC)iutil2.c $(GH) $(memory__h) $(string__h)\
$(gsparam_h) $(gsutil_h)\
$(errors_h) $(idict_h) $(imemory_h) $(iutil_h) $(iutil2_h) $(opcheck_h)
$(PSCC) $(PSO_)iutil2.$(OBJ) $(C_) $(PSSRC)iutil2.c
-$(PSOBJ)zmisc2.$(OBJ): $(PSSRC)zmisc2.c $(OP) $(memory__h) $(string__h)\
- $(idict_h) $(idparam_h) $(iparam_h) $(dstack_h) $(estack_h)\
+$(PSOBJ)zmisc2.$(OBJ) : $(PSSRC)zmisc2.c $(OP) $(memory__h) $(string__h)\
+ $(iddict_h) $(idparam_h) $(iparam_h) $(dstack_h) $(estack_h)\
$(ilevel_h) $(iname_h) $(iutil2_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)zmisc2.$(OBJ) $(C_) $(PSSRC)zmisc2.c
@@ -905,20 +981,20 @@ $(PSOBJ)zmisc2.$(OBJ): $(PSSRC)zmisc2.c $(OP) $(memory__h) $(string__h)\
# We make this a separate module only because it must have a default.
nousparm_=$(PSOBJ)inouparm.$(OBJ)
-nousparm.dev: $(INT_MAK) $(ECHOGS_XE) $(nousparm_)
- $(SETMOD) nousparm $(nousparm_)
+$(PSD)nousparm.dev : $(INT_MAK) $(ECHOGS_XE) $(nousparm_)
+ $(SETMOD) $(PSD)nousparm $(nousparm_)
-$(PSOBJ)inouparm.$(OBJ): $(PSSRC)inouparm.c\
+$(PSOBJ)inouparm.$(OBJ) : $(PSSRC)inouparm.c\
$(ghost_h) $(icontext_h)
$(PSCC) $(PSO_)inouparm.$(OBJ) $(C_) $(PSSRC)inouparm.c
usparam_=$(PSOBJ)zusparam.$(OBJ)
-usparam.dev: $(INT_MAK) $(ECHOGS_XE) $(usparam_)
- $(SETMOD) usparam $(usparam_)
- $(ADDMOD) usparam -oper zusparam -replace nousparm
+$(PSD)usparam.dev : $(INT_MAK) $(ECHOGS_XE) $(usparam_)
+ $(SETMOD) $(PSD)usparam $(usparam_)
+ $(ADDMOD) $(PSD)usparam -oper zusparam -replace $(PSD)nousparm
# Note that zusparam includes both Level 1 and Level 2 operators.
-$(PSOBJ)zusparam.$(OBJ): $(PSSRC)zusparam.c $(OP) $(memory__h) $(string__h)\
+$(PSOBJ)zusparam.$(OBJ) : $(PSSRC)zusparam.c $(OP) $(memory__h) $(string__h)\
$(gscdefs_h) $(gsfont_h) $(gsstruct_h) $(gsutil_h) $(gxht_h)\
$(ialloc_h) $(icontext_h) $(idict_h) $(idparam_h) $(iparam_h)\
$(iname_h) $(iutil2_h)\
@@ -931,32 +1007,33 @@ iimage2_h=$(PSSRC)iimage2.h
psl2read_=$(PSOBJ)zcolor2.$(OBJ) $(PSOBJ)zcsindex.$(OBJ) $(PSOBJ)zht2.$(OBJ) $(PSOBJ)zimage2.$(OBJ)
# Note that zmisc2 includes both Level 1 and Level 2 operators.
-psl2read.dev: $(INT_MAK) $(ECHOGS_XE) $(psl2read_) psl2int.dev dps2read.dev
- $(SETMOD) psl2read $(psl2read_)
- $(ADDMOD) psl2read -include psl2int dps2read
- $(ADDMOD) psl2read -oper zcolor2_l2 zcsindex_l2
- $(ADDMOD) psl2read -oper zht2_l2 zimage2_l2
-
-$(PSOBJ)zcolor2.$(OBJ): $(PSSRC)zcolor2.c $(OP)\
- $(gscolor_h) $(gsmatrix_h) $(gsstruct_h)\
+$(PSD)psl2read.dev : $(INT_MAK) $(ECHOGS_XE) $(psl2read_)\
+ $(PSD)psl2int.dev $(PSD)dps2read.dev
+ $(SETMOD) $(PSD)psl2read $(psl2read_)
+ $(ADDMOD) $(PSD)psl2read -include $(PSD)psl2int $(PSD)dps2read
+ $(ADDMOD) $(PSD)psl2read -oper zcolor2_l2 zcsindex_l2
+ $(ADDMOD) $(PSD)psl2read -oper zht2_l2 zimage2_l2
+
+$(PSOBJ)zcolor2.$(OBJ) : $(PSSRC)zcolor2.c $(OP)\
+ $(gscolor_h) $(gscssub_h) $(gsmatrix_h) $(gsstruct_h)\
$(gxcolor2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxfixed_h) $(gxpcolor_h)\
$(estack_h) $(ialloc_h) $(idict_h) $(idparam_h) $(igstate_h) $(istruct_h)\
$(store_h)
$(PSCC) $(PSO_)zcolor2.$(OBJ) $(C_) $(PSSRC)zcolor2.c
-$(PSOBJ)zcsindex.$(OBJ): $(PSSRC)zcsindex.c $(OP) $(memory__h)\
+$(PSOBJ)zcsindex.$(OBJ) : $(PSSRC)zcsindex.c $(OP) $(memory__h)\
$(gscolor_h) $(gsstruct_h) $(gxfixed_h) $(gxcolor2_h) $(gxcspace_h) $(gsmatrix_h)\
$(ialloc_h) $(icsmap_h) $(estack_h) $(igstate_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)zcsindex.$(OBJ) $(C_) $(PSSRC)zcsindex.c
-$(PSOBJ)zht2.$(OBJ): $(PSSRC)zht2.c $(OP)\
+$(PSOBJ)zht2.$(OBJ) : $(PSSRC)zht2.c $(OP)\
$(gsstruct_h) $(gxdevice_h) $(gzht_h)\
- $(estack_h) $(ialloc_h) $(icolor_h) $(idict_h) $(idparam_h) $(igstate_h)\
+ $(estack_h) $(ialloc_h) $(icolor_h) $(iddict_h) $(idparam_h) $(igstate_h)\
$(iht_h) $(store_h)
$(PSCC) $(PSO_)zht2.$(OBJ) $(C_) $(PSSRC)zht2.c
-$(PSOBJ)zimage2.$(OBJ): $(PSSRC)zimage2.c $(OP) $(math__h) $(memory__h)\
- $(gscolor_h) $(gscolor2_h) $(gscspace_h) $(gsimage_h) $(gsmatrix_h)\
+$(PSOBJ)zimage2.$(OBJ) : $(PSSRC)zimage2.c $(OP) $(math__h) $(memory__h)\
+ $(gschar_h) $(gscolor_h) $(gscolor2_h) $(gscspace_h) $(gsimage_h) $(gsmatrix_h)\
$(gxfixed_h)\
$(idict_h) $(idparam_h) $(iimage_h) $(iimage2_h) $(ilevel_h) $(igstate_h)
$(PSCC) $(PSO_)zimage2.$(OBJ) $(C_) $(PSSRC)zimage2.c
@@ -964,34 +1041,34 @@ $(PSOBJ)zimage2.$(OBJ): $(PSSRC)zimage2.c $(OP) $(math__h) $(memory__h)\
# ---------------- setpagedevice ---------------- #
pagedev_=$(PSOBJ)zdevice2.$(OBJ) $(PSOBJ)zmedia2.$(OBJ)
-pagedev.dev: $(INT_MAK) $(ECHOGS_XE) $(pagedev_) $(PSSRC)gs_setpd.ps
- $(SETMOD) pagedev $(pagedev_)
- $(ADDMOD) pagedev -oper zdevice2_l2 zmedia2_l2
- $(ADDMOD) pagedev -ps gs_setpd
+$(PSD)pagedev.dev : $(INT_MAK) $(ECHOGS_XE) $(pagedev_)
+ $(SETMOD) $(PSD)pagedev $(pagedev_)
+ $(ADDMOD) $(PSD)pagedev -oper zdevice2_l2 zmedia2_l2
+ $(ADDMOD) $(PSD)pagedev -ps gs_setpd
-$(PSOBJ)zdevice2.$(OBJ): $(PSSRC)zdevice2.c $(OP) $(math__h) $(memory__h)\
+$(PSOBJ)zdevice2.$(OBJ) : $(PSSRC)zdevice2.c $(OP) $(math__h) $(memory__h)\
$(dstack_h) $(estack_h) $(idict_h) $(idparam_h) $(igstate_h) $(iname_h) $(store_h)\
$(gxdevice_h) $(gsstate_h)
$(PSCC) $(PSO_)zdevice2.$(OBJ) $(C_) $(PSSRC)zdevice2.c
-$(PSOBJ)zmedia2.$(OBJ): $(PSSRC)zmedia2.c $(OP) $(math__h) $(memory__h)\
+$(PSOBJ)zmedia2.$(OBJ) : $(PSSRC)zmedia2.c $(OP) $(math__h) $(memory__h)\
$(gsmatrix_h) $(idict_h) $(idparam_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zmedia2.$(OBJ) $(C_) $(PSSRC)zmedia2.c
# ---------------- IODevices ---------------- #
iodevice_=$(PSOBJ)ziodev2.$(OBJ) $(PSOBJ)zdevcal.$(OBJ)
-iodevice.dev: $(INT_MAK) $(ECHOGS_XE) $(iodevice_)
- $(SETMOD) iodevice $(iodevice_)
- $(ADDMOD) iodevice -oper ziodev2_l2
- $(ADDMOD) iodevice -iodev null ram calendar
+$(PSD)iodevice.dev : $(INT_MAK) $(ECHOGS_XE) $(iodevice_)
+ $(SETMOD) $(PSD)iodevice $(iodevice_)
+ $(ADDMOD) $(PSD)iodevice -oper ziodev2_l2
+ $(ADDMOD) $(PSD)iodevice -iodev null ram calendar
-$(PSOBJ)ziodev2.$(OBJ): $(PSSRC)ziodev2.c $(OP) $(string__h) $(gp_h)\
+$(PSOBJ)ziodev2.$(OBJ) : $(PSSRC)ziodev2.c $(OP) $(string__h) $(gp_h)\
$(gxiodev_h) $(stream_h)\
$(dstack_h) $(files_h) $(iparam_h) $(iutil2_h) $(store_h)
$(PSCC) $(PSO_)ziodev2.$(OBJ) $(C_) $(PSSRC)ziodev2.c
-$(PSOBJ)zdevcal.$(OBJ): $(PSSRC)zdevcal.c $(GH) $(time__h)\
+$(PSOBJ)zdevcal.$(OBJ) : $(PSSRC)zdevcal.c $(GH) $(time__h)\
$(gxiodev_h) $(iparam_h) $(istack_h)
$(PSCC) $(PSO_)zdevcal.$(OBJ) $(C_) $(PSSRC)zdevcal.c
@@ -999,12 +1076,13 @@ $(PSOBJ)zdevcal.$(OBJ): $(PSSRC)zdevcal.c $(GH) $(time__h)\
# Standard Level 2 decoding filters only. The PDF configuration uses this.
fdecode_=$(GLOBJ)scantab.$(OBJ) $(GLOBJ)scfparam.$(OBJ) $(GLOBJ)sfilter2.$(OBJ) $(PSOBJ)zfdecode.$(OBJ)
-fdecode.dev: $(INT_MAK) $(ECHOGS_XE) $(fdecode_) cfd.dev lzwd.dev pdiff.dev pngp.dev rld.dev
- $(SETMOD) fdecode $(fdecode_)
- $(ADDMOD) fdecode -include cfd lzwd pdiff pngp rld
- $(ADDMOD) fdecode -oper zfdecode
+$(PSD)fdecode.dev : $(INT_MAK) $(ECHOGS_XE) $(fdecode_)\
+ $(GLD)cfd.dev $(GLD)lzwd.dev $(GLD)pdiff.dev $(GLD)pngp.dev $(GLD)rld.dev
+ $(SETMOD) $(PSD)fdecode $(fdecode_)
+ $(ADDMOD) $(PSD)fdecode -include $(GLD)cfd $(GLD)lzwd $(GLD)pdiff $(GLD)pngp $(GLD)rld
+ $(ADDMOD) $(PSD)fdecode -oper zfdecode
-$(PSOBJ)zfdecode.$(OBJ): $(PSSRC)zfdecode.c $(OP) $(memory__h)\
+$(PSOBJ)zfdecode.$(OBJ) : $(PSSRC)zfdecode.c $(OP) $(memory__h)\
$(gsparam_h) $(gsstruct_h)\
$(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h) $(ilevel_h) $(iparam_h)\
$(sa85x_h) $(scf_h) $(scfx_h) $(sfilter_h) $(slzwx_h) $(spdiffx_h) $(spngpx_h)\
@@ -1013,13 +1091,14 @@ $(PSOBJ)zfdecode.$(OBJ): $(PSSRC)zfdecode.c $(OP) $(memory__h)\
# Complete Level 2 filter capability.
filter_=$(PSOBJ)zfilter2.$(OBJ)
-filter.dev: $(INT_MAK) $(ECHOGS_XE) fdecode.dev $(filter_) cfe.dev lzwe.dev rle.dev
- $(SETMOD) filter -include fdecode
- $(ADDMOD) filter -obj $(filter_)
- $(ADDMOD) filter -include cfe lzwe rle
- $(ADDMOD) filter -oper zfilter2
-
-$(PSOBJ)zfilter2.$(OBJ): $(PSSRC)zfilter2.c $(OP) $(memory__h)\
+$(PSD)filter.dev : $(INT_MAK) $(ECHOGS_XE) $(PSD)fdecode.dev $(filter_)\
+ $(GLD)cfe.dev $(GLD)lzwe.dev $(GLD)rle.dev
+ $(SETMOD) $(PSD)filter -include $(PSD)fdecode
+ $(ADDMOD) $(PSD)filter -obj $(filter_)
+ $(ADDMOD) $(PSD)filter -include $(GLD)cfe $(GLD)lzwe $(GLD)rle
+ $(ADDMOD) $(PSD)filter -oper zfilter2
+
+$(PSOBJ)zfilter2.$(OBJ) : $(PSSRC)zfilter2.c $(OP) $(memory__h)\
$(gsstruct_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h) $(store_h)\
$(sfilter_h) $(scfx_h) $(slzwx_h) $(spdiffx_h) $(spngpx_h) $(strimpl_h)
$(PSCC) $(PSO_)zfilter2.$(OBJ) $(C_) $(PSSRC)zfilter2.c
@@ -1027,64 +1106,70 @@ $(PSOBJ)zfilter2.$(OBJ): $(PSSRC)zfilter2.c $(OP) $(memory__h)\
# Extensions beyond Level 2 standard.
xfilter_=$(PSOBJ)sbhc.$(OBJ) $(PSOBJ)sbwbs.$(OBJ) $(PSOBJ)shcgen.$(OBJ)\
$(PSOBJ)smtf.$(OBJ) $(PSOBJ)zfilterx.$(OBJ)
-xfilter.dev: $(INT_MAK) $(ECHOGS_XE) $(xfilter_) pcxd.dev pngp.dev
- $(SETMOD) xfilter $(xfilter_)
- $(ADDMOD) xfilter -include pcxd
- $(ADDMOD) xfilter -oper zfilterx
+$(PSD)xfilter.dev : $(INT_MAK) $(ECHOGS_XE) $(xfilter_) $(GLD)pngp.dev
+ $(SETMOD) $(PSD)xfilter $(xfilter_)
+ $(ADDMOD) $(PSD)xfilter -include $(GLD)pngp
+ $(ADDMOD) $(PSD)xfilter -oper zfilterx
-$(PSOBJ)sbhc.$(OBJ): $(PSSRC)sbhc.c $(AK) $(memory__h) $(stdio__h)\
+$(PSOBJ)sbhc.$(OBJ) : $(PSSRC)sbhc.c $(AK) $(memory__h) $(stdio__h)\
$(gdebug_h) $(sbhc_h) $(shcgen_h) $(strimpl_h)
$(PSCC) $(PSO_)sbhc.$(OBJ) $(C_) $(PSSRC)sbhc.c
-$(PSOBJ)sbwbs.$(OBJ): $(PSSRC)sbwbs.c $(AK) $(stdio__h) $(memory__h)\
+$(PSOBJ)sbwbs.$(OBJ) : $(PSSRC)sbwbs.c $(AK) $(stdio__h) $(memory__h)\
$(gdebug_h) $(sbwbs_h) $(sfilter_h) $(strimpl_h)
$(PSCC) $(PSO_)sbwbs.$(OBJ) $(C_) $(PSSRC)sbwbs.c
-$(PSOBJ)shcgen.$(OBJ): $(PSSRC)shcgen.c $(AK) $(memory__h) $(stdio__h)\
+$(PSOBJ)shcgen.$(OBJ) : $(PSSRC)shcgen.c $(AK) $(memory__h) $(stdio__h)\
$(gdebug_h) $(gserror_h) $(gserrors_h) $(gsmemory_h)\
$(scommon_h) $(shc_h) $(shcgen_h)
$(PSCC) $(PSO_)shcgen.$(OBJ) $(C_) $(PSSRC)shcgen.c
-$(PSOBJ)smtf.$(OBJ): $(PSSRC)smtf.c $(AK) $(stdio__h)\
+$(PSOBJ)smtf.$(OBJ) : $(PSSRC)smtf.c $(AK) $(stdio__h)\
$(smtf_h) $(strimpl_h)
$(PSCC) $(PSO_)smtf.$(OBJ) $(C_) $(PSSRC)smtf.c
-$(PSOBJ)zfilterx.$(OBJ): $(PSSRC)zfilterx.c $(OP) $(memory__h)\
+$(PSOBJ)zfilterx.$(OBJ) : $(PSSRC)zfilterx.c $(OP) $(memory__h)\
$(gsstruct_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h)\
$(store_h) $(sfilter_h) $(sbhc_h) $(sbtx_h) $(sbwbs_h) $(shcgen_h)\
- $(smtf_h) $(spcxx_h) $(strimpl_h)
+ $(smtf_h) $(strimpl_h)
$(PSCC) $(PSO_)zfilterx.$(OBJ) $(C_) $(PSSRC)zfilterx.c
# ---------------- Binary tokens ---------------- #
-btoken_=$(PSOBJ)iscanbin.$(OBJ) $(PSOBJ)zbseq.$(OBJ)
-btoken.dev: $(INT_MAK) $(ECHOGS_XE) $(btoken_)
- $(SETMOD) btoken $(btoken_)
- $(ADDMOD) btoken -oper zbseq_l2
- $(ADDMOD) btoken -ps gs_btokn
+nobtoken_=$(PSOBJ)inobtokn.$(OBJ)
+$(PSD)nobtoken.dev : $(INT_MAK) $(ECHOGS_XE) $(nobtoken_)
+ $(SETMOD) $(PSD)nobtoken $(nobtoken_)
-btoken_h=$(PSSRC)btoken.h
+$(PSOBJ)inobtokn.$(OBJ) : $(PSSRC)inobtokn.c $(GH)\
+ $(stream_h) $(errors_h) $(iscan_h)
+ $(PSCC) $(PSO_)inobtokn.$(OBJ) $(C_) $(PSSRC)inobtokn.c
-$(PSOBJ)iscanbin.$(OBJ): $(PSSRC)iscanbin.c $(GH)\
+btoken_=$(PSOBJ)iscanbin.$(OBJ) $(PSOBJ)zbseq.$(OBJ)
+$(PSD)btoken.dev : $(INT_MAK) $(ECHOGS_XE) $(btoken_)
+ $(SETMOD) $(PSD)btoken $(btoken_)
+ $(ADDMOD) $(PSD)btoken -oper zbseq_l2 -replace $(PSD)nobtoken
+ $(ADDMOD) $(PSD)btoken -ps gs_btokn
+
+$(PSOBJ)iscanbin.$(OBJ) : $(PSSRC)iscanbin.c $(GH)\
$(math__h) $(memory__h) $(errors_h)\
- $(gsutil_h) $(ialloc_h) $(ibnum_h) $(idict_h) $(iname_h)\
+ $(gsutil_h) $(ialloc_h) $(ibnum_h) $(iddict_h) $(iname_h)\
$(iscan_h) $(iutil_h) $(ivmspace_h)\
$(btoken_h) $(dstack_h) $(ostack_h)\
$(sfilter_h) $(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)iscanbin.$(OBJ) $(C_) $(PSSRC)iscanbin.c
-$(PSOBJ)zbseq.$(OBJ): $(PSSRC)zbseq.c $(OP) $(memory__h)\
+$(PSOBJ)zbseq.$(OBJ) : $(PSSRC)zbseq.c $(OP) $(memory__h)\
$(btoken_h) $(ialloc_h) $(store_h)
$(PSCC) $(PSO_)zbseq.$(OBJ) $(C_) $(PSSRC)zbseq.c
# ---------------- User paths & insideness testing ---------------- #
upath_=$(PSOBJ)zupath.$(OBJ) $(PSOBJ)ibnum.$(OBJ) $(GLOBJ)gdevhit.$(OBJ)
-upath.dev: $(INT_MAK) $(ECHOGS_XE) $(upath_)
- $(SETMOD) upath $(upath_)
- $(ADDMOD) upath -oper zupath_l2
+$(PSD)upath.dev : $(INT_MAK) $(ECHOGS_XE) $(upath_)
+ $(SETMOD) $(PSD)upath $(upath_)
+ $(ADDMOD) $(PSD)upath -oper zupath_l2
-$(PSOBJ)zupath.$(OBJ): $(PSSRC)zupath.c $(OP)\
+$(PSOBJ)zupath.$(OBJ) : $(PSSRC)zupath.c $(OP)\
$(dstack_h) $(store_h)\
$(ibnum_h) $(idict_h) $(igstate_h) $(iname_h) $(iutil_h) $(stream_h)\
$(gscoord_h) $(gsmatrix_h) $(gspaint_h) $(gspath_h) $(gsstate_h)\
@@ -1093,72 +1178,74 @@ $(PSOBJ)zupath.$(OBJ): $(PSSRC)zupath.c $(OP)\
# -------- Additions common to Display PostScript and Level 2 -------- #
-dpsand2.dev: $(INT_MAK) $(ECHOGS_XE) btoken.dev color.dev upath.dev dps2lib.dev dps2read.dev
- $(SETMOD) dpsand2 -include btoken color upath dps2lib dps2read
+$(PSD)dpsand2.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)btoken.dev $(PSD)color.dev $(PSD)upath.dev $(GLD)dps2lib.dev $(PSD)dps2read.dev
+ $(SETMOD) $(PSD)dpsand2 -include $(PSD)btoken $(PSD)color $(PSD)upath $(GLD)dps2lib $(PSD)dps2read
dps2int_=$(PSOBJ)zvmem2.$(OBJ) $(PSOBJ)zdps1.$(OBJ)
# Note that zvmem2 includes both Level 1 and Level 2 operators.
-dps2int.dev: $(INT_MAK) $(ECHOGS_XE) $(dps2int_)
- $(SETMOD) dps2int $(dps2int_)
- $(ADDMOD) dps2int -oper zvmem2 zdps1_l2
- $(ADDMOD) dps2int -ps gs_dps1
-
-dps2read_=$(PSOBJ)ibnum.$(OBJ) $(PSOBJ)zchar2.$(OBJ)
-dps2read.dev: $(INT_MAK) $(ECHOGS_XE) $(dps2read_) dps2int.dev
- $(SETMOD) dps2read $(dps2read_)
- $(ADDMOD) dps2read -include dps2int
- $(ADDMOD) dps2read -oper ireclaim_l2 zchar2
- $(ADDMOD) dps2read -ps gs_dps2
-
-$(PSOBJ)ibnum.$(OBJ): $(PSSRC)ibnum.c $(GH) $(math__h) $(memory__h)\
+$(PSD)dps2int.dev : $(INT_MAK) $(ECHOGS_XE) $(dps2int_)
+ $(SETMOD) $(PSD)dps2int $(dps2int_)
+ $(ADDMOD) $(PSD)dps2int -oper zvmem2 zdps1_l2
+ $(ADDMOD) $(PSD)dps2int -ps gs_dps1
+
+dps2read_=$(PSOBJ)ibnum.$(OBJ) $(PSOBJ)zcharx.$(OBJ)
+$(PSD)dps2read.dev : $(INT_MAK) $(ECHOGS_XE) $(dps2read_) $(PSD)dps2int.dev
+ $(SETMOD) $(PSD)dps2read $(dps2read_)
+ $(ADDMOD) $(PSD)dps2read -include $(PSD)dps2int
+ $(ADDMOD) $(PSD)dps2read -oper ireclaim_l2 zcharx
+ $(ADDMOD) $(PSD)dps2read -ps gs_dps2
+
+$(PSOBJ)ibnum.$(OBJ) : $(PSSRC)ibnum.c $(GH) $(math__h) $(memory__h)\
$(errors_h) $(stream_h) $(ibnum_h) $(imemory_h) $(iutil_h)
$(PSCC) $(PSO_)ibnum.$(OBJ) $(C_) $(PSSRC)ibnum.c
-$(PSOBJ)zchar2.$(OBJ): $(PSSRC)zchar2.c $(OP)\
+$(PSOBJ)zcharx.$(OBJ) : $(PSSRC)zcharx.c $(OP)\
$(gschar_h) $(gsmatrix_h) $(gspath_h) $(gsstruct_h)\
$(gxchar_h) $(gxfixed_h) $(gxfont_h)\
$(ialloc_h) $(ichar_h) $(estack_h) $(ifont_h) $(iname_h) $(igstate_h)\
$(store_h) $(stream_h) $(ibnum_h)
- $(PSCC) $(PSO_)zchar2.$(OBJ) $(C_) $(PSSRC)zchar2.c
+ $(PSCC) $(PSO_)zcharx.$(OBJ) $(C_) $(PSSRC)zcharx.c
-$(PSOBJ)zdps1.$(OBJ): $(PSSRC)zdps1.c $(OP)\
+$(PSOBJ)zdps1.$(OBJ) : $(PSSRC)zdps1.c $(OP)\
$(gsmatrix_h) $(gspath_h) $(gspath2_h) $(gsstate_h)\
$(ialloc_h) $(ivmspace_h) $(igstate_h) $(store_h) $(stream_h) $(ibnum_h)
$(PSCC) $(PSO_)zdps1.$(OBJ) $(C_) $(PSSRC)zdps1.c
-$(PSOBJ)zvmem2.$(OBJ): $(PSSRC)zvmem2.c $(OP)\
+$(PSOBJ)zvmem2.$(OBJ) : $(PSSRC)zvmem2.c $(OP)\
$(estack_h) $(ialloc_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)zvmem2.$(OBJ) $(C_) $(PSSRC)zvmem2.c
# -------- Composite (PostScript Type 0) font support -------- #
-compfont.dev: $(INT_MAK) $(ECHOGS_XE) psf0lib.dev psf0read.dev
- $(SETMOD) compfont -include psf0lib psf0read
+$(PSD)compfont.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(GLD)psf0lib.dev $(PSD)psf0read.dev
+ $(SETMOD) $(PSD)compfont -include $(GLD)psf0lib $(PSD)psf0read
# We always include zfcmap.$(OBJ) because zfont0.c refers to it,
# and it's not worth the trouble to exclude.
psf0read_=$(PSOBJ)zcfont.$(OBJ) $(PSOBJ)zfcmap.$(OBJ) $(PSOBJ)zfont0.$(OBJ)
-psf0read.dev: $(INT_MAK) $(ECHOGS_XE) $(psf0read_)
- $(SETMOD) psf0read $(psf0read_)
- $(ADDMOD) psf0read -oper zcfont zfcmap zfont0
+$(PSD)psf0read.dev : $(INT_MAK) $(ECHOGS_XE) $(psf0read_)
+ $(SETMOD) $(PSD)psf0read $(psf0read_)
+ $(ADDMOD) $(PSD)psf0read -oper zcfont zfcmap zfont0
-$(PSOBJ)zcfont.$(OBJ): $(PSSRC)zcfont.c $(OP)\
+$(PSOBJ)zcfont.$(OBJ) : $(PSSRC)zcfont.c $(OP)\
$(gschar_h) $(gsmatrix_h)\
$(gxchar_h) $(gxfixed_h) $(gxfont_h)\
$(ichar_h) $(estack_h) $(ifont_h) $(igstate_h) $(store_h)
$(PSCC) $(PSO_)zcfont.$(OBJ) $(C_) $(PSSRC)zcfont.c
-$(PSOBJ)zfcmap.$(OBJ): $(PSSRC)zfcmap.c $(OP)\
+$(PSOBJ)zfcmap.$(OBJ) : $(PSSRC)zfcmap.c $(OP)\
$(gsmatrix_h) $(gsstruct_h) $(gsutil_h)\
$(gxfcmap_h) $(gxfont_h)\
- $(ialloc_h) $(idict_h) $(idparam_h) $(ifont_h) $(iname_h) $(store_h)
+ $(ialloc_h) $(iddict_h) $(idparam_h) $(ifont_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zfcmap.$(OBJ) $(C_) $(PSSRC)zfcmap.c
-$(PSOBJ)zfont0.$(OBJ): $(PSSRC)zfont0.c $(OP)\
+$(PSOBJ)zfont0.$(OBJ) : $(PSSRC)zfont0.c $(OP)\
$(gschar_h) $(gsstruct_h)\
$(gxdevice_h) $(gxfcmap_h) $(gxfixed_h) $(gxfont_h) $(gxfont0_h) $(gxmatrix_h)\
$(gzstate_h)\
- $(bfont_h) $(ialloc_h) $(idict_h) $(idparam_h) $(igstate_h) $(iname_h)\
+ $(bfont_h) $(ialloc_h) $(iddict_h) $(idparam_h) $(igstate_h) $(iname_h)\
$(store_h)
$(PSCC) $(PSO_)zfont0.$(OBJ) $(C_) $(PSSRC)zfont0.c
@@ -1167,25 +1254,26 @@ $(PSOBJ)zfont0.$(OBJ): $(PSSRC)zfont0.c $(OP)\
# because it requires findresource.
cmapread_=$(PSOBJ)zfcmap.$(OBJ)
-cmapread.dev: $(INT_MAK) $(ECHOGS_XE) $(cmapread_) cmaplib.dev psl2int.dev
- $(SETMOD) cmapread $(cmapread_)
- $(ADDMOD) cmapread -include cmaplib psl2int
- $(ADDMOD) cmapread -oper zfcmap
- $(ADDMOD) cmapread -ps gs_cmap
+$(PSD)cmapread.dev : $(INT_MAK) $(ECHOGS_XE) $(cmapread_)\
+ $(GLD)cmaplib.dev $(PSD)psl2int.dev
+ $(SETMOD) $(PSD)cmapread $(cmapread_)
+ $(ADDMOD) $(PSD)cmapread -include $(GLD)cmaplib $(PSD)psl2int
+ $(ADDMOD) $(PSD)cmapread -oper zfcmap
+ $(ADDMOD) $(PSD)cmapread -ps gs_cmap
# ---------------- CIDFont support ---------------- #
# Note that this requires at least minimal Level 2 support,
# because it requires findresource.
cidread_=$(PSOBJ)zcid.$(OBJ)
-cidfont.dev: $(INT_MAK) $(ECHOGS_XE) psf1read.dev psl2int.dev type42.dev\
- $(cidread_)
- $(SETMOD) cidfont $(cidread_)
- $(ADDMOD) cidfont -include psf1read psl2int type42
- $(ADDMOD) cidfont -ps gs_cidfn
- $(ADDMOD) cidfont -oper zcid
-
-$(PSOBJ)zcid.$(OBJ): $(PSSRC)zcid.c $(OP)\
+$(PSD)cidfont.dev : $(INT_MAK) $(ECHOGS_XE) $(cidread_)\
+ $(PSD)psf1read.dev $(PSD)psl2int.dev $(PSD)type42.dev
+ $(SETMOD) $(PSD)cidfont $(cidread_)
+ $(ADDMOD) $(PSD)cidfont -include $(PSD)psf1read $(PSD)psl2int $(PSD)type42
+ $(ADDMOD) $(PSD)cidfont -ps gs_cidfn
+ $(ADDMOD) $(PSD)cidfont -oper zcid
+
+$(PSOBJ)zcid.$(OBJ) : $(PSSRC)zcid.c $(OP)\
$(gsccode_h) $(gsmatrix_h) $(gxfont_h)\
$(bfont_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zcid.$(OBJ) $(C_) $(PSSRC)zcid.c
@@ -1193,20 +1281,20 @@ $(PSOBJ)zcid.$(OBJ): $(PSSRC)zcid.c $(OP)\
# ---------------- CIE color ---------------- #
cieread_=$(PSOBJ)zcie.$(OBJ) $(PSOBJ)zcrd.$(OBJ)
-cie.dev: $(INT_MAK) $(ECHOGS_XE) $(cieread_) cielib.dev
- $(SETMOD) cie $(cieread_)
- $(ADDMOD) cie -oper zcie_l2 zcrd_l2
- $(ADDMOD) cie -include cielib
+$(PSD)cie.dev : $(INT_MAK) $(ECHOGS_XE) $(cieread_) $(GLD)cielib.dev
+ $(SETMOD) $(PSD)cie $(cieread_)
+ $(ADDMOD) $(PSD)cie -oper zcie_l2 zcrd_l2
+ $(ADDMOD) $(PSD)cie -include $(GLD)cielib
icie_h=$(PSSRC)icie.h
-$(PSOBJ)zcie.$(OBJ): $(PSSRC)zcie.c $(OP) $(math__h) $(memory__h)\
+$(PSOBJ)zcie.$(OBJ) : $(PSSRC)zcie.c $(OP) $(math__h) $(memory__h)\
$(gscolor2_h) $(gscie_h) $(gsstruct_h) $(gxcspace_h)\
$(ialloc_h) $(icie_h) $(idict_h) $(idparam_h) $(estack_h)\
$(isave_h) $(igstate_h) $(ivmspace_h) $(store_h)
$(PSCC) $(PSO_)zcie.$(OBJ) $(C_) $(PSSRC)zcie.c
-$(PSOBJ)zcrd.$(OBJ): $(PSSRC)zcrd.c $(OP) $(math__h)\
+$(PSOBJ)zcrd.$(OBJ) : $(PSSRC)zcrd.c $(OP) $(math__h)\
$(gscrd_h) $(gscrdp_h) $(gscspace_h) $(gscolor2_h) $(gsstruct_h)\
$(estack_h) $(ialloc_h) $(icie_h) $(idict_h) $(idparam_h) $(igstate_h)\
$(iparam_h) $(ivmspace_h) $(store_h)
@@ -1214,31 +1302,35 @@ $(PSOBJ)zcrd.$(OBJ): $(PSSRC)zcrd.c $(OP) $(math__h)\
# ---------------- Pattern color ---------------- #
-pattern.dev: $(INT_MAK) $(ECHOGS_XE) patlib.dev patread.dev
- $(SETMOD) pattern -include patlib patread
+ipcolor_h=$(PSSRC)ipcolor.h
+
+$(PSD)pattern.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)patlib.dev $(PSD)patread.dev
+ $(SETMOD) $(PSD)pattern -include $(GLD)patlib $(PSD)patread
patread_=$(PSOBJ)zpcolor.$(OBJ)
-patread.dev: $(INT_MAK) $(ECHOGS_XE) $(patread_)
- $(SETMOD) patread $(patread_)
- $(ADDMOD) patread -oper zpcolor_l2
+$(PSD)patread.dev : $(INT_MAK) $(ECHOGS_XE) $(patread_)
+ $(SETMOD) $(PSD)patread $(patread_)
+ $(ADDMOD) $(PSD)patread -oper zpcolor_l2
-$(PSOBJ)zpcolor.$(OBJ): $(PSSRC)zpcolor.c $(OP)\
+$(PSOBJ)zpcolor.$(OBJ) : $(PSSRC)zpcolor.c $(OP)\
$(gscolor_h) $(gsmatrix_h) $(gsstruct_h)\
$(gxcolor2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h)\
$(gxfixed_h) $(gxpcolor_h)\
- $(estack_h) $(ialloc_h) $(idict_h) $(idparam_h) $(igstate_h) $(istruct_h)\
+ $(estack_h)\
+ $(ialloc_h) $(icremap_h) $(idict_h) $(idparam_h) $(igstate_h)\
+ $(ipcolor_h) $(istruct_h)\
$(store_h)
$(PSCC) $(PSO_)zpcolor.$(OBJ) $(C_) $(PSSRC)zpcolor.c
# ---------------- Separation color ---------------- #
seprread_=$(PSOBJ)zcssepr.$(OBJ)
-sepr.dev: $(INT_MAK) $(ECHOGS_XE) $(seprread_) seprlib.dev
- $(SETMOD) sepr $(seprread_)
- $(ADDMOD) sepr -oper zcssepr_l2
- $(ADDMOD) sepr -include seprlib
+$(PSD)sepr.dev : $(INT_MAK) $(ECHOGS_XE) $(seprread_) $(GLD)seprlib.dev
+ $(SETMOD) $(PSD)sepr $(seprread_)
+ $(ADDMOD) $(PSD)sepr -oper zcssepr_l2
+ $(ADDMOD) $(PSD)sepr -include $(GLD)seprlib
-$(PSOBJ)zcssepr.$(OBJ): $(PSSRC)zcssepr.c $(OP)\
+$(PSOBJ)zcssepr.$(OBJ) : $(PSSRC)zcssepr.c $(OP) $(memory__h)\
$(gscolor_h) $(gscsepr_h) $(gsmatrix_h) $(gsstruct_h)\
$(gxcolor2_h) $(gxcspace_h) $(gxfixed_h)\
$(ialloc_h) $(icsmap_h) $(estack_h) $(igstate_h) $(ivmspace_h) $(store_h)
@@ -1246,21 +1338,22 @@ $(PSOBJ)zcssepr.$(OBJ): $(PSSRC)zcssepr.c $(OP)\
# ---------------- Functions ---------------- #
-ifunc_h=$(PSSRC)ifunc.h
+ifunc_h=$(PSSRC)ifunc.h $(gsfunc_h)
# Generic support, and FunctionType 0.
funcread_=$(PSOBJ)zfunc.$(OBJ) $(PSOBJ)zfunc0.$(OBJ)
-func.dev: $(INT_MAK) $(ECHOGS_XE) $(funcread_) funclib.dev
- $(SETMOD) func $(funcread_)
- $(ADDMOD) func -oper zfunc zfunc0
- $(ADDMOD) func -include funclib
-
-$(PSOBJ)zfunc.$(OBJ): $(PSSRC)zfunc.c $(OP) $(memory__h)\
- $(gsfunc_h) $(gsstruct_h)\
+$(PSD)func.dev : $(INT_MAK) $(ECHOGS_XE) $(funcread_) $(GLD)funclib.dev
+ $(SETMOD) $(PSD)func $(funcread_)
+ $(ADDMOD) $(PSD)func -oper zfunc
+ $(ADDMOD) $(PSD)func -functiontype 0
+ $(ADDMOD) $(PSD)func -include $(GLD)funclib
+
+$(PSOBJ)zfunc.$(OBJ) : $(PSSRC)zfunc.c $(OP) $(memory__h)\
+ $(gscdefs_h) $(gsfunc_h) $(gsstruct_h)\
$(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h) $(store_h)
$(PSCC) $(PSO_)zfunc.$(OBJ) $(C_) $(PSSRC)zfunc.c
-$(PSOBJ)zfunc0.$(OBJ): $(PSSRC)zfunc0.c $(OP) $(memory__h)\
+$(PSOBJ)zfunc0.$(OBJ) : $(PSSRC)zfunc0.c $(OP) $(memory__h)\
$(gsdsrc_h) $(gsfunc_h) $(gsfunc0_h)\
$(stream_h)\
$(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h)
@@ -1269,19 +1362,19 @@ $(PSOBJ)zfunc0.$(OBJ): $(PSSRC)zfunc0.c $(OP) $(memory__h)\
# ---------------- DCT filters ---------------- #
# The definitions for jpeg*.dev are in jpeg.mak.
-dct.dev: $(INT_MAK) $(ECHOGS_XE) dcte.dev dctd.dev
- $(SETMOD) dct -include dcte dctd
+$(PSD)dct.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)dcte.dev $(GLD)dctd.dev
+ $(SETMOD) $(PSD)dct -include $(GLD)dcte $(GLD)dctd
# Encoding (compression)
dcte_=$(PSOBJ)zfdcte.$(OBJ) $(GLOBJ)sdeparam.$(OBJ) $(GLOBJ)sdcparam.$(OBJ)
-dcte.dev: $(INT_MAK) $(ECHOGS_XE) sdcte.dev $(dcte_)
- $(SETMOD) dcte -include sdcte
- $(ADDMOD) dcte -obj $(dcte_)
- $(ADDMOD) dcte -oper zfdcte
+$(PSD)dcte.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)sdcte.dev $(dcte_)
+ $(SETMOD) $(PSD)dcte -include $(GLD)sdcte
+ $(ADDMOD) $(PSD)dcte -obj $(dcte_)
+ $(ADDMOD) $(PSD)dcte -oper zfdcte
-$(PSOBJ)zfdcte.$(OBJ): $(PSSRC)zfdcte.c $(OP)\
- $(memory__h) $(stdio__h) $(jpeglib_h)\
+$(PSOBJ)zfdcte.$(OBJ) : $(PSSRC)zfdcte.c $(OP)\
+ $(memory__h) $(stdio__h) $(jpeglib__h)\
$(gsmalloc_h)\
$(sdct_h) $(sjpeg_h) $(stream_h) $(strimpl_h)\
$(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h) $(iparam_h)
@@ -1290,13 +1383,13 @@ $(PSOBJ)zfdcte.$(OBJ): $(PSSRC)zfdcte.c $(OP)\
# Decoding (decompression)
dctd_=$(PSOBJ)zfdctd.$(OBJ) $(GLOBJ)sddparam.$(OBJ) $(GLOBJ)sdcparam.$(OBJ)
-dctd.dev: $(INT_MAK) $(ECHOGS_XE) sdctd.dev $(dctd_)
- $(SETMOD) dctd -include sdctd
- $(ADDMOD) dctd -obj $(dctd_)
- $(ADDMOD) dctd -oper zfdctd
+$(PSD)dctd.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)sdctd.dev $(dctd_)
+ $(SETMOD) $(PSD)dctd -include $(GLD)sdctd
+ $(ADDMOD) $(PSD)dctd -obj $(dctd_)
+ $(ADDMOD) $(PSD)dctd -oper zfdctd
-$(PSOBJ)zfdctd.$(OBJ): $(PSSRC)zfdctd.c $(OP)\
- $(memory__h) $(stdio__h) $(jpeglib_h)\
+$(PSOBJ)zfdctd.$(OBJ) : $(PSSRC)zfdctd.c $(OP)\
+ $(memory__h) $(stdio__h) $(jpeglib__h)\
$(gsmalloc_h)\
$(ialloc_h) $(ifilter_h) $(iparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h)
$(PSCC) $(PSO_)zfdctd.$(OBJ) $(C_) $(PSSRC)zfdctd.c
@@ -1304,12 +1397,13 @@ $(PSOBJ)zfdctd.$(OBJ): $(PSSRC)zfdctd.c $(OP)\
# ---------------- zlib/Flate filters ---------------- #
fzlib_=$(PSOBJ)zfzlib.$(OBJ)
-fzlib.dev: $(INT_MAK) $(ECHOGS_XE) $(fzlib_) szlibe.dev szlibd.dev
- $(SETMOD) fzlib -include szlibe szlibd
- $(ADDMOD) fzlib -obj $(fzlib_)
- $(ADDMOD) fzlib -oper zfzlib
+$(PSD)fzlib.dev : $(INT_MAK) $(ECHOGS_XE) $(fzlib_)\
+ $(GLD)szlibe.dev $(GLD)szlibd.dev
+ $(SETMOD) $(PSD)fzlib -include $(GLD)szlibe $(GLD)szlibd
+ $(ADDMOD) $(PSD)fzlib -obj $(fzlib_)
+ $(ADDMOD) $(PSD)fzlib -oper zfzlib
-$(PSOBJ)zfzlib.$(OBJ): $(PSSRC)zfzlib.c $(OP)\
+$(PSOBJ)zfzlib.$(OBJ) : $(PSSRC)zfzlib.c $(OP)\
$(idict_h) $(ifilter_h)\
$(spdiffx_h) $(spngpx_h) $(strimpl_h) $(szlibx_h)
$(PSCC) $(PSO_)zfzlib.$(OBJ) $(C_) $(PSSRC)zfzlib.c
@@ -1317,19 +1411,19 @@ $(PSOBJ)zfzlib.$(OBJ): $(PSSRC)zfzlib.c $(OP)\
# ================ Display PostScript ================ #
dps_=$(PSOBJ)zdps.$(OBJ) $(PSOBJ)zcontext.$(OBJ)
-dps.dev: $(INT_MAK) $(ECHOGS_XE) dpslib.dev psl2.dev $(dps_)
- $(SETMOD) dps -include dpslib psl2
- $(ADDMOD) dps -obj $(dps_)
- $(ADDMOD) dps -oper zcontext zdps
- $(ADDMOD) dps -ps gs_dps
+$(PSD)dps.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)dpslib.dev $(PSD)psl2.dev $(dps_)
+ $(SETMOD) $(PSD)dps -include $(GLD)dpslib $(PSD)psl2
+ $(ADDMOD) $(PSD)dps -obj $(dps_)
+ $(ADDMOD) $(PSD)dps -oper zcontext1 zcontext2 zdps
+ $(ADDMOD) $(PSD)dps -ps gs_dps
-$(PSOBJ)zdps.$(OBJ): $(PSSRC)zdps.c $(OP)\
+$(PSOBJ)zdps.$(OBJ) : $(PSSRC)zdps.c $(OP)\
$(gsdps_h) $(gsimage_h) $(gsiparm2_h) $(gsstate_h)\
$(gxfixed_h) $(gxpath_h)\
- $(btoken_h) $(idparam_h) $(idict_h) $(igstate_h) $(iname_h) $(store_h)
+ $(btoken_h) $(idparam_h) $(iddict_h) $(igstate_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zdps.$(OBJ) $(C_) $(PSSRC)zdps.c
-$(PSOBJ)zcontext.$(OBJ): $(PSSRC)zcontext.c $(OP) $(gp_h) $(memory__h)\
+$(PSOBJ)zcontext.$(OBJ) : $(PSSRC)zcontext.c $(OP) $(gp_h) $(memory__h)\
$(gsexit_h) $(gsstruct_h) $(gsutil_h) $(gxalloc_h) $(gxstate_h)\
$(icontext_h) $(idict_h) $(igstate_h) $(interp_h) $(isave_h) $(istruct_h)\
$(dstack_h) $(estack_h) $(files_h) $(ostack_h) $(store_h) $(stream_h)
@@ -1338,14 +1432,14 @@ $(PSOBJ)zcontext.$(OBJ): $(PSSRC)zcontext.c $(OP) $(gp_h) $(memory__h)\
# ---------------- NeXT Display PostScript ---------------- #
dpsnext_=$(PSOBJ)zdpnext.$(OBJ)
-dpsnext.dev: $(INT_MAK) $(ECHOGS_XE) dps.dev dpnxtlib.dev $(dpsnext_)\
- $(PSSRC)gs_dpnxt.ps
- $(SETMOD) dpsnext -include dps dpnxtlib
- $(ADDMOD) dpsnext -obj $(dpsnext_)
- $(ADDMOD) dpsnext -oper zdpnext
- $(ADDMOD) dpsnext -ps gs_dpnxt
-
-$(PSOBJ)zdpnext.$(OBJ): $(PSSRC)zdpnext.c $(math__h) $(OP)\
+$(PSD)dpsnext.dev : $(INT_MAK) $(ECHOGS_XE) $(dpsnext_)\
+ $(PSD)dps.dev $(GLD)dpnxtlib.dev
+ $(SETMOD) $(PSD)dpsnext -include $(PSD)dps $(GLD)dpnxtlib
+ $(ADDMOD) $(PSD)dpsnext -obj $(dpsnext_)
+ $(ADDMOD) $(PSD)dpsnext -oper zdpnext
+ $(ADDMOD) $(PSD)dpsnext -ps gs_dpnxt
+
+$(PSOBJ)zdpnext.$(OBJ) : $(PSSRC)zdpnext.c $(math__h) $(OP)\
$(gscoord_h) $(gscspace_h) $(gsdpnext_h)\
$(gsiparam_h) $(gsiparm2_h) $(gsmatrix_h) $(gspath2_h)\
$(gxcvalue_h) $(gxdevice_h) $(gxsample_h)\
@@ -1357,70 +1451,86 @@ $(PSOBJ)zdpnext.$(OBJ): $(PSSRC)zdpnext.c $(math__h) $(OP)\
# ---------------- DevicePixel color space ---------------- #
cspixint_=$(PSOBJ)zcspixel.$(OBJ)
-cspixel.dev: $(INT_MAK) $(ECHOGS_XE) $(cspixint_) cspixlib.dev
- $(SETMOD) cspixel $(cspixint_)
- $(ADDMOD) cspixel -oper zcspixel
- $(ADDMOD) cspixel -include cspixlib
+$(PSD)cspixel.dev : $(INT_MAK) $(ECHOGS_XE) $(cspixint_) $(GLD)cspixlib.dev
+ $(SETMOD) $(PSD)cspixel $(cspixint_)
+ $(ADDMOD) $(PSD)cspixel -oper zcspixel
+ $(ADDMOD) $(PSD)cspixel -include $(GLD)cspixlib
-$(PSOBJ)zcspixel.$(OBJ): $(PSSRC)zcspixel.c $(OP)\
+$(PSOBJ)zcspixel.$(OBJ) : $(PSSRC)zcspixel.c $(OP)\
$(gscolor2_h) $(gscpixel_h) $(gscspace_h) $(gsmatrix_h)\
$(igstate_h)
$(PSCC) $(PSO_)zcspixel.$(OBJ) $(C_) $(PSSRC)zcspixel.c
# ---------------- Rest of LanguageLevel 3 ---------------- #
-psl3.dev: $(INT_MAK) $(ECHOGS_XE)\
- psl2.dev cspixel.dev func.dev psl3lib.dev psl3read.dev
- $(SETMOD) psl3 -include psl2 cspixel func psl3lib psl3read
+$(PSD)psl3.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)psl2.dev $(PSD)cspixel.dev $(PSD)func.dev $(GLD)psl3lib.dev $(PSD)psl3read.dev
+ $(SETMOD) $(PSD)psl3 -include $(PSD)psl2 $(PSD)cspixel $(PSD)func $(GLD)psl3lib $(PSD)psl3read
-$(PSOBJ)zcsdevn.$(OBJ): $(PSSRC)zcsdevn.c $(OP)\
- $(gscolor2_h) $(gxcspace_h)\
- $(ialloc_h) $(igstate_h) $(iname_h)
+$(PSOBJ)zcsdevn.$(OBJ) : $(PSSRC)zcsdevn.c $(OP) $(memory__h)\
+ $(gscolor2_h) $(gxcdevn_h) $(gxcspace_h)\
+ $(estack_h) $(ialloc_h) $(icremap_h) $(igstate_h) $(iname_h) $(ostack_h)\
+ $(store_h)
$(PSCC) $(PSO_)zcsdevn.$(OBJ) $(C_) $(PSSRC)zcsdevn.c
-$(PSOBJ)zfreuse.$(OBJ): $(PSSRC)zfreuse.c $(OP) $(memory__h)\
+$(PSOBJ)zfreuse.$(OBJ) : $(PSSRC)zfreuse.c $(OP) $(memory__h)\
$(sfilter_h) $(stream_h) $(strimpl_h)\
$(files_h) $(idict_h) $(idparam_h) $(iname_h) $(store_h)
$(PSCC) $(PSO_)zfreuse.$(OBJ) $(C_) $(PSSRC)zfreuse.c
-$(PSOBJ)zfunc3.$(OBJ): $(PSSRC)zfunc3.c $(memory__h) $(OP)\
+$(PSOBJ)zfunc3.$(OBJ) : $(PSSRC)zfunc3.c $(memory__h) $(OP)\
$(gsfunc3_h) $(gsstruct_h)\
$(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h)\
$(store_h) $(stream_h)
$(PSCC) $(PSO_)zfunc3.$(OBJ) $(C_) $(PSSRC)zfunc3.c
-$(PSOBJ)zimage3.$(OBJ): $(PSSRC)zimage3.c $(OP) $(memory__h)\
+$(PSOBJ)zimage3.$(OBJ) : $(PSSRC)zimage3.c $(OP) $(memory__h)\
$(gscolor2_h) $(gsiparm3_h) $(gsiparm4_h) $(gscspace_h) $(gxiparam_h)\
$(idparam_h) $(idict_h) $(igstate_h) $(iimage_h) $(iimage2_h)
$(PSCC) $(PSO_)zimage3.$(OBJ) $(C_) $(PSSRC)zimage3.c
-$(PSOBJ)zmisc3.$(OBJ): $(PSSRC)zmisc3.c $(GH)\
- $(gsclipsr_h) $(igstate_h) $(oper_h) $(store_h)
+$(PSOBJ)zmisc3.$(OBJ) : $(PSSRC)zmisc3.c $(GH)\
+ $(gsclipsr_h) $(gscolor2_h) $(gscspace_h) $(gscssub_h) $(gsmatrix_h)\
+ $(igstate_h) $(oper_h) $(store_h)
$(PSCC) $(PSO_)zmisc3.$(OBJ) $(C_) $(PSSRC)zmisc3.c
-$(PSOBJ)zshade.$(OBJ): $(PSSRC)zshade.c $(memory__h) $(OP)\
+$(PSOBJ)zshade.$(OBJ) : $(PSSRC)zshade.c $(memory__h) $(OP)\
$(gscolor2_h) $(gscolor3_h) $(gscspace_h) $(gsfunc3_h)\
- $(gsshade_h) $(gsstruct_h) $(gsuid_h)\
+ $(gsptype2_h) $(gsshade_h) $(gsstruct_h) $(gsuid_h)\
$(stream_h)\
- $(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h) $(igstate_h) $(store_h)
+ $(files_h)\
+ $(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h) $(igstate_h) $(ipcolor_h)\
+ $(store_h)
$(PSCC) $(PSO_)zshade.$(OBJ) $(C_) $(PSSRC)zshade.c
-$(PSOBJ)ztrap.$(OBJ): $(PSSRC)ztrap.c $(OP)\
+psl3read_1=$(PSOBJ)zcsdevn.$(OBJ) $(PSOBJ)zfreuse.$(OBJ) $(PSOBJ)zfunc3.$(OBJ)
+psl3read_2=$(PSOBJ)zimage3.$(OBJ) $(PSOBJ)zmisc3.$(OBJ) $(PSOBJ)zshade.$(OBJ)
+psl3read_=$(psl3read_1) $(psl3read_2)
+
+$(PSD)psl3read.dev : $(INT_MAK) $(ECHOGS_XE) $(psl3read_) $(PSD)fzlib.dev
+ $(SETMOD) $(PSD)psl3read $(psl3read_1)
+ $(ADDMOD) $(PSD)psl3read $(psl3read_2)
+ $(ADDMOD) $(PSD)psl3read -oper zcsdevn zfreuse
+ $(ADDMOD) $(PSD)psl3read -oper zimage3 zmisc3 zshade
+ $(ADDMOD) $(PSD)psl3read -functiontype 2 3
+ $(ADDMOD) $(PSD)psl3read -ps gs_ll3
+ $(ADDMOD) $(PSD)psl3read -include $(PSD)fzlib
+
+# ---------------- Trapping ---------------- #
+
+trapread_=$(PSOBJ)ztrap.$(OBJ)
+$(PSD)trapread.dev : $(INT_MAK) $(ECHOGS_XE) $(trapread_)
+ $(SETMOD) $(PSD)trapread $(trapread_)
+ $(ADDMOD) $(PSD)trapread -oper ztrap
+ $(ADDMOD) $(PSD)trapread -ps gs_trap
+
+$(PSOBJ)ztrap.$(OBJ) : $(PSSRC)ztrap.c $(OP)\
$(gstrap_h)\
$(ialloc_h) $(iparam_h)
$(PSCC) $(PSO_)ztrap.$(OBJ) $(C_) $(PSSRC)ztrap.c
-psl3read_1=$(PSOBJ)zcsdevn.$(OBJ) $(PSOBJ)zfreuse.$(OBJ) $(PSOBJ)zfunc3.$(OBJ) $(PSOBJ)zimage3.$(OBJ)
-psl3read_2=$(PSOBJ)zmisc3.$(OBJ) $(PSOBJ)zshade.$(OBJ) $(PSOBJ)ztrap.$(OBJ)
-psl3read_=$(psl3read_1) $(psl3read_2)
-
-psl3read.dev: $(INT_MAK) $(ECHOGS_XE) $(psl3read_) fzlib.dev
- $(SETMOD) psl3read $(psl3read_1)
- $(ADDMOD) psl3read $(psl3read_2)
- $(ADDMOD) psl3read -oper zcsdevn zfreuse zfunc3 zimage3
- $(ADDMOD) psl3read -oper zmisc3 zshade ztrap
- $(ADDMOD) psl3read -ps gs_ll3
- $(ADDMOD) psl3read -include fzlib
+$(PSD)trapping.dev : $(INT_MAK) $(ECHOGS_XE) $(GLD)traplib.dev $(PSD)trapread.dev
+ $(SETMOD) $(PSD)trapping -include $(GLD)traplib $(PSD)trapread
# ================================ PDF ================================ #
@@ -1431,46 +1541,48 @@ psl3read.dev: $(INT_MAK) $(ECHOGS_XE) $(psl3read_) fzlib.dev
# before we install the Level 2 resource machinery.
# On the other hand, the PDF .ps files must get loaded after
# level2dict is defined.
-pdfmin.dev: $(INT_MAK) $(ECHOGS_XE)\
- psbase.dev color.dev compfont.dev dps2lib.dev dps2read.dev\
- fdecode.dev type1.dev pdffonts.dev psl2lib.dev psl2read.dev pdfread.dev
- $(SETMOD) pdfmin -include psbase color compfont
- $(ADDMOD) pdfmin -include dps2lib dps2read fdecode type1
- $(ADDMOD) pdfmin -include pdffonts psl2lib psl2read pdfread
- $(ADDMOD) pdfmin -emulator PDF
-
-pdf.dev: $(INT_MAK) $(ECHOGS_XE)\
- pdfmin.dev cff.dev cidfont.dev cie.dev cmapread.dev dctd.dev\
- func.dev ttfont.dev type2.dev
- $(SETMOD) pdf -include pdfmin cff cidfont cie cmapread dctd
- $(ADDMOD) pdf -include func ttfont type2
+$(PSD)pdfmin.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)psbase.dev $(PSD)color.dev $(PSD)compfont.dev $(GLD)dps2lib.dev $(PSD)dps2read.dev\
+ $(PSD)fdecode.dev $(PSD)type1.dev $(PSD)pdffonts.dev $(GLD)psl2lib.dev $(PSD)psl2read.dev $(PSD)pdfread.dev
+ $(SETMOD) $(PSD)pdfmin -include $(PSD)psbase $(PSD)color $(PSD)compfont $(GLD)dps2lib
+ $(ADDMOD) $(PSD)pdfmin -include $(PSD)dps2read $(PSD)fdecode $(PSD)type1 $(PSD)pdffonts
+ $(ADDMOD) $(PSD)pdfmin -include $(GLD)psl2lib $(PSD)psl2read $(PSD)pdfread
+ $(ADDMOD) $(PSD)pdfmin -emulator PDF
+
+$(PSD)pdf.dev : $(INT_MAK) $(ECHOGS_XE)\
+ $(PSD)pdfmin.dev $(PSD)cff.dev $(PSD)cidfont.dev $(PSD)cie.dev $(PSD)cmapread.dev $(PSD)dctd.dev\
+ $(PSD)func.dev $(PSD)ttfont.dev $(PSD)type2.dev
+ $(SETMOD) $(PSD)pdf -include $(PSD)pdfmin $(PSD)cff $(PSD)cidfont $(PSD)cie
+ $(ADDMOD) $(PSD)pdf -include $(PSD)cmapread $(PSD)dctd $(PSD)func $(PSD)ttfont $(PSD)type2
# Reader only
-pdffonts.dev: $(INT_MAK) $(ECHOGS_XE)\
- $(PSSRC)gs_mex_e.ps $(PSSRC)gs_mro_e.ps $(PSSRC)gs_pdf_e.ps\
- $(PSSRC)gs_wan_e.ps
- $(SETMOD) pdffonts -ps gs_mex_e gs_mro_e gs_pdf_e gs_wan_e
+$(PSD)pdffonts.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(PSD)pdffonts -ps gs_mex_e gs_mro_e gs_pdf_e gs_wan_e
-pdfread.dev: $(INT_MAK) $(ECHOGS_XE) fzlib.dev
- $(SETMOD) pdfread -include fzlib
- $(ADDMOD) pdfread -ps pdf_ops gs_l2img
- $(ADDMOD) pdfread -ps pdf_base pdf_draw pdf_font pdf_main pdf_sec
+$(PSD)pdfread.dev : $(INT_MAK) $(ECHOGS_XE) $(dpsnext_) $(PSD)fzlib.dev
+ $(SETMOD) $(PSD)pdfread -include $(PSD)fzlib
+ $(ADDMOD) $(PSD)pdfread -ps pdf_ops gs_l2img
+ $(ADDMOD) $(PSD)pdfread -ps pdf_base pdf_draw pdf_font pdf_main pdf_sec
+
+# ================ Dependencies for auxiliary programs ================ #
+
+GENINIT_DEPS=$(stdpre_h)
# ============================= Main program ============================== #
-$(PSOBJ)gs.$(OBJ): $(PSSRC)gs.c $(GH)\
+$(PSOBJ)gs.$(OBJ) : $(PSSRC)gs.c $(GH)\
$(imain_h) $(imainarg_h) $(iminst_h)
$(PSCC) $(PSO_)gs.$(OBJ) $(C_) $(PSSRC)gs.c
-$(PSOBJ)icontext.$(OBJ): $(PSSRC)icontext.c $(GH)\
+$(PSOBJ)icontext.$(OBJ) : $(PSSRC)icontext.c $(GH)\
$(gsstruct_h) $(gxalloc_h)\
- $(dstack_h) $(errors_h) $(estack_h) $(files_h) $(ostack_h)\
+ $(dstack_h) $(errors_h) $(estack_h) $(files_h)\
$(icontext_h) $(idict_h) $(igstate_h) $(interp_h) $(isave_h) $(store_h)\
$(stream_h)
$(PSCC) $(PSO_)icontext.$(OBJ) $(C_) $(PSSRC)icontext.c
-$(PSOBJ)imainarg.$(OBJ): $(PSSRC)imainarg.c $(GH)\
+$(PSOBJ)imainarg.$(OBJ) : $(PSSRC)imainarg.c $(GH)\
$(ctype__h) $(memory__h) $(string__h)\
$(gp_h)\
$(gsargs_h) $(gscdefs_h) $(gsdevice_h) $(gsmalloc_h) $(gsmdebug_h)\
@@ -1481,7 +1593,7 @@ $(PSOBJ)imainarg.$(OBJ): $(PSSRC)imainarg.c $(GH)\
$(ostack_h) $(sfilter_h) $(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)imainarg.$(OBJ) $(C_) $(PSSRC)imainarg.c
-$(PSOBJ)imain.$(OBJ): $(PSSRC)imain.c $(GH) $(memory__h) $(string__h)\
+$(PSOBJ)imain.$(OBJ) : $(PSSRC)imain.c $(GH) $(memory__h) $(string__h)\
$(gp_h) $(gslib_h) $(gsmatrix_h) $(gsutil_h) $(gxdevice_h)\
$(dstack_h) $(errors_h) $(estack_h) $(files_h)\
$(ialloc_h) $(idebug_h) $(idict_h) $(iname_h) $(interp_h)\
@@ -1491,16 +1603,16 @@ $(PSOBJ)imain.$(OBJ): $(PSSRC)imain.c $(GH) $(memory__h) $(string__h)\
$(PSCC) $(PSO_)imain.$(OBJ) $(C_) $(PSSRC)imain.c
#****** $(CCINT) interp.c
-$(PSOBJ)interp.$(OBJ): $(PSSRC)interp.c $(GH) $(memory__h) $(string__h)\
+$(PSOBJ)interp.$(OBJ) : $(PSSRC)interp.c $(GH) $(memory__h) $(string__h)\
$(gsstruct_h)\
$(dstack_h) $(errors_h) $(estack_h) $(files_h)\
- $(ialloc_h) $(iastruct_h) $(icontext_h) $(idict_h) $(iname_h) $(inamedef_h)\
- $(interp_h) $(ipacked_h) $(isave_h) $(iscan_h) $(istack_h)\
- $(iutil_h) $(ivmspace_h)\
+ $(ialloc_h) $(iastruct_h) $(icontext_h) $(icremap_h) $(iddict_h) $(igstate_h)\
+ $(iname_h) $(inamedef_h) $(interp_h) $(ipacked_h)\
+ $(isave_h) $(iscan_h) $(istack_h) $(iutil_h) $(ivmspace_h)\
$(oper_h) $(ostack_h) $(sfilter_h) $(store_h) $(stream_h) $(strimpl_h)
$(PSCC) $(PSO_)interp.$(OBJ) $(C_) $(PSSRC)interp.c
-$(PSOBJ)ireclaim.$(OBJ): $(PSSRC)ireclaim.c $(GH)\
+$(PSOBJ)ireclaim.$(OBJ) : $(PSSRC)ireclaim.c $(GH)\
$(gsstruct_h)\
$(iastate_h) $(icontext_h) $(interp_h) $(isave_h) $(isstate_h)\
$(dstack_h) $(errors_h) $(estack_h) $(opdef_h) $(ostack_h) $(store_h)
diff --git a/gs/src/interp.c b/gs/src/interp.c
index 623a7a538..136948950 100644
--- a/gs/src/interp.c
+++ b/gs/src/interp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,6 +28,8 @@
#include "ialloc.h"
#include "iastruct.h"
#include "icontext.h"
+#include "icremap.h"
+#include "igstate.h" /* for handling e_RemapColor */
#include "inamedef.h"
#include "iname.h" /* for the_name_table */
#include "interp.h"
@@ -36,7 +38,7 @@
#include "strimpl.h" /* for sfilter.h */
#include "sfilter.h" /* for iscan.h */
#include "iscan.h"
-#include "idict.h"
+#include "iddict.h"
#include "isave.h"
#include "istack.h"
#include "iutil.h" /* for array_get */
@@ -63,35 +65,41 @@
* a little slower.
*/
+/* GC descriptors for stacks */
+extern_st(st_ref_stack);
+public_st_dict_stack();
+public_st_exec_stack();
+public_st_op_stack();
+
/* Imported operator procedures */
extern int zop_add(P1(os_ptr));
-extern int zop_def(P1(os_ptr));
+extern int zop_def(P1(i_ctx_t *));
extern int zop_sub(P1(os_ptr));
/* Other imported procedures */
-extern int ztokenexec_continue(P1(os_ptr));
+extern int ztokenexec_continue(P1(i_ctx_t *));
/*
* The procedure to call if an operator requests rescheduling.
* This causes an error unless the context machinery has been installed.
*/
private int
-no_reschedule(void)
+no_reschedule(i_ctx_t **pi_ctx_p)
{
return_error(e_invalidcontext);
}
-int (*gs_interp_reschedule_proc) (P0()) = no_reschedule;
+int (*gs_interp_reschedule_proc)(P1(i_ctx_t **)) = no_reschedule;
/*
* The procedure to call for time-slicing.
* This is a no-op unless the context machinery has been installed.
*/
int
-no_time_slice_proc(void)
+no_time_slice_proc(i_ctx_t **pi_ctx_p)
{
return 0;
}
-int (*gs_interp_time_slice_proc) (P0()) = no_time_slice_proc;
+int (*gs_interp_time_slice_proc)(P1(i_ctx_t **)) = no_time_slice_proc;
/*
* The number of interpreter "ticks" between calls on the time_slice_proc.
@@ -106,24 +114,41 @@ int gs_interp_time_slice_ticks = 0x7fff;
*/
#ifdef DEBUG
private int
-call_operator(int (*op_proc) (P1(os_ptr)), os_ptr op)
+call_operator(op_proc_t op_proc, i_ctx_t *i_ctx_p)
{
- int code = (*op_proc) (op);
+ int code = op_proc(i_ctx_p);
return code;
}
#else
-# define call_operator(proc, op) ((*(proc))(op))
+# define call_operator(proc, p) ((*(proc))(p))
+#endif
+
+/* Define debugging statistics. */
+#ifdef DEBUG
+struct stats_interp_s {
+ long top;
+ long lit, lit_array, exec_array, exec_operator, exec_name;
+ long x_add, x_def, x_dup, x_exch, x_if, x_ifelse,
+ x_index, x_pop, x_roll, x_sub;
+ long find_name, name_lit, name_proc, name_oparray, name_operator;
+ long p_full, p_exec_operator, p_exec_oparray, p_exec_non_x_operator,
+ p_integer, p_lit_name, p_exec_name;
+ long p_find_name, p_name_lit, p_name_proc;
+} stats_interp;
+# define INCR(v) (++(stats_interp.v))
+#else
+# define INCR(v) DO_NOTHING
#endif
/* Forward references */
-private int estack_underflow(P1(os_ptr));
-private int interp(P2(ref *, ref *));
-private int interp_exit(P1(os_ptr));
-private void set_gc_signal(P2(int *, int));
-private int copy_stack(P2(const ref_stack *, ref *));
-private int oparray_pop(P1(os_ptr));
-private int oparray_cleanup(P1(os_ptr));
+private int estack_underflow(P1(i_ctx_t *));
+private int interp(P3(i_ctx_t **, const ref *, ref *));
+private int interp_exit(P1(i_ctx_t *));
+private void set_gc_signal(P3(i_ctx_t *, int *, int));
+private int copy_stack(P2(const ref_stack_t *, ref *));
+private int oparray_pop(P1(i_ctx_t *));
+private int oparray_cleanup(P1(i_ctx_t *));
/* Stack sizes */
@@ -176,9 +201,6 @@ const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */
*/
#define MIN_BLOCK_DSTACK 3
-/* Interpreter state variables */
-ref ref_language_level; /* 1 or 2, set by iinit.c */
-
/* See estack.h for a description of the execution stack. */
/* The logic for managing icount and iref below assumes that */
@@ -191,22 +213,14 @@ extern_st(st_ref_stack);
#define OS_GUARD_OVER 10
#define OS_REFS_SIZE(body_size)\
(stack_block_refs + OS_GUARD_UNDER + (body_size) + OS_GUARD_OVER)
-op_stack_t iop_stack;
#define ES_GUARD_UNDER 1
#define ES_GUARD_OVER 10
#define ES_REFS_SIZE(body_size)\
(stack_block_refs + ES_GUARD_UNDER + (body_size) + ES_GUARD_OVER)
-exec_stack_t iexec_stack;
#define DS_REFS_SIZE(body_size)\
(stack_block_refs + (body_size))
-dict_stack_t idict_stack;
-
- /*#define d_stack (idict_stack.stack) *//* in dstack.h */
-
-/* Define a pointer to the current interpreter context state. */
-gs_context_state_t *gs_interp_context_state_current;
/* Extended types. The interpreter may replace the type of operators */
/* in procedures with these, to speed up the interpretation loop. */
@@ -214,10 +228,6 @@ gs_context_state_t *gs_interp_context_state_current;
/****** you must change the three dispatches in the interpreter loop. */
/* The operator procedures are declared in opextern.h. */
#define tx_op t_next_index
-private const op_proc_p special_ops[] =
-{
- zadd, zdef, zdup, zexch, zif, zifelse, zindex, zpop, zroll, zsub
-};
typedef enum {
tx_op_add = tx_op,
tx_op_def,
@@ -236,24 +246,65 @@ typedef enum {
const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */
const int tx_next_index = tx_next_op;
+/*
+ * Define the interpreter operators, which include the extended-type
+ * operators defined in the list above. NOTE: if the size of this table
+ * ever exceeds 15 real entries, it will have to be split.
+ */
+const op_def interp_op_defs[] = {
+ /*
+ * The very first entry, which corresponds to operator index 0,
+ * must not contain an actual operator.
+ */
+ op_def_begin_dict("systemdict"),
+ /*
+ * The next entries must be the extended-type operators, in the
+ * correct order.
+ */
+ {"2add", zadd},
+ {"2def", zdef},
+ {"1dup", zdup},
+ {"2exch", zexch},
+ {"2if", zif},
+ {"3ifelse", zifelse},
+ {"1index", zindex},
+ {"1pop", zpop},
+ {"2roll", zroll},
+ {"2sub", zsub},
+ /*
+ * The remaining entries are internal operators.
+ */
+ {"0%interp_exit", interp_exit},
+ {"0%oparray_pop", oparray_pop},
+ op_def_end(0)
+};
+
#define make_null_proc(pref)\
make_empty_const_array(pref, a_executable + a_readonly)
/* Initialize the interpreter. */
-void
-gs_interp_init(void)
-{ /* Create and initialize a ocntext state. */
+int
+gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict)
+{
+ /* Create and initialize a context state. */
gs_context_state_t *pcst = 0;
int code = context_state_alloc(&pcst, &gs_imemory);
- if (code < 0 || (code = context_state_load(pcst)) < 0) {
- lprintf1("Fatal error %d in gs_interp_init!", code);
-/****** ABORT ******/
+ if (code >= 0) {
+ /*
+ * We have to initialize the dictionary stack early,
+ * for far-off references to systemdict.
+ */
+ pcst->dict_stack.system_dict = *psystem_dict;
+ pcst->dict_stack.stack.extension_size = 0;
+ pcst->dict_stack.min_size = 0;
+ code = context_state_load(pcst);
}
- gs_interp_context_state_current = pcst;
- gs_register_struct_root(imemory_local, NULL,
- (void **)&gs_interp_context_state_current,
- "gs_interp_init(gs_icst_root)");
+
+ *pi_ctx_p = pcst;
+ if (code < 0)
+ lprintf1("Fatal error %d in gs_interp_init!", code);
+ return code;
}
/*
* Create initial stacks for the interpreter.
@@ -272,46 +323,38 @@ gs_interp_alloc_stacks(gs_ref_memory_t * smem, gs_context_state_t * pcst)
REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
{
- ref_stack *pos = pcst->ostack =
- gs_alloc_struct((gs_memory_t *) smem, ref_stack, &st_ref_stack,
- "gs_interp_alloc_stacks(ostack)");
+ ref_stack_t *pos = &pcst->op_stack.stack;
r_set_size(&stk, REFS_SIZE_OSTACK);
- ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
- smem);
- pos->underflow_error = e_stackunderflow;
- pos->overflow_error = e_stackoverflow;
+ ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL, smem);
+ ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow);
ref_stack_set_max_count(pos, MAX_OSTACK);
+ stk.value.refs += REFS_SIZE_OSTACK;
}
{
- ref_stack *pes = pcst->estack =
- gs_alloc_struct((gs_memory_t *) smem, ref_stack, &st_ref_stack,
- "gs_interp_alloc_stacks(estack)");
+ ref_stack_t *pes = &pcst->exec_stack.stack;
ref euop;
- stk.value.refs += REFS_SIZE_OSTACK;
r_set_size(&stk, REFS_SIZE_ESTACK);
make_oper(&euop, 0, estack_underflow);
ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
smem);
- pes->underflow_error = e_ExecStackUnderflow;
- pes->overflow_error = e_execstackoverflow;
-/**************** E-STACK EXPANSION IS NYI. ****************/
- pes->allow_expansion = false;
+ ref_stack_set_error_codes(pes, e_ExecStackUnderflow,
+ e_execstackoverflow);
+ /**************** E-STACK EXPANSION IS NYI. ****************/
+ ref_stack_allow_expansion(pes, false);
ref_stack_set_max_count(pes, MAX_ESTACK);
+ stk.value.refs += REFS_SIZE_ESTACK;
}
{
- ref_stack *pds = pcst->dstack =
- gs_alloc_struct((gs_memory_t *) smem, ref_stack, &st_ref_stack,
- "gs_interp_alloc_stacks(dstack)");
+ ref_stack_t *pds = &pcst->dict_stack.stack;
- stk.value.refs += REFS_SIZE_ESTACK;
r_set_size(&stk, REFS_SIZE_DSTACK);
ref_stack_init(pds, &stk, 0, 0, NULL, smem);
- pds->underflow_error = e_dictstackunderflow;
- pds->overflow_error = e_dictstackoverflow;
+ ref_stack_set_error_codes(pds, e_dictstackunderflow,
+ e_dictstackoverflow);
ref_stack_set_max_count(pds, MAX_DSTACK);
}
@@ -326,17 +369,15 @@ gs_interp_alloc_stacks(gs_ref_memory_t * smem, gs_context_state_t * pcst)
*/
void
gs_interp_free_stacks(gs_ref_memory_t * smem, gs_context_state_t * pcst)
-{ /* Free the stacks in inverse order of allocation. */
- ref_stack_free(pcst->dstack, (gs_memory_t *) smem,
- "gs_interp_free_stacks(dstack)");
- ref_stack_free(pcst->estack, (gs_memory_t *) smem,
- "gs_interp_free_stacks(estack)");
- ref_stack_free(pcst->ostack, (gs_memory_t *) smem,
- "gs_interp_free_stacks(ostack)");
+{
+ /* Free the stacks in inverse order of allocation. */
+ ref_stack_release(&pcst->dict_stack.stack);
+ ref_stack_release(&pcst->exec_stack.stack);
+ ref_stack_release(&pcst->op_stack.stack);
}
void
-gs_interp_reset(void)
-{ /* Reset the stacks. */
+gs_interp_reset(i_ctx_t *i_ctx_p)
+{ /* Reset the stacks. */
ref_stack_clear(&o_stack);
ref_stack_clear(&e_stack);
esp++;
@@ -347,7 +388,7 @@ gs_interp_reset(void)
/* Report an e-stack block underflow. The bottom guard slots of */
/* e-stack blocks contain a pointer to this procedure. */
private int
-estack_underflow(os_ptr op)
+estack_underflow(i_ctx_t *i_ctx_p)
{
return e_ExecStackUnderflow;
}
@@ -358,13 +399,14 @@ estack_underflow(os_ptr op)
* assign it a special type and index.
*/
void
-gs_interp_make_oper(ref * opref, op_proc_p proc, int idx)
+gs_interp_make_oper(ref * opref, op_proc_t proc, int idx)
{
- register int i = num_special_ops;
+ int i;
- while (--i >= 0 && proc != special_ops[i]);
- if (i >= 0)
- make_tasv(opref, tx_op + i, a_executable, i + 1, opproc, proc);
+ for (i = num_special_ops; i > 0 && proc != interp_op_defs[i].proc; --i)
+ DO_NOTHING;
+ if (i > 0)
+ make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
else
make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
}
@@ -378,10 +420,12 @@ gs_interp_make_oper(ref * opref, op_proc_p proc, int idx)
* is active.)
* In case of a quit or a fatal error, also store the exit code.
*/
-private int gs_call_interp(P4(ref *, int, int *, ref *));
+private int gs_call_interp(P5(i_ctx_t **, ref *, int, int *, ref *));
int
-gs_interpret(ref * pref, int user_errors, int *pexit_code, ref * perror_object)
+gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code,
+ ref * perror_object)
{
+ i_ctx_t *i_ctx_p = *pi_ctx_p;
gs_gc_root_t error_root;
int code;
@@ -389,14 +433,17 @@ gs_interpret(ref * pref, int user_errors, int *pexit_code, ref * perror_object)
(void **)&perror_object, "gs_interpret");
/* Initialize the error object in case of GC. */
make_null(perror_object);
- code = gs_call_interp(pref, user_errors, pexit_code, perror_object);
+ code = gs_call_interp(pi_ctx_p, pref, user_errors, pexit_code,
+ perror_object);
+ i_ctx_p = *pi_ctx_p;
gs_unregister_root(imemory_system, &error_root, "gs_interpret");
/* Avoid a dangling reference to a stack-allocated GC signal. */
- set_gc_signal(NULL, 0);
+ set_gc_signal(i_ctx_p, NULL, 0);
return code;
}
private int
-gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object)
+gs_call_interp(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
+ int *pexit_code, ref * perror_object)
{
ref *epref = pref;
ref doref;
@@ -405,10 +452,12 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
int code, ccode;
ref saref;
int gc_signal = 0;
+ i_ctx_t *i_ctx_p = *pi_ctx_p;
*pexit_code = 0;
ialloc_reset_requested(idmemory);
- again:o_stack.requested = e_stack.requested = d_stack.requested = 0;
+again:
+ o_stack.requested = e_stack.requested = d_stack.requested = 0;
while (gc_signal) { /* Some routine below triggered a GC. */
gs_gc_root_t epref_root;
@@ -418,17 +467,20 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
gs_register_ref_root(imemory_system, &epref_root,
(void **)&epref,
"gs_call_interpret(epref)");
+ idmemory->reclaim_data = i_ctx_p;
code = (*idmemory->reclaim) (idmemory, -1);
+ *pi_ctx_p = i_ctx_p = idmemory->reclaim_data;
gs_unregister_root(imemory_system, &epref_root,
"gs_call_interpret(epref)");
if (code < 0)
return code;
}
- code = interp(epref, perror_object);
+ code = interp(pi_ctx_p, epref, perror_object);
+ i_ctx_p = *pi_ctx_p;
/* Prevent a dangling reference to the GC signal in ticks_left */
/* in the frame of interp, but be prepared to do a GC if */
/* an allocation in this routine asks for it. */
- set_gc_signal(&gc_signal, 1);
+ set_gc_signal(i_ctx_p, &gc_signal, 1);
if (esp < esbot) /* popped guard entry */
esp = esbot;
switch (code) {
@@ -452,10 +504,12 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
goto again;
case e_VMreclaim:
/* Do the GC and continue. */
+ idmemory->reclaim_data = i_ctx_p;
code = (*idmemory->reclaim) (idmemory,
(osp->value.intval == 2 ?
avm_global : avm_local));
-/****** What if code < 0? ******/
+ /****** What if code < 0? ******/
+ *pi_ctx_p = i_ctx_p = idmemory->reclaim_data;
make_oper(&doref, 0, zpop);
epref = &doref;
goto again;
@@ -511,7 +565,7 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
long limit = ref_stack_max_count(&e_stack) - 10;
if (count > limit)
- pop_estack(count - limit);
+ pop_estack(i_ctx_p, count - limit);
}
*++osp = saref;
break;
@@ -543,7 +597,7 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
}
if (user_errors < 0)
return code;
- if (gs_errorname(code, &error_name) < 0)
+ if (gs_errorname(i_ctx_p, code, &error_name) < 0)
return code; /* out-of-range error code! */
if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
dict_find(perrordict, &error_name, &epref) <= 0
@@ -557,20 +611,20 @@ gs_call_interp(ref * pref, int user_errors, int *pexit_code, ref * perror_object
goto again;
}
private int
-interp_exit(os_ptr op)
+interp_exit(i_ctx_t *i_ctx_p)
{
return e_InterpreterExit;
}
/* Set the GC signal for all VMs. */
private void
-set_gc_signal(int *psignal, int value)
+set_gc_signal(i_ctx_t *i_ctx_p, int *psignal, int value)
{
gs_memory_gc_status_t stat;
int i;
- for (i = 0; i < countof(idmemory->spaces.indexed); i++) {
- gs_ref_memory_t *mem = idmemory->spaces.indexed[i];
+ for (i = 0; i < countof(idmemory->spaces_indexed); i++) {
+ gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
if (mem != 0) {
gs_memory_gc_status(mem, &stat);
@@ -583,7 +637,7 @@ set_gc_signal(int *psignal, int value)
/* Copy the contents of an overflowed stack into a (local) array. */
private int
-copy_stack(const ref_stack * pstack, ref * arr)
+copy_stack(const ref_stack_t * pstack, ref * arr)
{
uint size = ref_stack_count(pstack);
uint save_space = ialloc_space(idmemory);
@@ -599,7 +653,7 @@ copy_stack(const ref_stack * pstack, ref * arr)
/* Get the name corresponding to an error number. */
int
-gs_errorname(int code, ref * perror_name)
+gs_errorname(i_ctx_t *i_ctx_p, int code, ref * perror_name)
{
ref *perrordict, *pErrorNames;
@@ -613,7 +667,7 @@ gs_errorname(int code, ref * perror_name)
/* Store an error string in $error.errorinfo. */
/* This routine is here because of the proximity to the error handler. */
int
-gs_errorinfo_put_string(const char *str)
+gs_errorinfo_put_string(i_ctx_t *i_ctx_p, const char *str)
{
ref rstr;
ref *pderror;
@@ -623,7 +677,7 @@ gs_errorinfo_put_string(const char *str)
return code;
if (dict_find_string(systemdict, "$error", &pderror) <= 0 ||
!r_has_type(pderror, t_dictionary) ||
- dict_put_string(pderror, "errorinfo", &rstr) < 0
+ idict_put_string(pderror, "errorinfo", &rstr) < 0
)
return_error(e_Fatal);
return 0;
@@ -634,19 +688,31 @@ gs_errorinfo_put_string(const char *str)
/* If an error occurs, leave the current object in *perror_object */
/* and return a (negative) error code. */
private int
-interp(ref * pref /* object to interpret */ , ref * perror_object)
-{ /*
- * Note that iref is declared as a ref *, but it may actually be
- * a ref_packed *.
- */
- register const ref *iref = pref;
+interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
+ const ref * pref /* object to interpret */,
+ ref * perror_object)
+{
+ i_ctx_t *i_ctx_p = *pi_ctx_p;
+ /*
+ * Note that iref may actually be either a ref * or a ref_packed *.
+ * Certain DEC compilers assume that a ref * is ref-aligned even if it
+ * is cast to a short *, and generate code on this assumption, leading
+ * to "unaligned access" errors. For this reason, we declare
+ * iref_packed, and use a macro to cast it to the more aligned type
+ * where necessary (which is almost everywhere it is used). This may
+ * lead to compiler warnings about "cast increases alignment
+ * requirements", but this is less harmful than expensive traps at run
+ * time.
+ */
+ register const ref_packed *iref_packed = (const ref_packed *)pref;
+#define IREF ((const ref *)iref_packed)
+#define SET_IREF(rp) (iref_packed = (const ref_packed *)(rp))
register int icount = 0; /* # of consecutive tokens at iref */
register os_ptr iosp = osp; /* private copy of osp */
register es_ptr iesp = esp; /* private copy of esp */
int code;
ref token; /* token read from file or string, */
-
- /* must be declared in this scope */
+ /* must be declared in this scope */
register const ref *pvalue;
os_ptr whichp;
@@ -691,7 +757,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
* If we exceed the VMThreshold, set ticks_left to -1
* to alert the interpreter that we need to garbage collect.
*/
- set_gc_signal(&ticks_left, -100);
+ set_gc_signal(i_ctx_p, &ticks_left, -100);
esfile_clear_cache();
/*
@@ -699,22 +765,24 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
* to the top entry on the execution stack: icount is the count
* of sequential entries remaining AFTER the current one.
*/
-#define add1_short(pref) (const ref *)((const ushort *)(pref) + 1)
-#define add1_either(pref) (r_is_packed(pref) ? add1_short(pref) : (pref) + 1)
+#define IREF_NEXT(ip)\
+ ((const ref_packed *)((const ref *)(ip) + 1))
+#define IREF_NEXT_EITHER(ip)\
+ ( r_is_packed(ip) ? (ip) + 1 : IREF_NEXT(ip) )
#define store_state(ep)\
- ( icount > 0 ? (ep->value.const_refs = iref + 1, r_set_size(ep, icount)) : 0 )
+ ( icount > 0 ? (ep->value.const_refs = IREF + 1, r_set_size(ep, icount)) : 0 )
#define store_state_short(ep)\
- ( icount > 0 ? (ep->value.const_refs = add1_short(iref), r_set_size(ep, icount)) : 0 )
+ ( icount > 0 ? (ep->value.packed = iref_packed + 1, r_set_size(ep, icount)) : 0 )
#define store_state_either(ep)\
- ( icount > 0 ? (ep->value.const_refs = add1_either(iref), r_set_size(ep, icount)) : 0 )
+ ( icount > 0 ? (ep->value.packed = IREF_NEXT_EITHER(iref_packed), r_set_size(ep, icount)) : 0 )
#define next()\
- if ( --icount > 0 ) { iref++; goto top; } else goto out
+ if ( --icount > 0 ) { iref_packed = IREF_NEXT(iref_packed); goto top; } else goto out
#define next_short()\
if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\
- iref = add1_short(iref); goto top
+ ++iref_packed; goto top
#define next_either()\
if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\
- iref = add1_either(iref); goto top
+ iref_packed = IREF_NEXT_EITHER(iref_packed); goto top
#if !PACKED_SPECIAL_OPS
# undef next_either
@@ -731,14 +799,16 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
++iesp;
ref_assign_inline(iesp, pref);
goto bot;
- top: /*
- * This is the top of the interpreter loop.
- * iref points to the ref being interpreted.
- * Note that this might be an element of a packed array,
- * not a real ref: we carefully arranged the first 16 bits of
- * a ref and of a packed array element so they could be distinguished
- * from each other. (See ghost.h and packed.h for more detail.)
- */
+ top:
+ /*
+ * This is the top of the interpreter loop.
+ * iref points to the ref being interpreted.
+ * Note that this might be an element of a packed array,
+ * not a real ref: we carefully arranged the first 16 bits of
+ * a ref and of a packed array element so they could be distinguished
+ * from each other. (See ghost.h and packed.h for more detail.)
+ */
+ INCR(top);
#ifdef DEBUG
/* Do a little validation on the top o-stack entry. */
if (iosp >= osbot &&
@@ -749,28 +819,20 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
}
if (gs_debug['I'] ||
(gs_debug['i'] &&
- (r_is_packed(iref) ?
- r_packed_is_name((const ref_packed *)iref) :
- r_has_type(iref, t_name)))
+ (r_is_packed(iref_packed) ?
+ r_packed_is_name(iref_packed) :
+ r_has_type(IREF, t_name)))
) {
void debug_print_ref(P1(const ref *));
os_ptr save_osp = osp; /* avoid side-effects */
es_ptr save_esp = esp;
- int edepth;
- char depth[10];
osp = iosp;
esp = iesp;
- edepth = ref_stack_count(&e_stack);
- sprintf(depth, "%2d", edepth);
- dputs(depth);
- for (edepth -= strlen(depth); edepth >= 5; edepth -= 5)
- dputc('*'); /* indent */
- for (; edepth > 0; --edepth)
- dputc('.');
- dlprintf3("0x%lx(%d)<%d>: ",
- (ulong) iref, icount, ref_stack_count(&o_stack));
- debug_print_ref(iref);
+ dlprintf5("d%u,e%u<%u>0x%lx(%d): ",
+ ref_stack_count(&d_stack), ref_stack_count(&e_stack),
+ ref_stack_count(&o_stack), (ulong)IREF, icount);
+ debug_print_ref(IREF);
if (iosp >= osbot) {
dputs(" // ");
debug_print_ref(iosp);
@@ -794,7 +856,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
* some compilers to use a dispatch rather than a testing loop.
* What a nuisance!
*/
- switch (r_type_xe(iref)) {
+ switch (r_type_xe(iref_packed)) {
/* Access errors. */
#define cases_invalid()\
case plain(t__invalid): case plain_exec(t__invalid)
@@ -844,21 +906,28 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
cases_lit_3():
cases_lit_4():
cases_lit_5():
+ INCR(lit);
+ break;
cases_lit_array():
+ INCR(lit_array);
break;
/* Special operators. */
case plain_exec(tx_op_add):
- x_add:if ((code = zop_add(iosp)) < 0)
+x_add: INCR(x_add);
+ if ((code = zop_add(iosp)) < 0)
return_with_error_code_op(2);
iosp--;
next_either();
case plain_exec(tx_op_def):
- x_def:if ((code = zop_def(iosp)) < 0)
+x_def: INCR(x_def);
+ osp = iosp; /* sync o_stack */
+ if ((code = zop_def(i_ctx_p)) < 0)
return_with_error_code_op(2);
iosp -= 2;
next_either();
case plain_exec(tx_op_dup):
- x_dup:if (iosp < osbot)
+x_dup: INCR(x_dup);
+ if (iosp < osbot)
return_with_error_iref(e_stackunderflow);
if (iosp >= ostop)
return_with_stackoverflow_iref();
@@ -866,14 +935,16 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
ref_assign_inline(iosp, iosp - 1);
next_either();
case plain_exec(tx_op_exch):
- x_exch:if (iosp <= osbot)
+x_exch: INCR(x_exch);
+ if (iosp <= osbot)
return_with_error_iref(e_stackunderflow);
ref_assign_inline(&token, iosp);
ref_assign_inline(iosp, iosp - 1);
ref_assign_inline(iosp - 1, &token);
next_either();
case plain_exec(tx_op_if):
- x_if:if (!r_has_type(iosp - 1, t_boolean))
+x_if: INCR(x_if);
+ if (!r_has_type(iosp - 1, t_boolean))
return_with_error_iref((iosp <= osbot ?
e_stackunderflow : e_typecheck));
if (!r_is_proc(iosp))
@@ -889,7 +960,8 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
iosp -= 2;
goto ifup;
case plain_exec(tx_op_ifelse):
- x_ifelse:if (!r_has_type(iosp - 2, t_boolean))
+x_ifelse: INCR(x_ifelse);
+ if (!r_has_type(iosp - 2, t_boolean))
return_with_error_iref((iosp < osbot + 2 ?
e_stackunderflow : e_typecheck));
if (!r_is_proc(iosp - 1))
@@ -905,35 +977,39 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
ifup:if ((icount = r_size(whichp) - 1) <= 0) {
if (icount < 0)
goto up; /* 0-element proc */
- iref = whichp->value.refs; /* 1-element proc */
+ SET_IREF(whichp->value.refs); /* 1-element proc */
if (--ticks_left > 0)
goto top;
}
++iesp;
/* Do a ref_assign, but also set iref. */
iesp->tas = whichp->tas;
- iref = iesp->value.refs = whichp->value.refs;
+ SET_IREF(iesp->value.refs = whichp->value.refs);
if (--ticks_left > 0)
goto top;
goto slice;
case plain_exec(tx_op_index):
- x_index:osp = iosp; /* zindex references o_stack */
- if ((code = zindex(iosp)) < 0)
+x_index: INCR(x_index);
+ osp = iosp; /* zindex references o_stack */
+ if ((code = zindex(i_ctx_p)) < 0)
return_with_error_code_op(1);
next_either();
case plain_exec(tx_op_pop):
- x_pop:if (iosp < osbot)
+x_pop: INCR(x_pop);
+ if (iosp < osbot)
return_with_error_iref(e_stackunderflow);
iosp--;
next_either();
case plain_exec(tx_op_roll):
- x_roll:osp = iosp; /* zroll references o_stack */
- if ((code = zroll(iosp)) < 0)
+x_roll: INCR(x_roll);
+ osp = iosp; /* zroll references o_stack */
+ if ((code = zroll(i_ctx_p)) < 0)
return_with_error_code_op(2);
iosp -= 2;
next_either();
case plain_exec(tx_op_sub):
- x_sub:if ((code = zop_sub(iosp)) < 0)
+x_sub: INCR(x_sub);
+ if ((code = zop_sub(iosp)) < 0)
return_with_error_code_op(2);
iosp--;
next_either();
@@ -942,7 +1018,8 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
goto bot;
case plain_exec(t_oparray):
/* Replace with the definition and go again. */
- pvalue = (const ref *)iref->value.const_refs;
+ INCR(exec_array);
+ pvalue = IREF->value.const_refs;
opst: /* Prepare to call a t_oparray procedure in *pvalue. */
store_state(iesp);
oppr: /* Record the stack depths in case of failure. */
@@ -961,7 +1038,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
if ((icount = r_size(pvalue) - 1) <= 0) {
if (icount < 0)
goto up; /* 0-element proc */
- iref = pvalue->value.refs; /* 1-element proc */
+ SET_IREF(pvalue->value.refs); /* 1-element proc */
if (--ticks_left > 0)
goto top;
}
@@ -970,11 +1047,12 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
++iesp;
/* Do a ref_assign, but also set iref. */
iesp->tas = pvalue->tas;
- iref = iesp->value.refs = pvalue->value.refs;
+ SET_IREF(iesp->value.refs = pvalue->value.refs);
if (--ticks_left > 0)
goto top;
goto slice;
case plain_exec(t_operator):
+ INCR(exec_operator);
if (--ticks_left <= 0) { /* The following doesn't work, */
/* and I can't figure out why. */
/****** goto sst; ******/
@@ -995,7 +1073,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
/* Note that each case must set iosp = osp: */
/* this is so we can switch on code without having to */
/* store it and reload it (for dumb compilers). */
- switch (code = call_operator(real_opproc(iref), iosp)) {
+ switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
case 0: /* normal case */
case 1: /* alternative success case */
iosp = osp;
@@ -1016,22 +1094,33 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
case o_reschedule:
store_state(iesp);
goto res;
- case e_InsertProc:
- store_state(iesp);
- oeinsert:ref_assign_inline(iesp + 1, iref);
- /* esp = iesp + 2; *esp = the procedure */
- iesp = esp;
+ case e_RemapColor:
+oe_remap: store_state(iesp);
+remap: if (iesp + 2 >= estop) {
+ esp = iesp;
+ code = ref_stack_extend(&e_stack, 2);
+ if (code < 0)
+ return_with_error_iref(code);
+ iesp = esp;
+ }
+ packed_get(iref_packed, iesp + 1);
+ make_oper(iesp + 2, 0,
+ r_ptr(&istate->remap_color_info,
+ int_remap_color_info_t)->proc);
+ iesp += 2;
goto up;
}
iosp = osp;
iesp = esp;
return_with_code_iref();
case plain_exec(t_name):
- pvalue = iref->value.pname->pvalue;
+ INCR(exec_name);
+ pvalue = IREF->value.pname->pvalue;
if (!pv_valid(pvalue)) {
- uint nidx = names_index(int_nt, iref);
+ uint nidx = names_index(int_nt, IREF);
uint htemp;
+ INCR(find_name);
if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
return_with_error_iref(e_undefined);
}
@@ -1047,6 +1136,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
cases_lit_3():
cases_lit_4():
cases_lit_5():
+ INCR(name_lit);
/* Just push the value */
if (iosp >= ostop)
return_with_stackoverflow(pvalue);
@@ -1056,6 +1146,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
case exec(t_array):
case exec(t_mixedarray):
case exec(t_shortarray):
+ INCR(name_proc);
/* This is an executable procedure, execute it. */
goto prst;
case plain_exec(tx_op_add):
@@ -1081,9 +1172,11 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
case plain_exec(t_null):
goto bot;
case plain_exec(t_oparray):
+ INCR(name_oparray);
pvalue = (const ref *)pvalue->value.const_refs;
goto opst;
case plain_exec(t_operator):
+ INCR(name_operator);
{ /* Shortcut for operators. */
/* See above for the logic. */
if (--ticks_left <= 0) { /* The following doesn't work, */
@@ -1092,7 +1185,9 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
}
esp = iesp;
osp = iosp;
- switch (code = call_operator(real_opproc(pvalue), iosp)) {
+ switch (code = call_operator(real_opproc(pvalue),
+ i_ctx_p)
+ ) {
case 0: /* normal case */
case 1: /* alternative success case */
iosp = osp;
@@ -1105,9 +1200,8 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
case o_reschedule:
store_state(iesp);
goto res;
- case e_InsertProc:
- store_state(iesp);
- goto oeinsert;
+ case e_RemapColor:
+ goto oe_remap;
}
iosp = osp;
iesp = esp;
@@ -1120,7 +1214,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
/* Not a procedure, reinterpret it. */
store_state(iesp);
icount = 0;
- iref = pvalue;
+ SET_IREF(pvalue);
goto top;
}
case exec(t_file):
@@ -1128,12 +1222,12 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
stream *s;
scanner_state sstate;
- check_read_known_file(s, iref, return_with_error_iref);
+ check_read_known_file(s, IREF, return_with_error_iref);
rt:if (iosp >= ostop) /* check early */
return_with_stackoverflow_iref();
osp = iosp; /* scan_token uses ostack */
scanner_state_init(&sstate, false);
- again:code = scan_token(s, &token, &sstate);
+ again:code = scan_token(i_ctx_p, s, &token, &sstate);
iosp = osp; /* ditto */
switch (code) {
case 0: /* read a token */
@@ -1157,8 +1251,8 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
if (iesp >= estop)
return_with_error_iref(e_execstackoverflow);
esfile_set_cache(++iesp);
- ref_assign_inline(iesp, iref);
- iref = &token;
+ ref_assign_inline(iesp, IREF);
+ SET_IREF(&token);
icount = 0;
goto top;
case scan_EOF: /* end of file */
@@ -1172,14 +1266,14 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
if (iesp >= estop)
return_with_error_iref(e_execstackoverflow);
esfile_set_cache(++iesp);
- ref_assign_inline(iesp, iref);
+ ref_assign_inline(iesp, IREF);
pvalue = &token;
goto pr;
case scan_Refill:
store_state(iesp);
/* iref may point into the exec stack; */
/* save its referent now. */
- ref_assign_inline(&token, iref);
+ ref_assign_inline(&token, IREF);
/* Push the file on the e-stack */
if (iesp >= estop)
return_with_error_iref(e_execstackoverflow);
@@ -1187,7 +1281,8 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
ref_assign_inline(iesp, &token);
esp = iesp;
osp = iosp;
- code = scan_handle_refill(&token, &sstate, true, true,
+ code = scan_handle_refill(i_ctx_p, &token, &sstate,
+ true, true,
ztokenexec_continue);
iosp = osp;
iesp = esp;
@@ -1213,9 +1308,9 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
scanner_state sstate;
scanner_state_init(&sstate, true);
- sread_string(&ss, iref->value.bytes, r_size(iref));
+ sread_string(&ss, IREF->value.bytes, r_size(IREF));
osp = iosp; /* scan_token uses ostack */
- code = scan_token(&ss, &token, &sstate);
+ code = scan_token(i_ctx_p, &ss, &token, &sstate);
iosp = osp; /* ditto */
switch (code) {
case 0: /* read a token */
@@ -1230,13 +1325,13 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
if (iesp >= estop)
return_with_error_iref(e_execstackoverflow);
++iesp;
- iesp->tas.type_attrs = iref->tas.type_attrs;
+ iesp->tas.type_attrs = IREF->tas.type_attrs;
iesp->value.const_bytes = sbufptr(&ss);
r_set_size(iesp, size);
}
}
if (code == 0) {
- iref = &token;
+ SET_IREF(&token);
icount = 0;
goto top;
}
@@ -1257,9 +1352,10 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
{
uint index;
- switch (*(const ushort *)iref >> r_packed_type_shift) {
+ switch (*iref_packed >> r_packed_type_shift) {
case pt_full_ref:
case pt_full_ref + 1:
+ INCR(p_full);
if (iosp >= ostop)
return_with_stackoverflow_iref();
/* We know this can't be an executable object */
@@ -1267,15 +1363,16 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
++iosp;
/* We know that refs are properly aligned: */
/* see packed.h for details. */
- ref_assign_inline(iosp, iref);
+ ref_assign_inline(iosp, IREF);
next();
case pt_executable_operator:
- index = *(const ushort *)iref & packed_value_mask;
+ index = *iref_packed & packed_value_mask;
if (--ticks_left <= 0) { /* The following doesn't work, */
/* and I can't figure out why. */
/****** goto sst_short; ******/
}
if (!op_index_is_operator(index)) {
+ INCR(p_exec_oparray);
store_state_short(iesp);
/* Call the operator procedure. */
index -= op_def_count;
@@ -1287,6 +1384,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
(index - r_size(&op_array_table_global.table)));
goto oppr;
}
+ INCR(p_exec_operator);
/* See the main plain_exec(t_operator) case */
/* for details of what happens here. */
#if PACKED_SPECIAL_OPS
@@ -1316,9 +1414,10 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
}
# undef case_xop
#endif
+ INCR(p_exec_non_x_operator);
esp = iesp;
osp = iosp;
- switch (code = call_operator(op_index_proc(index), iosp)) {
+ switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
case 0:
case 1:
iosp = osp;
@@ -1336,27 +1435,26 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
case o_reschedule:
store_state_short(iesp);
goto res;
- case e_InsertProc:
+ case e_RemapColor:
store_state_short(iesp);
- packed_get((const ref_packed *)iref, iesp + 1);
- /* esp = iesp + 2; *esp = the procedure */
- iesp = esp;
- goto up;
+ goto remap;
}
iosp = osp;
iesp = esp;
return_with_code_iref();
case pt_integer:
+ INCR(p_integer);
if (iosp >= ostop)
return_with_stackoverflow_iref();
++iosp;
make_int(iosp,
- (*(const short *)iref & packed_int_mask) +
+ ((int)*iref_packed & packed_int_mask) +
packed_min_intval);
next_short();
case pt_literal_name:
+ INCR(p_lit_name);
{
- uint nidx = *(const ushort *)iref & packed_value_mask;
+ uint nidx = *iref_packed & packed_value_mask;
if (iosp >= ostop)
return_with_stackoverflow_iref();
@@ -1365,20 +1463,22 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
next_short();
}
case pt_executable_name:
+ INCR(p_exec_name);
{
- uint nidx =
- (uint) * (const ushort *)iref & packed_value_mask;
+ uint nidx = *iref_packed & packed_value_mask;
pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
if (!pv_valid(pvalue)) {
uint htemp;
+ INCR(p_find_name);
if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
names_index_ref(int_nt, nidx, &token);
return_with_error(e_undefined, &token);
}
}
if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */
+ INCR(p_name_lit);
if (iosp >= ostop)
return_with_stackoverflow_iref();
++iosp;
@@ -1387,13 +1487,14 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
}
if (r_is_proc(pvalue)) { /* This is an executable procedure, */
/* execute it. */
+ INCR(p_name_proc);
store_state_short(iesp);
goto pr;
}
/* Not a literal or procedure, reinterpret it. */
store_state_short(iesp);
icount = 0;
- iref = pvalue;
+ SET_IREF(pvalue);
goto top;
}
/* default can't happen here */
@@ -1404,24 +1505,25 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
if (iosp >= ostop)
return_with_stackoverflow_iref();
++iosp;
- ref_assign_inline(iosp, iref);
+ ref_assign_inline(iosp, IREF);
bot:next();
out: /* At most 1 more token in the current procedure. */
/* (We already decremented icount.) */
- if (!icount) { /* Pop the execution stack for tail recursion. */
+ if (!icount) {
+ /* Pop the execution stack for tail recursion. */
iesp--;
- iref++;
+ iref_packed = IREF_NEXT(iref_packed);
goto top;
}
up:if (--ticks_left < 0)
goto slice;
/* See if there is anything left on the execution stack. */
if (!r_is_proc(iesp)) {
- iref = iesp--;
+ SET_IREF(iesp--);
icount = 0;
goto top;
}
- iref = iesp->value.refs; /* next element of array */
+ SET_IREF(iesp->value.refs); /* next element of array */
icount = r_size(iesp) - 1;
if (icount <= 0) { /* <= 1 more elements */
iesp--; /* pop, or tail recursion */
@@ -1429,9 +1531,12 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
goto up;
}
goto top;
- res: /* Some operator has asked for context rescheduling. */
+res:
+ /* Some operator has asked for context rescheduling. */
/* We've done a store_state. */
- code = (*gs_interp_reschedule_proc) ();
+ *pi_ctx_p = i_ctx_p;
+ code = (*gs_interp_reschedule_proc)(pi_ctx_p);
+ i_ctx_p = *pi_ctx_p;
sched: /* We've just called a scheduling procedure. */
/* The interpreter state is in memory; iref is not current. */
if (code < 0) {
@@ -1442,7 +1547,7 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
* *perror_object.)
*/
make_null_proc(&ierror.full);
- ierror.obj = iref = &ierror.full;
+ SET_IREF(ierror.obj = &ierror.full);
goto error_exit;
}
/* Reload state information from memory. */
@@ -1463,9 +1568,14 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
esp = iesp;
/* If ticks_left <= -100, we need to GC now. */
if (ticks_left <= -100) { /* We need to garbage collect now. */
+ idmemory->reclaim_data = i_ctx_p;
code = (*idmemory->reclaim) (idmemory, -1);
- } else
- code = (*gs_interp_time_slice_proc) ();
+ *pi_ctx_p = i_ctx_p = idmemory->reclaim_data;
+ } else {
+ *pi_ctx_p = i_ctx_p;
+ code = (*gs_interp_time_slice_proc)(pi_ctx_p);
+ i_ctx_p = *pi_ctx_p;
+ }
ticks_left = gs_interp_time_slice_ticks;
goto sched;
@@ -1474,19 +1584,19 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
rweci:
ierror.code = code;
rwei:
- ierror.obj = iref;
+ ierror.obj = IREF;
rwe:
- if (!r_is_packed(iref))
+ if (!r_is_packed(iref_packed))
store_state(iesp);
- else { /*
- * We need a real object to return as the error object.
- * (It only has to last long enough to store in
- * *perror_object.)
- */
+ else {
+ /*
+ * We need a real object to return as the error object.
+ * (It only has to last long enough to store in *perror_object.)
+ */
packed_get((const ref_packed *)ierror.obj, &ierror.full);
store_state_short(iesp);
- if (iref == ierror.obj)
- iref = &ierror.full;
+ if (IREF == ierror.obj)
+ SET_IREF(&ierror.full);
ierror.obj = &ierror.full;
}
error_exit:
@@ -1499,19 +1609,18 @@ interp(ref * pref /* object to interpret */ , ref * perror_object)
code = e_execstackoverflow;
else {
iesp++;
- ref_assign_inline(iesp, iref);
+ ref_assign_inline(iesp, IREF);
}
}
esp = iesp;
osp = iosp;
ref_assign_inline(perror_object, ierror.obj);
return gs_log_error(ierror.code, __FILE__, ierror.line);
-
}
/* Pop the bookkeeping information for a normal exit from a t_oparray. */
private int
-oparray_pop(os_ptr op)
+oparray_pop(i_ctx_t *i_ctx_p)
{
esp -= 3;
return o_pop_estack;
@@ -1520,7 +1629,7 @@ oparray_pop(os_ptr op)
/* Restore the stack pointers after an error inside a t_oparray procedure. */
/* This procedure is called only from pop_estack. */
private int
-oparray_cleanup(os_ptr op)
+oparray_cleanup(i_ctx_t *i_ctx_p)
{ /* esp points just below the cleanup procedure. */
es_ptr ep = esp;
uint ocount_old = (uint) ep[2].value.intval;
@@ -1536,13 +1645,3 @@ oparray_cleanup(os_ptr op)
}
return 0;
}
-
-/* ------ Initialization procedure ------ */
-
-const op_def interp_op_defs[] =
-{
- /* Internal operators */
- {"0%interp_exit", interp_exit},
- {"0%oparray_pop", oparray_pop},
- op_def_end(0)
-};
diff --git a/gs/src/interp.h b/gs/src/interp.h
index fcfffe4f6..03bc94ffb 100644
--- a/gs/src/interp.h
+++ b/gs/src/interp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,10 +25,14 @@
/* ------ iinit.c ------ */
/* Enter a name and value into systemdict. */
-void initial_enter_name(P2(const char *, const ref *));
+void i_initial_enter_name(P3(i_ctx_t *, const char *, const ref *));
+#define initial_enter_name(nstr, pvalue)\
+ i_initial_enter_name(i_ctx_p, nstr, pvalue)
/* Remove a name from systemdict. */
-void initial_remove_name(P1(const char *));
+void i_initial_remove_name(P2(i_ctx_t *, const char *));
+#define initial_remove_name(nstr)\
+ i_initial_remove_name(i_ctx_p, nstr)
/* ------ interp.c ------ */
@@ -49,26 +53,22 @@ extern const int gs_interp_num_special_ops;
* If operator is hard-coded into the interpreter,
* assign it a special type and index.
*/
-void gs_interp_make_oper(P3(ref * opref, op_proc_p, int index));
+void gs_interp_make_oper(P3(ref * opref, op_proc_t, int index));
/* Get the name corresponding to an error number. */
-int gs_errorname(P2(int, ref *));
+int gs_errorname(P3(i_ctx_t *, int, ref *));
/* Put a string in $error /errorinfo. */
-int gs_errorinfo_put_string(P1(const char *));
+int gs_errorinfo_put_string(P2(i_ctx_t *, const char *));
/* Initialize the interpreter. */
-void gs_interp_init(P0());
+int gs_interp_init(P2(i_ctx_t **pi_ctx_p, const ref *psystem_dict));
#ifndef gs_context_state_t_DEFINED
# define gs_context_state_t_DEFINED
typedef struct gs_context_state_s gs_context_state_t;
-
#endif
-/* Define a pointer to the current interpreter context state. */
-extern gs_context_state_t *gs_interp_context_state_current;
-
/*
* Create initial stacks for the interpreter.
* We export this for creating new contexts.
@@ -84,6 +84,6 @@ void gs_interp_free_stacks(P2(gs_ref_memory_t * smem,
gs_context_state_t * pcst));
/* Reset the interpreter. */
-void gs_interp_reset(P0());
+void gs_interp_reset(P1(i_ctx_t *i_ctx_p));
#endif /* interp_INCLUDED */
diff --git a/gs/src/iosdata.h b/gs/src/iosdata.h
new file mode 100644
index 000000000..1b944626b
--- /dev/null
+++ b/gs/src/iosdata.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Generic operand stack API */
+
+#ifndef iosdata_INCLUDED
+# define iosdata_INCLUDED
+
+#include "isdata.h"
+
+/* Define the operand stack structure. */
+/* Currently this is just a generic ref stack. */
+typedef struct op_stack_s {
+
+ ref_stack_t stack; /* the actual operand stack */
+
+} op_stack_t;
+
+#define public_st_op_stack() /* in interp.c */\
+ gs_public_st_suffix_add0(st_op_stack, op_stack_t, "op_stack_t",\
+ op_stack_enum_ptrs, op_stack_reloc_ptrs, st_ref_stack)
+#define st_op_stack_num_ptrs st_ref_stack_num_ptrs
+
+#endif /* iosdata_INCLUDED */
diff --git a/gs/src/iostack.h b/gs/src/iostack.h
index 4b27eb2d2..6924b3dff 100644
--- a/gs/src/iostack.h
+++ b/gs/src/iostack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,18 +22,11 @@
#ifndef iostack_INCLUDED
# define iostack_INCLUDED
+#include "iosdata.h"
#include "istack.h"
/* Define pointers into the operand stack. */
typedef s_ptr os_ptr;
typedef const_s_ptr const_os_ptr;
-/* Define the operand stack structure. */
-/* Currently this is just a generic ref stack. */
-typedef struct op_stack_s {
-
- ref_stack stack; /* the actual operand stack */
-
-} op_stack_t;
-
#endif /* iostack_INCLUDED */
diff --git a/gs/src/ipacked.h b/gs/src/ipacked.h
index 39587eb42..416cc2baa 100644
--- a/gs/src/ipacked.h
+++ b/gs/src/ipacked.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -127,4 +127,10 @@ typedef enum {
#define packed_next(prp)\
(r_is_packed(prp) ? prp + 1 : prp + packed_per_ref)
+/* Define the current array packing flag (setpacking/currentpacking) */
+/* for operators. */
+/* This is a ref so that it can be managed properly by save/restore. */
+#define ref_array_packing_container i_ctx_p
+#define ref_array_packing (ref_array_packing_container->array_packing)
+
#endif /* ipacked_INCLUDED */
diff --git a/gs/src/iparam.c b/gs/src/iparam.c
index 2cd23498b..24f11aa17 100644
--- a/gs/src/iparam.c
+++ b/gs/src/iparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -349,7 +349,7 @@ private int
stack_param_write(iparam_list * plist, const ref * pkey, const ref * pvalue)
{
stack_param_list *const splist = (stack_param_list *) plist;
- ref_stack *pstack = splist->pstack;
+ ref_stack_t *pstack = splist->pstack;
s_ptr p = pstack->p;
if (pstack->top - p < 2) {
@@ -391,7 +391,7 @@ stack_param_enumerate(iparam_list * plist, gs_param_enumerator_t * penum,
}
int
-stack_param_list_write(stack_param_list * plist, ref_stack * pstack,
+stack_param_list_write(stack_param_list * plist, ref_stack_t * pstack,
const ref * pwanted)
{
plist->u.w.write = stack_param_write;
@@ -407,7 +407,8 @@ stack_param_list_write(stack_param_list * plist, ref_stack * pstack,
private int
dict_param_write(iparam_list * plist, const ref * pkey, const ref * pvalue)
{
- int code = dict_put(&((dict_param_list *) plist)->dict, pkey, pvalue);
+ int code =
+ dict_put(&((dict_param_list *) plist)->dict, pkey, pvalue, NULL);
return min(code, 0);
}
@@ -597,7 +598,7 @@ ref_param_read_string_array(gs_param_list * plist, gs_param_name pkey,
{
iparam_list *const iplist = (iparam_list *) plist;
iparam_loc loc;
- ref aref, elt;
+ ref aref;
int code = ref_param_read_array(iplist, pkey, &loc);
gs_param_string *psv;
uint size;
@@ -612,10 +613,19 @@ ref_param_read_string_array(gs_param_list * plist, gs_param_name pkey,
if (psv == 0)
return_error(e_VMerror);
aref = *loc.pvalue;
- loc.pvalue = &elt;
- for (i = 0; code >= 0 && i < size; i++) {
- array_get(&aref, i, &elt);
- code = ref_param_read_string_value(&loc, psv + i);
+ if (r_has_type(&aref, t_array)) {
+ for (i = 0; code >= 0 && i < size; i++) {
+ loc.pvalue = aref.value.refs + i;
+ code = ref_param_read_string_value(&loc, psv + i);
+ }
+ } else {
+ ref elt;
+
+ loc.pvalue = &elt;
+ for (i = 0; code >= 0 && i < size; i++) {
+ array_get(&aref, i, &elt);
+ code = ref_param_read_string_value(&loc, psv + i);
+ }
}
if (code < 0) {
ifree_object(psv, "ref_param_read_string_array");
@@ -823,19 +833,22 @@ private int
ref_param_read_string_value(const iparam_loc * ploc, gs_param_string * pvalue)
{
const ref *pref = ploc->pvalue;
- ref nref;
switch (r_type(pref)) {
- case t_name:
+ case t_name: {
+ ref nref;
+
name_string_ref(pref, &nref);
- pref = &nref;
+ pvalue->data = nref.value.const_bytes;
+ pvalue->size = r_size(&nref);
pvalue->persistent = true;
- goto s;
+ }
+ break;
case t_string:
iparam_check_read(*ploc);
- pvalue->persistent = false;
- s:pvalue->data = pref->value.const_bytes;
+ pvalue->data = pref->value.const_bytes;
pvalue->size = r_size(pref);
+ pvalue->persistent = false;
break;
default:
return iparam_note_error(*ploc, e_typecheck);
@@ -1002,7 +1015,7 @@ private int
stack_param_read(iparam_list * plist, const ref * pkey, iparam_loc * ploc)
{
stack_param_list *const splist = (stack_param_list *) plist;
- ref_stack *pstack = splist->pstack;
+ ref_stack_t *pstack = splist->pstack;
/* This implementation is slow, but it probably doesn't matter. */
uint index = splist->skip + 1;
@@ -1021,8 +1034,8 @@ stack_param_read(iparam_list * plist, const ref * pkey, iparam_loc * ploc)
return 1;
}
int
-stack_param_list_read(stack_param_list * plist, ref_stack * pstack, uint skip,
- const ref * ppolicies, bool require_all)
+stack_param_list_read(stack_param_list * plist, ref_stack_t * pstack,
+ uint skip, const ref * ppolicies, bool require_all)
{
iparam_list *const iplist = (iparam_list *) plist;
uint count = ref_stack_counttomark(pstack);
diff --git a/gs/src/iparam.h b/gs/src/iparam.h
index b7d1c2aba..60ba3dfe0 100644
--- a/gs/src/iparam.h
+++ b/gs/src/iparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -78,7 +78,7 @@ typedef struct array_param_list_s {
/* For stack lists, the bottom of the list is just above a mark. */
typedef struct stack_param_list_s {
iparam_list_common;
- ref_stack *pstack;
+ ref_stack_t *pstack;
uint skip; /* # of top items to skip (reading only) */
} stack_param_list;
@@ -101,9 +101,9 @@ int array_indexed_param_list_write(P3(dict_param_list *, ref * /*t_*array */ ,
const ref *));
int array_param_list_read(P5(array_param_list *, ref *, uint,
const ref *, bool));
-int stack_param_list_read(P5(stack_param_list *, ref_stack *, uint,
+int stack_param_list_read(P5(stack_param_list *, ref_stack_t *, uint,
const ref *, bool));
-int stack_param_list_write(P3(stack_param_list *, ref_stack *,
+int stack_param_list_write(P3(stack_param_list *, ref_stack_t *,
const ref *));
#define iparam_list_release(plist)\
diff --git a/gs/src/iparray.h b/gs/src/iparray.h
index 8f114ff60..44cb57df2 100644
--- a/gs/src/iparray.h
+++ b/gs/src/iparray.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,6 +31,6 @@
/* Procedures implemented in zpacked.c */
/* Make a packed array from the top N elements of a stack. */
-int make_packed_array(P4(ref *, ref_stack *, uint, client_name_t));
+int make_packed_array(P4(ref *, ref_stack_t *, uint, client_name_t));
#endif /* iparray_INCLUDED */
diff --git a/gs/src/ipcolor.h b/gs/src/ipcolor.h
new file mode 100644
index 000000000..0a21b4eda
--- /dev/null
+++ b/gs/src/ipcolor.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interpreter definitions for Pattern color */
+
+#ifndef ipcolor_INCLUDED
+# define ipcolor_INCLUDED
+
+/*
+ * Define the structure for remembering the pattern dictionary.
+ * This is the "client data" in the template.
+ * See zgstate.c (int_gstate) or zfont2.c (font_data) for information
+ * as to why we define this as a structure rather than a ref array.
+ */
+typedef struct int_pattern_s {
+ ref dict;
+} int_pattern;
+
+#define private_st_int_pattern() /* in zpcolor.c */\
+ gs_private_st_ref_struct(st_int_pattern, int_pattern, "int_pattern")
+
+/* Create an interpreter pattern structure. */
+int int_pattern_alloc(P2(int_pattern **ppdata, const ref *op));
+
+#endif /* ipcolor_INCLUDED */
diff --git a/gs/src/ireclaim.c b/gs/src/ireclaim.c
index b12fa3f3c..b20b5ec47 100644
--- a/gs/src/ireclaim.c
+++ b/gs/src/ireclaim.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,10 +40,11 @@ private void gs_vmreclaim(P2(gs_dual_memory_t *, bool));
/* Initialize the GC hook in the allocator. */
private int ireclaim(P2(gs_dual_memory_t *, int));
-private void
-ireclaim_init(void)
+private int
+ireclaim_init(i_ctx_t *i_ctx_p)
{
gs_imemory.reclaim = ireclaim;
+ return 0;
}
/* GC hook called when the allocator returns a VMerror (space = -1), */
@@ -59,8 +60,8 @@ ireclaim(gs_dual_memory_t * dmem, int space)
int i;
mem = dmem->space_global; /* just in case */
- for (i = 0; i < countof(dmem->spaces.indexed); ++i) {
- mem = dmem->spaces.indexed[i];
+ for (i = 0; i < countof(dmem->spaces_indexed); ++i) {
+ mem = dmem->spaces_indexed[i];
if (mem == 0)
continue;
if (mem->gc_status.requested > 0)
@@ -71,7 +72,7 @@ ireclaim(gs_dual_memory_t * dmem, int space)
return_error(e_VMerror);
}
} else {
- mem = dmem->spaces.indexed[space >> r_space_shift];
+ mem = dmem->spaces_indexed[space >> r_space_shift];
}
if_debug3('0', "[0]GC called, space=%d, requestor=%d, requested=%ld\n",
space, mem->space, (long)mem->gc_status.requested);
@@ -87,10 +88,11 @@ ireclaim(gs_dual_memory_t * dmem, int space)
private void
gs_vmreclaim(gs_dual_memory_t * dmem, bool global)
{
+ i_ctx_t *i_ctx_p = dmem->reclaim_data;
gs_ref_memory_t *lmem = dmem->space_local;
gs_ref_memory_t *gmem = dmem->space_global;
gs_ref_memory_t *smem = dmem->space_system;
- int code = context_state_store(gs_interp_context_state_current);
+ int code = context_state_store(i_ctx_p);
/****** ABORT IF code < 0 ******/
alloc_close_chunk(lmem);
@@ -105,12 +107,12 @@ gs_vmreclaim(gs_dual_memory_t * dmem, bool global)
int i;
for (i = (global ? i_vm_system : i_vm_local);
- i < countof(dmem->spaces.indexed);
+ i < countof(dmem->spaces_indexed);
++i
) {
- gs_ref_memory_t *mem = dmem->spaces.indexed[i];
+ gs_ref_memory_t *mem = dmem->spaces_indexed[i];
- if (mem == 0 || (i > 0 && mem == dmem->spaces.indexed[i - 1]))
+ if (mem == 0 || (i > 0 && mem == dmem->spaces_indexed[i - 1]))
continue;
for (;; mem = &mem->saved->state) {
ialloc_gc_prepare(mem);
@@ -122,12 +124,29 @@ gs_vmreclaim(gs_dual_memory_t * dmem, bool global)
/* Do the actual collection. */
- gs_reclaim(&dmem->spaces, global);
+ {
+ gs_gc_root_t context_root;
+
+ gs_register_struct_root((gs_memory_t *)lmem, &context_root,
+ (void **)&dmem->reclaim_data, "reclaim_data");
+ GS_RECLAIM(&dmem->spaces, global);
+ gs_unregister_root((gs_memory_t *)lmem, &context_root, "reclaim_data");
+ }
+ i_ctx_p = dmem->reclaim_data;
+
+ /* Update caches not handled by context_state_load. */
+
+ *systemdict = *ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 1);
/* Reload the context state. */
- code = context_state_load(gs_interp_context_state_current);
-/****** ABORT IF code < 0 ******/
+ code = context_state_load(i_ctx_p);
+ /****** ABORT IF code < 0 ******/
+ /*
+ * context_state_load overwrites gs_memory (*dmem): put back the
+ * relocated context pointer.
+ */
+ dmem->reclaim_data = i_ctx_p;
/* Update the cached value pointers in names. */
@@ -139,14 +158,6 @@ gs_vmreclaim(gs_dual_memory_t * dmem, bool global)
if (gmem != lmem)
alloc_open_chunk(gmem);
alloc_open_chunk(lmem);
-
- /* Update caches not handled by context_state_load. */
-
- {
- uint dcount = ref_stack_count(&d_stack);
-
- *systemdict = *ref_stack_index(&d_stack, dcount - 1);
- }
}
/* ------ Initialization procedure ------ */
diff --git a/gs/src/iref.h b/gs/src/iref.h
index 928a4ecca..a6958cc02 100644
--- a/gs/src/iref.h
+++ b/gs/src/iref.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -123,19 +123,18 @@ typedef enum {
t_string, /* @!+# value.bytes */
/*
* The following are extensions to the PostScript type set.
- * When adding new types, be sure to edit:
- * - type_name_strings, type_print_strings, and type_properties below;
+ * If you add new types, be sure to edit:
+ * - REF_TYPE_*STRINGS* and REF_TYPE_PROPERTIES_DATA below;
* - the table in gs_init.ps (==only operator);
* - the printing routine in idebug.c;
* - the dispatches in igc.c, igcref.c, and interp.c;
- * - obj_eq in iutil.c;
+ * - obj_cvs, obj_cvp, and obj_eq in iutil.c;
* - restore_check_stack in zvmem.c.
*/
t_device, /* @ + value.pdevice */
t_oparray, /* @! # value.const_refs, uses size */
- /* for index */
- t_next_index
-/*** first available index ***/
+ /* for index */
+ t_next_index /*** first available index ***/
} ref_type;
/*
@@ -145,7 +144,7 @@ typedef enum {
* there is no need for any operators to check specifically for these
* types. The r_btype macro takes care of the conversion when required.
*/
- /*extern const int tx_next_index; *//* in interp.c */
+/*extern const int tx_next_index; *//* in interp.c */
/*
* Define a table giving properties of types, similar to the table used
* by the isxxx functions (macros) in <ctype.h>.
@@ -156,7 +155,7 @@ typedef enum {
#define _rtype_is_dictionary 8
extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
-#define ref_type_properties_data\
+#define REF_TYPE_PROPERTIES_DATA\
0, /* t__invalid */\
0, /* t_boolean */\
_rtype_uses_access | _rtype_is_dictionary, /* t_dictionary */\
@@ -205,7 +204,7 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
* Define the type names for debugging printout.
* All names must be the same length, so that columns will line up.
*/
-#define type_print_strings\
+#define REF_TYPE_DEBUG_PRINT_STRINGS\
"INVL","bool","dict","file",\
"arry","mpry","spry","u?ry",\
"STRC","ASTR",\
@@ -215,13 +214,24 @@ extern const byte ref_type_properties[1 << 6]; /* r_type_bits */
/*
* Define the type names for the type operator.
*/
-#define type_name_strings\
+#define REF_TYPE_NAME_STRINGS\
0,"booleantype","dicttype","filetype",\
"arraytype","packedarraytype","packedarraytype","arraytype",\
0,0,\
"fonttype","integertype","marktype","nametype","nulltype",\
"operatortype","realtype","savetype","stringtype",\
"devicetype","operatortype"
+/*
+ * Define the type names for obj_cvp (the == operator). We only need these
+ * for types that obj_cvp and obj_cvs don't handle specially.
+ */
+#define REF_TYPE_PRINT_STRINGS\
+ 0,0,"-dict-","-file-",\
+ "-array-","-packedarray-","-packedarray-","-array-",\
+ 0,0,\
+ "-fontID-",0,"-mark-",0,0,\
+ 0,0,"-save-","-string-",\
+ "-device-",0
/*
* The following factors affect the encoding of attributes:
@@ -288,23 +298,26 @@ typedef struct name_s name;
#ifndef stream_DEFINED
# define stream_DEFINED
typedef struct stream_s stream;
-
#endif
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
-
#endif
#ifndef obj_header_DEFINED
# define obj_header_DEFINED
typedef struct obj_header_s obj_header_t;
-
#endif
-/* We duplicate the definition of os_ptr (a.k.a. s_ptr) here */
-/* so that we can have an accurate typedef for op_proc */
-/* without having to drag in istack.h and ostack.h. */
-typedef int (*op_proc_p) (P1(ref *));
+/*
+ * Define the argument type for operator procedures. Note that the
+ * argument name is not arbitrary: it is used in access macros, so all
+ * operator procedures must use it.
+ */
+#ifndef i_ctx_t_DEFINED
+# define i_ctx_t_DEFINED
+typedef struct gs_context_state_s i_ctx_t;
+#endif
+typedef int (*op_proc_t)(P1(i_ctx_t *i_ctx_p));
/* real_opproc is a holdover.... */
#define real_opproc(pref) ((pref)->value.opproc)
@@ -401,8 +414,14 @@ struct ref_s {
const name *const_pname;
dict *pdict;
const dict *const_pdict;
+ /*
+ * packed is the normal variant for referring to packed arrays,
+ * but we need a writable variant for memory management and for
+ * storing into packed dictionary key arrays.
+ */
const ref_packed *packed;
- op_proc_p opproc;
+ ref_packed *writable_packed;
+ op_proc_t opproc;
struct stream_s *pfile;
struct gx_device_s *pdevice;
obj_header_t *pstruct;
diff --git a/gs/src/isave.c b/gs/src/isave.c
index b62ada152..686e5ac42 100644
--- a/gs/src/isave.c
+++ b/gs/src/isave.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -44,11 +44,6 @@ private_st_alloc_save();
/* see below for details. */
private const long max_repeated_scan = 100000;
-/* Some compilers try to substitute macro args in string literals! */
-#define print_save(str, spacen, sav)\
- if_debug5('u', "[u]%s space %u 0x%lx: cdata = 0x%lx, id = %lu\n",\
- str, spacen, (ulong)(sav), (ulong)(sav)->client_data, (ulong)(sav)->id);
-
/*
* The logic for saving and restoring the state is complex.
* Both the changes to individual objects, and the overall state
@@ -121,14 +116,14 @@ private const long max_repeated_scan = 100000;
*/
/*
- * A consequence of the foregoing algorithms is that the cost of a save
- * is proportional to the total amount of data allocated since the previous
- * save. If a PostScript program reads in a large amount of setup code
- * and then uses save/restore heavily, each save/restore will be expensive.
- * To mitigate this, we check to see how much data we are scanning at a save;
- * if it is large, we do a second, invisible save. This greatly reduces
- * the cost of inner saves, at the expense of possibly saving some changes
- * twice that otherwise would only have to be saved once.
+ * A consequence of the foregoing algorithms is that the cost of a save is
+ * proportional to the total amount of data allocated since the previous
+ * save. If a PostScript program reads in a large amount of setup code and
+ * then uses save/restore heavily, each save/restore will be expensive. To
+ * mitigate this, we check to see how much data we have scanned at this save
+ * level: if it is large, we do a second, invisible save. This greatly
+ * reduces the cost of inner saves, at the expense of possibly saving some
+ * changes twice that otherwise would only have to be saved once.
*/
/*
@@ -153,6 +148,14 @@ private const long max_repeated_scan = 100000;
* not by the current allocation mode.
*/
+/* Tracing printout */
+private void
+print_save(const char *str, uint spacen, const alloc_save_t *sav)
+{
+ if_debug5('u', "[u]%s space %u 0x%lx: cdata = 0x%lx, id = %lu\n",\
+ str, spacen, (ulong)sav, (ulong)sav->client_data, (ulong)sav->id);
+}
+
/*
* Structure for saved change chain for save/restore. Because of the
* garbage collector, we need to distinguish the cases where the change
@@ -168,28 +171,28 @@ struct alloc_change_s {
short offset; /* if >= 0, offset within struct */
};
-#define ptr ((alloc_change_t *)vptr)
private
CLEAR_MARKS_PROC(change_clear_marks)
{
+ alloc_change_t *const ptr = (alloc_change_t *)vptr;
+
if (r_is_packed(&ptr->contents))
r_clear_pmark((ref_packed *) & ptr->contents);
else
r_clear_attrs(&ptr->contents, l_mark);
}
private
-ENUM_PTRS_BEGIN(change_enum_ptrs) return 0;
-
+ENUM_PTRS_WITH(change_enum_ptrs, alloc_change_t *ptr) return 0;
ENUM_PTR(0, alloc_change_t, next);
case 1:
-if (ptr->offset >= 0)
- ENUM_RETURN((byte *) ptr->where - ptr->offset);
-else
- ENUM_RETURN_REF(ptr->where);
+ if (ptr->offset >= 0)
+ ENUM_RETURN((byte *) ptr->where - ptr->offset);
+ else
+ ENUM_RETURN_REF(ptr->where);
case 2:
-ENUM_RETURN_REF(&ptr->contents);
+ ENUM_RETURN_REF(&ptr->contents);
ENUM_PTRS_END
-private RELOC_PTRS_BEGIN(change_reloc_ptrs)
+private RELOC_PTRS_WITH(change_reloc_ptrs, alloc_change_t *ptr)
{
RELOC_VAR(ptr->next);
switch (ptr->offset) {
@@ -215,7 +218,6 @@ private RELOC_PTRS_BEGIN(change_reloc_ptrs)
}
}
RELOC_PTRS_END
-#undef ptr
gs_private_st_complex_only(st_alloc_change, alloc_change_t, "alloc_change",
change_clear_marks, change_enum_ptrs, change_reloc_ptrs, 0);
@@ -279,24 +281,26 @@ alloc_set_not_in_save(gs_dual_memory_t *dmem)
/* Save the state. */
private alloc_save_t *alloc_save_space(P2(gs_ref_memory_t *,
gs_dual_memory_t *));
+private void
+alloc_free_save(gs_ref_memory_t *mem, alloc_save_t *save, const char *scn,
+ const char *icn)
+{
+ chunk_t *inner = mem->pcc;
+ gs_free_object((gs_memory_t *)mem, save, scn);
+ gs_free_object(mem->parent, inner, icn);
+}
ulong
alloc_save_state(gs_dual_memory_t * dmem, void *cdata)
{
gs_ref_memory_t *lmem = dmem->space_local;
gs_ref_memory_t *gmem = dmem->space_global;
ulong sid = gs_next_ids(2);
-
-#define alloc_free_save(mem, s, scn, icn)\
- { chunk_t *inner = (mem)->pcc;\
- gs_free_object((gs_memory_t *)(mem), s, scn);\
- gs_free_object((mem)->parent, inner, icn);\
- }
bool global =
- dmem->save_level == 0 && gmem != lmem &&
- gmem->num_contexts == 1;
+ dmem->save_level == 0 && gmem != lmem &&
+ gmem->num_contexts == 1;
alloc_save_t *gsave =
- (global ? alloc_save_space(gmem, dmem) : (alloc_save_t *) 0);
+ (global ? alloc_save_space(gmem, dmem) : (alloc_save_t *) 0);
alloc_save_t *lsave = alloc_save_space(lmem, dmem);
if (lsave == 0 || (global &&gsave == 0)) {
@@ -308,7 +312,6 @@ alloc_save_state(gs_dual_memory_t * dmem, void *cdata)
"alloc_save_state(global inner)");
return 0;
}
-#undef alloc_free_save
if (gsave != 0) {
gsave->id = sid + 1;
gsave->client_data = 0;
@@ -326,7 +329,8 @@ alloc_save_state(gs_dual_memory_t * dmem, void *cdata)
if (dmem->save_level != 0) {
long scanned = save_set_new(&lsave->state, false);
- if (scanned > max_repeated_scan) { /* Do a second, invisible save. */
+ if ((lsave->state.total_scanned += scanned) > max_repeated_scan) {
+ /* Do a second, invisible save. */
alloc_save_t *rsave;
rsave = alloc_save_space(lmem, dmem);
@@ -339,8 +343,7 @@ alloc_save_state(gs_dual_memory_t * dmem, void *cdata)
/* Inherit the allocated space count -- */
/* we need this for triggering a GC. */
rsave->state.inherited =
- lsave->state.allocated +
- lsave->state.inherited;
+ lsave->state.allocated + lsave->state.inherited;
lmem->inherited = rsave->state.inherited;
print_save("save", lmem->space, lsave);
}
@@ -407,6 +410,7 @@ alloc_save_space(gs_ref_memory_t * mem, gs_dual_memory_t * dmem)
if_debug2('u', "[u%u]file_save 0x%lx\n",
mem->space, (ulong) mem->streams);
mem->streams = 0;
+ mem->total_scanned = 0;
return save;
}
@@ -422,7 +426,7 @@ alloc_save_change(gs_dual_memory_t * dmem, const ref * pcont,
if (dmem->save_level == 0)
return 0; /* no saving */
mem = (pcont == NULL ? dmem->space_local :
- dmem->spaces.indexed[r_space(pcont) >> r_space_shift]);
+ dmem->spaces_indexed[r_space(pcont) >> r_space_shift]);
cp = gs_alloc_struct((gs_memory_t *) mem, alloc_change_t,
&st_alloc_change, "alloc_save_change");
if (cp == 0)
@@ -449,7 +453,7 @@ alloc_save_change(gs_dual_memory_t * dmem, const ref * pcont,
mem->changes = cp;
#ifdef DEBUG
if (gs_debug_c('U')) {
- dlprintf1("[u]save(%s)", client_name_string(cname));
+ dlprintf1("[U]save(%s)", client_name_string(cname));
alloc_save_print(cp, false);
}
#endif
@@ -1050,8 +1054,8 @@ save_set_new_changes(gs_ref_memory_t * mem, bool to_new)
for (; chp; chp = chp->next) {
ref_packed *prp = chp->where;
- if_debug2('U', "[U]set_new(0x%lx, %d)\n",
- (ulong) prp, new);
+ if_debug3('U', "[U]set_new 0x%lx: (0x%lx, %d)\n",
+ (ulong)chp, (ulong)prp, new);
if (!r_is_packed(prp)) {
ref *const rp = (ref *) prp;
diff --git a/gs/src/iscan.c b/gs/src/iscan.c
index 85a533d92..478b4f14f 100644
--- a/gs/src/iscan.c
+++ b/gs/src/iscan.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#include "memory_.h"
#include "stream.h"
#include "errors.h"
+#include "btoken.h" /* for ref_binary_object_format */
#include "files.h" /* for fptr */
#include "ialloc.h"
#include "idict.h" /* for //name lookup */
@@ -31,6 +32,7 @@
#include "ipacked.h"
#include "iparray.h"
#include "strimpl.h" /* for string decoding */
+#include "sa85d.h" /* ditto */
#include "sfilter.h" /* ditto */
#include "ostack.h" /* for accumulating proc bodies; */
/* must precede iscan.h */
@@ -43,24 +45,15 @@
#include "store.h"
#include "scanchar.h"
-/* Array packing flag */
-ref ref_array_packing; /* t_boolean */
-
-/* Binary object format flag. This will never be set non-zero */
-/* unless the binary token feature is enabled. */
-ref ref_binary_object_format; /* t_integer */
-
#define recognize_btokens()\
(ref_binary_object_format.value.intval != 0 && level2_enabled)
-/* Procedure for binary tokens. Set at initialization if Level 2 */
-/* features are included; only called if recognize_btokens() is true. */
-/* Returns 0 or scan_BOS on success, <0 on failure. */
-int (*scan_btoken_proc) (P3(stream *, ref *, scanner_state *)) = NULL;
-
-/* Stream template for scanning ASCII85 literals. */
-/* Set at initialization if Level 2 features are included. */
-const stream_template *scan_ascii85_template = NULL;
+/*
+ * Procedure for binary tokens. Only called if recognize_btokens() is true;
+ * returns e_unregistered if Level 2 features are not included. Returns 0
+ * or scan_BOS on success, <0 on failure.
+ */
+int scan_binary_token(P4(i_ctx_t *, stream *, ref *, scanner_state *));
#ifdef DEBUG
/* Dummy comment processing procedure for testing. */
@@ -235,8 +228,8 @@ public_st_scanner_state();
/* This may return o_push_estack, 0 (meaning just call scan_token again), */
/* or an error code. */
int
-scan_handle_refill(const ref * fop, scanner_state * sstate, bool save,
- bool push_file, int (*cont) (P1(os_ptr)))
+scan_handle_refill(i_ctx_t *i_ctx_p, const ref * fop, scanner_state * sstate,
+ bool save, bool push_file, op_proc_t cont)
{
stream *s = fptr(fop);
uint avail = sbufavailable(s);
@@ -282,7 +275,7 @@ scan_handle_refill(const ref * fop, scanner_state * sstate, bool save,
make_istruct(&rstate[0], 0, pstate);
rstate[1] = *fop;
r_clear_attrs(&rstate[1], a_executable);
- return s_handle_read_exception(status, fop,
+ return s_handle_read_exception(i_ctx_p, status, fop,
rstate, nstate, cont);
}
}
@@ -329,7 +322,7 @@ scan_comment(const byte * base, const byte * end, bool saved)
/* Read a token from a string. */
/* Update the string if succesful. */
int
-scan_string_token(ref * pstr, ref * pref)
+scan_string_token(i_ctx_t *i_ctx_p, ref * pstr, ref * pref)
{
stream st;
stream *s = &st;
@@ -340,7 +333,7 @@ scan_string_token(ref * pstr, ref * pref)
return_error(e_invalidaccess);
sread_string(s, pstr->value.bytes, r_size(pstr));
scanner_state_init(&state, true);
- switch (code = scan_token(s, pref, &state)) {
+ switch (code = scan_token(i_ctx_p, s, pref, &state)) {
case 0: /* read a token */
case scan_BOS:
{
@@ -369,7 +362,7 @@ scan_string_token(ref * pstr, ref * pref)
* as well as for scan_Refill.
*/
int
-scan_token(stream * s, ref * pref, scanner_state * pstate)
+scan_token(i_ctx_t *i_ctx_p, stream * s, ref * pref, scanner_state * pstate)
{
ref *myref = pref;
int retcode = 0;
@@ -440,7 +433,8 @@ scan_token(stream * s, ref * pref, scanner_state * pstate)
daptr = da.next;
switch (scan_type) {
case scanning_binary:
- retcode = (*sstate.s_ss.binary.cont) (s, myref, &sstate);
+ retcode = (*sstate.s_ss.binary.cont)
+ (i_ctx_p, s, myref, &sstate);
scan_begin_inline();
if (retcode == scan_Refill)
goto pause;
@@ -494,8 +488,7 @@ scan_token(stream * s, ref * pref, scanner_state * pstate)
goto try_funny_name;
case '~':
s_A85D_init_inline(&sstate.s_ss.a85d);
- sstate.s_ss.st.template =
- scan_ascii85_template;
+ sstate.s_ss.st.template = &s_A85D_template;
goto str;
}
scan_putback();
@@ -832,7 +825,7 @@ scan_token(stream * s, ref * pref, scanner_state * pstate)
#undef case4
if (recognize_btokens()) {
scan_end_inline();
- retcode = (*scan_btoken_proc) (s, myref, &sstate);
+ retcode = scan_binary_token(i_ctx_p, s, myref, &sstate);
scan_begin_inline();
if (retcode == scan_Refill)
goto pause;
diff --git a/gs/src/iscan.h b/gs/src/iscan.h
index e60d1c21b..98e06c14b 100644
--- a/gs/src/iscan.h
+++ b/gs/src/iscan.h
@@ -61,7 +61,7 @@ typedef dynamic_area *da_ptr;
/* Define state specific to binary tokens and binary object sequences. */
typedef struct scan_binary_state_s {
int num_format;
- int (*cont) (P3(stream *, ref *, scanner_state *));
+ int (*cont)(P4(i_ctx_t *, stream *, ref *, scanner_state *));
ref bin_array;
uint index;
uint max_array_index; /* largest legal index in objects */
@@ -122,21 +122,23 @@ extern_st(st_scanner_state);
#define scan_BOS 1 /* binary object sequence */
#define scan_EOF 2 /* end of stream */
#define scan_Refill 3 /* get more input data, then call again */
-int scan_token(P3(stream * s, ref * pref, scanner_state * pstate));
+int scan_token(P4(i_ctx_t *i_ctx_p, stream * s, ref * pref,
+ scanner_state * pstate));
/*
* Read a token from a string. Return like scan_token, but also
* update the string to move past the token (if no error).
*/
-int scan_string_token(P2(ref * pstr, ref * pref));
+int scan_string_token(P3(i_ctx_t *i_ctx_p, ref * pstr, ref * pref));
/*
* Handle a scan_Refill return from scan_token.
* This may return o_push_estack, 0 (meaning just call scan_token again),
* or an error code.
*/
-int scan_handle_refill(P5(const ref * fop, scanner_state * pstate, bool save,
- bool push_file, int (*cont) (P1(os_ptr))));
+int scan_handle_refill(P6(i_ctx_t *i_ctx_p, const ref * fop,
+ scanner_state * pstate, bool save, bool push_file,
+ op_proc_t cont));
/*
* Define the procedure "hook" for parsing DSC comments. If not NULL,
diff --git a/gs/src/iscanbin.c b/gs/src/iscanbin.c
index 1c8036b1e..4140c0d8f 100644
--- a/gs/src/iscanbin.c
+++ b/gs/src/iscanbin.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,7 +27,7 @@
#include "sfilter.h" /* for iscan.h */
#include "errors.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "dstack.h" /* for immediately evaluated names */
#include "ostack.h" /* must precede iscan.h */
#include "iname.h"
@@ -128,21 +128,19 @@ typedef enum {
#define BS_EXECUTABLE 128
#define SIZEOF_BIN_SEQ_OBJ ((uint)8)
-/* Current binary format (in iscan.c) */
-extern ref ref_binary_object_format;
-
/* Forward references */
-private int scan_bin_num_array_continue(P3(stream *, ref *, scanner_state *));
-private int scan_bin_string_continue(P3(stream *, ref *, scanner_state *));
-private int scan_bos_continue(P3(stream *, ref *, scanner_state *));
+private int scan_bin_num_array_continue(P4(i_ctx_t *, stream *, ref *, scanner_state *));
+private int scan_bin_string_continue(P4(i_ctx_t *, stream *, ref *, scanner_state *));
+private int scan_bos_continue(P4(i_ctx_t *, stream *, ref *, scanner_state *));
private byte *scan_bos_resize(P3(scanner_state *, uint, uint));
-private int scan_bos_string_continue(P3(stream *, ref *, scanner_state *));
+private int scan_bos_string_continue(P4(i_ctx_t *, stream *, ref *, scanner_state *));
/* Scan a binary token. Called from the main scanner */
/* when it encounters an ASCII code 128-159, */
/* if binary tokens are being recognized (object format != 0). */
int
-scan_binary_token(stream * s, ref * pref, scanner_state * pstate)
+scan_binary_token(i_ctx_t *i_ctx_p, stream *s, ref *pref,
+ scanner_state *pstate)
{
scan_binary_state *const pbs = &pstate->s_ss.binary;
@@ -208,7 +206,7 @@ scan_binary_token(stream * s, ref * pref, scanner_state * pstate)
pstate->s_da.is_dynamic = false;
pstate->s_da.base = pstate->s_da.next =
pstate->s_da.limit = pstate->s_da.buf;
- code = scan_bos_continue(s, pref, pstate);
+ code = scan_bos_continue(i_ctx_p, s, pref, pstate);
if (code == scan_Refill || code < 0) {
/* Clean up array for GC. */
uint index = pbs->index;
@@ -279,7 +277,7 @@ scan_binary_token(stream * s, ref * pref, scanner_state * pstate)
s_end_inline(s, p, rlimit);
pstate->s_da.base = pstate->s_da.next = str;
pstate->s_da.limit = str + arg;
- code = scan_bin_string_continue(s, pref, pstate);
+ code = scan_bin_string_continue(i_ctx_p, s, pref, pstate);
if (code == scan_Refill || code < 0) {
pstate->s_da.is_dynamic = true;
make_null(&pbs->bin_array); /* clean up for GC */
@@ -325,7 +323,7 @@ scan_binary_token(stream * s, ref * pref, scanner_state * pstate)
pbs->index = 0;
p += 3;
s_end_inline(s, p, rlimit);
- code = scan_bin_num_array_continue(s, pref, pstate);
+ code = scan_bin_num_array_continue(i_ctx_p, s, pref, pstate);
if (code == scan_Refill || code < 0) {
/* Make sure the array is clean for the GC. */
refset_null(pbs->bin_array.value.refs + pbs->index,
@@ -339,7 +337,8 @@ scan_binary_token(stream * s, ref * pref, scanner_state * pstate)
/* Continue collecting a binary string. */
private int
-scan_bin_string_continue(stream * s, ref * pref, scanner_state * pstate)
+scan_bin_string_continue(i_ctx_t *i_ctx_p, stream * s, ref * pref,
+ scanner_state * pstate)
{
byte *q = pstate->s_da.next;
uint wanted = pstate->s_da.limit - q;
@@ -360,7 +359,8 @@ scan_bin_string_continue(stream * s, ref * pref, scanner_state * pstate)
/* Continue scanning a binary number array. */
private int
-scan_bin_num_array_continue(stream * s, ref * pref, scanner_state * pstate)
+scan_bin_num_array_continue(i_ctx_t *i_ctx_p, stream * s, ref * pref,
+ scanner_state * pstate)
{
scan_binary_state *const pbs = &pstate->s_ss.binary;
uint index = pbs->index;
@@ -402,7 +402,8 @@ scan_bin_num_array_continue(stream * s, ref * pref, scanner_state * pstate)
* all the pointers.
*/
private int
-scan_bos_continue(register stream * s, ref * pref, scanner_state * pstate)
+scan_bos_continue(i_ctx_t *i_ctx_p, register stream * s, ref * pref,
+ scanner_state * pstate)
{
scan_binary_state *const pbs = &pstate->s_ss.binary;
s_declare_inline(s, p, rlimit);
@@ -550,7 +551,7 @@ scan_bos_continue(register stream * s, ref * pref, scanner_state * pstate)
/* to be used for strings. */
iresize_ref_array(&pbs->bin_array, max_array_index,
"binary object sequence(objects)");
- code = scan_bos_string_continue(s, pref, pstate);
+ code = scan_bos_string_continue(i_ctx_p, s, pref, pstate);
if (code == scan_Refill)
pbs->cont = scan_bos_string_continue;
return code;
@@ -584,12 +585,13 @@ scan_bos_resize(scanner_state * pstate, uint new_size, uint index)
/* Continue reading the strings for a binary object sequence. */
private int
-scan_bos_string_continue(register stream * s, ref * pref, scanner_state * pstate)
+scan_bos_string_continue(i_ctx_t *i_ctx_p, register stream * s, ref * pref,
+ scanner_state * pstate)
{
scan_binary_state *const pbs = &pstate->s_ss.binary;
ref rstr;
ref *op = pbs->bin_array.value.refs;
- int code = scan_bin_string_continue(s, &rstr, pstate);
+ int code = scan_bin_string_continue(i_ctx_p, s, &rstr, pstate);
uint space = ialloc_space(idmemory);
bool rescan = false;
uint i;
@@ -642,7 +644,7 @@ scan_bos_string_continue(register stream * s, ref * pref, scanner_state * pstate
return code;
while (count) {
count -= 2;
- code = dict_put(&rdict,
+ code = idict_put(&rdict,
&op->value.refs[count],
&op->value.refs[count + 1]);
if (code < 0)
@@ -679,8 +681,8 @@ scan_bos_string_continue(register stream * s, ref * pref, scanner_state * pstate
/* ---------------- Writing ---------------- */
int
-encode_binary_token(const ref * obj, long *ref_offset, long *char_offset,
- byte * str)
+encode_binary_token(i_ctx_t *i_ctx_p, const ref *obj, long *ref_offset,
+ long *char_offset, byte *str)
{
bin_seq_type_t type;
uint size = 0;
diff --git a/gs/src/iscannum.c b/gs/src/iscannum.c
index 662c94993..da74ee5d7 100644
--- a/gs/src/iscannum.c
+++ b/gs/src/iscannum.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -42,20 +42,20 @@ scan_number(const byte * str, const byte * end, int sign,
{
const byte *sp = str;
#define GET_NEXT(cvar, sp, end_action)\
- if ( sp >= end ) { end_action; } else cvar = *sp++
+ if (sp >= end) { end_action; } else cvar = *sp++
+
/*
* Powers of 10 up to 6 can be represented accurately as
* a single-precision float.
*/
#define NUM_POWERS_10 6
- static const float powers_10[NUM_POWERS_10 + 1] =
- {
+ static const float powers_10[NUM_POWERS_10 + 1] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6
};
- static const double neg_powers_10[NUM_POWERS_10 + 1] =
- {
+ static const double neg_powers_10[NUM_POWERS_10 + 1] = {
1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6
};
+
int ival;
long lval;
double dval;
@@ -65,10 +65,10 @@ scan_number(const byte * str, const byte * end, int sign,
const byte *const decoder = scan_char_decoder;
#define IS_DIGIT(d, c)\
((d = decoder[c]) < 10)
-
- GET_NEXT(c, sp, return_error(e_syntaxerror));
#define WOULD_OVERFLOW(val, d, maxv)\
(val >= maxv / 10 && (val > maxv / 10 || d > (int)(maxv % 10)))
+
+ GET_NEXT(c, sp, return_error(e_syntaxerror));
if (!IS_DIGIT(d, c)) {
if (c != '.')
return_error(e_syntaxerror);
@@ -250,7 +250,7 @@ l2d:
case '.':
GET_NEXT(c, sp, c = EOFC);
exp10 = 0;
- goto fs;
+ goto fd;
default:
*psp = sp;
code = 1;
diff --git a/gs/src/isdata.h b/gs/src/isdata.h
new file mode 100644
index 000000000..3828f4c0d
--- /dev/null
+++ b/gs/src/isdata.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 1992, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Structure for expandable stacks of refs */
+/* Requires iref.h */
+
+#ifndef isdata_INCLUDED
+# define isdata_INCLUDED
+
+/*
+ * In order to detect under- and overflow with minimum overhead, we put
+ * guard elements at the top and bottom of each stack block (see idsdata.h,
+ * iesdata.h, and iosdata.h for details of the individual stacks). Note that
+ * the 'current' and 'next' arrays include the guard elements. See
+ * istack.h for the details of stack blocks.
+ */
+
+/*
+ * The garbage collector requires that the entire contents of every block
+ * be 'clean', i.e., contain legitimate refs; we also need to ensure that
+ * at GC time, pointers in unused areas of a block will not be followed
+ * (since they may be dangling). We ensure this as follows:
+ * - When allocating a new block, we set the entire body to nulls.
+ * This is necessary because the block may be freed before the next GC,
+ * and the GC must be able to scan (parse) refs even if they are free.
+ * - When adding a new block to the top of the stack, we set to nulls
+ * the unused area of the new next-to-top blocks.
+ * - At the beginning of garbage collection, we set to nulls the unused
+ * elements of the top block.
+ */
+
+/*
+ * Define pointers into stacks. Formerly, these were short (unsegmented)
+ * pointers, but this distinction is no longer needed.
+ */
+typedef ref *s_ptr;
+typedef const ref *const_s_ptr;
+
+/* Define an opaque allocator type. */
+#ifndef gs_ref_memory_DEFINED
+# define gs_ref_memory_DEFINED
+typedef struct gs_ref_memory_s gs_ref_memory_t;
+#endif
+
+/*
+ * Define the state of a stack, other than the data it holds.
+ * Note that the total size of a stack cannot exceed max_uint,
+ * because it has to be possible to copy a stack to a PostScript array.
+ */
+#ifndef ref_stack_DEFINED
+typedef struct ref_stack_s ref_stack_t; /* also defined in idebug.h */
+# define ref_stack_DEFINED
+#endif
+/*
+ * We divide the stack structure into two parts: ref_stack_params_t, which
+ * is set when the stack is created and (almost) never changed after that,
+ * and ref_stack_t, which changes dynamically.
+ */
+typedef struct ref_stack_params_s ref_stack_params_t;
+struct ref_stack_s {
+ /* Following are updated dynamically. */
+ s_ptr p; /* current top element */
+ /* Following are updated when adding or deleting blocks. */
+ s_ptr bot; /* bottommost valid element */
+ s_ptr top; /* topmost valid element = */
+ /* bot + data_size */
+ ref current; /* t_array for current top block */
+ uint extension_size; /* total sizes of extn. blocks */
+ uint extension_used; /* total used sizes of extn. blocks */
+ /* Following are updated rarely. */
+ ref max_stack; /* t_integer, Max...Stack user param */
+ uint requested; /* amount of last failing */
+ /* push or pop request */
+ uint margin; /* # of slots to leave between limit */
+ /* and top */
+ uint body_size; /* data_size - margin */
+ /* Following are set only at initialization. */
+ ref_stack_params_t *params;
+ gs_ref_memory_t *memory; /* allocator for params and blocks */
+};
+#define public_st_ref_stack() /* in istack.c */\
+ gs_public_st_complex_only(st_ref_stack, ref_stack_t, "ref_stack_t",\
+ ref_stack_clear_marks, ref_stack_enum_ptrs, ref_stack_reloc_ptrs, 0)
+#define st_ref_stack_num_ptrs 2 /* current, params */
+
+#endif /* isdata_INCLUDED */
diff --git a/gs/src/istack.c b/gs/src/istack.c
index d73c560cb..faccff6b8 100644
--- a/gs/src/istack.c
+++ b/gs/src/istack.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,7 +17,7 @@
*/
-/* Ghostscript expandable stack manager */
+/* Manager for expandable stacks of refs */
#include "memory_.h"
#include "ghost.h"
#include "gsstruct.h"
@@ -30,12 +30,31 @@
#include "ivmspace.h" /* for local/global test */
#include "store.h"
+/*
+ * Define the structure for stack parameters set at initialization.
+ */
+/*typedef struct ref_stack_params_s ref_stack_params_t;*/ /* in istack.h */
+struct ref_stack_params_s {
+ uint bot_guard; /* # of guard elements below bot */
+ uint top_guard; /* # of guard elements above top */
+ uint block_size; /* size of each block */
+ uint data_size; /* # of data slots in each block */
+ ref guard_value; /* t__invalid or t_operator, */
+ /* bottom guard value */
+ int underflow_error; /* error code for underflow */
+ int overflow_error; /* error code for overflow */
+ bool allow_expansion; /* if false, don't expand */
+};
+gs_private_st_simple(st_ref_stack_params, ref_stack_params_t,
+ "ref_stack_params_t");
+
/* Forward references */
-private void init_block(P3(ref_stack *, ref *, uint));
-int ref_stack_push_block(P3(ref_stack *, uint, uint));
+private void init_block(P3(ref_stack_t *pstack, const ref *pblock_array,
+ uint used));
+private int ref_stack_push_block(P3(ref_stack_t *pstack, uint keep, uint add));
/* GC procedures */
-#define sptr ((ref_stack *)vptr)
+#define sptr ((ref_stack_t *)vptr)
private
CLEAR_MARKS_PROC(ref_stack_clear_marks)
{
@@ -43,9 +62,8 @@ CLEAR_MARKS_PROC(ref_stack_clear_marks)
}
private
ENUM_PTRS_BEGIN(ref_stack_enum_ptrs) return 0;
-
-case 0:
-ENUM_RETURN_REF(&sptr->current);
+case 0: ENUM_RETURN_REF(&sptr->current);
+case 1: return ENUM_OBJ(sptr->params);
ENUM_PTRS_END
private RELOC_PTRS_BEGIN(ref_stack_reloc_ptrs)
{
@@ -65,24 +83,33 @@ private RELOC_PTRS_BEGIN(ref_stack_reloc_ptrs)
RELOC_P(bot);
RELOC_P(top);
#undef RELOC_P
+ RELOC_OBJ_VAR(sptr->params);
} RELOC_PTRS_END
/* Structure type for a ref_stack. */
public_st_ref_stack();
/* Initialize a stack. */
-void
-ref_stack_init(ref_stack * pstack, ref * psb, uint bot_guard, uint top_guard,
- ref * pguard, gs_ref_memory_t * mem)
+int
+ref_stack_init(ref_stack_t *pstack, const ref *pblock_array,
+ uint bot_guard, uint top_guard, const ref *pguard_value,
+ gs_ref_memory_t *mem)
{
- uint size = r_size(psb);
+ ref_stack_params_t *params =
+ gs_alloc_struct((gs_memory_t *)mem, ref_stack_params_t,
+ &st_ref_stack_params,
+ "ref_stack_alloc(stack.params)");
+ uint size = r_size(pblock_array);
uint avail = size - (stack_block_refs + bot_guard + top_guard);
- ref_stack_block *pblock = (ref_stack_block *) psb->value.refs;
- s_ptr body = (s_ptr) (pblock + 1);
+ ref_stack_block *pblock = (ref_stack_block *)pblock_array->value.refs;
+ s_ptr body = (s_ptr)(pblock + 1);
+
+ if (params == 0)
+ return_error(-1); /* avoid binding in any error codes */
pstack->bot = body + bot_guard;
pstack->p = pstack->bot - 1;
pstack->top = pstack->p + avail;
- pstack->current = *psb;
+ pstack->current = *pblock_array;
pstack->extension_size = 0;
pstack->extension_used = 0;
@@ -91,26 +118,45 @@ ref_stack_init(ref_stack * pstack, ref * psb, uint bot_guard, uint top_guard,
pstack->margin = 0;
pstack->body_size = avail;
- pstack->bot_guard = bot_guard;
- pstack->top_guard = top_guard;
- pstack->block_size = size;
- pstack->data_size = avail;
- if (pguard != 0)
- pstack->guard_value = *pguard;
- else
- make_tav(&pstack->guard_value, t__invalid, 0, intval, 0);
- pstack->underflow_error = -1; /* bogus, caller must set */
- pstack->overflow_error = -1; /* bogus, caller must set */
- pstack->allow_expansion = true; /* default, caller may reset */
+ pstack->params = params;
pstack->memory = mem;
- init_block(pstack, psb, 0);
+
+ params->bot_guard = bot_guard;
+ params->top_guard = top_guard;
+ params->block_size = size;
+ params->data_size = avail;
+ if (pguard_value != 0)
+ params->guard_value = *pguard_value;
+ else
+ make_tav(&params->guard_value, t__invalid, 0, intval, 0);
+ params->underflow_error = -1;
+ params->overflow_error = -1;
+ params->allow_expansion = true;
+ init_block(pstack, pblock_array, 0);
refset_null(pstack->bot, avail);
make_empty_array(&pblock->next, 0);
+ return 0;
+}
+
+/* Set whether a stack is allowed to expand. The initial value is true. */
+void
+ref_stack_allow_expansion(ref_stack_t *pstack, bool expand)
+{
+ pstack->params->allow_expansion = expand;
+}
+
+/* Set the error codes for under- and overflow. The initial values are -1. */
+void
+ref_stack_set_error_codes(ref_stack_t *pstack, int underflow_error,
+ int overflow_error)
+{
+ pstack->params->underflow_error = underflow_error;
+ pstack->params->overflow_error = overflow_error;
}
/* Set the maximum number of elements allowed on a stack. */
int
-ref_stack_set_max_count(ref_stack * pstack, long nmax)
+ref_stack_set_max_count(ref_stack_t *pstack, long nmax)
{
uint nmin = ref_stack_count_inline(pstack);
@@ -118,7 +164,7 @@ ref_stack_set_max_count(ref_stack * pstack, long nmax)
nmax = nmin;
if (nmax > max_uint / sizeof(ref))
nmax = max_uint / sizeof(ref);
- if (!pstack->allow_expansion) {
+ if (!pstack->params->allow_expansion) {
uint ncur = pstack->body_size;
if (nmax > ncur)
@@ -128,19 +174,24 @@ ref_stack_set_max_count(ref_stack * pstack, long nmax)
return 0;
}
-/* Set the margin between the limit and the top of the stack. */
-/* Note that this may require allocating a block. */
+/*
+ * Set the margin between the limit and the top of the stack.
+ * Note that this may require allocating a block.
+ */
int
-ref_stack_set_margin(ref_stack * pstack, uint margin)
+ref_stack_set_margin(ref_stack_t *pstack, uint margin)
{
+ const ref_stack_params_t *params = pstack->params;
+ uint data_size = params->data_size;
+
if (margin <= pstack->margin) {
refset_null(pstack->top + 1, pstack->margin - margin);
} else {
- if (margin > pstack->data_size >> 1)
+ if (margin > data_size >> 1)
return_error(e_rangecheck);
if (pstack->top - pstack->p < margin) {
uint used = pstack->p + 1 - pstack->bot;
- uint keep = pstack->data_size - margin;
+ uint keep = data_size - margin;
int code = ref_stack_push_block(pstack, keep, used - keep);
if (code < 0)
@@ -148,22 +199,24 @@ ref_stack_set_margin(ref_stack * pstack, uint margin)
}
}
pstack->margin = margin;
- pstack->body_size = pstack->data_size - margin;
+ pstack->body_size = data_size - margin;
pstack->top = pstack->bot + pstack->body_size - 1;
return 0;
}
/* Return the number of elements on a stack. */
uint
-ref_stack_count(const ref_stack * pstack)
+ref_stack_count(const ref_stack_t *pstack)
{
- return pstack->extension_used + (pstack->p - pstack->bot + 1);
+ return ref_stack_count_inline(pstack);
}
-/* Retrieve a given element from the stack, counting from */
-/* 0 as the top element. */
+/*
+ * Return a pointer to a given element from the stack, counting from
+ * 0 as the top element. If the index is out of range, return 0.
+ */
ref *
-ref_stack_index(const ref_stack * pstack, long idx)
+ref_stack_index(const ref_stack_t *pstack, long idx)
{
ref_stack_block *pblock;
uint used = pstack->p + 1 - pstack->bot;
@@ -183,10 +236,12 @@ ref_stack_index(const ref_stack * pstack, long idx)
return pblock->used.value.refs + (used - 1 - (uint) idx);
}
-/* Count the number of elements down to and including the first mark. */
-/* If no mark is found, return 0. */
+/*
+ * Count the number of elements down to and including the first mark.
+ * If no mark is found, return 0.
+ */
uint
-ref_stack_counttomark(const ref_stack * pstack)
+ref_stack_counttomark(const ref_stack_t *pstack)
{
uint scanned = 0;
ref_stack_enum_t rsenum;
@@ -204,10 +259,12 @@ ref_stack_counttomark(const ref_stack * pstack)
return 0;
}
-/* Do the store check for storing elements of a stack into an array. */
-/* May return e_invalidaccess. */
+/*
+ * Do the store check for storing 'count' elements of a stack, starting
+ * 'skip' elements below the top, into an array. Return 0 or e_invalidaccess.
+ */
int
-ref_stack_store_check(const ref_stack * pstack, ref * parray, uint count,
+ref_stack_store_check(const ref_stack_t *pstack, ref *parray, uint count,
uint skip)
{
uint space = r_space(parray);
@@ -243,12 +300,15 @@ ref_stack_store_check(const ref_stack * pstack, ref * parray, uint count,
return 0;
}
-/* Store the top elements of a stack into an array, */
-/* with or without store/undo checking. */
-/* May return e_rangecheck or e_invalidaccess. */
+/*
+ * Store the top 'count' elements of a stack, starting 'skip' elements below
+ * the top, into an array, with or without store/undo checking. age=-1 for
+ * no check, 0 for old, 1 for new. May return e_rangecheck or
+ * e_invalidaccess.
+ */
int
-ref_stack_store(const ref_stack * pstack, ref * parray, uint count, uint skip,
- int age, bool check, client_name_t cname)
+ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count,
+ uint skip, int age, bool check, client_name_t cname)
{
uint left, pass;
ref *to;
@@ -306,10 +366,12 @@ ref_stack_store(const ref_stack * pstack, ref * parray, uint count, uint skip,
return 0;
}
-/* Pop a given number of elements off a stack. */
-/* The number must not exceed the number of elements in use. */
+/*
+ * Pop the top N elements off a stack.
+ * The number must not exceed the number of elements in use.
+ */
void
-ref_stack_pop(ref_stack * pstack, uint count)
+ref_stack_pop(ref_stack_t *pstack, uint count)
{
uint used;
@@ -321,9 +383,9 @@ ref_stack_pop(ref_stack * pstack, uint count)
pstack->p -= count;
}
-/* Pop the top block off a stack. */
+/* Pop the top block off a stack. May return underflow_error. */
int
-ref_stack_pop_block(ref_stack * pstack)
+ref_stack_pop_block(ref_stack_t *pstack)
{
s_ptr bot = pstack->bot;
uint count = pstack->p + 1 - bot;
@@ -336,9 +398,9 @@ ref_stack_pop_block(ref_stack * pstack)
ref next;
if (pnext == 0)
- return_error(pstack->underflow_error);
+ return_error(pstack->params->underflow_error);
used = r_size(&pnext->used);
- body = (ref *) (pnext + 1) + pstack->bot_guard;
+ body = (ref *) (pnext + 1) + pstack->params->bot_guard;
next = pcur->next;
/*
* If the contents of the two blocks won't fit in a single block, we
@@ -388,16 +450,19 @@ ref_stack_pop_block(ref_stack * pstack)
return 0;
}
-/* Extend a stack to recover from an overflow condition. */
-/* May return overflow_error or e_VMerror. */
+/*
+ * Extend a stack to recover from an overflow condition.
+ * May return overflow_error or e_VMerror.
+ */
int
-ref_stack_extend(ref_stack * pstack, uint request)
+ref_stack_extend(ref_stack_t *pstack, uint request)
{
uint keep = (pstack->top - pstack->bot + 1) / 3;
uint count = pstack->p - pstack->bot + 1;
+ const ref_stack_params_t *params = pstack->params;
- if (request > pstack->data_size)
- return_error(pstack->overflow_error);
+ if (request > params->data_size)
+ return_error(params->overflow_error);
if (keep + request > pstack->body_size)
keep = pstack->body_size - request;
if (keep > count)
@@ -405,12 +470,14 @@ ref_stack_extend(ref_stack * pstack, uint request)
return ref_stack_push_block(pstack, keep, request);
}
-/* Push N empty slots onto a stack. These slots are not initialized; */
-/* the caller must fill them immediately. May return overflow_error */
-/* (if max_stack would be exceeded, or the stack has no allocator) */
-/* or e_VMerror. */
+/*
+ * Push N empty slots onto a stack. These slots are not initialized:
+ * the caller must immediately fill them. May return overflow_error
+ * (if max_stack would be exceeded, or the stack has no allocator)
+ * or e_VMerror.
+ */
int
-ref_stack_push(ref_stack * pstack, uint count)
+ref_stack_push(ref_stack_t *pstack, uint count)
{
/* Don't bother to pre-check for overflow: we must be able to */
/* back out in the case of a VMerror anyway, and */
@@ -436,14 +503,16 @@ ref_stack_push(ref_stack * pstack, uint count)
return 0;
}
-/* Push a block onto the stack, specifying how many elements of */
-/* the current top block should remain in the top block and also */
-/* how many elements we are trying to add. */
-/* May return overflow_error or e_VMerror. */
-/* Must have keep <= count. */
-int
-ref_stack_push_block(ref_stack * pstack, uint keep, uint add)
+/*
+ * Push a block onto the stack, specifying how many elements of the current
+ * top block should remain in the top block and also how many elements we
+ * are trying to add. Requires keep <= count. May return overflow_error or
+ * e_VMerror.
+ */
+private int
+ref_stack_push_block(ref_stack_t *pstack, uint keep, uint add)
{
+ const ref_stack_params_t *params = pstack->params;
uint count = pstack->p - pstack->bot + 1;
uint move = count - keep;
ref_stack_block *pcur = (ref_stack_block *) pstack->current.value.refs;
@@ -456,14 +525,13 @@ ref_stack_push_block(ref_stack * pstack, uint keep, uint add)
return_error(e_Fatal);
/* Check for overflowing the maximum size, */
/* or expansion not allowed. */
- if (pstack->memory == 0 ||
- pstack->extension_used + (pstack->top - pstack->bot) + add >=
+ if (pstack->extension_used + (pstack->top - pstack->bot) + add >=
pstack->max_stack.value.intval ||
- !pstack->allow_expansion
+ !params->allow_expansion
)
- return_error(pstack->overflow_error);
+ return_error(params->overflow_error);
code = gs_alloc_ref_array(pstack->memory, &next, 0,
- pstack->block_size, "ref_stack_push_block");
+ params->block_size, "ref_stack_push_block");
if (code < 0)
return code;
pnext = (ref_stack_block *) next.value.refs;
@@ -471,10 +539,10 @@ ref_stack_push_block(ref_stack * pstack, uint keep, uint add)
/* Copy the top keep elements into the new block, */
/* and make the new block the top block. */
init_block(pstack, &next, keep);
- body += pstack->bot_guard;
+ body += params->bot_guard;
memcpy(body, pstack->bot + move, keep * sizeof(ref));
/* Clear the elements above the top of the new block. */
- refset_null(body + keep, pstack->data_size - keep);
+ refset_null(body + keep, params->data_size - keep);
/* Clear the elements above the top of the old block. */
refset_null(pstack->bot + move, keep);
pnext->next = pstack->current;
@@ -491,7 +559,7 @@ ref_stack_push_block(ref_stack * pstack, uint keep, uint add)
/* Begin enumerating the blocks of a stack. */
void
-ref_stack_enum_begin(ref_stack_enum_t *prse, const ref_stack *pstack)
+ref_stack_enum_begin(ref_stack_enum_t *prse, const ref_stack_t *pstack)
{
prse->block = (ref_stack_block *)pstack->current.value.refs;
prse->ptr = pstack->bot;
@@ -513,10 +581,10 @@ ref_stack_enum_next(ref_stack_enum_t *prse)
/* Clean up a stack for garbage collection. */
void
-ref_stack_cleanup(ref_stack * pstack)
+ref_stack_cleanup(ref_stack_t *pstack)
{
ref_stack_block *pblock =
- (ref_stack_block *) pstack->current.value.refs;
+ (ref_stack_block *) pstack->current.value.refs;
refset_null(pstack->p + 1, pstack->top - pstack->p);
pblock->used = pstack->current; /* set attrs */
@@ -526,57 +594,64 @@ ref_stack_cleanup(ref_stack * pstack)
/*
* Free the entire contents of a stack, including the bottom block.
- * The client must free the ref_stack itself. Note that after calling
+ * The client must still call ref_stack_free. Note that after calling
* ref_stack_release, the stack is no longer usable.
*/
void
-ref_stack_release(ref_stack * pstack)
+ref_stack_release(ref_stack_t *pstack)
{
+ gs_ref_memory_t *mem = pstack->memory;
+
ref_stack_clear(pstack);
+ /* Free the parameter structure. */
+ gs_free_object((gs_memory_t *)mem, pstack->params,
+ "ref_stack_release(stack.params)");
/* Free the original (bottom) block. */
- gs_free_ref_array(pstack->memory, &pstack->current,
- "ref_stack_release");
+ gs_free_ref_array(mem, &pstack->current, "ref_stack_release");
}
/*
* Release a stack and then free the ref_stack object.
*/
void
-ref_stack_free(ref_stack * pstack, gs_memory_t * mem, client_name_t cname)
+ref_stack_free(ref_stack_t *pstack)
{
+ gs_memory_t *mem = (gs_memory_t *)pstack->memory;
+
ref_stack_release(pstack);
- gs_free_object(mem, pstack, cname);
+ gs_free_object(mem, pstack, "ref_stack_free");
}
/* ------ Internal routines ------ */
/* Initialize the guards and body of a stack block. */
private void
-init_block(ref_stack * pstack, ref * psb, uint used)
+init_block(ref_stack_t *pstack, const ref *psb, uint used)
{
+ ref_stack_params_t *params = pstack->params;
ref *brefs = psb->value.refs;
uint i;
ref *p;
- for (i = pstack->bot_guard, p = brefs + stack_block_refs;
+ for (i = params->bot_guard, p = brefs + stack_block_refs;
i != 0; i--, p++
)
- ref_assign(p, &pstack->guard_value);
+ ref_assign(p, &params->guard_value);
/* The top guard elements will never be read, */
/* but we need to initialize them for the sake of the GC. */
/* We can use refset_null for this, because even though it uses */
/* make_null_new and stack elements must not be marked new, */
/* these slots will never actually be read or written. */
- if (pstack->top_guard) {
+ if (params->top_guard) {
ref *top = brefs + r_size(psb);
- int top_guard = pstack->top_guard;
+ int top_guard = params->top_guard;
refset_null(top - top_guard, top_guard);
} {
ref_stack_block *const pblock = (ref_stack_block *) brefs;
pblock->used = *psb;
- pblock->used.value.refs = brefs + stack_block_refs + pstack->bot_guard;
+ pblock->used.value.refs = brefs + stack_block_refs + params->bot_guard;
r_set_size(&pblock->used, 0);
}
}
diff --git a/gs/src/istack.h b/gs/src/istack.h
index f79010caa..20900df1b 100644
--- a/gs/src/istack.h
+++ b/gs/src/istack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,17 +17,13 @@
*/
-/* Definitions for expandable Ghostscript stacks */
+/* Definitions for expandable stacks of refs */
/* Requires iref.h */
#ifndef istack_INCLUDED
# define istack_INCLUDED
-/* Define an opaque allocator type. */
-#ifndef gs_ref_memory_DEFINED
-# define gs_ref_memory_DEFINED
-typedef struct gs_ref_memory_s gs_ref_memory_t;
-#endif
+#include "isdata.h"
/*
* The 3 principal Ghostscript stacks (operand, execution, and dictionary)
@@ -39,9 +35,6 @@ typedef struct gs_ref_memory_s gs_ref_memory_t;
* see ostack.h, estack.h, and dstack.h for details.
*/
-typedef ref *s_ptr;
-typedef const ref *const_s_ptr;
-
/*
* Define the structure for a stack block.
* In order to simplify allocation, stack blocks are implemented as
@@ -66,86 +59,37 @@ typedef struct ref_stack_block_s {
#define stack_block_refs (sizeof(ref_stack_block) / sizeof(ref))
-/*
- * In order to detect under- and overflow with minimum overhead, we put
- * guard elements at the top and bottom of each stack block (see dstack.h,
- * estack.h, and ostack.h for details of the individual stacks). Note that
- * the 'current' and 'next' arrays include the guard elements.
- */
+/* ------ Procedural interface ------ */
/*
- * The garbage collector requires that the entire contents of every block
- * be 'clean', i.e., contain legitimate refs; we also need to ensure that
- * at GC time, pointers in unused areas of a block will not be followed
- * (since they may be dangling). We ensure this as follows:
- * - When allocating a new block, we set the entire body to nulls.
- * This is necessary because the block may be freed before the next GC,
- * and the GC must be able to scan (parse) refs even if they are free.
- * - When adding a new block to the top of the stack, we set to nulls
- * the unused area of the new next-to-top blocks.
- * - At the beginning of garbage collection, we set to nulls the unused
- * elements of the top block.
+ * Initialize a stack. Note that this allocates the stack parameter
+ * structure.
*/
+int ref_stack_init(P6(ref_stack_t *pstack, const ref *pblock_array,
+ uint bot_guard, uint top_guard,
+ const ref *pguard_value, gs_ref_memory_t *mem));
-/*
- * Define the (statically allocated) state of a stack.
- * Note that the total size of a stack cannot exceed max_uint,
- * because it has to be possible to copy a stack to a PostScript array.
- */
-#ifndef ref_stack_DEFINED
-typedef struct ref_stack_s ref_stack; /* also defined in idebug.h */
-# define ref_stack_DEFINED
-#endif
-struct ref_stack_s {
- /* Following are updated dynamically. */
- s_ptr p; /* current top element */
- /* Following are updated when adding or deleting blocks. */
- s_ptr bot; /* bottommost valid element */
- s_ptr top; /* topmost valid element = */
- /* bot + data_size */
- ref current; /* t_array for current top block */
- uint extension_size; /* total sizes of extn. blocks */
- uint extension_used; /* total used sizes of extn. blocks */
- /* Following are updated rarely. */
- ref max_stack; /* t_integer, Max...Stack user param */
- uint requested; /* amount of last failing */
- /* push or pop request */
- uint margin; /* # of slots to leave between limit */
- /* and top */
- uint body_size; /* data_size - margin */
- /* Following are set at initialization. */
- uint bot_guard; /* # of guard elements below bot */
- uint top_guard; /* # of guard elements above top */
- uint block_size; /* size of each block */
- uint data_size; /* # of data slots in each block */
- ref guard_value; /* t__invalid or t_operator, */
- /* bottom guard value */
- int underflow_error; /* error code for underflow */
- int overflow_error; /* error code for overflow */
- bool allow_expansion; /* if false, don't expand */
- gs_ref_memory_t *memory; /* allocator for blocks */
-};
-#define public_st_ref_stack() /* in istack.c */\
- gs_public_st_complex_only(st_ref_stack, ref_stack, "ref_stack",\
- ref_stack_clear_marks, ref_stack_enum_ptrs, ref_stack_reloc_ptrs, 0)
-#define st_ref_stack_num_ptrs 1 /* current */
+/* Set whether a stack is allowed to expand. The initial value is true. */
+void ref_stack_allow_expansion(P2(ref_stack_t *pstack, bool expand));
-/* ------ Procedural interface ------ */
+/* Set the error codes for under- and overflow. The initial values are -1. */
+void ref_stack_set_error_codes(P3(ref_stack_t *pstack, int underflow_error,
+ int overflow_error));
-/* Initialize a stack. */
-void ref_stack_init(P6(ref_stack *, ref *, uint, uint, ref *,
- gs_ref_memory_t *));
-
-/* Set the maximum number of elements allowed on a stack. */
-/* Note that the value is a long, not a uint or a ulong. */
-int ref_stack_set_max_count(P2(ref_stack *, long));
+/*
+ * Set the maximum number of elements allowed on a stack.
+ * Note that the value is a long, not a uint or a ulong.
+ */
+int ref_stack_set_max_count(P2(ref_stack_t *pstack, long nmax));
-/* Set the margin between the limit and the top of the stack. */
-/* Note that this may require allocating a block. */
-int ref_stack_set_margin(P2(ref_stack *, uint));
+/*
+ * Set the margin between the limit and the top of the stack.
+ * Note that this may require allocating a block.
+ */
+int ref_stack_set_margin(P2(ref_stack_t *pstack, uint margin));
/* Return the number of elements on a stack. */
-uint ref_stack_count(P1(const ref_stack *));
+uint ref_stack_count(P1(const ref_stack_t *pstack));
#define ref_stack_count_inline(pstk)\
((pstk)->p + 1 - (pstk)->bot + (pstk)->extension_used)
@@ -153,53 +97,62 @@ uint ref_stack_count(P1(const ref_stack *));
/* Return the maximum number of elements allowed on a stack. */
#define ref_stack_max_count(pstk) (uint)((pstk)->max_stack.value.intval)
-/* Return a pointer to a given element from the stack, counting from */
-/* 0 as the top element. If the index is out of range, return 0. */
-/* Note that the index is a long, not a uint or a ulong. */
-ref *ref_stack_index(P2(const ref_stack *, long));
+/*
+ * Return a pointer to a given element from the stack, counting from
+ * 0 as the top element. If the index is out of range, return 0.
+ * Note that the index is a long, not a uint or a ulong.
+ */
+ref *ref_stack_index(P2(const ref_stack_t *pstack, long index));
-/* Count the number of elements down to and including the first mark. */
-/* If no mark is found, return 0. */
-uint ref_stack_counttomark(P1(const ref_stack *));
+/*
+ * Count the number of elements down to and including the first mark.
+ * If no mark is found, return 0.
+ */
+uint ref_stack_counttomark(P1(const ref_stack_t *pstack));
/*
* Do the store check for storing 'count' elements of a stack, starting
* 'skip' elements below the top, into an array. Return 0 or e_invalidaccess.
*/
-int ref_stack_store_check(P4(const ref_stack * pstack, ref * parray,
+int ref_stack_store_check(P4(const ref_stack_t *pstack, ref *parray,
uint count, uint skip));
/*
- * Store 'count elements of a stack, starting 'skip' elements below the top,
- * into an array, with or without store/undo checking.
- * age=-1 for no check, 0 for old, 1 for new.
- * May return e_rangecheck or e_invalidaccess.
+ * Store the top 'count' elements of a stack, starting 'skip' elements below
+ * the top, into an array, with or without store/undo checking. age=-1 for
+ * no check, 0 for old, 1 for new. May return e_rangecheck or
+ * e_invalidaccess.
*/
-int ref_stack_store(P7(const ref_stack * pstack, ref * parray, uint count,
+int ref_stack_store(P7(const ref_stack_t *pstack, ref *parray, uint count,
uint skip, int age, bool check, client_name_t cname));
-/* Pop the top N elements off a stack. */
-/* The number must not exceed the number of elements in use. */
-void ref_stack_pop(P2(ref_stack *, uint));
+/*
+ * Pop the top N elements off a stack.
+ * The number must not exceed the number of elements in use.
+ */
+void ref_stack_pop(P2(ref_stack_t *pstack, uint count));
#define ref_stack_clear(pstk) ref_stack_pop(pstk, ref_stack_count(pstk))
#define ref_stack_pop_to(pstk, depth)\
ref_stack_pop(pstk, ref_stack_count(pstk) - (depth))
-/* Pop the top block off a stack. */
-/* May return underflow_error. */
-int ref_stack_pop_block(P1(ref_stack *));
+/* Pop the top block off a stack. May return underflow_error. */
+int ref_stack_pop_block(P1(ref_stack_t *pstack));
-/* Extend a stack to recover from an overflow condition. */
-/* Uses the requested value to decide what to do. */
-/* May return overflow_error or e_VMerror. */
-int ref_stack_extend(P2(ref_stack *, uint));
+/*
+ * Extend a stack to recover from an overflow condition.
+ * Uses the requested value to decide what to do.
+ * May return overflow_error or e_VMerror.
+ */
+int ref_stack_extend(P2(ref_stack_t *pstack, uint request));
-/* Push N empty slots onto a stack. These slots are not initialized; */
-/* the caller must immediately fill them. May return overflow_error */
-/* (if max_stack would be exceeded, or the stack has no allocator) */
-/* or e_VMerror. */
-int ref_stack_push(P2(ref_stack *, uint));
+/*
+ * Push N empty slots onto a stack. These slots are not initialized:
+ * the caller must immediately fill them. May return overflow_error
+ * (if max_stack would be exceeded, or the stack has no allocator)
+ * or e_VMerror.
+ */
+int ref_stack_push(P2(ref_stack_t *pstack, uint count));
/*
* Enumerate the blocks of a stack from top to bottom, as follows:
@@ -217,34 +170,23 @@ typedef struct ref_stack_enum_s {
ref *ptr;
uint size;
} ref_stack_enum_t;
-void ref_stack_enum_begin(P2(ref_stack_enum_t *, const ref_stack *));
-bool ref_stack_enum_next(P1(ref_stack_enum_t *));
-
-/* Define a previous enumeration structure, for backward compatibility. */
-#define STACK_LOOP_BEGIN(pstack, ptrv, sizev)\
-{ ref_stack_enum_t enum_;\
- ref_stack_enum_begin(&enum_, pstack);\
- do {\
- ref *ptrv = enum_.ptr;\
- uint sizev = enum_.size;
-#define STACK_LOOP_END(ptrv, sizev)\
- } while (ref_stack_enum_next(&enum_));\
-}
+void ref_stack_enum_begin(P2(ref_stack_enum_t *prse,
+ const ref_stack_t *pstack));
+bool ref_stack_enum_next(P1(ref_stack_enum_t *prse));
/* Clean up a stack for garbage collection. */
-void ref_stack_cleanup(P1(ref_stack *));
+void ref_stack_cleanup(P1(ref_stack_t *pstack));
/*
- * Free the entire contents of a stack, including the bottom block.
- * The client must free the ref_stack itself. Note that after calling
+ * Free the entire contents of a stack, including the bottom block. The
+ * client must still free the ref_stack_t object. Note that after calling
* ref_stack_release, the stack is no longer usable.
*/
-void ref_stack_release(P1(ref_stack *));
+void ref_stack_release(P1(ref_stack_t *pstack));
/*
- * Release a stack and then free the ref_stack object.
+ * Release a stack and then free the stack object.
*/
-void ref_stack_free(P3(ref_stack * pstack, gs_memory_t * mem,
- client_name_t cname));
+void ref_stack_free(P1(ref_stack_t *pstack));
#endif /* istack_INCLUDED */
diff --git a/gs/src/istream.h b/gs/src/istream.h
index 2b2acebfb..192c23850 100644
--- a/gs/src/istream.h
+++ b/gs/src/istream.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,9 +29,9 @@ int swrite_proc(P2(ref *, stream **));
/* for interp.c, zfileio.c, zpaint.c - handle a procedure */
/* callback or an interrupt */
-int s_handle_read_exception(P5(int, const ref *, const ref *, int,
- int (*)(P1(os_ptr))));
-int s_handle_write_exception(P5(int, const ref *, const ref *, int,
- int (*)(P1(os_ptr))));
+int s_handle_read_exception(P6(i_ctx_t *, int, const ref *, const ref *,
+ int, op_proc_t));
+int s_handle_write_exception(P6(i_ctx_t *, int, const ref *, const ref *,
+ int, op_proc_t));
#endif /* istream_INCLUDED */
diff --git a/gs/src/istruct.h b/gs/src/istruct.h
index f5c4bd6fc..3904e1944 100644
--- a/gs/src/istruct.h
+++ b/gs/src/istruct.h
@@ -61,7 +61,7 @@ typedef struct gc_procs_with_refs_s {
* not worth the trouble.)
*/
#define ENUM_RETURN_REF(ptr)\
- BEGIN *pep = (const void *)(ptr); return ptr_ref_type; END
+ return (*pep = (const void *)(ptr), ptr_ref_type)
#define ENUM_RETURN_REF_MEMBER(typ, memb)\
ENUM_RETURN_REF(&((typ *)vptr)->memb)
#define RELOC_REF_PTR_VAR(ptrvar)\
diff --git a/gs/src/iutil.c b/gs/src/iutil.c
index 95185da8f..b3eb26064 100644
--- a/gs/src/iutil.c
+++ b/gs/src/iutil.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,6 +23,12 @@
#include "string_.h"
#include "ghost.h"
#include "errors.h"
+#include "gsccode.h" /* for gxfont.h */
+#include "gsmatrix.h"
+#include "gsutil.h"
+#include "gxfont.h"
+#include "strimpl.h"
+#include "sstring.h"
#include "idict.h"
#include "imemory.h"
#include "iname.h"
@@ -31,17 +37,12 @@
#include "ivmspace.h"
#include "oper.h"
#include "store.h"
-#include "gsccode.h" /* for gxfont.h */
-#include "gsmatrix.h"
-#include "gsutil.h"
-#include "gxfont.h"
/* ------ Object utilities ------ */
/* Define the table of ref type properties. */
-const byte ref_type_properties[] =
-{
- ref_type_properties_data
+const byte ref_type_properties[] = {
+ REF_TYPE_PROPERTIES_DATA
};
/* Copy refs from one place to another. */
@@ -186,132 +187,284 @@ obj_ident_eq(const ref * pref1, const ref * pref2)
}
/*
- * Create a printable representation of an object, a la cvs (full_print =
- * false) or == (full_print = true). Return 0 if OK, <0 if the destination
- * wasn't large enough or the object's contents weren't readable.
- * If the object was a string or name, store a pointer to its characters
- * even if it was too large.
+ * Set *pchars and *plen to point to the data of a name or string, and
+ * return 0. If the object isn't a name or string, return e_typecheck.
+ * If the object is a string without read access, return e_invalidaccess.
*/
-private void ensure_dot(P1(char *));
int
-obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
- const byte ** pchars, bool full_print)
+obj_string_data(const ref *op, const byte **pchars, uint *plen)
{
- if (full_print)
- switch (r_btype(op)) {
- case t_boolean:
- case t_integer:
- break;
- case t_real:
- /*
- * To get fully accurate output results for IEEE single-
- * precision floats (24 bits of mantissa), the ANSI
- * %g default of 6 digits is not enough; 9 are needed.
- * Unfortunately, using %.9g for floats (as opposed to
- * doubles) produces unfortunate artifacts such as 0.01 5 mul
- * printing as 0.049999997. Therefore, we print using %g,
- * and if the result isn't accurate enough, print again
- * using %.9g. Unfortunately, a few PostScript programs
- * 'know' that the printed representation of floats fits
- * into 6 digits (e.g., with cvs). We resolve this by letting
- * cvs, cvrs, and = do what the Adobe interpreters appear
- * to do (use %g), and only produce accurate output for ==,
- * for which there is no analogue of cvs. What a hack!
- */
- if (!full_print)
- break;
- {
- char buf[30]; /* big enough for any float or double */
- float value = op->value.realval;
- float scanned;
- uint plen;
-
- sprintf(buf, "%g", value);
- sscanf(buf, "%f", &scanned);
- if (scanned != value)
- sprintf(buf, "%.9g", value);
- ensure_dot(buf);
- *prlen = plen = strlen(buf);
- if (plen > len)
- return_error(e_rangecheck);
- memcpy(str, buf, plen);
- return 0;
- }
- default:
- return_error(e_typecheck);
- }
- return obj_cvs(op, str, len, prlen, pchars);
+ switch (r_type(op)) {
+ case t_name: {
+ ref nref;
+
+ name_string_ref(op, &nref);
+ *pchars = nref.value.bytes;
+ *plen = r_size(&nref);
+ return 0;
+ }
+ case t_string:
+ check_read(*op);
+ *pchars = op->value.bytes;
+ *plen = r_size(op);
+ return 0;
+ default:
+ return_error(e_typecheck);
+ }
}
+
+/*
+ * Create a printable representation of an object, a la cvs and =
+ * (full_print = 0), == (full_print = 1), or === (full_print = 2). Return 0
+ * if OK, 1 if the destination wasn't large enough, e_invalidaccess if the
+ * object's contents weren't readable. If the return value is 0 or 1,
+ * *prlen contains the amount of data returned. start_pos is the starting
+ * output position -- the first start_pos bytes of output are discarded, and
+ * *prlen reflects the remaining amount of output.
+ *
+ * This rather complex API is needed so that a client can call obj_cvp
+ * repeatedly to print on a stream, which may require suspending at any
+ * point to handle stream callouts.
+ */
+private void ensure_dot(P1(char *));
int
-obj_cvs(const ref * op, byte * str, uint len, uint * prlen,
- const byte ** pchars)
+obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
+ int full_print, uint start_pos)
{
- char buf[30]; /* big enough for any float or double */
- const byte *pstr = (const byte *)buf;
- uint plen;
+ char buf[50]; /* big enough for any float, double, or struct name */
+ const byte *data = (const byte *)buf;
+ uint size;
+ int code;
ref nref;
- switch (r_btype(op)) {
+ if (full_print) {
+ static const char * const type_strings[] = { REF_TYPE_PRINT_STRINGS };
+
+ switch (r_btype(op)) {
case t_boolean:
- pstr = (const byte *)(op->value.boolval ? "true" : "false");
- break;
case t_integer:
- sprintf(buf, "%ld", op->value.intval);
break;
- case t_name:
- name_string_ref(op, &nref); /* name string */
-cvname: pstr = nref.value.bytes;
- plen = r_size(&nref);
- if (pchars != 0)
- *pchars = pstr;
- goto nl;
- case t_oparray:
- {
- uint index = op_index(op);
- const op_array_table *opt = op_index_op_array_table(index);
+ case t_real: {
+ /*
+ * To get fully accurate output results for IEEE
+ * single-precision floats (24 bits of mantissa), the ANSI %g
+ * default of 6 digits is not enough; 9 are needed.
+ * Unfortunately, using %.9g for floats (as opposed to doubles)
+ * produces unfortunate artifacts such as 0.01 5 mul printing as
+ * 0.049999997. Therefore, we print using %g, and if the result
+ * isn't accurate enough, print again using %.9g.
+ * Unfortunately, a few PostScript programs 'know' that the
+ * printed representation of floats fits into 6 digits (e.g.,
+ * with cvs). We resolve this by letting cvs, cvrs, and = do
+ * what the Adobe interpreters appear to do (use %g), and only
+ * produce accurate output for ==, for which there is no
+ * analogue of cvs. What a hack!
+ */
+ float value = op->value.realval;
+ float scanned;
- name_index_ref(opt->nx_table[index - opt->base_index], &nref);
- }
- name_string_ref(&nref, &nref);
- goto cvname;
+ sprintf(buf, "%g", value);
+ sscanf(buf, "%f", &scanned);
+ if (scanned != value)
+ sprintf(buf, "%.9g", value);
+ ensure_dot(buf);
+ goto rs;
+ }
case t_operator:
+ case t_oparray:
+ code = obj_cvp(op, (byte *)buf + 2, sizeof(buf) - 4, &size, 0, 0);
+ if (code < 0)
+ return code;
+ buf[0] = buf[1] = buf[size + 2] = buf[size + 3] = '-';
+ size += 4;
+ goto nl;
+ case t_name:
+ if (r_has_attr(op, a_executable)) {
+ code = obj_string_data(op, &data, &size);
+ if (code < 0)
+ return code;
+ goto nl;
+ }
+ if (start_pos > 0)
+ return obj_cvp(op, str, len, prlen, 0, start_pos - 1);
+ if (len < 1)
+ return_error(e_rangecheck);
+ code = obj_cvp(op, str + 1, len - 1, prlen, 0, 0);
+ if (code < 0)
+ return code;
+ str[0] = '/';
+ ++*prlen;
+ return code;
+ case t_null:
+ data = (const byte *)"null";
+ goto rs;
+ case t_string:
+ if (!r_has_attr(op, a_read))
+ goto other;
+ size = r_size(op);
{
- /* Recover the name from the initialization table. */
- uint index = op_index(op);
-
+ bool truncate = (full_print == 1 && size > CVP_MAX_STRING);
+ stream_cursor_read r;
+ stream_cursor_write w;
+ uint skip;
+ byte *wstr;
+ uint len1;
+ int status = 1;
+
+ if (start_pos == 0) {
+ if (len < 1)
+ return_error(e_rangecheck);
+ str[0] = '(';
+ skip = 0;
+ wstr = str + 1;
+ } else {
+ skip = start_pos - 1;
+ wstr = str;
+ }
+ len1 = len + (str - wstr);
+ r.ptr = op->value.const_bytes - 1;
+ r.limit = r.ptr + (truncate ? CVP_MAX_STRING : size);
+ while (skip && status == 1) {
+ uint written;
+
+ w.ptr = (byte *)buf - 1;
+ w.limit = w.ptr + min(skip + len1, sizeof(buf));
+ status = s_PSSE_template.process(NULL, &r, &w, false);
+ written = w.ptr - ((byte *)buf - 1);
+ if (written > skip) {
+ written -= skip;
+ memcpy(wstr, buf + skip, written);
+ wstr += written;
+ skip = 0;
+ break;
+ }
+ skip -= written;
+ }
/*
- * Check the validity of the index. (An out-of-bounds index
- * is only possible when examining an invalid object using
- * the debugger.)
+ * We can reach here with status == 0 (and skip != 0) if
+ * start_pos lies within the trailing ")" or "...)".
*/
- if (index > 0 && index < op_def_count) {
- pstr = (const byte *)(op_def_table[index]->oname + 1);
- break;
+ if (status == 0) {
+#ifdef DEBUG
+ if (skip > (truncate ? 4 : 1)) {
+ return_error(e_Fatal);
+ }
+#endif
+ }
+ w.ptr = wstr - 1;
+ w.limit = str - 1 + len;
+ if (status == 1)
+ status = s_PSSE_template.process(NULL, &r, &w, false);
+ *prlen = w.ptr - (str - 1);
+ if (status != 0)
+ return 1;
+ if (truncate) {
+ if (len - *prlen < 4 - skip)
+ return 1;
+ memcpy(w.ptr + 1, "...)" + skip, 4 - skip);
+ *prlen += 4 - skip;
+ } else {
+ if (len - *prlen < 1 - skip)
+ return 1;
+ memcpy(w.ptr + 1, ")" + skip, 1 - skip);
+ *prlen += 1 - skip;
}
}
- /* Internal operator, no name. */
- sprintf(buf, "@0x%lx", (ulong) op->value.opproc);
- break;
- case t_real:
- sprintf(buf, "%g", op->value.realval);
- ensure_dot(buf);
- break;
- case t_string:
- check_read(*op);
- pstr = op->value.bytes;
- plen = r_size(op);
- if (pchars != 0)
- *pchars = pstr;
+ return 0;
+ case t_astruct:
+ case t_struct:
+ if (r_is_foreign(op)) {
+ /* gs_object_type may not work. */
+ data = (const byte *)"-foreign-struct-";
+ goto rs;
+ }
+ data = (const byte *)
+ gs_struct_type_name_string(
+ gs_object_type(imemory,
+ (const obj_header_t *)op->value.pstruct));
+ size = strlen((const char *)data);
+ if (size > 4 && !memcmp(data + size - 4, "type", 4))
+ size -= 4;
+ if (size > sizeof(buf) - 2)
+ return_error(e_rangecheck);
+ buf[0] = '-';
+ memcpy(buf + 1, data, size);
+ buf[size + 1] = '-';
+ size += 2;
+ data = (const byte *)buf;
goto nl;
default:
- pstr = (const byte *)"--nostringval--";
+other:
+ {
+ int rtype = r_btype(op);
+
+ if (rtype > countof(type_strings))
+ return_error(e_rangecheck);
+ data = (const byte *)type_strings[rtype];
+ if (data == 0)
+ return_error(e_rangecheck);
+ }
+ goto rs;
+ }
+ }
+ /* full_print = 0 */
+ switch (r_btype(op)) {
+ case t_boolean:
+ data = (const byte *)(op->value.boolval ? "true" : "false");
+ break;
+ case t_integer:
+ sprintf(buf, "%ld", op->value.intval);
+ break;
+ case t_string:
+ check_read(*op);
+ /* falls through */
+ case t_name:
+ code = obj_string_data(op, &data, &size);
+ if (code < 0)
+ return code;
+ goto nl;
+ case t_oparray: {
+ uint index = op_index(op);
+ const op_array_table *opt = op_index_op_array_table(index);
+
+ name_index_ref(opt->nx_table[index - opt->base_index], &nref);
+ name_string_ref(&nref, &nref);
+ code = obj_string_data(&nref, &data, &size);
+ if (code < 0)
+ return code;
+ goto nl;
+ }
+ case t_operator: {
+ /* Recover the name from the initialization table. */
+ uint index = op_index(op);
+
+ /*
+ * Check the validity of the index. (An out-of-bounds index
+ * is only possible when examining an invalid object using
+ * the debugger.)
+ */
+ if (index > 0 && index < op_def_count) {
+ data = (const byte *)(op_index_def(index)->oname + 1);
+ break;
+ }
+ /* Internal operator, no name. */
+ sprintf(buf, "@0x%lx", (ulong) op->value.opproc);
+ break;
}
- plen = strlen((const char *)pstr);
-nl: *prlen = plen;
- if (plen > len)
+ case t_real:
+ sprintf(buf, "%g", op->value.realval);
+ ensure_dot(buf);
+ break;
+ default:
+ data = (const byte *)"--nostringval--";
+ }
+rs: size = strlen((const char *)data);
+nl: if (size < start_pos)
return_error(e_rangecheck);
- memcpy(str, pstr, plen);
- return 0;
+ size -= start_pos;
+ *prlen = min(size, len);
+ memmove(str, data + start_pos, *prlen);
+ return (size > len);
}
/*
* Make sure the converted form of a real number has a decimal point. This
@@ -331,22 +484,47 @@ ensure_dot(char *buf)
strcpy(buf1, ept);
strcpy(ept, ".0");
- strcat(buf, buf1);
+ strcat(buf, ept);
}
}
}
+/*
+ * Create a printable representation of an object, a la cvs and =. Return 0
+ * if OK, e_rangecheck if the destination wasn't large enough,
+ * e_invalidaccess if the object's contents weren't readable. If pchars !=
+ * NULL, then if the object was a string or name, store a pointer to its
+ * characters in *pchars even if it was too large; otherwise, set *pchars =
+ * str. In any case, store the length in *prlen.
+ */
+int
+obj_cvs(const ref * op, byte * str, uint len, uint * prlen,
+ const byte ** pchars)
+{
+ int code = obj_cvp(op, str, len, prlen, 0, 0);
+
+ if (code != 1 && pchars) {
+ *pchars = str;
+ return code;
+ }
+ code = obj_string_data(op, pchars, prlen);
+ return (code == e_typecheck ? gs_note_error(e_rangecheck) : code);
+}
+
/* Find the index of an operator that doesn't have one stored in it. */
ushort
op_find_index(const ref * pref /* t_operator */ )
{
- op_proc_p proc = real_opproc(pref);
- const op_def *const *opp = op_def_table;
- const op_def *const *opend = opp + op_def_count;
+ op_proc_t proc = real_opproc(pref);
+ const op_def *const *opp = op_defs_all;
+ const op_def *const *opend = opp + (op_def_count / OP_DEFS_MAX_SIZE);
+
+ for (; opp < opend; ++opp) {
+ const op_def *def = *opp;
- for (; ++opp < opend;) {
- if ((*opp)->proc == proc)
- return opp - op_def_table;
+ for (; def->oname != 0; ++def)
+ if (def->proc == proc)
+ return (opp - op_defs_all) * OP_DEFS_MAX_SIZE + (def - *opp);
}
/* Lookup failed! This isn't possible.... */
return 0;
diff --git a/gs/src/iutil.h b/gs/src/iutil.h
index e7b087279..e214ca807 100644
--- a/gs/src/iutil.h
+++ b/gs/src/iutil.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,16 +41,37 @@ bool obj_eq(P2(const ref *, const ref *));
bool obj_ident_eq(P2(const ref *, const ref *));
/*
- * Create a printable representation of an object, a la cvs (full_print =
- * false) or == (full_print = true). Return 0 if OK, <0 if the destination
- * wasn't large enough or the object's contents weren't readable.
- * If the object was a string or name, store a pointer to its characters
- * even if it was too large. Note that if full_print is true, the only
- * allowed types are boolean, integer, and real.
+ * Set *pchars and *plen to point to the data of a name or string, and
+ * return 0. If the object isn't a name or string, return e_typecheck.
+ * If the object is a string without read access, return e_invalidaccess.
+ */
+int obj_string_data(P3(const ref *op, const byte **pchars, uint *plen));
+
+/*
+ * Create a printable representation of an object, a la cvs and =
+ * (full_print = 0), == (full_print = 1), or === (full_print = 2). Return 0
+ * if OK, 1 if the destination wasn't large enough, e_invalidaccess if the
+ * object's contents weren't readable. If the return value is 0 or 1,
+ * *prlen contains the amount of data returned. start_pos is the starting
+ * output position -- the first start_pos bytes of output are discarded.
+ */
+#define CVP_MAX_STRING 200 /* strings are truncated here if full_print = 1 */
+int obj_cvp(P6(const ref * op, byte *str, uint len, uint * prlen,
+ int full_print, uint start_pos));
+
+/*
+ * Create a printable representation of an object, a la cvs and =. Return 0
+ * if OK, e_rangecheck if the destination wasn't large enough,
+ * e_invalidaccess if the object's contents weren't readable. If pchars !=
+ * NULL, then if the object was a string or name, store a pointer to its
+ * characters in *pchars even if it was too large; otherwise, set *pchars =
+ * str. In any case, store the length in *prlen.
+ *
+ * obj_cvs is different from obj_cvp in two respects: if the printed
+ * representation is too large, it returns e_rangecheck rather than 1;
+ * and it can return a pointer to the data for names and strings, like
+ * obj_string_data.
*/
-int obj_cvp(P6(const ref * op, byte * str, uint len, uint * prlen,
- const byte ** pchars, bool full_print));
-/* obj_cvs is equivalent to obj_cvp with full_print = false. */
int obj_cvs(P5(const ref * op, byte * str, uint len, uint * prlen,
const byte ** pchars));
diff --git a/gs/src/jerror_.h b/gs/src/jerror_.h
new file mode 100644
index 000000000..ff92274e2
--- /dev/null
+++ b/gs/src/jerror_.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Wrapper for jerror.h */
+
+#if SHARE_JPEG
+#include <jerror.h>
+#else
+#include "jerror.h"
+#endif
diff --git a/gs/src/jpeg.mak b/gs/src/jpeg.mak
index 359702a87..780f593cc 100644
--- a/gs/src/jpeg.mak
+++ b/gs/src/jpeg.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -62,13 +62,13 @@ JO_=$(O_)$(JOBJ)
# Define the name of this makefile.
JPEG_MAK=$(GLSRC)jpeg.mak
-jpeg.clean: jpeg.config-clean jpeg.clean-not-config-clean
+jpeg.clean : jpeg.config-clean jpeg.clean-not-config-clean
### WRONG. MUST DELETE OBJ AND GEN FILES SELECTIVELY.
-jpeg.clean-not-config-clean:
+jpeg.clean-not-config-clean :
$(RM_) $(JOBJ)*.$(OBJ)
-jpeg.config-clean:
+jpeg.config-clean :
$(RMN_) $(JGEN)jpeg*.dev
# JI_ and JF_ are defined in gs.mak.
@@ -83,19 +83,47 @@ JCC=$(CC_) $(I_)$(GLGENDIR) $(II)$(JI_)$(_I) $(JF_)
# Because this file is included after lib.mak, we can't use _h macros
# to express indirect dependencies; instead, we build the dependencies
# into the rules for copying the files.
-# Note: jerror_h and jpeglib_h are defined in lib.mak.
-jconfig_h=$(GLGEN)jconfig.h $(GLGEN)arch.h
-#jerror_h=$(JSRC)jerror.h
+# Note: jerror__h and jpeglib__h are defined in lib.mak.
+jconfig__h=$(GLGEN)jconfig_.h $(GLGEN)arch.h
+#jerror__h=$(GLSRC)jerror_.h
+jmorecf__h=$(GLGEN)jmorecf_.h
+#jpeglib__h=$(GLGEN)jpeglib_.h
+
+# We use our own jconfig.h and jmorecfg.h iff we aren't sharing the library.
+# The library itself may need copies of them.
+
+jconfig_h=$(GLGEN)jconfig.h
jmorecfg_h=$(GLGEN)jmorecfg.h
-#jpeglib_h=$(GLGEN)jpeglib.h
-$(GLGEN)jconfig.h: $(ECHOGS_XE) $(GLSRC)gsjconf.h $(stdpre_h)
- $(ECHOGS_XE) -w $(GLGEN)jconfig.h -R $(GLSRC)stdpre.h -R $(GLSRC)gsjconf.h
+$(GLGEN)jconfig_.h : $(GLGEN)jconfig$(SHARE_JPEG).h $(MAKEFILE)
+ $(CP_) $(GLGEN)jconfig$(SHARE_JPEG).h $(GLGEN)jconfig_.h
+
+$(GLGEN)jconfig0.h : $(ECHOGS_XE) $(GLSRC)gsjconf.h $(stdpre_h) $(MAKEFILE)
+ $(EXP)$(ECHOGS_XE) -w $(GLGEN)jconfig0.h -+R $(GLSRC)stdpre.h -+R $(GLSRC)gsjconf.h
+ $(RM_) $(GLGEN)jconfig1.h
+
+$(GLGEN)jconfig1.h : $(ECHOGS_XE) $(JPEG_MAK)
+ $(EXP)$(ECHOGS_XE) -w $(GLGEN)jconfig1.h -x 23 include -x 203c jconfig.h -x 3e
+ $(RMN_) $(GLGEN)jconfig0.h $(GLGEN)jconfig.h
+
+$(GLGEN)jconfig.h : $(GLGEN)jconfig0.h
+ $(CP_) $(GLGEN)jconfig0.h $(GLGEN)jconfig.h
+
+$(GLGEN)jmorecf_.h : $(GLGEN)jmorecf$(SHARE_JPEG).h $(MAKEFILE)
+ $(CP_) $(GLGEN)jmorecf$(SHARE_JPEG).h $(GLGEN)jmorecf_.h
+
+$(GLGEN)jmorecf0.h : $(GLSRC)gsjmorec.h $(GLGEN)jmcorig.h
+ $(CP_) $(GLSRC)gsjmorec.h $(GLGEN)jmorecf0.h
+ $(RM_) $(GLGEN)jmorecf1.h
-$(GLGEN)jmorecfg.h: $(GLSRC)gsjmorec.h $(GLGEN)jmcorig.h
- $(CP_) $(GLSRC)gsjmorec.h $(GLGEN)jmorecfg.h
+$(GLGEN)jmorecf1.h : $(ECHOGS_XE) $(JPEG_MAK)
+ $(EXP)$(ECHOGS_XE) -w $(GLGEN)jmorecf1.h -x 23 include -x 203c jmorecfg.h -x 3e
+ $(RMN_) $(GLGEN)jmorecf0.h $(GLGEN)jmorecfg.h
-$(GLGEN)jmcorig.h: $(JSRC)jmorecfg.h
+$(GLGEN)jmorecfg.h : $(GLGEN)jmorecf0.h
+ $(CP_) $(GLGEN)jmorecf0.h $(GLGEN)jmorecfg.h
+
+$(GLGEN)jmcorig.h : $(JSRC)jmorecfg.h
$(CP_) $(JSRC)jmorecfg.h $(GLGEN)jmcorig.h
# Contrary to what some portability bigots assert as fact, C compilers are
@@ -111,13 +139,23 @@ $(GLGEN)jmcorig.h: $(JSRC)jmorecfg.h
JHCOPY=$(GLGEN)jinclude.h $(GLGEN)jpeglib.h
-$(GLGEN)jinclude.h: $(JSRC)jinclude.h
+$(GLGEN)jinclude.h : $(JSRC)jinclude.h
$(CP_) $(JSRC)jinclude.h $(GLGEN)jinclude.h
-# jpeglib.h doesn't really depend on jconfig.h or jmcorig.h,
+# jpeglib_.h doesn't really depend on jconfig.h or jmcorig.h,
# but we choose to put the dependencies here rather than in the
-# definition of jpeglib_h.
-$(GLGEN)jpeglib.h: $(JSRC)jpeglib.h $(jconfig_h) $(jmorecfg_h)
+# definition of jpeglib__h.
+$(GLGEN)jpeglib_.h : $(GLGEN)jpeglib$(SHARE_JPEG).h $(MAKEFILE)
+ $(CP_) $(GLGEN)jpeglib$(SHARE_JPEG).h $(GLGEN)jpeglib_.h
+
+$(GLGEN)jpeglib0.h : $(JSRC)jpeglib.h $(jconfig_h) $(jmorecfg_h)
+ $(CP_) $(JSRC)jpeglib.h $(GLGEN)jpeglib0.h
+
+$(GLGEN)jpeglib1.h : $(ECHOGS_XE) $(JPEG_MAK)
+ $(EXP)$(ECHOGS_XE) -w $(GLGEN)jpeglib1.h -x 23 include -x 203c jpeglib.h -x 3e
+
+# We also need jpeglib.h for #includes in the library itself.
+$(GLGEN)jpeglib.h : $(JSRC)jpeglib.h
$(CP_) $(JSRC)jpeglib.h $(GLGEN)jpeglib.h
# In order to avoid having to keep the dependency lists for the IJG code
@@ -130,44 +168,39 @@ JDEP=$(AK) $(jconfig_h) $(jmorecfg_h) $(JHCOPY)
# Code common to compression and decompression.
-jpegc0_=$(JOBJ)jcomapi.$(OBJ) $(JOBJ)jutils.$(OBJ) $(JOBJ)sjpegerr.$(OBJ) $(JOBJ)jmemmgr.$(OBJ)
-$(JGEN)jpegc0.dev: $(JPEG_MAK) $(ECHOGS_XE) $(jpegc0_)
+jpegc0_=$(JOBJ)jcomapi.$(OBJ) $(JOBJ)jutils.$(OBJ) $(JOBJ)jmemmgr.$(OBJ) $(JOBJ)jerror.$(OBJ)
+$(JGEN)jpegc0.dev : $(JPEG_MAK) $(ECHOGS_XE) $(jpegc0_)
$(SETMOD) $(JGEN)jpegc0 $(jpegc0_)
-jpegc1_=$(JOBJ)sjpegerr.$(OBJ)
-$(JGEN)jpegc1.dev: $(JPEG_MAK) $(ECHOGS_XE) $(jpegc1_)
- $(SETMOD) $(JGEN)jpegc1 $(jpegc1_)
-
-$(JOBJ)jcomapi.$(OBJ): $(JSRC)jcomapi.c $(JDEP)
+$(JOBJ)jcomapi.$(OBJ) : $(JSRC)jcomapi.c $(JDEP)
$(CP_) $(JSRC)jcomapi.c $(GLGEN)jcomapi.c
$(JCC) $(JO_)jcomapi.$(OBJ) $(C_) $(GLGEN)jcomapi.c
$(RM_) $(GLGEN)jcomapi.c
-$(JOBJ)jutils.$(OBJ): $(JSRC)jutils.c $(JDEP)
+$(JOBJ)jutils.$(OBJ) : $(JSRC)jutils.c $(JDEP)
$(CP_) $(JSRC)jutils.c $(GLGEN)jutils.c
$(JCC) $(JO_)jutils.$(OBJ) $(C_) $(GLGEN)jutils.c
$(RM_) $(GLGEN)jutils.c
-# Note that sjpegerr replaces jerror, and is needed even if we are using
-# the shared library.
-$(JOBJ)sjpegerr.$(OBJ): $(GLSRC)sjpegerr.c $(JDEP) $(stdio__h)
- $(CC_) $(I_)$(GLI_) $(II)$(JI_)$(_I) $(GLF_) $(JO_)sjpegerr.$(OBJ) $(C_) $(GLSRC)sjpegerr.c
-
-$(JOBJ)jmemmgr.$(OBJ): $(JSRC)jmemmgr.c $(JDEP)
+$(JOBJ)jmemmgr.$(OBJ) : $(JSRC)jmemmgr.c $(JDEP)
$(CP_) $(JSRC)jmemmgr.c $(GLGEN)jmemmgr.c
$(JCC) $(JO_)jmemmgr.$(OBJ) $(C_) $(GLGEN)jmemmgr.c
$(RM_) $(GLGEN)jmemmgr.c
+$(JOBJ)jerror.$(OBJ) : $(JSRC)jerror.c $(JDEP)
+ $(CP_) $(JSRC)jerror.c $(GLGEN)jerror.c
+ $(JCC) $(JO_)jerror.$(OBJ) $(C_) $(GLGEN)jerror.c
+ $(RM_) $(GLGEN)jerror.c
+
# Encoding (compression) code.
-$(JGEN)jpege.dev: $(JGEN)jpege_$(SHARE_JPEG).dev
+$(JGEN)jpege.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpege_$(SHARE_JPEG).dev
$(CP_) $(JGEN)jpege_$(SHARE_JPEG).dev $(JGEN)jpege.dev
-$(JGEN)jpege_1.dev: $(MAKEFILE) $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc1.dev
- $(SETMOD) $(JGEN)jpege_1 -include $(JGEN)jpegc1
- $(ADDMOD) $(JGEN)jpege_1 -lib $(JPEG_NAME)
+$(JGEN)jpege_1.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(JGEN)jpege_1 -lib $(JPEG_NAME)
-$(JGEN)jpege_0.dev: $(JGEN)jpege$(JVERSION).dev
+$(JGEN)jpege_0.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpege$(JVERSION).dev
$(CP_) $(JGEN)jpege$(JVERSION).dev $(JGEN)jpege_0.dev
jpege6=$(JOBJ)jcapimin.$(OBJ) $(JOBJ)jcapistd.$(OBJ) $(JOBJ)jcinit.$(OBJ)
@@ -176,93 +209,92 @@ jpege_1=$(JOBJ)jccoefct.$(OBJ) $(JOBJ)jccolor.$(OBJ) $(JOBJ)jcdctmgr.$(OBJ)
jpege_2=$(JOBJ)jchuff.$(OBJ) $(JOBJ)jcmainct.$(OBJ) $(JOBJ)jcmarker.$(OBJ) $(JOBJ)jcmaster.$(OBJ)
jpege_3=$(JOBJ)jcparam.$(OBJ) $(JOBJ)jcprepct.$(OBJ) $(JOBJ)jcsample.$(OBJ) $(JOBJ)jfdctint.$(OBJ)
-$(JGEN)jpege6.dev: $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpege6) $(jpege_1) $(jpege_2) $(jpege_3)
+$(JGEN)jpege6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpege6) $(jpege_1) $(jpege_2) $(jpege_3)
$(SETMOD) $(JGEN)jpege6 $(jpege6)
- $(ADDMOD) $(JGEN)jpege6 -include $(JGEN)jpegc0
+ $(ADDMOD) $(JGEN)jpege6 -include $(JGEN)jpegc0.dev
$(ADDMOD) $(JGEN)jpege6 -obj $(jpege_1)
$(ADDMOD) $(JGEN)jpege6 -obj $(jpege_2)
$(ADDMOD) $(JGEN)jpege6 -obj $(jpege_3)
-$(JOBJ)jcapimin.$(OBJ): $(JSRC)jcapimin.c $(JDEP)
+$(JOBJ)jcapimin.$(OBJ) : $(JSRC)jcapimin.c $(JDEP)
$(CP_) $(JSRC)jcapimin.c $(GLGEN)jcapimin.c
$(JCC) $(JO_)jcapimin.$(OBJ) $(C_) $(GLGEN)jcapimin.c
$(RM_) $(GLGEN)jcapimin.c
-$(JOBJ)jcapistd.$(OBJ): $(JSRC)jcapistd.c $(JDEP)
+$(JOBJ)jcapistd.$(OBJ) : $(JSRC)jcapistd.c $(JDEP)
$(CP_) $(JSRC)jcapistd.c $(GLGEN)jcapistd.c
$(JCC) $(JO_)jcapistd.$(OBJ) $(C_) $(GLGEN)jcapistd.c
$(RM_) $(GLGEN)jcapistd.c
-$(JOBJ)jcinit.$(OBJ): $(JSRC)jcinit.c $(JDEP)
+$(JOBJ)jcinit.$(OBJ) : $(JSRC)jcinit.c $(JDEP)
$(CP_) $(JSRC)jcinit.c $(GLGEN)jcinit.c
$(JCC) $(JO_)jcinit.$(OBJ) $(C_) $(GLGEN)jcinit.c
$(RM_) $(GLGEN)jcinit.c
-$(JOBJ)jccoefct.$(OBJ): $(JSRC)jccoefct.c $(JDEP)
+$(JOBJ)jccoefct.$(OBJ) : $(JSRC)jccoefct.c $(JDEP)
$(CP_) $(JSRC)jccoefct.c $(GLGEN)jccoefct.c
$(JCC) $(JO_)jccoefct.$(OBJ) $(C_) $(GLGEN)jccoefct.c
$(RM_) $(GLGEN)jccoefct.c
-$(JOBJ)jccolor.$(OBJ): $(JSRC)jccolor.c $(JDEP)
+$(JOBJ)jccolor.$(OBJ) : $(JSRC)jccolor.c $(JDEP)
$(CP_) $(JSRC)jccolor.c $(GLGEN)jccolor.c
$(JCC) $(JO_)jccolor.$(OBJ) $(C_) $(GLGEN)jccolor.c
$(RM_) $(GLGEN)jccolor.c
-$(JOBJ)jcdctmgr.$(OBJ): $(JSRC)jcdctmgr.c $(JDEP)
+$(JOBJ)jcdctmgr.$(OBJ) : $(JSRC)jcdctmgr.c $(JDEP)
$(CP_) $(JSRC)jcdctmgr.c $(GLGEN)jcdctmgr.c
$(JCC) $(JO_)jcdctmgr.$(OBJ) $(C_) $(GLGEN)jcdctmgr.c
$(RM_) $(GLGEN)jcdctmgr.c
-$(JOBJ)jchuff.$(OBJ): $(JSRC)jchuff.c $(JDEP)
+$(JOBJ)jchuff.$(OBJ) : $(JSRC)jchuff.c $(JDEP)
$(CP_) $(JSRC)jchuff.c $(GLGEN)jchuff.c
$(JCC) $(JO_)jchuff.$(OBJ) $(C_) $(GLGEN)jchuff.c
$(RM_) $(GLGEN)jchuff.c
-$(JOBJ)jcmainct.$(OBJ): $(JSRC)jcmainct.c $(JDEP)
+$(JOBJ)jcmainct.$(OBJ) : $(JSRC)jcmainct.c $(JDEP)
$(CP_) $(JSRC)jcmainct.c $(GLGEN)jcmainct.c
$(JCC) $(JO_)jcmainct.$(OBJ) $(C_) $(GLGEN)jcmainct.c
$(RM_) $(GLGEN)jcmainct.c
-$(JOBJ)jcmarker.$(OBJ): $(JSRC)jcmarker.c $(JDEP)
+$(JOBJ)jcmarker.$(OBJ) : $(JSRC)jcmarker.c $(JDEP)
$(CP_) $(JSRC)jcmarker.c $(GLGEN)jcmarker.c
$(JCC) $(JO_)jcmarker.$(OBJ) $(C_) $(GLGEN)jcmarker.c
$(RM_) $(GLGEN)jcmarker.c
-$(JOBJ)jcmaster.$(OBJ): $(JSRC)jcmaster.c $(JDEP)
+$(JOBJ)jcmaster.$(OBJ) : $(JSRC)jcmaster.c $(JDEP)
$(CP_) $(JSRC)jcmaster.c $(GLGEN)jcmaster.c
$(JCC) $(JO_)jcmaster.$(OBJ) $(C_) $(GLGEN)jcmaster.c
$(RM_) $(GLGEN)jcmaster.c
-$(JOBJ)jcparam.$(OBJ): $(JSRC)jcparam.c $(JDEP)
+$(JOBJ)jcparam.$(OBJ) : $(JSRC)jcparam.c $(JDEP)
$(CP_) $(JSRC)jcparam.c $(GLGEN)jcparam.c
$(JCC) $(JO_)jcparam.$(OBJ) $(C_) $(GLGEN)jcparam.c
$(RM_) $(GLGEN)jcparam.c
-$(JOBJ)jcprepct.$(OBJ): $(JSRC)jcprepct.c $(JDEP)
+$(JOBJ)jcprepct.$(OBJ) : $(JSRC)jcprepct.c $(JDEP)
$(CP_) $(JSRC)jcprepct.c $(GLGEN)jcprepct.c
$(JCC) $(JO_)jcprepct.$(OBJ) $(C_) $(GLGEN)jcprepct.c
$(RM_) $(GLGEN)jcprepct.c
-$(JOBJ)jcsample.$(OBJ): $(JSRC)jcsample.c $(JDEP)
+$(JOBJ)jcsample.$(OBJ) : $(JSRC)jcsample.c $(JDEP)
$(CP_) $(JSRC)jcsample.c $(GLGEN)jcsample.c
$(JCC) $(JO_)jcsample.$(OBJ) $(C_) $(GLGEN)jcsample.c
$(RM_) $(GLGEN)jcsample.c
-$(JOBJ)jfdctint.$(OBJ): $(JSRC)jfdctint.c $(JDEP)
+$(JOBJ)jfdctint.$(OBJ) : $(JSRC)jfdctint.c $(JDEP)
$(CP_) $(JSRC)jfdctint.c $(GLGEN)jfdctint.c
$(JCC) $(JO_)jfdctint.$(OBJ) $(C_) $(GLGEN)jfdctint.c
$(RM_) $(GLGEN)jfdctint.c
# Decompression code
-$(JGEN)jpegd.dev: $(JGEN)jpegd_$(SHARE_JPEG).dev
+$(JGEN)jpegd.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpegd_$(SHARE_JPEG).dev
$(CP_) $(JGEN)jpegd_$(SHARE_JPEG).dev $(JGEN)jpegd.dev
-$(JGEN)jpegd_1.dev: $(MAKEFILE) $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc1.dev
- $(SETMOD) $(JGEN)jpegd_1 -include $(JGEN)jpegc1
- $(ADDMOD) $(JGEN)jpegd_1 -lib $(JPEG_NAME)
+$(JGEN)jpegd_1.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(JGEN)jpegd_1 -lib $(JPEG_NAME)
-$(JGEN)jpegd_0.dev: $(JGEN)jpegd$(JVERSION).dev
+$(JGEN)jpegd_0.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpegd$(JVERSION).dev
$(CP_) $(JGEN)jpegd$(JVERSION).dev $(JGEN)jpegd_0.dev
jpegd6=$(JOBJ)jdapimin.$(OBJ) $(JOBJ)jdapistd.$(OBJ) $(JOBJ)jdinput.$(OBJ) $(JOBJ)jdphuff.$(OBJ)
@@ -271,79 +303,79 @@ jpegd_1=$(JOBJ)jdcoefct.$(OBJ) $(JOBJ)jdcolor.$(OBJ)
jpegd_2=$(JOBJ)jddctmgr.$(OBJ) $(JOBJ)jdhuff.$(OBJ) $(JOBJ)jdmainct.$(OBJ) $(JOBJ)jdmarker.$(OBJ)
jpegd_3=$(JOBJ)jdmaster.$(OBJ) $(JOBJ)jdpostct.$(OBJ) $(JOBJ)jdsample.$(OBJ) $(JOBJ)jidctint.$(OBJ)
-$(JGEN)jpegd6.dev: $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpegd6) $(jpegd_1) $(jpegd_2) $(jpegd_3)
+$(JGEN)jpegd6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpegd6) $(jpegd_1) $(jpegd_2) $(jpegd_3)
$(SETMOD) $(JGEN)jpegd6 $(jpegd6)
- $(ADDMOD) $(JGEN)jpegd6 -include $(JGEN)jpegc0
+ $(ADDMOD) $(JGEN)jpegd6 -include $(JGEN)jpegc0.dev
$(ADDMOD) $(JGEN)jpegd6 -obj $(jpegd_1)
$(ADDMOD) $(JGEN)jpegd6 -obj $(jpegd_2)
$(ADDMOD) $(JGEN)jpegd6 -obj $(jpegd_3)
-$(JOBJ)jdapimin.$(OBJ): $(JSRC)jdapimin.c $(JDEP)
+$(JOBJ)jdapimin.$(OBJ) : $(JSRC)jdapimin.c $(JDEP)
$(CP_) $(JSRC)jdapimin.c $(GLGEN)jdapimin.c
$(JCC) $(JO_)jdapimin.$(OBJ) $(C_) $(GLGEN)jdapimin.c
$(RM_) $(GLGEN)jdapimin.c
-$(JOBJ)jdapistd.$(OBJ): $(JSRC)jdapistd.c $(JDEP)
+$(JOBJ)jdapistd.$(OBJ) : $(JSRC)jdapistd.c $(JDEP)
$(CP_) $(JSRC)jdapistd.c $(GLGEN)jdapistd.c
$(JCC) $(JO_)jdapistd.$(OBJ) $(C_) $(GLGEN)jdapistd.c
$(RM_) $(GLGEN)jdapistd.c
-$(JOBJ)jdcoefct.$(OBJ): $(JSRC)jdcoefct.c $(JDEP)
+$(JOBJ)jdcoefct.$(OBJ) : $(JSRC)jdcoefct.c $(JDEP)
$(CP_) $(JSRC)jdcoefct.c $(GLGEN)jdcoefct.c
$(JCC) $(JO_)jdcoefct.$(OBJ) $(C_) $(GLGEN)jdcoefct.c
$(RM_) $(GLGEN)jdcoefct.c
-$(JOBJ)jdcolor.$(OBJ): $(JSRC)jdcolor.c $(JDEP)
+$(JOBJ)jdcolor.$(OBJ) : $(JSRC)jdcolor.c $(JDEP)
$(CP_) $(JSRC)jdcolor.c $(GLGEN)jdcolor.c
$(JCC) $(JO_)jdcolor.$(OBJ) $(C_) $(GLGEN)jdcolor.c
$(RM_) $(GLGEN)jdcolor.c
-$(JOBJ)jddctmgr.$(OBJ): $(JSRC)jddctmgr.c $(JDEP)
+$(JOBJ)jddctmgr.$(OBJ) : $(JSRC)jddctmgr.c $(JDEP)
$(CP_) $(JSRC)jddctmgr.c $(GLGEN)jddctmgr.c
$(JCC) $(JO_)jddctmgr.$(OBJ) $(C_) $(GLGEN)jddctmgr.c
$(RM_) $(GLGEN)jddctmgr.c
-$(JOBJ)jdhuff.$(OBJ): $(JSRC)jdhuff.c $(JDEP)
+$(JOBJ)jdhuff.$(OBJ) : $(JSRC)jdhuff.c $(JDEP)
$(CP_) $(JSRC)jdhuff.c $(GLGEN)jdhuff.c
$(JCC) $(JO_)jdhuff.$(OBJ) $(C_) $(GLGEN)jdhuff.c
$(RM_) $(GLGEN)jdhuff.c
-$(JOBJ)jdinput.$(OBJ): $(JSRC)jdinput.c $(JDEP)
+$(JOBJ)jdinput.$(OBJ) : $(JSRC)jdinput.c $(JDEP)
$(CP_) $(JSRC)jdinput.c $(GLGEN)jdinput.c
$(JCC) $(JO_)jdinput.$(OBJ) $(C_) $(GLGEN)jdinput.c
$(RM_) $(GLGEN)jdinput.c
-$(JOBJ)jdmainct.$(OBJ): $(JSRC)jdmainct.c $(JDEP)
+$(JOBJ)jdmainct.$(OBJ) : $(JSRC)jdmainct.c $(JDEP)
$(CP_) $(JSRC)jdmainct.c $(GLGEN)jdmainct.c
$(JCC) $(JO_)jdmainct.$(OBJ) $(C_) $(GLGEN)jdmainct.c
$(RM_) $(GLGEN)jdmainct.c
-$(JOBJ)jdmarker.$(OBJ): $(JSRC)jdmarker.c $(JDEP)
+$(JOBJ)jdmarker.$(OBJ) : $(JSRC)jdmarker.c $(JDEP)
$(CP_) $(JSRC)jdmarker.c $(GLGEN)jdmarker.c
$(JCC) $(JO_)jdmarker.$(OBJ) $(C_) $(GLGEN)jdmarker.c
$(RM_) $(GLGEN)jdmarker.c
-$(JOBJ)jdmaster.$(OBJ): $(JSRC)jdmaster.c $(JDEP)
+$(JOBJ)jdmaster.$(OBJ) : $(JSRC)jdmaster.c $(JDEP)
$(CP_) $(JSRC)jdmaster.c $(GLGEN)jdmaster.c
$(JCC) $(JO_)jdmaster.$(OBJ) $(C_) $(GLGEN)jdmaster.c
$(RM_) $(GLGEN)jdmaster.c
-$(JOBJ)jdphuff.$(OBJ): $(JSRC)jdphuff.c $(JDEP)
+$(JOBJ)jdphuff.$(OBJ) : $(JSRC)jdphuff.c $(JDEP)
$(CP_) $(JSRC)jdphuff.c $(GLGEN)jdphuff.c
$(JCC) $(JO_)jdphuff.$(OBJ) $(C_) $(GLGEN)jdphuff.c
$(RM_) $(GLGEN)jdphuff.c
-$(JOBJ)jdpostct.$(OBJ): $(JSRC)jdpostct.c $(JDEP)
+$(JOBJ)jdpostct.$(OBJ) : $(JSRC)jdpostct.c $(JDEP)
$(CP_) $(JSRC)jdpostct.c $(GLGEN)jdpostct.c
$(JCC) $(JO_)jdpostct.$(OBJ) $(C_) $(GLGEN)jdpostct.c
$(RM_) $(GLGEN)jdpostct.c
-$(JOBJ)jdsample.$(OBJ): $(JSRC)jdsample.c $(JDEP)
+$(JOBJ)jdsample.$(OBJ) : $(JSRC)jdsample.c $(JDEP)
$(CP_) $(JSRC)jdsample.c $(GLGEN)jdsample.c
$(JCC) $(JO_)jdsample.$(OBJ) $(C_) $(GLGEN)jdsample.c
$(RM_) $(GLGEN)jdsample.c
-$(JOBJ)jidctint.$(OBJ): $(JSRC)jidctint.c $(JDEP)
+$(JOBJ)jidctint.$(OBJ) : $(JSRC)jidctint.c $(JDEP)
$(CP_) $(JSRC)jidctint.c $(GLGEN)jidctint.c
$(JCC) $(JO_)jidctint.$(OBJ) $(C_) $(GLGEN)jidctint.c
$(RM_) $(GLGEN)jidctint.c
diff --git a/gs/src/libpng.mak b/gs/src/libpng.mak
index 1c8a95a86..2789a968d 100644
--- a/gs/src/libpng.mak
+++ b/gs/src/libpng.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -24,9 +24,15 @@
# PNGSRCDIR - the source directory
# PNGGENDIR - the generated intermediate file directory
# PNGOBJDIR - the object directory
-# PNGVERSION - the library version number ("89", "90", "95", "96", "101")
+# PNGVERSION - the library version number ("89", "90", "95", "96",
+# "10001", "10002", "10003").
+# For historical reasons, "101" and "102" are also acceptable,
+# even though they don't match libpng's numbering scheme
+# (see png.h for more details).
# SHARE_LIBPNG - 0 to compile libpng, 1 to share
# LIBPNG_NAME - if SHARE_LIBPNG=1, the name of the shared library
+# NOTE: currently users of this makefile define PSRCDIR and PVERSION,
+# not PNGSRCDIR and PNGVERSION. This is a bug.
# This partial makefile compiles the png library for use in the Ghostscript
# PNG drivers. You can get the source code for this library from:
@@ -41,9 +47,10 @@
# for more convenient access.
#
# The makefile is known to work with the following library versions:
-# 0.89, 0.90, 0.95, 0.96, 1.0.1, 1.0.2. NOTE: the archive for libpng 0.95 may
-# be inconsistent: if you have compilation problems, use an older version.
-# Please see Ghostscript's `make.txt' file for instructions about how to
+# 0.89, 0.90, 0.95, 0.96, 1.0.1, 1.0.2, 1.0.3.
+# NOTE: the archive for libpng 0.95 may be inconsistent: if you have
+# compilation problems, use an older version.
+# Please see Ghostscript's Make.htm file for instructions about how to
# unpack these archives.
#
# The specification for the PNG file format is available from:
@@ -57,8 +64,7 @@ PNGSRC=$(PNGSRCDIR)$(D)
PNGGEN=$(PNGGENDIR)$(D)
PNGOBJ=$(PNGOBJDIR)$(D)
PNGO_=$(O_)$(PNGOBJ)
-ZGEN=$(ZGENDIR)$(D)
-ZOBJ=$(ZOBJDIR)$(D)
+PZGEN=$(ZGENDIR)$(D)
# PI_ and PF_ are defined in gs.mak.
PNGCC=$(CC_) $(I_)$(PI_)$(_I) $(PF_)
@@ -66,17 +72,15 @@ PNGCC=$(CC_) $(I_)$(PI_)$(_I) $(PF_)
# Define the name of this makefile.
LIBPNG_MAK=$(GLSRC)libpng.mak
-png.clean: png.config-clean png.clean-not-config-clean
+png.clean : png.config-clean png.clean-not-config-clean
### WRONG. MUST DELETE OBJ AND GEN FILES SELECTIVELY.
-png.clean-not-config-clean:
+png.clean-not-config-clean :
$(RM_) $(PNGOBJ)*.$(OBJ)
-png.config-clean:
- $(RM_) $(PNGGEN)libpng*.dev
+png.config-clean :
+ $(RM_) $(PNGGEN)lpg*.dev
-# We keep all of the PNG code in a separate directory so as not to
-# inadvertently mix it up with Aladdin Enterprises' own code.
PDEP=$(AK)
png_1=$(PNGOBJ)png.$(OBJ) $(PNGOBJ)pngmem.$(OBJ) $(PNGOBJ)pngerror.$(OBJ)
@@ -84,58 +88,70 @@ png_2=$(PNGOBJ)pngtrans.$(OBJ) $(PNGOBJ)pngwrite.$(OBJ) $(PNGOBJ)pngwtran.$(OBJ)
# libpng modules
-$(PNGOBJ)png.$(OBJ): $(PNGSRC)png.c $(PDEP)
+$(PNGOBJ)png.$(OBJ) : $(PNGSRC)png.c $(PDEP)
$(PNGCC) $(PNGO_)png.$(OBJ) $(C_) $(PNGSRC)png.c
-$(PNGOBJ)pngwio.$(OBJ): $(PNGSRC)pngwio.c $(PDEP)
+$(PNGOBJ)pngwio.$(OBJ) : $(PNGSRC)pngwio.c $(PDEP)
$(PNGCC) $(PNGO_)pngwio.$(OBJ) $(C_) $(PNGSRC)pngwio.c
-$(PNGOBJ)pngmem.$(OBJ): $(PNGSRC)pngmem.c $(PDEP)
+$(PNGOBJ)pngmem.$(OBJ) : $(PNGSRC)pngmem.c $(PDEP)
$(PNGCC) $(PNGO_)pngmem.$(OBJ) $(C_) $(PNGSRC)pngmem.c
-$(PNGOBJ)pngerror.$(OBJ): $(PNGSRC)pngerror.c $(PDEP)
+$(PNGOBJ)pngerror.$(OBJ) : $(PNGSRC)pngerror.c $(PDEP)
$(PNGCC) $(PNGO_)pngerror.$(OBJ) $(C_) $(PNGSRC)pngerror.c
-$(PNGOBJ)pngtrans.$(OBJ): $(PNGSRC)pngtrans.c $(PDEP)
+$(PNGOBJ)pngtrans.$(OBJ) : $(PNGSRC)pngtrans.c $(PDEP)
$(PNGCC) $(PNGO_)pngtrans.$(OBJ) $(C_) $(PNGSRC)pngtrans.c
-$(PNGOBJ)pngwrite.$(OBJ): $(PNGSRC)pngwrite.c $(PDEP)
+$(PNGOBJ)pngwrite.$(OBJ) : $(PNGSRC)pngwrite.c $(PDEP)
$(PNGCC) $(PNGO_)pngwrite.$(OBJ) $(C_) $(PNGSRC)pngwrite.c
-$(PNGOBJ)pngwtran.$(OBJ): $(PNGSRC)pngwtran.c $(PDEP)
+$(PNGOBJ)pngwtran.$(OBJ) : $(PNGSRC)pngwtran.c $(PDEP)
$(PNGCC) $(PNGO_)pngwtran.$(OBJ) $(C_) $(PNGSRC)pngwtran.c
-$(PNGOBJ)pngwutil.$(OBJ): $(PNGSRC)pngwutil.c $(PDEP)
+$(PNGOBJ)pngwutil.$(OBJ) : $(PNGSRC)pngwutil.c $(PDEP)
$(PNGCC) $(PNGO_)pngwutil.$(OBJ) $(C_) $(PNGSRC)pngwutil.c
# Define the version of libpng.dev that we are actually using.
-$(PNGGEN)libpng.dev: $(MAKEFILE) $(PNGGEN)libpng_$(SHARE_LIBPNG).dev
+$(PNGGEN)libpng.dev : $(TOP_MAKEFILES) $(PNGGEN)libpng_$(SHARE_LIBPNG).dev
$(CP_) $(PNGGEN)libpng_$(SHARE_LIBPNG).dev $(PNGGEN)libpng.dev
# Define the shared version of libpng.
# Note that it requires libz, which must be searched *after* libpng.
-$(PNGGEN)libpng_1.dev: $(MAKEFILE) $(LIBPNG_MAK) $(ECHOGS_XE) $(ZGEN)zlibe.dev
+$(PNGGEN)libpng_1.dev : $(TOP_MAKEFILES) $(LIBPNG_MAK) $(ECHOGS_XE) $(PZGEN)zlibe.dev
$(SETMOD) $(PNGGEN)libpng_1 -lib $(LIBPNG_NAME)
- $(ADDMOD) $(PNGGEN)libpng_1 -include $(ZGEN)zlibe
+ $(ADDMOD) $(PNGGEN)libpng_1 -include $(PZGEN)zlibe.dev
# Define the non-shared version of libpng.
-$(PNGGEN)libpng_0.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(png_1) $(png_2)\
- $(ZGEN)zlibe.dev $(PNGGEN)lpng$(PNGVERSION).dev
+$(PNGGEN)libpng_0.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(png_1) $(png_2)\
+ $(PZGEN)zlibe.dev $(PNGGEN)lpg$(PNGVERSION).dev
$(SETMOD) $(PNGGEN)libpng_0 $(png_1)
$(ADDMOD) $(PNGGEN)libpng_0 $(png_2)
- $(ADDMOD) $(PNGGEN)libpng_0 -include $(ZGEN)zlibe $(PNGGEN)lpng$(PNGVERSION)
+ $(ADDMOD) $(PNGGEN)libpng_0 -include $(PZGEN)zlibe.dev $(PNGGEN)lpg$(PNGVERSION).dev
-$(PNGGEN)lpng89.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ)
- $(SETMOD) $(PNGGEN)lpng89 $(PNGOBJ)pngwio.$(OBJ)
+$(PNGGEN)lpg89.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ)
+ $(SETMOD) $(PNGGEN)lpg89 $(PNGOBJ)pngwio.$(OBJ)
-$(PNGGEN)lpng90.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(ZGEN)crc32.dev
- $(SETMOD) $(PNGGEN)lpng90 $(PNGOBJ)pngwio.$(OBJ) -include $(ZGEN)crc32
+$(PNGGEN)lpg90.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg90 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
-$(PNGGEN)lpng95.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(ZGEN)crc32.dev
- $(SETMOD) $(PNGGEN)lpng95 $(PNGOBJ)pngwio.$(OBJ) -include $(ZGEN)crc32
+$(PNGGEN)lpg95.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg95 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
-$(PNGGEN)lpng96.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(ZGEN)crc32.dev
- $(SETMOD) $(PNGGEN)lpng96 $(PNGOBJ)pngwio.$(OBJ) -include $(ZGEN)crc32
+$(PNGGEN)lpg96.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg96 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
-$(PNGGEN)lpng101.dev: $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(ZGEN)crc32.dev
- $(SETMOD) $(PNGGEN)lpng101 $(PNGOBJ)pngwio.$(OBJ) -include $(ZGEN)crc32
+$(PNGGEN)lpg101.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg101 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
+
+$(PNGGEN)lpg102.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg102 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
+
+$(PNGGEN)lpg10001.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg10001 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
+
+$(PNGGEN)lpg10002.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg10002 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
+
+$(PNGGEN)lpg10003.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev
+ $(SETMOD) $(PNGGEN)lpg10003 $(PNGOBJ)pngwio.$(OBJ) -include $(PZGEN)crc32.dev
diff --git a/gs/src/main.h b/gs/src/main.h
index cccfce176..44b68688e 100644
--- a/gs/src/main.h
+++ b/gs/src/main.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -87,6 +87,18 @@
#define gs_run_string_end(ue, pec, peo)\
gs_main_run_string_end(gs_main_instance_default(), ue, pec, peo)
+/* ---------------- Debugging ---------------- */
+
+/*
+ * We should have the following definition:
+
+#define gs_debug_dump_stack(code, peo)\
+ gs_main_dump_stack(gs_main_instance_default(), code, peo)
+
+ * but we make it a procedure instead so it can be called from debuggers.
+ */
+void gs_debug_dump_stack(P2(int code, ref * perror_object));
+
/* ---------------- Termination ---------------- */
#define gs_finit(status, code)\
diff --git a/gs/src/md5.c b/gs/src/md5.c
new file mode 100644
index 000000000..0dbff594d
--- /dev/null
+++ b/gs/src/md5.c
@@ -0,0 +1,388 @@
+/*
+ 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
+
+ */
+/*
+ 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 ansi2knr is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 1999-05-03 lpd Original version.
+ */
+
+
+#include "md5.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.
+ */
+#include <string.h>
+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 <math.h>
+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/gs/src/md5.h b/gs/src/md5.h
new file mode 100644
index 000000000..1d3b6e444
--- /dev/null
+++ b/gs/src/md5.h
@@ -0,0 +1,79 @@
+/*
+ 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
+
+ */
+/*
+ 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 ansi2knr is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 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;
+
+/* 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
+
+#endif /* md5_INCLUDED */
diff --git a/gs/src/memory_.h b/gs/src/memory_.h
index 9291660a4..ac1a411e1 100644
--- a/gs/src/memory_.h
+++ b/gs/src/memory_.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -70,32 +70,50 @@ extern bcopy(), bcmp(), bzero();
# define memcpy(dest,src,len) bcopy(src,dest,len)
# define memcmp(b1,b2,len) bcmp(b1,b2,len)
/* Define our own versions of missing routines (in gsmisc.c). */
-# define memory__need_memmove
-# define memmove(dest,src,len) gs_memmove(dest,src,len)
+# define MEMORY__NEED_MEMMOVE
# include <sys/types.h> /* for size_t */
-void *gs_memmove(P3(void *, const void *, size_t));
-
-# define memory__need_memset
-# define memset(dest,ch,len) gs_memset(dest,ch,len)
-void *gs_memset(P3(void *, int, size_t));
-
+# define MEMORY__NEED_MEMSET
# if defined(UTEK)
-# define memory__need_memchr
-# define memchr(ptr,ch,len) gs_memchr(ptr,ch,len)
-const char *gs_memchr(P3(const void *, int, size_t));
-
+# define MEMORY__NEED_MEMCHR
# endif /* UTEK */
# else
# include <memory.h>
# if defined(__SVR3) || defined(sun) /* Not sure this is right.... */
-# define memory__need_memmove
-# define memmove(dest,src,len) gs_memmove(dest,src,len)
+# define MEMORY__NEED_MEMMOVE
# include <sys/types.h> /* for size_t */
-void *gs_memmove(P3(void *, const void *, size_t));
-
# endif /* __SVR3 or sun */
# endif /* BSD4_2 or UTEK */
# endif /* VMS, POSIX, ... */
#endif /* !__TURBOC__ */
+/*
+ * If we are profiling, substitute our own versions of memset, memcpy,
+ * and memmove, in case profiling libraries aren't available.
+ */
+#ifdef PROFILE
+# define MEMORY__NEED_MEMCPY
+# define MEMORY__NEED_MEMMOVE
+# define MEMORY__NEED_MEMSET
+#endif
+
+/* Declare substitutes for library procedures we supply. */
+#ifdef MEMORY__NEED_MEMMOVE
+# define memmove(dest,src,len) gs_memmove(dest,src,len)
+void *gs_memmove(P3(void *, const void *, size_t));
+#endif
+#ifdef MEMORY__NEED_MEMCPY
+# define memcpy(dest,src,len) gs_memcpy(dest,src,len)
+void *gs_memcpy(P3(void *, const void *, size_t));
+#endif
+#ifdef MEMORY__NEED_MEMSET
+# define memset(dest,ch,len) gs_memset(dest,ch,len)
+void *gs_memset(P3(void *, int, size_t));
+#endif
+#ifdef MEMORY__NEED_MEMCHR
+# define memchr(ptr,ch,len) gs_memchr(ptr,ch,len)
+void *gs_memchr(P3(const void *, int, size_t));
+#endif
+
+
+
#endif /* memory__INCLUDED */
diff --git a/gs/src/msvc32.mak b/gs/src/msvc32.mak
index 3fe4a79ad..15bf59e42 100644
--- a/gs/src/msvc32.mak
+++ b/gs/src/msvc32.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991-1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -21,11 +21,12 @@
# All configurable options are surrounded by !ifndef/!endif to allow
# preconfiguration from within another makefile.
#
-# Optimization /O2 seems OK with MSVC++ 4.1 & 5.0.
+# Optimization /O2 seems OK with MSVC++ 4.1, but not with 5.0.
# Created 1997-01-24 by Russell Lang from MSVC++ 2.0 makefile.
# Enhanced 97-05-15 by JD
# Common code factored out 1997-05-22 by L. Peter Deutsch.
# Made pre-configurable by JD 6/4/98
+# Revised to use subdirectories 1998-11-13 by lpd.
# ------------------------------- Options ------------------------------- #
@@ -46,7 +47,7 @@ GS_DOCDIR=c:/gs
# illegal escape.
!ifndef GS_LIB_DEFAULT
-GS_LIB_DEFAULT=.;c:/gs;c:/gs/fonts
+GS_LIB_DEFAULT=.;c:/gs/lib;c:/gs/fonts
!endif
# Define whether or not searching for initialization files should always
@@ -114,39 +115,33 @@ GSDLL=gsdll32
MAKEDLL=1
!endif
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-# If only one of PSSRCDIR or GLSRCDIR defined, use the other as default.
-# If neither defined, use .\
-!ifdef GLSRCDIR
-!elseifdef PSSRCDIR
-GLSRCDIR=$(PSSRCDIR)
-!else
-GLSRCDIR=.
+!ifndef BINDIR
+BINDIR=.\bin
!endif
-!ifndef PSSRCDIR
-PSSRCDIR=$(GLSRCDIR)
+!ifndef GLSRCDIR
+GLSRCDIR=.\src
!endif
-
-# If only one of PSOBJDIR or GLOBJDIR defined, use the other as default.
-# If neither defined, use .\obj
-!ifdef GLOBJDIR
-!elseifdef PSOBJDIR
-GLOBJDIR=$(PSOBJDIR)
-!else
+!ifndef GLGENDIR
+GLGENDIR=.\obj
+!endif
+!ifndef GLOBJDIR
GLOBJDIR=.\obj
!endif
-!ifndef PSOBJDIR
-PSOBJDIR=$(GLOBJDIR)
+!ifndef PSSRCDIR
+PSSRCDIR=.\src
!endif
-
-# If GLGENDIR undef'd, make = GLOBJDIR. If PSGENDIR undef'd, make = PSOBJDIR.
-!ifndef GLGENDIR
-GLGENDIR=$(GLOBJDIR)
+!ifndef PSLIBDIR
+PSLIBDIR=.\lib
!endif
!ifndef PSGENDIR
-PSGENDIR=$(PSOBJDIR)
+PSGENDIR=.\obj
+!endif
+!ifndef PSOBJDIR
+PSOBJDIR=.\obj
!endif
# Define the directory where the IJG JPEG library sources are stored,
@@ -166,7 +161,7 @@ JVERSION=6
!ifndef PSRCDIR
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
!endif
# Define the directory where the zlib sources are stored.
@@ -176,23 +171,24 @@ PVERSION=96
ZSRCDIR=zlib
!endif
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-!ifndef CONFIG
-CONFIG=
-!endif
-
# Define any other compilation flags.
!ifndef CFLAGS
CFLAGS=
!endif
-# Define the name of the makefile -- used in dependencies.
+# Do not edit the next group of lines.
-!ifndef MAKEFILE
-MAKEFILE=$(GLSRCDIR)\msvc32.mak
-!endif
+#!include $(COMMONDIR)\msvcdefs.mak
+#!include $(COMMONDIR)\pcdefs.mak
+#!include $(COMMONDIR)\generic.mak
+!include $(GLSRCDIR)\version.mak
+# The following is a hack to get around the special treatment of \ at
+# the end of a line.
+NUL=
+DD=$(GLGENDIR)\$(NUL)
+GLD=$(GLGENDIR)\$(NUL)
+PSD=$(PSGENDIR)\$(NUL)
# ------ Platform-specific options ------ #
@@ -200,7 +196,7 @@ MAKEFILE=$(GLSRCDIR)\msvc32.mak
# (currently, 4 & 5 are supported).
!ifndef MSVC_VERSION
-MSVC_VERSION = 5
+MSVC_VERSION=5
!endif
# Define the drive, directory, and compiler name for the Microsoft C files.
@@ -221,13 +217,26 @@ DEVSTUDIO=c:\msdev
! endif
COMPBASE=$(DEVSTUDIO)
SHAREDBASE=$(DEVSTUDIO)
-!else
+!endif
+
+!if $(MSVC_VERSION) == 5
! ifndef DEVSTUDIO
-DEVSTUDIO=c:\devstudio
+#DEVSTUDIO=c:\program files\devstudio
+DEVSTUDIO=c:\progra~1\devstu~1
! endif
COMPBASE=$(DEVSTUDIO)\VC
SHAREDBASE=$(DEVSTUDIO)\SharedIDE
!endif
+
+!if $(MSVC_VERSION) == 6
+! ifndef DEVSTUDIO
+#DEVSTUDIO=c:\program files\microsoft visual studio
+DEVSTUDIO=c:\progra~1\micros~2
+! endif
+COMPBASE=$(DEVSTUDIO)\VC98
+SHAREDBASE=$(DEVSTUDIO)\Common\MSDev98
+!endif
+
COMPDIR=$(COMPBASE)\bin
LINKDIR=$(COMPBASE)\bin
RCDIR=$(SHAREDBASE)\bin
@@ -278,12 +287,20 @@ FPU_TYPE=0
!endif
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+!ifndef SYNC
+SYNC=winsync
+!endif
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
!ifndef FEATURE_DEVS
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
!endif
# Choose whether to compile the .ps initialization files into the executable.
@@ -319,21 +336,27 @@ FILE_IMPLEMENTATION=stdio
# devs.mak and contrib.mak for the list of available devices.
!ifndef DEVICE_DEVS
-DEVICE_DEVS=mswindll.dev mswinprn.dev mswinpr2.dev
-DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev lbp8.dev uniprint.dev
-DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev m8510.dev necp6.dev bjc600.dev bjc800.dev
-DEVICE_DEVS7=t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev
-DEVICE_DEVS8=pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev pcxcmyk.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
-DEVICE_DEVS14=jpeg.dev jpeggray.dev
-DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+DEVICE_DEVS=$(DD)mswindll.dev $(DD)mswinprn.dev $(DD)mswinpr2.dev
+DEVICE_DEVS2=$(DD)epson.dev $(DD)eps9high.dev $(DD)eps9mid.dev $(DD)epsonc.dev $(DD)ibmpro.dev
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev
+DEVICE_DEVS5=$(DD)djet500c.dev $(DD)declj250.dev $(DD)lj250.dev
+DEVICE_DEVS6=$(DD)st800.dev $(DD)stcolor.dev $(DD)bj10e.dev $(DD)bj200.dev
+DEVICE_DEVS7=$(DD)t4693d2.dev $(DD)t4693d4.dev $(DD)t4693d8.dev $(DD)tek4696.dev
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)bmpmono.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+# Overflow for DEVS3,4,5,6,9
+DEVICE_DEVS16=$(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS17=$(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS18=$(DD)jetp3852.dev $(DD)r4081.dev $(DD)lbp8.dev $(DD)uniprint.dev
+DEVICE_DEVS19=$(DD)m8510.dev $(DD)necp6.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS20=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
!endif
# ---------------------------- End of options ---------------------------- #
@@ -353,6 +376,11 @@ FPU_TYPE=1
FPU_TYPE=1
!endif
+# Define the name of the makefile -- used in dependencies.
+
+MAKEFILE=$(GLSRCDIR)\msvc32.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\msvccmd.mak $(GLSRCDIR)\msvctail.mak $(GLSRCDIR)\winlib.mak $(GLSRCDIR)\winint.mak
+
# Define the files to be removed by `make clean'.
# nmake expands macros when encountered, not when used,
# so this must precede the !include statements.
@@ -366,10 +394,10 @@ BEGINFILES2=$(GLOBJDIR)\gs*32*.exp $(GLOBJDIR)\gs*32*.ilk $(GLOBJDIR)\gs*32*.pdb
# ----------------------------- Main program ------------------------------ #
-GSCONSOLE_XE=$(GLOBJ)$(GSCONSOLE).exe
-GSDLL_DLL=$(GLOBJ)$(GSDLL).dll
+GSCONSOLE_XE=$(BINDIR)\$(GSCONSOLE).exe
+GSDLL_DLL=$(BINDIR)\$(GSDLL).dll
-$(GLGEN)lib32.rsp: $(MAKEFILE)
+$(GLGEN)lib32.rsp: $(TOP_MAKEFILES)
echo /NODEFAULTLIB:LIBC.lib > $(GLGEN)lib32.rsp
echo $(LIBDIR)\libcmt.lib >> $(GLGEN)lib32.rsp
@@ -377,48 +405,48 @@ $(GLGEN)lib32.rsp: $(MAKEFILE)
# The graphical small EXE loader
$(GS_XE): $(GSDLL_DLL) $(DWOBJ) $(GSCONSOLE_XE)
echo /SUBSYSTEM:WINDOWS > $(GLGEN)gswin32.rsp
- echo /DEF:$(GLSRC)dwmain32.def /OUT:$(GS_XE) >> $(GLGEN)gswin32.rsp
- $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(DWOBJ) @$(LIBCTR) $(GLOBJ)$(GS).res
+ echo /DEF:$(GLSRCDIR)\dwmain32.def /OUT:$(GS_XE) >> $(GLGEN)gswin32.rsp
+ $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(DWOBJ) @$(LIBCTR) $(GS_OBJ).res
del $(GLGEN)gswin32.rsp
# The console mode small EXE loader
-$(GSCONSOLE_XE): $(OBJC) $(GLOBJ)$(GS).res $(GLSRC)dw32c.def
+$(GSCONSOLE_XE): $(OBJC) $(GS_OBJ).res $(GLSRCDIR)\dw32c.def
echo /SUBSYSTEM:CONSOLE > $(GLGEN)gswin32.rsp
- echo /DEF:$(GLSRC)dw32c.def /OUT:$(GSCONSOLE_XE) >> $(GLGEN)gswin32.rsp
+ echo /DEF:$(GLSRCDIR)\dw32c.def /OUT:$(GSCONSOLE_XE) >> $(GLGEN)gswin32.rsp
$(LINK_SETUP)
- $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(OBJC) @$(LIBCTR) $(GLOBJ)$(GS).res
+ $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(OBJC) @$(LIBCTR) $(GS_OBJ).res
del $(GLGEN)gswin32.rsp
# The big DLL
-$(GSDLL_DLL): $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(GLOBJ)$(GSDLL).res $(GLGEN)lib32.rsp
- echo /DLL /DEF:$(GLSRC)gsdll32.def /OUT:$(GSDLL_DLL) > $(GLGEN)gswin32.rsp
+$(GSDLL_DLL): $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(GSDLL_OBJ).res $(GLGEN)lib32.rsp
+ echo /DLL /DEF:$(GLSRCDIR)\gsdll32.def /OUT:$(GSDLL_DLL) > $(GLGEN)gswin32.rsp
$(LINK_SETUP)
- $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(ld_tr) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp @$(LIBCTR) $(GLOBJ)$(GSDLL).res
+ $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(ld_tr) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp @$(LIBCTR) $(GSDLL_OBJ).res
del $(GLGEN)gswin32.rsp
!else
# The big graphical EXE
-$(GS_XE): $(GSCONSOLE_XE) $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(DWOBJNO) $(GLOBJ)$(GS).res $(GLSRC)dwmain32.def $(GLGEN)lib32.rsp
+$(GS_XE): $(GSCONSOLE_XE) $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(DWOBJNO) $(GSDLL_OBJ).res $(GLSRCDIR)\dwmain32.def $(GLGEN)lib32.rsp
copy $(ld_tr) $(GLGEN)gswin32.tr
echo $(GLOBJ)dwnodll.obj >> $(GLGEN)gswin32.tr
echo $(GLOBJ)dwimg.obj >> $(GLGEN)gswin32.tr
echo $(GLOBJ)dwmain.obj >> $(GLGEN)gswin32.tr
echo $(GLOBJ)dwtext.obj >> $(GLGEN)gswin32.tr
- echo /DEF:$(GLSRC)dwmain32.def /OUT:$(GS_XE) > $(GLGEN)gswin32.rsp
+ echo /DEF:$(GLSRCDIR)\dwmain32.def /OUT:$(GS_XE) > $(GLGEN)gswin32.rsp
$(LINK_SETUP)
- $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(GLGEN)gswin32.tr @$(LIBCTR) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp $(GLOBJ)$(GSDLL).res
+ $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(GLGEN)gswin32.tr @$(LIBCTR) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp $(GSDLL_OBJ).res
del $(GLGEN)gswin32.tr
del $(GLGEN)gswin32.rsp
# The big console mode EXE
-$(GSCONSOLE_XE): $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(OBJCNO) $(GLOBJ)$(GS).res $(GLSRC)dw32c.def $(GLGEN)lib32.rsp
+$(GSCONSOLE_XE): $(GS_ALL) $(DEVS_ALL) $(GLOBJ)gsdll.$(OBJ) $(OBJCNO) $(GS_OBJ).res $(GLSRCDIR)\dw32c.def $(GLGEN)lib32.rsp
copy $(ld_tr) $(GLGEN)gswin32c.tr
echo $(GLOBJ)dwnodllc.obj >> $(GLGEN)gswin32c.tr
echo $(GLOBJ)dwmainc.obj >> $(GLGEN)gswin32c.tr
echo /SUBSYSTEM:CONSOLE > $(GLGEN)gswin32.rsp
- echo /DEF:$(GLSRC)dw32c.def /OUT:$(GSCONSOLE_XE) >> $(GLGEN)gswin32.rsp
+ echo /DEF:$(GLSRCDIR)\dw32c.def /OUT:$(GSCONSOLE_XE) >> $(GLGEN)gswin32.rsp
$(LINK_SETUP)
- $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(GLGEN)gswin32c.tr @$(LIBCTR) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp $(GLOBJ)$(GS).res
+ $(LINK) $(LCT) @$(GLGEN)gswin32.rsp $(GLOBJ)gsdll @$(GLGEN)gswin32c.tr @$(LIBCTR) $(INTASM) @$(GLGEN)lib.tr @$(GLGEN)lib32.rsp $(GS_OBJ).res
del $(GLGEN)gswin32.rsp
del $(GLGEN)gswin32c.tr
!endif
diff --git a/gs/src/msvccmd.mak b/gs/src/msvccmd.mak
index 8b435f6bf..6fd64045d 100644
--- a/gs/src/msvccmd.mak
+++ b/gs/src/msvccmd.mak
@@ -61,9 +61,7 @@ CCAUX_TAIL= /link $(LINK_LIB_SWITCH)
D=\#
-EXPP=
SH=
-SHP=
O_=-Fo
# Define the arguments for genconf.
@@ -147,7 +145,9 @@ COMPILE_WITHOUT_FRAMES= # no optimization when debugging
!else
CT=
LCT=$(LINK_LIB_SWITCH)
-COMPILE_FULL_OPTIMIZED=/O2
+# NOTE: With MSVC++ 5.0, /O2 produces a non-working executable.
+# We believe the following list of optimizations works around this bug.
+COMPILE_FULL_OPTIMIZED=/GF /Ot /Oi /Ob2 /Oy /Oa- /Ow-
COMPILE_WITH_FRAMES=
COMPILE_WITHOUT_FRAMES=/Oy
!endif
diff --git a/gs/src/msvclib.mak b/gs/src/msvclib.mak
index 3de43a59b..6f7fe827f 100644
--- a/gs/src/msvclib.mak
+++ b/gs/src/msvclib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991-1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -93,18 +93,21 @@ NOPRIVATE=0
GS=gslib
!endif
-# Define the source, generated intermediate file, and object directories
-# for the graphics library (GL).
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
+# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-# This is a bad joke. This makefile won't work with any other values!
+!ifndef BINDIR
+BINDIR=.\bin
+!endif
!ifndef GLSRCDIR
-GLSRCDIR=.
+GLSRCDIR=.\src
!endif
!ifndef GLGENDIR
-GLGENDIR=.
+GLGENDIR=.\obj
!endif
!ifndef GLOBJDIR
-GLOBJDIR=.
+GLOBJDIR=.\obj
!endif
# Define the directory where the IJG JPEG library sources are stored,
@@ -124,7 +127,7 @@ JVERSION=6
!ifndef PSRCDIR
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
!endif
# Define the directory where the zlib sources are stored.
@@ -134,12 +137,6 @@ PVERSION=96
ZSRCDIR=zlib
!endif
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-!ifndef CONFIG
-CONFIG=
-!endif
-
# Define any other compilation flags.
!ifndef CFLAGS
@@ -229,6 +226,14 @@ FPU_TYPE=0
!endif
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+!ifndef SYNC
+SYNC=winsync
+!endif
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
@@ -270,6 +275,7 @@ FILE_IMPLEMENTATION=stdio
# devs.mak and contrib.mak for the list of available devices.
!ifndef DEVICE_DEVS
DEVICE_DEVS=ljet2p.dev bbox.dev
+DEVICE_DEVS1=
DEVICE_DEVS2=
DEVICE_DEVS3=
DEVICE_DEVS4=
@@ -282,7 +288,13 @@ DEVICE_DEVS10=
DEVICE_DEVS11=
DEVICE_DEVS12=
DEVICE_DEVS13=
+DEVICE_DEVS14=
DEVICE_DEVS15=
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
!endif
# ---------------------------- End of options ---------------------------- #
@@ -304,8 +316,8 @@ FPU_TYPE=1
# Define the name of the makefile -- used in dependencies.
-# The use of multiple file names here is garbage!
-MAKEFILE=$(GLSRCDIR)\msvclib.mak $(GLSRCDIR)\msvccmd.mak $(GLSRCDIR)\msvctail.mak $(GLSRCDIR)\winlib.mak
+MAKEFILE=$(GLSRCDIR)\msvclib.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\msvccmd.mak $(GLSRCDIR)\msvctail.mak $(GLSRCDIR)\winlib.mak
# Define the files to be removed by `make clean'.
# nmake expands macros when encountered, not when used,
@@ -336,10 +348,9 @@ $(GLOBJ)gp_mslib.$(OBJ): $(GLSRC)gp_mslib.c $(AK)
mslib32__=$(GLOBJ)gp_mslib.$(OBJ)
-mslib32_.dev: $(mslib32__) $(ECHOGS_XE) msw32nc_.dev
- $(SETMOD) mslib32_ $(mslib32__)
- $(ADDMOD) mslib32_ -include msw32nc_
-
+$(GLGEN)mslib32_.dev: $(mslib32__) $(ECHOGS_XE) $(GLGEN)msw32nc_.dev
+ $(SETMOD) $(GLGEN)mslib32_ $(mslib32__)
+ $(ADDMOD) $(GLGEN)mslib32_ -include $(GLGEN)msw32nc_.dev
# ----------------------------- Main program ------------------------------ #
diff --git a/gs/src/msvctail.mak b/gs/src/msvctail.mak
index f0e3eeff8..77858aa02 100644
--- a/gs/src/msvctail.mak
+++ b/gs/src/msvctail.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -24,7 +24,7 @@
# -------------------------- Auxiliary programs --------------------------- #
-$(GLGENDIR)\ccf32.tr: $(MAKEFILE)
+$(GLGENDIR)\ccf32.tr: $(TOP_MAKEFILES)
echo $(GENOPT) /I$(INCDIR) -DCHECK_INTERRUPTS -D_Windows -D__WIN32__ > $(GLGENDIR)\ccf32.tr
$(ECHOGS_XE): $(GLSRC)echogs.c
@@ -33,22 +33,27 @@ $(ECHOGS_XE): $(GLSRC)echogs.c
# Don't create genarch if it's not needed
!ifdef GENARCH_XE
-$(GENARCH_XE): $(GLSRC)genarch.c $(stdpre_h) $(iref_h) $(GLGENDIR)\ccf32.tr
+$(GENARCH_XE): $(GLSRC)genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr
$(CCAUX_SETUP)
$(CCAUX) @$(GLGENDIR)\ccf32.tr /Fo$(GLOBJ)genarch.obj /Fe$(GENARCH_XE) $(GLSRC)genarch.c $(CCAUX_TAIL)
!endif
-$(GENCONF_XE): $(GLSRC)genconf.c $(stdpre_h)
+$(GENCONF_XE): $(GLSRC)genconf.c $(GENCONF_DEPS)
$(CCAUX_SETUP)
$(CCAUX) $(GLSRC)genconf.c /Fo$(GLOBJ)genconf.obj /Fe$(GENCONF_XE) $(CCAUX_TAIL)
-$(GENDEV_XE): $(GLSRC)gendev.c $(stdpre_h)
+$(GENDEV_XE): $(GLSRC)gendev.c $(GENDEV_DEPS)
$(CCAUX_SETUP)
$(CCAUX) $(GLSRC)gendev.c /Fo$(GLOBJ)gendev.obj /Fe$(GENDEV_XE) $(CCAUX_TAIL)
-$(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
+$(GENHT_XE): $(GLSRC)genht.c $(GENHT_DEPS)
$(CCAUX_SETUP)
- $(CCAUX) $(PSSRC)geninit.c /Fo$(GLOBJ)geninit.obj /Fe$(GENINIT_XE) $(CCAUX_TAIL)
+ $(CCAUX) $(GENHT_CFLAGS) $(GLSRC)genht.c /Fo$(GLOBJ)genht.obj /Fe$(GENHT_XE) $(CCAUX_TAIL)
+
+# PSSRC and PSOBJ aren't defined yet, so we spell out the definitions.
+$(GENINIT_XE): $(PSSRCDIR)$(D)geninit.c $(GENINIT_DEPS)
+ $(CCAUX_SETUP)
+ $(CCAUX) $(PSSRCDIR)$(D)geninit.c /Fo$(PSOBJDIR)$(D)geninit.obj /Fe$(GENINIT_XE) $(CCAUX_TAIL)
# -------------------------------- Library -------------------------------- #
@@ -58,7 +63,7 @@ $(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
LIBCTR=$(GLGEN)libc32.tr
-$(LIBCTR): $(MAKEFILE)
+$(LIBCTR): $(TOP_MAKEFILES)
echo $(LIBDIR)\shell32.lib >$(LIBCTR)
echo $(LIBDIR)\comdlg32.lib >>$(LIBCTR)
echo $(LIBDIR)\gdi32.lib >>$(LIBCTR)
diff --git a/gs/src/mv.bat b/gs/src/mv.bat
new file mode 100755
index 000000000..8b2dfeb24
--- /dev/null
+++ b/gs/src/mv.bat
@@ -0,0 +1,2 @@
+
+@rename %1 %2
diff --git a/gs/src/opdef.h b/gs/src/opdef.h
index b12e721d2..5cc36f811 100644
--- a/gs/src/opdef.h
+++ b/gs/src/opdef.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,20 +23,13 @@
# define opdef_INCLUDED
/*
- * Operator procedures take the pointer to the top of the o-stack
- * as their argument. They return 0 for success, a negative code
- * for an error, or a positive code for some uncommon situations (see below).
- */
-
-/*
* Define the structure for initializing the operator table. Each operator
* file zxxx.c declares an array of these as follows:
- const op_def * const zxxx_op_defs[] =
- {
- {"1name", zname},
- ...
- op_def_end(iproc)
+ const op_def * const zxxx_op_defs[] = {
+ {"1name", zname},
+ ...
+ op_def_end(iproc)
};
* where iproc is an initialization procedure for the file, or 0. This
@@ -45,8 +38,8 @@
* compatibility with an older convention, we also allow (deprecated)
BEGIN_OP_DEFS(my_defs) {
- {"1name", zname},
- ...
+ {"1name", zname},
+ ...
END_OP_DEFS(iproc) }
* Operators may be stored in dictionaries other than systemdict.
@@ -57,7 +50,7 @@
*/
typedef struct {
const char *oname;
- op_proc_p proc;
+ op_proc_t proc;
} op_def;
#define op_def_begin_dict(dname) {dname, 0}
@@ -65,7 +58,17 @@ typedef struct {
#define op_def_begin_level2() op_def_begin_dict("level2dict")
#define op_def_begin_ll3() op_def_begin_dict("ll3dict")
#define op_def_is_begin_dict(def) ((def)->proc == 0)
-#define op_def_end(iproc) {0, (op_proc_p)iproc}
+#define op_def_end(iproc) {0, iproc}
+
+/*
+ * NOTE: for implementation reasons, a single table of operator definitions
+ * is limited to 16 entries, including op_def_begin_xxx entries. If a file
+ * defines more operators than this, it must split them into multiple
+ * tables and have multiple -oper entries in the makefile. Currently,
+ * only 4 out of 85 operator files require this.
+ */
+#define OP_DEFS_LOG2_MAX_SIZE 4
+#define OP_DEFS_MAX_SIZE (1 << OP_DEFS_LOG2_MAX_SIZE)
/*
* Define the table of pointers to all operator definition tables.
@@ -114,17 +117,22 @@ ushort op_find_index(P1(const ref *));
#define op_index(opref)\
(r_size(opref) == 0 ? op_find_index(opref) : r_size(opref))
+
/*
* There are actually two kinds of operators: the real ones (t_operator),
* and ones defined by procedures (t_oparray). The catalog for t_operators
- * is op_def_table, and their index is in the range [1..op_def_count-1].
+ * is (indirectly) op_defs_all, and their index is in the range
+ * [1..op_def_count-1].
*/
#define op_index_is_operator(index) ((index) < op_def_count)
-extern const op_def **op_def_table;
-extern uint op_def_count;
+extern const uint op_def_count;
+
+#define op_index_def(index)\
+ (&op_defs_all[(index) >> OP_DEFS_LOG2_MAX_SIZE]\
+ [(index) & (OP_DEFS_MAX_SIZE - 1)])
+#define op_num_args(opref) (op_index_def(op_index(opref))->oname[0] - '0')
+#define op_index_proc(index) (op_index_def(index)->proc)
-#define op_num_args(opref) (op_def_table[op_index(opref)]->oname[0] - '0')
-#define op_index_proc(index) (op_def_table[index]->proc)
/*
* There are two catalogs for t_oparrays, one global and one local.
* Operator indices for the global table are in the range
diff --git a/gs/src/openvms.mak b/gs/src/openvms.mak
index aa5c70621..5737b19f5 100644
--- a/gs/src/openvms.mak
+++ b/gs/src/openvms.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -27,15 +27,30 @@
# on the make command line specify:
# make -fopenvms.mak "OPENVMS={VAX,ALPHA}" "DECWINDOWS={1.2,<blank>}"
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
+# NOTE: If you use GNU make, GLGENDIR and PSGENDIR must not be the
+# current directory ([]).
-GLSRCDIR=[]
-GLGENDIR=[]
-GLOBJDIR=[]
-PSSRCDIR=[]
-PSGENDIR=[]
-PSOBJDIR=[]
+BINDIR=[.bin]
+GLSRCDIR=[.src]
+GLGENDIR=[.obj]
+GLOBJDIR=[.obj]
+PSSRCDIR=[.src]
+PSLIBDIR=[.lib]
+PSGENDIR=[.obj]
+PSOBJDIR=[.obj]
+
+# Do not edit the next group of lines.
+
+#include $(COMMONDIR)/vmscdefs.mak
+#include $(COMMONDIR)/vmsdefs.mak
+#include $(COMMONDIR)/generic.mak
+include $(GLSRCDIR)version.mak
+DD=$(GLGENDIR)
+GLD=$(GLGENDIR)
+PSD=$(PSGENDIR)
# ------ Generic options ------ #
@@ -89,7 +104,7 @@ GS=GS
# You may need to change this if the IJG library version changes.
# See jpeg.mak for more information.
-JSRCDIR=[.jpeg-6a]
+JSRCDIR=[.jpeg-6b]
JVERSION=6
# Define the directory where the PNG library sources are stored,
@@ -97,13 +112,13 @@ JVERSION=6
# You may need to change this if the libpng version changes.
# See libpng.mak for more information.
-PSRCDIR=[.libpng-0_96]
-PVERSION=96
+PSRCDIR=[.libpng-1_0_3]
+PVERSION=10003
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
-ZSRCDIR=[.zlib-1_0_4]
+ZSRCDIR=[.zlib-1_1_3]
# Note that built-in third-party libraries aren't available.
@@ -111,10 +126,6 @@ SHARE_JPEG=0
SHARE_LIBPNG=0
SHARE_ZLIB=0
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# Define the path to X11 include files
X_INCLUDE=DECW$$INCLUDE
@@ -147,7 +158,7 @@ endif
# LINK is the full linker path name
-ifdef LDEBUG
+ifdef TDEBUG
LINKER=LINK/DEBUG/TRACEBACK
else
LINKER=LINK/NODEBUG/NOTRACEBACK
@@ -159,29 +170,43 @@ INCDIR=
# LIBDIR contains the library files
LIBDIR=
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
# ------ Devices and features ------ #
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-DEVICE_DEVS=x11.dev x11alpha.dev x11cmyk.dev x11mono.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=uniprint.dev
-DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev
-DEVICE_DEVS7=faxg3.dev faxg32d.dev faxg4.dev
-DEVICE_DEVS8=pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev pcxcmyk.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
-DEVICE_DEVS14=jpeg.dev jpeggray.dev
-DEVICE_DEVS15=pdfwrite.dev
+DEVICE_DEVS=$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
+#DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpamono.dev $(DD)posync.dev
+DEVICE_DEVS1=
+DEVICE_DEVS2=
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -219,6 +244,7 @@ PLATFORM=openvms_
# Define the name of the makefile -- used in dependencies.
MAKEFILE=$(GLSRCDIR)openvms.mak
+TOP_MAKEFILES=$(MAKEFILE)
# Define the platform options
@@ -241,6 +267,14 @@ CMD=
D=
+# Define the brackets for passing preprocessor definitions to the C compiler.
+
+NULL=
+
+D_=/DEFINE="
+_D_=$(NULL)=
+_D="
+
# Define the syntax of search paths for the C compiler.
# The OpenVMS compilers uses /INCLUDE=(dir1, dir2, ...dirn),
# and only a single /INCLUDE switch is allowed in the command line.
@@ -249,12 +283,6 @@ I_=/INCLUDE=(
II=,
_I=)
-# Define the syntax for compile command line defines
-# such as defining XYZZY to 0-1: $(D_)XYZZY$(_D_)0-1$(_D)
-D_=/DEFINE="
-_D_=$(NULL)=
-_D="
-
# Define the string for specifying the output file from the C compiler.
O_=/OBJECT=
@@ -277,17 +305,20 @@ BEGINFILES=OPENVMS.OPT OPENVMS.COM
CCA2K=
# Define the C invocation for auxiliary programs (echogs, genarch).
-# We don't need to define this separately.
-
-CCAUX=
+
+ifeq "$(OPENVMS)" "VAX"
+CCAUX=CC/VAXC
+else
+CCAUX=CC/DECC
+endif
# Define the C invocation for normal compilation.
-CC=$(COMP)/OBJECT=$@ $<
+CC=$(COMP)
# Define the Link invocation.
-LINK=$(LINKER)/MAP/EXE=$@ $^,OPENVMS.OPT/OPTION
+LINK=$(LINKER)/MAP/EXE=$@ $^,$(GLGENDIR)OPENVMS.OPT/OPTION
# Define the ANSI-to-K&R dependency. We don't need this.
@@ -297,27 +328,25 @@ AK=
OBJ=obj
-# Define the current directory prefix for image invocations.
+# Define the prefix for image invocations.
-EXPP=
-EXP=MCR []
+EXP=MCR $(NULL)
-# Define the current directory prefix for shell invocations.
+# Define the prefix for shell invocations.
SH=
-SHP=
# Define generic commands.
-CP_=$$ @COPY_ONE
+CP_=$$ @$(GLSRCDIR)COPY_ONE
# Define the command for deleting (a) file(s) (including wild cards)
-RM_=$$ @RM_ONE
+RM_=$$ @$(GLSRCDIR)RM_ONE
# Define the command for deleting multiple files / patterns.
-RMN_=$$ @RM_ALL
+RMN_=$$ @$(GLSRCDIR)RM_ALL
# Define the arguments for genconf.
@@ -339,10 +368,10 @@ CONFLDTR=-o
#include $(COMMONDIR)/ansidefs.mak
#include $(COMMONDIR)/vmsdefs.mak
#include $(COMMONDIR)/generic.mak
-include $(GLSRCDIR)version.mak
include $(GLSRCDIR)gs.mak
include $(GLSRCDIR)lib.mak
include $(PSSRCDIR)int.mak
+include $(PSSRCDIR)cfonts.mak
include $(GLSRCDIR)jpeg.mak
# zlib.mak must precede libpng.mak
include $(GLSRCDIR)zlib.mak
@@ -356,62 +385,91 @@ CC_=$(COMP)
CC_INT=$(CC_)
CC_LEAF=$(CC_)
-JI_=/INCLUDE=($(JSRCDIR))
-PI_=/INCLUDE=($(ZSRCDIR),$(PSRCDIR))
-ZI_=/INCLUDE=($(ZSRCDIR))
-
# ----------------------------- Main program ------------------------------ #
-$(GS_XE): openvms gs.$(OBJ) $(INT_ALL) $(LIB_ALL)
- $(LINKER)/MAP/EXE=$@ gs.$(OBJ),$(ld_tr)/OPTIONS,OPENVMS.OPT/OPTION
+$(GS_XE) : openvms $(GLOBJDIR)gs.$(OBJ) $(INT_ALL) $(LIB_ALL)
+ $(LINKER)/MAP=$(BINDIR)gs.map/EXE=$@ $(GLOBJ)gs.$(OBJ),$(ld_tr)/OPTIONS,$(GLGENDIR)OPENVMS.OPT/OPTION
# OpenVMS.dev
openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_vms.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ)
-openvms_.dev: $(openvms__) nosync.dev
- $(SETMOD) openvms_ $(openvms__) -include nosync
+$(GLGEN)openvms_.dev : $(openvms__) $(GLGEN)nosync.dev
+ $(SETMOD) $(GLGEN)openvms_ $(openvms__) -include $(GLGEN)nosync
+
+$(GLOBJ)gp_vms.$(OBJ) : $(GLSRC)gp_vms.c
+ $(CC_)/include=($(GLGENDIR),$(GLSRCDIR))/obj=$(GLOBJ)gp_vms.$(OBJ) $(GLSRC)gp_vms.c
# Interpreter AUX programs
-$(ECHOGS_XE): echogs.$(OBJ)
-$(GENARCH_XE): genarch.$(OBJ)
-$(GENCONF_XE): genconf.$(OBJ)
-$(GENDEV_XE): gendev.$(OBJ)
-$(GENINIT_XE): geninit.$(OBJ)
+$(ECHOGS_XE) : $(GLOBJ)echogs.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)echogs.$(OBJ)
+
+$(GLOBJ)echogs.$(OBJ) : $(GLSRC)echogs.c
+ $(CCAUX)/obj=$(GLOBJ)echogs.$(OBJ) $(GLSRC)echogs.c
+
+$(GENARCH_XE) : $(GLOBJ)genarch.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)genarch.$(OBJ)
+
+$(GLOBJ)genarch.$(OBJ) : $(GLSRC)genarch.c $(GENARCH_DEPS)
+ $(CCAUX)/obj=$(GLOBJ)genarch.$(OBJ) $(GLSRC)genarch.c
+
+$(GENCONF_XE) : $(GLOBJDIR)genconf.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)genconf.$(OBJ)
+
+$(GLOBJ)genconf.$(OBJ) : $(GLSRC)genconf.c $(GENCONF_DEPS)
+ $(CCAUX)/obj=$(GLOBJ)genconf.$(OBJ) $(GLSRC)genconf.c
+
+$(GENDEV_XE) : $(GLOBJDIR)gendev.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)gendev.$(OBJ)
+
+$(GLOBJ)gendev.$(OBJ) : $(GLSRC)gendev.c $(GENDEV_DEPS)
+ $(CCAUX)/obj=$(GLOBJ)gendev.$(OBJ) $(GLSRC)gendev.c
+
+$(GENHT_XE) : $(GLOBJDIR)genht.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)genht.$(OBJ)
+
+$(GLOBJ)genht.$(OBJ) : $(GLSRC)genht.c $(GENHT_DEPS)
+ $(CCAUX)/obj=$(GLOBJ)genht.$(OBJ) $(GENHT_CFLAGS) $(GLSRC)genht.c
+
+$(GENINIT_XE) : $(GLOBJDIR)geninit.$(OBJ)
+ LINK/EXE=$@ $(GLOBJ)geninit.$(OBJ)
+
+$(GLOBJ)geninit.$(OBJ) : $(GLSRC)geninit.c $(GENINIT_DEPS)
+ $(CCAUX)/obj=$(GLOBJ)geninit.$(OBJ) $(GLSRC)geninit.c
# Preliminary definitions
-openvms: openvms.com openvms.opt
- $$ @OPENVMS
+openvms : $(GLGENDIR)openvms.com $(GLGENDIR)openvms.opt
+ $$ @$(GLGENDIR)OPENVMS
-openvms.com: append_l.com
- $$ @APPEND_L $@ "$$ DEFINE/JOB X11 $(X_INCLUDE)"
- $$ @APPEND_L $@ "$$ DEFINE/JOB GS_LIB ''F$$ENVIRONMENT(""DEFAULT"")'"
- $$ @APPEND_L $@ "$$ DEFINE/JOB GS_DOC ''F$$ENVIRONMENT(""DEFAULT"")'"
+$(GLGENDIR)openvms.com : $(GLSRCDIR)append_l.com
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB X11 $(X_INCLUDE)"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB GS_LIB ''F$$ENVIRONMENT(""DEFAULT"")'"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB GS_DOC ''F$$ENVIRONMENT(""DEFAULT"")'"
ifeq "$(OPENVMS)" "VAX"
- $$ @APPEND_L $@ "$$ DEFINE/JOB C$$INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, SYS$$LIBRARY"
- $$ @APPEND_L $@ "$$ DEFINE/JOB VAXC$$INCLUDE C$$INCLUDE"
- $$ @APPEND_L $@ "$$ DEFINE/JOB SYS SYS$$LIBRARY"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB C$$INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, SYS$$LIBRARY"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB VAXC$$INCLUDE C$$INCLUDE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB SYS SYS$$LIBRARY"
else
- $$ @APPEND_L $@ "$$ DEFINE/JOB DECC$$USER_INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, DECC$$LIBRARY_INCLUDE, SYS$$LIBRARY"
- $$ @APPEND_L $@ "$$ DEFINE/JOB DECC$$SYSTEM_INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, DECC$$LIBRARY_INCLUDE, SYS$$LIBRARY"
- $$ @APPEND_L $@ "$$ DEFINE/JOB SYS "DECC$$LIBRARY_INCLUDE,SYS$$LIBRARY"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB DECC$$USER_INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, DECC$$LIBRARY_INCLUDE, SYS$$LIBRARY"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB DECC$$SYSTEM_INCLUDE ''F$$ENVIRONMENT(""DEFAULT"")', DECW$$INCLUDE, DECC$$LIBRARY_INCLUDE, SYS$$LIBRARY"
+ $$ @$(GLSRCDIR)APPEND_L $@ "$$ DEFINE/JOB SYS "DECC$$LIBRARY_INCLUDE,SYS$$LIBRARY"
endif
-openvms.opt:
+$(GLGENDIR)openvms.opt:
ifeq "$(OPENVMS)" "VAX"
- $$ @APPEND_L $@ "SYS$$SHARE:VAXCRTL.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:VAXCRTL.EXE/SHARE"
endif
ifeq "$(DECWINDOWS)" "1.2"
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XMLIBSHR12.EXE/SHARE"
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XTLIBSHRR5.EXE/SHARE"
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XLIBSHR.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XMLIBSHR12.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XTLIBSHRR5.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XLIBSHR.EXE/SHARE"
else
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XMLIBSHR.EXE/SHARE"
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XTSHR.EXE/SHARE"
- $$ @APPEND_L $@ "SYS$$SHARE:DECW$$XLIBSHR.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XMLIBSHR.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XTSHR.EXE/SHARE"
+ $$ @$(GLSRCDIR)APPEND_L $@ "SYS$$SHARE:DECW$$XLIBSHR.EXE/SHARE"
endif
- $$ @APPEND_L $@ ""Ident="""""GS $(GS_DOT_VERSION)"""""
+ $$ @$(GLSRCDIR)APPEND_L $@ ""Ident="""""GS $(GS_DOT_VERSION)"""""
# The platform-specific makefiles must also include rules for creating
# certain dynamically generated files:
@@ -423,10 +481,10 @@ endif
# and configuration-specific features derived from definitions
# in the platform-specific makefile.
-$(gconfig__h): $(MAKEFILE) $(ECHOGS_XE)
+$(gconfig__h) : $(TOP_MAKEFILES) $(ECHOGS_XE)
$(EXP)$(ECHOGS_XE) -w $(gconfig__h) -x 23 define "HAVE_SYS_TIME_H"
-$(gconfigv_h): $(MAKEFILE) $(ECHOGS_XE)
+$(gconfigv_h) : $(TOP_MAKEFILES) $(ECHOGS_XE)
$(EXP)$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define "USE_ASM" 0
$(EXP)$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define "USE_FPU" 1
$(EXP)$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define "EXTEND_NAMES" 0$(EXTEND_NAMES)
diff --git a/gs/src/openvms.mmk b/gs/src/openvms.mmk
new file mode 100644
index 000000000..b319c9c51
--- /dev/null
+++ b/gs/src/openvms.mmk
@@ -0,0 +1,488 @@
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+#
+# This file is part of Aladdin Ghostscript.
+#
+# Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+# or distributor accepts any responsibility for the consequences of using it,
+# or for whether it serves any particular purpose or works at all, unless he
+# or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+# License (the "License") for full details.
+#
+# Every copy of Aladdin Ghostscript must include a copy of the License,
+# normally in a plain ASCII text file named PUBLIC. The License grants you
+# the right to copy, modify and redistribute Aladdin Ghostscript, but only
+# under certain conditions described in the License. Among other things, the
+# License requires that the copyright notice and this notice be preserved on
+# all copies.
+
+
+# makefile for OpenVMS VAX and Alpha using MMK
+#
+# Please contact Jim Dunham (dunham@omtool.com) if you have questions.
+# Addapted for MMK by Jouk Jansen (joukj@crys.chem.uva.nl)
+#
+# ------------------------------- Options ------------------------------- #
+
+###### This section is the only part of the file you should need to edit.
+
+# on the make command line specify:
+# mmk/descrip=[.src]openvms.mmk/macro=("VAXC={0,1}","DECWINDOWS1_2={0,1}")
+
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
+# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
+
+BINDIR=[.bin]
+GLSRCDIR=[.src]
+GLGENDIR=[.obj]
+GLOBJDIR=[.obj]
+PSSRCDIR=[.src]
+PSGENDIR=[.obj]
+PSOBJDIR=[.obj]
+
+# create directories
+.first
+ if f$search("BIN.DIR") .eqs. "" then create/directory [.bin]
+ if f$search("OBJ.DIR") .eqs. "" then create/directory [.obj]
+
+# Do not edit the next group of lines.
+
+#.include $(COMMONDIR)vmscdefs.mak
+#.include $(COMMONDIR)vmsdefs.mak
+#.include $(COMMONDIR)generic.mak
+.include $(GLSRCDIR)version.mak
+DD=$(GLGENDIR)
+GLD=$(GLGENDIR)
+PSD=$(PSGENDIR)
+
+# ------ Generic options ------ #
+
+# Define the directory that will hold documentation at runtime.
+
+GS_DOCDIR=GS_DOC
+#GS_DOCDIR=SYS$COMMON:[GS]
+
+# Define the default directory/ies for the runtime
+# initialization and font files. Separate multiple directories with ,.
+
+GS_LIB_DEFAULT=GS_LIB
+#GS_LIB_DEFAULT=SYS$COMMON:[GS],SYS$COMMON:[GS.FONT]
+
+# Define whether or not searching for initialization files should always
+# look in the current directory first. This leads to well-known security
+# and confusion problems, but users insist on it.
+# NOTE: this also affects searching for files named on the command line:
+# see the "File searching" section of Use.htm for full details.
+# Because of this, setting SEARCH_HERE_FIRST to 0 is not recommended.
+
+SEARCH_HERE_FIRST=1
+
+# Define the name of the interpreter initialization file.
+# (There is no reason to change this.)
+
+GS_INIT=GS_INIT.PS
+
+# Choose generic configuration options.
+
+# Setting DEBUG=1 includes debugging features in the code
+
+DEBUG=
+
+# Setting TDEBUG=1 includes symbol table information for the debugger,
+# and also enables stack tracing on failure.
+
+TDEBUG=
+
+# Setting CDEBUG=1 enables 'C' compiler debugging and turns off optimization
+# Code is substantially slower and larger.
+
+CDEBUG=
+
+# Define the name of the executable file.
+
+GS=GS
+
+# Define the directory where the IJG JPEG library sources are stored,
+# and the major version of the library that is stored there.
+# You may need to change this if the IJG library version changes.
+# See jpeg.mak for more information.
+
+JSRCDIR=[-.jpeg-6b]
+JVERSION=6
+
+# Define the directory where the PNG library sources are stored,
+# and the version of the library that is stored there.
+# You may need to change this if the libpng version changes.
+# See libpng.mak for more information.
+
+PSRCDIR=[-.libpng-1_0_3]
+PVERSION=10003
+
+# Define the directory where the zlib sources are stored.
+# See zlib.mak for more information.
+
+ZSRCDIR=[-.zlib-1_1_3]
+
+# Note that built-in third-party libraries aren't available.
+
+SHARE_JPEG=0
+SHARE_LIBPNG=0
+SHARE_ZLIB=0
+
+# Define the path to X11 include files
+
+X_INCLUDE=DECW$INCLUDE
+
+# ------ Platform-specific options ------ #
+
+# Define the drive, directory, and compiler name for the 'C' compiler.
+# COMP is the full compiler path name.
+
+.ifdef DEBUG
+SW_DEBUG=/DEBUG/NOOPTIMIZE
+.else
+SW_DEBUG=/NODEBUG/OPTIMIZE
+.endif
+
+.ifdef VAXC
+SW_PLATFORM=/VAXC
+.else
+SW_PLATFORM=/DECC/PREFIX=ALL/NESTED_INCLUDE=PRIMARY
+.endif
+
+# Define any other compilation flags.
+# Including defines for A4 paper size
+
+.ifdef A4_PAPER
+SW_PAPER=/DEFINE=("A4")
+.else
+SW_PAPER=
+.endif
+
+COMP=CC$(SW_DEBUG)$(SW_PLATFORM)$(SW_PAPER)
+
+# LINK is the full linker path name
+
+.ifdef TDEBUG
+LINKER=LINK/DEBUG/TRACEBACK
+.else
+LINKER=LINK/NODEBUG/NOTRACEBACK
+.endif
+
+# INCDIR contains the include files
+INCDIR=
+
+# LIBDIR contains the library files
+LIBDIR=
+
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
+# ------ Devices and features ------ #
+
+# Choose the device(s) to include. See devs.mak for details,
+# devs.mak and contrib.mak for the list of available devices.
+
+DEVICE_DEVS=$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
+#DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpamono.dev $(DD)posync.dev
+DEVICE_DEVS1=
+DEVICE_DEVS2=
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+# Overflow from DEVS9
+DEVICE_DEVS16=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
+
+# Choose the language feature(s) to include. See gs.mak for details.
+
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev
+
+# Choose whether to compile the .ps initialization files into the executable.
+# See gs.mak for details.
+
+COMPILE_INITS=0
+
+# Choose whether to store band lists on files or in memory.
+# The choices are 'file' or 'memory'.
+
+BAND_LIST_STORAGE=file
+
+# Choose which compression method to use when storing band lists in memory.
+# The choices are 'lzw' or 'zlib'. lzw is not recommended, because the
+# LZW-compatible code in Ghostscript doesn't actually compress its input.
+
+BAND_LIST_COMPRESSOR=zlib
+
+# Choose the implementation of file I/O: 'stdio', 'fd', or 'both'.
+# See gs.mak and sfxfd.c for more details.
+
+FILE_IMPLEMENTATION=stdio
+
+# Define the name table capacity size of 2^(16+n).
+
+EXTEND_NAMES=0
+
+# Define whether the system constants are writable.
+
+SYSTEM_CONSTANTS_ARE_WRITABLE=0
+
+# Define the platform name.
+
+PLATFORM=openvms_
+
+# Define the name of the makefile -- used in dependencies.
+
+MAKEFILE=$(GLSRCDIR)openvms.mmk
+TOP_MAKEFILES=$(MAKEFILE)
+
+# Define the platform options
+
+PLATOPT=
+
+# Patch a couple of PC-specific things that aren't relevant to OpenVMS builds,
+# but that cause `make' to produce warnings.
+
+PCFBASM=
+
+# It is very unlikely that anyone would want to edit the remaining
+# symbols, but we describe them here for completeness:
+
+# Define the suffix for command files (e.g., null or .bat).
+
+CMD=
+
+# Define the directory separator character (\ for MS-DOS, / for Unix,
+# nothing for OpenVMS).
+
+D=
+
+# Define the brackets for passing preprocessor definitions to the C compiler.
+
+D_=/DEFINE="
+_D_=$(NULL)=
+_D="
+
+# Define the syntax of search paths for the C compiler.
+# The OpenVMS compilers uses /INCLUDE=(dir1, dir2, ...dirn),
+# and only a single /INCLUDE switch is allowed in the command line.
+
+I_=/INCLUDE=(
+II=,
+_I=)
+
+# Define the string for specifying the output file from the C compiler.
+
+O_=/OBJECT=
+
+# Define the extension for executable files (e.g., null or .exe).
+
+XE=.exe
+
+# Define the extension for executable files for the auxiliary programs
+# (e.g., null or .exe).
+
+XEAUX=.exe
+
+# Define the list of files that `make clean' removes.
+
+BEGINFILES=$(GLSRCDIR)OPENVMS.OPT $(GLSRCDIR)OPENVMS.COM
+
+# Define the C invocation for the ansi2knr program. We don't use this.
+
+CCA2K=
+
+# Define the C invocation for auxiliary programs (echogs, genarch).
+# We don't need to define this separately.
+
+CCAUX=
+
+# Define the C invocation for normal compilation.
+
+CC=$(COMP)
+
+# Define the Link invocation.
+
+LINK=$(LINKER)/MAP/EXE=$@ $+,$(GLSRCDIR)OPENVMS.OPT/OPTION
+
+# Define the ANSI-to-K&R dependency. We don't need this.
+
+AK=
+
+# Define the syntax for command, object, and executable files.
+
+OBJ=obj
+
+# Define the prefix for image invocations.
+
+NULL=
+EXP=MCR $(NULL)
+
+# Define the prefix for shell invocations.
+
+SH=
+
+# Define generic commands.
+
+CP_=@$(GLSRCDIR)COPY_ONE
+
+# Define the command for deleting (a) file(s) (including wild cards)
+
+RM_=@$(GLSRCDIR)RM_ONE
+
+# Define the command for deleting multiple files / patterns.
+
+RMN_=@$(GLSRCDIR)RM_ALL
+
+# Define the arguments for genconf.
+
+CONFILES=-p %s
+CONFLDTR=-o
+
+# Define the generic compilation rules.
+
+.suffixes : .c .obj .exe
+
+.obj.exe :
+ $(LINK)
+
+# ---------------------------- End of options ---------------------------- #
+
+# Define various incantations of the 'c' compiler.
+
+CC_=$(COMP)
+CC_INT=$(CC_)
+CC_LEAF=$(CC_)
+
+# ------------------- Include the generic makefiles ---------------------- #
+
+all : macro [.lib]Fontmap. $(GS_XE)
+
+#.include $(COMMONDIR)/ansidefs.mak
+#.include $(COMMONDIR)/vmsdefs.mak
+#.include $(COMMONDIR)/generic.mak
+.include $(GLSRCDIR)gs.mak
+.include $(GLSRCDIR)lib.mak
+.include $(PSSRCDIR)int.mak
+.include $(PSSRCDIR)cfonts.mak
+.include $(GLSRCDIR)jpeg.mak
+# zlib.mak must precede libpng.mak
+.include $(GLSRCDIR)zlib.mak
+.include $(GLSRCDIR)libpng.mak
+.include $(GLSRCDIR)devs.mak
+.include $(GLSRCDIR)contrib.mak
+
+
+# ----------------------------- Main program ------------------------------
+
+macro :
+.ifdef A4_PAPER
+ @ a4p = 1
+.else
+ @ a4p = 0
+.endif
+ @ decc = f$search("SYS$SYSTEM:DECC$COMPILER.EXE").nes.""
+ @ decw12 = f$search("SYS$SHARE:DECW$XTLIBSHRR5.EXE").nes.""
+ @ macro = ""
+ @ if a4p.or.decc.or.decw12 then macro = "/MACRO=("
+ @ if .not. decc then macro = macro + "VAXC=1,"
+ @ if decw12 then macro = macro + "DECWINDOWS1_2=1,"
+ @ if a4p then macro = macro + "A4_PAPER=1,"
+ @ if macro.nes."" then macro = f$extract(0,f$length(macro)-1,macro)+ ")"
+ $(MMS)$(MMSQUALIFIERS)'macro' $(GS_XE)
+
+$(GS_XE) : openvms $(GLGEN)arch.h $(GLOBJDIR)gs.$(OBJ) $(INT_ALL) $(LIB_ALL)
+ $(LINKER)/MAP/EXE=$@ $(GLOBJDIR)gs.$(OBJ),$(ld_tr)/OPTIONS,$(GLSRCDIR)OPENVMS.OPT/OPTION
+
+# OpenVMS.dev
+
+openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_vms.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ)
+$(GLGEN)openvms_.dev : $(openvms__) $(GLGEN)nosync.dev
+ $(SETMOD) $(GLGEN)openvms_ $(openvms__) -include $(GLGEN)nosync
+
+$(ECHOGS_XE) : $(GLOBJDIR)echogs.$(OBJ)
+$(GENARCH_XE) : $(GLOBJDIR)genarch.$(OBJ)
+$(GENCONF_XE) : $(GLOBJDIR)genconf.$(OBJ)
+$(GENDEV_XE) : $(GLOBJDIR)gendev.$(OBJ)
+$(GENHT_XE) : $(GLOBJDIR)genht.$(OBJ)
+$(GENINIT_XE) : $(GLOBJDIR)geninit.$(OBJ)
+
+$(GLOBJDIR)echogs.$(OBJ) : $(GLSRCDIR)echogs.c
+$(GLOBJDIR)genarch.$(OBJ) : $(GLSRCDIR)genarch.c $(GENARCH_DEPS)
+$(GLOBJDIR)genconf.$(OBJ) : $(GLSRCDIR)genconf.c $(GENCONF_DEPS)
+$(GLOBJDIR)gendev.$(OBJ) : $(GLSRCDIR)gendev.c $(GENDEV_DEPS)
+# ****** NEED TO ADD $(GENHT_CFLAGS) HERE ******
+$(GLOBJDIR)genht.$(OBJ) : $(GLSRCDIR)genht.c $(GENHT_DEPS)
+$(GLOBJDIR)geninit.$(OBJ) : $(GLSRCDIR)geninit.c $(GENINIT_DEPS)
+
+$(GLOBJ)gp_vms.$(OBJ) : $(GLSRC)gp_vms.c
+ $(CC_)/include=($(GLGENDIR),$(GLSRCDIR))/obj=$(GLOBJ)gp_vms.$(OBJ) $(GLSRC)gp_vms.c
+
+# Preliminary definitions
+
+openvms : $(GLSRCDIR)openvms.com $(GLSRCDIR)openvms.opt
+ @$(GLSRCDIR)OPENVMS
+
+$(GLSRCDIR)openvms.com : $(GLSRCDIR)append_l.com
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB X11 $(X_INCLUDE)"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB GS_LIB ''F$ENVIRONMENT(""DEFAULT"")'"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB GS_DOC ''F$ENVIRONMENT(""DEFAULT"")'"
+.ifdef VAXC
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB C$INCLUDE ''F$ENVIRONMENT(""DEFAULT"")', DECW$INCLUDE, SYS$LIBRARY"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB VAXC$INCLUDE C$INCLUDE"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB SYS SYS$LIBRARY"
+.else
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB DECC$USER_INCLUDE ''F$ENVIRONMENT(""DEFAULT"")', DECW$INCLUDE, DECC$LIBRARY_INCLUDE, SYS$LIBRARY"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB DECC$SYSTEM_INCLUDE ''F$ENVIRONMENT(""DEFAULT"")', DECW$INCLUDE, DECC$LIBRARY_INCLUDE, SYS$LIBRARY"
+ @$(GLSRCDIR)APPEND_L $@ "$ DEFINE/JOB SYS "DECC$LIBRARY_INCLUDE,SYS$LIBRARY"
+.endif
+
+$(GLSRCDIR)openvms.opt :
+.ifdef VAXC
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:VAXCRTL.EXE/SHARE"
+.endif
+.ifdef DECWINDOWS1_2
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XMLIBSHR12.EXE/SHARE"
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XTLIBSHRR5.EXE/SHARE"
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XLIBSHR.EXE/SHARE"
+.else
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XMLIBSHR.EXE/SHARE"
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XTSHR.EXE/SHARE"
+ @$(GLSRCDIR)APPEND_L $@ "SYS$SHARE:DECW$XLIBSHR.EXE/SHARE"
+.endif
+ @$(GLSRCDIR)APPEND_L $@ ""Ident="""""GS $(GS_DOT_VERSION)"""""
+
+# The platform-specific makefiles must also include rules for creating
+# certain dynamically generated files:
+# gconfig_.h - this indicates the presence or absence of
+# certain system header files that are located in different
+# places on different systems. (It could be generated by
+# the GNU `configure' program.)
+# gconfigv.h - this indicates the status of certain machine-
+# and configuration-specific features derived from definitions
+# in the platform-specific makefile.
+
+$(gconfig__h) : $(TOP_MAKEFILES) $(ECHOGS_XE)
+ $(EXP)$(ECHOGS_XE) -w $(gconfig__h) -x 23 define "HAVE_SYS_TIME_H"
+
+$(gconfigv_h) : $(TOP_MAKEFILES) $(ECHOGS_XE)
+ $(EXP)$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define "USE_ASM" 0
+ $(EXP)$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define "USE_FPU" 1
+ $(EXP)$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define "EXTEND_NAMES" 0$(EXTEND_NAMES)
+ $(EXP)$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define "SYSTEM_CONSTANTS_ARE_WRITABLE" 0$(SYSTEM_CONSTANTS_ARE_WRITABLE)
diff --git a/gs/src/oper.h b/gs/src/oper.h
index 0b2abcd7b..5c588a173 100644
--- a/gs/src/oper.h
+++ b/gs/src/oper.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,6 +30,13 @@
#include "iutil.h"
/*
+ * Operator procedures take a single argument. This is currently a pointer
+ * to the current context state, but might conceivably change in the future.
+ * They return 0 for success, a negative code for an error, or a positive
+ * code for some uncommon situations (see below).
+ */
+
+/*
* In order to combine typecheck and stackunderflow error checking
* into a single test, we guard the bottom of the o-stack with
* additional entries of type t__invalid. However, if a type check fails,
diff --git a/gs/src/opextern.h b/gs/src/opextern.h
index 72f555576..b833311c0 100644
--- a/gs/src/opextern.h
+++ b/gs/src/opextern.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,74 +36,74 @@
*/
/* Operators exported for the special operator encoding in interp.c. */
-int zadd(P1(os_ptr));
-int zdef(P1(os_ptr));
-int zdup(P1(os_ptr));
-int zexch(P1(os_ptr));
-int zif(P1(os_ptr));
-int zifelse(P1(os_ptr));
-int zindex(P1(os_ptr));
-int zpop(P1(os_ptr));
-int zroll(P1(os_ptr));
-int zsub(P1(os_ptr));
+int zadd(P1(i_ctx_t *));
+int zdef(P1(i_ctx_t *));
+int zdup(P1(i_ctx_t *));
+int zexch(P1(i_ctx_t *));
+int zif(P1(i_ctx_t *));
+int zifelse(P1(i_ctx_t *));
+int zindex(P1(i_ctx_t *));
+int zpop(P1(i_ctx_t *));
+int zroll(P1(i_ctx_t *));
+int zsub(P1(i_ctx_t *));
/* Operators exported for server loop implementations. */
-int zflush(P1(os_ptr));
-int zflushpage(P1(os_ptr));
-int zsave(P1(os_ptr));
-int zrestore(P1(os_ptr));
+int zflush(P1(i_ctx_t *));
+int zflushpage(P1(i_ctx_t *));
+int zsave(P1(i_ctx_t *));
+int zrestore(P1(i_ctx_t *));
/* Operators exported for save/restore. */
-int zgsave(P1(os_ptr));
-int zgrestore(P1(os_ptr));
+int zgsave(P1(i_ctx_t *));
+int zgrestore(P1(i_ctx_t *));
/* Operators exported for Level 2 pagedevice facilities. */
-int zcopy_gstate(P1(os_ptr));
-int zcurrentgstate(P1(os_ptr));
-int zgrestoreall(P1(os_ptr));
-int zgstate(P1(os_ptr));
-int zreadonly(P1(os_ptr));
-int zsetdevice(P1(os_ptr));
-int zsetgstate(P1(os_ptr));
+int zcopy_gstate(P1(i_ctx_t *));
+int zcurrentgstate(P1(i_ctx_t *));
+int zgrestoreall(P1(i_ctx_t *));
+int zgstate(P1(i_ctx_t *));
+int zreadonly(P1(i_ctx_t *));
+int zsetdevice(P1(i_ctx_t *));
+int zsetgstate(P1(i_ctx_t *));
/* Operators exported for Level 2 "wrappers". */
-int zcopy(P1(os_ptr));
-int zimage(P1(os_ptr));
-int zimagemask(P1(os_ptr));
-int zwhere(P1(os_ptr));
+int zcopy(P1(i_ctx_t *));
+int zimage(P1(i_ctx_t *));
+int zimagemask(P1(i_ctx_t *));
+int zwhere(P1(i_ctx_t *));
/* Operators exported for specific-VM operators. */
-int zarray(P1(os_ptr));
-int zdict(P1(os_ptr));
-int zpackedarray(P1(os_ptr));
-int zstring(P1(os_ptr));
+int zarray(P1(i_ctx_t *));
+int zdict(P1(i_ctx_t *));
+int zpackedarray(P1(i_ctx_t *));
+int zstring(P1(i_ctx_t *));
/* Operators exported for user path decoding. */
/* Note that only operators defined in all configurations are declared here. */
-int zclosepath(P1(os_ptr));
-int zcurveto(P1(os_ptr));
-int zlineto(P1(os_ptr));
-int zmoveto(P1(os_ptr));
-int zrcurveto(P1(os_ptr));
-int zrlineto(P1(os_ptr));
-int zrmoveto(P1(os_ptr));
+int zclosepath(P1(i_ctx_t *));
+int zcurveto(P1(i_ctx_t *));
+int zlineto(P1(i_ctx_t *));
+int zmoveto(P1(i_ctx_t *));
+int zrcurveto(P1(i_ctx_t *));
+int zrlineto(P1(i_ctx_t *));
+int zrmoveto(P1(i_ctx_t *));
/* Operators exported for CIE cache loading. */
-int zcvx(P1(os_ptr));
-int zexec(P1(os_ptr)); /* also for .runexec */
-int zfor(P1(os_ptr));
+int zcvx(P1(i_ctx_t *));
+int zexec(P1(i_ctx_t *)); /* also for .runexec */
+int zfor(P1(i_ctx_t *));
/* Odds and ends */
-int zbegin(P1(os_ptr));
-int zcleartomark(P1(os_ptr));
-int zend(P1(os_ptr));
-int zclosefile(P1(os_ptr)); /* for runexec_cleanup */
-int zsetfont(P1(os_ptr)); /* for cshow_continue */
+int zbegin(P1(i_ctx_t *));
+int zcleartomark(P1(i_ctx_t *));
+int zend(P1(i_ctx_t *));
+int zclosefile(P1(i_ctx_t *)); /* for runexec_cleanup */
+int zsetfont(P1(i_ctx_t *)); /* for cshow_continue */
/* Operators exported for special customer needs. */
-int zcurrentdevice(P1(os_ptr));
-int ztoken(P1(os_ptr));
-int ztokenexec(P1(os_ptr));
-int zwrite(P1(os_ptr));
+int zcurrentdevice(P1(i_ctx_t *));
+int ztoken(P1(i_ctx_t *));
+int ztokenexec(P1(i_ctx_t *));
+int zwrite(P1(i_ctx_t *));
#endif /* opextern_INCLUDED */
diff --git a/gs/src/os2.mak b/gs/src/os2.mak
index 3fe3f0594..226dbc4b2 100644
--- a/gs/src/os2.mak
+++ b/gs/src/os2.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -34,7 +34,7 @@ GS_DOCDIR=c:/gs
# initialization and font files. Separate multiple directories with ;.
# Use / to indicate directories, not a single \.
-GS_LIB_DEFAULT=c:/gs;c:/gs/fonts
+GS_LIB_DEFAULT=c:/gs/lib;c:/gs/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -82,15 +82,18 @@ IBMCPP=0
GS=gsos2
GSDLL=gsdll2
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
# This makefile has never been tested with any other values than these,
# and almost certainly won't work with other values.
+BINDIR=.
GLSRCDIR=.
GLGENDIR=.
GLOBJDIR=.
PSSRCDIR=.
+PSLIBDIR=.
PSGENDIR=.
PSOBJDIR=.
@@ -108,17 +111,13 @@ JVERSION=6
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
ZSRCDIR=zlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# ------ Platform-specific options ------ #
# If you don't have an assembler, set USE_ASM=0. Otherwise, set USE_ASM=1,
@@ -177,6 +176,12 @@ CPU_TYPE=386
FPU_TYPE=0
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=winsync
+
# ---------------------------- End of options ---------------------------- #
# Note that built-in libpng and zlib aren't available.
@@ -196,7 +201,8 @@ PLATFORM=os2_
# Define the name of the makefile -- used in dependencies.
-MAKEFILE=os2.mak
+MAKEFILE=$(GLSRCDIR)\os2.mak
+TOP_MAKEFILES=$(MAKEFILE)
# Define the files to be deleted by 'make clean'.
@@ -226,15 +232,18 @@ dosdefault: default gspmdrv.exe
# Define the extensions for command, object, and executable files.
+# Work around the fact that some `make' programs drop trailing spaces
+# or interpret == as a special definition operator.
+NULL=
+
CMD=.cmd
C_=-c
+D_=-D
+_D_=$(NULL)=
+_D=
I_=-I
II=-I
_I=
-# There should be a <space> at the end of the definition of O_,
-# but we have to work around the fact that some `make' programs
-# drop trailing spaces in macro definitions.
-NULL=
O_=-o $(NULL)
!if $(MAKEDLL)
OBJ=obj
@@ -251,7 +260,6 @@ D=\#
EXP=
QQ="
SH=
-SHP=
# Define generic commands.
@@ -307,10 +315,13 @@ ASMFLAGS=$(ASMCPU) $(ASMFPU) $(ASMDEBUG)
# ---------------------- MS-DOS I/O debugging option ---------------------- #
-dosio_=$(GLOBJ)zdosio.$(OBJ)
-dosio.dev: $(dosio_)
- $(SETMOD) dosio $(dosio_)
- $(ADDMOD) dosio -oper zdosio
+dosio_=$(PSOBJ)zdosio.$(OBJ)
+dosio.dev: $(PSGEN)dosio.dev
+ $(NO_OP)
+
+$(PSGEN)dosio.dev: $(dosio_)
+ $(SETMOD) $(PSGEN)dosio $(dosio_)
+ $(ADDMOD) $(PSGEN)dosio -oper zdosio
$(PSOBJ)zdosio.$(OBJ): $(PSSRC)zdosio.c $(OP) $(store_h)
$(PSCC) $(PSO_)zdosio.$(OBJ) $(C_) $(PSSRC)zdosio.c
@@ -372,7 +383,7 @@ CC_LEAF=$(CC_)
# Choose the language feature(s) to include. See gs.mak for details.
# Since we have a large address space, we include some optional features.
-FEATURE_DEVS=psl3.dev pdf.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -406,8 +417,8 @@ DEVICE_DEVS=os2pm.dev
#DEVICE_DEVS1=x11.dev x11alpha.dev x11cmyk.dev x11mono.dev
DEVICE_DEVS1=
DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
+DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev
+DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev
DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev lbp8.dev uniprint.dev
DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev bjc600.dev bjc800.dev m8510.dev necp6.dev
DEVICE_DEVS7=dfaxhigh.dev dfaxlow.dev
@@ -419,6 +430,12 @@ DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
DEVICE_DEVS14=jpeg.dev jpeggray.dev
DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+# Overflow for DEVS3,4,5,6,9
+DEVICE_DEVS16=ljet3.dev ljet3d.dev ljet4.dev ljet4d.dev
+DEVICE_DEVS17=pj.dev pjxl.dev pjxl300.dev
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# Include the generic makefiles.
!include "version.mak"
@@ -432,20 +449,21 @@ DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
!include "pcwin.mak"
!include "contrib.mak"
!include "int.mak"
+!include "cfonts.mak"
# -------------------------------- Library -------------------------------- #
# The GCC/EMX platform
os2__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_os2.$(OBJ)
-os2_.dev: $(os2__) nosync.dev
- $(SETMOD) os2_ $(os2__) -include nosync
+$(GLGEN)os2_.dev: $(os2__) nosync.dev
+ $(SETMOD) $(GLGEN)os2_ $(os2__) -include nosync
!if $(MAKEDLL)
# Using a file device resource to get the console streams re-initialized
# is bad architecture (an upward reference to ziodev),
# but it will have to do for the moment.
# We need to redirect stdin/out/err to gsdll_callback
- $(ADDMOD) os2_ -iodev wstdio
+ $(ADDMOD) $(GLGEN)os2_ -iodev wstdio
!endif
@@ -468,7 +486,7 @@ $(ECHOGS_XE): echogs.c
$(CCAUX) /Fe$(ECHOGS_XE) echogs.c
!endif
-$(GENARCH_XE): genarch.c $(stdpre_h)
+$(GENARCH_XE): genarch.c $(GENARCH_DEPS)
!if $(EMX)
$(CCAUX) -o $(AUXGEN)genarch genarch.c
$(COMPDIR)\emxbind $(EMXPATH)/bin/emxl.exe $(AUXGEN)genarch $(GENARCH_XE)
@@ -478,7 +496,7 @@ $(GENARCH_XE): genarch.c $(stdpre_h)
$(CCAUX) /Fe$(GENARCH_XE) genarch.c
!endif
-$(GENCONF_XE): genconf.c $(stdpre_h)
+$(GENCONF_XE): genconf.c $(GENCONF_DEPS)
!if $(EMX)
$(CCAUX) -o $(AUXGEN)genconf genconf.c
$(COMPDIR)\emxbind $(EMXPATH)/bin/emxl.exe $(AUXGEN)genconf $(GENCONF_XE)
@@ -488,7 +506,7 @@ $(GENCONF_XE): genconf.c $(stdpre_h)
$(CCAUX) /Fe$(GENCONF_XE) genconf.c
!endif
-$(GENDEV_XE): gendev.c $(stdpre_h)
+$(GENDEV_XE): gendev.c $(GENDEV_DEPS)
!if $(EMX)
$(CCAUX) -o $(AUXGEN)gendev gendev.c
$(COMPDIR)\emxbind $(EMXPATH)/bin/emxl.exe $(AUXGEN)gendev $(GENDEV_XE)
@@ -498,7 +516,17 @@ $(GENDEV_XE): gendev.c $(stdpre_h)
$(CCAUX) /Fe$(GENDEV_XE) gendev.c
!endif
-$(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
+$(GENHT_XE): $(PSSRC)genht.c $(GENHT_DEPS)
+!if $(EMX)
+ $(CCAUX) -o $(AUXGEN)genht $(GENHT_CFLAGS) $(PSSRC)genht.c
+ $(COMPDIR)\emxbind $(EMXPATH)/bin/emxl.exe $(AUXGEN)genht $(GENHT_XE)
+ del $(AUXGEN)genht
+!endif
+!if $(IBMCPP)
+ $(CCAUX) /Fe$(GENHT_XE) genht.c
+!endif
+
+$(GENINIT_XE): $(PSSRC)geninit.c $(GENINIT_DEPS)
!if $(EMX)
$(CCAUX) -o $(AUXGEN)geninit $(PSSRC)geninit.c
$(COMPDIR)\emxbind $(EMXPATH)/bin/emxl.exe $(AUXGEN)geninit $(GENINIT_XE)
@@ -509,10 +537,10 @@ $(GENINIT_XE): $(PSSRC)geninit.c $(stdio__h) $(string__h)
!endif
# No special gconfig_.h is needed.
-$(gconfig__h): $(MAKEFILE) $(ECHOGS_XE)
+$(gconfig__h): $(TOP_MAKEFILES) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfig__h) /* This file deliberately left blank. */
-$(gconfigv_h): os2.mak $(MAKEFILE) $(ECHOGS_XE)
+$(gconfigv_h): os2.mak $(TOP_MAKEFILES) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define USE_ASM -x 2028 -q $(USE_ASM)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define USE_FPU -x 2028 -q $(FPU_TYPE)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define EXTEND_NAMES 0$(EXTEND_NAMES)
@@ -520,6 +548,8 @@ $(gconfigv_h): os2.mak $(MAKEFILE) $(ECHOGS_XE)
# ----------------------------- Main program ------------------------------ #
+gsdllos2_h=$(GLSRC)gsdllos2.h
+
# Interpreter main program
ICONS=gsos2.ico gspmdrv.ico
@@ -529,7 +559,7 @@ ICONS=gsos2.ico gspmdrv.ico
GS_ALL=$(GLOBJ)gsdll.$(OBJ) $(INT_ALL) $(INTASM)\
$(LIB_ALL) $(LIBCTR) $(ld_tr) $(GLGEN)lib.tr $(GS).res $(ICONS)
-$(GS_XE): $(GSDLL).dll dpmainc.c $(gsdll_h) gsos2.rc gscdefs.$(OBJ)
+$(GS_XE): $(GSDLL).dll dpmainc.c $(gsdll_h) $(gsdllos2_h) gsos2.rc gscdefs.$(OBJ)
!if $(EMX)
$(COMPDIR)\gcc $(CGDB) $(CO) -Zomf -o$(GS_XE) dpmainc.c gscdefs.$(OBJ) gsos2.def
!endif
diff --git a/gs/src/ostack.h b/gs/src/ostack.h
index 3f6b9d754..bf149ca40 100644
--- a/gs/src/ostack.h
+++ b/gs/src/ostack.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,11 +23,12 @@
# define ostack_INCLUDED
#include "iostack.h"
+#include "icstate.h" /* for access to op_stack */
-/* Define the operand stack pointers. */
-extern op_stack_t iop_stack;
-
+/* Define the operand stack pointers for operators. */
+#define iop_stack (i_ctx_p->op_stack)
#define o_stack (iop_stack.stack)
+
#define osbot (o_stack.bot)
#define osp (o_stack.p)
#define ostop (o_stack.top)
diff --git a/gs/src/pcwin.mak b/gs/src/pcwin.mak
index 1c9614190..950f9abcb 100644
--- a/gs/src/pcwin.mak
+++ b/gs/src/pcwin.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -30,13 +30,14 @@ PCWIN_MAK=$(GLSRC)pcwin.mak
gp_mswin_h=$(GLSRC)gp_mswin.h
gsdll_h=$(GLSRC)gsdll.h
+gsdllwin_h=$(GLSRC)gsdllwin.h
gdevmswn_h=$(GLSRC)gdevmswn.h $(GDEVH)\
$(dos__h) $(memory__h) $(string__h) $(windows__h)\
$(gp_mswin_h)
$(GLOBJ)gdevmswn.$(OBJ): $(GLSRC)gdevmswn.c $(gdevmswn_h) $(gp_h) $(gpcheck_h)\
- $(gsdll_h) $(gsparam_h) $(gdevpccm_h)
+ $(gsdll_h) $(gsdllwin_h) $(gsparam_h) $(gdevpccm_h)
$(GLCCWIN) $(GLO_)gdevmswn.$(OBJ) $(C_) $(GLSRC)gdevmswn.c
$(GLOBJ)gdevmsxf.$(OBJ): $(GLSRC)gdevmsxf.c $(ctype__h) $(math__h) $(memory__h) $(string__h)\
@@ -44,21 +45,22 @@ $(GLOBJ)gdevmsxf.$(OBJ): $(GLSRC)gdevmsxf.c $(ctype__h) $(math__h) $(memory__h)
$(GLCCWIN) $(GLO_)gdevmsxf.$(OBJ) $(C_) $(GLSRC)gdevmsxf.c
# An implementation using a DIB filled by an image device.
-$(GLOBJ)gdevwdib.$(OBJ): $(GLSRC)gdevwdib.c $(gdevmswn_h) $(gsdll_h) $(gxdevmem_h)
+$(GLOBJ)gdevwdib.$(OBJ): $(GLSRC)gdevwdib.c\
+ $(gdevmswn_h) $(gsdll_h) $(gsdllwin_h) $(gxdevmem_h)
$(GLCCWIN) $(GLO_)gdevwdib.$(OBJ) $(C_) $(GLSRC)gdevwdib.c
mswindll1_=$(GLOBJ)gdevmswn.$(OBJ) $(GLOBJ)gdevmsxf.$(OBJ) $(GLOBJ)gdevwdib.$(OBJ)
mswindll2_=$(GLOBJ)gdevemap.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
mswindll_=$(mswindll1_) $(mswindll2_)
-mswindll.dev: $(mswindll_)
- $(SETDEV) mswindll $(mswindll1_)
- $(ADDMOD) mswindll $(mswindll2_)
+$(GLGEN)mswindll.dev: $(mswindll_)
+ $(SETDEV) $(GLGEN)mswindll $(mswindll1_)
+ $(ADDMOD) $(GLGEN)mswindll $(mswindll2_)
### -------------------- The MS-Windows DDB 3.n printer ----------------- ###
mswinprn_=$(GLOBJ)gdevwprn.$(OBJ) $(GLOBJ)gdevmsxf.$(OBJ)
-mswinprn.dev: $(mswinprn_)
- $(SETDEV) mswinprn $(mswinprn_)
+$(DD)mswinprn.dev: $(mswinprn_)
+ $(SETDEV) $(DD)mswinprn $(mswinprn_)
$(GLOBJ)gdevwprn.$(OBJ): $(GLSRC)gdevwprn.c $(gdevmswn_h) $(gp_h)
$(GLCCWIN) $(GLO_)gdevwprn.$(OBJ) $(C_) $(GLSRC)gdevwprn.c
@@ -66,8 +68,8 @@ $(GLOBJ)gdevwprn.$(OBJ): $(GLSRC)gdevwprn.c $(gdevmswn_h) $(gp_h)
### -------------------- The MS-Windows DIB 3.n printer ----------------- ###
mswinpr2_=$(GLOBJ)gdevwpr2.$(OBJ)
-mswinpr2.dev: $(mswinpr2_) page.dev
- $(SETPDEV) mswinpr2 $(mswinpr2_)
+$(DD)mswinpr2.dev: $(mswinpr2_) $(GLD)page.dev
+ $(SETPDEV) $(DD)mswinpr2 $(mswinpr2_)
$(GLOBJ)gdevwpr2.$(OBJ): $(GLSRC)gdevwpr2.c $(PDEVH) $(windows__h)\
$(gdevpccm_h) $(gp_h) $(gp_mswin_h)
@@ -76,16 +78,16 @@ $(GLOBJ)gdevwpr2.$(OBJ): $(GLSRC)gdevwpr2.c $(PDEVH) $(windows__h)\
### ------------------ OS/2 Presentation Manager device ----------------- ###
os2pm_=$(GLOBJ)gdevpm.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-os2pm.dev: $(os2pm_)
- $(SETDEV) os2pm $(os2pm_)
+$(DD)os2pm.dev: $(os2pm_)
+ $(SETDEV) $(DD)os2pm $(os2pm_)
os2dll_=$(GLOBJ)gdevpm.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ)
-os2dll.dev: $(os2dll_)
- $(SETDEV) os2dll $(os2dll_)
+$(GLGEN)os2dll.dev: $(os2dll_)
+ $(SETDEV) $(GLGEN)os2dll $(os2dll_)
$(GLOBJ)gdevpm.$(OBJ): $(GLSRC)gdevpm.c $(string__h)\
$(gp_h) $(gpcheck_h)\
- $(gsdll_h) $(gserrors_h) $(gsexit_h) $(gsparam_h)\
+ $(gsdll_h) $(gsdllwin_h) $(gserrors_h) $(gsexit_h) $(gsparam_h)\
$(gx_h) $(gxdevice_h) $(gxdevmem_h)\
$(gdevpccm_h) $(GLSRC)gdevpm.h
$(GLCC) $(GLO_)gdevpm.$(OBJ) $(C_) $(GLSRC)gdevpm.c
@@ -93,8 +95,8 @@ $(GLOBJ)gdevpm.$(OBJ): $(GLSRC)gdevpm.c $(string__h)\
### --------------------------- The OS/2 printer ------------------------ ###
os2prn_=$(GLOBJ)gdevos2p.$(OBJ)
-os2prn.dev: $(os2prn_) page.dev
- $(SETPDEV) os2prn $(os2prn_)
+$(DD)os2prn.dev: $(os2prn_) $(GLD)page.dev
+ $(SETPDEV) $(DD)os2prn $(os2prn_)
$(GLOBJ)gdevos2p.$(OBJ): gdevos2p.c $(gp_h) $(gdevpccm_h) $(gdevprn_h) $(gscdefs_h)
$(GLCC) $(GLO_)gdevos2p.$(OBJ) $(C_) $(GLSRC)gdevos2p.c
diff --git a/gs/src/png_.h b/gs/src/png_.h
new file mode 100644
index 000000000..250fe9cd6
--- /dev/null
+++ b/gs/src/png_.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Wrapper for png.h */
+
+#if SHARE_LIBPNG
+#include <png.h>
+#else
+#include "png.h"
+#endif
diff --git a/gs/lib/rm.bat b/gs/src/rm.bat
index 34ee52f9e..96fe999e0 100755
--- a/gs/lib/rm.bat
+++ b/gs/src/rm.bat
@@ -1,3 +1,4 @@
+
@echo off
:next
if '%1'=='' goto exit
diff --git a/gs/src/sa85d.c b/gs/src/sa85d.c
new file mode 100644
index 000000000..6e14b0ee4
--- /dev/null
+++ b/gs/src/sa85d.c
@@ -0,0 +1,157 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* ASCII85Decode filter */
+#include "std.h"
+#include "strimpl.h"
+#include "sa85d.h"
+#include "scanchar.h"
+
+/* ------ ASCII85Decode ------ */
+
+private_st_A85D_state();
+
+/* Initialize the state */
+private int
+s_A85D_init(stream_state * st)
+{
+ stream_A85D_state *const ss = (stream_A85D_state *) st;
+
+ return s_A85D_init_inline(ss);
+}
+
+/* Process a buffer */
+private int a85d_finish(P3(int, ulong, stream_cursor_write *));
+private int
+s_A85D_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ stream_A85D_state *const ss = (stream_A85D_state *) st;
+ register const byte *p = pr->ptr;
+ register byte *q = pw->ptr;
+ const byte *rlimit = pr->limit;
+ byte *wlimit = pw->limit;
+ int ccount = ss->odd;
+ ulong word = ss->word;
+ int status = 0;
+
+ while (p < rlimit) {
+ int ch = *++p;
+ uint ccode = ch - '!';
+
+ if (ccode < 85) { /* catches ch < '!' as well */
+ if (wlimit - q < 4) {
+ p--;
+ status = 1;
+ break;
+ }
+ word = word * 85 + ccode;
+ if (++ccount == 5) {
+ q[1] = (byte) (word >> 24);
+ q[2] = (byte) (word >> 16);
+ q[3] = (byte) ((uint) word >> 8);
+ q[4] = (byte) word;
+ q += 4;
+ word = 0;
+ ccount = 0;
+ }
+ } else if (ch == 'z' && ccount == 0) {
+ if (wlimit - q < 4) {
+ p--;
+ status = 1;
+ break;
+ }
+ q[1] = q[2] = q[3] = q[4] = 0,
+ q += 4;
+ } else if (scan_char_decoder[ch] == ctype_space)
+ DO_NOTHING;
+ else if (ch == '~') {
+ /* Handle odd bytes. */
+ if (p == rlimit) {
+ if (last)
+ status = ERRC;
+ else
+ p--;
+ break;
+ }
+ if ((int)(wlimit - q) < ccount - 1) {
+ status = 1;
+ p--;
+ break;
+ }
+ if (*++p != '>') {
+ status = ERRC;
+ break;
+ }
+ pw->ptr = q;
+ status = a85d_finish(ccount, word, pw);
+ q = pw->ptr;
+ break;
+ } else { /* syntax error or exception */
+ status = ERRC;
+ break;
+ }
+ }
+ pw->ptr = q;
+ if (status == 0 && last) {
+ if ((int)(wlimit - q) < ccount - 1)
+ status = 1;
+ else
+ status = a85d_finish(ccount, word, pw);
+ }
+ pr->ptr = p;
+ ss->odd = ccount;
+ ss->word = word;
+ return status;
+}
+/* Handle the end of input data. */
+private int
+a85d_finish(int ccount, ulong word, stream_cursor_write * pw)
+{
+ /* Assume there is enough room in the output buffer! */
+ byte *q = pw->ptr;
+ int status = EOFC;
+
+ switch (ccount) {
+ case 0:
+ break;
+ case 1: /* syntax error */
+ status = ERRC;
+ break;
+ case 2: /* 1 odd byte */
+ word = word * (85L * 85 * 85) + 0xffffffL;
+ goto o1;
+ case 3: /* 2 odd bytes */
+ word = word * (85L * 85) + 0xffffL;
+ goto o2;
+ case 4: /* 3 odd bytes */
+ word = word * 85 + 0xffL;
+ q[3] = (byte) (word >> 8);
+o2: q[2] = (byte) (word >> 16);
+o1: q[1] = (byte) (word >> 24);
+ q += ccount - 1;
+ pw->ptr = q;
+ }
+ return status;
+}
+
+/* Stream template */
+const stream_template s_A85D_template = {
+ &st_A85D_state, s_A85D_init, s_A85D_process, 2, 4
+};
diff --git a/gs/src/sa85d.h b/gs/src/sa85d.h
new file mode 100644
index 000000000..854750571
--- /dev/null
+++ b/gs/src/sa85d.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* ASCII85Decode filter interface */
+/* Requires scommon.h; strimpl.h if any templates are referenced */
+
+#ifndef sa85d_INCLUDED
+# define sa85d_INCLUDED
+
+/* ASCII85Decode */
+typedef struct stream_A85D_state_s {
+ stream_state_common;
+ int odd; /* # of odd digits */
+ ulong word; /* word being accumulated */
+} stream_A85D_state;
+
+#define private_st_A85D_state() /* in sfilter2.c */\
+ gs_private_st_simple(st_A85D_state, stream_A85D_state,\
+ "ASCII85Decode state")
+/* We define the initialization procedure here, so that the scanner */
+/* can avoid a procedure call. */
+#define s_A85D_init_inline(ss)\
+ ((ss)->word = 0, (ss)->odd = 0)
+extern const stream_template s_A85D_template;
+
+#endif /* sa85d_INCLUDED */
diff --git a/gs/src/sa85x.h b/gs/src/sa85x.h
index 32ac45354..bcda3f18b 100644
--- a/gs/src/sa85x.h
+++ b/gs/src/sa85x.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,29 +17,26 @@
*/
+/* ASCII85 filter interface */
/* Requires scommon.h; strimpl.h if any templates are referenced */
#ifndef sa85x_INCLUDED
# define sa85x_INCLUDED
-/* ASCII85Encode */
-/* (no state) */
-extern const stream_template s_A85E_template;
+#include "sa85d.h"
-/* ASCII85Decode */
-typedef struct stream_A85D_state_s {
+/* ASCII85Encode */
+typedef struct stream_A85E_state_s {
stream_state_common;
- int odd; /* # of odd digits */
- ulong word; /* word being accumulated */
-} stream_A85D_state;
-
-#define private_st_A85D_state() /* in sfilter2.c */\
- gs_private_st_simple(st_A85D_state, stream_A85D_state,\
- "ASCII85Decode state")
-/* We define the initialization procedure here, so that the scanner */
-/* can avoid a procedure call. */
-#define s_A85D_init_inline(ss)\
- ((ss)->word = 0, (ss)->odd = 0)
-extern const stream_template s_A85D_template;
+ /* The following change dynamically. */
+ int count; /* # of digits since last EOL */
+} stream_A85E_state;
+
+#define private_st_A85E_state() /* in sfilter2.c */\
+ gs_private_st_simple(st_A85E_state, stream_A85E_state,\
+ "ASCII85Encode state")
+#define s_A85E_init_inline(ss)\
+ ((ss)->count = 0)
+extern const stream_template s_A85E_template;
#endif /* sa85x_INCLUDED */
diff --git a/gs/src/scfd.c b/gs/src/scfd.c
index e57c1e607..115aad2ab 100644
--- a/gs/src/scfd.c
+++ b/gs/src/scfd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -44,7 +44,7 @@ s_CFD_init(stream_state * st)
{
stream_CFD_state *const ss = (stream_CFD_state *) st;
int raster = ss->raster =
- round_up((ss->Columns + 7) >> 3, ss->DecodedByteAlign);
+ ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign);
byte white = (ss->BlackIs1 ? 0 : 0xff);
s_hcd_init_inline(ss);
@@ -568,12 +568,17 @@ cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr)
count, pcount);
}
#endif
- /* We could just use get_run here, but we can do better: */
- ensure_bits(3, out0);
+ /*
+ * We could just use get_run here, but we can do better. However,
+ * we must be careful to handle the case where the very last codes
+ * in the input stream are 1-bit "vertical 0" codes: we can't just
+ * use ensure_bits(3, ...) and go to get more data if it fails.
+ */
+ ensure_bits(3, out3);
#define vertical_0 (countof(cf2_run_vertical) / 2)
switch (peek_bits(3)) {
- default /*4..7 */ : /* vertical(0) */
- skip_bits(1);
+ default /*4..7*/ : /* vertical(0) */
+v0: skip_bits(1);
rlen = vertical_0;
break;
case 2: /* vertical(+1) */
@@ -684,11 +689,17 @@ cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr)
invert = ~invert; /* polarity changes */
}
goto top;
+ out3:
+ if (bits_left > 0 && peek_bits(1)) {
+ /* This is a 1-bit "vertical 0" code, which we can still process. */
+ goto v0;
+ }
+ /* falls through */
+ out0:status = 0;
+ /* falls through */
out:cfd_store_state();
ss->invert = invert;
return status;
- out0:status = 0;
- goto out;
/*
* We handle horizontal decoding here, so that we can
* branch back into it if we run out of input data.
diff --git a/gs/src/scfe.c b/gs/src/scfe.c
index ebb7b8342..800dc96d5 100644
--- a/gs/src/scfe.c
+++ b/gs/src/scfe.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -142,7 +142,7 @@ s_CFE_init(register stream_state * st)
int code_bytes =
((columns * (ss->K == 0 ? 9 : 12)) >> 4) + 20; /* add slop */
int raster = ss->raster =
- round_up((columns + 7) >> 3, ss->DecodedByteAlign);
+ ROUND_UP((columns + 7) >> 3, ss->DecodedByteAlign);
s_hce_init_inline(ss);
ss->lbuf = ss->lprev = ss->lcode = 0; /* in case we have to release */
diff --git a/gs/src/scommon.h b/gs/src/scommon.h
index 98c0772d9..618496899 100644
--- a/gs/src/scommon.h
+++ b/gs/src/scommon.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,7 +24,7 @@
#include "gsmemory.h"
#include "gstypes.h" /* for gs_string */
-#include "gsstruct.h" /* for extern_st */
+#include "gsstype.h" /* for extern_st */
/*
* There are three major structures involved in the stream package.
@@ -152,10 +152,12 @@ stream_proc_report_error(s_no_report_error);
* we require that the generic stream state not contain any pointers
* to garbage-collectable storage.
*/
+#define STREAM_MAX_ERROR_STRING 79
#define stream_state_common\
const stream_template *template;\
gs_memory_t *memory;\
- stream_proc_report_error((*report_error))
+ stream_proc_report_error((*report_error));\
+ char error_string[STREAM_MAX_ERROR_STRING + 1]
struct stream_state_s {
stream_state_common;
};
diff --git a/gs/src/sdcparam.c b/gs/src/sdcparam.c
index b70f567db..db4fa6f9d 100644
--- a/gs/src/sdcparam.c
+++ b/gs/src/sdcparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,7 +19,7 @@
/* DCT filter parameter setting and reading */
#include "memory_.h"
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "gserror.h"
#include "gserrors.h"
#include "gstypes.h"
@@ -157,6 +157,7 @@ s_DCT_get_quantization_tables(gs_param_list * plist,
default_table_ptrs = defaults->data.compress->cinfo.quant_tbl_ptrs;
}
} else {
+ /**************** quant_tables.size NOT INITIALIZED ****************/
num_in_tables = quant_tables.size;
for (i = 0; i < num_in_tables; ++i)
d_comp_info[i].quant_tbl_no = i;
diff --git a/gs/src/sdctc.c b/gs/src/sdctc.c
index 18ecc6c25..3b96f2b38 100644
--- a/gs/src/sdctc.c
+++ b/gs/src/sdctc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,9 +19,9 @@
/* Code common to DCT encoding and decoding streams */
#include "stdio_.h"
+#include "jpeglib_.h"
#include "gsmemory.h"
#include "gsmalloc.h"
-#include "jpeglib.h"
#include "strimpl.h"
#include "sdct.h"
diff --git a/gs/src/sdctd.c b/gs/src/sdctd.c
index b02945c00..1dd74ad42 100644
--- a/gs/src/sdctd.c
+++ b/gs/src/sdctd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,8 +20,8 @@
/* DCT decoding filter stream */
#include "memory_.h"
#include "stdio_.h"
-#include "jpeglib.h"
-#include "jerror.h"
+#include "jpeglib_.h"
+#include "jerror_.h"
#include "gdebug.h"
#include "gsmemory.h" /* for gsmalloc.h */
#include "gsmalloc.h" /* for gs_memory_default */
diff --git a/gs/src/sdcte.c b/gs/src/sdcte.c
index 7363254c2..afb91f327 100644
--- a/gs/src/sdcte.c
+++ b/gs/src/sdcte.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,8 +20,8 @@
/* DCT encoding filter stream */
#include "memory_.h"
#include "stdio_.h"
-#include "jpeglib.h"
-#include "jerror.h"
+#include "jpeglib_.h"
+#include "jerror_.h"
#include "gdebug.h"
#include "gsmemory.h" /* for gsmalloc.h */
#include "gsmalloc.h" /* for gs_memory_default */
diff --git a/gs/src/sddparam.c b/gs/src/sddparam.c
index c006a2edb..15f2ea74d 100644
--- a/gs/src/sddparam.c
+++ b/gs/src/sddparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,7 +19,7 @@
/* DCTDecode filter parameter setting and reading */
#include "std.h"
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "gserror.h"
#include "gserrors.h"
#include "gstypes.h"
diff --git a/gs/src/sdeparam.c b/gs/src/sdeparam.c
index 64a55ddce..b1b74e65e 100644
--- a/gs/src/sdeparam.c
+++ b/gs/src/sdeparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,7 +19,7 @@
/* DCTEncode filter parameter setting and reading */
#include "memory_.h"
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "gserror.h"
#include "gserrors.h"
#include "gstypes.h"
diff --git a/gs/src/seexec.c b/gs/src/seexec.c
index 6281383c0..5ef6f5adb 100644
--- a/gs/src/seexec.c
+++ b/gs/src/seexec.c
@@ -146,12 +146,20 @@ s_exD_process(stream_state * st, stream_cursor_read * pr,
} else {
/*
* We only ignore leading whitespace, in an attempt to
- * keep from reading beyond the end of the encrypted data.
+ * keep from reading beyond the end of the encrypted data;
+ * but some badly coded files require us to ignore % also.
*/
- status = s_hex_process(pr, pw, &ss->odd,
+hp: status = s_hex_process(pr, pw, &ss->odd,
hex_ignore_leading_whitespace);
- p = q;
count = pw->ptr - q;
+ if (status < 0 && ss->odd < 0) {
+ if (count) {
+ --p;
+ status = 0; /* reprocess error next time */
+ } else if (*p == '%')
+ goto hp; /* ignore % */
+ }
+ p = q;
}
if (skip >= count && skip != 0) {
gs_type1_decrypt(q + 1, p + 1, count,
diff --git a/gs/src/sfilter1.c b/gs/src/sfilter1.c
index b21914b1e..2f4468a47 100644
--- a/gs/src/sfilter1.c
+++ b/gs/src/sfilter1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -233,16 +233,18 @@ cp:
if (c == pattern[match]) {
if (++match == ss->eod.size) {
- switch (ss->count) {
- case 0:
- status = EOFC;
- goto xit;
- case 1:
- ss->count = -1;
- break;
- default:
- ss->count--;
- }
+ /*
+ * We use if/else rather than switch because the value
+ * is long, which is not supported as a switch value in
+ * pre-ANSI C.
+ */
+ if (ss->count == 0) {
+ status = EOFC;
+ goto xit;
+ } else if (ss->count == 1) {
+ ss->count = -1;
+ } else
+ ss->count--;
ss->copy_ptr = 0;
ss->copy_count = match;
match = 0;
diff --git a/gs/src/sfilter2.c b/gs/src/sfilter2.c
index 3b2f2bf63..676246e2c 100644
--- a/gs/src/sfilter2.c
+++ b/gs/src/sfilter2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,15 +27,27 @@
/* ------ ASCII85Encode ------ */
+private_st_A85E_state();
+
+/* Initialize the state */
+private int
+s_A85E_init(stream_state * st)
+{
+ stream_A85E_state *const ss = (stream_A85E_state *) st;
+
+ return s_A85E_init_inline(ss);
+}
+
/* Process a buffer */
-#define LINE_LIMIT 65
+#define LINE_LIMIT 80
private int
s_A85E_process(stream_state * st, stream_cursor_read * pr,
stream_cursor_write * pw, bool last)
{
+ stream_A85E_state *const ss = (stream_A85E_state *) st;
register const byte *p = pr->ptr;
register byte *q = pw->ptr;
- byte *qn = q + LINE_LIMIT;
+ byte *qn = q + (LINE_LIMIT - ss->count);
const byte *rlimit = pr->limit;
byte *wlimit = pw->limit;
int status = 0;
@@ -123,6 +135,7 @@ put: if (wlimit - q < 6) {
qn = q + LINE_LIMIT;
}
}
+ ss->count = LINE_LIMIT - (qn - q);
/* Check for final partial word. */
if (last && status == 0 && count < 4) {
if (wlimit - q < (count == 0 ? 2 : count + 3))
@@ -160,140 +173,7 @@ put: if (wlimit - q < 6) {
/* Stream template */
const stream_template s_A85E_template = {
- &st_stream_state, NULL, s_A85E_process, 4, 6
-};
-
-/* ------ ASCII85Decode ------ */
-
-private_st_A85D_state();
-
-/* Initialize the state */
-private int
-s_A85D_init(stream_state * st)
-{
- stream_A85D_state *const ss = (stream_A85D_state *) st;
-
- return s_A85D_init_inline(ss);
-}
-
-/* Process a buffer */
-private int a85d_finish(P3(int, ulong, stream_cursor_write *));
-private int
-s_A85D_process(stream_state * st, stream_cursor_read * pr,
- stream_cursor_write * pw, bool last)
-{
- stream_A85D_state *const ss = (stream_A85D_state *) st;
- register const byte *p = pr->ptr;
- register byte *q = pw->ptr;
- const byte *rlimit = pr->limit;
- byte *wlimit = pw->limit;
- int ccount = ss->odd;
- ulong word = ss->word;
- int status = 0;
-
- while (p < rlimit) {
- int ch = *++p;
- uint ccode = ch - '!';
-
- if (ccode < 85) { /* catches ch < '!' as well */
- if (wlimit - q < 4) {
- p--;
- status = 1;
- break;
- }
- word = word * 85 + ccode;
- if (++ccount == 5) {
- q[1] = (byte) (word >> 24);
- q[2] = (byte) (word >> 16);
- q[3] = (byte) ((uint) word >> 8);
- q[4] = (byte) word;
- q += 4;
- word = 0;
- ccount = 0;
- }
- } else if (ch == 'z' && ccount == 0) {
- if (wlimit - q < 4) {
- p--;
- status = 1;
- break;
- }
- q[1] = q[2] = q[3] = q[4] = 0,
- q += 4;
- } else if (scan_char_decoder[ch] == ctype_space)
- DO_NOTHING;
- else if (ch == '~') {
- /* Handle odd bytes. */
- if (p == rlimit) {
- if (last)
- status = ERRC;
- else
- p--;
- break;
- }
- if ((int)(wlimit - q) < ccount - 1) {
- status = 1;
- p--;
- break;
- }
- if (*++p != '>') {
- status = ERRC;
- break;
- }
- pw->ptr = q;
- status = a85d_finish(ccount, word, pw);
- q = pw->ptr;
- break;
- } else { /* syntax error or exception */
- status = ERRC;
- break;
- }
- }
- pw->ptr = q;
- if (status == 0 && last) {
- if ((int)(wlimit - q) < ccount - 1)
- status = 1;
- else
- status = a85d_finish(ccount, word, pw);
- }
- pr->ptr = p;
- ss->odd = ccount;
- ss->word = word;
- return status;
-}
-/* Handle the end of input data. */
-private int
-a85d_finish(int ccount, ulong word, stream_cursor_write * pw)
-{
- /* Assume there is enough room in the output buffer! */
- byte *q = pw->ptr;
- int status = EOFC;
-
- switch (ccount) {
- case 0:
- break;
- case 1: /* syntax error */
- status = ERRC;
- break;
- case 2: /* 1 odd byte */
- word = word * (85L * 85 * 85) + 0xffffffL;
- goto o1;
- case 3: /* 2 odd bytes */
- word = word * (85L * 85) + 0xffffL;
- goto o2;
- case 4: /* 3 odd bytes */
- word = word * 85 + 0xffL;
- q[3] = (byte) (word >> 8);
-o2: q[2] = (byte) (word >> 16);
-o1: q[1] = (byte) (word >> 24);
- q += ccount - 1;
- pw->ptr = q;
- }
- return status;
-}
-
-/* Stream template */
-const stream_template s_A85D_template = {
- &st_A85D_state, s_A85D_init, s_A85D_process, 2, 4
+ &st_A85E_state, s_A85E_init, s_A85E_process, 4, 6
};
/* ------ ByteTranslateEncode/Decode ------ */
diff --git a/gs/src/sfxfd.c b/gs/src/sfxfd.c
index 56fb37c74..95792e0fe 100644
--- a/gs/src/sfxfd.c
+++ b/gs/src/sfxfd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,8 +19,8 @@
/* File stream implementation using direct OS calls */
/******
- ****** NOTE: THIS FILE PROBABLY WILL NOT COMPILE ON NON-UNIX
- ****** PLATFORMS, AND IT MAY REQUIRE EDITING ON SOME UNIX PLATFORMS.
+ ****** NOTE: THIS FILE MAY NOT COMPILE ON NON-UNIX PLATFORMS, AND MAY
+ ****** REQUIRE EDITING ON SOME UNIX PLATFORMS.
******/
#include "stdio_.h" /* includes std.h */
#include "errno_.h"
@@ -218,7 +218,7 @@ s_fileno_write_close(register stream * s)
}
/* Define the System V interrupts that require retrying a call. */
-inline private bool
+private bool
errno_is_retry(int errn)
{
switch (errn) {
@@ -244,8 +244,13 @@ s_fileno_read_process(stream_state * st, stream_cursor_read * ignore_pr,
int nread, status;
again:
- nread = read(sfileno((stream *) st), pw->ptr + 1,
- (uint) (pw->limit - pw->ptr));
+ /*
+ * In the Mac MetroWerks compiler, the prototype for read incorrectly
+ * declares the second argument of read as char * rather than void *.
+ * Work around this here.
+ */
+ nread = read(sfileno((stream *)st), (void *)(pw->ptr + 1),
+ (uint)(pw->limit - pw->ptr));
if (nread > 0) {
pw->ptr += nread;
status = 0;
@@ -276,7 +281,8 @@ again:
process_interrupts();
return 0;
}
- nwrite = write(sfileno((stream *) st), pr->ptr + 1, count);
+ /* See above regarding the Mac MetroWorks compiler. */
+ nwrite = write(sfileno((stream *)st), (const void *)(pr->ptr + 1), count);
if (nwrite >= 0) {
pr->ptr += nwrite;
status = 0;
diff --git a/gs/src/siinterp.c b/gs/src/siinterp.c
new file mode 100644
index 000000000..823789f49
--- /dev/null
+++ b/gs/src/siinterp.c
@@ -0,0 +1,261 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Image interpolation filter */
+#include "memory_.h"
+#include <assert.h>
+#include "gxfixed.h" /* for gxdda.h */
+#include "gxdda.h"
+#include "gxfrac.h"
+#include "strimpl.h"
+#include "siinterp.h"
+
+/* ImageInterpolateEncode state */
+typedef struct gx_dda_int_s {
+ dda_state_struct(ia_, int, uint) state;
+ dda_step_struct(ie_, int, uint) step;
+} gx_dda_int_t;
+typedef enum {
+ SCALE_SAME = 0,
+ SCALE_SAME_ALIGNED,
+ SCALE_8_8,
+ SCALE_8_8_ALIGNED,
+ SCALE_8_16_BYTE2FRAC,
+ SCALE_8_16_BYTE2FRAC_ALIGNED,
+ SCALE_8_16_BYTE2FRAC_3,
+ SCALE_8_16_BYTE2FRAC_3_ALIGNED,
+ SCALE_8_16_GENERAL,
+ SCALE_8_16_GENERAL_ALIGNED,
+ SCALE_16_8,
+ SCALE_16_8_ALIGNED,
+ SCALE_16_16,
+ SCALE_16_16_ALIGNED
+} scale_case_t;
+typedef struct stream_IIEncode_state_s {
+ /* The client sets the params values before initialization. */
+ stream_image_scale_state_common; /* = state_common + params */
+ /* The init procedure sets the following. */
+ int sizeofPixelIn; /* bytes per input pixel, 1 or 2 * Colors */
+ int sizeofPixelOut; /* bytes per output pixel, 1 or 2 * Colors */
+ uint src_size; /* bytes per row of input */
+ uint dst_size; /* bytes per row of output */
+ void /*PixelOut */ *prev; /* previous row of input data in output fmt, */
+ /* [WidthIn * sizeofPixelOut] */
+ void /*PixelOut */ *cur; /* current row of input data in output fmt, */
+ /* [WidthIn * sizeofPixelOut] */
+ scale_case_t scale_case;
+ /* The following are updated dynamically. */
+ int dst_x;
+ gx_dda_int_t dda_x; /* DDA for dest X in current scan line */
+ gx_dda_int_t dda_x_init; /* initial setting of dda_x */
+ int src_y, dst_y;
+ gx_dda_int_t dda_y; /* DDA for dest Y */
+ int src_offset, dst_offset;
+} stream_IIEncode_state;
+
+gs_private_st_ptrs2(st_IIEncode_state, stream_IIEncode_state,
+ "ImageInterpolateEncode state",
+ iiencode_state_enum_ptrs, iiencode_state_reloc_ptrs,
+ prev, cur);
+
+/* Forward references */
+private void s_IIEncode_release(P1(stream_state * st));
+
+/* Initialize the filter. */
+private int
+s_IIEncode_init(stream_state * st)
+{
+ stream_IIEncode_state *const ss = (stream_IIEncode_state *) st;
+ gs_memory_t *mem = ss->memory;
+
+ ss->sizeofPixelIn =
+ ss->params.BitsPerComponentIn / 8 * ss->params.Colors;
+ ss->sizeofPixelOut =
+ ss->params.BitsPerComponentOut / 8 * ss->params.Colors;
+ ss->src_size = ss->sizeofPixelIn * ss->params.WidthIn;
+ ss->dst_size = ss->sizeofPixelOut * ss->params.WidthOut;
+
+ /* Initialize destination DDAs. */
+ ss->dst_x = 0;
+ ss->src_offset = ss->dst_offset = 0;
+ dda_init(ss->dda_x, 0, ss->params.WidthIn, ss->params.WidthOut);
+ ss->dda_x_init = ss->dda_x;
+ ss->src_y = ss->dst_y = 0;
+ dda_init(ss->dda_y, 0, ss->params.HeightOut, ss->params.HeightIn);
+
+ /* Allocate buffers for 2 rows of input data. */
+ ss->prev = gs_alloc_byte_array(mem, ss->params.WidthIn,
+ ss->sizeofPixelOut, "IIEncode prev");
+ ss->cur = gs_alloc_byte_array(mem, ss->params.WidthIn,
+ ss->sizeofPixelOut, "IIEncode cur");
+ if (ss->prev == 0 || ss->cur == 0) {
+ s_IIEncode_release(st);
+ return ERRC; /****** WRONG ******/
+ }
+
+ /* Determine the case for the inner loop. */
+ ss->scale_case =
+ (ss->params.BitsPerComponentIn == 8 ?
+ (ss->params.BitsPerComponentOut == 8 ?
+ (ss->params.MaxValueIn == ss->params.MaxValueOut ?
+ SCALE_SAME : SCALE_8_8) :
+ (ss->params.MaxValueIn == 255 && ss->params.MaxValueOut == frac_1 ?
+ (ss->params.Colors == 3 ? SCALE_8_16_BYTE2FRAC_3 :
+ SCALE_8_16_BYTE2FRAC) :
+ SCALE_8_16_GENERAL)) :
+ (ss->params.BitsPerComponentOut == 8 ? SCALE_16_8 :
+ ss->params.MaxValueIn == ss->params.MaxValueOut ?
+ SCALE_SAME : SCALE_16_16));
+
+ return 0;
+}
+
+/* Process a buffer. */
+private int
+s_IIEncode_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ stream_IIEncode_state *const ss = (stream_IIEncode_state *) st;
+ const scale_case_t scale_case = ss->scale_case +
+ ALIGNMENT_MOD(pw->ptr, 2); /* ptr odd => buffer is aligned */
+ byte *out = pw->ptr + 1;
+ /****** WRONG, requires an entire output pixel ******/
+ byte *limit = pw->limit + 1 - ss->sizeofPixelOut;
+
+ /* Check whether we need to deliver any output. */
+
+top:
+ if (dda_current(ss->dda_y) > ss->dst_y) {
+ /* Deliver some or all of the current scaled row. */
+ while (ss->dst_x < ss->params.WidthOut) {
+ uint sx = dda_current(ss->dda_x) * ss->sizeofPixelIn;
+ const byte *in = (const byte *)ss->cur + sx;
+ int c;
+
+ if (out > limit) {
+ pw->ptr = out - 1;
+ return 1;
+ }
+ switch (scale_case) {
+ case SCALE_SAME:
+ case SCALE_SAME_ALIGNED:
+ memcpy(out, in, ss->sizeofPixelIn);
+ out += ss->sizeofPixelIn;
+ break;
+ case SCALE_8_8:
+ case SCALE_8_8_ALIGNED:
+ for (c = ss->params.Colors; --c >= 0; ++in, ++out)
+ *out = (byte)(*in * ss->params.MaxValueOut /
+ ss->params.MaxValueIn);
+ break;
+ case SCALE_8_16_BYTE2FRAC:
+ case SCALE_8_16_BYTE2FRAC_ALIGNED: /* could be optimized */
+ case SCALE_8_16_BYTE2FRAC_3: /* could be optimized */
+ for (c = ss->params.Colors; --c >= 0; ++in, out += 2) {
+ uint b = *in;
+ uint value = byte2frac(b);
+
+ out[0] = (byte)(value >> 8), out[1] = (byte)value;
+ }
+ break;
+ case SCALE_8_16_BYTE2FRAC_3_ALIGNED:
+ {
+ uint b = in[0];
+
+ ((bits16 *)out)[0] = byte2frac(b);
+ b = in[1];
+ ((bits16 *)out)[1] = byte2frac(b);
+ b = in[2];
+ ((bits16 *)out)[2] = byte2frac(b);
+ }
+ out += 6;
+ break;
+ case SCALE_8_16_GENERAL:
+ case SCALE_8_16_GENERAL_ALIGNED: /* could be optimized */
+ for (c = ss->params.Colors; --c >= 0; ++in, out += 2) {
+ uint value = *in * ss->params.MaxValueOut /
+ ss->params.MaxValueIn;
+
+ out[0] = (byte)(value >> 8), out[1] = (byte)value;
+ }
+ break;
+ case SCALE_16_8:
+ case SCALE_16_8_ALIGNED:
+ for (c = ss->params.Colors; --c >= 0; in += 2, ++out)
+ *out = (byte)(*(const bits16 *)in *
+ ss->params.MaxValueOut /
+ ss->params.MaxValueIn);
+ break;
+ case SCALE_16_16:
+ case SCALE_16_16_ALIGNED: /* could be optimized */
+ for (c = ss->params.Colors; --c >= 0; in += 2, out += 2) {
+ uint value = *(const bits16 *)in *
+ ss->params.MaxValueOut / ss->params.MaxValueIn;
+
+ out[0] = (byte)(value >> 8), out[1] = (byte)value;
+ }
+ }
+ dda_next(ss->dda_x);
+ ss->dst_x++;
+ }
+ ss->dst_x = 0;
+ ss->dst_y++;
+ ss->dda_x = ss->dda_x_init;
+ goto top;
+ }
+ pw->ptr = out - 1;
+ if (ss->dst_y >= ss->params.HeightOut)
+ return EOFC;
+
+ if (ss->src_offset < ss->src_size) {
+ uint count = min(ss->src_size - ss->src_offset, pr->limit - pr->ptr);
+
+ if (count == 0)
+ return 0;
+ memcpy((byte *)ss->cur + ss->src_offset, pr->ptr + 1, count);
+ ss->src_offset += count;
+ pr->ptr += count;
+ if (ss->src_offset < ss->src_size)
+ return 0;
+ }
+ ss->src_offset = 0;
+ ss->dst_x = 0;
+ ss->dda_x = ss->dda_x_init;
+ dda_next(ss->dda_y);
+ goto top;
+}
+
+/* Release the filter's storage. */
+private void
+s_IIEncode_release(stream_state * st)
+{
+ stream_IIEncode_state *const ss = (stream_IIEncode_state *) st;
+ gs_memory_t *mem = ss->memory;
+
+ gs_free_object(mem, ss->cur, "IIEncode cur");
+ ss->cur = 0;
+ gs_free_object(mem, ss->prev, "IIEncode prev");
+ ss->prev = 0;
+}
+
+/* Stream template */
+const stream_template s_IIEncode_template = {
+ &st_IIEncode_state, s_IIEncode_init, s_IIEncode_process, 1, 1,
+ s_IIEncode_release
+};
diff --git a/gs/src/siinterp.h b/gs/src/siinterp.h
new file mode 100644
index 000000000..3b3f0e508
--- /dev/null
+++ b/gs/src/siinterp.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Definitions for image interpolation filter */
+/* Requires strimpl.h */
+
+#ifndef siinterp_INCLUDED
+# define siinterp_INCLUDED
+
+#include "sisparam.h"
+
+extern const stream_template s_IIEncode_template;
+
+#endif /* siinterp_INCLUDED */
diff --git a/gs/src/siscale.c b/gs/src/siscale.c
index 7f9525b5d..9d7c01bc8 100644
--- a/gs/src/siscale.c
+++ b/gs/src/siscale.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#include "memory_.h"
#include "stdio_.h"
#include <assert.h>
+#include "gconfigv.h"
#include "strimpl.h"
#include "siscale.h"
@@ -32,7 +33,88 @@
/* ---------------- ImageScaleEncode/Decode ---------------- */
-public_st_IScale_state(); /* public so clients can allocate */
+/* Define whether to accumulate pixels in fixed or floating point. */
+#if USE_FPU <= 0
+
+ /* Accumulate pixels in fixed point. */
+
+typedef int PixelWeight;
+
+# if arch_ints_are_short
+typedef long AccumTmp;
+# else
+typedef int AccumTmp;
+# endif
+
+#define num_weight_bits\
+ ((sizeof(AccumTmp) - maxSizeofPixel) * 8 - (LOG2_MAX_ISCALE_SUPPORT + 1))
+#define scale_PixelWeight(factor) ((int)((factor) * (1 << num_weight_bits)))
+#define unscale_AccumTmp(atemp) arith_rshift(atemp, num_weight_bits)
+
+#else /* USE_FPU > 0 */
+
+ /* Accumulate pixels in floating point. */
+
+typedef float PixelWeight;
+typedef double AccumTmp;
+
+#define scale_PixelWeight(factor) (factor)
+#define unscale_AccumTmp(atemp) ((int)(atemp))
+
+#endif /* USE_FPU */
+
+/* Temporary intermediate values */
+typedef byte PixelTmp;
+typedef int PixelTmp2; /* extra width for clamping sum */
+
+#define minPixelTmp 0
+#define maxPixelTmp 255
+#define unitPixelTmp 255
+
+/* Max of all pixel sizes */
+#define maxSizeofPixel 2
+
+/* Auxiliary structures. */
+
+typedef struct {
+ PixelWeight weight; /* float or scaled fraction */
+} CONTRIB;
+
+typedef struct {
+ int index; /* index of first element in list of */
+ /* contributors */
+ int n; /* number of contributors */
+ /* (not multiplied by stride) */
+ int first_pixel; /* offset of first value in source data */
+} CLIST;
+
+/* ImageScaleEncode / ImageScaleDecode */
+typedef struct stream_IScale_state_s {
+ /* The client sets the params values before initialization. */
+ stream_image_scale_state_common; /* = state_common + params */
+ /* The init procedure sets the following. */
+ int sizeofPixelIn; /* bytes per input value, 1 or 2 */
+ int sizeofPixelOut; /* bytes per output value, 1 or 2 */
+ double xscale, yscale;
+ void /*PixelIn */ *src;
+ void /*PixelOut */ *dst;
+ PixelTmp *tmp;
+ CLIST *contrib;
+ CONTRIB *items;
+ /* The following are updated dynamically. */
+ int src_y;
+ uint src_offset, src_size;
+ int dst_y;
+ uint dst_offset, dst_size;
+ CLIST dst_next_list; /* for next output value */
+ int dst_last_index; /* highest index used in list */
+ CONTRIB dst_items[MAX_ISCALE_SUPPORT]; /* ditto */
+} stream_IScale_state;
+
+gs_private_st_ptrs5(st_IScale_state, stream_IScale_state,
+ "ImageScaleEncode/Decode state",
+ iscale_state_enum_ptrs, iscale_state_reloc_ptrs,
+ dst, src, tmp, contrib, items);
/* ------ Digital filter definition ------ */
@@ -81,10 +163,10 @@ Mitchell_filter(double t)
/* ------ Auxiliary procedures ------ */
/* Define the minimum scale. */
-#define min_scale ((fWidthIn * 2) / (max_support - 1.01))
+#define min_scale ((fWidthIn * 2) / (MAX_ISCALE_SUPPORT - 1.01))
/* Calculate the support for a given scale. */
-/* The value is always in the range 1 .. max_support. */
+/* The value is always in the range 1 .. MAX_ISCALE_SUPPORT. */
private int
contrib_pixels(double scale)
{
@@ -285,8 +367,8 @@ zoom_y(void /*PixelOut */ *dst, int sizeofPixelOut, uint MaxValueOut,
/* ------ Stream implementation ------ */
-#define tmp_width WidthOut
-#define tmp_height HeightIn
+#define tmp_width params.WidthOut
+#define tmp_height params.HeightIn
/* Forward references */
private void s_IScale_release(P1(stream_state * st));
@@ -295,28 +377,28 @@ private void s_IScale_release(P1(stream_state * st));
private void
calculate_dst_contrib(stream_IScale_state * ss, int y)
{
- uint row_size = ss->WidthOut * ss->Colors;
+ uint row_size = ss->params.WidthOut * ss->params.Colors;
int last_index =
calculate_contrib(&ss->dst_next_list, ss->dst_items, ss->yscale,
- y, 1, ss->HeightIn, max_support, row_size,
- (double)ss->MaxValueOut / unitPixelTmp);
+ y, 1, ss->params.HeightIn, MAX_ISCALE_SUPPORT, row_size,
+ (double)ss->params.MaxValueOut / unitPixelTmp);
int first_index_mod = ss->dst_next_list.first_pixel / row_size;
ss->dst_last_index = last_index;
- last_index %= max_support;
+ last_index %= MAX_ISCALE_SUPPORT;
if (last_index < first_index_mod) { /* Shuffle the indices to account for wraparound. */
- CONTRIB shuffle[max_support];
+ CONTRIB shuffle[MAX_ISCALE_SUPPORT];
int i;
- for (i = 0; i < max_support; ++i)
+ for (i = 0; i < MAX_ISCALE_SUPPORT; ++i)
shuffle[i].weight =
(i <= last_index ?
- ss->dst_items[i + max_support - first_index_mod].weight :
+ ss->dst_items[i + MAX_ISCALE_SUPPORT - first_index_mod].weight :
i >= first_index_mod ?
ss->dst_items[i - first_index_mod].weight :
0);
- memcpy(ss->dst_items, shuffle, max_support * sizeof(CONTRIB));
- ss->dst_next_list.n = max_support;
+ memcpy(ss->dst_items, shuffle, MAX_ISCALE_SUPPORT * sizeof(CONTRIB));
+ ss->dst_next_list.n = MAX_ISCALE_SUPPORT;
ss->dst_next_list.first_pixel = 0;
}
}
@@ -328,33 +410,33 @@ s_IScale_init(stream_state * st)
stream_IScale_state *const ss = (stream_IScale_state *) st;
gs_memory_t *mem = ss->memory;
- ss->sizeofPixelIn = ss->BitsPerComponentIn / 8;
- ss->sizeofPixelOut = ss->BitsPerComponentOut / 8;
- ss->xscale = (double)ss->WidthOut / (double)ss->WidthIn;
- ss->yscale = (double)ss->HeightOut / (double)ss->HeightIn;
+ ss->sizeofPixelIn = ss->params.BitsPerComponentIn / 8;
+ ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8;
+ ss->xscale = (double)ss->params.WidthOut / (double)ss->params.WidthIn;
+ ss->yscale = (double)ss->params.HeightOut / (double)ss->params.HeightIn;
ss->src_y = 0;
- ss->src_size = ss->WidthIn * ss->sizeofPixelIn * ss->Colors;
+ ss->src_size = ss->params.WidthIn * ss->sizeofPixelIn * ss->params.Colors;
ss->src_offset = 0;
ss->dst_y = 0;
- ss->dst_size = ss->WidthOut * ss->sizeofPixelOut * ss->Colors;
+ ss->dst_size = ss->params.WidthOut * ss->sizeofPixelOut * ss->params.Colors;
ss->dst_offset = 0;
/* create intermediate image to hold horizontal zoom */
ss->tmp = (PixelTmp *) gs_alloc_byte_array(mem,
- min(ss->tmp_height, max_support),
- ss->tmp_width * ss->Colors * sizeof(PixelTmp),
+ min(ss->tmp_height, MAX_ISCALE_SUPPORT),
+ ss->tmp_width * ss->params.Colors * sizeof(PixelTmp),
"image_scale tmp");
ss->contrib = (CLIST *) gs_alloc_byte_array(mem,
- max(ss->WidthOut, ss->HeightOut),
+ max(ss->params.WidthOut, ss->params.HeightOut),
sizeof(CLIST), "image_scale contrib");
ss->items = (CONTRIB *) gs_alloc_byte_array(mem,
- contrib_pixels(ss->xscale) * ss->WidthOut,
+ contrib_pixels(ss->xscale) * ss->params.WidthOut,
sizeof(CONTRIB), "image_scale contrib[*]");
/* Allocate buffers for 1 row of source and destination. */
- ss->dst = gs_alloc_byte_array(mem, ss->WidthOut * ss->Colors,
+ ss->dst = gs_alloc_byte_array(mem, ss->params.WidthOut * ss->params.Colors,
ss->sizeofPixelOut, "image_scale dst");
- ss->src = gs_alloc_byte_array(mem, ss->WidthIn * ss->Colors,
+ ss->src = gs_alloc_byte_array(mem, ss->params.WidthIn * ss->params.Colors,
ss->sizeofPixelIn, "image_scale src");
if (ss->tmp == 0 || ss->contrib == 0 || ss->items == 0 ||
ss->dst == 0 || ss->src == 0
@@ -365,8 +447,8 @@ s_IScale_init(stream_state * st)
}
/* Pre-calculate filter contributions for a row. */
calculate_contrib(ss->contrib, ss->items, ss->xscale,
- 0, ss->WidthOut, ss->WidthIn, ss->WidthIn,
- ss->Colors, (double)unitPixelTmp / ss->MaxValueIn);
+ 0, ss->params.WidthOut, ss->params.WidthIn, ss->params.WidthIn,
+ ss->params.Colors, (double)unitPixelTmp / ss->params.MaxValueIn);
/* Prepare the weights for the first output row. */
calculate_dst_contrib(ss, 0);
@@ -388,7 +470,7 @@ s_IScale_process(stream_state * st, stream_cursor_read * pr,
/* to generate a vertically scaled output row. */
uint wleft = pw->limit - pw->ptr;
- if (ss->dst_y == ss->HeightOut)
+ if (ss->dst_y == ss->params.HeightOut)
return EOFC;
if (wleft == 0)
return 1;
@@ -402,8 +484,8 @@ s_IScale_process(stream_state * st, stream_cursor_read * pr,
row = ss->dst;
}
/* Apply filter to zoom vertically from tmp to dst. */
- zoom_y(row, ss->sizeofPixelOut, ss->MaxValueOut, ss->tmp,
- ss->WidthOut, ss->tmp_width, ss->Colors,
+ zoom_y(row, ss->sizeofPixelOut, ss->params.MaxValueOut, ss->tmp,
+ ss->params.WidthOut, ss->tmp_width, ss->params.Colors,
&ss->dst_next_list, ss->dst_items);
/* Idiotic C coercion rules allow T* and void* to be */
/* inter-assigned freely, but not compared! */
@@ -422,7 +504,7 @@ s_IScale_process(stream_state * st, stream_cursor_read * pr,
}
/* Advance to the next output row. */
adv:++(ss->dst_y);
- if (ss->dst_y != ss->HeightOut)
+ if (ss->dst_y != ss->params.HeightOut)
calculate_dst_contrib(ss, ss->dst_y);
}
@@ -435,7 +517,7 @@ s_IScale_process(stream_state * st, stream_cursor_read * pr,
if (rleft == 0)
return 0; /* need more input */
#ifdef DEBUG
- assert(ss->src_y < ss->HeightIn);
+ assert(ss->src_y < ss->params.HeightIn);
#endif
if (rleft >= rcount) { /* We're going to fill up a row. */
const byte *row;
@@ -450,10 +532,10 @@ s_IScale_process(stream_state * st, stream_cursor_read * pr,
ss->src_offset = 0;
}
/* Apply filter to zoom horizontally from src to tmp. */
- zoom_x(ss->tmp + (ss->src_y % max_support) *
- ss->tmp_width * ss->Colors, row,
- ss->sizeofPixelIn, ss->tmp_width, ss->WidthIn,
- ss->Colors, ss->contrib, ss->items);
+ zoom_x(ss->tmp + (ss->src_y % MAX_ISCALE_SUPPORT) *
+ ss->tmp_width * ss->params.Colors, row,
+ ss->sizeofPixelIn, ss->tmp_width, ss->params.WidthIn,
+ ss->params.Colors, ss->contrib, ss->items);
pr->ptr += rcount;
++(ss->src_y);
goto top;
diff --git a/gs/src/siscale.h b/gs/src/siscale.h
index 4084248d6..5f14231e7 100644
--- a/gs/src/siscale.h
+++ b/gs/src/siscale.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,121 +22,8 @@
#ifndef siscale_INCLUDED
# define siscale_INCLUDED
-#include "gconfigv.h"
+#include "sisparam.h"
-/* Define whether to accumulate pixels in fixed or floating point. */
-#if USE_FPU <= 0
-
- /* Accumulate pixels in fixed point. */
-
-typedef int PixelWeight;
-
-# if arch_ints_are_short
-typedef long AccumTmp;
-
-# else
-typedef int AccumTmp;
-
-# endif
-#define num_weight_bits\
- ((sizeof(AccumTmp) - maxSizeofPixel) * 8 - (log2_max_support + 1))
-#define scale_PixelWeight(factor) ((int)((factor) * (1 << num_weight_bits)))
-#define unscale_AccumTmp(atemp) arith_rshift(atemp, num_weight_bits)
-
-#else /* USE_FPU > 0 */
-
- /* Accumulate pixels in floating point. */
-
-typedef float PixelWeight;
-typedef double AccumTmp;
-
-#define scale_PixelWeight(factor) (factor)
-#define unscale_AccumTmp(atemp) ((int)(atemp))
-
-#endif /* USE_FPU */
-
-/* Input values */
- /*typedef byte PixelIn; *//* see sizeofPixelIn below */
- /*#define MaxValueIn 255 *//* see MaxValueIn below */
-
-/* Temporary intermediate values */
-typedef byte PixelTmp;
-typedef int PixelTmp2; /* extra width for clamping sum */
-
-#define minPixelTmp 0
-#define maxPixelTmp 255
-#define unitPixelTmp 255
-
-/* Max of all pixel sizes */
-#define maxSizeofPixel 2
-
-/* Output values */
- /*typedef byte PixelOut; *//* see sizeofPixelOut below */
- /*#define MaxValueOut 255 *//* see MaxValueOut below */
-
-/*
- * The 'support' S of the digital filter is the value such that the filter
- * is guaranteed to be zero for all arguments outside the range [-S..S].
- * We artificially limit the support so that we can put an upper bound
- * on the time required to compute an output value and on the amount of
- * storage required for the X-filtered input data; this also allows us
- * to use pre-scaled fixed-point values for the weights if we wish.
- *
- * 8x8 pixels should be enough for any reasonable application....
- */
-#define log2_max_support 3
-#define max_support (1 << log2_max_support)
-
-/* Auxiliary structures. */
-
-typedef struct {
- PixelWeight weight; /* float or scaled fraction */
-} CONTRIB;
-
-typedef struct {
- int index; /* index of first element in list of */
- /* contributors */
- int n; /* number of contributors */
- /* (not multiplied by stride) */
- int first_pixel; /* offset of first value in source data */
-} CLIST;
-
-/* ImageScaleEncode / ImageScaleDecode */
-typedef struct stream_IScale_state_s {
- stream_state_common;
- /* The client sets the following before initialization. */
- int Colors; /* any number >= 1 */
- int BitsPerComponentIn; /* bits per input value, 8 or 16 */
- uint MaxValueIn; /* max value of input component */
- int WidthIn, HeightIn;
- int BitsPerComponentOut; /* bits per output value, 8 or 16 */
- uint MaxValueOut; /* max value of output component */
- int WidthOut, HeightOut;
- /* The init procedure sets the following. */
- int sizeofPixelIn; /* bytes per input value, 1 or 2 */
- int sizeofPixelOut; /* bytes per output value, 1 or 2 */
- double xscale, yscale;
- void /*PixelIn */ *src;
- void /*PixelOut */ *dst;
- PixelTmp *tmp;
- CLIST *contrib;
- CONTRIB *items;
- /* The following are updated dynamically. */
- int src_y;
- uint src_offset, src_size;
- int dst_y;
- uint dst_offset, dst_size;
- CLIST dst_next_list; /* for next output value */
- int dst_last_index; /* highest index used in list */
- CONTRIB dst_items[max_support]; /* ditto */
-} stream_IScale_state;
-
-extern_st(st_IScale_state); /* so clients can allocate */
-#define public_st_IScale_state() /* in siscale.c */\
- gs_public_st_ptrs5(st_IScale_state, stream_IScale_state,\
- "ImageScaleEncode/Decode state",\
- iscale_state_enum_ptrs, iscale_state_reloc_ptrs,\
- dst, src, tmp, contrib, items)
extern const stream_template s_IScale_template;
#endif /* siscale_INCLUDED */
diff --git a/gs/src/sisparam.h b/gs/src/sisparam.h
new file mode 100644
index 000000000..fd4387187
--- /dev/null
+++ b/gs/src/sisparam.h
@@ -0,0 +1,75 @@
+/* Copyright (C) 1995, 1996, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Generic image scaling stream definitions */
+/* Requires strimpl.h */
+
+#ifndef sisparam_INCLUDED
+# define sisparam_INCLUDED
+
+/*
+ * Image scaling streams all use a common set of parameters to define the
+ * input and output data. That is what we define here.
+ */
+
+/* Input values */
+/*typedef byte PixelIn; */ /* per BitsPerComponentIn */
+/*#define MaxValueIn 255 */ /* per MaxValueIn */
+
+/* Output values */
+/*typedef byte PixelOut; */ /* per BitsPerComponentOut */
+/*#define MaxValueOut 255 */ /* per MaxValueOut */
+
+/*
+ * The 'support' S of a digital filter is the value such that the filter is
+ * guaranteed to be zero for all arguments outside the range [-S..S]. We
+ * limit the support so that we can put an upper bound on the time required
+ * to compute an output value and on the amount of storage required for
+ * X-filtered input data; this also allows us to use pre-scaled fixed-point
+ * values for the weights if we wish.
+ *
+ * 8x8 pixels should be enough for any reasonable application....
+ */
+#define LOG2_MAX_ISCALE_SUPPORT 3
+#define MAX_ISCALE_SUPPORT (1 << LOG2_MAX_ISCALE_SUPPORT)
+
+/* Define image scaling stream parameters. */
+typedef struct stream_image_scale_params_s {
+ int Colors; /* >= 1 */
+ int BitsPerComponentIn; /* bits per input value, 8 or 16 */
+ uint MaxValueIn; /* max value of input component, */
+ /* 0 < MaxValueIn < 1 << BitsPerComponentIn */
+ int WidthIn, HeightIn; /* > 0 */
+ int BitsPerComponentOut; /* bits per output value, 8 or 16 */
+ uint MaxValueOut; /* max value of output component, */
+ /* 0 < MaxValueOut < 1 << BitsPerComponentOut*/
+ int WidthOut, HeightOut; /* > 0 */
+} stream_image_scale_params_t;
+
+/* Define a generic image scaling stream state. */
+
+#define stream_image_scale_state_common\
+ stream_state_common;\
+ stream_image_scale_params_t params
+
+typedef struct stream_image_scale_state_s {
+ stream_image_scale_state_common;
+} stream_image_scale_state;
+
+#endif /* sisparam_INCLUDED */
diff --git a/gs/src/sjpegc.c b/gs/src/sjpegc.c
index 655ddaaaf..e2d53d012 100644
--- a/gs/src/sjpegc.c
+++ b/gs/src/sjpegc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,19 +20,14 @@
/* Interface routines for IJG code, common to encode/decode. */
#include "stdio_.h"
#include "string_.h"
-#include "jpeglib.h"
-#include "jerror.h"
+#include "jpeglib_.h"
+#include "jerror_.h"
#include "gx.h"
#include "gserrors.h"
#include "strimpl.h"
#include "sdct.h"
#include "sjpeg.h"
-/* gs_jpeg_message_table() is kept in a separate file for arcane reasons.
- * See sjpegerr.c.
- */
-const char *const *gs_jpeg_message_table(P1(void));
-
/*
* Error handling routines (these replace corresponding IJG routines from
* jpeg/jerror.c). These are used for both compression and decompression.
@@ -67,66 +62,6 @@ gs_jpeg_emit_message(j_common_ptr cinfo, int msg_level)
}
/*
- * This is an exact copy of format_message from jpeg/jerror.c.
- * We do not use jerror.c in Ghostscript, so we have to duplicate this routine.
- */
-
-private void
-gs_jpeg_format_message(j_common_ptr cinfo, char *buffer)
-{
- struct jpeg_error_mgr *err = cinfo->err;
- int msg_code = err->msg_code;
- const char *msgtext = NULL;
- const char *msgptr;
- char ch;
- boolean isstring;
-
- /* Look up message string in proper table */
- if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
- msgtext = err->jpeg_message_table[msg_code];
- } else if (err->addon_message_table != NULL &&
- msg_code >= err->first_addon_message &&
- msg_code <= err->last_addon_message) {
- msgtext = err->addon_message_table[msg_code - err->first_addon_message];
- }
- /* Defend against bogus message number */
- if (msgtext == NULL) {
- err->msg_parm.i[0] = msg_code;
- msgtext = err->jpeg_message_table[0];
- }
- /* Check for string parameter, as indicated by %s in the message text */
- isstring = FALSE;
- msgptr = msgtext;
- while ((ch = *msgptr++) != '\0') {
- if (ch == '%') {
- if (*msgptr == 's')
- isstring = TRUE;
- break;
- }
- }
-
- /* Format the message into the passed buffer */
- if (isstring)
- sprintf(buffer, msgtext, err->msg_parm.s);
- else
- sprintf(buffer, msgtext,
- err->msg_parm.i[0], err->msg_parm.i[1],
- err->msg_parm.i[2], err->msg_parm.i[3],
- err->msg_parm.i[4], err->msg_parm.i[5],
- err->msg_parm.i[6], err->msg_parm.i[7]);
-}
-
-/* And this is an exact copy of another routine from jpeg/jerror.c. */
-
-private void
-gs_jpeg_reset_error_mgr(j_common_ptr cinfo)
-{
- cinfo->err->num_warnings = 0;
- /* trace_level is not reset since it is an application-supplied parameter */
- cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
-}
-
-/*
* This routine initializes the error manager fields in the JPEG object.
* It is based on jpeg_std_error from jpeg/jerror.c.
*/
@@ -136,27 +71,12 @@ gs_jpeg_error_setup(stream_DCT_state * st)
{
struct jpeg_error_mgr *err = &st->data.common->err;
+ /* Initialize the JPEG compression object with default error handling */
+ jpeg_std_error(err);
+
+ /* Replace some methods with our own versions */
err->error_exit = gs_jpeg_error_exit;
err->emit_message = gs_jpeg_emit_message;
- /* We need not set the output_message field since gs_jpeg_emit_message
- * doesn't call it, and the IJG library never calls output_message directly.
- * Setting the format_message field isn't strictly necessary either,
- * since gs_jpeg_log_error calls gs_jpeg_format_message directly.
- */
- err->format_message = gs_jpeg_format_message;
- err->reset_error_mgr = gs_jpeg_reset_error_mgr;
-
- err->trace_level = 0; /* default = no tracing */
- err->num_warnings = 0; /* no warnings emitted yet */
- err->msg_code = 0; /* may be useful as a flag for "no error" */
-
- /* Initialize message table pointers */
- err->jpeg_message_table = gs_jpeg_message_table();
- err->last_jpeg_message = (int)JMSG_LASTMSGCODE - 1;
-
- err->addon_message_table = NULL;
- err->first_addon_message = 0; /* for safety */
- err->last_addon_message = 0;
st->data.compress->cinfo.err = err; /* works for decompress case too */
}
@@ -170,7 +90,7 @@ gs_jpeg_log_error(stream_DCT_state * st)
char buffer[JMSG_LENGTH_MAX];
/* Format the error message */
- gs_jpeg_format_message(cinfo, buffer);
+ (*cinfo->err->format_message) (cinfo, buffer);
(*st->report_error) ((stream_state *) st, buffer);
return gs_error_ioerror; /* caller will do return_error() */
}
diff --git a/gs/src/sjpegd.c b/gs/src/sjpegd.c
index e5ff4d206..5e8402e60 100644
--- a/gs/src/sjpegd.c
+++ b/gs/src/sjpegd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,8 +20,8 @@
/* Interface routines for IJG decoding code. */
#include "stdio_.h"
#include "string_.h"
-#include "jpeglib.h"
-#include "jerror.h"
+#include "jpeglib_.h"
+#include "jerror_.h"
#include "gx.h"
#include "gserrors.h"
#include "strimpl.h"
diff --git a/gs/src/sjpege.c b/gs/src/sjpege.c
index b4e374d40..a0df585a4 100644
--- a/gs/src/sjpege.c
+++ b/gs/src/sjpege.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,8 +20,8 @@
/* Interface routines for IJG encoding code. */
#include "stdio_.h"
#include "string_.h"
-#include "jpeglib.h"
-#include "jerror.h"
+#include "jpeglib_.h"
+#include "jerror_.h"
#include "gx.h"
#include "gserrors.h"
#include "strimpl.h"
diff --git a/gs/src/sjpegerr.c b/gs/src/sjpegerr.c
deleted file mode 100644
index fa16d4e2e..000000000
--- a/gs/src/sjpegerr.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (C) 1994, 1995, 1998 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
-
-/* IJG error message table for Ghostscript. */
-#include "stdio_.h"
-#include "jpeglib.h"
-#include "jversion.h"
-
-/*
- * This file exists solely to hold the rather large IJG error message string
- * table (now about 4K, and likely to grow in future releases). The table
- * is large enough that we don't want it to be in the default data segment
- * in a 16-bit executable.
- *
- * In IJG version 5 and earlier, under Borland C, this is accomplished simply
- * by compiling this one file in "huge" memory model rather than "large".
- * The string constants will then go into a private far data segment.
- * In less brain-damaged architectures, this file is simply compiled normally,
- * and we pay only the price of one extra function call.
- *
- * In IJG version 5a and later, under Borland C, this is accomplished by making
- * each string be a separate variable that's explicitly declared "far".
- * (What a crock...)
- *
- * This must be a separate file to avoid duplicate-symbol errors, since we
- * use the IJG message code names as variables rather than as enum constants.
- */
-
-#if JPEG_LIB_VERSION <= 50 /**************** *************** */
-
-#include "jerror.h" /* get error codes */
-#define JMAKE_MSG_TABLE
-#include "jerror.h" /* create message string table */
-
-#define jpeg_std_message_table jpeg_message_table
-
-#else /* JPEG_LIB_VERSION >= 51 */ /**************** *************** */
-
-/* Create a static const char[] variable for each message string. */
-
-#define JMESSAGE(code,string) static const char code[] = string;
-
-#include "jerror.h"
-
-/* Now build an array of pointers to same. */
-
-#define JMESSAGE(code,string) code ,
-
-static const char *const jpeg_std_message_table[] =
-{
-#include "jerror.h"
- NULL
-};
-
-#endif /* JPEG_LIB_VERSION */ /**************** *************** */
-
-/*
- * Return a pointer to the message table.
- * It is unsafe to do much more than this within the "huge" environment.
- */
-
-const char *const *
-gs_jpeg_message_table(void)
-{
- return jpeg_std_message_table;
-}
diff --git a/gs/src/spcxd.c b/gs/src/spcxd.c
deleted file mode 100644
index 40dd56684..000000000
--- a/gs/src/spcxd.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
-
-/* PCXDecode filter */
-#include "stdio_.h" /* includes std.h */
-#include "memory_.h"
-#include "strimpl.h"
-#include "spcxx.h"
-
-/* ------ PCXDecode ------ */
-
-/* Refill the buffer */
-private int
-s_PCXD_process(stream_state * st, stream_cursor_read * pr,
- stream_cursor_write * pw, bool last)
-{
- register const byte *p = pr->ptr;
- register byte *q = pw->ptr;
- const byte *rlimit = pr->limit;
- byte *wlimit = pw->limit;
- int status = 0;
-
- while (p < rlimit) {
- int b = *++p;
-
- if (b < 0xc0) {
- if (q >= wlimit) {
- --p;
- status = 1;
- break;
- }
- *++q = b;
- } else if (p >= rlimit) {
- --p;
- break;
- } else if ((b -= 0xc0) > wlimit - q) {
- --p;
- status = 1;
- break;
- } else {
- memset(q + 1, *++p, b);
- q += b;
- }
- }
- pr->ptr = p;
- pw->ptr = q;
- return status;
-}
-
-/* Stream template */
-const stream_template s_PCXD_template = {
- &st_stream_state, NULL, s_PCXD_process, 2, 63
-};
diff --git a/gs/src/spdiff.c b/gs/src/spdiff.c
index c72ecf1f3..c6df11094 100644
--- a/gs/src/spdiff.c
+++ b/gs/src/spdiff.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,6 +19,7 @@
/* Pixel differencing filters */
#include "stdio_.h" /* should be std.h, but needs NULL */
+#include "memory_.h"
#include "strimpl.h"
#include "spdiffx.h"
@@ -28,11 +29,11 @@ private_st_PDiff_state();
/* Define values for case dispatch. */
#define cBits1 0
-#define cBits2 4
-#define cBits4 8
-#define cBits8 12
-#define cEncode -1
-#define cDecode 15
+#define cBits2 5
+#define cBits4 10
+#define cBits8 15
+#define cEncode 0
+#define cDecode 20
/* Set defaults */
private void
@@ -58,15 +59,17 @@ private int
s_PDiffE_init(stream_state * st)
{
stream_PDiff_state *const ss = (stream_PDiff_state *) st;
- long bits_per_row =
- ss->Colors * ss->BitsPerComponent * (long)ss->Columns;
- static const byte cb_values[] =
- {0, cBits1, cBits2, 0, cBits4, 0, 0, 0, cBits8};
+ int bits_per_row =
+ ss->Colors * ss->BitsPerComponent * ss->Columns;
+ static const byte cb_values[] = {
+ 0, cBits1, cBits2, 0, cBits4, 0, 0, 0, cBits8
+ };
- ss->row_count = (uint) ((bits_per_row + 7) >> 3);
+ ss->row_count = (bits_per_row + 7) >> 3;
ss->end_mask = (1 << (-bits_per_row & 7)) - 1;
ss->case_index =
- cb_values[ss->BitsPerComponent] + ss->Colors + cEncode;
+ cb_values[ss->BitsPerComponent] +
+ (ss->Colors > 4 ? 0 : ss->Colors) + cEncode;
return s_PDiff_reinit(st);
}
@@ -89,25 +92,29 @@ s_PDiff_process(stream_state * st, stream_cursor_read * pr,
stream_PDiff_state *const ss = (stream_PDiff_state *) st;
register const byte *p = pr->ptr;
register byte *q = pw->ptr;
- int rcount, wcount;
register int count;
int status = 0;
- register byte s0 = ss->s0;
+ register byte s0 = ss->prev[0];
register byte t;
- byte save_last;
const byte end_mask = ss->end_mask;
+ int colors = ss->Colors;
+ int ci;
- row:if (ss->row_left == 0)
- ss->row_left = ss->row_count,
- s0 = ss->s1 = ss->s2 = ss->s3 = 0;
- rcount = pr->limit - p;
- wcount = pw->limit - q;
- if (ss->row_left < rcount)
- rcount = ss->row_left;
- count = (wcount < rcount ? (status = 1, wcount) : rcount);
+row:
+ if (ss->row_left == 0) {
+ ss->row_left = ss->row_count;
+ s0 = 0;
+ memset(ss->prev + 1, s_PDiff_max_Colors - 1, 0);
+ }
+ {
+ int rcount = pr->limit - p;
+ int wcount = pw->limit - q;
+
+ if (ss->row_left < rcount)
+ rcount = ss->row_left;
+ count = (wcount < rcount ? (status = 1, wcount) : rcount);
+ }
ss->row_left -= count;
- if (ss->row_left == count)
- save_last = p[count];
/*
* Encoding and decoding are fundamentally different.
@@ -117,212 +124,290 @@ s_PDiff_process(stream_state * st, stream_cursor_read * pr,
* we put the code for both functions in the same place.
*/
-#define loopn(n, body)\
- while ( count >= n ) p += n, q += n, body, count -= n
+#define LOOP_BY(n, body)\
+ for (; count >= n; count -= n) p += n, q += n, body
switch (ss->case_index) {
/* 1 bit per component */
-#define eloop1(ee)\
- loopn(1, (t = *p, *q = ee, s0 = t))
+#define ENCODE1_LOOP(ee)\
+ LOOP_BY(1, (t = *p, *q = ee, s0 = t)); break
+
+ case cEncode + cBits1 + 0:
+ break; /****** NYI ******/
case cEncode + cBits1 + 1:
- eloop1(t ^ ((s0 << 7) | (t >> 1)));
+ ENCODE1_LOOP(t ^ ((s0 << 7) | (t >> 1)));
case cEncode + cBits1 + 2:
- eloop1(t ^ ((s0 << 6) | (t >> 2)));
+ ENCODE1_LOOP(t ^ ((s0 << 6) | (t >> 2)));
case cEncode + cBits1 + 3:
- eloop1(t ^ ((s0 << 5) | (t >> 3)));
+ ENCODE1_LOOP(t ^ ((s0 << 5) | (t >> 3)));
case cEncode + cBits1 + 4:
- eloop1(t ^ ((s0 << 4) | (t >> 4)));
+ ENCODE1_LOOP(t ^ ((s0 << 4) | (t >> 4)));
+
+#define DECODE1_LOOP(te, de)\
+ LOOP_BY(1, (t = te, s0 = *q = de)); break
-#define dloop1(te, de)\
- loopn(1, (t = te, s0 = *q = de)); break
+ case cDecode + cBits1 + 0:
+ break; /****** NYI ******/
case cDecode + cBits1 + 1:
- dloop1(*p ^ (s0 << 7),
- (t ^= t >> 1, t ^= t >> 2, t ^ (t >> 4)));
+ DECODE1_LOOP(*p ^ (s0 << 7),
+ (t ^= t >> 1, t ^= t >> 2, t ^ (t >> 4)));
case cDecode + cBits1 + 2:
- dloop1(*p ^ (s0 << 6),
- (t ^= (t >> 2), t ^ (t >> 4)));
+ DECODE1_LOOP(*p ^ (s0 << 6),
+ (t ^= (t >> 2), t ^ (t >> 4)));
case cDecode + cBits1 + 3:
- dloop1(*p ^ (s0 << 5),
- t ^ (t >> 3) ^ (t >> 6));
+ DECODE1_LOOP(*p ^ (s0 << 5),
+ t ^ (t >> 3) ^ (t >> 6));
case cDecode + cBits1 + 4:
- dloop1(*p ^ (s0 << 4),
- t ^ (t >> 4));
+ DECODE1_LOOP(*p ^ (s0 << 4),
+ t ^ (t >> 4));
/* 2 bits per component */
-#define add4x2(a, b) ( (((a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
-#define sub4x2(a, b) ( ((~(a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
+#define ADD4X2(a, b) ( (((a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
+/* The following computation looks very implausible, but it is correct. */
+#define SUB4X2(a, b) ( ((~(a) & (b) & 0x55) << 1) ^ (a) ^ (b) )
+
+ case cEncode + cBits2 + 0:
+ break; /****** NYI ******/
case cEncode + cBits2 + 1:
- eloop1((s0 = (s0 << 6) | (t >> 2), sub4x2(t, s0)));
+ ENCODE1_LOOP((s0 = (s0 << 6) | (t >> 2), SUB4X2(t, s0)));
case cEncode + cBits2 + 2:
- eloop1((s0 = (s0 << 4) | (t >> 4), sub4x2(t, s0)));
+ ENCODE1_LOOP((s0 = (s0 << 4) | (t >> 4), SUB4X2(t, s0)));
case cEncode + cBits2 + 3:
- eloop1((s0 = (s0 << 2) | (t >> 6), sub4x2(t, s0)));
+ ENCODE1_LOOP((s0 = (s0 << 2) | (t >> 6), SUB4X2(t, s0)));
case cEncode + cBits2 + 4:
- eloop1(sub4x2(t, s0));
+ ENCODE1_LOOP(SUB4X2(t, s0));
+
+ case cDecode + cBits2 + 0:
+ break; /****** NYI ******/
case cDecode + cBits2 + 1:
- dloop1(*p + (s0 << 6),
- (t = add4x2(t >> 2, t),
- add4x2(t >> 4, t)));
+ DECODE1_LOOP(*p + (s0 << 6),
+ (t = ADD4X2(t >> 2, t),
+ ADD4X2(t >> 4, t)));
case cDecode + cBits2 + 2:
- dloop1(*p, (t = add4x2(t, s0 << 4),
- add4x2(t >> 4, t)));
+ DECODE1_LOOP(*p, (t = ADD4X2(t, s0 << 4),
+ ADD4X2(t >> 4, t)));
case cDecode + cBits2 + 3:
- dloop1(*p, (t = add4x2(t, s0 << 2),
- add4x2(t >> 6, t)));
+ DECODE1_LOOP(*p, (t = ADD4X2(t, s0 << 2),
+ ADD4X2(t >> 6, t)));
case cDecode + cBits2 + 4:
- dloop1(*p, add4x2(t, s0));
+ DECODE1_LOOP(*p, ADD4X2(t, s0));
-#undef add4x2
-#undef sub4x2
+#undef ADD4X2
+#undef SUB4X2
/* 4 bits per component */
-#define add2x4(a, b) ( (((a) + (b)) & 0xf) + ((a) & 0xf0) + ((b) & 0xf0) )
-#define add2x4r4(a) ( (((a) + ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
-#define sub2x4(a, b) ( (((a) - (b)) & 0xf) + ((a) & 0xf0) - ((b) & 0xf0) )
-#define sub2x4r4(a) ( (((a) - ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
+#define ADD2X4(a, b) ( (((a) + (b)) & 0xf) + ((a) & 0xf0) + ((b) & 0xf0) )
+#define ADD2X4R4(a) ( (((a) + ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
+#define SUB2X4(a, b) ( (((a) - (b)) & 0xf) + ((a) & 0xf0) - ((b) & 0xf0) )
+#define SUB2X4R4(a) ( (((a) - ((a) >> 4)) & 0xf) + ((a) & 0xf0) )
+
+ case cEncode + cBits4 + 0: { /* Colors > 4 */
+ int nb = colors >> 1;
+
+ if (colors & 1) {
+ /****** WRONG ******/
+ for (; count >= nb; count -= nb)
+ for (ci = 1; ci <= nb; ++ci) {
+ ++p, ++q;
+ t = (s0 << 4) | (ss->prev[ci] >> 4);
+ s0 = ss->prev[ci];
+ ss->prev[ci] = *q = ADD2X4(*p, t);
+ }
+ } else {
+ ss->prev[0] = s0;
+ for (; count >= nb; count -= nb)
+ for (ci = 0; ci < nb; ++ci)
+ ++p, ++q, t = *p, *q = SUB2X4(t, ss->prev[ci]),
+ ss->prev[ci] = t;
+ s0 = ss->prev[0];
+ }
+ } break;
case cEncode + cBits4 + 1:
- eloop1(((t - (s0 << 4)) & 0xf0) | ((t - (t >> 4)) & 0xf));
+ ENCODE1_LOOP(((t - (s0 << 4)) & 0xf0) | ((t - (t >> 4)) & 0xf));
+
case cEncode + cBits4 + 2:
- eloop1(sub2x4(t, s0));
- case cEncode + cBits4 + 3:
- {
- register byte s1 = ss->s1;
-
- loopn(1, (t = *p,
- *q =
- ((t - (s0 << 4)) & 0xf0) | ((t - (s1 >> 4)) & 0xf),
- s0 = s1, s1 = t));
- ss->s1 = s1;
- } break;
- case cEncode + cBits4 + 4:
- {
- register byte s1 = ss->s1;
-
- loopn(2,
- (t = p[-1], q[-1] = sub2x4(t, s0), s0 = t,
- t = *p, *q = sub2x4(t, s1), s1 = t));
- ss->s1 = s1;
- } break;
+ ENCODE1_LOOP(SUB2X4(t, s0));
+
+ case cEncode + cBits4 + 3: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(1,
+ (t = *p,
+ *q = ((t - (s0 << 4)) & 0xf0) | ((t - (s1 >> 4)) & 0xf),
+ s0 = s1, s1 = t));
+ ss->prev[1] = s1;
+ } break;
+
+ case cEncode + cBits4 + 4: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(2,
+ (t = p[-1], q[-1] = SUB2X4(t, s0), s0 = t,
+ t = *p, *q = SUB2X4(t, s1), s1 = t));
+ ss->prev[1] = s1;
+ } break;
+
+ case cDecode + cBits4 + 0: { /* Colors > 4 */
+ int nb = colors >> 1;
+
+ if (colors & 1) {
+ /****** WRONG ******/
+ for (; count >= nb; count -= nb)
+ for (ci = 1; ci <= nb; ++ci) {
+ ++p, ++q;
+ t = (s0 << 4) | (ss->prev[ci] >> 4);
+ s0 = ss->prev[ci];
+ ss->prev[ci] = *q = ADD2X4(*p, t);
+ }
+ } else {
+ ss->prev[0] = s0;
+ for (; count >= nb; count -= nb)
+ for (ci = 0; ci < nb; ++ci)
+ ++p, ++q, ss->prev[ci] = *q = ADD2X4(*p, ss->prev[ci]);
+ s0 = ss->prev[0];
+ }
+ } break;
case cDecode + cBits4 + 1:
- dloop1(*p + (s0 << 4), add2x4r4(t));
+ DECODE1_LOOP(*p + (s0 << 4), ADD2X4R4(t));
+
case cDecode + cBits4 + 2:
- dloop1(*p, add2x4(t, s0));
- case cDecode + cBits4 + 3:
- {
- register byte s1 = ss->s1;
-
- loopn(1, (t = (s0 << 4) + (s1 >> 4),
- s0 = s1, s1 = *q = add2x4(*p, t)));
- ss->s1 = s1;
- } break;
- case cDecode + cBits4 + 4:
- {
- register byte s1 = ss->s1;
-
- loopn(2,
- (t = p[-1], s0 = q[-1] = add2x4(s0, t),
- t = *p, s1 = *q = add2x4(s1, t)));
- ss->s1 = s1;
- } break;
-
-#undef add2x4
-#undef add2x4r4
-#undef sub2x4
-#undef sub2x4r4
+ DECODE1_LOOP(*p, ADD2X4(t, s0));
+
+ case cDecode + cBits4 + 3: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(1, (t = (s0 << 4) + (s1 >> 4),
+ s0 = s1, s1 = *q = ADD2X4(*p, t)));
+ ss->prev[1] = s1;
+ } break;
+
+ case cDecode + cBits4 + 4: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(2,
+ (t = p[-1], s0 = q[-1] = ADD2X4(s0, t),
+ t = *p, s1 = *q = ADD2X4(s1, t)));
+ ss->prev[1] = s1;
+ } break;
+
+#undef ADD2X4
+#undef ADD2X4R4
+#undef SUB2X4
+#undef SUB2X4R4
/* 8 bits per component */
-#define encode8(s, d) (q[d] = p[d] - s, s = p[d])
-#define decode8(s, d) s = q[d] = s + p[d]
+#define ENCODE8(s, d) (q[d] = p[d] - s, s = p[d])
+#define DECODE8(s, d) q[d] = s += p[d]
+
+ case cEncode + cBits8 + 0: { /* Colors > 4 */
+ ss->prev[0] = s0;
+ for (; count >= colors; count -= colors)
+ for (ci = 0; ci < colors; ++ci) {
+ *++q = *++p - ss->prev[ci];
+ ss->prev[ci] = *p;
+ }
+ s0 = ss->prev[0];
+ } break;
+
+ case cDecode + cBits8 + 0: { /* Colors > 4 */
+ ss->prev[0] = s0;
+ for (; count >= colors; count -= colors)
+ for (ci = 0; ci < colors; ++ci)
+ *++q = ss->prev[ci] += *++p;
+ s0 = ss->prev[0];
+ } break;
case cEncode + cBits8 + 1:
- loopn(1, encode8(s0, 0));
+ LOOP_BY(1, ENCODE8(s0, 0));
break;
+
case cDecode + cBits8 + 1:
- loopn(1, decode8(s0, 0));
+ LOOP_BY(1, DECODE8(s0, 0));
break;
- case cEncode + cBits8 + 2:
- {
- register byte s1 = ss->s1;
-
- loopn(2, (encode8(s0, -1), encode8(s1, 0)));
- ss->s1 = s1;
- } break;
- case cDecode + cBits8 + 2:
- {
- register byte s1 = ss->s1;
-
- loopn(2, (decode8(s0, -1), decode8(s1, 0)));
- ss->s1 = s1;
- } break;
- case cEncode + cBits8 + 3:
- {
- register byte s1 = ss->s1, s2 = ss->s2;
-
- loopn(3, (encode8(s0, -2), encode8(s1, -1),
- encode8(s2, 0)));
- ss->s1 = s1, ss->s2 = s2;
- } break;
- case cDecode + cBits8 + 3:
- {
- register byte s1 = ss->s1, s2 = ss->s2;
-
- loopn(3, (decode8(s0, -2), decode8(s1, -1),
- decode8(s2, 0)));
- ss->s1 = s1, ss->s2 = s2;
- } break;
- case cEncode + cBits8 + 4:
- {
- register byte s1 = ss->s1, s2 = ss->s2, s3 = ss->s3;
-
- loopn(4, (encode8(s0, -3), encode8(s1, -2),
- encode8(s2, -1), encode8(s3, 0)));
- ss->s1 = s1, ss->s2 = s2, ss->s3 = s3;
- } break;
- case cDecode + cBits8 + 4:
- {
- register byte s1 = ss->s1, s2 = ss->s2, s3 = ss->s3;
-
- loopn(4, (decode8(s0, -3), decode8(s1, -2),
- decode8(s2, -1), decode8(s3, 0)));
- ss->s1 = s1, ss->s2 = s2, ss->s3 = s3;
- } break;
-
-#undef encode8
-#undef decode8
+
+ case cEncode + cBits8 + 2: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(2, (ENCODE8(s0, -1), ENCODE8(s1, 0)));
+ ss->prev[1] = s1;
+ } break;
+
+ case cDecode + cBits8 + 2: {
+ register byte s1 = ss->prev[1];
+
+ LOOP_BY(2, (DECODE8(s0, -1), DECODE8(s1, 0)));
+ ss->prev[1] = s1;
+ } break;
+
+ case cEncode + cBits8 + 3: {
+ register byte s1 = ss->prev[1], s2 = ss->prev[2];
+
+ LOOP_BY(3, (ENCODE8(s0, -2), ENCODE8(s1, -1),
+ ENCODE8(s2, 0)));
+ ss->prev[1] = s1, ss->prev[2] = s2;
+ } break;
+
+ case cDecode + cBits8 + 3: {
+ register byte s1 = ss->prev[1], s2 = ss->prev[2];
+
+ LOOP_BY(3, (DECODE8(s0, -2), DECODE8(s1, -1),
+ DECODE8(s2, 0)));
+ ss->prev[1] = s1, ss->prev[2] = s2;
+ } break;
+
+ case cEncode + cBits8 + 4: {
+ register byte s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
+
+ LOOP_BY(4, (ENCODE8(s0, -3), ENCODE8(s1, -2),
+ ENCODE8(s2, -1), ENCODE8(s3, 0)));
+ ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
+ } break;
+
+ case cDecode + cBits8 + 4: {
+ register byte s1 = ss->prev[1], s2 = ss->prev[2], s3 = ss->prev[3];
+
+ LOOP_BY(4, (DECODE8(s0, -3), DECODE8(s1, -2),
+ DECODE8(s2, -1), DECODE8(s3, 0)));
+ ss->prev[1] = s1, ss->prev[2] = s2, ss->prev[3] = s3;
+ } break;
+
+#undef ENCODE8
+#undef DECODE8
}
-#undef loopn
-#undef dloop1
+#undef LOOP_BY
+#undef ENCODE1_LOOP
+#undef DECODE1_LOOP
ss->row_left += count; /* leftover bytes are possible */
if (ss->row_left == 0) {
if (end_mask != 0)
- *q = (*q & ~end_mask) | (save_last & end_mask);
+ *q = (*q & ~end_mask) | (*p & end_mask);
if (p < pr->limit && q < pw->limit)
goto row;
}
- ss->s0 = s0;
+ ss->prev[0] = s0;
pr->ptr = p;
pw->ptr = q;
return status;
}
/* Stream templates */
-const stream_template s_PDiffE_template =
-{&st_PDiff_state, s_PDiffE_init, s_PDiff_process, 1, 1, NULL,
- s_PDiff_set_defaults, s_PDiff_reinit
+const stream_template s_PDiffE_template = {
+ &st_PDiff_state, s_PDiffE_init, s_PDiff_process, 1, 1, NULL,
+ s_PDiff_set_defaults, s_PDiff_reinit
};
-const stream_template s_PDiffD_template =
-{&st_PDiff_state, s_PDiffD_init, s_PDiff_process, 1, 1, NULL,
- s_PDiff_set_defaults, s_PDiff_reinit
+const stream_template s_PDiffD_template = {
+ &st_PDiff_state, s_PDiffD_init, s_PDiff_process, 1, 1, NULL,
+ s_PDiff_set_defaults, s_PDiff_reinit
};
diff --git a/gs/src/spdiffx.h b/gs/src/spdiffx.h
index 41cbcee4b..18e4aeeb4 100644
--- a/gs/src/spdiffx.h
+++ b/gs/src/spdiffx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,11 +22,17 @@
#ifndef spdiffx_INCLUDED
# define spdiffx_INCLUDED
+/*
+ * Define the maximum value for Colors. This must be at least 4, but can
+ * be arbitrarily large: the only cost is a larger stream state structure.
+ */
+#define s_PDiff_max_Colors 16
+
/* PixelDifferenceDecode / PixelDifferenceEncode */
typedef struct stream_PDiff_state_s {
stream_state_common;
/* The client sets the following before initialization. */
- int Colors; /* # of colors, 1..4 */
+ int Colors; /* # of colors, 1..s_PDiff_max_Colors */
int BitsPerComponent; /* 1, 2, 4, 8 */
int Columns;
/* The init procedure computes the following. */
@@ -35,7 +41,7 @@ typedef struct stream_PDiff_state_s {
int case_index; /* switch index for case dispatch */
/* The following are updated dynamically. */
uint row_left; /* # of bytes left in row */
- byte s0, s1, s2, s3; /* previous sample */
+ byte prev[s_PDiff_max_Colors]; /* previous sample */
} stream_PDiff_state;
#define private_st_PDiff_state() /* in spdiff.c */\
diff --git a/gs/src/spngp.c b/gs/src/spngp.c
index e12e00314..9ee32e776 100644
--- a/gs/src/spngp.c
+++ b/gs/src/spngp.c
@@ -35,8 +35,9 @@ private_st_PNGP_state();
#define cOptimum 15
#define cEncode -10
#define cDecode -4
-private const byte pngp_case_needs_prev[] =
-{0, 0, 1, 1, 1, 1};
+private const byte pngp_case_needs_prev[] = {
+ 0, 0, 1, 1, 1, 1
+};
/* Set defaults */
private void
@@ -59,7 +60,7 @@ s_PNGP_reinit(stream_state * st)
return 0;
}
-/* Initialize PNGPredictorEncode filter. */
+/* Common initialization. */
private int
s_pngp_init(stream_state * st, bool need_prev)
{
@@ -70,8 +71,7 @@ s_pngp_init(stream_state * st, bool need_prev)
#if arch_sizeof_long > arch_sizeof_int
if (bits_per_row > max_uint * 7L)
- return ERRC;
-/****** WRONG ******/
+ return ERRC; /****** WRONG ******/
#endif
ss->row_count = (uint) ((bits_per_row + 7) >> 3);
ss->end_mask = (1 << (-bits_per_row & 7)) - 1;
@@ -80,8 +80,7 @@ s_pngp_init(stream_state * st, bool need_prev)
prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count,
"PNGPredictor prev row");
if (prev_row == 0)
- return ERRC;
-/****** WRONG ******/
+ return ERRC; /****** WRONG ******/
memset(prev_row, 0, ss->bpp);
}
ss->prev_row = prev_row;
@@ -105,6 +104,16 @@ s_PNGPD_init(stream_state * st)
return s_pngp_init(st, true);
}
+/* Release a PNGPredictor filter. */
+private void
+s_PNGP_release(stream_state *st)
+{
+ stream_PNGP_state *const ss = (stream_PNGP_state *) st;
+
+ if (ss->prev_row)
+ gs_free_object(st->memory, ss->prev_row, "PNGPredictor prev row");
+}
+
/*
* Process a partial buffer. We pass in current and previous pointers
* to both the current and preceding scan line. Note that dprev is
@@ -115,13 +124,12 @@ s_PNGPD_init(stream_state * st)
private int
paeth_predictor(int a, int b, int c)
{
-#undef any_abs /* just in case */
-#define any_abs(u) ((u) < 0 ? -(u) : (u))
- int px = a + b - c;
- int pa = any_abs(px - a), pb = any_abs(px - b), pc = any_abs(px - c);
+ /* The definitions of ac and bc are correct, not a typo. */
+ int ac = b - c, bc = a - c, abcc = ac + bc;
+ int pa = (ac < 0 ? -ac : ac), pb = (bc < 0 ? -bc : bc),
+ pc = (abcc < 0 ? -abcc : abcc);
return (pa <= pb && pa <= pc ? a : pb <= pc ? b : c);
-#undef any_abs
}
private void
s_pngp_process(stream_state * st, stream_cursor_write * pw,
@@ -182,7 +190,7 @@ s_pngp_count(const stream_state * st_const, const stream_cursor_read * pr,
const stream_cursor_write * pw)
{
const stream_PNGP_state *const ss_const =
- (const stream_PNGP_state *)st_const;
+ (const stream_PNGP_state *)st_const;
uint rcount = pr->limit - pr->ptr;
uint wcount = pw->limit - pw->ptr;
uint row_left = ss_const->row_left;
@@ -216,16 +224,17 @@ s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
{
stream_PNGP_state *const ss = (stream_PNGP_state *) st;
int bpp = ss->bpp;
- int code = 0;
+ int status = 0;
while (pr->ptr < pr->limit) {
uint count;
- if (ss->row_left == 0) { /* Beginning of row, write algorithm byte. */
+ if (ss->row_left == 0) {
+ /* Beginning of row, write algorithm byte. */
int predictor;
if (pw->ptr >= pw->limit) {
- code = 1;
+ status = 1;
break;
}
predictor =
@@ -239,8 +248,9 @@ s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
continue;
}
count = s_pngp_count(st, pr, pw);
- if (count == 0) { /* We know we have input, so output must be full. */
- code = 1;
+ if (count == 0) {
+ /* We know we have input, so output must be full. */
+ status = 1;
break;
} {
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
@@ -250,8 +260,13 @@ s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
if (ss->prev_row)
memcpy(up - bpp, ss->prev, n);
- if (n < bpp) { /* We didn't have enough data to use up all of prev. */
- /* Shift more data into prev and exit. */
+ if (ss->row_left == 0)
+ continue;
+ if (n < bpp) {
+ /*
+ * We didn't have enough data to use up all of prev.
+ * Shift more data into prev and exit.
+ */
int prev_left = bpp - n;
memmove(ss->prev, ss->prev + n, prev_left);
@@ -272,7 +287,7 @@ s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
}
}
}
- return code;
+ return status;
}
/*
@@ -292,16 +307,17 @@ s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
{
stream_PNGP_state *const ss = (stream_PNGP_state *) st;
int bpp = ss->bpp;
- int code = 0;
+ int status = 0;
while (pr->ptr < pr->limit) {
uint count;
- if (ss->row_left == 0) { /* Beginning of row, read algorithm byte. */
+ if (ss->row_left == 0) {
+ /* Beginning of row, read algorithm byte. */
int predictor = pr->ptr[1];
if (predictor >= cOptimum - cNone) {
- code = ERRC;
+ status = ERRC;
break;
}
pr->ptr++;
@@ -311,8 +327,9 @@ s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
continue;
}
count = s_pngp_count(st, pr, pw);
- if (count == 0) { /* We know we have input, so output must be full. */
- code = 1;
+ if (count == 0) {
+ /* We know we have input, so output must be full. */
+ status = 1;
break;
} {
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
@@ -322,12 +339,17 @@ s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
if (ss->prev_row)
memcpy(up - bpp, ss->prev, n);
- if (n < bpp) { /* We didn't have enough data to use up all of prev. */
+ if (ss->row_left == 0)
+ continue;
+ if (n < bpp) {
+ /* We didn't have enough data to use up all of prev. */
/* Shift more data into prev and exit. */
int prev_left = bpp - n;
memmove(ss->prev, ss->prev + n, prev_left);
memcpy(ss->prev + prev_left, pw->ptr - (n - 1), n);
+ if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
+ status = 1;
break;
}
/* Process bytes whose predecessors are in the output. */
@@ -344,15 +366,15 @@ s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
}
}
}
- return code;
+ return status;
}
/* Stream templates */
-const stream_template s_PNGPE_template =
-{&st_PNGP_state, s_PNGPE_init, s_PNGPE_process, 1, 1, 0 /*NULL */ ,
- s_PNGP_set_defaults, s_PNGP_reinit
+const stream_template s_PNGPE_template = {
+ &st_PNGP_state, s_PNGPE_init, s_PNGPE_process, 1, 1, s_PNGP_release,
+ s_PNGP_set_defaults, s_PNGP_reinit
};
-const stream_template s_PNGPD_template =
-{&st_PNGP_state, s_PNGPD_init, s_PNGPD_process, 1, 1, 0 /*NULL */ ,
- s_PNGP_set_defaults, s_PNGP_reinit
+const stream_template s_PNGPD_template = {
+ &st_PNGP_state, s_PNGPD_init, s_PNGPD_process, 1, 1, s_PNGP_release,
+ s_PNGP_set_defaults, s_PNGP_reinit
};
diff --git a/gs/src/srdline.h b/gs/src/srdline.h
new file mode 100644
index 000000000..62d5d99a8
--- /dev/null
+++ b/gs/src/srdline.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Interface for readline */
+/* Requires gsmemory.h, gstypes.h */
+
+#ifndef srdline_INCLUDED
+# define srdline_INCLUDED
+
+/*
+ * Read a line from s_in, starting at index *pcount in buf. Start by
+ * printing prompt on s_out. If the string is longer than size - 1 (we need
+ * 1 extra byte at the end for a null or an EOL), use bufmem to reallocate
+ * buf; if bufmem is NULL, just return 1. In any case, store in *pcount the
+ * first unused index in buf. *pin_eol is normally false; it should be set
+ * to true (and true should be recognized) to indicate that the last
+ * character read was a ^M, which should cause a following ^J to be
+ * discarded. is_stdin(s) returns true iff s is stdin: this is needed for
+ * an obscure condition in the default implementation.
+ */
+#ifndef stream_DEFINED
+# define stream_DEFINED
+typedef struct stream_s stream;
+#endif
+#define sreadline_proc(proc)\
+ int proc(P9(stream *s_in, stream *s_out, void *readline_data,\
+ gs_const_string *prompt, gs_string *buf,\
+ gs_memory_t *bufmem, uint *pcount, bool *pin_eol,\
+ bool (*is_stdin)(P1(const stream *))))
+
+/* Declare the default implementation. */
+extern sreadline_proc(sreadline);
+
+#endif /* srdline_INCLUDED */
diff --git a/gs/src/sstring.c b/gs/src/sstring.c
index 49cd51d82..7f7e395ae 100644
--- a/gs/src/sstring.c
+++ b/gs/src/sstring.c
@@ -53,7 +53,7 @@ s_AXE_process(stream_state * st, stream_cursor_read * pr,
const char *hex_digits = "0123456789abcdef";
int status = 0;
- if (last)
+ if (last && ss->EndOfData)
wcount--; /* leave room for '>' */
wcount -= (wcount + 64) / 65; /* leave room for \n */
wcount >>= 1; /* 2 chars per input byte */
@@ -64,7 +64,7 @@ s_AXE_process(stream_state * st, stream_cursor_read * pr,
if (!(++pos & 31) && (count != 0 || !last))
*++q = '\n';
}
- if (last && status == 0)
+ if (last && status == 0 && ss->EndOfData)
*++q = '>';
pr->ptr = p;
pw->ptr = q;
diff --git a/gs/src/sstring.h b/gs/src/sstring.h
index f6fed9e28..8b89acd8b 100644
--- a/gs/src/sstring.h
+++ b/gs/src/sstring.h
@@ -25,6 +25,9 @@
/* ASCIIHexEncode */
typedef struct stream_AXE_state_s {
stream_state_common;
+ /* The following are set by the client. */
+ bool EndOfData; /* if true, write > at EOD (default) */
+ /* The following change dynamically. */
int count; /* # of digits since last EOL */
} stream_AXE_state;
@@ -32,7 +35,7 @@ typedef struct stream_AXE_state_s {
gs_private_st_simple(st_AXE_state, stream_AXE_state,\
"ASCIIHexEncode state")
#define s_AXE_init_inline(ss)\
- ((ss)->count = 0)
+ ((ss)->EndOfData = true, (ss)->count = 0)
extern const stream_template s_AXE_template;
/* ASCIIHexDecode */
diff --git a/gs/src/stat_.h b/gs/src/stat_.h
index 72bcd91c9..05eba3759 100644
--- a/gs/src/stat_.h
+++ b/gs/src/stat_.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -53,4 +53,22 @@
# define stat_is_dir(stbuf) S_ISDIR((stbuf).st_mode)
#endif
+/*
+ * Some systems have S_IFMT and S_IFCHR but not S_ISCHR.
+ */
+#ifndef S_ISCHR
+# ifndef S_IFMT
+# ifdef _S_IFMT
+# define S_IFMT _S_IFMT
+# define S_IFCHR _S_IFCHR
+# else
+# ifdef __S_IFMT
+# define S_IFMT __S_IFMT
+# define S_IFCHR __S_IFCHR
+# endif
+# endif
+# endif
+# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#endif
+
#endif /* stat__INCLUDED */
diff --git a/gs/src/std.h b/gs/src/std.h
index e7f7d9ed1..6c8e4ed94 100644
--- a/gs/src/std.h
+++ b/gs/src/std.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,29 +27,63 @@
/* Include the architecture definitions. */
#include "arch.h"
+/*
+ * Define lower-case versions of the architecture parameters for backward
+ * compatibility.
+ */
+#define arch_align_short_mod ARCH_ALIGN_SHORT_MOD
+#define arch_align_int_mod ARCH_ALIGN_INT_MOD
+#define arch_align_long_mod ARCH_ALIGN_LONG_MOD
+#define arch_align_ptr_mod ARCH_ALIGN_PTR_MOD
+#define arch_align_float_mod ARCH_ALIGN_FLOAT_MOD
+#define arch_align_double_mod ARCH_ALIGN_DOUBLE_MOD
+#define arch_log2_sizeof_short ARCH_LOG2_SIZEOF_SHORT
+#define arch_log2_sizeof_int ARCH_LOG2_SIZEOF_INT
+#define arch_log2_sizeof_long ARCH_LOG2_SIZEOF_LONG
+#define arch_sizeof_ptr ARCH_SIZEOF_PTR
+#define arch_sizeof_float ARCH_SIZEOF_FLOAT
+#define arch_sizeof_double ARCH_SIZEOF_DOUBLE
+#define arch_float_mantissa_bits ARCH_FLOAT_MANTISSA_BITS
+#define arch_double_mantissa_bits ARCH_DOUBLE_MANTISSA_BITS
+#define arch_max_uchar ARCH_MAX_UCHAR
+#define arch_max_ushort ARCH_MAX_USHORT
+#define arch_max_uint ARCH_MAX_UINT
+#define arch_max_ulong ARCH_MAX_ULONG
+#define arch_cache1_size ARCH_CACHE1_SIZE
+#define arch_cache2_size ARCH_CACHE2_SIZE
+#define arch_is_big_endian ARCH_IS_BIG_ENDIAN
+#define arch_ptrs_are_signed ARCH_PTRS_ARE_SIGNED
+#define arch_floats_are_ieee ARCH_FLOATS_ARE_IEEE
+#define arch_arith_rshift ARCH_ARITH_RSHIFT
+#define arch_can_shift_full_long ARCH_CAN_SHIFT_FULL_LONG
+
/* Define integer data type sizes in terms of log2s. */
-#define arch_sizeof_short (1 << arch_log2_sizeof_short)
-#define arch_sizeof_int (1 << arch_log2_sizeof_int)
-#define arch_sizeof_long (1 << arch_log2_sizeof_long)
-#define arch_ints_are_short (arch_sizeof_int == arch_sizeof_short)
+#define ARCH_SIZEOF_SHORT (1 << ARCH_LOG2_SIZEOF_SHORT)
+#define ARCH_SIZEOF_INT (1 << ARCH_LOG2_SIZEOF_INT)
+#define ARCH_SIZEOF_LONG (1 << ARCH_LOG2_SIZEOF_LONG)
+#define ARCH_INTS_ARE_SHORT (ARCH_SIZEOF_INT == ARCH_SIZEOF_SHORT)
+/* Backward compatibility */
+#define arch_sizeof_short ARCH_SIZEOF_SHORT
+#define arch_sizeof_int ARCH_SIZEOF_INT
+#define arch_sizeof_long ARCH_SIZEOF_LONG
+#define arch_ints_are_short ARCH_INTS_ARE_SHORT
/* Define whether we are on a large- or small-memory machine. */
/* Currently, we assume small memory and 16-bit ints are synonymous. */
-#define arch_small_memory (arch_sizeof_int <= 2)
+#define ARCH_SMALL_MEMORY (ARCH_SIZEOF_INT <= 2)
+/* Backward compatibility */
+#define arch_small_memory ARCH_SMALL_MEMORY
/* Define unsigned 16- and 32-bit types. These are needed in */
/* a surprising number of places that do bit manipulation. */
#if arch_sizeof_short == 2 /* no plausible alternative! */
typedef ushort bits16;
-
#endif
#if arch_sizeof_int == 4
typedef uint bits32;
-
#else
# if arch_sizeof_long == 4
typedef ulong bits32;
-
# endif
#endif
@@ -191,42 +225,47 @@ void dprintf_file_only(P2(FILE *, const char *));
#define dlprintf12(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12)\
(_dpl dprintf12(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12))
-void eprintf_program_name(P2(FILE *, const char *));
+void printf_program_ident(P3(FILE *f, const char *program_name,
+ long revision_number));
+void eprintf_program_ident(P3(FILE *f, const char *program_name,
+ long revision_number));
const char *gs_program_name(P0());
+long gs_revision_number(P0());
-#define _epn eprintf_program_name(estderr, gs_program_name()),
+#define _epi eprintf_program_ident(estderr, gs_program_name(),\
+ gs_revision_number()),
#define eprintf(str)\
- (_epn fprintf(estderr, str))
+ (_epi fprintf(estderr, str))
#define eprintf1(str,arg1)\
- (_epn fprintf(estderr, str, arg1))
+ (_epi fprintf(estderr, str, arg1))
#define eprintf2(str,arg1,arg2)\
- (_epn fprintf(estderr, str, arg1, arg2))
+ (_epi fprintf(estderr, str, arg1, arg2))
#define eprintf3(str,arg1,arg2,arg3)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3))
#define eprintf4(str,arg1,arg2,arg3,arg4)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4))
#define eprintf5(str,arg1,arg2,arg3,arg4,arg5)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5))
#define eprintf6(str,arg1,arg2,arg3,arg4,arg5,arg6)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6))
#define eprintf7(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7))
#define eprintf8(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8))
#define eprintf9(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9))
#define eprintf10(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)\
- (_epn fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10))
+ (_epi fprintf(estderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10))
#if __LINE__ /* compiler provides it */
void lprintf_file_and_line(P3(FILE *, const char *, int));
-# define _epl _epn lprintf_file_and_line(estderr, __FILE__, __LINE__),
+# define _epl _epi lprintf_file_and_line(estderr, __FILE__, __LINE__),
#else
void lprintf_file_only(P2(FILE *, const char *));
-# define _epl _epn lprintf_file_only(estderr, __FILE__)
+# define _epl _epi lprintf_file_only(estderr, __FILE__)
#endif
#define lprintf(str)\
diff --git a/gs/src/stdpre.h b/gs/src/stdpre.h
index b9eb6645d..79b27e9a0 100644
--- a/gs/src/stdpre.h
+++ b/gs/src/stdpre.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -91,8 +91,14 @@
# undef inline
# define inline __inline
#else
-# if !(defined(__GNUC__) || defined(__MWERKS__) || defined(inline))
-# define inline /* */
+# ifdef __GNUC__
+/* Define inline as __inline__ so -pedantic won't produce a warning. */
+# undef inline
+# define inline __inline__
+# else
+# if !(defined(__MWERKS__) || defined(inline))
+# define inline /* */
+# endif
# endif
#endif
@@ -118,33 +124,18 @@
#define size_of(x) ((int)(sizeof(x)))
/*
- * Disable MS-DOS specialized pointer types on non-MS-DOS systems.
- * Watcom C defines near, far, and huge as macros, so we must undef them.
- * far_data is used for static data that must get its own segment.
- * This is supported in Borland C++, but none of the others.
+ * far_data was formerly used for static data that had to be assigned its
+ * own segment on PCs with 64K segments. This was supported in Borland C++,
+ * but none of the other compilers. Since we no longer support
+ * small-segment systems, far_data is vacuous.
*/
#undef far_data
-#if defined(__TURBOC__) && !defined(__WIN32__)
-# ifdef __BORLANDC__
-# define far_data far
-# else
-# define far_data /* */
-# endif
-#else
-# undef near
-# define near /* */
-# undef far
-# define far /* */
-# define far_data /* */
-# undef huge
-# define huge /* */
-# define _cs /* */
-# define _ds /* */
-/* _es is never safe to use */
-# define _ss /* */
-#endif
+#define far_data /* */
-/* Get the size of a statically declared array. */
+/*
+ * Get the number of elements of a statically dimensioned array.
+ * Note that this also works on array members of structures.
+ */
#define countof(a) (sizeof(a) / sizeof((a)[0]))
#define count_of(a) (size_of(a) / size_of((a)[0]))
@@ -169,7 +160,7 @@
* There is no portable way to do this, but the following definition
* works on all reasonable systems.
*/
-#define alignment_mod(ptr, modu)\
+#define ALIGNMENT_MOD(ptr, modu)\
((uint)( ((const char *)(ptr) - (const char *)0) & ((modu) - 1) ))
/* Define short names for the unsigned types. */
@@ -208,10 +199,8 @@ typedef unsigned long ulong;
#ifndef __cplusplus
#ifdef __BEOS__
typedef unsigned char bool;
-
#else
typedef int bool;
-
#endif
#endif
/*
@@ -244,21 +233,10 @@ typedef int bool;
*/
#if defined(__TURBOC__) || defined(_MSC_VER)
typedef unsigned long ptr_ord_t;
-
#else
typedef const char *ptr_ord_t;
-
#endif
/* Define all the pointer comparison operations. */
-#define _ptr_cmp(p1, rel, p2) ((ptr_ord_t)(p1) rel (ptr_ord_t)(p2))
-#define ptr_le(p1, p2) _ptr_cmp(p1, <=, p2)
-#define ptr_lt(p1, p2) _ptr_cmp(p1, <, p2)
-#define ptr_ge(p1, p2) _ptr_cmp(p1, >=, p2)
-#define ptr_gt(p1, p2) _ptr_cmp(p1, >, p2)
-#define ptr_between(ptr, lo, hi)\
- (ptr_ge(ptr, lo) && ptr_lt(ptr, hi))
-
-/* Define UPPERCASE macros for the pointer comparison operations. */
#define _PTR_CMP(p1, rel, p2) ((ptr_ord_t)(p1) rel (ptr_ord_t)(p2))
#define PTR_LE(p1, p2) _PTR_CMP(p1, <=, p2)
#define PTR_LT(p1, p2) _PTR_CMP(p1, <, p2)
@@ -277,16 +255,6 @@ typedef const char *ptr_ord_t;
#endif
/* Define a standard way to round values to a (constant) modulus. */
-#define round_down(value, modulus)\
- ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
- (value) - (value) % (modulus) :\
- (value) & -(modulus) )
-#define round_up(value, modulus)\
- ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
- ((value) + ((modulus) - 1)) / (modulus) * (modulus) :\
- ((value) + ((modulus) - 1)) & -(modulus) )
-
-/* Define UPPERCASE macros for the rounding operations. */
#define ROUND_DOWN(value, modulus)\
( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
(value) - (value) % (modulus) :\
@@ -295,6 +263,9 @@ typedef const char *ptr_ord_t;
( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
((value) + ((modulus) - 1)) / (modulus) * (modulus) :\
((value) + ((modulus) - 1)) & -(modulus) )
+/* Backward compatibility */
+#define round_up(v, m) ROUND_UP(v, m)
+#define round_down(v, m) ROUND_DOWN(v, m)
/*
* In pre-ANSI C, float parameters get converted to double.
@@ -328,14 +299,12 @@ typedef double floatp;
#endif
/*
- * For accountability, debugging, and error messages,
- * we pass a client identification string to alloc and free,
- * and possibly other places as well. Define the type for these strings.
- * The definition used to have a _ds modifier, so we had to coerce
- * them when passing them to printf at all; this is no longer needed.
+ * For accountability, debugging, and error messages, we pass a client
+ * identification string to alloc and free, and possibly other places as
+ * well. Define the type for these strings.
*/
typedef const char *client_name_t;
-
+/****** WHAT TO DO ABOUT client_name_string ? ******/
#define client_name_string(cname) (cname)
/*
@@ -399,8 +368,16 @@ typedef const char *client_name_t;
# define P16(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16) /* */
#endif
-/* Define success and failure codes for 'exit'. */
-#ifdef VMS
+/*
+ * Define success and failure codes for 'exit'. The only system on which
+ * they are different is VMS with older DEC C versions. We aren't sure
+ * in what version DEC C started being compatible with the rest of the
+ * world, and we don't know what the story is with VAX C. If you have
+ * problems, uncomment the following line or add -DOLD_VMS_C to the C
+ * command line.
+ */
+/*#define OLD_VMS_C*/
+#if defined(VMS) && (defined(OLD_VMS_C) || !defined(__DECC))
# define exit_OK 1
# define exit_FAILED 18
#else
diff --git a/gs/src/store.h b/gs/src/store.h
index 422e9cb42..c2e6eb4bd 100644
--- a/gs/src/store.h
+++ b/gs/src/store.h
@@ -130,9 +130,14 @@ int alloc_save_level(P1(const gs_dual_memory_t *));
#ifdef DEBUG
# define and_fill_s(pref)\
, (gs_debug['$'] ? r_set_size(pref, 0xfeed) : 0)
+/*
+ * The following nonsense avoids compiler warnings about signed/unsigned
+ * integer constants.
+ */
+#define DEADBEEF ((0xdeadL << 16) | 0xbeef)
# define and_fill_sv(pref)\
, (gs_debug['$'] ? (r_set_size(pref, 0xfeed),\
- (pref)->value.intval = 0xdeadbeef) : 0)
+ (pref)->value.intval = DEADBEEF) : 0)
#else /* !DEBUG */
# define and_fill_s(pref) /* */
# define and_fill_sv(pref) /* */
diff --git a/gs/src/stream.c b/gs/src/stream.c
index 9adb326e5..049ee6984 100644
--- a/gs/src/stream.c
+++ b/gs/src/stream.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -101,6 +101,16 @@ private const stream_template s_no_template = {
/* ------ Generic procedures ------ */
/* Allocate a stream and initialize it minimally. */
+void
+s_init(stream *s, gs_memory_t * mem)
+{
+ s->memory = mem;
+ s->report_error = s_no_report_error;
+ s->error_string[0] = 0;
+ s->prev = s->next = 0; /* clean for GC */
+ s->close_strm = false; /* default */
+ s->close_at_eod = true; /* default */
+}
stream *
s_alloc(gs_memory_t * mem, client_name_t cname)
{
@@ -110,10 +120,7 @@ s_alloc(gs_memory_t * mem, client_name_t cname)
client_name_string(cname), (ulong) s);
if (s == 0)
return 0;
- s->memory = mem;
- s->report_error = s_no_report_error;
- s->prev = s->next = 0; /* clean for GC */
- s->close_strm = false; /* default */
+ s_init(s, mem);
return s;
}
@@ -316,8 +323,11 @@ savailable(stream * s, long *pl)
/* Return the current position of a stream. */
long
stell(stream * s)
-{ /* The stream might have been closed, but the position */
- /* is still meaningful in this case. */
+{
+ /*
+ * The stream might have been closed, but the position
+ * is still meaningful in this case.
+ */
const byte *ptr = (s_is_writing(s) ? s->swptr : s->srptr);
return (ptr == 0 ? 0 : ptr + 1 - s->cbuf) + s->position;
@@ -366,13 +376,13 @@ sclose(register stream * s)
}
/*
- * Implement sgetc when the buffer may be empty.
- * If the buffer really is empty, refill it and then read a byte.
- * Note that filters must read one byte ahead, so that they can close immediately
- * after the client reads the last data byte if the next thing is an EOD.
+ * Implement sgetc when the buffer may be empty. If the buffer really is
+ * empty, refill it and then read a byte. Note that filters must read one
+ * byte ahead, so that they can close immediately after the client reads the
+ * last data byte if the next thing is an EOD.
*/
int
-spgetcc(register stream * s, bool close_on_eof)
+spgetcc(register stream * s, bool close_at_eod)
{
int status, left;
int min_left = sbuf_min_left(s);
@@ -384,7 +394,7 @@ spgetcc(register stream * s, bool close_on_eof)
s_process_read_buf(s);
if (left <= min_left && (left == 0 || (status != EOFC && status != ERRC))) { /* Compact the stream so stell will return the right result. */
stream_compact(s, true);
- if (status == EOFC && close_on_eof) {
+ if (status == EOFC && close_at_eod && s->close_at_eod) {
status = sclose(s);
if (status == 0)
status = EOFC;
@@ -550,6 +560,98 @@ spskip(register stream * s, long nskip, long *pskipped)
return 0;
}
+/* Read a line from a stream. See srdline.h for the specification. */
+int
+sreadline(stream *s_in, stream *s_out, void *readline_data,
+ gs_const_string *prompt, gs_string * buf,
+ gs_memory_t * bufmem, uint * pcount, bool *pin_eol,
+ bool (*is_stdin)(P1(const stream *)))
+{
+ uint count = *pcount;
+
+ /* Most systems define \n as 0xa and \r as 0xd; however, */
+ /* OS-9 has \n == \r == 0xd and \l == 0xa. The following */
+ /* code works properly regardless of environment. */
+#if '\n' == '\r'
+# define LF 0xa
+#else
+# define LF '\n'
+#endif
+
+ if (count == 0 && s_out && prompt) {
+ uint ignore_n;
+ int ch = sputs(s_out, prompt->data, prompt->size, &ignore_n);
+
+ if (ch < 0)
+ return ch;
+ }
+
+top:
+ if (*pin_eol) {
+ /*
+ * We're in the middle of checking for a two-character
+ * end-of-line sequence. If we get an EOF here, stop, but
+ * don't signal EOF now; wait till the next read.
+ */
+ int ch = spgetcc(s_in, false);
+
+ if (ch == EOFC) {
+ *pin_eol = false;
+ return 0;
+ } else if (ch < 0)
+ return ch;
+ else if (ch != LF)
+ sputback(s_in);
+ *pin_eol = false;
+ return 0;
+ }
+ for (;;) {
+ int ch = sgetc(s_in);
+
+ if (ch < 0) { /* EOF or exception */
+ *pcount = count;
+ return ch;
+ }
+ switch (ch) {
+ case '\r':
+ {
+#if '\n' == '\r' /* OS-9 or similar */
+ if (!is_stdin(s_in))
+#endif
+ {
+ *pcount = count;
+ *pin_eol = true;
+ goto top;
+ }
+ }
+ /* falls through */
+ case LF:
+#undef LF
+ *pcount = count;
+ return 0;
+ }
+ if (count >= buf->size) { /* filled the string */
+ if (!bufmem) {
+ sputback(s_in);
+ *pcount = count;
+ return 1;
+ }
+ {
+ uint nsize = count + max(count, 20);
+ byte *ndata = gs_resize_string(bufmem, buf->data, buf->size,
+ nsize, "sreadline(buffer)");
+
+ if (ndata == 0)
+ return ERRC; /* no better choice */
+ buf->data = ndata;
+ buf->size = nsize;
+ }
+ }
+ buf->data[count++] = ch;
+ }
+ /*return 0; *//* not reached */
+}
+
/* ------ Utilities ------ */
/*
@@ -639,7 +741,8 @@ sreadbuf(stream * s, stream_cursor_write * pbuf)
}
/* If curr reached EOD and is a filter stream, close it. */
if (strm != 0 && status == EOFC &&
- curr->cursor.r.ptr >= curr->cursor.r.limit
+ curr->cursor.r.ptr >= curr->cursor.r.limit &&
+ curr->close_at_eod
) {
int cstat = sclose(curr);
@@ -805,25 +908,46 @@ private int
/* Initialize a stream for reading a string. */
void
-sread_string(register stream * s, const byte * ptr, uint len)
+sread_string(register stream *s, const byte *ptr, uint len)
{
- static const stream_procs p =
- {s_string_available, s_string_read_seek, s_std_read_reset,
- s_std_read_flush, s_std_null, s_string_read_process
+ static const stream_procs p = {
+ s_string_available, s_string_read_seek, s_std_read_reset,
+ s_std_read_flush, s_std_null, s_string_read_process
};
- s_std_init(s, (byte *) ptr, len, &p, s_mode_read + s_mode_seek);
- s->cbuf_string.data = (byte *) ptr;
+ s_std_init(s, (byte *)ptr, len, &p, s_mode_read + s_mode_seek);
+ s->cbuf_string.data = (byte *)ptr;
s->cbuf_string.size = len;
s->end_status = EOFC;
s->srlimit = s->swlimit;
}
+/* Initialize a reusable stream for reading a string. */
+private void
+s_string_reusable_reset(stream *s)
+{
+ s->srptr = s->cbuf - 1; /* just reset to the beginning */
+}
+private int
+s_string_reusable_flush(stream *s)
+{
+ s->srptr = s->srlimit; /* just set to the end */
+ return 0;
+}
+void
+sread_string_reusable(stream *s, const byte *ptr, uint len)
+{
+ sread_string(s, ptr, len);
+ s->procs.reset = s_string_reusable_reset;
+ s->procs.flush = s_string_reusable_flush;
+ s->close_at_eod = false;
+}
+
/* Return the number of available bytes when reading from a string. */
private int
-s_string_available(stream * s, long *pl)
+s_string_available(stream *s, long *pl)
{
*pl = sbufavailable(s);
- if (*pl == 0) /* EOF */
+ if (*pl == 0 && s->close_at_eod) /* EOF */
*pl = -1;
return 0;
}
@@ -890,9 +1014,9 @@ private int
void
swrite_position_only(stream *s)
{
- static byte buf[50]; /* size is arbitrary */
+ static byte discard_buf[50]; /* size is arbitrary */
- swrite_string(s, buf, sizeof(buf));
+ swrite_string(s, discard_buf, sizeof(discard_buf));
s->procs.process = s_write_position_process;
}
diff --git a/gs/src/stream.h b/gs/src/stream.h
index 4767fe3e5..c386e6142 100644
--- a/gs/src/stream.h
+++ b/gs/src/stream.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,6 +24,7 @@
# define stream_INCLUDED
#include "scommon.h"
+#include "srdline.h"
/* See scommon.h for documentation on the design of streams. */
@@ -110,8 +111,7 @@ struct stream_s {
short end_status; /* status at end of buffer (when */
/* reading) or now (when writing) */
byte foreign; /* true if buffer is outside heap */
- byte modes; /* access modes allowed for this */
- /* stream */
+ byte modes; /* access modes allowed for this stream */
#define s_mode_read 1
#define s_mode_write 2
#define s_mode_seek 4
@@ -147,6 +147,7 @@ struct stream_s {
ushort write_id; /* ditto to validate write access */
stream *prev, *next; /* keep track of all files */
bool close_strm; /* CloseSource/CloseTarget */
+ bool close_at_eod; /*(default is true, only false if "reusable")*/
/*
* In order to avoid allocating a separate stream_state for
* file streams, which are the most heavily used stream type,
@@ -199,12 +200,11 @@ int sswitch(P2(stream *, bool));
/*
* Following are only valid for read streams.
*/
-int spgetcc(P2(stream *, bool)); /* bool indicates close-on-EOD */
-
+int spgetcc(P2(stream *, bool)); /* bool indicates close at EOD */
#define spgetc(s) spgetcc(s, true) /* a procedure equivalent of sgetc */
/*
- * Note that sgetc must call spgetc one byte early, because filter must read ahead
- * to detect EOD.
+ * Note that sgetc must call spgetc one byte early, because filter must read
+ * ahead to detect EOD.
*
* In the definition of sgetc, the first alternative should read
* (int)(*++((s)->srptr))
@@ -295,9 +295,12 @@ int spseek(P2(stream *, long));
/* Allocate a stream or a stream state. */
stream *s_alloc(P2(gs_memory_t *, client_name_t));
stream_state *s_alloc_state(P3(gs_memory_t *, gs_memory_type_ptr_t, client_name_t));
+/* Initialize a separately allocated stream, as if allocated by s_alloc. */
+void s_init(P2(stream *, gs_memory_t *));
/* Create a stream on a string or a file. */
void sread_string(P3(stream *, const byte *, uint)),
+ sread_string_reusable(P3(stream *, const byte *, uint)),
swrite_string(P3(stream *, byte *, uint));
void sread_file(P4(stream *, FILE *, byte *, uint)),
swrite_file(P4(stream *, FILE *, byte *, uint)),
diff --git a/gs/src/string_.h b/gs/src/string_.h
index c40afaaa2..56ed611fa 100644
--- a/gs/src/string_.h
+++ b/gs/src/string_.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,7 +36,7 @@
# define memset(dest,chr,cnt) setmem(dest,cnt,chr)
# endif
# else
-# ifdef memory__need_memmove
+# ifdef MEMORY__NEED_MEMMOVE
# undef memmove /* This is disgusting, but so is GCC */
# endif
# include <string.h>
@@ -44,7 +44,7 @@
/* Patch strlen to return a uint rather than a size_t. */
# define strlen (uint)strlen
# endif
-# ifdef memory__need_memmove
+# ifdef MEMORY__NEED_MEMMOVE
# define memmove(dest,src,len) gs_memmove(dest,src,len)
# endif
# endif
diff --git a/gs/src/t b/gs/src/t
new file mode 100644
index 000000000..aa5d7f1b4
--- /dev/null
+++ b/gs/src/t
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Type 1 / Type 2 character rendering operator entry */
+
+#ifndef ichar1_INCLUDED
+# define ichar1_INCLUDED
+
+/* Render a Type 1 or Type 2 outline. */
+/* This is the entire implementation of the .type1/2execchar operators. */
+int charstring_execchar(P2(op_args_t *op_args_p, int font_type_mask));
+
+#endif /* ichar1_INCLUDED */
diff --git a/gs/src/ugcclib.mak b/gs/src/ugcclib.mak
index 4a04f7217..39d8102e5 100644
--- a/gs/src/ugcclib.mak
+++ b/gs/src/ugcclib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -18,9 +18,12 @@
# makefile for Unix / gcc library testing.
-GLSRCDIR=.
-GLGENDIR=./debugobj
-GLOBJDIR=./debugobj
+BINDIR=./libobj
+GLSRCDIR=./src
+GLGENDIR=./libobj
+GLOBJDIR=./libobj
+DD=$(GLGENDIR)/
+GLD=$(GLGENDIR)/
#include $(COMMONDIR)/gccdefs.mak
#include $(COMMONDIR)/unixdefs.mak
@@ -30,7 +33,7 @@ include $(GLSRCDIR)/version.mak
gsdir = /usr/local/share/ghostscript
gsdatadir = $(gsdir)/$(GS_DOT_VERSION)
GS_DOCDIR=$(gsdatadir)/doc
-GS_LIB_DEFAULT=$(gsdatadir):$(gsdir)/fonts
+GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts
SEARCH_HERE_FIRST=1
GS_INIT=gs_init.ps
@@ -45,7 +48,7 @@ SHARE_JPEG=0
JPEG_NAME=jpeg
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10003
SHARE_LIBPNG=1
LIBPNG_NAME=png
@@ -53,12 +56,10 @@ ZSRCDIR=zlib
SHARE_ZLIB=1
ZLIB_NAME=z
-CONFIG=
-
CC=gcc
CCLD=$(CC)
-GCFLAGS=-Wall -Wcast-qual -Wpointer-arith -Wstrict-prototypes -Wwrite-strings -fno-common
+GCFLAGS=-Wall -Wcast-qual -Wpointer-arith -Wstrict-prototypes -Wwrite-strings -fno-builtin -fno-common
XCFLAGS=
CFLAGS=-g -O $(GCFLAGS) $(XCFLAGS)
LDFLAGS=$(XLDFLAGS)
@@ -69,13 +70,18 @@ XLIBDIR=
XLIBS=Xt Xext X11
FPU_TYPE=1
+SYNC=posync
-FEATURE_DEVS=dps2lib.dev psl2cs.dev cielib.dev imasklib.dev patlib.dev htxlib.dev roplib.dev devcmap.dev
+FEATURE_DEVS=$(GLD)dps2lib.dev $(GLD)psl2cs.dev $(GLD)cielib.dev\
+ $(GLD)imasklib.dev $(GLD)patlib.dev $(GLD)htxlib.dev $(GLD)roplib.dev\
+ $(GLD)devcmap.dev
COMPILE_INITS=0
BAND_LIST_STORAGE=file
BAND_LIST_COMPRESSOR=zlib
FILE_IMPLEMENTATION=stdio
-DEVICE_DEVS=x11cmyk.dev x11mono.dev x11.dev x11alpha.dev djet500.dev pbmraw.dev pgmraw.dev ppmraw.dev bbox.dev
+DEVICE_DEVS=$(DD)x11cmyk.dev $(DD)x11mono.dev $(DD)x11.dev $(DD)x11alpha.dev\
+ $(DD)djet500.dev $(DD)pbmraw.dev $(DD)pgmraw.dev $(DD)ppmraw.dev\
+ $(DD)bitcmyk.dev $(GLD)bbox.dev
DEVICE_DEVS1=
DEVICE_DEVS2=
DEVICE_DEVS3=
@@ -91,8 +97,14 @@ DEVICE_DEVS12=
DEVICE_DEVS13=
DEVICE_DEVS14=
DEVICE_DEVS15=
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
MAKEFILE=$(GLSRCDIR)/ugcclib.mak
+TOP_MAKEFILES=$(MAKEFILE)
AK=
CCFLAGS=$(GENOPT) $(CFLAGS)
@@ -103,7 +115,6 @@ CC_LEAF=$(CC_)
CCA2K=$(CC)
include $(GLSRCDIR)/unixhead.mak
-
include $(GLSRCDIR)/gs.mak
include $(GLSRCDIR)/lib.mak
include $(GLSRCDIR)/jpeg.mak
@@ -112,52 +123,9 @@ include $(GLSRCDIR)/zlib.mak
include $(GLSRCDIR)/libpng.mak
include $(GLSRCDIR)/devs.mak
include $(GLSRCDIR)/contrib.mak
+include $(GLSRCDIR)/unix-aux.mak
-# Following is from unixtail.mak, we have a different link step.
-unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ)
-unix_.dev: $(unix__) nosync.dev
- $(SETMOD) unix_ $(unix__) -include nosync
-
-$(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
- $(pipe__h) $(string__h) $(time__h)\
- $(gx_h) $(gsexit_h) $(gp_h)
- $(GLCC) $(GLO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c
-
-sysv__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_sysv.$(OBJ)
-sysv_.dev: $(sysv__)
- $(SETMOD) sysv_ $(sysv__)
-
-$(GLOBJ)gp_sysv.$(OBJ): $(GLSRC)gp_sysv.c $(time__h) $(AK)
- $(GLCC) $(GLO_)gp_sysv.$(OBJ) $(C_) $(GLSRC)gp_sysv.c
-
-# Auxiliary programs
-
-$(ANSI2KNR_XE): $(GLSRC)ansi2knr.c
- $(CCA2K) $(O_)$(ANSI2KNR_XE) $(GLSRC)ansi2knr.c
-
-$(ECHOGS_XE): $(GLSRC)echogs.c $(AK)
- $(CCAUX) $(O_)$(ECHOGS_XE) $(GLSRC)echogs.c
-
-# On the RS/6000 (at least), compiling genarch.c with gcc with -O
-# produces a buggy executable.
-$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENARCH_XE) $(GLSRC)genarch.c
-
-$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENCONF_XE) $(GLSRC)genconf.c
-
-$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENDEV_XE) $(GLSRC)gendev.c
-
-INCLUDE=/usr/include
-$(gconfig__h): $(MAKEFILE) $(ECHOGS_XE)
- $(ECHOGS_XE) -w $(gconfig__h) -x 2f2a -s This file was generated automatically. -s -x 2a2f
- if ( test -f $(INCLUDE)/dirent.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_DIRENT_H; else true; fi
- if ( test -f $(INCLUDE)/ndir.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_NDIR_H; else true; fi
- if ( test -f $(INCLUDE)/sys/dir.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_DIR_H; else true; fi
- if ( test -f $(INCLUDE)/sys/ndir.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_NDIR_H; else true; fi
- if ( test -f $(INCLUDE)/sys/time.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_TIME_H; else true; fi
- if ( test -f $(INCLUDE)/sys/times.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_TIMES_H; else true; fi
+# The following replaces unixlink.mak
LIB_ONLY=$(GLOBJ)gslib.$(OBJ) $(GLOBJ)gsnogc.$(OBJ) $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
ldt_tr=$(GLOBJ)ldt.tr
diff --git a/gs/src/unixtail.mak b/gs/src/unix-aux.mak
index d9eea2b40..43e9f52a2 100644
--- a/gs/src/unixtail.mak
+++ b/gs/src/unix-aux.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1990, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -17,16 +17,11 @@
# Partial makefile common to all Unix configurations.
-# This is the last part of the makefile for Unix configurations.
+# This makefile contains the build rules for the auxiliary programs such as
+# echogs, and the 'platform' modules.
# Define the name of this makefile.
-UNIXTAIL_MAK=$(GLSRC)unixtail.mak
-
-# The following prevents GNU make from constructing argument lists that
-# include all environment variables, which can easily be longer than
-# brain-damaged system V allows.
-
-.NOEXPORT:
+UNIX_AUX_MAK=$(GLSRC)unix-aux.mak
# -------------------------------- Library -------------------------------- #
@@ -38,9 +33,9 @@ UNIXTAIL_MAK=$(GLSRC)unixtail.mak
# Define pipes as a separable feature.
pipe_=$(GLOBJ)gdevpipe.$(OBJ)
-pipe.dev: $(UNIXTAIL_MAK) $(ECHOGS_XE) $(pipe_)
- $(SETMOD) pipe $(pipe_)
- $(ADDMOD) pipe -iodev pipe
+$(GLD)pipe.dev: $(UNIX_AUX_MAK) $(ECHOGS_XE) $(pipe_)
+ $(SETMOD) $(GLD)pipe $(pipe_)
+ $(ADDMOD) $(GLD)pipe -iodev pipe
$(GLOBJ)gdevpipe.$(OBJ): $(GLSRC)gdevpipe.c $(AK) $(errno__h) $(pipe__h) $(stdio__h) $(string__h) \
$(gserror_h) $(gsmemory_h) $(gstypes_h) $(gxiodev_h) $(stream_h)
@@ -49,8 +44,8 @@ $(GLOBJ)gdevpipe.$(OBJ): $(GLSRC)gdevpipe.c $(AK) $(errno__h) $(pipe__h) $(stdio
# Unix platforms other than System V, and also System V Release 4
# (SVR4) platforms.
unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ)
-unix_.dev: $(unix__) nosync.dev
- $(SETMOD) unix_ $(unix__) -include nosync
+$(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev
+ $(SETMOD) $(GLGEN)unix_ $(unix__) -include $(GLD)nosync
$(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
$(pipe__h) $(string__h) $(time__h)\
@@ -60,40 +55,43 @@ $(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
# System V platforms other than SVR4, which lack some system calls,
# but have pipes.
sysv__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_sysv.$(OBJ)
-sysv_.dev: $(sysv__) nosync.dev
- $(SETMOD) sysv_ $(sysv__) -include nosync
+$(GLGEN)sysv_.dev: $(sysv__) $(GLD)nosync.dev
+ $(SETMOD) $(GLGEN)sysv_ $(sysv__) -include $(GLD)nosync
$(GLOBJ)gp_sysv.$(OBJ): $(GLSRC)gp_sysv.c $(stdio__h) $(time__h) $(AK)
$(GLCC) $(GLO_)gp_sysv.$(OBJ) $(C_) $(GLSRC)gp_sysv.c
# -------------------------- Auxiliary programs --------------------------- #
-$(GENINIT_XE): $(GLSRC)geninit.c $(AK) $(stdio__h) $(string__h)
- $(CCAUX) $(O_)$(GENINIT_XE) $(GLSRC)geninit.c
-
$(ANSI2KNR_XE): $(GLSRC)ansi2knr.c
$(CCA2K) $(O_)$(ANSI2KNR_XE) $(GLSRC)ansi2knr.c
-$(ECHOGS_XE): $(GLSRC)echogs.c $(AK)
- $(CCAUX) $(O_)$(ECHOGS_XE) $(GLSRC)echogs.c
+$(ECHOGS_XE): $(GLSRC)echogs.c $(AK) $(stdpre_h)
+ $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(ECHOGS_XE) $(GLSRC)echogs.c
# On the RS/6000 (at least), compiling genarch.c with gcc with -O
# produces a buggy executable.
-$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENARCH_XE) $(GLSRC)genarch.c
+$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(GENARCH_DEPS)
+ $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENARCH_XE) $(GLSRC)genarch.c
-$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENCONF_XE) $(GLSRC)genconf.c
+$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(GENCONF_DEPS)
+ $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENCONF_XE) $(GLSRC)genconf.c
-$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(stdpre_h)
- $(CCAUX) $(O_)$(GENDEV_XE) $(GLSRC)gendev.c
+$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(GENDEV_DEPS)
+ $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENDEV_XE) $(GLSRC)gendev.c
+
+$(GENHT_XE): $(GLSRC)genht.c $(AK) $(GENHT_DEPS)
+ $(CCAUX) $(GENHT_CFLAGS) $(O_)$(GENHT_XE) $(GLSRC)genht.c
+
+$(GENINIT_XE): $(GLSRC)geninit.c $(AK) $(GENINIT_DEPS)
+ $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENINIT_XE) $(GLSRC)geninit.c
# Query the environment to construct gconfig_.h.
-# The "else true; is required because Ultrix's implementation of sh -e
+# The "else true;" is required because Ultrix's implementation of sh -e
# terminates execution of a command if any error occurs, even if the command
# traps the error with ||.
INCLUDE=/usr/include
-$(gconfig__h): $(UNIXTAIL_MAK) $(ECHOGS_XE)
+$(gconfig__h): $(UNIX_AUX_MAK) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfig__h) -x 2f2a -s This file was generated automatically. -s -x 2a2f
if ( test -f $(INCLUDE)/dirent.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_DIRENT_H; else true; fi
if ( test -f $(INCLUDE)/ndir.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_NDIR_H; else true; fi
@@ -101,50 +99,3 @@ $(gconfig__h): $(UNIXTAIL_MAK) $(ECHOGS_XE)
if ( test -f $(INCLUDE)/sys/ndir.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_NDIR_H; else true; fi
if ( test -f $(INCLUDE)/sys/time.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_TIME_H; else true; fi
if ( test -f $(INCLUDE)/sys/times.h ); then $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_TIMES_H; else true; fi
-
-# ----------------------------- Main program ------------------------------ #
-
-### Library files and archive
-
-LIB_ARCHIVE_ALL=$(LIB_ALL) $(DEVS_ALL)\
- $(GLOBJ)gsnogc.$(OBJ) $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
-
-# Build an archive for the library only.
-# This is not used in a standard build.
-GSLIB_A=$(GS)lib.a
-$(GSLIB_A): $(LIB_ARCHIVE_ALL)
- rm -f $(GSLIB_A)
- $(AR) $(ARFLAGS) $(GSLIB_A) $(LIB_ARCHIVE_ALL)
- $(RANLIB) $(GSLIB_A)
-
-### Interpreter main program
-
-INT_ARCHIVE_ALL=$(PSOBJ)imainarg.$(OBJ) $(PSOBJ)imain.$(OBJ) $(INT_ALL) $(DEVS_ALL)\
- $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
-XE_ALL=$(PSOBJ)gs.$(OBJ) $(INT_ARCHIVE_ALL)
-
-# Build a library archive for the entire interpreter.
-# This is not used in a standard build.
-GS_A=$(GS).a
-$(GS_A): $(INT_ARCHIVE_ALL)
- rm -f $(GS_A)
- $(AR) $(ARFLAGS) $(GS_A) $(INT_ARCHIVE_ALL)
- $(RANLIB) $(GS_A)
-
-# Here is the final link step. The stuff with LD_RUN_PATH is for SVR4
-# systems with dynamic library loading; I believe it's harmless elsewhere.
-# The resetting of the environment variables to empty strings is for SCO Unix,
-# which has limited environment space.
-ldt_tr=$(PSOBJ)ldt.tr
-$(GS_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL)
- $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(LDFLAGS) $(XLIBDIRS) -o $(GS_XE)
- $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gs.$(OBJ) -s
- cat $(ld_tr) >>$(ldt_tr)
- $(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) -lm
- LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; \
- XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \
- FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \
- DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \
- DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \
- DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= \
- $(SH) <$(ldt_tr)
diff --git a/gs/src/unix-end.mak b/gs/src/unix-end.mak
index 8d7687472..56dd6d849 100644
--- a/gs/src/unix-end.mak
+++ b/gs/src/unix-end.mak
@@ -21,6 +21,7 @@
# Define the rule for building standard configurations.
STDDIRS:
+ @if test ! -d $(BINDIR); then mkdir $(BINDIR); fi
@if test ! -d $(GLGENDIR); then mkdir $(GLGENDIR); fi
@if test ! -d $(GLOBJDIR); then mkdir $(GLOBJDIR); fi
@if test ! -d $(PSGENDIR); then mkdir $(PSGENDIR); fi
@@ -28,21 +29,19 @@ STDDIRS:
# Define a rule for building profiling configurations.
PGDIRS: STDDIRS
+ @if test ! -d $(BINDIR)/$(PGRELDIR); then mkdir $(BINDIR)/$(PGRELDIR); fi
@if test ! -d $(GLGENDIR)/$(PGRELDIR); then mkdir $(GLGENDIR)/$(PGRELDIR); fi
@if test ! -d $(GLOBJDIR)/$(PGRELDIR); then mkdir $(GLOBJDIR)/$(PGRELDIR); fi
@if test ! -d $(PSGENDIR)/$(PGRELDIR); then mkdir $(PSGENDIR)/$(PGRELDIR); fi
@if test ! -d $(PSOBJDIR)/$(PGRELDIR); then mkdir $(PSOBJDIR)/$(PGRELDIR); fi
-PGDEFS=GENOPT='' CFLAGS='$(CFLAGS_PROFILE) $(GCFLAGS) $(XCFLAGS)'\
- LDFLAGS='$(XLDFLAGS) -pg' XLIBS='Xt SM ICE Xext X11' CC_LEAF='$(CC_)'\
+PGDEFS=GENOPT='-DPROFILE' CFLAGS='$(CFLAGS_PROFILE) $(GCFLAGS) $(XCFLAGS)'\
+ LDFLAGS='$(XLDFLAGS) -pg' XLIBS='Xt SM ICE Xext X11' CC_LEAF='$(CC_LEAF_PG)'\
+ BINDIR=$(BINDIR)/$(PGRELDIR)\
GLGENDIR=$(GLGENDIR)/$(PGRELDIR) GLOBJDIR=$(GLOBJDIR)/$(PGRELDIR)\
PSGENDIR=$(PSGENDIR)/$(PGRELDIR) PSOBJDIR=$(PSOBJDIR)/$(PGRELDIR)
-pg.dev:
- $(RMN_) *.dev
- echo Empty file. > pg.dev
-
-pg: PGDIRS pg.dev
+pg: PGDIRS
make $(PGDEFS) default
pgclean: PGDIRS
@@ -50,20 +49,18 @@ pgclean: PGDIRS
# Define a rule for building debugging configurations.
DEBUGDIRS: STDDIRS
+ @if test ! -d $(BINDIR)/$(DEBUGRELDIR); then mkdir $(BINDIR)/$(DEBUGRELDIR); fi
@if test ! -d $(GLGENDIR)/$(DEBUGRELDIR); then mkdir $(GLGENDIR)/$(DEBUGRELDIR); fi
@if test ! -d $(GLOBJDIR)/$(DEBUGRELDIR); then mkdir $(GLOBJDIR)/$(DEBUGRELDIR); fi
@if test ! -d $(PSGENDIR)/$(DEBUGRELDIR); then mkdir $(PSGENDIR)/$(DEBUGRELDIR); fi
@if test ! -d $(PSOBJDIR)/$(DEBUGRELDIR); then mkdir $(PSOBJDIR)/$(DEBUGRELDIR); fi
DEBUGDEFS=GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(GCFLAGS) $(XCFLAGS)'\
+ BINDIR=$(BINDIR)/$(DEBUGRELDIR)\
GLGENDIR=$(GLGENDIR)/$(DEBUGRELDIR) GLOBJDIR=$(GLOBJDIR)/$(DEBUGRELDIR)\
PSGENDIR=$(PSGENDIR)/$(DEBUGRELDIR) PSOBJDIR=$(PSOBJDIR)/$(DEBUGRELDIR)
-debug.dev:
- $(RMN_) *.dev
- echo Empty file. > debug.dev
-
-debug: DEBUGDIRS debug.dev
+debug: DEBUGDIRS
make $(DEBUGDEFS) default
debugclean: DEBUGDIRS
@@ -71,7 +68,7 @@ debugclean: DEBUGDIRS
# The rule for gconfigv.h is here because it is shared between Unix and
# DV/X environments.
-$(gconfigv_h): $(GLSRC)unix-end.mak $(MAKEFILE) $(ECHOGS_XE)
+$(gconfigv_h): $(GLSRC)unix-end.mak $(TOP_MAKEFILES) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define USE_ASM -x 2028 -q $(USE_ASM)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define USE_FPU -x 2028 -q $(FPU_TYPE)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define EXTEND_NAMES 0$(EXTEND_NAMES)
diff --git a/gs/src/unix-gcc.mak b/gs/src/unix-gcc.mak
index 2e1ec76bb..7a84b8545 100755
--- a/gs/src/unix-gcc.mak
+++ b/gs/src/unix-gcc.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -22,13 +22,16 @@
####### The following are the only parts of the file you should need to edit.
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
+BINDIR=./bin
+GLSRCDIR=./src
GLGENDIR=./obj
GLOBJDIR=./obj
-PSSRCDIR=.
+PSSRCDIR=./src
+PSLIBDIR=./lib
PSGENDIR=./obj
PSOBJDIR=./obj
@@ -37,9 +40,10 @@ PSOBJDIR=./obj
#include $(COMMONDIR)/gccdefs.mak
#include $(COMMONDIR)/unixdefs.mak
#include $(COMMONDIR)/generic.mak
-GLSRC=$(GLSRCDIR)/
-include $(GLSRC)version.mak
-PSSRC=$(PSSRCDIR)/
+include $(GLSRCDIR)/version.mak
+DD=$(GLGENDIR)/
+GLD=$(GLGENDIR)/
+PSD=$(PSGENDIR)/
# ------ Generic options ------ #
@@ -71,7 +75,7 @@ GS_DOCDIR=$(docdir)
# Define the default directory/ies for the runtime
# initialization and font files. Separate multiple directories with a :.
-GS_LIB_DEFAULT=$(gsdatadir):$(gsdir)/fonts
+GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -98,7 +102,6 @@ GS_INIT=gs_init.ps
# so they are visible to the debugger and profiler.
# No execution time or space penalty.
-#GENOPT=-DDEBUG
GENOPT=
# Define the name of the executable file.
@@ -135,7 +138,7 @@ JPEG_NAME=jpeg
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10003
# Choose whether to use a shared version of the PNG library, and if so,
# what its name is.
@@ -164,10 +167,6 @@ AR=ar
ARFLAGS=qc
RANLIB=ranlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# ------ Platform-specific options ------ #
# Define the name of the C compiler.
@@ -184,7 +183,7 @@ CCLD=$(CC)
# the 2.7.0-2.7.2 optimizer bug, either "-Dconst=" or
# "-Wcast-qual -Wwrite-strings" is automatically included.
-GCFLAGS=-Wall -Wcast-align -Wstrict-prototypes -Wwrite-strings -fno-common
+GCFLAGS=-Wall -Wstrict-prototypes -Wtraditional -fno-builtin -fno-common
# Define the added flags for standard, debugging, and profiling builds.
@@ -222,6 +221,7 @@ LDFLAGS=$(XLDFLAGS) -fno-common
# ISC Unix 2.2 wants -linet.
# SCO Unix needs -lsocket if you aren't including the X11 driver.
# SVR4 may need -lnsl.
+# Solaris may need -lnsl -lsocket -lposix4.
# (Libraries required by individual drivers are handled automatically.)
EXTRALIBS=
@@ -264,11 +264,22 @@ XLIBS=Xt Xext X11
FPU_TYPE=1
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
+# Note that there is one feature that requires a GNU library:
+# $(PSD)gnrdline.dev, which adds support for GNU readline, including
+# on-the-fly name completion and evaluation. For details, see gp_gnrdl.c.
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev pipe.dev
+#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)pipe.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)pipe.dev $(PSD)rasterop.dev
+#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)pipe.dev $(PSD)rasterop.dev $(PSD)double.dev $(PSD)trapping.dev $(PSD)compht.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -294,30 +305,36 @@ FILE_IMPLEMENTATION=stdio
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-DEVICE_DEVS=x11.dev x11alpha.dev x11cmyk.dev x11gray2.dev x11gray4.dev x11mono.dev
-#DEVICE_DEVS1=bmpmono.dev bmpamono.dev posync.dev
-DEVICE_DEVS1=
-DEVICE_DEVS2=
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=uniprint.dev
-DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev
-DEVICE_DEVS7=faxg3.dev faxg32d.dev faxg4.dev
-DEVICE_DEVS8=pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev pcxcmyk.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev pkm.dev pkmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev psgray.dev psrgb.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
-DEVICE_DEVS14=jpeg.dev jpeggray.dev
-DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+DEVICE_DEVS=$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
+DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev
+DEVICE_DEVS2=$(DD)bmpamono.dev $(DD)bmpasep1.dev $(DD)bmpasep8.dev $(DD)bmpa16.dev $(DD)bmpa256.dev $(DD)bmpa16m.dev $(DD)bmpa32b.dev
+#DEVICE_DEVS2=
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# ---------------------------- End of options --------------------------- #
# Define the name of the partial makefile that specifies options --
# used in dependencies.
-MAKEFILE=$(GLSRC)unix-gcc.mak
+MAKEFILE=$(GLSRCDIR)/unix-gcc.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/unixhead.mak
# Define the ANSI-to-K&R dependency. There isn't one, but we do have to
# detect whether we're running a version of gcc with the const optimization
@@ -329,27 +346,29 @@ AK=$(GLGENDIR)/cc.tr
CCFLAGS=$(GENOPT) $(CFLAGS)
CC_=$(CC) `cat $(AK)` $(CCFLAGS)
-CCAUX=$(CC)
-#We can't use -fomit-frame-pointer with -pg....
-#CC_LEAF=$(CC_)
+CCAUX=$(CC) `cat $(AK)`
CC_LEAF=$(CC_) -fomit-frame-pointer
+# gcc can't use -fomit-frame-pointer with -pg.
+CC_LEAF_PG=$(CC_)
# ---------------- End of platform-specific section ---------------- #
-include $(GLSRC)unixhead.mak
-include $(GLSRC)gs.mak
-include $(GLSRC)lib.mak
-include $(PSSRC)int.mak
-include $(GLSRC)jpeg.mak
+include $(GLSRCDIR)/unixhead.mak
+include $(GLSRCDIR)/gs.mak
+include $(GLSRCDIR)/lib.mak
+include $(PSSRCDIR)/int.mak
+include $(PSSRCDIR)/cfonts.mak
+include $(GLSRCDIR)/jpeg.mak
# zlib.mak must precede libpng.mak
-include $(GLSRC)zlib.mak
-include $(GLSRC)libpng.mak
-include $(GLSRC)devs.mak
-include $(GLSRC)contrib.mak
-include $(GLSRC)unixtail.mak
-include $(GLSRC)unix-end.mak
-include $(GLSRC)unixinst.mak
+include $(GLSRCDIR)/zlib.mak
+include $(GLSRCDIR)/libpng.mak
+include $(GLSRCDIR)/devs.mak
+include $(GLSRCDIR)/contrib.mak
+include $(GLSRCDIR)/unix-aux.mak
+include $(GLSRCDIR)/unixlink.mak
+include $(GLSRCDIR)/unix-end.mak
+include $(GLSRCDIR)/unixinst.mak
# This has to come last so it won't be taken as the default target.
$(AK):
- if ( gcc --version | grep "2.7.[01]" >/dev/null || test `gcc --version` = 2.7.2 ); then echo -Dconst= >$(AK); else echo -Wcast-qual -Wwrite-strings >$(AK); fi
+ if ( $(CC) --version | egrep "^2\.7\.([01]|2(\.[^1-9]|$$))" >/dev/null ); then echo -Dconst= >$(AK); else echo -Wcast-qual -Wwrite-strings >$(AK); fi
diff --git a/gs/src/unixansi.mak b/gs/src/unixansi.mak
index 2d58f9ddc..45c0f2b82 100755
--- a/gs/src/unixansi.mak
+++ b/gs/src/unixansi.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -22,13 +22,16 @@
####### The following are the only parts of the file you should need to edit.
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
+BINDIR=./bin
+GLSRCDIR=./src
GLGENDIR=./obj
GLOBJDIR=./obj
-PSSRCDIR=.
+PSSRCDIR=./src
+PSLIBDIR=./lib
PSGENDIR=./obj
PSOBJDIR=./obj
@@ -37,9 +40,10 @@ PSOBJDIR=./obj
#include $(COMMONDIR)/ansidefs.mak
#include $(COMMONDIR)/unixdefs.mak
#include $(COMMONDIR)/generic.mak
-GLSRC=$(GLSRCDIR)/
-include $(GLSRC)version.mak
-PSSRC=$(PSSRCDIR)/
+include $(GLSRCDIR)/version.mak
+DD=$(GLGENDIR)/
+GLD=$(GLGENDIR)/
+PSD=$(PSGENDIR)/
# ------ Generic options ------ #
@@ -71,7 +75,7 @@ GS_DOCDIR=$(docdir)
# Define the default directory/ies for the runtime initialization and
# font files. Separate multiple directories with a :.
-GS_LIB_DEFAULT=$(gsdatadir):$(gsdir)/fonts
+GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -134,7 +138,7 @@ JPEG_NAME=jpeg
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10003
# Choose whether to use a shared version of the PNG library, and if so,
# what its name is.
@@ -163,10 +167,6 @@ AR=ar
ARFLAGS=qc
RANLIB=ranlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# ------ Platform-specific options ------ #
# Define the name of the C compiler. If the standard compiler for your
@@ -214,6 +214,7 @@ LDFLAGS=$(XLDFLAGS)
# ISC Unix 2.2 wants -linet.
# SCO Unix needs -lsocket if you aren't including the X11 driver.
# SVR4 may need -lnsl.
+# Solaris may need -lnsl -lsocket -lposix4.
# (Libraries required by individual drivers are handled automatically.)
EXTRALIBS=
@@ -255,11 +256,17 @@ XLIBS=Xt Xext X11
FPU_TYPE=1
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev pipe.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)pipe.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -285,29 +292,35 @@ FILE_IMPLEMENTATION=stdio
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-DEVICE_DEVS=x11.dev x11alpha.dev x11cmyk.dev x11mono.dev
+DEVICE_DEVS=$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11mono.dev
DEVICE_DEVS1=
DEVICE_DEVS2=
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=uniprint.dev
-DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev
-DEVICE_DEVS7=faxg3.dev faxg32d.dev faxg4.dev
-DEVICE_DEVS8=jpeg.dev jpeggray.dev pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+DEVICE_DEVS8=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
DEVICE_DEVS14=
-DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# ---------------------------- End of options --------------------------- #
# Define the name of the partial makefile that specifies options --
# used in dependencies.
-MAKEFILE=unixansi.mak
+MAKEFILE=$(GLSRCDIR)/unixansi.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/unixhead.mak
# Define the ANSI-to-K&R dependency (none for ANSI compilers).
@@ -319,19 +332,22 @@ CCFLAGS=$(GENOPT) $(CFLAGS)
CC_=$(CC) $(CCFLAGS)
CCAUX=$(CC)
CC_LEAF=$(CC_)
+CC_LEAF_PG=$(CC_)
# ---------------- End of platform-specific section ---------------- #
-include $(GLSRC)unixhead.mak
-include $(GLSRC)gs.mak
-include $(GLSRC)lib.mak
-include $(PSSRC)int.mak
-include $(GLSRC)jpeg.mak
+include $(GLSRCDIR)/unixhead.mak
+include $(GLSRCDIR)/gs.mak
+include $(GLSRCDIR)/lib.mak
+include $(PSSRCDIR)/int.mak
+include $(PSSRCDIR)/cfonts.mak
+include $(GLSRCDIR)/jpeg.mak
# zlib.mak must precede libpng.mak
-include $(GLSRC)zlib.mak
-include $(GLSRC)libpng.mak
-include $(GLSRC)devs.mak
-include $(GLSRC)contrib.mak
-include $(GLSRC)unixtail.mak
-include $(GLSRC)unix-end.mak
-include $(GLSRC)unixinst.mak
+include $(GLSRCDIR)/zlib.mak
+include $(GLSRCDIR)/libpng.mak
+include $(GLSRCDIR)/devs.mak
+include $(GLSRCDIR)/contrib.mak
+include $(GLSRCDIR)/unix-aux.mak
+include $(GLSRCDIR)/unixlink.mak
+include $(GLSRCDIR)/unix-end.mak
+include $(GLSRCDIR)/unixinst.mak
diff --git a/gs/src/unixhead.mak b/gs/src/unixhead.mak
index 5780b1f44..969da00ea 100644
--- a/gs/src/unixhead.mak
+++ b/gs/src/unixhead.mak
@@ -30,22 +30,19 @@ PLATFORM=unix_
# Define the syntax for command, object, and executable files.
+# Work around the fact that some `make' programs drop trailing spaces
+# or interpret == as a special definition operator.
+NULL=
+
CMD=
C_=-c
-I_=-I
-II=-I
-_I=
-
-# Define the syntax for compile command line defines
-# such as defining XYZZY to 0-1: $(D_)XYZZY$(_D_)0-1$(_D)
D_=-D
_D_=$(NULL)=
_D=
-
-# There should be a <space> at the end of the definition of O_,
-# but we have to work around the fact that some `make' programs
-# drop trailing spaces in macro definitions.
-NULL=
+I_=-I
+II=-I
+_I=
+NO_OP=@:
O_=-o $(NULL)
OBJ=o
XE=
@@ -55,11 +52,9 @@ XEAUX=
CAT=cat
D=/
-EXPP=
-EXP=./
+EXP=
SHELL=/bin/sh
SH=$(SHELL)
-SHP=$(SH) $(EXP)
# Define generic commands.
@@ -69,7 +64,7 @@ RMN_=rm -f
# Define the arguments for genconf.
-CONFILES=-Z -p "%s&s&&" -pl "&-l%s&s&&" -pL "&-L%s&s&&"
+CONFILES=-p "%s&s&&" -pl "&-l%s&s&&" -pL "&-L%s&s&&"
CONFLDTR=-ol
# Define the compilation rules and flags.
@@ -85,11 +80,7 @@ BEGINFILES=
PCFBASM=
# Define the default build rule, so the object directories get created
-# automatically. std must precede std.dev so it will be the default target.
-
-std: STDDIRS std.dev default
- echo Done.
+# automatically.
-std.dev:
- $(RMN_) *.dev
- echo Empty file. > std.dev
+std: STDDIRS default
+ $(NO_OP)
diff --git a/gs/src/unixinst.mak b/gs/src/unixinst.mak
index cc238cd9b..f57cfb6ee 100644
--- a/gs/src/unixinst.mak
+++ b/gs/src/unixinst.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -36,55 +36,59 @@ install-exec: $(GS_XE)
-mkdir $(bindir)
$(INSTALL_PROGRAM) $(GS_XE) $(bindir)/$(GS)
-install-scripts: gsnd
+install-scripts: lib/gsnd
-mkdir $(datadir)
-mkdir $(gsdir)
-mkdir $(gsdatadir)
-mkdir $(scriptdir)
- sh -c 'for f in \
+ $(SH) -c 'for f in \
gsbj gsdj gsdj500 gslj gslp gsnd \
bdftops dvipdf font2c \
-pdf2dsc pdf2ps pf2afm printafm ps2ascii ps2epsi ps2pdf ps2ps wftopfa ;\
- do if ( test -f $$f ); then $(INSTALL_PROGRAM) $$f $(scriptdir)/$$f; fi;\
+pdf2dsc pdf2ps pf2afm pfbtopfa printafm \
+ps2ascii ps2epsi ps2pdf ps2ps wftopfa ;\
+ do if ( test -f lib/$$f ); then $(INSTALL_PROGRAM) lib/$$f $(scriptdir)/$$f; fi;\
done'
MAN1_PAGES=gs pdf2dsc pdf2ps ps2ascii ps2epsi ps2pdf ps2ps
-install-data: gs.1
+install-data: man/gs.1
-mkdir $(mandir)
-mkdir $(man1dir)
- sh -c 'for f in $(MAN1_PAGES) ;\
+ cd man; $(SH) -c 'for f in $(MAN1_PAGES) ;\
do if ( test -f $$f.1 ); then $(INSTALL_DATA) $$f.1 $(man1dir)/$$f.$(man1ext); fi;\
done'
-mkdir $(datadir)
-mkdir $(gsdir)
-mkdir $(gsdatadir)
- sh -c 'for f in \
+ -mkdir $(gsdatadir)/lib
+ cd lib; $(SH) -c 'for f in \
Fontmap \
cbjc600.ppd cbjc800.ppd *.upp \
gs_init.ps gs_btokn.ps gs_ccfnt.ps gs_cff.ps gs_cidfn.ps gs_cmap.ps \
gs_diskf.ps gs_dpnxt.ps gs_dps.ps gs_dps1.ps gs_dps2.ps gs_epsf.ps \
gs_fonts.ps gs_kanji.ps gs_lev2.ps gs_ll3.ps \
-gs_pfile.ps gs_res.ps gs_setpd.ps gs_statd.ps \
-gs_ttf.ps gs_typ32.ps gs_typ42.ps gs_type1.ps \
+gs_pfile.ps gs_rdlin.ps gs_res.ps gs_setpd.ps gs_statd.ps \
+gs_trap.ps gs_ttf.ps gs_typ32.ps gs_typ42.ps gs_type1.ps \
gs_dbt_e.ps gs_iso_e.ps gs_ksb_e.ps gs_std_e.ps gs_sym_e.ps \
+ht_ccbnm.ps \
acctest.ps align.ps bdftops.ps caption.ps cid2code.ps decrypt.ps docie.ps \
-font2c.ps font2pcl.ps gslp.ps impath.ps landscap.ps level1.ps lines.ps \
-markhint.ps markpath.ps \
+errpage.ps font2c.ps font2pcl.ps gslp.ps impath.ps \
+landscap.ps level1.ps lines.ps markhint.ps markpath.ps \
packfile.ps pcharstr.ps pf2afm.ps ppath.ps prfont.ps printafm.ps \
-ps2ai.ps ps2ascii.ps ps2epsi.ps ps2image.ps \
-quit.ps showchar.ps showpage.ps stcinfo.ps stcolor.ps \
+ps2ai.ps ps2ascii.ps ps2epsi.ps quit.ps rollconv.ps \
+showchar.ps showpage.ps stcinfo.ps stcolor.ps \
traceimg.ps traceop.ps type1enc.ps type1ops.ps uninfo.ps unprot.ps \
-viewcmyk.ps viewgif.ps viewjpeg.ps viewpcx.ps viewpbm.ps viewps2a.ps \
+viewcmyk.ps viewgif.ps viewjpeg.ps viewmiff.ps \
+viewpcx.ps viewpbm.ps viewps2a.ps \
winmaps.ps wftopfa.ps wrfont.ps zeroline.ps \
gs_l2img.ps \
pdf2dsc.ps \
pdf_base.ps pdf_draw.ps pdf_font.ps pdf_main.ps pdf_ops.ps pdf_sec.ps \
gs_mex_e.ps gs_mro_e.ps gs_pdf_e.ps gs_wan_e.ps \
gs_pdfwr.ps ;\
- do if ( test -f $$f ); then $(INSTALL_DATA) $$f $(gsdatadir)/$$f; fi;\
+ do if ( test -f $$f ); then $(INSTALL_DATA) $$f $(gsdatadir)/lib/$$f; fi;\
done'
-mkdir $(docdir)
- sh -c 'for f in \
+ cd doc; $(SH) -c 'for f in \
PUBLIC README \
ps2epsi.txt \
Bug-form.htm C-style.htm Commprod.htm Copying.htm Current.htm \
@@ -96,7 +100,7 @@ Readme.htm Source.htm Unix-lpr.htm Use.htm Xfonts.htm ;\
do if ( test -f $$f ); then $(INSTALL_DATA) $$f $(docdir)/$$f; fi;\
done'
-mkdir $(exdir)
- for f in \
+ cd examples; for f in \
alphabet.ps chess.ps cheq.ps colorcir.ps escher.ps golfer.ps \
grayalph.ps snowflak.ps tiger.ps vasarely.ps waterfal.ps \
ridt91.eps ;\
diff --git a/gs/src/unixlink.mak b/gs/src/unixlink.mak
new file mode 100644
index 000000000..3307b7f15
--- /dev/null
+++ b/gs/src/unixlink.mak
@@ -0,0 +1,77 @@
+# Copyright (C) 1990, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+#
+# This file is part of Aladdin Ghostscript.
+#
+# Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+# or distributor accepts any responsibility for the consequences of using it,
+# or for whether it serves any particular purpose or works at all, unless he
+# or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+# License (the "License") for full details.
+#
+# Every copy of Aladdin Ghostscript must include a copy of the License,
+# normally in a plain ASCII text file named PUBLIC. The License grants you
+# the right to copy, modify and redistribute Aladdin Ghostscript, but only
+# under certain conditions described in the License. Among other things, the
+# License requires that the copyright notice and this notice be preserved on
+# all copies.
+
+
+# Partial makefile common to all Unix configurations.
+# This part of the makefile contains the linking steps.
+
+# Define the name of this makefile.
+UNIXLINK_MAK=$(GLSRC)unixlink.mak
+
+# The following prevents GNU make from constructing argument lists that
+# include all environment variables, which can easily be longer than
+# brain-damaged system V allows.
+
+.NOEXPORT:
+
+# ----------------------------- Main program ------------------------------ #
+
+### Library files and archive
+
+LIB_ARCHIVE_ALL=$(LIB_ALL) $(DEVS_ALL)\
+ $(GLOBJ)gsnogc.$(OBJ) $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
+
+# Build an archive for the library only.
+# This is not used in a standard build.
+GSLIB_A=$(GS)lib.a
+$(GSLIB_A): $(LIB_ARCHIVE_ALL)
+ rm -f $(GSLIB_A)
+ $(AR) $(ARFLAGS) $(GSLIB_A) $(LIB_ARCHIVE_ALL)
+ $(RANLIB) $(GSLIB_A)
+
+### Interpreter main program
+
+INT_ARCHIVE_ALL=$(PSOBJ)imainarg.$(OBJ) $(PSOBJ)imain.$(OBJ) $(INT_ALL) $(DEVS_ALL)\
+ $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ)
+XE_ALL=$(PSOBJ)gs.$(OBJ) $(INT_ARCHIVE_ALL)
+
+# Build a library archive for the entire interpreter.
+# This is not used in a standard build.
+GS_A=$(GS).a
+$(GS_A): $(INT_ARCHIVE_ALL)
+ rm -f $(GS_A)
+ $(AR) $(ARFLAGS) $(GS_A) $(INT_ARCHIVE_ALL)
+ $(RANLIB) $(GS_A)
+
+# Here is the final link step. The stuff with LD_RUN_PATH is for SVR4
+# systems with dynamic library loading; I believe it's harmless elsewhere.
+# The resetting of the environment variables to empty strings is for SCO Unix,
+# which has limited environment space.
+ldt_tr=$(PSOBJ)ldt.tr
+$(GS_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL)
+ $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(LDFLAGS) $(XLIBDIRS) -o $(GS_XE)
+ $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gs.$(OBJ) -s
+ cat $(ld_tr) >>$(ldt_tr)
+ $(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) -lm
+ LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; \
+ XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \
+ FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \
+ DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \
+ DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \
+ DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \
+ DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= \
+ $(SH) <$(ldt_tr)
diff --git a/gs/src/unix-cc.mak b/gs/src/unixtrad.mak
index a3ad004b8..830d30788 100755..100644
--- a/gs/src/unix-cc.mak
+++ b/gs/src/unixtrad.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -16,19 +16,22 @@
# all copies.
-# makefile for Unix/cc/X11 configuration.
+# makefile for Unix/"Traditional" C/X11 configuration.
# ------------------------------- Options ------------------------------- #
####### The following are the only parts of the file you should need to edit.
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
+BINDIR=./bin
+GLSRCDIR=./src
GLGENDIR=./obj
GLOBJDIR=./obj
-PSSRCDIR=.
+PSSRCDIR=./src
+PSLIBDIR=./lib
PSGENDIR=./obj
PSOBJDIR=./obj
@@ -37,9 +40,10 @@ PSOBJDIR=./obj
#include $(COMMONDIR)/ccdefs.mak
#include $(COMMONDIR)/unixdefs.mak
#include $(COMMONDIR)/generic.mak
-GLSRC=$(GLSRCDIR)/
-include $(GLSRC)version.mak
-PSSRC=$(PSSRCDIR)/
+include $(GLSRCDIR)/version.mak
+DD=$(GLGENDIR)/
+GLD=$(GLGENDIR)/
+PSD=$(PSGENDIR)/
# ------ Generic options ------ #
@@ -68,10 +72,10 @@ docdir=$(gsdatadir)/doc
exdir=$(gsdatadir)/examples
GS_DOCDIR=$(docdir)
-# Define the default directory/ies for the runtime
-# initialization and font files. Separate multiple directories with a :.
+# Define the default directory/ies for the runtime initialization and
+# font files. Separate multiple directories with a :.
-GS_LIB_DEFAULT=$(gsdatadir):$(gsdir)/fonts
+GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -98,23 +102,12 @@ GS_INIT=gs_init.ps
# so they are visible to the debugger and profiler.
# No execution time or space penalty.
-#GENOPT=-DDEBUG
GENOPT=
# Define the name of the executable file.
GS=gs
-# Define the source, generated intermediate file, and object directories
-# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-
-GLSRCDIR=.
-GLGENDIR=./obj
-GLOBJDIR=./obj
-PSSRCDIR=.
-PSGENDIR=./obj
-PSOBJDIR=./obj
-
# Define the directories for debugging and profiling binaries, relative to
# the standard binaries.
@@ -145,7 +138,7 @@ JPEG_NAME=jpeg
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10003
# Choose whether to use a shared version of the PNG library, and if so,
# what its name is.
@@ -174,10 +167,6 @@ AR=ar
ARFLAGS=qc
RANLIB=ranlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# ------ Platform-specific options ------ #
# Define the name of the linker for the final link step.
@@ -220,6 +209,7 @@ LDFLAGS=$(XLDFLAGS)
# ISC Unix 2.2 wants -linet.
# SCO Unix needs -lsocket if you aren't including the X11 driver.
# SVR4 may need -lnsl.
+# Solaris may need -lnsl -lsocket -lposix4.
# (Libraries required by individual drivers are handled automatically.)
EXTRALIBS=
@@ -261,11 +251,17 @@ XLIBS=Xt Xext X11
FPU_TYPE=1
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=posync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev pipe.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)pipe.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -291,61 +287,70 @@ FILE_IMPLEMENTATION=stdio
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-DEVICE_DEVS=x11.dev x11alpha.dev x11cmyk.dev x11mono.dev
+DEVICE_DEVS=$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11mono.dev
DEVICE_DEVS1=
DEVICE_DEVS2=
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
# Sun's cc can't compile gdevcdj.c.
-#DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
+#DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
DEVICE_DEVS4=
-DEVICE_DEVS5=uniprint.dev
-DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
DEVICE_DEVS6=
-DEVICE_DEVS7=faxg3.dev faxg32d.dev faxg4.dev
-DEVICE_DEVS8=jpeg.dev jpeggray.dev pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
-DEVICE_DEVS9=pbm.dev pbmraw.dev pgm.dev pgmraw.dev pgnm.dev pgnmraw.dev pnm.dev pnmraw.dev ppm.dev ppmraw.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
+DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+DEVICE_DEVS8=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev
+DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
DEVICE_DEVS14=
-DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+DEVICE_DEVS16=
+DEVICE_DEVS17=
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# ---------------------------- End of options --------------------------- #
# Define the name of the partial makefile that specifies options --
# used in dependencies.
-MAKEFILE=unix-cc.mak
+MAKEFILE=$(GLSRCDIR)/unixtrad.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/unixhead.mak
# Define the ANSI-to-K&R dependency.
# This should be ansi2knr$(XEAUX), or $(ANSI2KNR_XE), but these macros
# haven't been defined yet, and some buggy 'make' programs expand macros in
# definitions at the time of definition rather than at the time of use.
-AK=ansi2knr
+AK=$(GLGENDIR)/ansi2knr
# Define the compilation rules and flags.
CCFLAGS=$(GENOPT) $(CFLAGS)
-CC_=$(SHP)ccgs "$(CC) $(CCFLAGS)"
+CC_=$(GLSRCDIR)/ccgs $(AK) "$(CC) $(CCFLAGS)"
# We compile ansi2knr, and only ansi2knr, unmodified.
CCA2K=$(CC)
-CCAUX=$(SHP)ccgs "$(CC)"
+CCAUX=$(GLSRCDIR)/ccgs $(AK) "$(CC)"
CC_LEAF=$(CC_)
+CC_LEAF_PG=$(CC_)
# ---------------- End of platform-specific section ---------------- #
-include $(GLSRC)unixhead.mak
-include $(GLSRC)gs.mak
-include $(GLSRC)lib.mak
-include $(PSSRC)int.mak
-include $(GLSRC)jpeg.mak
+include $(GLSRCDIR)/unixhead.mak
+include $(GLSRCDIR)/gs.mak
+include $(GLSRCDIR)/lib.mak
+include $(PSSRCDIR)/int.mak
+include $(PSSRCDIR)/cfonts.mak
+include $(GLSRCDIR)/jpeg.mak
# zlib.mak must precede libpng.mak
-include $(GLSRC)zlib.mak
-include $(GLSRC)libpng.mak
-include $(GLSRC)devs.mak
-include $(GLSRC)contrib.mak
-include $(GLSRC)unixtail.mak
-include $(GLSRC)unix-end.mak
-include $(GLSRC)unixinst.mak
+include $(GLSRCDIR)/zlib.mak
+include $(GLSRCDIR)/libpng.mak
+include $(GLSRCDIR)/devs.mak
+include $(GLSRCDIR)/contrib.mak
+include $(GLSRCDIR)/unix-aux.mak
+include $(GLSRCDIR)/unixlink.mak
+include $(GLSRCDIR)/unix-end.mak
+include $(GLSRCDIR)/unixinst.mak
diff --git a/gs/src/version.mak b/gs/src/version.mak
index 470fbacbe..bc7053dcf 100644
--- a/gs/src/version.mak
+++ b/gs/src/version.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -18,17 +18,13 @@
# Makefile fragment containing the current revision identification.
-# Define the name of this makefile.
-VERSION_MAK=$(GLSRC)version.mak
-
# Major and minor version numbers.
# MINOR0 is different from MINOR only if MINOR is a single digit.
GS_VERSION_MAJOR=5
-GS_VERSION_MINOR=55
-GS_VERSION_MINOR0=55
+GS_VERSION_MINOR=84
+GS_VERSION_MINOR0=84
# Revision date: year x 10000 + month x 100 + day.
-GS_REVISIONDATE=19981201
-
+GS_REVISIONDATE=19990519
# Derived values
GS_VERSION=$(GS_VERSION_MAJOR)$(GS_VERSION_MINOR0)
GS_DOT_VERSION=$(GS_VERSION_MAJOR).$(GS_VERSION_MINOR)
diff --git a/gs/src/watc.mak b/gs/src/watc.mak
index 45a33301f..33f4a28da 100644
--- a/gs/src/watc.mak
+++ b/gs/src/watc.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -34,7 +34,7 @@ GS_DOCDIR=c:/gs
# initialization and font files. Separate multiple directories with \;.
# Use / to indicate directories, not a single \.
-GS_LIB_DEFAULT=.;c:/gs\;c:/gs/fonts
+GS_LIB_DEFAULT=.\;c:/gs/lib\;c:/gs/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -74,15 +74,24 @@ NOPRIVATE=0
GS=gs386
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=..\gs
-GLGENDIR=..\gs\obj
-GLOBJDIR=..\gs\obj
-PSSRCDIR=..\gs
-PSGENDIR=..\gs\obj
-PSOBJDIR=..\gs\obj
+BINDIR=.\bin
+GLSRCDIR=.\src
+GLGENDIR=.\obj
+GLOBJDIR=.\obj
+PSSRCDIR=.\src
+PSLIBDIR=.\lib
+PSGENDIR=.\obj
+PSOBJDIR=.\obj
+
+# Do not edit the next group of lines.
+NUL=
+DD=$(GLGENDIR)\$(NUL)
+GLD=$(GLGENDIR)\$(NUL)
+PSD=$(PSGENDIR)\$(NUL)
# Define the directory where the IJG JPEG library sources are stored,
# and the major version of the library that is stored there.
@@ -98,17 +107,13 @@ JVERSION=6
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
ZSRCDIR=zlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# Define any other compilation flags. Including -DA4 makes A4 paper size
# the default for most, but not, printer drivers.
@@ -122,7 +127,7 @@ CFLAGS=
# so the version must be exactly one of those strings.
#
# 10.695 equates to version 10.6 on 95 or NT
-WCVERSION=10.695
+WCVERSION=10.0
# Define the locations of the libraries.
LIBPATHS=LIBPATH $(%WATCOM)\lib386 LIBPATH $(%WATCOM)\lib386\dos
@@ -134,7 +139,7 @@ LIBPATHS=LIBPATH $(%WATCOM)\lib386 LIBPATH $(%WATCOM)\lib386\dos
# Currently the only difference is that 486 and above assume
# the presence of a FPU, and the other processor types do not.
-CPU_TYPE=586
+CPU_TYPE=386
# Define the math coprocessor (FPU) type.
# Options are -1 (optimize for no FPU), 0 (optimize for FPU present,
@@ -147,6 +152,12 @@ CPU_TYPE=586
FPU_TYPE=0
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=winsync
+
# ---------------------------- End of options ---------------------------- #
# Define the platform name.
@@ -156,6 +167,7 @@ PLATFORM=watc_
# Define the name of the makefile -- used in dependencies.
MAKEFILE=$(GLSRCDIR)\watc.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\wccommon.mak
# Define additional platform compilation flags.
@@ -168,7 +180,7 @@ PLATOPT=
# Choose the language feature(s) to include. See gs.mak for details.
# Since we have a large address space, we include some optional features.
-FEATURE_DEVS=psl3.dev pdf.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -194,61 +206,65 @@ FILE_IMPLEMENTATION=stdio
# Choose the device(s) to include. See devs.mak for details,
# devs.mak and contrib.mak for the list of available devices.
-### DEVICE_DEVS=vga.dev ega.dev svga16.dev
-### DEVICE_DEVS1=atiw.dev tseng.dev tvga.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
-DEVICE_DEVS5=uniprint.dev
-DEVICE_DEVS6=epson.dev eps9high.dev ibmpro.dev bj10e.dev bj200.dev bjc600.dev bjc800.dev
-DEVICE_DEVS8=pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev pcxcmyk.dev
-DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
-DEVICE_DEVS11=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev tiff12nc.dev tiff24nc.dev
-DEVICE_DEVS12=psmono.dev psgray.dev bit.dev bitrgb.dev bitcmyk.dev
-DEVICE_DEVS14=jpeg.dev jpeggray.dev
-DEVICE_DEVS15=pdfwrite.dev
+DEVICE_DEVS=$(DD)vga.dev $(DD)ega.dev $(DD)svga16.dev
+DEVICE_DEVS1=$(DD)atiw.dev $(DD)tseng.dev $(DD)tvga.dev
+DEVICE_DEVS2=
+DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev
+DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev
+DEVICE_DEVS5=$(DD)uniprint.dev
+DEVICE_DEVS6=$(DD)epson.dev $(DD)eps9high.dev $(DD)ibmpro.dev $(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+DEVICE_DEVS7=
+DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+DEVICE_DEVS9=
+DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+DEVICE_DEVS11=$(DD)bmpmono.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)tiff12nc.dev $(DD)tiff24nc.dev
+DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+DEVICE_DEVS13=
+DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+DEVICE_DEVS15=$(DD)pdfwrite.dev
+# Overflow for DEVS3,4,5,6,9
+DEVICE_DEVS16=$(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
+DEVICE_DEVS17=$(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
!include $(GLSRCDIR)\wctail.mak
!include $(GLSRCDIR)\devs.mak
!include $(GLSRCDIR)\contrib.mak
!include $(PSSRCDIR)\int.mak
+!include $(PSSRCDIR)\cfonts.mak
# -------------------------------- Library -------------------------------- #
# make sure the target directories exist - use special Watcom .BEFORE
+# (This is not the best way to do this, but we will have to wait until
+# the makefiles get disentangled to do it better.)
.BEFORE
@if not exist $(GLGENDIR) mkdir $(GLGENDIR)
@if not exist $(GLOBJDIR) mkdir $(GLOBJDIR)
@if not exist $(PSGENDIR) mkdir $(PSGENDIR)
@if not exist $(PSOBJDIR) mkdir $(PSOBJDIR)
-$(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\
- $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h)
- $(GLCC) $(GLO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c
+GLCCWIN=$(GLCC)
-$(GLOBJ)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\
- $(dos__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gstypes_h)
- $(GLCC) $(GLO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c
+!include $(GLSRCDIR)\winplat.mak
# The Watcom C platform
+watc_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_dosfb.$(OBJ)
!ifeq WAT32 0
-watc_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_msdos.$(OBJ)
-watc_2=$(GLOBJ)gp_dosfb.$(OBJ) $(GLOBJ)gp_dosfs.$(OBJ) $(GLOBJ)gp_dosfe.$(OBJ)
-watc__=$(watc_1) $(watc_2)
-watc_.dev: $(watc__) nosync.dev
- $(SETMOD) watc_ $(watc_1)
- $(ADDMOD) watc_ -obj $(watc_2)
- $(ADDMOD) watc_ -include nosync
+watc_2=$(GLOBJ)gp_dosfs.$(OBJ) $(GLOBJ)gp_dosfe.$(OBJ) $(GLOBJ)gp_msdos.$(OBJ)
+watc_inc=
!else
-watc_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_win32.$(OBJ)
-watc_2=$(GLOBJ)gp_dosfb.$(OBJ) $(GLOBJ)gp_ntfs.$(OBJ) $(GLOBJ)gxsync.$(OBJ)
-watc__=$(watc_1) $(watc_2)
-watc_.dev: $(watc__)
- $(SETMOD) watc_ $(watc_1)
- $(ADDMOD) watc_ -obj $(watc_2)
+watc_2=
+watc_inc=$(GLD)winplat.dev
!endif
+watc__=$(watc_1) $(watc_2)
+$(GLGEN)watc_.dev: $(watc__) $(GLD)nosync.dev $(watc_inc)
+ $(SETMOD) $(GLGEN)watc_ $(watc_1)
+ $(ADDMOD) $(GLGEN)watc_ -obj $(watc_2)
+ $(ADDMOD) $(GLGEN)watc_ -include $(GLD)nosync $(watc_inc)
$(GLOBJ)gp_iwatc.$(OBJ): $(GLSRC)gp_iwatc.c $(stat__h) $(string__h)\
$(gx_h) $(gp_h)
@@ -264,8 +280,8 @@ LIBDOS=$(LIB_ALL) $(watc__) $(ld_tr)
GS_ALL=$(GLOBJ)gs.$(OBJ) $(INT_ALL) $(INTASM) $(LIBDOS)
-ll_tr=$(GLGENDIR)ll$(CONFIG).tr
-$(ll_tr): $(MAKEFILE)
+ll_tr=$(GLOBJ)ll.tr
+$(ll_tr): $(TOP_MAKEFILES)
echo OPTION STACK=64k >$(ll_tr)
!ifeq WAT32 0
echo SYSTEM DOS4G >>$(ll_tr)
diff --git a/gs/src/watclib.mak b/gs/src/watclib.mak
index 53db1df79..54f141473 100644
--- a/gs/src/watclib.mak
+++ b/gs/src/watclib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -19,114 +19,102 @@
# makefile for MS-DOS / Watcom C/C++ library testing.
libdefault: $(GLOBJ)gslib.exe
- %null
+ $(NO_OP)
GS_DOCDIR=c:/gs
-GS_LIB_DEFAULT=.;c:/gs\;c:/gs/fonts
+GS_LIB_DEFAULT=.;c:/gs/lib\;c:/gs/fonts
SEARCH_HERE_FIRST=1
GS_INIT=gs_init.ps
!ifndef DEBUG
DEBUG=1
!endif
-
!ifndef TDEBUG
TDEBUG=1
!endif
-
!ifndef NOPRIVATE
NOPRIVATE=1
!endif
GS=gslib
+!ifndef BINDIR
+BINDIR=.\debugobj
+!endif
!ifndef GLSRCDIR
-GLSRCDIR=.
+GLSRCDIR=.\src
!endif
-
!ifndef GLGENDIR
-GLGENDIR=.
+GLGENDIR=.\debugobj
!endif
-
!ifndef GLOBJDIR
-GLOBJDIR=.
+GLOBJDIR=.\debugobj
!endif
+# Do not edit the next group of lines.
+NUL=
+DD=$(GLGENDIR)\$(NUL)
+GLD=$(GLGENDIR)\$(NUL)
!ifndef JSRCDIR
JSRCDIR=jpeg
!endif
-
!ifndef JVERSION
JVERSION=6
!endif
-
!ifndef PSRCDIR
PSRCDIR=libpng
!endif
-
!ifndef PVERSION
-PVERSION=96
+PVERSION=10002
!endif
-
!ifndef ZSRCDIR
ZSRCDIR=zlib
!endif
-
-!ifndef CONFIG
-CONFIG=
-!endif
-
CFLAGS=
-# Allow predefinition of WCVERSION
-# when using this makefile from inside another one.
!ifndef WCVERSION
WCVERSION=10.0
!endif
-
-LIBPATHS=LIBPATH $(%WATCOM)\lib386 LIBPATH $(%WATCOM)\lib386\nt
+LIBPATHS=LIBPATH $(%WATCOM)\lib386 LIBPATH $(%WATCOM)\lib386\dos
+STUB=$(%WATCOM)\binb\wstub.exe
!ifndef CPU_TYPE
CPU_TYPE=386
!endif
-
!ifndef FPU_TYPE
FPU_TYPE=0
!endif
+!ifndef SYNC
+SYNC=winsync
+!endif
PLATFORM=watclib_
-MAKEFILE=watclib.mak
+MAKEFILE=$(GLSRCDIR)\watclib.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\wccommon.mak
PLATOPT=
!include $(GLSRCDIR)\wccommon.mak
-# Allow predefinition of selectable options
-# when using this makefile from inside another one.
!ifndef FEATURE_DEVS
-FEATURE_DEVS=patlib.dev path1lib.dev hsblib.dev
+FEATURE_DEVS=$(GLD)patlib.dev $(GLD)path1lib.dev $(GLD)hsblib.dev
!endif
-
!ifndef DEVICE_DEVS
-DEVICE_DEVS=vga.dev
+DEVICE_DEVS=$(DD)vga.dev
!endif
-
!ifndef COMPILE_INITS
COMPILE_INITS=0
!endif
-
!ifndef BAND_LIST_STORAGE
BAND_LIST_STORAGE=file
!endif
-
!ifndef BAND_LIST_COMPRESSOR
BAND_LIST_COMPRESSOR=zlib
!endif
-
!ifndef FILE_IMPLEMENTATION
FILE_IMPLEMENTATION=stdio
!endif
@@ -135,45 +123,32 @@ FILE_IMPLEMENTATION=stdio
!include $(GLSRCDIR)\devs.mak
!include $(GLSRCDIR)\contrib.mak
-$(GLOBJ)gp_iwatc.$(OBJ): $(GLSRC)gp_iwatc.c $(stat__h) $(string__h)\
- $(gx_h) $(gp_h)
- $(GLCC) $(GLO_)gp_iwatc.$(OBJ) $(C_) $(GLSRC)gp_iwatc.c
-
-$(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\
- $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h)
- $(GLCC) $(GLO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c
-
-$(GLOBJ)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\
- $(dos__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gstypes_h)
- $(GLCC) $(GLO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c
-
-# The Watcom C platform
+GLCCWIN=$(GLCC)
+!include $(GLSRCDIR)\winplat.mak
+watclib_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_dosfb.$(OBJ)
!ifeq WAT32 0
-watclib_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_msdos.$(OBJ)
-watclib_2=$(GLOBJ)gp_dosfb.$(OBJ) $(GLOBJ)gp_dosfs.$(OBJ) $(GLOBJ)gp_dosfe.$(OBJ)
-watclib__=$(watclib_1) $(watclib_2)
-watclib_.dev: $(watclib__) nosync.dev
- $(SETMOD) watclib_ $(watclib_1)
- $(ADDMOD) watclib_ -obj $(watclib_2)
- $(ADDMOD) watclib_ -include nosync
+watclib_2=$(GLOBJ)gp_dosfs.$(OBJ) $(GLOBJ)gp_dosfe.$(OBJ) $(GLOBJ)gp_msdos.$(OBJ)
+watclib_inc=
!else
-watclib_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_win32.$(OBJ)
-watclib_2=$(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_ntfs.$(OBJ) $(GLOBJ)gxsync.$(OBJ)
-watclib__=$(watclib_1) $(watclib_2)
-watclib_.dev: $(watclib__)
- $(SETMOD) watclib_ $(watclib_1)
- $(ADDMOD) watclib_ -obj $(watclib_2)
+watclib_2=
+watclib_inc=$(GLD)winplat.dev
!endif
+watclib__=$(watclib_1) $(watclib_2)
+$(GLGEN)watclib_.dev: $(watclib__) $(GLGEN)nosync.dev $(watclib_inc)
+ $(SETMOD) $(GLGEN)watclib_ $(watclib_1)
+ $(ADDMOD) $(GLGEN)watclib_ -obj $(watclib_2)
+ $(ADDMOD) $(GLGEN)watclib_ -include $(GLGEN)nosync $(watclib_inc)
+
+$(GLOBJ)gp_iwatc.$(OBJ): $(GLSRC)gp_iwatc.c $(stat__h) $(string__h)\
+ $(gx_h) $(gp_h)
+ $(GLCC) $(GLO_)gp_iwatc.$(OBJ) $(C_) $(GLSRC)gp_iwatc.c
BEGINFILES=*.err
LIB_ONLY=$(GLOBJ)gslib.obj $(GLOBJ)gsnogc.obj $(GLOBJ)gconfig.obj $(GLOBJ)gscdefs.obj
-ll_tr=ll$(CONFIG).tr
-
-$(ll_tr): $(MAKEFILE)
+ll_tr=ll.tr
+$(ll_tr): $(TOP_MAKEFILES)
echo OPTION STACK=64k >$(ll_tr)
!ifeq WAT32 0
echo SYSTEM DOS4G >>$(ll_tr)
diff --git a/gs/src/watcw32.mak b/gs/src/watcw32.mak
index e9764fc50..fbae2358e 100644
--- a/gs/src/watcw32.mak
+++ b/gs/src/watcw32.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991-1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -39,7 +39,7 @@ GS_DOCDIR=c:/gs
# initialization and font files. Separate multiple directories with \;.
# Use / to indicate directories, not a single \.
-GS_LIB_DEFAULT=.;c:/gs\;c:/gs/fonts
+GS_LIB_DEFAULT=.;c:/gs/lib\;c:/gs/fonts
# Define whether or not searching for initialization files should always
# look in the current directory first. This leads to well-known security
@@ -85,15 +85,18 @@ GSDLL=gsdll32
MAKEDLL=1
-# Define the source, generated intermediate file, and object directories
+# Define the directory for the final executable, and the
+# source, generated intermediate file, and object directories
# for the graphics library (GL) and the PostScript/PDF interpreter (PS).
-GLSRCDIR=.
-GLGENDIR=.
-GLOBJDIR=.
-PSSRCDIR=.
-PSGENDIR=.
-PSOBJDIR=.
+BINDIR=.\bin
+GLSRCDIR=.\src
+GLGENDIR=.\obj
+GLOBJDIR=.\obj
+PSSRCDIR=.\src
+PSLIBDIR=.\lib
+PSGENDIR=.\obj
+PSOBJDIR=.\obj
# Define the directory where the IJG JPEG library sources are stored,
# and the major version of the library that is stored there.
@@ -109,17 +112,13 @@ JVERSION=6
# See libpng.mak for more information.
PSRCDIR=libpng
-PVERSION=96
+PVERSION=10002
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
ZSRCDIR=zlib
-# Define the configuration ID. Read gs.mak carefully before changing this.
-
-CONFIG=
-
# Define any other compilation flags.
CFLAGS=
@@ -169,11 +168,17 @@ CPU_TYPE=486
FPU_TYPE=0
+# Define the .dev module that implements thread and synchronization
+# primitives for this platform. Don't change this unless you really know
+# what you're doing.
+
+SYNC=winsync
+
# ------ Devices and features ------ #
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=psl3.dev pdf.dev ttfont.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev
# Choose whether to compile the .ps initialization files into the executable.
# See gs.mak for details.
@@ -201,8 +206,8 @@ FILE_IMPLEMENTATION=stdio
DEVICE_DEVS=mswindll.dev mswinprn.dev mswinpr2.dev
DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
-DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
-DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
+DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev
+DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev
DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev lbp8.dev uniprint.dev
DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev m8510.dev necp6.dev bjc600.dev bjc800.dev
DEVICE_DEVS7=t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev
@@ -214,22 +219,26 @@ DEVICE_DEVS12=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
DEVICE_DEVS13=pngmono.dev pnggray.dev png16.dev png256.dev png16m.dev
DEVICE_DEVS14=jpeg.dev jpeggray.dev
DEVICE_DEVS15=pdfwrite.dev pswrite.dev epswrite.dev pxlmono.dev pxlcolor.dev
+# Overflow for DEVS3,4,5,6,9
+DEVICE_DEVS16=ljet3.dev ljet3d.dev ljet4.dev ljet4d.dev
+DEVICE_DEVS17=pj.dev pjxl.dev pjxl300.dev
+DEVICE_DEVS18=
+DEVICE_DEVS19=
+DEVICE_DEVS20=
# ---------------------------- End of options ---------------------------- #
# Define the name of the makefile -- used in dependencies.
-# The use of multiple file names here is garbage!
-MAKEFILE=$(GLSRCDIR)\watcw32.mak winlib.mak winint.mak
+MAKEFILE=$(GLSRCDIR)\watcw32.mak
+TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)\winlib.mak $(GLSRCDIR)\winint.mak
-# Define the current directory prefix and shell invocations.
+# Define the executable and shell invocations.
D=\\
-EXPP=
+EXP=
SH=
-# The following is needed to work around a problem in wmake
-SHP=command /c
# Define the arguments for genconf.
@@ -352,7 +361,7 @@ BEGINFILES2=gsdll32.rex gswin32.rex gswin32c.rex
# -------------------------- Auxiliary programs --------------------------- #
-$(GLGENDIR)\ccf32.tr: $(MAKEFILE) makefile
+$(GLGENDIR)\ccf32.tr: $(TOP_MAKEFILES)
echo $(GENOPT) -I$(INCDIR) -DCHECK_INTERRUPTS -D_Windows -D__WIN32__ -D_WATCOM_ > $(GLGENDIR)\ccf32.tr
# -------------------------------- Library -------------------------------- #
@@ -365,7 +374,7 @@ $(GLGENDIR)\ccf32.tr: $(MAKEFILE) makefile
LIBCTR=
#rjl
-#$(LIBCTR): $(MAKEFILE) $(ECHOGS_XE)
+#$(LIBCTR): $(TOP_MAKEFILES) $(ECHOGS_XE)
# echogs -w $(LIBCTR) $(LIBDIR)\shell32.lib
# echogs -a $(LIBCTR) $(LIBDIR)\comdlg32.lib
diff --git a/gs/src/wccommon.mak b/gs/src/wccommon.mak
index df7097d6b..049460ee6 100644
--- a/gs/src/wccommon.mak
+++ b/gs/src/wccommon.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -30,7 +30,7 @@
# PLATFORM, MAKEFILE, AK, CC*, DEBUG, NOPRIVATE, CP_, RM_, RMN_
# Configuration, internal, specific to DOS/Windows:
# TDEBUG, USE_ASM, ASM,
-# COMPDIR, INCDIR, LIBPATHS,
+# COMPDIR, LIBPATHS,
# CPU_TYPE, FPU_TYPE
# We want Unix-compatible behavior. This is part of it.
@@ -42,6 +42,7 @@
.EXTENSIONS: .be .z
# Define the ANSI-to-K&R dependency. Watcom C accepts ANSI syntax.
+
AK=
# Note that built-in libpng and zlib aren't available.
@@ -52,90 +53,100 @@ SHARE_ZLIB=0
# Define the extensions for command, object, and executable files.
+NULL=
+
CMD=.bat
+D_=-D
+# Watcom C requires quoting parameter values with a - in them!
+_D_=$(NULL)="
+_D="
I_=-i=
II=-i=
_I=
+NO_OP=%null
O_=-fo=
OBJ=obj
XE=.exe
XEAUX=.exe
-# Define the syntax for compile command line defines
-# such as defining XYZZY to 0-1: $(D_)XYZZY$(_D_)0-1$(_D)
-D_=-D
-_D_=$(NULL)="
-_D="
-
-# Define the current directory prefix and shell invocations.
+# Define the executable and shell invocations.
D=\\
-EXPP=dos4gw
+EXP=
SH=
-# The following is needed to work around a problem in wmake.
-SHP=command /c
# Define generic commands.
CP_=call $(GLSRCDIR)\cp.bat
-RM_=erase
+RM_=call $(GLSRCDIR)\rm.bat
RMN_=call $(GLSRCDIR)\rm.bat
# Define the arguments for genconf.
+# wmake interprets & as calling for background execution, and ^ fails on
+# Windows NT.
CONFILES=-e ~ -p FILE~s~ps
CONFLDTR=-ol
# Define the names of the Watcom C files.
# See the comments in watc.mak and watcwin.mak regarding WCVERSION.
-# Set some reasonable defaults
-COMP=$(%WATCOM)\bin\wcc386p
-LINK=$(%WATCOM)\bin\wlinkp
-STUB=$(%WATCOM)\binb\wstub.exe
-WRC=$(%WATCOM)\binb\rc.exe
-WAT32=0
-
!ifeq WCVERSION 11.0
# 11.0 is currently the same as 10.5.
COMP=$(%WATCOM)\binw\wcc386
LINK=$(%WATCOM)\binw\wlink
STUB=$(%WATCOM)\binw\wstub.exe
WRC=$(%WATCOM)\binw\wrc.exe
-!endif # version 11.0
+!endif
!ifeq WCVERSION 10.5
COMP=$(%WATCOM)\binw\wcc386
LINK=$(%WATCOM)\binw\wlink
STUB=$(%WATCOM)\binw\wstub.exe
WRC=$(%WATCOM)\binw\wrc.exe
-!endif # version 10.5
+!endif
!ifeq WCVERSION 10.0
COMP=$(%WATCOM)\binb\wcc386
LINK=$(%WATCOM)\bin\wlink
STUB=$(%WATCOM)\binb\wstub.exe
WRC=$(%WATCOM)\binb\wrc.exe
-!endif # version 10.0
+!endif
!ifeq WCVERSION 9.5
COMP=$(%WATCOM)\bin\wcc386
LINK=$(%WATCOM)\bin\wlinkp
STUB=$(%WATCOM)\binb\wstub.exe
WRC=$(%WATCOM)\binb\wrc.exe
-!endif # version 9.5
+!endif
-# 95/NT Watcom compiler versions
+# 95/NT Watcom compiler versions
+# 10.695 is 10.6 under Windows 95 or NT (32 bit hosted tools)
!ifeq WCVERSION 10.695
COMP=$(%WATCOM)\binnt\wcc386
LINK=$(%WATCOM)\binnt\wlink
STUB=$(%WATCOM)\binw\wstub.exe
WRC=$(%WATCOM)\binnt\wrc.exe
WAT32=1
-!endif # 10.6 under Windows 95 or NT (32 bit hosted tools)
+!endif
+
+# Defaults
+!ifndef COMP
+COMP=$(%WATCOM)\bin\wcc386p
+LINK=$(%WATCOM)\bin\wlinkp
+STUB=$(%WATCOM)\binb\wstub.exe
+WRC=$(%WATCOM)\binb\rc.exe
+!endif
+!ifndef WAT32
+WAT32=0
+!endif
-INCDIR=$(%WATCOM)\h -i=$(%WATCOM)\h\nt
+!ifeq WAT32 0
+INCDIRS=$(%WATCOM)\h
+!else
+INCDIRS=$(%WATCOM)\h;$(%WATCOM)\h\nt
+!endif
WBIND=$(%WATCOM)\binb\wbind.exe
# Define the generic compilation flags.
@@ -177,22 +188,27 @@ PCFBASM=
# Make sure we get the right default target for make.
dosdefault: default
- %null
+ $(NO_OP)
# Define the compilation flags.
+# Privacy
!ifneq NOPRIVATE 0
CP=-dNOPRIVATE
!else
CP=
!endif
+# Run-time debugging and stack checking
!ifneq DEBUG 0
CD=-dDEBUG
+CS=
!else
CD=
+CS=-oeilnt -s
!endif
+# Debugger symbols
!ifneq TDEBUG 0
CT=-d2
LCT=DEBUG ALL
@@ -201,18 +217,13 @@ CT=-d1
LCT=DEBUG LINES
!endif
-!ifneq DEBUG 0
-CS=
-!else
-CS=-s
-!endif
-
GENOPT=$(CP) $(CD) $(CT) $(CS)
-CCFLAGS=$(GENOPT) $(PLATOPT) $(FPFLAGS) $(CFLAGS) $(XCFLAGS)
-CC=$(COMP) -oi -i=$(INCDIR) $(CCFLAGS) -zq -zp8
-CCAUX=$(COMP) -oi -i=$(INCDIR) $(FPFLAGS) -zq -zp8
+CCOPT=-i=$(INCDIRS) -zq -zp8
+CCFLAGS=$(CCOPT) $(GENOPT) $(PLATOPT) $(FPFLAGS) $(CFLAGS) $(XCFLAGS)
+CC=$(COMP) -oi $(CCFLAGS)
+CCAUX=$(COMP) -oi $(CCOPT) $(FPFLAGS)
CC_=$(CC)
CC_D=$(CC)
-CC_INT=$(COMP) -oit -i=$(INCDIR) $(CCFLAGS)
+CC_INT=$(COMP) -oit $(CCFLAGS)
CC_LEAF=$(CC_) -s
diff --git a/gs/src/wctail.mak b/gs/src/wctail.mak
index 0d16c70f7..00343f2b6 100644
--- a/gs/src/wctail.mak
+++ b/gs/src/wctail.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -22,7 +22,8 @@
# Define the name of this makefile.
WCTAIL_MAK=$(GLSRCDIR)\wctail.mak
-# Include the generic makefiles, except for devs.mak, contrib.mak, and int.mak.
+# Include the generic makefiles, except for devs.mak, contrib.mak,
+# int.mak, and cfonts.mak.
#!include $(COMMONDIR)/watcdefs.mak
#!include $(COMMONDIR)/pcdefs.mak
#!include $(COMMONDIR)/generic.mak
@@ -36,54 +37,56 @@ WCTAIL_MAK=$(GLSRCDIR)\wctail.mak
# -------------------------- Auxiliary programs --------------------------- #
+temp_tr=$(GLOBJ)_temp_.tr
+
$(ECHOGS_XE): $(AUXGEN)echogs.$(OBJ)
- echo OPTION STUB=$(STUB) >_temp_.tr
- echo $(LIBPATHS) >>_temp_.tr
- $(LINK) @_temp_.tr FILE $(AUXGEN)echogs
+ echo OPTION STUB=$(STUB) >$(temp_tr)
+ echo $(LIBPATHS) >>$(temp_tr)
+ $(LINK) @$(temp_tr) FILE $(AUXGEN)echogs
$(AUXGEN)echogs.$(OBJ): $(GLSRC)echogs.c
$(CCAUX) $(GLSRC)echogs.c $(O_)$(AUXGEN)echogs.$(OBJ)
$(GENARCH_XE): $(AUXGEN)genarch.$(OBJ)
- echo $(LIBPATHS) >_temp_.tr
- $(LINK) @_temp_.tr FILE $(AUXGEN)genarch
+ echo $(LIBPATHS) >$(temp_tr)
+ $(LINK) @$(temp_tr) FILE $(AUXGEN)genarch
$(AUXGEN)genarch.$(OBJ): $(GLSRC)genarch.c $(stdpre_h)
$(CCAUX) $(GLSRC)genarch.c $(O_)$(AUXGEN)genarch.$(OBJ)
$(GENCONF_XE): $(AUXGEN)genconf.$(OBJ)
- echo OPTION STUB=$(STUB) >_temp_.tr
- echo OPTION STACK=8k >>_temp_.tr
- echo $(LIBPATHS) >>_temp_.tr
- $(LINK) @_temp_.tr FILE $(AUXGEN)genconf
+ echo OPTION STUB=$(STUB) >$(temp_tr)
+ echo OPTION STACK=8k >>$(temp_tr)
+ echo $(LIBPATHS) >>$(temp_tr)
+ $(LINK) @$(temp_tr) FILE $(AUXGEN)genconf
$(AUXGEN)genconf.$(OBJ): $(GLSRC)genconf.c $(stdpre_h)
$(CCAUX) $(GLSRC)genconf.c $(O_)$(AUXGEN)genconf.$(OBJ)
$(GENDEV_XE): $(AUXGEN)gendev.$(OBJ)
- echo OPTION STUB=$(STUB) >_temp_.tr
- echo OPTION STACK=8k >>_temp_.tr
- echo $(LIBPATHS) >>_temp_.tr
- $(LINK) @_temp_.tr FILE $(AUXGEN)gendev
+ echo OPTION STUB=$(STUB) >$(temp_tr)
+ echo OPTION STACK=8k >>$(temp_tr)
+ echo $(LIBPATHS) >>$(temp_tr)
+ $(LINK) @$(temp_tr) FILE $(AUXGEN)gendev
$(AUXGEN)gendev.$(OBJ): $(GLSRC)gendev.c $(stdpre_h)
$(CCAUX) $(GLSRC)gendev.c $(O_)$(AUXGEN)gendev.$(OBJ)
-$(GENINIT_XE): $(PSOBJ)geninit.$(OBJ)
- echo OPTION STUB=$(STUB) >_temp_.tr
- echo OPTION STACK=8k >>_temp_.tr
- echo $(LIBPATHS) >>_temp_.tr
- $(LINK) @_temp_.tr FILE $(PSOBJ)geninit
+$(GENINIT_XE): $(AUXGEN)geninit.$(OBJ)
+ echo OPTION STUB=$(STUB) >$(temp_tr)
+ echo OPTION STACK=8k >>$(temp_tr)
+ echo $(LIBPATHS) >>$(temp_tr)
+ $(LINK) @$(temp_tr) FILE $(AUXGEN)geninit
-$(PSOBJ)geninit.$(OBJ): $(PSSRC)geninit.c $(stdio__h) $(string__h)
- $(CCAUX) $(PSSRC)geninit.c $(PSO_)geninit.$(OBJ)
+$(AUXGEN)geninit.$(OBJ): $(GLSRC)geninit.c $(stdpre_h)
+ $(CCAUX) $(GLSRC)geninit.c $(O_)$(AUXGEN)geninit.$(OBJ)
# No special gconfig_.h is needed.
# Watcom `make' supports output redirection.
$(gconfig__h): $(WCTAIL_MAK)
echo /* This file deliberately left blank. */ >$(gconfig__h)
-$(gconfigv_h): $(WCTAIL_MAK) $(MAKEFILE) $(ECHOGS_XE)
+$(gconfigv_h): $(WCTAIL_MAK) $(TOP_MAKEFILES) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define USE_ASM -x 2028 -q $(USE_ASM)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define USE_FPU -x 2028 -q $(FPU_TYPE)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define EXTEND_NAMES 0$(EXTEND_NAMES)
diff --git a/gs/src/windows_.h b/gs/src/windows_.h
index 8b2af18d2..3bcc72101 100644
--- a/gs/src/windows_.h
+++ b/gs/src/windows_.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,7 +25,13 @@
#define STRICT
#include <windows.h>
-#ifndef __WATCOMC__
+#ifdef __WATCOMC__
+ /* Watcom's _beginthread takes an extra stack_bottom argument. */
+# define BEGIN_THREAD(proc, stksize, data)\
+ _beginthread(proc, NULL, stksize, data)
+#else
+# define BEGIN_THREAD(proc, stksize, data)\
+ _beginthread(proc, stksize, data)
/* Define null equivalents of the Watcom 32-to-16-bit glue. */
# define AllocAlias16(ptr) ((DWORD)(ptr))
# define FreeAlias16(dword) /* */
diff --git a/gs/src/winint.mak b/gs/src/winint.mak
index 1a27e4647..c665811d2 100644
--- a/gs/src/winint.mak
+++ b/gs/src/winint.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -25,6 +25,7 @@
# Include the generic makefile.
!include $(PSSRCDIR)\int.mak
+!include $(PSSRCDIR)\cfonts.mak
# Define the C++ compiler invocation for library modules.
GLCPP=$(CPP) $(CO) $(I_)$(GLI_)$(_I)
@@ -33,60 +34,72 @@ GLCPP=$(CPP) $(CO) $(I_)$(GLI_)$(_I)
# This requires PS*_ to be defined, so it has to come after int.mak.
PSCCWIN=$(CC_WX) $(CCWINFLAGS) $(I_)$(PSI_)$(_I) $(PSF_)
-# ----------------------------- Main program ------------------------------ #
+# Define the name of this makefile.
+WININT_MAK=$(PSSRC)winint.mak
-# We would like to put the icons into GLGENDIR, but that would require
-# fiddling with the .rc files in ways I don't understand.
+# ----------------------------- Main program ------------------------------ #
-ICONS=gsgraph.ico gstext.ico
+ICONS=$(GLGEN)gsgraph.ico $(GLGEN)gstext.ico
GS_ALL=$(INT_ALL) $(INTASM)\
$(LIB_ALL) $(LIBCTR) $(GLGEN)lib.tr $(ld_tr) $(GSDLL_OBJ).res $(GLSRC)$(GSDLL).def $(ICONS)
-dwdll_h=$(GLSRC)dwdll.h
+dwdll_h=$(GLSRC)dwdll.h $(gsdllwin_h)
dwimg_h=$(GLSRC)dwimg.h
dwmain_h=$(GLSRC)dwmain.h
dwtext_h=$(GLSRC)dwtext.h
# Make the icons from their text form.
-gsgraph.ico: $(GLSRC)gsgraph.icx $(ECHOGS_XE)
- $(ECHOGS_XE) -wb gsgraph.ico -n -X -r $(GLSRC)gsgraph.icx
+$(GLGEN)gsgraph.ico: $(GLSRC)gsgraph.icx $(ECHOGS_XE) $(WININT_MAK)
+ $(ECHOGS_XE) -wb $(GLGEN)gsgraph.ico -n -X -r $(GLSRC)gsgraph.icx
-gstext.ico: $(GLSRC)gstext.icx $(ECHOGS_XE)
- $(ECHOGS_XE) -wb gstext.ico -n -X -r $(GLSRC)gstext.icx
+$(GLGEN)gstext.ico: $(GLSRC)gstext.icx $(ECHOGS_XE) $(WININT_MAK)
+ $(ECHOGS_XE) -wb $(GLGEN)gstext.ico -n -X -r $(GLSRC)gstext.icx
# resources for short EXE loader (no dialogs)
-$(GS_OBJ).res: $(GLSRC)dwmain.rc $(dwmain_h) $(ICONS)
- $(RCOMP) -i$(INCDIR) -r -fo$(GS_OBJ).res $(GLSRC)dwmain.rc
+$(GS_OBJ).res: $(GLSRC)dwmain.rc $(dwmain_h) $(ICONS) $(WININT_MAK)
+ $(ECHOGS_XE) -w $(GLGEN)_exe.rc -x 23 define -s gstext_ico $(GLGENDIR)/gstext.ico
+ $(ECHOGS_XE) -a $(GLGEN)_exe.rc -x 23 define -s gsgraph_ico $(GLGENDIR)/gsgraph.ico
+ $(ECHOGS_XE) -a $(GLGEN)_exe.rc -R $(GLSRC)dwmain.rc
+ $(RCOMP) -I$(GLSRCDIR) -i$(INCDIR) -r -fo$(GS_OBJ).res $(GLGEN)_exe.rc
+ del $(GLGEN)_exe.rc
# resources for main program (includes dialogs)
-$(GSDLL_OBJ).res: $(GLSRC)gsdll32.rc $(gp_mswin_h) $(ICONS)
- $(RCOMP) -i$(INCDIR) -r -fo$(GSDLL_OBJ).res $(GLSRC)gsdll32.rc
+$(GSDLL_OBJ).res: $(GLSRC)gsdll32.rc $(gp_mswin_h) $(ICONS) $(WININT_MAK)
+ $(ECHOGS_XE) -w $(GLGEN)_dll.rc -x 23 define -s gstext_ico $(GLGENDIR)/gstext.ico
+ $(ECHOGS_XE) -a $(GLGEN)_dll.rc -x 23 define -s gsgraph_ico $(GLGENDIR)/gsgraph.ico
+ $(ECHOGS_XE) -a $(GLGEN)_dll.rc -R $(GLSRC)gsdll32.rc
+ $(RCOMP) -I$(GLSRCDIR) -i$(INCDIR) -r -fo$(GSDLL_OBJ).res $(GLGEN)_dll.rc
+ del $(GLGEN)_dll.rc
# Modules for small EXE loader.
DWOBJ=$(GLOBJ)dwdll.obj $(GLOBJ)dwimg.obj $(GLOBJ)dwmain.obj $(GLOBJ)dwtext.obj $(GLOBJ)gscdefs.obj $(GLOBJ)gp_wgetv.obj
-$(GLOBJ)dwdll.obj: $(GLSRC)dwdll.cpp $(AK) $(dwdll_h) $(gsdll_h)
+$(GLOBJ)dwdll.obj: $(GLSRC)dwdll.cpp $(AK)\
+ $(dwdll_h) $(gsdll_h) $(gsdllwin_h)
$(GLCPP) $(COMPILE_FOR_EXE) $(GLO_)dwdll.obj -c $(GLSRC)dwdll.cpp
-$(GLOBJ)dwimg.obj: dwimg.cpp $(AK) $(dwmain_h) $(dwdll_h) $(dwtext_h) $(dwimg_h)\
+$(GLOBJ)dwimg.obj: $(GLSRC)dwimg.cpp $(AK)\
+ $(dwmain_h) $(dwdll_h) $(dwtext_h) $(dwimg_h)\
$(gscdefs_h) $(gsdll_h)
$(GLCPP) $(COMPILE_FOR_EXE) $(GLO_)dwimg.obj -c $(GLSRC)dwimg.cpp
-$(GLOBJ)dwmain.obj: dwmain.cpp $(AK) $(dwdll_h) $(gscdefs_h) $(gsdll_h)
+$(GLOBJ)dwmain.obj: $(GLSRC)dwmain.cpp $(AK)\
+ $(dwdll_h) $(gscdefs_h) $(gsdll_h)
$(GLCPP) $(COMPILE_FOR_EXE) $(GLO_)dwmain.obj -c $(GLSRC)dwmain.cpp
-$(GLOBJ)dwtext.obj: dwtext.cpp $(AK) $(dwtext_h)
+$(GLOBJ)dwtext.obj: $(GLSRC)dwtext.cpp $(AK) $(dwtext_h)
$(GLCPP) $(COMPILE_FOR_EXE) $(GLO_)dwtext.obj -c $(GLSRC)dwtext.cpp
# Modules for big EXE
DWOBJNO = $(GLOBJ)dwnodll.obj $(GLOBJ)dwimg.obj $(GLOBJ)dwmain.obj $(GLOBJ)dwtext.obj
-$(GLOBJ)dwnodll.obj: $(GLSRC)dwnodll.cpp $(AK) $(dwdll_h) $(gsdll_h)
+$(GLOBJ)dwnodll.obj: $(GLSRC)dwnodll.cpp $(AK)\
+ $(dwdll_h) $(gsdll_h) $(gsdllwin_h)
$(GLCPP) $(COMPILE_FOR_EXE) $(GLO_)dwnodll.obj -c $(GLSRC)dwnodll.cpp
# Compile gsdll.c, the main program of the DLL.
diff --git a/gs/src/winlib.mak b/gs/src/winlib.mak
index 6014979f9..88954fb8e 100644
--- a/gs/src/winlib.mak
+++ b/gs/src/winlib.mak
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1998 Aladdin Enterprises. All rights reserved.
+# Copyright (C) 1991-1999 Aladdin Enterprises. All rights reserved.
#
# This file is part of Aladdin Ghostscript.
#
@@ -53,6 +53,7 @@ _D=
I_=-I
II=-I
_I=
+NO_OP=@rem
# O_ and XE_ are defined separately for each compiler.
OBJ=obj
XE=.exe
@@ -77,15 +78,14 @@ PCFBASM=
# nmake expands macros when encountered, not when used,
# so this must precede the !include statements.
-# *** see comments eleswhere why .ico files are not in obj directory
-BEGINFILES=$(GLOBJDIR)\gs*.res gs*.ico $(GLGENDIR)\ccf32.tr\
- $(GSDLL_DLL) $(GSCONSOLE_XE)\
+# ****** WRONG ****** NEED GLOBJ PREFIX ******
+BEGINFILES=gs*.res gs*.ico $(GLGENDIR)\ccf32.tr\
+ $(GSDLL).dll $(GSCONSOLE).exe\
$(BEGINFILES2)
# Include the generic makefiles.
#!include $(COMMONDIR)/pcdefs.mak
#!include $(COMMONDIR)/generic.mak
-!include $(GLSRCDIR)\version.mak
!include $(GLSRCDIR)\gs.mak
!include $(GLSRCDIR)\lib.mak
!include $(GLSRCDIR)\jpeg.mak
@@ -99,6 +99,7 @@ BEGINFILES=$(GLOBJDIR)\gs*.res gs*.ico $(GLGENDIR)\ccf32.tr\
# This requires GL*_ to be defined, so it has to come after lib.mak.
GLCCWIN=$(CC_WX) $(CCWINFLAGS) $(I_)$(GLI_)$(_I) $(GLF_)
+!include $(GLSRCDIR)\winplat.mak
!include $(GLSRCDIR)\pcwin.mak
# Define abbreviations for the executable and DLL files.
@@ -110,10 +111,10 @@ GSDLL_OBJ=$(GLOBJ)$(GSDLL)
# No special gconfig_.h is needed.
# Assume `make' supports output redirection.
-$(gconfig__h): $(MAKEFILE)
+$(gconfig__h): $(TOP_MAKEFILES)
echo /* This file deliberately left blank. */ >$(gconfig__h)
-$(gconfigv_h): $(MAKEFILE) $(ECHOGS_XE)
+$(gconfigv_h): $(TOP_MAKEFILES) $(ECHOGS_XE)
$(ECHOGS_XE) -w $(gconfigv_h) -x 23 define USE_ASM -x 2028 -q $(USE_ASM)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define USE_FPU -x 2028 -q $(FPU_TYPE)-0 -x 29
$(ECHOGS_XE) -a $(gconfigv_h) -x 23 define EXTEND_NAMES 0$(EXTEND_NAMES)
@@ -124,10 +125,10 @@ $(gconfigv_h): $(MAKEFILE) $(ECHOGS_XE)
# The Windows Win32 platform
mswin32__=$(GLOBJ)gp_msio.$(OBJ)
-mswin32_.dev: $(mswin32__) $(ECHOGS_XE) msw32nc_.dev
- $(SETMOD) mswin32_ $(mswin32__)
- $(ADDMOD) mswin32_ -include msw32nc_
- $(ADDMOD) mswin32_ -iodev wstdio
+$(GLGEN)mswin32_.dev: $(mswin32__) $(ECHOGS_XE) $(GLGEN)msw32nc_.dev
+ $(SETMOD) $(GLGEN)mswin32_ $(mswin32__)
+ $(ADDMOD) $(GLGEN)mswin32_ -include $(GLGEN)msw32nc_.dev
+ $(ADDMOD) $(GLGEN)mswin32_ -iodev wstdio
$(GLOBJ)gp_msio.$(OBJ): $(GLSRC)gp_msio.c $(AK) $(gp_mswin_h) \
$(gsdll_h) $(stdio__h) $(gxiodev_h) $(stream_h) $(gx_h) $(gp_h) $(windows__h)
@@ -137,28 +138,17 @@ $(GLOBJ)gp_msio.$(OBJ): $(GLSRC)gp_msio.c $(AK) $(gp_mswin_h) \
# console I/O module gp_msio.c, because this incorrectly refers to gsdll.c,
# which in turn incorrectly refers to PostScript interpreter code.
-msw32nc_1=$(GLOBJ)gp_mswin.$(OBJ) $(GLOBJ)gp_win32.$(OBJ) $(GLOBJ)gp_wgetv.$(OBJ)
-msw32nc_2=$(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_ntfs.$(OBJ)
-msw32nc__=$(msw32nc_1) $(msw32nc_2)
-msw32nc_.dev: $(msw32nc__) $(ECHOGS_XE)
- $(SETMOD) msw32nc_ $(msw32nc_1)
- $(ADDMOD) msw32nc_ -obj $(msw32nc_2)
+msw32nc__=$(GLOBJ)gp_mswin.$(OBJ) $(GLOBJ)gp_nofb.$(OBJ) $(GLOBJ)gp_wgetv.$(OBJ)
+msw32nc_inc=$(GLD)nosync.dev $(GLD)winplat.dev
+$(GLGEN)msw32nc_.dev: $(msw32nc__) $(ECHOGS_XE) $(msw32nc_inc)
+ $(SETMOD) $(GLGEN)msw32nc_ $(msw32nc__)
+ $(ADDMOD) $(GLGEN)msw32nc_ -include $(msw32nc_inc)
$(GLOBJ)gp_mswin.$(OBJ): $(GLSRC)gp_mswin.c $(AK) $(gp_mswin_h) \
$(ctype__h) $(dos__h) $(malloc__h) $(memory__h) $(string__h) $(windows__h) \
$(gx_h) $(gp_h) $(gpcheck_h) $(gserrors_h) $(gsexit_h)
$(GLCCWIN) $(GLO_)gp_mswin.$(OBJ) $(C_) $(GLSRC)gp_mswin.c
-$(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\
- $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h)
- $(GLCCWIN) $(GLO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c
-
-$(GLOBJ)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\
- $(dos__h) $(stdio__h) $(string__h) $(windows__h)\
- $(gp_h) $(gsmemory_h) $(gstypes_h)
- $(GLCCWIN) $(GLO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c
-
$(GLOBJ)gp_wgetv.$(OBJ): $(GLSRC)gp_wgetv.c $(AK) $(gscdefs_h)
$(GLCCWIN) $(GLO_)gp_wgetv.$(OBJ) $(C_) $(GLSRC)gp_wgetv.c
diff --git a/gs/src/winplat.mak b/gs/src/winplat.mak
new file mode 100644
index 000000000..bf98a883d
--- /dev/null
+++ b/gs/src/winplat.mak
@@ -0,0 +1,51 @@
+# Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+#
+# This file is part of Aladdin Ghostscript.
+#
+# Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+# or distributor accepts any responsibility for the consequences of using it,
+# or for whether it serves any particular purpose or works at all, unless he
+# or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+# License (the "License") for full details.
+#
+# Every copy of Aladdin Ghostscript must include a copy of the License,
+# normally in a plain ASCII text file named PUBLIC. The License grants you
+# the right to copy, modify and redistribute Aladdin Ghostscript, but only
+# under certain conditions described in the License. Among other things, the
+# License requires that the copyright notice and this notice be preserved on
+# all copies.
+
+
+# Common makefile section for builds on 32-bit MS Windows, including the
+# Watcom MS-DOS build.
+
+# Define the name of this makefile.
+WINPLAT_MAK=$(GLSRC)winplat.mak
+
+# Define generic Windows-specific modules.
+
+winplat_=$(GLOBJ)gp_ntfs.$(OBJ) $(GLOBJ)gp_win32.$(OBJ)
+$(GLD)winplat.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winplat_)
+ $(SETMOD) $(GLD)winplat $(winplat_)
+
+$(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\
+ $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\
+ $(gp_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h)
+ $(GLCCWIN) $(GLO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c
+
+$(GLOBJ)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\
+ $(dos__h) $(malloc__h) $(stdio__h) $(string__h) $(windows__h)\
+ $(gp_h) $(gsmemory_h) $(gstypes_h)
+ $(GLCCWIN) $(GLO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c
+
+# Define the Windows thread / synchronization module.
+
+winsync_=$(GLOBJ)gp_wsync.$(OBJ)
+$(GLD)winsync.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winsync_)
+ $(SETMOD) $(GLD)winsync $(winsync_)
+ $(ADDMOD) $(GLD)winsync -replace $(GLD)nosync
+
+$(GLOBJ)gp_wsync.$(OBJ): $(GLSRC)gp_wsync.c $(AK)\
+ $(dos__h) $(malloc__h) $(stdio__h) $(string__h) $(windows__h)\
+ $(gp_h) $(gsmemory_h) $(gstypes_h)
+ $(GLCCWIN) $(GLO_)gp_wsync.$(OBJ) $(C_) $(GLSRC)gp_wsync.c
diff --git a/gs/src/x_.h b/gs/src/x_.h
index efcd74349..75def5a6d 100644
--- a/gs/src/x_.h
+++ b/gs/src/x_.h
@@ -25,11 +25,6 @@
/* Some versions of the X library use `private' as a member name, so: */
#undef private
-/* Under DEC C, make sure abs() and exit() are defined. */
-#ifdef __DECC
-# include <stdlib.h>
-#endif
-
/* Most X implementations have _Xdebug, but VMS DECWindows doesn't. */
#ifndef VMS
# define have_Xdebug
diff --git a/gs/src/zarith.c b/gs/src/zarith.c
index 661b35a99..ae5e91466 100644
--- a/gs/src/zarith.c
+++ b/gs/src/zarith.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -72,8 +72,9 @@ zop_add(register os_ptr op)
return 0;
}
int
-zadd(os_ptr op)
+zadd(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = zop_add(op);
if (code == 0) {
@@ -84,9 +85,10 @@ zadd(os_ptr op)
/* <num1> <num2> div <real_quotient> */
private int
-zdiv(register os_ptr op)
+zdiv(i_ctx_t *i_ctx_p)
{
- register os_ptr op1 = op - 1;
+ os_ptr op = osp;
+ os_ptr op1 = op - 1;
/* We can't use the non_int_cases macro, */
/* because we have to check explicitly for op == 0. */
@@ -125,8 +127,10 @@ zdiv(register os_ptr op)
/* <num1> <num2> mul <product> */
private int
-zmul(register os_ptr op)
+zmul(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -216,8 +220,9 @@ zop_sub(register os_ptr op)
return 0;
}
int
-zsub(os_ptr op)
+zsub(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = zop_sub(op);
if (code == 0) {
@@ -228,8 +233,10 @@ zsub(os_ptr op)
/* <num1> <num2> idiv <int_quotient> */
private int
-zidiv(register os_ptr op)
+zidiv(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_type(op[-1], t_integer);
if (op->value.intval == 0)
@@ -245,8 +252,10 @@ zidiv(register os_ptr op)
/* <int1> <int2> mod <remainder> */
private int
-zmod(register os_ptr op)
+zmod(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_type(op[-1], t_integer);
if (op->value.intval == 0)
@@ -258,8 +267,10 @@ zmod(register os_ptr op)
/* <num1> neg <num2> */
private int
-zneg(register os_ptr op)
+zneg(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -277,8 +288,10 @@ zneg(register os_ptr op)
/* <num1> ceiling <num2> */
private int
-zceiling(register os_ptr op)
+zceiling(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -291,8 +304,10 @@ zceiling(register os_ptr op)
/* <num1> floor <num2> */
private int
-zfloor(register os_ptr op)
+zfloor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -305,8 +320,10 @@ zfloor(register os_ptr op)
/* <num1> round <num2> */
private int
-zround(register os_ptr op)
+zround(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -319,8 +336,10 @@ zround(register os_ptr op)
/* <num1> truncate <num2> */
private int
-ztruncate(register os_ptr op)
+ztruncate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -338,8 +357,10 @@ ztruncate(register os_ptr op)
/* <int1> <int2> .bitadd <sum> */
private int
-zbitadd(register os_ptr op)
+zbitadd(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_type(op[-1], t_integer);
op[-1].value.intval += op->value.intval;
diff --git a/gs/src/zarray.c b/gs/src/zarray.c
index e17dad409..843e3b184 100644
--- a/gs/src/zarray.c
+++ b/gs/src/zarray.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,8 +30,9 @@
/* <int> array <array> */
int
-zarray(register os_ptr op)
+zarray(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint size;
int code;
@@ -46,8 +47,9 @@ zarray(register os_ptr op)
/* <array> aload <obj_0> ... <obj_n-1> <array> */
private int
-zaload(register os_ptr op)
+zaload(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref aref;
uint asize;
@@ -85,8 +87,9 @@ zaload(register os_ptr op)
/* <obj_0> ... <obj_n-1> <array> astore <array> */
private int
-zastore(register os_ptr op)
+zastore(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint size;
int code;
diff --git a/gs/src/zbfont.c b/gs/src/zbfont.c
new file mode 100644
index 000000000..6295ac49e
--- /dev/null
+++ b/gs/src/zbfont.c
@@ -0,0 +1,551 @@
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Font creation utilities */
+#include "memory_.h"
+#include "string_.h"
+#include "ghost.h"
+#include "oper.h"
+#include "gxfixed.h"
+#include "gsmatrix.h"
+#include "gxdevice.h"
+#include "gschar.h"
+#include "gxfont.h"
+#include "bfont.h"
+#include "ialloc.h"
+#include "idict.h"
+#include "idparam.h"
+#include "ilevel.h"
+#include "iname.h"
+#include "interp.h" /* for initial_enter_name */
+#include "ipacked.h"
+#include "istruct.h"
+#include "store.h"
+
+/* Registered encodings. See ifont.h for documentation. */
+ref registered_Encodings;
+private ref *const registered_Encodings_p = &registered_Encodings;
+
+/* Structure descriptor */
+public_st_font_data();
+
+/* Initialize the font building operators */
+private int
+zbfont_init(i_ctx_t *i_ctx_p)
+{
+ /* Initialize the registered Encodings. */
+ int i;
+
+ ialloc_ref_array(&registered_Encodings, a_all,
+ registered_Encodings_countof,
+ "registered_Encodings");
+ for (i = 0; i < registered_Encodings_countof; i++)
+ make_empty_array(&registered_Encoding(i), 0);
+ initial_enter_name("registeredencodings", &registered_Encodings);
+ return gs_register_ref_root(imemory, NULL,
+ (void **)&registered_Encodings_p,
+ "registered_Encodings");
+}
+
+/* <string|name> <font_dict> .buildfont3 <string|name> <font> */
+/* Build a type 3 (user-defined) font. */
+private int
+zbuildfont3(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int code;
+ build_proc_refs build;
+ gs_font_base *pfont;
+
+ check_type(*op, t_dictionary);
+ code = build_gs_font_procs(op, &build);
+ if (code < 0)
+ return code;
+ code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_user_defined,
+ &st_gs_font_base, &build, bf_options_none);
+ if (code < 0)
+ return code;
+ return define_gs_font((gs_font *) pfont);
+}
+
+/* Encode a character. */
+private gs_glyph
+zfont_encode_char(gs_show_enum * penum, gs_font * pfont, gs_char * pchr)
+{
+ const ref *pencoding = &pfont_data(pfont)->Encoding;
+ ulong index = *pchr; /* work around VAX widening bug */
+ ref cname;
+ int code = array_get(pencoding, (long)index, &cname);
+
+ if (code < 0 || !r_has_type(&cname, t_name))
+ return gs_no_glyph;
+ return (gs_glyph) name_index(&cname);
+}
+
+/* Encode a character in a known encoding. */
+private gs_glyph
+zfont_known_encode(gs_char chr, int encoding_index)
+{
+ ulong index = chr; /* work around VAX widening bug */
+ ref cname;
+ int code;
+
+ if (encoding_index < 0)
+ return gs_no_glyph;
+ code = array_get(&registered_Encoding(encoding_index),
+ (long)index, &cname);
+ if (code < 0 || !r_has_type(&cname, t_name))
+ return gs_no_glyph;
+ return (gs_glyph) name_index(&cname);
+}
+
+/* Get the name of a glyph. */
+/* The following typedef is needed to work around a bug in */
+/* some AIX C compilers. */
+typedef const char *const_chars;
+private const_chars
+zfont_glyph_name(gs_glyph index, uint * plen)
+{
+ ref nref, sref;
+
+ if (index >= gs_min_cid_glyph) { /* Fabricate a numeric name. */
+ char cid_name[sizeof(gs_glyph) * 3 + 1];
+ int code;
+
+ sprintf(cid_name, "%lu", (ulong) index);
+ code = name_ref((const byte *)cid_name, strlen(cid_name),
+ &nref, 1);
+ if (code < 0)
+ return 0; /* What can we possibly do here? */
+ } else
+ name_index_ref(index, &nref);
+ name_string_ref(&nref, &sref);
+ *plen = r_size(&sref);
+ return (const char *)sref.value.const_bytes;
+}
+
+/* ------ Initialization procedure ------ */
+
+const op_def zbfont_op_defs[] =
+{
+ {"2.buildfont3", zbuildfont3},
+ op_def_end(zbfont_init)
+};
+
+/* ------ Subroutines ------ */
+
+/* Convert strings to executable names for build_proc_refs. */
+int
+build_proc_name_refs(build_proc_refs * pbuild,
+ const char *bcstr, const char *bgstr)
+{
+ int code;
+
+ if (!bcstr)
+ make_null(&pbuild->BuildChar);
+ else {
+ if ((code = name_ref((const byte *)bcstr, strlen(bcstr), &pbuild->BuildChar, 0)) < 0)
+ return code;
+ r_set_attrs(&pbuild->BuildChar, a_executable);
+ }
+ if (!bgstr)
+ make_null(&pbuild->BuildGlyph);
+ else {
+ if ((code = name_ref((const byte *)bgstr, strlen(bgstr), &pbuild->BuildGlyph, 0)) < 0)
+ return code;
+ r_set_attrs(&pbuild->BuildGlyph, a_executable);
+ }
+ return 0;
+}
+
+/* Get the BuildChar and/or BuildGlyph routines from a (base) font. */
+int
+build_gs_font_procs(os_ptr op, build_proc_refs * pbuild)
+{
+ int ccode, gcode;
+ ref *pBuildChar;
+ ref *pBuildGlyph;
+
+ check_type(*op, t_dictionary);
+ ccode = dict_find_string(op, "BuildChar", &pBuildChar);
+ gcode = dict_find_string(op, "BuildGlyph", &pBuildGlyph);
+ if (ccode <= 0) {
+ if (gcode <= 0)
+ return_error(e_invalidfont);
+ make_null(&pbuild->BuildChar);
+ } else {
+ check_proc(*pBuildChar);
+ pbuild->BuildChar = *pBuildChar;
+ }
+ if (gcode <= 0)
+ make_null(&pbuild->BuildGlyph);
+ else {
+ check_proc(*pBuildGlyph);
+ pbuild->BuildGlyph = *pBuildGlyph;
+ }
+ return 0;
+}
+
+/* Do the common work for building a primitive font -- one whose execution */
+/* algorithm is implemented in C (Type 1, Type 2, Type 4, or Type 42). */
+/* The caller guarantees that *op is a dictionary. */
+int
+build_gs_primitive_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
+ font_type ftype, gs_memory_type_ptr_t pstype,
+ const build_proc_refs * pbuild,
+ build_font_options_t options)
+{
+ int painttype;
+ float strokewidth;
+ ref *pcharstrings = 0;
+ gs_font_base *pfont;
+ font_data *pdata;
+ int code;
+
+ code = dict_int_param(op, "PaintType", 0, 3, 0, &painttype);
+ if (code < 0)
+ return code;
+ code = dict_float_param(op, "StrokeWidth", 0.0, &strokewidth);
+ if (code < 0)
+ return code;
+ if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) {
+ if (!(options & bf_CharStrings_optional))
+ return_error(e_invalidfont);
+ } else {
+ ref *ignore;
+
+ if (!r_has_type(pcharstrings, t_dictionary))
+ return_error(e_invalidfont);
+ if ((options & bf_notdef_required) != 0 &&
+ dict_find_string(pcharstrings, ".notdef", &ignore) <= 0
+ )
+ return_error(e_invalidfont);
+ }
+ code = build_gs_simple_font(i_ctx_p, op, &pfont, ftype, pstype, pbuild,
+ options);
+ if (code != 0)
+ return code;
+ pfont->PaintType = painttype;
+ pfont->StrokeWidth = strokewidth;
+ pdata = pfont_data(pfont);
+ if (pcharstrings)
+ ref_assign(&pdata->CharStrings, pcharstrings);
+ else
+ make_null(&pdata->CharStrings);
+ /* Check that the UniqueIDs match. This is part of the */
+ /* Adobe protection scheme, but we may as well emulate it. */
+ if (uid_is_valid(&pfont->UID) &&
+ !dict_check_uid_param(op, &pfont->UID)
+ )
+ uid_set_invalid(&pfont->UID);
+ *ppfont = pfont;
+ return 0;
+}
+
+/* Do the common work for building a font of any non-composite FontType. */
+/* The caller guarantees that *op is a dictionary. */
+int
+build_gs_simple_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont,
+ font_type ftype, gs_memory_type_ptr_t pstype,
+ const build_proc_refs * pbuild,
+ build_font_options_t options)
+{
+ double bbox[4];
+ gs_uid uid;
+ int code;
+ gs_font_base *pfont;
+
+ code = font_bbox_param(op, bbox);
+ if (code < 0)
+ return code;
+ if ((options & bf_FontBBox_required) &&
+ bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0
+ )
+ return_error(e_invalidfont);
+ code = dict_uid_param(op, &uid, 0, imemory, i_ctx_p);
+ if (code < 0)
+ return code;
+ if ((options & bf_UniqueID_ignored) && uid_is_UniqueID(&uid))
+ uid_set_invalid(&uid);
+ code = build_gs_font(i_ctx_p, op, (gs_font **) ppfont, ftype, pstype,
+ pbuild, options);
+ if (code != 0) /* invalid or scaled font */
+ return code;
+ pfont = *ppfont;
+ pfont->procs.init_fstack = gs_default_init_fstack;
+ pfont->procs.next_char = gs_default_next_char;
+ pfont->procs.define_font = gs_no_define_font;
+ pfont->procs.make_font = zbase_make_font;
+ pfont->FontBBox.p.x = bbox[0];
+ pfont->FontBBox.p.y = bbox[1];
+ pfont->FontBBox.q.x = bbox[2];
+ pfont->FontBBox.q.y = bbox[3];
+ pfont->UID = uid;
+ lookup_gs_simple_font_encoding(pfont);
+ return 0;
+}
+
+/* Compare the encoding of a simple font with the registered encodings. */
+void
+lookup_gs_simple_font_encoding(gs_font_base * pfont)
+{
+ const ref *pfe = &pfont_data(pfont)->Encoding;
+ int index;
+
+ for (index = registered_Encodings_countof; --index >= 0;)
+ if (obj_eq(pfe, &registered_Encoding(index)))
+ break;
+ pfont->encoding_index = index;
+ if (index < 0) { /* Look for an encoding that's "close". */
+ int near_index = -1;
+ uint esize = r_size(pfe);
+ uint best = esize / 3; /* must match at least this many */
+
+ for (index = registered_Encodings_countof; --index >= 0;) {
+ const ref *pre = &registered_Encoding(index);
+ bool r_packed = r_has_type(pre, t_shortarray);
+ bool f_packed = !r_has_type(pfe, t_array);
+ uint match = esize;
+ int i;
+ ref fchar, rchar;
+ const ref *pfchar = &fchar;
+
+ if (r_size(pre) != esize)
+ continue;
+ for (i = esize; --i >= 0;) {
+ uint rnidx;
+
+ if (r_packed)
+ rnidx = packed_name_index(pre->value.packed + i);
+ else {
+ array_get(pre, (long)i, &rchar);
+ rnidx = name_index(&rchar);
+ }
+ if (f_packed)
+ array_get(pfe, (long)i, &fchar);
+ else
+ pfchar = pfe->value.const_refs + i;
+ if (!r_has_type(pfchar, t_name) ||
+ name_index(pfchar) != rnidx
+ )
+ if (--match <= best)
+ break;
+ }
+ if (match > best)
+ best = match,
+ near_index = index;
+ }
+ index = near_index;
+ }
+ pfont->nearest_encoding_index = index;
+}
+
+/* Do the common work for building a font of any FontType. */
+/* The caller guarantees that *op is a dictionary. */
+/* op[-1] must be the key under which the font is being registered */
+/* in FontDirectory, normally a name or string. */
+/* Return 0 for a new font, 1 for a font made by makefont or scalefont, */
+/* or a negative error code. */
+private void get_font_name(P2(ref *, const ref *));
+private void copy_font_name(P2(gs_font_name *, const ref *));
+int
+build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
+ gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild,
+ build_font_options_t options)
+{
+ ref kname, fname; /* t_string */
+ ref *pftype;
+ ref *pfontname;
+ ref *pmatrix;
+ gs_matrix mat;
+ ref *pencoding = 0;
+ bool bitmapwidths;
+ int exactsize, inbetweensize, transformedchar;
+ int wmode;
+ int code;
+ gs_font *pfont;
+ ref *pfid;
+ ref *aop = dict_access_ref(op);
+
+ get_font_name(&kname, op - 1);
+ if (dict_find_string(op, "FontType", &pftype) <= 0 ||
+ !r_has_type(pftype, t_integer) ||
+ pftype->value.intval != (int)ftype ||
+ dict_find_string(op, "FontMatrix", &pmatrix) <= 0 ||
+ read_matrix(pmatrix, &mat) < 0
+ )
+ return_error(e_invalidfont);
+ if (dict_find_string(op, "Encoding", &pencoding) <= 0) {
+ if (!(options & bf_Encoding_optional))
+ return_error(e_invalidfont);
+ } else {
+ if (!r_is_array(pencoding))
+ return_error(e_invalidfont);
+ }
+ if (dict_find_string(op, "FontName", &pfontname) > 0)
+ get_font_name(&fname, pfontname);
+ else
+ make_empty_string(&fname, a_readonly);
+ if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 ||
+ (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 ||
+ (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 ||
+ (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 ||
+ (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0
+ )
+ return code;
+ code = dict_find_string(op, "FID", &pfid);
+ if (code > 0) {
+ if (!r_has_type(pfid, t_fontID))
+ return_error(e_invalidfont);
+ /*
+ * If this font has a FID entry already, it might be
+ * a scaled font made by makefont or scalefont;
+ * in a Level 2 environment, it might be an existing font
+ * being registered under a second name, or a re-encoded
+ * font (which is questionable PostScript, but dvips
+ * is known to do this).
+ */
+ pfont = r_ptr(pfid, gs_font);
+ if (pfont->base == pfont) { /* original font */
+ if (!level2_enabled)
+ return_error(e_invalidfont);
+ if (obj_eq(pfont_dict(pfont), op)) {
+ *ppfont = pfont;
+ return 1;
+ }
+ /*
+ * This is a re-encoded font, or some other
+ * questionable situation in which the FID
+ * was preserved. Pretend the FID wasn't there.
+ */
+ } else { /* This was made by makefont or scalefont. */
+ /* Just insert the new name. */
+ code = 1;
+ goto set_name;
+ }
+ }
+ /* This is a new font. */
+ if (!r_has_attr(aop, a_write))
+ return_error(e_invalidaccess);
+ {
+ font_data *pdata;
+ ref encoding;
+ /*
+ * Make sure that we allocate the font data
+ * in the same VM as the font dictionary.
+ */
+ uint space = ialloc_space(idmemory);
+
+ /*
+ * Since add_FID may resize the dictionary and cause
+ * pencoding to become invalid, save the Encoding.
+ */
+ if (pencoding)
+ encoding = *pencoding;
+ ialloc_set_space(idmemory, r_space(op));
+ pfont = ialloc_struct(gs_font, pstype,
+ "buildfont(font)");
+ pdata = ialloc_struct(font_data, &st_font_data,
+ "buildfont(data)");
+ if (pfont == 0 || pdata == 0)
+ code = gs_note_error(e_VMerror);
+ else
+ code = add_FID(i_ctx_p, op, pfont);
+ if (code < 0) {
+ ifree_object(pdata, "buildfont(data)");
+ ifree_object(pfont, "buildfont(font)");
+ ialloc_set_space(idmemory, space);
+ return code;
+ }
+ refset_null((ref *) pdata, sizeof(font_data) / sizeof(ref));
+ ref_assign_new(&pdata->dict, op);
+ ref_assign_new(&pdata->BuildChar, &pbuild->BuildChar);
+ ref_assign_new(&pdata->BuildGlyph, &pbuild->BuildGlyph);
+ if (pencoding)
+ ref_assign_new(&pdata->Encoding, &encoding);
+ /* Clear the chain pointers so as not to confuse the memory */
+ /* manager if we bail out after returning from here. */
+ pfont->next = pfont->prev = 0;
+ pfont->memory = imemory;
+ pfont->dir = 0;
+ pfont->base = pfont;
+ pfont->client_data = pdata;
+ pfont->FontType = ftype;
+ pfont->FontMatrix = mat;
+ pfont->BitmapWidths = bitmapwidths;
+ pfont->ExactSize = (fbit_type) exactsize;
+ pfont->InBetweenSize = (fbit_type) inbetweensize;
+ pfont->TransformedChar = (fbit_type) transformedchar;
+ pfont->WMode = wmode;
+ pfont->PaintType = 0;
+ pfont->StrokeWidth = 0.0;
+ pfont->procs.build_char = gs_no_build_char;
+ pfont->procs.encode_char = zfont_encode_char;
+ pfont->procs.callbacks.glyph_name = zfont_glyph_name;
+ pfont->procs.callbacks.known_encode = zfont_known_encode;
+ ialloc_set_space(idmemory, space);
+ }
+ code = 0;
+set_name:
+ copy_font_name(&pfont->key_name, &kname);
+ copy_font_name(&pfont->font_name, &fname);
+ *ppfont = pfont;
+ return code;
+}
+
+/* Get the string corresponding to a font name. */
+/* If the font name isn't a name or a string, return an empty string. */
+private void
+get_font_name(ref * pfname, const ref * op)
+{
+ switch (r_type(op)) {
+ case t_string:
+ *pfname = *op;
+ break;
+ case t_name:
+ name_string_ref(op, pfname);
+ break;
+ default:
+ /* This is weird, but legal.... */
+ make_empty_string(pfname, a_readonly);
+ }
+}
+
+/* Copy a font name into the gs_font structure. */
+private void
+copy_font_name(gs_font_name * pfstr, const ref * pfname)
+{
+ uint size = r_size(pfname);
+
+ if (size > gs_font_name_max)
+ size = gs_font_name_max;
+ memcpy(&pfstr->chars[0], pfname->value.const_bytes, size);
+ /* Following is only for debugging printout. */
+ pfstr->chars[size] = 0;
+ pfstr->size = size;
+}
+
+/* Finish building a font, by calling gs_definefont if needed. */
+int
+define_gs_font(gs_font * pfont)
+{
+ return (pfont->base == pfont && pfont->dir == 0 ? /* i.e., unregistered original font */
+ gs_definefont(ifont_dir, pfont) :
+ 0);
+}
diff --git a/gs/src/zbseq.c b/gs/src/zbseq.c
index d68449e05..005a3f52e 100644
--- a/gs/src/zbseq.c
+++ b/gs/src/zbseq.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,21 +25,13 @@
#include "btoken.h"
#include "store.h"
-/* Current binary format (in iscan.c) */
-extern ref ref_binary_object_format;
-
/* System and user name arrays. */
ref binary_token_names; /* array of size 2 */
private ref *const binary_token_names_p = &binary_token_names;
-/* Import the Level 2 scanner extensions. */
-typedef struct scanner_state_s scanner_state;
-extern int scan_binary_token(P3(stream *, ref *, scanner_state *));
-extern int (*scan_btoken_proc) (P3(stream *, ref *, scanner_state *));
-
/* Initialize the binary token machinery. */
-private void
-zbseq_init(void)
+private int
+zbseq_init(i_ctx_t *i_ctx_p)
{
/* Initialize fake system and user name tables. */
/* PostScript code will install the real system name table. */
@@ -47,17 +39,16 @@ zbseq_init(void)
"binary token names");
make_empty_array(system_names_p, a_readonly);
make_empty_array(user_names_p, a_all);
- gs_register_ref_root(imemory, NULL, (void **)&binary_token_names_p,
- "binary token names");
-
- /* Set up Level 2 scanning constants. */
- scan_btoken_proc = scan_binary_token;
+ return gs_register_ref_root(imemory, NULL, (void **)&binary_token_names_p,
+ "binary token names");
}
/* <names> .installsystemnames - */
private int
-zinstallsystemnames(register os_ptr op)
+zinstallsystemnames(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
if (r_space(op) != avm_global)
return_error(e_invalidaccess);
check_read_type(*op, t_shortarray);
@@ -68,8 +59,10 @@ zinstallsystemnames(register os_ptr op)
/* - currentobjectformat <int> */
private int
-zcurrentobjectformat(register os_ptr op)
+zcurrentobjectformat(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = ref_binary_object_format;
return 0;
@@ -77,12 +70,16 @@ zcurrentobjectformat(register os_ptr op)
/* <int> setobjectformat - */
private int
-zsetobjectformat(register os_ptr op)
+zsetobjectformat(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ ref cont;
+
check_type(*op, t_integer);
if (op->value.intval < 0 || op->value.intval > 4)
return_error(e_rangecheck);
- ref_assign_old(NULL, &ref_binary_object_format, op, "setobjectformat");
+ make_struct(&cont, avm_local, ref_binary_object_format_container);
+ ref_assign_old(&cont, &ref_binary_object_format, op, "setobjectformat");
pop(1);
return 0;
}
@@ -98,8 +95,9 @@ zsetobjectformat(register os_ptr op)
*/
private int
-zbosobject(os_ptr op)
+zbosobject(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(op[-3], t_integer);
@@ -107,7 +105,7 @@ zbosobject(os_ptr op)
check_write_type(*op, t_string);
if (r_size(op) < 8)
return_error(e_rangecheck);
- code = encode_binary_token(op - 1, &op[-3].value.intval,
+ code = encode_binary_token(i_ctx_p, op - 1, &op[-3].value.intval,
&op[-2].value.intval, op->value.bytes);
if (code < 0)
return code;
diff --git a/gs/src/zcfont.c b/gs/src/zcfont.c
index 9822ae172..ec57e26cb 100644
--- a/gs/src/zcfont.c
+++ b/gs/src/zcfont.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,13 +32,14 @@
#include "store.h"
/* Forward references */
-private int cshow_continue(P1(os_ptr));
-private int cshow_restore_font(P1(os_ptr));
+private int cshow_continue(P1(i_ctx_t *));
+private int cshow_restore_font(P1(i_ctx_t *));
/* <proc> <string> cshow - */
private int
-zcshow(os_ptr op)
+zcshow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr proc_op = op - 1;
os_ptr str_op = op;
gs_show_enum *penum;
@@ -58,7 +59,7 @@ zcshow(os_ptr op)
check_op(2);
return_error(e_typecheck);
}
- if ((code = op_show_setup(str_op, &penum)) != 0)
+ if ((code = op_show_setup(i_ctx_p, str_op, &penum)) != 0)
return code;
if ((code = gs_cshow_n_init(penum, igs, (char *)str_op->value.bytes,
r_size(str_op))) < 0
@@ -66,20 +67,22 @@ zcshow(os_ptr op)
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 2, NULL);
+ op_show_finish_setup(i_ctx_p, penum, 2, NULL);
sslot = *proc_op; /* save kerning proc */
- return cshow_continue(op - 2);
+ pop(2);
+ return cshow_continue(i_ctx_p);
}
private int
-cshow_continue(os_ptr op)
+cshow_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum = senum;
int code;
check_estack(4); /* in case we call the procedure */
code = gs_show_next(penum);
if (code != gs_show_move) {
- code = op_show_continue_dispatch(op, code);
+ code = op_show_continue_dispatch(i_ctx_p, 0, code);
if (code == o_push_estack) /* must be gs_show_render */
make_op_estack(esp - 1, cshow_continue);
return code;
@@ -118,7 +121,7 @@ cshow_continue(os_ptr op)
scaled_font = font;
#endif
push(3);
- make_int(op - 2, gs_show_current_char(penum));
+ make_int(op - 2, gs_show_current_char(penum) & 0xff);
make_real(op - 1, wpt.x);
make_real(op, wpt.y);
push_op_estack(cshow_continue);
@@ -131,15 +134,17 @@ cshow_continue(os_ptr op)
return o_push_estack;
}
private int
-cshow_restore_font(os_ptr op)
+cshow_restore_font(i_ctx_t *i_ctx_p)
{ /* We have 1 more entry on the e-stack (cshow_continue). */
return gs_show_restore_font(esenum(esp - 1));
}
/* - rootfont <font> */
private int
-zrootfont(os_ptr op)
+zrootfont(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = *pfont_dict(gs_rootfont(igs));
return 0;
diff --git a/gs/src/zchar.c b/gs/src/zchar.c
index ea31cc8b5..13a7b0be3 100644
--- a/gs/src/zchar.c
+++ b/gs/src/zchar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,7 +27,6 @@
#include "gxchar.h" /* for stringwidth_flag */
#include "gxdevice.h" /* for gxfont.h */
#include "gxfont.h"
-#include "gzpath.h"
#include "gzstate.h"
#include "dstack.h" /* for stack depth */
#include "estack.h"
@@ -43,17 +42,18 @@
/* Forward references */
private bool map_glyph_to_char(P3(const ref *, const ref *, ref *));
-private int finish_show(P1(os_ptr));
-private int finish_stringwidth(P1(os_ptr));
-private int op_show_cleanup(P1(os_ptr));
-private int op_show_return_width(P3(os_ptr, uint, double *));
+private int finish_show(P1(i_ctx_t *));
+private int finish_stringwidth(P1(i_ctx_t *));
+private int op_show_cleanup(P1(i_ctx_t *));
+private int op_show_return_width(P3(i_ctx_t *, uint, double *));
/* <string> show - */
private int
-zshow(register os_ptr op)
+zshow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
- int code = op_show_setup(op, &penum);
+ int code = op_show_setup(i_ctx_p, op, &penum);
if (code != 0)
return code;
@@ -61,34 +61,36 @@ zshow(register os_ptr op)
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 1, finish_show);
- return op_show_continue(op - 1);
+ op_show_finish_setup(i_ctx_p, penum, 1, finish_show);
+ return op_show_contioue_pop(i_ctx_p, 1);
}
/* <ax> <ay> <string> ashow - */
private int
-zashow(register os_ptr op)
+zashow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
int code;
double axy[2];
if ((code = num_params(op - 1, 2, axy)) < 0 ||
- (code = op_show_setup(op, &penum)) != 0
+ (code = op_show_setup(i_ctx_p, op, &penum)) != 0
)
return code;
if ((code = gs_ashow_n_init(penum, igs, axy[0], axy[1], (char *)op->value.bytes, r_size(op))) < 0) {
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 3, finish_show);
- return op_show_continue(op - 3);
+ op_show_finish_setup(i_ctx_p, penum, 3, finish_show);
+ return op_show_continue_pop(i_ctx_p, 3);
}
/* <cx> <cy> <char> <string> widthshow - */
private int
-zwidthshow(register os_ptr op)
+zwidthshow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
int code;
double cxy[2];
@@ -97,7 +99,7 @@ zwidthshow(register os_ptr op)
if ((gs_char) (op[-1].value.intval) != op[-1].value.intval)
return_error(e_rangecheck);
if ((code = num_params(op - 2, 2, cxy)) < 0 ||
- (code = op_show_setup(op, &penum)) != 0
+ (code = op_show_setup(i_ctx_p, op, &penum)) != 0
)
return code;
if ((code = gs_widthshow_n_init(penum, igs, cxy[0], cxy[1],
@@ -107,14 +109,15 @@ zwidthshow(register os_ptr op)
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 4, finish_show);
- return op_show_continue(op - 4);
+ op_show_finish_setup(i_ctx_p, penum, 4, finish_show);
+ return op_show_continue_pop(i_ctx_p, 4);
}
/* <cx> <cy> <char> <ax> <ay> <string> awidthshow - */
private int
-zawidthshow(register os_ptr op)
+zawidthshow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
int code;
double cxy[2], axy[2];
@@ -124,7 +127,7 @@ zawidthshow(register os_ptr op)
return_error(e_rangecheck);
if ((code = num_params(op - 4, 2, cxy)) < 0 ||
(code = num_params(op - 1, 2, axy)) < 0 ||
- (code = op_show_setup(op, &penum)) != 0
+ (code = op_show_setup(i_ctx_p, op, &penum)) != 0
)
return code;
if ((code = gs_awidthshow_n_init(penum, igs, cxy[0], cxy[1],
@@ -135,43 +138,45 @@ zawidthshow(register os_ptr op)
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 6, finish_show);
- return op_show_continue(op - 6);
+ op_show_finish_setup(i_ctx_p, penum, 6, finish_show);
+ return op_show_continue_pop(i_ctx_p, 6);
}
/* <proc> <string> kshow - */
private int
-zkshow(register os_ptr op)
+zkshow(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
int code;
check_proc(op[-1]);
- if ((code = op_show_setup(op, &penum)) != 0)
+ if ((code = op_show_setup(i_ctx_p, op, &penum)) != 0)
return code;
if ((code = gs_kshow_n_init(penum, igs, (char *)op->value.bytes, r_size(op))) < 0) {
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 2, finish_show);
+ op_show_finish_setup(i_ctx_p, penum, 2, finish_show);
sslot = op[-1]; /* save kerning proc */
- return op_show_continue(op - 2);
+ return op_show_continue_pop(i_ctx_p, 2);
}
/* Common finish procedure for all show operations. */
/* Doesn't have to do anything. */
private int
-finish_show(os_ptr op)
+finish_show(i_ctx_t *i_ctx_p)
{
return 0;
}
/* <string> stringwidth <wx> <wy> */
private int
-zstringwidth(register os_ptr op)
+zstringwidth(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_show_enum *penum;
- int code = op_show_setup(op, &penum);
+ int code = op_show_setup(i_ctx_p, op, &penum);
if (code != 0)
return code;
@@ -179,14 +184,15 @@ zstringwidth(register os_ptr op)
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 1, finish_stringwidth);
- return op_show_continue(op - 1);
+ op_show_finish_setup(i_ctx_p, penum, 1, finish_stringwidth);
+ return op_show_continue_pop(i_ctx_p, 1);
}
/* Finishing procedure for stringwidth. */
/* Pushes the accumulated width. */
private int
-finish_stringwidth(register os_ptr op)
+finish_stringwidth(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_point width;
gs_show_width(senum, &width);
@@ -198,42 +204,44 @@ finish_stringwidth(register os_ptr op)
/* Common code for charpath and .charboxpath. */
private int
-zchar_path(register os_ptr op,
- int (*init)(P5(gs_show_enum *, gs_state *, const char *, uint, bool)))
+zchar_path(i_ctx_t *i_ctx_p,
+ int (*init)(P5(gs_show_enum *, gs_state *, const char *, uint, bool)))
{
+ os_ptr op = osp;
gs_show_enum *penum;
int code;
check_type(*op, t_boolean);
- code = op_show_setup(op - 1, &penum);
+ code = op_show_setup(i_ctx_p, op - 1, &penum);
if (code != 0)
return code;
if ((code = (*init)(penum, igs, (char *)op[-1].value.bytes, r_size(op - 1), op->value.boolval)) < 0) {
ifree_object(penum, "op_show_enum_setup");
return code;
}
- op_show_finish_setup(penum, 2, finish_show);
- return op_show_continue(op - 2);
+ op_show_finish_setup(i_ctx_p, penum, 2, finish_show);
+ return op_show_continue_pop(i_ctx_p, 2);
}
/* <string> <outline_bool> charpath - */
private int
-zcharpath(register os_ptr op)
+zcharpath(i_ctx_t *i_ctx_p)
{
- return zchar_path(op, gs_charpath_n_init);
+ return zchar_path(i_ctx_p, gs_charpath_n_init);
}
/* <string> <box_bool> .charboxpath - */
private int
-zcharboxpath(register os_ptr op)
+zcharboxpath(i_ctx_t *i_ctx_p)
{
- return zchar_path(op, gs_charboxpath_n_init);
+ return zchar_path(i_ctx_p, gs_charboxpath_n_init);
}
/* <wx> <wy> <llx> <lly> <urx> <ury> setcachedevice - */
int
-zsetcachedevice(register os_ptr op)
+zsetcachedevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double wbox[6];
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
int code = num_params(op, 6, wbox);
if (penum == 0)
@@ -241,7 +249,7 @@ zsetcachedevice(register os_ptr op)
if (code < 0)
return code;
if (gs_show_width_only(penum))
- return op_show_return_width(op, 6, &wbox[0]);
+ return op_show_return_width(i_ctx_p, 6, &wbox[0]);
code = gs_setcachedevice_double(penum, igs, wbox);
if (code < 0)
return code;
@@ -253,10 +261,11 @@ zsetcachedevice(register os_ptr op)
/* <w0x> <w0y> <llx> <lly> <urx> <ury> <w1x> <w1y> <vx> <vy> setcachedevice2 - */
int
-zsetcachedevice2(os_ptr op)
+zsetcachedevice2(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double wbox[10];
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
int code = num_params(op, 10, wbox);
if (penum == 0)
@@ -264,7 +273,7 @@ zsetcachedevice2(os_ptr op)
if (code < 0)
return code;
if (gs_show_width_only(penum))
- return op_show_return_width(op, 10,
+ return op_show_return_width(i_ctx_p, 10,
(gs_rootfont(igs)->WMode ?
&wbox[6] : &wbox[0]));
code = gs_setcachedevice2_double(penum, igs, wbox);
@@ -278,10 +287,11 @@ zsetcachedevice2(os_ptr op)
/* <wx> <wy> setcharwidth - */
private int
-zsetcharwidth(register os_ptr op)
+zsetcharwidth(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double width[2];
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
int code = num_params(op, 2, width);
if (penum == 0)
@@ -289,7 +299,7 @@ zsetcharwidth(register os_ptr op)
if (code < 0)
return code;
if (gs_show_width_only(penum))
- return op_show_return_width(op, 2, &width[0]);
+ return op_show_return_width(i_ctx_p, 2, &width[0]);
code = gs_setcharwidth(penum, igs, width[0], width[1]);
if (code < 0)
return code;
@@ -300,8 +310,9 @@ zsetcharwidth(register os_ptr op)
/* <dict> .fontbbox <llx> <lly> <urx> <ury> -true- */
/* <dict> .fontbbox -false- */
private int
-zfontbbox(register os_ptr op)
+zfontbbox(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double bbox[4];
int code;
@@ -361,13 +372,13 @@ glyph_ref(gs_glyph glyph, ref * gref)
/* Prepare to set up for a show operator. */
/* Don't change any state yet. */
int
-op_show_setup(os_ptr op, gs_show_enum ** ppenum)
+op_show_setup(i_ctx_t *i_ctx_p, os_ptr op, gs_show_enum ** ppenum)
{
check_read_type(*op, t_string);
- return op_show_enum_setup(op, ppenum);
+ return op_show_enum_setup(i_ctx_p, ppenum);
}
int
-op_show_enum_setup(os_ptr op, gs_show_enum ** ppenum)
+op_show_enum_setup(i_ctx_t *i_ctx_p, gs_show_enum ** ppenum)
{
check_estack(snumpush + 2);
if ((*ppenum = gs_show_enum_alloc((gs_memory_t *) imemory, igs, "op_show_enum_setup")) == 0)
@@ -378,7 +389,8 @@ op_show_enum_setup(os_ptr op, gs_show_enum ** ppenum)
/* Finish setting up a show operator. This can't fail, since */
/* op_show_enum_setup did the check_estack. */
void
-op_show_finish_setup(gs_show_enum * penum, int npop, op_proc_p endproc /* end procedure */ )
+op_show_finish_setup(i_ctx_t *i_ctx_p, gs_show_enum * penum, int npop,
+ op_proc_t endproc /* end procedure */ )
{
register es_ptr ep = esp + snumpush;
@@ -398,9 +410,14 @@ op_show_finish_setup(gs_show_enum * penum, int npop, op_proc_p endproc /* end pr
/* Continuation operator for character rendering. */
int
-op_show_continue(os_ptr op)
+op_show_continue(i_ctx_t *i_ctx_p)
{
- return op_show_continue_dispatch(op, gs_show_next(senum));
+ return op_show_continue_dispatch(i_ctx_p, 0, gs_show_next(senum));
+}
+int
+op_show_continue_pop(i_ctx_t *i_ctx_p, int npop)
+{
+ return op_show_continue_dispatch(i_ctx_p, npop, gs_show_next(senum));
}
/*
* Note that op_show_continue_dispatch sets osp = op explicitly iff the
@@ -409,16 +426,18 @@ op_show_continue(os_ptr op)
* error, it has freed the enumerator.
*/
int
-op_show_continue_dispatch(register os_ptr op, int code)
+op_show_continue_dispatch(i_ctx_t *i_ctx_p, int npop, int code)
{
+ os_ptr op = osp - npop;
gs_show_enum *penum = senum;
switch (code) {
case 0: { /* all done */
os_ptr save_osp = osp;
+
osp = op;
- code = (*real_opproc(&seproc)) (op);
- op_show_free(code);
+ code = (*real_opproc(&seproc)) (i_ctx_p);
+ op_show_free(i_ctx_p, code);
if (code < 0) {
osp = save_osp;
return code;
@@ -444,14 +463,17 @@ op_show_continue_dispatch(register os_ptr op, int code)
push(2);
op[-1] = pfdata->dict; /* push the font */
/*
- * For Type 1 and Type 4 fonts, prefer BuildChar to
- * BuildGlyph, so that PostScript procedures appearing in the
- * CharStrings dictionary will receive the character code
- * rather than the character name; for Type 3 fonts,
- * prefer BuildGlyph to BuildChar. For other font types
+ * For Type 1 and Type 4 fonts, prefer BuildChar to BuildGlyph
+ * if there is no glyph, or if there is both a character and a
+ * glyph and the glyph is the one that corresponds to the
+ * character in the Encoding, so that PostScript procedures
+ * appearing in the CharStrings dictionary will receive the
+ * character code rather than the character name; for Type 3
+ * fonts, prefer BuildGlyph to BuildChar. For other font types
* (such as CID fonts), only BuildGlyph will be present.
*/
- if (pfont->FontType == ft_user_defined) { /* Type 3 font, prefer BuildGlyph. */
+ if (pfont->FontType == ft_user_defined) {
+ /* Type 3 font, prefer BuildGlyph. */
if (level2_enabled &&
!r_has_type(&pfdata->BuildGlyph, t_null) &&
glyph != gs_no_glyph
@@ -460,7 +482,8 @@ op_show_continue_dispatch(register os_ptr op, int code)
esp[2] = pfdata->BuildGlyph;
} else if (r_has_type(&pfdata->BuildChar, t_null))
goto err;
- else if (chr == gs_no_char) { /* glyphshow, reverse map the character */
+ else if (chr == gs_no_char) {
+ /* glyphshow, reverse map the character */
/* through the Encoding */
ref gref;
const ref *pencoding = &pfdata->Encoding;
@@ -478,17 +501,25 @@ op_show_continue_dispatch(register os_ptr op, int code)
}
esp[2] = pfdata->BuildChar;
} else {
- make_int(op, chr);
+ make_int(op, chr & 0xff);
esp[2] = pfdata->BuildChar;
}
} else {
/*
- * For a Type 1 or Type 4 font, prefer BuildChar: we know
- * that both BuildChar and BuildGlyph are present. For
- * other font types, only BuildGlyph is available.
+ * For a Type 1 or Type 4 font, prefer BuildChar or
+ * BuildGlyph as described above: we know that both
+ * BuildChar and BuildGlyph are present. For other font
+ * types, only BuildGlyph is available.
*/
- if (chr != gs_no_char && !r_has_type(&pfdata->BuildChar, t_null)) {
- make_int(op, chr);
+ ref eref, gref;
+
+ if (chr != gs_no_char &&
+ !r_has_type(&pfdata->BuildChar, t_null) &&
+ (glyph == gs_no_glyph ||
+ (array_get(&pfdata->Encoding, (long)(chr & 0xff), &eref) >= 0 &&
+ (glyph_ref(glyph, &gref), obj_eq(&gref, &eref))))
+ ) {
+ make_int(op, chr & 0xff);
esp[2] = pfdata->BuildChar;
} else {
/* We might not have a glyph: substitute 0. **HACK** */
@@ -510,7 +541,7 @@ op_show_continue_dispatch(register os_ptr op, int code)
err:
if (code >= 0)
code = gs_note_error(e_invalidfont);
- return op_show_free(code);
+ return op_show_free(i_ctx_p, code);
}
}
/* Reverse-map a glyph name to a character code for glyphshow. */
@@ -534,7 +565,7 @@ map_glyph_to_char(const ref * pgref, const ref * pencoding, ref * pch)
/* Find the index of the e-stack mark for the current show enumerator. */
/* Return 0 if we can't find the mark. */
uint
-op_show_find_index(void)
+op_show_find_index(i_ctx_t *i_ctx_p)
{
ref_stack_enum_t rsenum;
uint count = 0;
@@ -553,9 +584,9 @@ op_show_find_index(void)
/* Find the current show enumerator on the e-stack. */
gs_show_enum *
-op_show_find(void)
+op_show_find(i_ctx_t *i_ctx_p)
{
- uint index = op_show_find_index();
+ uint index = op_show_find_index(i_ctx_p);
if (index == 0)
return 0; /* no mark */
@@ -568,9 +599,9 @@ op_show_find(void)
/* a stringwidth or cshow, or if we are only collecting the scalable */
/* width for an xfont character. */
private int
-op_show_return_width(os_ptr op, uint npop, double *pwidth)
+op_show_return_width(i_ctx_t *i_ctx_p, uint npop, double *pwidth)
{
- uint index = op_show_find_index();
+ uint index = op_show_find_index(i_ctx_p);
es_ptr ep = (es_ptr) ref_stack_index(&e_stack, index - (snumpush - 1));
int code = gs_setcharwidth(esenum(ep), igs, pwidth[0], pwidth[1]);
uint ocount, dsaved, dcount;
@@ -586,7 +617,7 @@ op_show_return_width(os_ptr op, uint npop, double *pwidth)
if (dcount < dsaved)
return_error(e_dictstackunderflow);
while (dcount > dsaved) {
- code = zend(op);
+ code = zend(i_ctx_p);
if (code < 0)
return code;
dcount--;
@@ -594,7 +625,7 @@ op_show_return_width(os_ptr op, uint npop, double *pwidth)
ref_stack_pop(&o_stack, ocount);
/* We don't want to pop the mark or the continuation */
/* procedure (op_show_continue or cshow_continue). */
- pop_estack(index - snumpush);
+ pop_estack(i_ctx_p, index - snumpush);
return o_pop_estack;
}
@@ -603,7 +634,7 @@ op_show_return_width(os_ptr op, uint npop, double *pwidth)
* operation. Note that we assume op == osp, and may reset osp.
*/
private int
-op_show_restore(bool for_error)
+op_show_restore(i_ctx_t *i_ctx_p, bool for_error)
{
register es_ptr ep = esp + snumpush;
gs_show_enum *penum = esenum(ep);
@@ -643,18 +674,18 @@ op_show_restore(bool for_error)
}
/* Clean up after an error. */
private int
-op_show_cleanup(os_ptr op)
+op_show_cleanup(i_ctx_t *i_ctx_p)
{
- return op_show_restore(true);
+ return op_show_restore(i_ctx_p, true);
}
/* Clean up after termination of a show operation. */
int
-op_show_free(int code)
+op_show_free(i_ctx_t *i_ctx_p, int code)
{
int rcode;
esp -= snumpush;
- rcode = op_show_restore(code < 0);
+ rcode = op_show_restore(i_ctx_p, code < 0);
return (rcode < 0 ? rcode : code);
}
diff --git a/gs/src/zchar1.c b/gs/src/zchar1.c
index bf6ad1c34..281fed557 100644
--- a/gs/src/zchar1.c
+++ b/gs/src/zchar1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -18,6 +18,7 @@
/* Type 1 character display operator */
+#include "memory_.h"
#include "ghost.h"
#include "oper.h"
#include "gsstruct.h"
@@ -37,6 +38,7 @@
#include "estack.h"
#include "ialloc.h"
#include "ichar.h"
+#include "ichar1.h"
#include "icharout.h"
#include "idict.h"
#include "ifont.h"
@@ -46,18 +48,19 @@
/* ---------------- Inline utilities ---------------- */
-/* Test whether a font is Type 1 compatible. */
-inline private bool
-font_is_type1_compatible(const gs_font *pfont)
+/* Test whether a font is a CharString font. */
+private bool
+font_uses_charstrings(const gs_font *pfont)
{
return (pfont->FontType == ft_encrypted ||
+ pfont->FontType == ft_encrypted2 ||
pfont->FontType == ft_disk_based);
}
/* ---------------- .type1execchar ---------------- */
/*
- * This is the workhorse for %Type1BuildChar, %Type1BuildGlyph,
+ * This is the workhorse for %Type1/2BuildChar, %Type1/2BuildGlyph,
* CCRun, and CID fonts. Eventually this will appear in the C API;
* even now, its normal control path doesn't use any continuations.
*/
@@ -68,6 +71,7 @@ font_is_type1_compatible(const gs_font *pfont)
*/
typedef struct gs_type1exec_state_s {
gs_type1_state cis; /* must be first */
+ i_ctx_t *i_ctx_p; /* so push/pop can access o-stack */
double sbw[4];
int /*metrics_present */ present;
gs_rect char_bbox;
@@ -80,51 +84,62 @@ typedef struct gs_type1exec_state_s {
int num_args;
} gs_type1exec_state;
-gs_private_st_suffix_add0(st_gs_type1exec_state, gs_type1exec_state,
+gs_private_st_suffix_add1(st_gs_type1exec_state, gs_type1exec_state,
"gs_type1exec_state", gs_type1exec_state_enum_ptrs,
- gs_type1exec_state_reloc_ptrs, st_gs_type1_state);
+ gs_type1exec_state_reloc_ptrs, st_gs_type1_state,
+ i_ctx_p);
/* Forward references */
-private int bbox_continue(P1(os_ptr));
-private int nobbox_continue(P1(os_ptr));
-private int type1_push_OtherSubr(P3(const gs_type1exec_state *,
- int (*)(P1(os_ptr)), const ref *));
-private int type1_call_OtherSubr(P3(const gs_type1exec_state *,
- int (*)(P1(os_ptr)), const ref *));
-private int type1_callout_dispatch(P3(os_ptr, int (*)(P1(os_ptr)), int));
-private int type1_continue_dispatch(P4(gs_type1exec_state *, const ref *,
- ref *, int));
-private int op_type1_cleanup(P1(os_ptr));
-private void op_type1_free(P1(os_ptr));
+private int bbox_continue(P1(i_ctx_t *));
+private int nobbox_continue(P1(i_ctx_t *));
+private int type1_push_OtherSubr(P4(i_ctx_t *, const gs_type1exec_state *,
+ int (*)(P1(i_ctx_t *)), const ref *));
+private int type1_call_OtherSubr(P4(i_ctx_t *, const gs_type1exec_state *,
+ int (*)(P1(i_ctx_t *)), const ref *));
+private int type1_callout_dispatch(P3(i_ctx_t *, int (*)(P1(i_ctx_t *)),
+ int));
+private int type1_continue_dispatch(P5(i_ctx_t *, gs_type1exec_state *,
+ const ref *, ref *, int));
+private int op_type1_cleanup(P1(i_ctx_t *));
+private void op_type1_free(P1(i_ctx_t *));
private void
type1_cis_get_metrics(P2(const gs_type1_state * pcis, double psbw[4]));
-private int bbox_getsbw_continue(P1(os_ptr));
-private int type1exec_bbox(P3(os_ptr, gs_type1exec_state *, gs_font *));
-private int bbox_finish_fill(P1(os_ptr));
-private int bbox_finish_stroke(P1(os_ptr));
-private int bbox_fill(P1(os_ptr));
-private int bbox_stroke(P1(os_ptr));
-private int nobbox_finish(P2(os_ptr, gs_type1exec_state *));
-private int nobbox_draw(P2(os_ptr, int (*)(P1(gs_state *))));
-private int nobbox_fill(P1(os_ptr));
-private int nobbox_stroke(P1(os_ptr));
+private int bbox_getsbw_continue(P1(i_ctx_t *));
+private int type1exec_bbox(P3(i_ctx_t *, gs_type1exec_state *, gs_font *));
+private int bbox_finish_fill(P1(i_ctx_t *));
+private int bbox_finish_stroke(P1(i_ctx_t *));
+private int bbox_fill(P1(i_ctx_t *));
+private int bbox_stroke(P1(i_ctx_t *));
+private int nobbox_finish(P2(i_ctx_t *, gs_type1exec_state *));
+private int nobbox_draw(P2(i_ctx_t *, int (*)(P1(gs_state *))));
+private int nobbox_fill(P1(i_ctx_t *));
+private int nobbox_stroke(P1(i_ctx_t *));
/* <font> <code|name> <name> <charstring> .type1execchar - */
private int
-ztype1execchar(register os_ptr op)
+ztype1execchar(i_ctx_t *i_ctx_p)
{
+ return charstring_execchar(i_ctx_p, (1 << (int)ft_encrypted) |
+ (1 << (int)ft_disk_based));
+}
+int
+charstring_execchar(i_ctx_t *i_ctx_p, int font_type_mask)
+{
+ os_ptr op = osp;
gs_font *pfont;
int code = font_param(op - 3, &pfont);
gs_font_base *const pbfont = (gs_font_base *) pfont;
gs_font_type1 *const pfont1 = (gs_font_type1 *) pfont;
const gs_type1_data *pdata;
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
gs_type1exec_state cxs;
gs_type1_state *const pcis = &cxs.cis;
if (code < 0)
return code;
- if (penum == 0 || !font_is_type1_compatible(pfont))
+ if (penum == 0 ||
+ pfont->FontType > sizeof(font_type_mask) * 8 ||
+ !(font_type_mask & (1 << (int)pfont->FontType)))
return_error(e_undefined);
pdata = &pfont1->data;
/*
@@ -141,7 +156,7 @@ ztype1execchar(register os_ptr op)
* Execute the definition of the character.
*/
if (r_is_proc(op))
- return zchar_exec_char_proc(op);
+ return zchar_exec_char_proc(i_ctx_p);
/*
* The definition must be a Type 1 CharString.
* Note that we do not require read access: this is deliberate.
@@ -169,12 +184,13 @@ ztype1execchar(register os_ptr op)
pfont1->PaintType, pfont1);
if (code < 0)
return code;
+ gs_type1_set_callback_data(pcis, &cxs);
if (pfont1->FontBBox.q.x > pfont1->FontBBox.p.x &&
pfont1->FontBBox.q.y > pfont1->FontBBox.p.y
) {
/* The FontBBox appears to be valid. */
cxs.char_bbox = pfont1->FontBBox;
- return type1exec_bbox(op, &cxs, pfont);
+ return type1exec_bbox(i_ctx_p, &cxs, pfont);
} else {
/*
* The FontBBox is not valid. In this case,
@@ -195,15 +211,15 @@ ztype1execchar(register os_ptr op)
}
/* Continue interpreting. */
icont:
- code = type1_continue_dispatch(&cxs, opstr, &other_subr, 4);
+ code = type1_continue_dispatch(i_ctx_p, &cxs, opstr, &other_subr, 4);
op = osp; /* OtherSubrs might change it */
switch (code) {
case 0: /* all done */
- return nobbox_finish(op, &cxs);
+ return nobbox_finish(i_ctx_p, &cxs);
default: /* code < 0, error */
return code;
case type1_result_callothersubr: /* unknown OtherSubr */
- return type1_call_OtherSubr(&cxs, nobbox_continue,
+ return type1_call_OtherSubr(i_ctx_p, &cxs, nobbox_continue,
&other_subr);
case type1_result_sbw: /* [h]sbw, just continue */
if (cxs.present != metricsSideBearingAndWidth)
@@ -218,8 +234,10 @@ ztype1execchar(register os_ptr op)
/* Do all the work for the case where we have a bounding box. */
private int
-type1exec_bbox(os_ptr op, gs_type1exec_state * pcxs, gs_font * pfont)
+type1exec_bbox(i_ctx_t *i_ctx_p, gs_type1exec_state * pcxs,
+ gs_font * pfont)
{
+ os_ptr op = osp;
gs_type1_state *const pcis = &pcxs->cis;
gs_font_base *const pbfont = (gs_font_base *) pfont;
@@ -238,28 +256,28 @@ type1exec_bbox(os_ptr op, gs_type1exec_state * pcxs, gs_font * pfont)
/* Since an OtherSubr callout might change osp, */
/* save the character name now. */
ref_assign(&cnref, op - 1);
- code = type1_continue_dispatch(pcxs, op, &other_subr, 4);
+ code = type1_continue_dispatch(i_ctx_p, pcxs, op, &other_subr, 4);
op = osp; /* OtherSubrs might change it */
switch (code) {
default: /* code < 0 or done, error */
return ((code < 0 ? code :
gs_note_error(e_invalidfont)));
case type1_result_callothersubr: /* unknown OtherSubr */
- return type1_call_OtherSubr(pcxs,
+ return type1_call_OtherSubr(i_ctx_p, pcxs,
bbox_getsbw_continue,
&other_subr);
case type1_result_sbw: /* [h]sbw, done */
break;
}
type1_cis_get_metrics(pcis, pcxs->sbw);
- return zchar_set_cache(op, pbfont, &cnref,
+ return zchar_set_cache(i_ctx_p, pbfont, &cnref,
NULL, pcxs->sbw + 2,
&pcxs->char_bbox,
bbox_finish_fill, bbox_finish_stroke);
} else {
/* We have the width and bounding box: */
/* set up the cache device now. */
- return zchar_set_cache(op, pbfont, op - 1,
+ return zchar_set_cache(i_ctx_p, pbfont, op - 1,
(pcxs->present ==
metricsSideBearingAndWidth ?
pcxs->sbw : NULL),
@@ -271,21 +289,22 @@ type1exec_bbox(os_ptr op, gs_type1exec_state * pcxs, gs_font * pfont)
/* Continue from an OtherSubr callout while getting metrics. */
private int
-bbox_getsbw_continue(os_ptr op)
+bbox_getsbw_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref other_subr;
gs_type1exec_state *pcxs = r_ptr(esp, gs_type1exec_state);
gs_type1_state *const pcis = &pcxs->cis;
int code;
- code = type1_continue_dispatch(pcxs, NULL, &other_subr, 4);
+ code = type1_continue_dispatch(i_ctx_p, pcxs, NULL, &other_subr, 4);
op = osp; /* in case z1_push/pop_proc was called */
switch (code) {
default: /* code < 0 or done, error */
- op_type1_free(op);
+ op_type1_free(i_ctx_p);
return ((code < 0 ? code : gs_note_error(e_invalidfont)));
case type1_result_callothersubr: /* unknown OtherSubr */
- return type1_push_OtherSubr(pcxs, bbox_getsbw_continue,
+ return type1_push_OtherSubr(i_ctx_p, pcxs, bbox_getsbw_continue,
&other_subr);
case type1_result_sbw: { /* [h]sbw, done */
double sbw[4];
@@ -296,8 +315,8 @@ bbox_getsbw_continue(os_ptr op)
/* Get the metrics before freeing the state. */
type1_cis_get_metrics(pcis, sbw);
bbox = pcxs->char_bbox;
- op_type1_free(op);
- return zchar_set_cache(op, pbfont, op, sbw, sbw + 2, &bbox,
+ op_type1_free(i_ctx_p);
+ return zchar_set_cache(i_ctx_p, pbfont, op, sbw, sbw + 2, &bbox,
bbox_finish_fill, bbox_finish_stroke);
}
}
@@ -305,23 +324,24 @@ bbox_getsbw_continue(os_ptr op)
/* <font> <code|name> <name> <charstring> <sbx> <sby> %bbox_{fill|stroke} - */
/* <font> <code|name> <name> <charstring> %bbox_{fill|stroke} - */
-private int bbox_finish(P2(os_ptr, int (*)(P1(os_ptr))));
+private int bbox_finish(P2(i_ctx_t *, int (*)(P1(i_ctx_t *))));
private int
-bbox_finish_fill(os_ptr op)
+bbox_finish_fill(i_ctx_t *i_ctx_p)
{
- return bbox_finish(op, bbox_fill);
+ return bbox_finish(i_ctx_p, bbox_fill);
}
private int
-bbox_finish_stroke(os_ptr op)
+bbox_finish_stroke(i_ctx_t *i_ctx_p)
{
- return bbox_finish(op, bbox_stroke);
+ return bbox_finish(i_ctx_p, bbox_stroke);
}
private int
-bbox_finish(os_ptr op, int (*cont) (P1(os_ptr)))
+bbox_finish(i_ctx_t *i_ctx_p, int (*cont) (P1(i_ctx_t *)))
{
+ os_ptr op = osp;
gs_font *pfont;
int code;
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
gs_type1exec_state cxs; /* stack allocate to avoid sandbars */
gs_type1_state *const pcis = &cxs.cis;
double sbxy[2];
@@ -345,7 +365,7 @@ bbox_finish(os_ptr op, int (*cont) (P1(os_ptr)))
code = font_param(opc - 3, &pfont);
if (code < 0)
return code;
- if (penum == 0 || !font_is_type1_compatible(pfont))
+ if (penum == 0 || !font_uses_charstrings(pfont))
return_error(e_undefined);
{
gs_font_type1 *const pfont1 = (gs_font_type1 *) pfont;
@@ -362,17 +382,19 @@ bbox_finish(os_ptr op, int (*cont) (P1(os_ptr)))
}
opstr = opc;
icont:
- code = type1_continue_dispatch(&cxs, opstr, &other_subr, (psbpt ? 6 : 4));
+ code = type1_continue_dispatch(i_ctx_p, &cxs, opstr, &other_subr,
+ (psbpt ? 6 : 4));
op = osp; /* OtherSubrs might have altered it */
switch (code) {
case 0: /* all done */
/* Call the continuation now. */
if (psbpt)
pop(2);
- return (*cont)(osp);
+ return (*cont)(i_ctx_p);
case type1_result_callothersubr: /* unknown OtherSubr */
push_op_estack(cont); /* call later */
- return type1_call_OtherSubr(&cxs, bbox_continue, &other_subr);
+ return type1_call_OtherSubr(i_ctx_p, &cxs, bbox_continue,
+ &other_subr);
case type1_result_sbw: /* [h]sbw, just continue */
opstr = 0;
goto icont;
@@ -382,17 +404,18 @@ bbox_finish(os_ptr op, int (*cont) (P1(os_ptr)))
}
private int
-bbox_continue(os_ptr op)
+bbox_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int npop = (r_has_type(op, t_string) ? 4 : 6);
- int code = type1_callout_dispatch(op, bbox_continue, npop);
+ int code = type1_callout_dispatch(i_ctx_p, bbox_continue, npop);
if (code == 0) {
op = osp; /* OtherSubrs might have altered it */
npop -= 4; /* nobbox_fill/stroke handles the rest */
pop(npop);
op -= npop;
- op_type1_free(op);
+ op_type1_free(i_ctx_p);
}
return code;
}
@@ -402,8 +425,9 @@ bbox_continue(os_ptr op)
* of type1execchar are still on the o-stack.
*/
private int
-bbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
+bbox_draw(i_ctx_t *i_ctx_p, int (*draw)(P1(gs_state *)))
{
+ os_ptr op = osp;
gs_rect bbox;
gs_font *pfont;
gs_show_enum *penum;
@@ -413,13 +437,13 @@ bbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
int code;
if (igs->in_cachedevice < 2) /* not caching */
- return nobbox_draw(op, draw);
+ return nobbox_draw(i_ctx_p, draw);
if ((code = gs_pathbbox(igs, &bbox)) < 0 ||
(code = font_param(op - 3, &pfont)) < 0
)
return code;
- penum = op_show_find();
- if (penum == 0 || !font_is_type1_compatible(pfont))
+ penum = op_show_find(i_ctx_p);
+ if (penum == 0 || !font_uses_charstrings(pfont))
return_error(e_undefined);
if (draw == gs_stroke) {
/* Expand the bounding box by the line width. */
@@ -430,7 +454,7 @@ bbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
}
pbfont = (gs_font_base *)pfont;
if (rect_within(bbox, pbfont->FontBBox)) /* within bounds */
- return nobbox_draw(op, draw);
+ return nobbox_draw(i_ctx_p, draw);
/* Enlarge the FontBBox to save work in the future. */
rect_merge(pbfont->FontBBox, bbox);
/* Dismantle everything we've done, and start over. */
@@ -452,18 +476,18 @@ bbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
if (code < 0)
return code;
cxs.char_bbox = pfont1->FontBBox;
- return type1exec_bbox(op, &cxs, pfont);
+ return type1exec_bbox(i_ctx_p, &cxs, pfont);
}
private int
-bbox_fill(os_ptr op)
+bbox_fill(i_ctx_t *i_ctx_p)
{
/* See nobbox_fill for why we use eofill here. */
- return bbox_draw(op, gs_eofill);
+ return bbox_draw(i_ctx_p, gs_eofill);
}
private int
-bbox_stroke(os_ptr op)
+bbox_stroke(i_ctx_t *i_ctx_p)
{
- return bbox_draw(op, gs_stroke);
+ return bbox_draw(i_ctx_p, gs_stroke);
}
/* -------- Common code -------- */
@@ -478,11 +502,11 @@ type1_cis_get_metrics(const gs_type1_state * pcis, double psbw[4])
psbw[3] = fixed2float(pcis->width.y);
}
-/* Handle the results of gs_type1_interpret. */
+/* Handle the results of interpreting the CharString. */
/* pcref points to a t_string ref. */
private int
-type1_continue_dispatch(gs_type1exec_state *pcxs, const ref * pcref,
- ref *pos, int num_args)
+type1_continue_dispatch(i_ctx_t *i_ctx_p, gs_type1exec_state *pcxs,
+ const ref * pcref, ref *pos, int num_args)
{
int value;
int code;
@@ -505,7 +529,7 @@ type1_continue_dispatch(gs_type1exec_state *pcxs, const ref * pcref,
pcxs->num_args = num_args;
memcpy(pcxs->save_args, osp - (num_args - 1), num_args * sizeof(ref));
osp -= num_args;
- code = gs_type1_interpret(&pcxs->cis, pchars, &value);
+ code = pcxs->cis.pfont->data.interpret(&pcxs->cis, pchars, &value);
switch (code) {
case type1_result_callothersubr: {
/*
@@ -530,8 +554,8 @@ type1_continue_dispatch(gs_type1exec_state *pcxs, const ref * pcref,
* the OtherSubr procedure.
*/
private int
-type1_push_OtherSubr(const gs_type1exec_state *pcxs, int (*cont)(P1(os_ptr)),
- const ref *pos)
+type1_push_OtherSubr(i_ctx_t *i_ctx_p, const gs_type1exec_state *pcxs,
+ int (*cont)(P1(i_ctx_t *)), const ref *pos)
{
int i, n = pcxs->num_args;
@@ -554,7 +578,8 @@ type1_push_OtherSubr(const gs_type1exec_state *pcxs, int (*cont)(P1(os_ptr)),
* The caller must have done a check_estack(4 + num_args).
*/
private int
-type1_call_OtherSubr(const gs_type1exec_state * pcxs, int (*cont) (P1(os_ptr)),
+type1_call_OtherSubr(i_ctx_t *i_ctx_p, const gs_type1exec_state * pcxs,
+ int (*cont) (P1(i_ctx_t *)),
const ref * pos)
{
/* Move the Type 1 interpreter state to the heap. */
@@ -565,31 +590,33 @@ type1_call_OtherSubr(const gs_type1exec_state * pcxs, int (*cont) (P1(os_ptr)),
if (hpcxs == 0)
return_error(e_VMerror);
*hpcxs = *pcxs;
+ gs_type1_set_callback_data(&hpcxs->cis, hpcxs);
push_mark_estack(es_show, op_type1_cleanup);
++esp;
make_istruct(esp, 0, hpcxs);
- return type1_push_OtherSubr(pcxs, cont, pos);
+ return type1_push_OtherSubr(i_ctx_p, pcxs, cont, pos);
}
/* Continue from an OtherSubr callout while building the path. */
private int
-type1_callout_dispatch(os_ptr op, int (*cont)(P1(os_ptr)), int num_args)
+type1_callout_dispatch(i_ctx_t *i_ctx_p, int (*cont)(P1(i_ctx_t *)),
+ int num_args)
{
ref other_subr;
gs_type1exec_state *pcxs = r_ptr(esp, gs_type1exec_state);
int code;
icont:
- code = type1_continue_dispatch(pcxs, NULL, &other_subr, num_args);
- op = osp; /* in case z1_push/pop_proc was called */
+ code = type1_continue_dispatch(i_ctx_p, pcxs, NULL, &other_subr,
+ num_args);
switch (code) {
case 0: /* callout done, cont is on e-stack */
return 0;
default: /* code < 0 or done, error */
- op_type1_free(op);
+ op_type1_free(i_ctx_p);
return ((code < 0 ? code : gs_note_error(e_invalidfont)));
case type1_result_callothersubr: /* unknown OtherSubr */
- return type1_push_OtherSubr(pcxs, cont, &other_subr);
+ return type1_push_OtherSubr(i_ctx_p, pcxs, cont, &other_subr);
case type1_result_sbw: /* [h]sbw, just continue */
goto icont;
}
@@ -597,13 +624,13 @@ type1_callout_dispatch(os_ptr op, int (*cont)(P1(os_ptr)), int num_args)
/* Clean up after a Type 1 callout. */
private int
-op_type1_cleanup(os_ptr op)
+op_type1_cleanup(i_ctx_t *i_ctx_p)
{
ifree_object(r_ptr(esp + 2, void), "op_type1_cleanup");
return 0;
}
private void
-op_type1_free(os_ptr op)
+op_type1_free(i_ctx_t *i_ctx_p)
{
ifree_object(r_ptr(esp, void), "op_type1_free");
/*
@@ -619,20 +646,20 @@ op_type1_free(os_ptr op)
/* -------- no-bbox case -------- */
private int
-nobbox_continue(os_ptr op)
+nobbox_continue(i_ctx_t *i_ctx_p)
{
- int code = type1_callout_dispatch(op, nobbox_continue, 4);
+ int code = type1_callout_dispatch(i_ctx_p, nobbox_continue, 4);
if (code)
return code;
{
- gs_type1exec_state cxs;
gs_type1exec_state *pcxs = r_ptr(esp, gs_type1exec_state);
+ gs_type1exec_state cxs;
- op = osp; /* OtherSubrs might have altered it */
cxs = *pcxs;
- op_type1_free(op);
- return nobbox_finish(op, &cxs);
+ gs_type1_set_callback_data(&cxs.cis, &cxs);
+ op_type1_free(i_ctx_p);
+ return nobbox_finish(i_ctx_p, &cxs);
}
}
@@ -640,17 +667,18 @@ nobbox_continue(os_ptr op)
/* If we are oversampling for anti-aliasing, we have to go around again. */
/* <font> <code|name> <name> <charstring> %nobbox_continue - */
private int
-nobbox_finish(os_ptr op, gs_type1exec_state * pcxs)
+nobbox_finish(i_ctx_t *i_ctx_p, gs_type1exec_state * pcxs)
{
+ os_ptr op = osp;
int code;
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
gs_font *pfont;
if ((code = gs_pathbbox(igs, &pcxs->char_bbox)) < 0 ||
(code = font_param(op - 3, &pfont)) < 0
)
return code;
- if (penum == 0 || !font_is_type1_compatible(pfont))
+ if (penum == 0 || !font_uses_charstrings(pfont))
return_error(e_undefined);
{
gs_font_base *const pbfont = (gs_font_base *) pfont;
@@ -677,16 +705,16 @@ nobbox_finish(os_ptr op, gs_type1exec_state * pcxs)
pfont1->PaintType, pfont1);
if (code < 0)
return code;
- return type1exec_bbox(op, pcxs, pfont);
+ return type1exec_bbox(i_ctx_p, pcxs, pfont);
}
- return zchar_set_cache(op, pbfont, op, NULL, pcxs->sbw + 2,
+ return zchar_set_cache(i_ctx_p, pbfont, op, NULL, pcxs->sbw + 2,
&pcxs->char_bbox,
nobbox_fill, nobbox_stroke);
}
}
/* Finish by popping the operands and filling or stroking. */
private int
-nobbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
+nobbox_draw(i_ctx_t *i_ctx_p, int (*draw)(P1(gs_state *)))
{
int code = draw(igs);
@@ -695,7 +723,7 @@ nobbox_draw(os_ptr op, int (*draw)(P1(gs_state *)))
return code;
}
private int
-nobbox_fill(os_ptr op)
+nobbox_fill(i_ctx_t *i_ctx_p)
{
/*
* Properly designed fonts, which have no self-intersecting outlines
@@ -704,12 +732,12 @@ nobbox_fill(os_ptr op)
* badly designed fonts in the Genoa test suite seem to require
* using the even-odd rule to match Adobe interpreters.
*/
- return nobbox_draw(op, gs_eofill);
+ return nobbox_draw(i_ctx_p, gs_eofill);
}
private int
-nobbox_stroke(os_ptr op)
+nobbox_stroke(i_ctx_t *i_ctx_p)
{
- return nobbox_draw(op, gs_stroke);
+ return nobbox_draw(i_ctx_p, gs_stroke);
}
/* ------ Initialization procedure ------ */
@@ -815,8 +843,10 @@ next:
}
private int
-z1_push(gs_font_type1 * ignore, const fixed * pf, int count)
+z1_push(void *callback_data, const fixed * pf, int count)
{
+ gs_type1exec_state *pcxs = callback_data;
+ i_ctx_t *i_ctx_p = pcxs->i_ctx_p;
const fixed *p = pf + count - 1;
int i;
@@ -829,8 +859,10 @@ z1_push(gs_font_type1 * ignore, const fixed * pf, int count)
}
private int
-z1_pop(gs_font_type1 * ignore, fixed * pf)
+z1_pop(void *callback_data, fixed * pf)
{
+ gs_type1exec_state *pcxs = callback_data;
+ i_ctx_t *i_ctx_p = pcxs->i_ctx_p;
double val;
int code = real_param(osp, &val);
diff --git a/gs/src/zchar2.c b/gs/src/zchar2.c
index 790afcfa7..ab98acd55 100644
--- a/gs/src/zchar2.c
+++ b/gs/src/zchar2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,206 +17,27 @@
*/
-/* Level 2 character operators */
+/* Type 2 character display operator */
#include "ghost.h"
#include "oper.h"
-#include "gschar.h"
-#include "gsmatrix.h" /* for gxfont.h */
-#include "gsstruct.h" /* for st_stream */
-#include "gxfixed.h" /* for gxfont.h */
+#include "gxfixed.h"
+#include "gxmatrix.h"
#include "gxfont.h"
-#include "gxchar.h"
-#include "estack.h"
-#include "ialloc.h"
-#include "ichar.h"
-#include "ifont.h"
-#include "igstate.h"
-#include "iname.h"
-#include "store.h"
-#include "stream.h"
-#include "ibnum.h"
-#include "gspath.h" /* gs_rmoveto prototype */
-
-/* Table of continuation procedures. */
-private int xshow_continue(P1(os_ptr));
-private int yshow_continue(P1(os_ptr));
-private int xyshow_continue(P1(os_ptr));
-static const op_proc_p xyshow_continues[4] =
-{
- 0, xshow_continue, yshow_continue, xyshow_continue
-};
-
-/* Forward references */
-private int moveshow(P2(os_ptr, int));
-private int moveshow_continue(P2(os_ptr, int));
-
-/* <charname> glyphshow - */
-private int
-zglyphshow(os_ptr op)
-{
- gs_glyph glyph;
- gs_show_enum *penum;
- int code;
-
- switch (gs_currentfont(igs)->FontType) {
- case ft_CID_encrypted:
- case ft_CID_user_defined:
- case ft_CID_TrueType:
- case ft_CID_bitmap:
- check_int_leu(*op, gs_max_glyph - gs_min_cid_glyph);
- glyph = (gs_glyph) op->value.intval + gs_min_cid_glyph;
- break;
- default:
- check_type(*op, t_name);
- glyph = name_index(op);
- }
- if ((code = op_show_enum_setup(op, &penum)) != 0)
- return code;
- if ((code = gs_glyphshow_init(penum, igs, glyph)) < 0) {
- ifree_object(penum, "op_show_glyph");
- return code;
- }
- op_show_finish_setup(penum, 1, NULL);
- return op_show_continue(op - 1);
-}
-
-/* <string> <numarray|numstring> xshow - */
-private int
-zxshow(os_ptr op)
-{
- return moveshow(op, 1);
-}
-
-/* <string> <numarray|numstring> yshow - */
-private int
-zyshow(os_ptr op)
-{
- return moveshow(op, 2);
-}
-
-/* <string> <numarray|numstring> xyshow - */
-private int
-zxyshow(os_ptr op)
-{
- return moveshow(op, 3);
-}
-
-/* Common code for {x,y,xy}show */
-private int
-moveshow(os_ptr op, int xymask)
-{
- gs_show_enum *penum;
- int code = op_show_setup(op - 1, &penum);
-
- if (code != 0)
- return code;
- if ((code = gs_xyshow_n_init(penum, igs, (char *)op[-1].value.bytes, r_size(op - 1)) < 0)) {
- ifree_object(penum, "op_show_enum_setup");
- return code;
- }
- code = num_array_format(op);
- if (code < 0) {
- ifree_object(penum, "op_show_enum_setup");
- return code;
- }
- op_show_finish_setup(penum, 2, NULL);
- ref_assign(&sslot, op);
- return moveshow_continue(op - 2, xymask);
-}
-
-/* Continuation procedures */
-
-private int
-xshow_continue(os_ptr op)
-{
- return moveshow_continue(op, 1);
-}
-
-private int
-yshow_continue(os_ptr op)
-{
- return moveshow_continue(op, 2);
-}
+#include "gxfont1.h"
+#include "gxtype1.h"
+#include "ichar1.h"
+/* <font> <code|name> <name> <charstring> .type2execchar - */
private int
-xyshow_continue(os_ptr op)
+ztype2execchar(i_ctx_t *i_ctx_p)
{
- return moveshow_continue(op, 3);
-}
-
-/* Get one value from the encoded number string or array. */
-/* Sets pvalue->value.realval. */
-private int
-sget_real(const ref * nsp, int format, uint index, ref * pvalue)
-{
- int code;
-
- switch (code = num_array_get(nsp, format, index, pvalue)) {
- case t_integer:
- pvalue->value.realval = pvalue->value.intval;
- case t_real:
- return t_real;
- case t_null:
- code = gs_note_error(e_rangecheck);
- default:
- return code;
- }
-}
-
-private int
-moveshow_continue(os_ptr op, int xymask)
-{
- const ref *nsp = &sslot;
- int format = num_array_format(nsp);
- int code;
- gs_show_enum *penum = senum;
- uint index = ssindex.value.intval;
-
- for (;;) {
- ref rwx, rwy;
-
- code = gs_show_next(penum);
- if (code != gs_show_move) {
- ssindex.value.intval = index;
- code = op_show_continue_dispatch(op, code);
- if (code == o_push_estack) { /* must be gs_show_render */
- make_op_estack(esp - 1, xyshow_continues[xymask]);
- }
- return code;
- }
- /* Move according to the next value(s) from the stream. */
- if (xymask & 1) {
- code = sget_real(nsp, format, index++, &rwx);
- if (code < 0)
- break;
- } else
- rwx.value.realval = 0;
- if (xymask & 2) {
- code = sget_real(nsp, format, index++, &rwy);
- if (code < 0)
- break;
- } else
- rwy.value.realval = 0;
- code = gs_rmoveto(igs, rwx.value.realval, rwy.value.realval);
- if (code < 0)
- break;
- }
- /* An error occurred. Clean up before returning. */
- return op_show_free(code);
+ return charstring_execchar(i_ctx_p, (1 << (int)ft_encrypted2));
}
/* ------ Initialization procedure ------ */
const op_def zchar2_op_defs[] =
{
- op_def_begin_level2(),
- {"1glyphshow", zglyphshow},
- {"2xshow", zxshow},
- {"2xyshow", zxyshow},
- {"2yshow", zyshow},
- /* Internal operators */
- {"0%xshow_continue", xshow_continue},
- {"0%yshow_continue", yshow_continue},
- {"0%xyshow_continue", xyshow_continue},
+ {"4.type2execchar", ztype2execchar},
op_def_end(0)
};
diff --git a/gs/src/zchar32.c b/gs/src/zchar32.c
index 055fd43ea..bf90d9c6c 100644
--- a/gs/src/zchar32.c
+++ b/gs/src/zchar32.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,9 @@
/* ([wx wy llx lly urx ury] | [w0x w0y llx lly urx ury w1x w1y vx vy]) */
/* <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */
private int
-zmakeglyph32(os_ptr op)
+zmakeglyph32(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
bool long_form;
uint msize;
double metrics[10];
@@ -125,8 +126,9 @@ select_cid_range(cached_char * cc, void *range_ptr)
cc->pair->font == range->font);
}
private int
-zremoveglyphs(os_ptr op)
+zremoveglyphs(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
font_cid_range_t range;
@@ -145,11 +147,12 @@ zremoveglyphs(os_ptr op)
return 0;
}
-/* <str5/14/22> .getmetrics32 <width> <height> <w0x> ... <vy> 5/14 */
-/* <str5/14/22> .getmetrics32 <width> <height> <wx> ... <ury> 22 */
+/* <str5/14/22> .getmetrics32 <width> <height> <wx> ... <ury> 5/14 */
+/* <str5/14/22> .getmetrics32 <width> <height> <w0x> ... <vy> 22 */
private int
-zgetmetrics32(os_ptr op)
+zgetmetrics32(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const byte *data;
uint size;
int i, n = 6;
diff --git a/gs/src/zchar42.c b/gs/src/zchar42.c
index 9c6562424..e23eac752 100644
--- a/gs/src/zchar42.c
+++ b/gs/src/zchar42.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -47,15 +47,16 @@ int gs_type42_get_metrics(P3(gs_font_type42 * pfont, uint glyph_index,
float psbw[4]));
/* <font> <code|name> <name> <glyph_index> .type42execchar - */
-private int type42_fill(P1(os_ptr));
-private int type42_stroke(P1(os_ptr));
+private int type42_fill(P1(i_ctx_t *));
+private int type42_stroke(P1(i_ctx_t *));
private int
-ztype42execchar(register os_ptr op)
+ztype42execchar(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_font *pfont;
int code = font_param(op - 3, &pfont);
gs_font_base *const pbfont = (gs_font_base *) pfont;
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
int present;
double sbw[4];
@@ -80,7 +81,7 @@ ztype42execchar(register os_ptr op)
* Execute the definition of the character.
*/
if (r_is_proc(op))
- return zchar_exec_char_proc(op);
+ return zchar_exec_char_proc(i_ctx_p);
/*
* The definition must be a Type 42 glyph index.
* Note that we do not require read access: this is deliberate.
@@ -106,7 +107,7 @@ ztype42execchar(register os_ptr op)
for (i = 0; i < 4; ++i)
sbw[i] = sbw42[i];
}
- return zchar_set_cache(op, pbfont, op - 1,
+ return zchar_set_cache(i_ctx_p, pbfont, op - 1,
(present == metricsSideBearingAndWidth ?
sbw : NULL),
sbw + 2, &pbfont->FontBBox,
@@ -114,25 +115,27 @@ ztype42execchar(register os_ptr op)
}
/* Continue after a CDevProc callout. */
-private int type42_finish(P2(os_ptr op, int (*cont) (P1(gs_state *))));
+private int type42_finish(P2(i_ctx_t *i_ctx_p,
+ int (*cont)(P1(gs_state *))));
private int
-type42_fill(os_ptr op)
+type42_fill(i_ctx_t *i_ctx_p)
{
- return type42_finish(op, gs_fill);
+ return type42_finish(i_ctx_p, gs_fill);
}
private int
-type42_stroke(os_ptr op)
+type42_stroke(i_ctx_t *i_ctx_p)
{
- return type42_finish(op, gs_stroke);
+ return type42_finish(i_ctx_p, gs_stroke);
}
/* <font> <code|name> <name> <glyph_index> <sbx> <sby> %type42_{fill|stroke} - */
/* <font> <code|name> <name> <glyph_index> %type42_{fill|stroke} - */
private int
-type42_finish(os_ptr op, int (*cont) (P1(gs_state *)))
+type42_finish(i_ctx_t *i_ctx_p, int (*cont) (P1(gs_state *)))
{
+ os_ptr op = osp;
gs_font *pfont;
int code;
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
double sbxy[2];
gs_point sbpt;
gs_point *psbpt = 0;
diff --git a/gs/src/zcharout.c b/gs/src/zcharout.c
index c6080ccc0..924fd74ba 100644
--- a/gs/src/zcharout.c
+++ b/gs/src/zcharout.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,8 +33,8 @@
#include "store.h"
/* Imported operators */
-int zsetcachedevice(P1(os_ptr)); /* zchar.c */
-int zsetcachedevice2(P1(os_ptr)); /* zchar.c */
+int zsetcachedevice(P1(i_ctx_t *)); /* zchar.c */
+int zsetcachedevice2(P1(i_ctx_t *)); /* zchar.c */
/*
* Execute an outline defined by a PostScript procedure.
@@ -42,8 +42,10 @@ int zsetcachedevice2(P1(os_ptr)); /* zchar.c */
* <font> <code|name> <name> <outline_id>
*/
int
-zchar_exec_char_proc(os_ptr op)
-{ /*
+zchar_exec_char_proc(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ /*
* The definition is a PostScript procedure. Execute
* <code|name> proc
* within a systemdict begin/end and a font begin/end.
@@ -123,19 +125,21 @@ zchar_get_metrics(const gs_font_base * pbfont, const ref * pcnref,
* rendering process (only getting the metrics).
*/
int
-zchar_set_cache(os_ptr op, const gs_font_base * pbfont, const ref * pcnref,
- const double psb[2], const double pwidth[2], const gs_rect * pbbox,
- int (*cont_fill)(P1(os_ptr)), int (*cont_stroke)(P1(os_ptr)))
+zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
+ const ref * pcnref, const double psb[2],
+ const double pwidth[2], const gs_rect * pbbox,
+ op_proc_t cont_fill, op_proc_t cont_stroke)
{
+ os_ptr op = osp;
const ref *pfdict = &pfont_data(pbfont)->dict;
ref *pmdict;
ref *pcdevproc;
int have_cdevproc;
ref rpop;
bool metrics2 = false;
- int (*cont) (P1(os_ptr));
+ op_proc_t cont;
double w2[10];
- gs_show_enum *penum = op_show_find();
+ gs_show_enum *penum = op_show_find(i_ctx_p);
w2[0] = pwidth[0], w2[1] = pwidth[1];
@@ -164,8 +168,7 @@ zchar_set_cache(os_ptr op, const gs_font_base * pbfont, const ref * pcnref,
if (dict_find(pmdict, pcnref, &pmvalue) > 0) {
check_read_type_only(*pmvalue, t_array);
if (r_size(pmvalue) == 4) {
- int code = num_params(pmvalue->value.refs + 3,
- 4, w2 + 6);
+ int code = num_params(pmvalue->value.refs + 3, 4, w2 + 6);
if (code < 0)
return code;
@@ -178,7 +181,7 @@ zchar_set_cache(os_ptr op, const gs_font_base * pbfont, const ref * pcnref,
have_cdevproc = dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0;
if (have_cdevproc || gs_show_width_only(penum)) {
int i;
- int (*zsetc) (P1(os_ptr));
+ op_proc_t zsetc;
int nparams;
if (have_cdevproc) {
@@ -231,5 +234,5 @@ zchar_set_cache(os_ptr op, const gs_font_base * pbfont, const ref * pcnref,
make_real(op - 1, psb[0]);
make_real(op, psb[1]);
}
- return cont(op);
+ return cont(i_ctx_p);
}
diff --git a/gs/src/zcharx.c b/gs/src/zcharx.c
new file mode 100644
index 000000000..b20d111c1
--- /dev/null
+++ b/gs/src/zcharx.c
@@ -0,0 +1,224 @@
+/* Copyright (C) 1992, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Level 2 character operators */
+#include "ghost.h"
+#include "oper.h"
+#include "gschar.h"
+#include "gsmatrix.h" /* for gxfont.h */
+#include "gsstruct.h" /* for st_stream */
+#include "gxfixed.h" /* for gxfont.h */
+#include "gxfont.h"
+#include "gxchar.h"
+#include "estack.h"
+#include "ialloc.h"
+#include "ichar.h"
+#include "ifont.h"
+#include "igstate.h"
+#include "iname.h"
+#include "store.h"
+#include "stream.h"
+#include "ibnum.h"
+#include "gspath.h" /* gs_rmoveto prototype */
+
+/* Table of continuation procedures. */
+private int xshow_continue(P1(i_ctx_t *));
+private int yshow_continue(P1(i_ctx_t *));
+private int xyshow_continue(P1(i_ctx_t *));
+static const op_proc_t xyshow_continues[4] = {
+ 0, xshow_continue, yshow_continue, xyshow_continue
+};
+
+/* Forward references */
+private int moveshow(P2(i_ctx_t *, int));
+private int moveshow_continue(P2(i_ctx_t *, int));
+
+/* <charname> glyphshow - */
+private int
+zglyphshow(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gs_glyph glyph;
+ gs_show_enum *penum;
+ int code;
+
+ switch (gs_currentfont(igs)->FontType) {
+ case ft_CID_encrypted:
+ case ft_CID_user_defined:
+ case ft_CID_TrueType:
+ case ft_CID_bitmap:
+ check_int_leu(*op, gs_max_glyph - gs_min_cid_glyph);
+ glyph = (gs_glyph) op->value.intval + gs_min_cid_glyph;
+ break;
+ default:
+ check_type(*op, t_name);
+ glyph = name_index(op);
+ }
+ if ((code = op_show_enum_setup(i_ctx_p, &penum)) != 0)
+ return code;
+ if ((code = gs_glyphshow_init(penum, igs, glyph)) < 0) {
+ ifree_object(penum, "op_show_glyph");
+ return code;
+ }
+ op_show_finish_setup(i_ctx_p, penum, 1, NULL);
+ return op_show_continue_pop(i_ctx_p, 1);
+}
+
+/* <string> <numarray|numstring> xshow - */
+private int
+zxshow(i_ctx_t *i_ctx_p)
+{
+ return moveshow(i_ctx_p, 1);
+}
+
+/* <string> <numarray|numstring> yshow - */
+private int
+zyshow(i_ctx_t *i_ctx_p)
+{
+ return moveshow(i_ctx_p, 2);
+}
+
+/* <string> <numarray|numstring> xyshow - */
+private int
+zxyshow(i_ctx_t *i_ctx_p)
+{
+ return moveshow(i_ctx_p, 3);
+}
+
+/* Common code for {x,y,xy}show */
+private int
+moveshow(i_ctx_t *i_ctx_p, int xymask)
+{
+ os_ptr op = osp;
+ gs_show_enum *penum;
+ int code = op_show_setup(i_ctx_p, op - 1, &penum);
+
+ if (code != 0)
+ return code;
+ if ((code = gs_xyshow_n_init(penum, igs, (char *)op[-1].value.bytes, r_size(op - 1)) < 0)) {
+ ifree_object(penum, "op_show_enum_setup");
+ return code;
+ }
+ code = num_array_format(op);
+ if (code < 0) {
+ ifree_object(penum, "op_show_enum_setup");
+ return code;
+ }
+ op_show_finish_setup(i_ctx_p, penum, 2, NULL);
+ ref_assign(&sslot, op);
+ pop(2);
+ return moveshow_continue(i_ctx_p, xymask);
+}
+
+/* Continuation procedures */
+
+private int
+xshow_continue(i_ctx_t *i_ctx_p)
+{
+ return moveshow_continue(i_ctx_p, 1);
+}
+
+private int
+yshow_continue(i_ctx_t *i_ctx_p)
+{
+ return moveshow_continue(i_ctx_p, 2);
+}
+
+private int
+xyshow_continue(i_ctx_t *i_ctx_p)
+{
+ return moveshow_continue(i_ctx_p, 3);
+}
+
+/* Get one value from the encoded number string or array. */
+/* Sets pvalue->value.realval. */
+private int
+sget_real(const ref * nsp, int format, uint index, ref * pvalue)
+{
+ int code;
+
+ switch (code = num_array_get(nsp, format, index, pvalue)) {
+ case t_integer:
+ pvalue->value.realval = pvalue->value.intval;
+ case t_real:
+ return t_real;
+ case t_null:
+ code = gs_note_error(e_rangecheck);
+ default:
+ return code;
+ }
+}
+
+private int
+moveshow_continue(i_ctx_t *i_ctx_p, int xymask)
+{
+ const ref *nsp = &sslot;
+ int format = num_array_format(nsp);
+ int code;
+ gs_show_enum *penum = senum;
+ uint index = ssindex.value.intval;
+
+ for (;;) {
+ ref rwx, rwy;
+
+ code = gs_show_next(penum);
+ if (code != gs_show_move) {
+ ssindex.value.intval = index;
+ code = op_show_continue_dispatch(i_ctx_p, 0, code);
+ if (code == o_push_estack) { /* must be gs_show_render */
+ make_op_estack(esp - 1, xyshow_continues[xymask]);
+ }
+ return code;
+ }
+ /* Move according to the next value(s) from the stream. */
+ if (xymask & 1) {
+ code = sget_real(nsp, format, index++, &rwx);
+ if (code < 0)
+ break;
+ } else
+ rwx.value.realval = 0;
+ if (xymask & 2) {
+ code = sget_real(nsp, format, index++, &rwy);
+ if (code < 0)
+ break;
+ } else
+ rwy.value.realval = 0;
+ code = gs_rmoveto(igs, rwx.value.realval, rwy.value.realval);
+ if (code < 0)
+ break;
+ }
+ /* An error occurred. Clean up before returning. */
+ return op_show_free(i_ctx_p, code);
+}
+
+/* ------ Initialization procedure ------ */
+
+const op_def zcharx_op_defs[] =
+{
+ op_def_begin_level2(),
+ {"1glyphshow", zglyphshow},
+ {"2xshow", zxshow},
+ {"2xyshow", zxyshow},
+ {"2yshow", zyshow},
+ /* Internal operators */
+ {"0%xshow_continue", xshow_continue},
+ {"0%yshow_continue", yshow_continue},
+ {"0%xyshow_continue", xyshow_continue},
+ op_def_end(0)
+};
diff --git a/gs/src/zcid.c b/gs/src/zcid.c
index 18ae0ec21..2bc33afca 100644
--- a/gs/src/zcid.c
+++ b/gs/src/zcid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,7 +28,7 @@
#include "store.h"
/* Imported from zfont42.c */
-int build_gs_TrueType_font(P5(os_ptr op, font_type ftype,
+int build_gs_TrueType_font(P6(i_ctx_t *i_ctx_p, os_ptr op, font_type ftype,
const char *bcstr, const char *bgstr,
build_font_options_t options));
@@ -36,13 +36,14 @@ int build_gs_TrueType_font(P5(os_ptr op, font_type ftype,
/* Build a type 9 or 10 (CID-keyed) font. */
/* Right now, we treat these like type 3 (with a BuildGlyph procedure). */
private int
-build_gs_cid_font(os_ptr op, font_type ftype, const build_proc_refs * pbuild)
+build_gs_cid_font(i_ctx_t *i_ctx_p, os_ptr op, font_type ftype,
+ const build_proc_refs * pbuild)
{
int code;
gs_font_base *pfont;
check_type(*op, t_dictionary);
- code = build_gs_simple_font(op, &pfont, ftype, &st_gs_font_base,
+ code = build_gs_simple_font(i_ctx_p, op, &pfont, ftype, &st_gs_font_base,
pbuild,
bf_Encoding_optional |
bf_FontBBox_required |
@@ -52,33 +53,36 @@ build_gs_cid_font(os_ptr op, font_type ftype, const build_proc_refs * pbuild)
return define_gs_font((gs_font *) pfont);
}
private int
-zbuildfont9(os_ptr op)
+zbuildfont9(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
build_proc_refs build;
int code = build_proc_name_refs(&build, NULL, "%Type9BuildGlyph");
if (code < 0)
return code;
- return build_gs_cid_font(op, ft_CID_encrypted, &build);
+ return build_gs_cid_font(i_ctx_p, op, ft_CID_encrypted, &build);
}
private int
-zbuildfont10(os_ptr op)
+zbuildfont10(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
build_proc_refs build;
int code = build_gs_font_procs(op, &build);
if (code < 0)
return code;
make_null(&build.BuildChar); /* only BuildGlyph */
- return build_gs_cid_font(op, ft_CID_user_defined, &build);
+ return build_gs_cid_font(i_ctx_p, op, ft_CID_user_defined, &build);
}
/* <string|name> <font_dict> .buildfont11 <string|name> <font> */
private int
-zbuildfont11(os_ptr op)
+zbuildfont11(i_ctx_t *i_ctx_p)
{
- return build_gs_TrueType_font(op, ft_CID_TrueType, (const char *)0,
- "%Type11BuildGlyph",
+ os_ptr op = osp;
+ return build_gs_TrueType_font(i_ctx_p, op, ft_CID_TrueType,
+ (const char *)0, "%Type11BuildGlyph",
bf_Encoding_optional |
bf_FontBBox_required |
bf_UniqueID_ignored |
diff --git a/gs/src/zcie.c b/gs/src/zcie.c
index 7f22ad2d3..f51cb5e5d 100644
--- a/gs/src/zcie.c
+++ b/gs/src/zcie.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,9 +36,6 @@
#include "ivmspace.h"
#include "store.h" /* for make_null */
-/* CIE color dictionaries are so complex that */
-/* we handle the CIE case of setcolorspace separately here. */
-
/* Empty procedures */
static const ref empty_procs[4] =
{
@@ -48,16 +45,6 @@ static const ref empty_procs[4] =
empty_ref_data(t_array, a_readonly | a_executable)
};
-/* Redefined CIE color space installers that load the cache. */
-extern cs_proc_install_cspace(gx_install_CIEDEFG);
-extern cs_proc_install_cspace(gx_install_CIEDEF);
-extern cs_proc_install_cspace(gx_install_CIEABC);
-extern cs_proc_install_cspace(gx_install_CIEA);
-private cs_proc_install_cspace(cs_install_zCIEDEFG);
-private cs_proc_install_cspace(cs_install_zCIEDEF);
-private cs_proc_install_cspace(cs_install_zCIEABC);
-private cs_proc_install_cspace(cs_install_zCIEA);
-
/* ------ Parameter extraction utilities ------ */
/* Get a range array parameter from a dictionary. */
@@ -105,6 +92,31 @@ dict_proc_array_param(const ref * pdict, const char *kstr,
return 0;
}
+/* Get 3 ranges from a dictionary. */
+int
+dict_range3_param(const ref *pdref, const char *kstr, gs_range3 *prange3)
+{
+ return dict_ranges_param(pdref, kstr, 3, prange3->ranges);
+}
+
+/* Get a 3x3 matrix from a dictionary. */
+int
+dict_matrix3_param(const ref *pdref, const char *kstr, gs_matrix3 *pmat3)
+{
+ int code = dict_float_array_param(pdref, kstr, 9, (float *)pmat3,
+ (const float *)&Matrix3_default);
+
+ return (code < 0 ? code : code == 9 ? 0 :
+ gs_note_error(e_rangecheck));
+}
+
+/* Get 3 procedures from a dictionary. */
+int
+dict_proc3_param(const ref *pdref, const char *kstr, ref proc3[3])
+{
+ return dict_proc_array_param(pdref, kstr, 3, proc3);
+}
+
/* Get WhitePoint and BlackPoint values. */
int
cie_points_param(const ref * pdref, gs_cie_wb * pwb)
@@ -170,7 +182,11 @@ cie_table_param(const ref * ptref, gx_color_lookup_table * pclt,
if (table == 0)
return_error(e_VMerror);
psuba = pta[4].value.const_refs;
- for (i = 0; i < d0; ++i) {
+ /*
+ * We know that d0 > 0, so code will always be set in the loop:
+ * we initialize code to 0 here solely to pacify stupid compilers.
+ */
+ for (code = 0, i = 0; i < d0; ++i) {
code = cie_3d_table_param(psuba + i, d1, nbytes, table + d1 * i);
if (code < 0)
break;
@@ -216,10 +232,10 @@ cie_lmnp_param(const ref * pdref, gs_cie_common * pcie, ref_cie_procs * pcprocs)
if ((code = dict_range3_param(pdref, "RangeLMN", &pcie->RangeLMN)) < 0 ||
(code = dict_proc3_param(pdref, "DecodeLMN", &pcprocs->DecodeLMN)) < 0 ||
- (code = dict_matrix3_param(pdref, "MatrixLMN", &pcie->MatrixLMN)) != matrix3_ok ||
+ (code = dict_matrix3_param(pdref, "MatrixLMN", &pcie->MatrixLMN)) < 0 ||
(code = cie_points_param(pdref, &pcie->points)) < 0
)
- return (code < 0 ? code : gs_note_error(e_rangecheck));
+ return code;
pcie->DecodeLMN = DecodeLMN_default;
return 0;
}
@@ -232,47 +248,51 @@ cie_abc_param(const ref * pdref, gs_cie_abc * pcie, ref_cie_procs * pcprocs)
if ((code = dict_range3_param(pdref, "RangeABC", &pcie->RangeABC)) < 0 ||
(code = dict_proc3_param(pdref, "DecodeABC", &pcprocs->Decode.ABC)) < 0 ||
- (code = dict_matrix3_param(pdref, "MatrixABC", &pcie->MatrixABC)) != matrix3_ok ||
+ (code = dict_matrix3_param(pdref, "MatrixABC", &pcie->MatrixABC)) < 0 ||
(code = cie_lmnp_param(pdref, &pcie->common, pcprocs)) < 0
)
- return (code < 0 ? code : gs_note_error(e_rangecheck));
+ return code;
pcie->DecodeABC = DecodeABC_default;
return 0;
}
-/* Finish setting a CIE space. */
+/* Finish setting a CIE space (successful or not). */
private int
-set_cie_finish(os_ptr op, gs_color_space * pcs, const ref_cie_procs * pcprocs)
+set_cie_finish(i_ctx_t *i_ctx_p, gs_color_space * pcs,
+ const ref_cie_procs * pcprocs, int edepth, int code)
{
- ref_colorspace cspace_old;
- uint edepth = ref_stack_count(&e_stack);
- int code;
-
- /* The color space installation procedure may refer to */
- /* istate->colorspace.procs. */
- cspace_old = istate->colorspace;
- istate->colorspace.procs.cie = *pcprocs;
- code = gs_setcolorspace(igs, pcs);
+ if (code >= 0)
+ code = gs_setcolorspace(igs, pcs);
/* Delete the extra reference to the parameter tables. */
gs_cspace_release(pcs);
/* Free the top-level object, which was copied by gs_setcolorspace. */
gs_free_object(gs_state_memory(igs), pcs, "set_cie_finish");
if (code < 0) {
- istate->colorspace = cspace_old;
ref_stack_pop_to(&e_stack, edepth);
return code;
}
+ istate->colorspace.procs.cie = *pcprocs;
pop(1);
- return (ref_stack_count(&e_stack) == edepth ? 0 : o_push_estack); /* installation will load the caches */
+ return (ref_stack_count(&e_stack) == edepth ? 0 : o_push_estack);
}
+/* Forward references */
+private int cache_common(P5(i_ctx_t *, gs_cie_common *, const ref_cie_procs *,
+ void *, gs_ref_memory_t *));
+private int cache_abc_common(P5(i_ctx_t *, gs_cie_abc *, const ref_cie_procs *,
+ void *, gs_ref_memory_t *));
+
/* <dict> .setciedefgspace - */
+private int cie_defg_finish(P1(i_ctx_t *));
private int
-zsetciedefgspace(register os_ptr op)
+zsetciedefgspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ int edepth = ref_stack_count(&e_stack);
gs_memory_t *mem = gs_state_memory(igs);
+ gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
gs_color_space *pcs;
- ref_color_procs procs;
+ ref_cie_procs procs;
gs_cie_defg *pcie;
int code;
ref *ptref;
@@ -284,34 +304,53 @@ zsetciedefgspace(register os_ptr op)
check_read_type(*ptref, t_array);
if (r_size(ptref) != 5)
return_error(e_rangecheck);
- procs = istate->colorspace.procs;
+ procs = istate->colorspace.procs.cie;
code = gs_cspace_build_CIEDEFG(&pcs, NULL, mem);
if (code < 0)
return code;
pcie = pcs->params.defg;
- pcie->common.install_cspace = cs_install_zCIEDEFG;
pcie->Table.n = 4;
pcie->Table.m = 3;
if ((code = dict_ranges_param(op, "RangeDEFG", 4, pcie->RangeDEFG.ranges)) < 0 ||
- (code = dict_proc_array_param(op, "DecodeDEFG", 4, &procs.cie.PreDecode.DEFG)) < 0 ||
+ (code = dict_proc_array_param(op, "DecodeDEFG", 4, &procs.PreDecode.DEFG)) < 0 ||
(code = dict_ranges_param(op, "RangeHIJK", 4, pcie->RangeHIJK.ranges)) < 0 ||
(code = cie_table_param(ptref, &pcie->Table, mem)) < 0 ||
- (code = cie_abc_param(op, (gs_cie_abc *) pcie, &procs.cie)) < 0
- ) {
- gs_cspace_release(pcs);
- gs_free_object(mem, pcs, "setcolorspace(CIEBasedDEFG)");
- return code;
- }
- return set_cie_finish(op, pcs, &procs.cie);
+ (code = cie_abc_param(op, (gs_cie_abc *) pcie, &procs)) < 0 ||
+ (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
+ (code = cie_cache_push_finish(i_ctx_p, cie_defg_finish, imem, pcie)) < 0 ||
+ (code = cie_prepare_cache4(i_ctx_p, &pcie->RangeDEFG,
+ procs.PreDecode.DEFG.value.const_refs,
+ &pcie->caches_defg.DecodeDEFG[0],
+ pcie, imem, "Decode.DEFG")) < 0 ||
+ (code = cache_abc_common(i_ctx_p, (gs_cie_abc *)pcie, &procs, pcie, imem)) < 0
+ )
+ DO_NOTHING;
+ return set_cie_finish(i_ctx_p, pcs, &procs, edepth, code);
+}
+private int
+cie_defg_finish(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gs_cie_defg *pcie = r_ptr(op, gs_cie_defg);
+
+ pcie->DecodeDEFG = DecodeDEFG_from_cache;
+ pcie->common.DecodeLMN = DecodeLMN_from_cache;
+ gs_cie_defg_complete(pcie);
+ pop(1);
+ return 0;
}
/* <dict> .setciedefspace - */
+private int cie_def_finish(P1(i_ctx_t *));
private int
-zsetciedefspace(register os_ptr op)
+zsetciedefspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ int edepth = ref_stack_count(&e_stack);
gs_memory_t *mem = gs_state_memory(igs);
+ gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
gs_color_space *pcs;
- ref_color_procs procs;
+ ref_cie_procs procs;
gs_cie_def *pcie;
int code;
ref *ptref;
@@ -323,226 +362,124 @@ zsetciedefspace(register os_ptr op)
check_read_type(*ptref, t_array);
if (r_size(ptref) != 4)
return_error(e_rangecheck);
- procs = istate->colorspace.procs;
+ procs = istate->colorspace.procs.cie;
code = gs_cspace_build_CIEDEF(&pcs, NULL, mem);
if (code < 0)
return code;
pcie = pcs->params.def;
- pcie->common.install_cspace = cs_install_zCIEDEF;
pcie->Table.n = 3;
pcie->Table.m = 3;
if ((code = dict_range3_param(op, "RangeDEF", &pcie->RangeDEF)) < 0 ||
- (code = dict_proc3_param(op, "DecodeDEF", &procs.cie.PreDecode.DEF)) < 0 ||
+ (code = dict_proc3_param(op, "DecodeDEF", &procs.PreDecode.DEF)) < 0 ||
(code = dict_range3_param(op, "RangeHIJ", &pcie->RangeHIJ)) < 0 ||
(code = cie_table_param(ptref, &pcie->Table, mem)) < 0 ||
- (code = cie_abc_param(op, (gs_cie_abc *) pcie, &procs.cie)) < 0
- ) {
- gs_cspace_release(pcs);
- gs_free_object(mem, pcs, "setcolorspace(CIEBasedDEF)");
- return code;
- }
- return set_cie_finish(op, pcs, &procs.cie);
+ (code = cie_abc_param(op, (gs_cie_abc *) pcie, &procs)) < 0 ||
+ (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
+ (code = cie_cache_push_finish(i_ctx_p, cie_def_finish, imem, pcie)) < 0 ||
+ (code = cie_prepare_cache3(i_ctx_p, &pcie->RangeDEF,
+ procs.PreDecode.DEF.value.const_refs,
+ &pcie->caches_def.DecodeDEF[0],
+ pcie, imem, "Decode.DEF")) < 0 ||
+ (code = cache_abc_common(i_ctx_p, (gs_cie_abc *)pcie, &procs, pcie, imem)) < 0
+ )
+ DO_NOTHING;
+ return set_cie_finish(i_ctx_p, pcs, &procs, edepth, code);
+}
+private int
+cie_def_finish(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gs_cie_def *pcie = r_ptr(op, gs_cie_def);
+
+ pcie->DecodeDEF = DecodeDEF_from_cache;
+ pcie->common.DecodeLMN = DecodeLMN_from_cache;
+ gs_cie_def_complete(pcie);
+ pop(1);
+ return 0;
}
/* <dict> .setcieabcspace - */
+private int cie_abc_finish(P1(i_ctx_t *));
private int
-zsetcieabcspace(register os_ptr op)
+zsetcieabcspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ int edepth = ref_stack_count(&e_stack);
gs_memory_t *mem = gs_state_memory(igs);
+ gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
gs_color_space *pcs;
- ref_color_procs procs;
+ ref_cie_procs procs;
gs_cie_abc *pcie;
int code;
check_type(*op, t_dictionary);
check_dict_read(*op);
- procs = istate->colorspace.procs;
+ procs = istate->colorspace.procs.cie;
code = gs_cspace_build_CIEABC(&pcs, NULL, mem);
if (code < 0)
return code;
pcie = pcs->params.abc;
- pcie->common.install_cspace = cs_install_zCIEABC;
- code = cie_abc_param(op, pcie, &procs.cie);
- if (code < 0) {
- gs_cspace_release(pcs);
- gs_free_object(mem, pcs, "setcolorspace(CIEBasedABC)");
- return code;
- }
- return set_cie_finish(op, pcs, &procs.cie);
+ code = cie_abc_param(op, pcie, &procs);
+ if (code < 0 ||
+ (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
+ (code = cie_cache_push_finish(i_ctx_p, cie_abc_finish, imem, pcie)) < 0 ||
+ (code = cache_abc_common(i_ctx_p, pcie, &procs, pcie, imem)) < 0
+ )
+ DO_NOTHING;
+ return set_cie_finish(i_ctx_p, pcs, &procs, edepth, code);
+}
+private int
+cie_abc_finish(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gs_cie_abc *pcie = r_ptr(op, gs_cie_abc);
+
+ pcie->DecodeABC = DecodeABC_from_cache;
+ pcie->common.DecodeLMN = DecodeLMN_from_cache;
+ gs_cie_abc_complete(pcie);
+ pop(1);
+ return 0;
}
/* <dict> .setcieaspace - */
+private int cie_a_finish(P1(i_ctx_t *));
private int
-zsetcieaspace(register os_ptr op)
+zsetcieaspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ int edepth = ref_stack_count(&e_stack);
gs_memory_t *mem = gs_state_memory(igs);
+ gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
gs_color_space *pcs;
- ref_color_procs procs;
+ ref_cie_procs procs;
gs_cie_a *pcie;
int code;
check_type(*op, t_dictionary);
check_dict_read(*op);
- procs = istate->colorspace.procs;
- if ((code = dict_proc_param(op, "DecodeA", &procs.cie.Decode.A, true)) < 0)
+ procs = istate->colorspace.procs.cie;
+ if ((code = dict_proc_param(op, "DecodeA", &procs.Decode.A, true)) < 0)
return code;
code = gs_cspace_build_CIEA(&pcs, NULL, mem);
if (code < 0)
return code;
pcie = pcs->params.a;
- pcie->common.install_cspace = cs_install_zCIEA;
if ((code = dict_float_array_param(op, "RangeA", 2, (float *)&pcie->RangeA, (const float *)&RangeA_default)) != 2 ||
(code = dict_float_array_param(op, "MatrixA", 3, (float *)&pcie->MatrixA, (const float *)&MatrixA_default)) != 3 ||
- (code = cie_lmnp_param(op, &pcie->common, &procs.cie)) < 0
- ) {
- gs_cspace_release(pcs);
- gs_free_object(mem, pcs, "setcolorspace(CIEBasedA)");
- return code;
- }
+ (code = cie_lmnp_param(op, &pcie->common, &procs)) < 0 ||
+ (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
+ (code = cie_cache_push_finish(i_ctx_p, cie_a_finish, imem, pcie)) < 0 ||
+ (code = cie_prepare_cache(i_ctx_p, &pcie->RangeA, &procs.Decode.A, &pcie->caches.DecodeA.floats, pcie, imem, "Decode.A")) < 0 ||
+ (code = cache_common(i_ctx_p, &pcie->common, &procs, pcie, imem)) < 0
+ )
+ DO_NOTHING;
pcie->DecodeA = DecodeA_default;
- return set_cie_finish(op, pcs, &procs.cie);
-}
-
-/* ------ Install a CIE-based color space. ------ */
-
-/* Forward references */
-private int cache_common(P4(gs_cie_common *, const ref_cie_procs *,
- void *, gs_ref_memory_t *));
-private int cache_abc_common(P4(gs_cie_abc *, const ref_cie_procs *,
- void *, gs_ref_memory_t *));
-
-private int cie_defg_finish(P1(os_ptr));
-private int
-cs_install_zCIEDEFG(gs_color_space * pcs, gs_state * pgs)
-{
- es_ptr ep = esp;
- gs_cie_defg *pcie = pcs->params.defg;
- gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
- const int_gstate *pigs = gs_int_gstate(pgs);
- const ref_cie_procs *pcprocs = &pigs->colorspace.procs.cie;
- int code = gx_install_CIEDEFG(pcs, pgs); /* base routine */
-
- if (code < 0 ||
- (code = cie_cache_joint(&pigs->colorrendering.procs, pgs)) < 0 || /* do this last */
- (code = cie_cache_push_finish(cie_defg_finish, imem, pcie)) < 0 ||
- (code = cie_prepare_cache4(&pcie->RangeDEFG,
- pcprocs->PreDecode.DEFG.value.const_refs,
- &pcie->caches_defg.DecodeDEFG[0],
- pcie, imem, "Decode.DEFG")) < 0 ||
- (code = cache_abc_common((gs_cie_abc *)pcie, pcprocs, pcie, imem)) < 0
- ) {
- esp = ep;
- return code;
- }
- return o_push_estack;
-}
-private int
-cie_defg_finish(os_ptr op)
-{
- gs_cie_defg *pcie = r_ptr(op, gs_cie_defg);
-
- pcie->DecodeDEFG = DecodeDEFG_from_cache;
- pcie->common.DecodeLMN = DecodeLMN_from_cache;
- gs_cie_defg_complete(pcie);
- pop(1);
- return 0;
-}
-
-private int cie_def_finish(P1(os_ptr));
-private int
-cs_install_zCIEDEF(gs_color_space * pcs, gs_state * pgs)
-{
- es_ptr ep = esp;
- gs_cie_def *pcie = pcs->params.def;
- gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
- const int_gstate *pigs = gs_int_gstate(pgs);
- const ref_cie_procs *pcprocs = &pigs->colorspace.procs.cie;
- int code = gx_install_CIEDEF(pcs, pgs); /* base routine */
-
- if (code < 0 ||
- (code = cie_cache_joint(&pigs->colorrendering.procs, pgs)) < 0 || /* do this last */
- (code = cie_cache_push_finish(cie_def_finish, imem, pcie)) < 0 ||
- (code = cie_prepare_cache3(&pcie->RangeDEF,
- pcprocs->PreDecode.DEF.value.const_refs,
- &pcie->caches_def.DecodeDEF[0],
- pcie, imem, "Decode.DEF")) < 0 ||
- (code = cache_abc_common((gs_cie_abc *)pcie, pcprocs, pcie, imem)) < 0
- ) {
- esp = ep;
- return code;
- }
- return o_push_estack;
-}
-private int
-cie_def_finish(os_ptr op)
-{
- gs_cie_def *pcie = r_ptr(op, gs_cie_def);
-
- pcie->DecodeDEF = DecodeDEF_from_cache;
- pcie->common.DecodeLMN = DecodeLMN_from_cache;
- gs_cie_def_complete(pcie);
- pop(1);
- return 0;
-}
-
-private int cie_abc_finish(P1(os_ptr));
-private int
-cs_install_zCIEABC(gs_color_space * pcs, gs_state * pgs)
-{
- es_ptr ep = esp;
- gs_cie_abc *pcie = pcs->params.abc;
- gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
- const int_gstate *pigs = gs_int_gstate(pgs);
- const ref_cie_procs *pcprocs = &pigs->colorspace.procs.cie;
- int code = gx_install_CIEABC(pcs, pgs); /* base routine */
-
- if (code < 0 ||
- (code = cie_cache_joint(&pigs->colorrendering.procs, pgs)) < 0 || /* do this last */
- (code = cie_cache_push_finish(cie_abc_finish, imem, pcie)) < 0 ||
- (code = cache_abc_common(pcie, pcprocs, pcie, imem)) < 0
- ) {
- esp = ep;
- return code;
- }
- return o_push_estack;
-}
-private int
-cie_abc_finish(os_ptr op)
-{
- gs_cie_abc *pcie = r_ptr(op, gs_cie_abc);
-
- pcie->DecodeABC = DecodeABC_from_cache;
- pcie->common.DecodeLMN = DecodeLMN_from_cache;
- gs_cie_abc_complete(pcie);
- pop(1);
- return 0;
-}
-
-private int cie_a_finish(P1(os_ptr));
-private int
-cs_install_zCIEA(gs_color_space * pcs, gs_state * pgs)
-{
- es_ptr ep = esp;
- gs_cie_a *pcie = pcs->params.a;
- gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
- const int_gstate *pigs = gs_int_gstate(pgs);
- const ref_cie_procs *pcprocs = &pigs->colorspace.procs.cie;
- int code = gx_install_CIEA(pcs, pgs); /* base routine */
-
- if (code < 0 ||
- (code = cie_cache_joint(&pigs->colorrendering.procs, pgs)) < 0 || /* do this last */
- (code = cie_cache_push_finish(cie_a_finish, imem, pcie)) < 0 ||
- (code = cie_prepare_cache(&pcie->RangeA, &pcprocs->Decode.A, &pcie->caches.DecodeA.floats, pcie, imem, "Decode.A")) < 0 ||
- (code = cache_common(&pcie->common, pcprocs, pcie, imem)) < 0
- ) {
- esp = ep;
- return code;
- }
- return o_push_estack;
+ return set_cie_finish(i_ctx_p, pcs, &procs, edepth, code);
}
private int
-cie_a_finish(os_ptr op)
+cie_a_finish(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_cie_a *pcie = r_ptr(op, gs_cie_a);
pcie->DecodeA = DecodeA_from_cache;
@@ -555,24 +492,26 @@ cie_a_finish(os_ptr op)
/* Common cache code */
private int
-cache_abc_common(gs_cie_abc * pcie, const ref_cie_procs * pcprocs,
+cache_abc_common(i_ctx_t *i_ctx_p, gs_cie_abc * pcie,
+ const ref_cie_procs * pcprocs,
void *container, gs_ref_memory_t * imem)
{
int code =
- cie_prepare_cache3(&pcie->RangeABC,
+ cie_prepare_cache3(i_ctx_p, &pcie->RangeABC,
pcprocs->Decode.ABC.value.const_refs,
&pcie->caches.DecodeABC[0], pcie, imem,
"Decode.ABC");
return (code < 0 ? code :
- cache_common(&pcie->common, pcprocs, pcie, imem));
+ cache_common(i_ctx_p, &pcie->common, pcprocs, pcie, imem));
}
private int
-cache_common(gs_cie_common * pcie, const ref_cie_procs * pcprocs,
+cache_common(i_ctx_t *i_ctx_p, gs_cie_common * pcie,
+ const ref_cie_procs * pcprocs,
void *container, gs_ref_memory_t * imem)
{
- return cie_prepare_cache3(&pcie->RangeLMN,
+ return cie_prepare_cache3(i_ctx_p, &pcie->RangeLMN,
pcprocs->DecodeLMN.value.const_refs,
&pcie->caches.DecodeLMN[0], container, imem,
"Decode.LMN");
@@ -581,10 +520,10 @@ cache_common(gs_cie_common * pcie, const ref_cie_procs * pcprocs,
/* ------ Internal routines ------ */
/* Prepare to cache the values for one or more procedures. */
-private int cie_cache_finish1(P1(os_ptr));
-private int cie_cache_finish(P1(os_ptr));
+private int cie_cache_finish1(P1(i_ctx_t *));
+private int cie_cache_finish(P1(i_ctx_t *));
int
-cie_prepare_cache(const gs_range * domain, const ref * proc,
+cie_prepare_cache(i_ctx_t *i_ctx_p, const gs_range * domain, const ref * proc,
cie_cache_floats * pcache, void *container,
gs_ref_memory_t * imem, client_name_t cname)
{
@@ -630,7 +569,8 @@ cie_prepare_cache(const gs_range * domain, const ref * proc,
}
/* Note that pc3 may be 0, indicating that there are only 3 caches to load. */
int
-cie_prepare_caches_4(const gs_range * domains, const ref * procs,
+cie_prepare_caches_4(i_ctx_t *i_ctx_p, const gs_range * domains,
+ const ref * procs,
cie_cache_floats * pc0, cie_cache_floats * pc1,
cie_cache_floats * pc2, cie_cache_floats * pc3,
void *container,
@@ -645,15 +585,16 @@ cie_prepare_caches_4(const gs_range * domains, const ref * procs,
else
pcn[3] = pc3, n = 4;
for (i = 0; i < n && code >= 0; ++i)
- code = cie_prepare_cache(domains + i, procs + i, pcn[i],
+ code = cie_prepare_cache(i_ctx_p, domains + i, procs + i, pcn[i],
container, imem, cname);
return code;
}
/* Store the result of caching one procedure. */
private int
-cie_cache_finish_store(os_ptr op, bool replicate)
+cie_cache_finish_store(i_ctx_t *i_ctx_p, bool replicate)
{
+ os_ptr op = osp;
cie_cache_floats *pcache;
int code;
@@ -694,21 +635,21 @@ cie_cache_finish_store(os_ptr op, bool replicate)
return o_pop_estack;
}
private int
-cie_cache_finish(os_ptr op)
+cie_cache_finish(i_ctx_t *i_ctx_p)
{
- return cie_cache_finish_store(op, false);
+ return cie_cache_finish_store(i_ctx_p, false);
}
private int
-cie_cache_finish1(os_ptr op)
+cie_cache_finish1(i_ctx_t *i_ctx_p)
{
- return cie_cache_finish_store(op, true);
+ return cie_cache_finish_store(i_ctx_p, true);
}
/* Push a finishing procedure on the e-stack. */
/* ptr will be the top element of the o-stack. */
int
-cie_cache_push_finish(int (*finish_proc) (P1(os_ptr)), gs_ref_memory_t * imem,
- void *data)
+cie_cache_push_finish(i_ctx_t *i_ctx_p, op_proc_t finish_proc,
+ gs_ref_memory_t * imem, void *data)
{
check_estack(2);
push_op_estack(finish_proc);
diff --git a/gs/src/zcolor.c b/gs/src/zcolor.c
index d6b85e1ef..745f73a18 100644
--- a/gs/src/zcolor.c
+++ b/gs/src/zcolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,7 +34,7 @@
/* Import the 'for' operator */
extern int
- zfor_fraction(P1(os_ptr));
+ zfor_fraction(P1(i_ctx_t *));
/* Imported from gsht.c */
void gx_set_effective_transfer(P1(gs_state *));
@@ -45,8 +45,10 @@ const int zcolor_remap_one_estack = 3;
/* - currentgray <gray> */
private int
-zcurrentgray(register os_ptr op)
+zcurrentgray(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentgray(igs));
return 0;
@@ -54,8 +56,9 @@ zcurrentgray(register os_ptr op)
/* - currentrgbcolor <red> <green> <blue> */
private int
-zcurrentrgbcolor(register os_ptr op)
+zcurrentrgbcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
float par[3];
gs_currentrgbcolor(igs, par);
@@ -66,8 +69,10 @@ zcurrentrgbcolor(register os_ptr op)
/* - currenttransfer <proc> */
private int
-zcurrenttransfer(register os_ptr op)
+zcurrenttransfer(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = istate->transfer_procs.colored.gray;
return 0;
@@ -77,8 +82,10 @@ zcurrenttransfer(register os_ptr op)
/* Note: this is an undocumented operator that is not supported */
/* in Level 2. */
private int
-zprocesscolors(register os_ptr op)
+zprocesscolors(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, gs_currentdevice(igs)->color_info.num_components);
return 0;
@@ -86,8 +93,9 @@ zprocesscolors(register os_ptr op)
/* <gray> setgray - */
private int
-zsetgray(register os_ptr op)
+zsetgray(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double gray;
int code;
@@ -102,8 +110,9 @@ zsetgray(register os_ptr op)
/* <red> <green> <blue> setrgbcolor - */
private int
-zsetrgbcolor(register os_ptr op)
+zsetrgbcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double par[3];
int code;
@@ -118,8 +127,9 @@ zsetrgbcolor(register os_ptr op)
/* <proc> settransfer - */
private int
-zsettransfer(register os_ptr op)
+zsettransfer(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_proc(*op);
@@ -134,8 +144,7 @@ zsettransfer(register os_ptr op)
return code;
push_op_estack(zcolor_reset_transfer);
pop(1);
- op--;
- return zcolor_remap_one(&istate->transfer_procs.colored.gray, op,
+ return zcolor_remap_one(i_ctx_p, &istate->transfer_procs.colored.gray,
igs->set_transfer.colored.gray, igs,
zcolor_remap_one_finish);
}
@@ -147,10 +156,21 @@ zsettransfer(register os_ptr op)
/* Use the 'for' operator to gather the values. */
/* The caller must have done the necessary check_ostack and check_estack. */
int
-zcolor_remap_one(const ref * pproc, register os_ptr op, gx_transfer_map * pmap,
- const gs_state * pgs, int (*finish_proc)(P1(os_ptr)))
+zcolor_remap_one(i_ctx_t *i_ctx_p, const ref * pproc,
+ gx_transfer_map * pmap, const gs_state * pgs,
+ op_proc_t finish_proc)
{
- osp = op += 4;
+ os_ptr op;
+
+ /*
+ * Detect the identity function, which is a common value for one or
+ * more of these functions.
+ */
+ if (r_size(pproc) == 0) {
+ pmap->proc = gs_identity_transfer;
+ return 0;
+ }
+ op = osp += 4;
make_int(op - 3, 0);
make_int(op - 2, 1);
make_int(op - 1, transfer_map_size - 1);
@@ -165,7 +185,7 @@ zcolor_remap_one(const ref * pproc, register os_ptr op, gx_transfer_map * pmap,
/* Store the result of remapping a component. */
private int
-zcolor_remap_one_store(os_ptr op, floatp min_value)
+zcolor_remap_one_store(i_ctx_t *i_ctx_p, floatp min_value)
{
int i;
gx_transfer_map *pmap = r_ptr(esp, gx_transfer_map);
@@ -190,26 +210,26 @@ zcolor_remap_one_store(os_ptr op, floatp min_value)
return o_pop_estack;
}
int
-zcolor_remap_one_finish(os_ptr op)
+zcolor_remap_one_finish(i_ctx_t *i_ctx_p)
{
- return zcolor_remap_one_store(op, 0.0);
+ return zcolor_remap_one_store(i_ctx_p, 0.0);
}
int
-zcolor_remap_one_signed_finish(os_ptr op)
+zcolor_remap_one_signed_finish(i_ctx_t *i_ctx_p)
{
- return zcolor_remap_one_store(op, -1.0);
+ return zcolor_remap_one_store(i_ctx_p, -1.0);
}
/* Finally, reset the effective transfer functions and */
/* invalidate the current color. */
int
-zcolor_reset_transfer(os_ptr op)
+zcolor_reset_transfer(i_ctx_t *i_ctx_p)
{
gx_set_effective_transfer(igs);
- return zcolor_remap_color(op);
+ return zcolor_remap_color(i_ctx_p);
}
int
-zcolor_remap_color(os_ptr op)
+zcolor_remap_color(i_ctx_t *i_ctx_p)
{
gx_unset_dev_color(igs);
return 0;
diff --git a/gs/src/zcolor1.c b/gs/src/zcolor1.c
index d1c931576..7aed55910 100644
--- a/gs/src/zcolor1.c
+++ b/gs/src/zcolor1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,14 +31,17 @@
#include "gxdevice.h"
#include "gxcmap.h"
#include "gscolor1.h"
+#include "gscssub.h"
#include "gxcspace.h"
#include "icolor.h"
#include "iimage.h"
/* - currentblackgeneration <proc> */
private int
-zcurrentblackgeneration(register os_ptr op)
+zcurrentblackgeneration(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = istate->black_generation;
return 0;
@@ -46,8 +49,9 @@ zcurrentblackgeneration(register os_ptr op)
/* - currentcmykcolor <cyan> <magenta> <yellow> <black> */
private int
-zcurrentcmykcolor(register os_ptr op)
+zcurrentcmykcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
float par[4];
gs_currentcmykcolor(igs, par);
@@ -58,8 +62,10 @@ zcurrentcmykcolor(register os_ptr op)
/* - currentcolortransfer <redproc> <greenproc> <blueproc> <grayproc> */
private int
-zcurrentcolortransfer(register os_ptr op)
+zcurrentcolortransfer(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(4);
op[-3] = istate->transfer_procs.colored.red;
op[-2] = istate->transfer_procs.colored.green;
@@ -70,8 +76,10 @@ zcurrentcolortransfer(register os_ptr op)
/* - currentundercolorremoval <proc> */
private int
-zcurrentundercolorremoval(register os_ptr op)
+zcurrentundercolorremoval(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = istate->undercolor_removal;
return 0;
@@ -79,8 +87,9 @@ zcurrentundercolorremoval(register os_ptr op)
/* <proc> setblackgeneration - */
private int
-zsetblackgeneration(register os_ptr op)
+zsetblackgeneration(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_proc(*op);
@@ -91,17 +100,17 @@ zsetblackgeneration(register os_ptr op)
return code;
istate->black_generation = *op;
pop(1);
- op--;
push_op_estack(zcolor_remap_color);
- return zcolor_remap_one(&istate->black_generation, op,
+ return zcolor_remap_one(i_ctx_p, &istate->black_generation,
igs->black_generation, igs,
zcolor_remap_one_finish);
}
/* <cyan> <magenta> <yellow> <black> setcmykcolor - */
private int
-zsetcmykcolor(register os_ptr op)
+zsetcmykcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double par[4];
int code;
@@ -116,8 +125,9 @@ zsetcmykcolor(register os_ptr op)
/* <redproc> <greenproc> <blueproc> <grayproc> setcolortransfer - */
private int
-zsetcolortransfer(register os_ptr op)
+zsetcolortransfer(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_proc(op[-3]);
@@ -138,28 +148,32 @@ zsetcolortransfer(register os_ptr op)
return code;
/* Use osp rather than op here, because zcolor_remap_one pushes. */
pop(4);
- op -= 4;
push_op_estack(zcolor_reset_transfer);
- if ((code = zcolor_remap_one(&istate->transfer_procs.colored.red,
- osp, igs->set_transfer.colored.red, igs,
+ if ((code = zcolor_remap_one(i_ctx_p,
+ &istate->transfer_procs.colored.red,
+ igs->set_transfer.colored.red, igs,
zcolor_remap_one_finish)) < 0 ||
- (code = zcolor_remap_one(&istate->transfer_procs.colored.green,
- osp, igs->set_transfer.colored.green, igs,
+ (code = zcolor_remap_one(i_ctx_p,
+ &istate->transfer_procs.colored.green,
+ igs->set_transfer.colored.green, igs,
zcolor_remap_one_finish)) < 0 ||
- (code = zcolor_remap_one(&istate->transfer_procs.colored.blue,
- osp, igs->set_transfer.colored.blue, igs,
+ (code = zcolor_remap_one(i_ctx_p,
+ &istate->transfer_procs.colored.blue,
+ igs->set_transfer.colored.blue, igs,
+ zcolor_remap_one_finish)) < 0 ||
+ (code = zcolor_remap_one(i_ctx_p, &istate->transfer_procs.colored.gray,
+ igs->set_transfer.colored.gray, igs,
zcolor_remap_one_finish)) < 0
)
return code;
- return zcolor_remap_one(&istate->transfer_procs.colored.gray,
- osp, igs->set_transfer.colored.gray, igs,
- zcolor_remap_one_finish);
+ return o_push_estack;
}
/* <proc> setundercolorremoval - */
private int
-zsetundercolorremoval(register os_ptr op)
+zsetundercolorremoval(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_proc(*op);
@@ -170,9 +184,8 @@ zsetundercolorremoval(register os_ptr op)
return code;
istate->undercolor_removal = *op;
pop(1);
- op--;
push_op_estack(zcolor_remap_color);
- return zcolor_remap_one(&istate->undercolor_removal, op,
+ return zcolor_remap_one(i_ctx_p, &istate->undercolor_removal,
igs->undercolor_removal, igs,
zcolor_remap_one_signed_finish);
}
@@ -180,16 +193,17 @@ zsetundercolorremoval(register os_ptr op)
/* <width> <height> <bits/comp> <matrix> */
/* <datasrc_0> ... <datasrc_ncomp-1> true <ncomp> colorimage - */
/* <datasrc> false <ncomp> colorimage - */
-int zimage_multiple(P2(os_ptr op, bool has_alpha));
+int zimage_multiple(P2(i_ctx_t *i_ctx_p, bool has_alpha));
private int
-zcolorimage(register os_ptr op)
+zcolorimage(i_ctx_t *i_ctx_p)
{
- return zimage_multiple(op, false);
+ return zimage_multiple(i_ctx_p, false);
}
/* We export zimage_multiple for alphaimage. */
int
-zimage_multiple(os_ptr op, bool has_alpha)
+zimage_multiple(i_ctx_t *i_ctx_p, bool has_alpha)
{
+ os_ptr op = osp;
int spp; /* samples per pixel */
int npop = 7;
os_ptr procp = op - 2;
@@ -200,13 +214,13 @@ zimage_multiple(os_ptr op, bool has_alpha)
check_type(op[-1], t_boolean); /* multiproc */
switch ((spp = (int)(op->value.intval))) {
case 1:
- pcs = gs_cspace_DeviceGray((const gs_imager_state *)igs);
+ pcs = gs_current_DeviceGray_space(igs);
break;
case 3:
- pcs = gs_cspace_DeviceRGB((const gs_imager_state *)igs);
+ pcs = gs_current_DeviceRGB_space(igs);
goto color;
case 4:
- pcs = gs_cspace_DeviceCMYK((const gs_imager_state *)igs);
+ pcs = gs_current_DeviceCMYK_space(igs);
color:
if (op[-1].value.boolval) { /* planar format */
if (has_alpha)
@@ -219,7 +233,7 @@ color:
default:
return_error(e_rangecheck);
}
- return zimage_opaque_setup(procp, multi,
+ return zimage_opaque_setup(i_ctx_p, procp, multi,
(has_alpha ? gs_image_alpha_last : gs_image_alpha_none),
pcs, npop);
}
diff --git a/gs/src/zcolor2.c b/gs/src/zcolor2.c
index 0c4f514cc..4919e7e76 100644
--- a/gs/src/zcolor2.c
+++ b/gs/src/zcolor2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "ghost.h"
#include "oper.h"
#include "gscolor.h"
+#include "gscssub.h"
#include "gsmatrix.h"
#include "gsstruct.h"
#include "gxcspace.h"
@@ -38,29 +39,34 @@
#include "igstate.h"
#include "store.h"
-/* Declare a local alias for st_pattern_instance. */
-/* We do this so we can have configurations with */
-/* the base Level 2 color machinery but without patterns. */
-gs_memory_type_ptr_t zcolor2_st_pattern_instance_p = 0;
-
/* Forward references */
private int store_color_params(P3(os_ptr, const gs_paint_color *,
const gs_color_space *));
private int load_color_params(P3(os_ptr, gs_paint_color *,
const gs_color_space *));
+/* Test whether a Pattern instance uses a base space. */
+inline private bool
+pattern_instance_uses_base_space(const gs_pattern_instance_t *pinst)
+{
+ return pinst->type->procs.uses_base_space(pinst->type->procs.get_pattern(pinst));
+}
+
/* - currentcolor <param1> ... <paramN> */
private int
-zcurrentcolor(register os_ptr op)
+zcurrentcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gs_client_color *pc = gs_currentcolor(igs);
const gs_color_space *pcs = gs_currentcolorspace(igs);
int n;
check_ostack(5); /* Worst case: CMYK + pattern */
if (pcs->type->index == gs_color_space_index_Pattern) {
+ gs_pattern_instance_t *pinst = pc->pattern;
+
n = 1;
- if (pc->pattern != 0 && pc->pattern->template.PaintType == 2) /* uncolored */
+ if (pinst != 0 && pattern_instance_uses_base_space(pinst)) /* uncolored */
n += store_color_params(op, &pc->paint,
(const gs_color_space *)&pcs->params.pattern.base_space);
op[n] = istate->pattern;
@@ -72,28 +78,33 @@ zcurrentcolor(register os_ptr op)
/* - .currentcolorspace <array|int> */
private int
-zcurrentcolorspace(register os_ptr op)
+zcurrentcolorspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
- if (r_has_type(&istate->colorspace.array, t_null)) {
+ *op = istate->colorspace.array;
+ if (r_has_type(op, t_null)) {
/*
* Return the color space index. This is only possible
* for the parameterless color spaces.
*/
- make_int(op, (int)(gs_currentcolorspace(igs)->type->index));
- } else
- *op = istate->colorspace.array;
+ gs_color_space_index csi = gs_currentcolorspace_index(igs);
+
+ make_int(op, (int)(csi));
+ }
return 0;
}
/* <param1> ... <paramN> setcolor - */
private int
-zsetcolor(register os_ptr op)
+zsetcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_client_color c;
const gs_color_space *pcs = gs_currentcolorspace(igs);
int n, code;
- gs_pattern_instance *pinst = 0;
+ gs_pattern_instance_t *pinst = 0;
if (pcs->type->index == gs_color_space_index_Pattern) {
/* Make sure *op is a real Pattern. */
@@ -101,13 +112,19 @@ zsetcolor(register os_ptr op)
check_type(*op, t_dictionary);
check_dict_read(*op);
+ /*
+ * We have no way to check for a subclass of st_pattern_instance,
+ * so just make sure the structure is large enough.
+ */
if (dict_find_string(op, "Implementation", &pImpl) <= 0 ||
- !r_has_stype(pImpl, imemory, *zcolor2_st_pattern_instance_p)
+ !r_is_struct(pImpl) ||
+ gs_object_size(imemory, r_ptr(pImpl, const void)) <
+ sizeof(gs_pattern_instance_t)
)
return_error(e_rangecheck);
- pinst = r_ptr(pImpl, gs_pattern_instance);
+ pinst = r_ptr(pImpl, gs_pattern_instance_t);
c.pattern = pinst;
- if (pinst->template.PaintType == 2) { /* uncolored */
+ if (pattern_instance_uses_base_space(pinst)) { /* uncolored */
if (!pcs->params.pattern.has_base_space)
return_error(e_rangecheck);
n = load_color_params(op - 1, &c.paint,
@@ -134,8 +151,10 @@ zsetcolor(register os_ptr op)
/* <array> .setcolorspace - */
private int
-zsetcolorspace(register os_ptr op)
+zsetcolorspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_array);
istate->colorspace.array = *op;
pop(1);
diff --git a/gs/src/zcontext.c b/gs/src/zcontext.c
index 9bbbca840..f12374128 100644
--- a/gs/src/zcontext.c
+++ b/gs/src/zcontext.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -48,13 +48,10 @@
private int reschedule_interval = 100;
/* Scheduling hooks in interp.c */
-extern int (*gs_interp_reschedule_proc)(P0());
-extern int (*gs_interp_time_slice_proc)(P0());
+extern int (*gs_interp_reschedule_proc)(P1(i_ctx_t **));
+extern int (*gs_interp_time_slice_proc)(P1(i_ctx_t **));
extern int gs_interp_time_slice_ticks;
-/* Per-context state stored in statics */
-extern ref ref_binary_object_format;
-
/* Context structure */
typedef enum {
cs_active,
@@ -178,13 +175,13 @@ private RELOC_PTRS_BEGIN(scheduler_reloc_ptrs)
RELOC_PTRS_END
/* Forward references */
-private int context_create(P4(gs_scheduler_t *, gs_context **,
+private int context_create(P5(gs_scheduler_t *, gs_context **,
const gs_dual_memory_t *,
- const gs_context_state_t *));
+ const gs_context_state_t *, bool));
private long context_usertime(P0());
private int context_param(P3(const gs_scheduler_t *, os_ptr, gs_context **));
private void context_destroy(P1(gs_context *));
-private void stack_copy(P4(ref_stack *, const ref_stack *, uint, uint));
+private void stack_copy(P4(ref_stack_t *, const ref_stack_t *, uint, uint));
private int lock_acquire(P2(os_ptr, gs_context *));
private int lock_release(P1(ref *));
@@ -221,10 +218,24 @@ add_last(ctx_list *pl, gs_context *pc)
/* ------ Initialization ------ */
-private int ctx_reschedule(P0());
-private int ctx_time_slice(P0());
-private void
-zcontext_init(void)
+private int ctx_initialize(P1(i_ctx_t **));
+private int ctx_reschedule(P1(i_ctx_t **));
+private int ctx_time_slice(P1(i_ctx_t **));
+private int
+zcontext_init(i_ctx_t *i_ctx_p)
+{
+ /* Complete initialization after the interpreter is entered. */
+ gs_interp_reschedule_proc = ctx_initialize;
+ gs_interp_time_slice_proc = ctx_initialize;
+ gs_interp_time_slice_ticks = 0;
+ return 0;
+}
+/*
+ * The interpreter calls this procedure at the first reschedule point.
+ * It completes context initialization.
+ */
+private int
+ctx_initialize(i_ctx_t **pi_ctx_p)
{
gs_ref_memory_t *imem = iimemory_system;
gs_scheduler_t *psched =
@@ -236,7 +247,7 @@ zcontext_init(void)
psched->dead = 0;
memset(psched->table, 0, sizeof(psched->table));
/* Create an initial context. */
- if (context_create(psched, &psched->current, &gs_imemory, gs_interp_context_state_current) < 0) {
+ if (context_create(psched, &psched->current, &gs_imemory, *pi_ctx_p, true) < 0) {
lprintf("Can't create initial context!");
gs_abort();
}
@@ -245,10 +256,11 @@ zcontext_init(void)
(void **)&the_gs_scheduler,
"the_gs_scheduler");
/* Hook into the interpreter. */
- gs_interp_context_state_current = &psched->current->state;
+ *pi_ctx_p = &psched->current->state;
gs_interp_reschedule_proc = ctx_reschedule;
gs_interp_time_slice_proc = ctx_time_slice;
gs_interp_time_slice_ticks = reschedule_interval;
+ return 0;
}
/* ------ Interpreter interface to scheduler ------ */
@@ -257,11 +269,17 @@ zcontext_init(void)
/* it returns o_reschedule. The interpreter saves all its state in */
/* memory, calls ctx_reschedule, and then loads the state from memory. */
private int
-ctx_reschedule(void)
+ctx_reschedule(i_ctx_t **pi_ctx_p)
{
gs_scheduler_t *psched = the_gs_scheduler;
gs_context *current = psched->current;
+#ifdef DEBUG
+ if (*pi_ctx_p != &current->state) {
+ lprintf2("current->state = 0x%lx, != i_ctx_p = 0x%lx!\n",
+ (ulong)&current->state, (ulong)*pi_ctx_p);
+ }
+#endif
/* If there are any dead contexts waiting to be released, */
/* take care of that now. */
while (psched->dead != 0) {
@@ -322,8 +340,8 @@ ctx_reschedule(void)
psched->current = ready;
/* Load the state of the new current context. */
context_load(psched, ready);
- /* Switch the interpreter's global context state pointer. */
- gs_interp_context_state_current = &ready->state;
+ /* Switch the interpreter's context state pointer. */
+ *pi_ctx_p = &ready->state;
}
return 0;
}
@@ -331,7 +349,7 @@ ctx_reschedule(void)
/* If the interpreter wants to time-slice, it saves its state, */
/* calls ctx_time_slice, and reloads its state. */
private int
-ctx_time_slice(void)
+ctx_time_slice(i_ctx_t **pi_ctx_p)
{
gs_scheduler_t *psched = the_gs_scheduler;
@@ -339,15 +357,16 @@ ctx_time_slice(void)
return 0;
if_debug0('"', "[\"]time-slice\n");
add_last(&psched->active, psched->current);
- return ctx_reschedule();
+ return ctx_reschedule(pi_ctx_p);
}
/* ------ Context operators ------ */
/* - currentcontext <context> */
private int
-zcurrentcontext(register os_ptr op)
+zcurrentcontext(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gs_scheduler_t *psched = the_gs_scheduler;
push(1);
@@ -357,8 +376,9 @@ zcurrentcontext(register os_ptr op)
/* <context> detach - */
private int
-zdetach(register os_ptr op)
+zdetach(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gs_scheduler_t *psched = the_gs_scheduler;
gs_context *pctx;
int code;
@@ -382,18 +402,22 @@ zdetach(register os_ptr op)
private int
do_fork(P5(os_ptr op, const ref * pstdin, const ref * pstdout,
- uint mcount, bool local)), values_older_than(P4(const ref_stack * pstack, uint first, uint last,
- int max_space));
+ uint mcount, bool local)),
+ values_older_than(P4(const ref_stack_t * pstack, uint first, uint last,
+ int max_space));
private int
- fork_done(P1(os_ptr)), fork_done_with_error(P1(os_ptr)), finish_join(P1(os_ptr)),
- reschedule_now(P1(os_ptr));
+ fork_done(P1(i_ctx_t *)),
+ fork_done_with_error(P1(i_ctx_t *)),
+ finish_join(P1(i_ctx_t *)),
+ reschedule_now(P1(i_ctx_t *));
/* <mark> <obj1> ... <objN> <proc> .fork <context> */
/* <mark> <obj1> ... <objN> <proc> <stdin|null> <stdout|null> */
/* .localfork <context> */
private int
-zfork(register os_ptr op)
+zfork(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint mcount = ref_stack_counttomark(&o_stack);
ref rnull;
@@ -403,8 +427,9 @@ zfork(register os_ptr op)
return do_fork(op, &rnull, &rnull, mcount, false);
}
private int
-zlocalfork(register os_ptr op)
+zlocalfork(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint mcount = ref_stack_counttomark(&o_stack);
int code;
@@ -428,6 +453,8 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
bool local)
{
gs_scheduler_t *psched = the_gs_scheduler;
+ gs_context *pcur = psched->current;
+ i_ctx_t *i_ctx_p = &pcur->state;
stream *s;
gs_dual_memory_t dmem;
gs_context *pctx;
@@ -438,14 +465,14 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
if (gs_imemory.save_level)
return_error(e_invalidcontext);
if (r_has_type(pstdout, t_null)) {
- code = zget_stdout(&s);
+ code = zget_stdout(i_ctx_p, &s);
if (code < 0)
return code;
pstdout = &ref_stdio[1];
} else
check_read_file(s, pstdout);
if (r_has_type(pstdin, t_null)) {
- code = zget_stdin(&s);
+ code = zget_stdin(i_ctx_p, &s);
if (code < 0)
return code;
pstdin = &ref_stdio[0];
@@ -472,8 +499,7 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
lmem->space = avm_local;
dmem.space_local = lmem;
- code = context_create(psched, &pctx, &dmem,
- (const gs_context_state_t *)0);
+ code = context_create(psched, &pctx, &dmem, &pcur->state, false);
if (code < 0) {
/****** FREE lmem ******/
return code;
@@ -490,8 +516,7 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
}
} else {
/* Share global and local VM. */
- code = context_create(psched, &pctx, &dmem,
- (const gs_context_state_t *)0);
+ code = context_create(psched, &pctx, &dmem, &pcur->state, false);
if (code < 0) {
/****** FREE lmem ******/
return code;
@@ -526,11 +551,15 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
}
}
}
+ pctx->state.language_level = i_ctx_p->language_level;
+ pctx->state.dict_stack.min_size = idict_stack.min_size;
+ pctx->state.dict_stack.userdict_index = idict_stack.userdict_index;
pctx->state.stdio[0] = *pstdin;
pctx->state.stdio[1] = *pstdout;
+ pctx->state.stdio[2] = pcur->state.stdio[2];
/* Initialize the interpreter stacks. */
{
- ref_stack *dstack = pctx->state.dstack;
+ ref_stack_t *dstack = (ref_stack_t *)&pctx->state.dict_stack;
uint count = ref_stack_count(&d_stack);
uint copy = (local ? min_dstack_size : count);
@@ -549,7 +578,7 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
}
}
{
- ref_stack *estack = pctx->state.estack;
+ ref_stack_t *estack = (ref_stack_t *)&pctx->state.exec_stack;
ref_stack_push(estack, 3);
/* fork_done must be executed in both normal and error cases. */
@@ -558,13 +587,13 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
*estack->p = *op;
}
{
- ref_stack *ostack = pctx->state.ostack;
+ ref_stack_t *ostack = (ref_stack_t *)&pctx->state.op_stack;
uint count = mcount - 2;
ref_stack_push(ostack, count);
stack_copy(ostack, &o_stack, count, osp - op + 1);
}
- pctx->state.binary_object_format = ref_binary_object_format;
+ pctx->state.binary_object_format = pcur->state.binary_object_format;
add_last(&psched->active, pctx);
pop(mcount - 1);
op = osp;
@@ -577,7 +606,7 @@ do_fork(os_ptr op, const ref * pstdin, const ref * pstdout, uint mcount,
* to be valid in the environment to which they are being transferred.
*/
private int
-values_older_than(const ref_stack * pstack, uint first, uint last,
+values_older_than(const ref_stack_t * pstack, uint first, uint last,
int next_space)
{
uint i;
@@ -592,8 +621,9 @@ values_older_than(const ref_stack * pstack, uint first, uint last,
/****** MUST DO ALL RESTORES ******/
/****** WHAT IF invalidrestore? ******/
private int
-fork_done(os_ptr op)
+fork_done(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_scheduler_t *psched = the_gs_scheduler;
gs_context *pcur = psched->current;
@@ -606,7 +636,7 @@ fork_done(os_ptr op)
* next-to-bottom entry on the execution stack.
*/
ref_stack_pop_to(&d_stack, min_dstack_size);
- pop_estack(ref_stack_count(&e_stack) - 1);
+ pop_estack(&pcur->state, ref_stack_count(&e_stack) - 1);
gs_grestoreall(igs);
/*
* If there are any unmatched saves, we need to execute restores
@@ -658,16 +688,17 @@ fork_done(os_ptr op)
* termination.
*/
private int
-fork_done_with_error(os_ptr op)
+fork_done_with_error(i_ctx_t *i_ctx_p)
{
/****** WHAT TO DO? ******/
- return fork_done(op);
+ return fork_done(i_ctx_p);
}
/* <context> join <mark> <obj1> ... <objN> */
private int
-zjoin(register os_ptr op)
+zjoin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_scheduler_t *psched = the_gs_scheduler;
gs_context *pctx;
int code;
@@ -704,7 +735,8 @@ zjoin(register os_ptr op)
return o_push_estack;
case cs_done:
{
- const ref_stack *ostack = pctx->state.ostack;
+ const ref_stack_t *ostack =
+ (ref_stack_t *)&pctx->state.op_stack;
uint count = ref_stack_count(ostack);
push(count);
@@ -722,8 +754,9 @@ zjoin(register os_ptr op)
/* Finish a deferred join. */
private int
-finish_join(os_ptr op)
+finish_join(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_scheduler_t *psched = the_gs_scheduler;
gs_context *pctx;
int code;
@@ -735,19 +768,19 @@ finish_join(os_ptr op)
if (pctx->joiner != psched->current)
return_error(e_invalidcontext);
pctx->joiner = 0;
- return zjoin(op);
+ return zjoin(i_ctx_p);
}
/* Reschedule now. */
private int
-reschedule_now(os_ptr op)
+reschedule_now(i_ctx_t *i_ctx_p)
{
return o_reschedule;
}
/* - yield - */
private int
-zyield(register os_ptr op)
+zyield(i_ctx_t *i_ctx_p)
{
gs_scheduler_t *psched = the_gs_scheduler;
@@ -761,14 +794,17 @@ zyield(register os_ptr op)
/* ------ Condition and lock operators ------ */
private int
- monitor_cleanup(P1(os_ptr)), monitor_release(P1(os_ptr)), await_lock(P1(os_ptr));
+ monitor_cleanup(P1(i_ctx_t *)),
+ monitor_release(P1(i_ctx_t *)),
+ await_lock(P1(i_ctx_t *));
private void
activate_waiting(P1(ctx_list * pcl));
/* - condition <condition> */
private int
-zcondition(register os_ptr op)
+zcondition(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_condition *pcond =
ialloc_struct(gs_condition, &st_condition, "zcondition");
@@ -782,8 +818,9 @@ zcondition(register os_ptr op)
/* - lock <lock> */
private int
-zlock(register os_ptr op)
+zlock(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_lock *plock = ialloc_struct(gs_lock, &st_lock, "zlock");
if (plock == 0)
@@ -797,8 +834,9 @@ zlock(register os_ptr op)
/* <lock> <proc> monitor - */
private int
-zmonitor(register os_ptr op)
+zmonitor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_lock *plock;
gs_context *pctx;
int code;
@@ -841,7 +879,7 @@ zmonitor(register os_ptr op)
}
/* Release the monitor lock when unwinding for an error or exit. */
private int
-monitor_cleanup(os_ptr op)
+monitor_cleanup(i_ctx_t *i_ctx_p)
{
int code = lock_release(esp);
@@ -850,16 +888,17 @@ monitor_cleanup(os_ptr op)
}
/* Release the monitor lock when the procedure completes. */
private int
-monitor_release(os_ptr op)
+monitor_release(i_ctx_t *i_ctx_p)
{
--esp;
- return monitor_cleanup(op);
+ return monitor_cleanup(i_ctx_p);
}
/* <condition> notify - */
private int
-znotify(register os_ptr op)
+znotify(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_condition *pcond;
check_stype(*op, st_condition);
@@ -870,13 +909,14 @@ znotify(register os_ptr op)
if (pcond->waiting.head == 0) /* nothing to do */
return 0;
activate_waiting(&pcond->waiting);
- return zyield(op);
+ return zyield(i_ctx_p);
}
/* <lock> <condition> wait - */
private int
-zwait(register os_ptr op)
+zwait(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_lock *plock;
gs_context *pctx;
gs_condition *pcond;
@@ -901,8 +941,9 @@ zwait(register os_ptr op)
}
/* When the condition is signaled, wait for acquiring the lock. */
private int
-await_lock(os_ptr op)
+await_lock(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = lock_acquire(op - 1, the_gs_scheduler->current);
if (code == 0) {
@@ -934,8 +975,9 @@ activate_waiting(ctx_list * pcl)
/* - usertime <int> */
private int
-zusertime_context(register os_ptr op)
+zusertime_context(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
long utime = context_usertime();
gs_scheduler_t *psched = the_gs_scheduler;
@@ -958,7 +1000,8 @@ zusertime_context(register os_ptr op)
/* Create a context. */
private int
context_create(gs_scheduler_t * psched, gs_context ** ppctx,
- const gs_dual_memory_t * dmem, const gs_context_state_t * pcst)
+ const gs_dual_memory_t * dmem,
+ const gs_context_state_t *i_ctx_p, bool copy_state)
{
gs_ref_memory_t *mem = dmem->space_local;
gs_context *pctx;
@@ -970,8 +1013,8 @@ context_create(gs_scheduler_t * psched, gs_context ** ppctx,
"context_create");
if (pctx == 0)
return_error(e_VMerror);
- if (pcst != 0) {
- pctx->state = *pcst;
+ if (copy_state) {
+ pctx->state = *i_ctx_p;
} else {
gs_context_state_t *pctx_st = &pctx->state;
@@ -980,6 +1023,7 @@ context_create(gs_scheduler_t * psched, gs_context ** ppctx,
gs_free_object((gs_memory_t *) mem, pctx, "context_create");
return code;
}
+ pctx_st->dict_stack.system_dict = *systemdict;
}
ctx_index = gs_next_ids(1);
pctx->scheduler = psched;
@@ -1052,7 +1096,8 @@ context_destroy(gs_context * pctx)
/* Note that this does not push the elements: */
/* the destination stack must have enough space preallocated. */
private void
-stack_copy(ref_stack * to, const ref_stack * from, uint count, uint from_index)
+stack_copy(ref_stack_t * to, const ref_stack_t * from, uint count,
+ uint from_index)
{
long i;
@@ -1091,8 +1136,8 @@ lock_release(ref * op)
/* ------ Initialization procedure ------ */
-const op_def zcontext_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zcontext1_op_defs[] = {
{"0condition", zcondition},
{"0currentcontext", zcurrentcontext},
{"1detach", zdetach},
@@ -1107,6 +1152,9 @@ const op_def zcontext_op_defs[] =
/* Note that the following replace prior definitions */
/* in the indicated files: */
{"0usertime", zusertime_context}, /* zmisc.c */
+ op_def_end(0)
+};
+const op_def zcontext2_op_defs[] = {
/* Internal operators */
{"0%fork_done", fork_done},
{"1%finish_join", finish_join},
diff --git a/gs/src/zcontrol.c b/gs/src/zcontrol.c
index f837a88ef..750e98080 100644
--- a/gs/src/zcontrol.c
+++ b/gs/src/zcontrol.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,19 +32,20 @@
extern void make_invalid_file(P1(ref *)); /* in zfile.c */
/* Forward references */
-private int no_cleanup(P1(os_ptr));
-private uint count_exec_stack(P1(bool));
-private uint count_to_stopped(P1(long));
-private int unmatched_exit(P2(os_ptr, op_proc_p));
+private int no_cleanup(P1(i_ctx_t *));
+private uint count_exec_stack(P2(i_ctx_t *, bool));
+private uint count_to_stopped(P2(i_ctx_t *, long));
+private int unmatched_exit(P2(os_ptr, op_proc_t));
/* See the comment in opdef.h for an invariant which allows */
/* more efficient implementation of for, loop, and repeat. */
/* <[test0 body0 ...]> .cond - */
-private int cond_continue(P1(os_ptr));
+private int cond_continue(P1(i_ctx_t *));
private int
-zcond(register os_ptr op)
+zcond(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
/* Push the array on the e-stack and call the continuation. */
@@ -54,7 +55,7 @@ zcond(register os_ptr op)
if ((r_size(op) & 1) != 0)
return_error(e_rangecheck);
if (r_size(op) == 0)
- return zpop(op);
+ return zpop(i_ctx_p);
check_estack(3);
esp = ep += 3;
ref_assign(ep - 2, op); /* the cond body */
@@ -65,8 +66,9 @@ zcond(register os_ptr op)
return o_push_estack;
}
private int
-cond_continue(register os_ptr op)
+cond_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
int code;
@@ -102,8 +104,9 @@ cond_continue(register os_ptr op)
/* <obj> exec - */
int
-zexec(register os_ptr op)
+zexec(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_op(1);
if (!r_has_attr(op, a_executable))
return 0; /* literal object just gets pushed back */
@@ -117,8 +120,9 @@ zexec(register os_ptr op)
/* <obj1> ... <objn> <n> .execn - */
int
-zexecn(register os_ptr op)
+zexecn(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint n, i;
es_ptr esp_orig;
@@ -154,15 +158,17 @@ zexecn(register os_ptr op)
/* <obj> superexec - */
/* THIS IS NOT REALLY IMPLEMENTED YET. */
private int
-zsuperexec(os_ptr op)
+zsuperexec(i_ctx_t *i_ctx_p)
{
- return zexec(op);
+ return zexec(i_ctx_p);
}
/* <bool> <proc> if - */
int
-zif(register os_ptr op)
+zif(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(op[-1], t_boolean);
check_proc(*op);
if (op[-1].value.boolval) {
@@ -177,8 +183,10 @@ zif(register os_ptr op)
/* <bool> <proc_true> <proc_false> ifelse - */
int
-zifelse(register os_ptr op)
+zifelse(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(op[-2], t_boolean);
check_proc(op[-1]);
check_proc(*op);
@@ -196,11 +204,13 @@ zifelse(register os_ptr op)
/* <init> <step> <limit> <proc> for - */
private int
- for_pos_int_continue(P1(os_ptr)), for_neg_int_continue(P1(os_ptr)),
- for_real_continue(P1(os_ptr));
+ for_pos_int_continue(P1(i_ctx_t *)),
+ for_neg_int_continue(P1(i_ctx_t *)),
+ for_real_continue(P1(i_ctx_t *));
int
-zfor(register os_ptr op)
+zfor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register es_ptr ep;
check_estack(7);
@@ -251,8 +261,9 @@ zfor(register os_ptr op)
/* limit, and procedure (procedure is topmost.) */
/* Continuation operator for positive integers. */
private int
-for_pos_int_continue(register os_ptr op)
+for_pos_int_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register es_ptr ep = esp;
long var = ep[-3].value.intval;
@@ -269,8 +280,9 @@ for_pos_int_continue(register os_ptr op)
}
/* Continuation operator for negative integers. */
private int
-for_neg_int_continue(register os_ptr op)
+for_neg_int_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register es_ptr ep = esp;
long var = ep[-3].value.intval;
@@ -287,8 +299,9 @@ for_neg_int_continue(register os_ptr op)
}
/* Continuation operator for reals. */
private int
-for_real_continue(register os_ptr op)
+for_real_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
float var = ep[-3].value.realval;
float incr = ep[-2].value.realval;
@@ -311,11 +324,11 @@ for_real_continue(register os_ptr op)
/* values 0, 1/N, 2/N, ..., 1 precisely. The arguments must be */
/* the integers 0, 1, and N. We need this for */
/* loading caches such as the transfer function cache. */
-private int for_fraction_continue(P1(os_ptr));
+private int for_fraction_continue(P1(i_ctx_t *));
int
-zfor_fraction(register os_ptr op)
+zfor_fraction(i_ctx_t *i_ctx_p)
{
- int code = zfor(op);
+ int code = zfor(i_ctx_p);
if (code < 0)
return code; /* shouldn't ever happen! */
@@ -324,10 +337,10 @@ zfor_fraction(register os_ptr op)
}
/* Continuation procedure */
private int
-for_fraction_continue(register os_ptr op)
+for_fraction_continue(i_ctx_t *i_ctx_p)
{
register es_ptr ep = esp;
- int code = for_pos_int_continue(op);
+ int code = for_pos_int_continue(i_ctx_p);
if (code != o_push_estack)
return code;
@@ -338,10 +351,11 @@ for_fraction_continue(register os_ptr op)
}
/* <int> <proc> repeat - */
-private int repeat_continue(P1(os_ptr));
+private int repeat_continue(P1(i_ctx_t *));
private int
-zrepeat(register os_ptr op)
+zrepeat(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_type(op[-1], t_integer);
check_proc(*op);
if (op[-1].value.intval < 0)
@@ -354,11 +368,11 @@ zrepeat(register os_ptr op)
*++esp = *op;
make_op_estack(esp + 1, repeat_continue);
pop(2);
- return repeat_continue(op - 2);
+ return repeat_continue(i_ctx_p);
}
/* Continuation operator for repeat */
private int
-repeat_continue(register os_ptr op)
+repeat_continue(i_ctx_t *i_ctx_p)
{
es_ptr ep = esp; /* saved proc */
@@ -373,10 +387,12 @@ repeat_continue(register os_ptr op)
}
/* <proc> loop */
-private int loop_continue(P1(os_ptr));
+private int loop_continue(P1(i_ctx_t *));
private int
-zloop(register os_ptr op)
+zloop(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_proc(*op);
check_estack(4);
/* Push a mark and the procedure, and invoke */
@@ -385,11 +401,11 @@ zloop(register os_ptr op)
*++esp = *op;
make_op_estack(esp + 1, loop_continue);
pop(1);
- return loop_continue(op - 1);
+ return loop_continue(i_ctx_p);
}
/* Continuation operator for loop */
private int
-loop_continue(register os_ptr op)
+loop_continue(i_ctx_t *i_ctx_p)
{
register es_ptr ep = esp; /* saved proc */
@@ -400,8 +416,9 @@ loop_continue(register os_ptr op)
/* - exit - */
private int
-zexit(register os_ptr op)
+zexit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref_stack_enum_t rsenum;
uint scanned = 0;
@@ -415,7 +432,7 @@ zexit(register os_ptr op)
if (r_is_estack_mark(ep))
switch (estack_mark_index(ep)) {
case es_for:
- pop_estack(scanned + (used - count + 1));
+ pop_estack(i_ctx_p, scanned + (used - count + 1));
return o_pop_estack;
case es_stopped:
return_error(e_invalidexit); /* not a loop */
@@ -438,8 +455,10 @@ zexit(register os_ptr op)
/* In the normal (no-error) case, pop the mask from the e-stack, */
/* and move the result to the o-stack. */
private int
-stopped_push(register os_ptr op)
+stopped_push(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = esp[-1];
esp -= 3;
@@ -451,9 +470,10 @@ stopped_push(register os_ptr op)
/* This is implemented in C because if were a pseudo-operator, */
/* the stacks would get restored in case of an error. */
private int
-zstop(register os_ptr op)
+zstop(i_ctx_t *i_ctx_p)
{
- uint count = count_to_stopped(1L);
+ os_ptr op = osp;
+ uint count = count_to_stopped(i_ctx_p, 1L);
if (count) {
/*
@@ -462,7 +482,7 @@ zstop(register os_ptr op)
* until we have run all the unwind procedures.
*/
check_ostack(2);
- pop_estack(count);
+ pop_estack(i_ctx_p, count);
op = osp;
push(1);
make_true(op);
@@ -475,12 +495,13 @@ zstop(register os_ptr op)
/* <result> <mask> .stop - */
private int
-zzstop(register os_ptr op)
+zzstop(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count;
check_type(*op, t_integer);
- count = count_to_stopped(op->value.intval);
+ count = count_to_stopped(i_ctx_p, op->value.intval);
if (count) {
/*
* If there are any t_oparrays on the e-stack, they will pop
@@ -492,7 +513,7 @@ zzstop(register os_ptr op)
check_op(2);
save_result = op[-1];
pop(2);
- pop_estack(count);
+ pop_estack(i_ctx_p, count);
op = osp;
push(1);
*op = save_result;
@@ -507,8 +528,9 @@ zzstop(register os_ptr op)
/* This is implemented in C because if were a pseudo-operator, */
/* the stacks would get restored in case of an error. */
private int
-zstopped(register os_ptr op)
+zstopped(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_op(1);
/* Mark the execution stack, and push the default result */
/* in case control returns normally. */
@@ -527,8 +549,9 @@ zstopped(register os_ptr op)
/* <obj> <result> <mask> .stopped <result> */
private int
-zzstopped(register os_ptr op)
+zzstopped(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_type(*op, t_integer);
check_op(3);
/* Mark the execution stack, and push the default result */
@@ -547,12 +570,13 @@ zzstopped(register os_ptr op)
/* <mask> .instopped false */
/* <mask> .instopped <result> true */
private int
-zinstopped(register os_ptr op)
+zinstopped(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count;
check_type(*op, t_integer);
- count = count_to_stopped(op->value.intval);
+ count = count_to_stopped(i_ctx_p, op->value.intval);
if (count) {
push(1);
op[-1] = *ref_stack_index(&e_stack, count - 2); /* default result */
@@ -566,27 +590,32 @@ zinstopped(register os_ptr op)
/* - countexecstack <int> */
/* countexecstack is an operator solely for the sake of the Genoa tests. */
private int
-zcountexecstack(register os_ptr op)
+zcountexecstack(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
- make_int(op, count_exec_stack(false));
+ make_int(op, count_exec_stack(i_ctx_p, false));
return 0;
}
private int
-zcountexecstack1(register os_ptr op)
+zcountexecstack1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
- make_int(op, count_exec_stack(op->value.boolval));
+ make_int(op, count_exec_stack(i_ctx_p, op->value.boolval));
return 0;
}
/* <array> <include_marks> .execstack <subarray> */
/* <array> execstack <subarray> */
/* execstack is an operator solely for the sake of the Genoa tests. */
-private int execstack_continue(P1(os_ptr));
-private int execstack2_continue(P1(os_ptr));
+private int execstack_continue(P1(i_ctx_t *));
+private int execstack2_continue(P1(i_ctx_t *));
private int
-push_execstack(os_ptr op1, bool include_marks, int (*cont)(P1(os_ptr)))
+push_execstack(i_ctx_t *i_ctx_p, os_ptr op1, bool include_marks,
+ op_proc_t cont)
{
uint size;
/*
@@ -600,7 +629,7 @@ push_execstack(os_ptr op1, bool include_marks, int (*cont)(P1(os_ptr)))
check_write_type(*op1, t_array);
size = r_size(op1);
- depth = count_exec_stack(include_marks);
+ depth = count_exec_stack(i_ctx_p, include_marks);
if (depth > size)
return_error(e_rangecheck);
{
@@ -615,21 +644,26 @@ push_execstack(os_ptr op1, bool include_marks, int (*cont)(P1(os_ptr)))
return o_push_estack;
}
private int
-zexecstack(register os_ptr op)
+zexecstack(i_ctx_t *i_ctx_p)
{
- return push_execstack(op, false, execstack_continue);
+ os_ptr op = osp;
+
+ return push_execstack(i_ctx_p, op, false, execstack_continue);
}
private int
-zexecstack2(register os_ptr op)
+zexecstack2(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
- return push_execstack(op - 1, op->value.boolval, execstack2_continue);
+ return push_execstack(i_ctx_p, op - 1, op->value.boolval, execstack2_continue);
}
/* Continuation operator to do the actual transfer. */
/* r_size(op1) was set just above. */
private int
-do_execstack(os_ptr op, bool include_marks, os_ptr op1)
+do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
{
+ os_ptr op = osp;
ref *arefs = op1->value.refs;
uint asize = r_size(op1);
uint i;
@@ -654,7 +688,7 @@ do_execstack(os_ptr op, bool include_marks, os_ptr op1)
case t_operator: {
uint opidx = op_index(rq);
- if (opidx == 0 || op_def_is_internal(op_def_table[opidx]))
+ if (opidx == 0 || op_def_is_internal(op_index_def(opidx)))
r_clear_attrs(rq, a_executable);
break;
}
@@ -676,37 +710,44 @@ do_execstack(os_ptr op, bool include_marks, os_ptr op1)
return 0;
}
private int
-execstack_continue(os_ptr op)
+execstack_continue(i_ctx_t *i_ctx_p)
{
- return do_execstack(op, false, op);
+ os_ptr op = osp;
+
+ return do_execstack(i_ctx_p, false, op);
}
private int
-execstack2_continue(os_ptr op)
+execstack2_continue(i_ctx_t *i_ctx_p)
{
- return do_execstack(op, op->value.boolval, op - 1);
+ os_ptr op = osp;
+
+ return do_execstack(i_ctx_p, op->value.boolval, op - 1);
}
/* - .needinput - */
private int
-zneedinput(register os_ptr op)
+zneedinput(i_ctx_t *i_ctx_p)
{
return e_NeedInput; /* interpreter will exit to caller */
}
/* <obj> <int> .quit - */
private int
-zquit(register os_ptr op)
+zquit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(2);
check_type(*op, t_integer);
return_error(e_Quit); /* Interpreter will do the exit */
}
/* - currentfile <file> */
-private ref *zget_current_file(P0());
+private ref *zget_current_file(P1(i_ctx_t *));
private int
-zcurrentfile(register os_ptr op)
+zcurrentfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *fp;
push(1);
@@ -714,7 +755,7 @@ zcurrentfile(register os_ptr op)
if (esfile != 0) {
#ifdef DEBUG
/* Check that esfile is valid. */
- ref *efp = zget_current_file();
+ ref *efp = zget_current_file(i_ctx_p);
if (esfile != efp) {
lprintf2("currentfile: esfile=0x%lx, efp=0x%lx\n",
@@ -723,7 +764,7 @@ zcurrentfile(register os_ptr op)
} else
#endif
ref_assign(op, esfile);
- } else if ((fp = zget_current_file()) == 0) { /* Return an invalid file object. */
+ } else if ((fp = zget_current_file(i_ctx_p)) == 0) { /* Return an invalid file object. */
/* This doesn't make a lot of sense to me, */
/* but it's what the PostScript manual specifies. */
make_invalid_file(op);
@@ -737,7 +778,7 @@ zcurrentfile(register os_ptr op)
}
/* Get the current file from which the interpreter is reading. */
private ref *
-zget_current_file(void)
+zget_current_file(i_ctx_t *i_ctx_p)
{
ref_stack_enum_t rsenum;
@@ -755,8 +796,8 @@ zget_current_file(void)
/* ------ Initialization procedure ------ */
-const op_def zcontrol_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zcontrol1_op_defs[] = {
{"1.cond", zcond},
{"0countexecstack", zcountexecstack},
{"1.countexecstack", zcountexecstack1},
@@ -770,6 +811,9 @@ const op_def zcontrol_op_defs[] =
{"3ifelse", zifelse},
{"0.instopped", zinstopped},
{"0.needinput", zneedinput},
+ op_def_end(0)
+};
+const op_def zcontrol2_op_defs[] = {
{"4for", zfor},
{"1loop", zloop},
{"2.quit", zquit},
@@ -778,6 +822,9 @@ const op_def zcontrol_op_defs[] =
{"1.stop", zzstop},
{"1stopped", zstopped},
{"2.stopped", zzstopped},
+ op_def_end(0)
+};
+const op_def zcontrol3_op_defs[] = {
/* Internal operators */
{"1%cond_continue", cond_continue},
{"1%execstack_continue", execstack_continue},
@@ -798,7 +845,7 @@ const op_def zcontrol_op_defs[] =
/* Vacuous cleanup routine */
private int
-no_cleanup(os_ptr op)
+no_cleanup(i_ctx_t *i_ctx_p)
{
return 0;
}
@@ -808,7 +855,7 @@ no_cleanup(os_ptr op)
* the normally invisible elements (*op is a Boolean that indicates this).
*/
private uint
-count_exec_stack(bool include_marks)
+count_exec_stack(i_ctx_t *i_ctx_p, bool include_marks)
{
uint count = ref_stack_count(&e_stack);
@@ -829,7 +876,7 @@ count_exec_stack(bool include_marks)
* mark.
*/
private uint
-count_to_stopped(long mask)
+count_to_stopped(i_ctx_t *i_ctx_p, long mask)
{
ref_stack_enum_t rsenum;
uint scanned = 0;
@@ -857,7 +904,7 @@ count_to_stopped(long mask)
* but it isn't used enough to make this worthwhile.
*/
void
-pop_estack(uint count)
+pop_estack(i_ctx_t *i_ctx_p, uint count)
{
uint idx = 0;
uint popped = 0;
@@ -869,7 +916,7 @@ pop_estack(uint count)
if (r_is_estack_mark(ep)) {
ref_stack_pop(&e_stack, idx + 1 - popped);
popped = idx + 1;
- (*real_opproc(ep)) (osp);
+ (*real_opproc(ep)) (i_ctx_p);
}
}
ref_stack_pop(&e_stack, count - popped);
@@ -881,7 +928,7 @@ pop_estack(uint count)
* ensured two free slots on the top of the o-stack.
*/
private int
-unmatched_exit(os_ptr op, op_proc_p opproc)
+unmatched_exit(os_ptr op, op_proc_t opproc)
{
make_oper(op - 1, 0, opproc);
make_int(op, e_invalidexit);
diff --git a/gs/src/zcrd.c b/gs/src/zcrd.c
index a5fb4b7dc..064e99354 100644
--- a/gs/src/zcrd.c
+++ b/gs/src/zcrd.c
@@ -16,6 +16,7 @@
all copies.
*/
+
/* CIE color rendering operators */
#include "math_.h"
#include "ghost.h"
@@ -39,14 +40,16 @@
private int zcrd1_proc_params(P2(os_ptr op, ref_cie_render_procs * pcprocs));
private int zcrd1_params(P4(os_ptr op, gs_cie_render * pcrd,
ref_cie_render_procs * pcprocs, gs_memory_t * mem));
-private int cache_colorrendering1(P3(gs_cie_render * pcrd,
+private int cache_colorrendering1(P4(i_ctx_t *i_ctx_p, gs_cie_render * pcrd,
const ref_cie_render_procs * pcprocs,
gs_ref_memory_t * imem));
/* - currentcolorrendering <dict> */
private int
-zcurrentcolorrendering(os_ptr op)
+zcurrentcolorrendering(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = istate->colorrendering.dict;
return 0;
@@ -54,8 +57,9 @@ zcurrentcolorrendering(os_ptr op)
/* <dict> .buildcolorrendering1 <crd> */
private int
-zbuildcolorrendering1(os_ptr op)
+zbuildcolorrendering1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_memory_t *mem = gs_state_memory(igs);
int code;
es_ptr ep = esp;
@@ -69,7 +73,8 @@ zbuildcolorrendering1(os_ptr op)
return code;
code = zcrd1_params(op, pcrd, &procs, mem);
if (code < 0 ||
- (code = cache_colorrendering1(pcrd, &procs, (gs_ref_memory_t *) mem)) < 0
+ (code = cache_colorrendering1(i_ctx_p, pcrd, &procs,
+ (gs_ref_memory_t *) mem)) < 0
) {
rc_free_struct(pcrd, ".buildcolorrendering1");
esp = ep;
@@ -84,8 +89,9 @@ zbuildcolorrendering1(os_ptr op)
/* <dict> .builddevicecolorrendering1 <crd> */
private int
-zbuilddevicecolorrendering1(os_ptr op)
+zbuilddevicecolorrendering1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_memory_t *mem = gs_state_memory(igs);
dict_param_list list;
gs_cie_render *pcrd = 0;
@@ -116,8 +122,9 @@ zbuilddevicecolorrendering1(os_ptr op)
/* <dict> <crd> .setcolorrendering1 - */
private int
-zsetcolorrendering1(os_ptr op)
+zsetcolorrendering1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
ref_cie_render_procs procs;
int code;
@@ -131,7 +138,7 @@ zsetcolorrendering1(os_ptr op)
if (code < 0)
return code;
if (gs_cie_cs_common(igs) != 0 &&
- (code = cie_cache_joint(&procs, igs)) < 0
+ (code = cie_cache_joint(i_ctx_p, &procs, gs_cie_cs_common(igs), igs)) < 0
)
return code;
istate->colorrendering.dict = op[-1];
@@ -142,8 +149,9 @@ zsetcolorrendering1(os_ptr op)
/* <dict> <crd> .setdevicecolorrendering1 - */
private int
-zsetdevicecolorrendering1(os_ptr op)
+zsetdevicecolorrendering1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
ref_cie_render_procs procs;
@@ -154,7 +162,7 @@ zsetdevicecolorrendering1(os_ptr op)
return code;
refset_null((ref *)&procs, sizeof(procs) / sizeof(ref));
if (gs_cie_cs_common(igs) != 0 &&
- (code = cie_cache_joint(&procs, igs)) < 0
+ (code = cie_cache_joint(i_ctx_p, &procs, gs_cie_cs_common(igs), igs)) < 0
)
return code;
istate->colorrendering.dict = op[-1];
@@ -241,9 +249,9 @@ zcrd1_params(os_ptr op, gs_cie_render * pcrd,
}
/* Cache the results of the color rendering procedures. */
-private int cie_cache_render_finish(P1(os_ptr));
+private int cie_cache_render_finish(P1(i_ctx_t *));
private int
-cache_colorrendering1(gs_cie_render * pcrd,
+cache_colorrendering1(i_ctx_t *i_ctx_p, gs_cie_render * pcrd,
const ref_cie_render_procs * pcrprocs,
gs_ref_memory_t * imem)
{
@@ -252,9 +260,9 @@ cache_colorrendering1(gs_cie_render * pcrd,
int i;
if (code < 0 ||
- (code = cie_cache_push_finish(cie_cache_render_finish, imem, pcrd)) < 0 ||
- (code = cie_prepare_cache3(&pcrd->DomainLMN, pcrprocs->EncodeLMN.value.const_refs, &pcrd->caches.EncodeLMN[0], pcrd, imem, "Encode.LMN")) < 0 ||
- (code = cie_prepare_cache3(&pcrd->DomainABC, pcrprocs->EncodeABC.value.const_refs, &pcrd->caches.EncodeABC[0], pcrd, imem, "Encode.ABC")) < 0
+ (code = cie_cache_push_finish(i_ctx_p, cie_cache_render_finish, imem, pcrd)) < 0 ||
+ (code = cie_prepare_cache3(i_ctx_p, &pcrd->DomainLMN, pcrprocs->EncodeLMN.value.const_refs, &pcrd->caches.EncodeLMN[0], pcrd, imem, "Encode.LMN")) < 0 ||
+ (code = cie_prepare_cache3(i_ctx_p, &pcrd->DomainABC, pcrprocs->EncodeABC.value.const_refs, &pcrd->caches.EncodeABC[0], pcrd, imem, "Encode.ABC")) < 0
) {
esp = ep;
return code;
@@ -271,7 +279,7 @@ cache_colorrendering1(gs_cie_render * pcrd,
if (!is_identity)
for (i = 0; i < pcrd->RenderTable.lookup.m; i++)
if ((code =
- cie_prepare_cache(Range4_default.ranges,
+ cie_prepare_cache(i_ctx_p, Range4_default.ranges,
pcrprocs->RenderTableT.value.const_refs + i,
&pcrd->caches.RenderTableT[i].floats,
pcrd, imem, "RenderTable.T")) < 0
@@ -285,8 +293,9 @@ cache_colorrendering1(gs_cie_render * pcrd,
/* Finish up after loading the rendering caches. */
private int
-cie_cache_render_finish(os_ptr op)
+cie_cache_render_finish(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_cie_render *pcrd = r_ptr(op, gs_cie_render);
int code;
@@ -315,15 +324,15 @@ cie_cache_render_finish(os_ptr op)
/* Load the joint caches. */
private int
- cie_exec_tpqr(P1(os_ptr)),
- cie_post_exec_tpqr(P1(os_ptr)),
- cie_tpqr_finish(P1(os_ptr));
+ cie_exec_tpqr(P1(i_ctx_t *)),
+ cie_post_exec_tpqr(P1(i_ctx_t *)),
+ cie_tpqr_finish(P1(i_ctx_t *));
int
-cie_cache_joint(const ref_cie_render_procs * pcrprocs, gs_state * pgs)
+cie_cache_joint(i_ctx_t *i_ctx_p, const ref_cie_render_procs * pcrprocs,
+ const gs_cie_common *pcie, gs_state * pgs)
{
const gs_cie_render *pcrd = gs_currentcolorrendering(pgs);
gx_cie_joint_caches *pjc = gx_currentciecaches(pgs);
- const gs_cie_common *pcie = gs_cie_cs_common(pgs);
gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
ref pqr_procs;
uint space;
@@ -348,7 +357,7 @@ cie_cache_joint(const ref_cie_render_procs * pcrprocs, gs_state * pgs)
return code;
/* When we're done, deallocate the procs and complete the caches. */
check_estack(3);
- cie_cache_push_finish(cie_tpqr_finish, imem, pgs);
+ cie_cache_push_finish(i_ctx_p, cie_tpqr_finish, imem, pgs);
*++esp = pqr_procs;
space = r_space(&pqr_procs);
for (i = 0; i < 3; i++) {
@@ -365,7 +374,7 @@ cie_cache_joint(const ref_cie_render_procs * pcrprocs, gs_state * pgs)
for (j = 0, p += 4; j < 4 * 6; j++, p++, ppt++)
make_real(p, *ppt);
}
- return cie_prepare_cache3(&pcrd->RangePQR,
+ return cie_prepare_cache3(i_ctx_p, &pcrd->RangePQR,
pqr_procs.value.const_refs,
&pjc->TransformPQR[0],
pjc, imem, "Transform.PQR");
@@ -374,8 +383,9 @@ cie_cache_joint(const ref_cie_render_procs * pcrprocs, gs_state * pgs)
/* Private operator to shuffle arguments for the TransformPQR procedure: */
/* v [ws wd bs bd] proc -> -mark- ws wd bs bd v proc + exec */
private int
-cie_exec_tpqr(os_ptr op)
+cie_exec_tpqr(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const ref *ppt = op[-1].value.const_refs;
uint space = r_space(op - 1);
int i;
@@ -388,14 +398,15 @@ cie_exec_tpqr(os_ptr op)
make_const_array(op - 5 + i, a_readonly | space,
6, ppt + i * 6);
make_mark(op - 6);
- return zexec(op);
+ return zexec(i_ctx_p);
}
/* Remove extraneous values from the stack after executing */
/* the TransformPQR procedure. -mark- ... v -> v */
private int
-cie_post_exec_tpqr(os_ptr op)
+cie_post_exec_tpqr(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count = ref_stack_counttomark(&o_stack);
ref vref;
@@ -409,8 +420,9 @@ cie_post_exec_tpqr(os_ptr op)
/* Free the procs array and complete the joint caches. */
private int
-cie_tpqr_finish(os_ptr op)
+cie_tpqr_finish(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_state *pgs = r_ptr(op, gs_state);
gs_cie_render *pcrd =
(gs_cie_render *)gs_currentcolorrendering(pgs); /* break const */
diff --git a/gs/src/zcsdevn.c b/gs/src/zcsdevn.c
index 13c16394e..2cec8edd8 100644
--- a/gs/src/zcsdevn.c
+++ b/gs/src/zcsdevn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,20 +23,32 @@
#include "oper.h"
#include "gxcspace.h" /* must precede gscolor2.h */
#include "gscolor2.h"
-#include "igstate.h"
+#include "gxcdevn.h"
+#include "estack.h"
#include "ialloc.h"
+#include "icremap.h"
+#include "igstate.h"
#include "iname.h"
+#include "ostack.h"
+#include "store.h"
/* Imported from gscdevn.c */
extern const gs_color_space_type gs_color_space_type_DeviceN;
+/* Forward references */
+private int ztransform_DeviceN(P5(const gs_device_n_params * params,
+ const float *in, float *out,
+ const gs_imager_state *pis, void *data));
+
/* <array> .setdevicenspace - */
/* The current color space is the alternate space for the DeviceN space. */
private int
-zsetdevicenspace(register os_ptr op)
+zsetdevicenspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const ref *pcsa;
gs_separation_name *names;
+ gs_device_n_map *pmap;
uint num_components;
gs_color_space cs;
ref_colorspace cspace_old;
@@ -51,15 +63,22 @@ zsetdevicenspace(register os_ptr op)
num_components = r_size(pcsa);
if (num_components == 0)
return_error(e_rangecheck);
+ if (num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
+ return_error(e_limitcheck);
check_proc(pcsa[2]);
cs = *gs_currentcolorspace(igs);
if (!cs.type->can_be_alt_space)
return_error(e_rangecheck);
+ code = alloc_device_n_map(&pmap, imemory, ".setdevicenspace(map)");
+ if (code < 0)
+ return code;
names = (gs_separation_name *)
ialloc_byte_array(num_components, sizeof(gs_separation_name),
- ".setdevicenspace");
- if (names == 0)
+ ".setdevicenspace(names)");
+ if (names == 0) {
+ ifree_object(pmap, ".setdevicenspace(map)");
return_error(e_VMerror);
+ }
{
uint i;
ref sname;
@@ -70,7 +89,8 @@ zsetdevicenspace(register os_ptr op)
case t_string:
code = name_from_string(&sname, &sname);
if (code < 0) {
- ifree_object(names, ".setdevicenspace");
+ ifree_object(names, ".setdevicenspace(names)");
+ ifree_object(pmap, ".setdevicenspace(map)");
return code;
}
/* falls through */
@@ -78,7 +98,8 @@ zsetdevicenspace(register os_ptr op)
names[i] = name_index(&sname);
break;
default:
- ifree_object(names, ".setdevicenspace");
+ ifree_object(names, ".setdevicenspace(names)");
+ ifree_object(pmap, ".setdevicenspace(map)");
return_error(e_typecheck);
}
}
@@ -92,23 +113,160 @@ zsetdevicenspace(register os_ptr op)
istate->colorspace.procs.special.device_n.tint_transform = pcsa[2];
cs.params.device_n.names = names;
cs.params.device_n.num_components = num_components;
- cs.params.device_n.tint_transform = 0; /****** ? ******/
- cs.params.device_n.tint_transform_data = 0; /****** ? ******/
+ pmap->tint_transform = ztransform_DeviceN;
+ cs.params.device_n.map = pmap;
code = gs_setcolorspace(igs, &cs);
if (code < 0) {
istate->colorspace = cspace_old;
- ifree_object(names, ".setdevicenspace");
+ ifree_object(names, ".setdevicenspace(names)");
+ ifree_object(pmap, ".setdevicenspace(map)");
return code;
}
+ rc_decrement(pmap, ".setdevicenspace(map)"); /* build sets rc = 1 */
pop(1);
return 0;
}
+/* ------ Internal procedures ------ */
+
+/* Forward references */
+private int devicen_remap_transform(P5(const gs_device_n_params * params,
+ const float *in, float *out,
+ const gs_imager_state *pis,
+ void *data));
+private int devicen_remap_prepare(P1(i_ctx_t *));
+private int devicen_remap_finish(P1(i_ctx_t *));
+private int devicen_remap_cleanup(P1(i_ctx_t *));
+
+/* Map to a concrete color by calling the tint_transform procedure. */
+private int
+ztransform_DeviceN(const gs_device_n_params * params, const float *in,
+ float *out, const gs_imager_state *pis, void *data)
+{
+ /* Just schedule a call on the real tint_transform. */
+ int_remap_color_info_t *prci =
+ r_ptr(&gs_int_gstate((const gs_state *)pis)->remap_color_info,
+ int_remap_color_info_t);
+
+ prci->proc = devicen_remap_prepare;
+ memcpy(prci->tint, in, params->num_components * sizeof(float));
+ return_error(e_RemapColor);
+}
+
+/* Prepare to run tint_transform. */
+private int
+devicen_remap_prepare(i_ctx_t *i_ctx_p)
+{
+ gs_state *pgs = igs;
+ const gs_color_space *pcs = gs_currentcolorspace(pgs);
+ const gs_color_space *pbcs;
+ gs_client_color cc;
+ frac ignore_conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
+
+ /*
+ * Find the DeviceN space. The worst case is an uncolored Pattern over
+ * an Indexed space over a DeviceN space.
+ */
+ if (gs_color_space_get_index(pcs) == gs_color_space_index_Pattern) {
+ pcs = gs_cspace_base_space(pcs);
+ }
+ pbcs = pcs;
+ if (gs_color_space_get_index(pbcs) != gs_color_space_index_DeviceN) {
+ pbcs = gs_cspace_base_space(pbcs);
+ }
+ /*
+ * Temporarily set the tint_transform procedure in the color space to
+ * the one that calls the PostScript code, and its data to the context
+ * pointer. This is a hack, but a localized one, to get an Indexed
+ * color space to do the table lookup.
+ */
+ memcpy(cc.paint.values,
+ r_ptr(&istate->remap_color_info, int_remap_color_info_t)->tint,
+ pbcs->params.device_n.num_components * sizeof(float));
+ pbcs->params.device_n.map->tint_transform = devicen_remap_transform;
+ pbcs->params.device_n.map->tint_transform_data = i_ctx_p;
+ return pcs->type->concretize_color(&cc, pcs, ignore_conc,
+ (gs_imager_state *)pgs);
+}
+
+/* Run the tint_transform procedure on the tint values. */
+private int
+devicen_remap_transform(const gs_device_n_params * params, const float *in,
+ float *out, const gs_imager_state *pis, void *data)
+{
+ i_ctx_t *i_ctx_p = data;
+ int num_in = params->num_components;
+ int i;
+
+ check_estack(num_in + 4);
+ check_ostack(num_in);
+ for (i = 0; i < num_in; ++i) {
+ ++osp;
+ make_real(osp, in[i]);
+ *++esp = *osp;
+ }
+ ++esp;
+ make_int(esp, num_in);
+ push_mark_estack(es_other, devicen_remap_cleanup);
+ push_op_estack(devicen_remap_finish);
+ *++esp = istate->colorspace.procs.special.device_n.tint_transform;
+ /* Restore the tint_transform in the color space. */
+ params->map->tint_transform = ztransform_DeviceN;
+ params->map->tint_transform_data = 0;
+ return o_push_estack;
+}
+
+/* Save the transformed color value. */
+private int
+devicen_remap_finish(i_ctx_t *i_ctx_p)
+{
+ gs_state *pgs = igs;
+ const gs_color_space *pcs = gs_currentcolorspace(pgs);
+ const gs_device_n_params *params;
+ const gs_color_space *pacs;
+ gs_device_n_map *map;
+ int num_in, num_out;
+ float conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ int code;
+ int i;
+
+ while (gs_color_space_get_index(pcs) != gs_color_space_index_DeviceN) {
+ pcs = gs_cspace_base_space(pcs);
+ }
+ params = &pcs->params.device_n;
+ num_in = params->num_components; /* also on e-stack */
+ pacs = (const gs_color_space *)&params->alt_space;
+ map = params->map;
+ num_out = gs_color_space_num_components(pacs);
+ code = float_params(osp, num_out, conc);
+ if (code < 0)
+ return code;
+ esp -= num_in + 2; /* mark, count, tint values */
+ for (i = 0; i < num_in; ++i)
+ map->tint[i] = esp[i + 1].value.realval;
+ for (i = 0; i < num_out; ++i)
+ map->conc[i] = float2frac(conc[i]);
+ map->cache_valid = true;
+ osp -= num_out;
+ return o_pop_estack;
+}
+
+/* Clean up by removing the tint values from the e-stack. */
+private int
+devicen_remap_cleanup(i_ctx_t *i_ctx_p)
+{
+ int num_in = esp->value.intval;
+
+ esp -= num_in + 1;
+ return o_pop_estack;
+}
+
/* ------ Initialization procedure ------ */
const op_def zcsdevn_op_defs[] =
{
op_def_begin_ll3(),
{"1.setdevicenspace", zsetdevicenspace},
+ {"0%devicen_remap_prepare", devicen_remap_prepare},
op_def_end(0)
};
diff --git a/gs/src/zcsindex.c b/gs/src/zcsindex.c
index 788a4ee6e..5c4119f23 100644
--- a/gs/src/zcsindex.c
+++ b/gs/src/zcsindex.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -38,46 +38,14 @@
extern const gs_color_space_type gs_color_space_type_Indexed;
/* Forward references. */
-private int indexed_map1(P1(os_ptr));
-
-/* Free the map when freeing the gs_indexed_map structure. */
-private void
-rc_free_indexed_map(gs_memory_t * mem, void *data, client_name_t cname)
-{ /*
- * A bug in the SGI Irix 4.05 compiler requires the following:
- */
- char *cdata = (char *)data;
-
- gs_free_object(mem, ((gs_indexed_map *)cdata)->values, cname);
- gs_free_object(mem, cdata, cname);
-}
-
-/* Indexed lookup procedure that just consults the cache. */
-private int
-lookup_indexed(const gs_indexed_params * params, int index, float *values)
-{
- int m = cs_num_components((const gs_color_space *)&params->base_space);
- const float *pv = &params->lookup.map->values[index * m];
-
- switch (m) {
- default:
- return_error(e_rangecheck);
- case 4:
- values[3] = pv[3];
- case 3:
- values[2] = pv[2];
- values[1] = pv[1];
- case 1:
- values[0] = pv[0];
- }
- return 0;
-}
+private int indexed_map1(P1(i_ctx_t *));
/* <array> .setindexedspace - */
/* The current color space is the base space for the indexed space. */
private int
-zsetindexedspace(register os_ptr op)
+zsetindexedspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *pproc = &istate->colorspace.procs.special.index_proc;
const ref *pcsa;
gs_color_space cs;
@@ -106,19 +74,20 @@ zsetindexedspace(register os_ptr op)
cs.params.indexed.base_space = cs_base;
* But the Watcom C 10.0 compiler is too smart: it turns this into
* a direct assignment (and compiles incorrect code for it),
- * defeating our purpose. Instead, we have to do it by brute force:
+ * defeating our purpose. Instead, we have to do it by brute force
+ * using memmove.
*/
- memmove(&cs.params.indexed.base_space, &cs,
- sizeof(cs.params.indexed.base_space));
if (r_has_type(&pcsa[2], t_string)) {
int num_values = num_entries * cs_num_components(&cs);
check_read(pcsa[2]);
if (r_size(&pcsa[2]) != num_values)
return_error(e_rangecheck);
+ memmove(&cs.params.indexed.base_space, &cs,
+ sizeof(cs.params.indexed.base_space));
gs_cspace_init(&cs, &gs_color_space_type_Indexed, NULL);
- cs.params.indexed.lookup.table.data =
- pcsa[2].value.const_bytes;
+ cs.params.indexed.lookup.table.data = pcsa[2].value.const_bytes;
+ cs.params.indexed.lookup.table.size = num_values;
cs.params.indexed.use_proc = 0;
make_null(pproc);
code = 0;
@@ -126,15 +95,22 @@ zsetindexedspace(register os_ptr op)
gs_indexed_map *map;
check_proc(pcsa[2]);
- code = zcs_begin_map(&map, &pcsa[2], num_entries,
- (const gs_base_color_space *)&cs,
+ /*
+ * We have to call zcs_begin_map before moving the parameters,
+ * since if the color space is a DeviceN or Separation space,
+ * the memmove will overwrite its parameters.
+ */
+ code = zcs_begin_map(i_ctx_p, &map, &pcsa[2], num_entries,
+ (const gs_direct_color_space *)&cs,
indexed_map1);
if (code < 0)
return code;
+ memmove(&cs.params.indexed.base_space, &cs,
+ sizeof(cs.params.indexed.base_space));
gs_cspace_init(&cs, &gs_color_space_type_Indexed, NULL);
cs.params.indexed.use_proc = 1;
*pproc = pcsa[2];
- map->proc.lookup_index = lookup_indexed;
+ map->proc.lookup_index = lookup_indexed_map;
cs.params.indexed.lookup.map = map;
}
cs.params.indexed.hival = num_entries - 1;
@@ -150,8 +126,9 @@ zsetindexedspace(register os_ptr op)
/* Continuation procedure for saving mapped Indexed color values. */
private int
-indexed_map1(os_ptr op)
+indexed_map1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
int i = (int)ep[csme_index].value.intval;
@@ -192,12 +169,13 @@ const op_def zcsindex_l2_op_defs[] =
/* Allocate, and prepare to load, the index or tint map. */
int
-zcs_begin_map(gs_indexed_map ** pmap, const ref * pproc, int num_entries,
- const gs_base_color_space * base_space, int (*map1) (P1(os_ptr)))
+zcs_begin_map(i_ctx_t *i_ctx_p, gs_indexed_map ** pmap, const ref * pproc,
+ int num_entries, const gs_direct_color_space * base_space,
+ op_proc_t map1)
{
gs_memory_t *mem = gs_state_memory(igs);
int num_components =
- cs_num_components((const gs_color_space *)base_space);
+ cs_num_components((const gs_color_space *)base_space);
int num_values = num_entries * num_components;
gs_indexed_map *map;
es_ptr ep;
@@ -214,12 +192,12 @@ zcs_begin_map(gs_indexed_map ** pmap, const ref * pproc, int num_entries,
gs_free_object(mem, map, "setcolorspace(mapped)");
return_error(e_VMerror);
}
- map->rc.free = rc_free_indexed_map;
+ map->rc.free = free_indexed_map;
map->num_values = num_values;
map->values = values;
*pmap = map;
/* Map the entire set of color indices. Since the */
- /* o-stack may not be able to hold 4*4096 values, we have */
+ /* o-stack may not be able to hold N*4096 values, we have */
/* to load them into the cache as they are generated. */
check_estack(num_csme + 1); /* 1 extra for map1 proc */
ep = esp += num_csme;
diff --git a/gs/src/zcspixel.c b/gs/src/zcspixel.c
index bd27890fa..49e2a6a15 100644
--- a/gs/src/zcspixel.c
+++ b/gs/src/zcspixel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,8 +28,9 @@
/* <array> .setdevicepixelspace - */
private int
-zsetdevicepixelspace(register os_ptr op)
+zsetdevicepixelspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref depth;
gs_color_space cs;
int code;
diff --git a/gs/src/zcssepr.c b/gs/src/zcssepr.c
index 193765758..f02bf61e4 100644
--- a/gs/src/zcssepr.c
+++ b/gs/src/zcssepr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -39,7 +39,7 @@
extern const gs_color_space_type gs_color_space_type_Separation;
/* Forward references */
-private int separation_map1(P1(os_ptr));
+private int separation_map1(P1(i_ctx_t *));
/* Define the separation cache size. This makes many useful tint values */
/* map to integer cache indices. */
@@ -56,25 +56,16 @@ lookup_tint(const gs_separation_params * params, floatp tint, float *values)
(int)(tint * SEPARATION_CACHE_SIZE + 0.5) * m);
const float *pv = &map->values[value_index];
- switch (m) {
- default:
- return_error(e_rangecheck);
- case 4:
- values[3] = pv[3];
- case 3:
- values[2] = pv[2];
- values[1] = pv[1];
- case 1:
- values[0] = pv[0];
- }
+ memcpy(values, pv, sizeof(*values) * m);
return 0;
}
/* <array> .setseparationspace - */
/* The current color space is the alternate space for the separation space. */
private int
-zsetseparationspace(register os_ptr op)
+zsetseparationspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const ref *pcsa;
gs_color_space cs;
ref_colorspace cspace_old;
@@ -97,8 +88,8 @@ zsetseparationspace(register os_ptr op)
cs = *gs_currentcolorspace(igs);
if (!cs.type->can_be_alt_space)
return_error(e_rangecheck);
- code = zcs_begin_map(&map, &pcsa[2], SEPARATION_CACHE_SIZE + 1,
- (const gs_base_color_space *)&cs,
+ code = zcs_begin_map(i_ctx_p, &map, &pcsa[2], SEPARATION_CACHE_SIZE + 1,
+ (const gs_direct_color_space *)&cs,
separation_map1);
if (code < 0)
return code;
@@ -123,8 +114,9 @@ zsetseparationspace(register os_ptr op)
/* Continuation procedure for saving transformed tint values. */
private int
-separation_map1(os_ptr op)
+separation_map1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr ep = esp;
int i = (int)ep[csme_index].value.intval;
@@ -152,8 +144,10 @@ separation_map1(os_ptr op)
/* - currentoverprint <bool> */
private int
-zcurrentoverprint(register os_ptr op)
+zcurrentoverprint(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currentoverprint(igs));
return 0;
@@ -161,8 +155,10 @@ zcurrentoverprint(register os_ptr op)
/* <bool> setoverprint - */
private int
-zsetoverprint(register os_ptr op)
+zsetoverprint(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_setoverprint(igs, op->value.boolval);
pop(1);
diff --git a/gs/src/zdevice.c b/gs/src/zdevice.c
index 61e7bb904..2ac3846d1 100644
--- a/gs/src/zdevice.c
+++ b/gs/src/zdevice.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,8 +36,9 @@
/* <device> copydevice <newdevice> */
private int
-zcopydevice(register os_ptr op)
+zcopydevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *new_dev;
int code;
@@ -52,8 +53,9 @@ zcopydevice(register os_ptr op)
/* - currentdevice <device> */
int
-zcurrentdevice(register os_ptr op)
+zcurrentdevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory;
@@ -66,8 +68,9 @@ zcurrentdevice(register os_ptr op)
/* <device> .devicename <string> */
int
-zdevicename(register os_ptr op)
+zdevicename(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const char *dname;
check_read_type(*op, t_device);
@@ -79,7 +82,7 @@ zdevicename(register os_ptr op)
/* - .doneshowpage - */
private int
-zdoneshowpage(register os_ptr op)
+zdoneshowpage(i_ctx_t *i_ctx_p)
{
gx_device *dev = gs_currentdevice(igs);
gx_device *tdev = (*dev_proc(dev, get_page_device)) (dev);
@@ -91,20 +94,21 @@ zdoneshowpage(register os_ptr op)
/* - flushpage - */
int
-zflushpage(register os_ptr op)
+zflushpage(i_ctx_t *i_ctx_p)
{
return gs_flushpage(igs);
}
-/* <device> <x> <y> <width> <max_height> <alpha?> <std_depth> <string> */
+/* <device> <x> <y> <width> <max_height> <alpha?> <std_depth|null> <string> */
/* .getbitsrect <height> <substring> */
private int
-zgetbitsrect(register os_ptr op)
+zgetbitsrect(i_ctx_t *i_ctx_p)
{ /*
* alpha? is 0 for no alpha, -1 for alpha first, 1 for alpha last.
* std_depth is null for native pixels, depth/component for
* standard color space.
*/
+ os_ptr op = osp;
gx_device *dev;
gs_int_rect rect;
gs_get_bits_params_t params;
@@ -112,7 +116,7 @@ zgetbitsrect(register os_ptr op)
gs_get_bits_options_t options =
GB_ALIGN_ANY | GB_RETURN_COPY | GB_OFFSET_0 | GB_RASTER_STANDARD |
GB_PACKING_CHUNKY;
- int std_depth;
+ int depth;
uint raster;
int num_rows;
int code;
@@ -128,27 +132,28 @@ zgetbitsrect(register os_ptr op)
check_int_leu(op[-3], dev->height);
h = op[-3].value.intval;
check_type(op[-2], t_integer);
- switch (op[-2].value.intval) {
- case -1:
- options |= GB_ALPHA_FIRST;
- break;
- case 0:
- options |= GB_ALPHA_NONE;
- break;
- case 1:
- options |= GB_ALPHA_LAST;
- break;
- default:
- return_error(e_rangecheck);
- }
- if (r_has_type(op - 1, t_null))
+ /*
+ * We use if/else rather than switch because the value is long,
+ * which is not supported as a switch value in pre-ANSI C.
+ */
+ if (op[-2].value.intval == -1)
+ options |= GB_ALPHA_FIRST;
+ else if (op[-2].value.intval == 0)
+ options |= GB_ALPHA_NONE;
+ else if (op[-2].value.intval == 1)
+ options |= GB_ALPHA_LAST;
+ else
+ return_error(e_rangecheck);
+ if (r_has_type(op - 1, t_null)) {
options |= GB_COLORS_NATIVE;
- else {
+ depth = dev->color_info.depth;
+ } else {
static const gs_get_bits_options_t depths[17] = {
0, GB_DEPTH_1, GB_DEPTH_2, 0, GB_DEPTH_4, 0, 0, 0, GB_DEPTH_8,
0, 0, 0, GB_DEPTH_12, 0, 0, 0, GB_DEPTH_16
};
gs_get_bits_options_t depth_option;
+ int std_depth;
check_int_leu(op[-1], 16);
std_depth = (int)op[-1].value.intval;
@@ -156,16 +161,11 @@ zgetbitsrect(register os_ptr op)
if (depth_option == 0)
return_error(e_rangecheck);
options |= depth_option | gb_colors_for_device(dev);
+ depth = (dev->color_info.num_components +
+ (options & GB_ALPHA_NONE ? 0 : 1)) * std_depth;
}
+ raster = (w * depth + 7) >> 3;
check_write_type(*op, t_string);
- {
- int depth =
- (options & GB_COLORS_NATIVE ? dev->color_info.depth :
- (dev->color_info.num_components +
- (options & GB_ALPHA_NONE ? 0 : 1)) * std_depth);
-
- raster = (w * depth + 7) >> 3;
- }
num_rows = r_size(op) / raster;
h = min(h, num_rows);
if (h == 0)
@@ -186,8 +186,9 @@ zgetbitsrect(register os_ptr op)
/* <int> .getdevice <device> */
private int
-zgetdevice(register os_ptr op)
+zgetdevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gx_device *dev;
check_type(*op, t_integer);
@@ -205,8 +206,9 @@ zgetdevice(register os_ptr op)
/* Common functionality of zgethardwareparms & zgetdeviceparams */
private int
-zget_device_params(os_ptr op, bool is_hardware)
+zget_device_params(i_ctx_t *i_ctx_p, bool is_hardware)
{
+ os_ptr op = osp;
ref rkeys;
gx_device *dev;
stack_param_list list;
@@ -235,21 +237,22 @@ zget_device_params(os_ptr op, bool is_hardware)
}
/* <device> <key_dict|null> .getdeviceparams <mark> <name> <value> ... */
private int
-zgetdeviceparams(os_ptr op)
+zgetdeviceparams(i_ctx_t *i_ctx_p)
{
- return zget_device_params(op, false);
+ return zget_device_params(i_ctx_p, false);
}
/* <device> <key_dict|null> .gethardwareparams <mark> <name> <value> ... */
private int
-zgethardwareparams(os_ptr op)
+zgethardwareparams(i_ctx_t *i_ctx_p)
{
- return zget_device_params(op, true);
+ return zget_device_params(i_ctx_p, true);
}
/* <matrix> <width> <height> <palette> <word?> makewordimagedevice <device> */
private int
-zmakewordimagedevice(register os_ptr op)
+zmakewordimagedevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
gs_matrix imat;
gx_device *new_dev;
@@ -264,14 +267,14 @@ zmakewordimagedevice(register os_ptr op)
colors = 0;
colors_size = -24; /* 24-bit true color */
} else if (r_has_type(op1, t_integer)) {
- switch (op1->value.intval) {
- case 16:
- case 24:
- case 32:
- break;
- default:
- return_error(e_rangecheck);
- }
+ /*
+ * We use if/else rather than switch because the value is long,
+ * which is not supported as a switch value in pre-ANSI C.
+ */
+ if (op1->value.intval != 16 && op1->value.intval != 24 &&
+ op1->value.intval != 32
+ )
+ return_error(e_rangecheck);
colors = 0;
colors_size = -op1->value.intval;
} else {
@@ -301,7 +304,7 @@ zmakewordimagedevice(register os_ptr op)
/* - nulldevice - */
/* Note that nulldevice clears the current pagedevice. */
private int
-znulldevice(register os_ptr op)
+znulldevice(i_ctx_t *i_ctx_p)
{
gs_nulldevice(igs);
clear_pagedevice(istate);
@@ -310,8 +313,9 @@ znulldevice(register os_ptr op)
/* <num_copies> <flush_bool> .outputpage - */
private int
-zoutputpage(register os_ptr op)
+zoutputpage(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(op[-1], t_integer);
@@ -334,7 +338,7 @@ zoutputpage(register os_ptr op)
/* the key will be ignored. */
/* Note that .putdeviceparams clears the current pagedevice. */
private int
-zputdeviceparams(os_ptr op)
+zputdeviceparams(i_ctx_t *i_ctx_p)
{
uint count = ref_stack_counttomark(&o_stack);
ref *prequire_all;
@@ -368,7 +372,7 @@ zputdeviceparams(os_ptr op)
if (list.results[i] < 0) {
*ref_stack_index(&o_stack, dest) =
*ref_stack_index(&o_stack, count - (i << 1) - 2);
- gs_errorname(list.results[i],
+ gs_errorname(i_ctx_p, list.results[i],
ref_stack_index(&o_stack, dest - 1));
dest -= 2;
}
@@ -404,8 +408,9 @@ zputdeviceparams(os_ptr op)
/* <device> .setdevice <eraseflag> */
/* Note that .setdevice clears the current pagedevice. */
int
-zsetdevice(register os_ptr op)
+zsetdevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_write_type(*op, t_device);
diff --git a/gs/src/zdevice2.c b/gs/src/zdevice2.c
index e9bff36fd..ab0182923 100644
--- a/gs/src/zdevice2.c
+++ b/gs/src/zdevice2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,29 +33,31 @@
#include "gsstate.h"
/* Forward references */
-private int z2copy_gstate(P1(os_ptr));
-private int push_callout(P1(const char *));
+private int z2copy_gstate(P1(i_ctx_t *));
+private int push_callout(P2(i_ctx_t *, const char *));
/* Extend the `copy' operator to deal with gstates. */
/* This is done with a hack -- we know that gstates are the only */
/* t_astruct subtype that implements copy. */
private int
-z2copy(register os_ptr op)
+z2copy(i_ctx_t *i_ctx_p)
{
- int code = zcopy(op);
+ os_ptr op = osp;
+ int code = zcopy(i_ctx_p);
if (code >= 0)
return code;
if (!r_has_type(op, t_astruct))
return code;
- return z2copy_gstate(op);
+ return z2copy_gstate(i_ctx_p);
}
/* - .currentshowpagecount <count> true */
/* - .currentshowpagecount false */
private int
-zcurrentshowpagecount(register os_ptr op)
+zcurrentshowpagecount(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
if ((*dev_proc(dev, get_page_device))(dev) == 0) {
@@ -71,8 +73,9 @@ zcurrentshowpagecount(register os_ptr op)
/* - .currentpagedevice <dict> <bool> */
private int
-zcurrentpagedevice(register os_ptr op)
+zcurrentpagedevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
push(2);
@@ -88,8 +91,9 @@ zcurrentpagedevice(register os_ptr op)
/* <local_dict|null> .setpagedevice - */
private int
-zsetpagedevice(register os_ptr op)
+zsetpagedevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
/******
@@ -107,7 +111,7 @@ zsetpagedevice(register os_ptr op)
return_error(e_invalidaccess);
#endif /****************/
/* Make the dictionary read-only. */
- code = zreadonly(op);
+ code = zreadonly(i_ctx_p);
if (code < 0)
return code;
} else {
@@ -123,7 +127,7 @@ zsetpagedevice(register os_ptr op)
/* - .callinstall - */
private int
-zcallinstall(os_ptr op)
+zcallinstall(i_ctx_t *i_ctx_p)
{
gx_device *dev = gs_currentdevice(igs);
@@ -138,8 +142,9 @@ zcallinstall(os_ptr op)
/* <showpage_count> .callbeginpage - */
private int
-zcallbeginpage(os_ptr op)
+zcallbeginpage(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
check_type(*op, t_integer);
@@ -155,8 +160,9 @@ zcallbeginpage(os_ptr op)
/* <showpage_count> <reason_int> .callendpage <flush_bool> */
private int
-zcallendpage(os_ptr op)
+zcallendpage(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
int code;
@@ -195,47 +201,47 @@ save_page_device(gs_state *pgs)
/* - gsave - */
private int
-z2gsave(os_ptr op)
+z2gsave(i_ctx_t *i_ctx_p)
{
if (!save_page_device(igs))
return gs_gsave(igs);
- return push_callout("%gsavepagedevice");
+ return push_callout(i_ctx_p, "%gsavepagedevice");
}
/* - save - */
private int
-z2save(os_ptr op)
+z2save(i_ctx_t *i_ctx_p)
{
if (!save_page_device(igs))
- return zsave(op);
- return push_callout("%savepagedevice");
+ return zsave(i_ctx_p);
+ return push_callout(i_ctx_p, "%savepagedevice");
}
/* - gstate <gstate> */
private int
-z2gstate(os_ptr op)
+z2gstate(i_ctx_t *i_ctx_p)
{
if (!save_page_device(igs))
- return zgstate(op);
- return push_callout("%gstatepagedevice");
+ return zgstate(i_ctx_p);
+ return push_callout(i_ctx_p, "%gstatepagedevice");
}
/* <gstate1> <gstate2> copy <gstate2> */
private int
-z2copy_gstate(os_ptr op)
+z2copy_gstate(i_ctx_t *i_ctx_p)
{
if (!save_page_device(igs))
- return zcopy_gstate(op);
- return push_callout("%copygstatepagedevice");
+ return zcopy_gstate(i_ctx_p);
+ return push_callout(i_ctx_p, "%copygstatepagedevice");
}
/* <gstate> currentgstate <gstate> */
private int
-z2currentgstate(os_ptr op)
+z2currentgstate(i_ctx_t *i_ctx_p)
{
if (!save_page_device(igs))
- return zcurrentgstate(op);
- return push_callout("%currentgstatepagedevice");
+ return zcurrentgstate(i_ctx_p);
+ return push_callout(i_ctx_p, "%currentgstatepagedevice");
}
/* ------ Wrappers for operators that reset the graphics state. ------ */
@@ -273,16 +279,16 @@ restore_page_device(const gs_state * pgs_old, const gs_state * pgs_new)
/* - grestore - */
private int
-z2grestore(os_ptr op)
+z2grestore(i_ctx_t *i_ctx_p)
{
if (!restore_page_device(igs, gs_state_saved(igs)))
return gs_grestore(igs);
- return push_callout("%grestorepagedevice");
+ return push_callout(i_ctx_p, "%grestorepagedevice");
}
/* - grestoreall - */
private int
-z2grestoreall(os_ptr op)
+z2grestoreall(i_ctx_t *i_ctx_p)
{
for (;;) {
if (!restore_page_device(igs, gs_state_saved(igs))) {
@@ -292,34 +298,36 @@ z2grestoreall(os_ptr op)
if (done)
break;
} else
- return push_callout("%grestoreallpagedevice");
+ return push_callout(i_ctx_p, "%grestoreallpagedevice");
}
return 0;
}
/* <save> restore - */
private int
-z2restore(os_ptr op)
+z2restore(i_ctx_t *i_ctx_p)
{
for (;;) {
if (!restore_page_device(igs, gs_state_saved(igs))) {
- zgrestore(op);
if (!gs_state_saved(gs_state_saved(igs)))
break;
+ gs_grestore(igs);
} else
- return push_callout("%restorepagedevice");
+ return push_callout(i_ctx_p, "%restorepagedevice");
}
- return zrestore(op);
+ return zrestore(i_ctx_p);
}
/* <gstate> setgstate - */
private int
-z2setgstate(os_ptr op)
+z2setgstate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_stype(*op, st_igstate_obj);
if (!restore_page_device(igs, igstate_ptr(op)))
- return zsetgstate(op);
- return push_callout("%setgstatepagedevice");
+ return zsetgstate(i_ctx_p);
+ return push_callout(i_ctx_p, "%setgstatepagedevice");
}
/* ------ Initialization procedure ------ */
@@ -353,7 +361,7 @@ const op_def zdevice2_l2_op_defs[] =
/* Call out to a PostScript procedure. */
private int
-push_callout(const char *callout_name)
+push_callout(i_ctx_t *i_ctx_p, const char *callout_name)
{
int code;
diff --git a/gs/src/zdict.c b/gs/src/zdict.c
index 0c9895f7a..0095b95d1 100644
--- a/gs/src/zdict.c
+++ b/gs/src/zdict.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,7 +20,7 @@
/* Dictionary operators */
#include "ghost.h"
#include "oper.h"
-#include "idict.h"
+#include "iddict.h"
#include "dstack.h"
#include "ilevel.h" /* for [count]dictstack */
#include "iname.h" /* for dict_find_name */
@@ -30,8 +30,10 @@
/* <int> dict <dict> */
int
-zdict(register os_ptr op)
+zdict(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
#if arch_sizeof_int < arch_sizeof_long
check_int_leu(*op, max_uint);
@@ -44,8 +46,10 @@ zdict(register os_ptr op)
/* <dict> maxlength <int> */
private int
-zmaxlength(register os_ptr op)
+zmaxlength(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_dictionary);
check_dict_read(*op);
make_int(op, dict_maxlength(op));
@@ -54,8 +58,10 @@ zmaxlength(register os_ptr op)
/* <dict> begin - */
int
-zbegin(register os_ptr op)
+zbegin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_dictionary);
check_dict_read(*op);
if (dsp == dstop)
@@ -69,7 +75,7 @@ zbegin(register os_ptr op)
/* - end - */
int
-zend(register os_ptr op)
+zend(i_ctx_t *i_ctx_p)
{
if (ref_stack_count_inline(&d_stack) == min_dstack_size) {
/* We would underflow the d-stack. */
@@ -90,9 +96,10 @@ zend(register os_ptr op)
* the interpreter will almost always call it directly.
*/
int
-zop_def(register os_ptr op)
+zop_def(i_ctx_t *i_ctx_p)
{
- register os_ptr op1 = op - 1;
+ os_ptr op = osp;
+ os_ptr op1 = op - 1;
ref *pvslot;
/* The following combines a check_op(2) with a type check. */
@@ -131,16 +138,16 @@ zop_def(register os_ptr op)
* in the uncommon case.
*/
if (dict_find(dsp, op1, &pvslot) <= 0)
- return dict_put(dsp, op1, op);
+ return idict_put(dsp, op1, op);
ra:
ref_assign_old_inline(&dsp->value.pdict->values, pvslot, op,
"dict_put(value)");
return 0;
}
int
-zdef(os_ptr op)
+zdef(i_ctx_t *i_ctx_p)
{
- int code = zop_def(op);
+ int code = zop_def(i_ctx_p);
if (code >= 0) {
pop(2);
@@ -150,8 +157,9 @@ zdef(os_ptr op)
/* <key> load <value> */
private int
-zload(register os_ptr op)
+zload(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *pvalue;
switch (r_type(op)) {
@@ -191,19 +199,22 @@ zload(register os_ptr op)
/* <dict> <key> .undef - */
/* <dict> <key> undef - */
private int
-zundef(register os_ptr op)
+zundef(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(op[-1], t_dictionary);
check_dict_write(op[-1]);
- dict_undef(op - 1, op); /* ignore undefined error */
+ idict_undef(op - 1, op); /* ignore undefined error */
pop(2);
return 0;
}
/* <dict> <key> known <bool> */
private int
-zknown(register os_ptr op)
+zknown(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register os_ptr op1 = op - 1;
ref *pvalue;
@@ -217,8 +228,9 @@ zknown(register os_ptr op)
/* <key> where <dict> true */
/* <key> where false */
int
-zwhere(register os_ptr op)
+zwhere(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref_stack_enum_t rsenum;
check_op(1);
@@ -245,8 +257,9 @@ zwhere(register os_ptr op)
/* copy for dictionaries -- called from zcopy in zgeneric.c. */
/* Only the type of *op has been checked. */
int
-zcopy_dict(register os_ptr op)
+zcopy_dict(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int code;
@@ -257,7 +270,7 @@ zcopy_dict(register os_ptr op)
(dict_length(op) != 0 || dict_maxlength(op) < dict_length(op1))
)
return_error(e_rangecheck);
- code = dict_copy(op1, op);
+ code = idict_copy(op1, op);
if (code < 0)
return code;
/*
@@ -274,8 +287,10 @@ zcopy_dict(register os_ptr op)
/* - currentdict <dict> */
private int
-zcurrentdict(register os_ptr op)
+zcurrentdict(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
ref_assign(op, dsp);
return 0;
@@ -283,8 +298,9 @@ zcurrentdict(register os_ptr op)
/* - countdictstack <int> */
private int
-zcountdictstack(register os_ptr op)
+zcountdictstack(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count = ref_stack_count(&d_stack);
push(1);
@@ -296,8 +312,9 @@ zcountdictstack(register os_ptr op)
/* <array> dictstack <subarray> */
private int
-zdictstack(register os_ptr op)
+zdictstack(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count = ref_stack_count(&d_stack);
check_write_type(*op, t_array);
@@ -308,9 +325,10 @@ zdictstack(register os_ptr op)
/* - cleardictstack - */
private int
-zcleardictstack(os_ptr op)
+zcleardictstack(i_ctx_t *i_ctx_p)
{
- while (zend(op) >= 0);
+ while (zend(i_ctx_p) >= 0)
+ DO_NOTHING;
return 0;
}
@@ -318,8 +336,9 @@ zcleardictstack(os_ptr op)
/* <dict1> <dict2> .dictcopynew <dict2> */
private int
-zdictcopynew(register os_ptr op)
+zdictcopynew(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int code;
@@ -330,7 +349,7 @@ zdictcopynew(register os_ptr op)
/* This is only recognized in Level 2 mode. */
if (!dict_auto_expand)
return_error(e_undefined);
- code = dict_copy_new(op1, op);
+ code = idict_copy_new(op1, op);
if (code < 0)
return code;
ref_assign(op1, op);
@@ -341,7 +360,7 @@ zdictcopynew(register os_ptr op)
/* -mark- <key0> <value0> <key1> <value1> ... .dicttomark <dict> */
/* This is the Level 2 >> operator. */
private int
-zdicttomark(register os_ptr op)
+zdicttomark(i_ctx_t *i_ctx_p)
{
uint count2 = ref_stack_counttomark(&o_stack);
ref rdict;
@@ -359,9 +378,9 @@ zdicttomark(register os_ptr op)
/* << /a 1 /a 2 >> => << /a 1 >>, i.e., */
/* we must enter the keys in top-to-bottom order. */
for (idx = 0; idx < count2; idx += 2) {
- code = dict_put(&rdict,
- ref_stack_index(&o_stack, idx + 1),
- ref_stack_index(&o_stack, idx));
+ code = idict_put(&rdict,
+ ref_stack_index(&o_stack, idx + 1),
+ ref_stack_index(&o_stack, idx));
if (code < 0) { /* There's no way to free the dictionary -- too bad. */
return code;
}
@@ -381,8 +400,9 @@ zdicttomark(register os_ptr op)
* should no longer be accessible by name.
*/
private int
-zforceput(register os_ptr op)
+zforceput(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr odp = op - 2;
int code;
@@ -393,10 +413,10 @@ zforceput(register os_ptr op)
uint space = r_space(odp);
r_set_space(odp, avm_local);
- code = dict_put(odp, op - 1, op);
+ code = idict_put(odp, op - 1, op);
r_set_space(odp, space);
} else
- code = dict_put(odp, op - 1, op);
+ code = idict_put(odp, op - 1, op);
if (code < 0)
return code;
pop(3);
@@ -410,11 +430,13 @@ zforceput(register os_ptr op)
* and should not be accessible by name after initialization.
*/
private int
-zforceundef(register os_ptr op)
+zforceundef(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(op[-1], t_dictionary);
/* Don't check_dict_write */
- dict_undef(op - 1, op); /* ignore undefined error */
+ idict_undef(op - 1, op); /* ignore undefined error */
pop(2);
return 0;
}
@@ -422,8 +444,9 @@ zforceundef(register os_ptr op)
/* <dict> <key> .knownget <value> true */
/* <dict> <key> .knownget false */
private int
-zknownget(register os_ptr op)
+zknownget(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register os_ptr op1 = op - 1;
ref *pvalue;
@@ -441,14 +464,15 @@ zknownget(register os_ptr op)
/* <dict> <key> .knownundef <bool> */
private int
-zknownundef(register os_ptr op)
+zknownundef(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int code;
check_type(*op1, t_dictionary);
check_dict_write(*op1);
- code = dict_undef(op1, op);
+ code = idict_undef(op1, op);
make_bool(op1, code == 0);
pop(1);
return 0;
@@ -456,8 +480,9 @@ zknownundef(register os_ptr op)
/* <dict> <int> .setmaxlength - */
private int
-zsetmaxlength(register os_ptr op)
+zsetmaxlength(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
uint new_size;
int code;
@@ -474,7 +499,7 @@ zsetmaxlength(register os_ptr op)
new_size = (uint) op->value.intval;
if (dict_length(op - 1) > new_size)
return_error(e_dictfull);
- code = dict_resize(op - 1, new_size);
+ code = idict_resize(op - 1, new_size);
if (code >= 0)
pop(2);
return code;
@@ -482,8 +507,8 @@ zsetmaxlength(register os_ptr op)
/* ------ Initialization procedure ------ */
-const op_def zdict_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zdict1_op_defs[] = {
{"0cleardictstack", zcleardictstack},
{"1begin", zbegin},
{"0countdictstack", zcountdictstack},
@@ -497,6 +522,9 @@ const op_def zdict_op_defs[] =
{"1maxlength", zmaxlength},
{"2.undef", zundef}, /* we need this even in Level 1 */
{"1where", zwhere},
+ op_def_end(0)
+};
+const op_def zdict2_op_defs[] = {
/* Extensions */
{"2.dictcopynew", zdictcopynew},
{"1.dicttomark", zdicttomark},
diff --git a/gs/src/zdosio.c b/gs/src/zdosio.c
index acd551b8e..47f01d1b8 100644
--- a/gs/src/zdosio.c
+++ b/gs/src/zdosio.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,8 +26,10 @@
/* <port> .inport <word> */
private int
-zinport(register os_ptr op)
+zinport(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
make_int(op, inport((int)op->value.intval));
return 0;
@@ -35,8 +37,10 @@ zinport(register os_ptr op)
/* <port> .inportb <byte> */
private int
-zinportb(register os_ptr op)
+zinportb(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
make_int(op, inportb((int)op->value.intval));
return 0;
@@ -44,8 +48,10 @@ zinportb(register os_ptr op)
/* <port> <word> .outport - */
private int
-zoutport(register os_ptr op)
+zoutport(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_type(op[-1], t_integer);
outport((int)op[-1].value.intval, (int)op->value.intval);
@@ -55,8 +61,10 @@ zoutport(register os_ptr op)
/* <port> <byte> .outportb - */
private int
-zoutportb(register os_ptr op)
+zoutportb(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_int_leu(op[-1], 0xff);
outportb((int)op[-1].value.intval, (byte) op->value.intval);
@@ -66,8 +74,10 @@ zoutportb(register os_ptr op)
/* <loc> .peek <byte> */
private int
-zpeek(register os_ptr op)
+zpeek(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
make_int(op, *(byte *) (op->value.intval));
return 0;
@@ -75,8 +85,10 @@ zpeek(register os_ptr op)
/* <loc> <byte> .poke - */
private int
-zpoke(register os_ptr op)
+zpoke(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
check_int_leu(op[-1], 0xff);
*(byte *) (op[-1].value.intval) = (byte) op->value.intval;
diff --git a/gs/src/zdouble.c b/gs/src/zdouble.c
index 7e8c70961..3d999678b 100644
--- a/gs/src/zdouble.c
+++ b/gs/src/zdouble.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,10 +40,11 @@
/* Forward references */
private int double_params_result(P3(os_ptr, int, double *));
private int double_params(P3(os_ptr, int, double *));
-private int double_result(P3(os_ptr, int, double));
-private int double_unary(P2(os_ptr, double (*)(P1(double))));
+private int double_result(P3(i_ctx_t *, int, double));
+private int double_unary(P2(i_ctx_t *, double (*)(P1(double))));
#define dbegin_unary()\
+ os_ptr op = osp;\
double num;\
int code = double_params_result(op, 1, &num);\
\
@@ -51,6 +52,7 @@ private int double_unary(P2(os_ptr, double (*)(P1(double))));
return code
#define dbegin_binary()\
+ os_ptr op = osp;\
double num[2];\
int code = double_params_result(op, 2, num);\
\
@@ -61,119 +63,119 @@ private int double_unary(P2(os_ptr, double (*)(P1(double))));
/* <dnum1> <dnum2> <dresult> .dadd <dresult> */
private int
-zdadd(os_ptr op)
+zdadd(i_ctx_t *i_ctx_p)
{
dbegin_binary();
- return double_result(op, 2, num[0] + num[1]);
+ return double_result(i_ctx_p, 2, num[0] + num[1]);
}
/* <dnum1> <dnum2> <dresult> .ddiv <dresult> */
private int
-zddiv(os_ptr op)
+zddiv(i_ctx_t *i_ctx_p)
{
dbegin_binary();
if (num[1] == 0.0)
return_error(e_undefinedresult);
- return double_result(op, 2, num[0] / num[1]);
+ return double_result(i_ctx_p, 2, num[0] / num[1]);
}
/* <dnum1> <dnum2> <dresult> .dmul <dresult> */
private int
-zdmul(os_ptr op)
+zdmul(i_ctx_t *i_ctx_p)
{
dbegin_binary();
- return double_result(op, 2, num[0] * num[1]);
+ return double_result(i_ctx_p, 2, num[0] * num[1]);
}
/* <dnum1> <dnum2> <dresult> .dsub <dresult> */
private int
-zdsub(os_ptr op)
+zdsub(i_ctx_t *i_ctx_p)
{
dbegin_binary();
- return double_result(op, 2, num[0] - num[1]);
+ return double_result(i_ctx_p, 2, num[0] - num[1]);
}
/* ------ Simple functions ------ */
/* <dnum> <dresult> .dabs <dresult> */
private int
-zdabs(os_ptr op)
+zdabs(i_ctx_t *i_ctx_p)
{
- return double_unary(op, fabs);
+ return double_unary(i_ctx_p, fabs);
}
/* <dnum> <dresult> .dceiling <dresult> */
private int
-zdceiling(os_ptr op)
+zdceiling(i_ctx_t *i_ctx_p)
{
- return double_unary(op, ceil);
+ return double_unary(i_ctx_p, ceil);
}
/* <dnum> <dresult> .dfloor <dresult> */
private int
-zdfloor(os_ptr op)
+zdfloor(i_ctx_t *i_ctx_p)
{
- return double_unary(op, floor);
+ return double_unary(i_ctx_p, floor);
}
/* <dnum> <dresult> .dneg <dresult> */
private int
-zdneg(os_ptr op)
+zdneg(i_ctx_t *i_ctx_p)
{
dbegin_unary();
- return double_result(op, 1, -num);
+ return double_result(i_ctx_p, 1, -num);
}
/* <dnum> <dresult> .dround <dresult> */
private int
-zdround(os_ptr op)
+zdround(i_ctx_t *i_ctx_p)
{
dbegin_unary();
- return double_result(op, 1, floor(num + 0.5));
+ return double_result(i_ctx_p, 1, floor(num + 0.5));
}
/* <dnum> <dresult> .dsqrt <dresult> */
private int
-zdsqrt(os_ptr op)
+zdsqrt(i_ctx_t *i_ctx_p)
{
dbegin_unary();
if (num < 0.0)
return_error(e_rangecheck);
- return double_result(op, 1, sqrt(num));
+ return double_result(i_ctx_p, 1, sqrt(num));
}
/* <dnum> <dresult> .dtruncate <dresult> */
private int
-zdtruncate(os_ptr op)
+zdtruncate(i_ctx_t *i_ctx_p)
{
dbegin_unary();
- return double_result(op, 1, (num < 0 ? ceil(num) : floor(num)));
+ return double_result(i_ctx_p, 1, (num < 0 ? ceil(num) : floor(num)));
}
/* ------ Transcendental functions ------ */
private int
-darc(os_ptr op, double (*afunc)(P1(double)))
+darc(i_ctx_t *i_ctx_p, double (*afunc)(P1(double)))
{
dbegin_unary();
- return double_result(op, 1, (*afunc)(num) * radians_to_degrees);
+ return double_result(i_ctx_p, 1, (*afunc)(num) * radians_to_degrees);
}
/* <dnum> <dresult> .darccos <dresult> */
private int
-zdarccos(os_ptr op)
+zdarccos(i_ctx_t *i_ctx_p)
{
- return darc(op, acos);
+ return darc(i_ctx_p, acos);
}
/* <dnum> <dresult> .darcsin <dresult> */
private int
-zdarcsin(os_ptr op)
+zdarcsin(i_ctx_t *i_ctx_p)
{
- return darc(op, asin);
+ return darc(i_ctx_p, asin);
}
/* <dnum> <ddenom> <dresult> .datan <dresult> */
private int
-zdatan(register os_ptr op)
+zdatan(i_ctx_t *i_ctx_p)
{
double result;
@@ -187,19 +189,19 @@ zdatan(register os_ptr op)
if (result < 0)
result += 360;
}
- return double_result(op, 2, result);
+ return double_result(i_ctx_p, 2, result);
}
/* <dnum> <dresult> .dcos <dresult> */
private int
-zdcos(os_ptr op)
+zdcos(i_ctx_t *i_ctx_p)
{
- return double_unary(op, gs_cos_degrees);
+ return double_unary(i_ctx_p, gs_cos_degrees);
}
/* <dbase> <dexponent> <dresult> .dexp <dresult> */
private int
-zdexp(os_ptr op)
+zdexp(i_ctx_t *i_ctx_p)
{
double ipart;
@@ -208,42 +210,43 @@ zdexp(os_ptr op)
return_error(e_undefinedresult);
if (num[0] < 0.0 && modf(num[1], &ipart) != 0.0)
return_error(e_undefinedresult);
- return double_result(op, 2, pow(num[0], num[1]));
+ return double_result(i_ctx_p, 2, pow(num[0], num[1]));
}
private int
-dlog(os_ptr op, double (*lfunc)(P1(double)))
+dlog(i_ctx_t *i_ctx_p, double (*lfunc)(P1(double)))
{
dbegin_unary();
if (num <= 0.0)
return_error(e_rangecheck);
- return double_result(op, 1, (*lfunc)(num));
+ return double_result(i_ctx_p, 1, (*lfunc)(num));
}
/* <dposnum> <dresult> .dln <dresult> */
private int
-zdln(os_ptr op)
+zdln(i_ctx_t *i_ctx_p)
{
- return dlog(op, log);
+ return dlog(i_ctx_p, log);
}
/* <dposnum> <dresult> .dlog <dresult> */
private int
-zdlog(os_ptr op)
+zdlog(i_ctx_t *i_ctx_p)
{
- return dlog(op, log10);
+ return dlog(i_ctx_p, log10);
}
/* <dnum> <dresult> .dsin <dresult> */
private int
-zdsin(os_ptr op)
+zdsin(i_ctx_t *i_ctx_p)
{
- return double_unary(op, gs_sin_degrees);
+ return double_unary(i_ctx_p, gs_sin_degrees);
}
/* ------ Comparison ------ */
private int
-dcompare(os_ptr op, int mask)
+dcompare(i_ctx_t *i_ctx_p, int mask)
{
+ os_ptr op = osp;
double num[2];
int code = double_params(op, 2, num);
@@ -257,39 +260,39 @@ dcompare(os_ptr op, int mask)
}
/* <dnum1> <dnum2> .deq <bool> */
private int
-zdeq(os_ptr op)
+zdeq(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 2);
+ return dcompare(i_ctx_p, 2);
}
/* <dnum1> <dnum2> .dge <bool> */
private int
-zdge(os_ptr op)
+zdge(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 6);
+ return dcompare(i_ctx_p, 6);
}
/* <dnum1> <dnum2> .dgt <bool> */
private int
-zdgt(os_ptr op)
+zdgt(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 4);
+ return dcompare(i_ctx_p, 4);
}
/* <dnum1> <dnum2> .dle <bool> */
private int
-zdle(os_ptr op)
+zdle(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 3);
+ return dcompare(i_ctx_p, 3);
}
/* <dnum1> <dnum2> .dlt <bool> */
private int
-zdlt(os_ptr op)
+zdlt(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 1);
+ return dcompare(i_ctx_p, 1);
}
/* <dnum1> <dnum2> .dne <bool> */
private int
-zdne(os_ptr op)
+zdne(i_ctx_t *i_ctx_p)
{
- return dcompare(op, 5);
+ return dcompare(i_ctx_p, 5);
}
/* ------ Conversion ------ */
@@ -299,16 +302,17 @@ zdne(os_ptr op)
/* <dnum> <dresult> .cvd <dresult> */
private int
-zcvd(os_ptr op)
+zcvd(i_ctx_t *i_ctx_p)
{
dbegin_unary();
- return double_result(op, 1, num);
+ return double_result(i_ctx_p, 1, num);
}
/* <string> <dresult> .cvsd <dresult> */
private int
-zcvsd(os_ptr op)
+zcvsd(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = double_params_result(op, 0, NULL);
double num;
char buf[MAX_CHARS + 2];
@@ -339,13 +343,14 @@ zcvsd(os_ptr op)
strcat(str, "$");
if (sscanf(str, "%lf%c", &num, &end) != 2 || end != '$')
return_error(e_syntaxerror);
- return double_result(op, 1, num);
+ return double_result(i_ctx_p, 1, num);
}
/* <dnum> .dcvi <int> */
private int
-zdcvi(os_ptr op)
+zdcvi(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
#define alt_min_long (-1L << (arch_sizeof_long * 8 - 1))
#define alt_max_long (~(alt_min_long))
static const double min_int_real = (alt_min_long * 1.0 - 1);
@@ -364,8 +369,9 @@ zdcvi(os_ptr op)
/* <dnum> .dcvr <real> */
private int
-zdcvr(os_ptr op)
+zdcvr(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
#define b30 (0x40000000L * 1.0)
#define max_mag (0xffffff * b30 * b30 * b30 * 0x4000)
static const float min_real = -max_mag;
@@ -385,8 +391,9 @@ zdcvr(os_ptr op)
/* <dnum> <string> .dcvs <substring> */
private int
-zdcvs(os_ptr op)
+zdcvs(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num;
int code = double_params(op - 1, 1, &num);
char str[MAX_CHARS + 1];
@@ -424,13 +431,29 @@ zdcvs(os_ptr op)
/* ------ Initialization table ------ */
-const op_def zdouble_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zdouble1_op_defs[] = {
/* Arithmetic */
{"3.dadd", zdadd},
{"3.ddiv", zddiv},
{"3.dmul", zdmul},
{"3.dsub", zdsub},
+ /* Comparison */
+ {"2.deq", zdeq},
+ {"2.dge", zdge},
+ {"2.dgt", zdgt},
+ {"2.dle", zdle},
+ {"2.dlt", zdlt},
+ {"2.dne", zdne},
+ /* Conversion */
+ {"2.cvd", zcvd},
+ {"2.cvsd", zcvsd},
+ {"1.dcvi", zdcvi},
+ {"1.dcvr", zdcvr},
+ {"2.dcvs", zdcvs},
+ op_def_end(0)
+};
+const op_def zdouble2_op_defs[] = {
/* Simple functions */
{"2.dabs", zdabs},
{"2.dceiling", zdceiling},
@@ -448,19 +471,6 @@ const op_def zdouble_op_defs[] =
{"2.dln", zdln},
{"2.dlog", zdlog},
{"2.dsin", zdsin},
- /* Comparison */
- {"2.deq", zdeq},
- {"2.dge", zdge},
- {"2.dgt", zdgt},
- {"2.dle", zdle},
- {"2.dlt", zdlt},
- {"2.dne", zdne},
- /* Conversion */
- {"2.cvd", zcvd},
- {"2.cvsd", zcvsd},
- {"1.dcvi", zdcvi},
- {"1.dcvr", zdcvr},
- {"2.dcvs", zdcvs},
op_def_end(0)
};
@@ -503,14 +513,15 @@ double_params_result(os_ptr op, int count, double *pval)
{
check_write_type(*op, t_string);
if (r_size(op) != sizeof(double))
- return_error(e_typecheck);
+ return_error(e_typecheck);
return double_params(op - 1, count, pval);
}
/* Return a double result. */
private int
-double_result(os_ptr op, int count, double result)
+double_result(i_ctx_t *i_ctx_p, int count, double result)
{
+ os_ptr op = osp;
os_ptr op1 = op - count;
ref_assign_inline(op1, op);
@@ -521,8 +532,8 @@ double_result(os_ptr op, int count, double result)
/* Apply a unary function to a double operand. */
private int
-double_unary(os_ptr op, double (*func)(P1(double)))
+double_unary(i_ctx_t *i_ctx_p, double (*func)(P1(double)))
{
dbegin_unary();
- return double_result(op, 1, (*func)(num));
+ return double_result(i_ctx_p, 1, (*func)(num));
}
diff --git a/gs/src/zdpnext.c b/gs/src/zdpnext.c
index d0eb4dbd5..5c1ced905 100644
--- a/gs/src/zdpnext.c
+++ b/gs/src/zdpnext.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,8 +40,10 @@
/* - currentalpha <alpha> */
private int
-zcurrentalpha(register os_ptr op)
+zcurrentalpha(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentalpha(igs));
return 0;
@@ -49,8 +51,9 @@ zcurrentalpha(register os_ptr op)
/* <alpha> setalpha - */
private int
-zsetalpha(register os_ptr op)
+zsetalpha(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double alpha;
int code;
@@ -75,8 +78,9 @@ zsetalpha(register os_ptr op)
*/
/* Imported procedures */
-int zimage_multiple(P2(os_ptr op, bool has_alpha)); /* in zcolor1.c */
-int process_non_source_image(P2(const gs_image_common_t * pim,
+int zimage_multiple(P2(i_ctx_t *i_ctx_p, bool has_alpha)); /* in zcolor1.c */
+int process_non_source_image(P3(i_ctx_t *i_ctx_p,
+ const gs_image_common_t * pim,
client_name_t cname)); /* in zdps.c */
/*
@@ -92,24 +96,25 @@ typedef struct alpha_composite_state_s {
} alpha_composite_state_t;
/* Forward references */
-private int begin_composite(P1(alpha_composite_state_t *));
-private void end_composite(P1(alpha_composite_state_t *));
+private int begin_composite(P2(i_ctx_t *, alpha_composite_state_t *));
+private void end_composite(P2(i_ctx_t *, alpha_composite_state_t *));
private int rect_param(P2(os_ptr, double[4]));
/* <width> <height> <bits/comp> <matrix> */
/* <datasrc_0> ... <datasrc_ncomp-1> true <ncomp> alphaimage - */
/* <datasrc> false <ncomp> alphaimage - */
private int
-zalphaimage(register os_ptr op)
+zalphaimage(i_ctx_t *i_ctx_p)
{
/* Essentially the whole implementation is shared with colorimage. */
- return zimage_multiple(op, true);
+ return zimage_multiple(i_ctx_p, true);
}
/* <destx> <desty> <width> <height> <op> compositerect - */
private int
-zcompositerect(register os_ptr op)
+zcompositerect(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double dest_rect[4];
alpha_composite_state_t cstate;
int code = rect_param(op - 1, dest_rect);
@@ -118,7 +123,7 @@ zcompositerect(register os_ptr op)
return code;
check_int_leu(*op, compositerect_last);
cstate.params.op = (gs_composite_op_t) op->value.intval;
- code = begin_composite(&cstate);
+ code = begin_composite(i_ctx_p, &cstate);
if (code < 0)
return code;
{
@@ -128,7 +133,7 @@ zcompositerect(register os_ptr op)
rect.q.y = (rect.p.y = dest_rect[1]) + dest_rect[3];
code = gs_rectfill(igs, &rect, 1);
}
- end_composite(&cstate);
+ end_composite(i_ctx_p, &cstate);
if (code >= 0)
pop(5);
return code;
@@ -136,8 +141,9 @@ zcompositerect(register os_ptr op)
/* Common code for composite and dissolve. */
private int
-composite_image(os_ptr op, const gs_composite_alpha_params_t * params)
+composite_image(i_ctx_t *i_ctx_p, const gs_composite_alpha_params_t * params)
{
+ os_ptr op = osp;
alpha_composite_state_t cstate;
gs_image2_t image;
double src_rect[4];
@@ -171,11 +177,12 @@ composite_image(os_ptr op, const gs_composite_alpha_params_t * params)
image.XOrigin -= dest_pt[0];
image.YOrigin -= dest_pt[1];
}
- code = begin_composite(&cstate);
+ code = begin_composite(i_ctx_p, &cstate);
if (code >= 0) {
- code = process_non_source_image((const gs_image_common_t *)&image,
+ code = process_non_source_image(i_ctx_p,
+ (const gs_image_common_t *)&image,
"composite_image");
- end_composite(&cstate);
+ end_composite(i_ctx_p, &cstate);
if (code >= 0)
pop(8);
}
@@ -186,20 +193,22 @@ composite_image(os_ptr op, const gs_composite_alpha_params_t * params)
/* <srcx> <srcy> <width> <height> <srcgstate|null> <destx> <desty> <op> */
/* composite - */
private int
-zcomposite(register os_ptr op)
+zcomposite(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_composite_alpha_params_t params;
check_int_leu(*op, composite_last);
params.op = (gs_composite_op_t) op->value.intval;
- return composite_image(op, &params);
+ return composite_image(i_ctx_p, &params);
}
/* <srcx> <srcy> <width> <height> <srcgstate|null> <destx> <desty> <delta> */
/* dissolve - */
private int
-zdissolve(register os_ptr op)
+zdissolve(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_composite_alpha_params_t params;
double delta;
int code = real_param(op, &delta);
@@ -210,7 +219,7 @@ zdissolve(register os_ptr op)
return_error(e_rangecheck);
params.op = composite_Dissolve;
params.delta = delta;
- return composite_image(op, &params);
+ return composite_image(i_ctx_p, &params);
}
/* ------ Image reading ------ */
@@ -221,8 +230,9 @@ private int device_is_true_color(P1(gx_device * dev));
/* <dev_x> <dev_y> <dev_width> <dev_height> <matrix> */
private void box_confine(P3(int *pp, int *pq, int wh));
private int
-zsizeimagebox(os_ptr op)
+zsizeimagebox(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gx_device *dev = gs_currentdevice(igs);
gs_rect srect, drect;
gs_matrix mat;
@@ -289,8 +299,9 @@ box_confine(int *pp, int *pq, int wh)
/* - .sizeimageparams <bits/sample> <multiproc> <ncolors> */
private int
-zsizeimageparams(register os_ptr op)
+zsizeimageparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
int ncomp = dev->color_info.num_components;
int bps;
@@ -357,11 +368,11 @@ rect_param(os_ptr op, double rect[4])
/* Begin a compositing operation. */
private int
-begin_composite(alpha_composite_state_t * pcp)
+begin_composite(i_ctx_t *i_ctx_p, alpha_composite_state_t * pcp)
{
gx_device *dev = gs_currentdevice(igs);
int code =
- gs_create_composite_alpha(&pcp->pcte, &pcp->params, imemory);
+ gs_create_composite_alpha(&pcp->pcte, &pcp->params, imemory);
if (code < 0)
return code;
@@ -370,7 +381,7 @@ begin_composite(alpha_composite_state_t * pcp)
(dev, &pcp->cdev, pcp->pcte, (const gs_imager_state *)igs,
imemory);
if (code < 0) {
- end_composite(pcp);
+ end_composite(i_ctx_p, pcp);
return code;
}
gs_setdevice_no_init(igs, pcp->cdev);
@@ -379,7 +390,7 @@ begin_composite(alpha_composite_state_t * pcp)
/* End a compositing operation. */
private void
-end_composite(alpha_composite_state_t * pcp)
+end_composite(i_ctx_t *i_ctx_p, alpha_composite_state_t * pcp)
{
/* Close and free the compositor and the compositing object. */
if (pcp->cdev != pcp->orig_dev) {
@@ -463,7 +474,7 @@ device_is_true_color(gx_device * dev)
}
return 1;
default:
- return 0; /* error?! */
+ return 0; /* DeviceN */
}
#undef CV
#undef CV0
diff --git a/gs/src/zdps.c b/gs/src/zdps.c
index a03500374..c8f3d129a 100644
--- a/gs/src/zdps.c
+++ b/gs/src/zdps.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,7 +27,7 @@
#include "gxfixed.h" /* for gxpath.h */
#include "gxpath.h"
#include "btoken.h" /* for user_names_p */
-#include "idict.h"
+#include "iddict.h"
#include "idparam.h"
#include "igstate.h"
#include "iname.h"
@@ -40,8 +40,9 @@ extern int make_upath(P4(ref *, const gs_state *, gx_path *, bool));
/* <screen_index> <x> <y> .setscreenphase - */
private int
-zsetscreenphase(register os_ptr op)
+zsetscreenphase(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
long x, y;
@@ -64,8 +65,9 @@ zsetscreenphase(register os_ptr op)
/* <screen_index> .currentscreenphase <x> <y> */
private int
-zcurrentscreenphase(register os_ptr op)
+zcurrentscreenphase(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_int_point phase;
int code;
@@ -89,7 +91,8 @@ zcurrentscreenphase(register os_ptr op)
/* Process an image that has no explicit source data. */
/* We export this for composite images. */
int
-process_non_source_image(const gs_image_common_t * pic, client_name_t cname)
+process_non_source_image(i_ctx_t *i_ctx_p, const gs_image_common_t * pic,
+ client_name_t cname)
{
gx_image_enum_common_t *pie;
int code = gs_image_begin_typed(pic, igs, false /****** WRONG ******/ ,
@@ -101,8 +104,9 @@ process_non_source_image(const gs_image_common_t * pic, client_name_t cname)
/* <dict> .image2 - */
private int
-zimage2(register os_ptr op)
+zimage2(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(*op, t_dictionary);
@@ -143,7 +147,8 @@ zimage2(register os_ptr op)
} else
image.UnpaintedPath = 0;
}
- code = process_non_source_image((const gs_image_common_t *)&image,
+ code = process_non_source_image(i_ctx_p,
+ (const gs_image_common_t *)&image,
".image2");
if (image.UnpaintedPath) {
ref rupath;
@@ -157,7 +162,7 @@ zimage2(register os_ptr op)
gx_path_free(image.UnpaintedPath, ".image2 UnpaintedPath");
if (code < 0)
return code;
- code = dict_put_string(op, "UnpaintedPath", &rupath);
+ code = idict_put_string(op, "UnpaintedPath", &rupath);
}
}
if (code >= 0)
@@ -169,28 +174,28 @@ zimage2(register os_ptr op)
/* - viewclip - */
private int
-zviewclip(register os_ptr op)
+zviewclip(i_ctx_t *i_ctx_p)
{
return gs_viewclip(igs);
}
/* - eoviewclip - */
private int
-zeoviewclip(register os_ptr op)
+zeoviewclip(i_ctx_t *i_ctx_p)
{
return gs_eoviewclip(igs);
}
/* - initviewclip - */
private int
-zinitviewclip(register os_ptr op)
+zinitviewclip(i_ctx_t *i_ctx_p)
{
return gs_initviewclip(igs);
}
/* - viewclippath - */
private int
-zviewclippath(register os_ptr op)
+zviewclippath(i_ctx_t *i_ctx_p)
{
return gs_viewclippath(igs);
}
@@ -199,8 +204,9 @@ zviewclippath(register os_ptr op)
/* <index> <name> defineusername - */
private int
-zdefineusername(register os_ptr op)
+zdefineusername(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref uname;
check_int_ltu(op[-1], max_array_size);
diff --git a/gs/src/zdps1.c b/gs/src/zdps1.c
index 1f12c6b92..6985749ec 100644
--- a/gs/src/zdps1.c
+++ b/gs/src/zdps1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,23 +41,26 @@ public_st_igstate_obj();
/* This is done with a hack -- we know that gstates are the only */
/* t_astruct subtype that implements copy. */
private int
-z1copy(register os_ptr op)
+z1copy(i_ctx_t *i_ctx_p)
{
- int code = zcopy(op);
+ os_ptr op = osp;
+ int code = zcopy(i_ctx_p);
if (code >= 0)
return code;
if (!r_has_type(op, t_astruct))
return code;
- return zcopy_gstate(op);
+ return zcopy_gstate(i_ctx_p);
}
/* ------ Graphics state ------ */
/* <bool> setstrokeadjust - */
private int
-zsetstrokeadjust(register os_ptr op)
+zsetstrokeadjust(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_setstrokeadjust(igs, op->value.boolval);
pop(1);
@@ -66,8 +69,10 @@ zsetstrokeadjust(register os_ptr op)
/* - currentstrokeadjust <bool> */
private int
-zcurrentstrokeadjust(register os_ptr op)
+zcurrentstrokeadjust(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currentstrokeadjust(igs));
return 0;
@@ -89,8 +94,10 @@ gstate_check_space(int_gstate * isp, uint space)
/* - gstate <gstate> */
int
-zgstate(register os_ptr op)
+zgstate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
int code = gstate_check_space(istate, icurrent_space);
igstate_obj *pigo;
gs_state *pnew;
@@ -123,8 +130,9 @@ zgstate(register os_ptr op)
/* copy for gstates */
int
-zcopy_gstate(register os_ptr op)
+zcopy_gstate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
gs_state *pgs;
gs_state *pgs1;
@@ -160,8 +168,9 @@ zcopy_gstate(register os_ptr op)
/* <gstate> currentgstate <gstate> */
int
-zcurrentgstate(register os_ptr op)
+zcurrentgstate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_state *pgs;
int_gstate *pistate;
int code;
@@ -191,8 +200,9 @@ zcurrentgstate(register os_ptr op)
/* <gstate> setgstate - */
int
-zsetgstate(register os_ptr op)
+zsetgstate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_stype(*op, st_igstate_obj);
@@ -224,8 +234,9 @@ private void rect_release(P1(local_rects_t *));
/* <x> <y> <width> <height> .rectappend - */
/* <numarray|numstring> .rectappend - */
private int
-zrectappend(os_ptr op)
+zrectappend(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
local_rects_t lr;
int npop = rect_get(&lr, op);
int code;
@@ -243,8 +254,9 @@ zrectappend(os_ptr op)
/* <x> <y> <width> <height> rectclip - */
/* <numarray|numstring> rectclip - */
private int
-zrectclip(os_ptr op)
+zrectclip(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
local_rects_t lr;
int npop = rect_get(&lr, op);
int code;
@@ -262,8 +274,9 @@ zrectclip(os_ptr op)
/* <x> <y> <width> <height> rectfill - */
/* <numarray|numstring> rectfill - */
private int
-zrectfill(os_ptr op)
+zrectfill(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
local_rects_t lr;
int npop = rect_get(&lr, op);
int code;
@@ -281,8 +294,9 @@ zrectfill(os_ptr op)
/* <x> <y> <width> <height> rectstroke - */
/* <numarray|numstring> rectstroke - */
private int
-zrectstroke(os_ptr op)
+zrectstroke(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
local_rects_t lr;
int npop, code;
@@ -390,8 +404,9 @@ rect_release(local_rects_t * plr)
/* <llx> <lly> <urx> <ury> setbbox - */
int
-zsetbbox(register os_ptr op)
+zsetbbox(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double box[4];
int code = num_params(op, 4, box);
diff --git a/gs/src/zfbcp.c b/gs/src/zfbcp.c
index 76056378a..e71c7a2e4 100644
--- a/gs/src/zfbcp.c
+++ b/gs/src/zfbcp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -43,41 +43,41 @@ no_bcp_request_status(stream_state * st)
/* <source> BCPEncode/filter <file> */
/* <source> <dict> BCPEncode/filter <file> */
private int
-zBCPE(os_ptr op)
+zBCPE(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_BCPE_template);
+ return filter_write_simple(i_ctx_p, &s_BCPE_template);
}
/* <target> BCPDecode/filter <file> */
/* <target> <dict> BCPDecode/filter <file> */
private int
-zBCPD(os_ptr op)
+zBCPD(i_ctx_t *i_ctx_p)
{
stream_BCPD_state state;
state.signal_interrupt = no_bcp_signal_interrupt;
state.request_status = no_bcp_request_status;
- return filter_read(op, 0, &s_BCPD_template, (stream_state *) & state, 0);
+ return filter_read(i_ctx_p, 0, &s_BCPD_template, (stream_state *)&state, 0);
}
/* <source> TBCPEncode/filter <file> */
/* <source> <dict> TBCPEncode/filter <file> */
private int
-zTBCPE(os_ptr op)
+zTBCPE(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_TBCPE_template);
+ return filter_write_simple(i_ctx_p, &s_TBCPE_template);
}
/* <target> TBCPDecode/filter <file> */
/* <target> <dict> TBCPDecode/filter <file> */
private int
-zTBCPD(os_ptr op)
+zTBCPD(i_ctx_t *i_ctx_p)
{
stream_BCPD_state state;
state.signal_interrupt = no_bcp_signal_interrupt;
state.request_status = no_bcp_request_status;
- return filter_read(op, 0, &s_TBCPD_template, (stream_state *)&state, 0);
+ return filter_read(i_ctx_p, 0, &s_TBCPD_template, (stream_state *)&state, 0);
}
/* ------ Initialization procedure ------ */
diff --git a/gs/src/zfcmap.c b/gs/src/zfcmap.c
index 01a815d49..7429d6410 100644
--- a/gs/src/zfcmap.c
+++ b/gs/src/zfcmap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,7 +26,7 @@
#include "gxfcmap.h"
#include "gxfont.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "idparam.h"
#include "ifont.h" /* for zfont_mark_glyph_name */
#include "iname.h"
@@ -49,8 +49,9 @@ free_code_map(gx_code_map * pcmap, gs_memory_t * mem)
/* Convert a code map to internal form. */
private int
-acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
- gs_cmap * root, gs_memory_t * mem)
+acquire_code_map(gx_code_map * pcmap, const ref * pref,
+ const ref *pfxref, int depth, gs_cmap * root,
+ gs_memory_t * mem)
{
pcmap->add_offset = 0;
pcmap->cmap = root;
@@ -59,10 +60,19 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
case t_null:
pcmap->type = cmap_glyph;
pcmap->data.glyph = gs_no_glyph;
+ pcmap->byte_data.font_index = 0;
return 0;
case t_name:
pcmap->type = cmap_glyph;
pcmap->data.glyph = name_index(pref);
+leaf: if (!r_has_type(pfxref, t_integer)) {
+ break;
+ } else {
+ pcmap->byte_data.font_index = pfxref->value.intval;
+ /* Check for overflow. */
+ if (pcmap->byte_data.font_index != pfxref->value.intval)
+ break;
+ }
return 0;
case t_integer:
if (pref->value.intval < 0 ||
@@ -71,7 +81,7 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
break;
pcmap->type = cmap_glyph;
pcmap->data.glyph = pref->value.intval + gs_min_cid_glyph;
- return 0;
+ goto leaf;
case t_string:
if (r_size(pref) < 1 || r_size(pref) > 4)
break;
@@ -85,10 +95,14 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
chr = (chr << 8) + pref->value.const_bytes[i];
pcmap->data.ccode = chr;
}
- return 0;
+ goto leaf;
default:
if (!r_is_array(pref) || r_size(pref) < 1 || r_size(pref) > 256)
break;
+ if (!r_has_type(pfxref, t_integer) &&
+ (!r_is_array(pfxref) || r_size(pfxref) < 1 ||
+ r_size(pfxref) > 256))
+ break;
if (depth >= 4)
return_error(e_limitcheck);
{
@@ -157,6 +171,7 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
for (rtype = t_null, i = j = 0; i < size; ++i) {
ref_type prev_type = rtype;
gx_code_map *submap = &subtree[j];
+ ref rfxsub;
int code;
array_get(pref, (long)i, &rsub);
@@ -183,8 +198,12 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
prev_value = rsub.value.intval;
/* falls through */
default:
- code = acquire_code_map(submap, &rsub, depth + 1,
- root, mem);
+ if (r_has_type(pfxref, t_array))
+ array_get(pfxref, (long)i, &rfxsub);
+ else
+ rfxsub = *pfxref;
+ code = acquire_code_map(submap, &rsub, &rfxsub,
+ depth + 1, root, mem);
if (code < 0) { /* Release allocated elements. */
pcmap->byte_data.count1 = (j ? j - 1 : 0);
free_code_map(pcmap, mem);
@@ -201,26 +220,54 @@ acquire_code_map(gx_code_map * pcmap, const ref * pref, int depth,
return_error(e_rangecheck);
}
-/* Acquire CIDSystemInfo. If missing, set Registry and Ordering to */
-/* empty strings and Supplement to 0, and return 1. */
-/* Note that this currently does not handle the array format. */
+/*
+ * Acquire the CIDSystemInfo array from a dictionary. If missing, fabricate
+ * a 0-element array and return 1.
+ */
private int
-acquire_cid_system_info(gs_cid_system_info * pcidsi, const ref * op)
+acquire_cid_system_info(ref *psia, const ref *op)
{
ref *prcidsi;
+
+ if (dict_find_string(op, "CIDSystemInfo", &prcidsi) <= 0) {
+ make_empty_array(psia, a_readonly);
+ return 1;
+ }
+ if (r_has_type(prcidsi, t_dictionary)) {
+ make_array(psia, a_readonly, 1, prcidsi);
+ return 0;
+ }
+ if (!r_is_array(prcidsi))
+ return_error(e_typecheck);
+ *psia = *prcidsi;
+ return 0;
+}
+
+/*
+ * Get one element of a CIDSystemInfo array. If the element is missing or
+ * null (apparently Adobe interpreters accept null, even though the
+ * documentation doesn't allow this), fill in dummy values and return 1.
+ */
+private int
+get_cid_system_info(gs_cid_system_info * pcidsi, const ref * psia, uint index)
+{
+ ref rcidsi;
ref *pregistry;
ref *pordering;
+ int code;
- if (dict_find_string(op, "CIDSystemInfo", &prcidsi) <= 0) {
+ code = array_get(psia, (long)index, &rcidsi);
+ if (code < 0 || r_has_type(&rcidsi, t_null)) {
+ /* Return a null value. */
pcidsi->Registry.data = 0, pcidsi->Registry.size = 0;
pcidsi->Ordering.data = 0, pcidsi->Ordering.size = 0;
pcidsi->Supplement = 0;
return 1;
}
- if (!r_has_type(prcidsi, t_dictionary))
+ if (!r_has_type(&rcidsi, t_dictionary))
return_error(e_typecheck);
- if (dict_find_string(prcidsi, "Registry", &pregistry) <= 0 ||
- dict_find_string(prcidsi, "Ordering", &pordering) <= 0
+ if (dict_find_string(&rcidsi, "Registry", &pregistry) <= 0 ||
+ dict_find_string(&rcidsi, "Ordering", &pordering) <= 0
)
return_error(e_rangecheck);
check_read_type_only(*pregistry, t_string);
@@ -229,8 +276,9 @@ acquire_cid_system_info(gs_cid_system_info * pcidsi, const ref * op)
pcidsi->Registry.size = r_size(pregistry);
pcidsi->Ordering.data = pordering->value.const_bytes;
pcidsi->Ordering.size = r_size(pordering);
- return dict_int_param(prcidsi, "Supplement", 0, max_int, -1,
+ code = dict_int_param(&rcidsi, "Supplement", 0, max_int, -1,
&pcidsi->Supplement);
+ return (code < 0 ? code : 0);
}
/* Check compatibility of CIDSystemInfo. */
@@ -253,14 +301,14 @@ cid_system_info_compatible(const gs_cid_system_info * psi1,
/* Get the CodeMap from a Type 0 font, and check the CIDSystemInfo of */
/* its subsidiary fonts. */
int
-ztype0_get_cmap(const gs_cmap ** ppcmap, const ref * pfdepvector, const ref * op)
+ztype0_get_cmap(const gs_cmap **ppcmap, const ref *pfdepvector, const ref *op)
{
ref *prcmap;
ref *pcodemap;
const gs_cmap *pcmap;
int code;
- ref rfdep;
- gs_cid_system_info cidsi;
+ uint num_fonts;
+ uint i;
if (dict_find_string(op, "CMap", &prcmap) <= 0 ||
!r_has_type(prcmap, t_dictionary) ||
@@ -269,17 +317,23 @@ ztype0_get_cmap(const gs_cmap ** ppcmap, const ref * pfdepvector, const ref * op
)
return_error(e_invalidfont);
pcmap = r_ptr(pcodemap, gs_cmap);
- /* Currently we only handle 1-element fonts. */
- if (r_size(pfdepvector) != 1)
- return_error(e_rangecheck);
- array_get(pfdepvector, 0L, &rfdep);
- code = acquire_cid_system_info(&cidsi, &rfdep);
- if (code < 0)
- return code;
- if (code == 0 &&
- !cid_system_info_compatible(&cidsi, &pcmap->CIDSystemInfo)
- )
- return_error(e_rangecheck);
+ num_fonts = r_size(pfdepvector);
+ for (i = 0; i < num_fonts; ++i) {
+ ref rfdep, rfsi;
+ gs_cid_system_info cidsi;
+
+ array_get(pfdepvector, (long)i, &rfdep);
+ code = acquire_cid_system_info(&rfsi, &rfdep);
+ if (code < 0)
+ return code;
+ if (code == 0) {
+ if (r_size(&rfsi) != 1)
+ return_error(e_rangecheck);
+ get_cid_system_info(&cidsi, &rfsi, 0);
+ if (!cid_system_info_compatible(&cidsi, pcmap->CIDSystemInfo + i))
+ return_error(e_rangecheck);
+ }
+ }
*ppcmap = pcmap;
return 0;
}
@@ -291,15 +345,23 @@ ztype0_get_cmap(const gs_cmap ** ppcmap, const ref * pfdepvector, const ref * op
* Create the internal form of a CMap. The initial CMap must be read-write
* and have an entry with key = CodeMap and value = null; the result is
* read-only and has a real CodeMap.
+ *
+ * This operator reads the CIDSystemInfo, WMode, .CodeMaps, and .FontIndices
+ * elements of the CMap dictionary. For details, see lib/gs_cmap.ps.
*/
private int
-zbuildcmap(os_ptr op)
+zbuildcmap(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
ref *pcodemaps;
+ ref *pfontindices;
ref *pcodemap;
- gs_cmap *pcmap;
- ref rdef, rnotdef, rcmap;
+ ref rcidsi;
+ gs_cmap *pcmap = 0;
+ gs_cid_system_info *pcidsi = 0;
+ ref rdef, rfxdef, rcmap;
+ uint i;
check_type(*op, t_dictionary);
check_dict_write(*op);
@@ -308,35 +370,55 @@ zbuildcmap(os_ptr op)
code = gs_note_error(e_VMerror);
goto fail;
}
- if ((code = dict_uid_param(op, &pcmap->uid, 0, imemory)) < 0 ||
+ if ((code = dict_uid_param(op, &pcmap->uid, 0, imemory, i_ctx_p)) < 0 ||
(code = dict_int_param(op, "WMode", 0, 1, 0, &pcmap->WMode)) < 0
)
goto fail;
if (dict_find_string(op, ".CodeMaps", &pcodemaps) <= 0 ||
!r_has_type(pcodemaps, t_array) ||
r_size(pcodemaps) != 2 ||
+ dict_find_string(op, ".FontIndices", &pfontindices) <= 0 ||
+ !r_has_type(pfontindices, t_array) ||
+ r_size(pfontindices) != 2 ||
dict_find_string(op, "CodeMap", &pcodemap) <= 0 ||
!r_has_type(pcodemap, t_null)
) {
code = gs_note_error(e_rangecheck);
goto fail;
}
- if ((code = acquire_cid_system_info(&pcmap->CIDSystemInfo, op)) < 0 ||
- (array_get(pcodemaps, 0L, &rdef),
- (code = acquire_code_map(&pcmap->def, &rdef, 0, pcmap, imemory)) < 0) ||
- (array_get(pcodemaps, 1L, &rnotdef),
- (code = acquire_code_map(&pcmap->notdef, &rnotdef, 0, pcmap, imemory)) < 0)
- )
+ if ((code = acquire_cid_system_info(&rcidsi, op)) < 0)
+ goto fail;
+ pcidsi = ialloc_struct_array(r_size(&rcidsi), gs_cid_system_info,
+ &st_cid_system_info_element,
+ "zbuildcmap(CIDSystemInfo)");
+ if (pcidsi == 0) {
+ code = gs_note_error(e_VMerror);
+ goto fail;
+ }
+ pcmap->CIDSystemInfo = pcidsi;
+ for (i = 0; i < r_size(&rcidsi); ++i) {
+ code = get_cid_system_info(pcidsi + i, &rcidsi, i);
+ if (code < 0)
+ goto fail;
+ }
+ array_get(pcodemaps, 0L, &rdef);
+ array_get(pfontindices, 0L, &rfxdef);
+ if ((code = acquire_code_map(&pcmap->def, &rdef, &rfxdef, 0, pcmap, imemory)) < 0)
+ goto fail;
+ array_get(pcodemaps, 1L, &rdef);
+ array_get(pfontindices, 1L, &rfxdef);
+ if ((code = acquire_code_map(&pcmap->notdef, &rdef, &rfxdef, 0, pcmap, imemory)) < 0)
goto fail;
pcmap->mark_glyph = zfont_mark_glyph_name;
pcmap->mark_glyph_data = 0;
make_istruct_new(&rcmap, a_readonly, pcmap);
- code = dict_put_string(op, "CodeMap", &rcmap);
+ code = idict_put_string(op, "CodeMap", &rcmap);
if (code < 0)
goto fail;
- return zreadonly(op);
+ return zreadonly(i_ctx_p);
fail:
ifree_object(pcmap, "zbuildcmap(cmap)");
+ ifree_object(pcidsi, "zbuildcmap(CIDSystemInfo)");
return code;
}
diff --git a/gs/src/zfdctd.c b/gs/src/zfdctd.c
index 06b1d94cf..1045d9b41 100644
--- a/gs/src/zfdctd.c
+++ b/gs/src/zfdctd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,7 +20,7 @@
/* DCTDecode filter creation */
#include "memory_.h"
#include "stdio_.h" /* for jpeglib.h */
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "ghost.h"
#include "oper.h"
#include "gsmalloc.h" /* for gs_memory_default */
@@ -37,8 +37,9 @@ stream_state_proc_put_params(s_DCTD_put_params, stream_DCT_state);
/* <source> <dict> DCTDecode/filter <file> */
/* <source> DCTDecode/filter <file> */
private int
-zDCTD(os_ptr op)
+zDCTD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_memory_t *mem = &gs_memory_default;
stream_DCT_state state;
dict_param_list list;
@@ -72,7 +73,7 @@ zDCTD(os_ptr op)
goto rel;
/* Create the filter. */
jddp->template = s_DCTD_template;
- code = filter_read(op, npop, &jddp->template,
+ code = filter_read(i_ctx_p, npop, &jddp->template,
(stream_state *) & state, dspace);
if (code >= 0) /* Success! */
return code;
diff --git a/gs/src/zfdcte.c b/gs/src/zfdcte.c
index a6db4be79..e7398c7a5 100644
--- a/gs/src/zfdcte.c
+++ b/gs/src/zfdcte.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,7 +20,7 @@
/* DCTEncode filter creation */
#include "memory_.h"
#include "stdio_.h" /* for jpeglib.h */
-#include "jpeglib.h"
+#include "jpeglib_.h"
#include "ghost.h"
#include "oper.h"
#include "gsmalloc.h" /* for gs_memory_default */
@@ -43,8 +43,9 @@ stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state);
/* <target> <dict> DCTEncode/filter <file> */
private int
-zDCTE(os_ptr op)
+zDCTE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_memory_t *mem = &gs_memory_default;
stream_DCT_state state;
dict_param_list list;
@@ -85,7 +86,7 @@ zDCTE(os_ptr op)
/* Make sure we can write the user markers in a single go. */
jcdp->template.min_out_size =
max(s_DCTE_template.min_out_size, state.Markers.size);
- code = filter_write(op, npop, &jcdp->template,
+ code = filter_write(i_ctx_p, npop, &jcdp->template,
(stream_state *) & state, dspace);
if (code >= 0) /* Success! */
return code;
@@ -106,8 +107,9 @@ fail:
#include "files.h"
/* <dict> <filter> <bool> .dcteparams <dict> */
private int
-zdcteparams(os_ptr op)
+zdcteparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
dict_param_list list;
int code;
diff --git a/gs/src/zfdecode.c b/gs/src/zfdecode.c
index 4ff28856a..a5c1dfde3 100644
--- a/gs/src/zfdecode.c
+++ b/gs/src/zfdecode.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -40,16 +40,6 @@
#include "spngpx.h"
#include "ifilter.h"
-/* Import the Level 2 scanner extensions. */
-extern const stream_template *scan_ascii85_template;
-
-/* Initialize the Level 2 scanner for ASCII85 strings. */
-private void
-zfdecode_init(void)
-{
- scan_ascii85_template = &s_A85D_template;
-}
-
/* ------ ASCII85 filters ------ */
/* We include both encoding and decoding filters here, */
@@ -58,17 +48,17 @@ zfdecode_init(void)
/* <target> ASCII85Encode/filter <file> */
/* <target> <dict> ASCII85Encode/filter <file> */
private int
-zA85E(os_ptr op)
+zA85E(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_A85E_template);
+ return filter_write_simple(i_ctx_p, &s_A85E_template);
}
/* <source> ASCII85Decode/filter <file> */
/* <source> <dict> ASCII85Decode/filter <file> */
private int
-zA85D(os_ptr op)
+zA85D(i_ctx_t *i_ctx_p)
{
- return filter_read_simple(op, &s_A85D_template);
+ return filter_read_simple(i_ctx_p, &s_A85D_template);
}
/* ------ CCITTFaxDecode filter ------ */
@@ -92,8 +82,9 @@ zcf_setup(os_ptr op, stream_CF_state * pcfs)
/* <source> <dict> CCITTFaxDecode/filter <file> */
/* <source> CCITTFaxDecode/filter <file> */
private int
-zCFD(os_ptr op)
+zCFD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr dop;
stream_CFD_state cfs;
int code;
@@ -106,7 +97,7 @@ zCFD(os_ptr op)
code = zcf_setup(dop, (stream_CF_state *) & cfs);
if (code < 0)
return code;
- return filter_read(op, 0, &s_CFD_template, (stream_state *) & cfs, 0);
+ return filter_read(i_ctx_p, 0, &s_CFD_template, (stream_state *) & cfs, 0);
}
/* ------ Common setup for possibly pixel-oriented decoding filters ------ */
@@ -116,9 +107,10 @@ int zpd_setup(P2(os_ptr op, stream_PDiff_state * ppds));
int zpp_setup(P2(os_ptr op, stream_PNGP_state * ppps));
int
-filter_read_predictor(os_ptr op, int npop, const stream_template * template,
- stream_state * st)
+filter_read_predictor(i_ctx_t *i_ctx_p, int npop,
+ const stream_template * template, stream_state * st)
{
+ os_ptr op = osp;
int predictor, code;
stream_PDiff_state pds;
stream_PNGP_state pps;
@@ -151,7 +143,7 @@ filter_read_predictor(os_ptr op, int npop, const stream_template * template,
} else
predictor = 1;
if (predictor == 1)
- return filter_read(op, npop, template, st, 0);
+ return filter_read(i_ctx_p, npop, template, st, 0);
{
/* We need to cascade filters. */
ref rsource, rdict, rfd;
@@ -160,7 +152,7 @@ filter_read_predictor(os_ptr op, int npop, const stream_template * template,
/* Save the operands, just in case. */
ref_assign(&rsource, op - 1);
ref_assign(&rdict, op);
- code = filter_read(op, 1, template, st, 0);
+ code = filter_read(i_ctx_p, 1, template, st, 0);
if (code < 0)
return code;
/* filter_read changed osp.... */
@@ -168,8 +160,8 @@ filter_read_predictor(os_ptr op, int npop, const stream_template * template,
ref_assign(&rfd, op);
code =
(predictor == 2 ?
- filter_read(op, 0, &s_PDiffD_template, (stream_state *) & pds, 0) :
- filter_read(op, 0, &s_PNGPD_template, (stream_state *) & pps, 0));
+ filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0) :
+ filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0));
if (code < 0) {
/* Restore the operands. Don't bother trying to clean up */
/* the first stream. */
@@ -218,8 +210,9 @@ zlz_setup(os_ptr op, stream_LZW_state * plzs)
/* <source> LZWDecode/filter <file> */
/* <source> <dict> LZWDecode/filter <file> */
private int
-zLZWD(os_ptr op)
+zLZWD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_LZW_state lzs;
int code = zlz_setup(op, &lzs);
@@ -237,7 +230,7 @@ zLZWD(os_ptr op)
if (code == 0 /* UnitSize specified */ )
lzs.InitialCodeLength = unit_size + 1;
}
- return filter_read_predictor(op, 0, &s_LZWD_template,
+ return filter_read_predictor(i_ctx_p, 0, &s_LZWD_template,
(stream_state *) & lzs);
}
@@ -254,7 +247,7 @@ zpd_setup(os_ptr op, stream_PDiff_state * ppds)
check_type(*op, t_dictionary);
check_dict_read(*op);
- if ((code = dict_int_param(op, "Colors", 1, 4, 1,
+ if ((code = dict_int_param(op, "Colors", 1, s_PDiff_max_Colors, 1,
&ppds->Colors)) < 0 ||
(code = dict_int_param(op, "BitsPerComponent", 1, 8, 8,
&bpc)) < 0 ||
@@ -269,26 +262,28 @@ zpd_setup(os_ptr op, stream_PDiff_state * ppds)
/* <target> <dict> PixelDifferenceEncode/filter <file> */
private int
-zPDiffE(os_ptr op)
+zPDiffE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_PDiff_state pds;
int code = zpd_setup(op, &pds);
if (code < 0)
return code;
- return filter_write(op, 0, &s_PDiffE_template, (stream_state *) & pds, 0);
+ return filter_write(i_ctx_p, 0, &s_PDiffE_template, (stream_state *) & pds, 0);
}
/* <source> <dict> PixelDifferenceDecode/filter <file> */
private int
-zPDiffD(os_ptr op)
+zPDiffD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_PDiff_state pds;
int code = zpd_setup(op, &pds);
if (code < 0)
return code;
- return filter_read(op, 0, &s_PDiffD_template, (stream_state *) & pds, 0);
+ return filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0);
}
/* ------ PNG pixel predictor filters ------ */
@@ -318,32 +313,33 @@ zpp_setup(os_ptr op, stream_PNGP_state * ppps)
/* <target> <dict> PNGPredictorEncode/filter <file> */
private int
-zPNGPE(os_ptr op)
+zPNGPE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_PNGP_state pps;
int code = zpp_setup(op, &pps);
if (code < 0)
return code;
- return filter_write(op, 0, &s_PNGPE_template, (stream_state *) & pps, 0);
+ return filter_write(i_ctx_p, 0, &s_PNGPE_template, (stream_state *) & pps, 0);
}
/* <source> <dict> PNGPredictorDecode/filter <file> */
private int
-zPNGPD(os_ptr op)
+zPNGPD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_PNGP_state pps;
int code = zpp_setup(op, &pps);
if (code < 0)
return code;
- return filter_read(op, 0, &s_PNGPD_template, (stream_state *) & pps, 0);
+ return filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0);
}
/* ---------------- Initialization procedure ---------------- */
-const op_def zfdecode_op_defs[] =
-{
+const op_def zfdecode_op_defs[] = {
op_def_begin_filter(),
{"1ASCII85Encode", zA85E},
{"1ASCII85Decode", zA85D},
@@ -353,5 +349,5 @@ const op_def zfdecode_op_defs[] =
{"2PixelDifferenceEncode", zPDiffE},
{"2PNGPredictorDecode", zPNGPD},
{"2PNGPredictorEncode", zPNGPE},
- op_def_end(zfdecode_init)
+ op_def_end(0)
};
diff --git a/gs/src/zfile.c b/gs/src/zfile.c
index d75f2cbec..414694bd5 100644
--- a/gs/src/zfile.c
+++ b/gs/src/zfile.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -48,12 +48,15 @@ extern iodev_proc_open_file(iodev_os_open_file);
/* Import the IODevice table. */
extern_gx_io_device_table();
+/* Import the dtype of the stdio IODevices. */
+extern const char iodev_dtype_stdio[];
+
/* Forward references: file opening. */
int file_open(P6(const byte *, uint, const char *, uint, ref *, stream **));
/* Forward references: other. */
-private int execfile_finish(P1(os_ptr));
-private int execfile_cleanup(P1(os_ptr));
+private int execfile_finish(P1(i_ctx_t *));
+private int execfile_cleanup(P1(i_ctx_t *));
/*
* Since there can be many file objects referring to the same file/stream,
@@ -98,37 +101,38 @@ private int execfile_cleanup(P1(os_ptr));
const uint file_default_buffer_size = DEFAULT_BUFFER_SIZE;
/* An invalid file object */
-stream *invalid_file_entry; /* exported for zfileio.c */
+private stream invalid_file_stream;
+stream *const invalid_file_entry = &invalid_file_stream;
/* Initialize the file table */
-private void
-zfile_init(void)
+private int
+zfile_init(i_ctx_t *i_ctx_p)
{
/* Create and initialize an invalid (closed) stream. */
/* Initialize the stream for the sake of the GC, */
/* and so it can act as an empty input stream. */
- stream *s = s_alloc(imemory_system, "zfile_init");
+ stream *const s = &invalid_file_stream;
+ s_init(s, NULL);
sread_string(s, NULL, 0);
s->next = s->prev = 0;
s_init_no_id(s);
- invalid_file_entry = s;
- gs_register_struct_root(imemory, NULL, (void **)&invalid_file_entry,
- "invalid_file_entry");
+ return 0;
}
/* Make an invalid file object. */
void
make_invalid_file(ref * fp)
{
- make_file(fp, avm_system, ~0, invalid_file_entry);
+ make_file(fp, avm_invalid_file_entry, ~0, invalid_file_entry);
}
/* <name_string> <access_string> file <file> */
int
-zfile(register os_ptr op)
+zfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
char file_access[3];
parsed_file_name pname;
const byte *astr;
@@ -162,18 +166,33 @@ zfile(register os_ptr op)
code = parse_file_name(op - 1, &pname);
if (code < 0)
return code;
- if (pname.iodev == NULL)
- pname.iodev = iodev_default;
- if (pname.fname == NULL) /* just a device */
+ /*
+ * HACK: temporarily patch the current context pointer into the
+ * state pointer for stdio-related devices. See ziodev.c for
+ * more information.
+ */
+ if (pname.iodev && pname.iodev->dtype == iodev_dtype_stdio) {
+ if (pname.fname)
+ return_error(e_invalidfileaccess);
+ pname.iodev->state = i_ctx_p;
code = (*pname.iodev->procs.open_device)(pname.iodev,
file_access, &s, imemory);
- else { /* file */
- iodev_proc_open_file((*open_file)) =
- pname.iodev->procs.open_file;
- if (open_file == 0)
- open_file = iodev_os_open_file;
- code = (*open_file)(pname.iodev, pname.fname, pname.len,
- file_access, &s, imemory);
+ pname.iodev->state = NULL;
+ } else {
+ if (pname.iodev == NULL)
+ pname.iodev = iodev_default;
+ if (pname.fname == NULL) /* just a device */
+ code = (*pname.iodev->procs.open_device)(pname.iodev,
+ file_access, &s, imemory);
+ else { /* file */
+ iodev_proc_open_file((*open_file)) =
+ pname.iodev->procs.open_file;
+
+ if (open_file == 0)
+ open_file = iodev_os_open_file;
+ code = (*open_file)(pname.iodev, pname.fname, pname.len,
+ file_access, &s, imemory);
+ }
}
if (code < 0)
return code;
@@ -186,8 +205,9 @@ zfile(register os_ptr op)
/* <string> deletefile - */
private int
-zdeletefile(register os_ptr op)
+zdeletefile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
parsed_file_name pname;
int code = parse_real_file_name(op, &pname, "deletefile");
@@ -203,11 +223,12 @@ zdeletefile(register os_ptr op)
/* <template> <proc> <scratch> filenameforall - */
/****** NOT CONVERTED FOR IODEVICES YET ******/
-private int file_continue(P1(os_ptr));
-private int file_cleanup(P1(os_ptr));
+private int file_continue(P1(i_ctx_t *));
+private int file_cleanup(P1(i_ctx_t *));
private int
-zfilenameforall(register os_ptr op)
+zfilenameforall(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
file_enum *pfen;
int code;
@@ -227,14 +248,14 @@ zfilenameforall(register os_ptr op)
make_istruct(esp, 0, pfen);
*++esp = op[-1];
pop(3);
- op -= 3;
- code = file_continue(op);
+ code = file_continue(i_ctx_p);
return (code == o_pop_estack ? o_push_estack : code);
}
/* Continuation operator for enumerating files */
private int
-file_continue(register os_ptr op)
+file_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr pscratch = esp - 2;
file_enum *pfen = r_ptr(esp - 1, file_enum);
uint len = r_size(pscratch);
@@ -257,7 +278,7 @@ file_continue(register os_ptr op)
}
/* Cleanup procedure for enumerating files */
private int
-file_cleanup(os_ptr op)
+file_cleanup(i_ctx_t *i_ctx_p)
{
gp_enumerate_files_close(r_ptr(esp + 4, file_enum));
return 0;
@@ -265,8 +286,9 @@ file_cleanup(os_ptr op)
/* <string1> <string2> renamefile - */
private int
-zrenamefile(register os_ptr op)
+zrenamefile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
parsed_file_name pname1, pname2;
int code = parse_real_file_name(op - 1, &pname1, "renamefile(from)");
@@ -293,8 +315,10 @@ zrenamefile(register os_ptr op)
/* <string> status <pages> <bytes> <ref_time> <creation_time> true */
/* <string> status false */
private int
-zstatus(register os_ptr op)
+zstatus(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_file:
{
@@ -361,37 +385,40 @@ zstatus(register os_ptr op)
/* <executable_file> .execfile - */
private int
-zexecfile(register os_ptr op)
+zexecfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type_access(*op, t_file, a_executable | a_read | a_execute);
check_estack(4); /* cleanup, file, finish, file */
push_mark_estack(es_other, execfile_cleanup);
*++esp = *op;
push_op_estack(execfile_finish);
- return zexec(op);
+ return zexec(i_ctx_p);
}
/* Finish normally. */
private int
-execfile_finish(os_ptr op)
+execfile_finish(i_ctx_t *i_ctx_p)
{
check_ostack(1);
esp -= 2;
- execfile_cleanup(op);
+ execfile_cleanup(i_ctx_p);
return o_pop_estack;
}
/* Clean up by closing the file. */
private int
-execfile_cleanup(os_ptr op)
+execfile_cleanup(i_ctx_t *i_ctx_p)
{
check_ostack(1);
*++osp = esp[2];
- return zclosefile(osp);
+ return zclosefile(i_ctx_p);
}
/* <dir> <name> .filenamedirseparator <string> */
int
-zfilenamedirseparator(os_ptr op)
+zfilenamedirseparator(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const char *sepr;
check_read_type(*op, t_string);
@@ -409,8 +436,10 @@ zfilenamedirseparator(os_ptr op)
/* - .filenamelistseparator <string> */
int
-zfilenamelistseparator(os_ptr op)
+zfilenamelistseparator(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_const_string(op, avm_foreign | a_readonly, 1,
(const byte *)&gp_file_name_list_separator);
@@ -419,8 +448,10 @@ zfilenamelistseparator(os_ptr op)
/* <name> .filenamesplit <dir> <base> <extension> */
int
-zfilenamesplit(os_ptr op)
+zfilenamesplit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_read_type(*op, t_string);
/****** NOT IMPLEMENTED YET ******/
return_error(e_undefined);
@@ -429,10 +460,10 @@ zfilenamesplit(os_ptr op)
/* <string> findlibfile <found_string> <file> true */
/* <string> findlibfile <string> false */
int
-zfindlibfile(register os_ptr op)
+zfindlibfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
-
#define MAX_CNAME 200
byte cname[MAX_CNAME];
uint clen;
@@ -688,7 +719,14 @@ file_open_stream(const char *fname, uint len, const char *file_access,
sappend_file(s, file, buffer, buffer_size);
break;
case 'r':
- sread_file(s, file, buffer, buffer_size);
+ /* Defeat buffering for terminals. */
+ {
+ struct stat rstat;
+
+ fstat(fileno(file), &rstat);
+ sread_file(s, file, buffer,
+ (S_ISCHR(rstat.st_mode) ? 1 : buffer_size));
+ }
break;
case 'w':
swrite_file(s, file, buffer, buffer_size);
@@ -705,12 +743,15 @@ file_open_stream(const char *fname, uint len, const char *file_access,
return 0;
}
-/* Report an error by storing it in $error.errorinfo. */
+/* Report an error by storing it in the stream's error_string. */
int
filter_report_error(stream_state * st, const char *str)
{
if_debug1('s', "[s]stream error: %s\n", str);
- return gs_errorinfo_put_string(str);
+ strncpy(st->error_string, str, STREAM_MAX_ERROR_STRING);
+ /* Ensure null termination. */
+ st->error_string[STREAM_MAX_ERROR_STRING] = 0;
+ return 0;
}
/* Open a file stream for a filter. */
@@ -783,8 +824,8 @@ file_alloc_stream(gs_memory_t * mem, client_name_t cname)
{
int i;
- for (i = 0; i < countof(gs_imemory.spaces.indexed); ++i)
- if (mem == (gs_memory_t *) gs_imemory.spaces.indexed[i]) {
+ for (i = 0; i < countof(gs_imemory.spaces_indexed); ++i)
+ if (mem == (gs_memory_t *) gs_imemory.spaces_indexed[i]) {
imem = (gs_ref_memory_t *) mem;
break;
}
diff --git a/gs/src/zfileio.c b/gs/src/zfileio.c
index ac51265bd..03b9eb3c0 100644
--- a/gs/src/zfileio.c
+++ b/gs/src/zfileio.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,23 +26,26 @@
#include "store.h"
#include "strimpl.h" /* for ifilter.h */
#include "ifilter.h" /* for procedure streams */
+#include "interp.h" /* for gs_errorinfo_put_string */
#include "gsmatrix.h" /* for gxdevice.h */
#include "gxdevice.h"
#include "gxdevmem.h"
+#include "estack.h"
/* Forward references */
private int write_string(P2(ref *, stream *));
-private int handle_read_status(P4(int, const ref *, const uint *,
- int (*)(P1(os_ptr))));
-private int handle_write_status(P4(int, const ref *, const uint *,
- int (*)(P1(os_ptr))));
+private int handle_read_status(P5(i_ctx_t *, int, const ref *, const uint *,
+ op_proc_t));
+private int handle_write_status(P5(i_ctx_t *, int, const ref *, const uint *,
+ op_proc_t));
/* ------ Operators ------ */
/* <file> closefile - */
int
-zclosefile(register os_ptr op)
+zclosefile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
check_type(*op, t_file);
@@ -51,9 +54,11 @@ zclosefile(register os_ptr op)
if (status != 0) {
if (s_is_writing(s))
- return handle_write_status(status, op, NULL, zclosefile);
+ return handle_write_status(i_ctx_p, status, op, NULL,
+ zclosefile);
else
- return handle_read_status(status, op, NULL, zclosefile);
+ return handle_read_status(i_ctx_p, status, op, NULL,
+ zclosefile);
}
}
pop(1);
@@ -63,8 +68,9 @@ zclosefile(register os_ptr op)
/* <file> read <int> -true- */
/* <file> read -false- */
private int
-zread(register os_ptr op)
+zread(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
int ch;
@@ -77,14 +83,15 @@ zread(register os_ptr op)
} else if (ch == EOFC)
make_bool(op, 0);
else
- return handle_read_status(ch, op, NULL, zread);
+ return handle_read_status(i_ctx_p, ch, op, NULL, zread);
return 0;
}
/* <file> <int> write - */
int
-zwrite(register os_ptr op)
+zwrite(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
byte ch;
int status;
@@ -97,18 +104,18 @@ zwrite(register os_ptr op)
pop(2);
return 0;
}
- return handle_write_status(status, op - 1, NULL, zwrite);
+ return handle_write_status(i_ctx_p, status, op - 1, NULL, zwrite);
}
/* <file> <string> readhexstring <substring> <filled_bool> */
-private int zreadhexstring_continue(P1(os_ptr));
+private int zreadhexstring_continue(P1(i_ctx_t *));
/* We keep track of the odd digit in the next byte of the string */
/* beyond the bytes already used. (This is just for convenience; */
/* we could do the same thing by passing 2 state parameters to the */
/* continuation procedure instead of 1.) */
private int
-zreadhexstring_at(register os_ptr op, uint start)
+zreadhexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start)
{
stream *s;
uint len, nread;
@@ -148,7 +155,7 @@ zreadhexstring_at(register os_ptr op, uint start)
if (status != EOFC) { /* Error */
if (nread < len)
str[nread] = (odd < 0 ? 0x10 : odd);
- return handle_read_status(status, op - 1, &nread,
+ return handle_read_status(i_ctx_p, status, op - 1, &nread,
zreadhexstring_continue);
}
/* Reached end-of-file before filling the string. */
@@ -159,34 +166,37 @@ zreadhexstring_at(register os_ptr op, uint start)
return 0;
}
private int
-zreadhexstring(os_ptr op)
+zreadhexstring(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_write_type(*op, t_string);
if (r_size(op) > 0)
*op->value.bytes = 0x10;
- return zreadhexstring_at(op, 0);
+ return zreadhexstring_at(i_ctx_p, op, 0);
}
/* Continue a readhexstring operation after a callout. */
/* *op is the index within the string. */
private int
-zreadhexstring_continue(register os_ptr op)
+zreadhexstring_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(*op, t_integer);
if (op->value.intval < 0 || op->value.intval > r_size(op - 1))
return_error(e_rangecheck);
check_write_type(op[-1], t_string);
- code = zreadhexstring_at(op - 1, (uint) op->value.intval);
+ code = zreadhexstring_at(i_ctx_p, op - 1, (uint) op->value.intval);
if (code >= 0)
pop(1);
return code;
}
/* <file> <string> writehexstring - */
-private int zwritehexstring_continue(P1(os_ptr));
+private int zwritehexstring_continue(P1(i_ctx_t *));
private int
-zwritehexstring_at(register os_ptr op, uint odd)
+zwritehexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint odd)
{
register stream *s;
register byte ch;
@@ -230,7 +240,7 @@ zwritehexstring_at(register os_ptr op, uint odd)
op->value.bytes += count >> 1;
r_set_size(op, len - (count >> 1));
count &= 1;
- return handle_write_status(status, op - 1, &count,
+ return handle_write_status(i_ctx_p, status, op - 1, &count,
zwritehexstring_continue);
}
}
@@ -239,30 +249,33 @@ zwritehexstring_at(register os_ptr op, uint odd)
#undef MAX_HEX
}
private int
-zwritehexstring(os_ptr op)
+zwritehexstring(i_ctx_t *i_ctx_p)
{
- return zwritehexstring_at(op, 0);
+ os_ptr op = osp;
+
+ return zwritehexstring_at(i_ctx_p, op, 0);
}
/* Continue a writehexstring operation after a callout. */
/* *op is the odd/even hex digit flag for the first byte. */
private int
-zwritehexstring_continue(register os_ptr op)
+zwritehexstring_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(*op, t_integer);
if ((op->value.intval & ~1) != 0)
return_error(e_rangecheck);
- code = zwritehexstring_at(op - 1, (uint) op->value.intval);
+ code = zwritehexstring_at(i_ctx_p, op - 1, (uint) op->value.intval);
if (code >= 0)
pop(1);
return code;
}
/* <file> <string> readstring <substring> <filled_bool> */
-private int zreadstring_continue(P1(os_ptr));
+private int zreadstring_continue(P1(i_ctx_t *));
private int
-zreadstring_at(register os_ptr op, uint start)
+zreadstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start)
{
stream *s;
uint len, rlen;
@@ -278,7 +291,7 @@ zreadstring_at(register os_ptr op, uint start)
case 0:
break;
default:
- return handle_read_status(status, op - 1, &rlen,
+ return handle_read_status(i_ctx_p, status, op - 1, &rlen,
zreadstring_continue);
}
/*
@@ -296,21 +309,24 @@ zreadstring_at(register os_ptr op, uint start)
return 0;
}
private int
-zreadstring(os_ptr op)
+zreadstring(i_ctx_t *i_ctx_p)
{
- return zreadstring_at(op, 0);
+ os_ptr op = osp;
+
+ return zreadstring_at(i_ctx_p, op, 0);
}
/* Continue a readstring operation after a callout. */
/* *op is the index within the string. */
private int
-zreadstring_continue(register os_ptr op)
+zreadstring_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(*op, t_integer);
if (op->value.intval < 0 || op->value.intval > r_size(op - 1))
return_error(e_rangecheck);
- code = zreadstring_at(op - 1, (uint) op->value.intval);
+ code = zreadstring_at(i_ctx_p, op - 1, (uint) op->value.intval);
if (code >= 0)
pop(1);
return code;
@@ -318,8 +334,9 @@ zreadstring_continue(register os_ptr op)
/* <file> <string> writestring - */
private int
-zwritestring(register os_ptr op)
+zwritestring(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
int status;
@@ -330,12 +347,12 @@ zwritestring(register os_ptr op)
pop(2);
return 0;
}
- return handle_write_status(status, op - 1, NULL, zwritestring);
+ return handle_write_status(i_ctx_p, status, op - 1, NULL, zwritestring);
}
/* <file> <string> readline <substring> <bool> */
-private int zreadline(P1(os_ptr));
-private int zreadline_continue(P1(os_ptr));
+private int zreadline(P1(i_ctx_t *));
+private int zreadline_continue(P1(i_ctx_t *));
/*
* We could handle readline the same way as readstring,
@@ -348,18 +365,17 @@ private int zreadline_continue(P1(os_ptr));
* for readline_continue) to indicate interruption after the CR.
*/
private int
-zreadline_at(register os_ptr op, uint count, bool in_eol)
+zreadline_at(i_ctx_t *i_ctx_p, os_ptr op, uint count, bool in_eol)
{
stream *s;
- byte *ptr;
- uint len;
int status;
+ gs_string str;
check_read_file(s, op - 1);
check_write_type(*op, t_string);
- ptr = op->value.bytes;
- len = r_size(op);
- status = zreadline_from(s, ptr, len, &count, &in_eol);
+ str.data = op->value.bytes;
+ str.size = r_size(op);
+ status = zreadline_from(s, &str, NULL, &count, &in_eol);
switch (status) {
case 0:
case EOFC:
@@ -368,14 +384,14 @@ zreadline_at(register os_ptr op, uint count, bool in_eol)
return_error(e_rangecheck);
default:
if (count == 0 && !in_eol)
- return handle_read_status(status, op - 1, NULL,
+ return handle_read_status(i_ctx_p, status, op - 1, NULL,
zreadline);
else {
if (in_eol) {
r_set_size(op, count);
count = 0;
}
- return handle_read_status(status, op - 1, &count,
+ return handle_read_status(i_ctx_p, status, op - 1, &count,
zreadline_continue);
}
}
@@ -385,15 +401,18 @@ zreadline_at(register os_ptr op, uint count, bool in_eol)
return 0;
}
private int
-zreadline(register os_ptr op)
+zreadline(i_ctx_t *i_ctx_p)
{
- return zreadline_at(op, 0, false);
+ os_ptr op = osp;
+
+ return zreadline_at(i_ctx_p, op, 0, false);
}
/* Continue a readline operation after a callout. */
/* *op is the index within the string, or 0 for an interrupt after a CR. */
private int
-zreadline_continue(register os_ptr op)
+zreadline_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint size = r_size(op - 1);
uint start;
int code;
@@ -402,8 +421,8 @@ zreadline_continue(register os_ptr op)
if (op->value.intval < 0 || op->value.intval > size)
return_error(e_rangecheck);
start = (uint) op->value.intval;
- code = (start == 0 ? zreadline_at(op - 1, size, true) :
- zreadline_at(op - 1, start, false));
+ code = (start == 0 ? zreadline_at(i_ctx_p, op - 1, size, true) :
+ zreadline_at(i_ctx_p, op - 1, start, false));
if (code >= 0)
pop(1);
return code;
@@ -413,80 +432,24 @@ zreadline_continue(register os_ptr op)
/* Returns a stream status value, or 1 if we overflowed the string. */
/* This is exported for %lineedit. */
int
-zreadline_from(stream * s, byte * ptr, uint size, uint * pcount, bool * pin_eol)
-{
- uint count = *pcount;
-
- /* Most systems define \n as 0xa and \r as 0xd; however, */
- /* OS-9 has \n == \r == 0xd and \l == 0xa. The following */
- /* code works properly regardless of environment. */
-#if '\n' == '\r'
-# define LF 0xa
-#else
-# define LF '\n'
-#endif
-
-top:
- if (*pin_eol) {
- /*
- * We're in the middle of checking for a two-character
- * end-of-line sequence. If we get an EOF here, stop, but
- * don't signal EOF now; wait till the next read.
- */
- int ch = spgetcc(s, false);
-
- if (ch == EOFC) {
- *pin_eol = false;
- return 0;
- } else if (ch < 0)
- return ch;
- else if (ch != LF)
- sputback(s);
- *pin_eol = false;
- return 0;
- }
- for (;;) {
- int ch = sgetc(s);
+zreadline_from(stream *s, gs_string *buf, gs_memory_t *bufmem,
+ uint *pcount, bool *pin_eol)
+{
+ sreadline_proc((*readline));
- if (ch < 0) { /* EOF or exception */
- *pcount = count;
- return ch;
- }
- switch (ch) {
- case '\r':
- {
-#if '\n' == '\r' /* OS-9 or similar */
- stream *ins;
- int code = zget_stdin(&ins);
-
- if (code < 0 || s != ins)
-#endif
- {
- *pcount = count;
- *pin_eol = true;
- goto top;
- }
- }
- /* falls through */
- case LF:
-#undef LF
- *pcount = count;
- return 0;
- }
- if (count >= size) { /* filled the string */
- sputback(s);
- *pcount = count;
- return 1;
- }
- ptr[count++] = ch;
- }
- /*return 0; *//* not reached */
+ if (zis_stdin(s))
+ readline = gp_readline;
+ else
+ readline = sreadline;
+ return readline(s, NULL, NULL /*WRONG*/, NULL, buf, bufmem,
+ pcount, pin_eol, zis_stdin);
}
/* <file> bytesavailable <int> */
private int
-zbytesavailable(register os_ptr op)
+zbytesavailable(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
long avail;
@@ -505,10 +468,10 @@ zbytesavailable(register os_ptr op)
/* - flush - */
int
-zflush(register os_ptr op)
+zflush(i_ctx_t *i_ctx_p)
{
stream *s;
- int code = zget_stdout(&s);
+ int code = zget_stdout(i_ctx_p, &s);
if (code < 0)
return code;
@@ -518,12 +481,23 @@ zflush(register os_ptr op)
/* <file> flushfile - */
private int
-zflushfile(register os_ptr op)
+zflushfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
int status;
- check_file(s, op);
+ check_type(*op, t_file);
+ /*
+ * We think flushfile is a no-op on closed input files, but causes an
+ * error on closed output files.
+ */
+ if (file_is_invalid(s, op)) {
+ if (r_has_attr(op, a_write))
+ return_error(e_invalidaccess);
+ pop(1);
+ return 0;
+ }
status = sflush(s);
if (status == 0) {
pop(1);
@@ -531,14 +505,15 @@ zflushfile(register os_ptr op)
}
return
(s_is_writing(s) ?
- handle_write_status(status, op, NULL, zflushfile) :
- handle_read_status(status, op, NULL, zflushfile));
+ handle_write_status(i_ctx_p, status, op, NULL, zflushfile) :
+ handle_read_status(i_ctx_p, status, op, NULL, zflushfile));
}
/* <file> resetfile - */
private int
-zresetfile(register os_ptr op)
+zresetfile(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
/* According to Adobe, resetfile is a no-op on closed files. */
@@ -551,15 +526,16 @@ zresetfile(register os_ptr op)
/* <string> print - */
private int
-zprint(register os_ptr op)
+zprint(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
int status;
ref rstdout;
int code;
check_read_type(*op, t_string);
- code = zget_stdout(&s);
+ code = zget_stdout(i_ctx_p, &s);
if (code < 0)
return code;
status = write_string(op, s);
@@ -569,7 +545,8 @@ zprint(register os_ptr op)
}
/* Convert print to writestring on the fly. */
make_stream_file(&rstdout, s, "w");
- code = handle_write_status(status, &rstdout, NULL, zwritestring);
+ code = handle_write_status(i_ctx_p, status, &rstdout, NULL,
+ zwritestring);
if (code != o_push_estack)
return code;
push(1);
@@ -580,8 +557,10 @@ zprint(register os_ptr op)
/* <bool> echo - */
private int
-zecho(register os_ptr op)
+zecho(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
/****** NOT IMPLEMENTED YET ******/
pop(1);
@@ -592,8 +571,9 @@ zecho(register os_ptr op)
/* <file> fileposition <int> */
private int
-zfileposition(register os_ptr op)
+zfileposition(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
check_file(s, op);
@@ -603,8 +583,9 @@ zfileposition(register os_ptr op)
/* <file> <int> setfileposition - */
private int
-zsetfileposition(register os_ptr op)
+zsetfileposition(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
check_file(s, op - 1);
@@ -619,8 +600,9 @@ zsetfileposition(register os_ptr op)
/* <file> <int> unread - */
private int
-zunread(register os_ptr op)
+zunread(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
ulong ch;
@@ -635,30 +617,33 @@ zunread(register os_ptr op)
return 0;
}
-/* <file> <object> <==flag> .writecvp - */
-private int zwritecvp_continue(P1(os_ptr));
+/* <file> <obj> <==flag> .writecvp - */
+private int zwritecvp_continue(P1(i_ctx_t *));
private int
-zwritecvp_at(register os_ptr op, uint start)
+zwritecvp_at(i_ctx_t *i_ctx_p, os_ptr op, uint start, bool first)
{
stream *s;
-#define MAX_CVS 128
- byte str[MAX_CVS];
+ byte str[100]; /* arbitrary */
ref rstr;
- const byte *pchars = str;
+ const byte *data = str;
uint len;
int code, status;
check_write_file(s, op - 2);
- check_type(*op, t_boolean);
- code = obj_cvp(op - 1, str, MAX_CVS, &len, &pchars, op->value.boolval);
- if (code < 0) {
- if (pchars == str)
- return code;
+ check_type(*op, t_integer);
+ code = obj_cvp(op - 1, str, sizeof(str), &len, (int)op->value.intval,
+ start);
+ if (code == e_rangecheck) {
+ code = obj_string_data(op - 1, &data, &len);
+ if (len < start)
+ return_error(e_rangecheck);
+ data += start;
+ len -= start;
}
- if (start > len)
- return_error(e_rangecheck);
- r_set_size(&rstr, len - start);
- rstr.value.const_bytes = pchars + start;
+ if (code < 0)
+ return code;
+ r_set_size(&rstr, len);
+ rstr.value.const_bytes = data;
status = write_string(&rstr, s);
switch (status) {
default:
@@ -667,39 +652,49 @@ zwritecvp_at(register os_ptr op, uint start)
break;
case INTC:
case CALLC:
- len -= r_size(&rstr);
- return handle_write_status(status, op - 2, &len,
+ len = start + len - r_size(&rstr);
+ if (!first)
+ --osp; /* pop(1) without affecting op */
+ return handle_write_status(i_ctx_p, status, op - 2, &len,
zwritecvp_continue);
}
- pop(3);
+ if (code == 1) {
+ if (first)
+ check_ostack(1);
+ push_op_estack(zwritecvp_continue);
+ if (first)
+ push(1);
+ make_int(osp, start + len);
+ return o_push_estack;
+ }
+ if (first) /* zwritecvp */
+ pop(3);
+ else /* zwritecvp_continue */
+ pop(4);
return 0;
-#undef MAX_CVS
}
private int
-zwritecvp(os_ptr op)
+zwritecvp(i_ctx_t *i_ctx_p)
{
- return zwritecvp_at(op, 0);
+ return zwritecvp_at(i_ctx_p, osp, 0, true);
}
/* Continue a .writecvp after a callout. */
/* *op is the index within the string. */
private int
-zwritecvp_continue(os_ptr op)
+zwritecvp_continue(i_ctx_t *i_ctx_p)
{
- int code;
+ os_ptr op = osp;
check_type(*op, t_integer);
if (op->value.intval != (uint) op->value.intval)
return_error(e_rangecheck);
- code = zwritecvp_at(op - 1, (uint) op->value.intval);
- if (code >= 0)
- pop(1);
- return code;
+ return zwritecvp_at(i_ctx_p, op - 1, (uint) op->value.intval, false);
}
/* ------ Initialization procedure ------ */
-const op_def zfileio_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zfileio1_op_defs[] = {
{"1bytesavailable", zbytesavailable},
{"1closefile", zclosefile},
/* currentfile is in zcontrol.c */
@@ -713,6 +708,9 @@ const op_def zfileio_op_defs[] =
{"2readline", zreadline},
{"2readstring", zreadstring},
{"1resetfile", zresetfile},
+ op_def_end(0)
+};
+const op_def zfileio2_op_defs[] = {
{"2setfileposition", zsetfileposition},
{"2unread", zunread},
{"2write", zwrite},
@@ -785,17 +783,38 @@ write_string(ref * op, stream * s)
}
}
+/*
+ * Look for a stream error message that needs to be copied to
+ * $error.errorinfo, if any.
+ */
+private int
+copy_error_string(i_ctx_t *i_ctx_p, const ref *fop)
+{
+ stream *s;
+
+ for (s = fptr(fop); s->strm != 0 && s->state->error_string[0] == 0;)
+ s = s->strm;
+ if (s->state->error_string[0]) {
+ int code = gs_errorinfo_put_string(i_ctx_p, s->state->error_string);
+
+ if (code < 0)
+ return code;
+ s->state->error_string[0] = 0; /* just do it once */
+ }
+ return_error(e_ioerror);
+}
+
/* Handle an exceptional status return from a read stream. */
/* fop points to the ref for the stream. */
/* ch may be any stream exceptional value. */
/* Return 0, 1 (EOF), o_push_estack, or an error. */
private int
-handle_read_status(int ch, const ref * fop, const uint * pindex,
- int (*cont) (P1(os_ptr)))
+handle_read_status(i_ctx_t *i_ctx_p, int ch, const ref * fop,
+ const uint * pindex, op_proc_t cont)
{
switch (ch) {
default: /* error */
- return_error(e_ioerror);
+ return copy_error_string(i_ctx_p, fop);
case EOFC:
return 1;
case INTC:
@@ -804,9 +823,11 @@ handle_read_status(int ch, const ref * fop, const uint * pindex,
ref index;
make_int(&index, *pindex);
- return s_handle_read_exception(ch, fop, &index, 1, cont);
+ return s_handle_read_exception(i_ctx_p, ch, fop, &index, 1,
+ cont);
} else
- return s_handle_read_exception(ch, fop, NULL, 0, cont);
+ return s_handle_read_exception(i_ctx_p, ch, fop, NULL, 0,
+ cont);
}
}
@@ -815,12 +836,12 @@ handle_read_status(int ch, const ref * fop, const uint * pindex,
/* ch may be any stream exceptional value. */
/* Return 0, 1 (EOF), o_push_estack, or an error. */
private int
-handle_write_status(int ch, const ref * fop, const uint * pindex,
- int (*cont) (P1(os_ptr)))
+handle_write_status(i_ctx_t *i_ctx_p, int ch, const ref * fop,
+ const uint * pindex, op_proc_t cont)
{
switch (ch) {
default: /* error */
- return_error(e_ioerror);
+ return copy_error_string(i_ctx_p, fop);
case EOFC:
return 1;
case INTC:
@@ -829,8 +850,10 @@ handle_write_status(int ch, const ref * fop, const uint * pindex,
ref index;
make_int(&index, *pindex);
- return s_handle_write_exception(ch, fop, &index, 1, cont);
+ return s_handle_write_exception(i_ctx_p, ch, fop, &index, 1,
+ cont);
} else
- return s_handle_write_exception(ch, fop, NULL, 0, cont);
+ return s_handle_write_exception(i_ctx_p, ch, fop, NULL, 0,
+ cont);
}
}
diff --git a/gs/src/zfilter.c b/gs/src/zfilter.c
index 04b8fc998..e4f9a34e3 100644
--- a/gs/src/zfilter.c
+++ b/gs/src/zfilter.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -37,46 +37,46 @@
/* <source> ASCIIHexEncode/filter <file> */
/* <source> <dict> ASCIIHexEncode/filter <file> */
private int
-zAXE(os_ptr op)
+zAXE(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_AXE_template);
+ return filter_write_simple(i_ctx_p, &s_AXE_template);
}
/* <target> ASCIIHexDecode/filter <file> */
/* <target> <dict> ASCIIHexDecode/filter <file> */
private int
-zAXD(os_ptr op)
+zAXD(i_ctx_t *i_ctx_p)
{
- return filter_read_simple(op, &s_AXD_template);
+ return filter_read_simple(i_ctx_p, &s_AXD_template);
}
/* <target> NullEncode/filter <file> */
/* <target> <dict_ignored> NullEncode/filter <file> */
private int
-zNullE(os_ptr op)
+zNullE(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_NullE_template);
+ return filter_write_simple(i_ctx_p, &s_NullE_template);
}
/* <source> <bool> PFBDecode/filter <file> */
/* <source> <dict> <bool> PFBDecode/filter <file> */
private int
-zPFBD(os_ptr op)
+zPFBD(i_ctx_t *i_ctx_p)
{
+ os_ptr sop = osp;
stream_PFBD_state state;
- os_ptr sop = op;
check_type(*sop, t_boolean);
state.binary_to_hex = sop->value.boolval;
- return filter_read(op, 1, &s_PFBD_template, (stream_state *) & state, 0);
+ return filter_read(i_ctx_p, 1, &s_PFBD_template, (stream_state *)&state, 0);
}
/* <target> PSStringEncode/filter <file> */
/* <target> <dict> PSStringEncode/filter <file> */
private int
-zPSSE(os_ptr op)
+zPSSE(i_ctx_t *i_ctx_p)
{
- return filter_write_simple(op, &s_PSSE_template);
+ return filter_write_simple(i_ctx_p, &s_PSSE_template);
}
/* ------ RunLength filters ------ */
@@ -101,8 +101,9 @@ rl_setup(os_ptr dop, bool * eod)
/* <target> <record_size> RunLengthEncode/filter <file> */
/* <target> <dict> <record_size> RunLengthEncode/filter <file> */
private int
-zRLE(register os_ptr op)
+zRLE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_RLE_state state;
int code;
@@ -112,28 +113,30 @@ zRLE(register os_ptr op)
return code;
check_int_leu(*op, max_uint);
state.record_size = op->value.intval;
- return filter_write(op, 1, &s_RLE_template, (stream_state *) & state, 0);
+ return filter_write(i_ctx_p, 1, &s_RLE_template, (stream_state *) & state, 0);
}
/* <source> RunLengthDecode/filter <file> */
/* <source> <dict> RunLengthDecode/filter <file> */
private int
-zRLD(os_ptr op)
+zRLD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_RLD_state state;
int code = rl_setup(op, &state.EndOfData);
if (code < 0)
return code;
- return filter_read(op, 0, &s_RLD_template, (stream_state *) & state, 0);
+ return filter_read(i_ctx_p, 0, &s_RLD_template, (stream_state *) & state, 0);
}
/* <source> <EODcount> <EODstring> SubFileDecode/filter <file> */
/* <source> <dict> <EODcount> <EODstring> SubFileDecode/filter <file> */
/* <source> <dict> SubFileDecode/filter <file> *//* (LL3 only) */
private int
-zSFD(os_ptr op)
+zSFD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_SFD_state state;
ref *sop = op;
int npop;
@@ -159,8 +162,8 @@ zSFD(os_ptr op)
check_read_type(*sop, t_string);
state.eod.data = sop->value.const_bytes;
state.eod.size = r_size(sop);
- return filter_read(op, npop, &s_SFD_template, (stream_state *) & state,
- r_space(sop));
+ return filter_read(i_ctx_p, npop, &s_SFD_template,
+ (stream_state *)&state, r_space(sop));
}
/* ------ Utilities ------ */
@@ -170,9 +173,10 @@ private int filter_ensure_buf(P3(stream **, uint, bool));
/* Set up an input filter. */
int
-filter_read(os_ptr op, int npop, const stream_template * template,
+filter_read(i_ctx_t *i_ctx_p, int npop, const stream_template * template,
stream_state * st, uint space)
{
+ os_ptr op = osp;
uint min_size = template->min_out_size + max_min_left;
uint save_space = ialloc_space(idmemory);
os_ptr sop = op - npop;
@@ -239,16 +243,17 @@ out:
return code;
}
int
-filter_read_simple(os_ptr op, const stream_template * template)
+filter_read_simple(i_ctx_t *i_ctx_p, const stream_template * template)
{
- return filter_read(op, 0, template, NULL, 0);
+ return filter_read(i_ctx_p, 0, template, NULL, 0);
}
/* Set up an output filter. */
int
-filter_write(os_ptr op, int npop, const stream_template * template,
+filter_write(i_ctx_t *i_ctx_p, int npop, const stream_template * template,
stream_state * st, uint space)
{
+ os_ptr op = osp;
uint min_size = template->min_in_size + max_min_left;
uint save_space = ialloc_space(idmemory);
register os_ptr sop = op - npop;
@@ -315,9 +320,9 @@ out:
return code;
}
int
-filter_write_simple(os_ptr op, const stream_template * template)
+filter_write_simple(i_ctx_t *i_ctx_p, const stream_template * template)
{
- return filter_write(op, 0, template, NULL, 0);
+ return filter_write(i_ctx_p, 0, template, NULL, 0);
}
/* Define a byte-at-a-time NullDecode filter for intermediate buffers. */
diff --git a/gs/src/zfilter2.c b/gs/src/zfilter2.c
index cb88e9e8c..cc5e17a10 100644
--- a/gs/src/zfilter2.c
+++ b/gs/src/zfilter2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -44,8 +44,9 @@ int zpp_setup(P2(os_ptr op, stream_PNGP_state * ppps));
/* <target> <dict> CCITTFaxEncode/filter <file> */
private int
-zCFE(os_ptr op)
+zCFE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_CFE_state cfs;
int code;
@@ -54,15 +55,16 @@ zCFE(os_ptr op)
code = zcf_setup(op, (stream_CF_state *)&cfs);
if (code < 0)
return code;
- return filter_write(op, 0, &s_CFE_template, (stream_state *)&cfs, 0);
+ return filter_write(i_ctx_p, 0, &s_CFE_template, (stream_state *)&cfs, 0);
}
/* ------ Common setup for possibly pixel-oriented encoding filters ------ */
int
-filter_write_predictor(os_ptr op, int npop, const stream_template * template,
- stream_state * st)
+filter_write_predictor(i_ctx_t *i_ctx_p, int npop,
+ const stream_template * template, stream_state * st)
{
+ os_ptr op = osp;
int predictor, code;
stream_PDiff_state pds;
stream_PNGP_state pps;
@@ -95,7 +97,7 @@ filter_write_predictor(os_ptr op, int npop, const stream_template * template,
} else
predictor = 1;
if (predictor == 1)
- return filter_write(op, npop, template, st, 0);
+ return filter_write(i_ctx_p, npop, template, st, 0);
{
/* We need to cascade filters. */
ref rtarget, rdict, rfd;
@@ -104,7 +106,7 @@ filter_write_predictor(os_ptr op, int npop, const stream_template * template,
/* Save the operands, just in case. */
ref_assign(&rtarget, op - 1);
ref_assign(&rdict, op);
- code = filter_write(op, 1, template, st, 0);
+ code = filter_write(i_ctx_p, 1, template, st, 0);
if (code < 0)
return code;
/* filter_write changed osp.... */
@@ -112,8 +114,8 @@ filter_write_predictor(os_ptr op, int npop, const stream_template * template,
ref_assign(&rfd, op);
code =
(predictor == 2 ?
- filter_write(op, 0, &s_PDiffE_template, (stream_state *)&pds, 0) :
- filter_write(op, 0, &s_PNGPE_template, (stream_state *)&pps, 0));
+ filter_write(i_ctx_p, 0, &s_PDiffE_template, (stream_state *)&pds, 0) :
+ filter_write(i_ctx_p, 0, &s_PNGPE_template, (stream_state *)&pps, 0));
if (code < 0) {
/* Restore the operands. Don't bother trying to clean up */
/* the first stream. */
@@ -137,14 +139,15 @@ filter_write_predictor(os_ptr op, int npop, const stream_template * template,
* to be subject to Unisys' Welch Patent.
*/
private int
-zLZWE(os_ptr op)
+zLZWE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_LZW_state lzs;
int code = zlz_setup(op, &lzs);
if (code < 0)
return code;
- return filter_write_predictor(op, 0, &s_LZWE_template,
+ return filter_write_predictor(i_ctx_p, 0, &s_LZWE_template,
(stream_state *) & lzs);
}
diff --git a/gs/src/zfilterx.c b/gs/src/zfilterx.c
index a3d74a7cd..cd4c91be4 100644
--- a/gs/src/zfilterx.c
+++ b/gs/src/zfilterx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -33,7 +33,6 @@
#include "sbtx.h"
#include "shcgen.h"
#include "smtf.h"
-#include "spcxx.h"
#include "ifilter.h"
/* ------ Bounded Huffman code filters ------ */
@@ -116,8 +115,9 @@ bhc_setup(os_ptr op, stream_BHC_state * pbhcs)
/* <target> <dict> BoundedHuffmanEncode/filter <file> */
private int
-zBHCE(os_ptr op)
+zBHCE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BHCE_state bhcs;
int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
@@ -128,14 +128,15 @@ zBHCE(os_ptr op)
/* <source> <dict> BoundedHuffmanDecode/filter <file> */
private int
-zBHCD(os_ptr op)
+zBHCD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BHCD_state bhcs;
int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
if (code < 0)
return code;
- return filter_read(op, 0, &s_BHCD_template, (stream_state *)&bhcs, 0);
+ return filter_read(i_ctx_p, 0, &s_BHCD_template, (stream_state *)&bhcs, 0);
}
/* <array> <max_length> .computecodes <array> */
@@ -144,8 +145,9 @@ zBHCD(os_ptr op)
/* the code values. This is the form needed for the Tables element of */
/* the dictionary parameter for the BoundedHuffman filters. */
private int
-zcomputecodes(os_ptr op)
+zcomputecodes(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
uint asize;
hc_definition def;
@@ -218,8 +220,9 @@ bwbs_setup(os_ptr op, stream_BWBS_state * pbwbss)
/* <target> <dict> BWBlockSortEncode/filter <file> */
private int
-zBWBSE(os_ptr op)
+zBWBSE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BWBSE_state bwbss;
int code;
@@ -233,14 +236,15 @@ zBWBSE(os_ptr op)
/* <source> <dict> BWBlockSortDecode/filter <file> */
private int
-zBWBSD(os_ptr op)
+zBWBSD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BWBSD_state bwbss;
int code = bwbs_setup(op, (stream_BWBS_state *)&bwbss);
if (code < 0)
return code;
- return filter_read(op, 0, &s_BWBSD_template, (stream_state *)&bwbss, 0);
+ return filter_read(i_ctx_p, 0, &s_BWBSD_template, (stream_state *)&bwbss, 0);
}
/* ------ Byte translation filters ------ */
@@ -259,8 +263,9 @@ bt_setup(os_ptr op, stream_BT_state * pbts)
/* <target> <table> ByteTranslateEncode/filter <file> */
/* <target> <table> <dict> ByteTranslateEncode/filter <file> */
private int
-zBTE(os_ptr op)
+zBTE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BT_state bts;
int code = bt_setup(op, &bts);
@@ -272,14 +277,15 @@ zBTE(os_ptr op)
/* <target> <table> ByteTranslateDecode/filter <file> */
/* <target> <table> <dict> ByteTranslateDecode/filter <file> */
private int
-zBTD(os_ptr op)
+zBTD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_BT_state bts;
int code = bt_setup(op, &bts);
if (code < 0)
return code;
- return filter_read(op, 0, &s_BTD_template, (stream_state *)&bts, 0);
+ return filter_read(i_ctx_p, 0, &s_BTD_template, (stream_state *)&bts, 0);
}
/* ------ Move-to-front filters ------ */
@@ -287,27 +293,21 @@ zBTD(os_ptr op)
/* <target> MoveToFrontEncode/filter <file> */
/* <target> <dict> MoveToFrontEncode/filter <file> */
private int
-zMTFE(os_ptr op)
+zMTFE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
return filter_write_simple(op, &s_MTFE_template);
}
/* <source> MoveToFrontDecode/filter <file> */
/* <source> <dict> MoveToFrontDecode/filter <file> */
private int
-zMTFD(os_ptr op)
+zMTFD(i_ctx_t *i_ctx_p)
{
- return filter_read_simple(op, &s_MTFD_template);
-}
-
-/* ------ PCX decoding filter ------ */
+ os_ptr op = osp;
-/* <source> PCXDecode/filter <file> */
-/* <source> <dict> PCXDecode/filter <file> */
-private int
-zPCXD(os_ptr op)
-{
- return filter_read_simple(op, &s_PCXD_template);
+ return filter_read_simple(op, &s_MTFD_template);
}
/* ================ Initialization procedure ================ */
@@ -325,6 +325,5 @@ const op_def zfilterx_op_defs[] =
{"2ByteTranslateDecode", zBTD},
{"1MoveToFrontEncode", zMTFE},
{"1MoveToFrontDecode", zMTFD},
- {"1PCXDecode", zPCXD},
op_def_end(0)
};
diff --git a/gs/src/zfname.c b/gs/src/zfname.c
index ff211bd79..1611b3825 100644
--- a/gs/src/zfname.c
+++ b/gs/src/zfname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -106,5 +106,5 @@ void
free_file_name(parsed_file_name * pfn, client_name_t cname)
{
if (pfn->fname != 0)
- ifree_string((byte *) pfn->fname, pfn->len, cname);
+ ifree_const_string((const byte *)pfn->fname, pfn->len, cname);
}
diff --git a/gs/src/zfont.c b/gs/src/zfont.c
index 9f7efb652..701e5855f 100644
--- a/gs/src/zfont.c
+++ b/gs/src/zfont.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,7 +28,7 @@
#include "gxfcache.h"
#include "bfont.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "igstate.h"
#include "iname.h" /* for name_mark_index */
#include "isave.h"
@@ -36,7 +36,7 @@
#include "ivmspace.h"
/* Forward references */
-private int make_font(P2(os_ptr, const gs_matrix *));
+private int make_font(P2(i_ctx_t *, const gs_matrix *));
private void make_uint_array(P3(os_ptr, const uint *, int));
/* The (global) font directory */
@@ -51,19 +51,20 @@ zfont_mark_glyph_name(gs_glyph glyph, void *ignore_data)
}
/* Initialize the font operators */
-private void
-zfont_init(void)
+private int
+zfont_init(i_ctx_t *i_ctx_p)
{
ifont_dir = gs_font_dir_alloc2(imemory, &gs_memory_default);
ifont_dir->ccache.mark_glyph = zfont_mark_glyph_name;
- gs_register_struct_root(imemory, NULL, (void **)&ifont_dir,
- "ifont_dir");
+ return gs_register_struct_root(imemory, NULL, (void **)&ifont_dir,
+ "ifont_dir");
}
/* <font> <scale> scalefont <new_font> */
private int
-zscalefont(register os_ptr op)
+zscalefont(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
double scale;
gs_matrix mat;
@@ -72,25 +73,27 @@ zscalefont(register os_ptr op)
return code;
if ((code = gs_make_scaling(scale, scale, &mat)) < 0)
return code;
- return make_font(op, &mat);
+ return make_font(i_ctx_p, &mat);
}
/* <font> <matrix> makefont <new_font> */
private int
-zmakefont(register os_ptr op)
+zmakefont(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
gs_matrix mat;
if ((code = read_matrix(op, &mat)) < 0)
return code;
- return make_font(op, &mat);
+ return make_font(i_ctx_p, &mat);
}
/* <font> setfont - */
int
-zsetfont(register os_ptr op)
+zsetfont(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_font *pfont;
int code = font_param(op, &pfont);
@@ -102,8 +105,10 @@ zsetfont(register os_ptr op)
/* - currentfont <font> */
private int
-zcurrentfont(register os_ptr op)
+zcurrentfont(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
*op = *pfont_dict(gs_currentfont(igs));
return 0;
@@ -111,8 +116,9 @@ zcurrentfont(register os_ptr op)
/* - cachestatus <mark> <bsize> <bmax> <msize> <mmax> <csize> <cmax> <blimit> */
private int
-zcachestatus(register os_ptr op)
+zcachestatus(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint status[7];
gs_cachestatus(ifont_dir, status);
@@ -123,8 +129,10 @@ zcachestatus(register os_ptr op)
/* <blimit> setcachelimit - */
private int
-zsetcachelimit(register os_ptr op)
+zsetcachelimit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_int_leu(*op, max_uint);
gs_setcachelimit(ifont_dir, (uint) op->value.intval);
pop(1);
@@ -133,8 +141,9 @@ zsetcachelimit(register os_ptr op)
/* <mark> <size> <lower> <upper> setcacheparams - */
private int
-zsetcacheparams(register os_ptr op)
+zsetcacheparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint params[3];
int i, code;
os_ptr opp = op;
@@ -155,13 +164,14 @@ zsetcacheparams(register os_ptr op)
return code;
case 0:;
}
- return zcleartomark(op);
+ return zcleartomark(i_ctx_p);
}
/* - currentcacheparams <mark> <size> <lower> <upper> */
private int
-zcurrentcacheparams(register os_ptr op)
+zcurrentcacheparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint params[3];
params[0] = gs_currentcachesize(ifont_dir);
@@ -219,20 +229,23 @@ font_param(const ref * pfdict, gs_font ** ppfont)
}
/* Add the FID entry to a font dictionary. */
+/* Note that i_ctx_p may be NULL. */
int
-add_FID(ref * fp /* t_dictionary */ , gs_font * pfont)
+add_FID(i_ctx_t *i_ctx_p, ref * fp /* t_dictionary */ , gs_font * pfont)
{
ref fid;
make_tav_new(&fid, t_fontID, a_readonly | icurrent_space,
pstruct, (void *)pfont);
- return dict_put_string(fp, "FID", &fid);
+ return (i_ctx_p ? idict_put_string(fp, "FID", &fid) :
+ dict_put_string(fp, "FID", &fid, NULL));
}
/* Make a transformed font (common code for makefont/scalefont). */
private int
-make_font(os_ptr op, const gs_matrix * pmat)
+make_font(i_ctx_t *i_ctx_p, const gs_matrix * pmat)
{
+ os_ptr op = osp;
os_ptr fp = op - 1;
gs_font *oldfont, *newfont;
int code;
@@ -285,7 +298,7 @@ make_font(os_ptr op, const gs_matrix * pmat)
}
/* Create the transformed font dictionary. */
/* This is the make_font completion procedure for all non-composite fonts */
-/* created at the interpreter level (see build_gs_simple_font in zfont2.c.) */
+/* created at the interpreter level (see build_gs_simple_font in zbfont.c.) */
int
zbase_make_font(gs_font_dir * pdir, const gs_font * oldfont,
const gs_matrix * pmat, gs_font ** ppfont)
@@ -318,8 +331,12 @@ zdefault_make_font(gs_font_dir * pdir, const gs_font * oldfont,
"make_font(font_data)")) == 0
)
return_error(e_VMerror);
+ /*
+ * This dictionary is newly created: it's safe to pass NULL as the
+ * dstack pointer to dict_copy and dict_put_string.
+ */
if ((code = dict_create(dlen, &newdict)) < 0 ||
- (code = dict_copy(fp, &newdict)) < 0 ||
+ (code = dict_copy(fp, &newdict, NULL)) < 0 ||
(code = ialloc_ref_array(&newmat, a_all, 12, "make_font(matrices)")) < 0
)
return code;
@@ -350,10 +367,10 @@ zdefault_make_font(gs_font_dir * pdir, const gs_font * oldfont,
r_set_size(&newmat, 6);
write_matrix(&newmat, &newfont->FontMatrix);
r_clear_attrs(&newmat, a_write);
- if ((code = dict_put_string(&newdict, "FontMatrix", &newmat)) < 0 ||
- (code = dict_put_string(&newdict, "OrigFont", pfont_dict(oldfont->base))) < 0 ||
- (code = dict_put_string(&newdict, "ScaleMatrix", &scalemat)) < 0 ||
- (code = add_FID(&newdict, newfont)) < 0
+ if ((code = dict_put_string(&newdict, "FontMatrix", &newmat, NULL)) < 0 ||
+ (code = dict_put_string(&newdict, "OrigFont", pfont_dict(oldfont->base), NULL)) < 0 ||
+ (code = dict_put_string(&newdict, "ScaleMatrix", &scalemat, NULL)) < 0 ||
+ (code = add_FID(NULL, &newdict, newfont)) < 0
)
return code;
newfont->client_data = pdata;
diff --git a/gs/src/zfont0.c b/gs/src/zfont0.c
index 971c1ea78..b6709c1c8 100644
--- a/gs/src/zfont0.c
+++ b/gs/src/zfont0.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -38,7 +38,7 @@
#include "gxfont0.h"
#include "bfont.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "idparam.h"
#include "igstate.h"
#include "iname.h"
@@ -57,13 +57,14 @@ int ztype0_get_cmap(P3(const gs_cmap ** ppcmap, const ref * pfdepvector,
/* Forward references */
private font_proc_define_font(ztype0_define_font);
private font_proc_make_font(ztype0_make_font);
-private int ensure_char_entry(P4(os_ptr, const char *, byte *, int));
+private int ensure_char_entry(P5(i_ctx_t *, os_ptr, const char *, byte *, int));
/* <string|name> <font_dict> .buildfont0 <string|name> <font> */
/* Build a type 0 (composite) font. */
private int
-zbuildfont0(os_ptr op)
+zbuildfont0(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_type0_data data;
ref fdepvector;
ref *pprefenc;
@@ -125,12 +126,12 @@ zbuildfont0(os_ptr op)
switch (data.FMapType) {
case fmap_escape:
case fmap_double_escape: /* need EscChar */
- code = ensure_char_entry(op, "EscChar", &data.EscChar, 255);
+ code = ensure_char_entry(i_ctx_p, op, "EscChar", &data.EscChar, 255);
break;
case fmap_shift: /* need ShiftIn & ShiftOut */
- code = ensure_char_entry(op, "ShiftIn", &data.ShiftIn, 15);
+ code = ensure_char_entry(i_ctx_p, op, "ShiftIn", &data.ShiftIn, 15);
if (code >= 0)
- code = ensure_char_entry(op, "ShiftOut", &data.ShiftOut, 14);
+ code = ensure_char_entry(i_ctx_p, op, "ShiftOut", &data.ShiftOut, 14);
break;
case fmap_SubsVector: /* need SubsVector */
{
@@ -177,7 +178,7 @@ zbuildfont0(os_ptr op)
"%Type0BuildChar", "%Type0BuildGlyph");
if (code < 0)
return code;
- code = build_gs_font(op, (gs_font **) & pfont,
+ code = build_gs_font(i_ctx_p, op, (gs_font **) & pfont,
ft_composite, &st_gs_font_type0, &build,
bf_options_none);
}
@@ -193,7 +194,7 @@ zbuildfont0(os_ptr op)
ref nul;
make_null_new(&nul);
- if ((code = dict_put_string(op, "PrefEnc", &nul)) < 0)
+ if ((code = idict_put_string(op, "PrefEnc", &nul)) < 0)
goto fail;
}
/* Fill in the font data */
@@ -249,9 +250,9 @@ fail:
ref rnfid;
name_enter_string("FID", &rnfid);
- dict_undef(op, &rnfid);
+ idict_undef(op, &rnfid);
} else
- dict_put_string(op, "FID", &save_FID);
+ idict_put_string(op, "FID", &save_FID);
gs_free_object(pfont->memory, pfont, "buildfont0(font)");
return code;
}
@@ -277,7 +278,11 @@ ztype0_adjust_FDepVector(gs_font_type0 * pfont)
ref_assign_new(prdep, pdict);
}
- return dict_put_string(pfont_dict(pfont), "FDepVector", &newdep);
+ /*
+ * The FDepVector is an existing key in the parent's dictionary,
+ * so it's safe to pass NULL as the dstack pointer to dict_put_string.
+ */
+ return dict_put_string(pfont_dict(pfont), "FDepVector", &newdep, NULL);
}
private int
ztype0_define_font(gs_font_dir * pdir, gs_font * pfont)
@@ -313,7 +318,7 @@ ztype0_make_font(gs_font_dir * pdir, const gs_font * pfont,
/* Find or add a character entry in a font dictionary. */
private int
-ensure_char_entry(os_ptr op, const char *kstr,
+ensure_char_entry(i_ctx_t *i_ctx_p, os_ptr op, const char *kstr,
byte * pvalue, int default_value)
{
ref *pentry;
@@ -323,7 +328,7 @@ ensure_char_entry(os_ptr op, const char *kstr,
make_int(&ent, default_value);
*pvalue = (byte) default_value;
- return dict_put_string(op, kstr, &ent);
+ return idict_put_string(op, kstr, &ent);
} else {
check_int_leu_only(*pentry, 255);
*pvalue = (byte) pentry->value.intval;
diff --git a/gs/src/zfont1.c b/gs/src/zfont1.c
index 70e4733bf..2ab768ee0 100644
--- a/gs/src/zfont1.c
+++ b/gs/src/zfont1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,7 +17,7 @@
*/
-/* Type 1 and Type 4 font creation operator */
+/* Type 1 and Type 4 font creation operators */
#include "ghost.h"
#include "oper.h"
#include "gxfixed.h"
@@ -30,6 +30,7 @@
#include "ialloc.h"
#include "idict.h"
#include "idparam.h"
+#include "ifont1.h"
#include "store.h"
/*#define TEST*/
@@ -39,16 +40,8 @@ extern const gs_type1_data_procs_t z1_data_procs;
/* Default value of lenIV */
#define DEFAULT_LENIV_1 4
-#define DEFAULT_LENIV_2 (-1)
/* Private utilities */
-private uint
-subr_bias(const ref * psubrs)
-{
- uint size = r_size(psubrs);
-
- return (size < 1240 ? 107 : size < 33900 ? 1131 : 32768);
-}
private void
find_zone_height(float *pmax_height, int count, const float *values)
{
@@ -60,125 +53,90 @@ find_zone_height(float *pmax_height, int count, const float *values)
*pmax_height = zone_height;
}
-/* Build a Type 1 or Type 4 font. */
-private int
-buildfont1or4(os_ptr op, build_proc_refs * pbuild, font_type ftype,
- build_font_options_t options)
+/* Extract pointers to internal structures. */
+int
+charstring_font_get_refs(os_ptr op, charstring_font_refs_t *pfr)
{
- gs_type1_data data1;
- ref no_subrs;
- ref *pothersubrs = &no_subrs;
- ref *psubrs = &no_subrs;
- ref *pglobalsubrs = &no_subrs;
- ref *pprivate;
- gs_font_type1 *pfont;
- font_data *pdata;
- int code;
-
check_type(*op, t_dictionary);
- if (dict_find_string(op, "Private", &pprivate) <= 0 ||
- !r_has_type(pprivate, t_dictionary)
+ if (dict_find_string(op, "Private", &pfr->Private) <= 0 ||
+ !r_has_type(pfr->Private, t_dictionary)
)
return_error(e_invalidfont);
- make_empty_array(&no_subrs, 0);
- if (dict_find_string(pprivate, "OtherSubrs", &pothersubrs) > 0) {
- if (!r_is_array(pothersubrs))
+ make_empty_array(&pfr->no_subrs, 0);
+ if (dict_find_string(pfr->Private, "OtherSubrs", &pfr->OtherSubrs) > 0) {
+ if (!r_is_array(pfr->OtherSubrs))
return_error(e_typecheck);
- }
- if (dict_find_string(pprivate, "Subrs", &psubrs) > 0) {
- if (!r_is_array(psubrs))
+ } else
+ pfr->OtherSubrs = &pfr->no_subrs;
+ if (dict_find_string(pfr->Private, "Subrs", &pfr->Subrs) > 0) {
+ if (!r_is_array(pfr->Subrs))
return_error(e_typecheck);
- }
- if ((code = dict_int_param(op, "CharstringType", 1, 2, 1,
- &data1.CharstringType)) < 0
- )
- return code;
- /* Get information specific to Type 2 charstrings. */
- if (data1.CharstringType == 2) {
- float dwx, nwx;
+ } else
+ pfr->Subrs = &pfr->no_subrs;
+ pfr->GlobalSubrs = &pfr->no_subrs;
+ return 0;
+}
- data1.subroutineNumberBias = subr_bias(psubrs);
- if (dict_find_string(pprivate, "GlobalSubrs", &pglobalsubrs) > 0) {
- if (!r_is_array(pglobalsubrs))
- return_error(e_typecheck);
- }
- data1.gsubrNumberBias = subr_bias(pglobalsubrs);
- if ((code = dict_uint_param(pprivate, "gsubrNumberBias",
- 0, max_uint, data1.gsubrNumberBias,
- &data1.gsubrNumberBias)) < 0 ||
- (code = dict_float_param(pprivate, "defaultWidthX", 0.0,
- &dwx)) < 0 ||
- (code = dict_float_param(pprivate, "nominalWidthX", 0.0,
- &nwx)) < 0
- )
- return code;
- data1.defaultWidthX = float2fixed(dwx);
- data1.nominalWidthX = float2fixed(nwx);
- {
- ref *pirs;
+/* Build a Type 1, Type 2, or Type 4 font. */
+int
+build_charstring_font(i_ctx_t *i_ctx_p, os_ptr op, build_proc_refs *pbuild,
+ font_type ftype, charstring_font_refs_t *pfr,
+ gs_type1_data *pdata1, build_font_options_t options)
+{
+ const ref *pprivate = pfr->Private;
+ gs_font_type1 *pfont;
+ font_data *pdata;
+ int code;
- if (dict_find_string(pprivate, "initialRandomSeed", &pirs) <= 0)
- data1.initialRandomSeed = 0;
- else if (!r_has_type(pirs, t_integer))
- return_error(e_typecheck);
- else
- data1.initialRandomSeed = pirs->value.intval;
- }
- data1.lenIV = DEFAULT_LENIV_2;
- } else {
- data1.subroutineNumberBias = 0;
- data1.gsubrNumberBias = 0;
- data1.lenIV = DEFAULT_LENIV_1;
- }
/* Get the rest of the information from the Private dictionary. */
- if ((code = dict_int_param(pprivate, "lenIV", -1, 255, data1.lenIV,
- &data1.lenIV)) < 0 ||
+ if ((code = dict_int_param(pprivate, "lenIV", -1, 255, pdata1->lenIV,
+ &pdata1->lenIV)) < 0 ||
(code = dict_uint_param(pprivate, "subroutineNumberBias",
- 0, max_uint, data1.subroutineNumberBias,
- &data1.subroutineNumberBias)) < 0 ||
+ 0, max_uint, pdata1->subroutineNumberBias,
+ &pdata1->subroutineNumberBias)) < 0 ||
(code = dict_int_param(pprivate, "BlueFuzz", 0, 1999, 1,
- &data1.BlueFuzz)) < 0 ||
+ &pdata1->BlueFuzz)) < 0 ||
(code = dict_float_param(pprivate, "BlueScale", 0.039625,
- &data1.BlueScale)) < 0 ||
+ &pdata1->BlueScale)) < 0 ||
(code = dict_float_param(pprivate, "BlueShift", 7.0,
- &data1.BlueShift)) < 0 ||
- (code = data1.BlueValues.count =
+ &pdata1->BlueShift)) < 0 ||
+ (code = pdata1->BlueValues.count =
dict_float_array_param(pprivate, "BlueValues", max_BlueValues * 2,
- &data1.BlueValues.values[0], NULL)) < 0 ||
+ &pdata1->BlueValues.values[0], NULL)) < 0 ||
(code = dict_float_param(pprivate, "ExpansionFactor", 0.06,
- &data1.ExpansionFactor)) < 0 ||
- (code = data1.FamilyBlues.count =
+ &pdata1->ExpansionFactor)) < 0 ||
+ (code = pdata1->FamilyBlues.count =
dict_float_array_param(pprivate, "FamilyBlues", max_FamilyBlues * 2,
- &data1.FamilyBlues.values[0], NULL)) < 0 ||
- (code = data1.FamilyOtherBlues.count =
+ &pdata1->FamilyBlues.values[0], NULL)) < 0 ||
+ (code = pdata1->FamilyOtherBlues.count =
dict_float_array_param(pprivate,
"FamilyOtherBlues", max_FamilyOtherBlues * 2,
- &data1.FamilyOtherBlues.values[0], NULL)) < 0 ||
+ &pdata1->FamilyOtherBlues.values[0], NULL)) < 0 ||
(code = dict_bool_param(pprivate, "ForceBold", false,
- &data1.ForceBold)) < 0 ||
+ &pdata1->ForceBold)) < 0 ||
(code = dict_int_param(pprivate, "LanguageGroup", 0, 1, 0,
- &data1.LanguageGroup)) < 0 ||
- (code = data1.OtherBlues.count =
+ &pdata1->LanguageGroup)) < 0 ||
+ (code = pdata1->OtherBlues.count =
dict_float_array_param(pprivate, "OtherBlues", max_OtherBlues * 2,
- &data1.OtherBlues.values[0], NULL)) < 0 ||
+ &pdata1->OtherBlues.values[0], NULL)) < 0 ||
(code = dict_bool_param(pprivate, "RndStemUp", true,
- &data1.RndStemUp)) < 0 ||
- (code = data1.StdHW.count =
+ &pdata1->RndStemUp)) < 0 ||
+ (code = pdata1->StdHW.count =
dict_float_array_param(pprivate, "StdHW", 1,
- &data1.StdHW.values[0], NULL)) < 0 ||
- (code = data1.StdVW.count =
+ &pdata1->StdHW.values[0], NULL)) < 0 ||
+ (code = pdata1->StdVW.count =
dict_float_array_param(pprivate, "StdVW", 1,
- &data1.StdVW.values[0], NULL)) < 0 ||
- (code = data1.StemSnapH.count =
+ &pdata1->StdVW.values[0], NULL)) < 0 ||
+ (code = pdata1->StemSnapH.count =
dict_float_array_param(pprivate, "StemSnapH", max_StemSnap,
- &data1.StemSnapH.values[0], NULL)) < 0 ||
- (code = data1.StemSnapV.count =
+ &pdata1->StemSnapH.values[0], NULL)) < 0 ||
+ (code = pdata1->StemSnapV.count =
dict_float_array_param(pprivate, "StemSnapV", max_StemSnap,
- &data1.StemSnapV.values[0], NULL)) < 0 ||
+ &pdata1->StemSnapV.values[0], NULL)) < 0 ||
/* The WeightVector is in the font dictionary, not Private. */
- (code = data1.WeightVector.count =
+ (code = pdata1->WeightVector.count =
dict_float_array_param(op, "WeightVector", max_WeightVector,
- data1.WeightVector.values, NULL)) < 0
+ pdata1->WeightVector.values, NULL)) < 0
)
return code;
/*
@@ -192,7 +150,7 @@ buildfont1or4(os_ptr op, build_proc_refs * pbuild, font_type ftype,
float max_zone_height = 1.0;
#define SCAN_ZONE(z)\
- find_zone_height(&max_zone_height, data1.z.count, data1.z.values);
+ find_zone_height(&max_zone_height, pdata1->z.count, pdata1->z.values);
SCAN_ZONE(BlueValues);
SCAN_ZONE(OtherBlues);
@@ -201,50 +159,71 @@ buildfont1or4(os_ptr op, build_proc_refs * pbuild, font_type ftype,
#undef SCAN_ZONE
- if (data1.BlueScale * max_zone_height > 1.0)
- data1.BlueScale = 1.0 / max_zone_height;
+ if (pdata1->BlueScale * max_zone_height > 1.0)
+ pdata1->BlueScale = 1.0 / max_zone_height;
}
/* Do the work common to primitive font types. */
- code = build_gs_primitive_font(op, (gs_font_base **) & pfont, ftype,
+ code = build_gs_primitive_font(i_ctx_p, op, (gs_font_base **)&pfont, ftype,
&st_gs_font_type1, pbuild, options);
if (code != 0)
return code;
/* This is a new font, fill it in. */
pdata = pfont_data(pfont);
- pfont->data = data1;
- ref_assign(&pdata->u.type1.OtherSubrs, pothersubrs);
- ref_assign(&pdata->u.type1.Subrs, psubrs);
- ref_assign(&pdata->u.type1.GlobalSubrs, pglobalsubrs);
+ pfont->data = *pdata1;
+ ref_assign(&pdata->u.type1.OtherSubrs, pfr->OtherSubrs);
+ ref_assign(&pdata->u.type1.Subrs, pfr->Subrs);
+ ref_assign(&pdata->u.type1.GlobalSubrs, pfr->GlobalSubrs);
pfont->data.procs = &z1_data_procs;
pfont->data.proc_data = (char *)pdata;
return define_gs_font((gs_font *)pfont);
}
+/* Build a Type 1 or Type 4 font. */
+private int
+buildfont1or4(i_ctx_t *i_ctx_p, os_ptr op, build_proc_refs * pbuild,
+ font_type ftype, build_font_options_t options)
+{
+ charstring_font_refs_t refs;
+ int code = charstring_font_get_refs(op, &refs);
+ gs_type1_data data1;
+
+ if (code < 0)
+ return code;
+ data1.interpret = gs_type1_interpret;
+ data1.subroutineNumberBias = 0;
+ data1.lenIV = DEFAULT_LENIV_1;
+ return build_charstring_font(i_ctx_p, op, pbuild, ftype, &refs, &data1,
+ options);
+}
+
/* <string|name> <font_dict> .buildfont1 <string|name> <font> */
/* Build a type 1 (Adobe encrypted) font. */
private int
-zbuildfont1(os_ptr op)
+zbuildfont1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
build_proc_refs build;
int code = build_proc_name_refs(&build,
"%Type1BuildChar", "%Type1BuildGlyph");
if (code < 0)
return code;
- return buildfont1or4(op, &build, ft_encrypted, bf_notdef_required);
+ return buildfont1or4(i_ctx_p, op, &build, ft_encrypted,
+ bf_notdef_required);
}
/* <string|name> <font_dict> .buildfont4 <string|name> <font> */
/* Build a type 4 (disk-based Adobe encrypted) font. */
private int
-zbuildfont4(os_ptr op)
+zbuildfont4(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
build_proc_refs build;
int code = build_gs_font_procs(op, &build);
if (code < 0)
return code;
- return buildfont1or4(op, &build, ft_disk_based, bf_options_none);
+ return buildfont1or4(i_ctx_p, op, &build, ft_disk_based, bf_options_none);
}
#ifdef TEST
@@ -255,8 +234,9 @@ zbuildfont4(os_ptr op)
/* <file> .printfont1 - */
private int
-zprintfont1(os_ptr op)
+zprintfont1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gs_font *pfont = gs_currentfont(igs);
stream *s;
int code;
diff --git a/gs/src/zfont2.c b/gs/src/zfont2.c
index fd9147934..ee44ddddc 100644
--- a/gs/src/zfont2.c
+++ b/gs/src/zfont2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -17,531 +17,89 @@
*/
-/* Font creation utilities */
-#include "memory_.h"
-#include "string_.h"
+/* Type 2 font creation operators */
#include "ghost.h"
#include "oper.h"
#include "gxfixed.h"
#include "gsmatrix.h"
-#include "gxdevice.h"
-#include "gschar.h"
#include "gxfont.h"
+#include "gxfont1.h"
#include "bfont.h"
-#include "ialloc.h"
#include "idict.h"
#include "idparam.h"
-#include "ilevel.h"
-#include "iname.h"
-#include "interp.h" /* for initial_enter_name */
-#include "ipacked.h"
-#include "istruct.h"
-#include "store.h"
+#include "ifont1.h"
-/* Registered encodings. See ifont.h for documentation. */
-ref registered_Encodings;
-private ref *const registered_Encodings_p = &registered_Encodings;
+/* Declare the Type 2 interpreter. */
+extern charstring_interpret_proc(gs_type2_interpret);
-/* Structure descriptor */
-public_st_font_data();
+/* Default value of lenIV */
+#define DEFAULT_LENIV_2 (-1)
-/* Initialize the font building operators */
-private void
-zfont2_init(void)
-{ /* Initialize the registered Encodings. */
- int i;
+/* Private utilities */
+private uint
+subr_bias(const ref * psubrs)
+{
+ uint size = r_size(psubrs);
- ialloc_ref_array(&registered_Encodings, a_all,
- registered_Encodings_countof,
- "registered_Encodings");
- for (i = 0; i < registered_Encodings_countof; i++)
- make_empty_array(&registered_Encoding(i), 0);
- initial_enter_name("registeredencodings", &registered_Encodings);
- gs_register_ref_root(imemory, NULL, (void **)&registered_Encodings_p,
- "registered_Encodings");
+ return (size < 1240 ? 107 : size < 33900 ? 1131 : 32768);
}
-/* <string|name> <font_dict> .buildfont3 <string|name> <font> */
-/* Build a type 3 (user-defined) font. */
+/* <string|name> <font_dict> .buildfont2 <string|name> <font> */
+/* Build a type 2 (compact Adobe encrypted) font. */
private int
-zbuildfont3(os_ptr op)
+zbuildfont2(i_ctx_t *i_ctx_p)
{
- int code;
+ os_ptr op = osp;
+ charstring_font_refs_t refs;
build_proc_refs build;
- gs_font_base *pfont;
-
- check_type(*op, t_dictionary);
- code = build_gs_font_procs(op, &build);
- if (code < 0)
- return code;
- code = build_gs_simple_font(op, &pfont, ft_user_defined,
- &st_gs_font_base, &build, bf_options_none);
- if (code < 0)
- return code;
- return define_gs_font((gs_font *) pfont);
-}
-
-/* Encode a character. */
-private gs_glyph
-zfont_encode_char(gs_show_enum * penum, gs_font * pfont, gs_char * pchr)
-{
- const ref *pencoding = &pfont_data(pfont)->Encoding;
- ulong index = *pchr; /* work around VAX widening bug */
- ref cname;
- int code = array_get(pencoding, (long)index, &cname);
-
- if (code < 0 || !r_has_type(&cname, t_name))
- return gs_no_glyph;
- return (gs_glyph) name_index(&cname);
-}
-
-/* Encode a character in a known encoding. */
-private gs_glyph
-zfont_known_encode(gs_char chr, int encoding_index)
-{
- ulong index = chr; /* work around VAX widening bug */
- ref cname;
- int code;
-
- if (encoding_index < 0)
- return gs_no_glyph;
- code = array_get(&registered_Encoding(encoding_index),
- (long)index, &cname);
- if (code < 0 || !r_has_type(&cname, t_name))
- return gs_no_glyph;
- return (gs_glyph) name_index(&cname);
-}
-
-/* Get the name of a glyph. */
-/* The following typedef is needed to work around a bug in */
-/* some AIX C compilers. */
-typedef const char *const_chars;
-private const_chars
-zfont_glyph_name(gs_glyph index, uint * plen)
-{
- ref nref, sref;
-
- if (index >= gs_min_cid_glyph) { /* Fabricate a numeric name. */
- char cid_name[sizeof(gs_glyph) * 3 + 1];
- int code;
-
- sprintf(cid_name, "%lu", (ulong) index);
- code = name_ref((const byte *)cid_name, strlen(cid_name),
- &nref, 1);
- if (code < 0)
- return 0; /* What can we possibly do here? */
- } else
- name_index_ref(index, &nref);
- name_string_ref(&nref, &sref);
- *plen = r_size(&sref);
- return (const char *)sref.value.const_bytes;
-}
-
-/* ------ Initialization procedure ------ */
-
-const op_def zfont2_op_defs[] =
-{
- {"2.buildfont3", zbuildfont3},
- op_def_end(zfont2_init)
-};
-
-/* ------ Subroutines ------ */
-
-/* Convert strings to executable names for build_proc_refs. */
-int
-build_proc_name_refs(build_proc_refs * pbuild,
- const char *bcstr, const char *bgstr)
-{
- int code;
-
- if (!bcstr)
- make_null(&pbuild->BuildChar);
- else {
- if ((code = name_ref((const byte *)bcstr, strlen(bcstr), &pbuild->BuildChar, 0)) < 0)
- return code;
- r_set_attrs(&pbuild->BuildChar, a_executable);
- }
- if (!bgstr)
- make_null(&pbuild->BuildGlyph);
- else {
- if ((code = name_ref((const byte *)bgstr, strlen(bgstr), &pbuild->BuildGlyph, 0)) < 0)
- return code;
- r_set_attrs(&pbuild->BuildGlyph, a_executable);
- }
- return 0;
-}
-
-/* Get the BuildChar and/or BuildGlyph routines from a (base) font. */
-int
-build_gs_font_procs(os_ptr op, build_proc_refs * pbuild)
-{
- int ccode, gcode;
- ref *pBuildChar;
- ref *pBuildGlyph;
-
- check_type(*op, t_dictionary);
- ccode = dict_find_string(op, "BuildChar", &pBuildChar);
- gcode = dict_find_string(op, "BuildGlyph", &pBuildGlyph);
- if (ccode <= 0) {
- if (gcode <= 0)
- return_error(e_invalidfont);
- make_null(&pbuild->BuildChar);
- } else {
- check_proc(*pBuildChar);
- pbuild->BuildChar = *pBuildChar;
- }
- if (gcode <= 0)
- make_null(&pbuild->BuildGlyph);
- else {
- check_proc(*pBuildGlyph);
- pbuild->BuildGlyph = *pBuildGlyph;
- }
- return 0;
-}
-
-/* Do the common work for building a primitive font -- one whose execution */
-/* algorithm is implemented in C (Type 1, Type 4, or Type 42). */
-/* The caller guarantees that *op is a dictionary. */
-int
-build_gs_primitive_font(os_ptr op, gs_font_base ** ppfont, font_type ftype,
- gs_memory_type_ptr_t pstype,
- const build_proc_refs * pbuild,
- build_font_options_t options)
-{
- int painttype;
- float strokewidth;
- ref *pcharstrings = 0;
- gs_font_base *pfont;
- font_data *pdata;
- int code;
-
- code = dict_int_param(op, "PaintType", 0, 3, 0, &painttype);
- if (code < 0)
- return code;
- code = dict_float_param(op, "StrokeWidth", 0.0, &strokewidth);
- if (code < 0)
- return code;
- if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) {
- if (!(options & bf_CharStrings_optional))
- return_error(e_invalidfont);
- } else {
- ref *ignore;
-
- if (!r_has_type(pcharstrings, t_dictionary))
- return_error(e_invalidfont);
- if ((options & bf_notdef_required) != 0 &&
- dict_find_string(pcharstrings, ".notdef", &ignore) <= 0
- )
- return_error(e_invalidfont);
- }
- code = build_gs_simple_font(op, &pfont, ftype, pstype, pbuild, options);
- if (code != 0)
- return code;
- pfont->PaintType = painttype;
- pfont->StrokeWidth = strokewidth;
- pdata = pfont_data(pfont);
- if (pcharstrings)
- ref_assign(&pdata->CharStrings, pcharstrings);
- else
- make_null(&pdata->CharStrings);
- /* Check that the UniqueIDs match. This is part of the */
- /* Adobe protection scheme, but we may as well emulate it. */
- if (uid_is_valid(&pfont->UID) &&
- !dict_check_uid_param(op, &pfont->UID)
- )
- uid_set_invalid(&pfont->UID);
- *ppfont = pfont;
- return 0;
-}
-
-/* Do the common work for building a font of any non-composite FontType. */
-/* The caller guarantees that *op is a dictionary. */
-int
-build_gs_simple_font(os_ptr op, gs_font_base ** ppfont, font_type ftype,
- gs_memory_type_ptr_t pstype,
- const build_proc_refs * pbuild,
- build_font_options_t options)
-{
- double bbox[4];
- gs_uid uid;
- int code;
- gs_font_base *pfont;
+ int code = build_proc_name_refs(&build,
+ "%Type2BuildChar", "%Type2BuildGlyph");
+ gs_type1_data data1;
+ float dwx, nwx;
- code = font_bbox_param(op, bbox);
if (code < 0)
return code;
- if ((options & bf_FontBBox_required) &&
- bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0
- )
- return_error(e_invalidfont);
- code = dict_uid_param(op, &uid, 0, imemory);
+ code = charstring_font_get_refs(op, &refs);
if (code < 0)
return code;
- if ((options & bf_UniqueID_ignored) && uid_is_UniqueID(&uid))
- uid_set_invalid(&uid);
- code = build_gs_font(op, (gs_font **) ppfont, ftype, pstype, pbuild,
- options);
- if (code != 0) /* invalid or scaled font */
- return code;
- pfont = *ppfont;
- pfont->procs.init_fstack = gs_default_init_fstack;
- pfont->procs.next_char = gs_default_next_char;
- pfont->procs.define_font = gs_no_define_font;
- pfont->procs.make_font = zbase_make_font;
- pfont->FontBBox.p.x = bbox[0];
- pfont->FontBBox.p.y = bbox[1];
- pfont->FontBBox.q.x = bbox[2];
- pfont->FontBBox.q.y = bbox[3];
- pfont->UID = uid;
- lookup_gs_simple_font_encoding(pfont);
- return 0;
-}
-
-/* Compare the encoding of a simple font with the registered encodings. */
-void
-lookup_gs_simple_font_encoding(gs_font_base * pfont)
-{
- const ref *pfe = &pfont_data(pfont)->Encoding;
- int index;
-
- for (index = registered_Encodings_countof; --index >= 0;)
- if (obj_eq(pfe, &registered_Encoding(index)))
- break;
- pfont->encoding_index = index;
- if (index < 0) { /* Look for an encoding that's "close". */
- int near_index = -1;
- uint esize = r_size(pfe);
- uint best = esize / 3; /* must match at least this many */
-
- for (index = registered_Encodings_countof; --index >= 0;) {
- const ref *pre = &registered_Encoding(index);
- bool r_packed = r_has_type(pre, t_shortarray);
- bool f_packed = !r_has_type(pfe, t_array);
- uint match = esize;
- int i;
- ref fchar, rchar;
- const ref *pfchar = &fchar;
-
- if (r_size(pre) != esize)
- continue;
- for (i = esize; --i >= 0;) {
- uint rnidx;
-
- if (r_packed)
- rnidx = packed_name_index(pre->value.packed + i);
- else {
- array_get(pre, (long)i, &rchar);
- rnidx = name_index(&rchar);
- }
- if (f_packed)
- array_get(pfe, (long)i, &fchar);
- else
- pfchar = pfe->value.const_refs + i;
- if (!r_has_type(pfchar, t_name) ||
- name_index(pfchar) != rnidx
- )
- if (--match <= best)
- break;
- }
- if (match > best)
- best = match,
- near_index = index;
- }
- index = near_index;
- }
- pfont->nearest_encoding_index = index;
-}
-
-/* Do the common work for building a font of any FontType. */
-/* The caller guarantees that *op is a dictionary. */
-/* op[-1] must be the key under which the font is being registered */
-/* in FontDirectory, normally a name or string. */
-/* Return 0 for a new font, 1 for a font made by makefont or scalefont, */
-/* or a negative error code. */
-private void get_font_name(P2(ref *, const ref *));
-private void copy_font_name(P2(gs_font_name *, const ref *));
-int
-build_gs_font(os_ptr op, gs_font ** ppfont, font_type ftype,
- gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild,
- build_font_options_t options)
-{
- ref kname, fname; /* t_string */
- ref *pftype;
- ref *pfontname;
- ref *pmatrix;
- gs_matrix mat;
- ref *pencoding = 0;
- bool bitmapwidths;
- int exactsize, inbetweensize, transformedchar;
- int wmode;
- int code;
- gs_font *pfont;
- ref *pfid;
- ref *aop = dict_access_ref(op);
-
- get_font_name(&kname, op - 1);
- if (dict_find_string(op, "FontType", &pftype) <= 0 ||
- !r_has_type(pftype, t_integer) ||
- pftype->value.intval != (int)ftype ||
- dict_find_string(op, "FontMatrix", &pmatrix) <= 0 ||
- read_matrix(pmatrix, &mat) < 0
- )
- return_error(e_invalidfont);
- if (dict_find_string(op, "Encoding", &pencoding) <= 0) {
- if (!(options & bf_Encoding_optional))
- return_error(e_invalidfont);
- } else {
- if (!r_is_array(pencoding))
- return_error(e_invalidfont);
+ data1.interpret = gs_type2_interpret;
+ data1.lenIV = DEFAULT_LENIV_2;
+ data1.subroutineNumberBias = subr_bias(refs.Subrs);
+ /* Get information specific to Type 2 fonts. */
+ if (dict_find_string(refs.Private, "GlobalSubrs", &refs.GlobalSubrs) > 0) {
+ if (!r_is_array(refs.GlobalSubrs))
+ return_error(e_typecheck);
}
- if (dict_find_string(op, "FontName", &pfontname) > 0)
- get_font_name(&fname, pfontname);
- else
- make_empty_string(&fname, a_readonly);
- if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 ||
- (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 ||
- (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 ||
- (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 ||
- (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0
+ data1.gsubrNumberBias = subr_bias(refs.GlobalSubrs);
+ if ((code = dict_uint_param(refs.Private, "gsubrNumberBias",
+ 0, max_uint, data1.gsubrNumberBias,
+ &data1.gsubrNumberBias)) < 0 ||
+ (code = dict_float_param(refs.Private, "defaultWidthX", 0.0,
+ &dwx)) < 0 ||
+ (code = dict_float_param(refs.Private, "nominalWidthX", 0.0,
+ &nwx)) < 0
)
return code;
- code = dict_find_string(op, "FID", &pfid);
- if (code > 0) {
- if (!r_has_type(pfid, t_fontID))
- return_error(e_invalidfont);
- /*
- * If this font has a FID entry already, it might be
- * a scaled font made by makefont or scalefont;
- * in a Level 2 environment, it might be an existing font
- * being registered under a second name, or a re-encoded
- * font (which is questionable PostScript, but dvips
- * is known to do this).
- */
- pfont = r_ptr(pfid, gs_font);
- if (pfont->base == pfont) { /* original font */
- if (!level2_enabled)
- return_error(e_invalidfont);
- if (obj_eq(pfont_dict(pfont), op)) {
- *ppfont = pfont;
- return 1;
- }
- /*
- * This is a re-encoded font, or some other
- * questionable situation in which the FID
- * was preserved. Pretend the FID wasn't there.
- */
- } else { /* This was made by makefont or scalefont. */
- /* Just insert the new name. */
- code = 1;
- goto set_name;
- }
- }
- /* This is a new font. */
- if (!r_has_attr(aop, a_write))
- return_error(e_invalidaccess);
+ data1.defaultWidthX = float2fixed(dwx);
+ data1.nominalWidthX = float2fixed(nwx);
{
- font_data *pdata;
- ref encoding;
- /*
- * Make sure that we allocate the font data
- * in the same VM as the font dictionary.
- */
- uint space = ialloc_space(idmemory);
+ ref *pirs;
- /*
- * Since add_FID may resize the dictionary and cause
- * pencoding to become invalid, save the Encoding.
- */
- if (pencoding)
- encoding = *pencoding;
- ialloc_set_space(idmemory, r_space(op));
- pfont = ialloc_struct(gs_font, pstype,
- "buildfont(font)");
- pdata = ialloc_struct(font_data, &st_font_data,
- "buildfont(data)");
- if (pfont == 0 || pdata == 0)
- code = gs_note_error(e_VMerror);
+ if (dict_find_string(refs.Private, "initialRandomSeed", &pirs) <= 0)
+ data1.initialRandomSeed = 0;
+ else if (!r_has_type(pirs, t_integer))
+ return_error(e_typecheck);
else
- code = add_FID(op, pfont);
- if (code < 0) {
- ifree_object(pdata, "buildfont(data)");
- ifree_object(pfont, "buildfont(font)");
- ialloc_set_space(idmemory, space);
- return code;
- }
- refset_null((ref *) pdata, sizeof(font_data) / sizeof(ref));
- ref_assign_new(&pdata->dict, op);
- ref_assign_new(&pdata->BuildChar, &pbuild->BuildChar);
- ref_assign_new(&pdata->BuildGlyph, &pbuild->BuildGlyph);
- if (pencoding)
- ref_assign_new(&pdata->Encoding, &encoding);
- /* Clear the chain pointers so as not to confuse the memory */
- /* manager if we bail out after returning from here. */
- pfont->next = pfont->prev = 0;
- pfont->memory = imemory;
- pfont->dir = 0;
- pfont->base = pfont;
- pfont->client_data = pdata;
- pfont->FontType = ftype;
- pfont->FontMatrix = mat;
- pfont->BitmapWidths = bitmapwidths;
- pfont->ExactSize = (fbit_type) exactsize;
- pfont->InBetweenSize = (fbit_type) inbetweensize;
- pfont->TransformedChar = (fbit_type) transformedchar;
- pfont->WMode = wmode;
- pfont->PaintType = 0;
- pfont->StrokeWidth = 0.0;
- pfont->procs.build_char = gs_no_build_char;
- pfont->procs.encode_char = zfont_encode_char;
- pfont->procs.callbacks.glyph_name = zfont_glyph_name;
- pfont->procs.callbacks.known_encode = zfont_known_encode;
- ialloc_set_space(idmemory, space);
- }
- code = 0;
-set_name:
- copy_font_name(&pfont->key_name, &kname);
- copy_font_name(&pfont->font_name, &fname);
- *ppfont = pfont;
- return code;
-}
-
-/* Get the string corresponding to a font name. */
-/* If the font name isn't a name or a string, return an empty string. */
-private void
-get_font_name(ref * pfname, const ref * op)
-{
- switch (r_type(op)) {
- case t_string:
- *pfname = *op;
- break;
- case t_name:
- name_string_ref(op, pfname);
- break;
- default:
- /* This is weird, but legal.... */
- make_empty_string(pfname, a_readonly);
+ data1.initialRandomSeed = pirs->value.intval;
}
+ return build_charstring_font(i_ctx_p, op, &build, ft_encrypted2, &refs,
+ &data1, bf_notdef_required);
}
-/* Copy a font name into the gs_font structure. */
-private void
-copy_font_name(gs_font_name * pfstr, const ref * pfname)
-{
- uint size = r_size(pfname);
-
- if (size > gs_font_name_max)
- size = gs_font_name_max;
- memcpy(&pfstr->chars[0], pfname->value.const_bytes, size);
- /* Following is only for debugging printout. */
- pfstr->chars[size] = 0;
- pfstr->size = size;
-}
+/* ------ Initialization procedure ------ */
-/* Finish building a font, by calling gs_definefont if needed. */
-int
-define_gs_font(gs_font * pfont)
+const op_def zfont2_op_defs[] =
{
- return (pfont->base == pfont && pfont->dir == 0 ? /* i.e., unregistered original font */
- gs_definefont(ifont_dir, pfont) :
- 0);
-}
+ {"2.buildfont2", zbuildfont2},
+ op_def_end(0)
+};
diff --git a/gs/src/zfont32.c b/gs/src/zfont32.c
index 9062e74bc..4338733d9 100644
--- a/gs/src/zfont32.c
+++ b/gs/src/zfont32.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -39,8 +39,9 @@ zfont_no_encode_char(gs_show_enum * penum, gs_font * pfont, gs_char * pchr)
/* <string|name> <font_dict> .buildfont32 <string|name> <font> */
/* Build a type 32 (bitmap) font. */
private int
-zbuildfont32(os_ptr op)
+zbuildfont32(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
build_proc_refs build;
gs_font_base *pfont;
@@ -49,8 +50,9 @@ zbuildfont32(os_ptr op)
code = build_proc_name_refs(&build, NULL, "%Type32BuildGlyph");
if (code < 0)
return code;
- code = build_gs_simple_font(op, &pfont, ft_CID_bitmap, &st_gs_font_base,
- &build, bf_Encoding_optional);
+ code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_CID_bitmap,
+ &st_gs_font_base, &build,
+ bf_Encoding_optional);
if (code < 0)
return code;
/* Always transform cached bitmaps. */
diff --git a/gs/src/zfont42.c b/gs/src/zfont42.c
index 281a4a0c2..ed6183550 100644
--- a/gs/src/zfont42.c
+++ b/gs/src/zfont42.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -37,8 +37,9 @@ private int z42_gdir_get_outline(P3(gs_font_type42 *, uint, gs_const_string *));
/* <string|name> <font_dict> .buildfont11/42 <string|name> <font> */
/* Build a type 11 (TrueType CID-keyed) or 42 (TrueType) font. */
int
-build_gs_TrueType_font(os_ptr op, font_type ftype, const char *bcstr,
- const char *bgstr, build_font_options_t options)
+build_gs_TrueType_font(i_ctx_t *i_ctx_p, os_ptr op, font_type ftype,
+ const char *bcstr, const char *bgstr,
+ build_font_options_t options)
{
build_proc_refs build;
ref sfnts, sfnts0, GlyphDirectory;
@@ -72,7 +73,7 @@ build_gs_TrueType_font(os_ptr op, font_type ftype, const char *bcstr,
*/
sfnts = *psfnts;
}
- code = build_gs_primitive_font(op, (gs_font_base **) & pfont, ftype,
+ code = build_gs_primitive_font(i_ctx_p, op, (gs_font_base **)&pfont, ftype,
&st_gs_font_type42, &build, options);
if (code != 0)
return code;
@@ -111,9 +112,11 @@ build_gs_TrueType_font(os_ptr op, font_type ftype, const char *bcstr,
return define_gs_font((gs_font *) pfont);
}
private int
-zbuildfont42(os_ptr op)
+zbuildfont42(i_ctx_t *i_ctx_p)
{
- return build_gs_TrueType_font(op, ft_TrueType, "%Type42BuildChar",
+ os_ptr op = osp;
+
+ return build_gs_TrueType_font(i_ctx_p, op, ft_TrueType, "%Type42BuildChar",
"%Type42BuildGlyph", bf_options_none);
}
diff --git a/gs/src/zfproc.c b/gs/src/zfproc.c
index 4293b6abd..754ec0029 100644
--- a/gs/src/zfproc.c
+++ b/gs/src/zfproc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -93,7 +93,8 @@ s_proc_init(ref * sop, stream ** psstrm, uint mode,
/* This is logically unrelated to procedure streams, */
/* but it is also associated with the interpreter stream machinery. */
private int
-s_handle_intc(const ref * pstate, int nstate, int (*cont) (P1(os_ptr)))
+s_handle_intc(i_ctx_t *i_ctx_p, const ref *pstate, int nstate,
+ op_proc_t cont)
{
int npush = nstate + 2;
@@ -120,7 +121,7 @@ s_handle_intc(const ref * pstate, int nstate, int (*cont) (P1(os_ptr)))
/* Forward references */
private stream_proc_process(s_proc_read_process);
-private int s_proc_read_continue(P1(os_ptr));
+private int s_proc_read_continue(P1(i_ctx_t *));
/* Stream templates */
private const stream_template s_proc_read_template = {
@@ -172,15 +173,15 @@ s_proc_read_process(stream_state * st, stream_cursor_read * ignore_pr,
/* Handle an exception (INTC or CALLC) from a read stream */
/* whose buffer is empty. */
int
-s_handle_read_exception(int status, const ref * fop, const ref * pstate,
- int nstate, int (*cont) (P1(os_ptr)))
+s_handle_read_exception(i_ctx_t *i_ctx_p, int status, const ref * fop,
+ const ref * pstate, int nstate, op_proc_t cont)
{
int npush = nstate + 4;
stream *ps;
switch (status) {
case INTC:
- return s_handle_intc(pstate, nstate, cont);
+ return s_handle_intc(i_ctx_p, pstate, nstate, cont);
case CALLC:
break;
default:
@@ -205,8 +206,9 @@ s_handle_read_exception(int status, const ref * fop, const ref * pstate,
/* osp[-1] contains the new data string (pushed by the procedure). */
/* The top of the e-stack contains the real continuation. */
private int
-s_proc_read_continue(os_ptr op)
+s_proc_read_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr opbuf = op - 1;
stream *ps;
stream_proc_state *ss;
@@ -228,7 +230,7 @@ s_proc_read_continue(os_ptr op)
/* Forward references */
private stream_proc_process(s_proc_write_process);
-private int s_proc_write_continue(P1(os_ptr));
+private int s_proc_write_continue(P1(i_ctx_t *));
/* Stream templates */
private const stream_template s_proc_write_template = {
@@ -279,15 +281,15 @@ s_proc_write_process(stream_state * st, stream_cursor_read * pr,
/* Handle an exception (INTC or CALLC) from a write stream */
/* whose buffer is full. */
int
-s_handle_write_exception(int status, const ref * fop, const ref * pstate,
- int nstate, int (*cont) (P1(os_ptr)))
+s_handle_write_exception(i_ctx_t *i_ctx_p, int status, const ref * fop,
+ const ref * pstate, int nstate, op_proc_t cont)
{
stream *ps;
stream_proc_state *psst;
switch (status) {
case INTC:
- return s_handle_intc(pstate, nstate, cont);
+ return s_handle_intc(i_ctx_p, pstate, nstate, cont);
case CALLC:
break;
default:
@@ -329,8 +331,9 @@ s_handle_write_exception(int status, const ref * fop, const ref * pstate,
/* osp[-1] contains the new buffer string (pushed by the procedure). */
/* The top of the e-stack contains the real continuation. */
private int
-s_proc_write_continue(os_ptr op)
+s_proc_write_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr opbuf = op - 1;
stream *ps;
stream_proc_state *ss;
diff --git a/gs/src/zfreuse.c b/gs/src/zfreuse.c
index 6f254326b..494b149c4 100644
--- a/gs/src/zfreuse.c
+++ b/gs/src/zfreuse.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,6 +30,8 @@
#include "iname.h"
#include "store.h"
+/* ---------------- Reusable streams ---------------- */
+
/*
* The actual work of constructing the filter is done in PostScript code.
* The operators in this file are internal ones that handle the dirty work.
@@ -39,8 +41,9 @@
/* filters is always an array, and decodeparms is always either an array */
/* of the same length as filters, or null. */
private int
-zrsdparams(os_ptr op)
+zrsdparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *pFilter;
ref *pDecodeParms;
int Intent;
@@ -80,7 +83,7 @@ zrsdparams(os_ptr op)
return_error(e_typecheck);
name_string_ref(&f, &fname);
if (r_size(&fname) < 6 ||
- !memcmp(fname.value.bytes + r_size(&fname) - 6, "Decode", 6)
+ memcmp(fname.value.bytes + r_size(&fname) - 6, "Decode", 6)
)
return_error(e_rangecheck);
if (pDecodeParms) {
@@ -105,17 +108,18 @@ zrsdparams(os_ptr op)
/* <file|string> <length|null> <CloseSource> .reusablestream <filter> */
/*
* The file|string operand must be a "reusable source", either:
- * - A string;
+ * - A string or bytestring;
* - A readable, positionable file stream;
* - A SubFileDecode filter with an empty EODString and a reusable
* source;
* - A reusable stream.
*/
-private int make_rss(P6(os_ptr op, const byte * data, uint size, long offset,
- long length, bool close_source));
+private int make_rss(P7(os_ptr op, const byte * data, uint size, long offset,
+ long length, bool is_bytestring, bool close_source));
private int
-zreusablestream(os_ptr op)
+zreusablestream(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr source_op = op - 2;
os_ptr length_op = op - 1;
long length;
@@ -131,9 +135,21 @@ zreusablestream(os_ptr op)
check_type(*op, t_boolean);
close_source = op->value.boolval;
if (r_has_type(source_op, t_string)) {
+ uint size = r_size(source_op);
+
check_read(*source_op);
code = make_rss(source_op, source_op->value.const_bytes,
- r_size(source_op), 0L, length, close_source);
+ size, 0L, (length < 0 ? size : length), false,
+ close_source);
+ } else if (r_has_type(source_op, t_astruct)) {
+ uint size = gs_object_size(imemory, source_op->value.pstruct);
+
+ if (gs_object_type(imemory, source_op->value.pstruct) != &st_bytes)
+ return_error(e_rangecheck);
+ check_read(*source_op);
+ code = make_rss(source_op, (const byte *)source_op->value.pstruct,
+ size, 0L, (length < 0 ? size : length), true,
+ close_source);
} else {
long offset = 0;
stream *source;
@@ -148,14 +164,13 @@ rs:
savailable(source, &avail);
if (avail < 0)
avail = 0;
- if (avail > length)
- avail = length;
code = make_rss(source_op, source->cbuf_string.data,
- source->cbuf_string.size, offset, avail,
+ source->cbuf_string.size, offset, avail, false,
close_source);
} else if (source->file != 0) {
/* The data source is a file. */
-/****** NYI ******/
+ /****** NYI ******/
+ return_error(e_rangecheck);
} else if (source->state->template == &s_SFD_template) {
/* The data source is a SubFileDecode filter. */
const stream_SFD_state *const sfd_state =
@@ -172,9 +187,10 @@ rs:
source = source->strm;
goto rs;
}
-/****** REUSABLE CASE IS NYI ******/
- else
+ else {
+ /****** REUSABLE CASE IS NYI ******/
return_error(e_rangecheck);
+ }
}
if (code >= 0)
pop(2);
@@ -184,17 +200,27 @@ rs:
/* Make a reusable string stream. */
private int
make_rss(os_ptr op, const byte * data, uint size, long offset,
- long length, bool close_source)
+ long length, bool is_bytestring, bool close_source)
{
-/****** NYI ******/
- return_error(e_rangecheck);
+ stream *s;
+
+ /****** SELECT CORRECT VM FOR ALLOCATION ******/
+ s = file_alloc_stream(imemory, "make_rss");
+ if (s == 0)
+ return_error(e_VMerror);
+ sread_string_reusable(s, data + offset, min(length, size - offset));
+ if (is_bytestring)
+ s->cbuf_string.data = 0; /* byte array, not string */
+ /****** DO WHAT WITH close_source ? ******/
+ make_stream_file(op, s, "r");
+ return 0;
}
/* ---------------- Initialization procedure ---------------- */
const op_def zfreuse_op_defs[] =
{
- {"2.rsdparams", zrsdparams},
{"2.reusablestream", zreusablestream},
+ {"2.rsdparams", zrsdparams},
op_def_end(0)
};
diff --git a/gs/src/zfunc.c b/gs/src/zfunc.c
index 6a23efcb3..dd910b4c7 100644
--- a/gs/src/zfunc.c
+++ b/gs/src/zfunc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -21,6 +21,7 @@
#include "memory_.h"
#include "ghost.h"
#include "oper.h"
+#include "gscdefs.h"
#include "gsfunc.h"
#include "gsstruct.h"
#include "ialloc.h"
@@ -32,19 +33,6 @@
/* Define the maximum depth of nesting of subsidiary functions. */
#define MAX_SUB_FUNCTION_DEPTH 3
-/* Define the table of build procedures. */
-build_function_proc((*build_function_procs[5])) = {
- build_function_undefined, build_function_undefined, build_function_undefined,
- build_function_undefined, build_function_undefined
-};
-
-int
-build_function_undefined(const_os_ptr op, const gs_function_params_t * mnDR,
- int depth, gs_function_t ** ppfn)
-{
- return_error(e_rangecheck);
-}
-
/* GC descriptors */
gs_private_st_ptr(st_function_ptr, gs_function_t *, "gs_function_t *",
function_ptr_enum_ptrs, function_ptr_reloc_ptrs);
@@ -54,12 +42,13 @@ gs_private_st_element(st_function_ptr_element, gs_function_t *,
/* ------ Operators ------ */
-private int zexecfunction(P1(os_ptr op));
+private int zexecfunction(P1(i_ctx_t *));
/* <dict> .buildfunction <function_struct> */
private int
-zbuildfunction(os_ptr op)
+zbuildfunction(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_function_t *pfn;
ref cref; /* closure */
int code;
@@ -81,8 +70,11 @@ zbuildfunction(os_ptr op)
/* <in1> ... <function_struct> %execfunction <out1> ... */
private int
-zexecfunction(os_ptr op)
-{ /*
+zexecfunction(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+
+ /*
* Since this operator's name begins with %, the name is not defined
* in systemdict. The only place this operator can ever appear is
* in the execute-only closure created by .buildfunction.
@@ -138,16 +130,20 @@ zexecfunction(os_ptr op)
int
fn_build_sub_function(const ref * op, gs_function_t ** ppfn, int depth)
{
- int code, type;
+ int code, type, i;
gs_function_params_t params;
if (depth > MAX_SUB_FUNCTION_DEPTH)
return_error(e_limitcheck);
check_type(*op, t_dictionary);
- code = dict_int_param(op, "FunctionType", 0,
- countof(build_function_procs) - 1, -1, &type);
+ code = dict_int_param(op, "FunctionType", 0, max_int, -1, &type);
if (code < 0)
return code;
+ for (i = 0; i < build_function_type_table_count; ++i)
+ if (build_function_type_table[i].type == type)
+ break;
+ if (i == build_function_type_table_count)
+ return_error(e_rangecheck);
/* Collect parameters common to all function types. */
params.Domain = 0;
params.Range = 0;
@@ -161,10 +157,10 @@ fn_build_sub_function(const ref * op, gs_function_t ** ppfn, int depth)
params.n = code >> 1;
/* Finish building the function. */
/* If this fails, it will free all the parameters. */
- return (*build_function_procs[type]) (op, &params, depth + 1, ppfn);
+ return (*build_function_type_table[i].proc)(op, &params, depth + 1, ppfn);
fail:
- ifree_object((void *)params.Range, "Range"); /* break const */
- ifree_object((void *)params.Domain, "Domain"); /* break const */
+ ifree_const_object(params.Range, "Range");
+ ifree_const_object(params.Domain, "Domain");
return code;
}
diff --git a/gs/src/zfunc0.c b/gs/src/zfunc0.c
index 533276a19..89cc7c033 100644
--- a/gs/src/zfunc0.c
+++ b/gs/src/zfunc0.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,24 +31,10 @@
#include "idparam.h"
#include "ifunc.h"
-/* Initialization */
-private build_function_proc(build_function_0);
-int
-zfunc0_init(gs_memory_t * mem)
-{
- build_function_procs[0] = build_function_0;
- return 0;
-}
-
-const op_def zfunc0_op_defs[] =
-{
- op_def_end(zfunc0_init)
-};
-
/* Finish building a FunctionType 0 (Sampled) function. */
-private int
-build_function_0(const_os_ptr op, const gs_function_params_t * mnDR, int depth,
- gs_function_t ** ppfn)
+int
+gs_build_function_0(const ref *op, const gs_function_params_t * mnDR,
+ int depth, gs_function_t ** ppfn)
{
gs_function_Sd_params_t params;
ref *pDataSource;
diff --git a/gs/src/zfunc3.c b/gs/src/zfunc3.c
index c88ef8b96..c9d3cbb6b 100644
--- a/gs/src/zfunc3.c
+++ b/gs/src/zfunc3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,28 +31,12 @@
#include "ifunc.h"
#include "store.h"
-/* Initialization */
-private build_function_proc(build_function_2);
-private build_function_proc(build_function_3);
-int
-zfunc3_init(gs_memory_t * mem)
-{
- build_function_procs[2] = build_function_2;
- build_function_procs[3] = build_function_3;
- return 0;
-}
-
-const op_def zfunc3_op_defs[] =
-{
- op_def_end(zfunc3_init)
-};
-
/* Define the available Function types. */
/* Finish building a FunctionType 2 (ExponentialInterpolation) function. */
-private int
-build_function_2(const_os_ptr op, const gs_function_params_t * mnDR, int depth,
- gs_function_t ** ppfn)
+int
+gs_build_function_2(const ref *op, const gs_function_params_t * mnDR,
+ int depth, gs_function_t ** ppfn)
{
gs_function_ElIn_params_t params;
int code, n0, n1;
@@ -82,9 +66,9 @@ fail:
}
/* Finish building a FunctionType 3 (1-Input Stitching) function. */
-private int
-build_function_3(const_os_ptr op, const gs_function_params_t * mnDR, int depth,
- gs_function_t ** ppfn)
+int
+gs_build_function_3(const ref *op, const gs_function_params_t * mnDR,
+ int depth, gs_function_t ** ppfn)
{
gs_function_1ItSg_params_t params;
int code;
diff --git a/gs/src/zfzlib.c b/gs/src/zfzlib.c
index 589337de2..26e1b8945 100644
--- a/gs/src/zfzlib.c
+++ b/gs/src/zfzlib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -28,56 +28,56 @@
#include "ifilter.h"
/* Import the Predictor machinery from zfdecode.c and zfilter2.c. */
-int filter_read_predictor(P4(os_ptr op, int npop,
+int filter_read_predictor(P4(i_ctx_t *i_ctx_p, int npop,
const stream_template * template,
stream_state * st));
-int filter_write_predictor(P4(os_ptr op, int npop,
+int filter_write_predictor(P4(i_ctx_t *i_ctx_p, int npop,
const stream_template * template,
stream_state * st));
/* <source> zlibEncode/filter <file> */
/* <source> <dict> zlibEncode/filter <file> */
private int
-zzlibE(os_ptr op)
+zzlibE(i_ctx_t *i_ctx_p)
{
stream_zlib_state zls;
(*s_zlibE_template.set_defaults)((stream_state *)&zls);
- return filter_write(op, 0, &s_zlibE_template, (stream_state *)&zls, 0);
+ return filter_write(i_ctx_p, 0, &s_zlibE_template, (stream_state *)&zls, 0);
}
/* <target> zlibDecode/filter <file> */
/* <target> <dict> zlibDecode/filter <file> */
private int
-zzlibD(os_ptr op)
+zzlibD(i_ctx_t *i_ctx_p)
{
stream_zlib_state zls;
(*s_zlibD_template.set_defaults)((stream_state *)&zls);
- return filter_read(op, 0, &s_zlibD_template, (stream_state *)&zls, 0);
+ return filter_read(i_ctx_p, 0, &s_zlibD_template, (stream_state *)&zls, 0);
}
/* <source> FlateEncode/filter <file> */
/* <source> <dict> FlateEncode/filter <file> */
private int
-zFlateE(os_ptr op)
+zFlateE(i_ctx_t *i_ctx_p)
{
stream_zlib_state zls;
(*s_zlibE_template.set_defaults)((stream_state *)&zls);
- return filter_write_predictor(op, 0, &s_zlibE_template,
+ return filter_write_predictor(i_ctx_p, 0, &s_zlibE_template,
(stream_state *)&zls);
}
/* <target> FlateDecode/filter <file> */
/* <target> <dict> FlateDecode/filter <file> */
private int
-zFlateD(os_ptr op)
+zFlateD(i_ctx_t *i_ctx_p)
{
stream_zlib_state zls;
(*s_zlibD_template.set_defaults)((stream_state *)&zls);
- return filter_read_predictor(op, 0, &s_zlibD_template,
+ return filter_read_predictor(i_ctx_p, 0, &s_zlibD_template,
(stream_state *)&zls);
}
diff --git a/gs/src/zgeneric.c b/gs/src/zgeneric.c
index e1b0da620..ebddb1c50 100644
--- a/gs/src/zgeneric.c
+++ b/gs/src/zgeneric.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -20,9 +20,10 @@
/* Array/string/dictionary generic operators for PostScript */
#include "memory_.h"
#include "ghost.h"
+#include "gsstruct.h" /* for st_bytes */
#include "oper.h"
#include "estack.h" /* for forall */
-#include "idict.h"
+#include "iddict.h"
#include "iname.h"
#include "ipacked.h"
#include "ivmspace.h"
@@ -37,11 +38,11 @@
/* more efficient implementation of forall. */
/* Imported operators */
-extern int zcopy_dict(P1(os_ptr));
+extern int zcopy_dict(P1(i_ctx_t *));
/* Forward references */
-private int zcopy_integer(P1(os_ptr));
-private int zcopy_interval(P1(os_ptr));
+private int zcopy_integer(P1(i_ctx_t *));
+private int zcopy_interval(P1(i_ctx_t *));
private int copy_interval(P4(os_ptr, uint, os_ptr, client_name_t));
/* <various1> <various2> copy <various> */
@@ -49,19 +50,20 @@ private int copy_interval(P4(os_ptr, uint, os_ptr, client_name_t));
/* Note that this implements copy for arrays and strings, */
/* but not for dictionaries (see zcopy_dict in zdict.c). */
int
-zcopy(register os_ptr op)
+zcopy(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int type = r_type(op);
if (type == t_integer)
- return zcopy_integer(op);
+ return zcopy_integer(i_ctx_p);
check_op(2);
switch (type) {
case t_array:
case t_string:
- return zcopy_interval(op);
+ return zcopy_interval(i_ctx_p);
case t_dictionary:
- return zcopy_dict(op);
+ return zcopy_dict(i_ctx_p);
default:
return_op_typecheck(op);
}
@@ -69,8 +71,9 @@ zcopy(register os_ptr op)
/* <obj1> ... <objn> <int> copy <obj1> ... <objn> <obj1> ... <objn> */
private int
-zcopy_integer(register os_ptr op)
+zcopy_integer(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int count, i;
int code;
@@ -98,8 +101,9 @@ zcopy_integer(register os_ptr op)
/* <array1> <array2> copy <subarray2> */
/* <string1> <string2> copy <substring2> */
private int
-zcopy_interval(register os_ptr op)
+zcopy_interval(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int code = copy_interval(op, 0, op1, "copy");
@@ -113,8 +117,9 @@ zcopy_interval(register os_ptr op)
/* <array|dict|name|packedarray|string> length <int> */
private int
-zlength(register os_ptr op)
+zlength(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
switch (r_type(op)) {
case t_array:
case t_string:
@@ -134,6 +139,12 @@ zlength(register os_ptr op)
make_int(op, r_size(&str));
return 0;
}
+ case t_astruct:
+ if (gs_object_type(imemory, op->value.pstruct) != &st_bytes)
+ return_error(e_typecheck);
+ check_read(*op);
+ make_int(op, gs_object_size(imemory, op->value.pstruct));
+ return 0;
default:
return_op_typecheck(op);
}
@@ -142,8 +153,9 @@ zlength(register os_ptr op)
/* <array|packedarray|string> <index> get <obj> */
/* <dict> <key> get <obj> */
private int
-zget(register os_ptr op)
+zget(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
ref *pvalue;
@@ -181,16 +193,19 @@ zget(register os_ptr op)
/* <dict> <key> <value> put - */
/* <string> <index> <int> put - */
private int
-zput(register os_ptr op)
+zput(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
os_ptr op2 = op1 - 1;
+ byte *sdata;
+ uint ssize;
switch (r_type(op2)) {
case t_dictionary:
check_dict_write(*op2);
{
- int code = dict_put(op2, op1, op);
+ int code = idict_put(op2, op1, op);
if (code < 0)
return code; /* error */
@@ -210,11 +225,19 @@ zput(register os_ptr op)
case t_shortarray:
return_error(e_invalidaccess);
case t_string:
- check_write(*op2);
- check_int_ltu(*op1, r_size(op2));
+ sdata = op2->value.bytes;
+ ssize = r_size(op2);
+str: check_write(*op2);
+ check_int_ltu(*op1, ssize);
check_int_leu(*op, 0xff);
- op2->value.bytes[(uint) op1->value.intval] = (byte) op->value.intval;
+ sdata[(uint)op1->value.intval] = (byte)op->value.intval;
break;
+ case t_astruct:
+ if (gs_object_type(imemory, op2->value.pstruct) != &st_bytes)
+ return_error(e_typecheck);
+ sdata = r_ptr(op2, byte);
+ ssize = gs_object_size(imemory, op2->value.pstruct);
+ goto str;
default:
return_op_typecheck(op2);
}
@@ -224,8 +247,9 @@ zput(register os_ptr op)
/* <seq:array|packedarray|string> <index> <count> getinterval <subseq> */
private int
-zgetinterval(register os_ptr op)
+zgetinterval(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
os_ptr op2 = op1 - 1;
uint index;
@@ -270,9 +294,11 @@ zgetinterval(register os_ptr op)
/* <array1> <index> <array2|packedarray2> putinterval - */
/* <string1> <index> <string2> putinterval - */
+/* <bytestring1> <index> <string2> putinterval - */
private int
-zputinterval(register os_ptr op)
+zputinterval(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr opindex = op - 1;
os_ptr opto = opindex - 1;
int code;
@@ -285,11 +311,29 @@ zputinterval(register os_ptr op)
return_error(e_invalidaccess);
case t_array:
case t_string:
- ;
+ check_write(*opto);
+ check_int_leu(*opindex, r_size(opto));
+ code = copy_interval(opto, (uint)(opindex->value.intval), op,
+ "putinterval");
+ break;
+ case t_astruct: {
+ uint dsize, ssize, index;
+
+ check_write(*opto);
+ if (gs_object_type(imemory, opto->value.pstruct) != &st_bytes)
+ return_error(e_typecheck);
+ dsize = gs_object_size(imemory, opto->value.pstruct);
+ check_int_leu(*opindex, dsize);
+ index = (uint)opindex->value.intval;
+ check_read_type(*op, t_string);
+ ssize = r_size(op);
+ if (ssize > dsize - index)
+ return_error(e_rangecheck);
+ memcpy(r_ptr(opto, byte) + index, op->value.const_bytes, ssize);
+ code = 0;
+ break;
+ }
}
- check_write(*opto);
- check_int_leu(*opindex, r_size(opto));
- code = copy_interval(opto, (uint) (opindex->value.intval), op, "putinterval");
if (code >= 0)
pop(3);
return code;
@@ -298,14 +342,15 @@ zputinterval(register os_ptr op)
/* <array|packedarray|string> <<element> proc> forall - */
/* <dict> <<key> <value> proc> forall - */
private int
- array_continue(P1(os_ptr)),
- dict_continue(P1(os_ptr)),
- string_continue(P1(os_ptr)),
- packedarray_continue(P1(os_ptr));
-private int forall_cleanup(P1(os_ptr));
+ array_continue(P1(i_ctx_t *)),
+ dict_continue(P1(i_ctx_t *)),
+ string_continue(P1(i_ctx_t *)),
+ packedarray_continue(P1(i_ctx_t *));
+private int forall_cleanup(P1(i_ctx_t *));
private int
-zforall(register os_ptr op)
+zforall(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr obj = op - 1;
es_ptr ep = esp;
es_ptr cproc = ep + 4;
@@ -348,13 +393,13 @@ zforall(register os_ptr op)
ep[3] = *op;
esp = cproc - 1;
pop(2);
- op -= 2;
- return (*real_opproc(cproc))(op);
+ return (*real_opproc(cproc))(i_ctx_p);
}
/* Continuation operator for arrays */
private int
-array_continue(register os_ptr op)
+array_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr obj = esp - 1;
if (r_size(obj)) { /* continue */
@@ -372,8 +417,9 @@ array_continue(register os_ptr op)
}
/* Continuation operator for dictionaries */
private int
-dict_continue(register os_ptr op)
+dict_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr obj = esp - 2;
int index = (int)esp->value.intval;
@@ -391,8 +437,9 @@ dict_continue(register os_ptr op)
}
/* Continuation operator for strings */
private int
-string_continue(register os_ptr op)
+string_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr obj = esp - 1;
if (r_size(obj)) { /* continue */
@@ -410,8 +457,9 @@ string_continue(register os_ptr op)
}
/* Continuation operator for packed arrays */
private int
-packedarray_continue(register os_ptr op)
+packedarray_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
es_ptr obj = esp - 1;
if (r_size(obj)) { /* continue */
@@ -431,7 +479,7 @@ packedarray_continue(register os_ptr op)
}
/* Vacuous cleanup procedure */
private int
-forall_cleanup(os_ptr op)
+forall_cleanup(i_ctx_t *i_ctx_p)
{
return 0;
}
@@ -485,19 +533,9 @@ copy_interval(os_ptr prto, uint index, os_ptr prfrom, client_name_t cname)
fromsize, cname);
}
case t_string:
- { /* We have to worry about aliasing. */
- const byte *from = prfrom->value.bytes;
- byte *to = prto->value.bytes + index;
- uint i;
-
- if (from + fromsize <= to || to + fromsize <= from)
- memcpy(to, from, fromsize);
- else if (to < from)
- for (i = fromsize; i != 0; i--, from++, to++)
- *to = *from;
- else
- for (i = fromsize, from += i, to += i; i != 0; i--)
- *--to = *--from;
+ { /* memmove takes care of aliasing. */
+ memmove(prto->value.bytes + index, prfrom->value.bytes,
+ fromsize);
}
break;
case t_mixedarray:
diff --git a/gs/src/zgstate.c b/gs/src/zgstate.c
index 8b3ca9ef4..94df353f2 100644
--- a/gs/src/zgstate.c
+++ b/gs/src/zgstate.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#include "ghost.h"
#include "oper.h"
#include "ialloc.h"
+#include "icremap.h"
#include "idict.h"
#include "istruct.h"
#include "igstate.h"
@@ -29,51 +30,54 @@
#include "store.h"
/* Forward references */
-private int num_param(P2(const_os_ptr, int (*)(P2(gs_state *, floatp))));
+private int num_param(P2(i_ctx_t *, int (*)(P2(gs_state *, floatp))));
/* Structure descriptors */
private_st_int_gstate();
+private_st_int_remap_color_info();
/* ------ Operations on the entire graphics state ------ */
-/* The current graphics state */
-gs_state *igs;
-
/* "Client" procedures */
private void *gs_istate_alloc(P1(gs_memory_t * mem));
private int gs_istate_copy(P2(void *to, const void *from));
private void gs_istate_free(P2(void *old, gs_memory_t * mem));
-private const gs_state_client_procs istate_procs =
-{
+private const gs_state_client_procs istate_procs = {
gs_istate_alloc,
gs_istate_copy,
gs_istate_free
};
/* Initialize the graphics stack. */
-void
-igs_init(void)
-{
- gs_register_struct_root(imemory, NULL, (void **)&igs, "igs");
- igs = int_gstate_alloc(iimemory);
-}
gs_state *
-int_gstate_alloc(gs_ref_memory_t * mem)
+int_gstate_alloc(const gs_dual_memory_t * dmem)
{
int_gstate *iigs;
ref proc0;
- gs_state *pgs = gs_state_alloc((gs_memory_t *) mem);
+ int_remap_color_info_t *prci;
+ gs_ref_memory_t *lmem = dmem->space_local;
+ gs_ref_memory_t *gmem = dmem->space_global;
+ gs_state *pgs = gs_state_alloc((gs_memory_t *)lmem);
- iigs = gs_alloc_struct((gs_memory_t *) mem, int_gstate, &st_int_gstate,
+ iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate,
"int_gstate_alloc(int_gstate)");
int_gstate_map_refs(iigs, make_null);
make_empty_array(&iigs->dash_pattern, a_all);
- gs_alloc_ref_array(mem, &proc0, a_readonly + a_executable, 2,
+ gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2,
"int_gstate_alloc(proc0)");
make_oper(proc0.value.refs, 0, zpop);
make_real(proc0.value.refs + 1, 0.0);
iigs->black_generation = proc0;
iigs->undercolor_removal = proc0;
+ /*
+ * Even though the gstate itself is allocated in local VM, the
+ * container for the color remapping procedure must be allocated in
+ * global VM so that the gstate can be copied into global VM.
+ */
+ prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t,
+ &st_int_remap_color_info,
+ "int_gstate_alloc(remap color info)");
+ make_struct(&iigs->remap_color_info, imemory_space(gmem), prci);
clear_pagedevice(iigs);
gs_state_set_client(pgs, iigs, &istate_procs);
/* PostScript code wants limit clamping enabled. */
@@ -88,28 +92,28 @@ int_gstate_alloc(gs_ref_memory_t * mem)
/* - gsave - */
int
-zgsave(register os_ptr op)
+zgsave(i_ctx_t *i_ctx_p)
{
return gs_gsave(igs);
}
/* - grestore - */
int
-zgrestore(register os_ptr op)
+zgrestore(i_ctx_t *i_ctx_p)
{
return gs_grestore(igs);
}
/* - grestoreall - */
int
-zgrestoreall(register os_ptr op)
+zgrestoreall(i_ctx_t *i_ctx_p)
{
return gs_grestoreall(igs);
}
/* - initgraphics - */
private int
-zinitgraphics(register os_ptr op)
+zinitgraphics(i_ctx_t *i_ctx_p)
{
/* gs_initgraphics does a setgray; we must clear the interpreter's */
/* cached copy of the color space object. */
@@ -124,8 +128,10 @@ zinitgraphics(register os_ptr op)
/* <num> setlinewidth - */
private int
-zsetlinewidth(register os_ptr op)
-{ /*
+zsetlinewidth(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ /*
* The Red Book doesn't say anything about this, but Adobe
* interpreters return (or perhaps store) the absolute value
* of the width.
@@ -143,8 +149,10 @@ zsetlinewidth(register os_ptr op)
/* - currentlinewidth <num> */
private int
-zcurrentlinewidth(register os_ptr op)
+zcurrentlinewidth(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentlinewidth(igs));
return 0;
@@ -152,8 +160,9 @@ zcurrentlinewidth(register os_ptr op)
/* <cap_int> .setlinecap - */
private int
-zsetlinecap(register os_ptr op)
+zsetlinecap(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int param;
int code = int_param(op, max_int, &param);
@@ -165,8 +174,10 @@ zsetlinecap(register os_ptr op)
/* - currentlinecap <cap_int> */
private int
-zcurrentlinecap(register os_ptr op)
+zcurrentlinecap(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, (int)gs_currentlinecap(igs));
return 0;
@@ -174,8 +185,9 @@ zcurrentlinecap(register os_ptr op)
/* <join_int> .setlinejoin - */
private int
-zsetlinejoin(register os_ptr op)
+zsetlinejoin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int param;
int code = int_param(op, max_int, &param);
@@ -187,8 +199,10 @@ zsetlinejoin(register os_ptr op)
/* - currentlinejoin <join_int> */
private int
-zcurrentlinejoin(register os_ptr op)
+zcurrentlinejoin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, (int)gs_currentlinejoin(igs));
return 0;
@@ -196,15 +210,17 @@ zcurrentlinejoin(register os_ptr op)
/* <num> setmiterlimit - */
private int
-zsetmiterlimit(register os_ptr op)
+zsetmiterlimit(i_ctx_t *i_ctx_p)
{
- return num_param(op, gs_setmiterlimit);
+ return num_param(i_ctx_p, gs_setmiterlimit);
}
/* - currentmiterlimit <num> */
private int
-zcurrentmiterlimit(register os_ptr op)
+zcurrentmiterlimit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentmiterlimit(igs));
return 0;
@@ -212,8 +228,9 @@ zcurrentmiterlimit(register os_ptr op)
/* <array> <offset> setdash - */
private int
-zsetdash(register os_ptr op)
+zsetdash(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
double offset;
int code = real_param(op, &offset);
@@ -253,8 +270,10 @@ zsetdash(register os_ptr op)
/* - currentdash <array> <offset> */
private int
-zcurrentdash(register os_ptr op)
+zcurrentdash(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(2);
ref_assign(op - 1, &istate->dash_pattern);
make_real(op, gs_currentdash_offset(igs));
@@ -263,15 +282,17 @@ zcurrentdash(register os_ptr op)
/* <num> setflat - */
private int
-zsetflat(register os_ptr op)
+zsetflat(i_ctx_t *i_ctx_p)
{
- return num_param(op, gs_setflat);
+ return num_param(i_ctx_p, gs_setflat);
}
/* - currentflat <num> */
private int
-zcurrentflat(register os_ptr op)
+zcurrentflat(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentflat(igs));
return 0;
@@ -281,8 +302,10 @@ zcurrentflat(register os_ptr op)
/* <bool> .setaccuratecurves - */
private int
-zsetaccuratecurves(register os_ptr op)
+zsetaccuratecurves(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_setaccuratecurves(igs, op->value.boolval);
pop(1);
@@ -291,8 +314,10 @@ zsetaccuratecurves(register os_ptr op)
/* - .currentaccuratecurves <bool> */
private int
-zcurrentaccuratecurves(register os_ptr op)
+zcurrentaccuratecurves(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currentaccuratecurves(igs));
return 0;
@@ -300,8 +325,9 @@ zcurrentaccuratecurves(register os_ptr op)
/* <adjust.x> <adjust.y> .setfilladjust2 - */
private int
-zsetfilladjust2(register os_ptr op)
+zsetfilladjust2(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double adjust[2];
int code = num_params(op, 2, adjust);
@@ -316,8 +342,9 @@ zsetfilladjust2(register os_ptr op)
/* - .currentfilladjust2 <adjust.x> <adjust.y> */
private int
-zcurrentfilladjust2(register os_ptr op)
+zcurrentfilladjust2(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_point adjust;
push(2);
@@ -329,8 +356,10 @@ zcurrentfilladjust2(register os_ptr op)
/* <bool> .setdashadapt - */
private int
-zsetdashadapt(register os_ptr op)
+zsetdashadapt(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_setdashadapt(igs, op->value.boolval);
pop(1);
@@ -339,8 +368,10 @@ zsetdashadapt(register os_ptr op)
/* - .currentdashadapt <bool> */
private int
-zcurrentdashadapt(register os_ptr op)
+zcurrentdashadapt(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currentdashadapt(igs));
return 0;
@@ -348,8 +379,9 @@ zcurrentdashadapt(register os_ptr op)
/* <num> <bool> .setdotlength - */
private int
-zsetdotlength(register os_ptr op)
+zsetdotlength(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double length;
int code = real_param(op - 1, &length);
@@ -365,8 +397,10 @@ zsetdotlength(register os_ptr op)
/* - .currentdotlength <num> <bool> */
private int
-zcurrentdotlength(register os_ptr op)
+zcurrentdotlength(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(2);
make_real(op - 1, gs_currentdotlength(igs));
make_bool(op, gs_currentdotlength_absolute(igs));
@@ -375,22 +409,22 @@ zcurrentdotlength(register os_ptr op)
/* - .setdotorientation - */
private int
-zsetdotorientation(os_ptr op)
+zsetdotorientation(i_ctx_t *i_ctx_p)
{
return gs_setdotorientation(igs);
}
/* - .dotorientation - */
private int
-zdotorientation(os_ptr op)
+zdotorientation(i_ctx_t *i_ctx_p)
{
return gs_dotorientation(igs);
}
/* ------ Initialization procedure ------ */
-const op_def zgstate_op_defs[] =
-{
+/* We need to split the table because of the 16-element limit. */
+const op_def zgstate1_op_defs[] = {
{"0.currentaccuratecurves", zcurrentaccuratecurves},
{"0currentdash", zcurrentdash},
{"0.currentdashadapt", zcurrentdashadapt},
@@ -406,6 +440,9 @@ const op_def zgstate_op_defs[] =
{"0grestoreall", zgrestoreall},
{"0gsave", zgsave},
{"0initgraphics", zinitgraphics},
+ op_def_end(0)
+};
+const op_def zgstate2_op_defs[] = {
{"1.setaccuratecurves", zsetaccuratecurves},
{"2setdash", zsetdash},
{"1.setdashadapt", zsetdashadapt},
@@ -446,8 +483,9 @@ gs_istate_free(void *old, gs_memory_t * mem)
/* Get a numeric parameter */
private int
-num_param(const_os_ptr op, int (*pproc)(P2(gs_state *, floatp)))
+num_param(i_ctx_t *i_ctx_p, int (*pproc)(P2(gs_state *, floatp)))
{
+ os_ptr op = osp;
double param;
int code = real_param(op, &param);
diff --git a/gs/src/zhsb.c b/gs/src/zhsb.c
index 0342a14c6..78474c970 100644
--- a/gs/src/zhsb.c
+++ b/gs/src/zhsb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,8 +26,9 @@
/* - currenthsbcolor <hue> <saturation> <brightness> */
private int
-zcurrenthsbcolor(register os_ptr op)
+zcurrenthsbcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
float par[3];
gs_currenthsbcolor(igs, par);
@@ -38,8 +39,9 @@ zcurrenthsbcolor(register os_ptr op)
/* <hue> <saturation> <brightness> sethsbcolor - */
private int
-zsethsbcolor(register os_ptr op)
+zsethsbcolor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double par[3];
int code;
diff --git a/gs/src/zht.c b/gs/src/zht.c
index c829bb76f..0277da311 100644
--- a/gs/src/zht.c
+++ b/gs/src/zht.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1991, 1993, 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1991, 1993, 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,16 +34,17 @@
#include "store.h"
/* Forward references */
-private int screen_sample(P1(os_ptr));
-private int set_screen_continue(P1(os_ptr));
-private int screen_cleanup(P1(os_ptr));
+private int screen_sample(P1(i_ctx_t *));
+private int set_screen_continue(P1(i_ctx_t *));
+private int screen_cleanup(P1(i_ctx_t *));
/* - .currenthalftone <dict> 0 */
/* - .currenthalftone <frequency> <angle> <proc> 1 */
/* - .currenthalftone <red_freq> ... <gray_proc> 2 */
private int
-zcurrenthalftone(register os_ptr op)
+zcurrenthalftone(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_halftone ht;
gs_currenthalftone(igs, &ht);
@@ -83,8 +84,10 @@ zcurrenthalftone(register os_ptr op)
/* - .currentscreenlevels <int> */
private int
-zcurrentscreenlevels(register os_ptr op)
+zcurrentscreenlevels(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, gs_currentscreenlevels(igs));
return 0;
@@ -105,14 +108,13 @@ zcurrentscreenlevels(register os_ptr op)
#define senum r_ptr(esp, gs_screen_enum)
/* Forward references */
-int zscreen_enum_init(P7(os_ptr, const gx_ht_order *, gs_screen_halftone *,
- ref *, int, int (*)(P1(os_ptr)), gs_memory_t *));
-private int setscreen_finish(P1(os_ptr));
+private int setscreen_finish(P1(i_ctx_t *));
/* <frequency> <angle> <proc> setscreen - */
private int
-zsetscreen(register os_ptr op)
+zsetscreen(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_screen_halftone screen;
gx_ht_order order;
int code = zscreen_params(op, &screen);
@@ -120,7 +122,7 @@ zsetscreen(register os_ptr op)
if (code < 0)
return code;
- mem = (gs_memory_t *)idmemory->spaces.indexed[r_space_index(op)];
+ mem = (gs_memory_t *)idmemory->spaces_indexed[r_space_index(op)];
/*
* Allocate the halftone in the same VM space as the procedure.
* This keeps the space relationships consistent.
@@ -129,15 +131,15 @@ zsetscreen(register os_ptr op)
gs_currentaccuratescreens(), mem);
if (code < 0)
return code;
- return zscreen_enum_init(op, &order, &screen, op, 3,
+ return zscreen_enum_init(i_ctx_p, &order, &screen, op, 3,
setscreen_finish, mem);
}
/* We break out the body of this operator so it can be shared with */
/* the code for Type 1 halftones in sethalftone. */
int
-zscreen_enum_init(os_ptr op, const gx_ht_order * porder,
+zscreen_enum_init(i_ctx_t *i_ctx_p, const gx_ht_order * porder,
gs_screen_halftone * psp, ref * pproc, int npop,
- int (*finish_proc)(P1(os_ptr)), gs_memory_t * mem)
+ int (*finish_proc)(P1(i_ctx_t *)), gs_memory_t * mem)
{
gs_screen_enum *penum;
int code;
@@ -149,7 +151,7 @@ zscreen_enum_init(os_ptr op, const gx_ht_order * porder,
make_istruct(esp + snumpush, 0, penum); /* do early for screen_cleanup in case of error */
code = gs_screen_enum_init_memory(penum, porder, igs, psp, mem);
if (code < 0) {
- screen_cleanup(op);
+ screen_cleanup(i_ctx_p);
return code;
}
/* Push everything on the estack */
@@ -163,8 +165,9 @@ zscreen_enum_init(os_ptr op, const gx_ht_order * porder,
}
/* Set up the next sample */
private int
-screen_sample(register os_ptr op)
+screen_sample(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_screen_enum *penum = senum;
gs_point pt;
int code = gs_screen_currentpoint(penum, &pt);
@@ -176,9 +179,9 @@ screen_sample(register os_ptr op)
case 1:
/* All done */
if (real_opproc(esp - 2) != 0)
- code = (*real_opproc(esp - 2)) (op);
+ code = (*real_opproc(esp - 2)) (i_ctx_p);
esp -= snumpush;
- screen_cleanup(op);
+ screen_cleanup(i_ctx_p);
return (code < 0 ? code : o_pop_estack);
case 0:
;
@@ -193,8 +196,9 @@ screen_sample(register os_ptr op)
}
/* Continuation procedure for processing sampled pixels. */
private int
-set_screen_continue(register os_ptr op)
+set_screen_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double value;
int code = real_param(op, &value);
@@ -204,12 +208,11 @@ set_screen_continue(register os_ptr op)
if (code < 0)
return code;
pop(1);
- op--;
- return screen_sample(op);
+ return screen_sample(i_ctx_p);
}
/* Finish setscreen. */
private int
-setscreen_finish(os_ptr op)
+setscreen_finish(i_ctx_t *i_ctx_p)
{
gs_screen_install(senum);
istate->screen_procs.colored.red = sproc;
@@ -221,7 +224,7 @@ setscreen_finish(os_ptr op)
}
/* Clean up after screen enumeration */
private int
-screen_cleanup(os_ptr op)
+screen_cleanup(i_ctx_t *i_ctx_p)
{
ifree_object(esp[snumpush].value.pstruct, "screen_cleanup");
return 0;
diff --git a/gs/src/zht1.c b/gs/src/zht1.c
index 4a246263d..caa46545a 100644
--- a/gs/src/zht1.c
+++ b/gs/src/zht1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,11 +41,12 @@ spot_dummy(floatp x, floatp y)
}
/* <red_freq> ... <gray_proc> setcolorscreen - */
-private int setcolorscreen_finish(P1(os_ptr));
-private int setcolorscreen_cleanup(P1(os_ptr));
+private int setcolorscreen_finish(P1(i_ctx_t *));
+private int setcolorscreen_cleanup(P1(i_ctx_t *));
private int
-zsetcolorscreen(register os_ptr op)
+zsetcolorscreen(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_colorscreen_halftone cscreen;
ref sprocs[4];
gs_halftone *pht;
@@ -65,7 +66,7 @@ zsetcolorscreen(register os_ptr op)
sprocs[i] = *op1;
space = max(space, r_space_index(op1));
}
- mem = (gs_memory_t *)idmemory->spaces.indexed[space];
+ mem = (gs_memory_t *)idmemory->spaces_indexed[space];
check_estack(8); /* for sampling screens */
rc_alloc_struct_0(pht, gs_halftone, &st_halftone,
mem, pht = 0, "setcolorscreen(halftone)");
@@ -90,7 +91,7 @@ zsetcolorscreen(register os_ptr op)
for (i = 0; i < 4; i++) {
/* Shuffle the indices to correspond to */
/* the component order. */
- code = zscreen_enum_init(op,
+ code = zscreen_enum_init(i_ctx_p,
&pdht->components[(i + 1) & 3].corder,
&pht->params.colorscreen.screens.indexed[i],
&sprocs[i], 0, 0, mem);
@@ -110,7 +111,7 @@ zsetcolorscreen(register os_ptr op)
}
/* Install the color screen after sampling. */
private int
-setcolorscreen_finish(os_ptr op)
+setcolorscreen_finish(i_ctx_t *i_ctx_p)
{
gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
int code;
@@ -122,12 +123,12 @@ setcolorscreen_finish(os_ptr op)
memcpy(istate->screen_procs.indexed, esp - 5, sizeof(ref) * 4);
make_null(&istate->halftone);
esp -= 7;
- setcolorscreen_cleanup(op);
+ setcolorscreen_cleanup(i_ctx_p);
return o_pop_estack;
}
/* Clean up after installing the color screen. */
private int
-setcolorscreen_cleanup(os_ptr op)
+setcolorscreen_cleanup(i_ctx_t *i_ctx_p)
{
gs_halftone *pht = r_ptr(esp + 6, gs_halftone);
gx_device_halftone *pdht = r_ptr(esp + 7, gx_device_halftone);
diff --git a/gs/src/zht2.c b/gs/src/zht2.c
index 711546aca..57e1714c4 100644
--- a/gs/src/zht2.c
+++ b/gs/src/zht2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,7 +25,7 @@
#include "gzht.h"
#include "estack.h"
#include "ialloc.h"
-#include "idict.h"
+#include "iddict.h"
#include "idparam.h"
#include "igstate.h"
#include "icolor.h"
@@ -35,18 +35,20 @@
/* Forward references */
private int dict_spot_params(P4(const ref *, gs_spot_halftone *,
ref *, ref *));
-private int dict_spot_results(P2(ref *, const gs_spot_halftone *));
+private int dict_spot_results(P3(i_ctx_t *, ref *, const gs_spot_halftone *));
private int dict_threshold_params(P3(const ref *,
gs_threshold_halftone *, ref *));
+private int dict_threshold2_params(P3(const ref *,
+ gs_threshold2_halftone *, ref *));
/* <dict> <dict5> .sethalftone5 - */
float spot_dummy(P2(floatp, floatp)); /* in zht1.c */
-int spot_sample_finish(P1(os_ptr)); /* in zht.c */
-private int sethalftone_finish(P1(os_ptr));
-private int sethalftone_cleanup(P1(os_ptr));
+private int sethalftone_finish(P1(i_ctx_t *));
+private int sethalftone_cleanup(P1(i_ctx_t *));
private int
-zsethalftone5(register os_ptr op)
+zsethalftone5(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count;
gs_halftone_component *phtc;
gs_halftone_component *pc;
@@ -60,6 +62,7 @@ zsethalftone5(register os_ptr op)
ref sprocs[countof(color_names)];
ref tprocs[countof(color_names)];
gs_memory_t *mem;
+ uint edepth = ref_stack_count(&e_stack);
int npop = 2;
check_type(*op, t_dictionary);
@@ -75,7 +78,7 @@ zsethalftone5(register os_ptr op)
else if (i == gs_ht_separation_Default)
return_error(e_typecheck);
}
- mem = (gs_memory_t *) idmemory->spaces.indexed[r_space_index(op - 1)];
+ mem = (gs_memory_t *) idmemory->spaces_indexed[r_space_index(op - 1)];
check_estack(5); /* for sampling Type 1 screens */
refset_null(sprocs, countof(sprocs));
refset_null(tprocs, countof(tprocs));
@@ -96,7 +99,7 @@ zsethalftone5(register os_ptr op)
if (dict_find_string(op, color_names[i], &pvalue) > 0) {
check_type_only(*pvalue, t_dictionary);
check_dict_read(*pvalue);
- if (dict_int_param(pvalue, "HalftoneType", 1, 5, 0,
+ if (dict_int_param(pvalue, "HalftoneType", 1, 7, 0,
&type) < 0
) {
code = gs_note_error(e_typecheck);
@@ -119,6 +122,11 @@ zsethalftone5(register os_ptr op)
&pc->params.threshold, tprocs + j);
pc->type = ht_type_threshold;
break;
+ case 7:
+ code = dict_threshold2_params(pvalue,
+ &pc->params.threshold2, tprocs + j);
+ pc->type = ht_type_threshold2;
+ break;
}
if (code < 0)
break;
@@ -149,7 +157,7 @@ zsethalftone5(register os_ptr op)
ref *pvalue;
dict_find_string(op, color_names[pc->cname], &pvalue);
- code = dict_spot_results(pvalue, &pc->params.spot);
+ code = dict_spot_results(i_ctx_p, pvalue, &pc->params.spot);
if (code < 0)
break;
}
@@ -160,7 +168,6 @@ zsethalftone5(register os_ptr op)
* and any (Type 1 or Type 3) TransferFunctions.
* Save the stack depths in case we have to back out.
*/
- uint edepth = ref_stack_count(&e_stack);
uint odepth = ref_stack_count(&o_stack);
ref odict, odict5;
@@ -181,7 +188,7 @@ zsethalftone5(register os_ptr op)
switch (phtc[j].type) {
case ht_type_spot:
- code = zscreen_enum_init(op, porder,
+ code = zscreen_enum_init(i_ctx_p, porder,
&phtc[j].params.spot.screen,
&sprocs[j], 0, 0, mem);
if (code < 0)
@@ -193,8 +200,8 @@ zsethalftone5(register os_ptr op)
/****** check_xstack IS WRONG ******/
check_ostack(zcolor_remap_one_ostack);
check_estack(zcolor_remap_one_estack);
- code = zcolor_remap_one(tprocs + j,
- op, porder->transfer, igs,
+ code = zcolor_remap_one(i_ctx_p, tprocs + j,
+ porder->transfer, igs,
zcolor_remap_one_finish);
op = osp;
}
@@ -221,11 +228,11 @@ zsethalftone5(register os_ptr op)
return code;
}
pop(npop);
- return o_push_estack;
+ return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0);
}
/* Install the halftone after sampling. */
private int
-sethalftone_finish(os_ptr op)
+sethalftone_finish(i_ctx_t *i_ctx_p)
{
gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
int code;
@@ -237,12 +244,12 @@ sethalftone_finish(os_ptr op)
return code;
istate->halftone = esp[-2];
esp -= 4;
- sethalftone_cleanup(op);
+ sethalftone_cleanup(i_ctx_p);
return o_pop_estack;
}
/* Clean up after installing the halftone. */
private int
-sethalftone_cleanup(os_ptr op)
+sethalftone_cleanup(i_ctx_t *i_ctx_p)
{
gx_device_halftone *pdht = r_ptr(&esp[4], gx_device_halftone);
gs_halftone *pht = r_ptr(&esp[3], gs_halftone);
@@ -295,7 +302,7 @@ dict_spot_params(const ref * pdict, gs_spot_halftone * psp,
/* Set actual frequency and angle in a dictionary. */
private int
-dict_real_result(ref * pdict, const char *kstr, floatp val)
+dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val)
{
int code = 0;
ref *ignore;
@@ -305,47 +312,114 @@ dict_real_result(ref * pdict, const char *kstr, floatp val)
check_dict_write(*pdict);
make_real(&rval, val);
- code = dict_put_string(pdict, kstr, &rval);
+ code = idict_put_string(pdict, kstr, &rval);
}
return code;
}
private int
-dict_spot_results(ref * pdict, const gs_spot_halftone * psp)
+dict_spot_results(i_ctx_t *i_ctx_p, ref * pdict, const gs_spot_halftone * psp)
{
int code;
- code = dict_real_result(pdict, "ActualFrequency",
+ code = dict_real_result(i_ctx_p, pdict, "ActualFrequency",
psp->screen.actual_frequency);
if (code < 0)
return code;
- return dict_real_result(pdict, "ActualAngle",
+ return dict_real_result(i_ctx_p, pdict, "ActualAngle",
psp->screen.actual_angle);
}
-/* Extract width, height, and thresholds from a dictionary. */
+/* Extract Width, Height, and TransferFunction from a dictionary. */
private int
-dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp,
- ref * ptproc)
+dict_threshold_common_params(const ref * pdict,
+ gs_threshold_halftone_common * ptp,
+ ref **pptstring, ref *ptproc)
{
int code;
- ref *tstring;
check_dict_read(*pdict);
if ((code = dict_int_param(pdict, "Width", 1, 0x7fff, -1,
&ptp->width)) < 0 ||
(code = dict_int_param(pdict, "Height", 1, 0x7fff, -1,
&ptp->height)) < 0 ||
- (code = dict_find_string(pdict, "Thresholds", &tstring)) <= 0 ||
+ (code = dict_find_string(pdict, "Thresholds", pptstring)) <= 0 ||
(code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0
)
return (code < 0 ? code : e_undefined);
+ ptp->transfer_closure.proc = 0;
+ ptp->transfer_closure.data = 0;
+ return code;
+}
+
+/* Extract threshold common parameters + Thresholds. */
+private int
+dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp,
+ ref * ptproc)
+{
+ ref *tstring;
+ int code =
+ dict_threshold_common_params(pdict,
+ (gs_threshold_halftone_common *)ptp,
+ &tstring, ptproc);
+
+ if (code < 0)
+ return code;
check_read_type_only(*tstring, t_string);
if (r_size(tstring) != (long)ptp->width * ptp->height)
return_error(e_rangecheck);
ptp->thresholds.data = tstring->value.const_bytes;
ptp->thresholds.size = r_size(tstring);
ptp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer);
- ptp->transfer_closure.proc = 0;
- ptp->transfer_closure.data = 0;
+ return 0;
+}
+
+/* Extract threshold common parameters + Thresholds, Width2, Height2, */
+/* BitsPerSample. */
+private int
+dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp,
+ ref * ptproc)
+{
+ ref *tstring;
+ int code =
+ dict_threshold_common_params(pdict,
+ (gs_threshold_halftone_common *)ptp,
+ &tstring, ptproc);
+ int bps;
+ uint size;
+ int cw2, ch2;
+
+ if (code < 0 ||
+ (code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0,
+ &ptp->width2)) < 0 ||
+ (code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0,
+ &ptp->height2)) < 0 ||
+ (code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0
+ )
+ return code;
+ if ((bps != 8 && bps != 16) || cw2 != ch2 ||
+ (!cw2 && (ptp->width2 == 0 || ptp->height2 == 0))
+ )
+ return_error(e_rangecheck);
+ ptp->bytes_per_sample = bps / 8;
+ switch (r_type(tstring)) {
+ case t_string:
+ size = r_size(tstring);
+ gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes,
+ size);
+ break;
+ case t_astruct:
+ if (gs_object_type(imemory, tstring->value.pstruct) != &st_bytes)
+ return_error(e_typecheck);
+ size = gs_object_size(imemory, tstring->value.pstruct);
+ gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte),
+ 0, size);
+ break;
+ default:
+ return_error(e_typecheck);
+ }
+ check_read(*tstring);
+ if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) *
+ ptp->bytes_per_sample)
+ return_error(e_rangecheck);
return 0;
}
diff --git a/gs/src/zimage.c b/gs/src/zimage.c
index ae0014517..484836a88 100644
--- a/gs/src/zimage.c
+++ b/gs/src/zimage.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,7 +26,9 @@
#include "igstate.h"
#include "ilevel.h"
#include "store.h"
+#include "gschar.h" /* for in_cachedevice */
#include "gscspace.h"
+#include "gscssub.h"
#include "gsmatrix.h"
#include "gsimage.h"
#include "gxiparam.h"
@@ -35,38 +37,40 @@
#include "iimage.h"
/* Forward references */
-private int image_setup(P4(gs_image_t * pim, os_ptr op,
+private int image_setup(P5(i_ctx_t *i_ctx_p, os_ptr op, gs_image_t * pim,
const gs_color_space * pcs, int npop));
-private int image_proc_continue(P1(os_ptr));
-private int image_file_continue(P1(os_ptr));
-private int image_file_buffered_continue(P1(os_ptr));
-private int image_string_process(P3(os_ptr, gs_image_enum *, int));
-private int image_cleanup(P1(os_ptr));
+private int image_proc_process(P1(i_ctx_t *));
+private int image_file_continue(P1(i_ctx_t *));
+private int image_string_continue(P1(i_ctx_t *));
+private int image_cleanup(P1(i_ctx_t *));
/* <width> <height> <bits/sample> <matrix> <datasrc> image - */
int
-zimage(register os_ptr op)
+zimage(i_ctx_t *i_ctx_p)
{
- return zimage_opaque_setup(op, false, gs_image_alpha_none,
- gs_cspace_DeviceGray((const gs_imager_state *)igs), 5);
+ return zimage_opaque_setup(i_ctx_p, osp, false, gs_image_alpha_none,
+ gs_current_DeviceGray_space(igs), 5);
}
/* <width> <height> <paint_1s> <matrix> <datasrc> imagemask - */
int
-zimagemask(register os_ptr op)
+zimagemask(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image_t image;
check_type(op[-2], t_boolean);
- gs_image_t_init_mask(&image, op[-2].value.boolval);
- return image_setup(&image, op, NULL, 5);
+ gs_image_t_init_mask_adjust(&image, op[-2].value.boolval,
+ gs_incachedevice(igs) != CACHE_DEVICE_NONE);
+ return image_setup(i_ctx_p, op, &image, NULL, 5);
}
/* Common setup for [color|alpha]image. */
/* Fills in format, BitsPerComponent, Alpha. */
int
-zimage_opaque_setup(os_ptr op, bool multi, gs_image_alpha_t alpha,
- const gs_color_space * pcs, int npop)
+zimage_opaque_setup(i_ctx_t *i_ctx_p, os_ptr op, bool multi,
+ gs_image_alpha_t alpha, const gs_color_space * pcs,
+ int npop)
{
gs_image_t image;
@@ -76,13 +80,14 @@ zimage_opaque_setup(os_ptr op, bool multi, gs_image_alpha_t alpha,
image.Alpha = alpha;
image.format =
(multi ? gs_image_format_component_planar : gs_image_format_chunky);
- return image_setup(&image, op, pcs, npop);
+ return image_setup(i_ctx_p, op, &image, pcs, npop);
}
/* Common setup for [color|alpha]image and imagemask. */
/* Fills in Width, Height, ImageMatrix, ColorSpace. */
private int
-image_setup(gs_image_t * pim, os_ptr op, const gs_color_space * pcs, int npop)
+image_setup(i_ctx_t *i_ctx_p, os_ptr op, gs_image_t * pim,
+ const gs_color_space * pcs, int npop)
{
int code;
@@ -95,14 +100,14 @@ image_setup(gs_image_t * pim, os_ptr op, const gs_color_space * pcs, int npop)
pim->ColorSpace = pcs;
pim->Width = (int)op[-4].value.intval;
pim->Height = (int)op[-3].value.intval;
- return zimage_setup((gs_pixel_image_t *) pim, op,
+ return zimage_setup(i_ctx_p, (gs_pixel_image_t *) pim, op,
pim->ImageMask | pim->CombineWithColor, npop);
}
/* Common setup for all Level 1 and 2 images, and ImageType 4 images. */
int
-zimage_setup(const gs_pixel_image_t * pim, const ref * sources,
- bool uses_color, int npop)
+zimage_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
+ const ref * sources, bool uses_color, int npop)
{
gx_image_enum_common_t *pie;
int code =
@@ -111,49 +116,70 @@ zimage_setup(const gs_pixel_image_t * pim, const ref * sources,
if (code < 0)
return code;
- return zimage_data_setup((const gs_pixel_image_t *)pim, pie,
+ return zimage_data_setup(i_ctx_p, (const gs_pixel_image_t *)pim, pie,
sources, npop);
}
/* Common setup for all Level 1 and 2 images, and ImageType 3 and 4 images. */
+/*
+ * We push the following on the estack.
+ * control mark,
+ * num_sources,
+ * for I = num_sources-1 ... 0:
+ * data source I,
+ * aliasing information:
+ * if source is not file, irrelevant;
+ * if file is referenced by a total of M different sources and
+ * this is the occurrence with the lowest I, M;
+ * otherwise, -J, where J is the lowest I of the same file as
+ * this one;
+ * current plane index,
+ * num_sources,
+ * enumeration structure.
+ */
+#define NUM_PUSH(nsource) ((nsource) * 2 + 5)
+/*
+ * We can access these values either from the bottom (esp at control mark - 1,
+ * EBOT macros) or the top (esp = enumeration structure, ETOP macros).
+ * Note that all macros return pointers.
+ */
+#define EBOT_NUM_SOURCES(ep) ((ep) + 2)
+#define EBOT_SOURCE(ep, i)\
+ ((ep) + 3 + (EBOT_NUM_SOURCES(ep)->value.intval - 1 - (i)) * 2)
+#define ETOP_SOURCE(ep, i)\
+ ((ep) - 4 - (i) * 2)
+#define ETOP_PLANE_INDEX(ep) ((ep) - 2)
+#define ETOP_NUM_SOURCES(ep) ((ep) - 1)
int
-zimage_data_setup(const gs_pixel_image_t * pim, gx_image_enum_common_t * pie,
- const ref * sources, int npop)
+zimage_data_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
+ gx_image_enum_common_t * pie, const ref * sources, int npop)
{
int num_sources = pie->num_planes;
-
-#define NUM_PUSH(nsource) ((nsource) * 2 + 4) /* see below */
int inumpush = NUM_PUSH(num_sources);
int code;
gs_image_enum *penum;
int px;
const ref *pp;
- bool must_buffer = false;
- /*
- * We push the following on the estack.
- * Control mark,
- * num_sources times (plane N-1 first, plane 0 last):
- * row buffers (only if must_buffer, otherwise null),
- * data sources,
- * current plane index,
- * current byte in row (only if must_buffer, otherwise 0),
- * enumeration structure.
- */
check_estack(inumpush + 2); /* stuff above, + continuation + proc */
+ make_int(EBOT_NUM_SOURCES(esp), num_sources);
/*
* Note that the data sources may be procedures, strings, or (Level
* 2 only) files. (The Level 1 reference manual says that Level 1
* requires procedures, but Adobe Level 1 interpreters also accept
* strings.) The sources must all be of the same type.
*
- * If the sources are files, and two or more are the same file,
- * we must buffer data for each row; otherwise, we can deliver the
- * data directly out of the stream buffers. This is OK even if
- * some of the sources are filters on the same file, since they
- * have separate buffers.
+ * The Adobe documentation explicitly says that if two or more of the
+ * data sources are the same or inter-dependent files, the result is not
+ * defined. We don't have a problem with the bookkeeping for
+ * inter-dependent files, since each one has its own buffer, but we do
+ * have to be careful if two or more sources are actually the same file.
+ * That is the reason for the aliasing information described above.
*/
for (px = 0, pp = sources; px < num_sources; px++, pp++) {
+ es_ptr ep = EBOT_SOURCE(esp, px);
+
+ make_int(ep + 1, 1); /* default is no aliasing */
switch (r_type(pp)) {
case t_file:
if (!level2_enabled)
@@ -163,8 +189,12 @@ zimage_data_setup(const gs_pixel_image_t * pim, gx_image_enum_common_t * pie,
int pi;
for (pi = 0; pi < px; ++pi)
- if (sources[pi].value.pfile == pp->value.pfile)
- must_buffer = true;
+ if (sources[pi].value.pfile == pp->value.pfile) {
+ /* Record aliasing */
+ make_int(ep + 1, -pi);
+ EBOT_SOURCE(esp, pi)->value.intval++;
+ break;
+ }
}
/* falls through */
case t_string:
@@ -177,55 +207,32 @@ zimage_data_setup(const gs_pixel_image_t * pim, gx_image_enum_common_t * pie,
return_error(e_typecheck);
check_proc(*pp);
}
+ *ep = *pp;
}
if ((penum = gs_image_enum_alloc(imemory, "image_setup")) == 0)
return_error(e_VMerror);
- code = gs_image_common_init(penum, pie, (const gs_data_image_t *)pim,
- imemory, gs_currentdevice(igs));
+ code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, igs);
if (code != 0) { /* error, or empty image */
+ gs_image_cleanup(penum);
ifree_object(penum, "image_setup");
if (code >= 0) /* empty image */
pop(npop);
return code;
}
push_mark_estack(es_other, image_cleanup);
- ++esp;
- for (px = 0, pp = sources + num_sources - 1;
- px < num_sources; esp += 2, ++px, --pp
- ) {
- make_null(esp); /* buffer */
- esp[1] = *pp;
- }
- esp += 2;
- make_int(esp - 2, 0); /* current plane */
- make_int(esp - 1, 0); /* current byte in row */
+ esp += inumpush - 1;
+ make_int(ETOP_PLANE_INDEX(esp), 0);
+ make_int(ETOP_NUM_SOURCES(esp), num_sources);
make_istruct(esp, 0, penum);
switch (r_type(sources)) {
case t_file:
- if (must_buffer) { /* Allocate a buffer for each row. */
- for (px = 0; px < num_sources; ++px) {
- uint size = gs_image_bytes_per_plane_row(penum, px);
- byte *sbody = ialloc_string(size, "image_setup");
-
- if (sbody == 0) {
- esp -= inumpush;
- image_cleanup(osp);
- return_error(e_VMerror);
- }
- make_string(esp - 4 - px * 2,
- icurrent_space, size, sbody);
- }
- push_op_estack(image_file_buffered_continue);
- } else {
- push_op_estack(image_file_continue);
- }
+ push_op_estack(image_file_continue);
break;
case t_string:
- pop(npop);
- return image_string_process(osp, penum, num_sources);
+ push_op_estack(image_string_continue);
+ break;
default: /* procedure */
- push_op_estack(image_proc_continue);
- *++esp = sources[0];
+ push_op_estack(image_proc_process);
break;
}
pop(npop);
@@ -235,63 +242,74 @@ zimage_data_setup(const gs_pixel_image_t * pim, gx_image_enum_common_t * pie,
private es_ptr
zimage_pop_estack(es_ptr tep)
{
- es_ptr ep = tep - 3;
-
- while (!r_is_estack_mark(ep))
- ep -= 2;
- return ep - 1;
+ return tep - NUM_PUSH(ETOP_NUM_SOURCES(tep)->value.intval);
}
/* Continuation for procedure data source. */
private int
-image_proc_continue(register os_ptr op)
+image_proc_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image_enum *penum = r_ptr(esp, gs_image_enum);
uint size, used;
int code;
- int px;
- const ref *pp;
if (!r_has_type_attrs(op, t_string, a_read)) {
check_op(1);
/* Procedure didn't return a (readable) string. Quit. */
esp = zimage_pop_estack(esp);
- image_cleanup(op);
+ image_cleanup(i_ctx_p);
return_error(!r_has_type(op, t_string) ? e_typecheck : e_invalidaccess);
}
size = r_size(op);
if (size == 0)
code = 1;
- else
+ else {
code = gs_image_next(penum, op->value.bytes, size, &used);
+ if (code == e_RemapColor)
+ return code;
+ }
if (code) { /* Stop now. */
esp = zimage_pop_estack(esp);
pop(1);
- op = osp;
- image_cleanup(op);
+ image_cleanup(i_ctx_p);
return (code < 0 ? code : o_pop_estack);
}
pop(1);
- px = (int)(esp[-2].value.intval) + 1;
- pp = esp - 3 - px * 2;
- if (r_is_estack_mark(pp))
- px = 0, pp = esp - 3;
- esp[-2].value.intval = px;
- push_op_estack(image_proc_continue);
- *++esp = *pp;
- return o_push_estack;
+ return image_proc_process(i_ctx_p);
}
-/* Continue processing data from an image with file data sources */
-/* and no file buffering. */
private int
-image_file_continue(os_ptr op)
+image_proc_process(i_ctx_t *i_ctx_p)
{
+ int px = ETOP_PLANE_INDEX(esp)->value.intval;
gs_image_enum *penum = r_ptr(esp, gs_image_enum);
- const ref *pproc = esp - 3;
+ const byte *wanted = gs_image_planes_wanted(penum);
+ int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
+
+ for (;;) {
+ const ref *pp = ETOP_SOURCE(esp, px);
+ bool xmit = wanted[px];
+
+ if (++px == num_sources)
+ px = 0;
+ if (xmit) {
+ ETOP_PLANE_INDEX(esp)->value.intval = px;
+ push_op_estack(image_proc_continue);
+ *++esp = *pp;
+ return o_push_estack;
+ }
+ }
+}
+/* Continue processing data from an image with file data sources. */
+private int
+image_file_continue(i_ctx_t *i_ctx_p)
+{
+ gs_image_enum *penum = r_ptr(esp, gs_image_enum);
+ int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
for (;;) {
uint size = max_uint;
int code;
- int pn, px;
+ int px;
const ref *pp;
/*
@@ -300,14 +318,18 @@ image_file_continue(os_ptr op)
* of the available amounts.
*/
- for (pn = 0, pp = pproc; !r_is_estack_mark(pp);
- ++pn, pp -= 2
+ for (px = 0, pp = ETOP_SOURCE(esp, 0); px < num_sources;
+ ++px, pp -= 2
) {
stream *s = pp->value.pfile;
int min_left = sbuf_min_left(s);
+ int num_aliases = pp[1].value.intval;
uint avail;
- while ((avail = sbufavailable(s)) <= min_left) {
+ if (num_aliases <= 0)
+ continue; /* this is an alias for an earlier file */
+ while ((avail = sbufavailable(s)) < min_left + num_aliases) {
+ /****** REFILL BUFFER, NOT sgetc ******/
int next = sgetc(s);
if (next >= 0) {
@@ -322,7 +344,7 @@ image_file_continue(os_ptr op)
case INTC:
case CALLC:
return
- s_handle_read_exception(next, pp,
+ s_handle_read_exception(i_ctx_p, next, pp,
NULL, 0, image_file_continue);
default:
/* case ERRC: */
@@ -333,7 +355,7 @@ image_file_continue(os_ptr op)
/* Note that in the EOF case, we can get here with */
/* avail < min_left. */
if (avail >= min_left) {
- avail -= min_left;
+ avail = (avail - min_left) / num_aliases;
if (avail < size)
size = avail;
} else
@@ -349,105 +371,61 @@ image_file_continue(os_ptr op)
int pi;
uint used; /* only set for the last plane */
- for (px = 0, pp = pproc, code = 0; px < pn && !code;
+ /****** WRONG IF ALIASING ******/
+ /****** CHECK wanted ******/
+ for (px = 0, pp = ETOP_SOURCE(esp, 0), code = 0;
+ px < num_sources && !code;
++px, pp -= 2
)
code = gs_image_next(penum, sbufptr(pp->value.pfile),
size, &used);
+ if (code == e_RemapColor)
+ return code;
/* Now that used has been set, update the streams. */
- for (pi = 0, pp = pproc; pi < px; ++pi, pp -= 2)
+ for (pi = 0, pp = ETOP_SOURCE(esp, 0); pi < num_sources;
+ ++pi, pp -= 2
+ )
sbufskip(pp->value.pfile, used);
}
if (code) {
esp = zimage_pop_estack(esp);
- image_cleanup(op);
+ image_cleanup(i_ctx_p);
return (code < 0 ? code : o_pop_estack);
}
}
}
-/* Continue processing data from an image with file data sources */
-/* and file buffering. This is similar to the procedure case. */
-private int
-image_file_buffered_continue(os_ptr op)
-{
- gs_image_enum *penum = r_ptr(esp, gs_image_enum);
- const ref *pproc = esp - 3;
- int px = esp[-2].value.intval;
- int dpos = esp[-1].value.intval;
- int code = 0;
-
- while (!code) {
- const ref *pp;
-
- /****** 0 IS BOGUS ******/
- uint size = gs_image_bytes_per_plane_row(penum, 0);
- uint avail = size;
- uint used;
- int pi;
- /* Accumulate data until we have a full set of planes. */
- while (!r_is_estack_mark(pp = pproc - px * 2)) {
- const ref *pb = pp - 1;
- uint used;
- int status = sgets(pp->value.pfile, pb->value.bytes,
- size - dpos, &used);
-
- if ((dpos += used) == size)
- dpos = 0, ++px;
- else
- switch (status) {
- case EOFC:
- if (dpos < avail)
- avail = dpos;
- dpos = 0, ++px;
- break;
- case INTC:
- case CALLC:
- /* Call out to read from a procedure-based stream. */
- esp[-2].value.intval = px;
- esp[-1].value.intval = dpos;
- return s_handle_read_exception(status, pp,
- NULL, 0, image_file_buffered_continue);
- default:
- /*case ERRC: */
- return_error(e_ioerror);
- }
- }
- /* Pass the data to the image processor. */
- if (avail == 0) {
- code = 1;
- break;
- }
- for (pi = 0, pp = pproc; pi < px && !code; ++pi, pp -= 2)
- code = gs_image_next(penum, pp->value.bytes, avail, &used);
- /* Reinitialize for the next row. */
- px = dpos = 0;
- }
- esp = zimage_pop_estack(esp);
- image_cleanup(op);
- return (code < 0 ? code : o_pop_estack);
-}
/* Process data from an image with string data sources. */
-/* This never requires callbacks, so it's simpler. */
+/* This may still encounter a RemapColor callback. */
private int
-image_string_process(os_ptr op, gs_image_enum * penum, int num_sources)
+image_string_continue(i_ctx_t *i_ctx_p)
{
- int px = 0;
+ int px = ETOP_PLANE_INDEX(esp)->value.intval;
+ gs_image_enum *penum = r_ptr(esp, gs_image_enum);
+ const byte *wanted = gs_image_planes_wanted(penum);
+ int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
for (;;) {
- const ref *psrc = esp - 3 - px * 2;
- uint size = r_size(psrc);
- uint used;
- int code;
-
- if (size == 0)
- code = 1;
- else
- code = gs_image_next(penum, psrc->value.bytes, size, &used);
- if (code) { /* Stop now. */
- esp -= NUM_PUSH(num_sources);
- image_cleanup(op);
- return (code < 0 ? code : o_pop_estack);
+ if (wanted[px]) {
+ const ref *psrc = ETOP_SOURCE(esp, px);
+ uint size = r_size(psrc);
+ uint used;
+ int code;
+
+ if (size == 0)
+ code = 1;
+ else {
+ code = gs_image_next(penum, psrc->value.bytes, size, &used);
+ if (code == e_RemapColor) {
+ ETOP_PLANE_INDEX(esp)->value.intval = px;
+ return code;
+ }
+ }
+ if (code) { /* Stop now. */
+ esp -= NUM_PUSH(num_sources);
+ image_cleanup(i_ctx_p);
+ return (code < 0 ? code : o_pop_estack);
+ }
}
if (++px == num_sources)
px = 0;
@@ -455,17 +433,11 @@ image_string_process(os_ptr op, gs_image_enum * penum, int num_sources)
}
/* Clean up after enumerating an image */
private int
-image_cleanup(os_ptr op)
+image_cleanup(i_ctx_t *i_ctx_p)
{
- gs_image_enum *penum;
- const ref *pb;
-
- /* Free any row buffers, in LIFO order as usual. */
- for (pb = esp + 2; !r_has_type(pb, t_integer); pb += 2)
- if (r_has_type(pb, t_string))
- gs_free_string(imemory, pb->value.bytes, r_size(pb),
- "image_cleanup");
- penum = r_ptr(pb + 2, gs_image_enum);
+ es_ptr ep_top = esp + NUM_PUSH(EBOT_NUM_SOURCES(esp)->value.intval);
+ gs_image_enum *penum = r_ptr(ep_top, gs_image_enum);
+
gs_image_cleanup(penum);
ifree_object(penum, "image_cleanup");
return 0;
@@ -480,5 +452,6 @@ const op_def zimage_op_defs[] =
/* Internal operators */
{"1%image_proc_continue", image_proc_continue},
{"0%image_file_continue", image_file_continue},
+ {"0%image_string_continue", image_string_continue},
op_def_end(0)
};
diff --git a/gs/src/zimage2.c b/gs/src/zimage2.c
index 7e49997d9..b153814b0 100644
--- a/gs/src/zimage2.c
+++ b/gs/src/zimage2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -22,6 +22,7 @@
#include "memory_.h"
#include "ghost.h"
#include "oper.h"
+#include "gschar.h" /* for in_cachedevice */
#include "gscolor.h"
#include "gscspace.h"
#include "gscolor2.h"
@@ -37,8 +38,9 @@
/* Extract and check the parameters for a gs_data_image_t. */
int
-data_image_params(const ref * op, gs_data_image_t * pim, image_params * pip,
- bool require_DataSource, int num_components, int max_bits_per_component)
+data_image_params(const ref *op, gs_data_image_t *pim,
+ image_params *pip, bool require_DataSource,
+ int num_components, int max_bits_per_component)
{
int code;
int decode_size;
@@ -86,8 +88,8 @@ data_image_params(const ref * op, gs_data_image_t * pim, image_params * pip,
/* Extract and check the parameters for a gs_pixel_image_t. */
int
-pixel_image_params(const ref * op, gs_pixel_image_t * pim, image_params * pip,
- int max_bits_per_component)
+pixel_image_params(i_ctx_t *i_ctx_p, const ref *op, gs_pixel_image_t *pim,
+ image_params *pip, int max_bits_per_component)
{
int num_components =
gs_color_space_num_components(gs_currentcolorspace(igs));
@@ -109,35 +111,39 @@ pixel_image_params(const ref * op, gs_pixel_image_t * pim, image_params * pip,
/* <dict> .image1 - */
private int
-zimage1(register os_ptr op)
+zimage1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image_t image;
image_params ip;
int code;
gs_image_t_init(&image, gs_currentcolorspace(igs));
- code = pixel_image_params(op, (gs_pixel_image_t *) & image, &ip, 12);
+ code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
+ 12);
if (code < 0)
return code;
- return zimage_setup((gs_pixel_image_t *) & image, &ip.DataSource[0],
+ return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
image.CombineWithColor, 1);
}
/* <dict> .imagemask1 - */
private int
-zimagemask1(register os_ptr op)
+zimagemask1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image_t image;
image_params ip;
int code;
- gs_image_t_init_mask(&image, false);
+ gs_image_t_init_mask_adjust(&image, false,
+ gs_incachedevice(igs) != CACHE_DEVICE_NONE);
code = data_image_params(op, (gs_data_image_t *) & image, &ip, true, 1, 1);
if (code < 0)
return code;
if (ip.MultipleDataSources)
return_error(e_rangecheck);
- return zimage_setup((gs_pixel_image_t *) & image, &ip.DataSource[0],
+ return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
true, 1);
}
diff --git a/gs/src/zimage3.c b/gs/src/zimage3.c
index 0de667566..63541f107 100644
--- a/gs/src/zimage3.c
+++ b/gs/src/zimage3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,8 +34,9 @@
/* <dict> .image3 - */
private int
-zimage3(register os_ptr op)
+zimage3(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image3_t image;
int interleave_type;
ref *pDataDict;
@@ -55,8 +56,9 @@ zimage3(register os_ptr op)
dict_find_string(op, "MaskDict", &pMaskDict) <= 0
)
return_error(e_rangecheck);
- if ((code = pixel_image_params(pDataDict, (gs_pixel_image_t *)&image,
- &ip_data, 12)) < 0 ||
+ if ((code = pixel_image_params(i_ctx_p, pDataDict,
+ (gs_pixel_image_t *)&image, &ip_data,
+ 12)) < 0 ||
(mcode = code = data_image_params(pMaskDict, &image.MaskDict, &ip_mask, false, 1, 12)) < 0 ||
(code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
(code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0
@@ -70,22 +72,23 @@ zimage3(register os_ptr op)
mcode != (image.InterleaveType != 3)
)
return_error(e_rangecheck);
- if (!mcode) {
+ if (image.InterleaveType == 3) {
/* Insert the mask DataSource before the data DataSources. */
memmove(&ip_data.DataSource[1], &ip_data.DataSource[0],
(countof(ip_data.DataSource) - 1) *
sizeof(ip_data.DataSource[0]));
ip_data.DataSource[0] = ip_mask.DataSource[0];
}
- return zimage_setup((gs_pixel_image_t *)&image,
+ return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
&ip_data.DataSource[0],
image.CombineWithColor, 1);
}
/* <dict> .image4 - */
private int
-zimage4(register os_ptr op)
+zimage4(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_image4_t image;
image_params ip;
int num_components =
@@ -95,7 +98,8 @@ zimage4(register os_ptr op)
int i;
gs_image4_t_init(&image, NULL);
- code = pixel_image_params(op, (gs_pixel_image_t *)&image, &ip, 12);
+ code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
+ 12);
if (code < 0)
return code;
code = dict_int_array_param(op, "MaskColor", num_components * 2,
@@ -118,7 +122,7 @@ zimage4(register os_ptr op)
}
} else
return_error(code < 0 ? code : gs_note_error(e_rangecheck));
- return zimage_setup((gs_pixel_image_t *)&image, &ip.DataSource[0],
+ return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
image.CombineWithColor, 1);
}
diff --git a/gs/src/ziodev.c b/gs/src/ziodev.c
index d59abe129..f76fe4540 100644
--- a/gs/src/ziodev.c
+++ b/gs/src/ziodev.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -24,14 +24,13 @@
#include "ghost.h"
#include "gp.h"
#include "gpcheck.h"
-#include "gsstruct.h" /* for registering root */
#include "oper.h"
#include "stream.h"
#include "ialloc.h"
#include "iscan.h"
#include "ivmspace.h"
#include "gxiodev.h" /* must come after stream.h */
- /* and before files.h */
+ /* and before files.h */
#include "files.h"
#include "scanchar.h" /* for char_EOL */
#include "store.h"
@@ -48,8 +47,9 @@ iodev_os_open_file(gx_io_device * iodev, const char *fname, uint len,
}
/* Define the special devices. */
+const char iodev_dtype_stdio[] = "Special";
#define iodev_special(dname, init, open) {\
- dname, "Special",\
+ dname, iodev_dtype_stdio,\
{ init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
iodev_no_enumerate_files, NULL, NULL,\
@@ -57,8 +57,13 @@ iodev_os_open_file(gx_io_device * iodev, const char *fname, uint len,
}\
}
-/* Export the stdio refs for switching contexts. */
-ref ref_stdio[3];
+/*
+ * We need the current context pointer for accessing / opening the %std
+ * IODevices. However, this is not available to the open routine.
+ * Therefore, we use the hack of storing this pointer in the IODevice state
+ * pointer just before calling the open routines. We clear the pointer
+ * immediately afterwards so as not to wind up with dangling references.
+ */
#define STDIN_BUF_SIZE 128
/*#define ref_stdin ref_stdio[0] *//* in files.h */
@@ -70,17 +75,15 @@ const gx_io_device gs_iodev_stdin =
#define STDOUT_BUF_SIZE 128
/*#define ref_stdout ref_stdio[1] *//* in files.h */
-private iodev_proc_init(stdout_init);
private iodev_proc_open_device(stdout_open);
const gx_io_device gs_iodev_stdout =
- iodev_special("%stdout%", stdout_init, stdout_open);
+ iodev_special("%stdout%", iodev_no_init, stdout_open);
#define STDERR_BUF_SIZE 128
/*#define ref_stderr ref_stdio[2] *//* in files.h */
-private iodev_proc_init(stderr_init);
private iodev_proc_open_device(stderr_open);
const gx_io_device gs_iodev_stderr =
- iodev_special("%stderr%", stderr_init, stderr_open);
+ iodev_special("%stderr%", iodev_no_init, stderr_open);
#define LINEEDIT_BUF_SIZE 20 /* initial size, not fixed size */
private iodev_proc_open_device(lineedit_open);
@@ -96,8 +99,9 @@ const gx_io_device gs_iodev_statementedit =
/* <int> .getiodevice <string> */
private int
-zgetiodevice(register os_ptr op)
+zgetiodevice(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_io_device *iodev;
const byte *dname;
@@ -129,11 +133,7 @@ private int
private int
stdin_init(gx_io_device * iodev, gs_memory_t * mem)
{
- static void *const pstdin = &ref_stdin;
-
- make_file(&ref_stdin, a_readonly | avm_system, 1, invalid_file_entry);
gs_stdin_is_interactive = true;
- gs_register_ref_root(mem, NULL, (void **)&pstdin, "ref_stdin");
return 0;
}
@@ -164,6 +164,7 @@ int
iodev_stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
gs_memory_t * mem)
{
+ i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
stream *s;
if (!streq1(access, 'r'))
@@ -178,16 +179,14 @@ iodev_stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
/* but it must have a substantial buffer, in case it is used */
/* by a stream that requires more than one input byte */
/* to make progress. */
- buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE,
- "stdin_open(buffer)");
+ buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)");
if (s == 0 || buf == 0)
return_error(e_VMerror);
sread_file(s, gs_stdin, buf, STDIN_BUF_SIZE);
s->procs.process = s_stdin_read_process;
s->save_close = s_std_null;
s->procs.close = file_close_file;
- make_file(&ref_stdin, a_readonly | avm_system,
- s->read_id, s);
+ make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s);
*ps = s;
return 1;
}
@@ -204,33 +203,34 @@ stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
}
/* This is the public routine for getting the stdin stream. */
int
-zget_stdin(stream ** ps)
+zget_stdin(i_ctx_t *i_ctx_p, stream ** ps)
{
stream *s;
gx_io_device *iodev;
+ int code;
if (file_is_valid(s, &ref_stdin)) {
*ps = s;
return 0;
}
iodev = gs_findiodevice((const byte *)"%stdin", 6);
- return (*iodev->procs.open_device)(iodev, "r", ps, imemory_system);
+ iodev->state = i_ctx_p;
+ code = (*iodev->procs.open_device)(iodev, "r", ps, imemory_system);
+ iodev->state = NULL;
+ return code;
}
-
-private int
-stdout_init(gx_io_device * iodev, gs_memory_t * mem)
+/* Test whether a stream is stdin. */
+bool
+zis_stdin(const stream *s)
{
- static void *const pstdout = &ref_stdout;
-
- make_file(&ref_stdout, a_all | avm_system, 1, invalid_file_entry);
- gs_register_ref_root(mem, NULL, (void **)&pstdout, "ref_stdout");
- return 0;
+ return (s_is_valid(s) && s->procs.process == s_stdin_read_process);
}
int
iodev_stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
gs_memory_t * mem)
{
+ i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
stream *s;
if (!streq1(access, 'w'))
@@ -240,8 +240,7 @@ iodev_stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
byte *buf;
s = file_alloc_stream(mem, "stdout_open(stream)");
- buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE,
- "stdout_open(buffer)");
+ buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)");
if (s == 0 || buf == 0)
return_error(e_VMerror);
swrite_file(s, gs_stdout, buf, STDOUT_BUF_SIZE);
@@ -264,33 +263,28 @@ stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
}
/* This is the public routine for getting the stdout stream. */
int
-zget_stdout(stream ** ps)
+zget_stdout(i_ctx_t *i_ctx_p, stream ** ps)
{
stream *s;
gx_io_device *iodev;
+ int code;
if (file_is_valid(s, &ref_stdout)) {
*ps = s;
return 0;
}
iodev = gs_findiodevice((const byte *)"%stdout", 7);
- return (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
-}
-
-private int
-stderr_init(gx_io_device * iodev, gs_memory_t * mem)
-{
- static void *const pstderr = &ref_stderr;
-
- make_file(&ref_stderr, a_all | avm_system, 1, invalid_file_entry);
- gs_register_ref_root(mem, NULL, (void **)&pstderr, "ref_stderr");
- return 0;
+ iodev->state = i_ctx_p;
+ code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
+ iodev->state = NULL;
+ return code;
}
int
iodev_stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
gs_memory_t * mem)
{
+ i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
stream *s;
if (!streq1(access, 'w'))
@@ -300,8 +294,7 @@ iodev_stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
byte *buf;
s = file_alloc_stream(mem, "stderr_open(stream)");
- buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE,
- "stderr_open(buffer)");
+ buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)");
if (s == 0 || buf == 0)
return_error(e_VMerror);
swrite_file(s, gs_stderr, buf, STDERR_BUF_SIZE);
@@ -324,17 +317,21 @@ stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
}
/* This is the public routine for getting the stderr stream. */
int
-zget_stderr(stream ** ps)
+zget_stderr(i_ctx_t *i_ctx_p, stream ** ps)
{
stream *s;
gx_io_device *iodev;
+ int code;
if (file_is_valid(s, &ref_stderr)) {
*ps = s;
return 0;
}
iodev = gs_findiodevice((const byte *)"%stderr", 7);
- return (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
+ iodev->state = i_ctx_p;
+ code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
+ iodev->state = NULL;
+ return code;
}
/* ------ %lineedit and %statementedit ------ */
@@ -347,25 +344,42 @@ line_collect(gx_io_device * iodev, const char *access, stream ** ps,
bool in_eol = false;
int code;
gx_io_device *indev = gs_findiodevice((const byte *)"%stdin", 6);
+ /* HACK: get the context pointer from the IODevice. See above. */
+ i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state;
stream *s;
stream *ins;
- byte *buf;
- uint buf_size = initial_buf_size;
+ gs_string str;
+ /*
+ * buf exists only for stylistic parallelism: all occurrences of
+ * buf-> could just as well be str. .
+ */
+ gs_string *const buf = &str;
if (strcmp(access, "r"))
return_error(e_invalidfileaccess);
s = file_alloc_stream(mem, "line_collect(stream)");
if (s == 0)
return_error(e_VMerror);
+ /* HACK: see above. */
+ indev->state = i_ctx_p;
code = (indev->procs.open_device)(indev, access, &ins, mem);
+ indev->state = 0;
if (code < 0)
return code;
- buf = gs_alloc_string(mem, buf_size, "line_collect(buffer)");
- if (buf == 0)
+ buf->size = initial_buf_size;
+ buf->data = gs_alloc_string(mem, buf->size, "line_collect(buffer)");
+ if (buf->data == 0)
return_error(e_VMerror);
- rd: /* We have to stop 1 character short of the buffer size, */
- /* because %statementedit must append an EOL. */
- code = zreadline_from(ins, buf, buf_size - 1, &count, &in_eol);
+rd:
+ /*
+ * We have to stop 1 character short of the buffer size,
+ * because %statementedit must append an EOL.
+ */
+ buf->size--;
+ /* HACK: set %stdin's state so that GNU readline can retrieve it. */
+ indev->state = i_ctx_p;
+ code = zreadline_from(ins, buf, mem, &count, &in_eol);
+ indev->state = 0;
switch (code) {
case EOFC:
code = gs_note_error(e_undefinedfilename);
@@ -388,20 +402,20 @@ line_collect(gx_io_device * iodev, const char *access, stream ** ps,
nsize = max_uint;
else
#endif
- nsize = buf_size * 2;
- nbuf = gs_resize_string(mem, buf, buf_size, nsize,
+ nsize = buf->size * 2;
+ nbuf = gs_resize_string(mem, buf->data, buf->size, nsize,
"line_collect(grow buffer)");
if (nbuf == 0) {
code = gs_note_error(e_VMerror);
break;
}
- buf = nbuf;
- buf_size = nsize;
+ buf->data = nbuf;
+ buf->size = nsize;
goto rd;
}
}
if (code != 0) {
- gs_free_string(mem, buf, buf_size, "line_collect(buffer)");
+ gs_free_string(mem, buf->data, buf->size, "line_collect(buffer)");
return code;
}
if (statement) {
@@ -414,11 +428,11 @@ line_collect(gx_io_device * iodev, const char *access, stream ** ps,
int code;
/* Add a terminating EOL. */
- buf[count++] = char_EOL;
- sread_string(ts, buf, count);
+ buf->data[count++] = char_EOL;
+ sread_string(ts, buf->data, count);
sc:
scanner_state_init_check(&state, false, true);
- code = scan_token(ts, &ignore_value, &state);
+ code = scan_token(i_ctx_p, ts, &ignore_value, &state);
ref_stack_pop_to(&o_stack, depth);
switch (code) {
case 0: /* read a token */
@@ -429,15 +443,15 @@ sc:
case scan_EOF:
break;
default: /* error */
- gs_free_string(mem, buf, buf_size, "line_collect(buffer)");
+ gs_free_string(mem, buf->data, buf->size, "line_collect(buffer)");
return code;
}
}
- buf = gs_resize_string(mem, buf, buf_size, count,
+ buf->data = gs_resize_string(mem, buf->data, buf->size, count,
"line_collect(resize buffer)");
- if (buf == 0)
+ if (buf->data == 0)
return_error(e_VMerror);
- sread_string(s, buf, count);
+ sread_string(s, buf->data, count);
s->save_close = s->procs.close;
s->procs.close = file_close_disable;
*ps = s;
diff --git a/gs/src/ziodev2.c b/gs/src/ziodev2.c
index 11f3bdb28..10fc6fc53 100644
--- a/gs/src/ziodev2.c
+++ b/gs/src/ziodev2.c
@@ -75,8 +75,9 @@ const gx_io_device gs_iodev_ram = {
/* <iodevice> .getdevparams <mark> <name> <value> ... */
private int
-zgetdevparams(os_ptr op)
+zgetdevparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_io_device *iodev;
stack_param_list list;
gs_param_list *const plist = (gs_param_list *) & list;
@@ -99,8 +100,9 @@ zgetdevparams(os_ptr op)
/* <mark> <name> <value> ... <iodevice> .putdevparams */
private int
-zputdevparams(os_ptr op)
+zputdevparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gx_io_device *iodev;
stack_param_list list;
gs_param_list *const plist = (gs_param_list *) & list;
diff --git a/gs/src/zlib.mak b/gs/src/zlib.mak
index 22cf784a4..fb73f3186 100644
--- a/gs/src/zlib.mak
+++ b/gs/src/zlib.mak
@@ -48,19 +48,21 @@ ZO_=$(O_)$(ZOBJ)
# Because the Watcom C runtime (and compiler) substitute space for = in
# command lines (!), we can't have a -D whose argument begins with -,
# since this will cause the argument to be interpreted as a switch (!!).
+# We need D_, _D_, and _D because the OpenVMS and Watcom compilers use
+# different syntax.
# ZI_ and ZF_ are defined in gs.mak.
ZCC=$(CC_) $(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)0-1$(_D)
# Define the name of this makefile.
ZLIB_MAK=$(GLSRC)zlib.mak
-z.clean: z.config-clean z.clean-not-config-clean
+z.clean : z.config-clean z.clean-not-config-clean
### WRONG. MUST DELETE OBJ AND GEN FILES SELECTIVELY.
-z.clean-not-config-clean:
+z.clean-not-config-clean :
$(RM_) $(ZOBJ)*.$(OBJ)
-z.config-clean:
+z.config-clean :
$(RMN_) $(ZGEN)zlib*.dev $(ZGEN)crc32*.dev
ZDEP=$(AK)
@@ -68,79 +70,79 @@ ZDEP=$(AK)
# Code common to compression and decompression.
zlibc_=$(ZOBJ)zutil.$(OBJ)
-$(ZGEN)zlibc.dev: $(ZLIB_MAK) $(ECHOGS_XE) $(zlibc_)
+$(ZGEN)zlibc.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(zlibc_)
$(SETMOD) $(ZGEN)zlibc $(zlibc_)
-$(ZOBJ)zutil.$(OBJ): $(ZSRC)zutil.c $(ZDEP)
+$(ZOBJ)zutil.$(OBJ) : $(ZSRC)zutil.c $(ZDEP)
$(ZCC) $(ZO_)zutil.$(OBJ) $(C_) $(ZSRC)zutil.c
# Encoding (compression) code.
-$(ZGEN)zlibe.dev: $(MAKEFILE) $(ZGEN)zlibe_$(SHARE_ZLIB).dev
+$(ZGEN)zlibe.dev : $(TOP_MAKEFILES) $(ZGEN)zlibe_$(SHARE_ZLIB).dev
$(CP_) $(ZGEN)zlibe_$(SHARE_ZLIB).dev $(ZGEN)zlibe.dev
-$(ZGEN)zlibe_1.dev: $(MAKEFILE) $(ZLIB_MAK) $(ECHOGS_XE)
+$(ZGEN)zlibe_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE)
$(SETMOD) $(ZGEN)zlibe_1 -lib $(ZLIB_NAME)
zlibe_=$(ZOBJ)adler32.$(OBJ) $(ZOBJ)deflate.$(OBJ) $(ZOBJ)trees.$(OBJ)
-$(ZGEN)zlibe_0.dev: $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibe_)
+$(ZGEN)zlibe_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibe_)
$(SETMOD) $(ZGEN)zlibe_0 $(zlibe_)
- $(ADDMOD) $(ZGEN)zlibe_0 -include $(ZGEN)zlibc
+ $(ADDMOD) $(ZGEN)zlibe_0 -include $(ZGEN)zlibc.dev
-$(ZOBJ)adler32.$(OBJ): $(ZSRC)adler32.c $(ZDEP)
+$(ZOBJ)adler32.$(OBJ) : $(ZSRC)adler32.c $(ZDEP)
$(ZCC) $(ZO_)adler32.$(OBJ) $(C_) $(ZSRC)adler32.c
-$(ZOBJ)deflate.$(OBJ): $(ZSRC)deflate.c $(ZDEP)
+$(ZOBJ)deflate.$(OBJ) : $(ZSRC)deflate.c $(ZDEP)
$(ZCC) $(ZO_)deflate.$(OBJ) $(C_) $(ZSRC)deflate.c
-$(ZOBJ)trees.$(OBJ): $(ZSRC)trees.c $(ZDEP)
+$(ZOBJ)trees.$(OBJ) : $(ZSRC)trees.c $(ZDEP)
$(ZCC) $(ZO_)trees.$(OBJ) $(C_) $(ZSRC)trees.c
# The zlib filters per se don't need crc32, but libpng versions starting
# with 0.90 do.
-$(ZGEN)crc32.dev: $(MAKEFILE) $(ZGEN)crc32_$(SHARE_ZLIB).dev
+$(ZGEN)crc32.dev : $(TOP_MAKEFILES) $(ZGEN)crc32_$(SHARE_ZLIB).dev
$(CP_) $(ZGEN)crc32_$(SHARE_ZLIB).dev $(ZGEN)crc32.dev
-$(ZGEN)crc32_1.dev: $(MAKEFILE) $(ZLIB_MAK) $(ECHOGS_XE)
+$(ZGEN)crc32_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE)
$(SETMOD) $(ZGEN)crc32_1 -lib $(ZLIB_NAME)
-$(ZGEN)crc32_0.dev: $(ZLIB_MAK) $(ECHOGS_XE) $(ZOBJ)crc32.$(OBJ)
+$(ZGEN)crc32_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZOBJ)crc32.$(OBJ)
$(SETMOD) $(ZGEN)crc32_0 $(ZOBJ)crc32.$(OBJ)
-$(ZOBJ)crc32.$(OBJ): $(ZSRC)crc32.c $(ZDEP)
+$(ZOBJ)crc32.$(OBJ) : $(ZSRC)crc32.c $(ZDEP)
$(ZCC) $(ZO_)crc32.$(OBJ) $(C_) $(ZSRC)crc32.c
# Decoding (decompression) code.
-$(ZGEN)zlibd.dev: $(MAKEFILE) $(ZGEN)zlibd_$(SHARE_ZLIB).dev
+$(ZGEN)zlibd.dev : $(TOP_MAKEFILES) $(ZGEN)zlibd_$(SHARE_ZLIB).dev
$(CP_) $(ZGEN)zlibd_$(SHARE_ZLIB).dev $(ZGEN)zlibd.dev
-$(ZGEN)zlibd_1.dev: $(MAKEFILE) $(ZLIB_MAK) $(ECHOGS_XE)
+$(ZGEN)zlibd_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE)
$(SETMOD) $(ZGEN)zlibd_1 -lib $(ZLIB_NAME)
zlibd1_=$(ZOBJ)infblock.$(OBJ) $(ZOBJ)infcodes.$(OBJ) $(ZOBJ)inffast.$(OBJ)
zlibd2_=$(ZOBJ)inflate.$(OBJ) $(ZOBJ)inftrees.$(OBJ) $(ZOBJ)infutil.$(OBJ)
zlibd_ = $(zlibd1_) $(zlibd2_)
-$(ZGEN)zlibd_0.dev: $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibd_)
+$(ZGEN)zlibd_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibd_)
$(SETMOD) $(ZGEN)zlibd_0 $(zlibd1_)
$(ADDMOD) $(ZGEN)zlibd_0 -obj $(zlibd2_)
- $(ADDMOD) $(ZGEN)zlibd_0 -include $(ZGEN)zlibc
+ $(ADDMOD) $(ZGEN)zlibd_0 -include $(ZGEN)zlibc.dev
-$(ZOBJ)infblock.$(OBJ): $(ZSRC)infblock.c $(ZDEP)
+$(ZOBJ)infblock.$(OBJ) : $(ZSRC)infblock.c $(ZDEP)
$(ZCC) $(ZO_)infblock.$(OBJ) $(C_) $(ZSRC)infblock.c
-$(ZOBJ)infcodes.$(OBJ): $(ZSRC)infcodes.c $(ZDEP)
+$(ZOBJ)infcodes.$(OBJ) : $(ZSRC)infcodes.c $(ZDEP)
$(ZCC) $(ZO_)infcodes.$(OBJ) $(C_) $(ZSRC)infcodes.c
-$(ZOBJ)inffast.$(OBJ): $(ZSRC)inffast.c $(ZDEP)
+$(ZOBJ)inffast.$(OBJ) : $(ZSRC)inffast.c $(ZDEP)
$(ZCC) $(ZO_)inffast.$(OBJ) $(C_) $(ZSRC)inffast.c
-$(ZOBJ)inflate.$(OBJ): $(ZSRC)inflate.c $(ZDEP)
+$(ZOBJ)inflate.$(OBJ) : $(ZSRC)inflate.c $(ZDEP)
$(ZCC) $(ZO_)inflate.$(OBJ) $(C_) $(ZSRC)inflate.c
-$(ZOBJ)inftrees.$(OBJ): $(ZSRC)inftrees.c $(ZDEP)
+$(ZOBJ)inftrees.$(OBJ) : $(ZSRC)inftrees.c $(ZDEP)
$(ZCC) $(ZO_)inftrees.$(OBJ) $(C_) $(ZSRC)inftrees.c
-$(ZOBJ)infutil.$(OBJ): $(ZSRC)infutil.c $(ZDEP)
+$(ZOBJ)infutil.$(OBJ) : $(ZSRC)infutil.c $(ZDEP)
$(ZCC) $(ZO_)infutil.$(OBJ) $(C_) $(ZSRC)infutil.c
diff --git a/gs/src/zmath.c b/gs/src/zmath.c
index 83083f3b8..4962ff88e 100644
--- a/gs/src/zmath.c
+++ b/gs/src/zmath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1992, 1993, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1992, 1993, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,16 +25,16 @@
#include "store.h"
/*
- * Define the current state of random number generator. We have to
- * implement this ourselves because the Unix rand doesn't provide anything
- * equivalent to rrand. Note that the value always lies in the range
- * [0..0x7ffffffe], even if longs are longer than 32 bits.
+ * Define the current state of random number generator for operators. We
+ * have to implement this ourselves because the Unix rand doesn't provide
+ * anything equivalent to rrand. Note that the value always lies in the
+ * range [0..0x7ffffffe], even if longs are longer than 32 bits.
*
* The state must be public so that context switching can save and
* restore it. (Even though the Red Book doesn't mention this,
* we verified with Adobe that this is the case.)
*/
-long zrand_state;
+#define zrand_state (i_ctx_p->rand_state)
/* Initialize the random number generator. */
void
@@ -48,8 +48,9 @@ zrand_state_init(long *pstate)
/* <num> sqrt <real> */
private int
-zsqrt(register os_ptr op)
+zsqrt(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num;
int code = real_param(op, &num);
@@ -63,8 +64,9 @@ zsqrt(register os_ptr op)
/* <num> arccos <real> */
private int
-zarccos(register os_ptr op)
+zarccos(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num, result;
int code = real_param(op, &num);
@@ -77,8 +79,9 @@ zarccos(register os_ptr op)
/* <num> arcsin <real> */
private int
-zarcsin(register os_ptr op)
+zarcsin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num, result;
int code = real_param(op, &num);
@@ -91,8 +94,9 @@ zarcsin(register os_ptr op)
/* <num> <denom> atan <real> */
private int
-zatan(register os_ptr op)
+zatan(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double args[2];
double result;
int code = num_params(op, 2, args);
@@ -115,8 +119,9 @@ zatan(register os_ptr op)
/* <num> cos <real> */
private int
-zcos(register os_ptr op)
+zcos(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double angle;
int code = real_param(op, &angle);
@@ -128,8 +133,9 @@ zcos(register os_ptr op)
/* <num> sin <real> */
private int
-zsin(register os_ptr op)
+zsin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double angle;
int code = real_param(op, &angle);
@@ -141,8 +147,9 @@ zsin(register os_ptr op)
/* <base> <exponent> exp <real> */
private int
-zexp(register os_ptr op)
+zexp(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double args[2];
double result;
double ipart;
@@ -162,8 +169,9 @@ zexp(register os_ptr op)
/* <posnum> ln <real> */
private int
-zln(register os_ptr op)
+zln(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num;
int code = real_param(op, &num);
@@ -177,8 +185,9 @@ zln(register os_ptr op)
/* <posnum> log <real> */
private int
-zlog(register os_ptr op)
+zlog(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double num;
int code = real_param(op, &num);
@@ -192,8 +201,11 @@ zlog(register os_ptr op)
/* - rand <int> */
private int
-zrand(register os_ptr op)
-{ /*
+zrand(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+
+ /*
* We use an algorithm from CACM 31 no. 10, pp. 1192-1201,
* October 1988. According to a posting by Ed Taft on
* comp.lang.postscript, Level 2 (Adobe) PostScript interpreters
@@ -219,8 +231,9 @@ zrand(register os_ptr op)
/* <int> srand - */
private int
-zsrand(register os_ptr op)
+zsrand(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
long state;
check_type(*op, t_integer);
@@ -244,8 +257,10 @@ zsrand(register os_ptr op)
/* - rrand <int> */
private int
-zrrand(register os_ptr op)
+zrrand(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, zrand_state);
return 0;
diff --git a/gs/src/zmatrix.c b/gs/src/zmatrix.c
index 2b1f1d25c..3260ecfdb 100644
--- a/gs/src/zmatrix.c
+++ b/gs/src/zmatrix.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -26,21 +26,22 @@
#include "store.h"
/* Forward references */
-private int common_transform(P3(os_ptr,
+private int common_transform(P3(i_ctx_t *,
int (*)(P4(gs_state *, floatp, floatp, gs_point *)),
int (*)(P4(floatp, floatp, const gs_matrix *, gs_point *))));
/* - initmatrix - */
private int
-zinitmatrix(os_ptr op)
+zinitmatrix(i_ctx_t *i_ctx_p)
{
return gs_initmatrix(igs);
}
/* <matrix> defaultmatrix <matrix> */
private int
-zdefaultmatrix(register os_ptr op)
+zdefaultmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
gs_defaultmatrix(igs, &mat);
@@ -49,8 +50,9 @@ zdefaultmatrix(register os_ptr op)
/* - .currentmatrix <xx> <xy> <yx> <yy> <tx> <ty> */
private int
-zcurrentmatrix(register os_ptr op)
+zcurrentmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
int code = gs_currentmatrix(igs, &mat);
@@ -65,8 +67,9 @@ zcurrentmatrix(register os_ptr op)
/* <xx> <xy> <yx> <yy> <tx> <ty> .setmatrix - */
private int
-zsetmatrix(register os_ptr op)
+zsetmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
int code = float_params(op, 6, &mat.xx);
@@ -80,8 +83,9 @@ zsetmatrix(register os_ptr op)
/* <matrix|null> .setdefaultmatrix - */
private int
-zsetdefaultmatrix(register os_ptr op)
+zsetdefaultmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
if (r_has_type(op, t_null))
@@ -103,8 +107,9 @@ zsetdefaultmatrix(register os_ptr op)
/* <tx> <ty> translate - */
/* <tx> <ty> <matrix> translate <matrix> */
private int
-ztranslate(register os_ptr op)
+ztranslate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
double trans[2];
@@ -133,8 +138,9 @@ ztranslate(register os_ptr op)
/* <sx> <sy> scale - */
/* <sx> <sy> <matrix> scale <matrix> */
private int
-zscale(register os_ptr op)
+zscale(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
double scale[2];
@@ -163,8 +169,9 @@ zscale(register os_ptr op)
/* <angle> rotate - */
/* <angle> <matrix> rotate <matrix> */
private int
-zrotate(register os_ptr op)
+zrotate(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
double ang;
@@ -192,8 +199,9 @@ zrotate(register os_ptr op)
/* <matrix> concat - */
private int
-zconcat(register os_ptr op)
+zconcat(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
int code = read_matrix(op, &mat);
@@ -208,8 +216,9 @@ zconcat(register os_ptr op)
/* <matrix1> <matrix2> <matrix> concatmatrix <matrix> */
private int
-zconcatmatrix(register os_ptr op)
+zconcatmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix m1, m2, mp;
int code;
@@ -227,41 +236,42 @@ zconcatmatrix(register os_ptr op)
/* <x> <y> transform <xt> <yt> */
/* <x> <y> <matrix> transform <xt> <yt> */
private int
-ztransform(register os_ptr op)
+ztransform(i_ctx_t *i_ctx_p)
{
- return common_transform(op, gs_transform, gs_point_transform);
+ return common_transform(i_ctx_p, gs_transform, gs_point_transform);
}
/* <dx> <dy> dtransform <dxt> <dyt> */
/* <dx> <dy> <matrix> dtransform <dxt> <dyt> */
private int
-zdtransform(register os_ptr op)
+zdtransform(i_ctx_t *i_ctx_p)
{
- return common_transform(op, gs_dtransform, gs_distance_transform);
+ return common_transform(i_ctx_p, gs_dtransform, gs_distance_transform);
}
/* <xt> <yt> itransform <x> <y> */
/* <xt> <yt> <matrix> itransform <x> <y> */
private int
-zitransform(register os_ptr op)
+zitransform(i_ctx_t *i_ctx_p)
{
- return common_transform(op, gs_itransform, gs_point_transform_inverse);
+ return common_transform(i_ctx_p, gs_itransform, gs_point_transform_inverse);
}
/* <dxt> <dyt> idtransform <dx> <dy> */
/* <dxt> <dyt> <matrix> idtransform <dx> <dy> */
private int
-zidtransform(register os_ptr op)
+zidtransform(i_ctx_t *i_ctx_p)
{
- return common_transform(op, gs_idtransform, gs_distance_transform_inverse);
+ return common_transform(i_ctx_p, gs_idtransform, gs_distance_transform_inverse);
}
/* Common logic for [i][d]transform */
private int
-common_transform(register os_ptr op,
+common_transform(i_ctx_t *i_ctx_p,
int (*ptproc)(P4(gs_state *, floatp, floatp, gs_point *)),
int (*matproc)(P4(floatp, floatp, const gs_matrix *, gs_point *)))
{
+ os_ptr op = osp;
double opxy[2];
gs_point pt;
int code;
@@ -314,8 +324,9 @@ out:
/* <matrix> <inv_matrix> invertmatrix <inv_matrix> */
private int
-zinvertmatrix(register os_ptr op)
+zinvertmatrix(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix m;
int code;
diff --git a/gs/src/zmedia2.c b/gs/src/zmedia2.c
index 2055e6893..17be5db45 100644
--- a/gs/src/zmedia2.c
+++ b/gs/src/zmedia2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -47,8 +47,9 @@ reset_match(match_record_t *match)
match->priority = match->no_match_priority;
}
private int
-zmatchmedia(register os_ptr op)
+zmatchmedia(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr preq = op - 3;
os_ptr pattr = op - 2;
os_ptr ppol = op - 1;
@@ -223,8 +224,9 @@ no:;
* <matrix|null> <med_x> <med_y> true -or- false
*/
private int
-zmatchpagesize(register os_ptr op)
+zmatchpagesize(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_matrix mat;
float ignore_mismatch = (float)max_long;
gs_point media_size;
diff --git a/gs/src/zmisc.c b/gs/src/zmisc.c
index 54e30a16a..2b9a59679 100644
--- a/gs/src/zmisc.c
+++ b/gs/src/zmisc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,9 +34,16 @@
#include "store.h"
/* <proc> bind <proc> */
+inline private bool
+r_is_ex_oper(const ref *rp)
+{
+ return (r_has_attr(rp, a_executable) &&
+ (r_btype(rp) == t_operator || r_type(rp) == t_oparray));
+}
private int
-zbind(os_ptr op)
+zbind(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint depth = 1;
ref defn;
register os_ptr bsp;
@@ -64,9 +71,6 @@ zbind(os_ptr op)
* `depth' elements have been pushed on the ostack;
* For i < depth, p = ref_stack_index(&o_stack, i):
* *p is an array (or packedarray) ref. */
-#define r_is_ex_oper(rp)\
- ((r_btype(rp) == t_operator || r_type(rp) == t_oparray) &&\
- r_has_attr(rp, a_executable))
while (depth) {
while (r_size(bsp)) {
ref *tp = bsp->value.refs;
@@ -84,11 +88,17 @@ zbind(os_ptr op)
&nref);
if ((pvalue = dict_find_name(&nref)) != 0 &&
r_is_ex_oper(pvalue)
- )
- /* Note: can't undo this by restore! */
+ ) {
+ store_check_dest(bsp, pvalue);
+ /*
+ * Always save the change, since this can only
+ * happen once.
+ */
+ ref_do_save(bsp, tp, "bind");
*(ushort *) tp =
pt_tag(pt_executable_operator) +
op_index(pvalue);
+ }
}
bsp->value.refs = (ref *) ((ref_packed *) tp + 1);
} else
@@ -99,8 +109,10 @@ zbind(os_ptr op)
if ((pvalue = dict_find_name(tp)) != 0 &&
r_is_ex_oper(pvalue)
- )
+ ) {
+ store_check_dest(bsp, pvalue);
ref_assign_old(bsp, tp, pvalue, "bind");
+ }
}
break;
case t_array: /* push into array if writable */
@@ -145,8 +157,10 @@ zbind(os_ptr op)
/* - serialnumber <int> */
private int
-zserialnumber(register os_ptr op)
+zserialnumber(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, gs_serialnumber);
return 0;
@@ -154,8 +168,9 @@ zserialnumber(register os_ptr op)
/* - realtime <int> */
private int
-zrealtime(register os_ptr op)
+zrealtime(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
long secs_ns[2];
gp_get_realtime(secs_ns);
@@ -166,8 +181,9 @@ zrealtime(register os_ptr op)
/* - usertime <int> */
private int
-zusertime(register os_ptr op)
+zusertime(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
long secs_ns[2];
gp_get_usertime(secs_ns);
@@ -181,8 +197,9 @@ zusertime(register os_ptr op)
/* <string> getenv <value_string> true */
/* <string> getenv false */
private int
-zgetenv(register os_ptr op)
+zgetenv(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
char *str;
byte *value;
int code;
@@ -215,8 +232,9 @@ zgetenv(register os_ptr op)
/* <name> <proc> .makeoperator <oper> */
private int
-zmakeoperator(register os_ptr op)
+zmakeoperator(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
op_array_table *opt;
uint count;
ref *tab;
@@ -257,8 +275,10 @@ zmakeoperator(register os_ptr op)
/* - .oserrno <int> */
private int
-zoserrno(register os_ptr op)
+zoserrno(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, errno);
return 0;
@@ -266,8 +286,10 @@ zoserrno(register os_ptr op)
/* <int> .setoserrno - */
private int
-zsetoserrno(register os_ptr op)
+zsetoserrno(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
errno = op->value.intval;
pop(1);
@@ -277,8 +299,9 @@ zsetoserrno(register os_ptr op)
/* <int> .oserrorstring <string> true */
/* <int> .oserrorstring false */
private int
-zoserrorstring(register os_ptr op)
+zoserrorstring(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const char *str;
int code;
uint len;
@@ -306,8 +329,9 @@ zoserrorstring(register os_ptr op)
/* <string> <bool> .setdebug - */
private int
-zsetdebug(register os_ptr op)
+zsetdebug(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_read_type(op[-1], t_string);
check_type(*op, t_boolean);
{
diff --git a/gs/src/zmisc1.c b/gs/src/zmisc1.c
index 0b7f5cc85..422d1a0b8 100644
--- a/gs/src/zmisc1.c
+++ b/gs/src/zmisc1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1997, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,22 +31,23 @@
/* <state> <from_string> <to_string> .type1encrypt <new_state> <substring> */
/* <state> <from_string> <to_string> .type1decrypt <new_state> <substring> */
-private int type1crypt(P2(os_ptr,
+private int type1crypt(P2(i_ctx_t *,
int (*)(P4(byte *, const byte *, uint, ushort *))));
private int
-ztype1encrypt(os_ptr op)
+ztype1encrypt(i_ctx_t *i_ctx_p)
{
- return type1crypt(op, gs_type1_encrypt);
+ return type1crypt(i_ctx_p, gs_type1_encrypt);
}
private int
-ztype1decrypt(os_ptr op)
+ztype1decrypt(i_ctx_t *i_ctx_p)
{
- return type1crypt(op, gs_type1_decrypt);
+ return type1crypt(i_ctx_p, gs_type1_decrypt);
}
private int
-type1crypt(register os_ptr op,
+type1crypt(i_ctx_t *i_ctx_p,
int (*proc)(P4(byte *, const byte *, uint, ushort *)))
{
+ os_ptr op = osp;
crypt_state state;
uint ssize;
@@ -87,21 +88,23 @@ eexec_param(os_ptr op, ushort * pcstate)
/* <target> <seed> eexecEncode/filter <file> */
/* <target> <seed> <dict_ignored> eexecEncode/filter <file> */
private int
-zexE(register os_ptr op)
+zexE(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_exE_state state;
int code = eexec_param(op, &state.cstate);
if (code < 0)
return code;
- return filter_write(op, code, &s_exE_template, (stream_state *)&state, 0);
+ return filter_write(i_ctx_p, code, &s_exE_template, (stream_state *)&state, 0);
}
/* <source> <seed> eexecDecode/filter <file> */
/* <source> <dict> eexecDecode/filter <file> */
private int
-zexD(register os_ptr op)
+zexD(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream_exD_state state;
int code;
@@ -135,7 +138,7 @@ zexD(register os_ptr op)
state.pfb_state = (stream_PFBD_state *) s->state;
}
state.binary = -1;
- return filter_read(op, code, &s_exD_template, (stream_state *)&state, 0);
+ return filter_read(i_ctx_p, code, &s_exD_template, (stream_state *)&state, 0);
}
/* ------ Initialization procedure ------ */
diff --git a/gs/src/zmisc2.c b/gs/src/zmisc2.c
index 565fd6256..be589903e 100644
--- a/gs/src/zmisc2.c
+++ b/gs/src/zmisc2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -23,7 +23,7 @@
#include "ghost.h"
#include "oper.h"
#include "estack.h"
-#include "idict.h"
+#include "iddict.h"
#include "idparam.h"
#include "iparam.h"
#include "dstack.h"
@@ -34,78 +34,39 @@
#include "store.h"
/* Forward references */
-private int set_language_level(P1(int));
+private int set_language_level(P2(i_ctx_t *, int));
/* ------ Language level operators ------ */
/* - .languagelevel <int> */
private int
-zlanguagelevel(register os_ptr op)
+zlanguagelevel(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
- ref_assign(op, &ref_language_level);
+ make_int(op, LANGUAGE_LEVEL);
return 0;
}
/* <int> .setlanguagelevel - */
private int
-zsetlanguagelevel(register os_ptr op)
+zsetlanguagelevel(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = 0;
check_type(*op, t_integer);
- if (op->value.intval != ref_language_level.value.intval) {
- code = set_language_level((int)op->value.intval);
+ if (op->value.intval != LANGUAGE_LEVEL) {
+ code = set_language_level(i_ctx_p, (int)op->value.intval);
if (code < 0)
return code;
}
+ LANGUAGE_LEVEL = op->value.intval;
pop(1);
- ref_assign_old(NULL, &ref_language_level, op, "setlanguagelevel");
return code;
}
-/* ------ The 'where' hack ------ */
-
-private int
-z2where(register os_ptr op)
-{ /*
- * Aldus Freehand versions 2.x check for the presence of the
- * setcolor operator, and if it is missing, substitute a procedure.
- * Unfortunately, the procedure takes different parameters from
- * the operator. As a result, files produced by this application
- * cause an error if the setcolor operator is actually defined
- * and 'bind' is ever used. Aldus fixed this bug in Freehand 3.0,
- * but there are a lot of files created by the older versions
- * still floating around. Therefore, at Adobe's suggestion,
- * we implement the following dreadful hack in the 'where' operator:
- * If the key is /setcolor, and
- * there is a dictionary named FreeHandDict, and
- * currentdict is that dictionary,
- * then "where" consults only that dictionary and not any other
- * dictionaries on the dictionary stack.
- */
- ref rkns, rfh;
- const ref *pdref = dsp;
- ref *pvalue;
-
- if (!r_has_type(op, t_name) ||
- (name_string_ref(op, &rkns), r_size(&rkns)) != 8 ||
- memcmp(rkns.value.bytes, "setcolor", 8) != 0 ||
- name_ref((const byte *)"FreeHandDict", 12, &rfh, -1) < 0 ||
- (pvalue = dict_find_name(&rfh)) == 0 ||
- !obj_eq(pvalue, pdref)
- )
- return zwhere(op);
- check_dict_read(*pdref);
- if (dict_find(pdref, op, &pvalue) > 0) {
- ref_assign(op, pdref);
- push(1);
- make_true(op);
- } else
- make_false(op);
- return 0;
-}
-
/* ------ Initialization procedure ------ */
/* The level setting ops are recognized even in Level 1 mode. */
@@ -113,10 +74,6 @@ const op_def zmisc2_op_defs[] =
{
{"0.languagelevel", zlanguagelevel},
{"1.setlanguagelevel", zsetlanguagelevel},
- /* The rest of the operators are defined only in Level 2. */
- op_def_begin_level2(),
- /* Note that this overrides the definition in zdict.c. */
- {"1where", z2where},
op_def_end(0)
};
@@ -127,14 +84,15 @@ const op_def zmisc2_op_defs[] =
* This is used for the .setlanguagelevel operator,
* and (perhaps someday) after a restore.
*/
-private int swap_level_dict(P1(const char *dict_name));
-private int swap_entry(P3(ref elt[2], ref * pdict, ref * pdict2));
+private int swap_level_dict(P2(i_ctx_t *i_ctx_p, const char *dict_name));
+private int swap_entry(P4(i_ctx_t *i_ctx_p, ref elt[2], ref * pdict,
+ ref * pdict2));
private int
-set_language_level(int new_level)
+set_language_level(i_ctx_t *i_ctx_p, int new_level)
{
- int old_level = ref_language_level.value.intval;
+ int old_level = LANGUAGE_LEVEL;
ref *pgdict = /* globaldict, if present */
- ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 2);
+ ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 2);
ref *level2dict;
int code = 0;
@@ -171,13 +129,13 @@ set_language_level(int new_level)
/* Set other flags for Level 2 operation. */
dict_auto_expand = true;
}
- code = swap_level_dict("level2dict");
+ code = swap_level_dict(i_ctx_p, "level2dict");
if (code < 0)
return code;
++old_level;
continue;
case 3: /* 3 => 1 or 2 */
- code = swap_level_dict("ll3dict");
+ code = swap_level_dict(i_ctx_p, "ll3dict");
if (code < 0)
return code;
--old_level;
@@ -203,10 +161,10 @@ set_language_level(int new_level)
/* Set other flags for Level 1 operation. */
dict_auto_expand = false;
}
- code = swap_level_dict("level2dict");
+ code = swap_level_dict(i_ctx_p, "level2dict");
break;
case 3: /* 2 => 3 */
- code = swap_level_dict("ll3dict");
+ code = swap_level_dict(i_ctx_p, "ll3dict");
break;
default: /* not possible */
return_error(e_Fatal);
@@ -225,7 +183,7 @@ set_language_level(int new_level)
* to swap the contents of statusdict.)
*/
private int
-swap_level_dict(const char *dict_name)
+swap_level_dict(i_ctx_t *i_ctx_p, const char *dict_name)
{
ref *leveldict;
int index;
@@ -250,13 +208,13 @@ swap_level_dict(const char *dict_name)
while ((isub = dict_next(&elt[1], isub, &subelt[0])) >= 0)
if (!obj_eq(&subelt[0], &elt[0])) {
/* don't swap dict itself */
- int code = swap_entry(subelt, subdict, &elt[1]);
+ int code = swap_entry(i_ctx_p, subelt, subdict, &elt[1]);
if (code < 0)
return code;
}
} else {
- int code = swap_entry(elt, systemdict, leveldict);
+ int code = swap_entry(i_ctx_p, elt, systemdict, leveldict);
if (code < 0)
return code;
@@ -270,7 +228,7 @@ swap_level_dict(const char *dict_name)
* (*pdict2).
*/
private int
-swap_entry(ref elt[2], ref * pdict, ref * pdict2)
+swap_entry(i_ctx_t *i_ctx_p, ref elt[2], ref * pdict, ref * pdict2)
{
ref *pvalue;
ref old_value; /* current value in *pdict */
@@ -278,7 +236,11 @@ swap_entry(ref elt[2], ref * pdict, ref * pdict2)
switch (found) {
default: /* <0, error */
- return found;
+ /*
+ * The only possible error here is a dictfull error, which is
+ * harmless.
+ */
+ /* fall through */
case 0: /* missing */
make_null(&old_value);
break;
@@ -296,9 +258,9 @@ swap_entry(ref elt[2], ref * pdict, ref * pdict2)
int code;
r_set_space(pdict2, avm_local);
- dict_put(pdict2, &elt[0], &old_value);
+ idict_put(pdict2, &elt[0], &old_value);
if (r_has_type(&elt[1], t_null)) {
- code = dict_undef(pdict, &elt[0]);
+ code = idict_undef(pdict, &elt[0]);
if (code == e_undefined &&
r_has_type(&old_value, t_null)
)
@@ -307,7 +269,7 @@ swap_entry(ref elt[2], ref * pdict, ref * pdict2)
uint space = r_space(pdict);
r_set_space(pdict, avm_local);
- code = dict_put(pdict, &elt[0], &elt[1]);
+ code = idict_put(pdict, &elt[0], &elt[1]);
r_set_space(pdict, space);
}
r_set_space(pdict2, space2);
diff --git a/gs/src/zmisc3.c b/gs/src/zmisc3.c
index f07f0c9d4..f46a6fbd1 100644
--- a/gs/src/zmisc3.c
+++ b/gs/src/zmisc3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -19,21 +19,25 @@
/* Miscellaneous LanguageLevel 3 operators */
#include "ghost.h"
+#include "gscspace.h" /* for gscolor2.h */
+#include "gsmatrix.h" /* ditto */
#include "gsclipsr.h"
+#include "gscolor2.h"
+#include "gscssub.h"
#include "oper.h"
#include "igstate.h"
#include "store.h"
/* - clipsave - */
private int
-zclipsave(os_ptr op)
+zclipsave(i_ctx_t *i_ctx_p)
{
return gs_clipsave(igs);
}
/* - cliprestore - */
private int
-zcliprestore(os_ptr op)
+zcliprestore(i_ctx_t *i_ctx_p)
{
return gs_cliprestore(igs);
}
@@ -48,8 +52,9 @@ typedef struct ref2_s {
ref proc1, proc2;
} ref2_t;
private int
-zeqproc(register os_ptr op)
+zeqproc(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref2_t stack[MAX_DEPTH + 1];
ref2_t *top = stack;
@@ -111,6 +116,25 @@ zeqproc(register os_ptr op)
return 0;
}
+/* <index> <bool> .setsubstitutecolorspace - */
+private int
+zsetsubstitutecolorspace(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ int index, code;
+
+ check_type(*op, t_boolean);
+ check_int_leu(op[-1], 2);
+ index = (int)op[-1].value.intval;
+ code = gs_setsubstitutecolorspace(igs, index,
+ (op->value.boolval ?
+ gs_currentcolorspace(igs) :
+ NULL));
+ if (code >= 0)
+ pop(2);
+ return code;
+}
+
/* ------ Initialization procedure ------ */
const op_def zmisc3_op_defs[] =
@@ -119,5 +143,6 @@ const op_def zmisc3_op_defs[] =
{"0cliprestore", zcliprestore},
{"0clipsave", zclipsave},
{"2.eqproc", zeqproc},
+ {"2.setsubstitutecolorspace", zsetsubstitutecolorspace},
op_def_end(0)
};
diff --git a/gs/src/zpacked.c b/gs/src/zpacked.c
index b50748ba9..117e1db39 100644
--- a/gs/src/zpacked.c
+++ b/gs/src/zpacked.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1992, 1993 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1992, 1993, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,13 +29,12 @@
#include "oper.h"
#include "store.h"
-/* Import the array packing flag */
-extern ref ref_array_packing;
-
/* - currentpacking <bool> */
private int
-zcurrentpacking(register os_ptr op)
+zcurrentpacking(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
ref_assign(op, &ref_array_packing);
return 0;
@@ -43,8 +42,9 @@ zcurrentpacking(register os_ptr op)
/* <obj_0> ... <obj_n-1> <n> packedarray <packedarray> */
int
-zpackedarray(register os_ptr op)
+zpackedarray(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
ref parr;
@@ -65,10 +65,14 @@ zpackedarray(register os_ptr op)
/* <bool> setpacking - */
private int
-zsetpacking(register os_ptr op)
+zsetpacking(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+ ref cont;
+
check_type(*op, t_boolean);
- ref_assign_old(NULL, &ref_array_packing, op, "setpacking");
+ make_struct(&cont, avm_local, ref_array_packing_container);
+ ref_assign_old(&cont, &ref_array_packing, op, "setpacking");
pop(1);
return 0;
}
@@ -78,7 +82,7 @@ zsetpacking(register os_ptr op)
/* Make a packed array. See the comment in packed.h about */
/* ensuring that refs in mixed arrays are properly aligned. */
int
-make_packed_array(ref * parr, ref_stack * pstack, uint size,
+make_packed_array(ref * parr, ref_stack_t * pstack, uint size,
client_name_t cname)
{
uint i;
diff --git a/gs/src/zpaint.c b/gs/src/zpaint.c
index 4eecad4c3..330f27baf 100644
--- a/gs/src/zpaint.c
+++ b/gs/src/zpaint.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,21 +25,21 @@
/* - fill - */
private int
-zfill(register os_ptr op)
+zfill(i_ctx_t *i_ctx_p)
{
return gs_fill(igs);
}
/* - eofill - */
private int
-zeofill(register os_ptr op)
+zeofill(i_ctx_t *i_ctx_p)
{
return gs_eofill(igs);
}
/* - stroke - */
private int
-zstroke(register os_ptr op)
+zstroke(i_ctx_t *i_ctx_p)
{
return gs_stroke(igs);
}
@@ -48,15 +48,16 @@ zstroke(register os_ptr op)
/* - .fillpage - */
private int
-zfillpage(register os_ptr op)
+zfillpage(i_ctx_t *i_ctx_p)
{
return gs_fillpage(igs);
}
/* <width> <height> <data> .imagepath - */
private int
-zimagepath(register os_ptr op)
+zimagepath(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_type(op[-2], t_integer);
diff --git a/gs/src/zpath.c b/gs/src/zpath.c
index a090d4bd2..12dcd98b7 100644
--- a/gs/src/zpath.c
+++ b/gs/src/zpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,22 +27,23 @@
#include "store.h"
/* Forward references */
-private int common_to(P2(os_ptr,
+private int common_to(P2(i_ctx_t *,
int (*)(P3(gs_state *, floatp, floatp))));
-private int common_curve(P2(os_ptr,
+private int common_curve(P2(i_ctx_t *,
int (*)(P7(gs_state *, floatp, floatp, floatp, floatp, floatp, floatp))));
/* - newpath - */
private int
-znewpath(register os_ptr op)
+znewpath(i_ctx_t *i_ctx_p)
{
return gs_newpath(igs);
}
/* - currentpoint <x> <y> */
private int
-zcurrentpoint(register os_ptr op)
+zcurrentpoint(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_point pt;
int code = gs_currentpoint(igs, &pt);
@@ -56,36 +57,38 @@ zcurrentpoint(register os_ptr op)
/* <x> <y> moveto - */
int
-zmoveto(os_ptr op)
+zmoveto(i_ctx_t *i_ctx_p)
{
- return common_to(op, gs_moveto);
+ return common_to(i_ctx_p, gs_moveto);
}
/* <dx> <dy> rmoveto - */
int
-zrmoveto(os_ptr op)
+zrmoveto(i_ctx_t *i_ctx_p)
{
- return common_to(op, gs_rmoveto);
+ return common_to(i_ctx_p, gs_rmoveto);
}
/* <x> <y> lineto - */
int
-zlineto(os_ptr op)
+zlineto(i_ctx_t *i_ctx_p)
{
- return common_to(op, gs_lineto);
+ return common_to(i_ctx_p, gs_lineto);
}
/* <dx> <dy> rlineto - */
int
-zrlineto(os_ptr op)
+zrlineto(i_ctx_t *i_ctx_p)
{
- return common_to(op, gs_rlineto);
+ return common_to(i_ctx_p, gs_rlineto);
}
/* Common code for [r](move/line)to */
private int
-common_to(os_ptr op, int (*add_proc)(P3(gs_state *, floatp, floatp)))
+common_to(i_ctx_t *i_ctx_p,
+ int (*add_proc)(P3(gs_state *, floatp, floatp)))
{
+ os_ptr op = osp;
double opxy[2];
int code;
@@ -99,23 +102,24 @@ common_to(os_ptr op, int (*add_proc)(P3(gs_state *, floatp, floatp)))
/* <x1> <y1> <x2> <y2> <x3> <y3> curveto - */
int
-zcurveto(register os_ptr op)
+zcurveto(i_ctx_t *i_ctx_p)
{
- return common_curve(op, gs_curveto);
+ return common_curve(i_ctx_p, gs_curveto);
}
/* <dx1> <dy1> <dx2> <dy2> <dx3> <dy3> rcurveto - */
int
-zrcurveto(register os_ptr op)
+zrcurveto(i_ctx_t *i_ctx_p)
{
- return common_curve(op, gs_rcurveto);
+ return common_curve(i_ctx_p, gs_rcurveto);
}
/* Common code for [r]curveto */
private int
-common_curve(os_ptr op,
+common_curve(i_ctx_t *i_ctx_p,
int (*add_proc)(P7(gs_state *, floatp, floatp, floatp, floatp, floatp, floatp)))
{
+ os_ptr op = osp;
double opxy[6];
int code;
@@ -129,61 +133,38 @@ common_curve(os_ptr op,
/* - closepath - */
int
-zclosepath(register os_ptr op)
+zclosepath(i_ctx_t *i_ctx_p)
{
return gs_closepath(igs);
}
/* - initclip - */
private int
-zinitclip(register os_ptr op)
+zinitclip(i_ctx_t *i_ctx_p)
{
return gs_initclip(igs);
}
/* - clip - */
private int
-zclip(register os_ptr op)
+zclip(i_ctx_t *i_ctx_p)
{
return gs_clip(igs);
}
/* - eoclip - */
private int
-zeoclip(register os_ptr op)
+zeoclip(i_ctx_t *i_ctx_p)
{
return gs_eoclip(igs);
}
-/* <bool> .setclipoutside - */
-private int
-zsetclipoutside(register os_ptr op)
-{
- int code;
-
- check_type(*op, t_boolean);
- code = gs_setclipoutside(igs, op->value.boolval);
- if (code >= 0)
- pop(1);
- return code;
-}
-
-/* - .currentclipoutside <bool> */
-private int
-zcurrentclipoutside(register os_ptr op)
-{
- push(1);
- make_bool(op, gs_currentclipoutside(igs));
- return 0;
-}
-
/* ------ Initialization procedure ------ */
const op_def zpath_op_defs[] =
{
{"0clip", zclip},
{"0closepath", zclosepath},
- {"0.currentclipoutside", zcurrentclipoutside},
{"0currentpoint", zcurrentpoint},
{"6curveto", zcurveto},
{"0eoclip", zeoclip},
@@ -194,6 +175,5 @@ const op_def zpath_op_defs[] =
{"6rcurveto", zrcurveto},
{"2rlineto", zrlineto},
{"2rmoveto", zrmoveto},
- {"1.setclipoutside", zsetclipoutside},
op_def_end(0)
};
diff --git a/gs/src/zpath1.c b/gs/src/zpath1.c
index 6e1ebe77f..4c10a29b0 100644
--- a/gs/src/zpath1.c
+++ b/gs/src/zpath1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -29,29 +29,30 @@
#include "store.h"
/* Forward references */
-private int common_arc(P2(os_ptr,
+private int common_arc(P2(i_ctx_t *,
int (*)(P6(gs_state *, floatp, floatp, floatp, floatp, floatp))));
-private int common_arct(P2(os_ptr, float *));
+private int common_arct(P2(i_ctx_t *, float *));
/* <x> <y> <r> <ang1> <ang2> arc - */
int
-zarc(os_ptr op)
+zarc(i_ctx_t *i_ctx_p)
{
- return common_arc(op, gs_arc);
+ return common_arc(i_ctx_p, gs_arc);
}
/* <x> <y> <r> <ang1> <ang2> arcn - */
int
-zarcn(os_ptr op)
+zarcn(i_ctx_t *i_ctx_p)
{
- return common_arc(op, gs_arcn);
+ return common_arc(i_ctx_p, gs_arcn);
}
/* Common code for arc[n] */
private int
-common_arc(os_ptr op,
+common_arc(i_ctx_t *i_ctx_p,
int (*aproc)(P6(gs_state *, floatp, floatp, floatp, floatp, floatp)))
{
+ os_ptr op = osp;
double xyra[5]; /* x, y, r, ang1, ang2 */
int code = num_params(op, 5, xyra);
@@ -65,9 +66,9 @@ common_arc(os_ptr op,
/* <x1> <y1> <x2> <y2> <r> arct - */
int
-zarct(register os_ptr op)
+zarct(i_ctx_t *i_ctx_p)
{
- int code = common_arct(op, (float *)0);
+ int code = common_arct(i_ctx_p, (float *)0);
if (code < 0)
return code;
@@ -77,10 +78,11 @@ zarct(register os_ptr op)
/* <x1> <y1> <x2> <y2> <r> arcto <xt1> <yt1> <xt2> <yt2> */
private int
-zarcto(register os_ptr op)
+zarcto(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
float tanxy[4]; /* xt1, yt1, xt2, yt2 */
- int code = common_arct(op, tanxy);
+ int code = common_arct(i_ctx_p, tanxy);
if (code < 0)
return code;
@@ -94,8 +96,9 @@ zarcto(register os_ptr op)
/* Common code for arct[o] */
private int
-common_arct(os_ptr op, float *tanxy)
+common_arct(i_ctx_t *i_ctx_p, float *tanxy)
{
+ os_ptr op = osp;
double args[5]; /* x1, y1, x2, y2, r */
int code = num_params(op, 5, args);
@@ -106,43 +109,44 @@ common_arct(os_ptr op, float *tanxy)
/* - .dashpath - */
private int
-zdashpath(register os_ptr op)
+zdashpath(i_ctx_t *i_ctx_p)
{
return gs_dashpath(igs);
}
/* - flattenpath - */
private int
-zflattenpath(register os_ptr op)
+zflattenpath(i_ctx_t *i_ctx_p)
{
return gs_flattenpath(igs);
}
/* - reversepath - */
private int
-zreversepath(register os_ptr op)
+zreversepath(i_ctx_t *i_ctx_p)
{
return gs_reversepath(igs);
}
/* - strokepath - */
private int
-zstrokepath(register os_ptr op)
+zstrokepath(i_ctx_t *i_ctx_p)
{
return gs_strokepath(igs);
}
/* - clippath - */
private int
-zclippath(register os_ptr op)
+zclippath(i_ctx_t *i_ctx_p)
{
return gs_clippath(igs);
}
/* <bool> .pathbbox <llx> <lly> <urx> <ury> */
private int
-zpathbbox(register os_ptr op)
+zpathbbox(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_rect box;
int code;
@@ -159,11 +163,12 @@ zpathbbox(register os_ptr op)
}
/* <moveproc> <lineproc> <curveproc> <closeproc> pathforall - */
-private int path_continue(P1(os_ptr));
-private int path_cleanup(P1(os_ptr));
+private int path_continue(P1(i_ctx_t *));
+private int path_cleanup(P1(i_ctx_t *));
private int
-zpathforall(register os_ptr op)
+zpathforall(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_path_enum *penum;
int code;
@@ -190,9 +195,9 @@ zpathforall(register os_ptr op)
return o_push_estack;
}
/* Continuation procedure for pathforall */
-private void pf_push(P3(gs_point *, int, os_ptr));
+private void pf_push(P3(i_ctx_t *, gs_point *, int));
private int
-path_continue(register os_ptr op)
+path_continue(i_ctx_t *i_ctx_p)
{
gs_path_enum *penum = r_ptr(esp, gs_path_enum);
gs_point ppts[3];
@@ -205,21 +210,21 @@ path_continue(register os_ptr op)
switch (code) {
case 0: /* all done */
esp -= 6;
- path_cleanup(op);
+ path_cleanup(i_ctx_p);
return o_pop_estack;
default: /* error */
return code;
case gs_pe_moveto:
esp[2] = esp[-4]; /* moveto proc */
- pf_push(ppts, 1, op);
+ pf_push(i_ctx_p, ppts, 1);
break;
case gs_pe_lineto:
esp[2] = esp[-3]; /* lineto proc */
- pf_push(ppts, 1, op);
+ pf_push(i_ctx_p, ppts, 1);
break;
case gs_pe_curveto:
esp[2] = esp[-2]; /* curveto proc */
- pf_push(ppts, 3, op);
+ pf_push(i_ctx_p, ppts, 3);
break;
case gs_pe_closepath:
esp[2] = esp[-1]; /* closepath proc */
@@ -231,8 +236,10 @@ path_continue(register os_ptr op)
}
/* Internal procedure to push one or more points */
private void
-pf_push(gs_point * ppts, int n, os_ptr op)
+pf_push(i_ctx_t *i_ctx_p, gs_point * ppts, int n)
{
+ os_ptr op = osp;
+
while (n--) {
op += 2;
make_real(op - 1, ppts->x);
@@ -243,7 +250,7 @@ pf_push(gs_point * ppts, int n, os_ptr op)
}
/* Clean up after a pathforall */
private int
-path_cleanup(os_ptr op)
+path_cleanup(i_ctx_t *i_ctx_p)
{
gs_path_enum *penum = r_ptr(esp + 6, gs_path_enum);
@@ -266,7 +273,7 @@ const op_def zpath1_op_defs[] =
{"4pathforall", zpathforall},
{"0reversepath", zreversepath},
{"0strokepath", zstrokepath},
- {"0.pathbbox", zpathbbox},
+ {"1.pathbbox", zpathbbox},
/* Internal operators */
{"0%path_continue", path_continue},
op_def_end(0)
diff --git a/gs/src/zpcolor.c b/gs/src/zpcolor.c
index 87e738565..a382f4ba1 100644
--- a/gs/src/zpcolor.c
+++ b/gs/src/zpcolor.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,50 +32,55 @@
#include "gxpcolor.h"
#include "estack.h"
#include "ialloc.h"
+#include "icremap.h"
#include "istruct.h"
#include "idict.h"
#include "idparam.h"
#include "igstate.h"
+#include "ipcolor.h"
#include "store.h"
/* Imported from gspcolor.c */
extern const gs_color_space_type gs_color_space_type_Pattern;
-/* Imported from zcolor2.c */
-extern gs_memory_type_ptr_t zcolor2_st_pattern_instance_p;
-
/* Forward references */
private int zPaintProc(P2(const gs_client_color *, gs_state *));
-private int pattern_paint_prepare(P1(os_ptr));
-private int pattern_paint_finish(P1(os_ptr));
-
-/*
- * Define the structure for remembering the pattern dictionary.
- * This is the "client data" in the template.
- * See zgstate.c (int_gstate) or zfont2.c (font_data) for information
- * as to why we define this as a structure rather than a ref array.
- */
-typedef struct int_pattern_s {
- ref dict;
-} int_pattern;
+private int pattern_paint_prepare(P1(i_ctx_t *));
+private int pattern_paint_finish(P1(i_ctx_t *));
-gs_private_st_ref_struct(st_int_pattern, int_pattern, "int_pattern");
+/* GC descriptors */
+private_st_int_pattern();
-/* Initialize the Pattern cache and the Pattern instance type. */
-private void
-zpcolor_init(void)
+/* Initialize the Pattern cache. */
+private int
+zpcolor_init(i_ctx_t *i_ctx_p)
{
gstate_set_pattern_cache(igs,
gx_pattern_alloc_cache(imemory_system,
gx_pat_cache_default_tiles(),
gx_pat_cache_default_bits()));
- zcolor2_st_pattern_instance_p = &st_pattern_instance;
+ return 0;
+}
+
+/* Create an interpreter pattern structure. */
+int
+int_pattern_alloc(int_pattern **ppdata, const ref *op)
+{
+ int_pattern *pdata =
+ ialloc_struct(int_pattern, &st_int_pattern, "int_pattern");
+
+ if (pdata == 0)
+ return_error(e_VMerror);
+ pdata->dict = *op;
+ *ppdata = pdata;
+ return 0;
}
/* <pattern> <matrix> .buildpattern1 <pattern> <instance> */
private int
-zbuildpattern1(os_ptr op)
+zbuildpattern1(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int code;
gs_matrix mat;
@@ -89,7 +94,7 @@ zbuildpattern1(os_ptr op)
check_dict_read(*op1);
gs_pattern1_init(&template);
if ((code = read_matrix(op, &mat)) < 0 ||
- (code = dict_uid_param(op1, &template.uid, 1, imemory)) != 1 ||
+ (code = dict_uid_param(op1, &template.uid, 1, imemory, i_ctx_p)) != 1 ||
(code = dict_int_param(op1, "PaintType", 1, 2, 0, &template.PaintType)) < 0 ||
(code = dict_int_param(op1, "TilingType", 1, 3, 0, &template.TilingType)) < 0 ||
(code = dict_float_array_param(op1, "BBox", 4, BBox, NULL)) != 4 ||
@@ -104,11 +109,10 @@ zbuildpattern1(os_ptr op)
template.BBox.q.x = BBox[2];
template.BBox.q.y = BBox[3];
template.PaintProc = zPaintProc;
- pdata = ialloc_struct(int_pattern, &st_int_pattern, "int_pattern");
- if (pdata == 0)
- return_error(e_VMerror);
+ code = int_pattern_alloc(&pdata, op1);
+ if (code < 0)
+ return code;
template.client_data = pdata;
- pdata->dict = *op1;
code = gs_makepattern(&cc_instance, &template, &mat, igs, imemory);
if (code < 0) {
ifree_object(pdata, "int_pattern");
@@ -122,8 +126,9 @@ zbuildpattern1(os_ptr op)
/* In the case of uncolored patterns, the current color space is */
/* the base space for the pattern space. */
private int
-zsetpatternspace(register os_ptr op)
+zsetpatternspace(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_color_space cs;
uint edepth = ref_stack_count(&e_stack);
int code;
@@ -174,27 +179,24 @@ const op_def zpcolor_l2_op_defs[] =
/* ------ Internal procedures ------ */
-/* Set up the pattern pointer in a client color for setcolor */
-/* with a Pattern space. */
-/****** ? WHAT WAS THIS FOR ? ******/
-
/* Render the pattern by calling the PaintProc. */
-private int pattern_paint_cleanup(P1(os_ptr));
+private int pattern_paint_cleanup(P1(i_ctx_t *));
private int
zPaintProc(const gs_client_color * pcc, gs_state * pgs)
{
/* Just schedule a call on the real PaintProc. */
- check_estack(2);
- esp++;
- push_op_estack(pattern_paint_prepare);
- return e_InsertProc;
+ r_ptr(&gs_int_gstate(pgs)->remap_color_info,
+ int_remap_color_info_t)->proc =
+ pattern_paint_prepare;
+ return_error(e_RemapColor);
}
/* Prepare to run the PaintProc. */
private int
-pattern_paint_prepare(os_ptr op)
+pattern_paint_prepare(i_ctx_t *i_ctx_p)
{
gs_state *pgs = igs;
- gs_pattern_instance *pinst = gs_currentcolor(pgs)->pattern;
+ gs_pattern1_instance_t *pinst =
+ (gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
ref *pdict = &((int_pattern *) pinst->template.client_data)->dict;
gx_device_pattern_accum *pdev;
int code;
@@ -231,7 +233,7 @@ pattern_paint_prepare(os_ptr op)
}
/* Save the rendered pattern. */
private int
-pattern_paint_finish(os_ptr op)
+pattern_paint_finish(i_ctx_t *i_ctx_p)
{
gx_device_pattern_accum *pdev = r_ptr(esp, gx_device_pattern_accum);
gx_color_tile *ctile;
@@ -241,13 +243,13 @@ pattern_paint_finish(os_ptr op)
if (code < 0)
return code;
esp -= 2;
- pattern_paint_cleanup(op);
+ pattern_paint_cleanup(i_ctx_p);
return o_pop_estack;
}
/* Clean up after rendering a pattern. Note that iff the rendering */
/* succeeded, closing the accumulator won't free the bits. */
private int
-pattern_paint_cleanup(os_ptr op)
+pattern_paint_cleanup(i_ctx_t *i_ctx_p)
{
gx_device_pattern_accum *const pdev =
r_ptr(esp + 2, gx_device_pattern_accum);
diff --git a/gs/src/zrelbit.c b/gs/src/zrelbit.c
index 53c0d0abb..bea34275b 100644
--- a/gs/src/zrelbit.c
+++ b/gs/src/zrelbit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -41,8 +41,9 @@ private int obj_le(P2(os_ptr, os_ptr));
/* <obj1> <obj2> eq <bool> */
private int
-zeq(register os_ptr op)
+zeq(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
EQ_CHECK_READ(op - 1, check_op(2));
EQ_CHECK_READ(op, DO_NOTHING);
make_bool(op - 1, (obj_eq(op - 1, op) ? 1 : 0));
@@ -52,20 +53,21 @@ zeq(register os_ptr op)
/* <obj1> <obj2> ne <bool> */
private int
-zne(register os_ptr op)
+zne(i_ctx_t *i_ctx_p)
{ /* We'll just be lazy and use eq. */
- int code = zeq(op);
+ int code = zeq(i_ctx_p);
if (!code)
- op[-1].value.boolval ^= 1;
+ osp->value.boolval ^= 1;
return code;
}
/* <num1> <num2> ge <bool> */
/* <str1> <str2> ge <bool> */
private int
-zge(register os_ptr op)
+zge(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op, op - 1);
if (code < 0)
@@ -78,8 +80,9 @@ zge(register os_ptr op)
/* <num1> <num2> gt <bool> */
/* <str1> <str2> gt <bool> */
private int
-zgt(register os_ptr op)
+zgt(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op - 1, op);
if (code < 0)
@@ -92,8 +95,9 @@ zgt(register os_ptr op)
/* <num1> <num2> le <bool> */
/* <str1> <str2> le <bool> */
private int
-zle(register os_ptr op)
+zle(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op - 1, op);
if (code < 0)
@@ -106,8 +110,9 @@ zle(register os_ptr op)
/* <num1> <num2> lt <bool> */
/* <str1> <str2> lt <bool> */
private int
-zlt(register os_ptr op)
+zlt(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op, op - 1);
if (code < 0)
@@ -120,8 +125,9 @@ zlt(register os_ptr op)
/* <num1> <num2> .max <num> */
/* <str1> <str2> .max <str> */
private int
-zmax(register os_ptr op)
+zmax(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op - 1, op);
if (code < 0)
@@ -136,8 +142,9 @@ zmax(register os_ptr op)
/* <num1> <num2> .min <num> */
/* <str1> <str2> .min <str> */
private int
-zmin(register os_ptr op)
+zmin(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = obj_le(op - 1, op);
if (code < 0)
@@ -152,8 +159,10 @@ zmin(register os_ptr op)
/* <bool1> <bool2> and <bool> */
/* <int1> <int2> and <int> */
private int
-zand(register os_ptr op)
+zand(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_boolean:
check_type(op[-1], t_boolean);
@@ -173,8 +182,10 @@ zand(register os_ptr op)
/* <bool> not <bool> */
/* <int> not <int> */
private int
-znot(register os_ptr op)
+znot(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_boolean:
op->value.boolval = !op->value.boolval;
@@ -191,8 +202,10 @@ znot(register os_ptr op)
/* <bool1> <bool2> or <bool> */
/* <int1> <int2> or <int> */
private int
-zor(register os_ptr op)
+zor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_boolean:
check_type(op[-1], t_boolean);
@@ -212,8 +225,10 @@ zor(register os_ptr op)
/* <bool1> <bool2> xor <bool> */
/* <int1> <int2> xor <int> */
private int
-zxor(register os_ptr op)
+zxor(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_boolean:
check_type(op[-1], t_boolean);
@@ -232,8 +247,9 @@ zxor(register os_ptr op)
/* <int> <shift> bitshift <int> */
private int
-zbitshift(register os_ptr op)
+zbitshift(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int shift;
check_type(*op, t_integer);
@@ -254,8 +270,10 @@ zbitshift(register os_ptr op)
/* <obj1> <obj2> .identeq <bool> */
private int
-zidenteq(register os_ptr op)
+zidenteq(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
EQ_CHECK_READ(op - 1, check_op(2));
EQ_CHECK_READ(op, DO_NOTHING);
make_bool(op - 1, (obj_ident_eq(op - 1, op) ? 1 : 0));
@@ -266,12 +284,13 @@ zidenteq(register os_ptr op)
/* <obj1> <obj2> .identne <bool> */
private int
-zidentne(register os_ptr op)
-{ /* We'll just be lazy and use .identeq. */
- int code = zidenteq(op);
+zidentne(i_ctx_t *i_ctx_p)
+{
+ /* We'll just be lazy and use .identeq. */
+ int code = zidenteq(i_ctx_p);
if (!code)
- op[-1].value.boolval ^= 1;
+ osp->value.boolval ^= 1;
return code;
}
diff --git a/gs/src/zrop.c b/gs/src/zrop.c
index abffe84f3..2a3d0af3e 100644
--- a/gs/src/zrop.c
+++ b/gs/src/zrop.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -31,8 +31,9 @@
/* <int8> .setrasterop - */
private int
-zsetrasterop(register os_ptr op)
+zsetrasterop(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int param;
int code = int_param(op, 0xff, &param);
@@ -45,8 +46,10 @@ zsetrasterop(register os_ptr op)
/* - .currentrasterop <int8> */
private int
-zcurrentrasterop(register os_ptr op)
+zcurrentrasterop(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, (int)gs_currentrasterop(igs));
return 0;
@@ -54,8 +57,10 @@ zcurrentrasterop(register os_ptr op)
/* <bool> .setsourcetransparent - */
private int
-zsetsourcetransparent(register os_ptr op)
+zsetsourcetransparent(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_setsourcetransparent(igs, op->value.boolval);
pop(1);
@@ -64,8 +69,10 @@ zsetsourcetransparent(register os_ptr op)
/* - .currentsourcetransparent <bool> */
private int
-zcurrentsourcetransparent(register os_ptr op)
+zcurrentsourcetransparent(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currentsourcetransparent(igs));
return 0;
@@ -73,8 +80,10 @@ zcurrentsourcetransparent(register os_ptr op)
/* <bool> .settexturetransparent - */
private int
-zsettexturetransparent(register os_ptr op)
+zsettexturetransparent(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
gs_settexturetransparent(igs, op->value.boolval);
pop(1);
@@ -83,8 +92,10 @@ zsettexturetransparent(register os_ptr op)
/* - .currenttexturetransparent <bool> */
private int
-zcurrenttexturetransparent(register os_ptr op)
+zcurrenttexturetransparent(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, gs_currenttexturetransparent(igs));
return 0;
diff --git a/gs/src/zshade.c b/gs/src/zshade.c
index b02611fce..b529e8fc5 100644
--- a/gs/src/zshade.c
+++ b/gs/src/zshade.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -25,6 +25,7 @@
#include "gscspace.h"
#include "gscolor2.h" /* requires gscspace.h */
#include "gsfunc3.h"
+#include "gsptype2.h"
#include "gsstruct.h" /* must precede gsshade.h */
#include "gsshade.h"
#include "gsuid.h"
@@ -35,6 +36,7 @@
#include "idparam.h"
#include "ifunc.h"
#include "igstate.h"
+#include "ipcolor.h"
#include "store.h"
/* Forward references */
@@ -44,8 +46,10 @@ private int shading_param(P2(const_os_ptr op, const gs_shading_t ** ppsh));
/* - currentsmoothness <smoothness> */
private int
-zcurrentsmoothness(register os_ptr op)
+zcurrentsmoothness(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_real(op, gs_currentsmoothness(igs));
return 0;
@@ -53,8 +57,9 @@ zcurrentsmoothness(register os_ptr op)
/* <smoothness> setsmoothness - */
private int
-zsetsmoothness(register os_ptr op)
+zsetsmoothness(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
double smoothness;
int code;
@@ -68,8 +73,9 @@ zsetsmoothness(register os_ptr op)
/* <shading> .shfill - */
private int
-zshfill(register os_ptr op)
+zshfill(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
const gs_shading_t *psh;
int code = shading_param(op, &psh);
@@ -83,26 +89,36 @@ zshfill(register os_ptr op)
/* <pattern> <matrix> <shading> .buildshadingpattern <pattern> <instance> */
private int
-zbuildshadingpattern(os_ptr op)
+zbuildshadingpattern(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op2 = op - 2;
- const gs_shading_t *psh;
gs_matrix mat;
- struct {
- gs_uid uid;
- } template; /****** WRONG ******/
+ gs_pattern2_template_t template;
+ int_pattern *pdata;
+ gs_client_color cc_instance;
int code;
check_type(*op2, t_dictionary);
check_dict_read(*op2);
-
- if ((code = shading_param(op, &psh)) < 0 ||
- (code = read_matrix(op - 1, &mat)) < 0 ||
- (code = dict_uid_param(op2, &template.uid, 1, imemory)) != 1
+ gs_pattern2_init(&template);
+ if ((code = read_matrix(op - 1, &mat)) < 0 ||
+ (code = dict_uid_param(op2, &template.uid, 1, imemory, i_ctx_p)) != 1 ||
+ (code = shading_param(op, &template.Shading)) < 0 ||
+ (code = int_pattern_alloc(&pdata, op2)) < 0
)
return_error((code < 0 ? code : e_rangecheck));
- /****** NYI ******/
- return_error(e_undefined);
+ template.client_data = pdata;
+ code = gs_make_pattern(&cc_instance,
+ (const gs_pattern_template_t *)&template,
+ &mat, igs, imemory);
+ if (code < 0) {
+ ifree_object(pdata, "int_pattern");
+ return code;
+ }
+ make_istruct(op - 1, a_readonly, cc_instance.pattern);
+ pop(1);
+ return code;
}
/* ------ Internal procedures ------ */
@@ -136,8 +152,9 @@ typedef int (*build_shading_proc_t)(P3(const ref *op,
/* Common framework for building shadings. */
private int
-build_shading(ref * op, build_shading_proc_t proc)
+build_shading(i_ctx_t *i_ctx_p, build_shading_proc_t proc)
{
+ os_ptr op = osp;
int code;
float box[4];
gs_shading_params_t params;
@@ -278,9 +295,9 @@ build_shading_1(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading1 <shading_struct> */
private int
-zbuildshading1(os_ptr op)
+zbuildshading1(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_1);
+ return build_shading(i_ctx_p, build_shading_1);
}
/* Collect parameters for an Axial or Radial shading. */
@@ -338,9 +355,9 @@ build_shading_2(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading2 <shading_struct> */
private int
-zbuildshading2(os_ptr op)
+zbuildshading2(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_2);
+ return build_shading(i_ctx_p, build_shading_2);
}
/* Build a ShadingType 3 (Radial) shading. */
@@ -363,9 +380,9 @@ build_shading_3(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading3 <shading_struct> */
private int
-zbuildshading3(os_ptr op)
+zbuildshading3(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_3);
+ return build_shading(i_ctx_p, build_shading_3);
}
/* Collect parameters for a mesh shading. */
@@ -484,9 +501,9 @@ build_shading_4(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading4 <shading_struct> */
private int
-zbuildshading4(os_ptr op)
+zbuildshading4(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_4);
+ return build_shading(i_ctx_p, build_shading_4);
}
/* Build a ShadingType 5 (Lattice-form Gouraud triangle mesh) shading. */
@@ -512,9 +529,9 @@ build_shading_5(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading5 <shading_struct> */
private int
-zbuildshading5(os_ptr op)
+zbuildshading5(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_5);
+ return build_shading(i_ctx_p, build_shading_5);
}
/* Build a ShadingType 6 (Coons patch mesh) shading. */
@@ -540,9 +557,9 @@ build_shading_6(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading6 <shading_struct> */
private int
-zbuildshading6(os_ptr op)
+zbuildshading6(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_6);
+ return build_shading(i_ctx_p, build_shading_6);
}
/* Build a ShadingType 7 (Tensor product patch mesh) shading. */
@@ -568,9 +585,9 @@ build_shading_7(const ref * op, const gs_shading_params_t * pcommon,
}
/* <dict> .buildshading7 <shading_struct> */
private int
-zbuildshading7(os_ptr op)
+zbuildshading7(i_ctx_t *i_ctx_p)
{
- return build_shading(op, build_shading_7);
+ return build_shading(i_ctx_p, build_shading_7);
}
/* ------ Initialization procedure ------ */
diff --git a/gs/src/zstack.c b/gs/src/zstack.c
index 644a9e610..587c63523 100644
--- a/gs/src/zstack.c
+++ b/gs/src/zstack.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1991, 1992, 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1991, 1992, 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -27,8 +27,10 @@
/* <obj> pop - */
int
-zpop(register os_ptr op)
+zpop(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
pop(1);
return 0;
@@ -36,8 +38,9 @@ zpop(register os_ptr op)
/* <obj1> <obj2> exch <obj2> <obj1> */
int
-zexch(register os_ptr op)
+zexch(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref next;
check_op(2);
@@ -49,8 +52,10 @@ zexch(register os_ptr op)
/* <obj> dup <obj> <obj> */
int
-zdup(register os_ptr op)
+zdup(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
push(1);
ref_assign_inline(op, op - 1);
@@ -59,8 +64,9 @@ zdup(register os_ptr op)
/* <obj_n> ... <obj_0> <n> index <obj_n> ... <obj_0> <obj_n> */
int
-zindex(register os_ptr op)
+zindex(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
register os_ptr opn;
check_type(*op, t_integer);
@@ -84,8 +90,9 @@ zindex(register os_ptr op)
/* <obj_n-1> ... <obj_0> <n> <i> roll */
/* <obj_(i-1)_mod_ n> ... <obj_0> <obj_n-1> ... <obj_i_mod_n> */
int
-zroll(register os_ptr op)
+zroll(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
int count, mod;
register os_ptr from, to;
@@ -221,7 +228,7 @@ zroll(register os_ptr op)
/* The function name is changed, because the IRIS library has */
/* a function called zclear. */
private int
-zclear_stack(os_ptr op)
+zclear_stack(i_ctx_t *i_ctx_p)
{
ref_stack_clear(&o_stack);
return 0;
@@ -229,8 +236,10 @@ zclear_stack(os_ptr op)
/* |- <obj_n-1> ... <obj_0> count <obj_n-1> ... <obj_0> <n> */
private int
-zcount(register os_ptr op)
+zcount(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_int(op, ref_stack_count(&o_stack) - 1);
return 0;
@@ -238,8 +247,10 @@ zcount(register os_ptr op)
/* - mark <mark> */
private int
-zmark(register os_ptr op)
+zmark(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_mark(op);
return 0;
@@ -247,7 +258,7 @@ zmark(register os_ptr op)
/* <mark> ... cleartomark */
int
-zcleartomark(register os_ptr op)
+zcleartomark(i_ctx_t *i_ctx_p)
{
uint count = ref_stack_counttomark(&o_stack);
@@ -260,8 +271,9 @@ zcleartomark(register os_ptr op)
/* <mark> <obj_n-1> ... <obj_0> counttomark */
/* <mark> <obj_n-1> ... <obj_0> <n> */
private int
-zcounttomark(os_ptr op)
+zcounttomark(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint count = ref_stack_counttomark(&o_stack);
if (count == 0)
diff --git a/gs/src/zstring.c b/gs/src/zstring.c
index e781ef6fd..fc858f26a 100644
--- a/gs/src/zstring.c
+++ b/gs/src/zstring.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,10 +30,29 @@
/* The generic operators (copy, get, put, getinterval, putinterval, */
/* length, and forall) are implemented in zgeneric.c. */
+/* <int> .bytestring <bytestring> */
+private int
+zbytestring(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ byte *sbody;
+ uint size;
+
+ check_int_leu(*op, max_int);
+ size = (uint)op->value.intval;
+ sbody = ialloc_bytes(size, ".bytestring");
+ if (sbody == 0)
+ return_error(e_VMerror);
+ make_astruct(op, a_all | icurrent_space, sbody);
+ memset(sbody, 0, size);
+ return 0;
+}
+
/* <int> string <string> */
int
-zstring(register os_ptr op)
+zstring(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
byte *sbody;
uint size;
@@ -49,8 +68,10 @@ zstring(register os_ptr op)
/* <name> .namestring <string> */
private int
-znamestring(register os_ptr op)
+znamestring(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_name);
name_string_ref(op, op);
return 0;
@@ -59,8 +80,9 @@ znamestring(register os_ptr op)
/* <string> <pattern> anchorsearch <post> <match> -true- */
/* <string> <pattern> anchorsearch <string> -false- */
private int
-zanchorsearch(register os_ptr op)
+zanchorsearch(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
uint size = r_size(op);
@@ -83,8 +105,9 @@ zanchorsearch(register os_ptr op)
/* <string> <pattern> search <post> <match> <pre> -true- */
/* <string> <pattern> search <string> -false- */
private int
-zsearch(register os_ptr op)
+zsearch(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
uint size = r_size(op);
uint count;
@@ -128,8 +151,9 @@ found:
/* <obj> <pattern> .stringmatch <bool> */
private int
-zstringmatch(register os_ptr op)
+zstringmatch(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
os_ptr op1 = op - 1;
bool result;
@@ -157,6 +181,7 @@ cmp:
const op_def zstring_op_defs[] =
{
+ {"1.bytestring", zbytestring},
{"2anchorsearch", zanchorsearch},
{"1.namestring", znamestring},
{"2search", zsearch},
diff --git a/gs/src/zsysvm.c b/gs/src/zsysvm.c
index e906e413d..e7bca7731 100644
--- a/gs/src/zsysvm.c
+++ b/gs/src/zsysvm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1995, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -34,105 +34,107 @@
/* Execute an operator with a specific VM selected as current VM. */
private int
-specific_vm_op(os_ptr op, int (*opproc)(P1(os_ptr)), uint space)
+specific_vm_op(i_ctx_t *i_ctx_p, op_proc_t opproc, uint space)
{
uint save_space = icurrent_space;
int code;
ialloc_set_space(idmemory, space);
- code = (*opproc)(op);
+ code = opproc(i_ctx_p);
ialloc_set_space(idmemory, save_space);
return code;
}
/* <int> .globalvmarray <array> */
private int
-zglobalvmarray(os_ptr op)
+zglobalvmarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zarray, avm_global);
+ return specific_vm_op(i_ctx_p, zarray, avm_global);
}
/* <int> .globalvmdict <dict> */
private int
-zglobalvmdict(os_ptr op)
+zglobalvmdict(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zdict, avm_global);
+ return specific_vm_op(i_ctx_p, zdict, avm_global);
}
/* <obj_0> ... <obj_n-1> <n> .globalvmpackedarray <packedarray> */
private int
-zglobalvmpackedarray(os_ptr op)
+zglobalvmpackedarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zpackedarray, avm_global);
+ return specific_vm_op(i_ctx_p, zpackedarray, avm_global);
}
/* <int> .globalvmstring <string> */
private int
-zglobalvmstring(os_ptr op)
+zglobalvmstring(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zstring, avm_global);
+ return specific_vm_op(i_ctx_p, zstring, avm_global);
}
/* <int> .localvmarray <array> */
private int
-zlocalvmarray(os_ptr op)
+zlocalvmarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zarray, avm_local);
+ return specific_vm_op(i_ctx_p, zarray, avm_local);
}
/* <int> .localvmdict <dict> */
private int
-zlocalvmdict(os_ptr op)
+zlocalvmdict(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zdict, avm_local);
+ return specific_vm_op(i_ctx_p, zdict, avm_local);
}
/* <obj_0> ... <obj_n-1> <n> .localvmpackedarray <packedarray> */
private int
-zlocalvmpackedarray(os_ptr op)
+zlocalvmpackedarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zpackedarray, avm_local);
+ return specific_vm_op(i_ctx_p, zpackedarray, avm_local);
}
/* <int> .localvmstring <string> */
private int
-zlocalvmstring(os_ptr op)
+zlocalvmstring(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zstring, avm_local);
+ return specific_vm_op(i_ctx_p, zstring, avm_local);
}
/* <int> .systemvmarray <array> */
private int
-zsystemvmarray(os_ptr op)
+zsystemvmarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zarray, avm_system);
+ return specific_vm_op(i_ctx_p, zarray, avm_system);
}
/* <int> .systemvmdict <dict> */
private int
-zsystemvmdict(os_ptr op)
+zsystemvmdict(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zdict, avm_system);
+ return specific_vm_op(i_ctx_p, zdict, avm_system);
}
/* <obj_0> ... <obj_n-1> <n> .systemvmpackedarray <packedarray> */
private int
-zsystemvmpackedarray(os_ptr op)
+zsystemvmpackedarray(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zpackedarray, avm_system);
+ return specific_vm_op(i_ctx_p, zpackedarray, avm_system);
}
/* <int> .systemvmstring <string> */
private int
-zsystemvmstring(os_ptr op)
+zsystemvmstring(i_ctx_t *i_ctx_p)
{
- return specific_vm_op(op, zstring, avm_system);
+ return specific_vm_op(i_ctx_p, zstring, avm_system);
}
/* <any> .systemvmcheck <bool> */
private int
-zsystemvmcheck(register os_ptr op)
+zsystemvmcheck(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
make_bool(op, (r_space(op) == avm_system ? true : false));
return 0;
}
diff --git a/gs/src/ztoken.c b/gs/src/ztoken.c
index b1f657df6..4f29023a7 100644
--- a/gs/src/ztoken.c
+++ b/gs/src/ztoken.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1994, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -32,11 +32,13 @@
/* <file> token <obj> -true- */
/* <string> token <post> <obj> -true- */
/* <string|file> token -false- */
-private int ztoken_continue(P1(os_ptr));
-private int token_continue(P4(os_ptr, stream *, scanner_state *, bool));
+private int ztoken_continue(P1(i_ctx_t *));
+private int token_continue(P4(i_ctx_t *, stream *, scanner_state *, bool));
int
-ztoken(register os_ptr op)
+ztoken(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
default:
return_op_typecheck(op);
@@ -47,11 +49,11 @@ ztoken(register os_ptr op)
check_read_file(s, op);
check_ostack(1);
scanner_state_init(&state, false);
- return token_continue(op, s, &state, true);
+ return token_continue(i_ctx_p, s, &state, true);
}
case t_string: {
ref token;
- int code = scan_string_token(op, &token);
+ int code = scan_string_token(i_ctx_p, op, &token);
switch (code) {
case scan_EOF: /* no tokens */
@@ -71,8 +73,9 @@ ztoken(register os_ptr op)
/* Continue reading a token after an interrupt or callout. */
/* *op is the scanner state; op[-1] is the file. */
private int
-ztoken_continue(os_ptr op)
+ztoken_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
scanner_state *pstate;
@@ -80,12 +83,14 @@ ztoken_continue(os_ptr op)
check_stype(*op, st_scanner_state);
pstate = r_ptr(op, scanner_state);
pop(1);
- return token_continue(osp, s, pstate, false);
+ return token_continue(i_ctx_p, s, pstate, false);
}
/* Common code for token reading. */
private int
-token_continue(os_ptr op, stream * s, scanner_state * pstate, bool save)
+token_continue(i_ctx_t *i_ctx_p, stream * s, scanner_state * pstate,
+ bool save)
{
+ os_ptr op = osp;
int code;
ref token;
@@ -97,7 +102,7 @@ token_continue(os_ptr op, stream * s, scanner_state * pstate, bool save)
ref_assign(&fref, op);
again:
pop(1);
- code = scan_token(s, &token, pstate);
+ code = scan_token(i_ctx_p, s, &token, pstate);
op = osp;
switch (code) {
default: /* error */
@@ -119,7 +124,7 @@ again:
case scan_Refill: /* need more data */
push(1);
ref_assign(op, &fref);
- code = scan_handle_refill(op, pstate, save, false,
+ code = scan_handle_refill(i_ctx_p, op, pstate, save, false,
ztoken_continue);
switch (code) {
case 0: /* state is not copied to the heap */
@@ -139,26 +144,28 @@ again:
/* Read a token and do what the interpreter would do with it. */
/* This is different from token + exec because literal procedures */
/* are not executed (although binary object sequences ARE executed). */
-int ztokenexec_continue(P1(os_ptr)); /* export for interpreter */
-private int tokenexec_continue(P4(os_ptr, stream *, scanner_state *, bool));
+int ztokenexec_continue(P1(i_ctx_t *)); /* export for interpreter */
+private int tokenexec_continue(P4(i_ctx_t *, stream *, scanner_state *, bool));
int
-ztokenexec(register os_ptr op)
+ztokenexec(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
scanner_state state;
check_read_file(s, op);
check_estack(1);
scanner_state_init(&state, false);
- return tokenexec_continue(op, s, &state, true);
+ return tokenexec_continue(i_ctx_p, s, &state, true);
}
/* Continue reading a token for execution after an interrupt or callout. */
/* *op is the scanner state; op[-1] is the file. */
/* We export this because this is how the interpreter handles a */
/* scan_Refill for an executable file. */
int
-ztokenexec_continue(os_ptr op)
+ztokenexec_continue(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
stream *s;
scanner_state *pstate;
@@ -166,12 +173,14 @@ ztokenexec_continue(os_ptr op)
check_stype(*op, st_scanner_state);
pstate = r_ptr(op, scanner_state);
pop(1);
- return tokenexec_continue(osp, s, pstate, false);
+ return tokenexec_continue(i_ctx_p, s, pstate, false);
}
/* Common code for token reading + execution. */
private int
-tokenexec_continue(os_ptr op, stream * s, scanner_state * pstate, bool save)
+tokenexec_continue(i_ctx_t *i_ctx_p, stream * s, scanner_state * pstate,
+ bool save)
{
+ os_ptr op = osp;
int code;
/* Note that scan_token may change osp! */
@@ -182,7 +191,7 @@ tokenexec_continue(os_ptr op, stream * s, scanner_state * pstate, bool save)
ref_assign(&fref, op);
pop(1);
again:
- code = scan_token(s, (ref *) (esp + 1), pstate);
+ code = scan_token(i_ctx_p, s, (ref *) (esp + 1), pstate);
op = osp;
switch (code) {
case 0:
@@ -201,7 +210,7 @@ again:
code = 0;
break;
case scan_Refill: /* need more data */
- code = scan_handle_refill(&fref, pstate, save, true,
+ code = scan_handle_refill(i_ctx_p, &fref, pstate, save, true,
ztokenexec_continue);
switch (code) {
case 0: /* state is not copied to the heap */
diff --git a/gs/src/ztrap.c b/gs/src/ztrap.c
index b2efb9932..d8df57572 100644
--- a/gs/src/ztrap.c
+++ b/gs/src/ztrap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -30,8 +30,9 @@ gs_trap_params_t i_trap_params;
/* <dict> .settrapparams - */
private int
-zsettrapparams(os_ptr op)
+zsettrapparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
dict_param_list list;
int code;
@@ -49,7 +50,7 @@ zsettrapparams(os_ptr op)
/* - settrapzone - */
private int
-zsettrapzone(os_ptr op)
+zsettrapzone(i_ctx_t *i_ctx_p)
{
/****** NYI ******/
return_error(e_undefined);
diff --git a/gs/src/ztype.c b/gs/src/ztype.c
index ee2ffc63f..983faf926 100644
--- a/gs/src/ztype.c
+++ b/gs/src/ztype.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -36,7 +36,7 @@
#include "store.h"
/* Forward references */
-private int access_check(P3(os_ptr, int, bool));
+private int access_check(P3(i_ctx_t *, int, bool));
private int convert_to_string(P2(os_ptr, os_ptr));
/*
@@ -60,34 +60,11 @@ private const double max_int_real = (ALT_MAX_LONG * 1.0 + 1);
#define ACCESS_REF(opp)\
(r_has_type(opp, t_dictionary) ? dict_access_ref(opp) : opp)
-/* Initialize the table of type names. */
-private void
-ztype_init(void)
-{
- static const char *const tnames[] = { type_name_strings };
- ref type_names;
- int i;
-
- ialloc_ref_array(&type_names, a_readonly, t_next_index,
- "type names");
- for (i = 0; i < t_next_index; i++) {
- if (i >= countof(tnames) || tnames[i] == 0)
- make_null(&type_names.value.refs[i]);
- else {
- name_enter_string(tnames[i], &type_names.value.refs[i]);
- r_set_attrs(&type_names.value.refs[i], a_executable);
- }
- }
- if (dict_put_string(systemdict, "typenames", &type_names) < 0) {
- lprintf("Entering typenames in systemdict failed.\n");
- gs_exit(1);
- }
-}
-
/* <obj> <typenames> .type <name> */
private int
-ztype(register os_ptr op)
+ztype(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref tnref;
int code = array_get(op, (long)r_btype(op - 1), &tnref);
@@ -114,10 +91,37 @@ ztype(register os_ptr op)
return 0;
}
+/* - .typenames <name1|null> ... <nameN|null> */
+private int
+ztypenames(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ static const char *const tnames[] = { REF_TYPE_NAME_STRINGS };
+ int i;
+
+ check_ostack(t_next_index);
+ for (i = 0; i < t_next_index; i++) {
+ ref *const rtnp = op + 1 + i;
+
+ if (i >= countof(tnames) || tnames[i] == 0)
+ make_null(rtnp);
+ else {
+ int code = name_enter_string(tnames[i], rtnp);
+
+ if (code < 0)
+ return code;
+ r_set_attrs(rtnp, a_executable);
+ }
+ }
+ osp += t_next_index;
+ return 0;
+}
+
/* <obj> cvlit <obj> */
private int
-zcvlit(register os_ptr op)
+zcvlit(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *aop;
check_op(1);
@@ -128,8 +132,9 @@ zcvlit(register os_ptr op)
/* <obj> cvx <obj> */
int
-zcvx(register os_ptr op)
+zcvx(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref *aop;
uint opidx;
@@ -140,7 +145,7 @@ zcvx(register os_ptr op)
*/
if (r_has_type(op, t_operator) &&
((opidx = op_index(op)) == 0 ||
- op_def_is_internal(op_def_table[opidx]))
+ op_def_is_internal(op_index_def(opidx)))
)
return_error(e_rangecheck);
aop = ACCESS_REF(op);
@@ -150,8 +155,10 @@ zcvx(register os_ptr op)
/* <obj> xcheck <bool> */
private int
-zxcheck(register os_ptr op)
+zxcheck(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
make_bool(op, (r_has_attr(ACCESS_REF(op), a_executable) ? 1 : 0));
return 0;
@@ -159,18 +166,22 @@ zxcheck(register os_ptr op)
/* <obj:array|packedarray|file|string> executeonly <obj> */
private int
-zexecuteonly(register os_ptr op)
+zexecuteonly(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
if (r_has_type(op, t_dictionary))
return_error(e_typecheck);
- return access_check(op, a_execute, true);
+ return access_check(i_ctx_p, a_execute, true);
}
/* <obj:array|packedarray|dict|file|string> noaccess <obj> */
private int
-znoaccess(register os_ptr op)
+znoaccess(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
if (r_has_type(op, t_dictionary)) {
/*
@@ -184,21 +195,22 @@ znoaccess(register os_ptr op)
)
return_error(e_invalidaccess);
}
- return access_check(op, 0, true);
+ return access_check(i_ctx_p, 0, true);
}
/* <obj:array|packedarray|dict|file|string> readonly <obj> */
int
-zreadonly(register os_ptr op)
+zreadonly(i_ctx_t *i_ctx_p)
{
- return access_check(op, a_readonly, true);
+ return access_check(i_ctx_p, a_readonly, true);
}
/* <array|packedarray|dict|file|string> rcheck <bool> */
private int
-zrcheck(register os_ptr op)
+zrcheck(i_ctx_t *i_ctx_p)
{
- int code = access_check(op, a_read, false);
+ os_ptr op = osp;
+ int code = access_check(i_ctx_p, a_read, false);
if (code >= 0)
make_bool(op, code), code = 0;
@@ -207,9 +219,10 @@ zrcheck(register os_ptr op)
/* <array|packedarray|dict|file|string> wcheck <bool> */
private int
-zwcheck(register os_ptr op)
+zwcheck(i_ctx_t *i_ctx_p)
{
- int code = access_check(op, a_write, false);
+ os_ptr op = osp;
+ int code = access_check(i_ctx_p, a_write, false);
if (code >= 0)
make_bool(op, code), code = 0;
@@ -219,8 +232,9 @@ zwcheck(register os_ptr op)
/* <num> cvi <int> */
/* <string> cvi <int> */
private int
-zcvi(register os_ptr op)
+zcvi(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
float fval;
switch (r_type(op)) {
@@ -237,7 +251,7 @@ zcvi(register os_ptr op)
int code;
ref_assign(&str, op);
- code = scan_string_token(&str, &token);
+ code = scan_string_token(i_ctx_p, &str, &token);
switch (code) {
case scan_EOF: /* no tokens */
case scan_BOS: /* not allowed */
@@ -266,8 +280,10 @@ zcvi(register os_ptr op)
/* <string> cvn <name> */
private int
-zcvn(register os_ptr op)
+zcvn(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_read_type(*op, t_string);
return name_from_string(op, op);
}
@@ -275,8 +291,10 @@ zcvn(register os_ptr op)
/* <num> cvr <real> */
/* <string> cvr <real> */
private int
-zcvr(register os_ptr op)
+zcvr(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
switch (r_type(op)) {
case t_integer:
make_real(op, op->value.intval);
@@ -290,7 +308,7 @@ zcvr(register os_ptr op)
int code;
ref_assign(&str, op);
- code = scan_string_token(&str, &token);
+ code = scan_string_token(i_ctx_p, &str, &token);
switch (code) {
case scan_EOF: /* no tokens */
case scan_BOS: /* not allowed */
@@ -315,8 +333,9 @@ zcvr(register os_ptr op)
/* <num> <radix_int> <string> cvrs <substring> */
private int
-zcvrs(register os_ptr op)
+zcvrs(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int radix;
check_type(op[-1], t_integer);
@@ -379,8 +398,9 @@ zcvrs(register os_ptr op)
/* <any> <string> cvs <substring> */
private int
-zcvs(register os_ptr op)
+zcvs(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
check_op(2);
@@ -407,9 +427,10 @@ const op_def ztype_op_defs[] =
{"1rcheck", zrcheck},
{"1readonly", zreadonly},
{"2.type", ztype},
+ {"0.typenames", ztypenames},
{"1wcheck", zwcheck},
{"1xcheck", zxcheck},
- op_def_end(ztype_init)
+ op_def_end(0)
};
/* ------ Internal routines ------ */
@@ -421,10 +442,11 @@ const op_def ztype_op_defs[] =
/* Return an error code if the object is not of appropriate type, */
/* or if the object did not have the access already when modify=1. */
private int
-access_check(os_ptr op,
+access_check(i_ctx_t *i_ctx_p,
int access, /* mask for attrs */
bool modify) /* if true, reduce access */
{
+ os_ptr op = osp;
ref *aop;
switch (r_type(op)) {
diff --git a/gs/src/zupath.c b/gs/src/zupath.c
index 8ba593cbf..0a58f0e31 100644
--- a/gs/src/zupath.c
+++ b/gs/src/zupath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1990, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -43,57 +43,57 @@ extern const gx_device gs_hit_device;
extern const int gs_hit_detected;
/* Forward references */
-private int upath_append(P2(os_ptr, os_ptr));
-private int upath_stroke(P2(os_ptr, gs_matrix *));
+private int upath_append(P2(os_ptr, i_ctx_t *));
+private int upath_stroke(P2(i_ctx_t *, gs_matrix *));
/* ---------------- Insideness testing ---------------- */
/* Forward references */
-private int in_test(P2(os_ptr, int (*)(P1(gs_state *))));
-private int in_path(P3(os_ptr, os_ptr, gx_device *));
-private int in_path_result(P3(os_ptr, int, int));
-private int in_utest(P2(os_ptr, int (*)(P1(gs_state *))));
-private int in_upath(P2(os_ptr, gx_device *));
-private int in_upath_result(P3(os_ptr, int, int));
+private int in_test(P2(i_ctx_t *, int (*)(P1(gs_state *))));
+private int in_path(P3(os_ptr, i_ctx_t *, gx_device *));
+private int in_path_result(P3(i_ctx_t *, int, int));
+private int in_utest(P2(i_ctx_t *, int (*)(P1(gs_state *))));
+private int in_upath(P2(i_ctx_t *, gx_device *));
+private int in_upath_result(P3(i_ctx_t *, int, int));
/* <x> <y> ineofill <bool> */
/* <userpath> ineofill <bool> */
private int
-zineofill(os_ptr op)
+zineofill(i_ctx_t *i_ctx_p)
{
- return in_test(op, gs_eofill);
+ return in_test(i_ctx_p, gs_eofill);
}
/* <x> <y> infill <bool> */
/* <userpath> infill <bool> */
private int
-zinfill(os_ptr op)
+zinfill(i_ctx_t *i_ctx_p)
{
- return in_test(op, gs_fill);
+ return in_test(i_ctx_p, gs_fill);
}
/* <x> <y> instroke <bool> */
/* <userpath> instroke <bool> */
private int
-zinstroke(os_ptr op)
+zinstroke(i_ctx_t *i_ctx_p)
{
- return in_test(op, gs_stroke);
+ return in_test(i_ctx_p, gs_stroke);
}
/* <x> <y> <userpath> inueofill <bool> */
/* <userpath1> <userpath2> inueofill <bool> */
private int
-zinueofill(os_ptr op)
+zinueofill(i_ctx_t *i_ctx_p)
{
- return in_utest(op, gs_eofill);
+ return in_utest(i_ctx_p, gs_eofill);
}
/* <x> <y> <userpath> inufill <bool> */
/* <userpath1> <userpath2> inufill <bool> */
private int
-zinufill(os_ptr op)
+zinufill(i_ctx_t *i_ctx_p)
{
- return in_utest(op, gs_fill);
+ return in_utest(i_ctx_p, gs_fill);
}
/* <x> <y> <userpath> inustroke <bool> */
@@ -101,8 +101,9 @@ zinufill(os_ptr op)
/* <userpath1> <userpath2> inustroke <bool> */
/* <userpath1> <userpath2> <matrix> inustroke <bool> */
private int
-zinustroke(os_ptr op)
+zinustroke(i_ctx_t *i_ctx_p)
{ /* This is different because of the optional matrix operand. */
+ os_ptr op = osp;
int code = gs_gsave(igs);
int spop, npop;
gs_matrix mat;
@@ -110,11 +111,11 @@ zinustroke(os_ptr op)
if (code < 0)
return code;
- if ((spop = upath_stroke(op, &mat)) < 0) {
+ if ((spop = upath_stroke(i_ctx_p, &mat)) < 0) {
gs_grestore(igs);
return spop;
}
- if ((npop = in_path(op - spop, op, &hdev)) < 0) {
+ if ((npop = in_path(op - spop, i_ctx_p, &hdev)) < 0) {
gs_grestore(igs);
return npop;
}
@@ -122,28 +123,29 @@ zinustroke(os_ptr op)
code = gs_concat(igs, &mat);
if (code >= 0)
code = gs_stroke(igs);
- return in_upath_result(op, npop + spop, code);
+ return in_upath_result(i_ctx_p, npop + spop, code);
}
/* ------ Internal routines ------ */
/* Do the work of the non-user-path insideness operators. */
private int
-in_test(os_ptr op, int (*paintproc)(P1(gs_state *)))
+in_test(i_ctx_t *i_ctx_p, int (*paintproc)(P1(gs_state *)))
{
+ os_ptr op = osp;
gx_device hdev;
- int npop = in_path(op, op, &hdev);
+ int npop = in_path(op, i_ctx_p, &hdev);
int code;
if (npop < 0)
return npop;
code = (*paintproc)(igs);
- return in_path_result(op, npop, code);
+ return in_path_result(i_ctx_p, npop, code);
}
/* Set up a clipping path and device for insideness testing. */
private int
-in_path(os_ptr oppath, os_ptr op, gx_device * phdev)
+in_path(os_ptr oppath, i_ctx_t *i_ctx_p, gx_device * phdev)
{
int code = gs_gsave(igs);
int npop;
@@ -172,7 +174,7 @@ in_path(os_ptr oppath, os_ptr op, gx_device * phdev)
gx_path_init_local(&save, imemory);
gx_path_assign_preserve(&save, ipath);
gs_newpath(igs);
- code = upath_append(oppath, op);
+ code = upath_append(oppath, i_ctx_p);
if (code >= 0)
code = gx_clip_to_path(igs);
gx_path_assign_free(igs->path, &save);
@@ -194,8 +196,9 @@ in_path(os_ptr oppath, os_ptr op, gx_device * phdev)
/* Finish an insideness test. */
private int
-in_path_result(os_ptr op, int npop, int code)
+in_path_result(i_ctx_t *i_ctx_p, int npop, int code)
{
+ os_ptr op = osp;
bool result;
gs_grestore(igs); /* matches gsave in in_path */
@@ -215,30 +218,31 @@ in_path_result(os_ptr op, int npop, int code)
/* Do the work of the user-path insideness operators. */
private int
-in_utest(os_ptr op, int (*paintproc)(P1(gs_state *)))
+in_utest(i_ctx_t *i_ctx_p, int (*paintproc)(P1(gs_state *)))
{
gx_device hdev;
- int npop = in_upath(op, &hdev);
+ int npop = in_upath(i_ctx_p, &hdev);
int code;
if (npop < 0)
return npop;
code = (*paintproc)(igs);
- return in_upath_result(op, npop, code);
+ return in_upath_result(i_ctx_p, npop, code);
}
/* Set up a clipping path and device for insideness testing */
/* with a user path. */
private int
-in_upath(os_ptr op, gx_device * phdev)
+in_upath(i_ctx_t *i_ctx_p, gx_device * phdev)
{
+ os_ptr op = osp;
int code = gs_gsave(igs);
int npop;
if (code < 0)
return code;
- if ((code = upath_append(op, op)) < 0 ||
- (npop = in_path(op - 1, op, phdev)) < 0
+ if ((code = upath_append(op, i_ctx_p)) < 0 ||
+ (npop = in_path(op - 1, i_ctx_p, phdev)) < 0
) {
gs_grestore(igs);
return code;
@@ -248,10 +252,10 @@ in_upath(os_ptr op, gx_device * phdev)
/* Finish an insideness test with a user path. */
private int
-in_upath_result(os_ptr op, int npop, int code)
+in_upath_result(i_ctx_t *i_ctx_p, int npop, int code)
{
gs_grestore(igs); /* matches gsave in in_upath */
- return in_path_result(op, npop, code);
+ return in_path_result(i_ctx_p, npop, code);
}
/* ---------------- User paths ---------------- */
@@ -279,14 +283,14 @@ static const byte up_nargs[UPATH_MAX_OP + 1] = {
};
/* Declare operator procedures not declared in opextern.h. */
-int zsetbbox(P1(os_ptr));
-int zarc(P1(os_ptr));
-int zarcn(P1(os_ptr));
-int zarct(P1(os_ptr));
-private int zucache(P1(os_ptr));
+int zsetbbox(P1(i_ctx_t *));
+int zarc(P1(i_ctx_t *));
+int zarcn(P1(i_ctx_t *));
+int zarct(P1(i_ctx_t *));
+private int zucache(P1(i_ctx_t *));
#undef zp
-static const op_proc_p up_ops[UPATH_MAX_OP + 1] = {
+static const op_proc_t up_ops[UPATH_MAX_OP + 1] = {
zsetbbox, zmoveto, zrmoveto, zlineto, zrlineto,
zcurveto, zrcurveto, zarc, zarcn, zarct,
zclosepath, zucache
@@ -294,20 +298,22 @@ static const op_proc_p up_ops[UPATH_MAX_OP + 1] = {
/* - ucache - */
private int
-zucache(os_ptr op)
-{ /* A no-op for now. */
+zucache(i_ctx_t *i_ctx_p)
+{
+ /* A no-op for now. */
return 0;
}
/* <userpath> uappend - */
private int
-zuappend(register os_ptr op)
+zuappend(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = gs_gsave(igs);
if (code < 0)
return code;
- if ((code = upath_append(op, op)) >= 0)
+ if ((code = upath_append(op, i_ctx_p)) >= 0)
code = gs_upmergepath(igs);
gs_grestore(igs);
if (code < 0)
@@ -318,13 +324,14 @@ zuappend(register os_ptr op)
/* <userpath> ueofill - */
private int
-zueofill(register os_ptr op)
+zueofill(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = gs_gsave(igs);
if (code < 0)
return code;
- if ((code = upath_append(op, op)) >= 0)
+ if ((code = upath_append(op, i_ctx_p)) >= 0)
code = gs_eofill(igs);
gs_grestore(igs);
if (code < 0)
@@ -335,13 +342,14 @@ zueofill(register os_ptr op)
/* <userpath> ufill - */
private int
-zufill(register os_ptr op)
+zufill(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code = gs_gsave(igs);
if (code < 0)
return code;
- if ((code = upath_append(op, op)) >= 0)
+ if ((code = upath_append(op, i_ctx_p)) >= 0)
code = gs_fill(igs);
gs_grestore(igs);
if (code < 0)
@@ -353,14 +361,14 @@ zufill(register os_ptr op)
/* <userpath> ustroke - */
/* <userpath> <matrix> ustroke - */
private int
-zustroke(register os_ptr op)
+zustroke(i_ctx_t *i_ctx_p)
{
int code = gs_gsave(igs);
int npop;
if (code < 0)
return code;
- if ((code = npop = upath_stroke(op, NULL)) >= 0)
+ if ((code = npop = upath_stroke(i_ctx_p, NULL)) >= 0)
code = gs_stroke(igs);
gs_grestore(igs);
if (code < 0)
@@ -372,7 +380,7 @@ zustroke(register os_ptr op)
/* <userpath> ustrokepath - */
/* <userpath> <matrix> ustrokepath - */
private int
-zustrokepath(register os_ptr op)
+zustrokepath(i_ctx_t *i_ctx_p)
{
gx_path save;
int code, npop;
@@ -380,7 +388,7 @@ zustrokepath(register os_ptr op)
/* Save and reset the path. */
gx_path_init_local(&save, imemory);
gx_path_assign_preserve(&save, igs->path);
- if ((code = npop = upath_stroke(op, NULL)) < 0 ||
+ if ((code = npop = upath_stroke(i_ctx_p, NULL)) < 0 ||
(code = gs_strokepath(igs)) < 0
) {
gx_path_assign_free(igs->path, &save);
@@ -397,8 +405,10 @@ zustrokepath(register os_ptr op)
int make_upath(P4(ref * rupath, gs_state * pgs, gx_path * ppath,
bool with_ucache));
private int
-zupath(register os_ptr op)
+zupath(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_boolean);
return make_upath(op, igs, igs->path, op->value.boolval);
}
@@ -509,7 +519,7 @@ make_upath(ref * rupath, gs_state * pgs, gx_path * ppath, bool with_ucache)
/* Append a user path to the current path. */
private int
-upath_append(os_ptr oppath, os_ptr op)
+upath_append(os_ptr oppath, i_ctx_t *i_ctx_p)
{
check_read(*oppath);
gs_newpath(igs);
@@ -538,6 +548,7 @@ upath_append(os_ptr oppath, os_ptr op)
return_error(e_rangecheck);
else { /* operator */
do {
+ os_ptr op = osp;
byte opargs = up_nargs[opx];
while (opargs--) {
@@ -554,10 +565,9 @@ upath_append(os_ptr oppath, os_ptr op)
return_error(e_typecheck);
}
}
- code = (*up_ops[opx])(op);
+ code = (*up_ops[opx])(i_ctx_p);
if (code < 0)
return code;
- op = osp; /* resync */
}
while (--repcount);
repcount = 1;
@@ -568,12 +578,13 @@ upath_append(os_ptr oppath, os_ptr op)
uint ocount = r_size(oppath);
long index = 0;
int argcount = 0;
- int (*oproc)(P1(os_ptr));
+ op_proc_t oproc;
int opx, code;
for (; index < ocount; index++) {
ref rup;
ref *defp;
+ os_ptr op = osp;
array_get(arp, index, &rup);
switch (r_type(&rup)) {
@@ -601,10 +612,9 @@ upath_append(os_ptr oppath, os_ptr op)
break;
if (opx > UPATH_MAX_OP || argcount != up_nargs[opx])
return_error(e_typecheck);
- code = (*oproc)(op);
+ code = (*oproc)(i_ctx_p);
if (code < 0)
return code;
- op = osp; /* resync ostack pointer */
argcount = 0;
break;
default:
@@ -621,13 +631,14 @@ upath_append(os_ptr oppath, os_ptr op)
/* Append a user path to the current path, and then apply or return */
/* a transformation if one is supplied. */
private int
-upath_stroke(os_ptr op, gs_matrix *pmat)
+upath_stroke(i_ctx_t *i_ctx_p, gs_matrix *pmat)
{
+ os_ptr op = osp;
int code, npop;
gs_matrix mat;
if ((code = read_matrix(op, &mat)) >= 0) {
- if ((code = upath_append(op - 1, op)) >= 0) {
+ if ((code = upath_append(op - 1, i_ctx_p)) >= 0) {
if (pmat)
*pmat = mat;
else
@@ -635,7 +646,7 @@ upath_stroke(os_ptr op, gs_matrix *pmat)
}
npop = 2;
} else {
- if ((code = upath_append(op, op)) >= 0)
+ if ((code = upath_append(op, i_ctx_p)) >= 0)
if (pmat)
gs_make_identity(pmat);
npop = 1;
diff --git a/gs/src/zusparam.c b/gs/src/zusparam.c
index 05a92e011..76f026809 100644
--- a/gs/src/zusparam.c
+++ b/gs/src/zusparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -42,8 +42,8 @@
extern gs_font_dir *ifont_dir; /* in zfont.c */
/* Import the GC parameters from zvmem2.c. */
-extern int set_vm_reclaim(P1(long));
-extern int set_vm_threshold(P1(long));
+extern int set_vm_reclaim(P2(i_ctx_t *, long));
+extern int set_vm_threshold(P2(i_ctx_t *, long));
/* Define an individual user or system parameter. */
/* Eventually this will be made public. */
@@ -55,8 +55,8 @@ typedef struct param_def_s {
typedef struct long_param_def_s {
param_def_common;
long min_value, max_value;
- long (*current)(P0());
- int (*set)(P1(long));
+ long (*current)(P1(i_ctx_t *));
+ int (*set)(P2(i_ctx_t *, long));
} long_param_def_t;
#if arch_sizeof_long > arch_sizeof_int
@@ -66,13 +66,13 @@ typedef struct long_param_def_s {
#endif
typedef struct bool_param_def_s {
param_def_common;
- bool (*current)(P0());
- int (*set)(P1(bool));
+ bool (*current)(P1(i_ctx_t *));
+ int (*set)(P2(i_ctx_t *, bool));
} bool_param_def_t;
typedef struct string_param_def_s {
param_def_common;
- void (*current)(P1(gs_param_string *));
- int (*set)(P1(gs_param_string *));
+ void (*current)(P2(i_ctx_t *, gs_param_string *));
+ int (*set)(P2(i_ctx_t *, gs_param_string *));
} string_param_def_t;
/* Define a parameter set (user or system). */
@@ -86,16 +86,17 @@ typedef struct param_set_s {
} param_set;
/* Forward references */
-private int setparams(P2(gs_param_list *, const param_set *));
-private int currentparams(P2(os_ptr, const param_set *));
-private int currentparam1(P2(os_ptr, const param_set *));
+private int setparams(P3(i_ctx_t *, gs_param_list *, const param_set *));
+private int currentparams(P2(i_ctx_t *, const param_set *));
+private int currentparam1(P2(i_ctx_t *, const param_set *));
/* ------ Passwords ------ */
/* <string|int> .checkpassword <0|1|2> */
private int
-zcheckpassword(register os_ptr op)
+zcheckpassword(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
ref params[2];
array_param_list list;
gs_param_list *const plist = (gs_param_list *)&list;
@@ -124,24 +125,24 @@ zcheckpassword(register os_ptr op)
/* Integer values */
private long
-current_BuildTime(void)
+current_BuildTime(i_ctx_t *i_ctx_p)
{
return gs_buildtime;
}
private long
-current_MaxFontCache(void)
+current_MaxFontCache(i_ctx_t *i_ctx_p)
{
return gs_currentcachesize(ifont_dir);
}
private int
-set_MaxFontCache(long val)
+set_MaxFontCache(i_ctx_t *i_ctx_p, long val)
{
return gs_setcachesize(ifont_dir,
(uint)(val < 0 ? 0 : val > max_uint ? max_uint :
val));
}
private long
-current_CurFontCache(void)
+current_CurFontCache(i_ctx_t *i_ctx_p)
{
uint cstat[7];
@@ -149,7 +150,7 @@ current_CurFontCache(void)
return cstat[0];
}
private long
-current_MaxGlobalVM(void)
+current_MaxGlobalVM(i_ctx_t *i_ctx_p)
{
gs_memory_gc_status_t stat;
@@ -157,7 +158,7 @@ current_MaxGlobalVM(void)
return stat.max_vm;
}
private int
-set_MaxGlobalVM(long val)
+set_MaxGlobalVM(i_ctx_t *i_ctx_p, long val)
{
gs_memory_gc_status_t stat;
@@ -167,7 +168,7 @@ set_MaxGlobalVM(long val)
return 0;
}
private long
-current_Revision(void)
+current_Revision(i_ctx_t *i_ctx_p)
{
return gs_revision;
}
@@ -183,7 +184,7 @@ private const long_param_def_t system_long_params[] =
/* Boolean values */
private bool
-current_ByteOrder(void)
+current_ByteOrder(i_ctx_t *i_ctx_p)
{
return !arch_is_big_endian;
}
@@ -194,14 +195,12 @@ private const bool_param_def_t system_bool_params[] =
/* String values */
private void
-current_RealFormat(gs_param_string * pval)
+current_RealFormat(i_ctx_t *i_ctx_p, gs_param_string * pval)
{
#if arch_floats_are_IEEE
static const char *const rfs = "IEEE";
-
#else
static const char *const rfs = "not IEEE";
-
#endif
pval->data = (const byte *)rfs;
@@ -223,8 +222,9 @@ private const param_set system_param_set =
/* <dict> .setsystemparams - */
private int
-zsetsystemparams(register os_ptr op)
+zsetsystemparams(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
int code;
dict_param_list list;
gs_param_list *const plist = (gs_param_list *)&list;
@@ -267,7 +267,7 @@ zsetsystemparams(register os_ptr op)
if (code < 0)
goto out;
}
- code = setparams(plist, &system_param_set);
+ code = setparams(i_ctx_p, plist, &system_param_set);
out:
iparam_list_release(&list);
if (code < 0)
@@ -278,83 +278,83 @@ zsetsystemparams(register os_ptr op)
/* - .currentsystemparams <name1> <value1> ... */
private int
-zcurrentsystemparams(os_ptr op)
+zcurrentsystemparams(i_ctx_t *i_ctx_p)
{
- return currentparams(op, &system_param_set);
+ return currentparams(i_ctx_p, &system_param_set);
}
/* <name> .getsystemparam <value> */
private int
-zgetsystemparam(os_ptr op)
+zgetsystemparam(i_ctx_t *i_ctx_p)
{
- return currentparam1(op, &system_param_set);
+ return currentparam1(i_ctx_p, &system_param_set);
}
/* ------ User parameters ------ */
/* Integer values */
private long
-current_JobTimeout(void)
+current_JobTimeout(i_ctx_t *i_ctx_p)
{
return 0;
}
private int
-set_JobTimeout(long val)
+set_JobTimeout(i_ctx_t *i_ctx_p, long val)
{
return 0;
}
private long
-current_MaxFontItem(void)
+current_MaxFontItem(i_ctx_t *i_ctx_p)
{
return gs_currentcacheupper(ifont_dir);
}
private int
-set_MaxFontItem(long val)
+set_MaxFontItem(i_ctx_t *i_ctx_p, long val)
{
return gs_setcacheupper(ifont_dir, val);
}
private long
-current_MinFontCompress(void)
+current_MinFontCompress(i_ctx_t *i_ctx_p)
{
return gs_currentcachelower(ifont_dir);
}
private int
-set_MinFontCompress(long val)
+set_MinFontCompress(i_ctx_t *i_ctx_p, long val)
{
return gs_setcachelower(ifont_dir, val);
}
private long
-current_MaxOpStack(void)
+current_MaxOpStack(i_ctx_t *i_ctx_p)
{
return ref_stack_max_count(&o_stack);
}
private int
-set_MaxOpStack(long val)
+set_MaxOpStack(i_ctx_t *i_ctx_p, long val)
{
return ref_stack_set_max_count(&o_stack, val);
}
private long
-current_MaxDictStack(void)
+current_MaxDictStack(i_ctx_t *i_ctx_p)
{
return ref_stack_max_count(&d_stack);
}
private int
-set_MaxDictStack(long val)
+set_MaxDictStack(i_ctx_t *i_ctx_p, long val)
{
return ref_stack_set_max_count(&d_stack, val);
}
private long
-current_MaxExecStack(void)
+current_MaxExecStack(i_ctx_t *i_ctx_p)
{
return ref_stack_max_count(&e_stack);
}
private int
-set_MaxExecStack(long val)
+set_MaxExecStack(i_ctx_t *i_ctx_p, long val)
{
return ref_stack_set_max_count(&e_stack, val);
}
private long
-current_MaxLocalVM(void)
+current_MaxLocalVM(i_ctx_t *i_ctx_p)
{
gs_memory_gc_status_t stat;
@@ -362,7 +362,7 @@ current_MaxLocalVM(void)
return stat.max_vm;
}
private int
-set_MaxLocalVM(long val)
+set_MaxLocalVM(i_ctx_t *i_ctx_p, long val)
{
gs_memory_gc_status_t stat;
@@ -372,7 +372,7 @@ set_MaxLocalVM(long val)
return 0;
}
private long
-current_VMReclaim(void)
+current_VMReclaim(i_ctx_t *i_ctx_p)
{
gs_memory_gc_status_t gstat, lstat;
@@ -381,7 +381,7 @@ current_VMReclaim(void)
return (!gstat.enabled ? -2 : !lstat.enabled ? -1 : 0);
}
private long
-current_VMThreshold(void)
+current_VMThreshold(i_ctx_t *i_ctx_p)
{
gs_memory_gc_status_t stat;
@@ -389,22 +389,22 @@ current_VMThreshold(void)
return stat.vm_threshold;
}
private long
-current_WaitTimeout(void)
+current_WaitTimeout(i_ctx_t *i_ctx_p)
{
return 0;
}
private int
-set_WaitTimeout(long val)
+set_WaitTimeout(i_ctx_t *i_ctx_p, long val)
{
return 0;
}
private long
-current_MinScreenLevels(void)
+current_MinScreenLevels(i_ctx_t *i_ctx_p)
{
return gs_currentminscreenlevels();
}
private int
-set_MinScreenLevels(long val)
+set_MinScreenLevels(i_ctx_t *i_ctx_p, long val)
{
gs_setminscreenlevels((uint) val);
return 0;
@@ -438,12 +438,12 @@ private const long_param_def_t user_long_params[] =
/* Boolean values */
private bool
-current_AccurateScreens(void)
+current_AccurateScreens(i_ctx_t *i_ctx_p)
{
return gs_currentaccuratescreens();
}
private int
-set_AccurateScreens(bool val)
+set_AccurateScreens(i_ctx_t *i_ctx_p, bool val)
{
gs_setaccuratescreens(val);
return 0;
@@ -464,23 +464,24 @@ private const param_set user_param_set =
/* <dict> .setuserparams - */
/* We break this out for use when switching contexts. */
int
-set_user_params(const ref * op)
+set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
{
dict_param_list list;
int code;
- check_type(*op, t_dictionary);
- code = dict_param_list_read(&list, op, NULL, false);
+ check_type(*paramdict, t_dictionary);
+ code = dict_param_list_read(&list, paramdict, NULL, false);
if (code < 0)
return code;
- code = setparams((gs_param_list *)&list, &user_param_set);
+ code = setparams(i_ctx_p, (gs_param_list *)&list, &user_param_set);
iparam_list_release(&list);
return code;
}
private int
-zsetuserparams(register os_ptr op)
+zsetuserparams(i_ctx_t *i_ctx_p)
{
- int code = set_user_params(op);
+ os_ptr op = osp;
+ int code = set_user_params(i_ctx_p, op);
if (code >= 0)
pop(1);
@@ -489,16 +490,16 @@ zsetuserparams(register os_ptr op)
/* - .currentuserparams <name1> <value1> ... */
private int
-zcurrentuserparams(os_ptr op)
+zcurrentuserparams(i_ctx_t *i_ctx_p)
{
- return currentparams(op, &user_param_set);
+ return currentparams(i_ctx_p, &user_param_set);
}
/* <name> .getuserparam <value> */
private int
-zgetuserparam(os_ptr op)
+zgetuserparam(i_ctx_t *i_ctx_p)
{
- return currentparam1(op, &user_param_set);
+ return currentparam1(i_ctx_p, &user_param_set);
}
/* ------ Initialization procedure ------ */
@@ -524,7 +525,7 @@ const op_def zusparam_op_defs[] =
/* Set the values of a parameter set from a parameter list. */
/* We don't attempt to back out if anything fails. */
private int
-setparams(gs_param_list * plist, const param_set * pset)
+setparams(i_ctx_t *i_ctx_p, gs_param_list * plist, const param_set * pset)
{
int i, code;
@@ -543,7 +544,7 @@ setparams(gs_param_list * plist, const param_set * pset)
case 0:
if (val < pdef->min_value || val > pdef->max_value)
return_error(e_rangecheck);
- code = (*pdef->set)(val);
+ code = (*pdef->set)(i_ctx_p, val);
if (code < 0)
return code;
}
@@ -556,7 +557,7 @@ setparams(gs_param_list * plist, const param_set * pset)
continue;
code = param_read_bool(plist, pdef->pname, &val);
if (code == 0)
- code = (*pdef->set)(val);
+ code = (*pdef->set)(i_ctx_p, val);
if (code < 0)
return code;
}
@@ -574,7 +575,7 @@ pname_matches(const char *pname, const ref * psref)
psref->value.const_bytes, r_size(psref)));
}
private int
-current_param_list(os_ptr op, const param_set * pset,
+current_param_list(i_ctx_t *i_ctx_p, const param_set * pset,
const ref * psref /*t_string */ )
{
stack_param_list list;
@@ -586,7 +587,7 @@ current_param_list(os_ptr op, const param_set * pset,
const char *pname = pset->long_defs[i].pname;
if (pname_matches(pname, psref)) {
- long val = (*pset->long_defs[i].current)();
+ long val = (*pset->long_defs[i].current)(i_ctx_p);
int code = param_write_long(plist, pname, &val);
if (code < 0)
@@ -597,7 +598,7 @@ current_param_list(os_ptr op, const param_set * pset,
const char *pname = pset->bool_defs[i].pname;
if (pname_matches(pname, psref)) {
- bool val = (*pset->bool_defs[i].current)();
+ bool val = (*pset->bool_defs[i].current)(i_ctx_p);
int code = param_write_bool(plist, pname, &val);
if (code < 0)
@@ -611,7 +612,7 @@ current_param_list(os_ptr op, const param_set * pset,
gs_param_string val;
int code;
- (*pset->string_defs[i].current)(&val);
+ (*pset->string_defs[i].current)(i_ctx_p, &val);
code = param_write_string(plist, pname, &val);
if (code < 0)
return code;
@@ -622,22 +623,23 @@ current_param_list(os_ptr op, const param_set * pset,
/* Get the current values of a parameter set to the stack. */
private int
-currentparams(os_ptr op, const param_set * pset)
+currentparams(i_ctx_t *i_ctx_p, const param_set * pset)
{
- return current_param_list(op, pset, NULL);
+ return current_param_list(i_ctx_p, pset, NULL);
}
/* Get the value of a single parameter to the stack, or signal an error. */
private int
-currentparam1(os_ptr op, const param_set * pset)
+currentparam1(i_ctx_t *i_ctx_p, const param_set * pset)
{
+ os_ptr op = osp;
ref sref;
int code;
check_type(*op, t_name);
check_ostack(2);
name_string_ref((const ref *)op, &sref);
- code = current_param_list(op, pset, &sref);
+ code = current_param_list(i_ctx_p, pset, &sref);
if (code < 0)
return code;
if (osp == op)
diff --git a/gs/src/zvmem.c b/gs/src/zvmem.c
index de0094c21..82d6e0ded 100644
--- a/gs/src/zvmem.c
+++ b/gs/src/zvmem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -55,7 +55,7 @@ gs_private_st_ptrs1(st_vm_save, vm_save_t, "savetype",
/* Clean up the stacks and validate storage. */
private void
-ivalidate_clean_spaces(void)
+ivalidate_clean_spaces(i_ctx_t *i_ctx_p)
{
if (gs_debug_c('?')) {
ref_stack_cleanup(&d_stack);
@@ -67,8 +67,9 @@ ivalidate_clean_spaces(void)
/* - save <save> */
int
-zsave(register os_ptr op)
+zsave(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
uint space = icurrent_space;
vm_save_t *vmsave;
ulong sid;
@@ -76,7 +77,7 @@ zsave(register os_ptr op)
gs_state *prev;
if (I_VALIDATE_BEFORE_SAVE)
- ivalidate_clean_spaces();
+ ivalidate_clean_spaces(i_ctx_p);
ialloc_set_space(idmemory, avm_local);
vmsave = ialloc_struct(vm_save_t, &st_vm_save, "zsave");
ialloc_set_space(idmemory, space);
@@ -99,17 +100,18 @@ zsave(register os_ptr op)
push(1);
make_tav(op, t_save, 0, saveid, sid);
if (I_VALIDATE_AFTER_SAVE)
- ivalidate_clean_spaces();
+ ivalidate_clean_spaces(i_ctx_p);
return 0;
}
/* <save> restore - */
private int restore_check_operand(P2(os_ptr, alloc_save_t **));
-private int restore_check_stack(P3(const ref_stack *, const alloc_save_t *, bool));
-private void restore_fix_stack(P3(ref_stack *, const alloc_save_t *, bool));
+private int restore_check_stack(P3(const ref_stack_t *, const alloc_save_t *, bool));
+private void restore_fix_stack(P3(ref_stack_t *, const alloc_save_t *, bool));
int
-zrestore(register os_ptr op)
+zrestore(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
alloc_save_t *asave;
bool last;
vm_save_t *vmsave;
@@ -121,7 +123,7 @@ zrestore(register os_ptr op)
(ulong) alloc_save_client_data(asave),
(ulong) op->value.saveid);
if (I_VALIDATE_BEFORE_RESTORE)
- ivalidate_clean_spaces();
+ ivalidate_clean_spaces(i_ctx_p);
/* Check the contents of the stacks. */
osp--;
{
@@ -168,7 +170,7 @@ zrestore(register os_ptr op)
}
dict_set_top(); /* reload dict stack cache */
if (I_VALIDATE_AFTER_RESTORE)
- ivalidate_clean_spaces();
+ ivalidate_clean_spaces(i_ctx_p);
return 0;
}
/* Check the operand of a restore. */
@@ -192,7 +194,7 @@ restore_check_operand(os_ptr op, alloc_save_t ** pasave)
}
/* Check a stack to make sure all its elements are older than a save. */
private int
-restore_check_stack(const ref_stack * pstack, const alloc_save_t * asave,
+restore_check_stack(const ref_stack_t * pstack, const alloc_save_t * asave,
bool is_estack)
{
ref_stack_enum_t rsenum;
@@ -272,7 +274,7 @@ restore_check_stack(const ref_stack * pstack, const alloc_save_t * asave,
* Note that this procedure is only called if restore_check_stack succeeded.
*/
private void
-restore_fix_stack(ref_stack * pstack, const alloc_save_t * asave,
+restore_fix_stack(ref_stack_t * pstack, const alloc_save_t * asave,
bool is_estack)
{
ref_stack_enum_t rsenum;
@@ -319,8 +321,9 @@ restore_fix_stack(ref_stack * pstack, const alloc_save_t * asave,
/* - vmstatus <save_level> <vm_used> <vm_maximum> */
private int
-zvmstatus(register os_ptr op)
+zvmstatus(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
gs_memory_status_t mstat, dstat;
gs_memory_status(imemory, &mstat);
@@ -343,8 +346,9 @@ zvmstatus(register os_ptr op)
/* <save> .forgetsave - */
private int
-zforgetsave(register os_ptr op)
+zforgetsave(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
alloc_save_t *asave;
vm_save_t *vmsave;
int code = restore_check_operand(op, &asave);
diff --git a/gs/src/zvmem2.c b/gs/src/zvmem2.c
index ae2dd6fb0..17118f553 100644
--- a/gs/src/zvmem2.c
+++ b/gs/src/zvmem2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -35,8 +35,9 @@
/* <bool> .setglobal - */
private int
-zsetglobal(register os_ptr op)
+zsetglobal(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
check_type(*op, t_boolean);
ialloc_set_space(idmemory,
(op->value.boolval ? avm_global : avm_local));
@@ -46,8 +47,10 @@ zsetglobal(register os_ptr op)
/* <bool> .currentglobal - */
private int
-zcurrentglobal(register os_ptr op)
+zcurrentglobal(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
push(1);
make_bool(op, ialloc_space(idmemory) != avm_local);
return 0;
@@ -55,8 +58,10 @@ zcurrentglobal(register os_ptr op)
/* <any> gcheck/scheck <bool> */
private int
-zgcheck(register os_ptr op)
+zgcheck(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_op(1);
make_bool(op, (r_is_local(op) ? false : true));
return 0;
@@ -72,7 +77,7 @@ zgcheck(register os_ptr op)
* This is implemented as a PostScript procedure that calls setuserparams.
*/
int
-set_vm_threshold(long val)
+set_vm_threshold(i_ctx_t *i_ctx_p, long val)
{
gs_memory_gc_status_t stat;
@@ -101,7 +106,7 @@ set_vm_threshold(long val)
* disabling GC is implemented by calling setuserparams.
*/
int
-set_vm_reclaim(long val)
+set_vm_reclaim(i_ctx_t *i_ctx_p, long val)
{
if (val >= -2 && val <= 0) {
gs_memory_gc_status_t stat;
@@ -120,8 +125,10 @@ set_vm_reclaim(long val)
return_error(e_rangecheck);
}
private int
-zvmreclaim(register os_ptr op)
+zvmreclaim(i_ctx_t *i_ctx_p)
{
+ os_ptr op = osp;
+
check_type(*op, t_integer);
if (op->value.intval == 1 || op->value.intval == 2) {
/* Force the interpreter to store its state and exit. */