Page tree
Skip to end of metadata
Go to start of metadata

Introduction

The PostScript language is an evolving standard. The compatibility target for Jaws is to implement the core operator set for the latest version of the language for which documentation is publicly available. GGS do not make use of any information which is not in the public domain, including any information in the SDK which is only available under non-disclosure agreements. The latest publicly documented version of the PostScript language is version 3, so Jaws should be compatible with the version of the PostScript language described in the Version 3 Supplement to the Adobe documentation.

This is also the version described in the 3rd Edition of the PostScript Language Reference Manual (PLRM).

From version 3015 of Adobe’s CPSI RIP onwards, it is possible to set the overprint mode using the setoverprintmode operator. Jaws also provides this feature.

The current target PostScript language version is reflected in the value of the version entry in systemdict. The actual Jaws version number is stored elsewhere. The reason for this is that some code produced by common PostScript printer drivers (as well as the code emitted by InDesign) checks for a particular version number, instead of explicitly checking for support of individual language features, as recommended in the PLRM.

An example of this is the output produced by some Windows printer drivers, which only uses the xshow operator if the value of version is greater than 2015. In such cases, a low version number, like the actual Jaws version number, can result in substantial performance penalties. Storing a “compatibility” version number in version ensures that the relevant language features are used whenever they should be.

If a new version of the PostScript language is released, the value in version will be updated to reflect whether or not Jaws is compatible with this version.

Such an update may require the release of a new version of Jaws, or it may just require rebuilding your product with the latest Jaws libraries.

Architectural differences

Jaws uses a quite different representation for fundamental objects to that used by Adobe interpreters. Much of this is a necessary result of the pointer-based representation of objects in memory, which makes the graphics and device class code much more flexible. The different representation leads to a few minor differences in behavior.

In practice, these differences have never caused a real-world PostScript language file to fail.

Operators

Jaws implements a core set of operators from the PostScript language. This includes all operators that are relevant to producing printed output, including all the operators that may be used in page descriptions or normal device setup.

Jaws does not implement operators that are not relevant to producing printed output. This includes operators such as sethardwareiomode, which are intended to be used in embedded controllers. These operators generally appear in statusdict on any products which include them, and this set of operators is generally product-dependent in any case. However, OEMs can add to and extend the existing set of PostScript language operators.

Jaws does not support trapping, and therefore does not implement the settrapparams or settrapzone operators.

The shfill operator, used with smooth shading, is implemented as a PostScript language procedure, not as an operator. This procedure simply sets a Pattern color space with the appropriate shading dictionary and fills the current clipping path. There are no known incompatibilities caused by doing this.

There is another group of operators in statusdict which is used to control production of printed output. These are generally old Level 1 operators such as setduplexmode which performed functions now carried out by the setpagedevice operator. In Jaws, these are not implemented as operators, but instead as PostScript language procedures which in turn call setpagedevice. In normal operation, the difference between implementing these as operators or as procedures is invisible. The biggest difference is that PostScript code cannot use the presence or absence of these operators to test for the presence of hardware features such as duplex capability, as they are always present. If this is important for your application, it is possible to modify the Jaws initialization code to only define those operators which are appropriate for the current output device see Chapter 5, “Jaws initialization files” for more information.

Jaws implements all the Level 2 file I/O operators described in the PLRM. These are implemented on top of a resource-based file system similar to the one described in the discussion of resources in the PLRM. This means that you can use file names such as %font%Times-Roman across all Jaws implementations, without having to worry about where the file for Times-Roman actually resides. Adobe products often implement a simpler file system, where the device names represent physical devices such as %disk0%, %disk1% and so on, instead of the logical devices such as %font% and %resource% used by Jaws. Normally, this is not a problem, as any PostScript language code you write which needs to use file names will be specific to Jaws anyway.

However, some font installers—particularly for CJK far-eastern fonts—will explicitly use device names like %disk1%. It is possible to accommodate these downloaders and map them to Jaws file devices. CJK font installers may also make use of a further set of procedures in statusdict, such as diskonline, which they use to search all of the disks attached to a printer to find one with enough room to install the fonts. Jaws includes devforall as a built-in kernel operator that will enumerate all file system devices.

