Hello, While running GhostScript 8.60 on Windows Vista Ultimate, I came across a problem with the 'arc' command limiting the size of radius (I believe) that is valid. When sending the following command to GhostScript: 5e13 350 5e13 180 0 arc I get the follow error message back: ERROR: limitcheck OFFENDING COMMAND: arc OPERAND STACK: 0 180 5e+13 350 5e+13 This same arc doesn't throw any error in either the HP interpreter or the Ricoh interpreter we have running on our printers. I'm not positive, but I haven't seen anything in the Red Book about limits to the size of radius which can exist for an arc command (other than the limits set on any number, which 5e13 falls under). Here you can download an example of the arc command: http://jeff.crazybaglok.com/junk/cet_25_216.ps Thanks again! Jeff Vance ps: Sorry for the empty description, hit enter unintentionally.
Created attachment 4676 [details] cet_25_216.ps - local copy of the sample file.
Seems to be a 32-bit vs 64-bit issue. 64-bit linux gs 8.63 works okay; 32-bit linux 8.61 and 32-bit win32 8.63 both die with the same error.
I got the error with win32 8.63 under wine, so it is not vista-specific.
The section about arc in the redbook did mention in the end it could throw a limitcheck error, which is for exceeding any implementation limits - and I don't think you should take the implementation limit list at the appendix as exhaustive... In any case, I have looked through the ghostscript code and here is what I found: 1) this is a ghostscript-specific problem (i.e. does not affect other ps interpreters) - it is actually "documented" in the source code (gspath.c, around line 85) near clamp_point_aux(): * Define clamped values for out-of-range coordinates. * Currently the path drawing routines can't handle values * close to the edge of the representable space. 2) it only affects 32-bit builds - win32 or 32-bit linux; not affecting 64-bit linux. You don't need 5e+13 to go over - 5e+7 would exceed the limit. 3) The actual limitcheck is thrown by gs_point_transform2fixed_rounding() in base/gsmatrix.c . Most of the routines in gspath.c is protected by clamp_point_aux(). The actual problem is this: gs_arc() -> gs_arc_add_inline() -> gs_imager_arc_add() -> arc_add() , at which point it tries to break down the arc into quadrants for curveto, and realises the end point curveto are beyond representable space. (this is smaller for 32-bit platforms than 64-bit platform, because it is related to size of long). To fix this, I would propose moving the clamp_point_aux() into a common area, (or duplicate it to gspath1.c from gspath.c), adding a new boolean argument to base/gsmatrix.c to clamp or not; and make some usage not to clamp but some do. Either way it is quite invasive change. Hi Igor/Leonard, do you want to comment how to go about this? You were the last person to work on the clamp_point_aux() code.
Created attachment 4686 [details] proposed patch This replaces the limitcheck with clamp_point(). (i.e. clip the co-ordinates and continue, rather than throw an error). The duplication of clamp_point() from gspath.c is somewhat undesirable; also, clamping within a transform feels "wrong". However, the clamp needs to happen *after* gs_point_transform() in gs_point_transform2fixed_rounding(), so the current location of change seems to be the only practical place to do a clamp. This patch utilizes the fact that gs_point_transform2fixed_rounding() is only called and used by exactly one upstream routine arc_add() - this may also be considered undesirable. Looking for suggestions on how to make this patch better and/or more agreeable.
There seems to be an issue with such an approach of clamping the coordinates to max_fixed_point, that it might produce a line inside some clipping region while the original arc might be outside of that region and not supposed to be visible. Am I correct here? Might be better to do such clamping on the page boundaries / visible region instead (based on page size and resolution). If that exceeds the max_fixed_point, then it is really limit of current GS implementation on 32-bit system.
Actually, unless the path segments have been broken down to very small, should not use clamping at all, but calculate the intersections of the original segments (line or curve) with the page boundaries and draw the visible segments along with lines on the boundaries. This needs to be handled one level up, which should also includes fast rejection of paths or segments out of the page boundaries.
Reassigning path and fill problems to Robin Watts.
Reassigning to new email address.
Bug still reproducible in Ghostscript 9.03
Created attachment 13996 [details] proposed patch To avoid limitcheck in the graphic library, we replace arcs whose radius greatly exceeds the page size with a polyline. The polyline goes from the start point to the end point through every intersection between the arc and the lines continuing from the page edges. This ensures that the insideness of the page is preserved and the arc segments that fall within the page dimensions are replaced by their chords.
Created attachment 13997 [details] Test file A test file that draws many large arcs through 3 random points. Two points are in or near the media box and the 3rd point is far away.