diff options
Diffstat (limited to 'pcl')
-rw-r--r-- | pcl/Anomalies.txt | 845 | ||||
-rw-r--r-- | pcl/news-pcl | 2215 | ||||
-rw-r--r-- | pcl/pcbiptrn.c | 355 | ||||
-rw-r--r-- | pcl/pcbiptrn.h | 51 | ||||
-rw-r--r-- | pcl/pccid.c | 462 | ||||
-rw-r--r-- | pcl/pccid.h | 160 | ||||
-rw-r--r-- | pcl/pccolor.c | 166 | ||||
-rw-r--r-- | pcl/pccoord.h | 28 | ||||
-rw-r--r-- | pcl/pccprint.c | 103 | ||||
-rw-r--r-- | pcl/pccrd.c | 341 | ||||
-rw-r--r-- | pcl/pccrd.h | 132 | ||||
-rw-r--r-- | pcl/pccsbase.c | 1189 | ||||
-rw-r--r-- | pcl/pccsbase.h | 164 | ||||
-rw-r--r-- | pcl/pcdict.h | 30 | ||||
-rw-r--r-- | pcl/pcdither.c | 147 | ||||
-rw-r--r-- | pcl/pcdither.h | 98 | ||||
-rw-r--r-- | pcl/pcdraw.c | 174 | ||||
-rw-r--r-- | pcl/pcdraw.h | 26 | ||||
-rw-r--r-- | pcl/pcfont.c | 601 | ||||
-rw-r--r-- | pcl/pcfont.h | 107 | ||||
-rw-r--r-- | pcl/pcfontst.h | 30 | ||||
-rw-r--r-- | pcl/pcfrgrnd.c | 241 | ||||
-rw-r--r-- | pcl/pcfrgrnd.h | 112 | ||||
-rw-r--r-- | pcl/pcfsel.c | 445 | ||||
-rw-r--r-- | pcl/pcfsel.h | 38 | ||||
-rw-r--r-- | pcl/pcht.c | 2228 | ||||
-rw-r--r-- | pcl/pcht.h | 329 | ||||
-rw-r--r-- | pcl/pcident.c | 32 | ||||
-rw-r--r-- | pcl/pcident.h | 46 | ||||
-rw-r--r-- | pcl/pcimpl.c | 19 | ||||
-rw-r--r-- | pcl/pcindxed.c | 1161 | ||||
-rw-r--r-- | pcl/pcindxed.h | 363 | ||||
-rw-r--r-- | pcl/pcjob.c | 232 | ||||
-rw-r--r-- | pcl/pcl.mak | 1200 | ||||
-rw-r--r-- | pcl/pcl_msvc.mak | 160 | ||||
-rw-r--r-- | pcl/pcl_sgi.mak | 74 | ||||
-rw-r--r-- | pcl/pcl_top.mak | 30 | ||||
-rw-r--r-- | pcl/pcl_ugcc.mak | 98 | ||||
-rw-r--r-- | pcl/pcl_watc.mak | 153 | ||||
-rw-r--r-- | pcl/pclfont.c | 256 | ||||
-rw-r--r-- | pcl/pclookup.c | 146 | ||||
-rw-r--r-- | pcl/pclookup.h | 207 | ||||
-rw-r--r-- | pcl/pcmacros.c | 258 | ||||
-rw-r--r-- | pcl/pcmisc.c | 58 | ||||
-rw-r--r-- | pcl/pcmtx3.c | 255 | ||||
-rw-r--r-- | pcl/pcmtx3.h | 149 | ||||
-rw-r--r-- | pcl/pcommand.c | 226 | ||||
-rw-r--r-- | pcl/pcommand.h | 275 | ||||
-rw-r--r-- | pcl/pcpage.c | 987 | ||||
-rw-r--r-- | pcl/pcpage.h | 56 | ||||
-rw-r--r-- | pcl/pcpalet.c | 1006 | ||||
-rw-r--r-- | pcl/pcpalet.h | 303 | ||||
-rw-r--r-- | pcl/pcparam.h | 24 | ||||
-rw-r--r-- | pcl/pcparse.c | 615 | ||||
-rw-r--r-- | pcl/pcparse.h | 101 | ||||
-rw-r--r-- | pcl/pcpatrn.c | 1386 | ||||
-rw-r--r-- | pcl/pcpatrn.h | 552 | ||||
-rw-r--r-- | pcl/pcpattyp.h | 103 | ||||
-rw-r--r-- | pcl/pcpatxfm.c | 340 | ||||
-rw-r--r-- | pcl/pcpatxfm.h | 74 | ||||
-rw-r--r-- | pcl/pcrect.c | 276 | ||||
-rw-r--r-- | pcl/pcsfont.c | 746 | ||||
-rw-r--r-- | pcl/pcstate.h | 365 | ||||
-rw-r--r-- | pcl/pcstatus.c | 726 | ||||
-rw-r--r-- | pcl/pcsymbol.c | 320 | ||||
-rw-r--r-- | pcl/pcsymbol.h | 35 | ||||
-rw-r--r-- | pcl/pctext.c | 1054 | ||||
-rw-r--r-- | pcl/pctop.c | 631 | ||||
-rw-r--r-- | pcl/pctop.h | 18 | ||||
-rw-r--r-- | pcl/pctpm.h | 36 | ||||
-rw-r--r-- | pcl/pcuptrn.c | 577 | ||||
-rw-r--r-- | pcl/pcuptrn.h | 56 | ||||
-rw-r--r-- | pcl/pcursor.c | 810 | ||||
-rw-r--r-- | pcl/pcursor.h | 57 | ||||
-rw-r--r-- | pcl/pcwhtidx.c | 376 | ||||
-rw-r--r-- | pcl/pcwhtidx.h | 117 | ||||
-rw-r--r-- | pcl/pcxfmst.h | 146 | ||||
-rw-r--r-- | pcl/pgchar.c | 512 | ||||
-rw-r--r-- | pcl/pgcolor.c | 137 | ||||
-rw-r--r-- | pcl/pgconfig.c | 585 | ||||
-rw-r--r-- | pcl/pgdraw.c | 1505 | ||||
-rw-r--r-- | pcl/pgdraw.h | 103 | ||||
-rw-r--r-- | pcl/pgfdata.c | 936 | ||||
-rw-r--r-- | pcl/pgfdata.h | 38 | ||||
-rw-r--r-- | pcl/pgfont.c | 211 | ||||
-rw-r--r-- | pcl/pgfont.h | 15 | ||||
-rw-r--r-- | pcl/pgframe.c | 206 | ||||
-rw-r--r-- | pcl/pggeom.c | 101 | ||||
-rw-r--r-- | pcl/pggeom.h | 81 | ||||
-rw-r--r-- | pcl/pginit.c | 181 | ||||
-rw-r--r-- | pcl/pginit.h | 24 | ||||
-rw-r--r-- | pcl/pglabel.c | 1311 | ||||
-rw-r--r-- | pcl/pglfill.c | 884 | ||||
-rw-r--r-- | pcl/pgmand.h | 318 | ||||
-rw-r--r-- | pcl/pgmisc.c | 53 | ||||
-rw-r--r-- | pcl/pgmisc.h | 72 | ||||
-rw-r--r-- | pcl/pgparse.c | 384 | ||||
-rw-r--r-- | pcl/pgpoly.c | 284 | ||||
-rw-r--r-- | pcl/pgstate.h | 329 | ||||
-rw-r--r-- | pcl/pgvector.c | 568 | ||||
-rw-r--r-- | pcl/rtgmode.c | 713 | ||||
-rw-r--r-- | pcl/rtgmode.h | 39 | ||||
-rw-r--r-- | pcl/rtmisc.c | 244 | ||||
-rw-r--r-- | pcl/rtraster.c | 1385 | ||||
-rw-r--r-- | pcl/rtraster.h | 30 | ||||
-rw-r--r-- | pcl/rtrstcmp.c | 253 | ||||
-rw-r--r-- | pcl/rtrstcmp.h | 80 | ||||
-rw-r--r-- | pcl/rtrstst.h | 138 |
108 files changed, 0 insertions, 39828 deletions
diff --git a/pcl/Anomalies.txt b/pcl/Anomalies.txt deleted file mode 100644 index 47f067f3a..000000000 --- a/pcl/Anomalies.txt +++ /dev/null @@ -1,845 +0,0 @@ -Overview: - -Though designed to emulate the HP Color LaserJet 5/5M, there are several areas -where the behavior of the Artifex interpreter differs from that device. The -first part of this document provides an overview of these differences, and -the second part notes specific examples in the PCL 5c FTS where the differences -between the Artifex interpreter and the HP implementation are apparent. - -Overview: - - Fonts - Since the release of the LaserJet III in 1989, successive printer products - from HP have shifted away from using bitmap fonts toward scalable fonts, - originally using Intellifont fonts and more recently TrueType fonts (using - the InfiniFont packaging technique). The Color LaserJet 5/5M represents an - intermediate stage in this development. It has a single bitmap font (line- - printer), a primary set of scalable fonts in Intellifont format, and an - additional set of fonts in TrueType format. - - Artifex is not a font vendor, and the default set of fonts offered with the - interpreter is not meant to exactly emulate the offerings of an HP product. - In addition, the default font set corresponds to a later stage in the - evolution of HP products; more similar to the monochrome LaserJet 5/5M and - the LaserJet 6P than the Color LaserJet 5/5M (which more closely resembles - the font offering of the monochrome LaserJet 4 series). Though the set of - typeface "names" that are supported is similar, the format in which these - fonts are stored and some aspects of the supported character set vary. - - This discrepancy in font offerings has many visible manifestations, most of - them quite minor. Some of the more obvious differences are: - - 1. Spacing. - - Not all of the proportionally spaced fonts in the default set match - the spacing (advance width) of the corresponding fonts provided - by HP. This is most often visible when lines of text are set up to be - clipped at the right margin (rare in applications but more common in - the FTS), or when the automatic line wrap feature is used. - - 2. Adherence to requested height and/or (fixed-width) space. - - In normal operation, a PCL document does not directly specify which - fonts are to be used for a given block of text. Rather, the document - will specify a set of font properties which the interpreter attempts - to match as best possible given the set of available fonts (the rules - which define a "best" match are quite specific). Among the properties - specified are the height of the font and, in the case of a fixed-pitch - font, the character pitch. - - All of the fonts provided in the default set for the Artifex - interpreter are scalable, hence all will exactly adhere to the - requested font size and/or pitch. In situations where a bitmap font - would, instead, be used by an HP printer, only an approximate match - may be available for font size/pitch. Hence, the size of text - rendered by the Artifex interpreter may differ from that of an HP - printer. - - 3. Interaction with downloaded symbol sets. - - All of the fonts in the Artifex default set are TrueType fonts, which - make use of the Unicode font encoding scheme. Intellifont fonts, such - as the base set provided with the Color LaserJet 5/5M, make use of a - different font encoding scheme known as MSL. (In principle there is no - connection between a font's scaling technology and its encoding scheme, - but in practice all Intellifont fonts use the MSL scheme and all - (unbound) TrueType fonts use the Unicode scheme.) - - In PCL, a user defined (downloaded) symbol set may apply to either the - Unicode or the MSL encoding scheme, but not to both. Hence, a downloaded - symbol set that uses the MSL encoding can be used with the base font - set of the Color LaserJet 5/5M, but not with fonts provided with the - Artifex interpreter. Conversely, any downloaded symbol set that uses - the Unicode encoding can be used with the base font set of the Artifex - interpreter, but not the Color LaserJet 5/5M. - - Because support for the currently selected symbol set is the highest - priority selection parameter in the PCL font selection mechanism, this - difference in font format can have dramatic effects, as is evident in - some of the 5c FTS tests. - - 4. Font scaler anomalies - - The set of Intellifont fonts distributed by Agfa includes fonts with - some "malformed" character outlines (outlines that do not adhere to the - documented format). These outlines are handled differently by the - HP Intellifont scaler and the scaler provided with the Artifex - interpreter. For example, in the 5c FTS, the lower case 't' in the - Park Avenue font has a malformed outline, and its rendering with the - Artifex interpreter is quite different (i.e., distorted) from that - produced by an HP interpreter. - - Rendering Methods/Halftones - - HP's documentation identifies 20 different "rendering algorithms" that can - be selected on an object-by-object basis. For the most part these rendering - algorithms represent different halftones, though certain rendering - algorithms also specify color mapping (in particular, color to monochrome - conversion). - - No actual devices support all 20 algorithms. For any given device, many - algorithms are mapped to others, so that no more than 6 to 12 unique - algorithms are supported. This remapping respects color transformations: - a monochrome algorithm may be remapped to another monochrome algorithm but - not to a color algorithm, and vice-versa. Hence, the remapping of render - algorithms is essentially a mechanism for selecting amongst different - halftones. - - Halftones for PCL 5c devices fall into two categories: "predictable" and not - "predictable". Prior to the release of the Color LaserJet 5/5M, all PCL 5c - halftones were predictable: all halftones were based on threshold arrays - (HP's documentation terms such halftones "ordered dithers", because they - have a monotonicity or "order" property), and the same halftone was used on - all devices. (Strictly speaking, there is "upward compatibility": some - devices offer more halftones than others, but when a halftone is offered on - multiple devices it is the same.) - - The Color LaserJet 5/5M completely broke with this tradition, and offered - only "unpredictable", or device specific, halftones. This was accomplished - by adding five new halftone algorithms to the previously existing set of 15, - and on the Color LaserJet 5/5M, remapping all of the existing algorithms - that require halftoning (algorithms 1 and 2 do not) to these five. - - The "predictability" of a halftone is potentially of great significance in - PCL 5c, because of the manner in which HP chose to implement raster - operations. These are defined on a pixel-by-pixel basis after halftoning - (at least, where such a definition is possible; see the contone discussion - below for further information). Hence, when using raster operations to - combine objects rendered with two different halftones, the order in which - a halftone darkens pixels is of great significance: given two objects of - approximately 50% intensity and an exclusive-or raster operation, the - resulting region may be solidly colored, fully white, or anything in - between. - - The Artifex interpreter provides the full set of rendering algorithms that - use "predictable" halftones, and except for the case of the noise ordered - dither, the halftone used is identical to that used by HP devices prior - to the Color LaserJet 5/5M. The halftone provided for noise-ordered - dither is only roughly similar to that provided by HP, but this should - not cause a problem in practice. Though in principle "predictable", the - noise ordered dither used on HP devices is so large (128 x 128 pixels) - that no application could reasonably take advantage of its ordered - property. - - The Artifex interpreter provides no device-specific halftones because it - is impossible to know a priori what output device it will be used with. - Mechanisms are provided to allow device-specific halftones to be assigned - to specific rendering methods--see the accompanying interface description - for more information. All of the rendering algorithms that would normally - use a device specific halftone have been remapped to a method that uses - a predictable halftone. A mechanism is available for modifying this - mapping; again, see the interface document for details. - - The Artifex interpreter supports user-downloaded threshold (dither) arrays, - which are supported by all recent HP color devices except the Color - LaserJet 5/5M. If desired, this support can be disabled by remapping the - corresponding render algorithms (9 and 10) via the mechanism noted above; - by default, however, these are not remapped. - - In practice, this implies that halftoned output produced by the unmodified - Artifex PCL 5c interpreter will have a very different appearance from that - produced by the Color LaserJet 5/5M, even when the former is output on the - 5/5M. (There are also other complications, which are described further - below.) In general, the output from the Artifex interpreter will be similar - to that of the original Color LaserJet and the HP DeskJet 1200 and 1600 - C/CM printers. This is a reflection of a different configuration rather - than a fundamental difference in the interpreter. - - Raster Operations, device pixel depth - - In any industry that undergoes rapid technological evolution, any technical - term that becomes significant for purposes of marketing tends to lose its - technical meaning, as manufacturers shift the definition to show their - products in the best light. Such has been the case for the term "resolution" - when used with respect to inkjet and laser printers. - - HP does not provided a resolution specification for the Color LaserJet 5/5M. - It does, however, claim "1200 dpi" equivalent performance, via the use of - "resolution enhancement technology" (RET). - - Based on the traditional metric, namely, the thinnest horizontal and - vertical pure color line that can be drawn, the Color LaserJet 5/5M is - a 300 dpi device. The resolution enhancement technology used by HP - provides for more rapid modulation of the laser in the fast-scan - direction (the long edge of a letter or A4 page). This is used as part of - a halftoning technique that produces thinner lines in the slow-scan - direction than would be indicated by the 300 dpi resolution. This makes - the printer somewhat of a contone device, with between 8 and 16 levels - per pixel in each color plane. - - Based on empirical evidence, HP does not make use of this contone capability - in a direct manner. Rather, the level used for a specific pixel is based - both on the color of that pixel and on the colors for a small number of - nearest neighbor pixels. A likely reason for this is that PCL rasters are - traditionally bi-level in each color plane (this is true for all of the - default or "fixed" color palettes), and the printer will only support - input resolutions to 300 dpi. - - A side-effect of this arrangement is to make the effect of general raster - operations completely unpredictable; indeed, much less predictable than - would be indicated by usage of "unpredictable" halftones. For actual - applications this is almost never visible, but in several of the tests - in the PCL 5c FTS, the results on the Color LaserJet 5/5M bear only - slight resemblance to what is documented and what is produced by other - PCL 5c printers. In these cases, the Artifex PCL 5c interpreter - follows the documentation, as the results produced by the CLJ 5/5M seem to - be extremely specific to that device. - - Color Correction - - The Color LaserJet 5/5M provides sets of two device dependent and three - device independent color spaces. One of the latter is not, however, a fully - device independent color space: the "Colorimetric RGB" space is documented - as a device independent color space but is implemented as a set of lookup - tables based on the device-dependent RGB space (all above board: this - arrangement is noted in the documentation). - - The implementation of the device dependent color spaces is simple enough, - with the exception of some peculiar color correction applied to the fixed - color spaces. The latter is discussed below. The implementation in the - Artifex code matches that of the Color LaserJet 5/5M quite closely in this - area, with the exception of the color correction anomaly. - - The device independent color spaces are another matter entirely. Nothing can - be said directly about the "Colorimetric RGB" space since this is not - actually supported. The documentation for this format does, however, include - several parameters whose significance is, at best, obscure. The definition - of the chromaticities of the primaries is straightforward enough, and the - specification of gamma parameters for the components is reasonably - standard (though why the language provides for both a per component gamma - specification and a per-component, per-color-space lookup table is less - clear). The gain parameter, on the other hand, is not standard, and we - could find no description in the literature as to what it might mean. Based - on empirical work using the luminance-chrominance color space (which uses - the same parameter for its base color space), we have implemented the - gamma and gain parameters as: - - out = 1.0 - (1.0 - pow(in, 1/gamma)) / gain - - The CIE L*a*b* color space provided by the Color LaserJet 5/5M is also - somewhat peculiar. Its most unusual property is that an L* value 0 does not - yield black but rather a fairly solid red. This leaves one at somewhat of a - loss as to what the L* parameter is intended to correspond to. In any event, - after prior discussions with the OEM customer, the Artifex interpreter - was built to use the CIE specified conversion from L*a*b* to XYZ (the - color rendering dictionary converts the latter to device colors). The - difference between the two is visible in several of the tests of the PCL - 5c FTS. - - The default color correction information provided with the Artifex - interpreter assumes the output device has uncorrected SMPTE primaries. This - is, of course, not likely to be correct for any actual output device. The - output observed using device independent color spaces will be incorrect - unless a suitable color rendering dictionary has been installed. How this - may be accomplished is described in the accompanying interface document. - - Device dependent color correction - - The fixed or "simple" color space palettes provided with the Color LaserJet - 5/5M are ostensibly variations of the device-dependent RGB color space. - However, unlike the latter, the "simple" color spaces produce different - results when used for raster as opposed to geometric objects: red becomes - orange, green becomes notably lighter in shade, cyan becomes nearly blue, - and blue becomes deep purple. This effect is quite noticeable and is only - present on the Color LaserJet 5/5M; other HP printers do not show this - effect. - - Because rasters rendered with the simple color spaces generate output much - more "quickly" than rasters generated with the equivalent writeable color - palette by a factor of about 3, it is our belief that the simple color - space raster palettes represent the true colors of the device primaries, - and that color correction is applied to colors used with geometric objects - to make them more nearly match what is expected of these colors. - - The Artifex PCL 5c interpreter does and, and indeed cannot, provide the - same form of correction. In the 5c interpreter, geometric and raster - objects that use the same color will have identical appearance. Hence, - rasters produced with simple color space in the Artifex interpreter will not - have the same appearance as those produced by the Color LaserJet 5/5m. - - View Illuminant - - For reasons that are likely specific to the implementation, the view - illuminant setting on the Color LaserJet 5/5m only affects rasters, not - geometric objects. The Artifex interpreter does not replicate this - behavior: the view illuminant setting affects all output. This leads to - different output on one of the tests of the PCL 5c FTS. - - Default Colors - - HP specifies that up to the first eight entries of each palette be given - a set of default, device dependent primary colors. Furthermore, these colors - are not affected by color lookup tables for the device independent color - spaces, but are affected by lookup tables for the appropriate device - dependent color space. - - This effect is difficult to achieve given the design of the Artifex - interpreter and its underlying graphic library. The effect is also of - questionable merit: why use a device-dependent default color with a - device independent color space? Hence, in the Artifex interpreter, the - default colors used with device independent color spaces are themselves - device independent, and are affected by all applicable color lookup - tables. - - Transparency - - The implementation of transparency in the Artifex PCL 5c interpreter - closely follows that of HP interpreters, with one major exception. In HP - interpreters, the determination of which colors are white is made at the - device level, immediately before dithering. In the Artifex interpreter, - the same determination is made at the source color level, after consider- - ation of the black and white reference points but before any other color - transformation. This is arguably a bug but one that is difficult to remedy - given the design of the underlying graphic library. - - In practice, this difference is not visible in application files, and is - visible in test files in only two cases: when using an inverting color - lookup table, and when using rendering algorithm 2 (map black to white and - all other colors to black). Both of these situations arise in a small - number of tests in the PCL 5c FTS. - - Pixel Placement - - Though the definition of pixel placement is consistent across all PCL 5c - implementations from HP, the set of objects affected is not. In all cases - pixel placement affects rectangles in PCL and polygon fills in GL, and do - not affect PCL rasters. For all devices except the Color LaserJet 5/5M, - pixel placement does not affect text; this is also the documented behavior. - For the CLJ 5/5M, pixel placement affects the rendering of scalable fonts, - but does so in a manner not consistent with its effects on other objects - (an extra pixel is added on each side of the character, as opposed to just - the right and bottom sides). - - The Artifex PCL 5c interpreter adheres to the documented behavior: only - PCL rectangles and polygon fills in GL/2 are affected by pixel placement - (currently there is a bug that causes the pixel placement command in - GL/2 to have incorrect behavior, but the design intent is as stated). - - Driver configuration parameters - - The Artifex PCL 5c interpreter does not implement the driver configuration - command. This causes several tests near the end of the PCL 5c FTS to - produce different results than is the case for the Color LaserJet 5/5M. - - - -Difference in specific tests of the PCL 5c FTS - -54: - - The line "12345..." is printed in an 8 pt. version of the default - proportionally spaced font. In the Artifex interpreter, this is a Times - font, as it is for the Color LaserJet 5/5M, but not with the same spacing. - -65, 75, 85, 95, 103: - - The raster in each of these tests is printed in a "simple" color space - (fixed palette). As described above, the colors in these color spaces - vary between geometric objects and rasters for the Color LaserJet 5/5M, - but not for the Artifex interpreter. Hence, the colors for the raster - will appear different in the two interpreters. - -140, 143: - - The vertical bar character is from the bitmap lineprinter font on - the HP and from the Courier font on the Artifex interpreter, hence - the differences in the length of the bars. - -273, 274, 275, 276, 284, 285, 286: - - Symbol set differences. - -310, 320: - - These two panels are printed with the printer's "line printer" font. - On the HP DJ 1600C/CM and the CLJ 5/5M, this is a bitmap font that is - not scalable and is offered in only one size, hence its size does not - change with pitch. On the Artifex system, the scalable Courier font is - substituted for the line printer font. This font does change pitch as - requested in the tests. - -403, 412: - - The Univers Condensed font provided with the Artifex PCL interpreter - has all characters condensed. In the version of the same font provided - by HP, certain "universal" characters (characters that are independent - of font style), are not condensed. - -411 (et. al.): - - The lower case 't' in the downloaded Park Avenue font contains a malformed - outline. This is handled differently by the Intellifont font scaler - provided with the Artifex PCL interpreter than by the scaler provided with - HP PCL implementations. - -422: - - The default vertical offset applied to floating underlines by the Artifex - PCL interpreter is not the same as that provided by HP PCL interpreters. - -441 - 443, 450 - 512: - - The fonts provided with the Artifex PCL 5 interpreter are TrueType fonts, - which use the Unicode encoding scheme. The corresponding fonts in the - Color LaserJet 5/5M are Intellifont fonts, which use the MSL encoding - scheme. Thus, downloaded symbol sets that use the MSL coding scheme - can be used with the resident fonts of the Color LaserJet 5/5M, but not - with the resident fonts provided with the Artifex interpreter. Similarly, - downloaded symbol sets that use the Unicode encoding scheme can be used - with fonts provided with the Artifex interpreter, but not with those - provided with the CLJ 5/5M. - -520, 521: - - Symbol set discrepancies. - -680 - 682: - - These rasters are generated in a simple color space, and thus have the color - anomalies described in the first section of this document. - -701: - The length of the bitarray for the third and fourth pair of raster - (magenta and yellow) differ from those on the HP CLJ 5/5M. - - The output of the Artifex interpreter matches that of the HP DJ 1600C/CM. - The output of the CLJ 5/5M is contrary to the documentation, and likely - a limitation of the particular implementation due to the interaction - between rasters and the hardware dither method. - -714: - - On the Color LaserJet 5/5M, two of the white gaps between the cyan lines - appear to be wider than the others (after the 48th line and 98th cyan - lines). These larger gaps are not present in the input data, and are - probably due to a resonance phenomenon between the raster and the - resolution enhancement technology used by the CLJ 5/5M. This behavior - is not reproduced in the Artifex PCL 5c interpreter. - -721: - - This raster are generated in a simple color space, and thus has the color - anomalies described in the first section of this document. - -722: - - On the Color LaserJet 5/5M, the first of the shorter, magenta raster lines - appears to be thinner than the others. In the input data all of the lines - are the same width, and there is no apparent reason for the thinness of - the first line. The Artifex PCL 5c interpreter does not replicate this - anomaly. - -750: - - In the third row, the row with the greatest reduction in scale, the first - (thinnest) bar of the raster completely disappears on the Color LaserJet - 5/5M, but not with the Artifex PCL 5c interpreter. - - Whether a given artifact of a raster appears or disappears when scaled down - is a property of the specific raster scale implementation used. There is - no reason to expect the results to be the same across two implementations, - and little reason to try to make them the same. - -765: - - The output produced by the Artifex interpreter appears to be correct and - agrees with the output of the DJ 1600C/CM. The output on the CLJ 5/5M - differs, quite probably due to a physical limitation of the printer. - - This example involves scaled PCL rasters. Such rasters are clipped to the - the page's printable region. In PCL, a page is always assumed to have a 1/6" - unprintable margin. For this test all three of the rasters present are - scaled by a factor of 14.5. The middle (green) raster in the example has a - width of 25 samples, and is placed 205 pixels to the left of the right - printable margin. Hence, all of the first 14 samples should be visible - (14 * 14.5 = 203), as well as two pixels of the 15th sample. - - In this test, all raster sample lines are the same, and consist of the - following pattern (0 == white, 1 == color, either dark blue or green): - - 0000 0001 0000 0011 0000 0111 0 - - Hence, the 15th sample value is colored, and a two-pixel-wide sliver of this - sample should be visible. - -800 - 804: - - Each of the "bars" in these test are rendered in a different color space, - in the sequence RGB, CMY, Colorimetric RGB, CIE L*a*b*, Luminance- - Chrominance. The final three bars are in device independent color spaces, - hence their appearance will vary based on the color rendering - dictionary provided. - - Note also that fourth bar in tests 800 and 803 reflect the implementation - of the CIE L*a*b* color space in the Color LaserJet 5/5M, which renders - colors with the value of L* = 0 as red rather than black. - -811 - - Each raster in this example is rendered in a different color space, in the - sequence RGB, CMY, Colorimetric RGB, CIE L*a*b*, and Luminance-Chrominance. - Hence, the appearance of the last three rows will depend on the color - rendering dictionary provided. For the fourth raster, the different - implementations of the CIE L*a*b* color spaces is also evident. - -813: - The first two rasters are printed in RGB and CMY color spaces, with the - white and black points reversed. Due to an error in the implementation - of transparency in the CLJ 5/5M, this causes BOTH white and black to be - considered transparent, which in turn causes the center region to be - fully transparent. - - The Artifex implementation does not have this bug, hence either the - black triangles or the black background of this region is visible. - - The additional three rasters are printed in device-independent color spaces, - hence their appearance is dependent on the color rendering dictionary - provided. - -830, 831: - - A number of differences between the Artifex PCL 5c interpreter and the - CLJ 5/5M are visible in these tests: - - 1. The Artifex PCL 5c interpreter, in its default form, supports the - rendering methods with predictable halftones, and does not support - the rendering methods with unpredictable or device-specific halftones. - The CLJ 5/5M has the reverse arrangement. In particular, the Artifex - interpreter supports user downloaded dithers, which the CLJ 5/5M - does not. - - 2. The Artifex PCL 5c interpreter determines which pixels are "white" - for purposes of transparency prior to the effects of the color mapping - implied by the rendering algorithm; the CLJ 5/5M makes this same - determination after such color mapping. This is most visible in the - case of render algorithm 2 (prominent horizontal black lines in both - tests), where the output from the Artifex interpreter is transparent - while that of the CLJ 5/5M is opaque. - - 3. The Artifex PCL 5c interpreter, in common with most HP implementations - of PCL 5c, implements render algorithm 1 (snap to primaries) after - applying gamma correction. The CLJ 5/5M is exceptional in this area in - snapping the colors to primaries before applying gamma correction. - Hence, when using render algorithm 1, the output of the Artifex - interpreter (and most HP PCL 5c interpreters) is always a solid - primary color, while for the CLJ 5/5M it may be a halftoned color. - This difference is visible in the latter part of test 831. - - 4. The final two columns of tests 830 and 831 represent a non-solid - raster object combined with a non-solid foreground, using logical - operation 252. Especially for the larger gamma values, the appearance - of the result is critically dependent on the nature of the halftones - used for the raster and the foreground. In the Artifex PCL 5c - interpreter, the halftones used cause these regions to become white - more rapidly than is the case for the CLJ 5/5M. - -833: - - Each pair of lines in this example constitutes a pair of rasters. The - data for each raster pair is the same, only resolution is changed. - A bug in the CLJ 5/5M interpreter, also evident in test 701, results in - the improper rendering of raster output at 100 and 150 dpi in some - situations. The Artifex PCL 5c interpreter does not mimic this bug, - hence the different appearance of the output. - -853: - - The modified render algorithm referred to in the fourth line of this test - is render algorithm 10, monochrome user defined dither. This render method - is supported by the Artifex PCL 5c interpreter (in its default form), - but not by the CLJ 5/5M. Hence the different appearance. Note also that - the final foreground for the fourth line is used to draw the text for - the final, fifth line of the test, so its appearance is modified as well. - -860 - 865: - - See discussion for test 830 and 831. - -866: - - The different appearance of this test between the Artifex PCL 5c - interpreter and the Color LaserJet 5/5M is due to the different halftones - used. - -871: - - The final three rows of rectangles in this example are rendered in a device - independent color space, hence their appearance will depend on the nature - of the color rendering dictionary provided. In the default configuration, - these rectangles have a yellow hue where white would be expected. - -883: - - The output from the Artifex PCL 5c interpreter matches the documented - behavior, and the behavior of HP implementations other than the CLJ 5/5M. - For reasons that are not clear, the CLJ 5/5M will print a faint outline - of "Text" for the rightmost instance of this string in the first line - of the test. Examination under magnification reveals that this outline - is smaller than the design resolution of the device, so this may be a - print engine artifact. - -956: - - The rectangle on the right is printed with a transparent pattern. This - produces the expected output on the HP 1600C/CM and with the Artifex PCL - interpreter. It does not produce the expected output for the HP CLJ 5/5M, - apparently due to a bug. - - -974: - - See the discussion for test 830. This particular example also demonstrates - a situation in which different color mapping methods are being used for the - foreground and the raster being printed. For reasons that are not yet - clear, this (highly unusual) combination is not properly supported by the - graphic library underlying the Artifex PCL 5c interpreter. - -980, 981: - - 1. The raster operation mechanism of the CLJ 5/5M is broken, and thus - cannot be used as a reliable comparison (see notes at the start of - this document). - - 2. The implementation of opaque text for scalable fonts in the - Artifex PCL 5c interpreter is somewhat imperfect. The implementation - requires both inside and "outside" of a path to be filled, in - independent operations. The two filled regions do not join exactly, - hence a faint outline of the original character is usually visible. - - 3. When compared to the documented behavior, the behavior of the Artifex - interpreter varies in some of the opaque source, transparent pattern - cases. We have not yet analyzed why this is the case, but do not - expect it to cause difficulty in practice. - -983: - - The behavior of the Artifex PCL 5c interpreter matches the documented - behavior, and the behavior of HP devices other than the CLJ 5/5M. Raster - operations on the CLJ 5/5M are broken. - -1053: - - The behavior of the Artifex PCL 5c interpreter matches the documented - behavior, and the behavior of HP devices other than the CLJ 5/5M. The - behavior of the CLJ 5/5M is apparently a bug. - -1074 and 1084: - - The artifex interpreter's implementation of fill type 3 and 4 - (FT) differs slightly from HP. Artifex gl/2 vector fills always - radiate away from the origin in plotter units space. This can - cause slight discrepancies as evidenced in these two frames. - -1070: - The artifex interpreter always fills along +x and +y for hpgl/2 - vector fills. HP apparently fills in a direction related to the - direction of the graphical objects. We believe our interpretation - is follows the HP spec. - -1272: - - The gl/2 interpreter places scalable characters slightly to the - left, the discrepancy for a font scaled to 2" is about 1/16". - Attachment 1 below illustrates the problem. The GL/2 Label is - drawn then we return to pcl maintaining the current "y" coordinate, - select the same font and print the same string. The Artifex - interpreter produces the same output for each string, the expected - result. HP does not. - -begin 664 gl2chbug.pcl -M&T4;)3!"24X[4%<P.T94-"PV,RXU+#`[4$$P+#`[4E(U,#`P,"PU,#`P,#M0 -M5S`N,C4[1E0T+#4P."PP.U!!,"PP.U)2-3`P,#`L-3`P,#`[4%<P+C4[1E0T -M+#$P,38L,#M003`L,#M24C4P,#`P+#4P,#`P.QLE,4))3CM34#$[25`[4%<P -M+C`T.U-$-"PQ-#0L,BPQ+#<L-#$P,3M003`L-3`P,#M,0E!#3`-003`L,#L; -5)3%!&RAS,30T5ALH<S%04$-,&T4* -` -end - -1402 (et. al.): - - The filling of GL/2 polygon regions with lines in the Artifex PCL 5c - interpreter is not completely accurate. Line space and phasing are both - incorrect. These bugs are present in many other GL/2 tests as well. - -1422, 1423, 1424, 1445, 1446, 1462, 1463, 1801, 1803, 1811, 1817, 1894, 1895, 1941, 1946, -1950, 1951, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 2210 (page 1), 2220 (page 2) - - Artifex GL/2 contains minor discrepancies with anchoring line - fills. The problem is more evident in cases where scaling is - specified. Low priority. - -1463, 1463: - - The patterned line fills used in these two tests vary in appearance - between the CLJ 5/5M and the Artifex PCL 5c interpreter because - the latter does not properly set the phase of GL/2 line fills. - -1601, 1602: - - The GL/2 label printing command ("LB") in the Artifex PCL 5c interpreter - does not set the initial position of text correctly when printing in the - vertical direction. - -1641: - - The handling of horizontal tab in GL/2 differs between the Artifex PCL 5c - interpreter and the CLJ 5/5M. - -1642, 1650: - - The position of the label origin in GL/2 varies between the Artifex PCL 5c - interpreter and the CLJ 5/5M. - -1680: - - The character sets supported by the fonts used in Artifex PCL 5c - interpreter, in its default form, are not the same as those supported by - the fonts in the CLJ 5/5M. - -1752, 1753 (et. al.): - - The lower-case 'a' in the GL/2 stick font provided with the Artifex PCL 5c - interpreter is a different style than that of the stick font in the - CLJ 5/5M. This difference is also evident in other tests. - -1860, 1862, 1863: - - The position of the GL/2 label origin in the Artifex PCL 5c interpreter is - not accurate. This is particularly noticeable for arbitrary transformations - of text, as in the first two tests cited. - -2080: - - The scaling of the rightmost imported image in this test is - different than the HP printer. The artifex interpreter complies - with the HP PCLTRM. The following test shows that simply entering - and leaving HPGL/2 <ESC>%OB<ESC>%0A has the side effect of - resetting HPGL/2 scaling. This should not happen according to - PCLTRM 18-17. - - <ESC>E - <ESC>*c720X - <ESC>*c0T - <ESC>*c8.3K -(1) <ESC>%0B /* enter hpgl2/2 */ -(2) <ESC>%0A /* enter pcl */ - <ESC>*c420Y - <ESC>*c0T - <ESC>%1BSP2;PW0;IN;SP6;SC0,100,0,100;PA50,50;SC;SP7;CI450; - <ESC>%1A - <ESC>E - - the two commands (1) and (2) change the behavior the HP scaling - but not Artifex Scaling. If (1) and (2) are removed both HP and - Artifex produce the same results. - -2101, 2102: - - See comments for test 830 and 831. - -2106: - - Logical operations are broken on the CLJ 5/5M. The behavior of the Artifex - PCL 5c interpreter follows the documentation. - -2120, 2122: - - HPGL/2 pixel placement is implemented using the postscript - operator setfilladjust. The HP command definition is not consistant with - the behavior of the implementation and different devices (Color - Laserjet & 6MP) produce different results for each of these test files. - -2210 and 2220 (fourth page): - - SI, SR discrenpancy. - - -2322, 2323: - - Because the Artifex PCL 5c interpreter determines which regions are "white" - for purposes of transparency before taking into account any color lookup - table modifications, the white arrows in the center of these images are - considered transparent even in the center case (the inverting color - lookup table). Hence, for the inverting color lookup table case, the - central rectangle of the raster will be completely white. - -2330: - - The CLJ 5/5M does not support the viewing illuminant command; the Artifex - PCL interpreter does. - -2331: - - These rasters are rendered in a device independent color space, hence - their appearance will be dependent on the color rendering dictionary - provided. - -2351, 2352: - - The driver configuration command linearly maps saturation and - lightness arguments to pcl's gamma function. It is expected that - vendors will provide product specific code for this function. - -2412: - - After downloading a color lookup table, the monochrome palettes at the - bottom of the first and second pages of this test have one additional - black entry when rendered with the Artifex PCL 5c interpreter, as compared - to the output of the CLJ 5/5M. This problem has not been analyzed. - -PCL5c ATS Anomalies -=================== - - -ak506k21.bin: - - A PCL raster does not overlap an HPGL/2 line segment because the - line is not positioned exactly like HP due to a rounding - difference. The HP 1600C/CM also images this differently than - the HP Color Laserjet breaking only half of the line. After - rounding to the nearest pixel the ASI interpreter places the - raster rectangle one 300 dpi pixel below the gl/2 line. The HP - overlaps for at least one pixel on the 1600C/CM and the width of - the line on the Color Laserjet. - -fp309k22.bin: - - The right edge of the clipboard is missing. This is a font - rasterizer anomaly. The clipboard is a winding bitmap font and - images correctly at 600 dpi but is slightly clipped at 300 dpi. - -Qp606w21.bin: - - It is possible for the artifex interpreter to miss closing a - path in polygon mode under certain unusual conditions, due to - rounding problems. Here is a very simple example that - demonstrates the problem. This problem has only manifested in - problems of low visibility so we have not fixed it. - -begin 664 Qp606w21.bin.small -M&R4M,3(S-#580%!*3"!3150@4$%'15!23U1%0U0]05543PI`4$I,(%-%5"!2 -M15-/3%5424]./38P,`I`4$I,($5.5$52($Q!3D=504=%/5!#3`H;11LE,$)) -M3E-0,5!!4%<N-3M053(Q,C`L,SDT-CM033`[4$0[4%(M."PM,BPM-#8L+3$Q -?+#(R,2PM.#8W+"TQ-C<L.#@P.U!-,CM%4!LE,$$;10`` -` -end diff --git a/pcl/news-pcl b/pcl/news-pcl deleted file mode 100644 index 3f335f7fd..000000000 --- a/pcl/news-pcl +++ /dev/null @@ -1,2215 +0,0 @@ - Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. - Unauthorized use, copying, and/or distribution prohibited. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -This file, NEWS-PCL, describes the changes in the most recent releases -of PCL5e/c, entries are made in reverse chronological order. This -news file differs from other Aladdin news files it is automatically -generated from the revision control logs. The dates provided for each -entry are the dates the sources were committed to the source code -repository. - -Version 1.32 (01/12/00) -======================= - -Tue Jan 11 02:00:00 2000 GMT ray@artifex.com - - * pglabel.c [1.27]: - Change name of hpgl_select_font to prevent multiply defined symbol - when building with -DNOPRIVATE. - - -Wed Jan 5 03:00:00 2000 GMT Henry Stiles henrys@artifex.com - - * pgvector.c [1.16]: - stroke paths that get excessively large during PE (polyline encode). - This change was motivated by a performance problem in the test file - bwalldpf.pcl. - - * pgframe.c [1.10], pcstate.h [1.24], pcjob.c [1.17]: - Code to implicitly exit gl/2 when if we receive an ESC E while the - gl/2 parser is active. - - -Tue Dec 21 23:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglabel.c [1.26]: - clears the path after exiting label mode. - - -Tue Dec 21 22:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.51]: - The new pixel placement algorithm introduced several problems in the pcl5e ats because pcl was using and adjustment of 0.0 instead of 0.5. - - * pcfont.c [1.23]: - PCL did not correctly process corrupt files because the font selection - structures were not properly initialized without <ESC>E. - - -Mon Dec 13 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.50]: - The last change fixing pixel placement cause a bug with 0 width lines. - - -Mon Dec 13 00:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctext.c [1.25]: - The plot thickens. pcl double rounds truetype fonts - the scaling - factor and the final resulting width are integral in centipoints. - Other fonts, intellifont and bitmap only round the final width. - - * pgdraw.c [1.49]: - Uses gx_translate_path() to emulate pcl pixel placement. Also, we now - properly emulate gl/2 character fill, apparently characters are filled - first, then edged. Also the edging stroke must be done with the - default raster op. The combination of these two changes fixes the - problems on fts panels 2390, 2391, and other pixel placement panels. - - * pcl_ugcc.mak [1.25]: - pcl now uses cljet5pr, cljet5 is no longer longedge feed. - - -Mon Nov 29 01:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglabel.c [1.25]: - positioning of vertical labels was not correct. - - * pgvector.c [1.15], pgstate.h [1.9], pgpoly.c [1.10], pgdraw.c [1.48], - pgconfig.c [1.18]: - We now emulate the unusual HP Line Type 0 behavior (fixes fts panel - 1503) and phase of dashing has been fixed to exactly emulate hp (fixes - fts panels 1482, 1483, 1484 and others). The hp spec is not clear - exactly what happens when assymetric scaling is combined with vector - fills 3 and 4. We now apply the x and y scaling to x and y spacing - when the fill type is crosshatch (4) and apply the maximum spacing for - single line fills (fill type 3). This was done to fix fts panel 2380. - This entry and code mods are too "heavy", each of the problems above - should have been checked in separately. - - * rtraster.c [1.21]: - "CombineWithColor" was not properly set to false with thresholding - monochrome pcl configuration. - - * Anomalies.txt [1.16]: - Replaces gl/2 character anomaly test file with a smaller one. Adds a - new anomaly with an example illustrating a rounding difference between - HP and Artifex, the example was extracted from a "low priority" ats - test file. - - -Wed Nov 10 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * Anomalies.txt [1.15]: - Documents hpgl/2 character placement bug in HP printers. - - * pgdraw.c [1.47]: - Fixes hpgl (FT3 & FT4) polygon fills to support non-zero winding and - even odd filling. Thanks to Ray for finding this problem and - explaining my misuse of "clip". - - * rtgmode.c [1.15]: - Not properly converting coordinates from raster space to device space, - in some cases. Problem introduced with the last round of performance - improvements. - - -Fri Nov 5 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgconfig.c [1.17]: - fix for a font initialization problem. - - -Tue Nov 2 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpage.h [1.5], pcpage.c [1.33]: - the bounding box is now accessed through one pcl routine to prevent - duplicating the code everywhere. - - * pglfill.c [1.19], pgcolor.c [1.7], pcpatrn.c [1.21], pcpalet.c [1.16], - pclookup.c [1.4], pcfrgrnd.c [1.7], pccolor.c [1.7], pccid.c [1.11]: - adds configuration for pcl5e without the benefit of grayscaling to - improve performance. - - * pgdraw.c [1.46]: - It seems that HP would prefer 6 digits of accuracy while scaling. The - test file cd60bw22.bin actually requires this lesser accuracy to print - correctly. This fixes the stray lines on the baseball players face on - page 3. The truncation was empirically derived. - - * rtraster.h [1.6]: - This file should have been checked in with the raster speedup logged - below. - - * pctext.c [1.24]: - Performance modifications to print strings using xyshow for the common - cases instead of showing a single character at a time. - - * rtraster.c [1.20], rtgmode.c [1.14]: - Special speedup to handle an unusual class of pcl files that use - opaque source and transparent pattern raster with no background, we - use the pages bounding box to conservatively determine if the region - of interest (the area the raster will cover) is blank, then we can use - a simpler raster algorithm. - - -Tue Oct 26 19:00:00 1999 GMT ray@artifex.com - - * pcl_watc.mak [1.8], pcl_ugcc.mak [1.24], pcl_msvc.mak [1.7]: - Change to -include gsnogc.dev instead of explicit reference to gsnogc.obj. - Avoids linker unresolved / mulitply defined problems with async devices. - - -Mon Oct 25 21:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglfill.c [1.18], pgdraw.c [1.45], pgconfig.c [1.16], - pcursor.c [1.16], pctop.c [1.11], pcpage.c [1.32], pcommand.c [1.14]: - adds initializations needed after removing the clearing of the pcl - state structure. - - * pcl_ugcc.mak [1.23]: - adds jpeg driver and necessary jpeg source directory setting. - - * pctext.c [1.23]: - modification to round font width calculations to pcl current units. - - -Mon Oct 25 01:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtgmode.c [1.13]: - Raster state's graphics margin was not being reset when a pcl reset - was issued, potentially resulting in an obscure bug. If the margin - was set in raster mode and raster mode is subsequently entered - implicitly, after a reset, the graphics margin was improperly retained. - Running the fts test panels 2278-83 immediately followed by fts panel - 2290 improperly retains the graphics margin which resulting indirectly - in a misplaced vertical line. The probability of this occurring in - any real pcl file is very low. - - -Fri Oct 15 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctop.c [1.10]: - removes setting of the entire pcl state to 0 bugmask at the beginning - of a job. - - -Fri Oct 15 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.44]: - Adds a "moveto" the first point of a bezier curve if there is no - current subpath even if we are in polygon mode. - - -Thu Oct 7 07:00:00 1999 GMT ray@artifex.com - - * pglabel.c [1.24], pgfont.c [1.5]: - adds (void *) casts for some font related function to avoid the work - of (1) finding a reasonable set of include files for plchar.c and (2) - the indirectly related problem of derefencing pointers to the graphics - state whose type definition should be opaque. - - -Tue Oct 5 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcl_ugcc.mak [1.22], pcl_top.mak [1.19]: - Moves "FEATUREDEVS" back to the main makefiles. These were moved to - the top level makefile to avoid duplicating the definitions in each - file. Because pipe.dev must be included unix makefiles and not - microsoft (Watcom) environments different definitiion are required for - FEATUREDEVS. - - -Sun Oct 3 18:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctext.c [1.22]: - changes typedef from gs_show_enum to gs_text_enum_t. This one was missed - in the integration. - - -Sun Oct 3 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglabel.c [1.23], pgfont.c [1.4], pctop.c [1.9], pctext.c [1.21], - pcstate.h [1.23], pcl_top.mak [1.18]: - This is the first gs593 integration it is *NOT* a release. Normally - each file is checked in with an associated log entry, in order to - check in all of the code simultaneously we batch all of the file - name's modified and change descriptions here (Note: Aladdin code changes - are documented in gs/doc/News.htm) - - - pcstate.h - removes show enumeration from pcl state. - - pctop.c, pxtop.c - - gs_grestore_no_wraparound()'s is now gs_grestore_only(). - - pxgstate.c - - ENUM_RETURN_CONST_STRING_PTR() now takes a gs string - argument instead of the string's data as it did - previously. - - plmain.c - - - The library no longer initializes io devices. Adds - gs_iodev_init() to main() procedure. Also, gs_c_param_list_rewrite() - is renamed to gs_c_param_list_write_more(). - - pcltop.mak - adds pipe.dev for operating system pipe support. - - pctext.c, pglabel.c, pxfont.c, plfont.c - - extensive modifications to support the text api (gstext.h) - - use gs_text_enum_t instead of gs_show_enum. - - removes enumeration allocation, this is now done by the text - "begin" functions. - - update "next_char" procs and "encode char" procs to take a - glyph argument and the character argument is now passed by value - (pcl nor xl make use of the glyph argument). - - char_path_n_init() replaced with gs_charpath_begin(). - - gs_show_n_init() replaced with gs_show_begin(). - - gs_show_next() is now handled by gs_process_text(). - - gs_release_text() added. - - gs_xyshow_n_init() replace with gs_xyshow_begin(). Passing - of x and y coordinates modified to support the new interface. - Unfortunately, we need to transform the coordinates into the - space of the font scaling matrix, that is the current ctm for - xl when the the text is processed. This differs from postscript - which appears to have the regular user->device matrix in the - graphics state during processing. - - (plfont.c) - gs_notify_init() is now part of the pfont - initialization procedure, related TODO: cut over to gs_font_alloc() - and gs_font_base_alloc(). - - - all gs files - removes uninitialized rcs identifiers. - - KNOWN PROBLEMS: - - occassional pxl and pcl crashes in gdev_mem_set_line_ptrs() when - running in color due to null base (data) pointer. - - -Thu Sep 30 20:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgvector.c [1.14], pgdraw.c [1.43]: - Allowing unnecessary "pen ups" in polygon mode when placing beziers in - the polygon buffer. Fixes missing graphics in lotus 1-2-3 generated - files: ls40c1d3.bin and ls40d1d3.bin. - - -Wed Sep 29 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctop.c [1.8]: - The cursor pointer was not correctly updated to the beginning of the - UEL code int the stream when flushing to the end of a job. - - -Wed Sep 29 00:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgpoly.c [1.9]: - Corrects a typo in the last pgpoly.c fix that used the wrong pen state - structure. Thanks to Larry Baer for noticing this problem. - - -Sun Sep 26 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgvector.c [1.13]: - modified to ignore spurious pen ups in polygon mode to accomodate the - unusual pcl in ls4031d1.bin and ls4051d1.bin. - - * pgpoly.c [1.8]: - Exiting polygon mode should only have an effect if we are already in - polygon mode. This problem was discovered in two legacy dos lotus 1 2 - 3 files ls4031d1.bin and ls4051d1.bin. - - * pcsfont.c [1.18]: - The partial implementation of continuation (see below) did not allow - for more than one continuation command. This change should work - for any number of continuation commands. This fixes the truncated - large bookman font that prints the number '200' on fw21fww3.bin. - - * pglfill.c [1.17]: - In contradicton to PCLTRM Select Pen is not ignored in polygon mode. - This also fixes problems seen in legacy ls4031d1.bin and ls4051d1.bin. - NOTE: I have not tested if this is also true for polyline encoded - select pen command. - - -Wed Sep 22 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.42]: - normalizes angle on second pass of gl/2 vector fills to the 1st or 2nd - quadrant, specifically [0..PI). Fixes problem in test file c3.bin bug - number 199912. - - -Tue Sep 21 16:00:00 1999 GMT marcos@artifex.com - - * pctop.c [1.7], pcsymbol.c [1.13], pcfrgrnd.c [1.6], pcfont.c [1.22]: - Changed comments from // to /* */ - - -Mon Sep 20 17:00:00 1999 GMT marcos@artifex.com - - * pcl.mak [1.33]: - Changed version number. - - -Fri Sep 17 19:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgchar.c [1.13]: - In contradiction to PCLTRM 23-85 the HPGL/2 SD command permits the - same values for posture as pcl permits for the style attribute. The - possible values of 0, 1 and 2 on 23-85 are incorrect. - - -Fri Sep 17 09:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.41]: - Improves algorithm to determine if a path should be closed. We now - make comparisons of gl/2's first and last point of a subpath in device - space instead of user space. Fixes missing miter and join in test - file golfer.pcl. - - -Thu Sep 16 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpage.c [1.31]: - Proper "page feed if marked" logic for set paper source and set page - size commands. - - * pcjob.c [1.16]: - resets "parse other" to pcl upon receiving a printer reset in case we - received the command after entering gl/2 mode. Fixes the overlay - macro bug page 3 fts.2230. - - * pcjob.c [1.15]: - Proper "page feed if marked" logic for duplexing commands. - - -Fri Sep 10 09:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctext.c [1.20]: - Improperly qualifying an undefined glyph. In pcl parlance undefined - glyphs are space characters, for some reason this rule was not being - upheld in all cases. Fixes the bad spacing on page 1 of mc608w22.bin. - - * pcfont.c [1.21]: - The pcl font machinary was changed (see below) to maintain a flag in - the font selection state indicating if the font should be selected by - id. Unfortunately, we forgot to clear the flag when decaching font - and font selection parameters. This fixes the missing characters seen - on pcl5e ats file mc608w22.bin and others. - - -Fri Sep 10 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgchar.c [1.12]: - HP does not stop processing an SD or AD command because one or more of - the parameters are out of range, out of range parameters are skipped. - File bug410.pcl. - - * pcstate.h [1.22]: - This file should have been checked in with the change to implement - soft font continuation - see last entry for file pcsfont.c. This fixes - large missing 4 character in ats file pl30aw22.bin. - - -Fri Sep 10 01:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcsfont.c [1.17]: - soft font continuation support for uncompressed bitmap fonts. - - -Sun Sep 5 19:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpage.c [1.30]: - pjl wide a4 should only be in effect if a4 paper is selected. - - -Tue Aug 31 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcjob.c [1.14]: - The pcl duplex page side select command does not do an unconditional - page eject contrary to the documentation. - - -Sun Aug 29 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctext.c [1.19]: - Change to not automatically treat ascii character 32 as a space. As a - hack we only do this for internal fonts which shouldn't have a real - character mapped at position 32. Download fonts may hava a real - character mapped at position 32 in which case the escapement for the - character (not hmi) should be used. Thanks to Jan Stoeckenius for - fixing this one. - - -Wed Aug 25 22:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcfsel.c [1.13]: - fixes pitch selection problem - scalable fonts should score worst not - best when a fixed pitch font is requested. Improves font selection - debugging code, as well. - -Version 1.30 (08/25/99) -======================= - -Wed Aug 25 17:00:00 1999 GMT Marcos H. Woehrmann marcos@artifex.com - - * pcl.mak [1.32]: - Changed version number for release. - - -Wed Aug 25 16:00:00 1999 GMT Marcos H. Woehrmann marcos@artifex.com - - * pcl.mak [1.31]: - Changed version number to 1.10. - - -Wed Aug 25 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcursor.c [1.15]: - Horizontal relative cursor motion logical error fixed. Relative - cursor positions less than 0 were not handled correctly. - - -Tue Aug 24 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpage.c [1.29]: - Contrary to the documentation perforation skip does not reset the vertical - margins. - - -Tue Aug 24 01:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpage.c [1.28]: - setting the top margin has the side effect of resetting the y - component of the pcl cap. - - * pctop.c [1.6]: - adds initialization for language personality. - - -Thu Aug 19 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcl.mak [1.30.2.1]: - whitespace change. - - -Tue Aug 17 23:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtmisc.c [1.11], pcuptrn.c [1.16]: - clears the current path before entering gl/2 and adds support for an - undocumented user defined pattern type, format 20. - - -Fri Aug 13 17:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcl.mak [1.30]: - branches: 1.30.2; - Misspelling of a device resulted in not including initialization code - for the pgcolor module. Fixes black background regression present in - many of the ats files. - - -Wed Jul 28 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctop.c [1.5], pcsymbol.c [1.12]: - loading of the built in symbol sets is now a private procedure in - pcsymbol.c, invoked by the reset code. - - -Tue Jul 27 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcfont.c [1.20]: - When a font is selected by id simply decache and let it be reselected - when it is required. - - * pcsfont.c [1.16]: - Workaround - dictionary synynyms do not work properly with dictionary - enumerations when deleting all fonts. To work around this the - enumeration is reinitialized each time a font is deleted. - - * pgdraw.c [1.40]: - The gl/2's clipping region is rounded slightly differently on the - LJ6mp versus the Color Laserjet. Code change to emulate the 6mp for - now but work still in progress here. - - -Mon Jul 19 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtmisc.c [1.10], pglabel.c [1.22], pgdraw.h [1.8], pgdraw.c [1.39]: - hpgl/2 clipping region was not being set properly when rendering - characters (LB). The current transformation matrix did not account - for pcl text direction when the current position (cap) was imported - into the gl/2 coordinate system. - - * pgchar.c [1.11], pcsfont.c [1.15], pcfsel.h [1.6], pcfsel.c [1.12], - pcfontst.h [1.3], pcfont.c [1.19]: - Modification to always select fonts by id instead of selecting the - font by id and subsequently depending on the selection parameters to - uniquely determine the font. Also a minor change to decache the - currently selected gl/2 font when pcl fonts are decached, this - behavior is not documented in PCLTRM. - - * pcuptrn.c [1.15]: - Apparently raster fill unlike other fills take the resolution of the - device not the PCL documented 300dpi. - - -Thu Jun 17 20:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcsfont.c [1.14], pclfont.c [1.10], pcfont.c [1.18]: - releases pxl error page font and enumeration when shutting down an - interpreter instance. This required adding support to pl_font_t for - fonts with permenent data (data that should not be freed). - - -Wed Jun 16 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcmacros.c [1.9]: - release macro dictionary for permanent resets. - - -Tue Jun 15 19:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcht.c [1.17]: - revert back to our old reference count hacking. TODO: we initialize a - new color mapper device each time the rendering method changes, - requiring the hack to the reference counts. It would be much simpler - to set the rendering method by setting a parameter using one color - mapping device instead of juggling 4 separate color mapper devices. A - project for another day. - - * pcpalet.c [1.15]: - release of the default and current palette for permanent resets. Also - removes an unnecessary call to pcl_set_drawing_color() apparently used - to track down memory leaks. - - * pcstate.h [1.21]: - prototype for pcl_free_gstate_stk(). - - * pcfrgrnd.c [1.5]: - removes final references to current halftone, crd, color space and foreground - objects for permanent resets. - - * pcdraw.c [1.10]: - function to deallocate the pcl graphics state stack to be done during - interpreter deinit. - - -Mon Jun 14 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctop.c [1.4]: - adds assertions about the current device (bbox and special color - mapper) as pcl is shutdown. Free's pcl graphics state upon shutdown. - - -Mon Jun 14 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctext.c [1.18]: - pcl now gets the advance vector for each character directly from the - fonts for better performance. Previously gs_show_width() was used. - Also, obsolete font substitution has been removed. - - * pcfont.c [1.17]: - Adds decaching for fonts for shift in, shift out, and selection by id. - This was previously done awkwardly in pctext.c - - -Mon Jun 7 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pginit.c [1.13]: - frees polygon buffer when there is a permenant reset. - - * pcsymbol.c [1.11]: - frees soft and internal symbol sets when there is a permanent reset. - - * pctop.c [1.3], pcl.mak [1.29]: - adds debugging assertions for current devices while devices are being - removed from the pcl interpreter's instance. - - -Sun Jun 6 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pclver.h [1.3]: - remove automatically generated version file that was accidentally - added to the repository. - - -Sun Jun 6 00:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pctop.c [1.2], pcsymbol.c [1.10], pcommand.h [1.8], pclver.h [1.2], - pcfont.c [1.16]: - Adds a new pcl reset type, pcl_reset_permenant, used to get - rid of pcl permenant objects and internal objects normally - maintained across job boundaries. Adds functionality for - releasing the pcl the internal fonts. Moves loading of symbol - out of pctop.c. - - -Wed Jun 2 03:00:00 1999 GMT johnd@artifex.com - - * pgparse.c [1.8], pgmand.h [1.9], pcursor.c [1.14], pctop.h [1.1], - pctop.c [1.1], pcstate.h [1.20], pcsfont.c [1.13], pcpage.c [1.27], - pcommand.c [1.13], pcmain.c [1.33], pclver.h [1.1], pclfont.c [1.9], - pcl_watc.mak [1.7], pcl_ugcc.mak [1.21], pcl_top.mak [1.17], - pcl_sgi.mak [1.8], pcl_msvc.mak [1.6], pcl.mak [1.28], pcjob.c [1.13], - pcimpl.c [1.1], pcfont.c [1.15]: - Initial checkin for multiple language support, shared devices, - interpreter instances, interpreter initialization/de-initialization, - etc. A todo list of unfinished work is in pctop.c and pxtop.c. - - -Thu May 27 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcht.c [1.16]: - casts color mapper devices to normal devices for gx_device_retain and - fixes a typo. - - * pcpage.c [1.26], pcmain.c [1.32], pcl_top.mak [1.16]: - replace gsgc.h include with gsnogc.h - - -Wed May 26 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcht.c [1.15]: - replaces reference counting hack with gx_device_retain(). - - * pcht.c [1.14]: - adds calls to gx_device_retain, so that the color mapper devices will - not be inadvertantly freed. - - -Tue May 25 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcl_top.mak [1.15], pcl_msvc.mak [1.5]: - gs5.84 integration. Initialization of DD macro, initializes directory - location for device (.dev) files - - -Mon May 24 20:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtraster.c [1.19], pcuptrn.c [1.14], pcpage.c [1.25], - pcmain.c [1.31], pcl_ugcc.mak [1.20], pccid.c [1.10]: - initial gs5.84 checkin with pcl and xl compiling. - - -Tue May 18 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcursor.c [1.13]: - fixes static removal regression. The pcl cap can reside in the pcl - state but is not really part of the modified print environment. After - macro invocation, copy back the cap to simulate this behavior. - - -Mon May 17 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcstate.h [1.19], pcparse.h [1.5], pcparse.c [1.9], pcpage.c [1.24], - pcommand.c [1.12], pcmain.c [1.30], pcmacros.c [1.8]: - modifications to get max stack usage for pcl_execute_macro() down from - 56K to 38K. To be continued. - - -Mon May 17 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglabel.c [1.21]: - corrects typo and fixes a compiler warning introduced in the last - modification. - - -Mon May 17 05:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcuptrn.c [1.13]: - removes unnecessary header file. - - * rtgmode.c [1.12]: - raster source width and source height were calculated incorrectly when - not given explicity. This caused the bounds of the image to be larger - than the extant the of the clipping rectangle for the page, resulting - in expensive and unnecessary calls to gx_default_fill_triangle from - the bbox device. - - * pgvector.c [1.12]: - hpgl/2 will now allow round joins with beziers, other joins - default to bevel. - - * pglabel.c [1.20]: - The labeling code is now more liberal about using "show" and the - graphics library character cache instead of drawing characters with - the gl/2 line drawing code. This change speeds up the fts about 20%. - Effects on other test are not likely to be as significant since most - applications don't use gl/2's LB as frequently as the fts tests. - - -Thu May 13 04:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglfill.c [1.16]: - removes obsolete comment. - - * pcuptrn.c [1.12]: - properly initialize pattern reference point and orientation. - - -Wed May 5 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtraster.c [1.18], rtmisc.c [1.9], rtlrastr.c [1.6], rtgmode.c [1.11], - rtcursor.c [1.6], pgvector.c [1.11], pgstate.h [1.8], pgpoly.c [1.7], - pgparse.c [1.7], pgmand.h [1.8], pglfill.c [1.15], pglabel.c [1.19], - pgframe.c [1.9], pgconfig.c [1.15], pgcolor.c [1.6], pgchar.c [1.10], - pcursor.c [1.12], pcrect.c [1.12], pcpatxfm.c [1.7], pcpatrn.c [1.20], - pcparse.c [1.8], pcpalet.c [1.14], pcommand.h [1.7], pclfont.c [1.8], - pcl.mak [1.27], pcjob.c [1.12], pcfont.c [1.14], pccprint.c [1.7], - pccolor.c [1.6], pccid.c [1.9]: - Fixes 2 problems with polyline encoding: After PE is executed, the - previous plotting mode (absolute or relative) is restored, but the pen - up and down status is maintained. - - Simplification of RTL configurations - allows dynamic selection of - commands in pcl or rtl mode. The rtl interpreter will now run without - TrueType fonts being loaded, only stick and arc fonts are accessed - through hpgl's LB instruction. - - Unnecessary path clearing removed when plot mode changes. - - -Sun May 2 00:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pclfont.c [1.7]: - PCL now exits with an error message(s) if internal fonts cannot be - found. - - -Thu Apr 29 00:00:00 1999 GMT Marcos H. Woehrmann marcos@artifex.com - - * pcparse.c [1.7]: - Changes to const and private for msvc. - - -Mon Apr 26 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pginit.c [1.12], pgframe.c [1.8], pgdraw.c [1.38], pgconfig.c [1.14], - pcursor.h [1.5], pcursor.c [1.11], pctext.c [1.17], pcstate.h [1.18], - pcpage.h [1.4], pcpage.c [1.23], pcmain.c [1.29]: - Modifications for RTL/GL2 mode, these changes are only relevant to RTL - not pcl5c or pcl5e: (1) Adds rtl personality to pcl state and factory - defaults (2) sets page size offsets to zero (3) changes clipping - region to not use the pcl default setting of a 1/6" margin around the - page (4) export pcl's new logical page and pcl's form feed procedure - for use by gl/2's plot size (PS) and advance full page (PG) (5) - Ignores text (6) Adds more implementations to plot size and advance - page size (these commands are not complete) (7) defines rtl coordinate - system for cases plot length < plot width and plot length > plot width - (8) change gl/2 picture frame to have the same extant as the logical - page size. (9) defaults gl/2's anchor point to have coordinate 0, 0 - (having no effect on the coordinate system). - - -Mon Apr 26 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcpalet.c [1.13]: - modification to get around const warning. - - -Mon Apr 19 20:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcmain.c [1.28]: - removes external declarations that are now properly done in gxalloc.h. - - -Wed Apr 14 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcstate.h [1.17], pcpalet.c [1.12], pcindxed.h [1.5], - pcindxed.c [1.4]: - Removes a global variable and a static local to a function, both - supporting indexed color spaces. - - -Tue Apr 13 20:00:00 1999 GMT ray@artifex.com - - * pgparse.c [1.6]: - Add initialization for hpgl parser. Fixes exception error. - - -Tue Apr 13 06:00:00 1999 GMT ray@artifex.com - - * pclookup.h [1.4]: - Add extern to prevent multiple definition linker errors. - - * rtrstst.h [1.5]: - Add comment delimiters following #endif to prevent warning. - - * rtrstcmp.h [1.4]: - Add missing 'extern' to prevent multiple definition link errors. - - * pcpalet.c [1.11]: - Change to use defining macro for pstack_entry (see change in pcpalet.h). - This definition only here, others do not cause multiple def'n link errors. - - * pcpalet.h [1.7]: - Add defining instance macro for pstack_entry to prevent multiple def'n - link errors. - - -Tue Apr 13 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtrstst.h [1.4], rtraster.h [1.5], rtraster.c [1.17], - rtmisc.c [1.8], rtlrastr.c [1.5], rtgmode.c [1.10], rtcursor.c [1.5], - pgvector.c [1.10], pgpoly.c [1.6], pgparse.c [1.5], pgmand.h [1.7], - pglfill.c [1.14], pglabel.c [1.18], pgframe.c [1.7], pgconfig.c [1.13], - pgcolor.c [1.5], pgchar.c [1.9], pcursor.c [1.10], pcuptrn.c [1.11], - pctext.c [1.16], pcsymbol.h [1.5], pcsymbol.c [1.9], pcstatus.c [1.8], - pcstate.h [1.16], pcsfont.c [1.12], pcrect.c [1.11], pcpatxfm.c [1.6], - pcpatrn.h [1.10], pcpatrn.c [1.19], pcparse.h [1.4], pcparse.c [1.6], - pcpalet.h [1.6], pcpalet.c [1.10], pcpage.c [1.22], pcommand.h [1.6], - pcommand.c [1.11], pcmisc.c [1.5], pcmain.c [1.27], pcmacros.c [1.7], - pclookup.c [1.3], pcl.mak [1.26], pcjob.c [1.11], pcident.h [1.4], - pcident.c [1.3], pcfrgrnd.h [1.4], pcfrgrnd.c [1.4], pcfont.c [1.13], - pcdither.c [1.4], pccsbase.h [1.6], pccsbase.c [1.9], pccrd.h [1.6], - pccrd.c [1.9], pccprint.c [1.6], pccolor.c [1.5], pccid.c [1.8]: - WARNING: changes pending - do not release. First stable pcl checkin - with no statics and general code clean up. Modifications for pcl - raster, parser, color, foreground, palette and hpgl/2 parser. - - -Thu Apr 8 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtrstcmp.h [1.3], rtraster.h [1.4], rtgmode.h [1.4], pgmisc.h [1.4], - pginit.h [1.5], pcwhtidx.h [1.3], pcursor.h [1.4], pcuptrn.h [1.5], - pcstate.h [1.15], pcpatxfm.h [1.3], pcpatrn.h [1.9], pcpatrn.c [1.18], - pcparam.h [1.6], pcpalet.h [1.5], pcpalet.c [1.9], pcpage.h [1.3], - pcmtx3.h [1.5], pclookup.h [1.3], pcl.mak [1.25], pcindxed.h [1.4], - pcident.h [1.3], pcht.h [1.6], pcht.c [1.13], pcfrgrnd.h [1.3], - pcfont.h [1.5], pcdraw.h [1.4], pcdither.h [1.3], pccsbase.h [1.5], - pccrd.h [1.5], pccid.h [1.5], pcbiptrn.h [1.6], pcbiptrn.c [1.7]: - extensive changes to support static removal from the pcl halftone - code. Removes use of extern in prototypes and adds the standard - prototype macros for argument templates. Adds support for device - resolution patterns. - - -Tue Apr 6 02:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglfill.c [1.13]: - hpgl_MC now draws the current path first even if the command fails. - - * pcuptrn.c [1.10], pcstate.h [1.14], pcrect.c [1.10], pcpatrn.c [1.17], - pcl.mak [1.24], pcbiptrn.h [1.5], pcbiptrn.c [1.6]: - pcl static removal - removes statics from the pattern building machinery. - - -Fri Apr 2 07:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtmisc.c [1.7], rtlrastr.c [1.4], rtgmode.c [1.9], rtcursor.c [1.4], - pgstate.h [1.7], pglabel.c [1.17], pginit.h [1.4], pginit.c [1.11], - pgframe.c [1.6], pcxfmst.h [1.3], pcursor.h [1.3], pcursor.c [1.9], - pctext.c [1.15], pcsymbol.h [1.4], pcsymbol.c [1.8], pcstatus.c [1.7], - pcstate.h [1.13], pcsfont.c [1.11], pcrect.c [1.9], pcpatxfm.c [1.5], - pcparse.h [1.3], pcparse.c [1.5], pcpage.c [1.21], pcommand.h [1.5], - pcmisc.c [1.4], pcmain.c [1.26], pcmacros.c [1.6], pclfont.c [1.6], - pcjob.c [1.10], pcfsel.h [1.5], pcfsel.c [1.11], pcfont.h [1.4], - pcfont.c [1.12], pccoord.h [1.3], pccid.h [1.4]: - Static removal phase 2. Moves pcl cursor (cap) back into pcl's state, - along with the cursor stack and stack size. Also, PCL was referencing - the state using the names pcs or pcls, now we use pcs only. - - -Thu Apr 1 09:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcuptrn.h [1.4], pcuptrn.c [1.9], pcstatus.c [1.6], pcstate.h [1.12], - pcrect.c [1.8], pcpatrn.c [1.16]: - pcl static removal phase 1 - removes all statics associated with pcl - and gl/2 patterns. - - -Tue Mar 30 19:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.37]: - The number of lines filled was not being updated after drawing the - line instead of before. - - -Fri Mar 26 18:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglabel.c [1.16]: - changed stick font compliment, Accents are not supplied by stick font. - - * pcmain.c [1.25]: - increases parse buffer size to a reasonable size. - - -Wed Mar 24 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pglfill.c [1.12], pgdraw.c [1.36]: - fixes initialization problem with LT and reworks most of the logic in - hpgl_LT(). - - -Tue Mar 23 20:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.35]: - Set character edge line width as a function of the point size. The - proportion was derived empirically to be line width = 0.0375 * font - points size in quarter points. This is not specified in the HP - documentation. - - -Sun Mar 21 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.34]: - make sure we clear the path if there is no gl/2 subpath. - - -Fri Mar 19 06:00:00 1999 GMT jan@artifex.com - - * pcht.c [1.12]: - makes sure first default color mapper device reference count does not - become 0. - - -Tue Mar 16 08:00:00 1999 GMT jan@artifex.com - - * rtrstst.h [1.3], rtraster.c [1.16], rtgmode.c [1.8]: - Fix to properly clip rasters. A detailed explanation of this change - is in the header file pcl/rtrstst.h, item 4. - - -Tue Mar 16 08:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgdraw.c [1.33]: - changes to support opaque gx_path - - -Sat Mar 13 22:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pcommand.c [1.10], pcmain.c [1.24]: - Modified to use gs_state_setdeviceparams in lieue of gs_deviceparams. - Removes redundant calls to gs_clippath() and gs_state_set_client(). - - -Mon Mar 8 06:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * rtraster.c [1.15]: - The "clearing" of planes not provided has been moved to the - process_row routine (it was in transfer_raster_row). To - facilitate this change the current compression mode is now an - operand of process_row. - - The code that handles repeated rows in process_adaptive_compress - has been modified to use its fast-case only if the number of planes - is 1. Otherwise, it repeatedly calls process_row. - - The check test for nplanes == 1 in the adaptive compression case - in add_raster_plane has been removed; the routine will now only - check that the plane data is from a transfer_raster_row command - rather than a transfer_raster_plane command. - - -Mon Mar 8 03:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgvector.c [1.9]: - more careful placement of the center point in CI to avoid inadvertant - implicit closepath. - - -Mon Mar 8 00:00:00 1999 GMT Henry Stiles henrys@artifex.com - - * pgmand.h [1.6], pglfill.c [1.11], pgdraw.c [1.32], pgconfig.c [1.12]: - more emulation of hp bugs: LT with no parameters does not in fact - reset the line patterns it only sets the current line type to solid. - - - -Version 1.07 (03/04/99) -======================= - -Thu Mar 4 20:00:00 1999 Henry Stiles henrys@artifex.com - - * pcl_top.mak [1.14]: - version number updated. - - -Thu Mar 4 08:00:00 1999 Henry Stiles henrys@artifex.com - - * Anomalies.txt [1.14]: - adds 2 new ats anomalies. - - -Thu Mar 4 03:00:00 1999 Jan Stoeckenius,,,, jan@artifex.com - - * rtraster.c [1.14], Anomalies.txt [1.13]: - Adds fts 765 and reverts adaptive compression fix. - - -Wed Mar 3 08:00:00 1999 Henry Stiles henrys@artifex.com - - * rtmisc.c [1.6]: - hpgl/2 does not free the polygon buffer when entering pcl. - - * pclfont.c [1.5]: - Albertus Medium was incorrectly identified with weight 0 instead of 1. - - -Tue Mar 2 07:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.31]: - new evidence from the ats test indicates the IW soft clip command - defines a half-closed clip box and the hpgl/2 picture frame defines an - closed clip box. Also add more path and clip path debugging - information for hpgl/2. - - -Mon Mar 1 08:00:00 1999 Henry Stiles henrys@artifex.com - - * pgconfig.c [1.11]: - IW was not stroking the current path unless parameters were given. - - -Mon Mar 1 05:00:00 1999 Henry Stiles henrys@artifex.com - - * pgconfig.c [1.10]: - 2 current ctm fixes: SC does not reset the ctm before deriving the - current user position in device space, and the routine to get the - default picture frame did not properly restore the ctm. - - -Sun Feb 28 07:00:00 1999 Henry Stiles henrys@artifex.com - - * pglabel.c [1.15], pgdraw.c [1.30]: - corrects label offset calculation when SI and SR are enabled. - - -Fri Feb 26 05:00:00 1999 Jan Stoeckenius,,,, jan@artifex.com - - * pccid.c [1.7]: - HP ignores the bits-per-primary setting for device-independent color - spaces, and always uses [255, 0] as white and black reference points for these - spaces. - - We have modified the routine check_cid_hdr in pccid.c to set bits-per-primary - to 8 for all device-independent color spaces. The modified file is attached. - - -Thu Feb 25 09:00:00 1999 Henry Stiles henrys@artifex.com - - * pgvector.c [1.8]: - It is not necessary to return to the starting point of a circle when - drawing in polygon mode. - - -Thu Feb 25 08:00:00 1999 Henry Stiles henrys@artifex.com - - * rtgmode.c [1.7]: - rtgmode.c was truncated at the last checkin (not analyzed). - - -Thu Feb 25 04:00:00 1999 Jan Stoeckenius,,,, jan@artifex.com - - * rtgmode.c [1.6]: - Fixes ats file floating poing rounding and truncating error. For the - particular transformation in effect, the initial horizontal position - of 7008 centi-points would come back as 7007.9994... centi-points, - which was converted to 7007 centipoints, which would come back as - 7006.9994... centi-points, and so on. The process finally stopped at - about 6600 centi-points, due to a change in the least significant bit - of the tx field of transformation matrix. Now we round the calculated - centipoint position before converting to an integer. - -Version 1.06 (02/24/99) -====================== - -Wed Feb 24 11:00:00 1999 Henry Stiles henrys@artifex.com - - * pcstate.h [1.11], pcsfont.c [1.10], pcpage.c [1.20], pcmain.c [1.23], - pclfont.c [1.4], pcl.mak [1.23], pcfont.c [1.10]: - Modifications to support PJL fontsource and fontnumber environment - variables. - - -Fri Feb 19 00:00:00 1999 ray@artifex.com - - * pcl_watc.mak [1.6]: - Fix problems that kept this from working. Change to make 32-bit tools and - target the default. Update it to work with the new directory structure. - This is probably the first workable version for Watcom. - - * pcindxed.h [1.3], pcindxed.c [1.3]: - Change cs_indexed_..._ptrs to pcl_cs_indexed_..._ptrs to prevent conflict - with gscolor2.c when building NOPRIVATE=1. - - -Thu Feb 18 23:00:00 1999 ray@artifex.com - - * pcl_top.mak [1.13]: - Fix building of pclver.h to use '-x 23' instead of '#' which breaks under - Watcom/Dos. - - * pcl.mak [1.22]: - Fix PCLCCC to use $(I_) macro instead of hard coded -I which doesn't work - on Watcom, VMS, etc. - - -Thu Feb 18 06:00:00 1999 Henry Stiles henrys@artifex.com - - * Anomalies.txt [1.12]: - removes pcl clipping region bug - not actually a bug but a problem - with the device driver. - - * Anomalies.txt [1.11]: - removes clipping anomaly. - - * pgdraw.c [1.29], pcpage.c [1.19]: - Rounding of device clip boxes and ctm translation components. Also, - modifies GL/2 to use a closed clipping region instead of the default - half-open region. - - -Wed Feb 17 08:00:00 1999 Henry Stiles henrys@artifex.com - - * pgchar.c [1.8], pcursor.c [1.8], pcl.mak [1.21], pcjob.c [1.9], pcfont.c [1.9]: - modifications to support PCLXL processing of PJL. - - -Tue Feb 16 00:00:00 1999 Henry Stiles henrys@artifex.com - - * pglabel.c [1.14]: - moves SR, SI line spacing hack to cursor positioning routine. - - -Sun Feb 14 08:00:00 1999 marcos@artifex.com - - * rtraster.c [1.13]: - Added check for adaptive compression mode in transfer_raster_row() - to avoid duplicating last line of raster data (fixes fts.0717). - - -Sun Feb 14 06:00:00 1999 marcos@artifex.com - - * rtraster.c [1.12]: - Fixed problem with adaptive compression (if the last command was repeat - previous row it was ignored, showed up in adaptivecompression.pcl). - - -Sat Feb 13 20:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.28]: - hpgl/2 vector fills now support assymetric scaling properly. - - * pgconfig.c [1.9]: - draws the current path when IP is issued. - - * pglabel.c [1.13]: - corrects multiplier for cell height. - - -Sat Feb 13 06:00:00 1999 Henry Stiles henrys@artifex.com - - * pglabel.c [1.12]: - modified to properly handle label placement with SI, SR. - - -Sat Feb 13 05:00:00 1999 Henry Stiles henrys@artifex.com - - * pglfill.c [1.10]: - removes obsolete comment. - - -Sat Feb 13 00:00:00 1999 Henry Stiles henrys@artifex.com - - * pgfont.c [1.3], pgdraw.c [1.27]: - all labels use round caps and round joins. - - -Fri Feb 12 05:00:00 1999 Henry Stiles henrys@artifex.com - - * rtraster.c [1.11]: - removes optimization that prints raster as rectangle. The code only - worked properly with short edge feed devices. We might reimplement - this in the future if this part of the code is indeed a performance - bottleneck. - - -Fri Feb 12 03:00:00 1999 Henry Stiles henrys@artifex.com - - * pgvector.c [1.7], pgstate.h [1.6], pglfill.c [1.9], pglabel.c [1.11], - pginit.c [1.10], pgdraw.c [1.26], Anomalies.txt [1.10]: - Improvement of fill line anchoring in gl/2. Now use gl/2's position - in user space instead of tracking device space position, which - resulted in rounding errors when tranforming and doing comparisons. - Label code updated to use gl/2 line drawing instead of using gs - functions directly. Also we now draw the current path when the for - relative/absolution mode changes in the pen. Updates Anomalies.txt to - reflect changes. - - -Thu Feb 11 18:00:00 1999 ray@artifex.com - - * pcl.mak [1.20]: - Remove the extra space after $(O_). This messes up platforms which cannot - have a space. Correct fix is to define O_ correctly for platforms that - require a space. See common/unixdefs.mak where O_=-o $(NULL). - - -Mon Feb 8 09:00:00 1999 Henry Stiles henrys@artifex.com - - * pcsfont.c [1.9], pcparse.c [1.4]: - Quiets pcl in DEBUG mode. - - -Sun Feb 7 09:00:00 1999 Henry Stiles henrys@artifex.com - - * pglfill.c [1.8], pglabel.c [1.10], pgdraw.h [1.7], pgdraw.c [1.25], pgchar.c [1.7]: - Addition to properly select and wrap the current pen. Adds an - accessor function for getting the currently selected pen. - - * pcpatrn.c [1.15]: - Sample implementation of driver configuration. - - * Anomalies.txt [1.9]: - removes bezier problem. - - -Sun Feb 7 08:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.24]: - fixes a stupid typo that was messing up the clipping region in gl/2. - - -Fri Feb 5 18:00:00 1999 marcos@artifex.com - - * pcl.mak [1.19]: - Added space for solaris gcc: $(O_) $(PCLOBJ). - - -Fri Feb 5 06:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.23]: - set dot orientation immediately after setting the ctm. - - * pgvector.c [1.6]: - a hack to clear the current path before printing bezier curves. The - drawing machinery is not set up to apply line joins between lines and - curves. Lines of zero length are frequently used to set up for - drawing a bezier. We clear these points so they will not print as - "orthogonal dots". - - -Thu Feb 4 00:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.22], pcpage.c [1.18]: - intersect pcl's clipping region with the hardware margins. - - -Mon Feb 1 19:00:00 1999 marcos@artifex.com - - * pcl_ugcc.mak [1.19]: - Added bmpa32b.dev device. - - -Mon Feb 1 19:00:00 1999 Henry Stiles henrys@artifex.com - - * Anomalies.txt [1.8]: - updates for recent fixes. - - -Mon Feb 1 02:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.21]: - modifications to support dot orientation. HPGL/2 dots (zero length - lines) are always drawn parallel to the HPGL/2 X-axis. Also, makes - dot orientation independent of device space. - - -Sun Jan 31 06:00:00 1999 Henry Stiles henrys@artifex.com - - * rtmisc.c [1.5], pgvector.c [1.5], pglabel.c [1.9], pgdraw.h [1.6], pgdraw.c [1.20], - pgconfig.c [1.8], pgchar.c [1.6]: - Properly update carriage return position when entering HPGL/2 with the - the current pcl cap. Provides a function for updating a carriage - return position to the current position. - - -Sat Jan 30 22:00:00 1999 Henry Stiles henrys@artifex.com - - * pccrd.c [1.8]: - removes redundant call to initialize the crd. - - -Fri Jan 29 22:00:00 1999 Henry Stiles henrys@artifex.com - - * pccrd.c [1.7]: - use the new interface to initialize a new crd derived from an old one. - - -Wed Jan 27 07:00:00 1999 Henry Stiles henrys@artifex.com - - * pcpage.c [1.17]: - added warning message if the bbox is not installed properly. - - -Mon Jan 18 07:00:00 1999 Henry Stiles henrys@artifex.com - - * rtraster.c [1.10], pgdraw.c [1.19], pctext.c [1.14], pcstate.h [1.10], - pcrect.c [1.7], pcpage.c [1.16], pcmain.c [1.22], pcht.c [1.11]: - Properly installs the bbox device and removes the "dubious" dirty page - optimization that avoided using the bbox device to check if a page was dirty. - - -Mon Jan 18 05:00:00 1999 Henry Stiles henrys@artifex.com - - * pcdraw.c [1.9]: - fixes comment. - - -Sat Jan 16 07:00:00 1999 Henry Stiles henrys@artifex.com - - * pcl_top.mak [1.12]: - updates version number. - - -Thu Jan 14 08:00:00 1999 Henry Stiles henrys@artifex.com - - * NEWS-PCL [1.13]: - chinook check-in. - -Version 1.05 (01/14/99) -====================== - -Mon Jan 11 16:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.18], pcpatrn.c [1.14], pcdraw.c [1.8]: - pattern_set_pen() modified to correctly install CIE color spaces for - pcl raster, as suggested by jan. - - * pccid.c [1.6]: - normalizing min and max ranges is only necessary for the RGB - colorimetric color space. - -Mon Jan 11 15:00:00 1999 Henry Stiles henrys@artifex.com - - * pglfill.c [1.7]: - line pattern was not specified correctly. - -Mon Jan 9 07:00:00 1999 Henry Stiles henrys@artifex.com - - * pcmain.c [1.21]: - Explicitly closes pcl's target device, forwarding devices like the - color mapper do not close the target device automatically. - -Mon Jan 6 22:00:00 1999 Marcos H. Woehrmann marcos@artifex.com - - * pcmain.c [1.20], pcl_top.mak [1.11]: - Fixed problem with version number under msvc (and watcom). - -Mon Jan 5 23:00:00 1999 Henry Stiles henrys@artifex.com - - * pglfill.c [1.6]: - hpgl_RF() was not properly saving and restoring the index when the - parser ran out of data and reinvokes hpgl_RF(). - -Mon Jan 4 14:00:00 1999 Henry Stiles henrys@artifex.com - - * pcmain.c [1.19], pcl_top.mak [1.10]: - Version number and build date for PCL. - -Mon Jan 4 05:00:00 1999 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.17]: - pixel placement was being applied in gl/2 to graphical objects other - than polygons. - - * Anomalies.txt [1.7]: - updates anomalies. - - * pgconfig.c [1.7]: - PP is not reset by IN on the color laserjet but is on the 6MP. - - * pcpatrn.c [1.13], pccsbase.c [1.8], pccid.c [1.5]: - normalizes min max range value when they are parsed from the long form - of the cid command. Previously the decode procedures accounted for - the normalization. Also a hack in pcpatrn.c to force install of cie - even if the current pen is white. The last change is incorrect and - will take a different form in the next release. - -Mon Dec 29 02:00:00 1998 Henry Stiles henrys@artifex.com - - * pglabel.c [1.8]: - ES (extra space) is independent of the current text direction. - -Mon Dec 23 08:00:00 1998 Henry Stiles henrys@artifex.com - - * pcmain.c [1.18]: - changes to use gs standard i/o - gs_stderr, gs_stdout, and gs_stderr. - -Mon Dec 23 00:00:00 1998 Henry Stiles henrys@artifex.com - - * pgdraw.c [1.16]: - removes unwanted debugging print statements mistakenly added to the - last revision. - -Mon Dec 22 20:00:00 1998 Henry Stiles henrys@artifex.com - - * pcl_watc.mak [1.5], pcl_ugcc.mak [1.18], pcl_top.mak [1.9], pcl_sgi.mak [1.7], - pcl_msvc.mak [1.4]: - Prefixes devices with $(DD) and moves zlib configuration variable - initialization to the to the top level unix makefiles. Someone else - will need to check the other makefile systems. This change requires - that we set ZLIB variable in # PLATFORMS SUPPORTED * 2 (pcl and XL) - places instead of one, but will allow the code to be compiled with - gs5.66. - - * pginit.c [1.9]: - adds warning message for resetting the picture frame. This is handled - directly by the picture frame and plot size commands. - -Mon Dec 22 19:00:00 1998 Henry Stiles henrys@artifex.com - - * pgvector.c [1.4]: - replaces explicit setting of the ctm with clearing the current path - which has the same result for the ctm but also updates gl/2's current - path to the correct state. Specifically, CI adds a point to the path - for positioning after drawing to set the current position to the - center of the circle. It is not necessary to leave this moveto in the - path, adding the point has already updated the current position. - - * pgdraw.c [1.15]: - (1) comments to indicate setting of the current line width is wrong, - (2) Saves and restores the CTM "around" setting plu ctm and stroking - gl line fills, and (3) adds warning message for bogus picture frame. - - * Anomalies.txt [1.6]: - identifies fts 2080 anomaly. - - * pgframe.c [1.5]: - Reorganizes picture frame and plot size logic. - -Mon Dec 18 17:00:00 1998 Henry Stiles henrys@artifex.com - - * pcl_ugcc.mak [1.17]: - adds full color bmp asyncronous device. - - * pcstate.h [1.9], pcommand.c [1.9], pcmain.c [1.17], pcl.mak [1.18], pcht.c [1.10], - pccrd.c [1.6]: - Change to set the target device in pcl's state. Adds accessor - functions to set and get the target device. Modifies all put param - like functions in pcl to use the real device. - -Mon Dec 16 08:00:00 1998 Henry Stiles henrys@artifex.com - - * pcl_ugcc.mak [1.16]: - add cljet5 device. - -Mon Dec 2 21:00:00 1998 Henry Stiles henrys@artifex.com - - * NEWS-PCL [1.12]: - news file update. - -Version 1.04 (12/01/98) -====================== - -Mon Nov 30 23:23:29 1998 Henry Stiles <henrys@meerkat> - - * pcl_msvc.mak: adds new drivers for MSVC builds. - - * pcpage.c: removed unused variable. - - * pgchar.c, pgdraw.c, pgmisc.h: - adds accessor function to get the current pen for character fill edge - mode. - - * pcursor.c, pcjob.c: adds stdlib and documents its use for atoi(). - - * Anomalies.txt: updates for fixed bugs and a spell check. - - * pcl_ugcc.mak: changes order of devices. - -Thu Nov 26 19:54:46 1998 Henry Stiles <henrys@meerkat> - - * pcfont.c, pcjob.c, pcpage.c: - changed to use pjl_compare() instead of strcmp(). - - * pcl_ugcc.mak: - asynchronous drivers are now included by default on unix platforms. - - * Anomalies.txt: updated for recent bug fixes. - -Tue Nov 24 23:24:22 1998 Henry Stiles <henrys@meerkat> - - * rtraster.c, rtgmode.c, pcwhtidx.c, pcwhtidx.h, pcuptrn.c, pcpatrn.c, pcpatrn.h, pcindxed.h, pcpalet.h, pcindxed.c: - changes #inlclude to 8.3 - - * Attic/pcwhtindx.h, Attic/pcindexed.c, Attic/pcindexed.h, Attic/pcwhtindx.c: - removes >8.3 file names. - - * pgdraw.c: hpgl_rm_vector_fill was not handled properly. - - * pgframe.c: - factors out common code for side effect of changing the picture frame. And fixes a fixes bug where we were not setting the default plot size correctly. - - * pginit.c: provides initialization for the plot size being set. - - * pcindxed.h, pcwhtidx.c, pcwhtidx.h, pcindxed.c, pcl.mak: - canonicalizes filenames to 8.3 and fixes clean makes for msvc. - -Thu Nov 19 06:16:42 1998 Henry Stiles <henrys@meerkat> - - * pgdraw.c: - We now correctly implement the background of hpgl/2 vector fills. - Strangely HP draws the backgrounds with an opaque or transparent white - depending on the current transparency mode. - - * pcursor.c: pcl support for pjl formlines. - - * pgconfig.c, pggeom.h: - hpgl_PS command #ifdef in for the sole purpose of being able to print - large plot sizes for RTL customers. - - * pcpage.c, pcstate.h: First cut at wide a4 implementation. - -Sun Nov 8 09:00:53 1998 Henry Stiles <henrys@meerkat> - - * NEWS-PCL: *** empty log message *** - -Thu Nov 5 21:50:43 1998 Henry Stiles <henrys@meerkat> - - * pgvector.c: - bezier curves appear to be hardwired to no joins - they do not use the current LA setting for join type - - * pgdraw.c, pgchar.c: - fixes for character edging the pen was not being defaulted correctly in CF and the hpgl/2 drawing machinery was filling the character in addition to stroking hpgl/2 vector fills - -Thu Nov 5 06:57:31 1998 Marcos H. Woehrmann <marcos@meerkat> - - * pcfont.c: Added /winnt/fonts/ to tt font search path. - -Version 1.03 (11/06/98) -===================== - -Thu Nov 5 21:50:43 1998 Red Hat Linux User <henrys@warthog> - - * pgvector.c: - bezier curves appear to be hardwired to no joins - they do not - use the current LA setting for join type - - * pgdraw.c, pgchar.c: - fixes for character edging the pen was not being defaulted - correctly in CF and the hpgl/2 drawing machinery was filling the - character in addition to stroking hpgl/2 vector fills - -Thu Nov 5 06:57:31 1998 marcos <marcos@warthog> - - * pcfont.c: Added /winnt/fonts/ to tt font search path. - -Thu Nov 5 05:48:16 1998 Red Hat Linux User <henrys@warthog> - - * pcpage.c: adds a call to erase page after new paper size is - called. - -Tue Nov 3 08:01:38 1998 Red Hat Linux User <henrys@warthog> - - * pctext.c, pcfsel.c: - - returns in error instead of noting an error if symbol mapping - fails - - * pcmain.c: forgetting to close the device at the end of processing - -Fri Oct 30 22:49:06 1998 Red Hat Linux User <henrys@warthog> - - * pccsbase.c: normalizes ranges to (0,1) for independent color spaces - -Sun Oct 25 08:05:36 1998 Red Hat Linux User <henrys@warthog> - - * pcmain.c: proper usage of debugging memory switches - - * rtraster.c: better bit twiddling for performance - -Fri Oct 16 15:41:39 1998 Red Hat Linux User <henrys@warthog> - - * pcmain.c: "canocalizes" args to **args. - - * pgdraw.h: adds prototype for exported function hpgl_close_path(). - - * pglabel.c: - corrects a parameter mismatch with fetching the next - character. This code was not updated when the gs text interface - changed in 550. - - * pcpage.c, pcsfont.c: removes an incorrect const qualifier. - - * pccsbase.c, pcindexed.c: corrects improper aggregate initialization. - - * pcl.mak: reviewed and added new include file dependencies. - - * pgstate.h: removes obsolete boolean which detected a path - - * pcjob.c, pcmtx3.c, pcommand.c, pgdraw.c, pcbiptrn.c, - pccrd.c, pcfont.c, pctext.c, pcuptrn.c, rtraster.c, rtrstcmp.c: - - adds include files for correct prototypes we also corrected a problem - in correctly detecting if a path was actually being rendered - -Wed Oct 14 20:50:48 1998 Red Hat Linux User <henrys@warthog> - - * pcpatrn.c: fixes benevolant type mismatch - -Tue Oct 6 17:49:00 1998 Red Hat Linux User <henrys@warthog> - - * pcmtx3.h: changes math.h to math_h. - -Version 1.02 (10/05/98) -===================== - -Mon Oct 5 02:12:39 1998 Red Hat Linux User <henrys@warthog> - - * pcstate.h, pcsymbol.h, pcmain.c, pcommand.c, pcpage.c, - pcfsel.c, pcjob.c, pclfont.c, pcfont.c: - Updates for getting intitial state from the pjl environment. - - * pcl_ugcc.mak: adds contone color laserjet device for - testing purposes - -Sun Oct 4 06:50:52 1998 Red Hat Linux User <henrys@warthog> - - * pgpoly.c, pgdraw.c, pctext.c: - a more conservative approach to page ejecting. The have_page - boolean was being updated to true unnecessarily - - * pcfsel.c: Did not score symbol set correctly during font selection. - - -Version 1.01 (9/26/98) -===================== - -Sat Sep 26 18:50:50 1998 Red Hat Linux User <henrys@warthog> - - * Attic/pcl_conf.mak, pcl.mak, pcl_msvc.mak, pcl_top.mak, pcl_watc.mak: - changes to support msvc builds - -Version 1.00 (9/18/98) -======================= - -Fri Sep 18 06:22:58 1998 Henry Stiles <henrys@meerkat> - -* All files - - * Removes ghostscript license and replaces it with the shorter - Aladdin license notice. - - * pcindexed.h, rtgmode.c, pcfrgrnd.c, pcindexed.c: - Changes a variable name from fixed to pfixed to avoid a spurious - warning from the Solaris C compiler. - - * pcl.mak: - corrected typos in dependency lists and removes ghostscript - copyright notice. - -Tue Sep 15 07:04:00 1998 Henry Stiles <henrys@meerkat> - - * pcl_ugcc.mak: adds tiff devices to the makefile. - - * Anomalies.txt: A new file that describes known anomalies. - -Mon Sep 14 05:28:27 1998 Henry Stiles <henrys@meerkat> - - * pcpatrn.c: - sets pen to 1 if the pen number equals the number of entries in the - palette. - -Sun Sep 13 05:51:08 1998 Henry Stiles <henrys@meerkat> - - * rtraster.c, rtrstcmp.c, pgdraw.c, pcpatxfm.c, pcrect.c, - pctext.c, pcwhtindx.c, pgcolor.c, pgconfig.c, pcl.mak, pcl_ugcc.mak, - pcmain.c, pcmtx3.c, pcpalet.c, pcpatrn.c, pcht.c, pcindexed.c, - pccid.c, pccprint.c, pccsbase.c: - - adds color laserjet driver, fixes makefile header file - dependency typos and, removes unused variables. - -Sat Sep 12 08:09:46 1998 Henry Stiles <henrys@meerkat> - - * pcpage.c: modification so that pcl can request page sizes. - - * pcparam.h: modifications so pcl can request page sizes. - -Fri Sep 11 03:42:59 1998 Henry Stiles <henrys@meerkat> - - * pcpage.c, pcparam.h: - reverts page device media changes to support cljet5. - -Thu Sep 10 17:07:39 1998 Henry Stiles <henrys@meerkat> - - * pcl_msvc.mak: adds broken msvc files for shipment to johnd's. - - * pcpatrn.c: removes SGI NFS null from the end of a file. - - * pcl_ugcc.mak: removes cljet driver temporarily. - -Tue Sep 8 07:35:55 1998 Red Hat Linux User <jan@meerkat> - - * pcl.mak: adds .h file dependencies. - - * pcl_top.mak: changes to not compile main with debug. - - * pcsymbol.c: - We were allocating extra for the symbol set codes but they are - actually allocated through the structure allocation since the symbol - code array is defined statically. - - * pctext.c: - Modified the handling of the right text margin. It turns out that the case - of no-line-wrap must be handle differently that the case in which line - wrapping is enabled. - - * pcpatrn.c: - Fixed typo in pattern_set_shade_gl: a solid pattern should be used for - an unrecognized intensity if the intensity is > 0, not <= 0. This gave - rise to an anomally on panel 1815 of the PCL 5c FTS. - - * pcpalet.c: - Modified invocations of pcl_crd_build_default_crd to pass a pcl_state_t - pointer rather than a memory structure pointer; see pccrd.h above. - - * pcmain.c: Modified code to not always define DEBUG. - - * pcindexed.c: - Modified the code to handle the situation in which the black and white - reference points for a component are the same. This is tested in the - PCL 5c FTS. - - * pcht.h, pcht.c: - Changed from a single color mapping device to multiple color mapping - devices, one for each mapping type. This is needed because the - rendering method used by the foreground may be different from that used - by the palette (which, in turn, is used by a raster), so it is necessary - to have two different color mapping device present at the same time. - - Added support for table-dither (mask, non-monotonic) halftones to be - used with the (not fixed) built-in rendering methods. - - Added code to allow device-specific halftones and re-mapping arrays - encoded as gs_param dictionaries to be read from the device on start-up. - - Added support for table dither halftones. Also provided a structure - descriptor for pcl_ht_builtin_dither_t structures, as these may now need - to be allocated when read from a device. - - * pccrd.c, pccrd.h: - Added facility to read a device-specific CRD encoded as a gs_param - dictionary. - - Changed the operand to pcl_crd_build_default_crd from a memory pointer - to a pcl_state_t pointer. This is necessary to allow the default dictionary - to be read from a device. - -Mon Sep 7 02:02:19 1998 Henry Stiles <henrys@meerkat> - - * pcsfont.c: bad revision. - -Sun Sep 6 19:50:14 1998 Henry Stiles <henrys@meerkat> - - * pcsymbol.c: - fixes memory allocation problem introduced because a new field was - added to the symbol set data structure. - -Sat Sep 5 05:55:09 1998 Henry Stiles <henrys@meerkat> - - * pcpage.c, pcparam.h, pcommand.c, pcl_sgi.mak, pcl_ugcc.mak: - modifications to support paper size specification from pcl. - -Fri Sep 4 02:47:44 1998 Red Hat Linux User <jan@meerkat> - - * pcl.mak: add new header file dependencies. - -Fri Sep 4 02:45:08 1998 Henry Stiles <henrys@meerkat> - - * pcl.mak: update documentation. - -Fri Sep 4 02:39:01 1998 Red Hat Linux User <jan@meerkat> - - * pcl_top.mak: adds decmap device. - - * pcsymbol.c: Modified pcsymbol_do_reset to support overlay macros. - - * pcbiptrn.c, pcbiptrn.h: - Modified the shade pattern for the 11% - 20% case; this had been entered - incorrectly previously. - - Added the "un-solid" pattern. This is a masked patter that has no - foreground pixels. It is used with GL/2, as a solid white foreground - is transparent in GL/2 (if GL's "source transparency" is set), but - opaque in PCL. - - Added prototype for the pcl_pattern_get_unsolid_pattern. - - * pccprint.c: - Modified the code for the pixel placement operator for the new manner - in which pixel placement information is kept in the PCL state. - - Modified the pccprint_do_reset routine to support overlay macros. - - * pcdraw.c: - Added code to handle GL/2's source transparency separately from PCL's - pattern transparency. The two parameters have the same effect (all - GL/2 objects are masks, and hence do not support notion of "source" - transparency similar to PCL's), but must be maintained independently - in the PCL-GL/2 state. - - Turned off fill-adjust for all PCL objects. This used to (incorrectly) - implement pixel placement, which is now implemented directly for - rectangles (the only object affected by pixel placement for most - printers (the CLJ 5/5M allows pixel placement to also affect scalable - characters)). - - * pcht.c: - Modified to support color-mapping as part of a rendering method, and to - support monochrome mode. - - As part of this change, the never-used device field of the rend_info_t - structure is replaced with a color mapping parameter, which is used - with a color-mapping forwarding device that is always present. - - To support monochrome mode, the nature of the remapping array has been - change somewhat, and the render_method field of the pcl_ht_t structure - modified to be the mapped rather than raw rendering method. Fields for - print mode (monochrome or color) and raw rendering method have been - added to the PCL state. - - * pcht.h: - Added prototype for the new procedure pcl_ht_set_print_mode, which - can be used to set monochrome or colored print mode. - - Changed the render_method field/operand to be unsigned. - - * pcindexed.h, pcindexed.c: - Generalixed the pcl_cs_indexed_0_is_{black | white} routines to check - for the blackness or whiteness of any entry. The routines are now know - as pcl_cs_indexed_is_{black | white}. Replaced prototypes for - pcl_cs_indexed_0_is_{black | white} with those for - pcl_cs_indexed_is_{black | white}. Defined macros to correspond to the - former prototypes, for backwards compatibility. - - * pcfont.c, pcmacros.c, pcjob.c: - Modified pcmacros_do_reset to support overlay macros. - - * pcmain.c: - Added a pair of calls to gs_reclaim prior to running the first job. - This is very important; until gs_reclaim is called for the first time, - freed string objects are not recovered. Hence, the memory they use - is lost. - - Added some debugging code to assist with memory leak detection. - - * pcmisc.c: Modified pcmisc_do_reset to support overlay marcos. - - * pcommand.c: - Modifed pcl_init_state for the deletion of the grid_adjust field and the - addition of the addition of the monochrome_mode and render_mode fields - in the graphic state. - - * pcpage.c: - Modified print quality command (<esc> * o # Q) to home the cursor. - Modified pcpage_do_reset to support overlay macros. - - * pcpalet.c: Added command for setting monochrome/normal print mode. - - Modified pcl_palette_set_render_method to reflect the addition of - the render_mode field in the PCL state. - - Modified palette_do_reset to support overlay macros. - - * pcpalet.h: Changed render_method operand to be unsigned. - - * pcpatrn.c: - Modified pattern_set_gl_RF to account for the fact that patterns defined - with the RF command may be either masked or colored patterns, and in the - former case are fully transparent if GL/2's source transparency is set and - the current pen is white. Also modified this routine to use the current - pen if the pattern does not exist, even if the applicable SV or FT command - specified using pen 1 (this requires a hack regarding the interpretation - of the current pen operand when it is negative). - - Modified several other pattern_set_*_gl routines for mask patterns (shades, - cross-hatch, user-defined) to make these fully transparent if the current - pen is white. - - Also modified pattern_do_reset to support overlay macros. - - * pcrect.c: - Moved implementation of pixel placement for PCL objects to this module - (rectangles are the only PCL object affected by pixel placement in - this and most other PCL interpreters, including most but not all HP - implementations. - - Modified pcrect_do_reset to support overlay macros. - - * pcsfont.c: Modified pcsfont_do_reset to support overlay macros. - - * pcstate.h: - Added pcl_pattern_transparent field, so that PCL's pattern transparency - setting and GL/2's source transparency setting may be separately - maintained. - - Added the render_mode and monochrome_mode fields, to support the - monochrome/normal print mode selection command. - - Replaced the grid_adjust field with the pp_mode field. - - * pcstatus.c: Modified pcsymbol_do_reset to support overlay macros. - - * pctext.c: - Removed no longer needed invocation of gs_setfilladjust (for PCL, fill - adjust is now always set to 0). - - Modified pctext_do_reset to support overlay macros. - - * pcuptrn.c: - Modified pcl_pattern_RF to handle both colored and uncolored patterns - created via the RF command. - - * pcursor.c: Modified pcursor_do_reset to support overlay macros. - - * pgconfig.c: - Split the hpgl_DF command into two sections, one of which is accessible - separately to support the reset required for overlay macros. - - * pgdraw.c: - Modified the handling of patterns generated with the RF command to - allow both colored and uncolored variations. - - Modified the manner in which the current pen is specified for - uncolored patterns generated via the RF command. If pen 1 is desired, - the opposite of the current pen is specified, to allow for the - possibility that the pattern may not exist. - - Changed the handling of fill adjust to reflect the replacement of the - grid_adjust state parameter with pp_mode (note that the actual - implementation of pixel placement for GL objects is still broken). - - * pginit.c: Added support for overlay macros. - - * pglfill.c: - Modified hpgl_FT to read and use the second optional parameter for - mode 11 patterns (this is contrary to the documentation, but - consistent with the SV command and has been empirically verified on - two HP PCL implementations). - - Modified hpgl_RF to allow for both colored and uncolored patterns. - - * pgmand.h: - Added prototype for the new procedure hpgl_reset_overlay. This is used to - reset the GL/2 state prior to the execution of an overlay macro. - - * pgstate.h: - 1. Replaced the su_ union with the sp_ structure, and made the latter part - of the fp_ structure consistent with the sp_ structure. Though not - documented as such, for fills other than line fills the FT and SV - commands are symmetric. - - 2. Added the is_mask field to the rf_ structure. This is used to support - uncolored patterns created via the RF command. - - * rtgmode.c: Modified gmode_do_reset to support overlay macros. - -Tue Aug 25 19:18:59 1998 Henry Stiles <henrys@meerkat> - - * pcl.mak: adds code to clean up gs generated files. - -Mon Aug 24 08:03:18 1998 Henry Stiles <henrys@meerkat> - - * pcl.mak: - removed device files from current working source directory that should - not exist there in the first place... - -Mon Aug 24 07:36:32 1998 Red Hat Linux User <jan@meerkat> - - * pglabel.c: whitespace difference. - - * pcwhtindx.c: - Fixed a bug/memory leak in pcl_cmap_map_raster. If a new raster array was - allocated to hold the re-mapped pattern data, its pointer was never being - placed in *pout_pixinfo. - - * pcuptrn.c: - 1. Modified code to support (up to) two rendered instances per pattern: - one mask and one colored. - - 2. Modified the reset code to clear the pattern cache. This is an attempt - to limit memory fragmenation. - - * pcpatrn.h: - Modified the pattern structure to be able to hold two rendered instances: - one colored and one uncolored. This is an attempt to reduce memory - thrashing due to the frequent and unnecessary re-allocation of mask - patterns. - - * pcpatrn.c: - Modified to the pattern handling code to allow for two rendered instances - per pattern: one mask and one colored. This is an attempt to reduce - memory thrashing due to the frequent and unnecessary re-allocation of - mask patterns. - - * pcpalet.c: - 1. Fixed a pair of memory-related problems in the push/pop palette code: - pop palettes were erroneously getting an extra reference, and the - palette stack global was not being set to NULL after the palette had - been cleared. - - 2. Removed code in build_default_palette that undefined the current - palette before redefining it. This avoids a release/allocate operation - for a dictionary entry that otherwise would confuse the memory leak - detection tool. - - 3. Fixed a bug in a never-used case in pcl_palette_PW. If the palette - does not exist when this routine is called, it is created, but in the - earlier code the ppalet pointer was not being updated after the - creation. - - 4. Modified clear_palette_store to leave the current palette alone if it - already is the default palette. This simplifies work with the memory - leak detector. This change also moves the invocation of the - build_default_palette routine to this procedure from its various - callers. - - * pcmain.c: - Moved the reporting points for the memory leak detection code to more - convenient locations. - - * pcht.c: - Fixed a memory leak in set_threshold_ht. A fourth threshold string was - being generated to handle the case of a 4-color output device, but - this was overwritting the red-component threshold array allocated - previously. Not output error occurred because the two arrays were - meant to be the same, but the previously allocated array could no - longer be freed. - - * pcfsel.c: *** empty log message *** - - * pccolor.c: - Modified the set color component and assign color index commands to be - permitted but ignored in raster graphics mode (i.e.: they do not end - raster graphics mode). This is contrary to the documentation but - matches the behavior of the CLJ 5/5M and DJ 1600C/CM. The effect is - visible in PCL 5c FTS panel 845. - - * pcindexed.c: - Fixed bug in pcl_cs_indexed_update_lookup_tbl. A new indexed color - space may have been created via the "unshare" operation, but the color - space pointer was never being updated. Hence, the lookup table was - being modified in the old color space. This bug is visible on PCL 5c - FTS panels 2410 and 2411. - - * pcmain.c, pcindexed.c, pcl.mak, pcht.c, pcfsel.c, pccolor.c: - *** empty log message *** - -Sun Aug 23 05:30:05 1998 Henry Stiles <henrys@meerkat> - - * pgdraw.c: - Work around to stroke lines gl/2 style fills individually instead of - accumulating the entire fill in one path. This guarantees that a - fixed amount of memory will be used for fills. It was changed to fix - fts 1462 which creates a path that is much to large, not due to the - size of the graphical object being filled but the algorithm fills from - GL/2's anchor corner and clips the resulting fill to the graphical - object. We should find the equivalent maximum value for the anchor - corner such that the coordinates are less than the X and Y origin - coordinates of the bounding box of the object being filled. - -Sun Aug 23 05:10:18 1998 Red Hat Linux User <jan@meerkat> - - * rtraster.c: - Modified to properly (if quite slowly) handle the case of a raster with - source transaprency off but pattern transparency on. - - * pcwhtindx.c: - Modified pcl_cmap_create_remap_ary to potentially provide a remap - array if source of pattern transparency is set. This is necessary to - support the "two part" image structure required for rendering images - with opaque source\ s but transparent patterns. Also removed a remnant - of the temporary hack that made all rasters opaque. - - * pctext.c: fills in a missing else. - - * pcpatrn.h: - Added the "colored" bit to the pattern object, to indicate if it was - rendered as a colored pattern. - - * pcpatrn.c: - 1. Moved the retained copy of the special white base color space to - pccsbase.c, and the retained copy of the default halftone to pcht.c. - This improves modularity and simplifies work with memory leak - detection tools. - - 2. Modified the rendering of uncolored, transparent, foreground - patterns. If the halftone or color rendering dictionary in the - foreground varies from that in the current palette, these must be - rendered as colored patterns (because the graphic library's state - cannot retain two halftones). - - 3. Plugged a memory leak in render_pattern: the pattern instance of - the previous pattern was not being released. - - 4. Added stub for the driver configuratioin command. This will absorb - any data provided. - - * pcpalet.c: - Modified to retain a copy of the default palette, and to set the - default drawing color during initialization. This reduces memory - thrashing slightly and simplies work with memory leak detection tools. - - * pcpage.c: - Modified new_page_size to reset the default transformation in the graphic - state. This is necessary for devices that feed different size sheets in - different directions. - - * pcmain.c: - Removed initialization of the PCL coordinate system; this is now - handled in pcpage.c - - * pcindexed.h: - Changed the third operand of pcl_cs_indexed_build_special to be a - const byte pointer rather than a byte pointer. Also added the - prototype for the new initialization routine pcl_cs_indexed_init. - - * pcindexed.c: - Modified default pen widths to be in plotter units rather than - millemeters. Also modified to retain the default indexed color - space. This reduces memory thrashing slightly, and makes working - with memory leak detection tools simpler. The latter change requires - the addition of the an intialization procedure, pcl_cs_indexed_init. - - * pcht.c: - Modified to provide a default transfer map (color lookup table) for - the default (K) component of the output. This is necessary to properly - handle cases in which the provided transfer function for the other - components is an inverting function, for otherwise the results will be - very black. - - Also modified to maintain a copy of the default halftone, which is - allocated at boot time. This reduces memory trhashing slight, but more - significantly it greatly simplifies working with the memory leak - detection tools. - - * pcfrgrnd.c: - Modified to retain a copy of the default foreground. This reduces - memory thrashing slightly, and more significantly simplifies work with - memory leak detection tools. - - * pcdraw.c: Modified pcl_grestore to release the references held by the - pcl_gstate_ids_t structure that will be discarded. This plugs a major - memory leak. - VS: ---------------------------------------------------------------------- - - * pccsbase.h: - Added prototype for initialization routine pcl_cs_base_init. - - * pccsbase.c: Modified to keep a copy of the special "white" color - space. Previously, this was kept in pcpatrn.c, which was not ideal - from a modularity point of view. As part of the change, an - initialization routine, pcl_cs_base_init, has been added. - -Thu Aug 20 20:56:10 1998 Henry Stiles <henrys@meerkat> - - * Anomalies.txt: remove cvs anomalies - - * pglabel.c, pcindexed.c, pcmain.c: - changes default translation (pcmain.c) to put pcl's origin correctly - on devices that have a non-zero imageable area. Also, pcl was not - using the default plu to initialize line width and the character code - was not properly initializing the line width prior to stroking - "stroke" font characters. - diff --git a/pcl/pcbiptrn.c b/pcl/pcbiptrn.c deleted file mode 100644 index 202031956..000000000 --- a/pcl/pcbiptrn.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcbiptrn.c - code for PCL built-in patterns */ - -#include "math_.h" -#include "string_.h" -#include "gstypes.h" /* for gsstate.h */ -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" -#include "gscoord.h" -#include "pcpatrn.h" -#include "pcuptrn.h" -#include "pcbiptrn.h" -#include "pcstate.h" - -/* - * Bitmap arrays for the built-in patterns. - */ -private const byte bi_data_array[(PCL_NUM_SHADE_PATTERNS + PCL_NUM_CROSSHATCH_PATTERNS) * 2 * 16] = { - - /* shade 1% to 2% */ - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* shade 3% to 10% */ - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* shade 11% to 20% */ - 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, - - /* shade 21% to 35% */ - 0xc1, 0xc1, 0xc1, 0xc1, 0x80, 0x80, 0x08, 0x08, - 0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x08, 0x80, 0x80, - 0xc1, 0xc1, 0xc1, 0xc1, 0x80, 0x80, 0x08, 0x08, - 0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x08, 0x80, 0x80, - - /* shade 36% to 55% */ - 0xc1, 0xc1, 0xeb, 0xeb, 0xc1, 0xc1, 0x88, 0x88, - 0x1c, 0x1c, 0xbe, 0xbe, 0x1c, 0x1c, 0x88, 0x88, - 0xc1, 0xc1, 0xeb, 0xeb, 0xc1, 0xc1, 0x88, 0x88, - 0x1c, 0x1c, 0xbe, 0xbe, 0x1c, 0x1c, 0x88, 0x88, - - /* shade 56% to 80% */ - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xdd, 0xdd, - 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0xdd, 0xdd, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xdd, 0xdd, - 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0xdd, 0xdd, - - /* shade 81% to 99% */ - 0xf7, 0xf7, 0xe3, 0xe3, 0xf7, 0xf7, 0xff, 0xff, - 0x7f, 0x7f, 0x3e, 0x3e, 0x7f, 0x7f, 0xff, 0xff, - 0xf7, 0xf7, 0xe3, 0xe3, 0xf7, 0xf7, 0xff, 0xff, - 0x7f, 0x7f, 0x3e, 0x3e, 0x7f, 0x7f, 0xff, 0xff, - - /* cross-hatch 1 (horizontal stripes) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* cross-hatch 2 (vertical stripes) */ - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - - /* cross-hatch 3 (upper right/lower left diagonal stripes) */ - 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, - 0x00, 0x38, 0x00, 0x70, 0x00, 0xe0, 0x01, 0xc0, - 0x03, 0x80, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, - 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01, - - /* cross-hatch 4 (upper left/lower right diagonal stripes) */ - 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, - 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x03, 0x80, - 0x01, 0xc0, 0x00, 0xe0, 0x00, 0x70, 0x00, 0x38, - 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, - - /* cross-hatch 5 (aligned cross-hatch) */ - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff, - 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, - - /* cross-hatch 6 (diagnoal cross-hatch) */ - 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c, - 0x1c, 0x38, 0x0e, 0x70, 0x07, 0xe0, 0x03, 0xc0, - 0x03, 0xc0, 0x07, 0xe0, 0x0e, 0x70, 0x1c, 0x38, - 0x38, 0x1c, 0x70, 0x0e, 0xe0, 0x07, 0xc0, 0x03 -}; - - -#define make_pixmap(indx) \ - { (byte *)(bi_data_array + indx * 2 * 16), 2, {16, 16}, 0, 1, 1 } - -private const gs_depth_bitmap bi_pixmap_array[PCL_NUM_CROSSHATCH_PATTERNS + - PCL_NUM_SHADE_PATTERNS] = { - make_pixmap(0), - make_pixmap(1), - make_pixmap(2), - make_pixmap(3), - make_pixmap(4), - make_pixmap(5), - make_pixmap(6), - make_pixmap(7), - make_pixmap(8), - make_pixmap(9), - make_pixmap(10), - make_pixmap(11), - make_pixmap(12) -}; - -#define bi_cross_offset 7 - -/* - * A special pattern, used for rendering images that interact with solid - * foregrounds. - * - * Handling the interaction of rasters and foregrounds in PCL is tricky. PCL - * foregounds carry a full set of rendering information, including color - * correction and halftoning information. These may differe from the color - * correction information and halftone mechanism used to process the raster - * itself (which is always taken from the current palette at the time the - * raster is output). The graphic library can accommodate only a single - * color rendering dictionary and halftone mechanism at one time, hence the - * problem. - * - * The solution is to invoke a second graphic state. Patterns in the graphic - * library are provided with their own graphic state, so method for handling - * solid foreground colors is to create a solid, uncolored pattern that is - * is "on" (assumes the foreground color) everywhere. - * - * The following 1x1 pixel texture is used for this prupose. As with the - * pattern above, two copies of this structure are required: a prototype - * (qualified as const) and the pattern actually used. - */ -private const byte solid_pattern_data = 0xff; -private const gs_depth_bitmap solid_pattern_pixmap = { - (byte *)&solid_pattern_data, 1, {1, 1}, 0, 1, 1 -}; - -/* - * An "un-solid" pattern, similar to the solid pattern described above, but - * with only background. This is used primarily to handle the case of an - * uncolored patter with a white foreground color in GL/2, which such patterns - * are completely transparent (if pattern transparency is on; note that what - * the GL/2 documentation describes as source transparency is actually pattern - * transparency). - */ -private const byte unsolid_pattern_data = 0x0; -private const gs_depth_bitmap unsolid_pattern_pixmap = { - (byte *)&unsolid_pattern_data, 1, {1, 1}, 0, 1, 1 -}; - -/* - * Initialize the built-in patterns - */ - void -pcl_pattern_init_bi_patterns( - pcl_state_t *pcs -) -{ - memset(pcs->bi_pattern_array, 0, sizeof(pcs->bi_pattern_array)); - pcs->psolid_pattern = 0; - pcs->punsolid_pattern = 0; -} - -/* - * Clear all built-in patterns. This is normally called during a reset, to - * conserve memory. - */ - void -pcl_pattern_clear_bi_patterns(pcl_state_t *pcs) -{ - int i; - - for (i = 0; i < countof(pcs->bi_pattern_array); i++) { - if (pcs->bi_pattern_array[i] != 0) { - pcl_pattern_free_pattern( pcs->memory, - pcs->bi_pattern_array[i], - "clear PCL built-in patterns" - ); - pcs->bi_pattern_array[i] = 0; - } - } - - if (pcs->psolid_pattern != 0) { - pcl_pattern_free_pattern( pcs->memory, - pcs->psolid_pattern, - "clear PCL built-in patterns" - ); - - pcs->psolid_pattern = 0; - } - if (pcs->punsolid_pattern != 0) { - pcl_pattern_free_pattern( pcs->memory, - pcs->punsolid_pattern, - "clear PCL built-in patterns" - ); - - pcs->punsolid_pattern = 0; - } -} - -/* - * pcl patterns are always always 300 dpi but we use the device - * resolution on devices lower than 300 dpi so we can at least see the - * patterns on screen resolution devices. We also provide a #define - * here for customers that wish to have better patterns at higher - * resolutions. - */ - -/* #define DEVICE_RES_PATTERNS */ - - private int -pcl_get_pattern_resolution(pcl_state_t *pcs, gs_point *pattern_res) -{ - /* default is 300 */ - pattern_res->x = 300; - pattern_res->y = 300; - /* get the current resolutions based on the device. */ - { - gs_point device_res; - gx_device *pdev = gs_currentdevice(pcs->pgs); - device_res.x = pdev->HWResolution[0]; - device_res.y = pdev->HWResolution[1]; -#ifdef DEVICE_RES_PATTERNS - pattern_res->x = device_res.x; - pattern_res->y = device_res.y; -#else - /* if both are less than 300 dpi override the 300 dpi default. */ - if ( (device_res.x < 300) && (device_res.y < 300) ) { - pattern_res->x = device_res.x; - pattern_res->y = device_res.y; - } -#endif - } - return 0; -} -#undef DEVICE_RES_PATTERNS -/* - * Return the pointer to a built-in pattern, building it if inecessary. - */ - private pcl_pattern_t * -get_bi_pattern(pcl_state_t *pcs, int indx) -{ - if (pcs->bi_pattern_array[indx] == 0) { - gs_point pattern_res; - pcl_get_pattern_resolution(pcs, &pattern_res); - (void)pcl_pattern_build_pattern( &(pcs->bi_pattern_array[indx]), - &(bi_pixmap_array[indx]), - pcl_pattern_uncolored, - pattern_res.x, - pattern_res.y, - pcs->memory - ); - pcs->bi_pattern_array[indx]->ppat_data->storage = pcds_internal; - } - return pcs->bi_pattern_array[indx]; -} - -/* - * For a given intensity value, return the corresponding shade pattern. A - * null return indicates that a solid pattern should be used - the caller - * must look at the intensity to determine if it is black or white. - */ - pcl_pattern_t * -pcl_pattern_get_shade(pcl_state_t *pcs, int inten) -{ - pcl_pattern_t *shade = 0; - if (inten <= 0) - shade = 0; - else if (inten <= 2) - shade = get_bi_pattern(pcs, 0); - else if (inten <= 10) - shade = get_bi_pattern(pcs, 1); - else if (inten <= 20) - shade = get_bi_pattern(pcs, 2); - else if (inten <= 35) - shade = get_bi_pattern(pcs, 3); - else if (inten <= 55) - shade = get_bi_pattern(pcs, 4); - else if (inten <= 80) - shade = get_bi_pattern(pcs, 5); - else if (inten <= 99) - shade = get_bi_pattern(pcs, 6); - return shade; -} - -/* - * For a given index value, return the corresponding cross-hatch pattern. A - * null return indicates that the pattern is out of range. The caller must - * determine what to do in this case. - */ - pcl_pattern_t * -pcl_pattern_get_cross(pcl_state_t *pcs, int indx) -{ - if ((indx < 1) || (indx > 6)) - return 0; - else - return get_bi_pattern(pcs, indx + bi_cross_offset - 1); -} - -/* - * Return the solid uncolored pattern, to be used with rasters (see above). - */ - pcl_pattern_t * -pcl_pattern_get_solid_pattern(pcl_state_t *pcs) -{ - if (pcs->psolid_pattern == 0) { - gs_point pattern_res; - pcl_get_pattern_resolution(pcs, &pattern_res); - (void)pcl_pattern_build_pattern( &(pcs->psolid_pattern), - &solid_pattern_pixmap, - pcl_pattern_uncolored, - pattern_res.x, - pattern_res.y, - pcs->memory - ); - pcs->psolid_pattern->ppat_data->storage = pcds_internal; - } - return pcs->psolid_pattern; -} - -/* - * Return the "unsolid" uncolored patterns, to be used with GL/2. - */ - pcl_pattern_t * -pcl_pattern_get_unsolid_pattern(pcl_state_t *pcs) -{ - if (pcs->punsolid_pattern == 0) { - gs_point pattern_res; - pcl_get_pattern_resolution(pcs, &pattern_res); - (void)pcl_pattern_build_pattern( &(pcs->punsolid_pattern), - &unsolid_pattern_pixmap, - pcl_pattern_uncolored, - pattern_res.x, - pattern_res.y, - pcs->memory - ); - pcs->punsolid_pattern->ppat_data->storage = pcds_internal; - } - return pcs->punsolid_pattern; -} diff --git a/pcl/pcbiptrn.h b/pcl/pcbiptrn.h deleted file mode 100644 index 1d91b44de..000000000 --- a/pcl/pcbiptrn.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcbiptrn.h - interface for PCL's built-in patterns */ - -#ifndef pcbiptrn_INCLUDED -#define pcbiptrn_INCLUDED - -#include "pcpatrn.h" - -/* - * Initialize the built-in pattern machinery. This routine copies "const" to - * "non-const" structures, to facilitate working with systems that install all - * initialized global data in ROM. - */ -void pcl_pattern_init_bi_patterns(P1( pcl_state_t *pcs )); - -/* - * Clear the renderings of the built-in patterns. This may be called during - * a reset to conserve memory. - */ -void pcl_pattern_clear_bi_patterns(P1(pcl_state_t *pcs)); - -/* - * For a given intensity value, return the corresponding shade pattern. A - * null return indicates that a solid pattern should be used - the caller - * must look at the intensity to determine if it is black or white. - */ -pcl_pattern_t * pcl_pattern_get_shade(P2( pcl_state_t *pcs, int inten)); - -/* - * For a given index value, return the corresponding cross-hatch pattern. A - * null return indicates that the pattern is out of range. The caller must - * determine what to do in this case. - */ -pcl_pattern_t * pcl_pattern_get_cross(P2(pcl_state_t *pcs, int indx)); - -/* - * Return a solid, 1 x 1 pattern for use with rasters. See the comments in - * pcbiptrn.c for why this is necessary. - */ -pcl_pattern_t * pcl_pattern_get_solid_pattern(P1(pcl_state_t *pcs)); - -/* - * Return an "unsolid", 1 x 1 pattern for use with GL/2. See the comments in - * pcbiptrn.c for why this is necessary. - */ -pcl_pattern_t * pcl_pattern_get_unsolid_pattern(P1(pcl_state_t *pcs)); - -#endif /* pcbiptrn_INCLUDED */ diff --git a/pcl/pccid.c b/pcl/pccid.c deleted file mode 100644 index 53082b9b0..000000000 --- a/pcl/pccid.c +++ /dev/null @@ -1,462 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccid.c - PCL configure image data command and object implementation */ -#include "gx.h" -#include "gsmemory.h" -#include "gsstruct.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcpalet.h" -#include "pccid.h" - - -/* GC memory descriptor for the pcl_cid_data_t structure */ -private_st_cid_data_t(); - -/* - * Convert a 32-bit floating point number stored in HP's big-endian form - * into the native form required by the host processor. - * - * The non-IEEE case does not even attempt optimization, or proper handling - * of non-numbers (+-inf, nan); there are not enough non-IEEE processors that - * this code is likely to run on to make the effort worth-while. - */ - private float -make_float( - const byte * pbuff -) -{ - union { - float f; - uint32 l; - } lf; - - lf.l = (((uint32)pbuff[0]) << 24) + (((uint32)pbuff[1]) << 16) - + (((uint32)pbuff[2]) << 8) + pbuff[3]; - -#if (ARCH_FLOATS_ARE_IEEE && (ARCH_SIZEOF_FLOAT == 4)) - return lf.f; -#else - if (lf.l == 0L) - return 0.0; - else - return ldexp( (double)((1L << 23) | (lf.l & ((1L << 23) - 1))), - (((lf.l >> 23) & 0xff) - (127 + 23)) - ) - * ( (lf.l & (1UL << 31)) != 0 ? -1.0 : 1.0 ); -#endif -} - -/* - * Convert an array of 32-bit floats from the HP big-endian form into the - * native form required by the host processor. - */ - private void -convert_float_array( - int num_floats, - const byte * pinbuff, - float * poutbuff -) -{ - while (num_floats-- > 0) { - (*poutbuff++) = make_float(pinbuff);; - pinbuff += 4; - } -} - -/* - * Convert a 16-bit integer in HP's big-endian order into native byte order. - */ - private int -make_int16( - const byte * pbuff -) -{ - ulong l; - - l = (((ulong)pbuff[0]) << 8) + pbuff[1]; - return (int)((int16)l); -} - -/* - * Convert an array of 16-bit integers from HP's big-endian form to the - * native byte order required by the host processor. - */ - private void -convert_int16_array( - int num_ints, - const byte * pinbuff, - int16 * poutbuff -) -{ - while(num_ints-- > 0) { - *poutbuff++ = make_int16(pinbuff); - pinbuff += 2; - } -} - - -/* - * Build the various long-form configure image data structures. - * Returns 0 on success, < 0 in case of an error. - */ - private int -build_cid_dev_long( - pcl_cid_data_t * pcid, - const byte * pbuff -) -{ - pcl_cid_dev_long_t * pdev = &(pcid->u.dev); - - if (pcid->len != 18) - return e_Range; - convert_int16_array(3, pbuff + 6, pdev->white_ref); - convert_int16_array(3, pbuff + 12, pdev->black_ref); - return 0; -} - -/* The documentation is not clear if these are specified 0..255 or 0..1 - all cid long examples in the ats tests use 0..255. We use 0..1 for - the short form */ - private void -normalize_cid_minmax_valrange_long(float *minmax) -{ - int i; - for ( i = 0; i < 6; i++ ) { - minmax[i] /= 255; - } -} - - private int -build_cid_col_long( - pcl_cid_data_t * pcid, - const byte * pbuff -) -{ - pcl_cid_col_long_t * pcol = &(pcid->u.col); - - if (pcid->len != 86) - return e_Range; - convert_float_array(8, pbuff + 6, (float *)(pcol->colmet.chroma)); - convert_float_array(6, pbuff + 38, (float *)(pcol->colmet.nonlin)); - convert_float_array(6, pbuff + 62, (float *)(pcol->minmax.val_range)); - normalize_cid_minmax_valrange_long((float *)(pcol->minmax.val_range)); - return 0; -} - - private int -build_cid_lab_long( - pcl_cid_data_t * pcid, - const byte * pbuff -) -{ - pcl_cid_Lab_long_t * plab = &(pcid->u.lab); - - if (pcid->len != 30) - return e_Range; - convert_float_array(6, pbuff + 6, (float *)(plab->minmax.val_range)); - return 0; -} - - private int -build_cid_lum_long( - pcl_cid_data_t * pcid, - const byte * pbuff -) -{ - pcl_cid_lum_long_t * plum = &(pcid->u.lum); - - if (pcid->len != 122) - return e_Range; - convert_float_array(9, pbuff + 6, plum->matrix); - convert_float_array(6, pbuff + 42, (float *)(plum->minmax.val_range)); - convert_float_array(8, pbuff + 66, (float *)(plum->colmet.chroma)); - convert_float_array(6, pbuff + 98, (float *)(plum->colmet.nonlin)); - return 0; -} - -private int (*const build_cid_longform[])( pcl_cid_data_t *, const byte * ) = { - build_cid_dev_long, /* pcl_cspace_RGB */ - build_cid_dev_long, /* pcl_cspace_CMY */ - build_cid_col_long, /* pcl_cspace_Colorimetric */ - build_cid_lab_long, /* pcl_cspace_CIELab */ - build_cid_lum_long /* pcl_cspace_LumChrom */ -}; - -/* - * Check the configure image data short form structure. - * - * Because of the #%&&!!! confounded idiocy of causing e_Range to be ignored in - * the parser by seeting it to be a non-error (0), we must use literal -1 here - * to indicate that a palette is not acceptable. - * - * Returns 0 on success, < 0 in case of an error. - */ - private int -check_cid_hdr( - pcl_cid_hdr_t * pcid -) -{ - int i; - -#ifdef PCL5EMONO - pcid->bits_per_index = 1; -#endif - if ((pcid->cspace >= pcl_cspace_num) || (pcid->encoding >= pcl_penc_num)) - return -1; - - /* - * Map zero values. Zero bits per index is equivalent to one bit per index; - * zero bits per primary is equivalent to 8 bits per primary. - */ - if (pcid->bits_per_index == 0) - pcid->bits_per_index = 1; - for (i = 0; i < countof(pcid->bits_per_primary); i++) { - if (pcid->bits_per_primary[i] == 0) - pcid->bits_per_primary[i] = 8; - } - - switch (pcid->encoding) { - - case pcl_penc_indexed_by_pixel: - if ((pcid->bits_per_index & (pcid->bits_per_index - 1)) != 0) - return -1; - /* fall through */ - - case pcl_penc_indexed_by_plane: - if (pcid->bits_per_index > 8) - return -1; - break; - - case pcl_penc_direct_by_plane: - /* must be device-specific color space */ - if ((pcid->cspace != pcl_cspace_RGB) && (pcid->cspace != pcl_cspace_CMY)) - return -1; - if ( (pcid->bits_per_primary[0] != 1) || - (pcid->bits_per_primary[1] != 1) || - (pcid->bits_per_primary[2] != 1) ) - return -1; - break; - - case pcl_penc_direct_by_pixel: - if ( (pcid->bits_per_primary[0] != 8) || - (pcid->bits_per_primary[1] != 8) || - (pcid->bits_per_primary[2] != 8) ) - return -1; - break; - } - - /* - * Strange HP-ism: for device independent color spaces, bits per primary - * is always 8. For the direct by plane/pixel cases, this will already be - * the case, but the indexed by pixel/plane cases may require modification. - */ - if ( (pcid->encoding < pcl_penc_direct_by_plane) && - (pcid->cspace > pcl_cspace_CMY) ) { - pcid->bits_per_primary[0] = 8; - pcid->bits_per_primary[1] = 8; - pcid->bits_per_primary[2] = 8; - } - - return 0; -} - -/* - * Construct a configure image data object, and use it to overwrite the current - * active palette. - * - * Returns 0 if successful, < 0 in case of error. - */ - private int -install_cid_data( - int len, /* length of data */ - const byte * pbuff, /* the data provided with command */ - pcl_state_t * pcs, /* current state */ - bool fixed, /* from set simple color mode */ - bool gl2 /* from IN command in GL/2 */ -) -{ - pcl_cid_data_t cid; - int code = 0; - - if ((cid.len = len) < 6) - return e_Range; - memcpy(&(cid.u.hdr), pbuff, sizeof(pcl_cid_hdr_t)); - if ( ((code = check_cid_hdr(&(cid.u.hdr))) >= 0) && (len > 6) ) - code = build_cid_longform[pbuff[0]](&cid, pbuff); - if (code < 0) { - if (code == -1) - code = e_Range; /* handle idiocy in pcommand.h */ - return code; - } else - return pcl_palette_set_cid(pcs, &cid, fixed, gl2); -} - -/* - * Build a "simple color mode" pcl_cid_data_t structure, and use it to - * overwrite the current palette. This routine is separated out because it - * is required by both the simple color space command and the reset code. - */ - private int -set_simple_color_mode( - int type, - pcl_state_t * pcs -) -{ - static const byte cid_K[6] = { (byte)pcl_cspace_RGB, - (byte)pcl_penc_indexed_by_plane, - 1, 1, 1, 1 }; - static const byte cid_CMY[6] = { (byte)pcl_cspace_CMY, - (byte)pcl_penc_indexed_by_plane, - 3, 1, 1, 1 }; - static const byte cid_RGB[6] = { (byte)pcl_cspace_RGB, - (byte)pcl_penc_indexed_by_plane, - 3, 1, 1, 1 }; - const byte * pbuff = 0; - - if (type == 1) - pbuff = cid_K; - else if (type == 3) - pbuff = cid_RGB; - else if (type == -3) - pbuff = cid_CMY; - else - return e_Range; - - /* install the new color space */ - return install_cid_data(6, pbuff, pcs, true, false); -} - - -/* - * ESC * v <nbytes> W - * - * This command creates only the basic element of the the palette: the cid_data - * array. Other parts are created as needed. - */ - private int -pcl_configure_image_data( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ -#ifdef PCL5EMONO - return 0; -#endif - return install_cid_data( uint_arg(pargs), - arg_data(pargs), - pcs, - false, - false - ); -} - -/* - * ESC * r <code> U - * - * Simple color space command. Note that all the simple color spaces are - * variations of the RGB/CMY device-specific color space. - */ - private int -pcl_simple_color_space( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - return set_simple_color_mode(int_arg(pargs), pcs); -} - -/* - * ESC * i <nbytes> W - * - * Set viewing illuminant. This command is related to the configure image - * data object only in the sense that both apply to palettes. The command - * is implemented in this file as it is the only other command that involves - * binary floating point number arrays. - * - * This routine will convert the whitepoint to the form anticipated by the - * gs_cie_render structure (i.e., Y = 1.0). - */ - private int -set_view_illuminant( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint len = uint_arg(pargs); - const byte * pbuff = arg_data(pargs); - float x, y; - gs_vector3 wht_pt; - - if (len != 8) - return e_Range; - x = make_float(pbuff); - y = make_float(pbuff + 4); - - /* - * A white point must have a non-zero y value, as otherwise it carries - * no chromaticity infomration. It should also have x >= 0, y > 0, and - * x + y <= 1, for otherwise it represents an unrealizable color. - */ - if ((x < 0.0) || (y <= 0.0) || (x + y > 1.0)) - return e_Range; - - wht_pt.u = x / y; - wht_pt.v = 1.0; - wht_pt.w = (1.0 - x - y) / y; - - return pcl_palette_set_view_illuminant(pcs, &wht_pt); -} - -/* - * The following procedure supports the GL/2 "IN" command. It would be better - * implemented via a reset flag, but at the moment there are no reset flags - * that propagate out of GL/2. - * - * Returns 0 on success, < 0 in case of an error. - */ - int -pcl_cid_IN( - pcl_state_t * pcs -) -{ - static const byte cid_GL2[6] = { (byte)pcl_cspace_RGB, - (byte)pcl_penc_indexed_by_plane, - 3, 8, 8, 8 }; - - return install_cid_data(6, cid_GL2, pcs, false, true); -} - -/* - * There is no copy code required for this module, as any copying that is - * required is performed at the palette level. Similarly, there is no reset - * code, as reset is handled at the palette level. - */ - private int -pcl_cid_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - DEFINE_CLASS('*') - { - 'v', 'W', - PCL_COMMAND("Configure Image Data", pcl_configure_image_data, pca_bytes | pca_in_rtl) - }, -#ifndef PCL5EMONO - { - 'r', 'U', - PCL_COMMAND("Simple Color Mode", pcl_simple_color_space, pca_neg_ok | pca_in_rtl) - }, - { - 'i', 'W', - PCL_COMMAND("Set Viewing Illuminant", set_view_illuminant, pca_bytes | pca_in_rtl) - }, -#endif - END_CLASS - return 0; -} - -const pcl_init_t pcl_cid_init = { pcl_cid_do_registration, 0, 0 }; diff --git a/pcl/pccid.h b/pcl/pccid.h deleted file mode 100644 index b2a861e1a..000000000 --- a/pcl/pccid.h +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -#ifndef pccid_INCLUDED -#define pccid_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "pcommand.h" - -typedef short int16; -typedef unsigned short uint16; - -/* - * Enumeration of the 5c color spaces. - * - * Note that there is no separate monochrome color space; the monochrome - * simple color space is simply an RGB color space with a two-entry palette - * (1-bit/index) containing white (0) and black (1). - * - * These values are defined by HP. - */ -typedef enum { - pcl_cspace_White = -1, - pcl_cspace_RGB = 0, - pcl_cspace_CMY = 1, - pcl_cspace_Colorimetric = 2, - pcl_cspace_CIELab = 3, - pcl_cspace_LumChrom = 4, - pcl_cspace_num -} pcl_cspace_type_t; - -/* - * The pixel encoding enumeration. - * - * These values are defined by HP. - */ -typedef enum { - pcl_penc_indexed_by_plane = 0, - pcl_penc_indexed_by_pixel = 1, - pcl_penc_direct_by_plane = 2, - pcl_penc_direct_by_pixel = 3, - pcl_penc_num -} pcl_encoding_type_t; - -/* - * The short form and various long-form configure image data structures. - * Though the long form structures are similar to those defined by HP, - * only pcl_cid_shortform is the same (the others must be different to - * support alignment-sensitive processors). - * - * A GC memory descriptor is provided for pcl_cid_data_t object, though - * it should seldom be used: the configure image data information is needed - * only fleetingly while an indexed color space is created. Beyond that only - * the header (short form) is needed, and this is so small it can be copied - * into any objects that require it. - * - * NB: For the long form luminance-chrominance case, rows and columns of - * of the RGB ==> LumChrom transformation matrix must be transposed, - * to go from the column-vector view of HP to row-vector view used - * by the pc_mtx3_t data structure and the graphics library. The column - * vector form is stored in the matrix field of the pcl_cid_lum_chrom_t - * structure. - */ -#define pcl_cid_hdr_common \ - byte cspace; /* actually pcl_cspace_type_t */ \ - byte encoding; /* actually pcl_encoding_type_t */ \ - byte bits_per_index; \ - byte bits_per_primary[3] - -typedef struct pcl_cid_hdr_s { - pcl_cid_hdr_common; -} pcl_cid_hdr_t; - -typedef struct pcl_cid_dev_long_s { - pcl_cid_hdr_common; - int16 white_ref[3]; - int16 black_ref[3]; -} pcl_cid_dev_long_t; - -typedef struct pcl_cid_minmax_s { - struct { - float min_val, max_val; - } val_range[3]; -} pcl_cid_minmax_t; - -typedef struct pcl_cid_col_common_s { - struct { - float x, y; - } chroma[4]; - struct { - float gamma, gain; - } nonlin[3]; -} pcl_cid_col_common_t; - -typedef struct pcl_cid_col_long_s { - pcl_cid_hdr_common; - pcl_cid_col_common_t colmet; - pcl_cid_minmax_t minmax; -} pcl_cid_col_long_t; - -typedef struct pcl_cid_Lab_long_s { - pcl_cid_hdr_common; - pcl_cid_minmax_t minmax; -} pcl_cid_Lab_long_t; - -typedef struct pcl_cid_lum_long_s { - pcl_cid_hdr_common; - float matrix[9]; - pcl_cid_minmax_t minmax; - pcl_cid_col_common_t colmet; -} pcl_cid_lum_long_t; - -/* - * The unified PCL configure image data structure. - */ -typedef struct pcl_cid_data_s { - uint16 len; - union { - pcl_cid_hdr_t hdr; - pcl_cid_dev_long_t dev; - pcl_cid_col_long_t col; - pcl_cid_Lab_long_t lab; - pcl_cid_lum_long_t lum; - } u; -} pcl_cid_data_t; - -#define private_st_cid_data_t() \ - gs_private_st_simple( st_cid_data, \ - pcl_cid_data_t, \ - "pcl_cid_data_t" \ - ) - -/* - * Macros to getting configuration parameters from the first six bytes of - * the configure image data structure. - */ -#define pcl_cid_get_cspace(pcid) ((pcl_cspace_type_t)((pcid)->u.hdr.cspace)) - -#define pcl_cid_get_encoding(pcid) \ - ((pcl_encoding_type_t)((pcid)->u.hdr.encoding)) - -#define pcl_cid_get_bits_per_index(pcid) ((pcid)->u.hdr.bits_per_index) - -#define pcl_cid_get_bits_per_primary(pcid, i) \ - ((pcid)->u.hdr.bits_per_primary[i]) - -/* - * Implement the GL/2 IN command. This is probably better done via a reset flag, - * but currently there are no reset flags that propagate out of GL/2. - */ -int pcl_cid_IN(P1(pcl_state_t * pcs)); - -/* - * Entry point for the configure image data code. - */ -extern const pcl_init_t pcl_cid_init; - -#endif /* pccid_INCLUDED */ diff --git a/pcl/pccolor.c b/pcl/pccolor.c deleted file mode 100644 index 16180e8a9..000000000 --- a/pcl/pccolor.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccolor.c - commands to add colors to a PCL palette */ -#include "std.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcpalet.h" - -/* - * Prior to being assigned into a palette, the PCL color component values are - * simple globals; they are not saved and restored with the PCL state. - * - * This implies that color components may not be converted until the set - * color index command is executed, as it is not possible to predict for - * which palette they will be used. - * - * NB: contrary to the documentation, all of the set color component commands - * and the assign color index command are allowed but ignored in graphics - * mode (i.e.: they do NOT end graphics mode, as one would expect from the - * documentation). - */ - -/* - * ESC * v <cc> A - */ - private int -set_color_comp_1( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) - pcs->color_comps[0] = float_arg(pargs); - return 0; -} - -/* - * ESC * v <cc> B - */ - private int -set_color_comp_2( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) - pcs->color_comps[1] = float_arg(pargs); - return 0; -} - -/* - * ESC * v <cc> C - */ - private int -set_color_comp_3( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) - pcs->color_comps[2] = float_arg(pargs); - return 0; -} - -/* - * ESC * v <indx> I - * - * Set a color into the active palette. - * - * This implementation matches HP's documentation, in that out-of-range indices - * will not affect the palette, but will reset the color component registers. - * This matches the behavior of the HP Color Laser Jet 5/5M, but not that of - * the HP DeskJet 1600C/CM. For the latter, negative indices are ignored and - * the color component registers are NOT cleared, while positive indices are - * interpreted modulo the palette size. - */ - private int -assign_color_index( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int indx = int_arg(pargs); - - if (!pcs->raster_state.graphics_mode) { - if ((indx >= 0) && (indx < pcl_palette_get_num_entries(pcs->ppalet))) - pcl_palette_set_color(pcs, indx, pcs->color_comps); - pcs->color_comps[0] = 0.0; - pcs->color_comps[1] = 0.0; - pcs->color_comps[2] = 0.0; - } - return 0; -} - -/* - * Initialization - */ - private int -color_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ -#ifndef PCL5EMONO - /* Register commands */ - DEFINE_CLASS('*') - { - 'v', 'A', - PCL_COMMAND( "Color Component 1", - set_color_comp_1, - pca_neg_ok | pca_big_error | pca_raster_graphics | pca_in_rtl - ) - }, - { - 'v', 'B', - PCL_COMMAND( "Color Component 2", - set_color_comp_2, - pca_neg_ok | pca_big_error | pca_raster_graphics | pca_in_rtl - ) - }, - { - 'v', 'C', - PCL_COMMAND( "Color Component 3", - set_color_comp_3, - pca_neg_ok | pca_big_error | pca_raster_graphics | pca_in_rtl - ) - }, - { - 'v', 'I', - PCL_COMMAND( "Assign Color Index", - assign_color_index, - pca_neg_ok | pca_big_ignore | pca_raster_graphics | pca_in_rtl - ) - }, - END_CLASS -#endif - return 0; -} - -/* - * Handle the various forms of reset. - */ - private void -color_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_cold - | pcl_reset_printer ); - - if ((type & mask) != 0) { - pcs->color_comps[0] = 0.0; - pcs->color_comps[1] = 0.0; - pcs->color_comps[2] = 0.0; - } -} - -/* - * There is no copy operation for this module, as the color components are - * just globals. - */ -const pcl_init_t pcl_color_init = { color_do_registration, color_do_reset, 0 }; diff --git a/pcl/pccoord.h b/pcl/pccoord.h deleted file mode 100644 index 4c7efc478..000000000 --- a/pcl/pccoord.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccoord.h - centipoint coordinate structures for PCL */ - -#ifndef pccoord_INCLUDED -#define pccoord_INCLUDED - -/* - * Following the PCL documentation, we represent coordinates internally in - * centipoints (1/7200"). - */ -#if arch_sizeof_int == 2 -typedef long coord; -#else -typedef int coord; -#endif - -#define pcl_coord_scale 7200 -#define inch2coord(v) ((coord)((v) * (coord)pcl_coord_scale)) -#define coord2inch(c) ((c) / (float)pcl_coord_scale) - -typedef struct coord_point_s { - coord x, y; -} coord_point_t; - -#endif /* pccoord_INCLUDED */ diff --git a/pcl/pccprint.c b/pcl/pccprint.c deleted file mode 100644 index 5c24783aa..000000000 --- a/pcl/pccprint.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccprint.c - PCL5c print model commands */ - -#include "std.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcfont.h" -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsstate.h" -#include "gsrop.h" - -/* - * ESC * l <rop> O - * - * Set logical operation. - */ - private int -pcl_logical_operation( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint rop = uint_arg(pargs); - - if (rop > 255) - return e_Range; - - pcl_break_underline(pcs); /* use the 5c convention; in 5e, the - * underline is not broken by a change in - * the logical operation */ - pcs->logical_op = rop; - return 0; -} - -/* - * ESC * l <bool> R - * - * Set prixel placement. Note that this feature is not yet properly - * implemented. - */ - private int -pcl_pixel_placement( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if (i > 1) - return 0; - pcs->pp_mode = i; - return 0; -} - -/* - * Initialization - */ - private int -pccprint_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - /* Register commands */ - DEFINE_CLASS('*') - { - 'l', 'O', - PCL_COMMAND( "Logical Operation", - pcl_logical_operation, - pca_neg_ok | pca_big_error | pca_in_rtl - ) - }, - { - 'l', 'R', - PCL_COMMAND( "Pixel Placement", - pcl_pixel_placement, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS - return 0; -} - - private void -pccprint_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_printer - | pcl_reset_overlay ); - - if ((type & mask) != 0) { - pcs->logical_op = 252; - pcs->pp_mode = 0; - } -} - -const pcl_init_t pccprint_init = { pccprint_do_registration, pccprint_do_reset, 0 }; diff --git a/pcl/pccrd.c b/pcl/pccrd.c deleted file mode 100644 index 91d0d9267..000000000 --- a/pcl/pccrd.c +++ /dev/null @@ -1,341 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccrd.c - PCL interface to the graphic library color rendering dictionary */ -#include "string_.h" -#include "gx.h" -#include "gxdevcli.h" -#include "gsmatrix.h" -#include "gsmemory.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gsparam.h" -#include "gsdevice.h" -#include "gscspace.h" -#include "gscolor2.h" -#include "gscie.h" -#include "gscrd.h" -#include "gscrdp.h" -#include "pcommand.h" -#include "pccrd.h" - -/* GC routines */ -private_st_crd_t(); - -/* - * The default color rendering information. This works for a monitor that - * uses linear SMPTE-C phosphors. This is almost certainly not the case for - * any actual printing device, but the approximation will do for now. - * - * The following parameters are left at their graphic-library default values: - * - * BlackPoint - * MatrixPQR - * RangePQR - * EncodeLMN - * RangeLMN - * MatrixABC - * EncodeABC - * RangeABC - * RenderTable - * - */ -private const gs_vector3 dflt_WhitePoint = { 0.95, 1.0, 1.09 }; -private const gs_matrix3 dflt_MatrixLMN = { { 3.51, -1.07, 0.06 }, - { -1.74, 1.98, -0.20 }, - { -0.54, 0.04, 1.05 }, - false }; - -/* - * The TransformPQR structure. - * - * Unlike the earlier impelementations, there is now just a single procedure, - * which accepts the the component index as an operand. Rather than returning - * the mapped value, the location pointed to by pnew_val is used to hold the - * result and a success (0) or error (< 0) indication is returned. - */ - private int -dflt_TransformPQR_proc( - int cmp_indx, - floatp val, - const gs_cie_wbsd * cs_wbsd, - gs_cie_render * pcrd, - float * pnew_val -) -{ - const float * pcrd_wht = (float *)&(cs_wbsd->wd.pqr); - const float * pcs_wht = (float *)&(cs_wbsd->ws.pqr); - - *pnew_val = val * pcrd_wht[cmp_indx] / pcs_wht[cmp_indx]; - return 0; -} - -private const gs_cie_transform_proc3 dflt_TransformPQR_proto = { - dflt_TransformPQR_proc, - NULL, - { NULL, 0 }, - NULL -}; - -/* - * Free a PCL color rendering dictionary structure. - */ - private void -free_crd( - gs_memory_t * pmem, - void * pvcrd, - client_name_t cname -) -{ - pcl_crd_t * pcrd = (pcl_crd_t *)pvcrd; - - if (pcrd->pgscrd != 0) - rc_decrement(pcrd->pgscrd, cname); - gs_free_object(pmem, pvcrd, cname); -} - -/* - * Allocate a PCL color rendering dictionary structure. - */ - private int -alloc_crd( - pcl_crd_t ** ppcrd, - gs_memory_t * pmem -) -{ - pcl_crd_t * pcrd = 0; - int code = 0; - - rc_alloc_struct_1( pcrd, - pcl_crd_t, - &st_crd_t, - pmem, - return e_Memory, - "pcl allocate CRD" - ); - pcrd->rc.free = free_crd; - pcrd->is_dflt_illum = true; - pcrd->pgscrd = 0; - - code = gs_cie_render1_build(&(pcrd->pgscrd), pmem, "pcl allocate CRD"); - if (code >= 0) - *ppcrd = pcrd; - else - free_crd(pmem, pcrd, "pcl allocate CRD"); - return code; -} - -/* - * See if the default CRD is specified by the device. - * - * To simplify selection of more than one default CRD, this code allows more - * than one CRD to be included in the parameters associated with a device, - * and uses the device parameter "CRDName" to select the one that is to be - * used as a default. - * - * Returns - */ - private bool -read_device_CRD( - pcl_crd_t * pcrd, - pcl_state_t * pcs -) -{ - gx_device * pdev = pcl_get_target_device(pcs); - gs_c_param_list list; - gs_param_string dstring; - char nbuff[64]; /* ample size */ - int code = 0; - - /*get the CRDName parameter from the device */ - gs_c_param_list_write(&list, pcs->memory); - if (param_request((gs_param_list *)&list, "CRDName") < 0) - return false; - - if ((code = gs_getdeviceparams(pdev, (gs_param_list *)&list)) >= 0) { - gs_c_param_list_read(&list); - if ( (code = param_read_string( (gs_param_list *)&list, - "CRDName", - &dstring - )) == 0 ) { - if (dstring.size > sizeof(nbuff) - 1) - code = 1; - else { - strncpy(nbuff, (char *)dstring.data, dstring.size); - nbuff[dstring.size] = '\0'; - } - } - } - gs_c_param_list_release(&list); - if (code != 0) - return false; - - gs_c_param_list_write(&list, pcs->memory); - if (param_request((gs_param_list *)&list, nbuff) < 0) - return false; - if ((code = gs_getdeviceparams(pdev, (gs_param_list *)&list)) >= 0) { - gs_param_dict dict; - - gs_c_param_list_read(&list); - if ( (code = param_begin_read_dict( (gs_param_list *)&list, - nbuff, - &dict, - false - )) == 0 ) { - code = param_get_cie_render1(pcrd->pgscrd, dict.list, pdev); - param_end_read_dict((gs_param_list *)&list, nbuff, &dict); - if (code > 0) - code = 0; - } - } - gs_c_param_list_release(&list); - return (code == 0); -} - -/* - * Build the default color rendering dictionary. - * - * This routine should be called only once, and then only when there is no - * current CRD. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_crd_build_default_crd( - pcl_state_t * pcs -) -{ - pcl_crd_t * pcrd = pcs->pcl_default_crd; - int code = 0; - - /* must not be a current CRD */ - if (pcrd != 0) - return e_Range; - - /* allocate the CRD structure */ - if ((code = alloc_crd(&pcrd, pcs->memory)) < 0) - return code; - pcs->pcl_default_crd = pcrd; - - if (read_device_CRD(pcrd, pcs)) - return 0; - else { - pcs->dflt_TransformPQR = dflt_TransformPQR_proto; - return gs_cie_render1_initialize( pcrd->pgscrd, - NULL, - &dflt_WhitePoint, - NULL, - NULL, - NULL, - &pcs->dflt_TransformPQR, - &dflt_MatrixLMN, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - } -} - -/* - * Set the viewing illuminant. - * - * Though this code goes through the motions of an "unshare" operation, it - * will almost always allocate a new structure, as the CRD will be referred - * to both by the palette and the graphic state. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_crd_set_view_illuminant( - pcl_state_t * pcs, - pcl_crd_t ** ppcrd, - const gs_vector3 * pwht_pt -) -{ - pcl_crd_t * pcrd = *ppcrd; - pcl_crd_t * pold = pcrd; - int code = 0; - - if (pcrd->rc.ref_count > 1) { - if ((code = alloc_crd(ppcrd, pcrd->rc.memory)) < 0) - return code; - pcrd = *ppcrd; - } - pcrd->is_dflt_illum = false; - - /* if no previous CRD, use the default settings */ - if (pold == 0) { - pcs->dflt_TransformPQR = dflt_TransformPQR_proto; - return gs_cie_render1_initialize( pcrd->pgscrd, - NULL, - pwht_pt, - NULL, - NULL, - NULL, - &pcs->dflt_TransformPQR, - &dflt_MatrixLMN, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - } - code = gs_cie_render1_init_from( pcrd->pgscrd, - NULL, /* for now */ - pold->pgscrd, - pwht_pt, - &(pold->pgscrd->points.BlackPoint), - &(pold->pgscrd->MatrixPQR), - &(pold->pgscrd->RangePQR), - &(pold->pgscrd->TransformPQR), - &(pold->pgscrd->MatrixLMN), - &(pold->pgscrd->EncodeLMN), - &(pold->pgscrd->RangeLMN), - &(pold->pgscrd->MatrixABC), - &(pold->pgscrd->EncodeABC), - &(pold->pgscrd->RangeABC), - &(pold->pgscrd->RenderTable) - ); - - if (pcrd != pold) - rc_decrement(pold, "pcl set viewing illuminant"); - return code; -} - -/* - * Set a color rendering dictionary into the graphic state. If the rendering - * dictionary does not yet exist, create a default color rendering dictionary. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_crd_set_crd( - pcl_crd_t ** ppcrd, - pcl_state_t * pcs -) -{ - pcl_crd_t * pcrd = *ppcrd; - int code = 0; - - if (pcrd == 0) { - if ( (pcs->pcl_default_crd == 0) && - ((code = pcl_crd_build_default_crd(pcs)) < 0) ) - return code; - pcrd = pcs->pcl_default_crd; - pcl_crd_init_from(*ppcrd, pcrd); - } - - /* see if there is anything to do */ - if (pcs->pids->pcrd == pcrd) - return 0; - - if ((code = gs_setcolorrendering(pcs->pgs, pcrd->pgscrd)) >= 0) - pcl_crd_copy_from(pcs->pids->pcrd, pcrd); - return code; -} diff --git a/pcl/pccrd.h b/pcl/pccrd.h deleted file mode 100644 index 6b1815893..000000000 --- a/pcl/pccrd.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccrd.h - PCL interface to color rendering dictionaries */ - -#ifndef pccrd_INCLUDED -#define pccrd_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gsmatrix.h" -#include "gscspace.h" -#include "gscolor2.h" -#include "gscie.h" -#include "gscrd.h" -#include "pcident.h" -#include "pcstate.h" - -/* - * In PCL, color rendering dictionaries are set by the device, but the - * default white point is specified by the language, and the white point - * may be modified by the language via the "View Illuminant" command. - * - * Though trivial in principle, this arrangement is a bit awkward for the - * graphic library as there is no make-unique functionality provided - * for color rendering dictionaries (none is necessary for PostScript as - * color rendering dictionaries may not be modified once they are set). - * - * This code hides some of the structure of the graphic library color - * rendering objects from the rest of the PCL code. - */ - -/* - * The PCL id exists to provide an identifier for a color rendering - * dictionary. Having such an identifier is important to avoid the need - * to repeatedly re-insert the color rendering dictionary into the - * graphic state. - * - * The is_dflt_illum flag is used to optimize the case in which a CRD that - * already uses the default view illuminant is once again set to use this - * view illuminant. - */ -struct pcl_crd_s { - rc_header rc; - bool is_dflt_illum; - gs_cie_render * pgscrd; -}; - -#define private_st_crd_t() \ - gs_private_st_ptrs1( st_crd_t, \ - pcl_crd_t, \ - "pcl color rendering dictionary", \ - crd_enum_ptrs, \ - crd_reloc_ptrs, \ - pgscrd \ - ) - -#ifndef pcl_crd_DEFINED -#define pcl_crd_DEFINED -typedef struct pcl_crd_s pcl_crd_t; -#endif - -/* - * The usual copy, init, and release macros. - */ -#define pcl_crd_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_crd_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_crd_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_crd_release(pindexed) \ - rc_decrement(pindexed, "pcl_crd_release") - -/* - * Unlike other elements of the PCL "palette", color rendering dictionaries - * are for the most part not a feature that can be controlled from the language. - * Except for the white point, the parameters of a color rendering dictionary - * are determined by the output device rather than the language. - * - * To accommodate this situation, the device-specific or default color - * rendering dictionary is maintained as a global. When used to as part of a - * palette, this global should be "copied" using the copy_from macro provided - * below. - */ -extern pcl_crd_t * pcl_default_crd; - -/* - * Build the default color rendering dictionary. - * - * This routine should be called only once, and then only when there is no - * current CRD. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_crd_build_default_crd(P1(pcl_state_t *pcs)); - -/* - * Set the viewing illuminant. - * - * Though this code goes through the motions of an "unshare" operation, it - * will almost always allocate a new structure, as the CRD will be referred - * to both by the palette and the graphic state. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_crd_set_view_illuminant(P3( - pcl_state_t * pcs, - pcl_crd_t ** ppcrd, - const gs_vector3 * pwht_pt -)); - -/* - * Set a color rendering dictionary into the graphic state. If the rendering - * dictionary does not yet exist, create a default color rendering dictionary. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_crd_set_crd(P2(pcl_crd_t **ppcrd, pcl_state_t *pcs)); - -#endif /* pccrd_INCLUDED */ diff --git a/pcl/pccsbase.c b/pcl/pccsbase.c deleted file mode 100644 index 9d39a65a7..000000000 --- a/pcl/pccsbase.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccsbase.h - base color space code for PCL 5c */ - -#include "gx.h" -#include "math_.h" -#include "gstypes.h" -#include "gsmatrix.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gscspace.h" -#include "gscolor2.h" -#include "gscie.h" -#include "pcmtx3.h" -#include "pccsbase.h" -#include "pcstate.h" - -/* GC routines */ -private_st_cs_base_t(); - -/* - * Handle min/max values for device-independent color spaces. - * - * Examples in HP's "PCL 5 Color Technical Reference Manual" are unclear - * about the interpretation of minimum/maximum value for components for the - * device independent color spaces. It is clear that the "raw" input range - * for these parameters is always [ 0, 255 ], but how this range is mapped - * is not fully obvious. - * - * Empirical observations with both the CIE L*a*b* and the luminance- - * chrominance color space do little to clear up this confusion. In the range - * [ 0, 255 ] (as suggested in the "PCL 5 Color Technical Reference Manual"), - * integer arithmetic overflow seems to occur at some points, leading to - * rather curious color progressions (a moderate brown changes abruptly to - * a dark green at the half-intensity point of a "gray" scale). - * - * Side Note: - * Device dependent color spaces in PCL 5c are not provided with - * ranges, but are assigned white and black points. The interpretation of - * these points is clear: specify the white point to get the maximum - * intensity value for all components on the device, and the black point - * to achieve the minimum value (for printers these are reasonably white - * and black; most screens are adjusted to achieve the same result, - * though there is no strict requirement for this to be the case). - * Values within this range [black_point, white_point] are mapped - * by the obvious linear transformation; values outside of the range - * are clamped to the nearest boundary point. - * - * Two items of note for device dependent color spaces: - * - * a CMY color space is just an RGB color space with the white and - * black points inverted. - * - * For a given value of bits-per-primary, it is quite possible to - * set the white and black points so that one or both may not be - * achievable - * - * In this implementation, the white and black points of the device- - * specific color spaces are handled in the initial "normalization" - * step, before colors are entered into the palette. - * - * To do something sensible for device independent color space ranges, it is - * ncessary to ignore HP's implementation and ask what applications might - * reasonably want to do with the range parameters. The answer depends on the - * particular color space: - * - * a. For colorimetric RGB spaces, the reasonable assumption is that the - * parameters correspond to the range of the input primaries, from - * minimal 0 to full intensity. Furthermore, the white point corresponds - * to the full intensity for each primary, the black point to minimum - * intensity. - * - * The difficulty with this interpretation is that it renders the range - * parameters meaningless. PCL requires input data for device-independent - * color spaces to be in the range [0, 255], with 0 ==> minimum value and - * 255 ==> maximum value. Combined with the assumption above, this will - * always map the "raw" input values {0, 0, 0} and {255, 255, 255} to - * the black and white points, respectively. - * - * To avoid making the range parameters completely meaningless in this - * case, we will actually use a different interpretation. The modification - * continues to map the raw input values such that 0 ==> minimum value - * and 255 ==> maximum value, but the black and white points continue - * to be {0, 0, 0} and {1, 1, 1}. Values outside of this range are - * clipped. - * - * To the extent that we can determine, this interpretation bears some - * relationship to that used by HP. - * - * b. For the CIE L*a*b* space, the interpretation of the value of each - * component is fixed by standards, so the ranges specified in the - * Configure Image Data command can only be interpreted as indicating - * which set of values the "raw" input range [0, 255] should be mapped - * to (0 ==> min_value, 255 ==> max value) - * - * c. For consistency it is necessary to handle the range parameters for - * luminance-chrominance in the same manner as they are handled for the - * colorimetric RGB case. This approach makes even less sense in this - * case than for the colorimetric RGB case, as the region of input space - * that corresponds to real colors for luminance-chrominance spaces is - * not a cube (i.e.: it is possible for each of the components to be - * in a reasonable range, but for the combination to yield primary - * component values < 0 or > 1). There is not much choice about this - * arrangement, however, because a luminance-chrominance space can be - * set up to directly mimic a colorimetric RGB space by setting the - * transformation between the two to the identity transformation. - * - * For all of these range mappings, the initial step is to map the "raw" input - * range to [min_val, max_val], and incorporate the effect of the lookup - * table for the particular color space (if any). This is accomplished by the - * following macro. Note that the initial normalization step has already - * converted the "raw" input range to [0, 1] (the same range as is used by - * device-dependent color spaces). - */ - -#define convert_val(val, min_val, range, plktbl) \ - BEGIN \ - if ((plktbl) != 0) \ - val = (double)(plktbl)[(int)(255 * val)] / 255.0; \ - val = min_val + val * range; \ - END - - -/* - * Default Configure Image Data information for the various color spaces. - * - * The black and white points for device dependent color spaces are not included - * here as those are handled via palette value normalization, not via the color - * space. Since the black and white points are the only parameters for the - * device-specific color spaces, there is no default information here for them - * at all. - * - * Other color spaces have up to three sets of default information: - * - * default parameter ranges (all device-independent color spaces) - * - * the default chromaticity of the primaries (colorimetric RGB and - * luminance-chrominance spaces) - * - * the default conversion between the color components and the primaries - * for which chromaticities have been provided (only luminance- - * chrominance space) - */ -private const pcl_cid_minmax_t cielab_range_default = { - { { 0.0, 100.0 }, { -100.0, 100.0 }, { -100.0, 100.0 } } -}; - -private const pcl_cid_minmax_t colmet_range_default = { - { { 0.0, 1.0 }, { 0.0, 1.0 }, { 0.0, 1.0 } } -}; - -private const pcl_cid_minmax_t lumchrom_range_default = { - { { 0.0, 1.0 }, { -0.89, 0.89 }, { -0.70, 0.70 } } -}; - -private const pcl_cid_col_common_t chroma_default = { - { - { 0.640, 0.340 }, /* "red" primary chromaticity */ - { 0.310, 0.595 }, /* "green" primary chromaticity */ - { 0.155, 0.070 }, /* "blue" chromaticity */ - { 0.313, 0.329 } /* white chromaticity */ - }, - { { 2.2, 1.0 }, { 2.2, 1.0 }, { 2.2, 1.0 } } -}; - -private const float lumchrom_xform_default[9] = { - 0.30, 0.59, 0.11, -0.30, -0.59, 0.89, 0.70, -0.59, -0.11 -}; - -/* structure of default values for all color spaces */ -private const struct { - const pcl_cid_minmax_t * pminmax; - const pcl_cid_col_common_t * pchroma; - const float * pxform; -} cid_data_default[(int)pcl_cspace_num] = { - { 0, 0, 0 }, /* pcl_cspace_RGB */ - { 0, 0, 0 }, /* pcl_cspace_CMY */ - { &colmet_range_default, &chroma_default, 0 }, /* pcl_cspace_Colorimetric */ - { &cielab_range_default, 0, 0}, /* pcl_cspace_CIELab */ - { &lumchrom_range_default, &chroma_default, lumchrom_xform_default } - /* pcl_cspace_LumChrom */ -}; - - -/* - * Code for constructing/modifying the client data structure of PCL base - * color spaces. - */ - -/* - * Set the range parameters for a color space. - */ - private void -set_client_info_range( - pcl_cs_client_data_t * pdata, - const pcl_cid_minmax_t * pminmax -) -{ - int i; - - for (i = 0; i < 3; i++) { - pdata->min_val[i] = pminmax->val_range[i].min_val; - pdata->range[i] = pminmax->val_range[i].max_val - - pminmax->val_range[i].min_val; - } -} - -/* - * Set the gamma/gain information for a color space. - */ - private void -set_client_info_chroma( - pcl_cs_client_data_t * pdata, - const pcl_cid_col_common_t * pchroma -) -{ - int i; - - for (i = 0; i < 3; i++) { - floatp gamma = pchroma->nonlin[i].gamma; - floatp gain = pchroma->nonlin[i].gain; - - pdata->inv_gamma[i] = (gamma == 0.0 ? 1.0 : 1.0 / gamma); - pdata->inv_gain[i] = (gain == 0.0 ? 1.0 : 1.0 / gain); - } -} - -/* - * Build the client information structure for a color space. - */ - private void -build_client_data( - pcl_cs_client_data_t * pdata, - const pcl_cid_data_t * pcid, - gs_memory_t * pmem -) -{ - pcl_cspace_type_t type = pcl_cid_get_cspace(pcid); - const pcl_cid_minmax_t * pminmax = cid_data_default[type].pminmax; - const pcl_cid_col_common_t * pchroma = cid_data_default[type].pchroma; - - /* see if we have long-form information for device-independent spaces */ - if (pcid->len > 6) { - if (type == pcl_cspace_Colorimetric) { - pminmax = &(pcid->u.col.minmax); - pchroma = &(pcid->u.col.colmet); - } else if (type == pcl_cspace_CIELab) - pminmax = &(pcid->u.lab.minmax); - else if (type == pcl_cspace_LumChrom) { - pminmax = &(pcid->u.lum.minmax); - pchroma = &(pcid->u.col.colmet); - } - } - - /* set the range and gamma/gain parameters, as required */ - if (pminmax != 0) - set_client_info_range(pdata, pminmax); - if (pchroma != 0) - set_client_info_chroma(pdata, pchroma); -} - -/* - * Init a client data structure from an existing client data structure. - */ - private void -init_client_data_from( - pcl_cs_client_data_t * pnew, - const pcl_cs_client_data_t * pfrom -) -{ - *pnew = *pfrom; - pcl_lookup_tbl_init_from(pnew->plktbl1, pfrom->plktbl1); - pcl_lookup_tbl_init_from(pnew->plktbl2, pfrom->plktbl2); -} - -/* - * Update the lookup table information in a PCL base color space. - */ - private void -update_lookup_tbls( - pcl_cs_client_data_t * pdata, - pcl_lookup_tbl_t * plktbl1, - pcl_lookup_tbl_t * plktbl2, - gs_memory_t * pmem -) -{ - pcl_lookup_tbl_copy_from(pdata->plktbl1, plktbl1); - pcl_lookup_tbl_copy_from(pdata->plktbl2, plktbl2); -} - -/* - * Free a client data structure. This releases the lookup tables, if they - * are present. - */ -#define free_lookup_tbls(pdata, pmem) \ - update_lookup_tbls((pdata), NULL, NULL, (pmem)) - - -/* - * The colorimetric case. - * - * The information provided with this color space consists of the CIE (x, y) - * chromaticities of the three primaries, and the white point. In order to - * derive a color space from this information, three additional assumptions - * are required: - * - * the intensity (Y value) or the white point is 1.0 (identical to the - * convention used by PostScript) - * - * the white point is achieved by setting each of the primaries to its - * maximum value (1.0) - * - * the black point (in this case, { 0, 0, 0 }, since it is not specified) - * is achieved by setting each of the primaries to its minimum value - * (0.0) - * - * Relaxing the former assumption would only modify the mapping provided by the - * color space by a multiplicative constant. The assumption is also reasonable - * for a printing device: even under the strongest reasonable assumptions, the - * actual intensity achieved by printed output is determined by the intensity - * of the illuminant and the reflectivity of the paper, neither one of which is - * known to the color space. Hence, the value of Y selected is arbitrary (so - * long as it is > 0), and using 1.0 simplifies the calculations a bit. - * - * The second and third assumptions are standard and, in fact, define the - * concept of "white point" and "black point" for the purposes of this color - * space. These assumptions are, however, often either poorly documented or - * not documented at all. At least the former is also not particularly intuitive: - * in an additive color arrangement (such as a display), the color achieved by - * full intensity on each of the primaries may be colored, and its color need - * not correspond to any of the standard "color temperatures" usually used - * as white points. - * - * The assumption is, unfortunately, critical to allow derivation of the - * transformation from the primaries provided to the XYZ color space. If we - * let {Xr, Yr, Zr}, {Xg, Yg, Z,}, and {Xb, Yb, Zb} denote the XYZ coordinates - * of the red, green, and blue primaries, respectively, then the desired - * conversion is: - * - * - - - * {X, Y, Z} = {R, G, B} * | Xr Yr Zr | - * | Xg Yg Zg | - * | Xb Yb Zb | - * - - - * - * The chromaticities of the primaries and the white point are derived by - * adjusting the X, Y, and Z coordinates such that x + y + z = 1. Hence: - * - * x = X / (X + Y + Z) - * - * y = Y / (X + Y + Z) - * - * z = Z / (X + Y + Z) - * - * Note that these relationships preserve the ratios between components: - * - * x / y = X / Y - * - * Hence: - * - * X = (x / y) * Y - * - * Z = ((1 - (x + y)) / y) * Y - * - * Using this relationship, the conversion equation above can be restated as: - * - * - - - * {X, Y, Z} = {R, G, B} * | Yr * xr / yr Yr Yr * zr / yr | - * | Yg * xg / yg Yg Yg * zg / yg | - * | Yb * xb / yb Yb Yb * zb / yb | - * - - - * - * Where zr = 1.0 - (xr + yr), zg = 1.0 - (xg + yg), and zb = 1.0 - (xb + yb). - * - * As discussed above, in order to make the range parameters of the long form - * Configure Image Data command meaningful, we must use the convention that - * full intensity for all components is {1, 1, 1}, and no intensity is - * {0, 0, 0}. Because the transformation is linear, the latter point provides - * no information, but the former establishes the following relationship. - * - * - - - * {Xw, Yw, Zw} = {1, 1, 1} * | Yr * xr / yr Yr Yr * zr / yr | - * | Yg * xg / yg Yg Yg * zg / yg | - * | Yb * xb / yb Yb Yb * zb / yb | - * - - - * - * This is equivalent to: - * - * - - - * {Xw, Yw, Zw} = {Yr, Yg, Yb} * | xr / yr 1.0 zr / yr | - * | xg / yg 1.0 zg / yg | - * | xb / yb 1.0 zb / yb | - * - - - * - * = {Yr, Yg, Yb} * mtx - * - * Using the assumption that Yw = 1.0, we have Xw = xw / yw and Zw = zw / yw - * (zw = 1 - (xw + yw)), so: - * - * {Yr, Yg, Yb} = {xw / yw, 1.0, zw / yw} * mtx^-1 - * - * Since Yr, Yg, and Yb are now known, it is possible to generate the - * RGB ==> XYZ transformation. - * - * HP also provides for a gamma and gain parameter to be applied to each - * primary, though it does not specify exactly what these mean. The - * interpretation provided below (in the EncodeABC procedures) seems to - * correspond with the observed phenomena, though it is not clear that this - * interpretation is correct. Note also that the interpretation of gamma - * requires that component intensities be positive. - */ - -/* - * The EncodeABC procedures for colorimetric RGB spaces. All three procedures - * are the same, except for the array index used. - */ -#define colmet_DecodeABC_proc(procname, indx) \ - private float \ - procname( \ - floatp val, \ - const gs_cie_abc * pabc \ - ) \ - { \ - const pcl_cs_client_data_t * pdata = \ - (const pcl_cs_client_data_t *) \ - pabc->common.client_data; \ - floatp inv_gamma = pdata->inv_gamma[indx]; \ - floatp inv_gain = pdata->inv_gain[indx]; \ - \ - convert_val( val, \ - pdata->min_val[indx], \ - pdata->range[indx], \ - pcl_lookup_tbl_get_tbl(pdata->plktbl1, indx) \ - ); \ - if (val < 0.0) \ - val = 0.0; \ - if (inv_gamma != 1.0) \ - val = pow(val, inv_gamma); \ - if (inv_gain != 1.0) \ - val = 1.0 - (1.0 - val) * inv_gain; \ - return val; \ - } - -colmet_DecodeABC_proc(colmet_DecodeABC_0, 0) -colmet_DecodeABC_proc(colmet_DecodeABC_1, 1) -colmet_DecodeABC_proc(colmet_DecodeABC_2, 2) - -private const gs_cie_abc_proc3 colmet_DecodeABC = { - { colmet_DecodeABC_0, colmet_DecodeABC_1, colmet_DecodeABC_2 } -}; - -/* - * Build the matrix to convert a calibrated RGB color space to XYZ space; see - * the discussion above for the reasoning behind this derivation. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -build_colmet_conv_mtx( - const pcl_cid_col_common_t * pdata, - pcl_vec3_t * pwhite_pt, - pcl_mtx3_t * pmtx -) -{ - pcl_vec3_t tmp_vec; - pcl_mtx3_t inv_mtx; - const float * pf = (float *)pdata->chroma; - int i, code; - - for (i = 0; i < 3; i++) { - floatp x = pf[2 * i]; - floatp y = pf[2 * i + 1]; - - pmtx->a[3 * i] = x / y; - pmtx->a[3 * i + 1] = 1.0; - pmtx->a[3 * i + 2] = (1.0 - x - y) / y; - } - if ((code = pcl_mtx3_invert(pmtx, &inv_mtx)) < 0) - return code; - - pwhite_pt->vc.v1 = pdata->chroma[3].x / pdata->chroma[3].y; - pwhite_pt->vc.v2 = 1.0; - pwhite_pt->vc.v3 = (1.0 - pdata->chroma[3].x - pdata->chroma[3].y) - / pdata->chroma[3].y; - pcl_vec3_xform(pwhite_pt, &tmp_vec, &inv_mtx); - - for (i = 0; i < 9; i++) - pmtx->a[i] *= tmp_vec.va[i / 3]; - return 0; -} - -/* - * Finish the creation of a colorimetric RGB color space. - */ - private int -finish_colmet_cspace( - gs_color_space * pcspace, - const pcl_cid_data_t * pcid -) -{ - pcl_mtx3_t mtxABC; - pcl_vec3_t white_pt; - const pcl_cid_col_common_t * pcoldata; - int code = 0; - - if (pcid->len == 6) - pcoldata = cid_data_default[pcl_cspace_Colorimetric].pchroma; - else - pcoldata = &(pcid->u.col.colmet); - if ((code = build_colmet_conv_mtx(pcoldata, &white_pt, &mtxABC)) < 0) - return code; - - /* RangeABC has the default value */ - *(gs_cie_abc_DecodeABC(pcspace)) = colmet_DecodeABC; - pcl_mtx3_convert_to_gs(&mtxABC, gs_cie_abc_MatrixABC(pcspace)); - - gs_cie_RangeLMN(pcspace)->ranges[0].rmin = 0; - gs_cie_RangeLMN(pcspace)->ranges[0].rmax = white_pt.va[0]; - gs_cie_RangeLMN(pcspace)->ranges[1].rmin = 0; - gs_cie_RangeLMN(pcspace)->ranges[1].rmax = white_pt.va[1]; - gs_cie_RangeLMN(pcspace)->ranges[2].rmin = 0; - gs_cie_RangeLMN(pcspace)->ranges[2].rmax = white_pt.va[2]; - /* DecodeLMN and MatrixLMN have the default values */ - - pcl_vec3_to_gs_vector3(gs_cie_WhitePoint(pcspace), white_pt); - /* BlackPoint has the default value */ - - return 0; -} - -/* - * The CIE L*a*b* case. - * - * The mapping from L*a*b* space to XYZ space is fairly simple over most of - * its range, but becomes complicated in the range of dark grays because the - * dominant cubic/cube root relationship changes to linear in this region. - * - * Let: - * - * f(h) = (h > (6/29)^3 ? h^(1/3) : (29^2 / (3 * 6^2)) * h + 4/29) - * - * g(h) = (h > (6/29)^3 ? 116 * h^(1/3) - 16 : (29/3)^3 * h) - * - * Note that, for h = (6/29)^3, the two different expressions for g(h) yield - * the same result: - * - * 116 * h^(1.3) - 16 = (116 * 6 / 29) - 16 = 24 - 16 = 8, and - * - * (29/3)^3 * h = (29 * 6 / 3 * 29)^3 = 2^3 = 8 - * - * Since each part of g is monotonically increasing, g(h) is itself - * monotonically increasing, and therefore invertible. Similarly, for - * this value of h both expressions for f yield the same result: - * - * h^(1/3) = 6/29, and - * - * (29^2 / (3 * 6^2)) * h + 4/29 = (29^2 * 6^3) / (29^3 * 3 * 6^2) + 4/29 - * - * = 2/29 + 4/29 = 6/29 - * - * Again, the individual parts of f are monotonically increasing, hence f is - * monotonically increasing and therefore invertible. - * - * Let { Xw, 1.0, Yw } be the desired white-point. Then, the conversion from - * XYZ ==> L*a*b* is given by: - * - * L* = g(Y) - * - * a* = 500 * (f(X/Xw) - f(Y)) - * - * b* = 200 * (f(Y) - f(Z/Zw)) - * - * Inverting this relationship, we find that: - * - * Y = g^-1(L*) - * - * X = Xw * f^-1(a* / 500 + f(Y)) = Xw * f^-1(a* / 500 + f(g^-1(L*))) - * - * Z = Zw * f^-1(b* / 200 + f(Y)) = Zw * f^-1(f(g^-1(L*)) - b* / 200) - * - * Before providing expressions for f^-1 and g^-1 (we know from the argument - * above that these functions exist), we should note that the structure of the - * PostScript CIE color spaces cannot deal directly with a relationship such as - * described above, because all cross-component steps (operations that depend - * more than one component) must be linear. It is possible, however, to convert - * the relationship to the required form by extracting the value of Y in two - * steps. This is accomplished by the following algorithm: - * - * T1 = f(g^-1(L*)) - * a1 = a* / 500 - * b1 = b* / 200 - * - - - * { a2, T1, b2 } = { T1, a1, b1 } * | 1 1 1 | - * | 1 0 0 | - * | 0 0 -1 | - * - - - * X = Xw * f^-1(a2) - * Y = f^-1(f(g^-1(L*))) - * Z = Zw * f^-1(b2) - * - * While the handling of the L* ==> Y conversion in this algorithm may seem a - * bit overly complex, it is perfectly legitimate and, as shown below, results - * in a very simple expression. - * - * To complete the algorithm, expressions for f^-1 and g^-1 must be provided. - * These are derived directly from the forward expressions: - * - * f^-1(h) = (h > 6/29 ? h^3 : (3 * 6^2) * (h - 4/29) / 29^2) - * - * g^-1(h) = (h > 8 ? ((h + 16) / 116)^3 : (3/29)^3 * h) - * - * Note that because both f and g change representations at the same point, - * there is only a single representation of f(g^-1(h)) required. Specifically, - * if h > 8, then - * - * g-1(h) = ((h + 16) / 116)^3 > (24 / 116)^3 = (6/29)^3 - * - * so - * - * f(g^-1(h)) = (g^-1(h))^(1/3) = (h + 16) / 116 - * - * while if h <= 8 - * - * g-1(h) = (3/29)^3 * h <= (6/29)^3 - * - * so - * - * f(g-1(h)) = (29^2 / (3 * 6^2)) * g^-1(h) + 4/29 - * - * = ((29^2 * 3^3) / (29^3 * 3 * 6^2)) * h + 4/29 - * - * = h/116 + 16/116 = (h + 16) / 116 - * - * This is the algorithm used below, with the Encode procedures also responsible - * for implementing the color lookup tables (if present). - */ - -/* - * Unlike the other color spaces, the DecodeABC procedures for the CIE L*a*b* - * color space have slightly different code for the different components. The - * conv_code operand allows for this difference. - */ -#define lab_DecodeABC_proc(procname, indx, conv_code) \ - private float \ - procname( \ - floatp val, \ - const gs_cie_abc * pabc \ - ) \ - { \ - const pcl_cs_client_data_t * pdata = \ - (const pcl_cs_client_data_t *)\ - pabc->common.client_data; \ - \ - convert_val( val, \ - pdata->min_val[indx], \ - pdata->range[indx], \ - pcl_lookup_tbl_get_tbl(pdata->plktbl1, indx) \ - ); \ - conv_code; \ - return val; \ - } - -lab_DecodeABC_proc(lab_DecodeABC_0, 0, (val = (val + 16.0) / 116.0)) -lab_DecodeABC_proc(lab_DecodeABC_1, 1, (val /= 500)) -lab_DecodeABC_proc(lab_DecodeABC_2, 2, (val /= 200)) - -private const gs_cie_abc_proc3 lab_DecodeABC = { - { lab_DecodeABC_0, lab_DecodeABC_1, lab_DecodeABC_2 } -}; - -private const gs_matrix3 lab_MatrixABC = { - { 1, 1, 1 }, { 1, 0, 0 }, { 0, 0, -1 }, - false -}; - -/* - * The DecodeLMN procedures for CIE L*a*b* color spaces are all identical - * except for the index. The explicit use of the white point is overkill, - * since we know this will always be the D65 white point with Y normalized - * to 1.0, but it guards against future variations. - */ -#define lab_DecodeLMN_proc(procname, indx) \ - private float \ - procname( \ - floatp val, \ - const gs_cie_common * pcie \ - ) \ - { \ - if (val > 6.0 / 29.0) \ - val = val * val * val; \ - else \ - val = 108 * (29.0 * val + 4) / (29.0 * 29.0 * 29.0); \ - val *= (&(pcie->points.WhitePoint.u))[indx]; \ - return val; \ - } - -lab_DecodeLMN_proc(lab_DecodeLMN_0, 0) -lab_DecodeLMN_proc(lab_DecodeLMN_1, 1) -lab_DecodeLMN_proc(lab_DecodeLMN_2, 2) - -private const gs_cie_common_proc3 lab_DecodeLMN = { - { lab_DecodeLMN_0, lab_DecodeLMN_1, lab_DecodeLMN_2 } -}; - -private const gs_vector3 lab_WhitePoint = { .9504, 1.0, 1.0889 }; - - -/* - * Finish the creation of a CIE L*a*b* color space. - */ - private int -finish_lab_cspace( - gs_color_space * pcspace, - const pcl_cid_data_t * pcid -) -{ - /* RangeABC has the default value */ - *(gs_cie_abc_DecodeABC(pcspace)) = lab_DecodeABC; - *(gs_cie_abc_MatrixABC(pcspace)) = lab_MatrixABC; - - /* RangeLMN and MatrixLMN have the default values */ - *(gs_cie_DecodeLMN(pcspace)) = lab_DecodeLMN; - - gs_cie_WhitePoint(pcspace) = lab_WhitePoint; - /* BlackPoint has the default value */ - return 0; -} - - -/* - * The luminance-chrominance color space - * - * As HP would have it, the matrix provided in the long-form luminance- - * chrominance color space specification maps the calibrated RGB coordinates - * to the coordinates of the source space. This is, of course, the inverse - * of the transform that is useful: from the desired color space to calibrated - * RGB. - * - * The rest of the handling of luminance-chrominance spaces is similar to - * that for colorimetric RGB spaces. Note, however, that in this case the - * RangeLMN is the default value (primary components must be clipped to - * [0, 1]), and the DecodeLMN function must verify that its output is still - * in this range. - * - * As commented upon elsewhere, HP allows multiple lookup tables to be attached - * to the same color space, but does not clarify what this should do. The - * lookup table for the device dependent color spaces is not a problem; this - * is implemented as a transfer function. The situation with device independent - * color spaces is not as clear. The choice made here is to allow two device - * independent lookup tables to be applied to the luminance-chrominance color - * space: the luminance-chrominance lookup table and the colorimetric RGB - * lookup table. This does not match HP's behavior, but the latter does not - * make any sense, so this should not be an issue. - */ - -/* - * The DecodeABC procedures for luminance-chrominance color space are simple. - */ -#define lumchrom_DecodeABC_proc(procname, indx) \ - private float \ - procname( \ - floatp val, \ - const gs_cie_abc * pabc \ - ) \ - { \ - const pcl_cs_client_data_t * pdata = \ - (const pcl_cs_client_data_t *) \ - pabc->common.client_data; \ - \ - convert_val( val, \ - pdata->min_val[indx], \ - pdata->range[indx], \ - pcl_lookup_tbl_get_tbl(pdata->plktbl1, indx) \ - ); \ - return val; \ - } - -lumchrom_DecodeABC_proc(lumchrom_DecodeABC_0, 0) -lumchrom_DecodeABC_proc(lumchrom_DecodeABC_1, 1) -lumchrom_DecodeABC_proc(lumchrom_DecodeABC_2, 2) - -private const gs_cie_abc_proc3 lumchrom_DecodeABC = { - { lumchrom_DecodeABC_0, lumchrom_DecodeABC_1, lumchrom_DecodeABC_2 } -}; - -/* - * The DecodeLMN procedures for luminance-chrominance spaces are similar - * to the colorimetric DecodeABC procedures. Since there is no Range* parameter - * for the XYZ components, this procedure checks the range of its output. - */ -#define lumchrom_DecodeLMN_proc(procname, indx) \ - private float \ - procname( \ - floatp val, \ - const gs_cie_common * pcie \ - ) \ - { \ - const pcl_cs_client_data_t * pdata = \ - (const pcl_cs_client_data_t *)\ - pcie->client_data; \ - floatp inv_gamma = pdata->inv_gamma[indx]; \ - floatp inv_gain = pdata->inv_gain[indx]; \ - \ - convert_val( val, \ - 0.0, \ - 1.0, \ - pcl_lookup_tbl_get_tbl(pdata->plktbl2, indx)); \ - if (inv_gamma != 1.0) \ - val = pow(val, inv_gamma); \ - if (inv_gain != 1.0) \ - val = 1.0 - (1.0 - val) * inv_gain; \ - if (val < 0.0) \ - val = 0.0; \ - else if (val > 1.0) \ - val = 1.0; \ - return val; \ - } - -lumchrom_DecodeLMN_proc(lumchrom_DecodeLMN_0, 0) -lumchrom_DecodeLMN_proc(lumchrom_DecodeLMN_1, 1) -lumchrom_DecodeLMN_proc(lumchrom_DecodeLMN_2, 2) - -private const gs_cie_common_proc3 lumchrom_DecodeLMN = { - { lumchrom_DecodeLMN_0, lumchrom_DecodeLMN_1, lumchrom_DecodeLMN_2 } -}; - - -/* - * Build the MatrixABC value for a luminance/chrominance color space. Note that - * this is the inverse of the matrix provided in the Configure Image Data - * command. - * - * Return 0 on success, < 0 in the event of an error. - */ - private int -build_lum_chrom_mtxABC( - const float pin_mtx[9], - pcl_mtx3_t * pmtxABC -) -{ - int i; - pcl_mtx3_t tmp_mtx; - - /* transpose the input to create a row-order matrix */ - for (i = 0; i < 3; i++) { - int j; - - for (j = 0; j < 3; j++) - tmp_mtx.a[i * 3 + j] = pin_mtx[i + 3 * j]; - } - - return pcl_mtx3_invert(&tmp_mtx, pmtxABC); -} - -/* - * Finish the creation of a luminance-chrominance color space. - */ - private int -finish_lumchrom_cspace( - gs_color_space * pcspace, - const pcl_cid_data_t * pcid -) -{ - const float * pin_mtx; - pcl_mtx3_t mtxABC, mtxLMN; - pcl_vec3_t white_pt; - const pcl_cid_col_common_t * pcoldata; - int code = 0; - - if (pcid->len == 6) { - pcoldata = cid_data_default[pcl_cspace_LumChrom].pchroma; - pin_mtx = cid_data_default[pcl_cspace_LumChrom].pxform; - } else { - pcoldata = &(pcid->u.lum.colmet); - pin_mtx = pcid->u.lum.matrix; - } - - if ( ((code = build_lum_chrom_mtxABC(pin_mtx, &mtxABC)) < 0) || - ((code = build_colmet_conv_mtx(pcoldata, &white_pt, &mtxLMN)) < 0) ) - return code; - - /* RangeABC has the default value */ - *(gs_cie_abc_DecodeABC(pcspace)) = lumchrom_DecodeABC; - pcl_mtx3_convert_to_gs(&mtxABC, gs_cie_abc_MatrixABC(pcspace)); - - /* RangeLMN has the default value */ - *(gs_cie_DecodeLMN(pcspace)) = lumchrom_DecodeLMN; - pcl_mtx3_convert_to_gs(&mtxLMN, gs_cie_MatrixLMN(pcspace)); - - pcl_vec3_to_gs_vector3(gs_cie_WhitePoint(pcspace), white_pt); - /* BlackPoint has the default value */ - - return 0; -} - -private int (*const finish_cspace[(int)pcl_cspace_num])( gs_color_space *, - const pcl_cid_data_t * - ) = { - 0, /* pcl_cspace_RGB */ - 0, /* pcl_cspace_CMY */ - finish_colmet_cspace, /* pcl_cspace_Colorimetric */ - finish_lab_cspace, /* pcl_cspace_CIELab */ - finish_lumchrom_cspace /* pcl_cspace_LumChrom */ -}; - - -/* - * Free a PCL base color space. This decrements the reference count for the - * GS color space, and frees any lookup tables that might have been - * used (device independent color spaces only). - */ - private void -free_base_cspace( - gs_memory_t * pmem, - void * pvbase, - client_name_t cname -) -{ - pcl_cs_base_t * pbase = (pcl_cs_base_t *)pvbase; - - if (pbase->pcspace != 0) { - gs_cspace_release(pbase->pcspace); - gs_free_object(pmem, pbase->pcspace, cname); - } - free_lookup_tbls(&(pbase->client_data), pmem); - gs_free_object(pmem, pvbase, cname); -} - -/* - * Allocate a PCL base color space. - * - * Because a PCL base color space and the associated graphic-library color - * space must be kept in a one-to-one relationship, the latter color space is - * allocated here as well. For this reason the PCL color space type is - * an operand. - * - * Returns 0 on success, e_Memory in the event of a memory error. - */ - private int -alloc_base_cspace( - pcl_cs_base_t ** ppbase, - pcl_cspace_type_t type, - gs_memory_t * pmem -) -{ - pcl_cs_base_t * pbase = 0; - int code; - - *ppbase = 0; - rc_alloc_struct_1( pbase, - pcl_cs_base_t, - &st_cs_base_t, - pmem, - return e_Memory, - "allocate pcl base color space" - ); - pbase->rc.free = free_base_cspace; - pbase->type = type; - pbase->client_data.plktbl1 = 0; - pbase->client_data.plktbl2 = 0; - pbase->pcspace = 0; - - if (type == pcl_cspace_White) - code = gs_cspace_build_DeviceGray(&(pbase->pcspace), pmem); - else if (type <= pcl_cspace_CMY) - code = gs_cspace_build_DeviceRGB(&(pbase->pcspace), pmem); - else - code = gs_cspace_build_CIEABC( &(pbase->pcspace), - &(pbase->client_data), - pmem - ); - if (code < 0) - free_base_cspace(pmem, pbase, "allocate pcl base color space"); - else - *ppbase = pbase; - return code; -} - -/* - * Create a unique instance of a pcl_cs_base_t object (if one does not already - * exist). - * - * This code is not fully legitimate. To assure that a PCL base color space is - * unique, it is also necessary to assure that the associated graphics library - * color space is unique. Unfortunately, that is not a simple matter, because - * graphic library color spaces are not themselves reference counted, though - * they have reference-counted elements. - * - * We can get away with this arrangement for now by relying on a one-to-one - * association between PCL base color spaces and the associated graphic library - * color spaces. For all current implementations of the graphic library this - * will work. The code may fail, however, for implementations that use a - * "lazy evaluation" technique, as these may require access to the graphics - * library color space after the PCL base color space has been released (the - * graphic library color space will still be present in this case, but its - * client data may have been changed). - */ - private int -unshare_base_cspace( - pcl_cs_base_t ** ppbase -) -{ - pcl_cs_base_t * pbase = *ppbase; - pcl_cs_base_t * pnew = 0; - int code; - - /* check if there is anything to do */ - if (pbase->rc.ref_count == 1) - return 0; - rc_decrement(pbase, "unshare PCL base color space"); - - /* allocate a new gs_color_space */ - if ((code = alloc_base_cspace(ppbase, pbase->type, pbase->rc.memory)) < 0) - return code; - pnew = *ppbase; - - /* copy the client data */ - init_client_data_from(&(pnew->client_data), &(pbase->client_data)); - - /* copy the color space (primarily for CIE color spaces; UGLY!!!) */ - if (pbase->type > pcl_cspace_CMY) { - gs_cie_abc * pcs1 = pbase->pcspace->params.abc; - gs_cie_abc * pcs2 = pnew->pcspace->params.abc; - - pcs2->common.install_cspace = pcs1->common.install_cspace; - pcs2->common.RangeLMN = pcs1->common.RangeLMN; - pcs2->common.DecodeLMN = pcs1->common.DecodeLMN; - pcs2->common.MatrixLMN = pcs1->common.MatrixLMN; - pcs2->common.points = pcs1->common.points; - pcs2->RangeABC = pcs1->RangeABC; - pcs2->DecodeABC = pcs1->DecodeABC; - pcs2->MatrixABC = pcs1->MatrixABC; - } else - pnew->pcspace->params.pixel = pbase->pcspace->params.pixel; - return 0; -} - -/* - * Build a PCL base color space. This should be invoked whenever a color space - * is required, typically after a Configure Image Data (CID) command. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_base_build_cspace( - pcl_cs_base_t ** ppbase, - const pcl_cid_data_t * pcid, - gs_memory_t * pmem -) -{ - pcl_cs_base_t * pbase = *ppbase; - pcl_cspace_type_t type = pcl_cid_get_cspace(pcid); - int code = 0; - - /* release the existing color space, if present */ - if (pbase != 0) - rc_decrement(pbase, "build base pcl color space"); - - /* build basic structure and client info. structure */ - if ((code = alloc_base_cspace(ppbase, type, pmem)) < 0) - return code; - pbase = *ppbase; - build_client_data(&(pbase->client_data), pcid, pmem); - - /* fill in color space parameters */ - if ( (finish_cspace[type] != 0) && - ((code = finish_cspace[type](pbase->pcspace, pcid)) < 0) ) - free_base_cspace(pmem, pbase, "build base pcl color space"); - return code; -} - -/* - * Build a special base color space, used for setting the color white. - * This base space is unique in that it uses the DeviceGray graphic library - * color space. - * - * This routine is usually called once at initialization. - */ - int -pcl_cs_base_build_white_cspace( - pcl_state_t * pcs, - pcl_cs_base_t ** ppbase, - gs_memory_t * pmem -) -{ - int code = 0; - - if (pcs->pwhite_cs == 0) - code = alloc_base_cspace(&pcs->pwhite_cs, pcl_cspace_White, pmem); - if (code >= 0) - pcl_cs_base_copy_from(*ppbase, pcs->pwhite_cs); - return code; -} - -/* - * Update the lookup table information for a base color space. This applies - * only to device-independent color spaces (updating device dependent color - * spaces updates the transfer function in the current halftone). Passing a - * null pointer for the lookup table operand resets the tables for ALL color - * spaces to be the identity table. - * - * See the comments in pclookup.h for a description of how device independent - * lookup tables are interpreted in this implementation. - * - * Returns > 0 if the update changed the color space, 0 if the update did not - * change the color space, and < 0 in the event of an error. If the base color - * Space was updated, the current PCL indexed color space (which includes this - * color space as a base color space) must also be updated. - */ - int -pcl_cs_base_update_lookup_tbl( - pcl_cs_base_t ** ppbase, - pcl_lookup_tbl_t * plktbl -) -{ - pcl_cs_base_t * pbase = *ppbase; - pcl_lookup_tbl_t * plktbl1 = pbase->client_data.plktbl1; - pcl_lookup_tbl_t * plktbl2 = pbase->client_data.plktbl2; - int code = 0; - - if (plktbl == 0) { - if ( (pbase->client_data.plktbl1 == 0) && - (pbase->client_data.plktbl2 == 0) ) - return 0; - plktbl1 = 0; - plktbl2 = 0; - - } else { - pcl_cspace_type_t cstype = pbase->type; - pcl_cspace_type_t lktype = pcl_lookup_tbl_get_cspace(plktbl); - - /* lookup tables for "higher" color spaces are always ignored */ - if ( (cstype < lktype) || - (lktype == pcl_cspace_RGB) || - (lktype == pcl_cspace_CMY) ) - return 0; - - /* CIE L*a*b* space and the L*a*b* lookup table must match */ - if ((cstype == pcl_cspace_CIELab) || (lktype == pcl_cspace_CIELab)) { - plktbl1 = plktbl; - } else if (cstype == lktype) - plktbl1 = plktbl; - else - plktbl2 = plktbl; - } - - /* make a unique copy of the base color space */ - if ((code = unshare_base_cspace(ppbase)) < 0) - return code; - pbase = *ppbase; - - /* update the lookup table information */ - update_lookup_tbls( &(pbase->client_data), - plktbl1, - plktbl2, - pbase->rc.memory - ); - - return 1; -} - -/* - * Install a base color space into the graphic state. - * - * The pointer-pointer form of the first operand is for consistency with the - * other "install" procedures. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_base_install( - pcl_cs_base_t ** ppbase, - pcl_state_t * pcs -) -{ - return gs_setcolorspace(pcs->pgs, (*ppbase)->pcspace); -} - -/* - * One-time initialization routine. This exists only to handle possible non- - * initialization of BSS. - */ - void -pcl_cs_base_init(pcl_state_t *pcs) -{ - pcs->pwhite_cs = 0; -} diff --git a/pcl/pccsbase.h b/pcl/pccsbase.h deleted file mode 100644 index ffd34eb72..000000000 --- a/pcl/pccsbase.h +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pccsbase.h - base color space portion of the PCL 5c palette object */ - -#ifndef pccsbase_INCLUDED -#define pccsbase_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gscspace.h" -#include "pcident.h" -#include "pcommand.h" -#include "pccid.h" -#include "pclookup.h" - - -/* - * The client data structure for use with color-metric RGB, CIE L*a*b*, and - * luminanace-chrominance color spaces. - * - * Two color lookup table pointers are provided, but only the luminance- - * chrominance space will ever use both; for all other space plktbl2 is - * null. The inv_gamma and inv_gain parameters are not used by the CIE L*a*b* - * color space. - */ -typedef struct pcl_cs_client_data_s { - pcl_lookup_tbl_t * plktbl1; /* null ==> identity map */ - pcl_lookup_tbl_t * plktbl2; /* null ==> identity map */ - float min_val[3]; - float range[3]; /* max_val - min_val */ - float inv_gamma[3]; /* 1 / gamma */ - float inv_gain[3]; /* 1 / gain */ -} pcl_cs_client_data_t; - -/* - * Base color space structure for PCL 5c. - * - * The client_data structure is referenced by the color space, but that space - * does not take ownership of the data nor is aware of its content, hence the - * need to keep a separate structure that ties the two elements together. - * - * Note that PCL has the responsibility of keeping this structure around until - * the cloro space is not longer needed. If it fails to do so, the client data - * may not be available when required by the (graphic library) color space. - * This is messy, but to do otherwise would require passing a release function - * along with the client data. - * - * The type field is included to allow subsequent addition of color lookup - * tables; the type is necessary to determine if a color lookup table is - * applicable. - * - * The color space referenced by this structure is always a base color space - * (there is no particular reason it could not be a separation of DeviceN - * color space, but these are not required by the current PCL 5c - * specification.) - */ -typedef struct pcl_cs_base_s { - rc_header rc; - pcl_cspace_type_t type; - pcl_cs_client_data_t client_data; - gs_color_space * pcspace; -} pcl_cs_base_t; - -#define private_st_cs_base_t() \ - gs_private_st_ptrs3( st_cs_base_t, \ - pcl_cs_base_t, \ - "pcl base color space",\ - cs_base_enum_ptrs, \ - cs_base_reloc_ptrs, \ - client_data.plktbl1, \ - client_data.plktbl2, \ - pcspace \ - ) - -/* - * Macros to init, copy, and release PCL base color spaces. - */ -#define pcl_cs_base_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_cs_base_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_cs_base_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_cs_base_release(pbase) \ - rc_decrement(pbase, "pcl_cs_base_release") - - -/* - * Build a PCL base color space. In principle this may be invoked at any time, - * but it should generally be called the first time a color space is required - * after a "configure image data" command. The new color space will always be - * given null color lookup tables (the identity map). - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_base_build_cspace(P3( - pcl_cs_base_t ** ppbase, - const pcl_cid_data_t * pcid, - gs_memory_t * pmem -)); - -/* - * Build a special base color space, used for setting the color white. - * This base space is unique in that it uses the DeviceGray graphic library - * color space. - * - * This routine is usually called once at initialization. - */ -int pcl_cs_base_build_white_cspace(P3( - pcl_state_t * pcs, - pcl_cs_base_t ** ppbase, - gs_memory_t * pmem -)); - -/* - * Update the lookup table information for a PCL base color space. This is - * necessary only for lookup tables associated with device-independent color - * spaces; lookup tables for the device dependent color spaces are implemented - * as transfer functions. - * - * To reset all color lookup tables for device-independent color spaces, call - * with a null second operand. - * - * Returns 1 if successful and the lookup table actually modified the base - * color space, 0 if no modification occurred but there was no error, and < 0 - * in the event of an error. - */ -int pcl_cs_base_update_lookup_tbl(P2( - pcl_cs_base_t ** ppbase, - pcl_lookup_tbl_t * plktbl -)); - -/* - * Install a base color space into the graphic state. - * - * The pointer-pointer form of the first operand is for consistency with the - * other "install" procedures. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_base_install(P2( - pcl_cs_base_t ** ppbase, - pcl_state_t * pcs -)); - -/* - * One-time initialization routine. This exists only to handle possible non- - * initialization of BSS. - */ -void pcl_cs_base_init(P1(pcl_state_t *pcs)); - -#endif /* pccsbase_INCLUDED */ diff --git a/pcl/pcdict.h b/pcl/pcdict.h deleted file mode 100644 index d99ce516c..000000000 --- a/pcl/pcdict.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcdict.h - PCL utilities for interfacing the PL's dictionary mechanism */ - -#ifndef pcdict_INCLUDED -#define pcdict_INCLUDED - -#include "gx.h" - - -/* Define the type for an ID key used in a dictionary. */ -typedef struct pcl_id_s { - uint value; - byte key[2]; /* key for dictionaries */ -} pcl_id_t; - -#define id_key(id) ((id).key) -#define id_value(id) ((id).value) - -#define id_set_key(id, bytes) \ - ( (id).key[0] = (bytes)[0], \ - (id).key[1] = (bytes)[1], \ - (id).value = ((id).key[0] << 8) + (id).key[1] ) - -#define id_set_value(id, val) \ - ( (id).value = (val), (id).key[0] = (val) >> 8, (id).key[1] = (byte)(val) ) - -#endif /* pcdict_INCLUDED */ diff --git a/pcl/pcdither.c b/pcl/pcdither.c deleted file mode 100644 index 7efd15346..000000000 --- a/pcl/pcdither.c +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcdither.c - PCL user-defined dither object implementation */ - -#include "pcommand.h" -#include "pcpalet.h" -#include "pcdither.h" - -/* GC Routines */ -private_st_udither_t(); - -/* - * Return a pointer to the thershold array appropriate for one color plane. - */ - const byte * -pcl_udither_get_threshold( - const pcl_udither_t * pdither, - int indx -) -{ - uint nplanes = pdither->ptbl->nplanes; - - if (nplanes == 1) - return pdither->ptbl->data; - else - return pdither->ptbl->data + indx * pcl_udither_get_size(pdither); -} - -/* - * Free a dither matrix structure. - */ - private void -free_dither_matrix( - gs_memory_t * pmem, - void * pvdither, - client_name_t cname -) -{ - pcl_udither_t * pdither = (pcl_udither_t *)pvdither; - - if (pdither->ptbl != 0) - gs_free_object(pmem, (void *)pdither->ptbl, cname); - gs_free_object(pmem, pvdither, cname); -} - -/* - * ESC * m <nbytes> W - * - * Download dither matrix. - */ - private int -download_dither_matrix( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint len = uint_arg(pargs); - pcl_udither_t * pdither = 0; - const pcl__udither_t * ptbl = (pcl__udither_t *)arg_data(pargs); - uint nplanes, h, w, rlen; - int code = 0; - byte * bp; - - /* check for legitimate parameter values */ - if (len < 7) - return 0; - nplanes = ptbl->nplanes; - h = (ptbl->height[0] << 8) + ptbl->height[1]; - w = (ptbl->width[0] << 8) + ptbl->width[1]; - rlen = nplanes * h * w + 6; - if ( ((nplanes != 1) && (nplanes != 3)) || - (h == 0) || - (w == 0) || - (len < rlen) ) - return e_Range; - - rc_alloc_struct_1( pdither, - pcl_udither_t, - &st_udither_t, - pcs->memory, - return e_Memory, - "download dither matrix" - ); - pdither->rc.free = free_dither_matrix; - pdither->ptbl = 0; - - /* either take possession of buffer, or allocate a new one */ - if (pargs->data_on_heap) - arg_data(pargs) = 0; - else { - pcl__udither_t * ptmp = 0; - - ptmp = (pcl__udither_t *)gs_alloc_bytes( pcs->memory, - rlen, - "donwload dither matrix" - ); - if (ptmp == 0) { - free_dither_matrix( pdither->rc.memory, - pdither, - "download dither matrix" - ); - return e_Memory; - } - memcpy(ptmp, ptbl, rlen); - ptbl = ptmp; - } - pdither->height = h; - pdither->width = w; - pdither->ptbl = ptbl; - - /* do not allow the value 0 in the array - black must be black */ - bp = (byte *)ptbl->data; - rlen -= 6; - while (rlen-- > 0) { - byte b = *bp; - - *bp++ = (b == 0 ? 1 : b); - } - - /* update the dither matrix; release our reference */ - code = pcl_palette_set_udither(pcs, pdither); - pcl_udither_release(pdither); - return code; -} - -/* - * There is no reset or copy procedure for this module, as both functions are - * handled at the palette level. - */ - private int -udither_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmme -) -{ - DEFINE_CLASS('*') - { - 'm', 'W', - PCL_COMMAND("Download Dither Matrix", download_dither_matrix, pca_bytes) - }, - END_CLASS - return 0; -} - -const pcl_init_t pcl_udither_init = { udither_do_registration, 0, 0 }; diff --git a/pcl/pcdither.h b/pcl/pcdither.h deleted file mode 100644 index a3457c6b6..000000000 --- a/pcl/pcdither.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcdither.h - PCL user-defined dither object */ - -#ifndef pcdither_INCLUDED -#define pcdither_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "pcstate.h" -#include "pcommand.h" - -/* - * PCL user-defined dither matrix structure. - * - * This structure is defined by HP. - * - * NB: don't take sizeof of this structure. - * - */ -typedef struct pcl__udither_s { - byte format; - byte nplanes; - byte height[2]; - byte width[2]; - byte data[1 /* actually height * width * nplanes */ ]; -} pcl__udither_t; - -/* - * Header for tha PCL user-defined dither object. This exists to provide a - * reference-counting mechanism for the user-defined dithers. It also is a - * convenient location in which to store endian-adjusted size information - * about the dither. - */ -typedef struct pcl_udither_s { - rc_header rc; - uint height; - uint width; - const pcl__udither_t * ptbl; -} pcl_udither_t; - -#define private_st_udither_t() \ - gs_private_st_ptrs1( st_udither_t, \ - pcl_udither_t, \ - "pcl user defined dither matrix", \ - udither_enum_ptr, \ - udither_reloc_ptr, \ - ptbl \ - ) - -/* - * Copy, init, and release macros. - */ -#define pcl_udither_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_udither_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_udither_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_udither_release(pdither) \ - rc_decrement(pdither, "pcl_udither_release") - -/* - * Macros for retrieving information from a pcl_udither_t structure. - */ -#define pcl_udither_get_nplanes(pdither) ((pdither)->ptbl->nplanes) -#define pcl_udither_get_height(pdither) ((pdither)->height) -#define pcl_udither_get_width(pdither) ((pdither)->width) - -#define pcl_udither_get_size(pdither) ((pdither)->height * (pdither)->width) - -/* - * Get a pointer to the appropriate portion of the dither table in a user - * defined dither structure. - */ -const byte *pcl_udither_get_threshold(P2( - const pcl_udither_t * pdither, - int indx -)); - -/* - * External access to the user-defined dither matrix machinery. - */ -extern const pcl_init_t pcl_udither_init; - -#endif /* pcdither_INCLUDED */ diff --git a/pcl/pcdraw.c b/pcl/pcdraw.c deleted file mode 100644 index 7ae861d2a..000000000 --- a/pcl/pcdraw.c +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcdraw.c - PCL5 drawing utilities */ - -#include "gx.h" -#include "gsmatrix.h" -#include "gscoord.h" -#include "gsstate.h" -#include "gsrop.h" -#include "gxfixed.h" -#include "pcstate.h" -#include "pcht.h" -#include "pccrd.h" -#include "pcpatrn.h" -#include "pcdraw.h" - - -/* - * Set all necessary graphics state parameters for PCL drawing - * (currently only CTM and clipping region). - */ - int -pcl_set_graphics_state( - pcl_state_t * pcs -) -{ - int code = pcl_set_ctm(pcs, true); - - return ( code < 0 ? code - : gx_clip_to_rectangle( pcs->pgs, - &(pcs->xfm_state.dev_print_rect) - ) ); -} - -/* - * Backwards compatibility function. Now, however, it provides accurate - * results. - */ - int -pcl_set_ctm( - pcl_state_t * pcs, - bool use_pd -) -{ - gs_setmatrix( pcs->pgs, - ( use_pd ? &(pcs->xfm_state.pd2dev_mtx) - : &(pcs->xfm_state.lp2dev_mtx) ) - ); - return 0; -} - -/* - * set pcl's drawing color. Uses pcl state values to determine - * rotation and translation of patterns. - * - * The final operand indicates if a PCL raster (image) is being rendered; - * special considerations apply in this case. See the comments in pcbipatrn.c - * pcpatrn.c for further information. - * - * PCL no longer uses the graphic library transparency mechanism. - */ - int -pcl_set_drawing_color( - pcl_state_t * pcs, - pcl_pattern_source_t type, - int id, - bool for_image -) -{ int code; - - /* use PCL's pattern transparency */ - pcs->pattern_transparent = pcs->pcl_pattern_transparent; - - if (type == pcl_pattern_raster_cspace) - code = (pcl_pattern_get_proc_PCL(type))(pcs, 0, true); - else - code = (pcl_pattern_get_proc_PCL(type))(pcs, id, (int)for_image); - if (code >= 0) { - gs_setrasterop(pcs->pgs, (gs_rop3_t)pcs->logical_op); - gs_setfilladjust(pcs->pgs, 0.0, 0.0); - } - return 0; -} - -/* - * The pcl state structure retains information concerning the current contents - * of the grpahic state. To keep this information synchronized with the - * graphic state itself, this information is kept in a stack that is pushed - * or poped, repsectively, for each invocation of gsave and grestore. - * This opertion is prefromed by the following pair of routines, which should - * be used in place of gsave and grestore. - */ - -private_st_gstate_ids_t(); - - int -pcl_gsave( - pcl_state_t * pcs -) -{ - int code = 0; - pcl_gstate_ids_t * pids = gs_alloc_struct( pcs->memory, - pcl_gstate_ids_t, - &st_gstate_ids_t, - "PCL gsave" - ); - - if (pids == 0) - return e_Memory; - - if ((code = gs_gsave(pcs->pgs)) >= 0) { - pids->prev = pcs->pids->prev; - pcs->pids->prev = pids; - pcl_ccolor_init_from(pids->pccolor, pcs->pids->pccolor); - pcl_ht_init_from(pids->pht, pcs->pids->pht); - pcl_crd_init_from(pids->pcrd, pcs->pids->pcrd); - } else - gs_free_object(pcs->memory, pids, "PCL gsave"); - - return code; -} - - int -pcl_grestore( - pcl_state_t * pcs -) -{ - pcl_gstate_ids_t * pids = pcs->pids->prev; - int code = 0; - - /* check for bottom of graphic state stack */ - if (pids == 0) - return e_Range; - if ((code = gs_grestore(pcs->pgs)) >= 0) { - pcs->pids->prev = pids->prev; - pcl_ccolor_copy_from(pcs->pids->pccolor, pids->pccolor); - pcl_ccolor_release(pids->pccolor); - pcl_ht_copy_from(pcs->pids->pht, pids->pht); - pcl_ht_release(pids->pht); - pcl_crd_copy_from(pcs->pids->pcrd, pids->pcrd); - pcl_crd_release(pids->pcrd); - gs_free_object(pcs->memory, pids, "PCL grestore"); - } - - return code; -} - - void -pcl_init_gstate_stk( - pcl_state_t * pcs -) -{ - pcl_gstate_ids_t * pids = gs_alloc_struct( pcs->memory, - pcl_gstate_ids_t, - &st_gstate_ids_t, - "PCL gsave" - ); - if (pids != 0) { /* otherwise will crash soon enough */ - pids->prev = 0; - pids->pccolor = 0; - pids->pht = 0; - pids->pcrd = 0; - } - pcs->pids = pids; -} - -void -pcl_free_gstate_stk(pcl_state_t *pcs) -{ - gs_free_object(pcs->memory, pcs->pids, "PCL grestore"); -} - diff --git a/pcl/pcdraw.h b/pcl/pcdraw.h deleted file mode 100644 index 59039b4c4..000000000 --- a/pcl/pcdraw.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcdraw.h - Interface to PCL5 drawing utilities */ - -#ifndef pcdraw_INCLUDED -#define pcdraw_INCLUDED - -#include "pcstate.h" - -/* compatibility function */ -int pcl_set_ctm(P2(pcl_state_t * pcs, bool print_direction)); - -/* set CTM and clip rectangle for drawing PCL object */ -int pcl_set_graphics_state(P1(pcl_state_t * pcs)); - -/* set the current drawing color */ -int pcl_set_drawing_color(P4( - pcl_state_t * pcs, - pcl_pattern_source_t type, - int pcl_id, - bool for_image -)); - -#endif /* pcdraw_INCLUDED */ diff --git a/pcl/pcfont.c b/pcl/pcfont.c deleted file mode 100644 index 2785ebe9a..000000000 --- a/pcl/pcfont.c +++ /dev/null @@ -1,601 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfont.c */ -/* PCL5 font selection and text printing commands */ -#include "std.h" -#include <stdlib.h> -#include "memory_.h" -/* The following are all for gxfont42.h. */ -#include "gx.h" -#include "gsccode.h" -#include "gsmatrix.h" -#include "gxfont.h" -#include "gxfont42.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcursor.h" -#include "pcfont.h" -#include "pcfsel.h" -#include "pjtop.h" - -/* - * Decache the HMI after resetting the font. According to TRM 5-22, - * this always happens, regardless of how the HMI was set; formerly, - * we only invalidated the HMI if it was set from the font rather than - * explicitly. - */ -#define pcl_decache_hmi(pcs)\ - do {\ - pcs->hmi_cp = HMI_DEFAULT;\ - } while (0) - - -/* Clear the font pointer cache after changing a font parameter. set - * indicates which font (0/1 for primary/secondary). -1 means both. */ -void -pcl_decache_font(pcl_state_t *pcs, int set) -{ - if ( set < 0 ) - { - pcl_decache_font(pcs, 0); - pcl_decache_font(pcs, 1); - } - else - { - pcs->font_selection[set].font = NULL; - pcs->font_selection[set].selected_id = 0; - pcs->g.font_selection[set].font = NULL; - if ( pcs->font_selected == set ) - { - pcs->font = NULL; - pcs->map = NULL; - pcs->g.font = NULL; - pcs->g.map = NULL; - pcl_decache_hmi(pcs); - } - } -} - -/* set current font and symbol table to selected parameter's font and - symbol table */ -private int -pcl_set_font(pcl_state_t *pcs, pcl_font_selection_t *pfs) -{ - pcs->font = pfs->font; - pcs->map = pfs->map; - return 0; -} - -int -pcl_recompute_substitute_font(pcl_state_t *pcs, const uint chr) -{ - pcl_font_selection_t *pfs = &pcs->font_selection[pcs->font_selected]; - int code = pcl_reselect_substitute_font(pfs, pcs, chr); - if ( code < 0 ) - return code; - pcl_set_font(pcs, pfs); - return 0; -} - -/* Recompute the current font from the descriptive parameters. */ -/* This is exported for resetting HMI. */ -int -pcl_recompute_font(pcl_state_t *pcs) -{ pcl_font_selection_t *pfs = &pcs->font_selection[pcs->font_selected]; - int code = pcl_reselect_font(pfs, pcs); - - if ( code < 0 ) - return code; - pcl_set_font(pcs, pfs); - return 0; -} - -/* The font parameter commands all come in primary and secondary variants. */ -private int -pcl_symbol_set(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint num = uint_arg(pargs); - uint symset; - - if ( num > 1023 ) - return e_Range; - /* The following algorithm is from Appendix C of the */ - /* PCL5 Comparison Guide. */ - symset = (num << 5) + pargs->command - 64; - if ( symset != pcs->font_selection[set].params.symbol_set ) - { - pcs->font_selection[set].params.symbol_set = symset; - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( <> others */ -pcl_primary_symbol_set(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_symbol_set(pargs, pcs, 0); -} -private int /* ESC ) <> others */ -pcl_secondary_symbol_set(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_symbol_set(pargs, pcs, 1); -} - -private int -pcl_spacing(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint spacing = uint_arg(pargs); - - if ( spacing > 1 ) - return 0; - if ( spacing != pcs->font_selection[set].params.proportional_spacing ) - { - pcs->font_selection[set].params.proportional_spacing = spacing; - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <prop_bool> P */ -pcl_primary_spacing(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_spacing(pargs, pcs, 0); -} -private int /* ESC ) s <prop_bool> P */ -pcl_secondary_spacing(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_spacing(pargs, pcs, 1); -} - -private int -pcl_pitch(floatp cpi, pcl_state_t *pcs, int set) -{ uint pitch_cp; - pcl_font_selection_t *pfs = &pcs->font_selection[set]; - - if ( cpi < 0.1 ) - cpi = 0.1; - /* Convert characters per inch to 100ths of design units. */ - pitch_cp = 7200.0 / cpi; - if ( pitch_cp > 65535 ) - return e_Range; - if ( pitch_cp < 1 ) - pitch_cp = 1; - if ( pitch_cp != pl_fp_pitch_cp(&pfs->params) ) - { - pl_fp_set_pitch_cp(&pfs->params, pitch_cp); - if ( !pfs->selected_id ) - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <pitch> H */ -pcl_primary_pitch(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_pitch(float_arg(pargs) + 0.005, pcs, 0); -} -private int /* ESC ) s <pitch> H */ -pcl_secondary_pitch(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_pitch(float_arg(pargs) + 0.005, pcs, 1); -} - -private int -pcl_height(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint height_4ths = (uint)(float_arg(pargs) * 4 + 0.5); - pcl_font_selection_t *pfs = &pcs->font_selection[set]; - - if ( height_4ths >= 4000 ) - return e_Range; - if ( height_4ths != pfs->params.height_4ths ) - { - pfs->params.height_4ths = height_4ths; - if ( !pfs->selected_id ) - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <height> V */ -pcl_primary_height(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_height(pargs, pcs, 0); -} -private int /* ESC ) s <height> V */ -pcl_secondary_height(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_height(pargs, pcs, 1); -} - -private int -pcl_style(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint style = uint_arg(pargs); - - if ( style != pcs->font_selection[set].params.style ) - { - pcs->font_selection[set].params.style = style; - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <style> S */ -pcl_primary_style(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_style(pargs, pcs, 0); -} -private int /* ESC ) s <style> S */ -pcl_secondary_style(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_style(pargs, pcs, 1); -} - -private int -pcl_stroke_weight(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ int weight = int_arg(pargs); - - if ( weight < -7 ) - weight = -7; - else if ( weight > 7 ) - weight = 7; - if ( weight != pcs->font_selection[set].params.stroke_weight ) - { - pcs->font_selection[set].params.stroke_weight = weight; - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <weight> B */ -pcl_primary_stroke_weight(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_stroke_weight(pargs, pcs, 0); -} -private int /* ESC ) s <weight> B */ -pcl_secondary_stroke_weight(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_stroke_weight(pargs, pcs, 1); -} - -private int -pcl_typeface(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint typeface = uint_arg(pargs); - - if ( typeface != pcs->font_selection[set].params.typeface_family ) - { - pcs->font_selection[set].params.typeface_family = typeface; - pcl_decache_font(pcs, set); - } - return 0; -} -private int /* ESC ( s <typeface> T */ -pcl_primary_typeface(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_typeface(pargs, pcs, 0); -} -private int /* ESC ) s <typeface> T */ -pcl_secondary_typeface(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_typeface(pargs, pcs, 1); -} - -private int -pcl_font_selection_id(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ uint id = uint_arg(pargs); - pcl_font_selection_t *pfs = &pcs->font_selection[set]; - int code = pcl_select_font_by_id(pfs, id, pcs); - - switch ( code ) - { - default: /* error */ - return code; - case 0: - pcl_decache_font(pcs, -1); - pfs->selected_id = id; - case 1: /* not found */ - return 0; - } -} -private int /* ESC ( <font_id> X */ -pcl_primary_font_selection_id(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_font_selection_id(pargs, pcs, 0); -} -private int /* ESC ) <font_id> X */ -pcl_secondary_font_selection_id(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_font_selection_id(pargs, pcs, 1); -} - -private int -pcl_select_default_font(pcl_args_t *pargs, pcl_state_t *pcs, int set) -{ if ( int_arg(pargs) != 3 ) - return e_Range; - pcl_decache_font(pcs, set); - return e_Unimplemented; -} -private int /* ESC ( 3 @ */ -pcl_select_default_font_primary(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_select_default_font(pargs, pcs, 0); -} -private int /* ESC ) 3 @ */ -pcl_select_default_font_secondary(pcl_args_t *pargs, pcl_state_t *pcs) -{ return pcl_select_default_font(pargs, pcs, 1); -} - -private int /* SO */ -pcl_SO(pcl_args_t *pargs, pcl_state_t *pcs) -{ - if ( pcs->font_selected != 1 ) { - pcs->font_selected = secondary; - pcl_decache_font(pcs, secondary); - } - return 0; -} - -private int /* SI */ -pcl_SI(pcl_args_t *pargs, pcl_state_t *pcs) -{ - if ( pcs->font_selected != 0 ) { - pcs->font_selected = primary; - pcl_decache_font(pcs, primary); - } - return 0; -} - -/* This command is listed only on p. A-7 of the PCL5 Comparison Guide. */ -private int /* ESC & k <mode> S */ -pcl_set_pitch_mode(pcl_args_t *pargs, pcl_state_t *pcs) -{ int mode = int_arg(pargs); - floatp cpi; - - /* - * The specification in the PCL5 Comparison Guide is: - * 0 => 10.0, 2 => 16.67, 4 => 12.0. - */ - switch ( mode ) - { - case 0: cpi = 10.0; break; - case 2: cpi = 16.67; break; - case 4: cpi = 12.0; break; - default: return e_Range; - } - /* - * It's anybody's guess what this is supposed to do. - * We're guessing that it sets the pitch of the currently - * selected font parameter set (primary or secondary) to - * the given pitch in characters per inch. - */ - return pcl_pitch(cpi, pcs, pcs->font_selected); -} - -/* Initialization */ -private int -pcfont_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - { int chr; - /* - * The H-P manual only talks about A through Z, but it appears - * that characters from A through ^ (94) can be used. - */ - for ( chr = 'A'; chr <= '^'; ++chr ) - if ( chr != 'X' ) - { DEFINE_CLASS_COMMAND_ARGS('(', 0, chr, "Primary Symbol Set", - pcl_primary_symbol_set, - pca_neg_error|pca_big_error); - DEFINE_CLASS_COMMAND_ARGS(')', 0, chr, "Secondary Symbol Set", - pcl_secondary_symbol_set, - pca_neg_error|pca_big_error); - } - } - DEFINE_CLASS('(') - {'s', 'P', - PCL_COMMAND("Primary Spacing", pcl_primary_spacing, - pca_neg_ignore|pca_big_ignore)}, - {'s', 'H', - PCL_COMMAND("Primary Pitch", pcl_primary_pitch, - pca_neg_error|pca_big_error)}, - {'s', 'V', - PCL_COMMAND("Primary Height", pcl_primary_height, - pca_neg_error|pca_big_error)}, - {'s', 'S', - PCL_COMMAND("Primary Style", pcl_primary_style, - pca_neg_error|pca_big_clamp)}, - {'s', 'B', - PCL_COMMAND("Primary Stroke Weight", pcl_primary_stroke_weight, - pca_neg_ok|pca_big_error)}, - {'s', 'T', - PCL_COMMAND("Primary Typeface", pcl_primary_typeface, - pca_neg_error|pca_big_ok)}, - {0, 'X', - PCL_COMMAND("Primary Font Selection ID", - pcl_primary_font_selection_id, - pca_neg_error|pca_big_error)}, - {0, '@', - PCL_COMMAND("Default Font Primary", - pcl_select_default_font_primary, - pca_neg_error|pca_big_error)}, - END_CLASS - DEFINE_CLASS(')') - {'s', 'P', - PCL_COMMAND("Secondary Spacing", pcl_secondary_spacing, - pca_neg_ignore|pca_big_ignore)}, - {'s', 'H', - PCL_COMMAND("Secondary Pitch", pcl_secondary_pitch, - pca_neg_error|pca_big_error)}, - {'s', 'V', - PCL_COMMAND("Secondary Height", pcl_secondary_height, - pca_neg_error|pca_big_error)}, - {'s', 'S', - PCL_COMMAND("Secondary Style", pcl_secondary_style, - pca_neg_error|pca_big_clamp)}, - {'s', 'B', - PCL_COMMAND("Secondary Stroke Weight", - pcl_secondary_stroke_weight, - pca_neg_ok|pca_big_error)}, - {'s', 'T', - PCL_COMMAND("Secondary Typeface", pcl_secondary_typeface, - pca_neg_error|pca_big_ok)}, - {0, 'X', - PCL_COMMAND("Secondary Font Selection ID", - pcl_secondary_font_selection_id, - pca_neg_error|pca_big_error)}, - {0, '@', - PCL_COMMAND("Default Font Secondary", - pcl_select_default_font_secondary, - pca_neg_error|pca_big_error)}, - END_CLASS - DEFINE_CONTROL(SO, "SO", pcl_SO) - DEFINE_CONTROL(SI, "SI", pcl_SI) - DEFINE_CLASS('&') - {'k', 'S', - PCL_COMMAND("Set Pitch Mode", pcl_set_pitch_mode, - pca_neg_error|pca_big_error)}, - END_CLASS - return 0; -} - -/* look up pjl font number with data storage type. Return 0 on - success, 1 if we cannot find the font number and -1 if the data - storage type does not exist. Return the font parameters for the - requested font number or the font parameters of the first found - font for the active resource. */ - private int -pcl_lookup_pjl_font(pcl_state_t *pcs, int pjl_font_number, - pcl_data_storage_t pcl_data_storage, pl_font_params_t *params) -{ - pl_dict_enum_t dictp; - gs_const_string key; - void *value; - bool found_resource = false; - - pl_dict_enum_begin(&pcs->soft_fonts, &dictp); - while ( pl_dict_enum_next(&dictp, &key, &value) ) { - pl_font_t *fp = (pl_font_t *)value; - int ds = fp->storage; - if ( (int)pcl_data_storage == ds ) { - found_resource = true; - *params = fp->params; - if ( fp->params.pjl_font_number == pjl_font_number ) { - return 0; - } - } - } - return (found_resource ? 1 : -1); -} - -/* inherit the current pjl font environment */ - int -pcl_set_current_font_environment(pcl_state_t *pcs) -{ - /* Loop through font resources until we find some fonts. Set up - pcl's storage identifier to mirror pjl's */ - pcl_data_storage_t pcl_data_storage; - while( 1 ) { - /* get current font source */ - pjl_envvar_t *fontsource = pjl_proc_get_envvar(pcs->pjls, "fontsource"); - switch (fontsource[0]) { - case 'I': - /* NB what happens if pjl command is not I - hmmph? */ - if (!pcl_load_built_in_fonts(pcs, - pjl_proc_fontsource_to_path(pcs->pjls, fontsource))) { - if ( pcs->personality == rtl ) - /* rtl doesn't use fonts */ - return 0; - else { - dprintf("No built-in fonts found during initialization\n"); - return -1; - } - } - pcl_data_storage = pcds_internal; - break; - case 'S': - /* nothing to load */ - pcl_data_storage = pcds_permanent; - break; - /* NB we incorrectly treat C, C1, C2... as one collective resource */ - case 'C': - if ( !pcl_load_cartridge_fonts(pcs, - pjl_proc_fontsource_to_path(pcs->pjls, fontsource)) ) { - pjl_proc_set_next_fontsource(pcs->pjls); - continue; /* try next resource */ - } - pcl_data_storage = pcds_all_cartridges; - break; - /* NB we incorrectly treat M, M1, M2... as one collective resource */ - case 'M': - if ( !pcl_load_simm_fonts(pcs, - pjl_proc_fontsource_to_path(pcs->pjls, fontsource)) ) { - pjl_proc_set_next_fontsource(pcs->pjls); - continue; /* try next resource */ - } - pcl_data_storage = pcds_all_simms; - break; - default: - dprintf("pcfont.c: unknown pjl resource\n"); - return -1; - } - { - int code; - pl_font_params_t params; - code = pcl_lookup_pjl_font(pcs, - pjl_proc_vartoi(pcs->pjls, - pjl_proc_get_envvar(pcs->pjls, "fontnumber")), - pcl_data_storage, ¶ms); - /* resource found, but if code is 1 we did not match the - font number. NB unsure what to do when code == 1. */ - if ( code >= 0 ) { - /* copy parameters to the requested font and - apply the other pjl settings to construct the - initial font request from pjltrm: "The recommended - order for setting FONTNUMBER, FONTSOURCE, and - SYMSET is SYMSET first, then FONTSOURCE, then - FONTNUMBER". Perhaps this is a clue as to how - these interact. We search for the font number in - the fontsource and apply pjl's SYMSET, PTSIZE and - PITCH to the font we found. That in turn becomes - the default requested font */ - pcs->font_selection[0].params = params; - pcs->default_symbol_set_value = pcs->font_selection[0].params.symbol_set; - /* NB: The fontsource and fontnumber selection - parameters get stepped on next, unless pjl symset, - pitch and ptsize are properly updated by the PJL - interpreter when the font changes. Our pjl - interpreter does not currently do this. - Consequently wrong selections are possible. */ - pcs->default_symbol_set_value = pcs->font_selection[0].params.symbol_set = - pjl_proc_map_pjl_sym_to_pcl_sym(pcs->pjls, - pjl_proc_get_envvar(pcs->pjls, "symset")); - pl_fp_set_pitch_per_inch(&pcs->font_selection[0].params, - pjl_proc_vartof(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "pitch"))); - pcs->font_selection[0].params.height_4ths = - pjl_proc_vartof(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "ptsize")) * 4.0; - pcs->font_selection[0].font = 0; - pcs->font_selection[0].selected_id = 0; - pcs->font_selection[1] = pcs->font_selection[0]; - pcs->font_selected = primary; - pcs->font = 0; - } - else { - /* no resouce found - Note for everything but 'S' this - is a double check, since we should have failed when - checking for the resource Note this is fatal for - internal resources but should be caught above. */ - pjl_proc_set_next_fontsource(pcs->pjls); - continue; /* try next resource */ - - } - } - return 0; /* done */ - } -} - - -private void -pcfont_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ - if ((type & pcl_reset_initial) != 0) { - pcs->font_dir = gs_font_dir_alloc(pcs->memory); - pl_dict_init(&pcs->built_in_fonts, pcs->memory, pl_free_font); - pl_dict_init(&pcs->soft_fonts, pcs->memory, pl_free_font); - pl_dict_set_parent(&pcs->soft_fonts, &pcs->built_in_fonts); - } - if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay) ) { - int code = 0; - if ( pcs->personality != rtl ) - code = pcl_set_current_font_environment(pcs); - /* corrupt configuration */ - if ( code != 0 ) - exit( 1 ); - } - if ( type & pcl_reset_permanent ) { - pl_dict_release(&pcs->soft_fonts); - pl_dict_release(&pcs->built_in_fonts); - gs_free_object(pcs->memory, pcs->font_dir, "pcfont_do_reset"); - } -} - -const pcl_init_t pcfont_init = { - pcfont_do_registration, pcfont_do_reset, 0 -}; diff --git a/pcl/pcfont.h b/pcl/pcfont.h deleted file mode 100644 index 7ecf9c3f5..000000000 --- a/pcl/pcfont.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfont.h - Definitions for PCL5 fonts */ - -#ifndef pcfont_INCLUDED -#define pcfont_INCLUDED - -#include "pcstate.h" -#include "plfont.h" - -/* - * Clear the font pointer cache. Some non-font operations--removing a - * downloaded symbol set, or changing orientations--can cause this. - * set == -1 means all. - */ -void pcl_decache_font(P2(pcl_state_t * pcs, int set)); - -/* - * Recompute the font if necessary. This is exported for resetting HMI. - */ -int pcl_recompute_font(P1(pcl_state_t * pcs)); - -/* - * Recompute the font if the glyph is not found at the time of rendering - */ -int pcl_recompute_substitute_font(P2( - pcl_state_t * pcs, - const uint chr -)); - -/* - * Do any underlining just before a break in motion (vertical motion or - * negative horizontal motion)... - */ -#define pcl_break_underline(pcs) \ - BEGIN \ - if (pcs->underline_enabled) \ - pcl_do_underline(pcs); \ - END - -/* ...and then, after repositioning, restart underlining if necessary... */ -#define pcl_continue_underline(pcs) \ - BEGIN \ - if (pcs->underline_enabled) \ - pcs->underline_start = pcs->cap; \ - END - -void pcl_do_underline(P1(pcl_state_t *pcs)); - -/* Define the common structure of downloaded font headers. */ -typedef struct pcl_font_header_s { - byte FontDescriptorSize[2]; /* must be >=64 */ - byte HeaderFormat; - byte FontType; - byte StyleMSB; - byte Reserved; /* must be 0 */ - byte BaselinePosition[2]; - byte CellWidth[2]; - byte CellHeight[2]; - byte Orientation; - byte Spacing; - byte SymbolSet[2]; - byte Pitch[2]; - byte Height[2]; - byte xHeight[2]; - byte WidthType; - byte StyleLSB; - byte StrokeWeight; - byte TypefaceLSB; - byte TypefaceMSB; - byte SerifStyle; - byte Quality; - byte Placement; - byte UnderlinePosition; - byte UnderlineThickness; - byte TextHeight[2]; - byte TextWidth[2]; - byte FirstCode[2]; - byte LastCode[2]; - byte PitchExtended; - byte HeightExtended; - byte CapHeight[2]; - byte FontNumber[4]; - char FontName[16]; -} pcl_font_header_t; - -/* Define the downloaded font header formats. */ -typedef enum { - pcfh_bitmap = 0, - pcfh_resolution_bitmap = 20, - pcfh_intellifont_bound = 10, - pcfh_intellifont_unbound = 11, - pcfh_truetype = 15, - pcfh_truetype_large = 16 -} pcl_font_header_format_t; - -/* Define the extended of resolution-specified bitmap font header (type 20). */ -typedef struct pcl_resolution_bitmap_header_s { - pcl_font_header_t common; - byte XResolution[2]; - byte YResolution[2]; - char Copyright[1]; -} pcl_resolution_bitmap_header_t; - -#endif /* pcfont_INCLUDED */ diff --git a/pcl/pcfontst.h b/pcl/pcfontst.h deleted file mode 100644 index 1cd503a98..000000000 --- a/pcl/pcfontst.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfontst.h - font information structures for the PCL state */ - -#include "gx.h" -#include "plfont.h" - -#ifndef pcfontst_INCLUDED -#define pcfontst_INCLUDED - -#ifndef pl_font_t_DEFINED -# define pl_font_t_DEFINED -typedef struct pl_font_s pl_font_t; -#endif - -typedef struct pcl_font_selection_s { - /* Parameters used for selection, or loaded from font selected by ID. */ - pl_font_params_t params; - - /* Font found by matching or by ID */ - pl_font_t * font; - uint selected_id; - - /* The symbol map that goes with it. */ - pl_symbol_map_t * map; -} pcl_font_selection_t; - -#endif /* pcfontst_INCLUDED */ diff --git a/pcl/pcfrgrnd.c b/pcl/pcfrgrnd.c deleted file mode 100644 index bcedbbe4f..000000000 --- a/pcl/pcfrgrnd.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfrgrnd.c - PCL foreground object implementation */ -#include "gx.h" -#include "pcommand.h" -#include "pcfont.h" -#include "pcfrgrnd.h" - -/* GC routines */ -private_st_frgrnd_t(); - - -/* - * Free a pcl foreground object. - */ - private void -free_foreground( - gs_memory_t * pmem, - void * pvfrgrnd, - client_name_t cname -) -{ - pcl_frgrnd_t * pfrgrnd = (pcl_frgrnd_t *)pvfrgrnd; - - if (pfrgrnd->pbase != 0) - pcl_cs_base_release(pfrgrnd->pbase); - if (pfrgrnd->pht != 0) - pcl_ht_release(pfrgrnd->pht); - if (pfrgrnd->pcrd != 0) - pcl_crd_release(pfrgrnd->pcrd); - gs_free_object(pmem, pvfrgrnd, cname); -} - -/* - * Allocate a pcl foreground object. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -alloc_foreground( - pcl_state_t *pcs, - pcl_frgrnd_t ** ppfrgrnd, - gs_memory_t * pmem -) -{ - pcl_frgrnd_t * pfrgrnd = 0; - - rc_alloc_struct_1( pfrgrnd, - pcl_frgrnd_t, - &st_frgrnd_t, - pmem, - return e_Memory, - "allocate pcl foreground object" - ); - pfrgrnd->rc.free = free_foreground; - pfrgrnd->id = pcl_next_id(pcs); - pfrgrnd->pbase = 0; - pfrgrnd->pht = 0; - pfrgrnd->pcrd = 0; - *ppfrgrnd = pfrgrnd; - return 0; -} - -/* - * Build a foreground object from a palette object, releasing any exsiting - * foreground object. - * - * There is no "unshare" routine for foreground, as a foreground object cannot - * be modified. - * - * Returns 0 on success, < 0 in the event of an error - */ - private int -build_foreground( - pcl_state_t * pcs, - pcl_frgrnd_t ** ppfrgrnd, - const pcl_palette_t * ppalet, - int pal_entry, - gs_memory_t * pmem -) -{ - pcl_frgrnd_t * pfrgrnd = *ppfrgrnd; - const pcl_cs_indexed_t * pindexed = ppalet->pindexed; - int num_entries = pindexed->num_entries; - bool is_default = false; - int code = 0; - - /* - * Check for a request for the default foreground. Since there are only - * three fixed palettes, it is sufficient to check that the palette provided - * is fixed and has two entries. The default foreground is black, which is - * the second of the two entries. - */ - if ( (pindexed != 0) && - (pindexed->pfixed) && - (num_entries == 2) && - (pal_entry == 1) ) { - is_default = true; - if (pcs->pdflt_frgrnd != 0) { - pcl_frgrnd_copy_from(*ppfrgrnd, pcs->pdflt_frgrnd); - return 0; - } - } - - /* release the existing foreground */ - if (pfrgrnd != 0) { - rc_decrement(pfrgrnd, "build pcl foreground"); - *ppfrgrnd = 0; - } - - if ((code = alloc_foreground(pcs, ppfrgrnd, pmem)) < 0) - return code; - pfrgrnd = *ppfrgrnd; - - /* pal_entry is interpreted modulo the current palette size */ - if ((pal_entry < 0) || (pal_entry >= num_entries)) { - pal_entry %= num_entries; - if (pal_entry < 0) - pal_entry += num_entries; - } - - pfrgrnd->color[0] = pindexed->palette.data[3 * pal_entry]; - pfrgrnd->color[1] = pindexed->palette.data[3 * pal_entry + 1]; - pfrgrnd->color[2] = pindexed->palette.data[3 * pal_entry + 2]; - pcl_cs_base_init_from(pfrgrnd->pbase, ppalet->pindexed->pbase); - pcl_ht_init_from(pfrgrnd->pht, ppalet->pht); - pcl_crd_init_from(pfrgrnd->pcrd, ppalet->pcrd); - - if (is_default) - pcl_frgrnd_init_from(pcs->pdflt_frgrnd, pfrgrnd); - - return 0; -} - -/* - * Build the default foreground. This should be called by the reset function - * for palettes, and should only be called when the current palette is the - * default 2-entry palette. - */ - int -pcl_frgrnd_set_default_foreground( - pcl_state_t * pcs -) -{ - int code = 0; - - /* check that the palette is complete */ - if ((code = pcl_palette_check_complete(pcs)) < 0) - return code; - - return build_foreground( pcs, - &(pcs->pfrgrnd), - pcs->ppalet, - 1, - pcs->memory - ); -} - -/* - * ESC * v # S - * - * Set foreground. It is not clear the handling of negative values is accurate. - */ - private int -set_foreground( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int code; - - pcl_break_underline(pcs); - - /* check that the palette is complete */ - if ((code = pcl_palette_check_complete(pcs)) < 0) - return code; - - return build_foreground( pcs, - &(pcs->pfrgrnd), - pcs->ppalet, - int_arg(pargs), - pcs->memory - ); -} - - -/* - * Initialization, reset, and copy procedures. - * - * There is no reset procedure for this module, as the function is accomplished - * by the palette module. - */ - private int -frgrnd_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ -#ifndef PCL5EMONO - DEFINE_CLASS('*') - { - 'v', 'S', - PCL_COMMAND("Set Foreground", set_foreground, pca_neg_ok) - }, - END_CLASS -#endif - return 0; -} - -private void -frgrnd_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ - if ( type & (pcl_reset_permanent) ) { - /* Release foreground, NB these releases should be moved to - * their corresponding modules. */ - pcl_ht_release(pcs->pdflt_ht); - pcl_cs_base_release(pcs->pdflt_cs_indexed); - pcl_cs_base_release(pcs->pwhite_cs); - pcl_crd_release(pcs->pcl_default_crd); - pcl_frgrnd_release(pcs->pdflt_frgrnd); - pcl_frgrnd_release(pcs->pfrgrnd); - } -} - - private int -frgrnd_do_copy( - pcl_state_t * psaved, - const pcl_state_t * pcs, - pcl_copy_operation_t operation -) -{ - if ((operation & (pcl_copy_before_call | pcl_copy_before_overlay)) != 0) - pcl_frgrnd_init_from(psaved->pfrgrnd, pcs->pfrgrnd); - else if ((operation & pcl_copy_after) != 0) - pcl_frgrnd_release(((pcl_state_t *)pcs)->pfrgrnd); - return 0; -} - -const pcl_init_t pcl_frgrnd_init = { frgrnd_do_registration, frgrnd_do_reset, frgrnd_do_copy }; diff --git a/pcl/pcfrgrnd.h b/pcl/pcfrgrnd.h deleted file mode 100644 index 32097f2f6..000000000 --- a/pcl/pcfrgrnd.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfrgrnd.h - PCL foreground object */ - -#ifndef pcfrgrnd_INCLUDED -# define pcfrgrnd_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "pcstate.h" -#include "pcommand.h" -#include "pccsbase.h" -#include "pcht.h" -#include "pccrd.h" -#include "pcpalet.h" - -/* - * Foreground data structure for PCL 5c; see Chapter 3 of the "PCL 5 Color - * Technical Reference Manual". This structure is part of the PCL state. - * - * The handling of foreground color in PCL 5c is somewhat unintuitive, as - * changing parameters that affect the foreground (rendering method, color - * palette, etc.) does not affect the foreground until the latter is - * explicitly modified. Clearly, this definition reflected HP's particular - * implementation: a set of textures (one per component) is generated for - * the current color index, current color palette, and current rendering - * method when the foreground color command is issued, and this rendered - * representation is stored in the PCL state. - * - * In a system such a Ghostscript graphic library, where rendered - * representations are (properly) not visible to the client, a fair amount - * of information must be kept to achieve the desired behavior. In essence, - * the foreground color maintains the foreground color, base color space, - * halfone/transfer function, and CRD with which it was created. - * - * When necessary, the foreground color also builds one additional color - * space, to work around a limitation in the graphics library. All PCL's - * built-in patterns (including shades) and format 0 user defined patterns - * are, in the PostScript sense, uncolored: they adopt the foreground color - * current when they are rendered. Unfortunately, these patterns also have - * the transparency property of colored patterns: pixels outside of the mask - * can still be opaque. The graphics library does not currently support - * opaque rendering of uncolored patterns, so all PCL patterns are rendered - * as colored. The foreground will build an indexed color space with two - * entries for this purpose. - * - * The foreground structure is reference-counted. It is also assigned an - * identifier, so that we can track when it is necessary to re-render - * uncolored patterns. - */ -struct pcl_frgrnd_s { - rc_header rc; - pcl_gsid_t id; - byte color[3]; - pcl_cs_base_t * pbase; - pcl_ht_t * pht; - pcl_crd_t * pcrd; -}; - -#ifndef pcl_frgrnd_DEFINED -#define pcl_frgrnd_DEFINED -typedef struct pcl_frgrnd_s pcl_frgrnd_t; -#endif - -#define private_st_frgrnd_t() \ - gs_private_st_ptrs3( st_frgrnd_t, \ - pcl_frgrnd_t, \ - "pcl foreground object", \ - frgrnd_enum_ptrs, \ - frgrnd_reloc_ptrs, \ - pbase, \ - pht, \ - pcrd \ - ) - -/* - * The usual init, copy,and release macros. - */ -#define pcl_frgrnd_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_frgrnd_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_frgrnd_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_frgrnd_release(pbase) \ - rc_decrement(pbase, "pcl_frgrnd_release") - -/* - * Get the base color space type from a foreground object - */ -#define pcl_frgrnd_get_cspace(pfrgrnd) ((pfrgrnd)->pbase->type) - -/* - * Build the default foreground. This should be called by the reset function - * for palettes, and should only be called when the current palette is the - * default 2-entry palette. - */ -int pcl_frgrnd_set_default_foreground(P1(pcl_state_t * pcs)); - -#endif /* pcfrgrnd_INCLUDED */ diff --git a/pcl/pcfsel.c b/pcl/pcfsel.c deleted file mode 100644 index fd98136a7..000000000 --- a/pcl/pcfsel.c +++ /dev/null @@ -1,445 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfsel.c */ -/* PCL5 / HP-GL/2 font selection */ -#include "stdio_.h" /* stdio for gdebug */ -#include "gdebug.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcfont.h" -#include "pcfsel.h" -#include "pcsymbol.h" - -/* hack to avoid compiler message */ -#ifndef abs -extern int abs( int ); -#endif - -/* Vector for scoring how well a font matches selection criteria. It - * would be nice to do this with a single scalar, but pitch/height in - * particular require too much info. Elements of the vector correspond - * to the selection criteria, in order - TRM Ch 8. */ -typedef enum { - score_first = 0, - score_symbol_set=score_first, - score_spacing, - score_pitch, - score_height, - score_style, - score_weight, - score_typeface, - score_location, - score_orientation, - score_limit -} score_index_t; -typedef int match_score_t[score_limit]; - -#ifdef DEBUG - -const char *score_name[] = { - "symbol", - "spacing", - "pitch", - "height", - "style", - "weight", - "typeface", - "location", - "orientation", -}; - -private void -dprint_cc(const byte *pcc) -{ dprintf8("cc=%02x %02x %02x %02x %02x %02x %02x %02x", pcc[0], - pcc[1], pcc[2], pcc[3], pcc[4], pcc[5], pcc[6], pcc[7]); -} -private void -dprint_font_params_t(const pl_font_params_t *pfp) -{ dprintf7("symset=%u %s pitch=%g ht=%u style=%u wt=%d face=%u\n", - pfp->symbol_set, - (pfp->proportional_spacing ? "prop." : "fixed"), - pl_fp_pitch_cp(pfp) / 100.0, pfp->height_4ths / 4, pfp->style, - pfp->stroke_weight, pfp->typeface_family); -} -private void -dprint_font_t(const pl_font_t *pfont) -{ dprintf3("storage=%d scaling=%d type=%d ", - pfont->storage, pfont->scaling_technology, pfont->font_type); - dprint_cc(pfont->character_complement); - dputs(";\n "); - dprint_font_params_t(&pfont->params); -} - -#endif - -/* Decide whether an unbound font supports a symbol set (mostly - convenient setup for pcl_check_symbol_support(). (HAS) Has the - peculiar side effect of setting the symbol table to the default if - the requested map is not available or to the requested symbol set - if it is available. 2 is returned for no matching symbol set, 1 for - mismatched vocabulary and 0 if the sets match. */ -private int -check_support(const pcl_state_t *pcs, uint symbol_set, const pl_font_t *fp, - pl_symbol_map_t **mapp) -{ - pl_glyph_vocabulary_t gv = (pl_glyph_vocabulary_t) - (~fp->character_complement[7] & 07); - byte id[2]; - id[0] = symbol_set >> 8; - id[1] = symbol_set; - *mapp = pcl_find_symbol_map(pcs, id, gv); - if ( *mapp == 0 ) - { - id[0] = pcs->default_symbol_set_value >> 8; - id[1] = (byte)(pcs->default_symbol_set_value); - *mapp = pcl_find_symbol_map(pcs, id, gv); - return 0; /* worst */ - } - if ( pcl_check_symbol_support((*mapp)->character_requirements, - fp->character_complement) ) - return 2; /* best */ - else - return 1; -} - -/* Compute a font's score against selection parameters. TRM 8-27. - * Also set *mapp to the symbol map to be used if this font wins. */ -private void -score_match(const pcl_state_t *pcs, const pcl_font_selection_t *pfs, - const pl_font_t *fp, pl_symbol_map_t **mapp, match_score_t score) -{ - int tscore; - - /* 1. Symbol set. 2 for exact match or full support, 1 for - * default supported, 0 for no luck. */ - if ( pl_font_is_bound(fp) ) - { - score[score_symbol_set] = - pfs->params.symbol_set == fp->params.symbol_set? 2: - (fp->params.symbol_set == pcs->default_symbol_set_value); - *mapp = 0; /* bound fonts have no map */ - } - else - score[score_symbol_set] = check_support(pcs, pfs->params.symbol_set, fp, mapp); - /* 2. Spacing. */ - score[score_spacing] = - pfs->params.proportional_spacing == fp->params.proportional_spacing; - - /* 3. Pitch. */ - /* Need to score this so that (1) exact match is highest, (2) any - * higher-than-requested pitch is better than any lower-than- - * requested pitch, (3) within these categories, nearer is better. */ - if ( pfs->params.proportional_spacing ) - score[score_pitch] = 0; /* should not influence score */ - else - { /* The magic hex constants here allow 24 bits + sign to resolve - * the meaning of "close". They are deliberately NOT #defined - * elsewhere because they have no meaning outside this block. */ - if ( pl_font_is_scalable(fp) ) - /* scalable; match is effectively worst possible */ - score[score_pitch] = 0; - else - { - int delta = pl_fp_pitch_per_inch_x100(&fp->params) - - pl_fp_pitch_per_inch_x100(&pfs->params); - - /* If within one unit, call it exact; otherwise give - * preference to higher pitch than requested. */ - if ( abs(delta) <= 1 ) - score[score_pitch] = 0x2000000; - else if ( delta > 0 ) - score[score_pitch] = 0x2000000 - delta; - else - score[score_pitch] = 0x1000000 + delta; - } - } - /* 4. Height. */ - /* Closest match scores highest (no preference for + or -). Otherwise - * similar to pitch, and again, values assigned have no meaning out- - * side this code. */ - if ( pl_font_is_scalable(fp) ) - score[score_height] = 0x1000000; - else - { int delta = abs(pfs->params.height_4ths - fp->params.height_4ths); - - /* As before, allow one unit of error to appear "exact". */ - if ( delta <= 1 ) - delta = 0; - score[score_height] = 0x1000000 - delta; - } - - /* 5. Style. */ - score[score_style] = pfs->params.style == fp->params.style; - - /* 6. Stroke Weight. */ - /* If not exact match, prefer closest value away from 0 (more - * extreme). If none, then prefer closest value nearer 0. Once - * again, the actual values assigned here have no meaning outside - * this chunk of code. */ - { /* Worst cases (font value toward zero from request) 0..13. - * Nearest more extreme: 14..21. 21 is exact. */ - int fwt = fp->params.stroke_weight; - int pwt = pfs->params.stroke_weight; - int delta = pwt - fwt; - - /* With a little time, this could be collapsed. */ - if ( pwt >= 0 ) - if ( fwt >= pwt ) - tscore = 21 + delta; - else - tscore = 14 - delta; - else - if ( fwt <= pwt ) - tscore = 21 - delta; - else - tscore = 14 + delta; - score[score_weight] = tscore; - } - - /* 7. Typeface family. */ - { uint diff = pfs->params.typeface_family ^ fp->params.typeface_family; - - /* Give partial credit for the same typeface from a different */ - /* vendor. */ - score[score_typeface] = - (diff == 0 ? 2 : !(diff & 0xfff) ? 1 : 0); - } - - /* 8. Location. */ - /* Rearrange the value from "storage" into priority for us. We - * only care that we get the priority sequence: soft-font, cartridge, - * SIMM, and internal, and that we order at least 2 cartridges. (TRM - * implies that SIMMs are *not* to be ordered.) Once again, values - * assigned here have no external meaning. */ - /* 1 bit at bottom for SIMM _vs_ internal, then cartridge-number - * bits, then soft-font bit at top. */ - if ( fp->storage & pcds_downloaded ) - tscore = 1 << (pcds_cartridge_max + 1); - else if ( fp->storage & pcds_all_cartridges ) - tscore = (fp->storage & pcds_all_cartridges) >> - (pcds_cartridge_shift - 1); - else - /* no priority among SIMMs, and internal is 0 */ - tscore = (fp->storage & pcds_all_simms)? 1: 0; - score[score_location] = tscore; - - /* 9. Orientation */ - if ( fp->scaling_technology != plfst_bitmap ) - score[score_orientation] = 1; - else - { pcl_font_header_t *fhp = (pcl_font_header_t *)(fp->header); - - score[score_orientation] = fhp? - fhp->Orientation == pcs->xfm_state.lp_orient : - 0; - } - -#ifdef DEBUG - if ( gs_debug_c('=') ) - { int i; - - dprintf1("[=]scoring 0x%lx: ", (ulong)fp); - dprint_font_t(fp); - dputs(" score:"); - for ( i = 0; i < score_limit; ++i ) - dprintf2(" %s: %d", score_name[i], score[i]); - dputs("\n"); - } -#endif - -} - -/* Recompute the current font from the descriptive parameters. */ -/* This is used by both PCL and HP-GL/2. */ -int -pcl_reselect_font(pcl_font_selection_t *pfs, const pcl_state_t *pcs) -{ if ( pfs->font == 0 ) - { pl_dict_enum_t dictp; - gs_const_string key; - void *value; - pl_font_t *best_font = 0; - pl_symbol_map_t *best_map = 0; - pl_symbol_map_t *mapp; - match_score_t best_match; - -#ifdef DEBUG - if ( gs_debug_c('=') ) - { dputs("[=]request: "); - dprint_font_params_t(&pfs->params); - } -#endif - /* if the font table is set up to select character by id - we attempt to reselect the font by id. As a fallback - we use family selection. NB We do not correctly handle - the fonts with alphanumeric id's */ - if ( pfs->selected_id ) { - byte id_key[2]; - void *value; - id_key[0] = pfs->selected_id >> 8; - id_key[1] = (byte)(pfs->selected_id); - if ( pl_dict_find(&pcs->soft_fonts, id_key, 2, &value) ) { - - pfs->font = (pl_font_t *)value; - /* probably not necessary */ - if ( !pl_font_is_bound(pfs->font) ) { - if ( check_support(pcs, pfs->params.symbol_set, pfs->font, &pfs->map) ) - DO_NOTHING; - else if ( check_support(pcs, pcs->default_symbol_set_value, - pfs->font, &pfs->map) - ) - DO_NOTHING; - else { /* - * This font doesn't support the required symbol set. - * Punt -- map 1-for-1. - */ - } - } - return 0; - } - } - /* Initialize the best match to be worse than any real font. */ - best_match[0] = -1; - pl_dict_enum_begin(&pcs->soft_fonts, &dictp); - while ( pl_dict_enum_next(&dictp, &key, &value) ) - { pl_font_t *fp = (pl_font_t *)value; - match_score_t match; - score_index_t i; - score_match(pcs, pfs, fp, &mapp, match); - for (i=(score_index_t)0; i<score_limit; i++) - if ( match[i] != best_match[i] ) - { - if ( match[i] > best_match[i] ) - { - best_font = fp; - best_map = mapp; - memcpy((void*)best_match, (void*)match, - sizeof(match)); - if_debug1('=', " (***best so far, better %s***)\n", score_name[i]); - } - break; - } - } - if ( best_font == 0 ) - return e_Unimplemented; /* no fonts */ - pfs->font = best_font; - pfs->map = best_map; - } - pfs->selected_id = 0; - return 0; -} - -/* Selects a substitute font after a glyph is not found in the - currently selected font upon rendering. Very expensive in the - current architecture. We should have a more efficient way of - finding characters in fonts */ - -/* This is used by both PCL and HP-GL/2. */ -int -pcl_reselect_substitute_font(pcl_font_selection_t *pfs, - const pcl_state_t *pcs, const uint chr) -{ - if ( pfs->font == 0 ) - { - pl_dict_enum_t dictp; - gs_const_string key; - void *value; - pl_font_t *best_font = 0; - pl_symbol_map_t *best_map = 0; - pl_symbol_map_t *mapp; - match_score_t best_match; -#ifdef DEBUG - if ( gs_debug_c('=') ) - { dputs("[=]request: "); - dprint_font_params_t(&pfs->params); - } -#endif - - /* Initialize the best match to be worse than any real font. */ - best_match[0] = -1; - pl_dict_enum_begin(&pcs->soft_fonts, &dictp); - while ( pl_dict_enum_next(&dictp, &key, &value) ) - { pl_font_t *fp = (pl_font_t *)value; - match_score_t match; - score_index_t i; - gs_matrix ignore_mat; - if ( !pl_font_includes_char(fp, NULL, &ignore_mat, chr) ) - continue; - score_match(pcs, pfs, fp, &mapp, match); - for (i=(score_index_t)0; i<score_limit; i++) - if ( match[i] != best_match[i] ) - { - if ( match[i] > best_match[i] ) - { - best_font = fp; - best_map = mapp; - memcpy((void*)best_match, (void*)match, - sizeof(match)); - if_debug0('=', " (***best so far***)\n"); - } - break; - } - } - if ( best_font == 0 ) - return -1; /* no font found */ - pfs->font = best_font; - pfs->map = best_map; - } - pfs->selected_id = 0; - return 0; -} - -/* set font parameters after an id selection */ -void -pcl_set_id_parameters(const pcl_state_t *pcs, - pcl_font_selection_t *pfs, pl_font_t *fp, uint id) -{ - /* Transfer parameters from the selected font into the selection - * parameters, being careful with the softer parameters. */ - pfs->font = fp; - pfs->selected_id = id; - pfs->map = 0; - if ( pl_font_is_bound(fp) ) - pfs->params.symbol_set = fp->params.symbol_set; - else - { if ( check_support(pcs, pfs->params.symbol_set, fp, &pfs->map) ) - DO_NOTHING; - else if ( check_support(pcs, pcs->default_symbol_set_value, - fp, &pfs->map) - ) - DO_NOTHING; - else - { /* - * This font doesn't support the required symbol set. - * Punt -- map 1-for-1. - */ - } - } - pfs->params.proportional_spacing = fp->params.proportional_spacing; - if ( !pfs->params.proportional_spacing && !pl_font_is_scalable(fp) ) - pfs->params.pitch = fp->params.pitch; - if ( !pl_font_is_scalable(fp) ) - pfs->params.height_4ths = fp->params.height_4ths; - pfs->params.style = fp->params.style; - pfs->params.stroke_weight = fp->params.stroke_weight; - pfs->params.typeface_family = fp->params.typeface_family; - return; -} - -/* Select a font by ID, updating the selection parameters. */ -/* Return 0 normally, 1 if no font was found, or an error code. */ -int -pcl_select_font_by_id(pcl_font_selection_t *pfs, uint id, pcl_state_t *pcs) -{ byte id_key[2]; - void *value; - pl_font_t *fp; - - id_key[0] = id >> 8; - id_key[1] = (byte)id; - if ( !pl_dict_find(&pcs->soft_fonts, id_key, 2, &value) ) - return 1; /* font not found */ - fp = (pl_font_t *)value; - pcl_set_id_parameters(pcs, pfs, fp, id); - return 0; -} diff --git a/pcl/pcfsel.h b/pcl/pcfsel.h deleted file mode 100644 index 2fdc3a1e8..000000000 --- a/pcl/pcfsel.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcfsel.h */ -/* Interface to PCL5 / HP-GL/2 font selection */ - -#ifndef pcfsel_INCLUDED -# define pcfsel_INCLUDED - -#include "pcstate.h" - - -/* Recompute the font from the parameters if necessary. */ -/* This is used by both PCL and HP-GL/2. */ -int pcl_reselect_font(P2(pcl_font_selection_t *pfs, const pcl_state_t *pcs)); - -/* fallback if a glyph is not found in a font. This select the best - from the parameters, however, the font is chosen only from the - collection of fonts that actually have the desired character code */ -int pcl_reselect_substitute_font(P3(pcl_font_selection_t *pfs, - const pcl_state_t *pcs, - const uint chr)); -/* - * Select a font by ID, updating the selection parameters. Return 0 - * normally, 1 if no font was found, or an error code. The pcl_state_t is - * used only for the font and symbol set dictionaries. - */ -int pcl_select_font_by_id(P3(pcl_font_selection_t *pfs, uint id, - pcl_state_t *pcs)); - -/* set font parameters after an id selection */ -void -pcl_set_id_parameters(P4(const pcl_state_t *pcs, - pcl_font_selection_t *pfs, pl_font_t *fp, uint id)); - - -#endif /* pcfsel_INCLUDED */ diff --git a/pcl/pcht.c b/pcl/pcht.c deleted file mode 100644 index bd80825f7..000000000 --- a/pcl/pcht.c +++ /dev/null @@ -1,2228 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcht.c - PCL halftone/rendering object implementation */ -#include "gx.h" -#include "math_.h" -#include "gsmemory.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gsdevice.h" -#include "gsparam.h" -#include "gxdevice.h" -#include "gdevcmap.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcdither.h" -#include "pcht.h" - -/* - * GC routines - */ - private -ENUM_PTRS_BEGIN(ht_dither_enum_ptrs) - - return 0; - - case 1: - { - pcl_ht_builtin_dither_t * pdither = (pcl_ht_builtin_dither_t *)vptr; - - if (pdither->type == pcl_halftone_Threshold) - ENUM_RETURN(pdither->u.thresh.pdata); - else if (pdither->type == pcl_halftone_Table_Dither) - ENUM_RETURN(pdither->u.tdither.pdata); - else - return 0; - } -ENUM_PTRS_END - - private -RELOC_PTRS_BEGIN(ht_dither_reloc_ptrs) - pcl_ht_builtin_dither_t * pdither = (pcl_ht_builtin_dither_t *)vptr; - - if (pdither->type == pcl_halftone_Threshold) - RELOC_VAR(pdither->u.thresh.pdata); - else if (pdither->type == pcl_halftone_Table_Dither) - RELOC_VAR(pdither->u.tdither.pdata); -RELOC_PTRS_END - -private_st_ht_builtin_dither_t(); - - - private -ENUM_PTRS_BEGIN(ht_enum_ptrs) - return 0; - ENUM_PTR(0, pcl_ht_t, client_data[0].plktbl); - ENUM_PTR(1, pcl_ht_t, client_data[1].plktbl); - ENUM_PTR(2, pcl_ht_t, client_data[2].plktbl); - ENUM_PTR(3, pcl_ht_t, pdither); - ENUM_STRING_PTR(4, pcl_ht_t, thresholds[0]); - ENUM_STRING_PTR(5, pcl_ht_t, thresholds[1]); - ENUM_STRING_PTR(6, pcl_ht_t, thresholds[2]); - ENUM_PTR(7, pcl_ht_t, pfg_ht); - ENUM_PTR(8, pcl_ht_t, pim_ht); -ENUM_PTRS_END - - private -RELOC_PTRS_BEGIN(ht_reloc_ptrs) - RELOC_PTR(pcl_ht_t, client_data[0].plktbl); - RELOC_PTR(pcl_ht_t, client_data[1].plktbl); - RELOC_PTR(pcl_ht_t, client_data[2].plktbl); - RELOC_PTR(pcl_ht_t, pdither); - RELOC_STRING_PTR(pcl_ht_t, thresholds[0]); - RELOC_STRING_PTR(pcl_ht_t, thresholds[1]); - RELOC_STRING_PTR(pcl_ht_t, thresholds[2]); - RELOC_PTR(pcl_ht_t, pfg_ht); - RELOC_PTR(pcl_ht_t, pim_ht); -RELOC_PTRS_END - -private_st_ht_t(); - -/* - * Built-in dither information. The ordered and clustered-ordered dither - * matrices are fixed so as to give predictable results when used in combination - * with logical operations (raster-ops). - */ -private const byte ordered_dither_data[16 * 16] = { - 142, 46, 174, 6, 134, 38, 166, 12, 140, 44, 172, 4, 132, 36, 164, 14, - 78, 238, 110, 198, 70, 230, 102, 204, 76, 236, 108, 196, 68, 228, 100, 206, - 190, 30, 158, 54, 182, 22, 150, 60, 188, 28, 156, 52, 180, 20, 148, 62, - 126, 222, 94, 246, 118, 214, 86, 252, 124, 220, 92, 244, 116, 212, 84, 254, - 129, 33, 161, 9, 137, 41, 169, 3, 131, 35, 163, 11, 139, 43, 171, 1, - 65, 225, 97, 201, 73, 233, 105, 195, 67, 227, 99, 203, 75, 235, 107, 193, - 177, 17, 145, 57, 185, 25, 153, 51, 179, 19, 147, 59, 187, 27, 155, 49, - 113, 209, 81, 249, 121, 217, 89, 243, 115, 211, 83, 251, 123, 219, 91, 241, - 141, 45, 173, 5, 133, 37, 165, 15, 143, 47, 175, 7, 135, 39, 167, 13, - 77, 237, 109, 197, 69, 229, 101, 207, 79, 239, 111, 199, 71, 231, 103, 205, - 189, 29, 157, 53, 181, 21, 149, 63, 191, 31, 159, 55, 183, 23, 151, 61, - 125, 221, 93, 245, 117, 213, 85, 255, 127, 223, 95, 247, 119, 215, 87, 253, - 130, 34, 162, 10, 138, 42, 170, 1, 128, 32, 160, 8, 136, 40, 168, 2, - 66, 226, 98, 202, 74, 234, 106, 192, 64, 224, 96, 200, 72, 232, 104, 194, - 178, 18, 146, 58, 186, 26, 154, 48, 176, 16, 144, 56, 184, 24, 152, 50, - 114, 210, 82, 250, 122, 218, 90, 240, 112, 208, 80, 248, 120, 216, 88, 242 -}; - -private const byte clustered_dither_data[16 * 16] = { - 228, 164, 40, 8, 24, 152, 199, 247, 231, 167, 43, 11, 27, 155, 196, 244, - 116, 52, 96, 176, 80, 64, 135, 215, 119, 55, 99, 179, 83, 67, 132, 212, - 20, 148, 192, 240, 224, 160, 39, 7, 23, 151, 195, 243, 227, 163, 36, 4, - 94, 78, 128, 208, 112, 48, 109, 189, 93, 77, 131, 211, 115, 51, 111, 190, - 238, 174, 32, 1, 16, 144, 205, 253, 237, 173, 35, 3, 19, 147, 206, 254, - 126, 62, 106, 186, 90, 74, 141, 221, 125, 61, 105, 185, 89, 73, 142, 222, - 30, 158, 202, 250, 234, 170, 45, 13, 29, 157, 201, 249, 233, 169, 46, 14, - 86, 70, 138, 218, 122, 58, 101, 181, 85, 69, 137, 217, 121, 57, 102, 182, - 230, 166, 42, 10, 26, 154, 197, 245, 229, 165, 41, 9, 25, 153, 198, 246, - 118, 54, 98, 178, 82, 66, 133, 213, 117, 53, 97, 177, 81, 65, 134, 214, - 22, 150, 194, 242, 226, 162, 37, 5, 21, 149, 193, 241, 225, 161, 38, 6, - 92, 76, 130, 210, 114, 50, 111, 191, 95, 79, 129, 209, 113, 49, 108, 188, - 236, 172, 34, 2, 18, 146, 207, 255, 239, 175, 33, 1, 17, 145, 204, 252, - 124, 60, 104, 184, 88, 72, 143, 223, 127, 63, 107, 187, 91, 75, 140, 220, - 28, 156, 200, 248, 232, 168, 47, 15, 31, 159, 203, 251, 235, 171, 44, 12, - 84, 68, 136, 216, 120, 56, 103, 183, 87, 71, 139, 219, 123, 59, 100, 180 -}; - -private const byte noise_dither_data[128 * 128] = { - 112, 122, 183, 239, 27, 78, 115, 52, 204, 212, 6, 114, 72, 134, 205, 61, - 1, 38, 91, 107, 30, 206, 115, 168, 184, 7, 148, 32, 16, 195, 103, 191, - 15, 121, 109, 64, 246, 184, 48, 208, 245, 220, 34, 187, 216, 30, 35, 148, - 30, 167, 189, 158, 38, 9, 209, 51, 114, 133, 82, 29, 137, 240, 245, 73, - 196, 27, 97, 54, 28, 9, 62, 201, 80, 202, 253, 183, 50, 6, 47, 92, - 152, 73, 47, 81, 91, 10, 46, 191, 55, 119, 199, 188, 39, 178, 122, 212, - 230, 16, 151, 203, 178, 96, 176, 62, 172, 50, 102, 148, 190, 117, 85, 105, - 183, 85, 107, 222, 88, 181, 171, 47, 82, 106, 58, 240, 46, 142, 195, 214, - 1, 223, 24, 174, 203, 89, 151, 99, 154, 184, 138, 80, 238, 31, 186, 148, - 51, 132, 166, 183, 216, 63, 231, 10, 214, 105, 82, 120, 74, 27, 62, 146, - 194, 182, 129, 171, 49, 119, 160, 122, 90, 27, 101, 128, 105, 243, 115, 9, - 1, 59, 210, 129, 190, 99, 207, 140, 53, 68, 159, 33, 195, 118, 148, 94, - 244, 75, 40, 187, 94, 41, 71, 163, 37, 25, 112, 129, 115, 72, 148, 190, - 177, 124, 32, 34, 101, 52, 137, 249, 150, 164, 135, 233, 140, 145, 93, 246, - 43, 215, 98, 242, 144, 2, 124, 252, 18, 71, 126, 207, 64, 195, 161, 48, - 160, 114, 201, 115, 182, 129, 6, 118, 48, 126, 206, 184, 55, 16, 210, 108, - 57, 70, 201, 45, 169, 10, 240, 46, 166, 98, 92, 251, 13, 127, 175, 245, - 118, 158, 239, 18, 155, 254, 106, 72, 237, 70, 204, 48, 24, 245, 145, 236, - 212, 244, 44, 22, 86, 3, 76, 110, 10, 170, 133, 52, 179, 84, 174, 237, - 85, 98, 74, 35, 17, 115, 145, 246, 215, 72, 229, 181, 63, 171, 2, 32, - 96, 122, 13, 149, 234, 254, 221, 191, 85, 217, 174, 56, 168, 247, 225, 107, - 209, 204, 108, 243, 120, 173, 218, 74, 43, 64, 28, 90, 59, 77, 165, 200, - 53, 28, 107, 186, 240, 37, 202, 30, 95, 246, 224, 6, 20, 237, 154, 217, - 166, 18, 75, 11, 230, 80, 156, 62, 20, 72, 239, 2, 22, 169, 95, 148, - 254, 94, 147, 139, 249, 198, 161, 124, 226, 47, 59, 28, 210, 106, 95, 44, - 243, 203, 73, 209, 35, 143, 96, 164, 141, 162, 57, 255, 223, 84, 123, 130, - 240, 73, 147, 95, 234, 165, 209, 21, 196, 138, 79, 222, 204, 135, 53, 69, - 113, 202, 231, 244, 163, 70, 212, 87, 168, 203, 243, 14, 106, 172, 37, 217, - 131, 209, 176, 239, 105, 136, 120, 154, 227, 125, 147, 7, 144, 220, 206, 19, - 162, 240, 133, 6, 155, 22, 207, 236, 223, 104, 2, 210, 227, 26, 11, 98, - 89, 173, 132, 66, 201, 79, 104, 150, 38, 221, 134, 184, 4, 73, 254, 133, - 237, 34, 253, 50, 112, 219, 241, 23, 211, 172, 143, 146, 74, 177, 252, 119, - 214, 54, 176, 97, 242, 213, 32, 178, 107, 55, 69, 219, 102, 194, 221, 140, - 139, 61, 39, 192, 205, 86, 1, 170, 169, 129, 227, 4, 14, 201, 110, 113, - 78, 232, 143, 217, 16, 231, 221, 152, 201, 151, 94, 57, 181, 12, 172, 63, - 188, 149, 116, 16, 48, 160, 6, 78, 218, 255, 54, 193, 228, 192, 100, 156, - 236, 167, 53, 134, 23, 177, 1, 235, 135, 109, 68, 10, 22, 173, 180, 1, - 58, 44, 237, 89, 68, 193, 149, 35, 95, 203, 7, 156, 139, 187, 197, 33, - 159, 110, 243, 93, 32, 235, 84, 244, 122, 45, 27, 57, 12, 116, 228, 223, - 87, 7, 223, 111, 212, 247, 155, 120, 109, 174, 32, 41, 208, 36, 77, 232, - 33, 182, 128, 206, 14, 135, 86, 157, 189, 229, 88, 228, 77, 120, 81, 7, - 233, 2, 121, 252, 69, 212, 182, 22, 36, 235, 153, 47, 232, 135, 41, 165, - 167, 104, 157, 242, 175, 136, 29, 42, 26, 163, 180, 239, 100, 223, 156, 200, - 138, 223, 235, 75, 230, 84, 251, 62, 23, 127, 96, 155, 1, 76, 19, 226, - 74, 3, 91, 155, 78, 132, 116, 204, 219, 207, 81, 251, 121, 143, 212, 237, - 224, 27, 186, 141, 94, 5, 115, 189, 16, 181, 245, 117, 170, 222, 234, 49, - 231, 192, 125, 166, 182, 127, 80, 51, 77, 14, 156, 83, 141, 189, 101, 21, - 19, 116, 53, 249, 84, 9, 5, 204, 215, 136, 228, 13, 251, 3, 164, 28, - 131, 67, 146, 1, 105, 68, 177, 43, 170, 25, 197, 15, 21, 233, 173, 152, - 152, 29, 80, 218, 251, 228, 160, 59, 71, 12, 179, 88, 157, 92, 75, 23, - 38, 82, 50, 198, 107, 203, 77, 254, 214, 68, 98, 250, 85, 25, 40, 124, - 254, 60, 206, 111, 200, 125, 134, 185, 164, 104, 191, 3, 126, 166, 83, 220, - 29, 197, 250, 103, 243, 158, 152, 218, 228, 153, 170, 42, 248, 198, 150, 104, - 169, 9, 146, 99, 53, 231, 172, 19, 238, 61, 110, 114, 253, 113, 88, 158, - 65, 200, 24, 1, 44, 219, 129, 205, 138, 220, 162, 233, 68, 171, 61, 131, - 150, 70, 193, 192, 38, 141, 73, 190, 203, 43, 130, 65, 137, 66, 64, 103, - 225, 30, 247, 84, 62, 116, 156, 236, 121, 153, 137, 38, 255, 64, 179, 39, - 174, 78, 181, 111, 122, 97, 137, 46, 194, 224, 101, 117, 242, 220, 53, 177, - 2, 178, 31, 120, 192, 116, 91, 51, 126, 36, 7, 142, 227, 255, 70, 134, - 21, 95, 40, 165, 211, 24, 175, 102, 80, 227, 22, 141, 143, 64, 197, 34, - 44, 192, 216, 123, 101, 87, 35, 60, 51, 118, 24, 164, 30, 43, 63, 70, - 121, 254, 69, 206, 242, 106, 134, 213, 71, 167, 216, 37, 1, 107, 24, 75, - 33, 222, 136, 59, 7, 169, 106, 158, 248, 198, 100, 187, 199, 36, 236, 88, - 227, 170, 133, 45, 229, 167, 110, 61, 123, 90, 248, 163, 213, 121, 153, 188, - 42, 93, 136, 16, 191, 56, 19, 199, 150, 227, 208, 216, 195, 224, 132, 215, - 200, 151, 247, 94, 79, 50, 125, 198, 207, 58, 68, 250, 193, 49, 33, 171, - 149, 252, 111, 59, 39, 229, 19, 249, 45, 43, 211, 56, 202, 72, 125, 191, - 183, 105, 233, 150, 219, 186, 45, 15, 39, 224, 139, 4, 43, 28, 208, 131, - 179, 83, 17, 90, 31, 117, 141, 69, 64, 159, 110, 240, 194, 142, 252, 185, - 252, 130, 226, 54, 219, 80, 163, 230, 248, 48, 109, 166, 12, 85, 143, 148, - 26, 174, 35, 188, 157, 113, 46, 81, 145, 177, 5, 142, 209, 149, 39, 193, - 149, 125, 33, 99, 187, 76, 89, 217, 51, 194, 168, 35, 1, 205, 176, 178, - 187, 58, 158, 22, 12, 103, 172, 82, 65, 8, 130, 40, 129, 100, 168, 41, - 140, 175, 222, 230, 241, 136, 238, 126, 109, 150, 144, 172, 114, 67, 138, 249, - 218, 207, 140, 14, 164, 118, 193, 215, 251, 137, 117, 226, 13, 205, 233, 60, - 20, 47, 196, 69, 90, 194, 239, 79, 198, 25, 93, 238, 56, 182, 50, 157, - 226, 151, 203, 67, 59, 100, 182, 2, 66, 139, 166, 205, 36, 12, 102, 79, - 65, 23, 202, 128, 63, 208, 144, 180, 62, 201, 125, 87, 184, 228, 205, 168, - 120, 86, 1, 56, 10, 214, 245, 114, 123, 103, 92, 76, 140, 232, 108, 180, - 54, 94, 135, 173, 234, 152, 101, 122, 134, 81, 24, 104, 238, 250, 147, 144, - 83, 193, 74, 165, 141, 71, 248, 209, 167, 126, 37, 246, 87, 192, 253, 125, - 15, 66, 108, 187, 8, 176, 180, 87, 185, 9, 226, 43, 89, 147, 98, 188, - 150, 17, 123, 93, 102, 6, 58, 190, 186, 87, 145, 108, 20, 33, 83, 146, - 173, 204, 57, 249, 5, 153, 241, 174, 154, 184, 77, 97, 81, 250, 169, 7, - 39, 133, 113, 255, 178, 214, 86, 162, 188, 26, 14, 242, 233, 161, 145, 4, - 220, 131, 76, 42, 36, 160, 29, 86, 175, 132, 214, 154, 79, 126, 100, 20, - 210, 238, 60, 99, 229, 208, 74, 40, 163, 34, 225, 23, 67, 8, 170, 54, - 67, 179, 244, 1, 30, 158, 42, 52, 233, 246, 117, 8, 56, 96, 92, 17, - 222, 118, 232, 252, 48, 159, 231, 109, 51, 111, 188, 9, 11, 26, 75, 50, - 116, 44, 21, 60, 37, 100, 215, 17, 213, 20, 81, 124, 211, 234, 6, 26, - 230, 183, 18, 66, 80, 131, 88, 153, 195, 169, 4, 32, 97, 139, 166, 248, - 91, 117, 142, 8, 103, 123, 132, 58, 170, 248, 55, 107, 120, 237, 216, 112, - 58, 172, 222, 11, 241, 48, 238, 146, 95, 127, 34, 199, 114, 55, 93, 210, - 179, 82, 147, 13, 118, 1, 250, 112, 66, 3, 31, 225, 247, 50, 21, 211, - 197, 139, 249, 160, 91, 164, 181, 19, 241, 147, 211, 52, 69, 253, 118, 13, - 200, 224, 29, 231, 199, 12, 131, 243, 154, 79, 191, 209, 68, 44, 97, 196, - 211, 20, 190, 113, 234, 35, 202, 155, 144, 250, 63, 217, 96, 123, 104, 18, - 202, 19, 56, 244, 42, 149, 189, 13, 128, 90, 40, 199, 65, 208, 159, 85, - 106, 155, 161, 23, 185, 176, 158, 81, 92, 112, 235, 144, 132, 188, 75, 89, - 26, 108, 12, 214, 13, 110, 27, 71, 124, 213, 61, 86, 89, 41, 232, 152, - 8, 119, 57, 45, 108, 77, 137, 46, 195, 230, 98, 213, 65, 16, 232, 128, - 185, 56, 40, 229, 136, 60, 190, 153, 123, 161, 159, 215, 116, 129, 30, 96, - 47, 58, 25, 155, 135, 75, 153, 49, 179, 137, 22, 72, 82, 11, 255, 41, - 26, 4, 226, 102, 165, 124, 221, 39, 189, 254, 140, 105, 100, 37, 138, 161, - 5, 34, 237, 163, 143, 119, 164, 220, 2, 101, 36, 180, 145, 142, 79, 230, - 34, 76, 197, 5, 83, 64, 229, 161, 167, 95, 133, 55, 3, 142, 221, 173, - 247, 141, 1, 228, 41, 71, 65, 11, 197, 55, 241, 189, 238, 37, 99, 8, - 88, 146, 205, 234, 221, 151, 161, 199, 177, 11, 121, 179, 242, 130, 201, 147, - 246, 200, 175, 156, 215, 189, 89, 208, 61, 157, 33, 106, 165, 20, 193, 186, - 251, 127, 183, 72, 15, 103, 241, 105, 41, 195, 192, 8, 232, 102, 198, 151, - 239, 204, 216, 165, 183, 97, 251, 226, 111, 196, 175, 234, 167, 185, 213, 227, - 71, 159, 132, 186, 98, 63, 197, 180, 162, 93, 151, 127, 185, 157, 91, 235, - 110, 90, 49, 133, 108, 4, 29, 85, 73, 235, 23, 196, 181, 60, 244, 218, - 156, 112, 163, 127, 102, 77, 248, 31, 154, 219, 246, 240, 253, 45, 178, 225, - 96, 47, 213, 61, 62, 130, 1, 224, 168, 24, 46, 127, 159, 28, 199, 54, - 135, 46, 119, 253, 92, 247, 225, 144, 236, 44, 252, 136, 31, 65, 10, 180, - 184, 82, 124, 224, 138, 211, 126, 171, 169, 130, 229, 181, 140, 52, 223, 160, - 221, 174, 25, 157, 18, 84, 45, 194, 83, 111, 78, 239, 14, 38, 255, 217, - 128, 3, 90, 191, 168, 42, 218, 206, 247, 63, 212, 115, 194, 146, 70, 112, - 216, 21, 113, 255, 145, 25, 78, 83, 202, 57, 15, 225, 128, 242, 220, 14, - 76, 207, 149, 243, 185, 53, 241, 66, 91, 117, 162, 160, 171, 17, 3, 200, - 210, 93, 190, 131, 217, 196, 134, 119, 11, 25, 186, 54, 104, 28, 99, 52, - 74, 103, 177, 162, 225, 236, 206, 114, 154, 5, 67, 210, 253, 219, 113, 173, - 176, 42, 67, 187, 52, 36, 178, 122, 162, 66, 109, 18, 101, 128, 222, 49, - 99, 231, 18, 73, 5, 245, 21, 49, 15, 76, 88, 32, 38, 249, 84, 111, - 97, 138, 92, 4, 235, 176, 67, 196, 142, 17, 244, 51, 57, 70, 182, 171, - 130, 250, 78, 109, 94, 119, 29, 15, 9, 152, 87, 17, 143, 31, 121, 55, - 49, 198, 86, 175, 139, 245, 236, 10, 218, 59, 40, 31, 60, 207, 27, 69, - 8, 91, 169, 180, 237, 88, 156, 197, 170, 95, 70, 33, 45, 209, 155, 125, - 102, 175, 32, 206, 187, 83, 223, 1, 137, 250, 79, 132, 173, 197, 159, 231, - 4, 205, 84, 71, 231, 93, 203, 157, 130, 202, 251, 165, 222, 139, 85, 39, - 207, 181, 78, 245, 161, 217, 156, 251, 36, 81, 149, 200, 130, 249, 9, 69, - 126, 62, 171, 178, 61, 250, 141, 156, 79, 82, 184, 157, 144, 72, 41, 148, - 232, 20, 79, 220, 75, 255, 137, 15, 236, 139, 199, 243, 104, 159, 168, 229, - 123, 154, 57, 242, 138, 248, 45, 236, 246, 160, 8, 218, 113, 225, 135, 112, - 119, 170, 221, 58, 195, 153, 192, 237, 245, 136, 99, 86, 82, 63, 210, 32, - 101, 127, 232, 251, 10, 247, 100, 79, 121, 227, 136, 158, 201, 17, 87, 254, - 72, 14, 243, 150, 237, 103, 198, 106, 186, 191, 89, 229, 64, 177, 26, 81, - 228, 34, 50, 170, 224, 59, 15, 67, 17, 110, 151, 87, 164, 119, 41, 148, - 115, 97, 60, 5, 136, 112, 190, 13, 234, 139, 183, 246, 187, 22, 94, 55, - 4, 212, 253, 136, 185, 101, 215, 65, 175, 139, 47, 90, 174, 114, 107, 225, - 56, 242, 119, 90, 36, 192, 148, 47, 179, 23, 149, 35, 202, 76, 212, 248, - 118, 211, 232, 26, 189, 223, 153, 73, 103, 81, 237, 167, 7, 197, 49, 165, - 231, 77, 156, 90, 166, 18, 219, 116, 27, 36, 142, 209, 145, 252, 69, 13, - 205, 147, 223, 32, 63, 157, 167, 113, 22, 249, 58, 219, 11, 173, 104, 236, - 144, 48, 214, 227, 242, 158, 21, 142, 163, 108, 13, 118, 128, 35, 201, 6, - 126, 141, 98, 210, 105, 254, 169, 123, 187, 65, 43, 223, 3, 49, 190, 20, - 165, 129, 228, 15, 30, 38, 88, 53, 163, 56, 21, 109, 227, 158, 121, 170, - 237, 109, 93, 43, 120, 166, 32, 7, 201, 29, 115, 49, 20, 55, 13, 214, - 133, 1, 145, 204, 171, 87, 223, 18, 107, 200, 114, 53, 123, 59, 135, 24, - 202, 108, 179, 171, 114, 162, 100, 14, 20, 207, 143, 182, 224, 80, 147, 184, - 34, 187, 11, 193, 255, 52, 76, 102, 78, 151, 2, 114, 130, 238, 128, 39, - 54, 46, 75, 142, 139, 42, 211, 28, 1, 108, 181, 199, 47, 131, 186, 71, - 55, 94, 124, 190, 38, 164, 54, 68, 212, 59, 30, 47, 78, 101, 130, 246, - 146, 132, 253, 22, 138, 21, 37, 186, 103, 56, 12, 234, 204, 255, 238, 107, - 206, 113, 39, 68, 239, 73, 194, 119, 80, 122, 8, 214, 223, 43, 82, 197, - 30, 131, 66, 198, 94, 206, 48, 239, 6, 248, 221, 227, 189, 197, 241, 54, - 173, 102, 178, 42, 100, 194, 127, 230, 66, 10, 170, 89, 7, 85, 45, 189, - 34, 66, 1, 70, 203, 90, 61, 1, 38, 124, 47, 74, 25, 87, 48, 245, - 100, 246, 134, 21, 94, 38, 5, 131, 203, 230, 49, 181, 178, 111, 173, 207, - 250, 50, 15, 200, 141, 235, 102, 165, 74, 143, 198, 106, 129, 97, 221, 13, - 234, 138, 58, 33, 119, 160, 219, 42, 82, 218, 230, 181, 91, 20, 97, 170, - 28, 160, 44, 246, 177, 36, 158, 116, 243, 181, 155, 161, 218, 201, 127, 145, - 198, 255, 216, 173, 154, 204, 92, 243, 93, 48, 49, 180, 114, 224, 193, 240, - 80, 18, 199, 240, 21, 142, 76, 87, 78, 89, 27, 226, 42, 238, 172, 128, - 130, 195, 33, 150, 77, 52, 210, 131, 95, 201, 147, 177, 193, 142, 88, 49, - 29, 156, 133, 51, 209, 210, 77, 227, 69, 126, 41, 163, 50, 84, 128, 169, - 122, 208, 92, 217, 53, 1, 20, 188, 115, 154, 239, 242, 226, 223, 31, 68, - 68, 174, 82, 98, 203, 246, 185, 1, 118, 52, 183, 94, 128, 207, 76, 233, - 153, 86, 109, 241, 254, 80, 17, 188, 16, 145, 90, 162, 253, 43, 213, 189, - 162, 72, 191, 193, 239, 136, 112, 214, 82, 66, 226, 142, 40, 23, 252, 8, - 50, 6, 87, 218, 172, 71, 135, 238, 166, 141, 29, 247, 101, 11, 70, 177, - 143, 40, 155, 192, 200, 63, 176, 152, 64, 246, 162, 117, 179, 96, 251, 105, - 166, 28, 99, 213, 185, 197, 6, 82, 111, 239, 25, 169, 109, 157, 69, 183, - 79, 95, 174, 98, 22, 42, 173, 104, 9, 214, 31, 230, 188, 249, 16, 131, - 161, 66, 55, 249, 196, 157, 233, 65, 33, 103, 1, 214, 4, 109, 42, 159, - 134, 234, 220, 149, 212, 64, 83, 40, 6, 44, 172, 230, 56, 162, 80, 248, - 23, 208, 1, 117, 205, 56, 96, 236, 62, 73, 127, 245, 195, 235, 51, 15, - 86, 113, 209, 111, 74, 172, 54, 92, 109, 7, 19, 194, 144, 173, 73, 60, - 66, 116, 132, 104, 52, 7, 17, 117, 145, 79, 233, 12, 96, 140, 155, 24, - 254, 119, 165, 220, 243, 10, 183, 234, 207, 11, 39, 110, 5, 132, 147, 205, - 51, 65, 240, 254, 160, 41, 115, 216, 68, 12, 128, 37, 175, 21, 215, 235, - 215, 190, 116, 235, 94, 64, 152, 194, 92, 52, 146, 82, 99, 17, 136, 40, - 28, 16, 171, 160, 98, 35, 164, 117, 93, 200, 59, 189, 124, 132, 190, 81, - 190, 20, 29, 114, 146, 73, 27, 124, 214, 23, 229, 159, 48, 189, 137, 19, - 178, 77, 211, 168, 133, 172, 3, 98, 131, 36, 18, 203, 113, 65, 143, 146, - 184, 13, 133, 64, 16, 247, 27, 207, 47, 124, 62, 211, 83, 99, 182, 237, - 148, 25, 42, 184, 18, 211, 108, 185, 103, 100, 213, 179, 254, 40, 176, 57, - 108, 1, 81, 44, 222, 35, 125, 98, 223, 191, 138, 154, 22, 73, 218, 51, - 96, 3, 121, 188, 161, 26, 101, 247, 246, 132, 54, 217, 39, 122, 1, 245, - 10, 27, 252, 183, 130, 120, 3, 180, 129, 244, 204, 186, 228, 196, 58, 220, - 137, 110, 232, 44, 216, 140, 80, 247, 113, 37, 175, 15, 206, 174, 251, 62, - 57, 107, 241, 151, 67, 9, 96, 253, 18, 164, 217, 179, 216, 116, 213, 55, - 12, 248, 232, 70, 179, 114, 207, 240, 154, 60, 107, 161, 104, 217, 40, 4, - 143, 46, 80, 58, 131, 212, 117, 76, 96, 120, 30, 196, 149, 106, 77, 53, - 35, 188, 196, 175, 133, 106, 41, 65, 150, 1, 98, 47, 126, 230, 157, 201, - 97, 167, 204, 149, 86, 14, 124, 228, 247, 181, 224, 36, 137, 230, 91, 74, - 55, 73, 5, 140, 205, 125, 61, 30, 93, 153, 32, 234, 117, 206, 9, 19, - 178, 12, 60, 119, 97, 121, 161, 144, 11, 62, 19, 229, 72, 213, 247, 134, - 197, 57, 108, 228, 70, 12, 125, 201, 85, 202, 41, 213, 48, 138, 184, 205, - 240, 122, 78, 171, 41, 191, 239, 12, 110, 119, 84, 35, 206, 177, 140, 152, - 183, 100, 165, 215, 85, 29, 8, 148, 180, 238, 224, 134, 247, 204, 228, 92, - 90, 225, 118, 180, 250, 25, 51, 179, 178, 101, 244, 154, 232, 220, 91, 185, - 134, 31, 152, 248, 124, 208, 23, 241, 203, 72, 27, 89, 192, 26, 33, 212, - 202, 25, 121, 235, 196, 133, 168, 17, 50, 233, 28, 92, 182, 169, 252, 15, - 152, 58, 219, 120, 113, 86, 8, 72, 207, 224, 105, 136, 176, 83, 227, 14, - 166, 158, 231, 254, 177, 88, 195, 37, 105, 168, 191, 125, 33, 115, 23, 155, - 248, 176, 73, 26, 167, 243, 152, 88, 168, 141, 74, 7, 118, 61, 250, 212, - 133, 38, 26, 16, 176, 51, 204, 150, 154, 255, 120, 61, 25, 166, 243, 65, - 88, 37, 115, 24, 209, 123, 49, 166, 126, 255, 44, 9, 28, 76, 156, 50, - 229, 195, 219, 1, 14, 208, 236, 89, 134, 38, 70, 1, 200, 24, 6, 114, - 86, 54, 110, 74, 178, 209, 235, 160, 59, 210, 225, 226, 10, 111, 162, 84, - 229, 130, 70, 177, 103, 75, 188, 46, 104, 159, 99, 164, 100, 12, 53, 122, - 226, 196, 167, 92, 48, 155, 112, 172, 78, 63, 40, 4, 98, 221, 74, 144, - 24, 39, 212, 96, 145, 59, 217, 251, 255, 36, 85, 76, 13, 91, 193, 172, - 129, 30, 123, 95, 17, 185, 54, 107, 235, 104, 180, 51, 14, 169, 149, 91, - 202, 182, 92, 210, 130, 193, 123, 85, 49, 2, 208, 226, 112, 14, 86, 43, - 157, 202, 129, 52, 249, 53, 99, 46, 200, 87, 31, 74, 169, 167, 120, 141, - 100, 176, 150, 11, 29, 163, 88, 156, 221, 52, 168, 230, 174, 115, 45, 248, - 1, 128, 232, 215, 62, 169, 16, 85, 174, 189, 143, 120, 77, 63, 242, 142, - 38, 2, 56, 85, 209, 151, 52, 244, 77, 193, 113, 9, 219, 194, 160, 34, - 22, 34, 250, 164, 233, 225, 222, 190, 182, 251, 163, 118, 146, 64, 244, 181, - 137, 67, 107, 208, 239, 75, 18, 4, 205, 200, 139, 159, 56, 102, 234, 148, - 198, 9, 147, 182, 234, 143, 224, 43, 254, 24, 121, 155, 211, 106, 72, 19, - 81, 7, 194, 138, 184, 196, 62, 109, 228, 99, 161, 89, 72, 178, 4, 93, - 95, 174, 22, 226, 125, 71, 182, 93, 7, 184, 105, 152, 121, 27, 233, 220, - 33, 183, 26, 240, 63, 121, 81, 102, 61, 97, 166, 199, 233, 167, 159, 57, - 19, 195, 244, 105, 20, 253, 137, 58, 102, 51, 229, 76, 236, 131, 32, 202, - 145, 67, 24, 211, 217, 231, 134, 59, 106, 146, 127, 60, 31, 71, 216, 150, - 124, 162, 110, 27, 94, 187, 71, 16, 228, 50, 151, 165, 143, 11, 17, 180, - 122, 201, 192, 28, 164, 142, 181, 219, 109, 21, 93, 5, 43, 68, 176, 199, - 127, 22, 89, 150, 199, 84, 101, 215, 3, 133, 148, 96, 162, 83, 120, 45, - 77, 21, 105, 60, 34, 168, 252, 5, 153, 69, 36, 224, 160, 132, 24, 244, - 57, 151, 75, 225, 135, 155, 239, 34, 171, 67, 10, 116, 66, 39, 61, 251, - 94, 147, 55, 69, 171, 32, 215, 242, 140, 249, 48, 79, 217, 68, 189, 245, - 95, 147, 221, 37, 205, 125, 219, 46, 28, 83, 220, 146, 182, 90, 61, 3, - 95, 195, 123, 255, 187, 88, 118, 23, 163, 186, 140, 213, 8, 58, 153, 83, - 81, 57, 154, 186, 231, 249, 46, 126, 134, 29, 116, 44, 67, 141, 43, 97, - 2, 106, 240, 89, 117, 243, 83, 65, 187, 198, 150, 111, 238, 86, 30, 141, - 220, 244, 79, 64, 60, 225, 67, 6, 29, 97, 179, 194, 50, 253, 204, 105, - 242, 117, 148, 163, 31, 222, 126, 238, 3, 245, 30, 195, 37, 218, 188, 53, - 45, 185, 111, 122, 199, 252, 63, 176, 221, 19, 222, 84, 194, 140, 192, 69, - 10, 241, 135, 206, 137, 78, 227, 42, 125, 188, 216, 31, 108, 35, 129, 128, - 151, 191, 127, 45, 231, 14, 64, 168, 144, 167, 252, 44, 67, 171, 153, 123, - 135, 210, 1, 173, 3, 111, 242, 170, 26, 68, 203, 84, 245, 208, 116, 129, - 209, 38, 191, 129, 31, 218, 62, 156, 108, 80, 184, 203, 60, 106, 174, 214, - 54, 241, 175, 132, 110, 206, 53, 226, 170, 140, 216, 233, 250, 221, 101, 127, - 10, 40, 87, 135, 241, 47, 139, 25, 172, 75, 218, 229, 146, 8, 23, 222, - 215, 39, 225, 192, 66, 145, 144, 90, 103, 187, 59, 135, 175, 115, 231, 111, - 5, 193, 139, 216, 11, 110, 25, 210, 41, 244, 136, 196, 147, 112, 2, 149, - 122, 175, 213, 104, 197, 192, 153, 9, 235, 5, 152, 75, 198, 2, 95, 18, - 4, 237, 75, 138, 159, 91, 107, 164, 186, 118, 2, 199, 222, 99, 34, 250, - 57, 190, 19, 102, 158, 37, 69, 180, 16, 249, 33, 236, 232, 161, 45, 112, - 13, 252, 237, 70, 208, 103, 138, 158, 211, 2, 241, 84, 91, 198, 253, 238, - 71, 222, 149, 35, 32, 6, 151, 46, 44, 78, 253, 55, 15, 157, 63, 185, - 165, 186, 183, 227, 126, 163, 177, 158, 240, 112, 46, 56, 236, 191, 144, 71, - 218, 246, 113, 150, 245, 97, 33, 117, 252, 36, 9, 210, 5, 14, 83, 139, - 248, 187, 83, 25, 196, 115, 156, 49, 21, 4, 41, 147, 191, 52, 210, 146, - 112, 30, 166, 200, 40, 49, 70, 141, 104, 215, 144, 228, 110, 92, 43, 168, - 195, 237, 54, 104, 66, 53, 236, 193, 228, 241, 57, 48, 234, 99, 215, 242, - 113, 240, 51, 190, 45, 11, 237, 206, 212, 62, 228, 150, 245, 47, 103, 200, - 72, 113, 226, 222, 1, 156, 27, 118, 177, 88, 49, 116, 175, 240, 150, 109, - 157, 52, 139, 181, 252, 6, 151, 135, 164, 94, 193, 232, 192, 116, 85, 202, - 133, 192, 117, 99, 151, 248, 123, 162, 107, 167, 223, 155, 9, 69, 39, 210, - 171, 27, 230, 108, 228, 195, 15, 20, 208, 209, 128, 102, 169, 202, 43, 254, - 63, 205, 45, 2, 240, 33, 105, 17, 110, 93, 250, 134, 38, 230, 22, 78, - 38, 88, 253, 224, 185, 8, 81, 219, 76, 186, 173, 32, 114, 62, 153, 227, - 246, 42, 68, 211, 40, 203, 254, 144, 108, 149, 115, 196, 177, 50, 125, 201, - 32, 112, 204, 172, 182, 84, 152, 66, 72, 196, 149, 246, 186, 14, 122, 138, - 253, 165, 138, 202, 111, 59, 179, 234, 18, 137, 237, 160, 139, 254, 192, 117, - 72, 235, 227, 121, 60, 169, 19, 166, 11, 97, 54, 152, 16, 239, 160, 209, - 160, 25, 221, 255, 45, 75, 83, 56, 181, 203, 6, 101, 23, 136, 112, 50, - 11, 45, 141, 76, 148, 185, 53, 133, 25, 159, 78, 187, 220, 103, 178, 52, - 149, 172, 144, 216, 167, 243, 218, 132, 61, 174, 219, 204, 202, 127, 244, 135, - 14, 240, 137, 67, 115, 174, 255, 28, 134, 183, 52, 84, 199, 252, 27, 78, - 26, 179, 145, 96, 81, 151, 183, 118, 138, 187, 84, 56, 90, 23, 34, 173, - 93, 70, 159, 248, 133, 29, 59, 170, 102, 124, 75, 31, 58, 148, 68, 225, - 33, 52, 24, 2, 77, 135, 45, 252, 112, 169, 14, 208, 56, 20, 93, 70, - 201, 4, 10, 172, 112, 115, 88, 36, 178, 26, 141, 99, 176, 76, 22, 110, - 164, 228, 73, 195, 197, 240, 217, 4, 27, 53, 85, 242, 120, 163, 87, 152, - 181, 81, 49, 203, 60, 223, 161, 93, 95, 162, 56, 134, 123, 229, 70, 156, - 72, 117, 107, 179, 183, 91, 70, 8, 192, 67, 225, 113, 106, 166, 1, 87, - 116, 177, 158, 33, 196, 231, 156, 69, 124, 39, 4, 235, 16, 189, 210, 143, - 131, 124, 174, 11, 163, 112, 8, 28, 168, 221, 2, 18, 7, 156, 140, 78, - 142, 34, 3, 219, 100, 236, 120, 218, 117, 176, 4, 40, 94, 210, 169, 28, - 106, 188, 92, 110, 215, 204, 75, 166, 61, 22, 224, 251, 206, 214, 10, 36, - 84, 103, 212, 44, 196, 67, 211, 226, 66, 34, 215, 247, 254, 119, 63, 18, - 89, 46, 52, 12, 109, 134, 19, 166, 198, 142, 47, 72, 188, 205, 234, 245, - 41, 84, 219, 145, 16, 19, 96, 152, 217, 7, 164, 147, 39, 226, 37, 112, - 19, 162, 9, 160, 129, 203, 186, 168, 99, 48, 118, 60, 143, 54, 84, 40, - 249, 184, 95, 60, 101, 142, 35, 205, 37, 17, 94, 179, 182, 20, 3, 154, - 89, 44, 51, 128, 247, 166, 159, 43, 109, 154, 226, 63, 3, 32, 148, 171, - 195, 252, 52, 98, 131, 41, 184, 220, 173, 50, 146, 187, 42, 6, 53, 20, - 134, 83, 28, 128, 124, 162, 143, 79, 209, 216, 167, 42, 178, 73, 8, 43, - 174, 80, 9, 236, 129, 91, 251, 98, 150, 195, 5, 48, 243, 130, 224, 8, - 8, 20, 124, 121, 54, 94, 178, 111, 40, 200, 10, 140, 218, 7, 18, 60, - 61, 180, 165, 79, 239, 72, 177, 138, 132, 18, 126, 100, 80, 200, 174, 244, - 44, 161, 208, 125, 253, 232, 50, 65, 242, 199, 58, 236, 151, 119, 108, 215, - 25, 45, 209, 160, 128, 147, 1, 29, 123, 208, 155, 99, 86, 107, 204, 139, - 143, 182, 248, 101, 238, 97, 76, 200, 197, 67, 119, 92, 198, 122, 47, 250, - 154, 119, 18, 140, 254, 26, 92, 157, 222, 235, 69, 101, 251, 160, 161, 132, - 105, 63, 154, 232, 31, 203, 38, 238, 47, 153, 186, 32, 140, 185, 152, 19, - 33, 46, 220, 114, 2, 65, 126, 180, 140, 189, 90, 53, 51, 71, 78, 198, - 183, 185, 215, 36, 15, 193, 122, 43, 82, 64, 115, 3, 168, 230, 157, 236, - 255, 17, 237, 98, 120, 46, 63, 249, 201, 241, 42, 89, 30, 1, 149, 191, - 112, 209, 95, 137, 214, 154, 98, 37, 221, 159, 24, 139, 234, 249, 69, 207, - 193, 165, 108, 132, 192, 167, 221, 93, 140, 61, 66, 1, 225, 73, 163, 223, - 69, 239, 6, 191, 110, 91, 5, 49, 142, 217, 41, 252, 58, 188, 129, 214, - 89, 33, 165, 227, 16, 121, 174, 64, 48, 137, 194, 115, 114, 233, 85, 217, - 196, 16, 161, 44, 91, 163, 230, 1, 200, 13, 243, 131, 119, 245, 219, 228, - 107, 199, 244, 143, 64, 221, 28, 41, 122, 101, 255, 30, 42, 133, 89, 182, - 232, 147, 249, 66, 250, 24, 225, 148, 159, 247, 212, 165, 90, 204, 141, 97, - 142, 194, 10, 106, 170, 166, 216, 109, 75, 231, 192, 50, 135, 118, 86, 215, - 231, 251, 53, 73, 75, 28, 128, 10, 184, 94, 11, 170, 5, 163, 18, 177, - 222, 15, 65, 120, 247, 53, 239, 75, 243, 232, 216, 171, 246, 63, 41, 117, - 172, 19, 150, 222, 161, 212, 16, 116, 31, 178, 169, 9, 220, 77, 94, 100, - 15, 181, 74, 221, 205, 65, 231, 99, 17, 1, 88, 244, 191, 178, 105, 54, - 247, 217, 181, 68, 220, 55, 103, 149, 78, 120, 85, 82, 54, 104, 95, 147, - 148, 29, 82, 186, 155, 168, 197, 231, 170, 217, 228, 70, 156, 25, 225, 118, - 61, 86, 173, 65, 144, 67, 169, 219, 239, 104, 55, 186, 37, 127, 182, 68, - 22, 122, 38, 94, 205, 57, 243, 26, 235, 12, 110, 82, 225, 251, 40, 130, - 254, 181, 59, 109, 223, 126, 81, 136, 239, 120, 104, 3, 20, 103, 62, 15, - 87, 55, 56, 148, 229, 90, 46, 10, 13, 105, 149, 130, 72, 97, 5, 50, - 98, 86, 123, 243, 233, 121, 186, 45, 120, 93, 225, 4, 62, 206, 244, 20, - 207, 129, 5, 109, 87, 163, 208, 44, 39, 175, 95, 143, 234, 91, 141, 57, - 249, 86, 115, 67, 142, 164, 255, 87, 121, 145, 81, 76, 171, 193, 246, 212, - 234, 20, 92, 55, 105, 95, 73, 35, 93, 213, 79, 14, 138, 74, 194, 187, - 202, 71, 95, 190, 105, 177, 128, 28, 29, 114, 35, 241, 38, 143, 93, 30, - 160, 232, 101, 199, 158, 238, 74, 124, 207, 224, 153, 114, 92, 121, 66, 146, - 193, 43, 131, 212, 6, 30, 252, 155, 241, 35, 194, 158, 228, 86, 140, 152, - 195, 236, 6, 136, 22, 197, 172, 175, 96, 211, 203, 51, 145, 207, 113, 226, - 204, 30, 38, 61, 153, 137, 1, 202, 175, 27, 75, 147, 29, 189, 82, 223, - 21, 180, 238, 242, 209, 79, 155, 179, 127, 130, 71, 198, 167, 214, 185, 250, - 176, 15, 148, 141, 205, 108, 183, 5, 182, 144, 37, 170, 159, 236, 46, 26, - 146, 132, 190, 127, 171, 158, 31, 253, 131, 237, 163, 128, 216, 240, 96, 106, - 103, 254, 172, 153, 58, 149, 2, 129, 98, 84, 145, 224, 49, 150, 244, 174, - 168, 222, 55, 131, 35, 85, 4, 213, 71, 116, 54, 21, 190, 167, 32, 204, - 233, 31, 123, 171, 237, 74, 51, 169, 133, 57, 27, 89, 182, 211, 201, 229, - 23, 212, 180, 164, 109, 254, 126, 58, 34, 127, 79, 241, 18, 220, 102, 83, - 73, 1, 216, 155, 64, 87, 25, 70, 139, 59, 213, 181, 240, 133, 114, 74, - 224, 56, 19, 81, 24, 108, 134, 60, 61, 12, 215, 232, 76, 82, 201, 147, - 189, 197, 210, 30, 39, 198, 6, 80, 250, 58, 221, 7, 133, 66, 107, 4, - 68, 214, 167, 45, 125, 238, 219, 185, 23, 38, 241, 179, 17, 120, 162, 145, - 26, 16, 41, 132, 235, 78, 175, 194, 137, 77, 11, 237, 1, 70, 110, 191, - 242, 6, 182, 77, 184, 105, 144, 172, 250, 129, 34, 179, 64, 8, 221, 67, - 153, 13, 79, 92, 197, 85, 178, 42, 217, 80, 165, 185, 34, 176, 122, 68, - 48, 98, 242, 118, 133, 213, 159, 74, 170, 188, 2, 238, 44, 162, 190, 248, - 165, 184, 135, 235, 245, 160, 80, 210, 230, 107, 33, 208, 15, 164, 103, 158, - 123, 156, 171, 73, 10, 107, 241, 226, 255, 25, 192, 111, 23, 118, 8, 38, - 98, 231, 64, 40, 57, 126, 158, 233, 225, 195, 21, 99, 53, 127, 89, 191, - 204, 109, 7, 249, 49, 1, 144, 183, 102, 56, 147, 206, 245, 62, 12, 43, - 118, 44, 216, 226, 91, 251, 17, 214, 57, 158, 187, 196, 209, 207, 125, 227, - 28, 3, 48, 65, 62, 31, 188, 211, 176, 59, 140, 197, 24, 136, 183, 44, - 189, 32, 1, 213, 71, 245, 46, 227, 175, 180, 36, 76, 29, 235, 47, 96, - 11, 157, 36, 119, 176, 68, 187, 234, 245, 12, 201, 100, 82, 251, 191, 161, - 72, 55, 227, 167, 224, 37, 117, 192, 157, 180, 255, 162, 105, 232, 170, 152, - 135, 223, 189, 116, 247, 63, 144, 2, 90, 188, 27, 49, 13, 164, 229, 197, - 190, 96, 213, 174, 235, 248, 71, 223, 239, 94, 184, 130, 50, 41, 199, 173, - 246, 32, 203, 159, 175, 248, 61, 153, 154, 27, 77, 108, 113, 205, 86, 149, - 76, 246, 213, 59, 113, 42, 199, 229, 1, 135, 48, 189, 13, 208, 211, 33, - 186, 212, 247, 91, 175, 1, 107, 137, 189, 47, 87, 227, 51, 125, 214, 151, - 16, 64, 246, 238, 121, 164, 206, 130, 102, 247, 226, 23, 141, 255, 148, 188, - 250, 237, 218, 131, 64, 91, 42, 244, 54, 125, 85, 152, 202, 26, 121, 214, - 17, 12, 209, 111, 102, 52, 205, 10, 85, 127, 65, 13, 251, 36, 79, 14, - 153, 36, 110, 243, 193, 77, 230, 104, 162, 136, 43, 249, 96, 253, 183, 22, - 125, 97, 62, 146, 172, 122, 201, 34, 25, 242, 101, 60, 151, 123, 136, 65, - 40, 57, 81, 117, 24, 75, 230, 104, 229, 47, 87, 124, 21, 39, 3, 223, - 116, 88, 131, 154, 108, 184, 21, 130, 92, 233, 138, 126, 74, 139, 179, 96, - 58, 119, 143, 240, 236, 69, 193, 115, 253, 29, 154, 68, 88, 163, 73, 206, - 195, 82, 145, 111, 220, 138, 55, 97, 116, 224, 39, 157, 7, 173, 101, 198, - 103, 71, 169, 178, 7, 150, 194, 24, 146, 47, 19, 230, 151, 57, 31, 129, - 113, 88, 39, 253, 231, 132, 141, 95, 46, 130, 24, 218, 194, 190, 219, 126, - 83, 30, 203, 9, 177, 1, 86, 151, 97, 67, 199, 216, 125, 145, 80, 106, - 132, 227, 29, 194, 100, 12, 23, 187, 168, 35, 155, 3, 102, 211, 84, 229, - 208, 59, 100, 1, 123, 137, 200, 222, 242, 218, 13, 58, 69, 233, 134, 111, - 31, 201, 161, 180, 222, 171, 14, 81, 220, 63, 243, 106, 102, 62, 170, 252, - 198, 173, 99, 155, 23, 234, 90, 157, 127, 111, 2, 196, 104, 13, 233, 248, - 114, 150, 66, 142, 26, 12, 190, 88, 200, 14, 100, 90, 56, 124, 222, 77, - 206, 21, 59, 89, 138, 106, 122, 198, 181, 135, 217, 80, 9, 77, 111, 233, - 185, 146, 199, 134, 71, 249, 21, 176, 60, 106, 207, 229, 136, 35, 22, 83, - 37, 168, 239, 78, 128, 46, 202, 166, 158, 7, 211, 126, 35, 213, 139, 55, - 74, 48, 9, 241, 129, 157, 51, 90, 207, 114, 218, 69, 17, 244, 180, 11, - 142, 165, 191, 210, 83, 188, 15, 37, 207, 161, 184, 136, 50, 250, 177, 173, - 231, 34, 100, 5, 253, 51, 156, 80, 79, 206, 176, 22, 238, 32, 146, 119, - 198, 111, 188, 54, 24, 135, 229, 13, 102, 202, 215, 120, 141, 106, 94, 193, - 111, 64, 237, 46, 38, 168, 192, 115, 122, 167, 191, 198, 66, 231, 9, 219, - 116, 244, 9, 227, 104, 123, 250, 4, 166, 237, 74, 52, 118, 23, 249, 109, - 76, 193, 59, 212, 54, 254, 238, 93, 136, 225, 88, 187, 45, 120, 255, 153, - 11, 215, 158, 25, 181, 116, 170, 201, 55, 183, 232, 136, 109, 35, 79, 119, - 146, 246, 44, 224, 53, 188, 148, 97, 231, 78, 135, 12, 242, 7, 90, 226, - 238, 164, 28, 160, 126, 214, 49, 4, 151, 17, 201, 241, 148, 142, 247, 5, - 183, 173, 214, 24, 223, 127, 74, 171, 35, 216, 149, 227, 59, 232, 123, 207, - 246, 219, 26, 235, 182, 163, 184, 156, 62, 67, 251, 166, 250, 101, 183, 231, - 21, 181, 153, 15, 5, 90, 81, 76, 112, 17, 86, 145, 92, 194, 120, 25, - 97, 193, 55, 91, 200, 132, 140, 203, 101, 98, 46, 5, 179, 3, 63, 171, - 99, 44, 222, 74, 100, 210, 9, 23, 167, 248, 118, 49, 130, 234, 176, 103, - 251, 44, 227, 101, 255, 139, 46, 58, 175, 9, 124, 27, 187, 223, 253, 205, - 71, 192, 51, 143, 32, 38, 15, 82, 42, 199, 105, 116, 35, 158, 99, 182, - 54, 249, 114, 1, 132, 161, 239, 163, 76, 218, 131, 190, 121, 166, 63, 180, - 119, 147, 133, 1, 14, 32, 103, 249, 125, 199, 172, 187, 203, 9, 190, 43, - 77, 140, 7, 58, 118, 224, 253, 45, 191, 41, 17, 83, 171, 30, 1, 53, - 140, 175, 89, 69, 152, 29, 207, 210, 1, 254, 60, 65, 50, 157, 245, 134, - 158, 135, 187, 42, 218, 13, 87, 176, 154, 27, 206, 136, 153, 88, 144, 201, - 137, 81, 1, 232, 126, 47, 201, 169, 105, 134, 7, 214, 91, 8, 207, 78, - 177, 39, 202, 137, 106, 26, 77, 84, 156, 96, 71, 31, 150, 32, 167, 6, - 204, 127, 29, 147, 165, 227, 131, 103, 214, 52, 241, 30, 72, 140, 128, 58, - 189, 65, 222, 37, 246, 157, 42, 83, 9, 95, 51, 227, 66, 194, 193, 19, - 197, 101, 39, 235, 186, 146, 36, 229, 76, 5, 57, 251, 86, 19, 167, 155, - 153, 160, 125, 42, 51, 85, 100, 66, 129, 154, 16, 230, 69, 137, 218, 43, - 118, 224, 241, 201, 137, 36, 250, 240, 37, 218, 129, 234, 43, 187, 100, 166, - 22, 174, 222, 66, 62, 186, 45, 68, 189, 95, 212, 255, 239, 221, 48, 80, - 162, 180, 31, 154, 50, 156, 140, 184, 65, 33, 199, 28, 185, 29, 213, 56, - 92, 65, 117, 145, 238, 216, 149, 1, 204, 211, 239, 112, 138, 62, 95, 233, - 101, 2, 237, 87, 50, 244, 216, 194, 189, 151, 175, 96, 171, 26, 198, 220, - 141, 106, 204, 90, 100, 186, 29, 72, 105, 48, 115, 165, 41, 231, 104, 91, - 83, 58, 244, 78, 51, 93, 137, 194, 129, 102, 96, 18, 138, 70, 109, 247, - 65, 200, 59, 29, 165, 143, 223, 61, 130, 52, 238, 204, 195, 70, 186, 5, - 170, 51, 142, 193, 246, 84, 156, 189, 33, 106, 55, 249, 14, 35, 253, 61, - 173, 77, 205, 110, 106, 49, 84, 121, 162, 107, 14, 75, 124, 214, 51, 234, - 18, 113, 101, 196, 27, 79, 197, 124, 131, 150, 102, 41, 181, 128, 80, 164, - 200, 93, 218, 157, 20, 2, 249, 206, 134, 192, 51, 28, 166, 99, 37, 199, - 17, 170, 121, 75, 138, 48, 109, 213, 94, 33, 187, 210, 195, 80, 160, 36, - 94, 221, 12, 169, 23, 7, 175, 73, 162, 192, 219, 77, 13, 39, 251, 18, - 255, 88, 16, 23, 177, 253, 41, 150, 181, 12, 63, 164, 225, 20, 72, 245, - 104, 187, 225, 220, 47, 71, 122, 248, 222, 11, 241, 175, 87, 32, 228, 60, - 19, 209, 147, 230, 24, 138, 103, 73, 93, 13, 214, 117, 161, 18, 183, 132, - 148, 183, 10, 120, 29, 6, 57, 160, 139, 185, 21, 197, 102, 251, 143, 39, - 144, 170, 96, 209, 244, 16, 85, 141, 84, 230, 242, 3, 132, 82, 253, 4, - 8, 163, 228, 24, 67, 85, 48, 140, 82, 155, 97, 174, 60, 126, 61, 22, - 234, 61, 179, 223, 19, 79, 228, 207, 155, 100, 162, 68, 249, 168, 114, 236, - 232, 109, 143, 199, 178, 70, 64, 154, 56, 235, 96, 98, 128, 118, 206, 211, - 99, 61, 224, 200, 120, 174, 28, 130, 112, 228, 117, 29, 192, 81, 49, 148, - 126, 92, 2, 167, 159, 21, 12, 236, 97, 33, 76, 124, 146, 112, 217, 38, - 107, 82, 127, 1, 206, 104, 57, 6, 53, 233, 158, 178, 196, 126, 236, 102, - 253, 220, 228, 89, 248, 190, 163, 233, 126, 149, 236, 216, 177, 194, 78, 165, - 186, 58, 11, 21, 38, 166, 55, 110, 163, 219, 125, 60, 208, 34, 152, 237, - 242, 107, 98, 191, 194, 213, 179, 100, 254, 195, 66, 42, 94, 5, 250, 190, - 129, 6, 45, 157, 130, 56, 169, 117, 124, 9, 205, 27, 54, 110, 21, 191, - 31, 187, 116, 145, 102, 117, 233, 253, 35, 158, 20, 200, 182, 92, 69, 236, - 160, 48, 179, 231, 10, 206, 68, 91, 204, 134, 80, 246, 166, 217, 15, 42, - 152, 37, 233, 113, 180, 206, 86, 110, 155, 31, 90, 181, 123, 144, 252, 174, - 177, 23, 244, 70, 212, 173, 39, 235, 144, 32, 208, 172, 222, 151, 67, 94, - 141, 19, 35, 33, 40, 196, 137, 210, 93, 50, 47, 240, 156, 96, 1, 30, - 249, 157, 236, 77, 155, 235, 217, 178, 19, 190, 198, 68, 218, 62, 97, 30, - 63, 34, 144, 73, 49, 153, 165, 114, 230, 121, 15, 210, 143, 133, 229, 219, - 201, 112, 253, 83, 245, 186, 10, 89, 141, 252, 203, 55, 85, 211, 16, 136, - 40, 50, 225, 59, 209, 43, 198, 133, 1, 248, 127, 139, 173, 103, 146, 53, - 67, 132, 121, 176, 219, 236, 94, 50, 156, 73, 221, 38, 208, 98, 113, 100, - 177, 201, 148, 114, 1, 216, 115, 39, 127, 96, 189, 176, 173, 81, 44, 128, - 146, 226, 98, 136, 160, 11, 42, 119, 242, 121, 49, 78, 97, 41, 182, 248, - 53, 83, 69, 181, 81, 76, 157, 115, 169, 108, 54, 26, 17, 86, 145, 56, - 127, 216, 172, 251, 220, 75, 133, 87, 171, 109, 72, 233, 246, 114, 108, 200, - 74, 247, 7, 168, 245, 125, 83, 164, 178, 52, 81, 4, 17, 193, 241, 127, - 208, 251, 118, 232, 126, 137, 31, 172, 41, 218, 149, 240, 25, 177, 239, 139, - 36, 21, 228, 125, 234, 71, 196, 30, 120, 202, 10, 134, 220, 45, 207, 252, - 202, 25, 139, 158, 110, 195, 175, 7, 241, 52, 198, 89, 11, 239, 71, 170, - 93, 234, 133, 205, 3, 134, 169, 179, 9, 213, 75, 244, 190, 78, 203, 63, - 96, 131, 123, 217, 83, 202, 27, 162, 95, 221, 108, 195, 227, 30, 80, 2, - 134, 25, 103, 150, 223, 131, 28, 38, 243, 71, 211, 152, 99, 138, 65, 125, - 107, 61, 92, 148, 52, 39, 106, 247, 139, 241, 32, 64, 66, 51, 36, 182, - 54, 131, 162, 90, 142, 21, 151, 189, 171, 41, 110, 248, 104, 169, 3, 76, - 102, 64, 86, 167, 229, 1, 46, 154, 92, 144, 57, 67, 70, 11, 145, 120, - 86, 140, 25, 242, 217, 159, 33, 87, 88, 47, 172, 78, 130, 68, 82, 240, - 218, 163, 69, 27, 21, 222, 144, 40, 135, 211, 234, 185, 152, 178, 53, 136, - 161, 55, 19, 48, 196, 227, 91, 150, 197, 36, 142, 28, 239, 8, 20, 212, - 68, 180, 22, 54, 56, 114, 247, 101, 174, 3, 31, 135, 200, 155, 62, 141, - 1, 219, 43, 113, 191, 254, 105, 235, 36, 7, 161, 92, 2, 41, 232, 184, - 73, 191, 43, 13, 5, 24, 158, 147, 121, 90, 160, 10, 211, 94, 143, 240, - 69, 38, 197, 13, 188, 80, 53, 240, 203, 115, 148, 78, 217, 45, 152, 225, - 37, 152, 133, 20, 74, 247, 217, 95, 4, 174, 8, 250, 77, 163, 107, 63, - 191, 212, 75, 15, 188, 144, 52, 97, 213, 243, 177, 26, 60, 108, 113, 185, - 56, 3, 188, 90, 180, 62, 95, 237, 131, 108, 8, 169, 45, 118, 26, 106, - 80, 245, 88, 15, 72, 98, 254, 35, 237, 64, 157, 105, 255, 131, 145, 103, - 45, 12, 205, 238, 74, 211, 229, 188, 159, 190, 213, 44, 171, 128, 75, 223, - 168, 241, 202, 238, 61, 170, 8, 198, 129, 199, 225, 114, 151, 252, 217, 207, - 138, 203, 226, 6, 115, 228, 183, 206, 188, 195, 42, 223, 1, 175, 26, 149, - 235, 159, 120, 222, 33, 214, 105, 10, 30, 113, 212, 226, 91, 59, 130, 185, - 183, 65, 222, 13, 59, 108, 181, 197, 111, 123, 206, 185, 255, 39, 212, 196, - 99, 155, 195, 167, 254, 124, 2, 171, 84, 224, 61, 147, 6, 32, 174, 152, - 215, 122, 233, 111, 116, 145, 75, 243, 124, 44, 77, 31, 92, 252, 212, 161, - 84, 208, 56, 211, 73, 149, 243, 4, 121, 82, 6, 168, 147, 74, 108, 194, - 48, 8, 105, 72, 110, 87, 125, 184, 148, 186, 116, 20, 163, 232, 216, 88, - 31, 59, 209, 188, 44, 245, 213, 58, 20, 192, 224, 204, 60, 208, 130, 79, - 2, 25, 63, 111, 46, 231, 250, 67, 20, 98, 179, 146, 135, 37, 161, 192, - 87, 57, 123, 221, 234, 208, 68, 182, 16, 111, 196, 220, 246, 43, 236, 154, - 18, 219, 14, 161, 142, 73, 5, 60, 28, 238, 47, 84, 23, 164, 62, 230, - 110, 62, 122, 16, 8, 93, 46, 27, 179, 67, 129, 150, 181, 156, 107, 229, - 240, 126, 105, 85, 151, 97, 2, 210, 82, 165, 107, 230, 115, 79, 46, 226, - 79, 107, 209, 172, 99, 136, 226, 57, 25, 199, 109, 210, 242, 162, 18, 50, - 113, 203, 149, 165, 251, 176, 154, 228, 99, 40, 164, 71, 150, 124, 179, 243, - 15, 229, 167, 73, 32, 85, 226, 128, 231, 12, 242, 159, 122, 90, 215, 24, - 122, 117, 243, 177, 15, 189, 95, 194, 205, 83, 165, 252, 224, 245, 204, 227, - 237, 180, 147, 207, 243, 56, 224, 86, 29, 160, 50, 122, 19, 198, 103, 12, - 193, 69, 178, 150, 125, 93, 190, 34, 66, 49, 221, 3, 106, 113, 134, 76, - 203, 81, 216, 80, 244, 184, 237, 223, 89, 101, 119, 215, 22, 58, 34, 210, - 159, 22, 66, 254, 238, 87, 193, 157, 242, 6, 37, 191, 13, 154, 220, 143, - 46, 14, 138, 117, 95, 221, 119, 207, 240, 132, 34, 158, 139, 10, 214, 170, - 197, 4, 58, 239, 220, 63, 77, 130, 16, 143, 59, 85, 185, 139, 47, 52, - 133, 70, 178, 117, 11, 67, 100, 142, 37, 64, 127, 82, 172, 182, 112, 246, - 173, 35, 89, 215, 123, 174, 57, 142, 53, 229, 71, 116, 145, 119, 40, 12, - 40, 108, 75, 252, 146, 141, 1, 102, 231, 88, 184, 173, 209, 70, 89, 128, - 22, 225, 88, 235, 243, 166, 176, 156, 122, 159, 98, 115, 153, 1, 180, 248, - 255, 183, 24, 176, 74, 111, 137, 138, 250, 38, 230, 14, 149, 85, 3, 205, - 162, 182, 1, 213, 30, 250, 184, 128, 65, 17, 64, 114, 189, 55, 248, 84, - 151, 192, 23, 249, 27, 164, 178, 40, 49, 68, 247, 185, 22, 116, 89, 232, - 169, 252, 91, 133, 26, 10, 34, 199, 225, 204, 255, 215, 7, 28, 109, 79, - 111, 34, 147, 247, 146, 175, 195, 180, 94, 119, 164, 72, 230, 18, 155, 16, - 239, 159, 168, 69, 104, 22, 202, 151, 129, 48, 14, 221, 86, 17, 70, 112, - 14, 132, 172, 18, 23, 118, 47, 161, 72, 129, 36, 244, 176, 135, 64, 186, - 91, 132, 43, 119, 24, 209, 233, 104, 173, 200, 184, 254, 40, 215, 202, 81, - 153, 136, 44, 226, 170, 55, 208, 123, 57, 168, 197, 11, 112, 79, 245, 135, - 60, 47, 140, 201, 142, 54, 34, 33, 209, 153, 205, 141, 196, 104, 168, 4, - 246, 93, 50, 169, 83, 136, 243, 207, 15, 143, 54, 68, 1, 106, 45, 188, - 37, 11, 139, 87, 117, 7, 229, 103, 138, 22, 249, 57, 68, 169, 186, 13, - 163, 60, 250, 85, 179, 95, 247, 100, 32, 147, 188, 50, 37, 173, 255, 221, - 220, 35, 16, 116, 218, 112, 253, 56, 178, 12, 77, 142, 36, 136, 82, 85, - 247, 185, 164, 118, 12, 215, 127, 45, 145, 252, 62, 21, 173, 69, 139, 108, - 47, 220, 225, 178, 161, 194, 17, 141, 81, 126, 102, 164, 105, 217, 232, 185, - 208, 67, 240, 162, 254, 54, 187, 84, 172, 98, 58, 220, 151, 103, 63, 207, - 181, 39, 19, 192, 47, 143, 72, 3, 199, 69, 94, 214, 31, 175, 34, 155, - 231, 67, 144, 113, 121, 63, 8, 218, 226, 156, 98, 186, 165, 215, 255, 195, - 110, 243, 172, 223, 21, 189, 164, 41, 214, 98, 47, 119, 85, 134, 81, 200, - 78, 182, 224, 138, 49, 211, 117, 140, 47, 113, 248, 219, 1, 71, 160, 96, - 181, 87, 243, 70, 235, 208, 29, 177, 37, 196, 252, 119, 118, 172, 21, 13, - 37, 76, 102, 63, 133, 197, 242, 3, 106, 222, 43, 162, 220, 104, 154, 205, - 37, 19, 241, 83, 216, 252, 35, 98, 193, 42, 240, 244, 104, 245, 53, 4, - 209, 184, 91, 99, 44, 210, 110, 29, 243, 139, 228, 18, 227, 70, 213, 40, - 11, 172, 236, 230, 213, 122, 153, 244, 4, 131, 18, 170, 206, 99, 238, 5, - 151, 36, 31, 201, 44, 232, 11, 158, 252, 163, 128, 39, 120, 225, 159, 75, - 239, 124, 203, 156, 75, 242, 135, 55, 177, 230, 197, 74, 226, 36, 196, 155, - 14, 17, 236, 198, 176, 41, 181, 228, 235, 69, 205, 144, 21, 115, 190, 103, - 59, 200, 108, 155, 2, 154, 168, 69, 169, 231, 84, 173, 38, 210, 153, 246, - 138, 32, 7, 155, 59, 86, 142, 166, 233, 79, 201, 6, 17, 89, 44, 244, - 5, 144, 169, 200, 50, 124, 91, 184, 67, 180, 11, 18, 95, 154, 152, 136, - 52, 7, 118, 36, 4, 128, 153, 170, 155, 28, 108, 68, 131, 23, 11, 177, - 71, 83, 210, 145, 197, 191, 150, 61, 64, 35, 154, 249, 224, 254, 54, 113, - 220, 178, 100, 12, 168, 104, 180, 65, 25, 197, 91, 224, 37, 22, 85, 116, - 24, 50, 79, 183, 92, 201, 129, 217, 161, 71, 3, 152, 26, 250, 56, 123, - 101, 40, 153, 119, 6, 18, 70, 152, 112, 10, 93, 165, 133, 196, 232, 58, - 165, 233, 137, 17, 115, 114, 47, 54, 51, 97, 14, 147, 188, 232, 202, 72, - 218, 231, 194, 83, 180, 58, 101, 239, 114, 113, 153, 74, 9, 204, 54, 188, - 118, 146, 65, 84, 16, 147, 237, 71, 142, 54, 224, 153, 207, 38, 76, 26, - 138, 249, 26, 117, 136, 230, 202, 76, 14, 186, 194, 94, 82, 251, 122, 161, - 108, 130, 49, 124, 12, 103, 86, 226, 180, 240, 109, 120, 95, 177, 138, 76, - 71, 152, 46, 132, 38, 16, 112, 236, 175, 202, 92, 10, 177, 155, 28, 217, - 108, 179, 38, 88, 255, 120, 171, 70, 76, 240, 14, 45, 101, 181, 224, 17, - 57, 192, 72, 148, 16, 108, 52, 30, 208, 174, 240, 212, 118, 74, 89, 137, - 184, 207, 126, 145, 49, 198, 180, 20, 39, 50, 234, 179, 247, 170, 55, 143, - 246, 123, 191, 81, 55, 217, 198, 95, 60, 116, 206, 11, 13, 255, 18, 207, - 253, 12, 48, 206, 213, 247, 111, 46, 233, 226, 120, 208, 49, 1, 254, 170, - 92, 3, 215, 31, 1, 203, 81, 56, 174, 48, 216, 51, 85, 21, 15, 113, - 237, 13, 157, 218, 40, 219, 229, 164, 70, 25, 139, 151, 179, 66, 251, 82, - 229, 203, 115, 254, 89, 253, 29, 127, 138, 26, 34, 230, 114, 129, 78, 96, - 1, 136, 127, 202, 132, 209, 106, 59, 122, 107, 25, 159, 142, 19, 97, 62, - 167, 33, 114, 2, 146, 66, 243, 38, 109, 44, 178, 7, 5, 164, 245, 207, - 33, 86, 103, 249, 132, 83, 106, 240, 214, 1, 104, 139, 211, 109, 204, 192, - 1, 131, 66, 214, 122, 161, 30, 141, 251, 229, 168, 149, 212, 52, 128, 68, - 221, 151, 143, 191, 239, 115, 177, 148, 89, 2, 135, 218, 97, 219, 199, 28, - 135, 106, 169, 160, 12, 75, 211, 178, 97, 132, 24, 180, 38, 226, 168, 217, - 202, 73, 127, 97, 137, 125, 105, 92, 183, 209, 57, 116, 220, 44, 98, 163, - 60, 184, 13, 79, 70, 149, 154, 161, 241, 105, 125, 59, 240, 166, 7, 55, - 149, 228, 63, 168, 185, 43, 206, 150, 208, 83, 252, 130, 5, 89, 80, 247, - 218, 201, 237, 254, 142, 180, 229, 200, 75, 251, 94, 131, 46, 216, 53, 97, - 215, 148, 11, 22, 121, 6, 250, 80, 242, 201, 96, 66, 123, 26, 156, 239, - 174, 202, 35, 160, 109, 65, 181, 241, 31, 94, 72, 192, 46, 134, 238, 163, - 125, 231, 62, 86, 52, 96, 78, 163, 9, 172, 112, 36, 34, 192, 87, 80, - 231, 55, 119, 66, 121, 159, 248, 234, 200, 13, 245, 238, 152, 201, 225, 62, - 178, 30, 33, 89, 147, 185, 207, 7, 100, 65, 171, 16, 234, 198, 53, 1, - 214, 170, 103, 30, 223, 57, 134, 193, 73, 212, 182, 160, 227, 35, 102, 196, - 244, 69, 213, 31, 91, 238, 27, 10, 175, 49, 219, 180, 174, 234, 147, 178, - 132, 25, 98, 65, 209, 162, 92, 121, 156, 110, 29, 36, 239, 185, 23, 157, - 131, 238, 68, 64, 129, 40, 209, 176, 124, 27, 174, 150, 89, 71, 4, 45, - 61, 27, 236, 112, 15, 47, 156, 226, 41, 99, 223, 129, 88, 111, 150, 182, - 107, 31, 69, 175, 138, 203, 32, 15, 189, 51, 61, 159, 134, 230, 156, 119, - 198, 241, 39, 185, 33, 105, 164, 140, 50, 79, 158, 124, 144, 182, 109, 72, - 52, 243, 168, 140, 250, 80, 29, 62, 239, 42, 193, 246, 126, 136, 24, 146, - 99, 88, 153, 179, 249, 204, 123, 69, 101, 23, 49, 157, 219, 131, 95, 248, - 23, 163, 116, 58, 121, 211, 220, 192, 218, 114, 236, 53, 162, 145, 35, 93, - 54, 158, 9, 102, 155, 26, 124, 242, 67, 15, 184, 168, 244, 55, 104, 3, - 254, 34, 161, 117, 251, 151, 236, 128, 187, 164, 157, 110, 99, 18, 65, 206, - 130, 179, 250, 40, 70, 64, 209, 103, 176, 57, 249, 137, 125, 151, 221, 136, - 106, 130, 73, 235, 229, 176, 197, 45, 211, 20, 64, 183, 25, 190, 33, 121, - 69, 114, 27, 37, 32, 195, 115, 250, 45, 49, 223, 244, 16, 221, 80, 123, - 107, 159, 68, 50, 165, 189, 104, 255, 204, 221, 241, 85, 132, 101, 212, 235, - 72, 209, 41, 86, 133, 110, 210, 185, 221, 74, 82, 24, 198, 9, 183, 176, - 39, 194, 154, 8, 167, 102, 131, 205, 109, 176, 182, 86, 113, 133, 32, 184, - 90, 252, 122, 204, 195, 43, 183, 210, 246, 64, 123, 107, 125, 82, 186, 175, - 152, 30, 7, 228, 182, 73, 42, 101, 194, 113, 62, 223, 229, 167, 15, 183, - 158, 26, 82, 53, 228, 245, 29, 93, 237, 199, 115, 48, 28, 71, 38, 16, - 27, 248, 215, 166, 68, 222, 59, 23, 99, 93, 187, 10, 167, 139, 90, 57, - 104, 41, 87, 193, 101, 163, 78, 6, 93, 150, 65, 167, 232, 242, 179, 96, - 135, 228, 87, 15, 51, 225, 20, 38, 110, 123, 28, 169, 36, 8, 252, 203, - 228, 206, 3, 51, 53, 47, 2, 208, 237, 187, 141, 244, 18, 58, 146, 107, - 137, 170, 78, 212, 4, 30, 34, 66, 248, 199, 160, 48, 111, 251, 237, 210, - 189, 143, 77, 161, 172, 68, 84, 62, 225, 213, 86, 139, 31, 220, 199, 80, - 74, 191, 93, 144, 130, 23, 199, 216, 241, 88, 46, 25, 219, 149, 245, 92, - 121, 75, 213, 8, 5, 177, 117, 196, 78, 189, 14, 23, 178, 56, 170, 97, - 13, 123, 129, 43, 181, 113, 108, 140, 72, 44, 133, 128, 157, 210, 79, 234, - 253, 142, 5, 176, 89, 130, 196, 235, 133, 20, 100, 229, 22, 90, 143, 42, - 176, 216, 201, 46, 74, 10, 88, 114, 141, 161, 148, 79, 162, 27, 184, 84, - 21, 139, 251, 173, 130, 84, 27, 164, 14, 171, 122, 205, 233, 66, 119, 43, - 99, 235, 241, 90, 153, 51, 95, 246, 115, 2, 77, 1, 54, 198, 6, 73, - 217, 35, 19, 202, 134, 4, 230, 91, 48, 206, 13, 151, 149, 42, 130, 231, - 100, 203, 224, 60, 163, 9, 61, 81, 10, 75, 140, 225, 52, 98, 134, 32, - 200, 169, 230, 105, 147, 140, 175, 33, 146, 92, 100, 219, 96, 254, 227, 195, - 75, 204, 165, 56, 145, 1, 94, 255, 238, 158, 251, 174, 3, 205, 101, 250, - 189, 157, 218, 236, 46, 64, 191, 149, 206, 188, 126, 8, 53, 146, 199, 165, - 187, 23, 247, 118, 195, 211, 158, 81, 43, 45, 6, 200, 77, 119, 156, 60, - 192, 247, 108, 162, 56, 194, 87, 33, 97, 213, 52, 48, 150, 77, 19, 61, - 195, 40, 28, 216, 233, 215, 33, 118, 141, 15, 151, 204, 12, 173, 46, 94, - 171, 22, 215, 159, 11, 76, 154, 227, 1, 241, 191, 214, 238, 81, 120, 111, - 175, 222, 227, 57, 135, 43, 146, 255, 111, 48, 190, 125, 102, 31, 160, 127, - 42, 187, 20, 110, 148, 77, 135, 24, 87, 85, 159, 143, 167, 34, 2, 73, - 100, 40, 149, 122, 63, 74, 162, 82, 24, 137, 29, 223, 131, 179, 227, 6, - 77, 102, 183, 252, 154, 73, 219, 222, 74, 129, 25, 255, 239, 30, 86, 156, - 59, 115, 67, 231, 75, 245, 215, 152, 128, 2, 90, 78, 26, 121, 208, 186, - 199, 42, 17, 118, 174, 234, 145, 216, 126, 167, 200, 181, 81, 242, 190, 6, - 232, 245, 16, 166, 143, 84, 187, 72, 128, 188, 67, 112, 29, 61, 191, 52, - 136, 99, 127, 8, 223, 170, 59, 28, 56, 45, 20, 87, 61, 222, 177, 27, - 185, 24, 107, 226, 19, 105, 217, 122, 138, 78, 248, 90, 67, 205, 41, 141, - 171, 144, 80, 90, 190, 25, 208, 119, 216, 1, 183, 36, 98, 235, 51, 248, - 127, 14, 85, 168, 8, 155, 30, 132, 228, 88, 171, 103, 110, 41, 198, 173, - 148, 34, 137, 17, 88, 134, 247, 181, 83, 1, 166, 145, 127, 205, 173, 71, - 41, 134, 22, 205, 233, 129, 194, 173, 48, 223, 149, 190, 166, 56, 21, 55, - 147, 137, 64, 238, 142, 245, 1, 117, 250, 62, 32, 5, 191, 222, 239, 172, - 82, 65, 105, 144, 227, 193, 20, 104, 96, 231, 18, 165, 253, 100, 225, 125, - 253, 51, 34, 83, 126, 135, 226, 88, 166, 234, 203, 105, 194, 145, 116, 12, - 120, 159, 133, 79, 193, 63, 3, 189, 1, 158, 58, 171, 53, 237, 5, 91, - 225, 193, 50, 157, 4, 211, 172, 243, 165, 120, 234, 232, 224, 152, 84, 184, - 77, 214, 201, 182, 114, 236, 109, 243, 186, 7, 202, 150, 209, 92, 242, 70, - 95, 57, 171, 125, 60, 116, 19, 2, 59, 107, 147, 120, 43, 141, 61, 9, - 188, 14, 106, 242, 37, 117, 111, 96, 112, 142, 227, 196, 232, 93, 144, 102, - 4, 211, 80, 94, 109, 20, 189, 76, 90, 235, 135, 148, 40, 140, 111, 124, - 42, 126, 146, 190, 60, 9, 158, 148, 254, 44, 222, 64, 157, 221, 140, 207, - 193, 79, 233, 187, 106, 169, 24, 197, 150, 141, 128, 73, 63, 129, 249, 39, - 44, 8, 195, 94, 221, 162, 95, 76, 28, 230, 213, 197, 244, 212, 186, 166, - 210, 253, 124, 10, 91, 240, 107, 39, 67, 49, 203, 22, 126, 186, 19, 132, - 212, 21, 246, 58, 196, 39, 188, 195, 66, 117, 249, 60, 160, 55, 22, 116, - 237, 10, 190, 212, 47, 175, 112, 204, 35, 197, 233, 224, 192, 246, 111, 214, - 133, 174, 91, 217, 58, 182, 9, 32, 167, 248, 17, 63, 222, 1, 160, 253, - 105, 81, 202, 191, 117, 168, 34, 24, 55, 179, 200, 214, 15, 42, 28, 102, - 165, 107, 143, 150, 220, 13, 189, 174, 234, 85, 185, 16, 182, 68, 24, 132, - 241, 56, 75, 188, 203, 104, 17, 237, 242, 74, 103, 170, 131, 58, 79, 23, - 232, 236, 59, 188, 179, 160, 4, 105, 167, 46, 187, 64, 228, 102, 140, 66, - 40, 145, 220, 132, 165, 161, 222, 34, 94, 169, 60, 209, 200, 228, 147, 75, - 222, 120, 21, 11, 18, 241, 144, 76, 236, 138, 146, 166, 30, 15, 217, 69, - 138, 68, 239, 83, 101, 124, 14, 232, 250, 73, 227, 127, 212, 186, 133, 72, - 95, 125, 79, 160, 12, 247, 109, 165, 51, 101, 142, 152, 105, 136, 254, 190, - 3, 211, 31, 244, 194, 233, 18, 99, 241, 159, 103, 212, 189, 74, 157, 232, - 96, 198, 35, 122, 54, 208, 226, 136, 37, 102, 59, 216, 214, 45, 251, 7, - 209, 33, 232, 137, 243, 162, 215, 92, 159, 133, 223, 6, 236, 4, 115, 196, - 112, 77, 199, 219, 210, 212, 51, 83, 222, 30, 193, 226, 180, 29, 164, 45, - 55, 126, 178, 12, 127, 70, 97, 193, 128, 39, 4, 109, 122, 250, 218, 10, - 199, 77, 110, 240, 7, 238, 204, 213, 189, 8, 45, 62, 232, 203, 141, 250, - 216, 171, 20, 200, 174, 147, 254, 203, 195, 32, 142, 149, 15, 59, 114, 43, - 137, 186, 212, 215, 78, 232, 130, 115, 18, 214, 126, 158, 128, 218, 74, 59, - 129, 71, 124, 172, 143, 220, 243, 154, 69, 134, 23, 116, 125, 227, 215, 83, - 191, 25, 228, 1, 100, 235, 128, 84, 242, 160, 140, 168, 83, 156, 194, 120, - 205, 128, 2, 129, 138, 43, 7, 72, 225, 9, 52, 94, 109, 70, 149, 216, - 94, 1, 163, 154, 28, 174, 195, 244, 73, 115, 132, 16, 126, 8, 213, 245, - 92, 29, 162, 225, 87, 129, 62, 242, 231, 177, 138, 249, 102, 151, 120, 189, - 248, 143, 165, 192, 172, 186, 94, 107, 80, 244, 205, 84, 152, 178, 96, 115, - 58, 37, 4, 141, 210, 95, 181, 57, 182, 78, 1, 62, 153, 236, 241, 31, - 13, 246, 167, 32, 184, 48, 217, 201, 73, 88, 177, 35, 90, 200, 175, 39, - 44, 226, 155, 60, 7, 95, 181, 49, 41, 165, 93, 2, 121, 205, 171, 50, - 74, 205, 53, 249, 40, 79, 30, 159, 206, 32, 69, 116, 63, 111, 237, 172, - 105, 172, 18, 95, 63, 161, 117, 150, 186, 38, 206, 119, 47, 180, 175, 254, - 122, 143, 37, 20, 74, 47, 123, 129, 152, 85, 107, 254, 96, 49, 203, 141, - 73, 247, 98, 203, 28, 235, 7, 149, 144, 201, 19, 78, 37, 25, 90, 54, - 89, 46, 61, 159, 64, 145, 119, 40, 27, 104, 208, 127, 112, 53, 162, 36, - 185, 251, 123, 108, 19, 129, 38, 69, 109, 29, 176, 218, 97, 94, 167, 207, - 36, 205, 64, 108, 147, 34, 19, 93, 5, 238, 163, 252, 10, 27, 148, 240, - 78, 20, 185, 38, 230, 91, 58, 122, 208, 174, 133, 145, 245, 163, 43, 152, - 202, 126, 134, 163, 41, 183, 133, 252, 158, 27, 106, 229, 108, 135, 10, 201, - 66, 240, 199, 250, 249, 20, 73, 132, 12, 251, 24, 220, 193, 60, 65, 42, - 38, 136, 196, 116, 119, 169, 101, 208, 124, 23, 91, 55, 21, 217, 172, 253, - 188, 27, 248, 196, 47, 148, 30, 58, 24, 105, 141, 36, 5, 84, 236, 59, - 148, 108, 87, 175, 43, 75, 13, 183, 160, 227, 24, 242, 135, 206, 174, 71, - 184, 152, 71, 47, 131, 89, 76, 120, 247, 201, 99, 116, 102, 163, 199, 21, - 224, 150, 102, 231, 25, 234, 161, 211, 104, 2, 208, 77, 146, 129, 44, 14, - 195, 219, 10, 173, 213, 147, 206, 253, 22, 53, 218, 239, 94, 217, 178, 138, - 49, 58, 187, 46, 221, 227, 118, 52, 127, 67, 12, 250, 179, 162, 60, 87, - 83, 98, 218, 140, 219, 116, 96, 200, 77, 99, 153, 204, 21, 127, 139, 10, - 209, 186, 99, 225, 144, 88, 218, 181, 197, 12, 75, 192, 128, 159, 61, 185, - 239, 100, 85, 163, 241, 195, 71, 99, 229, 16, 185, 159, 114, 155, 181, 31, - 44, 136, 14, 126, 63, 22, 226, 168, 182, 167, 111, 55, 125, 12, 93, 37, - 211, 10, 140, 194, 205, 23, 49, 249, 220, 3, 82, 42, 70, 190, 40, 92, - 22, 70, 249, 117, 85, 8, 156, 38, 248, 178, 221, 56, 23, 58, 84, 116, - 96, 151, 242, 231, 14, 109, 142, 79, 82, 16, 120, 247, 110, 228, 70, 9, - 28, 222, 244, 104, 80, 14, 29, 184, 167, 42, 190, 193, 20, 243, 210, 65, - 123, 145, 178, 40, 34, 53, 190, 1, 30, 185, 86, 176, 89, 148, 179, 252, - 155, 25, 7, 251, 230, 35, 247, 78, 162, 142, 237, 242, 104, 39, 15, 227, - 197, 1, 63, 33, 179, 224, 11, 167, 221, 82, 252, 41, 245, 48, 214, 76, - 65, 234, 1, 164, 82, 194, 239, 101, 202, 86, 223, 118, 158, 99, 52, 28, - 111, 86, 115, 27, 213, 237, 104, 160, 157, 162, 17, 173, 135, 52, 98, 233, - 162, 87, 143, 9, 49, 192, 100, 71, 11, 123, 134, 229, 76, 164, 181, 209, - 80, 144, 57, 118, 17, 47, 161, 183, 66, 36, 104, 187, 25, 196, 64, 127, - 70, 11, 124, 236, 173, 94, 151, 103, 51, 215, 129, 88, 148, 39, 209, 115, - 13, 62, 151, 31, 210, 100, 155, 163, 234, 141, 57, 126, 228, 167, 177, 111, - 168, 92, 53, 71, 31, 33, 153, 3, 150, 103, 36, 220, 79, 202, 89, 134, - 80, 130, 153, 119, 240, 83, 131, 123, 207, 67, 174, 115, 204, 176, 139, 106, - 247, 49, 215, 198, 130, 153, 117, 214, 132, 39, 68, 6, 255, 221, 229, 188, - 170, 253, 197, 61, 44, 188, 12, 172, 67, 134, 34, 225, 228, 223, 7, 158, - 204, 63, 41, 180, 195, 144, 120, 253, 168, 159, 43, 86, 245, 196, 111, 239, - 141, 255, 216, 33, 188, 209, 176, 249, 235, 182, 164, 92, 89, 67, 250, 39, - 207, 81, 64, 26, 114, 91, 152, 97, 57, 17, 6, 82, 161, 101, 19, 218, - 120, 208, 187, 222, 248, 168, 213, 239, 195, 160, 88, 26, 202, 142, 49, 217, - 13, 148, 72, 138, 69, 65, 5, 26, 62, 158, 10, 90, 67, 149, 161, 48, - 156, 183, 142, 243, 50, 52, 238, 194, 17, 61, 108, 150, 49, 26, 68, 96, - 56, 73, 190, 41, 32, 50, 155, 180, 97, 179, 35, 92, 251, 54, 33, 147, - 229, 166, 215, 106, 113, 11, 214, 110, 35, 151, 13, 175, 80, 100, 18, 169, - 139, 118, 99, 179, 236, 30, 169, 33, 6, 50, 230, 89, 203, 121, 174, 17, - 85, 166, 130, 76, 193, 46, 61, 132, 139, 56, 65, 101, 199, 52, 123, 5, - 245, 145, 240, 212, 18, 61, 217, 239, 1, 225, 139, 192, 200, 73, 43, 230, - 64, 8, 144, 158, 135, 183, 207, 106, 244, 114, 46, 192, 45, 91, 101, 227, - 60, 19, 81, 97, 87, 207, 146, 58, 249, 233, 100, 68, 130, 2, 189, 248, - 124, 104, 217, 205, 137, 113, 89, 173, 77, 184, 43, 255, 226, 186, 160, 206, - 253, 74, 105, 124, 5, 230, 245, 81, 151, 235, 51, 252, 42, 137, 88, 122, - 128, 90, 33, 243, 187, 77, 234, 39, 244, 26, 209, 93, 117, 219, 51, 125, - 47, 194, 213, 244, 206, 155, 69, 98, 176, 133, 251, 187, 97, 7, 237, 191, - 63, 236, 197, 112, 106, 119, 4, 150, 204, 223, 126, 153, 30, 238, 184, 222, - 8, 138, 78, 98, 246, 48, 3, 177, 72, 157, 213, 253, 131, 56, 90, 146, - 164, 85, 253, 67, 93, 37, 157, 35, 230, 224, 108, 80, 173, 245, 55, 15, - 166, 241, 41, 127, 243, 118, 44, 133, 11, 198, 108, 40, 224, 231, 120, 86, - 79, 21, 175, 15, 253, 187, 211, 107, 212, 91, 121, 234, 215, 22, 135, 2, - 26, 140, 231, 150, 83, 116, 201, 123, 142, 23, 211, 10, 177, 31, 4, 233, - 193, 177, 75, 137, 252, 178, 150, 136, 74, 231, 103, 60, 191, 235, 156, 85, - 154, 65, 227, 16, 235, 1, 57, 122, 199, 114, 157, 53, 60, 243, 67, 94, - 13, 190, 128, 21, 240, 27, 72, 88, 48, 1, 26, 246, 140, 97, 175, 148, - 123, 186, 44, 170, 130, 164, 77, 197, 166, 196, 89, 119, 147, 255, 110, 2, - 28, 238, 44, 90, 124, 16, 19, 69, 1, 51, 169, 102, 22, 121, 181, 156, - 204, 211, 238, 145, 194, 183, 171, 229, 173, 139, 214, 177, 98, 63, 27, 200, - 93, 46, 56, 227, 32, 1, 157, 45, 166, 13, 140, 199, 101, 81, 168, 219, - 9, 216, 176, 195, 156, 38, 72, 224, 170, 207, 78, 121, 171, 103, 209, 197, - 22, 155, 63, 5, 9, 161, 64, 87, 202, 121, 189, 132, 255, 8, 204, 46, - 61, 83, 31, 172, 220, 183, 131, 81, 72, 20, 42, 202, 46, 151, 210, 135, - 115, 6, 167, 8, 68, 1, 86, 100, 198, 32, 77, 146, 192, 87, 210, 251, - 181, 99, 47, 137, 178, 34, 121, 223, 66, 22, 142, 219, 31, 86, 109, 180, - 97, 27, 50, 136, 48, 113, 246, 134, 125, 11, 36, 255, 41, 154, 212, 82, - 70, 239, 137, 14, 175, 113, 80, 32, 121, 18, 190, 6, 42, 156, 84, 17, - 111, 38, 8, 213, 230, 42, 191, 208, 172, 74, 112, 202, 65, 95, 44, 182, - 67, 131, 254, 163, 95, 243, 114, 133, 48, 3, 134, 225, 1, 249, 19, 58, - 41, 105, 54, 91, 24, 154, 16, 217, 122, 148, 180, 30, 53, 221, 118, 196, - 1, 250, 185, 40, 29, 222, 166, 132, 37, 119, 4, 141, 171, 107, 110, 145, - 75, 180, 254, 136, 45, 149, 169, 160, 59, 84, 221, 229, 111, 158, 203, 131, - 38, 233, 149, 224, 141, 92, 199, 254, 50, 5, 247, 204, 113, 211, 33, 176, - 118, 147, 214, 166, 165, 78, 235, 107, 194, 221, 130, 110, 229, 25, 14, 76, - 178, 106, 201, 43, 57, 93, 221, 205, 215, 252, 56, 95, 182, 110, 176, 255, - 125, 88, 143, 146, 51, 69, 103, 170, 3, 216, 251, 233, 133, 152, 198, 232, - 228, 106, 20, 60, 57, 185, 173, 219, 79, 246, 184, 25, 113, 98, 181, 169, - 146, 65, 183, 240, 230, 246, 66, 144, 84, 55, 248, 206, 79, 45, 242, 28, - 54, 106, 28, 80, 103, 15, 188, 55, 62, 92, 255, 68, 26, 52, 21, 182, - 90, 156, 37, 201, 177, 19, 98, 237, 114, 135, 170, 186, 73, 225, 51, 12, - 93, 15, 203, 248, 155, 4, 231, 112, 238, 36, 125, 95, 241, 144, 9, 232, - 247, 81, 39, 5, 211, 32, 146, 182, 84, 152, 226, 59, 198, 122, 143, 233, - 250, 54, 170, 114, 1, 131, 184, 157, 191, 240, 109, 76, 52, 50, 9, 135, - 64, 180, 192, 66, 86, 20, 9, 117, 14, 136, 158, 53, 116, 6, 110, 254, - 128, 85, 191, 16, 196, 66, 220, 157, 90, 129, 109, 218, 212, 70, 149, 200, - 126, 145, 208, 245, 168, 179, 119, 107, 222, 48, 6, 81, 143, 192, 96, 164, - 140, 225, 153, 219, 82, 242, 75, 127, 24, 173, 112, 233, 223, 228, 193, 66, - 234, 207, 108, 54, 137, 62, 224, 248, 107, 11, 252, 40, 113, 162, 35, 29, - 117, 169, 23, 71, 76, 21, 171, 55, 175, 188, 105, 154, 195, 153, 75, 62, - 201, 68, 189, 231, 3, 197, 61, 87, 29, 71, 174, 191, 184, 171, 54, 112, - 147, 223, 82, 24, 34, 234, 111, 246, 165, 22, 125, 151, 216, 206, 235, 117, - 237, 23, 164, 244, 134, 246, 223, 154, 190, 35, 72, 118, 171, 18, 57, 210, - 154, 210, 17, 193, 2, 34, 29, 100, 161, 59, 187, 102, 91, 237, 47, 139, - 25, 1, 224, 130, 198, 88, 36, 50, 238, 56, 165, 139, 2, 159, 112, 226, - 207, 124, 170, 91, 226, 149, 45, 198, 197, 138, 216, 189, 241, 113, 96, 3, - 114, 196, 58, 164, 40, 178, 39, 250, 23, 42, 140, 145, 155, 44, 119, 130, - 254, 79, 22, 94, 65, 241, 28, 175, 9, 69, 179, 42, 126, 76, 88, 27, - 219, 36, 62, 241, 92, 165, 154, 45, 136, 60, 88, 37, 5, 169, 48, 177, - 209, 163, 227, 12, 203, 33, 237, 130, 102, 168, 228, 254, 122, 108, 67, 250, - 235, 159, 80, 37, 147, 78, 184, 230, 169, 122, 21, 2, 106, 58, 128, 14, - 45, 162, 137, 185, 81, 156, 203, 238, 186, 125, 42, 12, 82, 214, 173, 80, - 69, 21, 128, 162, 230, 84, 138, 146, 52, 122, 174, 245, 119, 166, 67, 40, - 98, 138, 245, 32, 111, 252, 228, 220, 246, 126, 5, 45, 21, 77, 46, 56, - 212, 143, 33, 148, 70, 168, 127, 32, 238, 217, 186, 115, 98, 176, 181, 255, - 100, 82, 129, 5, 145, 15, 43, 197, 234, 18, 246, 96, 160, 168, 98, 202, - 14, 79, 199, 202, 116, 7, 193, 188, 160, 252, 163, 198, 244, 104, 30, 70, - 69, 149, 141, 206, 73, 159, 249, 29, 151, 25, 79, 48, 46, 133, 199, 240, - 254, 206, 163, 94, 64, 244, 200, 210, 149, 112, 140, 205, 87, 134, 245, 31, - 248, 97, 89, 235, 191, 2, 98, 107, 170, 51, 239, 134, 145, 233, 108, 119, - 254, 217, 235, 2, 6, 216, 35, 193, 99, 187, 209, 152, 145, 59, 8, 213, - 116, 54, 148, 164, 66, 16, 17, 191, 209, 52, 153, 93, 248, 201, 176, 82, - 180, 72, 93, 28, 11, 87, 133, 218, 7, 50, 100, 79, 71, 26, 232, 3, - 211, 178, 59, 193, 63, 239, 103, 116, 99, 123, 148, 203, 58, 255, 137, 221, - 127, 148, 137, 95, 251, 130, 53, 68, 214, 85, 240, 32, 224, 98, 59, 134, - 90, 119, 100, 60, 121, 175, 75, 218, 182, 94, 54, 113, 174, 180, 95, 15, - 20, 39, 100, 132, 139, 115, 9, 93, 66, 189, 224, 12, 181, 203, 152, 162, - 127, 224, 79, 64, 139, 22, 215, 175, 244, 219, 27, 129, 138, 200, 3, 17, - 181, 109, 205, 141, 9, 164, 70, 251, 73, 240, 87, 4, 94, 201, 17, 246, - 178, 230, 12, 49, 169, 140, 43, 70, 76, 195, 108, 165, 13, 104, 184, 226, - 245, 197, 1, 97, 160, 94, 205, 236, 82, 183, 150, 244, 209, 83, 62, 207, - 237, 45, 173, 136, 60, 215, 141, 183, 143, 150, 51, 219, 238, 16, 169, 39, - 175, 192, 109, 22, 222, 227, 19, 100, 66, 126, 181, 8, 233, 178, 157, 81, - 186, 40, 26, 243, 61, 105, 178, 3, 223, 194, 8, 143, 49, 24, 154, 213, - 125, 187, 3, 215, 165, 34, 107, 17, 70, 252, 60, 240, 68, 228, 220, 35, - 152, 30, 16, 204, 252, 56, 34, 66, 78, 103, 184, 87, 49, 254, 47, 177, - 58, 136, 96, 41, 191, 62, 106, 126, 32, 203, 47, 132, 229, 105, 130, 188, - 42, 212, 196, 88, 147, 202, 86, 53, 135, 239, 31, 181, 159, 129, 199, 121, - 229, 153, 88, 128, 147, 234, 175, 116, 166, 237, 8, 194, 233, 163, 220, 67, - 206, 231, 108, 93, 196, 83, 118, 120, 161, 119, 236, 97, 247, 57, 87, 198, - 223, 55, 77, 18, 4, 150, 242, 39, 2, 253, 82, 167, 215, 135, 207, 152, - 17, 161, 255, 97, 9, 134, 239, 165, 253, 30, 126, 110, 116, 193, 183, 144, - 89, 195, 48, 85, 95, 216, 111, 18, 41, 11, 144, 236, 83, 157, 194, 209, - 220, 160, 143, 90, 187, 77, 199, 216, 63, 242, 205, 155, 243, 148, 217, 48, - 234, 195, 12, 81, 172, 182, 31, 243, 90, 10, 60, 131, 255, 114, 227, 80, - 249, 139, 194, 145, 179, 113, 247, 130, 143, 187, 28, 106, 81, 213, 234, 161, - 252, 112, 47, 224, 52, 90, 129, 29, 35, 158, 110, 21, 199, 2, 107, 36, - 243, 134, 66, 23, 104, 70, 252, 157, 29, 184, 200, 36, 21, 48, 228, 156, - 102, 231, 124, 3, 28, 105, 120, 94, 168, 29, 122, 74, 225, 164, 180, 33, - 230, 150, 219, 38, 123, 217, 43, 181, 34, 235, 13, 215, 62, 172, 88, 251, - 72, 164, 97, 4, 69, 238, 119, 166, 91, 73, 180, 51, 248, 179, 110, 171, - 29, 15, 106, 122, 104, 151, 8, 176, 140, 14, 195, 25, 93, 111, 178, 76, - 23, 117, 108, 154, 236, 127, 101, 37, 75, 156, 202, 228, 88, 158, 5, 103, - 57, 11, 74, 97, 62, 41, 65, 132, 235, 206, 10, 216, 141, 1, 55, 152, - 55, 53, 192, 144, 184, 73, 201, 223, 64, 253, 121, 214, 49, 146, 249, 22, - 176, 61, 127, 1, 165, 192, 226, 217, 249, 149, 216, 50, 140, 78, 167, 102, - 155, 90, 139, 161, 162, 185, 117, 234, 44, 143, 49, 138, 31, 71, 93, 1, - 140, 36, 80, 96, 64, 22, 104, 158, 162, 129, 68, 160, 103, 70, 37, 6, - 150, 221, 49, 246, 124, 13, 50, 42, 213, 160, 103, 250, 54, 118, 136, 33, - 229, 179, 60, 43, 116, 246, 38, 135, 182, 124, 37, 75, 113, 207, 11, 136, - 149, 86, 44, 244, 1, 139, 160, 78, 22, 231, 39, 100, 171, 56, 200, 135, - 37, 170, 27, 91, 3, 173, 221, 96, 71, 48, 149, 95, 69, 180, 203, 18, - 203, 162, 1, 18, 48, 106, 251, 10, 182, 95, 142, 66, 120, 134, 65, 190, - 181, 38, 152, 220, 7, 34, 24, 49, 130, 13, 67, 85, 8, 115, 218, 191, - 16, 190, 243, 204, 201, 58, 73, 220, 103, 209, 239, 206, 101, 247, 118, 63, - 114, 11, 201, 189, 197, 71, 246, 84, 58, 81, 200, 156, 152, 211, 28, 187, - 237, 190, 129, 25, 151, 198, 178, 218, 32, 207, 120, 174, 1, 231, 65, 23, - 171, 193, 251, 58, 240, 19, 74, 44, 100, 91, 166, 225, 23, 172, 50, 210, - 218, 66, 185, 63, 206, 222, 92, 50, 115, 168, 184, 210, 165, 18, 219, 26, - 236, 124, 163, 210, 30, 107, 208, 229, 123, 64, 168, 225, 112, 39, 243, 125, - 254, 92, 235, 69, 59, 20, 222, 125, 240, 13, 17, 243, 19, 185, 45, 74, - 109, 52, 162, 146, 84, 213, 47, 80, 209, 1, 144, 64, 248, 89, 153, 111, - 13, 69, 173, 229, 83, 230, 24, 51, 110, 158, 11, 212, 129, 151, 78, 187, - 112, 44, 244, 214, 65, 188, 10, 221, 191, 229, 66, 173, 212, 164, 35, 146, - 170, 61, 5, 47, 233, 40, 242, 138, 71, 131, 16, 104, 53, 143, 241, 98, - 36, 131, 181, 226, 92, 128, 69, 46, 72, 183, 141, 95, 109, 9, 169, 218, - 192, 104, 241, 120, 183, 163, 198, 226, 1, 133, 20, 83, 189, 238, 15, 173, - 100, 207, 83, 144, 174, 20, 190, 51, 193, 99, 157, 90, 25, 75, 222, 160, - 173, 38, 208, 61, 231, 200, 139, 109, 108, 111, 68, 191, 91, 246, 6, 156, - 201, 74, 188, 214, 105, 131, 114, 14, 204, 147, 110, 180, 32, 138, 172, 222, - 65, 184, 217, 108, 159, 213, 128, 15, 56, 250, 131, 41, 114, 52, 21, 40, - 202, 63, 145, 7, 167, 106, 137, 47, 131, 42, 120, 98, 195, 107, 83, 177, - 222, 137, 185, 145, 15, 105, 219, 208, 46, 226, 197, 167, 79, 126, 146, 86, - 71, 247, 59, 167, 249, 234, 194, 165, 227, 126, 245, 163, 189, 28, 73, 83, - 157, 38, 71, 214, 24, 76, 137, 248, 167, 150, 110, 186, 25, 77, 36, 207, - 167, 61, 19, 150, 227, 94, 146, 136, 162, 253, 40, 78, 47, 224, 59, 197, - 126, 30, 136, 105, 37, 75, 171, 226, 135, 174, 27, 131, 138, 63, 123, 169, - 20, 10, 19, 125, 26, 182, 233, 208, 33, 253, 30, 73, 235, 11, 53, 72, - 34, 140, 17, 205, 142, 195, 171, 186, 170, 123, 75, 228, 97, 197, 156, 91, - 135, 225, 31, 171, 238, 245, 93, 59, 153, 86, 16, 32, 2, 136, 241, 128, - 253, 82, 113, 77, 123, 19, 192, 62, 251, 121, 155, 183, 22, 191, 8, 158, - 117, 102, 157, 1, 84, 57, 7, 120, 147, 223, 105, 6, 61, 144, 250, 153, - 197, 176, 30, 55, 151, 13, 124, 48, 43, 215, 199, 250, 93, 212, 51, 140, - 38, 215, 238, 2, 1, 128, 110, 241, 58, 9, 182, 218, 120, 89, 137, 244, - 210, 16, 188, 151, 9, 161, 154, 84, 86, 54, 213, 193, 215, 195, 225, 102, - 139, 229, 225, 86, 151, 250, 54, 170, 163, 92, 122, 210, 113, 185, 37, 207, - 246, 64, 145, 113, 50, 107, 248, 43, 27, 179, 194, 87, 238, 254, 12, 216, - 192, 77, 82, 101, 142, 27, 204, 127, 252, 56, 196, 216, 52, 55, 232, 20, - 225, 102, 188, 28, 172, 63, 81, 153, 55, 211, 30, 96, 212, 38, 202, 239, - 206, 5, 211, 85, 21, 221, 158, 188, 24, 196, 39, 55, 115, 197, 236, 33, - 82, 11, 239, 144, 85, 211, 64, 111, 237, 53, 123, 79, 112, 118, 252, 155, - 242, 119, 80, 185, 223, 205, 68, 34, 114, 142, 26, 240, 102, 192, 6, 155, - 206, 80, 103, 228, 157, 141, 187, 96, 241, 159, 179, 34, 5, 89, 4, 132, - 177, 244, 124, 41, 164, 132, 90, 62, 107, 166, 232, 199, 106, 117, 227, 194, - 237, 153, 26, 111, 10, 89, 35, 112, 208, 47, 86, 236, 46, 106, 245, 232, - 139, 170, 236, 220, 57, 109, 132, 169, 111, 208, 23, 76, 198, 179, 51, 117, - 84, 52, 116, 182, 154, 127, 177, 243, 24, 161, 199, 114, 227, 27, 176, 186, - 180, 231, 154, 118, 255, 123, 159, 32, 237, 198, 190, 209, 110, 18, 161, 20, - 89, 34, 179, 223, 74, 95, 19, 232, 68, 170, 129, 247, 91, 54, 142, 29, - 63, 251, 211, 24, 73, 133, 85, 151, 127, 8, 60, 250, 4, 255, 67, 23, - 137, 177, 85, 31, 216, 198, 99, 172, 57, 124, 81, 15, 60, 152, 242, 211, - 101, 81, 240, 158, 195, 112, 189, 6, 133, 154, 40, 77, 212, 44, 56, 187, - 218, 72, 191, 141, 149, 189, 235, 196, 20, 182, 249, 9, 42, 172, 84, 1, - 148, 124, 4, 99, 1, 72, 248, 190, 91, 184, 115, 138, 19, 147, 87, 234, - 7, 232, 36, 29, 234, 92, 59, 141, 130, 57, 75, 229, 247, 108, 88, 156, - 202, 133, 230, 112, 88, 54, 70, 10, 96, 253, 31, 52, 149, 86, 4, 208, - 221, 249, 194, 14, 113, 148, 33, 107, 116, 3, 147, 61, 125, 204, 102, 159, - 44, 175, 188, 131, 15, 231, 103, 117, 177, 156, 233, 214, 158, 217, 237, 171, - 56, 122, 12, 221, 14, 77, 247, 24, 101, 113, 219, 230, 118, 189, 239, 204, - 3, 4, 46, 75, 159, 68, 251, 128, 25, 190, 95, 223, 71, 91, 31, 242, - 203, 6, 38, 174, 54, 121, 23, 176, 99, 57, 211, 166, 25, 183, 221, 67, - 205, 45, 74, 50, 207, 222, 85, 18, 210, 53, 41, 166, 39, 78, 118, 176, - 109, 173, 223, 148, 26, 67, 6, 217, 99, 175, 90, 44, 56, 117, 193, 142, - 40, 53, 168, 13, 174, 192, 41, 232, 1, 164, 101, 65, 146, 241, 213, 132, - 121, 28, 97, 143, 7, 169, 134, 57, 98, 196, 27, 225, 175, 72, 190, 220, - 101, 198, 87, 232, 50, 204, 36, 254, 33, 105, 84, 115, 35, 22, 92, 109, - 248, 149, 170, 41, 51, 227, 117, 43, 167, 25, 78, 202, 165, 46, 104, 76, - 135, 174, 224, 205, 17, 35, 230, 186, 2, 245, 121, 55, 142, 171, 12, 155, - 119, 61, 96, 226, 255, 210, 133, 80, 76, 115, 146, 144, 147, 200, 132, 125, - 92, 21, 185, 233, 157, 125, 226, 1, 14, 155, 231, 247, 5, 89, 224, 242, - 76, 204, 249, 133, 45, 168, 101, 201, 10, 255, 135, 214, 43, 1, 196, 74, - 26, 94, 222, 68, 201, 130, 99, 212, 150, 142, 35, 121, 114, 228, 67, 62, - 161, 153, 42, 49, 224, 208, 177, 253, 65, 180, 178, 46, 242, 45, 233, 16, - 154, 72, 122, 7, 29, 189, 219, 172, 186, 166, 14, 79, 200, 118, 183, 134, - 232, 128, 147, 178, 153, 173, 198, 96, 84, 219, 47, 228, 69, 244, 52, 1, - 143, 209, 29, 188, 104, 49, 31, 238, 106, 75, 169, 28, 197, 233, 178, 124, - 11, 245, 120, 213, 166, 160, 71, 203, 59, 89, 75, 152, 38, 31, 247, 112, - 83, 108, 197, 121, 67, 153, 30, 217, 206, 82, 171, 216, 134, 245, 116, 192, - 122, 211, 87, 238, 52, 121, 149, 195, 36, 196, 15, 134, 82, 177, 7, 114, - 90, 43, 249, 51, 85, 227, 67, 248, 18, 255, 81, 174, 212, 142, 228, 253, - 2, 150, 179, 252, 12, 65, 240, 192, 239, 13, 117, 140, 180, 85, 131, 59, - 233, 60, 120, 255, 53, 13, 73, 221, 176, 148, 1, 67, 104, 136, 41, 7, - 67, 199, 242, 40, 102, 80, 51, 35, 162, 226, 54, 75, 182, 86, 160, 48, - 149, 7, 120, 77, 223, 180, 39, 13, 221, 56, 194, 15, 78, 64, 129, 36, - 84, 228, 19, 194, 22, 41, 10, 95, 126, 172, 250, 155, 135, 186, 82, 159, - 48, 176, 179, 254, 56, 186, 165, 81, 164, 236, 74, 2, 145, 91, 229, 151, - 245, 135, 173, 40, 34, 106, 3, 165, 229, 182, 125, 30, 244, 147, 45, 109, - 117, 72, 22, 225, 49, 151, 167, 26, 6, 220, 150, 86, 152, 186, 126, 164, - 238, 224, 100, 111, 200, 113, 82, 130, 211, 176, 71, 201, 156, 81, 28, 116, - 180, 99, 14, 224, 46, 196, 177, 96, 223, 106, 91, 117, 18, 59, 150, 195, - 50, 176, 17, 12, 137, 185, 8, 254, 6, 126, 204, 101, 115, 170, 135, 110, - 95, 30, 247, 55, 138, 243, 118, 203, 119, 184, 234, 248, 220, 27, 94, 158, - 85, 164, 97, 57, 104, 55, 121, 225, 46, 231, 202, 1, 117, 179, 50, 232, - 147, 139, 19, 49, 26, 195, 1, 253, 27, 143, 130, 33, 73, 112, 220, 8, - 152, 72, 66, 23, 93, 26, 243, 189, 91, 254, 172, 79, 202, 50, 167, 28, - 101, 200, 188, 2, 48, 136, 198, 108, 80, 187, 38, 115, 109, 57, 75, 197, - 66, 163, 49, 127, 44, 234, 61, 153, 90, 148, 27, 64, 165, 196, 243, 219, - 36, 134, 88, 71, 250, 94, 124, 151, 208, 28, 123, 228, 128, 149, 189, 194, - 103, 202, 142, 70, 118, 225, 210, 18, 14, 151, 180, 131, 203, 209, 231, 31, - 199, 111, 175, 205, 83, 150, 165, 69, 89, 145, 48, 141, 1, 242, 168, 91, - 153, 178, 42, 80, 222, 255, 131, 177, 29, 210, 102, 133, 195, 175, 5, 72, - 72, 177, 13, 228, 234, 123, 138, 92, 118, 252, 110, 54, 39, 31, 55, 196, - 6, 186, 62, 207, 74, 138, 227, 214, 155, 57, 209, 102, 68, 144, 212, 240, - 154, 217, 176, 132, 191, 123, 223, 11, 63, 237, 140, 208, 8, 23, 27, 82, - 91, 37, 30, 205, 161, 98, 20, 168, 245, 25, 188, 97, 45, 4, 237, 68, - 130, 173, 27, 207, 172, 141, 21, 235, 40, 184, 251, 54, 248, 76, 89, 211, - 155, 23, 127, 193, 201, 138, 152, 29, 60, 130, 224, 121, 88, 129, 157, 41, - 8, 159, 219, 208, 14, 66, 137, 110, 32, 152, 172, 239, 229, 47, 252, 192, - 238, 94, 129, 168, 167, 244, 137, 227, 149, 215, 140, 18, 44, 77, 171, 132, - 226, 113, 133, 181, 45, 129, 148, 80, 71, 57, 201, 88, 65, 24, 89, 167, - 117, 160, 58, 86, 44, 178, 98, 210, 242, 136, 14, 181, 60, 255, 184, 200, - 251, 118, 50, 185, 157, 135, 163, 213, 137, 42, 165, 93, 12, 60, 69, 128, - 110, 118, 213, 244, 70, 14, 39, 22, 154, 72, 232, 9, 50, 207, 247, 171, - 90, 110, 32, 170, 229, 57, 61, 107, 64, 97, 153, 45, 113, 167, 35, 205, - 55, 250, 15, 100, 177, 211, 163, 98, 150, 229, 187, 82, 194, 243, 63, 66, - 21, 82, 114, 76, 63, 126, 255, 154, 185, 250, 108, 144, 176, 9, 87, 146, - 9, 254, 134, 101, 67, 87, 150, 107, 204, 240, 162, 34, 86, 17, 14, 211, - 53, 36, 76, 198, 59, 29, 221, 84, 162, 40, 247, 211, 185, 213, 15, 208, - 236, 31, 9, 216, 157, 215, 19, 96, 104, 222, 43, 83, 150, 85, 78, 27, - 170, 24, 139, 106, 102, 254, 10, 120, 107, 158, 45, 113, 41, 153, 89, 218, - 169, 34, 184, 55, 251, 105, 126, 183, 167, 194, 135, 221, 92, 147, 109, 215, - 33, 162, 213, 17, 25, 118, 164, 69, 203, 138, 114, 220, 78, 100, 62, 146, - 44, 73, 192, 215, 124, 34, 79, 83, 106, 26, 200, 164, 181, 172, 111, 217, - 98, 38, 254, 226, 19, 189, 162, 224, 6, 122, 59, 86, 207, 134, 22, 222, - 73, 15, 113, 197, 123, 205, 51, 188, 81, 251, 69, 60, 191, 62, 98, 234, - 25, 90, 210, 7, 103, 172, 241, 182, 189, 131, 107, 3, 240, 244, 144, 160, - 48, 73, 198, 139, 53, 77, 5, 120, 169, 126, 21, 145, 17, 194, 99, 4, - 68, 159, 233, 84, 65, 194, 236, 37, 216, 54, 25, 196, 195, 28, 172, 189, - 208, 155, 233, 8, 57, 172, 218, 228, 106, 189, 38, 86, 190, 229, 78, 36, - 143, 145, 230, 11, 140, 185, 42, 214, 22, 161, 238, 253, 231, 222, 81, 241, - 94, 236, 166, 143, 252, 9, 61, 230, 245, 22, 72, 11, 13, 233, 125, 28, - 173, 43, 113, 187, 34, 195, 92, 235, 217, 206, 46, 71, 128, 53, 112, 80, - 36, 54, 221, 189, 8, 212, 39, 25, 114, 181, 7, 109, 246, 208, 147, 122, - 150, 170, 101, 243, 207, 231, 12, 100, 157, 21, 119, 235, 63, 44, 99, 120, - 248, 192, 163, 100, 232, 166, 130, 193, 237, 56, 70, 197, 226, 103, 162, 113, - 3, 193, 47, 221, 92, 180, 52, 7, 252, 231, 14, 181, 129, 98, 240, 250, - 21, 141, 79, 88, 95, 198, 159, 144, 253, 33, 19, 122, 133, 115, 7, 31, - 122, 66, 204, 252, 199, 244, 8, 159, 6, 72, 191, 95, 133, 26, 188, 3, - 7, 113, 78, 184, 123, 168, 3, 222, 148, 16, 255, 175, 171, 235, 46, 213, - 227, 62, 251, 103, 139, 225, 1, 54, 153, 85, 16, 73, 177, 44, 123, 105, - 206, 145, 64, 66, 157, 43, 182, 161, 23, 158, 128, 130, 58, 218, 3, 198, - 38, 215, 212, 105, 219, 96, 42, 70, 168, 104, 233, 23, 10, 251, 43, 64, - 16, 190, 51, 148, 127, 221, 1, 239, 233, 101, 41, 140, 32, 146, 161, 13, - 199, 242, 207, 29, 206, 162, 70, 1, 245, 239, 211, 31, 146, 222, 166, 4, - 84, 204, 16, 214, 128, 1, 227, 54, 222, 121, 76, 250, 1, 231, 246, 104, - 112, 225, 16, 23, 20, 80, 137, 154, 186, 144, 158, 166, 169, 5, 182, 212, - 165, 216, 136, 90, 227, 95, 122, 179, 97, 39, 238, 132, 246, 4, 53, 76, - 117, 198, 23, 74, 164, 244, 68, 200, 179, 215, 60, 101, 93, 174, 17, 11, - 163, 223, 138, 184, 236, 65, 253, 196, 63, 83, 224, 76, 243, 143, 45, 56, - 242, 200, 61, 175, 47, 155, 97, 6, 50, 156, 250, 115, 149, 114, 194, 95, - 203, 228, 107, 37, 18, 131, 69, 39, 253, 142, 187, 12, 81, 111, 241, 124, - 5, 160, 130, 110, 61, 244, 99, 95, 125, 55, 97, 74, 59, 71, 177, 96, - 181, 74, 158, 254, 145, 210, 137, 80, 206, 226, 3, 99, 142, 46, 199, 93, - 92, 52, 34, 201, 165, 236, 243, 85, 108, 247, 210, 12, 65, 109, 254, 131, - 107, 25, 45, 253, 59, 33, 65, 104, 27, 49, 223, 189, 109, 20, 156, 149, - 216, 190, 5, 156, 3, 181, 90, 130, 245, 25, 201, 228, 72, 183, 57, 232, - 47, 27, 108, 16, 68, 141, 24, 49, 100, 6, 192, 226, 106, 93, 124, 209, - 75, 9, 154, 32, 142, 239, 173, 191, 69, 136, 202, 68, 174, 66, 102, 178, - 129, 250, 220, 24, 55, 185, 151, 249, 61, 208, 88, 20, 133, 64, 67, 204, - 175, 56, 83, 78, 35, 230, 156, 214, 15, 171, 87, 148, 247, 122, 46, 205, - 41, 53, 173, 138, 107, 42, 241, 193, 187, 160, 164, 26, 69, 123, 151, 11, - 190, 242, 155, 216, 183, 102, 58, 202, 63, 206, 37, 74, 47, 87, 56, 237, - 56, 140, 214, 195, 32, 154, 241, 196, 197, 119, 91, 74, 120, 208, 87, 139, - 167, 88, 33, 135, 99, 115, 42, 213, 37, 127, 148, 133, 160, 218, 142, 241, - 119, 239, 90, 249, 110, 1, 127, 219, 252, 201, 170, 35, 20, 183, 165, 146, - 187, 128, 94, 132, 125, 205, 20, 249, 11, 34, 222, 183, 140, 17, 232, 218, - 76, 118, 84, 168, 199, 97, 89, 175, 128, 171, 80, 217, 153, 38, 231, 219, - 36, 121, 173, 215, 21, 100, 133, 178, 182, 144, 204, 39, 112, 32, 234, 134, - 103, 230, 29, 119, 17, 73, 177, 139, 136, 43, 87, 60, 191, 162, 209, 58, - 135, 79, 126, 175, 217, 116, 38, 1, 227, 115, 19, 93, 198, 29, 101, 160, - 24, 37, 133, 10, 141, 183, 57, 5, 218, 206, 30, 159, 81, 158, 221, 248, - 191, 79, 131, 12, 4, 136, 51, 61, 236, 116, 84, 70, 96, 125, 202, 140, - 96, 26, 230, 4, 103, 70, 118, 28, 193, 136, 53, 125, 12, 217, 116, 92, - 204, 58, 106, 122, 146, 62, 230, 5, 93, 203, 141, 77, 137, 161, 46, 188, - 8, 230, 59, 90, 188, 94, 213, 54, 137, 206, 46, 35, 159, 25, 71, 223, - 219, 203, 40, 155, 79, 241, 179, 127, 143, 13, 58, 119, 111, 235, 184, 210, - 67, 40, 124, 96, 32, 120, 56, 175, 203, 6, 114, 132, 35, 63, 149, 23, - 121, 193, 98, 9, 70, 219, 2, 156, 125, 48, 50, 86, 103, 55, 246, 132, - 212, 85, 89, 174, 220, 19, 186, 92, 62, 249, 114, 38, 169, 134, 191, 205, - 155, 20, 45, 163, 211, 161, 121, 109, 212, 10, 166, 170, 210, 2, 186, 231, - 187, 78, 169, 111, 91, 241, 40, 185, 174, 105, 13, 48, 33, 79, 52, 180, - 163, 255, 135, 190, 184, 111, 1, 78, 180, 4, 169, 209, 14, 124, 52, 18, - 108, 176, 75, 247, 252, 235, 1, 170, 174, 123, 29, 246, 115, 225, 42, 205, - 73, 9, 19, 229, 238, 145, 192, 105, 76, 34, 246, 88, 243, 64, 44, 66, - 5, 170, 129, 24, 157, 10, 236, 52, 223, 101, 225, 48, 220, 15, 134, 235, - 129, 49, 24, 192, 249, 30, 142, 111, 234, 240, 187, 105, 127, 215, 84, 77, - 251, 64, 99, 190, 234, 43, 117, 108, 1, 188, 161, 36, 21, 42, 116, 71, - 58, 100, 193, 97, 151, 240, 41, 196, 204, 147, 50, 107, 18, 102, 157, 230, - 220, 144, 115, 37, 61, 216, 207, 139, 233, 32, 214, 88, 148, 242, 173, 142, - 225, 41, 223, 28, 248, 86, 199, 166, 159, 22, 37, 238, 193, 224, 79, 98, - 33, 158, 10, 191, 65, 143, 47, 179, 218, 110, 95, 49, 2, 180, 141, 112, - 53, 77, 103, 149, 224, 1, 62, 30, 147, 20, 201, 232, 131, 168, 91, 16, - 217, 51, 212, 146, 255, 202, 143, 178, 248, 18, 182, 152, 83, 75, 102, 125, - 232, 68, 245, 44, 51, 163, 43, 200, 218, 197, 174, 4, 31, 226, 168, 178, - 146, 207, 237, 77, 145, 68, 167, 247, 144, 93, 105, 239, 240, 2, 112, 58, - 81, 214, 253, 237, 246, 182, 24, 67, 132, 35, 249, 26, 171, 65, 52, 40, - 248, 199, 154, 21, 176, 151, 237, 2, 74, 235, 156, 190, 99, 30, 229, 200, - 152, 16, 87, 60, 127, 126, 35, 214, 109, 51, 227, 117, 158, 85, 246, 237, - 116, 132, 224, 201, 105, 22, 119, 154, 156, 234, 183, 11, 63, 92, 164, 251, - 226, 124, 183, 138, 161, 141, 33, 94, 169, 104, 190, 209, 202, 114, 17, 116, - 195, 242, 112, 185, 89, 216, 108, 47, 77, 62, 94, 174, 166, 249, 197, 186, - 209, 147, 171, 82, 181, 119, 239, 83, 75, 139, 10, 152, 39, 15, 179, 157 -}; - -private const pcl_ht_builtin_threshold_t ordered_dither_thresh = { - 1, /* all planes the same */ - 16, 16, /* 16 x 16 pixels */ - ordered_dither_data -}; - -private const pcl_ht_builtin_threshold_t clustered_dither_thresh = { - 1, /* all planes the same */ - 16, 16, /* 16 x 16 pixels */ - clustered_dither_data -}; - -private const pcl_ht_builtin_threshold_t noise_dither_thresh = { - 1, /* all planes the same */ - 128, 128, /* 128 x 128 pixels */ - noise_dither_data -}; - -private const byte rendering_remap_proto[20] = { - 0, 1, 2, 3, /* 0 - 3 */ - 3, 5, 5, 7, /* 4 - 7 */ - 8, 9, 10, 11, /* 8 - 11 */ - 12, 13, 14, 3, /* 12 - 15 */ - 5, 5, 3, 5 /* 16 - 19 */ -}; - -/* - * Update built-in rendering information. Attempts to changed fixed rendering - * infomration are ignored. - */ - private void -pcl_ht_update_rendering_info( - pcl_state_t * pcs, - int method, - const pcl_ht_builtin_dither_t * pbidither -) -{ - if ( (method > 0) && - (method < countof(pcs->rendering_info)) && - ((pcs->rendering_info[method].flags & HT_FIXED) == 0) && - (pbidither->type >= pcl_halftone_Threshold) && - (pbidither->type < pcl_halftone_num) ) - pcs->rendering_info[method].pbidither = pbidither; -} - -/* - * Read dither information from a parameter dictionary held by the device. - */ - private void -read_dither( - pcl_state_t * pcs, - int method, - gs_param_list * plist, - gs_memory_t * pmem -) -{ - pcl_ht_builtin_dither_t * pdt = 0; - int itype; - int height, width; - int nplanes = 1, nlevels = 1; - uint req_size = 0; - gs_param_string dstring; - - /* gather the common parameters */ - if ( (param_read_int(plist, "Type", &itype) != 0) || - (param_read_int(plist, "NumPlanes", &nplanes) < 0) || - (param_read_int(plist, "Height", &height) != 0) || - (param_read_int(plist, "Width", &width) != 0) || - (param_read_string(plist, "Data", &dstring) != 0) ) - return; - - /* check for a recognized type, and number of levels for table dither */ - if (itype == pcl_halftone_Threshold) - req_size = width * height; - else if ( (itype == pcl_halftone_Table_Dither) && - (param_read_int(plist, "NumLevels", &nlevels) == 0) ) - req_size = ((width + 7) / 8) * height; - else - return; - - /* check that the data is large enough; copy it if necessary */ - req_size *= nplanes * nlevels; - if (dstring.size < req_size) - return; - - pdt = gs_alloc_struct( pmem, - pcl_ht_builtin_dither_t, - &st_ht_builtin_dither_t, - "read device dither" - ); - if (pdt == 0) - return; - - if (!dstring.persistent) { - byte * pdata = gs_alloc_bytes(pmem, req_size, "read device dither"); - - if (pdata == 0) { - gs_free_object(pmem, pdt, "read device dither"); - return; - } - memcpy(pdata, dstring.data, req_size); - dstring.data = pdata; - dstring.persistent = true; - } - - /* update rendering information */ - pdt->type = (pcl_halftone_type_t)itype; - if (itype == pcl_halftone_Threshold) { - pdt->u.thresh.nplanes = nplanes; - pdt->u.thresh.height = height; - pdt->u.thresh.width = width; - pdt->u.thresh.pdata = dstring.data; - } else { - pdt->u.tdither.nplanes = nplanes; - pdt->u.tdither.height = height; - pdt->u.tdither.width = width; - pdt->u.tdither.nlevels = nlevels; - pdt->u.tdither.pdata = dstring.data; - } - pcl_ht_update_rendering_info(pcs, method, pdt); -} - -/* - * Modify the rendering remap table. Note that the change will not take - * effect until the next time the print mode is reset. - */ - private void -pcl_ht_update_rendering_remap( - pcl_state_t * pcs, - const byte * map -) -{ - memcpy(pcs->dflt_rendering_remap, map, sizeof(pcs->dflt_rendering_remap)); -} - -/* - * Read a re-mapping array for rendering methods. - */ - private void -read_remap_array( - pcl_state_t *pcs, - gs_param_list * plist, - gs_memory_t * pmem -) -{ - gs_param_string dstring; - int i; - - if ( (param_read_string(plist, "RenderRemap", &dstring) != 0) || - (dstring.size < countof(pcs->dflt_rendering_remap)) ) - return; - for (i = 0; i < countof(pcs->dflt_rendering_remap); i++) { - if (dstring.data[i] >= countof(pcs->dflt_rendering_remap)) - return; - } - pcl_ht_update_rendering_remap(pcs, dstring.data); -} - -/* - * Initialize the default rendering information. - */ - void -pcl_ht_init_render_methods( - pcl_state_t * pcs, - gs_memory_t * pmem -) -{ - int i; - gx_device * pcur_dev = gs_currentdevice(pcs->pgs); - gs_c_param_list list; - - pcs->ordered_dither.type = pcl_halftone_Threshold; - pcs->ordered_dither.u.thresh = ordered_dither_thresh; - pcs->clustered_dither.type = pcl_halftone_Threshold; - pcs->clustered_dither.u.thresh = clustered_dither_thresh; - pcs->noise_dither.type = pcl_halftone_Threshold; - pcs->noise_dither.u.thresh = noise_dither_thresh; - - /* 0 */ - pcs->rendering_info[0].flags = HT_NONE; - pcs->rendering_info[0].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[0].pbidither = &pcs->ordered_dither; - - /* 1 - dither doesn't matter */ - pcs->rendering_info[1].flags = HT_FIXED | HT_DEVCSPACE; - pcs->rendering_info[1].pdev = &pcs->cmap_device_snap_to_primaries; - pcs->rendering_info[1].pbidither = &pcs->ordered_dither; - - /* 2 - dither doesn't matter */ - pcs->rendering_info[2].flags = HT_FIXED | HT_DEVCSPACE; - pcs->rendering_info[2].pdev = &pcs->cmap_device_color_to_black_over_white; - pcs->rendering_info[2].pbidither = &pcs->ordered_dither; - - /* 3 - the default */ - pcs->rendering_info[3].flags = HT_NONE; - pcs->rendering_info[3].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[3].pbidither = &pcs->ordered_dither; - - /* 4 - currently not supported */ - pcs->rendering_info[4].flags = HT_FIXED | HT_IMONLY; - pcs->rendering_info[4].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[4].pbidither = 0; - - /* 5 - monochrome version of 3 */ - pcs->rendering_info[5].flags = HT_NONE; - pcs->rendering_info[5].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[5].pbidither = &pcs->ordered_dither; - - /* 6 - currently not supported */ - pcs->rendering_info[6].flags = HT_FIXED | HT_IMONLY; - pcs->rendering_info[6].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[6].pbidither = 0; - - /* 7 */ - pcs->rendering_info[7].flags = HT_FIXED; - pcs->rendering_info[7].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[7].pbidither = &pcs->clustered_dither; - - /* 8 */ - pcs->rendering_info[8].flags = HT_FIXED; - pcs->rendering_info[8].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[8].pbidither = &pcs->clustered_dither; - - /* 9 - dither comes from user */ - pcs->rendering_info[9].flags = HT_FIXED | HT_USERDEF | HT_DEVCSPACE; - pcs->rendering_info[9].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[9].pbidither = 0; - - pcs->rendering_info[10].flags = HT_FIXED | HT_USERDEF | HT_DEVCSPACE; - pcs->rendering_info[10].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[10].pbidither = 0; - - /* 11 */ - pcs->rendering_info[11].flags = HT_FIXED | HT_USERDEF | HT_DEVCSPACE; - pcs->rendering_info[11].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[11].pbidither = &pcs->ordered_dither; - - /* 12 */ - pcs->rendering_info[12].flags = HT_FIXED; - pcs->rendering_info[12].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[12].pbidither = &pcs->ordered_dither; - - /* 13 - device should override */ - pcs->rendering_info[13].flags = HT_NONE; - pcs->rendering_info[13].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[13].pbidither = &pcs->noise_dither; - - /* 14 - device should override */ - pcs->rendering_info[14].flags = HT_NONE; - pcs->rendering_info[14].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[14].pbidither = &pcs->noise_dither; - - /* 15 - device should override */ - pcs->rendering_info[15].flags = HT_NONE; - pcs->rendering_info[15].pdev = &pcs->cmap_device_identity; - pcs->rendering_info[15].pbidither = &pcs->ordered_dither; - - /* 16 - device should override */ - pcs->rendering_info[16].flags = HT_NONE; - pcs->rendering_info[16].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[16].pbidither = &pcs->ordered_dither; - - /* 17 - device should override */ - pcs->rendering_info[17].flags = HT_NONE; - pcs->rendering_info[17].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[17].pbidither = &pcs->ordered_dither; - - /* 18 - device should override */ - pcs->rendering_info[18].flags = HT_NONE; - pcs->rendering_info[18].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[18].pbidither = &pcs->ordered_dither; - - /* 19 - device should override */ - pcs->rendering_info[19].flags = HT_NONE; - pcs->rendering_info[19].pdev = &pcs->cmap_device_monochrome; - pcs->rendering_info[19].pbidither = &pcs->ordered_dither; - - { - /* - * Remap the the rendering methods. This will generally be - * selected from the device; the default value provided below - * maps all methods to ones that are supported in the default - * system. - */ - private const byte rendering_remap[20] = { - 0, 1, 2, 3, /* 0 - 3 */ - 3, 5, 5, 7, /* 4 - 7 */ - 8, 9, 10, 11, /* 8 - 11 */ - 12, 13, 14, 3, /* 12 - 15 */ - 5, 5, 3, 5 /* 16 - 19 */ - }; - for ( i = 0; i < countof(rendering_remap); i++ ) - pcs->dflt_rendering_remap[i] = - pcs->rendering_remap[i] = rendering_remap[i]; - } - - /* get any dither information from the current device */ - for (i = 0; i < countof(pcs->rendering_info); i++) { - char nbuff[12]; - - if ((pcs->rendering_info[i].flags & HT_FIXED) != 0) - continue; - gs_c_param_list_write(&list, pmem); - sprintf(nbuff, "Dither_%d", i); - if ( (param_request((gs_param_list *)&list, nbuff) >= 0) && - (gs_getdeviceparams(pcur_dev, (gs_param_list *)&list) >= 0) ) { - gs_param_dict dict; - - gs_c_param_list_read(&list); - if ( param_begin_read_dict( (gs_param_list *)&list, - nbuff, - &dict, - false - ) == 0 ) - read_dither(pcs, i, dict.list, pmem); - param_end_read_dict((gs_param_list *)&list, nbuff, &dict); - } - - gs_c_param_list_release(&list); - } - gs_c_param_list_release(&list); - - /* read in a new remapping array (if any) */ - gs_c_param_list_write(&list, pmem); - if ( (param_request((gs_param_list *)&list, "RenderRemap") >= 0) && - (gs_getdeviceparams(pcur_dev, (gs_param_list *)&list) >= 0) ) { - gs_c_param_list_read(&list); - read_remap_array(pcs, (gs_param_list *)&list, pmem); - } - gs_c_param_list_release(&list); - - /* initialize the color mapping mapping devices; install the default */ - gdev_cmap_init(&pcs->cmap_device_identity, pcur_dev, device_cmap_identity); - gx_device_retain((gx_device *)&pcs->cmap_device_identity, true); - - gdev_cmap_init( &pcs->cmap_device_snap_to_primaries, - pcur_dev, - device_cmap_snap_to_primaries - ); - gx_device_retain((gx_device *)&pcs->cmap_device_snap_to_primaries, true); - - gdev_cmap_init( &pcs->cmap_device_color_to_black_over_white, - pcur_dev, - device_cmap_color_to_black_over_white - ); - gx_device_retain((gx_device *)&pcs->cmap_device_color_to_black_over_white, true); - - gdev_cmap_init(&pcs->cmap_device_monochrome, pcur_dev, device_cmap_monochrome); - gx_device_retain((gx_device *)&pcs->cmap_device_monochrome, true); - - gs_setdevice_no_init(pcs->pgs, (gx_device *)&pcs->cmap_device_identity); - /* initialize default halftone */ - pcs->pdflt_ht = 0; -} - - -/* - * Set up normal or monochrome print mode. The latter is accomplished by - * remapping each of the rendering algorithms to its monochrome equivalent. - * The handling of the snap-to-primaries rendering method (1) is almost - * certianly wrong, but it is the best that can be done with the current - * scheme. - * - * Note that the current rendering method must be set before this change - * will take effect. - */ - void -pcl_ht_set_print_mode( - pcl_state_t * pcs, - bool monochrome -) -{ - static const byte monochrome_remap[20] = { 5, 5, 2, 5, - 6, 5, 6, 8, - 8, 10, 10, 12, - 12, 14, 14, 17, - 16, 17, 19, 19 }; - - memcpy(pcs->rendering_remap, pcs->dflt_rendering_remap, sizeof(pcs->rendering_remap)); - if (monochrome) { - int i; - for (i = 0; i < countof(pcs->rendering_remap); i++) - pcs->rendering_remap[i] = monochrome_remap[pcs->rendering_remap[i]]; - } -} - - -/* - * Report if a rendering method is a monochrome method. The evaluation is made - * with considering the remapping array. - */ - private bool -is_monochrome( - pcl_state_t * pcs, - int method -) -{ - pcl_rend_info_t * pinfo = &pcs->rendering_info[method]; - - return pinfo->pdev == &pcs->cmap_device_monochrome; -} - - -/* - * Free the graphic library halftone objects associated with a PCL halftone - * object. - * - * Note that freeing of the halftone strings is legitimate, as graphic library - * halftones are never shared among PCL halftone objects. - */ - private void -free_gs_hts( - pcl_ht_t * pht -) -{ - int i; - - if (pht->pfg_ht != 0) - gs_ht_release(pht->pfg_ht); - if (pht->pim_ht != 0) - gs_ht_release(pht->pim_ht); - pht->pfg_ht = 0; - pht->pim_ht = 0; - - for (i = 0; i < countof(pht->thresholds); i++) { - gs_string * pstr = &(pht->thresholds[i]); - - if (pstr->data != 0) - gs_free_string( pht->rc.memory, - pstr->data, - pstr->size, - "free_gs_hts" - ); - pstr->size = 0; - pstr->data = 0; - } -} - -/* - * Free a PCL halftone object. - * - * Note that the pointers in the three string constants are ignored by this - * code: all three refer to the same dither object, which is either statically - * allocated or also refered to by the pudither field. The string pointers - * exist only because they are required by the graphic library halftone - * structures. - */ - private void -free_pcl_ht( - gs_memory_t * pmem, - void * pvht, - client_name_t cname -) -{ - pcl_ht_t * pht = (pcl_ht_t *)pvht; - - if (pht->client_data[0].plktbl != 0) - rc_adjust(pht->client_data[0].plktbl, -3, cname); - pcl_udither_release(pht->pdither); - - /* free_gs_hts frees the string pointers */ - free_gs_hts(pht); - - gs_free_object(pmem, pvht, cname); -} - -/* - * Allocate a PCL halftone object. - * - * Note that this allocates only the PCL halftone object, not the associated - * graphic library halftone object. - * - * Returns 0 on success, < 0 in event of an error. - */ - private int -alloc_pcl_ht( - pcl_ht_t ** ppht, - gs_memory_t * pmem -) -{ - pcl_ht_t * pht = 0; - int i; - - rc_alloc_struct_1( pht, - pcl_ht_t, - &st_ht_t, - pmem, - return e_Memory, - "allocate pcl halftone object" - ); - pht->rc.free = free_pcl_ht; - - pht->pdither = 0; - pht->render_method = 3; /* HP specified default value */ - pht->pfg_ht = 0; - pht->pim_ht = 0; - - for (i = 0; i < 3; i++) { - pht->client_data[i].comp_indx = i; - pht->client_data[i].inv_gamma = 1.0; - pht->client_data[i].plktbl = 0; - - /* don't need the threshold string pointers yet */ - pht->thresholds[i].data = 0; - pht->thresholds[i].size = 0; - } - - *ppht = pht; - return 0; -} - - -/* - * Make a unique copy of a PCL halftone object. - * - * Because the graphic library does not provide a "make unique" feature for - * the its halftone objects, it is necessary to keep the PCL halftone object - * and the associated graphic library halftone object in a one-to-one - * relationship. Hence, two of PCL objects will never share a grahpic library - * halftone object, and so the "unshared" PCL halftone object will always - * start without any associated graphic library halftone objects. - * - * To simplify the other code in this module, "unshared" halftones are always - * given new identifiers, even if the unshare operation itself does not - * change anything. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -unshare_pcl_ht( - pcl_ht_t ** ppht -) -{ - pcl_ht_t * pht = *ppht; - pcl_ht_t * pnew = 0; - int code = 0; - int i; - - /* check if there is anything to do */ - if (pht->rc.ref_count == 1) { - free_gs_hts(pht); - return 0; - } - rc_decrement(pht, "unshare pcl halftone object"); - - if ((code = alloc_pcl_ht(ppht, pht->rc.memory)) < 0) - return code; - pnew = *ppht; - - if (pht->pdither != 0) - pcl_udither_init_from(pnew->pdither, pht->pdither); - pnew->render_method = pht->render_method; - - for (i = 0; i < 3; i++) { - pnew->client_data[i].comp_indx = pht->client_data[i].comp_indx; - pnew->client_data[i].inv_gamma = pht->client_data[i].inv_gamma; - if (pht->client_data[i].plktbl != 0) - pcl_lookup_tbl_copy_from( pnew->client_data[i].plktbl, - pht->client_data[i].plktbl - ); - } - - /* all other fields are left "null" until needed */ - - return 0; -} - -/* - * Set the render method. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_set_render_method( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - uint render_method -) -{ - int code = 0; - - if (render_method >= countof(pcs->rendering_info)) - return 0; - - render_method = pcs->rendering_remap[render_method]; - if (render_method == (*ppht)->render_method) - return 0; - if ((code = unshare_pcl_ht(ppht)) < 0) - return code; - (*ppht)->render_method = render_method; - return 0; -} - -/* - * Update the gamma parameter. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_set_gamma( - pcl_ht_t ** ppht, - float gamma -) -{ - pcl_ht_t * pht = *ppht; - float inv_gamma = (gamma == 0.0 ? 1.0 : 1.0 / gamma); - int code = 0; - int i; - - /* - * All of the gamma correction factors and lookup table pointers are the - * same, so just check the first of these. If nothing has changed, just - * return. - */ - if ( (pht->client_data[0].inv_gamma == inv_gamma) && - (pht->client_data[0].plktbl == 0) ) - return 0; - - /* get a unique copy of the halftone object */ - if ((code = unshare_pcl_ht(ppht)) < 0) - return code; - pht = *ppht; - - /* discard the device specific color lookup table, if present */ - for (i = 0; i < 3; i++) { - pht->client_data[i].inv_gamma = inv_gamma; - pcl_lookup_tbl_release(pht->client_data[i].plktbl); - pht->client_data[i].plktbl = 0; - } - - return 0; -} - -/* - * Update the color lookup table information. This takes action only for lookup - * tables associated with device-dependent color spaces; other lookup tables - * are handled via color spaces. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_set_lookup_tbl( - pcl_ht_t ** ppht, - pcl_lookup_tbl_t * plktbl -) -{ - pcl_ht_t * pht = *ppht; - int code = 0; - int i; - - /* check if this is a nop clear lookup table command */ - if ((plktbl == 0) && (pht->client_data[0].plktbl == 0)) - return 0; - - /* check that the table is for a device-specific color space */ - if ((plktbl != 0) && (pcl_lookup_tbl_get_cspace(plktbl) > pcl_cspace_CMY)) - return 0; - - /* get a unique copy of the halftone object */ - if ((code = unshare_pcl_ht(ppht)) < 0) - return code; - pht = *ppht; - - for (i = 0; i < 3; i++) - pcl_lookup_tbl_copy_from(pht->client_data[i].plktbl, plktbl); - return 0; -} - -/* - * Set the user-defined dither matrix for a halftone object. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_set_udither( - pcl_ht_t ** ppht, - pcl_udither_t * pdither -) -{ - pcl_ht_t * pht = *ppht; - int code = 0; - - /* get a unique copy of the halftone object */ - if ((code = unshare_pcl_ht(ppht)) < 0) - return code; - pht = *ppht; - - pcl_udither_copy_from(pht->pdither, pdither); - return 0; -} - -/* - * Update the current halftone for a change in the color space. - * - * The color space usually does not affect the halftone, but it can in cases - * in which a device-independent color space is used with a rendering method - * that is not compatible with device-independent color spaces. - */ - int -pcl_ht_update_cspace( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - pcl_cspace_type_t cstype_old, - pcl_cspace_type_t cstype_new -) -{ - pcl_ht_t * pht = *ppht; - uint i = pht->render_method; - uint flags = pcs->rendering_info[i].flags; - - if ( ((pht->pfg_ht == 0) && (pht->pim_ht == 0)) || - ((flags & HT_DEVCSPACE) == 0) || - ((cstype_old <= pcl_cspace_CMY) && (cstype_new <= pcl_cspace_CMY)) || - ((cstype_old > pcl_cspace_CMY) && (cstype_new > pcl_cspace_CMY)) ) - return 0; - - /* get a unique copy of the halftone object */ - return unshare_pcl_ht(ppht); -} - -/* - * Create the default halftone, releasing the current halftone if it exists. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_build_default_ht( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - gs_memory_t * pmem -) -{ - int code = 0; - - if ((pcs->pdflt_ht == 0) && ((code = alloc_pcl_ht(&pcs->pdflt_ht, pmem)) < 0)) - return code; - pcl_ht_copy_from(*ppht, pcs->pdflt_ht); - return 0; -} - -/* - * Procedure to be used for transfer functions. - * - * Unlike the color space code, in this code the procedure is the same for all - * components, but the client data differs. - */ - private float -transfer_proc( - floatp val, - const gx_transfer_map * pmap, /* ignored */ - const void * pvdata -) -{ - const pcl_ht_client_data_t * pdata = (pcl_ht_client_data_t *)pvdata; - const byte * ptbl; - - if (pdata->plktbl == 0) - return pow(val, pdata->inv_gamma); - ptbl = pcl_lookup_tbl_get_tbl(pdata->plktbl, pdata->comp_indx); - return (float)(ptbl[(int)floor(255.0 * val + 0.5)]) / 255.0; -} - -/* - * Special transfer function for use with the K component. We always want - * this component to have the default (identity) transfer function when - * operating in normal (colored) mode. - */ - private float -dflt_transfer_proc( - floatp val, - const gx_transfer_map * pmap, /* ignored */ - const void * pvdata /* ignored */ -) -{ - return val; -} - -/* - * Get the rendering information corresponding to a given rendering method. - * This takes into account the restriction that certain rendering methods may - * not be used with device-independent color spaces. Also considers whether - * or not the rendering is processing PCL rasters (the for_image operand). - */ - private const pcl_rend_info_t * -get_rendering_info( - pcl_state_t * pcs, - uint sel_method, - pcl_cspace_type_t cstype, - bool for_image -) -{ - pcl_rend_info_t * pinfo = &(pcs->rendering_info[sel_method]); - uint flags = pinfo->flags; - - /* check for methods that require device-dependent color spaces */ - if ( (((flags & HT_DEVCSPACE) != 0) && (cstype > pcl_cspace_CMY)) || - (((flags & HT_IMONLY) != 0) && !for_image) ) - pinfo = &pcs->rendering_info[3]; - - return pinfo; -} - -/* - * Set the halftone component - * - * Currently, only threshold halftones are supported. - * - * The relocation properties of the memory manager require that dither - * matrices, whether built-in or user-defined, must be copied to strings to - * fit into the format required by the graphic library halftone machiner. - * - * For lack of a better alternative, the monochrome threshold is set to be the - * same as the first component. - * - * The separation names employed are not accurate, but the graphic library - * insists that 4-color spaces uses the subtractive names (there is a way - * around this, using the halftone type ht_typ_multiple_colorscreen, but that - * did not seem to work with normal CMYK devices). Providing only three color - * screens is not an option, as then the fourth component of a CMYK devices - * will use the transfer function provided by one of the other components. If - * this transfer function is inverting, the output will be very black. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_threshold_ht( - pcl_state_t * pcs, - pcl_ht_t * pht, - gs_ht * pgsht, - const pcl_rend_info_t * pinfo, - int comp, - const gs_ht_separation_name sepname -) -{ - int icomp = (comp == 3 ? 0 : comp); - pcl_ht_builtin_dither_t dt; - float (*proc)( floatp, - const gx_transfer_map *, - const void * - ) = transfer_proc; - - /* if not in monochrome print mode, make sure K has default transfer */ - if ((comp == 3) && !is_monochrome(pcs, pht->render_method)) - proc = dflt_transfer_proc; - - /* set the array threshold pointers */ - if ((pinfo->flags & HT_USERDEF) != 0) { - if (pht->pdither != 0) { - dt.type = pcl_halftone_Threshold; - dt.u.thresh.nplanes = pcl_udither_get_nplanes(pht->pdither); - dt.u.thresh.width = pcl_udither_get_width(pht->pdither); - dt.u.thresh.height = pcl_udither_get_height(pht->pdither); - dt.u.thresh.pdata = pcl_udither_get_threshold(pht->pdither, 0); - } else - dt = pcs->ordered_dither; - } else if (pinfo->pbidither != 0) - dt = *(pinfo->pbidither); - else - return e_Unimplemented; - - if (dt.type == pcl_halftone_Threshold) { - ulong size = dt.u.thresh.width * dt.u.thresh.height; - const byte * pdata = ( dt.u.thresh.nplanes == 1 - ? dt.u.thresh.pdata - : dt.u.thresh.pdata + icomp * size ); - - /* don't create a separate threshold array for the K component */ - if (comp != 3) { - byte * pb = gs_alloc_string( pht->rc.memory, - size, - "set_threshold_ht" - ); - - if (pb == 0) - return e_Memory; - memcpy(pb, pdata, size); - pht->thresholds[comp].size = size; - pht->thresholds[comp].data = pb; - } - - return gs_ht_set_threshold_comp( pgsht, - comp, - sepname, - dt.u.thresh.width, - dt.u.thresh.height, - (gs_const_string *) - &(pht->thresholds[icomp]), - proc, - &(pht->client_data[icomp]) - ); - - } else if (dt.type == pcl_halftone_Table_Dither) { - ulong size = ((dt.u.tdither.width + 7) / 8) - * dt.u.tdither.height * dt.u.tdither.nlevels; - const byte * pdata = ( dt.u.thresh.nplanes == 1 - ? dt.u.thresh.pdata - : dt.u.thresh.pdata + icomp * size ); - - return gs_ht_set_mask_comp( pgsht, - comp, - sepname, - dt.u.tdither.width, - dt.u.tdither.height, - dt.u.tdither.nlevels, - pdata, - proc, - &(pht->client_data[icomp]) - ); - - } else - return e_Unimplemented; -} - -/* - * Color plane separation names for the three standard "concrete" color spaces. - * The RGB space uses four components so as to provide a default component - * (which is required by the graphic library code). - */ -private const gs_ht_separation_name sepnames_cmyk[4] = { - gs_ht_separation_Cyan, - gs_ht_separation_Magenta, - gs_ht_separation_Yellow, - gs_ht_separation_Default /* Cyan is arbitrarily made the default */ -}; - -private const gs_ht_separation_name sepnames_rgb[4] = { - gs_ht_separation_Red, - gs_ht_separation_Green, - gs_ht_separation_Blue, - gs_ht_separation_Default, /* Red is arbitrarily made the default */ -}; - -private const gs_ht_separation_name sepnames_gray[1] = { - gs_ht_separation_Default -}; - - -/* - * Create the graphic library halftone objects corresponding to a PCL halftone - * object. - * - * The color space is provided as an operand, because certain rendering - * mehtods are only usuable with device-specific color spaces. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -create_gs_halftones( - pcl_state_t * pcs, - pcl_ht_t * pht, - pcl_cspace_type_t cstype, - int ncomps /* # device components */ -) -{ - int code = 0; - const pcl_rend_info_t * pinfo = 0; - int i; - const gs_ht_separation_name * sepnames = 0; - - /* see if there is anything to do */ - if ( (pht->pfg_ht != 0) && (pht->pim_ht != 0)) - return 0; - free_gs_hts(pht); - - /* get the rendering information for geometric objects */ - pinfo = get_rendering_info(pcs, pht->render_method, cstype, false); - - /* make the typical assumption concerning the color space */ - if (ncomps == 4) - sepnames = sepnames_cmyk; - else if (ncomps == 3) { - sepnames = sepnames_rgb; - ncomps = 4; - } else if (ncomps == 1) - sepnames = sepnames_gray; - else - return e_Range; - - /* create the top-level halftone graphic object */ - if ((code = gs_ht_build(&(pht->pfg_ht), ncomps, pht->rc.memory)) < 0) - return code; - - /* create the halftone components (allow for 4-color device) */ - for (i = 0; i < ncomps; i++) { - code = set_threshold_ht(pcs, pht, pht->pfg_ht, pinfo, i, sepnames[i]); - if (code < 0) - break; - } - - /* currently the foreground and image halftone objects must be the same */ - if (code == 0) { - if (pinfo != get_rendering_info(pcs, pht->render_method, cstype, true)) - code = e_Unimplemented; - else - gs_ht_init_ptr(pht->pim_ht, pht->pfg_ht); - } - - if (code < 0) - free_gs_hts(pht); - return code; -} - -/* - * Set the given halftone into the graphic state. If the halftone doesn't - * exist yet, create a default halftone and set it into the graphic state. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_ht_set_halftone( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - pcl_cspace_type_t cstype, - bool for_image -) -{ - pcl_ht_t * pht = *ppht; - gx_device_cmap * pdev = 0; - gx_device_cmap * old_pdev = 0; - int ncomps = 0; - gs_ht * pgsht = 0; - int code = 0; - const pcl_rend_info_t *pinfo_new = 0; - - /* if no halftone yet, create one */ - if (pht == 0) { - if ((code = pcl_ht_build_default_ht(pcs, ppht, pcs->memory)) < 0) - return code; - pht = *ppht; - } - - /* see if the halftone is already set */ - if (pcs->pids->pht == pht) - return 0; - - /* - * Check if the color mapping has changed. If it has, re-initialize the - * the mapping device, so that it will pick up any changes in the target - * device. Be sure to preserve the reference count when doing so (unless - * it is 0). - */ - if (pcs->pids->pht != 0) { - const pcl_rend_info_t * pinfo_old; - - pinfo_old = get_rendering_info( pcs, - pcs->pids->pht->render_method, - cstype, /* irrelevant */ - for_image /* irrelevant */ - ); - old_pdev = pinfo_old->pdev; - } - pinfo_new = get_rendering_info(pcs, pht->render_method, cstype, for_image); - if ((pdev = pinfo_new->pdev) != old_pdev) { - long ref_count = pdev->rc.ref_count; /* HACK ALERT */ - - if (ref_count == 0) /* HACK ALERT */ - ref_count = 1; - gdev_cmap_init(pdev, pdev->target, pdev->mapping_method); - pdev->rc.ref_count = ref_count; /* HACK ALERT */ - gs_setdevice_no_init(pcs->pgs, (gx_device *)pdev); - } - ncomps = pdev->color_info.num_components; - - /* see if we need to create a halftone object */ - if ( ((pgsht = (for_image ? pht->pim_ht : pht->pfg_ht)) == 0) && - ((code = create_gs_halftones(pcs, pht, cstype, ncomps)) < 0) ) - return code; - pgsht = (for_image ? pht->pim_ht : pht->pfg_ht); - - /* install the halftone object */ - if ((code = gs_ht_install(pcs->pgs, pgsht)) < 0) - return code; - - pcl_ht_copy_from(pcs->pids->pht, pht); - return code; -} diff --git a/pcl/pcht.h b/pcl/pcht.h deleted file mode 100644 index d8a60c449..000000000 --- a/pcl/pcht.h +++ /dev/null @@ -1,329 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcht.h - PCL halftone/rendering object */ - -#ifndef pcht_INCLUDED -#define pcht_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gsht1.h" -#include "gshtx.h" -#include "pcident.h" -#include "pcstate.h" -#include "pcommand.h" -#include "pclookup.h" -#include "pcdither.h" - - -/* - * Structure for built-in dither methods. "built-in" in this case refers to - * items that cannot be modifiied by the user via the PCL interpreter; there - * are also "fixed" dithers that are defined in the interpreter itself and - * cannot be modified by either the output device or the user. - * - * Currently two types are recognized: threshold dithers (which have the - * monotinicity property), and table dithers. Others may be added subsequently, - * though this is a large task. - * - * As is the case for both PostScript and PCL, all dithers are set up for an - * additive color spaces. This is also the organization expected by the (now - * repaired) graphic library. - * - * For thresholds, data is organized as an array of bytes in (device-space) - * by row, column, and then color plane. Each byte represents a threshold - * level between 1 and 255. Hence, for a 3 (rgb) color 2 x 2 dither, the data - * should be provided as: - * - * red(0, 0), red(1, 0), red(0, 1), red(1, 1), green(0, 0), ..., blue(1, 1) - * - * For table dithers, data is organized by (device-space) row, then column, - * then level (the intensity level to which the given color plane corresponds), - * then color plane. Data is one bit per pixel, high-order-bit leftmost, and - * rows are rounded to byte boundaries. Any number of levels may be provided, - * but the zero-intensity level (which, for subtractive color space devices, - * is all 1's) should not be provided. Note also that some code in the graphic - * library assumes that full intensity colors are pure (all 0's or all 1's), - * so these may not be handled correctly if the full intensity dither has - * both 0's and 1's. - * - * Thus, for a 3 color (rgb) 11 x 3 dither with 32 levels, data would be - * organized as follows: - * - * red_level_1(0..7, 0), red_level_1(8..10, 0), - * red_level_1(0..7, 1), red_level_1(8..10, 1), - * red_level_1(0..7, 2), red_level_1(8..10, 2), - * red_level_2(0..7, 0), red_level_2(8..10, 0), - * ... - * red_level_32(0..7, 2), red_level_32(8..10, 2), - * green_level_1(0..7, 0), green_level_1(8..10, 0), - * ... - * green_level_32(0..7, 2), green_level_32(8..10, 2), - * blue_level_1(0..7, 0), blue_level_1(8..10, 0), - * ... - * blue_level_32(0..7, 2), blue_level_32(8..10, 2) - * - * - * Note that this module does NOT take ownership of built-in dither objects; - * that is the responsibility of the caller. - */ -typedef struct pcl_ht_builtin_threshold_s { - int nplanes; /* number of planes */ - int height, width; /* in device pixels */ - const byte * pdata; -} pcl_ht_builtin_threshold_t; - -typedef struct pcl_ht_builtin_table_dither_s { - int nplanes; /* number of color planes */ - int height, width; /* in device pixels */ - int nlevels; /* number of levels in a plane; must be - the same for all planes */ - const byte * pdata; /* width x height x num_levels x nplanes */ -} pcl_ht_builtin_table_dither_t; - -typedef enum { - pcl_halftone_Threshold = 0, - pcl_halftone_Table_Dither, - pcl_halftone_num -} pcl_halftone_type_t; - -#ifndef pcl_ht_builtin_dither_DEFINED -#define pcl_ht_builtin_dither_DEFINED -typedef struct pcl_ht_builtin_dither_s { - pcl_halftone_type_t type; - union { - pcl_ht_builtin_threshold_t thresh; - pcl_ht_builtin_table_dither_t tdither; - } u; -} pcl_ht_builtin_dither_t; -#endif - -#define private_st_ht_builtin_dither_t() \ - gs_private_st_composite( st_ht_builtin_dither_t, \ - pcl_ht_builtin_dither_t, \ - "pcl builtin dither object", \ - ht_dither_enum_ptrs, \ - ht_dither_reloc_ptrs \ - ) - -/* - * Array of dithers and devices to be used for different rendering methods. - * - * The HT_FIXED flag indicates which methods may not be changed by the output - * device. The ordered, clustered ordered, and user-defined dithers (both - * color and monochrome versions) are in this category, because they must - * have predictable matrices for the logical operations to produce predictable - * results. - * - * The HT_USERDEF flag indicates which methods make use of the user-defined - * dither matrix. - * - * The HT_DECSPACE flag indicates which methods may be used with device - * independent color spaces. If one of these methods is selected and a device - * independent color space is set, the default rendering method is used - * instead. - * - * The HT_IMONLY flag indicates that a rendering method applies only to - * images. ***This feature is currently not supported*** - * - * For each rendering method there is an associated color mapping method, to - * be used with the devcmap color mapping device. A single device is used - * rather than one device for each different mapping, as the the graphic - * library provides no good technique for removing a device from a graphic - * state (this is typically done by grestore, as is the case for PostScript). - */ - -#define HT_NONE 0x0 -#define HT_FIXED 0x1 -#define HT_USERDEF 0x2 -#define HT_DEVCSPACE 0x4 -#define HT_IMONLY 0x8 - -typedef struct rend_info_s { - uint flags; - gx_device_cmap * pdev; - const pcl_ht_builtin_dither_t * pbidither; -} pcl_rend_info_t; - -/* - * Client data structure for PCL halftones. This holds two pieces of - * information: the gamma correction factor, and a pointer to the lookup table - * for device specific color spaces. The former is used only if the latter is - * null. The gamma correction factor must be kept, however, as it may be - * inherited by newly created palettes, while the lookup table itself is - * cleared (see the comment in pclookup.h for some notes on not fully - * understood items in HP's documentation concerning these tables). - * - * The system maintains three of these objects, because a separate one is - * required for each component of the (base) color space. The different - * components are distinguished only by the comp_indx field. - */ -typedef struct pcl_ht_client_data_s { - int comp_indx; - float inv_gamma; - pcl_lookup_tbl_t * plktbl; -} pcl_ht_client_data_t; - -/* - * Structure of the PCL halftone/render object. - * - * This structure contains a pair of halftone objects since, in principle, - * PCL can simultaneously support two separate halftone techniques: one for - * geometric objects (which use the foreground color), the other for images. - * For the time being these two will always be the same. - * - * As is the case with all PCL objects that access modifiable reference - * counted objects in gs, this must be kept in a one-to-one relationship with - * the graphic library halftone objects. Hence, two of these objects will never - * share a gs_ht structure. Unlike the colorspaces, however, there may be - * extended periods of time when this structure has no associated graphic - * library halftone structure. - * - * The id field is used to identify a specific halftone, and is updated whenever - * the halftone changes. This is used to indicate when structures that depend - * on the halftone must be updated. - */ -struct pcl_ht_s { - rc_header rc; - pcl_ht_client_data_t client_data[3]; - pcl_udither_t * pdither; - gs_string thresholds[3]; - uint render_method; - gs_ht * pfg_ht; - gs_ht * pim_ht; -}; - -#define private_st_ht_t() \ - gs_private_st_composite( st_ht_t, \ - pcl_ht_t, \ - "pcl halftone object", \ - ht_enum_ptrs, \ - ht_reloc_ptrs \ - ) - -#ifndef pcl_ht_DEFINED -#define pcl_ht_DEFINED -typedef struct pcl_ht_s pcl_ht_t; -#endif - -/* - * The usual init, copy,and release macros. - */ -#define pcl_ht_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_ht_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_ht_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_ht_release(pht) \ - rc_decrement(pht, "pcl_ht_release") - -/* - * The following routine is intended to initialize the forwarding devices used - * for special render methods. Currently it only creates the built-in dither - * arrays. - */ -void pcl_ht_init_render_methods(P2( - pcl_state_t * pcs, - gs_memory_t * pmem -)); - -/* - * Set up normal or monochrome print mode. The latter is accomplished by - * remapping each of the rendering algorithms to its monochrome equivalent. - * The handling of the snap-to-primaries rendering method (1) is almost - * certianly wrong, but it is the best that can be done with the current - * scheme. - * - * Note that the current rendering method must be set before this change - * will take effect. - */ -void pcl_ht_set_print_mode(P2(pcl_state_t *pcs, bool monochrome)); - -/* - * Set the render method. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_set_render_method(P3(pcl_state_t *pcs, pcl_ht_t ** ppht, uint render_method)); - -/* - * Update the gamma parameter. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_set_gamma(P2(pcl_ht_t ** ppht, float gamma)); - -/* - * Update the color lookup table information. This takes action only for lookup - * tables associated with device-dependent color spaces; other lookup tables - * are handled via color spaces. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_set_lookup_tbl(P2( - pcl_ht_t ** ppht, - pcl_lookup_tbl_t * plktbl -)); - -/* - * Set the user-defined dither matrix for a halftone object. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_set_udither(P2( - pcl_ht_t ** ppht, - pcl_udither_t * pdither -)); - -/* - * Update the current halftone for a change in the color space. - * - * The color space usually does not affect the halftone, but it can in cases - * in which a device-independent color space is used with a rendering method - * that is not compatible with device-independent color spaces. - */ -int pcl_ht_update_cspace(P4( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - pcl_cspace_type_t cstype_old, - pcl_cspace_type_t cstype_new -)); - -/* - * Create the default halftone, releasing the current halftone if it exists. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_build_default_ht(P3( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - gs_memory_t * pmem -)); - -/* - * Set the given halftone into the graphic state. If the halftone doesn't - * exist yet, create a default halftone and set it into the graphic state. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_ht_set_halftone(P4( - pcl_state_t * pcs, - pcl_ht_t ** ppht, - pcl_cspace_type_t cstype, - bool for_image -)); - -#endif /* pcht_INCLUDED */ diff --git a/pcl/pcident.c b/pcl/pcident.c deleted file mode 100644 index f6309053c..000000000 --- a/pcl/pcident.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcident.c - object identification mechanism for PCL */ - -#include "gx.h" -#include "gsuid.h" -#include "pcident.h" -#include "pcstate.h" - -/* - * Return the next unique identifier. - * - * Identifiers start at 8 to try to expose errors that might be masked by an - * identifier of 0. In the unlikely event that so many identifiers are created - * that the number wraps back to 0, the next assigned identifier will be - * 16 * 1024 * 1024. This avoids potential overlap with permanent objects that - * are assigned identifiers at initialization time. - * - * Special handling is also provided to avoid the no_UniqueID value used by - * the graphic library. - */ - pcl_gsid_t -pcl_next_id(pcl_state_t *pcs) -{ - if (pcs->next_id == 0) - pcs->next_id = 16 * 1024 * 1024; - else if (pcs->next_id == no_UniqueID) - ++(pcs->next_id); - return (pcs->next_id)++; -} diff --git a/pcl/pcident.h b/pcl/pcident.h deleted file mode 100644 index 38d6f2723..000000000 --- a/pcl/pcident.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcident.h - object identification mechanism for PCL */ - -#ifndef pcident_INCLUDED -#define pcident_INCLUDED - -#include "gx.h" - -/* - * Various "graphic attribute" objects created by PCL are used in the graphic - * state: patterns, color spaces, halftones, and rendering dictionaries. Unlike - * PostScript, these objects also have an existence outside of the graphic state. - * When graphic objects are rendered, it is necessary to determine the set of - * attribute objects they should use, and which of these is currently installed - * in the graphic state. - * - * There is no way to do this directly in the graphic library, as its attribute - * objects do not carry any identifiers (they provide no benefit in a PostScript - * setting). Hence, we pair the graphic library objects with PCL objects, and - * assign identifiers to the latter. So long as the two objects are kept in a - * one-to-one relationship, the identifiers can be used as identifiers of the - * graphic library objects as well. - * - * Though objects of different types can in principle be assigned the same - * identifier, for simplicity the current code assigns unique identifiers for - * all objects. These identifiers are unsigned longs. They are assigned - * consecutively beginning from 8 at boot time. In the unlikely event that - * they should reach 0 once more, they will restart at 16 * 1024 * 1024; this - * should prevent overlap with codes that are assigned to statically allocated - * objects at boot time. - */ - -typedef ulong pcl_gsid_t; - -/* Define an opaque type for the PCL state. */ -#ifndef pcl_state_DEFINED -# define pcl_state_DEFINED -typedef struct pcl_state_s pcl_state_t; -#endif - -pcl_gsid_t pcl_next_id(P1(pcl_state_t *pcs)); - -#endif /* pcident_INCLUDED */ diff --git a/pcl/pcimpl.c b/pcl/pcimpl.c deleted file mode 100644 index 7f33d697a..000000000 --- a/pcl/pcimpl.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcimpl.c - PCL5c pl_interp_implementation_t descriptor */ - -#include "memory_.h" -#include "scommon.h" -#include "gxdevice.h" -#include "pltop.h" - -extern const pl_interp_implementation_t pcl_implementation; - -/* Zero-terminated list of pointers to implementations */ -pl_interp_implementation_t const * const pdl_implementation[] = { - &pcl_implementation, - 0 -}; - diff --git a/pcl/pcindxed.c b/pcl/pcindxed.c deleted file mode 100644 index 33243a9b7..000000000 --- a/pcl/pcindxed.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcindexed.c - PCL indexed color space implementation */ -#include "math_.h" -#include "string_.h" -#include "gx.h" -#include "pcmtx3.h" -#include "pccid.h" -#include "pccsbase.h" -#include "pcpalet.h" - -/* default GL/2 pen width, in plotter units (1016 ploter units per inch) */ -private const float dflt_pen_width = 14.0; - -/* the image data configuration for the default color space */ -private const pcl_cid_hdr_t dflt_cid_hdr = { - pcl_cspace_RGB, /* color space type */ - pcl_penc_indexed_by_plane, /* pixel encoding type */ - 1, /* bits per index */ - { 1, 1, 1 } /* bits per primary (3 components) */ -}; - -/* - * GC routines - */ - private -ENUM_PTRS_BEGIN(pcl_cs_indexed_enum_ptrs) - return 0; - ENUM_PTR(0, pcl_cs_indexed_t, pbase); - ENUM_PTR(1, pcl_cs_indexed_t, pcspace); - ENUM_STRING_PTR(2, pcl_cs_indexed_t, palette); -ENUM_PTRS_END - - private -RELOC_PTRS_BEGIN(pcl_cs_indexed_reloc_ptrs) - RELOC_PTR(pcl_cs_indexed_t, pbase); - RELOC_PTR(pcl_cs_indexed_t, pcspace); - RELOC_STRING_PTR(pcl_cs_indexed_t, palette); -RELOC_PTRS_END - -private_st_cs_indexed_t(); - - -/* - * Find the smallest non-negative integral exponent of 2 larger than the - * given number. - */ - private int -get_pow_2( - int num -) -{ - int i; - - for (i = 0; num > 1; num >>= 1, ++i) - ; - return i; -} - -/* - * Free a PCL indexed color space structure. - */ - private void -free_indexed_cspace( - gs_memory_t * pmem, - void * pvindexed, - client_name_t cname -) -{ - pcl_cs_indexed_t * pindexed = (pcl_cs_indexed_t *)pvindexed; - - pcl_cs_base_release(pindexed->pbase); - if (pindexed->pcspace != 0) { - gs_cspace_release(pindexed->pcspace); - gs_free_object(pmem, pindexed->pcspace, cname); - } - if (pindexed->palette.data != 0) - gs_free_string( pmem, - pindexed->palette.data, - pindexed->palette.size, - cname - ); - gs_free_object(pmem, pvindexed, cname); -} - -/* - * Allocate a PCL indexed color space. - * - * Because a PCL indexed color space and the associated graphic library - * indexed color space must be kept in a one-to-one relationship, the latter - * color space is allocated here as well. This requires that the base color - * space be an operand. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -alloc_indexed_cspace( - pcl_cs_indexed_t ** ppindexed, - pcl_cs_base_t * pbase, - gs_memory_t * pmem -) -{ - pcl_cs_indexed_t * pindexed = 0; - int code = 0; - byte * bp = 0; - - rc_alloc_struct_1( pindexed, - pcl_cs_indexed_t, - &st_cs_indexed_t, - pmem, - return e_Memory, - "allocate pcl indexed color space" - ); - pindexed->rc.free = free_indexed_cspace; - pindexed->pfixed = false; - pcl_cs_base_init_from(pindexed->pbase, pbase); - pindexed->pcspace = 0; - pindexed->num_entries = 0; - pindexed->palette.data = 0; - pindexed->palette.size = 0; - - bp = gs_alloc_string( pmem, - 3 * pcl_cs_indexed_palette_size, - "allocate pcl indexed color space" - ); - if (bp == 0) { - free_indexed_cspace(pmem, pindexed, "allocate pcl indexed color space"); - return e_Memory; - } - pindexed->palette.data = bp; - pindexed->palette.size = 3 * pcl_cs_indexed_palette_size; - - code = gs_cspace_build_Indexed( &(pindexed->pcspace), - pbase->pcspace, - pcl_cs_indexed_palette_size, - (gs_const_string *)&(pindexed->palette), - pmem - ); - if (code < 0) { - free_indexed_cspace(pmem, pindexed, "allocate pcl indexed color space"); - return code; - } - - *ppindexed = pindexed; - return 0; -} - -/* - * Make a PCL indexed color space unique. - * - * Note that neither the palette nor the graphic state indexed color space can - * be shared between two PCL indexed color spaces. The two would need to be - * shared in tandem, which would require common reference counting between the - * pair, which would require yet another PCL object, and so on. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -unshare_indexed_cspace( - pcl_cs_indexed_t ** ppindexed -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - pcl_cs_indexed_t * pnew = 0; - int code = 0; - int num_entries = pindexed->num_entries; - - /* check if there is anything to do */ - if (pindexed->rc.ref_count == 1) - return 0; - rc_decrement(pindexed, "unshare PCL indexed color space"); - - /* allocate a new indexed color space */ - code = alloc_indexed_cspace( ppindexed, - pindexed->pbase, - pindexed->rc.memory - ); - if (code < 0) - return code; - pnew = *ppindexed; - - /* copy fields various and sundry */ - pnew->pfixed = pindexed->pfixed; - pnew->cid = pindexed->cid; - pnew->num_entries = pindexed->num_entries; - memcpy(pnew->palette.data, pindexed->palette.data, 3 * num_entries); - memcpy(pnew->pen_widths, pindexed->pen_widths, num_entries * sizeof(float)); - memcpy(pnew->norm, pindexed->norm, 3 * sizeof(pindexed->norm[0])); - memcpy(pnew->Decode, pindexed->Decode, 6 * sizeof(float)); - - return 0; -} - - -/* - * Fill in the default entries in a color palette. This is handled separately - * for each color space type. - * - * The manner in which the default color palette is specified by HP is, - * unfortunately, completely dependent on their particular implementation. - * HP maintains palettes in device space, and initializes palettes with - * device space colors. Hence, these palettes are affected by gamma correction - * and the lookup tables for the device color space, but not by any lookup - * tables for device independent color spaces (even if the base color space is - * device independent), nor by range specifications in the color space - * parameters. - * - * Because this implementation of PCL 5c works strictly in source color space, - * it is not possible to achieve the same result. Instead, this implementation - * will give accurate default color space values only for the RGB and CMY - * color space values, and will give approximate results for the other color - * spaces. The default colors will be modified by all applicable color lookup - * tables, though some compensation is provided for component ranges. - * - * For applications, this should not matter: presumably an application does - * not select a device independent color space in order to achieve a device- - * specific color. For tests such as the PCL 5c FTS, it is more likely that - * a discrepancy will be visible, because these tests illustrate the default - * palette for each color space. - */ - -/* - * Convert a device-independent color intensity value to the range [0, 255]. - */ - private int -convert_comp_val( - floatp val, - floatp min_val, - floatp range -) -{ - val = 255.0 * (val - min_val) / range; - return ( val < 0.0 ? 0 : (val > 255.0 ? 255 : (int)floor(val + 0.5)) ); -} - -/* - * Set the default palette for device specific color spaces. - */ - private void -set_dev_specific_default_palette( - pcl_cs_base_t * pbase, /* ignored in this case */ - byte * palette, - const byte * porder, - int start, - int num -) -{ - int i; - static const byte cmy_default[8 * 3] = { - 255, 255, 255, /* white */ - 0, 255, 255, /* cyan */ - 255, 0, 255, /* magenta */ - 0, 0, 255, /* blue */ - 255, 255, 0, /* yellow */ - 0, 255, 0, /* green */ - 255, 0, 0, /* red */ - 0, 0, 0 /* black */ - }; - - /* fill in the num_entries - 1 values from the RGB default */ - for (i = start; i < num + start; i++) { - palette[3 * i] = cmy_default[3 * porder[i]]; - palette[3 * i + 1] = cmy_default[3 * porder[i] + 1]; - palette[3 * i + 2] = cmy_default[3 * porder[i] + 2]; - } -} - -/* - * Set the default palette for a colorimetric RGB space. - * - * The assumption used in this case is that if the user specified primaries, - * presumably they want those primaries. Further, it is assumed that the red - * primary is associated with red, the green with green, and so on. Should - * the user specify a "blue" color as the red primary, then the default - * palette will have blue where red is normally expected. - * - * An adjustment is made for the specified ranges. - */ - private void -set_colmet_default_palette( - pcl_cs_base_t * pbase, - byte * palette, - const byte * porder, - int start, - int num -) -{ - float * pmin = pbase->client_data.min_val; - float * prange = pbase->client_data.range; - int i; - static const float colmet_default[8 * 3] = { - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 0.0 /* black */ - }; - - /* fill in the num_entries - 1 values from the colorimetric default */ - for (i = start; i < start + num; i++) { - int j; - byte * pb = palette + 3 * i; - const float * pdef = colmet_default + 3 * porder[i]; - - for (j = 0; j < 3; j++) - pb[j] = convert_comp_val(pdef[j], pmin[j], prange[j]); - } -} - -/* - * Set the default palette for a CIE L*a*b* color space. - * - * The values provided will, for a sufficiently capable device, generate the - * SMPTE-C primaries (assuming that ranges and/or color lookup tables don't - * get in the way). Most printing devices cannot generate these colors, so - * a somewhat different output is produced, but this is as close as we can - * come to a "device independent" set of default entries. - * - * The code provides some compensation for range: if the desired value is - * within the permitted range, the palette entry intensity (always in the range - * [0, 1]) will be adjusted so as to achieve it; otherwise the intensity will - * be set to the appropriate bound. Obviously, none of this works if a - * color lookup table is subsequently installed, but it is as much as can be - * achieved under the current arrangement. - */ - private void -set_CIELab_default_palette( - pcl_cs_base_t * pbase, - byte * palette, - const byte * porder, - int start, - int num -) -{ - float * pmin = pbase->client_data.min_val; - float * prange = pbase->client_data.range; - int i; - static const float lab_default[8 * 3] = { - 100.0, 0.0, 0.0, /* white */ - 91.1, -43.4, -14.1, /* cyan */ - 61.6, 91.0, -59.2, /* magenta */ - 35.3, 72.0, -100.0, /* blue */ - 96.6, -21.3, 95.4, /* yellow */ - 87.0, -80.7, 84.0, /* green */ - 53.2, 74.4, 67.7, /* red */ - 0.0, 0.0, 0.0 /* black */ - }; - - for (i = start; i < start + num; i++) { - int j; - byte * pb = palette + 3 * i; - const float * pdef = lab_default + 3 * porder[i]; - - for (j = 0; j < 3; j++) - pb[j] = convert_comp_val(pdef[j], pmin[j], prange[j]); - } -} - -/* - * Set the default palette for a luminance-chrominance color space. - * - * The arrangement used for this color space is based on the one used for - * the colorimetric color space. The user specifies a set of primaries - * for the color space underlying the luminance-chrominance color space, - * and we provide those primaries in the default palette. Since the - * palette entries themselves are in the luminance-chrominance color space, - * the default values must be converted to that color space. - * - * An adjustment is made for the specified ranges. - */ - private void -set_lumchrom_default_palette( - pcl_cs_base_t * pbase, - byte * palette, - const byte * porder, - int start, - int num -) -{ - gs_matrix3 * pxfm = gs_cie_abc_MatrixABC(pbase->pcspace); - float * pmin = pbase->client_data.min_val; - float * prange = pbase->client_data.range; - pcl_mtx3_t tmp_mtx; - int i; - static const pcl_vec3_t lumchrom_default[8] = { - { 1.0, 1.0, 1.0 }, /* white */ - { 0.0, 1.0, 1.0 }, /* cyan */ - { 1.0, 0.0, 1.0 }, /* magenta */ - { 0.0, 0.0, 1.0 }, /* blue */ - { 1.0, 1.0, 0.0 }, /* yellow */ - { 0.0, 1.0, 0.0 }, /* green */ - { 1.0, 0.0, 0.0 }, /* red */ - { 0.0, 0.0, 0.0 } /* black */ - }; - - /* form the primaries to component values matrix */ - pcl_mtx3_convert_from_gs(&tmp_mtx, pxfm); - pcl_mtx3_invert(&tmp_mtx, &tmp_mtx); - - for (i = start; i < start + num; i++) { - pcl_vec3_t compvec; - byte * pb = palette + 3 * i; - int j; - - pcl_vec3_xform(&(lumchrom_default[porder[i]]), &compvec, &tmp_mtx); - for (j = 0; j < 3; j++) - pb[j] = convert_comp_val(compvec.va[j], pmin[j], prange[j]); - } -} - -/* - * Set the default values for a specific range of an indexed PCL color space. - * The starting point is indicated by start; the number of subsequent entires - * to be set by num (for PCL, start is always 0 and num is always the number of - * entires in the palette, but that may not be the case for GL/2). - * - * If gl2 is true, this call is being made from GL/2, hence the GL/2 default - * palettes should be used. - * - * Returns 0 if successful, < 0 in case of an error. - */ - private int -set_default_entries( - pcl_cs_indexed_t * pindexed, - int start, - int num, - bool gl2 -) -{ - /* array of procedures to set the default palette entries */ - static void (*const set_default_palette[(int)pcl_cspace_num])( - pcl_cs_base_t * pbase, - byte * palette, - const byte * porder, - int start, - int num - ) = { - set_dev_specific_default_palette, /* RGB */ - set_dev_specific_default_palette, /* CMY */ - set_colmet_default_palette, /* colorimetric RGB */ - set_CIELab_default_palette, /* CIE L*a*b* */ - set_lumchrom_default_palette /* luminance- - * chrominance */ - }; - - /* - * For each color space, 8 palette entries are stored in the canonical - * CMY order; any palette entries beyond the first 8 always default to - * black. These arrays are incorporated into procedures that handle the - * generation of colors for each color space type. For the bits per index - * settings of 1, 2, or >= 3, an order array is provided, to indicate the - * order in which the default palette entries should be entered into the - * palette. Separate arrays are provided for the RGB and CMY color spaces, - * and for GL/2 default colors. - */ - static const byte order_1[] = { 0, 7 }; - static const byte cmy_order_2[] = { 0, 1, 2, 7 }; - static const byte cmy_order_3[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - static const byte rgb_order_2[] = { 7, 6, 5, 0 }; - static const byte rgb_order_3[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; - static const byte gl2_order_2[] = { 0, 7, 6, 5 }; - static const byte gl2_order_3[] = { 0, 7, 6, 5, 4, 3, 2, 1 }; - static const byte * cmy_order[3] = {order_1, cmy_order_2, cmy_order_3}; - static const byte * rgb_order[3] = {order_1, rgb_order_2, rgb_order_3}; - static const byte * gl2_order[3] = {order_1, gl2_order_2, gl2_order_3}; - - int type = pindexed->cid.cspace; - int bits = pindexed->cid.bits_per_index - 1; - const byte * porder; - int cnt = (num + start > 8 ? 8 - start : num); - int i; - - if (bits > 2) - bits = 2; - if (gl2) - porder = gl2_order[bits]; - else if (type == pcl_cspace_RGB) - porder = rgb_order[bits]; - else - porder = cmy_order[bits]; - - /* set the default colors for up to the first 8 entries */ - set_default_palette[(int)type]( pindexed->pbase, - pindexed->palette.data, - porder, - start, - cnt - ); - - /* all other entries are black (always comp. value 0) */ - if (num > cnt) - memset(pindexed->palette.data + 3 * (start + cnt), 0, num - cnt); - - /* set the default widths */ - for (i = start; i < start + num; i++) - pindexed->pen_widths[i] = dflt_pen_width; - - return 0; -} - -/* - * Generate the normalization and, if appropriate, Decode arrays that correspond - * to a pcl_cid_data structure. - * - * Normalization in PCL and GL/2 involves a modification of a component color - * setting prior to its being stored in the palette. This is set in PCL via - * the black and white reference points for device specific color spaces, and - * in GL/2 via the CR command. The latter provides the much more general - * interface, which in turn drives the implementation. - * - * In PCL, white and black reference points may be set only for the device- - * dependent color spaces, and may only be set once when a palette is created - * (via the configure image data command; the min/max ranges for the device - * independent color spaces have a different interpretation). The CR command, - * on the other hand, applies to all color spaces, and can used to modfiy the - * range without otherwise changing the current color palette. - * - * All color spaces in this implementation are set up so that, in the palette, - * 0 represents the minimum intensity, and 1 the maximum intensity. For a - * component that has black and white reference points of blk and wht, - * respectively, the normalization applied is: - * - * tmp_val = ((i_val - blk) / (wht - blk) - * - * o_val = (tmp_val < 0 ? 0 : (tmp_val > 1 ? 1 : tmp_val)) - * - * Because palette entries are stored as integers in the range [0, 255], the - * actual form in which the normalization data are stored (and the modified - * normalization calculation) are: - * - * blkref = blk - * - * inv_range = 255.0 / (wht - blk) - * - * tmp_val = (i_val - blkref) * inv_range + 0.5; - * - * o_val = (tmp_val < 0 ? 0 : (tmp_val > 255 ? 255 : floor(tmp_val + 0.5))) - * - * For a primary that uses an n-bit representation, the default values for - * blk and wht are 0 and 2^n - 1, respectively. (For HP's implementation this - * only applies to device-dependent color spaces; wht for device-independent - * color spaces is always 255. There seems to be no reason for such a - * restriction, hence it is not used here. This is unlikely to cause difficulty - * in practice, as it is unlikely a device-independent color space will ever - * be used with anything other than 8-bits per primary.) - * - * Note that for the CMY color space, the white and black points are reversed. - * This is the only distinction between the RGB and CMY color spaces. - * - * The Decode array is used for images, and thus has different forms - * depending on the pixel encoding mode. For the "direct by" cases - * it incorporates normalization information; for the "indexed by" - * cases its contents are dictated by the size of the palette. - */ - int -pcl_cs_indexed_set_norm_and_Decode( - pcl_cs_indexed_t ** ppindexed, - floatp wht0, - floatp wht1, - floatp wht2, - floatp blk0, - floatp blk1, - floatp blk2 -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - pcl_encoding_type_t enc = (pcl_encoding_type_t)pindexed->cid.encoding; - pcl_cs_indexed_norm_t * pnorm; - int code = 0; - - /* ignore request if palette is fixed */ - if (pindexed->pfixed) - return 0; - - /* get a unique copy of the color space */ - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - pnorm = pindexed->norm; - - /* set up for the additive space */ - pnorm[0].blkref = blk0; - pnorm[0].inv_range = (wht0 == blk0 ? 0.0 : 255.0 / (wht0 - blk0)); - pnorm[1].blkref = blk1; - pnorm[1].inv_range = (wht1 == blk1 ? 0.0 : 255.0 / (wht1 - blk1)); - pnorm[2].blkref = blk2; - pnorm[2].inv_range = (wht2 == blk2 ? 0.0 : 255.0 / (wht2 - blk2)); - - /* - * Build the Decode array to be used with images. - * - * If an "indexed by" pixel encoding scheme is being used, the color - * space for images is the same color space used for the foreground, and - * the Decode array is the canonical array for Indexed color spaces. - * - * If a "direct by" pixel encoding is being used, the Decode array must - * yield the same color component values as would be produced by use of - * the "color component" commands. Thus, for any color component intensity - * a, we must have - * - * (a - blkref) / range = Dmin + a * (Dmax - Dmin) / (2^n - 1) - * - * where blkref and range are the black reference point and range value for - * this component (computed above), Dmin and Dmax are the first and second - * elements of the Decode array for this component, and n is the number of - * bits per pixel. Setting a = 0, this yields: - * - * -blkref / range = Dmin - * - * Substituting this into the original equation yields: - * - * (a - blkref) / range = a * (Dmax + blkref/range) / (2^n - 1) - * - blkref / range; - * - * Adding blkref / range to both sides, and multiplying both sides by - * range * (2^n - 1) / a yields: - * - * 2^n - 1 = range * Dmax + blkref - * - * or - * - * (2^n - 1 - blkref) / range = Dmax - * - * Note that this arrangement requires the image/color space code to - * properly handle out of range values. - */ - if (enc >= pcl_penc_direct_by_plane) { - int i; - float * pdecode = pindexed->Decode; - - for (i = 0; i < 3; i++) { - int nbits = pindexed->cid.bits_per_primary[i]; - floatp inv_range = pnorm[i].inv_range; - - if (inv_range == 0.0) - inv_range = 254; - pdecode[2 * i] = -pnorm[i].blkref * inv_range / 255.0; - pdecode[2 * i + 1] = ((float)((1L << nbits) - 1) - pnorm[i].blkref) - * inv_range / 255.0; - } - } else { - pindexed->Decode[0] = 0.0; - pindexed->Decode[1] = 0.0; /* modified subsequently */ - } - return 0; -} - -/* - * Change the number of entries in an PCL indexed color space palette. For - * PCL itself, this occurs only when a palette is created, and is determined - * by the number of bits per index. The NP command in GL/2, on the other hand, - * can override the palette size for an existing palette. - * - * The gl2 boolean indicates if this call is being made from GL/2 (either the - * IN or NP command). The routine needs to know this so as to set the - * appropriate default colors. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_indexed_set_num_entries( - pcl_cs_indexed_t ** ppindexed, - int new_num, - bool gl2 -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - int bits = get_pow_2(new_num); - int old_num = pindexed->num_entries; - int code = 0; - - /* ignore request if palette is fixed */ - if (pindexed->pfixed) - return 0; - - /* - * Set new_num to the smallest larger power of 2 less than - * pcl_cs_indexed_palette_size. - */ - bits = ( bits > pcl_cs_indexed_palette_size_log - ? pcl_cs_indexed_palette_size_log - : bits ); - new_num = 1L << bits; - - /* check if there is anything to do */ - if (new_num == old_num) - return 0; - - /* make sure the palette is unique */ - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - pindexed->num_entries = new_num; - pindexed->cid.bits_per_index = bits; - - /* check if the Decode array must be updated */ - if (pindexed->cid.encoding < pcl_penc_direct_by_plane) - pindexed->Decode[1] = new_num - 1; - - /* if the palette grew, write in default colors and widths */ - if (new_num > old_num) - set_default_entries(pindexed, old_num, new_num, gl2); - return 0; -} - -/* - * Update the lookup table information for an indexed color space. - * - * Because lookup tables can modify base color spaces, this operation is - * rather ugly. If the base color space is changed, it is necessary to release - * and re-build the graphic library indexed color space as well, as this will - * now have references to obsolete parts of the graphic library base color - * space. - * - * Fortunately, this operation does not happen very often. - * - * Returns 0 if successful, < 0 in the event of an error. - */ - int -pcl_cs_indexed_update_lookup_tbl( - pcl_cs_indexed_t ** ppindexed, - pcl_lookup_tbl_t * plktbl -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - pcl_cspace_type_t cstype = (pcl_cspace_type_t)pindexed->cid.cspace; - pcl_cspace_type_t lktype; - int code = 0; - - /* make some simple checks for not-interesting color spaces */ - if (plktbl != 0) - lktype = pcl_lookup_tbl_get_cspace(plktbl); - if ( (plktbl != 0) && - ((cstype < lktype) || (lktype < pcl_cspace_Colorimetric)) ) - return 0; - - /* make a unique copy of the indexed color space */ - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - - /* update the base color space, if appropriate */ - code = pcl_cs_base_update_lookup_tbl(&(pindexed->pbase), plktbl); - if (code <= 0) - return code; - - /* the base space was updated, so re-build the indexed color space */ - if (pindexed->pcspace != 0) { - gs_cspace_release(pindexed->pcspace); - gs_free_object( pindexed->rc.memory, - pindexed->pcspace, - "update_lookup_tbl" - ); - pindexed->pcspace = 0; - } - - return gs_cspace_build_Indexed( &(pindexed->pcspace), - pindexed->pbase->pcspace, - pcl_cs_indexed_palette_size, - (gs_const_string *)&(pindexed->palette), - pindexed->rc.memory - ); - -} - -/* - * Update an entry in the palette of a PCL indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_indexed_set_palette_entry( - pcl_cs_indexed_t ** ppindexed, - int indx, - const float comps[3] -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - int code; - int i; - - /* ignore request if palette is fixed */ - if (pindexed->pfixed) - return 0; - - /* - * Verify that the index is in range. This code obeys HP's documentation, - * and the implementation in the CLJ 5/5M. The DJ 1600C/CM behaves - * differently; it sets indx = indx % num_entries, but only if indx is - * non-negative. - */ - if ((indx < 0) || (indx >= pindexed->num_entries)) - return e_Range; - - /* get a unique copy of the indexed color space */ - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - - /* normalize and store the entry */ - indx *= 3; - for (i = 0; i < 3; i++) { - pcl_cs_indexed_norm_t * pn = &(pindexed->norm[i]); - floatp val = comps[i]; - - if (pn->inv_range == 0) - val = (val >= pn->blkref ? 255.0 : 0.0); - else { - val = (val - pn->blkref) * pn->inv_range; - val = (val < 0.0 ? 0.0 : (val > 255.0 ? 255.0 : val)); - } - pindexed->palette.data[indx + i] = (byte)val; - } - return 0; -} - -/* - * Default the contents of a palette entry. - * - * This request can only come from GL/2, hence there is no gl2 boolean. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_indexed_set_default_palette_entry( - pcl_cs_indexed_t ** ppindexed, - int indx -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - int code; - - /* - * Verify that the index is in range. This code obeys HP's documentation, - * and the implementation in the CLJ 5/5M. The DJ 1600C/CM behaves - * differently; it sets indx = indx % num_entries, but only if indx is - * non-negative. - */ - if ((indx < 0) || (indx >= pindexed->num_entries)) - return e_Range; - - /* get a unique copy of the indexed color space */ - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - - return set_default_entries(*ppindexed, indx, 1, true); -} - -/* - * Set a pen width in a palette. Units used are still TBD. - * - * Returns 0 if successful, < 0 in case of error. - */ - int -pcl_cs_indexed_set_pen_width( - pcl_cs_indexed_t ** ppindexed, - int pen, - floatp width -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - int code; - - /* check for out-of-range pen */ - if ((pen < 0) || (pen > pindexed->num_entries)) - return e_Range; /* probably should be a different error */ - - if ((code = unshare_indexed_cspace(ppindexed)) < 0) - return code; - pindexed = *ppindexed; - - pindexed->pen_widths[pen] = width; - return 0; -} - -/* - * Build a PCL indexed color space. - * - * To maintain the one-to-one relationship between the PCL indexed color space - * and the graphic library indexed color space, the latter is created at the - * same time as the former. Hence, the base PCL color space must be created - * first (it is required to create the graphics library indexed color space), - * and released once it has been referenced by the (PCL) indexed color space. - * - * The boolean gl2 indicates if this request came from the GL/2 IN command. - * - * Returns 0 if successful, < 0 in case of error. - */ - - int -pcl_cs_indexed_build_cspace( - pcl_state_t * pcs, - pcl_cs_indexed_t ** ppindexed, - const pcl_cid_data_t * pcid, - bool pfixed, - bool gl2, - gs_memory_t * pmem -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - pcl_cspace_type_t type = pcl_cid_get_cspace(pcid); - int bits = pcl_cid_get_bits_per_index(pcid); - floatp wht_ref[3]; - floatp blk_ref[3]; - pcl_cs_base_t * pbase = 0; - bool is_default = false; - int code = 0; - /* - * Check if the default color space is being requested. Since there are - * only three fixed spaces, it is sufficient to check that palette is - * fixed and has 1-bit per pixel. - */ - if (pfixed && (pcid->u.hdr.bits_per_index == dflt_cid_hdr.bits_per_index)) { - is_default = true; - if (pcs->pdflt_cs_indexed != 0) { - pcl_cs_indexed_copy_from(*ppindexed, pcs->pdflt_cs_indexed); - return 0; - } - } - - /* release the existing color space, if present */ - if (pindexed != 0) - rc_decrement(pindexed, "build indexed color space"); - - /* build the base color space */ - if ((code = pcl_cs_base_build_cspace(&pbase, pcid, pmem)) < 0) - return code; - - /* build the indexed color space */ - if ((code = alloc_indexed_cspace(ppindexed, pbase, pmem)) < 0) { - pcl_cs_base_release(pbase); - return code; - } - pindexed = *ppindexed; - - /* release our extra reference of the base color space */ - pcl_cs_base_release(pbase); - pbase = 0; - - /* copy the header of the configure image data structure */ - pindexed->cid = pcid->u.hdr; - - /* set up the normalization information */ - if ((pcid->len > 6) && (type < pcl_cspace_Colorimetric)) { - const pcl_cid_dev_long_t * pdev = &(pcid->u.dev); - int i; - - for (i = 0; i < 3; i++) { - wht_ref[i] = pdev->white_ref[i]; - blk_ref[i] = pdev->black_ref[i]; - } - } else { - int i; - - for (i = 0; i < 3; i++) { - wht_ref[i] = (1L << pcl_cid_get_bits_per_primary(pcid, i)) - 1; - blk_ref[i] = 0.0; - } - - /* reverse for the CMY color space */ - if (type == pcl_cspace_CMY) { - int i; - - for (i = 0; i < 3; i++) { - floatp ftmp = wht_ref[i]; - - wht_ref[i] = blk_ref[i]; - blk_ref[i] = ftmp; - } - } - } - pcl_cs_indexed_set_norm_and_Decode( ppindexed, - wht_ref[0], wht_ref[1], wht_ref[2], - blk_ref[0], blk_ref[1], blk_ref[2] - ); - - /* set the palette size and the default palette entries */ - pcl_cs_indexed_set_num_entries(ppindexed, 1L << bits, gl2); - - /* now can indicate if the palette is fixed */ - pindexed->pfixed = pfixed; - - /* record if this is the default */ - if (is_default) - pcl_cs_indexed_init_from(pcs->pdflt_cs_indexed, pindexed); - - return 0; -} - -/* - * Build the default indexed color space. This function is usually called only - * once, at initialization time. - * - * Returns 0 on success, < 0 - */ - int -pcl_cs_indexed_build_default_cspace( - pcl_state_t * pcs, - pcl_cs_indexed_t ** ppindexed, - gs_memory_t * pmem -) -{ - if (pcs->pdflt_cs_indexed == 0) { - pcs->dflt_cid_data.len = 6; - pcs->dflt_cid_data.u.hdr = dflt_cid_hdr; - return pcl_cs_indexed_build_cspace( pcs, - ppindexed, - &pcs->dflt_cid_data, - true, - false, - pmem - ); - } else { - pcl_cs_indexed_copy_from(*ppindexed, pcs->pdflt_cs_indexed); - return 0; - } -} - -/* - * Special indexed color space constructor, for building a 2 entry indexed color - * space based on an existing base color space. The first color is always set - * to white, while the second entry takes the value indicated by pcolor1. - * - * This reoutine is used to build the two-entry indexed color spaces required - * for creating opaque "uncolored" patterns. - */ - int -pcl_cs_indexed_build_special( - pcl_cs_indexed_t ** ppindexed, - pcl_cs_base_t * pbase, - const byte * pcolor1, - gs_memory_t * pmem -) -{ - static const pcl_cid_hdr_t cid = { pcl_cspace_White, /* ignored */ - pcl_penc_indexed_by_pixel, - 1, - { 8, 8, 8} /* ignored */ }; - static const floatp wht_ref[3] = { 255.0, 255.0, 255.0 }; - static const floatp blk_ref[3] = { 0.0, 0.0, 0.0 }; - - pcl_cs_indexed_t * pindexed; - int i, code = 0; - - /* build the indexed color space */ - if ((code = alloc_indexed_cspace(ppindexed, pbase, pmem)) < 0) - return code; - pindexed = *ppindexed; - pindexed->pfixed = false; - pindexed->cid = cid; - pindexed->num_entries = 2; - - /* set up the normalization information - not strictly necessary */ - pcl_cs_indexed_set_norm_and_Decode( ppindexed, - wht_ref[0], wht_ref[1], wht_ref[2], - blk_ref[0], blk_ref[1], blk_ref[2] - ); - pindexed->Decode[1] = 1; - - for (i = 0; i < 3; i++) { - pindexed->palette.data[i] = 255; - pindexed->palette.data[i + 3] = pcolor1[i]; - } - - /* the latter are not strictly necessary */ - pindexed->pen_widths[0] = dflt_pen_width; - pindexed->pen_widths[1] = dflt_pen_width; - - return 0; -} - -/* - * Install an indexed color space into the graphic state. If no indexed color - * space exists yet, build a default color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_cs_indexed_install( - pcl_cs_indexed_t ** ppindexed, - pcl_state_t * pcs -) -{ - pcl_cs_indexed_t * pindexed = *ppindexed; - int code = 0; - - if (pindexed == 0) { - code = pcl_cs_indexed_build_default_cspace(pcs, ppindexed, pcs->memory); - if (code < 0) - return code; - pindexed = *ppindexed; - } - - return gs_setcolorspace(pcs->pgs, pindexed->pcspace); -} - -/* - * Return true if the given entry in the color palette represents white, - * false otherwise. - * - * As with many other parts of this code, the determination of what is "white" - * is done, for practical reasons, in source color space. HP's implementations - * make the same determination in device color space (but prior to dithering). - * In the absence of color lookup tables, the two will give the same result. - * An inverting color lookup table will, however, cause the two approaches to - * vary. - */ - bool -pcl_cs_indexed_is_white( - const pcl_cs_indexed_t * pindexed, - int indx -) -{ - const byte * pb = 0; - - if (pindexed == 0) - return true; - if ((indx < 0) || (indx >= pindexed->num_entries)) - return false; - pb = pindexed->palette.data + 3 * indx; - return (pb[0] == 0xff) && (pb[1] == 0xff) && (pb[2] == 0xff); -} - -/* - * Return true if the given entry in the color palette is black, false - * otherwise. - * - * The determination of "blackness" is made in source space, rather than in - * device space (prior to dither). The latter would be more correct, but is - * not as easily accomplished, and only in very unusual circumstances will the - * two produce different results. - */ - bool -pcl_cs_indexed_is_black( - const pcl_cs_indexed_t * pindexed, - int indx -) -{ - const byte * pb = 0; - - if ((pindexed == 0) || (indx < 0) || (indx >= pindexed->num_entries)) - return false; - pb = pindexed->palette.data + 3 * indx; - return (pb[0] == 0) && (pb[1] == 0) && (pb[2] == 0); -} - -/* - * One time initialization. This exists only because of the possibility that - * BSS may not be initialized. - */ - void -pcl_cs_indexed_init(pcl_state_t *pcs) -{ - pcs->pdflt_cs_indexed = 0; -} diff --git a/pcl/pcindxed.h b/pcl/pcindxed.h deleted file mode 100644 index 32dfaf60b..000000000 --- a/pcl/pcindxed.h +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcindxed.h - PCL indexed color space object */ - -#ifndef pcindexed_INCLUDED -#define pcindexed_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "gscspace.h" -#include "pcident.h" -#include "pcstate.h" -#include "pccid.h" -#include "pclookup.h" -#include "pccsbase.h" - - -/* - * Size of a PCL color palette. All palettes are allocated at this size, as - * GL/2 may change the size of a palette after it has been created. - * - * The overall size must be a power of 2, and for all practical purposes must - * be >= 8. The PCL documentation does not specify a value for this parameter, - * though in chapter 7 of the "PCL 5 Color Technical Reference Manual" it - * is indicated as being implementation specific. For all of the PCL 5c devices - * we have tested, the value is 8. - */ -#define pcl_cs_indexed_palette_size_log 8 -#define pcl_cs_indexed_palette_size (1 << pcl_cs_indexed_palette_size_log) - - -/* - * Structure to hold the parameters that normalize raw color values to values - * usable for the base color space. The formula used is: - * - * out = 255 * (in - blkref) / (whtref - blkref) - * - * The black and white reference points can be set in PCL only for the device- - * dependent color spaces (the max/min parameters for device-independent color - * spaces have a different interpretation). The parameters may be set for all - * color spaces, however, via the CR command in GL/2. - * - * Note that for the CMY color space, the white and black reference points are - * reversed. - */ -typedef struct pcl_cs_indexed_norm_s { - float blkref; - float inv_range; /* 255 / (whtref - blkref) */ -} pcl_cs_indexed_norm_t; - - -/* - * PCL indexed color space. This consists of: - * - * A copy of the configure image data header (short form) which was used - * to create this color space (only the header is necessary; all the - * other relevant information is captured in the normalization and - * graphic library color space structures) - * - * A PCL base color space, which in turn consists of a graphic library - * base color space and its associated client data (including lookup - * tables for device-independent color spaces) - * - * A graphic library indexed color space - * - * An indication of how many entries in the palette are currently - * "accessible" (this is required to support the GL/2 "NP" command) - * - * The palette used by the indexed color space. This is always the maximum - * size, as GL/2 can change the number of entries in a palette without - * changing the palette (via the NP command) - * - * In a reasonable world this palette would be a fixed size array of - * bytes in the (PCL) indexed color space structure. Unfortunately, - * the GhostScript graphic library is not a reasonable world in this - * respect. The table used by an indexed color space must be a string, - * which means it must be allocated separately. The gs_string structure - * kept in this structure is a pointer to this separately allocated - * string. - * - * The set of pen widths. This has nothing to do with colors, but since - * pens in GL/2 are associated with palette entries in PCL, this is - * the logical place to put this information; issues concerning which - * units to use are still TBD. - * - * Since there is no PostScript-centric library which must make use of - * these widths, they can be kept in a sensible array. - * - * A boolean to indicate if a palette is fixed (with respect to colors; all - * palettes have settable pen widths). - * - * A identifier, which is used to indicate when objects dependent on this - * color space must be regenerated. The identifier is incremented each - * time the color space is modified (but not when pen widths are - * modified, as the width information is not cached). - * - * A structure for normalizing raw input values to component values in - * the palette; this supports the black/white reference points for - * each color component - * - * A Decode array, to be used with images. This incorporates the same - * information as provided by the conversion parameters described in - * the previous item, but in a different form - * - * Note that the graphic state color space is referenced twice in this - * structure: once by the indexed color space and again by the PCL base color - * space. This arrangement is necessary because the graphic state base color - * space does not take ownership of its client data. - * - * Though the palette is stored as a separate object, it is not possible - * to share graphic library indexed color spaces between two PCL indexed color - * spaces. Given the current structure of graphic state color spaces, this - * problem is not easily remedied, as both the palette and the pcl base color - * space must be kept in a one-to-one relationship with the graphic library - * indexed color space. - */ - -struct pcl_cs_indexed_s { - rc_header rc; - bool pfixed; - pcl_cid_hdr_t cid; - pcl_cs_base_t * pbase; - gs_color_space * pcspace; - int num_entries; - gs_string palette; - float pen_widths[pcl_cs_indexed_palette_size]; - pcl_cs_indexed_norm_t norm[3]; - float Decode[6]; -}; - -#ifndef pcl_cs_indexed_DEFINED -#define pcl_cs_indexed_DEFINED -typedef pcl_cs_indexed_s pcl_cs_indexed_t; -#endif - -#define private_st_cs_indexed_t() \ - gs_private_st_composite( st_cs_indexed_t, \ - pcl_cs_indexed_t, \ - "pcl indexed color space", \ - pcl_cs_indexed_enum_ptrs, \ - pcl_cs_indexed_reloc_ptrs \ - ) - -/* - * The usual copy, init, and release macros. - */ -#define pcl_cs_indexed_init_from(pto, pfrom)\ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_cs_indexed_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_cs_indexed_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_cs_indexed_release(pindexed) \ - rc_decrement(pindexed, "pcl_cs_indexed_release") - -/* - * Get the color space type for the base color space of an indexed color space. - */ -#define pcl_cs_indexed_get_cspace(pindexed) \ - ((pcl_cspace_type_t)((pindexed)->cid.cspace)) - -/* - * Get the pixel encoding mode from an indexed color space. - */ -#define pcl_cs_indexed_get_encoding(pindexed) \ - ((pcl_encoding_type_t)((pindexed)->cid.encoding)) - -/* - * Get the number of bits per index from an indexed color space - */ -#define pcl_cs_indexed_get_bits_per_index(pindexed) \ - ((pindexed)->cid.bits_per_index) - -/* - * Get the number of bits per primary from an indexed color space. - */ -#define pcl_cs_indexed_get_bits_per_primary(pindexed, i) \ - ((pindexed)->cid.bits_per_primary[i]) - -/* - * Nacro to return the number of entries in the current color space. - */ -#define pcl_cs_indexed_get_num_entries(pindexed) ((pindexed)->num_entries) - -/* - * Macro to return a pointer to the array of pen widths. Note that the pointer - * is a const float. - */ -#define pcl_cs_indexed_get_pen_widths(pindexed) \ - ((const float *)((pindexed)->pen_widths)) - -/* - * Generate the normalization and, if appropriate, Decode array that correspond - * to a pcl_cid_data structure. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_indexed_set_norm_and_Decode(P7( - pcl_cs_indexed_t ** ppindexed, - floatp wht0, - floatp wht1, - floatp wht2, - floatp blk0, - floatp blk1, - floatp blk2 -)); - -/* - * Change the number of entries in an PCL indexed color space palette. - * - * The gl2 boolean indicates if this call is being made from GL/2 (either the - * IN or NP command). - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_indexed_set_num_entries(P3( - pcl_cs_indexed_t ** ppindexed, - int new_num, - bool gl2 -)); - -/* - * Update the lookup table information for an indexed color space. - * - * Returns 0 if successful, < 0 in the event of an error. - */ -int pcl_cs_indexed_update_lookup_tbl(P2( - pcl_cs_indexed_t ** pindexed, - pcl_lookup_tbl_t * plktbl -)); - -/* - * Update an entry in the palette of a PCL indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_indexed_set_palette_entry(P3( - pcl_cs_indexed_t ** ppindexed, - int indx, - const float comps[3] -)); - -/* - * Default the contents of a palette entry. - * - * This request can only come from GL/2, hence there is no gl2 boolean. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_indexed_set_default_palette_entry(P2( - pcl_cs_indexed_t ** ppindexed, - int indx -)); - -/* - * Set a pen width in a palette. Units used are still TBD. - * - * Returns 0 if successful, < 0 in case of error. - */ -int pcl_cs_indexed_set_pen_width(P3( - pcl_cs_indexed_t ** ppindexed, - int pen, - floatp width -)); - -/* - * Build a PCL indexed color space. - * - * The boolean gl2 indicates if this request came from the GL/2 IN command. - * - * Returns 0 if successful, < 0 in case of error. - */ -int pcl_cs_indexed_build_cspace(P6( - pcl_state_t * pcs, - pcl_cs_indexed_t ** ppindexed, - const pcl_cid_data_t * pcid, - bool fixed, - bool gl2, - gs_memory_t * pmem -)); - -/* - * Build the default indexed color space. This function is usually called only - * once, at initialization time. - * - * Returns 0 on success, < 0 - */ -int pcl_cs_indexed_build_default_cspace(P3( - pcl_state_t * pcs, - pcl_cs_indexed_t ** ppindexed, - gs_memory_t * pmem -)); - -/* - * Special indexed color space constructor, for building a 2 entry indexed color - * space based on an existing base color space. The first color is always set - * to white, while the second entry takes the value indicated by pcolor1. - * - * This reoutine is used to build the two-entry indexed color spaces required - * for creating opaque "uncolored" patterns. - */ -int pcl_cs_indexed_build_special(P4( - pcl_cs_indexed_t ** ppindexed, - pcl_cs_base_t * pbase, - const byte * pcolor1, - gs_memory_t * pmem -)); - -/* - * Install an indexed color space into the graphic state. If not indexed - * color space exists yet, build a default color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_cs_indexed_install(P2( - pcl_cs_indexed_t ** ppindexed, - pcl_state_t * pcs -)); - -/* - * Two routines to determine if an entry of a color palette is either white - * or black, and two macros to specialize these to the first entry (index 0). - * - * The determination of "whiteness" and "blackness" is made in source space. - * This is not fully legitimate, as the HP's implementations make this - * determination in device space. However, only in unusual circumnstances will - * the two give different results, and the former is much simpler to implement - * in the current system. - */ -bool pcl_cs_indexed_is_white(P2( - const pcl_cs_indexed_t * pindexed, - int indx -)); - -bool pcl_cs_indexed_is_black(P2( - const pcl_cs_indexed_t * pindexed, - int indx -)); - -#define pcl_cs_indexed_0_is_white(pindexed) \ - pcl_cs_indexed_is_white(pindexed, 0) -#define pcl_cs_indexed_0_is_black(pindexed) \ - pcl_cs_indexed_is_black(pindexed, 0) - -/* - * One time initialization. This exists only because of the possibility that - * BSS may not be initialized. - */ -void pcl_cs_indexed_init(pcl_state_t *pcs); - -#endif /* pcindexed_INCLUDED */ diff --git a/pcl/pcjob.c b/pcl/pcjob.c deleted file mode 100644 index 30a4ac1ec..000000000 --- a/pcl/pcjob.c +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcjob.c - PCL5 job control commands */ -#include "std.h" -#include "gx.h" -#include "gsmemory.h" -#include "gsmatrix.h" /* for gsdevice.h */ -#include "gsdevice.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcparam.h" -#include "pcdraw.h" -#include "pcpage.h" -#include "pjtop.h" - -/* Commands */ - -private int /* ESC E */ -pcl_printer_reset(pcl_args_t *pargs, pcl_state_t *pcs) -{ - if ( pcs->macro_level ) - return e_Range; /* not allowed inside macro */ - - /* reset the other parser in case we have gotten the - pcl_printer_reset while in gl/2 mode. */ - pcl_implicit_gl2_finish(pcs); - /* Print any partial page. */ - { - int code = pcl_end_page_if_marked(pcs); - if ( code < 0 ) - return code; - } - /* Reset to user default state. */ - return pcl_do_resets(pcs, pcl_reset_printer); -} - -private int /* ESC % -12345 X */ -pcl_exit_language(pcl_args_t *pargs, pcl_state_t *pcs) -{ if ( int_arg(pargs) != -12345 ) - return e_Range; - { int code = pcl_printer_reset(pargs, pcs); - return (code < 0 ? code : e_ExitLanguage); - } -} - -private int /* ESC & l <num_copies> X */ -pcl_number_of_copies(pcl_args_t *pargs, pcl_state_t *pcs) -{ int i = int_arg(pargs); - if ( i < 1 ) - return 0; - pcs->num_copies = i; - return put_param1_int(pcs, "NumCopies", i); -} - -private int /* ESC & l <sd_enum> S */ -pcl_simplex_duplex_print(pcl_args_t *pargs, pcl_state_t *pcs) -{ int code; - bool reopen = false; - - /* oddly the command goes to the next page irrespective of - arguments */ - code = pcl_end_page_if_marked(pcs); - if ( code < 0 ) - return code; - pcl_home_cursor(pcs); - switch ( int_arg(pargs) ) - { - case 0: - pcs->duplex = false; - break; - case 1: - pcs->duplex = true; - pcs->bind_short_edge = false; - break; - case 2: - pcs->duplex = true; - pcs->bind_short_edge = false; - break; - default: - return 0; - } - code = put_param1_bool(pcs, "Duplex", pcs->duplex); - switch ( code ) - { - case 1: /* reopen device */ - reopen = true; - case 0: - break; - case gs_error_undefined: - return 0; - default: /* error */ - if ( code < 0 ) - return code; - } - code = put_param1_bool(pcs, "BindShortEdge", pcs->bind_short_edge); - switch ( code ) - { - case 1: /* reopen device */ - reopen = true; - case 0: - case gs_error_undefined: - break; - default: /* error */ - if ( code < 0 ) - return code; - } - return (reopen ? gs_setdevice_no_erase(pcs->pgs, - gs_currentdevice(pcs->pgs)) : - 0); -} - -private int /* ESC & a <side_enum> G */ -pcl_duplex_page_side_select(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint i = uint_arg(pargs); - int code; - - /* oddly the command goes to the next page irrespective of - arguments */ - code = pcl_end_page_if_marked(pcs); - if ( code < 0 ) - return code; - pcl_home_cursor(pcs); - - if ( i > 2 ) - return 0; - - if ( i > 0 && pcs->duplex ) - put_param1_bool(pcs, "FirstSide", i == 1); - return 0; -} - -private int /* ESC & l 1 T */ -pcl_job_separation(pcl_args_t *pargs, pcl_state_t *pcs) -{ int i = int_arg(pargs); - if ( i != 1 ) - return 0; - /**** NEED A DRIVER PROCEDURE FOR END-OF-JOB ****/ - return 0; -} - -private int /* ESC & l <bin_enum> G */ -pcl_output_bin_selection(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint i = uint_arg(pargs); - if ( i < 1 || i > 2 ) - return e_Range; - return put_param1_int(pcs, "OutputBin", i); -} - -private int /* ESC & u <upi> B */ -pcl_set_unit_of_measure(pcl_args_t *pargs, pcl_state_t *pcs) -{ int num = int_arg(pargs); - - if ( num <= 96 ) - num = 96; - else if ( num >= 7200 ) - num = 7200; - else if ( 7200 % num != 0 ) - { /* Pick the exact divisor of 7200 with the smallest */ - /* relative error. */ - static const int values[] = { - 96, 100, 120, 144, 150, 160, 180, 200, 225, 240, 288, - 300, 360, 400, 450, 480, 600, 720, 800, 900, - 1200, 1440, 1800, 2400, 3600, 7200 - }; - const int *p = values; - - while ( num > p[1] ) p++; - /* Now *p < num < p[1]. */ - if ( (p[1] - (float)num) / p[1] < ((float)num - *p) / *p ) - p++; - num = *p; - } - pcs->uom_cp = pcl_coord_scale / num; - return 0; -} - -/* Initialization */ -private int -pcjob_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_ESCAPE_ARGS('E', "Printer Reset", pcl_printer_reset, pca_in_rtl) - DEFINE_CLASS('%') - {0, 'X', {pcl_exit_language, pca_neg_ok|pca_big_error|pca_in_rtl}}, - END_CLASS - DEFINE_CLASS('&') - {'l', 'X', - PCL_COMMAND("Number of Copies", pcl_number_of_copies, - pca_neg_ignore|pca_big_clamp)}, - {'l', 'S', - PCL_COMMAND("Simplex/Duplex Print", pcl_simplex_duplex_print, - pca_neg_ignore|pca_big_ignore)}, - {'a', 'G', - PCL_COMMAND("Duplex Page Side Select", - pcl_duplex_page_side_select, - pca_neg_ignore|pca_big_ignore)}, - {'l', 'T', - PCL_COMMAND("Job Separation", pcl_job_separation, - pca_neg_error|pca_big_error)}, - {'l', 'G', - PCL_COMMAND("Output Bin Selection", pcl_output_bin_selection, - pca_neg_error|pca_big_error)}, - {'u', 'D', - PCL_COMMAND("Set Unit of Measure", pcl_set_unit_of_measure, - pca_neg_error|pca_big_error)}, - END_CLASS - return 0; -} -private void -pcjob_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ if ( type & (pcl_reset_initial | pcl_reset_printer) ) - { pcs->num_copies = pjl_proc_vartoi(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "copies")); - pcs->duplex = - !pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "duplex"), "off") ? false : true; - pcs->bind_short_edge = - !pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "binding"), "longedge") ? false : true; - pcs->back_side = false; - pcs->output_bin = 1; - } - if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay) ) - { pcl_args_t args; - arg_set_uint(&args, 300); - pcl_set_unit_of_measure(&args, pcs); - } -} -const pcl_init_t pcjob_init = { - pcjob_do_registration, pcjob_do_reset, 0 -}; diff --git a/pcl/pcl.mak b/pcl/pcl.mak deleted file mode 100644 index 711c911ae..000000000 --- a/pcl/pcl.mak +++ /dev/null @@ -1,1200 +0,0 @@ -# Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. -# All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# makefile for PCL5*, HP RTL, and HP-GL/2 interpreters -# Users of this makefile must define the following: -# GSSRCDIR - the GS library source directory -# PLSRCDIR - the PCL* support library source directory -# PLOBJDIR - the object directory for the PCL support library -# PCLSRCDIR - the source directory -# PCLGENDIR - the directory for source files generated during building -# PCLOBJDIR - the object / executable directory -# PLOBJ = $(PLOBJDIR)$(D) - -PCLSRC = $(PCLSRCDIR)$(D) -PCLGEN = $(PCLGENDIR)$(D) -PCLOBJ = $(PCLOBJDIR)$(D) -PCLO_ = $(O_)$(PCLOBJ) - -PCLCCC = $(CC_) $(I_)$(PCLSRCDIR)$(_I) $(I_)$(PCLGENDIR)$(_I) $(I_)$(PLSRCDIR)$(_I) $(I_)$(GLSRCDIR)$(_I) $(C_) - -# Define the name of this makefile. -PCL_MAK = $(PCLSRC)pcl.mak - -pcl.clean: pcl.config-clean pcl.clean-not-config-clean - -pcl.clean-not-config-clean: - $(RM_) $(PCLOBJ)*.$(OBJ) - -pcl.config-clean: clean_gs - $(RM_) $(PCLOBJ)*.dev - $(RM_) $(PCLOBJ)devs.tr5 - -################ PCL / RTL support ################ - -#### Miscellaneous - -PCLVERSION=1.32 - -# pgstate.h is out of order because pcstate.h includes it. -pclver_h = $(PCLSRC)pclver.h -pgstate_h = $(PCLSRC)pgstate.h \ - $(gx_h) \ - $(gxfixed_h) \ - $(gslparam_h) \ - $(gzpath_h) - -pccoord_h = $(PCLSRC)pccoord.h - -pcxfmst_h = $(PCLSRC)pcxfmst.h \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gxfixed_h) \ - $(pccoord_h) - -pcfontst_h = $(PCLSRC)pcfontst.h \ - $(gx_h) \ - $(plfont_h) - -pctpm_h = $(PCLSRC)pctpm.h \ - $(gx_h) - -pcident_h = $(PCLSRC)pcident.h \ - $(gx_h) - -pcpattyp_h = $(PCLSRC)pcpattyp.h - -pcdict_h = $(PCLSRC)pcdict.h \ - $(gx_h) - -rtrstst_h = $(PCLSRC)rtrstst.h \ - $(gx_h) \ - $(gsimage_h) \ - $(pccoord_h) - -pcmtx3_h = $(PCLSRC)pcmtx3.h \ - $(math__h) \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gscspace_h) \ - $(gscolor2_h) \ - $(gscie_h) - -pcommand_h = $(PCLSRC)pcommand.h \ - $(gx_h) \ - $(gserrors_h) - -pcstate_h = $(PCLSRC)pcstate.h \ - $(gx_h) \ - $(gxdevice_h) \ - $(scommon_h) \ - $(gsdcolor_h) \ - $(gschar_h) \ - $(pldict_h) \ - $(plfont_h) \ - $(pccoord_h) \ - $(pcxfmst_h) \ - $(pcfontst_h) \ - $(pctpm_h) \ - $(pcpattyp_h) \ - $(pcdict_h) \ - $(rtrstst_h) \ - $(pgstate_h) \ - $(pjtop_h) - -pccid_h = $(PCLSRC)pccid.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(pcommand_h) - -pccrd_h = $(PCLSRC)pccrd.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gsmatrix_h) \ - $(gscspace_h) \ - $(gscolor2_h) \ - $(gscie_h) \ - $(gscrd_h) \ - $(pcident_h) \ - $(pcstate_h) - -pcdither_h = $(PCLSRC)pcdither.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(pcstate_h) \ - $(pcommand_h) - -pcdraw_h = $(PCLSRC)pcdraw.h \ - $(pcstate_h) - -pcfont_h = $(PCLSRC)pcfont.h \ - $(pcstate_h) \ - $(plfont_h) - -pclookup_h = $(PCLSRC)pclookup.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(pcommand_h) \ - $(pccid_h) - -pccsbase_h = $(PCLSRC)pccsbase.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gscspace_h) \ - $(pcident_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pccid_h) \ - $(pclookup_h) - -pcht_h = $(PCLSRC)pcht.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gsht1_h) \ - $(gxhtx_h) \ - $(pcident_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pclookup_h) \ - $(pcdither_h) - -pcindxed_h = $(PCLSRC)pcindxed.h\ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gscspace_h) \ - $(pcident_h) \ - $(pcstate_h) \ - $(pccid_h) \ - $(pclookup_h) \ - $(pccsbase_h) - -pcpalet_h = $(PCLSRC)pcpalet.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(pcident_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pclookup_h) \ - $(pcdither_h) \ - $(pccid_h) \ - $(pcindxed_h) \ - $(pcht_h) \ - $(pccrd_h) - -pcfrgrnd_h = $(PCLSRC)pcfrgrnd.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pccsbase_h) \ - $(pcht_h) \ - $(pccrd_h) \ - $(pcpalet_h) - -pcpage_h = $(PCLSRC)/pcpage.h \ - $(pcstate_h) \ - $(pcommand_h) - -pcparam_h = $(PCLSRC)pcparam.h \ - $(gsparam_h) - -pcparse_h = $(PCLSRC)pcparse.h \ - $(gsmemory_h) \ - $(pcommand_h) - -pcpatrn_h = $(PCLSRC)pcpatrn.h \ - $(gx_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(pcindxed_h) \ - $(pccsbase_h) - -pcbiptrn_h = $(PCLSRC)pcbiptrn.h \ - $(pcpatrn_h) - -pcpatxfm_h = $(PCLSRC)pcpatxfm.h \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pcpatrn_h) - -pctop_h = $(PCLSRC)pctop.h - -pcuptrn_h = $(PCLSRC)pcuptrn.h \ - $(gx_h) \ - $(pcommand_h) \ - $(pcpatrn_h) - -pcursor_h = $(PCLSRC)pcursor.h \ - $(gx_h) \ - $(pcstate_h) \ - $(pcommand_h) - -pcwhtidx_h = $(PCLSRC)pcwhtidx.h\ - $(gx_h) \ - $(gsbitmap_h) \ - $(pcindxed_h) - -rtgmode_h = $(PCLSRC)rtgmode.h \ - $(rtrstst_h) \ - $(pcstate_h) \ - $(pcommand_h) - -rtraster_h = $(PCLSRC)rtraster.h \ - $(pcstate_h) \ - $(pcommand_h) - -rtrstcmp_h = $(PCLSRC)rtrstcmp.h \ - $(gx_h) \ - $(gsstruct_h) - - -$(PCLSRC)pclver.h: $(PCLSRC)pcl_top.mak - $(PCLGEN)echogs$(XE) -e .h -w $(PCLSRC)pclver -n -x 23 "define PCLVERSION" - $(PCLGEN)echogs$(XE) -e .h -a $(PCLSRC)pclver -s -x 22 $(PCLVERSION) -x 22 - $(PCLGEN)echogs$(XE) -e .h -a $(PCLSRC)pclver -n -x 23 "define PCLBUILDDATE" - $(PCLGEN)echogs$(XE) -e .h -a $(PCLSRC)pclver -s -x 22 -d -x 22 - - -$(PCLOBJ)pcommand.$(OBJ): $(PCLSRC)pcommand.c \ - $(std_h) \ - $(memory__h) \ - $(gstypes_h) \ - $(gsmemory_h) \ - $(gsmatrix_h) \ - $(gxstate_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcparam_h) \ - $(pcident_h) - $(PCLCCC) $(PCLSRC)pcommand.c $(PCLO_)pcommand.$(OBJ) - -$(PCLOBJ)pcdraw.$(OBJ): $(PCLSRC)pcdraw.c \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gsstate_h) \ - $(gsrop_h) \ - $(gxfixed_h) \ - $(pcstate_h) \ - $(pcht_h) \ - $(pccrd_h) \ - $(pcpatrn_h) \ - $(pcdraw_h) - $(PCLCCC) $(PCLSRC)pcdraw.c $(PCLO_)pcdraw.$(OBJ) - -#### PCL5 parsing - -$(PCLOBJ)pcparse.$(OBJ): $(PCLSRC)pcparse.c \ - $(AK) \ - $(stdio__h) \ - $(gdebug_h) \ - $(gstypes_h) \ - $(scommon_h) \ - $(pcparse_h) \ - $(pcstate_h) \ - $(pcursor_h) \ - $(rtgmode_h) - $(PCLCCC) $(PCLSRC)pcparse.c $(PCLO_)pcparse.$(OBJ) - -PCL5_PARSE = $(PCLOBJ)pcommand.$(OBJ) $(PCLOBJ)pcparse.$(OBJ) - -# PCL5_OTHER should include $(GD)stream.$(OBJ), but that is included -# automatically anyway. -PCL5_OTHER = $(PCL5_PARSE) $(PCLOBJ)pcdraw.$(OBJ) - -$(PCLOBJ)pcl5base.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL5_OTHER) \ - $(PLOBJ)pl.dev $(PLOBJ)pjl.dev - $(SETMOD) $(PCLOBJ)pcl5base $(PCL5_OTHER) - $(ADDMOD) $(PCLOBJ)pcl5base -include $(PLOBJ)pl $(PLOBJ)pjl - $(ADDMOD) $(PCLOBJ)pcl5base -init pcparse - -################ Raster graphics base ################ - -# This is the intersection of HP RTL and PCL5e/5C. -# We separate this out because HP RTL isn't *quite* a subset of PCL5. - -# pgmand.h is here because it is needed for the enter/exit language -# commands in HP RTL. -pgmand_h = $(PCLSRC)pgmand.h \ - $(stdio__h) \ - $(gdebug_h) \ - $(pcommand_h) \ - $(pcstate_h) - -#### Monochrome commands -# These are organized by chapter # in the PCL 5 Technical Reference Manual. - -rtraster_h = $(PCLSRC)rtraster.h \ - $(pcstate_h) \ - $(pcommand_h) - -# Chapters 4, 13, 18, and Comparison Guide -$(PCLOBJ)rtmisc.$(OBJ): $(PCLSRC)rtmisc.c \ - $(math__h) \ - $(pgmand_h) \ - $(pgdraw_h) \ - $(pgmisc_h) \ - $(gsmemory_h) \ - $(gsrop_h) \ - $(gscoord_h) \ - $(pcpatxfm_h) \ - $(pcpage_h) \ - $(pcdraw_h) - $(PCLCCC) $(PCLSRC)rtmisc.c $(PCLO_)rtmisc.$(OBJ) - -# Chapter 15 -$(PCLOBJ)rtraster.$(OBJ): $(PCLSRC)rtraster.c \ - $(memory__h) \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gspath_h) \ - $(gspath2_h) \ - $(gsimage_h) \ - $(gsiparam_h) \ - $(gsiparm4_h) \ - $(gsdevice_h) \ - $(gsrop_h) \ - $(pcstate_h) \ - $(pcpalet_h) \ - $(pcindxed_h) \ - $(pcwhtidx_h) \ - $(pcdraw_h) \ - $(rtgmode_h) \ - $(rtrstcmp_h) \ - $(rtraster_h) - $(PCLCCC) $(PCLSRC)rtraster.c $(PCLO_)rtraster.$(OBJ) - -rtlbase_ = $(PCLOBJ)rtmisc.$(OBJ) $(PCLOBJ)rtraster.$(OBJ) - -$(PCLOBJ)rtlbase.dev: $(PCL_MAK) $(ECHOGS_XE) $(rtlbase_) $(PCLOBJ)pcl5base.dev - $(SETMOD) $(PCLOBJ)rtlbase $(rtlbase_) - $(ADDMOD) $(PCLOBJ)rtlbase -include $(PCLOBJ)pcl5base - $(ADDMOD) $(PCLOBJ)rtlbase -init rtmisc rtraster - -#### Color commands -# These are organized by chapter # in the PCL 5 Color Technical Reference -# Manual. (These are no longer separable from the base PCL set) - -# Chapter 2, 3, 4, 5 -$(PCLOBJ)pcbiptrn.$(OBJ): $(PCLSRC)pcbiptrn.c \ - $(string__h) \ - $(gstypes_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(gscoord_h) \ - $(pcpatrn_h) \ - $(pcstate_h) \ - $(pcuptrn_h) \ - $(pcbiptrn_h) - $(PCLCCC) $(PCLSRC)pcbiptrn.c $(PCLO_)pcbiptrn.$(OBJ) - -$(PCLOBJ)pccid.$(OBJ): $(PCLSRC)pccid.c \ - $(gx_h) \ - $(gsmemory_h) \ - $(gsstruct_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcpalet_h) \ - $(pccid_h) - $(PCLCCC) $(PCLSRC)pccid.c $(PCLO_)pccid.$(OBJ) - -$(PCLOBJ)pccolor.$(OBJ): $(PCLSRC)pccolor.c \ - $(std_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcpalet_h) - $(PCLCCC) $(PCLSRC)pccolor.c $(PCLO_)pccolor.$(OBJ) - -$(PCLOBJ)pccrd.$(OBJ): $(PCLSRC)pccrd.c \ - $(string__h) \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gsparam_h) \ - $(gsdevice_h) \ - $(gscspace_h) \ - $(gscolor2_h) \ - $(gscie_h) \ - $(gscrd_h) \ - $(gscrdp_h) \ - $(pcommand_h) \ - $(pccrd_h) - $(PCLCCC) $(PCLSRC)pccrd.c $(PCLO_)pccrd.$(OBJ) - -$(PCLOBJ)pccsbase.$(OBJ): $(PCLSRC)pccsbase.c \ - $(gx_h) \ - $(math__h) \ - $(gstypes_h) \ - $(gsmatrix_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gscspace_h) \ - $(gscolor2_h) \ - $(gscie_h) \ - $(pcmtx3_h) \ - $(pccsbase_h) - $(PCLCCC) $(PCLSRC)pccsbase.c $(PCLO_)pccsbase.$(OBJ) - -$(PCLOBJ)pcdither.$(OBJ): $(PCLSRC)pcdither.c \ - $(pcommand_h) \ - $(pcpalet_h) \ - $(pcdither_h) - $(PCLCCC) $(PCLSRC)pcdither.c $(PCLO_)pcdither.$(OBJ) - -$(PCLOBJ)pcfrgrnd.$(OBJ): $(PCLSRC)pcfrgrnd.c \ - $(gx_h) \ - $(pcommand_h) \ - $(pcfont_h) \ - $(pcfrgrnd_h) - $(PCLCCC) $(PCLSRC)pcfrgrnd.c $(PCLO_)pcfrgrnd.$(OBJ) - -$(PCLOBJ)pcht.$(OBJ): $(PCLSRC)pcht.c \ - $(gx_h) \ - $(math__h) \ - $(gsmemory_h) \ - $(gsstruct_h) \ - $(gsrefct_h) \ - $(gsdevice_h) \ - $(gsparam_h) \ - $(gxdevice_h) \ - $(gdevcmap_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcdither_h) \ - $(pcht_h) - $(PCLCCC) $(PCLSRC)pcht.c $(PCLO_)pcht.$(OBJ) - -$(PCLOBJ)pcident.$(OBJ): $(PCLSRC)pcident.c \ - $(gx_h) \ - $(gsuid_h) \ - $(pcident_h) - $(PCLCCC) $(PCLSRC)pcident.c $(PCLO_)pcident.$(OBJ) - -$(PCLOBJ)pcindxed.$(OBJ): $(PCLSRC)pcindxed.c \ - $(gx_h) \ - $(math__h) \ - $(string__h) \ - $(pcmtx3_h) \ - $(pccid_h) \ - $(pccsbase_h) \ - $(pcindxed_h) \ - $(pcpalet_h) - $(PCLCCC) $(PCLSRC)pcindxed.c $(PCLO_)pcindxed.$(OBJ) - -$(PCLOBJ)pclookup.$(OBJ): $(PCLSRC)pclookup.c \ - $(pcpalet_h) \ - $(pclookup_h) - $(PCLCCC) $(PCLSRC)pclookup.c $(PCLO_)pclookup.$(OBJ) - -$(PCLOBJ)pcmtx3.$(OBJ): $(PCLSRC)pcmtx3.c \ - $(gx_h) \ - $(string__h) \ - $(math__h) \ - $(gstypes_h) \ - $(pcommand_h) \ - $(pcmtx3_h) - $(PCLCCC) $(PCLSRC)pcmtx3.c $(PCLO_)pcmtx3.$(OBJ) - -$(PCLOBJ)pcpalet.$(OBJ): $(PCLSRC)pcpalet.c \ - $(gx_h) \ - $(pldict_h) \ - $(pcdraw_h) \ - $(pcpage_h) \ - $(pcursor_h) \ - $(pcpalet_h) \ - $(pcfrgrnd_h) - $(PCLCCC) $(PCLSRC)pcpalet.c $(PCLO_)pcpalet.$(OBJ) - -$(PCLOBJ)pcpatrn.$(OBJ): $(PCLSRC)pcpatrn.c \ - $(gx_h) \ - $(gsuid_h) \ - $(gsmatrix_h) \ - $(gspcolor_h) \ - $(pccid_h) \ - $(pcfont_h) \ - $(pcpalet_h) \ - $(pcfrgrnd_h) \ - $(pcht_h) \ - $(pcwhtidx_h) \ - $(pcpatrn_h) \ - $(pcbiptrn_h) \ - $(pcuptrn_h) \ - $(pcpatxfm_h) - $(PCLCCC) $(PCLSRC)pcpatrn.c $(PCLO_)pcpatrn.$(OBJ) - -$(PCLOBJ)pcpatxfm.$(OBJ): $(PCLSRC)pcpatxfm.c \ - $(gx_h) \ - $(math__h) \ - $(pcpatrn_h) \ - $(pcfont_h) \ - $(pcpatxfm_h) - $(PCLCCC) $(PCLSRC)pcpatxfm.c $(PCLO_)pcpatxfm.$(OBJ) - -$(PCLOBJ)pcuptrn.$(OBJ): $(PCLSRC)pcuptrn.c \ - $(string__h) \ - $(gx_h) \ - $(gscsel_h) \ - $(gxdevice_h) \ - $(gxpcolor_h) \ - $(pldict_h) \ - $(pcindxed_h) \ - $(pcpatrn_h) \ - $(pcbiptrn_h) \ - $(pcuptrn_h) - $(PCLCCC) $(PCLSRC)pcuptrn.c $(PCLO_)pcuptrn.$(OBJ) - -$(PCLOBJ)pcwhtidx.$(OBJ): $(PCLSRC)pcwhtidx.c \ - $(pcstate_h) \ - $(pcpalet_h) \ - $(pcindxed_h) \ - $(pcwhtidx_h) - $(PCLCCC) $(PCLSRC)pcwhtidx.c $(PCLO_)pcwhtidx.$(OBJ) - -# Chapter 6 -$(PCLOBJ)rtgmode.$(OBJ): $(PCLSRC)rtgmode.c \ - $(gx_h) \ - $(math__h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gsstate_h) \ - $(pcstate_h) \ - $(pcpatxfm_h) \ - $(pcindxed_h) \ - $(pcpalet_h) \ - $(pcursor_h) \ - $(pcdraw_h) \ - $(rtraster_h) \ - $(rtrstcmp_h) \ - $(rtgmode_h) \ - $(rtrstst_h) \ - $(pcstate_h) \ - $(pcommand_h) - $(PCLCCC) $(PCLSRC)rtgmode.c $(PCLO_)rtgmode.$(OBJ) - -$(PCLOBJ)rtrstcmp.$(OBJ): $(PCLSRC)rtrstcmp.c \ - $(string__h) \ - $(pcstate_h) \ - $(rtrstcmp_h) - $(PCLCCC) $(PCLSRC)rtrstcmp.c $(PCLO_)rtrstcmp.$(OBJ) - - -rtlbasec_ = $(PCLOBJ)pcbiptrn.$(OBJ) $(PCLOBJ)pccid.$(OBJ) \ - $(PCLOBJ)pccolor.$(OBJ) $(PCLOBJ)pccrd.$(OBJ) \ - $(PCLOBJ)pccsbase.$(OBJ) $(PCLOBJ)pcdither.$(OBJ) \ - $(PCLOBJ)pcfrgrnd.$(OBJ) $(PCLOBJ)pcht.$(OBJ) \ - $(PCLOBJ)pcident.$(OBJ) $(PCLOBJ)pcindxed.$(OBJ) \ - $(PCLOBJ)pclookup.$(OBJ) $(PCLOBJ)pcmtx3.$(OBJ) \ - $(PCLOBJ)pcpalet.$(OBJ) $(PCLOBJ)pcpatrn.$(OBJ) \ - $(PCLOBJ)pcpatxfm.$(OBJ) $(PCLOBJ)pcuptrn.$(OBJ) \ - $(PCLOBJ)pcwhtidx.$(OBJ) $(PCLOBJ)rtgmode.$(OBJ) \ - $(PCLOBJ)rtrstcmp.$(OBJ) - -$(PCLOBJ)rtlbasec.dev: $(PCL_MAK) $(ECHOGS_XE) $(rtlbasec_) $(PCLOBJ)rtlbase.dev - $(SETMOD) $(PCLOBJ)rtlbasec $(rtlbasec_) - $(ADDMOD) $(PCLOBJ)rtlbasec -include $(PCLOBJ)rtlbase - $(ADDMOD) $(PCLOBJ)rtlbasec -init pcl_cid pcl_color pcl_udither - $(ADDMOD) $(PCLOBJ)rtlbasec -init pcl_frgrnd pcl_lookup_tbl - $(ADDMOD) $(PCLOBJ)rtlbasec -init pcl_palette pcl_pattern - $(ADDMOD) $(PCLOBJ)rtlbasec -init pcl_xfm pcl_upattern - $(ADDMOD) $(PCLOBJ)rtlbasec -init rtgmode - -################ PCL 5e/5c ################ - -#### Shared support - -pcfsel_h = $(PCLSRC)pcfsel.h \ - $(pcstate_h) - -pcsymbol_h = $(PCLSRC)pcsymbol.h \ - $(plsymbol_h) - -# Font selection is essentially identical in PCL and HP-GL/2. -$(PCLOBJ)pcfsel.$(OBJ): $(PCLSRC)pcfsel.c \ - $(stdio__h) \ - $(gdebug_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcfont_h) \ - $(pcfsel_h) \ - $(pcsymbol_h) - $(PCLCCC) $(PCLSRC)pcfsel.c $(PCLO_)pcfsel.$(OBJ) - -$(TOP_OBJ): $(PCLSRC)pctop.c \ - $(AK) \ - $(malloc__h) \ - $(math__h) \ - $(memory__h) \ - $(stdio__h) \ - $(scommon_h) \ - $(pcparse_h) \ - $(pcstate_h) \ - $(pldebug_h) \ - $(gdebug_h) \ - $(gsmatrix_h) \ - $(gsstate_h) \ - $(gxalloc_h) \ - $(gxdevice_h) \ - $(gxstate_h) \ - $(gdevbbox_h) \ - $(pjparse_h) \ - $(plmain_h) \ - $(pltop_h) \ - $(pclver_h) \ - $(pctop_h) \ - $(PCLGEN)pconf.h - $(CP_) $(PCLGEN)pconf.h $(PCLGEN)pconfig.h - $(PCLCCC) $(PCLSRC)pctop.c $(PCLO_)pctop.$(OBJ) - -PCL_COMMON = $(PCLOBJ)pcfsel.$(OBJ) - -#### PCL5(e) commands -# These are organized by chapter # in the PCL 5 Technical Reference Manual. - -# Chapter 4 -# Some of these replace implementations in rtmisc.c. -$(PCLOBJ)pcjob.$(OBJ): $(PCLSRC)pcjob.c \ - $(std_h) \ - $(gx_h) \ - $(gsmemory_h) \ - $(gsmatrix_h) \ - $(gsdevice_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcparam_h) \ - $(pcdraw_h) \ - $(pcpage_h) \ - $(pjparse_h) \ - $(pjtop_h) - $(PCLCCC) $(PCLSRC)pcjob.c $(PCLO_)pcjob.$(OBJ) - -# Chapter 5 -$(PCLOBJ)pcpage.$(OBJ): $(PCLSRC)pcpage.c \ - $(std_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcdraw_h) \ - $(pcparam_h) \ - $(pcparse_h) \ - $(pcfont_h) \ - $(pcpatxfm_h) \ - $(pcursor_h) \ - $(pcpage_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pjparse_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gsdevice_h) \ - $(gspaint_h) \ - $(gxdevice_h) \ - $(gdevbbox_h) \ - $(pjtop_h) - $(PCLCCC) $(PCLSRC)pcpage.c $(PCLO_)pcpage.$(OBJ) - -# Chapter 6 -$(PCLOBJ)pcursor.$(OBJ): $(PCLSRC)pcursor.c \ - $(std_h) \ - $(math__h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcdraw_h) \ - $(pcpatxfm_h) \ - $(pcfont_h) \ - $(pcursor_h) \ - $(pcpage_h) \ - $(pjparse_h) \ - $(pjtop_h) \ - $(gscoord_h) - $(PCLCCC) $(PCLSRC)pcursor.c $(PCLO_)pcursor.$(OBJ) - -# Chapter 8 -$(PCLOBJ)pcfont.$(OBJ): $(PCLSRC)pcfont.c \ - $(std_h) \ - $(memory__h) \ - $(gx_h) \ - $(gsccode_h) \ - $(gsmatrix_h) \ - $(gxfont_h) \ - $(gxfont42_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcursor_h) \ - $(pcfont_h) \ - $(pcfsel_h) \ - $(pjparse_h) \ - $(pjtop_h) - $(PCLCCC) $(PCLSRC)pcfont.c $(PCLO_)pcfont.$(OBJ) - -$(PCLOBJ)pclfont.$(OBJ): $(PCLSRC)pclfont.c \ - $(stdio__h) \ - $(string__h) \ - $(gx_h) \ - $(gp_h) \ - $(gsccode_h) \ - $(gsmatrix_h) \ - $(gsutil_h) \ - $(gxfont_h) \ - $(gxfont42_h) \ - $(pcommand_h) \ - $(pcstate_h) - $(PCLCCC) $(PCLSRC)pclfont.c $(PCLO_)pclfont.$(OBJ) - -$(PCLOBJ)pctext.$(OBJ): $(PCLSRC)pctext.c \ - $(gx_h) \ - $(gsimage_h) \ - $(plvalue_h) \ - $(plvocab_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcdraw_h) \ - $(pcfont_h) \ - $(pcursor_h) \ - $(gdebug_h) \ - $(gscoord_h) \ - $(gsline_h) \ - $(gspaint_h) \ - $(gspath_h) \ - $(gspath2_h) \ - $(gsrop) \ - $(gsstate_h) \ - $(gxchar_h) \ - $(gxfont_h) \ - $(gxstate_h) - $(PCLCCC) $(PCLSRC)pctext.c $(PCLO_)pctext.$(OBJ) - -# Chapter 10 -$(PCLOBJ)pcsymbol.$(OBJ): $(PCLSRC)pcsymbol.c \ - $(stdio__h) \ - $(plvalue_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcfont_h) \ - $(pcsymbol_h) - $(PCLCCC) $(PCLSRC)pcsymbol.c $(PCLO_)pcsymbol.$(OBJ) - -$(PCLOBJ)pcsfont.$(OBJ): $(PCLSRC)pcsfont.c \ - $(memory__h) \ - $(stdio__h) \ - $(math__h) \ - $(pcommand_h) \ - $(pcfont_h) \ - $(pcstate_h) \ - $(pcfsel_h) \ - $(pldict_h) \ - $(plvalue_h) \ - $(gsbitops_h) \ - $(gsccode_h) \ - $(gsmatrix_h) \ - $(gsutil_h) \ - $(gxfont_h) \ - $(gxfont42_h) - $(PCLCCC) $(PCLSRC)pcsfont.c $(PCLO_)pcsfont.$(OBJ) - -# Chapter 12 -$(PCLOBJ)pcmacros.$(OBJ): $(PCLSRC)pcmacros.c \ - $(stdio__h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcparse_h) - $(PCLCCC) $(PCLSRC)pcmacros.c $(PCLO_)pcmacros.$(OBJ) - -# Chapter 14 -$(PCLOBJ)pcrect.$(OBJ): $(PCLSRC)pcrect.c \ - $(math__h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcdraw_h) \ - $(pcpatrn_h) \ - $(pcbiptrn_h) \ - $(pcuptrn_h) \ - $(gspath_h) \ - $(gspath2_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gspaint_h) \ - $(gsrop_h) - $(PCLCCC) $(PCLSRC)pcrect.c $(PCLO_)pcrect.$(OBJ) - -# Chapter 15 -# All of these are in rtraster.c, but some of them are only registered -# in PCL5 mode. - -# Chapter 16 -$(PCLOBJ)pcstatus.$(OBJ): $(PCLSRC)pcstatus.c \ - $(memory__h) \ - $(stdio__h) \ - $(string__h) \ - $(gsmemory_h) \ - $(gsmalloc_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcfont_h) \ - $(pcsymbol_h) \ - $(pcpatrn_h) \ - $(pcuptrn_h) \ - $(pcpage_h) \ - $(pcursor_h) \ - $(stream_h) - $(PCLCCC) $(PCLSRC)pcstatus.c $(PCLO_)pcstatus.$(OBJ) - -# Chapter 24 -$(PCLOBJ)pcmisc.$(OBJ): $(PCLSRC)pcmisc.c \ - $(std_h) \ - $(pcommand_h) \ - $(pcstate_h) - $(PCLCCC) $(PCLSRC)pcmisc.c $(PCLO_)pcmisc.$(OBJ) - -PCL5_OPS1 = $(PCLOBJ)pcjob.$(OBJ) $(PCLOBJ)pcpage.$(OBJ) \ - $(PCLOBJ)pcursor.$(OBJ) - -PCL5_OPS2 = $(PCLOBJ)pcfont.$(OBJ) $(PCLOBJ)pclfont.$(OBJ) \ - $(PCLOBJ)pctext.$(OBJ) - -PCL5_OPS3 = $(PCLOBJ)pcsymbol.$(OBJ) - -PCL5_OPS4 = $(PCLOBJ)pcsfont.$(OBJ) $(PCLOBJ)pcmacros.$(OBJ) - -PCL5_OPS5 = $(PCLOBJ)pcrect.$(OBJ) $(PCLOBJ)pcstatus.$(OBJ) \ - $(PCLOBJ)pcmisc.$(OBJ) - -PCL5_OPS = $(PCL5_OPS1) $(PCL5_OPS2) $(PCL5_OPS3) $(PCL5_OPS4) $(PCL5_OPS5) - -# Note: we have to initialize the cursor after initializing the logical -# page dimensions, so we do it last. This is a hack. -$(PCLOBJ)pcl5.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL_COMMON) $(PCL5_OPS) \ - $(PCLOBJ)pcl5base.dev $(PCLOBJ)rtlbase.dev - $(SETMOD) $(PCLOBJ)pcl5 $(PCL_COMMON) - $(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS1) - $(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS2) - $(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS3) - $(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS4) - $(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS5) - $(ADDMOD) $(PCLOBJ)pcl5 -include $(PCLOBJ)rtlbase - $(ADDMOD) $(PCLOBJ)pcl5 -init pcjob pcpage pcfont pctext - $(ADDMOD) $(PCLOBJ)pcl5 -init pcsymbol pcsfont pcmacros - $(ADDMOD) $(PCLOBJ)pcl5 -init pcrect rtraster pcstatus - $(ADDMOD) $(PCLOBJ)pcl5 -init pcmisc - $(ADDMOD) $(PCLOBJ)pcl5 -init pcursor - -#### PCL5c commands -# These are organized by chapter # in the PCL 5 Color Technical Reference -# Manual. - -# Chapter 5 -$(PCLOBJ)pccprint.$(OBJ): $(PCLSRC)pccprint.c \ - $(std_h) \ - $(pcommand_h) \ - $(pcstate_h) \ - $(pcfont_h) \ - $(gsmatrix_h) \ - $(gsstate_h) \ - $(gsrop_h) - $(PCLCCC) $(PCLSRC)pccprint.c $(PCLO_)pccprint.$(OBJ) - -# Chapter 6 -# All of these are in rtgmode.c, but some of them are only registered -# in PCL5 mode. - -PCL5C_OPS = $(PCLOBJ)pccprint.$(OBJ) - -$(PCLOBJ)pcl5c.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL5C_OPS) \ - $(PCLOBJ)pcl5.dev $(PCLOBJ)rtlbasec.dev - $(SETMOD) $(PCLOBJ)pcl5c $(PCL5C_OPS) - $(ADDMOD) $(PCLOBJ)pcl5c -include $(PCLOBJ)pcl5 $(PCLOBJ)rtlbasec - $(ADDMOD) $(PCLOBJ)pcl5c -init pccprint rtgmode - -################ HP-GL/2 ################ - -pgdraw_h = $(PCLSRC)pgdraw.h - -pgfdata_h = $(PCLSRC)pgfdata.h - -pgfont_h = $(PCLSRC)pgfont.h - -pggeom_h = $(PCLSRC)pggeom.h \ - $(math__h) \ - $(gstypes_h) - -pginit_h = $(PCLSRC)pginit.h \ - $(gx_h) \ - $(pcstate_h) \ - $(pcommand_h) \ - $(pgmand_h) - -pgmisc_h = $(PCLSRC)pgmisc.h - -#### HP-GL/2 non-commands - -# Utilities - -$(PCLOBJ)pgdraw.$(OBJ): $(PCLSRC)pgdraw.c \ - $(stdio__h) \ - $(math__h) \ - $(gdebug_h) \ - $(gstypes_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(gscoord_h) \ - $(gspath_h) \ - $(gspaint_h) \ - $(gsrop_h) \ - $(gxfarith_h) \ - $(gxfixed_h) \ - $(pgmand_h) \ - $(pgdraw_h) \ - $(pggeom_h) \ - $(pgmisc_h) \ - $(pcdraw_h) \ - $(pcpalet_h) \ - $(pcpatrn_h) - $(PCLCCC) $(PCLSRC)pgdraw.c $(PCLO_)pgdraw.$(OBJ) - -$(PCLOBJ)pggeom.$(OBJ): $(PCLSRC)pggeom.c \ - $(stdio__h) \ - $(pggeom_h) \ - $(gxfarith_h) - $(PCLCCC) $(PCLSRC)pggeom.c $(PCLO_)pggeom.$(OBJ) - -$(PCLOBJ)pgmisc.$(OBJ): $(PCLSRC)pgmisc.c \ - $(pgmand_h) \ - $(pgmisc_h) - $(PCLCCC) $(PCLSRC)pgmisc.c $(PCLO_)pgmisc.$(OBJ) - -# Initialize/reset. We break this out simply because it's easier to keep -# track of it this way. - -$(PCLOBJ)pginit.$(OBJ): $(PCLSRC)pginit.c \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pgdraw_h) \ - $(pgmisc_h) \ - $(pcpatrn_h) - $(PCLCCC) $(PCLSRC)pginit.c $(PCLO_)pginit.$(OBJ) - -# Parsing and utilities - -$(PCLOBJ)pgparse.$(OBJ): $(PCLSRC)pgparse.c \ - $(AK) \ - $(math__h) \ - $(stdio__h) \ - $(gdebug_h) \ - $(gstypes_h) \ - $(scommon_h) \ - $(pgmand_h) - $(PCLCCC) $(PCLSRC)pgparse.c $(PCLO_)pgparse.$(OBJ) - -HPGL2_OTHER1 = $(PCLOBJ)pgdraw.$(OBJ) $(PCLOBJ)pggeom.$(OBJ) \ - $(PCLOBJ)pginit.$(OBJ) -HPGL2_OTHER2 = $(PCLOBJ)pgparse.$(OBJ) $(PCLOBJ)pgmisc.$(OBJ) -HPGL2_OTHER = $(HPGL2_OTHER1) $(HPGL2_OTHER2) - -#### HP-GL/2 commands -# These are organized by chapter # in the PCL 5 Technical Reference Manual. - -# Chapter 18 -# These are PCL commands, but are only relevant to HP RTL and/or HP-GL/2. -# Some of these are in rtmisc.c. -$(PCLOBJ)pgframe.$(OBJ): $(PCLSRC)pgframe.c \ - $(math__h) \ - $(pgmand_h) \ - $(pgdraw_h) \ - $(pgmisc_h) \ - $(gstypes_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(pcdraw_h) \ - $(pcfont_h) \ - $(pcstate_h) - $(PCLCCC) $(PCLSRC)pgframe.c $(PCLO_)pgframe.$(OBJ) - -# Chapter 19 -$(PCLOBJ)pgconfig.$(OBJ): $(PCLSRC)pgconfig.c \ - $(gx_h) \ - $(gsmatrix_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(gscoord_h) \ - $(pgmand_h) \ - $(pgdraw_h) \ - $(pginit_h) \ - $(pggeom_h) \ - $(pgmisc_h) \ - $(pcpalet_h) \ - $(pcdraw_h) - $(PCLCCC) $(PCLSRC)pgconfig.c $(PCLO_)pgconfig.$(OBJ) - -# Chapter 20 -$(PCLOBJ)pgvector.$(OBJ): $(PCLSRC)pgvector.c \ - $(stdio__h) \ - $(gdebug_h) \ - $(pcparse_h) \ - $(pgmand_h) \ - $(pggeom_h) \ - $(pgdraw_h) \ - $(pgmisc_h) \ - $(gspath_h) \ - $(gscoord_h) \ - $(math__h) - $(PCLCCC) $(PCLSRC)pgvector.c $(PCLO_)pgvector.$(OBJ) - -# Chapter 21 -$(PCLOBJ)pgpoly.$(OBJ): $(PCLSRC)pgpoly.c \ - $(std_h) \ - $(pcparse_h) \ - $(pgmand_h) \ - $(pgdraw_h) \ - $(pggeom_h) \ - $(pgmisc_h) \ - $(pcpatrn_h) - $(PCLCCC) $(PCLSRC)pgpoly.c $(PCLO_)pgpoly.$(OBJ) - -# Chapter 22 -$(PCLOBJ)pglfill.$(OBJ): $(PCLSRC)pglfill.c \ - $(memory__h) \ - $(pcparse_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pggeom_h) \ - $(pgdraw_h) \ - $(pgmisc_h) \ - $(pcdraw_h) \ - $(gsuid_h) \ - $(gstypes_h) \ - $(gsstate_h) \ - $(gsrop_h) \ - $(gxbitmap_h) \ - $(pcpalet_h) \ - $(pcpatrn_h) - $(PCLCCC) $(PCLSRC)pglfill.c $(PCLO_)pglfill.$(OBJ) - -# Chapter 23 -$(PCLOBJ)pgchar.$(OBJ): $(PCLSRC)pgchar.c \ - $(math__h) \ - $(stdio__h) \ - $(gdebug_h) \ - $(pgdraw_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pggeom_h) \ - $(pgmisc_h) \ - $(pcfsel_h) \ - $(pcpalet_h) - $(PCLCCC) $(PCLSRC)pgchar.c $(PCLO_)pgchar.$(OBJ) - -$(PCLOBJ)pglabel.$(OBJ): $(PCLSRC)pglabel.c \ - $(math__h) \ - $(memory__h) \ - $(ctype__h) \ - $(stdio__h) \ - $(gdebug_h) \ - $(plvalue_h) \ - $(pcparse_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pgfont_h) \ - $(pgdraw_h) \ - $(pggeom_h) \ - $(pgmisc_h) \ - $(pcfsel_h) \ - $(pcsymbol_h) \ - $(pcpalet_h) \ - $(pcdraw_h) \ - $(gscoord_h) \ - $(gsline_h) \ - $(gspath_h) \ - $(gsutil_h) \ - $(gxchar_h) \ - $(gxfont_h) \ - $(gxstate_h) - $(PCLCCC) $(PCLSRC)pglabel.c $(PCLO_)pglabel.$(OBJ) - -$(PCLOBJ)pgfdata.$(OBJ): $(PCLSRC)pgfdata.c \ - $(std_h) \ - $(gstypes_h) \ - $(gsccode_h) \ - $(gxarith_h) \ - $(pgfdata_h) \ - $(math__h) - $(PCLCCC) $(PCLSRC)pgfdata.c $(PCLO_)pgfdata.$(OBJ) - -$(PCLOBJ)pgfont.$(OBJ): $(PCLSRC)pgfont.c \ - $(math__h) \ - $(gstypes_h) \ - $(gsccode_h) \ - $(gsmemory_h) \ - $(gsstate_h) \ - $(gsmatrix_h) \ - $(gscoord_h) \ - $(gspaint_h) \ - $(gspath_h) \ - $(gxfixed_h) \ - $(gxchar_h) \ - $(gxfarith_h) \ - $(gxfont_h) \ - $(plfont_h) \ - $(pgfdata_h) \ - $(pgfont_h) - $(PCLCCC) $(PCLSRC)pgfont.c $(PCLO_)pgfont.$(OBJ) - -HPGL2_OPS1 = $(PCLOBJ)pgframe.$(OBJ) $(PCLOBJ)pgconfig.$(OBJ) \ - $(PCLOBJ)pgvector.$(OBJ) -HPGL2_OPS2 = $(PCLOBJ)pgpoly.$(OBJ) $(PCLOBJ)pglfill.$(OBJ) \ - $(PCLOBJ)pgchar.$(OBJ) -HPGL2_OPS3 = $(PCLOBJ)pglabel.$(OBJ) $(PCLOBJ)pgfdata.$(OBJ) \ - $(PCLOBJ)pgfont.$(OBJ) -HPGL2_OPS = $(HPGL2_OPS1) $(HPGL2_OPS2) $(HPGL2_OPS3) - -$(PCLOBJ)hpgl2.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL_COMMON) \ - $(HPGL2_OTHER) $(HPGL2_OPS) - $(SETMOD) $(PCLOBJ)hpgl2 $(PCL_COMMON) - $(ADDMOD) $(PCLOBJ)hpgl2 $(HPGL2_OTHER1) - $(ADDMOD) $(PCLOBJ)hpgl2 $(HPGL2_OTHER2) - $(ADDMOD) $(PCLOBJ)hpgl2 $(HPGL2_OPS1) - $(ADDMOD) $(PCLOBJ)hpgl2 $(HPGL2_OPS2) - $(ADDMOD) $(PCLOBJ)hpgl2 $(HPGL2_OPS3) - $(ADDMOD) $(PCLOBJ)hpgl2 -init pginit pgframe pgconfig pgvector - $(ADDMOD) $(PCLOBJ)hpgl2 -init pgpoly pglfill pgchar pglabel - -#### Color HP-GL/2 commands -# These correspond to chapter 7 in the PCL 5 Color Technical Reference -# Manual. - -$(PCLOBJ)pgcolor.$(OBJ): $(PCLSRC)pgcolor.c \ - $(std_h) \ - $(pgmand_h) \ - $(pginit_h) \ - $(pgmisc_h) \ - $(pgdraw_h) \ - $(gsstate_h) \ - $(pcpalet_h) - $(PCLCCC) $(PCLSRC)pgcolor.c $(PCLO_)pgcolor.$(OBJ) - -HPGL2C_OPS = $(PCLOBJ)pgcolor.$(OBJ) - -$(PCLOBJ)hpgl2c.dev: $(PCL_MAK) $(ECHOGS_XE) $(HPGL2C_OPS) $(PCLOBJ)hpgl2.dev - $(SETMOD) $(PCLOBJ)hpgl2c $(HPGL2C_OPS) - $(ADDMOD) $(PCLOBJ)hpgl2c -include $(PCLOBJ)hpgl2 - $(ADDMOD) $(PCLOBJ)hpgl2c -init pgcolor - diff --git a/pcl/pcl_msvc.mak b/pcl/pcl_msvc.mak deleted file mode 100644 index f0e59fd23..000000000 --- a/pcl/pcl_msvc.mak +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright (C) 1997 Aladdin Enterprises. All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# pcl_msvc.mak -# Top-level makefile for PCL5* on Win32 platforms using MS Visual C 4.1 or later - -# Define the name of this makefile. -!ifndef MAKEFILE -MAKEFILE=..\pcl\pcl_msvc.mak -!endif - -# The build process will put all of its output in this directory: -!ifndef GENDIR -GENDIR=..\pcl\obj -!endif - -# The sources are taken from these directories: -!ifndef GLSRCDIR -GLSRCDIR=..\gs\src -!endif -!ifndef PLSRCDIR -PLSRCDIR=..\pl -!endif -!ifndef PCLSRCDIR -PCLSRCDIR=..\pcl -!endif -!ifndef COMMONDIR -COMMONDIR=..\common -!endif -!ifndef JSRCDIR -JSRCDIR=..\gs\jpeg -JVERSION=6 -!endif -!ifndef PSRCDIR -PSRCDIR=..\gs\libpng -PVERSION=96 -!endif -!ifndef ZSRCDIR -ZSRCDIR=..\gs\zlib -!endif - - -# If you want to build the individual packages in their own directories, -# you can define this here, although normally you won't need to do this: -!ifndef GLGENDIR -GLGENDIR=$(GENDIR) -!endif -!ifndef GLOBJDIR -GLOBJDIR=$(GENDIR) -!endif -!ifndef PLGENDIR -PLGENDIR=$(GENDIR) -!endif -!ifndef PLOBJDIR -PLOBJDIR=$(GENDIR) -!endif -!ifndef PCLGENDIR -PCLGENDIR=$(GENDIR) -!endif -!ifndef PCLOBJDIR -PCLOBJDIR=$(GENDIR) -!endif - -!ifndef DD -DD=$(GLGENDIR)$(D) -!endif - -# Language and configuration. These are actually platform-independent, -# but we define them here just to keep all parameters in one place. -CONFIG=5 -TARGET_DEVS=$(PCLOBJDIR)$(D)pcl5c.dev $(PCLOBJDIR)$(D)hpgl2c.dev - -# Main file's name -MAIN_OBJ=$(PLOBJDIR)$(D)plmain.$(OBJ) $(PCLOBJDIR)$(D)pcimpl.$(OBJ) -TOP_OBJ=$(PCLOBJDIR)$(D)pctop.$(OBJ) - -# Executable path\name w/o the .EXE extension -!ifndef TARGET_XE -TARGET_XE=$(PCLOBJDIR)\pcl5 -!endif - -# Debugging options -!ifndef DEBUG -DEBUG=1 -!endif -!ifndef TDEBUG -TDEBUG=1 -!endif -!ifndef NOPRIVATE -NOPRIVATE=0 -!endif - -# Target options -!ifndef CPU_TYPE -CPU_TYPE=486 -!endif -!ifndef FPU_TYPE -FPU_TYPE=0 -!endif - -# Assorted definitions. Some of these should probably be factored out.... -!ifndef GS -GS=gs386 -!endif - -# Define which major version of MSVC is being used (currently, 4, 5, & 6 supported) -# default to the latest version -!ifndef MSVC_VERSION -MSVC_VERSION=6 -!endif - -!ifndef DEVICE_DEVS -DEVICE_DEVS= $(DD)djet500.dev\ - $(DD)ljet4.dev\ - $(DD)cljet5c.dev\ - $(DD)pcx16.dev\ - $(DD)pcx256.dev\ - $(DD)pcxmono.dev\ - $(DD)pcxcmyk.dev\ - $(DD)pcxgray.dev\ - $(DD)pbmraw.dev\ - $(DD)pgmraw.dev\ - $(DD)ppmraw.dev\ - $(DD)pkmraw.dev\ - $(DD)pxlmono.dev\ - $(DD)pxlcolor.dev\ - $(DD)tiffcrle.dev\ - $(DD)tiffg3.dev\ - $(DD)tiffg32d.dev\ - $(DD)tiffg4.dev\ - $(DD)tifflzw.dev\ - $(DD)tiffpack.dev\ - $(DD)tiff12nc.dev\ - $(DD)tiff24nc.dev -!endif - -# GS options -# Even though FEATURE_DEVS is defined in pcl_top.mak, define identically here -# for msvc_top.mak because nmake defines macros eagerly (i.e. here & now). -FEATURE_DEVS = $(DD)dps2lib.dev \ - $(DD)path1lib.dev \ - $(DD)patlib.dev \ - $(DD)rld.dev \ - $(DD)roplib.dev \ - $(DD)ttflib.dev \ - $(DD)colimlib.dev \ - $(DD)cielib.dev \ - $(DD)htxlib.dev \ - $(DD)devcmap.dev \ - $(DD)gsnogc.dev - -!include $(COMMONDIR)\msvc_top.mak - -# Subsystems -!include $(PLSRCDIR)\pl.mak -!include $(PCLSRCDIR)\pcl.mak - -# Main program. -!include $(PCLSRCDIR)\pcl_top.mak - diff --git a/pcl/pcl_sgi.mak b/pcl/pcl_sgi.mak deleted file mode 100644 index 970371ba8..000000000 --- a/pcl/pcl_sgi.mak +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# pcl_sgi.mak -# Top-level makefile for PCL5* on Silicon Graphics Irix 6.x platforms. - -# Directories -GLSRCDIR = ../gs535 -GLGENDIR = $(GLSRCDIR) -GLOBJDIR = $(GLSRCDIR) - -PLSRCDIR = ../pl -PLGENDIR = $(PLSRCDIR) -PLOBJDIR = $(PLSRCDIR) - -PCLSRCDIR = ../pcl_new -PCLGENDIR = $(PCLSRCDIR) -PCLOBJDIR = $(PCLSRCDIR) -GENDIR = $(PCLSRCDIR) - -COMMONDIR = ../common - -# Define the name of this makefile. -MAKEFILE = $(PCLSRCDIR)/pcl_sgi.mak - -# Language and configuration. These are actually platform-independent, -# but we define them here just to keep all parameters in one place. -CONFIG = 5 -TARGET_DEVS = $(PCLOBJDIR)/pcl5c.dev $(PCLOBJDIR)/hpgl2c.dev -TARGET_XE = pcl5 -MAIN_OBJ = $(PLOBJDIR)/plmain.$(OBJ) $(PCLOBJDIR)/pcimpl.$(OBJ) -TOP_OBJ = $(PCLOBJDIR)/pctop.$(OBJ) - -# Assorted definitions. Some of these should probably be factored out.... -# -# -woff turns off specific warnings: -# -# 1174 - unused function parameter -# -# 1209 - constant value for control expression -# -# 1506 - loss of precision on implicit rounding -# -CDEFS = -DSYSV -XCFLAGS = -SGICFLAGS = -mips4 -n32 -fullwarn -woff 1506 -woff 1174 -woff 1209 -CFLAGS = -g $(CDEFS) $(SGICFLAGS) $(XCFLAGS) -LDFLAGS = -n32 -mips4 $(XLDFLAGS) -EXTRALIBS = -XINCLUDE = -I/usr/include -XLIBDIRS = -XLIBDIR = -XLIBS = Xt SM ICE X11 - -CCLD = cc - -DEVICE_DEVS = $(DD)x11mono.dev \ - $(DD)x11.dev \ - $(DD)x11alpha.dev \ - $(DD)x11cmyk.dev \ - $(DD)ljet4.dev \ - $(DD)paintjet.dev \ - $(DD)cljet.dev \ - $(DD)pbmraw.dev - -# Generic makefile -include $(COMMONDIR)/sgi_top.mak - -# Subsystems -include $(PLSRCDIR)/pl.mak -include $(PCLSRCDIR)/pcl.mak - -# Main program. -include $(PCLSRCDIR)/pcl_top.mak diff --git a/pcl/pcl_top.mak b/pcl/pcl_top.mak deleted file mode 100644 index 235757b81..000000000 --- a/pcl/pcl_top.mak +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 1997 Aladdin Enterprises. All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# pcl_top.mak -# Top-level platform-independent makefile for PCL5* et al - -# This file must be preceded by pcl.mak. - -default: $(TARGET_XE)$(XE) - @echo Done. - -clean: config-clean clean-not-config-clean - -clean-not-config-clean: pl.clean-not-config-clean pcl.clean-not-config-clean - $(RM_) $(TARGET_XE)$(XE) - -config-clean: pl.config-clean pcl.config-clean - $(RMN_) *.tr $(GD)devs.tr $(GD)ld.tr - $(RMN_) $(PCLGEN)pconf.h $(PCLGEN)pconfig.h - $(RM_) $(PCLSRC)pclver.h - -#### Implementation stub - -$(PCLOBJ)pcimpl.$(OBJ): $(PCLSRC)pcimpl.c \ - $(AK) \ - $(memory__h) \ - $(scommon_h) \ - $(gxdevice_h) \ - $(pltop_h) - $(PCLCCC) $(PCLSRC)pcimpl.c $(PCLO_)pcimpl.$(OBJ) diff --git a/pcl/pcl_ugcc.mak b/pcl/pcl_ugcc.mak deleted file mode 100644 index 528a013c2..000000000 --- a/pcl/pcl_ugcc.mak +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# pcl_ugcc.mak -# Top-level makefile for PCL5* on Unix/gcc platforms. - -# Define the name of this makefile. -MAKEFILE=../pcl/pcl_ugcc.mak - -# The build process will put all of its output in this directory: -GENDIR=./obj - -# The sources are taken from these directories: -GLSRCDIR=../gs/src -PLSRCDIR=../pl -PCLSRCDIR=../pcl -COMMONDIR=../common - -# If you want to build the individual packages in their own directories, -# you can define this here, although normally you won't need to do this: -GLGENDIR=$(GENDIR) -GLOBJDIR=$(GENDIR) -PLGENDIR=$(GENDIR) -PLOBJDIR=$(GENDIR) -PCLGENDIR=$(GENDIR) -PCLOBJDIR=$(GENDIR) - -# Language and configuration. These are actually platform-independent, -# but we define them here just to keep all parameters in one place. -CONFIG=5 -TARGET_DEVS=$(PCLOBJDIR)/pcl5c.dev $(PCLOBJDIR)/hpgl2c.dev -TARGET_XE=$(PCLOBJDIR)/pcl5 -MAIN_OBJ=$(PLOBJDIR)/plmain.$(OBJ) $(PCLOBJDIR)/pcimpl.$(OBJ) -TOP_OBJ=$(PCLOBJDIR)/pctop.$(OBJ) - -# specify the location of zlib. We use zlib for bandlist compression. -ZSRCDIR=../gs/zlib -ZGENDIR=$(GENDIR) -ZOBJDIR=$(GENDIR) -SHARE_ZLIB=0 - -JSRCDIR=../gs/jpeg -JGENDIR=$(GENDIR) -JOBJDIR=$(GENDIR) - -# Assorted definitions. Some of these should probably be factored out.... -# We use -O0 for debugging, because optimization confuses gdb. -#GCFLAGS=-Wall -Wcast-qual -Wpointer-arith -Wstrict-prototypes -Wwrite-strings -GCFLAGS=-Wall -Wpointer-arith -Wstrict-prototypes -Wcast-align -CFLAGS=-g -O0 $(GCFLAGS) $(XCFLAGS) -LDFLAGS=$(XLDFLAGS) -EXTRALIBS= -XINCLUDE=-I/usr/local/X/include -XLIBDIRS=-L/usr/X11/lib -XLIBDIR= -XLIBS=Xt SM ICE Xext X11 - -CCLD=gcc - -DD='$(GLGENDIR)$(D)' -DEVICE_DEVS=$(DD)x11mono.dev $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev\ - $(DD)djet500.dev $(DD)ljet4.dev $(DD)cljet5pr.dev $(DD)cljet5c.dev\ - $(DD)pcx16.dev $(DD)pcx256.dev\ - $(DD)pcxmono.dev $(DD)pcxcmyk.dev $(DD)pcxgray.dev\ - $(DD)pbmraw.dev $(DD)pgmraw.dev $(DD)ppmraw.dev $(DD)pkmraw.dev\ - $(DD)pxlmono.dev $(DD)pxlcolor.dev\ - $(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev\ - $(DD)tifflzw.dev $(DD)tiffpack.dev\ - $(DD)tiff12nc.dev $(DD)tiff24nc.dev\ - $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev \ - $(DD)jpeg.dev \ - $(DD)bmpmono.dev $(DD)bmpamono.dev $(DD)bmpa16m.dev $(DD)bmpa32b.dev - -FEATURE_DEVS = $(DD)dps2lib.dev \ - $(DD)path1lib.dev \ - $(DD)patlib.dev \ - $(DD)rld.dev \ - $(DD)roplib.dev \ - $(DD)ttflib.dev \ - $(DD)colimlib.dev \ - $(DD)cielib.dev \ - $(DD)htxlib.dev \ - $(DD)pipe.dev \ - $(DD)devcmap.dev \ - $(DD)gsnogc.dev - -# posync for most unix variants bsd needs fbsdsync. -SYNC=posync - -# Generic makefile -include $(COMMONDIR)/ugcc_top.mak - -# Subsystems -include $(PLSRCDIR)/pl.mak -include $(PCLSRCDIR)/pcl.mak - -# Main program. -include $(PCLSRCDIR)/pcl_top.mak diff --git a/pcl/pcl_watc.mak b/pcl/pcl_watc.mak deleted file mode 100644 index b51a38db7..000000000 --- a/pcl/pcl_watc.mak +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. -# Unauthorized use, copying, and/or distribution prohibited. - -# pcl_watc.mak -# Top-level makefile for PCL5* on MS-DOS/Watcom platforms. - -# The build process will put all of its output in this directory: -!ifndef GENDIR -GENDIR=..\pcl\obj -!endif - -# The sources are taken from these directories: -!ifndef GLSRCDIR -GLSRCDIR=..\gs\src -!endif -!ifndef PLSRCDIR -PLSRCDIR=..\pl -!endif -!ifndef PCLSRCDIR -PCLSRCDIR=..\pcl -!endif -!ifndef COMMONDIR -COMMONDIR=..\common -!endif -!ifndef JSRCDIR -JSRCDIR=..\gs\jpeg -JVERSION=6 -!endif -!ifndef PSRCDIR -PSRCDIR=..\gs\libpng -PVERSION=96 -!endif -!ifndef ZSRCDIR -ZSRCDIR=..\gs\zlib -!endif - - -# If you want to build the individual packages in their own directories, -# you can define this here, although normally you won't need to do this: -!ifndef GLGENDIR -GLGENDIR=$(GENDIR) -!endif -!ifndef GLOBJDIR -GLOBJDIR=$(GENDIR) -!endif -!ifndef PSGENDIR -PSGENDIR=$(GENDIR) -!endif -!ifndef PSOBJDIR -PSOBJDIR=$(GENDIR) -!endif -!ifndef PLGENDIR -PLGENDIR=$(GENDIR) -!endif -!ifndef PLOBJDIR -PLOBJDIR=$(GENDIR) -!endif -!ifndef PCLGENDIR -PCLGENDIR=$(GENDIR) -!endif -!ifndef PCLOBJDIR -PCLOBJDIR=$(GENDIR) -!endif -!ifndef DD -DD=$(GLGENDIR)$(D) -!endif - -# Define the name of this makefile. -MAKEFILE=$(PCLSRCDIR)\pcl_watc.mak - -# Language and configuration. These are actually platform-independent, -# but we define them here just to keep all parameters in one place. -TARGET_DEVS=$(PCLOBJDIR)$(D)pcl5c.dev $(PCLOBJDIR)$(D)hpgl2c.dev - -# Main file's name -MAIN_OBJ=FILE $(PLOBJDIR)$(D)plmain.$(OBJ) FILE $(PCLOBJDIR)$(D)pcimpl.$(OBJ) -TOP_OBJ=FILE $(PCLOBJDIR)$(D)pctop.$(OBJ) - -# Executable path\name w/o the .EXE extension -!ifndef TARGET_XE -TARGET_XE=$(PCLOBJDIR)\pcl5 -!endif - -# Debugging options -!ifndef DEBUG -DEBUG=0 -!endif -!ifndef TDEBUG -TDEBUG=0 -!endif -!ifndef NOPRIVATE -NOPRIVATE=0 -!endif - -# Target options -!ifndef CPU_TYPE -CPU_TYPE=586 -!endif -!ifndef FPU_TYPE -FPU_TYPE=0 -!endif - -# Assorted definitions. Some of these should probably be factored out.... -WCVERSION=10.695 - -# For building on 16 bit platforms (which may not work anymore) use 'wmakel' -MAKE=wmake - -!ifndef DEVICE_DEVS -DEVICE_DEVS=$(DD)ljet4.dev\ - $(DD)pkmraw.dev $(DD)ppmraw.dev $(DD)pgmraw.dev $(DD)pbmraw.dev\ - $(DD)pcx16.dev $(DD)pcx256.dev $(DD)bitcmyk.dev\ - $(DD)cljet5.dev $(DD)ljet4.dev\ - $(DD)pcxmono.dev $(DD)pcxcmyk.dev $(DD)pcxgray.dev\ - $(DD)pbmraw.dev $(DD)pgmraw.dev $(DD)ppmraw.dev $(DD)pkmraw.dev\ - $(DD)pxlmono.dev $(DD)pxlcolor.dev\ - $(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev\ - $(DD)tifflzw.dev $(DD)tiffpack.dev\ - $(DD)tiff12nc.dev $(DD)tiff24nc.dev \ - $(DD)bmpamono.dev $(DD)bmpa16m.dev $(DD)bmpmono.dev $(DD)bmp16m.dev -# $(DD)bmpmono.dev $(DD)bmp16m.dev -!endif -# Generic makefile - -# GS options -#DEVICE_DEVS is defined in the platform-specific file. -FEATURE_DEVS = $(DD)dps2lib.dev \ - $(DD)path1lib.dev \ - $(DD)patlib.dev \ - $(DD)rld.dev \ - $(DD)roplib.dev \ - $(DD)ttflib.dev \ - $(DD)colimlib.dev \ - $(DD)cielib.dev \ - $(DD)htxlib.dev \ - $(DD)devcmap.dev \ - $(DD)gsnogc.dev - -# make sure the target directories exist - use special Watcom .BEFORE -.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) - -!include $(COMMONDIR)\watc_top.mak - -# Subsystems -!include $(PLSRCDIR)\pl.mak -!include $(PCLSRCDIR)\pcl.mak - -# Main program. -!include $(PCLSRCDIR)\pcl_top.mak diff --git a/pcl/pclfont.c b/pcl/pclfont.c deleted file mode 100644 index b1a40a1e1..000000000 --- a/pcl/pclfont.c +++ /dev/null @@ -1,256 +0,0 @@ -/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. - * Unauthorized use, copying, and/or distribution prohibited. - */ - -/* pclfont.c */ -/* PCL5 font preloading */ -#include "stdio_.h" -#include "string_.h" -/* The following are all for gxfont42.h, except for gp.h. */ -#include "gx.h" -#include "gp.h" -#include "gsccode.h" -#include "gsmatrix.h" -#include "gsutil.h" -#include "gxfont.h" -#include "gxfont42.h" -#include "pcommand.h" -#include "pcstate.h" - -/* Load some built-in fonts. This must be done at initialization time, but - * after the state and memory are set up. Return an indication of whether - * at least one font was successfully loaded. XXX The existing code is more - * than a bit of a hack. Approach: expect to find some fonts in one or more - * of a given list of directories with names *.ttf. Load whichever ones are - * found in the table below. Probably very little of this code can be - * salvaged for later. - */ - - int -pcl_load_built_in_fonts(pcl_state_t *pcs, const char *pathname) -{ - typedef struct font_resident { - const char *ext_name; - pl_font_params_t params; - byte character_complement[8]; - /* a ridiculous hack because somebody thought this was a font solution... */ - } font_resident_t; - static const font_resident_t resident_table[] = { - /* - * Symbol sets, typeface family values, and character complements - * are faked; they do not (necessarily) match the actual fonts. */ -#define C(b) ((byte)((b) ^ 0xff)) -#define cc_alphabetic\ - { C(0), C(0), C(0), C(0), C(0xff), C(0xc0), C(0), C(plgv_Unicode) } -#define cc_symbol\ - { C(0), C(0), C(0), C(4), C(0), C(0), C(0), C(plgv_MSL) } -#define cc_dingbats\ - { C(0), C(0), C(0), C(1), C(0), C(0), C(0), C(plgv_MSL) } -#define pitch_1 fp_pitch_value_cp(1) - /* - * Per TRM 23-87, PCL5 printers are supposed to have Univers - * and CG Times fonts. Substitute Arial for Univers and - * Times for CG Times. - */ - /* hack the vendor value to be agfa's. */ -#define agfa (4096) - /* the actual typeface number is vendor + base value. Base - values are found in the pcl 5 Comparison guide - Appendix - C-6. We can add a parameter for vendor if necessary, for - now it is agfa. */ -#define face_val(base_value, vendor) (vendor + (base_value)) - /* definition for style word as defined on 11-19 PCLTRM */ -#define style_word(posture, width, structure) \ - ((posture) + (4 * (width)) + (32 * (structure))) - {"letri", {0, 0, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(6, agfa)}, cc_alphabetic}, - {"letrbi", {0, 0, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(6, agfa)}, cc_alphabetic}, - {"letrb", {0, 0, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(6, agfa)}, cc_alphabetic}, - {"letr", {0, 0, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(6, agfa)}, cc_alphabetic }, - {"courbi", {0, 0, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(3, agfa)}, cc_alphabetic}, - {"couri", {0, 0, pitch_1, 0, style_word(1, 0, 0), - 0, face_val(3, agfa)}, cc_alphabetic }, - {"courbd", {0, 0, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(3, agfa)}, cc_alphabetic }, - {"cour", {0, 0, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(3, agfa)}, cc_alphabetic}, - /* Note that "bound" TrueType fonts are indexed starting at 0xf000, */ - /* not at 0. */ - {"wingding", {18540, 1, pitch_1,0, style_word(0, 0, 0), 0, - face_val(2730, agfa)}, cc_dingbats}, - {"symbol", {621, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(302, agfa)}, cc_symbol}, - {"timesbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(517, agfa)}, cc_alphabetic}, - {"timesi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(517, agfa)}, cc_alphabetic}, - {"timesbd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(517, agfa)}, cc_alphabetic}, - {"times", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(517, agfa)}, cc_alphabetic}, - {"arialbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(218, agfa)}, cc_alphabetic}, - {"ariali", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(218, agfa)}, cc_alphabetic}, - {"arialbd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(218, agfa)}, cc_alphabetic}, - {"arial", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(218, agfa)}, cc_alphabetic}, - {"albrmdi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(266, agfa)}, cc_alphabetic}, - {"albrxb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 4, - face_val(266, agfa)}, cc_alphabetic}, - {"albrmd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 1, - face_val(266, agfa)}, cc_alphabetic}, - {"mari", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(201, agfa)}, cc_alphabetic}, - {"garrkh", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(101, agfa)}, cc_alphabetic}, - {"garak", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(101, agfa)}, cc_alphabetic}, - {"garrah", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(101, agfa)}, cc_alphabetic}, - {"garaa", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(101, agfa)}, cc_alphabetic}, - {"antoi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(72, agfa)}, cc_alphabetic}, - {"antob", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(72, agfa)}, cc_alphabetic}, - {"anto", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(72, agfa)}, cc_alphabetic }, - {"univcbi", {0, 1, pitch_1, 0, style_word(1, 1, 0), 3, - face_val(52, agfa)}, cc_alphabetic}, - {"univmci", {0, 1, pitch_1, 0, style_word(1, 1, 0), 0, - face_val(52, agfa)}, cc_alphabetic}, - {"univcb", {0, 1, pitch_1, 0, style_word(0, 1, 0), 3, - face_val(52, agfa)}, cc_alphabetic}, - {"univmc", {0, 1, pitch_1, 0, style_word(0, 1, 0), 0, - face_val(52, agfa)}, cc_alphabetic}, - {"univbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(52, agfa)}, cc_alphabetic}, - {"univmi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(52, agfa)}, cc_alphabetic}, - {"univb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(52, agfa)}, cc_alphabetic}, - {"univm", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(52, agfa)}, cc_alphabetic }, - {"clarbc", {0, 1, pitch_1, 0, style_word(0, 1, 0), 3, - face_val(44, agfa)}, cc_alphabetic}, - {"coro", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(20, agfa)}, cc_alphabetic}, - {"cgombi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(17, agfa)}, cc_alphabetic}, - {"cgomi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(17, agfa)}, cc_alphabetic}, - {"cgomb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(17, agfa)}, cc_alphabetic}, - {"cgom", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(17, agfa)}, cc_alphabetic}, - {"cgtibi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, - face_val(5, agfa)}, cc_alphabetic}, - {"cgtii", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, - face_val(5, agfa)}, cc_alphabetic}, - {"cgtib", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, - face_val(5, agfa)}, cc_alphabetic}, - {"cgti", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, - face_val(5, agfa)}, cc_alphabetic}, - {NULL, {0, 0, pitch_1, 0, 0, 0, 0} } -#undef C -#undef cc_alphabetic -#undef cc_symbol -#undef cc_dingbats -#undef pitch_1 -#undef agfa_value -#undef face_val - }; - const font_resident_t *residentp; - pl_font_t *font_found[countof(resident_table)]; - bool found_some = false; - byte key[3]; - - if ( pathname == NULL ) { - /* no font pathname */ - return 0; - } - /* don't load fonts more than once */ - if (pl_dict_length(&pcs->built_in_fonts, true) > 0 ) - return true; - /* Load only those fonts we know about. */ - memset(font_found, 0, sizeof(font_found)); - /* We use a 3-byte key so the built-in fonts don't have */ - /* IDs that could conflict with user-defined ones. */ - key[0] = key[1] = key[2] = 0; - for ( residentp = resident_table; residentp->ext_name != 0; ++residentp ) - if ( !font_found[residentp - resident_table] ) { - char fname[150]; - FILE *fnp; - pl_font_t *plfont; - if ( pathname != NULL ) { - strcpy(fname, pathname); - strcat(fname, residentp->ext_name); - } else - strcpy(fname, residentp->ext_name); - strcat(fname, ".ttf"); - if ( (fnp=fopen(fname, gp_fmode_rb)) == NULL ) - continue; - if ( pl_load_tt_font(fnp, pcs->font_dir, pcs->memory, - gs_next_ids(1), &plfont) < 0 ) { -#ifdef DEBUG - lprintf1("Failed loading font %s\n", fname); -#endif - continue; - } - plfont->storage = pcds_internal; - plfont->data_are_permanent = false; - if ( residentp->params.symbol_set != 0 ) - plfont->font_type = plft_8bit; - /* - * Don't smash the pitch, which was obtained - * from the actual font. - */ - { - pl_font_pitch_t save_pitch; - save_pitch = plfont->params.pitch; - plfont->params = residentp->params; - plfont->params.pitch = save_pitch; - } - memcpy(plfont->character_complement, - residentp->character_complement, 8); - plfont->params.pjl_font_number = pjl_proc_get_pcl_internal_font_number(pcs->pjls, residentp->ext_name); - pl_dict_put(&pcs->built_in_fonts, key, sizeof(key), plfont); - key[sizeof(key) - 1]++; - font_found[residentp - resident_table] = plfont; - found_some = true; - } -#ifdef DEBUG - /* check that we have loaded everything in the resident font table */ - { - int i; - for (i=0; resident_table[i].ext_name != 0; i++) - if ( !font_found[i] ) - dprintf1( "Could not load resident font: %s\n", - resident_table[i].ext_name ); - } -#endif - return found_some; -} - -/* These are not implemented */ - -/* load simm fonts given a path */ - int -pcl_load_simm_fonts(pcl_state_t *pcs, const char *pathname) -{ - return 0; -} - -/* load simm fonts given a path */ - int -pcl_load_cartridge_fonts(pcl_state_t *pcs, const char *pathname) -{ - return 0; -} diff --git a/pcl/pclookup.c b/pcl/pclookup.c deleted file mode 100644 index 2be49cd97..000000000 --- a/pcl/pclookup.c +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pclookup.c - color lookup table implementation for PCL 5c */ - -#include "pcpalet.h" -#include "pclookup.h" - -/* GC routines */ -private_st_lookup_tbl_t(); - -/* - * Free lookup table. - */ - private void -free_lookup_tbl( - gs_memory_t * pmem, - void * pvlktbl, - client_name_t cname -) -{ - pcl_lookup_tbl_t * plktbl = (pcl_lookup_tbl_t *)pvlktbl; - - if (plktbl->ptbl != 0) - gs_free_object(pmem, (void *)plktbl->ptbl, cname); - gs_free_object(pmem, pvlktbl, cname); -} - -/* - * ESC * l <nbytes> W - * - * Set color lookup table. - */ - private int -set_lookup_tbl( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint len = uint_arg(pargs); - pcl_lookup_tbl_t * plktbl = 0; - pcl__lookup_tbl_t * ptbl = 0; - int code = 0; - - /* check for clearing of lookup tables, and for incorrect size */ - if (len == 0) - return pcl_palette_set_lookup_tbl(pcs, NULL); - else if (len != sizeof(pcl__lookup_tbl_t)) - return e_Range; - - rc_alloc_struct_1( plktbl, - pcl_lookup_tbl_t, - &st_lookup_tbl_t, - pcs->memory, - return e_Memory, - "set color lookup table" - ); - plktbl->rc.free = free_lookup_tbl; - plktbl->ptbl = 0; - - /* either take possession of buffer, or allocate a new one */ - if (pargs->data_on_heap) { - ptbl = (pcl__lookup_tbl_t *)arg_data(pargs); - arg_data(pargs) = 0; - } else { - ptbl = (pcl__lookup_tbl_t *)gs_alloc_bytes( pcs->memory, - sizeof(pcl__lookup_tbl_t), - "set color lookup table" - ); - if (ptbl == 0) { - free_lookup_tbl(plktbl->rc.memory, plktbl, "set color lookup table"); - return e_Memory; - } - memcpy(ptbl, arg_data(pargs), sizeof(pcl__lookup_tbl_t)); - } - plktbl->ptbl = ptbl; - - /* for the CMY color space, convert to RGB color space */ - if (pcl_lookup_tbl_get_cspace(plktbl) == pcl_cspace_CMY) { - int i; - - for (i = 0; i < 128; i++) { - byte b1 = ptbl->data[i]; - byte b2 = ptbl->data[255 - i]; - - ptbl->data[i] = 255 - b2; - ptbl->data[255 - i] = 255 - b1; - } - ptbl->cspace = (byte)pcl_cspace_RGB; - } - - /* update the current palette; release our reference to the lookup table */ - code = pcl_palette_set_lookup_tbl(pcs, plktbl); - pcl_lookup_tbl_release(plktbl); - return code; -} - -/* - * ESC * t # I - * - * Set gamma correction - */ - private int -set_gamma_correction( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - float gamma = float_arg(pargs); - - if ((gamma < 0.0) || (gamma > (float)((1L << 15) - 1))) - return 0; - else - return pcl_palette_set_gamma(pcs, gamma); -} - -/* - * There is no copy or reset code for this module, as both copying and reset - * are handled by the PCL palette module (using macros defined in pclookup.h). - */ - private int -lookup_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ -#ifndef PCL5EMONO - DEFINE_CLASS('*') - { - 'l', 'W', - PCL_COMMAND("Color Lookup Tables", set_lookup_tbl, pca_bytes) - }, - { - 't', 'I', - PCL_COMMAND( "Gamma Correction", - set_gamma_correction, - pca_neg_ignore | pca_big_ignore - ) - }, - END_CLASS -#endif - return 0; -} - -const pcl_init_t pcl_lookup_tbl_init = { lookup_do_registration, 0, 0 }; diff --git a/pcl/pclookup.h b/pcl/pclookup.h deleted file mode 100644 index 1c8111309..000000000 --- a/pcl/pclookup.h +++ /dev/null @@ -1,207 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pclookup.h - color lookup table structure for PCL 5c */ - -#ifndef pclookup_INCLUDED -#define pclookup_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "pcommand.h" -#include "pccid.h" - -/* - * Though straightforward in principle, the color lookup table feature in - * PCL 5c is made complicated due to its development history. Specifically, - * while all PCL color lookup tables are involved in color mapping, the - * nature of the mapping desired varies with each color space. - * - * 1. For the device specific color spaces (RGB and CMY), the color lookup - * table is a generalization of the gamma correction feature. Thus: - * - * RGB and CMY color lookup tables override gamma correction, - * and vice-versa. - * - * The index value to an RGB or CMY lookup table is formed from the - * post-normalization input intensity. In the 4-bit/pixel case with - * the canonical white and black points, the input value 7 would - * select the color rendering table entry with index in the range - * [119, 136], not the entry with index 7. - * - * In addition, the RGB and CMY color spaces in PCL are not really - * different spaces, but the same space with white and black points - * reversed. Hence, the two lookup tables are also the same, but the - * latter is modified to work in an additive space: - * - * tbl_rgb[i] = 255 - tbl_cmy[255 - i] - * - * Note also that the gamma correction parameter is always interpreted - * in an additive space: gamma1 > gamma2 implies all colors rendered - * using gamma1 will be lighter (or possibly the same as) the - * corresponding color rendered with gamma2. - * - * 2. The lookup tables for the device independent color spaces are not - * generalizations for gamma correction and are intended to be used - * with gamma correction, and thus with the device-specific color - * space lookup functions. - * - * The canonical ranges for the device independent color space components - * do not fit neatly into the [0, 255] range used by lookup tables, the - * image encoding, etc. PCL handles this problem by requiring that device - * independent color components be normalized by the application. Exactly - * what HP expects in these circumstances is not known, and does not - * seem to be implemented correctly on the CLJ 5/5M; this implementation - * will always assume that 0 corresponds to the minimum value and 255 to - * the maximum (for device independent color space components only; device - * dependent color space components are handled differently). - * - * For the purposes of color lookup tables, this arrangement implies that - * for device independent color spaces, the raw input value (rounded - * to an integer) is used as an index to the color rendering table, - * without applying any normalization. - * - * 3. PCL allows a given palette to have multiple color lookup tables, as - * many as 4. Each color lookup table is associated with a color space, - * selected from the five supported color spaces. - * - * There are more color spaces than color lookup tables that may be - * attached to a palette because the two device specific color spaces - * use the same color lookup table (which is also used by gamma correction). - * Associating a color lookup table with the RGB color space as opposed - * to the CMY color space only alters the way its entries are interpreted, - * using the equation given in Item (1) above. - * - * HP's documentation implies that multiple device independent color lookup - * tables may be used for the same device independent color space. - * Unfortunately, while testing shows that multiple such tables are used, - * there is no consistency in their use. Furthermore, it is not entirely - * obvious how to use a CIE L*a*b* lookup table with a luminance-chrominance - * color space. - * - * This implementation tries to achieve the most reasonable interpretation - * of device independent color spaces that might actually be useful: - * - * The colorimetric RGB color space uses only the colorimetric - * lookup table - * - * The CIE L*a*b* color space uses only the L*a*b* lookup table - * - * The luminance-chrominance color space uses both the luminance- - * chrominance color lookup table and the colorimetric RGB - * color lookup table. - * - * All of these spaces also use the device-dependent color lookup table. - * - * 4. A color lookup table applies when a color is USED, not when it is - * entered into the palette. This is a critical consideration from the - * point of view of an implementation, as it requires that the client- - * provided color values must be stored in the palette (possibly normalized - * in the case of device-specific color spaces). - * - * 5. Though gamma correction and color lookup tables for device specific - * color spaces overwrite each other, the former is inherited by a new - * palette from the current active palette, but the latter is not (all - * color lookup tables are cleared by the configure image data command). - * - * The following text appears in HP's "PCL 5 Color Technical Reference - * Manual" (May, 1996 edition (part no. 5961-0940), p. 4-16: - * - * Gamma correction is referred to in terms of device-dependent - * RGB. This command does not destroy the contents of the device- - * dependent color lookup tables, but setting a gamma value - * supercedes any lookup table input in either Device CMY or - * Device RGB - * - * The significance of the statement "does not destroy" is difficult - * to determine, as color lookup tables are not inherited and there is - * no way to "turn-off" gamma correction (setting the gamma value to - * 0 is equivalent to setting it to 1.0, and results in the unity - * map being used). Consequently, in this implementation setting a - * gamma correction discards the current device-specific color lookup - * table (if one is present). - */ - -/* - * Raw color lookup tables. Though color lookup tables exist for each color - * space, the one for the two device-dependent color spaces is the same, and - * is also the lookup table used for gamma correction. This lookup table is - * implemented via transfer functions. - * - * This structure should only be accessed via the pcl_lookup_t structure. - * - * Note: this structure is defined by HP. - */ -typedef struct pcl__lookup_tbl_s { - byte cspace; /* actually pcl_cspace_type_t */ - byte dummy; - byte data[3 * 256]; -} pcl__lookup_tbl_t; - -/* - * The pcl_lookup_t structure provides a reference-count header for a lookup - * table. This is necessary because there is a way that lookup tables can - * shared between PCL base color spaces (this could occur in the case of a - * luminance-chrominance color space, which might have an instantiation with - * two color tables that shares one of these color tables with another - * instantiation). - */ -typedef struct pcl_lookup_tbl_s { - rc_header rc; - const pcl__lookup_tbl_t * ptbl; -} pcl_lookup_tbl_t; - -#define private_st_lookup_tbl_t() \ - gs_private_st_ptrs1( st_lookup_tbl_t, \ - pcl_lookup_tbl_t, \ - "pcl color lookup table", \ - lookup_enum_ptr, \ - lookup_reloc_ptr, \ - ptbl \ - ) - -/* - * Copy, init, and release macros. - */ -#define pcl_lookup_tbl_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_lookup_tbl_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_lookup_tbl_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_lookup_tbl_release(plktbl) \ - rc_decrement(plktbl, "pcl_lookup_tbl_release") - -/* - * Get the color space type of a lookup table. - */ -#define pcl_lookup_tbl_get_cspace(plktbl) \ - ((pcl_cspace_type_t)((plktbl)->ptbl->cspace)) - -/* - * Macro to retrieve a single-component color table pointer from a - * pcl_lookup_hdr_t pointer. - * - * This macro is provided in preference to a conversion macro because the - * transfer function objects require a table. - */ -#define pcl_lookup_tbl_get_tbl(plktbl, indx) \ - ( (plktbl) != 0 ? (plktbl)->ptbl->data + (indx) * 256 : 0 ) - -/* - * External access to the color lookup table/gamma correction code. - */ -extern const pcl_init_t pcl_lookup_tbl_init; - -#endif /* pclookup_INCLUDED */ diff --git a/pcl/pcmacros.c b/pcl/pcmacros.c deleted file mode 100644 index a7e55161b..000000000 --- a/pcl/pcmacros.c +++ /dev/null @@ -1,258 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. - Unauthorized use, copying, and/or distribution prohibited. - */ - -/* pcmacros.c */ -/* PCL5 macro commands */ -#include "stdio_.h" /* std.h + NULL */ -#include "pcommand.h" -#include "pgmand.h" -#include "pcstate.h" -#include "pcparse.h" - -/* ---------------- Macro execution ---------------- */ - -/* Execute a macro. We're willing to use C recursion for this because */ -/* the PCL5 specification only allows 2 levels of call. */ -private int -do_copies(pcl_state_t *psaved, pcl_state_t *pcs, - pcl_copy_operation_t copy) -{ const pcl_init_t **init = pcl_init_table; - int code = 0; - - for ( ; *init && code >= 0; ++init ) - if ( (*init)->do_copy ) - code = (*(*init)->do_copy)(psaved, pcs, copy); - return code; -} -int -pcl_execute_macro(const pcl_macro_t *pmac, pcl_state_t *pcs, - pcl_copy_operation_t before, pcl_reset_type_t reset, - pcl_copy_operation_t after) -{ - pcl_parser_state_t state; - hpgl_parser_state_t gstate; - pcl_state_t saved; - stream_cursor_read r; - int code; - - if ( before ) { - memcpy(&saved, pcs, sizeof(*pcs)); - do_copies(&saved, pcs, before); - pcs->saved = &saved; - } - if ( reset ) - pcl_do_resets(pcs, reset); - state.definitions = pcs->pcl_commands; - state.hpgl_parser_state=&gstate; - pcl_process_init(&state); - r.ptr = (const byte *)(pmac + 1) - 1; - r.limit = - (const byte *)pmac + (gs_object_size(pcs->memory, pmac) - 1); - pcs->macro_level++; - code = pcl_process(&state, pcs, &r); - pcs->macro_level--; - if ( after ) { - do_copies(&saved, pcs, after); - memcpy(pcs, &saved, sizeof(*pcs)); - } - return code; -} - -/* ---------------- Commands ---------------- */ - -/* Define the macro control operations. */ -enum { - macro_end_definition = 1, - macro_execute = 2, - macro_call = 3, - macro_delete_temporary = 7 -}; - -private int /* ESC & f <mc_enum> X */ -pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcs) -{ int i = int_arg(pargs); - gs_const_string key; - void *value; - pl_dict_enum_t denum; - - if ( i == macro_end_definition ) - { if ( pcs->defining_macro ) - { /* The parser has included everything through this command */ - /* in the macro_definition, so we can finish things up. */ - int code; - code = pl_dict_put(&pcs->macros, current_macro_id, - current_macro_id_size, pcs->macro_definition); - pcs->defining_macro = false; - pcs->macro_definition = 0; - return code; - } - } - else if ( pcs->defining_macro ) - return 0; /* don't execute other macro operations */ - else if ( i == macro_execute || i == macro_call ) - { /* - * TRM 12-9 says that "two levels of nesting are allowed", - * which means 3 levels of macros (1 non-nested, 2 nested). - */ - if ( pcs->macro_level > 2 ) - return 0; - } - else if ( pcs->macro_level ) - return e_Range; /* macro operations not allowed inside macro */ - switch ( i ) - { - case 0: - { /* Start defining <macro_id>. */ - pcl_macro_t *pmac; - - pl_dict_undef_purge_synonyms(&pcs->macros, current_macro_id, current_macro_id_size); - pmac = (pcl_macro_t *) - gs_alloc_bytes(pcs->memory, sizeof(pcl_macro_t), - "begin macro definition"); - if ( pmac == 0 ) - return_error(e_Memory); - pmac->storage = pcds_temporary; - pcs->macro_definition = (byte *)pmac; - pcs->defining_macro = true; - return 0; - } - case macro_end_definition: /* 1 */ - { /* Stop defining macro. Outside a macro, this is an error. */ - return e_Range; - } - case macro_execute: /* 2 */ - { /* Execute <macro_id>. */ - void *value; - if ( !pl_dict_find(&pcs->macros, current_macro_id, current_macro_id_size, - &value) - ) - return 0; - return pcl_execute_macro((const pcl_macro_t *)value, pcs, - pcl_copy_none, pcl_reset_none, pcl_copy_none); - } - case macro_call: /* 3 */ - { /* Call <macro_id>, saving and restoring environment. */ - void *value; - if ( !pl_dict_find(&pcs->macros, current_macro_id, current_macro_id_size, - &value) - ) - return 0; - return pcl_execute_macro((const pcl_macro_t *)value, pcs, - pcl_copy_before_call, pcl_reset_none, - pcl_copy_after_call); - } - case 4: - { /* Define <macro_id> as automatic overlay. */ - pcs->overlay_macro_id = pcs->macro_id; - pcs->overlay_enabled = true; - return 0; - } - case 5: - { /* Cancel automatic overlay. */ - pcs->overlay_enabled = false; - return 0; - } - case 6: - { /* Delete all macros. */ - pl_dict_release(&pcs->macros); - return 0; - } - case macro_delete_temporary: /* 7 */ - { /* Delete temporary macros. */ - pl_dict_enum_stack_begin(&pcs->macros, &denum, false); - while ( pl_dict_enum_next(&denum, &key, &value) ) - if ( ((pcl_macro_t *)value)->storage == pcds_temporary ) - pl_dict_undef_purge_synonyms(&pcs->macros, key.data, key.size); - return 0; - } - case 8: - { /* Delete <macro_id>. */ - pl_dict_undef_purge_synonyms(&pcs->macros, current_macro_id, current_macro_id_size); - return 0; - } - case 9: - { /* Make <macro_id> temporary. */ - if ( pl_dict_find(&pcs->macros, current_macro_id, current_macro_id_size, &value) ) - ((pcl_macro_t *)value)->storage = pcds_temporary; - return 0; - } - case 10: - { /* Make <macro_id> permanent. */ - if ( pl_dict_find(&pcs->macros, current_macro_id, current_macro_id_size, &value) ) - ((pcl_macro_t *)value)->storage = pcds_permanent; - return 0; - } - default: - return e_Range; - } -} - -private int /* ESC & f <id> Y */ -pcl_assign_macro_id(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint id = uint_arg(pargs); - id_set_value(pcs->macro_id, id); - pcs->macro_id_type = numeric_id; - return 0; -} - -/* Initialization */ -private int -pcmacros_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem) -{ /* Register commands */ - DEFINE_CLASS('&') - {'f', 'X', - PCL_COMMAND("Macro Control", pcl_macro_control, - pca_neg_error|pca_big_error|pca_in_macro)}, - {'f', 'Y', - PCL_COMMAND("Assign Macro ID", pcl_assign_macro_id, - pca_neg_error|pca_big_error)}, - END_CLASS - return 0; -} -private void -pcmacros_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ if ( type & (pcl_reset_initial | pcl_reset_printer) ) - { pcs->overlay_enabled = false; - pcs->macro_level = 0; - pcs->defining_macro = false; - pcs->saved = 0; - pcs->macro_definition = 0; - - if ( type & pcl_reset_initial ) - pl_dict_init(&pcs->macros, pcs->memory, NULL); - else - { pcl_args_t args; - arg_set_uint(&args, macro_delete_temporary); - pcl_macro_control(&args, pcs); - if ( pcs->alpha_macro_id.id != 0 ) - gs_free_object(pcs->memory, - pcs->alpha_macro_id.id, - "pcmacros_do_reset"); - } - } - - if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay | pcl_reset_permanent) ) - { - pcs->alpha_macro_id.size = 0; - pcs->macro_id_type = numeric_id; - id_set_value(pcs->macro_id, 0); - pcs->alpha_macro_id.id = 0; - } - if ( type & pcl_reset_permanent ) - pl_dict_release(&pcs->macros); -} -private int -pcmacros_do_copy(pcl_state_t *psaved, const pcl_state_t *pcs, - pcl_copy_operation_t operation) -{ if ( operation & pcl_copy_after ) - { /* Don't restore the macro dictionary. */ - psaved->macros = pcs->macros; - } - return 0; -} -const pcl_init_t pcmacros_init = { - pcmacros_do_registration, pcmacros_do_reset, pcmacros_do_copy -}; diff --git a/pcl/pcmisc.c b/pcl/pcmisc.c deleted file mode 100644 index 46587b0bd..000000000 --- a/pcl/pcmisc.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. - Unauthorized use, copying, and/or distribution prohibited. - */ - -/* pcmisc.c */ -/* PCL5 miscellaneous and debugging commands */ -#include "std.h" -#include "pcommand.h" -#include "pcstate.h" - -private int /* ESC & s <bool> C */ -pcl_end_of_line_wrap(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint i = uint_arg(pargs); - - if ( i > 1 ) - return e_Range; - pcs->end_of_line_wrap = i == 0; - return 0; -} - -private int /* ESC Y */ -pcl_enable_display_functions(pcl_args_t *pargs, pcl_state_t *pcs) -{ pcs->display_functions = true; - return 0; -} - -/* We export this procedure so we can detect the end of display fns mode. */ -int /* ESC Z */ -pcl_disable_display_functions(pcl_args_t *pargs, pcl_state_t *pcs) -{ pcs->display_functions = false; - return 0; -} - -/* Initialization */ -private int -pcmisc_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem) -{ /* Register commands */ - DEFINE_CLASS_COMMAND_ARGS('&', 's', 'C', "End of Line Wrap", - pcl_end_of_line_wrap, - pca_neg_error|pca_big_error) - DEFINE_ESCAPE_ARGS('Y', "Enable Display Functions", - pcl_enable_display_functions, pca_in_macro) - DEFINE_ESCAPE_ARGS('Z', "Disable Display Functions", - pcl_disable_display_functions, pca_in_macro) - return 0; -} -private void -pcmisc_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay) ) - { pcs->end_of_line_wrap = false; - pcs->display_functions = false; - } -} -const pcl_init_t pcmisc_init = { - pcmisc_do_registration, pcmisc_do_reset -}; diff --git a/pcl/pcmtx3.c b/pcl/pcmtx3.c deleted file mode 100644 index f711d5d80..000000000 --- a/pcl/pcmtx3.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcmtx3.c - 3 x 3 matrix utilities for PCL device independent color spaces */ -#include "string_.h" -#include "math_.h" -#include "gx.h" -#include "gstypes.h" -#include "pcommand.h" -#include "pcmtx3.h" - - -/* - * Calculate the co-factor for the (i, j) component of a 3 x 3 matrix, - * including the sign. Note that i and j range from 0 to 2. - * - * The cofactor of the (i, j) entry in an n-dimensional matrix is the - * determinant of the (n - 1) dimensional matrix formed by dropping the - * ith row and jth column of the given matrix, multiplied by -1 if - * (i + j) is odd. - */ - private floatp -calc_cofactor( - int i, - int j, - const pcl_mtx3_t * pmtx -) -{ - int i1 = (i == 0 ? 1 : 0); - int i2 = (i == 2 ? 1 : 2); - int j1 = (j == 0 ? 1 : 0); - int j2 = (j == 2 ? 1 : 2); - floatp cf = pmtx->a[3 * i1 + j1] * pmtx->a[3 * i2 + j2] - - pmtx->a[3 * i1 + j2] * pmtx->a[3 * i2 + j1]; - - return (((i + j) & 0x1) != 0) ? -cf : cf; -} - -/* - * Form the "cofactor matrix" corresponding to the given matrix. - * - * For this routine, pinmtx and poutmtx must be different. - */ - private void -make_cofactor_mtx( - const pcl_mtx3_t * pinmtx, - pcl_mtx3_t * poutmtx -) -{ - int i; - - for (i = 0; i < 3; i++) { - int j; - - for (j = 0; j < 3; j++) - poutmtx->a[3 * i + j] = calc_cofactor(i, j, pinmtx); - } -} - - -/* - * Add and subtract 3 dimensional vectors. These are not currently needed, - * but are included for completeness. No inner-product is provided because - * color spaces do not, in general, have geometric or even metric properties - * (the CID L*a*b* space is an exception, and then only approximately). - * - * Any of the three pointer operands may be the same. - */ - void -pcl_vec3_add( - const pcl_vec3_t * pivec1, - const pcl_vec3_t * pivec2, - pcl_vec3_t * poutvec -) -{ - poutvec->vc.v1 = pivec1->vc.v1 + pivec2->vc.v1; - poutvec->vc.v2 = pivec1->vc.v2 + pivec2->vc.v2; - poutvec->vc.v3 = pivec1->vc.v3 + pivec2->vc.v3; -} - - void -pcl_vec3_sub( - const pcl_vec3_t * pivec1, - const pcl_vec3_t * pivec2, - pcl_vec3_t * poutvec -) -{ - poutvec->vc.v1 = pivec1->vc.v1 - pivec2->vc.v1; - poutvec->vc.v2 = pivec1->vc.v2 - pivec2->vc.v2; - poutvec->vc.v3 = pivec1->vc.v3 - pivec2->vc.v3; -} - -/* - * Apply a matrix to a color component vector. Note that vectors are inter- - * preted as row vectors, and matrices are specified in a row-first order. - * - * The code will properly handle the case pinvec == poutvec. - */ - void -pcl_vec3_xform( - const pcl_vec3_t * pinvec, - pcl_vec3_t * poutvec, - const pcl_mtx3_t * pmtx -) -{ - pcl_vec3_t tmp_vec; - int i; - - for (i = 0; i < 3; i++) - tmp_vec.va[i] = pinvec->vc.v1 * pmtx->a[i] - + pinvec->vc.v2 * pmtx->a[i + 3] - + pinvec->vc.v3 * pmtx->a[i + 6]; - poutvec->vc = tmp_vec.vc; -} - -/* - * Invert a 3 x 3 matrix. - * - * This will properly handle the case of pinmtx == poutmtx. - * - * Returns 0 on success, e_Range if the matrix provided is singular. - */ - int -pcl_mtx3_invert( - const pcl_mtx3_t * pinmtx, - pcl_mtx3_t * poutmtx -) -{ - pcl_mtx3_t cf_mtx; - floatp det; - int i; - - make_cofactor_mtx(pinmtx, &cf_mtx); - det = pinmtx->c.a11 * cf_mtx.c.a11 - + pinmtx->c.a12 * cf_mtx.c.a12 - + pinmtx->c.a13 * cf_mtx.c.a13; - if (det == 0.0) - return e_Range; - for (i = 0; i < 3; i++) { - int j; - - for (j = 0; j < 3; j++) - poutmtx->a[3 * i + j] = cf_mtx.a[3 * j + i] / det; - } - - return 0; -} - -/* - * Add, subtract, and multiply two 3 x 3 matrices. These are not currently - * needed, but are included for completenese. - * - * In all cases, any of the three pointers provided may be identical. - */ - void -pcl_mtx3_add( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -) -{ - int i; - - for (i = 0; i < 9; i++) - poutmtx->a[i] = pinmtx1->a[i] + pinmtx2->a[i]; -} - - void -pcl_mtx3_sub( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -) -{ - int i; - - for (i = 0; i < 9; i++) - poutmtx->a[i] = pinmtx1->a[i] - pinmtx2->a[i]; -} - - void -pcl_mtx3_mul( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -) -{ - pcl_mtx3_t tmp_mtx; - int i; - - for (i = 0; i < 3; i++) { - int j; - - for (j = 0; j < 3; j++) { - int k; - floatp val = 0.0; - - for (k = 0; k < 3; k++) - val += pinmtx1->a[3 * i + k] * pinmtx2->a[3 * k + j]; - tmp_mtx.a[3 * i + j] = val; - } - } - *poutmtx = tmp_mtx; -} - -/* - * Convert a pcl_mtx3_t structure to and from a gs_matrix3 struct. Identity - * transformations are rare in PCL, so no attempt is made to identify them. - * - * Note that the conversion transposes the matrix in interpretation, though - * physically entries remain in the same order. This is due to the use of - * a "column vector" interpretation of color components in the graphic library. - */ - void -pcl_mtx3_convert_to_gs( - const pcl_mtx3_t * pinmtx, - gs_matrix3 * pgsmtx -) -{ - pgsmtx->cu.u = pinmtx->c.a11; - pgsmtx->cu.v = pinmtx->c.a12; - pgsmtx->cu.w = pinmtx->c.a13; - pgsmtx->cv.u = pinmtx->c.a21; - pgsmtx->cv.v = pinmtx->c.a22; - pgsmtx->cv.w = pinmtx->c.a23; - pgsmtx->cw.u = pinmtx->c.a31; - pgsmtx->cw.v = pinmtx->c.a32; - pgsmtx->cw.w = pinmtx->c.a33; - pgsmtx->is_identity = false; -} - - void -pcl_mtx3_convert_from_gs( - pcl_mtx3_t * poutmtx, - const gs_matrix3 * pgsmtx -) -{ - if (pgsmtx->is_identity) { - memset(poutmtx, 0, sizeof(pcl_mtx3_t)); - poutmtx->c.a11 = 1.0; - poutmtx->c.a22 = 1.0; - poutmtx->c.a22 = 1.0; - } else { - poutmtx->c.a11 = pgsmtx->cu.u; - poutmtx->c.a12 = pgsmtx->cu.v; - poutmtx->c.a13 = pgsmtx->cu.w; - poutmtx->c.a21 = pgsmtx->cv.u; - poutmtx->c.a22 = pgsmtx->cv.v; - poutmtx->c.a23 = pgsmtx->cw.v; - poutmtx->c.a31 = pgsmtx->cw.u; - poutmtx->c.a32 = pgsmtx->cw.v; - poutmtx->c.a33 = pgsmtx->cw.w; - } -} diff --git a/pcl/pcmtx3.h b/pcl/pcmtx3.h deleted file mode 100644 index a22aff4bd..000000000 --- a/pcl/pcmtx3.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcmtx3.h - 3 x 3 matrix utilities for PCL device independent color spaces */ - -#ifndef pcmtx3_INCLUDED -#define pcmtx3_INCLUDED - -#include "math_.h" -#include "gx.h" -#include "gsmatrix.h" -#include "gscspace.h" -#include "gscolor2.h" -#include "gscie.h" - - -/* - * To support device independent color spaces, PCL performs a number of - * calculations with 3 x 3 matrices. The CIE color space code in the graphic - * library provides a format for 3 x 3 matrices, but the format is a bit - * unusual and no corresponding utilities are provided. Hence, a separate - * (though logically identical) format is provided here. - * - * Essentially all of the literature on color spaces deals with column - * vectors, EXCEPT that specific to PostScript. The latter deals with row - * vectors to remain consistent with the use of matrices for geometric - * transformations. The graphics library code, being based on PostScript, - * uses the latter arrangement of components. The CIE code in the library is - * documented for column vectors, but specifies matrices in the less usual - * column-first order. The current code takes the logically equivalent and - * no less intuitive approach of using row vectors, and specifying - * matrices in the more normal row-first order. - * - * There is actually some reason for these alternate approaches. The CIE code - * is primarily concerned with transformation of color vectors, and performs - * relatively few other matrix operations. The current code infrequently - * transforms color vectors, but does perform other matrix operations. - * Each code module uses the format that is more intuitive for its more - * common operation. - */ -typedef union { - struct { - floatp v1, v2, v3; - } vc; - floatp va[3]; -} pcl_vec3_t; - -typedef union { - struct { - floatp a11, a12, a13, - a21, a22, a23, - a31, a32, a33; - } c; - floatp a[9]; -} pcl_mtx3_t; - -/* - * Vectors in PCL and the graphic library are physically the same structure, - * but the former are thought of as row vectors and the latter as column - * vectors, so two different C-language structures are used. The following - * macros are used for conversion. - */ -#define pcl_vec3_to_gs_vector3(gsv3, pcv3) \ - ((gsv3).u = (pcv3).vc.v1, (gsv3).v = (pcv3).vc.v2, (gsv3).w = (pcv3).vc.v3) - -#define pcl_vec3_from_gs_vector3(pcv3, gsv3) \ - ((pcv3).vc.v1 = (gsv3).u, (pcv3).vc.v2 = (gsv3).v, (pcv3).vc.v3 = (gsv3).w) - -/* - * Add and subtract 3 dimensional vectors. These are not currently needed, - * but are included for completeness. - * - * Any of the three pointer operands may be the same. - */ -void pcl_vec3_add(P3( - const pcl_vec3_t * pivec1, - const pcl_vec3_t * pivec2, - pcl_vec3_t * poutvec -)); - -void pcl_vec3_sub(P3( - const pcl_vec3_t * pivec1, - const pcl_vec3_t * pivec2, - pcl_vec3_t * poutvec -)); - -/* - * Apply a matrix to a 3-dimensional row vector. - * - * The code will properly handle the case pinvec == poutvec. - */ -void pcl_vec3_xform(P3( - const pcl_vec3_t * pinvec, - pcl_vec3_t * poutvec, - const pcl_mtx3_t * pmtx -)); - -/* - * Invert a 3 x 3 matrix. - * - * This will properly handle the case of pinmtx == poutmtx. - * - * Returns 0 on success, e_Range if the matrix provided is singular. - */ -int pcl_mtx3_invert(P2( - const pcl_mtx3_t * pinmtx, - pcl_mtx3_t * poutmtx -)); - -/* - * Add, subtract, and multiply two 3 x 3 matrices. These are not currently - * needed, but are included for completenese. - * - * In all cases, any of the three pointers provided may be identical. - */ -void pcl_mtx3_add(P3( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -)); - -void pcl_mtx3_sub(P3( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -)); - -void pcl_mtx3_mul(P3( - const pcl_mtx3_t * pinmtx1, - const pcl_mtx3_t * pinmtx2, - pcl_mtx3_t * poutmtx -)); - -/* - * Convert a pcl_mtx3_t structure to and from a gs_matrix3 struct. Identity - * transformations are rare in PCL, so no attempt is made to identify them. - */ -void pcl_mtx3_convert_to_gs(P2( - const pcl_mtx3_t * pinmtx, - gs_matrix3 * pgsmtx -)); - -void pcl_mtx3_convert_from_gs(P2( - pcl_mtx3_t * poutmtx, - const gs_matrix3 * pgsmtx -)); - -#endif /* pcmtx3_INCLUDED */ diff --git a/pcl/pcommand.c b/pcl/pcommand.c deleted file mode 100644 index a3194539c..000000000 --- a/pcl/pcommand.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcommand.c - Utilities for PCL 5 commands */ - -#include "std.h" -#include "memory_.h" -#include "gstypes.h" -#include "gsmemory.h" -#include "gsmatrix.h" -#include "gxstate.h" -#include "gsdevice.h" -#include "pcommand.h" -#include "pcparse.h" -#include "pcstate.h" -#include "pcparam.h" -#include "pcident.h" -#include "pgmand.h" /* temporary */ -/* - * Get the command argument as an int, uint, or float. - */ - int -int_value( - const pcl_value_t * pv -) -{ - return (int)(value_is_neg(pv) ? -(int)pv->i : pv->i); -} - - uint -uint_value( - const pcl_value_t * pv -) -{ - return pv->i; -} - - float -float_value( - const pcl_value_t * pv -) -{ - return ( value_is_float(pv) ? - (float)(value_is_neg(pv) ? -(int)pv->i - pv->fraction - : pv->i + pv->fraction) - : (float)int_value(pv) ); -} - - -/* - * Set an integer parameter. - */ - private int -end_param1( - gs_c_param_list * alist, - pcl_state_t * pcs -) -{ - int code; - gs_c_param_list_read(alist); - /* put the parameters using the target device, not the forwarding - device */ - code = gs_state_putdeviceparams(pcs->pgs, (gs_param_list *)alist); - gs_c_param_list_release(alist); - return code; -} - -/* - * Set a Boolean parameter. - */ - int -put_param1_bool( - pcl_state_t * pcs, - gs_param_name pkey, - bool value -) -{ - gs_c_param_list list; - - gs_c_param_list_write(&list, pcs->memory); - /*code =*/ param_write_bool((gs_param_list *)&list, pkey, &value); - return end_param1(&list, pcs); -} - -/* - * Set a float parameter. - */ - int -put_param1_float( - pcl_state_t * pcs, - gs_param_name pkey, - floatp value -) -{ - gs_c_param_list list; - float fval = value; - - gs_c_param_list_write(&list, pcs->memory); - /*code =*/ param_write_float((gs_param_list *)&list, pkey, &fval); - return end_param1(&list, pcs); -} - -/* - * Set an integer parameter. - */ - int -put_param1_int( - pcl_state_t * pcs, - gs_param_name pkey, - int value -) -{ - gs_c_param_list list; - - gs_c_param_list_write(&list, pcs->memory); - /*code =*/ param_write_int((gs_param_list *)&list, pkey, &value); - return end_param1(&list, pcs); -} - -/* - * Set a parameter consisting of an array of two floats. This is used to pass - * the paper size parameter to the device. - */ - int -put_param1_float_array( - pcl_state_t * pcs, - gs_param_name pkey, - float pf[2] -) -{ - gs_c_param_list list; - gs_param_float_array pf_array; - - pf_array.data = pf; - pf_array.size = 2; - pf_array.persistent = false; - - gs_c_param_list_write(&list, pcs->memory); - /* code = */param_write_float_array((gs_param_list *)&list, pkey, &pf_array); - return end_param1(&list, pcs); -} - -/* initilialize the parser states */ - int -pcl_do_registrations( - pcl_state_t *pcs, - pcl_parser_state_t *pst -) -{ - const pcl_init_t ** init; - int code; - /* initialize gl/2 command counter */ - hpgl_init_command_index(&pst->hpgl_parser_state, pcs->memory); - pcs->parse_data = pst->hpgl_parser_state; - /* initialize pcl's command counter */ - code = pcl_init_command_index(pst, pcs); - if ( code < 0 ) - return code; - for (init = pcl_init_table; *init; ++init) { - if ( (*init)->do_registration ) { - code = (*(*init)->do_registration)(pst, pcs->memory); - if (code < 0) { - lprintf1("Error %d during initialization!\n", code); - return code; - } - } - } - return 0; -} -/* - * Run the reset code of all the modules. - */ - int -pcl_do_resets( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - const pcl_init_t ** init = pcl_init_table; - int code = 0; - - for ( ; *init && code >= 0; ++init) { - if ((*init)->do_reset) - (*(*init)->do_reset)(pcs, type); - } - return code; -} - -/* - * "Cold start" initialization of the graphic state. This is provided as a - * special routine to avoid (as much as possible) order depedencies in the - * various reset routines used by individual modules. Some of the values - * selected may be subsequently overridden by the reset routines; this code - * just attempts to set them to reasonable values. - */ - void -pcl_init_state( - pcl_state_t * pcs, - gs_memory_t * pmem -) -{ - /* some elementary fields */ - pcs->memory = pmem; - pcs->num_copies = 1; - pcs->output_bin = 1; - pcs->uom_cp = 7200L / 300L; - - pcs->perforation_skip = 1; - - pcs->font_id_type = numeric_id; - pcs->macro_id_type = numeric_id; - - pcs->rotate_patterns = true; - pcs->source_transparent = true; - pcs->pattern_transparent = true; - - pcs->logical_op = 252; - - pcs->monochrome_mode = false; - pcs->render_mode = 3; - - pcs->next_id = 8UL; - pcl_init_gstate_stk(pcs); - pcs->configure_appletalk = 0; -} diff --git a/pcl/pcommand.h b/pcl/pcommand.h deleted file mode 100644 index 1e6cf9032..000000000 --- a/pcl/pcommand.h +++ /dev/null @@ -1,275 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. - Unauthorized use, copying, and/or distribution prohibited. - */ - -/* pcommand.h */ -/* Definitions for PCL5 commands */ - -#ifndef pcommand_INCLUDED -# define pcommand_INCLUDED - -#include "memory_.h" -#include "gx.h" -#include "gserrors.h" - -/* Define a PCL value (PCL command parameter). */ -/* The 16+16 representation is required to match the PCL5 documentation. */ -#if arch_sizeof_int == 4 -typedef int int32; -typedef uint uint32; -#else -# if arch_sizeof_long == 4 -typedef long int32; -typedef ulong uint32; -# endif -#endif - -typedef enum { - pcv_none = 0, - /* The following masks merge together: */ - pcv_int = 1, - pcv_float = 2, - pcv_neg = 4, - pcv_pos = 8 -} pcl_value_type_t; -#define value_is_present(pv)\ - ((pv)->type != pcv_none) -#define value_is_float(pv)\ - ((pv)->type & pcv_float) -#define value_is_neg(pv)\ - ((pv)->type & pcv_neg) -#define value_is_signed(pv)\ - ((pv)->type & (pcv_neg | pcv_pos)) -typedef struct pcl_value_s { - pcl_value_type_t type; - uint i; /* integer part */ - float fraction; -} pcl_value_t; -#define value_set_uint(pv, ui)\ - ((pv)->type = pcv_int, (pv)->i = (ui)) -#define value_set_float(pv, in, fr)\ - ((pv)->type = pcv_float, (pv)->i = (in), (pv)->fraction = (fr)) -#define _vshift 16 -typedef int32 pcl_fixed; /* sign + 15 int + 16 fraction */ -typedef uint32 pcl_ufixed; /* 16 int + 16 fraction */ -/* Get a command argument as an int, uint, or float. */ -int int_value(P1(const pcl_value_t *)); -uint uint_value(P1(const pcl_value_t *)); -float float_value(P1(const pcl_value_t *)); - -/* Convert a 32-bit IEEE float to the local representation. */ -float word2float(P1(uint32 word)); - -/* Define the argument passed to PCL commands. */ -typedef struct pcl_args_s { - pcl_value_t value; /* PCL5 command argument */ - byte *data; /* data following the command */ - bool data_on_heap; /* if true, data is allocated on heap */ - char command; /* (last) command character */ -} pcl_args_t; -#define int_arg(pargs) int_value(&(pargs)->value) -#define uint_arg(pargs) uint_value(&(pargs)->value) -#define float_arg(pargs) float_value(&(pargs)->value) -#define arg_data(pargs) ((pargs)->data) -#define arg_data_size(pargs) uint_arg(pargs) /* data size */ -#define arg_is_present(pargs) value_is_present(&(pargs)->value) -#define arg_is_signed(pargs) value_is_signed(&(pargs)->value) -#define arg_set_uint(pargs, ui) value_set_uint(&(pargs)->value, ui) -#define arg_set_float(pargs, in, fr) value_set_float(&(pargs)->value, in, fr) -/* Define an opaque type for the PCL state. */ -#ifndef pcl_state_DEFINED -# define pcl_state_DEFINED -typedef struct pcl_state_s pcl_state_t; -#endif - -#ifndef pcl_parser_state_DEFINED -# define pcl_parser_state_DEFINED -typedef struct pcl_parser_state_s pcl_parser_state_t; -#endif - -#ifndef hpgl_parser_state_DEFINED -# define hpgl_parser_state_DEFINED -typedef struct hpgl_args_s hpgl_parser_state_t; -#endif - -/* Define a command processing procedure. */ -#define pcl_command_proc(proc)\ - int proc(P2(pcl_args_t *, pcl_state_t *)) -typedef pcl_command_proc((*pcl_command_proc_t)); - -/* Define a few exported processing procedures. */ -pcl_command_proc(pcl_disable_display_functions); -uint pcl_status_read(P3(byte *data, uint max_data, pcl_state_t *pcs)); -/* Process a string of plain (printable) text. */ -int pcl_text(P4(const byte *str, uint size, pcl_state_t *pcs, bool literal)); -/* Process a single text character. This is almost never called. */ -pcl_command_proc(pcl_plain_char); - -/* Define error returns. */ -#define e_Range (0) /* ignore range errors */ -#define e_Syntax (-18) /* gs_error_syntaxerror */ -#define e_Memory gs_error_VMerror -#define e_Unimplemented (105) /* ignore unimplemented commands */ -#define e_ExitLanguage (-102) /* e_InterpreterExit */ - -/* Define a command definition. */ -typedef struct { - pcl_command_proc_t proc; - byte/*pcl_command_action_t*/ actions; -#ifdef DEBUG - const char *cname; -# define PCL_COMMAND(cname, proc, actions) { proc, actions, cname } -#else -# define PCL_COMMAND(cname, proc, actions) { proc, actions } -#endif -} pcl_command_definition_t; -/* Define actions associated with a command. */ -typedef enum { - /* Negative arguments may be clamped to 0, give an error, cause the */ - /* command to be ignored, or be passed to the command. */ - pca_neg_action = 3, - pca_neg_clamp = 0, - pca_neg_error = 1, - pca_neg_ignore = 2, - pca_neg_ok = 3, - /* Arguments in the range 32K to 64K-1 may be clamped, give an error, */ - /* cause the command to be ignored, or be passed to the command. */ - pca_big_action = 0xc, - pca_big_clamp = 0, - pca_big_error = 4, - pca_big_ignore = 8, - pca_big_ok = 0xc, - /* Indicate whether the command is followed by data bytes. */ - pca_byte_data = 0x10, - pca_bytes = pca_neg_error | pca_big_ok | pca_byte_data, - /* Indicate whether the command is allowed in raster graphics mode. */ - pca_raster_graphics = 0x20, - /* Indicate whether the command should be called while defining a macro. */ - pca_in_macro = 0x40, - /* Indicate whether the command is allowed in rtl mode */ - pca_in_rtl = 0x80 -} pcl_command_action_t; - -/* Define a table of command definitions. */ -typedef struct { - char group; - char command; - pcl_command_definition_t defn; -} pcl_grouped_command_definition_t; - -/* Register (a) command definition(s). */ -void pcl_define_control_command(P3(int/*char*/, - const pcl_command_definition_t *, pcl_parser_state_t *)); -#define DEFINE_CONTROL(chr, cname, proc)\ -{ static const pcl_command_definition_t defn_ = PCL_COMMAND(cname, proc, 0);\ - pcl_define_control_command(chr, &defn_, pcl_parser_state);\ -} -void pcl_define_escape_command(P3(int/*char*/, - const pcl_command_definition_t *, pcl_parser_state_t *)); -#define DEFINE_ESCAPE_ARGS(chr, cname, proc, acts)\ -{ static const pcl_command_definition_t defn_ = PCL_COMMAND(cname, proc, acts);\ - pcl_define_escape_command(chr, &defn_, pcl_parser_state);\ -} -#define DEFINE_ESCAPE(chr, cname, proc)\ - DEFINE_ESCAPE_ARGS(chr, cname, proc, 0) -void pcl_define_class_command(P5(int/*char*/, int/*char*/, int/*char*/, - const pcl_command_definition_t *, pcl_parser_state_t *)); -#define DEFINE_CLASS_COMMAND_ARGS(cls, group, chr, cname, proc, acts)\ -{ static const pcl_command_definition_t defn_ = PCL_COMMAND(cname, proc, acts);\ - pcl_define_class_command(cls, group, chr, &defn_, pcl_parser_state);\ -} -#define DEFINE_CLASS_COMMAND(cls, group, chr, cname, proc)\ - DEFINE_CLASS_COMMAND_ARGS(cls, group, chr, cname, proc, 0) -void pcl_define_class_commands(P3(int/*char*/, - const pcl_grouped_command_definition_t *, - pcl_parser_state_t *)); -#define DEFINE_CLASS(cls)\ -{ const byte class_ = cls;\ - static const pcl_grouped_command_definition_t defs_[] = { -#define END_CLASS\ - {0, 0}\ - };\ - pcl_define_class_commands(class_, defs_, pcl_parser_state);\ -} - -/* - * Define the different kinds of reset that may occur during execution. - * Some of them are only of interest to HPGL. We define them as bit masks - * rather than as ordinals so that if it turns out to be useful, we can - * defer HPGL resets until we enter HPGL mode. - */ -typedef enum { - pcl_reset_none = 0, - pcl_reset_initial = 1, - pcl_reset_cold = 2, - pcl_reset_printer = 4, - pcl_reset_overlay = 8, - pcl_reset_page_params = 0x10, - pcl_reset_picture_frame = 0x20, - pcl_reset_anchor_point = 0x40, - pcl_reset_plot_size = 0x80, - /* define a special reset to be used to free permanent and internal - objects: fonts, symbol sets and macros */ - pcl_reset_permanent = 0x100 -} pcl_reset_type_t; -/* - * Define the different kinds of state copying operation that are required - * for macro call and overlay. - */ -typedef enum { - pcl_copy_none = 0, - pcl_copy_before_call = 1, - pcl_copy_after_call = 2, - pcl_copy_before_overlay = 4, - pcl_copy_after_overlay = 8, - pcl_copy_after = pcl_copy_after_call | pcl_copy_after_overlay -} pcl_copy_operation_t; -/* Define the structure for per-module implementation procedures. */ -typedef struct pcl_init_s { - /* Register commands */ - int (*do_registration)(P2(pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem)); - /* Initialize state at startup, printer reset, and other times. */ - void (*do_reset)(P2(pcl_state_t *pcs, pcl_reset_type_t type)); - /* Partially copy the state for macro call, overlay, and exit. */ - int (*do_copy)(P3(pcl_state_t *psaved, const pcl_state_t *pcs, - pcl_copy_operation_t operation)); -} pcl_init_t; -/* Define the table of pointers to init structures (in pcjob.c). */ -extern const pcl_init_t *pcl_init_table[]; - -/* run the init code */ -int pcl_do_registrations(P2(pcl_state_t *pcs, pcl_parser_state_t *pst)); - -/* Run the reset code of all the modules. */ -int pcl_do_resets(P2(pcl_state_t *pcs, pcl_reset_type_t type)); - -/* Define stored entity storage status. */ -/* Note that this is a mask, not an ordinal. */ -typedef enum { - pcds_temporary = 1, - pcds_permanent = 2, - pcds_downloaded = pcds_temporary | pcds_permanent, - pcds_internal = 4 -#define pcds_cartridge_shift 3 -#define pcds_cartridge_max 8 -#define pcds_all_cartridges\ - ( ((1 << pcds_cartridge_max) - 1) << pcds_cartridge_shift ) -#define pcds_simm_shift (pcds_cartridge_shift + pcds_cartridge_max) -#define pcds_simm_max 8 -#define pcds_all_simms\ - ( ((1 << pcds_simm_max) - 1) << pcds_simm_shift ) -} pcl_data_storage_t; - -/* Define the control characters. */ -#define BS 0x8 -#define HT 0x9 -#define LF 0xa -#define FF 0xc -#define CR 0xd -#define SO 0xe -#define SI 0xf -#define ESC 0x1b -#define SP 0x20 - -#endif /* pcommand_INCLUDED */ diff --git a/pcl/pcpage.c b/pcl/pcpage.c deleted file mode 100644 index 9745e4f52..000000000 --- a/pcl/pcpage.c +++ /dev/null @@ -1,987 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpage.c - PCL5 page and transformation control commands */ - -#include "math_.h" -#include "std.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcdraw.h" -#include "pcparam.h" -#include "pcparse.h" /* for pcl_execute_macro */ -#include "pcfont.h" /* for underline interface */ -#include "pcpatxfm.h" -#include "pcursor.h" -#include "pcpage.h" -#include "pgmand.h" -#include "pginit.h" -#include "plmain.h" /* for finish page */ -#include "gsmatrix.h" /* for gsdevice.h */ -#include "gsnogc.h" -#include "gscoord.h" -#include "gsdevice.h" -#include "gspaint.h" -#include "gxdevice.h" -#include "gdevbbox.h" -#include "gdevcmap.h" -#include "pjtop.h" - -/* - * The PCL printable region. HP always sets the boundary of this region to be - * 1/6" in from the edge of the paper, irrespecitve of the paper size or the - * device. Since this dimension affects some default values related to rasters, - * it is important that it be assigned this value. - */ -#define PRINTABLE_MARGIN_CP inch2coord(1.0 / 6.0) - -#define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) - - -/* Procedures */ - -/* - * Preserve the current point and text margin set by transfroming them into - * logical page space. - */ - private void -preserve_cap_and_margins( - const pcl_state_t * pcs, - gs_point * pcur_pt, - gs_rect * ptext_rect -) -{ - pcur_pt->x = (double)pcs->cap.x; - pcur_pt->y = (double)pcs->cap.y; - gs_point_transform( pcur_pt->x, - pcur_pt->y, - &(pcs->xfm_state.pd2lp_mtx), - pcur_pt - ); - ptext_rect->p.x = (double)pcs->margins.left; - ptext_rect->p.y = (double)pcs->margins.top; - ptext_rect->q.x = (double)pcs->margins.right; - ptext_rect->q.y = (double)(pcs->margins.top + pcs->margins.length); - pcl_transform_rect(ptext_rect, ptext_rect, &(pcs->xfm_state.pd2lp_mtx)); -} - -/* - * Convert the current point and text margin set back into "pseudo print - * direction" space. - */ - private void -restore_cap_and_margins( - pcl_state_t * pcs, - const gs_point * pcur_pt, - const gs_rect * ptext_rect -) -{ - gs_matrix lp2pd; - gs_point tmp_pt; - gs_rect tmp_rect; - - pcl_invert_mtx(&(pcs->xfm_state.pd2lp_mtx), &lp2pd); - gs_point_transform(pcur_pt->x, pcur_pt->y, &lp2pd, &tmp_pt); - pcs->cap.x = (coord)tmp_pt.x; - pcs->cap.y = (coord)tmp_pt.y; - pcl_transform_rect(ptext_rect, &tmp_rect, &lp2pd); - pcs->margins.left = (coord)tmp_rect.p.x; - pcs->margins.top = (coord)tmp_rect.p.y; - pcs->margins.right = (coord)tmp_rect.q.x; - pcs->margins.length = (coord)tmp_rect.q.y - pcs->margins.top; -} - -/* - * Update the transformations stored in the PCL state. This will also update - * the device clipping region information in device and logical page space. - * The text region margins are preserved. - * - * This routine should be called for: - * - * changes in the paper size - * transition from page front to page back for duplexing - * (this facility is not currently implemented) - * change of left or top offset registration - * change of logical page orientation - * change of print direction - * - * The paper size, left/top offsets, logical page orientation, and print - * direction should be set before this procedure is called. - */ - private void -update_xfm_state( - pcl_state_t * pcs, - bool reset_initial -) -{ - pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - const pcl_paper_size_t * psize = pxfmst->paper_size; - coord offset; - gs_matrix pg2dev, pg2lp; - gs_rect print_rect, dev_rect, text_rect; - gs_point cur_pt; - floatp loff = pxfmst->left_offset_cp; - floatp toff = pxfmst->top_offset_cp; - - /* preserve the current point and text rectangle in logical page space */ - if ( !reset_initial ) - preserve_cap_and_margins(pcs, &cur_pt, &text_rect); - - /* get the page to device transformation */ - gs_defaultmatrix(pcs->pgs, &pg2dev); - - /* - * Get the logical to page space transformation, and the dimensions of the - * logical page. - * - * NOT YET IMPLEMENT - if on back of a duplex page, change size of offsets - * - * if (duplex_back(pcs)) { - * loff = -loff; - * toff = -toff; - * } - */ - pcl_make_rotation( pxfmst->lp_orient, - (floatp)(psize->width), - (floatp)(psize->height), - &(pxfmst->lp2pg_mtx) - ); - pxfmst->lp2pg_mtx.tx += loff; - pxfmst->lp2pg_mtx.ty += toff; - if ( pcs->personality == rtl ) - offset = 0; - else - offset = ( (pxfmst->lp_orient & 0x1) != 0 ? psize->offset_landscape - : psize->offset_portrait ); - - /* we need an extra 1/10 inch on each side to support 80 - characters vs. 78 at 10 cpi. Only apply to A4. */ - if ( ( pcs->wide_a4 ) && - (psize->width == 59520) && - (psize->height == 84168) ) - offset -= inch2coord(1.0/10.0); - - gs_matrix_translate( &(pxfmst->lp2pg_mtx), - (floatp)offset, - 0.0, - &(pxfmst->lp2pg_mtx) - ); - if ((pxfmst->lp_orient & 0x1) != 0) { - pxfmst->lp_size.x = psize->height - 2 * offset; - pxfmst->lp_size.y = psize->width; - } else { - pxfmst->lp_size.x = psize->width - 2 * offset; - pxfmst->lp_size.y = psize->height; - } - - /* then the logical page to device transformation */ - gs_matrix_multiply(&(pxfmst->lp2pg_mtx), &pg2dev, &(pxfmst->lp2dev_mtx)); - pg2dev.ty = round(pg2dev.ty); pg2dev.tx = round(pg2dev.tx); - pxfmst->lp2dev_mtx.tx = round(pxfmst->lp2dev_mtx.tx); - pxfmst->lp2dev_mtx.ty = round(pxfmst->lp2dev_mtx.ty); - /* the "pseudo page direction to logical page/device transformations */ - pcl_make_rotation( pxfmst->print_dir, - (floatp)pxfmst->lp_size.x, - (floatp)pxfmst->lp_size.y, - &(pxfmst->pd2lp_mtx) - ); - gs_matrix_multiply( &(pxfmst->pd2lp_mtx), - &(pxfmst->lp2dev_mtx), - &(pxfmst->pd2dev_mtx) - ); - - /* calculate the print direction page size */ - if ((pxfmst->print_dir) & 0x1) { - pxfmst->pd_size.x = pxfmst->lp_size.y; - pxfmst->pd_size.y = pxfmst->lp_size.x; - } else - pxfmst->pd_size = pxfmst->lp_size; - - { - gx_device *pdev = gs_currentdevice(pcs->pgs); - /* We must not set up a clipping region beyond the hardware margins of - the device, but the pcl language definition requires hardware - margins to be 1/6". We set all margins to the the maximum of the - PCL language defined 1/6" and the actual hardware margin. If 1/6" - is not available pcl will not work correctly all of the time. */ - if ( pcs->personality == rtl ) { - print_rect.p.x = inch2coord(pdev->HWMargins[0] / 72.0); - print_rect.p.y = inch2coord(pdev->HWMargins[1]) / 72.0; - print_rect.q.x = psize->width - inch2coord(pdev->HWMargins[2] / 72.0); - print_rect.q.y = psize->height - inch2coord(pdev->HWMargins[3] / 72.0); - } else { - print_rect.p.x = max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[0] / 72.0)); - print_rect.p.y = max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[1]) / 72.0); - print_rect.q.x = psize->width - max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[2] / 72.0)); - print_rect.q.y = psize->height - max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[3] / 72.0)); - } - pcl_transform_rect(&print_rect, &dev_rect, &pg2dev); - pxfmst->dev_print_rect.p.x = float2fixed(round(dev_rect.p.x)); - pxfmst->dev_print_rect.p.y = float2fixed(round(dev_rect.p.y)); - pxfmst->dev_print_rect.q.x = float2fixed(round(dev_rect.q.x)); - pxfmst->dev_print_rect.q.y = float2fixed(round(dev_rect.q.y)); - } - pcl_invert_mtx(&(pxfmst->lp2pg_mtx), &pg2lp); - pcl_transform_rect(&print_rect, &(pxfmst->lp_print_rect), &pg2lp); - - /* restablish the current point and text region */ - if ( !reset_initial ) - restore_cap_and_margins(pcs, &cur_pt, &text_rect); - - /* - * No need to worry about pat_orient or pat_ref_pt; these will always - * be recalculated just prior to use. - */ -} - - -/* default margins, relative to the logical page boundaries */ -#define DFLT_TOP_MARGIN inch2coord(0.5) -#define DFLT_LEFT_MARGIN inch2coord(0.0) -#define DFLT_RIGHT_MARGIN inch2coord(0.0) -#define DFLT_BOTTOM_MARGIN inch2coord(0.5) - -#define TOP_MARGIN(hgt, tmarg) ((hgt) > (tmarg) ? (tmarg) : 0) -#define PAGE_LENGTH(hgt, bmarg) ((hgt) > (bmarg) ? (hgt) - (bmarg) : (hgt)) - -/* - * Reset the top margin an text length. - * - * Note that, even though changing the print direction merely relabels (but does - * not relocate) the margins, the preint direction does change the location of - * the default margins. - */ - private void -reset_vertical_margins( - pcl_state_t * pcs -) -{ - pcl_margins_t * pmar = &(pcs->margins); - coord hgt = pcs->xfm_state.pd_size.y; - - pmar->top = TOP_MARGIN(hgt, DFLT_TOP_MARGIN); - pmar->length = PAGE_LENGTH(hgt - pmar->top, DFLT_BOTTOM_MARGIN); -} - -/* - * Reset horizontal margins - * - * Note that, even though changing the print direction merely relabels (but does - * not relocate) the margins, the preint direction does change the location of - * the default margins. - */ - private void -reset_horizontal_margins( - pcl_state_t * pcs -) -{ - pcl_margins_t * pmar = &(pcs->margins); - - pmar->left = DFLT_LEFT_MARGIN; - pmar->right = pcs->xfm_state.pd_size.x - DFLT_RIGHT_MARGIN; -} - -/* - * Reset both the horizontal and vertical margins - */ - private void -reset_margins( - pcl_state_t * pcs -) -{ - reset_horizontal_margins(pcs); - reset_vertical_margins(pcs); -} - -/* - * Reset all parameters which must be reset whenever the page size changes. - * - * The third operand indicates if this routine is being called as part of - * an initial reset. In that case, done't call HPGL's reset - the reset - * will do that later. - */ - void -new_page_size( - pcl_state_t * pcs, - const pcl_paper_size_t * psize, - bool reset_initial -) -{ - floatp width_pts = psize->width * 0.01; - floatp height_pts = psize->height * 0.01; - float page_size[2]; - gs_state * pgs = pcs->pgs; - gs_matrix mat; - - page_size[0] = width_pts; - page_size[1] = height_pts; - put_param1_float_array(pcs, "PageSize", page_size); - - /* - * Reset the default transformation. - * - * The graphic library provides a coordinate system in points, with the - * origin at the lower left corner of the page. The PCL code uses a - * coordinate system in centi-points, with the origin at the upper left - * corner of the page. - */ - gs_setdefaultmatrix(pgs, NULL); - gs_initmatrix(pgs); - gs_currentmatrix(pgs, &mat); - gs_matrix_translate(&mat, 0.0, height_pts, &mat); - gs_matrix_scale(&mat, 0.01, -0.01, &mat); - gs_setdefaultmatrix(pgs, &mat); - - pcs->xfm_state.paper_size = psize; - pcs->overlay_enabled = false; - update_xfm_state(pcs, reset_initial); - reset_margins(pcs); - - /* - * If this is an initial reset, make sure underlining is disabled (homing - * the cursor may cause an underline to be put out. - */ - if (reset_initial) - pcs->underline_enabled = false; - else - pcl_home_cursor(pcs); - - pcl_xfm_reset_pcl_pat_ref_pt(pcs); - - if (!reset_initial) - hpgl_do_reset(pcs, pcl_reset_page_params); - gs_erasepage(pcs->pgs); -} - -/* - * Reset all parameters which must be reset whenever the logical page - * orientation changes. - * - * The last operand indicates if this routine is being called as part of - * an initial resete. - */ - void -new_logical_page( - pcl_state_t * pcs, - int lp_orient, - const pcl_paper_size_t * psize, - bool reset_initial -) -{ - pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - - pcs->hmi_cp = HMI_DEFAULT; - pcs->vmi_cp = VMI_DEFAULT; - pxfmst->lp_orient = lp_orient; - pxfmst->print_dir = 0; - new_page_size(pcs, psize, reset_initial); -} - - int -pcl_current_bounding_box(pcl_state_t * pcs, - gs_rect * pbbox) -{ - gx_device * dev = ((gx_device_cmap *)gs_currentdevice(pcs->pgs))->target; - /* Check whether we're working with a bbox device. */ - if (strcmp(gs_devicename(dev), "bbox") == 0) { - gs_matrix mat; - /* - * A bbox device can give us a definitive answer; - * (otherwise we have to be conservative). - */ - gx_device_bbox_bbox((gx_device_bbox *)dev, pbbox); - /* wacko - NB fix this the coordinates come out wrong for - the 0 area case */ - if ((pbbox->p.x >= pbbox->q.x) || (pbbox->p.y >= pbbox->q.y)) - return 0; - /* convert to device space */ - gs_deviceinitialmatrix((gx_device *)dev, &mat); - gs_bbox_transform(pbbox, &mat, pbbox); - } else { - dprintf("Error bbox not installed\n"); - return -1; - } - return 0; -} - -/* returns the bounding box coordinates for the current device and a - boolean to indicate marked status. 0 - unmarked 1 - marked -1 error */ - int -pcl_page_marked( - pcl_state_t * pcs -) -{ - gs_rect bbox; - int code; - - code = pcl_current_bounding_box(pcs, &bbox); - if ( code < 0 ) - return code; - - if ((bbox.p.x >= bbox.q.x) || (bbox.p.y >= bbox.q.y)) - return false; - else - return true; -} - -/* - * End a page, either unconditionally or only if there are marks on it. - * Return 1 if the page was actually printed and erased. - */ - int -pcl_end_page( - pcl_state_t * pcs, - pcl_print_condition_t condition -) -{ - int code = 0; - pl_main_instance_t *pmi = pcs->client_data; - - pcl_break_underline(pcs); /* (could mark page) */ - - /* If we are conditionally printing (normal case) check if the - page is marked */ - if (condition != pcl_print_always) { - if ( !pcl_page_marked(pcs) ) - return 0; - } - - /* If there's an overlay macro, execute it now. */ - if (pcs->overlay_enabled) { - void * value; - - if ( pl_dict_find( &pcs->macros, - id_key(pcs->overlay_macro_id), - 2, - &value - ) ) { - pcs->overlay_enabled = false; /**** IN reset_overlay ****/ - code = pcl_execute_macro( (const pcl_macro_t *)value, - pcs, - pcl_copy_before_overlay, - pcl_reset_overlay, - pcl_copy_after_overlay - ); - pcs->overlay_enabled = true; /**** IN copy_after ****/ - } - } - gs_nogc_reclaim(&(pmi->spaces), true); - /* output the page */ - (*pcs->end_page)(pcs, pcs->num_copies, true); - pcl_set_drawing_color(pcs, pcl_pattern_solid_white, 0, false); - code = gs_erasepage(pcs->pgs); - /* - * Advance of a page may move from a page front to a page back. This may - * change the applicable transformations. - */ - update_xfm_state(pcs, 0); - - pcl_continue_underline(pcs); - return (code < 0 ? code : 1); -} - - -/* Commands */ - -/* - * Define the known paper sizes. - * - * The values are taken from the H-P manual and are in 1/300" units, - * but the structure values are in centipoints (1/7200"). - */ -#define p_size(t, n, w, h, offp, offl) \ - { (t), (n), { (w) * 24L, (h) * 24L, (offp) * 24L, (offl) * 24L } } - -private struct { - uint tag; - const char * pname; - pcl_paper_size_t psize; -} paper_sizes[] = { - p_size( 1, "executive", 2175, 3150, 75, 60), - p_size( 2, "letter", 2550, 3300, 75, 60), - p_size( 3, "legal", 2550, 4200, 75, 60), - p_size( 6, "ledger", 3300, 5100, 75, 60), - p_size( 26, "a4", 2480, 3507, 71, 59), - p_size( 27, "a3", 3507, 4960, 71, 59), - p_size( 80, "monarch", 1162, 2250, 75, 60), - p_size( 81, "com_10", 1237, 2850, 75, 60), - p_size( 90, "dl", 1299, 2598, 71, 59), - p_size( 91, "c5", 1913, 2704, 71, 59), - p_size(100, "b5", 2078, 2952, 71, 59) -}; - -/* - * ESC & l <psize_enum> A - * - * Select paper size - */ - private int -set_page_size( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - /* Note: not all values are implemented on all printers. */ - uint tag = uint_arg(pargs); - int i; - int code = 0; - const pcl_paper_size_t * psize = 0; - - /* oddly the command goes to the next page irrespective of - arguments */ - code = pcl_end_page_if_marked(pcs); - if ( code < 0 ) - return code; - pcl_home_cursor(pcs); - - for (i = 0; i < countof(paper_sizes); i++) { - if (tag == paper_sizes[i].tag) { - psize = &(paper_sizes[i].psize); - break; - } - } - if ((psize != 0) && ((code = pcl_end_page_if_marked(pcs)) >= 0)) - new_page_size(pcs, psize, false); - return code; -} - -/* - * ESC & l <feed_enum> H - * - * Set paper source - */ - private int -set_paper_source( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - /* oddly the command goes to the next page irrespective of - arguments */ - int code = pcl_end_page_if_marked(pcs); - if ( code < 0 ) - return code; - pcl_home_cursor(pcs); - - /* Note: not all printers support all possible values. */ - if (i <= 6) { - code = 0; - if (i > 0) - code = put_param1_int(pcs, "%MediaSource", i); - return (code < 0 ? code : 0); - } else - return e_Range; -} - -/* - * ESC & l <xoff_dp> U - * - * Note that this shifts the logical page, but does NOT change its size nor - * does it reset any logical-page related parameters. - */ - private int -set_left_offset_registration( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->xfm_state.left_offset_cp = float_arg(pargs) * 10.0; - update_xfm_state(pcs, 0); - return 0; -} - -/* - * ESC & l <yoff_dp> Z - * - * Note that this shifts the logical page, but does NOT change its size nor - * does it reset any logical-page related parameters. - */ - private int -set_top_offset_registration( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->xfm_state.top_offset_cp = float_arg(pargs) * 10; - update_xfm_state(pcs, 0); - return 0; -} - -/* - * ESC & l <orient> O - * - * Set logical page orientation. - */ - private int -set_logical_page_orientation( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - int code = 0; - - if ( (i <= 3) && - ((code = pcl_end_page_if_marked(pcs)) >= 0) ) - new_logical_page(pcs, i, pcs->xfm_state.paper_size, false); - return code; -} - -/* - * ESC & a <angle> P - */ - private int -set_print_direction( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if ((i <= 270) && (i % 90 == 0)) { - pcs->xfm_state.print_dir = i / 90; - update_xfm_state(pcs, 0); - } - return 0; -} - -/* - * ESC & a <col> L - * - * Set left margin. - */ - private int -set_left_margin( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - coord lmarg = uint_arg(pargs) * pcl_hmi(pcs); - - if (lmarg < pcs->margins.right) { - pcs->margins.left = lmarg; - if (pcs->cap.x < lmarg) - pcl_set_cap_x(pcs, lmarg, false, false); - } - return 0; -} - -/* - * ESC & a <col> M - * - * Set right margin. The right margin is set to the *right* edge of the - * specified column, so we need to add 1 to the column number. - */ - private int -set_right_margin( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - coord rmarg = (uint_arg(pargs) + 1) * pcl_hmi(pcs); - - if (rmarg > pcs->xfm_state.pd_size.x) - rmarg = pcs->xfm_state.pd_size.x; - if (rmarg > pcs->margins.left) { - pcs->margins.right = rmarg; - if (pcs->cap.x > rmarg) - pcl_set_cap_x(pcs, rmarg, false, false); - } - - return 0; -} - -/* - * ESC 9 - * - * Clear horizontal margins. - */ - private int -clear_horizontal_margins( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - reset_horizontal_margins(pcs); - return 0; -} - -/* - * ESC & l <line> E - * - * Set top margin. This will also reset the page length. - */ - private int -set_top_margin( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - coord hgt = pcs->xfm_state.pd_size.y; - coord tmarg = uint_arg(pargs) * pcs->vmi_cp; - - if ((pcs->vmi_cp != 0) && (tmarg <= hgt)) { - int code; - gs_rect bbox; - pcs->margins.top = tmarg; - pcs->margins.length = PAGE_LENGTH(hgt - tmarg, DFLT_BOTTOM_MARGIN); - /* The pcl manual implies the cursor is only adjusted for the - first line of text we approximate this language by checking - that the page is blank. If it is we "home" the cursor. */ - code = pcl_current_bounding_box(pcs, &bbox) ; - if ( (bbox.p.x >= bbox.q.x) || (bbox.p.y >= bbox.q.y) ) - return pcl_set_cap_y(pcs, 0L, false, false, true); - } - return 0; -} - -/* - * ESC & l <lines> F - * - * Set text length (which indirectly sets the bottom margin). - */ - private int -set_text_length( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - coord len = uint_arg(pargs) * pcs->vmi_cp; - - if ((len != 0) && (pcs->margins.top + len <= pcs->xfm_state.pd_size.y) ) - pcs->margins.length = len; - return 0; -} - -/* - * ESC & l <enable> L - * - * Set perforation skip mode. Though performation skip is more closely related - * to vertical motion than to margins, the command is included here because it - * resets the vertical margins (top margin and text length) to their defaults. - */ - private int -set_perforation_skip( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - bool new_skip = uint_arg(pargs); - - if ((new_skip != pcs->perforation_skip) && (new_skip <= 1)) - pcs->perforation_skip = new_skip; - return 0; -} - -/* - * (From PCL5 Comparison Guide, p. 1-98) - * - * ESC & l <type> M - * - * Set media type. - */ - private int -pcl_media_type( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int type = uint_arg(pargs); - - if (type <= 4) { - int code = pcl_end_page_if_marked(pcs); - - if (code >= 0) - pcl_home_cursor(pcs); - return (code < 0 ? code : e_Unimplemented); - } else - return e_Range; -} - -/* - * (From PCL5 Comparison Guide, p. 1-99) - * - * ESC * o <quality> Q - * - * Set print quality. - */ - private int -pcl_print_quality( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int quality = int_arg(pargs); - - if ((quality >= -1) && (quality <= 1)) { - int code = pcl_end_page_if_marked(pcs); - - if (code >= 0) - pcl_home_cursor(pcs); - return (code < 0 ? code : 0); - } else - return e_Range; -} - -/* - * Initialization - */ - private int -pcpage_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem /* ignored */ -) -{ - /* Register commands */ - DEFINE_CLASS('&') - { - 'l', 'A', - PCL_COMMAND( "Page Size", - set_page_size, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'H', - PCL_COMMAND( "Paper Source", - set_paper_source, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'U', - PCL_COMMAND( "Left Offset Registration", - set_left_offset_registration, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'Z', - PCL_COMMAND( "Top Offset Registration", - set_top_offset_registration, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'O', - PCL_COMMAND( "Page Orientation", - set_logical_page_orientation, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'a', 'P', - PCL_COMMAND( "Print Direction", - set_print_direction, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'a', 'L', - PCL_COMMAND( "Left Margin", - set_left_margin, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'a', 'M', - PCL_COMMAND( "Right Margin", - set_right_margin, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'E', - PCL_COMMAND( "Top Margin", - set_top_margin, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'F', - PCL_COMMAND( "Text Length", - set_text_length, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'L', - PCL_COMMAND( "Perforation Skip", - set_perforation_skip, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'M', - PCL_COMMAND( "Media Type", - pcl_media_type, - pca_neg_ok | pca_big_ignore - ) - }, - END_CLASS - - DEFINE_ESCAPE( '9', - "Clear Horizontal Margins", - clear_horizontal_margins - ) - - DEFINE_CLASS_COMMAND_ARGS( '*', - 'o', - 'Q', - "Print Quality", - pcl_print_quality, - pca_neg_ok | pca_big_ignore - ) - return 0; -} - - private pcl_paper_size_t * -get_default_paper( - pcl_state_t * pcs -) -{ - int i; - pjl_envvar_t *psize = pjl_proc_get_envvar(pcs->pjls, "paper"); - pcs->wide_a4 = false; - for (i = 0; i < countof(paper_sizes); i++) - if (!pjl_proc_compare(pcs->pjls, psize, paper_sizes[i].pname)) { - /* set wide a4, only used if the paper is a4 */ - if (!pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "widea4"), "YES")) - pcs->wide_a4 = true; - return &(paper_sizes[i].psize); - } - dprintf("system does not support requested paper setting\n"); - return &(paper_sizes[1].psize); -} - - private void -pcpage_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - if ((type & (pcl_reset_initial | pcl_reset_printer)) != 0) { - pcs->paper_source = 0; /* ??? */ - pcs->xfm_state.left_offset_cp = 0.0; - pcs->xfm_state.top_offset_cp = 0.0; - pcs->perforation_skip = 1; - new_logical_page( pcs, - !pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, - "orientation"), - "portrait") ? 0 : 1, - get_default_paper(pcs), - (type & pcl_reset_initial) != 0 - ); - } else if ((type & pcl_reset_overlay) != 0) { - pcs->perforation_skip = 1; - pcs->xfm_state.print_dir = 0; - update_xfm_state(pcs, 0); - reset_margins(pcs); - pcl_xfm_reset_pcl_pat_ref_pt(pcs); - } -} - -const pcl_init_t pcpage_init = { pcpage_do_registration, pcpage_do_reset, 0 }; diff --git a/pcl/pcpage.h b/pcl/pcpage.h deleted file mode 100644 index b7067df61..000000000 --- a/pcl/pcpage.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpage.c - PCL5 page and transformation control interface */ - -#ifndef pcpage_INCLUDED -#define pcpage_INCLUDED - -#include "pcstate.h" -#include "pcommand.h" - -/* set the page output procedure */ -void pcl_set_end_page(P1(int (*procp)(pcl_state_t *, int, int))); - -/* - * End a page, either unconditionally or only if there are marks on it. - * Return 1 if the page was actually printed and erased. - */ -typedef enum { - pcl_print_always, - pcl_print_if_marked -} pcl_print_condition_t; - -int pcl_end_page(P2( - pcl_state_t * pcs, - pcl_print_condition_t condition -)); - -void new_logical_page(P4( - pcl_state_t * pcs, - int lp_orient, - const pcl_paper_size_t * psize, - bool reset_initial -)); - - int -pcl_getdevice_initial_matrix(P2(pcl_state_t * pcs, - gs_matrix * mat -)); - - int -pcl_current_bounding_box(P2(pcl_state_t * pcs, - gs_rect * pbbox -)); - -bool pcl_page_marked(P1( - pcl_state_t * pcs -));; - -#define pcl_end_page_always(pcs) pcl_end_page((pcs), pcl_print_always) -#define pcl_end_page_if_marked(pcs) pcl_end_page((pcs), pcl_print_if_marked) - -extern const pcl_init_t pcpage_init; - -#endif /* pcpage_INCLUDED */ diff --git a/pcl/pcpalet.c b/pcl/pcpalet.c deleted file mode 100644 index 1872c0c2e..000000000 --- a/pcl/pcpalet.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpalet.c - PCL 5c palette object implementation */ -#include "gx.h" -#include "pldict.h" -#include "pcdraw.h" -#include "pcpage.h" -#include "pcursor.h" -#include "pcpalet.h" -#include "pcfrgrnd.h" - -/* GC routines */ -private_st_palette_t(); -private_st_pstack_entry_t(); - -/* - * Free a PCL palette. - */ - private void -free_palette( - gs_memory_t * pmem, - void * pvpalet, - client_name_t cname -) -{ - pcl_palette_t * ppalet = (pcl_palette_t *)pvpalet; - - if (ppalet->pindexed != 0) - pcl_cs_indexed_release(ppalet->pindexed); - if (ppalet->pcrd != 0) - pcl_crd_release(ppalet->pcrd); - if (ppalet->pht != 0) - pcl_ht_release(ppalet->pht); - gs_free_object(pmem, pvpalet, cname); -} - -/* - * Free procedure for palettes to be used by the dictionary which implements - * the palette store. - */ - private void -dict_free_palette( - gs_memory_t * pmem, - void * pvpalet, - client_name_t cname -) -{ - pcl_palette_t * ppalet = (pcl_palette_t *)pvpalet; - - rc_decrement(ppalet, cname); -} - -/* - * Allocat a PCL palette object. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -alloc_palette( - pcl_state_t * pcs, - pcl_palette_t ** pppalet, - gs_memory_t * pmem -) -{ - pcl_palette_t * ppalet = 0; - - rc_alloc_struct_1( ppalet, - pcl_palette_t, - &st_palette_t, - pmem, - return e_Memory, - "allocate pcl palette object" - ); - ppalet->rc.free = free_palette; - ppalet->id = pcl_next_id(pcs); - ppalet->pindexed = 0; - ppalet->pcrd = 0; - ppalet->pht = 0; - *pppalet = ppalet; - return 0; -} - -/* - * Create a unique copy of a PCL palette. - * - * The unsharing of PCL palettes is a bit involved due to the nature of the - * palette store. In normal handling, the current PCL state does not maintain - * a reference to the current palette. Rather, it keeps the current palette id., - * and the definition of this id. in the dictionary that implements the palette - * store is the only reference to the palette. - * - * The structure of XL dictionaries is (properly) opaque, so there is no direct - * access is available to pointer to a palette. Furthermore, the dictionary - * get, put, and undef procedures do not recognize object structure, hence they - * provide no native support for reference counted objects. - * - * To work around these problems, a separate pointer to a palette is maintained - * in the PCL, though one that does not normally counted as a reference. The - * make-unique operation will modify this pointer, and immediately redefine - * the current palette id. - * - * To simplify the remainder of this code, unshared palettes are given new - * identifiers, even if the unshare operation does nothing. This operation is - * specifically overridden when modifying pen widths, since the latter are never - * cached. - * - * Unlike the "unshare" functions for other objects, this function will create - * the PCL palette object if it does not already exist. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -unshare_palette( - pcl_state_t * pcs -) -{ - pcl_palette_t * ppalet = pcs->ppalet; - pcl_palette_t * pnew = 0; - int code = 0; - pcl_id_t key; - - /* check if there is anything to do */ - if ((ppalet != 0) && (ppalet->rc.ref_count == 1)) { - ppalet->id = pcl_next_id(pcs); - return 0; - } - - /* allocate a new palette */ - if ((code = alloc_palette(pcs, &pnew, pcs->memory)) < 0) - return code; - if (ppalet != 0) { - pcl_cs_indexed_init_from(pnew->pindexed, ppalet->pindexed); - pcl_crd_init_from(pnew->pcrd, ppalet->pcrd); - pcl_ht_init_from(pnew->pht, ppalet->pht); - } - - /* redefine the current palette id. */ - pcs->ppalet = pnew; - id_set_value(key, pcs->sel_palette_id); - code = pl_dict_put(&pcs->palette_store, id_key(key), 2, pnew); - return (code == -1 ? e_Memory : 0); -} - -/* - * Build a default palette, and define it to be the currently selected - * palette. - */ - private int -build_default_palette( - pcl_state_t * pcs -) -{ - pcl_id_t key; - gs_memory_t * pmem = pcs->memory; - pcl_palette_t * ppalet = 0; - int code = 0; - - if (pcs->pdflt_palette == 0) { - code = alloc_palette(pcs, &ppalet, pmem); - if (code == 0) - code = pcl_cs_indexed_build_default_cspace( pcs, - &(ppalet->pindexed), - pmem - ); - if ((code == 0) && (pcs->pcl_default_crd == 0)) - code = pcl_crd_build_default_crd(pcs); - if (code == 0) - pcl_crd_init_from(ppalet->pcrd, pcs->pcl_default_crd); - if (code == 0) - code = pcl_ht_build_default_ht(pcs, &(ppalet->pht), pmem); - if (code < 0) { - if (ppalet != 0) - free_palette(pmem, ppalet, "build default palette"); - return code; - } - pcl_palette_init_from(pcs->pdflt_palette, ppalet); - } else - pcl_palette_init_from(ppalet, pcs->pdflt_palette); - - - /* NB: definitions do NOT record a referece */ - id_set_value(key, pcs->sel_palette_id); - code = pl_dict_put(&pcs->palette_store, id_key(key), 2, ppalet); - if (code < 0) - return e_Memory; - - /* the graphic state pointer does not (yet) amount to a reference */ - pcs->ppalet = ppalet; - return 0; -} - -/* - * Clear the palette stack. - */ - void -clear_palette_stack( - pcl_state_t * pcs, - gs_memory_t * pmem -) -{ - pstack_entry_t * pentry = pcs->palette_stack; - - while (pentry != 0) { - pstack_entry_t * pnext = pentry->pnext; - - pcl_palette_release(pentry->ppalet); - gs_free_object(pmem, pentry, "clear palette stack"); - pentry = pnext; - } - pcs->palette_stack = 0; -} - -/* - * ESC * p # P - * - * Push a copy of the current palette onto the palette stack, or pop one off. - * Note the need to redefine the select palette id. in the event that a palette - * is popped. - */ - private int -push_pop_palette( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int action = uint_arg(pargs); - - if (action == 0) { - pstack_entry_t * pentry; - int code; - - /* if there is not yet a palette, build the default */ - if ((pcs->ppalet == 0) && ((code = build_default_palette(pcs)) < 0)) - return code; - - pentry = gs_alloc_struct( pcs->memory, - pstack_entry_t, - &st_pstack_entry_t, - "push pcl palette" - ); - if (pentry == 0) - return e_Memory; - - pcl_palette_init_from(pentry->ppalet, pcs->ppalet); - pentry->pnext = pcs->palette_stack; - pcs->palette_stack = pentry; - - return 0; - - } else if (action == 1) { - pstack_entry_t * pentry = pcs->palette_stack; - int code = 0; - - if (pentry != 0) { - pcl_id_t key; - - pcs->palette_stack = pentry->pnext; - - /* NB: just set - pcs->ppalet is not a reference */ - pcs->ppalet = pentry->ppalet; - - /* the dictionary gets the stack reference on the palette */ - id_set_value(key, pcs->sel_palette_id); - code = pl_dict_put(&pcs->palette_store, id_key(key), 2, pentry->ppalet); - gs_free_object(pcs->memory, pentry, "pop pcl palette"); - } - - return (code < 0 ? e_Memory : 0); - - } else - return 0; -} - - -/* - * Set the normalization values for an indexed color space. This is needed - * only for the GL/2 CR command; PCL sets normalization information via the - * configure image data command, which builds a new indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_CR( - pcl_state_t * pcs, - floatp wht0, - floatp wht1, - floatp wht2, - floatp blk0, - floatp blk1, - floatp blk2 -) -{ - int code = unshare_palette(pcs); - - /* if the default color space must be built, it is fixed, so don't bother */ - if (pcs->ppalet->pindexed == 0) - return code; - - if (code == 0) - code = pcl_cs_indexed_set_norm_and_Decode( &(pcs->ppalet->pindexed), - wht0, - wht1, - wht2, - blk0, - blk1, - blk2 - ); - return code; -} - -/* - * Set the number of entries in a color palette. This is needed only for the - * GL/2 NP command; PCL sets the number of entries in a palette via the - * configure image data command, which creates a new indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_NP( - pcl_state_t * pcs, - int num_entries -) -{ - int code = unshare_palette(pcs); - - /* if the default color space must be built, it is fixed, so don't bother */ - if (pcs->ppalet->pindexed == 0) - return code; - - if (code == 0) - code = pcl_cs_indexed_set_num_entries( &(pcs->ppalet->pindexed), - num_entries, - true - ); - return code; -} - -/* - * Set the render method for the palette. - * - * Returns 0 on success, < 0 in the event of an error. - * - * The value of the render method is not checked against the existing value, - * since the fact that two are the same is neither a necessary nor sufficient - * condition for determining that the render algorithm has changed: it is - * possible that the rendering remap array (see pcht.c) has been modified. - */ - int -pcl_palette_set_render_method( - pcl_state_t * pcs, - uint render_method -) -{ - int code = unshare_palette(pcs); - - if ((code == 0) && (pcs->ppalet->pht == 0)) - code = pcl_ht_build_default_ht(pcs, &(pcs->ppalet->pht), pcs->memory); - if (code >= 0) - code = pcl_ht_set_render_method(pcs, &(pcs->ppalet->pht), render_method); - if (code >= 0) - pcs->render_mode = render_method; - return code; -} - -/* - * Set gamma correction information for a palette. - * - * Gamma correction and the color lookup table for device specific color spaces - * perform the same function, but are of different origins. Hence, while a - * configure image data command will discard all color lookup tables, it inherits - * the gamma configuration parameter from the existing palette. In addition, - * while there is an "unset" command for color lookup tables, there is no such - * command for gamma correction: to override the existing gamma correction, - * either specify a new one or download a color correction table for a device - * specific color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_set_gamma( - pcl_state_t * pcs, - float gamma -) -{ - int code = unshare_palette(pcs); - - if ((code == 0) && (pcs->ppalet->pht == 0)) - code = pcl_ht_build_default_ht(pcs, &(pcs->ppalet->pht), pcs->memory); - if (code == 0) - code = pcl_ht_set_gamma(&(pcs->ppalet->pht), gamma); - return code; -} - -/* - * Set color lookup table information for a palette. - * - * Lookup tables for device-specific and device-independent color spaces are - * implemented in different ways. The former are implemented via transfer - * functions, and thus affect the halftone component of the current palette. - * The latter are implemented in the device-independent color spaces themselves, - * and thus affect the color spaces component of the palette. - * - * An anachronism of the PCL is that, while color lookup tables may be set - * individually for different color spaces, they only be cleared all at once. - * This is accomplished by calling this routine with a null lookup table pointer. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_set_lookup_tbl( - pcl_state_t * pcs, - pcl_lookup_tbl_t * plktbl -) -{ - int code = unshare_palette(pcs); - pcl_cspace_type_t lktype; - - if ((code == 0) && (pcs->ppalet->pindexed == 0)) - code = pcl_cs_indexed_build_default_cspace( pcs, - &(pcs->ppalet->pindexed), - pcs->memory - ); - if ((code == 0) && (pcs->ppalet->pht == 0)) - code = pcl_ht_build_default_ht(pcs, &(pcs->ppalet->pht), pcs->memory); - if (code < 0) - return code; - - /* all look tables are cleared simultaneously */ - if (plktbl != 0) - lktype = pcl_lookup_tbl_get_cspace(plktbl); - if ((plktbl == 0) || (lktype <= pcl_cspace_CMY)) - code = pcl_ht_set_lookup_tbl(&(pcs->ppalet->pht), plktbl); - if ( (code == 0) && ((plktbl == 0) || (lktype >= pcl_cspace_Colorimetric)) ) - code = pcl_cs_indexed_update_lookup_tbl(&(pcs->ppalet->pindexed), plktbl); - return code; -} - -/* - * Set an entry in a color palette. - * - * Returns 0 on success, < 0 in the event of an error. The returned code will - * normally be ignored. - */ - int -pcl_palette_set_color( - pcl_state_t * pcs, - int indx, - const float comps[3] -) -{ - int code = unshare_palette(pcs); - - /* if the default color space must be built, it is fixed, so don't bother */ - if (pcs->ppalet->pindexed == 0) - return code; - - if (code == 0) - code = pcl_cs_indexed_set_palette_entry( &(pcs->ppalet->pindexed), - indx, - comps - ); - return code; -} - -/* - * Set a palette entry to its default color. - * - * Returns 0 on success, < 0 in the event of an error. The returned code will - * normally be ignored. - */ - int -pcl_palette_set_default_color( - pcl_state_t * pcs, - int indx -) -{ - int code = unshare_palette(pcs); - - /* if the default color space must be built, it is fixed, so don't bother */ - if (pcs->ppalet->pindexed == 0) - return code; - - if (code == 0) - code = pcl_cs_indexed_set_default_palette_entry( &(pcs->ppalet->pindexed), - indx - ); - return code; -} - -/* - * Set a pen width. Note that this does NOT change the palette id. This - * procedure can only be called from GL/2, hence the procedure name. - * - * Returns 0 on success, < 0 in the even of an error; - */ - int -pcl_palette_PW( - pcl_state_t * pcs, - int pen, - floatp width -) -{ - int code = 0; - pcl_gsid_t palette_id; - pcl_palette_t * ppalet = pcs->ppalet; - - if (ppalet != 0) { - pcl_cs_indexed_t * pindexed = ppalet->pindexed; - - if ( (pindexed != 0) && - (pen >= 0) && - (pen < pcl_cs_indexed_get_num_entries(pindexed)) && - (width == pcl_cs_indexed_get_pen_widths(pindexed)[pen]) ) - return 0; - - palette_id = ppalet->id; - if ((code = unshare_palette(pcs)) < 0) - return code; - ppalet = pcs->ppalet; - ppalet->id = palette_id; - - } else { - if ((code = unshare_palette(pcs)) < 0) - return code; - ppalet = pcs->ppalet; - } - - return pcl_cs_indexed_set_pen_width(&(ppalet->pindexed), pen, width); -} - -/* - * Set the user-defined dither matrix. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_set_udither( - pcl_state_t * pcs, - pcl_udither_t * pdither -) -{ - int code = unshare_palette(pcs); - - if ((code == 0) && (pcs->ppalet->pht == 0)) - code = pcl_ht_build_default_ht(pcs, &(pcs->ppalet->pht), pcs->memory); - if (code == 0) - code = pcl_ht_set_udither(&(pcs->ppalet->pht), pdither); - return code; -} - -/* - * Overwrite the current palette with new a new image data configuration. - * This will rebuild the indexed color space, and discard any currently - * installed color lookup tables. - * - * Tf the operand "fixed" is true, this procedure is being called as part of - * a "simple color mode" command, and the resulting color palette will have - * fixed entries. - * - * The boolean operand gl2 indicates if this call is being made as the result - * of an IN command in GL/2. If so, the default set of entries in the color - * palette is modified. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_set_cid( - pcl_state_t * pcs, - pcl_cid_data_t * pcid, - bool fixed, - bool gl2 -) -{ - int code = unshare_palette(pcs); - pcl_palette_t * ppalet = pcs->ppalet; - pcl_cspace_type_t cstype_new = pcl_cid_get_cspace(pcid); - pcl_cspace_type_t cstype_old; - - if (code < 0) - return code; - - /* record the old color space type, if it is present */ - if (ppalet->pindexed != 0) - cstype_old = (pcl_cspace_type_t)ppalet->pindexed->cid.cspace; - else - cstype_old = cstype_new; - - /* pcl_cspace_bnuild_indexed_cspace will release the old space */ - code = pcl_cs_indexed_build_cspace( pcs, - &(ppalet->pindexed), - pcid, - fixed, - gl2, - pcs->memory - ); - - /* if a halftone exist, inform it of the update and discard lookup tables */ - if ((code == 0) && (ppalet->pht != 0)) { - code = pcl_ht_update_cspace(pcs, &(ppalet->pht), cstype_old, cstype_new); - if (code == 0) - code = pcl_ht_set_lookup_tbl(&(ppalet->pht), NULL); - } - - return code; -} - -/* - * Set the view illuminant for a palette. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_set_view_illuminant( - pcl_state_t * pcs, - const gs_vector3 * pwht_pt -) -{ - int code = unshare_palette(pcs); - - if ((code == 0) && (pcs->ppalet->pcrd == 0)) { - if ((code = pcl_crd_build_default_crd(pcs)) == 0) - pcl_crd_init_from(pcs->ppalet->pcrd, pcs->pcl_default_crd); - } - if (code == 0) - code = pcl_crd_set_view_illuminant(pcs, &(pcs->ppalet->pcrd), pwht_pt); - return code; -} - -/* - * Check that all parts of a PCL palette have been built. If not, build the - * necessary default objects. - * - * This procedure should never be required, as the reset operation should build - * a default palette, but it is kept in case that routine does not succeed. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_palette_check_complete( - pcl_state_t * pcs -) -{ - pcl_palette_t * ppalet = pcs->ppalet; - int code = 0; - - if ( (ppalet != 0) && - (ppalet->pindexed != 0) && - (ppalet->pcrd != 0) && - (ppalet->pht != 0) ) - return 0; - - if ((code = unshare_palette(pcs)) < 0) - return code; - ppalet = pcs->ppalet; - if (ppalet->pindexed == 0) - code = pcl_cs_indexed_build_default_cspace( pcs, - &(ppalet->pindexed), - pcs->memory - ); - if ((code == 0) && (ppalet->pcrd == 0)) { - if ((code = pcl_crd_build_default_crd(pcs)) == 0) - pcl_crd_init_from(pcs->ppalet->pcrd, pcs->pcl_default_crd); - } - if ((code == 0) && (ppalet->pht == 0)) - code = pcl_ht_build_default_ht(pcs, &(ppalet->pht), pcs->memory); - return code; -} - - -/* - * ESC & p # S - * - * Change the select palette id. Note that, since the pointer to the palette in - * the pcl state does not count as a reference, no reference counts are adjusted. - */ - private int -set_sel_palette_id( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint id = uint_arg(pargs); - pcl_id_t key; - - /* ignore attempts to select non-existent palettes */ - id_set_value(key, id); - if ( pl_dict_lookup( &pcs->palette_store, - id_key(key), - 2, - (void **)&(pcs->ppalet), - false, - NULL - ) ) - pcs->sel_palette_id = id; - return 0; -} - -/* - * ESC & p # I - * - * Set the palette control id. - */ - private int -set_ctrl_palette_id( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->ctrl_palette_id = uint_arg(pargs); - return 0; -} - -/* - * Clear the palette store. This will delete the current palette, but will - * NOT build the default palette in its place. - * - * If the current palette id. already has the default palette assigned, don't - * bother removing it. This is helpful when working with memory leak detection - * tools. - */ - private void -clear_palette_store( - pcl_state_t * pcs -) -{ - pl_dict_enum_t denum; - void * pvalue; - gs_const_string plkey; - int sel_id = pcs->sel_palette_id; - - pl_dict_enum_begin(&pcs->palette_store, &denum); - while (pl_dict_enum_next(&denum, &plkey, &pvalue)) { - int id = (((int)plkey.data[0]) << 8) + plkey.data[1]; - - if (id == sel_id) { - if (pvalue != pcs->pdflt_palette) - build_default_palette(pcs); /* will redefine sel_id */ - } else - pl_dict_undef(&pcs->palette_store, plkey.data, plkey.size); - } -} - -/* - * ESC & p # C - * - * Palette control - */ - private int -palette_control( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint action = uint_arg(pargs); - - switch (action) { - - case 0: - clear_palette_store(pcs); - break; - - case 1: - clear_palette_stack(pcs, pcs->memory); - break; - - case 2: - if (pcs->ctrl_palette_id == pcs->sel_palette_id) { - if ((pcs->ppalet == 0) || (pcs->ppalet != pcs->pdflt_palette)) - build_default_palette(pcs); - } else { - pcl_id_t key; - - id_set_value(key, pcs->ctrl_palette_id); - pl_dict_undef(&pcs->palette_store, id_key(key), 2); - } - break; - - case 6: - if (pcs->ctrl_palette_id != pcs->sel_palette_id) { - pcl_id_t key; - int code = 0; - - /* NB: definitions don't incremente refernece counts */ - id_set_value(key, pcs->ctrl_palette_id); - code = pl_dict_put(&pcs->palette_store, id_key(key), 2, pcs->ppalet); - if (code < 0) - return code; - rc_increment(pcs->ppalet); - - } - break; - - default: - return e_Range; - } - - return 0; -} - -/* - * ESC * t # J - * - * Set render method. The rendering method is specifically part of the PCL - * halftone structure, but the setting command is included here because it - * must run via the palette mechanism. - */ - private int -set_render_algorithm( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - return pcl_palette_set_render_method(pcs, uint_arg(pargs)); -} - -/* - * ESC & b # M - * - * Set monochrome or normal print mode. Note that, for a change in the print - * mode to take effect, the current rendering mode must be reset. - * - * NB: Unlike certain other commands, a monochrome print command always ejects - * the current page if it has been marked, even if no change in the print - * mode occurs. - */ - private int -set_print_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint mode = uint_arg(pargs); - int code = 0; - - if (mode > 1) - return 0; - - if ((code = pcl_end_page_if_marked(pcs)) < 0) - return code; - pcl_home_cursor(pcs); - - pcs->monochrome_mode = (mode == 1); - pcl_ht_set_print_mode(pcs, pcs->monochrome_mode); - return pcl_palette_set_render_method(pcs, pcs->render_mode); -} - -/* - * Initialization routine for palettes. - */ - private int -palette_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ -#ifndef PCL5EMONO - DEFINE_CLASS('*') - { - 'p', 'P', - PCL_COMMAND( "Push/Pop Palette", - push_pop_palette, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 't', 'J', - PCL_COMMAND( "Render Algorithm", - set_render_algorithm, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS - - DEFINE_CLASS('&') - { - 'b', 'M', - PCL_COMMAND( "Monochrome Printing", - set_print_mode, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 'p', 'S', - PCL_COMMAND( "Select Palette", - set_sel_palette_id, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 'p', 'I', - PCL_COMMAND( "Palette Control ID", - set_ctrl_palette_id, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 'p', 'C', - PCL_COMMAND( "Palette Control", - palette_control, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS -#endif - return 0; -} - -/* - * Reset routine for palettes. - */ - private void -palette_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_cold - | pcl_reset_printer - | pcl_reset_overlay - | pcl_reset_permanent); - - if ((type & mask) == 0) - return; - - /* for initial reset, set up the palette store */ - if ((type & pcl_reset_initial) != 0) { - pl_dict_init(&pcs->palette_store, pcs->memory, dict_free_palette); - pcs->ppalet = 0; - pcs->pfrgrnd = 0; - pcs->pdflt_frgrnd = 0; - /* set up the built-in render methods and dithers matrices */ - pcl_ht_init_render_methods(pcs, pcs->memory); - - /* handle possible non-initialization of BSS */ - pcs->pdflt_palette = 0; - pcs->palette_stack = 0; - pcs->pcl_default_crd = 0; - pcl_cs_base_init(pcs); - pcl_cs_indexed_init(pcs); - - } else if ((type & (pcl_reset_cold | pcl_reset_printer | pcl_reset_permanent)) != 0) { - /* clear the palette stack and store */ - clear_palette_stack(pcs, pcs->memory); - clear_palette_store(pcs); - } - if ( type & pcl_reset_permanent ) { - pcl_palette_release(pcs->pdflt_palette); - pcl_palette_release(pcs->ppalet); - } - /* select and control palette ID's must be set back to 0 */ - pcs->sel_palette_id = 0; - pcs->ctrl_palette_id = 0; - - if ( !(type & pcl_reset_permanent) ) { - (void)build_default_palette(pcs); - (void)pcl_frgrnd_set_default_foreground(pcs); - } -} - -/* - * The copy function for palettes. - * - * This procedure implements the two most unusual features of the palette - * object: - * - * The palette pointer becomes a reference on the palette when the - * state is saved. - * - * When the state is restored, the palette in the saved state is used - * to re-define the select palette id. in the palette store. Palettes are - * the only PCL resource object with this behavior. - * - * It is not clear HP intended palette to have this behavior. More likely, - * it was a by-product of the way in which they implemented the save/restore - * for foregrounds. - * - * Note that, in the restore case, the dictionary definition absorbs the - * reference to the palette held by the saved state, so there is no need to - * explicitly release this reference (an example of the asymmetric define/ - * undefine properties of the pl_dict_t object). - */ - private int -palette_do_copy( - pcl_state_t * psaved, - const pcl_state_t * pcs, - pcl_copy_operation_t operation -) -{ - if ((operation & (pcl_copy_before_call | pcl_copy_before_overlay)) != 0) - pcl_palette_init_from(psaved->ppalet, pcs->ppalet); - else if ((operation & pcl_copy_after) != 0) { - pcl_id_t key; - /* fix the compiler warning resulting from overuse of const */ - pcl_state_t *pcs2 = (pcl_state_t *)pcs; - id_set_value(key, psaved->sel_palette_id); - pl_dict_put(&pcs2->palette_store, id_key(key), 2, psaved->ppalet); - } - return 0; -} - -const pcl_init_t pcl_palette_init = { - palette_do_registration, palette_do_reset, palette_do_copy -}; diff --git a/pcl/pcpalet.h b/pcl/pcpalet.h deleted file mode 100644 index 6d40a8790..000000000 --- a/pcl/pcpalet.h +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpalet.h - PCL palette object */ - -#ifndef pcpalet_INCLUDED -#define pcpalet_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "pcident.h" -#include "pcstate.h" -#include "pcommand.h" -#include "pclookup.h" -#include "pcdither.h" -#include "pccid.h" -#include "pcindxed.h" -#include "pcht.h" -#include "pccrd.h" - -/* - * The PCL palette. - * - * The identifier is used to indicate when colored patterns need to be - * re-rendered. - * - * A curious feature of the PCL palette is not the object itself, but the - * manner in which it is stored in the PCL state. During normal operation, - * the PCL state does not maintain a reference to a plette. Rather, it - * maintains a current installed palette ID, which can be searched for the - * in the appropriate dictionary to find the current palette. Changes to - * the current palette update this entry directly. - * - * In the case of a called or overlayed macro, however, the saved PCL state - * will create its own reference to the palette, as well as retaining the - * current palette id. in effect at the time the palette was saved. When the - * state is subsequently restored, the save palette is once more associated - * with the save palette id. Hence, the end of a called or overlay macro can - * lead to a redefinition in the palette store. This is inconsistent with - * the way all other identified objects are handled in PCL, but it is the - * mechanism HP selected. - */ -struct pcl_palette_s { - rc_header rc; - pcl_gsid_t id; - pcl_cs_indexed_t * pindexed; - pcl_crd_t * pcrd; - pcl_ht_t * pht; -}; - -#ifndef pcl_palette_DEFINED -#define pcl_palette_DEFINED -typedef struct pcl_palette_s pcl_palette_t; -#endif - -#define private_st_palette_t() \ - gs_private_st_ptrs3( st_palette_t, \ - pcl_palette_t, \ - "pcl palette object", \ - palette_enum_ptrs, \ - palette_reloc_ptrs, \ - pindexed, \ - pcrd, \ - pht \ - ) - - -/* - * The usual init, copy,and release macros. - */ -#define pcl_palette_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_palette_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_palette_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_palette_release(pbase) \ - rc_decrement(pbase, "pcl_frgrnd_release") - - -/* - * Get the color space type for the base color space of a palette. - */ -#define pcl_palette_get_cspace(ppalet) \ - ((pcl_cspace_type_t)((ppalet)->pindexed->cid.cspace)) - -/* - * Get the pixel encoding mode from the current palette. - */ -#define pcl_palette_get_encoding(ppalet) \ - ((pcl_encoding_type_t)((ppalet)->pindexed->cid.encoding)) - -/* - * Get the number of bits per index from the current palette. - */ -#define pcl_palette_get_bits_per_index(ppalet) \ - ((ppalet)->pindexed->cid.bits_per_index) - -/* - * Get the number of bits per primary from the current palette. - */ -#define pcl_palette_get_bits_per_primary(ppalet, i) \ - ((ppalet)->pindexed->cid.bits_per_primary[i]) - -/* - * Macro to return the number or entries in the current palette. - */ -#define pcl_palette_get_num_entries(ppalet) \ - pcl_cs_indexed_get_num_entries((ppalet)->pindexed) - -/* - * Macro to return a pointer to the array of pen widths. - */ -#define pcl_palette_get_pen_widths(ppalet) \ - pcl_cs_indexed_get_pen_widths((ppalet)->pindexed) - -/* - * Set the normalization values for an indexed color space. This is needed - * only for the GL/2 CR command; PCL sets normalization information via the - * configure image data command, which builds a new indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_CR(P7( - pcl_state_t * pcs, - floatp wht0, - floatp wht1, - floatp wht2, - floatp blk0, - floatp blk1, - floatp blk2 -)); - -/* - * Set the number of entries in a color palette. This is needed only for the - * GL/2 NP command; PCL sets the number of entries in a palette via the - * configure image data command, which creates a new indexed color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_NP(P2(pcl_state_t * pcs, int num_entries)); - -/* - * Set a pen width. Note that this does NOT change the palette id. This - * procedure can only be called from GL/2, hence the procedure name. - * - * Returns 0 on success, < 0 in the even of an error; - */ -int pcl_palette_PW(P3(pcl_state_t * pcs, int pen, floatp width)); - -/* - * Support for the GL/2 IN command. This is actually implemented in pccid.c, - * but an interface is included here for consistency. - */ -#define pcl_palette_IN(pcs) pcl_cid_IN(pcs) - -/* - * Set the render method for the palette. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_render_method(P2( - pcl_state_t * pcs, - uint render_method -)); - -/* - * Set gamma correction information for a palette. - * - * Gamma correction and the color lookup table for device specific color spaces - * perform the same function, but are of different origins. Hence, while a - * configure image data command will discard all color lookup tables, it inherits - * the gamma configuration parameter from the existing palette. In addition, - * while there is an "unset" command for color lookup tables, there is no such - * command for gamma correction: to override the existing gamma correction, - * either specify a new one or download a color correction table for a device - * specific color space. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_gamma(P2(pcl_state_t * pcs, float gamma)); - -/* - * Set color lookup table information for a palette. - * - * Lookup tables for device-specific and device-independent color spaces are - * implemented in different ways. The former are implemented via transfer - * functions, and thus affect the halftone component of the current palette. - * The latter are implemented in the device-independent color spaces themselves, - * and thus affect the color spaces component of the palette. - * - * An anachronism of the PCL is that, while color lookup tables may be set - * individually for different color spaces, they only be cleared all at once. - * This is accomplished by calling this routine with a null lookup table pointer. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_lookup_tbl(P2( - pcl_state_t * pcs, - pcl_lookup_tbl_t * plktbl -)); - -/* - * Set an entry in a color palette. - * - * Returns 0 on success, < 0 in the event of an error. The returned code will - * normally be ignored. - */ -int pcl_palette_set_color(P3( - pcl_state_t * pcs, - int indx, - const float comps[3] -)); - -/* - * Set a palette entry to its default color. - * - * Returns 0 on success, < 0 in the event of an error. The returned code will - * normally be ignored. - */ -int pcl_palette_set_default_color(P2( - pcl_state_t * pcs, - int indx -)); - -/* - * Set the user-defined dither matrix. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_udither(P2( - pcl_state_t * pcs, - pcl_udither_t * pdither -)); - -/* - * Overwrite the current palette with new a new image data configuration. - * This will rebuild the indexed color space, and discard any currently - * installed color lookup tables. - * - * Tf the operand "fixed" is true, this procedure is being called as part of - * a "simple color mode" command, and the resulting color palette will have - * fixed entries. - * - * The boolean operand gl2 indicates if this call is being made as the result - * of an IN command in GL/2. If so, the default set of entries in the color - * palette is modified. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_cid(P4( - pcl_state_t * pcs, - pcl_cid_data_t * pcid, - bool fixed, - bool gl2 -)); - -/* - * Set the view illuminant for a palette. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_set_view_illuminant(P2( - pcl_state_t * pcs, - const gs_vector3 * pwht_pt -)); - -/* - * Check that all parts of a PCL palette have been built. If not, build the - * necessary default objects. - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_palette_check_complete(P1(pcl_state_t * pcs)); - - -#define private_st_pstack_entry_t() \ - gs_private_st_ptrs1( st_pstack_entry_t, \ - pstack_entry_t, \ - "palette stack entry", \ - pstack_enum_ptrs, \ - pstack_reloc_ptrs, \ - ppalet \ - ); - -/* - * Entry points to the palette-related commands. - */ -extern const pcl_init_t pcl_palette_init; -extern const pcl_init_t pcl_color_init; - -#endif /* pcpalet_INCLUDED */ diff --git a/pcl/pcparam.h b/pcl/pcparam.h deleted file mode 100644 index 98592b637..000000000 --- a/pcl/pcparam.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* - * pcparam.h - Definitions for PCL5 parameter setting - * Requires gsmemory.h - */ - -#ifndef pcparam_INCLUDED -# define pcparam_INCLUDED - -#include "gsparam.h" - -/* - * Put a single device parameter. - * Return 0 if OK, 1 if must reopen device, or an error code. - */ -int put_param1_bool(P3(pcl_state_t *, gs_param_name, bool)); -int put_param1_float(P3(pcl_state_t *, gs_param_name, floatp)); -int put_param1_int(P3(pcl_state_t *, gs_param_name, int) ); -int put_param1_float_array(P3(pcl_state_t *, gs_param_name, float[2])); - -#endif /* pcparam_INCLUDED */ diff --git a/pcl/pcparse.c b/pcl/pcparse.c deleted file mode 100644 index 7285d0274..000000000 --- a/pcl/pcparse.c +++ /dev/null @@ -1,615 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcparse.c */ -/* PCL5 parser */ -#include "stdio_.h" -#include "gdebug.h" -#include "gstypes.h" -#include "scommon.h" -#include "pcparse.h" -#include "pcstate.h" /* for display_functions */ -#include "pcursor.h" -#include "rtgmode.h" - -/* We don't know whether an Enable Display Functions takes effect while */ -/* defining a macro. To play it safe, we're providing both options. */ -/* If the following #define is uncommented, E.D.F. *does* take effect */ -/* while scanning a macro definition. */ -/*#define DISPLAY_FUNCTIONS_IN_MACRO*/ - -/* ---------------- Command definition ---------------- */ - -/* Register a command. Return true if this is a redefinition. */ -private bool -pcl_register_command(byte *pindex, const pcl_command_definition_t *pcmd, - pcl_parser_state_t *pcl_parser_state) -{ int index = pcl_parser_state->definitions->pcl_command_next_index; - byte prev = *pindex; - - if ( prev != 0 && prev <= index && pcl_parser_state->definitions->pcl_command_list[prev] == pcmd ) - index = prev; - else if ( index != 0 && pcl_parser_state->definitions->pcl_command_list[index] == pcmd ) - ; - else - pcl_parser_state->definitions->pcl_command_list[pcl_parser_state->definitions->pcl_command_next_index = ++index] = pcmd; - *pindex = index; - return (prev != 0 && prev != index); -} - -/* Define a command or list of commands. */ -void -pcl_define_control_command(int/*char*/ chr, const pcl_command_definition_t *pcmd, - pcl_parser_state_t *pcl_parser_state) -{ -#ifdef DEBUG - if ( chr < 0 || chr >= countof(pcl_parser_state->definitions->pcl_control_command_indices) ) - if_debug1('I', "Invalid control character %d\n", chr); - else if ( -#endif - pcl_register_command(&pcl_parser_state->definitions->pcl_control_command_indices[chr], pcmd, pcl_parser_state) -#ifdef DEBUG - ) - if_debug1('I', "Redefining control character %d\n", chr); -#endif - ; -} -void -pcl_define_escape_command(int/*char*/ chr, - const pcl_command_definition_t *pcmd, pcl_parser_state_t *pcl_parser_state) -{ -#ifdef DEBUG - if ( chr < min_escape_2char || chr > max_escape_2char ) - if_debug1('I', "Invalid escape character %c\n", chr); - else if ( -#endif - pcl_register_command(&pcl_parser_state->definitions->pcl_escape_command_indices - [chr - min_escape_2char], pcmd, - pcl_parser_state) -#ifdef DEBUG - ) - if_debug1('I', "Redefining ESC %c\n", chr) -#endif - ; -} - -/* - * Convert escape classes to second level dispatch indices. - */ -private const byte pcl_escape_class_indices[max_escape_class - min_escape_class + 1] = { - 0, 0, 0, 0, 1/*%*/, 2/*&*/, 0, 3/*(*/, 4/*)*/, 5/***/, 0, 0, 0, 0, 0 -}; - -void -pcl_define_class_command(int/*char*/ class, int/*char*/ group, - int/*char*/ command, const pcl_command_definition_t *pcmd, pcl_parser_state_t *pcl_parser_state) -{ -#ifdef DEBUG - if ( class < min_escape_class || class > max_escape_class || - pcl_escape_class_indices[class - min_escape_class] == 0 || - (group != 0 && (group < min_escape_group || group > max_escape_group)) || - command < min_escape_command || command > max_escape_command - ) - if_debug3('I', "Invalid command %c %c %c\n", class, group, command); - else if ( -#endif - pcl_register_command(&pcl_parser_state->definitions->pcl_grouped_command_indices - [pcl_escape_class_indices[class - min_escape_class] - 1] - [group == 0 ? 0 : group - min_escape_group + 1] - [command - min_escape_command], pcmd, - pcl_parser_state) -#ifdef DEBUG - ) - if_debug3('I', "Redefining ESC %c %c %c\n", class, - (group == 0 ? ' ' : group), command) -#endif - ; -} -void -pcl_define_class_commands(int/*char*/ class, - const pcl_grouped_command_definition_t *pgroup, pcl_parser_state_t *pcl_parser_state) -{ const pcl_grouped_command_definition_t *pgc = pgroup; - - for ( ; pgc->command != 0; ++pgc ) - pcl_define_class_command(class, pgc->group, pgc->command, - &pgc->defn, pcl_parser_state); -} - -/* - * Look up an escape command. The arguments are as follows: - * ESC x 0, 0, 'x' - * ESC ? <arg> c '?', 0, 'c' - * ESC ? b <arg> c '?', 'b', 'c' - * The caller is responsible for providing valid arguments. - */ -private const pcl_command_definition_t * -pcl_get_command_definition(pcl_parser_state_t *pcl_parser_state, int/*char*/ class, int/*char*/ group, - int/*char*/ command) -{ const pcl_command_definition_t *cdefn = 0; - - if ( class == 0 ) - {if ( command >= min_escape_2char && command <= max_escape_2char ) - cdefn = pcl_parser_state->definitions->pcl_command_list - [pcl_parser_state->definitions->pcl_escape_command_indices[command - min_escape_2char]]; - } - else - { int class_index = pcl_escape_class_indices[class - min_escape_class]; - if ( class_index ) - cdefn = pcl_parser_state->definitions->pcl_command_list - [pcl_parser_state->definitions->pcl_grouped_command_indices[class_index - 1] - [group ? group - min_escape_group + 1 : 0] - [command - min_escape_command] - ]; - } -#ifdef DEBUG - if ( cdefn == 0 ) - { if ( class == 0 ) - if_debug1('I', "ESC %c undefined\n", command); - else if ( group == 0 ) - if_debug2('I', "ESC %c %c undefined\n", class, command); - else - if_debug3('I', "ESC %c %c %c undefined\n", class, group, command); - } -#endif - return cdefn; -} - -/* ---------------- Parsing ---------------- */ - -/* Initialize the parser state. */ -void -pcl_process_init(pcl_parser_state_t *pst) -{ pcl_parser_init_inline(pst); -} - -/* Adjust the argument value according to the command's argument type. */ -/* Return 1 if the command should be ignored. */ -private int -pcl_adjust_arg(pcl_args_t *pargs, const pcl_command_definition_t *pdefn) -{ uint acts = pdefn->actions; - - if ( value_is_neg(&pargs->value) ) - { if ( pargs->value.i == 0 && - (!value_is_float(&pargs->value) || - pargs->value.fraction == 0) - ) - arg_set_uint(pargs, 0); - else switch ( acts & pca_neg_action ) - { - case pca_neg_clamp: - arg_set_uint(pargs, 0); break; - case pca_neg_error: - return e_Range; - case pca_neg_ignore: - return 1; - default: /* case pca_neg_ok */ - ; - } - } - else if ( pargs->value.i > 32767 ) /* overflowed int range */ - switch ( acts & pca_big_action ) - { - case pca_big_clamp: - arg_set_uint(pargs, 32767); break; - case pca_big_error: - return e_Range; - case pca_big_ignore: - return 1; - default: /* case pca_big_ok */ - ; - } - return 0; -} - -/* Append some just-scanned input data to the macro being defined. */ -private int -append_macro(const byte *from, const byte *to, pcl_state_t *pcs) -{ uint count = to - from; - uint size = gs_object_size(pcs->memory, pcs->macro_definition); - byte *new_defn = - gs_resize_object(pcs->memory, pcs->macro_definition, size + count, - "append_macro"); - - if ( new_defn == 0 ) - return_error(e_Memory); - memcpy(new_defn + size, from + 1, count); - pcs->macro_definition = new_defn; - return 0; -} - -/* Process a buffer of PCL commands. */ -int -pcl_process(pcl_parser_state_t *pst, pcl_state_t *pcs, stream_cursor_read *pr) -{ const byte *p = pr->ptr; - const byte *rlimit = pr->limit; - int code = 0; - bool in_macro = pcs->defining_macro; - /* Record how much of the input we've copied into a macro */ - /* in the process of being defined. */ - const byte *macro_p = p; - -/* Reset the parameter scanner */ -#define avalue pst->args.value -#define param_init()\ - (avalue.type = pcv_none, avalue.i = 0) - -#ifdef DISPLAY_FUNCTIONS_IN_MACRO -# define do_display_functions() 1 -#else -# define do_display_functions() (!in_macro) -#endif - - while ( p < rlimit ) - { byte chr; - const pcl_command_definition_t *cdefn = NULL; - - switch ( pst->scan_type ) - { - case scanning_data: - { /* Accumulate command data in a buffer. */ - uint count = uint_arg(&pst->args); - uint pos = pst->data_pos; - - if ( pos < count ) - { uint avail = rlimit - p; - uint copy = min(count - pos, avail); - - memcpy(pst->args.data + pos, p + 1, copy); - pst->data_pos += copy; - p += copy; - continue; - } - /* Invoke the command. */ - cdefn = pcl_get_command_definition(pst, - pst->param_class, - pst->param_group, - pst->args.command); - pst->scan_type = scanning_none; - break; - } - case scanning_display: - { /* Display, don't execute, all characters. */ - chr = *++p; - if ( chr == ESC ) - { int index; - if ( p >= rlimit ) - goto x; - if ( p[1] >= min_escape_2char && p[1] <= max_escape_2char && - (index = pst->definitions->pcl_escape_command_indices[p[1] - min_escape_2char]) != 0 && - pst->definitions->pcl_command_list[index]->proc == - pcl_disable_display_functions - ) - { if ( do_display_functions() ) - { pst->args.command = chr; - code = pcl_plain_char(&pst->args, pcs); - if ( code < 0 ) - goto x; - } - pst->args.command = chr = *++p; - pcl_disable_display_functions(&pst->args, pcs); - pst->scan_type = scanning_none; - } - } - if ( do_display_functions() ) - { if ( chr == CR ) - { pcl_do_CR(pcs); - code = pcl_do_LF(pcs); - } - else - { pst->args.command = chr; - code = pcl_plain_char(&pst->args, pcs); - } - if ( code < 0 ) - goto x; - } - continue; - } - case scanning_parameter: - for ( ; ; ) - { if ( p >= rlimit ) - goto x; - chr = *++p; - /* - * The parser for numbers is very lenient, and accepts - * many strings that aren't valid numbers. If this - * ever becomes a problem, we can tighten it up.... - */ - if ( chr >= '0' && chr <= '9' ) - { chr -= '0'; - if ( value_is_float(&avalue) ) - avalue.fraction += (chr / (pst->scale *= 10)); - else - avalue.type |= pcv_int, - avalue.i = avalue.i * 10 + chr; - } - else if ( chr == '-' ) - avalue.type |= pcv_neg; - else if ( chr == '+' ) - avalue.type |= pcv_pos; - else if ( chr == '.' ) - avalue.type |= pcv_float, - avalue.fraction = 0, - pst->scale = 1.0; - else if ( chr >= ' ' && chr <= '?' ) - { /* Ignore garbage nearby in the code space. */ - continue; - } - else - break; - } -#ifdef DEBUG - if ( gs_debug_c('i') ) - { dprintf2("(ESC %c %c)", - pst->param_class, pst->param_group); - if ( value_is_present(&avalue) ) - { dputc(' '); - if ( value_is_signed(&avalue) ) - dputc((value_is_neg(&avalue) ? '-' : '+')); - if ( value_is_float(&avalue) ) - dprintf1("%g", avalue.i + avalue.fraction); - else - dprintf1("%u", avalue.i); - } - dprintf1(" %c\n", chr); - } -#endif - if ( chr >= min_escape_command + 32 && - chr <= max_escape_command + 32 - ) - chr -= 32; - else if ( chr >= min_escape_command && - chr <= max_escape_command - ) - pst->scan_type = scanning_none; - else - { pst->scan_type = scanning_none; - /* Rescan the out-of-place character. */ - --p; - continue; - } - /* Dispatch on param_class, param_group, and chr. */ - cdefn = pcl_get_command_definition(pst, - pst->param_class, - pst->param_group, - chr); - if ( cdefn ) - { if_debug1('i', " [%s]\n", cdefn->cname); - code = pcl_adjust_arg(&pst->args, cdefn); - if ( code < 0 ) - goto x; - if ( cdefn->actions & pca_byte_data ) - { uint count = uint_arg(&pst->args); - if ( rlimit - p <= count ) - { /* Allocate a buffer for the data. */ - pst->args.data = - gs_alloc_bytes(pcs->memory, count, - "command data"); - if ( pst->args.data == 0 ) - { --p; - code = gs_note_error(e_Memory); - goto x; - } - pst->args.data_on_heap = true; - pst->args.command = chr; - pst->data_pos = 0; - pst->scan_type = scanning_data; - continue; - } - pst->args.data = (byte *)(p + 1); - pst->args.data_on_heap = false; - p += count; - } - break; - } - param_init(); - continue; - case scanning_none: - if ( pcs->parse_other ) - { /* - * Hand off the data stream - * to another parser (HP-GL/2). - */ - pr->ptr = p; - code = (*pcs->parse_other) - (pcs->parse_data, pcs, pr); - p = pr->ptr; - if ( code < 0 || (code == 0 && pcs->parse_other) ) - goto x; - } - chr = *++p; - if ( chr != ESC ) - { if_debug1('i', - (chr == '\\' ? "\\%c\n" : - chr >= 33 && chr <= 126 ? - "%c\n" : "\\%03o\n"), - chr); - cdefn = pst->definitions->pcl_command_list - [chr < 33 ? - pst->definitions->pcl_control_command_indices[chr] : - pst->definitions->pcl_control_command_indices[1]]; - if ( (cdefn == 0 || - cdefn->proc == pcl_plain_char) && - !in_macro && - !pcs->parse_other && - !pcs->raster_state.graphics_mode - ) - { /* - * Look ahead for a run of plain text. - * We can be very conservative about this, - * because this is only a performance - * enhancement. - */ - const byte *str = p; - while ( p < rlimit && p[1] >= 32 && - p[1] <= 127 - ) - { if_debug1('i', "%c", p[1]); - ++p; - } - if_debug0('i', "\n"); - code = pcl_text(str, (uint)(p + 1 - str), - pcs, false); - if ( code < 0 ) - goto x; - cdefn = NULL; - } - } - else - { if ( p >= rlimit ) { --p; goto x; } - chr = *++p; - if ( chr < min_escape_class || - chr > max_escape_class - ) - { if_debug1('i', - (chr >= 33 && chr <= 126 ? - "ESC %c\n" : - "ESC \\%03o\n"), - chr); - cdefn = - pcl_get_command_definition(pst, 0, 0, chr); - if ( !cdefn ) - { /* Skip only the ESC. */ - --p; - continue; - } - if_debug1('i', " [%s]\n", - cdefn->cname); - } - else - { if ( p >= rlimit ) { p -= 2; goto x; } - pst->param_class = chr; - chr = *++p; - if ( chr < min_escape_group || - chr > max_escape_group - ) - { /* Class but no group */ - --p; - chr = 0; - } - pst->param_group = chr; - if_debug2('i', "ESC %c %c\n", - pst->param_class, chr); - pst->scan_type = scanning_parameter; - param_init(); - continue; - } - } - break; - } - if ( cdefn == NULL ) - { param_init(); - continue; - } - if ( !in_macro || (cdefn->actions & pca_in_macro) ) - { /* This might be the end-of-macro command. */ - /* Make sure all the data through this point */ - /* has been captured in the macro definition. */ - if ( in_macro ) - { code = append_macro(macro_p, p, pcs); - macro_p = p; - if ( code < 0 ) - goto x; - } - pst->args.command = chr; - if ( !pcs->raster_state.graphics_mode || - (cdefn->actions & pca_raster_graphics) || - (code = pcl_end_graphics_mode(pcs)) >= 0 - ) { - if ( (pcs->personality != rtl) || - ((pcs->personality == rtl) && (cdefn->actions & pca_in_rtl)) ) - code = (*cdefn->proc)(&pst->args, pcs); - } - /* - * If we allocated a buffer for command data, - * and the command didn't take possession of it, - * free it now. */ - if ( pst->args.data_on_heap && pst->args.data ) - { gs_free_object(pcs->memory, pst->args.data, - "command data"); - pst->args.data = 0; - } - if ( code == e_Unimplemented ) - { -#if e_Unimplemented != 0 - if_debug0('i', "Unimplemented\n"); -#endif - } - else if ( code < 0 ) - break; - if ( pcs->display_functions ) - { /* This calls for a special parsing state. */ - pst->scan_type = scanning_display; - } - if ( pcs->defining_macro && !in_macro ) - { /* We just started a macro definition. */ - macro_p = p; - } - in_macro = pcs->defining_macro; - } - else - { /* - * If we allocated a buffer for command data, - * free it now. - */ - if ( pst->args.data_on_heap && pst->args.data ) - { gs_free_object(pcs->memory, pst->args.data, - "command data"); - pst->args.data = 0; - } - } - param_init(); - } -x: pr->ptr = p; - /* Append the last bit of data to the macro, if defining. */ - if ( in_macro ) - { int mcode = append_macro(macro_p, p, pcs); - if ( mcode < 0 && code >= 0 ) - code = mcode; - } - return code; -} - -/* inialize the pcl command counter */ - int -pcl_init_command_index(pcl_parser_state_t *pcl_parser_state, pcl_state_t *pcs) -{ - pcl_command_definitions_t *definitions = - (pcl_command_definitions_t *)gs_alloc_bytes(pcs->memory, - sizeof(pcl_command_definitions_t), - "pcl_init_command_index"); - /* fatal */ - if ( definitions == 0 ) - return -1; - /* we should set these individually but each field is properly - initialized to zero */ - memset(definitions, 0, sizeof(pcl_command_definitions_t)); - /* plug command definitions into the parser state and a pointer - for the command definitions into pcl's state for use by macros, - I don't like this but the alternative is getting the parser - state to the code that executer macros which is inconvenient at - this time */ - pcs->pcl_commands = pcl_parser_state->definitions = definitions; - return 0; -} - -/* for now deallocates the memory associated with the command definitions */ - int -pcl_parser_shutdown(pcl_parser_state_t *pcl_parser_state, gs_memory_t *mem) -{ - gs_free_object(mem, pcl_parser_state->definitions, - "pcl_parser_shutdown"); - return 0; -} -/* ---------------- Initialization ---------------- */ - -void -pcparse_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ - if ( type & (pcl_reset_initial | pcl_reset_printer) ) - pcs->parse_other = 0; -} - -const pcl_init_t pcparse_init = { - 0, pcparse_do_reset -}; diff --git a/pcl/pcparse.h b/pcl/pcparse.h deleted file mode 100644 index 90ff69b3a..000000000 --- a/pcl/pcparse.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcparse.h */ -/* Interface and definitions for PCL5 parser */ - -#ifndef pcparse_INCLUDED -# define pcparse_INCLUDED - -#include "gsmemory.h" -#include "scommon.h" -#include "pcommand.h" - -/* Define the lexical state of the scanner. */ -typedef enum { - scanning_none, - scanning_parameter, - scanning_display, /* display_functions mode */ - scanning_data /* data following a command */ -} pcl_scan_type_t; - -#define min_escape_2char '0' -#define max_escape_2char '~' -#define min_escape_class '!' -#define max_escape_class '/' -#define min_escape_group '`' -#define max_escape_group '~' -#define min_escape_command '@' /* or '`' */ -#define max_escape_command '^' /* or '~' */ - -typedef struct pcl_command_definitions_s { - /* - * First-level dispatch for control characters. - */ - byte pcl_control_command_indices[33]; - /* - * Second-level dispatch for 2-character escape sequences. - */ - byte pcl_escape_command_indices[max_escape_2char - min_escape_2char + 1]; - /* - * Dispatch on class, group, and command. - */ - byte pcl_grouped_command_indices - [5 /* number of implemented classes, see escape_class_indices above */] - [1 + max_escape_group - min_escape_group + 1] - [max_escape_command - min_escape_command + 1]; - int pcl_command_next_index; - /* - * We register all the PCL5* commands dynamically, for maximum configuration - * flexibility. pcl_command_list points to the individual command - * definitions; as each command is registered, we enter it in the list, and - * then store its index in the actual dispatch table - * (pcl_xxx_command_xxx_indices). - */ - pcl_command_definition_t *pcl_command_list[256]; -} pcl_command_definitions_t; - -/* Define the state of the parser. */ -struct pcl_parser_state_s { - /* Internal state */ - pcl_scan_type_t scan_type; - pcl_args_t args; - double scale; /* for accumulating floating numbers */ - byte param_class, param_group; /* for parameterized commands */ - uint data_pos; /* for data crossing buffer boundaries */ - hpgl_parser_state_t *hpgl_parser_state; - pcl_command_definitions_t *definitions; -}; -#define pcl_parser_init_inline(pst)\ - ((pst)->scan_type = scanning_none, (pst)->args.data = 0) - -/* Define the prefix of a macro definition. */ -typedef struct pcl_macro_s { - pcl_data_storage_t storage; -} pcl_macro_t; - -/* ---------------- Procedural interface ---------------- */ - -/* Allocate a parser state. */ -pcl_parser_state_t *pcl_process_alloc(P1(gs_memory_t *memory)); - -/* Initialize the PCL parser. */ -void pcl_process_init(P1(pcl_parser_state_t *pst)); - -/* Process a buffer of PCL commands. */ -int pcl_process(P3(pcl_parser_state_t *pst, pcl_state_t *pcs, - stream_cursor_read *pr)); - -/* Execute a macro (in pcmacros.c). */ -int pcl_execute_macro(P5(const pcl_macro_t *pmac, pcl_state_t *pcs, - pcl_copy_operation_t before, pcl_reset_type_t reset, - pcl_copy_operation_t after)); - -void pcparse_do_reset(P2(pcl_state_t *pcs, pcl_reset_type_t type)); - -int pcl_init_command_index(P2(pcl_parser_state_t *pcl_parser_state, pcl_state_t *pcs)); - -/* shutdown the pcl parser */ -int pcl_parser_shutdown(P2(pcl_parser_state_t *pcl_parser_state, gs_memory_t *mem)); -#endif /* pcparse_INCLUDED */ diff --git a/pcl/pcpatrn.c b/pcl/pcpatrn.c deleted file mode 100644 index 7fac463c8..000000000 --- a/pcl/pcpatrn.c +++ /dev/null @@ -1,1386 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpatrn.c - code for PCL and GL/2 patterns, including color */ - -#include "gx.h" -#include "gsuid.h" -#include "gsmatrix.h" -#include "gspcolor.h" -#include "pccid.h" -#include "pcfont.h" -#include "pcpalet.h" -#include "pcfrgrnd.h" -#include "pcht.h" -#include "pcwhtidx.h" -#include "pcpatrn.h" -#include "pcbiptrn.h" -#include "pcuptrn.h" -#include "pcpatxfm.h" - - - -/* - * The base color space for setting the color white. Unlike all other color - * spaces in PCL, this uses the DeviceGray color space in the graphic library. - * - * A copy of the default halftone is also maintained for setting the color - * "white". Since the halftone carries the device-specific color lookup tables, - * a non-standard halftone might end up mapping white to black (definitely - * undesirable). - */ -private const gs_paint_color white_paint = {{ 1.0, 0.0, 0.0, 0.0 }}; - -/* GC routines */ -private_st_ccolor_t(); - - -/* - * Convert a color value specified as a three-element byte array, or an index - * to a palette, into a gs_paint_color structure. - */ - private void -convert_color_to_paint( - const byte * pcomp, - gs_paint_color * ppaint -) -{ - ppaint->values[0] = (float)pcomp[0] / 255.0; - ppaint->values[1] = (float)pcomp[1] / 255.0; - ppaint->values[2] = (float)pcomp[2] / 255.0; - ppaint->values[3] = 0.0; -} - - private void -convert_index_to_paint( - int indx, - gs_paint_color * ppaint -) -{ - ppaint->values[0] = indx; - ppaint->values[1] = 0.0; - ppaint->values[2] = 0.0; - ppaint->values[3] = 0.0; -} - -/* - * Set the halftone and color rendering dictionary objects from the - * current palette. This will check that the palette is complete. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_ht_crd_from_palette( - pcl_state_t * pcs -) -{ - int code = 0; - pcl_cspace_type_t cstype = pcl_palette_get_cspace(pcs->ppalet); - pcl_palette_t * ppalet = 0; - - /* check that the palette is complete */ - pcl_palette_check_complete(pcs); - ppalet = pcs->ppalet; - - /* install crd and ht */ - code = pcl_ht_set_halftone(pcs, &(ppalet->pht), cstype, false); - if (code == 0) - code = pcl_crd_set_crd(&(ppalet->pcrd), pcs); - return code; -} - -/* - * Set the halftone and color rendering dictionary objects from the current - * foreground. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_ht_crd_from_foreground( - pcl_state_t * pcs -) -{ - int code = 0; - pcl_frgrnd_t * pfrgrnd = pcs->pfrgrnd; - pcl_cspace_type_t cstype = pcl_frgrnd_get_cspace(pfrgrnd); - - /* install crd and ht */ - code = pcl_ht_set_halftone(pcs, &(pfrgrnd->pht), cstype, false); - if (code == 0) - code = pcl_crd_set_crd(&(pfrgrnd->pcrd), pcs); - return code; -} - - -/* - * Free a PCL client color structure. - */ - private void -free_ccolor( - gs_memory_t * pmem, - void * pvccolor, - client_name_t cname -) -{ - pcl_ccolor_t * pccolor = (pcl_ccolor_t *)pvccolor; - - pcl_pattern_data_release(pccolor->ppat_data); - pcl_cs_indexed_release(pccolor->pindexed); - pcl_cs_base_release(pccolor->pbase); - if (pccolor->prast != 0) - gs_free_object(pmem, (void *)pccolor->prast, cname); - gs_pattern_reference(&(pccolor->ccolor), -1); - gs_free_object(pmem, pvccolor, cname); -} - -/* - * Make a unique copy of a PCL client color structure. This function also - * serves as the allocator function. - * - * Because the byte array pointed to by the prast structure is not reference - * counted, the "copy" of the client color created this procedure will always - * have this pointer set to NULL. This is unfortunate and ugly, as it implies - * the copy cannot be used immediately as a client color, but it causes no - * trouble in the current context because: - * - * prast is non-null only for colored patterns - * the client color for a colored pattern would only be unshared - * if it was about to be rendered, in which case the prast - * array would need to be recreated. - * - * Newly created colors are solid white. - */ - private int -unshare_ccolor( - pcl_state_t * pcs, - pcl_ccolor_t ** ppccolor, - gs_memory_t * pmem -) -{ - pcl_ccolor_t * pold = *ppccolor; - pcl_ccolor_t * pnew = 0; - - if ((pold != NULL) && (pold->rc.ref_count == 1)) { - if (pold->prast != 0) - gs_free_object( pmem, - (void *)pold->prast, - "unshared PCL client color" - ); - pold->prast = 0; - return 0; - } - rc_decrement(pold, "unshare PCL client color object"); - - rc_alloc_struct_1( pnew, - pcl_ccolor_t, - &st_ccolor_t, - pmem, - return e_Memory, - "allocate PCL client color" - ); - pnew->rc.free = free_ccolor; - pnew->prast = 0; - - if (pold != 0) { - pnew->type = pold->type; - pcl_pattern_data_init_from(pnew->ppat_data, pold->ppat_data); - pcl_cs_indexed_init_from(pnew->pindexed, pold->pindexed); - pcl_cs_base_init_from(pnew->pbase, pold->pbase); - pnew->ccolor = pold->ccolor; - gs_pattern_reference(&(pnew->ccolor), 1); - } else { - pnew->type = pcl_ccolor_unpatterned; - pnew->ppat_data = 0; - pnew->pindexed = 0; - - /* set the color space to pure white */ - pnew->pbase = 0; - (void)pcl_cs_base_build_white_cspace(pcs, &(pnew->pbase), pmem); - pnew->ccolor.paint = white_paint; - pnew->ccolor.pattern = 0; - } - - *ppccolor = pnew; - return 0; -} - -/* - * Set a solid color (unpattered) color. This is handled separately from - * patterns as it will usually not be necessary to build a PCL client color - * structure in this case. - * - * Exactly one of the pair of operands pbase and pindex shoud be non-null. - */ - private int -set_unpatterned_color( - pcl_state_t * pcs, - pcl_cs_indexed_t * pindexed, - pcl_cs_base_t * pbase, - const gs_paint_color * ppaint -) -{ - pcl_ccolor_t * pcur = pcs->pids->pccolor; - pcl_ccolor_type_t type = (pcur != 0 ? pcur->type - : pcl_ccolor_unpatterned); - int code = 0; - - if ( (pcur != 0) && - (type == pcl_ccolor_unpatterned) && - (pcur->pindexed == pindexed) && - (pcur->pbase == pbase) && - (pcur->ccolor.paint.values[0] == ppaint->values[0]) && - (pcur->ccolor.paint.values[1] == ppaint->values[1]) && - (pcur->ccolor.paint.values[2] == ppaint->values[2]) ) - return 0; - - if ( (code = unshare_ccolor(pcs, &(pcs->pids->pccolor), pcs->memory)) < 0 ) - return code; - pcur = pcs->pids->pccolor; - - pcur->type = pcl_ccolor_unpatterned; - if (pcur->ppat_data != 0) { - pcl_pattern_data_release(pcur->ppat_data); - pcur->ppat_data = 0; - } - - if (pindexed != 0) { - if ((type != pcl_ccolor_unpatterned) || (pcur->pindexed != pindexed)) - code = pcl_cs_indexed_install(&pindexed, pcs); - } else { /* pbase != 0 */ - if ((type != pcl_ccolor_unpatterned) || (pcur->pbase != pbase)) - code = pcl_cs_base_install(&pbase, pcs); - } - if (code < 0) - return code; - pcl_cs_indexed_copy_from(pcur->pindexed, pindexed); - pcl_cs_base_copy_from(pcur->pbase, pbase); - - gs_pattern_reference(&(pcur->ccolor), -1); - pcur->ccolor.pattern = 0; - pcur->ccolor.paint = *ppaint; - return gs_setcolor(pcs->pgs, &(pcur->ccolor)); -} - -/* - * Set a patterned color space. Note that this is a substantially different - * operation from setting a solid (unpatterned) color. - */ - private int -set_patterned_color( - pcl_state_t * pcs, - pcl_ccolor_t * pnew -) -{ - pcl_ccolor_t * pcur = pcs->pids->pccolor; - int code = 0; - - /* check if already set */ - if (pcur == pnew) - return 0; - - /* set a base color space for the pattern, if necessary */ - if (pnew->type == pcl_ccolor_mask_pattern) { - - if ( (pnew->pindexed != 0) && - ((pcur == 0) || (pcur->pindexed != pnew->pindexed)) ) - code = pcl_cs_indexed_install(&(pnew->pindexed), pcs); - - if ( (pnew->pbase != 0) && - ((pcur == 0) || (pcur->pbase != pnew->pbase)) ) - code = pcl_cs_base_install(&(pnew->pbase), pcs); - } - if (code < 0) - return code; - - /* set the pattern instance */ - if ((code = gs_setpattern(pcs->pgs, &(pnew->ccolor))) >= 0) - pcl_ccolor_copy_from(pcs->pids->pccolor, pnew); - return code; -} - -/* - * Check if the pattern pointed to by pptrn has a rendering and, if so, whether - * or not that rendering is appropriate for the curren environment. - * - * If the rendering is appropriate, install the conrresponding color; otherwise - * return false. - * - * The case of GL uncolored patterns rendered with patterns opaque is unique. - * In this case the pattern must be generated as a colored pattern (mask - * patterns are always transparent), with a specially generated 2-entry - * indexed color space. The cache_id field identifies the palette that gave - * rise to this pattern, but not the entry from that palette that was used - * as the foreground color. Hence, for this case alone there must be a match - * on the pen number key. To avoid the need for a much qualified check in this - * case, we use the convention that the pen number field is zero in all but - * this case. - * - * Note that a difference in the paint color does not require re-rendering; - * these fields are ignored for colored patterns, and for mask patterns changes - * only require another call to gs_setpattern. - */ - private bool -check_pattern_rendering( - pcl_state_t * pcs, - pcl_pattern_t * pptrn, - bool use_frgrnd, /* else use palette */ - uint pen_num, - bool colored, - const gs_paint_color * ppaint -) -{ - pcl_ccolor_t * pccolor = 0; - - /* check the common parameters first */ - if ( (pptrn->orient != pcs->pat_orient) || - (pptrn->ref_pt.x != pcs->pat_ref_pt.x) || - (pptrn->ref_pt.y != pcs->pat_ref_pt.y) ) - return false; - - if (colored) { - pcl_gsid_t cache_id = ( use_frgrnd ? pcs->pfrgrnd->id - : pcs->ppalet->id ); - - /* check that there is a rendering in the appropriate environment */ - if ( ((pccolor = pptrn->pcol_ccolor) == 0) || - (pptrn->transp != pcs->pattern_transparent) || - (pptrn->cache_id != cache_id) || - (pptrn->pen != pen_num) ) - return false; - - } else { /* mask pattern */ - pcl_cs_indexed_t * pindexed = (use_frgrnd ? 0 : pcs->ppalet->pindexed); - pcl_cs_base_t * pbase = (use_frgrnd ? pcs->pfrgrnd->pbase : 0); - - /* check if there is a rendering */ - if ((pccolor = pptrn->pmask_ccolor) == 0) - return false; - - /* handle changes in the "foreground" color or color space */ - if ( (pccolor->ccolor.paint.values[0] != ppaint->values[0]) || - (pccolor->ccolor.paint.values[1] != ppaint->values[1]) || - (pccolor->ccolor.paint.values[2] != ppaint->values[2]) || - (pccolor->pindexed != pindexed) || - (pccolor->pbase != pbase) ) { - - /* get a unique copy, and update the painting information */ - if (unshare_ccolor(pcs, &(pptrn->pmask_ccolor), pcs->memory) < 0) - return false; - pccolor = pptrn->pmask_ccolor; - - pcl_cs_indexed_copy_from(pccolor->pindexed, pindexed); - pcl_cs_base_copy_from(pccolor->pbase, pbase); - pccolor->ccolor.paint = *ppaint; - } - } - - return (set_patterned_color(pcs, pccolor) == 0); -} - -/* - * Render and set a pattern. - * - * In a somewhat unfortunate division of labor, this code sets some but not - * all of the cache keys in the pattern. The fields set are transparency, - * orientation, and reference point. The caller is responsible for setting - * the cache_id and pen number. - * - * If this routine is called, it may be assumed that the pattern needs to be - * rendered. - * - */ - private int -render_pattern( - pcl_state_t * pcs, - pcl_pattern_t * pptrn, - pcl_ccolor_type_t type, - pcl_cs_indexed_t * pindexed, - pcl_cs_base_t * pbase, - const gs_paint_color * ppaint, - int wht_indx, - bool remap -) -{ - int code = 0; - pcl_ccolor_t * pccolor = 0; - gs_color_space * pcspace; - gs_matrix mat; - gs_depth_bitmap pixinfo; - - /* - * If the orientation or reference point has changed, discard both - * renderings. Otherwise, just discard the one being modified. - * - * Note that the unshare function doubles as an allocator. - */ - if ( (pptrn->orient != pcs->pat_orient) || - (pptrn->ref_pt.x != pcs->pat_ref_pt.x) || - (pptrn->ref_pt.y != pcs->pat_ref_pt.y) ) { - if (type == pcl_ccolor_mask_pattern) { - pcl_ccolor_release(pptrn->pcol_ccolor); - pptrn->pcol_ccolor = 0; - } else { /* type == pcl_ccolor_colored_pattern */ - pcl_ccolor_release(pptrn->pmask_ccolor); - pptrn->pmask_ccolor = 0; - } - } - - /* un-share, or allocate, the appropriate client color */ - if (type == pcl_ccolor_mask_pattern) { - code = unshare_ccolor(pcs, &(pptrn->pmask_ccolor), pcs->memory); - pccolor = pptrn->pmask_ccolor; - pcspace = 0; - } else { /* type == pcl_ccolor_colored_pattern */ - code = unshare_ccolor(pcs, &(pptrn->pcol_ccolor), pcs->memory); - pccolor = pptrn->pcol_ccolor; - pcspace = pindexed->pcspace; - pptrn->transp = pcs->pattern_transparent; - } - if (code < 0) - return code; - - /* discard the existing pattern instance */ - gs_pattern_reference(&(pccolor->ccolor), -1); - pccolor->ccolor.pattern = 0; - - /* initialize the pattern data, if the client color is newly allocated */ - pccolor->type = type; - pcl_pattern_data_copy_from(pccolor->ppat_data, pptrn->ppat_data); - - /* set up the transformation and transparency information */ - pcl_xfm_get_pat_xfm(pcs, pptrn, &mat); - - /* set up the white index and remap as necessary */ - if (remap) { - code = pcl_cmap_map_raster( pindexed, - &wht_indx, - &(pptrn->ppat_data->pixinfo), - &pixinfo, - true, - pcs->memory - ); - if (code < 0) - return code; - pcspace = pindexed->pcspace; - if (pixinfo.data != pptrn->ppat_data->pixinfo.data) - pccolor->prast = pixinfo.data; - } else - pixinfo = pptrn->ppat_data->pixinfo; - - /* render the pattern */ - code = gs_makepixmappattern( &(pccolor->ccolor), - &pixinfo, - (pcspace == 0), - &mat, - no_UniqueID, - pcspace, - wht_indx, - pcs->pgs, - pcs->memory - ); - - /* if all is OK, install the pattern; otherwise clear the pattern */ - if (code >= 0) { - pcl_cs_indexed_copy_from(pccolor->pindexed, pindexed); - pcl_cs_base_copy_from(pccolor->pbase, pbase); - if (type == pcl_ccolor_mask_pattern) - pccolor->ccolor.paint = *ppaint; - code = set_patterned_color(pcs, pccolor); - } - return code; -} - -/* - * Set a pattern using the foreground parameters. - * - * The for-image boolean indicates if the foreground is being set to render - * a PCL raster. If so, and if the halftone/CRD combination for the foreground - * is not the same as for the palette, a colored pattern must be generated. - * This is because the CRD/halftone combination for the palette will be - * current at the time the pattern is loaded into the cache, and thus the - * color would be evaluated in the wrong context. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_frgrnd_pattern( - pcl_state_t * pcs, - pcl_pattern_t * pptrn, - bool for_image -) -{ - pcl_frgrnd_t * pfrgrnd = pcs->pfrgrnd; - pcl_cs_base_t * pbase = pfrgrnd->pbase; - pcl_cs_indexed_t * pindexed = 0; - pcl_ccolor_type_t type = pcl_ccolor_mask_pattern; - gs_paint_color paint; - bool colored = false; - int code = set_ht_crd_from_foreground(pcs); - int wht_indx = (pcs->pattern_transparent ? 0 : 2); - - if (code < 0) - return code; - - if ( (pfrgrnd->pht == pcs->ppalet->pht) && - (pfrgrnd->pcrd == pcs->ppalet->pcrd) ) - for_image = false; - colored = (for_image || !pcs->pattern_transparent); - - convert_color_to_paint(pfrgrnd->color, &paint); - if (check_pattern_rendering(pcs, pptrn, true, 0, colored, &paint)) - return 0; - - /* build the two-entry palette if necessary */ - if (colored) { - code = pcl_cs_indexed_build_special( &pindexed, - pbase, - pfrgrnd->color, - pcs->memory - ); - if (code < 0) - return code; - pbase = 0; - type = pcl_ccolor_colored_pattern; - } - - code = render_pattern( pcs, - pptrn, - type, - pindexed, - pbase, - &paint, - wht_indx, - false - ); - - /* release the extra reference to the indexed color space */ - if (colored) { - pcl_cs_indexed_release(pindexed); - if (code >= 0) { - pptrn->pen = 0; - pptrn->cache_id = pfrgrnd->id; - } - } - - return code; -} - -/* - * Set an uncolored pattern using the palette parameters and indicated pen - * number. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_uncolored_palette_pattern( - pcl_state_t * pcs, - pcl_pattern_t * pptrn, - int pen -) -{ - pcl_cs_indexed_t * pindexed = pcs->ppalet->pindexed; - pcl_ccolor_type_t type = pcl_ccolor_mask_pattern; - gs_paint_color paint; - bool colored = !pcs->pattern_transparent; - int code = set_ht_crd_from_palette(pcs); - - if (code < 0) - return code; - - convert_index_to_paint(pen, &paint); - if (check_pattern_rendering(pcs, pptrn, false, pen, colored, &paint)) - return 0; - - /* build the two-entry palette if necessary */ - if (colored) { - code = pcl_cs_indexed_build_special( &pindexed, - pindexed->pbase, - &(pindexed->palette.data[3 * pen]), - pcs->memory - ); - if (code < 0) - return code; - type = pcl_ccolor_colored_pattern; - } - - code = render_pattern(pcs, pptrn, type, pindexed, NULL, &paint, 2, false); - - /* release the extra reference to the indexed color space */ - if (colored) { - pcl_cs_indexed_release(pindexed); - if (code >= 0) { - pptrn->pen = pen; - pptrn->cache_id = pcs->ppalet->id; - } - } - - return code; -} - -/* - * Set a colored pattern. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -set_colored_pattern( - pcl_state_t * pcs, - pcl_pattern_t * pptrn -) -{ - pcl_cs_indexed_t * pindexed = pcs->ppalet->pindexed; - pcl_gsid_t cache_id = pcs->ppalet->id; - bool remap = pcs->pattern_transparent; - int code = set_ht_crd_from_palette(pcs); - - if (code < 0) - return code; - - if (check_pattern_rendering(pcs, pptrn, false, 0, true, NULL)) - return 0; - - code = render_pattern( pcs, - pptrn, - pcl_ccolor_colored_pattern, - pindexed, - NULL, - &white_paint, - (remap ? 0 : pindexed->num_entries), - remap - ); - if (code >= 0) { - pptrn->pen = 0; - pptrn->cache_id = cache_id; - } - - return code; -} - -/* - * Routines to set the current color space to a specific pattern. Since patterns - * have different sources, each with its own system of identifiers, there are - * several such routines. Each routine takes the current PCL state (including - * the GL/2 state) as an operand; the additional operands, if any, vary by - * routine type. - * - * pattern_set_white No additional operands. This routine - * will set the color space to DeviceRGB, the - * color to white, but will not override the - * source or pattern transparency. A special - * halftone with a null transfer function is used, - * to avoid possible re-mapping of white to some - * other color. - * - * pattern_set_pen Two additional operand: the pen number and a flag - * to suppress use of unsolid patterns. GL pens Use - * the indexed color space from the current palette - * as the color space, and the pen number operand as - * the index into this palette. The halftone and color - * rendering dictionaries are taken from the current - * palette. - * - * This routine is also used to set up the color to - * be used for PCL rasters. This is necessary because, - * while images in the graphic library carry their - * own color space, this space must be installed in - * a graphic state at least once inorder to be used - * (specifically, CIE color spaces have this - * requirement). In this situation, the use of the - * "unsolid pattern" for transparency, which is - * specific to GL, must be suppressed. - * - * Note that this routine does NOT set the current - * line width (it does not have sufficient - * information to convert the dimensions). - * - * pattern_set_frgrnd One additional operands. Sets currect base - * color space as the color space, and the - * foreground color as the current color. - * The third (NOT second) operand indicates if the - * foreground is being set to render a PCL raster. - * The latter case involves special considerations; - * see the paragraphs at the bottom of this comment - * for additional information. - * - * pattern_set_shade_pcl - * Two additional operands, the shade indensity - * value and whether or not the shade pattern is - * being set to render a PCL raster. - * - * This procedure is intended to be used by PCL. - * It generates the shade as a colored pattern from - * a two-element color palette consisting of the - * canonical white for the current base color space - * and the foreground color. The color space in the - * graphic state is set to Pattern color space and - * the current color is set to be the generated - * pattern. The halftone and color rendering dictionary - * objects are also taken from the current - * foreground. - * - * Special considerations apply if the pattern is - * being set to render a PCL raster. See the - * paragraphs at the bottom of this comment for - * additional information. - * - * pattern_set_shade_gl Two additional operands; the first provides - * the pattern intensity, the latter the pen - * number to be be used as the foreground color. - * This routine generates the pattern using a two - * entry palette consisting of canonical white in - * the current base color space, and the operand - * pen color from the current palette as the - * second. The color space in the graphic state - * is set to Pattern color space and the current - * color is set to the generated pattern. The - * halftone and color rendering dictionary objects - * are taken from the current palette. - * - * pattern_set_hatch_pcl - * Two additional operands, the index of the cross - * hatch pattern and an indication of whether or not - * the pattern is being set to render a PCL raster. - * - * Similar to pcl_pattern_set_shade_pcl, but for - * cross-hatch patterns. - * - * pattern_set_hatch_gl Two additional operands; the first provides - * the index of the cross hatch pattern, the - * latter the pen number to be used as the - * foreground color. Similar to - * pcl_pattern_set_shade_gl, but for cross hatch - * patterns. - * - * pattern_set_user_pcl - * Two additional operands, the user pattern id. and - * and indicator of whether or not the pattern is being - * set to render a PCL raster. - * - * Handling is based on whether the pattern is - * colored or uncolored. - * - * For uncolored patterns, handling is similar - * to pcl_pattern_set_shade_pcl. The special - * consideration for rasters apply only in this case. - * - * For colored patterns, the pattern is generated - * using the indexed color space in the current - * color palette. The color space in the graphic - * state is set to Pattern color space, the current - * color is set to the generated pattern, and the - * halftone and color rendering dictionary objects - * are taken from the current palette. - * - * pattern_set_user_gl Two additional operands. The first provides the - * PCL user-defined pattern id. The second is the - * current pen. Handling is base on whether the - * pattern is colored or uncolored. - * - * For uncolored patterns, handling is similar - * to pcl_pattern_set_shade_gl. - * - * For colored patterns, handling is similar to - * pcl_pattern_set_user_pcl. - * - * pattern_set_gl_RF Two additional operands, the index of the - * GL/2 user defined pattern (created with the - * RF command), and the current pen number. The - * latter is used only for unoclored RF patterns. - * - * To keep life interesting, HP inserted a very - * odd feature into the behavior of uncolored - * RF patterns. Generally, the applicable SV or - * FT command determines whether the current pen - * or pen 1 is to be used for the foreground pixels. - * However, if the reference pattern does not exist, - * the current pen is always used. - * - * To accommodate this behavior within the current - * scheme, the current pen is passed as a negative - * number if pen 1 is for a pattern that exists. - * - * All procedures return 0 on success, < 0 in the event of an error. - * - * If that did not seem to make things complex enough, some additional - * complications arise for transparency in GL/2 and for PCL rasters. - * - * GL/2 has a concept of transparency similar to PCL's, though what GL terms - * "source" transparency corresponds to PCL's pattern transparency (all GL/2 - * objects are mask; hence, they have neither color nor background, so the - * PCL concept of source transparency is irrelevant for them). Unlike PCL, - * however, uncolored patterns in GL/2 are fully transparent if the current - * pen is white. The normal code for uncolored patterns is not equipped to - * handle this situation, and it make little sense to modify it for what is - * not a particular useful case. Hence, a special "unsolid" uncolored pattern - * is provided. This pattern has only background, and thus is fully transparent. - * - * The difficulty with PCL rasters is that, being colored objects, they make - * use of a CRD and a halftone to render. Rasters may also interact with the - * current color, which may be using a different CRD and halftone. - * - * The CRD and halftone to be used with rasters are taken from the current - * PCL palette. If the current pattern is either solid foreground (the most - * typical case) or an uncolored pattern, the current "texture" is generated - * using the CRD and halftone from the PCL foreground. The two may not be the - * same, and unfortunately there is room for only one of each in the graphic - * state. - * - * The solution is to make use of an additional graphic state. Patterns in the - * graphic library have their own graphic state. Hence, but converting a solid - * foreground into an uncolored pattern which happens to be "on" everywhere, it - * is possible to achieve the desired result. For performance reasons, this - * should be done only when necessary. - */ - - private int -pattern_set_white( - pcl_state_t * pcs, - int arg1, /* ignored */ - int arg2 /* ignored */ -) -{ - int code = set_ht_crd_from_foreground(pcs); - pcl_cs_base_t * pwhite_cs = 0; - pcl_ht_t * pdflt_ht = 0; - - if (code < 0) - return code; - - /* build the pure white color space and default halftone if necessary */ - if ((code = pcl_cs_base_build_white_cspace(pcs, &pwhite_cs, pcs->memory)) >= 0) - code = pcl_ht_build_default_ht(pcs, &pdflt_ht, pcs->memory); - - /* set the halftone and color space */ - if (code >= 0) - code = pcl_ht_set_halftone(pcs, &pdflt_ht, pcl_cspace_RGB, false); - pcl_ht_release(pdflt_ht); - if (code >= 0) - code = set_unpatterned_color(pcs, NULL, pwhite_cs, &white_paint); - pcl_cs_base_release(pwhite_cs); - return code; -} - -private int pattern_set_shade_gl( - pcl_state_t * pcs, - int inten, /* intensity value */ - int pen /* pen number for foreground */ -); - - private int -pattern_set_pen( - pcl_state_t * pcs, - int pen, - int for_pcl_raster -) -{ - pcl_cs_indexed_t * pindexed = pcs->ppalet->pindexed; - int num_entries = pindexed->num_entries; - int code = 0; - - /* put the pen number in the proper range */ - if ( (pen >= num_entries) && - ((pen = (pen % num_entries) + 1) == num_entries) ) - pen = 1; - - /* check if the current pen is white; if so, use the "unsolid" pattern */ - if (!for_pcl_raster && pcl_cs_indexed_is_white(pindexed, pen)) - return pattern_set_shade_gl(pcs, 1, pen); - - /* set halftone and crd from the palette */ - code = set_ht_crd_from_palette(pcs); - - if (code >= 0) { - gs_paint_color paint; - - convert_index_to_paint(pen, &paint); - code = set_unpatterned_color(pcs, pindexed, NULL, &paint); - } - return code; -} - - private int -pattern_set_frgrnd( - pcl_state_t * pcs, - int arg1, /* ignored */ - int for_image -) -{ - pcl_frgrnd_t * pfrgrnd = pcs->pfrgrnd; - pcl_palette_t * ppalet = pcs->ppalet; - int code = set_ht_crd_from_foreground(pcs); - - if (code < 0) - return code; - - /* check if a solid pattern should be substituted */ - if ( for_image && - ((pfrgrnd->pht != ppalet->pht) || - (pfrgrnd->pcrd != ppalet->pcrd) ) ) { - code = set_frgrnd_pattern(pcs, pcl_pattern_get_solid_pattern(pcs), true); - if (code >= 0) - code = set_ht_crd_from_palette(pcs); - } else { - gs_paint_color paint; - - convert_color_to_paint(pfrgrnd->color, &paint); - code = set_unpatterned_color(pcs, NULL, pfrgrnd->pbase, &paint); - } - - return code; -} - - private int -pattern_set_shade_pcl( - pcl_state_t * pcs, - int inten, /* intensity value */ - int for_image -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_shade(pcs, inten); - - if (pptrn == 0) - return ( inten > 0 ? pattern_set_frgrnd(pcs, 0, for_image) - : pattern_set_white(pcs, 0, 0) ); - else { - int code = 0; - - pcl_xfm_pcl_set_pat_ref_pt(pcs); - code = set_frgrnd_pattern(pcs, pptrn, for_image); - - if (for_image && (code >= 0)) - code = set_ht_crd_from_palette(pcs); - return code; - } -} - - private int -pattern_set_shade_gl( - pcl_state_t * pcs, - int inten, /* intensity value */ - int pen /* pen number for foreground */ -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_shade(pcs, inten); - - /* check if the current pen is white; if so, use the "unsolid" pattern */ - if (pcl_cs_indexed_is_white(pcs->ppalet->pindexed, pen)) - pptrn = pcl_pattern_get_unsolid_pattern(pcs); - else if (pptrn == 0) - return ( inten > 0 ? pattern_set_pen(pcs, pen, false) - : pattern_set_white(pcs, 0, 0) ); - - pcl_xfm_gl_set_pat_ref_pt(pcs); - return set_uncolored_palette_pattern(pcs, pptrn, pen); -} - - private int -pattern_set_hatch_pcl( - pcl_state_t * pcs, - int indx, /* cross-hatch pattern index */ - int for_image -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_cross(pcs, indx); - - if (pptrn == 0) - return pattern_set_frgrnd(pcs, 0, for_image); - else { - int code = 0; - - pcl_xfm_pcl_set_pat_ref_pt(pcs); - code = set_frgrnd_pattern(pcs, pptrn, for_image); - if (for_image && (code >= 0)) - code = set_ht_crd_from_palette(pcs); - return code; - } -} - - private int -pattern_set_hatch_gl( - pcl_state_t * pcs, - int indx, /* cross-hatch pattern index */ - int pen /* pen number for foreground */ -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_cross(pcs, indx); - - /* check if the current pen is white; if so, use the "unsolid" pattern */ - if (pcl_cs_indexed_is_white(pcs->ppalet->pindexed, pen)) - pptrn = pcl_pattern_get_unsolid_pattern(pcs); - else if (pptrn == 0) - return pattern_set_pen(pcs, pen, false); - - pcl_xfm_gl_set_pat_ref_pt(pcs); - return set_uncolored_palette_pattern(pcs, pptrn, pen); -} - - private int -pattern_set_user_pcl( - pcl_state_t * pcs, - int id, /* pattern id. */ - int for_image -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_pcl_uptrn(pcs, id); - - if (pptrn == 0) - return pattern_set_frgrnd(pcs, 0, for_image); - else { - pcl_xfm_pcl_set_pat_ref_pt(pcs); - if (pptrn->ppat_data->type == pcl_pattern_uncolored) { - int code = set_frgrnd_pattern(pcs, pptrn, for_image); - - if (for_image && (code >= 0)) - code = set_ht_crd_from_palette(pcs); - return code; - } else - return set_colored_pattern(pcs, pptrn); - } -} - - private int -pattern_set_user_gl( - pcl_state_t * pcs, - int id, /* pattern id. */ - int pen /* pen to use for foreground */ -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_pcl_uptrn(pcs, id); - - if (pptrn == 0) - return pattern_set_pen(pcs, 0, false); - else { - - pcl_xfm_gl_set_pat_ref_pt(pcs); - if (pptrn->ppat_data->type == pcl_pattern_uncolored) { - - /* check if the current pen is white */ - if (pcl_cs_indexed_is_white(pcs->ppalet->pindexed, pen)) - pptrn = pcl_pattern_get_unsolid_pattern(pcs); - return set_uncolored_palette_pattern(pcs, pptrn, pen); - - } else - return set_colored_pattern(pcs, pptrn); - } -} - - private int -pattern_set_gl_RF( - pcl_state_t * pcs, - int indx, /* GL/2 RF pattern index */ - int pen /* used only for uncolored patterns */ -) -{ - pcl_pattern_t * pptrn = pcl_pattern_get_gl_uptrn(pcs, indx); - - /* - * HACK - if pen 1 is to be use for actual uncolored RF patterns, the pen - * operand will be the opposite of the current pen number. This allows us - * to use the current pen if the pattern does not exist. - */ - if (pptrn == 0) - return pattern_set_pen(pcs, (pen < 0 ? -pen : pen), false); - else { - if (pen < 0) - pen = 1; - - pcl_xfm_gl_set_pat_ref_pt(pcs); - if (pptrn->ppat_data->type == pcl_pattern_uncolored) { - - /* check if the current pen is white */ - if (pcl_cs_indexed_is_white(pcs->ppalet->pindexed, pen)) - pptrn = pcl_pattern_get_unsolid_pattern(pcs); - return set_uncolored_palette_pattern(pcs, pptrn, pen); - - } else - return set_colored_pattern(pcs, pptrn); - } -} - - -/* - * Return the appropriate "set" procedure, given a PCL pattern type. - */ - pcl_pattern_set_proc_t -pcl_pattern_get_proc_PCL( - pcl_pattern_source_t pattern_source -) -{ - static const pcl_pattern_set_proc_t procs[] = { pattern_set_frgrnd, - pattern_set_white, - pattern_set_shade_pcl, - pattern_set_hatch_pcl, - pattern_set_user_pcl, - 0, - pattern_set_pen }; - - return procs[(int)pattern_source]; -} - -/* - * Returen the appropriate "set" procedure, given a GL fill type specification. - */ - pcl_pattern_set_proc_t -pcl_pattern_get_proc_FT( - hpgl_FT_pattern_source_t pattern_source -) -{ - if ( (pattern_source == hpgl_FT_pattern_solid_pen1) || - (pattern_source == hpgl_FT_pattern_solid_pen2) ) - return pattern_set_pen; - else if (pattern_source == hpgl_FT_pattern_shading) - return pattern_set_shade_gl; - else if (pattern_source == hpgl_FT_pattern_RF) - return pattern_set_gl_RF; - else if (pattern_source == hpgl_FT_pattern_cross_hatch) - return pattern_set_hatch_gl; - else if (pattern_source == hpgl_FT_pattern_user_defined) - return pattern_set_user_gl; - else - return 0; -} - -/* - * Returen the appropriate "set" procedure, given a GL screened vector - * specification. - */ - pcl_pattern_set_proc_t -pcl_pattern_get_proc_SV( - hpgl_SV_pattern_source_t pattern_source -) -{ - if (pattern_source == hpgl_SV_pattern_solid_pen) - return pattern_set_pen; - else if (pattern_source == hpgl_SV_pattern_shade) - return pattern_set_shade_gl; - else if (pattern_source == hpgl_SV_pattern_RF) - return pattern_set_gl_RF; - else if (pattern_source == hpgl_SV_pattern_cross_hatch) - return pattern_set_hatch_gl; - else if (pattern_source == hpgl_SV_pattern_user_defined) - return pattern_set_user_gl; - else - return 0; -} - - -/* - * ESC * c <#/id> G - * - * Set the pattern id. - */ - private int -set_pattern_id( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->pattern_id = int_arg(pargs); - return 0; -} - -/* - * ESC * v <bool> N - * - * Set source transparency mode - */ - private int -set_source_transparency_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if (i <= 1) { - pcl_break_underline(pcs); - pcs->source_transparent = (i == 0); - } - return 0; -} - -/* - * ESC * v <bool> O - * - * Set pattern transparency mode. - */ - private int -set_pattern_transparency_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if (i <= 1) { - pcl_break_underline(pcs); - pcs->pcl_pattern_transparent = (i == 0); - } - return 0; -} - -/* - * ESC * v # T - * - * Set current pattern id. - */ - private int -select_current_pattern( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if (i <= (int)pcl_pattern_user_defined) { - pcl_break_underline(pcs); - pcs->current_pattern_id = pcs->pattern_id; - pcs->pattern_type = (pcl_pattern_source_t)i; - } - return 0; -} - -/* - * ESC * o # W - * - * Driver configuration command. A partial implementation to show - * that we are parsing the command correctly. The lightness and - * saturation parameters are not documented so we do not believe this - * command will be used by an application or driver. - * - */ - -typedef struct driver_configuration_s { - byte device_id; - byte function_index; - char arguments; -} driver_configuration_t; - - private int -set_driver_configuration( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs /* ignored */ -) -{ - uint count = uint_arg(pargs); - driver_configuration_t *driver = (driver_configuration_t *)arg_data(pargs); - - if ( count != sizeof(driver_configuration_t) ) - return e_Range; - - /* the only device known to support this command */ -#define COLOR_HP_LASERJET_PRINTERS 6 - if ( driver->device_id != COLOR_HP_LASERJET_PRINTERS ) - return e_Range; -#undef COLOR_HP_LASERJET_PRINTERS - - /* return unless the function index indicates lightness or - saturation. */ - switch (driver->function_index) { - case 0: /* lightness */ - { - int code; - if ( driver->arguments < -100 || driver->arguments > 100 ) - return e_Range; - /* map -100..100 to gamma setting 0.05..4.05 */ - code = pcl_palette_set_gamma(pcs, ((driver->arguments + 100.0) / 200.0) + 0.05); - if ( code < 0 ) - return code; - } - break; - case 1: /* saturation */ - { - int code; - if ( driver->arguments < -100 || driver->arguments > 100 ) - return e_Range; - /* map -100..100 to gamma setting 0.05..4.05 */ - code = pcl_palette_set_gamma(pcs, ((driver->arguments + 100.0) / 200.0) + 0.05); - if ( code < 0 ) - return code; - } - break; - default: - /* out of range or 3, 4, and 5 is not supported. */ - return e_Range; - } - return 0; -} - - -/* - * Initialization and reset routines. - */ - private int -pattern_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - DEFINE_CLASS('*') - { - 'c', 'G', - PCL_COMMAND( "Pattern ID", - set_pattern_id, - pca_neg_ignore | pca_big_ignore | pca_in_rtl - ) - }, - { - 'v', 'N', - PCL_COMMAND( "Source Transparency Mode", - set_source_transparency_mode, - pca_neg_ignore | pca_big_ignore | pca_in_rtl - ) - }, - { - 'v', 'O', - PCL_COMMAND( "Pattern Transparency Mode", - set_pattern_transparency_mode, - pca_neg_ignore | pca_big_ignore | pca_in_rtl - ) - }, - { - 'v', 'T', - PCL_COMMAND( "Select Current Pattern", - select_current_pattern, - pca_neg_ignore | pca_big_ignore | pca_in_rtl - ) - }, -#ifndef PCL5EMONO - { - 'o', 'W', - PCL_COMMAND( "Driver Configuration Command", - set_driver_configuration, - pca_bytes | pca_in_rtl - ) - }, -#endif - END_CLASS - return 0; - -} - - private void -pattern_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_cold - | pcl_reset_printer - | pcl_reset_overlay ); - - if ((type & mask) != 0) { - if ((type & pcl_reset_initial) != 0) - pcl_pattern_init_bi_patterns(pcs); - pcs->pcl_pattern_transparent = true; - pcs->pattern_transparent = true; - pcs->source_transparent = true; - pcs->pattern_id = 0; - pcs->current_pattern_id = 0; - pcs->pattern_type = pcl_pattern_solid_frgrnd; - } -} - -const pcl_init_t pcl_pattern_init = { pattern_do_registration, pattern_do_reset, 0 }; diff --git a/pcl/pcpatrn.h b/pcl/pcpatrn.h deleted file mode 100644 index 6d5098337..000000000 --- a/pcl/pcpatrn.h +++ /dev/null @@ -1,552 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpatrn.h - PCL/GL client color and pattern code */ - -#ifndef pcpatrn_INCLUDED -#define pcpatrn_INCLUDED - -#include "gx.h" -#include "gsstruct.h" -#include "gsrefct.h" -#include "pcindxed.h" -#include "pccsbase.h" - -/* - * PCL pattern types. - * - * There are two types of patterns used in PCL, colored and uncolored. In - * order to support transparency, both types are implemented as colored - * patterns in the graphics library (which does not support opaque - * uncolored patterns). - * - * The values used are defined by HP. - * - * Note: The implementation of opaque uncolored patterns is not correct, and - * cannot be handled correctly with the current graphics library. The - * difficulty is that the "background" regions of opaque uncolored - * patterns should be rendered in "device" white. Due to the properties - * of the color space and the color lookup tables employed, it is not - * obvious which source color yields device white, or whether such a - * a source color even exists. Hence, there is no colored pattern that - * is known to give the same result as the opaque uncolored pattern. - */ -typedef enum { - pcl_pattern_uncolored = 0, - pcl_pattern_colored = 1 -} pcl_pattern_type_t; - -/* - * The pattern data structure. This includes the pattern data, dimensions, - * type, and implied resolution. - * - * It is not strictly necessary that this structure be reference counted, as - * there is no chance that any unrendered objects will make use of the deleted - * pattern. The use of reference counts makes for a more consistent - * implementation, however, and leaves open the possibility of subsequent - * implementations that may involve delayed rendering. - */ -typedef struct pcl_pattern_data_s { - gs_depth_bitmap pixinfo; /* pixmap information; must be first */ - pcl_data_storage_t storage; /* temporary/permanent/internal flag */ - rc_header rc; - pcl_pattern_type_t type; /* pattern type */ - int xres; /* intended resolution for pattern */ - int yres; -} pcl_pattern_data_t; - -#define private_st_pattern_data_t() /* in pcuptrn.c */ \ - gs_private_st_suffix_add0( st_pattern_data_t, \ - pcl_pattern_data_t, \ - "PCL/GL pattern data", \ - pattern_data_enum_ptrs, \ - pattern_data_reloc_ptrs, \ - st_gs_depth_bitmap \ - ) - -/* - * The usual copy, init, and release macros. - */ -#define pcl_pattern_data_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_pattern_data_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_pattern_data_copy_from");\ - (pto) = (pfrom); \ - } \ - END - -#define pcl_pattern_data_release(ppat_data) \ - rc_decrement(ppat_data, "pcl_pattern_data_release") - - - -/* forward declaration */ -#ifndef pcl_ccolor_DEFINED -#define pcl_ccolor_DEFINED -typedef struct pcl_ccolor_s pcl_ccolor_t; -#endif - -/* - * The pattern structure. This is not reference counted, as the only place it - * is referred to is the pattern dictionary. - * - * The primary purpose for this structure is to handle cahcing of pattern - * instances. There are potentially two rendered instances of a pattern, - * one as a mask (uncolored) pattern and one as a colored pattern. - * - * A "colored" pattern in the PCL sense will never have a mask rendering, but - * an "uncolored" PCL pattern may have both a mask and a colored rendering, - * because mask patterns in the graphic library cannot be opaque, and cannot - * use a halftone or color redering dictionary that differs from that being - * used by a raster. - * - * The various "render key" field values are used to identify the environment - * for which the client colors pointed to by pmask_ccolor and pcol_ccolor - * have been rendered for. Not all fields apply to both client colors: - * - * - * The transp bit indicates if the colored rendering was render with - * transparency set (mask patterns are always rendered with - * transparency set). - * - * The orient field indicates the orientation of the rendering, in - * the range 0 to 3. - * - * The pen field applies only to the colored pattern rendering and is used - * only for patterns that are uncolored in the PCL sense and rendered - * from GL/2. The pen field indicates the palette entry used as the - * foreground for the pattern. For PCL colored patterns or uncolored - * patterns rendered from PCL, this field will be 0. The value 0 is - * also valid for GL/2, but this causes no difficulty as uncolored - * patterns rendered in GL/2 use the current palette, while those - * rendered in PCL use the current foreground. Hence, the cache_id - * (see below) will never be the same for both cases. - * - * cache_id is the identifier of either the foreground or palette used - * to create the colored rendering of the pattern. This is the - * identifier of either a palette or a foreground. Only for opaque - * uncolored (in the PCL sense) patterns rendered from PCL is it - * the id of the foreground; in all other cases it is the id of the - * palette. - * - * The ref_pt field identifies the reference point, in device space, for - * which both renderings of the pattern were created. - */ -typedef struct pcl_pattern_t { - pcl_pattern_data_t * ppat_data; - - /* the mask and colored rendered instances, if any */ - pcl_ccolor_t * pcol_ccolor; - pcl_ccolor_t * pmask_ccolor; - - /* "rendered key" */ - uint transp:1; /* transparency of rendering */ - uint orient:2; /* orientation of rendering */ - uint pen:8; /* 0 for PCL or colored patterns */ - pcl_gsid_t cache_id; /* foreground or palette */ - gs_point ref_pt; /* referenc point (device space) */ -} pcl_pattern_t; - -#define private_st_pattern_t() /* in pcuptrn.c */ \ - gs_private_st_ptrs3( st_pattern_t, \ - pcl_pattern_t, \ - "PCL/GL pattern", \ - pattern_enum_ptrs, \ - pattern_reloc_ptrs, \ - ppat_data, \ - pcol_ccolor, \ - pmask_ccolor \ - ) - - -/* - * The PCL structure corresponding to the graphic library's client color - * structure. The latter potentially contains a client data structure pointer - * (for pattern colors) which it does not (an cannot) take ownership of. To - * release the associated memory at the correct time, it is necessary to build - * a parallel structure which has ownership of the client data, and which - * can be kept in a one-to-one relationship with the graphic library client - * color structure. - * - * The interpretation of the various fields varies by color type: - * - * For pcl_ccolor_unpatterned: - * - * ppat_data == NULL, - * - * one of pindexed or pbase points to the current color space (the other - * is NULL) - * - * ccolor.paint.values[0] or ccolor.paint.values[0..2] holds the - * color component values - * - * ccolor.pattern == NULL - * - * For pcl_ccolor_mask_pattern: - * - * ppat_data points to the pattern data - * - * one of pindexed or pbase points to the base color space of the - * pattern color space (the other is NULL) - * - * ccolor.paint.values[0] or ccolor.paint.values[0..2] holds the - * color values to be use for the pattern foreground - * - * ccolor.pattern points to the pattern instance - * - * For pcl_ccolor_colored_pattern - * - * ppat_data points to the pattern data - * - * pindexed points to the base color space of the pattern - * - * pbase == NULL, - * - * ccolor.paint is ignored - * - * ccolor.pattern points to the pattern instance - * - * Not that exactly one of pbase or pindexed will ever be non-NULL. - * - * The prast data is used only for colored patterns. When these are rendered - * with transparency on, difficulties might arise because there is more than - * one "white" value in the palette of the indexed color space pointed to by - * pindexed. Since the ImageType 4 rendering mechanism used to implement - * transaprent colored patterns cannot accommodate multiple non-contiguous - * while values, the pattern data must be copied and all white values mapped - * to a unique white value. The prast pointer points to this remapped array. - */ - -typedef enum { - pcl_ccolor_unpatterned = 0, - pcl_ccolor_mask_pattern, - pcl_ccolor_colored_pattern -} pcl_ccolor_type_t; - -struct pcl_ccolor_s { - rc_header rc; - pcl_ccolor_type_t type; - pcl_pattern_data_t * ppat_data; - pcl_cs_indexed_t * pindexed; - pcl_cs_base_t * pbase; - const byte * prast; - gs_client_color ccolor; -}; - -#define private_st_ccolor_t() \ - gs_private_st_ptrs4( st_ccolor_t, \ - pcl_ccolor_t, \ - "PCL client color",\ - ccolor_enum_ptrs, \ - ccolor_reloc_ptrs, \ - ppat_data, \ - pindexed, \ - pbase, \ - ccolor.pattern \ - ) - -/* - * The usual copy, init, and release macros. - */ -#define pcl_ccolor_init_from(pto, pfrom) \ - BEGIN \ - rc_increment(pfrom); \ - (pto) = (pfrom); \ - END - -#define pcl_ccolor_copy_from(pto, pfrom) \ - BEGIN \ - if ((pto) != (pfrom)) { \ - rc_increment(pfrom); \ - rc_decrement(pto, "pcl_ccolor_copy_from"); \ - (pto) = (pfrom); \ - } \ - END - -#define pcl_ccolor_release(pccolor) \ - rc_decrement(pccolor, "pcl_ccolor_release") - - -/* - * Create a colored pcl_pattern_t object from a gs_depth_bitmap object. This - * object will be considered "temporary" in the sense of a PCL resource, and - * is stored in the GL/2 pattern dictionary (reserved for patterns created - * via the GL/2 RF command. - * - * This procedure is exported for the convenience of the GL/2 RF command, as - * it avoids having the GL/2 module deal with the pattern structure provided - * above. - * - * Passing a null pointer clears the indicated entry; this can be used by - * GL/2 to facilitate the reset functions of the IN and DF operators (and - * the RF operator without operands). - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_pattern_RF(P3( - int ptrn_indx, /* pattern index */ - const gs_depth_bitmap * ppixmap, /* pixmap */ - pcl_state_t * pcs -)); - -/* - * Procedure to get/set up the current graphic state for the proper "pattern" - * (which may be a solid color). The routine is called with the current PCL - * state and one or two additional operands. The interpretation of the operands - * is dependent on the particular routine used. - * - * These routines are intended to handle the many different combinations of - * color space, color rendering dictionary, and halftone object required in - * the graphic state in different situations. The chart below characterizes - * what the operands are interpreted to mean, and what the source of the - * (graphic state) color space, color, color rendering dictionary, and - * halftone (including transfer function) are for each case. Note in - * particular that uncolored patterns (including the built-in shades and - * cross-hatch patterns) must be handled separately for PCL and GL. - * - * solid white (PCL or GL) - * arg1 ignored - * arg2 ignored - * - * pattern source none - * - * cspace DeviceGray (irrespective of current space) - * color 1,0 (irrespective of current color) - * CRD unchanged (irrelevant since DeviceGray is - * the color space) - * halftone Fixed halftone with null transfer function - * - * note: this routine does NOT override the current transparency - * values. - * - * solid color (GL only) - * arg1 pen number - * arg2 ignored - * - * pattern source none - * - * cspace indexed color space from current palette - * color pen number - * CRD from current palette - * halftone from current palette - * - * note: this routine does NOT set the line width - * - * solid foreground (PCL only) - * arg1 ignored - * arg2 ignored - * - * pattern source none - * - * cspace base color space from current foreground - * color color from current foreground - * CRD from current foreground - * halftone from current foreground - * - * shade pattern (PCL only) - * arg1 shade percentage - * arg2 ignored - * - * pattern source built-in shade patterns - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current foreground and a 2-entry palette. The - * palette contains the canonical white color and - * the foreground color. The color rendering - * dictionary and halftone also are taken from - * the current color. - * CRD from current foreground (only relevant for - * pattern rendering) - * halftone from current foreground (only relevant for - * pattern rendering). - * - * shade pattern (GL only) - * arg1 shade percentage - * arg2 current pen - * - * pattern source built-in shade patterns - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current palette and a 2-entry palette. The - * palette contains the canonical white color and - * the color corresponding to the given pen. The - * color rendering dictionary and halftone are - * taken from the given palette. - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for - * pattern rendering). - * - * cross-hatch pattern (PCL only) - * arg1 pattern index - * arg2 ignored - * - * pattern-source built-in cross-hatch patterns - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current foreground and a 2-entry palette. The - * palette contains the canonical white color and - * the foreground color. The color rendering - * dictionary and halftone also are taken from the - * current color. - * CRD from current foreground (only relevant for - * pattern rendering) - * halftone from current foreground (only relevant for - * pattern rendering). - * - * cross-hatch pattern (GL only) - * arg1 pattern index - * arg2 current pen - * - * pattern source built-in cross-hatch patterns - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current palette und and a 2-entry palette. The - * palette contains the canonical white color and - * the color corresponding to the given pen. The - * color rendering dictionary and halftone are - * taken from the given palette. - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for - * pattern rendering). - * - * PCL user-defined pattern (PCL only) - * arg1 pattern id - * arg2 ignored - * - * pattern source PCL user defined patterns - * - * Handling depends on the pattern type. For uncolored patterns, the - * settings are: - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current foreground and a 2-entry palette. The - * palette contains the canonical white color and - * the foreground color. The color rendering - * dictionary and halftone also are taken from the - * current color. - * CRD from current foreground (only relevant for - * pattern rendering) - * halftone from current foreground (only relevant for - * pattern rendering). - * - * For colored patterns, the settings are: - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and the indexed color space in the - * current palette, along with the halftone and - * color rendering dictionary in the current palette - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for color - * generation) - * - * PCL user-defined pattern (GL only) - * arg1 pattern id - * arg2 current pen - * - * pattern source PCL user defined patterns - * - * Handling depends on the pattern type. For uncolored patterns, the - * settings are: - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and a special indexed color space - * which utilizes the base color space in the - * current palette and a 2-entry palette. The - * palette contains the canonical white color and - * the color corresponding to the given pen. The - * color rendering dictionary and halftone are - * taken from the given palette. - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for - * pattern rendering). - * - * For colored patterns, the settings are: - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and the indexed color space in the - * current palette, along with the halftone and - * color rendering dictionary in the current palette - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for color - * generation) - * - * RF pattern (GL only) - * arg1 pattern index - * arg2 ignored - * - * pattern source GL user defined patterns - * - * cspace Pattern color space without base color space - * color Colored pattern generated from the pixmap data - * provided and the indexed color space in the - * current palette, along with the halftone and - * color rendering dictionary in the current palette - * CRD from current palette (only relevant for - * pattern rendering) - * halftone from current palette (only relevant for color - * generation) - * - * These routines will also set the pattern reference point appropriatel for - * either PCL or GL. - * - * The routines return 0 on success (with the graphic state properly set up), - * < 0 in the event of an error. - */ - -typedef int (*pcl_pattern_set_proc_t)( pcl_state_t *, int arg1, int arg2 ); - -/* - * Return the pattern set procedure appropriate for the specified pattern - * source specification (the command that selected the pattern). - * - * A return of NULL indicates a range check error. - */ -pcl_pattern_set_proc_t pcl_pattern_get_proc_PCL(P1( - pcl_pattern_source_t pattern_source -)); - -pcl_pattern_set_proc_t pcl_pattern_get_proc_FT(P1( - hpgl_FT_pattern_source_t pattern_source -)); - -pcl_pattern_set_proc_t pcl_pattern_get_proc_SV(P1( - hpgl_SV_pattern_source_t pattern_source -)); - -/* - * Entry point to pattern-related functions. - */ -extern const pcl_init_t pcl_pattern_init; - -#endif /* pcpatrn_INCLUDED */ diff --git a/pcl/pcpattyp.h b/pcl/pcpattyp.h deleted file mode 100644 index a79eff88f..000000000 --- a/pcl/pcpattyp.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpattyp.h - pattern type enumerations and related information */ - -#ifndef pcpattyp_INCLUDED -#define pcpattyp_INCLUDED - -/* - * Pattern source identifiers. There are three of these, one for PCL and two - * for GL (one for FT, the other for SV). Though GL types are not usually - * defined in PCL files, they are in this case so that the pattern code - * can be kept together. - */ -typedef enum { - pcl_pattern_solid_frgrnd = 0, /* solid foreground / current pen */ - pcl_pattern_solid_white, - pcl_pattern_shading, - pcl_pattern_cross_hatch, - pcl_pattern_user_defined, - pcl_pattern_current_pattern, /* for rectangle fill only */ - pcl_pattern_raster_cspace /* internal - used for rasters only */ -} pcl_pattern_source_t; - -typedef enum { - hpgl_FT_pattern_solid_pen1 = 1, - hpgl_FT_pattern_solid_pen2 = 2, - hpgl_FT_pattern_one_line = 3, - hpgl_FT_pattern_two_lines = 4, - hpgl_FT_pattern_shading = 10, - hpgl_FT_pattern_RF = 11, - hpgl_FT_pattern_cross_hatch = 21, - hpgl_FT_pattern_user_defined = 22 -} hpgl_FT_pattern_source_t; - -typedef enum { - hpgl_SV_pattern_solid_pen = 0, - hpgl_SV_pattern_shade = 1, - hpgl_SV_pattern_RF = 2, - hpgl_SV_pattern_cross_hatch = 21, - hpgl_SV_pattern_user_defined = 22 -} hpgl_SV_pattern_source_t; - - -/* - * Opaque definitions of palettes, foregrounds, client colors, halftones, - * and backgrounds. - */ -#ifndef pcl_palette_DEFINED -#define pcl_palette_DEFINED -typedef struct pcl_palette_s pcl_palette_t; -#endif - -#ifndef pcl_frgrnd_DEFINED -#define pcl_frgrnd_DEFINED -typedef struct pcl_frgrnd_s pcl_frgrnd_t; -#endif - -#ifndef pcl_ccolor_DEFINED -#define pcl_ccolor_DEFINED -typedef struct pcl_ccolor_s pcl_ccolor_t; -#endif - -#ifndef pcl_ht_DEFINED -#define pcl_ht_DEFINED -typedef struct pcl_ht_s pcl_ht_t; -#endif - -#ifndef pcl_crd_DEFINED -#define pcl_crd_DEFINED -typedef struct pcl_crd_s pcl_crd_t; -#endif - -/* - * Structure to track what has been installed in the graphic state. This is - * used to avoid unnecessary re-installation, and to avoid memory handling - * problems that would arise if various objects were released while the - * graphic state still retained pointes to them. - * - * The PCL client color structure (pcl_ccolor_t) incorporates both color and - * color space information. - */ -typedef struct pcl_gstate_ids_s { - struct pcl_gstate_ids_s * prev; /* stack back pointer */ - pcl_ccolor_t * pccolor; - pcl_ht_t * pht; - pcl_crd_t * pcrd; -} pcl_gstate_ids_t; - -#define private_st_gstate_ids_t() /* in pcdraw.c */ \ - gs_private_st_ptrs4( st_gstate_ids_t, \ - pcl_gstate_ids_t, \ - "PCL graphics state tracker", \ - gstate_ids_enum_ptrs, \ - gstate_ids_reloc_ptrs, \ - prev, \ - pccolor, \ - pht, \ - pcrd \ - ) - -#endif /* pcpattyp_INCLUDED */ diff --git a/pcl/pcpatxfm.c b/pcl/pcpatxfm.c deleted file mode 100644 index ae6eaa5cc..000000000 --- a/pcl/pcpatxfm.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpatxfm.c - code to set the pattern transformation */ - -#include "gx.h" -#include "math_.h" -#include "pcpatrn.h" -#include "pcfont.h" -#include "pcpatxfm.h" - - -/* - * The four rotation matrices used by PCL. Note that rotations in PCL are - * always multiples of 90 degrees, and map the positive x-axis to the negative - * y-axis (the opposite or the rotation sense used by PostScript). - * - * All of the matrices are pure rotations; they have no scaling or translation - * components. - */ -private const gs_matrix rot_mtx[4] = { - { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* 0 degrees */ - { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 }, /* 90 degrees */ - { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, /* 180 degrees */ - { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 } /* 270 degrees */ -}; - - -/* - * Inverst a diagonal 2-dimensional affine transformation. This is much simpler - * than inverting a general 2-dimensional affine transformation, hence a - * separate routine is provided for this purpose. - * - * Note that both operands may point to the same matrix. - * - * NB: This routine ASSUMES that *pmtx1 is non singular. This is always the - * case for PCL, but obviously may not be in a more general setting. - */ - void -pcl_invert_mtx( - const gs_matrix * pmtx1, - gs_matrix * pmtx2 -) -{ - float xx = pmtx1->xx; - float tx = pmtx1->tx; - float ty = pmtx1->ty; - - if (xx == 0.0) { - float xy = pmtx1->xy; - float yx = pmtx1->yx; - - pmtx2->xx = 0.0; - pmtx2->xy = 1.0 / yx; - pmtx2->yx = 1.0 / xy; - pmtx2->yy = 0.0; - pmtx2->tx = -ty / xy; - pmtx2->ty = -tx / yx; - - } else { - float yy = pmtx1->yy; - - pmtx2->xx = 1.0 / xx; - pmtx2->xy = 0.0; - pmtx2->yx = 0.0; - pmtx2->yy = 1.0 / yy; - pmtx2->tx = -tx / xx; - pmtx2->ty = -ty / yy; - } -} - -/* - * Transform an aligned rectangle. Because all transformations in PCL are - * diagonal, both the source and destination rectangles are aligned with the - * coordinate axes, and hence may be represented by a pair of points. - * - * prect1 and prect2 may point to the same rectangle. - */ - void -pcl_transform_rect( - const gs_rect * prect1, - gs_rect * prect2, - const gs_matrix * pmtx -) -{ - gs_point_transform(prect1->p.x, prect1->p.y, pmtx, &(prect2->p)); - gs_point_transform(prect1->q.x, prect1->q.y, pmtx, &(prect2->q)); - if (prect2->p.x > prect2->q.x) { - double ftmp = prect2->p.x; - - prect2->p.x = prect2->q.x; - prect2->q.x = ftmp; - } - if (prect2->p.y > prect2->q.y) { - double ftmp = prect2->p.y; - - prect2->p.y = prect2->q.y; - prect2->q.y = ftmp; - } -} - -/* - * Create the transformation matrix corresponding to a PCL rotation. - * - * The rotation operand is an integer in the range 0..3; the desired angle of - * rotation is 90 * rot. - * - * PCL rotations are not pure rotations, and thus cannot be uniquely identified - * by an angle. A PCL coordinate system is always associated with a rectangular - * (and aligned) subset of the page, which lies in the possitive quadrant of - * the coordinate system. The origin of the coordinate system is always one - * corner of this rectangular region. A rotation in PCL both alters the - * orientation of the coordinate system and moves its origin to another corner, - * so as to keep the rectangluar subregion in the positive quadrant. - * - * To implement such a transformation, it is necessary to know both the - * desired change of orientation, and the dimensions of the rectangular - * region (in the original coordinate system). - */ - void -pcl_make_rotation( - int rot, - floatp width, - floatp height, - gs_matrix * pmtx -) -{ - *pmtx = rot_mtx[rot & 0x3]; - if (pmtx->xx + pmtx->yx < 0.0) - pmtx->tx = width; - if (pmtx->xy + pmtx->yy < 0.0) - pmtx->ty = height; -} - -/* - * Pattern reference point manipulation. - * - * Logically, the pattern reference point transforms in the same manner as the - * logical page: it is reset by changing the logical page orientation (not - * documented, but verified empirically), it moves with the left and top offset - * commands, but it does not change with changes in print direction. - * - * Ergo, the logical space in which to maintain the pattern reference point - * is the logical page transformation. This is also the logical space in which - * to keep the current addressable (cursor) position, but the PCL code is - * illogical in this regard (see the code for pcl_set_print_direction in - * pcdraw.c if you are not convinced of this); the current addressable - * position is instead maintained in a curious "semi-print-direction" space, - * which incorporates the orientation but not the translation component of - * the "print direction" coordinate space. - * - * Hence, this code must convert the current addressable position back into - * logical page space before making use of it. In other portions of this code - * such a change is by using the current transformation directly the graphic - * state. This is a bit unfortunate, as transformation must be set twice, - * which can play havoc with transformation-sensitive caches. - * - * The current code instead instead directly access the matrix machinery, - * using the graphic state only to gather the default transformation (which - * maps the physical page to the device, with centipoints as the source unit). - * - * When setting up the transformation matrix to be used by a pattern, the code - * constructs the resulting matrix in three steps: - * - * Get the default transformation matrix and modify it to transform - * logical page space to device space. This involves incorporating - * the left and top offsets and the logical page orientation. - * - * Translate the resulting matrix by the pattern reference point. - * - * If the pattern is to be rotated by the print direction, apply the - * print direction rotation - */ - -/* - * Convert a floating point number that is nearly an integer to an integer. - */ - private floatp -adjust_param( - floatp val -) -{ - floatp fval = floor(val); - floatp cval = ceil(val); - - return (val - fval < .001 ? fval : (cval - val < .001 ? cval : val)); -} - -/* - * Form the transformation matrix required to render a pattern. - */ - void -pcl_xfm_get_pat_xfm( - const pcl_state_t * pcs, - pcl_pattern_t * pptrn, - gs_matrix * pmat -) -{ - const pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - int rot = (pcs->pat_orient - pxfmst->lp_orient) & 0x3; - - *pmat = pxfmst->lp2dev_mtx; - pmat->tx = pcs->pat_ref_pt.x; - pmat->ty = pcs->pat_ref_pt.y; - - /* record the referenc point used in the rendering structure */ - pptrn->ref_pt = pcs->pat_ref_pt; - - /* rotate as necessar */ - if (rot != 0) - gs_matrix_multiply(&(rot_mtx[rot]), pmat, pmat); - - /* scale to the appropriate resolution (before print direction rotation) */ - gs_matrix_scale( pmat, - inch2coord(1.0 / (floatp)pptrn->ppat_data->xres), - inch2coord(1.0 / (floatp)pptrn->ppat_data->yres), - pmat - ); - - /* avoid parameters that are slightly different from integers */ - pmat->xx = adjust_param(pmat->xx); - pmat->xy = adjust_param(pmat->xy); - pmat->yx = adjust_param(pmat->yx); - pmat->yy = adjust_param(pmat->yy); - - /* record the rotation used for rendering */ - pptrn->orient = pcs->pat_orient; -} - -/* - * Reset the pattern reference point. This should be done each time the logical - * page parameters change. (This would be better done via a reset, but - * unfortunately there was no reset created for this category of even.) - */ - void -pcl_xfm_reset_pcl_pat_ref_pt( - pcl_state_t * pcs -) -{ - pcs->pcl_pat_ref_pt.x = 0.0; - pcs->pcl_pat_ref_pt.y = 0.0; - pcs->rotate_patterns = true; -} - -/* - * Set up the pattern orientation and reference point for PCL. Note that PCL's - * pattern reference point is kept in logical page space. - */ - void -pcl_xfm_pcl_set_pat_ref_pt( - pcl_state_t * pcs -) -{ - pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - - gs_point_transform( pcs->pcl_pat_ref_pt.x, - pcs->pcl_pat_ref_pt.y, - &(pxfmst->lp2dev_mtx), - &(pcs->pat_ref_pt) - ); - pcs->pat_ref_pt.x = floor(pcs->pat_ref_pt.x + 0.5); - pcs->pat_ref_pt.y = floor(pcs->pat_ref_pt.y + 0.5); - pcs->pat_orient = (pxfmst->lp_orient - + (pcs->rotate_patterns ? pxfmst->print_dir : 0)) & 0x3; -} - -/* - * Set up the pattern orientatin and reference point for GL. The anchor point - * is taken as being in the current GL space, and the current transform is - * assumed properly set. The orientation is that of the logical page. - */ - void -pcl_xfm_gl_set_pat_ref_pt( - pcl_state_t * pcs -) -{ - gs_transform( pcs->pgs, - pcs->g.anchor_corner.x, - pcs->g.anchor_corner.y, - &(pcs->pat_ref_pt) - ); - pcs->pat_ref_pt.x = floor(pcs->pat_ref_pt.x + 0.5); - pcs->pat_ref_pt.y = floor(pcs->pat_ref_pt.y + 0.5); - pcs->pat_orient = (pcs->xfm_state.lp_orient + (pcs->g.rotation / 90)) & 0x3; -} - - -/* - * ESC * p # R - * - * Set pattern reference point. - * - */ - private int -set_pat_ref_pt( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint rotate = uint_arg(pargs); - - if (rotate <= 1) { - pcl_break_underline(pcs); - gs_point_transform( (floatp)pcs->cap.x, - (floatp)pcs->cap.y, - &(pcs->xfm_state.pd2lp_mtx), - &(pcs->pcl_pat_ref_pt) - ); - pcs->rotate_patterns = (rotate == 0); - } - return 0; -} - - -/* - * Initializaton and reset routines. There is currently no copy routine, as the - * desired transformation is reset for each object printed. No special reset - * routine is required, as a reset of the logical page will reset the pattern - * reference point as well. - */ - private int -xfm_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - DEFINE_CLASS('*') - { - 'p', 'R', - PCL_COMMAND( "Pattern Reference Point", - set_pat_ref_pt, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS - return 0; -} - -const pcl_init_t pcl_xfm_init = { xfm_do_registration, 0, 0 }; diff --git a/pcl/pcpatxfm.h b/pcl/pcpatxfm.h deleted file mode 100644 index d471104ab..000000000 --- a/pcl/pcpatxfm.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcpatxfm.h - interface for the pattern and general PCL transformation code */ - -#ifndef pcpatxfm_INCLUDED -#define pcpatxfm_INCLUDED - -#include "gx.h" -#include "gsmatrix.h" -#include "gscoord.h" -#include "pcstate.h" -#include "pcommand.h" -#include "pcpatrn.h" - - -/* invert a diagonal matrix (assumed to be non-signular) */ -void pcl_invert_mtx(P2(const gs_matrix * pmtx1, gs_matrix * pmtx2)); - -/* transform a rectangel via a diagonal matrix */ -void pcl_transform_rect(P3( - const gs_rect * prect1, - gs_rect * prect2, - const gs_matrix * pmtx -)); - -/* - * create a 90 degree rotation matrix (counter clockwise rotation) that includes - * the transformation required to keep the indicated rectangle in the positive - * quadrant (with the origin at one corner of the rectangle). - */ -void pcl_make_rotation(P4( - int rot, - floatp width, - floatp height, - gs_matrix * pmtx -)); - -/* - * Form the transformation matrix required to render a pattern. - * - * Note that, though the rotation implicit in the print direction may apply - * to a pattern transformation, the translation never does. - */ -void pcl_xfm_get_pat_xfm(P3( - const pcl_state_t * pcs, - pcl_pattern_t * pptrn, - gs_matrix * pmat -)); - -/* - * Reset the PCL pattern reference point. This should be done each time the - * logical page parameters change. (This would be better done via a reset, but - * unfortunately there was no reset created for this category of event.) - */ -void pcl_xfm_reset_pcl_pat_ref_pt(P1(pcl_state_t * pcs)); - -/* - * Set up the pattern orientation and reference point for PCL. Note that PCL's - * pattern reference point is kept in logical page space. - */ -void pcl_xfm_pcl_set_pat_ref_pt(P1(pcl_state_t * pcs)); - -/* - * Set up the pattern orientatin and reference point for GL. The anchor point - * is taken as being in the current GL space, and the current transform is - * assumed properly set. The orientation is that of the logical page. - */ -void pcl_xfm_gl_set_pat_ref_pt(P1(pcl_state_t * pcs)); - -extern const pcl_init_t pcl_xfm_init; - -#endif /* pcpatxfm_INCLUDED */ diff --git a/pcl/pcrect.c b/pcl/pcrect.c deleted file mode 100644 index 7a0b29d19..000000000 --- a/pcl/pcrect.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcrect.c - PCL5 rectangular area fill commands */ -#include "math_.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcdraw.h" -#include "pcpatrn.h" -#include "pcbiptrn.h" -#include "pcuptrn.h" -#include "gspath.h" -#include "gspath2.h" -#include "gsmatrix.h" -#include "gscoord.h" -#include "gspaint.h" -#include "gsrop.h" - - - -/* - * The graphic library is, unfortunately, not equipped to produce accurate - * PCL rectangles on its own. These rectangles must always be rendered with - * the same pixel dimensions, regardless of location (ignoring clipping), - * in the "grid intersection" pixel placement mode, must always add one - * additional pixel in the "right" and "down" directions, relative to print - * direction 0. - * - * To accomplish these tasks, it is necessary to properly adjust the rectangle - * dimensions provided to the graphic layer. That task is accomplished by - * this routine. - * - * Note that this code is designed to work with no fill adjustment in the - * graphic library. - */ - private int -adjust_render_rectangle( - pcl_state_t * pcs -) -{ - gs_state * pgs = pcs->pgs; - const pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - coord w = pcs->rectangle.x; - coord h = pcs->rectangle.y; - gs_point dims; - gs_rect rect; - gs_matrix save_mtx, ident_mtx; - int code = 0; - - /* adjust the width and height to reflect the logical page boundaries */ - if (pcs->cap.x + w > pxfmst->pd_size.x) - w = pxfmst->pd_size.x - pcs->cap.x; - if (pcs->cap.y + h > pxfmst->pd_size.y) - h = pxfmst->pd_size.y - pcs->cap.y; - - /* move the current point to an integral pixel location */ - gs_transform(pgs, (floatp)pcs->cap.x, (floatp)pcs->cap.y, &(rect.p)); - rect.p.x = floor(rect.p.x + 0.5); - rect.p.y = floor(rect.p.y + 0.5); - - /* set the dimensions to be a multiple of pixels */ - gs_dtransform(pgs, (floatp)w, (floatp)h, &dims); - if (dims.x >= 0) - rect.q.x = rect.p.x + ceil(dims.x); - else { - rect.q.x = rect.p.x; - rect.p.x += floor(dims.x); - } - if (dims.y >= 0) - rect.q.y = rect.p.y + ceil(dims.y); - else { - rect.q.y = rect.p.y; - rect.p.y += floor(dims.y); - } - - /* - * If the pixel-placement mode is 1, decrease the size of the rectangle - * by one pixel. Note that this occurs only if the rectangle dimension is - * not 0; rectangles with a zero dimension are never rendered, irrespective - * of pixle placement mode. - * - * This trickiest part of this increase in dimension concerns correction - * for the device orientation relative to print direction 0. The output - * produced needs to be the same for pages produced with either long-edge - * -feed or short-edge-feed printers, so it is not possible to add one - * pixel in each direction in device space. - */ - if ((pcs->pp_mode == 1) && (dims.x != 0.0) && (dims.y != 0.0)) { - gs_matrix dflt_mtx; - gs_point disp; - - gs_defaultmatrix(pgs, &dflt_mtx); - gs_distance_transform(1.0, 1.0, &dflt_mtx, &disp); - if (disp.x < 0.0) - rect.p.x += 1.0; - else - rect.q.x -= 1.0; - if (disp.y < 0.0) - rect.p.y += 1.0; - else - rect.q.y -= 1.0; - } - - /* rectangles with 0-dimensions are never printed */ - if ((rect.p.x == rect.q.x) || (rect.p.y == rect.q.y)) - return 0; - - /* transform back into pseudo-print-direction space */ - gs_currentmatrix(pgs, &save_mtx); - gs_make_identity(&ident_mtx); - gs_setmatrix(pgs, &ident_mtx); - code = gs_rectfill(pgs, &rect, 1); - gs_setmatrix(pgs, &save_mtx); - return code; -} - -/* - * ESC * c <dp> H - */ - private int -pcl_horiz_rect_size_decipoints( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->rectangle.x = float_arg(pargs) * 10; - return 0; -} - -/* - * ESC * c <units> A - */ - private int -pcl_horiz_rect_size_units( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->rectangle.x = int_arg(pargs) * pcs->uom_cp; - return 0; -} - -/* - * ESC * c <dp> V - */ - private int -pcl_vert_rect_size_decipoints( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->rectangle.y = float_arg(pargs) * 10; - return 0; -} - -/* - * ESC * c B - */ - private int -pcl_vert_rect_size_units( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->rectangle.y = int_arg(pargs) * pcs->uom_cp; - return 0; -} - -/* - * ESC * c <fill_enum> P - */ - private int -pcl_fill_rect_area( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcl_pattern_source_t type = (pcl_pattern_source_t)int_arg(pargs); - int id = pcs->pattern_id; - int code = 0; - - /* - * Rectangles have a special property with respect to patterns: - * - * a non-zero, non-existent pattern specification causes the command - * to be ignored, UNLESS this is the current pattern. This only - * applies to cross-hatch and user-defined patterns, as the - * pattern id. is interpreted as an intensity level for shade - * patterns, and patterns >= 100% are considered white. - */ - if (type == pcl_pattern_cross_hatch) { - if (pcl_pattern_get_cross(pcs, id) == 0) - return 0; - } else if (type == pcl_pattern_user_defined) { - if (pcl_pattern_get_pcl_uptrn(pcs, id) == 0) - return 0; - } else if (type == pcl_pattern_current_pattern) { - type = pcs->pattern_type; - id = pcs->current_pattern_id; - } else if (type > pcl_pattern_shading) - return 0; - - /* set up the graphic state; render the rectangle */ - if ( ((code = pcl_set_drawing_color(pcs, type, id, false)) >= 0) && - ((code = pcl_set_graphics_state(pcs)) >= 0) ) - code = adjust_render_rectangle(pcs); - return code; -} - -/* - * Initialization - */ - private int -pcrect_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * mem -) -{ - /* Register commands */ - DEFINE_CLASS('*') - { - 'c', 'H', - PCL_COMMAND( "Horizontal Rectangle Size Decipoints", - pcl_horiz_rect_size_decipoints, - pca_neg_error | pca_big_error | pca_in_rtl - ) - }, - { - 'c', 'A', - PCL_COMMAND( "Horizontal Rectangle Size Units", - pcl_horiz_rect_size_units, - pca_neg_error | pca_big_error | pca_in_rtl - ) - }, - { - 'c', 'V', - PCL_COMMAND( "Vertical Rectangle Size Decipoint", - pcl_vert_rect_size_decipoints, - pca_neg_error | pca_big_error | pca_in_rtl - ) - }, - { - 'c', 'B', - PCL_COMMAND( "Vertical Rectangle Size Units", - pcl_vert_rect_size_units, - pca_neg_error | pca_big_error | pca_in_rtl - ) - }, - { - 'c', 'P', - PCL_COMMAND( "Fill Rectangular Area", - pcl_fill_rect_area, - pca_neg_ignore | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS - return 0; -} - - private void -pcrect_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_printer - | pcl_reset_overlay ); - if ((type & mask) != 0) { - pcs->rectangle.x = 0; - pcs->rectangle.y = 0; - } -} - -const pcl_init_t pcrect_init = { pcrect_do_registration, pcrect_do_reset, 0 }; diff --git a/pcl/pcsfont.c b/pcl/pcsfont.c deleted file mode 100644 index 79ec501a9..000000000 --- a/pcl/pcsfont.c +++ /dev/null @@ -1,746 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcsfont.c */ -/* PCL5 soft font creation commands */ -#include "memory_.h" -#include "stdio_.h" /* needed for pl_load_tt_font */ -#include "math_.h" -#include "gdebug.h" -#include "pcommand.h" -#include "pcfont.h" -#include "pcstate.h" -#include "pcfsel.h" -#include "pldict.h" -#include "plvalue.h" -#include "gsbitops.h" -#include "gsccode.h" -#include "gsmatrix.h" -#include "gsutil.h" -#include "gxfont.h" -#include "gxfont42.h" - -/* Define the downloaded character data formats. */ -typedef enum { - pccd_bitmap = 4, - pccd_intellifont = 10, - pccd_truetype = 15 -} pcl_character_format; - -/* ------ Internal procedures ------ */ - -/* Delete a soft font. If it is the currently selected font, or the */ -/* current primary or secondary font, cause a new one to be chosen. */ -private void -pcl_delete_soft_font(pcl_state_t *pcs, const byte *key, uint ksize, - void *value) -{ - if ( value == NULL ) { - if ( !pl_dict_find(&pcs->soft_fonts, key, ksize, &value) ) - return; /* not a defined font */ - } - { - pl_font_t *plfontp = (pl_font_t *)value; - if ( pcs->font_selection[0].font == plfontp ) - pcs->font_selection[0].font = 0; - if ( pcs->font_selection[1].font == plfontp ) - pcs->font_selection[1].font = 0; - /* if this is permanent font we need to tell PJL we are - removing it */ - if ( plfontp->storage & pcds_permanent ) - if ( pjl_proc_register_permanent_soft_font_deletion(pcs->pjls, - plfontp->params.pjl_font_number) > 0 ) - pcl_set_current_font_environment(pcs); - pcs->font = pcs->font_selection[pcs->font_selected].font; - pl_dict_undef_purge_synonyms(&pcs->soft_fonts, key, ksize); - } -} - -/* ------ Commands ------ */ - -private int /* ESC * c <id> D */ -pcl_assign_font_id(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint id = uint_arg(pargs); - id_set_value(pcs->font_id, id); - /* set state to use id's not strings */ - pcs->font_id_type = numeric_id; - return 0; -} - -private int /* ESC * c <fc_enum> F */ -pcl_font_control(pcl_args_t *pargs, pcl_state_t *pcs) -{ - gs_const_string key; - void *value; - pl_dict_enum_t denum; - - switch ( uint_arg(pargs) ) { - case 0: - /* Delete all soft fonts. */ - pcs->font = pcs->font_selection[pcs->font_selected].font; - pl_dict_enum_stack_begin(&pcs->soft_fonts, &denum, false); - while ( pl_dict_enum_next(&denum, &key, &value) ) { - pcl_delete_soft_font(pcs, key.data, key.size, value); - /* when deleting fonts we must restart the enumeration - each time because the last deleted font may have had - deleted synonyms which are not properly registered in - the enumeration structure. NB A similar change should - be made for deleting all temporary fonts. */ - pl_dict_enum_stack_begin(&pcs->soft_fonts, &denum, false); - } - pl_dict_release(&pcs->soft_fonts); - break; - case 1: - /* Delete all temporary soft fonts. */ - pl_dict_enum_stack_begin(&pcs->soft_fonts, &denum, false); - while ( pl_dict_enum_next(&denum, &key, &value) ) - if ( ((pl_font_t *)value)->storage == pcds_temporary ) - pcl_delete_soft_font(pcs, key.data, key.size, value); - break; - case 2: - /* Delete soft font <font_id>. */ - pcl_delete_soft_font(pcs, current_font_id, current_font_id_size, NULL); - /* decache the currently selected font in case we deleted it. */ - pcl_decache_font(pcs, -1); - - break; - case 3: - /* Delete character <font_id, character_code>. */ - if ( pl_dict_find(&pcs->soft_fonts, current_font_id, current_font_id_size, &value) ) - pl_font_remove_glyph((pl_font_t *)value, pcs->character_code); - return 0; - - break; - case 4: - /* Make soft font <font_id> temporary. */ - if ( pl_dict_find(&pcs->soft_fonts, current_font_id, current_font_id_size, &value) ) - ((pl_font_t *)value)->storage = pcds_temporary; - - break; - case 5: - /* Make soft font <font_id> permanent. */ - if ( pl_dict_find(&pcs->soft_fonts, current_font_id, current_font_id_size, &value) ) { - ((pl_font_t *)value)->storage = pcds_permanent; - ((pl_font_t *)value)->params.pjl_font_number = - pjl_proc_register_permanent_soft_font_addition(pcs->pjls); - } - break; - case 6: - { - int code; - if ( pcs->font == 0 ) { - code = pcl_recompute_font(pcs); - if ( code < 0 ) - return code; - } - { - pl_font_t *plfont = pl_clone_font(pcs->font, - pcs->memory, - "pcl_font_control()"); - if ( plfont == 0 ) - return_error(e_Memory); - code = gs_definefont(pcs->font_dir, plfont->pfont); - if ( code < 0 ) - return code; - pcl_delete_soft_font(pcs, current_font_id, current_font_id_size, NULL); - plfont->storage = pcds_temporary; - plfont->data_are_permanent = false; - pl_dict_put(&pcs->soft_fonts, current_font_id, current_font_id_size, plfont); - } - } - break; - default: - return 0; - } - return 0; -} - -private int /* ESC ) s <count> W */ -pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint count = uint_arg(pargs); - const byte *data = arg_data(pargs); - pcl_font_header_t *pfh = (pcl_font_header_t *)data; - uint desc_size; - pl_font_scaling_technology_t fst; - gs_memory_t *mem = pcs->memory; - pl_font_t *plfont; - byte *header; - int code; - - if ( count < 64 ) - return e_Range; - desc_size = - (pfh->FontDescriptorSize[0] << 8) + pfh->FontDescriptorSize[1]; - /* Dispatch on the header format. */ - switch ( pfh->HeaderFormat ) - { - case pcfh_bitmap: - case pcfh_resolution_bitmap: - fst = plfst_bitmap; - break; - case pcfh_intellifont_bound: - case pcfh_intellifont_unbound: - fst = plfst_Intellifont; - break; - case pcfh_truetype: - case pcfh_truetype_large: - fst = plfst_TrueType; - break; - default: - return_error(gs_error_invalidfont); - } - /* Delete any previous font with this ID. */ - pcl_delete_soft_font(pcs, current_font_id, current_font_id_size, NULL); - /* Create the generic font information. */ - plfont = pl_alloc_font(mem, "pcl_font_header(pl_font_t)"); - header = gs_alloc_bytes(mem, count, "pcl_font_header(header)"); - if ( plfont == 0 || header == 0 ) - return_error(e_Memory); - memcpy(header, data, count); - plfont->storage = pcds_temporary; - plfont->data_are_permanent = false; - plfont->header = header; - plfont->header_size = count; - plfont->scaling_technology = fst; - plfont->font_type = (pl_font_type_t)pfh->FontType; - code = pl_font_alloc_glyph_table(plfont, 256, mem, - "pcl_font_header(char table)"); - if ( code < 0 ) - return code; - /* Create the actual font. */ - switch ( fst ) - { - case plfst_bitmap: - { - gs_font_base *pfont = - gs_alloc_struct(mem, gs_font_base, &st_gs_font_base, - "pcl_font_header(bitmap font)"); - - if ( pfont == 0 ) - return_error(e_Memory); - code = pl_fill_in_font((gs_font *)pfont, plfont, pcs->font_dir, - mem); - if ( code < 0 ) - return code; - pl_fill_in_bitmap_font(pfont, gs_next_ids(1)); - /* Extract parameters from the font header. */ - if ( pfh->HeaderFormat == pcfh_resolution_bitmap ) - { -#define pfhx ((const pcl_resolution_bitmap_header_t *)pfh) - plfont->resolution.x = pl_get_uint16(pfhx->XResolution); - plfont->resolution.y = pl_get_uint16(pfhx->YResolution); -#undef pfhx - } - else - plfont->resolution.x = plfont->resolution.y = 300; - { ulong pitch_1024th_dots = - ((ulong)pl_get_uint16(pfh->Pitch) << 8) + pfh->PitchExtended; - uint pitch_cp = (uint) - (pitch_1024th_dots / 1024.0 /* dots */ - / plfont->resolution.x /* => inches */ - * 7200.0); - - pl_fp_set_pitch_cp(&plfont->params, pitch_cp); - } - { - uint height_quarter_dots = pl_get_uint16(pfh->Height); - plfont->params.height_4ths = - (uint)(floor((double)height_quarter_dots * 72.0 / - (double)(plfont->resolution.x) + 0.5)); - } - break; - } - case plfst_TrueType: - { - gs_font_type42 *pfont = - gs_alloc_struct(mem, gs_font_type42, &st_gs_font_type42, - "pcl_font_header(truetype font)"); - - if ( pfont == 0 ) - return_error(e_Memory); - { static const pl_font_offset_errors_t errors = { - gs_error_invalidfont, 0 - }; - code = - pl_font_scan_segments(plfont, 70, desc_size, (ulong)count - 2, - pfh->HeaderFormat == pcfh_truetype_large, - &errors); - if ( code < 0 ) - return code; - } - { uint num_chars = pl_get_uint16(pfh->LastCode); - - if ( num_chars < 20 ) - num_chars = 20; - else if ( num_chars > 300 ) - num_chars = 300; - code = pl_tt_alloc_char_glyphs(plfont, num_chars, mem, - "pcl_font_header(char_glyphs)"); - if ( code < 0 ) - return code; - } - code = pl_fill_in_font((gs_font *)pfont, plfont, pcs->font_dir, - mem); - if ( code < 0 ) - return code; - pl_fill_in_tt_font(pfont, NULL, gs_next_ids(1)); - /* pfh->Pitch is design unit width for scalable fonts. */ - { uint pitch_cp = - pl_get_uint16(pfh->Pitch) * 100 / pfont->data.unitsPerEm; - pl_fp_set_pitch_cp(&plfont->params, pitch_cp); - } - } - break; - case plfst_Intellifont: - { - gs_font_base *pfont = - gs_alloc_struct(mem, gs_font_base, &st_gs_font_base, - "pcl_font_header(bitmap font)"); - - if ( pfont == 0 ) - return_error(e_Memory); - code = pl_fill_in_font((gs_font *)pfont, plfont, pcs->font_dir, - mem); - if ( code < 0 ) - return code; - pl_fill_in_intelli_font(pfont, gs_next_ids(1)); - if ( pfh->HeaderFormat == pcfh_intellifont_unbound ) { - bool zero_complement = true; - int i; - memcpy(plfont->character_complement, &data[78], 8); - for (i = 0; i < sizeof(plfont->character_complement); i++) - if (plfont->character_complement[i] != 0x0) { - zero_complement = false; - break; - } - if ( zero_complement ) - plfont->character_complement[7] = 0x7; - } - /* pfh->Pitch is design unit width for scalable fonts. */ - { uint pitch_cp = - pl_get_uint16(pfh->Pitch) * 100 * pfont->FontMatrix.xx; - pl_fp_set_pitch_cp(&plfont->params, pitch_cp); - } - break; - } - default: - return_error(gs_error_invalidfont); /* can't happen */ - } - /* Extract common parameters from the font header. */ - plfont->params.symbol_set = pl_get_uint16(pfh->SymbolSet); - plfont->params.proportional_spacing = pfh->Spacing; - plfont->params.style = (pfh->StyleMSB << 8) + pfh->StyleLSB; - plfont->params.stroke_weight = /* signed byte */ - (int)(pfh->StrokeWeight ^ 0x80) - 0x80; - plfont->params.typeface_family = - (pfh->TypefaceMSB << 8) + pfh->TypefaceLSB; - pl_dict_put(&pcs->soft_fonts, current_font_id, - current_font_id_size, plfont); - plfont->pfont->procs.define_font = gs_no_define_font; - return gs_definefont(pcs->font_dir, plfont->pfont); -} - -private int /* ESC * c <char_code> E */ -pcl_character_code(pcl_args_t *pargs, pcl_state_t *pcs) -{ pcs->character_code = uint_arg(pargs); - return 0; -} - -private int /* ESC ( s <count> W */ -pcl_character_data(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint count = uint_arg(pargs); - uint font_data_size = count; - const byte *data = arg_data(pargs); - void *value; -#define plfont ((pl_font_t *)value) - pcl_font_header_format_t format; - byte *char_data = 0; - - if ( !pl_dict_find(&pcs->soft_fonts, current_font_id, - current_font_id_size, &value) ) - return 0; /* font not found */ - if ( count < 4 || data[2] > count - 2 ) - return e_Range; - if ( data[1] ) /* continuation */ { - /* Check that we are continuing data - we know this is the - case if the previous download character command byte - count is smaller than the data indicated calculating - the space for the glyph */ - if ( (pcs->soft_font_char_data == 0) ) - return e_Range; - /* NB we only enable this for uncompressed bitmap - characters for now, since we don't have real world - examples for the other font file formats. */ - if ( data[0] != pccd_bitmap && data[3] != 1 ) { - dprintf("continuation not implemented for this font type\n"); - return e_Unimplemented; - } - /* append the new data to the new object */ - memcpy(pcs->soft_font_char_data + pcs->soft_font_count, data + 2, count - 2); - /* update the continuation count */ - pcs->soft_font_count += (count -2); - return 0; - } else { - pcs->soft_font_count = 0; - pcs->soft_font_char_data = 0; - } - format = (pcl_font_header_format_t) - ((const pcl_font_header_t *)plfont->header)->HeaderFormat; - switch ( data[0] ) - { - case pccd_bitmap: - { uint width, height; - if ( data[2] != 14 || - (format != pcfh_bitmap && - format != pcfh_resolution_bitmap) - ) - return e_Range; - width = pl_get_uint16(data + 10); - height = pl_get_uint16(data + 12); - switch ( data[3] ) - { - case 1: /* uncompressed bitmap */ - font_data_size = 16 + (((width + 7) >> 3) * height); - if ( count > font_data_size ) - return e_Range; - break; - case 2: /* compressed bitmap */ - { uint y = 0; - const byte *src = data + 16; - const byte *end = data + count; - uint width_bytes = (width + 7) >> 3; - byte *row; - - char_data = - gs_alloc_bytes(pcs->memory, 16 + width_bytes * height, - "pcl_character_data(compressed bitmap)"); - if ( char_data == 0 ) - return_error(e_Memory); - memcpy(char_data, data, 16); - memset(char_data + 16, 0, width_bytes * height); - row = char_data + 16; - while ( src < end && y < height ) - { /* Read the next compressed row. */ - uint x; - int color = 0; - uint reps = *src++; - for ( x = 0; src < end && x < width; color ^= 1 ) - { /* Read the next run. */ - uint rlen = *src++; - - if ( rlen > width - x ) - return e_Range; /* row overrun */ - if ( color ) - { /* Set the run to black. */ - char *data = (char *)row; - while ( rlen-- ) - { - data[x >> 3] |= (128 >> (x & 7)); - x++; - } - } - else - x += rlen; - } - row += width_bytes; - ++y; - /* Replicate the row if needed. */ - for ( ; reps > 0 && y < height; - --reps, ++y, row += width_bytes - ) - memcpy(row, row - width_bytes, width_bytes); - } - } break; - default: - return e_Range; - } - } - break; - case pccd_intellifont: - if ( data[2] != 2 || - (format != pcfh_intellifont_bound && - format != pcfh_intellifont_unbound) - ) - return e_Range; - switch ( data[3] ) - { - case 3: /* non-compound character */ - /* See TRM Figure 11-16 (p. 11-67) for the following. */ - if ( count < 14 ) - return e_Range; - { uint data_size = pl_get_uint16(data + 4); - uint contour_offset = pl_get_uint16(data + 6); - uint metric_offset = pl_get_uint16(data + 8); - uint outline_offset = pl_get_uint16(data + 10); - uint xy_offset = pl_get_uint16(data + 12); - /* The contour data excludes 4 initial bytes of header */ - /* and 2 final bytes of padding/checksum. */ - if ( data_size != count - 6 || - contour_offset < 10 || - metric_offset < contour_offset || - outline_offset < metric_offset || - xy_offset < outline_offset || - xy_offset > count - 6 - ) - return e_Range; - } - break; - case 4: /* compound character */ - /* See TRM Figure 11-18 (p. 11-68) and 11-19 (p. 11-73) */ - /* for the following. */ - if ( count < 8 ) - return e_Range; - { /* - * TRM Figure 11-18 is wrong: the number of components - * is a byte, not a 16-bit quantity. (It is identified - * correctly as a UB on p. 11-70, however.) - */ - uint num_components = data[6]; - if ( count != 8 + num_components * 6 + 2 ) - return e_Range; - } - break; - default: - return e_Range; - } - break; - case pccd_truetype: - if ( format != pcfh_truetype && - format != pcfh_truetype_large - ) - return e_Range; - break; - default: - return e_Range; - } - /* Register the character. */ - /**** FREE PREVIOUS DEFINITION ****/ - /* Compressed bitmaps have already allocated and filled in */ - /* the character data structure. */ - if ( char_data == 0 ) - { - char_data = gs_alloc_bytes(pcs->memory, font_data_size, - "pcl_character_data"); - if ( char_data == 0 ) - return_error(e_Memory); - memcpy(char_data, data, count); - /* NB we only handle continuation for uncompressed bitmap characters */ - if ( data[0] == pccd_bitmap && - data[3] == 1 && - font_data_size > count /* expecting continuation */ - ) { - pcs->soft_font_char_data = char_data; - pcs->soft_font_count = count; - } else { - pcs->soft_font_char_data = 0; - pcs->soft_font_count = 0; - } - } - return pl_font_add_glyph(plfont, pcs->character_code, char_data); -#undef plfont -} - -/* template for casting data to command */ -typedef struct alphanumeric_data_s { - byte operation; - byte string_id[512]; -} alphanumeric_data_t; - -private int /* ESC & n <count> W [operation][string ID] */ -pcl_alphanumeric_id_data(pcl_args_t *pargs, pcl_state_t *pcs) -{ - uint count = uint_arg(pargs); - const alphanumeric_data_t *alpha_data = - (const alphanumeric_data_t *)arg_data(pargs); - int string_id_size = (count - 1); /* size of id data size - operation size */ - if ( count == 0 ) - return 0; - if ( count < 1 || count > 512 ) - return e_Range; - switch ( alpha_data->operation ) - { - case 0: - /* Set the current font id to the given string id. */ - { - char *new_id = (char *)gs_alloc_bytes(pcs->memory, string_id_size, - "pcl_alphanumeric_id_data"); - if ( new_id == 0 ) - return_error(e_Memory); - /* release the previous id, if necessary */ - if ( pcs->alpha_font_id.id ) - gs_free_object( pcs->memory, - pcs->alpha_font_id.id, - "pcl_free_string_id" ); - /* copy in the new id from the data */ - memcpy(new_id, alpha_data->string_id, string_id_size); - /* set new id and size */ - pcs->alpha_font_id.id = (byte *)new_id; - pcs->alpha_font_id.size = string_id_size; - /* now set up the state to use string id's */ - pcs->font_id_type = string_id; - } - break; - case 1: - { - /* Associates the current font's font id to the font - with the string id. We simply create an alias entry - for the current font id entry. HAS - FIXME. ... */ - void *value; - if ( !pl_dict_find(&pcs->soft_fonts, - alpha_data->string_id, - string_id_size, - &value) ) - return 0; - pl_dict_put_synonym(&pcs->soft_fonts, alpha_data->string_id, - string_id_size, current_font_id, - current_font_id_size); - } - break; - case 2: - { - /* Select the fonts referred to by the String ID as - primary. Same as font id selection but uses the - string key instead of a numerical key */ - void *value; - pcl_font_selection_t *pfs = &pcs->font_selection[primary]; - if ( !pl_dict_find(&pcs->soft_fonts, - alpha_data->string_id, - string_id_size, - &value) ) - return 1; - /* NB wrong */ - pcl_set_id_parameters(pcs, pfs, (pl_font_t *)value, 0); - pcl_decache_font(pcs, -1); - } - break; - case 3: - { - /* same as case 2 but sets secondary font */ - void *value; - pcl_font_selection_t *pfs = &pcs->font_selection[secondary]; - if ( !pl_dict_find(&pcs->soft_fonts, - alpha_data->string_id, - string_id_size, - &value) ) - return 1; - /* NB wrong */ - pcl_set_id_parameters(pcs, pfs, (pl_font_t *)value, 0); - pcl_decache_font(pcs, -1); - } - break; - case 4: - { - /* sets the current macro id to the string id */ - char *new_id = (char *)gs_alloc_bytes(pcs->memory, string_id_size, - "pcl_alphanumeric_id_data"); - if ( new_id == 0 ) - return_error(e_Memory); - /* release the previous id, if necessary */ - if ( pcs->alpha_macro_id.id ) - gs_free_object( pcs->memory, - pcs->alpha_macro_id.id, - "pcl_free_string_id" ); - /* copy in the new id from the data */ - memcpy(new_id, alpha_data->string_id, string_id_size); - /* set new id and size */ - pcs->alpha_macro_id.id = (byte *)new_id; - pcs->alpha_macro_id.size = string_id_size; - /* now set up the state to use string id's */ - pcs->macro_id_type = string_id; - } - break; - case 5: - /* associates current macro id to the supplied string id */ - { - void *value; - if ( !pl_dict_find(&pcs->macros, - alpha_data->string_id, - string_id_size, - &value) ) - return 0; - pl_dict_put_synonym(&pcs->macros, alpha_data->string_id, string_id_size, - current_macro_id, current_macro_id_size ); - } - break; - case 20: - /* deletes the font association named by the current Font ID */ - if ( pcs->font_id_type == string_id ) - pcl_delete_soft_font(pcs, current_font_id, current_font_id_size, NULL); - break; - case 21: - /* deletes the macro association named the the current macro id */ - if ( pcs->macro_id_type == string_id ) - pl_dict_undef(&pcs->macros, current_macro_id, current_macro_id_size); - break; - case 100: - /* media select */ - /* this is not sufficiently specified in the PCL - comparison guide and interacts with the control panel - so we do not implement it (yet). */ - return e_Unimplemented; - default: - return e_Range; - } - return 0; -} - -/* Initialization */ -private int -pcsfont_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_CLASS('*') - {'c', 'D', - PCL_COMMAND("Assign Font ID", pcl_assign_font_id, - pca_neg_error|pca_big_error)}, - {'c', 'F', - PCL_COMMAND("Font Control", pcl_font_control, - pca_neg_error|pca_big_error)}, - END_CLASS - DEFINE_CLASS_COMMAND_ARGS(')', 's', 'W', "Font Header", - pcl_font_header, pca_bytes) - DEFINE_CLASS_COMMAND_ARGS('*', 'c', 'E', "Character Code", - pcl_character_code, pca_neg_error|pca_big_ok) - DEFINE_CLASS_COMMAND_ARGS('(', 's', 'W', "Character Data", - pcl_character_data, pca_bytes) - DEFINE_CLASS_COMMAND_ARGS('&', 'n', 'W', "Alphanumeric ID Data", - pcl_alphanumeric_id_data, pca_bytes) - return 0; -} -private void -pcsfont_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ - if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay) ) { - pcs->soft_font_char_data = 0; - pcs->soft_font_count = 0; - id_set_value(pcs->font_id, 0); - pcs->character_code = 0; - pcs->font_id_type = numeric_id; - if ( (type & pcl_reset_printer) != 0 ) { - pcl_args_t args; - arg_set_uint(&args, 1); /* delete temporary fonts */ - pcl_font_control(&args, pcs); - if ( pcs->alpha_font_id.id != 0 ) - gs_free_object(pcs->memory, - pcs->alpha_font_id.id, - "pcsfont_do_reset"); - } - pcs->alpha_font_id.id = 0; - } -} -private int -pcsfont_do_copy(pcl_state_t *psaved, const pcl_state_t *pcs, - pcl_copy_operation_t operation) -{ if ( operation & pcl_copy_after ) - { /* Don't restore the soft font set. */ - /**** MUST HANDLE POSSIBILITY THAT CURRENT FONT WAS DELETED. ****/ - psaved->soft_fonts = pcs->soft_fonts; - } - return 0; -} -const pcl_init_t pcsfont_init = { - pcsfont_do_registration, pcsfont_do_reset, pcsfont_do_copy -}; diff --git a/pcl/pcstate.h b/pcl/pcstate.h deleted file mode 100644 index b96d8df13..000000000 --- a/pcl/pcstate.h +++ /dev/null @@ -1,365 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcstate.h - Definition of PCL5 state */ - -#ifndef pcstate_INCLUDED -# define pcstate_INCLUDED - -#include "gx.h" -#include "gxdevice.h" -#include "gdevcmap.h" -#include "scommon.h" -#include "gscspace.h" -#include "gscolor2.h" -#include "gscrd.h" -#include "gsdcolor.h" /* for gx_ht_tile */ -#include "gschar.h" -#include "pldict.h" -#include "plfont.h" - -/* various components of the state structure */ -#include "pccoord.h" /* centi-point coordinate system */ -#include "pcxfmst.h" /* geometric transformation information */ -#include "pcfontst.h" /* font selection information */ -#include "pctpm.h" /* text parsing method information */ -#include "pcpattyp.h" /* pattern related structures */ -#include "pcdict.h" /* PL dictionary key structure */ -#include "rtrstst.h" /* raster state information */ -#include "pcht.h" -#include "pcident.h" -#include "pccsbase.h" - -/*#include "pgstate.h"*/ /* HP-GL/2 state, included below */ -#include "pjtop.h" - -/* type for string id's */ -typedef struct pcl_string_id_s { - byte * id; - int size; -} alphanumeric_string_id_t; - -/* type for current state of id's, string or regular id's macros */ -typedef enum id_type_enum { - string_id, - numeric_id -} id_type_t; - -/* define different language personalities for dynamic configuration */ -typedef enum personality_enum { /* NB document */ - pcl5c, - pcl5e, - rtl, - hpgl -} pcl_personality_t; - -/* - * Palette stack. This is implemented as a simple linked list. NB - * needs to be moved. - */ -typedef struct pstack_entry_s { - struct pstack_entry_s * pnext; - pcl_palette_t * ppalet; -} pstack_entry_t; - -#ifndef pcl_state_DEFINED -# define pcl_state_DEFINED -typedef struct pcl_state_s pcl_state_t; -#endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; -#endif - -/* - * The routines pcl_gsave and pcl_grestore should be used instead of - * gs_gsave and gs_grestore. See the comment in pcdraw.c for details. - * - * The routine pcl_init_gstate_stk must be called once a boot time to - * intialize PCL graphics state stack tracking mechanism. - */ -int pcl_gsave(P1(pcl_state_t * pcs)); -int pcl_grestore(P1(pcl_state_t * pcs)); -void pcl_init_gstate_stk(P1(pcl_state_t * pcs)); -void pcl_free_gstate_stk(P1(pcl_state_t * pcs)); -/* - * "Cold start" initialization for the graphic state. - */ -void pcl_init_state(P2(pcl_state_t * pcs, gs_memory_t * pmem)); - - -#include "pgstate.h" /* HP-GL/2 state */ - -#ifndef pcl_pattern_data_DEFINED -#define pcl_ht_builtin_dither_DEFINED -typedef struct pcl_pattern_t pcl_pattern; -#endif - -#ifndef pcl_cs_indexed_DEFINED -#define pcl_cs_indexed_DEFINED -typedef struct pcl_cs_indexed_s pcl_cs_indexed_t; -#endif - -/* - * Define the entire PCL/HPGL state. The documentation for this is spread - * out over the PCL reference manuals, and is incomplete, inconsistent, and - * poorly organized. In order to have a ghost (:-)) of a chance of being - * able to think about it as a whole, we've organized it here by - * documentation chapter, just as we did the .c files. - * - * NB: If you modify this structure, be sure to also modify the routine - * pcl_init_state in pcommand.c. - */ -struct pcl_state_s { - - gs_memory_t * memory; - - /* hook back to client data, for callback procedures */ - void * client_data; - - /* graphics state */ - gs_state * pgs; - - /* Define an optional procedure for parsing non-ESC data. */ - int (*parse_other)(P3( void * parse_data, - pcl_state_t * pcs, - stream_cursor_read * pr - )); - void * parse_data; /* closure data for parse_other */ - - /* Chapter 4 (pcjob.c) */ - int num_copies; /* (also a device parameter) */ - bool duplex; /* (also a device parameter) */ - bool bind_short_edge; /* (also a device parameter) */ - bool back_side; /* (also a device parameter) */ - int output_bin; /* (also a device parameter) */ - coord uom_cp; /* centipoints per PCL unit */ - - /* Chapter 5 (pcpage.c) */ - int paper_source; - int perforation_skip; - pcl_margins_t margins; /* relative to print_direction */ - pcl_xfm_state_t xfm_state; - - /* Chapter 6 (pcursor.c) */ - coord hmi_cp; - coord vmi_cp; - int line_termination; - coord_point_t cap; - gs_point cursor_stk[20]; - int cursor_stk_size; - - /* Chapter 8 (pcfont.c) */ - pcl_font_selection_t font_selection[2]; - enum { - primary = 0, - secondary = 1 - } font_selected; - pl_font_t * font; /* 0 means recompute from params */ - pl_dict_t built_in_fonts; /* "built-in", known at start-up */ - - /* Internal variables */ - gs_font_dir * font_dir; /* gs-level dictionary of fonts */ - pl_symbol_map_t * map; /* map for current font (above) */ - - /* more Chapter 8 (pctext.c) */ - bool underline_enabled; - bool underline_floating; - float underline_position; /* distance from baseline */ - - const pcl_text_parsing_method_t * text_parsing_method; - - int text_path; /* 0 or -1 */ - - /* Internal variables */ - float last_width; /* escapement of last char (for BS) */ - coord_point_t underline_start; /* start point of underline */ - bool last_was_BS; /* no printable chars since last BS */ - - /* Chapter 10 (pcsymbol.c) */ - pcl_id_t symbol_set_id; - pl_dict_t soft_symbol_sets; - pl_dict_t built_in_symbol_sets; - int default_symbol_set_value; - - /* Chapter 9 & 11 (pcsfont.c) */ - pcl_id_t font_id; - uint character_code; - pl_dict_t soft_fonts; - uint soft_font_count; - byte * soft_font_char_data; - /* PCL comparison guide - alphanumeric string id */ - alphanumeric_string_id_t alpha_font_id; - id_type_t font_id_type; - -#define current_font_id \ - ( ((pcs->font_id_type == string_id) ? (pcs->alpha_font_id.id) \ - : (id_key(pcs->font_id))) ) - -#define current_font_id_size \ - ( ((pcs->font_id_type == string_id) ? (pcs->alpha_font_id.size) : (2)) ) - - /* Chapter 12 (pcmacros.c) */ - pcl_id_t macro_id; - pcl_id_t overlay_macro_id; - bool overlay_enabled; - int macro_level; - pl_dict_t macros; - - bool defining_macro; - pcl_state_t * saved; /* saved state during execute/call/overlay */ - - /* Internal variables */ - byte * macro_definition; /* for macro being defined, if any */ - alphanumeric_string_id_t alpha_macro_id; - id_type_t macro_id_type; - -#define current_macro_id \ - ( ((pcs->macro_id_type == string_id) ? (pcs->alpha_macro_id.id) \ - : (id_key(pcs->macro_id))) ) - -#define current_macro_id_size \ - ( ((pcs->macro_id_type == string_id) ? (pcs->alpha_macro_id.size) : (2)) ) - - /* Chapter 13 (pcprint.c) */ - gs_point pat_ref_pt; /* active pattern reference point, - * in device space */ - - int pat_orient; /* current pattern orientation */ - int pattern_id; - int current_pattern_id; - pcl_pattern_source_t pattern_type; /* current source for PCL patterns */ - gs_point pcl_pat_ref_pt; /* PCL's pattern reference point */ - pl_dict_t pcl_patterns; /* dictionaries to hold pcl and gl/2 patterns */ - pl_dict_t gl_patterns; -#define PCL_NUM_SHADE_PATTERNS (7) /* pcl support 7 shades of gray */ -#define PCL_NUM_CROSSHATCH_PATTERNS (6) /* and 6 cross hatch patterns */ - pcl_pattern * bi_pattern_array[PCL_NUM_SHADE_PATTERNS + PCL_NUM_CROSSHATCH_PATTERNS]; - int last_pcl_uptrn_id; /* optimizations for recording last patter */ - pcl_pattern * plast_pcl_uptrn; /* and pattern id */ - int last_gl2_RF_indx; - pcl_pattern * plast_gl2_uptrn; - pcl_pattern * psolid_pattern; /* see documentation in pcbiptrn.c for these two */ - pcl_pattern * punsolid_pattern; - bool rotate_patterns; /* rotate patterns with print direction in PCL */ - bool source_transparent; /* (also in graphics state) */ - bool pattern_transparent;/* (also in graphics state); - * PCL and GL/2 set this - * independenty; for GL/2 it is - * known as source transparent */ - bool pcl_pattern_transparent; - - - /* Chapter 14 (pcrect.c) */ - coord_point_t rectangle; - - /* Chapter 15 & Chapter C6 (pcgmode.c) */ - pcl_raster_state_t raster_state; - - /* Chapter 16 (pcstatus.c) */ - int location_type; - int location_unit; - struct _sb { - byte internal_buffer[80]; /* enough for an error message */ - byte * buffer; - uint write_pos; - uint read_pos; - } status; - - /* Chapter 24 (pcmisc.c) */ - bool end_of_line_wrap; - bool display_functions; - int (*configure_appletalk)(P4( const byte * key, - uint key_length, - const byte * value, - uint value_length - )); - - /* Chapter C2/C3/C4 (pcpalet.c/pcindexed.c/pccsbase.c/etc.) */ - int sel_palette_id; - int ctrl_palette_id; - bool monochrome_mode;/* true ==> monochrome print mode */ - int render_mode; /* raw (unmapped) render algorithm */ - pcl_palette_t * ppalet; - pcl_gsid_t next_id; /* id's for palette's and foreground - colors see pcident.h */ - pcl_frgrnd_t * pfrgrnd; - pcl_gsid_t frgnd_cache_id; - - pcl_gstate_ids_t * pids; - /* - * Unlike other elements of the PCL "palette", color rendering dictionaries - * are for the most part not a feature that can be controlled from the language. - * Except for the white point, the parameters of a color rendering dictionary - * are determined by the output device rather than the language. - */ - pcl_crd_t * pcl_default_crd; - - /* internal dithers */ - pcl_ht_builtin_dither_t ordered_dither; - pcl_ht_builtin_dither_t clustered_dither; - pcl_ht_builtin_dither_t noise_dither; - /* - * The forwarding devices to preform any necessary color mapping. There are - * four of these: identity mapping, snap to primaries, map black to white and - * all other colors to black, and monochrome mapping. The devices are all - * identical except for the mapping method used. - * - * Several devices are required because the rendering method used by the - * foreground may not be the same as that used by the current palette. - */ - gs_cie_transform_proc3 dflt_TransformPQR; /* default transform PQR */ - gx_device_cmap cmap_device_identity; - gx_device_cmap cmap_device_snap_to_primaries; - gx_device_cmap cmap_device_color_to_black_over_white; - gx_device_cmap cmap_device_monochrome; - pcl_rend_info_t rendering_info[20]; /* rendering methods */ - byte dflt_rendering_remap[20]; /* NB not convinced this is necessary (review) */ - byte rendering_remap[20]; /* remap the table of rendering methods */ - pcl_ht_t * pdflt_ht; /* default halftone */ - pcl_cs_indexed_t *pdflt_cs_indexed; - pcl_cid_data_t dflt_cid_data; - pcl_cs_base_t * pwhite_cs; - pcl_frgrnd_t * pdflt_frgrnd; - pstack_entry_t *palette_stack; - pcl_palette_t *pdflt_palette; /* default palette */ - pl_dict_t palette_store; /* dictionary to hold the palette store */ - float color_comps[3]; - /* Chapter C5 (pccprint.c) */ - byte logical_op; /* (also in graphics state) */ - byte pp_mode; /* pixel placement mode */ - /* ---------------- HP-GL/2 state ---------------- */ - pcl_hpgl_state_t g; /* see pgstate.h */ - /* ---------------- PJL state -------------------- */ - pl_interp_instance_t *pjls; - /* yet another poorly documented pjl variable - this should widen - the margins on A4 paper to support 80 10 pitch characters but - it appears to affect letter paper as well */ - bool wide_a4; - /* We store away the target device in the pcl state, since the gs - library expects put_params to be applied to the real device and - not pcl forwarding devices */ - gx_device *ptarget_device; - - /* the current language personality */ - pcl_personality_t personality; - - /* store a pointer to the command definitions for use by macros */ - void *pcl_commands; - - /* end page procedure to use */ - int (*end_page)( pcl_state_t * pcs, int num_copies, int flush ); -}; - -/* accessor functions for the pcl target device. These live in - pctop.c for now */ -void pcl_set_target_device(P2(pcl_state_t *pcs, gx_device *pdev)); -gx_device *pcl_get_target_device(P1(pcl_state_t *pcs)); -int pcl_load_cartridge_fonts(P2(pcl_state_t *pcs, const char *pathname)); -int pcl_load_simm_fonts(P2(pcl_state_t *pcs, const char *pathname)); -int pcl_load_built_in_fonts(P2(pcl_state_t *pcs, const char *pathname)); -int pcl_set_current_font_environment(P1(pcl_state_t *pcs)); -/* implicitly exit gl/2 whenever ESC E is found */ -int pcl_implicit_gl2_finish(P1(pcl_state_t *pcs)); -#endif /* pcstate_INCLUDED */ diff --git a/pcl/pcstatus.c b/pcl/pcstatus.c deleted file mode 100644 index 3b90e8d47..000000000 --- a/pcl/pcstatus.c +++ /dev/null @@ -1,726 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcstatus.c - PCL5 status readback commands */ - -#include "memory_.h" -#include "stdio_.h" -#include <stdarg.h> /* how to make this portable? */ -#include "string_.h" -#include "gsmemory.h" -#include "gsmalloc.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcfont.h" -#include "pcsymbol.h" -#include "pcparse.h" -#include "pcpatrn.h" -#include "pcuptrn.h" -#include "pcpage.h" -#include "pcursor.h" -#include "stream.h" - -#define STATUS_BUFFER_SIZE 10000 - -/* Internal routines */ - -private int status_add_symbol_id(ushort *, int, ushort); - - -/* Read out from the status buffer. */ -/* Return the number of bytes read. */ -uint -pcl_status_read(byte *data, uint max_data, pcl_state_t *pcs) -{ uint count = min(max_data, - pcs->status.write_pos - pcs->status.read_pos); - if ( count ) - memcpy(data, pcs->status.buffer + pcs->status.read_pos, count); - pcs->status.read_pos += count; - if ( pcs->status.read_pos == pcs->status.write_pos ) - { gs_free_object(pcs->memory, pcs->status.buffer, "status buffer"); - pcs->status.write_pos = pcs->status.read_pos = 0; - } - return count; -} - -/* Write a string on a stream. */ -private void -stputs(stream *s, const char *str) -{ uint ignore_count; - sputs(s, (const byte *)str, strlen(str), &ignore_count); -} - -/* printf on a stream. */ -/**** THIS SHOULD BE IN THE STREAM PACKAGE. ****/ -void -stprintf(stream *s, const char *fmt, ...) -{ uint count; - va_list args; - char buf[1024]; - - va_start(args, fmt); - count = vsprintf(buf, fmt, args); - sputs(s, (const byte *)buf, count, &count); -} - -/* Set up a stream for writing into the status buffer. */ -private void -status_begin(stream *s, pcl_state_t *pcs) -{ byte *buffer = pcs->status.buffer; - - if ( pcs->status.read_pos > 0 ) - { memmove(buffer, buffer + pcs->status.read_pos, - pcs->status.write_pos - pcs->status.read_pos); - pcs->status.write_pos -= pcs->status.read_pos; - pcs->status.read_pos = 0; - } - if ( buffer == 0 ) - { buffer = gs_alloc_bytes(pcs->memory, STATUS_BUFFER_SIZE, - "status buffer"); - pcs->status.buffer = buffer; - } - if ( buffer == 0 ) - swrite_string(s, pcs->status.internal_buffer, - sizeof(pcs->status.internal_buffer)); - else - swrite_string(s, buffer, gs_object_size(pcs->memory, buffer)); - sseek(s, pcs->status.write_pos); - stputs(s, "PCL\r\n"); -} - -/* Add an ID to a list being written. */ -private void -status_put_id(stream *s, const char *title, const char *id) -{ /* HACK: we know that there's at least one character in the buffer. */ - if ( *s->cursor.w.ptr == '\n' ) - { /* We haven't started the list yet. */ - stprintf(s, "%s=\"%s", title, id); - } - else - { stprintf(s, ",%s", id); - } -} - - -/* Finish writing an ID list. */ -private void -status_end_id_list(stream *s) -{ /* HACK: we know that there's at least one character in the buffer. */ - if ( *s->cursor.w.ptr != '\n' ) - stputs(s, "\"\r\n"); -} - - -private void -status_print_idlist(stream *s, const ushort *idlist, int nid, const char *title) -{ - int i; - - for ( i = 0; i < nid; i++ ) - { char idstr[6]; /* ddddL and a null */ - int n, l; - n = idlist[i] >> 6; - l = (idlist[i] & 077) + 'A' - 1; - sprintf(idstr, "%d%c", n, l); - status_put_id(s, title, idstr); - } - status_end_id_list(s); -} - - -/* Output a number, at most two decimal places, but trimming trailing 0's - * and possibly the ".". Want to match HP's output as closely as we can. */ -private void -status_put_floating(stream *s, double v) -{ /* Figure the format--easier than printing and chipping out the - * chars we need. */ - int vf = (int)(v * 100 + ((v < 0)? -0.5: 0.5)); - if ( vf / 100 * 100 == vf ) - stprintf(s, "%d", vf / 100); - else if ( vf / 10 * 10 == vf ) - stprintf(s, "%.1f", v); - else - stprintf(s, "%.2f", v); -} - -/* Print font status information. */ -/* font_set = -1 for font list, 0 or 1 for current font. */ -private int -status_put_font(stream *s, pcl_state_t *pcs, - uint font_id, uint internal_id, - pl_font_t *plfont, int font_set, bool extended) -{ char paren = (font_set > 0 ? ')' : '('); - bool proportional = plfont->params.proportional_spacing; - - /* first escape sequence: symbol-set selection */ - stputs(s, "SELECT=\""); - if ( pl_font_is_bound(plfont) || font_set > 0 ) - { /* Bound or current font, put out the symbol set. */ - uint symbol_set = font_set > 0? - pcs->font_selection[font_set].params.symbol_set: - plfont->params.symbol_set; - stprintf(s, "<Esc>%c%u%c", paren, symbol_set >> 5, - (symbol_set & 31) + 'A' - 1); - } - - /* second escape sequence: font selection */ - stprintf(s, "<Esc>%cs%dp", paren, proportional); - if ( plfont->scaling_technology == plfst_bitmap ) - { /* Bitmap font */ - status_put_floating(s, pl_fp_pitch_per_inch(&plfont->params)); - stputs(s, "h"); - status_put_floating(s, plfont->params.height_4ths / 4.0); - stputs(s, "v"); - } - else - { /* Scalable font: output depends on whether selected */ - if ( font_set > 0 ) - { /* If selected, we have to cheat and reach up for info; - * plfont is below where the scaled values exist. */ - if ( proportional ) - { status_put_floating(s, - pcs->font_selection[font_set].params.height_4ths / 4.0); - stputs(s, "h"); - } - else - { status_put_floating(s, - pl_fp_pitch_per_inch(&pcs->font_selection[font_set]. - params)); - stputs(s, "v"); - } - } - else - { - stputs(s, proportional? "__v": "__h"); - } - } - stprintf(s, "%ds%db%uT", plfont->params.style, - plfont->params.stroke_weight, plfont->params.typeface_family); - if ( plfont->storage & pcds_downloaded ) - stprintf(s, "<Esc>%c%uX", paren, font_id); - stputs(s, "\"\r\n"); - if ( !pl_font_is_bound(plfont) && font_set < 0 ) - { int nid; - ushort *idlist; - pl_dict_enum_t denum; - gs_const_string key; - void *value; - - idlist = (ushort *)gs_alloc_bytes(pcs->memory, - pl_dict_length(&pcs->soft_symbol_sets, false) + - pl_dict_length(&pcs->built_in_symbol_sets, false), - "status_fonts(idlist)"); - if ( idlist == NULL ) - return e_Memory; - nid = 0; - /* Current fonts show the symbol set bound to them, above. */ - - /* NOTE: Temporarily chain soft, built-in symbol sets. DON'T - * exit this section without unchaining them. */ - pl_dict_set_parent(&pcs->soft_symbol_sets, - &pcs->built_in_symbol_sets); - pl_dict_enum_begin(&pcs->soft_symbol_sets, &denum); - while ( pl_dict_enum_next(&denum, &key, &value) ) - { pcl_symbol_set_t *ssp = (pcl_symbol_set_t *)value; - pl_glyph_vocabulary_t gx; - - for ( gx = plgv_MSL; gx < plgv_next; gx++ ) - if ( ssp->maps[gx] != NULL && - pcl_check_symbol_support( - ssp->maps[gx]->character_requirements, - plfont->character_complement) ) - { - nid = status_add_symbol_id(idlist, nid, - (ssp->maps[gx]->id[0] << 8) + ssp->maps[gx]->id[1]); - break; /* one will suffice */ - } - } - pl_dict_set_parent(&pcs->soft_symbol_sets, NULL); - /* Symbol sets are back to normal. */ - - gs_free_object(pcs->memory, (void*)idlist, - "status_fonts(idlist)"); - } - if ( extended ) - { /* Put out the "internal ID number". */ - if ( plfont->storage & pcds_temporary ) - stputs(s, "DEFID=NONE\r\n"); - else - { - stputs(s, "DEFID=\""); - if ( plfont->storage & pcds_all_cartridges ) - { int c; - int n = (plfont->storage & pcds_all_cartridges) >> - pcds_cartridge_shift; - - /* pick out the bit index of the cartridge */ - for (c = 0; (n & 1) == 0; c++) - n >>= 1; - stprintf(s, "C%d ", c); - } - else if ( plfont->storage & pcds_all_simms ) - { int m; - int n = (plfont->storage & pcds_all_simms) >> - pcds_simm_shift; - - /* pick out the bit index of the SIMM */ - for (m = 0; (n & 1) == 0; m++) - n >>= 1; - stprintf(s, "M%d ", m); - } - else - /* internal _vs_ permanent soft */ - stputs(s, (plfont->storage & pcds_internal)? "I ": "S "); - stprintf(s, "%d\"\r\n", internal_id); - } - - /* XXX Put out the font name - we need a way to get the name - * for fonts that weren't downloaded, hence lack the known - * header field. */ - if ( (plfont->storage & pcds_downloaded) && - plfont->header != NULL ) - { /* Wire in the size of the FontName field (16)--it can't - * change anyway, and this saves work. */ - pcl_font_header_t *hdr = (pcl_font_header_t *)(plfont->header); - - stprintf(s, "NAME=\"%.16s\"\r\n", hdr->FontName); - } - } - return 0; -} - -/* Finish writing status. */ -/* If we overflowed the buffer, store an error message. */ -private void -status_end(stream *s, pcl_state_t *pcs) -{ if ( sendwp(s) ) - { /* Overrun. Scan back to the last EOL that leaves us */ - /* enough room for the error line. */ - static const char *error_line = "ERROR=INTERNAL ERROR\r\n"; - int error_size = strlen(error_line) + 1; - uint limit = gs_object_size(pcs->memory, pcs->status.buffer); - uint wpos = stell(s); - - while ( limit - wpos < error_size || - pcs->status.buffer[wpos - 1] != '\n' - ) - --wpos; - s->end_status = 0; /**** SHOULDN'T BE NECESSARY ****/ - sseek(s, wpos); - stputs(s, error_line); - } - sputc(s, FF); - pcs->status.write_pos = stell(s); -} - -/* Status readouts */ -/* storage = 0 means currently selected, otherwise it is a mask. */ - -private int -status_do_fonts(stream *s, pcl_state_t *pcs, - pcl_data_storage_t storage, bool extended) -{ gs_const_string key; - void *value; - pl_dict_enum_t denum; - int res; - - pl_dict_enum_begin(&pcs->soft_fonts, &denum); - while ( pl_dict_enum_next(&denum, &key, &value) ) - { uint id = (key.data[0] << 8) + key.data[1]; - if ( (((pl_font_t *)value)->storage & storage) != 0 || - (storage == 0 && pcs->font == (pl_font_t *)value) - ) - res = status_put_font(s, pcs, id, id, (pl_font_t *)value, - (storage != 0 ? -1 : pcs->font_selected), extended); - if ( res != 0 ) - return res; - } - return 0; -} - -private int -status_fonts(stream *s, pcl_state_t *pcs, - pcl_data_storage_t storage) -{ return status_do_fonts(s, pcs, storage, false); -} - -private int -status_macros(stream *s, pcl_state_t *pcs, - pcl_data_storage_t storage) -{ gs_const_string key; - void *value; - pl_dict_enum_t denum; - - if ( storage == 0 ) - return 0; /* no "currently selected" macro */ - pl_dict_enum_begin(&pcs->macros, &denum); - while ( pl_dict_enum_next(&denum, &key, &value) ) - if ( ((pcl_macro_t *)value)->storage & storage ) - { char id_string[6]; - sprintf(id_string, "%u", (key.data[0] << 8) + key.data[1]); - status_put_id(s, "IDLIST", id_string); - } - status_end_id_list(s); - return 0; -} - -/* - * Get a list of current provided patterns in the given storage class(es). - * The pattern storage dictionary is now private, and provides no externally - * visible enumeratioin; hence this operation is rather crudely implemented. - */ - private int -status_patterns( - stream * s, - pcl_state_t * pcs, - pcl_data_storage_t storage -) -{ - if (storage == 0) { - int id = pcs->current_pattern_id; - pcl_pattern_t * pptrn = pcl_pattern_get_pcl_uptrn(pcs, id); - - if ((pptrn != 0) && (pcs->pattern_type == pcl_pattern_user_defined)) { - char id_string[6]; - - sprintf(id_string, "%u", id); - status_put_id(s, "IDLIST", id_string); - } - } else { - int id; - - for (id = 0; id < (1L << 15) - 1; id++) { - pcl_pattern_t * pptrn = pcl_pattern_get_pcl_uptrn(pcs, id); - - if (pptrn != 0) { - char id_string[6]; - - sprintf(id_string, "%u", id); - status_put_id(s, "IDLIST", id_string); - } - } - } - status_end_id_list(s); - return 0; -} - - -private bool /* Is this symbol map supported by any relevant font? */ -status_check_symbol_set(pcl_state_t *pcs, pl_symbol_map_t *mapp, - pcl_data_storage_t storage) -{ gs_const_string key; - void *value; - pl_dict_enum_t fenum; - - pl_dict_enum_begin(&pcs->soft_fonts, &fenum); - while ( pl_dict_enum_next(&fenum, &key, &value) ) - { pl_font_t *fp = (pl_font_t *)value; - - if ( fp->storage != storage ) - continue; - if ( pcl_check_symbol_support(mapp->character_requirements, - fp->character_complement) ) - return true; - } - return false; -} - -private int /* add symbol set ID to list (insertion), return new length */ -status_add_symbol_id(ushort *idlist, int nid, ushort new_id) -{ int i; - ushort *idp; - ushort t1, t2; - - for ( i = 0, idp = idlist; i < nid; i++ ) - if ( new_id <= *idp ) - break; - if ( new_id == *idp ) /* duplicate item */ - return nid; - /* insert new_id in front of *idp */ - for ( t1 = new_id; i < nid; i++ ) - { - t2 = *idp; - *idp++ = t1; - t1 = t2; - } - *idp = t1; - return nid + 1; -} - -private int -status_symbol_sets(stream *s, pcl_state_t *pcs, pcl_data_storage_t storage) -{ gs_const_string key; - void *value; - pl_dict_enum_t denum; - ushort *idlist; - int nid; - - if ( storage == 0 ) - return 0; /* no "currently selected" symbol set */ - - /* Note carefully the meaning of this status inquiry. First, - * we return only symbol sets applicable to unbound fonts. Second, - * the "storage" value refers to the location of fonts. */ - - /* total up built-in symbol sets, downloaded ones */ - nid = pl_dict_length(&pcs->soft_symbol_sets, false) + - pl_dict_length(&pcs->built_in_symbol_sets, false); - idlist = (ushort *)gs_alloc_bytes(pcs->memory, nid * sizeof(ushort), - "status_symbol_sets(idlist)"); - if ( idlist == NULL ) - return e_Memory; - nid = 0; - - /* For each symbol set, - * for each font in appropriate storage, - * if the font supports that symbol set, list the symbol set - * and break (because we only need to find one such font). */ - - /* NOTE: Temporarily chain soft, built-in symbol sets. DON'T - * exit this section without unchaining them. */ - pl_dict_set_parent(&pcs->soft_symbol_sets, - &pcs->built_in_symbol_sets); - pl_dict_enum_begin(&pcs->soft_symbol_sets, &denum); - while ( pl_dict_enum_next(&denum, &key, &value) ) - { pcl_symbol_set_t *ssp = (pcl_symbol_set_t *)value; - pl_glyph_vocabulary_t gx; - - for ( gx = plgv_MSL; gx < plgv_next; gx++ ) - if ( ssp->maps[gx] != NULL && - status_check_symbol_set(pcs, ssp->maps[gx], storage) ) - { - nid = status_add_symbol_id(idlist, nid, - (ssp->maps[gx]->id[0] << 8) + ssp->maps[gx]->id[1]); - break; /* one will suffice */ - } - } - pl_dict_set_parent(&pcs->soft_symbol_sets, NULL); - /* Symbol sets are back to normal. */ - - status_print_idlist(s, idlist, nid, "IDLIST"); - gs_free_object(pcs->memory, (void*)idlist, - "status_symbol_sets(idlist)"); - return 0; -} - -private int -status_fonts_extended(stream *s, pcl_state_t *pcs, - pcl_data_storage_t storage) -{ return status_do_fonts(s, pcs, storage, true); -} - -private int (*const status_write[])(P3(stream *s, pcl_state_t *pcs, - pcl_data_storage_t storage)) = { - status_fonts, status_macros, status_patterns, status_symbol_sets, - status_fonts_extended -}; - -/* Commands */ - -private int /* ESC * s <enum> T */ -pcl_set_readback_loc_type(pcl_args_t *pargs, pcl_state_t *pcs) -{ pcs->location_type = uint_arg(pargs); - return 0; -} - -private int /* ESC * s <enum> U */ -pcl_set_readback_loc_unit(pcl_args_t *pargs, pcl_state_t *pcs) -{ pcs->location_unit = uint_arg(pargs); - return 0; -} - -private int /* ESC * s <enum> I */ -pcl_inquire_readback_entity(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint i = uint_arg(pargs); - int unit = pcs->location_unit; - stream st; - static const char *entity_types[] = { - "FONTS", "MACROS", "PATTERNS", "SYMBOLSETS", "FONTS EXTENDED" - }; - pcl_data_storage_t storage; - int code = 0; - long pos; - - if ( i > 4 ) - return e_Range; - status_begin(&st, pcs); - stprintf(&st, "INFO %s\r\n", entity_types[i]); - switch ( pcs->location_type ) - { - case 0: /* invalid location */ - code = -1; - break; - case 1: /* currently selected */ - storage = (pcl_data_storage_t)0; /* indicates currently selected */ - break; - case 2: /* all locations */ - storage = (pcl_data_storage_t)~0; - break; - case 3: /* internal */ - if ( unit != 0 ) - { code = -1; - break; - } - storage = pcds_internal; - break; - case 4: /* downloaded */ - if ( unit > 2 ) - code = -1; - else - { static const pcl_data_storage_t dl_masks[] = - { pcds_downloaded, pcds_temporary, pcds_permanent - }; - storage = dl_masks[unit]; - } - break; - case 5: /* cartridges */ - if ( unit == 0 ) - storage = (pcl_data_storage_t)pcds_all_cartridges; - else if ( unit <= pcds_cartridge_max ) - storage = (pcl_data_storage_t) - (1 << (pcds_cartridge_shift + unit - 1)); - else - code = -1; - break; - case 6: /* SIMMs */ - if ( unit == 0 ) - storage = (pcl_data_storage_t)pcds_all_simms; - else if ( unit <= pcds_simm_max ) - storage = (pcl_data_storage_t)(1 << (pcds_simm_shift + unit - 1)); - else - code = -1; - break; - default: - stputs(&st, "ERROR=INVALID ENTITY\r\n"); - break; - } - if ( code >= 0 ) - { pos = stell(&st); - code = (*status_write[i])(&st, pcs, storage); - if ( code >= 0 ) - { if ( stell(&st) == pos ) - stputs(&st, "ERROR=NONE\r\n"); - else if ( storage == 0 ) /* currently selected */ - stprintf(&st, "LOCTYPE=%d\r\nLOCUNIT=%d\r\n", - pcs->location_type, unit); - } - } - if ( code < 0 ) - { - if ( code == e_Memory ) - stputs(&st, "ERROR=INTERNAL ERROR\r\n"); - else - stputs(&st, "ERROR=INVALID LOCATION\r\n"); - } - status_end(&st, pcs); - return 0; -} - -private int /* ESC * s 1 M */ -pcl_free_space(pcl_args_t *pargs, pcl_state_t *pcs) -{ stream st; - - status_begin(&st, pcs); - stprintf(&st, "INFO MEMORY\r\n"); - if ( int_arg(pargs) != 1 ) - stprintf(&st, "ERROR=INVALID UNIT\r\n"); - else - { gs_memory_status_t mstat; - gs_memory_status(pcs->memory, &mstat); - if ( pcs->memory != &gs_memory_default ) - { gs_memory_status_t dstat; - gs_memory_status(&gs_memory_default, &dstat); - mstat.allocated += dstat.allocated; - mstat.used += dstat.used; - } - stprintf(&st, "TOTAL=%ld\r\n", mstat.allocated - mstat.used); - /* We don't currently have an API for determining */ - /* the largest contiguous block. */ - /**** RETURN SOMETHING RANDOM ****/ - stprintf(&st, "LARGEST=%ld\r\n", - (mstat.allocated - mstat.used) >> 2); - } - status_end(&st, pcs); - return 0; -} - -private int /* ESC & r <bool> F */ -pcl_flush_all_pages(pcl_args_t *pargs, pcl_state_t *pcs) -{ switch ( uint_arg(pargs) ) - { - case 0: - { /* Flush all complete pages. */ - /* This is a driver function.... */ - return 0; - } - case 1: - { /* Flush all pages, including an incomplete one. */ - int code = pcl_end_page_if_marked(pcs); - - if (code >= 0) - pcl_home_cursor(pcs); - return code; - } - default: - return e_Range; - } -} - -private int /* ESC * s <int_id> X */ -pcl_echo(pcl_args_t *pargs, pcl_state_t *pcs) -{ stream st; - - status_begin(&st, pcs); - stprintf(&st, "ECHO %d\r\n", int_arg(pargs)); - status_end(&st, pcs); - return 0; -} - -/* Initialization */ -private int -pcstatus_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_CLASS('*') - {'s', 'T', - PCL_COMMAND("Set Readback Location Type", - pcl_set_readback_loc_type, - pca_neg_error|pca_big_error)}, - {'s', 'U', - PCL_COMMAND("Set Readback Location Unit", - pcl_set_readback_loc_unit, - pca_neg_error|pca_big_error)}, - {'s', 'I', - PCL_COMMAND("Inquire Readback Entity", - pcl_inquire_readback_entity, - pca_neg_error|pca_big_error)}, - {'s', 'M', - PCL_COMMAND("Free Space", pcl_free_space, - pca_neg_ok|pca_big_ok)}, - END_CLASS - DEFINE_CLASS_COMMAND_ARGS('&', 'r', 'F', "Flush All Pages", - pcl_flush_all_pages, - pca_neg_error|pca_big_error) - DEFINE_CLASS_COMMAND_ARGS('*', 's', 'X', "Echo", - pcl_echo, pca_neg_ok|pca_big_error) - return 0; -} -private void -pcstatus_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ if ( type & (pcl_reset_initial | pcl_reset_printer) ) - { if ( type & pcl_reset_initial ) - { pcs->status.buffer = 0; - pcs->status.write_pos = 0; - pcs->status.read_pos = 0; - } - pcs->location_type = 0; - pcs->location_unit = 0; - } -} - -const pcl_init_t pcstatus_init = { - pcstatus_do_registration, pcstatus_do_reset -}; diff --git a/pcl/pcsymbol.c b/pcl/pcsymbol.c deleted file mode 100644 index 33df3d6f0..000000000 --- a/pcl/pcsymbol.c +++ /dev/null @@ -1,320 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcsymbol.c */ -/* PCL5 user-defined symbol set commands */ -#include "stdio_.h" /* std.h + NULL */ -#include "plvalue.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcfont.h" -#include "pcsymbol.h" - - -private int /* ESC * c <id> R */ -pcl_symbol_set_id_code(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint id = uint_arg(pargs); - id_set_value(pcs->symbol_set_id, id); - return 0; -} - -private int /* ESC ( f <count> W */ -pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcs) -{ uint count = uint_arg(pargs); - const pl_symbol_map_t *psm = (pl_symbol_map_t *)arg_data(pargs); - uint header_size; - uint first_code, last_code; - gs_memory_t *mem = pcs->memory; - pl_symbol_map_t *header; - pcl_symbol_set_t *symsetp; - pl_glyph_vocabulary_t gv; - -#define psm_header_size 18 - if ( count < psm_header_size ) - return e_Range; - header_size = pl_get_uint16(psm->header_size); - if ( header_size < psm_header_size || - psm->id[0] != id_key(pcs->symbol_set_id)[0] || - psm->id[1] != id_key(pcs->symbol_set_id)[1] || - psm->type > 2 - ) - return e_Range; - switch ( psm->format ) - { - case 1: - case 3: - break; - default: - return e_Range; - } - first_code = pl_get_uint16(psm->first_code); - last_code = pl_get_uint16(psm->last_code); - gv = (psm->character_requirements[7] & 07)==1? plgv_Unicode: plgv_MSL; - { int num_codes = last_code - first_code + 1; - int i; - - if ( num_codes <= 0 || count < psm_header_size + num_codes * 2 ) - return e_Range; - header = - (pl_symbol_map_t *)gs_alloc_bytes(mem, - sizeof(pl_symbol_map_t), - "pcl_font_header(header)"); - if ( header == 0 ) - return_error(e_Memory); - memcpy((void *)header, (void *)psm, psm_header_size); - /* specify that we do not allow these sets to map to and fro - msl and unicode */ - header->mapping_type = PLGV_NO_MAPPING; - /* - * Byte swap the codes now, so that we don't have to byte swap - * them every time we access them. - */ - for ( i = num_codes; --i >= 0; ) - header->codes[i] = - pl_get_uint16((byte *)psm + psm_header_size + i * 2); - } -#undef psm_header_size - - /* Symbol set may already exist; if so, we may be replacing one of - * its existing maps or adding one for a new glyph vocabulary. */ - if ( pl_dict_find(&pcs->soft_symbol_sets, id_key(pcs->symbol_set_id), - 2, (void **)&symsetp) ) - { - if ( symsetp->maps[gv] != NULL ) - gs_free_object(mem, symsetp->maps[gv], "symset map"); - } - else - { pl_glyph_vocabulary_t gx; - symsetp = (pcl_symbol_set_t *)gs_alloc_bytes(mem, - sizeof(pcl_symbol_set_t), "symset dict value"); - if ( !symsetp ) - return_error(e_Memory); - for ( gx = plgv_MSL; gx < plgv_next; gx++ ) - symsetp->maps[gx] = NULL; - symsetp->storage = pcds_temporary; - pl_dict_put(&pcs->soft_symbol_sets, id_key(pcs->symbol_set_id), - 2, symsetp); - } - symsetp->maps[gv] = header; - - return 0; -} - -private int /* ESC * c <ssc_enum> S */ -pcl_symbol_set_control(pcl_args_t *pargs, pcl_state_t *pcs) -{ gs_const_string key; - void *value; - pl_dict_enum_t denum; - - switch ( int_arg(pargs) ) - { - case 0: - { /* Delete all user-defined symbol sets. */ - /* Note: When deleting symbol set(s), it is easier (safer?) - * to decache and reselect fonts unconditionally. (Consider, - * for example, deleting a downloaded overload of a built-in - * which might be the default ID.) */ - pl_dict_release(&pcs->soft_symbol_sets); - pcl_decache_font(pcs, -1); - } - return 0; - case 1: - { /* Delete all temporary symbol sets. */ - pl_dict_enum_stack_begin(&pcs->soft_symbol_sets, &denum, false); - while ( pl_dict_enum_next(&denum, &key, &value) ) - if ( ((pcl_symbol_set_t *)value)->storage == pcds_temporary ) - pl_dict_undef(&pcs->soft_symbol_sets, key.data, key.size); - pcl_decache_font(pcs, -1); - } - return 0; - case 2: - { /* Delete symbol set <symbol_set_id>. */ - pl_dict_undef(&pcs->soft_symbol_sets, - id_key(pcs->symbol_set_id), 2); - pcl_decache_font(pcs, -1); - } - return 0; - case 4: - { /* Make <symbol_set_id> temporary. */ - if ( pl_dict_find(&pcs->soft_symbol_sets, - id_key(pcs->symbol_set_id), 2, &value) ) - ((pcl_symbol_set_t *)value)->storage = pcds_temporary; - } - return 0; - case 5: - { /* Make <symbol_set_id> permanent. */ - if ( pl_dict_find(&pcs->soft_symbol_sets, - id_key(pcs->symbol_set_id), 2, &value) ) - ((pcl_symbol_set_t *)value)->storage = pcds_permanent; - } - return 0; - default: - return 0; - } -} - -private void /* free any symbol maps as well as dict value entry */ -pcsymbol_dict_value_free(gs_memory_t *mem, void *value, client_name_t cname) -{ pcl_symbol_set_t *ssp = (pcl_symbol_set_t *)value; - pl_glyph_vocabulary_t gx; - - if ( ssp->storage != pcds_internal ) - { - for ( gx = plgv_MSL; gx < plgv_next; gx++ ) - { - if ( ssp->maps[gx] != NULL ) - gs_free_object(mem, (void*)ssp->maps[gx], cname); - } - } - gs_free_object(mem, value, cname); -} - -private int -pcl_load_built_in_symbol_sets(pcl_state_t *pcs) -{ - const pl_symbol_map_t **maplp; - pcl_symbol_set_t *symsetp; - pl_glyph_vocabulary_t gv; - - for ( maplp = &pl_built_in_symbol_maps[0]; *maplp; maplp++ ) - { - const pl_symbol_map_t *mapp = *maplp; - /* Create entry for symbol set if this is the first map for - * that set. */ - if ( !pl_dict_find(&pcs->built_in_symbol_sets, mapp->id, 2, - (void **)&symsetp) ) - { pl_glyph_vocabulary_t gx; - symsetp = (pcl_symbol_set_t *)gs_alloc_bytes(pcs->memory, - sizeof(pcl_symbol_set_t), "symset init dict value"); - if ( !symsetp ) - return_error(e_Memory); - for ( gx = plgv_MSL; gx < plgv_next; gx++ ) - symsetp->maps[gx] = NULL; - symsetp->storage = pcds_internal; - } - gv = (mapp->character_requirements[7] & 07)==1? - plgv_Unicode: plgv_MSL; - pl_dict_put(&pcs->built_in_symbol_sets, mapp->id, 2, symsetp); - symsetp->maps[gv] = (pl_symbol_map_t *)mapp; - } - return 0; -} - -bool -pcl_check_symbol_support(const byte *symset_req, const byte *font_sup) -{ int i; - - /* if glyph vocabularies match, following will work on the - * last 3 bits of last byte. Note that the font-support bits - * are inverted (0 means available). - */ - for ( i = 0; i < 7; i++ ) - if ( symset_req[i] & font_sup[i] ) - return false; /* something needed, not present */ - /* check the last byte but not the glyph vocabularies. */ - if ((symset_req[7] >> 3) & (font_sup[7] >> 3)) - return false; - - return true; -} - - -/* Find the symbol map for a particular symbol set and glyph vocabulary, - * if it exists. - * There are two dictionaries--one for soft (downloaded) symbol sets and - * one for built-ins. These are searched separately. The actual maps - * present for a symbol set may overlap between soft and built-in. */ -pl_symbol_map_t * -pcl_find_symbol_map(const pcl_state_t *pcs, const byte *id, - pl_glyph_vocabulary_t gv) -{ - pcl_symbol_set_t *setp; - - if ( pl_dict_find((pl_dict_t *)&pcs->soft_symbol_sets, - id, 2, (void **)&setp) && - setp->maps[gv] != NULL ) - return setp->maps[gv]; - if ( pl_dict_find((pl_dict_t *)&pcs->built_in_symbol_sets, - id, 2, (void**)&setp) ) { - /* simple case we found a matching symbol set */ - if ( setp->maps[gv] != NULL ) - return setp->maps[gv]; - /* we requested a unicode symbol set and found an msl - symbol set that can be mapped to unicode */ - if ( (gv == plgv_Unicode) && - (setp->maps[plgv_MSL]) && - ((setp->maps[plgv_MSL])->mapping_type == PLGV_M2U_MAPPING) ) - return setp->maps[plgv_MSL]; - /* we requested an msl symbol set and found a unicode - symbol set that can be mapped to msl */ - if ( (gv == plgv_MSL) && - (setp->maps[plgv_Unicode]) && - ((setp->maps[plgv_Unicode])->mapping_type == PLGV_U2M_MAPPING) ) - return setp->maps[plgv_Unicode]; - } - return NULL; -} - -/* Initialization */ -private int -pcsymbol_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_CLASS_COMMAND_ARGS('*', 'c', 'R', "Symbol Set ID Code", - pcl_symbol_set_id_code, - pca_neg_error|pca_big_error) - DEFINE_CLASS_COMMAND_ARGS('(', 'f', 'W', "Define Symbol Set", - pcl_define_symbol_set, pca_bytes) - DEFINE_CLASS_COMMAND_ARGS('*', 'c', 'S', "Symbol Set Control", - pcl_symbol_set_control, - pca_neg_ignore|pca_big_ignore) - return 0; -} - -private void -pcsymbol_do_reset(pcl_state_t *pcs, pcl_reset_type_t type) -{ - if ( type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_overlay) ) { - id_set_value(pcs->symbol_set_id, 0); - if ( type & pcl_reset_initial ) { - /* Don't set a parent relationship from soft to built-in - * symbol sets. Although it is arguably useful, it's - * better to avoid it and keep anyone who's looking at the - * soft symbol sets from mucking up the permanent ones. */ - pl_dict_init(&pcs->soft_symbol_sets, pcs->memory, - pcsymbol_dict_value_free); - pl_dict_init(&pcs->built_in_symbol_sets, pcs->memory, - pcsymbol_dict_value_free); - /* NB. Symbol sets are require for RTL/HPGL/2 mode for - * stickfonts but we shouldn't load all of them. */ - if ( pcl_load_built_in_symbol_sets(pcs) < 0 ) - dprintf("Internal error, no symbol sets found"); - } - else if ( type & pcl_reset_printer ) { - pcl_args_t args; - arg_set_uint(&args, 1); /* delete temporary symbol sets */ - pcl_symbol_set_control(&args, pcs); - } - } - if ( type & pcl_reset_permanent ) { - pl_dict_release(&pcs->soft_symbol_sets); - pl_dict_release(&pcs->built_in_symbol_sets); - } -} - -private int -pcsymbol_do_copy(pcl_state_t *psaved, const pcl_state_t *pcs, - pcl_copy_operation_t operation) -{ if ( operation & pcl_copy_after ) - { /* Don't restore the downloaded symbol set dictionary. */ - psaved->built_in_symbol_sets = pcs->built_in_symbol_sets; - } - return 0; -} - -const pcl_init_t pcsymbol_init = { - pcsymbol_do_registration, pcsymbol_do_reset, pcsymbol_do_copy -}; diff --git a/pcl/pcsymbol.h b/pcl/pcsymbol.h deleted file mode 100644 index 8363fdb35..000000000 --- a/pcl/pcsymbol.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcsymbol.h */ -/* Definitions for PCL5 symbol sets */ - -#ifndef pcsymbol_INCLUDED -# define pcsymbol_INCLUDED - -#include "plsymbol.h" - -/* The structure for symbol sets (fig 10-1, p. 10-5 of PCL5 TRM) is in - * plsymbol.h, as a "symbol map". A symbol map describes the mapping - * from one symbol set to one glyph vocabulary. A symbol set may comprise - * multiple maps (currently at most two, one each for MSL and Unicode). - * We want a separate dictionary of symbol sets because there are various - * operations performed per symbol set (affecting all mappings). */ - -typedef struct pcl_symbol_set_s { - pcl_data_storage_t storage; - pl_symbol_map_t *maps[plgv_next]; /* (these may be NULL) */ -} pcl_symbol_set_t; - -/* Check whether a symbol map's character requirements are supported by a - * font's character complement. */ -bool pcl_check_symbol_support(P2(const byte *symset_req, - const byte *font_sup)); - -/* Find a symbol map, given its ID and glyph vocabulary. */ -pl_symbol_map_t *pcl_find_symbol_map(P3(const pcl_state_t *pcs, - const byte *id, - pl_glyph_vocabulary_t gv)); - -#endif /* pcsymbol_INCLUDED */ diff --git a/pcl/pctext.c b/pcl/pctext.c deleted file mode 100644 index 805cc460f..000000000 --- a/pcl/pctext.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pctext.c - PCL5 text printing commands */ - -#include "math_.h" -#include "gx.h" -#include "gsimage.h" -#include "plvalue.h" -#include "plvocab.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcdraw.h" -#include "pcfont.h" -#include "pcursor.h" -#include "gdebug.h" -#include "gscoord.h" -#include "gsline.h" -#include "gspaint.h" -#include "gspath.h" -#include "gspath2.h" -#include "gsrop.h" -#include "gsstate.h" -#include "gxchar.h" -#include "gxfont.h" /* for setting next_char proc */ -#include "gxstate.h" - -/* Define the text parsing methods. */ -private const pcl_text_parsing_method_t pcl_tpm_0 = pcl_tpm_0_data, - pcl_tpm_21 = pcl_tpm_21_data, - pcl_tpm_31 = pcl_tpm_31_data, - pcl_tpm_38 = pcl_tpm_38_data; - -/* pseudo-"dots" (actually 1/300" units) used in underline only */ -#define dots(n) ((float)(7200 / 300 * n)) - - -/* - * Get next character procedure, to be passed to the graphic library font - * machinery. Always assumes two bytes are in the string. - */ - private int -get_gs_next_char( - gs_text_enum_t * penum, - gs_char * pchr, - gs_glyph * pglyph -) -{ - const byte * pb = penum->text.data.bytes; - if ( (penum->index / 2 ) == penum->text.size ) - return 2; - *pglyph = gs_no_glyph; - *pchr = (((uint)pb[penum->index]) << 8) + pb[penum->index+1]; - penum->index += 2; - return 0; -} - -/* - * Install a font in the graphic state. - */ - private void -set_gs_font( - pcl_state_t * pcs -) -{ - gs_font * pfont = (gs_font *)pcs->font->pfont; - - pfont->procs.next_char_glyph = get_gs_next_char; - gs_setfont(pcs->pgs, pfont); -} - -/* - * Mapping via symbol sets. Note that this applies only to unbound fonts. - */ - private gs_char -map_symbol( - const pl_font_t * pfont, - const pl_symbol_map_t * psm, - gs_char chr -) -{ - uint first_code, last_code; - - /* - * If there is no symbol map we assume the the character - * implicitly indexes the font. - */ - if (psm == 0) { - if ( (pfont->scaling_technology == plfst_TrueType) && - (pfont->storage == pcds_internal) ) - return chr + 0xf000; - return chr; - } - - first_code = pl_get_uint16(psm->first_code); - last_code = pl_get_uint16(psm->last_code); - - /* - * If chr is double-byte but the symbol map is only single-byte, - * just return chr (it is not clear this make any sense - jan, I - * agree - henry). - */ - if ((chr < first_code) || (chr > last_code)) - return ((last_code <= 0xff) && (chr > 0xff) ? chr : 0xffff); - else { - pl_glyph_vocabulary_t fgv = /* font glyph vocabulary */ - (pl_glyph_vocabulary_t)(~pfont->character_complement[7] & 07); - gs_char code = psm->codes[chr - first_code]; - - /* simple common case - the glyph vocabs match */ - if ( pl_symbol_map_vocabulary(psm) == fgv ) - return code; - /* font wants unicode and we have mapped an msl symbol set */ - if ( ( pl_symbol_map_vocabulary(psm) == plgv_MSL ) && - ( fgv == plgv_Unicode ) ) { - if ( psm->mapping_type != PLGV_M2U_MAPPING ) - /* font selection should not have given us this */ - return_error(gs_error_invalidfont); - else - return pl_map_MSL_to_Unicode(code, - (psm->id[0] << 8) + psm->id[1]); - } - /* font wants msl coding we have mapped unicode */ - if ( ( pl_symbol_map_vocabulary(psm) == plgv_Unicode ) && - ( fgv == plgv_MSL ) ) { - if ( psm->mapping_type != PLGV_U2M_MAPPING ) - /* symbol set doesn't support the mapping - should not happen */ - return_error(gs_error_invalidfont); - else - return pl_map_Unicode_to_MSL(code, - (psm->id[0] << 8) + psm->id[1]); - } else - return 0xffff; - } -} - -/* - * Check if a character code is considered "printable" by given symbol set. - */ - private bool -is_printable( - const pl_symbol_map_t * psm, - gs_char chr -) -{ - if ((psm == 0) || (psm->type >= 2)) - return true; - else if (psm->type == 1) - chr &= 0x7f; - return (chr >= ' ') && (chr <= '\177'); -} - -/* - * Retrieve the next character identifier from a string. - * - * Both the string pointer and the length are modified. - * - * The final operand is true if the text was provided via the literal - * (transparent) text command: ESC & p <nbytes> X. This distinction is - * important for characters that are not considered printable by the - * current symbol set. Normally, such characters are ignored. But if they - * resulted from the literal (transparent) text command, they are handled as - * spaces. Characters that are mapped by the symbol set but are not in a font - * are always dealt with as space characters. - * - * The special handling provided for the character code 32 below is not, - * in fact, correct. PCL fonts may map non-space characters to code 32, and - * if this is done no special handling is provided for this code; in PCL, - * a space character is a character not present in the font. Unfortunately, - * some of the resident fonts used have explicit space characters, and to - * handle the hmi properly when these fonts are used, this code must handle - * fonts that have actual characters at code 32 improperly. - * - * Returns 0 on success, 2 if the string is exhausted. Note that it is not an - * error for the string to end in the middle of a 2-byte sequence. - */ - private int -get_next_char( - pcl_state_t * pcs, - const byte ** ppb, - uint * plen, - gs_char * pchr, - bool * pis_space, - bool literal, - gs_point * pwidth -) -{ - const byte * pb = *ppb; - int len = *plen; - gs_char chr; - if (len <= 0) - return 2; - chr = *pb++; - len--; - if (pcl_char_is_2_byte(chr, pcs->text_parsing_method) && (len > 0)) { - chr = (chr << 8) + *pb++; - len--; - *pis_space = false; - } else - *pis_space = (chr == ' ' && pcs->font->storage == pcds_internal); - *ppb = pb; - *plen = len; - - /* check if the code is considered "printable" in the current symbol set */ - if (!is_printable(pcs->map, chr)) { - *pis_space = literal; - *pchr = 0xffff; - return 0; - } - - /* map the symbol. If it fails to map, quit now */ - chr = map_symbol(pcs->font, pcs->map, chr); - *pchr = chr; - if (chr == 0xffff) { - *pis_space = true; - return 0; - } - - /* check if the character is in the font and get the character - width at the same time */ - { - const gs_matrix identity_matrix = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }; - if (pl_font_char_width(pcs->font, pcs->map, &identity_matrix, chr, pwidth) == 0) - return 0; - } - /* - * The character is not in the font. - */ - *pis_space = true; - *pchr = 0xffff; - return 0; -} - -/* - * Draw the foreground of a character. For transparent text this is the only - * part that must be drawn. - */ - private int -show_char_foreground( - const pcl_state_t * pcs, - const char * pbuff -) -{ - gs_text_enum_t * penum; - int code = gs_show_begin(pcs->pgs, pbuff, 1, pcs->memory, &penum); - - if (code >= 0) - code = gs_text_process(penum); - gs_text_release(penum, "show_char_foreground"); - return code; -} - -/* - * draw the opaque background of a character. - * - * In the graphic library, characters are masks, hence they are always - * transparent. Not so in PCL, where characters may be either opaque or - * transparent. - * - * To deal with this dichotomy, opaque characters are rendered as a pair of - * masks. One is the normal character mask; the other is the bounding box of - * the character less the character itself. - * - * The manner in which the second mask is formed varies based on the font type. - * For bitmap fonts, the inverse mask is formed as an imagemask object, with - * inverted polarity. For scalable fonts (which have only provided a path), - * the inverse is formed by adding the bounding box rectangle as a path to - * the character path, and using eofill on the resultant path. - * - * Special handling is required to achieve the desired raster operation on the - * "background" mask. From the point of view of the graphic library, the - * background mask is a normal mask, and hence would utiltise the S = 0 - * portion of the current logical operation (recall that rop's are expressed - * in an additive sense). The desired effect is, however, the S = 1 portion - * of the current rop, so the current rop must be inverted in the sense of the - * source to achive the desired result. In principle, the S = 1 porition of - * the background rop should be set to the no-op rop, but this is not necessary - * as the source is a mask. - * - * An additional complication arises from the specification provided by HP for - * handling the source opaque, pattern transparent situation. In this case, - * the pattern affects only for the foreground pixels of the source; the back- - * ground must be rendered as a solid, opaque white. - */ - private int -show_char_background( - pcl_state_t * pcs, - const char * pbuff -) -{ - gs_text_enum_t * penum; - gs_state * pgs = pcs->pgs; - gs_rop3_t rop = (gs_rop3_t)(pcs->logical_op); - const pl_font_t * plfont = pcs->font; - gs_font * pfont = plfont->pfont; - gs_point pt; - int code = 0; - - /* save the graphic state and set the background raster operation */ - pcl_gsave(pcs); - if (pcs->pattern_transparent) - pcl_set_drawing_color(pcs, pcl_pattern_solid_white, 0, false); - gs_setrasterop(pgs, (gs_rop3_t)rop3_know_S_1((int)rop)); - gs_currentpoint(pgs, &pt); - - if (plfont->scaling_technology == plfst_bitmap) { - gs_char chr = (((uint)pbuff[0]) << 8) + pbuff[1]; - gs_glyph glyph = pfont->procs.encode_char(pfont, chr, gs_no_glyph); - const byte * cdata = pl_font_lookup_glyph(plfont, glyph)->data; - int nbytes; - uint used; - gs_image_enum * pen = 0; - gs_image1_t mask; - - /* empty characters have no background */ - if (cdata == 0) { - pcl_grestore(pcs); - return 0; - } - - /* allocate the image enumerator */ - pen = gs_image_enum_alloc(gs_state_memory(pgs), "bitmap font background"); - if (pen == 0) { - pcl_grestore(pcs); - return e_Memory; - } - - /* translate the origin to the ul corner of the image */ - pt.x += (float)pl_get_int16(cdata + 6); - pt.y -= (float)pl_get_int16(cdata + 8); - gs_translate(pgs, pt.x, pt.y); - - /* set up and render the image mask */ - gs_image_t_init_mask(&mask, false); - mask.adjust = false; - mask.Width = pl_get_uint16(cdata + 10); - mask.Height = pl_get_uint16(cdata + 12); - nbytes = ((mask.Width + 7) / 8) * mask.Height; - gs_image_init(pen, &mask, false, pgs); - code = gs_image_next(pen, cdata + 16, nbytes, &used); - - /* clean up */ - gs_image_cleanup(pen); - gs_free_object(gs_state_memory(pgs), pen, "bitmap font background"); - - } else { - gs_rect bbox; - - /* clear the path; start the new one from the current point */ - gs_newpath(pgs); - gs_moveto(pgs, pt.x, pt.y); - - /* get the character path */ - gs_charpath_begin(pgs, pbuff, 2, true, pcs->memory, &penum); - if ((code = gs_text_process(penum)) >= 0) { - - /* append the characters bounding box and use eofill */ - gs_pathbbox(pgs, &bbox); - gs_rectappend(pgs, &bbox, 1); - gs_eofill(pgs); - } - gs_text_release(penum, "show_char_background"); - } - - pcl_grestore(pcs); - return code; -} - -/* - * get the advance width. - */ - private floatp -pcl_get_width(pcl_state_t *pcs, gs_point *advance_vector, const gs_point *pscale, gs_char chr, bool is_space) -{ - pcl_font_selection_t * pfp = &(pcs->font_selection[pcs->font_selected]); - floatp width; - if (chr != 0xffff) { - if (!pfp->params.proportional_spacing || is_space) - width = pcl_hmi(pcs); - else { - if ( pcs->font->scaling_technology == plfst_TrueType ) { - floatp tmp; - tmp = pscale->x / (floatp)pcs->uom_cp + 0.5; - tmp -= fmod(tmp, (floatp)1.0); - tmp *= (floatp)pcs->uom_cp; - width = advance_vector->x * tmp; - } else - width = advance_vector->x * pscale->x; - } - } else if (is_space) - width = pcl_hmi(pcs); - else - width = 0.0; - /* round to nearest integral pcl units */ - width += (floatp)pcs->uom_cp / 2.0; - width -= fmod(width, (floatp)pcs->uom_cp); - return width; -} - -/* - * Show a string of characters. Provide a general purpose function - * that can be used in all cases (pcl_show_chars_slow) and a faster - * function (pcl_show_chars_fast) that can be used for most - * circumstances. The latter algorithm can print strings of - * characters the slow algorithm only prints one character at a time. - * - * As is the case for other parts of this code, this code is made more complex - * by the PostScript-centric nature of the the graphics library, and by a - * long standing flaw in the PostScript view of fonts. Specifically, the - * initial introduction of Encoding arrays into PostScript fonts, followed by - * composite font mechanism, very much confused the concepts of font and text - * parsing method. - * - * A font is an object which accepts a character identifier and returns a - * "rendering" of that character (which may be a bitmap, may be a path, may - * be an advance vector, or may be some combination of the above); it may also - * in some cases apply this rendering to the graphic state (which may include - * modifying the output). Whether or not a font caches or expects its client - * to handle caching is a separate issue; there are good areguments for either - * approach. - * - * A text parsing method is an object that accepts a character string and - * returns one or more character identifiers. A text parsing method is, in - * principle, completely independent of a font, though for historical reasons - * the two concepts are often linked at the application level. - * - * Because of the PostScript origins of the graphic library, its font interface - * handles both text parsing and rendering. To achieve flexibility, the client - * may provide a "get next character" procedure for the graphic library font - * machinery to work with, but this flexibility is not sufficient for PCL, as - * the latter potentially needs to perform additional operations on each - * character. Hence, PCL will not ask the font machiner to render more than - * one character at a time. - * - * Complicating this picture is the nature of memory management in the graphic - * library. The show class operators in PostScript generally take a string as - * an operand. PostScript strings have the "getinterval" property: one string - * may be part of another string. Hence strings cannot have headers. In a - * relocating memory systems, this implies that strings must be dealt with - * separately from other objects: they must be allocated as strings. In the - * case of PCL, this is not necessarily the case (see, for example, the case - * of transparent mode, below). - * - * The original implementation of this routine ignored this distinction and - * could, in principle, have failed if re-location was enabled. It was also - * rather hard to read, because it parsed the input string (at least) twice: - * once the find the character so that PCL-specific actions could be taken, - * then again via the font machiner. - * - * - * The final operand is true if the text was provided via the literal - * (transparent) text command: ESC & p <nbytes> X. This distinction is - * important for characters that are not mapped by the current symbol set. */ - - private int -pcl_show_chars_slow( - pcl_state_t * pcs, - const gs_point * pscale, - const byte * str, - uint size, - bool literal -) -{ - gs_state * pgs = pcs->pgs; - char buff[2]; - floatp rmargin = pcs->margins.right; - floatp page_size = pcs->xfm_state.pd_size.x; - bool opaque = !pcs->source_transparent; - bool wrap = pcs->end_of_line_wrap; - bool is_space = false; - bool use_rmargin = (pcs->cap.x <= rmargin); - gs_char chr; - int code = 0; - floatp width; - gs_point cpt; - gs_point advance_vector; - - cpt.x = pcs->cap.x; - cpt.y = pcs->cap.y; - while (get_next_char(pcs, &str, &size, &chr, &is_space, literal, &advance_vector) == 0) { - floatp tmp_x; - - /* check if a character was found */ - buff[0] = (chr >> 8); - buff[1] = (chr & 0xff); - /* round width to integral pcl current units */ - width = (pcl_get_width(pcs, &advance_vector, pscale, chr, is_space)); - /* - * Check for transitions of the left margin; this check is - * disabled if the immediately preceding character was a back-space. - * A move beyond the "right" logical page edge is also considered - * a margin transition. - * - * A little-known feature of PCL is the effect of the line-wrap - * command on the interpretation of the right margin. If line - * wrap is in effect, a transition of the left margin will cause - * a <cr><lf> operation BEFORE the current character is printed. If - * line-wrap is not in effect, a transition of the right margin will - * stop printing AFTER the current character is printed. - * - * A special case occurs in the non-wrap situation when the current - * position exactly equals the current margin. In that case, no - * character is printed. - */ - if (!pcs->last_was_BS) { - if (wrap) { - if ( (use_rmargin && (cpt.x + width > rmargin)) || - (cpt.x + width > page_size) ) { - pcl_do_CR(pcs); - pcl_do_LF(pcs); - cpt.x = pcs->cap.x; - cpt.y = pcs->cap.y; - use_rmargin = true; - } - } else { - if (use_rmargin && (cpt.x == rmargin)) - break; - else if (cpt.x >= page_size) { - cpt.x = page_size; - break; - } - } - } - - /* - * If the immediately preceding character was a BS, the code will - * center the current character on top of the preceding one. After - * the character is printed, the current point is returned to the - * prior point. - */ - tmp_x = cpt.x; - if (pcs->last_was_BS) - tmp_x += (pcs->last_width - width) / 2; - gs_moveto(pgs, tmp_x / pscale->x, cpt.y / pscale->y); - - if (chr != 0xffff) { - - /* if source is opaque, show and opaque background */ - if (opaque) - code = show_char_background(pcs, buff); - if (code >= 0) - code = show_char_foreground(pcs, buff); - if (code < 0) - break; - } - - /* - * Check again for the first character following a back-space. if - * this is the case, go back to the original position. - */ - if (pcs->last_was_BS) { - cpt.x += pcs->last_width; - pcs->last_was_BS = false; - } else - cpt.x += width; - - /* check for going beyond the margin if not wrapping */ - if (!wrap) { - if (use_rmargin && (cpt.x > rmargin)) { - cpt.x = rmargin; - break; - } else if (cpt.x >= page_size) { - cpt.x = page_size; - break; - } - } - } - - /* record the last width */ - pcs->last_width = width; - - /* update the current position */ - pcs->cap.x = cpt.x; - pcs->cap.y = cpt.y; - - return code; -} - - private int -pcl_show_chars_fast( - pcl_state_t * pcs, - const gs_point * pscale, - const byte * str, - uint size, - bool literal -) -{ - gs_state * pgs = pcs->pgs; - floatp rmargin = pcs->margins.right; - floatp page_size = pcs->xfm_state.pd_size.x; - bool is_space = false; - int code = 0; - gs_char chr; - floatp width; - gs_point cpt; - gs_point advance_vector; - char *xyshow_buffp; - float *xyshow_fvalsp; - int xyshow_index; - gs_text_enum_t *penum; - - cpt.x = pcs->cap.x; - cpt.y = pcs->cap.y; - xyshow_index = 0; - - /* allocate arrays of coordinates and buffer for xyshow. Note we - are really doing xshow, the y displacement is alway 0.0 but the - graphics library only has an interface for xyshow. */ - xyshow_fvalsp = (float *)gs_alloc_byte_array(pcs->memory, size, sizeof(float) * 2, "pcl_show_chars_fast"); - if ( xyshow_fvalsp == 0 ) - return_error(e_Memory); - xyshow_buffp = (char *)gs_alloc_byte_array(pcs->memory, size, sizeof(char) * 2, "pcl_show_chars_fast"); - if ( xyshow_buffp == 0 ) { - gs_free_object(pcs->memory, xyshow_fvalsp, "pcl_show_chars_fast" ); - return_error(e_Memory); - } - - while (get_next_char(pcs, &str, &size, &chr, &is_space, literal, &advance_vector) == 0) { - /* check if a character was found. For an undefined character - backup the index to accumulate hmi in the last characters */ - xyshow_buffp[xyshow_index * 2] = (chr >> 8); - xyshow_buffp[xyshow_index * 2 + 1] = (chr & 0xff); - /* round width to integral pcl current units */ - width = (pcl_get_width(pcs, &advance_vector, pscale, chr, is_space)); - /* - * A special case occurs in the non-wrap situation when the current - * position exactly equals the current margin. In that case, no - * character is printed. - */ - if (cpt.x == rmargin) - break; - else if (cpt.x >= page_size) { - cpt.x = page_size; - break; - } - - /* store the x displacement - accumulate the displacement for - undefined characters which pcl treats as spaces. We don't - have to set the y displacement at position (xyshow_index * - 2 + 1) because it is always zero and the entire array was - initialized to zero above. */ - xyshow_fvalsp[xyshow_index * 2] = (width / pscale->x); - xyshow_fvalsp[xyshow_index * 2 + 1] = 0.0; - xyshow_index++; - - /* the pcl cap moves the width of the character */ - cpt.x += width; - /* check for crossing rmargin or exceeding page boundary */ - if (cpt.x > rmargin) { - cpt.x = rmargin; - break; - } else if (cpt.x >= page_size) { - cpt.x = page_size; - break; - } - } - /* finally move back to the original point, the start of the string */ - gs_moveto(pgs, pcs->cap.x / pscale->x, pcs->cap.y / pscale->y); - - /* start the "show" - we pass the same array of floats for - parameters 4 and 5 - the graphics library does the right thing */ - code = gs_xyshow_begin(pcs->pgs, xyshow_buffp, xyshow_index, - xyshow_fvalsp, xyshow_fvalsp, xyshow_index * 2, - pcs->memory, &penum); - if (code >= 0) - code = gs_text_process(penum); - gs_text_release(penum, "pcl_show_chars_fast"); - /* record the last width */ - pcs->last_width = width; - /* update the current position in pcl's state */ - pcs->cap.x = cpt.x; - pcs->cap.y = cpt.y; - /* free everything */ - gs_free_object(pcs->memory, xyshow_fvalsp, "pcl_show_chars_fast" ); - gs_free_object(pcs->memory, xyshow_buffp, "pcl_show_chars_fast" ); - return code; -} - -/* - * Set up to handle a string of text. - * - * The final operand is true if the text was provided via the literal - * (transparent) text command: ESC & p <nbytes> X. This distinction is - * important for characters that are not mapped by the current symbol set. - */ - int -pcl_text( - const byte * str, - uint size, - pcl_state_t * pcs, - bool literal -) -{ - gs_state * pgs = pcs->pgs; - gs_matrix user_ctm; - gs_point scale; - int scale_sign; - int code; - - /* rtl files can have text in them - we don't print any characters - in rtl */ - if (pcs->personality == rtl) - return 0; - /* set up the current font and HMI */ - if ((pcs->font == 0) && ((code = pcl_recompute_font(pcs)) < 0)) - return code; - - /* set up the graphic state */ - code = pcl_set_drawing_color( pcs, - pcs->pattern_type, - pcs->current_pattern_id, - false - ); - if (code >= 0) - code = pcl_set_graphics_state(pcs); - if (code < 0) - return code; - set_gs_font(pcs); - - /* set up the font transformation */ - if (pcs->font->scaling_technology == plfst_bitmap) { - scale.x = pcl_coord_scale / pcs->font->resolution.x; - scale.y = pcl_coord_scale / pcs->font->resolution.y; - - /* - * Bitmap fonts use an inverted coordinate system, - * the same as the usual PCL system. - */ - scale_sign = 1; - } else { - /* - * Outline fonts are 1-point; the font height is given in - * (quarter-)points. However, if the font is fixed-width, - * it must be scaled by pitch, not by height, relative to - * the nominal pitch of the outline. - */ - pcl_font_selection_t * pfp = &pcs->font_selection[pcs->font_selected]; - - if (pfp->params.proportional_spacing) - scale.x = scale.y = pfp->params.height_4ths - * 0.25 * inch2coord(1.0 / 72.0); - else - scale.x = scale.y = pl_fp_pitch_cp(&pfp->params) - * (100.0 / pl_fp_pitch_cp(&pfp->font->params)) - * inch2coord(1.0 / 7200.0); - /* - * Scalable fonts use an upright coordinate system, - * the opposite from the usual PCL system. - */ - scale_sign = -1; - } - - /* - * If floating underline is on, since we're about to print a real - * character, track the best-underline position. - * XXX Until we have the font's design value for underline position, - * use 0.2 em. This is enough to almost clear descenders in typical - * fonts; it's also large enough for us to check that the mechanism - * works. - */ - if (pcs->underline_enabled && pcs->underline_floating) { - float yu = scale.y / 5.0; - - if (yu > pcs->underline_position) - pcs->underline_position = yu; - } - - /* - * XXX I'm using the more general, slower approach rather than - * just multiplying/dividing by scale factors, in order to keep it - * correct through orientation changes. Various parts of this should - * be cleaned up when performance time rolls around. - */ - gs_currentmatrix(pgs, &user_ctm); - - /* possibly invert text because HP coordinate system is inverted */ - scale.y *= scale_sign; - gs_scale(pgs, scale.x, scale.y); - /* Print remaining characters, restore the ctm */ - if ( (pcs->cap.x <= pcs->margins.right) && - (pcs->source_transparent) && - (!pcs->last_was_BS) && - (!pcs->end_of_line_wrap) ) - code = pcl_show_chars_fast(pcs, &scale, str, size, literal); - else - code = pcl_show_chars_slow(pcs, &scale, str, size, literal); - gs_setmatrix(pgs, &user_ctm); - if (code > 0) /* shouldn't happen */ - code = gs_note_error(gs_error_invalidfont); - - return code; -} - -/* - * Individual non-command/control characters - */ - int -pcl_plain_char( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - return pcl_text((const byte *)&(pargs->command), 1, pcs, false); -} - -/* - * draw underline up to current point, adjust status - */ - void -pcl_do_underline( - pcl_state_t * pcs -) -{ - if (pcs->underline_start.x != pcs->cap.x) { - gs_state * pgs = pcs->pgs; - float y = pcs->underline_start.y + pcs->underline_position; - int code; - - code = pcl_set_drawing_color( pcs, - pcs->pattern_type, - pcs->current_pattern_id, - false - ); - if (code >= 0) - code = pcl_set_graphics_state(pcs); - if (code < 0) - return; - - /* - * TRM says (8-34) that underline is 3 dots. In a victory for - * common sense, it's not. Rather, it's 0.01" (which *is* 3 dots - * at 300 dpi only) - */ - gs_setlinewidth(pgs, dots(3)); - gs_moveto(pgs, pcs->underline_start.x, y); - gs_lineto(pgs, pcs->cap.x, y); - gs_stroke(pgs); - } - - /* - * Fixed underline is 5 "dots" (actually 5/300") down. Floating - * will be determined on the fly. - */ - pcs->underline_start = pcs->cap; - pcs->underline_position = pcs->underline_floating ? 0.0 : dots(5); -} - -/* ------ Commands ------ */ - -/* - * ESC & p <count> X - * - * Unparsed text command - */ - private int -pcl_transparent_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - return pcl_text(arg_data(pargs), uint_arg(pargs), pcs, true); -} - -/* - * ESC & d <0|3> D - * - * Enable floating or fixed-depth underlining. - * - * NB: If underlining is already enabled, this command is ignored. Underlining - * must be specifically disabled to switch from fixed to floating. - */ - private int -pcl_enable_underline( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int type = int_arg(pargs); - - /* ignore command if underlining is already enabled */ - if (pcs->underline_enabled) - return 0; - - if (type == 0) { - pcs->underline_floating = false; - pcs->underline_position = dots(5); - } else if (type == 3) { - pcs->underline_floating = true; - pcs->underline_position = 0.0; - } else - return 0; - - pcs->underline_enabled = true; - pcs->underline_start = pcs->cap; - return 0; -} - -/* - * ESC & d @ - * - * Disable underlining - */ - private int -pcl_disable_underline( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcl_break_underline(pcs); - pcs->underline_enabled = false; - return 0; -} - -/* (From PCL5 Comparison Guide, p. 1-56) */ - -/* - * ESC & t <method> P - * - * Select the text parsing method. - */ - private int -pcl_text_parsing_method( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - switch (int_arg(pargs)) { - - case 0: case 1: - pcs->text_parsing_method = &pcl_tpm_0; - break; - - case 21: - pcs->text_parsing_method = &pcl_tpm_21; - break; - - case 31: - pcs->text_parsing_method = &pcl_tpm_31; - break; - - case 38: - pcs->text_parsing_method = &pcl_tpm_38; - break; - - default: - return e_Range; - } - - return 0; -} - -/* (From PCL5 Comparison Guide, p. 1-57) */ - -/* - * ESC & c <direction> T - * - * Set the text path direction - not yet implemented. - */ - private int -pcl_text_path_direction( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int direction = int_arg(pargs); - - switch (direction) { - - case 0: - case -1: - break; - - default: - return e_Range; - } - - pcs->text_path = direction; - return e_Unimplemented; -} - -/* ------ Initialization ------ */ - private int -pctext_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * mem -) -{ - /* Register commands */ - DEFINE_CONTROL(0, "(plain char)", pcl_plain_char); - - DEFINE_CLASS('&') - { - 'p', 'X', - PCL_COMMAND("Transparent Mode", pcl_transparent_mode, pca_bytes) - }, - { - 'd', 'D', - PCL_COMMAND( "Enable Underline", - pcl_enable_underline, - pca_neg_ignore | pca_big_ignore - ) - }, - { - 'd', '@', - PCL_COMMAND( "Disable Underline", - pcl_disable_underline, - pca_neg_ignore | pca_big_ignore - ) - }, - END_CLASS - - DEFINE_CLASS('&') - { - 't', 'P', - PCL_COMMAND( "Text Parsing Method", - pcl_text_parsing_method, - pca_neg_error | pca_big_error - ) - }, - { - 'c', 'T', - PCL_COMMAND( "Text Path Direction", - pcl_text_path_direction, - pca_neg_ok | pca_big_error - ) - }, - END_CLASS - - DEFINE_CONTROL(1, "(plain char)", pcl_plain_char); /* default "command" */ - - return 0; -} - - private void -pctext_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_printer - | pcl_reset_overlay ); - - if ((type & mask) != 0) { - pcs->underline_enabled = false; - pcs->last_was_BS = false; - pcs->last_width = inch2coord(1.0 / 10.0); - pcs->text_parsing_method = &pcl_tpm_0; - pcs->text_path = 0; - } -} - -const pcl_init_t pctext_init = { pctext_do_registration, pctext_do_reset, 0 }; diff --git a/pcl/pctop.c b/pcl/pctop.c deleted file mode 100644 index 3e3c143fe..000000000 --- a/pcl/pctop.c +++ /dev/null @@ -1,631 +0,0 @@ -/* Portions Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pctop.c - PCL5c top-level API */ - -/* - NOTICE from JD: There is still some work to do pending improved PCL - de/init. Those places are commented and flagged with @@@. The - following documents some of those limitations: - - The remaining de-init issues fall into 3 categories, in order of urgency: - i) parser state cleanup after unexpected input stream termination - ii) de-init to enable device-specific re-init when switching devices - iii) complete de-init to recover all memory allocated to PCL - - Issue (i): There is currently no way to reset the state of PCL in - mid-flight, say if there's an unexpected EOF and the interpreter is - currently defining a macro or a font (this is not an exhaustive list - of trouble spots). What is needed is a new PCL function which specifically - does the appropriate resets to "reasonably" start processing a new stream - of data. HP does not document just how far such implied resets - go -- probably not as far as an <esc>E reset does -- so some experiments - with HP hardware will be necessary. - - Issue (ii), There is a class of resets which are currently done by calling - pcl_do_resets(pcs, pcl_reset_initial). A device must have been selected into - the associated gstate before those resets are invoked, since some of the reset - actions are device-specific. The upshot of this arrangement is that some reset - actions must be carried out again when a new device is selected into the - interpreter. Unfortunately, the two above functions can only be called once - at the beginning of the interpreter's lifetime, and there are no functions - to terminate the interpreter. - - There are 4 possible ways modify PCL to fix the problem: a) make the functions - in question callable multiple times, b) create special re-init functions that - are callable multiple times, c) create de-init functions that are a mirror - image of the initial resets; to re-init, one would de-init, then do initial - resets again, d) make it possible to de-init the entire interpreter; one would - destroy the interpreter, then start another. According to Henry at Artifex, - c & d would have some performance hits, though probably acceptable when - switching devices. Options a & b are interchangeable and don't suffer from the - same performance hits, but don't help with issue (iii), below. - - Issue (iii): PCL does two layers of 1-time init at startup, both of - which allocate memory: I) the "static" inits called by the various - pcl_init_table[]->do_init's, II) the above-mentioned pcl_do_resets - (pcs, pcl_reset_initial). In both cases, no corresponding function - exists to free the allocated memory, so reallocation functions are - needed. If resolution (c) to issue (ii) is adopted, you only need a - function to undo (I). Otherwise, you need a complete de-init - function(s). My initial feeling is that it'd be quickest to - implement resolution (c) to issue (ii), and resolve issue (iii) by - implementing a function to undo (I). -*/ - -#include "malloc_.h" -#include "math_.h" -#include "memory_.h" -#include "stdio_.h" -#include "scommon.h" /* for pparse.h */ -#include "pcparse.h" -#include "pcstate.h" -#include "pldebug.h" -#include "gdebug.h" -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsrop.h" -#include "gspaint.h" /* for gs_erasepage */ -#include "gsstate.h" -#include "gxalloc.h" -#include "gxdevice.h" -#include "gxstate.h" -#include "gdevbbox.h" -#include "pclver.h" -#include "pjparse.h" -#include "pltop.h" -#include "pctop.h" - -/* Define the table of pointers to initialization data. */ -#define init_(init) extern const pcl_init_t init; -#include "pconfig.h" -#undef init_ - -const pcl_init_t * pcl_init_table[] = { -#define init_(init) &init, -#include "pconfig.h" -#undef init_ - 0 -}; - - - -/* Built-in symbol set initialization procedure */ -private int pcl_end_page_top(P3(pcl_state_t *pcs, int num_copies, int flush)); - - -/* - * Define the gstate client procedures. - */ - private void * -pcl_gstate_client_alloc( - gs_memory_t * mem -) -{ - /* - * We don't want to allocate anything here, but we don't have any way - * to say we want to share the client data. Since this will only ever - * be called once, return something random. - */ - return (void *)1; -} - -/* - * set and get for pcl's target device. This is the device at the end - * of the pipeline. - */ - void -pcl_set_target_device(pcl_state_t *pcs, gx_device *pdev) -{ - pcs->ptarget_device = pdev; -} - - gx_device * -pcl_get_target_device(pcl_state_t *pcs) -{ - return pcs->ptarget_device; -} - - private int -pcl_gstate_client_copy_for( - void * to, - void * from, - gs_state_copy_reason_t reason -) -{ - return 0; -} - - private void -pcl_gstate_client_free( - void * old, - gs_memory_t * mem -) -{} - -private const gs_state_client_procs pcl_gstate_procs = { - pcl_gstate_client_alloc, - 0, /* copy -- superseded by copy_for */ - pcl_gstate_client_free, - pcl_gstate_client_copy_for -}; - -/************************************************************/ -/******** Language wrapper implementation (see pltop.h) *****/ -/************************************************************/ - -/* - * PCL interpeter: derived from pl_interp_t - */ -typedef struct pcl_interp_s { - pl_interp_t pl; /* common part: must be first */ - gs_memory_t *memory; /* memory allocator to use */ -} pcl_interp_t; - -/* - * PCL interpreter instance: derived from pl_interp_instance_t - */ -typedef struct pcl_interp_instance_s { - pl_interp_instance_t pl; /* common part: must be first */ - gs_memory_t *memory; /* memory allocator to use */ - pcl_state_t pcs; /* pcl state */ - pcl_parser_state_t pst; /* parser state */ - gx_device_bbox *bbox_device; /* device used to detect blank pages */ - pl_page_action_t pre_page_action; /* action before page out */ - void *pre_page_closure; /* closure to call pre_page_action with */ - pl_page_action_t post_page_action; /* action before page out */ - void *post_page_closure;/* closure to call post_page_action with */ -} pcl_interp_instance_t; - - -/* Get implemtation's characteristics */ -const pl_interp_characteristics_t * /* always returns a descriptor */ -pcl_impl_characteristics( - const pl_interp_implementation_t *impl /* implementation of interpereter to alloc */ -) -{ - static pl_interp_characteristics_t pcl_characteristics = { - "PCL5", - "Artifex", - PCLVERSION, - PCLBUILDDATE, - 17 /* size of min buffer == sizeof UEL */ - }; - return &pcl_characteristics; -} - -/* Do static init of PCL interpreter, since there's nothing to allocate */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_allocate_interp( - pl_interp_t **interp, /* RETURNS abstract interpreter struct */ - const pl_interp_implementation_t *impl, /* implementation of interpereter to alloc */ - gs_memory_t *mem /* allocator to allocate interp from */ -) -{ - static pcl_interp_t pi; /* there's only one interpreter possible, so static */ - - /* There's only one possible PCL interp, so return the static */ - pi.memory = mem; - *interp = (pl_interp_t *)π - return 0; /* success */ -} - -/* Do per-instance interpreter allocation/init. No device is set yet */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_allocate_interp_instance( - pl_interp_instance_t **instance, /* RETURNS instance struct */ - pl_interp_t *interp, /* dummy interpreter */ - gs_memory_t *mem /* allocator to allocate instance from */ -) -{ - /* Allocate everything up front */ - pcl_interp_instance_t *pcli /****** SHOULD HAVE A STRUCT DESCRIPTOR ******/ - = (pcl_interp_instance_t *)gs_alloc_bytes( mem, - sizeof(pcl_interp_instance_t), - "pcl_allocate_interp_instance(pcl_interp_instance_t)" - ); - gx_device_bbox *bbox = gs_alloc_struct_immovable( - mem, - gx_device_bbox, - &st_device_bbox, - "pcl_allocate_interp_intance(bbox device)" - ); - gs_state *pgs = gs_state_alloc(mem); - - /* If allocation error, deallocate & return */ - if (!pcli || !bbox || !pgs) { - if (!pcli) - gs_free_object(mem, pcli, "pcl_allocate_interp_instance(pcl_interp_instance_t)"); - if (!bbox) - gs_free_object(mem, bbox, "pcl_allocate_interp_intance(bbox device)"); - if (!pgs) - gs_state_free(pgs); - return gs_error_VMerror; - } - - /* Setup pointers to allocated mem within instance */ - pcli->bbox_device = bbox; - pcli->memory = mem; - - /* initialize personality here - NB this needs to be associated - with the language option. */ - pcli->pcs.personality = pcl5e; - /* pcli->pcs.personality = rtl; */ - - /* zero-init pre/post page actions for now */ - pcli->pre_page_action = 0; - pcli->post_page_action = 0; - - /* General init of pcl_state */ - pcl_init_state(&pcli->pcs, mem); - pcli->pcs.client_data = pcli; - pcli->pcs.pgs = pgs; - /* provide an end page procedure */ - pcli->pcs.end_page = pcl_end_page_top; - /* Init gstate to point to pcl state */ - gs_state_set_client(pgs, &pcli->pcs, &pcl_gstate_procs); - /* register commands */ - { - int code = pcl_do_registrations(&pcli->pcs, &pcli->pst); - if ( code < 0 ) - return(code); - } - - /* Return success */ - *instance = (pl_interp_instance_t *)pcli; - return 0; -} - -/* Set a client language into an interperter instance */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_set_client_instance( - pl_interp_instance_t *instance, /* interp instance to use */ - pl_interp_instance_t *client /* client to set */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - pcli->pcs.pjls = client; - return 0; -} - -/* Set an interpreter instance's pre-page action */ -private int /* ret 0 ok, else -ve err */ -pcl_impl_set_pre_page_action( - pl_interp_instance_t *instance, /* interp instance to use */ - pl_page_action_t action, /* action to execute (rets 1 to abort w/o err) */ - void *closure /* closure to call action with */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - pcli->pre_page_action = action; - pcli->pre_page_closure = closure; - return 0; -} - -/* Set an interpreter instance's post-page action */ -private int /* ret 0 ok, else -ve err */ -pcl_impl_set_post_page_action( - pl_interp_instance_t *instance, /* interp instance to use */ - pl_page_action_t action, /* action to execute */ - void *closure /* closure to call action with */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - pcli->post_page_action = action; - pcli->post_page_closure = closure; - return 0; -} - -/* Set a device into an interperter instance */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_set_device( - pl_interp_instance_t *instance, /* interp instance to use */ - gx_device *device /* device to set (open or closed) */ -) -{ - int code; - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - enum {Sbegin, Ssetdevice, Sgsave1, Serase, Sreset, Sload, Sgsave2, Sdone} stage; - - /* Init the bbox device & wrap it around the real device */ - stage = Sbegin; - gx_device_bbox_init(pcli->bbox_device, device); - rc_increment(pcli->bbox_device); /* prevent refcnt-delete from deleting this */ - - /* Set the device into the pcl_state & gstate */ - stage = Ssetdevice; - pcl_set_target_device(&pcli->pcs, device); - code = gs_setdevice_no_erase(pcli->pcs.pgs, (gx_device *)pcli->bbox_device); - if (code < 0 ) /* can't erase yet */ - goto pisdEnd; - - /* Save a gstate with the original device == bbox config */ - stage = Sgsave1; - if ( (code = gs_gsave(pcli->pcs.pgs)) < 0 ) - goto pisdEnd; - stage = Serase; - if ( (code = gs_erasepage(pcli->pcs.pgs)) < 0 ) - goto pisdEnd; - - /* Do inits of gstate that may be reset by setdevice */ - /* PCL no longer uses the graphic library transparency mechanism */ - gs_setsourcetransparent(pcli->pcs.pgs, false); - gs_settexturetransparent(pcli->pcs.pgs, false); - gs_setaccuratecurves(pcli->pcs.pgs, true); /* All H-P languages want accurate curves. */ - - /* Do device-dependent pcl inits */ - /* These resets will not clear any "permanent" storage (fonts, macros) */ - /* One of these resets will also install an extra color-mapper device */ -/*@@@there is a potential problem because mem from resets is not dealloc'd */ - stage = Sreset; - /*@@@remove color mapper in dnit (think should be in PCL d/nit code)? */ - if ((code = pcl_do_resets(&pcli->pcs, pcl_reset_initial)) < 0 ) - goto pisdEnd; -/*@@@ possibly remove sload - loading symbol set should be part of reset process. */ - stage = Sload; - - /* provide a PCL graphic state we can return to */ - stage = Sgsave2; - if ( (code = pcl_gsave(&pcli->pcs)) < 0 ) - goto pisdEnd; - stage = Sdone; /* success */ - - /* Unwind any errors */ -pisdEnd: - switch (stage) { - case Sdone: /* don't undo success */ - break; - - case Sgsave2: /* 2nd gsave failed */ - /*@@@ unload built-in sym sets */ - /* fall thru to next */ - - case Sload: /* load_built_in_symbol_sets failed */ - /*@@@ undo do_resets */ - /* fall thru to next */ - - case Sreset: /* pcl_do_resets failed */ - case Serase: /* gs_erasepage failed */ - /* undo 1st gsave */ - gs_grestore_only(pcli->pcs.pgs); /* destroys gs_save stack */ - /* fall thru to next */ - - case Sgsave1: /* 1st gsave failed */ - /* undo setdevice */ - gs_nulldevice(pcli->pcs.pgs); - /* fall thru to next */ - - case Ssetdevice: /* gs_setdevice failed */ - /* undo bbox device init */ - gs_closedevice((gx_device *)(pcli->bbox_device)); - gx_device_bbox_release(pcli->bbox_device); /* also removes target from bbox */ - /* fall thru to next */ - - case Sbegin: /* nothing left to undo */ - break; - } - return code; -} - -/* Prepare interp instance for the next "job" */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_init_job( - pl_interp_instance_t *instance /* interp instance to start job in */ -) -{ - int code = 0; - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - - pcl_process_init(&pcli->pst); - return code; -} - -/* Parse a cursor-full of data */ -private int /* ret 0 or +ve if ok, else -ve error code */ -pcl_impl_process( - pl_interp_instance_t *instance, /* interp instance to process data job in */ - stream_cursor_read *cursor /* data to process */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - int code = pcl_process(&pcli->pst, &pcli->pcs, cursor); - return code; -} - -/* Skip to end of job ret 1 if done, 0 ok but EOJ not found, else -ve error code */ -private int -pcl_impl_flush_to_eoj( - pl_interp_instance_t *instance, /* interp instance to flush for */ - stream_cursor_read *cursor /* data to process */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - const byte *p = cursor->ptr; - const byte *rlimit = cursor->limit; - - /* Skip to, but leave UEL in buffer for PJL to find later */ - for (; p < rlimit; ++p) - if (p[1] == '\033') { - uint avail = rlimit - p; - - if (memcmp(p + 1, "\033%-12345X", min(avail, 9))) - continue; - if (avail < 9) - break; - cursor->ptr = p; - return 1; /* found eoj */ - } - cursor->ptr = p; - return 0; /* need more data */ -} - -/* Parser action for end-of-file */ -private int /* ret 0 or +ve if ok, else -ve error code */ -pcl_impl_process_eof( - pl_interp_instance_t *instance /* interp instance to process data job in */ -) -{ - int code; - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - pcl_process_init(&pcli->pst); - /* force restore & cleanup if unexpected data end was encountered */ - return 0; -} - -/* Report any errors after running a job */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_report_errors( - pl_interp_instance_t *instance, /* interp instance to wrap up job in */ - int code, /* prev termination status */ - long file_position, /* file position of error, -1 if unknown */ - bool force_to_cout, /* force errors to cout */ - FILE *cout /* stream for back-channel reports */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - byte buf[200]; - uint count; - - while ( (count = pcl_status_read(buf, sizeof(buf), &pcli->pcs)) != 0 ) - fwrite(buf, 1, count, cout); - fflush(cout); - - return 0; -} - -/* Wrap up interp instance after a "job" */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_dnit_job( - pl_interp_instance_t *instance /* interp instance to wrap up job in */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - return 0; -} - -/* Remove a device from an interperter instance */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_remove_device( - pl_interp_instance_t *instance /* interp instance to use */ -) -{ - int code = 0; /* first error status encountered */ - int error; - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - - /* to help with memory leak detection, issue a reset */ - code = pcl_do_resets(&pcli->pcs, pcl_reset_printer); - - /* return to the original graphic state w/color mapper, bbox, target */ - error = pcl_grestore(&pcli->pcs); - /* free the pcl's gstate that mirrors the gs gstate */ - pcl_free_gstate_stk(&pcli->pcs); - if (code >= 0) - code = error; - /* return to original gstate w/bbox, target */ - gs_grestore_only(pcli->pcs.pgs); /* destroys gs_save stack */ - /* Deselect bbox. Bbox has been prevented from auto-closing/deleting */ - error = gs_nulldevice(pcli->pcs.pgs); - if (code >= 0) - code = error; - error = gs_closedevice((gx_device *)pcli->bbox_device); - if (code >= 0) - code = error; - gx_device_bbox_release(pcli->bbox_device); /* also removes target from bbox */ - - return code; -} - -/* Deallocate a interpreter instance */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_deallocate_interp_instance( - pl_interp_instance_t *instance /* instance to dealloc */ -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)instance; - gs_memory_t *mem = pcli->memory; - - /* Get rid of permanent and internal objects */ - if ( pcl_do_resets(&pcli->pcs, pcl_reset_permanent) < 0 ) - return -1; - /* Unwind allocation */ - gs_state_free(pcli->pcs.pgs); - gs_free_object(mem, pcli->bbox_device, "pcl_deallocate_interp_intance(bbox device)"); - gs_free_object(mem, pcli, "pcl_deallocate_interp_instance(pcl_interp_instance_t)"); - - return 0; -} - -/* Do static deinit of PCL interpreter */ -private int /* ret 0 ok, else -ve error code */ -pcl_impl_deallocate_interp( - pl_interp_t *interp /* interpreter to deallocate */ -) -{ - pcl_interp_t *pi = (pcl_interp_t *)interp; - - /* Deinit interp */ - /*@@@ free memory */ - - return 0; -} - -/* - * End-of-page called back by PCL - */ -private int -pcl_end_page_top( - pcl_state_t * pcs, - int num_copies, - int flush -) -{ - pcl_interp_instance_t *pcli = (pcl_interp_instance_t *)(pcs->client_data); - pl_interp_instance_t *instance = (pl_interp_instance_t *)pcli; - int code = 0; - - /* do pre-page action */ - if (pcli->pre_page_action) - { - code = pcli->pre_page_action(instance, pcli->pre_page_closure); - if (code < 0) - return code; - if (code != 0) - return 0; /* code > 0 means abort w/no error */ - } - - /* output the page */ - code = gs_output_page(pcs->pgs, num_copies, flush); - if (code < 0) - return code; - - /* do post-page action */ - if (pcli->post_page_action) - { - code = pcli->post_page_action(instance, pcli->post_page_closure); - if (code < 0) - return code; - } - - return 0; -} - -/* Parser implementation descriptor */ -const pl_interp_implementation_t pcl_implementation = { - pcl_impl_characteristics, - pcl_impl_allocate_interp, - pcl_impl_allocate_interp_instance, - pcl_impl_set_client_instance, - pcl_impl_set_pre_page_action, - pcl_impl_set_post_page_action, - pcl_impl_set_device, - pcl_impl_init_job, - pcl_impl_process, - pcl_impl_flush_to_eoj, - pcl_impl_process_eof, - pcl_impl_report_errors, - pcl_impl_dnit_job, - pcl_impl_remove_device, - pcl_impl_deallocate_interp_instance, - pcl_impl_deallocate_interp -}; diff --git a/pcl/pctop.h b/pcl/pctop.h deleted file mode 100644 index 52763f79d..000000000 --- a/pcl/pctop.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (C) 1996, 1997 Aladdin Enterprises. All rights reserved. - Unauthorized use, copying, and/or distribution prohibited. - */ - -/* pctop.h */ -/* Interface to main program utilities for PCL5 interpreter */ - -#ifndef pctop_INCLUDED -# define pctop_INCLUDED - -/* Set PCL's target device */ -void pcl_set_target_device(P2(pcl_state_t *pcs, gx_device *pdev)); - -/* Get PCL's curr target device */ -gx_device * pcl_get_target_device(P1(pcl_state_t *pcs)); - - -#endif /* pctop_INCLUDED */ diff --git a/pcl/pctpm.h b/pcl/pctpm.h deleted file mode 100644 index 2cd87bb98..000000000 --- a/pcl/pctpm.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pctpm.h - structures of PCL's text parsing methods */ - -#ifndef pctpm_INCLUDED -#define pctpm_INCLUDED - -#include "gx.h" - -typedef struct pcl_text_parsing_method_s { - byte min1, max1; - byte min2, max2; -} pcl_text_parsing_method_t; - -#define pcl_char_is_2_byte(ch, tpm) \ - ( ((ch) >= (tpm)->min1) && \ - ((ch) <= (tpm)->max2) && \ - (((ch) <= (tpm)->max1) || ((ch) >= (tpm)->min2)) ) - -#define pcl_tpm_is_single_byte(tpm) ((tpm)->max1 == 0) - -/* Single-byte only */ -#define pcl_tpm_0_data { 0xff, 0, 0xff, 0 } - -/* 0x21-0xff are double-byte */ -#define pcl_tpm_21_data { 0x21, 0xff, 0x21, 0xff } - -/* 0x81-0x9f, 0xe0-0xfc are double-byte */ -#define pcl_tpm_31_data { 0x81, 0x9f, 0xe0, 0xfc } - -/* 0x80-0xff are double-byte */ -#define pcl_tpm_38_data { 0x80, 0xff, 0x80, 0xff } - -#endif /* pctpm_INCLUDED */ diff --git a/pcl/pcuptrn.c b/pcl/pcuptrn.c deleted file mode 100644 index 4b1a391a6..000000000 --- a/pcl/pcuptrn.c +++ /dev/null @@ -1,577 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcuptrn.c - code for PCL and GL/2 user defined patterns */ - -#include "string_.h" -#include "gx.h" -#include "gsuid.h" -#include "gscsel.h" -#include "gsdevice.h" -#include "gxdevice.h" -#include "gscspace.h" -#include "gxdcolor.h" -#include "gxcolor2.h" -#include "gxpcolor.h" -#include "pldict.h" -#include "pcindxed.h" -#include "pcpatrn.h" -#include "pcbiptrn.h" -#include "pcuptrn.h" - -/* - * GC routines. - */ -private_st_pattern_data_t(); -private_st_pattern_t(); - -/* - * Free routine for pattern data structure. - */ - private void -free_pattern_data( - gs_memory_t * pmem, - void * pvpat_data, - client_name_t cname -) -{ - pcl_pattern_data_t * ppat_data = (pcl_pattern_data_t *)pvpat_data; - - if ((ppat_data->storage != pcds_internal) && (ppat_data->pixinfo.data != 0)) - gs_free_object(pmem, ppat_data->pixinfo.data, cname); - gs_free_object(pmem, pvpat_data, cname); -} - -/* - * Build a pattern data structure. This routine is private as pattern data - * structures may only be built as part of a pattern. - * - * All pattern data structure are built as "temporary". Routines that build - * internal patterns should modify this as soon as the pattern is built. - * - * Returns 0 on success, < 0 in the event of an error. In the latter case, - * *pppat_data will be set to NULL. - */ - private int -build_pattern_data( - pcl_pattern_data_t ** pppat_data, - const gs_depth_bitmap * ppixinfo, - pcl_pattern_type_t type, - int xres, - int yres, - gs_memory_t * pmem -) -{ - pcl_pattern_data_t * ppat_data = 0; - - *pppat_data = 0; - rc_alloc_struct_1( ppat_data, - pcl_pattern_data_t, - &st_pattern_data_t, - pmem, - return e_Memory, - "allocate PCL pattern data" - ); - ppat_data->rc.free = free_pattern_data; - - ppat_data->pixinfo = *ppixinfo; - ppat_data->storage = pcds_temporary; - ppat_data->type = type; - ppat_data->xres = xres; - ppat_data->yres = yres; - - *pppat_data = ppat_data; - return 0; -} - -/* - * Free the rendered portion of a pattern. - */ - private void -free_pattern_rendering( - pcl_pattern_t * pptrn -) -{ - if (pptrn->pcol_ccolor != 0) { - pcl_ccolor_release(pptrn->pcol_ccolor); - pptrn->pcol_ccolor = 0; - } - if (pptrn->pmask_ccolor != 0) { - pcl_ccolor_release(pptrn->pmask_ccolor); - pptrn->pmask_ccolor = 0; - } -} - -/* - * Free routine for patterns. This is exported for the benefit of the code - * that handles PCL built-in patterns. - */ - void -pcl_pattern_free_pattern( - gs_memory_t * pmem, - void * pvptrn, - client_name_t cname -) -{ - pcl_pattern_t * pptrn = (pcl_pattern_t *)pvptrn; - - free_pattern_rendering(pptrn); - if (pptrn->ppat_data != 0) - pcl_pattern_data_release(pptrn->ppat_data); - gs_free_object(pmem, pvptrn, cname); -} - -/* - * Build a PCL pattern. - * - * This is expoorted for use by the routines that create the "built in" - * patterns. - * - * Returns 0 if successful, < 0 in the event of an error. In the latter case, - * *ppptrn will be set to null. - */ - int -pcl_pattern_build_pattern( - pcl_pattern_t ** ppptrn, - const gs_depth_bitmap * ppixinfo, - pcl_pattern_type_t type, - int xres, - int yres, - gs_memory_t * pmem -) -{ - pcl_pattern_t * pptrn = 0; - int code = 0; - - *ppptrn = 0; - pptrn = gs_alloc_struct( pmem, - pcl_pattern_t, - &st_pattern_t, - "create PCL pattern" - ); - if (pptrn == 0) - return e_Memory; - - pptrn->pcol_ccolor = 0; - pptrn->pmask_ccolor = 0; - pptrn->orient = 0; - /* provide a sentinel to guarantee the initial pattern is - rendered */ - pptrn->ref_pt.x = pptrn->ref_pt.y = -1.0; - code = build_pattern_data( &(pptrn->ppat_data), - ppixinfo, - type, - xres, - yres, - pmem - ); - if (code < 0) { - pcl_pattern_free_pattern(pmem, pptrn, "create PCL pattern"); - return code; - } - - *ppptrn = pptrn; - return 0; -} - -/* - * Get a PCL user-defined pattern. A null return indicates the pattern is - * not defined. - */ - pcl_pattern_t * -pcl_pattern_get_pcl_uptrn( pcl_state_t *pcs, int id ) -{ - if (pcs->last_pcl_uptrn_id != id) { - pcl_id_t key; - - pcs->last_pcl_uptrn_id = id; - id_set_value(key, id); - if ( !pl_dict_lookup( &pcs->pcl_patterns, - id_key(key), - 2, - (void **)&pcs->plast_pcl_uptrn, - false, - NULL - ) ) - pcs->plast_pcl_uptrn = 0; - } - - return pcs->plast_pcl_uptrn; -} - -/* - * Define a PCL user-defined pattern. This procedure updates the cached - * information, hence it should be used for all definitions. To undefine - * an entry, set the second operard to null. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -define_pcl_ptrn( - pcl_state_t * pcs, - int id, - pcl_pattern_t * pptrn -) -{ - pcl_id_t key; - - id_set_value(key, id); - if (pptrn == 0) - pl_dict_undef(&pcs->pcl_patterns, id_key(key), 2); - else if (pl_dict_put(&pcs->pcl_patterns, id_key(key), 2, pptrn) < 0) - return e_Memory; - - if (pcs->last_pcl_uptrn_id == id) - pcs->plast_pcl_uptrn = pptrn; - - return 0; -} - -/* - * Delete all temporary patterns or all patterns, based on the value of - * the operand. - */ - private void -delete_all_pcl_ptrns( - bool renderings, - bool tmp_only, - pcl_state_t * pcs -) -{ - pcl_pattern_t * pptrn; - pl_dict_enum_t denum; - gs_const_string plkey; - - pl_dict_enum_begin(&pcs->pcl_patterns, &denum); - while (pl_dict_enum_next(&denum, &plkey, (void **)&pptrn)) { - if (!tmp_only || (pptrn->ppat_data->storage == pcds_temporary)) { - pcl_id_t key; - - id_set_key(key, plkey.data); - define_pcl_ptrn(pcs, id_value(key), NULL); - } else if (renderings) - free_pattern_rendering(pptrn); - } -} - -/* - * Get a GL/2 user defined pattern. A null return indicates there is no pattern - * defined for the index. - */ - pcl_pattern_t * -pcl_pattern_get_gl_uptrn(pcl_state_t *pcs, int indx) -{ - if (pcs->last_gl2_RF_indx != indx) { - pcl_id_t key; - - pcs->last_gl2_RF_indx = indx; - id_set_value(key, indx); - if ( !pl_dict_lookup( &pcs->gl_patterns, - id_key(key), - 2, - (void **)(&pcs->plast_gl2_uptrn), - false, - NULL - ) ) - pcs->plast_gl2_uptrn = 0; - } - - return pcs->plast_gl2_uptrn; -} - -/* - * Create and define a GL/2 user-define pattern. This is the only pattern- - * control like facility provided for GL/2. To undefine patterns, use null - * as the second operand. See pcpatrn.h for further information. - * - * Note that RF patterns may be either colored or uncolored. At the GL/2 level - * the determination is made based on whether or not they contain pen indices - * other than 0 or 1. At this level the determination is based on the depth - * of the data pixmap: 1 for uncolored, 8 for colored. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_pattern_RF( - int indx, - const gs_depth_bitmap * ppixmap, - pcl_state_t * pcs -) -{ - pcl_id_t key; - pcl_pattern_t * pptrn = 0; - - id_set_value(key, indx); - - if (ppixmap != 0) { - pcl_pattern_type_t type = ( ppixmap->pix_depth == 1 - ? pcl_pattern_uncolored - : pcl_pattern_colored ); - /* RF appears to use the resolution of the device contrary to - what the pcl documentation implies */ - gx_device *pdev = gs_currentdevice(pcs->pgs); - int code = pcl_pattern_build_pattern( &pptrn, - ppixmap, - type, - pdev->HWResolution[0], - pdev->HWResolution[1], - pcs->memory - ); - - if (code < 0) - return code; - - if (pl_dict_put(&pcs->gl_patterns, id_key(key), 2, pptrn) < 0) { - pcl_pattern_free_pattern( pcs->memory, - pptrn, - "create GL/2 RF pattern" - ); - return e_Memory; - } - - } else - pl_dict_undef(&pcs->gl_patterns, id_key(key), 2); - - if (pcs->last_gl2_RF_indx == indx) - pcs->plast_gl2_uptrn = pptrn; - - return 0; -} - - -/* - * The PCL user-define pattern type. For memory management reasons, this has - * a transitory existence. - * - * This object comes in two forms, with and without resolution. Which form - * applies is determined based on the size of the received data array as - * compared to that indicated by the height, width, and depth fields - * - * Note: These structures are defined by HP. - */ -typedef struct pcl_upattern0_s { - byte format; /* actually pcl_pattern_type_t */ - byte cont; /* continuation; currently unused */ - byte depth; /* bits per pixel; 1 or 8 */ - byte dummy; /* reserved - currently unused */ - byte height[2]; /* height in pixels */ - byte width[2]; /* width in pixels */ - byte data[1]; /* actual size derived from hgiht, width, and bits */ -} pcl_upattern0_t; - -typedef struct pcl_upattern1_s { - byte format; /* actually pcl_pattern_type_t */ - byte cont; /* continuation; currently unused */ - byte depth; /* bits per pixel; 1 or 8 */ - byte dummy; /* reserved - currently unused */ - byte height[2]; /* height in pixels */ - byte width[2]; /* width in pixels */ - byte xres[2]; /* width resolution */ - byte yres[2]; /* height resolution */ - byte data[1]; /* actual size derived from hgiht, width, and bits */ -} pcl_upattern1_t; - -/* - * ESC * c # W - * - * Download Pattern - */ - private int -download_pcl_pattern( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint count = arg_data_size(pargs); - const pcl_upattern0_t * puptrn0 = (pcl_upattern0_t *)arg_data(pargs); - uint format, depth, rsize; - gs_depth_bitmap pixinfo; - int xres = 300, yres = 300; - pcl_pattern_t * pptrn = 0; - int code = 0; - - if (count < 8) - return e_Range; - - format = puptrn0->format; - pixinfo.num_comps = 1; - pixinfo.size.x = (((uint)puptrn0->width[0]) << 8) + puptrn0->width[1]; - pixinfo.size.y = (((uint)puptrn0->height[0]) << 8) + puptrn0->height[1]; - depth = puptrn0->depth & 0xf; - pixinfo.pix_depth = depth; - pixinfo.raster = (pixinfo.size.x * depth + 7) / 8; - rsize = pixinfo.raster * pixinfo.size.y; - - /* check for legitimate format */ - if ((format == 0) || (format == 20)) { - if (depth != 1) - return e_Range; - } else if ( (format != 1) || - ((depth != 1) && (depth != 8)) || - (pixinfo.size.x == 0) || - (pixinfo.size.y == 0) ) - return e_Range; - - /* allocate space for the array */ - pixinfo.data = gs_alloc_bytes(pcs->memory, rsize, "download PCL pattern"); - if (pixinfo.data == 0) - return e_Memory; - - /* check for resolution fields; note that HP allows count < rsize + 8 */ - if (count >= rsize + 12) { - pcl_upattern1_t * puptrn1 = (pcl_upattern1_t *)puptrn0; - - xres = (((uint)puptrn1->xres[0]) << 8) + puptrn1->xres[1]; - yres = (((uint)puptrn1->yres[0]) << 8) + puptrn1->yres[1]; - memcpy(pixinfo.data, puptrn1->data, rsize); - - } else { - uint tmp_cnt = min(count - 8, rsize); - - memcpy(pixinfo.data, puptrn0->data, tmp_cnt); - if (tmp_cnt < rsize) - memset(pixinfo.data + tmp_cnt, 0, rsize - tmp_cnt); - } - - /* build the pattern */ - code = pcl_pattern_build_pattern( &(pptrn), - &pixinfo, - (format == 1 ? pcl_pattern_colored - : pcl_pattern_uncolored), - xres, - yres, - pcs->memory - ); - - /* place the pattern into the pattern dictionary */ - if ( (code < 0) || - ((code = define_pcl_ptrn(pcs, pcs->pattern_id, pptrn)) < 0) ) { - if (pptrn != 0) - pcl_pattern_free_pattern(pcs->memory, pptrn, "download PCL pattern"); - else - gs_free_object( pcs->memory, - (void *)pixinfo.data, - "download PCL pattern" - ); - } - - return code; -} - -/* - * ESC * c # Q - * - * Pattern contorl. - */ - private int -pattern_control( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcl_pattern_t * pptrn = 0; - - switch (int_arg(pargs)) { - - /* delete all patterns */ - case 0: - delete_all_pcl_ptrns(false, false, pcs); - break; - - /* delete all temporary patterns */ - case 1: - delete_all_pcl_ptrns(false, true, pcs); - break; - - /* delete last specified pattern */ - case 2: - define_pcl_ptrn(pcs, pcs->pattern_id, NULL); - - /* make last specified pattern temporary */ - case 4: - pptrn = pcl_pattern_get_pcl_uptrn(pcs, pcs->pattern_id); - if (pptrn != 0) - pptrn->ppat_data->storage = pcds_temporary; - break; - - /* make last specified pattern permanent */ - case 5: - pptrn = pcl_pattern_get_pcl_uptrn(pcs, pcs->pattern_id); - if (pptrn != 0) - pptrn->ppat_data->storage = pcds_permanent; - break; - - default: - break; - } - - return 0; -} - -/* - * Stub routine to be used for clearing the pattern cache. - */ - private bool -delete_cached_patterns_stub( - gx_color_tile * ctile, /* ignored */ - void * pcls_data /* ignored */ -) -{ - return true; -} - -/* - * Initialization and reset routines. - */ - private int -upattern_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - DEFINE_CLASS('*') - { - 'c', 'W', - PCL_COMMAND("Download Pattern", download_pcl_pattern, pca_bytes) - }, - { - 'c', 'Q', - PCL_COMMAND( "Pattern Control", - pattern_control, - pca_neg_ignore | pca_big_ignore - ) - }, - END_CLASS - return 0; -} - - private void -upattern_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - if ((type & pcl_reset_initial) != 0) { - pl_dict_init(&pcs->pcl_patterns, pcs->memory, pcl_pattern_free_pattern); - pl_dict_init(&pcs->gl_patterns, pcs->memory, pcl_pattern_free_pattern); - pcs->last_pcl_uptrn_id = -1; - pcs->plast_pcl_uptrn = 0; - pcs->last_gl2_RF_indx = -1; - pcs->plast_gl2_uptrn = 0; - - } else if ((type & (pcl_reset_cold | pcl_reset_printer)) != 0) { - - /* HACK - purge the pattern cache to try to avoid fragmentation */ - gx_pattern_cache_winnow( gstate_pattern_cache(pcs->pgs), - delete_cached_patterns_stub, - NULL - ); - - delete_all_pcl_ptrns(true, true, pcs); - pcl_pattern_clear_bi_patterns(pcs); - /* GL's IN command takes care of the GL patterns */ - } -} - -const pcl_init_t pcl_upattern_init = { upattern_do_registration, upattern_do_reset }; diff --git a/pcl/pcuptrn.h b/pcl/pcuptrn.h deleted file mode 100644 index 3c763e77d..000000000 --- a/pcl/pcuptrn.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcuptrn.h - interface for PCL and GL/2 user defined patterns */ - -#ifndef pcuptrn_INCLUDED -#define pcuptrn_INCLUDED - -#include "gx.h" -#include "pcommand.h" -#include "pcpatrn.h" - -/* - * Free routine for patterns. This is exported for the benefit of the code - * that handles PCL built-in patterns. - */ -void pcl_pattern_free_pattern(P3( - gs_memory_t * pmem, - void * pvptrn, - client_name_t cname -)); - -/* - * Build a PCL pattern. This is exported for use by the routines supporting - * built-in patterns. - */ -int pcl_pattern_build_pattern(P6( - pcl_pattern_t ** pppat_data, - const gs_depth_bitmap * ppixmap, - pcl_pattern_type_t type, - int xres, - int yres, - gs_memory_t * pmem -)); - -/* - * Get a PCL user-defined pattern. A null return indicates the pattern is - * not defined. - */ -pcl_pattern_t * pcl_pattern_get_pcl_uptrn(P2(pcl_state_t *pcs, int id)); - -/* - * Get a GL/2 user defined pattern. A null return indicates there is no pattern - * defined for the index. - */ -extern pcl_pattern_t * pcl_pattern_get_gl_uptrn(P2(pcl_state_t *pcs, int indx)); - -/* pcl_pattern_RF is in pcpatrn.h */ - -/* - * External access to the user defined pattern related operators. - */ -extern const pcl_init_t pcl_upattern_init; - -#endif /* pcuptrn_INCLUDED */ diff --git a/pcl/pcursor.c b/pcl/pcursor.c deleted file mode 100644 index fb27e54c5..000000000 --- a/pcl/pcursor.c +++ /dev/null @@ -1,810 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcursor.c - PCL5 cursor positioning commands */ - -#include "std.h" -#include "math_.h" -#include "pcommand.h" -#include "pcstate.h" -#include "pcdraw.h" -#include "pcpatxfm.h" -#include "pcfont.h" -#include "pcursor.h" -#include "pcpage.h" -#include "gscoord.h" -#include "pjtop.h" - -/* - * Hoizontal and vertical movement. - * - * This is one of the most confusing areas of PCL because the individual - * movement commands and margins evolved at different times in the history - * of PCL, and thus have different behavior. In the dicussion below, we - * divide the various horizontal and vertical motion commands into groups, - * and identify the interaction of each group with the corresponding horizontal - * or vertical boundaries. (Note that, if the current print direciton is not - * zero, what is called the "left" logical page boundary would, from the - * point of view of the logical page, be given a different label.) - * - * Horizontal motion commmands (note: a movement "transitions" a boundary if - * the current point before and after the movement is on opposite sides of - * the boundary): - * - * a. Horizontal position by column, decipoint, or PCL unit, in absolute - * or relative mode, and horizontal motion due to rasters: - * - * "left" logical page boundary is used as origin for absolute positions - * movement to the left of the left logical page boundary is clamped - * to that boundary - * left text boundary is ignored - * right text boundary is ignored - * movement beyond the "right" logical page boundary is clamped to - * that boundary - * - * b. Tab (always relative) - * - * "left" logical boundary is irrelevant - * left text boundary is used as the origin for tab stops - * movement that transitions the right text boundary is clamped to - * that boundary - * movement beyond the "right" logical page boundary is clamped - * to that boundary - * - * c. Character or space (code legal in symbol set up not occupied by a - * printable character; motion always relative) - * - * "left" logical page boundary is irrelevant - * left text boundary is ignored - * if the character WOULD transition the right text boundary, ignore - * the character or issue a CR/LF sequence BEFORE printing the - * character, base on whether or not end-of-line wrapping is - * enabled (with one exception; see below) - * if the character WOULD transition the "right" logical page boundary, - * ignore the character or issue a CR/LF sequence BEFORE printing - * the character, base on whether or not end-of-line wrapping is - * enabled - * - * Note that only one of the latter two operations will be preformed if - * the logical and text margins are the same. - * - * An exception is made in third case above in the event that a back- - * space was received immediately before the character to be rendered. - * In that case, the character is rendered regardless of the transition - * of the right text boundary. - * - * d. Carriage return (always absolute) - * - * "left" logical page boundary is irrelevant - * left text boundary is used as the new horizontal location - * right text boundary is irrelevant - * "right" logical page boundary is irrelevant - * - * e. Back space - * - * movement beyond the "left" logical page boundary is clamped to - * that boundary - * movement that would transition the left text boundary is clamped - * to that boundary - * right text boundary is ignored (this is contrary to HP's - * documentation, but empirically verified on several machines) - * "right" logical page boundary is irrelevant - * - * In addtion, any horizontal movement to the left will "break" the current - * underline (this is significant for floating underlines). - * - * Vertical motion commands: - * - * f. Vertical cursor position by decipoints or PCL units (but NOT by - * rows), both absolute and relative - * - * movement beyond the "top" logical page boundary is clamped to - * that boundary - * top text boundary is used as the origin for absolute moves - * bottom text margin is ignored - * movement beyond the "bottom" logical page boundary is clamped to - * that boundary - * - * g. Absolute (NOT relative) vertical cursor position by rows - * - * "top" logical page boundary is irrelevant (can only be reached by - * relative moves) - * top text boundary, offset by 75% of the VMI distance, is used as - * the origin - * bottom text margin is ignored - * movement beyond the "bottom" logical page boundary is clamped to - * that boundary - * - * h. Relative (NOT absolute) vertical cursor position by rows, and both - * line-feed and half line-feed when perforation skip is disabled - * - * movement beyond the "top" logical page boundary is clamped to - * that boundary - * if and advance of n rows (n == 1 for LF) is requested, and only - * m additional rows can be accommodated on the current page, - * an implicit page ejection occurs and the cursor is positioned - * n - m rows below the "top" logical page boundary on the - * subsequent page; if the subsequent page will not accommodate - * n - m rows, the process is repeated - * after an implicit page eject (see below), the cursor is positioned - * one VMI distance below the "top" logical page boundary plus - * - * top text boundary is ignored - * bottom text boundary is ignored - * movement beyond the "bottom" page boundary causes an implicit - * page eject - * - * i. Line-feed and halft line feed, when perforation skip is enabled - * - * "top" logical page boundary is irrelevant - * after an implicit page eject (see below), the cursor is set 75% of - * the VMI distance below the top text boundary - * any movement that ends below the bottom text boundary causes a - * page eject (NB: this does not require a transition of the - * boundary, as is the case for the right text boundary) - * the "bottom" logical page boundary is irrelevant - * - * j. Form feed - * - * "top" logical page boundary is irrelevant - * the cursor is positioned 75% of the VMI distance below the top - * text boundary - * bottom text boundary is irrelevant - * "bottom" logical page boundary is irrelevant - * - * Wow - an even 10 different forms to accommodate. - * - * The special handling required by character and space induced horizontal - * movement is handled in pctext.c (pcl_show_chars); all other movement is - * handled in this file. - */ - -#define HOME_X(pcs) (pcs->margins.left) -#define HOME_Y(pcs) (pcs->margins.top + (3L * pcs->vmi_cp) / 4L) - - void -pcl_set_cap_x( - pcl_state_t * pcs, - coord x, - bool relative, - bool use_margins -) -{ - coord old_x = pcs->cap.x; - - if (relative) - x += pcs->cap.x; - - /* the horizontal text margins are only interesting in transition */ - if (use_margins) { - coord min_x = pcs->margins.left; - coord max_x = pcs->margins.right; - - if ((old_x >= min_x) && (x < min_x)) - x = min_x; - else if ((old_x <= max_x) && (x > max_x)) - x = max_x; - } - - /* the logical page bounds always apply */ - x = ( x > pcs->xfm_state.pd_size.x ? pcs->xfm_state.pd_size.x - : (x < 0L ? 0L : x) ); - - /* leftward motion "breaks" an underline */ - if (x < old_x) { - pcl_break_underline(pcs); - pcs->cap.x = x; - pcl_continue_underline(pcs); - } else - pcs->cap.x = x; -} - - int -pcl_set_cap_y( - pcl_state_t * pcs, - coord y, - bool relative, - bool use_margins, - bool by_row -) -{ - coord lim_y = pcs->xfm_state.pd_size.y; - coord max_y = pcs->margins.top + pcs->margins.length; - bool page_eject = (by_row && relative); - - /* adjust the vertical position provided */ - if (relative) - y += pcs->cap.y; - else - y += (by_row ? HOME_Y(pcs) : pcs->margins.top); - - /* vertical moves always "break" underlines */ - pcl_break_underline(pcs); - - max_y = (use_margins ? max_y : lim_y); - if (y < 0L) - pcs->cap.y = 0L; - else if (y <= max_y) - pcs->cap.y = y; - else if (!page_eject) - pcs->cap.y = (y <= lim_y ? y : lim_y); - else { - coord vmi_cp = pcs->vmi_cp; - coord y0 = pcs->cap.y; - - while (y > max_y) { - int code = pcl_end_page_always(pcs); - - if (code < 0) - return code; - y -= (y0 <= max_y ? max_y : y0); - y0 = (use_margins ? HOME_Y(pcs) : vmi_cp); - - /* if one VMI distance or less remains, always exit */ - if ((vmi_cp == 0) || (y <= vmi_cp)) { - y = y0; - break; - } - - /* otherwise, round to a multiple of VMI distance */ - y += y0 - 1 - ((y - 1) % vmi_cp); - } - - pcs->cap.y = y; - } - - pcl_continue_underline(pcs); - return 0; -} - -/* some convenient short-hand for the cursor movement commands */ -#define do_horiz_motion(pargs, pcs, mul) \ - pcl_set_cap_x((pcs), float_arg(pargs) * (mul), arg_is_signed(pargs), false) - -#define do_vertical_move(pcs, pargs, mul, use_margins, by_row) \ - return pcl_set_cap_y( (pcs), \ - float_arg(pargs) * (mul), \ - arg_is_signed(pargs), \ - (use_margins), \ - (by_row) \ - ) - - -/* - * Control character action implementation. - * - * These routines perform just the individual actions. The control character - * routines may invoke several of these, based on the selected line termination - * setting. - * - * do_CR and do_LF are exported for use by the text manipulation routines and - * the display functions. - * - * Note: CR always "breaks" an underline, even if it is a movement to the right. - */ - void -pcl_do_CR( - pcl_state_t * pcs -) -{ - pcl_break_underline(pcs); - pcl_set_cap_x(pcs, pcs->margins.left, false, false); - pcl_continue_underline(pcs); -} - - int -pcl_do_LF( - pcl_state_t * pcs -) -{ - return pcl_set_cap_y( pcs, - pcs->vmi_cp, - true, - (pcs->perforation_skip == 1), - true - ); -} - -/* - * Unconditionally feed a page, and move the the "home" verical position on - * the followin page. - */ - int -pcl_do_FF( - pcl_state_t * pcs -) -{ - int code = pcl_end_page_always(pcs); - - if (code >= 0) { - code = pcl_set_cap_y(pcs, 0L, false, false, true); - pcl_continue_underline(pcs); /* (after adjusting y!) */ - } - return code; -} - -/* - * Return the cursor to its "home" position - */ - void -pcl_home_cursor( - pcl_state_t * pcs -) -{ - pcl_set_cap_x(pcs, pcs->margins.left, false, false); - pcl_set_cap_y(pcs, 0L, false, false, true); -} - -/* - * Update the HMI by recomputing it from the font. - */ - coord -pcl_updated_hmi( - pcl_state_t * pcs -) -{ - coord hmi; - const pcl_font_selection_t * pfs = - &(pcs->font_selection[pcs->font_selected]); - int code = pcl_recompute_font(pcs); - const pl_font_t * plfont = pcs->font; - - if (code < 0) - return pcs->hmi_cp; /* bad news; don't mark the HMI as valid. */ - - if (pl_font_is_scalable(plfont)) { - if (plfont->params.proportional_spacing) - /* Scale the font's pitch by the requested height. */ - hmi = pl_fp_pitch_cp(&plfont->params) * pfs->params.height_4ths / 4; - else - hmi = pl_fp_pitch_cp(&(pfs->params)); - } else - hmi = pl_fp_pitch_cp(&(plfont->params)); - - /* - * Round to a multiple of the unit of measure (see the "PCL 5 Printer - * LanguageTechnical Reference Manual", October 1992 ed., page 5-22. - */ - hmi = hmi + pcs->uom_cp / 2; - return pcs->hmi_cp = hmi - (hmi % pcs->uom_cp); -} - - -/* Commands */ - -/* - * ESC & k <x> H - * - * Set horizontal motion index. - */ - private int -set_horiz_motion_index( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->hmi_cp = inch2coord(fabs(float_arg(pargs)) / 120.0); - return 0; -} - -/* - * ESC & l <y> C - * - * Set vertical motion index. - * - * Contrary to HP's documentation ("PCL 5 Printer Language Technical Reference - * Manual", October 1992 ed., p. 5-24), this command is NOT ignored if the - * requested VMI is greater than the page length. - */ - private int -set_vert_motion_index( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcs->vmi_cp = inch2coord(fabs(float_arg(pargs)) / 48.0); - return 0; -} - -/* - * ESC & l <lpi> D - * - * Set line spacing. Though it is not documented anywhere, various HP devices - * agree that a zero operand specifies 12 lines per inch (NOT the default). - */ - private int -set_line_spacing( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint lpi = uint_arg(pargs); - - if (lpi == 0) /* 0 ==> 12 lines per inch */ - lpi = 12; - if ((48 % lpi) == 0) /* lpi must divide 48 */ - pcs->vmi_cp = inch2coord(1.0 / lpi); - return 0; -} - -/* - * ESC & k G - */ - private int -set_line_termination( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint ui = uint_arg(pargs); - - if (ui <= 3) - pcs->line_termination = ui; - return 0; -} - - -/* - * ESC & a <cols> C - */ - private int -horiz_cursor_pos_columns( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_horiz_motion(pargs, pcs, pcl_hmi(pcs)); - return 0; -} - -/* - * ESC & a <dp> H - */ - private int -horiz_cursor_pos_decipoints( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_horiz_motion(pargs, pcs, 10.0); - return 0; -} - -/* - * ESC * p <units> X - */ - private int -horiz_cursor_pos_units( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_horiz_motion(pargs, pcs, pcs->uom_cp); - return 0; -} - -/* - * CR - */ - private int -cmd_CR( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - pcl_do_CR(pcs); - return ((pcs->line_termination & 1) != 0 ? pcl_do_LF(pcs) : 0); -} - -/* - * BS - */ - private int -cmd_BS( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - pcl_set_cap_x(pcs, -pcs->last_width, true, true); - pcs->last_was_BS = true; - return 0; -} - -/* - * HT - * - * Tabs occur at ever 8 columns, measure from the left text margin. - */ - private int -cmd_HT( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - coord x = pcs->cap.x - pcs->margins.left; - coord tab; - - if (x < 0) - x = -x; - else if ((tab = 8 * pcl_hmi(pcs)) > 0) - x = tab - (x % tab); - else - x = 0L; - pcl_set_cap_x(pcs, x, true, true); - return 0; -} - - -/* - * ESC & a <rows> R - */ - private int -vert_cursor_pos_rows( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_vertical_move(pcs, pargs, pcs->vmi_cp, false, true); -} - -/* - * ESC & a <dp> V - */ - private int -vert_cursor_pos_decipoints( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_vertical_move(pcs, pargs, 10.0, false, false); -} - -/* - * ESC * p <units> Y - */ - private int -vert_cursor_pos_units( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - do_vertical_move(pcs, pargs, pcs->uom_cp, false, false); -} - -/* - * ESC = - */ - private int -half_line_feed( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - return pcl_set_cap_y( pcs, - pcs->vmi_cp / 2, - true, - (pcs->perforation_skip == 1), - true - ); -} - -/* - * LF - */ - private int -cmd_LF( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - if ((pcs->line_termination & 2) != 0) - pcl_do_CR(pcs); - return pcl_do_LF(pcs); -} - -/* - * FF - */ - private int -cmd_FF( - pcl_args_t * pargs, /* ignored */ - pcl_state_t * pcs -) -{ - if ((pcs->line_termination & 2) != 0) - pcl_do_CR(pcs); - return pcl_do_FF(pcs); -} - - -/* - * ESC & f <pp_enum> S - * - * Contrary to what is indicated in the "PCL 5 Printer Language Technical - * Reference Manual", October 1992 ed., p. 6-16, pushd cursors are stored - * in logical page space, not device space. - */ - private int -push_pop_cursor( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int type = uint_arg(pargs); - - if ((type == 0) && (pcs->cursor_stk_size < countof(pcs->cursor_stk))) { - gs_point * ppt = &(pcs->cursor_stk[pcs->cursor_stk_size++]); - - ppt->x = (double)pcs->cap.x; - ppt->y = (double)pcs->cap.y; - gs_point_transform( ppt->x, ppt->y, &(pcs->xfm_state.pd2lp_mtx), ppt); - - } else if ((type == 1) && (pcs->cursor_stk_size > 0)) { - gs_point * ppt = &(pcs->cursor_stk[--pcs->cursor_stk_size]); - gs_matrix lp2pd; - - pcl_invert_mtx(&(pcs->xfm_state.pd2lp_mtx), &lp2pd); - gs_point_transform(ppt->x, ppt->y, &lp2pd, ppt); - pcl_set_cap_x(pcs, (coord)ppt->x, false, false); - pcl_set_cap_y( pcs, - (coord)ppt->y - pcs->margins.top, - false, - false, - false - ); - } - - return 0; -} - -private int -pcursor_do_copy(pcl_state_t *psaved, - const pcl_state_t *pcs, pcl_copy_operation_t operation) -{ - /* don't restore the current cap. The cap is not part of the - state */ - if ( operation & pcl_copy_after ) - psaved->cap = pcs->cap; - return 0; -} - -/* - * Initialization - */ - private int -pcursor_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem -) -{ - - DEFINE_CLASS('&') - { - 'k', 'H', - PCL_COMMAND( "Horizontal Motion Index", - set_horiz_motion_index, - pca_neg_ok | pca_big_clamp - ) - }, - { - 'l', 'C', - PCL_COMMAND( "Vertical Motion Index", - set_vert_motion_index, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'l', 'D', - PCL_COMMAND( "Line Spacing", - set_line_spacing, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'k', 'G', - PCL_COMMAND( "Line Termination", - set_line_termination, - pca_neg_ok | pca_big_ignore - ) - }, - { - 'a', 'C', - PCL_COMMAND( "Horizontal Cursor Position Columns", - horiz_cursor_pos_columns, - pca_neg_ok | pca_big_ok - ) - }, - { - 'a', 'H', - PCL_COMMAND( "Horizontal Cursor Position Decipoints", - horiz_cursor_pos_decipoints, - pca_neg_ok | pca_big_ok - ) - }, - { - 'a', 'R', - PCL_COMMAND( "Vertical Cursor Position Rows", - vert_cursor_pos_rows, - pca_neg_ok | pca_big_clamp - ) - }, - { - 'a', 'V', - PCL_COMMAND( "Vertical Cursor Position Decipoints", - vert_cursor_pos_decipoints, - pca_neg_ok | pca_big_ok - ) - }, - { - 'f', 'S', - PCL_COMMAND( "Push/Pop Cursor", - push_pop_cursor, - pca_neg_ok | pca_big_ignore - ) - }, - END_CLASS - - DEFINE_CLASS('*') - { - 'p', 'X', - PCL_COMMAND( "Horizontal Cursor Position Units", - horiz_cursor_pos_units, - pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - { - 'p', 'Y', - PCL_COMMAND( "Vertical Cursor Position Units", - vert_cursor_pos_units, - pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - END_CLASS - - DEFINE_CONTROL(CR, "CR", cmd_CR) - DEFINE_CONTROL(BS, "BS", cmd_BS) - DEFINE_CONTROL(HT, "HT", cmd_HT) - DEFINE_ESCAPE('=', "Half Line Feed", half_line_feed) - DEFINE_CONTROL(LF, "LF", cmd_LF) - DEFINE_CONTROL(FF, "FF", cmd_FF) - - return 0; -} - - private void -pcursor_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_printer - | pcl_reset_overlay ); - - if ((type & mask) == 0) - return; - - pcs->line_termination = 0; - pcs->hmi_cp = HMI_DEFAULT; - pcs->vmi_cp = pcs->margins.length - / pjl_proc_vartoi(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "formlines")); - - if ( (type & pcl_reset_overlay) == 0 ) { - pcs->cursor_stk_size = 0; - - /* - * If this is an initial reset, make sure underlining is - * disabled (homing the cursor may cause an underline to be - * put out. And provide reasonable initial values for the - * cap. - */ - if ((type & pcl_reset_initial) != 0) { - pcs->underline_enabled = false; - pcs->cap.x = pcs->cap.y = 0; - } - pcl_home_cursor(pcs); - } -} - -const pcl_init_t pcursor_init = { pcursor_do_registration, pcursor_do_reset, pcursor_do_copy }; diff --git a/pcl/pcursor.h b/pcl/pcursor.h deleted file mode 100644 index 95f7924c3..000000000 --- a/pcl/pcursor.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcursor.h - interface to the PCL cursor positioning code */ - -#ifndef pcursor_INCLUDED -#define pcursor_INCLUDED - -#include "gx.h" -#include "pcstate.h" -#include "pcommand.h" - -/* - * Default values for HMI and VMI. The use of -1 for HMI indicates "not set". - */ -#define HMI_DEFAULT -1L -#define VMI_DEFAULT inch2coord(8.0 / 48) - -/* - * Horizontal and vertical cursor movement routines. x and y are in - * centipoints. - * - * NB: absolute vertical positions passed to pcl_set_cap_y are in full - * page direction space, not the "pseudo" page directions space in - * which the pcs->cap is maintained. If passing coordinates in the - * latter space, BE SURE TO SUBTRACT THE CURRENT TOP MARGIN. - */ -void pcl_set_cap_x(P4( - pcl_state_t * pcs, - coord x, /* position or distance */ - bool relative, /* x is distance (else position) */ - bool use_margins /* apply text margins */ -)); - -int pcl_set_cap_y(P5( - pcl_state_t * pcs, - coord y, /* position or distance */ - bool relative, /* y is distance (else position) */ - bool use_margins, /* apply text margins */ - bool by_row /* LF, half LF, or by row */ -)); - -void pcl_do_CR(P1(pcl_state_t * pcs)); -int pcl_do_FF(P1(pcl_state_t * pcs)); -int pcl_do_LF(P1(pcl_state_t * pcs)); -void pcl_home_cursor(P1(pcl_state_t * pcs)); - -/* Get the HMI. This may require recomputing it from the font. */ -coord pcl_updated_hmi(P1(pcl_state_t * pcs)); - -#define pcl_hmi(pcs) \ - ((pcs)->hmi_cp == HMI_DEFAULT ? pcl_updated_hmi(pcs) : (pcs)->hmi_cp) - -extern const pcl_init_t pcursor_init; - -#endif /* pcursor_INCLUDED */ diff --git a/pcl/pcwhtidx.c b/pcl/pcwhtidx.c deleted file mode 100644 index 4a01bc816..000000000 --- a/pcl/pcwhtidx.c +++ /dev/null @@ -1,376 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcwhtidx.c - code to find index of white in a palette */ - -#include "pcstate.h" -#include "pcpalet.h" -#include "pcindxed.h" -#include "pcwhtidx.h" - -/* - * Find the first white point in a palette. If none are found, the palette - * size is returned. - */ - private int -find_first_white( - const byte * ptbl, - int num_entries -) -{ - int i; - - for (i = 0; i < 3 * num_entries; i += 3) { - if ( (ptbl[i] == 255) && (ptbl[i + 1] == 255) && (ptbl[i + 2] == 255)) - break; - } - return i / 3; -} - -/* - * Create a palette index re-map array, assuming that the number of bits per - * pixel divides 8. This allows parallel mapping of multiple pixels. - * - * It is also assumed that ptbl points to a table of at least 256 entries. - */ - private void -build_remap_array8( - byte * pmap, /* existing (general) re-map array */ - int num_entries, /* number of entries in re-map array */ - int b_per_p /* bits per pixel */ -) -{ - byte tmp_map[256]; - int i; - int pix_per_byte = 8 / b_per_p; - uint mask = (1 << b_per_p) - 1; - - /* create the "parallel" mapping table */ - for (i = 0; i < 256; i++) { - int j; - - tmp_map[i] = 0; - for (j = 0; j < pix_per_byte; j++) - tmp_map[i] |= pmap[((i >> (j * b_per_p)) & mask)] << (j * b_per_p); - } - - /* copy into the orignal table */ - memcpy(pmap, tmp_map, 256); -} - -/* - * Create a palette index re-map array, which maps all non-white entries to - * themselves and all white entries to the first white entry. - * - * If for_pattern is true, this code will always create a re-map array if - * (1 << b_per_p) > num_entries, in which case pixel index values larger than - * the palette are possible. A map is necessary in this case so that these - * "out of range" pixel values are interpreted modulo the palette size. The - * map is not necessary for the case of rasters, as for these the actual - * pixel values will never be larger than the palette, even though b_per_p is - * set to 8 in some cases to facilitate subsequent processing. - * - * Returns true if a re-map table formed and remapping is required, false - * otherwise. - */ - private bool -build_remap_array( - const byte * ptbl, - int num_entries, - byte * pmap, - int * pfirst_white, - int b_per_p, - bool for_pattern -) -{ - int first_white; - int second_white; - int map_size = (1 << b_per_p); - bool must_map = (map_size > num_entries); - int i; - - /* limit consideration to those indices that can be achieved */ - if (num_entries > map_size) - num_entries = map_size; - - /* if there is no white and we don't absolutely need a map, quit now */ - first_white = find_first_white(ptbl, num_entries); - *pfirst_white = first_white; - if ((first_white == num_entries) && !must_map) - return false; - - /* get the next white; if no other white, quit if possible */ - second_white = find_first_white( ptbl + 3 * (first_white + 1), - num_entries - first_white - 1 - ) + first_white + 1; - if ((second_white == num_entries) && !must_map) - return false; - - /* build the re-map table */ - for (i = 0; i < second_white; i++) - pmap[i] = i; - pmap[i++] = first_white; - for (; i < map_size; i++) { - int j = i & (num_entries - 1); /* in case map_size > num_entries */ - - if ( (ptbl[3 * j] == 255) && - (ptbl[3 * j + 1] == 255) && - (ptbl[3 * j + 2] == 255) ) - pmap[i] = first_white; - else - pmap[i] = j; - } - - /* check if a special "parallel map" can be used */ - if ( (b_per_p < 8) && - ((8 % b_per_p) == 0) && - (pcl_cs_indexed_palette_size >= 8) ) - build_remap_array8(pmap, num_entries, b_per_p); - - return true; -} - -/* - * Special case for mapping rasters when the number of bits per pixel divides - * 8 (i.e.: there is an integral number of pixels in a byte). In this case - * all pixels within a byte can be mapped at once. - */ - private void -remap_raster_ary8( - const byte * inp, /* array to read from */ - byte * outp, /* array to write to; may be same as inp */ - int npixels, /* number of pixels in raster */ - int b_per_p, /* bits per pixel */ - const byte * pmap /* re-map table */ -) -{ - int nbytes = (npixels * b_per_p) / 8; - - while (nbytes-- > 0) - *outp++ = pmap[*inp++]; -} - -/* - * Remap one raster array into another, using the re-map table provided. The - * two arrays may be the same. - * - * This will work for any number of bits per pixel <= 8. - */ - private void -remap_raster_ary( - const byte * inp, /* array to read from */ - byte * outp, /* array to write to; may be same as inp */ - int npixels, /* number of pixels in raster */ - int b_per_p, /* bits per pixel */ - const byte * pmap /* re-map table */ -) -{ - int nbytes = (npixels * b_per_p + 7) / 8; - ulong mask = (1UL << b_per_p) - 1; - ulong in_accum = 0L; - int in_nbits = 0; - ulong out_accum = 0L; - int out_nbits = 0; - - /* check if the the simpler case can be used */ - if (8 % b_per_p == 0) { - remap_raster_ary8(inp, outp, npixels, b_per_p, pmap); - return; - } - - while (npixels-- > 0) { - int val; - - if (in_nbits < b_per_p) { - while ((nbytes-- > 0) && (in_nbits <= 8 * (sizeof(ulong) - 1))) { - in_accum <<= 8; - in_accum |= *inp++; - in_nbits += 8; - } - } - - val = (in_accum >> (in_nbits - b_per_p)) & mask; - in_accum <<= b_per_p; - in_nbits -= b_per_p; - - out_accum <<= b_per_p; - out_accum |= pmap[val]; - out_nbits += b_per_p; - - if (out_nbits > 8 * sizeof(ulong) - b_per_p) { - while (out_nbits >= 8) { - - *outp++ = (out_accum >> (out_nbits - 8)) & 0xff; - out_nbits -= 8; - out_accum <<= 8; - } - } - } - - while (out_nbits > 0) { - if (out_nbits < 8) - out_accum <<= 8 - out_nbits; - *outp++ = (out_accum >> (out_nbits - 8)) & 0xff; - out_nbits -= 8; - out_accum <<= 8; - } -} - -/* - * Determine the white entry in the color palette of an indexed color space, - * and perform any remapping that is required. - * - * The must_copy operand indicates if the raster data can be overwritten in - * place (false) or if a new array must be allocated. - * - * Colored patterns are always provided at either 1 or 8-bits per pixel. In - * the latter case, the palette size may be smaller than the number of bits - * per pixel. In this case, values should be interpreted modulo the palette - * size. The graphic library does not support such an interpretation, so - * remapping is required at this level. The code in build_remap_ary will detect - * this situation and create a re=-map array even if one is not otherwise - * required. - * - * Returns 0 if successful, < 0 in the event of an error. - */ - int -pcl_cmap_map_raster( - const pcl_cs_indexed_t * pindexed, - int * pfirst_white, - const gs_depth_bitmap * pin_pixinfo, - gs_depth_bitmap * pout_pixinfo, - bool must_copy, - gs_memory_t * pmem -) -{ - byte remap[pcl_cs_indexed_palette_size]; - const byte * pin_rast = 0; - byte * pout_rast = 0; - int pix_depth = pin_pixinfo->pix_depth; - bool fast_mode = ( (pix_depth < 8) && - (8 % pix_depth == 0) ); - int npixels = pin_pixinfo->size.x; - int i; - - /* see if any remapping is necessary */ - *pout_pixinfo = *pin_pixinfo; - if ( !build_remap_array( pindexed->palette.data, - pindexed->num_entries, - remap, - pfirst_white, - pix_depth, - true - ) ) - return 0; - - /* allocate a new raster if necessary (pack scanlines) */ - if (must_copy) { - long nbytes = pin_pixinfo->size.x * pin_pixinfo->pix_depth; - - nbytes = ((nbytes + 7) / 8); - pout_pixinfo->raster = nbytes; - pout_rast = gs_alloc_bytes( pmem, - nbytes * pin_pixinfo->size.y, - "re-map colored pattern raster" - ); - if (pout_rast == 0) - return e_Memory; - pout_pixinfo->data = pout_rast; - - } else - pout_rast = (byte *)pin_pixinfo->data; - - /* remap one scanline at a time */ - pin_rast = pin_pixinfo->data; - for (i = 0; i < pin_pixinfo->size.y; i++) { - if (fast_mode) - remap_raster_ary8(pin_rast, pout_rast, npixels, pix_depth, remap); - else - remap_raster_ary(pin_rast, pout_rast, npixels, pix_depth, remap); - pin_rast += pin_pixinfo->raster; - pout_rast += pout_pixinfo->raster; - } - - return 0; -} - -/* - * Create a re-map array to be used with raster, if inecessary. For such an - * array to be necessary, all of the following must hold: - * - * source transparency on - * pixel encoding is indexed by plane or indexed by pixel - * there is more than one "white" color in the palette - * - * If all of these conditions hold, a point to a remapping array is retuned; - * otherwise a null pointer is returned. The routne pcl_free_remap_ary should - * be used to free this memory. - * - * To simplify processing, data received in the indexed by plane pixel encoding - * format are consolidated into an indexed-by-pixel form with 8 bits/pixel, - * irrespective of the specified number of bits per index (so long as the latter - * number if > 1). This convention can make it appear that (1 << b_per_p) is - * larger than the number of entries in the palette, though no pixel index - * values are ever larger than the palette size. - */ - const void * -pcl_cmap_create_remap_ary( - pcl_state_t * pcs, - int * pfirst_white -) -{ - byte tmp_remap[pcl_cs_indexed_palette_size]; - byte * pmap = 0; - pcl_cs_indexed_t * pindexed = pcs->ppalet->pindexed; - int b_per_p; - - /* if a re-map array might be required, build it on the stack first */ - *pfirst_white = pindexed->num_entries; - - if ( (!pcs->source_transparent && !pcs->pattern_transparent) || - (pcl_cs_indexed_get_encoding(pindexed) > pcl_penc_indexed_by_pixel) ) - return 0; - b_per_p = pcl_cs_indexed_get_bits_per_index(pindexed); - if ( !build_remap_array( pindexed->palette.data, - pindexed->num_entries, - tmp_remap, - pfirst_white, - b_per_p, - false - ) ) - return 0; - - /* a re-mapping array is necessary; copy the temprorary one to the heap */ - pmap = gs_alloc_bytes( pcs->memory, - pcl_cs_indexed_palette_size, - "create PCL raster remapping array" - ); - memcpy(pmap, tmp_remap, pcl_cs_indexed_palette_size); - - return (const void *)pmap; -} - -/* - * Apply the remapping array to one raster scanline. - * - * This routine is normally accessed via the pcl_cmap_apply_remap_ary macro, - * which checks for a null remap array. However, and additional check is - * performed here for safety purposes. Similarly, for rasters it is always - * the case that 8 % bits_per_pixel == 0, but an explicit check is performed - * in any case. - */ - void -pcl_cmap_int_apply_ary( - const void * vpmap, /* remap array pointer */ - byte * prast, /* array of bytes to be mapped */ - int b_per_p, /* bits per pixel */ - int npixels -) -{ - if (8 % b_per_p == 0) - remap_raster_ary8(prast, prast, npixels, b_per_p, (const byte *)vpmap); - else - remap_raster_ary(prast, prast, npixels, b_per_p, (const byte *)vpmap); - -} diff --git a/pcl/pcwhtidx.h b/pcl/pcwhtidx.h deleted file mode 100644 index 595b596de..000000000 --- a/pcl/pcwhtidx.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcwhtindx.c - interface to code for finding white index of a palette */ - -#ifndef pcwhtindx_INCLUDED -#define pcwhtindx_INCLUDED - -#include "gx.h" -#include "gsbitmap.h" -#include "pcindxed.h" - -/* - * To implement transparency in PCL colored patterns and rasters, it is - * necessary to identify those pixels which should be considered white, as - * those are the pixels which should be transparent. - * - * "White" in the sense of PCL means white in the device color space, just - * prior to dithering. Hence, the effect of normalization, color lookup tables, - * and conversion from the source to device color lookup table are taken into - * account before determining if a given pixel is (potentially) transparent. - * - * Such a mechanism is, unfortunately, not easily implemented via the existing - * graphic library, as raster transparency is implemented via PostScript - * ImageType 4 images. For these images, the single color or range of colors - * required that identify pixels as transparent are specified in the source - * color space, before any conversion. - * - * In this implementation, normalization of colors for black and white - * reference points occurs before the raw data is ever considered a color, - * so at least that part of the problem is handled correctly. Beyond this - * canonical white--(1.0, 1.0, 1.0) in all color spaces--is assumed to yield - * white; if it does not (due to color lookup tables), the results will be - * incorrect. - * - * Where appropriate, this implementation also uses the graphic library's - * support for indexed color spaces. Creating potentially transparent rasters - * with these color spaces requires us to identify which entries in the - * color palette are white. When there is only one such entry, this is simple. - * When several palette entries are involved, life is more difficult. It is - * then necessary to remap all raster values which map to a white palette - * entry to the same white entry. - * - * For straight rasters, this is can be done in-place, as the raster will - * never be rendered with another color space. Patterns are not so easily - * handled, as they may be rendered subsequently with other color spaces. - * Hence, for those it is necessary to copy the data. - */ - -/* - * Determine the white entry in the color palette of an indexed color space, - * and perform any remapping that is required. - * - * The must_copy operand indicates if the raster data can be overwritten in - * place (false) or if a new array must be allocated. - * - * Returns 0 if successful, < 0 in the event of an error. - */ -int pcl_cmap_map_raster(P6( - const pcl_cs_indexed_t * pindexed, - int * pfirst_white, - const gs_depth_bitmap * pin_pixinfo, - gs_depth_bitmap * pout_pixinfo, - bool must_copy, - gs_memory_t * pmem -)); - -/* - * An alternative interface to the remapping capability, this one more suited - * to working with rasters. - * - * Because rasters are provided in a large number of pieces (typically one - * sanline is an individual piece), and all pieces are rendered using the - * the same color palette, it does not make sense to re-derive the mapping - * table for each raster. Consequently, the code below can be used to get - * the mapping table once, re-use it for each piece, and then free it. - * - * This code is specifically intended for rasters, and will only create a - * remap table if: - * - * source transparency is required - * the current palette uses an indexed pixel encoding (by plane or - * by pixel) - * there is more than one "white" in the current palette. - * - * Note that the macros for apply and free a remapping array will check for - * a null-pointer inline. Hence, the caller need not provide any other check - * of whether or nor remapping is necessary. - */ -const void * pcl_cmap_create_remap_ary(P2( - pcl_state_t * pcs, - int * pfirst_white -)); - -void pcl_cmap_int_apply_ary(P4( - const void * vpmap, /* remap array pointer */ - byte * prast, /* array of bytes to be mapped */ - int b_per_p, /* bits per pixel */ - int npixels -)); - -#define pcl_cmap_apply_remap_ary(pmap, prast, b_per_p, npixels) \ - BEGIN \ - if ((pmap) != 0) \ - pcl_cmap_int_apply_ary((pmap), (prast), (b_per_p), (npixels)); \ - END - -#define pcl_cmap_free_remap_ary(pmap, pcs) \ - BEGIN \ - if ((pmap) != 0) \ - gs_free_object( (pcs)->memory, \ - (void *)(pmap), \ - "pcl_cmap_free_remap_ary"); \ - END - -#endif /* pcwhtindx_INCLUDED */ diff --git a/pcl/pcxfmst.h b/pcl/pcxfmst.h deleted file mode 100644 index 16f3f09df..000000000 --- a/pcl/pcxfmst.h +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pcxfmst.h - transformation information structures in the PCL state */ - -#ifndef pcxfmst_INCLUDED -#define pcxfmst_INCLUDED - -#include "gx.h" -#include "gsmatrix.h" -#include "gxfixed.h" -#include "pccoord.h" - -/* - * Structure for paper size parameters. Note that these values are all coords - * (centipoints). - */ -typedef struct pcl_paper_size_s { - coord width, height; /* physical page size */ - coord offset_portrait; /* offset of logical page left edge from - * the physical page in portrait orientations */ - coord offset_landscape; /* ditto for landscape orientations */ -} pcl_paper_size_t; - -/* - * Geometric transformation structure for PCL. - * - * Except for GL/2, PCL deals strictly in diagonal transformations: all - * transformations are compositions of 90 degree rotations, scaling, and - * translations. Thus, maintaining a full matrix representation is overkill. - * For the most part, however, any gains in performance from use of a simpler - * representation would be lost due ot the non-general nature of the code, - * so a normal matrix representations and set of matrix operations is used. - * - * Because orientation plays such a significant role in PCL, both the logical - * page orientation and the orientation of the print direction relative to - * the logical page are kept separately, even though this information is - * implicit in the transformations. - * - * For all of the transformations used here, units are centi-points. - * - * For historical reasons, the print direction coordinate system identified by - * the pd2lp_mtx field does not include any translation. Hence the origin of - * of the coordinate space is at the intersection of two logical page boundaries - * (one of which is also a physical page boundary) rather than at the - * intersection of a logical page boundary and the top margin. We term this - * the "pseudo print direction" space. - * - * The page space to device space transformation, which is established by the - * output device, is not kept here. It is the default transformation of the - * graphic state, and thus does not need to be kept separately. This code - * makes the implicit assumption that this transformation matrix is also - * diagonal, which is the case for all reasonable devices. - * - * This structure also maintains a copy of the printable region rectangle in - * logical page space and device space (the latter in gs_fixed_rect format). - * The raster module uses the former to calculate default raster destination - * dimensions and usable raster source dimensions; the latter is needed - * frequently as the clip window must be re-established prior to each object - * printed. - * - * fields: - * - * left_offset_cp left and top offset registrations, in centipoints; - * top_offset_cp these move the logical page on the physica page but - * do not change the logical page size - * - * paper_size pointer to a structure describing the current paper - * size (including logical page offsets) - * - * lp_orient logical page orientation, 0..3 - * - * print_dir print direction (relative to logical page), divided - * by 90 (thus in the range 0..3) - * - * lp2pg_mtx logical page space to page space transformation - * - * lp2dev_mtx logical page to device space transformation; this is - * used as the current matrix in some situations, and - * for conversion of pattern reference points - * - * pd2lp_mtx "pseudo print direction" space to logical page space - * transformation - * - * pd2dev_mtx "pseudo print direction" space to device space - * transformation; the is commonly used as the current - * transformation for PCL objects (other than rasters) - * - * lp_size dimensions of the logical page in logical pace - * space - * - * pd_size dimensions of the logical page in print direction - * space - * - * lp_print_rect printable region rectangle, in logical page space - * - * dev_print_rect printable region rectangle, in device space - */ -typedef struct pcl_xfm_state_s { - - float left_offset_cp; - float top_offset_cp; - - const pcl_paper_size_t * paper_size; - byte lp_orient; - byte print_dir; - - /* the remaining fields are filled in by update_xfm_state() */ - gs_matrix lp2pg_mtx; - gs_matrix lp2dev_mtx; - gs_matrix pd2lp_mtx; - gs_matrix pd2dev_mtx; - - /* height and width of logical page, in centipoints */ - coord_point_t lp_size; - coord_point_t pd_size; - - /* printable region in logical page and device space */ - gs_rect lp_print_rect; - gs_fixed_rect dev_print_rect; - -} pcl_xfm_state_t; - -/* - * Convert a point from "semi print direction" space to logical page space. - */ -#define pcl_xfm_to_logical_page_space(pcs, ppt) \ - gs_point_transform( (ppt)->x, \ - (ppt)->y, \ - &((pcs)->xfm_state.pd2lp_mtx), \ - ppt \ - ) - -/* - * Structure for text region margins. These are all in centipoint relative - * to the current "pseudo print direction" space. - */ -typedef struct pcl_margins_s { - coord left; /* measured from left edge */ - coord right; /* measured from *left* edge */ - coord top; /* measured from top */ - coord length; /* text_length, distance from top to bottom */ -} pcl_margins_t; - -#endif /* pcxfmst_INCLUDED */ diff --git a/pcl/pgchar.c b/pcl/pgchar.c deleted file mode 100644 index 1a19c1cdb..000000000 --- a/pcl/pgchar.c +++ /dev/null @@ -1,512 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgchar.c */ -/* HP-GL/2 font and character commands */ -#include "math_.h" -#include "stdio_.h" /* for gdebug.h */ -#include "gdebug.h" -#include "pcparse.h" -#include "pgmand.h" -#include "pgdraw.h" -#include "pginit.h" -#include "pggeom.h" -#include "pgmisc.h" -#include "pcfsel.h" -#include "pcpalet.h" - -/* ------ Internal procedures ------ */ - -/* Define font parameters (AD, SD). */ -private int -hpgl_font_definition(hpgl_args_t *pargs, hpgl_state_t *pgls, int index) -{ /* - * Since these commands take an arbitrary number of arguments, - * we reset the argument bookkeeping after each group. - * We reset phase to 1, 2, or 3 after seeing the first pair, - * so we can tell whether there were any arguments at all. - * (1 means no parameter changed, >1 means some parameter changed.) - */ - pcl_font_selection_t *pfs = &pgls->g.font_selection[index]; -#define pfp (&pfs->params) - int kind; - pfs->selected_id = 0; - for ( ; hpgl_arg_c_int(pargs, &kind); pargs->phase |= 1 ) - switch ( kind ) - { - case 1: /* symbol set */ - { int32 sset; - if ( !hpgl_arg_int(pargs, &sset) ) - return e_Range; - if ( pfp->symbol_set != (uint)sset ) - pfp->symbol_set = (uint)sset, - pargs->phase |= 2; - } - break; - case 2: /* spacing */ - { int spacing; - if ( !hpgl_arg_c_int(pargs, &spacing) ) - return e_Range; - if ( ((spacing == 1) || (spacing == 0)) && (pfp->proportional_spacing != spacing) ) - pfp->proportional_spacing = spacing, - pargs->phase |= 2; - } - break; - case 3: /* pitch */ - { hpgl_real_t pitch; - if ( !hpgl_arg_c_real(pargs, &pitch) ) - return e_Range; - if ( (pl_fp_pitch_per_inch(pfp) != pitch) && (pitch >= 0) ) - pl_fp_set_pitch_per_inch(pfp, pitch), - pargs->phase |= 2; - } - break; - case 4: /* height */ - { hpgl_real_t height; - if ( !hpgl_arg_c_real(pargs, &height) ) - return e_Range; - if ( (pfp->height_4ths != (uint)(height * 4)) && (height >= 0)) - pfp->height_4ths = (uint)(height * 4), - pargs->phase |= 2; - } - break; - case 5: /* posture */ - { int posture; - if ( !hpgl_arg_c_int(pargs, &posture) ) - return e_Range; - if ( pfp->style != posture ) - pfp->style = posture, - pargs->phase |= 2; - - } - break; - case 6: /* stroke weight */ - { int weight; - if ( !hpgl_arg_c_int(pargs, &weight) ) - return e_Range; - if ( pfp->stroke_weight != weight ) - if ( ((weight >= -7 ) && (weight <= 7)) || (weight == 9999 ) ) - pfp->stroke_weight = weight, - pargs->phase |= 2; - } - break; - case 7: /* typeface */ - { int32 face; - if ( !hpgl_arg_int(pargs, &face) ) - return e_Range; - if ( pfp->typeface_family != (uint)face ) - pfp->typeface_family = (uint)face, - pargs->phase |= 2; - } - break; - default: - return e_Range; - } - /* If there were no arguments at all, default all values. */ - if ( !pargs->phase ) - hpgl_default_font_params(pfs); - if ( pargs->phase != 1 ) - { /* A value changed, or we are defaulting. Decache the font. */ - pfs->font = 0; - if ( index == pgls->g.font_selected ) - pgls->g.font = 0; - } - return 0; -} -/* Define label drawing direction (DI, DR). */ -private int -hpgl_label_direction(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) -{ hpgl_real_t run = 1, rise = 0; - - if ( hpgl_arg_c_real(pargs, &run) ) - { if ( !hpgl_arg_c_real(pargs, &rise) || (run == 0 && rise == 0) ) - return e_Range; - { double hyp = hypot(run, rise); - run /= hyp; - rise /= hyp; - } - } - pgls->g.character.direction.x = run; - pgls->g.character.direction.y = rise; - pgls->g.character.direction_relative = relative; - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* Select font by ID (FI, FN). */ -private int -hpgl_select_font_by_id(hpgl_args_t *pargs, hpgl_state_t *pgls, int index) -{ pcl_font_selection_t *pfs = &pgls->g.font_selection[index]; - int32 id; - int code; - - if ( !hpgl_arg_c_int(pargs, &id) || id < 0 ) - return e_Range; - code = pcl_select_font_by_id(pfs, id, pgls /****** NOTA BENE ******/); - switch ( code ) - { - default: /* error */ - return code; - case 1: /* ID not found, no effect */ - return 0; - case 0: /* ID found */ - break; - } - pgls->g.font = pfs->font; - pgls->g.map = pfs->map; - /* - * If we just selected a bitmap font, force the equivalent of SB1. - * See TRM 23-65 and 23-81. - */ - if ( pfs->font->scaling_technology == plfst_bitmap ) - pgls->g.bitmap_fonts_allowed = true; - return 0; -} - -/* Select font (SA, SS). */ -private int -hpgl_select_font(hpgl_state_t *pgls, int index) -{ - if ( pgls->g.font_selected != index ) - { pgls->g.font_selected = index; - pgls->g.font = pgls->g.font_selection[index].font; - pgls->g.map = pgls->g.font_selection[index].map; - } - return 0; -} - -/* ------ Commands ------ */ - -/* AD [kind,value...]; */ - int -hpgl_AD(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_font_definition(pargs, pgls, 1); -} - -#define CHAR_EDGE_PEN_UNSET -1 - -/* return the current edge pen based on whethere or not the interpreter specifically set the pen */ - int32 -hpgl_get_character_edge_pen( - hpgl_state_t * pgls -) -{ - /* if the character edge pen has not been set then we return the - current pen number, otherwise the state value as set in the CF - command is used. (see hpgl_CF) */ - return (pgls->g.character.edge_pen == CHAR_EDGE_PEN_UNSET ? - hpgl_get_selected_pen(pgls) : - pgls->g.character.edge_pen); - -} - -/* - * CF [mode[,pen]]; - */ - int -hpgl_CF( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int mode = 0; - int npen = pcl_palette_get_num_entries(pgls->ppalet); - int32 pen = 0; - - if (hpgl_arg_c_int(pargs, &mode)) { - if ((mode & ~3) != 0) - return e_Range; - /* With only 1 argument, we "unset" the current pen. This - causes the drawing machinery to use the current pen when - the stroke is rendered (i.e. a subsequent SP will change - the character edge pen */ - if (hpgl_arg_int(pargs, &pen)) { - if ((pen < 0) || (pen >= npen)) - return e_Range; - } else - pen = CHAR_EDGE_PEN_UNSET; - } - pgls->g.character.fill_mode = mode; - pgls->g.character.edge_pen = pen; - return 0; -} - -#undef CHAR_EDGE_PEN_UNSET - -/* DI [run,rise]; */ - int -hpgl_DI(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_label_direction(pargs, pgls, false); -} - -/* DR [run,rise]; */ - int -hpgl_DR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_label_direction(pargs, pgls, true); -} - -/* DT terminator[,mode]; */ - int -hpgl_DT(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ const byte *p = pargs->source.ptr; - const byte *rlimit = pargs->source.limit; - byte ch = (byte)pargs->phase; - int mode = 1; - - /* We use phase to remember the terminator character */ - /* in case we had to restart execution. */ - if ( p >= rlimit ) - return e_NeedData; - if ( !ch ) - switch ( (ch = *++p) ) - { - case ';': - pargs->source.ptr = p; - pgls->g.label.terminator = 3; - pgls->g.label.print_terminator = false; - return 0; - case 0: case 10: case 27: - return e_Range; - default: - if ( p >= rlimit ) - return e_NeedData; - if ( *++p ==',' ) - { pargs->source.ptr = p; - pargs->phase = ch; - } - } - if ( hpgl_arg_c_int(pargs, &mode) && (mode & ~1) ) - return e_Range; - pgls->g.label.terminator = ch; - pgls->g.label.print_terminator = !mode; - return 0; -} - -/* DV [path[,line]]; */ - int -hpgl_DV(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int path = 0, line = 0; - - hpgl_arg_c_int(pargs, &path); - hpgl_arg_c_int(pargs, &line); - if ( (path & ~3) | (line & ~1) ) - return e_Range; - pgls->g.character.text_path = path; - pgls->g.character.line_feed_direction = (line ? -1 : 1); - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* ES [width[,height]]; */ - int -hpgl_ES(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t width = 0, height = 0; - - hpgl_arg_c_real(pargs, &width); - hpgl_arg_c_real(pargs, &height); - pgls->g.character.extra_space.x = width; - pgls->g.character.extra_space.y = height; - return 0; -} - -/* FI fontid; */ - int -hpgl_FI(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_select_font_by_id(pargs, pgls, 0); -} - -/* FN fontid; */ - int -hpgl_FN(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_select_font_by_id(pargs, pgls, 1); -} - -/* The following is an extension documented in the Comparison Guide. */ -/* LM [mode[, row number]]; */ - int -hpgl_LM(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int mode = 0, row_number = 0; - int old_mode = - (pgls->g.label.double_byte ? 1 : 0) + - (pgls->g.label.write_vertical ? 2 : 0); - - hpgl_arg_c_int(pargs, &mode); - hpgl_arg_c_int(pargs, &row_number); - pgls->g.label.row_offset = - (row_number < 0 ? 0 : row_number > 255 ? 255 : row_number) << 8; - mode &= 3; - pgls->g.label.double_byte = (mode & 1) != 0; - pgls->g.label.write_vertical = (mode & 2) != 0; - /* - * The documentation says "When LM switches modes, it turns off - * symbol mode." We take this literally: LM only turns off - * symbol mode if the new label mode differs from the old one. - */ - if ( mode != old_mode ) - pgls->g.symbol_mode = 0; - return 0; -} - -/* LO [origin]; */ - int -hpgl_LO(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int origin = 1; - - hpgl_arg_c_int(pargs, &origin); - if ( origin < 1 || origin == 10 || origin == 20 || origin > 21 ) - return e_Range; - pgls->g.label.origin = origin; - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* SA; */ - int -hpgl_SA(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_select_font(pgls, 1); -} - -/* SB [mode]; */ - int -hpgl_SB(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int mode = 0; - - if ( hpgl_arg_c_int(pargs, &mode) && (mode & ~1) ) - return e_Range; - if ( pgls->g.bitmap_fonts_allowed != mode ) - { int i; - - pgls->g.bitmap_fonts_allowed = mode; - /* - * A different set of fonts is now available for consideration. - * Decache any affected font(s): those selected by parameter, - * and bitmap fonts selected by ID if bitmap fonts are now - * disallowed. - */ - for ( i = 0; i < countof(pgls->g.font_selection); ++i ) - { pcl_font_selection_t *pfs = &pgls->g.font_selection[i]; - if ( !pfs->selected_id || - (!mode && pfs->font != 0 && - pfs->font->scaling_technology == plfst_bitmap) - ) - { pfs->font = 0; - if ( i == pgls->g.font_selected ) - pgls->g.font = 0; - } - } - } - return 0; -} - -/* SD [kind,value...]; */ - int -hpgl_SD(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_font_definition(pargs, pgls, 0); -} - -/* SI [width,height]; */ - int -hpgl_SI(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t width_cm, height_cm; - - if ( hpgl_arg_c_real(pargs, &width_cm) ) - { if ( !hpgl_arg_c_real(pargs, &height_cm) ) - return e_Range; - pgls->g.character.size.x = mm_2_plu(width_cm * 10); - pgls->g.character.size.y = mm_2_plu(height_cm * 10); - pgls->g.character.size_mode = hpgl_size_absolute; - } - else - pgls->g.character.size_mode = hpgl_size_not_set; - return 0; -} - -/* SL [slant]; */ - int -hpgl_SL(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t slant = 0; - - hpgl_arg_c_real(pargs, &slant); - pgls->g.character.slant = slant; - return 0; -} - -/* SR [width,height]; */ - int -hpgl_SR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t width_pct, height_pct; - - if ( hpgl_arg_c_real(pargs, &width_pct) ) - { if ( !hpgl_arg_c_real(pargs, &height_pct) ) - return e_Range; - pgls->g.character.size.x = width_pct / 100; - pgls->g.character.size.y = height_pct / 100; - } - else - { pgls->g.character.size.x = 0.0075; - pgls->g.character.size.y = 0.015; - } - pgls->g.character.size_mode = hpgl_size_relative; - return 0; -} - -/* SS; */ - int -hpgl_SS(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return hpgl_select_font(pgls, 0); -} - -/* TD [mode]; */ - int -hpgl_TD(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int mode = 0; - - if ( hpgl_arg_c_int(pargs, &mode) && (mode & ~1) ) - return e_Range; - pgls->g.transparent_data = mode; - return 0; -} - -/* Initialization */ -private int -pgchar_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem) -{ /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('A', 'D', hpgl_AD, hpgl_cdf_pcl_rtl_both), /* kind/value pairs */ - HPGL_COMMAND('C', 'F', hpgl_CF, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('D', 'I', hpgl_DI, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('D', 'R', hpgl_DR, hpgl_cdf_pcl_rtl_both), - /* DT has special argument parsing, so it must handle skipping */ - /* in polygon mode itself. */ - HPGL_COMMAND('D', 'T', hpgl_DT, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('D', 'V', hpgl_DV, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('E', 'S', hpgl_ES, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('F', 'I', hpgl_FI, hpgl_cdf_pcl), - HPGL_COMMAND('F', 'N', hpgl_FN, hpgl_cdf_pcl), - HPGL_COMMAND('L', 'M', hpgl_LM, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('L', 'O', hpgl_LO, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'A', hpgl_SA, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'B', hpgl_SB, hpgl_cdf_pcl), - HPGL_COMMAND('S', 'D', hpgl_SD, hpgl_cdf_pcl_rtl_both), /* kind/value pairs */ - HPGL_COMMAND('S', 'I', hpgl_SI, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'L', hpgl_SL, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'R', hpgl_SR, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'S', hpgl_SS, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('T', 'D', hpgl_TD, hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -} -const pcl_init_t pgchar_init = { - pgchar_do_registration, 0 -}; diff --git a/pcl/pgcolor.c b/pcl/pgcolor.c deleted file mode 100644 index 7d3a116f6..000000000 --- a/pcl/pgcolor.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgcolor.c - HP-GL/2 color vector graphics commands */ - -#include "std.h" -#include "pcparse.h" -#include "pgmand.h" -#include "pginit.h" -#include "pgmisc.h" -#include "pgdraw.h" -#include "gsstate.h" /* for gs_setfilladjust */ -#include "pcpalet.h" - -/* ------ Commands ------ */ - -/* - * PC [pen[,primary1,primary2,primary3]; - */ - private int -hpgl_PC( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int32 pen; - int32 npen = pcl_palette_get_num_entries(pgls->ppalet); - - /* output any current path */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - if (hpgl_arg_int(pargs, &pen)) { - hpgl_real_t primary[3]; - - if ((pen < 0) || (pen >= npen)) - return e_Range; - - if (hpgl_arg_c_real(pargs, &primary[0])) { - float comps[3]; - - if ( !hpgl_arg_c_real(pargs, &primary[1]) || - !hpgl_arg_c_real(pargs, &primary[2]) ) - return e_Range; - comps[0] = primary[0]; - comps[1] = primary[1]; - comps[2] = primary[2]; - return pcl_palette_set_color(pgls, pen, comps); - } else - return pcl_palette_set_default_color(pgls, pen); - } else { - int i; - int code; - - for (i = 0; i < npen; ++i) { - if ((code = pcl_palette_set_default_color(pgls, i)) < 0) - return code; - } - } - - return 0; -} - -/* - * NP [n]; - */ - int -hpgl_NP( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int32 n = 8; - - /* output any current path */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - if ( hpgl_arg_int(pargs, &n) && ((n < 2) || (n > 32768)) ) - return e_Range; - return pcl_palette_NP(pgls, n); -} - -/* - * CR [b_red, w_red, b_green, w_green, b_blue, w_blue]; - */ - private int -hpgl_CR( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - hpgl_real_t range[6]; - int i; - - /* output any current path */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - range[0] = range[2] = range[4] = 0; - range[1] = range[3] = range[5] = 255; - for (i = 0; (i < 6) && hpgl_arg_c_real(pargs, &range[i]); ++i) - ; - if ( (range[0] == range[1]) || - (range[2] == range[3]) || - (range[4] == range[5]) ) - return e_Range; - return pcl_palette_CR( pgls, - (floatp)range[1], - (floatp)range[3], - (floatp)range[5], - (floatp)range[0], - (floatp)range[2], - (floatp)range[4] - ); -} - -/* - * Initialization. There is no reset or copy command, as those operations are - * carried out by the palette mechanism. - */ - private int -pgcolor_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ -#ifndef PCL5EMONO - /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('C', 'R', hpgl_CR, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('N', 'P', hpgl_NP, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'C', hpgl_PC, hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -#endif -} - -const pcl_init_t pgcolor_init = { pgcolor_do_registration, 0, 0 }; diff --git a/pcl/pgconfig.c b/pcl/pgconfig.c deleted file mode 100644 index 4e7863255..000000000 --- a/pcl/pgconfig.c +++ /dev/null @@ -1,585 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgconfig.c */ -/* HP-GL/2 configuration and status commands */ -#include "gx.h" -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" /* for gscoord.h */ -#include "gscoord.h" -#include "pgmand.h" -#include "pcparse.h" -#include "pgdraw.h" -#include "pginit.h" -#include "pggeom.h" -#include "pgmisc.h" -#include "pcursor.h" -#include "pcpage.h" -#include "pcpalet.h" -#include "pcdraw.h" - -/* contrary to the documentation HP also seems to parse CO.*; as a - legitimate comment as well as a string enclosed in quotation marks. */ -int -hpgl_CO(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ const byte *p = pargs->source.ptr; - const byte *rlimit = pargs->source.limit; - - while ( p < rlimit ) { - if ( !pargs->phase ) { - switch ( *++p ) { - case ' ': - /* Ignore spaces between command and opening ". */ - continue; - case '"': - pargs->phase = 1; - break; - default: - /* Search for semicolon */ - pargs->phase = 2; - break; - - } - } else { - /* Scanning for closing " or closing ';' */ - switch ( pargs->phase ) { - case 1: - if ( *++p == '"' ) { - pargs->source.ptr = p; - return 0; - } - /* syntax error on some hp devices */ - if ( *p == '\\' ) { - pargs->source.ptr = p; - return 0; - } - break; - case 2: - if ( *++p == ';' ) { - pargs->source.ptr = p; - return 0; - } - break; - default: - dprintf( "HPGL CO automata is in an unknown state\n" ); - pargs->source.ptr = p; - return 0; - } - } - } - pargs->source.ptr = p; - return e_NeedData; -} - -/* The part of the DF command applicable for overlay macros */ -void -hpgl_reset_overlay(hpgl_state_t *pgls) -{ hpgl_args_t args; - hpgl_args_setup(&args); - hpgl_AC(&args, pgls); - hpgl_args_setup(&args); - pgls->g.font_selected = 0; - hpgl_AD(&args, pgls); - hpgl_args_setup(&args); - hpgl_SD(&args, pgls); - hpgl_args_setup(&args); - hpgl_CF(&args, pgls); - hpgl_args_setup(&args); - hpgl_args_add_int(&args, 1); - hpgl_args_add_int(&args, 0); - hpgl_DI(&args, pgls); - /* HAS -- Figure out some way to do this so that it is consistant */ - pgls->g.label.terminator = 3; - pgls->g.label.print_terminator = false; - hpgl_args_setup(&args); - hpgl_DV(&args, pgls); - hpgl_args_setup(&args); - hpgl_ES(&args, pgls); - pgls->g.label.write_vertical = false; - pgls->g.label.double_byte = false; - hpgl_args_setup(&args); - hpgl_LM(&args, pgls); - hpgl_args_set_int(&args, 1); - hpgl_LO(&args, pgls); - /* we do this instead of calling SC directly */ - pgls->g.scaling_type = hpgl_scaling_none; - pgls->g.fill_type = hpgl_even_odd_rule; - hpgl_args_set_int(&args,0); - hpgl_PM(&args, pgls); - hpgl_args_set_int(&args,2); - hpgl_PM(&args, pgls); - pgls->g.bitmap_fonts_allowed = 0; - hpgl_args_setup(&args); - hpgl_SI(&args, pgls); - hpgl_args_setup(&args); - hpgl_SL(&args, pgls); - /* We initialize symbol mode directly because hpgl_SM parses - its argument differently than most other commands */ - pgls->g.symbol_mode = 0; - hpgl_args_setup(&args); - hpgl_SS(&args, pgls); - hpgl_args_set_int(&args,1); - hpgl_TR(&args, pgls); - hpgl_args_setup(&args); - hpgl_TD(&args, pgls); - hpgl_args_setup(&args); - hpgl_MC(&args, pgls); -#ifdef LJ6_COMPAT - /* LJ6 seems to reset PP with an IN command the Color Laserjet - does not. NB this needs to be handled with dynamic - configuration */ - hpgl_args_setup(&args); - hpgl_PP(&args, pgls); -#endif -} - -/* DF; sets programmable features except P1 and P2 */ -int -hpgl_DF(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_args_t args; - hpgl_reset_overlay(pgls); - - hpgl_args_setup(&args); - hpgl_FT(&args, pgls); - hpgl_args_setup(&args); - hpgl_IW(&args, pgls); - hpgl_args_setup(&args); - hpgl_LA(&args, pgls); - hpgl_set_line_pattern_defaults(pgls); - hpgl_args_setup(&args); - hpgl_RF(&args, pgls); - hpgl_args_setup(&args); - hpgl_SV(&args, pgls); - hpgl_args_setup(&args); - hpgl_UL(&args, pgls); - return 0; -} - -/* - * The "implicit" portion of the IN command. - * - * With the advent of PCL 5c, both PCL and GL want to reset the current - * palette. The difficulty is that they want to reset it to different things. - * - * The proper way to handle this would be to implement IN as a reset type, - * create a single palette reset routine, and have it do different things - * depending on the nature of the reset. - * - * At the time this comment was written, such a change was larger than could - * be easily accommodated. Hence, a less drastic alternative was employed: - * split the IN command into implicit and explicit portions, and only use the - * latter when the IN command is explicitly invoked. - */ - int -hpgl_IN_implicit( - hpgl_state_t * pgls\ -) -{ - hpgl_args_t args; - - /* cancel rotation */ - pgls->g.rotation = 0; - /* restore defaults */ - hpgl_DF(&args, pgls); - - /* defaults P1 and P2 */ - hpgl_args_setup(&args); - hpgl_IP(&args, pgls); - hpgl_args_set_int(&args,1); - hpgl_SP(&args, pgls); - - /* pen width units - metric */ - hpgl_args_setup(&args); - hpgl_WU(&args, pgls); - - - /* - * pen up-absolute position and set gl/2 current positon to - * 0,0 or the lower left of the picture frame. Simply sets - * the gl/2 state, we subsequently clear the path because we - * do not want to create a live gs path. - */ - hpgl_args_set_real2(&args, 0.0, 0.0); - hpgl_PU(&args, pgls); - hpgl_args_set_real2(&args, 0.0, 0.0); - hpgl_PA(&args, pgls); - hpgl_call(hpgl_clear_current_path(pgls)); - - return 0; -} - -/* - * IN = DF (see below) - */ - int -hpgl_IN( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int code = 0; - - /* handle the work or an implicit reset */ - code = hpgl_IN_implicit(pgls); - - /* set up the default palette (8 entries, not-fixed) */ - if (code == 0) - code = pcl_palette_IN(pgls); - return code; -} - -/* derive the current picture frame coordinates */ - - private int -hpgl_picture_frame_coords(hpgl_state_t *pgls, gs_int_rect *gl2_win) -{ - gs_rect dev_win; /* device window */ - hpgl_real_t x1 = pgls->g.picture_frame.anchor_point.x; - hpgl_real_t y1 = pgls->g.picture_frame.anchor_point.y; - hpgl_real_t x2 = x1 + pgls->g.picture_frame_width; - hpgl_real_t y2 = y1 + pgls->g.picture_frame_height; - - pcl_set_ctm(pgls, false); - hpgl_call(gs_transform(pgls->pgs, x1, y1, &dev_win.p)); - hpgl_call(gs_transform(pgls->pgs, x2, y2, &dev_win.q)); - hpgl_call(hpgl_set_plu_ctm(pgls)); - /* - * gs_bbox_transform_inverse puts the resulting points in the - * correct order, with p < q. - */ - { gs_matrix mat; - gs_rect pcl_win; /* pcl window */ - - gs_currentmatrix(pgls->pgs, &mat); - hpgl_call(gs_bbox_transform_inverse(&dev_win, &mat, &pcl_win)); -/* Round all coordinates to the nearest integer. */ -#define set_round(e) gl2_win->e = (int)floor(pcl_win.e + 0.5) - set_round(p.x); - set_round(p.y); - set_round(q.x); - set_round(q.y); -#undef set_round - } - /* restore the ctm */ - hpgl_call(hpgl_set_ctm(pgls)); - return 0; -} - -/* IP p1x,p1y[,p2x,p2y]; */ -/* IP; */ -int -hpgl_IP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int32 ptxy[4]; - int i; - gs_int_rect win; - - /* draw the current path */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - /* get the default picture frame coordinates */ - hpgl_call(hpgl_picture_frame_coords(pgls, &win)); - - /* round the picture frame coordinates */ - ptxy[0] = win.p.x; ptxy[1] = win.p.y; - ptxy[2] = win.q.x; ptxy[3] = win.q.y; - for ( i = 0; i < 4 && hpgl_arg_int(pargs, &ptxy[i]); ++i ) - ; - if ( i & 1 ) - return e_Range; - - if ( i == 2 ) - { - pgls->g.P2.x = (ptxy[0] - pgls->g.P1.x) + - pgls->g.P2.x; - pgls->g.P2.y = (ptxy[1] - pgls->g.P1.y) + - pgls->g.P2.y; - pgls->g.P1.x = ptxy[0]; - pgls->g.P1.y = ptxy[1]; - } - else - { - pgls->g.P1.x = ptxy[0]; - pgls->g.P1.y = ptxy[1]; - pgls->g.P2.x = ptxy[2]; - pgls->g.P2.y = ptxy[3]; - } - - /* if either coordinate is equal it is incremented by 1 */ - if ( pgls->g.P1.x == pgls->g.P2.x ) pgls->g.P2.x++; - if ( pgls->g.P1.y == pgls->g.P2.y ) pgls->g.P2.y++; - - return 0; -} - -/* IR r1x,r1y[,r2x,r2y]; */ -/* IR; */ -int -hpgl_IR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t rptxy[4]; - int i; - hpgl_args_t args; - gs_int_rect win; - - for ( i = 0; i < 4 && hpgl_arg_c_real(pargs, &rptxy[i]); ++i ) - ; - if ( i & 1 ) - return e_Range; - - /* get the PCL picture frame coordinates */ - hpgl_call(hpgl_picture_frame_coords(pgls, &win)); - hpgl_args_setup(&args); - hpgl_args_add_int(&args, win.p.x + (win.q.x - win.p.x) * - rptxy[0] / 100.0); - - hpgl_args_add_int(&args, win.p.y + (win.q.y - win.p.y) * - rptxy[1] / 100.0); - - if ( i == 4 ) - { - hpgl_args_add_int(&args, win.p.x + (win.q.x - win.p.x) * - rptxy[2] / 100.0); - - hpgl_args_add_int(&args, win.p.y + (win.q.y - win.p.y) * - rptxy[3] / 100.0); - } - hpgl_IP( &args, pgls ); - return 0; -} - -/* IW llx,lly,urx,ury; */ -/* IW; */ -int -hpgl_IW(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t wxy[4]; - int i; - gs_int_rect win; - - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - /* get the default picture frame coordinates. */ - hpgl_call(hpgl_picture_frame_coords(pgls, &win)); - wxy[0] = win.p.x; - wxy[1] = win.p.y; - wxy[2] = win.q.x; - wxy[3] = win.q.y; - for ( i = 0; i < 4 && hpgl_arg_units(pargs, &wxy[i]); ++i ) - ; - if ( i & 3 ) - return e_Range; - - /* no args case disables the soft clip window */ - if ( i == 0 ) { - pgls->g.soft_clip_window.state = inactive; - return 0; - } - /* HAS needs error checking */ - pgls->g.soft_clip_window.rect.p.x = wxy[0]; - pgls->g.soft_clip_window.rect.p.y = wxy[1]; - pgls->g.soft_clip_window.rect.q.x = wxy[2]; - pgls->g.soft_clip_window.rect.q.y = wxy[3]; - pgls->g.soft_clip_window.state = active; - return 0; -} - -/* PG; */ -int -hpgl_PG(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - if ( pgls->personality == rtl ) { - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - hpgl_call(pcl_do_FF(pgls)); - } - return 0; -} - -/* PS; NB this is only a partial implementation. */ -int -hpgl_PS(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_real_t page_dims[2]; - /* we use the pcl paper handling machinery to set the plot size */ - pcl_paper_size_t paper; - int i; - - if ( pgls->personality != rtl ) - return 0; - for ( i = 0; i < 2 && hpgl_arg_real(pargs, &page_dims[i]); ++i ) - ; /* NOTHING */ - if ( i != 2 ) - return e_Range; - paper.height = plu_2_coord(page_dims[0]); - paper.width = plu_2_coord(page_dims[1]); - paper.offset_portrait = 0; - paper.offset_landscape = 0; - new_logical_page(pgls, 0, &paper, false); - return 0; -} - -/* RO angle; */ -/* RO; */ -int -hpgl_RO(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - int angle=0; - gs_point point, dev_pt; - - /* this business is used by both SC and RO -- perhaps it needs - a new home */ - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(hpgl_get_current_position(pgls, &point)); - hpgl_call(gs_transform(pgls->pgs, point.x, point.y, &dev_pt)); - - if ( hpgl_arg_c_int(pargs, &angle) ) - switch ( angle ) - { - case 0: case 90: case 180: case 270: - break; - default: - return e_Range; - } - - if ( angle != pgls->g.rotation ) - { - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.rotation = angle; - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); - hpgl_call(hpgl_set_current_position(pgls, &point)); - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - } - return 0; -} - -/* RP; */ -int -hpgl_RP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return e_Unimplemented; -} - -/* SC xmin,xmax,ymin,ymax[,type=0]; */ -/* SC xmin,xmax,ymin,ymax,type=1[,left,bottom]; */ -/* SC xmin,xfactor,ymin,yfactor,type=2; */ -/* SC; */ -int -hpgl_SC(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t xy[4]; - int i; - int type; - hpgl_scaling_params_t scale_params; - gs_point point, dev_pt, dev_anchor; - - scale_params = pgls->g.scaling_params; - /* we have to save the real position of the current point and - anchor corner. Convert each to device space, set up the - new transformation and convert stored device coordinates to - user space at the end of the routine. */ - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(hpgl_get_current_position(pgls, &point)); - hpgl_call(gs_transform(pgls->pgs, point.x, point.y, &dev_pt)); - hpgl_call(gs_transform(pgls->pgs, pgls->g.anchor_corner.x, - pgls->g.anchor_corner.y, &dev_anchor)); - for ( i = 0; i < 4 && hpgl_arg_real(pargs, &xy[i]); ++i ) - ; - switch ( i ) - { - case 0: /* set defaults */ - type = hpgl_scaling_none; - break; - default: - return e_Range; - case 4: - type = hpgl_scaling_anisotropic; - hpgl_arg_c_int(pargs, &type); - switch ( type ) - { - case hpgl_scaling_anisotropic: /* 0 */ - if ( xy[0] == xy[1] || xy[2] == xy[3] ) - return e_Range; -pxy: scale_params.pmin.x = xy[0]; - scale_params.pmax.x = xy[1]; - scale_params.pmin.y = xy[2]; - scale_params.pmax.y = xy[3]; - break; - case hpgl_scaling_isotropic: /* 1 */ - if ( xy[0] == xy[1] || xy[2] == xy[3] ) - return e_Range; - { hpgl_real_t left = 50, bottom = 50; - if ( (hpgl_arg_c_real(pargs, &left) && - (left < 0 || left > 100 || - !hpgl_arg_c_real(pargs, &bottom) || - bottom < 0 || bottom > 100)) - ) - return e_Range; - scale_params.left = left; - scale_params.bottom = bottom; - } - goto pxy; - case hpgl_scaling_point_factor: /* 2 */ - if ( xy[1] == 0 || xy[3] == 0 ) - return e_Range; - scale_params.pmin.x = xy[0]; - scale_params.factor.x = xy[1]; - scale_params.pmin.y = xy[2]; - scale_params.factor.y = xy[3]; - break; - default: - return e_Range; - } - } - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.scaling_params = scale_params; - pgls->g.scaling_type = type; - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); - hpgl_call(hpgl_set_current_position(pgls, &point)); - hpgl_call(gs_itransform(pgls->pgs, dev_anchor.x, dev_anchor.y, - &pgls->g.anchor_corner)); - - /* PCLTRM 23-7 (commands the update cr position) does not list - SC but PCL updates the position */ - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* BP - BreakPoint - add this to the HPGL stream and set a breakpoint - on this function. This function is only defined for debugging - system. */ -#ifdef DEBUG - private int -hpgl_BP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - return 0; -} -#endif - -/* Initialization */ -private int -pgconfig_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_HPGL_COMMANDS - /* CO has special argument parsing, so it must handle skipping */ - /* in polygon mode itself. */ - HPGL_COMMAND('C', 'O', hpgl_CO, hpgl_cdf_polygon | hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('D', 'F', hpgl_DF, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('I', 'N', hpgl_IN, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('I', 'P', hpgl_IP, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('I', 'R', hpgl_IR, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('I', 'W', hpgl_IW, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'G', hpgl_PG, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'S', hpgl_PS, hpgl_cdf_rtl), - HPGL_COMMAND('R', 'O', hpgl_RO, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('R', 'P', hpgl_RP, hpgl_cdf_rtl), - HPGL_COMMAND('S', 'C', hpgl_SC, hpgl_cdf_pcl_rtl_both), -#ifdef DEBUG - HPGL_COMMAND('B', 'P', hpgl_BP, hpgl_cdf_pcl_rtl_both), -#endif - END_HPGL_COMMANDS - return 0; -} -const pcl_init_t pgconfig_init = { - pgconfig_do_registration, 0 -}; diff --git a/pcl/pgdraw.c b/pcl/pgdraw.c deleted file mode 100644 index e66084ea5..000000000 --- a/pcl/pgdraw.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgdraw.c - HP-GL/2 line drawing/path building routines. */ - -#include "stdio_.h" -#include "math_.h" -#include "gdebug.h" -#include "gstypes.h" /* for gsstate.h */ -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" -#include "gscoord.h" -#include "gspath.h" -#include "gspaint.h" -#include "gsrop.h" /* for gs_setrasterop */ -#include "gxfarith.h" /* for sincos */ -#include "gxfixed.h" -#include "pgmand.h" -#include "pgdraw.h" -#include "pggeom.h" -#include "pgmisc.h" -#include "pcdraw.h" -#include "pcpalet.h" -#include "pcpatrn.h" - - -/* hack to quiet compiler warnings */ -#ifndef abs -extern int abs( int ); -#endif - -#define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) - - int -hpgl_set_picture_frame_scaling(hpgl_state_t *pgls) -{ - if ( (pgls->g.picture_frame_height == 0) || - (pgls->g.picture_frame_width == 0) || - (pgls->g.plot_width == 0) || - (pgls->g.plot_height == 0) ) { - dprintf("bad picture frame coordinates\n"); - return 0; - } else { - hpgl_real_t vert_scale = (pgls->g.plot_size_vertical_specified) ? - ((hpgl_real_t)pgls->g.picture_frame_height / - (hpgl_real_t)pgls->g.plot_height) : - 1.0; - hpgl_real_t horz_scale = (pgls->g.plot_size_horizontal_specified) ? - ((hpgl_real_t)pgls->g.picture_frame_width / - (hpgl_real_t)pgls->g.plot_width) : - 1.0; - hpgl_call(gs_scale(pgls->pgs, horz_scale, vert_scale)); - } - return 0; - -} - -/* ctm to translate from pcl space to plu space */ - int -hpgl_set_pcl_to_plu_ctm(hpgl_state_t *pgls) -{ - hpgl_call(pcl_set_ctm(pgls, false)); - if ( pgls->personality == rtl ) { - /* for plot length > width, y increases across the short - edge and x increases down the plot. Rotate the pcl - coordinate system -90, scale and flip the x axis. If - the plot width > length the origin is in the upper - right and x increases going to the left and y increases - going down. Translate the pcl coordinate system by the - picture frame width, scale and flip x. */ - if ( pgls->g.picture_frame_height > pgls->g.picture_frame_width ) - hpgl_call(gs_rotate(pgls->pgs, -90)); - else - hpgl_call(gs_translate(pgls->pgs, pgls->g.picture_frame_width, 0)); - hpgl_call(gs_scale(pgls->pgs, -(7200.0/1016.0), (7200.0/1016.0))); - } else { - hpgl_call(gs_translate(pgls->pgs, - pgls->g.picture_frame.anchor_point.x, - pgls->g.picture_frame.anchor_point.y)); - /* move the origin */ - hpgl_call(gs_translate(pgls->pgs, 0, pgls->g.picture_frame_height)); - /* scale to plotter units and a flip for y */ - hpgl_call(gs_scale(pgls->pgs, (7200.0/1016.0), -(7200.0/1016.0))); - /* account for rotated coordinate system */ - } - hpgl_call(gs_rotate(pgls->pgs, pgls->g.rotation)); - { - hpgl_real_t fw_plu = (coord_2_plu(pgls->g.picture_frame_width)); - hpgl_real_t fh_plu = (coord_2_plu(pgls->g.picture_frame_height)); - switch (pgls->g.rotation) - { - case 0 : - hpgl_call(gs_translate(pgls->pgs, 0, 0)); - break; - case 90 : - hpgl_call(gs_translate(pgls->pgs, 0, -fw_plu)); - break; - case 180 : - hpgl_call(gs_translate(pgls->pgs, -fw_plu, -fh_plu)); - break; - case 270 : - hpgl_call(gs_translate(pgls->pgs, -fh_plu, 0)); - break; - } - } - hpgl_call(hpgl_set_picture_frame_scaling(pgls)); - { - gs_matrix mat; - gs_currentmatrix(pgls->pgs, &mat); - mat.ty = floor(mat.ty); mat.tx = floor(mat.tx); - gs_setmatrix(pgls->pgs, &mat); - } - hpgl_call(gs_setdotorientation(pgls->pgs)); - return 0; -} - -/* Set the CTM to map PLU to device units, regardless of scaling. */ -/* (We need this for labels when scaling is on.) */ - int -hpgl_set_plu_ctm(hpgl_state_t *pgls) -{ - hpgl_call(hpgl_set_pcl_to_plu_ctm(pgls)); - return 0; -} - -/* The CTM maps PLU to device units; adjust it to handle scaling, if any. */ - int -hpgl_compute_user_units_to_plu_ctm(const hpgl_state_t *pgls, gs_matrix *pmat) -{ floatp origin_x = pgls->g.P1.x, origin_y = pgls->g.P1.y; - - switch ( pgls->g.scaling_type ) - { - case hpgl_scaling_none: - gs_make_identity(pmat); - break; - case hpgl_scaling_point_factor: - hpgl_call(gs_make_translation(origin_x, origin_y, pmat)); - hpgl_call(gs_matrix_scale(pmat, pgls->g.scaling_params.factor.x, - pgls->g.scaling_params.factor.y, pmat)); - hpgl_call(gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, - -pgls->g.scaling_params.pmin.y, pmat)); - break; - default: - /*case hpgl_scaling_anisotropic:*/ - /*case hpgl_scaling_isotropic:*/ - { - floatp window_x = pgls->g.P2.x - origin_x, - range_x = pgls->g.scaling_params.pmax.x - - pgls->g.scaling_params.pmin.x, - scale_x = window_x / range_x; - floatp window_y = pgls->g.P2.y - origin_y, - range_y = pgls->g.scaling_params.pmax.y - - pgls->g.scaling_params.pmin.y, - scale_y = window_y / range_y; - - if ( pgls->g.scaling_type == hpgl_scaling_isotropic ) - { if ( scale_x > scale_y ) - { /* Reduce the X scaling. */ - origin_x += range_x * (scale_x - scale_y) * - (pgls->g.scaling_params.left / 100.0); - scale_x = scale_y; - } - else if ( scale_y > scale_x ) - { /* Reduce the Y scaling. */ - origin_y += range_y * (scale_y - scale_x) * - (pgls->g.scaling_params.bottom / 100.0); - scale_y = scale_x; - } - } - /* looks like HP keeps 5 decimal digits of accuracy - here. This was derived empirically */ - scale_x -= fmod(scale_x, 1.0E-5); - scale_y -= fmod(scale_y, 1.0E-5); - hpgl_call(gs_make_translation(origin_x, origin_y, pmat)); - hpgl_call(gs_matrix_scale(pmat, scale_x, scale_y, pmat)); - hpgl_call(gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, - -pgls->g.scaling_params.pmin.y, pmat)); - break; - } - } - return 0; - -} - int -hpgl_set_user_units_to_plu_ctm(const hpgl_state_t *pgls) -{ - if ( pgls->g.scaling_type != hpgl_scaling_none ) - { - gs_matrix mat; - - hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - hpgl_call(gs_concat(pgls->pgs, &mat)); - } - return 0; -} - -/* set up ctm's. Uses the current render mode to figure out which ctm - is appropriate */ - int -hpgl_set_ctm(hpgl_state_t *pgls) -{ - hpgl_call(hpgl_set_plu_ctm(pgls)); - hpgl_call(hpgl_set_user_units_to_plu_ctm(pgls)); - return 0; -} - - private int -hpgl_get_line_pattern_length(hpgl_state_t *pgls) -{ - return ((pgls->g.line.current.pattern_length_relative == 0) ? - ((pgls->g.line.current.pattern_length / 100.0) * - hpgl_compute_distance(pgls->g.P1.x, - pgls->g.P1.y, - pgls->g.P2.x, - pgls->g.P2.y)) : - (mm_2_plu(pgls->g.line.current.pattern_length))); -} - - private int -hpgl_set_graphics_dash_state(hpgl_state_t *pgls) -{ - int entry = abs(pgls->g.line.current.type); - bool adaptive; - const hpgl_line_type_t *pat; - float length; - float pattern[20]; - float offset; - int count; - int i; - - /* Make sure we always draw dots. */ - hpgl_call(gs_setdotlength(pgls->pgs, 0.00098, true)); - - /* handle the simple case (no dash) and return */ - if ( pgls->g.line.current.is_solid ) - { - /* use a 0 count pattern to turn off dashing in case it is - set */ - hpgl_call(gs_setdash(pgls->pgs, pattern, 0, 0)); - return 0; - } - - if ( entry == 0 ) - { - /* dot length NOTE this is in absolute 1/72" units not - user space */ - /* Use an adaptive pattern with an infinitely long segment length - to get the dots drawn just at the ends of lines. */ - pattern[0] = 0; - pattern[1] = 1.0e6; /* "infinity" */ - hpgl_call(gs_setdash(pgls->pgs, pattern, 2, 0)); - gs_setdashadapt(pgls->pgs, true); - return 0; - } - - adaptive = ( pgls->g.line.current.type < 0 ); - pat = ((adaptive) ? - (&pgls->g.adaptive_line_type[entry - 1]) : - (&pgls->g.fixed_line_type[entry - 1])); - - length = hpgl_get_line_pattern_length(pgls); - gs_setdashadapt(pgls->pgs, adaptive); - /* - * The graphics library interprets odd pattern counts differently - * from GL: if the pattern count is odd, we need to do something - * a little special. - */ - count = pat->count; - for ( i = 0; i < count; i++ ) - pattern[i] = length * pat->gap[i]; - offset = pgls->g.line.current.pattern_offset * hpgl_get_line_pattern_length(pgls); - if ( count & 1 ) - { - /* - * Combine the last gap with the first one, and change the - * offset to compensate. NOTE: this doesn't work right with - * adaptive line type: we may need to change the library to - * make this work properly. - */ - --count; - pattern[0] += pattern[count]; - offset += pattern[count]; - } - - hpgl_call(gs_setdash(pgls->pgs, pattern, count, offset)); - - return 0; -} - -/* catch pen not being in the palette */ - int -hpgl_get_selected_pen(hpgl_state_t *pgls) -{ - /* get the current pen */ - int pen = pgls->g.pen.selected; - /* 0 is the first pen */ - int max_pen = pcl_palette_get_num_entries(pgls->ppalet) - 1; - /* this is bad */ - if ( pen < 0 ) - pen = -pen; - /* try to recover if necessary */ - while ( pen > max_pen ) - pen = pen - max_pen; - return pen; -} - -/* - * set up joins, caps, miter limit, and line width - */ - private int -hpgl_set_graphics_line_attribute_state( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - const gs_line_cap cap_map[] = { gs_cap_butt, /* 0 not supported */ - gs_cap_butt, /* 1 butt end */ - gs_cap_square, /* 2 square end */ - gs_cap_triangle, /* 3 triag. end */ - gs_cap_round /* 4 round cap */ - }; - - const gs_line_join join_map[] = { gs_join_none, /* 0 not supported */ - gs_join_miter, /* 1 mitered */ - gs_join_miter, /* 2 mitrd/bevld */ - gs_join_triangle, /* 3 triag. join */ - gs_join_round, /* 4 round join */ - gs_join_bevel, /* 5 bevel join */ - gs_join_none /* 6 no join */ - }; - const float * widths = pcl_palette_get_pen_widths(pgls->ppalet); - floatp pen_wid = widths[hpgl_get_selected_pen(pgls)]; - - gs_setfilladjust(pgls->pgs, 0.5, 0.5); - - /* - * HP appears to use default line attributes if the the pen - * width is less than or equal to .35mm or 14.0 plu. This - * is not documented PCLTRM. Pen widths are maintained in - * plotter units - */ - if ( render_mode != hpgl_rm_character && pen_wid <= 14.0 ) { - hpgl_call(gs_setlinejoin(pgls->pgs, gs_join_miter)); - hpgl_call(gs_setlinecap(pgls->pgs, gs_cap_butt)); - hpgl_call(gs_setlinewidth(pgls->pgs, pen_wid)); - hpgl_call(gs_setmiterlimit(pgls->pgs, 5.0)); - return 0; - } - - switch (render_mode) { - - case hpgl_rm_character: - case hpgl_rm_polygon: - case hpgl_rm_clip_and_fill_polygon: - hpgl_call(gs_setlinejoin(pgls->pgs, gs_join_round)); - hpgl_call(gs_setlinecap(pgls->pgs, gs_cap_round)); - break; - - case hpgl_rm_vector_fill: - case hpgl_rm_vector: -vector: - hpgl_call(gs_setlinejoin(pgls->pgs, join_map[pgls->g.line.join])); - hpgl_call(gs_setlinecap(pgls->pgs, cap_map[pgls->g.line.cap])); - hpgl_call(gs_setlinewidth(pgls->pgs, pen_wid)); - break; - - default: - /* shouldn't happen; we must have a mode to properly parse hpgl file. */ - dprintf("warning no hpgl rendering mode set using vector mode\n"); - goto vector; - } - -#ifdef COMMENT - /* I do not remember the rational for the large miter */ - hpgl_call(gs_setmiterlimit( pgls->pgs, - (pgls->g.line.join == 1) - ? 5000.0 - : pgls->g.miter_limit - ) ); -#endif - hpgl_call(gs_setmiterlimit(pgls->pgs, pgls->g.miter_limit)); - return 0; -} - -/* - * A bounding box for the current polygon -- used for HPGL/2 vector - * fills. - */ - private int -hpgl_polyfill_bbox( - hpgl_state_t * pgls, - gs_rect * bbox -) -{ - /* get the bounding box for the current path / polygon */ - hpgl_call(gs_pathbbox(pgls->pgs, bbox)); - return 0; -} - -/* set up an hpgl clipping region -- intersection of IW command and - picture frame. */ - int -hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) -{ - /* if we are doing vector fill a clipping path has already - been set up using the last polygon */ - if ( render_mode == hpgl_rm_vector_fill ) - return 0; - else - { - gs_fixed_rect fixed_box; - gs_rect pcl_clip_box; - gs_rect dev_clip_box; - gs_matrix save_ctm; - gs_matrix pcl_ctm; - - /* get pcl to device ctm and restore the current ctm */ - hpgl_call(gs_currentmatrix(pgls->pgs, &save_ctm)); - hpgl_call(pcl_set_ctm(pgls, false)); - hpgl_call(gs_currentmatrix(pgls->pgs, &pcl_ctm)); - hpgl_call(gs_setmatrix(pgls->pgs, &save_ctm)); - /* find the clipping region defined by the picture frame - which is defined in pcl coordinates */ - pcl_clip_box.p.x = pgls->g.picture_frame.anchor_point.x; - pcl_clip_box.p.y = pgls->g.picture_frame.anchor_point.y; - pcl_clip_box.q.x = pcl_clip_box.p.x + pgls->g.picture_frame_width; - pcl_clip_box.q.y = pcl_clip_box.p.y + pgls->g.picture_frame_height; - - hpgl_call(gs_bbox_transform(&pcl_clip_box, - &pcl_ctm, - &dev_clip_box)); - /* the clip box defined by the picture frame appears to be - open and the clip box defined by IW is closed */ - dev_clip_box.q.x += 1.0; - dev_clip_box.q.y += 1.0; - if ( gs_debug_c('P') ) - dprintf4("gl/2 device picture frame: p.x=%f p.y=%f q.x=%f q.y=%f\n", - dev_clip_box.p.x, dev_clip_box.p.y, - dev_clip_box.q.x, dev_clip_box.q.y); - /* if the clipping window is active calculate the new clip - box derived from IW and the intersection of the device - space boxes replace the current box. Note that IW - coordinates are in current units and and the picture - frame in pcl coordinates. */ - if ( pgls->g.soft_clip_window.state == active ) { - gs_rect dev_soft_window_box; - gs_matrix ctm; - hpgl_call(gs_currentmatrix(pgls->pgs, &ctm)); - hpgl_call(gs_bbox_transform(&pgls->g.soft_clip_window.rect, - &ctm, - &dev_soft_window_box)); - dev_clip_box.p.x = max(dev_clip_box.p.x, dev_soft_window_box.p.x); - dev_clip_box.p.y = max(dev_clip_box.p.y, dev_soft_window_box.p.y); - dev_clip_box.q.x = min(dev_clip_box.q.x, dev_soft_window_box.q.x); - dev_clip_box.q.y = min(dev_clip_box.q.y, dev_soft_window_box.q.y); - if ( gs_debug_c('P') ) { - dprintf4("gl/2 window user units: p.x=%f p.y=%f q.x=%f q.y=%f\n", - pgls->g.soft_clip_window.rect.p.x, - pgls->g.soft_clip_window.rect.p.y, - pgls->g.soft_clip_window.rect.q.x, - pgls->g.soft_clip_window.rect.q.y); - dprintf4("gl/2 device soft clip region: p.x=%f p.y=%f q.x=%f q.y=%f\n", - dev_soft_window_box.p.x, dev_soft_window_box.p.y, - dev_soft_window_box.q.x, dev_soft_window_box.q.y); - } - } - /* convert intersection box to fixed point and clip */ - fixed_box.p.x = float2fixed(floor(dev_clip_box.p.x)); - fixed_box.p.y = float2fixed(floor(dev_clip_box.p.y)); - fixed_box.q.x = float2fixed(ceil(dev_clip_box.q.x)); - fixed_box.q.y = float2fixed(ceil(dev_clip_box.q.y)); - /* intersect with pcl clipping region */ - fixed_box.p.x = max(fixed_box.p.x, pgls->xfm_state.dev_print_rect.p.x); - fixed_box.p.y = max(fixed_box.p.y, pgls->xfm_state.dev_print_rect.p.y); - fixed_box.q.x = min(fixed_box.q.x, pgls->xfm_state.dev_print_rect.q.x); - fixed_box.q.y = min(fixed_box.q.y, pgls->xfm_state.dev_print_rect.q.y); - if ( gs_debug_c('P') ) { - gs_matrix mat; - dprintf4("gl/2 device clip region: p.x=%f p.y=%f q.x=%f q.y=%f\n", - fixed2float(fixed_box.p.x), fixed2float(fixed_box.p.y), - fixed2float(fixed_box.q.x), fixed2float(fixed_box.q.y)); - gs_make_identity(&mat); - hpgl_gsave(pgls); - gs_setmatrix(pgls->pgs, &mat); - gs_setgray(pgls->pgs, 0); - gs_newpath(pgls->pgs); - gs_setlinewidth(pgls->pgs, 0); - gs_moveto(pgls->pgs, fixed2float(fixed_box.p.x), - fixed2float(fixed_box.p.y)); - gs_lineto(pgls->pgs, fixed2float(fixed_box.p.x), - fixed2float(fixed_box.q.y)); - gs_lineto(pgls->pgs, fixed2float(fixed_box.q.x), - fixed2float(fixed_box.q.y)); - gs_lineto(pgls->pgs, fixed2float(fixed_box.q.x), - fixed2float(fixed_box.p.y)); - gs_closepath(pgls->pgs); - gs_stroke(pgls->pgs); - hpgl_grestore(pgls); - } else - hpgl_call(gx_clip_to_rectangle(pgls->pgs, &fixed_box)); - } - return 0; -} - -/* Plot one vector for vector fill all these use absolute coordinates. */ - private int -hpgl_draw_vector_absolute( - hpgl_state_t * pgls, - hpgl_real_t x0, - hpgl_real_t y0, - hpgl_real_t x1, - hpgl_real_t y1, - hpgl_rendering_mode_t render_mode -) -{ - bool set_ctm = (render_mode != hpgl_rm_character); - - hpgl_call( hpgl_add_point_to_path( pgls, - x0, - y0, - hpgl_plot_move_absolute, - set_ctm - ) ); - hpgl_call( hpgl_add_point_to_path( pgls, - x1, - y1, - hpgl_plot_draw_absolute, - set_ctm - ) ); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector_fill)); - return 0; -} - - private int -hpgl_get_adjusted_corner( - hpgl_real_t x_fill_increment, - hpgl_real_t y_fill_increment, - gs_rect * bbox, - gs_point * current_anchor_corner, - gs_point * adjusted_anchor_corner -) -{ - adjusted_anchor_corner->x = current_anchor_corner->x; - adjusted_anchor_corner->y = current_anchor_corner->y; - - /* account for anchor corner greater than origin */ - if (x_fill_increment != 0) { - while (adjusted_anchor_corner->x > bbox->p.x) - adjusted_anchor_corner->x -= x_fill_increment; - } else if (adjusted_anchor_corner->x > bbox->p.x) - adjusted_anchor_corner->x = bbox->p.x; - if (y_fill_increment != 0) { - while (adjusted_anchor_corner->y > bbox->p.y) - adjusted_anchor_corner->y -= y_fill_increment; - } else if (adjusted_anchor_corner->y > bbox->p.y) - adjusted_anchor_corner->y = bbox->p.y; - return 0; -} - - private void -hpgl_alternate_line_pattern_offset(hpgl_state_t *pgls, uint lines_filled) -{ - if ( lines_filled & 1 ) - pgls->g.line.current.pattern_offset = 0.5; - else - pgls->g.line.current.pattern_offset = 0.0; -} - -/* - * HAS should replicate lines beginning at the anchor corner to +X and - * +Y. Not quite right - anchor corner not yet supported. - * pgls->g.anchor_corner needs to be used to set dash offsets - */ - private int -hpgl_polyfill( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - hpgl_real_t diag_mag, endx, endy; - gs_sincos_t sincos; - gs_point start; - -#define sin_dir sincos.sin -#define cos_dir sincos.cos - - gs_rect bbox; - hpgl_pen_state_t saved_pen_state; - hpgl_real_t x_fill_increment, y_fill_increment; - hpgl_FT_pattern_source_t type = pgls->g.fill.type; - bool cross = (type == hpgl_FT_pattern_two_lines); - const hpgl_hatch_params_t * params = (cross ? &pgls->g.fill.param.crosshatch - : &pgls->g.fill.param.hatch); - gs_point spacing; - hpgl_real_t direction = params->angle; - float saved_line_pattern_offset = pgls->g.line.current.pattern_offset; - int lines_filled; - /* initilialize spacing between fill line vector */ - spacing.x = spacing.y = params->spacing; - /* save the pen position */ - hpgl_save_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); - if (params->spacing == 0) { - /* Per TRM 22-12, use 1% of the P1/P2 distance. */ - gs_matrix mat; - - hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - spacing.x = spacing.y = 0.01 * hpgl_compute_distance( pgls->g.P1.x, - pgls->g.P1.y, - pgls->g.P2.x, - pgls->g.P2.y - ); - spacing.x /= fabs(mat.xx); - spacing.y /= fabs(mat.yy); - } - - /* For fill type 3 (hatch) we take the max spacing value for fill - type 4 (crosshatch) we fill asymetrically. */ - if ( !cross ) - spacing.x = spacing.y = max(spacing.x, spacing.y); - - /* get the bounding box */ - hpgl_call(hpgl_polyfill_bbox(pgls, &bbox)); - - /* - * HAS calculate the offset for dashing - we do not need this for - * solid lines - */ - /* - * if the line width exceeds the spacing we use the line width - * to avoid overlapping of the fill lines. HAS this can be - * integrated with the logic above for spacing as not to - * duplicate alot of code. - */ - { - gs_matrix mat; - const float * widths = pcl_palette_get_pen_widths(pgls->ppalet); - hpgl_real_t line_width = widths[hpgl_get_selected_pen(pgls)]; - - hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - line_width /= min(fabs(mat.xx), fabs(mat.yy)); - if (line_width >= spacing.x || line_width >= spacing.y) { - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_polygon)); - return 0; - } - } - - /* get rid of the current path */ - hpgl_call(hpgl_clear_current_path(pgls)); -start: - lines_filled = 0; - gs_sincos_degrees(direction, &sincos); - if (sin_dir < 0) - sin_dir = -sin_dir, cos_dir = -cos_dir; /* ensure y_inc >= 0 */ - x_fill_increment = (sin_dir != 0) ? fabs(spacing.x / sin_dir) : 0; - y_fill_increment = (cos_dir != 0) ? fabs(spacing.y / cos_dir) : 0; - hpgl_call( hpgl_get_adjusted_corner( x_fill_increment, - y_fill_increment, - &bbox, - &pgls->g.anchor_corner, - &start - ) ); - - /* - * calculate the diagonals magnitude. Note we clip this - * latter in the library. If desired we could clip to the - * actual bbox here to save processing time. For now we simply - * draw all fill lines using the diagonals magnitude - */ - diag_mag = hpgl_compute_distance(start.x, start.y, bbox.q.x, bbox.q.y); - endx = (diag_mag * cos_dir) + start.x; - endy = (diag_mag * sin_dir) + start.y; - hpgl_alternate_line_pattern_offset(pgls, lines_filled++); - hpgl_call( hpgl_draw_vector_absolute( pgls, - start.x, - start.y, - endx, - endy, - render_mode - ) ); - /* Travel along +x using current spacing. */ - if (x_fill_increment != 0) { - while ( endx += x_fill_increment, - (start.x += x_fill_increment) <= bbox.q.x ) { - - hpgl_alternate_line_pattern_offset(pgls, lines_filled++); - hpgl_call( hpgl_draw_vector_absolute( pgls, - start.x, - start.y, - endx, - endy, - render_mode - ) ); - } - } - - /* Travel along +Y similarly. */ - if (y_fill_increment != 0) { - /* - * If the slope is negative, we have to travel along the right - * edge of the box rather than the left edge. Fortuitously, - * the X loop left everything set up exactly right for this case. - */ - if (cos_dir >= 0) { - hpgl_call( hpgl_get_adjusted_corner( x_fill_increment, - y_fill_increment, - &bbox, - &pgls->g.anchor_corner, - &start - ) ); - endx = (diag_mag * cos_dir) + start.x; - endy = (diag_mag * sin_dir) + start.y; - } else - start.y -= y_fill_increment, endy -= y_fill_increment; - - while ( endy += y_fill_increment, - (start.y += y_fill_increment) <= bbox.q.y ) { - hpgl_alternate_line_pattern_offset(pgls, lines_filled++); - hpgl_call( hpgl_draw_vector_absolute( pgls, - start.x, - start.y, - endx, - endy, - render_mode - ) ); - } - - } - if (cross) { - cross = false; - direction += 90; - if ( direction >= 180 ) - direction -= 180; - goto start; - } - hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); - pgls->g.line.current.pattern_offset = saved_line_pattern_offset; - return 0; - -#undef sin_dir -#undef cos_dir - -} - -/* gl/2 vector filled objects always have a white background. It can - be either a transparent or white. In the former case we don't have - to do anything. We expect the fill area of the object to already - be defined in the graphics state. */ - private int -hpgl_fill_polyfill_background(hpgl_state_t *pgls) -{ - /* if we are drawing on a transparent background */ - if ( pgls->g.source_transparent ) - return 0; - /* preserve the current foreground color */ - hpgl_call(hpgl_gsave(pgls)); - /* fill a white region. NB have not experimented with different - rasterops and transparency. */ - hpgl_call(gs_setgray(pgls->pgs, 1.0)); - hpgl_call(gs_fill(pgls->pgs)); - /* restore the foreground color */ - hpgl_call(hpgl_grestore(pgls)); - return 0; -} - - private int -hpgl_polyfill_using_current_line_type( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - /* gsave and grestore used to preserve the clipping region */ - hpgl_call(hpgl_gsave(pgls)); - - /* - * Use the current path to set up a clipping path - * beginning at the anchor corner replicate lines - */ - if (pgls->g.fill_type == hpgl_even_odd_rule) - hpgl_call(gs_eoclip(pgls->pgs)); - else - hpgl_call(gs_clip(pgls->pgs)); - hpgl_call(hpgl_fill_polyfill_background(pgls)); - hpgl_call(hpgl_polyfill(pgls, render_mode)); - hpgl_call(hpgl_grestore(pgls)); - return 0; -} - - int -hpgl_set_drawing_color( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - int code = 0; - pcl_pattern_set_proc_t set_proc; - byte pixel_placement_mode = 0; - switch (render_mode) { - - case hpgl_rm_clip_and_fill_polygon: - hpgl_call(hpgl_polyfill_using_current_line_type(pgls, render_mode)); - return 0; - - case hpgl_rm_character: - switch (pgls->g.character.fill_mode) { - - case hpgl_char_solid_edge: /* fall through */ - case hpgl_char_edge: - set_proc = pcl_pattern_get_proc_FT(hpgl_FT_pattern_solid_pen1); - code = set_proc(pgls, hpgl_get_selected_pen(pgls), false); - break; - - case hpgl_char_fill: - case hpgl_char_fill_edge: - if ( (pgls->g.fill.type == hpgl_FT_pattern_one_line) || - (pgls->g.fill.type == hpgl_FT_pattern_two_lines) ) { - hpgl_call( hpgl_polyfill_using_current_line_type( pgls, - render_mode - ) ); - return 0; - } else - goto fill; - - default: - dprintf("hpgl_set_drawing_color: internal error illegal fill\n"); - return 0; - } - break; - - /* fill like a polygon */ - case hpgl_rm_polygon: -fill: - /* pixel placement mode is only relevant to polygon fills */ - pixel_placement_mode = pgls->pp_mode; - set_proc = pcl_pattern_get_proc_FT(pgls->g.fill.type); - switch (pgls->g.fill.type) { - - case hpgl_FT_pattern_solid_pen1: - case hpgl_FT_pattern_solid_pen2: - /* - * this is documented incorrectly PCLTRM 22-12 says - * these should be solid black but they are actually - * set to the value of the current pen - (i.e pen 0 is - * solid white - */ - code = set_proc(pgls, hpgl_get_selected_pen(pgls), false); - break; - - case hpgl_FT_pattern_one_line: - case hpgl_FT_pattern_two_lines: - set_proc = pcl_pattern_get_proc_FT(hpgl_FT_pattern_solid_pen1); - code = set_proc(pgls, hpgl_get_selected_pen(pgls), false); - break; - - case hpgl_FT_pattern_cross_hatch: - code = set_proc( pgls, - pgls->g.fill.param.pattern_type, - hpgl_get_selected_pen(pgls) - ); - break; - - case hpgl_FT_pattern_shading: - code = set_proc( pgls, - pgls->g.fill.param.shading, - hpgl_get_selected_pen(pgls) - ); - break; - - case hpgl_FT_pattern_user_defined: - code = set_proc( pgls, - pgls->g.fill.param.pattern_id, - hpgl_get_selected_pen(pgls) - ); - break; - - case hpgl_FT_pattern_RF: - /* pcl5e does not care about the current pen it always uses black (1). */ - if ( pgls->personality == pcl5e ) - code = set_proc( pgls, - pgls->g.fill.param.user_defined.pattern_index, - 1 ); - else - code = set_proc( pgls, - pgls->g.fill.param.user_defined.pattern_index, - (pgls->g.fill.param.user_defined.use_current_pen - ? hpgl_get_selected_pen(pgls) - : -hpgl_get_selected_pen(pgls)) - ); - - break; - default: - dprintf("hpgl_set_drawing_color: internal error illegal fill\n"); - break; - } - break; - - case hpgl_rm_vector: - case hpgl_rm_vector_fill: - set_proc = pcl_pattern_get_proc_SV(pgls->g.screen.type); - switch(pgls->g.screen.type) { - - case hpgl_SV_pattern_solid_pen: - code = set_proc(pgls, hpgl_get_selected_pen(pgls), false); - break; - - case hpgl_SV_pattern_shade: - code = set_proc( pgls, - pgls->g.screen.param.shading, - hpgl_get_selected_pen(pgls) - ); - break; - - case hpgl_SV_pattern_cross_hatch: - code = set_proc( pgls, - pgls->g.screen.param.pattern_type, - hpgl_get_selected_pen(pgls) - ); - break; - - case hpgl_SV_pattern_RF: - code = set_proc( pgls, - pgls->g.screen.param.user_defined.pattern_index, - (pgls->g.screen.param.user_defined.use_current_pen - ? hpgl_get_selected_pen(pgls) - : -hpgl_get_selected_pen(pgls)) - ); - break; - - case hpgl_SV_pattern_user_defined: - code = set_proc( pgls, - pgls->g.screen.param.pattern_id, - hpgl_get_selected_pen(pgls) - ); - break; - - default: - dprintf("hpgl_set_drawing_color: internal error illegal fill\n"); - break; - } - break; - - default: - dprintf("hpgl_set_drawing_color: internal error illegal mode\n"); - break; - } - - if (code >= 0) { - /* PCL and GL/2 no longer use graphic library transparency */ - gs_setrasterop(pgls->pgs, (gs_rop3_t)pgls->logical_op); - } - return code; -} - - private int -hpgl_set_drawing_state( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - /* do dash stuff. */ - hpgl_call(hpgl_set_graphics_dash_state(pgls)); - - /* joins, caps, and line width. */ - hpgl_call(hpgl_set_graphics_line_attribute_state(pgls, render_mode)); - - /* set up a clipping region */ - hpgl_call(hpgl_set_clipping_region(pgls, render_mode)); - - /* set up the hpgl fills (GL's source transp. is PCL's pattern trasp. */ - pgls->pattern_transparent = pgls->g.source_transparent; - hpgl_call(hpgl_set_drawing_color(pgls, render_mode)); - - return 0; -} - - int -hpgl_get_current_position( - hpgl_state_t * pgls, - gs_point * pt -) -{ - *pt = pgls->g.pos; - return 0; -} - - int -hpgl_update_carriage_return_pos(hpgl_state_t *pgls) -{ - pgls->g.carriage_return_pos = pgls->g.pos; - return 0; -} - - int -hpgl_set_current_position( - hpgl_state_t * pgls, - gs_point * pt -) -{ - pgls->g.pos = *pt; - if ( gs_debug_c('P') ) - dprintf2("gl/2 setting position: x=%f y=%f\n", pt->x, pt->y); - return 0; -} - - int -hpgl_add_point_to_path( - hpgl_state_t * pgls, - floatp x, - floatp y, - hpgl_plot_function_t func, - bool set_ctm -) -{ - static int (*const gs_procs[])(P3(gs_state *, floatp, floatp)) - = { hpgl_plot_function_procedures }; - - if (gx_path_is_null(gx_current_path(pgls->pgs))) { - /* Start a new GL/2 path. */ - gs_point current_pt; - - if (set_ctm) - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(gs_newpath(pgls->pgs)); - - /* moveto the current position */ - hpgl_call(hpgl_get_current_position(pgls, ¤t_pt)); - hpgl_call_check_lost( gs_moveto( pgls->pgs, - current_pt.x, - current_pt.y - ) ); - } - { - int code = (*gs_procs[func])(pgls->pgs, x, y); - if ( gs_debug_c('P') ) { - static const char *hpgl_draw_func[] = { - "hpgl_plot_move_absolute", - "hpgl_plot_move_relative", - "hpgl_plot_draw_absolute", - "hpgl_plot_draw_relative" - }; - gs_point dev_pt; - hpgl_call(gs_transform(pgls->pgs, x, y, &dev_pt)); - dprintf1("gl/2 plot function=%s\t", hpgl_draw_func[func]); - dprintf2("gl/2 user coord: x=%f y=%f\t", x, y); - dprintf2("gl/2 device coord: x=%f y=%f\n", dev_pt.x, dev_pt.y); - } - if (code < 0) { - hpgl_call_note_error(code); - if (code == gs_error_limitcheck) - hpgl_set_lost_mode(pgls, hpgl_lost_mode_entered); - } else { - gs_point point; - - if (hpgl_plot_is_absolute(func)) - hpgl_set_lost_mode(pgls, hpgl_lost_mode_cleared); - - /* update hpgl's state position */ - if (hpgl_plot_is_absolute(func)) { - point.x = x; - point.y = y; - } else { - hpgl_call(hpgl_get_current_position(pgls, &point)); - point.x += x; point.y += y; - } - hpgl_call(hpgl_set_current_position(pgls, &point)); - } - } - return 0; -} - -/* destroy the current path. */ - int -hpgl_clear_current_path(hpgl_state_t *pgls) -{ - hpgl_call(gs_newpath(pgls->pgs)); - return 0; -} - -/* closes the current path, making the first point and last point coincident */ - int -hpgl_close_current_path(hpgl_state_t *pgls) -{ - hpgl_call(gs_closepath(pgls->pgs)); - return 0; -} - -/* converts pcl coordinate to device space and back to hpgl space */ - int -hpgl_add_pcl_point_to_path(hpgl_state_t *pgls, const gs_point *pcl_pt) -{ - gs_point dev_pt, hpgl_pt; - - hpgl_call(hpgl_clear_current_path(pgls)); - pcl_set_ctm(pgls, true); - hpgl_call(gs_transform(pgls->pgs, pcl_pt->x, pcl_pt->y, &dev_pt)); - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &hpgl_pt)); - hpgl_call(hpgl_add_point_to_path(pgls, hpgl_pt.x, hpgl_pt.y, - hpgl_plot_move_absolute, true)); - return 0; -} - - int -hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y, - floatp radius, floatp start_angle, floatp sweep_angle, - floatp chord_angle, bool start_moveto, hpgl_plot_function_t draw, - bool set_ctm) -{ - /* - * Ensure that the sweep angle is an integral multiple of the - * chord angle, by decreasing the chord angle if necessary. - */ - int num_chords = (int)ceil(sweep_angle / chord_angle); - floatp integral_chord_angle = sweep_angle / num_chords; - int i; - floatp arccoord_x, arccoord_y; - - (void)hpgl_compute_arc_coords(radius, center_x, center_y, - start_angle, - &arccoord_x, &arccoord_y); - hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, - (draw && !start_moveto ? - hpgl_plot_draw_absolute : - hpgl_plot_move_absolute), set_ctm)); - - /* HAS - pen up/down is invariant in the loop */ - for ( i = 0; i < num_chords; i++ ) - { - start_angle += integral_chord_angle; - hpgl_compute_arc_coords(radius, center_x, center_y, - start_angle, &arccoord_x, &arccoord_y); - hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, - (draw ? hpgl_plot_draw_absolute : - hpgl_plot_move_absolute), set_ctm)); - } - return 0; -} - -/* add a 3 point arc to the path */ - int -hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp - start_y, floatp inter_x, floatp inter_y, - floatp end_x, floatp end_y, floatp chord_angle, - hpgl_plot_function_t draw) -{ - /* handle unusual cases as per pcltrm */ - if ( hpgl_3_same_points(start_x, start_y, - inter_x, inter_y, - end_x, end_y) ) - { - hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); - return 0; - } - if ( hpgl_3_no_intermediate(start_x, start_y, - inter_x, inter_y, - end_x, end_y) ) - { - hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); - hpgl_call(hpgl_add_point_to_path(pgls, end_x, end_y, draw, true)); - return 0; - } - if ( hpgl_3_same_endpoints(start_x, start_y, - inter_x, y_inter, - end_x, end_y) ) - { - hpgl_call(hpgl_add_arc_to_path(pgls, (start_x + inter_x) / 2.0, - (start_y + inter_y) / 2.0, - (hypot((inter_x - start_x), - (inter_y - start_y)) / 2.0), - 0.0, 360.0, chord_angle, false, - draw, true)); - return 0; - } - - if ( hpgl_3_colinear_points(start_x, start_y, inter_x, inter_y, end_x, end_y) ) - { - if ( hpgl_3_intermediate_between(start_x, start_y, - inter_x, inter_y, - end_x, end_y) ) - { - hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); - hpgl_call(hpgl_add_point_to_path(pgls, end_x, end_x, draw, true)); - } - else - { - hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); - hpgl_call(hpgl_add_point_to_path(pgls, inter_x, inter_y, draw, true)); - hpgl_call(hpgl_add_point_to_path(pgls, end_x, end_y, draw, true)); - } - return 0; - } - - /* normal 3 point arc case */ - { - hpgl_real_t center_x, center_y, radius; - hpgl_real_t start_angle, inter_angle, end_angle; - hpgl_real_t sweep_angle; - - hpgl_call(hpgl_compute_arc_center(start_x, start_y, - inter_x, inter_y, - end_x, end_y, - ¢er_x, ¢er_y)); - - radius = hypot(start_x - center_x, start_y - center_y); - start_angle = radians_to_degrees * - hpgl_compute_angle(start_x - center_x, start_y - center_y); - - inter_angle = radians_to_degrees * - hpgl_compute_angle(inter_x - center_x, inter_y - center_y); - - end_angle = radians_to_degrees * - hpgl_compute_angle(end_x - center_x, end_y - center_y); - sweep_angle = end_angle - start_angle; - - /* - * Figure out which direction to draw the arc, depending on the - * relative position of start, inter, and end. Case analysis - * shows that we should draw the arc counter-clockwise from S to - * E iff exactly 2 of S<I, I<E, and E<S are true, and clockwise - * if exactly 1 of these relations is true. (These are the only - * possible cases if no 2 of the points coincide.) - */ - - if ( (start_angle < inter_angle) + (inter_angle < end_angle) + - (end_angle < start_angle) == 1 - ) - { - if ( sweep_angle > 0 ) - sweep_angle -= 360; - } - else - { - if ( sweep_angle < 0 ) - sweep_angle += 360; - } - - hpgl_call(hpgl_add_arc_to_path(pgls, center_x, center_y, - radius, start_angle, sweep_angle, - (sweep_angle < 0.0 ) ? - -chord_angle : chord_angle, false, - draw, true)); - return 0; - } -} - -/* Bezier's are handled a bit differently than arcs as we use the - gs_curveto() operator directly in lieue of flattening and using - gs_moveto() and gs_lineto(). */ - - int -hpgl_add_bezier_to_path(hpgl_state_t *pgls, floatp x1, floatp y1, - floatp x2, floatp y2, floatp x3, floatp y3, - floatp x4, floatp y4, hpgl_plot_function_t draw) -{ - gs_fixed_point dummy_pt; - /* Don't add superflous points in polygon mode */ - if ( ( !pgls->g.polygon_mode ) || - ( gx_path_subpath_start_point(gx_current_path(pgls->pgs), - &dummy_pt) < 0 ) ) - hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, - hpgl_plot_move_absolute, true)); - if ( draw ) - hpgl_call(gs_curveto(pgls->pgs, x2, y2, x3, y3, x4, y4)); - /* update hpgl's state position to last point of the curve. */ - { - gs_point point; - point.x = x4; point.y = y4; - hpgl_call(hpgl_set_current_position(pgls, &point)); - } - return 0; -} - -/* - * an implicit gl/2 style closepath. If the first and last point are - * the same the path gets closed. HAS - eliminate CSE gx_current_path - */ - int -hpgl_close_path( - hpgl_state_t * pgls -) -{ - gs_point first, last; - gs_fixed_point first_device; - - /* if we do not have a subpath there is nothing to do, get the - first points of the path in device space and convert to floats */ - if ( gx_path_subpath_start_point(gx_current_path(pgls->pgs), - &first_device) < 0 ) - return 0; - first.x = fixed2float(first_device.x); - first.y = fixed2float(first_device.y); - /* get gl/2 current position -- always current units */ - hpgl_call(hpgl_get_current_position(pgls, &last)); - /* convert to device space using the current ctm */ - hpgl_call(gs_transform(pgls->pgs, last.x, last.y, &last)); - /* - * if the first and last are the same close the path (i.e - * force gs to apply join and miter) - */ - if (equal(first.x, last.x) && equal(first.y, last.y)) - hpgl_call(gs_closepath(pgls->pgs)); - return 0; -} - - -/* To implement centered we simply slide everything up and left. This - is not exactly correct but produces the desired results in most - cases. Note this routine is sensitive to the orientation of the - device */ - private int -hpgl_set_special_pixel_placement(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) -{ - if ( pgls->pp_mode == 1 ) { - gs_matrix default_matrix; - gs_point distance, adjust; - gx_path *ppath = gx_current_path(pgls->pgs); - /* arbitrary just need the signs after transformation to - device space */ - gs_setfilladjust(pgls->pgs, 0, 0); - adjust.x = -1; - adjust.y = -1; - /* determine the adjustment in device space */ - hpgl_call(gs_defaultmatrix(pgls->pgs, &default_matrix)); - hpgl_call(gs_distance_transform(adjust.x, adjust.y, &default_matrix, &distance)); - /* translate all points in the path by the adjustment. The - 1.5 is a hack, it should be 1 */ - hpgl_call(gx_path_translate(ppath, - float2fixed(1.0 * (distance.x / fabs(distance.x))), - float2fixed(1.5 * (distance.y / fabs(distance.y))))); - } - return 0; -} - -/* - * Draw (stroke or fill) the current path. - */ - int -hpgl_draw_current_path( - hpgl_state_t * pgls, - hpgl_rendering_mode_t render_mode -) -{ - gs_fixed_point dummy_pt; - gs_state * pgs = pgls->pgs; - pcl_pattern_set_proc_t set_proc; - int code = 0; - - /* check if we have a current path - we don't need the current - point */ - if ( gx_path_subpath_start_point(gx_current_path(pgls->pgs), - &dummy_pt) < 0 ) { - hpgl_call(hpgl_clear_current_path(pgls)); - return 0; - } - - if ( render_mode == hpgl_rm_vector_no_close ) - render_mode = hpgl_rm_vector; - else - hpgl_call(hpgl_close_path(pgls)); - - hpgl_call(hpgl_set_drawing_state(pgls, render_mode)); - - switch (render_mode) { - case hpgl_rm_character: - { - /* HAS need to set attributes in set_drawing color (next 2) */ - - /* Intellifonts require eofill, but TrueType require fill. */ - /****** HACK: look at the scaling technology of ******/ - /****** the current font to decide. ******/ - int (*fill)(P1(gs_state *)); - - if (pgls->g.font->scaling_technology == plfst_Intellifont) - fill = gs_eofill; - else - fill = gs_fill; - - switch (pgls->g.character.fill_mode) { - - case hpgl_char_solid_edge: - set_proc = pcl_pattern_get_proc_FT(hpgl_FT_pattern_solid_pen1); - if ((code = set_proc(pgls, hpgl_get_selected_pen(pgls), false)) < 0) - return code; - hpgl_call((*fill)(pgs)); - /* falls through */ - - case hpgl_char_edge: - if (pgls->g.bitmap_fonts_allowed) - break; /* no edging */ - set_proc = pcl_pattern_get_proc_FT(hpgl_FT_pattern_solid_pen1); - if ((code = set_proc(pgls, hpgl_get_character_edge_pen(pgls), false)) < 0) - return code; - hpgl_call(hpgl_set_plu_ctm(pgls)); - hpgl_call(gs_setlinewidth(pgls->pgs, - pgls->g.font_selection[pgls->g.font_selected].params.height_4ths * 0.0375)); - hpgl_call(gs_stroke(pgs)); - break; - - case hpgl_char_fill: - /* the fill has already been done if the fill type is - hpgl/2 vector fills. This was handled when we set - the drawing color */ - if ((pgls->g.fill.type != hpgl_FT_pattern_one_line) && - (pgls->g.fill.type != hpgl_FT_pattern_two_lines)) - hpgl_call((*fill)(pgs)); - else - hpgl_call(hpgl_clear_current_path(pgls)); - break; - case hpgl_char_fill_edge: - if (pgls->g.bitmap_fonts_allowed) - break; /* no edging */ - /* the fill has already been done if the fill type is - hpgl/2 vector fills. This was handled when we set - the drawing color. gsave to preserve the path for - subsequent edging */ - if ((pgls->g.fill.type != hpgl_FT_pattern_one_line) && - (pgls->g.fill.type != hpgl_FT_pattern_two_lines)) { - hpgl_call(hpgl_gsave(pgls)); - /* all character fills appear to have 0 fill adjustment */ - gs_setfilladjust(pgls->pgs, 0, 0); - hpgl_call((*fill)(pgs)); - hpgl_call(hpgl_grestore(pgls)); - } - set_proc = pcl_pattern_get_proc_FT(hpgl_FT_pattern_solid_pen1); - if ((code = set_proc(pgls, hpgl_get_character_edge_pen(pgls), false)) < 0) - return code; - hpgl_call(hpgl_set_plu_ctm(pgls)); - /* use the default raster operation for the edge. It - is automaticall restored next drawing operation */ - hpgl_call(gs_setrasterop(pgls->pgs, (gs_rop3_t)252)); - hpgl_call(gs_setlinewidth(pgls->pgs, - pgls->g.font_selection[pgls->g.font_selected].params.height_4ths * 0.0375)); - hpgl_call(gs_stroke(pgs)); - break; - } - break; - } - break; - case hpgl_rm_polygon: - hpgl_set_special_pixel_placement(pgls, hpgl_rm_polygon); - if (pgls->g.fill_type == hpgl_even_odd_rule) - hpgl_call(gs_eofill(pgs)); - else /* hpgl_winding_number_rule */ - hpgl_call(gs_fill(pgs)); - break; - - case hpgl_rm_clip_and_fill_polygon: - /* - * A bizarre HPISM - If the pen is white we do a solid - * white fill this is true for *all* fill types (arg!) as - * tested on the 6mp. If pen 1 (black) - * hpgl_set_drawing_color() handles this case by drawing - * the lines that comprise the vector fill - */ - if (hpgl_get_selected_pen(pgls) == 0) - hpgl_call(gs_fill(pgls->pgs)); - hpgl_call(hpgl_clear_current_path(pgls)); - break; - - case hpgl_rm_vector: - case hpgl_rm_vector_fill: - /* - * we reset the ctm before stroking to preserve the line width - * information, then restore the ctm. - */ - { - gs_matrix save_ctm; - hpgl_call(gs_currentmatrix(pgs, &save_ctm)); - hpgl_call(hpgl_set_plu_ctm(pgls)); - if ( !pgls->g.line.current.is_solid && (pgls->g.line.current.type == 0) ) - hpgl_call(gs_reversepath(pgls->pgs)); - hpgl_call(gs_stroke(pgls->pgs)); - gs_setmatrix(pgs, &save_ctm); - break; - } - default : - dprintf("unknown render mode\n"); - } - - return 0; -} - - int -hpgl_copy_current_path_to_polygon_buffer( - hpgl_state_t * pgls -) -{ - gx_path * ppath = gx_current_path(pgls->pgs); - - gx_path_new(&pgls->g.polygon.buffer.path); - gx_path_copy(ppath, &pgls->g.polygon.buffer.path); - return 0; -} - - int -hpgl_copy_polygon_buffer_to_current_path( - hpgl_state_t * pgls -) -{ - gx_path * ppath = gx_current_path(pgls->pgs); - - gx_path_copy(&pgls->g.polygon.buffer.path, ppath); - return 0; -} diff --git a/pcl/pgdraw.h b/pcl/pgdraw.h deleted file mode 100644 index 4b1d844c8..000000000 --- a/pcl/pgdraw.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgdraw.h */ -/* Definitions for HP-GL/2 line drawing/path building routines */ - -#ifndef pgdraw_INCLUDED -# define pgdraw_INCLUDED - -/* set plu ctm, exported only so that labels can ignore scaling */ -int hpgl_set_plu_ctm(P1(hpgl_state_t *pgls)); - -/* compute the scaling transformation from plu to user units */ -int hpgl_compute_user_units_to_plu_ctm(P2(const hpgl_state_t *pgls, - gs_matrix *pmat)); - -/* The following 2 functions can be used together to calculate a ctm - without picture frame scaling. */ -int hpgl_set_pcl_to_plu_ctm(P1(hpgl_state_t *pgls)); - -int hpgl_set_user_units_to_plu_ctm(P1(const hpgl_state_t *pgls)); - -/* set (user units) ctm */ -int hpgl_set_ctm(P1(hpgl_state_t *pgls)); - -int hpgl_get_selected_pen(P1(hpgl_state_t *pgls)); - -/* set the hpgl/2 clipping region accounting for pcl picture frame and - gl/2 soft clip window */ - int -hpgl_set_clipping_region(P2(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)); - -/* function set up the current drawing attributes this is only used by - the character code since it does most of it's own graphic's state - bookkeeping */ -int hpgl_set_drawing_color(P2(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)); - -/* function to get the current hpgl/2 state position */ -int hpgl_get_current_position(P2(hpgl_state_t *pgls, gs_point *pt)); - -/* update the carriage return position to the current gl/2 positiion */ - int -hpgl_update_carriage_return_pos(P1(hpgl_state_t *pgls)); - -/* function to set the current hpgl/2 state position */ -int hpgl_set_current_position(P2(hpgl_state_t *pgls, gs_point *pt)); - -/* puts a point into the path using the operation specified by func */ -int hpgl_add_point_to_path(P5(hpgl_state_t *pgls, floatp x, floatp y, - hpgl_plot_function_t func, bool set_ctm)); - -/* puts an arc into the current path. start moveto indicates that we - use moveto to go from the arc center to arc circumference. */ -int hpgl_add_arc_to_path(P10(hpgl_state_t *pgls, floatp center_x, - floatp center_y, floatp radius, - floatp start_angle, floatp sweep_angle, - floatp chord_angle, bool start_moveto, - hpgl_plot_function_t draw, bool set_ctm)); - -/* puts a 3 point arc into the current path. Note that the - decomposition is a bit different for 3 point arcs since the polygon - wedge routines use this function as well */ -int hpgl_add_arc_3point_to_path(P9(hpgl_state_t *pgls, floatp start_x, floatp - start_y, floatp inter_x, floatp inter_y, - floatp end_x, floatp end_y, floatp chord_angle, - hpgl_plot_function_t draw)); - -int hpgl_close_path(P1(hpgl_state_t *pgls)); - -/* put bezier into the current path */ -int hpgl_add_bezier_to_path(P10(hpgl_state_t *pgls, floatp x1, - floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, floatp x4, - floatp y4, hpgl_plot_function_t draw)); - -/* clears the current path with stroke or fill */ -int hpgl_draw_current_path(P2(hpgl_state_t *pgls, - hpgl_rendering_mode_t render_mode)); - -/* save/restore gs graphics state + HPGL/2's first moveto state */ -#define hpgl_gsave(pgls) pcl_gsave(pgls) -#define hpgl_grestore(pgls) pcl_grestore(pgls) - -/* path copying for polygons rendering */ -int hpgl_copy_polygon_buffer_to_current_path(P1(hpgl_state_t *pgls)); - -int hpgl_copy_current_path_to_polygon_buffer(P1(hpgl_state_t *pgls)); - -/* draw the current path with stroke or fill, but do not clear */ -int hpgl_draw_and_preserve_path(P2(hpgl_state_t *pgls, - hpgl_rendering_mode_t render_mode)); - -/* destroy the current path */ -int hpgl_clear_current_path(P1(hpgl_state_t *pgls)); - -/* closes the current path, making the first point and last point coincident */ -int hpgl_close_current_path(P1(hpgl_state_t *pgls)); - -/* adds a pcl point to the current path */ -int hpgl_add_pcl_point_to_path(P2(hpgl_state_t *pgls, const gs_point *pcl_point)); - -#endif /* pgdraw_INCLUDED */ diff --git a/pcl/pgfdata.c b/pcl/pgfdata.c deleted file mode 100644 index af9791742..000000000 --- a/pcl/pgfdata.c +++ /dev/null @@ -1,936 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgfdata.c */ -/* HP-GL/2 stick and arc font data */ -#include "std.h" -#include "gstypes.h" -#include "gsccode.h" -#include "gxarith.h" /* for any_abs */ -#include "pgfdata.h" - -/* - * This file serves 3 different purposes: - * - * Compiled normally, it contains the runtime procedures for - * implementing the stick/arc font. - * - * Compiled with -dESCAPEMENTS, it creates an executable that prints out - * the escapements for this font. - * - * Compiled with -dOUTLINES, it creates an executable that prints out - * PostScript procedures for the character outlines. - */ - -/* Define the number of symbols in the stick/arc font. */ -#define hpgl_stick_num_symbols (256+20) - -/* - * Characters are defined by a series of 1-byte points. Normally, the top - * nibble is X and the bottom nibble is Y. If the top nibble is 0xf, the - * bottom nibble has special meaning as follows: - */ -typedef enum { - arc_op_pen_up = 0x0, /* pen up */ - arc_op_draw_180 = 0x1, /* draw half circle, next delta is center of */ - /* half circle in grid coordinate system. */ - arc_op_draw_360 = 0x2, /* same as f1 but draw a circle instead. */ - arc_op_line_45 = 0x3, /* next delta specifies 45 degree line */ - /* instead of an arc. */ - arc_op_vertical = 0x4, /* force a vertical for an arc. */ - arc_op_BS = 0x5, /* hpgl backspace char */ - arc_op_up_5 = 0x6, /* ascend by 5 points */ - arc_op_down_5 = 0x7, /* descend by 5 points */ - arc_op_back_8 = 0x8, /* backspace by 8 points */ - arc_op_forward_8 = 0x9 /* forward by 8 points */ - /* 0xa - 0xf */ /* not used */ -} arc_op_t; - -/* The actual font data */ -private const byte arc_symbol_strokes[]={ - 0xf5,0x54,0x4e,0xf4,0xf1,0x5e,0x54,0xf0,0x52,0xf2 - ,0x51,0xf0,0x67,0xf2,0x57,0xf0,0xf7,0x43,0x46,0xf1 - ,0x56,0x43,0x40,0x43,0xf1,0x53,0x40,0xf4,0x3b,0x2e - ,0xf1,0x3e,0x3b,0xf4,0xf0,0x8b,0x7e,0xf1,0x8e,0x8b - ,0x9a,0x4a,0x39,0x38,0x47,0xf0,0x97,0x37,0x15,0x14 - ,0x32,0x82,0x93,0x60,0x40,0x04,0x06,0x28,0x38,0x5a - ,0x5e,0x4f,0x3f,0x2e,0x2a,0x90,0x04,0x22,0x82,0xa4 - ,0xa6,0x88,0x28,0x0a,0x0b,0x2d,0x8d,0xab,0xf0,0x50 - ,0x5f,0x3c,0x31,0x37,0xf0,0x39,0x3e,0x5e,0x50,0xf0 - ,0x30,0x70,0xf0,0x5c,0x5b,0xf0,0x39,0x59,0x50,0xf7 - ,0x52,0x30,0x20,0x02,0x82,0xf0,0x08,0x88,0xf0,0x4c - ,0x44,0xf0,0x15,0x7b,0xf0,0x4c,0xf0,0x1b,0x75,0x3f - ,0x7f,0xf0,0x70,0x30,0xf0,0x50,0x5f,0xf0,0xaf,0x0f - ,0x08,0xf0,0xf6,0x2c,0xf2,0x3c,0xf0,0x6c,0xf2,0x7c - ,0xf0,0x0a,0xf7,0xf0,0x0f,0x04,0x40,0x60,0xa4,0xaf - ,0x50,0x0f,0x20,0x56,0x80,0xaf,0x00,0xf0,0x0a,0xf1 - ,0x5a,0xa5,0xf1,0x55,0x0a,0xbf,0xaf,0x7c,0x73,0xa0 - ,0xb0,0x0c,0x3f,0x7f,0xac,0xab,0x67,0x57,0x02,0x00 - ,0xa0,0x00,0x0f,0xaf,0xf0,0x78,0x08,0x66,0xa6,0xa4 - ,0xf4,0x60,0x40,0x04,0x0b,0x4f,0x6f,0xab,0xa4,0xf0 - ,0x73,0xa0,0x58,0xf0,0x00,0x0f,0x6f,0x9c,0x9b,0x68 - ,0x08,0xf0,0x68,0xa4,0xa3,0x70,0x00,0x0f,0x3f,0xa8 - ,0xa7,0x30,0x00,0xaf,0xf0,0x0f,0xa0,0x00,0xaf,0x0f - ,0x1f,0x4c,0x43,0x10,0x00,0x09,0xf6,0xf0,0x2c,0xf2 - ,0x3c,0xf0,0x6c,0xf2,0x7c,0xf0,0x00,0xf7,0xf0,0x00 - ,0x5f,0xa0,0xf0,0x86,0x26,0x70,0x7f,0x06,0xa6,0x0f - ,0xaf,0x59,0x79,0xa6,0xa4,0x60,0x40,0x04,0x06,0x39 - ,0x69,0xf0,0x39,0x1b,0x1c,0x4f,0x6f,0x9c,0x9b,0x79 - ,0x04,0x40,0x60,0xa4,0xa5,0x78,0x38,0x0b,0x0c,0x3f - ,0x7f,0xac,0xf0,0xf6,0x1f,0x5c,0x9f,0xf7,0x9f,0x4f - ,0x0b,0x03,0x30,0x60,0xa4,0xa6,0x6a,0x3a,0x07,0x0f - ,0xaf,0x00,0x0f,0xf0,0xaf,0x08,0xf0,0x4b,0xa0,0xaf - ,0x59,0x0f,0x00,0x0f,0xf0,0xaf,0xa0,0xf0,0xa8,0x08 - ,0xf5,0xf0,0x08,0xf6,0xf0,0x0c,0x2e,0x4e,0x5d,0xf3 - ,0x6c,0x8c,0xae,0xf0,0x00,0xf7,0xf0,0x00,0x0f,0xa0 - ,0xaf,0x16,0x38,0x48,0x57,0xf3,0x66,0x76,0x98,0xf0 - ,0x9d,0x7b,0x6b,0x5c,0xf3,0x4d,0x3d,0x1b,0xf0,0x19 - ,0x10,0x16,0x49,0x59,0x86,0x80,0xf0,0x1e,0x19,0x13 - ,0x40,0x50,0x83,0xf0,0x89,0x80,0xf2,0x82,0xf0,0x00 - ,0xaf,0xf0,0x2f,0xf2,0x2d,0x13,0x4d,0xf0,0x8d,0x53 - ,0xf0,0x1a,0x9a,0xf0,0x86,0x06,0x86,0xf0,0x8a,0x0a - ,0xf0,0x02,0x8e,0x52,0xf2,0x51,0xf0,0x53,0x57,0x68 - ,0x78,0x9a,0x9b,0x5f,0x4f,0x0b,0x87,0x03,0xf0,0x01 - ,0x81,0x83,0x07,0x8b,0xf0,0x01,0x81,0xa3,0xf4,0x70 - ,0x50,0x14,0x18,0x5c,0x6c,0xa8,0xa5,0x83,0x87,0x69 - ,0x59,0x37,0x35,0x53,0x63,0x85,0x04,0x40,0x50,0xa5 - ,0xaf,0xa9,0xf4,0x76,0x46,0x0a,0x0b,0x4f,0x6f,0xab - ,0xa4,0x60,0x10,0xf7,0x10,0x1e,0xf0,0xf6,0x13,0xf4 - ,0x40,0x50,0x83,0x86,0x59,0x49,0x16,0x13,0xf0,0xf7 - ,0x80,0x8e,0x89,0x80,0xf0,0x83,0xf4,0x50,0x40,0x13 - ,0x16,0x49,0x59,0x86,0x85,0x15,0x95,0xf0,0x53,0xf2 - ,0x52,0xf0,0x57,0xf2,0x58,0x1e,0x10,0xf0,0x50,0x40 - ,0x13,0x16,0x49,0x59,0x86,0x83,0x50,0xf0,0xf7,0x8e - ,0x83,0x50,0x30,0x12,0xf4,0x30,0x60,0x82,0x83,0x65 - ,0x25,0x16,0x17,0x39,0x79,0x88,0xf0,0x1e,0x5b,0x9e - ,0xf7,0x49,0xf4,0x7c,0x8c,0xb9,0xb8,0x85,0x75,0x48 - ,0x32,0x30,0x3c,0x5e,0x6e,0x8c,0xf0,0x59,0x19,0xf0 - ,0x3d,0x32,0x50,0x60,0x82,0x99,0x70,0x59,0x30,0x19 - ,0x50,0x99,0x00,0x30,0x3f,0x0f,0xa0,0x70,0x7f,0xaf - ,0x59,0xf0,0x0f,0x59,0x50,0xf0,0x36,0x76,0xf0,0x74 - ,0x34,0x08,0xf6,0xf0,0x2c,0xf2,0x3c,0xf0,0x6c,0xf2 - ,0x7c,0xf0,0xa0,0xf7,0xf0,0xa4,0x60,0x40,0x04,0x0b - ,0x4f,0x6f,0xab,0xa4,0xf0,0x9f,0x5d,0x1f,0x2f,0x3e - ,0x39,0x58,0x37,0x31,0x20,0x10,0x19,0x17,0x39,0x49 - ,0x67,0x60,0xf0,0x67,0x89,0x99,0xb7,0xb0,0xbf,0xaf - ,0x9e,0x99,0x78,0x97,0x91,0xa0,0xb0,0xf5,0x00,0x0f - ,0x1f,0x10,0x20,0x2f,0x3f,0x30,0x40,0x4f,0x5f,0x50 - ,0x60,0x6f,0x7f,0x70,0x80,0x8f,0x9f,0x90,0xa0,0xaf - ,0xbf,0xb0,0xc0,0xcf,0xdf,0xd0,0xe0,0xef,0x0f,0x0e - ,0xee,0xed,0x0d,0x0c,0xec,0xeb,0x0b,0x0a,0xea,0xe9 - ,0x09,0x08,0xe8,0xe7,0x07,0x06,0xe6,0xe5,0x05,0x04 - ,0xe4,0xe3,0x03,0x02,0xe2,0xe1,0x01,0x00,0xe0,0xf5 - ,0x00,0xe0,0x2c,0xf2,0x3c,0xf0,0x6c,0xf2,0x7c,0x6c - ,0xf0,0x19,0x50,0xf0,0xf7,0x9e,0x30,0x10,0x01,0xf0 - ,0xf6,0x7d,0x3b,0xf7,0x4a,0xf1,0x4c,0x5e,0xf1,0x5c - ,0x4a,0xf0,0x12,0x17,0x39,0x69,0x87,0x82,0x60,0x30 - ,0x12,0xf0,0x89,0x80,0x91,0x80,0x70,0x33,0x23,0x12 - ,0x11,0x20,0x30,0x52,0x5d,0x7f,0x8f,0xad,0xf0,0x79 - ,0x39,0xf0,0x77,0x37,0x39,0x59,0x7b,0x7c,0x5e,0x3e - ,0x1c,0x1b,0x39,0x19,0x59,0x86,0x80,0xf0,0x83,0x50 - ,0x30,0x12,0x14,0x36,0x86,0xf0,0x1c,0xf2,0x2c,0xf0 - ,0x6c,0xf2,0x7c,0x24,0x33,0x83,0x94,0x95,0x86,0x36 - ,0x27,0x29,0x3a,0x8a,0x99,0x97,0x86,0xf0,0x8a,0x3a - ,0x2b,0x2c,0x3d,0x8d,0x9c,0x18,0x3a,0x9a,0xf0,0x92 - ,0x84,0x7a,0xf0,0x4a,0x12,0x3e,0x6e,0x8c,0x8a,0x68 - ,0xf0,0x28,0x78,0x96,0x94,0x72,0x32,0x14,0x32,0x62 - ,0x84,0xaa,0xf0,0x84,0x83,0x92,0xa2,0xf0,0x3a,0x01 - ,0x0c,0x2e,0x3e,0x5c,0x92,0xf0,0x69,0x02,0x5e,0xa2 - ,0x02,0x32,0x07,0x0a,0x4e,0x5e,0x9a,0x97,0x62,0x92 - ,0x1a,0x38,0x43,0x42,0x64,0x9a,0xf0,0x6b,0x41,0xae - ,0xaf,0x0f,0x58,0x00,0xa0,0xa1,0xf5,0x2a,0x6d,0xaa - ,0x6a,0x3a,0x18,0x14,0x32,0x62,0x84,0x88,0x6a,0x13 - ,0x16,0x49,0x59,0x86,0x83,0x50,0x40,0x13,0xf0,0x10 - ,0x89,0x83,0x61,0x31,0x13,0x17,0x4a,0x7a,0x98,0x97 - ,0xaa,0x83,0x82,0x91,0xb1,0xa4,0xf4,0x60,0x40,0x04 - ,0x0b,0x4f,0x6f,0xab,0xa4,0xf0,0xaf,0x00,0xaf,0x5f - ,0x50,0xa0,0xf0,0x96,0x26,0x07,0x29,0x39,0x48,0x41 - ,0x30,0x20,0x02,0x07,0xf0,0x45,0x85,0x87,0x69,0x59 - ,0x48,0x41,0x50,0x60,0x82,0x6d,0x4d,0xf1,0x4e,0x4f - ,0x6f,0xf1,0x6e,0xf0,0x00,0x4c,0x6c,0xa0,0x86,0x26 - ,0x23,0xf2,0x56,0xf0,0x1a,0x29,0xf0,0x9a,0x89,0xf0 - ,0x92,0x83,0xf0,0x12,0x23,0x2d,0x4f,0x6f,0x9c,0x9b - ,0x68,0x58,0xf0,0x68,0xa4,0xa3,0x70,0x50,0x32,0x9d - ,0x5f,0x1d,0x10,0xf0,0x89,0x14,0xf0,0x80,0x46,0x45 - ,0x57,0x65,0xf0,0x57,0x51,0x10,0x89,0xf0,0x19,0x80 - ,0x10,0x89,0x19,0x13,0x40,0x50,0x83,0x80,0x89,0xf0 - ,0x1c,0xf2,0x2c,0xf0,0x6c,0xf2,0x7c,0x6c,0xf0,0x50 - ,0x40,0x13,0x16,0x49,0x59,0x86,0x83,0x50,0x55,0xf0 - ,0x57,0x58,0xf4,0xbe,0xcf,0xdf,0xee,0xdd,0xcd,0xf0 - ,0xdd,0xec,0xdb,0xcb,0xbc,0xf4,0xbe,0xcf,0xdf,0xee - ,0xed,0xbb,0xeb,0xf7,0x04,0x14,0x10,0xf0,0x21,0x23 - ,0x34,0x44,0x53,0x51,0x40,0x30,0x21,0xf0,0xf7,0xb2 - ,0xe2,0xe3,0xd4,0xc4,0xb3,0xb1,0xc0,0xd0,0xe1,0xbb - ,0xef,0xf0,0xbf,0xeb,0x5f,0xf2,0x5e,0xf0,0x5c,0x58 - ,0x47,0x37,0x15,0x14,0x50,0x60,0x93,0xf1,0x64,0x49 - ,0xf1,0x78,0x93,0xf0,0xb6,0x26,0x1e,0xf2,0x2d,0x6b - ,0xf0,0x19,0x59,0x86,0x80,0xf0,0x83,0x50,0x30,0x12 - ,0x14,0x36,0x86,0xf0,0x6d,0x2b,0xf0,0x15,0x85,0x86 - ,0x59,0x49,0x16,0x13,0x40,0x50,0x83,0xf0,0x2d,0x6b - ,0xf0,0x50,0x40,0x13,0x16,0x49,0x59,0x86,0x83,0x50 - ,0xf0,0x6d,0x2b,0xf0,0x19,0x13,0x40,0x50,0x83,0x80 - ,0x89,0xf0,0x2d,0x6b,0xf7,0x42,0x55,0xf0,0xf7,0x8a - ,0xf0,0x88,0x55,0x45,0x18,0x1a,0x4d,0x5d,0x8a,0xf0 - ,0x45,0x34,0x33,0x22,0xa4,0xf4,0x60,0x40,0x04,0x0b - ,0x4f,0x6f,0xab,0xf0,0x00,0xf7,0xf0,0x45,0x63,0x41 - ,0x13,0x1f,0x6f,0x9c,0x9b,0x68,0x18,0xf0,0x68,0xa4 - ,0xa3,0x70,0x20,0x02,0x68,0x3b,0x2b,0x1a,0xf0,0x8f - ,0x40,0xf5,0x4e,0xf2,0x5e,0xf0,0x8e,0xf2,0x9e,0xf5 - ,0x4d,0xf2,0x5e,0x4c,0xf2,0x5d,0xf0,0x19,0x59,0x86 - ,0x80,0xf0,0x83,0x50,0x30,0x12,0x14,0x36,0x86,0xf5 - ,0xf6,0x0c,0x1d,0x2d,0x3c,0x4c,0x5d,0x88,0x8e,0xf0 - ,0x8e,0x2e,0x22,0xe2,0xee,0x8e,0xf0,0x88,0x88,0x8e - ,0xf0,0x8e,0x5e,0x2b,0x25,0x52,0xb2,0xe5,0xeb,0xbe - ,0x8e,0xf0,0x88,0x88,0x8e,0xf0,0x8e,0x22,0xe2,0x8e - ,0xf0,0x88,0x88,0x8e,0xf0,0x88,0x82,0xf0,0x88,0x28 - ,0xe8,0xf0,0x88,0xf0,0x2e,0xf3,0x2e,0xf3,0xe2,0x88 - ,0x22,0xee,0x88,0x88,0x8e,0xf0,0x8e,0xf3,0x28,0xf3 - ,0x82,0xf3,0xe8,0xf3,0x8e,0xf0,0x88,0x88,0x8e,0xf0 - ,0x8e,0xf3,0x28,0xf3,0xe8,0xe8,0xf3,0x8e,0x82,0xf0 - ,0x88,0xe2,0x22,0xf3,0xee,0x2e,0xf3,0xe2,0xf0,0x88 - ,0x2e,0xee,0xf3,0x22,0xe2,0xf0,0x68,0xa8,0xf0,0x88 - ,0x88,0x2e,0xf0,0x88,0xee,0xf0,0x88,0x82,0xf0,0x88 - ,0x88,0x8a,0xf0,0x8a,0x6a,0xf3,0x2e,0xf3,0x6a,0x66 - ,0xf3,0x22,0xf3,0x66,0xa6,0xf3,0xe2,0xf3,0xa6,0xaa - ,0xf3,0xee,0xf3,0xaa,0x8a,0xf0,0x88,0x88,0x26,0xf0 - ,0x26,0xe6,0x8e,0x26,0xf0,0x8b,0x2b,0x82,0xeb,0x8b - ,0xf0,0x88,0x08,0x88,0xf0,0x44,0x4c,0xf0,0x0d,0x8d - ,0x76,0xa8,0x7a,0xf0,0xa8,0x28,0xf0,0x56,0x28,0x5a - ,0x06,0x26,0x50,0xcf,0xef,0x54,0x88,0x39,0xf0,0x8d - ,0x88,0xd9,0xf0,0xb4,0x88,0xf5,0x0f,0xef,0xf5,0x4c - ,0x7e,0xf5,0x4e,0x7c,0x12,0x1d,0xf0,0x18,0xb8,0x67 - ,0x8a,0xa7,0xf0,0x8a,0x82,0xf0,0x65,0x82,0xa5,0x3c - ,0x9c,0xf1,0x97,0x32,0xe2,0x82,0xf1,0x87,0xec,0x31 - ,0x37,0xf1,0x87,0xd1,0xdc,0xd6,0xf1,0x86,0x3c,0x80 - ,0x4c,0xcc,0x80,0x23,0x22,0x31,0x41,0x52,0x7c,0x8d - ,0x9d,0xac,0xab,0x38,0xd8,0xf0,0xd5,0x35,0xf0,0x32 - ,0xd2,0xf0,0x38,0x59,0x69,0xa7,0xb7,0xd8,0xa4,0xf4 - ,0x60,0x40,0x04,0x0b,0x4f,0x6f,0xab,0xa4,0xf0,0x08 - ,0xf6,0xf0,0x0c,0x2e,0x4e,0x5d,0xf3,0x6c,0x8c,0xae - ,0xf7,0xf0,0x00,0x5f,0xa0,0xf0,0x86,0x26,0xf6,0xf0 - ,0x1a,0x5d,0x9a,0xf7,0x05,0xf6,0xf0,0x7e,0x3c,0xf0 - ,0x00,0xf7,0xf0,0xf0,0x00,0x5f,0xa0,0xf0,0x86,0x26 - ,0xf6,0xf0,0x3e,0x7c,0xf7,0xf0,0x9d,0x7b,0x6b,0x5c - ,0xf3,0x4d,0x3d,0x1b,0xf0,0x19,0x59,0x86,0x80,0xf0 - ,0x83,0x50,0x30,0x12,0x14,0x36,0x86,0xf0,0x1b,0x5e - ,0x9b,0x50,0x40,0x13,0x16,0x49,0x59,0x86,0x83,0x50 - ,0xf0,0x78,0x1f,0xf0,0x6e,0x1b,0x53,0x43,0x16,0x19 - ,0x4c,0x5c,0x89,0x86,0x53,0xf0,0x10,0xa0,0xf0,0x8c - ,0x83,0xf3,0x86,0xf7,0x53,0x43,0x16,0x19,0x4c,0x5c - ,0x89,0xaf,0xaf,0x59,0xf0,0x0f,0x59,0x50,0xf0,0x08 - ,0xf6,0xf0,0x1c,0xf2,0x2c,0xf0,0x6c,0xf2,0x7c,0xf0 - ,0x00,0xf7,0xf0,0xa0,0x00,0x0f,0xaf,0xf0,0x78,0x08 - ,0xa0,0x00,0x0f,0xaf,0xf0,0x78,0x08,0xf0,0xf6,0xf0 - ,0x1c,0x5f,0x9c,0xf7,0xf0,0xa4,0xf4,0x60,0x40,0x04 - ,0x0b,0x4f,0x6f,0xab,0xa4,0x05,0xf6,0xf0,0x7e,0x3c - ,0xf0,0x00,0xf7,0xf0,0xa0,0x00,0x0f,0xaf,0xf0,0x78 - ,0x08,0xf6,0xf0,0x3e,0x7c,0xf7,0x1c,0xf2,0x2c,0xf0 - ,0x6c,0xf2,0x7c,0x6c,0xf0,0x83,0xf4,0x50,0x40,0x13 - ,0x16,0x49,0x59,0x86,0x85,0x15,0xf0,0x1a,0x5d,0x9a - ,0xf0,0x0f,0x04,0x40,0x60,0xa4,0xaf,0xf0,0xf6,0xf0 - ,0x1c,0x5f,0x9c,0xf7,0xf0,0x3f,0x7f,0xf0,0x70,0x30 - ,0xf0,0x50,0x5f,0xf0,0xf6,0xf0,0x2c,0xf2,0x3c,0xf0 - ,0x6c,0xf2,0x7c,0xf7,0xf6,0x7e,0x3c,0xf7,0xf0,0x3f - ,0x7f,0xf0,0x70,0x30,0xf0,0x50,0x5f,0xf6,0xf0,0x2e - ,0x7c,0x1a,0x5d,0x9a,0xf0,0x30,0x70,0xf0,0x39,0x59 - ,0x50,0xf0,0x1c,0xf2,0x2c,0xf0,0x6c,0xf2,0x7c,0x6c - ,0x6d,0x2b,0xf0,0x30,0x70,0xf0,0x39,0x59,0x50,0xf0 - ,0x2d,0x6b,0x9d,0x7b,0x6b,0x5c,0xf3,0x4d,0x3d,0x1b - ,0xf0,0x50,0x40,0x13,0x16,0x49,0x59,0x86,0x83,0x50 - ,0xf0,0x1b,0x5e,0x9b,0xf0,0x19,0x13,0x40,0x50,0x83 - ,0xf0,0x89,0x80,0xf6,0x7e,0x3c,0xf7,0xf0,0x0f,0x04 - ,0x40,0x60,0xa4,0xaf,0xf6,0xf0,0x3e,0x7c,0xf7,0xf6 - ,0x7e,0x3c,0xf7,0xf0,0xaf,0xaf,0x59,0xf0,0x0f,0x59 - ,0x50,0xf6,0x7e,0x3c,0xf7,0xf0,0xa4,0xf4,0x60,0x40 - ,0x04,0x0b,0x4f,0x6f,0xab,0xa4,0xf6,0xf0,0x3e,0x7c - ,0xf7,0xf6,0x2e,0x4f,0x6f,0xf1,0x6d,0x3a,0x4a,0xf1 - ,0x58,0x36,0x27,0xf7,0xf0,0xf6,0x2d,0x5e,0x6e,0xf1 - ,0x6c,0x3a,0x6a,0xf1,0x68,0x56,0x27,0xf7,0xf0,0x08 - ,0x98,0xf0,0xf7,0x71,0x7a,0xf4,0x23,0x83,0xf6,0xf0 - ,0xf6,0x3b,0x6e,0x66,0xf7,0xf0,0x08,0x98,0xf0,0xf7 - ,0x29,0x4a,0xf1,0x47,0x33,0x22,0x21,0x71,0xf6,0x4c - ,0xf2,0x5d,0x1c,0xf2,0x2c,0xf0,0x6c,0xf2,0x7c,0x6c - ,0x0e,0x9e,0x01,0xa1,0xf0,0x51,0x5f,0xf7,0x25,0x24 - ,0x33,0x53,0x64,0xf6,0x6d,0x7e,0x8e,0x9e,0xad,0xac - ,0xf0,0x39,0x89,0x60,0x6f,0xf0,0xa2,0x62,0xf1,0x67 - ,0xac,0x0b,0x87,0x03,0xf0,0x4b,0xc7,0x43,0x83,0x07 - ,0x8b,0xf0,0xc3,0x47,0xcb,0x00,0x0a,0x9a,0x90,0x00 - ,0xf7,0x10,0x1e,0xf6,0x1d,0xf0,0x13,0xf4,0x40,0x50 - ,0x83,0x86,0x59,0x49,0x16,0x13,0xf0,0xf7,0x00,0x30 - ,0xf0,0xf6,0x0d,0x3d,0xf8,0x58,0xa8,0xf9,0xf0,0x00 - ,0x0f,0x3f,0xa8,0xa7,0x30,0x00,0xf0,0x5f,0x50,0xf0 - ,0x70,0x7f,0xf0,0x59,0x59,0xf1,0x5c,0x5f,0x9f,0x7d - ,0x4b,0x28,0xf3,0x4a,0xf0,0x6a,0xf3,0x88,0xf0,0x8d - ,0xf3,0x6b,0xf0,0x5c,0x5f,0xf0,0x2d,0xf3,0x4b,0x35 - ,0x10,0x25,0xf2,0x37,0xf0,0x65,0x65,0xf2,0x77}; - -private const ushort arc_symbol_offsets[]={ - 1, 1, 27, 395, 66, 385, 52, 27 - , 165, 229, 106, 106, 22, 106, 8, 389 - , 158, 79, 171, 259, 255, 301, 298, 309 - , 261, 461, 8, 12, 431, 405, 425, 413 - , 437, 249, 204, 189, 216, 180, 181, 187 - , 322, 119, 456, 311, 180, 318, 346, 189 - , 204, 189, 201, 280, 125, 144, 149, 151 - , 222, 589, 226, 586, 585, 582, 907, 720 - ,1502, 492, 515, 495, 491, 495, 561, 518 - , 369, 90, 93,1031, 86, 635, 369, 518 - , 473, 478, 369, 533, 567, 378, 579, 575 - ,1045, 731,1049, 648, 82, 627, 351, 658 - , 505, 103,1129,1095,1082,1103,1118, 431 - , 425,1156, 351, 880, 931, 844,1264, 877 - , 40,1146, 870, 857, 890, 835, 550, 899 - , 909, 919, 890,1039, 155,1000, 405, 589 - , 235, 601, 130, 793,1060,1052,1014,1077 - , 331,1134, 360, 764,1158,1214, 813,1174 - ,1204,1177, 744, 957, 965, 985,1029, 625 - ,1161,1188,1191,1201,1217,1250, 945,1529 - ,1519,1524,1534,1495,1553,1556,1462,1470 - ,1474,1513,1543,1485,1539,1498,1502,1480 - ,1504,1509,1578,1625,1234,1745,1863,1568 - ,1872,1188,2012,2020,2022,2009,1307,1318 - ,1333,1342,1353,1363,1377,1392,1400,1410 - ,1420,1342,1391,1342,1447,1349,1342, 1 - , 0, 0,1271,1279, 27, 906, 719, 330 - ,1299, 0, 657,1501,1498, 0,1495, 0 - ,1591,1635,1604,1613,1699,1766,1720,1775 - ,1754,1798,1841,1805,1845,1824,1860,1829 - ,1728,1881,1936,1931,1666,1676, 280, 533 - ,1691, 722, 731,1919,1903,1791,1891,1908 - ,2051,2058,2065,1990,1979,1965,2070,2070 - ,2107,2141,2043,2027,2094,1651,2119, 764 - ,1283,1625,2139,2121}; - -private const byte arc_symbol_counts[]={ - 0,10,13,11,15,10,14, 6 - , 6, 6,13, 5, 5, 2, 3, 2 - , 7, 3,10, 9, 4,10,11, 3 - ,19,12, 7,10, 3, 5, 3,13 - ,19, 6,13, 9, 7, 7, 6,11 - , 8, 8, 5, 8, 3, 5, 5,10 - , 7,13,10,12, 5, 6, 3, 5 - , 5, 6, 4, 4, 2, 4, 3, 2 - , 2,12,12, 9,13,11, 8,17 - ,10, 9,11, 8, 6,13, 7, 9 - ,15,14, 6,13, 8, 8, 3, 5 - , 5, 8, 4, 9, 5, 9, 8,61 - ,10, 8, 5, 8,13,14,11, 6 - , 6, 3,17,10,14,14, 7, 4 - ,13,10, 8,13, 6,10,11, 7 - ,10,12, 9, 6,10,15, 8,12 - ,20,24,20,20,18,16,15, 5 - ,20,13,16,17,15,15,22,13 - ,10,13,20, 8,20,15, 3, 3 - ,15,12,12,10,17,14,13, 5 - , 5, 5, 5, 3, 8,12, 8, 6 - , 6, 6,10,10, 4, 3, 2, 5 - , 5, 6,20,22,16,16, 9,23 - ,19,12, 8, 2, 5, 3,11,15 - , 9,11,10,14,14, 8,10,10 - ,27,21, 9, 7,15, 4, 4, 0 - , 0, 0, 8, 4, 6, 4, 3,16 - , 8, 1,62, 3, 3, 1, 3, 0 - ,13,16,16,12,21,21,14,16 - ,12,15,10,19,15,13, 9,12 - ,17,14,15,15,12,15,18,17 - ,22,17,13,12,11,14,12,11 - , 7, 7, 5,19,16,25,24,16 - ,12, 8, 8,16,13,15, 2,20 - ,16,10, 2,18}; - -private const byte arc_symbol_widths[] = { - 0, 6, 9, 9,10,10,11, 4,13, 4, - 8, 8, 6, 8, 6,10,10, 5,13,10, - 10,10, 9,10,10,10, 6, 6, 8, 8, - 8, 8,10,10,10,10,10,10,10,10, - 10, 7, 8,10,10,10,10,10, 9,10, - 10,10,10, 9,10,10,10,10,10,10, - 10, 3,10,14, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 7, 5, 8, 7,11, 8, 8, - 7, 8, 8, 8, 7, 7, 9, 9, 8, 9, - 8,11, 3, 4, 8,14, 9, 8,14,14, - 14, 5,14, 8, 8, 3, 8, 9,10, 9, - 9,10, 9,11, 5,10, 8, 9,11,10, - 10, 8, 8, 6,10, 9, 8,10, 8,10, - 9, 8, 8, 8,10, 5, 9, 9, 9,10, - 8, 8, 9, 8, 7, 8, 8,10, 8,10, - 9, 9, 8, 8, 8, 7, 8,10,10,13, - 14,14,13,14,13,13, 8,10,10,10, - 10,13,12, 7, 7,14,11,10, 9,11, - 10,10, 7,10, 9, 8, 8, 9,10, 6, - 14,13,14,14,14,14,14,14,14,14, - 14,14,14, 8,14,14, 8, 0, 0, 0, - 10, 6, 4,10,14, 9, 5, 0,14, 7, - 7, 0,14, 0,10, 9,10,10, 8, 8, - 10, 9,10, 9, 9, 8, 8, 7, 7, 7, - 10, 9,10,10,10,10,10, 8,10, 8, - 9,10, 9, 9, 9, 9,12,12, 9, 9, - 9, 9, 7, 7, 9, 9,11,10,18, 8, - 7,10, 8, 9, 3, 8, - 0 -}; - -/* Enumerate the segments of a stick/arc character. */ -/* We break this out so that we can use it for calculating escapements. */ -int -hpgl_stick_arc_segments(const hpgl_stick_segment_procs_t *procs, void *data, - uint char_index, floatp chord_angle) -{ const byte *ptr; - const byte *end; - gs_int_point prev; - gs_int_point shift; - bool draw = false; - enum { - arc_direction_other, - arc_direction_vertical, - arc_direction_horizontal - } direction = arc_direction_other; - int code = 0; - - ptr = &arc_symbol_strokes[arc_symbol_offsets[char_index - 0x20]]; - end = ptr + arc_symbol_counts[char_index - 0x20]; - prev.x = prev.y = 0; - shift.x = shift.y = 0; - while ( ptr < end ) { - int x = *ptr >> 4; - int y = *ptr++ & 0x0f; - int dx, dy; - - if ( x == 0xf ) { - /* Special function */ - switch ( (arc_op_t)y ) - { - case arc_op_pen_up: - draw = false; - continue; - case arc_op_draw_180: - draw = true; - x = (*ptr >> 4) + shift.x; - y = (*ptr++ & 0x0f) + shift.y; - code = (*procs->arc)(data, x, y, &prev, -180, chord_angle); - prev.x = x * 2 - prev.x, prev.y = y * 2 - prev.y; - break; - case arc_op_draw_360: - draw = true; - x = (*ptr >> 4) + shift.x; - y = (*ptr++ & 0x0f) + shift.y; - code = (*procs->arc)(data, x, y, &prev, -360, chord_angle); - prev.x = x, prev.y = y; - break; - case arc_op_line_45: - draw = true; - x = (*ptr >> 4) + shift.x; - y = (*ptr++ & 0x0f) + shift.y; - code = (*procs->line)(data, x - prev.x, y - prev.y); - direction = - (x == prev.x && y != prev.y ? arc_direction_vertical : - y == prev.y && x != prev.x ? arc_direction_horizontal : - arc_direction_other); - prev.x = x, prev.y = y; - break; - case arc_op_vertical: - direction = arc_direction_vertical; - continue; - case arc_op_BS: - /****** WHAT TO DO? ******/ - continue; - case arc_op_up_5: - shift.y += 5; - continue; - case arc_op_down_5: - shift.y -= 5; - continue; - case arc_op_back_8: - shift.x += 8; - continue; - case arc_op_forward_8: - shift.x -= 8; - continue; - } - } else { - /* Normal segment */ - x += shift.x; - y += shift.y; - dx = x - prev.x; - dy = y - prev.y; - if ( !draw ) { - code = (*procs->move)(data, dx, dy); - direction = - (x == prev.x ? arc_direction_vertical : - y == prev.y ? arc_direction_horizontal : - arc_direction_other); - draw = true; - } else { - if ( any_abs(dx) == any_abs(dy) && - direction != arc_direction_other - ) { - /* 45 degree move following horizontal or vertical */ - if ( direction == arc_direction_vertical ) { - /* - * If the current point is in quadrant 2 or 4 relative to - * the previous, draw the arc counter-clockwise, otherwise - * draw clockwise. - */ - bool clockwise = !((dx > 0) ^ (dy > 0)); - - code = (*procs->arc)(data, x, prev.y, &prev, - (clockwise ? -90 : 90), chord_angle); - direction = arc_direction_horizontal; - } else { - /* direction == arc_direction_horizontal */ - /* - * If the current point is in quadrant 2 or 4 relative to - * the previous, draw the arc clockwise, otherwise - * draw counter-clockwise. - */ - bool clockwise = (dx > 0) ^ (dy > 0); - - code = (*procs->arc)(data, prev.x, y, &prev, - (clockwise ? -90 : 90), chord_angle); - direction = arc_direction_vertical; - } - } else { - /* Not 45 degree case, just draw the line. */ - code = (*procs->line)(data, dx, dy); - direction = - (dx == 0 ? arc_direction_vertical : - dy == 0 ? arc_direction_horizontal : - arc_direction_other); - } - } - prev.x = x, prev.y = y; - } - if ( code < 0 ) - break; - } - return 0; -} - -/* Get the unscaled width of a stick/arc character. */ -int -hpgl_stick_arc_width(uint char_index) -{ /* Add a little for inter-character spacing. */ - return arc_symbol_widths[char_index - 0x20] + 3; -} - -#ifdef ESCAPEMENTS - -/* - * Main program for computing escapements. Compile with: - * gcc -I../gs -DESCAPEMENTS -lm pgfdata.c - */ -#include "math_.h" -typedef struct esc_data_s { - int x; - int xmin, xmax; -} esc_data_t; -private void -esc_include(esc_data_t *edata, int x) -{ if ( x < edata->xmin ) - edata->xmin = x; - if ( x > edata->xmax ) - edata->xmax = x; -} - -private int -esc_rmoveto(void *data, int dx, int dy) -{ esc_data_t *edata = data; - - esc_include(edata, edata->x += dx); - return 0; -} -private int -esc_arc(void *data, int cx, int cy, const gs_int_point *start, - int sweep_angle, floatp chord_angle) -{ esc_data_t *edata = data; - int dx = start->x - cx, dy = start->y - cy; - double radius, angle; - - if ( dx == 0 ) { - radius = any_abs(dy); - angle = (dy >= 0 ? 90.0 : 270.0); - } else if ( dy == 0 ) { - radius = any_abs(dx); - angle = (dx >= 0 ? 0.0 : 180.0); - } else { - radius = hypot((floatp)dx, (floatp)dy); - angle = atan2((floatp)dy, (floatp)dx) * radians_to_degrees; - } - { double count = ceil(any_abs(sweep_angle) / chord_angle); - double delta = sweep_angle / count; - - while ( count-- ) { - double cosv = cos(angle += delta); - - esc_include(edata, (int)(cx + cosv * radius + 0.5)); - } - } - return 0; -} - -const hpgl_stick_segment_procs_t esc_procs = { - esc_rmoveto, esc_rmoveto, esc_arc -}; - -int -main(int argc, char *argv[]) -{ uint index; - - printf("private const byte arc_symbol_widths[] = {"); - for ( index = 0x20; index < 0x20 + hpgl_stick_num_symbols; ++index ) - { esc_data_t edata; - uint count = index - 0x20; - - edata.x = 0; - edata.xmin = 100; - edata.xmax = 0; - hpgl_stick_arc_segments(&esc_procs, (void *)&edata, index, 22.5); - if ( edata.xmin == 100 ) - edata.xmin = 0; - if ( count % 10 == 0 ) { - printf("\n "); - } - printf("%2d,", edata.xmax); - } - printf("\n 0\n};\n"); - return 0; -} - -#endif /* ESCAPEMENTS */ - -#ifdef OUTLINES - -/* - * Main program for printing outlines. Compile with: - * gcc -I../gs -DOUTLINES -lm pgfdata.c - */ -#include "math_.h" - -private int -out_rmoveto(void *data, int dx, int dy) -{ printf(" %d %d rmoveto", dx, dy); - return 0; -} -private int -out_rlineto(void *data, int dx, int dy) -{ printf(" %d %d rlineto", dx, dy); - return 0; -} -private int -out_arc(void *data, int cx, int cy, const gs_int_point *start, - int sweep_angle, floatp chord_angle) -{ int sx = start->x, sy = start->y; - int dx = sx - cx, dy = sy - cy; - double radius, angle; - - if ( dx == 0 ) { - radius = any_abs(dy); - angle = (dy >= 0 ? 90.0 : 270.0); - } else if ( dy == 0 ) { - radius = any_abs(dx); - angle = (dx >= 0 ? 0.0 : 180.0); - } else { - radius = hypot((floatp)dx, (floatp)dy); - angle = atan2((floatp)dy, (floatp)dx) * radians_to_degrees; - } - printf(" %d %d %g %g %g %s", cx, cy, radius, angle, - angle + sweep_angle, - (sweep_angle < 0 ? "arcn" : "arc")); - return 0; -} - -const hpgl_stick_segment_procs_t out_procs = { - out_rmoveto, out_rlineto, out_arc -}; - -int -main(int argc, char *argv[]) -{ uint index; - - for ( index = 0x20; index < 0x20 + hpgl_stick_num_symbols; ++index ) - { uint count = index - 0x20; - - printf("%d {\n", count); - hpgl_stick_arc_segments(&out_procs, (void *)0, index, 0.0); - printf("\n} defchar\n"); - } - return 0; -} - -#endif /* OUTLINES */ - -/* Unicode to symbol index mapping */ - -/* - * The H-P plotter symbol set includes quite a few symbols that aren't - * in Unicode, plus what appear to be many duplicate symbols. - * The following table includes a fair number of educated guesses, - * and some missing mappings. - * - * H-P numbers their symbols starting at 32, so we do too. - * The table below is indexed by symbol number - 32. - */ - -private const ushort hpgl_stick_to_unicode[hpgl_stick_num_symbols] = { - /* The first 92 symbols are 1-for-1 with the corresponding Unicode. */ -/* 32 (0x20) */ - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, -/* 48 (0x30) */ - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, -/* 64 (0x40) */ - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, -/* 80 (0x50) */ - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, -/* 96 (0x60) */ - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, -/* 112 (0x70) */ - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007a, 0x007b, - 0x00a6, /* broken vertical bar */ - 0x007d, /* right brace */ - 0x007e, /* tilde */ - 0x25a0, /* solid black square (DEL) */ -/* 128 (0x80) */ - 0x00f7, /* division symbol */ - 0x00b1, /* plus-minus */ - 0xffff, /* small superscript x */ - 0x00b2, /* small superscript 2 */ - 0x00b3, /* small superscript 3 */ - 0xffff, /* small subscript 10 */ - 0xffff, /* small subscript e */ - 0x2264, - 0x2265, - 0x00b0, /* (duplicate) degree symbol */ - 0x2248, - 0x03a9, - 0x03b1, - 0x03b2, - 0x03b3, - 0x0394, -/* 144 (0x90) */ - 0x03b5, /* small epsilon */ - 0x03b8, - 0x03bb, - 0x00b5, - 0x03bd, - 0x03c0, - 0x03c1, - 0x03a3, - 0x03c3, - 0x00f8, - 0x03c8, - 0xffff, /* small upward arrow */ - 0x2205, - 0x00a4, - 0x2260, - 0x00a5, -/* 160 (0xa0) */ - 0x00c4, /* capital A diaeresis */ - 0x00d6, - 0x00dc, - 0x00e4, - 0x00f6, - 0x00fc, - 0x00df, - 0x00a1, - 0x00d1, - 0x00bf, - 0x00f1, - 0x00a3, - 0x00e0, - 0x00e7, - 0x00a7, - 0x00e9, -/* 176 (0xb0) */ - 0x00f9, /* small u grave */ - 0x00e8, - 0xffff, /* small a (or o?) ring */ - 0x00c6, - 0x00e6, - 0x00c5, - 0x02c6, - 0x02c7, - 0x00e1, - 0x00f2, - 0x00f3, - 0x00fa, - 0x00e7, - 0xffff, /* capital sharp s?? (no such letter) */ - 0x00d8, - 0x2229, -/* 192 (0xc0) */ - 0x2283, /* includes symbol */ - 0x2282, - 0x222a, - 0xffff, /* long overscore */ - 0x2261, - 0x2245, - 0x2213, - 0x2192, - 0x2190, - 0x2193, - 0x222b, - 0x2217, - 0x2207, - 0x02ca, - 0x02cb, - 0x221a, -/* 208 (0xd0) */ - 0x22a2, /* right tack */ - 0x2191, - 0x00c3, - 0x00e3, - 0x00c7, - 0x00c9, - 0x00ec, - 0x00d5, - 0x00f5, - 0x00f2, - 0xffff, /* duplicate diaeresis? */ - 0xffff, /* macron? */ - 0x22a5, - 0xffff, /* duplicate ring/degree? */ - 0xffff, /* square with top vertical tick */ - 0xffff, /* rounded square with top vertical tick */ -/* 224 (0xe0) */ - 0xffff, /* upward triangle with top vertical tick */ - 0xffff, /* large plus sign */ - 0xffff, /* large X / multiply sign */ - 0xffff, /* 45 degree tilted square with top v. tick */ - 0xffff, /* upward pointing arrow with open tri. head */ - 0xffff, /* X with closed top */ - 0xffff, /* large Z with small bar */ - 0xffff, /* large Y */ - 0xffff, /* large X with center replaced by small */ - /* square with top vertical tick */ - 0xffff, /* large 8-point star */ - 0xffff, /* X with closed top and bottom */ - 0x007c, - 0x2721, - 0xffff, /* em dash? */ - 0xffff, /* top vertical tick */ - 0xffff, /* (undefined) */ -/* 240 (0xf0) */ - 0xffff, /* (undefined) */ - 0xffff, /* (undefined) */ - 0x00a8, - 0x02da, - 0x02c8, - 0xffff, /* duplicate circumflex? */ - 0xffff, /* duplicate em dash? */ - 0xffff, /* raised large tilde */ - 0x02dc, /* raised small tilde */ - 0xffff, /* (undefined) */ - 0x25a0, /* (duplicate) black square */ - 0x02cb, /* (duplicate) grave accent */ - 0x02ca, /* (duplicate) acute accent */ - 0xffff, /* (undefined) */ - 0xffff, /* long macron */ - 0xffff, /* (undefined) */ -/* 256 (0x100) */ - 0x00c2, /* capital A circumflex */ - 0x00e2, - 0x00c1, - 0x00c0, - 0x00cb, - 0x00eb, - 0x00ca, - 0x00ea, - 0x00c8, - 0x00ce, - 0x00ee, - 0x00cf, - 0x00ef, - 0x00cd, - 0x00ed, - 0x00cc, -/* 272 (0x110) */ - 0x00d4, /* capital O circumflex */ - 0x00f4, - 0x00d2, - 0x00d3, - 0x00ba, - 0x00aa, - 0x0160, - 0x0161, - 0x0178, - 0x00ff, - 0x00fd, - 0x00dd, - 0x00da, - 0x00db, - 0x00fb, - 0x00d9, -/* 288 (0x120) */ - 0x00bb, /* double guillemet right */ - 0x00ab, - 0x25a1, - 0x00bd, - 0x00bc, - 0x00be, - 0x00de, /* capital Thorn (maybe small?) */ - 0x00fe, /* small thorn (maybe capital?) */ - 0x00b6, - 0xffff, /* infinity sign? */ - 0x00a2, - 0x0192, - 0x00d0, - 0x00f0, - 0x02ca, /* (duplicate) acute accent? */ - 0x20a4, -/* 304 (0x130) */ - 0x00e5, /* small a tilde */ - 0xffff, /* (duplicate) tilde? */ - 0xffff, /* straight comma */ - 0xffff /* 5-pointed asterisk */ -}; - -/* - * Some stick font symbols have more than 1 plausible Unicode mapping. - * Define those here. - */ - -private const ushort hpgl_stick_alt_unicode[] = { - 139, 0x2126, /* capital Omega = ohm symbol */ - 143, 0x2206, /* capital Delta = increment */ - 143, 0x25b3, /* = upward-pointing triangle */ - 147, 0x03bc, /* micro = small mu */ - 151, 0x2211, /* capital Sigma = summation */ - 204, 0x25bd, /* nabla = downward-pointing triangle */ - 288, 0x226b, /* double guil. right = much greater than */ - 289, 0x226a /* double guil. left = much less than */ -}; - -/* - * Map a Unicode character number to an index in the stick/arc font - * symbol table. Return 0 if not mappable. (The first real symbol - * index is 32.) - */ -uint -hpgl_unicode_stick_index(gs_glyph char_code) -{ if ( char_code < 0x20 ) - return 0; - if ( char_code <= 0x7b ) - return char_code; - if ( char_code == 0xffff ) - return 0; - /* Search the table. This is slow. */ - { uint i; - - for ( i = 0x7c - 0x20; i < countof(hpgl_stick_to_unicode); ++i ) - if ( hpgl_stick_to_unicode[i] == char_code ) - return i + 0x20; - /* Look for an alternate mapping. */ - for ( i = 0; i < countof(hpgl_stick_alt_unicode); i += 2 ) - if ( hpgl_stick_alt_unicode[i+1] == char_code ) - return hpgl_stick_alt_unicode[i]; - } - return 0; -} - diff --git a/pcl/pgfdata.h b/pcl/pgfdata.h deleted file mode 100644 index f528618f5..000000000 --- a/pcl/pgfdata.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgfdata.h */ -/* Interface to HP-GL/2 stick and arc font data */ - -/* We use 'stick' instead of 'stick_or_arc' below just because it's shorter. */ - -/* The arc font is just a condensed version of the stick font, */ -/* with minimal inter-character spacing. */ -#define hpgl_arc_font_condensation 0.70 - -/* Define the procedures for processing segments. */ -typedef int (*hpgl_stick_move_proc_t)(P3(void *data, int dx, int dy)); -typedef int (*hpgl_stick_line_proc_t)(P3(void *data, int dx, int dy)); -typedef int (*hpgl_stick_arc_proc_t)(P6(void *data, int cx, int cy, - const gs_int_point *start, int sweep_angle, floatp chord_angle)); -typedef struct hpgl_stick_segment_procs_s { - hpgl_stick_move_proc_t move; - hpgl_stick_line_proc_t line; - hpgl_stick_arc_proc_t arc; -} hpgl_stick_segment_procs_t; - -/* Enumerate the segments of a stick/arc character. */ -/* We break this out so that we can use it for calculating escapements. */ -int hpgl_stick_arc_segments(P4(const hpgl_stick_segment_procs_t *procs, - void *data, uint char_index, - floatp chord_angle)); - -/* Get the unscaled width of a stick/arc character. */ -int hpgl_stick_arc_width(P1(uint char_index)); - -/* - * Map a Unicode character number to a stick/arc symbol index. - * Return 0 if not mappable. (The first real symbol index is 32.) - */ -uint hpgl_unicode_stick_index(P1(gs_glyph char_code)); diff --git a/pcl/pgfont.c b/pcl/pgfont.c deleted file mode 100644 index 7bc75afa2..000000000 --- a/pcl/pgfont.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgfont.c */ -/* HP-GL/2 stick and arc font */ -#include "math_.h" -#include "gstypes.h" -#include "gsccode.h" -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" /* for gscoord.h, gspath.h */ -#include "gsmatrix.h" -#include "gscoord.h" -#include "gspaint.h" -#include "gspath.h" -#include "gxfixed.h" /* for gxchar.h */ -#include "gxchar.h" -#include "gxfarith.h" -#include "gxfont.h" -#include "plfont.h" -#include "pgfdata.h" -#include "pgfont.h" - -/* Note that we misappropriate pfont->StrokeWidth for the chord angle. */ - -/* The client handles all encoding issues for these fonts. */ -/* The fonts themselves use Unicode indexing. */ -private gs_glyph -hpgl_stick_arc_encode_char(gs_font *pfont, gs_char chr, gs_glyph not_used) -{ return (gs_glyph)chr; -} - -/* The stick font is fixed-pitch. */ -private int -hpgl_stick_char_width(const pl_font_t *plfont, const pl_symbol_map_t *map, - const gs_matrix *pmat, uint uni_code, gs_point *pwidth) -{ bool in_range = hpgl_unicode_stick_index(uni_code) != 0; - - if ( pwidth ) { - gs_distance_transform(0.667, 0.0, pmat, pwidth); - } - return in_range; -} -/* The arc font is proportionally spaced. */ -private int -hpgl_arc_char_width(const pl_font_t *plfont, const pl_symbol_map_t *map, - const gs_matrix *pmat, uint uni_code, gs_point *pwidth) -{ uint char_code = hpgl_unicode_stick_index(uni_code); - bool in_range = char_code != 0; - - if ( pwidth ) { - gs_distance_transform(hpgl_stick_arc_width(char_code) / 15.0 - * 0.667 * hpgl_arc_font_condensation, - 0.0, pmat, pwidth); - } - return in_range; -} - -/* Forward procedure declarations */ -private int hpgl_arc_rmoveto(P3(void *data, int dx, int dy)); -private int hpgl_arc_rlineto(P3(void *data, int dx, int dy)); -private int hpgl_arc_add_arc(P6(void *data, int cx, int cy, - const gs_int_point *start, int sweep_angle, floatp chord_angle)); - -/* Add a symbol to the path. */ -private int -hpgl_stick_arc_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont, - gs_glyph uni_code, floatp condensation) -{ uint char_index = hpgl_unicode_stick_index(uni_code); - double chord_angle; - int width; - gs_matrix save_ctm; - int code; - - if ( char_index == 0 ) - return 0; - chord_angle = pfont->StrokeWidth; - width = (chord_angle == 0 ? hpgl_stick_arc_width(char_index) : 15); - /* The TRM says the stick font is based on a 32x32 unit cell, */ - /* but the font we're using here is only 15x15. */ - /* Also, per TRM 23-18, the character cell is only 2/3 the */ - /* point size. */ - gs_setcharwidth(penum, pgs, width / 15.0 * 0.667 * condensation, 0.0); - gs_currentmatrix(pgs, &save_ctm); -#define scale (1.0 / 15 * 2 / 3) - gs_scale(pgs, scale * condensation, scale); -#undef scale - gs_moveto(pgs, 0.0, 0.0); - { const hpgl_stick_segment_procs_t draw_procs = { - hpgl_arc_rmoveto, hpgl_arc_rlineto, hpgl_arc_add_arc - }; - code = hpgl_stick_arc_segments(&draw_procs, (void *)pgs, - char_index, chord_angle); - } - gs_setmatrix(pgs, &save_ctm); - if ( code < 0 ) - return code; - /* Set predictable join and cap styles. */ - gs_setlinejoin(pgs, gs_join_round); - gs_setmiterlimit(pgs, 2.61); /* start beveling at 45 degrees */ - gs_setlinecap(pgs, gs_cap_round); - return gs_stroke(pgs); -} - -/* Add a point or line. */ -private int -hpgl_arc_rmoveto(void *data, int dx, int dy) -{ return gs_rmoveto((gs_state *)data, (floatp)dx, (floatp)dy); -} -private int -hpgl_arc_rlineto(void *data, int dx, int dy) -{ return gs_rlineto((gs_state *)data, (floatp)dx, (floatp)dy); -} - -/* Add an arc given the center, start point, and sweep angle. */ -private int -hpgl_arc_add_arc(void *data, int cx, int cy, const gs_int_point *start, - int sweep_angle, floatp chord_angle) -{ gs_state *pgs = (gs_state *)data; - int dx = start->x - cx, dy = start->y - cy; - double radius, angle; - int code = 0; - - if ( dx == 0 ) { - radius = any_abs(dy); - angle = (dy >= 0 ? 90.0 : 270.0); - } else if ( dy == 0 ) { - radius = any_abs(dx); - angle = (dx >= 0 ? 0.0 : 180.0); - } else { - radius = hypot((floatp)dx, (floatp)dy); - angle = atan2((floatp)dy, (floatp)dx) * radians_to_degrees; - } - if ( chord_angle == 0 ) { - /* Just add the arc. */ - code = (sweep_angle < 0 ? - gs_arcn(pgs, (floatp)cx, (floatp)cy, radius, angle, - angle + sweep_angle) : - gs_arc(pgs, (floatp)cx, (floatp)cy, radius, angle, - angle + sweep_angle)); - } else { - double count = ceil(any_abs(sweep_angle) / chord_angle); - double delta = sweep_angle / count; - - while ( count-- ) { - gs_sincos_t sincos; - - angle += delta; - gs_sincos_degrees(angle, &sincos); - code = gs_lineto(pgs, cx + sincos.cos * radius, - cy + sincos.sin * radius); - if ( code < 0 ) - break; - } - } - return code; -} - -private int -hpgl_stick_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont, - gs_char ignore_chr, gs_glyph uni_code) -{ return hpgl_stick_arc_build_char(penum, pgs, pfont, uni_code, 1.0); -} -private int -hpgl_arc_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont, - gs_char ignore_chr, gs_glyph uni_code) -{ return hpgl_stick_arc_build_char(penum, pgs, pfont, uni_code, - hpgl_arc_font_condensation); -} - -/* Fill in stick/arc font boilerplate. */ -private void -hpgl_fill_in_stick_arc_font(gs_font_base *pfont, long unique_id) -{ /* The way the code is written requires FontMatrix = identity. */ - gs_make_identity(&pfont->FontMatrix); - pfont->FontType = ft_user_defined; - pfont->PaintType = 1; /* stroked fonts */ - pfont->BitmapWidths = false; - pfont->ExactSize = fbit_use_outlines; - pfont->InBetweenSize = fbit_use_outlines; - pfont->TransformedChar = fbit_use_outlines; - pfont->procs.encode_char = (void *)hpgl_stick_arc_encode_char; /* FIX ME (void *) */ - /* p.y of the FontBBox is a guess, because of descenders. */ - /* Because of descenders, we have no real idea what the */ - /* FontBBox should be. */ - pfont->FontBBox.p.x = 0; - pfont->FontBBox.p.y = -0.333; - pfont->FontBBox.q.x = 0.667; - pfont->FontBBox.q.y = 0.667; - uid_set_UniqueID(&pfont->UID, unique_id); - pfont->encoding_index = 1; /****** WRONG ******/ - pfont->nearest_encoding_index = 1; /****** WRONG ******/ -} -void -hpgl_fill_in_stick_font(gs_font_base *pfont, long unique_id) -{ hpgl_fill_in_stick_arc_font(pfont, unique_id); - pfont->StrokeWidth = 22.5; -#define plfont ((pl_font_t *)pfont->client_data) - pfont->procs.build_char = (void *)hpgl_stick_build_char; /* FIX ME (void *) */ - plfont->char_width = hpgl_stick_char_width; -#undef plfont -} -void -hpgl_fill_in_arc_font(gs_font_base *pfont, long unique_id) -{ hpgl_fill_in_stick_arc_font(pfont, unique_id); - pfont->StrokeWidth = 0; /* don't flatten arcs */ -#define plfont ((pl_font_t *)pfont->client_data) - pfont->procs.build_char = (void *)hpgl_arc_build_char; /* FIX ME (void *) */ - plfont->char_width = hpgl_arc_char_width; -#undef plfont -} diff --git a/pcl/pgfont.h b/pcl/pgfont.h deleted file mode 100644 index f7e4e9fb2..000000000 --- a/pcl/pgfont.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgfont.h */ -/* Definitions for HP-GL/2 stick and arc fonts */ - -#ifndef pgfont_INCLUDED -# define pgfont_INCLUDED - -/* Fill in stick/arc font boilerplate. */ -void hpgl_fill_in_stick_font(P2(gs_font_base *pfont, long unique_id)); -void hpgl_fill_in_arc_font(P2(gs_font_base *pfont, long unique_id)); - -#endif /* pgfont_INCLUDED */ diff --git a/pcl/pgframe.c b/pcl/pgframe.c deleted file mode 100644 index 15b90b405..000000000 --- a/pcl/pgframe.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgframe.c */ -/* PCL5/HP-GL/2 picture frame commands */ -#include "math_.h" -#include "pgmand.h" -#include "pgdraw.h" -#include "pgmisc.h" -#include "gstypes.h" /* for gsstate.h */ -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" -#include "pcdraw.h" -#include "pcfont.h" /* for pcl_continue_underline */ -#include "pcstate.h" - -/* Import the RTL implementation of ESC % # A. */ -extern pcl_command_proc(rtl_enter_pcl_mode); - -/* This routine should only be used by the pcl reset command. We - implicitly enter pcl mode if an ESC E is embedded in the gl/2 - stream. */ - int -pcl_implicit_gl2_finish(pcl_state_t *pcs) -{ - pcs->parse_other = 0; - hpgl_call(hpgl_draw_current_path(pcs, hpgl_rm_vector)); - return 0; -} - -/* Even though these are PCL commands, */ -/* they are only relevant to HPGL. */ - -/* side effects resulting from a change in picture frame size or - anchor point position */ - private int -pcl_set_picture_frame_side_effects(pcl_state_t *pcs) -{ - hpgl_args_t args; - /* default P1 and P2 */ - hpgl_args_setup(&args); - hpgl_IP(&args, pcs); - - /* default the clipping window */ - hpgl_args_setup(&args); - hpgl_IW(&args, pcs); - - /* clear the polygon buffer */ - hpgl_args_set_int(&args,0); - hpgl_PM(&args, pcs); - - hpgl_args_set_int(&args,2); - hpgl_PM(&args, pcs); - - /* NB according to spec should move pen to P1. */ - return 0; -} - - -int /* ESC * c <w_dp> X */ -pcl_horiz_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcs) -{ - coord size = (coord)(float_arg(pargs) * 10.0); /* --> centipoints */ - - if ( size == 0 ) - size = pcs->xfm_state.lp_size.x; - pcs->g.picture_frame_width = size; - pcl_set_picture_frame_side_effects(pcs); - return 0; -} - -int /* ESC * c <h_dp> Y */ -pcl_vert_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcs) -{ - coord size = (coord)(float_arg(pargs) * 10.0); /* --> centipoints */ - - /* default to pcl logical page */ - if ( size == 0 ) { - size = pcs->xfm_state.lp_size.y; - if ( pcs->personality != rtl ) - size -= inch2coord(1.0); - } - pcs->g.picture_frame_height = size; - pcl_set_picture_frame_side_effects(pcs); - return 0; -} - -/* - * ESC * c 0 T - */ - int -pcl_set_pic_frame_anchor_point( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - gs_point tmp_pt; - - if (i != 0) - return 0; - - /* The anchor point is in logical page space */ - tmp_pt.x = pcs->cap.x; - tmp_pt.y = pcs->cap.y; - pcl_xfm_to_logical_page_space(pcs, &tmp_pt); - pcs->g.picture_frame.anchor_point.x = tmp_pt.x; - pcs->g.picture_frame.anchor_point.y = tmp_pt.y; - pcl_set_picture_frame_side_effects(pcs); - return 0; -} - -int /* ESC * c <w_in> K */ -pcl_hpgl_plot_horiz_size(pcl_args_t *pargs, pcl_state_t *pcs) -{ - /* convert to centipoints as to match the picture frame */ - float size = float_arg(pargs) * 7200.0; - - if ( (coord)size == 0 ) { - size = pcs->g.picture_frame_width; - pcs->g.plot_size_horizontal_specified = false; - } - else - pcs->g.plot_size_horizontal_specified = true; - - pcs->g.plot_width = (coord)size; - return 0; -} - -int /* ESC * c <h_in> L */ -pcl_hpgl_plot_vert_size(pcl_args_t *pargs, pcl_state_t *pcs) -{ - /* convert to centipoints as to match the picture frame */ - float size = float_arg(pargs) * 7200.0; - if ( (coord)size == 0 ) { - size = pcs->g.picture_frame_height; - pcs->g.plot_size_vertical_specified = false; - } - else - pcs->g.plot_size_vertical_specified = true; - pcs->g.plot_height = (coord)size; - return 0; -} - -/* We redefine this command so we can draw the current GL path */ -/* and, if appropriate, reset the underline bookkeeping. */ -private int /* ESC % <enum> A */ -pcl_enter_pcl_mode(pcl_args_t *pargs, pcl_state_t *pcs) -{ int code; - - hpgl_call(hpgl_draw_current_path(pcs, hpgl_rm_vector)); - code = rtl_enter_pcl_mode(pargs, pcs); - switch ( code ) - { - default: /* error */ - return code; - case 1: /* CAP changed */ - pcl_continue_underline(pcs); - case 0: /* CAP not changed */ - break; - } - return 0; -} - -/* Initialization */ -private int -pgframe_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_CLASS('*') - {'c', 'X', - PCL_COMMAND("Horizontal Picture Frame Size Decipoints", - pcl_horiz_pic_frame_size_decipoints, - pca_neg_error|pca_big_error)}, - {'c', 'Y', - PCL_COMMAND("Vertical Picture Frame Size Decipoints", - pcl_vert_pic_frame_size_decipoints, - pca_neg_error|pca_big_error)}, - {'c', 'T', - PCL_COMMAND("Set Picture Frame Anchor Point", - pcl_set_pic_frame_anchor_point, - pca_neg_error|pca_big_error)}, - {'c', 'K', - PCL_COMMAND("HP-GL/2 Plot Horizontal Size", - pcl_hpgl_plot_horiz_size, - pca_neg_error|pca_big_error)}, - {'c', 'L', - PCL_COMMAND("HP-GL/2 Plot Vertical Size", - pcl_hpgl_plot_vert_size, - pca_neg_error|pca_big_error)}, - END_CLASS - DEFINE_CLASS('%') - {0, 'A', - PCL_COMMAND("Enter PCL Mode", - pcl_enter_pcl_mode, - pca_neg_ok|pca_big_ok|pca_in_macro|pca_in_rtl)}, - END_CLASS - return 0; -} -const pcl_init_t pgframe_init = { - pgframe_do_registration, 0 -}; diff --git a/pcl/pggeom.c b/pcl/pggeom.c deleted file mode 100644 index 9af8f5f0c..000000000 --- a/pcl/pggeom.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pggeom.c */ -/* HP-GL/2 geometry routines */ - -#include "stdio_.h" -#include "pggeom.h" -#include "gxfarith.h" /* for gs_sincos */ - -/* HAS most of these computations require more error checking */ - -/* ------ Lines, angles, arcs, and chords ------ */ - -/* compute the angle between 0 and 2*PI given the slope */ -floatp -hpgl_compute_angle(floatp dx, floatp dy) -{ - floatp alpha = atan2(dy, dx); - - return (alpha < 0 ? alpha + M_PI * 2.0 : alpha); -} - -/* compute the center of an arc given 3 points on the arc */ -int -hpgl_compute_arc_center(floatp x1, floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, floatp *pcx, floatp *pcy) - -{ - floatp px2, py2, dx2, dy2, px3, py3, dx3, dy3; - double denom, t2; - - /* - * The center is the intersection of the perpendicular bisectors - * of the 3 chords. Any two will do for the computation. - * (For greatest numerical stability, we should probably choose - * the two outside chords, but this is a refinement that we will - * leave for the future.) - * We define each bisector by a line with the equations - * xi = pxi + ti * dxi - * yi = pyi + ti * dyi - * where i is 2 or 3. - */ - -#define compute_bisector(px, py, dx, dy, xa, ya, xb, yb)\ - (px = (xa + xb) / 2, py = (ya + yb) / 2,\ - dx = (ya - yb), dy = (xb - xa) /* 90 degree rotation (either way is OK) */) - - compute_bisector(px2, py2, dx2, dy2, x1, y1, x2, y2); - compute_bisector(px3, py3, dx3, dy3, x1, y1, x3, y3); - -#undef compute_bisector - - /* - * Now find the intersections by solving for t2 or t3: - * px2 + t2 * dx2 = px3 + t3 * dx3 - * py2 + t2 * dy2 = py3 + t3 * dy3 - * i.e., in standard form, - * t2 * dx2 - t3 * dx3 = px3 - px2 - * t2 * dy2 - t3 * dy3 = py3 - py2 - * The solution of - * a*x + b*y = c - * d*x + e*y = f - * is - * denom = a*e - b*d - * x = (c*e - b*f) / denom - * y = (a*f - c*d) / denom - */ - denom = dx3 * dy2 - dx2 * dy3; - if ( fabs(denom) < 1.0e-6 ) - return -1; /* degenerate */ - - t2 = ((px3 - px2) * (-dy3) - (-dx3) * (py3 - py2)) / denom; - *pcx = px2 + t2 * dx2; - *pcy = py2 + t2 * dy2; - return 0; -} - -/* compute the coordinates of a point on an arc */ -int -hpgl_compute_arc_coords(floatp radius, floatp center_x, floatp center_y, - floatp angle, floatp *px, floatp *py) -{ - gs_sincos_t sincos; - gs_sincos_degrees(angle, &sincos); - *px = radius * sincos.cos + center_x; - *py = radius * sincos.sin + center_y; - return 0; -} - -/* given a start point, angle (degrees) and magnitude of a vector compute its - endpoints */ -int -hpgl_compute_vector_endpoints(floatp magnitude, floatp x, floatp y, - floatp angle_degrees, floatp *endx, floatp *endy) - -{ - return hpgl_compute_arc_coords(magnitude, x, y, - angle_degrees, endx, endy); -} diff --git a/pcl/pggeom.h b/pcl/pggeom.h deleted file mode 100644 index a0f3e7796..000000000 --- a/pcl/pggeom.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pggeom.h */ -/* Definitions for HP-GL/2 geometry. */ - -#ifndef pggeom_INCLUDED -# define pggeom_INCLUDED - -#include "math_.h" -#include "gstypes.h" /* for gs_point */ - -/* ------ Useful conversions ------ */ - -/* - * Convert various other kinds of units to plotter units - * (1 plu = 1/40 mm = 1/1016 inch). - */ -#define coord_2_plu(a) ((a) * (1016.0 / 7200.0)) -#define plu_2_coord(a) ((a) * (7200.0 / 1016.0)) -#define points_2_plu(a) ((a) * (1016.0 / 72.0)) -#define mm_2_plu(a) ((a) * 40.0) -#define inches_2_plu(a) ((a) * 1016.0) -#define plu_2_inches(a) ((a) / 1016.0) - -/* ------ Lines, angles, arcs, and chords ------ */ - -/* calculate the distance between 2 points */ -#define hpgl_compute_distance(x1, y1, x2, y2) \ - hypot((x1) - (x2), (y1) - (y2)) - -/* compute the angle between 0 and 2*PI given the slope */ -floatp hpgl_compute_angle(P2(floatp dx, floatp dy)); - -/* compute the center of an arc given 3 points on the arc */ -int hpgl_compute_arc_center(P8(floatp x1, floatp y1, floatp x2, - floatp y2, floatp x3, floatp y3, - floatp *pcx, floatp *pcy)); - -/* compute the coordinates of a point on an arc */ -int hpgl_compute_arc_coords(P6(floatp radius, floatp center_x, - floatp center_y, floatp angle, - floatp *px, floatp *py)); - -/* given a start point, angle (degrees) and magnitude of a vector compute its - endpoints */ -int hpgl_compute_vector_endpoints(P6(floatp magnitude, floatp x, floatp y, - floatp angle_degrees, floatp *endx, - floatp *endy)); - -/* ------ 3-point arcs ------ */ - -#define epsilon (1.0/2048.0) -/* defined with epsilon */ -#define equal(a, b) ((fabs((a)-(b)) < epsilon)) - -/* this definition simplifies subsequent definitions */ -#define equal2(a, b, c, d) ((equal((a), (b))) && (equal((c), (d)))) - -/* points are equal. HAS -- TEST for epsilon */ -#define hpgl_3_same_points(x1, y1, x2, y2, x3, y3) \ - ((equal2((x1), (x2), (x2), (x3))) && (equal2((y1), (y2), (y2), (y3)))) - -/* points are on the same line */ -#define hpgl_3_colinear_points(x1, y1, x2, y2, x3, y3) \ - (equal(((y1) - (y3)) * ((x1) - (x2)), ((y1) - (y2)) * ((x1) - (x3)))) - -/* intermediate is the same as first point or last */ -#define hpgl_3_no_intermediate(x1, y1, x2, y2, x3, y3) \ - ((equal2((x1), (x2), (y1), (y2))) || (equal2((x2), (x3), (y2), (y3)))) - -/* intermediate lies between endpoints */ -#define hpgl_3_intermediate_between(x1, y1, x2, y2, x3, y3) \ - ((((x1) >= (x2)) && ((x2) <= (x3))) && \ - (((y1) >= (y2)) && ((y2) <= (y3)))) - -/* equal endpoints */ -#define hpgl_3_same_endpoints(x1, y1, x2, y2, x3, y3) \ - (equal2((x1), (x3), (y1), (y3))) -#endif /* pggeom_INCLUDED */ diff --git a/pcl/pginit.c b/pcl/pginit.c deleted file mode 100644 index c79e25420..000000000 --- a/pcl/pginit.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pginit.c - Initialization and resetting for HP-GL/2. */ -#include "gx.h" -#include "gsmatrix.h" /* for gsstate.h */ -#include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" /* for gs_setlimitclamp */ -#include "pgmand.h" -#include "pginit.h" -#include "pgdraw.h" -#include "pgmisc.h" -#include "pcpatrn.h" - -/* ------ Internal procedures ------ */ - -/* - * Reset a set of font parameters to their default values. - */ - void -hpgl_default_font_params( - pcl_font_selection_t * pfs -) -{ - pfs->params.symbol_set = 277; /* Roman-8 */ - pfs->params.proportional_spacing = false; - pl_fp_set_pitch_per_inch(&pfs->params, 9); - pfs->params.height_4ths = (int)(11.5*4); - pfs->params.style = 0; - pfs->params.stroke_weight = 0; - pfs->params.typeface_family = 48; /* stick font */ - pfs->font = 0; /* not looked up yet */ -} - -/* - * the following is not consistant with the general model as we - * usually depend upon calling the commands directly to update - * appropriate qtate variables, unfortunately we must guarantee a - * reasonable picture frame, anchor point, and plot size for the rest - * of the hpgl/2 code to function properly, and they must be provided - * all at once. For example documented side effects of changing the - * vertical picture frame height are IP;IW;PM;PM2, but these commands - * do not make sense if the horizontal picture frame has never been - * set. - */ - private void -hpgl_default_coordinate_system( - hpgl_state_t * pcs -) -{ - pcs->g.plot_width = pcs->g.picture_frame_width - = pcs->xfm_state.lp_size.x; - pcs->g.plot_height = pcs->g.picture_frame_height - = pcs->xfm_state.lp_size.y; - if ( pcs->personality == rtl ) { - pcs->g.picture_frame.anchor_point.x = 0; - pcs->g.picture_frame.anchor_point.y = 0; - } else { - pcs->g.picture_frame.anchor_point.x = pcs->margins.left; - pcs->g.picture_frame.anchor_point.y = pcs->margins.top; - pcs->g.plot_height -= inch2coord(1.0); - pcs->g.picture_frame_height -= inch2coord(1.0); - } - pcs->g.plot_size_vertical_specified = false; - pcs->g.plot_size_horizontal_specified = false; - /* The default coordinate system is absolute with the origin at 0,0 */ - pcs->g.move_or_draw = hpgl_plot_move; - pcs->g.relative_coords = hpgl_plot_absolute; - { - gs_point pos; - pos.x = 0.0; - pos.y = 0.0; - (void)hpgl_set_current_position(pcs, &pos); - } - pcs->g.scaling_type = hpgl_scaling_none; - return; -} - -/* - * Reset all the fill patterns to solid fill. - */ - void -hpgl_default_all_fill_patterns( - hpgl_state_t * pgls -) -{ - int i; - - for (i = 1; i <= 8; ++i) - (void)pcl_pattern_RF(i, NULL, pgls); -} - - void -hpgl_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - /* pgframe.c (Chapter 18) */ - hpgl_args_t hpgl_args; - - if ((type & (pcl_reset_initial | pcl_reset_printer | pcl_reset_cold)) != 0 ) { - if ((type & (pcl_reset_initial | pcl_reset_cold)) != 0) { - gx_path_alloc_contained( &pcs->g.polygon.buffer.path, - pcs->memory, - "hpgl_do_reset polygon buffer" - ); - - /* - * HAS This is required for GL/2 but probably should - * be maintained locally in gl/2's state machinery - */ - gs_setlimitclamp(pcs->pgs, true); - } else - gx_path_new(&pcs->g.polygon.buffer.path); - - /* provide default anchor point, plot size and picture frame size */ - hpgl_default_coordinate_system(pcs); - - /* we should not have a path at this point but we make sure */ - hpgl_clear_current_path(pcs); - - /* Initialize stick/arc font instances */ - pcs->g.stick_font[0][0].pfont = - pcs->g.stick_font[0][1].pfont = - pcs->g.stick_font[1][0].pfont = - pcs->g.stick_font[1][1].pfont = 0; - - /* execute only the implicit portion of IN */ - hpgl_IN_implicit(pcs); - } - - /* NB check all of these */ - if ((type & pcl_reset_page_params) != 0) { - /* provide default anchor point, plot size and picture frame size */ - hpgl_default_coordinate_system(pcs); - hpgl_args_setup(&hpgl_args); - hpgl_IW(&hpgl_args, pcs); - hpgl_args_set_int(&hpgl_args,0); - hpgl_PM(&hpgl_args, pcs); - hpgl_args_set_int(&hpgl_args,2); - hpgl_PM(&hpgl_args, pcs); - } - - if ((type & pcl_reset_picture_frame) != 0) { - /* this shouldn't happen. Picture frame side effects are - handled directly by the command picture frame command. */ - dprintf("PCL reset picture frame received\n"); - } - - if ((type & pcl_reset_overlay) != 0) - hpgl_reset_overlay(pcs); - - if ((type & (pcl_reset_plot_size)) != 0) { - /* this shouldn't happen. Plot size side effects are handled - directly by the command picture frame command. */ - dprintf("PCL reset plot received\n"); - } - - if ((type & (pcl_reset_permanent)) != 0 ) - gx_path_free(&pcs->g.polygon.buffer.path, "hpgl_do_reset polygon buffer"); - return; -} - -/* ------ Copy the HP-GL/2 state for macro call/overlay/exit. */ - - private int -hpgl_do_copy( - pcl_state_t * psaved, - const pcl_state_t * pcs, - pcl_copy_operation_t operation -) -{ - if ((operation & pcl_copy_after) != 0) { - /* Don't restore the polygon buffer. (Copy from pcs to psaved.) */ - } - return 0; -} - -const pcl_init_t pginit_init = { 0, hpgl_do_reset, hpgl_do_copy }; diff --git a/pcl/pginit.h b/pcl/pginit.h deleted file mode 100644 index cd12317be..000000000 --- a/pcl/pginit.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pginit.h - Interface to initialize/reset procedures in pginit.c */ - -#ifndef pginit_INCLUDED -#define pginit_INCLUDED - -#include "gx.h" -#include "pcstate.h" -#include "pcommand.h" -#include "pgmand.h" - -/* Reset a set of font parameters to their default values. */ -void hpgl_default_font_params(P1( pcl_font_selection_t * pfs )); - -/* Reset all the fill patterns to solid fill. */ -void hpgl_default_all_fill_patterns(P1( hpgl_state_t * pgls )); - -/* Reset (parts of) the HP-GL/2 state. */ -void hpgl_do_reset(P2( pcl_state_t * pcs, pcl_reset_type_t type )); - -#endif /* pginit_INCLUDED */ diff --git a/pcl/pglabel.c b/pcl/pglabel.c deleted file mode 100644 index e738ab522..000000000 --- a/pcl/pglabel.c +++ /dev/null @@ -1,1311 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pglabel.c - HP-GL/2 label commands */ - -#include "math_.h" -#include "memory_.h" -#include "ctype_.h" -#include "stdio_.h" /* for gdebug.h */ -#include "gdebug.h" -#include "pcparse.h" -#include "plvalue.h" -#include "pgmand.h" -#include "pginit.h" -#include "pgfont.h" -#include "pgdraw.h" -#include "pggeom.h" -#include "pgmisc.h" -#include "pcfsel.h" -#include "pcsymbol.h" -#include "pcpalet.h" -#include "pcdraw.h" -#include "gscoord.h" -#include "gsline.h" -#include "gspath.h" -#include "gsutil.h" -#include "gxchar.h" /* for show enumerator */ -#include "gxfont.h" -#include "gxstate.h" /* for gs_state_client_data */ - -#define STICK_FONT_TYPEFACE 48 - -/* ------ Next-character procedure ------ */ - -/* - * Parse one character from a string. Return 2 if the string is exhausted, - * 0 if a character was parsed, -1 if the string ended in the middle of - * a double-byte character. - */ -private int -hpgl_next_char(gs_show_enum *penum, const hpgl_state_t *pgls, gs_char *pchr) -{ uint i = penum->index; - uint size = penum->text.size; - const byte *p; - - if ( i >= size ) - return 2; - p = penum->text.data.bytes; - if ( pgls->g.label.double_byte ) { - if ( i + 1 >= size ) - return -1; - *pchr = (*p << 8) + p[1]; - penum->index = i + 2; - } else { - *pchr = *p + pgls->g.label.row_offset; - penum->index = i + 1; - } - return 0; -} - -/* - * Map a character through the symbol set, if needed. - */ -private uint -hpgl_map_symbol(uint chr, const hpgl_state_t *pgls) -{ const pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - const pl_symbol_map_t *psm = pfs->map; - - if ( psm == 0 ) - { /* Hack: bound TrueType fonts are indexed from 0xf000. */ - if ( pfs->font->scaling_technology == plfst_TrueType ) - return chr + 0xf000; - return chr; - } - { uint first_code = pl_get_uint16(psm->first_code); - uint last_code = pl_get_uint16(psm->last_code); - - /* - * If chr is double-byte but the symbol map is only - * single-byte, just return chr. - */ - if ( chr < first_code || chr > last_code ) - return (last_code <= 0xff && chr > 0xff ? chr : 0xffff); - else - return psm->codes[chr - first_code]; - } -} - -/* Next-character procedure for fonts in GL/2 mode. NB. this need to - be reworked. */ -private int -hpgl_next_char_proc(gs_show_enum *penum, gs_char *pchr, gs_glyph *pglyph) -{ const pcl_state_t *pcs = gs_state_client_data(penum->pgs); -#define pgls pcs - int code = hpgl_next_char(penum, pgls, pchr); - if ( code ) - return code; - *pglyph = gs_no_glyph; - *pchr = hpgl_map_symbol(*pchr, pgls); -#undef pgls - return 0; -} - -/* ------ Font selection ------- */ - -/* Select primary (0) or alternate (1) font. */ -private void -hpgl_select_font_pri_alt(hpgl_state_t *pgls, int index) -{ - if ( pgls->g.font_selected != index ) { - pgls->g.font_selected = index; - pgls->g.font = 0; - } - return; -} - -/* forward decl */ -private int hpgl_recompute_font(P1(hpgl_state_t *pgls)); - -/* Ensure a font is available. */ -private int -hpgl_ensure_font(hpgl_state_t *pgls) -{ - if ( pgls->g.font == 0 ) - hpgl_call(hpgl_recompute_font(pgls)); - return 0; -} - -/* - * The character complement for the stick font is puzzling: it doesn't seem - * to correspond directly to any of the MSL *or* Unicode symbol set bits - * described in the Comparison Guide. We set the bits for MSL Basic Latin - * (63) and for Unicode ASCII (31), and Latin 1 (30). - */ -private const byte stick_character_complement[8] = { - 0x7f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xfe -}; - -/* Select the stick font, creating it if necessary. */ -/* We break this out only for readability: it's only called in one place. */ -private int -hpgl_select_stick_font(hpgl_state_t *pgls) -{ pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - pl_font_t *font = &pgls->g.stick_font[pgls->g.font_selected] - [pfs->params.proportional_spacing]; - - /* Create a gs_font if none has been created yet. */ - if ( font->pfont == 0 ) - { gs_font_base *pfont = - gs_alloc_struct(pgls->memory, gs_font_base, &st_gs_font_base, - "stick/arc font"); - int code; - - if ( pfont == 0 ) - return_error(e_Memory); - code = pl_fill_in_font((gs_font *)pfont, font, pgls->font_dir, - pgls->memory); - if ( code < 0 ) - return code; - if ( pfs->params.proportional_spacing ) - hpgl_fill_in_arc_font(pfont, gs_next_ids(1)); - else - hpgl_fill_in_stick_font(pfont, gs_next_ids(1)); - font->pfont = (gs_font *)pfont; - font->scaling_technology = plfst_TrueType;/****** WRONG ******/ - font->font_type = plft_Unicode; - memcpy(font->character_complement, stick_character_complement, 8); - } - /* - * The stick/arc font is protean: set its proportional spacing, - * style, and stroke weight parameters to the requested ones. - * We could fill in some of the other characteristics earlier, - * but it's simpler to do it here. - */ - font->params = pfs->params; - font->params.typeface_family = STICK_FONT_TYPEFACE; - /* - * The stick font is defined in a cell that's only 2/3 - * the size of the actual character. - */ - pl_fp_set_pitch_cp(&font->params, 100.0*2/3); - pfs->font = font; - { byte id[2]; - - id[0] = pfs->params.symbol_set >> 8; - id[1] = pfs->params.symbol_set & 255; - pfs->map = pcl_find_symbol_map(pgls, - id, plgv_Unicode); - } - return 0; -} - -/* Check whether the stick font supports a given symbol set. */ -private bool -hpgl_stick_font_supports(const pcl_state_t *pcs, uint symbol_set) -{ pl_glyph_vocabulary_t gv = (pl_glyph_vocabulary_t) - (~stick_character_complement[7] & 07); - byte id[2]; - pl_symbol_map_t *map; - - id[0] = symbol_set >> 8; - id[1] = symbol_set; - if ( (map = pcl_find_symbol_map(pcs, id, gv)) == 0 ) - return false; - return pcl_check_symbol_support(map->character_requirements, - stick_character_complement); -} - -/* Recompute the current font if necessary. */ -private int -hpgl_recompute_font(hpgl_state_t *pgls) -{ pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - - if ( ((pfs->params.typeface_family & 0xfff) == STICK_FONT_TYPEFACE - && pfs->params.style == 0 /* upright */ - && hpgl_stick_font_supports(pgls, - pfs->params.symbol_set)) - /* rtl only has stick fonts */ - || ( pgls->personality == rtl ) - ) - hpgl_call(hpgl_select_stick_font(pgls)); - else - { int code = pcl_reselect_font(pfs, pgls); - - if ( code < 0 ) - return code; - } - pgls->g.font = pfs->font; - pgls->g.map = pfs->map; - return 0; -} - -/* ------ Position management ------ */ - -/* Get a character width in the current font, plus extra space if any. */ -/* If the character isn't defined, return 1, otherwise return 0. */ -private int -hpgl_get_char_width(const hpgl_state_t *pgls, uint ch, hpgl_real_t *width) -{ - uint glyph = hpgl_map_symbol(ch, pgls); - const pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - int code = 0; - gs_point gs_width; - gs_matrix mat; - if ( pgls->g.character.size_mode == hpgl_size_not_set ) { - if ( pfs->params.proportional_spacing ) { - gs_make_identity(&mat); - code = pl_font_char_width(pfs->font, pfs->map, &mat, glyph, - &gs_width); - if ( code >= 0 ) { - *width = gs_width.x * points_2_plu(pfs->params.height_4ths / 4.0); - goto add; - } - code = 1; - } - *width = points_2_plu(pl_fp_pitch_cp(&pfs->params) / 100.0); - } else { - *width = pgls->g.character.size.x; - if (pgls->g.character.size_mode == hpgl_size_relative) - *width *= pgls->g.P2.x - pgls->g.P1.x; - - } - add: - - if ( pgls->g.character.extra_space.x != 0 ) { - /* Add extra space. */ - if ( pfs->params.proportional_spacing && ch != ' ' ) { - /* Get the width of the space character. */ - int scode = - pl_font_char_width(pfs->font, pfs->map, &mat, - hpgl_map_symbol(' ', pgls), &gs_width); - hpgl_real_t extra; - - if ( scode >= 0 ) - extra = gs_width.x * points_2_plu(pfs->params.height_4ths / 4.0); - else - extra = points_2_plu(pl_fp_pitch_cp(&pfs->params) / 100.0); - *width += extra * pgls->g.character.extra_space.x; - } else { - /* All characters have the same width, */ - /* or we're already getting the width of a space. */ - *width *= 1.0 + pgls->g.character.extra_space.x; - } - } - return code; -} -/* Get the cell height or character height in the current font, */ -/* plus extra space if any. */ -private int -hpgl_get_current_cell_height(const hpgl_state_t *pgls, hpgl_real_t *height, - bool cell_height) -{ - const pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - - if ( pgls->g.character.size_mode == hpgl_size_not_set ) { - *height = - (pfs->params.proportional_spacing ? - points_2_plu(pfs->params.height_4ths / 4.0) : - 1.667 * inches_2_plu(pl_fp_pitch_cp(&pfs->params) / 7200.0)); - if ( !cell_height ) - *height *= 0.75; /****** HACK ******/ - } else { - /* character size is actually the cap height see 23-6 */ - *height = pgls->g.character.size.y * 1.5; - if (pgls->g.character.size_mode == hpgl_size_relative) - *height *= pgls->g.P2.y - pgls->g.P1.y; - } - *height *= 1.0 + pgls->g.character.extra_space.y; - return 0; -} - -/* distance tranformation for character slant */ - private int -hpgl_slant_transform_distance(hpgl_state_t *pgls, gs_point *dxy, gs_point *s_dxy) -{ - if ( pgls->g.character.slant && !pgls->g.bitmap_fonts_allowed ) { - gs_matrix smat; - gs_point tmp_dxy = *dxy; - gs_make_identity(&smat); - smat.yx = pgls->g.character.slant; - hpgl_call(gs_distance_transform(tmp_dxy.x, tmp_dxy.y, &smat, s_dxy)); - } - return 0; -} - -/* distance tranformation for character direction */ - private int -hpgl_rotation_transform_distance(hpgl_state_t *pgls, gs_point *dxy, gs_point *r_dxy) -{ - double run = pgls->g.character.direction.x; - double rise = pgls->g.character.direction.y; - if ( rise != 0 ) { - double denom = hypot(run, rise); - gs_point tmp_dxy = *dxy; - gs_matrix rmat; - gs_make_identity(&rmat); - rmat.xx = run / denom; - rmat.xy = rise / denom; - rmat.yx = -rmat.xy; - rmat.yy = rmat.xx; - hpgl_call(gs_distance_transform(tmp_dxy.x, tmp_dxy.y, &rmat, r_dxy)); - } - return 0; -} - -/* Reposition the cursor. This does all the work for CP, and is also */ -/* used to handle some control characters within LB. */ -/* If pwidth != 0, it points to a precomputed horizontal space width. */ -private int -hpgl_move_cursor_by_characters(hpgl_state_t *pgls, hpgl_real_t spaces, - hpgl_real_t lines, const hpgl_real_t *pwidth) -{ - int nx, ny; - double dx = 0, dy = 0; - - hpgl_call(hpgl_ensure_font(pgls)); - - lines *= pgls->g.character.line_feed_direction; - /* For vertical text paths, we have to swap spaces and lines. */ - switch ( pgls->g.character.text_path ) - { - case hpgl_text_right: - nx = spaces, ny = lines; break; - case hpgl_text_down: - nx = lines, ny = -spaces; break; - case hpgl_text_left: - nx = -spaces, ny = -lines; break; - case hpgl_text_up: - nx = -lines, ny = spaces; break; - } - /* calculate the next label position in relative coordinates. */ - if ( nx ) { - hpgl_real_t width; - if ( pwidth != 0 ) - width = *pwidth; - else - hpgl_get_char_width(pgls, ' ', &width); - dx = width * nx; - } - if ( ny ) { - hpgl_real_t height; - pcl_font_selection_t *pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - hpgl_call(hpgl_get_current_cell_height(pgls, &height, true)); - if ( (pfs->params.typeface_family & 0xfff) == STICK_FONT_TYPEFACE ) - dy = ny * height * 1.15; - else - dy = ny * height * 1.2; - } - - /* - * We just computed the deltas in user units if characters are - * using relative sizing, and in PLU otherwise. - * If scaling is on but characters aren't using relative - * sizing, we have to convert the deltas to user units. - */ - if ( pgls->g.scaling_type != hpgl_scaling_none && - pgls->g.character.size_mode != hpgl_size_relative - ) - { - gs_matrix mat; - gs_point user_dxy; - hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - hpgl_call(gs_distance_transform_inverse(dx, dy, &mat, &user_dxy)); - dx = user_dxy.x; - dy = user_dxy.y; - } - - { - gs_point dxy; - dxy.x = dx; - dxy.y = dy; - hpgl_rotation_transform_distance(pgls, &dxy, &dxy); - dx = dxy.x; - dy = dxy.y; - } - /* a relative move to the new position */ - hpgl_call(hpgl_add_point_to_path(pgls, dx, dy, - hpgl_plot_move_relative, true)); - - if ( lines != 0 ) { - /* update the position of the carriage return point */ - pgls->g.carriage_return_pos.x += dx; - pgls->g.carriage_return_pos.y += dy; - } - return 0; -} - -/* Execute a CR for CP or LB. */ -private int -hpgl_do_CR(hpgl_state_t *pgls) -{ - return hpgl_add_point_to_path(pgls, pgls->g.carriage_return_pos.x, - pgls->g.carriage_return_pos.y, - hpgl_plot_move_absolute, - true); -} - -/* CP [spaces,lines]; */ -/* CP [;] */ - int -hpgl_CP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_real_t spaces, lines; - - if ( hpgl_arg_c_real(pargs, &spaces) ) - { - if ( !hpgl_arg_c_real(pargs, &lines) ) - return e_Range; - } - else - { - /* if there are no arguments a carriage return and line feed - is executed */ - hpgl_call(hpgl_do_CR(pgls)); - spaces = 0, lines = -1; - } - return hpgl_move_cursor_by_characters(pgls, spaces, lines, - (const hpgl_real_t *)0); -} - -/* ------ Label buffer management ------ */ - -/* initialize the character buffer, setting state pointers for the - beginning of the character buffer and the current character within - the buffer to position 0. */ - private int -hpgl_init_label_buffer(hpgl_state_t *pgls) -{ - pgls->g.label.char_count = 0; - pgls->g.label.buffer_size = hpgl_char_count; - return ((pgls->g.label.buffer = - gs_alloc_bytes(pgls->memory, hpgl_char_count, - "hpgl_init_label_buffer")) == 0 ? - e_Memory : - 0); -} - -/* release the character buffer */ - private int -hpgl_destroy_label_buffer(hpgl_state_t *pgls) -{ - gs_free_object(pgls->memory, pgls->g.label.buffer, - "hpgl_destroy_label_buffer"); - pgls->g.label.char_count = 0; - pgls->g.label.buffer_size = 0; - pgls->g.label.buffer = 0; - return 0; -} - -/* add a single character to the line buffer */ - private int -hpgl_buffer_char(hpgl_state_t *pgls, byte ch) -{ - /* check if there is room for the new character and resize if - necessary */ - if ( pgls->g.label.buffer_size == pgls->g.label.char_count ) - { /* Resize the label buffer, currently by doubling its size. */ - uint new_size = pgls->g.label.buffer_size << 1; - byte *new_mem = - gs_resize_object(pgls->memory, pgls->g.label.buffer, new_size, - "hpgl_resize_label_buffer"); - - if ( new_mem == 0 ) - return_error(e_Memory); - pgls->g.label.buffer = new_mem; - pgls->g.label.buffer_size = new_size; - } - /* store the character */ - pgls->g.label.buffer[pgls->g.label.char_count++] = ch; - return 0; -} - -/* - * Test whether we can use show instead of charpath followed by - * a GL/2 fill. If so, the library will be able to use its - * character cache. - */ - -private bool -hpgl_use_show(hpgl_state_t *pgls) -{ - /* Show cannot be used if CF is not default since the character - may require additional processing by the line drawing code. */ - if ( (pgls->g.character.fill_mode == 0) && - (pgls->g.character.edge_pen == 0) ) - return true; - else - return false; -} - -/* - * build the path and render it - */ - private int -hpgl_print_char( - hpgl_state_t * pgls, - uint ch -) -{ - int text_path = pgls->g.character.text_path; - const pcl_font_selection_t * pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - const pl_font_t * font = pfs->font; - gs_state * pgs = pgls->pgs; - gs_point pos; - gs_matrix save_ctm; - - /* Set up the graphics state. */ - pos = pgls->g.pos; - - /* - * Reset the 'have path' flag so that the CTM gets reset. - * This is a hack; doing things properly requires a more subtle - * approach to handling pen up/down and path construction. - */ - hpgl_call(hpgl_clear_current_path(pgls)); - - /* - * All character data is relative, but we have to start at - * the right place. - */ - hpgl_call( hpgl_add_point_to_path( pgls, - pos.x, - pos.y, - hpgl_plot_move_absolute, - true - ) ); - hpgl_call(gs_currentmatrix(pgs, &save_ctm)); - - /* - * Reset the CTM if GL/2 scaling is on but we aren't using - * relative-size characters (SR). - */ - hpgl_call(hpgl_set_plu_ctm(pgls)); - - /* - * We know that the drawing machinery only sets the CTM - * once, at the beginning of the path. We now impose the scale - * (and other transformations) on the CTM so that we can add - * the symbol outline based on a 1x1-unit cell. - */ - { - gs_font * pfont = pgls->g.font->pfont; - const float * widths = pcl_palette_get_pen_widths(pgls->ppalet); - float save_width = widths[hpgl_get_selected_pen(pgls)]; - bool save_relative = pgls->g.pen.width_relative; - gs_point scale; - bool bitmaps_allowed = pgls->g.bitmap_fonts_allowed; - bool use_show = hpgl_use_show(pgls); - gs_matrix pre_rmat, rmat, advance_mat; - int angle = -1; /* a multiple of 90 if used */ - int weight = pfs->params.stroke_weight; - gs_text_enum_t *penum; - byte str[1]; - int code; - gs_point start_pt, end_pt; - hpgl_real_t space_width; - int space_code; - hpgl_real_t width; - - /* Handle size. */ - if (pgls->g.character.size_mode == hpgl_size_not_set) { - - /* Scale fixed-width fonts by pitch, variable-width by height. */ - if (pfs->params.proportional_spacing) { - if (pl_font_is_scalable(font)) { - scale.x = points_2_plu(pfs->params.height_4ths / 4.0); - scale.y = scale.x; - } else { - double ratio = (double)pfs->params.height_4ths - / font->params.height_4ths; - - scale.x = ratio * inches_2_plu(1.0 / font->resolution.x); - - /* - * Bitmap fonts use the PCL coordinate system, - * so we must invert the Y coordinate. - */ - scale.y = -(ratio * inches_2_plu(1.0 / font->resolution.y)); - } - } else { - scale.x = points_2_plu( pl_fp_pitch_cp(&pfs->params) / - pl_fp_pitch_cp(&pfs->font->params) ); - scale.y = scale.x; - } - - } else { - /* - * Note that the CTM takes P1/P2 into account unless - * an absolute character size is in effect. - */ - /* HP is really scaling the cap height not the point size. - We assume point size is 1.5 times the point size */ - scale.x = pgls->g.character.size.x * 1.5 * 1.25; - scale.y = pgls->g.character.size.y * 1.5; - if (pgls->g.character.size_mode == hpgl_size_relative) - scale.x *= pgls->g.P2.x - pgls->g.P1.x, - scale.y *= pgls->g.P2.y - pgls->g.P1.y; - if (bitmaps_allowed) /* no mirroring */ - scale.x = fabs(scale.x), scale.y = fabs(scale.y); - } - gs_scale(pgs, scale.x, scale.y); - - /* Handle rotation. */ - { - double run = pgls->g.character.direction.x, - rise = pgls->g.character.direction.y; - - if (pgls->g.character.direction_relative) - run *= pgls->g.P2.x - pgls->g.P1.x, - rise *= pgls->g.P2.y - pgls->g.P1.y; - gs_make_identity(&rmat); - if ((run < 0) || (rise != 0)) { - double denom = hypot(run, rise); - - rmat.xx = run / denom; - rmat.xy = rise / denom; - rmat.yx = -rmat.xy; - rmat.yy = rmat.xx; - if ( bitmaps_allowed && - (run != 0) && - (rise != 0) ) { /* not a multple of 90 degrees */ - /* - * If bitmap fonts are allowed, rotate to the nearest - * multiple of 90 degrees. We have to do something - * special at the end to create the correct escapement. - */ - gs_currentmatrix(pgs, &pre_rmat); - if (run >= 0) { - if (rise >= 0) - angle = (run >= rise ? 0 : 90); - else - angle = (-rise >= run ? 270 : 0); - } else { - if (rise >= 0) - angle = (rise >= -run ? 90 : 180); - else - angle = (-run >= -rise ? 180 : 270); - } - } - gs_concat(pgs, &rmat); - } - } - - /* Handle slant. */ - if (pgls->g.character.slant && !bitmaps_allowed) { - gs_matrix smat; - - gs_make_identity(&smat); - smat.yx = pgls->g.character.slant; - gs_concat(pgs, &smat); - } - - /* - * Patch the next-character procedure. - */ - pfont->procs.next_char_glyph = (void *)hpgl_next_char_proc; /* FIX ME (void *) */ - gs_setfont(pgs, pfont); - - /* - * Adjust the initial position of the character according to - * the text path. - */ - hpgl_call(gs_currentpoint(pgs, &start_pt)); - if (text_path == hpgl_text_left) { - hpgl_get_char_width(pgls, ch, &width); - start_pt.x -= width / scale.x; - hpgl_call(hpgl_add_point_to_path(pgls, start_pt.x, start_pt.y, - hpgl_plot_move_absolute, false)); - - } - - /* - * Reset the rotation if we're using a bitmap font. - */ - gs_currentmatrix(pgs, &advance_mat); - if (angle >= 0) { - gs_setmatrix(pgs, &pre_rmat); - gs_rotate(pgs, (floatp)angle); - } - - /* - * If we're using a stroked font, patch the pen width to reflect - * the stroke weight. Note that when the font's build_char - * procedure calls stroke, the CTM is still scaled. - ****** WHAT IF scale.x != scale.y? ****** - */ - if (pfont->PaintType != 0) { - int code = 0; - int pen = hpgl_get_selected_pen(pgls); - floatp nwidth; - - if (weight == 9999) - nwidth = save_width / scale.y; - else { - nwidth = 0.05 + weight * (weight < 0 ? 0.005 : 0.010); - pgls->g.pen.width_relative = true; - } - if ((code = pcl_palette_PW(pgls, pen, nwidth)) < 0) { - pgls->g.pen.width_relative = save_relative; - return code; - } - - gs_setlinewidth(pgs, nwidth); - } - - str[0] = ch; - - /* If SP is a control code, get the width of the space character. */ - if (ch == ' ') { - space_code = hpgl_get_char_width(pgls, ' ', &space_width); - if (space_code == 1) { - /* Space is a control code. */ - if ( pl_font_is_scalable(font) ) { - if (pfs->params.proportional_spacing) - space_width = - (coord_2_plu(pl_fp_pitch_cp(&pfs->font->params) - * pfs->params.height_4ths / 4) ) / scale.x; - else - space_width = 1.0; /* NB not sure */ - } else - space_width = - ( coord_2_plu(pl_fp_pitch_cp(&pfs->font->params)) ) / scale.x; - space_width *= (1.0 + pgls->g.character.extra_space.x); - } - } - - /* Check for SP control code. */ - if (ch == ' ' && space_code != 0) { - /* Space is a control code. Just advance the position. */ - gs_setmatrix(pgs, &advance_mat); - hpgl_call(hpgl_add_point_to_path(pgls, space_width, 0.0, - hpgl_plot_move_relative, false)); - hpgl_call(gs_currentpoint(pgs, &end_pt)); - } else { - if (use_show) { - hpgl_call(hpgl_set_drawing_color(pgls, hpgl_rm_character)); - code = gs_show_begin(pgs, (char *)str, 1, pgls->memory, &penum); - } else - code = gs_charpath_begin(pgs, (char *)str, 1, true, pgls->memory, &penum); - if ( code >= 0 ) - code = gs_text_process(penum); - gs_text_release(penum, "hpgl_print_char"); - if ( code < 0 ) - return code; - gs_setmatrix(pgs, &advance_mat); - if (angle >= 0) { - /* Compensate for bitmap font non-rotation. */ - if (text_path == hpgl_text_right) { - hpgl_get_char_width(pgls, ch, &width); - hpgl_call(hpgl_add_point_to_path(pgls, start_pt.x + width / scale.x, - start_pt.y, hpgl_plot_move_absolute, false)); - } - } - hpgl_call(gs_currentpoint(pgs, &end_pt)); - if ( (text_path == hpgl_text_right) && - (pgls->g.character.extra_space.x != 0) ) { - hpgl_get_char_width(pgls, ch, &width); - end_pt.x = start_pt.x + width / scale.x; - hpgl_call(hpgl_add_point_to_path(pgls, end_pt.x, end_pt.y, hpgl_plot_move_absolute, false)); - } - } - /* - * Adjust the final position according to the text path. - */ - switch (text_path) { - case hpgl_text_right: - break; - - case hpgl_text_down: - { - hpgl_real_t height; - - hpgl_call( hpgl_get_current_cell_height( pgls, - &height, - true - ) ); - /* magic number nonsense */ - if ( (pfs->params.typeface_family & 0xfff) == STICK_FONT_TYPEFACE ) - height *= (13.8/16.0); - else - height *= (14.375/16.0); - hpgl_call( hpgl_add_point_to_path(pgls, start_pt.x, end_pt.y - height / scale.y, - hpgl_plot_move_absolute, false) ); - - } - break; - - case hpgl_text_left: - hpgl_call(hpgl_add_point_to_path(pgls, start_pt.x, start_pt.y, - hpgl_plot_move_absolute, false)); - break; - case hpgl_text_up: - { - hpgl_real_t height; - - hpgl_call(hpgl_get_current_cell_height( pgls, - &height, - true - )); - if ( (pfs->params.typeface_family & 0xfff) == STICK_FONT_TYPEFACE ) - height *= (13.8/16.0); - else - height *= (14.375/16.0); - hpgl_call(hpgl_add_point_to_path(pgls, start_pt.x, - end_pt.y + height / scale.y, hpgl_plot_move_absolute, false)); - } - break; - } - - gs_setmatrix(pgs, &save_ctm); - hpgl_call(gs_currentpoint(pgs, &end_pt)); - if (!use_show) - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_character)); - (void )pcl_palette_PW(pgls, hpgl_get_selected_pen(pgls), save_width); - - pgls->g.pen.width_relative = save_relative; - hpgl_call( hpgl_add_point_to_path( pgls, - end_pt.x, - end_pt.y, - hpgl_plot_move_absolute, - true - ) ); - } - - return 0; -} - -/* Determine whether labels can concatenate. */ -/* Note that LO requires a pre-scan iff this is false. */ -private bool -hpgl_can_concat_labels(const hpgl_state_t *pgls) -{ /* The following is per TRM 23-78. */ - static const byte can_concat[22] = { - 0, 9, 1, 3, 8, 0, 2, 12, 4, 6, - 0, 9, 1, 3, 8, 0, 2, 12, 4, 6, - 0, 9 - }; - - return (can_concat[pgls->g.label.origin] & - (1 << pgls->g.character.text_path)) != 0; -} - - -/* return relative coordinates to compensate for origin placement -- LO */ - private int -hpgl_get_character_origin_offset(hpgl_state_t *pgls, int origin, - hpgl_real_t width, hpgl_real_t height, - gs_point *offset) -{ - double pos_x = 0.0, pos_y = 0.0; - double off_x, off_y; - /* stickfonts are offset by 16 grid units or .33 times the - point size. HAS need to support other font types. */ - if ( origin > 10 ) - off_x = off_y = 0.33 * height; - switch ( origin ) - { - case 11: - pos_x = -off_x; - pos_y = -off_y; - case 1: - break; - case 12: - pos_x = -off_x; - case 2: - pos_y = .5 * height; - break; - case 13: - pos_x = -off_x; - pos_y = off_y; - case 3: - pos_y += height; - break; - case 14: - pos_y = -off_y; - case 4: - pos_x = .5 * width; - break; - case 15: - case 5: - pos_x = .5 * width; - pos_y = .5 * height; - break; - case 16: - pos_y = off_y; - case 6: - pos_x = .5 * width; - pos_y += height; - break; - case 17: - pos_x = off_x; - pos_y = -off_y; - case 7: - pos_x += width; - break; - case 18: - pos_x = off_x; - case 8: - pos_x += width; - pos_y = .5 * height; - break; - case 19: - pos_x = off_x; - pos_y = off_y; - case 9: - pos_x += width; - pos_y += height; - break; - case 21: - { - gs_matrix save_ctm; - gs_point pcl_pos_dev, label_origin; - - gs_currentmatrix(pgls->pgs, &save_ctm); - pcl_set_ctm(pgls, false); - hpgl_call(gs_transform(pgls->pgs, (floatp)pgls->cap.x, - (floatp)pgls->cap.y, &pcl_pos_dev)); - gs_setmatrix(pgls->pgs, &save_ctm); - hpgl_call(gs_itransform(pgls->pgs, (floatp)pcl_pos_dev.x, - (floatp)pcl_pos_dev.y, &label_origin)); - pos_x = -(pgls->g.pos.x - label_origin.x); - pos_y = (pgls->g.pos.y - label_origin.y); - } - break; - default: - dprintf("unknown label parameter"); - - } - /* a relative move to the new position */ - offset->x = pos_x; - offset->y = pos_y; - - /* account for character direction and slant */ - hpgl_rotation_transform_distance(pgls, offset, offset); - hpgl_slant_transform_distance(pgls, offset, offset); - return 0; -} - -/* Prints a buffered line of characters. */ -/* If there is a CR, it is the last character in the buffer. */ - private int -hpgl_process_buffer(hpgl_state_t *pgls) -{ - gs_point offset; - hpgl_real_t label_length = 0.0, label_height = 0.0; - bool vertical = hpgl_text_is_vertical(pgls->g.character.text_path); - /* - * NOTE: the two loops below must be consistent with each other! - */ - - { - hpgl_real_t width = 0.0, height = 0.0; - int save_index = pgls->g.font_selected; - int i = 0; - bool first_char_on_line = true; - while ( i < pgls->g.label.char_count ) - { - byte ch = pgls->g.label.buffer[i++]; - - if ( ch < 0x20 && !pgls->g.transparent_data ) - switch (ch) - { - case BS : - if ( width == 0.0 ) /* BS as first char of string */ - { hpgl_call(hpgl_ensure_font(pgls)); - hpgl_get_char_width(pgls, ' ', &width); - hpgl_call(hpgl_get_current_cell_height(pgls, &height, vertical)); - } - if ( vertical ) - { /* Vertical text path, back up in Y. */ - label_height -= height; - if ( label_height < 0.0 ) - label_height = 0.0; - } - else - { /* Horizontal text path, back up in X. */ - label_length -= width; - if ( label_length < 0.0 ) - label_length = 0.0; - } - continue; - case LF : - first_char_on_line = true; - continue; - case CR : - continue; - case FF : - continue; - case HT : - hpgl_call(hpgl_ensure_font(pgls)); - hpgl_get_char_width(pgls, ' ', &width); - width *= 5; - goto acc_ht; - case SI : - hpgl_select_font_pri_alt(pgls, 0); - continue; - case SO : - hpgl_select_font_pri_alt(pgls, 1); - continue; - default : - break; - } - hpgl_call(hpgl_ensure_font(pgls)); - hpgl_get_char_width(pgls, ch, &width); -acc_ht: hpgl_call(hpgl_get_current_cell_height(pgls, &height, vertical)); - if ( vertical ) - { /* Vertical text path: sum heights, take max of widths. */ - const pcl_font_selection_t * pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - if ( !pfs->params.proportional_spacing && - (pfs->params.typeface_family & 0xfff) == STICK_FONT_TYPEFACE ) - height *= (13.80/16.0); - else - height *= (14.375/16.0); - if ( width > label_length ) - label_length = width; - if ( !first_char_on_line ) - label_height += height; - else - first_char_on_line = false; - } - else - { /* Horizontal text path: sum widths, take max of heights. */ - label_length += width; - if ( height > label_height ) - label_height = height; - } - } - hpgl_select_font_pri_alt(pgls, save_index); - } - hpgl_call(hpgl_get_character_origin_offset(pgls, pgls->g.label.origin, - label_length, label_height, - &offset)); - switch ( pgls->g.character.text_path ) - { - case hpgl_text_left: - offset.x -= label_length; - break; - case hpgl_text_down: - offset.y -= label_height; - break; - default: - DO_NOTHING; - } - - /* these units should be strictly plu except for LO 21 */ - if ( pgls->g.label.origin != 21 ) { - gs_matrix mat; - hpgl_compute_user_units_to_plu_ctm(pgls, &mat); - offset.x /= mat.xx; - offset.y /= mat.yy; - } - /* now add the offsets in relative plu coordinates */ - hpgl_call(hpgl_add_point_to_path(pgls, -offset.x, -offset.y, - hpgl_plot_move_relative, false)); - { - int i; - for ( i = 0; i < pgls->g.label.char_count; ++i ) - { byte ch = pgls->g.label.buffer[i]; - - if ( ch < 0x20 && !pgls->g.transparent_data ) - { hpgl_real_t spaces, lines; - - switch (ch) - { - case BS : - spaces = -1, lines = 0; - break; - case LF : - /* - * If the text path is vertical, we must use the - * computed label (horizontal) width, not the width - * of a space. - */ - if ( vertical ) { - const pcl_font_selection_t * pfs = - &pgls->g.font_selection[pgls->g.font_selected]; - hpgl_real_t label_advance; - /* Handle size. */ - if (pgls->g.character.size_mode == hpgl_size_not_set) { - - /* Scale fixed-width fonts by pitch, variable-width by height. */ - if (pfs->params.proportional_spacing) { - if (pl_font_is_scalable(pfs->font)) - label_advance = points_2_plu(pfs->params.height_4ths / 4.0); - else { - double ratio = (double)pfs->params.height_4ths - / pfs->font->params.height_4ths; - label_advance = ratio * inches_2_plu(1.0 / pfs->font->resolution.x); - } - } else - label_advance = points_2_plu( pl_fp_pitch_cp(&pfs->params) / - pl_fp_pitch_cp(&pfs->font->params) ); - } else { - /* - * Note that the CTM takes P1/P2 into account unless - * an absolute character size is in effect. - * - * - * HACKS - I am not sure what this should be the - * actual values ??? - */ - label_advance = pgls->g.character.size.x * 1.5 * 1.25; - if (pgls->g.character.size_mode == hpgl_size_relative) - label_advance *= pgls->g.P2.x - pgls->g.P1.x; - if (pgls->g.bitmap_fonts_allowed) /* no mirroring */ - label_advance = fabs(label_advance); - } - hpgl_move_cursor_by_characters(pgls, 0, -1, - &label_advance); - continue; - } - spaces = 0, lines = -1; - break; - case CR : - hpgl_call(hpgl_do_CR(pgls)); - continue; - case FF : - /* does nothing */ - spaces = 0, lines = 0; - break; - case HT : - /* appears to expand to 5 spaces */ - spaces = 5, lines = 0; - break; - case SI : - hpgl_select_font_pri_alt(pgls, 0); - continue; - case SO : - hpgl_select_font_pri_alt(pgls, 1); - continue; - default : - goto print; - } - hpgl_move_cursor_by_characters(pgls, spaces, lines, - (const hpgl_real_t *)0); - continue; - } -print: hpgl_call(hpgl_ensure_font(pgls)); - hpgl_call(hpgl_print_char(pgls, ch)); - } - } - - pgls->g.label.char_count = 0; - return 0; -} - -/* LB ..text..terminator */ - int -hpgl_LB(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ const byte *p = pargs->source.ptr; - const byte *rlimit = pargs->source.limit; - bool print_terminator = pgls->g.label.print_terminator; - - if ( pargs->phase == 0 ) - { - /* initialize the character buffer and CTM first time only */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - hpgl_call(hpgl_init_label_buffer(pgls)); - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(hpgl_set_clipping_region(pgls, hpgl_rm_vector)); - pgls->g.label.initial_pos = pgls->g.pos; - pargs->phase = 1; - } - - while ( p < rlimit ) - { byte ch = *++p; - if_debug1('I', - (ch == '\\' ? " \\%c" : ch >= 33 && ch <= 126 ? " %c" : - " \\%03o"), - ch); - if ( ch == pgls->g.label.terminator ) - { - if ( !print_terminator ) - { - hpgl_call(hpgl_process_buffer(pgls)); - hpgl_call(hpgl_destroy_label_buffer(pgls)); - pargs->source.ptr = p; - /* - * Depending on the DV/LO combination, conditionally - * restore the initial position, per TRM 23-78. - */ - if ( !hpgl_can_concat_labels(pgls) ) - { /* HAS not sure if this is correct. But - restoring Y causes problems printing - captions in the FTS. */ - hpgl_call(hpgl_add_point_to_path(pgls, - pgls->g.label.initial_pos.x, - pgls->g.pos.y, - hpgl_plot_move_absolute, true)); - } - /* always clear the current path since terminating - carriage returns and linefeeds will leave - "moveto's" in the path */ - hpgl_call(hpgl_clear_current_path(pgls)); - return 0; - } - /* - * Process the character in the ordinary way, then come here - * again. We do things this way to simplify the case where - * the terminator is a control character. - */ - --p; - print_terminator = false; - } - - /* process the buffer for a carriage return so that we can - treat the label origin correctly, and initialize a new - buffer */ - - hpgl_call(hpgl_buffer_char(pgls, ch)); - if ( ch == CR && !pgls->g.transparent_data ) - { - hpgl_call(hpgl_process_buffer(pgls)); - hpgl_call(hpgl_destroy_label_buffer(pgls)); - hpgl_call(hpgl_init_label_buffer(pgls)); - } - } - pargs->source.ptr = p; - return e_NeedData; -} - - int -hpgl_print_symbol_mode_char(hpgl_state_t *pgls) -{ - /* save the original origin since symbol mode character are - always centered */ - int saved_origin = pgls->g.label.origin; - gs_point save_pos = pgls->g.pos; - hpgl_call(hpgl_gsave(pgls)); - /* HAS this need checking. I don't know how text direction - and label origin interact in symbol mode */ - pgls->g.label.origin = 5; - /* HAS - alot of work for one character */ - hpgl_call(hpgl_clear_current_path(pgls)); - hpgl_call(hpgl_init_label_buffer(pgls)); - hpgl_call(hpgl_buffer_char(pgls, pgls->g.symbol_mode)); - hpgl_call(hpgl_process_buffer(pgls)); - hpgl_call(hpgl_destroy_label_buffer(pgls)); - hpgl_call(hpgl_grestore(pgls)); - /* restore the origin */ - pgls->g.label.origin = saved_origin; - hpgl_call(hpgl_set_current_position(pgls, &save_pos)); - return 0; -} - -/* Initialization */ -private int -pglabel_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('C', 'P', hpgl_CP, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - /* LB also has special argument parsing. */ - HPGL_COMMAND('L', 'B', hpgl_LB, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -} -const pcl_init_t pglabel_init = { - pglabel_do_registration, 0 -}; diff --git a/pcl/pglfill.c b/pcl/pglfill.c deleted file mode 100644 index 14b5c8214..000000000 --- a/pcl/pglfill.c +++ /dev/null @@ -1,884 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pglfill.c - HP-GL/2 line and fill attributes commands */ -#include "memory_.h" -#include "pcparse.h" -#include "pgmand.h" -#include "pginit.h" -#include "pggeom.h" -#include "pgdraw.h" -#include "pgmisc.h" -#include "pcdraw.h" -#include "gsuid.h" /* for gxbitmap.h */ -#include "gstypes.h" /* for gxbitmap.h */ -#include "gsstate.h" /* needed by gsrop.h */ -#include "gsrop.h" -#include "gxbitmap.h" -#include "pcpalet.h" -#include "pcpatrn.h" - -/* - * AC [x,y]; Anchor corner for fill offsets, note that this is - * different than the anchor corner of the pcl picture frame. - */ - int -hpgl_AC( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - hpgl_real_t x, y; - - if (hpgl_arg_units(pargs, &x)) { - if (!hpgl_arg_units(pargs, &y)) - return e_Range; - } else { - x = 0.0; - y = 0.0; - } - - /* draw the current path */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.anchor_corner.x = x; - pgls->g.anchor_corner.y = y; - - return 0; -} - -/* - * FT 1|2; - * FT 3[,spacing[,angle]]; - * FT 4[,spacing[,angle]]; - * FT 10[,level]; - * FT 11[,index][,use_pen_1_or_cur_pen]; - varies from documentation - * FT 21[,type]; - * FT 22[,id]; - * FT; - */ - int -hpgl_FT( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int type = hpgl_FT_pattern_solid_pen1; - hpgl_hatch_params_t * params; - - hpgl_arg_int(pargs, &type); - switch (type) { - - case hpgl_FT_pattern_solid_pen1: /* 1 */ - case hpgl_FT_pattern_solid_pen2: /* 2 */ - /* Default all the parameters. */ - pgls->g.fill.param.hatch.spacing = 0; - pgls->g.fill.param.hatch.angle = 0; - pgls->g.fill.param.crosshatch.spacing = 0; - pgls->g.fill.param.crosshatch.angle = 0; - pgls->g.fill.param.shading = 100; - pgls->g.fill.param.user_defined.pattern_index = 1; - pgls->g.fill.param.user_defined.use_current_pen = false; - pgls->g.fill.param.pattern_type = 1; /****** NOT SURE ******/ - pgls->g.fill.param.pattern_id = 0; /****** NOT SURE ******/ - break; - - case hpgl_FT_pattern_one_line: /* 3 */ - params = &pgls->g.fill.param.hatch; - goto hatch; - - case hpgl_FT_pattern_two_lines: /* 4 */ - params = &pgls->g.fill.param.crosshatch; -hatch: - { - hpgl_real_t spacing = params->spacing; - hpgl_real_t angle = params->angle; - - if (hpgl_arg_real(pargs, &spacing)) { - if (spacing < 0) - return e_Range; - hpgl_arg_real(pargs, &angle); - } - - /* - * If the specified spacing is 0, we use 1% of the P1/P2 - * diagonal distance. We handle this when performing the - * fill, not here, because this distance may change - * depending on the position of P1 and P2. - */ - params->spacing = spacing; - params->angle = angle; - } - break; - - case hpgl_FT_pattern_shading: /* 10 */ - { - int level; - - if (hpgl_arg_c_int(pargs, &level)) { - if ((level < 0) || (level > 100)) - return e_Range; - pgls->g.fill.param.shading = level; - } - } - break; - - case hpgl_FT_pattern_RF: /* 11 */ - { - int index, mode; - - /* contrary to the documentation, option 2 is used */ - if (!hpgl_arg_int(pargs, &index)) - index = pgls->g.fill.param.user_defined.pattern_index; - else if ((index < 1) || (index > 8)) - return e_Range; - if (!hpgl_arg_c_int(pargs, &mode)) - mode = pgls->g.fill.param.user_defined.use_current_pen; - else if ((mode & ~1) != 0) - return e_Range; - pgls->g.fill.param.user_defined.pattern_index = index; - pgls->g.fill.param.user_defined.use_current_pen = mode; - } - break; - - case hpgl_FT_pattern_cross_hatch: /* 21 */ - { - int pattern; - - if (hpgl_arg_c_int(pargs, &pattern)) { - if ((pattern < 1) || (pattern > 6)) - return e_Range; - pgls->g.fill.param.pattern_type = pattern; - } - } - break; - - case hpgl_FT_pattern_user_defined: /* 22 */ - { - int32 id; - - if (hpgl_arg_int(pargs, &id)) { - if ((id < 0) || (id > 0xffff)) - return e_Range; - pgls->g.fill.param.pattern_id = id; - } - } - break; - - default: - return e_Range; - } - pgls->g.fill.type = (hpgl_FT_pattern_source_t)type; - return 0; -} - -/* - * LA [kind1,value1[,kind2,value2[,kind3,value3]]]; - */ - int -hpgl_LA( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int cap = pgls->g.line.cap, join = pgls->g.line.join; - hpgl_real_t miter_limit = pgls->g.miter_limit; - bool no_args=true; - int kind; - - while (hpgl_arg_c_int(pargs, &kind)) { - no_args=false; - switch (kind) { - - case 1: /* line ends */ - if ( !hpgl_arg_c_int(pargs, &cap) || (cap < 1) || (cap > 4) ) - return e_Range; - break; - - case 2: /* line joins */ - if ( !hpgl_arg_c_int(pargs, &join) || (join < 1) || (join > 6) ) - return e_Range; - break; - - case 3: /* miter limit */ - if ( !hpgl_arg_c_real(pargs, &miter_limit) ) - return e_Range; - if (miter_limit < 1) - miter_limit = 1; - break; - - default: - return e_Range; - } - } - - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - /* LA1,1,2,1,3,5 is the same as LA */ - if (no_args) { - hpgl_args_setup(pargs); - hpgl_args_add_int(pargs, 1); - hpgl_args_add_int(pargs, 1); - hpgl_args_add_int(pargs, 2); - hpgl_args_add_int(pargs, 1); - hpgl_args_add_int(pargs, 3); - hpgl_args_add_real(pargs, 5.0); - hpgl_LA(pargs, pgls); - return 0; - } - - pgls->g.line.cap = cap; - pgls->g.line.join = join; - pgls->g.miter_limit = miter_limit; - return 0; -} - -/* constant data for default pattern percentages, */ - -private const hpgl_line_type_t hpgl_fixed_pats[8] = { - { 2, { 0.0, 1.0 } }, - { 2, { 0.5, 0.5 } }, - { 2, { 0.7, 0.3 } }, - { 4, { 0.8, 0.1, 0.0, 0.1 } }, - { 4, { 0.7, 0.1, 0.1, 0.1 } }, - { 6, { 0.5, 0.1, 0.1, 0.1, 0.1, 0.1 } }, - { 6, { 0.7, 0.1, 0.0, 0.1, 0.0, 0.1 } }, - { 8, { 0.5, 0.1, 0.0, 0.1, 0.1, 0.1, 0.0, 0.1 } } -}; - -private const hpgl_line_type_t hpgl_adaptive_pats[8] = { - { 3, { 0.0, 1.0, 0.0 } }, - { 3, { 0.25, 0.5, 0.25 } }, - { 3, { 0.35, 0.3, 0.35 } }, - { 5, { 0.4, 0.1, 0.0, 0.1, 0.4 } }, - { 5, { 0.35, 0.1, 0.1, 0.1, 0.35 } }, - { 7, { 0.25, 0.1, 0.1, 0.1, 0.1, 0.1, 0.25 } }, - { 7, { 0.35, 0.1, 0.0, 0.1, 0.0, 0.1, 0.35 } }, - { 9, { 0.25, 0.1, 0.0, 0.1, 0.1, 0.1, 0.0, 0.1, 0.25 } } -}; - - void -hpgl_set_line_pattern_defaults(hpgl_state_t *pgls) -{ - pgls->g.line.current.pattern_length_relative = 0; /* relative */ - pgls->g.line.current.pattern_length = 4.0; /* % of P1 P2 */ - pgls->g.line.current.is_solid = true; - pgls->g.line.current.type = - memcpy( &pgls->g.fixed_line_type, - &hpgl_fixed_pats, - sizeof(hpgl_fixed_pats) - ); - memcpy( &pgls->g.adaptive_line_type, - &hpgl_adaptive_pats, - sizeof(hpgl_adaptive_pats) - ); - - /* initialize the current pattern offset - this is not part of the - command but is used internally to modulate the phase of the - HPGL/2 vector fills. NB - needs a new home. */ - pgls->g.line.current.pattern_offset = 0.0; -} - -/* - * LT type[,length[,mode]]; - * LT99; - * LT; - * NB - needs reorganizing - */ - int -hpgl_LT( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int type; - - /* Draw the current path for any LT command irrespective of - whether or not the the LT changes anything */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - /* no parameter defaults to solid line type - note line type 0 is - for dots, this is the no parameter default. We keep the old - pattern parameters (no update) and save the current pattern - since type 99 can only be invoked if the current line is solid - (i.e. the 99 pattern only needs to be saved here */ - if ( !hpgl_arg_c_int(pargs, &type) ) { - pgls->g.line.saved = pgls->g.line.current; - pgls->g.line.current.is_solid = true; - return 0; - } - - /* 99 restores the previous line type if a solid line type is the - current selection (LT;) LT99 is ignored when a non-solid line - type is in effect, of course the previous line may have been a - solid line resulting in nop. */ - if ( type == 99 && pgls->g.line.current.is_solid == true ) { - pgls->g.line.current = pgls->g.line.saved; - return 0; - } - - /* check line type range */ - if ( type < -8 || type > 8 ) - return e_Range; - /* Initialize, get and check pattern length and mode. If the mode - is relative (0) the units are a % of the distance from P1 to P2 - for the absolute mode units are millimeters */ - { - /* initialize pattern lengths to current state values */ - hpgl_real_t length = pgls->g.line.current.pattern_length; - int mode = pgls->g.line.current.pattern_length_relative; - - /* get/check the pattern length and mode */ - if ( hpgl_arg_c_real(pargs, &length) ) { - if ( length <= 0 ) - return e_Range; - if ( hpgl_arg_c_int(pargs, &mode) ) - if ( (mode != 0) && (mode != 1) ) - return e_Range; - } - - /* if we are here this is a non-solid line and we should be - able to set the rest of the line parameter state values. - NB have not checked if some of these get set if there is a - range error for pattern length or mode. An experiment for - another day... */ - pgls->g.line.current.is_solid = false; - pgls->g.line.current.type = type; - pgls->g.line.current.pattern_length = length; - pgls->g.line.current.pattern_length_relative = mode; - pgls->g.line.current.type = type; - } - return 0; -} - -/* - * MC mode[,opcode]; - */ - int -hpgl_MC( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int mode = 0, opcode; - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - if (hpgl_arg_c_int(pargs, &mode) && ((mode & ~1) != 0)) - return e_Range; - opcode = mode ? 168 : 252; - if ((mode != 0) && hpgl_arg_c_int(pargs, &opcode)) { - if ((opcode < 0) || (opcode > 255)) { - pgls->logical_op = 252; - return e_Range; - } - } - pgls->logical_op = opcode; - return 0; -} - -/* - * PP [mode]; - */ - int -hpgl_PP( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int mode = 0; - - if (hpgl_arg_c_int(pargs, &mode)) { - if ((mode < 0) || (mode > 1)) - return e_Range; - } - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->pp_mode = mode; - return 0; -} - -/* - * PW [width[,pen]]; - */ - int -hpgl_PW( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - /* - * we initialize the parameter to be parsed to either .1 which - * is a % of the magnitude of P1 P2 or .35 MM WU sets up how - * it gets interpreted. - */ - hpgl_real_t param = pgls->g.pen.width_relative ? .1 : .35; - hpgl_real_t width_plu; - int pmin = 0; - int pmax = pcl_palette_get_num_entries(pgls->ppalet) - 1; - - /* - * we maintain the line widths in plotter units, irrespective - * of current units (WU). - */ - if (hpgl_arg_c_real(pargs, ¶m)) { - if (hpgl_arg_c_int(pargs, &pmin)) { - if ((pmin < 0) || (pmin > pmax)) - return e_Range; - pmax = pmin; - } - } - - /* width is maintained in plu only */ - width_plu = ( (pgls->g.pen.width_relative) - ? ( (param / 100.0) * hpgl_compute_distance( pgls->g.P1.x, - pgls->g.P1.y, - pgls->g.P2.x, - pgls->g.P2.y - ) ) - : mm_2_plu(param) ); - - /* - * PCLTRM 22-38 metric widths scaled scaled by the ratio of - * the picture frame to plot size. Note that we always store - * the line width in PU not MM. - */ - if (pgls->g.pen.width_relative) - width_plu *= min( (hpgl_real_t)pgls->g.picture_frame_height - / (hpgl_real_t)pgls->g.plot_height, - (hpgl_real_t)pgls->g.picture_frame_width - / (hpgl_real_t)pgls->g.plot_width - ); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - { - int i; - - for (i = pmin; i <= pmax; ++i) - pcl_palette_PW(pgls, i, width_plu); - } - return 0; -} - -/* - * RF [index[,width,height,pen...]]; - * - * Nominally, patterns generated via RF are colored patterns. For backwards - * compatibility with PCL 5e, however, they may also be uncolored patterns. The - * determining factor is whether or not all of the entries in the pattern are - * 0 or 1: if so, the pattern is an uncolored pattern; otherwise it is a colored - * pattern. - */ - int -hpgl_RF( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - uint index, width, height; - gs_depth_bitmap pixmap; - int code = 0; - bool is_mask = true; - byte * data; - - if (pargs->phase == 0) { - - if (!hpgl_arg_c_int(pargs, (int *)&index)) { - hpgl_default_all_fill_patterns(pgls); - return 0; - } - if ((index < 1) || (index > 8)) - return e_Range; - - if (!hpgl_arg_c_int(pargs, (int *)&width)) { - pcl_pattern_RF(index, NULL, pgls); - return 0; - } - if ( (width < 1) || - (width > 255) || - !hpgl_arg_c_int(pargs, (int *)&height) || - (height < 1) || - (height > 255) ) - return e_Range; - - /* allocate enough memory for pattern header and data */ - data = gs_alloc_bytes(pgls->memory, width * height, "hpgl raster fill"); - if (data == 0) - return e_Memory; - - /* - * All variables must be saved in globals since the parser - * the parser reinvokes hpgl_RF() while processing data - * (hpgl_arg_c_int can execute a longjmp). - */ - pgls->g.raster_fill.width = width; - pgls->g.raster_fill.height = height; - pgls->g.raster_fill.data = data; - pgls->g.raster_fill.is_mask = is_mask; - pgls->g.raster_fill.index = index; - /* set bitmap to 0, as not all pens need be provided */ - memset(data, 0, width * height); - pargs->phase = 1; - - } else { - width = pgls->g.raster_fill.width; - height = pgls->g.raster_fill.height; - data = pgls->g.raster_fill.data; - is_mask = pgls->g.raster_fill.is_mask; - index = pgls->g.raster_fill.index; - } - - while ((pargs->phase - 1) < width * height) { - int pixel; - - if (!hpgl_arg_c_int(pargs, &pixel)) - break; - if (pixel != 0) { - data[pargs->phase - 1] = pixel; - if (pixel != 1) - is_mask = false; - } - hpgl_next_phase(pargs); - } - -#ifdef PCL5EMONO - is_mask = true; /* always for a monochrome configuration */ -#endif - /* if the pattern is uncolored, collapse it to 1-bit per pixel */ - if (is_mask) { - int raster = (width + 7) / 8; - byte * mdata = gs_alloc_bytes( pgls->memory, - height * raster, - "hpgl mask raster fill" - ); - byte * pb1 = data; - byte * pb2 = mdata; - int i; - - if (mdata == 0) { - gs_free_object(pgls->memory, data, "hpgl raster fill"); - return e_Memory; - } - - for (i = 0; i < height; i++) { - int mask = 0x80; - int outval = 0; - int j; - - for (j = 0; j < width; j++) { - if (*pb1++ != 0) - outval |= mask; - if ((mask >>= 1) == 0) { - *pb2++ = outval; - outval = 0; - mask = 0x80; - } - } - - if (mask != 0x80) - *pb2++ = outval; - } - - gs_free_object(pgls->memory, data, "hpgl raster fill"); - pixmap.data = mdata; - pixmap.raster = raster; - pixmap.pix_depth = 1; - - } else { - pixmap.data = data; - pixmap.raster = width; - pixmap.pix_depth = 8; - } - - /* set up the pixmap */ - pixmap.size.x = width; - pixmap.size.y = height; - pixmap.id = 0; - pixmap.num_comps = 1; - - if ((code = pcl_pattern_RF(index, &pixmap, pgls)) < 0) - gs_free_object(pgls->memory, data, "hpgl raster fill"); - pgls->g.raster_fill.data = 0; - return code;; -} - -/* - * SM [char]; - */ - int -hpgl_SM( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - const byte * p = pargs->source.ptr; - const byte * rlimit = pargs->source.limit; - - for (;;) { - if (p >= rlimit) { - pargs->source.ptr = p; - return e_NeedData; - } - ++p; - if (*p == ' ') - continue; /* ignore initial spaces */ - else if (*p == ';') { - pgls->g.symbol_mode = 0; - break; - } - - /* - * p. 22-44 of the PCL5 manual says that the allowable codes - * are 33-58, 60-126, 161 and 254. This is surely an error: - * it must be 161-254. - */ - else if ( ((*p >= 33) && (*p <= 126)) || ((*p >= 161) && (*p <= 254)) ) { - pgls->g.symbol_mode = *p; - return 0; - } else - return e_Range; - } - return 0; -} - -/* - * SP [pen]; - */ - int -hpgl_SP( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int pen = 0; - /* palette pen numbers are always consecutive integers starting - with 0 */ - int max_pen = pcl_palette_get_num_entries(pgls->ppalet) - 1; - - if (hpgl_arg_c_int(pargs, &pen)) { - if (pen < 0) - return e_Range; - while ( pen > max_pen ) - pen = pen - max_pen; - } - if ( !pgls->g.polygon_mode ) - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.pen.selected = pen; - return 0; -} - -/* - * SV [type[,option1[,option2]]; - */ -/* - * HAS - this should be redone with a local copy of the screen - * parameters and need to check if we draw the current path if the - * command is called with arguments that set the state to the current - * state - */ - int -hpgl_SV( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int type = hpgl_SV_pattern_solid_pen; - - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - if (hpgl_arg_c_int(pargs, &type)) { - - switch (type) { - - case hpgl_SV_pattern_solid_pen: /* 0 */ - pgls->g.screen.param.shading = 100; - pgls->g.screen.param.user_defined.pattern_index = 1; - pgls->g.screen.param.user_defined.use_current_pen = false; - pgls->g.screen.param.pattern_type = 1; - pgls->g.screen.param.pattern_id = 0; - break; - - case hpgl_SV_pattern_shade: /* 1 */ - { - int level; - - if ( !hpgl_arg_c_int(pargs, &level) || - (level < 0) || - (level > 100) ) - return e_Range; - pgls->g.screen.param.shading = level; - } - break; - - case hpgl_SV_pattern_RF: /* 2 */ - { - int index, mode; - - if (!hpgl_arg_int(pargs, &index)) - index = pgls->g.screen.param.user_defined.pattern_index; - else if ((index < 1) || (index > 8)) - return e_Range; - if (!hpgl_arg_c_int(pargs, &mode)) - mode = pgls->g.screen.param.user_defined.use_current_pen; - else if ((mode & ~1) != 0) - return e_Range; - pgls->g.screen.param.user_defined.pattern_index = index; - pgls->g.screen.param.user_defined.use_current_pen = mode; - } - break; - - case hpgl_SV_pattern_cross_hatch: /* 21 */ - { - int pattern; - - if ( !hpgl_arg_c_int(pargs, &pattern) || - (pattern < 1) || - (pattern > 6) ) - return e_Range; - pgls->g.screen.param.pattern_type = pattern; - } - break; - - case hpgl_SV_pattern_user_defined: /* 22 */ - { - int32 id; - - if (!hpgl_arg_int(pargs, &id) || (id < 0) || (id > 0xffff)) - return e_Range; - pgls->g.screen.param.pattern_id = id; - } - break; - - default: - return e_Range; - } - } - - pgls->g.screen.type = (hpgl_SV_pattern_source_t)type; - return 0; -} - -/* - * TR [mode]; - * - * NB: Though termed "source transparency" in HP's documentation, GL/2 - * transparency concept actually corresponds to pattern transparency in - * the PCL sense. GL/2 objects are all logically masks: they have no - * background, and thus are unaffected by source transparency. - * - * The GL/2 source and PCL pattern transparency states are, however, - * maintained separately. The former affects only GL/2 objects, the - * latter only objects generated in PCL. - */ - int -hpgl_TR( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int mode = 1; - - if (hpgl_arg_c_int(pargs, &mode) && ((mode & ~1) != 0)) - return e_Range; - - pgls->g.source_transparent = (mode != 0); - return 0; -} - -/* - * UL [index[,gap1..20]; - */ - int -hpgl_UL( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int index; - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - if (hpgl_arg_c_int(pargs, &index)) { - hpgl_real_t gap[20]; - double total = 0; - int i, k; - - if ((index < -8) || (index > 8) || (index == 0)) - return e_Range; - for (i = 0; (i < 20) && hpgl_arg_c_real(pargs, &gap[i]); ++i ) { - if (gap[i] < 0) - return e_Range; - total += gap[i]; - } - if (total == 0) - return e_Range; - - for (k = 0; k < i; k++) - gap[k] /= total; - - { - hpgl_line_type_t * fixed_plt = - &pgls->g.fixed_line_type[(index < 0 ? -index : index) - 1]; - hpgl_line_type_t * adaptive_plt = - &pgls->g.adaptive_line_type[(index < 0 ? -index : index) - 1]; - - fixed_plt->count = adaptive_plt->count = i; - memcpy(fixed_plt->gap, gap, i * sizeof(hpgl_real_t)); - memcpy(adaptive_plt->gap, gap, i * sizeof(hpgl_real_t)); - } - - } else { - hpgl_set_line_pattern_defaults(pgls); - } - return 0; -} - -/* - * WU [mode]; - */ - int -hpgl_WU( - hpgl_args_t * pargs, - hpgl_state_t * pgls -) -{ - int mode = 0; - - if (hpgl_arg_c_int(pargs, &mode)) { - if ((mode != 0) && (mode != 1)) - return e_Range; - } - pgls->g.pen.width_relative = mode; - hpgl_args_setup(pargs); - hpgl_PW(pargs, pgls); - return 0; -} - -/* - * Initialization - */ - private int -pglfill_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * mem -) -{ - /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('A', 'C', hpgl_AC, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('F', 'T', hpgl_FT, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('L', 'A', hpgl_LA, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('L', 'T', hpgl_LT, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('M', 'C', hpgl_MC, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'W', hpgl_PW, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'P', hpgl_PP, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('R', 'F', hpgl_RF, hpgl_cdf_pcl_rtl_both), /* + additional I parameters */ - - /* - * SM has special argument parsing, so it must handle skipping - * in polygon mode itself.` - */ - HPGL_COMMAND('S', 'M', hpgl_SM, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('S', 'P', hpgl_SP, hpgl_cdf_pcl_rtl_both|hpgl_cdf_polygon), - HPGL_COMMAND('S', 'V', hpgl_SV, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('T', 'R', hpgl_TR, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('U', 'L', hpgl_UL, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('W', 'U', hpgl_WU, hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -} - -const pcl_init_t pglfill_init = { pglfill_do_registration, 0, 0 }; diff --git a/pcl/pgmand.h b/pcl/pgmand.h deleted file mode 100644 index 0477e4b29..000000000 --- a/pcl/pgmand.h +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgmand.h - Definitions for HP-GL/2 commands and parser */ - -#ifndef pgmand_INCLUDED -#define pgmand_INCLUDED - -#include "stdio_.h" /* for gdebug.h */ -#include <setjmp.h> /* must come after std.h */ -#include "gdebug.h" -#include "pcommand.h" -#include "pcstate.h" -/* Define the type for the HP-GL state. */ -typedef struct pcl_state_s hpgl_state_t; - -/* Define the type for HP-GL/2 command arguments. */ -#ifndef hpgl_parser_state_DEFINED -# define hpgl_parser_state_DEFINED -typedef struct hpgl_args_s hpgl_parser_state_t; -#endif - -typedef struct hpgl_args_s hpgl_args_t; - -/* Define a command processing procedure. */ -#define hpgl_command_proc(proc)\ - int proc(P2(hpgl_args_t *, hpgl_state_t *)) -typedef hpgl_command_proc((*hpgl_command_proc_t)); - -/* - * Because HP-GL/2 commands have irregular syntax, we have to let them parse - * their arguments themselves. But parsing can be interrupted at any point - * by reaching an input buffer boundary, so we can't just let the commands - * call procedures that get the next argument of a given type out of the - * input stream. At the same time, we would like to hide buffer boundaries - * from the individual command implementations to the greatest extent - * possible. - * - * For simple commands that take a maximum number of numeric arguments, we - * do indeed let the commands call get-argument procedures. In addition to - * parsing the input, these procedures save the scanned arguments in an - * array. If one of these procedures runs out of input data, it does a - * longjmp back to the main parser, which exits to its client to request - * more input. When the parser regains control, it simply restarts the - * command procedure from the beginning. This time, the get-argument - * procedures return the saved values from the array before continuing to - * scan the (new) input. In this way, buffer boundaries cause some extra - * work, but the command implementations don't notice them. The only - * requirement is that a command must not change the permanent state until - * it has read all of its arguments. - * - * For commands that take other kinds of arguments, or a variable - * (potentially large) number of numeric arguments, the situation is more - * complicated. The command is still expected to detect running out of - * input data, and is still restarted, but it must keep track of its - * progress itself. We provide a variable called 'phase' for this - * purpose: it is set to 0 just after the parser recognizes a command, - * and is free for the command to use thereafter. - */ -typedef struct hpgl_command_s { - hpgl_command_proc_t proc; - byte flags; -#define hpgl_cdf_polygon 1 /* execute command even in polygon mode */ -#define hpgl_cdf_lost_mode_cleared 2 /* exectute command only if lost mode cleared */ -#define hpgl_cdf_rtl 4 /* execute only in rtl mode */ -#define hpgl_cdf_pcl 8 /* execute only in pcl mode */ -#define hpgl_cdf_pcl_rtl_both (hpgl_cdf_rtl|hpgl_cdf_pcl) -} hpgl_command_definition_t; - -/* Define a HP-GL/2 command argument value. */ -typedef struct hpgl_value_s { - union v_ { - int32 i; - hpgl_real_t r; - } v; - bool is_real; -} hpgl_value_t; - -/* Define the structure passed to HP-GL/2 commands. */ -struct hpgl_args_s { - /* Parsing state */ - stream_cursor_read source; - int first_letter; /* -1 if we haven't seen the first letter of */ - /* a command, the letter (0-25) if we have */ - bool done; /* true if we've seen an argument */ - /* terminator */ - hpgl_command_definition_t *command; /* command being executed, */ - /* 0 if none */ - jmp_buf exit_to_parser; /* longjmp here if we ran out of data */ - /* while scanning an argument, or we */ - /* found a syntax error */ - struct arg_ { /* argument scanning state */ - /* State within the current argument */ - int have_value; /* 0 = no value, 1 = int, 2 = real */ - double frac_scale; /* 10 ^ # of digits after dot */ - int sign; /* 0 = none, +/-1 = sign */ - /* State of argument list collection */ - int count; /* # of fully scanned arguments */ - int next; /* # of next scanned arg to return */ - hpgl_value_t scanned[21]; /* args already scanned */ - } arg; - /* Command execution state */ - int phase; /* phase within command, see above */ - - /* - * We register all the HP-GL/2 commands dynamically, for maximum - * configuration flexibility. hpgl_command_list points to the individual - * command definitions; as each command is registered, we enter it in the - * list, and then store its index in the actual dispatch table - * (hpgl_command_indices). - */ - hpgl_command_definition_t *hpgl_command_list[100]; - int hpgl_command_next_index; - /* Dispatch tables */ - byte hpgl_command_indices[26][26]; -}; - -/* Register HP-GL/2 commands. */ -typedef struct { - char char1, char2; - hpgl_command_definition_t defn; -} hpgl_named_command_t; -int hpgl_init_command_index(P2(hpgl_parser_state_t **pgl_parser_state, gs_memory_t *mem)); -void hpgl_define_commands(P2(const hpgl_named_command_t *, hpgl_parser_state_t *pgl_parser_state)); -#define DEFINE_HPGL_COMMANDS \ -{ static const hpgl_named_command_t defs_[] = { -#define HPGL_COMMAND(c1, c2, proc, flag)\ - {c1, c2, {proc, flag}} -#define END_HPGL_COMMANDS\ - {0, 0}\ - };\ - hpgl_define_commands(defs_, pcl_parser_state->hpgl_parser_state);\ -} - -/* Define a return code asking for more data. */ -#define e_NeedData (-200) - -/* Initialize the HP-GL/2 parser. */ -void hpgl_process_init(P1(hpgl_parser_state_t *)); - -/* Process a buffer of HP-GL/2 commands. */ -/* Return 0 if more input needed, 1 if ESC seen, or an error code. */ -int hpgl_process(P3(hpgl_parser_state_t *pst, hpgl_state_t *pgls, - stream_cursor_read *pr)); - -/* Prepare to scan the next (numeric) argument. */ -#define hpgl_arg_init(pargs)\ - ((pargs)->arg.have_value = 0, (pargs)->arg.sign = 0) - -/* Prepare to scan a sequence of numeric arguments. Execute this */ -/* once per sequence, when incrementing the phase. */ -#define hpgl_args_init(pargs)\ - (hpgl_arg_init(pargs), (pargs)->arg.count = 0) -/* Move to the next phase of a command. */ -#define hpgl_next_phase(pargs)\ - ((pargs)->phase++, hpgl_args_init(pargs)) - -/* - * Scan a numeric argument, returning true if there was one, or false - * if we have reached the end of the arguments. Note that these - * procedures longjmp back to the parser if they run out of input data. - */ -bool hpgl_arg_real(P2(hpgl_args_t *pargs, hpgl_real_t *pr)); -bool hpgl_arg_c_real(P2(hpgl_args_t *pargs, hpgl_real_t *pr)); -bool hpgl_arg_int(P2(hpgl_args_t *pargs, int32 *pi)); -bool hpgl_arg_c_int(P2(hpgl_args_t *pargs, int *pi)); -/* - * Many vector commands are defined as taking parameters whose format is - * "current units". This is nonsensical: whether scaling is on or off - * has no bearing on whether coordinates are represented as integers or - * reals. Nevertheless, in deference to this definition (and just in case - * it turns out it actually matters), we define a separate procedure for - * this. - */ -bool hpgl_arg_units(P2(hpgl_args_t *pargs, hpgl_real_t *pu)); - -/* In some cases, it is convenient for the implementation of command A to - * call another command B. While we don't particularly like this approach - * in general, we do support it, as long as command B doesn't do its own - * argument parsing (e.g., PE, LB). The framework for doing this is the - * following: - * hpgl_args_t args; - * ... - * hpgl_args_setup(&args); - * << As many times as desired: >> - * hpgl_args_add_int/real(&args, value); - * hpgl_B(&args, pgls); - */ -#define args_setup_count_(pargs, numargs)\ - ((void)((pargs)->done = true, (pargs)->arg.count = (numargs),\ - (pargs)->arg.next = (pargs)->phase = 0)) -#define hpgl_args_setup(pargs)\ - args_setup_count_(pargs, 0) -#define args_put_int_(pargs, index, iplus, ival)\ - ((void)((pargs)->arg.scanned[index].v.i = (ival),\ - (pargs)->arg.scanned[iplus].is_real = false)) -#define hpgl_args_add_int(pargs, ival)\ - args_put_int_(pargs, (pargs)->arg.count, (pargs)->arg.count++, ival) -#define args_put_real_(pargs, index, iplus, rval)\ - ((void)((pargs)->arg.scanned[index].v.r = (rval),\ - (pargs)->arg.scanned[iplus].is_real = true)) -#define hpgl_args_add_real(pargs, rval)\ - args_put_real_(pargs, (pargs)->arg.count, (pargs)->arg.count++, rval) -/* - * We provide shortcuts for commands that take just 1 or 2 arguments. - */ -#define hpgl_args_set_int(pargs, ival)\ - (args_setup_count_(pargs, 1), args_put_int_(pargs, 0, 0, ival)) -#define hpgl_args_set_real(pargs, rval)\ - (args_setup_count_(pargs, 1), args_put_real_(pargs, 0, 0, rval)) -#define hpgl_args_set_real2(pargs, rval1, rval2)\ - (args_setup_count_(pargs, 2), args_put_real_(pargs, 0, 0, rval1),\ - args_put_real_(pargs, 1, 1, rval2)) - -/* - * HPGL mnemonics - */ - -/* commands from pgchar.c -- HP-GL/2 character commands */ -int hpgl_AD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_CF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_CP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_DI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_DR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_DT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_DV(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_ES(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_FI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_FN(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_LB(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_LM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_LO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SB(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SL(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SS(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_TD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pgcolor.c - HP-GL/2 color vector graphics commands */ -int hpgl_MC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_NP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pgconfig.c - HP-GL/2 configuration and status commands */ -int hpgl_CO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_DF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -int hpgl_IN(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_IN_implicit(P1(hpgl_state_t *pgls)); - -int hpgl_IP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_IR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_IW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PG(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pglfill.c - HP-GL/2 line and fill attributes commands */ -int hpgl_AC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_FT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_LA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_LT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_SV(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_TR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_UL(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_WU(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pgpoly.c -- HP-GL/2 polygon commands */ -int hpgl_EA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_EP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_ER(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_EW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_FP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_WG(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pgvector.c - HP-GL/2 vector commands */ -int hpgl_AA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_AR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_AT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_BR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_BZ(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_CI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PE(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_PU(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); -int hpgl_RT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); - -/* commands from pgframe.c -- PCL5/HP-GL/2 picture frame commands */ -int pcl_horiz_pic_frame_size_decipoints(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); -int pcl_vert_pic_frame_size_decipoints(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); -int pcl_set_pic_frame_anchor_point(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); -int pcl_hpgl_plot_horiz_size(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); -int pcl_hpgl_plot_vert_size(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); - -/* reset required for overlay macros - a partial DF command */ -void hpgl_reset_overlay(P1(hpgl_state_t *pgls)); - -/* this should find a new home but for now we list it here. */ -int hpgl_print_symbol_mode_char(P1(hpgl_state_t *pgls)); - -/* reset LT parameters */ -void hpgl_set_line_pattern_defaults(P1(hpgl_state_t *pgls)); - -#endif /* pgmand_INCLUDED */ diff --git a/pcl/pgmisc.c b/pcl/pgmisc.c deleted file mode 100644 index ba741fde8..000000000 --- a/pcl/pgmisc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgmisc.c */ -/* HP-GL/2 miscellaneous support */ - -#include "pgmand.h" -#include "pgmisc.h" - -void -hpgl_set_lost_mode(hpgl_state_t *pgls, hpgl_lost_mode_t lost_mode) -{ - if ( lost_mode == hpgl_lost_mode_entered ) - { -#ifdef INFINITE_LOOP - hpgl_args_t args; - /* raise the pen. Note this should handle the pcl oddity - that when lost mode is cleared with an absolute PD we - draw a line from the last valid position to the first - args of pen down. The following appends a moveto the - current point in the gs path */ - hpgl_args_setup(&args); - hpgl_PU(&args, pgls); -#endif -#ifdef DEBUG - dprintf("entering lost mode\n"); -#endif - } - pgls->g.lost_mode = lost_mode; - -} - -#ifdef DEBUG - -/* Print an error message. Note that function may be NULL. */ -/* This procedure must return its 'code' argument: see pgmisc.h. */ -int -hpgl_print_error(const char *function, const char *file, int line, int code) -{ - dprintf4("hpgl call failed\n\tcalled from: %s\n\tfile: %s\n\tline: %d\n\terror code: %d\n", - (function == 0 ? "" : function), file, line, code); - hpgl_error(); - return code; -} - -/* called when there is a graphics error. Keep a breakpoint on this function */ -void -hpgl_error() -{ - return; -} -#endif diff --git a/pcl/pgmisc.h b/pcl/pgmisc.h deleted file mode 100644 index 608a8d640..000000000 --- a/pcl/pgmisc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgmisc.h */ -/* definitions for HP-GL/2 lost mode and error handling routines. */ - -#ifndef pgmisc_INCLUDED -# define pgmisc_INCLUDED - -void hpgl_set_lost_mode(P2(hpgl_state_t *pgls, hpgl_lost_mode_t lost_mode)); -/* get the current setting of the edge pen set by CF, NB this should - be in a different header file */ -int32 hpgl_get_character_edge_pen(P1(hpgl_state_t *pgls)); - -/* macro to see if we are in lost mode */ -#define hpgl_lost (pgls->g.lost_mode == hpgl_lost_mode_entered) - -/* a macro that calls a function and returns an error code if the code - returned is less than 0. Most of the hpgl and gs functions return - if the calling function is less than 0 so this avoids cluttering up - the code with the if statement and debug code. */ - -#ifdef DEBUG - -void hpgl_error(P0()); -int hpgl_print_error(P4(const char *function, const char *file, int line, int code)); - -# ifdef __GNUC__ -# define hpgl_call_note_error(code)\ - hpgl_print_error(__FUNCTION__, __FILE__, __LINE__, code) -# else -# define hpgl_call_note_error(code)\ - hpgl_print_error((const char *)0, __FILE__, __LINE__, code) -# endif - -#else /* !DEBUG */ - -#define hpgl_call_note_error(code) (code) - -#endif - -/* We use the do ... while(0) in order to make the call be a statement */ -/* syntactically. */ - -#define hpgl_call_and_check(call, if_check_else)\ -do { \ - int code; \ - if ((code = (call)) < 0) \ - { if_check_else() \ - return hpgl_call_note_error(code); \ - } \ -} while (0) - -/* Ordinary function calls */ - -#define hpgl_no_check() /* */ - -#define hpgl_call(call)\ - hpgl_call_and_check(call, hpgl_no_check) - -/* Function calls that can set LOST mode */ - -#define hpgl_limitcheck_set_lost()\ - if ( code == gs_error_limitcheck )\ - hpgl_set_lost_mode(pgls, hpgl_lost_mode_entered);\ - else - -#define hpgl_call_check_lost(call)\ - hpgl_call_and_check(call, hpgl_limitcheck_set_lost) - -#endif /* pgmisc_INCLUDED */ diff --git a/pcl/pgparse.c b/pcl/pgparse.c deleted file mode 100644 index a40c1e019..000000000 --- a/pcl/pgparse.c +++ /dev/null @@ -1,384 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgparse.c */ -/* HP-GL/2 parser */ -#include "math_.h" -#include "stdio_.h" -#include "gdebug.h" -#include "gstypes.h" -#include "scommon.h" -#include "pgmand.h" - -/* ---------------- Command definition ---------------- */ - -/* Register a command. Return true if this is a redefinition. */ -private bool -hpgl_register_command(hpgl_parser_state_t *pgl_parser_state, - byte *pindex, - const hpgl_command_definition_t *pcmd) -{ - int index = pgl_parser_state->hpgl_command_next_index; - byte prev = *pindex; - - if ( prev != 0 && prev <= index && - pgl_parser_state->hpgl_command_list[prev] == pcmd ) - index = prev; - else if ( index != 0 && pgl_parser_state->hpgl_command_list[index] == pcmd ) - ; - else - pgl_parser_state->hpgl_command_list[pgl_parser_state->hpgl_command_next_index = ++index] = pcmd; - *pindex = index; - return (prev != 0 && prev != index); -} - -/* Define a list of commands. */ -void -hpgl_define_commands(const hpgl_named_command_t *pcmds, - hpgl_parser_state_t *pgl_parser_state -) -{ const hpgl_named_command_t *pcmd = pcmds; - - for ( ; pcmd->char1; ++pcmd ) -#ifdef DEBUG - if ( -#endif - hpgl_register_command(pgl_parser_state, - &pgl_parser_state->hpgl_command_indices - [pcmd->char1 - 'A'][pcmd->char2 - 'A'], - &pcmd->defn) -#ifdef DEBUG - ) - dprintf2("Redefining command %c%c\n", pcmd->char1, pcmd->char2); -#endif - ; -} - -/* ---------------- Parsing ---------------- */ - -/* Initialize the HP-GL/2 parser state. */ -void -hpgl_process_init(hpgl_parser_state_t *pst) -{ pst->first_letter = -1; - pst->command = 0; -} - -/* Process a buffer of HP-GL/2 commands. */ -/* Return 0 if more input needed, 1 if ESC seen, or an error code. */ -int -hpgl_process(hpgl_parser_state_t *pst, hpgl_state_t *pgls, - stream_cursor_read *pr) -{ const byte *p = pr->ptr; - const byte *rlimit = pr->limit; - int code = 0; - - pst->source.limit = rlimit; - /* Prepare to catch a longjmp indicating the argument scanner */ - /* needs more data, or encountered an error. */ - code = setjmp(pst->exit_to_parser); - if ( code ) - { /* The command detected an error, or we need to ask */ - /* the caller for more data. pst->command != 0. */ - pr->ptr = pst->source.ptr; - if ( code < 0 && code != e_NeedData ) - { pst->command = 0; /* cancel command */ - if_debug0('i', "\n"); - return code; - } - return 0; - } - /* Check whether we're still feeding data to a command. */ -call: if ( pst->command ) - { pst->source.ptr = p; - pst->arg.next = 0; - code = (*pst->command->proc)(pst, pgls); - p = pst->source.ptr; - if ( code < 0 ) - goto x; - pst->command = 0; - if_debug0('i', "\n"); - } - while ( p < rlimit ) - { byte next = *++p; - - if ( next >= 'A' && next <= 'Z' ) - next -= 'A'; - else if ( next >= 'a' && next <= 'z' ) - next -= 'a'; - else if ( next == ESC ) - { --p; - pst->first_letter = -1; - code = 1; - break; - } - else /* ignore everything else */ - { /* Apparently this is what H-P plotters do.... */ - if ( next > ' ' && next != ',' ) - pst->first_letter = -1; - continue; - } - if ( pst->first_letter < 0 ) - { pst->first_letter = next; - continue; - } - { int index = pst->hpgl_command_indices[pst->first_letter][next]; - -#ifdef DEBUG - if ( gs_debug_c('i') ) - { char c = (index ? '-' : '?'); - dprintf4("--%c%c%c%c", pst->first_letter + 'A', - next + 'A', c, c); - } -#endif - if ( index == 0 ) /* anomalous, drop 1st letter */ - { pst->first_letter = next; - continue; - } - pst->first_letter = -1; - pst->command = pst->hpgl_command_list[index]; - pst->phase = 0; - pst->done = false; - hpgl_args_init(pst); - /* - * Only a few commands should be executed while we're in - * polygon mode: check for this here. Note that we rely - * on the garbage-skipping property of the parser to skip - * over any following arguments. This doesn't work for - * the few commands with special syntax that should be - * ignored in polygon mode (CO, DT, LB, SM); they must be - * flagged as executable even in polygon mode, and check - * the render_mode themselves. - */ - { - bool ignore_command = false; - if (( pgls->g.polygon_mode ) && - !(pst->command->flags & hpgl_cdf_polygon) - ) - ignore_command = true; - else - { /* similarly if we are in lost mode we do not - execute the commands that are only defined to - be used when lost mode is cleared. */ - if (( pgls->g.lost_mode == hpgl_lost_mode_entered ) && - (pst->command->flags & hpgl_cdf_lost_mode_cleared) - ) - ignore_command = true; - } - /* Also, check that we have a command that can be executed - with the current personality. NB reorganize me. */ - if ( pgls->personality == rtl ) - if ( !(pst->command->flags & hpgl_cdf_rtl) ) /* not rtl pcl only */ - ignore_command = true; - if ( (pgls->personality == pcl5c) || (pgls->personality == pcl5e) ) - if ( !(pst->command->flags & hpgl_cdf_pcl) ) /* not pcl rtl only */ - ignore_command = true; - if ( ignore_command ) - pst->command = 0; - } - goto call; - } - } -x: pr->ptr = p; - return (code == e_NeedData ? 0 : code); -} - -/* - * Get a numeric HP-GL/2 argument from the input stream. Return 0 if no - * argument, a pointer to the value if an argument is present, or longjmp if - * need more data. Note that no errors are possible. - */ -private const hpgl_value_t * -hpgl_arg(hpgl_parser_state_t *pst) -{ const byte *p = pst->source.ptr; - const byte *rlimit = pst->source.limit; - hpgl_value_t *pvalue; - -#define parg (&pst->arg) - if ( parg->next < parg->count ) - { /* We're still replaying already-scanned arguments. */ - return &parg->scanned[parg->next++]; - } - if ( pst->done ) - return 0; - pvalue = &parg->scanned[parg->count]; -#define check_value()\ - if ( parg->have_value ) goto done - - for ( ; p < rlimit; ++p ) - { byte ch = p[1]; - switch ( ch ) - { - case '+': - check_value(); - parg->have_value = 1; - parg->sign = 1; - pvalue->v.i = 0; - break; - case '-': - check_value(); - parg->have_value = 1; - parg->sign = -1; - pvalue->v.i = 0; - break; - case '.': - switch ( parg->have_value ) - { - default: /* > 1 */ - goto out; - case 0: - pvalue->v.r = 0; - break; - case 1: - pvalue->v.r = pvalue->v.i; - } - parg->have_value = 2; - parg->frac_scale = 1.0; - break; - case HT: case LF: case FF: case CR: case ';': - ++p; - pst->done = true; - check_value(); - goto out; - case SP: case ',': - /* - * The specification doesn't say what to do with extra - * separators; we just ignore them. - */ - if ( !parg->have_value ) - break; - ++p; -done: if ( parg->sign < 0 ) - { if ( parg->have_value > 1 ) - pvalue->v.r = -pvalue->v.r; - else - pvalue->v.i = -pvalue->v.i; - } - goto out; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - ch -= '0'; -#define max_i 0x3fffffff - switch ( parg->have_value ) - { - default: /* case 2 */ - pvalue->v.r += ch / (parg->frac_scale *= 10); - break; - case 0: - parg->have_value = 1; - pvalue->v.i = ch; - break; - case 1: - if ( pvalue->v.i >= max_i/10 && - (pvalue->v.i > max_i/10 || ch > max_i%10) - ) - pvalue->v.i = max_i; - else - pvalue->v.i = pvalue->v.i * 10 + ch; - } - break; - default: - pst->done = true; - check_value(); - goto out; - } - } - /* We ran out of data before reaching a terminator. */ - pst->source.ptr = p; - longjmp(pst->exit_to_parser, e_NeedData); - /* NOTREACHED */ -out: pst->source.ptr = p; - switch ( parg->have_value ) - { - case 0: /* no argument */ - return false; - case 1: /* integer */ - if_debug1('I', " %ld", (long)pvalue->v.i); - pvalue->is_real = false; - break; - default /* case 2 */: /* real */ - if_debug1('I', " %g", pvalue->v.r); - pvalue->is_real = true; - } - hpgl_arg_init(pst); - parg->next = ++(parg->count); - return pvalue; -#undef parg -} - -/* Get a real argument. */ -bool -hpgl_arg_real(hpgl_args_t *pargs, hpgl_real_t *pr) -{ const hpgl_value_t *pvalue = hpgl_arg(pargs); - - if ( !pvalue ) - return false; - *pr = (pvalue->is_real ? pvalue->v.r : pvalue->v.i); - return true; -} - -/* Get a clamped real argument. */ -bool -hpgl_arg_c_real(hpgl_args_t *pargs, hpgl_real_t *pr) -{ const hpgl_value_t *pvalue = hpgl_arg(pargs); - hpgl_real_t r; - - if ( !pvalue ) - return false; - r = (pvalue->is_real ? pvalue->v.r : pvalue->v.i); - *pr = (r < -32768 ? -32768 : r > 32767 ? 32767 : r); - return true; - -} - -/* Get an integer argument. */ -bool -hpgl_arg_int(hpgl_args_t *pargs, int32 *pi) -{ const hpgl_value_t *pvalue = hpgl_arg(pargs); - - if ( !pvalue ) - return false; - *pi = (pvalue->is_real ? (int32)pvalue->v.r : pvalue->v.i); - return true; -} - -/* Get a clamped integer argument. */ -bool -hpgl_arg_c_int(hpgl_args_t *pargs, int *pi) -{ const hpgl_value_t *pvalue = hpgl_arg(pargs); - int32 i; - - if ( !pvalue ) - return false; - i = (pvalue->is_real ? (int32)pvalue->v.r : pvalue->v.i); - *pi = (i < -32768 ? -32768 : i > 32767 ? 32767 : i); - return true; -} - -/* Get a "current units" argument. */ -bool -hpgl_arg_units(hpgl_args_t *pargs, hpgl_real_t *pu) -{ /****** PROBABLY WRONG ******/ - return hpgl_arg_real(pargs, pu); -} - -/* initialize the HPGL command counter */ - int -hpgl_init_command_index(hpgl_parser_state_t **pgl_parser_state, gs_memory_t *mem) -{ - hpgl_parser_state_t *pgst = - (hpgl_parser_state_t *)gs_alloc_bytes(mem, sizeof(hpgl_parser_state_t), - "hpgl_init_command_index"); - /* fatal */ - if ( pgst == 0 ) - return -1; - - pgst->hpgl_command_next_index = 0; - /* NB fix me the parser should not depend on this behavior the - previous design had these in bss which was automatically - cleared to zero. */ - memset(pgst->hpgl_command_indices, 0, sizeof(pgst->hpgl_command_indices)); - hpgl_process_init(pgst); - *pgl_parser_state = pgst; - return 0; -} diff --git a/pcl/pgpoly.c b/pcl/pgpoly.c deleted file mode 100644 index f00ca9f6c..000000000 --- a/pcl/pgpoly.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgpoly.c - HP-GL/2 polygon commands */ - -#include "std.h" -#include "pcparse.h" -#include "pgmand.h" -#include "pgdraw.h" -#include "pggeom.h" -#include "pgmisc.h" -#include "pcpatrn.h" - -/* ------ Internal procedures ------ */ - -/* Define fill/edge and absolute/relative flags. */ -#define DO_EDGE 1 -#define DO_RELATIVE 2 - -/* Build a rectangle in polygon mode used by (EA, ER, RA, RR). */ -private int -hpgl_rectangle(hpgl_args_t *pargs, hpgl_state_t *pgls, int flags) -{ hpgl_real_t x2, y2; - if ( !hpgl_arg_units(pargs, &x2) || !hpgl_arg_units(pargs, &y2) ) - return e_Range; - - if ( flags & DO_RELATIVE ) - { - x2 += pgls->g.pos.x; - y2 += pgls->g.pos.y; - } - - hpgl_args_setup(pargs); - /* enter polygon mode. */ - hpgl_call(hpgl_PM(pargs, pgls)); - - /* do the rectangle */ - { - hpgl_real_t x1 = pgls->g.pos.x; - hpgl_real_t y1 = pgls->g.pos.y; - - hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_move_absolute, true)); - hpgl_call(hpgl_add_point_to_path(pgls, x2, y1, hpgl_plot_draw_absolute, true)); - hpgl_call(hpgl_add_point_to_path(pgls, x2, y2, hpgl_plot_draw_absolute, true)); - hpgl_call(hpgl_add_point_to_path(pgls, x1, y2, hpgl_plot_draw_absolute, true)); - hpgl_call(hpgl_close_current_path(pgls)); - } - /* exit polygon mode PM2 */ - hpgl_args_set_int(pargs,2); - hpgl_call(hpgl_PM(pargs, pgls)); - return 0; -} - -/* Fill or edge a wedge (EW, WG). */ -private int -hpgl_wedge(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ hpgl_real_t radius, start, sweep, chord = 5; - - if ( !hpgl_arg_units(pargs, &radius) || - !hpgl_arg_c_real(pargs, &start) || - !hpgl_arg_c_real(pargs, &sweep) || sweep < -360 || sweep > 360 || - (hpgl_arg_c_real(pargs, &chord) && (chord < 0.5 || chord > 180)) - ) - return e_Range; - - - /* enter polygon mode */ - hpgl_args_setup(pargs); - hpgl_call(hpgl_PM(pargs, pgls)); - - if ( sweep == 360.0 ) /* HAS needs epsilon */ - hpgl_call(hpgl_add_arc_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y, - radius, 0.0, 360.0, chord, true, - hpgl_plot_draw_absolute, true)); - else - /* draw the 2 lines and the arc using 3 point this does seem - convoluted but it does guarantee that the endpoint lines - for the vectors and the arc endpoints are coincident. */ - { - hpgl_real_t x1, y1, x2, y2, x3, y3; - hpgl_compute_vector_endpoints(radius, pgls->g.pos.x, pgls->g.pos.y, - start, &x1, &y1); - hpgl_compute_vector_endpoints(radius, pgls->g.pos.x, pgls->g.pos.y, - (start + (sweep / 2.0)), &x2, &y2); - hpgl_compute_vector_endpoints(radius, pgls->g.pos.x, pgls->g.pos.y, - (start + sweep), &x3, &y3); - hpgl_call(hpgl_add_point_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y, - hpgl_plot_move_absolute, true)); - hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, - hpgl_plot_draw_absolute, true)); - hpgl_call(hpgl_add_arc_3point_to_path(pgls, - x1, y1, - x2, y2, - x3, y3, chord, - hpgl_plot_draw_absolute)); - } - - hpgl_call(hpgl_close_current_path(pgls)); - hpgl_args_set_int(pargs,2); - hpgl_call(hpgl_PM(pargs, pgls)); - - return 0; -} - -/* ------ Commands ------ */ - -/* EA x,y; */ -int -hpgl_EA(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - - hpgl_call(hpgl_rectangle(pargs, pgls, DO_EDGE)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - return 0; -} - -/* EP; */ -int -hpgl_EP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - /* preserve the current path and copy the polygon buffer to - the current path */ - hpgl_call(hpgl_gsave(pgls)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector_no_close)); - hpgl_call(hpgl_grestore(pgls)); - return 0; -} - -/* ER dx,dy; */ -int -hpgl_ER(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_rectangle(pargs, pgls, DO_RELATIVE)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - return 0; -} - -/* EW radius,astart,asweep[,achord]; */ -int -hpgl_EW(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_wedge(pargs, pgls)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - return 0; -} - - private hpgl_rendering_mode_t -hpgl_get_poly_render_mode( - hpgl_state_t * pgls -) -{ - hpgl_FT_pattern_source_t type = pgls->g.fill.type; - - return ( ((type == hpgl_FT_pattern_one_line) || - (type == hpgl_FT_pattern_two_lines) ) - ? hpgl_rm_clip_and_fill_polygon - : hpgl_rm_polygon ); -} - -/* FP method; */ -/* FP; */ -int -hpgl_FP(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int method = 0; - - if ( hpgl_arg_c_int(pargs, &method) && (method & ~1) ) - return e_Range; - pgls->g.fill_type = (method == 0) ? - hpgl_even_odd_rule : hpgl_winding_number_rule; - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, - hpgl_get_poly_render_mode(pgls))); - return 0; -} - -/* PM op; */ -int -hpgl_PM(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ int op; - - if ( hpgl_arg_c_int(pargs, &op) == 0 ) - op = 0; - - switch( op ) - { - case 0 : - /* draw the current path if there is one */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - /* clear the polygon buffer as well */ - gx_path_new(&pgls->g.polygon.buffer.path); - /* global flag to indicate that we are in polygon mode */ - pgls->g.polygon_mode = true; - /* save the pen state, to be restored by PM2 */ - hpgl_save_pen_state(pgls, - &pgls->g.polygon.pen_state, - hpgl_pen_down | hpgl_pen_pos); - break; - case 1 : - hpgl_call(hpgl_close_current_path(pgls)); - /* remain in poly mode, this shouldn't be necessary */ - pgls->g.polygon_mode = true; - break; - case 2 : - if ( pgls->g.polygon_mode ) { - /* explicitly close the path if the pen is down */ - if ( pgls->g.move_or_draw == hpgl_pen_down ) - hpgl_call(hpgl_close_current_path(pgls)); - /* make a copy of the path and clear the current path */ - hpgl_call(hpgl_copy_current_path_to_polygon_buffer(pgls)); - hpgl_call(hpgl_clear_current_path(pgls)); - /* return to vector mode */ - pgls->g.polygon_mode = false; - /* restore the pen state */ - hpgl_restore_pen_state(pgls, - &pgls->g.polygon.pen_state, - hpgl_pen_down | hpgl_pen_pos); - } - break; - default: - return e_Range; - } - return 0; -} - -/* RA x,y; */ -int -hpgl_RA(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_rectangle(pargs, pgls, 0)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, - hpgl_get_poly_render_mode(pgls))); - return 0; -} - -/* RR dx,dy; */ -int -hpgl_RR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_rectangle(pargs, pgls, DO_RELATIVE)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, - hpgl_get_poly_render_mode(pgls))); - return 0; -} - -/* WG radius,astart,asweep[,achord]; */ -int -hpgl_WG(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_wedge(pargs, pgls)); - hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, - hpgl_get_poly_render_mode(pgls))); - return 0; -} - -/* Initialization */ -private int -pgpoly_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem) -{ /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('E', 'A', hpgl_EA, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('E', 'P', hpgl_EP, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('E', 'R', hpgl_ER, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('E', 'W', hpgl_EW, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('F', 'P', hpgl_FP, hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'M', hpgl_PM, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('R', 'A', hpgl_RA, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('R', 'R', hpgl_RR, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('W', 'G', hpgl_WG, hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -} -const pcl_init_t pgpoly_init = { - pgpoly_do_registration, 0 -}; diff --git a/pcl/pgstate.h b/pcl/pgstate.h deleted file mode 100644 index df773ae7c..000000000 --- a/pcl/pgstate.h +++ /dev/null @@ -1,329 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgstate.h - definition of HP-GL/2 portion of PCL5 state */ - -/* - * This file should not be included by files other than pcstate.h; if you - * need the information in this file, include pcstate.h. - */ - -#ifndef pgstate_INCLUDED -#define pgstate_INCLUDED - -/* - * HPGL/2 coordinates are internally represented in plotter units - * 1/1024" when scaling is off and user units when scaling is in - * effect. The data structure g.pos maintains the coordinates in the - * hpgl/2 state. By default the coordinate system sets up the origin - * in the lower left of the page with X increasing along the short - * edge and Y increasing up the long edge. Note the Y direction is - * opposite PCL's. - */ - -#include "gx.h" -#include "gxfixed.h" -#include "gslparam.h" - -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; -#endif -#include "gzpath.h" - -/* Opaque type for a path */ -#ifndef gx_path_DEFINED -# define gx_path_DEFINED -typedef struct gx_path_s gx_path; -#endif - -/* Define a type for HP-GL/2 floating point values. */ -typedef double hpgl_real_t; - -/* scaling definition */ -typedef struct hpgl_scaling_params_s { - gs_point pmin, pmax, factor; - float left, bottom; -} hpgl_scaling_params_t; - -/* Define a line type (a.k.a. dash pattern). */ -typedef struct hpgl_line_type_s { - int count; - hpgl_real_t gap[20]; -} hpgl_line_type_t; - -typedef struct hpgl_path_state_s { - gx_path path; -} hpgl_path_state_t; - -/* Define rendering modes - character, polygon, or vector. - This affects the line attributes chosen (see - hpgl_set_graphics_line_attribute_state) and whether we use - stroke or fill on the path. */ -typedef enum { - hpgl_rm_vector, - hpgl_rm_vector_no_close, - hpgl_rm_character, - hpgl_rm_polygon, - hpgl_rm_vector_fill, - hpgl_rm_clip_and_fill_polygon, /* for hpgl/2 line type filling */ - hpgl_rm_nop /* don't do anything with the path. future use */ -} hpgl_rendering_mode_t; - -/* state of lost mode */ -typedef enum { - hpgl_lost_mode_entered, - hpgl_lost_mode_cleared -} hpgl_lost_mode_t; - -typedef enum { - hpgl_even_odd_rule, - hpgl_winding_number_rule -} hpgl_render_fill_type_t; - -/* Define the structure for saving the pen state temporarily. */ -/* HAS: note don't mix and match save a restores. perhaps there - should be a type check field in the structure. */ -typedef struct hpgl_pen_state_s { - int relative_coords; - int move_or_draw; - gs_point pos; -} hpgl_pen_state_t; - -/* Define the parameters for GL hatch/cross-hatch fill types. */ -typedef struct hpgl_hatch_params_s { - float spacing; - float angle; -} hpgl_hatch_params_t; - -/* - * Define the functions for adding points to paths. Note that the - * move/draw and absolute/relative alternatives can be tested, set, etc. - * individually. - */ -#define hpgl_plot_absolute 0 -#define hpgl_plot_relative 1 -#define hpgl_plot_is_absolute(func) (((func) & hpgl_plot_relative) == 0) -#define hpgl_plot_is_relative(func) (((func) & hpgl_plot_relative) != 0) -#define hpgl_plot_move 0 -#define hpgl_plot_draw 2 -#define hpgl_plot_is_move(func) (((func) & hpgl_plot_draw) == 0) -#define hpgl_plot_is_draw(func) (((func) & hpgl_plot_draw) != 0) -typedef enum { - hpgl_plot_move_absolute = hpgl_plot_move | hpgl_plot_absolute, - hpgl_plot_move_relative = hpgl_plot_move | hpgl_plot_relative, - hpgl_plot_draw_absolute = hpgl_plot_draw | hpgl_plot_absolute, - hpgl_plot_draw_relative = hpgl_plot_draw | hpgl_plot_relative -} hpgl_plot_function_t; -#define hpgl_plot_function_procedures\ - gs_moveto, gs_rmoveto, gs_lineto, gs_rlineto - -typedef struct pcl_hpgl_state_s { - /* Chapter 17 lost mode (pgmisc.c) */ - - /* According to PCLTRM IN, PG, RP and PA with args in range clears - lost mode. Note that all these commands have PA with valid args - as a side effect so only PA needs to clear lost mode. */ - - hpgl_lost_mode_t lost_mode; - - /* Chapter 18 (pgframe.c) */ - - struct pf_ { - coord_point_t size; - coord_point_t anchor_point; - } picture_frame; - -#define picture_frame_width picture_frame.size.x -#define picture_frame_height picture_frame.size.y - - coord_point_t plot_size; - -#define plot_width plot_size.x -#define plot_height plot_size.y - bool plot_size_vertical_specified; - bool plot_size_horizontal_specified; - /* Chapter 19 (pgconfig.c) */ - - enum { - hpgl_scaling_none = -1, - hpgl_scaling_anisotropic = 0, - hpgl_scaling_isotropic = 1, - hpgl_scaling_point_factor = 2 - } scaling_type; - hpgl_scaling_params_t scaling_params; - struct soft_clip_window_ { - enum { - active, /* current unit window has be given */ - inactive, /* use picture frame */ - bound /* bound to plotter units */ - } state; - gs_rect rect; /* clipping window (IW) */ - } soft_clip_window; - int rotation; - gs_point P1, P2; /* in plotter units */ - - /* Chapter 20 (pgvector.c) */ - - int move_or_draw; /* hpgl_plot_move/draw */ - int relative_coords; /* hpgl_plot_absolute/relative */ - gs_point pos; - /* used to track the line drawing state in hpgl */ - gs_point first_point; - - /* Chapter 21 (pgpoly.c) */ - struct polygon_ { - hpgl_path_state_t buffer; /* path for polygon buffer */ - hpgl_pen_state_t pen_state; /* save pen state during polygon mode */ - } polygon; - bool polygon_mode; - - /* Chapter 22 (pglfill.c) */ - - struct lp_ { - struct ltl_ { - int type; - /* the offset value is not required by the gl/2 - language, however we use it to implement offsetting - line patterns for hpgl/2 vector fills */ - float pattern_offset; - float pattern_length; - bool pattern_length_relative; - bool is_solid; - } current, saved; /* enable saving for LT99 */ - int cap; - int join; - } line; - float miter_limit; - struct pen_ { - bool width_relative; - int selected; /* currently selected pen # */ - } pen; - byte symbol_mode; /* 0 if not in symbol mode */ - struct ft_ { - hpgl_FT_pattern_source_t type; - /* - * Because each fill type remembers its previous parameter values, - * we must use a structure rather than a union here. - */ - struct fp_ { - hpgl_hatch_params_t hatch; - hpgl_hatch_params_t crosshatch; - int shading; /* 0..100 */ - struct { int pattern_index; bool use_current_pen; } user_defined; - int pattern_type; - uint pattern_id; - } param; - } fill; - hpgl_render_fill_type_t fill_type; - hpgl_line_type_t fixed_line_type[8]; - hpgl_line_type_t adaptive_line_type[8]; - gs_point anchor_corner; - bool source_transparent; - struct scr_ { - hpgl_SV_pattern_source_t type; - struct sp_ { - int shading; /* 0..100 */ - struct { int pattern_index; bool use_current_pen; } user_defined; - int pattern_type; - uint pattern_id; - } param; - } screen; - /* Temporary while downloading raster fill pattern */ - struct rf_ { - int index, width, height; - uint raster; - byte *data; - bool is_mask; - } raster_fill; - - /* Chapter 23 (pgchar.c, pglabel.c) */ - - pcl_font_selection_t font_selection[2]; - int font_selected; /* 0 or 1 */ - pl_font_t *font; /* 0 means recompute from params */ - pl_symbol_map_t *map; /* map for current font */ - pl_font_t stick_font[2][2]; /* stick/arc fonts */ - struct ch_ { - gs_point direction; - bool direction_relative; - enum { - hpgl_text_right = 0, - hpgl_text_down = 1, - hpgl_text_left = 2, - hpgl_text_up = 3 - } text_path; -#define hpgl_text_is_vertical(path) (((path) & 1) != 0) - int line_feed_direction; /* +1 = normal, -1 = reversed */ - gs_point extra_space; - gs_point size; - enum { - hpgl_size_not_set, - hpgl_size_absolute, - hpgl_size_relative - } size_mode; - hpgl_real_t slant; - enum { - hpgl_char_solid_edge = 0, - hpgl_char_edge = 1, - hpgl_char_fill = 2, - hpgl_char_fill_edge = 3 - } fill_mode; - int edge_pen; /* 0 = no edge */ - } character; - struct lb_ { - int origin; - uint terminator; - bool print_terminator; - /* Double-byte support */ - uint row_offset; /* implicit high byte */ - bool double_byte; - bool write_vertical; - /* - * The following are only used during the execution of a - * single LB command, but since hpgl_LB may need to exit - * back to the parser for more data, we can't make them - * local variables of hpgl_LB. - */ - gs_point initial_pos; -#define hpgl_char_count 128 /* initial buffer size */ - byte *buffer; /* start of line buffer pointer */ - uint buffer_size; /* size of the current buffer */ - uint char_count; /* count of chars in the buffer */ - } label; - bool transparent_data; - uint font_id[2]; - bool bitmap_fonts_allowed; - gs_point carriage_return_pos; - /* extra pen state for routines that cannot use local variables - because of longjmp parser braindamage. */ - hpgl_pen_state_t pen_state; -} pcl_hpgl_state_t; - -#define hpgl_pen_relative (1) -#define hpgl_pen_down (1<<1) -#define hpgl_pen_pos (1<<2) -#define hpgl_pen_all (hpgl_pen_relative | hpgl_pen_down | hpgl_pen_pos) - -#define hpgl_save_pen_state(pgls, save, save_flags)\ -do {\ - if ( (save_flags) & hpgl_pen_relative )\ - ((save)->relative_coords = (pgls)->g.relative_coords);\ - if ( (save_flags) & hpgl_pen_down )\ - ((save)->move_or_draw = (pgls)->g.move_or_draw);\ - if ( (save_flags) & hpgl_pen_pos )\ - ((save)->pos = (pgls)->g.pos);\ -} while (0) - -#define hpgl_restore_pen_state(pgls, save, restore_flags)\ -do {\ - if ( (restore_flags) & hpgl_pen_relative )\ - ((pgls)->g.relative_coords = (save)->relative_coords);\ - if ( (restore_flags) & hpgl_pen_down )\ - ((pgls)->g.move_or_draw = (save)->move_or_draw);\ - if ( (restore_flags) & hpgl_pen_pos )\ - ((pgls)->g.pos = (save)->pos);\ -} while (0) - -#endif /* pgstate_INCLUDED */ diff --git a/pcl/pgvector.c b/pcl/pgvector.c deleted file mode 100644 index 1f7b6a304..000000000 --- a/pcl/pgvector.c +++ /dev/null @@ -1,568 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* pgvector.c */ -/* HP-GL/2 vector commands */ - -#include "stdio_.h" /* for gdebug.h */ -#include "gdebug.h" -#include "pcparse.h" -#include "pgmand.h" -#include "pggeom.h" -#include "pgdraw.h" -#include "pgmisc.h" -#include "gspath.h" -#include "gscoord.h" -#include "math_.h" - -/* ------ Internal procedures ------ */ - -/* Draw an arc (AA, AR). */ - private int -hpgl_arc(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) -{ - hpgl_real_t x_center, y_center, sweep, x_current, y_current, chord_angle = 5; - hpgl_real_t radius, start_angle; - - if ( !hpgl_arg_units(pargs, &x_center) || - !hpgl_arg_units(pargs, &y_center) || - !hpgl_arg_c_real(pargs, &sweep) - ) - return e_Range; - - hpgl_arg_c_real(pargs, &chord_angle); - - x_current = pgls->g.pos.x; - y_current = pgls->g.pos.y; - - if ( relative ) - { - x_center += x_current; - y_center += y_current; - } - - radius = - hpgl_compute_distance(x_current, y_current, x_center, y_center); - - start_angle = radians_to_degrees * - hpgl_compute_angle(x_current - x_center, y_current - y_center); - - hpgl_call(hpgl_add_arc_to_path(pgls, x_center, y_center, - radius, start_angle, sweep, - (sweep < 0.0 ) ? - -chord_angle : chord_angle, false, - pgls->g.move_or_draw, true)); - - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* Draw a 3-point arc (AT, RT). */ - private int -hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) -{ - hpgl_real_t x_start = pgls->g.pos.x, y_start = pgls->g.pos.y; - hpgl_real_t x_inter, y_inter, x_end, y_end; - hpgl_real_t chord_angle = 5; - - if ( !hpgl_arg_units(pargs, &x_inter) || - !hpgl_arg_units(pargs, &y_inter) || - !hpgl_arg_units(pargs, &x_end) || - !hpgl_arg_units(pargs, &y_end) - ) - return e_Range; - - hpgl_arg_c_real(pargs, &chord_angle); - - if ( relative ) - { - x_inter += x_start; - y_inter += y_start; - x_end += x_start; - y_end += y_start; - } - - hpgl_call(hpgl_add_arc_3point_to_path(pgls, - x_start, y_start, - x_inter, y_inter, - x_end, y_end, chord_angle, - pgls->g.move_or_draw)); - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* Draw a Bezier (BR, BZ). */ -int -hpgl_bezier(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) -{ - hpgl_real_t x_start, y_start; - - /* We must clear the current path since we cannot properly - join lines to curves with the current line drawing - machinery */ - if ( ( pargs->phase == 0 ) && ( !pgls->g.polygon_mode ) ) { - hpgl_call(hpgl_clear_current_path(pgls)); - pargs->phase = 1; - } - - /* - * Since these commands take an arbitrary number of arguments, - * we reset the argument bookkeeping after each group. - */ - - for ( ; ; ) - { - hpgl_real_t coords[6]; - int i; - - for ( i = 0; i < 6 && hpgl_arg_units(pargs, &coords[i]); ++i ) - ; - switch ( i ) - { - case 0: /* done */ - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - /* draw the path */ - if ( !pgls->g.polygon_mode ) { - /* apparently only round and beveled joins are - allowed 5 is bevel and 4 is round */ - int save_join = pgls->g.line.join; - if ( pgls->g.line.join != 1 && pgls->g.line.join != 4 ) - pgls->g.line.join = 1; /* bevel */ - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.line.join = save_join; - } - return 0; - case 6: - break; - default: - return e_Range; - } - - x_start = pgls->g.pos.x; - y_start = pgls->g.pos.y; - - if ( relative ) - hpgl_call(hpgl_add_bezier_to_path(pgls, x_start, y_start, - x_start + coords[0], - y_start + coords[1], - x_start + coords[2], - y_start + coords[3], - x_start + coords[4], - y_start + coords[5], - pgls->g.move_or_draw)); - else - hpgl_call(hpgl_add_bezier_to_path(pgls, x_start, y_start, - coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5], - pgls->g.move_or_draw)); - /* Prepare for the next set of points. */ - hpgl_args_init(pargs); - } -} - -/* Plot points, symbols, or lines (PA, PD, PR, PU). */ -int -hpgl_plot(hpgl_args_t *pargs, hpgl_state_t *pgls, hpgl_plot_function_t func) -{ - - /* - * Since these commands take an arbitrary number of arguments, - * we reset the argument bookkeeping after each group. - */ - - hpgl_real_t x, y; - if ( hpgl_plot_is_move(func) ) - hpgl_call(hpgl_close_path(pgls)); - - while ( hpgl_arg_units(pargs, &x) && hpgl_arg_units(pargs, &y) ) - { - pargs->phase = 1; /* we have arguments */ - hpgl_call(hpgl_add_point_to_path(pgls, x, y, func, true)); - /* Prepare for the next set of points. */ - if ( pgls->g.symbol_mode != 0 ) - hpgl_call(hpgl_print_symbol_mode_char(pgls)); - hpgl_args_init(pargs); - } - - /* check for no argument case */ - if ( !pargs->phase) - { - if ( hpgl_plot_is_relative(func) ) - /*hpgl_call(hpgl_add_point_to_path(pgls, 0.0, 0.0, func, true)) */; - else - { - gs_point cur_point; - if ( !pgls->g.polygon_mode ) { - hpgl_call(hpgl_get_current_position(pgls, &cur_point)); - hpgl_call(hpgl_add_point_to_path(pgls, cur_point.x, - cur_point.y, func, true)); - } - } - } - if ( pgls->g.symbol_mode != 0 ) - hpgl_call(hpgl_print_symbol_mode_char(pgls)); - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; -} - -/* ------ Commands ------ */ - private int -hpgl_draw_arc(hpgl_state_t *pgls) -{ - if ( !pgls->g.polygon_mode ) - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - return 0; -} - -/* AA xcenter,ycenter,sweep[,chord]; */ - int -hpgl_AA(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_arc(pargs, pgls, false)); - hpgl_call(hpgl_draw_arc(pgls)); - return 0; -} - -/* AR xcenter,ycenter,sweep[,chord]; */ - int -hpgl_AR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_arc(pargs, pgls, true)); - hpgl_call(hpgl_draw_arc(pgls)); - return 0; -} - -/* AT xinter,yinter,xend,yend[,chord]; */ - int -hpgl_AT(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_arc_3_point(pargs, pgls, false)); - hpgl_call(hpgl_draw_arc(pgls)); - return 0; -} - -/* BR x1,y1,x2,y2,x3,y3...; */ - int -hpgl_BR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ return hpgl_bezier(pargs, pgls, true); -} - -/* BZ x1,y1,x2,y2,x3,y3...; */ -int -hpgl_BZ(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ return hpgl_bezier(pargs, pgls, false); -} - -/* CI radius[,chord]; */ -int -hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_real_t radius, chord = 5; - bool reset_ctm = true; - gs_point pos = pgls->g.pos; /* center */ - - if ( !hpgl_arg_units(pargs, &radius) ) - return e_Range; - hpgl_arg_c_real(pargs, &chord); - /* draw the path here for line type 0, otherwise the first dot - drawn in the circumference of the circle will be oriented - in the same direction as the center dot */ - if ( !pgls->g.line.current.is_solid && (pgls->g.line.current.type == 0) ) - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - - /* draw the arc/circle */ - hpgl_call(hpgl_add_arc_to_path(pgls, pos.x, pos.y, - radius, 0.0, 360.0, chord, true, - hpgl_plot_draw_absolute, reset_ctm)); - if ( !pgls->g.polygon_mode ) - hpgl_call(hpgl_draw_arc(pgls)); - /* move back to the center */ - hpgl_call(hpgl_set_current_position(pgls, &pos)); - if ( !pgls->g.polygon_mode ) - hpgl_call(hpgl_clear_current_path(pgls)); - return 0; - -} - -/* PA x,y...; */ -int -hpgl_PA(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - - if ( pgls->g.relative_coords != hpgl_plot_absolute ) { - pgls->g.relative_coords = hpgl_plot_absolute; - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - hpgl_call(hpgl_clear_current_path(pgls)); - } - return hpgl_plot(pargs, pgls, - pgls->g.move_or_draw | hpgl_plot_absolute); -} - -/* PD (d)x,(d)y...; */ -int -hpgl_PD(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - pgls->g.move_or_draw = hpgl_plot_draw; - return hpgl_plot(pargs, pgls, - hpgl_plot_draw | pgls->g.relative_coords); -} - -/* PE (flag|value|coord)*; */ -/* - * We record the state of the command in the 'phase' as follows: - */ -enum { - pe_pen_up = 1, /* next coordinate are pen-up move */ - pe_absolute = 2, /* next coordinates are absolute */ - pe_7bit = 4, /* use 7-bit encoding */ - pe_entered = 8 /* we have entered PE once */ -}; -#define pe_fbits_shift 3 /* ... + # of fraction bits << this much */ -private bool pe_args(P3(hpgl_args_t *, int32 *, int)); -int -hpgl_PE(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - /* - * To simplify the control structure here, we require that - * the input buffer be large enough to hold 2 coordinates - * in the base 32 encoding, i.e., 14 bytes. We're counting on - * there not being any whitespace within coordinate values.... - */ - const byte *p = pargs->source.ptr; - const byte *rlimit = pargs->source.limit; - - if ( pargs->phase == 0 ) { - /* After PE is executed, the previous plotting mode (absolute or - relative) is restored. If the finnal move is made with the pen up, - the pen remains in the up position; otherwise the pen is left in - the down position. At least HP documented this bug. */ - hpgl_save_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative); - pargs->phase |= pe_entered; - } - while ( p < rlimit ) { - byte ch = *(pargs->source.ptr = ++p); - switch ( ch & 127 /* per spec */ ) { - case ';': - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - if ( pargs->phase & pe_entered ) - hpgl_restore_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative); - /* prevent paths from getting excessively large */ - if ( !pgls->g.polygon_mode ) - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - return 0; - case ':': - if_debug0('I', "\n :"); - { - int32 pen; - if ( !pe_args(pargs, &pen, 1) ) - { - pargs->source.ptr = p - 1; - break; - } - if ( !pgls->g.polygon_mode ) { - hpgl_args_t args; - hpgl_args_set_int(&args, pen); - /* Note SP is illegal in polygon mode we must handle that here */ - hpgl_call(hpgl_SP(&args, pgls)); - } - } - p = pargs->source.ptr; - continue; - case '<': - if_debug0('I', "\n <"); - pargs->phase |= pe_pen_up; - continue; - case '>': - if_debug0('I', "\n >"); - { - int32 fbits; - if ( !pe_args(pargs, &fbits, 1) ) - { - pargs->source.ptr = p - 1; - break; - } - if ( fbits < -26 || fbits > 26 ) - return e_Range; - pargs->phase = - (pargs->phase & (-1 << pe_fbits_shift)) + - (fbits << pe_fbits_shift); - } - p = pargs->source.ptr; - continue; - case '=': - if_debug0('I', " ="); - pargs->phase |= pe_absolute; - continue; - case '7': - if_debug0('I', "\n 7"); - pargs->phase |= pe_7bit; - continue; - case ESC: - /* - * This is something of a hack. Apparently we're supposed - * to parse all PCL commands embedded in the GL/2 stream, - * and simply ignore everything except the 3 that end GL/2 - * mode. Instead, we simply stop parsing PE arguments as - * soon as we see an ESC. - */ - if ( ch == ESC ) /* (might be ESC+128) */ { - pargs->source.ptr = p - 1; /* rescan ESC */ - if ( pargs->phase & pe_entered ) { - hpgl_restore_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative); - } - hpgl_call(hpgl_update_carriage_return_pos(pgls)); - return 0; - } - /* falls through */ - default: - if ( (ch & 127) <= 32 || (ch & 127) == 127 ) - continue; - pargs->source.ptr = p - 1; - { - int32 xy[2]; - hpgl_args_t args; - if ( !pe_args(pargs, xy, 2) ) - break; - hpgl_args_setup(&args); - if ( pargs->phase & pe_absolute ) - hpgl_PA(&args, pgls); - else - hpgl_PR(&args, pgls); - hpgl_args_set_real2(&args, (floatp)xy[0], (floatp)xy[1]); - if ( pargs->phase & pe_pen_up ) - hpgl_PU(&args, pgls); - else - hpgl_PD(&args, pgls); - } - pargs->phase &= ~(pe_pen_up | pe_absolute); - p = pargs->source.ptr; - continue; - } - break; - } - return e_NeedData; -} -/* Get an encoded value from the input. Return false if we ran out of */ -/* input data. Ignore syntax errors (!). */ -private bool -pe_args(hpgl_args_t *pargs, int32 *pvalues, int count) -{ const byte *p = pargs->source.ptr; - const byte *rlimit = pargs->source.limit; - int i; - - for ( i = 0; i < count; ++i ) - { int32 value = 0; - int shift = 0; - - for ( ; ; ) - { int ch; - - if ( p >= rlimit ) - return false; - ch = *++p; - if ( (ch & 127) <= 32 || (ch & 127) == 127 ) - continue; - if ( pargs->phase & pe_7bit ) - { ch -= 63; - if ( ch & ~63 ) - goto syntax_error; - value += (int32)(ch & 31) << shift; - shift += 5; - if ( ch & 32 ) - break; - } - else - { ch -= 63; - if ( ch & ~191 ) - goto syntax_error; - value += (int32)(ch & 63) << shift; - shift += 6; - if ( ch & 128 ) - break; - } - } - pvalues[i] = (value & 1 ? -(value >> 1) : value >> 1); - if_debug2('I', " [%ld,%d]", (long)pvalues[i], - (int)arith_rshift(pargs->phase, pe_fbits_shift)); - } - pargs->source.ptr = p; - return true; -syntax_error: - /* Just ignore everything we've parsed up to this point. */ - pargs->source.ptr = p; - return false; -} - -/* PR dx,dy...; */ -int -hpgl_PR(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - if ( pgls->g.relative_coords != hpgl_plot_relative ) { - pgls->g.relative_coords = hpgl_plot_relative; - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - hpgl_call(hpgl_clear_current_path(pgls)); - } - return hpgl_plot(pargs, pgls, - pgls->g.move_or_draw | hpgl_plot_relative); - -} - -/* PU (d)x,(d)y...; */ -int -hpgl_PU(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - pgls->g.move_or_draw = hpgl_plot_move; - return hpgl_plot(pargs, pgls, - hpgl_plot_move | pgls->g.relative_coords); -} - -/* RT xinter,yinter,xend,yend[,chord]; */ -int -hpgl_RT(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_call(hpgl_arc_3_point(pargs, pgls, true)); - hpgl_call(hpgl_draw_arc(pgls)); - return 0; -} - -/* Initialization */ -private int -pgvector_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t *mem -) -{ - /* Register commands */ - DEFINE_HPGL_COMMANDS - HPGL_COMMAND('A', 'A', - hpgl_AA, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('A', 'R', - hpgl_AR, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('A', 'T', - hpgl_AT, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('B', 'R', - hpgl_BR, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('B', 'Z', - hpgl_BZ, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('C', 'I', - hpgl_CI, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'A', - hpgl_PA, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('P', 'D', - hpgl_PD, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('P', 'E', - hpgl_PE, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), - HPGL_COMMAND('P', 'R', - hpgl_PR, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('P', 'U', - hpgl_PU, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */ - HPGL_COMMAND('R', 'T', - hpgl_RT, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), - END_HPGL_COMMANDS - return 0; -} -const pcl_init_t pgvector_init = { - pgvector_do_registration, 0 -}; diff --git a/pcl/rtgmode.c b/pcl/rtgmode.c deleted file mode 100644 index 6224cdd4f..000000000 --- a/pcl/rtgmode.c +++ /dev/null @@ -1,713 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtgmode.c - PCL graphics (raster) mode */ -#include "gx.h" -#include "math_.h" -#include "gsmatrix.h" -#include "gscoord.h" -#include "gsrect.h" -#include "gsstate.h" -#include "pcstate.h" -#include "pcpatxfm.h" -#include "pcpage.h" -#include "pcindxed.h" -#include "pcpalet.h" -#include "pcursor.h" -#include "pcdraw.h" -#include "rtraster.h" -#include "rtrstcmp.h" -#include "rtgmode.h" - -/* - * Intersect a rectangle with the positive quadrant. - */ - private void -intersect_with_positive_quadrant( - gs_rect * prect -) -{ - if (prect->p.x < 0.0) { - prect->p.x = 0.0; - prect->q.x = (prect->q.x < 0.0 ? 0.0 : prect->q.x); - } - if (prect->p.y < 0.0) { - prect->p.y = 0.0; - prect->q.y = (prect->q.y < 0.0 ? 0.0 : prect->q.y); - } -} - -/* - * Get the effective printing region in raster space - */ - private void -get_raster_print_rect( - const gs_rect * plp_print_rect, - gs_rect * prst_print_rect, - const gs_matrix * prst2lp -) -{ - gs_matrix lp2rst; - - pcl_invert_mtx(prst2lp, &lp2rst); - pcl_transform_rect(plp_print_rect, prst_print_rect, &lp2rst); - intersect_with_positive_quadrant(prst_print_rect); -} - -/* - * Enter raster graphics mode. - * - * The major function of this routine is to establish the raster to device - * space transformations. This is rather involved: - * - * 1. The first feature to be established is the orientation of raster space - * relative to page space. Three state parameters are involved in - * determining this orientation: the logical page orientation, the current - * print direction, and the raster presentation mode. These are combined - * in the following manner: - * - * tr = (print_direction / 90) + logical_page_orientation - * - * raster_rotate = (presentation_mode == 0 ? tr : tr & 0x2) - * - * 2. The next step is to determine the location of the origin of the raster - * to page transformation. Intially this origin is set at the appropriate - * corner of the logical page, based on the orientation determined above. - * The origin is then shift based on the manner in which graphics mode is - * entered (the mode operand): - * - * If entry is IMPLICIT (i.e.: via a transfer data command rather than - * an enter graphics mode command), translation by the existing left - * graphics margin is used, in the orientation of raster space. - * - * If entry is via an enter graphics mode command which specifies moving - * the origin to the logical page boundary (NO_SCALE_LEFT_MARG (0) or - * SCALE_LEFT_MARG (2)), action depends on whether or not horizontal - * access of print direction space and of raster space are the same: - * - * if there are the same, the origin is left unchanged - * - * if they are not the same, the origin is shifted 1/6" (1200 centi- - * points) in the positive horizontal raster space axis. - * - * The latter correction is not documented by HP, and there is no clear - * reason why it should apply, but it has been verified to be the case - * for all HP products testd. - * - * If entry is via an enter graphics mode command with specifies use - * of the current point (NO_SCALE_CUR_PT(1) or SCALE_CUR_PT(3)), the - * current point is transformed to raster space and its "horizontal" - * component is used as the new graphics margin. - * - * Irrespective of how the "horizontal" component of the raster image origin - * is specified, the vertical component is always derived from the current - * addressable point, by converting the point to raster space. - * - * 3. Next, the scale of the raster to page space transformation is established. - * This depends on whether or not PCL raster scaling is to be employed. - * For raster scaling to be used, all of the following must hold: - * - * the scale_raster flag in the PCL raster state must be set - * the current palette must be writable - * the raster source height and width must have been explicitly set - * - * The scale_raster flag in the PCL raster state is normally set by the - * enter raster graphics command. Hence, if graphics mode is entered - * explicitly, the first requirement follows the behavior of the HP Color - * LaserJet 5/5M. The DeskJet 1600C/CM behaves differently: it will never - * user raster scaling if graphics mode is entered implicitly. - * - * The reason for the second requirement is undoubtedly related to some - * backwards compatibility requirement, but is otherwise obscure. The - * restriction is, however, both document and uniformly applied by all - * HP products that support raster scaling. - * - * If raster scaling is not used, the scale of raster space is determined - * by the ratio of the graphics resolution (set by the graphics resolution - * command) and unit of page space (centi-points). This factor is applied - * in both scan directions. - * - * If scaline is employed, the situation is somewhat more complicated. It - * is necessary, in this case, to know which of the raster destination - * dimensions have been explicitly set: - * - * If both dimensions are specified, the ration of these dimensions - * to the source raster width and height determine the raster scale. - * - * If only one destination dimension is specified, the ratio of this - * dimension to the corresponding source dimension determins the - * raster scale for both dimensions - * - * If neither dimension is specified, the page printable region is - * transformed to raster space, the intersection of this with the - * positive quadrant is taken. The dimensions of the resulting region - * are compared with the dimensions of the source raster. The smaller - * of the two dest_dim / src_dim ratios is used as the ratio for - * the raster scale in both dimensions (i.e.: select the largest - * isotropic scaling that does not cause clipping). - * - * 4. Finally, the extent of raster space must be determined. This is done by - * converting the page printable region to raster space and intersecting - * the result with the positive quadrant. This region is used to determine - * the useable source raster width and height. - * - */ - int -pcl_enter_graphics_mode( - pcl_state_t * pcs, - pcl_gmode_entry_t mode -) -{ - floatp scale_x, scale_y; - pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); - pcl_raster_state_t * prstate = &(pcs->raster_state); - float gmargin_cp = (float)prstate->gmargin_cp; - gs_point cur_pt; - gs_matrix rst2lp, rst2dev, lp2rst; - gs_rect print_rect; - uint src_wid, src_hgt; - int rot; - int code = 0; - bool marked; - - /* - * Check if the raster is to be clipped fully; see rtrstst.h for details. - * Since this is a discontinuous effect, the equality checks below - * should be made while still in centipoings. - */ - prstate->clip_all = ( (pcs->cap.x == pxfmst->pd_size.x) || - (pcs->cap.y == pxfmst->pd_size.y) ); - - /* create to raster space to logical page space transformation */ - rot = pxfmst->lp_orient + pxfmst->print_dir; - if (prstate->pres_mode_3) - rot &= 0x2; - rot = (rot - pxfmst->lp_orient) & 0x3; - if (prstate->y_advance == -1) - rot = (rot + 2) & 0x3; - pcl_make_rotation(rot, pxfmst->lp_size.x, pxfmst->lp_size.y, &rst2lp); - pcl_invert_mtx(&rst2lp, &lp2rst); - - /* convert the current point to raster space */ - cur_pt.x = (double)pcs->cap.x; - cur_pt.y = (double)pcs->cap.y; - pcl_xfm_to_logical_page_space(pcs, &cur_pt); - gs_point_transform(cur_pt.x, cur_pt.y, &lp2rst, &cur_pt); - - /* translate the origin of the forward transformation */ - if (((int)mode & 0x1) != 0) - gmargin_cp = cur_pt.x; - gs_matrix_translate(&rst2lp, gmargin_cp, cur_pt.y, &rst2lp); - prstate->gmargin_cp = gmargin_cp; - - /* set the matrix scale */ - if ( !prstate->scale_raster || - !prstate->src_width_set || - !prstate->src_height_set || - pcs->ppalet->pindexed->pfixed ) { - scale_x = 7200.0 / (floatp)prstate->resolution; - scale_y = scale_x; - - } else if (prstate->dest_width_set) { - scale_x = (floatp)prstate->dest_width_cp / (floatp)prstate->src_width; - if (prstate->dest_height_set) - scale_y = (floatp)prstate->dest_height_cp - / (floatp)prstate->src_height; - else - scale_y = scale_x; - - } else if (prstate->dest_height_set) { - scale_y = (floatp)prstate->dest_height_cp / (floatp)prstate->src_height; - scale_x = scale_y; - - } else { - double dwid, dhgt; - - /* transform the clipping window to raster space */ - get_raster_print_rect(&(pxfmst->lp_print_rect), &print_rect, &rst2lp); - - /* select isotropic scaling with no clipping */ - dwid = print_rect.q.x - print_rect.p.x; - dhgt = print_rect.q.y - print_rect.p.y; - scale_x = (floatp)dwid / (floatp)prstate->src_width; - scale_y = (floatp)dhgt / (floatp)prstate->src_height; - if (scale_x > scale_y) - scale_x = scale_y; - else - scale_y = scale_x; - } - - gs_matrix_scale(&rst2lp, scale_x, scale_y, &rst2lp); - gs_matrix_multiply(&rst2lp, &(pxfmst->lp2dev_mtx), &rst2dev); - - /* - * Set up the graphic stat for rasters. This turns out to be more difficult - * than might first be imagined. - * - * One problem is that two halftones may be needed simultaneously: - * - * the foreground CRD and halftone, in case the current "texture" is a - * a solid color or an uncolored pattern - * - * the palette CRD and halftone, to be used in rendering the raster - * itself - * - * Since the graphic state can only hold one CRD and one halftone method - * at a time, this presents a bit of a problem. - * - * To get around the problem, an extra graphic state is necessary. Patterns - * in the graphic library are given their own graphic state. Hence, by - * replacing a solid color with an uncolored pattern that takes the - * foreground value everywhere, the desired effect can be achieved. Code - * in pcpatrn.c handles these matters. - * - * The second problem is a limitation in the graphic library's support of - * CIE color spaces. These spaces require a joint cache, which is only - * created when the color space is installed in the graphic state. However, - * the current color space at the time a raster is rendered may need to - * be a pattern color space, so that the proper interaction between the - * raster and the texture generated by the pattern. To work around this - * problem, we install the raster's color space in the current graphic - * state, perform a gsave, then place what may be a patterned color space - * in the new graphic state. - */ - pcl_set_graphics_state(pcs); - pcl_set_drawing_color(pcs, pcl_pattern_raster_cspace, 0, true); - pcl_gsave(pcs); - pcl_set_drawing_color(pcs, pcs->pattern_type, pcs->current_pattern_id, true); - gs_setmatrix(pcs->pgs, &rst2dev); - - /* translate the origin of the forward transformation */ - /* tansform the clipping window to raster space; udpate source dimensions */ - get_raster_print_rect(&(pxfmst->lp_print_rect), &print_rect, &rst2lp); - - src_wid = (uint)(floor(print_rect.q.x) - floor(print_rect.p.x)); - src_hgt = (uint)(floor(print_rect.q.y) - floor(print_rect.p.y)); - if (prstate->src_width_set && (src_wid > prstate->src_width)) - src_wid = prstate->src_width; - if (prstate->src_height_set && (src_hgt > prstate->src_height)) - src_hgt = prstate->src_height; - - /* determine (conservatively) if the region of interest has been - marked */ - marked = true; - if ( !pcs->source_transparent && pcs->pattern_transparent ) { - gs_matrix mat; - gs_rect page_bbox; - gs_rect rast_bbox; - gs_point initial_pt; - - code = pcl_current_bounding_box(pcs, &page_bbox); - if ( code < 0 ) - return code; /* a shouldn't happen */ - /* get the bounding box for the raster and convert the box to - device space and check if the two rectangles overlap. */ - print_rect.q.x = print_rect.p.x + src_wid; - print_rect.q.y = print_rect.p.y + src_hgt; - gs_bbox_transform(&print_rect, &rst2dev, &print_rect); - rect_intersect(print_rect, page_bbox); - if ((print_rect.p.x >= print_rect.q.x) || (print_rect.p.y >= print_rect.q.y)) - marked = false; - } - if ((code = pcl_start_raster(src_wid, src_hgt, marked, pcs)) >= 0) - prstate->graphics_mode = true; - else - pcl_grestore(pcs); - return code; -} - -/* - * End (raster) graphics mode. This may be called explicitly by either of the - * end graphics mode commands (<esc>*rB or <esc>*rC), or implicitly by any - * commmand which is neither legal nor ignored in graphics mode. - */ - int -pcl_end_graphics_mode( - pcl_state_t * pcs -) -{ - gs_point cur_pt; - gs_matrix dev2pd; - - /* close the raster; exit graphics mode */ - pcl_complete_raster(pcs); - pcs->raster_state.graphics_mode = false; - - /* get the new current point; then restore the graphic state */ - gs_transform(pcs->pgs, 0.0, 0.0, &cur_pt); - pcl_grestore(pcs); - - /* transform the new point back to "pseudo print direction" space */ - pcl_invert_mtx(&(pcs->xfm_state.pd2dev_mtx), &dev2pd); - gs_point_transform(cur_pt.x, cur_pt.y, &dev2pd, &cur_pt); - pcl_set_cap_x(pcs, (coord)(cur_pt.x + 0.5), false, false); - return pcl_set_cap_y( pcs, - (coord)(cur_pt.y + 0.5) - pcs->margins.top, - false, - false, - false - ); -} - - -/* - * ESC * t # R - * - * Set raster graphics resolution. The value provided will be adjusted to be - * an integral divisor of 600 that is >= 75. For consistency with HP, the - * value 120 is not allowed. - */ - private int -set_graphics_resolution( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint res = uint_arg(pargs); - uint qi = (uint)floor(600.0 / (floatp)res); - - /* HP does not allow 120 dpi as a resolution */ - qi = (qi == 0 ? 1 : (qi > 8 ? 8 : (qi == 5 ? 4 : qi))); - - /* ignore if already in graphics mode */ - if (!pcs->raster_state.graphics_mode) - pcs->raster_state.resolution = 600 / qi; - - return 0; -} - -/* - * ESC * r # F - * - * Set raster graphics presentation mode. - * - * This command is ignored if values other than 0 and 3 are provided, ignoring - * any sign. The command is also ignored inside graphics mode. - */ - private int -set_graphics_presentation_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint mode = uint_arg(pargs); - - if (!pcs->raster_state.graphics_mode) { - if (mode == 3) - pcs->raster_state.pres_mode_3 = 1; - else if (mode == 0) - pcs->raster_state.pres_mode_3 = 0; - } - - return 0; -} - -/* - * ESC * r # S - * - * Set raster width. Note that the useable width may be less due to clipping. - * This implementation ignores the sign of the dimension, which matches the - * behavior of the HP Color LaserJet 5/5M. The behavior of the of the DeskJet - * 1600C/CM differs: it ignores the command if a negative operand is provided. - * - * This command is ignored in graphics mode. - */ - private int -set_src_raster_width( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) { - pcs->raster_state.src_width = uint_arg(pargs); - pcs->raster_state.src_width_set = true; - } - return 0; -} - -/* - * ESC * r # t - * - * Set raster height. Note that the useable height may be less due to clipping. - * This implementation ignores the sign of the dimension, which matches the - * behavior of the HP Color LaserJet 5/5M. The behavior of the of the DeskJet - * 1600C/CM differs: it ignores the command if a negative operand is provided. - * - * This command is ignored in graphics mode. - */ - private int -set_src_raster_height( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) { - pcs->raster_state.src_height = uint_arg(pargs); - pcs->raster_state.src_height_set = true; - } - return 0; -} - -/* - * ESC * b # M - * - * Set compresson method. - * - * This command is unique among PCL commands in that it is interpreted both - * inside and outside of graphics mode, and its execution neither starts nor - * ends graphic mode. - * - * It is not possible to use adaptive compression (mode 5) with mutliple plane - * pixel encodings, but it is not possible to check for a conflict at this - * point as the pixel encoding may be changed before any raster data is - * transfered. Hence, the transfer raster data command must perform the required - * check. - */ - private int -set_compression_method( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint mode = uint_arg(pargs); - - if ( (mode < count_of(pcl_decomp_proc)) && - ((pcl_decomp_proc[mode] != 0) || (mode == (uint)ADAPTIVE_COMPRESS)) ) - pcs->raster_state.compression_mode = mode; - return 0; -} - -/* - * ESC * t # H - * - * Set destination raster width, in decipoints. This implementation follows that - * of the HP Color LaserJet 5/5M in that it ignores the sign of the operand; the - * DeskJet 1600 C/CM has different behavior. Note that the stored value is in - * centi-points, while the operand is in deci-points. - * - * Though it is not noted in the "PCL 5 Color Technical Reference Manual", this - * command is ignored in graphics mode. - */ - private int -set_dest_raster_width( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) { - uint dw = 10 * uint_arg(pargs); - - pcs->raster_state.dest_width_cp = dw; - pcs->raster_state.dest_width_set = (dw != 0); - } - return 0; -} - -/* - * ESC * t # V - * - * Set destination raster height, in decipoints. This implementation follows that - * of the HP Color LaserJet 5/5M in that it ignores the sign of the operand; the - * DeskJet 1600 C/CM has different behavior. Note that the stored value is in - * centi-points, while the operand is in deci-points. - * - * Though it is not noted in the "PCL 5 Color Technical Reference Manual", this - * command is ignored in graphics mode. - */ - private int -set_dest_raster_height( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (!pcs->raster_state.graphics_mode) { - uint dh = 10 * uint_arg(pargs); - - pcs->raster_state.dest_height_cp = dh; - pcs->raster_state.dest_height_set = (dh != 0); - } - return 0; -} - -/* - * ESC * r # A - * - * Start raster graphics mode. - * - * See the commment ahead of the procedure pcl_enter_graphics mode above for - * a discussion of the rather curios manner in which the left raster graphics - * margin is set below. - */ - private int -start_graphics_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcl_gmode_entry_t mode = (pcl_gmode_entry_t)uint_arg(pargs); - pcl_raster_state_t * prstate = &(pcs->raster_state); - - if (mode > SCALE_CUR_PTR) - mode = NO_SCALE_LEFT_MARG; - if (!prstate->graphics_mode) { - int r90 = (pcs->xfm_state.lp_orient + pcs->xfm_state.print_dir) & 0x1; - - prstate->scale_raster = ((((int)mode) & 0x2) != 0); - prstate->gmargin_cp = 0; - if (prstate->pres_mode_3 && (r90 != 0)) - prstate->gmargin_cp += inch2coord(1.0 / 6.0); - pcl_enter_graphics_mode(pcs, mode); - } - return 0; -} - -/* - * ESC * r # B - * - * End raster graphics mode - old style. - */ - private int -end_graphics_mode_B( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (pcs->raster_state.graphics_mode) - pcl_end_graphics_mode(pcs); - return 0; -} - -/* - * ESC * r # C - * - * End raster graphics mode - new style. This resets the compression mode and - * the left grahics margin, in addition to ending graphics mode. - */ - private int -end_graphics_mode_C( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - if (pcs->raster_state.graphics_mode) - pcl_end_graphics_mode(pcs); - pcs->raster_state.gmargin_cp = 0L; - pcs->raster_state.compression_mode = 0; - return 0; -} - - -/* - * Initialization - */ - private int -gmode_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem /* ignored */ -) -{ - DEFINE_CLASS('*') - { - 't', 'R', - PCL_COMMAND( "Raster Graphics Resolution", - set_graphics_resolution, - pca_raster_graphics | pca_neg_ok | pca_big_clamp | pca_in_rtl - ) - }, - { - 'r', 'F', - PCL_COMMAND( "Raster Graphics Presentation Mode", - set_graphics_presentation_mode, - pca_raster_graphics | pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 'r', 'S', - PCL_COMMAND( "Source Raster Width", - set_src_raster_width, - pca_raster_graphics | pca_neg_ok | pca_big_clamp | pca_in_rtl - ) - }, - { - 'r', 'T', - PCL_COMMAND( "Source Raster_Height", - set_src_raster_height, - pca_raster_graphics | pca_neg_ok | pca_big_clamp | pca_in_rtl - ) - }, - { - 'b', 'M', - PCL_COMMAND( "Set Compresion Method", - set_compression_method, - pca_raster_graphics | pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 't', 'H', - PCL_COMMAND( "Destination Raster Width", - set_dest_raster_width, - pca_raster_graphics | pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 't', 'V', - PCL_COMMAND( "Destination Raster Height", - set_dest_raster_height, - pca_raster_graphics | pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - { - 'r', 'A', - PCL_COMMAND( "Start Raster Graphics", - start_graphics_mode, - pca_raster_graphics | pca_neg_ok | pca_big_clamp | pca_in_rtl - ) - }, - { - 'r', 'B', - PCL_COMMAND( "End Raster Graphics (Old)", - end_graphics_mode_B, - pca_raster_graphics | pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - { - 'r', 'C', - PCL_COMMAND( "End Raster Graphics (New)", - end_graphics_mode_C, - pca_raster_graphics | pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - END_CLASS - return 0; -} - - private void -gmode_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_printer - | pcl_reset_overlay ); - - if ((type & mask) != 0) { - pcl_raster_state_t * prstate = &(pcs->raster_state); - - prstate->gmargin_cp = 0L; - prstate->resolution = 75; - prstate->pres_mode_3 = true; - prstate->scale_raster = false; - prstate->src_width_set = false; - prstate->src_height_set = false; - prstate->dest_width_set = false; - prstate->dest_height_set = false; - prstate->scale_algorithm = 0; - prstate->graphics_mode = false; - prstate->compression_mode = NO_COMPRESS; - prstate->y_advance = 1; - } -} - -const pcl_init_t rtgmode_init = { gmode_do_registration, gmode_do_reset, 0 }; diff --git a/pcl/rtgmode.h b/pcl/rtgmode.h deleted file mode 100644 index 8a7621215..000000000 --- a/pcl/rtgmode.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtgmode.h - interface to PCL graphics (raster) mode */ - -#ifndef rtgmode_INCLUDED -#define rtgmode_INCLUDED - -#include "rtrstst.h" -#include "pcstate.h" -#include "pcommand.h" - -/* - * Types of entry into graphics mode. Note that implicit entry is distinct - * from any of the explicit modes. - */ -typedef enum { - NO_SCALE_LEFT_MARG = 0, - NO_SCALE_CUR_PT = 1, - SCALE_LEFT_MARG = 2, - SCALE_CUR_PTR = 3, - IMPLICIT = 100 -} pcl_gmode_entry_t; - - -/* enter raster graphics mode */ -int pcl_enter_graphics_mode(P2( - pcl_state_t * pcs, - pcl_gmode_entry_t mode -)); - -/* exit raster graphics mode */ -int pcl_end_graphics_mode(P1(pcl_state_t * pcs)); - -extern const pcl_init_t rtgmode_init; -extern const pcl_init_t rtlrastr_init; - -#endif /* rtgmode_INCLUDED */ diff --git a/pcl/rtmisc.c b/pcl/rtmisc.c deleted file mode 100644 index e5ea322dd..000000000 --- a/pcl/rtmisc.c +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtmisc.c - Miscellanous HP RTL commands */ -/* the order of these includes are jumbled because of dependencies */ -#include "math_.h" -#include "pgmand.h" -#include "pgdraw.h" /* for hpgl_add_pcl_point_to_path() */ -#include "pgmisc.h" /* for hpgl_call */ -#include "gsmemory.h" -#include "gsrop.h" -#include "gscoord.h" -#include "pcpatxfm.h" -#include "pcpage.h" -#include "pcdraw.h" - -/* ---------------- Chapter 4 ---------------- */ - -/* Import the table of pointers to initialization data. */ -extern const pcl_init_t * pcl_init_table[]; - -/* ---------------- Chapter 18 ---------------- */ - -/* - * ESC % <enum> B - */ - private int -rtl_enter_hpgl_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int i = int_arg(pargs); - - /* Note: -1..3 for PCL5c, 0..1 for PCL5 */ - if (i < 0) - i = -1; - else if (i > 3) - return 0; - hpgl_call(hpgl_clear_current_path(pcs)); - pcs->parse_other = ( int (*)( void *, - pcl_state_t *, - stream_cursor_read * - ) ) hpgl_process; - - /* add the pcl cap to hpgl/2's path */ - if (i == 1) { - gs_point pcl_pt; - - pcl_pt.x = (hpgl_real_t)pcs->cap.x; - pcl_pt.y = (hpgl_real_t)pcs->cap.y; - hpgl_add_pcl_point_to_path(pcs, &pcl_pt); - hpgl_update_carriage_return_pos(pcs); - } - return 0; -} - -/* - * We export this so we can call it from HP-GL/2 configurations. - * Note that it returns 1 iff it changed the PCL CAP. - * - * ESC % <enum> A - */ - int -rtl_enter_pcl_mode( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int b = int_arg(pargs) & 1; - - if ( pcs->parse_other == - (int(*)(void *, pcl_state_t *, stream_cursor_read *))hpgl_process ) { - /* - * We were in HP-GL/2 mode. Destroy the gl/2 polygon path - * and conditionally copy back the cursor position. - */ - if (b != 0) { - /* the usual user -> device -> user dance. */ - gs_point pt, dev_pt; - - hpgl_call(hpgl_set_ctm(pcs)); - hpgl_call(hpgl_get_current_position(pcs, &pt)); - hpgl_call(gs_transform(pcs->pgs, pt.x, pt.y, &dev_pt)); - hpgl_call(pcl_set_ctm(pcs, true)); - hpgl_call(gs_itransform(pcs->pgs, dev_pt.x, dev_pt.y, &pt)); - - /* HPGL/2 uses floats for coordinates */ -#define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) - pcs->cap.x = round(pt.x); - pcs->cap.y = round(pt.y); -#undef round - } - } else - b = 0; - - pcs->parse_other = 0; - return b; /* not 0, see comment above */ -} - -/* ---------------- Comparison Guide ---------------- */ - -/* (From PCL5 Comparison Guide, p. 1-30 & 1-92) */ - -/* - * ESC & b <count> W - */ - private int -pcl_appletalk_configuration( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - const byte * data = arg_data(pargs); - uint count = uint_arg(pargs); - uint i; - - if ((count < 2) || (data[0] == ' ')) - return e_Range; - - /* split the string at the first space */ - for (i = 1; data[i] != ' '; ++i) { - if (i == count - 1) - return e_Range; - } - if (pcs->configure_appletalk == 0) - return 0; - return (*pcs->configure_appletalk)(data, i, data + i + 1, count - (i + 1)); -} - -/* (From PCL5 Comparison Guide, p. 1-100) */ - -/* - * ESC & a <bool> N - */ - private int -pcl_negative_motion( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - int motion = int_arg(pargs); - - if (motion > 1) - return e_Range; - - /* Currently we can't take any advantage of this.... */ - return 0; -} - -/* ---------------- Initialization ---------------- */ - private int -rtmisc_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * mem -) -{ - /* Register commands */ - /* Chapter 4 */ - DEFINE_CLASS('%') - /* Chapter 18 */ - { - 0, 'B', - PCL_COMMAND( "Enter HP-GL/2 Mode", - rtl_enter_hpgl_mode, - pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - { - 0, 'A', - PCL_COMMAND( "Enter PCL Mode", - rtl_enter_pcl_mode, - pca_neg_ok | pca_big_ok | pca_in_rtl - ) - }, - END_CLASS - - /* Comparison Guide */ - DEFINE_CLASS('&') - { - 'b', 'W', - PCL_COMMAND( "Appletalk Configuration", - pcl_appletalk_configuration, - pca_bytes - ) - }, - { - 'a', 'N', - PCL_COMMAND( "Negative Motion", - pcl_negative_motion, - pca_neg_error | pca_big_error - ) - }, - END_CLASS - - return 0; -} - -/* - * The default for printer name should be set by the output device, but - * we will ignore that for now. - * - * Note that printer and device names are NOT reset by a pcl_reset_printer - * (ESC E); if they were, AppleTalk network communication would be in - * serious trouble. In fact, these parameters are normally stored in NVRAM, - * so they should not even be reset for pcl_reset_initial. Hence, we have - * consigned them to the currently unused pcl_reset_cold category - * - * The value of the device type field is as specified by the PCL 5 Comparison - * Guide (October, 1996 ed.), but it is not clear this is the correct value - * for a color device. This field is generally used to select a driver on - * the host system, and it is not clear an "HP LaserJet 4" device will - * generate color output (this may vary from host to host). - */ - private void -rtmisc_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - static const uint mask = ( pcl_reset_initial - | pcl_reset_cold - | pcl_reset_printer ); - - if (pcs->configure_appletalk == 0) - return; - - if ((type & mask) != 0) - pcs->configure_appletalk("JOB", 3, "", 0); - if ((type & pcl_reset_cold) != 0) { - static const byte prntr_name[] = "HP Color LaserJet 5M"; - static const byte dev_type[] = "HP LaserJet 4"; - - pcs->configure_appletalk( "RENAME", - 6, - prntr_name, - sizeof(prntr_name) - 1 - ); - pcs->configure_appletalk("TYPE", 4, dev_type, sizeof(dev_type) - 1); - } -} - -const pcl_init_t rtmisc_init = { rtmisc_do_registration, rtmisc_do_reset, 0 }; diff --git a/pcl/rtraster.c b/pcl/rtraster.c deleted file mode 100644 index baddc2472..000000000 --- a/pcl/rtraster.c +++ /dev/null @@ -1,1385 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtraster.c - raster transfer commands */ - -#include "memory_.h" -#include "gx.h" -#include "gsmatrix.h" -#include "gscoord.h" -#include "gspath.h" -#include "gspath2.h" -#include "gsimage.h" -#include "gsiparam.h" -#include "gsiparm4.h" -#include "gsdevice.h" -#include "gsrop.h" -#include "pcstate.h" -#include "pcpalet.h" -#include "pcpage.h" -#include "pcindxed.h" -#include "pcwhtidx.h" -#include "pcdraw.h" -#include "rtgmode.h" -#include "rtrstcmp.h" -#include "rtraster.h" - -/* - * The maximum number of planes for which seed rows need to be kept. This is the - * larger of the maximum number of bits per index (for pixel encoding mode 0 - - * indexed by plane) or maximum of the sum over the primaries of the number of - * bits per primary for pixel encoding mode 2 (direct by plane). For all - * current PCL printers, the effective bound is the the former, and is 8. - */ -#define MAX_PLANES 8 - -/* - * Structure to describe a PCL raster - */ -typedef struct pcl_raster_s { - - /* memory used to allocate this structure */ - gs_memory_t * pmem; - - byte nplanes; /* # of planes (seed rows) */ - byte bits_per_plane; /* bits per plane */ - byte nsrcs; /* # of data sources, 1 or 3 */ - - uint transparent:1; /* 1 ==> source transparency */ - uint src_height_set:1; /* source height was set */ - uint indexed:1; /* != 0 ==> indexed color space */ - uint zero_is_white:1; /* all planes 0 ==> white */ - uint zero_is_black:1; /* all planes 0 ==> solid color */ - - int wht_indx; /* white index, for indexed color - space only */ - const void * remap_ary; /* remap array, if needed */ - - pcl_state_t * pcs; /* to avoid n extra operand */ - pcl_cs_indexed_t * pindexed; /* color space */ - - gs_image_enum * pen; /* image enumerator */ - uint16 plane_index; /* next plane to be received */ - uint16 rows_rendered; /* # of source rows rendered */ - uint16 src_width; /* usable raster width */ - uint16 src_height; /* remaining usable raster height */ - - /* objects required for opaque source/transparent pattern case */ - gs_image_enum * mask_pen; /* enumerator for mask */ - pcl_cs_indexed_t * mask_pindexed; /* special color space for mask */ - ulong white_val; /* value interpreted as white */ - void (*gen_mask_row)( struct pcl_raster_s * prast ); - - /* buffers */ - pcl_seed_row_t * pseed_rows; /* seed rows, one per plane */ - byte * cons_buff; /* consolidation buffer */ - byte * mask_buff; /* buffer for mask row, if needed */ - -} pcl_raster_t; - -/* GC routines */ -private_st_seed_row_t(); -private_st_seed_row_t_element(); - -gs_private_st_ptrs2( st_raster_t, - pcl_raster_t, - "PCL raster object", - raster_enum_ptrs, - raster_reloc_ptrs, - pseed_rows, - cons_buff - ); - -/* forward declaration */ -private int process_zero_rows( pcl_raster_t * prast, int nrows ); - - -/* - * Clear the consolidation buffer, allocating it if it does not already - * exist. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -clear_cons_buff( - pcl_raster_t * prast -) -{ - byte * pcons = prast->cons_buff; - int npixels = prast->src_width; - - if (pcons == 0) { - pcons = gs_alloc_bytes( prast->pmem, - npixels, - "PCL raster consolidation buff" - ); - if (pcons == 0) - return e_Memory; - prast->cons_buff = pcons; - } - memset(pcons, 0, npixels); - - return 0; -} - -/* - * Clear the mask buffer, allocating it if it does not exist. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -clear_mask_buff( - pcl_raster_t * prast -) -{ - byte * pmask = prast->mask_buff; - int nbytes = (prast->src_width + 7) / 8; - - if (pmask == 0) { - pmask = gs_alloc_bytes( prast->pmem, - nbytes, - "PCL raster mask buffer" - ); - if (pmask == 0) - return e_Memory; - prast->mask_buff = pmask; - } - memset(pmask, 0, nbytes); - - return 0; - -} - -/* - * Generate a mask row in case there are multiple data sources (in the graphic - * library sense). This code takes much advantage of the knowledge that the - * mutliple source case is always direct and one bit per pixel. - */ - private void -gen_mask_multisrc( - pcl_raster_t * prast -) -{ - byte * ip0 = prast->pseed_rows[0].pdata; - byte * ip1 = prast->pseed_rows[1].pdata; - byte * ip2 = prast->pseed_rows[2].pdata; - byte * op = prast->mask_buff; - uint m0 = (prast->white_val >> 16) & 0xff; - uint m1 = (prast->white_val >> 8) & 0xff; - uint m2 = prast->white_val & 0xff; - int nbytes = prast->pseed_rows[0].size; - int i; - - for (i = 0; i < nbytes; i++) - *op++ = (*ip0++ ^ m0) & (*ip1++ ^ m1) & (*ip2++ ^ m2); -} - -/* - * Generate a mask from input data that is less than one byte. For PCL rasters - * as implemented by this routine, such situations only occur when an integral - * number of pixels fit within one byte, and this routine takes advantage of - * that situation. - */ - private void -gen_mask_subbyte( - pcl_raster_t * prast -) -{ - byte * ip = prast->pseed_rows[0].pdata; - byte * op = prast->mask_buff; - int ishift = prast->bits_per_plane; - uint targ = prast->white_val; - int size = prast->src_width; - uint ival, oval, imask, omask; - int i; - - for (i = 0, ival = 0, oval = 0, imask = 0, omask = 0x80; i < size; i++) { - if ((imask >>= ishift) == 0) { - imask = 0xff - (0xff >> ishift); - ival = *ip++; - } - if (((ival ^ targ) & imask) == 0) - oval |= omask; - if ((omask >>= 1) == 0) { - *op++ = oval; - omask = 0x80; - oval = 0; - } - } - if (omask != 0x80) - *op++ = oval; -} - -/* - * Generate a mask from input data that has one byte per pixel. - */ - private void -gen_mask_1byte( - pcl_raster_t * prast -) -{ - byte * ip = (prast->nplanes == 1 ? prast->pseed_rows[0].pdata - : prast->cons_buff); - byte * op = prast->mask_buff; - uint targ = prast->white_val; - int size = prast->src_width; - uint oval, omask; - int i; - - for (i = 0, oval = 0, omask = 0x80; i < size; i++) { - if (*ip++ == targ) - oval |= omask; - if ((omask >>= 1) == 0) { - *op++ = oval; - omask = 0x80; - oval = 0; - } - } - if (omask != 0x80) - *op++ = oval; -} - -/* - * Generate a mask row in the case that more than one byte is required per - * pixel. The only possible such case in PCL is 8-bits per primary 3 color, - * so this routine handles only that case. - */ - void -gen_mask_multibyte( - pcl_raster_t * prast -) -{ - byte * ip = prast->pseed_rows[0].pdata; - byte * op = prast->mask_buff; - int size = prast->src_width; - ulong targ = prast->white_val; - uint oval, omask; - int i; - - for (i = 0, oval = 0, omask = 0x80; i < size; i++, ip += 3) { - ulong ival = (((ulong)ip[0]) << 16) | (((ulong)ip[1]) << 8) | ip[2]; - - if (ival == targ) - oval |= omask; - if ((omask >>= 1) == 0) { - *op++ = oval; - omask = 0x80; - oval = 0; - } - } - if (omask != 0x80) - *op++ = oval; -} - -/* - * Consolidate a set of seed rows into the consolidated row buffer. - * - * This routine will only be called if: - * - * prast->nplanes > 1 - * prast->bits_per_plane = 1 - * prast->nsrcs = 1 - * - * The output is always packed 8 bits per pixel, even if ferwer are required. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -consolidate_row( - pcl_raster_t * prast -) -{ - byte * pcons; - uint nplanes = prast->nplanes; - uint npixels = prast->src_width; - int code, i; - - /* clear the consolidation buffer */ - if ((code = clear_cons_buff(prast)) < 0) - return code; - pcons = prast->cons_buff; - - /* for each plane, "or" in the appropriate bit */ - for (i = 0; i < nplanes; i++) { - if (!prast->pseed_rows[i].is_blank) { - const byte * ip = prast->pseed_rows[i].pdata; - byte * op = pcons; - int cnt = npixels; - - for (; cnt >= 8; ip++, op += 8, cnt -= 8) { - uint val = *ip; - - /* - * cons_buff was allocated with gs_alloc_bytes, so we know - * it is aligned for (at least) bits32 access. - */ -#if ARCH_IS_BIG_ENDIAN - static const bits32 spread[16] = { - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 - }; -#else - static const bits32 spread[16] = { - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101 - }; -#endif - ((bits32 *)op)[0] |= spread[val >> 4] << i; - ((bits32 *)op)[1] |= spread[val & 0xf] << i; - } - if (cnt) { - uint ishift = 7; - uint val = *ip; - - do { - *op++ |= ((val >> ishift--) & 0x1) << i; - } while (--cnt > 0); - } - } - } - - return 0; -} - -/* - * Create an enumerator for the mask portion of an image (if required). - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -create_mask_enumerator( - pcl_raster_t * prast -) -{ - gs_image4_t image; - gs_image_enum * pen = gs_image_enum_alloc( prast->pmem, - "Create image for PCL raster" ); - int code = 0; - const byte * pcolor = 0; - gx_image_enum_common_t * pie = 0; - pcl_state_t * pcs = prast->pcs; - - if (pen == 0) - return e_Memory; - - pcl_set_drawing_color(pcs, pcl_pattern_solid_white, 0, true); - - /* generate the special two entry indexed color space required */ - if (prast->indexed) - pcolor = prast->pindexed->palette.data + 3 * prast->wht_indx; - else { - static const byte cwhite[3] = { 1.0, 1.0, 1.0 }; - - pcolor = cwhite; - } - code = pcl_cs_indexed_build_special( &(prast->mask_pindexed), - prast->pindexed->pbase, - pcolor, - prast->pmem - ); - - if (code >= 0) { - gs_image4_t_init(&image, prast->mask_pindexed->pcspace); - image.Width = prast->src_width; - image.Height = prast->src_height; -#ifdef PCL5EMONO - image.CombineWithColor = false; -#else - image.CombineWithColor = true; -#endif - image.format = gs_image_format_chunky; - image.BitsPerComponent = 1; - image.Decode[0] = 0.0; - image.Decode[1] = 1.0; - image.MaskColor[0] = 0.0; - - code = gs_image_begin_typed( (const gs_image_common_t *)&image, - pcs->pgs, - true, - &pie - ); - - if (code >= 0) - code = gs_image_common_init( pen, - pie, - (gs_data_image_t *)&image, - prast->pmem, - gs_currentdevice_inline(pcs->pgs) - ); - } - - if (code < 0) - gs_free_object(prast->pmem, pen, "Create image for PCL raster"); - else - prast->mask_pen = pen; - - pcl_set_drawing_color(pcs, pcs->pattern_type, pcs->pattern_id, true); - return code; -} - -/* - * Create the graphic library image object needed to represent a raster. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -create_image_enumerator( - pcl_raster_t * prast -) -{ - int nplanes = prast->nplanes; - int b_per_p = prast->bits_per_plane; - int num_comps = (prast->indexed ? 1 : 3); - int nsrcs = prast->nsrcs; - gs_image4_t image; - gs_image_enum * pen = gs_image_enum_alloc( prast->pmem, - "Create image for PCL raster" ); - gx_image_enum_common_t * pie = 0; - gs_color_space * pcspace = ( prast->indexed - ? prast->pindexed->pcspace - : prast->pindexed->pbase->pcspace ); - int code = 0; - - if (pen == 0) - return e_Memory; - - gs_image4_t_init(&image, pcspace); - image.Width = prast->src_width; - image.Height = prast->src_height; - image.CombineWithColor = true; - image.format = ( nsrcs > 1 ? gs_image_format_component_planar - : gs_image_format_chunky ); - - if (nplanes > nsrcs) - image.BitsPerComponent = 8; /* always 8 bits per pixel if consolidated */ - else - image.BitsPerComponent = (nplanes * b_per_p) / num_comps; - - if (prast->indexed) { - - /* avoid unnecessary transparency mask in the by-plane case */ - if (prast->wht_indx >= 1 << (nplanes * b_per_p)) - image.MaskColor[0] = (1 << image.BitsPerComponent); - else - image.MaskColor[0] = prast->wht_indx; - image.Decode[0] = 0.0; - image.Decode[1] = (1 << image.BitsPerComponent) - 1; - } else { - int i; - - for (i = 0; i < num_comps; i++) { - image.Decode[2 * i] = prast->pindexed->Decode[2 * i]; - image.Decode[2 * i + 1] = prast->pindexed->Decode[2 * i + 1]; - - image.MaskColor[i] = (1 << image.BitsPerComponent); - if (prast->transparent) { - if (image.Decode[2 * i] == 1.0) - image.MaskColor[i] = 0; - else if (image.Decode[2 * i + 1] == 1.0) - image.MaskColor[i] = (1 << image.BitsPerComponent) - 1; - } - } - } - - code = gs_image_begin_typed( (const gs_image_common_t *)&image, - prast->pcs->pgs, - true, - &pie - ); - if (code >= 0) - code = gs_image_common_init( pen, - pie, - (gs_data_image_t *)&image, - prast->pmem, - gs_currentdevice_inline(prast->pcs->pgs) - ); - if (code < 0) { - gs_free_object(prast->pmem, pen, "Create image for PCL raster"); - return code; - } - prast->pen = pen; - return 0; -} - -/* - * Close the image being used to represent a raster. If the second argument is - * true, complete the raster as well. - * - * This routine does NOT clear the seed rows, as their content may be needed - * for the next row of the raster. - * - * NB: This routine may re-invoke itself recursively when completing the raster, - * as this routine will call process_zero_rows, which may once again invoke - * this routine. The recursion can only extend to one additional level, - * however, as process_zero_rows will call this routine with complete set - * set to false. - */ - private void -close_raster( - pcl_raster_t * prast, - bool complete -) -{ - /* see if we need to fill in any missing rows */ - if ( complete && - (prast->src_height > prast->rows_rendered) && - prast->src_height_set ) - (void)process_zero_rows(prast, prast->src_height - prast->rows_rendered); - if (prast->pen != 0) { - gs_image_cleanup(prast->pen); - gs_free_object(prast->pmem, prast->pen, "Close PCL raster"); - prast->pen = 0; - } - if (prast->mask_pen != 0) { - gs_image_cleanup(prast->mask_pen); - gs_free_object(prast->pmem, prast->mask_pen, "Close PCL raster"); - prast->mask_pen = 0; - } - gs_translate(prast->pcs->pgs, 0.0, (floatp)(prast->rows_rendered)); - prast->src_height -= prast->rows_rendered; - prast->rows_rendered = 0; -} - - -/* - * Generate the white-mask corresponding to an image scanline. This is - * necessary to implement the opaque source/transparent texture case. - * - * HP's specification of transparency includes one unintuitive case: opaque - * source and transparent texture. In this case, the texture applies only to - * the non-white portion of the source; the white portion should be rendered - * in a solid white. - * - * Since the graphic library does not support mutliple textures in a single - * rendering operation, it is necessary to split objects that have both a - * foreground and a background into two transparent objects: one having just - * the foreground, the other just the background. In the case of rasters it - * is necessary to form a mask object that is the inverse of the background, - * and "paint" it with "white". The following code accomplishes this task. - * - * It is, unfortunately, not possible to use the graphic libraries image mask - * feature to implement the "white mask", because image masks in the graphic - * library are not implemented as mask objects. Rather, they are implemented - * as transparent colored patterns, with the foreground color taken from the - * current color at the time the image mask is begun. Instead, a two entry - * transparent colored image is used, whose foreground color is the current - * white and whose background color is a transparent white. - * - * As always, what is considered "white" is evaluated in the source color space; - * this varies from HP's practice, and can give unexpected results if an - * inverting color lookup table is used. - */ - private int -process_mask_row( - pcl_raster_t * prast -) -{ - int code = clear_mask_buff(prast); - gs_image_enum * pen = prast->mask_pen; - - if ( (code >= 0) && - ((pen != 0) || ((code = create_mask_enumerator(prast)) >= 0)) ) { - uint dummy; - pcl_state_t * pcs = prast->pcs; - - pen = prast->mask_pen; - pcl_set_drawing_color(pcs, pcl_pattern_solid_white, 0, true); - prast->gen_mask_row(prast); - code = gs_image_next( pen, - prast->mask_buff, - (prast->src_width + 7) / 8, - &dummy - ); - pcl_set_drawing_color(pcs, pcs->pattern_type, pcs->pattern_id, true); - } - return code; -} - - private int -process_zero_mask_rows( - pcl_raster_t * prast, - int nrows -) -{ - int code = clear_mask_buff(prast); - gs_image_enum * pen = prast->mask_pen; - - if ( (code >= 0) && - ((pen != 0) || ((code = create_mask_enumerator(prast)) >= 0)) ) { - uint dummy; - pcl_state_t * pcs = prast->pcs; - int nbytes = (prast->src_width + 7) / 8; - - pen = prast->mask_pen; - memset(prast->mask_buff, 0xff, nbytes); - pcl_set_drawing_color(pcs, pcl_pattern_solid_white, 0, true); - gs_setrasterop(pcs->pgs, (gs_rop3_t)rop3_know_S_1((int)0xff)); - while ((nrows-- > 0) && (code >= 0)) - code = gs_image_next(pen, prast->mask_buff, nbytes, &dummy); - pcl_set_drawing_color(pcs, pcs->pattern_type, pcs->pattern_id, true); - } - return code; -} - -/* - * Process some number of zero-ed out rows, either as rasters or as a rectangle. - * - * Ideally, any sufficiently large regions of zero value would be rendered as - * a rectangle, but doing so runs afoul of PCL's graphic model. Rectangles are - * mask objects, whose value is provided by the current color/pattern/texture. - * Images are colored objects, whose interaction with the the current color/ - * texture/raster is established by the current raster operation. - * - * In many cases, it is possible to emulate the effect of a colored object by - * use of a mask object and modifications to the current pattern/color/texture - * and the current raster operation. For the most part, however, situations in - * which such modifications are useful do not occur often enough to be worth - * special handling. - * - * There is one case that does arise with some frequency and is simple to - * handle: 0 is white, and source transparency is on. In this case, no work - * is necessary: just leave the output as is. - * - * The other case that is likely to arise often enough to be worth special - * handling is when 0 is white but source transparency is off. In this case, - * the current raster operation must be inverted relative to the source - * component and a solid rectangle output. A similar situation with a black - * rectangle does not occur very frequently, but can be handled by the same - * technique (without inverting the raster operation), so it is handled here - * as well. - * - * Zero regions of less than a kilo byte are not given special handling, so - * as to avoid the overhead of closing and then restarting an image. - * - * Returns 0 on success, < 0 in the event of an error. - */ - private int -process_zero_rows( - pcl_raster_t * prast, - int nrows -) -{ - int npixels = prast->src_width; - int nbytes = (npixels * prast->bits_per_plane + 7) / 8; - int nplanes = prast->nplanes; - int rem_rows = prast->src_height - prast->rows_rendered; - pcl_seed_row_t * pseed_rows = prast->pseed_rows; - int code = 0; - int i; - - /* don't bother going beyond the end of the image */ - if (nrows > rem_rows) - nrows = rem_rows; - - /* if clipping the whole raster, just update rendered rows */ - if (prast->pcs->raster_state.clip_all) { - prast->rows_rendered += nrows; - return 0; - } - - /* clear the seed rows */ - for (i = 0; i < nplanes; i++) { - if (!pseed_rows[i].is_blank) { - memset(prast->pseed_rows[i].pdata, 0, nbytes); - pseed_rows[i].is_blank = true; - } - } - - /* render as raster or rectangle */ - if ( ((nrows * nbytes > 1024) || (prast->pen == 0)) && - (prast->zero_is_white || prast->zero_is_black) ) { - gs_state * pgs = prast->pcs->pgs; - - close_raster(prast, false); - if ((prast->zero_is_black) || !prast->transparent) { - gs_rect tmp_rect; - bool invert = prast->zero_is_white; - - tmp_rect.p.x = 0.0; - tmp_rect.p.y = 0.0; - tmp_rect.q.x = (double)npixels; - tmp_rect.q.y = (double)nrows; - if (invert) - gs_setrasterop( pgs, - (gs_rop3_t)rop3_invert_S(gs_currentrasterop(pgs)) - ); - gs_rectfill(pgs, &tmp_rect, 1); - if (invert) - gs_setrasterop( pgs, - (gs_rop3_t)rop3_invert_S(gs_currentrasterop(pgs)) - ); - - } - - prast->src_height -= nrows; - gs_translate(pgs, 0.0, (floatp)nrows); - - return 0; - - } else { - int nsrcs = prast->nsrcs; - gs_image_enum * pen = prast->pen; - int cnt = 0; - uint size = 0; - const byte * pb; - - if (pen == 0) { - if ((code = create_image_enumerator(prast)) < 0) - return code; - pen = prast->pen; - } - - if (nplanes > nsrcs) { - if ((code = clear_cons_buff(prast)) < 0) - return code; - cnt = nrows; - size = npixels; - pb = prast->cons_buff; - } else { - cnt = nrows * nsrcs; - size = nbytes; - pb = prast->pseed_rows[0].pdata; - } - - for (i = 0; i < cnt; i++) { - uint dummy; - - if ((code = gs_image_next(pen, pb, size, &dummy)) < 0) - return code; - } - prast->rows_rendered += nrows; - - if (prast->gen_mask_row != 0) - code = process_zero_mask_rows(prast, nrows); - - return code; - } -} - -/* - * Process the next raster row. - * - * The compression mode is provided to allow this routine to fill in any - * missing rows. For adaptive compression (mode 5), this will be 0. - */ - private int -process_row( - pcl_raster_t * prast, - int comp_mode /* modified compression mode */ -) -{ - int nplanes = prast->nplanes; - gs_image_enum * pen = prast->pen; - int i; - int code = 0; - - /* check if there is anything to do */ - if (prast->rows_rendered >= prast->src_height) - return 0; - else if (prast->pcs->raster_state.clip_all) { - prast->rows_rendered++; - return 0; - } - - /* handle any planes not provided */ - for (i = prast->plane_index; i < nplanes; i++) { - static const byte dummy = 0; - - (void)pcl_decomp_proc[comp_mode](prast->pseed_rows + i, &dummy, 0); - } - - /* create the image enumerator if it does not already exist */ - if (pen == 0) { - if ((code = create_image_enumerator(prast)) < 0) - return code; - pen = prast->pen; - } - - /* update the raster parameters */ - prast->rows_rendered++; - prast->plane_index = 0; - - if (prast->nsrcs == 1) { - byte * pb; - int nbytes, b_per_p; - uint dummy; - - /* consolidate the planes if necessary */ - if (nplanes > prast->nsrcs) { - if ((code = consolidate_row(prast)) < 0) - return code; - pb = prast->cons_buff; - b_per_p = 8; - nbytes = prast->src_width; - } else { - pb = prast->pseed_rows[0].pdata; - nbytes = prast->pseed_rows[0].size; - b_per_p = prast->bits_per_plane; - } - - /* - * Remap the planes, if this is required. - * - * Remapping is only required for indexed color spaces. The indexed - * by plane case will have been collapsed to an indexed by pixel case - * by this point. - * - * (The macro pcl_cmap_apply_remap_ary checks for - * prast->remap_ary == 0.) - */ - pcl_cmap_apply_remap_ary( prast->remap_ary, - pb, - b_per_p, - prast->src_width - ); - - code = gs_image_next(pen, pb, nbytes, &dummy); - - } else { - uint dummy; - int nsrcs = prast->nsrcs; - - for (i = 0; (i < nsrcs) && (code >= 0); i++) - code = gs_image_next( pen, - prast->pseed_rows[i].pdata, - prast->pseed_rows[i].size, - &dummy - ); - } - - if ((prast->gen_mask_row != 0) && (code >= 0)) - code = process_mask_row(prast); - return code; -} - -/* - * Process an input data buffer using adpative compression. - */ - private int -process_adaptive_compress( - pcl_raster_t * prast, - const byte * pin, - uint insize -) -{ - pcl_seed_row_t * pseed_row = prast->pseed_rows; - byte * pdata = pseed_row->pdata; - uint row_size = pseed_row->size; - int code = 0; - - prast->plane_index = 0; - while ((insize >= 3) && (code >= 0)) { - int cmd = *pin++; - uint param = *pin++; - - param = (param << 8) + *pin++; - insize -= 3; - if (cmd <= 3) { - uint cnt = min(insize, param); - - pcl_decomp_proc[cmd](pseed_row, pin, cnt); - insize -= cnt; - pin += cnt; - prast->plane_index = 1; - code = process_row(prast, 0); - } else if (cmd == 4) - code = process_zero_rows(prast, param); - else if (cmd == 5) { - uint rem_rows = prast->src_height - prast->rows_rendered; - gs_image_enum * pen = prast->pen; - - if (param > rem_rows) - param = rem_rows; - - /* if clipping the raster, just update lines rendered */ - if (prast->pcs->raster_state.clip_all) { - prast->rows_rendered += param; - continue; - } - - /* create the image enumerator if it does not already exist */ - if (pen == 0) { - if ((code = create_image_enumerator(prast)) < 0) - return code; - pen = prast->pen; - } - - if (prast->nplanes == 1) { - prast->rows_rendered += param; - while ((param-- > 0) && (code >= 0)) { - uint dummy; - - code = gs_image_next(pen, pdata, row_size, &dummy); - if ((prast->gen_mask_row != 0) && (code >= 0)) - code = process_mask_row(prast); - } - } else { - prast->plane_index = 1; - while ( (param-- > 0) && ((code = process_row(prast, 0) >= 0)) ) - prast->plane_index = 1; - prast->plane_index = 0; - } - } else - break; - } - - return code; -} - -/* - * Add a raster plane. The second operand indicates whether or not this is the - * final plane of a row. - */ - private int -add_raster_plane( - const byte * pdata, - uint nbytes, - bool end_row, - pcl_state_t * pcs -) -{ - pcl_raster_t * prast = (pcl_raster_t *)pcs->raster_state.pcur_raster; - int comp_mode = pcs->raster_state.compression_mode; - int nplanes = 0; - int plane_index = 0; - int code = 0; - - /* enter raster mode implicitly if not already there */ - if (prast == 0) { - if ((code = pcl_enter_graphics_mode(pcs, IMPLICIT)) < 0) - return code; - prast = (pcl_raster_t *)pcs->raster_state.pcur_raster; - } - - /* - * Adaptive compression (mode 5) is only available for single-plane - * encodings, and then only if used with a transfer row (ESC * b # W) - * command. The latter behavior matches that of the HP Color LaserJet 5/5M, - * but not that of the DeskJet 1600C/CM, which has somewhat erratic - * behavior in this case. - */ - nplanes = prast->nplanes; - if ((comp_mode == ADAPTIVE_COMPRESS) && !end_row) - return e_Range; - - /* - * If all the rows that can be output have already been rendered, just - * return. - */ - if (prast->rows_rendered >= prast->src_height) - return 0; - - /* - * If all planes for this row have been entered, just ignore the current - * data (but don't return yet, as we may still need to output the current - * raster row). - */ - plane_index = prast->plane_index; - if (plane_index < nplanes) { - pcl_seed_row_t * pseed = prast->pseed_rows + plane_index; - - prast->plane_index++; - if (comp_mode == ADAPTIVE_COMPRESS) - return process_adaptive_compress(prast, pdata, nbytes); - else - (void)pcl_decomp_proc[comp_mode](pseed, pdata, nbytes); - } - - return 0; -} - -/* - * Create a PCL raster object. This procedure is called when entering graphics - * mode. - * - * Note that a raster must be considered "transparent" if either source or - * pattern transparency is in effect. If only pattern transparency is set, an - * addition mask object must be created to fill the "white" regions of the - * raster. This object does not use the current texture; it sets the texture - * to opaque white when it is rendered. This is in conformance with HP's - * somewhat unintuitive interpretation of the opaque source/transparent - * pattern situation. - * - * Returns 0 on success, < 0 in the event of an error. - */ - int -pcl_start_raster( - uint src_width, - uint src_height, - bool region_marked, - pcl_state_t * pcs -) -{ - pcl_raster_t * prast = (pcl_raster_t *)pcs->raster_state.pcur_raster; - pcl_palette_t * ppalet = pcs->ppalet; - pcl_cs_indexed_t * pindexed = ppalet->pindexed; - pcl_encoding_type_t penc = pcl_cs_indexed_get_encoding(pindexed); - pcl_seed_row_t * pseed_rows = 0; - - /* there can only be one raster object present at a time */ - if (prast != 0) - pcl_complete_raster(pcs); - - prast = gs_alloc_struct( pcs->memory, - pcl_raster_t, - &st_raster_t, - "start PCL raster" - ); - if (prast == 0) - return e_Memory; - - prast->pmem = pcs->memory; - - prast->transparent = (pcs->source_transparent || pcs->pattern_transparent); - prast->src_height_set = pcs->raster_state.src_height_set; - prast->pcs = pcs; - pcl_cs_indexed_init_from(prast->pindexed, pindexed); - - prast->pen = 0; - prast->plane_index = 0; - prast->rows_rendered = 0; - prast->src_width = src_width; - prast->src_height = src_height; - prast->mask_pen = 0; - prast->mask_pindexed = 0; - prast->gen_mask_row = 0; - - /* the conslidation and mask buffers are created when first needed */ - prast->cons_buff = 0; - prast->mask_buff = 0; - - if (penc <= pcl_penc_indexed_by_pixel) { - int b_per_i = pcl_cs_indexed_get_bits_per_index(pindexed); - - if (penc == pcl_penc_indexed_by_plane) { - prast->nplanes = b_per_i; - prast->bits_per_plane = 1; - } else { /* penc == pcl_penc_indexed_by_pixel */ - prast->nplanes = 1; - prast->bits_per_plane = b_per_i; - } - prast->nsrcs = 1; - prast->indexed = true; - prast->zero_is_white = pcl_cs_indexed_0_is_white(pindexed); - prast->zero_is_black = pcl_cs_indexed_0_is_black(pindexed); - prast->remap_ary = pcl_cmap_create_remap_ary(pcs, &(prast->wht_indx)); - - } else { /* penc >= pcl_penc_direct_by_plane */ - int b_per_primary = pcl_cs_indexed_get_bits_per_primary(pindexed, 0); - - if (penc == pcl_penc_direct_by_plane) { - prast->nplanes = 3; - prast->bits_per_plane = b_per_primary; - prast->nsrcs = 3; - } else { /* penc == pcl_penc_direct_by_pixel */ - prast->nplanes = 1; - prast->bits_per_plane = 3 * b_per_primary; - prast->nsrcs = 1; - } - prast->indexed = false; - prast->zero_is_white = false; - prast->zero_is_black = true; - prast->wht_indx = 1; /* not significant */ - prast->remap_ary = 0; - } - - /* allocate the seed row buffers */ - pseed_rows = gs_alloc_struct_array( prast->pmem, - prast->nplanes, - pcl_seed_row_t, - &st_seed_row_t_element, - "start PCL raster" - ); - if (pseed_rows != 0) { - int seed_row_bytes = (prast->src_width * prast->bits_per_plane + 7) - / 8; - int nplanes = prast->nplanes; - int i, j; - - for (i = 0; i < nplanes; i++) { - byte * pdata = gs_alloc_bytes( prast->pmem, - seed_row_bytes, - "start PCL raster" - ); - - if (pdata == 0) - break; - pseed_rows[i].size = seed_row_bytes; - pseed_rows[i].pdata = pdata; - memset(pseed_rows[i].pdata, 0, seed_row_bytes); - pseed_rows[i].is_blank = true; - } - - /* check if everything was successful */ - if (i < nplanes) { - - /* memory exhaustion; release the already allocated seed rows */ - for (j = 0; j < i; j++) - gs_free_object( prast->pmem, - pseed_rows[i].pdata, - "start PCL raster" - ); - gs_free_object(prast->pmem, pseed_rows, "start PCL raster"); - pseed_rows = 0; - } - } - - /* check for memory exhaustion */ - if (pseed_rows == 0) { - gs_free_object(prast->pmem, prast, "start PCL raster"); - return e_Memory; - } - - prast->pseed_rows = pseed_rows; - pcs->raster_state.pcur_raster = (pcl_raster_type *)prast; - - /* a mask is never required if the region of interest is blank and - the interpreter is pcl5e or monochrome, this is actually worth - checking because many pcl files blindly set the expensive - source opaque/pattern transparent combination. */ - if ( pcs->personality == pcl5e && !region_marked ) - return 0; - - /* see if a mask is required */ - if ( !pcs->source_transparent && - pcs->pattern_transparent && - (!prast->indexed || - (prast->wht_indx - < (1 << prast->nplanes * prast->bits_per_plane)) ) ) { - - if (!prast->indexed) { - ulong white_val = 0UL; - - /* direct by plane or by pixel, one or 8 bits per primary */ - prast->gen_mask_row = (prast->nsrcs > 1 ? gen_mask_multisrc - : gen_mask_multibyte); - if (prast->pindexed->Decode[1] == 1.0) - white_val |= ((ulong)0xff) << 16; - if (prast->pindexed->Decode[3] == 1.0) - white_val |= ((ulong)0xff) << 8; - if (prast->pindexed->Decode[5] == 1.0) - white_val |= 0xff; - prast->white_val = white_val; - - } else if ((prast->nplanes > 1) || (prast->bits_per_plane == 8)){ - - /* indexed by plane or direct by pixel, 8 bits per pixel */ - prast->gen_mask_row = gen_mask_1byte; - prast->white_val = prast->wht_indx; - - } else { - ulong white_val = prast->wht_indx; - int n = 8 / prast->bits_per_plane; - - /* indexed by pixel, < 8 bits per pixel */ - prast->gen_mask_row = gen_mask_subbyte; - while (n-- > 0) - white_val |= (white_val << prast->bits_per_plane); - prast->white_val = white_val; - } - } - - return 0; -} - -/* - * Complete a raster. This is called when exiting graphics mode. - */ - void -pcl_complete_raster(pcl_state_t *pcs) -{ - pcl_raster_t * prast = (pcl_raster_t *)pcs->raster_state.pcur_raster; - int i; - - /* if already in raster mode, ignore */ - if (prast == 0) - return; - - /* close the current raster */ - close_raster(prast, true); - - /* free associated objects */ - if (prast->remap_ary != 0) { - gs_free_object( prast->pmem, - (void *)prast->remap_ary, - "Complete PCL raster" - ); - prast->remap_ary = 0; - } - - if (prast->pindexed != 0) { - pcl_cs_indexed_release(prast->pindexed); - prast->pindexed = 0; - } - if (prast->mask_pindexed != 0) { - pcl_cs_indexed_release(prast->mask_pindexed); - prast->mask_pindexed = 0; - } - - if (prast->pseed_rows != 0) { - for (i = 0; i < prast->nplanes; i++) { - if (prast->pseed_rows[i].pdata != 0) - gs_free_object( prast->pmem, - prast->pseed_rows[i].pdata, - "Complete PCL raster" - ); - } - gs_free_object(prast->pmem, prast->pseed_rows, "Complete PCL raster"); - prast->pseed_rows = 0; - } - - if (prast->cons_buff != 0) - gs_free_object(prast->pmem, prast->cons_buff, "Complete PCL raster"); - if (prast->mask_buff != 0) - gs_free_object(prast->pmem, prast->mask_buff, "Complete PCL raster"); - - - /* free the PCL raster robject itself */ - gs_free_object(prast->pmem, prast, "Complete PCL raster"); - pcs->raster_state.pcur_raster = 0; -} - -/* - * ESC * b # V - * - * Add a plane buffer to the current set. - */ - private int -transfer_raster_plane( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - return add_raster_plane(arg_data(pargs), arg_data_size(pargs), false, pcs); -} - -/* - * <esc> * b # W - * - * Add a plane buffer to the current buffered set, and complete the current - * raster row. - */ - private int -transfer_raster_row( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - const byte * pdata = arg_data(pargs); - int comp_mode = pcs->raster_state.compression_mode; - int code = 0; - - code = add_raster_plane(pdata, arg_data_size(pargs), true, pcs); - - /* complete the row (execpt for adaptive compression) */ - if (comp_mode != ADAPTIVE_COMPRESS && code >= 0) - code = process_row((pcl_raster_t *)pcs->raster_state.pcur_raster, comp_mode); - - return code; -} - -/* - * <esc> * b # Y - * - * Skip (zero-fill) a number of raster rows. This command is ignored outside - * of raster mode. - * - * Note that any incomplete plane data for the current row is discarded by this - * command. - */ - private int -raster_y_offset( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - pcl_raster_t * prast = (pcl_raster_t *)pcs->raster_state.pcur_raster; - - /* ignored outside of graphics mode */ - if ((prast != 0) && (uint_arg(pargs) > 0)) { - return process_zero_rows(prast, uint_arg(pargs)); - } else - return 0; -} - -/* - * ESC * b <direction> L - * - * set raster print direction - */ - private int -set_line_path( - pcl_args_t * pargs, - pcl_state_t * pcs -) -{ - uint i = uint_arg(pargs); - - if (i <= 1) - pcs->raster_state.y_advance = (i == 1 ? -1 : 1); - return 0; -} - -/* - * There is no specific copy code for this module, as both entry to and exit - * from a macro must end graphics mode (and thus are handled by the parser). - * There is also no explicit reset routine, as the required work is handled - * at a higher level. - */ - private int -raster_do_registration( - pcl_parser_state_t *pcl_parser_state, - gs_memory_t * pmem /* ignored */ -) -{ - DEFINE_CLASS('*') - { - 'b', 'V', - PCL_COMMAND( "Transfer Raster Plane", - transfer_raster_plane, - pca_raster_graphics | pca_bytes | pca_in_rtl - ) - }, - { - 'b', 'W', - PCL_COMMAND( "Transfer Raster Row", - transfer_raster_row, - pca_raster_graphics | pca_bytes | pca_in_rtl - ) - }, - { - 'b', 'Y', - PCL_COMMAND( "Raster Y Offset", - raster_y_offset, - pca_raster_graphics | pca_neg_ok | pca_big_clamp | pca_in_rtl - ) - }, - { - /* NB this command should *only* be exectuted in rtl but we - use it in both rtl and pcl5 */ - 'b', 'L', - PCL_COMMAND( "Line Path", - set_line_path, - pca_neg_ok | pca_big_ignore | pca_in_rtl - ) - }, - END_CLASS - return 0; -} - - private void -raster_do_reset( - pcl_state_t * pcs, - pcl_reset_type_t type -) -{ - if ((type & pcl_reset_initial) != 0) - pcs->raster_state.pcur_raster = 0; -} - -const pcl_init_t rtraster_init = { raster_do_registration, raster_do_reset, 0 }; diff --git a/pcl/rtraster.h b/pcl/rtraster.h deleted file mode 100644 index e7683c71f..000000000 --- a/pcl/rtraster.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtraster.h - interface to raster rendering code */ - -#ifndef rtraster_INCLUDED -#define rtraster_INCLUDED - -#include "pcstate.h" -#include "pcommand.h" - -/* - * Create a PCL raster object (on entering raster graphics mode). - * - * Returns 0 on success, < 0 in the event of an error. - */ -int pcl_start_raster(P4( - uint src_width, - uint src_height, - bool region_marked, - pcl_state_t * pcs -)); - -/* complete a raster (when exiting raster graphics mode) */ -void pcl_complete_raster(pcl_state_t *pcs); - -extern const pcl_init_t rtraster_init; - -#endif /* rtraster_INCLUDED */ diff --git a/pcl/rtrstcmp.c b/pcl/rtrstcmp.c deleted file mode 100644 index 4d742c292..000000000 --- a/pcl/rtrstcmp.c +++ /dev/null @@ -1,253 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtrstcmp.c - raster decompression routines */ - -#include "string_.h" -#include "pcstate.h" -#include "rtrstcmp.h" - -/* - * Each of the decompression methods has the same structure. The operands are - * are the seed row to be filled in and the buffer from which it is to be - * filled. A size is provided for the latter. - * - * Adpative compression (mode 5) is not handled at this level, though it will - * make use of these routines for decompressing individual raster rows. - */ - -/* - * Uncompressed data. - */ - private void -uncompress_0( - pcl_seed_row_t * pout, - const byte * pin, - int in_size -) -{ - int nbytes = (in_size > pout->size ? pout->size : in_size); - - memcpy(pout->pdata, pin, nbytes); - if (!pout->is_blank) - memset(pout->pdata + nbytes, 0, pout->size - nbytes); - pout->is_blank = (in_size == 0); -} - -/* - * Run-length compression. - */ - private void -uncompress_1( - pcl_seed_row_t * pout, - const byte * pin, - int in_size -) -{ - int i = in_size / 2; - byte * pb = pout->pdata; - byte * plim = pb + pout->size; - - while (i-- > 0) { - int cnt = *pin++ + 1; - byte val = *pin++; - - if (cnt > plim - pb) - cnt = plim - pb; - while (cnt-- > 0) - *pb++ = val; - } - if (!pout->is_blank) - memset(pb, 0, plim - pb); - pout->is_blank = (in_size == 0); -} - -/* - * TIFF "Packbits" compression. - */ - private void -uncompress_2( - pcl_seed_row_t * pout, - const byte * pin, - int in_size -) -{ - int i = in_size; - byte * pb = pout->pdata; - byte * plim = pb + pout->size; - - while (i-- > 0) { - int cntrl = *pin++; - - if (cntrl < 128) { - uint cnt = min(cntrl + 1, i); - const byte * ptmp = pin; - - i -= cnt; - pin += cnt; - if (cnt > plim - pb) - cnt = plim - pb; - while (cnt-- > 0) - *pb++ = *ptmp++; - - } else if ((cntrl > 128) && (i-- > 0)) { - int cnt = min(257 - cntrl, plim - pb); - int val = *pin++; - - while (cnt-- > 0) - *pb++ = val; - } - } - if (!pout->is_blank) - memset(pb, 0, plim - pb); - pout->is_blank = (in_size == 0); -} - -/* - * Delta row compression - */ - private void -uncompress_3( - pcl_seed_row_t * pout, - const byte * pin, - int in_size -) -{ - int i = in_size; - byte * pb = pout->pdata; - byte * plim = pb + pout->size; - - while (i-- > 0) { - uint val = *pin++; - uint cnt = (val >> 5) + 1; - uint offset = val & 0x1f; - const byte * ptmp = 0; - - if ((offset == 0x1f) && (i-- > 0)) { - uint add_offset; - - do - offset += (add_offset = *pin++); - while ((add_offset == 0xff) && (i-- > 0)); - } - - if (cnt > i) - cnt = i; - i -= cnt; - ptmp = pin; - pin += cnt; - if ((pb += offset) >= plim) - break; - if (cnt > plim - pb) - cnt = plim - pb; - while (cnt-- > 0) - *pb++ = *ptmp++; - } - pout->is_blank = (pout->is_blank && (in_size == 0)); -} - -/* - * Adpative compression (mode 5) is handled at a higher level. - */ - -/* - * Compression mode 9. - * - * HP's documentation of this command is not completely clear regarding the - * interpretation of the replacement byte count for the run-length compression - * case. The interpretation used here, based on the documentation in the - * "PCL 5 Comparison Guide", October 1996 edition, pp. 2.94-2.96, is that the - * replacement byte count refers to the number of output bytes replaced, and - * as many input bytes as required are read until at leas this many output - * bytes have been replaced. - */ - private void -uncompress_9( - pcl_seed_row_t * pout, - const byte * pin, - int in_size -) -{ - int i = in_size; - byte * pb = pout->pdata; - byte * plim = pb + pout->size; - - - while (i-- > 0) { - uint val = *pin++; - uint cnt = 0; - uint offset = 0; - bool more_cnt = false; - bool more_offset = false; - bool comp = ((val & 0x80) != 0); - - if (comp) { - offset = (val >> 5) & 0x3; - more_offset = (offset == 0x3); - cnt = (val & 0x1f) + 1; - more_cnt = (cnt == 0x20); - } else { - offset = (val >> 3) & 0xf; - more_offset = (offset == 0xf); - cnt = (val & 0x7) + 1; - more_cnt = (cnt == 0x8); - } - - while (more_offset && (i-- > 0)) { - uint extra = *pin++; - - more_offset = (extra == 0xff); - offset += extra; - } - while (more_cnt && (i-- > 0)) { - uint extra = *pin++; - - more_cnt = (extra == 0xff); - offset += extra; - } - - if ((pb += offset) >= plim) - break; - if (comp) { - uint j = i / 2; - - while (j-- > 0) { - uint rep_cnt = *pin++; - uint rep_val = *pin++; - - if (rep_cnt > plim - pb) - rep_cnt = plim - pb; - while (rep_cnt-- > 0) - *pb++ = rep_val; - } - i -= 2 * j; - - } else { - if (cnt > i) - cnt = i; - i -= cnt; - pin += cnt; - if (cnt > plim - pb) - cnt = plim - pb; - while (cnt-- > 0) - *pb++ = *pin++; - } - - } - pout->is_blank = (pout->is_blank && (in_size == 0)); - -} - - -void (*const pcl_decomp_proc[9 + 1])( pcl_seed_row_t * pout, - const byte * pin, - int in_size - ) = { - uncompress_0, - uncompress_1, - uncompress_2, - uncompress_3, - 0, 0, 0, 0, 0, /* modes 4 and 6 - 8 unused; mode 5 handled separately */ - uncompress_9 -}; diff --git a/pcl/rtrstcmp.h b/pcl/rtrstcmp.h deleted file mode 100644 index ac4e54edc..000000000 --- a/pcl/rtrstcmp.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtrstcmp.h - interface to the raster decompression code */ - -#ifndef rtrstcmp_INCLUDED -#define rtrstcmp_INCLUDED - -#include "gx.h" -#include "gsstruct.h" - -/* - * Types: - * - * 0 - compression mode 0 (no compression), param is size in bytes - * 1 - compression mode 1 (run length compression), param is size in bytes - * 2 - compression mode 2 ("Packbits" compression), param is size in bytes - * 3 - compression mode 3 (delta row compression), param is size in bytes - * 4 - not used - * 5 - compression mode 5 (adaptive), param is size in bytes - * 9 - compression mode 9 (modified delta row), param is size in bytes - * - * There is no separate format for repeated rows. The desired effect can be - * achieve by create a buffer of type 3 with a size of 0 bytes. - */ -typedef enum { - NO_COMPRESS = 0, - RUN_LEN_COMPRESS = 1, - PACKBITS_COMPRESS = 2, - DELTA_ROW_COMPRESS = 3, - /* 4 is not used, and indicated as reserved by HP */ - ADAPTIVE_COMPRESS = 5, - /* 6 - 8 unused */ - MOD_DELTA_ROW_COMPRESS = 9 -} pcl_rast_buff_type_t; - -/* - * A seed-row structure. These buffers are used both to pass data to the - * graphic library image routines, and to retain information on the last row - * sent to support "delta-row" compression. - * - * The is_blank flag is intended as a hint, not as an absolute indication. If - * it is set, the seed row is known to be blank. However, even if it is not - * set the seed row may still be blank. - */ -typedef struct pcl_seed_row_s { - ushort size; - bool is_blank; - byte * pdata; -} pcl_seed_row_t; - -/* in rtraster.c */ -#define private_st_seed_row_t() \ - gs_private_st_ptrs1( st_seed_row_t, \ - pcl_seed_row_t, \ - "PCL raster seed row", \ - seed_row_enum_ptrs, \ - seed_row_reloc_ptrs, \ - pdata \ - ) - -#define private_st_seed_row_t_element() \ - gs_private_st_element( st_seed_row_t_element, \ - pcl_seed_row_t, \ - "PCL seed row array", \ - seed_row_element_enum_ptrs, \ - seed_row_element_reloc_ptrs, \ - st_seed_row_t \ - ) - -/* - * The array of decompression functions. - */ -extern void (*const pcl_decomp_proc[9 + 1])(P3(pcl_seed_row_t *pout, - const byte *pin, - int in_size - )); - -#endif /* rtrstcmp_INCLUDED */ diff --git a/pcl/rtrstst.h b/pcl/rtrstst.h deleted file mode 100644 index 961706b43..000000000 --- a/pcl/rtrstst.h +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights - reserved. Unauthorized use, copying, and/or distribution - prohibited. */ - -/* rtrstst.h - structure for holding raster information in the PCL state */ - -#ifndef rtrstst_INCLUDED -#define rtrstst_INCLUDED - -#include "gsimage.h" -#include "gx.h" -#include "pccoord.h" - -/* - * The current state of the raster machinery. - * - * There are several fields in the structure whose presence (or absence) may not - * be totally intuitive. - * - * 1. The graphics margin (the "horizontal" distance of the origin of the image - * from the applicable edge of the logical page) is a state variable, even - * though this fact is almost never apparent in practice. The parameter is - * significant only if "graphics mode" (in the sense used in the PCL - * documentation) is entered implicitly; all of the explicit ways of entering - * graphics mode (<esc>*r#A, where # is in the range 0-3) set the graphics - * margin. Furthermore, if the graphics mode is ended via <esc>*rC (but not - * <esc>*rB), the graphics margin is reset to 0. - * - * For ease of implementation, the graphics margin is in centipoints, but in - * the orientation of raster space. The latter feature is significant: it is - * possible to implicitly enter graphics mode in an orientation different - * from that in which the graphics margin was set. In this case, the - * displacement remains the same, but in a different orientation. - * - * 2. Whether or not raster scaling is (potentially) used for a given image - * is a state variable in some HP PCL implementations, but not in others. - * Speicifically, the DeskJet 1600C/CM never uses raster scaling on implicit - * entry into graphics mode, while the Color LaserJet 5/5M retains the - * state of the last entry into graphics mode (in the current PCL state). - * The latter approach is used in this code. - * - * Note that it is the scale/don't scale value of the last entry into - * graphics mode that is retained, not whether or not scaling actually - * took place for that raster. In particular, assume that graphics mode - * was entered with <esc>*r[23]A but the raster was not scaled due to some - * other condition (palette not writable, source raster dimensions not - * supplied). If the condition preventing raster scaling is altered, and - * subsequently graphics mode entered implicitly, raster scaling will - * occur. - * - * 3. The situation with the scale algorithm feature is not yet clear. The - * documentation states ("PCL 5 Color Technical Reference Manual", May - * 1996 ed., p. 6-42) that "This command is valid only after a Start - * Raster command (<esc>*r#A) with scale mode ON." While this might indicate - * that the scale algorithm is not a state variable, we tend to think the - * statement merely reflects a poor choice of wording. We believe it - * would have been better stated as "this command is not effective except - * after ..." A reason for this belief is that all of the commands that - * are "valid" after a start raster mode are of the form <esc>*b#, while - * the scale algorithm command is of the form <esc>*t#, as are the source - * resolution and destination dimension commands (all of which are state - * variables). - * - * 4. Clipping or rasters in PCL is handled in a manner similar to that of - * text, which leads to some curious behavior. Normally, rasters are clipped - * to the printable page boundary. However, if the raster orgin is at - * the logical page "right" or "bottom" boundary relative to the print - * direction, the raster is clipped completely, even in cases in which the - * logical page boundary is inside the printable region. - * - * Centi-point precision is used to determine whether or not the raster - * origin is at the logical page boundary. For logical orientation 0 and - * 2, the the logical page is either 25 or 21 pixels (at 300 dpi) inside - * the printable region, depending on the page size. Hence, it is possible - * to relocate a raster by one centipoint, and have a 25 pixel extent of - * that raster either appear or disappear. - * - * This clipping is inconsistently applied when presentation mode 3 is - * used and the print direction is not along with width of the "physical" - * page. In this case, the perpendicular of the raster scanline direction - * points in the opposite of the print direction, thus the raster could - * move off the "left" edge of the logical page. No clipping is performed - * in this case, most likely due to the implementation method chosen by HP. - * - * The field clip_all is set to true if the raster output is to be suppressed - * because the raster origin is at the logical page boundary. The motion - * implied by rendered scanlines must still be accounted for, hence the - * need for this field. - * - * Because of the dis-continuous nature of this effect, it is sensitive to - * to arithmetic precision. It is possible to set up situations in practice - * in which the last bit of precision of a floating-point calculation will - * determine whether a raster is clipped or not. Fortunately, these - * situations do not arise in practice. - */ - -#ifndef pcl_raster_t_DEFINED -#define pcl_raster_t_DEFINED -typedef struct pcl_raster_t pcl_raster_type; -#endif /* pcl_raster_t_DEFINED */ - -typedef struct pcl_raster_state_s { - uint resolution; /* source resolution, dots per inch */ - - /* various flags */ - uint pres_mode_3:1; /* 1 ==> presentation mode 3 */ - uint scale_raster:1; /* 1 ==> raster scaling enabled */ - uint src_width_set:1; /* source raster width explicitly set */ - uint src_height_set:1; /* source raster height explicitly set */ - uint dest_width_set:1; /* destination width explicitly set */ - uint dest_height_set:1; /* destination height explicitly set */ - uint scale_algorithm:1; /* not currently supported */ - uint graphics_mode:1; /* 1 ==> in graphics mode */ - uint compression_mode:8; /* compression mode */ - - /* for RTL support */ - int y_advance; /* advance is +y (1) or -y (-1) */ - - /* source and (if applicable) destination dimensions */ - uint src_width; /* source raster width, samples */ - uint src_height; /* source raster height, scanlines */ - uint dest_width_cp; /* destination width, centi-points */ - uint dest_height_cp; /* destination height, centi-points */ - - coord gmargin_cp; /* "horizontal" displacement of raster origin */ - - int clip_all; /* on last entry into raster mode, the raster - * origin was at the logical page edge, hence - * the raster needs to be clipped */ - pcl_raster_type *pcur_raster; /* There is at most one image - * actively under construction in PCL - * at one time. This pointer points - * to that image, if it exists. The - * pointer will be non-null while in - * graphic mode. */ -} pcl_raster_state_t; - -#endif /* rtrstst_INCLUDED */ |