There are also a number of undocumented features of Adobe products, which fall into two categories:

Firstly, are those features which are deliberately undocumented.

Secondly are features which are not deliberately undocumented. This can include the behavior of specific operators under certain boundary conditions, or operators which do not signal an error in conditions where the PLRM stipulates that they do, and so on. In these cases, Jaws will implement the undocumented behavior if the required behavior can be determined without reverse engineering (that is, if the behavior can be determined unambiguously just by running a “real-world” PostScript language job on an Adobe product) and if it can be implemented in such a way that the class of real-world jobs which now run after the change to Jaws is likely to be larger than the class of real-world jobs which now fail after the change. In some cases, a PostScript user parameter is available to switch the change on and off, where it is not possible to mimic the undocumented behavior in a totally harmless way.

Lastly, there are also behaviors which are documented in the PLRM as being specifically undefined. One example of this is the behavior of filtered files which are closed without flushing. The position of the underlying data stream will depend on the buffering strategy employed by the interpreter, and may change between different versions of Adobe products. However, despite the warnings in the PLRM, there are applications which generate PostScript language that depends on the particular behavior of current (or sometimes even obsolete) versions of Adobe PostScript language. These cases are treated in the same way as undocumented behavior—Jaws emulates the required behavior if it can be determined without reverse engineering and if it is not harmful to other jobs—with the exception that we regard this as a “luxury” and may remove the change in the future if we find it interferes with the correct execution of other real-world jobs which heed the warnings in the PLRM.

Jaws also implements a small number of extension operators and interpreter parameters which are not present in the PostScript language. Since these do not affect compatibility, they are described separately in the following sections.

Resources

Jaws supports all of the regular resource categories except for InkParams and TrapParams, which are used with trapping, and ControlLanguage, PDL, HWOptions and Localization, which relate to embedded printer applications.

The OutputDevice resource category is intended to describe the available media sizes and the like, associated with a particular output device. Jaws allows an open-ended set of output devices, and the capabilities of even the sample output devices are widely variable, so Jaws does not ship with any resources in this category. An OEM can add this resource category, if desired, after integrating Jaws into their product.

The ProcSet resource category is intended to hold collections of PostScript language procedures and operators, mainly for dealing with other kinds of resources.

Of the standard ProcSet resources, Jaws implements BitmapFontInit, CIDInit, ColorRendering and FontSetInit. These resources are implemented from their respective functional definitions in the PostScript language documentation. Any procedures which are described in that documentation are present and should function as described. For example, all of the procedures begincmap and so on. described in the CID file format documentation exist and behave as documented. However, the underlying implementation of these procedures, and any procedures called in turn by them, are most probably different to what you would find on an Adobe product. Therefore, when using these procedure sets, you should only use the publicly documented procedures in them.

The ColorRendering procedure set behaves as documented. However, the only color rendering dictionary supplied with Jaws is DefaultColorRendering. Therefore, the findcolorrendering procedure will always calculate the name of the required color rendering dictionary, and then pick DefaultColorRendering anyway. If you wish to make use of findcolorrendering, it is your responsibility to make sure that you provide a properly coordinated set of named page device dictionaries, halftones and color rendering dictionaries.

The Trapping procedure set is not implemented.

Jaws supports type 4 fonts. These were used in old format composite fonts, before CID fonts were introduced. Jaws optionally supports the CCRun operator, for type 4 fonts, and the SpecialRun operator for encrypted fonts. Use of SpecialRun requires OEM code to supply Jaws with a set of serial numbers; if the serial numbers are not present or are incorrect, this operator will signal an invalidaccess error. Use of this operator requires a separate agreement with Morisawa in Japan.

Jaws implements all the implicit resource categories except for Emulator. The instances of the IODevice category are not the same as the instances of this category found on Adobe products.

Jaws does not implement the special %fontset% file device which is used in Adobe products to enumerate type 2 fonts within a single CFF (Compact Font Format) font set stored on disk as if they were individual font files. Although the fonts that ship with Jaws are stored in CFF format, they are stored one per font set in the normal font directory, so that resourceforall and filenameforall behave correctly anyway.

