[gs-cvs] rev 8770 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Thu May 22 11:06:24 PDT 2008
Author: leonardo
Date: 2008-05-22 11:06:22 -0700 (Thu, 22 May 2008)
New Revision: 8770
Modified:
trunk/gs/src/gsptype1.c
trunk/gs/src/gxcldev.h
trunk/gs/src/gxclpath.c
trunk/gs/src/gxclrast.c
trunk/gs/src/gxclutil.c
Log:
Enhancement (graphics) : Delay applying type 1 raster patterns until clist interpretation (continued 4).
DETAILS :
The old code assumes that a pattern always fits into the clist writer buffer.
However ppmraw -r400 176-01.ps violates this assumption.
This patch implements a subdivision of a pattern into slices,
each of which is smaller than the buffer size.
1. The new function cmd_get_buffer_space retrives maximal available space
in the clist writer buffer (gxclutil.c).
2. cmd_put_drawing_color now implements a cycle for slicing big patterns.
Each slice writes to clist as a separate clist instruction (gxclpath.c).
3. gx_dc_pattern_write_raster drops the constraint that the pattern
fits into a single buffer (gsptype1.c).
4. The clist interpreter is enhanced with composing a pattern from slices
(gxclrast.c).
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gsptype1.c
===================================================================
--- trunk/gs/src/gsptype1.c 2008-05-22 09:52:18 UTC (rev 8769)
+++ trunk/gs/src/gsptype1.c 2008-05-22 18:06:22 UTC (rev 8770)
@@ -1269,6 +1269,7 @@
}
if (offset1 == 0) { /* Serialize tile parameters: */
gx_dc_serialized_tile_t buf;
+ gx_strip_bitmap buf1;
buf.id = ptile->id;
buf.size.x = 0; /* fixme: don't write with raster patterns. */
@@ -1289,20 +1290,28 @@
left -= sizeof(buf);
dp += sizeof(buf);
offset1 += sizeof(buf);
+
+ buf1 = ptile->tbits;
+ buf1.data = NULL; /* fixme: we don't need to write it actually. */
+ if (sizeof(buf1) > left) {
+ /* For a while we require the client to provide enough buffer size. */
+ return_error(gs_error_unregistered); /* Must not happen. */
+ }
+ memcpy(dp, &buf1, sizeof(buf1));
+ left -= sizeof(buf1);
+ dp += sizeof(buf1);
+ offset1 += sizeof(buf1);
}
- if (left < size_b)
- return_error(gs_error_unregistered); /* Not implemented yet because cmd_put_drawing_color provides a big buffer. */
if (offset1 <= sizeof(gx_dc_serialized_tile_t) + size_b) {
- gx_strip_bitmap buf;
+ int l = min((size_b - sizeof(gx_strip_bitmap)) - (offset1 - sizeof(gx_dc_serialized_tile_t) - sizeof(gx_strip_bitmap)), left);
- buf = ptile->tbits;
- buf.data = NULL; /* fixme: we don't need to write it actually. */
- memcpy(dp, &buf, sizeof(buf));
- memcpy(dp + sizeof(buf), ptile->tbits.data, size_b - sizeof(buf));
- left -= size_b;
- dp += size_b;
- offset1 += size_b;
+ memcpy(dp, ptile->tbits.data + (offset1 - sizeof(gx_dc_serialized_tile_t) - sizeof(gx_strip_bitmap)), l);
+ left -= l;
+ dp += l;
+ offset1 += l;
}
+ if (left == 0)
+ return 0;
if (size_c == 0)
return 0;
if (offset1 <= sizeof(gx_dc_serialized_tile_t) + size_b + sizeof(gx_strip_bitmap)) {
@@ -1325,7 +1334,7 @@
return 0;
}
-/* currently, patterns cannot be passed through the command list */
+/* Write a pattern into command list, possibly dividing intoi portions. */
int
gx_dc_pattern_write(
const gx_device_color * pdevc,
Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h 2008-05-22 09:52:18 UTC (rev 8769)
+++ trunk/gs/src/gxcldev.h 2008-05-22 18:06:22 UTC (rev 8770)
@@ -378,6 +378,11 @@
/* and allocate space for its data. */
byte *cmd_put_list_op(gx_device_clist_writer * cldev, cmd_list * pcl, uint size);
+/* Request a space in the buffer.
+ Writes out the buffer if necessary.
+ Returns the size of available space. */
+int cmd_get_buffer_space(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size);
+
#ifdef DEBUG
byte *cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size);
#else
Modified: trunk/gs/src/gxclpath.c
===================================================================
--- trunk/gs/src/gxclpath.c 2008-05-22 09:52:18 UTC (rev 8769)
+++ trunk/gs/src/gxclpath.c 2008-05-22 18:06:22 UTC (rev 8770)
@@ -105,6 +105,11 @@
byte * dp;
byte * dp0;
gs_int_point color_phase;
+ int buffer_space;
+ int offset = 0;
+ int left;
+ uint portion_size, prefix_size;
+ int req_size_final;
/* see if the halftone must be inserted in the command list */
if ( pdht != NULL &&
@@ -136,7 +141,7 @@
return 0;
else if (code < 0 && code != gs_error_rangecheck)
return code;
- req_size = dc_size + 2 + 1 + enc_u_sizew(dc_size);
+ left = dc_size;
/* see if phase informaiton must be inserted in the command list */
if ( pdcolor->type->get_phase(pdcolor, &color_phase) &&
@@ -148,27 +153,39 @@
color_phase.y )) < 0 )
return code;
- /*
- * Encoded device colors are small in comparison to the command
- * buffer size (< 64 bytes), so we can just clear space in the
- * command buffer for them.
- */
- if ((code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_extend, req_size)) < 0)
- return code;
- dp0 = dp;
- dp[1] = cmd_opv_ext_put_drawing_color;
- dp += 2;
- *dp++ = di;
- enc_u_putw(dc_size, dp);
- code = pdcolor->type->write( pdcolor,
- &pcls->sdc,
- (gx_device *)cldev,
- 0,
- dp,
- &dc_size );
- if (code < 0) {
- cldev->cnext = dp0;
- return code;
+ while (left) {
+ prefix_size = 2 + 1 + (offset > 0 ? enc_u_sizew(offset) : 0);
+ req_size = left + prefix_size + enc_u_sizew(left);
+ code = cmd_get_buffer_space(cldev, pcls, req_size);
+ if (code < 0)
+ return code;
+ buffer_space = min(code, req_size);
+ portion_size = buffer_space - prefix_size - enc_u_sizew(left);
+ req_size_final = portion_size + prefix_size + enc_u_sizew(portion_size);
+ if (req_size_final > buffer_space)
+ return_error(gs_error_unregistered); /* Must not happen. */
+ if ((code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_extend, req_size_final)) < 0)
+ return code;
+ dp0 = dp;
+ dp[1] = cmd_opv_ext_put_drawing_color;
+ dp += 2;
+ *dp++ = di | (offset > 0 ? 0x80 : 0);
+ if (offset > 0)
+ enc_u_putw(offset, dp);
+ enc_u_putw(portion_size, dp);
+ code = pdcolor->type->write( pdcolor,
+ &pcls->sdc,
+ (gx_device *)cldev,
+ offset,
+ dp,
+ &portion_size);
+ if (code < 0) {
+ if (offset == 0)
+ cldev->cnext = dp0;
+ return code;
+ }
+ offset += portion_size;
+ left -= portion_size;
}
/* should properly calculate colors_used, but for now just punt */
Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c 2008-05-22 09:52:18 UTC (rev 8769)
+++ trunk/gs/src/gxclrast.c 2008-05-22 18:06:22 UTC (rev 8770)
@@ -1616,15 +1616,19 @@
uint color_size;
int left, offset, l;
const gx_device_color_type_t * pdct;
+ byte type_and_flag = *cbp++;
+ byte is_continuation = type_and_flag & 0x80;
- pdct = gx_get_dc_type_from_index(*cbp++);
+ pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
if (pdct == 0) {
code = gs_note_error(gs_error_rangecheck);
goto out;
}
+ offset = 0;
+ if (is_continuation)
+ enc_u_getw(offset, cbp);
enc_u_getw(color_size, cbp);
left = color_size;
- offset = 0;
if (!left) {
/* We still need to call pdct->read because it may change dev_color.type -
see gx_dc_null_read.*/
Modified: trunk/gs/src/gxclutil.c
===================================================================
--- trunk/gs/src/gxclutil.c 2008-05-22 09:52:18 UTC (rev 8769)
+++ trunk/gs/src/gxclutil.c 2008-05-22 18:06:22 UTC (rev 8770)
@@ -279,6 +279,25 @@
cldev->cnext = dp + size;
return dp;
}
+
+/* Request a space in the buffer.
+ Writes out the buffer if necessary.
+ Returns the size of available space. */
+int
+cmd_get_buffer_space(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size)
+{
+ cmd_list * pcl = &pcls->list;
+
+ if (size + cmd_headroom > cldev->cend - cldev->cnext) {
+ cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run);
+ if (cldev->error_code < 0) {
+ cldev->error_is_retryable = 0; /* hard error */
+ return cldev->error_code;
+ }
+ }
+ return cldev->cend - cldev->cnext - cmd_headroom;
+}
+
#ifdef DEBUG
byte *
cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size)
More information about the gs-cvs
mailing list