Jaws implements all of the ...Encode filters, which are documented as being optional for Level 3 implementations. Jaws does not support the optional GIFDecode or PNGDecode filters.

Interpreter parameters

This section describes and lists the various user, system and page device parameters which are supported by Jaws. In addition, those parameters which are not supported by Jaws are identified.

User parameters

For a full list of user parameters see “User parameters”.

Only some of these user parameters are used within Jaws. For example, Jaws does not perform garbage collection of VM (instead, it uses a reference counted memory), so VMReclaim is ignored completely. However, Jaws maintains the values of all these parameters, so that code which uses them continues to work.

Any system or user parameters which describe the size of caches or cached objects—the MaxFontItem user parameter or the MaxFormCache system parameter, for example—will obviously be product dependent, as they depend on the representation used for storing these objects internally. The strategy for dealing with font cache overflow is conventional, and Jaws will fall back to executing individual glyph descriptions when the font cache is full. Jaws will never fail to render a form or pattern because it is too large; however, large forms or patterns may not be added to the cache. In this case, a job with inappropriate cache settings will always render, but with potentially reduced performance.

The HalftoneMode parameter is not used by the Jaws kernel in any way. However, it is provided so that OEM code for halftone selection may inspect its value. Such code would typically be implemented as PostScript language procedures in the %lib%utils.ps support file.

Jaws does not implement the following user parameters:

JobTimeout                                         WaitTimeout

System parameters

Jaws implements the following system parameters:

/BuildTime

/JobTimeout

/ByteOrder

/KernelBuild

/CurFontCache

/MaxFontCache

/CurFormCache

/MaxFormCache

/CurPatternCache

/MaxPatternCache

/CurScreenStorage

/MaxScreenStorage

/CurUPathCache

/MaxUPathCache

/FontResourceDir

/PrinterName

/GenericResourceDir

/RealFormat

/GenericResourcePathSep

/Revision

/JawsVersion

/WaitTimeout

Jaws does not implement the following system parameters:

CompressImageSource

LicenseID

CurBufferType

MaxDisplayAndSourceList

CurDisplayList

MaxDisplayList

CurInputDevice

MaxHWRenderingBuffer

CurOutlineCache

MaxImageBuffer

CurOutputDevice

MaxOutlineCache

CurSourceList

MaxPermanentVM

CurStoredFontCache

MaxRasterMemory

CurStoredScreenCache

MaxSourceList

DoPrintErrors

MaxStoredFontCache

DoStartPage

MaxStoredScreenCache

EnvironmentSave

MinBandBuffers

FactoryDefaults

PageCount

FatalErrorAddress

SourceListBypass

InstalledRAM

StartupMode

JobTimeout

ValidNV

A number of these parameters relate to the disposition of memory when rendering to a band device, and are necessarily product-dependent. Jaws provides an alternative method for controlling memory when banding, described below.

The undocumented MaxResolution system parameter is required to support some Kanji font installers. This is a read-only parameter giving the maximum resolution at which the current product may operate. Jaws does not implement this parameter in the kernel, but it is possible to “hook” the currentsystemparams operator to provide this value.

Page device parameters

The page device parameters which are passed to the interpreter via the dictionary operand to the setpagedevice operator form an open-ended collection, intended to describe the physical characteristics of each product. However, there are a core set of page device parameters which are either always implemented, such as PageSize, or else always implemented in the same way when present, such as Duplex.

Jaws supports some of these parameters in the kernel; others are passed straight to the OEM’s device drivers to be handled there.

The Jaws kernel supports the following page device parameters:

BeginPage

MaxSeparations

OutputType

DeferredMediaSelection

MediaClass

PageDeviceName

Duplex

MediaColor

PageOffset

EndPage

MediaType

PageSize

HWResolution

MediaWeight

Policies

ImageShift

MediaPosition

ProcessColorModel

ImagingBBox

MirrorPrint

RollFedMedia

InputAttributes

NegativePrint

SeparationColorNames

InsertSheet

NumCopies

SeparationOrder

Install

Orientation

Separations

LeadingEdge

OutputAttributes

Signature

ManualFeed

OutputDevice

Tumble

Margins

OutputPage

UseCIEColor

Communication of these parameters between the kernel and the device driver is via a special structure in the PostScript language graphics state which represents the current state of the page device. Not all of the above parameters are applicable to all output devices; in this case the device driver may set a flag which indicates to the kernel that it does not support a given feature, such as Duplex. Many parameters, such as PageOffset, MirrorPrint and NegativePrint are handled directly by the kernel and are always available, for all device drivers.

The OutputDevice parameter is treated in a special way in Jaws, as it is used to select and initialize a new output device driver.

The MaxSeparations read-only parameter is always set to a value of 250.

The Signature parameter is used by Jaws to implement a simple form of n-up printing, in conjunction with a SignatureDetails dictionary. For more information, see “Imposition” on page 83.

The ProcessColorModel parameter may be constrained by the capabilities of a particular device driver. For some device drivers, this key should be regarded as read-only. For example, if the output is to a single one-bit per pixel bitmap, the only possible value for ProcessColorModel is DeviceGray. Some other device drivers may use the value of ProcessColorModel to control the output they generate—for example, the sample anti-aliased output device driver lets you use this parameter to control whether the final output is 32-bits per pixel RGBa color or 32-bits per pixel CMYK color. In all cases, the initial value is set by the kernel to a default provided by the device driver. Any attempt to set ProcessColorModel to a value which cannot be handled by the currently selected device driver will cause a configurationerror.

Jaws does not support values of either DeviceCMY or DeviceRGBK for ProcessColorModel, which are supported by some Adobe products. In fact, DeviceCMY is the same as DeviceRGB except that it produces inverted outputs—Jaws lets device drivers nominate the “natural” polarity of their output, so the equivalent of DeviceCMY can be achieved just by setting a device driver flag. The DeviceRGBK color model is a special color model which, if required, can be emulated using a relatively simple device class.

Jaws allows a value of DeviceN for ProcessColorModel, but does not support this in the kernel. This value requires extra support in the form of an OEMwritten device class, as there is no “standard” specification for how colors should be converted with this color model.

The Separations parameter functions in a similar way. Device drivers which can only produce composite output will initially set Separations to false and will reject any attempt to set it to true. Device drivers which produce either separated or composite output will allow either value, and set it to an initial driver-dependent default. In the set of sample device drivers shipped with Jaws, it is possible to configure some of the drivers to only produce monochrome output. In this case, composite and separated output are of course identical, and the driver will usually allow both values of Separations but not take any action when it changes.

Similarly, whether or not the SeparationColorNames and SeparationOrder parameters may be changed by calling setpagedevice is under the control of the device driver. If the device driver has enabled SeparationOrder, and if you are producing separated output, then any combination of process and spot color names is permitted, and you may also repeat separation names or omit them completely, as described in the PLRM.

Jaws provides an additional color model which is not visible to PostScript language code. This color model is intended to render CMYK colors more faithfully to RGB output devices, and is controlled by the D_RGB1 flag. This color model converts CMYK colors to RGB colors using a formula that is intended to mimic the way CMYK is printed, instead of using the usual formula given in the PLRM. In addition, if any transfer functions have been set in the graphics state, all colors are converted to CMYK before being converted back to RGB using this formula.

If you are using this alternative color model, the value of ProcessColorModel is set to DeviceCMYK (for the benefit of PostScript language code which examines this parameter to determine if a four-color output device is being used), but the appropriate colorant names for SeparationOrder are Red, Green and Blue.

The UseCIEColor page device parameter is used to define “default” color spaces for the grayscale, RGB and CMYK color spaces used by the setgray, setrgbcolor and setcmykcolor operators. These default color spaces interact with the default color spaces defined in the PDF specification. If a PDF rendering context (a page description or a form, for example) uses the g, r or k operators to specify a color, then Jaws first consults the ColorSpace resource dictionary for that rendering context, and if a DefaultGray, DefaultRGB or DefaultCMYK color space is found, Jaws will use that as the color space for the operator. This substitution is performed according to the PDF specification and happens regardless of the state of the UseCIEColor page device parameter.

If no default color space is found in the PDF file, and the UseCIEColor page device parameter is true, Jaws will next look for a default PostScript language color space, and use that if it is present. If there is no default PostScript language color space, or if UseCIEColor is set to false, Jaws will use the DeviceGray, DeviceRGB or DeviceCMYK color space as appropriate.

Jaws will recognize default color spaces that are defined either before UseCIEColor is set to true, or while it is true. However, if you use undefineresource to delete a default color space while UseCIEColor is set to true, Jaws will not recognize this and will continue to use the color space until UseCIEColor is next changed to false.

Some objects carry color space information around with them, either explicitly (type 2 patterns) or implicitly (type 1 patterns and forms). The PLRM does not specify when the default color space substitution should take place for such objects. For type 2 patterns, Jaws makes the default color space substitution when the pattern is defined, not when it is rendered. For type 1 patterns and forms, Jaws makes the substitution when the display list for the object is compiled, which normally corresponds to the execution of makepattern or the first execution of execform.

Of the standard keys listed in the PLRM, the Jaws kernel does not support the following:

AdvanceDistance

DeviceRenderingInfo

PostRenderingEnhance

AdvanceMedia

ExitJamRecovery

PreRenderingEnhance

Bind

Fold

Staple

Booklet

Jog

Trapping

Collate

Laminate

TraySwitch

CutMedia

ManualFeedTimeout

Trim

Any unrecognized page device parameter, including these, is passed directly to the device driver by the kernel. A number of these parameters may be handled directly by the device driver without kernel intervention.

Implementation limits

Jaws has the following implementation limits:

  • Support for 32-bit integers and single-precision floating point, with limits as described in the PLRM.
  • Arrays and strings with an arbitrary length (up to 214783647), and dictionaries with an arbitrary capacity, subject only to the amount of PostScript language VM available.
  • Jaws’ name objects are limited to 127 characters.
  • Emulated filename components are limited to 1023 characters (unless the PostScript language filename is represented as a PostScript language name object, in which case the name limit of 127 applies.
  • Jaws allows an arbitrary depth of save nesting.
  • Up to 65535 active gsave operations. Each gsave may have up to 65535 active clipsave operations, subject only to the amount of memory available.
  • Jaws allows an arbitrary number of separations for SeparationColorNames and for DeviceN color spaces.
  • The operand, dictionary, and execution stacks may grow to any size, limited only by the amount of available memory.
  • The execution stack may optionally be limited by the MaxExecStack user parameter in order to avoid the interpreter locking up when a PostScript language procedure goes into an infinite recursion. This parameter counts execution stack frames, not objects—each operator which pushes a new frame onto the execution stack pushes a single, opaque object, whereas Adobe implementations push one or more individual PostScript language objects.
  • Jaws does not support recursive invocation of the interpreter, in the sense that an operator may not simply invoke the top-level interpreter. All of the operators which appear to do so, such as pathforall, show and image are written so that they instead push a new frame onto the execution stack (and are therefore limited only by available memory). Any OEM-written operators which need to execute PostScript language code must be written in the same way.
  • Paths may have an arbitrary number of segments, subject only to available memory.
  • Dash patterns may have an arbitrary number of elements.
  • Any number of files may be open simultaneously, subject to the constraints of the host operating system, including any per-user quotas which may be imposed by the operating system.
  • Image data may contain an arbitrary number of samples in both width and height.

Graphics

The default value for the stroke adjustment parameter in the graphics state is true. The reason for this is that it produces better looking results at lower resolutions, and the results of rendering are closer to what was originally requested than the result of rendering with stroke adjustment set to false. In addition, there often is a slight performance advantage to rendering with stroke adjustment set to true.

The PLRM states that the initial value of stroke adjustment is device dependent. However, there are some files which depend on the value of stroke adjustment, but which do not bother to check its value or explicitly set it to false. These include jobs produced by PowerPoint. This application renders background blends as a series of parallel stroked lines which are calculated to butt up against each other when rendered at a particular resolution and with stroke adjustment set to false. If rendered at the wrong resolution, or with stroke adjustment set to true, the stroked lines do not meet, and the blend appears to have periodic white lines drawn over it. A more subtle effect that stroke adjustment can have on a job is if the job includes paths with very short line segments—the movement of the end points of the lines can change the angle between two adjacent line segments. This is a small effect in itself, but it might, for example, cause the angle to exceed the miter limit, substantially changing the appearance of part of the path.

Before running such jobs, it is advisable to set the initial value of stroke adjustment to false, by editing the PostScript language start up files. For more information on startup files, see the chapter “Jaws initialization files”. If you are generating output intended for high resolution devices, you may wish to make this change permanent.

Although Jaws supports type 16 halftones as a language feature, only the most significant 8-bits of each threshold value are used for rendering purposes.

In Jaws, device space always use a right-handed co-ordinate system, the same as user space. That is to say, pixel y co-ordinates increase up the page. In contrast, in most Adobe products, device space uses a left-handed co-ordinate system, the opposite of user space, in which pixel y co-ordinates increase down the page. Normally, the mapping from user space to device space is invisible in the PostScript language, with one exception. If you use a threshold array to specify a halftone screen, the threshold values in the threshold array are defined so that the first threshold has device co-ordinates (0,0) and subsequent thresholds have increasing x and y co-ordinates, with x co-ordinates changing faster than y co-ordinates. This means that in Jaws, the threshold array is “painted” up the page, whereas in most Adobe products it is “painted” down the page. This in turn means that the dot pattern will be upside-down in Jaws relative to other products. If you are using a type 10 or type 16 halftone dictionary to simulate a halftone screen with a particular screen angle, you will also find that the angle appears to be the negative of what you intended. In fact, the angle is correct, because device space is righthanded and so angles are still measured anti-clockwise, just as for user space, and not clockwise, as would be the case on a product where device space was left-handed.

When stroking paths, Jaws endeavors to produce an optimal path to fill. Normally, this happens internally and is invisible, but you can observe that the path produced by the strokepath operator attempts to trace out each subpath “without lifting the pencil”. This is different to most other products, where the result of strokepath normally makes the actual method used to stroke paths visible.

The orientation (that is, clockwise or anti-clockwise) of individual sub-paths produced by applying strokepath to a dashed path is officially undefined.

There are files which fail because they assume a particular orientation.

As described in the PLRM, the path resulting from execution of the clippath operator is intended only for filling or clipping, not for stroking. In fact, in all but the simplest cases, this is not a path at all in Jaws, but instead a scan-converted shape. There is no way for a PostScript language program to tell the difference, of course, but if it attempts to stroke the path, it will instead be filled. This is different to some other products, which represent this path as a complex path with a lot of extra “construction lines”—such a path can be stroked, but the results will probably not be what was expected anyway.

The scan-conversion rule that Jaws uses for filling and stroking paths is slightly different to that described in the PLRM. The set of pixels painted by a fill operation is the union of the set of pixels whose centers lie inside the original path, and the set of pixels whose centers lie inside a single-pixel wide line drawn around the original path (that is, around the perimeter of the region to be filled). For pixels whose centers lie exactly on the boundary of either of these regions, the same tie-breaking rule is used as described in the PLRM— pixels which lie below or to the left of the region are considered to be inside it, and pixels which lie above or to the right of the region are considered to be outside it. This rule normally fills slightly fewer pixels than the rule described in the PLRM. For edges which are exactly horizontal or vertical, this rule produces the same results as that described in the PLRM; the greatest difference between the two occurs for edges oriented at 45° to the axes.

If you are using Jaws on a “write-white” printer, the write-white adjustment in the page device structure, directly affects this scan conversion rule. In this case, the write-white compensation increases the width of the line drawn around the perimeter of the region to be filled, thus increasing the size of the filled region. An OEM can control the precise amount by which the width of the line is increased, although increasing it from one pixel to two will add an average of half a pixel all around the region to be filled.

The following diagram illustrates this scan conversion rule for a simple path with two intersecting sub-paths. The left hand figure shows the scan conversion rule that Jaws uses: the red pixels are those that would be filled by pixel centre sampling, and the blue pixels are the extra pixels that are filled by the outlining operation. If the write-white adjustment parameter was set to a nonzero value, there would be more blue pixels as the width of the outline (shown as the thin stroke) increased. The right hand figure shows the scan conversion rule described in the PLRM. Although the line around the perimeter is shown as having round joins, the requirement for adequate performance dictates that Jaws actually uses a polygonal approximation to a round join.

Since the features here are usually smaller than a pixel, you are only likely to notice the difference for extremely large values of the write-white adjustment parameter.

Figure 2.1 Scan conversion rule

This scan conversion rule has some useful properties. The first is that, like the rule in the PLRM, it does not suffer from dropout aliasing. If pixel-center sampling were used on its own, then rendering features less than a pixel wide would cause dropouts to appear where the feature happen to fall entirely between the centers of adjacent pixels. Adding the line drawn around the perimeter prevents this from happening.

Another property is that a single pixel line (drawn by the PostScript language when the line width parameter in the graphics state is zero) is comprised of the same set of pixels that you would get if you applied the full rendering process with a line width of zero. Or, to put it another way, in Jaws, a zero width line is just the limit of the set of lines you would get as the line width tended to zero. This may seem academic, but it can affect the rendering of pages at low resolution. Consider a path that is filled in one color and stroked in another, which is quite common in figures produced by DTP illustration software. Although the path is almost certainly stroked with a non-zero width, at low resolution, the width may be small enough that the line passes the interpreter’s test for rendering the stroke as a zero-width line (especially with the graphics state stroke adjustment parameter set to true). With the rule described in the PLRM, this can result in “pimples” around the edge of the path, where the filled interior actually projects outside the stroked boundary. With the Jaws filling rule, on the other hand, the filled interior should not project more than half a pixel beyond the path itself, and therefore does not project beyond the outside of the stroke. (Rounding errors in arithmetic mean that there may still be pimples in some cases, but there are normally fewer than would otherwise be the case.)

The above description only applies to “normal” fills and strokes. As with Adobe products, Jaws uses a completely different filling rule when rendering type 1 and type 42 fonts. Using the normal scan-conversion rule for characters would lead to text that appeared too dark, especially at low resolutions.

Instead, Jaws uses pixel-center sampling, coupled with a set of heuristic rules to avoid dropout aliasing in small characters.

Jaws also renders spline curves in a different way to that implied by the PLRM. Instead of repeated bisection, Jaws uses a forward-differencing method to flatten splines. Although not fully adaptive, this method does usually render a given spline with fewer straight line segments than bisection, with a consequent improvement in performance. However, this does mean

that the flatness parameter in the graphics state is not interpreted in the usual way. Although increasing the flatness from its default value will result in coarser rendering, the exact results will not necessarily match those produced by a different interpreter.

Jaws renders images using pixel-center sampling, exactly as described in the PLRM.

Interpolated images, other than masks and 1-bit-per-component images, are always interpolated using bilinear interpolation. Adobe products appear to use bicubic and/or bilinear interpolation. For masks and 1-bit-per-component images, Jaws uses a different interpolation technique which rounds off square corners in the mask. Some Adobe products use bilinear and/or bicubic density interpolation for 1-bit-per-component images, yielding an interpolated result with more than two gray levels.

Jaws also uses pixel-center sampling for smooth shading. The PLRM does not explicitly describe a rule for rendering smooth shading, although the description of the various types of shading dictionary implies pixel centre sampling in places. However, there is some evidence that Adobe products bleed the edges of smooth shaded meshes slightly. This difference will show itself when rendering a patch mesh which has small cracks between the individual patches. This can happen when the application generating the PostScript language code has not been careful about subdividing the mesh so that it does not crack—Illustrator is capable of generating such meshes. Jaws will faithfully reproduce the cracks, leading to visible dropouts at most resolutions.

Adobe products will bleed the patch meshes, causing the dropouts to disappear at lower resolutions.

Jaws does not currently implement the AntiAlias feature for smooth shading.



  • No labels