diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-09-27 11:19:24 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-10-20 18:22:47 +0200 |
commit | cc6be9c3577168805ec34b2d396e63361012282b (patch) | |
tree | 7dc794b08a1a6a786d540516c623cb1eebfb1863 /base | |
parent | Import Ghostscript 9.54 (diff) | |
download | ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.gz ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.bz2 ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.zip |
Import Ghostscript 9.55ghostscript-9.55
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'base')
215 files changed, 10752 insertions, 6912 deletions
@@ -1,26 +1,17 @@ -/* - * Testbed implementation of Even Better Screening. Please see - * http://www.artofcode.com/eventone/ for more details. - * - * Copyright 2001-2004 Raph Levien <raph@acm.org> - * - * Code in this module is covered by US Patents 5,055,942 and - * 5,917,614, and corresponding international patents. This version - * of ETS is for commercial licensees and is governed by the licensing - * agreement between artofcode LLC and the licensee. Please see - * http://www.artofcode.com/eventone/ for information on licensing. - * - * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. - * - * All Rights Reserved. - * - * This software is provided AS-IS with no warranty, either express or - * implied. - * - * This software is distributed under license and may not be copied, - * modified or distributed except as expressly authorized under the terms - * of the license contained in the file LICENSE in this distribution. - */ +/* Copyright (C) 2013-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ #include <stdlib.h> #include <string.h> @@ -1,26 +1,17 @@ -/* - * Testbed implementation of Even Better Screening. Please see - * http://www.artofcode.com/eventone/ for more details. - * - * Copyright 2001-2004 Raph Levien <raph@acm.org> - * - * Code in this module is covered by US Patents 5,055,942 and - * 5,917,614, and corresponding international patents. This version - * of ETS is for commercial licensees and is governed by the licensing - * agreement between artofcode LLC and the licensee. Please see - * http://www.artofcode.com/eventone/ for information on licensing. - * - * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. - * - * All Rights Reserved. - * - * This software is provided AS-IS with no warranty, either express or - * implied. - * - * This software is distributed under license and may not be copied, - * modified or distributed except as expressly authorized under the terms - * of the license contained in the file LICENSE in this distribution. - */ +/* Copyright (C) 2013-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ #ifndef ets_h_INCLUDED # define ets_h_INCLUDED diff --git a/base/ets_tm.h b/base/ets_tm.h index 61318977..ab737162 100644 --- a/base/ets_tm.h +++ b/base/ets_tm.h @@ -1,26 +1,17 @@ -/* - * Testbed implementation of Even Better Screening. Please see - * http://www.artofcode.com/eventone/ for more details. - * - * Copyright 2001-2004 Raph Levien <raph@acm.org> - * - * Code in this module is covered by US Patents 5,055,942 and - * 5,917,614, and corresponding international patents. This version - * of ETS is for commercial licensees and is governed by the licensing - * agreement between artofcode LLC and the licensee. Please see - * http://www.artofcode.com/eventone/ for information on licensing. - * - * Subsequent Changes: Copyright (C) 2013-2021 Artifex Software, Inc. - * - * All Rights Reserved. - * - * This software is provided AS-IS with no warranty, either express or - * implied. - * - * This software is distributed under license and may not be copied, - * modified or distributed except as expressly authorized under the terms - * of the license contained in the file LICENSE in this distribution. - */ +/* Copyright (C) 2013-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ #ifndef ets_tm_h_INCLUDED diff --git a/base/fapi_ft.c b/base/fapi_ft.c index e4d935d9..4b4b6857 100644 --- a/base/fapi_ft.c +++ b/base/fapi_ft.c @@ -56,6 +56,7 @@ #include FT_IMAGE_H #include FT_BITMAP_H #include FT_TRUETYPE_DRIVER_H +#include FT_TRUETYPE_TABLES_H #include FT_MULTIPLE_MASTERS_H #include FT_TYPE1_TABLES_H @@ -1381,7 +1382,8 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font, for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { if (a_font->ttf_cmap_req[i].platform_id > 0) { for (j = 0; j < face->ft_face->num_charmaps; j++) { - if (face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id + if (FT_Get_CMap_Format(face->ft_face->charmaps[j]) >= 0 + && face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) { cmap = face->ft_face->charmaps[j]; diff --git a/base/gdbflags.h b/base/gdbflags.h index 073ca73f..8f044b4a 100644 --- a/base/gdbflags.h +++ b/base/gdbflags.h @@ -32,7 +32,7 @@ FLAG(epo_details, 5, 0, "Erasepage Optimization tracing"), FLAG(epo_install_only, 6, 0, "Erasepage Optimization install only (for debugging subclass)"), FLAG(init_details, 7, 0, "Language initialisation (detail)"), FLAG(overprint, 8, 0, "Overprint"), -UNUSED(9) +FLAG(clist_color, 9, 0, "Clist color"), UNUSED(10) UNUSED(11) UNUSED(12) diff --git a/base/gdevabuf.c b/base/gdevabuf.c index 1f7c3902..e22418a3 100644 --- a/base/gdevabuf.c +++ b/base/gdevabuf.c @@ -32,100 +32,6 @@ * useful for other things someday. */ -/* We can't initialize the device descriptor statically very well, */ -/* so we patch up the image2 or image4 descriptor. */ -static dev_proc_map_rgb_color(mem_alpha_map_rgb_color); -static dev_proc_map_color_rgb(mem_alpha_map_color_rgb); -static dev_proc_map_rgb_alpha_color(mem_alpha_map_rgb_alpha_color); -static dev_proc_copy_alpha(mem_alpha_copy_alpha); - -void -gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem, - gx_device * target, int alpha_bits) -{ - gs_make_mem_device(adev, gdev_mem_device_for_bits(alpha_bits), - mem, 0, target); - /* This is a black-and-white device ... */ - adev->color_info = gdev_mem_device_for_bits(1)->color_info; - /* ... but it has multiple bits per pixel ... */ - adev->color_info.depth = alpha_bits; - adev->graphics_type_tag = target->graphics_type_tag; - /* ... and different color mapping. */ - set_dev_proc(adev, map_rgb_color, mem_alpha_map_rgb_color); - set_dev_proc(adev, map_color_rgb, mem_alpha_map_color_rgb); - set_dev_proc(adev, map_rgb_alpha_color, mem_alpha_map_rgb_alpha_color); - set_dev_proc(adev, copy_alpha, mem_alpha_copy_alpha); -} - -/* Reimplement color mapping. */ -static gx_color_index -mem_alpha_map_rgb_color(gx_device * dev, const gx_color_value cv[]) -{ - gx_device_memory * const mdev = (gx_device_memory *)dev; - gx_color_index color = gx_forward_map_rgb_color(dev, cv); - - return (color == 0 || color == gx_no_color_index ? color : - (((gx_color_index)1 << mdev->log2_alpha_bits) - 1)); -} -static int -mem_alpha_map_color_rgb(gx_device * dev, gx_color_index color, - gx_color_value prgb[3]) -{ - return - gx_forward_map_color_rgb(dev, - (color == 0 ? color : (gx_color_index) 1), - prgb); -} -static gx_color_index -mem_alpha_map_rgb_alpha_color(gx_device * dev, gx_color_value r, - gx_color_value g, gx_color_value b, gx_color_value alpha) -{ - gx_device_memory * const mdev = (gx_device_memory *)dev; - gx_color_index color; - gx_color_value cv[3]; - - cv[0] = r; cv[1] = g; cv[2] = b; - color = gx_forward_map_rgb_color(dev, cv); - - return (color == 0 || color == gx_no_color_index ? color : - (gx_color_index) (alpha >> (gx_color_value_bits - - mdev->log2_alpha_bits))); -} -/* Implement alpha copying. */ -static int -mem_alpha_copy_alpha(gx_device * dev, const byte * data, int data_x, - int raster, gx_bitmap_id id, int x, int y, int width, int height, - gx_color_index color, int depth) -{ /* Just use copy_color. */ - if (depth == 8) { - /* We don't support depth=8 in this function, but this doesn't - * matter, because: - * 1) This code is only called for dTextAlphaBits > 0, when - * DisableFAPI=true. And we don't support DisableFAPI. - * 2) Even if we did support DisableFAPI, this can never actually - * be called because gx_compute_text_oversampling arranges that - * log2_scale.{x,y} sum to <= alpha_bits, and this code is only - * called if it sums to MORE than alpha_bits. - * 3) Even if copy_alpha DID somehow manage to be called, the - * only place that uses depth==8 is the imagemask interpolation - * code, and that can never hit this code. (Type 3 fonts might - * include Imagemasks, but those don't go through FAPI). - * - * If in the future we ever rearrange the conditions under which - * this code is called (so that it CAN be called with depth == 8) - * then this will probably be best implemented by decimating the - * input alpha values to either 2 or 4 bits as appropriate and - * then recursively calling us back. - */ - return_error(gs_error_unknownerror); - } - return (color == 0 ? - (*dev_proc(dev, fill_rectangle)) (dev, x, y, width, height, - color) : - (*dev_proc(dev, copy_color)) (dev, data, data_x, raster, id, - x, y, width, height)); -} - /* ================ Alpha-buffer device ================ */ /* @@ -170,11 +76,22 @@ static dev_proc_get_clipping_box(mem_abuf_get_clipping_box); static dev_proc_fill_rectangle_hl_color(mem_abuf_fill_rectangle_hl_color); /* The device descriptor. */ +static void +mem_alpha_initialize_device_procs(gx_device *dev) +{ + mem_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, mem_abuf_fill_rectangle); + set_dev_proc(dev, copy_mono, mem_abuf_copy_mono); + set_dev_proc(dev, copy_color, gx_default_copy_color); + set_dev_proc(dev, strip_copy_rop2, gx_no_strip_copy_rop2); + set_dev_proc(dev, fill_rectangle_hl_color, mem_abuf_fill_rectangle_hl_color); +} + static const gx_device_memory mem_alpha_buffer_device = -mem_device_hl("image(alpha buffer)", 0, 1, - gx_forward_map_rgb_color, gx_forward_map_color_rgb, - mem_abuf_copy_mono, gx_default_copy_color, mem_abuf_fill_rectangle, - gx_no_strip_copy_rop, mem_abuf_fill_rectangle_hl_color); + mem_device("image(alpha buffer)", 0, 1, mem_alpha_initialize_device_procs); /* Make an alpha-buffer memory device. */ /* We use abuf instead of alpha_buffer because */ @@ -406,11 +323,13 @@ mem_abuf_copy_mono(gx_device * dev, code = y_transfer_next(&yt, dev); if (code < 0) return code; - (*dev_proc(&mem_mono_device, copy_mono)) (dev, - base + (yt.y_next - y) * sraster, - sourcex, sraster, gx_no_bitmap_id, - x, yt.transfer_y, w, yt.transfer_height, - gx_no_color_index, (gx_color_index) 1); + code = mem_mono_copy_mono(dev, + base + (yt.y_next - y) * sraster, + sourcex, sraster, gx_no_bitmap_id, + x, yt.transfer_y, w, yt.transfer_height, + gx_no_color_index, (gx_color_index) 1); + if (code < 0) + return code; } return 0; } @@ -442,9 +361,11 @@ mem_abuf_fill_rectangle(gx_device * dev, int x, int y, int w, int h, code = y_transfer_next(&yt, dev); if (code < 0) return code; - (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, - x, yt.transfer_y, w, yt.transfer_height, - (gx_color_index) 1); + code = mem_mono_fill_rectangle(dev, x, yt.transfer_y, + w, yt.transfer_height, + (gx_color_index) 1); + if (code < 0) + return code; } return 0; } @@ -484,9 +405,11 @@ mem_abuf_fill_rectangle_hl_color(gx_device * dev, const gs_fixed_rect *rect, code = y_transfer_next(&yt, dev); if (code < 0) return code; - (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, - x, yt.transfer_y, w, yt.transfer_height, - (gx_color_index) 1); + code = mem_mono_fill_rectangle(dev, x, yt.transfer_y, + w, yt.transfer_height, + (gx_color_index) 1); + if (code < 0) + return code; } return 0; } diff --git a/base/gdevbbox.c b/base/gdevbbox.c index 542124a9..ac5c2e8b 100644 --- a/base/gdevbbox.c +++ b/base/gdevbbox.c @@ -52,14 +52,45 @@ static dev_proc_fill_parallelogram(bbox_fill_parallelogram); static dev_proc_fill_triangle(bbox_fill_triangle); static dev_proc_draw_thin_line(bbox_draw_thin_line); static dev_proc_strip_tile_rectangle(bbox_strip_tile_rectangle); -static dev_proc_strip_copy_rop(bbox_strip_copy_rop); static dev_proc_strip_copy_rop2(bbox_strip_copy_rop2); static dev_proc_strip_tile_rect_devn(bbox_strip_tile_rect_devn); static dev_proc_begin_typed_image(bbox_begin_typed_image); -static dev_proc_create_compositor(bbox_create_compositor); +static dev_proc_composite(bbox_composite); static dev_proc_text_begin(bbox_text_begin); static dev_proc_fillpage(bbox_fillpage); +static void +bbox_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, bbox_open_device); + set_dev_proc(dev, get_initial_matrix, gx_upright_get_initial_matrix); + set_dev_proc(dev, output_page, bbox_output_page); + set_dev_proc(dev, close_device, bbox_close_device); + set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb); + set_dev_proc(dev, fill_rectangle, bbox_fill_rectangle); + set_dev_proc(dev, copy_mono, bbox_copy_mono); + set_dev_proc(dev, copy_color, bbox_copy_color); + set_dev_proc(dev, get_params, bbox_get_params); + set_dev_proc(dev, put_params, bbox_put_params); + set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); + set_dev_proc(dev, copy_alpha, bbox_copy_alpha); + set_dev_proc(dev, fill_path, bbox_fill_path); + set_dev_proc(dev, stroke_path, bbox_stroke_path); + set_dev_proc(dev, fill_mask, bbox_fill_mask); + set_dev_proc(dev, fill_trapezoid, bbox_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, bbox_fill_parallelogram); + set_dev_proc(dev, fill_triangle, bbox_fill_triangle); + set_dev_proc(dev, draw_thin_line, bbox_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, bbox_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, bbox_begin_typed_image); + set_dev_proc(dev, composite, bbox_composite); + set_dev_proc(dev, text_begin, bbox_text_begin); + set_dev_proc(dev, fillpage, bbox_fillpage); + set_dev_proc(dev, strip_copy_rop2, bbox_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, bbox_strip_tile_rect_devn); +} + /* The device prototype */ /* * Normally this would be static, but if the device is going to be used @@ -85,82 +116,11 @@ gx_device_bbox gs_bbox_device = /* * Define the device as 8-bit gray scale to avoid computing halftones. */ - std_device_dci_body(gx_device_bbox, 0, "bbox", + std_device_dci_body(gx_device_bbox, bbox_initialize_device_procs, "bbox", MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, 1, 8, 255, 0, 256, 1), - {bbox_open_device, - gx_upright_get_initial_matrix, - NULL, /* sync_output */ - bbox_output_page, - bbox_close_device, - gx_default_gray_map_rgb_color, - gx_default_gray_map_color_rgb, - bbox_fill_rectangle, - NULL, /* tile_rectangle */ - bbox_copy_mono, - bbox_copy_color, - NULL, /* draw_line */ - NULL, /* get_bits */ - bbox_get_params, - bbox_put_params, - gx_default_map_cmyk_color, - NULL, /* get_xfont_procs */ - NULL, /* get_xfont_device */ - gx_default_map_rgb_alpha_color, - gx_page_device_get_page_device, - NULL, /* get_alpha_bits */ - bbox_copy_alpha, - NULL, /* get_band */ - NULL, /* copy_rop */ - bbox_fill_path, - bbox_stroke_path, - bbox_fill_mask, - bbox_fill_trapezoid, - bbox_fill_parallelogram, - bbox_fill_triangle, - bbox_draw_thin_line, - gx_default_begin_image, - NULL, /* image_data */ - NULL, /* end_image */ - bbox_strip_tile_rectangle, - bbox_strip_copy_rop, - NULL, /* get_clipping_box */ - bbox_begin_typed_image, - NULL, /* get_bits_rectangle */ - gx_default_map_color_rgb_alpha, - bbox_create_compositor, - NULL, /* get_hardware_params */ - bbox_text_begin, - NULL, /* finish_copydevice */ - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - NULL, /* get_color_mapping_procs */ - NULL, /* get_color_comp_index */ - NULL, /* encode_color */ - NULL, /* decode_color */ - NULL, /* pattern_manage */ - NULL, /* fill_rectangle_hl_color */ - NULL, /* include_color_space */ - NULL, /* fill_linear_color_scanline */ - NULL, /* fill_linear_color_trapezoid */ - NULL, /* fill_linear_color_triangle */ - NULL, /* update_spot_equivalent_colors */ - NULL, /* ret_devn_params */ - bbox_fillpage, /* fillpage */ - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - NULL, /* dev_spec_op */ - NULL, /* copy_planes */ - NULL, /* get_profile */ - NULL, /* set_graphics_type_tag */ - bbox_strip_copy_rop2, - bbox_strip_tile_rect_devn - }, + { 0 }, 0, /* target */ 1, /*true *//* free_standing */ 1 /*true *//* forward_open_close */ @@ -275,15 +235,15 @@ bbox_close_device(gx_device * dev) void gx_device_bbox_init(gx_device_bbox * dev, gx_device * target, gs_memory_t *mem) { - gx_device_init((gx_device *) dev, (const gx_device *)&gs_bbox_device, - (target ? target->memory : mem), true); + /* Can never fail */ + (void)gx_device_init((gx_device *) dev, (const gx_device *)&gs_bbox_device, + (target ? target->memory : mem), true); if (target) { gx_device_forward_fill_in_procs((gx_device_forward *) dev); set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); - set_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color); set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); set_dev_proc(dev, encode_color, gx_forward_encode_color); @@ -417,7 +377,8 @@ bbox_fill_rectangle(gx_device * dev, int x, int y, int w, int h, { gx_device_bbox *const bdev = (gx_device_bbox *) dev; gx_device *tdev = bdev->target; - /* gx_forward_fill_rectangle doesn't exist */ + /* gx_forward_fill_rectangle exists, but does the wrong thing in + * the event of a NULL target, so open code it here. */ int code = (tdev == 0 ? 0 : dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color)); @@ -432,7 +393,8 @@ bbox_copy_mono(gx_device * dev, const byte * data, gx_color_index zero, gx_color_index one) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - /* gx_forward_copy_mono doesn't exist */ + /* gx_forward_copy_mono exists, but does the wrong thing in + * the event of a NULL target, so open code it here. */ gx_device *tdev = bdev->target; int code = (tdev == 0 ? 0 : @@ -451,7 +413,8 @@ bbox_copy_color(gx_device * dev, const byte * data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - /* gx_forward_copy_color doesn't exist */ + /* gx_forward_copy_color exists, but does the wrong thing in + * the event of a NULL target, so open code it here. */ gx_device *tdev = bdev->target; int code = (tdev == 0 ? 0 : @@ -468,7 +431,8 @@ bbox_copy_alpha(gx_device * dev, const byte * data, int data_x, gx_color_index color, int depth) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - /* gx_forward_copy_alpha doesn't exist */ + /* gx_forward_copy_alpha exists, but does the wrong thing in + * the event of a NULL target, so open code it here. */ gx_device *tdev = bdev->target; int code = (tdev == 0 ? 0 : @@ -512,29 +476,6 @@ bbox_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, } static int -bbox_strip_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, - gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int w, int h, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_bbox *const bdev = (gx_device_bbox *) dev; - /* gx_forward_strip_copy_rop doesn't exist */ - gx_device *tdev = bdev->target; - int code = - (tdev == 0 ? 0 : - dev_proc(tdev, strip_copy_rop) - (tdev, sdata, sourcex, sraster, id, scolors, - textures, tcolors, x, y, w, h, phase_x, phase_y, lop)); - - BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h); - return code; -} - -static int bbox_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, @@ -546,7 +487,8 @@ bbox_strip_copy_rop2(gx_device * dev, uint planar_height) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - /* gx_forward_strip_copy_rop doesn't exist */ + /* gx_forward_strip_copy_rop2 exists, but does the wrong thing in + * the event of a NULL target, so open code it here. */ gx_device *tdev = bdev->target; int code = (tdev == 0 ? 0 : @@ -817,8 +759,7 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, gx_device_bbox *const bdev = (gx_device_bbox *) dev; gx_device *tdev = bdev->target; dev_proc_fill_path((*fill_path)) = - (tdev == 0 ? dev_proc(&gs_null_device, fill_path) : - dev_proc(tdev, fill_path)); + (tdev == 0 ? NULL : dev_proc(tdev, fill_path)); int code; gx_drawing_color devc; @@ -846,18 +787,25 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, * If the path lies within the already accumulated box, just draw * on the target. */ - if (BBOX_IN_RECT(bdev, &ibox)) + if (BBOX_IN_RECT(bdev, &ibox)) { + /* If we have no target device, just exit */ + if (fill_path == NULL) + return 0; return fill_path(tdev, pgs, ppath, params, pdevc, pcpath); - /* - * If the target uses the default algorithm, just draw on the - * bbox device. - */ - if (tdev != 0 && fill_path == gx_default_fill_path) - return fill_path(dev, pgs, ppath, params, pdevc, pcpath); - /* Draw on the target now. */ - code = fill_path(tdev, pgs, ppath, params, pdevc, pcpath); - if (code < 0) - return code; + } + if (tdev != 0) { + /* + * If the target uses the default algorithm, just draw on the + * bbox device. + */ + if (fill_path == gx_default_fill_path) + return fill_path(dev, pgs, ppath, params, pdevc, pcpath); + /* Draw on the target now. */ + code = fill_path(tdev, pgs, ppath, params, pdevc, pcpath); + if (code < 0) + return code; + } + /* Previously we would use the path bbox above usually, but that bbox is * inaccurate for curves, because it considers the control points of the * curves to be included whcih of course they are not. Now we scan-convert @@ -873,7 +821,9 @@ bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, code = gx_default_fill_path(dev, pgs, ppath, params, &devc, pcpath); bdev->target = tdev; return code; - } else + } else if (fill_path == NULL) + return 0; + else return fill_path(tdev, pgs, ppath, params, pdevc, pcpath); } @@ -950,8 +900,9 @@ bbox_fill_mask(gx_device * dev, pdcolor, depth, lop, pcpath); bdev->target = tdev; } else { - /* Just use the mask bounding box. */ - BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h); + if (w > 0 && h > 0) + /* Just use the mask bounding box. */ + BBOX_ADD_INT_RECT(bdev, x, y, x + w, y + h); } return code; } @@ -1010,15 +961,8 @@ bbox_image_begin(const gs_gstate * pgs, const gs_matrix * pmat, pbe->x0 = prect->p.x, pbe->x1 = prect->q.x; pbe->y = prect->p.y, pbe->height = prect->q.y - prect->p.y; } else { - gs_int_point size; - int code = (*pic->type->source_size) (pgs, pic, &size); - - if (code < 0) { - gs_free_object(memory, pbe, "bbox_image_begin"); - return code; - } - pbe->x0 = 0, pbe->x1 = size.x; - pbe->y = 0, pbe->height = size.y; + pbe->x0 = 0, pbe->x1 = pic->Width; + pbe->y = 0, pbe->height = pic->Height; } *ppbe = pbe; return 0; @@ -1051,7 +995,7 @@ bbox_begin_typed_image(gx_device * dev, if (code < 0) return code; /* - * If there is no target, we still have to call default_begin_image + * If there is no target, we still have to call default_begin_typed_image * to get the correct num_planes and plane_depths. */ { @@ -1145,8 +1089,9 @@ bbox_image_plane_data(gx_image_enum_common_t * info, bx2, by2, &devc, lop_default); bdev->target = tdev; } else { - /* Just use the bounding box. */ - BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); + /* Just use the bounding box if the image is not 0 width or height */ + if (ibox.p.x != ibox.q.x && ibox.p.y != ibox.q.y) + BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); } return code; } @@ -1218,7 +1163,7 @@ static const gx_device_bbox_procs_t box_procs_forward = { }; static int -bbox_create_compositor(gx_device * dev, +bbox_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * memory, gx_device *cindev) { @@ -1241,7 +1186,7 @@ bbox_create_compositor(gx_device * dev, { gx_device *temp_cdev; gx_device_bbox *bbcdev; - int code = (*dev_proc(target, create_compositor)) + int code = (*dev_proc(target, composite)) (target, &temp_cdev, pcte, pgs, memory, cindev); /* If the target did not create a new compositor then we are done. */ @@ -1251,7 +1196,7 @@ bbox_create_compositor(gx_device * dev, } bbcdev = gs_alloc_struct_immovable(memory, gx_device_bbox, &st_device_bbox, - "bbox_create_compositor"); + "bbox_composite"); if (bbcdev == 0) { (*dev_proc(temp_cdev, close_device)) (temp_cdev); return_error(gs_error_VMerror); @@ -1272,13 +1217,12 @@ bbox_create_compositor(gx_device * dev, static int bbox_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, - gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, - gs_memory_t * memory, gs_text_enum_t ** ppenum) + gs_text_enum_t ** ppenum) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - int code = gx_default_text_begin(dev, pgs, text, font, path, pdcolor, - pcpath, memory, ppenum); + int code = gx_default_text_begin(dev, pgs, text, font, + pcpath, ppenum); if (code >=0 && bdev->target != NULL) { /* See note on imaging_dev in gxtext.h */ diff --git a/base/gdevdbit.c b/base/gdevdbit.c index aba17446..a04e0b33 100644 --- a/base/gdevdbit.c +++ b/base/gdevdbit.c @@ -28,21 +28,6 @@ #undef mdev #include "gxcpath.h" -/* By default, implement tile_rectangle using strip_tile_rectangle. */ -int -gx_default_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile, - int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, - int px, int py) -{ - gx_strip_bitmap tiles; - - *(gx_tile_bitmap *) & tiles = *tile; - tiles.shift = tiles.rep_shift = 0; - tiles.num_planes = 1; - return (*dev_proc(dev, strip_tile_rectangle)) - (dev, &tiles, x, y, w, h, color0, color1, px, py); -} - /* Implement copy_mono by filling lots of small rectangles. */ /* This is very inefficient, but it works as a default. */ int @@ -241,7 +226,7 @@ gx_default_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * out_raster; code = dev_proc(dev, get_bits_rectangle) (dev, &gb_rect, - &gb_params, 0); + &gb_params); src_planes[k] = gb_params.data[k]; if (code < 0) { gs_free_object(mem, gb_buff, "copy_alpha_hl_color"); @@ -370,6 +355,7 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x, int code = 0; gx_color_value color_cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; int ry, lx; + gs_int_rect rect; fit_copy(dev, data, data_x, raster, id, x, y, width, height); row = data; @@ -381,6 +367,8 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x, goto out; } (*dev_proc(dev, decode_color)) (dev, color, color_cv); + rect.p.x = 0; + rect.q.x = dev->width; for (ry = y; ry < y + height; row += raster, ++ry) { byte *line; int sx, rx; @@ -389,10 +377,23 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x, int l_dbit = 0; byte l_dbyte = ((l_dbit) ? (byte)(*(l_dptr) & (0xff00 >> (l_dbit))) : 0); int l_xprev = x; - - code = (*dev_proc(dev, get_bits)) (dev, ry, lin, &line); + gs_get_bits_params_t params; + + params.options = (GB_ALIGN_ANY | + (GB_RETURN_COPY | GB_RETURN_POINTER) | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.x_offset = 0; + params.raster = bitmap_raster(dev->width * dev->color_info.depth); + params.data[0] = lin; + rect.p.y = ry; + rect.q.y = ry+1; + code = (*dev_proc(dev, get_bits_rectangle))(dev, &rect, + ¶ms); if (code < 0) break; + line = params.data[0]; lx = x; for (sx = data_x, rx = x; sx < data_x + width; ++sx, ++rx) { gx_color_index previous = gx_no_color_index; @@ -530,17 +531,6 @@ gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x, } int -gx_no_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_tile_bitmap * texture, const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - return_error(gs_error_unknownerror); /* not implemented */ -} - -int gx_default_fill_mask(gx_device * orig_dev, const byte * data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, @@ -644,27 +634,7 @@ gx_default_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, } #endif - if (dev_proc(dev, tile_rectangle) != gx_default_tile_rectangle) { - if (shift == 0) { /* - * Temporarily patch the tile_rectangle procedure in the - * device so we don't get into a recursion loop if the - * device has a tile_rectangle procedure that conditionally - * calls the strip_tile_rectangle procedure. - */ - dev_proc_tile_rectangle((*tile_proc)) = - dev_proc(dev, tile_rectangle); - int code = 0; - - set_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle); - code = (*tile_proc) - (dev, (const gx_tile_bitmap *)tiles, x, y, w, h, - color0, color1, px, py); - set_dev_proc(dev, tile_rectangle, tile_proc); - return code; - } - /* We should probably optimize this case too, for the benefit */ - /* of window systems, but we don't yet. */ - } { /* + { /* * Note: we can't do the following computations until after * the fit_fill_xy. */ @@ -794,12 +764,13 @@ gx_default_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, } int -gx_no_strip_copy_rop(gx_device * dev, +gx_no_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) + int phase_x, int phase_y, gs_logical_operation_t lop, + uint planar_height) { return_error(gs_error_unknownerror); /* not implemented */ } diff --git a/base/gdevddrw.c b/base/gdevddrw.c index 4f91a02d..1d22e746 100644 --- a/base/gdevddrw.c +++ b/base/gdevddrw.c @@ -955,14 +955,6 @@ gx_default_draw_thin_line(gx_device * dev, } } -/* Stub out the obsolete procedure. */ -int -gx_default_draw_line(gx_device * dev, - int x0, int y0, int x1, int y1, gx_color_index color) -{ - return -1; -} - /* ---------------- Image drawing ---------------- */ /* GC structures for image enumerator */ @@ -980,51 +972,6 @@ static RELOC_PTRS_WITH(image_enum_common_reloc_ptrs, gx_image_enum_common_t *ept } RELOC_PTRS_END -/* - * gx_default_begin_image is only invoked for ImageType 1 images. However, - * the argument types are different, and if the device provides a - * begin_typed_image procedure, we should use it. See gxdevice.h. - */ -static int -gx_no_begin_image(gx_device * dev, - const gs_gstate * pgs, const gs_image_t * pim, - gs_image_format_t format, const gs_int_rect * prect, - const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, - gs_memory_t * memory, gx_image_enum_common_t ** pinfo) -{ - return -1; -} -int -gx_default_begin_image(gx_device * dev, - const gs_gstate * pgs, const gs_image_t * pim, - gs_image_format_t format, const gs_int_rect * prect, - const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, - gs_memory_t * memory, gx_image_enum_common_t ** pinfo) -{ - /* - * Hand off to begin_typed_image, being careful to avoid a - * possible recursion loop. - */ - dev_proc_begin_image((*save_begin_image)) = dev_proc(dev, begin_image); - gs_image_t image; - const gs_image_t *ptim; - int code; - - set_dev_proc(dev, begin_image, gx_no_begin_image); - if (pim->format == format) - ptim = pim; - else { - image = *pim; - image.format = format; - ptim = ℑ - } - code = (*dev_proc(dev, begin_typed_image)) - (dev, pgs, NULL, (const gs_image_common_t *)ptim, prect, pdcolor, - pcpath, memory, pinfo); - set_dev_proc(dev, begin_image, save_begin_image); - return code; -} - int gx_default_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix * pmat, @@ -1032,44 +979,10 @@ gx_default_begin_typed_image(gx_device * dev, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gx_image_enum_common_t ** pinfo) { - /* If this is an ImageType 1 image using the gs_gstate's CTM, - * defer to begin_image. - */ - if (pic->type->begin_typed_image == gx_begin_image1) { - const gs_image_t *pim = (const gs_image_t *)pic; - - if (pmat == 0 || - (pgs != 0 && !gs_matrix_compare(pmat, &ctm_only(pgs))) - ) { - int code = (*dev_proc(dev, begin_image)) - (dev, pgs, pim, pim->format, prect, pdcolor, - pcpath, memory, pinfo); - - if (code >= 0) - return code; - } - } return (*pic->type->begin_typed_image) (dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); } -/* Backward compatibility for obsolete driver procedures. */ - -int -gx_default_image_data(gx_device *dev, gx_image_enum_common_t * info, - const byte ** plane_data, - int data_x, uint raster, int height) -{ - return gx_image_data(info, plane_data, data_x, raster, height); -} - -int -gx_default_end_image(gx_device *dev, gx_image_enum_common_t * info, - bool draw_last) -{ - return gx_image_end(info, draw_last); -} - int gx_default_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { diff --git a/base/gdevdevn.c b/base/gdevdevn.c index 692edf76..f6791276 100644 --- a/base/gdevdevn.c +++ b/base/gdevdevn.c @@ -38,7 +38,7 @@ /* Convert a gray color space to DeviceN colorants. */ void -gray_cs_to_devn_cm(gx_device * dev, int * map, frac gray, frac out[]) +gray_cs_to_devn_cm(const gx_device * dev, int * map, frac gray, frac out[]) { int i = dev->color_info.num_components - 1; @@ -50,7 +50,7 @@ gray_cs_to_devn_cm(gx_device * dev, int * map, frac gray, frac out[]) /* Convert an RGB color space to DeviceN colorants. */ void -rgb_cs_to_devn_cm(gx_device * dev, int * map, +rgb_cs_to_devn_cm(const gx_device * dev, int * map, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { int i = dev->color_info.num_components - 1; @@ -71,7 +71,7 @@ rgb_cs_to_devn_cm(gx_device * dev, int * map, /* Convert a CMYK color space to DeviceN colorants. */ void -cmyk_cs_to_devn_cm(gx_device * dev, const int * map, +cmyk_cs_to_devn_cm(const gx_device * dev, const int * map, frac c, frac m, frac y, frac k, frac out[]) { int i = dev->color_info.num_components - 1; @@ -845,8 +845,19 @@ devn_printer_put_params(gx_device * pdev, gs_param_list * plist, !devn_params_equal(pdevn_params, &saved_devn_params) || (pequiv_colors != NULL && compare_equivalent_cmyk_color_params(pequiv_colors, &saved_equiv_colors))) { - gs_closedevice(pdev); - /* Reset the sparable and linear shift, masks, bits. */ + gx_device *parent_dev = pdev; + gx_device_color_info resave_info = pdev->color_info; + + while (parent_dev->parent != NULL) + parent_dev = parent_dev->parent; + + /* Temporarily restore the old color_info, so the close happens with + * the old version. In particular this allows Nup to flush properly. */ + pdev->color_info = save_info; + gs_closedevice(parent_dev); + /* Then put the shiny new color_info back in. */ + pdev->color_info = resave_info; + /* Reset the separable and linear shift, masks, bits. */ set_linear_color_bits_mask_shift(pdev); } /* @@ -940,71 +951,21 @@ gs_public_st_composite_final(st_gx_devn_prn_device, gx_devn_prn_device, "gx_devn_prn_device", gx_devn_prn_device_enum_ptrs, gx_devn_prn_device_reloc_ptrs, static_gx_devn_prn_device_finalize); -/* - * Macro definition for DeviceN procedures - */ -#define device_procs()\ -{ spotcmyk_prn_open,\ - gx_default_get_initial_matrix,\ - NULL, /* sync_output */\ - gdev_prn_output_page, /* output_page */\ - gdev_prn_close, /* close */\ - NULL, /* map_rgb_color - not used */\ - NULL, /* map_color_rgb - not used */\ - NULL, /* fill_rectangle */\ - NULL, /* tile_rectangle */\ - NULL, /* copy_mono */\ - NULL, /* copy_color */\ - NULL, /* draw_line */\ - NULL, /* get_bits */\ - gx_devn_prn_get_params, /* get_params */\ - gx_devn_prn_put_params, /* put_params */\ - NULL, /* map_cmyk_color - not used */\ - NULL, /* get_xfont_procs */\ - NULL, /* get_xfont_device */\ - NULL, /* map_rgb_alpha_color */\ - gx_page_device_get_page_device, /* get_page_device */\ - NULL, /* get_alpha_bits */\ - NULL, /* copy_alpha */\ - NULL, /* get_band */\ - NULL, /* copy_rop */\ - NULL, /* fill_path */\ - NULL, /* stroke_path */\ - NULL, /* fill_mask */\ - NULL, /* fill_trapezoid */\ - NULL, /* fill_parallelogram */\ - NULL, /* fill_triangle */\ - NULL, /* draw_thin_line */\ - NULL, /* begin_image */\ - NULL, /* image_data */\ - NULL, /* end_image */\ - NULL, /* strip_tile_rectangle */\ - NULL, /* strip_copy_rop */\ - NULL, /* get_clipping_box */\ - NULL, /* begin_typed_image */\ - NULL, /* get_bits_rectangle */\ - NULL, /* map_color_rgb_alpha */\ - NULL, /* create_compositor */\ - NULL, /* get_hardware_params */\ - NULL, /* text_begin */\ - NULL, /* finish_copydevice */\ - NULL, /* begin_transparency_group */\ - NULL, /* end_transparency_group */\ - NULL, /* begin_transparency_mask */\ - NULL, /* end_transparency_mask */\ - NULL, /* discard_transparency_layer */\ - gx_devn_prn_get_color_mapping_procs,/* get_color_mapping_procs */\ - gx_devn_prn_get_color_comp_index,/* get_color_comp_index */\ - gx_devn_prn_encode_color, /* encode_color */\ - gx_devn_prn_decode_color, /* decode_color */\ - NULL, /* pattern_manage */\ - NULL, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - gx_devn_prn_update_spot_equivalent_colors,/* update_spot_equivalent_colors */\ - gx_devn_prn_ret_devn_params /* ret_devn_params */\ +static void +devicen_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, spotcmyk_prn_open); + set_dev_proc(dev, output_page, gdev_prn_output_page); + set_dev_proc(dev, close_device, gdev_prn_close); + set_dev_proc(dev, get_params, gx_devn_prn_get_params); + set_dev_proc(dev, put_params, gx_devn_prn_put_params); + set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); + set_dev_proc(dev, get_color_mapping_procs, gx_devn_prn_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_devn_prn_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_devn_prn_encode_color); + set_dev_proc(dev, decode_color, gx_devn_prn_decode_color); + set_dev_proc(dev, update_spot_equivalent_colors, gx_devn_prn_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_devn_prn_ret_devn_params); } fixed_colorant_name DeviceGrayComponents[] = { @@ -1027,8 +988,8 @@ fixed_colorant_name DeviceCMYKComponents[] = { 0 /* List terminator */ }; -#define gx_devn_prn_device_body(procs, dname, ncomp, pol, depth, mg, mc, cn)\ - std_device_full_body_type_extended(gx_devn_prn_device, &procs, dname,\ +#define gx_devn_prn_device_body(init, dname, ncomp, pol, depth, mg, mc, cn)\ + std_device_full_body_type_extended(gx_devn_prn_device, init, dname,\ &st_gx_devn_prn_device,\ (int)((long)(DEFAULT_WIDTH_10THS) * (X_DPI) / 10),\ (int)((long)(DEFAULT_HEIGHT_10THS) * (Y_DPI) / 10),\ @@ -1049,11 +1010,11 @@ fixed_colorant_name DeviceCMYKComponents[] = { /* * Example device with CMYK and spot color support */ -static const gx_device_procs spot_cmyk_procs = device_procs(); - const gx_devn_prn_device gs_spotcmyk_device = { - gx_devn_prn_device_body(spot_cmyk_procs, "spotcmyk", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 4, 1, 1, "DeviceCMYK"), + gx_devn_prn_device_body(devicen_initialize_device_procs, "spotcmyk", + 4, GX_CINFO_POLARITY_SUBTRACTIVE, 4, 1, 1, + "DeviceCMYK"), /* DeviceN device specific parameters */ { 1, /* Bits per color - must match ncomp, depth, etc. above */ DeviceCMYKComponents, /* Names of color model colorants */ @@ -1069,11 +1030,11 @@ const gx_devn_prn_device gs_spotcmyk_device = /* * Example DeviceN color device */ -static const gx_device_procs devicen_procs = device_procs(); - const gx_devn_prn_device gs_devicen_device = { - gx_devn_prn_device_body(devicen_procs, "devicen", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 32, 255, 255, "DeviceCMYK"), + gx_devn_prn_device_body(devicen_initialize_device_procs, "devicen", + 4, GX_CINFO_POLARITY_SUBTRACTIVE, 32, 255, 255, + "DeviceCMYK"), /* DeviceN device specific parameters */ { 8, /* Bits per color - must match ncomp, depth, etc. above */ DeviceCMYKComponents, /* Names of color model colorants */ @@ -1103,7 +1064,7 @@ spotcmyk_prn_open(gx_device * pdev) /* Color mapping routines for the spotcmyk device */ static void -gray_cs_to_spotcmyk_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_spotcmyk_cm(const gx_device * dev, frac gray, frac out[]) { int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; @@ -1111,7 +1072,7 @@ gray_cs_to_spotcmyk_cm(gx_device * dev, frac gray, frac out[]) } static void -rgb_cs_to_spotcmyk_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_spotcmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; @@ -1120,7 +1081,7 @@ rgb_cs_to_spotcmyk_cm(gx_device * dev, const gs_gstate *pgs, } static void -cmyk_cs_to_spotcmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_spotcmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; @@ -1132,8 +1093,9 @@ static const gx_cm_color_map_procs spotCMYK_procs = { }; const gx_cm_color_map_procs * -gx_devn_prn_get_color_mapping_procs(const gx_device * dev) +gx_devn_prn_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev) { + *map_dev = dev; return &spotCMYK_procs; } @@ -1211,6 +1173,14 @@ gx_devn_prn_ret_devn_params(gx_device * dev) return &pdev->devn_params; } +const gs_devn_params * +gx_devn_prn_ret_devn_params_const(const gx_device * dev) +{ + const gx_devn_prn_device *pdev = (const gx_devn_prn_device *)dev; + + return &pdev->devn_params; +} + /* * Device proc for updating the equivalent CMYK color for spot colors. */ @@ -1882,7 +1852,7 @@ devn_pcx_write_page(gx_device_printer * pdev, gp_file * infile, int linesize, gp /* If needed, convert to rgb */ if (convert_to_rgb) { int i; - byte *row_in = line; + byte *row_in = line; /* Transform the data. */ row = rgb_buff; /* adjust to converted output buffer */ diff --git a/base/gdevdevn.h b/base/gdevdevn.h index fb34e1c0..89d7b882 100644 --- a/base/gdevdevn.h +++ b/base/gdevdevn.h @@ -21,9 +21,6 @@ #include "gxblend.h" #include "gsequivc.h" -/* See Comments in gdevtsep.c or gdevpsd.c as to the purpose of this */ -#define LIMIT_TO_ICC 1 - /* * Type definitions associated with the fixed color model names. */ @@ -110,12 +107,12 @@ extern fixed_colorant_name DeviceCMYKComponents[]; * Convert standard color spaces into DeviceN colorants. * Note; This routine require SeparationOrder map. */ -void gray_cs_to_devn_cm(gx_device * dev, int * map, frac gray, frac out[]); +void gray_cs_to_devn_cm(const gx_device * dev, int * map, frac gray, frac out[]); -void rgb_cs_to_devn_cm(gx_device * dev, int * map, +void rgb_cs_to_devn_cm(const gx_device * dev, int * map, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); -void cmyk_cs_to_devn_cm(gx_device * dev, const int * map, +void cmyk_cs_to_devn_cm(const gx_device * dev, const int * map, frac c, frac m, frac y, frac k, frac out[]); /* diff --git a/base/gdevdevnprn.h b/base/gdevdevnprn.h index 4d556b60..fb009286 100644 --- a/base/gdevdevnprn.h +++ b/base/gdevdevnprn.h @@ -54,6 +54,7 @@ dev_proc_encode_color(gx_devn_prn_encode_color); dev_proc_decode_color(gx_devn_prn_decode_color); dev_proc_update_spot_equivalent_colors(gx_devn_prn_update_spot_equivalent_colors); dev_proc_ret_devn_params(gx_devn_prn_ret_devn_params); +dev_proc_ret_devn_params_const(gx_devn_prn_ret_devn_params_const); #endif /* ifndef gdevdevnprn_INCLUDED */ diff --git a/base/gdevdflt.c b/base/gdevdflt.c index 4f92c7a2..71d8c1c7 100644 --- a/base/gdevdflt.c +++ b/base/gdevdflt.c @@ -127,18 +127,19 @@ static gx_color_index static bool is_like_DeviceRGB(gx_device * dev) { - subclass_color_mappings scm; frac cm_comp_fracs[3]; int i; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; if ( dev->color_info.num_components != 3 || dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE ) return false; - scm = get_color_mapping_procs_subclass(dev); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* check the values 1/4, 1/3, and 3/4 */ - map_rgb_subclass(scm, 0, frac_1 / 4, frac_1 / 3, 3 * frac_1 / 4,cm_comp_fracs); + cmprocs->map_rgb(cmdev, 0, frac_1 / 4, frac_1 / 3, 3 * frac_1 / 4, cm_comp_fracs); /* verify results to .01 */ cm_comp_fracs[0] -= frac_1 / 4; @@ -159,23 +160,24 @@ is_like_DeviceRGB(gx_device * dev) static bool is_like_DeviceCMYK(gx_device * dev) { - subclass_color_mappings scm; frac cm_comp_fracs[4]; int i; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; if ( dev->color_info.num_components != 4 || dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE ) return false; - scm = get_color_mapping_procs_subclass(dev); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* check the values 1/4, 1/3, 3/4, and 1/8 */ - map_cmyk_subclass( scm, - frac_1 / 4, - frac_1 / 3, - 3 * frac_1 / 4, - frac_1 / 8, - cm_comp_fracs ); + cmprocs->map_cmyk(cmdev, + frac_1 / 4, + frac_1 / 3, + 3 * frac_1 / 4, + frac_1 / 8, + cm_comp_fracs); /* verify results to .01 */ cm_comp_fracs[0] -= frac_1 / 4; @@ -586,7 +588,6 @@ int gx_default_no_copy_alpha_hl_color(gx_device * dev, const byte * data, int da void gx_device_fill_in_procs(register gx_device * dev) { - gx_device_set_procs(dev); fill_dev_proc(dev, open_device, gx_default_open_device); fill_dev_proc(dev, get_initial_matrix, gx_default_get_initial_matrix); fill_dev_proc(dev, sync_output, gx_default_sync_output); @@ -595,22 +596,14 @@ gx_device_fill_in_procs(register gx_device * dev) /* see below for map_rgb_color */ fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb); /* NOT fill_rectangle */ - fill_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle); fill_dev_proc(dev, copy_mono, gx_default_copy_mono); fill_dev_proc(dev, copy_color, gx_default_copy_color); - fill_dev_proc(dev, obsolete_draw_line, gx_default_draw_line); - fill_dev_proc(dev, get_bits, gx_default_get_bits); fill_dev_proc(dev, get_params, gx_default_get_params); fill_dev_proc(dev, put_params, gx_default_put_params); /* see below for map_cmyk_color */ - fill_dev_proc(dev, get_xfont_procs, gx_default_get_xfont_procs); - fill_dev_proc(dev, get_xfont_device, gx_default_get_xfont_device); - fill_dev_proc(dev, map_rgb_alpha_color, gx_default_map_rgb_alpha_color); fill_dev_proc(dev, get_page_device, gx_default_get_page_device); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); fill_dev_proc(dev, copy_alpha, gx_default_copy_alpha); - fill_dev_proc(dev, get_band, gx_default_get_band); - fill_dev_proc(dev, copy_rop, gx_default_copy_rop); fill_dev_proc(dev, fill_path, gx_default_fill_path); fill_dev_proc(dev, stroke_path, gx_default_stroke_path); fill_dev_proc(dev, fill_mask, gx_default_fill_mask); @@ -618,43 +611,16 @@ gx_device_fill_in_procs(register gx_device * dev) fill_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); fill_dev_proc(dev, fill_triangle, gx_default_fill_triangle); fill_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); - fill_dev_proc(dev, begin_image, gx_default_begin_image); - /* - * We always replace get_alpha_bits, image_data, and end_image with the - * new procedures, and, if in a DEBUG configuration, print a warning if - * the definitions aren't the default ones. - */ -#ifdef DEBUG -# define CHECK_NON_DEFAULT(proc, default, procname)\ - BEGIN\ - if ( dev_proc(dev, proc) != NULL && dev_proc(dev, proc) != default )\ - dmprintf2(dev->memory, "**** Warning: device %s implements obsolete procedure %s\n",\ - dev->dname, procname);\ - END -#else -# define CHECK_NON_DEFAULT(proc, default, procname)\ - DO_NOTHING -#endif - CHECK_NON_DEFAULT(get_alpha_bits, gx_default_get_alpha_bits, - "get_alpha_bits"); - set_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); - CHECK_NON_DEFAULT(image_data, gx_default_image_data, "image_data"); - set_dev_proc(dev, image_data, gx_default_image_data); - CHECK_NON_DEFAULT(end_image, gx_default_end_image, "end_image"); - set_dev_proc(dev, end_image, gx_default_end_image); -#undef CHECK_NON_DEFAULT + fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); fill_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); - fill_dev_proc(dev, strip_copy_rop, gx_default_strip_copy_rop); fill_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2); fill_dev_proc(dev, strip_tile_rect_devn, gx_default_strip_tile_rect_devn); fill_dev_proc(dev, get_clipping_box, gx_default_get_clipping_box); fill_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); fill_dev_proc(dev, get_bits_rectangle, gx_default_get_bits_rectangle); - fill_dev_proc(dev, map_color_rgb_alpha, gx_default_map_color_rgb_alpha); - fill_dev_proc(dev, create_compositor, gx_default_create_compositor); + fill_dev_proc(dev, composite, gx_default_composite); fill_dev_proc(dev, get_hardware_params, gx_default_get_hardware_params); fill_dev_proc(dev, text_begin, gx_default_text_begin); - fill_dev_proc(dev, finish_copydevice, gx_default_finish_copydevice); set_dev_proc(dev, encode_color, get_encode_color(dev)); if (dev->color_info.num_components == 3) @@ -727,19 +693,6 @@ gx_device_fill_in_procs(register gx_device * dev) fill_dev_proc(dev, get_profile, gx_default_get_profile); fill_dev_proc(dev, set_graphics_type_tag, gx_default_set_graphics_type_tag); - /* - * If the device is known not to support overprint mode, indicate this now. - * Note that we do not insist that a device be use a strict DeviceCMYK - * encoding; any color model that is subtractive and supports the cyan, - * magenta, yellow, and black color components will do. We defer a more - * explicit check until this information is explicitly required. - */ - if ( dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN && - (dev->color_info.num_components < 4 || - dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE || - dev->color_info.gray_index == GX_CINFO_COMP_NO_INDEX ) ) - dev->color_info.opmode = GX_CINFO_OPMODE_NOT; - fill_dev_proc(dev, fill_rectangle_hl_color, gx_default_fill_rectangle_hl_color); fill_dev_proc(dev, include_color_space, gx_default_include_color_space); fill_dev_proc(dev, fill_linear_color_scanline, gx_default_fill_linear_color_scanline); @@ -757,7 +710,6 @@ gx_device_fill_in_procs(register gx_device * dev) fill_dev_proc(dev, end_transparency_mask, gx_default_end_transparency_mask); fill_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer); - fill_dev_proc(dev, pattern_manage, gx_default_pattern_manage); fill_dev_proc(dev, push_transparency_state, gx_default_push_transparency_state); fill_dev_proc(dev, pop_transparency_state, gx_default_pop_transparency_state); @@ -864,18 +816,6 @@ gx_default_close_device(gx_device * dev) return 0; } -const gx_xfont_procs * -gx_default_get_xfont_procs(gx_device * dev) -{ - return NULL; -} - -gx_device * -gx_default_get_xfont_device(gx_device * dev) -{ - return dev; -} - gx_device * gx_default_get_page_device(gx_device * dev) { @@ -894,12 +834,6 @@ gx_default_get_alpha_bits(gx_device * dev, graphics_object_type type) dev->color_info.anti_alias.graphics_bits); } -int -gx_default_get_band(gx_device * dev, int y, int *band_start) -{ - return 0; -} - void gx_default_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) { @@ -918,7 +852,7 @@ gx_get_largest_clipping_box(gx_device * dev, gs_fixed_rect * pbox) } int -gx_no_create_compositor(gx_device * dev, gx_device ** pcdev, +gx_no_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) @@ -926,7 +860,7 @@ gx_no_create_compositor(gx_device * dev, gx_device ** pcdev, return_error(gs_error_unknownerror); /* not implemented */ } int -gx_default_create_compositor(gx_device * dev, gx_device ** pcdev, +gx_default_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) @@ -935,7 +869,7 @@ gx_default_create_compositor(gx_device * dev, gx_device ** pcdev, (pcte, pcdev, dev, pgs, memory); } int -gx_null_create_compositor(gx_device * dev, gx_device ** pcdev, +gx_null_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) @@ -1001,10 +935,9 @@ gx_default_composite_get_cropping(const gs_composite_t *pxcte, int *ry, int *rhe } int -gx_default_finish_copydevice(gx_device *dev, const gx_device *from_dev) +gx_default_initialize_device(gx_device *dev) { - /* Only allow copying the prototype. */ - return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); + return 0; } int @@ -1028,6 +961,7 @@ gx_default_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) case gxdso_supports_iccpostrender: case gxdso_supports_alpha: case gxdso_pdf14_sep_device: + case gxdso_supports_pattern_transparency: return 0; case gxdso_pattern_shfill_doesnt_need_path: return (dev_proc(pdev, fill_path) == gx_default_fill_path); @@ -1171,12 +1105,6 @@ gx_default_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) } int -gx_default_pattern_manage(gx_device *pdev, gx_bitmap_id id, gs_pattern1_instance_t *pinst, pattern_manage_t function) -{ - return_error(gs_error_undefined); -} - -int gx_default_push_transparency_state(gx_device *dev, gs_gstate *pgs) { return 0; @@ -1236,7 +1164,7 @@ gx_default_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t graphics /* ---------------- Device subclassing procedures ---------------- */ /* Non-obvious code. The 'dest_procs' is the 'procs' memory occupied by the original device that we decided to subclass, - * 'src_procs' is the newly allocated piece of memory, to whch we have already copied the content of the + * 'src_procs' is the newly allocated piece of memory, to which we have already copied the content of the * original device (including the procs), prototype is the device structure prototype for the subclassing device. * Here we copy the methods from the prototype to the original device procs memory *but* if the original (src_procs) * device had a NULL method, we make the new device procs have a NULL method too. @@ -1253,83 +1181,83 @@ gx_default_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t graphics * prototype (subclass device) method if the original device had the default implementation. * I suspect a combination of forwarding and subclassing devices will not work properly for this reason. */ -int gx_copy_device_procs(gx_device *dest, gx_device *src, gx_device *prototype) -{ - set_dev_proc(dest, open_device, dev_proc(prototype, open_device)); - set_dev_proc(dest, get_initial_matrix, dev_proc(prototype, get_initial_matrix)); - set_dev_proc(dest, sync_output, dev_proc(prototype, sync_output)); - set_dev_proc(dest, output_page, dev_proc(prototype, output_page)); - set_dev_proc(dest, close_device, dev_proc(prototype, close_device)); - set_dev_proc(dest, map_rgb_color, dev_proc(prototype, map_rgb_color)); - set_dev_proc(dest, map_color_rgb, dev_proc(prototype, map_color_rgb)); - set_dev_proc(dest, fill_rectangle, dev_proc(prototype, fill_rectangle)); - set_dev_proc(dest, tile_rectangle, dev_proc(prototype, tile_rectangle)); - set_dev_proc(dest, copy_mono, dev_proc(prototype, copy_mono)); - set_dev_proc(dest, copy_color, dev_proc(prototype, copy_color)); - set_dev_proc(dest, obsolete_draw_line, dev_proc(prototype, obsolete_draw_line)); - set_dev_proc(dest, get_bits, dev_proc(prototype, get_bits)); - set_dev_proc(dest, get_params, dev_proc(prototype, get_params)); - set_dev_proc(dest, put_params, dev_proc(prototype, put_params)); - set_dev_proc(dest, map_cmyk_color, dev_proc(prototype, map_cmyk_color)); - set_dev_proc(dest, get_xfont_procs, dev_proc(prototype, get_xfont_procs)); - set_dev_proc(dest, get_xfont_device, dev_proc(prototype, get_xfont_device)); - set_dev_proc(dest, map_rgb_alpha_color, dev_proc(prototype, map_rgb_alpha_color)); - set_dev_proc(dest, get_page_device, dev_proc(prototype, get_page_device)); - set_dev_proc(dest, get_alpha_bits, dev_proc(prototype, get_alpha_bits)); - set_dev_proc(dest, copy_alpha, dev_proc(prototype, copy_alpha)); - set_dev_proc(dest, get_band, dev_proc(prototype, get_band)); - set_dev_proc(dest, copy_rop, dev_proc(prototype, copy_rop)); - set_dev_proc(dest, fill_path, dev_proc(prototype, fill_path)); - set_dev_proc(dest, stroke_path, dev_proc(prototype, stroke_path)); - set_dev_proc(dest, fill_trapezoid, dev_proc(prototype, fill_trapezoid)); - set_dev_proc(dest, fill_parallelogram, dev_proc(prototype, fill_parallelogram)); - set_dev_proc(dest, fill_triangle, dev_proc(prototype, fill_triangle)); - set_dev_proc(dest, draw_thin_line, dev_proc(prototype, draw_thin_line)); - set_dev_proc(dest, begin_image, dev_proc(prototype, begin_image)); - set_dev_proc(dest, image_data, dev_proc(prototype, image_data)); - set_dev_proc(dest, end_image, dev_proc(prototype, end_image)); - set_dev_proc(dest, strip_tile_rectangle, dev_proc(prototype, strip_tile_rectangle)); - set_dev_proc(dest, strip_copy_rop, dev_proc(prototype, strip_copy_rop)); - set_dev_proc(dest, get_clipping_box, dev_proc(prototype, get_clipping_box)); - set_dev_proc(dest, begin_typed_image, dev_proc(prototype, begin_typed_image)); - set_dev_proc(dest, get_bits_rectangle, dev_proc(prototype, get_bits_rectangle)); - set_dev_proc(dest, map_color_rgb_alpha, dev_proc(prototype, map_color_rgb_alpha)); - set_dev_proc(dest, create_compositor, dev_proc(prototype, create_compositor)); - set_dev_proc(dest, get_hardware_params, dev_proc(prototype, get_hardware_params)); - set_dev_proc(dest, text_begin, dev_proc(prototype, text_begin)); - set_dev_proc(dest, finish_copydevice, dev_proc(prototype, finish_copydevice)); - set_dev_proc(dest, discard_transparency_layer, dev_proc(prototype, discard_transparency_layer)); - set_dev_proc(dest, get_color_mapping_procs, dev_proc(prototype, get_color_mapping_procs)); - set_dev_proc(dest, get_color_comp_index, dev_proc(prototype, get_color_comp_index)); - set_dev_proc(dest, encode_color, dev_proc(prototype, encode_color)); - set_dev_proc(dest, decode_color, dev_proc(prototype, decode_color)); - set_dev_proc(dest, pattern_manage, dev_proc(prototype, pattern_manage)); - set_dev_proc(dest, fill_rectangle_hl_color, dev_proc(prototype, fill_rectangle_hl_color)); - set_dev_proc(dest, include_color_space, dev_proc(prototype, include_color_space)); - set_dev_proc(dest, fill_linear_color_scanline, dev_proc(prototype, fill_linear_color_scanline)); - set_dev_proc(dest, fill_linear_color_trapezoid, dev_proc(prototype, fill_linear_color_trapezoid)); - set_dev_proc(dest, fill_linear_color_triangle, dev_proc(prototype, fill_linear_color_triangle)); - set_dev_proc(dest, update_spot_equivalent_colors, dev_proc(prototype, update_spot_equivalent_colors)); - set_dev_proc(dest, ret_devn_params, dev_proc(prototype, ret_devn_params)); - set_dev_proc(dest, fillpage, dev_proc(prototype, fillpage)); - set_dev_proc(dest, push_transparency_state, dev_proc(prototype, push_transparency_state)); - set_dev_proc(dest, pop_transparency_state, dev_proc(prototype, pop_transparency_state)); - set_dev_proc(dest, dev_spec_op, dev_proc(prototype, dev_spec_op)); - set_dev_proc(dest, get_profile, dev_proc(prototype, get_profile)); - set_dev_proc(dest, strip_copy_rop2, dev_proc(prototype, strip_copy_rop2)); - set_dev_proc(dest, strip_tile_rect_devn, dev_proc(prototype, strip_tile_rect_devn)); - set_dev_proc(dest, process_page, dev_proc(prototype, process_page)); - set_dev_proc(dest, transform_pixel_region, dev_proc(prototype, transform_pixel_region)); - set_dev_proc(dest, fill_stroke_path, dev_proc(prototype, fill_stroke_path)); +int gx_copy_device_procs(gx_device *dest, const gx_device *src, const gx_device *pprototype) +{ + gx_device prototype = *pprototype; + + /* In the new (as of 2021) world, the prototype does not contain + * device procs. We need to call the 'initialize_device_procs' + * function to properly populate the procs array. We can't write to + * the const prototype pointer we are passed in, so copy it to a + * local block, and initialize that instead, */ + prototype.initialize_device_procs(&prototype); + /* Fill in missing entries with the global defaults */ + gx_device_fill_in_procs(&prototype); + + if (dest->initialize_device_procs == NULL) + dest->initialize_device_procs = prototype.initialize_device_procs; + + set_dev_proc(dest, initialize_device, dev_proc(&prototype, initialize_device)); + set_dev_proc(dest, open_device, dev_proc(&prototype, open_device)); + set_dev_proc(dest, get_initial_matrix, dev_proc(&prototype, get_initial_matrix)); + set_dev_proc(dest, sync_output, dev_proc(&prototype, sync_output)); + set_dev_proc(dest, output_page, dev_proc(&prototype, output_page)); + set_dev_proc(dest, close_device, dev_proc(&prototype, close_device)); + set_dev_proc(dest, map_rgb_color, dev_proc(&prototype, map_rgb_color)); + set_dev_proc(dest, map_color_rgb, dev_proc(&prototype, map_color_rgb)); + set_dev_proc(dest, fill_rectangle, dev_proc(&prototype, fill_rectangle)); + set_dev_proc(dest, copy_mono, dev_proc(&prototype, copy_mono)); + set_dev_proc(dest, copy_color, dev_proc(&prototype, copy_color)); + set_dev_proc(dest, get_params, dev_proc(&prototype, get_params)); + set_dev_proc(dest, put_params, dev_proc(&prototype, put_params)); + set_dev_proc(dest, map_cmyk_color, dev_proc(&prototype, map_cmyk_color)); + set_dev_proc(dest, get_page_device, dev_proc(&prototype, get_page_device)); + set_dev_proc(dest, get_alpha_bits, dev_proc(&prototype, get_alpha_bits)); + set_dev_proc(dest, copy_alpha, dev_proc(&prototype, copy_alpha)); + set_dev_proc(dest, fill_path, dev_proc(&prototype, fill_path)); + set_dev_proc(dest, stroke_path, dev_proc(&prototype, stroke_path)); + set_dev_proc(dest, fill_trapezoid, dev_proc(&prototype, fill_trapezoid)); + set_dev_proc(dest, fill_parallelogram, dev_proc(&prototype, fill_parallelogram)); + set_dev_proc(dest, fill_triangle, dev_proc(&prototype, fill_triangle)); + set_dev_proc(dest, draw_thin_line, dev_proc(&prototype, draw_thin_line)); + set_dev_proc(dest, strip_tile_rectangle, dev_proc(&prototype, strip_tile_rectangle)); + set_dev_proc(dest, get_clipping_box, dev_proc(&prototype, get_clipping_box)); + set_dev_proc(dest, begin_typed_image, dev_proc(&prototype, begin_typed_image)); + set_dev_proc(dest, get_bits_rectangle, dev_proc(&prototype, get_bits_rectangle)); + set_dev_proc(dest, composite, dev_proc(&prototype, composite)); + set_dev_proc(dest, get_hardware_params, dev_proc(&prototype, get_hardware_params)); + set_dev_proc(dest, text_begin, dev_proc(&prototype, text_begin)); + set_dev_proc(dest, discard_transparency_layer, dev_proc(&prototype, discard_transparency_layer)); + set_dev_proc(dest, get_color_mapping_procs, dev_proc(&prototype, get_color_mapping_procs)); + set_dev_proc(dest, get_color_comp_index, dev_proc(&prototype, get_color_comp_index)); + set_dev_proc(dest, encode_color, dev_proc(&prototype, encode_color)); + set_dev_proc(dest, decode_color, dev_proc(&prototype, decode_color)); + set_dev_proc(dest, fill_rectangle_hl_color, dev_proc(&prototype, fill_rectangle_hl_color)); + set_dev_proc(dest, include_color_space, dev_proc(&prototype, include_color_space)); + set_dev_proc(dest, fill_linear_color_scanline, dev_proc(&prototype, fill_linear_color_scanline)); + set_dev_proc(dest, fill_linear_color_trapezoid, dev_proc(&prototype, fill_linear_color_trapezoid)); + set_dev_proc(dest, fill_linear_color_triangle, dev_proc(&prototype, fill_linear_color_triangle)); + set_dev_proc(dest, update_spot_equivalent_colors, dev_proc(&prototype, update_spot_equivalent_colors)); + set_dev_proc(dest, ret_devn_params, dev_proc(&prototype, ret_devn_params)); + set_dev_proc(dest, fillpage, dev_proc(&prototype, fillpage)); + set_dev_proc(dest, push_transparency_state, dev_proc(&prototype, push_transparency_state)); + set_dev_proc(dest, pop_transparency_state, dev_proc(&prototype, pop_transparency_state)); + set_dev_proc(dest, dev_spec_op, dev_proc(&prototype, dev_spec_op)); + set_dev_proc(dest, get_profile, dev_proc(&prototype, get_profile)); + set_dev_proc(dest, strip_copy_rop2, dev_proc(&prototype, strip_copy_rop2)); + set_dev_proc(dest, strip_tile_rect_devn, dev_proc(&prototype, strip_tile_rect_devn)); + set_dev_proc(dest, process_page, dev_proc(&prototype, process_page)); + set_dev_proc(dest, transform_pixel_region, dev_proc(&prototype, transform_pixel_region)); + set_dev_proc(dest, fill_stroke_path, dev_proc(&prototype, fill_stroke_path)); /* * We absolutely must set the 'set_graphics_type_tag' to the default subclass one * even if the subclassed device is using the default. This is because the * default implementation sets a flag in the device structure, and if we - * copy the default method, we'lll end up setting the flag in the subclassing device + * copy the default method, we'll end up setting the flag in the subclassing device * instead of the subclassed device! */ - set_dev_proc(dest, set_graphics_type_tag, dev_proc(prototype, set_graphics_type_tag)); + set_dev_proc(dest, set_graphics_type_tag, dev_proc(&prototype, set_graphics_type_tag)); /* These are the routines whose existence is checked against the default at * some point in the code. The code path differs when the device implements a @@ -1338,17 +1266,18 @@ int gx_copy_device_procs(gx_device *dest, gx_device *src, gx_device *prototype) * do not overwrite the default method. */ if (dev_proc(src, fill_mask) != gx_default_fill_mask) - set_dev_proc(dest, fill_mask, dev_proc(prototype, fill_mask)); + set_dev_proc(dest, fill_mask, dev_proc(&prototype, fill_mask)); if (dev_proc(src, begin_transparency_group) != gx_default_begin_transparency_group) - set_dev_proc(dest, begin_transparency_group, dev_proc(prototype, begin_transparency_group)); + set_dev_proc(dest, begin_transparency_group, dev_proc(&prototype, begin_transparency_group)); if (dev_proc(src, end_transparency_group) != gx_default_end_transparency_group) - set_dev_proc(dest, end_transparency_group, dev_proc(prototype, end_transparency_group)); + set_dev_proc(dest, end_transparency_group, dev_proc(&prototype, end_transparency_group)); if (dev_proc(src, put_image) != gx_default_put_image) - set_dev_proc(dest, put_image, dev_proc(prototype, put_image)); + set_dev_proc(dest, put_image, dev_proc(&prototype, put_image)); if (dev_proc(src, copy_planes) != gx_default_copy_planes) - set_dev_proc(dest, copy_planes, dev_proc(prototype, copy_planes)); + set_dev_proc(dest, copy_planes, dev_proc(&prototype, copy_planes)); if (dev_proc(src, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) - set_dev_proc(dest, copy_alpha_hl_color, dev_proc(prototype, copy_alpha_hl_color)); + set_dev_proc(dest, copy_alpha_hl_color, dev_proc(&prototype, copy_alpha_hl_color)); + return 0; } @@ -1423,8 +1352,6 @@ int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, uns memset(psubclass_data, 0x00, private_data_size); gx_copy_device_procs(dev_to_subclass, child_dev, new_prototype); - set_dev_proc(dev_to_subclass, fill_rectangle, dev_proc(new_prototype, fill_rectangle)); - set_dev_proc(dev_to_subclass, copy_planes, dev_proc(new_prototype, copy_planes)); dev_to_subclass->finalize = new_prototype->finalize; dev_to_subclass->dname = new_prototype->dname; if (dev_to_subclass->icc_struct) @@ -1434,6 +1361,9 @@ int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, uns if (dev_to_subclass->NupControl) rc_increment(dev_to_subclass->NupControl); + dev_to_subclass->page_procs = new_prototype->page_procs; + gx_subclass_fill_in_page_procs(dev_to_subclass); + /* In case the new device we're creating has already been initialised, copy * its additional data. */ @@ -1484,7 +1414,7 @@ int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, uns return 0; } -int gx_device_unsubclass(gx_device *dev) +void gx_device_unsubclass(gx_device *dev) { generic_subclass_data *psubclass_data; gx_device *parent, *child; @@ -1493,7 +1423,7 @@ int gx_device_unsubclass(gx_device *dev) /* This should not happen... */ if (!dev) - return 0; + return; ref_count = dev->rc.ref_count; child = dev->child; @@ -1503,7 +1433,7 @@ int gx_device_unsubclass(gx_device *dev) /* We need to account for the fact that we are removing ourselves from * the device chain after a clist device has been pushed, due to a - * compositor action. Since we patched the clist 'create_compositor' + * compositor action. Since we patched the clist 'composite' * method (and target device) when it was pushed. * A point to note; we *don't* want to change the forwarding device's * 'target', because when we copy the child up to replace 'this' device @@ -1511,7 +1441,7 @@ int gx_device_unsubclass(gx_device *dev) * device that goes away. */ if (psubclass_data != NULL && psubclass_data->forwarding_dev != NULL && psubclass_data->saved_compositor_method) - psubclass_data->forwarding_dev->procs.create_compositor = psubclass_data->saved_compositor_method; + psubclass_data->forwarding_dev->procs.composite = psubclass_data->saved_compositor_method; /* If ths device's stype is dynamically allocated, keep a copy of it * in case we might need it. @@ -1524,7 +1454,7 @@ int gx_device_unsubclass(gx_device *dev) /* If ths device has any private storage, free it now */ if (psubclass_data) - gs_free_object(dev->memory->non_gc_memory, psubclass_data, "subclass memory for first-last page"); + gs_free_object(dev->memory->non_gc_memory, psubclass_data, "gx_device_unsubclass"); /* Copy the child device into ths device's memory */ if (child) { @@ -1536,62 +1466,67 @@ int gx_device_unsubclass(gx_device *dev) gs_set_object_type(child->memory, dev, b_std); dev->stype = b_std; - /* The reference count of the subclassing device may have been changed - * (eg graphics states pointing to it) after we subclassed the device. We - * need to ensure that we do not overwrite this when we copy back the subclassed - * device. + /* The reference count of the subclassing device may have been + * changed (eg graphics states pointing to it) after we subclassed + * the device. We need to ensure that we do not overwrite this + * when we copy back the subclassed device. */ dev->rc.ref_count = ref_count; - /* If we have a chain of devices, make sure the chain beond the device we're unsubclassing - * doesn't get broken, we needd to detach the lower chain and reattach it at the new - * highest level + /* If we have a chain of devices, make sure the chain beyond the + * device we're unsubclassing doesn't get broken, we need to + * detach the lower chain and reattach it at the new highest level. */ if (child->child) child->child->parent = dev; child->parent->child = child->child; } - /* How can we have a subclass device with no child ? Simples; when we hit the end of job - * restore, the devices are not freed in device chain order. To make sure we don't end up - * following stale pointers, when a device is freed we remove it from the chain and update - * any danlging poitners to NULL. When we later free the remaining devices its possible that - * their child pointer can then be NULL. + /* How can we have a subclass device with no child ? Simples; when we + * hit the end of job restore, the devices are not freed in device + * chain order. To make sure we don't end up following stale pointers, + * when a device is freed we remove it from the chain and update + * any dangling pointers to NULL. When we later free the remaining + * devices it's possible that their child pointer can then be NULL. */ if (child) { if (child->icc_struct) - rc_decrement(child->icc_struct, "gx_unsubclass_device, icc_struct"); + rc_decrement(child->icc_struct, "gx_device_unsubclass, icc_struct"); if (child->PageList) - rc_decrement(child->PageList, "gx_unsubclass_device, PageList"); + rc_decrement(child->PageList, "gx_device_unsubclass, PageList"); if (child->NupControl) - rc_decrement(child->NupControl, "gx_unsubclass_device, NupControl"); - /* we cannot afford to free the child device if its stype is not dynamic because - * we can't 'null' the finalise routine, and we cannot permit the device to be finalised - * because we have copied it up one level, not discarded it. - * (this shouldn't happen! Child devices are always created with a dynamic stype) - * If this ever happens garbage collecton will eventually clean up the memory. + rc_decrement(child->NupControl, "gx_device_unsubclass, NupControl"); + /* We cannot afford to free the child device if its stype is not + * dynamic because we can't 'null' the finalise routine, and we + * cannot permit the device to be finalised because we have copied + * it up one level, not discarded it. (This shouldn't happen! Child + * devices are always created with a dynamic stype.) If this ever + * happens garbage collecton will eventually clean up the memory. */ if (child->stype_is_dynamic) { - /* Make sure that nothing will tyr to follow the device chain, just security here */ + /* Make sure that nothing will try to follow the device chain, + * just security here. */ child->parent = NULL; child->child = NULL; - /* Make certainthe memory will be freed, zap the reference count */ + /* Make certain the memory will be freed, zap the reference count */ child->rc.ref_count = 0; - /* We *don't* want to run the finalize routine. This would free the stype and - * properly handle the icc_struct and PageList, but for devices with a custom - * finalize (eg psdcmyk) it might also free memory it had allocated, and we're - * still pointing at that memory in the parent. - * The indirection through a variable is just to get rid of const warnings. + /* We *don't* want to run the finalize routine. This would free + * the stype and properly handle the icc_struct and PageList, + * but for devices with a custom finalize (eg psdcmyk) it might + * also free memory it had allocated, and we're still pointing + * at that memory in the parent. The indirection through a + * variable is just to get rid of const warnings. */ b_std = (gs_memory_struct_type_t *)child->stype; b_std->finalize = NULL; - /* Having patched the stype, we need to make sure the memory manager uses it. - * It keeps a copy in its own data structure, and would use that copy, which would - * mean it would call the finalize routine that we just patched out. + /* Having patched the stype, we need to make sure the memory + * manager uses it. It keeps a copy in its own data structure, + * and would use that copy, which would mean it would call the + * finalize routine that we just patched out. */ gs_set_object_type(dev->memory->stable_memory, child, b_std); /* Now (finally) free the child memory */ - gs_free_object(dev->memory->stable_memory, child, "gx_unsubclass_device(device)"); + gs_free_object(dev->memory->stable_memory, child, "gx_device_unsubclass(device)"); /* And the stype for it */ gs_free_const_object(dev->memory->non_gc_memory, b_std, "gs_device_unsubclass(stype)"); child = 0; @@ -1611,8 +1546,6 @@ int gx_device_unsubclass(gx_device *dev) } else { dev->stype_is_dynamic = 0; } - - return 0; } int gx_update_from_subclass(gx_device *dev) @@ -1655,7 +1588,7 @@ int gx_update_from_subclass(gx_device *dev) return 0; } -int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, +int gx_subclass_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) { pdf14_clist_device *p14dev; @@ -1663,9 +1596,9 @@ int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_co int code = 0; p14dev = (pdf14_clist_device *)dev; - psubclass_data = p14dev->target->subclass_data; + psubclass_data = (generic_subclass_data *)p14dev->target->subclass_data; - set_dev_proc(dev, create_compositor, psubclass_data->saved_compositor_method); + set_dev_proc(dev, composite, psubclass_data->saved_compositor_method); if (gs_is_pdf14trans_compositor(pcte) != 0 && strncmp(dev->dname, "pdf14clist", 10) == 0) { const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte; @@ -1692,7 +1625,7 @@ int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_co subclass_device = p14dev->target; p14dev->target = p14dev->target->child; - code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + code = dev_proc(dev, composite)(dev, pcdev, pcte, pgs, memory, cdev); p14dev->target = subclass_device; @@ -1704,13 +1637,13 @@ int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_co } break; default: - code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + code = dev_proc(dev, composite)(dev, pcdev, pcte, pgs, memory, cdev); break; } } else { - code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + code = dev_proc(dev, composite)(dev, pcdev, pcte, pgs, memory, cdev); } - set_dev_proc(dev, create_compositor, gx_subclass_create_compositor); + set_dev_proc(dev, composite, gx_subclass_composite); return code; } diff --git a/base/gdevdgbr.c b/base/gdevdgbr.c index d7b34b77..c2376202 100644 --- a/base/gdevdgbr.c +++ b/base/gdevdgbr.c @@ -24,41 +24,6 @@ #include "gdevmem.h" #include "gxdevsop.h" -int -gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) -{ - return_error(gs_error_unknownerror); -} -int -gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) -{ /* - * Hand off to get_bits_rectangle, being careful to avoid a - * possible recursion loop. - */ - dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits); - gs_int_rect rect; - gs_get_bits_params_t params; - int code; - - rect.p.x = 0, rect.p.y = y; - rect.q.x = dev->width, rect.q.y = y + 1; - params.options = - (actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY | - (GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD | - /* No depth specified, we always use native colors. */ - GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE); - params.x_offset = 0; - params.raster = bitmap_raster(dev->width * dev->color_info.depth); - params.data[0] = data; - set_dev_proc(dev, get_bits, gx_no_get_bits); - code = (*dev_proc(dev, get_bits_rectangle)) - (dev, &rect, ¶ms, NULL); - if (actual_data) - *actual_data = params.data[0]; - set_dev_proc(dev, get_bits, save_get_bits); - return code; -} - /* * Determine whether we can satisfy a request by simply using the stored * representation. dev is used only for color_info.{num_components, depth}. @@ -246,11 +211,6 @@ gx_get_bits_copy_cmyk_1bit(byte *dest_line, uint dest_raster, * A good optimizing compiler would compile them in-line. */ static int - gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h, - gs_get_bits_params_t * params, - const gs_get_bits_params_t *stored, - const byte * src_base, uint dev_raster, - int x_offset, uint raster), gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h, gs_get_bits_params_t * params, const gs_get_bits_params_t *stored, @@ -330,17 +290,16 @@ gx_get_bits_copy(gx_device * dev, int x, int w, int h, /* set up parameters required by copy_mono's fit_copy */ tdev.width = dest_bit_x + (align << 3) + bit_w; tdev.height = 1; - (*dev_proc(&mem_mono_device, copy_mono)) - ((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id, - dest_bit_x + (align << 3), 0, bit_w, 1, - (gx_color_index) 0, (gx_color_index) 1); + code = mem_mono_copy_mono((gx_device *) & tdev, src, bit_x, + dev_raster, gx_no_bitmap_id, + dest_bit_x + (align << 3), 0, bit_w, 1, + (gx_color_index) 0, (gx_color_index) 1); + if (code < 0) + break; } } else if (options & ~stored_options & GB_COLORS_NATIVE) { /* Convert standard colors to native. */ - code = gx_get_bits_std_to_native(dev, x, w, h, params, stored, - src_base, dev_raster, - x_offset, raster); - options = params->options; + return_error(gs_error_rangecheck); } else { /* Convert native colors to standard. */ code = gx_get_bits_native_to_std(dev, x, w, h, params, stored, @@ -398,120 +357,6 @@ gx_get_bits_copy(gx_device * dev, int x, int w, int h, } /* - * Convert standard colors to native. Note that the source - * may have depths other than 8 bits per component. - */ -static int -gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h, - gs_get_bits_params_t * params, - const gs_get_bits_params_t *stored, - const byte * src_base, uint dev_raster, - int x_offset, uint raster) -{ - int depth = dev->color_info.depth; - int dest_bit_offset = x_offset * depth; - byte *dest_line = params->data[0] + (dest_bit_offset >> 3); - int ncolors = - (stored->options & GB_COLORS_RGB ? 3 : - stored->options & GB_COLORS_CMYK ? 4 : - stored->options & GB_COLORS_GRAY ? 1 : -1); - int ncomp = ncolors + - ((stored->options & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0); - int src_depth = GB_OPTIONS_DEPTH(stored->options); - int src_bit_offset = x * src_depth * ncomp; - const byte *src_line = src_base + (src_bit_offset >> 3); - gx_color_value src_max = (1 << src_depth) - 1; -#define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max) - gx_color_value alpha_default = src_max; - subclass_color_mappings scm; - - scm = get_color_mapping_procs_subclass(dev); - - params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE; - for (; h > 0; dest_line += raster, src_line += dev_raster, --h) { - int i; - const byte *src = src_line; - int sbit = src_bit_offset & 7; - byte *dest = dest_line; - int dbit = dest_bit_offset & 7; - byte dbyte = (dbit ? (byte)(*dest & (0xff00 >> dbit)) : 0); - -#define v2frac(value) ((long)(value) * frac_1 / src_max) - - for (i = 0; i < w; ++i) { - int j; - uchar k; - frac sc[4], dc[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value va = alpha_default; - gx_color_index pixel; - bool do_alpha = false; - - /* Fetch the source data. */ - if (stored->options & GB_ALPHA_FIRST) { - if (sample_load_next16(&va, &src, &sbit, src_depth) < 0) - return_error(gs_error_rangecheck); - va = v2cv(va); - do_alpha = true; - } - for (j = 0; j < ncolors; ++j) { - gx_color_value vj; - - if (sample_load_next16(&vj, &src, &sbit, src_depth) < 0) - return_error(gs_error_rangecheck); - sc[j] = v2frac(vj); - } - if (stored->options & GB_ALPHA_LAST) { - if (sample_load_next16(&va, &src, &sbit, src_depth) < 0) - return_error(gs_error_rangecheck); - va = v2cv(va); - do_alpha = true; - } - - /* Convert and store the pixel value. */ - if (do_alpha) { - for (j = 0; j < ncolors; j++) - v[j] = frac2cv(sc[j]); - if (ncolors == 1) - v[2] = v[1] = v[0]; - pixel = dev_proc(dev, map_rgb_alpha_color) - (dev, v[0], v[1], v[2], va); - } else { - - switch (ncolors) { - case 1: - map_gray_subclass(scm, sc[0], dc); - break; - case 3: - map_rgb_subclass(scm, 0, sc[0], sc[1], sc[2], dc); - break; - case 4: - map_cmyk_subclass(scm, sc[0], sc[1], sc[2], sc[3], dc); - break; - default: - return_error(gs_error_rangecheck); - } - - for (k = 0; k < dev->color_info.num_components; k++) - v[k] = frac2cv(dc[k]); - - pixel = dev_proc(dev, encode_color)(dev, v); - } - if (sizeof(pixel) > 4) { - if (sample_store_next64(pixel, &dest, &dbit, depth, &dbyte) < 0) - return_error(gs_error_rangecheck); - } - else { - if (sample_store_next32(pixel, &dest, &dbit, depth, &dbyte) < 0) - return_error(gs_error_rangecheck); - } - } - sample_store_flush(dest, dbit, dbyte); - } - return 0; -} - -/* * Convert native colors to standard. Only GB_DEPTH_8 is supported. */ static int @@ -603,9 +448,9 @@ gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h, } mapped[pixel] = dest; } - (*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba); + (*dev_proc(dev, map_color_rgb)) (dev, pixel, rgba); if (options & GB_ALPHA_FIRST) - *dest++ = gx_color_value_to_byte(rgba[3]); + *dest++ = 0xff; /* Convert to the requested color space. */ if (options & GB_COLORS_RGB) { dest[0] = gx_color_value_to_byte(rgba[0]); @@ -632,7 +477,7 @@ gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h, / lum_all_weights); } if (options & GB_ALPHA_LAST) - *dest++ = gx_color_value_to_byte(rgba[3]); + *dest++ = 0xff; } } return 0; @@ -641,162 +486,38 @@ gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h, /* ------ Default implementations of get_bits_rectangle ------ */ int -gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) +gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params) { return_error(gs_error_unknownerror); } -int -gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) +int gx_blank_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, + gs_get_bits_params_t *params) { - dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) = - dev_proc(dev, get_bits_rectangle); - int depth = dev->color_info.depth; - uint min_raster = (dev->width * depth + 7) >> 3; - gs_get_bits_options_t options = params->options; - int code; - - /* Avoid a recursion loop. */ - set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle); - /* - * If the parameters are right, try to call get_bits directly. Note - * that this may fail if a device only implements get_bits_rectangle - * (not get_bits) for a limited set of options. Note also that this - * must handle the case of the recursive call from within - * get_bits_rectangle (see below): because of this, and only because - * of this, it must handle partial scan lines. - */ - if (prect->q.y == prect->p.y + 1 && - !(~options & - (GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) && - (options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) && - ((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) || - ((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) && - ((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) || - ((options & GB_RASTER_SPECIFIED) && - params->raster >= min_raster)) && - unread == NULL - ) { - byte *data = params->data[0]; - byte *row = data; - - if (!(prect->p.x == 0 && prect->q.x == dev->width)) { - /* Allocate an intermediate row buffer. */ - row = gs_alloc_bytes(dev->memory, min_raster, - "gx_default_get_bits_rectangle"); - - if (row == 0) { - code = gs_note_error(gs_error_VMerror); - goto ret; - } - } - code = (*dev_proc(dev, get_bits)) (dev, prect->p.y, row, - (params->options & GB_RETURN_POINTER) ? ¶ms->data[0] - : NULL ); - if (code >= 0) { - if (row != data) { - if (prect->p.x == 0 && params->data[0] != row - && params->options & GB_RETURN_POINTER) { - /* - * get_bits returned an appropriate pointer: we can - * avoid doing any copying. - */ - DO_NOTHING; - } else { - /* Copy the partial row into the supplied buffer. */ - int width_bits = (prect->q.x - prect->p.x) * depth; - gx_device_memory tdev; - - tdev.width = width_bits; - tdev.height = 1; - tdev.line_ptrs = &tdev.base; - tdev.base = data; - tdev.raster = bitmap_raster(width_bits); - code = (*dev_proc(&mem_mono_device, copy_mono)) - ((gx_device *) & tdev, - (params->options & GB_RETURN_POINTER) ? params->data[0] : row, - prect->p.x * depth, - min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1, - (gx_color_index) 0, (gx_color_index) 1); - params->data[0] = data; - } - gs_free_object(dev->memory, row, - "gx_default_get_bits_rectangle"); - } - params->options = - GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY | - GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD | - (params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER); - goto ret; - } - } { - /* Do the transfer row-by-row using a buffer. */ - int x = prect->p.x, w = prect->q.x - x; - int bits_per_pixel = depth; - byte *row; - - if (options & GB_COLORS_STANDARD_ALL) { - /* - * Make sure the row buffer can hold the standard color - * representation, in case the device decides to use it. - */ - int bpc = GB_OPTIONS_MAX_DEPTH(options); - int nc = - (options & GB_COLORS_CMYK ? 4 : - options & GB_COLORS_RGB ? 3 : 1) + - (options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0); - int bpp = bpc * nc; - - if (bpp > bits_per_pixel) - bits_per_pixel = bpp; - } - row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3, - "gx_default_get_bits_rectangle"); - if (row == 0) { - code = gs_note_error(gs_error_VMerror); - } else { - uint dev_raster = gx_device_raster(dev, true); - uint raster = - (options & GB_RASTER_SPECIFIED ? params->raster : - options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) : - (depth * w + 7) >> 3); - gs_int_rect rect; - gs_get_bits_params_t copy_params; - gs_get_bits_options_t copy_options = - (GB_ALIGN_STANDARD | GB_ALIGN_ANY) | - (GB_RETURN_COPY | GB_RETURN_POINTER) | - (GB_OFFSET_0 | GB_OFFSET_ANY) | - (GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY | - GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) | - GB_ALPHA_ALL; - byte *dest = params->data[0]; - int y; - - rect.p.x = x, rect.q.x = x + w; - code = 0; - for (y = prect->p.y; y < prect->q.y; ++y) { - rect.p.y = y, rect.q.y = y + 1; - copy_params.options = copy_options; - copy_params.data[0] = row; - code = (*save_get_bits_rectangle) - (dev, &rect, ©_params, NULL); - if (code < 0) - break; - if (copy_params.options & GB_OFFSET_0) - copy_params.x_offset = 0; - params->data[0] = dest + (y - prect->p.y) * raster; - code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1, - params, ©_params, - copy_params.data[0], dev_raster); - if (code < 0) - break; - } - gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle"); - params->data[0] = dest; - } + int supported = GB_COLORS_NATIVE | + GB_ALPHA_NONE | + GB_DEPTH_8 | + GB_PACKING_CHUNKY | + GB_RETURN_COPY | + GB_ALIGN_STANDARD | + GB_OFFSET_0 | + GB_RASTER_STANDARD; + unsigned char *ptr = params->data[0]; + int bytes = (prect->q.x - prect->p.x) * dev->color_info.num_components; + int col = dev->color_info.num_components > 3 ? 0 : 0xff; + int raster = bitmap_raster(dev->width * dev->color_info.num_components); + int y; + + if ((params->options & supported) != supported) + return_error(gs_error_unknownerror); + + params->options = supported; + + for (y = prect->p.y; y < prect->q.y; y++) { + memset(ptr, col, bytes); + ptr += raster; } - ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle); - return (code < 0 ? code : 0); + + return 0; } diff --git a/base/gdevdrop.c b/base/gdevdrop.c index 9186eea1..7a6ca1d4 100644 --- a/base/gdevdrop.c +++ b/base/gdevdrop.c @@ -23,7 +23,6 @@ #include "gxdcolor.h" #include "gxdevice.h" #include "gxdevmem.h" -#include "gxdevrop.h" #include "gxgetbit.h" #include "gdevmem.h" /* for mem_default_strip_copy_rop prototype */ #include "gdevmpla.h" @@ -89,28 +88,6 @@ trace_copy_rop(const char *cname, gx_device * dev, /* ---------------- Default copy_rop implementations ---------------- */ -/* - * The default implementation for non-memory devices uses get_bits_rectangle - * to read out the pixels, the memory device implementation to do the - * operation, and copy_color to write the pixels back. - */ -int -gx_default_strip_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, - uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop) -{ - return gx_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop, 0); -} - int gx_default_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, @@ -139,7 +116,7 @@ gx_default_strip_copy_rop2(gx_device * dev, #ifdef DEBUG if (gs_debug_c('b')) - trace_copy_rop("gx_default_strip_copy_rop", + trace_copy_rop("gx_default_strip_copy_rop2", dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); @@ -212,7 +189,7 @@ gx_default_strip_copy_rop2(gx_device * dev, bit_params.data[0] = row; bit_params.x_offset = 0; code = (*dev_proc(dev, get_bits_rectangle)) - (dev, &rect, &bit_params, NULL); + (dev, &rect, &bit_params); if (code < 0) break; code = (*dev_proc(pmdev, copy_color)) @@ -222,23 +199,13 @@ gx_default_strip_copy_rop2(gx_device * dev, if (code < 0) return code; } - if (planar_height == 0) { - code = (*dev_proc(pmdev, strip_copy_rop)) - ((gx_device *)pmdev, - sdata + (py - y) * sraster, sourcex, sraster, - gx_no_bitmap_id, scolors, textures, tcolors, - 0, 0, width, block_height, - phase_x + x, phase_y + py, - lop); - } else { - code = (*dev_proc(pmdev, strip_copy_rop2)) + code = (*dev_proc(pmdev, strip_copy_rop2)) ((gx_device *)pmdev, sdata + (py - y) * sraster, sourcex, sraster, gx_no_bitmap_id, scolors, textures, tcolors, 0, 0, width, block_height, phase_x + x, phase_y + py, lop, planar_height); - } if (code < 0) break; if (is_planar) { @@ -598,24 +565,8 @@ pack_planar_from_standard(gx_device_memory * dev, int y, int destx, * operation, pack_from_standard to convert them back to the device * representation, and copy_color to write the pixels back. */ -int -mem_default_strip_copy_rop2(gx_device * dev, - const byte * sdata, int sourcex, - uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop, - uint planar_height) -{ - dmlprintf(dev->memory, "mem_default_strip_copy_rop2 should never be called!\n"); - return_error(gs_error_Fatal); -} - -int -mem_default_strip_copy_rop(gx_device * dev, +static int +do_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, @@ -823,7 +774,7 @@ mem_default_strip_copy_rop(gx_device * dev, bit_params.x_offset = 0; bit_params.raster = mdev.raster; code = (*dev_proc(dev, get_bits_rectangle)) - (dev, &rect, &bit_params, NULL); + (dev, &rect, &bit_params); if (code < 0) break; } @@ -836,10 +787,10 @@ mem_default_strip_copy_rop(gx_device * dev, source_data = source_row; source_raster = source_row_raster; } - code = (*dev_proc(&mdev, strip_copy_rop)) + code = (*dev_proc(&mdev, strip_copy_rop2)) ((gx_device *)&mdev, source_data, sx, source_raster, gx_no_bitmap_id, real_scolors, real_texture, real_tcolors, - 0, 0, width, loop_height, phase_x + x, phase_y + py, lop); + 0, 0, width, loop_height, phase_x + x, phase_y + py, lop, 0); if (code < 0) break; /* Convert the result back to the device's format. */ @@ -863,104 +814,26 @@ out: return code; } -/* ------ Implementation of related functions ------ */ - int -gx_default_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_tile_bitmap * texture, const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - const gx_strip_bitmap *textures; - gx_strip_bitmap tiles; - - if (texture == 0) - textures = 0; - else { - *(gx_tile_bitmap *) & tiles = *texture; - tiles.rep_shift = tiles.shift = 0; - tiles.num_planes = 1; - textures = &tiles; - } - return (*dev_proc(dev, strip_copy_rop)) - (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, - x, y, width, height, phase_x, phase_y, lop); -} - -int -gx_copy_rop_unaligned(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_tile_bitmap * texture, const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - const gx_strip_bitmap *textures; - gx_strip_bitmap tiles; - - if (texture == 0) - textures = 0; - else { - *(gx_tile_bitmap *) & tiles = *texture; - tiles.rep_shift = tiles.shift = 0; - tiles.num_planes = 1; - textures = &tiles; - } - return gx_strip_copy_rop_unaligned - (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, - x, y, width, height, phase_x, phase_y, lop); -} - -int -gx_strip_copy_rop_unaligned(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, +mem_default_strip_copy_rop2(gx_device * dev, + const byte * sdata, int sourcex, + uint sraster, gx_bitmap_id id, const gx_color_index * scolors, - const gx_strip_bitmap * textures, const gx_color_index * tcolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) + int phase_x, int phase_y, + gs_logical_operation_t lop, + uint planar_height) { - dev_proc_strip_copy_rop((*copy_rop)) = dev_proc(dev, strip_copy_rop); - int depth = (scolors == 0 ? dev->color_info.depth : 1); - int step = sraster & (align_bitmap_mod - 1); - - /* Adjust the origin. */ - if (sdata != 0) { - uint offset = - (uint) (sdata - (const byte *)0) & (align_bitmap_mod - 1); - - /* See copy_color above re the following statement. */ - if (depth == 24) - offset += (offset % 3) * - (align_bitmap_mod * (3 - (align_bitmap_mod % 3))); - sdata -= offset; - sourcex += (offset << 3) / depth; - } - /* Adjust the raster. */ - if (!step || sdata == 0 || - (scolors != 0 && scolors[0] == scolors[1]) - ) { /* No adjustment needed. */ - return (*copy_rop) (dev, sdata, sourcex, sraster, id, scolors, - textures, tcolors, x, y, width, height, - phase_x, phase_y, lop); - } - /* Do the transfer one scan line at a time. */ + if (planar_height != 0) { - const byte *p = sdata; - int d = sourcex; - int dstep = (step << 3) / depth; - int code = 0; - int i; - - for (i = 0; i < height && code >= 0; - ++i, p += sraster - step, d += dstep - ) - code = (*copy_rop) (dev, p, d, sraster, gx_no_bitmap_id, scolors, - textures, tcolors, x, y + i, width, 1, - phase_x, phase_y, lop); - return code; + dmlprintf(dev->memory, "mem_default_strip_copy_rop2 should never be called!\n"); + return_error(gs_error_Fatal); } + return do_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, + textures, tcolors, x, y, width, height, + phase_x, phase_y, lop); } /* ---------------- Internal routines ---------------- */ diff --git a/base/gdevepo.c b/base/gdevepo.c index 7c9eb0b7..f8c46c54 100644 --- a/base/gdevepo.c +++ b/base/gdevepo.c @@ -49,7 +49,6 @@ extern void epo_disable(int flag); /* Device procedures, we need quite a lot of them */ static dev_proc_output_page(epo_output_page); static dev_proc_fill_rectangle(epo_fill_rectangle); -static dev_proc_draw_line(epo_draw_line); static dev_proc_fill_path(epo_fill_path); static dev_proc_fill_mask(epo_fill_mask); static dev_proc_fill_trapezoid(epo_fill_trapezoid); @@ -62,20 +61,16 @@ static dev_proc_fill_linear_color_trapezoid(epo_fill_linear_color_trapezoid); static dev_proc_fill_linear_color_triangle(epo_fill_linear_color_triangle); static dev_proc_put_image(epo_put_image); static dev_proc_fillpage(epo_fillpage); -static dev_proc_create_compositor(epo_create_compositor); +static dev_proc_composite(epo_composite); static dev_proc_text_begin(epo_text_begin); -static dev_proc_finish_copydevice(epo_finish_copydevice); -static dev_proc_begin_image(epo_begin_image); +static dev_proc_initialize_device_procs(epo_initialize_device_procs); static dev_proc_begin_typed_image(epo_begin_typed_image); static dev_proc_stroke_path(epo_stroke_path); -static dev_proc_tile_rectangle(epo_tile_rectangle); static dev_proc_copy_mono(epo_copy_mono); static dev_proc_copy_color(epo_copy_color); -static dev_proc_get_bits(epo_get_bits); static dev_proc_copy_alpha(epo_copy_alpha); -static dev_proc_copy_rop(epo_copy_rop); +static dev_proc_get_bits_rectangle(epo_get_bits_rectangle); static dev_proc_strip_tile_rectangle(epo_strip_tile_rectangle); -static dev_proc_strip_copy_rop(epo_strip_copy_rop); static dev_proc_strip_copy_rop2(epo_strip_copy_rop2); static dev_proc_copy_planes(epo_copy_planes); static dev_proc_copy_alpha_hl_color(epo_copy_alpha_hl_color); @@ -108,86 +103,11 @@ public_st_epo_device(); const gx_device_epo gs_epo_device = { - std_device_dci_type_body(gx_device_epo, 0, EPO_DEVICENAME, &st_epo_device, + std_device_dci_type_body_sc(gx_device_epo, epo_initialize_device_procs, + EPO_DEVICENAME, &st_epo_device, MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, - 1, 8, 255, 0, 256, 1), - {default_subclass_open_device, - default_subclass_get_initial_matrix, - default_subclass_sync_output, /* sync_output */ - epo_output_page, - default_subclass_close_device, - default_subclass_map_rgb_color, - default_subclass_map_color_rgb, - epo_fill_rectangle, - epo_tile_rectangle, /* tile_rectangle */ - epo_copy_mono, - epo_copy_color, - epo_draw_line, /* draw_line */ - epo_get_bits, /* get_bits */ - default_subclass_get_params, - default_subclass_put_params, - default_subclass_map_cmyk_color, - default_subclass_get_xfont_procs, /* get_xfont_procs */ - default_subclass_get_xfont_device, /* get_xfont_device */ - default_subclass_map_rgb_alpha_color, - default_subclass_get_page_device, - default_subclass_get_alpha_bits, /* get_alpha_bits */ - epo_copy_alpha, - default_subclass_get_band, /* get_band */ - epo_copy_rop, /* copy_rop */ - epo_fill_path, - epo_stroke_path, - epo_fill_mask, - epo_fill_trapezoid, - epo_fill_parallelogram, - epo_fill_triangle, - epo_draw_thin_line, - epo_begin_image, - default_subclass_image_data, /* image_data */ - default_subclass_end_image, /* end_image */ - epo_strip_tile_rectangle, - epo_strip_copy_rop, - default_subclass_get_clipping_box, /* get_clipping_box */ - epo_begin_typed_image, - default_subclass_get_bits_rectangle, /* get_bits_rectangle */ - default_subclass_map_color_rgb_alpha, - epo_create_compositor, - default_subclass_get_hardware_params, /* get_hardware_params */ - epo_text_begin, - epo_finish_copydevice, /* finish_copydevice */ - default_subclass_begin_transparency_group, /* begin_transparency_group */ - default_subclass_end_transparency_group, /* end_transparency_group */ - default_subclass_begin_transparency_mask, /* begin_transparency_mask */ - default_subclass_end_transparency_mask, /* end_transparency_mask */ - default_subclass_discard_transparency_layer, /* discard_transparency_layer */ - default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ - default_subclass_get_color_comp_index, /* get_color_comp_index */ - default_subclass_encode_color, /* encode_color */ - default_subclass_decode_color, /* decode_color */ - default_subclass_pattern_manage, /* pattern_manage */ - epo_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - default_subclass_include_color_space, /* include_color_space */ - epo_fill_linear_color_scanline, /* fill_linear_color_scanline */ - epo_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ - epo_fill_linear_color_triangle, /* fill_linear_color_triangle */ - default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ - default_subclass_ret_devn_params, /* ret_devn_params */ - epo_fillpage, /* fillpage */ - default_subclass_push_transparency_state, /* push_transparency_state */ - default_subclass_pop_transparency_state, /* pop_transparency_state */ - epo_put_image, /* put_image */ - default_subclass_dev_spec_op, /* dev_spec_op */ - epo_copy_planes, /* copy_planes */ - default_subclass_get_profile, /* get_profile */ - default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ - epo_strip_copy_rop2, - default_subclass_strip_tile_rect_devn, - epo_copy_alpha_hl_color, - epo_process_page, - epo_transform_pixel_region, - epo_fill_stroke_path, - } + 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) }; #undef MAX_COORD @@ -236,6 +156,87 @@ epo_disable(int flag) gs_debug[gs_debug_flag_epo_disable] = flag; } +static void +enable_procs(gx_device *dev) +{ + set_dev_proc(dev, output_page, epo_output_page); + set_dev_proc(dev, fill_rectangle, epo_fill_rectangle); + set_dev_proc(dev, copy_mono, epo_copy_mono); + set_dev_proc(dev, copy_color, epo_copy_color); + set_dev_proc(dev, copy_alpha, epo_copy_alpha); + set_dev_proc(dev, get_bits_rectangle, epo_get_bits_rectangle); + set_dev_proc(dev, fill_path, epo_fill_path); + set_dev_proc(dev, stroke_path, epo_stroke_path); + set_dev_proc(dev, fill_mask, epo_fill_mask); + set_dev_proc(dev, fill_trapezoid, epo_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, epo_fill_parallelogram); + set_dev_proc(dev, fill_triangle, epo_fill_triangle); + set_dev_proc(dev, draw_thin_line, epo_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, epo_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, epo_begin_typed_image); + set_dev_proc(dev, composite, epo_composite); + set_dev_proc(dev, text_begin, epo_text_begin); + set_dev_proc(dev, fill_rectangle_hl_color, epo_fill_rectangle_hl_color); + set_dev_proc(dev, fill_linear_color_scanline, epo_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, epo_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, epo_fill_linear_color_triangle); + set_dev_proc(dev, fillpage, epo_fillpage); + set_dev_proc(dev, put_image, epo_put_image); + set_dev_proc(dev, copy_planes, epo_copy_planes); + set_dev_proc(dev, strip_copy_rop2, epo_strip_copy_rop2); + set_dev_proc(dev, copy_alpha_hl_color, epo_copy_alpha_hl_color); + set_dev_proc(dev, process_page, epo_process_page); + set_dev_proc(dev, transform_pixel_region, epo_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, epo_fill_stroke_path); +} + +static void +enable_self(gx_device *dev) +{ + erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; + + data->disabled = 0; + enable_procs(dev); +} + +static void +disable_self(gx_device *dev) +{ + erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; + + data->disabled = 1; + + set_dev_proc(dev, output_page, default_subclass_output_page); + set_dev_proc(dev, fill_rectangle, default_subclass_fill_rectangle); + set_dev_proc(dev, copy_mono, default_subclass_copy_mono); + set_dev_proc(dev, copy_color, default_subclass_copy_color); + set_dev_proc(dev, copy_alpha, default_subclass_copy_alpha); + set_dev_proc(dev, get_bits_rectangle, default_subclass_get_bits_rectangle); + set_dev_proc(dev, fill_path, default_subclass_fill_path); + set_dev_proc(dev, stroke_path, default_subclass_stroke_path); + set_dev_proc(dev, fill_mask, default_subclass_fill_mask); + set_dev_proc(dev, fill_trapezoid, default_subclass_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, default_subclass_fill_parallelogram); + set_dev_proc(dev, fill_triangle, default_subclass_fill_triangle); + set_dev_proc(dev, draw_thin_line, default_subclass_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, default_subclass_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, default_subclass_begin_typed_image); + set_dev_proc(dev, composite, default_subclass_composite); + set_dev_proc(dev, text_begin, default_subclass_text_begin); + set_dev_proc(dev, fill_rectangle_hl_color, default_subclass_fill_rectangle_hl_color); + set_dev_proc(dev, fill_linear_color_scanline, default_subclass_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, default_subclass_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, default_subclass_fill_linear_color_triangle); + /* NOT fillpage! */ + set_dev_proc(dev, put_image, default_subclass_put_image); + set_dev_proc(dev, copy_planes, default_subclass_copy_planes); + set_dev_proc(dev, strip_copy_rop2, default_subclass_strip_copy_rop2); + set_dev_proc(dev, copy_alpha_hl_color, default_subclass_copy_alpha_hl_color); + set_dev_proc(dev, process_page, default_subclass_process_page); + set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); +} + int epo_check_and_install(gx_device *dev) { @@ -264,7 +265,7 @@ epo_check_and_install(gx_device *dev) if (!can_optimize) { DPRINTF1(dev->memory, "child %s can't be optimized, uninstalling\n", installed_epo_device->child->dname); /* Not doing any pending fillpages because we are about to do a fillpage anyway */ - gx_device_unsubclass(installed_epo_device); + disable_self(installed_epo_device); return code; } } else { @@ -273,6 +274,7 @@ epo_check_and_install(gx_device *dev) /* Already installed, nothing to do */ if (installed_epo_device != NULL) { + enable_self(installed_epo_device); return code; } @@ -282,6 +284,10 @@ epo_check_and_install(gx_device *dev) return code; } + /* Always install us as low down the chain as possible. */ + while (dev->child) + dev = dev->child; + /* Install subclass for optimization */ code = gx_device_subclass(dev, (gx_device *)&gs_epo_device, sizeof(erasepage_subclass_data)); if (code < 0) { @@ -299,8 +305,11 @@ epo_handle_erase_page(gx_device *dev) erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; int code = 0; + if (data->disabled) + return 0; + if (gs_debug_c(gs_debug_flag_epo_install_only)) { - gx_device_unsubclass(dev); + disable_self(dev); DPRINTF1(dev->memory, "Uninstall erasepage, device=%s\n", dev->dname); return code; } @@ -308,15 +317,15 @@ epo_handle_erase_page(gx_device *dev) DPRINTF1(dev->memory, "Do fillpage, Uninstall erasepage, device %s\n", dev->dname); /* Just do a fill_rectangle (using saved color) */ - if (dev->child) { + if (dev->child && dev->child->is_open && data->queued) { code = dev_proc(dev->child, fill_rectangle)(dev->child, 0, 0, dev->child->width, dev->child->height, data->last_color); } - /* Remove the epo device */ - gx_device_unsubclass(dev); + /* Disable the epo device */ + disable_self(dev); return code; } @@ -325,19 +334,20 @@ int epo_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; - if (gs_debug_c(gs_debug_flag_epo_install_only)) { + if (data->disabled || gs_debug_c(gs_debug_flag_epo_install_only)) { return default_subclass_fillpage(dev, pgs, pdevc); } /* If color is not pure, don't defer this, uninstall and do it now */ if (!color_is_pure(pdevc)) { DPRINTF(dev->memory, "epo_fillpage(), color is not pure, uninstalling\n"); - gx_device_unsubclass(dev); - return dev_proc(dev, fillpage)(dev, pgs, pdevc); + disable_self(dev); + return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); } /* Save the color being requested, and swallow the fillpage */ data->last_color = pdevc->colors.pure; + data->queued = 1; DPRINTF(dev->memory, "Swallowing fillpage\n"); return 0; @@ -349,6 +359,7 @@ int epo_output_page(gx_device *dev, int num_copies, int flush) if (code != 0) return code; + dev = dev->child; return dev_proc(dev, output_page)(dev, num_copies, flush); } @@ -358,18 +369,10 @@ int epo_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_c if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_rectangle)(dev, x, y, width, height, color); } -int epo_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) -{ - int code = epo_handle_erase_page(dev); - - if (code != 0) - return code; - return dev_proc(dev, obsolete_draw_line)(dev, x0, y0, x1, y1, color); -} - int epo_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) @@ -378,6 +381,7 @@ int epo_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_path)(dev, pgs, ppath, params, pdcolor, pcpath); } @@ -390,6 +394,7 @@ int epo_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_b if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_mask)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); } @@ -401,6 +406,7 @@ int epo_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_trapezoid)(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); } @@ -411,6 +417,7 @@ int epo_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed a if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_parallelogram)(dev, px, py, ax, ay, bx, by, pdcolor, lop); } @@ -421,6 +428,7 @@ int epo_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fi if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_triangle)(dev, px, py, ax, ay, bx, by, pdcolor, lop); } @@ -432,6 +440,7 @@ int epo_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy if (code != 0) return code; + dev = dev->child; return dev_proc(dev, draw_thin_line)(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); } @@ -442,6 +451,7 @@ int epo_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_rectangle_hl_color)(dev, rect, pgs, pdcolor, pcpath); } @@ -453,6 +463,7 @@ int epo_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_linear_color_scanline)(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); } @@ -466,6 +477,7 @@ int epo_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_linear_color_trapezoid)(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); } @@ -477,6 +489,7 @@ int epo_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_linear_color_triangle)(dev, fa, p0, p1, p2, c0, c1, c2); } @@ -488,31 +501,33 @@ int epo_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num if (code != 0) return code; + dev = dev->child; return dev_proc(dev, put_image)(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); } -int epo_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, +int epo_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) { int code = epo_handle_erase_page(dev); if (code != 0) return code; - return dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + return default_subclass_composite(dev, pcdev, pcte, pgs, memory, cdev); } int epo_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gs_text_enum_t **ppte) + gs_font *font, const gx_clip_path *pcpath, + gs_text_enum_t **ppte) { int code = epo_handle_erase_page(dev); if (code != 0) return code; - return dev_proc(dev, text_begin)(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + dev = dev->child; + return dev_proc(dev, text_begin)(dev, pgs, text, font, pcpath, ppte); } -int epo_finish_copydevice(gx_device *dev, const gx_device *from_dev) +static int epo_initialize_device(gx_device *dev) { /* We musn't allow the following pointers to remain shared with the from_dev because we're about to tell the caller it's only allowed to copy the prototype @@ -522,20 +537,15 @@ int epo_finish_copydevice(gx_device *dev, const gx_device *from_dev) dev->child = NULL; dev->parent = NULL; dev->subclass_data = NULL; - /* Only allow copying the prototype. */ - return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); + return 0; } -int epo_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, - gs_image_format_t format, const gs_int_rect *prect, - const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gx_image_enum_common_t **pinfo) +void epo_initialize_device_procs(gx_device *dev) { - int code = epo_handle_erase_page(dev); + default_subclass_initialize_device_procs(dev); - if (code != 0) - return code; - return dev_proc(dev, begin_image)(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); + set_dev_proc(dev, initialize_device, epo_initialize_device); + enable_procs(dev); } int epo_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, @@ -547,6 +557,7 @@ int epo_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix if (code != 0) return code; + dev = dev->child; return dev_proc(dev, begin_typed_image)(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); } @@ -558,20 +569,10 @@ int epo_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, stroke_path)(dev, pgs, ppath, params, pdcolor, pcpath); } -int epo_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, - gx_color_index color0, gx_color_index color1, - int phase_x, int phase_y) -{ - int code = epo_handle_erase_page(dev); - - if (code != 0) - return code; - return dev_proc(dev, tile_rectangle)(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); -} - int epo_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) @@ -580,6 +581,7 @@ int epo_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_b if (code != 0) return code; + dev = dev->child; return dev_proc(dev, copy_mono)(dev, data, data_x, raster, id, x, y, width, height, color0, color1); } @@ -590,16 +592,19 @@ int epo_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_ if (code != 0) return code; + dev = dev->child; return dev_proc(dev, copy_color)(dev, data, data_x, raster, id, x, y, width, height); } -int epo_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) +int epo_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, + gs_get_bits_params_t *params) { int code = epo_handle_erase_page(dev); if (code != 0) return code; - return dev_proc(dev, get_bits)(dev, y, data, actual_data); + dev = dev->child; + return dev_proc(dev, get_bits_rectangle)(dev, prect, params); } int epo_copy_alpha(gx_device *dev, const byte *data, int data_x, @@ -610,22 +615,10 @@ int epo_copy_alpha(gx_device *dev, const byte *data, int data_x, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, copy_alpha)(dev, data, data_x, raster, id, x, y, width, height, color, depth); } -int epo_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_tile_bitmap *texture, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - int code = epo_handle_erase_page(dev); - - if (code != 0) - return code; - return dev_proc(dev, copy_rop)(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); -} - int epo_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) @@ -634,22 +627,10 @@ int epo_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x if (code != 0) return code; + dev = dev->child; return dev_proc(dev, strip_tile_rectangle)(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); } -int epo_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_strip_bitmap *textures, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - int code = epo_handle_erase_page(dev); - - if (code != 0) - return code; - return dev_proc(dev, strip_copy_rop)(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); -} - int epo_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) @@ -658,6 +639,7 @@ int epo_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sra if (code != 0) return code; + dev = dev->child; return dev_proc(dev, strip_copy_rop2)(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); } @@ -668,6 +650,7 @@ int epo_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx if (code != 0) return code; + dev = dev->child; return dev_proc(dev, copy_planes)(dev, data, data_x, raster, id, x, y, width, height, plane_height); } @@ -679,6 +662,7 @@ int epo_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, copy_alpha_hl_color)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); } @@ -688,6 +672,7 @@ int epo_process_page(gx_device *dev, gx_process_page_options_t *options) if (code != 0) return code; + dev = dev->child; return dev_proc(dev, process_page)(dev, options); } @@ -700,6 +685,7 @@ int epo_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, if (code != 0) return code; + dev = dev->child; return dev_proc(dev, fill_stroke_path)(dev, pgs, ppath, fill_params, pdcolor_fill, stroke_params, pdcolor_stroke, pcpath); } @@ -710,5 +696,6 @@ int epo_transform_pixel_region(gx_device *dev, transform_pixel_region_reason rea if (code != 0) return code; + dev = dev->child; return dev_proc(dev, transform_pixel_region)(dev, reason, data); } diff --git a/base/gdevepo.h b/base/gdevepo.h index 029a54ad..eeadc2a2 100644 --- a/base/gdevepo.h +++ b/base/gdevepo.h @@ -29,7 +29,9 @@ typedef struct gx_device_s gx_device_epo; typedef struct { subclass_common; - gx_color_index last_color; // Pure color only + gx_color_index last_color; /* Pure color only */ + int queued; /* We have a fillpage queued */ + int disabled; /* Set once we have done our job */ } erasepage_subclass_data; /* Check if epo subclass device installed, and install it if not */ diff --git a/base/gdevflp.c b/base/gdevflp.c index 20757bbe..3c1ad135 100644 --- a/base/gdevflp.c +++ b/base/gdevflp.c @@ -60,16 +60,12 @@ private_st_flp_text_enum(); static dev_proc_output_page(flp_output_page); static dev_proc_close_device(flp_close_device); static dev_proc_fill_rectangle(flp_fill_rectangle); -static dev_proc_tile_rectangle(flp_tile_rectangle); static dev_proc_copy_mono(flp_copy_mono); static dev_proc_copy_color(flp_copy_color); -static dev_proc_draw_line(flp_draw_line); -static dev_proc_get_bits(flp_get_bits); +static dev_proc_get_bits_rectangle(flp_get_bits_rectangle); static dev_proc_get_params(flp_put_params); static dev_proc_get_alpha_bits(flp_get_alpha_bits); static dev_proc_copy_alpha(flp_copy_alpha); -static dev_proc_get_band(flp_get_band); -static dev_proc_copy_rop(flp_copy_rop); static dev_proc_fill_path(flp_fill_path); static dev_proc_stroke_path(flp_stroke_path); static dev_proc_fill_mask(flp_fill_mask); @@ -77,21 +73,16 @@ static dev_proc_fill_trapezoid(flp_fill_trapezoid); static dev_proc_fill_parallelogram(flp_fill_parallelogram); static dev_proc_fill_triangle(flp_fill_triangle); static dev_proc_draw_thin_line(flp_draw_thin_line); -static dev_proc_begin_image(flp_begin_image); -static dev_proc_image_data(flp_image_data); -static dev_proc_end_image(flp_end_image); static dev_proc_strip_tile_rectangle(flp_strip_tile_rectangle); -static dev_proc_strip_copy_rop(flp_strip_copy_rop); static dev_proc_begin_typed_image(flp_begin_typed_image); static dev_proc_get_bits_rectangle(flp_get_bits_rectangle); -static dev_proc_create_compositor(flp_create_compositor); +static dev_proc_composite(flp_composite); static dev_proc_text_begin(flp_text_begin); static dev_proc_begin_transparency_group(flp_begin_transparency_group); static dev_proc_end_transparency_group(flp_end_transparency_group); static dev_proc_begin_transparency_mask(flp_begin_transparency_mask); static dev_proc_end_transparency_mask(flp_end_transparency_mask); static dev_proc_discard_transparency_layer(flp_discard_transparency_layer); -static dev_proc_pattern_manage(flp_pattern_manage); static dev_proc_fill_rectangle_hl_color(flp_fill_rectangle_hl_color); static dev_proc_fill_linear_color_scanline(flp_fill_linear_color_scanline); static dev_proc_fill_linear_color_trapezoid(flp_fill_linear_color_trapezoid); @@ -107,6 +98,7 @@ static dev_proc_copy_alpha_hl_color(flp_copy_alpha_hl_color); static dev_proc_process_page(flp_process_page); static dev_proc_transform_pixel_region(flp_transform_pixel_region); static dev_proc_fill_stroke_path(flp_fill_stroke_path); +static dev_proc_initialize_device_procs(flp_initialize_device_procs); /* The device prototype */ #define MAX_COORD (max_int_in_fixed - 1000) @@ -133,86 +125,11 @@ public_st_flp_device(); const gx_device_flp gs_flp_device = { - std_device_dci_type_body(gx_device_flp, 0, "first_lastpage", &st_flp_device, + std_device_dci_type_body_sc(gx_device_flp, flp_initialize_device_procs, + "first_lastpage", &st_flp_device, MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, - 1, 8, 255, 0, 256, 1), - {default_subclass_open_device, - default_subclass_get_initial_matrix, - default_subclass_sync_output, /* sync_output */ - flp_output_page, - flp_close_device, - default_subclass_map_rgb_color, - default_subclass_map_color_rgb, - flp_fill_rectangle, - flp_tile_rectangle, /* tile_rectangle */ - flp_copy_mono, - flp_copy_color, - flp_draw_line, /* draw_line */ - flp_get_bits, /* get_bits */ - default_subclass_get_params, - flp_put_params, - default_subclass_map_cmyk_color, - default_subclass_get_xfont_procs, /* get_xfont_procs */ - default_subclass_get_xfont_device, /* get_xfont_device */ - default_subclass_map_rgb_alpha_color, - default_subclass_get_page_device, - flp_get_alpha_bits, /* get_alpha_bits */ - flp_copy_alpha, - flp_get_band, /* get_band */ - flp_copy_rop, /* copy_rop */ - flp_fill_path, - flp_stroke_path, - flp_fill_mask, - flp_fill_trapezoid, - flp_fill_parallelogram, - flp_fill_triangle, - flp_draw_thin_line, - flp_begin_image, - flp_image_data, /* image_data */ - flp_end_image, /* end_image */ - flp_strip_tile_rectangle, - flp_strip_copy_rop, - default_subclass_get_clipping_box, /* get_clipping_box */ - flp_begin_typed_image, - flp_get_bits_rectangle, /* get_bits_rectangle */ - default_subclass_map_color_rgb_alpha, - flp_create_compositor, - default_subclass_get_hardware_params, /* get_hardware_params */ - flp_text_begin, - default_subclass_finish_copydevice, /* finish_copydevice */ - flp_begin_transparency_group, /* begin_transparency_group */ - flp_end_transparency_group, /* end_transparency_group */ - flp_begin_transparency_mask, /* begin_transparency_mask */ - flp_end_transparency_mask, /* end_transparency_mask */ - flp_discard_transparency_layer, /* discard_transparency_layer */ - default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ - default_subclass_get_color_comp_index, /* get_color_comp_index */ - default_subclass_encode_color, /* encode_color */ - default_subclass_decode_color, /* decode_color */ - flp_pattern_manage, /* pattern_manage */ - flp_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - default_subclass_include_color_space, /* include_color_space */ - flp_fill_linear_color_scanline, /* fill_linear_color_scanline */ - flp_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ - flp_fill_linear_color_triangle, /* fill_linear_color_triangle */ - default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ - default_subclass_ret_devn_params, /* ret_devn_params */ - flp_fillpage, /* fillpage */ - flp_push_transparency_state, /* push_transparency_state */ - flp_pop_transparency_state, /* pop_transparency_state */ - flp_put_image, /* put_image */ - default_subclass_dev_spec_op, /* dev_spec_op */ - flp_copy_planes, /* copy_planes */ - default_subclass_get_profile, /* get_profile */ - default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ - flp_strip_copy_rop2, - flp_strip_tile_rect_devn, - flp_copy_alpha_hl_color, - flp_process_page, - flp_transform_pixel_region, - flp_fill_stroke_path, - } + 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) }; #undef MAX_COORD @@ -449,20 +366,6 @@ int flp_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_c return 0; } -int flp_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, - gx_color_index color0, gx_color_index color1, - int phase_x, int phase_y) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_tile_rectangle(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); - - return 0; -} - int flp_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) @@ -490,30 +393,6 @@ int flp_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_ return 0; } -int flp_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_draw_line(dev, x0, y0, x1, y1, color); - - return 0; -} - -int flp_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_get_bits(dev, y, data, actual_data); - - return gx_default_get_bits(dev, y, data, actual_data); -} - static void flp_rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname) { @@ -653,34 +532,6 @@ int flp_copy_alpha(gx_device *dev, const byte *data, int data_x, return 0; } -int flp_get_band(gx_device *dev, int y, int *band_start) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_get_band(dev, y, band_start); - - return gx_default_get_band(dev, y, band_start); -} - -int flp_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_tile_bitmap *texture, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); - - return 0; -} - int flp_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) @@ -778,46 +629,6 @@ int flp_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy return 0; } -int flp_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, - gs_image_format_t format, const gs_int_rect *prect, - const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gx_image_enum_common_t **pinfo) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); - - return 0; -} - -int flp_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, - uint raster, int height) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_image_data(dev, info, planes, data_x, raster, height); - - return 0; -} - -int flp_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_end_image(dev, info, draw_last); - - return 0; -} - int flp_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) @@ -832,22 +643,6 @@ int flp_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x return 0; } -int flp_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_strip_bitmap *textures, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); - - return 0; -} - typedef struct flp_image_enum_s { gx_image_enum_common; int y; @@ -937,19 +732,19 @@ int flp_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix } int flp_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, - gs_get_bits_params_t *params, gs_int_rect **unread) + gs_get_bits_params_t *params) { int code = SkipPage(dev); if (code < 0) return code; if (!code) - return default_subclass_get_bits_rectangle(dev, prect, params, unread); + return default_subclass_get_bits_rectangle(dev, prect, params); - return gx_default_get_bits_rectangle(dev->child, prect, params, unread); + return gx_default_get_bits_rectangle(dev->child, prect, params); } -int flp_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, +int flp_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) { int code = SkipPage(dev); @@ -965,7 +760,7 @@ int flp_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_ if (code < 0) return code; if (!code) - return default_subclass_create_compositor(dev, pcdev, pcte, pgs, memory, cdev); + return default_subclass_composite(dev, pcdev, pcte, pgs, memory, cdev); return 0; } @@ -1034,11 +829,12 @@ static const gs_text_enum_procs_t flp_text_procs = { * up to the device, in which case we simply pass on the 'begin' method to the device. */ int flp_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gs_text_enum_t **ppte) + gs_font *font, const gx_clip_path *pcpath, + gs_text_enum_t **ppte) { flp_text_enum_t *penum; int code; + gs_memory_t *memory = pgs->memory; /* We don't want to simply ignore stringwidth for 2 reasons; * firstly because following elelments may be positioned based on the value returned @@ -1050,19 +846,19 @@ int flp_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, * stringwidth operation, or they won;t be able to cache the glyphs properly. * So always pass stringwidth operations to the child. */ - return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte); code = SkipPage(dev); if (code < 0) return code; if (!code) - return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte); rc_alloc_struct_1(penum, flp_text_enum_t, &st_flp_text_enum, memory, return_error(gs_error_VMerror), "gdev_flp_text_begin"); penum->rc.free = rc_free_text_enum; code = gs_text_enum_init((gs_text_enum_t *)penum, &flp_text_procs, - dev, pgs, text, font, path, pdcolor, pcpath, memory); + dev, pgs, text, font, pcpath, memory); if (code < 0) { gs_free_object(memory, penum, "gdev_flp_text_begin"); return code; @@ -1134,19 +930,6 @@ int flp_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) return 0; } -int flp_pattern_manage(gx_device *dev, gx_bitmap_id id, - gs_pattern1_instance_t *pinst, pattern_manage_t function) -{ - int code = SkipPage(dev); - - if (code < 0) - return code; - if (!code) - return default_subclass_pattern_manage(dev, id, pinst, function); - - return 0; -} - int flp_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { @@ -1346,3 +1129,50 @@ int flp_transform_pixel_region(gx_device *dev, transform_pixel_region_reason rea return 0; } + +static void +flp_initialize_device_procs(gx_device *dev) +{ + default_subclass_initialize_device_procs(dev); + + set_dev_proc(dev, output_page, flp_output_page); + set_dev_proc(dev, close_device, flp_close_device); + set_dev_proc(dev, fill_rectangle, flp_fill_rectangle); + set_dev_proc(dev, copy_mono, flp_copy_mono); + set_dev_proc(dev, copy_color, flp_copy_color); + set_dev_proc(dev, put_params, flp_put_params); + set_dev_proc(dev, get_alpha_bits, flp_get_alpha_bits); + set_dev_proc(dev, copy_alpha, flp_copy_alpha); + set_dev_proc(dev, fill_path, flp_fill_path); + set_dev_proc(dev, stroke_path, flp_stroke_path); + set_dev_proc(dev, fill_mask, flp_fill_mask); + set_dev_proc(dev, fill_trapezoid, flp_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, flp_fill_parallelogram); + set_dev_proc(dev, fill_triangle, flp_fill_triangle); + set_dev_proc(dev, draw_thin_line, flp_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, flp_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, flp_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, flp_get_bits_rectangle); + set_dev_proc(dev, composite, flp_composite); + set_dev_proc(dev, text_begin, flp_text_begin); + set_dev_proc(dev, begin_transparency_group, flp_begin_transparency_group); + set_dev_proc(dev, end_transparency_group, flp_end_transparency_group); + set_dev_proc(dev, begin_transparency_mask, flp_begin_transparency_mask); + set_dev_proc(dev, end_transparency_mask, flp_end_transparency_mask); + set_dev_proc(dev, discard_transparency_layer, flp_discard_transparency_layer); + set_dev_proc(dev, fill_rectangle_hl_color, flp_fill_rectangle_hl_color); + set_dev_proc(dev, fill_linear_color_scanline, flp_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, flp_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, flp_fill_linear_color_triangle); + set_dev_proc(dev, fillpage, flp_fillpage); + set_dev_proc(dev, push_transparency_state, flp_push_transparency_state); + set_dev_proc(dev, pop_transparency_state, flp_pop_transparency_state); + set_dev_proc(dev, put_image, flp_put_image); + set_dev_proc(dev, copy_planes, flp_copy_planes); + set_dev_proc(dev, strip_copy_rop2, flp_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, flp_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, flp_copy_alpha_hl_color); + set_dev_proc(dev, process_page, flp_process_page); + set_dev_proc(dev, transform_pixel_region, flp_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, flp_fill_stroke_path); +}
\ No newline at end of file diff --git a/base/gdevhit.c b/base/gdevhit.c index 0a804b4c..04f7345a 100644 --- a/base/gdevhit.c +++ b/base/gdevhit.c @@ -28,52 +28,30 @@ const int gs_hit_detected = gs_error_hit_detected; * It returns e_hit whenever it is asked to actually paint any pixels. */ static dev_proc_fill_rectangle(hit_fill_rectangle); +static void +hit_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, fill_rectangle, hit_fill_rectangle); + set_dev_proc(dev, composite, gx_non_imaging_composite); + + set_dev_proc(dev, map_rgb_color, gx_default_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb); + set_dev_proc(dev, map_cmyk_color, gx_default_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_default_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2); + set_dev_proc(dev, get_clipping_box, gx_get_largest_clipping_box); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); +} const gx_device gs_hit_device = { - std_device_std_body(gx_device, 0, "hit detector", - 0, 0, 1, 1), - {NULL, /* open_device */ - NULL, /* get_initial_matrix */ - NULL, /* sync_output */ - NULL, /* output_page */ - NULL, /* close_device */ - gx_default_map_rgb_color, - gx_default_map_color_rgb, - hit_fill_rectangle, - NULL, /* tile_rectangle */ - NULL, /* copy_mono */ - NULL, /* copy_color */ - gx_default_draw_line, - NULL, /* get_bits */ - NULL, /* get_params */ - NULL, /* put_params */ - gx_default_map_cmyk_color, - NULL, /* get_xfont_procs */ - NULL, /* get_xfont_device */ - gx_default_map_rgb_alpha_color, - gx_default_get_page_device, - gx_default_get_alpha_bits, - NULL, /* copy_alpha */ - gx_default_get_band, - NULL, /* copy_rop */ - gx_default_fill_path, - NULL, /* stroke_path */ - NULL, /* fill_mask */ - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - gx_default_strip_tile_rectangle, - gx_default_strip_copy_rop, - gx_get_largest_clipping_box, - gx_default_begin_typed_image, - NULL, /* get_bits_rectangle */ - gx_default_map_color_rgb_alpha, - gx_non_imaging_create_compositor, - NULL /* get_hardware_params */ - } + std_device_std_body(gx_device, hit_initialize_device_procs, "hit detector", + 0, 0, 1, 1) }; /* Test for a hit when filling a rectangle. */ diff --git a/base/gdevkrnlsclass.c b/base/gdevkrnlsclass.c index d615a100..8ae05fb2 100644 --- a/base/gdevkrnlsclass.c +++ b/base/gdevkrnlsclass.c @@ -39,7 +39,7 @@ int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded) #else if (!dev->NupHandlerPushed && dev->NupControl != 0) { #endif - code = gx_device_subclass(dev, (gx_device *)&gs_nup_device, sizeof(Nup_device_subclass_data)); + code = gx_device_nup_device_install(dev); if (code < 0) return code; diff --git a/base/gdevm1.c b/base/gdevm1.c index 7801c3a6..f7381446 100644 --- a/base/gdevm1.c +++ b/base/gdevm1.c @@ -48,14 +48,15 @@ * functions below. In this function, rop works in terms of device pixel * values, not RGB-space values. */ int -mem_mono_strip_copy_rop_dev(gx_device * dev, const byte * sdata, - int sourcex,uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop) +mem_mono_strip_copy_rop2_dev(gx_device * dev, const byte * sdata, + int sourcex,uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, + gs_logical_operation_t lop, + uint planar_height) { gx_device_memory *mdev = (gx_device_memory *) dev; gs_rop3_t rop = (gs_rop3_t)lop; @@ -67,6 +68,11 @@ mem_mono_strip_copy_rop_dev(gx_device * dev, const byte * sdata, int ty; rop_run_op ropper; + if (planar_height != 0) { + dmlprintf(dev->memory, "mem_default_strip_copy_rop2 should never be called!\n"); + return_error(gs_error_Fatal); + } + /* Modify the raster operation according to the source palette. */ if (scolors != 0) { /* Source with palette. */ switch ((int)((scolors[1] << 1) + scolors[0])) { @@ -426,19 +432,25 @@ mem_mono_strip_copy_rop_dev(gx_device * dev, const byte * sdata, /* Procedures */ static dev_proc_map_rgb_color(mem_mono_map_rgb_color); static dev_proc_map_color_rgb(mem_mono_map_color_rgb); -static dev_proc_copy_mono(mem_mono_copy_mono); -static dev_proc_fill_rectangle(mem_mono_fill_rectangle); static dev_proc_strip_tile_rectangle(mem_mono_strip_tile_rectangle); /* The device descriptor. */ /* The instance is public. */ const gx_device_memory mem_mono_device = -mem_full_alpha_device("image1", 0, 1, mem_open, - mem_mono_map_rgb_color, mem_mono_map_color_rgb, - mem_mono_copy_mono, gx_default_copy_color, mem_mono_fill_rectangle, - gx_default_map_cmyk_color, gx_no_copy_alpha, - mem_mono_strip_tile_rectangle, mem_mono_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image1", 0, 1, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_1 = +{ + mem_mono_map_rgb_color, + mem_mono_map_color_rgb, + mem_mono_fill_rectangle, + mem_mono_copy_mono, + gx_default_copy_color, + gx_default_copy_alpha, + mem_mono_strip_tile_rectangle, + mem_mono_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Map color to/from RGB. This may be inverted. */ static gx_color_index @@ -458,7 +470,7 @@ mem_mono_map_color_rgb(gx_device * dev, gx_color_index color, } /* Fill a rectangle with a color. */ -static int +int mem_mono_fill_rectangle(gx_device * dev, int x, int y, int w, int h, gx_color_index color) { @@ -582,7 +594,7 @@ static const copy_mode copy_modes[16] = { (invert ? gs_note_error(-1) :\ mem_mono_fill_rectangle(dev, x, y, w, h, color0)) -static int +int mem_mono_copy_mono(gx_device * dev, const byte * source_data, int source_x, int source_raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1) @@ -617,14 +629,15 @@ mem_mono_copy_mono(gx_device * dev, fit_copy(dev, source_data, source_x, source_raster, id, x, y, w, h); #ifdef DO_COPY_MONO_BY_COPY_ROP if (w >= 32) { - return mem_mono_strip_copy_rop_dev(dev, source_data, source_x, - source_raster, - id, NULL, NULL, NULL, - x, y, w, h, 0, 0, - ((color0 == gx_no_color_index ? rop3_D : - color0 == 0 ? rop3_0 : rop3_1) & ~rop3_S) | - ((color1 == gx_no_color_index ? rop3_D : - color1 == 0 ? rop3_0 : rop3_1) & rop3_S)); + return mem_mono_strip_copy_rop2_dev(dev, source_data, source_x, + source_raster, + id, NULL, NULL, NULL, + x, y, w, h, 0, 0, + ((color0 == gx_no_color_index ? rop3_D : + color0 == 0 ? rop3_0 : rop3_1) & ~rop3_S) | + ((color1 == gx_no_color_index ? rop3_D : + color1 == 0 ? rop3_0 : rop3_1) & rop3_S), + 0); } #endif /* !DO_COPY_MONO_BY_COPY_ROP */ #if gx_no_color_index_value != -1 /* hokey! */ @@ -867,9 +880,9 @@ int tx, int y, int tw, int th, gx_color_index color0, gx_color_index color1, if (rop == 0xAA) return gx_default_strip_tile_rectangle(dev, tiles, tx, y, tw, th, color0, color1, px, py); - return mem_mono_strip_copy_rop_dev(dev, NULL, 0, 0, tiles->id, NULL, - tiles, NULL, - tx, y, tw, th, px, py, rop); + return mem_mono_strip_copy_rop2_dev(dev, NULL, 0, 0, tiles->id, NULL, + tiles, NULL, + tx, y, tw, th, px, py, rop, 0); #else /* !USE_COPY_ROP */ gx_device_memory * const mdev = (gx_device_memory *)dev; register uint invert; @@ -1074,6 +1087,8 @@ int tx, int y, int tw, int th, gx_color_index color0, gx_color_index color1, #endif /* !USE_COPY_ROP */ } + + /* ================ "Word"-oriented device ================ */ /* Note that on a big-endian machine, this is the same as the */ @@ -1089,12 +1104,20 @@ static dev_proc_fill_rectangle(mem1_word_fill_rectangle); /* Here is the device descriptor. */ const gx_device_memory mem_mono_word_device = -mem_full_alpha_device("image1w", 0, 1, mem_open, - mem_mono_map_rgb_color, mem_mono_map_color_rgb, - mem1_word_copy_mono, gx_default_copy_color, mem1_word_fill_rectangle, - gx_default_map_cmyk_color, gx_no_copy_alpha, - mem1_word_strip_tile_rectangle, gx_no_strip_copy_rop, - mem_word_get_bits_rectangle); + mem_device("image1w", 0, 1, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_1w = +{ + mem_mono_map_rgb_color, + mem_mono_map_color_rgb, + mem1_word_fill_rectangle, + mem1_word_copy_mono, + gx_default_copy_color, + gx_default_copy_alpha, + mem1_word_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm16.c b/base/gdevm16.c index f4d662eb..0f54f2b8 100644 --- a/base/gdevm16.c +++ b/base/gdevm16.c @@ -32,10 +32,20 @@ declare_mem_procs(mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_r /* The device descriptor. */ const gx_device_memory mem_true16_device = - mem_device("image16", 16, 0, - mem_true16_map_rgb_color, mem_true16_map_color_rgb, - mem_true16_copy_mono, mem_true16_copy_color, - mem_true16_fill_rectangle, mem_default_strip_copy_rop); + mem_device("image16", 16, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_16 = +{ + mem_true16_map_rgb_color, + mem_true16_map_color_rgb, + mem_true16_fill_rectangle, + mem_true16_copy_mono, + mem_true16_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Map a r-g-b color to a color index. */ static gx_color_index diff --git a/base/gdevm2.c b/base/gdevm2.c index 863811b8..107e0700 100644 --- a/base/gdevm2.c +++ b/base/gdevm2.c @@ -31,10 +31,20 @@ declare_mem_procs(mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fil /* The device descriptor. */ const gx_device_memory mem_mapped2_device = -mem_device("image2", 2, 0, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem_mapped2_copy_mono, mem_mapped2_copy_color, - mem_mapped2_fill_rectangle, mem_gray_strip_copy_rop); + mem_device("image2", 2, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_2 = +{ + mem_mapped_map_rgb_color, + mem_mapped_map_color_rgb, + mem_mapped2_fill_rectangle, + mem_mapped2_copy_mono, + mem_mapped2_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_gray_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -157,9 +167,9 @@ mem_mapped2_copy_color(gx_device * dev, /* Use monobit copy_mono. */ /* Patch the width in the device temporarily. */ dev->width <<= 1; - code = (*dev_proc(&mem_mono_device, copy_mono)) - (dev, base, sourcex << 1, sraster, id, - x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1); + code = mem_mono_copy_mono(dev, base, sourcex << 1, sraster, id, + x << 1, y, w << 1, h, + (gx_color_index) 0, (gx_color_index) 1); /* Restore the correct width. */ dev->width >>= 1; return code; @@ -177,12 +187,20 @@ declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rect /* Here is the device descriptor. */ const gx_device_memory mem_mapped2_word_device = -mem_full_device("image2w", 2, 0, mem_open, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem2_word_copy_mono, mem2_word_copy_color, - mem2_word_fill_rectangle, gx_default_map_cmyk_color, - gx_default_strip_tile_rectangle, gx_no_strip_copy_rop, - mem_word_get_bits_rectangle); + mem_device("image2w", 2, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_2w = +{ + mem_mapped_map_rgb_color, + mem_mapped_map_color_rgb, + mem2_word_fill_rectangle, + mem2_word_copy_mono, + mem2_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int @@ -238,7 +256,7 @@ mem2_word_copy_color(gx_device * dev, /* Use monobit copy_mono. */ /* Patch the width in the device temporarily. */ dev->width <<= 1; - code = (*dev_proc(&mem_mono_word_device, copy_mono)) + code = gdev_mem_word_functions_for_bits(1)->copy_mono (dev, base, sourcex << 1, sraster, id, x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1); /* Restore the correct width. */ diff --git a/base/gdevm24.c b/base/gdevm24.c index 332279b6..913f0028 100644 --- a/base/gdevm24.c +++ b/base/gdevm24.c @@ -20,7 +20,7 @@ #include "gxdevmem.h" /* semi-public definitions */ #include "gdevmem.h" /* private definitions */ -#define mem_true24_strip_copy_rop mem_gray8_rgb24_strip_copy_rop +#define mem_true24_strip_copy_rop2 mem_gray8_rgb24_strip_copy_rop2 /* * Define whether to use the library's memset. @@ -58,12 +58,20 @@ static dev_proc_copy_alpha(mem_true24_copy_alpha); /* The device descriptor. */ const gx_device_memory mem_true24_device = -mem_full_alpha_device("image24", 24, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle, - gx_default_map_cmyk_color, mem_true24_copy_alpha, - gx_default_strip_tile_rectangle, mem_true24_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image24", 24, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_24 = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem_true24_fill_rectangle, + mem_true24_copy_mono, + mem_true24_copy_color, + mem_true24_copy_alpha, + gx_default_strip_tile_rectangle, + mem_true24_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -551,11 +559,20 @@ declare_mem_procs(mem24_word_copy_mono, mem24_word_copy_color, mem24_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true24_word_device = -mem_full_device("image24w", 24, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem24_word_copy_mono, mem24_word_copy_color, mem24_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image24w", 24, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_24w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem24_word_fill_rectangle, + mem24_word_copy_mono, + mem24_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm32.c b/base/gdevm32.c index 414831c1..7fb0746a 100644 --- a/base/gdevm32.c +++ b/base/gdevm32.c @@ -30,11 +30,20 @@ declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_r /* The device descriptor. */ const gx_device_memory mem_true32_device = -mem_full_device("image32", 24, 8, mem_open, - gx_default_map_rgb_color, gx_default_map_color_rgb, - mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle, - gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, - mem_default_strip_copy_rop, mem_get_bits_rectangle); + mem_device("image32", 24, 8, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_32 = +{ + gx_default_map_rgb_color, + gx_default_map_color_rgb, + mem_true32_fill_rectangle, + mem_true32_copy_mono, + mem_true32_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -248,11 +257,20 @@ declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true32_word_device = -mem_full_device("image32w", 24, 8, mem_open, - gx_default_map_rgb_color, gx_default_map_color_rgb, - mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle, - gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image32w", 24, 8, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_32w = +{ + gx_default_map_rgb_color, + gx_default_map_color_rgb, + mem32_word_fill_rectangle, + mem32_word_copy_mono, + mem32_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm4.c b/base/gdevm4.c index 51940a5b..d4832eec 100644 --- a/base/gdevm4.c +++ b/base/gdevm4.c @@ -31,10 +31,20 @@ declare_mem_procs(mem_mapped4_copy_mono, mem_mapped4_copy_color, mem_mapped4_fil /* The device descriptor. */ const gx_device_memory mem_mapped4_device = -mem_device("image4", 3, 1, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem_mapped4_copy_mono, mem_mapped4_copy_color, mem_mapped4_fill_rectangle, - mem_gray_strip_copy_rop); + mem_device("image4", 3, 1, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_4 = +{ + mem_mapped_map_rgb_color, + mem_mapped_map_color_rgb, + mem_mapped4_fill_rectangle, + mem_mapped4_copy_mono, + mem_mapped4_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_gray_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -216,9 +226,9 @@ mem_mapped4_copy_color(gx_device * dev, /* Patch the width in the device temporarily. */ dev->width <<= 2; - code = (*dev_proc(&mem_mono_device, copy_mono)) - (dev, base, sourcex << 2, sraster, id, - x << 2, y, w << 2, h, (gx_color_index) 0, (gx_color_index) 1); + code = mem_mono_copy_mono(dev, base, sourcex << 2, sraster, id, + x << 2, y, w << 2, h, + (gx_color_index) 0, (gx_color_index) 1); /* Restore the correct width. */ dev->width >>= 2; return code; @@ -236,11 +246,20 @@ declare_mem_procs(mem4_word_copy_mono, mem4_word_copy_color, mem4_word_fill_rect /* Here is the device descriptor. */ const gx_device_memory mem_mapped4_word_device = -mem_full_device("image4w", 4, 0, mem_open, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem4_word_copy_mono, mem4_word_copy_color, mem4_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image4w", 4, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_4w = +{ + mem_mapped_map_rgb_color, + mem_mapped_map_color_rgb, + mem4_word_fill_rectangle, + mem4_word_copy_mono, + mem4_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int @@ -295,7 +314,7 @@ mem4_word_copy_color(gx_device * dev, /* Use monobit copy_mono. */ /* Patch the width in the device temporarily. */ dev->width <<= 2; - code = (*dev_proc(&mem_mono_word_device, copy_mono)) + code = gdev_mem_word_functions_for_bits(1)->copy_mono (dev, base, sourcex << 2, sraster, id, x << 2, y, w << 2, h, (gx_color_index) 0, (gx_color_index) 1); /* Restore the correct width. */ diff --git a/base/gdevm40.c b/base/gdevm40.c index 0946a033..31425f1a 100644 --- a/base/gdevm40.c +++ b/base/gdevm40.c @@ -46,12 +46,20 @@ declare_mem_procs(mem_true40_copy_mono, mem_true40_copy_color, mem_true40_fill_r /* The device descriptor. */ const gx_device_memory mem_true40_device = -mem_full_alpha_device("image40", 40, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem_true40_copy_mono, mem_true40_copy_color, mem_true40_fill_rectangle, - gx_default_map_cmyk_color, gx_default_copy_alpha, - gx_default_strip_tile_rectangle, mem_default_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image40", 40, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_40 = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem_true40_fill_rectangle, + mem_true40_copy_mono, + mem_true40_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -416,11 +424,20 @@ declare_mem_procs(mem40_word_copy_mono, mem40_word_copy_color, mem40_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true40_word_device = -mem_full_device("image40w", 40, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem40_word_copy_mono, mem40_word_copy_color, mem40_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image40w", 40, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_40w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem40_word_fill_rectangle, + mem40_word_copy_mono, + mem40_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm48.c b/base/gdevm48.c index d951ccfa..0a3d8a29 100644 --- a/base/gdevm48.c +++ b/base/gdevm48.c @@ -46,12 +46,20 @@ declare_mem_procs(mem_true48_copy_mono, mem_true48_copy_color, mem_true48_fill_r /* The device descriptor. */ const gx_device_memory mem_true48_device = -mem_full_alpha_device("image48", 48, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem_true48_copy_mono, mem_true48_copy_color, mem_true48_fill_rectangle, - gx_default_map_cmyk_color, gx_default_copy_alpha, - gx_default_strip_tile_rectangle, mem_default_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image48", 48, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_48 = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem_true48_fill_rectangle, + mem_true48_copy_mono, + mem_true48_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -385,11 +393,20 @@ declare_mem_procs(mem48_word_copy_mono, mem48_word_copy_color, mem48_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true48_word_device = -mem_full_device("image48w", 48, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem48_word_copy_mono, mem48_word_copy_color, mem48_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image48w", 48, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_48w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem48_word_fill_rectangle, + mem48_word_copy_mono, + mem48_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm56.c b/base/gdevm56.c index 72774fb9..70cfd942 100644 --- a/base/gdevm56.c +++ b/base/gdevm56.c @@ -46,12 +46,20 @@ declare_mem_procs(mem_true56_copy_mono, mem_true56_copy_color, mem_true56_fill_r /* The device descriptor. */ const gx_device_memory mem_true56_device = -mem_full_alpha_device("image56", 56, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem_true56_copy_mono, mem_true56_copy_color, mem_true56_fill_rectangle, - gx_default_map_cmyk_color, gx_default_copy_alpha, - gx_default_strip_tile_rectangle, mem_default_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image56", 56, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_56 = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem_true56_fill_rectangle, + mem_true56_copy_mono, + mem_true56_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -440,11 +448,20 @@ declare_mem_procs(mem56_word_copy_mono, mem56_word_copy_color, mem56_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true56_word_device = -mem_full_device("image56w", 56, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem56_word_copy_mono, mem56_word_copy_color, mem56_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image56w", 56, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_56w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem56_word_fill_rectangle, + mem56_word_copy_mono, + mem56_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm64.c b/base/gdevm64.c index 899713ef..a66c3c16 100644 --- a/base/gdevm64.c +++ b/base/gdevm64.c @@ -46,12 +46,20 @@ declare_mem_procs(mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_r /* The device descriptor. */ const gx_device_memory mem_true64_device = -mem_full_alpha_device("image64", 64, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_rectangle, - gx_default_map_cmyk_color, gx_default_copy_alpha, - gx_default_strip_tile_rectangle, mem_default_strip_copy_rop, - mem_get_bits_rectangle); + mem_device("image64", 64, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_64 = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem_true64_fill_rectangle, + mem_true64_copy_mono, + mem_true64_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_default_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -343,11 +351,20 @@ declare_mem_procs(mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_r /* Here is the device descriptor. */ const gx_device_memory mem_true64_word_device = -mem_full_device("image64w", 64, 0, mem_open, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, - mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image64w", 64, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_64w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem64_word_fill_rectangle, + mem64_word_copy_mono, + mem64_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevm8.c b/base/gdevm8.c index 65013507..6717c585 100644 --- a/base/gdevm8.c +++ b/base/gdevm8.c @@ -20,7 +20,7 @@ #include "gxdevmem.h" /* semi-public definitions */ #include "gdevmem.h" /* private definitions */ -#define mem_gray8_strip_copy_rop mem_gray8_rgb24_strip_copy_rop +#define mem_gray8_strip_copy_rop2 mem_gray8_rgb24_strip_copy_rop2 /* ================ Standard (byte-oriented) device ================ */ @@ -32,10 +32,20 @@ declare_mem_procs(mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fil /* The device descriptor. */ const gx_device_memory mem_mapped8_device = -mem_device("image8", 8, 0, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle, - mem_gray8_strip_copy_rop); + mem_device("image8", 8, 0, mem_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_8 = +{ + mem_mapped_map_rgb_color, + mem_mapped_map_color_rgb, + mem_mapped8_fill_rectangle, + mem_mapped8_copy_mono, + mem_mapped8_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + mem_gray8_strip_copy_rop2, + mem_get_bits_rectangle +}; /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte @@ -330,11 +340,20 @@ declare_mem_procs(mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rect /* Here is the device descriptor. */ const gx_device_memory mem_mapped8_word_device = -mem_full_device("image8w", 8, 0, mem_open, - mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, - mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle, - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, - gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + mem_device("image8w", 8, 0, mem_word_dev_initialize_device_procs); + +const gdev_mem_functions gdev_mem_fns_8w = +{ + gx_default_rgb_map_rgb_color, + gx_default_rgb_map_color_rgb, + mem8_word_fill_rectangle, + mem8_word_copy_mono, + mem8_word_copy_color, + gx_default_copy_alpha, + gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop2, + mem_word_get_bits_rectangle +}; /* Fill a rectangle with a color. */ static int diff --git a/base/gdevmem.c b/base/gdevmem.c index 68e7e857..aa47dc95 100644 --- a/base/gdevmem.c +++ b/base/gdevmem.c @@ -122,6 +122,44 @@ gdev_mem_word_device_for_bits(int bits_per_pixel) mem_word_devices[bits_per_pixel]); } +static const gdev_mem_functions *mem_fns[65] = { + NULL, &gdev_mem_fns_1, &gdev_mem_fns_2, NULL, + &gdev_mem_fns_4, NULL, NULL, NULL, + &gdev_mem_fns_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_24, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_40, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_48, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_56, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_64 +}; + +const gdev_mem_functions * +gdev_mem_functions_for_bits(int bits_per_pixel) +{ + return ((uint)bits_per_pixel > 64 ? NULL : mem_fns[bits_per_pixel]); +} + +static const gdev_mem_functions *mem_word_fns[65] = { + NULL, &gdev_mem_fns_1, &gdev_mem_fns_2w, NULL, + &gdev_mem_fns_4w, NULL, NULL, NULL, + &gdev_mem_fns_8w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_24w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_32w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_40w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_48w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_56w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &gdev_mem_fns_64w +}; + +const gdev_mem_functions * +gdev_mem_word_functions_for_bits(int bits_per_pixel) +{ + return ((uint)bits_per_pixel > 64 ? NULL : mem_word_fns[bits_per_pixel]); +} + /* Test whether a device is a memory device */ bool gs_device_is_memory(const gx_device * dev) @@ -130,17 +168,7 @@ gs_device_is_memory(const gx_device * dev) * We use the draw_thin_line procedure to mark memory devices. * See gdevmem.h. */ - int bits_per_pixel = dev->color_info.depth; - const gx_device_memory *mdproto; - - if (dev->is_planar) - bits_per_pixel /= dev->color_info.num_components; - - mdproto = gdev_mem_device_for_bits(bits_per_pixel); - if (mdproto != 0 && dev_proc(dev, draw_thin_line) == dev_proc(mdproto, draw_thin_line)) - return true; - mdproto = gdev_mem_word_device_for_bits(bits_per_pixel); - return (mdproto != 0 && dev_proc(dev, draw_thin_line) == dev_proc(mdproto, draw_thin_line)); + return (dev_proc(dev, draw_thin_line) == mem_draw_thin_line); } /* Make a memory device. */ @@ -149,8 +177,9 @@ void gs_make_mem_device(gx_device_memory * dev, const gx_device_memory * mdproto, gs_memory_t * mem, int page_device, gx_device * target) { - gx_device_init((gx_device *) dev, (const gx_device *)mdproto, - mem, true); + /* Can never fail */ + (void)gx_device_init((gx_device *) dev, (const gx_device *)mdproto, + mem, true); dev->stype = &st_device_memory; switch (page_device) { case -1: @@ -297,8 +326,10 @@ void gs_make_mem_mono_device(gx_device_memory * dev, gs_memory_t * mem, gx_device * target) { - gx_device_init((gx_device *)dev, (const gx_device *)&mem_mono_device, - mem, true); + /* Can never fail */ + (void)gx_device_init((gx_device *)dev, + (const gx_device *)&mem_mono_device, + mem, true); set_dev_proc(dev, get_page_device, gx_default_get_page_device); gx_device_set_target((gx_device_forward *)dev, target); dev->raster = gx_device_raster((gx_device *)dev, 1); @@ -624,7 +655,7 @@ mem_close(gx_device * dev) #define chunk byte int mem_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_memory * const mdev = (gx_device_memory *)dev; gs_get_bits_options_t options = params->options; @@ -720,7 +751,7 @@ mem_swap_byte_rect(byte * base, uint raster, int x, int w, int h, bool store) /* Copy a word-oriented rectangle to the client, swapping bytes as needed. */ int mem_word_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_memory * const mdev = (gx_device_memory *)dev; byte *src; @@ -736,8 +767,7 @@ mem_word_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, if (w <= 0 || h <= 0) { /* * It's easiest to just keep going with an empty rectangle. - * We pass the original rectangle to mem_get_bits_rectangle, - * so unread will be filled in correctly. + * We pass the original rectangle to mem_get_bits_rectangle. */ x = y = w = h = 0; } @@ -749,7 +779,7 @@ mem_word_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, src = scan_line_base(mdev, y); mem_swap_byte_rect(src, dev_raster, bit_x, bit_w, h, false); - code = mem_get_bits_rectangle(dev, prect, params, unread); + code = mem_get_bits_rectangle(dev, prect, params); mem_swap_byte_rect(src, dev_raster, bit_x, bit_w, h, false); return code; } @@ -827,11 +857,20 @@ mem_mapped_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value prgb[3]) { gx_device_memory * const mdev = (gx_device_memory *)dev; - const byte *pptr = mdev->palette.data + (int)color * 3; + const byte *pptr = mdev->palette.data; - prgb[0] = gx_color_value_from_byte(pptr[0]); - prgb[1] = gx_color_value_from_byte(pptr[1]); - prgb[2] = gx_color_value_from_byte(pptr[2]); + if (pptr == NULL) { + color = color * gx_max_color_value / ((1<<mdev->color_info.depth)-1); + prgb[0] = color; + prgb[1] = color; + prgb[2] = color; + } else { + pptr += (int)color * 3; + + prgb[0] = gx_color_value_from_byte(pptr[0]); + prgb[1] = gx_color_value_from_byte(pptr[1]); + prgb[2] = gx_color_value_from_byte(pptr[2]); + } return 0; } @@ -848,3 +887,73 @@ mem_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); } + +void mem_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, get_initial_matrix, mem_get_initial_matrix); + set_dev_proc(dev, sync_output, gx_default_sync_output); + set_dev_proc(dev, output_page, gx_default_output_page); + set_dev_proc(dev, close_device, mem_close); + set_dev_proc(dev, get_params, gx_default_get_params); + set_dev_proc(dev, put_params, gx_default_put_params); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, stroke_path, gx_default_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, mem_draw_thin_line); + set_dev_proc(dev, get_clipping_box, gx_default_get_clipping_box); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, composite, gx_default_composite); + set_dev_proc(dev, get_hardware_params, gx_default_get_hardware_params); + set_dev_proc(dev, text_begin, gx_default_text_begin); + set_dev_proc(dev, transform_pixel_region, mem_transform_pixel_region); + + /* Defaults that may well get overridden. */ + set_dev_proc(dev, open_device, mem_open); + set_dev_proc(dev, copy_alpha, gx_default_copy_alpha); + set_dev_proc(dev, map_cmyk_color, gx_default_map_cmyk_color); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, get_bits_rectangle, mem_get_bits_rectangle); +} + +void mem_dev_initialize_device_procs(gx_device *dev) +{ + int depth = dev->color_info.depth; + const gdev_mem_functions *fns; + + if (dev->is_planar) + depth /= dev->color_info.num_components; + fns = gdev_mem_functions_for_bits(depth); + + mem_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, fns->map_rgb_color); + set_dev_proc(dev, map_color_rgb, fns->map_color_rgb); + set_dev_proc(dev, fill_rectangle, fns->fill_rectangle); + set_dev_proc(dev, copy_mono, fns->copy_mono); + set_dev_proc(dev, copy_color, fns->copy_color); + set_dev_proc(dev, copy_alpha, fns->copy_alpha); + set_dev_proc(dev, strip_copy_rop2, fns->strip_copy_rop2); + set_dev_proc(dev, strip_tile_rectangle, fns->strip_tile_rectangle); +} + +void mem_word_dev_initialize_device_procs(gx_device *dev) +{ + const gdev_mem_functions *fns = + gdev_mem_word_functions_for_bits(dev->color_info.depth); + + mem_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, fns->map_rgb_color); + set_dev_proc(dev, map_color_rgb, fns->map_color_rgb); + set_dev_proc(dev, fill_rectangle, fns->fill_rectangle); + set_dev_proc(dev, copy_mono, fns->copy_mono); + set_dev_proc(dev, copy_color, fns->copy_color); + set_dev_proc(dev, copy_alpha, fns->copy_alpha); + set_dev_proc(dev, strip_copy_rop2, fns->strip_copy_rop2); + set_dev_proc(dev, strip_tile_rectangle, fns->strip_tile_rectangle); +} diff --git a/base/gdevmem.h b/base/gdevmem.h index 71db0797..ef2b7c60 100644 --- a/base/gdevmem.h +++ b/base/gdevmem.h @@ -101,7 +101,6 @@ dev_proc_get_bits_rectangle(mem_word_get_bits_rectangle); dev_proc_map_rgb_color(mem_mapped_map_rgb_color); dev_proc_map_color_rgb(mem_mapped_map_color_rgb); /* Default implementations */ -dev_proc_strip_copy_rop(mem_default_strip_copy_rop); dev_proc_strip_copy_rop2(mem_default_strip_copy_rop2); dev_proc_transform_pixel_region(mem_transform_pixel_region); @@ -120,8 +119,13 @@ dev_proc_transform_pixel_region(mem_transform_pixel_region); #define max_value_rgb(rgb_depth, gray_depth)\ (rgb_depth >= 8 ? 255 : rgb_depth == 4 ? 15 : rgb_depth == 2 ? 3 :\ rgb_depth == 1 ? 1 : (1 << gray_depth) - 1) -#define mem_full_alpha_device_hl(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, copy_alpha, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle, fill_rectangle_hl_color)\ -{ std_device_dci_body(gx_device_memory, 0, name,\ + +void mem_initialize_device_procs(gx_device *dev); +void mem_dev_initialize_device_procs(gx_device *dev); +void mem_word_dev_initialize_device_procs(gx_device *dev); + +#define mem_device(name, rgb_depth, gray_depth, initialize)\ +{ std_device_dci_body(gx_device_memory, initialize, name,\ 0, 0, 72, 72,\ (rgb_depth ? 3 : 0) + (gray_depth ? 1 : 0), /* num_components */\ rgb_depth + gray_depth, /* depth */\ @@ -130,110 +134,10 @@ dev_proc_transform_pixel_region(mem_transform_pixel_region); max_value_gray(rgb_depth, gray_depth) + 1, /* dither_grays */\ max_value_rgb(rgb_depth, gray_depth) + 1 /* dither_colors */\ ),\ - { open, /* differs */\ - mem_get_initial_matrix,\ - gx_default_sync_output,\ - gx_default_output_page,\ - mem_close,\ - map_rgb_color, /* differs */\ - map_color_rgb, /* differs */\ - fill_rectangle, /* differs */\ - gx_default_tile_rectangle,\ - copy_mono, /* differs */\ - copy_color, /* differs */\ - gx_default_draw_line,\ - gx_default_get_bits,\ - gx_default_get_params,\ - gx_default_put_params,\ - map_cmyk_color, /* differs */\ - gx_forward_get_xfont_procs,\ - gx_forward_get_xfont_device,\ - gx_default_map_rgb_alpha_color,\ - gx_forward_get_page_device,\ - gx_default_get_alpha_bits, /* default is no alpha */\ - copy_alpha, /* differs */\ - gx_default_get_band,\ - gx_default_copy_rop,\ - gx_default_fill_path,\ - gx_default_stroke_path,\ - gx_default_fill_mask,\ - gx_default_fill_trapezoid,\ - gx_default_fill_parallelogram,\ - gx_default_fill_triangle,\ - mem_draw_thin_line, /* see above */\ - gx_default_begin_image,\ - gx_default_image_data,\ - gx_default_end_image,\ - strip_tile_rectangle, /* differs */\ - strip_copy_rop, /* differs */\ - gx_default_get_clipping_box,\ - gx_default_begin_typed_image,\ - get_bits_rectangle, /* differs */\ - gx_default_map_color_rgb_alpha,\ - gx_default_create_compositor,\ - gx_default_get_hardware_params,\ - gx_default_text_begin,\ - gx_default_finish_copydevice,\ - NULL, /* begin_transparency_group */\ - NULL, /* end_transparency_group */\ - NULL, /* begin_transparency_mask */\ - NULL, /* end_transparency_mask */\ - NULL, /* discard_transparency_layer */\ - NULL, /* get_color_mapping_procs */\ - NULL, /* get_color_comp_index */\ - NULL, /* encode_color */\ - NULL, /* decode_color */\ - NULL, /* pattern_manage */\ - fill_rectangle_hl_color, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - NULL, /* update_spot_equivalent_colors */\ - NULL, /* ret_devn_params */\ - NULL, /* fillpage */\ - NULL, /* push_transparency_state */\ - NULL, /* pop_transparency_state */\ - NULL, /* put_image */\ - NULL, /* dev_spec_op */\ - NULL, /* copy_planes */\ - NULL, /* get_profile */\ - NULL, /* set_graphics_type_tag */\ - NULL, /* strip_copy_rop2 */\ - NULL, /* strip_tile_rect_devn */\ - NULL, /* copy_alpha_hl_color */\ - NULL, /* process_page */\ - mem_transform_pixel_region,\ - NULL, /* fill_stroke_path */\ - },\ + { 0 },\ 0, /* target */\ mem_device_init_private /* see gxdevmem.h */\ } -#define mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, copy_alpha, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\ - mem_full_alpha_device_hl(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, copy_alpha, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle, NULL) - -#define mem_full_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\ - mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color,\ - map_color_rgb, copy_mono, copy_color, fill_rectangle,\ - map_cmyk_color, gx_default_copy_alpha,\ - strip_tile_rectangle, strip_copy_rop,\ - get_bits_rectangle) -#define mem_device(name, rgb_depth, gray_depth, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, strip_copy_rop)\ - mem_full_device(name, rgb_depth, gray_depth, mem_open, map_rgb_color,\ - map_color_rgb, copy_mono, copy_color, fill_rectangle,\ - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,\ - strip_copy_rop, mem_get_bits_rectangle) -#define mem_full_device_hl(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle, fill_rectangle_hl)\ - mem_full_alpha_device_hl(name, rgb_depth, gray_depth, open, map_rgb_color,\ - map_color_rgb, copy_mono, copy_color, fill_rectangle,\ - map_cmyk_color, gx_default_copy_alpha,\ - strip_tile_rectangle, strip_copy_rop,\ - get_bits_rectangle, fill_rectangle_hl) -#define mem_device_hl(name, rgb_depth, gray_depth, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, strip_copy_rop, fill_rectangle_hl)\ - mem_full_device_hl(name, rgb_depth, gray_depth, mem_open, map_rgb_color,\ - map_color_rgb, copy_mono, copy_color, fill_rectangle,\ - gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,\ - strip_copy_rop, mem_get_bits_rectangle, fill_rectangle_hl) /* Swap a rectangle of bytes, for converting between word- and */ /* byte-oriented representation. */ @@ -265,10 +169,12 @@ extern const gx_device_memory mem_planar_device; * We declare the RasterOp implementation procedures here because they are * referenced in several implementation modules. */ -dev_proc_strip_copy_rop(mem_mono_strip_copy_rop); -dev_proc_strip_copy_rop(mem_mono_strip_copy_rop_dev); -dev_proc_strip_copy_rop(mem_gray_strip_copy_rop); -dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop); +dev_proc_strip_copy_rop2(mem_mono_strip_copy_rop2); +dev_proc_strip_copy_rop2(mem_mono_strip_copy_rop2_dev); +dev_proc_strip_copy_rop2(mem_gray_strip_copy_rop2); +dev_proc_strip_copy_rop2(mem_gray8_rgb24_strip_copy_rop2); +dev_proc_copy_mono(mem_mono_copy_mono); +dev_proc_fill_rectangle(mem_mono_fill_rectangle); #if ARCH_IS_BIG_ENDIAN # define mem_mono_word_device mem_mono_device diff --git a/base/gdevmpla.c b/base/gdevmpla.c index d233a132..632610d3 100644 --- a/base/gdevmpla.c +++ b/base/gdevmpla.c @@ -37,7 +37,6 @@ static dev_proc_copy_planes(mem_planar_copy_planes); /* Not static due to an optimized case in tile_clip_fill_rectangle_hl_color*/ static dev_proc_strip_tile_rectangle(mem_planar_strip_tile_rectangle); static dev_proc_strip_tile_rect_devn(mem_planar_strip_tile_rect_devn); -static dev_proc_strip_copy_rop(mem_planar_strip_copy_rop); static dev_proc_strip_copy_rop2(mem_planar_strip_copy_rop2); static dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle); static dev_proc_fill_rectangle_hl_color(mem_planar_fill_rectangle_hl_color); @@ -94,7 +93,8 @@ gdev_mem_set_planar_interleaved(gx_device_memory * mdev, int num_planes, int same_depth = planes[0].depth; gx_color_index covered = 0; int pi; - const gx_device_memory *mdproto = gdev_mem_device_for_bits(mdev->color_info.depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(mdev->color_info.depth); if (num_planes < 1 || num_planes > GX_DEVICE_COLOR_MAX_COMPONENTS || num_planes != mdev->color_info.num_components) return_error(gs_error_rangecheck); @@ -136,20 +136,20 @@ gdev_mem_set_planar_interleaved(gx_device_memory * mdev, int num_planes, mem_planar_fill_rectangle_hl_color); if (num_planes == 1) { /* For 1 plane, just use a normal device */ - set_dev_proc(mdev, fill_rectangle, dev_proc(mdproto, fill_rectangle)); - set_dev_proc(mdev, copy_mono, dev_proc(mdproto, copy_mono)); - set_dev_proc(mdev, copy_color, dev_proc(mdproto, copy_color)); - set_dev_proc(mdev, copy_alpha, dev_proc(mdproto, copy_alpha)); - set_dev_proc(mdev, strip_tile_rectangle, dev_proc(mdproto, strip_tile_rectangle)); - set_dev_proc(mdev, strip_copy_rop, dev_proc(mdproto, strip_copy_rop)); - set_dev_proc(mdev, strip_copy_rop2, dev_proc(mdproto, strip_copy_rop2)); - set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle)); + set_dev_proc(mdev, fill_rectangle, fns->fill_rectangle); + set_dev_proc(mdev, copy_mono, fns->copy_mono); + set_dev_proc(mdev, copy_color, fns->copy_color); + set_dev_proc(mdev, copy_alpha, fns->copy_alpha); + set_dev_proc(mdev, strip_tile_rectangle, fns->strip_tile_rectangle); + set_dev_proc(mdev, strip_copy_rop2, fns->strip_copy_rop2); + set_dev_proc(mdev, get_bits_rectangle, fns->get_bits_rectangle); } else { /* If we are going out to a separation device or one that has more than four planes then use the high level color filling procedure. Also make use of the put_image operation to go from the pdf14 device directly to the planar buffer. */ - if (num_planes >= 4) { + /* Note this is only valid for contone (8 or more bits per component) */ + if (num_planes >= 4 && mdev->color_info.depth/num_planes >= 8) { set_dev_proc(mdev, put_image, mem_planar_put_image); } set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle); @@ -175,7 +175,6 @@ gdev_mem_set_planar_interleaved(gx_device_memory * mdev, int num_planes, set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha); set_dev_proc(mdev, strip_tile_rectangle, mem_planar_strip_tile_rectangle); set_dev_proc(mdev, strip_tile_rect_devn, mem_planar_strip_tile_rect_devn); - set_dev_proc(mdev, strip_copy_rop, mem_planar_strip_copy_rop); set_dev_proc(mdev, strip_copy_rop2, mem_planar_strip_copy_rop2); set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle); } @@ -247,7 +246,7 @@ put_image_copy_planes(gx_device * dev, const byte **base_ptr, int sourcex, gx_device_memory * const mdev = (gx_device_memory *)dev; int plane_depth; mem_save_params_t save; - const gx_device_memory *mdproto; + const gdev_mem_functions *fns; int code = 0; uchar plane; @@ -256,19 +255,17 @@ put_image_copy_planes(gx_device * dev, const byte **base_ptr, int sourcex, { const byte *base = base_ptr[plane]; plane_depth = mdev->planes[plane].depth; - mdproto = gdev_mem_device_for_bits(plane_depth); + fns = gdev_mem_functions_for_bits(plane_depth); if (base == NULL) { /* Blank the plane */ - code = dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, + code = fns->fill_rectangle(dev, x, y, w, h, (gx_color_index)(dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ? 0 : -1)); } else if (plane_depth == 1) - code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id, - x, y, w, h, - (gx_color_index)0, - (gx_color_index)1); + code = fns->copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, + (gx_color_index)0, (gx_color_index)1); else - code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster, - id, x, y, w, h); + fns->copy_color(dev, base, sourcex, sraster, id, x, y, w, h); mdev->line_ptrs += mdev->height; } MEM_RESTORE_PARAMS(mdev, save); @@ -319,11 +316,12 @@ mem_planar_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; int shift = 16 - plane_depth; - const gx_device_memory *mdproto = gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); MEM_SET_PARAMS(mdev, plane_depth); - dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, - (pdcolor->colors.devn.values[pi]) >> shift & mask); + fns->fill_rectangle(dev, x, y, w, h, + (pdcolor->colors.devn.values[pi]) >> shift & mask); mdev->line_ptrs += mdev->height; } MEM_RESTORE_PARAMS(mdev, save); @@ -343,13 +341,12 @@ mem_planar_fill_rectangle(gx_device * dev, int x, int y, int w, int h, for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; - const gx_device_memory *mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); MEM_SET_PARAMS(mdev, plane_depth); - dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, - (color >> mdev->planes[pi].shift) & - mask); + fns->fill_rectangle(dev, x, y, w, h, + (color >> mdev->planes[pi].shift) & mask); mdev->line_ptrs += mdev->height; } MEM_RESTORE_PARAMS(mdev, save); @@ -371,8 +368,8 @@ mem_planar_copy_mono(gx_device * dev, const byte * base, int sourcex, int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; - const gx_device_memory *mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); gx_color_index c0 = (color0 == gx_no_color_index ? gx_no_color_index : (color0 >> shift) & mask); @@ -382,10 +379,10 @@ mem_planar_copy_mono(gx_device * dev, const byte * base, int sourcex, MEM_SET_PARAMS(mdev, plane_depth); if (c0 == c1) - dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, c0); + fns->fill_rectangle(dev, x, y, w, h, c0); else - dev_proc(mdproto, copy_mono) - (dev, base, sourcex, sraster, id, x, y, w, h, c0, c1); + fns->copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, c0, c1); mdev->line_ptrs += mdev->height; } MEM_RESTORE_PARAMS(mdev, save); @@ -406,7 +403,8 @@ mem_planar_copy_color_24to8(gx_device * dev, const byte * base, int sourcex, byte b[BUF_BYTES]; } buf, buf1, buf2; mem_save_params_t save; - const gx_device_memory *mdproto = gdev_mem_device_for_bits(8); + dev_proc_copy_color((*copy_color)) = + gdev_mem_functions_for_bits(8)->copy_color; uint plane_raster = bitmap_raster(w<<3); int br, bw, bh, cx, cy, cw, ch, ix, iy; @@ -449,14 +447,11 @@ mem_planar_copy_color_24to8(gx_device * dev, const byte * base, int sourcex, } while (--ix); source_base += sraster; } - dev_proc(mdproto, copy_color) - (dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); + copy_color(dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_color) - (dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); + copy_color(dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_color) - (dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); + copy_color(dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); mdev->line_ptrs -= 2*mdev->height; } } @@ -485,7 +480,8 @@ mem_planar_copy_color_4to1(gx_device * dev, const byte * base, int sourcex, byte b[BUF_BYTES]; } buf0, buf1, buf2, buf3; mem_save_params_t save; - const gx_device_memory *mdproto = gdev_mem_device_for_bits(1); + dev_proc_copy_mono((*copy_mono)) = + gdev_mem_fill_functions_for_bits(1)->copy_mono; uint plane_raster = bitmap_raster(w); int br, bw, bh, cx, cy, cw, ch, ix, iy; @@ -632,21 +628,17 @@ loop_entry: source_base += sraster; } } - dev_proc(mdproto, copy_mono) - (dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs -= 3*mdev->height; } } @@ -736,7 +728,8 @@ mem_planar_copy_color_4to1(gx_device * dev, const byte * base, int sourcex, byte b[BUF_BYTES]; } buf0, buf1, buf2, buf3; mem_save_params_t save; - const gx_device_memory *mdproto = gdev_mem_device_for_bits(1); + dev_proc_copy_mono((*copy_mono)) = + gdev_mem_functions_for_bits(1)->copy_mono; uint plane_raster = bitmap_raster(w); int br, bw, bh, cx, cy, cw, ch, ix, iy; @@ -833,21 +826,17 @@ loop_entry: source_base += sraster; } } - dev_proc(mdproto, copy_mono) - (dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs += mdev->height; - dev_proc(mdproto, copy_mono) - (dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, - (gx_color_index)0, (gx_color_index)1); + copy_mono(dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, + (gx_color_index)0, (gx_color_index)1); mdev->line_ptrs -= 3*mdev->height; } } @@ -888,8 +877,8 @@ mem_planar_copy_color(gx_device * dev, const byte * base, int sourcex, int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; - const gx_device_memory *mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); /* * Divide up the transfer into chunks that can be assembled * within the fixed-size buffer. This code can be simplified @@ -960,11 +949,11 @@ mem_planar_copy_color(gx_device * dev, const byte * base, int sourcex, * defined in terms of copy_mono. */ if (plane_depth == 1) - dev_proc(mdproto, copy_mono) + fns->copy_mono (dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch, (gx_color_index)0, (gx_color_index)1); else - dev_proc(mdproto, copy_color) + fns->copy_color (dev, buf.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch); } } @@ -983,25 +972,23 @@ mem_planar_copy_planes(gx_device * dev, const byte * base, int sourcex, int x, int y, int w, int h, int plane_height) { gx_device_memory * const mdev = (gx_device_memory *)dev; - int plane_depth; mem_save_params_t save; - const gx_device_memory *mdproto; int code = 0; uchar plane; MEM_SAVE_PARAMS(mdev, save); for (plane = 0; plane < mdev->color_info.num_components; plane++) { - plane_depth = mdev->planes[plane].depth; - mdproto = gdev_mem_device_for_bits(plane_depth); + int plane_depth = mdev->planes[plane].depth; + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); if (plane_depth == 1) - code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id, - x, y, w, h, - (gx_color_index)0, - (gx_color_index)1); + code = fns->copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, + (gx_color_index)0, (gx_color_index)1); else - code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster, - id, x, y, w, h); + code = fns->copy_color(dev, base, sourcex, sraster, + id, x, y, w, h); base += sraster * plane_height; mdev->line_ptrs += mdev->height; } @@ -1024,8 +1011,8 @@ mem_planar_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; int shift = 16 - plane_depth; - const gx_device_memory *mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); gx_color_index c1, c0; if (pdcolor0->type == gx_dc_type_devn) { @@ -1045,15 +1032,14 @@ mem_planar_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, #endif MEM_SET_PARAMS(mdev, plane_depth); if (c0 == c1) - dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, c0); + fns->fill_rectangle(dev, x, y, w, h, c0); else { /* * Temporarily replace copy_mono in case strip_tile_rectangle is * defined in terms of it. */ - set_dev_proc(dev, copy_mono, dev_proc(mdproto, copy_mono)); - dev_proc(mdproto, strip_tile_rectangle) - (dev, tiles, x, y, w, h, c0, c1, px, py); + set_dev_proc(dev, copy_mono, fns->copy_mono); + fns->strip_tile_rectangle(dev, tiles, x, y, w, h, c0, c1, px, py); } mdev->line_ptrs += mdev->height; } @@ -1081,8 +1067,8 @@ mem_planar_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; - const gx_device_memory *mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); gx_color_index c0 = (color0 == gx_no_color_index ? gx_no_color_index : (color0 >> shift) & mask); @@ -1092,15 +1078,14 @@ mem_planar_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, MEM_SET_PARAMS(mdev, plane_depth); if (c0 == c1) - dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, c0); + fns->fill_rectangle(dev, x, y, w, h, c0); else { /* * Temporarily replace copy_mono in case strip_tile_rectangle is * defined in terms of it. */ - set_dev_proc(dev, copy_mono, dev_proc(mdproto, copy_mono)); - dev_proc(mdproto, strip_tile_rectangle) - (dev, tiles, x, y, w, h, c0, c1, px, py); + set_dev_proc(dev, copy_mono, fns->copy_mono); + fns->strip_tile_rectangle(dev, tiles, x, y, w, h, c0, c1, px, py); } mdev->line_ptrs += mdev->height; } @@ -1110,14 +1095,15 @@ mem_planar_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, } static int -planar_cmyk4bit_strip_copy_rop(gx_device_memory * mdev, - const byte * srow, int sourcex, uint sraster, - gx_bitmap_id id, const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop) +planar_cmyk4bit_strip_copy_rop2(gx_device_memory * mdev, + const byte * srow, int sourcex, uint sraster, + gx_bitmap_id id, const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, + gs_logical_operation_t lop, + uint planar_height) { gs_rop3_t rop = (gs_rop3_t)lop; uint draster = mdev->raster; @@ -1130,6 +1116,8 @@ planar_cmyk4bit_strip_copy_rop(gx_device_memory * mdev, int ctcolor = 0, mtcolor = 0, ytcolor = 0, ktcolor = 0; int constant_s = 0; + /* assert(planar_height == 0) */ + /* Modify the raster operation according to the source palette. */ fit_copy(mdev, srow, sourcex, sraster, id, x, y, width, height); @@ -1722,32 +1710,39 @@ planar_cmyk4bit_strip_copy_rop(gx_device_memory * mdev, } static int -plane_strip_copy_rop(gx_device_memory * mdev, - const byte * sdata, int sourcex, uint sraster, - gx_bitmap_id id, const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop, int plane) +plane_strip_copy_rop2(gx_device_memory * mdev, + const byte * sdata, int sourcex, uint sraster, + gx_bitmap_id id, const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, + gs_logical_operation_t lop, int plane, + uint planar_height) { mem_save_params_t save; int code; - const gx_device_memory *mdproto; + const gdev_mem_functions *fns; + int n; + + /* assert(planar_height == 0); */ MEM_SAVE_PARAMS(mdev, save); mdev->line_ptrs += mdev->height * plane; - mdproto = gdev_mem_device_for_bits(mdev->planes[plane].depth); - /* strip_copy_rop might end up calling get_bits_rectangle or fill_rectangle, + fns = gdev_mem_functions_for_bits(mdev->planes[plane].depth); + /* strip_copy_rop2 might end up calling get_bits_rectangle or fill_rectangle, * so ensure we have the right ones in there. */ - set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle)); - set_dev_proc(mdev, fill_rectangle, dev_proc(mdproto, fill_rectangle)); + set_dev_proc(mdev, get_bits_rectangle, fns->get_bits_rectangle); + set_dev_proc(mdev, fill_rectangle, fns->fill_rectangle); /* mdev->color_info.depth is restored by MEM_RESTORE_PARAMS below. */ mdev->color_info.depth = mdev->planes[plane].depth; - code = dev_proc(mdproto, strip_copy_rop)((gx_device *)mdev, sdata, sourcex, sraster, - id, scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop); + n = mdev->color_info.num_components; + mdev->color_info.num_components = 1; + code = fns->strip_copy_rop2((gx_device *)mdev, sdata, sourcex, sraster, + id, scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, planar_height); + mdev->color_info.num_components = n; set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle); set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle); /* The following effectively does: mdev->line_ptrs -= mdev->height * plane; */ @@ -1881,22 +1876,6 @@ static byte cmykrop[256] = }; static int -mem_planar_strip_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, - gx_bitmap_id id, const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop) -{ - return mem_planar_strip_copy_rop2(dev, sdata, sourcex, sraster, - id, scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop, 0); -} - -static int mem_planar_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, @@ -2043,11 +2022,11 @@ mem_planar_strip_copy_rop2(gx_device * dev, scolors2[0] = (scolors[0] >> shift) & mask; scolors2[1] = (scolors[1] >> shift) & mask; } - code = plane_strip_copy_rop(mdev, sdata, sourcex, sraster, - id, (scolors ? scolors2 : NULL), - textures, (tcolors ? tcolors2 : NULL), - x, y, width, height, - phase_x, phase_y, lop, plane); + code = plane_strip_copy_rop2(mdev, sdata, sourcex, sraster, + id, (scolors ? scolors2 : NULL), + textures, (tcolors ? tcolors2 : NULL), + x, y, width, height, + phase_x, phase_y, lop, plane, 0); if (code < 0) return code; } @@ -2056,37 +2035,36 @@ mem_planar_strip_copy_rop2(gx_device * dev, if ((mdev->color_info.num_components == 4) && (mdev->plane_depth == 1)) { lop = cmykrop[lop & 0xff] | (lop & ~0xff); - return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex, - sraster, id, scolors, - textures, tcolors, - x, y, width, height, - phase_x, phase_y, - lop); + return planar_cmyk4bit_strip_copy_rop2(mdev, sdata, sourcex, + sraster, id, scolors, + textures, tcolors, + x, y, width, height, + phase_x, phase_y, + lop, 0); } } if (!tcolors && !scolors && (mdev->color_info.num_components == 4) && (mdev->plane_depth == 1)) { lop = cmykrop[lop & 0xff] | (lop & ~0xff); - return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex, - sraster, id, scolors, - textures, tcolors, - x, y, width, height, - phase_x, phase_y, - lop); + return planar_cmyk4bit_strip_copy_rop2(mdev, sdata, sourcex, + sraster, id, scolors, + textures, tcolors, + x, y, width, height, + phase_x, phase_y, + lop, 0); } /* Fall back to the default implementation (the only one that * guarantees to properly cope with D being planar). */ - return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, - id, scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop); + return mem_default_strip_copy_rop2(dev, sdata, sourcex, sraster, + id, scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, 0); } /* Copy bits back from a planar memory device. */ static int mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, - gs_int_rect ** unread) + gs_get_bits_params_t * params) { /* This duplicates most of mem_get_bits_rectangle. Tant pgs. */ gx_device_memory * const mdev = (gx_device_memory *)dev; @@ -2180,8 +2158,7 @@ mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, MEM_SAVE_PARAMS(mdev, save); mdev->line_ptrs += mdev->height * plane; MEM_SET_PARAMS(mdev, mdev->planes[plane].depth); - code = mem_get_bits_rectangle(dev, prect, ©_params, - unread); + code = mem_get_bits_rectangle(dev, prect, ©_params); MEM_RESTORE_PARAMS(mdev, save); if (code >= 0) { params->data[plane] = copy_params.data[0]; diff --git a/base/gdevmplt.c b/base/gdevmplt.c index 89720535..85e5e87f 100644 --- a/base/gdevmplt.c +++ b/base/gdevmplt.c @@ -41,6 +41,7 @@ #include "gdevsclass.h" #include "gdevmplt.h" #include "gxdcconv.h" /* for color_rgb_to_gray and color_cmyk_to_gray */ +#include "gxdevsop.h" /* Device procedures, we only need one */ static dev_proc_get_color_mapping_procs(pcl_mono_palette_get_color_mapping_procs); @@ -69,92 +70,58 @@ RELOC_PTRS_END public_st_pcl_mono_palette_device(); +static int +pcl_mono_dev_spec_op(gx_device *dev, int dev_spec_op, void *data, int size) +{ + if (dev_spec_op == gxdso_supports_hlcolor) + return 0; + if (dev->child) + return dev_proc(dev->child, dev_spec_op)(dev->child, dev_spec_op, data, size); + return_error(gs_error_rangecheck); +} + +static int +pcl_mono_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, + gs_font *font, const gx_clip_path *pcpath, gs_text_enum_t **ppte) +{ + /* The 'high level' version of the color has not been 'monochromized' by this + * device, so ensure that routines that we call (notably pdfwrite) don't + * think it's valid and use it. */ + pgs->color[0].dev_color->ccolor_valid = 0; + + if (dev->child) + return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, pcpath, ppte); + else + return gx_default_text_begin(dev, pgs, text, font, pcpath, ppte); +} + +static void +pcl_mono_palette_initialize(gx_device *dev) +{ + default_subclass_initialize_device_procs(dev); + + set_dev_proc(dev, get_color_mapping_procs, pcl_mono_palette_get_color_mapping_procs); + /* We must override begin_typed_image here with the default. If + * we don't, then we forward down to the underlying devices own + * begin_typed_image, and the color calls done during that bypass + * the monochroming behaviour. See: page 32 of 75dpi png rendering of + * tests_private/pcl/pcl5ccet/15-01.BIN for an example. */ + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, dev_spec_op, pcl_mono_dev_spec_op); + set_dev_proc(dev, text_begin, pcl_mono_text_begin); +} + const gx_device_mplt gs_pcl_mono_palette_device = { /* * Define the device as 8-bit gray scale to avoid computing halftones. */ - std_device_dci_type_body(gx_device_mplt, 0, "PCL_Mono_Palette", &st_pcl_mono_palette_device, + std_device_dci_type_body_sc(gx_device_mplt, pcl_mono_palette_initialize, + "PCL_Mono_Palette", &st_pcl_mono_palette_device, MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, - 1, 8, 255, 0, 256, 1), - {default_subclass_open_device, - default_subclass_get_initial_matrix, - default_subclass_sync_output, /* sync_output */ - default_subclass_output_page, - default_subclass_close_device, - default_subclass_map_rgb_color, - default_subclass_map_color_rgb, - default_subclass_fill_rectangle, - default_subclass_tile_rectangle, /* tile_rectangle */ - default_subclass_copy_mono, - default_subclass_copy_color, - default_subclass_draw_line, /* draw_line */ - default_subclass_get_bits, /* get_bits */ - default_subclass_get_params, - default_subclass_put_params, - default_subclass_map_cmyk_color, - default_subclass_get_xfont_procs, /* get_xfont_procs */ - default_subclass_get_xfont_device, /* get_xfont_device */ - default_subclass_map_rgb_alpha_color, - default_subclass_get_page_device, - default_subclass_get_alpha_bits, /* get_alpha_bits */ - default_subclass_copy_alpha, - default_subclass_get_band, /* get_band */ - default_subclass_copy_rop, /* copy_rop */ - default_subclass_fill_path, - default_subclass_stroke_path, - default_subclass_fill_mask, - default_subclass_fill_trapezoid, - default_subclass_fill_parallelogram, - default_subclass_fill_triangle, - default_subclass_draw_thin_line, - default_subclass_begin_image, - default_subclass_image_data, /* image_data */ - default_subclass_end_image, /* end_image */ - default_subclass_strip_tile_rectangle, - default_subclass_strip_copy_rop, - default_subclass_get_clipping_box, /* get_clipping_box */ - default_subclass_begin_typed_image, - default_subclass_get_bits_rectangle, /* get_bits_rectangle */ - default_subclass_map_color_rgb_alpha, - default_subclass_create_compositor, - default_subclass_get_hardware_params, /* get_hardware_params */ - default_subclass_text_begin, - default_subclass_finish_copydevice, /* finish_copydevice */ - default_subclass_begin_transparency_group, /* begin_transparency_group */ - default_subclass_end_transparency_group, /* end_transparency_group */ - default_subclass_begin_transparency_mask, /* begin_transparency_mask */ - default_subclass_end_transparency_mask, /* end_transparency_mask */ - default_subclass_discard_transparency_layer, /* discard_transparency_layer */ - pcl_mono_palette_get_color_mapping_procs, /* get_color_mapping_procs */ - default_subclass_get_color_comp_index, /* get_color_comp_index */ - default_subclass_encode_color, /* encode_color */ - default_subclass_decode_color, /* decode_color */ - default_subclass_pattern_manage, /* pattern_manage */ - default_subclass_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - default_subclass_include_color_space, /* include_color_space */ - default_subclass_fill_linear_color_scanline, /* fill_linear_color_scanline */ - default_subclass_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ - default_subclass_fill_linear_color_triangle, /* fill_linear_color_triangle */ - default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ - default_subclass_ret_devn_params, /* ret_devn_params */ - default_subclass_fillpage, /* fillpage */ - default_subclass_push_transparency_state, /* push_transparency_state */ - default_subclass_pop_transparency_state, /* pop_transparency_state */ - default_subclass_put_image, /* put_image */ - default_subclass_dev_spec_op, /* dev_spec_op */ - default_subclass_copy_planes, /* copy_planes */ - default_subclass_get_profile, /* get_profile */ - default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ - default_subclass_strip_copy_rop2, - default_subclass_strip_tile_rect_devn, - default_subclass_copy_alpha_hl_color, - default_subclass_process_page, - default_subclass_transform_pixel_region, - default_subclass_fill_stroke_path, - } + 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) }; #undef MAX_COORD @@ -164,76 +131,70 @@ gx_device_mplt gs_pcl_mono_palette_device = * to gray values */ static void -pcl_gray_cs_to_cm(gx_device * dev, frac gray, frac out[]) +pcl_gray_cs_to_cm(const gx_device * dev, frac gray, frac out[]) { - pcl_mono_palette_subclass_data *psubclass_data; + pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data; - while(dev && dev->child) { - if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - break; - dev = dev->child; - }; + /* assert(strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - otherwise we are being + * called with the wrong dev! */ - if (dev && dev->child) { - psubclass_data = dev->subclass_data; + if (psubclass_data->device_cm) { /* just pass it along */ - psubclass_data->device_cm_procs->map_gray(dev, gray, out); - } else - return; + psubclass_data->device_cm_procs->map_gray(psubclass_data->device_cm, gray, out); + } } static void -pcl_rgb_cs_to_cm(gx_device * dev, const gs_gstate * pgs, frac r, frac g, +pcl_rgb_cs_to_cm(const gx_device * dev, const gs_gstate * pgs, frac r, frac g, frac b, frac out[]) { - pcl_mono_palette_subclass_data *psubclass_data; + pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data; frac gray; - while(dev && dev->child) { - if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - break; - dev = dev->child; - }; + /* assert(strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - otherwise we are being + * called with the wrong dev! */ - if (dev && dev->child) { - psubclass_data = dev->subclass_data; + if (psubclass_data->device_cm) { gray = color_rgb_to_gray(r, g, b, NULL); - psubclass_data->device_cm_procs->map_rgb(dev, pgs, gray, gray, gray, out); - } else - return; + psubclass_data->device_cm_procs->map_rgb(psubclass_data->device_cm, pgs, gray, gray, gray, out); + } } static void -pcl_cmyk_cs_to_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +pcl_cmyk_cs_to_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { - pcl_mono_palette_subclass_data *psubclass_data; + pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data; frac gray; - while(dev && dev->child) { - if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - break; - dev = dev->child; - }; + /* assert(strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - otherwise we are being + * called with the wrong dev! */ - if (dev && dev->child) { - psubclass_data = dev->subclass_data; + if (psubclass_data->device_cm) { gray = color_cmyk_to_gray(c, m, y, k, NULL); - psubclass_data->device_cm_procs->map_cmyk(dev, gray, gray, gray, gray, out); - } else - return; + psubclass_data->device_cm_procs->map_cmyk(psubclass_data->device_cm, gray, gray, gray, gray, out); + } } -const gx_cm_color_map_procs *pcl_mono_palette_get_color_mapping_procs(const gx_device *dev) +static gx_cm_color_map_procs pcl_mono_procs = +{ + pcl_gray_cs_to_cm, + pcl_rgb_cs_to_cm, + pcl_cmyk_cs_to_cm +}; + +const gx_cm_color_map_procs *pcl_mono_palette_get_color_mapping_procs(const gx_device *dev, + const gx_device **tdev) { pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data; - if (psubclass_data->device_cm_procs == 0L) { - psubclass_data->pcl_mono_procs.map_gray = pcl_gray_cs_to_cm; - psubclass_data->pcl_mono_procs.map_rgb = pcl_rgb_cs_to_cm; - psubclass_data->pcl_mono_procs.map_cmyk = pcl_cmyk_cs_to_cm; - psubclass_data->device_cm_procs = (gx_cm_color_map_procs *)dev_proc(dev->child, get_color_mapping_procs) (dev->child); + /* assert(strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) - otherwise we are being + * called with the wrong dev! */ + + *tdev = dev; + if (psubclass_data->device_cm_procs == NULL) { + psubclass_data->device_cm_procs = (gx_cm_color_map_procs *)dev_proc(dev->child, get_color_mapping_procs)(dev->child, &psubclass_data->device_cm); } - return &psubclass_data->pcl_mono_procs; + return &pcl_mono_procs; } diff --git a/base/gdevmplt.h b/base/gdevmplt.h index 669efdc7..de20ca25 100644 --- a/base/gdevmplt.h +++ b/base/gdevmplt.h @@ -29,7 +29,8 @@ void gx_device_pcl_mono_palette_init(gx_device_mplt * dev); typedef struct { subclass_common; gx_cm_color_map_procs pcl_mono_procs; - gx_cm_color_map_procs *device_cm_procs; + const gx_cm_color_map_procs *device_cm_procs; + const gx_device *device_cm; } pcl_mono_palette_subclass_data; extern_st(st_device_mplt); diff --git a/base/gdevmr1.c b/base/gdevmr1.c index ed2faab9..fb9a4373 100644 --- a/base/gdevmr1.c +++ b/base/gdevmr1.c @@ -23,7 +23,6 @@ #include "gxdcolor.h" #include "gxdevice.h" #include "gxdevmem.h" -#include "gxdevrop.h" #include "gdevmem.h" #include "gdevmrop.h" @@ -35,19 +34,22 @@ * does everything in device space. */ int -mem_mono_strip_copy_rop(gx_device * dev, const byte * sdata, - int sourcex,uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, - gs_logical_operation_t lop) +mem_mono_strip_copy_rop2(gx_device * dev, const byte * sdata, + int sourcex,uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, + gs_logical_operation_t lop, + uint planar_height) { gx_device_memory *mdev = (gx_device_memory *) dev; gs_rop3_t rop = lop_sanitize(lop); /* handle transparency */ bool invert; + /* assert(planar_height == 0); */ + /* If map_rgb_color isn't the default one for monobit memory */ /* devices, palette might not be set; set it now if needed. */ if (mdev->palette.data == 0) { @@ -80,8 +82,8 @@ mem_mono_strip_copy_rop(gx_device * dev, const byte * sdata, if (invert) rop = byte_reverse_bits[rop & 0xff] ^ 0xff; - return mem_mono_strip_copy_rop_dev(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, x, y, - width, height, phase_x, phase_y, - (gs_logical_operation_t)rop); + return mem_mono_strip_copy_rop2_dev(dev, sdata, sourcex, sraster, id, + scolors, textures, tcolors, x, y, + width, height, phase_x, phase_y, + (gs_logical_operation_t)rop, 0); } diff --git a/base/gdevmr2n.c b/base/gdevmr2n.c index a19b9f69..4a12eed2 100644 --- a/base/gdevmr2n.c +++ b/base/gdevmr2n.c @@ -23,7 +23,6 @@ #include "gxdcolor.h" #include "gxdevice.h" #include "gxdevmem.h" -#include "gxdevrop.h" #include "gdevmem.h" #include "gdevmrop.h" @@ -65,12 +64,13 @@ mem_gray_rop_strip_tile_rectangle(gx_device * dev, } int -mem_gray_strip_copy_rop(gx_device * dev, +mem_gray_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) + int phase_x, int phase_y, gs_logical_operation_t lop, + uint planar_height) { gx_color_index scolors2[2]; const gx_color_index *real_scolors = scolors; @@ -84,6 +84,8 @@ mem_gray_strip_copy_rop(gx_device * dev, gx_color_index max_pixel = ((gx_color_index)1 << depth) - 1; int code; + /* assert(planar_height == 0); */ + #ifdef DEBUG if (gs_debug_c('b')) trace_copy_rop("mem_gray_strip_copy_rop", @@ -99,10 +101,10 @@ mem_gray_strip_copy_rop(gx_device * dev, (tcolors && (tcolors[0] != tcolors[1])) ) { /* We can't fake it: do it the slow, painful way. */ - return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop); + return mem_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id, + scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, 0); } if (scolors) { /* Must be a solid color: see above. */ scolors2[0] = scolors2[1] = scolors[0] & 1; @@ -154,14 +156,15 @@ mem_gray_strip_copy_rop(gx_device * dev, set_dev_proc(dev, strip_tile_rectangle, mem_gray_rop_strip_tile_rectangle); dev->width <<= log2_depth; - code = mem_mono_strip_copy_rop(dev, sdata, - (real_scolors == NULL ? - sourcex << log2_depth : sourcex), - sraster, id, real_scolors, - real_texture, real_tcolors, - x << log2_depth, y, - width << log2_depth, height, - phase_x << log2_depth, phase_y, lop); + code = mem_mono_strip_copy_rop2(dev, sdata, + (real_scolors == NULL ? + sourcex << log2_depth : sourcex), + sraster, id, real_scolors, + real_texture, real_tcolors, + x << log2_depth, y, + width << log2_depth, height, + phase_x << log2_depth, phase_y, + lop, 0); set_dev_proc(dev, fill_rectangle, fill_rectangle); set_dev_proc(dev, copy_mono, copy_mono); set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle); @@ -169,9 +172,9 @@ mem_gray_strip_copy_rop(gx_device * dev, } /* If we punted, use the general procedure. */ if (code < 0) - return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop); + return mem_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id, + scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, 0); return code; } diff --git a/base/gdevmr8n.c b/base/gdevmr8n.c index e90bb151..c4224697 100644 --- a/base/gdevmr8n.c +++ b/base/gdevmr8n.c @@ -23,7 +23,6 @@ #include "gxdcolor.h" #include "gxdevice.h" #include "gxdevmem.h" -#include "gxdevrop.h" #include "gdevmem.h" #include "gdevmrop.h" @@ -47,12 +46,13 @@ /* ---------------- RasterOp with 8-bit gray / 24-bit RGB ---------------- */ int -mem_gray8_rgb24_strip_copy_rop(gx_device * dev, +mem_gray8_rgb24_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t dirty_lop) + int phase_x, int phase_y, + gs_logical_operation_t dirty_lop, uint planar_height) { gx_device_memory *mdev = (gx_device_memory *) dev; gs_logical_operation_t lop = lop_sanitize(dirty_lop); @@ -77,6 +77,8 @@ mem_gray8_rgb24_strip_copy_rop(gx_device * dev, #endif #endif + /* assert(planar_height == 0); */ + /* Check for constant source. */ if (!rop3_uses_S(lop)) { const_source = 0; /* arbitrary */ @@ -136,11 +138,11 @@ bw: if (bw_pixel == 0x00) case rop3_T: break; default: -df: return mem_default_strip_copy_rop(dev, - sdata, sourcex, sraster, id, - scolors, textures, tcolors, - x, y, width, height, - phase_x, phase_y, lop); +df: return mem_default_strip_copy_rop2(dev, + sdata, sourcex, sraster, id, + scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, 0); } /* Put the updated rop back into the lop */ lop = rop; diff --git a/base/gdevmrun.c b/base/gdevmrun.c index fa16ffbc..f143fbd8 100644 --- a/base/gdevmrun.c +++ b/base/gdevmrun.c @@ -165,7 +165,7 @@ static dev_proc_copy_color(run_copy_color); static dev_proc_fill_rectangle(run_fill_rectangle); static dev_proc_copy_alpha(run_copy_alpha); static dev_proc_strip_tile_rectangle(run_strip_tile_rectangle); -static dev_proc_strip_copy_rop(run_strip_copy_rop); +static dev_proc_strip_copy_rop2(run_strip_copy_rop2); static dev_proc_get_bits_rectangle(run_get_bits_rectangle); /* @@ -211,7 +211,7 @@ gdev_run_from_mem(gx_device_run *rdev, gx_device_memory *mdev) REPLACE(fill_rectangle, run_fill_rectangle); REPLACE(copy_alpha, run_copy_alpha); REPLACE(strip_tile_rectangle, run_strip_tile_rectangle); - REPLACE(strip_copy_rop, run_strip_copy_rop); + REPLACE(strip_copy_rop2, run_strip_copy_rop2); REPLACE(get_bits_rectangle, run_get_bits_rectangle); #undef REPLACE return 0; @@ -334,31 +334,33 @@ run_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, color0, color1, px, py); } static int -run_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, - uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int w, int h, int px, int py, - gs_logical_operation_t lop) +run_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, + uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int w, int h, int px, int py, + gs_logical_operation_t lop, + uint planar_height) { gx_device_run *const rdev = (gx_device_run *)dev; run_standardize(rdev, y, h); - return rdev->save_procs.strip_copy_rop((gx_device *)&rdev->md, - sdata, sourcex, sraster, - id, scolors, textures, tcolors, - x, y, w, h, px, py, lop); + return rdev->save_procs.strip_copy_rop2((gx_device *)&rdev->md, + sdata, sourcex, sraster, + id, scolors, textures, tcolors, + x, y, w, h, px, py, lop, + planar_height); } static int run_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect **unread) + gs_get_bits_params_t * params) { gx_device_run *const rdev = (gx_device_run *)dev; run_standardize(rdev, prect->p.y, prect->q.y - prect->p.y); return rdev->save_procs.get_bits_rectangle((gx_device *)&rdev->md, - prect, params, unread); + prect, params); } /* Finish initializing a line. This is a separate procedure only */ diff --git a/base/gdevmrun.h b/base/gdevmrun.h index 15ee2f79..ff6666d3 100644 --- a/base/gdevmrun.h +++ b/base/gdevmrun.h @@ -44,7 +44,7 @@ typedef struct gx_device_run_s { dev_proc_fill_rectangle((*fill_rectangle)); dev_proc_copy_alpha((*copy_alpha)); dev_proc_strip_tile_rectangle((*strip_tile_rectangle)); - dev_proc_strip_copy_rop((*strip_copy_rop)); + dev_proc_strip_copy_rop2((*strip_copy_rop2)); dev_proc_get_bits_rectangle((*get_bits_rectangle)); } save_procs; } gx_device_run; diff --git a/base/gdevmx.c b/base/gdevmx.c index fa2287cc..08b0cbcf 100644 --- a/base/gdevmx.c +++ b/base/gdevmx.c @@ -25,4 +25,4 @@ /* The device descriptor. */ const gx_device_memory mem_x_device = - mem_device("imagex", 256, 0, NULL, NULL, NULL, NULL, NULL, NULL); + mem_device("imagex", 256, 0, NULL); diff --git a/base/gdevnfwd.c b/base/gdevnfwd.c index a6c69e44..f761750b 100644 --- a/base/gdevnfwd.c +++ b/base/gdevnfwd.c @@ -55,7 +55,6 @@ gx_device_set_target(gx_device_forward *fdev, gx_device *target) void gx_device_forward_fill_in_procs(register gx_device_forward * dev) { - gx_device_set_procs((gx_device *) dev); /* NOT open_device */ fill_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); fill_dev_proc(dev, sync_output, gx_forward_sync_output); @@ -64,22 +63,14 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev) fill_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); fill_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); /* NOT fill_rectangle */ - /* NOT tile_rectangle */ /* NOT copy_mono */ /* NOT copy_color */ - /* NOT draw_line (OBSOLETE) */ - fill_dev_proc(dev, get_bits, gx_forward_get_bits); fill_dev_proc(dev, get_params, gx_forward_get_params); fill_dev_proc(dev, put_params, gx_forward_put_params); fill_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); - fill_dev_proc(dev, get_xfont_procs, gx_forward_get_xfont_procs); - fill_dev_proc(dev, get_xfont_device, gx_forward_get_xfont_device); - fill_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color); fill_dev_proc(dev, get_page_device, gx_forward_get_page_device); - /* NOT get_alpha_bits (OBSOLETE) */ + fill_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); /* NOT copy_alpha */ - fill_dev_proc(dev, get_band, gx_forward_get_band); - fill_dev_proc(dev, copy_rop, gx_forward_copy_rop); fill_dev_proc(dev, fill_path, gx_forward_fill_path); fill_dev_proc(dev, stroke_path, gx_forward_stroke_path); fill_dev_proc(dev, fill_mask, gx_forward_fill_mask); @@ -87,16 +78,11 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev) fill_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); fill_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); fill_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); - fill_dev_proc(dev, begin_image, gx_forward_begin_image); - /* NOT image_data (OBSOLETE) */ - /* NOT end_image (OBSOLETE) */ /* NOT strip_tile_rectangle */ - fill_dev_proc(dev, strip_copy_rop, gx_forward_strip_copy_rop); fill_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); fill_dev_proc(dev, begin_typed_image, gx_forward_begin_typed_image); fill_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); - fill_dev_proc(dev, map_color_rgb_alpha, gx_forward_map_color_rgb_alpha); - fill_dev_proc(dev, create_compositor, gx_no_create_compositor); + fill_dev_proc(dev, composite, gx_no_composite); fill_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); fill_dev_proc(dev, text_begin, gx_forward_text_begin); fill_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); @@ -130,7 +116,6 @@ gx_device_forward_color_procs(gx_device_forward * dev) set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); - set_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color); set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); set_dev_proc(dev, encode_color, gx_forward_encode_color); @@ -224,20 +209,6 @@ gx_forward_fill_rectangle(gx_device * dev, int x, int y, int w, int h, } int -gx_forward_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile, - int x, int y, int w, int h, gx_color_index color0, - gx_color_index color1, int px, int py) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - dev_proc_tile_rectangle((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_tile_rectangle) : - dev_proc(tdev, tile_rectangle)); - - return proc(tdev, tile, x, y, w, h, color0, color1, px, py); -} - -int gx_forward_copy_mono(gx_device * dev, const byte * data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, @@ -295,16 +266,6 @@ gx_forward_copy_planes(gx_device * dev, const byte * data, } int -gx_forward_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? gx_default_get_bits(dev, y, data, actual_data) : - dev_proc(tdev, get_bits)(tdev, y, data, actual_data)); -} - -int gx_forward_get_params(gx_device * dev, gs_param_list * plist) { gx_device_forward * const fdev = (gx_device_forward *)dev; @@ -344,39 +305,6 @@ gx_forward_map_cmyk_color(gx_device * dev, const gx_color_value cv[]) dev_proc(tdev, map_cmyk_color)(tdev, cv)); } -const gx_xfont_procs * -gx_forward_get_xfont_procs(gx_device * dev) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? gx_default_get_xfont_procs(dev) : - dev_proc(tdev, get_xfont_procs)(tdev)); -} - -gx_device * -gx_forward_get_xfont_device(gx_device * dev) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? gx_default_get_xfont_device(dev) : - dev_proc(tdev, get_xfont_device)(tdev)); -} - -gx_color_index -gx_forward_map_rgb_alpha_color(gx_device * dev, gx_color_value r, - gx_color_value g, gx_color_value b, - gx_color_value alpha) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? - gx_default_map_rgb_alpha_color(dev, r, g, b, alpha) : - dev_proc(tdev, map_rgb_alpha_color)(tdev, r, g, b, alpha)); -} - gx_device * gx_forward_get_page_device(gx_device * dev) { @@ -391,37 +319,6 @@ gx_forward_get_page_device(gx_device * dev) } int -gx_forward_get_band(gx_device * dev, int y, int *band_start) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? - gx_default_get_band(dev, y, band_start) : - dev_proc(tdev, get_band)(tdev, y, band_start)); -} - -int -gx_forward_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, - gx_bitmap_id id, const gx_color_index * scolors, - const gx_tile_bitmap * texture, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - dev_proc_copy_rop((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_copy_rop) : - dev_proc(tdev, copy_rop)); - - return proc(tdev, sdata, sourcex, sraster, id, scolors, - texture, tcolors, x, y, width, height, - phase_x, phase_y, lop); -} - -int gx_forward_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, @@ -547,24 +444,6 @@ gx_forward_draw_thin_line(gx_device * dev, } int -gx_forward_begin_image(gx_device * dev, - const gs_gstate * pgs, const gs_image_t * pim, - gs_image_format_t format, const gs_int_rect * prect, - const gx_drawing_color * pdcolor, - const gx_clip_path * pcpath, - gs_memory_t * memory, gx_image_enum_common_t ** pinfo) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - dev_proc_begin_image((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_begin_image) : - dev_proc(tdev, begin_image)); - - return proc(tdev, pgs, pim, format, prect, pdcolor, pcpath, - memory, pinfo); -} - -int gx_forward_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int px, int py) @@ -579,26 +458,6 @@ gx_forward_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, } int -gx_forward_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, - uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - dev_proc_strip_copy_rop((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_strip_copy_rop) : - dev_proc(tdev, strip_copy_rop)); - - return proc(tdev, sdata, sourcex, sraster, id, scolors, - textures, tcolors, x, y, width, height, - phase_x, phase_y, lop); -} - -int gx_forward_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, @@ -611,23 +470,13 @@ gx_forward_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device *tdev = fdev->target; - if (planar_height != 0) { - dev_proc_strip_copy_rop2((*proc2)) = + dev_proc_strip_copy_rop2((*proc2)) = (tdev == 0 ? (tdev = dev, gx_default_strip_copy_rop2) : dev_proc(tdev, strip_copy_rop2)); - return proc2(tdev, sdata, sourcex, sraster, id, scolors, - textures, tcolors, x, y, width, height, - phase_x, phase_y, lop, planar_height); - } else { - dev_proc_strip_copy_rop((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_strip_copy_rop) : - dev_proc(tdev, strip_copy_rop)); - - return proc(tdev, sdata, sourcex, sraster, id, scolors, - textures, tcolors, x, y, width, height, - phase_x, phase_y, lop); - } + return proc2(tdev, sdata, sourcex, sraster, id, scolors, + textures, tcolors, x, y, width, height, + phase_x, phase_y, lop, planar_height); } int @@ -680,7 +529,7 @@ gx_forward_begin_typed_image(gx_device * dev, const gs_gstate * pgs, int gx_forward_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device *tdev = fdev->target; @@ -688,18 +537,7 @@ gx_forward_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, (tdev == 0 ? (tdev = dev, gx_default_get_bits_rectangle) : dev_proc(tdev, get_bits_rectangle)); - return proc(tdev, prect, params, unread); -} - -int -gx_forward_map_color_rgb_alpha(gx_device * dev, gx_color_index color, - gx_color_value prgba[4]) -{ - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - - return (tdev == 0 ? gx_default_map_color_rgb_alpha(dev, color, prgba) : - dev_proc(tdev, map_color_rgb_alpha)(tdev, color, prgba)); + return proc(tdev, prect, params); } int @@ -715,8 +553,7 @@ gx_forward_get_hardware_params(gx_device * dev, gs_param_list * plist) int gx_forward_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, - gx_path * path, const gx_device_color * pdcolor, - const gx_clip_path * pcpath, gs_memory_t * memory, + const gx_clip_path * pcpath, gs_text_enum_t ** ppenum) { gx_device_forward * const fdev = (gx_device_forward *)dev; @@ -725,8 +562,7 @@ gx_forward_text_begin(gx_device * dev, gs_gstate * pgs, (tdev == 0 ? (tdev = dev, gx_default_text_begin) : dev_proc(tdev, text_begin)); - return proc(tdev, pgs, text, font, path, pdcolor, pcpath, - memory, ppenum); + return proc(tdev, pgs, text, font, pcpath, ppenum); } /* Forwarding device color mapping procs. */ @@ -735,15 +571,16 @@ gx_forward_text_begin(gx_device * dev, gs_gstate * pgs, * We need to forward the color mapping to the target device. */ static void -fwd_map_gray_cs(gx_device * dev, frac gray, frac out[]) +fwd_map_gray_cs(const gx_device * dev, frac gray, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device * tdev = fdev->target; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; if (tdev) { - scm = get_color_mapping_procs_subclass(tdev); - map_gray_subclass(scm, gray, out); + cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); + cmprocs->map_gray(cmdev, gray, out); } else gray_cs_to_gray_cm(tdev, gray, out); /* if all else fails */ @@ -753,16 +590,17 @@ fwd_map_gray_cs(gx_device * dev, frac gray, frac out[]) * We need to forward the color mapping to the target device. */ static void -fwd_map_rgb_cs(gx_device * dev, const gs_gstate *pgs, +fwd_map_rgb_cs(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device * tdev = fdev->target; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; if (tdev) { - scm = get_color_mapping_procs_subclass(tdev); - map_rgb_subclass(scm, pgs, r, g, b, out); + cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); + cmprocs->map_rgb(cmdev, pgs, r, g, b, out); } else rgb_cs_to_rgb_cm(tdev, pgs, r, g, b, out); /* if all else fails */ @@ -772,15 +610,16 @@ fwd_map_rgb_cs(gx_device * dev, const gs_gstate *pgs, * We need to forward the color mapping to the target device. */ static void -fwd_map_cmyk_cs(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +fwd_map_cmyk_cs(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device * tdev = fdev->target; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; if (tdev) { - scm = get_color_mapping_procs_subclass(tdev); - map_cmyk_subclass(scm, c, m, y, k, out); + cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); + cmprocs->map_cmyk(cmdev, c, m, y, k, out); } else cmyk_cs_to_cmyk_cm(tdev, c, m, y, k, out); /* if all else fails */ @@ -797,13 +636,18 @@ static const gx_cm_color_map_procs FwdDevice_cm_map_procs = { * device pointer). */ const gx_cm_color_map_procs * -gx_forward_get_color_mapping_procs(const gx_device * dev) +gx_forward_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev) { const gx_device_forward * fdev = (const gx_device_forward *)dev; gx_device * tdev = fdev->target; - return (tdev == 0 ? gx_default_DevGray_get_color_mapping_procs(dev) - : &FwdDevice_cm_map_procs); + if (tdev) + return dev_proc(tdev, get_color_mapping_procs)(tdev, map_dev); + + /* Testing in the cluster seems to indicate that we never get here, + * but we've written the code now... */ + *map_dev = dev; + return &FwdDevice_cm_map_procs; } int @@ -999,7 +843,7 @@ gx_forward_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) } int -gx_forward_create_compositor(gx_device * dev, gx_device ** pcdev, +gx_forward_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) @@ -1009,9 +853,9 @@ gx_forward_create_compositor(gx_device * dev, gx_device ** pcdev, int code; if (tdev == 0) - return gx_no_create_compositor(dev, pcdev, pcte, pgs, memory, cdev); + return gx_no_composite(dev, pcdev, pcte, pgs, memory, cdev); /* else do the compositor action */ - code = dev_proc(tdev, create_compositor)(tdev, pcdev, pcte, pgs, memory, cdev); + code = dev_proc(tdev, composite)(tdev, pcdev, pcte, pgs, memory, cdev); /* the compositor may have changed color_info. Pick up the new value */ dev->color_info = tdev->color_info; if (code == 1) { @@ -1024,14 +868,14 @@ gx_forward_create_compositor(gx_device * dev, gx_device ** pcdev, } int -gx_forward_get_profile(gx_device *dev, cmm_dev_profile_t **profile) +gx_forward_get_profile(const gx_device *dev, cmm_dev_profile_t **profile) { gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device *tdev = fdev->target; - dev_proc_get_profile((*proc)) = - (tdev == 0 ? (tdev = dev, gx_default_get_profile) : - dev_proc(tdev, get_profile)); - return proc(tdev, profile); + const gx_device *tdev = fdev->target; + + if (tdev == NULL) + return gx_default_get_profile(dev, profile); + return dev_proc(tdev, get_profile)(tdev, profile); } void @@ -1080,7 +924,6 @@ static dev_proc_copy_mono(null_copy_mono); static dev_proc_copy_color(null_copy_color); static dev_proc_put_params(null_put_params); static dev_proc_copy_alpha(null_copy_alpha); -static dev_proc_copy_rop(null_copy_rop); static dev_proc_fill_path(null_fill_path); static dev_proc_stroke_path(null_stroke_path); static dev_proc_fill_trapezoid(null_fill_trapezoid); @@ -1091,105 +934,69 @@ static dev_proc_decode_color(null_decode_color); /* We would like to have null implementations of begin/data/end image, */ /* but we can't do this, because image_data must keep track of the */ /* Y position so it can return 1 when done. */ -static dev_proc_strip_copy_rop(null_strip_copy_rop); static dev_proc_strip_copy_rop2(null_strip_copy_rop2); static dev_proc_strip_tile_rect_devn(null_strip_tile_rect_devn); static dev_proc_fill_rectangle_hl_color(null_fill_rectangle_hl_color); static dev_proc_dev_spec_op(null_spec_op); -#define null_procs(get_initial_matrix, get_page_device) {\ - gx_default_open_device,\ - get_initial_matrix, /* differs */\ - gx_default_sync_output,\ - gx_default_output_page,\ - gx_default_close_device,\ - gx_forward_map_rgb_color,\ - gx_forward_map_color_rgb,\ - null_fill_rectangle,\ - gx_default_tile_rectangle,\ - null_copy_mono,\ - null_copy_color,\ - gx_default_draw_line,\ - gx_default_get_bits,\ - gx_forward_get_params,\ - null_put_params,\ - gx_forward_map_cmyk_color,\ - gx_forward_get_xfont_procs,\ - gx_forward_get_xfont_device,\ - gx_forward_map_rgb_alpha_color,\ - get_page_device, /* differs */\ - gx_default_get_alpha_bits,\ - null_copy_alpha,\ - gx_forward_get_band,\ - null_copy_rop,\ - null_fill_path,\ - null_stroke_path,\ - gx_default_fill_mask,\ - null_fill_trapezoid,\ - null_fill_parallelogram,\ - null_fill_triangle,\ - null_draw_thin_line,\ - gx_default_begin_image,\ - gx_default_image_data,\ - gx_default_end_image,\ - gx_default_strip_tile_rectangle,\ - null_strip_copy_rop,\ - gx_default_get_clipping_box,\ - gx_default_begin_typed_image,\ - gx_default_get_bits_rectangle,\ - gx_forward_map_color_rgb_alpha,\ - gx_non_imaging_create_compositor,\ - gx_forward_get_hardware_params,\ - gx_default_text_begin,\ - gx_default_finish_copydevice,\ - NULL, /* begin_transparency_group */\ - NULL, /* end_transparency_group */\ - NULL, /* begin_transparency_mask */\ - NULL, /* end_transparency_mask */\ - NULL, /* discard_transparency_layer */\ - gx_default_DevGray_get_color_mapping_procs, /* get_color_mapping_procs */\ - gx_default_DevGray_get_color_comp_index,/* get_color_comp_index */\ - gx_default_gray_fast_encode, /* encode_color */\ - null_decode_color, /* decode_color */\ - NULL, /* pattern_manage */\ - null_fill_rectangle_hl_color,\ - gx_default_include_color_space,\ - NULL, /* fill_line_sl */\ - NULL, /* fill_line_tr */\ - NULL, /* fill_line_tri */\ - NULL, /* up_spot_eq_col */\ - gx_default_ret_devn_params, /* ret_devn_params */\ - NULL, /* fillpage */\ - NULL, /* push_transparency_state */\ - NULL, /* pop_transparency_state */\ - NULL, /* put_image */\ - null_spec_op, /* dev_spec_op */\ - NULL, /* copy_planes */\ - NULL, /* get_profile */\ - NULL, /* set_graphics_type_tag */\ - null_strip_copy_rop2,\ - null_strip_tile_rect_devn\ +static void +null_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, get_initial_matrix, gx_forward_upright_get_initial_matrix); + set_dev_proc(dev, get_page_device, gx_default_get_page_device); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, null_fill_rectangle); + set_dev_proc(dev, copy_mono, null_copy_mono); + set_dev_proc(dev, copy_color, null_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, null_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, copy_alpha, null_copy_alpha); + set_dev_proc(dev, fill_path, null_fill_path); + set_dev_proc(dev, stroke_path, null_stroke_path); + set_dev_proc(dev, fill_trapezoid, null_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, null_fill_parallelogram); + set_dev_proc(dev, fill_triangle, null_fill_triangle); + set_dev_proc(dev, draw_thin_line, null_draw_thin_line); + set_dev_proc(dev, composite, gx_non_imaging_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_default_DevGray_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_default_DevGray_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_default_gray_fast_encode); + set_dev_proc(dev, decode_color, null_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, null_fill_rectangle_hl_color); + set_dev_proc(dev, dev_spec_op, null_spec_op); + set_dev_proc(dev, strip_copy_rop2, null_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, null_strip_tile_rect_devn); +} + +static void +nullpage_initialize_device_procs(gx_device *dev) +{ + null_initialize_device_procs(dev); + + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); } #define NULLD_X_RES 72 #define NULLD_Y_RES 72 const gx_device_null gs_null_device = { - std_device_std_body_type_open(gx_device_null, 0, "null", &st_device_null, - 0, 0, NULLD_X_RES, NULLD_Y_RES), - null_procs(gx_forward_upright_get_initial_matrix, /* upright matrix */ - gx_default_get_page_device /* not a page device */ ), - 0 /* target */ + std_device_std_body_type_open(gx_device_null, + null_initialize_device_procs, + "null", &st_device_null, + 0, 0, NULLD_X_RES, NULLD_Y_RES) }; const gx_device_null gs_nullpage_device = { -std_device_std_body_type_open(gx_device_null, 0, "nullpage", &st_device_null, +std_device_std_body_type_open(gx_device_null, + nullpage_initialize_device_procs, + "nullpage", &st_device_null, (int)((float)(DEFAULT_WIDTH_10THS * NULLD_X_RES) / 10), (int)((float)(DEFAULT_HEIGHT_10THS * NULLD_Y_RES) / 10), - NULLD_X_RES, NULLD_Y_RES), - null_procs( gx_forward_get_initial_matrix, /* default matrix */ - gx_page_device_get_page_device /* a page device */ ), - 0 /* target */ + NULLD_X_RES, NULLD_Y_RES) }; static void @@ -1261,16 +1068,6 @@ null_copy_alpha(gx_device * dev, const byte * data, int data_x, int raster, return 0; } static int -null_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_tile_bitmap * texture, const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - return 0; -} -static int null_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) @@ -1319,17 +1116,6 @@ null_draw_thin_line(gx_device * dev, return 0; } static int -null_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, - uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, - const gx_color_index * tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - return 0; -} -static int null_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, @@ -1372,36 +1158,67 @@ null_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) /* Defeat the ICC profile components check, which we want to do since we also short-circuit ICC device parameters - see null_put_params. */ - if (dev_spec_op == gxdso_skip_icc_component_validation) { + if (dev_spec_op == gxdso_skip_icc_component_validation) + return 1; + if (dev_spec_op == gxdso_is_null_device) return 1; - } return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); } -bool -fwd_uses_fwd_cmap_procs(gx_device * dev) -{ - const gx_cm_color_map_procs *pprocs; - - pprocs = dev_proc(dev, get_color_mapping_procs)(dev); - if (pprocs == &FwdDevice_cm_map_procs) { - return true; - } - return false; -} - -const gx_cm_color_map_procs* -fwd_get_target_cmap_procs(gx_device * dev) +void gx_forward_device_initialize_procs(gx_device *dev) { - const gx_cm_color_map_procs *pprocs; - gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device * const tdev = fdev->target; - - pprocs = dev_proc(tdev, get_color_mapping_procs(tdev)); - while (pprocs == &FwdDevice_cm_map_procs) { - pprocs = fwd_get_target_cmap_procs(tdev); - } - return pprocs; + fill_dev_proc(dev, close_device, gx_forward_close_device); + fill_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + fill_dev_proc(dev, sync_output, gx_forward_sync_output); + fill_dev_proc(dev, output_page, gx_forward_output_page); + fill_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + fill_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + fill_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle); + fill_dev_proc(dev, copy_mono, gx_forward_copy_mono); + fill_dev_proc(dev, copy_color, gx_forward_copy_color); + fill_dev_proc(dev, get_params, gx_forward_get_params); + fill_dev_proc(dev, put_params, gx_forward_put_params); + fill_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + fill_dev_proc(dev, get_page_device, gx_forward_get_page_device); + fill_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + fill_dev_proc(dev, copy_alpha, gx_forward_copy_alpha); + fill_dev_proc(dev, fill_path, gx_forward_fill_path); + fill_dev_proc(dev, stroke_path, gx_forward_stroke_path); + fill_dev_proc(dev, fill_mask, gx_forward_fill_mask); + fill_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid); + fill_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); + fill_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); + fill_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); + fill_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle); + fill_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + fill_dev_proc(dev, begin_typed_image, gx_forward_begin_typed_image); + fill_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); + /* There is no forward_composite (see Drivers.htm). */ + fill_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + fill_dev_proc(dev, text_begin, gx_forward_text_begin); + fill_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + fill_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + fill_dev_proc(dev, encode_color, gx_forward_encode_color); + fill_dev_proc(dev, decode_color, gx_forward_decode_color); + fill_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); + fill_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); + fill_dev_proc(dev, include_color_space, gx_forward_include_color_space); + fill_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); + fill_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); + fill_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); + fill_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + fill_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + fill_dev_proc(dev, fillpage, gx_forward_fillpage); + fill_dev_proc(dev, put_image, gx_forward_put_image); + fill_dev_proc(dev, copy_planes, gx_forward_copy_planes); + fill_dev_proc(dev, composite, gx_forward_composite); + fill_dev_proc(dev, get_profile, gx_forward_get_profile); + fill_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + fill_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2); + fill_dev_proc(dev, strip_tile_rect_devn, gx_forward_strip_tile_rect_devn); + fill_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color); + fill_dev_proc(dev, transform_pixel_region, gx_forward_transform_pixel_region); + fill_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); } #ifdef DEBUG diff --git a/base/gdevnup.c b/base/gdevnup.c index e1d79d1c..b9f4f356 100644 --- a/base/gdevnup.c +++ b/base/gdevnup.c @@ -86,92 +86,30 @@ static dev_proc_dev_spec_op(nup_dev_spec_op); #define MAX_COORD (max_int_in_fixed - 1000) #define MAX_RESOLUTION 4000 +static void +nup_initialize_device_procs(gx_device *dev) +{ + default_subclass_initialize_device_procs(dev); + + set_dev_proc(dev, get_initial_matrix, nup_get_initial_matrix); + set_dev_proc(dev, output_page, nup_output_page); + set_dev_proc(dev, close_device, nup_close_device); + set_dev_proc(dev, put_params, nup_put_params); /* to catch PageSize changes */ + set_dev_proc(dev, fillpage, nup_fillpage); + set_dev_proc(dev, dev_spec_op, nup_dev_spec_op); +} + const gx_device_nup gs_nup_device = { /* * Define the device as 8-bit gray scale to avoid computing halftones. */ - std_device_dci_type_body(gx_device_nup, 0, "N-up", &st_nup_device, + std_device_dci_type_body_sc(gx_device_nup, nup_initialize_device_procs, + "N-up", &st_nup_device, MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, - 1, 8, 255, 0, 256, 1), - {default_subclass_open_device, - nup_get_initial_matrix, - default_subclass_sync_output, /* sync_output */ - nup_output_page, - nup_close_device, - default_subclass_map_rgb_color, - default_subclass_map_color_rgb, - default_subclass_fill_rectangle, - default_subclass_tile_rectangle, /* tile_rectangle */ - default_subclass_copy_mono, - default_subclass_copy_color, - default_subclass_draw_line, /* draw_line */ - default_subclass_get_bits, /* get_bits */ - default_subclass_get_params, - nup_put_params, /* to catch PageSize changes */ - default_subclass_map_cmyk_color, - default_subclass_get_xfont_procs, /* get_xfont_procs */ - default_subclass_get_xfont_device, /* get_xfont_device */ - default_subclass_map_rgb_alpha_color, - default_subclass_get_page_device, - default_subclass_get_alpha_bits, /* get_alpha_bits */ - default_subclass_copy_alpha, - default_subclass_get_band, /* get_band */ - default_subclass_copy_rop, /* copy_rop */ - default_subclass_fill_path, - default_subclass_stroke_path, - default_subclass_fill_mask, - default_subclass_fill_trapezoid, - default_subclass_fill_parallelogram, - default_subclass_fill_triangle, - default_subclass_draw_thin_line, - default_subclass_begin_image, - default_subclass_image_data, /* image_data */ - default_subclass_end_image, /* end_image */ - default_subclass_strip_tile_rectangle, - default_subclass_strip_copy_rop, - default_subclass_get_clipping_box, /* get_clipping_box */ - default_subclass_begin_typed_image, - default_subclass_get_bits_rectangle, /* get_bits_rectangle */ - default_subclass_map_color_rgb_alpha, - default_subclass_create_compositor, - default_subclass_get_hardware_params, /* get_hardware_params */ - default_subclass_text_begin, - default_subclass_finish_copydevice, /* finish_copydevice */ - default_subclass_begin_transparency_group, /* begin_transparency_group */ - default_subclass_end_transparency_group, /* end_transparency_group */ - default_subclass_begin_transparency_mask, /* begin_transparency_mask */ - default_subclass_end_transparency_mask, /* end_transparency_mask */ - default_subclass_discard_transparency_layer, /* discard_transparency_layer */ - default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ - default_subclass_get_color_comp_index, /* get_color_comp_index */ - default_subclass_encode_color, /* encode_color */ - default_subclass_decode_color, /* decode_color */ - default_subclass_pattern_manage, /* pattern_manage */ - default_subclass_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - default_subclass_include_color_space, /* include_color_space */ - default_subclass_fill_linear_color_scanline, /* fill_linear_color_scanline */ - default_subclass_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ - default_subclass_fill_linear_color_triangle, /* fill_linear_color_triangle */ - default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ - default_subclass_ret_devn_params, /* ret_devn_params */ - nup_fillpage, /* fillpage */ - default_subclass_push_transparency_state, /* push_transparency_state */ - default_subclass_pop_transparency_state, /* pop_transparency_state */ - default_subclass_put_image, /* put_image */ - nup_dev_spec_op, /* for GetParam of PdfmarkCapable */ - default_subclass_copy_planes, /* copy_planes */ - default_subclass_get_profile, /* get_profile */ - default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ - default_subclass_strip_copy_rop2, - default_subclass_strip_tile_rect_devn, - default_subclass_copy_alpha_hl_color, - default_subclass_process_page, - default_subclass_transform_pixel_region, - default_subclass_fill_stroke_path, - } + 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) }; #undef MAX_COORD @@ -291,7 +229,7 @@ nup_set_children_MediaSize(gx_device *dev, float PageW, float PageH) } static int -nup_flush_nest_to_output(gx_device *dev, Nup_device_subclass_data *pNup_data, bool flush) +nup_flush_nest_to_output(gx_device *dev, Nup_device_subclass_data *pNup_data) { int code = 0; @@ -315,7 +253,7 @@ nup_close_device(gx_device *dev) return code; if (pNup_data->PageCount > 0) - acode = nup_flush_nest_to_output(dev, pNup_data, true); + acode = nup_flush_nest_to_output(dev, pNup_data); /* Reset the Nup control data */ /* NB: the data will be freed from non_gc_memory by the finalize function */ @@ -327,34 +265,6 @@ nup_close_device(gx_device *dev) return min(code, acode); } - /* - * Template: - * BEGIN_ARRAY_PARAM(param_read_xxx_array, "pname", pxxa, size, pxxe) { - * ... check value if desired ... - * if (success) - * break; - * ... set ecode ... - * } END_ARRAY_PARAM(pxxa, pxxe); - */ - -#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\ - BEGIN\ - switch (code = pread(plist, (param_name = pname), &(pa))) {\ - case 0:\ - if ((pa).size != psize) {\ - ecode = gs_note_error(gs_error_rangecheck);\ - (pa).data = 0; /* mark as not filled */\ - } else -#define END_ARRAY_PARAM(pa, e)\ - goto e;\ - default:\ - ecode = code;\ -e: param_signal_error(plist, param_name, ecode);\ - case 1:\ - (pa).data = 0; /* mark as not filled */\ - }\ - END - /* Read .MediaSize or, if supported as a synonym, PageSize. */ static int param_MediaSize(gs_param_list * plist, gs_param_name pname, @@ -364,26 +274,171 @@ param_MediaSize(gs_param_list * plist, gs_param_name pname, int ecode = 0; int code; - BEGIN_ARRAY_PARAM(param_read_float_array, pname, *pa, 2, mse) { - float width_new = pa->data[0] * res[0] / 72; - float height_new = pa->data[1] * res[1] / 72; - - if (width_new < 0 || height_new < 0) - ecode = gs_note_error(gs_error_rangecheck); + switch (code = param_read_float_array(plist, (param_name = pname), pa)) { + case 0: + if (pa->size != 2) { + ecode = gs_note_error(gs_error_rangecheck); + pa->data = 0; /* mark as not filled */ + } else { + float width_new = pa->data[0] * res[0] / 72; + float height_new = pa->data[1] * res[1] / 72; + + if (width_new < 0 || height_new < 0) + ecode = gs_note_error(gs_error_rangecheck); #define max_coord (max_fixed / fixed_1) #if max_coord < max_int - else if (width_new > (long)max_coord || height_new > (long)max_coord) - ecode = gs_note_error(gs_error_limitcheck); + else if (width_new > (long)max_coord || height_new > (long)max_coord) + ecode = gs_note_error(gs_error_limitcheck); #endif #undef max_coord - else - break; - } END_ARRAY_PARAM(*pa, mse); + else + break; + } + goto err; + default: + ecode = code; +err: param_signal_error(plist, param_name, ecode); + /* fall through */ + case 1: + pa->data = 0; /* mark as not filled */ + } return ecode; } +/* Horrible hacked version of param_list_copy from gsparamx.c. + * Copy one parameter list to another, recursively if necessary, + * rewriting PageUsesTransparency to be true if it occurs. */ +static int +copy_and_modify_sub(gs_param_list *plto, gs_param_list *plfrom, int *present) +{ + gs_param_enumerator_t key_enum; + gs_param_key_t key; + bool copy_persists; + int code; + + if (present) + *present = 0; + if (plfrom == NULL) + return 0; + + /* If plfrom and plto use different allocators, we must copy + * aggregate values even if they are "persistent". */ + copy_persists = plto->memory == plfrom->memory; + + param_init_enumerator(&key_enum); + while ((code = param_get_next_key(plfrom, &key_enum, &key)) == 0) { + char string_key[256]; /* big enough for any reasonable key */ + gs_param_typed_value value; + gs_param_collection_type_t coll_type; + gs_param_typed_value copy; + + if (key.size > sizeof(string_key) - 1) { + code = gs_note_error(gs_error_rangecheck); + break; + } + memcpy(string_key, key.data, key.size); + string_key[key.size] = 0; + if ((code = param_read_typed(plfrom, string_key, &value)) != 0) { + code = (code > 0 ? gs_note_error(gs_error_unknownerror) : code); + break; + } + gs_param_list_set_persistent_keys(plto, key.persistent); + switch (value.type) { + case gs_param_type_dict: + coll_type = gs_param_collection_dict_any; + goto cc; + case gs_param_type_dict_int_keys: + coll_type = gs_param_collection_dict_int_keys; + goto cc; + case gs_param_type_array: + coll_type = gs_param_collection_array; + cc: + copy.value.d.size = value.value.d.size; + if (copy.value.d.size == 0) + break; + if ((code = param_begin_write_collection(plto, string_key, + ©.value.d, + coll_type)) < 0 || + (code = copy_and_modify_sub(copy.value.d.list, + value.value.d.list, + NULL)) < 0 || + (code = param_end_write_collection(plto, string_key, + ©.value.d)) < 0) + break; + code = param_end_read_collection(plfrom, string_key, + &value.value.d); + break; + case gs_param_type_bool: + if (strcmp(string_key, "PageUsesTransparency") == 0 && present != NULL) + { + value.value.b = 1; + *present = 1; + } + goto ca; + case gs_param_type_string: + value.value.s.persistent &= copy_persists; goto ca; + case gs_param_type_name: + value.value.n.persistent &= copy_persists; goto ca; + case gs_param_type_int_array: + value.value.ia.persistent &= copy_persists; goto ca; + case gs_param_type_float_array: + value.value.fa.persistent &= copy_persists; goto ca; + case gs_param_type_string_array: + value.value.sa.persistent &= copy_persists; + /* fall through */ + ca: + default: + code = param_write_typed(plto, string_key, &value); + } + if (code < 0) + break; + } + return code; +} + static int -nup_put_params(gx_device *dev, gs_param_list * plist) +param_list_copy_and_modify(gs_param_list *plto, gs_param_list *plfrom) +{ + int found_put; + int code = copy_and_modify_sub(plto, plfrom, &found_put); + + if (code >= 0 && !found_put) { + gs_param_typed_value value; + value.type = gs_param_type_bool; + value.value.b = 1; + code = param_write_typed(plto, "PageUsesTransparency", &value); + } + + return code; +} + +static int +promote_errors(gs_param_list * plist_orig, gs_param_list * plist) +{ + gs_param_enumerator_t key_enum; + gs_param_key_t key; + int code; + int error; + + param_init_enumerator(&key_enum); + while ((code = param_get_next_key(plist_orig, &key_enum, &key)) == 0) { + char string_key[256]; /* big enough for any reasonable key */ + + if (key.size > sizeof(string_key) - 1) { + code = gs_note_error(gs_error_rangecheck); + break; + } + memcpy(string_key, key.data, key.size); + string_key[key.size] = 0; + error = param_read_signalled_error(plist, string_key); + param_signal_error(plist_orig, string_key, error); + } + + return code; +} + +static int +nup_put_params(gx_device *dev, gs_param_list * plist_orig) { int code, ecode = 0; gs_param_float_array msa; @@ -392,11 +447,29 @@ nup_put_params(gx_device *dev, gs_param_list * plist) gs_param_string nuplist; Nup_device_subclass_data* pNup_data = dev->subclass_data; gx_device *next_dev; + gs_c_param_list *plist_c; + gs_param_list *plist; #if 0000 -gs_param_list_dump(plist); +gs_param_list_dump(plist_orig); #endif + plist_c = gs_c_param_list_alloc(dev->memory->non_gc_memory, "nup_put_params"); + plist = (gs_param_list *)plist_c; + if (plist == NULL) + return_error(gs_error_VMerror); + gs_c_param_list_write(plist_c, dev->memory->non_gc_memory); + gs_param_list_set_persistent_keys((gs_param_list *)plist_c, false); + + /* Bulk copy the whole list. Can't enumerate and copy without it + * becoming an absolute nightmare due to the stupid way we handle + * 'collection' objects on writing. */ + code = param_list_copy_and_modify((gs_param_list *)plist_c, plist_orig); + if (code < 0) + goto fail; + + gs_c_param_list_read(plist_c); + code = param_read_string(plist, "NupControl", &nuplist); if (code < 0) ecode = code; @@ -406,7 +479,7 @@ gs_param_list_dump(plist); (strncmp(dev->NupControl->nupcontrol_str, (const char *)nuplist.data, nuplist.size) != 0))) { /* If we have accumulated a nest when the NupControl changes, flush the nest */ if (pNup_data->PagesPerNest > 1 && pNup_data->PageCount > 0) - code = nup_flush_nest_to_output(dev, pNup_data, true); + code = nup_flush_nest_to_output(dev, pNup_data); if (code < 0) ecode = code; /* There was a NupControl, but this one is different -- no longer use the old one */ @@ -416,15 +489,18 @@ gs_param_list_dump(plist); if (dev->NupControl == NULL && nuplist.size > 0) { dev->NupControl = (gdev_nupcontrol *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_nupcontrol), "structure to hold nupcontrol_str"); - if (dev->NupControl == NULL) - return gs_note_error(gs_error_VMerror); + if (dev->NupControl == NULL) { + code = gs_note_error(gs_error_VMerror); + goto fail; + } dev->NupControl->nupcontrol_str = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, nuplist.size + 1, "nupcontrol string"); if (dev->NupControl->nupcontrol_str == NULL){ gs_free(dev->memory->non_gc_memory, dev->NupControl, 1, sizeof(gdev_nupcontrol), "free structure to hold nupcontrol string"); dev->NupControl = 0; - return gs_note_error(gs_error_VMerror); + code = gs_note_error(gs_error_VMerror); + goto fail; } memset(dev->NupControl->nupcontrol_str, 0x00, nuplist.size + 1); memcpy(dev->NupControl->nupcontrol_str, nuplist.data, nuplist.size); @@ -446,17 +522,21 @@ gs_param_list_dump(plist); rc_increment(next_dev->NupControl); next_dev = next_dev->parent; } - if (ecode < 0) - return ecode; + if (ecode < 0) { + code = ecode; + goto fail; + } } code = ParseNupControl(dev, pNup_data); /* update the nesting params */ if (code < 0) - return code; + goto fail; /* If nesting is now off, just pass params on to children devices */ - if (pNup_data->PagesPerNest == 1) - return default_subclass_put_params(dev, plist); + if (pNup_data->PagesPerNest == 1) { + code = default_subclass_put_params(dev, plist); + goto fail; /* Not actually failing! */ + } /* .MediaSize takes precedence over PageSize, so we read PageSize first. */ code = param_MediaSize(plist, "PageSize", res, &msa); @@ -468,34 +548,54 @@ gs_param_list_dump(plist); code = param_MediaSize(plist, ".MediaSize", res, &msa); if (code < 0) ecode = code; - else if (msa.data == 0) + else if (msa.data == NULL) msa.data = data; - if (ecode < 0) - return ecode; + if (ecode < 0) { + code = ecode; + goto fail; + } /* If there was PageSize or .MediaSize, update the NestedPage size */ - if (msa.data != 0) { + if (msa.data != NULL) { Nup_device_subclass_data *pNup_data = dev->subclass_data; + /* Calculate the page sizes as ints to allow for tiny changes + * of width that don't actually make a difference. */ + int w1 = (int)(pNup_data->NestedPageW * dev->HWResolution[0] / 72.0f + 0.5f); + int w2 = (int)(msa.data[0] * dev->HWResolution[0] / 72.0f + 0.5f); + int h1 = (int)(pNup_data->NestedPageH * dev->HWResolution[1] / 72.0f + 0.5f); + int h2 = (int)(msa.data[1] * dev->HWResolution[1] / 72.0f + 0.5f); /* FIXME: Handle changing size (if previous value was non-zero) */ - if (msa.data[0] != pNup_data->NestedPageW || msa.data[1] != pNup_data->NestedPageH) { + if (w1 != w2 || h1 != h2) { /* If needed, flush previous nest before changing */ if (pNup_data->PageCount > 0 && pNup_data->PagesPerNest > 1) { - code = nup_flush_nest_to_output(dev, pNup_data, true); + code = nup_flush_nest_to_output(dev, pNup_data); if (code < 0) - return code; + goto fail; } pNup_data->NestedPageW = msa.data[0]; pNup_data->NestedPageH = msa.data[1]; /* And update the Nup parameters based on the updated PageSize */ code = ParseNupControl(dev, pNup_data); if (code < 0) - return code; + goto fail; } } /* now that we've intercepted PageSize and/or MediaSize, pass the rest along */ code = default_subclass_put_params(dev, plist); + + /* Now promote errors from the copied list to the original list. */ + { + int ecode = promote_errors(plist_orig, plist); + if (code == 0) + code = ecode; + } + +fail: + gs_c_param_list_release(plist_c); + gs_free_object(dev->memory->non_gc_memory, plist_c, "nup_put_params"); + return code; } @@ -519,11 +619,19 @@ nup_output_page(gx_device *dev, int num_copies, int flush) } /* FIXME: Handle num_copies > 1 */ + + /* pNup_data holds the number of 'sub pages' we have produced, + * so update that. dev->PageCount holds the number of 'actual' + * pages we've output, so only increment that if we really + * do an output. */ pNup_data->PageCount++; - dev->PageCount++; dev->ShowpageCount = dev->child->ShowpageCount; - if (pNup_data->PageCount >= pNup_data->PagesPerNest) - code = nup_flush_nest_to_output(dev, pNup_data, flush); + if (pNup_data->PageCount >= pNup_data->PagesPerNest) { + code = nup_flush_nest_to_output(dev, pNup_data); + /* Increment this afterwards, in case the child accesses + * the value to fill in a %d in the filename. */ + dev->PageCount++; + } return code; } @@ -591,3 +699,36 @@ nup_dev_spec_op(gx_device *dev, int dev_spec_op, void *data, int size) } return default_subclass_dev_spec_op(dev, dev_spec_op, data, size); } + +int gx_device_nup_device_install(gx_device *dev) +{ + gs_param_typed_value value; + gs_c_param_list *plist_c; + int code; + + code = gx_device_subclass(dev, (gx_device *)&gs_nup_device, sizeof(Nup_device_subclass_data)); + if (code < 0) + return code; + + /* Ensure that PageUsesTransparency is set. */ + plist_c = gs_c_param_list_alloc(dev->memory->non_gc_memory, "nup_open_device"); + if (plist_c == NULL) + return_error(gs_error_VMerror); + gs_c_param_list_write(plist_c, dev->memory->non_gc_memory); + gs_param_list_set_persistent_keys((gs_param_list *)plist_c, false); + + value.type = gs_param_type_bool; + value.value.b = 1; + code = param_write_typed((gs_param_list *)plist_c, "PageUsesTransparency", &value); + if (code >= 0) { + gs_c_param_list_read(plist_c); + + code = default_subclass_put_params(dev, (gs_param_list *)plist_c); + if (code >= 0) + code = default_subclass_open_device(dev->child); + } + gs_c_param_list_release(plist_c); + gs_free_object(dev->memory->non_gc_memory, plist_c, "nup_open_device"); + + return code; +} diff --git a/base/gdevnup.h b/base/gdevnup.h index a8b34c4b..51cf24eb 100644 --- a/base/gdevnup.h +++ b/base/gdevnup.h @@ -23,8 +23,7 @@ typedef struct gx_device_s gx_device_nup; -/* Initialize device. */ -void gx_device_nup_device_init(gx_device_nup * dev); +int gx_device_nup_device_install(gx_device *dev); typedef struct { subclass_common; diff --git a/base/gdevoflt.c b/base/gdevoflt.c index e7fc3809..98f16f49 100644 --- a/base/gdevoflt.c +++ b/base/gdevoflt.c @@ -44,8 +44,6 @@ private_st_obj_filter_text_enum(); /* Device procedures, we need to implement all of them */ static dev_proc_fill_rectangle(obj_filter_fill_rectangle); -static dev_proc_tile_rectangle(obj_filter_tile_rectangle); -static dev_proc_draw_line(obj_filter_draw_line); static dev_proc_fill_path(obj_filter_fill_path); static dev_proc_stroke_path(obj_filter_stroke_path); static dev_proc_fill_mask(obj_filter_fill_mask); @@ -53,11 +51,7 @@ static dev_proc_fill_trapezoid(obj_filter_fill_trapezoid); static dev_proc_fill_parallelogram(obj_filter_fill_parallelogram); static dev_proc_fill_triangle(obj_filter_fill_triangle); static dev_proc_draw_thin_line(obj_filter_draw_thin_line); -static dev_proc_begin_image(obj_filter_begin_image); -static dev_proc_image_data(obj_filter_image_data); -static dev_proc_end_image(obj_filter_end_image); static dev_proc_strip_tile_rectangle(obj_filter_strip_tile_rectangle); -static dev_proc_strip_copy_rop(obj_filter_strip_copy_rop); static dev_proc_begin_typed_image(obj_filter_begin_typed_image); static dev_proc_text_begin(obj_filter_text_begin); static dev_proc_fill_rectangle_hl_color(obj_filter_fill_rectangle_hl_color); @@ -92,92 +86,44 @@ RELOC_PTRS_END public_st_obj_filter_device(); +static void +obj_filter_initialize_device_procs(gx_device *dev) +{ + default_subclass_initialize_device_procs(dev); + + set_dev_proc(dev, fill_rectangle, obj_filter_fill_rectangle); + set_dev_proc(dev, fill_path, obj_filter_fill_path); + set_dev_proc(dev, stroke_path, obj_filter_stroke_path); + set_dev_proc(dev, fill_mask, obj_filter_fill_mask); + set_dev_proc(dev, fill_trapezoid, obj_filter_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, obj_filter_fill_parallelogram); + set_dev_proc(dev, fill_triangle, obj_filter_fill_triangle); + set_dev_proc(dev, draw_thin_line, obj_filter_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, obj_filter_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, obj_filter_begin_typed_image); + set_dev_proc(dev, text_begin, obj_filter_text_begin); + set_dev_proc(dev, fill_rectangle_hl_color, obj_filter_fill_rectangle_hl_color); + set_dev_proc(dev, fill_linear_color_scanline, obj_filter_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, obj_filter_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, obj_filter_fill_linear_color_triangle); + set_dev_proc(dev, put_image, obj_filter_put_image); + set_dev_proc(dev, strip_copy_rop2, obj_filter_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, obj_filter_strip_tile_rect_devn); + set_dev_proc(dev, fill_stroke_path, obj_filter_fill_stroke_path); +} + const gx_device_obj_filter gs_obj_filter_device = { /* * Define the device as 8-bit gray scale to avoid computing halftones. */ - std_device_dci_type_body(gx_device_obj_filter, 0, "object_filter", &st_obj_filter_device, + std_device_dci_type_body_sc(gx_device_obj_filter, + obj_filter_initialize_device_procs, + "object_filter", &st_obj_filter_device, MAX_COORD, MAX_COORD, MAX_RESOLUTION, MAX_RESOLUTION, - 1, 8, 255, 0, 256, 1), - {default_subclass_open_device, - default_subclass_get_initial_matrix, - default_subclass_sync_output, /* sync_output */ - default_subclass_output_page, - default_subclass_close_device, - default_subclass_map_rgb_color, - default_subclass_map_color_rgb, - obj_filter_fill_rectangle, - obj_filter_tile_rectangle, /* tile_rectangle */ - default_subclass_copy_mono, - default_subclass_copy_color, - obj_filter_draw_line, /* draw_line */ - default_subclass_get_bits, /* get_bits */ - default_subclass_get_params, - default_subclass_put_params, - default_subclass_map_cmyk_color, - default_subclass_get_xfont_procs, /* get_xfont_procs */ - default_subclass_get_xfont_device, /* get_xfont_device */ - default_subclass_map_rgb_alpha_color, - default_subclass_get_page_device, - default_subclass_get_alpha_bits, /* get_alpha_bits */ - default_subclass_copy_alpha, - default_subclass_get_band, /* get_band */ - default_subclass_copy_rop, /* copy_rop */ - obj_filter_fill_path, - obj_filter_stroke_path, - obj_filter_fill_mask, - obj_filter_fill_trapezoid, - obj_filter_fill_parallelogram, - obj_filter_fill_triangle, - obj_filter_draw_thin_line, - obj_filter_begin_image, - obj_filter_image_data, /* image_data */ - obj_filter_end_image, /* end_image */ - obj_filter_strip_tile_rectangle, - obj_filter_strip_copy_rop, - default_subclass_get_clipping_box, /* get_clipping_box */ - obj_filter_begin_typed_image, - default_subclass_get_bits_rectangle, /* get_bits_rectangle */ - default_subclass_map_color_rgb_alpha, - default_subclass_create_compositor, - default_subclass_get_hardware_params, /* get_hardware_params */ - obj_filter_text_begin, - default_subclass_finish_copydevice, /* finish_copydevice */ - default_subclass_begin_transparency_group, /* begin_transparency_group */ - default_subclass_end_transparency_group, /* end_transparency_group */ - default_subclass_begin_transparency_mask, /* begin_transparency_mask */ - default_subclass_end_transparency_mask, /* end_transparency_mask */ - default_subclass_discard_transparency_layer, /* discard_transparency_layer */ - default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ - default_subclass_get_color_comp_index, /* get_color_comp_index */ - default_subclass_encode_color, /* encode_color */ - default_subclass_decode_color, /* decode_color */ - default_subclass_pattern_manage, /* pattern_manage */ - obj_filter_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - default_subclass_include_color_space, /* include_color_space */ - obj_filter_fill_linear_color_scanline, /* fill_linear_color_scanline */ - obj_filter_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ - obj_filter_fill_linear_color_triangle, /* fill_linear_color_triangle */ - default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ - default_subclass_ret_devn_params, /* ret_devn_params */ - default_subclass_fillpage, /* fillpage */ - default_subclass_push_transparency_state, /* push_transparency_state */ - default_subclass_pop_transparency_state, /* pop_transparency_state */ - obj_filter_put_image, /* put_image */ - default_subclass_dev_spec_op, /* dev_spec_op */ - default_subclass_copy_planes, /* copy_planes */ - default_subclass_get_profile, /* get_profile */ - default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ - obj_filter_strip_copy_rop2, - obj_filter_strip_tile_rect_devn, - default_subclass_copy_alpha_hl_color, - default_subclass_process_page, - default_subclass_transform_pixel_region, - obj_filter_fill_stroke_path, - } + 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) }; #undef MAX_COORD @@ -190,22 +136,6 @@ int obj_filter_fill_rectangle(gx_device *dev, int x, int y, int width, int heigh return 0; } -int obj_filter_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, - gx_color_index color0, gx_color_index color1, - int phase_x, int phase_y) -{ - if ((dev->ObjectFilter & FILTERVECTOR) == 0) - return default_subclass_tile_rectangle(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); - return 0; -} - -int obj_filter_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) -{ - if ((dev->ObjectFilter & FILTERVECTOR) == 0) - return default_subclass_draw_line(dev, x0, y0, x1, y1, color); - return 0; -} - int obj_filter_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) @@ -278,31 +208,6 @@ int obj_filter_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, f return 0; } -int obj_filter_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, - gs_image_format_t format, const gs_int_rect *prect, - const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gx_image_enum_common_t **pinfo) -{ - if ((dev->ObjectFilter & FILTERIMAGE) == 0) - return default_subclass_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); - return 0; -} - -int obj_filter_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, - uint raster, int height) -{ - if ((dev->ObjectFilter & FILTERIMAGE) == 0) - return default_subclass_image_data(dev, info, planes, data_x, raster, height); - return 0; -} - -int obj_filter_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) -{ - if ((dev->ObjectFilter & FILTERIMAGE) == 0) - return default_subclass_end_image(dev, info, draw_last); - return 0; -} - int obj_filter_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) @@ -312,17 +217,6 @@ int obj_filter_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles return 0; } -int obj_filter_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_strip_bitmap *textures, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - if ((dev->ObjectFilter & FILTERIMAGE) == 0) - return default_subclass_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); - return 0; -} - typedef struct obj_filter_image_enum_s { gx_image_enum_common; int y; @@ -474,11 +368,12 @@ static const gs_text_enum_procs_t obj_filter_text_procs = { * up to the device, in which case we simply pass on the 'begin' method to the device. */ int obj_filter_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gs_text_enum_t **ppte) + gs_font *font, const gx_clip_path *pcpath, + gs_text_enum_t **ppte) { obj_filter_text_enum_t *penum; int code = 0; + gs_memory_t * memory = pgs->memory; /* We don't want to simply ignore stringwidth for 2 reasons; * firstly because following elelments may be positioned based on the value returned @@ -490,16 +385,16 @@ int obj_filter_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t * stringwidth operation, or they won;t be able to cache the glyphs properly. * So always pass stringwidth operations to the child. */ - return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte); if ((dev->ObjectFilter & FILTERTEXT) == 0) - return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte); rc_alloc_struct_1(penum, obj_filter_text_enum_t, &st_obj_filter_text_enum, memory, return_error(gs_error_VMerror), "gdev_obj_filter_text_begin"); penum->rc.free = rc_free_text_enum; code = gs_text_enum_init((gs_text_enum_t *)penum, &obj_filter_text_procs, - dev, pgs, text, font, path, pdcolor, pcpath, memory); + dev, pgs, text, font, pcpath, memory); if (code < 0) { gs_free_object(memory, penum, "gdev_obj_filter_text_begin"); return code; diff --git a/base/gdevp14.c b/base/gdevp14.c index 8819ad90..d7992bc4 100644 --- a/base/gdevp14.c +++ b/base/gdevp14.c @@ -69,6 +69,7 @@ #define CAL_SLOP 0 #endif #include "assert_.h" +#include "gxgetbit.h" #if RAW_DUMP unsigned int global_index = 0; @@ -119,7 +120,7 @@ static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev); # define INCR(v) DO_NOTHING /* Forward prototypes */ -void pdf14_cmyk_cs_to_cmyk_cm(gx_device *, frac, frac, frac, frac, frac *); +void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *); static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct); @@ -168,6 +169,8 @@ gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor", #define X_DPI 72 #define Y_DPI 72 +static int pdf14_initialize_device(gx_device *dev); + static int pdf14_open(gx_device * pdev); static dev_proc_close_device(pdf14_close); static int pdf14_output_page(gx_device * pdev, int num_copies, int flush); @@ -193,9 +196,8 @@ static dev_proc_fill_mask(pdf14_fill_mask); static dev_proc_stroke_path(pdf14_stroke_path); static dev_proc_begin_typed_image(pdf14_begin_typed_image); static dev_proc_text_begin(pdf14_text_begin); -static dev_proc_finish_copydevice(pdf14_finish_copydevice); -static dev_proc_create_compositor(pdf14_create_compositor); -static dev_proc_create_compositor(pdf14_forward_create_compositor); +static dev_proc_composite(pdf14_composite); +static dev_proc_composite(pdf14_forward_composite); static dev_proc_begin_transparency_group(pdf14_begin_transparency_group); static dev_proc_end_transparency_group(pdf14_end_transparency_group); static dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask); @@ -218,121 +220,121 @@ static const gx_color_map_procs * /* 24-bit color. */ -#define pdf14_dev_procs(get_color_mapping_procs, get_color_comp_index, encode_color, decode_color) \ -{\ - pdf14_open, /* open */\ - NULL, /* get_initial_matrix */\ - NULL, /* sync_output */\ - pdf14_output_page, /* output_page */\ - pdf14_close, /* close */\ - encode_color, /* rgb_map_rgb_color */\ - decode_color, /* gx_default_rgb_map_color_rgb */\ - pdf14_fill_rectangle, /* fill_rectangle */\ - NULL, /* tile_rectangle */\ - pdf14_copy_mono, /* copy_mono */\ - NULL, /* copy_color */\ - NULL, /* draw_line */\ - NULL, /* get_bits */\ - gx_forward_get_params, /* get_params */\ - pdf14_put_params, /* put_params */\ - NULL, /* map_cmyk_color */\ - NULL, /* get_xfont_procs */\ - NULL, /* get_xfont_device */\ - NULL, /* map_rgb_alpha_color */\ - NULL, /* get_page_device */\ - NULL, /* get_alpha_bits */\ - pdf14_copy_alpha, /* copy_alpha */\ - NULL, /* get_band */\ - NULL, /* copy_rop */\ - pdf14_fill_path, /* fill_path */\ - pdf14_stroke_path, /* stroke_path */\ - pdf14_fill_mask, /* fill_mask */\ - NULL, /* fill_trapezoid */\ - NULL, /* fill_parallelogram */\ - NULL, /* fill_triangle */\ - NULL, /* draw_thin_line */\ - NULL, /* begin_image */\ - NULL, /* image_data */\ - NULL, /* end_image */\ - NULL, /* strip_tile_rectangle */\ - NULL, /* strip_copy_rop, */\ - NULL, /* get_clipping_box */\ - pdf14_begin_typed_image, /* begin_typed_image */\ - NULL, /* get_bits_rectangle */\ - NULL, /* map_color_rgb_alpha */\ - pdf14_create_compositor, /* create_compositor */\ - NULL, /* get_hardware_params */\ - pdf14_text_begin, /* text_begin */\ - pdf14_finish_copydevice, /* finish_copydevice */\ - pdf14_begin_transparency_group,\ - pdf14_end_transparency_group,\ - pdf14_begin_transparency_mask,\ - pdf14_end_transparency_mask,\ - pdf14_discard_trans_layer,\ - get_color_mapping_procs, /* get_color_mapping_procs */\ - get_color_comp_index, /* get_color_comp_index */\ - encode_color, /* encode_color */\ - decode_color, /* decode_color */\ - NULL, /* pattern_manage */\ - pdf14_fill_rectangle_hl_color, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - gx_forward_update_spot_equivalent_colors, /* update spot */\ - pdf14_ret_devn_params, /* DevN params */\ - NULL, /* fill page */\ - pdf14_push_transparency_state, /* push_transparency_state */\ - pdf14_pop_transparency_state, /* pop_transparency_state */\ - NULL, /* put_image */\ - pdf14_dev_spec_op, /* dev_spec_op */\ - pdf14_copy_planes, /* copy_planes */\ - NULL, /* */\ - gx_forward_set_graphics_type_tag, /* set_graphics_type_tag */\ - NULL, /* strip_copy_rop2 */\ - pdf14_strip_tile_rect_devn, /* strip_tile_rect_devn */\ - pdf14_copy_alpha_hl_color, /* copy_alpha_hl_color */\ - NULL, /* process_page */\ - NULL, /* transform_pixel_region */\ - pdf14_fill_stroke_path, /* fill_stroke */\ -} - -static const gx_device_procs pdf14_Gray_procs = - pdf14_dev_procs(gx_default_DevGray_get_color_mapping_procs, - gx_default_DevGray_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_RGB_procs = - pdf14_dev_procs(gx_default_DevRGB_get_color_mapping_procs, - gx_default_DevRGB_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_CMYK_procs = - pdf14_dev_procs(gx_default_DevCMYK_get_color_mapping_procs, - gx_default_DevCMYK_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_CMYKspot_procs = - pdf14_dev_procs(pdf14_cmykspot_get_color_mapping_procs, - pdf14_cmykspot_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_RGBspot_procs = - pdf14_dev_procs(pdf14_rgbspot_get_color_mapping_procs, - pdf14_rgbspot_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_Grayspot_procs = -pdf14_dev_procs(pdf14_grayspot_get_color_mapping_procs, - pdf14_grayspot_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - - -static const gx_device_procs pdf14_custom_procs = - pdf14_dev_procs(gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color); +static void +pdf14_procs_initialize(gx_device *dev, + dev_proc_get_color_mapping_procs(get_color_mapping_procs), + dev_proc_get_color_comp_index(get_color_comp_index), + dev_proc_encode_color(encode_color), + dev_proc_decode_color(decode_color)) +{ + set_dev_proc(dev, initialize_device, pdf14_initialize_device); + set_dev_proc(dev, open_device, pdf14_open); + set_dev_proc(dev, output_page, pdf14_output_page); + set_dev_proc(dev, close_device, pdf14_close); + set_dev_proc(dev, map_rgb_color, encode_color); + set_dev_proc(dev, map_color_rgb, decode_color); + set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle); + set_dev_proc(dev, copy_mono, pdf14_copy_mono); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, pdf14_put_params); + set_dev_proc(dev, copy_alpha, pdf14_copy_alpha); + set_dev_proc(dev, fill_path, pdf14_fill_path); + set_dev_proc(dev, stroke_path, pdf14_stroke_path); + set_dev_proc(dev, fill_mask, pdf14_fill_mask); + set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image); + set_dev_proc(dev, composite, pdf14_composite); + set_dev_proc(dev, text_begin, pdf14_text_begin); + set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group); + set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group); + set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask); + set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask); + set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer); + set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, get_color_comp_index); + set_dev_proc(dev, encode_color, encode_color); + set_dev_proc(dev, decode_color, decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params); + set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state); + set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state); + set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op); + set_dev_proc(dev, copy_planes, pdf14_copy_planes); + set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color); + set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path); +} + +static void +pdf14_Gray_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + gx_default_DevGray_get_color_mapping_procs, + gx_default_DevGray_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_RGB_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + gx_default_DevRGB_get_color_mapping_procs, + gx_default_DevRGB_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_CMYK_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + gx_default_DevCMYK_get_color_mapping_procs, + gx_default_DevCMYK_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_CMYKspot_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + pdf14_cmykspot_get_color_mapping_procs, + pdf14_cmykspot_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_RGBspot_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + pdf14_rgbspot_get_color_mapping_procs, + pdf14_rgbspot_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_Grayspot_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + pdf14_grayspot_get_color_mapping_procs, + pdf14_grayspot_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +} + +static void +pdf14_custom_initialize_device_procs(gx_device *dev) +{ + pdf14_procs_initialize(dev, + gx_forward_get_color_mapping_procs, + gx_forward_get_color_comp_index, + gx_forward_encode_color, + gx_forward_decode_color); +} static struct_proc_finalize(pdf14_device_finalize); @@ -448,10 +450,12 @@ static const pdf14_nonseparable_blending_procs_t custom_blending_procs = { }; const pdf14_device gs_pdf14_Gray_device = { - std_device_std_color_full_body_type(pdf14_device, &pdf14_Gray_procs, "pdf14gray", - &st_pdf14_device, - XSIZE, YSIZE, X_DPI, Y_DPI, 8, - 0, 0, 0, 0, 0, 0), + std_device_std_color_full_body_type(pdf14_device, + pdf14_Gray_initialize_device_procs, + "pdf14gray", + &st_pdf14_device, + XSIZE, YSIZE, X_DPI, Y_DPI, 8, + 0, 0, 0, 0, 0, 0), { 0 }, /* Procs */ NULL, /* target */ { 0 }, /* devn_params - not used */ @@ -461,7 +465,9 @@ const pdf14_device gs_pdf14_Gray_device = { }; const pdf14_device gs_pdf14_RGB_device = { - std_device_color_stype_body(pdf14_device, &pdf14_RGB_procs, "pdf14RGB", + std_device_color_stype_body(pdf14_device, + pdf14_RGB_initialize_device_procs, + "pdf14RGB", &st_pdf14_device, XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256), { 0 }, /* Procs */ @@ -472,10 +478,13 @@ const pdf14_device gs_pdf14_RGB_device = { 3 }; -const pdf14_device gs_pdf14_CMYK_device = { - std_device_std_color_full_body_type(pdf14_device, &pdf14_CMYK_procs, - "pdf14cmyk", &st_pdf14_device, XSIZE, YSIZE, X_DPI, Y_DPI, 32, - 0, 0, 0, 0, 0, 0), +const pdf14_device gs_pdf14_CMYK_device = { + std_device_std_color_full_body_type(pdf14_device, + pdf14_CMYK_initialize_device_procs, + "pdf14cmyk", + &st_pdf14_device, + XSIZE, YSIZE, X_DPI, Y_DPI, 32, + 0, 0, 0, 0, 0, 0), { 0 }, /* Procs */ NULL, /* target */ { 0 }, /* devn_params - not used */ @@ -485,8 +494,11 @@ const pdf14_device gs_pdf14_CMYK_device = { }; const pdf14_device gs_pdf14_CMYKspot_device = { - std_device_part1_(pdf14_device, &pdf14_CMYKspot_procs, "pdf14cmykspot", - &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_CMYKspot_initialize_device_procs, + "pdf14cmykspot", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -509,8 +521,11 @@ const pdf14_device gs_pdf14_CMYKspot_device = { }; const pdf14_device gs_pdf14_RGBspot_device = { - std_device_part1_(pdf14_device, &pdf14_RGBspot_procs, "pdf14rgbspot", - &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_RGBspot_initialize_device_procs, + "pdf14rgbspot", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -533,8 +548,11 @@ const pdf14_device gs_pdf14_RGBspot_device = { }; const pdf14_device gs_pdf14_Grayspot_device = { - std_device_part1_(pdf14_device, &pdf14_Grayspot_procs, "pdf14grayspot", - &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_Grayspot_initialize_device_procs, + "pdf14grayspot", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -568,8 +586,11 @@ const pdf14_device gs_pdf14_Grayspot_device = { * about how to treat these blending modes. */ const pdf14_device gs_pdf14_custom_device = { - std_device_part1_(pdf14_device, &pdf14_custom_procs, "pdf14custom", - &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_custom_initialize_device_procs, + "pdf14custom", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -634,141 +655,96 @@ gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum, "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs, gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev); -static const gx_device_procs pdf14_accum_Gray_procs = - prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, - gx_default_8bit_map_gray_color, gx_default_8bit_map_color_gray); +static void +pdf14_accum_Gray_initialize_device_procs(gx_device *dev) +{ + gdev_prn_initialize_device_procs_gray8(dev); + + set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color); + set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray); +} const gx_device_pdf14_accum pdf14_accum_Gray = { - prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_Gray_procs, "pdf14-accum-Gray", - &st_gx_devn_accum_device, - 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, - 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, - 1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/, - 256/*dither_grays*/, 0/*dither_colors*/, - no_print_page), + prn_device_stype_body(gx_device_pdf14_accum, + pdf14_accum_Gray_initialize_device_procs, + "pdf14-accum-Gray", + &st_gx_devn_accum_device, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/, + 256/*dither_grays*/, 0/*dither_colors*/, + no_print_page), { 0 }, /* devn_params - not used */ { 0 }, /* equivalent_cmyk_color_params - not used */ 0/*save_p14dev*/ }; -static const gx_device_procs pdf14_accum_RGB_procs = - prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, - gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb); +static void +pdf14_accum_RGB_initialize_device_procs(gx_device *dev) +{ + gdev_prn_initialize_device_procs_rgb(dev); +} const gx_device_pdf14_accum pdf14_accum_RGB = { - prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_RGB_procs, "pdf14-accum-RGB", - &st_gx_devn_accum_device, - 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, - 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, - 3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/, - 1/*dither_grays*/, 256/*dither_colors*/, - no_print_page), + prn_device_stype_body(gx_device_pdf14_accum, + pdf14_accum_RGB_initialize_device_procs, + "pdf14-accum-RGB", + &st_gx_devn_accum_device, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/, + 1/*dither_grays*/, 256/*dither_colors*/, + no_print_page), { 0 }, /* devn_params - not used */ { 0 }, /* equivalent_cmyk_color_params - not used */ 0/*save_p14dev*/ }; -static const gx_device_procs pdf14_accum_CMYK_procs = - prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, - cmyk_8bit_map_cmyk_color, cmyk_8bit_map_color_cmyk); +static void +pdf14_accum_CMYK_initialize_device_procs(gx_device *dev) +{ + gdev_prn_initialize_device_procs_cmyk8(dev); + + set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color); + set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk); +} const gx_device_pdf14_accum pdf14_accum_CMYK = { - prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_CMYK_procs, "pdf14-accum-CMYK", - &st_gx_devn_accum_device, - 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, - 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, - 4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/, - 256/*dither_grays*/, 256/*dither_colors*/, - no_print_page), + prn_device_stype_body(gx_device_pdf14_accum, + pdf14_accum_CMYK_initialize_device_procs, + "pdf14-accum-CMYK", + &st_gx_devn_accum_device, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/, + 256/*dither_grays*/, 256/*dither_colors*/, + no_print_page), { 0 }, /* devn_params - not used */ { 0 }, /* equivalent_cmyk_color_params - not used */ 0/*save_p14dev*/ }; -static const gx_device_procs pdf14_accum_CMYKspot_procs = -{\ - gdev_prn_open, /* open */\ - NULL, /* get_initial_matrix */\ - NULL, /* sync_output */\ - NULL, /* output_page */\ - gdev_prn_close, /* close */\ - cmyk_8bit_map_cmyk_color, /* rgb_map_rgb_color */\ - cmyk_8bit_map_color_cmyk, /* gx_default_rgb_map_color_rgb */\ - NULL, /* fill_rectangle */\ - NULL, /* tile_rectangle */\ - NULL, /* copy_mono */\ - NULL, /* copy_color */\ - NULL, /* draw_line */\ - NULL, /* get_bits */\ - NULL, /* get_params */\ - NULL, /* put_params */\ - NULL, /* map_cmyk_color */\ - NULL, /* get_xfont_procs */\ - NULL, /* get_xfont_device */\ - NULL, /* map_rgb_alpha_color */\ - NULL, /* get_page_device */\ - NULL, /* get_alpha_bits */\ - NULL , /* copy_alpha */\ - NULL, /* get_band */\ - NULL, /* copy_rop */\ - NULL, /* fill_path */\ - NULL, /* stroke_path */\ - NULL, /* fill_mask */\ - NULL, /* fill_trapezoid */\ - NULL, /* fill_parallelogram */\ - NULL, /* fill_triangle */\ - NULL, /* draw_thin_line */\ - NULL, /* begin_image */\ - NULL, /* image_data */\ - NULL, /* end_image */\ - NULL, /* strip_tile_rectangle */\ - NULL, /* strip_copy_rop, */\ - NULL, /* get_clipping_box */\ - NULL, /* begin_typed_image */\ - NULL, /* get_bits_rectangle */\ - NULL, /* map_color_rgb_alpha */\ - NULL, /* create_compositor */\ - NULL, /* get_hardware_params */\ - NULL, /* text_begin */\ - NULL, /* finish_copydevice */\ - NULL, /* begin_transparency_group */\ - NULL, /* end_transparency_group */\ - NULL, /* begin_transparency_mask */\ - NULL, /* end_transparency_mask */\ - NULL, /* discard_trans_layer */\ - pdf14_accum_get_color_mapping_procs, /* get_color_mapping_procs */\ - pdf14_accum_get_color_comp_index, /* get_color_comp_index */\ - cmyk_8bit_map_cmyk_color, /* encode_color */\ - cmyk_8bit_map_color_cmyk, /* decode_color */\ - NULL, /* pattern_manage */\ - NULL, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - pdf14_accum_update_spot_equivalent_colors, /* update spot */\ - pdf14_accum_ret_devn_params, /* DevN params */\ - NULL, /* fill page */\ - NULL, /* push_transparency_state */\ - NULL, /* pop_transparency_state */\ - NULL, /* put_image */\ - NULL, /* dev_spec_op */\ - NULL, /* copy_planes */\ - NULL, /* */\ - NULL, /* set_graphics_type_tag */\ - NULL, /* strip_copy_rop2 */\ - NULL, /* strip_tile_rect_devn */\ - NULL /* copy_alpha_hl_color */\ -}; +static void +pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev) +{ + pdf14_accum_CMYK_initialize_device_procs(dev); + + set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index); + set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params); +} const gx_device_pdf14_accum pdf14_accum_CMYKspot = { - prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_CMYKspot_procs, "pdf14-accum-CMYKspot", - &st_gx_devn_accum_device, - 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, - 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, - 4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/, - 256/*dither_grays*/, 256/*dither_colors*/, - no_print_page), + prn_device_stype_body(gx_device_pdf14_accum, + pdf14_accum_initialize_device_procs_cmykspot, + "pdf14-accum-CMYKspot", + &st_gx_devn_accum_device, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/, + 256/*dither_grays*/, 256/*dither_colors*/, + no_print_page), /* DeviceN parameters */ { 8, /* Not used - Bits per color */ DeviceCMYKComponents, /* Names of color model colorants */ @@ -1609,6 +1585,7 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, bool overprint = pdev->overprint; gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill; bool has_matte = false; + int code = 0; #ifdef DEBUG pdf14_debug_mask_stack_state(ctx); @@ -1643,8 +1620,10 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, if (nos == NULL && maskbuf != NULL) { nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape, tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep); - if (nos == NULL) - return gs_error_VMerror; + if (nos == NULL) { + code = gs_error_VMerror; + goto exit; + } if_debug4m('v', ctx->memory, "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n", @@ -1744,8 +1723,11 @@ pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x, tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false); } - if (result == NULL) - return_error(gs_error_unknownerror); /* transform failed */ + if (result == NULL) { + /* Clean up and return error code */ + code = gs_error_unknownerror; + goto exit; + } #if RAW_DUMP /* Dump the current buffer to see what we have. */ @@ -1781,6 +1763,8 @@ exit: } if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle); pdf14_buf_free(tos); + if (code < 0) + return_error(code); return 0; } @@ -2239,20 +2223,23 @@ static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = { }; static const gx_cm_color_map_procs * -pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev) +pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev) { + *tdev = dev; return &pdf14_DeviceCMYKspot_procs; } static const gx_cm_color_map_procs * -pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev) +pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev) { + *tdev = dev; return &pdf14_DeviceRGBspot_procs; } static const gx_cm_color_map_procs * -pdf14_grayspot_get_color_mapping_procs(const gx_device * dev) +pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev) { + *tdev = dev; return &pdf14_DeviceGrayspot_procs; } @@ -3124,6 +3111,48 @@ pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rows } } +static pdf14_buf* +insert_empty_planes(pdf14_ctx* ctx, pdf14_buf** src_buf, int num_new_planes, int insert_index) +{ + int planestride = (*src_buf)->planestride; + int src_n_planes = (*src_buf)->n_planes; + int src_n_chan = (*src_buf)->n_chan; + int des_n_planes = src_n_planes + num_new_planes; + int des_n_chan = src_n_chan + num_new_planes; + byte *src_ptr = (*src_buf)->data; + byte* des_ptr; + byte *des_data; + bool deep = ctx->deep; + + des_data = gs_alloc_bytes(ctx->memory, + (size_t)planestride * des_n_planes + CAL_SLOP, + "insert_empty_planes"); + if (des_data == NULL) + return NULL; + + des_ptr = des_data; + + /* First copy portion prior to insert point */ + memcpy(des_ptr, src_ptr, (planestride * insert_index) << deep); + + /* New planes */ + des_ptr += (planestride * insert_index) << deep; + src_ptr += (planestride * insert_index) << deep; + memset(des_ptr, 0, (planestride * num_new_planes) << deep); + + /* Extra planes (i.e. doc spots, tags) */ + des_ptr += (planestride * num_new_planes) << deep; + memcpy(des_ptr, src_ptr, (planestride * (src_n_planes - insert_index)) << deep); + + /* Set up buffer structure */ + gs_free_object(ctx->memory, (*src_buf)->data, "insert_empty_planes"); + (*src_buf)->n_planes = des_n_planes; + (*src_buf)->n_chan = des_n_chan; + (*src_buf)->data = des_data; + + return *src_buf; +} + static int pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, gs_gstate* pgs, pdf14_buf* buf, int planestride_in, @@ -3367,6 +3396,30 @@ pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target, tag_offset = buf->has_tags ? buf->n_chan : 0; } + /* We may need to pad the buffers to ensure that any additional spot + channels that are not created by the ICC color conversion (or + non-conversion if this is not an NCLR profile) get placed properly. + It is up to the target device to + handle these planes how it sees fit based upon the image data + and/or any tags plane during any put image call. We *could* + do something here to possibly communicate through the put_image + call where the page related spots start, but that would/could + be confusing, especially for long term maintenance. Easier just + to have put_image hand all the data */ + if (dev_target_profile->spotnames != NULL && + dev_target_profile->spotnames->count > des_profile->num_comps) { + int num_new_planes = dev_target_profile->spotnames->count - des_profile->num_comps; + int insert_index = des_profile->num_comps; + pdf14_buf* result; + + result = insert_empty_planes(pdev->ctx, &buf, num_new_planes, insert_index); + if (result == NULL) + return_error(gs_error_VMerror); + + num_comp = buf->n_chan; + tag_offset = buf->has_tags ? buf->n_chan : 0; + buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep); + } #if RAW_DUMP /* Dump after the CS transform */ dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride, @@ -4018,6 +4071,7 @@ pdf14_fill_path(gx_device *dev, const gs_gstate *pgs, if (pdcolor == NULL) return_error(gs_error_unknownerror); /* color must be defined */ + ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE; if (gx_dc_is_pattern1_color(pdcolor)){ if( gx_pattern1_get_transptr(pdcolor) != NULL || gx_pattern1_clist_has_trans(pdcolor) ){ @@ -4209,9 +4263,13 @@ pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs, } else update_lop_for_pdf14(&new_pgs, pdcolor); pdf14_set_marking_params(dev, &new_pgs); - if (code >= 0) - code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, - pcpath); + if (code >= 0) { + PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state; + + ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE; + code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath); + ((pdf14_device*)dev)->op_state = save_op_state; + } if (code >= 0 && push_group) { code = pop_shfill_group(&new_pgs); pdf14_set_marking_params(dev, pgs); @@ -4242,6 +4300,7 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, float stroke_alpha = cpgs->strokeconstantalpha; float fill_alpha = cpgs->fillconstantalpha; gs_blend_mode_t blend_mode = cpgs->blend_mode; + PDF14_OP_FS_STATE save_op_state = p14dev->op_state; /* Break const just once, neatly */ const_breaker.cpgs = cpgs; @@ -4290,7 +4349,10 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box); if (code < 0) return code; - + if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) { + p14dev->overprint = pgs->overprint; + p14dev->stroke_overprint = pgs->stroke_overprint; + } /* See if overprint is enabled for both stroke and fill AND if ca == CA */ if (fill_alpha == stroke_alpha && p14dev->overprint && p14dev->stroke_overprint && @@ -4345,7 +4407,6 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, /* restore blend mode for actual drawing in the group */ (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */ - p14dev->op_state = PDF14_OP_STATE_FILL; /* If we are in an overprint situation, set the blend mode to compatible overprint */ @@ -4384,6 +4445,7 @@ pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath, cleanup: /* Restore the state */ + p14dev->op_state = save_op_state; (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */ (void)gs_setstrokeconstantalpha(pgs, stroke_alpha); (void)gs_setfillconstantalpha(pgs, fill_alpha); @@ -5343,7 +5405,7 @@ pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs, renderer which will end up installed for this case. Detect setting of begin_image to gx_no_begin_image. (final recursive call) */ - if (dev_proc(dev, begin_image) != gx_default_begin_image) { + if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) { code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); @@ -5444,7 +5506,6 @@ pdf14_forward_device_procs(gx_device * dev) set_dev_proc(dev, close_device, gx_forward_close_device); set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle); set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); - set_dev_proc(dev, tile_rectangle, gx_forward_tile_rectangle); set_dev_proc(dev, copy_mono, gx_forward_copy_mono); set_dev_proc(dev, copy_color, gx_forward_copy_color); set_dev_proc(dev, get_page_device, gx_forward_get_page_device); @@ -5471,7 +5532,7 @@ pdf14_disable_device(gx_device * dev) if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n"); dev->color_info = pdev->target->color_info; pdf14_forward_device_procs(dev); - set_dev_proc(dev, create_compositor, pdf14_forward_create_compositor); + set_dev_proc(dev, composite, pdf14_forward_composite); return 0; } @@ -5600,9 +5661,11 @@ pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum, * currently only using a color space based upon the device. */ static int -get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, - pdf14_device * ptempdevproto, gs_gstate * pgs, - const gs_pdf14trans_t * pdf14pct, bool use_pdf14_accum) +get_pdf14_device_proto(gx_device *dev, + pdf14_device *pdevproto, + gs_gstate *pgs, + const gs_pdf14trans_t *pdf14pct, + bool use_pdf14_accum) { bool using_blend_cs; pdf14_default_colorspace_t dev_cs = @@ -5623,38 +5686,32 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, switch (dev_cs) { case PDF14_DeviceGray: - *pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.max_components = 1; - ptempdevproto->color_info.num_components = - ptempdevproto->color_info.max_components; - ptempdevproto->color_info.depth = 8<<deep; - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.gray_index = 0; /* Avoid halftoning */ - ptempdevproto->color_info.dither_grays = deep ? 65536 : 256; - ptempdevproto->sep_device = false; - *pdevproto = ptempdevproto; + *pdevproto = gs_pdf14_Gray_device; + pdevproto->color_info.max_components = 1; + pdevproto->color_info.num_components = + pdevproto->color_info.max_components; + pdevproto->color_info.depth = 8<<deep; + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.gray_index = 0; /* Avoid halftoning */ + pdevproto->color_info.dither_grays = deep ? 65536 : 256; + pdevproto->sep_device = false; break; case PDF14_DeviceRGB: - *pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.depth = 24<<deep; - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.dither_grays = deep ? 65536 : 256; - ptempdevproto->sep_device = false; - *pdevproto = ptempdevproto; + *pdevproto = gs_pdf14_RGB_device; + pdevproto->color_info.depth = 24<<deep; + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.dither_grays = deep ? 65536 : 256; + pdevproto->sep_device = false; break; case PDF14_DeviceCMYK: - *pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.depth = 32<<deep; - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.dither_grays = deep ? 65536 : 256; - ptempdevproto->sep_device = false; - *pdevproto = ptempdevproto; + *pdevproto = gs_pdf14_CMYK_device; + pdevproto->color_info.depth = 32<<deep; + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.dither_grays = deep ? 65536 : 256; + pdevproto->sep_device = false; break; case PDF14_DeviceCMYKspot: - *pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device; + *pdevproto = gs_pdf14_CMYKspot_device; /* Need to figure out how we want to handle the device profile for this case */ /* @@ -5663,18 +5720,14 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, * for the page. */ if (num_spots >= 0) { - *ptempdevproto = **pdevproto; - ptempdevproto->devn_params.page_spot_colors = num_spots; - ptempdevproto->color_info.num_components = - ptempdevproto->devn_params.num_std_colorant_names + num_spots; - if (ptempdevproto->color_info.num_components > - GS_CLIENT_COLOR_MAX_COMPONENTS) - ptempdevproto->color_info.num_components = - GS_CLIENT_COLOR_MAX_COMPONENTS; - ptempdevproto->color_info.depth = - ptempdevproto->color_info.num_components * (8<<deep); - ptempdevproto->sep_device = true; - *pdevproto = ptempdevproto; + pdevproto->devn_params.page_spot_colors = num_spots; + pdevproto->color_info.num_components = + pdevproto->devn_params.num_std_colorant_names + num_spots; + if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS) + pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS; + pdevproto->color_info.depth = + pdevproto->color_info.num_components * (8<<deep); + pdevproto->sep_device = true; } break; case PDF14_DeviceCustom: @@ -5683,23 +5736,22 @@ get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, * color_info for the PDF 1.4 compositing device needs to match * the output device. */ - *ptempdevproto = gs_pdf14_custom_device; - ptempdevproto->color_info = dev->color_info; + *pdevproto = gs_pdf14_custom_device; + pdevproto->color_info = dev->color_info; /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */ - ptempdevproto->color_info.depth = - ptempdevproto->color_info.num_components * (8<<deep); - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.max_color = deep ? 65535 : 255; - ptempdevproto->color_info.dither_grays = deep ? 65536 : 256; - ptempdevproto->color_info.dither_colors = deep ? 65536 : 256; - - *pdevproto = ptempdevproto; + pdevproto->color_info.depth = + pdevproto->color_info.num_components * (8<<deep); + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.max_color = deep ? 65535 : 255; + pdevproto->color_info.dither_grays = deep ? 65536 : 256; + pdevproto->color_info.dither_colors = deep ? 65536 : 256; break; default: /* Should not occur */ return_error(gs_error_rangecheck); } - ptempdevproto->using_blend_cs = using_blend_cs; - ptempdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; + pdevproto->initialize_device_procs((gx_device *)pdevproto); + pdevproto->using_blend_cs = using_blend_cs; + pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; return 0; } @@ -5773,8 +5825,7 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, { pdf14_device * pdev = (pdf14_device *)dev; gx_device * target = pdev->target; - pdf14_device * dev_proto; - pdf14_device temp_dev_proto; + pdf14_device dev_proto; bool has_tags = device_encodes_tags(dev); int code; bool deep = device_is_deep(dev); @@ -5785,11 +5836,11 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, * We will not use the entire prototype device but we will set the * color related info and the device procs to match the prototype. */ - code = get_pdf14_device_proto(target, &dev_proto, &temp_dev_proto, pgs, + code = get_pdf14_device_proto(target, &dev_proto, pgs, pdf14pct, false); if (code < 0) return code; - pdev->color_info = dev_proto->color_info; + pdev->color_info = dev_proto.color_info; pdev->pad = target->pad; pdev->log2_align_mod = target->log2_align_mod; @@ -5798,7 +5849,7 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, else pdev->is_planar = target->is_planar; - pdev->procs = dev_proto->procs; + pdev->procs = dev_proto.procs; if (deep) { set_dev_proc(pdev, encode_color, pdf14_encode_color16); set_dev_proc(pdev, decode_color, pdf14_decode_color16); @@ -5808,8 +5859,6 @@ pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth; pdev->color_info.depth += 8; } - dev->static_procs = dev_proto->static_procs; - gx_device_set_procs(dev); pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; gx_device_fill_in_procs((gx_device *)pdev); pdev->save_get_cmap_procs = pgs->get_cmap_procs; @@ -5947,7 +5996,7 @@ gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs, * to the target. */ static int -pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, +pdf14_forward_composite(gx_device * dev, gx_device * * pcdev, const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { @@ -5963,7 +6012,7 @@ pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem); return 0; } - code = dev_proc(tdev, create_compositor)(tdev, pcdev, pct, pgs, mem, cdev); + code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev); if (code == 1) { /* We have created a new compositor that wrapped tdev. This means * that our target should be updated to point to that. */ @@ -5979,7 +6028,7 @@ pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, * of the interface, don't bother trying to handle any other compositor. */ static int -pdf14_create_compositor(gx_device * dev, gx_device * * pcdev, +pdf14_composite(gx_device * dev, gx_device * * pcdev, const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { @@ -6005,7 +6054,8 @@ pdf14_create_compositor(gx_device * dev, gx_device * * pcdev, p14dev->op_state = op_pct->params.op_state; - if (!p14dev->op_state) { + + if (p14dev->op_state == PDF14_OP_STATE_NONE) { if (op_pct->params.retain_any_comps) { drawn_comps = op_pct->params.drawn_comps; } else { @@ -6026,7 +6076,7 @@ pdf14_create_compositor(gx_device * dev, gx_device * * pcdev, *pcdev = dev; return 0; } else - return gx_no_create_compositor(dev, pcdev, pct, pgs, mem, cdev); + return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev); } static int @@ -6073,8 +6123,7 @@ pdf14_push_text_group(gx_device *dev, gs_gstate *pgs, static int pdf14_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, - gx_path * path, const gx_device_color * pdcolor, - const gx_clip_path * pcpath, gs_memory_t * memory, + const gx_clip_path * pcpath, gs_text_enum_t ** ppenum) { int code; @@ -6094,10 +6143,9 @@ pdf14_text_begin(gx_device * dev, gs_gstate * pgs, if (code < 0) return code; - if_debug0m('v', memory, "[v]pdf14_text_begin\n"); + if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n"); pdf14_set_marking_params(dev, pgs); - code = gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, - memory, &penum); + code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum); if (code < 0) return code; @@ -6139,7 +6187,7 @@ pdf14_text_begin(gx_device * dev, gs_gstate * pgs, } static int -pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev) +pdf14_initialize_device(gx_device *new_dev) { pdf14_device *pdev = (pdf14_device*)new_dev; @@ -6147,8 +6195,7 @@ pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev) pdev->color_model_stack = NULL; pdev->smaskcolor = NULL; - /* Only allow copying the prototype. */ - return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); + return 0; } /* @@ -6488,11 +6535,18 @@ pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, const gx_drawing_color *pdcolor1, int px, int py) { pdf14_device *pdev = (pdf14_device *)dev; - pdf14_buf *buf = pdev->ctx->stack; - int num_comp = buf->n_chan - 1; + pdf14_buf *buf; + int num_comp; int k; bool same = false; - int code = 0; + int code; + + code = pdf14_initialize_ctx(dev, dev->color_info.num_components, + dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL); + if (code < 0) + return code; + buf = pdev->ctx->stack; + num_comp = buf->n_chan - 1; /* if color0 is identical to color1, do rect fill */ if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) { @@ -6829,6 +6883,8 @@ pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs) code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs, pdev->color_info.num_components, group_profile, (gx_device*)pdev); + if (code < 0) + return code; #ifdef DEBUG pdf14_debug_mask_stack_state(pdev->ctx); #endif @@ -7019,8 +7075,14 @@ pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type, if_debug2m('v', pdev->memory, "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n", pdev->color_info.num_components,new_num_comps); - set_dev_proc(pdev, get_color_mapping_procs, pdevproto->static_procs->get_color_mapping_procs); - set_dev_proc(pdev, get_color_comp_index, pdevproto->static_procs->get_color_comp_index); + { + gx_device local_device; + + local_device.initialize_device_procs = pdevproto->initialize_device_procs; + local_device.initialize_device_procs((gx_device *)&local_device); + set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index); + } group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs; group_color->polarity = pdev->color_info.polarity = new_polarity; group_color->num_components = pdev->color_info.num_components = new_num_comps; @@ -7296,8 +7358,14 @@ pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs, "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n", pdev->color_info.num_components, new_num_comps); /* Set new information in the device */ - set_dev_proc(pdev, get_color_mapping_procs, pdevproto->static_procs->get_color_mapping_procs); - set_dev_proc(pdev, get_color_comp_index, pdevproto->static_procs->get_color_comp_index); + { + gx_device local_device; + + local_device.initialize_device_procs = pdevproto->initialize_device_procs; + local_device.initialize_device_procs((gx_device *)&local_device); + set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index); + } pdev->blend_procs = pdevproto->blend_procs; pdev->color_info.polarity = new_polarity; pdev->color_info.num_components = new_num_comps; @@ -7726,6 +7794,7 @@ do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h, dst_ptr[k * planestride] = dst2[k]; } } + dst_ptr[num_comp * planestride] = dst[num_comp]; /* alpha */ } } else { if (overprint) { @@ -7942,6 +8011,7 @@ do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h, dst_ptr[k * planestride] = dst2[k]; } } + dst_ptr[num_comp * planestride] = dst[num_comp]; /* alpha */ } } else { if (overprint) { @@ -8024,7 +8094,6 @@ pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h, static cmap_proc_gray(pdf14_cmap_gray_direct); static cmap_proc_rgb(pdf14_cmap_rgb_direct); static cmap_proc_cmyk(pdf14_cmap_cmyk_direct); -static cmap_proc_rgb_alpha(pdf14_cmap_rgb_alpha_direct); static cmap_proc_separation(pdf14_cmap_separation_direct); static cmap_proc_devicen(pdf14_cmap_devicen_direct); static cmap_proc_is_halftoned(pdf14_cmap_is_halftoned); @@ -8033,7 +8102,6 @@ static const gx_color_map_procs pdf14_cmap_many = { pdf14_cmap_gray_direct, pdf14_cmap_rgb_direct, pdf14_cmap_cmyk_direct, - pdf14_cmap_rgb_alpha_direct, pdf14_cmap_separation_direct, pdf14_cmap_devicen_direct, pdf14_cmap_is_halftoned @@ -8087,6 +8155,8 @@ pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_device *trans_device; + const gx_device *map_dev; + const gx_cm_color_map_procs *procs; /* If trans device is set, we need to use its procs. */ if (pgs->trans_device != NULL) { @@ -8097,7 +8167,8 @@ pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, ncomps = trans_device->color_info.num_components; /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_gray(trans_device, gray, cm_comps); + procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev); + procs->map_gray(map_dev, gray, cm_comps); if (pdf14_state_opaque(trans_device, pgs)) { for (i = 0; i < ncomps; i++) @@ -8131,6 +8202,8 @@ pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_device *trans_device; + const gx_device *map_dev; + const gx_cm_color_map_procs *procs; /* If trans device is set, we need to use its procs. */ if (pgs->trans_device != NULL){ @@ -8140,7 +8213,8 @@ pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, } ncomps = trans_device->color_info.num_components; /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pgs, r, g, b, cm_comps); + procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev); + procs->map_rgb(map_dev, pgs, r, g, b, cm_comps); if (pdf14_state_opaque(trans_device, pgs)) { for (i = 0; i < ncomps; i++) @@ -8175,6 +8249,9 @@ pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_device *trans_device; + const gx_device *map_dev; + const gx_cm_color_map_procs *procs; + /* If trans device is set, we need to use its procs. */ if (pgs->trans_device != NULL){ @@ -8186,7 +8263,8 @@ pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, /* Map to the color model. Transfer function is only used if we are drawing with an opaque color. */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_cmyk(trans_device, c, m, y, k, cm_comps); + procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev); + procs->map_cmyk(map_dev, c, m, y, k, cm_comps); if (pdf14_state_opaque(trans_device, pgs)) { for (i = 0; i < ncomps; i++) @@ -8211,47 +8289,6 @@ pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, } } -static void -pdf14_cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) -{ - int i, ncomps; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - gx_device *trans_device; - - /* We may be coming from the clist writer which often forwards us the - target device. If this occurs we actually need to get to the color - space defined by the transparency group and we use the operators - defined by the transparency device to do the job. */ - if (pgs->trans_device != NULL){ - trans_device = pgs->trans_device; - } else { - trans_device = dev; - } - ncomps = trans_device->color_info.num_components; - /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pgs, r, g, b, cm_comps); - /* pre-multiply to account for the alpha weighting */ - if (alpha != frac_1) { -#ifdef PREMULTIPLY_TOWARDS_WHITE - frac alpha_bias = frac_1 - alpha; -#else - frac alpha_bias = 0; -#endif - for (i = 0; i < ncomps; i++) - cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias; - } - - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); -} - static int pdf14_get_num_spots(gx_device * dev) { @@ -8398,6 +8435,8 @@ pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op, { pdf14_device * p14dev = (pdf14_device *)pdev; + if (dev_spec_op == gxdso_supports_pattern_transparency) + return 1; if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) return 1; if (dev_spec_op == gxdso_is_pdf14_device) { @@ -8492,8 +8531,8 @@ static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct) { - pdf14_device * dev_proto; - pdf14_device * p14dev, temp_dev_proto; + pdf14_device dev_proto; + pdf14_device * p14dev; int code; bool has_tags; cmm_profile_t *icc_profile; @@ -8540,12 +8579,12 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, &render_cond); if_debug0m('v', mem, "[v]gs_pdf14_device_push\n"); - code = get_pdf14_device_proto(target, &dev_proto, &temp_dev_proto, pgs, + code = get_pdf14_device_proto(target, &dev_proto, pgs, pdf14pct, use_pdf14_accum); if (code < 0) return code; code = gs_copydevice((gx_device **) &p14dev, - (const gx_device *) dev_proto, mem); + (const gx_device *) &dev_proto, mem); if (code < 0) return code; @@ -8564,8 +8603,11 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, p14dev->fillconstantalpha = 1.0; p14dev->strokeconstantalpha = 1.0; - /* Simulated overprint case. We have to use CMYK-based profile */ - if (p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) { + /* Simulated overprint case. We have to use CMYK-based profile. Also if the target + profile is NCLR, we are going to use a pdf14 device that is CMYK based and + do the mapping to the NCLR profile when the put_image occurs */ + if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) || + icc_profile->data_cs == gsNCHANNEL) { gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push"); gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_push"); @@ -8638,7 +8680,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, p14dev->height = 1; } - p14dev->op_state = pgs->is_fill_color; + p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE; code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev); *pdev = (gx_device *) p14dev; pdf14_set_marking_params((gx_device *)p14dev, pgs); @@ -8716,7 +8758,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, goto no_clist_accum; (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor); - code = clist_create_compositor(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL); + code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL); if (code < 0) goto no_clist_accum; @@ -9248,7 +9290,7 @@ c_pdf14trans_create_default_compositor(const gs_composite_t * pct, /* * We only handle the push operation. All other operations are ignored. - * The other operations will be handled by the create_compositor routine + * The other operations will be handled by the composite routine * for the PDF 1.4 compositing device. */ switch (pdf14pct->params.pdf14_op) { @@ -9522,7 +9564,7 @@ send_pdf14trans(gs_gstate * pgs, gx_device * dev, code = gs_create_pdf14trans(&pct, pparams, mem); if (code < 0) return code; - code = dev_proc(dev, create_compositor) (dev, pcdev, pct, pgs, mem, NULL); + code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL); if (code == gs_error_handled) code = 0; @@ -9551,137 +9593,127 @@ send_pdf14trans(gs_gstate * pgs, gx_device * dev, * device. */ -#define pdf14_clist_procs(get_color_mapping_procs, get_color_comp_index,\ - encode_color, decode_color) \ -{\ - NULL, /* open */\ - gx_forward_get_initial_matrix, /* get_initial_matrix */\ - gx_forward_sync_output, /* sync_output */\ - gx_forward_output_page, /* output_page */\ - gx_forward_close_device, /* close_device */\ - encode_color, /* rgb_map_rgb_color */\ - decode_color, /* map_color_rgb */\ - gx_forward_fill_rectangle, /* fill_rectangle */\ - gx_forward_tile_rectangle, /* tile_rectangle */\ - gx_forward_copy_mono, /* copy_mono */\ - gx_forward_copy_color, /* copy_color */\ - NULL , /* draw_line - obsolete */\ - gx_forward_get_bits, /* get_bits */\ - gx_forward_get_params, /* get_params */\ - pdf14_put_params, /* put_params */\ - encode_color, /* map_cmyk_color */\ - gx_forward_get_xfont_procs, /* get_xfont_procs */\ - gx_forward_get_xfont_device, /* get_xfont_device */\ - NULL, /* map_rgb_alpha_color */\ - gx_forward_get_page_device, /* get_page_device */\ - NULL, /* get_alpha_bits */\ - gx_forward_copy_alpha, /* copy_alpha */\ - gx_forward_get_band, /* get_band */\ - gx_forward_copy_rop, /* copy_rop */\ - pdf14_clist_fill_path, /* fill_path */\ - pdf14_clist_stroke_path, /* stroke_path */\ - gx_forward_fill_mask, /* fill_mask */\ - gx_forward_fill_trapezoid, /* fill_trapezoid */\ - gx_forward_fill_parallelogram, /* fill_parallelogram */\ - gx_forward_fill_triangle, /* fill_triangle */\ - gx_forward_draw_thin_line, /* draw_thin_line */\ - pdf14_clist_begin_image, /* begin_image */\ - gx_forward_image_data, /* image_data */\ - gx_forward_end_image, /* end_image */\ - gx_forward_strip_tile_rectangle, /* strip_tile_rectangle */\ - gx_forward_strip_copy_rop, /* strip_copy_rop, */\ - gx_forward_get_clipping_box, /* get_clipping_box */\ - pdf14_clist_begin_typed_image, /* begin_typed_image */\ - gx_forward_get_bits_rectangle, /* get_bits_rectangle */\ - NULL, /* map_color_rgb_alpha */\ - pdf14_clist_create_compositor, /* create_compositor */\ - gx_forward_get_hardware_params, /* get_hardware_params */\ - pdf14_clist_text_begin, /* text_begin */\ - NULL, /* finish_copydevice */\ - pdf14_begin_transparency_group,\ - pdf14_end_transparency_group,\ - pdf14_begin_transparency_mask,\ - pdf14_end_transparency_mask,\ - gx_default_discard_transparency_layer, /* discard_transparency_layer */\ - get_color_mapping_procs, /* get_color_mapping_procs */\ - get_color_comp_index, /* get_color_comp_index */\ - encode_color, /* encode_color */\ - decode_color, /* decode_color */\ - NULL, /* pattern_manage */\ - gx_forward_fill_rectangle_hl_color, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - gx_forward_update_spot_equivalent_colors, /* update spot */\ - gx_forward_ret_devn_params, /* gx_forward_ret_devn_params */\ - gx_forward_fillpage,\ - pdf14_push_transparency_state,\ - pdf14_pop_transparency_state,\ - NULL, /* put_image */\ - pdf14_dev_spec_op,\ - pdf14_clist_copy_planes, /* copy planes */\ - NULL, /* get_profile */\ - gx_forward_set_graphics_type_tag, /* set_graphics_type_tag */\ - NULL, /* strip_copy_rop2 */\ - NULL, /* strip_tile_rect_devn */\ - gx_forward_copy_alpha_hl_color,\ - NULL, /* process_page */\ - NULL, /* transform_pixel_region */\ - pdf14_clist_fill_stroke_path,\ -} - -static dev_proc_create_compositor(pdf14_clist_create_compositor); -static dev_proc_create_compositor(pdf14_clist_forward_create_compositor); +static dev_proc_composite(pdf14_clist_composite); +static dev_proc_composite(pdf14_clist_forward_composite); static dev_proc_fill_path(pdf14_clist_fill_path); static dev_proc_stroke_path(pdf14_clist_stroke_path); static dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path); static dev_proc_text_begin(pdf14_clist_text_begin); -static dev_proc_begin_image(pdf14_clist_begin_image); static dev_proc_begin_typed_image(pdf14_clist_begin_typed_image); static dev_proc_copy_planes(pdf14_clist_copy_planes); -static const gx_device_procs pdf14_clist_Gray_procs = - pdf14_clist_procs(gx_default_DevGray_get_color_mapping_procs, - gx_default_DevGray_get_color_comp_index, - pdf14_encode_color, - pdf14_decode_color); - -static const gx_device_procs pdf14_clist_RGB_procs = - pdf14_clist_procs(gx_default_DevRGB_get_color_mapping_procs, - gx_default_DevRGB_get_color_comp_index, - pdf14_encode_color, - pdf14_decode_color); - -static const gx_device_procs pdf14_clist_CMYK_procs = - pdf14_clist_procs(gx_default_DevCMYK_get_color_mapping_procs, - gx_default_DevCMYK_get_color_comp_index, - pdf14_encode_color, pdf14_decode_color); - -static const gx_device_procs pdf14_clist_CMYKspot_procs = - pdf14_clist_procs(pdf14_cmykspot_get_color_mapping_procs, - pdf14_cmykspot_get_color_comp_index, - pdf14_encode_color, - pdf14_decode_color); +static void +pdf14_clist_init_procs(gx_device *dev, + dev_proc_get_color_mapping_procs(get_color_mapping_procs), + dev_proc_get_color_comp_index(get_color_comp_index)) +{ + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, sync_output, gx_forward_sync_output); + set_dev_proc(dev, output_page, gx_forward_output_page); + set_dev_proc(dev, close_device, gx_forward_close_device); + set_dev_proc(dev, map_rgb_color, pdf14_encode_color); + set_dev_proc(dev, map_color_rgb, pdf14_decode_color); + set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle); + set_dev_proc(dev, copy_mono, gx_forward_copy_mono); + set_dev_proc(dev, copy_color, gx_forward_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, pdf14_put_params); + set_dev_proc(dev, map_cmyk_color, pdf14_encode_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha); + set_dev_proc(dev, fill_path, pdf14_clist_fill_path); + set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path); + set_dev_proc(dev, fill_mask, gx_forward_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle); + set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2); + set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); + set_dev_proc(dev, composite, pdf14_clist_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, text_begin, pdf14_clist_text_begin); + set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group); + set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group); + set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask); + set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask); + set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer); + set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, get_color_comp_index); + set_dev_proc(dev, encode_color, pdf14_encode_color); + set_dev_proc(dev, decode_color, pdf14_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state); + set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state); + set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op); + set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes); + set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color); + set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path); +} + +static void +pdf14_clist_Gray_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + gx_default_DevGray_get_color_mapping_procs, + gx_default_DevGray_get_color_comp_index); +} + +static void +pdf14_clist_RGB_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + gx_default_DevRGB_get_color_mapping_procs, + gx_default_DevRGB_get_color_comp_index); +} + +static void +pdf14_clist_CMYK_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + gx_default_DevCMYK_get_color_mapping_procs, + gx_default_DevCMYK_get_color_comp_index); +} + +static void +pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + pdf14_cmykspot_get_color_mapping_procs, + pdf14_cmykspot_get_color_comp_index); +} #if 0 /* NOT USED */ -static const gx_device_procs pdf14_clist_RGBspot_procs = - pdf14_clist_procs(pdf14_rgbspot_get_color_mapping_procs, - pdf14_rgbspot_get_color_comp_index, - pdf14_encode_color, - pdf14_decode_color); - -static const gx_device_procs pdf14_clist_Grayspot_procs = - pdf14_clist_procs(pdf14_grayspot_get_color_mapping_procs, - pdf14_grayspot_get_color_comp_index, - pdf14_encode_color, - pdf14_decode_color); +static void +pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + pdf14_rgbspot_get_color_mapping_procs, + pdf14_rgbspot_get_color_comp_index); +} + +static int +pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev) +{ + pdf14_clist_init_procs(dev, + pdf14_grayspot_get_color_mapping_procs, + pdf14_grayspot_get_color_comp_index); +} #endif /* NOT USED */ const pdf14_clist_device pdf14_clist_Gray_device = { - std_device_color_stype_body(pdf14_clist_device, &pdf14_clist_Gray_procs, - "pdf14clistgray", &st_pdf14_device, - XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256), + std_device_color_stype_body(pdf14_clist_device, + pdf14_clist_Gray_initialize_device_procs, + "pdf14clistgray", + &st_pdf14_device, + XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256), { 0 }, /* Procs */ NULL, /* target */ { 0 }, /* devn_params - not used */ @@ -9690,9 +9722,11 @@ const pdf14_clist_device pdf14_clist_Gray_device = { }; const pdf14_clist_device pdf14_clist_RGB_device = { - std_device_color_stype_body(pdf14_clist_device, &pdf14_clist_RGB_procs, - "pdf14clistRGB", &st_pdf14_device, - XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256), + std_device_color_stype_body(pdf14_clist_device, + pdf14_clist_RGB_initialize_device_procs, + "pdf14clistRGB", + &st_pdf14_device, + XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256), { 0 }, /* Procs */ NULL, /* target */ { 0 }, /* devn_params - not used */ @@ -9702,9 +9736,11 @@ const pdf14_clist_device pdf14_clist_RGB_device = { const pdf14_clist_device pdf14_clist_CMYK_device = { std_device_std_color_full_body_type(pdf14_clist_device, - &pdf14_clist_CMYK_procs, "pdf14clistcmyk", - &st_pdf14_device, XSIZE, YSIZE, X_DPI, Y_DPI, 32, - 0, 0, 0, 0, 0, 0), + pdf14_clist_CMYK_initialize_device_procs, + "pdf14clistcmyk", + &st_pdf14_device, + XSIZE, YSIZE, X_DPI, Y_DPI, 32, + 0, 0, 0, 0, 0, 0), { 0 }, /* Procs */ NULL, /* target */ { 0 }, /* devn_params - not used */ @@ -9713,7 +9749,11 @@ const pdf14_clist_device pdf14_clist_CMYK_device = { }; const pdf14_clist_device pdf14_clist_CMYKspot_device = { - std_device_part1_(pdf14_device, &pdf14_clist_CMYKspot_procs, "pdf14clistcmykspot", &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_clist_CMYKspot_initialize_device_procs, + "pdf14clistcmykspot", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -9735,7 +9775,11 @@ const pdf14_clist_device pdf14_clist_CMYKspot_device = { }; const pdf14_clist_device pdf14_clist_custom_device = { - std_device_part1_(pdf14_device, &pdf14_clist_CMYKspot_procs, "pdf14clistcustom", &st_pdf14_device, open_init_closed), + std_device_part1_(pdf14_device, + pdf14_clist_CMYKspot_initialize_device_procs, + "pdf14clistcustom", + &st_pdf14_device, + open_init_closed), dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), offset_margin_values(0, 0, 0, 0, 0, 0), @@ -9763,9 +9807,11 @@ const pdf14_clist_device pdf14_clist_custom_device = { * currently only using a color space based upon the device. */ static int -get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, - pdf14_clist_device * ptempdevproto, gs_gstate * pgs, - const gs_pdf14trans_t * pdf14pct, bool use_pdf14_accum) +get_pdf14_clist_device_proto(gx_device *dev, + pdf14_clist_device *pdevproto, + gs_gstate *pgs, + const gs_pdf14trans_t *pdf14pct, + bool use_pdf14_accum) { bool using_blend_cs; pdf14_default_colorspace_t dev_cs = @@ -9787,7 +9833,6 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, switch (dev_cs) { case PDF14_DeviceGray: - *pdevproto = (pdf14_clist_device *)&pdf14_clist_Gray_device; /* We want gray to be single channel. Low level initialization of gray device prototype is peculiar in that in dci_std_color_num_components @@ -9796,70 +9841,67 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, Here we want monochrome anytime we have a gray device. To avoid breaking things elsewhere, we will overide the prototype intialization here */ - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.max_components = 1; - ptempdevproto->color_info.num_components = - ptempdevproto->color_info.max_components; - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.gray_index = 0; /* Avoid halftoning */ - ptempdevproto->color_info.dither_grays = ptempdevproto->color_info.max_gray+1; - ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; - ptempdevproto->color_info.depth = deep ? 16 : 8; - ptempdevproto->sep_device = false; - *pdevproto = ptempdevproto; + *pdevproto = pdf14_clist_Gray_device; + pdevproto->color_info.max_components = 1; + pdevproto->color_info.num_components = + pdevproto->color_info.max_components; + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.gray_index = 0; /* Avoid halftoning */ + pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1; + pdevproto->color_info.anti_alias = dev->color_info.anti_alias; + pdevproto->color_info.depth = deep ? 16 : 8; + pdevproto->sep_device = false; break; case PDF14_DeviceRGB: - *pdevproto = (pdf14_clist_device *)&pdf14_clist_RGB_device; - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; - ptempdevproto->sep_device = false; + *pdevproto = pdf14_clist_RGB_device; + pdevproto->color_info.anti_alias = dev->color_info.anti_alias; + pdevproto->sep_device = false; if (deep) { - ptempdevproto->color_info.depth = 3*16; - ptempdevproto->color_info.max_color = 65535; - ptempdevproto->color_info.max_gray = 65535; - ptempdevproto->color_info.dither_colors = 65536; - ptempdevproto->color_info.dither_grays = 65536; + pdevproto->color_info.depth = 3*16; + pdevproto->color_info.max_color = 65535; + pdevproto->color_info.max_gray = 65535; + pdevproto->color_info.dither_colors = 65536; + pdevproto->color_info.dither_grays = 65536; } - *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYK: - *pdevproto = (pdf14_clist_device *)&pdf14_clist_CMYK_device; - *ptempdevproto = **pdevproto; - ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; - ptempdevproto->sep_device = false; + *pdevproto = pdf14_clist_CMYK_device; + pdevproto->color_info.anti_alias = dev->color_info.anti_alias; + pdevproto->sep_device = false; if (deep) { - ptempdevproto->color_info.depth = 4*16; - ptempdevproto->color_info.max_color = 65535; - ptempdevproto->color_info.max_gray = 65535; - ptempdevproto->color_info.dither_colors = 65536; - ptempdevproto->color_info.dither_grays = 65536; + pdevproto->color_info.depth = 4*16; + pdevproto->color_info.max_color = 65535; + pdevproto->color_info.max_gray = 65535; + pdevproto->color_info.dither_colors = 65536; + pdevproto->color_info.dither_grays = 65536; } - *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYKspot: - *pdevproto = (pdf14_clist_device *)&pdf14_clist_CMYKspot_device; - *ptempdevproto = **pdevproto; + *pdevproto = pdf14_clist_CMYKspot_device; /* * The number of components for the PDF14 device is the sum * of the process components and the number of spot colors - * for the page. + * for the page. If we are using an NCLR ICC profile at + * the output device, those spot colors are skipped. They + * do not appear in the transparency buffer, but appear + * during put image transform of the page group to the target + * color space. */ if (num_spots >= 0) { - ptempdevproto->devn_params.page_spot_colors = num_spots; - ptempdevproto->color_info.num_components = - ptempdevproto->devn_params.num_std_colorant_names + num_spots; - if (ptempdevproto->color_info.num_components > - ptempdevproto->color_info.max_components) - ptempdevproto->color_info.num_components = - ptempdevproto->color_info.max_components; - ptempdevproto->color_info.depth = - ptempdevproto->color_info.num_components * (8<<deep); + pdevproto->devn_params.page_spot_colors = num_spots; + pdevproto->color_info.num_components = + pdevproto->devn_params.num_std_colorant_names + num_spots; + if (pdevproto->color_info.num_components > + pdevproto->color_info.max_components) + pdevproto->color_info.num_components = + pdevproto->color_info.max_components; + pdevproto->color_info.depth = + pdevproto->color_info.num_components * (8<<deep); if (deep && has_tags) - ptempdevproto->color_info.depth -= 8; + pdevproto->color_info.depth -= 8; } - ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; - ptempdevproto->sep_device = true; - *pdevproto = ptempdevproto; + pdevproto->color_info.anti_alias = dev->color_info.anti_alias; + pdevproto->sep_device = true; break; case PDF14_DeviceCustom: /* @@ -9867,23 +9909,22 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, * color_info for the PDF 1.4 compositing device needs to match * the output device. */ - *ptempdevproto = pdf14_clist_custom_device; - ptempdevproto->color_info = dev->color_info; + *pdevproto = pdf14_clist_custom_device; + pdevproto->color_info = dev->color_info; /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */ - ptempdevproto->color_info.depth = - ptempdevproto->color_info.num_components * (8<<deep); - ptempdevproto->color_info.max_gray = deep ? 65535 : 255; - ptempdevproto->color_info.max_color = deep ? 65535 : 255; - ptempdevproto->color_info.dither_grays = deep ? 65536 : 256; - ptempdevproto->color_info.dither_colors = deep ? 65536 : 256; - ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; - *pdevproto = ptempdevproto; + pdevproto->color_info.depth = + pdevproto->color_info.num_components * (8<<deep); + pdevproto->color_info.max_gray = deep ? 65535 : 255; + pdevproto->color_info.max_color = deep ? 65535 : 255; + pdevproto->color_info.dither_grays = deep ? 65536 : 256; + pdevproto->color_info.dither_colors = deep ? 65536 : 256; + pdevproto->color_info.anti_alias = dev->color_info.anti_alias; break; default: /* Should not occur */ return_error(gs_error_rangecheck); } - ptempdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; - ptempdevproto->using_blend_cs = using_blend_cs; + pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push; + pdevproto->using_blend_cs = using_blend_cs; return 0; } @@ -9892,8 +9933,8 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, gx_device ** ppdev, gx_device * target, const gs_pdf14trans_t * pdf14pct) { - pdf14_clist_device * dev_proto; - pdf14_clist_device * pdev, temp_dev_proto; + pdf14_clist_device dev_proto; + pdf14_clist_device * pdev; int code; bool has_tags = device_encodes_tags(target); cmm_profile_t *target_profile; @@ -9911,11 +9952,11 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, &render_cond); if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n"); code = get_pdf14_clist_device_proto(target, &dev_proto, - &temp_dev_proto, pgs, pdf14pct, false); + pgs, pdf14pct, false); if (code < 0) return code; code = gs_copydevice((gx_device **) &pdev, - (const gx_device *) dev_proto, mem); + (const gx_device *) &dev_proto, mem); if (code < 0) return code; @@ -9936,7 +9977,7 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, else pdev->is_planar = target->is_planar; - pdev->op_state = pgs->is_fill_color; + pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE; if (deep) { set_dev_proc(pdev, encode_color, pdf14_encode_color16); @@ -9973,8 +10014,12 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, &render_cond); if_debug0m('v', mem, "[v]pdf14_create_clist_device\n"); - /* Simulated overprint case. We have to use CMYK-based profile */ - if (pdev->overprint_sim && icc_profile->data_cs != gsCMYK) { + /* Simulated overprint case. We have to use CMYK-based profile + Also if the target profile is NCLR, we are going to use a pdf14 + device that is CMYK based and do the mapping to the NCLR profile + when the put_image occurs */ + if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) || + icc_profile->data_cs == gsNCHANNEL) { gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device"); gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_create_clist_device"); @@ -10026,12 +10071,12 @@ pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs, /* * To disable the action of this device, we forward all device - * procedures to the target except the create_compositor and copy + * procedures to the target except the composite and copy * the target's color_info. */ dev->color_info = target->color_info; pdf14_forward_device_procs(dev); - set_dev_proc(dev, create_compositor, pdf14_clist_forward_create_compositor); + set_dev_proc(dev, composite, pdf14_clist_forward_composite); return 0; } @@ -10048,8 +10093,7 @@ pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs, { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; gx_device * target = pdev->target; - pdf14_clist_device * dev_proto; - pdf14_clist_device temp_dev_proto; + pdf14_clist_device dev_proto; int code; if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n"); @@ -10058,12 +10102,11 @@ pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs, * color related info to match the prototype. */ code = get_pdf14_clist_device_proto(target, &dev_proto, - &temp_dev_proto, pgs, pdf14pct, false); + pgs, pdf14pct, false); if (code < 0) return code; - pdev->color_info = dev_proto->color_info; - pdev->procs = dev_proto->procs; - pdev->static_procs = dev_proto->static_procs; + pdev->color_info = dev_proto.color_info; + pdev->procs = dev_proto.procs; pdev->pad = target->pad; pdev->log2_align_mod = target->log2_align_mod; @@ -10126,7 +10169,7 @@ pdf14_accum_get_color_comp_index(gx_device * dev, * the separation color components for the pdf14_accum device. */ static void -pdf14_accum_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) +pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[]) { int * map = (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map); @@ -10135,7 +10178,7 @@ pdf14_accum_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) } static void -pdf14_accum_rgb_cs_to_cmyk_cm(gx_device * dev, +pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { int * map = @@ -10145,7 +10188,7 @@ pdf14_accum_rgb_cs_to_cmyk_cm(gx_device * dev, } static void -pdf14_accum_cmyk_cs_to_cmyk_cm(gx_device * dev, +pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { const int * map = @@ -10161,8 +10204,9 @@ static const gx_cm_color_map_procs pdf14_accum_cm_procs = { }; static const gx_cm_color_map_procs * -pdf14_accum_get_color_mapping_procs(const gx_device * dev) +pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev) { + *map_dev = dev; return &pdf14_accum_cm_procs; } @@ -10276,7 +10320,7 @@ pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params, * exists. */ static int -pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, +pdf14_clist_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { @@ -10323,7 +10367,7 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, gs_pdf14trans_t pctemp = *pdf14pct; pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type; - code = dev_proc(pdev->target, create_compositor) + code = dev_proc(pdev->target, composite) (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev); /* We should never have created a new device here. */ assert(code != 1); @@ -10366,6 +10410,7 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, pdf14_decrement_smask_color(pgs, dev); /* Restore the color_info for the clist device */ clistdev->color_info = pdev->saved_target_color_info; + ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */ set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color); set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color); set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs); @@ -10499,7 +10544,7 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, break; /* Pass remaining ops to target */ } } - code = dev_proc(pdev->target, create_compositor) + code = dev_proc(pdev->target, composite) (pdev->target, pcdev, pct, pgs, mem, cdev); /* If we were accumulating into a pdf14-clist-accum device, */ /* we now have to render the page into it's target device */ @@ -10521,6 +10566,7 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, bool save_planar = pdev->is_planar; gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target); int save_num_separations; + gs_int_rect rect; pdev->is_planar = false; /* so gx_device_raster is for entire chunky pixel line */ linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev"); @@ -10550,7 +10596,7 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &(pcs->cmm_icc_profile_data), &render_cond); /* pcs takes a reference to the profile data it just retrieved. */ - gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_create_compositor"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite"); gsicc_set_icc_range(&(pcs->cmm_icc_profile_data)); } else { /* DeviceN case -- need to handle spot colors */ @@ -10602,10 +10648,26 @@ pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, pgs->memory, &info); if (code < 0) goto put_accum_error; + rect.p.x = 0; + rect.q.x = tdev->width; for (y=0; y < tdev->height; y++) { - code = dev_proc(tdev, get_bits)((gx_device *)tdev, y, linebuf, &actual_data); + gs_get_bits_params_t params; + + params.options = (GB_ALIGN_ANY | + (GB_RETURN_COPY | GB_RETURN_POINTER) | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.x_offset = 0; + params.raster = bitmap_raster(dev->width * dev->color_info.depth); + params.data[0] = linebuf; + rect.p.y = y; + rect.q.y = y+1; + code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev, + &rect, ¶ms); if (code < 0) goto put_accum_error; + actual_data = params.data[0]; planes.data = actual_data; planes.data_x = 0; planes.raster = tdev->width * tdev->color_info.num_components; @@ -10654,7 +10716,7 @@ put_accum_error: * to the targer. */ static int -pdf14_clist_forward_create_compositor(gx_device * dev, gx_device * * pcdev, +pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev, const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { @@ -10668,10 +10730,10 @@ pdf14_clist_forward_create_compositor(gx_device * dev, gx_device * * pcdev, const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE) - return pdf14_clist_create_compositor(dev, &ndev, pct, pgs, mem, cdev); + return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev); return 0; } - code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pgs, mem, cdev); + code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev); if (code == 1) { /* We just wrapped tdev, so update our target. */ gx_device_set_target((gx_device_forward *)pdev, ndev); @@ -10747,7 +10809,7 @@ pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs, if (changed != 0) { code = gs_create_pdf14trans(&pct_new, ¶ms, pgs->memory); if (code < 0) return code; - code = dev_proc(pdev->target, create_compositor) + code = dev_proc(pdev->target, composite) (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL); gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params"); } @@ -11198,8 +11260,7 @@ pdf14_clist_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppat static int pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, - gx_path * path, const gx_device_color * pdcolor, - const gx_clip_path * pcpath, gs_memory_t * memory, + const gx_clip_path * pcpath, gs_text_enum_t ** ppenum) { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; @@ -11214,7 +11275,7 @@ pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs, bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6); bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6); - if_debug0m('v', memory, "[v]pdf14_clist_text_begin\n"); + if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n"); /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines @@ -11225,8 +11286,8 @@ pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs, if (code < 0) return code; /* Pass text_begin to the target */ - code = gx_forward_text_begin(dev, pgs, text, font, path, - pdcolor, pcpath, memory, &penum); + code = gx_forward_text_begin(dev, pgs, text, font, + pcpath, &penum); if (code < 0) return code; @@ -11267,36 +11328,6 @@ pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs, } static int -pdf14_clist_begin_image(gx_device * dev, - const gs_gstate * pgs, const gs_image_t * pim, - gs_image_format_t format, const gs_int_rect * prect, - const gx_drawing_color * pdcolor, - const gx_clip_path * pcpath, - gs_memory_t * memory, gx_image_enum_common_t ** pinfo) -{ - pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - int code; - - /* - * Ensure that that the PDF 1.4 reading compositor will have the current - * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the gs_gstate. Thus we have to pass any - * changes explictly. - */ - code = pdf14_clist_update_params(pdev, pgs, false, NULL); - if (code < 0) - return code; - /* Pass image to the target */ - code = gx_forward_begin_image(dev, pgs, pim, format, prect, - pdcolor, pcpath, memory, pinfo); - if (code < 0) - return gx_default_begin_image(dev, pgs, pim, format, prect, - pdcolor, pcpath, memory, pinfo); - else return code; - -} - -static int pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect * prect, @@ -11335,7 +11366,7 @@ pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, if (pim->ImageMask) { if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) { if( gx_pattern1_get_transptr(pdcolor) != NULL){ - if (dev_proc(dev, begin_image) != pdf14_clist_begin_image) { + if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) { ptile = pdcolor->colors.pattern.p_tile; /* Set up things in the ptile so that we get the proper blending etc */ @@ -11439,7 +11470,7 @@ gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev, /* * Set the color_info of the clist device to match the compositing * device. We will restore it when the compositor is popped. - * See pdf14_clist_create_compositor for the restore. Do the + * See pdf14_clist_composite for the restore. Do the * same with the gs_gstate's get_cmap_procs. We do not want * the gs_gstate to use transfer functions on our color values. * The transfer functions will be applied at the end after we @@ -11505,17 +11536,6 @@ c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev, return code; case PDF14_POP_DEVICE: -# if 0 /* Disabled because pdf14_clist_create_compositor does so. */ - /* - * Ensure that the tranfer functions, etc. are current before we - * dump our transparency image to the output device. - */ - if (pgs->dev_ht) - code = cmd_put_halftone((gx_device_clist_writer *) - (((pdf14_clist_device *)dev)->target), pgs->dev_ht); -# else - code = 0; -# endif code = clist_writer_check_empty_cropping_stack(cdev); break; @@ -11584,7 +11604,7 @@ c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev, if (code < 0) return code; /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and - apply_create_compositor. */ + apply_composite. */ code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm); /* Wrote an extra ctm. */ cmd_clear_known(cdev, ctm_known); @@ -11630,14 +11650,16 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev, * device. */ switch (pdf14pct->params.pdf14_op) { - case PDF14_PUSH_DEVICE: - /* Overprint simulation sets the profile at prototype creation. */ - if (!p14dev->overprint_sim) { - gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update"); - gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], - -1, "c_pdf14trans_clist_read_update"); - p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile; - } + case PDF14_PUSH_DEVICE: + /* Overprint simulation sets the profile at prototype creation, as does + when the target profile is NCLR. Match the logic in gs_pdf14_device_push */ + if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) || + cl_icc_profile->data_cs == gsNCHANNEL)) { + gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update"); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], + -1, "c_pdf14trans_clist_read_update"); + p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile; + } /* * If we are blending using spot colors (i.e. the output device * supports spot colors) then we need to transfer @@ -11853,7 +11875,7 @@ pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname, target_get_color_comp_index = dev_proc(tdev, get_color_comp_index); - /* The pdf14_clist_create_compositor may have set the color procs. + /* The pdf14_clist_composite may have set the color procs. We need the real target procs, but not if we are doing simulated overprint */ if (target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index && @@ -12189,8 +12211,8 @@ dump_mask_stack(pdf14_mask_t *mask_stack) while (curr_mask != NULL) { if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level); - if_debug1m('v', curr_mask->memory, "[v]mask_buf, %x\n", curr_mask->rc_mask->mask_buf); - if_debug1m('v', curr_mask->memory, "[v]rc_count, %d\n", curr_mask->rc_mask->rc); + if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf); + if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count); level++; curr_mask = curr_mask->previous; } @@ -12200,13 +12222,13 @@ dump_mask_stack(pdf14_mask_t *mask_stack) static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx) { - if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %x\n", ctx->mask_stack); + if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack); if (ctx->mask_stack != NULL) { dump_mask_stack(ctx->mask_stack); } - if_debug1m('v', ctx->memory, "[v]ctx_stack, %x\n", ctx->stack); + if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack); if (ctx->stack != NULL) { - if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %x\n", ctx->stack->mask_stack); + if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack); if (ctx->stack->mask_stack != NULL) { dump_mask_stack(ctx->stack->mask_stack); } diff --git a/base/gdevp14.h b/base/gdevp14.h index 44f0b8a5..434f594f 100644 --- a/base/gdevp14.h +++ b/base/gdevp14.h @@ -116,7 +116,7 @@ struct pdf14_group_color_s { uint max_color; /* Causes issues if these are not maintained */ const gx_color_map_procs *(*get_cmap_procs)(const gs_gstate *, const gx_device *); - const gx_cm_color_map_procs *(*group_color_mapping_procs)(const gx_device *); + const gx_cm_color_map_procs *(*group_color_mapping_procs)(const gx_device *, const gx_device **); gx_color_index (*encode)(gx_device *, const gx_color_value value[]); int (*decode)(gx_device *, gx_color_index, gx_color_value *); int (*group_color_comp_index)(gx_device *, const char *, int, int); diff --git a/base/gdevpipe.c b/base/gdevpipe.c index 96d71f5d..5bdc485b 100644 --- a/base/gdevpipe.c +++ b/base/gdevpipe.c @@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access, #else gs_lib_ctx_t *ctx = mem->gs_lib_ctx; gs_fs_list_t *fs = ctx->core->fs; + /* The pipe device can be reached in two ways, explicltly with %pipe% + or implicitly with "|", so we have to check for both + */ + char f[gp_file_name_sizeof]; + const char *pipestr = "|"; + const size_t pipestrlen = strlen(pipestr); + const size_t preflen = strlen(iodev->dname); + const size_t nlen = strlen(fname); + int code1; + + if (preflen + nlen >= gp_file_name_sizeof) + return_error(gs_error_invalidaccess); + + memcpy(f, iodev->dname, preflen); + memcpy(f + preflen, fname, nlen + 1); + + code1 = gp_validate_path(mem, f, access); + + memcpy(f, pipestr, pipestrlen); + memcpy(f + pipestrlen, fname, nlen + 1); - if (gp_validate_path(mem, fname, access) != 0) + if (code1 != 0 && gp_validate_path(mem, f, access) != 0 ) return gs_error_invalidfileaccess; /* diff --git a/base/gdevplnx.c b/base/gdevplnx.c index e60b7565..60a84139 100644 --- a/base/gdevplnx.c +++ b/base/gdevplnx.c @@ -64,88 +64,53 @@ static dev_proc_fill_mask(plane_fill_mask); static dev_proc_fill_parallelogram(plane_fill_parallelogram); static dev_proc_fill_triangle(plane_fill_triangle); static dev_proc_strip_tile_rectangle(plane_strip_tile_rectangle); -static dev_proc_strip_copy_rop(plane_strip_copy_rop); +static dev_proc_strip_copy_rop2(plane_strip_copy_rop2); static dev_proc_begin_typed_image(plane_begin_typed_image); static dev_proc_get_bits_rectangle(plane_get_bits_rectangle); /* Device prototype */ +static void +plane_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, plane_open_device); + set_dev_proc(dev, fill_rectangle, plane_fill_rectangle); + set_dev_proc(dev, copy_mono, plane_copy_mono); + set_dev_proc(dev, copy_color, plane_copy_color); + set_dev_proc(dev, copy_alpha, plane_copy_alpha); + set_dev_proc(dev, fill_path, plane_fill_path); + set_dev_proc(dev, stroke_path, plane_stroke_path); + set_dev_proc(dev, fill_mask, plane_fill_mask); + set_dev_proc(dev, fill_parallelogram, plane_fill_parallelogram); + set_dev_proc(dev, fill_triangle, plane_fill_triangle); + set_dev_proc(dev, strip_tile_rectangle, plane_strip_tile_rectangle); + set_dev_proc(dev, strip_copy_rop2, plane_strip_copy_rop2); + set_dev_proc(dev, begin_typed_image, plane_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, plane_get_bits_rectangle); + set_dev_proc(dev, composite, gx_no_composite); /* WRONG */ + + /* Ideally the following would be initialized to the defaults + * automatically, but this does not currently work. */ + set_dev_proc(dev, close_device, gx_default_close_device); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, text_begin, gx_default_text_begin); + set_dev_proc(dev, fill_rectangle_hl_color, gx_default_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, gx_default_include_color_space); + set_dev_proc(dev, fill_linear_color_scanline, gx_default_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, gx_default_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, gx_default_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, gx_default_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_default_ret_devn_params); + set_dev_proc(dev, fillpage, gx_default_fillpage); + set_dev_proc(dev, strip_tile_rect_devn, gx_default_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, gx_default_copy_alpha_hl_color); +} + static const gx_device_plane_extract gs_plane_extract_device = { - std_device_std_body(gx_device_plane_extract, 0, "plane_extract", + std_device_std_body(gx_device_plane_extract, + plane_initialize_device_procs, "plane_extract", 0, 0, 72, 72), - { - plane_open_device, - NULL, - NULL, - NULL, - gx_default_close_device, - NULL, - NULL, - plane_fill_rectangle, - gx_default_tile_rectangle, - plane_copy_mono, - plane_copy_color, - gx_default_draw_line, - gx_default_get_bits, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - plane_copy_alpha, - NULL, - gx_default_copy_rop, - plane_fill_path, - plane_stroke_path, - plane_fill_mask, - gx_default_fill_trapezoid, - plane_fill_parallelogram, - plane_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - plane_strip_tile_rectangle, - plane_strip_copy_rop, - NULL, - plane_begin_typed_image, - plane_get_bits_rectangle, - NULL, - gx_no_create_compositor, /* WRONG */ - NULL, - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* deprecated and never implemented transparency procs */ - NULL, /* | */ - NULL, /* | */ - NULL, /* | */ - NULL, /* V */ - NULL, /* DeviceN support color mapping procs */ - NULL, /* | */ - NULL, /* | */ - NULL, /* | */ - NULL, /* pattern_manage */ - gx_default_fill_rectangle_hl_color, - gx_default_include_color_space, - gx_default_fill_linear_color_scanline, - gx_default_fill_linear_color_trapezoid, - gx_default_fill_linear_color_triangle, - gx_default_update_spot_equivalent_colors, - gx_default_ret_devn_params, - gx_default_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - NULL, /* dev_spec_op */ - NULL, /* copy_planes */ - NULL, /* get_profile */ - NULL, /* set_graphics_type_tag */ - gx_default_strip_copy_rop2, - gx_default_strip_tile_rect_devn, - gx_default_copy_alpha_hl_color - }, + { 0 }, /* device-specific members */ NULL, /* target */ NULL, /* plane_dev */ @@ -220,9 +185,7 @@ reduce_drawing_color(gx_device_color *ppdc, gx_device_plane_extract *edev, gx_devn_reduce_colored_halftone(ppdc, (gx_device *)edev); ppdc->colors.pure = COLOR_PIXEL(edev, ppdc->colors.pure); reduced = REDUCE_PURE(edev, gx_dc_pure_color(ppdc)); - } else if (ppdc->colors.colored.alpha != gx_max_color_value) - return REDUCE_FAILED; /* can't reduce */ - else { + } else { gx_devn_reduce_colored_halftone(ppdc, (gx_device *)edev); ppdc->colors.binary.color[0] = COLOR_PIXEL(edev, ppdc->colors.binary.color[0]); @@ -418,12 +381,15 @@ int plane_device_init(gx_device_plane_extract *edev, gx_device *target, gx_device *plane_dev, const gx_render_plane_t *render_plane, bool clear) { + int code; /* Check for compatibility of the plane specification. */ if (render_plane->depth > plane_dev->color_info.depth) return_error(gs_error_rangecheck); - gx_device_init((gx_device *)edev, - (const gx_device *)&gs_plane_extract_device, - edev->memory, true); + code = gx_device_init((gx_device *)edev, + (const gx_device *)&gs_plane_extract_device, + edev->memory, true); + if (code < 0) + return code; check_device_separable((gx_device *)edev); gx_device_forward_fill_in_procs((gx_device_forward *)edev); gx_device_set_target((gx_device_forward *)edev, target); @@ -449,13 +415,13 @@ plane_open_device(gx_device *dev) gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; gx_device * const plane_dev = edev->plane_dev; int plane_depth = plane_dev->color_info.depth; - const gx_device_memory * const mdproto = - gdev_mem_device_for_bits(plane_depth); + const gdev_mem_functions *fns = + gdev_mem_functions_for_bits(plane_depth); edev->plane_white = gx_device_white(plane_dev); edev->plane_mask = (1 << plane_depth) - 1; - edev->plane_dev_is_memory = mdproto != 0 && - dev_proc(plane_dev, copy_color) == dev_proc(mdproto, copy_color); + edev->plane_dev_is_memory = fns != NULL && + dev_proc(plane_dev, copy_color) == fns->copy_color; /* We don't set or clear any_marks here: see ...init above. */ return 0; } @@ -744,12 +710,13 @@ plane_strip_tile_rectangle(gx_device *dev, } static int -plane_strip_copy_rop(gx_device *dev, +plane_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, int x, int y, int w, int h, - int phase_x, int phase_y, gs_logical_operation_t lop) + int phase_x, int phase_y, gs_logical_operation_t lop, + uint plane_height) { gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; gx_device * const plane_dev = edev->plane_dev; @@ -795,9 +762,10 @@ plane_strip_copy_rop(gx_device *dev, code = begin_tiling(&source.state, edev, sdata, sourcex, sraster, w, y, (byte *)sbuf, sizeof(sbuf), true); if (code < 0) - return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, - x, y, w, h, phase_x, phase_y, rop); + return gx_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id, + scolors, textures, tcolors, + x, y, w, h, phase_x, phase_y, rop, + plane_height); plane_source = source.state.buffer.data; plane_raster = source.state.buffer.raster; } else @@ -822,10 +790,10 @@ plane_strip_copy_rop(gx_device *dev, do { if (sdata) extract_partial_tile(&source.state); - code = dev_proc(plane_dev, strip_copy_rop) + code = dev_proc(plane_dev, strip_copy_rop2) (plane_dev, plane_source, sourcex, plane_raster, gx_no_bitmap_id, source.colors, plane_textures, texture.colors, - x, y, w, h, phase_x, phase_y, rop); + x, y, w, h, phase_x, phase_y, rop, plane_height); } while (code >= 0 && sdata && next_tile(&source.state)); if (textures) end_tiling(&texture.state); @@ -904,21 +872,6 @@ plane_cmap_cmyk(frac c, frac m, frac y, frac k, gx_device_color * pdc, (gx_device *)edev, select, NULL); reduce_drawing_color(pdc, edev, &dcolor, &lop); } -static void -plane_cmap_rgb_alpha(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_gstate *pgs_image, gx_device *dev, gs_color_select_t select) -{ - const plane_image_enum_t *ppie = - (const plane_image_enum_t *)pgs_image->client_data; - gx_device_plane_extract * const edev = - (gx_device_plane_extract *)ppie->dev; - gs_logical_operation_t lop = gs_current_logical_op_inline(pgs_image); - gx_device_color dcolor; - - gx_remap_concrete_rgb_alpha(r, g, b, alpha, &dcolor, ppie->pgs, - (gx_device *)edev, select); - reduce_drawing_color(pdc, edev, &dcolor, &lop); -} static bool plane_cmap_is_halftoned(const gs_gstate *pgs_image, gx_device *dev) { @@ -926,7 +879,7 @@ plane_cmap_is_halftoned(const gs_gstate *pgs_image, gx_device *dev) } static const gx_color_map_procs plane_color_map_procs = { - plane_cmap_gray, plane_cmap_rgb, plane_cmap_cmyk, plane_cmap_rgb_alpha, + plane_cmap_gray, plane_cmap_rgb, plane_cmap_cmyk, NULL, NULL, plane_cmap_is_halftoned }; static const gx_color_map_procs * @@ -1048,7 +1001,7 @@ plane_image_end_image(gx_image_enum_common_t * info, bool draw_last) static int plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; gx_device * const plane_dev = edev->plane_dev; @@ -1066,11 +1019,11 @@ plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, */ if ((options & GB_PACKING_PLANAR) && (options & GB_SELECT_PLANES)) { if (params->data[plane_index] == 0) - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); /* If the caller wants any other plane(s), punt. */ for (plane = 0; plane < dev->color_info.num_components; ++plane) if (plane != plane_index && params->data[plane] != 0) - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); /* Pass the request on to the plane device. */ plane_params = *params; plane_params.options = @@ -1078,7 +1031,7 @@ plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, GB_PACKING_CHUNKY; plane_params.data[0] = params->data[plane_index]; code = dev_proc(plane_dev, get_bits_rectangle) - (plane_dev, prect, &plane_params, unread); + (plane_dev, prect, &plane_params); if (code >= 0) { *params = plane_params; params->options = (params->options & ~GB_PACKING_ALL) | @@ -1116,7 +1069,7 @@ plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, (GB_RASTER_STANDARD | GB_RASTER_ANY)); plane_params.raster = gx_device_raster(plane_dev, true); code = dev_proc(plane_dev, get_bits_rectangle) - (plane_dev, prect, &plane_params, unread); + (plane_dev, prect, &plane_params); if (code >= 0) { /* Success, expand the plane into pixels. */ source.data.read = plane_params.data[0]; @@ -1128,6 +1081,6 @@ plane_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, } params->options = (options & ~GB_RETURN_POINTER) | GB_RETURN_COPY; } else - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); return code; } diff --git a/base/gdevprn.c b/base/gdevprn.c index cb3fdf45..0cfb453f 100644 --- a/base/gdevprn.c +++ b/base/gdevprn.c @@ -53,12 +53,6 @@ public_st_device_printer(); /* ---------------- Standard device procedures ---------------- */ -/* Define the standard printer procedure vector. */ -const gx_device_procs prn_std_procs = - prn_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close); -const gx_device_procs prn_bg_procs = - prn_procs(gdev_prn_open, gdev_prn_bg_output_page, gdev_prn_close); - /* Forward references */ int gdev_prn_maybe_realloc_memory(gx_device_printer *pdev, gdev_space_params *old_space, @@ -70,6 +64,7 @@ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seeka extern dev_proc_open_device(pattern_clist_open_device); extern dev_proc_open_device(clist_open); +extern dev_proc_close_device(clist_close); /* The function run in a background thread */ static void prn_print_page_in_background(void *data); @@ -230,10 +225,11 @@ gdev_prn_tear_down(gx_device *pdev, byte **the_memory) if (PRINTER_IS_CLIST(ppdev)) { /* Close cmd list device & point to the storage */ - (*gs_clist_device_procs.close_device)( (gx_device *)pcldev ); + clist_close( (gx_device *)pcldev ); *the_memory = ppdev->buf; ppdev->buf = 0; ppdev->buffer_space = 0; + pmemdev->base = 0; /* in case finalize tries to free this */ was_command_list = true; prn_finish_bg_print(ppdev); @@ -435,8 +431,12 @@ gdev_prn_allocate(gx_device *pdev, gdev_space_params *new_space_params, if (ecode == 0) ecode = code; - if (code >= 0 || (reallocate && pass > 1)) - ppdev->procs = gs_clist_device_procs; + if (code >= 0 || (reallocate && pass > 1)) { + ppdev->initialize_device_procs = clist_initialize_device_procs; + /* Hacky - we know this can't fail. */ + (void)ppdev->initialize_device_procs((gx_device *)ppdev); + gx_device_fill_in_procs((gx_device *)ppdev); + } } else { /* Render entirely in memory. */ gx_device *bdev = (gx_device *)pmemdev; @@ -475,14 +475,10 @@ gdev_prn_allocate(gx_device *pdev, gdev_space_params *new_space_params, COPY_PROC(get_params); COPY_PROC(put_params); COPY_PROC(map_cmyk_color); - COPY_PROC(get_xfont_procs); - COPY_PROC(get_xfont_device); - COPY_PROC(map_rgb_alpha_color); /* All printers are page devices, even if they didn't use the */ /* standard macros for generating their procedure vectors. */ set_dev_proc(ppdev, get_page_device, gx_page_device_get_page_device); COPY_PROC(get_clipping_box); - COPY_PROC(map_color_rgb_alpha); COPY_PROC(get_hardware_params); COPY_PROC(get_color_mapping_procs); COPY_PROC(get_color_comp_index); @@ -1399,6 +1395,9 @@ gx_default_create_buf_device(gx_device **pbdev, gx_device *target, int y, dev_t_proc_dev_spec_op((*orig_dso), gx_device) = dev_proc(mdev, dev_spec_op); /* The following is a special hack for setting up printer devices. */ assign_dev_procs(mdev, mdproto); + mdev->initialize_device_procs = mdproto->initialize_device_procs; + mdev->initialize_device_procs((gx_device *)mdev); + /* We know mdev->procs.initialize_device is NULL! */ /* Do not override the dev_spec_op! */ dev_proc(mdev, dev_spec_op) = orig_dso; check_device_separable((gx_device *)mdev); @@ -1471,6 +1470,7 @@ gx_default_size_buf_device(gx_device_buf_space_t *space, gx_device *target, mdev.color_info.depth = (render_plane && render_plane->index >= 0 ? render_plane->depth : target->color_info.depth); + mdev.color_info.num_components = target->color_info.num_components; mdev.width = target->width; mdev.is_planar = target->is_planar; mdev.pad = target->pad; @@ -1580,7 +1580,7 @@ gdev_prn_get_lines(gx_device_printer *pdev, int y, int height, params.x_offset = 0; params.raster = bytes_per_line; code = dev_proc(pdev, get_bits_rectangle) - ((gx_device *)pdev, &rect, ¶ms, NULL); + ((gx_device *)pdev, &rect, ¶ms); if (code < 0 && actual_buffer) { /* * RETURN_POINTER might not be implemented for this @@ -1589,7 +1589,7 @@ gdev_prn_get_lines(gx_device_printer *pdev, int y, int height, params.options &= ~(GB_RETURN_POINTER | GB_RASTER_ALL); params.options |= GB_RETURN_COPY | GB_RASTER_SPECIFIED; code = dev_proc(pdev, get_bits_rectangle) - ((gx_device *)pdev, &rect, ¶ms, NULL); + ((gx_device *)pdev, &rect, ¶ms); } if (code < 0) return code; @@ -1604,14 +1604,35 @@ gdev_prn_get_lines(gx_device_printer *pdev, int y, int height, int gdev_prn_get_bits(gx_device_printer * pdev, int y, byte * str, byte ** actual_data) { - int code = (*dev_proc(pdev, get_bits)) ((gx_device *) pdev, y, str, actual_data); + int code; uint line_size = gdev_prn_raster(pdev); int last_bits = -(pdev->width * pdev->color_info.depth) & 7; + gs_int_rect rect; + gs_get_bits_params_t params; + rect.p.x = 0; + rect.p.y = y; + rect.q.x = pdev->width; + rect.q.y = y+1; + + params.options = (GB_ALIGN_ANY | + GB_RETURN_COPY | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + if (actual_data) + params.options |= GB_RETURN_POINTER; + params.x_offset = 0; + params.raster = bitmap_raster(pdev->width * pdev->color_info.depth); + params.data[0] = str; + code = (*dev_proc(pdev, get_bits_rectangle))((gx_device *)pdev, &rect, + ¶ms); if (code < 0) return code; + if (actual_data) + *actual_data = params.data[0]; if (last_bits != 0) { - byte *dest = (actual_data != 0 ? *actual_data : str); + byte *dest = (actual_data != NULL ? *actual_data : str); dest[line_size - 1] &= 0xff << last_bits; } @@ -1707,3 +1728,148 @@ dmprintf4(pdev->memory, "w=%d/%d, h=%d/%d\n", old_width, new_width, old_height, } return code; } + +void +gdev_prn_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, gdev_prn_open); + set_dev_proc(dev, close_device, gdev_prn_close); + set_dev_proc(dev, output_page, gdev_prn_output_page); + set_dev_proc(dev, get_params, gdev_prn_get_params); + set_dev_proc(dev, put_params, gdev_prn_put_params); + set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); + set_dev_proc(dev, dev_spec_op, gdev_prn_dev_spec_op); + set_dev_proc(dev, map_rgb_color, gdev_prn_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gdev_prn_map_color_rgb); + set_dev_proc(dev, encode_color, gdev_prn_map_rgb_color); + set_dev_proc(dev, decode_color, gdev_prn_map_color_rgb); +} + +void gdev_prn_initialize_device_procs_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void +gdev_prn_initialize_device_procs_mono(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, gdev_prn_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gdev_prn_map_color_rgb); + set_dev_proc(dev, encode_color, gdev_prn_map_rgb_color); + set_dev_proc(dev, decode_color, gdev_prn_map_color_rgb); +} + +void gdev_prn_initialize_device_procs_mono_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_mono(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void +gdev_prn_initialize_device_procs_gray(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb); + set_dev_proc(dev, encode_color, gx_default_gray_map_rgb_color); + set_dev_proc(dev, decode_color, gx_default_gray_map_color_rgb); +} + +void gdev_prn_initialize_device_procs_gray_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_gray(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void gdev_prn_initialize_device_procs_rgb(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb); + set_dev_proc(dev, encode_color, gx_default_rgb_map_rgb_color); + set_dev_proc(dev, decode_color, gx_default_rgb_map_color_rgb); +} + +void gdev_prn_initialize_device_procs_rgb_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_rgb(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void +gdev_prn_initialize_device_procs_gray8(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_rgb_color, gx_default_8bit_map_gray_color); + set_dev_proc(dev, map_color_rgb, gx_default_8bit_map_color_gray); + set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color); + set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray); +} + +void gdev_prn_initialize_device_procs_gray8_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_gray8(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void gdev_prn_initialize_device_procs_cmyk1(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_cmyk_color, cmyk_1bit_map_cmyk_color); + set_dev_proc(dev, map_color_rgb, cmyk_1bit_map_color_rgb); + set_dev_proc(dev, encode_color, cmyk_1bit_map_cmyk_color); + set_dev_proc(dev, decode_color, cmyk_1bit_map_color_cmyk); +} + +void gdev_prn_initialize_device_procs_cmyk1_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_cmyk1(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void gdev_prn_initialize_device_procs_cmyk8(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_cmyk_color, cmyk_8bit_map_cmyk_color); + set_dev_proc(dev, map_color_rgb, cmyk_8bit_map_color_rgb); + set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color); + set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk); +} + +void gdev_prn_initialize_device_procs_cmyk8_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_cmyk8(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} + +void gdev_prn_initialize_device_procs_cmyk16(gx_device *dev) +{ + gdev_prn_initialize_device_procs(dev); + + set_dev_proc(dev, map_cmyk_color, cmyk_16bit_map_cmyk_color); + set_dev_proc(dev, map_color_rgb, cmyk_16bit_map_color_rgb); + set_dev_proc(dev, encode_color, cmyk_16bit_map_cmyk_color); + set_dev_proc(dev, decode_color, cmyk_16bit_map_color_cmyk); +} + +void gdev_prn_initialize_device_procs_cmyk16_bg(gx_device *dev) +{ + gdev_prn_initialize_device_procs_cmyk16(dev); + + set_dev_proc(dev, output_page, gdev_prn_bg_output_page); +} diff --git a/base/gdevprn.h b/base/gdevprn.h index fbc7cb0c..a7e1b9c5 100644 --- a/base/gdevprn.h +++ b/base/gdevprn.h @@ -187,95 +187,6 @@ prn_dev_proc_get_space_params(gx_default_get_space_params); /* BACKWARD COMPATIBILITY */ #define gdev_prn_default_get_space_params gx_default_get_space_params -/* Macro for generating procedure table */ -#define prn_procs(p_open, p_output_page, p_close)\ - prn_color_procs_enc_dec(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb) -#define prn_params_procs(p_open, p_output_page, p_close, p_get_params, p_put_params)\ - prn_color_params_procs_enc_dec(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb, p_get_params, p_put_params, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb) -#define prn_color_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb)\ - prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, gdev_prn_get_params, gdev_prn_put_params) -#define prn_color_procs_enc_dec(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_encode_color, p_decode_color)\ - prn_color_params_procs_enc_dec(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, gdev_prn_get_params, gdev_prn_put_params, p_encode_color, p_decode_color) -/* See gdev_prn_open for explanation of the NULLs below. */ -#define prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_get_params, p_put_params) \ - prn_color_params_procs_enc_dec(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_get_params, p_put_params, NULL, NULL) -#define prn_color_params_procs_enc_dec(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_get_params, p_put_params, p_encode_color, p_decode_color) {\ - p_open,\ - NULL, /* get_initial_matrix */\ - NULL, /* sync_output */\ - p_output_page,\ - p_close,\ - p_map_rgb_color,\ - p_map_color_rgb,\ - NULL, /* fill_rectangle */\ - NULL, /* tile_rectangle */\ - NULL, /* copy_mono */\ - NULL, /* copy_color */\ - NULL, /* draw_line */\ - NULL, /* get_bits */\ - p_get_params,\ - p_put_params,\ - NULL, /* map_cmyk_color */\ - NULL, /* get_xfont_procs */\ - NULL, /* get_xfont_device */\ - NULL, /* map_rgb_alpha_color */\ - gx_page_device_get_page_device,\ - NULL, /* get_alpha_bits */\ - NULL, /* copy_alpha */\ - NULL, /* get_band */\ - NULL, /* copy_rop */\ - NULL, /* fill_path */\ - NULL, /* stroke_path */\ - NULL, /* fill_mask */\ - NULL, /* fill_trapezoid */\ - NULL, /* fill_parallelogram */\ - NULL, /* fill_triangle */\ - NULL, /* draw_thin_line */\ - NULL, /* begin_image */\ - NULL, /* image_data */\ - NULL, /* end_image */\ - NULL, /* strip_tile_rectangle */\ - NULL, /* strip_copy_rop, */\ - NULL, /* get_clipping_box */\ - NULL, /* begin_typed_image */\ - NULL, /* get_bits_rectangle */\ - NULL, /* map_color_rgb_alpha */\ - NULL, /* create_compositor */\ - NULL, /* get_hardware_params */\ - NULL, /* text_begin */\ - NULL, /* finish_copydevice */\ - NULL, /* begin_transparency_group */\ - NULL, /* end_transparency_group */\ - NULL, /* begin_transparency_mask */\ - NULL, /* end_transparency_mask */\ - NULL, /* discard_transparency_layer */\ - NULL, /* get_color_mapping_procs */\ - NULL, /* get_color_comp_index */\ - p_encode_color, /* encode_color */\ - p_decode_color, /* decode_color */\ - NULL, /* pattern_manage */\ - NULL, /* fill_rectangle_hl_color */\ - NULL, /* include_color_space */\ - NULL, /* fill_linear_color_scanline */\ - NULL, /* fill_linear_color_trapezoid */\ - NULL, /* fill_linear_color_triangle */\ - NULL, /* update_spot_equivalent_colors */\ - NULL, /* ret_devn_params */\ - NULL, /* fillpage */\ - NULL, /* push_transparency_state */\ - NULL, /* pop_transparency_state */\ - NULL, /* put_image */\ - gdev_prn_dev_spec_op, /* dev_spec_op */\ - NULL, /* copy plane */\ - gx_default_get_profile, /* get_profile */\ - gx_default_set_graphics_type_tag /* set_graphics_type_tag */\ -} - -/* The standard printer device procedures */ -/* (using gdev_prn_open/output_page/close). */ -extern const gx_device_procs prn_std_procs; -extern const gx_device_procs prn_bg_procs; - /* * Define macros for generating the device structure, * analogous to the std_device_body macros in gxdevice.h @@ -320,8 +231,8 @@ extern const gx_device_procs prn_bg_procs; /* The Sun cc compiler won't allow \ within a macro argument list. */ /* This accounts for the short parameter names here and below. */ -#define prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ - std_device_full_body_type(dtype, &procs, dname, &st_device_printer,\ +#define prn_device_margins_body(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + std_device_full_body_type(dtype, init, dname, &st_device_printer,\ (int)((float)(w10) * (xdpi) / 10 + 0.5),\ (int)((float)(h10) * (ydpi) / 10 + 0.5),\ xdpi, ydpi,\ @@ -331,8 +242,19 @@ extern const gx_device_procs prn_bg_procs; (float)((rm) * 72.0), (float)((tm) * 72.0)\ ),\ prn_device_body_rest_(print_page) -#define prn_device_margins_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ - std_device_full_body_type(dtype, &procs, dname, stype,\ +#define prn_device_margins_body_duplex(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + std_device_full_body_type(dtype, init, dname, &st_device_printer,\ + (int)((float)(w10) * (xdpi) / 10 + 0.5),\ + (int)((float)(h10) * (ydpi) / 10 + 0.5),\ + xdpi, ydpi,\ + ncomp, depth, mg, mc, dg, dc,\ + (float)(-(lo) * (xdpi)), (float)(-(to) * (ydpi)),\ + (float)((lm) * 72.0), (float)((bm) * 72.0),\ + (float)((rm) * 72.0), (float)((tm) * 72.0)\ + ),\ + prn_device_body_rest2_(print_page, gx_default_print_page_copies, 0) +#define prn_device_margins_stype_body(dtype, init, dname, stype, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + std_device_full_body_type(dtype, init, dname, stype,\ (int)((float)(w10) * (xdpi) / 10 + 0.5),\ (int)((float)(h10) * (ydpi) / 10 + 0.5),\ xdpi, ydpi,\ @@ -343,15 +265,18 @@ extern const gx_device_procs prn_bg_procs; ),\ prn_device_body_rest_(print_page) -#define prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ - prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device_body(dtype, init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + prn_device_margins_body(dtype, init, dname, w10, h10, xdpi, ydpi,\ + lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page) +#define prn_device_body_duplex(dtype, init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + prn_device_margins_body_duplex(dtype, init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page) -#define prn_device_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ - prn_device_margins_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi,\ +#define prn_device_stype_body(dtype, init, dname, stype, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + prn_device_margins_stype_body(dtype, init, dname, stype, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page) -#define prn_device_margins_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\ - std_device_full_body_type_extended(dtype, &procs, dname, &st_device_printer,\ +#define prn_device_margins_body_extended(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\ + std_device_full_body_type_extended(dtype, init, dname, &st_device_printer,\ (int)((long)(w10) * (xdpi) / 10),\ (int)((long)(h10) * (ydpi) / 10),\ xdpi, ydpi,\ @@ -362,12 +287,12 @@ extern const gx_device_procs prn_bg_procs; ),\ prn_device_body_rest_(print_page) -#define prn_device_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\ - prn_device_margins_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device_body_extended(dtype, init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\ + prn_device_margins_body_extended(dtype, init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page) -#define prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ - std_device_std_color_full_body_type(dtype, &procs, dname, &st_device_printer,\ +#define prn_device_std_margins_body(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ + std_device_std_color_full_body_type(dtype,init, dname, &st_device_printer,\ (int)((float)(w10) * (xdpi) / 10 + 0.5),\ (int)((float)(h10) * (ydpi) / 10 + 0.5),\ xdpi, ydpi, color_bits,\ @@ -377,12 +302,12 @@ extern const gx_device_procs prn_bg_procs; ),\ prn_device_body_rest_(print_page) -#define prn_device_std_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ - prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device_std_body(dtype, init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ + prn_device_std_margins_body(dtype, init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, color_bits, print_page) -#define prn_device_std_margins_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\ - std_device_std_color_full_body_type(dtype, &procs, dname, &st_device_printer,\ +#define prn_device_std_margins_body_copies(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\ + std_device_std_color_full_body_type(dtype, init, dname, &st_device_printer,\ (int)((float)(w10) * (xdpi) / 10 + 0.5),\ (int)((float)(h10) * (ydpi) / 10 + 0.5),\ xdpi, ydpi, color_bits,\ @@ -392,28 +317,28 @@ extern const gx_device_procs prn_bg_procs; ),\ prn_device_body_copies_rest_(print_page_copies) -#define prn_device_std_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\ - prn_device_std_margins_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device_std_body_copies(dtype, init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\ + prn_device_std_margins_body_copies(dtype, init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, color_bits, print_page_copies) /* Note that the following macros add { } around the data. */ -#define prn_device_margins(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ -{ prn_device_std_margins_body(gx_device_printer, procs, dname,\ +#define prn_device_margins(init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ +{ prn_device_std_margins_body(gx_device_printer, init, dname,\ w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ } -#define prn_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ - prn_device_margins(procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device(init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ + prn_device_margins(init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, color_bits, print_page) -#define prn_device_margins_copies(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\ -{ prn_device_std_margins_body_copies(gx_device_printer, procs, dname,\ +#define prn_device_margins_copies(init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\ +{ prn_device_std_margins_body_copies(gx_device_printer, init, dname,\ w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\ } -#define prn_device_copies(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\ - prn_device_margins_copies(procs, dname, w10, h10, xdpi, ydpi,\ +#define prn_device_copies(init, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\ + prn_device_margins_copies(init, dname, w10, h10, xdpi, ydpi,\ lm, tm, lm, bm, rm, tm, color_bits, print_page_copies) /* ------ Utilities ------ */ @@ -452,8 +377,8 @@ bool gdev_prn_file_is_new(const gx_device_printer *pdev); * not available, so we return all-1s (i.e., any color may appear) as the * 'or', and the entire page as the range; we may improve this someday. * - * The return value is like get_band: the first Y value of the actual range - * is stored in *range_start, and the height of the range is returned. + * On return the first Y value of the actual range is stored in + * *range_start, and the height of the range is returned. * If the parameters are invalid, the procedure returns -1. */ int gdev_prn_color_usage(gx_device *dev, int y, int height, @@ -593,34 +518,21 @@ int gdev_create_buf_device(create_buf_device_proc_t cbd_proc, #define gdev_prn_transpose_8x8(inp,ils,outp,ols)\ memflip8x8(inp,ils,outp,ols) -/* ------ Printer device types ------ */ -/**************** THE FOLLOWING CODE IS NOT USED YET. ****************/ - -#if 0 /**************** VMS linker gets upset *************** */ -#endif -int gdev_prn_initialize(gx_device *, const char *, dev_proc_print_page((*))); -void gdev_prn_init_color(gx_device *, int, dev_proc_map_rgb_color((*)), dev_proc_map_color_rgb((*))); - -#define prn_device_type(dtname, initproc, pageproc)\ -static dev_proc_print_page(pageproc);\ -device_type(dtname, st_prn_device, initproc) - -#define prn_device_type_mono(dtname, dname, initproc, pageproc)\ -static dev_proc_print_page(pageproc);\ -static int \ -initproc(gx_device *dev)\ -{ return gdev_prn_initialize(dev, dname, pageproc);\ -}\ -device_type(dtname, st_prn_device, initproc) - -#define prn_device_type_color(dtname, dname, depth, initproc, pageproc, rcproc, crproc)\ -static dev_proc_print_page(pageproc);\ -static int \ -initproc(gx_device *dev)\ -{ int code = gdev_prn_initialize(dev, dname, pageproc);\ - gdev_prn_init_color(dev, depth, rcproc, crproc);\ - return code;\ -}\ -device_type(dtname, st_prn_device, initproc) +void gdev_prn_initialize_device_procs(gx_device *dev); +void gdev_prn_initialize_device_procs_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_mono(gx_device *dev); +void gdev_prn_initialize_device_procs_mono_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_rgb(gx_device *dev); +void gdev_prn_initialize_device_procs_rgb_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_gray(gx_device *dev); +void gdev_prn_initialize_device_procs_gray_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_gray8(gx_device *dev); +void gdev_prn_initialize_device_procs_gray8_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk1(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk1_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk8(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk8_bg(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk16(gx_device *dev); +void gdev_prn_initialize_device_procs_cmyk16_bg(gx_device *dev); #endif /* gdevprn_INCLUDED */ diff --git a/base/gdevrops.c b/base/gdevrops.c index 13582008..d0c97b04 100644 --- a/base/gdevrops.c +++ b/base/gdevrops.c @@ -46,79 +46,45 @@ static dev_proc_copy_color(rop_texture_copy_color); static dev_proc_copy_planes(rop_texture_copy_planes); /* The device descriptor. */ +static void +rop_texture_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, get_initial_matrix,gx_forward_get_initial_matrix); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, rop_texture_fill_rectangle); + set_dev_proc(dev, copy_mono, rop_texture_copy_mono); + set_dev_proc(dev, copy_color, rop_texture_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, gx_forward_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, copy_alpha, gx_no_copy_alpha); + set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_forward_encode_color); + set_dev_proc(dev, decode_color, gx_forward_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, gx_forward_include_color_space); + set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); + set_dev_proc(dev, copy_planes, rop_texture_copy_planes); + set_dev_proc(dev, get_profile, gx_forward_get_profile); + set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); +} static const gx_device_rop_texture gs_rop_texture_device = { - std_device_std_body(gx_device_rop_texture, 0, "rop source", + std_device_std_body(gx_device_rop_texture, + rop_texture_initialize_device_procs, + "rop source", 0, 0, 1, 1), - {NULL, /* open_device */ - gx_forward_get_initial_matrix, - NULL, /* default_sync_output */ - NULL, /* output_page */ - NULL, /* close_device */ - gx_forward_map_rgb_color, - gx_forward_map_color_rgb, - rop_texture_fill_rectangle, - NULL, /* tile_rectangle */ - rop_texture_copy_mono, - rop_texture_copy_color, - NULL, /* draw_line */ - NULL, /* get_bits */ - gx_forward_get_params, - gx_forward_put_params, - gx_forward_map_cmyk_color, - gx_forward_get_xfont_procs, - gx_forward_get_xfont_device, - gx_forward_map_rgb_alpha_color, - gx_forward_get_page_device, - NULL, /* get_alpha_bits (no alpha) */ - gx_no_copy_alpha, /* shouldn't be called */ - gx_forward_get_band, - gx_no_copy_rop, /* shouldn't be called */ - NULL, /* fill_path */ - NULL, /* stroke_path */ - NULL, /* fill_mask */ - NULL, /* fill_trapezoid */ - NULL, /* fill_parallelogram */ - NULL, /* fill_triangle */ - NULL, /* draw_thin_line */ - NULL, /* begin_image */ - NULL, /* image_data */ - NULL, /* end_image */ - NULL, /* strip_tile_rectangle */ - NULL, /* strip_copy_rop */ - gx_forward_get_clipping_box, - NULL, /* begin_typed_image */ - NULL, /* get_bits_rectangle */ - gx_forward_map_color_rgb_alpha, - NULL, /* create_compositor */ - gx_forward_get_hardware_params, - NULL, /* text_begin */ - NULL, /* finish_copydevice */ - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color, - NULL, /* dev_spec_op */ - gx_forward_fill_rectangle_hl_color, - gx_forward_include_color_space, - gx_forward_fill_linear_color_scanline, - gx_forward_fill_linear_color_trapezoid, - gx_forward_fill_linear_color_triangle, - gx_forward_update_spot_equivalent_colors, - gx_forward_ret_devn_params, - gx_forward_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - gx_forward_dev_spec_op, - rop_texture_copy_planes, /* copy planes */ - gx_forward_get_profile, - gx_forward_set_graphics_type_tag - }, + { 0 }, 0, /* target */ lop_default /* log_op */ /* */ /* texture */ @@ -140,9 +106,10 @@ void gx_make_rop_texture_device(gx_device_rop_texture * dev, gx_device * target, gs_logical_operation_t log_op, const gx_device_color * texture) { - gx_device_init((gx_device *) dev, - (const gx_device *)&gs_rop_texture_device, - target->memory, true); + /* Can never fail */ + (void)gx_device_init((gx_device *) dev, + (const gx_device *)&gs_rop_texture_device, + target->memory, true); gx_device_set_target((gx_device_forward *)dev, target); /* Drawing operations are defaulted, non-drawing are forwarded. */ check_device_separable((gx_device *) dev); diff --git a/base/gdevsclass.c b/base/gdevsclass.c index 9ce98148..aec26893 100644 --- a/base/gdevsclass.c +++ b/base/gdevsclass.c @@ -62,7 +62,7 @@ * before overwriting it, rather than the current check for NULL. */ -/* More observations; method naems, we have text_begin, but begin_image. +/* More observations; method naems, we have text_begin, but begin_typed_image. * The enumerator initialiser for images gx_image_enum_common_init doesn't initialise * the 'memory' member variable. The text enumerator initialiser gs_text_enum_init does. * The default text enum init routine increments the reference count of the device, but the image enumerator @@ -178,15 +178,6 @@ int default_subclass_fill_rectangle(gx_device *dev, int x, int y, int width, int return 0; } -int default_subclass_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, - gx_color_index color0, gx_color_index color1, - int phase_x, int phase_y) -{ - if (dev->child) - return dev_proc(dev->child, tile_rectangle)(dev->child, tile, x, y, width, height, color0, color1, phase_x, phase_y); - return 0; -} - int default_subclass_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) @@ -204,21 +195,6 @@ int default_subclass_copy_color(gx_device *dev, const byte *data, int data_x, in return 0; } -int default_subclass_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) -{ - if (dev->child) - return dev_proc(dev->child, obsolete_draw_line)(dev->child, x0, y0, x1, y1, color); - return 0; -} - -int default_subclass_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) -{ - if (dev->child) - return dev_proc(dev->child, get_bits)(dev->child, y, data, actual_data); - /* else */ - return gx_default_get_bits(dev, y, data, actual_data); -} - int default_subclass_get_params(gx_device *dev, gs_param_list *plist) { if (dev->child) @@ -250,31 +226,6 @@ gx_color_index default_subclass_map_cmyk_color(gx_device *dev, const gx_color_va return gx_default_map_cmyk_color(dev, cv); } -const gx_xfont_procs *default_subclass_get_xfont_procs(gx_device *dev) -{ - if (dev->child) - return dev_proc(dev->child, get_xfont_procs)(dev->child); - /* else */ - return gx_default_get_xfont_procs(dev); -} - -gx_device *default_subclass_get_xfont_device(gx_device *dev) -{ - if (dev->child) - return dev_proc(dev->child, get_xfont_device)(dev->child); - /* else */ - return gx_default_get_xfont_device(dev); -} - -gx_color_index default_subclass_map_rgb_alpha_color(gx_device *dev, gx_color_value red, gx_color_value green, gx_color_value blue, - gx_color_value alpha) -{ - if (dev->child) - return dev_proc(dev->child, map_rgb_alpha_color)(dev->child, red, green, blue, alpha); - /* else */ - return gx_default_map_rgb_alpha_color(dev, red, green, blue, alpha); -} - gx_device *default_subclass_get_page_device(gx_device *dev) { if (dev->child) @@ -299,26 +250,6 @@ int default_subclass_copy_alpha(gx_device *dev, const byte *data, int data_x, return 0; } -int default_subclass_get_band(gx_device *dev, int y, int *band_start) -{ - if (dev->child) - return dev_proc(dev->child, get_band)(dev->child, y, band_start); - /* else */ - return gx_default_get_band(dev, y, band_start); -} - -int default_subclass_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_tile_bitmap *texture, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - if (dev->child) - return dev_proc(dev->child, copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); - /* else */ - return gx_default_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); -} - int default_subclass_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) @@ -388,32 +319,6 @@ int default_subclass_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); } -int default_subclass_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, - gs_image_format_t format, const gs_int_rect *prect, - const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gx_image_enum_common_t **pinfo) -{ - if (dev->child) - return dev_proc(dev->child, begin_image)(dev->child, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); - /* else */ - return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); -} - -int default_subclass_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, - uint raster, int height) -{ - if (dev->child) - return dev_proc(dev->child, image_data)(dev->child, info, planes, data_x, raster, height); - return 0; -} - -int default_subclass_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) -{ - if (dev->child) - return dev_proc(dev->child, end_image)(dev->child, info, draw_last); - return 0; -} - int default_subclass_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) @@ -424,18 +329,6 @@ int default_subclass_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap return gx_default_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); } -int default_subclass_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index *scolors, - const gx_strip_bitmap *textures, const gx_color_index *tcolors, - int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - if (dev->child) - return dev_proc(dev->child, strip_copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); - /* else */ - return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); -} - void default_subclass_get_clipping_box(gx_device *dev, gs_fixed_rect *pbox) { if (dev->child) { @@ -458,23 +351,15 @@ int default_subclass_begin_typed_image(gx_device *dev, const gs_gstate *pgs, con } int default_subclass_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, - gs_get_bits_params_t *params, gs_int_rect **unread) + gs_get_bits_params_t *params) { if (dev->child) - return dev_proc(dev->child, get_bits_rectangle)(dev->child, prect, params, unread); + return dev_proc(dev->child, get_bits_rectangle)(dev->child, prect, params); /* else */ - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); } -int default_subclass_map_color_rgb_alpha(gx_device *dev, gx_color_index color, gx_color_value rgba[4]) -{ - if (dev->child) - return dev_proc(dev->child, map_color_rgb_alpha)(dev->child, color, rgba); - /* else */ - return gx_default_map_color_rgb_alpha(dev, color, rgba); -} - -int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, +int default_subclass_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) { int code; @@ -484,7 +369,7 @@ int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const * that we pass to access its own data (not unreasonably), so we need to make sure we pass in the * child device. This has some follow on implications detailed below. */ - code = dev_proc(dev->child, create_compositor)(dev->child, pcdev, pcte, pgs, memory, cdev); + code = dev_proc(dev->child, composite)(dev->child, pcdev, pcte, pgs, memory, cdev); if (code < 0) return code; @@ -575,22 +460,13 @@ int default_subclass_get_hardware_params(gx_device *dev, gs_param_list *plist) } int default_subclass_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, - gs_memory_t *memory, gs_text_enum_t **ppte) + gs_font *font, const gx_clip_path *pcpath, + gs_text_enum_t **ppte) { if (dev->child) - return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, pcpath, ppte); /* else */ - return gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); -} - -/* This method seems (despite the name) to be intended to allow for - * devices to initialise data before being invoked. For our subclassed - * device this should already have been done. - */ -int default_subclass_finish_copydevice(gx_device *dev, const gx_device *from_dev) -{ - return 0; + return gx_default_text_begin(dev, pgs, text, font, pcpath, ppte); } int default_subclass_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, @@ -635,12 +511,13 @@ int default_subclass_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) return 0; } -const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev) +const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev, + const gx_device **tdev) { if (dev->child) - return dev_proc(dev->child, get_color_mapping_procs)(dev->child); + return dev_proc(dev->child, get_color_mapping_procs)(dev->child, tdev); /* else */ - return gx_default_DevGray_get_color_mapping_procs(dev); + return gx_default_DevGray_get_color_mapping_procs(dev, tdev); } int default_subclass_get_color_comp_index(gx_device *dev, const char * pname, int name_size, int component_type) @@ -670,15 +547,6 @@ int default_subclass_decode_color(gx_device *dev, gx_color_index cindex, gx_colo return 0; } -int default_subclass_pattern_manage(gx_device *dev, gx_bitmap_id id, - gs_pattern1_instance_t *pinst, pattern_manage_t function) -{ - if (dev->child) - return dev_proc(dev->child, pattern_manage)(dev->child, id, pinst, function); - - return 0; -} - int default_subclass_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { @@ -809,7 +677,7 @@ int default_subclass_copy_planes(gx_device *dev, const byte *data, int data_x, i return 0; } -int default_subclass_get_profile(gx_device *dev, cmm_dev_profile_t **dev_profile) +int default_subclass_get_profile(const gx_device *dev, cmm_dev_profile_t **dev_profile) { if (dev->child) { return dev_proc(dev->child, get_profile)(dev->child, dev_profile); @@ -929,3 +797,98 @@ void default_subclass_finalize(const gs_memory_t *cmem, void *vptr) if (dev->NupControl) rc_decrement(dev->NupControl, "finalize subclass device"); } + +void default_subclass_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, default_subclass_open_device); + set_dev_proc(dev, get_initial_matrix, default_subclass_get_initial_matrix); + set_dev_proc(dev, sync_output, default_subclass_sync_output); + set_dev_proc(dev, output_page, default_subclass_output_page); + set_dev_proc(dev, close_device, default_subclass_close_device); + set_dev_proc(dev, map_rgb_color, default_subclass_map_rgb_color); + set_dev_proc(dev, map_color_rgb, default_subclass_map_color_rgb); + set_dev_proc(dev, fill_rectangle, default_subclass_fill_rectangle); + set_dev_proc(dev, copy_mono, default_subclass_copy_mono); + set_dev_proc(dev, copy_color, default_subclass_copy_color); + set_dev_proc(dev, get_params, default_subclass_get_params); + set_dev_proc(dev, put_params, default_subclass_put_params); + set_dev_proc(dev, map_cmyk_color, default_subclass_map_cmyk_color); + set_dev_proc(dev, get_page_device, default_subclass_get_page_device); + set_dev_proc(dev, get_alpha_bits, default_subclass_get_alpha_bits); + set_dev_proc(dev, copy_alpha, default_subclass_copy_alpha); + set_dev_proc(dev, fill_path, default_subclass_fill_path); + set_dev_proc(dev, stroke_path, default_subclass_stroke_path); + set_dev_proc(dev, fill_mask, default_subclass_fill_mask); + set_dev_proc(dev, fill_trapezoid, default_subclass_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, default_subclass_fill_parallelogram); + set_dev_proc(dev, fill_triangle, default_subclass_fill_triangle); + set_dev_proc(dev, draw_thin_line, default_subclass_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, default_subclass_strip_tile_rectangle); + set_dev_proc(dev, get_clipping_box, default_subclass_get_clipping_box); + set_dev_proc(dev, begin_typed_image, default_subclass_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, default_subclass_get_bits_rectangle); + set_dev_proc(dev, composite, default_subclass_composite); + set_dev_proc(dev, get_hardware_params, default_subclass_get_hardware_params); + set_dev_proc(dev, text_begin, default_subclass_text_begin); + set_dev_proc(dev, begin_transparency_group, default_subclass_begin_transparency_group); + set_dev_proc(dev, end_transparency_group, default_subclass_end_transparency_group); + set_dev_proc(dev, begin_transparency_mask, default_subclass_begin_transparency_mask); + set_dev_proc(dev, end_transparency_mask, default_subclass_end_transparency_mask); + set_dev_proc(dev, discard_transparency_layer, default_subclass_discard_transparency_layer); + set_dev_proc(dev, get_color_mapping_procs, default_subclass_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, default_subclass_get_color_comp_index); + set_dev_proc(dev, encode_color, default_subclass_encode_color); + set_dev_proc(dev, decode_color, default_subclass_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, default_subclass_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, default_subclass_include_color_space); + set_dev_proc(dev, fill_linear_color_scanline, default_subclass_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, default_subclass_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, default_subclass_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, default_subclass_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, default_subclass_ret_devn_params); + set_dev_proc(dev, fillpage, default_subclass_fillpage); + set_dev_proc(dev, push_transparency_state, default_subclass_push_transparency_state); + set_dev_proc(dev, pop_transparency_state, default_subclass_pop_transparency_state); + set_dev_proc(dev, put_image, default_subclass_put_image); + set_dev_proc(dev, dev_spec_op, default_subclass_dev_spec_op); + set_dev_proc(dev, copy_planes, default_subclass_copy_planes); + set_dev_proc(dev, get_profile, default_subclass_get_profile); + set_dev_proc(dev, set_graphics_type_tag, default_subclass_set_graphics_type_tag); + set_dev_proc(dev, strip_copy_rop2, default_subclass_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, default_subclass_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, default_subclass_copy_alpha_hl_color); + set_dev_proc(dev, process_page, default_subclass_process_page); + set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); +} + +int +default_subclass_install(gx_device *dev, gs_gstate *pgs) +{ + dev = dev->child; + return dev->page_procs.install(dev, pgs); +} + +int +default_subclass_begin_page(gx_device *dev, gs_gstate *pgs) +{ + dev = dev->child; + return dev->page_procs.begin_page(dev, pgs); +} + +int +default_subclass_end_page(gx_device *dev, int reason, gs_gstate *pgs) +{ + dev = dev->child; + return dev->page_procs.end_page(dev, reason, pgs); +} + +void gx_subclass_fill_in_page_procs(gx_device *dev) +{ + if (dev->page_procs.install == NULL) + dev->page_procs.install = default_subclass_install; + if (dev->page_procs.begin_page == NULL) + dev->page_procs.begin_page = default_subclass_begin_page; + if (dev->page_procs.end_page == NULL) + dev->page_procs.end_page = default_subclass_end_page; +} diff --git a/base/gdevsclass.h b/base/gdevsclass.h index aface183..2fb440d6 100644 --- a/base/gdevsclass.h +++ b/base/gdevsclass.h @@ -36,22 +36,14 @@ dev_proc_close_device(default_subclass_close_device); dev_proc_map_rgb_color(default_subclass_map_rgb_color); dev_proc_map_color_rgb(default_subclass_map_color_rgb); dev_proc_fill_rectangle(default_subclass_fill_rectangle); -dev_proc_tile_rectangle(default_subclass_tile_rectangle); dev_proc_copy_mono(default_subclass_copy_mono); dev_proc_copy_color(default_subclass_copy_color); -dev_proc_draw_line(default_subclass_draw_line); -dev_proc_get_bits(default_subclass_get_bits); dev_proc_get_params(default_subclass_get_params); dev_proc_put_params(default_subclass_put_params); dev_proc_map_cmyk_color(default_subclass_map_cmyk_color); -dev_proc_get_xfont_procs(default_subclass_get_xfont_procs); -dev_proc_get_xfont_device(default_subclass_get_xfont_device); -dev_proc_map_rgb_alpha_color(default_subclass_map_rgb_alpha_color); dev_proc_get_page_device(default_subclass_get_page_device); dev_proc_get_alpha_bits(default_subclass_get_alpha_bits); dev_proc_copy_alpha(default_subclass_copy_alpha); -dev_proc_get_band(default_subclass_get_band); -dev_proc_copy_rop(default_subclass_copy_rop); dev_proc_fill_path(default_subclass_fill_path); dev_proc_stroke_path(default_subclass_stroke_path); dev_proc_fill_mask(default_subclass_fill_mask); @@ -59,19 +51,14 @@ dev_proc_fill_trapezoid(default_subclass_fill_trapezoid); dev_proc_fill_parallelogram(default_subclass_fill_parallelogram); dev_proc_fill_triangle(default_subclass_fill_triangle); dev_proc_draw_thin_line(default_subclass_draw_thin_line); -dev_proc_begin_image(default_subclass_begin_image); -dev_proc_image_data(default_subclass_image_data); -dev_proc_end_image(default_subclass_end_image); dev_proc_strip_tile_rectangle(default_subclass_strip_tile_rectangle); -dev_proc_strip_copy_rop(default_subclass_strip_copy_rop); dev_proc_get_clipping_box(default_subclass_get_clipping_box); dev_proc_begin_typed_image(default_subclass_begin_typed_image); dev_proc_get_bits_rectangle(default_subclass_get_bits_rectangle); -dev_proc_map_color_rgb_alpha(default_subclass_map_color_rgb_alpha); -dev_proc_create_compositor(default_subclass_create_compositor); +dev_proc_composite(default_subclass_composite); dev_proc_get_hardware_params(default_subclass_get_hardware_params); dev_proc_text_begin(default_subclass_text_begin); -dev_proc_finish_copydevice(default_subclass_finish_copydevice); +dev_proc_initialize_device_procs(default_subclass_initialize_device_procs); dev_proc_begin_transparency_group(default_subclass_begin_transparency_group); dev_proc_end_transparency_group(default_subclass_end_transparency_group); dev_proc_begin_transparency_mask(default_subclass_begin_transparency_mask); @@ -81,7 +68,6 @@ dev_proc_get_color_mapping_procs(default_subclass_get_color_mapping_procs); dev_proc_get_color_comp_index(default_subclass_get_color_comp_index); dev_proc_encode_color(default_subclass_encode_color); dev_proc_decode_color(default_subclass_decode_color); -dev_proc_pattern_manage(default_subclass_pattern_manage); dev_proc_fill_rectangle_hl_color(default_subclass_fill_rectangle_hl_color); dev_proc_include_color_space(default_subclass_include_color_space); dev_proc_fill_linear_color_scanline(default_subclass_fill_linear_color_scanline); @@ -103,7 +89,10 @@ dev_proc_copy_alpha_hl_color(default_subclass_copy_alpha_hl_color); dev_proc_process_page(default_subclass_process_page); dev_proc_transform_pixel_region(default_subclass_transform_pixel_region); dev_proc_fill_stroke_path(default_subclass_fill_stroke_path); - +dev_page_proc_install(default_subclass_install); +dev_page_proc_begin_page(default_subclass_begin_page); +dev_page_proc_end_page(default_subclass_end_page); void default_subclass_finalize(const gs_memory_t *cmem, void *vptr); -#endif /* gdev_obj_filter_INCLUDED */ + +#endif /* gdev_default_subclass_INCLUDED */ diff --git a/base/gdevvec.c b/base/gdevvec.c index d2694207..2a9915cd 100644 --- a/base/gdevvec.c +++ b/base/gdevvec.c @@ -643,7 +643,7 @@ gdev_vector_dopath_init(gdev_vector_dopath_state_t *state, */ int gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, - gs_fixed_point vs[3]) + gs_fixed_point *vs) { gx_device_vector *vdev = state->vdev; const gs_matrix *const pmat = &state->scale_mat; @@ -901,9 +901,10 @@ gdev_vector_begin_image(gx_device_vector * vdev, (pim->CombineWithColor && rop3_uses_T(pgs->log_op))) && (code = gdev_vector_update_fill_color(vdev, pgs, pdcolor)) < 0) || (vdev->bbox_device && - (code = (*dev_proc(vdev->bbox_device, begin_image)) - ((gx_device *) vdev->bbox_device, pgs, pim, format, prect, - pdcolor, pcpath, mem, &pie->bbox_info)) < 0) + (code = (*dev_proc(vdev->bbox_device, begin_typed_image)) + ((gx_device *) vdev->bbox_device, pgs, NULL, + (gs_image_common_t *)pim, prect, + pdcolor, pcpath, mem, &pie->bbox_info)) < 0) ) return code; pie->memory = mem; @@ -926,8 +927,7 @@ gdev_vector_end_image(gx_device_vector * vdev, int code; if (pie->default_info) { - code = gx_default_end_image((gx_device *) vdev, pie->default_info, - draw_last); + code = gx_image_end(pie->default_info, draw_last); if (code >= 0) code = 0; } else { /* Fill out to the full image height. */ diff --git a/base/gdevvec.h b/base/gdevvec.h index b7476229..b7998e52 100644 --- a/base/gdevvec.h +++ b/base/gdevvec.h @@ -306,7 +306,7 @@ void gdev_vector_dopath_init(gdev_vector_dopath_state_t *state, /* Write a segment of a path using the default implementation. */ int gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, - gs_fixed_point vs[3]); + gs_fixed_point *vs); typedef struct gdev_vector_path_seg_record_s { int op; @@ -374,6 +374,17 @@ int gdev_vector_begin_image(gx_device_vector * vdev, gs_memory_t * mem, const gx_image_enum_procs_t * pprocs, gdev_vector_image_enum_t * pie); +int gdev_vector_begin_typed_image(gx_device_vector *vdev, + const gs_gstate *pgs, + const gs_matrix *pmat, + const gs_image_common_t *pim, + const gs_int_rect *prect, + const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath, + gs_memory_t *mem, + const gx_image_enum_procs_t *pprocs, + gdev_vector_image_enum_t *pie); + /* End an image, optionally supplying any necessary blank padding rows. */ /* Return 0 if we used the default implementation, 1 if not. */ int gdev_vector_end_image(gx_device_vector * vdev, diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c index 2b964ed7..8d87cead 100644 --- a/base/gp_mshdl.c +++ b/base/gp_mshdl.c @@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access, long hfile; /* Correct for Win32, may be wrong for Win64 */ gs_lib_ctx_t *ctx = mem->gs_lib_ctx; gs_fs_list_t *fs = ctx->core->fs; + char f[gp_file_name_sizeof]; + const size_t preflen = strlen(iodev->dname); + const size_t nlen = strlen(fname); - if (gp_validate_path(mem, fname, access) != 0) + if (preflen + nlen >= gp_file_name_sizeof) + return_error(gs_error_invalidaccess); + + memcpy(f, iodev->dname, preflen); + memcpy(f + preflen, fname, nlen + 1); + + if (gp_validate_path(mem, f, access) != 0) return gs_error_invalidfileaccess; /* First we try the open_handle method. */ diff --git a/base/gp_msprn.c b/base/gp_msprn.c index ed482796..746a974f 100644 --- a/base/gp_msprn.c +++ b/base/gp_msprn.c @@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, uintptr_t *ptid = &((tid_t *)(iodev->state))->tid; gs_lib_ctx_t *ctx = mem->gs_lib_ctx; gs_fs_list_t *fs = ctx->core->fs; + const size_t preflen = strlen(iodev->dname); + const size_t nlen = strlen(fname); - if (gp_validate_path(mem, fname, access) != 0) + if (preflen + nlen >= gp_file_name_sizeof) + return_error(gs_error_invalidaccess); + + memcpy(pname, iodev->dname, preflen); + memcpy(pname + preflen, fname, nlen + 1); + + if (gp_validate_path(mem, pname, access) != 0) return gs_error_invalidfileaccess; /* First we try the open_printer method. */ diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c index f852c71f..ba54cde6 100644 --- a/base/gp_os2pr.c +++ b/base/gp_os2pr.c @@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { os2_printer_t *pr = (os2_printer_t *)iodev->state; - char driver_name[256]; + char driver_name[gp_file_name_sizeof]; gs_lib_ctx_t *ctx = mem->gs_lib_ctx; gs_fs_list_t *fs = ctx->core->fs; + const size_t preflen = strlen(iodev->dname); + const int size_t = strlen(fname); + + if (preflen + nlen >= gp_file_name_sizeof) + return_error(gs_error_invalidaccess); + + memcpy(driver_name, iodev->dname, preflen); + memcpy(driver_name + preflen, fname, nlen + 1); + + if (gp_validate_path(mem, driver_name, access) != 0) + return gs_error_invalidfileaccess; /* First we try the open_printer method. */ /* Note that the loop condition here ensures we don't diff --git a/base/gp_unifs.c b/base/gp_unifs.c index a007ddce..3da81444 100644 --- a/base/gp_unifs.c +++ b/base/gp_unifs.c @@ -112,7 +112,7 @@ gp_open_scratch_file_impl(const gs_memory_t *mem, # else file = mkstemp(fname); # endif - if (file < -1) { + if (file < 0) { emprintf1(mem, "**** Could not open temporary file %s\n", ofname); return NULL; } diff --git a/base/gp_unix.c b/base/gp_unix.c index 420f7526..98db2ddf 100644 --- a/base/gp_unix.c +++ b/base/gp_unix.c @@ -497,7 +497,7 @@ void gp_enumerate_fonts_free(void *enum_state) #ifdef __MINGW32__ int -gp_local_arg_encoding_get_codepoint(FILE *file, const char **astr) +gp_local_arg_encoding_get_codepoint(gp_file *file, const char **astr) { int len; int c; @@ -506,7 +506,7 @@ gp_local_arg_encoding_get_codepoint(FILE *file, const char **astr) char utf8[4]; if (file) { - c = fgetc(file); + c = gp_fgetc(file); if (c == EOF) return EOF; } else if (**astr) { @@ -520,7 +520,7 @@ gp_local_arg_encoding_get_codepoint(FILE *file, const char **astr) arg[0] = c; if (IsDBCSLeadByte(c)) { if (file) { - c = fgetc(file); + c = gp_fgetc(file); if (c == EOF) return EOF; } else if (**astr) { diff --git a/base/gs.mak b/base/gs.mak index f67a2446..0b84be49 100644 --- a/base/gs.mak +++ b/base/gs.mak @@ -248,6 +248,7 @@ GS_MAK=$(GLSRCDIR)$(D)gs.mak $(TOP_MAKEFILES) GS_XE=$(BINDIR)$(D)$(GS)$(XE) GPCL_XE=$(BINDIR)$(D)$(PCL)$(XE) GXPS_XE=$(BINDIR)$(D)$(XPS)$(XE) +GPDF_XE=$(BINDIR)$(D)$(PDF)$(XE) GPDL_XE=$(BINDIR)$(D)$(GPDL)$(XE) AUX=$(AUXDIR)$(D) @@ -411,6 +412,11 @@ XPS_DEVS_ALL=$(GSPLAT_DEVS_ALL) \ $(FEATURE_DEVS_EXTRA) \ $(DEVICE_DEVS_ALL) +PDF_DEVS_ALL=$(GSPLAT_DEVS_ALL) \ + $(FEATURE_DEVS) \ + $(FEATURE_DEVS_EXTRA) \ + $(DEVICE_DEVS_ALL) + DEVS_ALL=$(GLGENDIR)$(D)$(GSPLATFORM).dev\ $(FEATURE_DEVS_EXTRA) \ $(DEVICE_DEVS) $(DEVICE_DEVS1) \ @@ -513,6 +519,16 @@ $(xps_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_ $(EXP)$(ECHOGS_XE) -a $(xps_tr) -R $(ixps_tr) $(EXP)$(GENCONF_XE) $(xps_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) $(CONFLDTR) $(xpsld_tr) +pdf_tr=$(GLGENDIR)$(D)pdf.tr +ipdf_tr=$(GLGENDIR)$(D)ipdf.tr +pdfld_tr=$(GLGENDIR)$(D)pdfld.tr +$(pdf_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_tr) $(devs_tr) $(PDF_DEVS_ALL) \ + $(devs_tr) $(PDF_FEATURE_DEVS) $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(ipdf_tr) - -include $(PDF_FEATURE_DEVS) + $(EXP)$(ECHOGS_XE) -w $(pdf_tr) -R $(devs_tr) + $(EXP)$(ECHOGS_XE) -a $(pdf_tr) -R $(ipdf_tr) + $(EXP)$(GENCONF_XE) $(pdf_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) $(CONFLDTR) $(pdfld_tr) + gpdl_tr=$(GLGENDIR)$(D)gpdl.tr igpdl_tr=$(GLGENDIR)$(D)igpdl.tr gpdlld_tr=$(GLGENDIR)$(D)gpdlld.tr @@ -560,6 +576,10 @@ xpsobj_tr=$(GLGENDIR)$(D)xpsobj.tr $(xpsobj_tr) : $(xps_tr) $(EXP)$(GENCONF_XE) $(xps_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(xpsobj_tr) +pdfobj_tr=$(GLGENDIR)$(D)pdfobj.tr +$(pdfobj_tr) : $(pdf_tr) + $(EXP)$(GENCONF_XE) $(pdf_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(pdfobj_tr) + pdlobj_tr=$(GLGENDIR)$(D)pdlobj.tr $(pdlobj_tr) : $(gpdl_tr) diff --git a/base/gsagl.c b/base/gsagl.c new file mode 100644 index 00000000..434520cf --- /dev/null +++ b/base/gsagl.c @@ -0,0 +1,4312 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ +#include "gsagl.h" + +single_glyph_list_t SingleGlyphList[] = { +{"A", 0x0041}, +{"AE", 0x00C6}, +{"AEacute", 0x01FC}, +{"AEmacron", 0x01E2}, +{"AEsmall", 0xF7E6}, +{"Aacute", 0x00C1}, +{"Aacutesmall", 0xF7E1}, +{"Abreve", 0x0102}, +{"Abreveacute", 0x1EAE}, +{"Abrevecyrillic", 0x04D0}, +{"Abrevedotbelow", 0x1EB6}, +{"Abrevegrave", 0x1EB0}, +{"Abrevehookabove", 0x1EB2}, +{"Abrevetilde", 0x1EB4}, +{"Acaron", 0x01CD}, +{"Acircle", 0x24B6}, +{"Acircumflex", 0x00C2}, +{"Acircumflexacute", 0x1EA4}, +{"Acircumflexdotbelow", 0x1EAC}, +{"Acircumflexgrave", 0x1EA6}, +{"Acircumflexhookabove", 0x1EA8}, +{"Acircumflexsmall", 0xF7E2}, +{"Acircumflextilde", 0x1EAA}, +{"Acute", 0xF6C9}, +{"Acutesmall", 0xF7B4}, +{"Acyrillic", 0x0410}, +{"Adblgrave", 0x0200}, +{"Adieresis", 0x00C4}, +{"Adieresiscyrillic", 0x04D2}, +{"Adieresismacron", 0x01DE}, +{"Adieresissmall", 0xF7E4}, +{"Adotbelow", 0x1EA0}, +{"Adotmacron", 0x01E0}, +{"Agrave", 0x00C0}, +{"Agravesmall", 0xF7E0}, +{"Ahookabove", 0x1EA2}, +{"Aiecyrillic", 0x04D4}, +{"Ainvertedbreve", 0x0202}, +{"Alpha", 0x0391}, +{"Alphatonos", 0x0386}, +{"Amacron", 0x0100}, +{"Amonospace", 0xFF21}, +{"Aogonek", 0x0104}, +{"Aring", 0x00C5}, +{"Aringacute", 0x01FA}, +{"Aringbelow", 0x1E00}, +{"Aringsmall", 0xF7E5}, +{"Asmall", 0xF761}, +{"Atilde", 0x00C3}, +{"Atildesmall", 0xF7E3}, +{"Aybarmenian", 0x0531}, +{"B", 0x0042}, +{"Bcircle", 0x24B7}, +{"Bdotaccent", 0x1E02}, +{"Bdotbelow", 0x1E04}, +{"Becyrillic", 0x0411}, +{"Benarmenian", 0x0532}, +{"Beta", 0x0392}, +{"Bhook", 0x0181}, +{"Blinebelow", 0x1E06}, +{"Bmonospace", 0xFF22}, +{"Brevesmall", 0xF6F4}, +{"Bsmall", 0xF762}, +{"Btopbar", 0x0182}, +{"C", 0x0043}, +{"Caarmenian", 0x053E}, +{"Cacute", 0x0106}, +{"Caron", 0xF6CA}, +{"Caronsmall", 0xF6F5}, +{"Ccaron", 0x010C}, +{"Ccedilla", 0x00C7}, +{"Ccedillaacute", 0x1E08}, +{"Ccedillasmall", 0xF7E7}, +{"Ccircle", 0x24B8}, +{"Ccircumflex", 0x0108}, +{"Cdot", 0x010A}, +{"Cdotaccent", 0x010A}, +{"Cedillasmall", 0xF7B8}, +{"Chaarmenian", 0x0549}, +{"Cheabkhasiancyrillic", 0x04BC}, +{"Checyrillic", 0x0427}, +{"Chedescenderabkhasiancyrillic", 0x04BE}, +{"Chedescendercyrillic", 0x04B6}, +{"Chedieresiscyrillic", 0x04F4}, +{"Cheharmenian", 0x0543}, +{"Chekhakassiancyrillic", 0x04CB}, +{"Cheverticalstrokecyrillic", 0x04B8}, +{"Chi", 0x03A7}, +{"Chook", 0x0187}, +{"Circumflexsmall", 0xF6F6}, +{"Cmonospace", 0xFF23}, +{"Coarmenian", 0x0551}, +{"Csmall", 0xF763}, +{"D", 0x0044}, +{"DZ", 0x01F1}, +{"DZcaron", 0x01C4}, +{"Daarmenian", 0x0534}, +{"Dafrican", 0x0189}, +{"Dcaron", 0x010E}, +{"Dcedilla", 0x1E10}, +{"Dcircle", 0x24B9}, +{"Dcircumflexbelow", 0x1E12}, +{"Dcroat", 0x0110}, +{"Ddotaccent", 0x1E0A}, +{"Ddotbelow", 0x1E0C}, +{"Decyrillic", 0x0414}, +{"Deicoptic", 0x03EE}, +{"Delta", 0x2206}, +{"Deltagreek", 0x0394}, +{"Dhook", 0x018A}, +{"Dieresis", 0xF6CB}, +{"DieresisAcute", 0xF6CC}, +{"DieresisGrave", 0xF6CD}, +{"Dieresissmall", 0xF7A8}, +{"Digammagreek", 0x03DC}, +{"Djecyrillic", 0x0402}, +{"Dlinebelow", 0x1E0E}, +{"Dmonospace", 0xFF24}, +{"Dotaccentsmall", 0xF6F7}, +{"Dslash", 0x0110}, +{"Dsmall", 0xF764}, +{"Dtopbar", 0x018B}, +{"Dz", 0x01F2}, +{"Dzcaron", 0x01C5}, +{"Dzeabkhasiancyrillic", 0x04E0}, +{"Dzecyrillic", 0x0405}, +{"Dzhecyrillic", 0x040F}, +{"E", 0x0045}, +{"Eacute", 0x00C9}, +{"Eacutesmall", 0xF7E9}, +{"Ebreve", 0x0114}, +{"Ecaron", 0x011A}, +{"Ecedillabreve", 0x1E1C}, +{"Echarmenian", 0x0535}, +{"Ecircle", 0x24BA}, +{"Ecircumflex", 0x00CA}, +{"Ecircumflexacute", 0x1EBE}, +{"Ecircumflexbelow", 0x1E18}, +{"Ecircumflexdotbelow", 0x1EC6}, +{"Ecircumflexgrave", 0x1EC0}, +{"Ecircumflexhookabove", 0x1EC2}, +{"Ecircumflexsmall", 0xF7EA}, +{"Ecircumflextilde", 0x1EC4}, +{"Ecyrillic", 0x0404}, +{"Edblgrave", 0x0204}, +{"Edieresis", 0x00CB}, +{"Edieresissmall", 0xF7EB}, +{"Edot", 0x0116}, +{"Edotaccent", 0x0116}, +{"Edotbelow", 0x1EB8}, +{"Efcyrillic", 0x0424}, +{"Egrave", 0x00C8}, +{"Egravesmall", 0xF7E8}, +{"Eharmenian", 0x0537}, +{"Ehookabove", 0x1EBA}, +{"Eightroman", 0x2167}, +{"Einvertedbreve", 0x0206}, +{"Eiotifiedcyrillic", 0x0464}, +{"Elcyrillic", 0x041B}, +{"Elevenroman", 0x216A}, +{"Emacron", 0x0112}, +{"Emacronacute", 0x1E16}, +{"Emacrongrave", 0x1E14}, +{"Emcyrillic", 0x041C}, +{"Emonospace", 0xFF25}, +{"Encyrillic", 0x041D}, +{"Endescendercyrillic", 0x04A2}, +{"Eng", 0x014A}, +{"Enghecyrillic", 0x04A4}, +{"Enhookcyrillic", 0x04C7}, +{"Eogonek", 0x0118}, +{"Eopen", 0x0190}, +{"Epsilon", 0x0395}, +{"Epsilontonos", 0x0388}, +{"Ercyrillic", 0x0420}, +{"Ereversed", 0x018E}, +{"Ereversedcyrillic", 0x042D}, +{"Escyrillic", 0x0421}, +{"Esdescendercyrillic", 0x04AA}, +{"Esh", 0x01A9}, +{"Esmall", 0xF765}, +{"Eta", 0x0397}, +{"Etarmenian", 0x0538}, +{"Etatonos", 0x0389}, +{"Eth", 0x00D0}, +{"Ethsmall", 0xF7F0}, +{"Etilde", 0x1EBC}, +{"Etildebelow", 0x1E1A}, +{"Euro", 0x20AC}, +{"Ezh", 0x01B7}, +{"Ezhcaron", 0x01EE}, +{"Ezhreversed", 0x01B8}, +{"F", 0x0046}, +{"Fcircle", 0x24BB}, +{"Fdotaccent", 0x1E1E}, +{"Feharmenian", 0x0556}, +{"Feicoptic", 0x03E4}, +{"Fhook", 0x0191}, +{"Fitacyrillic", 0x0472}, +{"Fiveroman", 0x2164}, +{"Fmonospace", 0xFF26}, +{"Fourroman", 0x2163}, +{"Fsmall", 0xF766}, +{"G", 0x0047}, +{"GBsquare", 0x3387}, +{"Gacute", 0x01F4}, +{"Gamma", 0x0393}, +{"Gammaafrican", 0x0194}, +{"Gangiacoptic", 0x03EA}, +{"Gbreve", 0x011E}, +{"Gcaron", 0x01E6}, +{"Gcedilla", 0x0122}, +{"Gcircle", 0x24BC}, +{"Gcircumflex", 0x011C}, +{"Gcommaaccent", 0x0122}, +{"Gdot", 0x0120}, +{"Gdotaccent", 0x0120}, +{"Gecyrillic", 0x0413}, +{"Ghadarmenian", 0x0542}, +{"Ghemiddlehookcyrillic", 0x0494}, +{"Ghestrokecyrillic", 0x0492}, +{"Gheupturncyrillic", 0x0490}, +{"Ghook", 0x0193}, +{"Gimarmenian", 0x0533}, +{"Gjecyrillic", 0x0403}, +{"Gmacron", 0x1E20}, +{"Gmonospace", 0xFF27}, +{"Grave", 0xF6CE}, +{"Gravesmall", 0xF760}, +{"Gsmall", 0xF767}, +{"Gsmallhook", 0x029B}, +{"Gstroke", 0x01E4}, +{"H", 0x0048}, +{"H18533", 0x25CF}, +{"H18543", 0x25AA}, +{"H18551", 0x25AB}, +{"H22073", 0x25A1}, +{"HPsquare", 0x33CB}, +{"Haabkhasiancyrillic", 0x04A8}, +{"Hadescendercyrillic", 0x04B2}, +{"Hardsigncyrillic", 0x042A}, +{"Hbar", 0x0126}, +{"Hbrevebelow", 0x1E2A}, +{"Hcedilla", 0x1E28}, +{"Hcircle", 0x24BD}, +{"Hcircumflex", 0x0124}, +{"Hdieresis", 0x1E26}, +{"Hdotaccent", 0x1E22}, +{"Hdotbelow", 0x1E24}, +{"Hmonospace", 0xFF28}, +{"Hoarmenian", 0x0540}, +{"Horicoptic", 0x03E8}, +{"Hsmall", 0xF768}, +{"Hungarumlaut", 0xF6CF}, +{"Hungarumlautsmall", 0xF6F8}, +{"Hzsquare", 0x3390}, +{"I", 0x0049}, +{"IAcyrillic", 0x042F}, +{"IJ", 0x0132}, +{"IUcyrillic", 0x042E}, +{"Iacute", 0x00CD}, +{"Iacutesmall", 0xF7ED}, +{"Ibreve", 0x012C}, +{"Icaron", 0x01CF}, +{"Icircle", 0x24BE}, +{"Icircumflex", 0x00CE}, +{"Icircumflexsmall", 0xF7EE}, +{"Icyrillic", 0x0406}, +{"Idblgrave", 0x0208}, +{"Idieresis", 0x00CF}, +{"Idieresisacute", 0x1E2E}, +{"Idieresiscyrillic", 0x04E4}, +{"Idieresissmall", 0xF7EF}, +{"Idot", 0x0130}, +{"Idotaccent", 0x0130}, +{"Idotbelow", 0x1ECA}, +{"Iebrevecyrillic", 0x04D6}, +{"Iecyrillic", 0x0415}, +{"Ifraktur", 0x2111}, +{"Igrave", 0x00CC}, +{"Igravesmall", 0xF7EC}, +{"Ihookabove", 0x1EC8}, +{"Iicyrillic", 0x0418}, +{"Iinvertedbreve", 0x020A}, +{"Iishortcyrillic", 0x0419}, +{"Imacron", 0x012A}, +{"Imacroncyrillic", 0x04E2}, +{"Imonospace", 0xFF29}, +{"Iniarmenian", 0x053B}, +{"Iocyrillic", 0x0401}, +{"Iogonek", 0x012E}, +{"Iota", 0x0399}, +{"Iotaafrican", 0x0196}, +{"Iotadieresis", 0x03AA}, +{"Iotatonos", 0x038A}, +{"Ismall", 0xF769}, +{"Istroke", 0x0197}, +{"Itilde", 0x0128}, +{"Itildebelow", 0x1E2C}, +{"Izhitsacyrillic", 0x0474}, +{"Izhitsadblgravecyrillic", 0x0476}, +{"J", 0x004A}, +{"Jaarmenian", 0x0541}, +{"Jcircle", 0x24BF}, +{"Jcircumflex", 0x0134}, +{"Jecyrillic", 0x0408}, +{"Jheharmenian", 0x054B}, +{"Jmonospace", 0xFF2A}, +{"Jsmall", 0xF76A}, +{"K", 0x004B}, +{"KBsquare", 0x3385}, +{"KKsquare", 0x33CD}, +{"Kabashkircyrillic", 0x04A0}, +{"Kacute", 0x1E30}, +{"Kacyrillic", 0x041A}, +{"Kadescendercyrillic", 0x049A}, +{"Kahookcyrillic", 0x04C3}, +{"Kappa", 0x039A}, +{"Kastrokecyrillic", 0x049E}, +{"Kaverticalstrokecyrillic", 0x049C}, +{"Kcaron", 0x01E8}, +{"Kcedilla", 0x0136}, +{"Kcircle", 0x24C0}, +{"Kcommaaccent", 0x0136}, +{"Kdotbelow", 0x1E32}, +{"Keharmenian", 0x0554}, +{"Kenarmenian", 0x053F}, +{"Khacyrillic", 0x0425}, +{"Kheicoptic", 0x03E6}, +{"Khook", 0x0198}, +{"Kjecyrillic", 0x040C}, +{"Klinebelow", 0x1E34}, +{"Kmonospace", 0xFF2B}, +{"Koppacyrillic", 0x0480}, +{"Koppagreek", 0x03DE}, +{"Ksicyrillic", 0x046E}, +{"Ksmall", 0xF76B}, +{"L", 0x004C}, +{"LJ", 0x01C7}, +{"LL", 0xF6BF}, +{"Lacute", 0x0139}, +{"Lambda", 0x039B}, +{"Lcaron", 0x013D}, +{"Lcedilla", 0x013B}, +{"Lcircle", 0x24C1}, +{"Lcircumflexbelow", 0x1E3C}, +{"Lcommaaccent", 0x013B}, +{"Ldot", 0x013F}, +{"Ldotaccent", 0x013F}, +{"Ldotbelow", 0x1E36}, +{"Ldotbelowmacron", 0x1E38}, +{"Liwnarmenian", 0x053C}, +{"Lj", 0x01C8}, +{"Ljecyrillic", 0x0409}, +{"Llinebelow", 0x1E3A}, +{"Lmonospace", 0xFF2C}, +{"Lslash", 0x0141}, +{"Lslashsmall", 0xF6F9}, +{"Lsmall", 0xF76C}, +{"M", 0x004D}, +{"MBsquare", 0x3386}, +{"Macron", 0xF6D0}, +{"Macronsmall", 0xF7AF}, +{"Macute", 0x1E3E}, +{"Mcircle", 0x24C2}, +{"Mdotaccent", 0x1E40}, +{"Mdotbelow", 0x1E42}, +{"Menarmenian", 0x0544}, +{"Mmonospace", 0xFF2D}, +{"Msmall", 0xF76D}, +{"Mturned", 0x019C}, +{"Mu", 0x039C}, +{"N", 0x004E}, +{"NJ", 0x01CA}, +{"Nacute", 0x0143}, +{"Ncaron", 0x0147}, +{"Ncedilla", 0x0145}, +{"Ncircle", 0x24C3}, +{"Ncircumflexbelow", 0x1E4A}, +{"Ncommaaccent", 0x0145}, +{"Ndotaccent", 0x1E44}, +{"Ndotbelow", 0x1E46}, +{"Nhookleft", 0x019D}, +{"Nineroman", 0x2168}, +{"Nj", 0x01CB}, +{"Njecyrillic", 0x040A}, +{"Nlinebelow", 0x1E48}, +{"Nmonospace", 0xFF2E}, +{"Nowarmenian", 0x0546}, +{"Nsmall", 0xF76E}, +{"Ntilde", 0x00D1}, +{"Ntildesmall", 0xF7F1}, +{"Nu", 0x039D}, +{"O", 0x004F}, +{"OE", 0x0152}, +{"OEsmall", 0xF6FA}, +{"Oacute", 0x00D3}, +{"Oacutesmall", 0xF7F3}, +{"Obarredcyrillic", 0x04E8}, +{"Obarreddieresiscyrillic", 0x04EA}, +{"Obreve", 0x014E}, +{"Ocaron", 0x01D1}, +{"Ocenteredtilde", 0x019F}, +{"Ocircle", 0x24C4}, +{"Ocircumflex", 0x00D4}, +{"Ocircumflexacute", 0x1ED0}, +{"Ocircumflexdotbelow", 0x1ED8}, +{"Ocircumflexgrave", 0x1ED2}, +{"Ocircumflexhookabove", 0x1ED4}, +{"Ocircumflexsmall", 0xF7F4}, +{"Ocircumflextilde", 0x1ED6}, +{"Ocyrillic", 0x041E}, +{"Odblacute", 0x0150}, +{"Odblgrave", 0x020C}, +{"Odieresis", 0x00D6}, +{"Odieresiscyrillic", 0x04E6}, +{"Odieresissmall", 0xF7F6}, +{"Odotbelow", 0x1ECC}, +{"Ogoneksmall", 0xF6FB}, +{"Ograve", 0x00D2}, +{"Ogravesmall", 0xF7F2}, +{"Oharmenian", 0x0555}, +{"Ohm", 0x2126}, +{"Ohookabove", 0x1ECE}, +{"Ohorn", 0x01A0}, +{"Ohornacute", 0x1EDA}, +{"Ohorndotbelow", 0x1EE2}, +{"Ohorngrave", 0x1EDC}, +{"Ohornhookabove", 0x1EDE}, +{"Ohorntilde", 0x1EE0}, +{"Ohungarumlaut", 0x0150}, +{"Oi", 0x01A2}, +{"Oinvertedbreve", 0x020E}, +{"Omacron", 0x014C}, +{"Omacronacute", 0x1E52}, +{"Omacrongrave", 0x1E50}, +{"Omega", 0x2126}, +{"Omegacyrillic", 0x0460}, +{"Omegagreek", 0x03A9}, +{"Omegaroundcyrillic", 0x047A}, +{"Omegatitlocyrillic", 0x047C}, +{"Omegatonos", 0x038F}, +{"Omicron", 0x039F}, +{"Omicrontonos", 0x038C}, +{"Omonospace", 0xFF2F}, +{"Oneroman", 0x2160}, +{"Oogonek", 0x01EA}, +{"Oogonekmacron", 0x01EC}, +{"Oopen", 0x0186}, +{"Oslash", 0x00D8}, +{"Oslashacute", 0x01FE}, +{"Oslashsmall", 0xF7F8}, +{"Osmall", 0xF76F}, +{"Ostrokeacute", 0x01FE}, +{"Otcyrillic", 0x047E}, +{"Otilde", 0x00D5}, +{"Otildeacute", 0x1E4C}, +{"Otildedieresis", 0x1E4E}, +{"Otildesmall", 0xF7F5}, +{"P", 0x0050}, +{"Pacute", 0x1E54}, +{"Pcircle", 0x24C5}, +{"Pdotaccent", 0x1E56}, +{"Pecyrillic", 0x041F}, +{"Peharmenian", 0x054A}, +{"Pemiddlehookcyrillic", 0x04A6}, +{"Phi", 0x03A6}, +{"Phook", 0x01A4}, +{"Pi", 0x03A0}, +{"Piwrarmenian", 0x0553}, +{"Pmonospace", 0xFF30}, +{"Psi", 0x03A8}, +{"Psicyrillic", 0x0470}, +{"Psmall", 0xF770}, +{"Q", 0x0051}, +{"Qcircle", 0x24C6}, +{"Qmonospace", 0xFF31}, +{"Qsmall", 0xF771}, +{"R", 0x0052}, +{"Raarmenian", 0x054C}, +{"Racute", 0x0154}, +{"Rcaron", 0x0158}, +{"Rcedilla", 0x0156}, +{"Rcircle", 0x24C7}, +{"Rcommaaccent", 0x0156}, +{"Rdblgrave", 0x0210}, +{"Rdotaccent", 0x1E58}, +{"Rdotbelow", 0x1E5A}, +{"Rdotbelowmacron", 0x1E5C}, +{"Reharmenian", 0x0550}, +{"Rfraktur", 0x211C}, +{"Rho", 0x03A1}, +{"Ringsmall", 0xF6FC}, +{"Rinvertedbreve", 0x0212}, +{"Rlinebelow", 0x1E5E}, +{"Rmonospace", 0xFF32}, +{"Rsmall", 0xF772}, +{"Rsmallinverted", 0x0281}, +{"Rsmallinvertedsuperior", 0x02B6}, +{"S", 0x0053}, +{"SF010000", 0x250C}, +{"SF020000", 0x2514}, +{"SF030000", 0x2510}, +{"SF040000", 0x2518}, +{"SF050000", 0x253C}, +{"SF060000", 0x252C}, +{"SF070000", 0x2534}, +{"SF080000", 0x251C}, +{"SF090000", 0x2524}, +{"SF100000", 0x2500}, +{"SF110000", 0x2502}, +{"SF190000", 0x2561}, +{"SF200000", 0x2562}, +{"SF210000", 0x2556}, +{"SF220000", 0x2555}, +{"SF230000", 0x2563}, +{"SF240000", 0x2551}, +{"SF250000", 0x2557}, +{"SF260000", 0x255D}, +{"SF270000", 0x255C}, +{"SF280000", 0x255B}, +{"SF360000", 0x255E}, +{"SF370000", 0x255F}, +{"SF380000", 0x255A}, +{"SF390000", 0x2554}, +{"SF400000", 0x2569}, +{"SF410000", 0x2566}, +{"SF420000", 0x2560}, +{"SF430000", 0x2550}, +{"SF440000", 0x256C}, +{"SF450000", 0x2567}, +{"SF460000", 0x2568}, +{"SF470000", 0x2564}, +{"SF480000", 0x2565}, +{"SF490000", 0x2559}, +{"SF500000", 0x2558}, +{"SF510000", 0x2552}, +{"SF520000", 0x2553}, +{"SF530000", 0x256B}, +{"SF540000", 0x256A}, +{"Sacute", 0x015A}, +{"Sacutedotaccent", 0x1E64}, +{"Sampigreek", 0x03E0}, +{"Scaron", 0x0160}, +{"Scarondotaccent", 0x1E66}, +{"Scaronsmall", 0xF6FD}, +{"Scedilla", 0x015E}, +{"Schwa", 0x018F}, +{"Schwacyrillic", 0x04D8}, +{"Schwadieresiscyrillic", 0x04DA}, +{"Scircle", 0x24C8}, +{"Scircumflex", 0x015C}, +{"Scommaaccent", 0x0218}, +{"Sdotaccent", 0x1E60}, +{"Sdotbelow", 0x1E62}, +{"Sdotbelowdotaccent", 0x1E68}, +{"Seharmenian", 0x054D}, +{"Sevenroman", 0x2166}, +{"Shaarmenian", 0x0547}, +{"Shacyrillic", 0x0428}, +{"Shchacyrillic", 0x0429}, +{"Sheicoptic", 0x03E2}, +{"Shhacyrillic", 0x04BA}, +{"Shimacoptic", 0x03EC}, +{"Sigma", 0x03A3}, +{"Sixroman", 0x2165}, +{"Smonospace", 0xFF33}, +{"Softsigncyrillic", 0x042C}, +{"Ssmall", 0xF773}, +{"Stigmagreek", 0x03DA}, +{"T", 0x0054}, +{"Tau", 0x03A4}, +{"Tbar", 0x0166}, +{"Tcaron", 0x0164}, +{"Tcedilla", 0x0162}, +{"Tcircle", 0x24C9}, +{"Tcircumflexbelow", 0x1E70}, +{"Tcommaaccent", 0x0162}, +{"Tdotaccent", 0x1E6A}, +{"Tdotbelow", 0x1E6C}, +{"Tecyrillic", 0x0422}, +{"Tedescendercyrillic", 0x04AC}, +{"Tenroman", 0x2169}, +{"Tetsecyrillic", 0x04B4}, +{"Theta", 0x0398}, +{"Thook", 0x01AC}, +{"Thorn", 0x00DE}, +{"Thornsmall", 0xF7FE}, +{"Threeroman", 0x2162}, +{"Tildesmall", 0xF6FE}, +{"Tiwnarmenian", 0x054F}, +{"Tlinebelow", 0x1E6E}, +{"Tmonospace", 0xFF34}, +{"Toarmenian", 0x0539}, +{"Tonefive", 0x01BC}, +{"Tonesix", 0x0184}, +{"Tonetwo", 0x01A7}, +{"Tretroflexhook", 0x01AE}, +{"Tsecyrillic", 0x0426}, +{"Tshecyrillic", 0x040B}, +{"Tsmall", 0xF774}, +{"Twelveroman", 0x216B}, +{"Tworoman", 0x2161}, +{"U", 0x0055}, +{"Uacute", 0x00DA}, +{"Uacutesmall", 0xF7FA}, +{"Ubreve", 0x016C}, +{"Ucaron", 0x01D3}, +{"Ucircle", 0x24CA}, +{"Ucircumflex", 0x00DB}, +{"Ucircumflexbelow", 0x1E76}, +{"Ucircumflexsmall", 0xF7FB}, +{"Ucyrillic", 0x0423}, +{"Udblacute", 0x0170}, +{"Udblgrave", 0x0214}, +{"Udieresis", 0x00DC}, +{"Udieresisacute", 0x01D7}, +{"Udieresisbelow", 0x1E72}, +{"Udieresiscaron", 0x01D9}, +{"Udieresiscyrillic", 0x04F0}, +{"Udieresisgrave", 0x01DB}, +{"Udieresismacron", 0x01D5}, +{"Udieresissmall", 0xF7FC}, +{"Udotbelow", 0x1EE4}, +{"Ugrave", 0x00D9}, +{"Ugravesmall", 0xF7F9}, +{"Uhookabove", 0x1EE6}, +{"Uhorn", 0x01AF}, +{"Uhornacute", 0x1EE8}, +{"Uhorndotbelow", 0x1EF0}, +{"Uhorngrave", 0x1EEA}, +{"Uhornhookabove", 0x1EEC}, +{"Uhorntilde", 0x1EEE}, +{"Uhungarumlaut", 0x0170}, +{"Uhungarumlautcyrillic", 0x04F2}, +{"Uinvertedbreve", 0x0216}, +{"Ukcyrillic", 0x0478}, +{"Umacron", 0x016A}, +{"Umacroncyrillic", 0x04EE}, +{"Umacrondieresis", 0x1E7A}, +{"Umonospace", 0xFF35}, +{"Uogonek", 0x0172}, +{"Upsilon", 0x03A5}, +{"Upsilon1", 0x03D2}, +{"Upsilonacutehooksymbolgreek", 0x03D3}, +{"Upsilonafrican", 0x01B1}, +{"Upsilondieresis", 0x03AB}, +{"Upsilondieresishooksymbolgreek", 0x03D4}, +{"Upsilonhooksymbol", 0x03D2}, +{"Upsilontonos", 0x038E}, +{"Uring", 0x016E}, +{"Ushortcyrillic", 0x040E}, +{"Usmall", 0xF775}, +{"Ustraightcyrillic", 0x04AE}, +{"Ustraightstrokecyrillic", 0x04B0}, +{"Utilde", 0x0168}, +{"Utildeacute", 0x1E78}, +{"Utildebelow", 0x1E74}, +{"V", 0x0056}, +{"Vcircle", 0x24CB}, +{"Vdotbelow", 0x1E7E}, +{"Vecyrillic", 0x0412}, +{"Vewarmenian", 0x054E}, +{"Vhook", 0x01B2}, +{"Vmonospace", 0xFF36}, +{"Voarmenian", 0x0548}, +{"Vsmall", 0xF776}, +{"Vtilde", 0x1E7C}, +{"W", 0x0057}, +{"Wacute", 0x1E82}, +{"Wcircle", 0x24CC}, +{"Wcircumflex", 0x0174}, +{"Wdieresis", 0x1E84}, +{"Wdotaccent", 0x1E86}, +{"Wdotbelow", 0x1E88}, +{"Wgrave", 0x1E80}, +{"Wmonospace", 0xFF37}, +{"Wsmall", 0xF777}, +{"X", 0x0058}, +{"Xcircle", 0x24CD}, +{"Xdieresis", 0x1E8C}, +{"Xdotaccent", 0x1E8A}, +{"Xeharmenian", 0x053D}, +{"Xi", 0x039E}, +{"Xmonospace", 0xFF38}, +{"Xsmall", 0xF778}, +{"Y", 0x0059}, +{"Yacute", 0x00DD}, +{"Yacutesmall", 0xF7FD}, +{"Yatcyrillic", 0x0462}, +{"Ycircle", 0x24CE}, +{"Ycircumflex", 0x0176}, +{"Ydieresis", 0x0178}, +{"Ydieresissmall", 0xF7FF}, +{"Ydotaccent", 0x1E8E}, +{"Ydotbelow", 0x1EF4}, +{"Yericyrillic", 0x042B}, +{"Yerudieresiscyrillic", 0x04F8}, +{"Ygrave", 0x1EF2}, +{"Yhook", 0x01B3}, +{"Yhookabove", 0x1EF6}, +{"Yiarmenian", 0x0545}, +{"Yicyrillic", 0x0407}, +{"Yiwnarmenian", 0x0552}, +{"Ymonospace", 0xFF39}, +{"Ysmall", 0xF779}, +{"Ytilde", 0x1EF8}, +{"Yusbigcyrillic", 0x046A}, +{"Yusbigiotifiedcyrillic", 0x046C}, +{"Yuslittlecyrillic", 0x0466}, +{"Yuslittleiotifiedcyrillic", 0x0468}, +{"Z", 0x005A}, +{"Zaarmenian", 0x0536}, +{"Zacute", 0x0179}, +{"Zcaron", 0x017D}, +{"Zcaronsmall", 0xF6FF}, +{"Zcircle", 0x24CF}, +{"Zcircumflex", 0x1E90}, +{"Zdot", 0x017B}, +{"Zdotaccent", 0x017B}, +{"Zdotbelow", 0x1E92}, +{"Zecyrillic", 0x0417}, +{"Zedescendercyrillic", 0x0498}, +{"Zedieresiscyrillic", 0x04DE}, +{"Zeta", 0x0396}, +{"Zhearmenian", 0x053A}, +{"Zhebrevecyrillic", 0x04C1}, +{"Zhecyrillic", 0x0416}, +{"Zhedescendercyrillic", 0x0496}, +{"Zhedieresiscyrillic", 0x04DC}, +{"Zlinebelow", 0x1E94}, +{"Zmonospace", 0xFF3A}, +{"Zsmall", 0xF77A}, +{"Zstroke", 0x01B5}, +{"a", 0x0061}, +{"aabengali", 0x0986}, +{"aacute", 0x00E1}, +{"aadeva", 0x0906}, +{"aagujarati", 0x0A86}, +{"aagurmukhi", 0x0A06}, +{"aamatragurmukhi", 0x0A3E}, +{"aarusquare", 0x3303}, +{"aavowelsignbengali", 0x09BE}, +{"aavowelsigndeva", 0x093E}, +{"aavowelsigngujarati", 0x0ABE}, +{"abbreviationmarkarmenian", 0x055F}, +{"abbreviationsigndeva", 0x0970}, +{"abengali", 0x0985}, +{"abopomofo", 0x311A}, +{"abreve", 0x0103}, +{"abreveacute", 0x1EAF}, +{"abrevecyrillic", 0x04D1}, +{"abrevedotbelow", 0x1EB7}, +{"abrevegrave", 0x1EB1}, +{"abrevehookabove", 0x1EB3}, +{"abrevetilde", 0x1EB5}, +{"acaron", 0x01CE}, +{"acircle", 0x24D0}, +{"acircumflex", 0x00E2}, +{"acircumflexacute", 0x1EA5}, +{"acircumflexdotbelow", 0x1EAD}, +{"acircumflexgrave", 0x1EA7}, +{"acircumflexhookabove", 0x1EA9}, +{"acircumflextilde", 0x1EAB}, +{"acute", 0x00B4}, +{"acutebelowcmb", 0x0317}, +{"acutecmb", 0x0301}, +{"acutecomb", 0x0301}, +{"acutedeva", 0x0954}, +{"acutelowmod", 0x02CF}, +{"acutetonecmb", 0x0341}, +{"acyrillic", 0x0430}, +{"adblgrave", 0x0201}, +{"addakgurmukhi", 0x0A71}, +{"adeva", 0x0905}, +{"adieresis", 0x00E4}, +{"adieresiscyrillic", 0x04D3}, +{"adieresismacron", 0x01DF}, +{"adotbelow", 0x1EA1}, +{"adotmacron", 0x01E1}, +{"ae", 0x00E6}, +{"aeacute", 0x01FD}, +{"aekorean", 0x3150}, +{"aemacron", 0x01E3}, +{"afii00208", 0x2015}, +{"afii08941", 0x20A4}, +{"afii10017", 0x0410}, +{"afii10018", 0x0411}, +{"afii10019", 0x0412}, +{"afii10020", 0x0413}, +{"afii10021", 0x0414}, +{"afii10022", 0x0415}, +{"afii10023", 0x0401}, +{"afii10024", 0x0416}, +{"afii10025", 0x0417}, +{"afii10026", 0x0418}, +{"afii10027", 0x0419}, +{"afii10028", 0x041A}, +{"afii10029", 0x041B}, +{"afii10030", 0x041C}, +{"afii10031", 0x041D}, +{"afii10032", 0x041E}, +{"afii10033", 0x041F}, +{"afii10034", 0x0420}, +{"afii10035", 0x0421}, +{"afii10036", 0x0422}, +{"afii10037", 0x0423}, +{"afii10038", 0x0424}, +{"afii10039", 0x0425}, +{"afii10040", 0x0426}, +{"afii10041", 0x0427}, +{"afii10042", 0x0428}, +{"afii10043", 0x0429}, +{"afii10044", 0x042A}, +{"afii10045", 0x042B}, +{"afii10046", 0x042C}, +{"afii10047", 0x042D}, +{"afii10048", 0x042E}, +{"afii10049", 0x042F}, +{"afii10050", 0x0490}, +{"afii10051", 0x0402}, +{"afii10052", 0x0403}, +{"afii10053", 0x0404}, +{"afii10054", 0x0405}, +{"afii10055", 0x0406}, +{"afii10056", 0x0407}, +{"afii10057", 0x0408}, +{"afii10058", 0x0409}, +{"afii10059", 0x040A}, +{"afii10060", 0x040B}, +{"afii10061", 0x040C}, +{"afii10062", 0x040E}, +{"afii10063", 0xF6C4}, +{"afii10064", 0xF6C5}, +{"afii10065", 0x0430}, +{"afii10066", 0x0431}, +{"afii10067", 0x0432}, +{"afii10068", 0x0433}, +{"afii10069", 0x0434}, +{"afii10070", 0x0435}, +{"afii10071", 0x0451}, +{"afii10072", 0x0436}, +{"afii10073", 0x0437}, +{"afii10074", 0x0438}, +{"afii10075", 0x0439}, +{"afii10076", 0x043A}, +{"afii10077", 0x043B}, +{"afii10078", 0x043C}, +{"afii10079", 0x043D}, +{"afii10080", 0x043E}, +{"afii10081", 0x043F}, +{"afii10082", 0x0440}, +{"afii10083", 0x0441}, +{"afii10084", 0x0442}, +{"afii10085", 0x0443}, +{"afii10086", 0x0444}, +{"afii10087", 0x0445}, +{"afii10088", 0x0446}, +{"afii10089", 0x0447}, +{"afii10090", 0x0448}, +{"afii10091", 0x0449}, +{"afii10092", 0x044A}, +{"afii10093", 0x044B}, +{"afii10094", 0x044C}, +{"afii10095", 0x044D}, +{"afii10096", 0x044E}, +{"afii10097", 0x044F}, +{"afii10098", 0x0491}, +{"afii10099", 0x0452}, +{"afii10100", 0x0453}, +{"afii10101", 0x0454}, +{"afii10102", 0x0455}, +{"afii10103", 0x0456}, +{"afii10104", 0x0457}, +{"afii10105", 0x0458}, +{"afii10106", 0x0459}, +{"afii10107", 0x045A}, +{"afii10108", 0x045B}, +{"afii10109", 0x045C}, +{"afii10110", 0x045E}, +{"afii10145", 0x040F}, +{"afii10146", 0x0462}, +{"afii10147", 0x0472}, +{"afii10148", 0x0474}, +{"afii10192", 0xF6C6}, +{"afii10193", 0x045F}, +{"afii10194", 0x0463}, +{"afii10195", 0x0473}, +{"afii10196", 0x0475}, +{"afii10831", 0xF6C7}, +{"afii10832", 0xF6C8}, +{"afii10846", 0x04D9}, +{"afii299", 0x200E}, +{"afii300", 0x200F}, +{"afii301", 0x200D}, +{"afii57381", 0x066A}, +{"afii57388", 0x060C}, +{"afii57392", 0x0660}, +{"afii57393", 0x0661}, +{"afii57394", 0x0662}, +{"afii57395", 0x0663}, +{"afii57396", 0x0664}, +{"afii57397", 0x0665}, +{"afii57398", 0x0666}, +{"afii57399", 0x0667}, +{"afii57400", 0x0668}, +{"afii57401", 0x0669}, +{"afii57403", 0x061B}, +{"afii57407", 0x061F}, +{"afii57409", 0x0621}, +{"afii57410", 0x0622}, +{"afii57411", 0x0623}, +{"afii57412", 0x0624}, +{"afii57413", 0x0625}, +{"afii57414", 0x0626}, +{"afii57415", 0x0627}, +{"afii57416", 0x0628}, +{"afii57417", 0x0629}, +{"afii57418", 0x062A}, +{"afii57419", 0x062B}, +{"afii57420", 0x062C}, +{"afii57421", 0x062D}, +{"afii57422", 0x062E}, +{"afii57423", 0x062F}, +{"afii57424", 0x0630}, +{"afii57425", 0x0631}, +{"afii57426", 0x0632}, +{"afii57427", 0x0633}, +{"afii57428", 0x0634}, +{"afii57429", 0x0635}, +{"afii57430", 0x0636}, +{"afii57431", 0x0637}, +{"afii57432", 0x0638}, +{"afii57433", 0x0639}, +{"afii57434", 0x063A}, +{"afii57440", 0x0640}, +{"afii57441", 0x0641}, +{"afii57442", 0x0642}, +{"afii57443", 0x0643}, +{"afii57444", 0x0644}, +{"afii57445", 0x0645}, +{"afii57446", 0x0646}, +{"afii57448", 0x0648}, +{"afii57449", 0x0649}, +{"afii57450", 0x064A}, +{"afii57451", 0x064B}, +{"afii57452", 0x064C}, +{"afii57453", 0x064D}, +{"afii57454", 0x064E}, +{"afii57455", 0x064F}, +{"afii57456", 0x0650}, +{"afii57457", 0x0651}, +{"afii57458", 0x0652}, +{"afii57470", 0x0647}, +{"afii57505", 0x06A4}, +{"afii57506", 0x067E}, +{"afii57507", 0x0686}, +{"afii57508", 0x0698}, +{"afii57509", 0x06AF}, +{"afii57511", 0x0679}, +{"afii57512", 0x0688}, +{"afii57513", 0x0691}, +{"afii57514", 0x06BA}, +{"afii57519", 0x06D2}, +{"afii57534", 0x06D5}, +{"afii57636", 0x20AA}, +{"afii57645", 0x05BE}, +{"afii57658", 0x05C3}, +{"afii57664", 0x05D0}, +{"afii57665", 0x05D1}, +{"afii57666", 0x05D2}, +{"afii57667", 0x05D3}, +{"afii57668", 0x05D4}, +{"afii57669", 0x05D5}, +{"afii57670", 0x05D6}, +{"afii57671", 0x05D7}, +{"afii57672", 0x05D8}, +{"afii57673", 0x05D9}, +{"afii57674", 0x05DA}, +{"afii57675", 0x05DB}, +{"afii57676", 0x05DC}, +{"afii57677", 0x05DD}, +{"afii57678", 0x05DE}, +{"afii57679", 0x05DF}, +{"afii57680", 0x05E0}, +{"afii57681", 0x05E1}, +{"afii57682", 0x05E2}, +{"afii57683", 0x05E3}, +{"afii57684", 0x05E4}, +{"afii57685", 0x05E5}, +{"afii57686", 0x05E6}, +{"afii57687", 0x05E7}, +{"afii57688", 0x05E8}, +{"afii57689", 0x05E9}, +{"afii57690", 0x05EA}, +{"afii57694", 0xFB2A}, +{"afii57695", 0xFB2B}, +{"afii57700", 0xFB4B}, +{"afii57705", 0xFB1F}, +{"afii57716", 0x05F0}, +{"afii57717", 0x05F1}, +{"afii57718", 0x05F2}, +{"afii57723", 0xFB35}, +{"afii57793", 0x05B4}, +{"afii57794", 0x05B5}, +{"afii57795", 0x05B6}, +{"afii57796", 0x05BB}, +{"afii57797", 0x05B8}, +{"afii57798", 0x05B7}, +{"afii57799", 0x05B0}, +{"afii57800", 0x05B2}, +{"afii57801", 0x05B1}, +{"afii57802", 0x05B3}, +{"afii57803", 0x05C2}, +{"afii57804", 0x05C1}, +{"afii57806", 0x05B9}, +{"afii57807", 0x05BC}, +{"afii57839", 0x05BD}, +{"afii57841", 0x05BF}, +{"afii57842", 0x05C0}, +{"afii57929", 0x02BC}, +{"afii61248", 0x2105}, +{"afii61289", 0x2113}, +{"afii61352", 0x2116}, +{"afii61573", 0x202C}, +{"afii61574", 0x202D}, +{"afii61575", 0x202E}, +{"afii61664", 0x200C}, +{"afii63167", 0x066D}, +{"afii64937", 0x02BD}, +{"agrave", 0x00E0}, +{"agujarati", 0x0A85}, +{"agurmukhi", 0x0A05}, +{"ahiragana", 0x3042}, +{"ahookabove", 0x1EA3}, +{"aibengali", 0x0990}, +{"aibopomofo", 0x311E}, +{"aideva", 0x0910}, +{"aiecyrillic", 0x04D5}, +{"aigujarati", 0x0A90}, +{"aigurmukhi", 0x0A10}, +{"aimatragurmukhi", 0x0A48}, +{"ainarabic", 0x0639}, +{"ainfinalarabic", 0xFECA}, +{"aininitialarabic", 0xFECB}, +{"ainmedialarabic", 0xFECC}, +{"ainvertedbreve", 0x0203}, +{"aivowelsignbengali", 0x09C8}, +{"aivowelsigndeva", 0x0948}, +{"aivowelsigngujarati", 0x0AC8}, +{"akatakana", 0x30A2}, +{"akatakanahalfwidth", 0xFF71}, +{"akorean", 0x314F}, +{"alef", 0x05D0}, +{"alefarabic", 0x0627}, +{"alefdageshhebrew", 0xFB30}, +{"aleffinalarabic", 0xFE8E}, +{"alefhamzaabovearabic", 0x0623}, +{"alefhamzaabovefinalarabic", 0xFE84}, +{"alefhamzabelowarabic", 0x0625}, +{"alefhamzabelowfinalarabic", 0xFE88}, +{"alefhebrew", 0x05D0}, +{"aleflamedhebrew", 0xFB4F}, +{"alefmaddaabovearabic", 0x0622}, +{"alefmaddaabovefinalarabic", 0xFE82}, +{"alefmaksuraarabic", 0x0649}, +{"alefmaksurafinalarabic", 0xFEF0}, +{"alefmaksurainitialarabic", 0xFEF3}, +{"alefmaksuramedialarabic", 0xFEF4}, +{"alefpatahhebrew", 0xFB2E}, +{"alefqamatshebrew", 0xFB2F}, +{"aleph", 0x2135}, +{"allequal", 0x224C}, +{"alpha", 0x03B1}, +{"alphatonos", 0x03AC}, +{"amacron", 0x0101}, +{"amonospace", 0xFF41}, +{"ampersand", 0x0026}, +{"ampersandmonospace", 0xFF06}, +{"ampersandsmall", 0xF726}, +{"amsquare", 0x33C2}, +{"anbopomofo", 0x3122}, +{"angbopomofo", 0x3124}, +{"angkhankhuthai", 0x0E5A}, +{"angle", 0x2220}, +{"anglebracketleft", 0x3008}, +{"anglebracketleftvertical", 0xFE3F}, +{"anglebracketright", 0x3009}, +{"anglebracketrightvertical", 0xFE40}, +{"angleleft", 0x2329}, +{"angleright", 0x232A}, +{"angstrom", 0x212B}, +{"anoteleia", 0x0387}, +{"anudattadeva", 0x0952}, +{"anusvarabengali", 0x0982}, +{"anusvaradeva", 0x0902}, +{"anusvaragujarati", 0x0A82}, +{"aogonek", 0x0105}, +{"apaatosquare", 0x3300}, +{"aparen", 0x249C}, +{"apostrophearmenian", 0x055A}, +{"apostrophemod", 0x02BC}, +{"apple", 0xF8FF}, +{"approaches", 0x2250}, +{"approxequal", 0x2248}, +{"approxequalorimage", 0x2252}, +{"approximatelyequal", 0x2245}, +{"araeaekorean", 0x318E}, +{"araeakorean", 0x318D}, +{"arc", 0x2312}, +{"arighthalfring", 0x1E9A}, +{"aring", 0x00E5}, +{"aringacute", 0x01FB}, +{"aringbelow", 0x1E01}, +{"arrowboth", 0x2194}, +{"arrowdashdown", 0x21E3}, +{"arrowdashleft", 0x21E0}, +{"arrowdashright", 0x21E2}, +{"arrowdashup", 0x21E1}, +{"arrowdblboth", 0x21D4}, +{"arrowdbldown", 0x21D3}, +{"arrowdblleft", 0x21D0}, +{"arrowdblright", 0x21D2}, +{"arrowdblup", 0x21D1}, +{"arrowdown", 0x2193}, +{"arrowdownleft", 0x2199}, +{"arrowdownright", 0x2198}, +{"arrowdownwhite", 0x21E9}, +{"arrowheaddownmod", 0x02C5}, +{"arrowheadleftmod", 0x02C2}, +{"arrowheadrightmod", 0x02C3}, +{"arrowheadupmod", 0x02C4}, +{"arrowhorizex", 0xF8E7}, +{"arrowleft", 0x2190}, +{"arrowleftdbl", 0x21D0}, +{"arrowleftdblstroke", 0x21CD}, +{"arrowleftoverright", 0x21C6}, +{"arrowleftwhite", 0x21E6}, +{"arrowright", 0x2192}, +{"arrowrightdblstroke", 0x21CF}, +{"arrowrightheavy", 0x279E}, +{"arrowrightoverleft", 0x21C4}, +{"arrowrightwhite", 0x21E8}, +{"arrowtableft", 0x21E4}, +{"arrowtabright", 0x21E5}, +{"arrowup", 0x2191}, +{"arrowupdn", 0x2195}, +{"arrowupdnbse", 0x21A8}, +{"arrowupdownbase", 0x21A8}, +{"arrowupleft", 0x2196}, +{"arrowupleftofdown", 0x21C5}, +{"arrowupright", 0x2197}, +{"arrowupwhite", 0x21E7}, +{"arrowvertex", 0xF8E6}, +{"asciicircum", 0x005E}, +{"asciicircummonospace", 0xFF3E}, +{"asciitilde", 0x007E}, +{"asciitildemonospace", 0xFF5E}, +{"ascript", 0x0251}, +{"ascriptturned", 0x0252}, +{"asmallhiragana", 0x3041}, +{"asmallkatakana", 0x30A1}, +{"asmallkatakanahalfwidth", 0xFF67}, +{"asterisk", 0x002A}, +{"asteriskaltonearabic", 0x066D}, +{"asteriskarabic", 0x066D}, +{"asteriskmath", 0x2217}, +{"asteriskmonospace", 0xFF0A}, +{"asterisksmall", 0xFE61}, +{"asterism", 0x2042}, +{"asuperior", 0xF6E9}, +{"asymptoticallyequal", 0x2243}, +{"at", 0x0040}, +{"atilde", 0x00E3}, +{"atmonospace", 0xFF20}, +{"atsmall", 0xFE6B}, +{"aturned", 0x0250}, +{"aubengali", 0x0994}, +{"aubopomofo", 0x3120}, +{"audeva", 0x0914}, +{"augujarati", 0x0A94}, +{"augurmukhi", 0x0A14}, +{"aulengthmarkbengali", 0x09D7}, +{"aumatragurmukhi", 0x0A4C}, +{"auvowelsignbengali", 0x09CC}, +{"auvowelsigndeva", 0x094C}, +{"auvowelsigngujarati", 0x0ACC}, +{"avagrahadeva", 0x093D}, +{"aybarmenian", 0x0561}, +{"ayin", 0x05E2}, +{"ayinaltonehebrew", 0xFB20}, +{"ayinhebrew", 0x05E2}, +{"b", 0x0062}, +{"babengali", 0x09AC}, +{"backslash", 0x005C}, +{"backslashmonospace", 0xFF3C}, +{"badeva", 0x092C}, +{"bagujarati", 0x0AAC}, +{"bagurmukhi", 0x0A2C}, +{"bahiragana", 0x3070}, +{"bahtthai", 0x0E3F}, +{"bakatakana", 0x30D0}, +{"bar", 0x007C}, +{"barmonospace", 0xFF5C}, +{"bbopomofo", 0x3105}, +{"bcircle", 0x24D1}, +{"bdotaccent", 0x1E03}, +{"bdotbelow", 0x1E05}, +{"beamedsixteenthnotes", 0x266C}, +{"because", 0x2235}, +{"becyrillic", 0x0431}, +{"beharabic", 0x0628}, +{"behfinalarabic", 0xFE90}, +{"behinitialarabic", 0xFE91}, +{"behiragana", 0x3079}, +{"behmedialarabic", 0xFE92}, +{"behmeeminitialarabic", 0xFC9F}, +{"behmeemisolatedarabic", 0xFC08}, +{"behnoonfinalarabic", 0xFC6D}, +{"bekatakana", 0x30D9}, +{"benarmenian", 0x0562}, +{"bet", 0x05D1}, +{"beta", 0x03B2}, +{"betasymbolgreek", 0x03D0}, +{"betdagesh", 0xFB31}, +{"betdageshhebrew", 0xFB31}, +{"bethebrew", 0x05D1}, +{"betrafehebrew", 0xFB4C}, +{"bhabengali", 0x09AD}, +{"bhadeva", 0x092D}, +{"bhagujarati", 0x0AAD}, +{"bhagurmukhi", 0x0A2D}, +{"bhook", 0x0253}, +{"bihiragana", 0x3073}, +{"bikatakana", 0x30D3}, +{"bilabialclick", 0x0298}, +{"bindigurmukhi", 0x0A02}, +{"birusquare", 0x3331}, +{"blackcircle", 0x25CF}, +{"blackdiamond", 0x25C6}, +{"blackdownpointingtriangle", 0x25BC}, +{"blackleftpointingpointer", 0x25C4}, +{"blackleftpointingtriangle", 0x25C0}, +{"blacklenticularbracketleft", 0x3010}, +{"blacklenticularbracketleftvertical", 0xFE3B}, +{"blacklenticularbracketright", 0x3011}, +{"blacklenticularbracketrightvertical", 0xFE3C}, +{"blacklowerlefttriangle", 0x25E3}, +{"blacklowerrighttriangle", 0x25E2}, +{"blackrectangle", 0x25AC}, +{"blackrightpointingpointer", 0x25BA}, +{"blackrightpointingtriangle", 0x25B6}, +{"blacksmallsquare", 0x25AA}, +{"blacksmilingface", 0x263B}, +{"blacksquare", 0x25A0}, +{"blackstar", 0x2605}, +{"blackupperlefttriangle", 0x25E4}, +{"blackupperrighttriangle", 0x25E5}, +{"blackuppointingsmalltriangle", 0x25B4}, +{"blackuppointingtriangle", 0x25B2}, +{"blank", 0x2423}, +{"blinebelow", 0x1E07}, +{"block", 0x2588}, +{"bmonospace", 0xFF42}, +{"bobaimaithai", 0x0E1A}, +{"bohiragana", 0x307C}, +{"bokatakana", 0x30DC}, +{"bparen", 0x249D}, +{"bqsquare", 0x33C3}, +{"braceex", 0xF8F4}, +{"braceleft", 0x007B}, +{"braceleftbt", 0xF8F3}, +{"braceleftmid", 0xF8F2}, +{"braceleftmonospace", 0xFF5B}, +{"braceleftsmall", 0xFE5B}, +{"bracelefttp", 0xF8F1}, +{"braceleftvertical", 0xFE37}, +{"braceright", 0x007D}, +{"bracerightbt", 0xF8FE}, +{"bracerightmid", 0xF8FD}, +{"bracerightmonospace", 0xFF5D}, +{"bracerightsmall", 0xFE5C}, +{"bracerighttp", 0xF8FC}, +{"bracerightvertical", 0xFE38}, +{"bracketleft", 0x005B}, +{"bracketleftbt", 0xF8F0}, +{"bracketleftex", 0xF8EF}, +{"bracketleftmonospace", 0xFF3B}, +{"bracketlefttp", 0xF8EE}, +{"bracketright", 0x005D}, +{"bracketrightbt", 0xF8FB}, +{"bracketrightex", 0xF8FA}, +{"bracketrightmonospace", 0xFF3D}, +{"bracketrighttp", 0xF8F9}, +{"breve", 0x02D8}, +{"brevebelowcmb", 0x032E}, +{"brevecmb", 0x0306}, +{"breveinvertedbelowcmb", 0x032F}, +{"breveinvertedcmb", 0x0311}, +{"breveinverteddoublecmb", 0x0361}, +{"bridgebelowcmb", 0x032A}, +{"bridgeinvertedbelowcmb", 0x033A}, +{"brokenbar", 0x00A6}, +{"bstroke", 0x0180}, +{"bsuperior", 0xF6EA}, +{"btopbar", 0x0183}, +{"buhiragana", 0x3076}, +{"bukatakana", 0x30D6}, +{"bullet", 0x2022}, +{"bulletinverse", 0x25D8}, +{"bulletoperator", 0x2219}, +{"bullseye", 0x25CE}, +{"c", 0x0063}, +{"caarmenian", 0x056E}, +{"cabengali", 0x099A}, +{"cacute", 0x0107}, +{"cadeva", 0x091A}, +{"cagujarati", 0x0A9A}, +{"cagurmukhi", 0x0A1A}, +{"calsquare", 0x3388}, +{"candrabindubengali", 0x0981}, +{"candrabinducmb", 0x0310}, +{"candrabindudeva", 0x0901}, +{"candrabindugujarati", 0x0A81}, +{"capslock", 0x21EA}, +{"careof", 0x2105}, +{"caron", 0x02C7}, +{"caronbelowcmb", 0x032C}, +{"caroncmb", 0x030C}, +{"carriagereturn", 0x21B5}, +{"cbopomofo", 0x3118}, +{"ccaron", 0x010D}, +{"ccedilla", 0x00E7}, +{"ccedillaacute", 0x1E09}, +{"ccircle", 0x24D2}, +{"ccircumflex", 0x0109}, +{"ccurl", 0x0255}, +{"cdot", 0x010B}, +{"cdotaccent", 0x010B}, +{"cdsquare", 0x33C5}, +{"cedilla", 0x00B8}, +{"cedillacmb", 0x0327}, +{"cent", 0x00A2}, +{"centigrade", 0x2103}, +{"centinferior", 0xF6DF}, +{"centmonospace", 0xFFE0}, +{"centoldstyle", 0xF7A2}, +{"centsuperior", 0xF6E0}, +{"chaarmenian", 0x0579}, +{"chabengali", 0x099B}, +{"chadeva", 0x091B}, +{"chagujarati", 0x0A9B}, +{"chagurmukhi", 0x0A1B}, +{"chbopomofo", 0x3114}, +{"cheabkhasiancyrillic", 0x04BD}, +{"checkmark", 0x2713}, +{"checyrillic", 0x0447}, +{"chedescenderabkhasiancyrillic", 0x04BF}, +{"chedescendercyrillic", 0x04B7}, +{"chedieresiscyrillic", 0x04F5}, +{"cheharmenian", 0x0573}, +{"chekhakassiancyrillic", 0x04CC}, +{"cheverticalstrokecyrillic", 0x04B9}, +{"chi", 0x03C7}, +{"chieuchacirclekorean", 0x3277}, +{"chieuchaparenkorean", 0x3217}, +{"chieuchcirclekorean", 0x3269}, +{"chieuchkorean", 0x314A}, +{"chieuchparenkorean", 0x3209}, +{"chochangthai", 0x0E0A}, +{"chochanthai", 0x0E08}, +{"chochingthai", 0x0E09}, +{"chochoethai", 0x0E0C}, +{"chook", 0x0188}, +{"cieucacirclekorean", 0x3276}, +{"cieucaparenkorean", 0x3216}, +{"cieuccirclekorean", 0x3268}, +{"cieuckorean", 0x3148}, +{"cieucparenkorean", 0x3208}, +{"cieucuparenkorean", 0x321C}, +{"circle", 0x25CB}, +{"circlemultiply", 0x2297}, +{"circleot", 0x2299}, +{"circleplus", 0x2295}, +{"circlepostalmark", 0x3036}, +{"circlewithlefthalfblack", 0x25D0}, +{"circlewithrighthalfblack", 0x25D1}, +{"circumflex", 0x02C6}, +{"circumflexbelowcmb", 0x032D}, +{"circumflexcmb", 0x0302}, +{"clear", 0x2327}, +{"clickalveolar", 0x01C2}, +{"clickdental", 0x01C0}, +{"clicklateral", 0x01C1}, +{"clickretroflex", 0x01C3}, +{"club", 0x2663}, +{"clubsuitblack", 0x2663}, +{"clubsuitwhite", 0x2667}, +{"cmcubedsquare", 0x33A4}, +{"cmonospace", 0xFF43}, +{"cmsquaredsquare", 0x33A0}, +{"coarmenian", 0x0581}, +{"colon", 0x003A}, +{"colonmonetary", 0x20A1}, +{"colonmonospace", 0xFF1A}, +{"colonsign", 0x20A1}, +{"colonsmall", 0xFE55}, +{"colontriangularhalfmod", 0x02D1}, +{"colontriangularmod", 0x02D0}, +{"comma", 0x002C}, +{"commaabovecmb", 0x0313}, +{"commaaboverightcmb", 0x0315}, +{"commaaccent", 0xF6C3}, +{"commaarabic", 0x060C}, +{"commaarmenian", 0x055D}, +{"commainferior", 0xF6E1}, +{"commamonospace", 0xFF0C}, +{"commareversedabovecmb", 0x0314}, +{"commareversedmod", 0x02BD}, +{"commasmall", 0xFE50}, +{"commasuperior", 0xF6E2}, +{"commaturnedabovecmb", 0x0312}, +{"commaturnedmod", 0x02BB}, +{"compass", 0x263C}, +{"congruent", 0x2245}, +{"contourintegral", 0x222E}, +{"control", 0x2303}, +{"controlACK", 0x0006}, +{"controlBEL", 0x0007}, +{"controlBS", 0x0008}, +{"controlCAN", 0x0018}, +{"controlCR", 0x000D}, +{"controlDC1", 0x0011}, +{"controlDC2", 0x0012}, +{"controlDC3", 0x0013}, +{"controlDC4", 0x0014}, +{"controlDEL", 0x007F}, +{"controlDLE", 0x0010}, +{"controlEM", 0x0019}, +{"controlENQ", 0x0005}, +{"controlEOT", 0x0004}, +{"controlESC", 0x001B}, +{"controlETB", 0x0017}, +{"controlETX", 0x0003}, +{"controlFF", 0x000C}, +{"controlFS", 0x001C}, +{"controlGS", 0x001D}, +{"controlHT", 0x0009}, +{"controlLF", 0x000A}, +{"controlNAK", 0x0015}, +{"controlRS", 0x001E}, +{"controlSI", 0x000F}, +{"controlSO", 0x000E}, +{"controlSOT", 0x0002}, +{"controlSTX", 0x0001}, +{"controlSUB", 0x001A}, +{"controlSYN", 0x0016}, +{"controlUS", 0x001F}, +{"controlVT", 0x000B}, +{"copyright", 0x00A9}, +{"copyrightsans", 0xF8E9}, +{"copyrightserif", 0xF6D9}, +{"cornerbracketleft", 0x300C}, +{"cornerbracketlefthalfwidth", 0xFF62}, +{"cornerbracketleftvertical", 0xFE41}, +{"cornerbracketright", 0x300D}, +{"cornerbracketrighthalfwidth", 0xFF63}, +{"cornerbracketrightvertical", 0xFE42}, +{"corporationsquare", 0x337F}, +{"cosquare", 0x33C7}, +{"coverkgsquare", 0x33C6}, +{"cparen", 0x249E}, +{"cruzeiro", 0x20A2}, +{"cstretched", 0x0297}, +{"curlyand", 0x22CF}, +{"curlyor", 0x22CE}, +{"currency", 0x00A4}, +{"cyrBreve", 0xF6D1}, +{"cyrFlex", 0xF6D2}, +{"cyrbreve", 0xF6D4}, +{"cyrflex", 0xF6D5}, +{"d", 0x0064}, +{"daarmenian", 0x0564}, +{"dabengali", 0x09A6}, +{"dadarabic", 0x0636}, +{"dadeva", 0x0926}, +{"dadfinalarabic", 0xFEBE}, +{"dadinitialarabic", 0xFEBF}, +{"dadmedialarabic", 0xFEC0}, +{"dagesh", 0x05BC}, +{"dageshhebrew", 0x05BC}, +{"dagger", 0x2020}, +{"daggerdbl", 0x2021}, +{"dagujarati", 0x0AA6}, +{"dagurmukhi", 0x0A26}, +{"dahiragana", 0x3060}, +{"dakatakana", 0x30C0}, +{"dalarabic", 0x062F}, +{"dalet", 0x05D3}, +{"daletdagesh", 0xFB33}, +{"daletdageshhebrew", 0xFB33}, +{"dalethebrew", 0x05D3}, +{"dalfinalarabic", 0xFEAA}, +{"dammaarabic", 0x064F}, +{"dammalowarabic", 0x064F}, +{"dammatanaltonearabic", 0x064C}, +{"dammatanarabic", 0x064C}, +{"danda", 0x0964}, +{"dargahebrew", 0x05A7}, +{"dargalefthebrew", 0x05A7}, +{"dasiapneumatacyrilliccmb", 0x0485}, +{"dblGrave", 0xF6D3}, +{"dblanglebracketleft", 0x300A}, +{"dblanglebracketleftvertical", 0xFE3D}, +{"dblanglebracketright", 0x300B}, +{"dblanglebracketrightvertical", 0xFE3E}, +{"dblarchinvertedbelowcmb", 0x032B}, +{"dblarrowleft", 0x21D4}, +{"dblarrowright", 0x21D2}, +{"dbldanda", 0x0965}, +{"dblgrave", 0xF6D6}, +{"dblgravecmb", 0x030F}, +{"dblintegral", 0x222C}, +{"dbllowline", 0x2017}, +{"dbllowlinecmb", 0x0333}, +{"dbloverlinecmb", 0x033F}, +{"dblprimemod", 0x02BA}, +{"dblverticalbar", 0x2016}, +{"dblverticallineabovecmb", 0x030E}, +{"dbopomofo", 0x3109}, +{"dbsquare", 0x33C8}, +{"dcaron", 0x010F}, +{"dcedilla", 0x1E11}, +{"dcircle", 0x24D3}, +{"dcircumflexbelow", 0x1E13}, +{"dcroat", 0x0111}, +{"ddabengali", 0x09A1}, +{"ddadeva", 0x0921}, +{"ddagujarati", 0x0AA1}, +{"ddagurmukhi", 0x0A21}, +{"ddalarabic", 0x0688}, +{"ddalfinalarabic", 0xFB89}, +{"dddhadeva", 0x095C}, +{"ddhabengali", 0x09A2}, +{"ddhadeva", 0x0922}, +{"ddhagujarati", 0x0AA2}, +{"ddhagurmukhi", 0x0A22}, +{"ddotaccent", 0x1E0B}, +{"ddotbelow", 0x1E0D}, +{"decimalseparatorarabic", 0x066B}, +{"decimalseparatorpersian", 0x066B}, +{"decyrillic", 0x0434}, +{"degree", 0x00B0}, +{"dehihebrew", 0x05AD}, +{"dehiragana", 0x3067}, +{"deicoptic", 0x03EF}, +{"dekatakana", 0x30C7}, +{"deleteleft", 0x232B}, +{"deleteright", 0x2326}, +{"delta", 0x03B4}, +{"deltaturned", 0x018D}, +{"denominatorminusonenumeratorbengali", 0x09F8}, +{"dezh", 0x02A4}, +{"dhabengali", 0x09A7}, +{"dhadeva", 0x0927}, +{"dhagujarati", 0x0AA7}, +{"dhagurmukhi", 0x0A27}, +{"dhook", 0x0257}, +{"dialytikatonos", 0x0385}, +{"dialytikatonoscmb", 0x0344}, +{"diamond", 0x2666}, +{"diamondsuitwhite", 0x2662}, +{"dieresis", 0x00A8}, +{"dieresisacute", 0xF6D7}, +{"dieresisbelowcmb", 0x0324}, +{"dieresiscmb", 0x0308}, +{"dieresisgrave", 0xF6D8}, +{"dieresistonos", 0x0385}, +{"dihiragana", 0x3062}, +{"dikatakana", 0x30C2}, +{"dittomark", 0x3003}, +{"divide", 0x00F7}, +{"divides", 0x2223}, +{"divisionslash", 0x2215}, +{"djecyrillic", 0x0452}, +{"dkshade", 0x2593}, +{"dlinebelow", 0x1E0F}, +{"dlsquare", 0x3397}, +{"dmacron", 0x0111}, +{"dmonospace", 0xFF44}, +{"dnblock", 0x2584}, +{"dochadathai", 0x0E0E}, +{"dodekthai", 0x0E14}, +{"dohiragana", 0x3069}, +{"dokatakana", 0x30C9}, +{"dollar", 0x0024}, +{"dollarinferior", 0xF6E3}, +{"dollarmonospace", 0xFF04}, +{"dollaroldstyle", 0xF724}, +{"dollarsmall", 0xFE69}, +{"dollarsuperior", 0xF6E4}, +{"dong", 0x20AB}, +{"dorusquare", 0x3326}, +{"dotaccent", 0x02D9}, +{"dotaccentcmb", 0x0307}, +{"dotbelowcmb", 0x0323}, +{"dotbelowcomb", 0x0323}, +{"dotkatakana", 0x30FB}, +{"dotlessi", 0x0131}, +{"dotlessj", 0xF6BE}, +{"dotlessjstrokehook", 0x0284}, +{"dotmath", 0x22C5}, +{"dottedcircle", 0x25CC}, +{"doubleyodpatah", 0xFB1F}, +{"doubleyodpatahhebrew", 0xFB1F}, +{"downtackbelowcmb", 0x031E}, +{"downtackmod", 0x02D5}, +{"dparen", 0x249F}, +{"dsuperior", 0xF6EB}, +{"dtail", 0x0256}, +{"dtopbar", 0x018C}, +{"duhiragana", 0x3065}, +{"dukatakana", 0x30C5}, +{"dz", 0x01F3}, +{"dzaltone", 0x02A3}, +{"dzcaron", 0x01C6}, +{"dzcurl", 0x02A5}, +{"dzeabkhasiancyrillic", 0x04E1}, +{"dzecyrillic", 0x0455}, +{"dzhecyrillic", 0x045F}, +{"e", 0x0065}, +{"eacute", 0x00E9}, +{"earth", 0x2641}, +{"ebengali", 0x098F}, +{"ebopomofo", 0x311C}, +{"ebreve", 0x0115}, +{"ecandradeva", 0x090D}, +{"ecandragujarati", 0x0A8D}, +{"ecandravowelsigndeva", 0x0945}, +{"ecandravowelsigngujarati", 0x0AC5}, +{"ecaron", 0x011B}, +{"ecedillabreve", 0x1E1D}, +{"echarmenian", 0x0565}, +{"echyiwnarmenian", 0x0587}, +{"ecircle", 0x24D4}, +{"ecircumflex", 0x00EA}, +{"ecircumflexacute", 0x1EBF}, +{"ecircumflexbelow", 0x1E19}, +{"ecircumflexdotbelow", 0x1EC7}, +{"ecircumflexgrave", 0x1EC1}, +{"ecircumflexhookabove", 0x1EC3}, +{"ecircumflextilde", 0x1EC5}, +{"ecyrillic", 0x0454}, +{"edblgrave", 0x0205}, +{"edeva", 0x090F}, +{"edieresis", 0x00EB}, +{"edot", 0x0117}, +{"edotaccent", 0x0117}, +{"edotbelow", 0x1EB9}, +{"eegurmukhi", 0x0A0F}, +{"eematragurmukhi", 0x0A47}, +{"efcyrillic", 0x0444}, +{"egrave", 0x00E8}, +{"egujarati", 0x0A8F}, +{"eharmenian", 0x0567}, +{"ehbopomofo", 0x311D}, +{"ehiragana", 0x3048}, +{"ehookabove", 0x1EBB}, +{"eibopomofo", 0x311F}, +{"eight", 0x0038}, +{"eightarabic", 0x0668}, +{"eightbengali", 0x09EE}, +{"eightcircle", 0x2467}, +{"eightcircleinversesansserif", 0x2791}, +{"eightdeva", 0x096E}, +{"eighteencircle", 0x2471}, +{"eighteenparen", 0x2485}, +{"eighteenperiod", 0x2499}, +{"eightgujarati", 0x0AEE}, +{"eightgurmukhi", 0x0A6E}, +{"eighthackarabic", 0x0668}, +{"eighthangzhou", 0x3028}, +{"eighthnotebeamed", 0x266B}, +{"eightideographicparen", 0x3227}, +{"eightinferior", 0x2088}, +{"eightmonospace", 0xFF18}, +{"eightoldstyle", 0xF738}, +{"eightparen", 0x247B}, +{"eightperiod", 0x248F}, +{"eightpersian", 0x06F8}, +{"eightroman", 0x2177}, +{"eightsuperior", 0x2078}, +{"eightthai", 0x0E58}, +{"einvertedbreve", 0x0207}, +{"eiotifiedcyrillic", 0x0465}, +{"ekatakana", 0x30A8}, +{"ekatakanahalfwidth", 0xFF74}, +{"ekonkargurmukhi", 0x0A74}, +{"ekorean", 0x3154}, +{"elcyrillic", 0x043B}, +{"element", 0x2208}, +{"elevencircle", 0x246A}, +{"elevenparen", 0x247E}, +{"elevenperiod", 0x2492}, +{"elevenroman", 0x217A}, +{"ellipsis", 0x2026}, +{"ellipsisvertical", 0x22EE}, +{"emacron", 0x0113}, +{"emacronacute", 0x1E17}, +{"emacrongrave", 0x1E15}, +{"emcyrillic", 0x043C}, +{"emdash", 0x2014}, +{"emdashvertical", 0xFE31}, +{"emonospace", 0xFF45}, +{"emphasismarkarmenian", 0x055B}, +{"emptyset", 0x2205}, +{"enbopomofo", 0x3123}, +{"encyrillic", 0x043D}, +{"endash", 0x2013}, +{"endashvertical", 0xFE32}, +{"endescendercyrillic", 0x04A3}, +{"eng", 0x014B}, +{"engbopomofo", 0x3125}, +{"enghecyrillic", 0x04A5}, +{"enhookcyrillic", 0x04C8}, +{"enspace", 0x2002}, +{"eogonek", 0x0119}, +{"eokorean", 0x3153}, +{"eopen", 0x025B}, +{"eopenclosed", 0x029A}, +{"eopenreversed", 0x025C}, +{"eopenreversedclosed", 0x025E}, +{"eopenreversedhook", 0x025D}, +{"eparen", 0x24A0}, +{"epsilon", 0x03B5}, +{"epsilontonos", 0x03AD}, +{"equal", 0x003D}, +{"equalmonospace", 0xFF1D}, +{"equalsmall", 0xFE66}, +{"equalsuperior", 0x207C}, +{"equivalence", 0x2261}, +{"erbopomofo", 0x3126}, +{"ercyrillic", 0x0440}, +{"ereversed", 0x0258}, +{"ereversedcyrillic", 0x044D}, +{"escyrillic", 0x0441}, +{"esdescendercyrillic", 0x04AB}, +{"esh", 0x0283}, +{"eshcurl", 0x0286}, +{"eshortdeva", 0x090E}, +{"eshortvowelsigndeva", 0x0946}, +{"eshreversedloop", 0x01AA}, +{"eshsquatreversed", 0x0285}, +{"esmallhiragana", 0x3047}, +{"esmallkatakana", 0x30A7}, +{"esmallkatakanahalfwidth", 0xFF6A}, +{"estimated", 0x212E}, +{"esuperior", 0xF6EC}, +{"eta", 0x03B7}, +{"etarmenian", 0x0568}, +{"etatonos", 0x03AE}, +{"eth", 0x00F0}, +{"etilde", 0x1EBD}, +{"etildebelow", 0x1E1B}, +{"etnahtafoukhhebrew", 0x0591}, +{"etnahtafoukhlefthebrew", 0x0591}, +{"etnahtahebrew", 0x0591}, +{"etnahtalefthebrew", 0x0591}, +{"eturned", 0x01DD}, +{"eukorean", 0x3161}, +{"euro", 0x20AC}, +{"evowelsignbengali", 0x09C7}, +{"evowelsigndeva", 0x0947}, +{"evowelsigngujarati", 0x0AC7}, +{"exclam", 0x0021}, +{"exclamarmenian", 0x055C}, +{"exclamdbl", 0x203C}, +{"exclamdown", 0x00A1}, +{"exclamdownsmall", 0xF7A1}, +{"exclammonospace", 0xFF01}, +{"exclamsmall", 0xF721}, +{"existential", 0x2203}, +{"ezh", 0x0292}, +{"ezhcaron", 0x01EF}, +{"ezhcurl", 0x0293}, +{"ezhreversed", 0x01B9}, +{"ezhtail", 0x01BA}, +{"f", 0x0066}, +{"fadeva", 0x095E}, +{"fagurmukhi", 0x0A5E}, +{"fahrenheit", 0x2109}, +{"fathaarabic", 0x064E}, +{"fathalowarabic", 0x064E}, +{"fathatanarabic", 0x064B}, +{"fbopomofo", 0x3108}, +{"fcircle", 0x24D5}, +{"fdotaccent", 0x1E1F}, +{"feharabic", 0x0641}, +{"feharmenian", 0x0586}, +{"fehfinalarabic", 0xFED2}, +{"fehinitialarabic", 0xFED3}, +{"fehmedialarabic", 0xFED4}, +{"feicoptic", 0x03E5}, +{"female", 0x2640}, +{"ff", 0xFB00}, +{"ffi", 0xFB03}, +{"ffl", 0xFB04}, +{"fi", 0xFB01}, +{"fifteencircle", 0x246E}, +{"fifteenparen", 0x2482}, +{"fifteenperiod", 0x2496}, +{"figuredash", 0x2012}, +{"filledbox", 0x25A0}, +{"filledrect", 0x25AC}, +{"finalkaf", 0x05DA}, +{"finalkafdagesh", 0xFB3A}, +{"finalkafdageshhebrew", 0xFB3A}, +{"finalkafhebrew", 0x05DA}, +{"finalmem", 0x05DD}, +{"finalmemhebrew", 0x05DD}, +{"finalnun", 0x05DF}, +{"finalnunhebrew", 0x05DF}, +{"finalpe", 0x05E3}, +{"finalpehebrew", 0x05E3}, +{"finaltsadi", 0x05E5}, +{"finaltsadihebrew", 0x05E5}, +{"firsttonechinese", 0x02C9}, +{"fisheye", 0x25C9}, +{"fitacyrillic", 0x0473}, +{"five", 0x0035}, +{"fivearabic", 0x0665}, +{"fivebengali", 0x09EB}, +{"fivecircle", 0x2464}, +{"fivecircleinversesansserif", 0x278E}, +{"fivedeva", 0x096B}, +{"fiveeighths", 0x215D}, +{"fivegujarati", 0x0AEB}, +{"fivegurmukhi", 0x0A6B}, +{"fivehackarabic", 0x0665}, +{"fivehangzhou", 0x3025}, +{"fiveideographicparen", 0x3224}, +{"fiveinferior", 0x2085}, +{"fivemonospace", 0xFF15}, +{"fiveoldstyle", 0xF735}, +{"fiveparen", 0x2478}, +{"fiveperiod", 0x248C}, +{"fivepersian", 0x06F5}, +{"fiveroman", 0x2174}, +{"fivesuperior", 0x2075}, +{"fivethai", 0x0E55}, +{"fl", 0xFB02}, +{"florin", 0x0192}, +{"fmonospace", 0xFF46}, +{"fmsquare", 0x3399}, +{"fofanthai", 0x0E1F}, +{"fofathai", 0x0E1D}, +{"fongmanthai", 0x0E4F}, +{"forall", 0x2200}, +{"four", 0x0034}, +{"fourarabic", 0x0664}, +{"fourbengali", 0x09EA}, +{"fourcircle", 0x2463}, +{"fourcircleinversesansserif", 0x278D}, +{"fourdeva", 0x096A}, +{"fourgujarati", 0x0AEA}, +{"fourgurmukhi", 0x0A6A}, +{"fourhackarabic", 0x0664}, +{"fourhangzhou", 0x3024}, +{"fourideographicparen", 0x3223}, +{"fourinferior", 0x2084}, +{"fourmonospace", 0xFF14}, +{"fournumeratorbengali", 0x09F7}, +{"fouroldstyle", 0xF734}, +{"fourparen", 0x2477}, +{"fourperiod", 0x248B}, +{"fourpersian", 0x06F4}, +{"fourroman", 0x2173}, +{"foursuperior", 0x2074}, +{"fourteencircle", 0x246D}, +{"fourteenparen", 0x2481}, +{"fourteenperiod", 0x2495}, +{"fourthai", 0x0E54}, +{"fourthtonechinese", 0x02CB}, +{"fparen", 0x24A1}, +{"fraction", 0x2044}, +{"franc", 0x20A3}, +{"g", 0x0067}, +{"gabengali", 0x0997}, +{"gacute", 0x01F5}, +{"gadeva", 0x0917}, +{"gafarabic", 0x06AF}, +{"gaffinalarabic", 0xFB93}, +{"gafinitialarabic", 0xFB94}, +{"gafmedialarabic", 0xFB95}, +{"gagujarati", 0x0A97}, +{"gagurmukhi", 0x0A17}, +{"gahiragana", 0x304C}, +{"gakatakana", 0x30AC}, +{"gamma", 0x03B3}, +{"gammalatinsmall", 0x0263}, +{"gammasuperior", 0x02E0}, +{"gangiacoptic", 0x03EB}, +{"gbopomofo", 0x310D}, +{"gbreve", 0x011F}, +{"gcaron", 0x01E7}, +{"gcedilla", 0x0123}, +{"gcircle", 0x24D6}, +{"gcircumflex", 0x011D}, +{"gcommaaccent", 0x0123}, +{"gdot", 0x0121}, +{"gdotaccent", 0x0121}, +{"gecyrillic", 0x0433}, +{"gehiragana", 0x3052}, +{"gekatakana", 0x30B2}, +{"geometricallyequal", 0x2251}, +{"gereshaccenthebrew", 0x059C}, +{"gereshhebrew", 0x05F3}, +{"gereshmuqdamhebrew", 0x059D}, +{"germandbls", 0x00DF}, +{"gershayimaccenthebrew", 0x059E}, +{"gershayimhebrew", 0x05F4}, +{"getamark", 0x3013}, +{"ghabengali", 0x0998}, +{"ghadarmenian", 0x0572}, +{"ghadeva", 0x0918}, +{"ghagujarati", 0x0A98}, +{"ghagurmukhi", 0x0A18}, +{"ghainarabic", 0x063A}, +{"ghainfinalarabic", 0xFECE}, +{"ghaininitialarabic", 0xFECF}, +{"ghainmedialarabic", 0xFED0}, +{"ghemiddlehookcyrillic", 0x0495}, +{"ghestrokecyrillic", 0x0493}, +{"gheupturncyrillic", 0x0491}, +{"ghhadeva", 0x095A}, +{"ghhagurmukhi", 0x0A5A}, +{"ghook", 0x0260}, +{"ghzsquare", 0x3393}, +{"gihiragana", 0x304E}, +{"gikatakana", 0x30AE}, +{"gimarmenian", 0x0563}, +{"gimel", 0x05D2}, +{"gimeldagesh", 0xFB32}, +{"gimeldageshhebrew", 0xFB32}, +{"gimelhebrew", 0x05D2}, +{"gjecyrillic", 0x0453}, +{"glottalinvertedstroke", 0x01BE}, +{"glottalstop", 0x0294}, +{"glottalstopinverted", 0x0296}, +{"glottalstopmod", 0x02C0}, +{"glottalstopreversed", 0x0295}, +{"glottalstopreversedmod", 0x02C1}, +{"glottalstopreversedsuperior", 0x02E4}, +{"glottalstopstroke", 0x02A1}, +{"glottalstopstrokereversed", 0x02A2}, +{"gmacron", 0x1E21}, +{"gmonospace", 0xFF47}, +{"gohiragana", 0x3054}, +{"gokatakana", 0x30B4}, +{"gparen", 0x24A2}, +{"gpasquare", 0x33AC}, +{"gradient", 0x2207}, +{"grave", 0x0060}, +{"gravebelowcmb", 0x0316}, +{"gravecmb", 0x0300}, +{"gravecomb", 0x0300}, +{"gravedeva", 0x0953}, +{"gravelowmod", 0x02CE}, +{"gravemonospace", 0xFF40}, +{"gravetonecmb", 0x0340}, +{"greater", 0x003E}, +{"greaterequal", 0x2265}, +{"greaterequalorless", 0x22DB}, +{"greatermonospace", 0xFF1E}, +{"greaterorequivalent", 0x2273}, +{"greaterorless", 0x2277}, +{"greateroverequal", 0x2267}, +{"greatersmall", 0xFE65}, +{"gscript", 0x0261}, +{"gstroke", 0x01E5}, +{"guhiragana", 0x3050}, +{"guillemotleft", 0x00AB}, +{"guillemotright", 0x00BB}, +{"guilsinglleft", 0x2039}, +{"guilsinglright", 0x203A}, +{"gukatakana", 0x30B0}, +{"guramusquare", 0x3318}, +{"gysquare", 0x33C9}, +{"h", 0x0068}, +{"haabkhasiancyrillic", 0x04A9}, +{"haaltonearabic", 0x06C1}, +{"habengali", 0x09B9}, +{"hadescendercyrillic", 0x04B3}, +{"hadeva", 0x0939}, +{"hagujarati", 0x0AB9}, +{"hagurmukhi", 0x0A39}, +{"haharabic", 0x062D}, +{"hahfinalarabic", 0xFEA2}, +{"hahinitialarabic", 0xFEA3}, +{"hahiragana", 0x306F}, +{"hahmedialarabic", 0xFEA4}, +{"haitusquare", 0x332A}, +{"hakatakana", 0x30CF}, +{"hakatakanahalfwidth", 0xFF8A}, +{"halantgurmukhi", 0x0A4D}, +{"hamzaarabic", 0x0621}, +{"hamzalowarabic", 0x0621}, +{"hangulfiller", 0x3164}, +{"hardsigncyrillic", 0x044A}, +{"harpoonleftbarbup", 0x21BC}, +{"harpoonrightbarbup", 0x21C0}, +{"hasquare", 0x33CA}, +{"hatafpatah", 0x05B2}, +{"hatafpatah16", 0x05B2}, +{"hatafpatah23", 0x05B2}, +{"hatafpatah2f", 0x05B2}, +{"hatafpatahhebrew", 0x05B2}, +{"hatafpatahnarrowhebrew", 0x05B2}, +{"hatafpatahquarterhebrew", 0x05B2}, +{"hatafpatahwidehebrew", 0x05B2}, +{"hatafqamats", 0x05B3}, +{"hatafqamats1b", 0x05B3}, +{"hatafqamats28", 0x05B3}, +{"hatafqamats34", 0x05B3}, +{"hatafqamatshebrew", 0x05B3}, +{"hatafqamatsnarrowhebrew", 0x05B3}, +{"hatafqamatsquarterhebrew", 0x05B3}, +{"hatafqamatswidehebrew", 0x05B3}, +{"hatafsegol", 0x05B1}, +{"hatafsegol17", 0x05B1}, +{"hatafsegol24", 0x05B1}, +{"hatafsegol30", 0x05B1}, +{"hatafsegolhebrew", 0x05B1}, +{"hatafsegolnarrowhebrew", 0x05B1}, +{"hatafsegolquarterhebrew", 0x05B1}, +{"hatafsegolwidehebrew", 0x05B1}, +{"hbar", 0x0127}, +{"hbopomofo", 0x310F}, +{"hbrevebelow", 0x1E2B}, +{"hcedilla", 0x1E29}, +{"hcircle", 0x24D7}, +{"hcircumflex", 0x0125}, +{"hdieresis", 0x1E27}, +{"hdotaccent", 0x1E23}, +{"hdotbelow", 0x1E25}, +{"he", 0x05D4}, +{"heart", 0x2665}, +{"heartsuitblack", 0x2665}, +{"heartsuitwhite", 0x2661}, +{"hedagesh", 0xFB34}, +{"hedageshhebrew", 0xFB34}, +{"hehaltonearabic", 0x06C1}, +{"heharabic", 0x0647}, +{"hehebrew", 0x05D4}, +{"hehfinalaltonearabic", 0xFBA7}, +{"hehfinalalttwoarabic", 0xFEEA}, +{"hehfinalarabic", 0xFEEA}, +{"hehhamzaabovefinalarabic", 0xFBA5}, +{"hehhamzaaboveisolatedarabic", 0xFBA4}, +{"hehinitialaltonearabic", 0xFBA8}, +{"hehinitialarabic", 0xFEEB}, +{"hehiragana", 0x3078}, +{"hehmedialaltonearabic", 0xFBA9}, +{"hehmedialarabic", 0xFEEC}, +{"heiseierasquare", 0x337B}, +{"hekatakana", 0x30D8}, +{"hekatakanahalfwidth", 0xFF8D}, +{"hekutaarusquare", 0x3336}, +{"henghook", 0x0267}, +{"herutusquare", 0x3339}, +{"het", 0x05D7}, +{"hethebrew", 0x05D7}, +{"hhook", 0x0266}, +{"hhooksuperior", 0x02B1}, +{"hieuhacirclekorean", 0x327B}, +{"hieuhaparenkorean", 0x321B}, +{"hieuhcirclekorean", 0x326D}, +{"hieuhkorean", 0x314E}, +{"hieuhparenkorean", 0x320D}, +{"hihiragana", 0x3072}, +{"hikatakana", 0x30D2}, +{"hikatakanahalfwidth", 0xFF8B}, +{"hiriq", 0x05B4}, +{"hiriq14", 0x05B4}, +{"hiriq21", 0x05B4}, +{"hiriq2d", 0x05B4}, +{"hiriqhebrew", 0x05B4}, +{"hiriqnarrowhebrew", 0x05B4}, +{"hiriqquarterhebrew", 0x05B4}, +{"hiriqwidehebrew", 0x05B4}, +{"hlinebelow", 0x1E96}, +{"hmonospace", 0xFF48}, +{"hoarmenian", 0x0570}, +{"hohipthai", 0x0E2B}, +{"hohiragana", 0x307B}, +{"hokatakana", 0x30DB}, +{"hokatakanahalfwidth", 0xFF8E}, +{"holam", 0x05B9}, +{"holam19", 0x05B9}, +{"holam26", 0x05B9}, +{"holam32", 0x05B9}, +{"holamhebrew", 0x05B9}, +{"holamnarrowhebrew", 0x05B9}, +{"holamquarterhebrew", 0x05B9}, +{"holamwidehebrew", 0x05B9}, +{"honokhukthai", 0x0E2E}, +{"hookabovecomb", 0x0309}, +{"hookcmb", 0x0309}, +{"hookpalatalizedbelowcmb", 0x0321}, +{"hookretroflexbelowcmb", 0x0322}, +{"hoonsquare", 0x3342}, +{"horicoptic", 0x03E9}, +{"horizontalbar", 0x2015}, +{"horncmb", 0x031B}, +{"hotsprings", 0x2668}, +{"house", 0x2302}, +{"hparen", 0x24A3}, +{"hsuperior", 0x02B0}, +{"hturned", 0x0265}, +{"huhiragana", 0x3075}, +{"huiitosquare", 0x3333}, +{"hukatakana", 0x30D5}, +{"hukatakanahalfwidth", 0xFF8C}, +{"hungarumlaut", 0x02DD}, +{"hungarumlautcmb", 0x030B}, +{"hv", 0x0195}, +{"hyphen", 0x002D}, +{"hypheninferior", 0xF6E5}, +{"hyphenmonospace", 0xFF0D}, +{"hyphensmall", 0xFE63}, +{"hyphensuperior", 0xF6E6}, +{"hyphentwo", 0x2010}, +{"i", 0x0069}, +{"iacute", 0x00ED}, +{"iacyrillic", 0x044F}, +{"ibengali", 0x0987}, +{"ibopomofo", 0x3127}, +{"ibreve", 0x012D}, +{"icaron", 0x01D0}, +{"icircle", 0x24D8}, +{"icircumflex", 0x00EE}, +{"icyrillic", 0x0456}, +{"idblgrave", 0x0209}, +{"ideographearthcircle", 0x328F}, +{"ideographfirecircle", 0x328B}, +{"ideographicallianceparen", 0x323F}, +{"ideographiccallparen", 0x323A}, +{"ideographiccentrecircle", 0x32A5}, +{"ideographicclose", 0x3006}, +{"ideographiccomma", 0x3001}, +{"ideographiccommaleft", 0xFF64}, +{"ideographiccongratulationparen", 0x3237}, +{"ideographiccorrectcircle", 0x32A3}, +{"ideographicearthparen", 0x322F}, +{"ideographicenterpriseparen", 0x323D}, +{"ideographicexcellentcircle", 0x329D}, +{"ideographicfestivalparen", 0x3240}, +{"ideographicfinancialcircle", 0x3296}, +{"ideographicfinancialparen", 0x3236}, +{"ideographicfireparen", 0x322B}, +{"ideographichaveparen", 0x3232}, +{"ideographichighcircle", 0x32A4}, +{"ideographiciterationmark", 0x3005}, +{"ideographiclaborcircle", 0x3298}, +{"ideographiclaborparen", 0x3238}, +{"ideographicleftcircle", 0x32A7}, +{"ideographiclowcircle", 0x32A6}, +{"ideographicmedicinecircle", 0x32A9}, +{"ideographicmetalparen", 0x322E}, +{"ideographicmoonparen", 0x322A}, +{"ideographicnameparen", 0x3234}, +{"ideographicperiod", 0x3002}, +{"ideographicprintcircle", 0x329E}, +{"ideographicreachparen", 0x3243}, +{"ideographicrepresentparen", 0x3239}, +{"ideographicresourceparen", 0x323E}, +{"ideographicrightcircle", 0x32A8}, +{"ideographicsecretcircle", 0x3299}, +{"ideographicselfparen", 0x3242}, +{"ideographicsocietyparen", 0x3233}, +{"ideographicspace", 0x3000}, +{"ideographicspecialparen", 0x3235}, +{"ideographicstockparen", 0x3231}, +{"ideographicstudyparen", 0x323B}, +{"ideographicsunparen", 0x3230}, +{"ideographicsuperviseparen", 0x323C}, +{"ideographicwaterparen", 0x322C}, +{"ideographicwoodparen", 0x322D}, +{"ideographiczero", 0x3007}, +{"ideographmetalcircle", 0x328E}, +{"ideographmooncircle", 0x328A}, +{"ideographnamecircle", 0x3294}, +{"ideographsuncircle", 0x3290}, +{"ideographwatercircle", 0x328C}, +{"ideographwoodcircle", 0x328D}, +{"ideva", 0x0907}, +{"idieresis", 0x00EF}, +{"idieresisacute", 0x1E2F}, +{"idieresiscyrillic", 0x04E5}, +{"idotbelow", 0x1ECB}, +{"iebrevecyrillic", 0x04D7}, +{"iecyrillic", 0x0435}, +{"ieungacirclekorean", 0x3275}, +{"ieungaparenkorean", 0x3215}, +{"ieungcirclekorean", 0x3267}, +{"ieungkorean", 0x3147}, +{"ieungparenkorean", 0x3207}, +{"igrave", 0x00EC}, +{"igujarati", 0x0A87}, +{"igurmukhi", 0x0A07}, +{"ihiragana", 0x3044}, +{"ihookabove", 0x1EC9}, +{"iibengali", 0x0988}, +{"iicyrillic", 0x0438}, +{"iideva", 0x0908}, +{"iigujarati", 0x0A88}, +{"iigurmukhi", 0x0A08}, +{"iimatragurmukhi", 0x0A40}, +{"iinvertedbreve", 0x020B}, +{"iishortcyrillic", 0x0439}, +{"iivowelsignbengali", 0x09C0}, +{"iivowelsigndeva", 0x0940}, +{"iivowelsigngujarati", 0x0AC0}, +{"ij", 0x0133}, +{"ikatakana", 0x30A4}, +{"ikatakanahalfwidth", 0xFF72}, +{"ikorean", 0x3163}, +{"ilde", 0x02DC}, +{"iluyhebrew", 0x05AC}, +{"imacron", 0x012B}, +{"imacroncyrillic", 0x04E3}, +{"imageorapproximatelyequal", 0x2253}, +{"imatragurmukhi", 0x0A3F}, +{"imonospace", 0xFF49}, +{"increment", 0x2206}, +{"infinity", 0x221E}, +{"iniarmenian", 0x056B}, +{"integral", 0x222B}, +{"integralbottom", 0x2321}, +{"integralbt", 0x2321}, +{"integralex", 0xF8F5}, +{"integraltop", 0x2320}, +{"integraltp", 0x2320}, +{"intersection", 0x2229}, +{"intisquare", 0x3305}, +{"invbullet", 0x25D8}, +{"invcircle", 0x25D9}, +{"invsmileface", 0x263B}, +{"iocyrillic", 0x0451}, +{"iogonek", 0x012F}, +{"iota", 0x03B9}, +{"iotadieresis", 0x03CA}, +{"iotadieresistonos", 0x0390}, +{"iotalatin", 0x0269}, +{"iotatonos", 0x03AF}, +{"iparen", 0x24A4}, +{"irigurmukhi", 0x0A72}, +{"ismallhiragana", 0x3043}, +{"ismallkatakana", 0x30A3}, +{"ismallkatakanahalfwidth", 0xFF68}, +{"issharbengali", 0x09FA}, +{"istroke", 0x0268}, +{"isuperior", 0xF6ED}, +{"iterationhiragana", 0x309D}, +{"iterationkatakana", 0x30FD}, +{"itilde", 0x0129}, +{"itildebelow", 0x1E2D}, +{"iubopomofo", 0x3129}, +{"iucyrillic", 0x044E}, +{"ivowelsignbengali", 0x09BF}, +{"ivowelsigndeva", 0x093F}, +{"ivowelsigngujarati", 0x0ABF}, +{"izhitsacyrillic", 0x0475}, +{"izhitsadblgravecyrillic", 0x0477}, +{"j", 0x006A}, +{"jaarmenian", 0x0571}, +{"jabengali", 0x099C}, +{"jadeva", 0x091C}, +{"jagujarati", 0x0A9C}, +{"jagurmukhi", 0x0A1C}, +{"jbopomofo", 0x3110}, +{"jcaron", 0x01F0}, +{"jcircle", 0x24D9}, +{"jcircumflex", 0x0135}, +{"jcrossedtail", 0x029D}, +{"jdotlessstroke", 0x025F}, +{"jecyrillic", 0x0458}, +{"jeemarabic", 0x062C}, +{"jeemfinalarabic", 0xFE9E}, +{"jeeminitialarabic", 0xFE9F}, +{"jeemmedialarabic", 0xFEA0}, +{"jeharabic", 0x0698}, +{"jehfinalarabic", 0xFB8B}, +{"jhabengali", 0x099D}, +{"jhadeva", 0x091D}, +{"jhagujarati", 0x0A9D}, +{"jhagurmukhi", 0x0A1D}, +{"jheharmenian", 0x057B}, +{"jis", 0x3004}, +{"jmonospace", 0xFF4A}, +{"jparen", 0x24A5}, +{"jsuperior", 0x02B2}, +{"k", 0x006B}, +{"kabashkircyrillic", 0x04A1}, +{"kabengali", 0x0995}, +{"kacute", 0x1E31}, +{"kacyrillic", 0x043A}, +{"kadescendercyrillic", 0x049B}, +{"kadeva", 0x0915}, +{"kaf", 0x05DB}, +{"kafarabic", 0x0643}, +{"kafdagesh", 0xFB3B}, +{"kafdageshhebrew", 0xFB3B}, +{"kaffinalarabic", 0xFEDA}, +{"kafhebrew", 0x05DB}, +{"kafinitialarabic", 0xFEDB}, +{"kafmedialarabic", 0xFEDC}, +{"kafrafehebrew", 0xFB4D}, +{"kagujarati", 0x0A95}, +{"kagurmukhi", 0x0A15}, +{"kahiragana", 0x304B}, +{"kahookcyrillic", 0x04C4}, +{"kakatakana", 0x30AB}, +{"kakatakanahalfwidth", 0xFF76}, +{"kappa", 0x03BA}, +{"kappasymbolgreek", 0x03F0}, +{"kapyeounmieumkorean", 0x3171}, +{"kapyeounphieuphkorean", 0x3184}, +{"kapyeounpieupkorean", 0x3178}, +{"kapyeounssangpieupkorean", 0x3179}, +{"karoriisquare", 0x330D}, +{"kashidaautoarabic", 0x0640}, +{"kashidaautonosidebearingarabic", 0x0640}, +{"kasmallkatakana", 0x30F5}, +{"kasquare", 0x3384}, +{"kasraarabic", 0x0650}, +{"kasratanarabic", 0x064D}, +{"kastrokecyrillic", 0x049F}, +{"katahiraprolongmarkhalfwidth", 0xFF70}, +{"kaverticalstrokecyrillic", 0x049D}, +{"kbopomofo", 0x310E}, +{"kcalsquare", 0x3389}, +{"kcaron", 0x01E9}, +{"kcedilla", 0x0137}, +{"kcircle", 0x24DA}, +{"kcommaaccent", 0x0137}, +{"kdotbelow", 0x1E33}, +{"keharmenian", 0x0584}, +{"kehiragana", 0x3051}, +{"kekatakana", 0x30B1}, +{"kekatakanahalfwidth", 0xFF79}, +{"kenarmenian", 0x056F}, +{"kesmallkatakana", 0x30F6}, +{"kgreenlandic", 0x0138}, +{"khabengali", 0x0996}, +{"khacyrillic", 0x0445}, +{"khadeva", 0x0916}, +{"khagujarati", 0x0A96}, +{"khagurmukhi", 0x0A16}, +{"khaharabic", 0x062E}, +{"khahfinalarabic", 0xFEA6}, +{"khahinitialarabic", 0xFEA7}, +{"khahmedialarabic", 0xFEA8}, +{"kheicoptic", 0x03E7}, +{"khhadeva", 0x0959}, +{"khhagurmukhi", 0x0A59}, +{"khieukhacirclekorean", 0x3278}, +{"khieukhaparenkorean", 0x3218}, +{"khieukhcirclekorean", 0x326A}, +{"khieukhkorean", 0x314B}, +{"khieukhparenkorean", 0x320A}, +{"khokhaithai", 0x0E02}, +{"khokhonthai", 0x0E05}, +{"khokhuatthai", 0x0E03}, +{"khokhwaithai", 0x0E04}, +{"khomutthai", 0x0E5B}, +{"khook", 0x0199}, +{"khorakhangthai", 0x0E06}, +{"khzsquare", 0x3391}, +{"kihiragana", 0x304D}, +{"kikatakana", 0x30AD}, +{"kikatakanahalfwidth", 0xFF77}, +{"kiroguramusquare", 0x3315}, +{"kiromeetorusquare", 0x3316}, +{"kirosquare", 0x3314}, +{"kiyeokacirclekorean", 0x326E}, +{"kiyeokaparenkorean", 0x320E}, +{"kiyeokcirclekorean", 0x3260}, +{"kiyeokkorean", 0x3131}, +{"kiyeokparenkorean", 0x3200}, +{"kiyeoksioskorean", 0x3133}, +{"kjecyrillic", 0x045C}, +{"klinebelow", 0x1E35}, +{"klsquare", 0x3398}, +{"kmcubedsquare", 0x33A6}, +{"kmonospace", 0xFF4B}, +{"kmsquaredsquare", 0x33A2}, +{"kohiragana", 0x3053}, +{"kohmsquare", 0x33C0}, +{"kokaithai", 0x0E01}, +{"kokatakana", 0x30B3}, +{"kokatakanahalfwidth", 0xFF7A}, +{"kooposquare", 0x331E}, +{"koppacyrillic", 0x0481}, +{"koreanstandardsymbol", 0x327F}, +{"koroniscmb", 0x0343}, +{"kparen", 0x24A6}, +{"kpasquare", 0x33AA}, +{"ksicyrillic", 0x046F}, +{"ktsquare", 0x33CF}, +{"kturned", 0x029E}, +{"kuhiragana", 0x304F}, +{"kukatakana", 0x30AF}, +{"kukatakanahalfwidth", 0xFF78}, +{"kvsquare", 0x33B8}, +{"kwsquare", 0x33BE}, +{"l", 0x006C}, +{"labengali", 0x09B2}, +{"lacute", 0x013A}, +{"ladeva", 0x0932}, +{"lagujarati", 0x0AB2}, +{"lagurmukhi", 0x0A32}, +{"lakkhangyaothai", 0x0E45}, +{"lamaleffinalarabic", 0xFEFC}, +{"lamalefhamzaabovefinalarabic", 0xFEF8}, +{"lamalefhamzaaboveisolatedarabic", 0xFEF7}, +{"lamalefhamzabelowfinalarabic", 0xFEFA}, +{"lamalefhamzabelowisolatedarabic", 0xFEF9}, +{"lamalefisolatedarabic", 0xFEFB}, +{"lamalefmaddaabovefinalarabic", 0xFEF6}, +{"lamalefmaddaaboveisolatedarabic", 0xFEF5}, +{"lamarabic", 0x0644}, +{"lambda", 0x03BB}, +{"lambdastroke", 0x019B}, +{"lamed", 0x05DC}, +{"lameddagesh", 0xFB3C}, +{"lameddageshhebrew", 0xFB3C}, +{"lamedhebrew", 0x05DC}, +{"lamfinalarabic", 0xFEDE}, +{"lamhahinitialarabic", 0xFCCA}, +{"laminitialarabic", 0xFEDF}, +{"lamjeeminitialarabic", 0xFCC9}, +{"lamkhahinitialarabic", 0xFCCB}, +{"lamlamhehisolatedarabic", 0xFDF2}, +{"lammedialarabic", 0xFEE0}, +{"lammeemhahinitialarabic", 0xFD88}, +{"lammeeminitialarabic", 0xFCCC}, +{"largecircle", 0x25EF}, +{"lbar", 0x019A}, +{"lbelt", 0x026C}, +{"lbopomofo", 0x310C}, +{"lcaron", 0x013E}, +{"lcedilla", 0x013C}, +{"lcircle", 0x24DB}, +{"lcircumflexbelow", 0x1E3D}, +{"lcommaaccent", 0x013C}, +{"ldot", 0x0140}, +{"ldotaccent", 0x0140}, +{"ldotbelow", 0x1E37}, +{"ldotbelowmacron", 0x1E39}, +{"leftangleabovecmb", 0x031A}, +{"lefttackbelowcmb", 0x0318}, +{"less", 0x003C}, +{"lessequal", 0x2264}, +{"lessequalorgreater", 0x22DA}, +{"lessmonospace", 0xFF1C}, +{"lessorequivalent", 0x2272}, +{"lessorgreater", 0x2276}, +{"lessoverequal", 0x2266}, +{"lesssmall", 0xFE64}, +{"lezh", 0x026E}, +{"lfblock", 0x258C}, +{"lhookretroflex", 0x026D}, +{"lira", 0x20A4}, +{"liwnarmenian", 0x056C}, +{"lj", 0x01C9}, +{"ljecyrillic", 0x0459}, +{"ll", 0xF6C0}, +{"lladeva", 0x0933}, +{"llagujarati", 0x0AB3}, +{"llinebelow", 0x1E3B}, +{"llladeva", 0x0934}, +{"llvocalicbengali", 0x09E1}, +{"llvocalicdeva", 0x0961}, +{"llvocalicvowelsignbengali", 0x09E3}, +{"llvocalicvowelsigndeva", 0x0963}, +{"lmiddletilde", 0x026B}, +{"lmonospace", 0xFF4C}, +{"lmsquare", 0x33D0}, +{"lochulathai", 0x0E2C}, +{"logicaland", 0x2227}, +{"logicalnot", 0x00AC}, +{"logicalnotreversed", 0x2310}, +{"logicalor", 0x2228}, +{"lolingthai", 0x0E25}, +{"longs", 0x017F}, +{"lowlinecenterline", 0xFE4E}, +{"lowlinecmb", 0x0332}, +{"lowlinedashed", 0xFE4D}, +{"lozenge", 0x25CA}, +{"lparen", 0x24A7}, +{"lslash", 0x0142}, +{"lsquare", 0x2113}, +{"lsuperior", 0xF6EE}, +{"ltshade", 0x2591}, +{"luthai", 0x0E26}, +{"lvocalicbengali", 0x098C}, +{"lvocalicdeva", 0x090C}, +{"lvocalicvowelsignbengali", 0x09E2}, +{"lvocalicvowelsigndeva", 0x0962}, +{"lxsquare", 0x33D3}, +{"m", 0x006D}, +{"mabengali", 0x09AE}, +{"macron", 0x00AF}, +{"macronbelowcmb", 0x0331}, +{"macroncmb", 0x0304}, +{"macronlowmod", 0x02CD}, +{"macronmonospace", 0xFFE3}, +{"macute", 0x1E3F}, +{"madeva", 0x092E}, +{"magujarati", 0x0AAE}, +{"magurmukhi", 0x0A2E}, +{"mahapakhhebrew", 0x05A4}, +{"mahapakhlefthebrew", 0x05A4}, +{"mahiragana", 0x307E}, +{"maichattawalowleftthai", 0xF895}, +{"maichattawalowrightthai", 0xF894}, +{"maichattawathai", 0x0E4B}, +{"maichattawaupperleftthai", 0xF893}, +{"maieklowleftthai", 0xF88C}, +{"maieklowrightthai", 0xF88B}, +{"maiekthai", 0x0E48}, +{"maiekupperleftthai", 0xF88A}, +{"maihanakatleftthai", 0xF884}, +{"maihanakatthai", 0x0E31}, +{"maitaikhuleftthai", 0xF889}, +{"maitaikhuthai", 0x0E47}, +{"maitholowleftthai", 0xF88F}, +{"maitholowrightthai", 0xF88E}, +{"maithothai", 0x0E49}, +{"maithoupperleftthai", 0xF88D}, +{"maitrilowleftthai", 0xF892}, +{"maitrilowrightthai", 0xF891}, +{"maitrithai", 0x0E4A}, +{"maitriupperleftthai", 0xF890}, +{"maiyamokthai", 0x0E46}, +{"makatakana", 0x30DE}, +{"makatakanahalfwidth", 0xFF8F}, +{"male", 0x2642}, +{"mansyonsquare", 0x3347}, +{"maqafhebrew", 0x05BE}, +{"mars", 0x2642}, +{"masoracirclehebrew", 0x05AF}, +{"masquare", 0x3383}, +{"mbopomofo", 0x3107}, +{"mbsquare", 0x33D4}, +{"mcircle", 0x24DC}, +{"mcubedsquare", 0x33A5}, +{"mdotaccent", 0x1E41}, +{"mdotbelow", 0x1E43}, +{"meemarabic", 0x0645}, +{"meemfinalarabic", 0xFEE2}, +{"meeminitialarabic", 0xFEE3}, +{"meemmedialarabic", 0xFEE4}, +{"meemmeeminitialarabic", 0xFCD1}, +{"meemmeemisolatedarabic", 0xFC48}, +{"meetorusquare", 0x334D}, +{"mehiragana", 0x3081}, +{"meizierasquare", 0x337E}, +{"mekatakana", 0x30E1}, +{"mekatakanahalfwidth", 0xFF92}, +{"mem", 0x05DE}, +{"memdagesh", 0xFB3E}, +{"memdageshhebrew", 0xFB3E}, +{"memhebrew", 0x05DE}, +{"menarmenian", 0x0574}, +{"merkhahebrew", 0x05A5}, +{"merkhakefulahebrew", 0x05A6}, +{"merkhakefulalefthebrew", 0x05A6}, +{"merkhalefthebrew", 0x05A5}, +{"mhook", 0x0271}, +{"mhzsquare", 0x3392}, +{"middledotkatakanahalfwidth", 0xFF65}, +{"middot", 0x00B7}, +{"mieumacirclekorean", 0x3272}, +{"mieumaparenkorean", 0x3212}, +{"mieumcirclekorean", 0x3264}, +{"mieumkorean", 0x3141}, +{"mieumpansioskorean", 0x3170}, +{"mieumparenkorean", 0x3204}, +{"mieumpieupkorean", 0x316E}, +{"mieumsioskorean", 0x316F}, +{"mihiragana", 0x307F}, +{"mikatakana", 0x30DF}, +{"mikatakanahalfwidth", 0xFF90}, +{"minus", 0x2212}, +{"minusbelowcmb", 0x0320}, +{"minuscircle", 0x2296}, +{"minusmod", 0x02D7}, +{"minusplus", 0x2213}, +{"minute", 0x2032}, +{"miribaarusquare", 0x334A}, +{"mirisquare", 0x3349}, +{"mlonglegturned", 0x0270}, +{"mlsquare", 0x3396}, +{"mmcubedsquare", 0x33A3}, +{"mmonospace", 0xFF4D}, +{"mmsquaredsquare", 0x339F}, +{"mohiragana", 0x3082}, +{"mohmsquare", 0x33C1}, +{"mokatakana", 0x30E2}, +{"mokatakanahalfwidth", 0xFF93}, +{"molsquare", 0x33D6}, +{"momathai", 0x0E21}, +{"moverssquare", 0x33A7}, +{"moverssquaredsquare", 0x33A8}, +{"mparen", 0x24A8}, +{"mpasquare", 0x33AB}, +{"mssquare", 0x33B3}, +{"msuperior", 0xF6EF}, +{"mturned", 0x026F}, +{"mu", 0x00B5}, +{"mu1", 0x00B5}, +{"muasquare", 0x3382}, +{"muchgreater", 0x226B}, +{"muchless", 0x226A}, +{"mufsquare", 0x338C}, +{"mugreek", 0x03BC}, +{"mugsquare", 0x338D}, +{"muhiragana", 0x3080}, +{"mukatakana", 0x30E0}, +{"mukatakanahalfwidth", 0xFF91}, +{"mulsquare", 0x3395}, +{"multiply", 0x00D7}, +{"mumsquare", 0x339B}, +{"munahhebrew", 0x05A3}, +{"munahlefthebrew", 0x05A3}, +{"musicalnote", 0x266A}, +{"musicalnotedbl", 0x266B}, +{"musicflatsign", 0x266D}, +{"musicsharpsign", 0x266F}, +{"mussquare", 0x33B2}, +{"muvsquare", 0x33B6}, +{"muwsquare", 0x33BC}, +{"mvmegasquare", 0x33B9}, +{"mvsquare", 0x33B7}, +{"mwmegasquare", 0x33BF}, +{"mwsquare", 0x33BD}, +{"n", 0x006E}, +{"nabengali", 0x09A8}, +{"nabla", 0x2207}, +{"nacute", 0x0144}, +{"nadeva", 0x0928}, +{"nagujarati", 0x0AA8}, +{"nagurmukhi", 0x0A28}, +{"nahiragana", 0x306A}, +{"nakatakana", 0x30CA}, +{"nakatakanahalfwidth", 0xFF85}, +{"napostrophe", 0x0149}, +{"nasquare", 0x3381}, +{"nbopomofo", 0x310B}, +{"nbspace", 0x00A0}, +{"ncaron", 0x0148}, +{"ncedilla", 0x0146}, +{"ncircle", 0x24DD}, +{"ncircumflexbelow", 0x1E4B}, +{"ncommaaccent", 0x0146}, +{"ndotaccent", 0x1E45}, +{"ndotbelow", 0x1E47}, +{"nehiragana", 0x306D}, +{"nekatakana", 0x30CD}, +{"nekatakanahalfwidth", 0xFF88}, +{"newsheqelsign", 0x20AA}, +{"nfsquare", 0x338B}, +{"ngabengali", 0x0999}, +{"ngadeva", 0x0919}, +{"ngagujarati", 0x0A99}, +{"ngagurmukhi", 0x0A19}, +{"ngonguthai", 0x0E07}, +{"nhiragana", 0x3093}, +{"nhookleft", 0x0272}, +{"nhookretroflex", 0x0273}, +{"nieunacirclekorean", 0x326F}, +{"nieunaparenkorean", 0x320F}, +{"nieuncieuckorean", 0x3135}, +{"nieuncirclekorean", 0x3261}, +{"nieunhieuhkorean", 0x3136}, +{"nieunkorean", 0x3134}, +{"nieunpansioskorean", 0x3168}, +{"nieunparenkorean", 0x3201}, +{"nieunsioskorean", 0x3167}, +{"nieuntikeutkorean", 0x3166}, +{"nihiragana", 0x306B}, +{"nikatakana", 0x30CB}, +{"nikatakanahalfwidth", 0xFF86}, +{"nikhahitleftthai", 0xF899}, +{"nikhahitthai", 0x0E4D}, +{"nine", 0x0039}, +{"ninearabic", 0x0669}, +{"ninebengali", 0x09EF}, +{"ninecircle", 0x2468}, +{"ninecircleinversesansserif", 0x2792}, +{"ninedeva", 0x096F}, +{"ninegujarati", 0x0AEF}, +{"ninegurmukhi", 0x0A6F}, +{"ninehackarabic", 0x0669}, +{"ninehangzhou", 0x3029}, +{"nineideographicparen", 0x3228}, +{"nineinferior", 0x2089}, +{"ninemonospace", 0xFF19}, +{"nineoldstyle", 0xF739}, +{"nineparen", 0x247C}, +{"nineperiod", 0x2490}, +{"ninepersian", 0x06F9}, +{"nineroman", 0x2178}, +{"ninesuperior", 0x2079}, +{"nineteencircle", 0x2472}, +{"nineteenparen", 0x2486}, +{"nineteenperiod", 0x249A}, +{"ninethai", 0x0E59}, +{"nj", 0x01CC}, +{"njecyrillic", 0x045A}, +{"nkatakana", 0x30F3}, +{"nkatakanahalfwidth", 0xFF9D}, +{"nlegrightlong", 0x019E}, +{"nlinebelow", 0x1E49}, +{"nmonospace", 0xFF4E}, +{"nmsquare", 0x339A}, +{"nnabengali", 0x09A3}, +{"nnadeva", 0x0923}, +{"nnagujarati", 0x0AA3}, +{"nnagurmukhi", 0x0A23}, +{"nnnadeva", 0x0929}, +{"nohiragana", 0x306E}, +{"nokatakana", 0x30CE}, +{"nokatakanahalfwidth", 0xFF89}, +{"nonbreakingspace", 0x00A0}, +{"nonenthai", 0x0E13}, +{"nonuthai", 0x0E19}, +{"noonarabic", 0x0646}, +{"noonfinalarabic", 0xFEE6}, +{"noonghunnaarabic", 0x06BA}, +{"noonghunnafinalarabic", 0xFB9F}, +{"nooninitialarabic", 0xFEE7}, +{"noonjeeminitialarabic", 0xFCD2}, +{"noonjeemisolatedarabic", 0xFC4B}, +{"noonmedialarabic", 0xFEE8}, +{"noonmeeminitialarabic", 0xFCD5}, +{"noonmeemisolatedarabic", 0xFC4E}, +{"noonnoonfinalarabic", 0xFC8D}, +{"notcontains", 0x220C}, +{"notelement", 0x2209}, +{"notelementof", 0x2209}, +{"notequal", 0x2260}, +{"notgreater", 0x226F}, +{"notgreaternorequal", 0x2271}, +{"notgreaternorless", 0x2279}, +{"notidentical", 0x2262}, +{"notless", 0x226E}, +{"notlessnorequal", 0x2270}, +{"notparallel", 0x2226}, +{"notprecedes", 0x2280}, +{"notsubset", 0x2284}, +{"notsucceeds", 0x2281}, +{"notsuperset", 0x2285}, +{"nowarmenian", 0x0576}, +{"nparen", 0x24A9}, +{"nssquare", 0x33B1}, +{"nsuperior", 0x207F}, +{"ntilde", 0x00F1}, +{"nu", 0x03BD}, +{"nuhiragana", 0x306C}, +{"nukatakana", 0x30CC}, +{"nukatakanahalfwidth", 0xFF87}, +{"nuktabengali", 0x09BC}, +{"nuktadeva", 0x093C}, +{"nuktagujarati", 0x0ABC}, +{"nuktagurmukhi", 0x0A3C}, +{"numbersign", 0x0023}, +{"numbersignmonospace", 0xFF03}, +{"numbersignsmall", 0xFE5F}, +{"numeralsigngreek", 0x0374}, +{"numeralsignlowergreek", 0x0375}, +{"numero", 0x2116}, +{"nun", 0x05E0}, +{"nundagesh", 0xFB40}, +{"nundageshhebrew", 0xFB40}, +{"nunhebrew", 0x05E0}, +{"nvsquare", 0x33B5}, +{"nwsquare", 0x33BB}, +{"nyabengali", 0x099E}, +{"nyadeva", 0x091E}, +{"nyagujarati", 0x0A9E}, +{"nyagurmukhi", 0x0A1E}, +{"o", 0x006F}, +{"oacute", 0x00F3}, +{"oangthai", 0x0E2D}, +{"obarred", 0x0275}, +{"obarredcyrillic", 0x04E9}, +{"obarreddieresiscyrillic", 0x04EB}, +{"obengali", 0x0993}, +{"obopomofo", 0x311B}, +{"obreve", 0x014F}, +{"ocandradeva", 0x0911}, +{"ocandragujarati", 0x0A91}, +{"ocandravowelsigndeva", 0x0949}, +{"ocandravowelsigngujarati", 0x0AC9}, +{"ocaron", 0x01D2}, +{"ocircle", 0x24DE}, +{"ocircumflex", 0x00F4}, +{"ocircumflexacute", 0x1ED1}, +{"ocircumflexdotbelow", 0x1ED9}, +{"ocircumflexgrave", 0x1ED3}, +{"ocircumflexhookabove", 0x1ED5}, +{"ocircumflextilde", 0x1ED7}, +{"ocyrillic", 0x043E}, +{"odblacute", 0x0151}, +{"odblgrave", 0x020D}, +{"odeva", 0x0913}, +{"odieresis", 0x00F6}, +{"odieresiscyrillic", 0x04E7}, +{"odotbelow", 0x1ECD}, +{"oe", 0x0153}, +{"oekorean", 0x315A}, +{"ogonek", 0x02DB}, +{"ogonekcmb", 0x0328}, +{"ograve", 0x00F2}, +{"ogujarati", 0x0A93}, +{"oharmenian", 0x0585}, +{"ohiragana", 0x304A}, +{"ohookabove", 0x1ECF}, +{"ohorn", 0x01A1}, +{"ohornacute", 0x1EDB}, +{"ohorndotbelow", 0x1EE3}, +{"ohorngrave", 0x1EDD}, +{"ohornhookabove", 0x1EDF}, +{"ohorntilde", 0x1EE1}, +{"ohungarumlaut", 0x0151}, +{"oi", 0x01A3}, +{"oinvertedbreve", 0x020F}, +{"okatakana", 0x30AA}, +{"okatakanahalfwidth", 0xFF75}, +{"okorean", 0x3157}, +{"olehebrew", 0x05AB}, +{"omacron", 0x014D}, +{"omacronacute", 0x1E53}, +{"omacrongrave", 0x1E51}, +{"omdeva", 0x0950}, +{"omega", 0x03C9}, +{"omega1", 0x03D6}, +{"omegacyrillic", 0x0461}, +{"omegalatinclosed", 0x0277}, +{"omegaroundcyrillic", 0x047B}, +{"omegatitlocyrillic", 0x047D}, +{"omegatonos", 0x03CE}, +{"omgujarati", 0x0AD0}, +{"omicron", 0x03BF}, +{"omicrontonos", 0x03CC}, +{"omonospace", 0xFF4F}, +{"one", 0x0031}, +{"onearabic", 0x0661}, +{"onebengali", 0x09E7}, +{"onecircle", 0x2460}, +{"onecircleinversesansserif", 0x278A}, +{"onedeva", 0x0967}, +{"onedotenleader", 0x2024}, +{"oneeighth", 0x215B}, +{"onefitted", 0xF6DC}, +{"onegujarati", 0x0AE7}, +{"onegurmukhi", 0x0A67}, +{"onehackarabic", 0x0661}, +{"onehalf", 0x00BD}, +{"onehangzhou", 0x3021}, +{"oneideographicparen", 0x3220}, +{"oneinferior", 0x2081}, +{"onemonospace", 0xFF11}, +{"onenumeratorbengali", 0x09F4}, +{"oneoldstyle", 0xF731}, +{"oneparen", 0x2474}, +{"oneperiod", 0x2488}, +{"onepersian", 0x06F1}, +{"onequarter", 0x00BC}, +{"oneroman", 0x2170}, +{"onesuperior", 0x00B9}, +{"onethai", 0x0E51}, +{"onethird", 0x2153}, +{"oogonek", 0x01EB}, +{"oogonekmacron", 0x01ED}, +{"oogurmukhi", 0x0A13}, +{"oomatragurmukhi", 0x0A4B}, +{"oopen", 0x0254}, +{"oparen", 0x24AA}, +{"openbullet", 0x25E6}, +{"option", 0x2325}, +{"ordfeminine", 0x00AA}, +{"ordmasculine", 0x00BA}, +{"orthogonal", 0x221F}, +{"oshortdeva", 0x0912}, +{"oshortvowelsigndeva", 0x094A}, +{"oslash", 0x00F8}, +{"oslashacute", 0x01FF}, +{"osmallhiragana", 0x3049}, +{"osmallkatakana", 0x30A9}, +{"osmallkatakanahalfwidth", 0xFF6B}, +{"ostrokeacute", 0x01FF}, +{"osuperior", 0xF6F0}, +{"otcyrillic", 0x047F}, +{"otilde", 0x00F5}, +{"otildeacute", 0x1E4D}, +{"otildedieresis", 0x1E4F}, +{"oubopomofo", 0x3121}, +{"overline", 0x203E}, +{"overlinecenterline", 0xFE4A}, +{"overlinecmb", 0x0305}, +{"overlinedashed", 0xFE49}, +{"overlinedblwavy", 0xFE4C}, +{"overlinewavy", 0xFE4B}, +{"overscore", 0x00AF}, +{"ovowelsignbengali", 0x09CB}, +{"ovowelsigndeva", 0x094B}, +{"ovowelsigngujarati", 0x0ACB}, +{"p", 0x0070}, +{"paampssquare", 0x3380}, +{"paasentosquare", 0x332B}, +{"pabengali", 0x09AA}, +{"pacute", 0x1E55}, +{"padeva", 0x092A}, +{"pagedown", 0x21DF}, +{"pageup", 0x21DE}, +{"pagujarati", 0x0AAA}, +{"pagurmukhi", 0x0A2A}, +{"pahiragana", 0x3071}, +{"paiyannoithai", 0x0E2F}, +{"pakatakana", 0x30D1}, +{"palatalizationcyrilliccmb", 0x0484}, +{"palochkacyrillic", 0x04C0}, +{"pansioskorean", 0x317F}, +{"paragraph", 0x00B6}, +{"parallel", 0x2225}, +{"parenleft", 0x0028}, +{"parenleftaltonearabic", 0xFD3E}, +{"parenleftbt", 0xF8ED}, +{"parenleftex", 0xF8EC}, +{"parenleftinferior", 0x208D}, +{"parenleftmonospace", 0xFF08}, +{"parenleftsmall", 0xFE59}, +{"parenleftsuperior", 0x207D}, +{"parenlefttp", 0xF8EB}, +{"parenleftvertical", 0xFE35}, +{"parenright", 0x0029}, +{"parenrightaltonearabic", 0xFD3F}, +{"parenrightbt", 0xF8F8}, +{"parenrightex", 0xF8F7}, +{"parenrightinferior", 0x208E}, +{"parenrightmonospace", 0xFF09}, +{"parenrightsmall", 0xFE5A}, +{"parenrightsuperior", 0x207E}, +{"parenrighttp", 0xF8F6}, +{"parenrightvertical", 0xFE36}, +{"partialdiff", 0x2202}, +{"paseqhebrew", 0x05C0}, +{"pashtahebrew", 0x0599}, +{"pasquare", 0x33A9}, +{"patah", 0x05B7}, +{"patah11", 0x05B7}, +{"patah1d", 0x05B7}, +{"patah2a", 0x05B7}, +{"patahhebrew", 0x05B7}, +{"patahnarrowhebrew", 0x05B7}, +{"patahquarterhebrew", 0x05B7}, +{"patahwidehebrew", 0x05B7}, +{"pazerhebrew", 0x05A1}, +{"pbopomofo", 0x3106}, +{"pcircle", 0x24DF}, +{"pdotaccent", 0x1E57}, +{"pe", 0x05E4}, +{"pecyrillic", 0x043F}, +{"pedagesh", 0xFB44}, +{"pedageshhebrew", 0xFB44}, +{"peezisquare", 0x333B}, +{"pefinaldageshhebrew", 0xFB43}, +{"peharabic", 0x067E}, +{"peharmenian", 0x057A}, +{"pehebrew", 0x05E4}, +{"pehfinalarabic", 0xFB57}, +{"pehinitialarabic", 0xFB58}, +{"pehiragana", 0x307A}, +{"pehmedialarabic", 0xFB59}, +{"pekatakana", 0x30DA}, +{"pemiddlehookcyrillic", 0x04A7}, +{"perafehebrew", 0xFB4E}, +{"percent", 0x0025}, +{"percentarabic", 0x066A}, +{"percentmonospace", 0xFF05}, +{"percentsmall", 0xFE6A}, +{"period", 0x002E}, +{"periodarmenian", 0x0589}, +{"periodcentered", 0x00B7}, +{"periodhalfwidth", 0xFF61}, +{"periodinferior", 0xF6E7}, +{"periodmonospace", 0xFF0E}, +{"periodsmall", 0xFE52}, +{"periodsuperior", 0xF6E8}, +{"perispomenigreekcmb", 0x0342}, +{"perpendicular", 0x22A5}, +{"perthousand", 0x2030}, +{"peseta", 0x20A7}, +{"pfsquare", 0x338A}, +{"phabengali", 0x09AB}, +{"phadeva", 0x092B}, +{"phagujarati", 0x0AAB}, +{"phagurmukhi", 0x0A2B}, +{"phi", 0x03C6}, +{"phi1", 0x03D5}, +{"phieuphacirclekorean", 0x327A}, +{"phieuphaparenkorean", 0x321A}, +{"phieuphcirclekorean", 0x326C}, +{"phieuphkorean", 0x314D}, +{"phieuphparenkorean", 0x320C}, +{"philatin", 0x0278}, +{"phinthuthai", 0x0E3A}, +{"phisymbolgreek", 0x03D5}, +{"phook", 0x01A5}, +{"phophanthai", 0x0E1E}, +{"phophungthai", 0x0E1C}, +{"phosamphaothai", 0x0E20}, +{"pi", 0x03C0}, +{"pieupacirclekorean", 0x3273}, +{"pieupaparenkorean", 0x3213}, +{"pieupcieuckorean", 0x3176}, +{"pieupcirclekorean", 0x3265}, +{"pieupkiyeokkorean", 0x3172}, +{"pieupkorean", 0x3142}, +{"pieupparenkorean", 0x3205}, +{"pieupsioskiyeokkorean", 0x3174}, +{"pieupsioskorean", 0x3144}, +{"pieupsiostikeutkorean", 0x3175}, +{"pieupthieuthkorean", 0x3177}, +{"pieuptikeutkorean", 0x3173}, +{"pihiragana", 0x3074}, +{"pikatakana", 0x30D4}, +{"pisymbolgreek", 0x03D6}, +{"piwrarmenian", 0x0583}, +{"plus", 0x002B}, +{"plusbelowcmb", 0x031F}, +{"pluscircle", 0x2295}, +{"plusminus", 0x00B1}, +{"plusmod", 0x02D6}, +{"plusmonospace", 0xFF0B}, +{"plussmall", 0xFE62}, +{"plussuperior", 0x207A}, +{"pmonospace", 0xFF50}, +{"pmsquare", 0x33D8}, +{"pohiragana", 0x307D}, +{"pointingindexdownwhite", 0x261F}, +{"pointingindexleftwhite", 0x261C}, +{"pointingindexrightwhite", 0x261E}, +{"pointingindexupwhite", 0x261D}, +{"pokatakana", 0x30DD}, +{"poplathai", 0x0E1B}, +{"postalmark", 0x3012}, +{"postalmarkface", 0x3020}, +{"pparen", 0x24AB}, +{"precedes", 0x227A}, +{"prescription", 0x211E}, +{"primemod", 0x02B9}, +{"primereversed", 0x2035}, +{"product", 0x220F}, +{"projective", 0x2305}, +{"prolongedkana", 0x30FC}, +{"propellor", 0x2318}, +{"propersubset", 0x2282}, +{"propersuperset", 0x2283}, +{"proportion", 0x2237}, +{"proportional", 0x221D}, +{"psi", 0x03C8}, +{"psicyrillic", 0x0471}, +{"psilipneumatacyrilliccmb", 0x0486}, +{"pssquare", 0x33B0}, +{"puhiragana", 0x3077}, +{"pukatakana", 0x30D7}, +{"pvsquare", 0x33B4}, +{"pwsquare", 0x33BA}, +{"q", 0x0071}, +{"qadeva", 0x0958}, +{"qadmahebrew", 0x05A8}, +{"qafarabic", 0x0642}, +{"qaffinalarabic", 0xFED6}, +{"qafinitialarabic", 0xFED7}, +{"qafmedialarabic", 0xFED8}, +{"qamats", 0x05B8}, +{"qamats10", 0x05B8}, +{"qamats1a", 0x05B8}, +{"qamats1c", 0x05B8}, +{"qamats27", 0x05B8}, +{"qamats29", 0x05B8}, +{"qamats33", 0x05B8}, +{"qamatsde", 0x05B8}, +{"qamatshebrew", 0x05B8}, +{"qamatsnarrowhebrew", 0x05B8}, +{"qamatsqatanhebrew", 0x05B8}, +{"qamatsqatannarrowhebrew", 0x05B8}, +{"qamatsqatanquarterhebrew", 0x05B8}, +{"qamatsqatanwidehebrew", 0x05B8}, +{"qamatsquarterhebrew", 0x05B8}, +{"qamatswidehebrew", 0x05B8}, +{"qarneyparahebrew", 0x059F}, +{"qbopomofo", 0x3111}, +{"qcircle", 0x24E0}, +{"qhook", 0x02A0}, +{"qmonospace", 0xFF51}, +{"qof", 0x05E7}, +{"qofdagesh", 0xFB47}, +{"qofdageshhebrew", 0xFB47}, +{"qofhebrew", 0x05E7}, +{"qparen", 0x24AC}, +{"quarternote", 0x2669}, +{"qubuts", 0x05BB}, +{"qubuts18", 0x05BB}, +{"qubuts25", 0x05BB}, +{"qubuts31", 0x05BB}, +{"qubutshebrew", 0x05BB}, +{"qubutsnarrowhebrew", 0x05BB}, +{"qubutsquarterhebrew", 0x05BB}, +{"qubutswidehebrew", 0x05BB}, +{"question", 0x003F}, +{"questionarabic", 0x061F}, +{"questionarmenian", 0x055E}, +{"questiondown", 0x00BF}, +{"questiondownsmall", 0xF7BF}, +{"questiongreek", 0x037E}, +{"questionmonospace", 0xFF1F}, +{"questionsmall", 0xF73F}, +{"quotedbl", 0x0022}, +{"quotedblbase", 0x201E}, +{"quotedblleft", 0x201C}, +{"quotedblmonospace", 0xFF02}, +{"quotedblprime", 0x301E}, +{"quotedblprimereversed", 0x301D}, +{"quotedblright", 0x201D}, +{"quoteleft", 0x2018}, +{"quoteleftreversed", 0x201B}, +{"quotereversed", 0x201B}, +{"quoteright", 0x2019}, +{"quoterightn", 0x0149}, +{"quotesinglbase", 0x201A}, +{"quotesingle", 0x0027}, +{"quotesinglemonospace", 0xFF07}, +{"r", 0x0072}, +{"raarmenian", 0x057C}, +{"rabengali", 0x09B0}, +{"racute", 0x0155}, +{"radeva", 0x0930}, +{"radical", 0x221A}, +{"radicalex", 0xF8E5}, +{"radoverssquare", 0x33AE}, +{"radoverssquaredsquare", 0x33AF}, +{"radsquare", 0x33AD}, +{"rafe", 0x05BF}, +{"rafehebrew", 0x05BF}, +{"ragujarati", 0x0AB0}, +{"ragurmukhi", 0x0A30}, +{"rahiragana", 0x3089}, +{"rakatakana", 0x30E9}, +{"rakatakanahalfwidth", 0xFF97}, +{"ralowerdiagonalbengali", 0x09F1}, +{"ramiddlediagonalbengali", 0x09F0}, +{"ramshorn", 0x0264}, +{"ratio", 0x2236}, +{"rbopomofo", 0x3116}, +{"rcaron", 0x0159}, +{"rcedilla", 0x0157}, +{"rcircle", 0x24E1}, +{"rcommaaccent", 0x0157}, +{"rdblgrave", 0x0211}, +{"rdotaccent", 0x1E59}, +{"rdotbelow", 0x1E5B}, +{"rdotbelowmacron", 0x1E5D}, +{"referencemark", 0x203B}, +{"reflexsubset", 0x2286}, +{"reflexsuperset", 0x2287}, +{"registered", 0x00AE}, +{"registersans", 0xF8E8}, +{"registerserif", 0xF6DA}, +{"reharabic", 0x0631}, +{"reharmenian", 0x0580}, +{"rehfinalarabic", 0xFEAE}, +{"rehiragana", 0x308C}, +{"rekatakana", 0x30EC}, +{"rekatakanahalfwidth", 0xFF9A}, +{"resh", 0x05E8}, +{"reshdageshhebrew", 0xFB48}, +{"reshhebrew", 0x05E8}, +{"reversedtilde", 0x223D}, +{"reviahebrew", 0x0597}, +{"reviamugrashhebrew", 0x0597}, +{"revlogicalnot", 0x2310}, +{"rfishhook", 0x027E}, +{"rfishhookreversed", 0x027F}, +{"rhabengali", 0x09DD}, +{"rhadeva", 0x095D}, +{"rho", 0x03C1}, +{"rhook", 0x027D}, +{"rhookturned", 0x027B}, +{"rhookturnedsuperior", 0x02B5}, +{"rhosymbolgreek", 0x03F1}, +{"rhotichookmod", 0x02DE}, +{"rieulacirclekorean", 0x3271}, +{"rieulaparenkorean", 0x3211}, +{"rieulcirclekorean", 0x3263}, +{"rieulhieuhkorean", 0x3140}, +{"rieulkiyeokkorean", 0x313A}, +{"rieulkiyeoksioskorean", 0x3169}, +{"rieulkorean", 0x3139}, +{"rieulmieumkorean", 0x313B}, +{"rieulpansioskorean", 0x316C}, +{"rieulparenkorean", 0x3203}, +{"rieulphieuphkorean", 0x313F}, +{"rieulpieupkorean", 0x313C}, +{"rieulpieupsioskorean", 0x316B}, +{"rieulsioskorean", 0x313D}, +{"rieulthieuthkorean", 0x313E}, +{"rieultikeutkorean", 0x316A}, +{"rieulyeorinhieuhkorean", 0x316D}, +{"rightangle", 0x221F}, +{"righttackbelowcmb", 0x0319}, +{"righttriangle", 0x22BF}, +{"rihiragana", 0x308A}, +{"rikatakana", 0x30EA}, +{"rikatakanahalfwidth", 0xFF98}, +{"ring", 0x02DA}, +{"ringbelowcmb", 0x0325}, +{"ringcmb", 0x030A}, +{"ringhalfleft", 0x02BF}, +{"ringhalfleftarmenian", 0x0559}, +{"ringhalfleftbelowcmb", 0x031C}, +{"ringhalfleftcentered", 0x02D3}, +{"ringhalfright", 0x02BE}, +{"ringhalfrightbelowcmb", 0x0339}, +{"ringhalfrightcentered", 0x02D2}, +{"rinvertedbreve", 0x0213}, +{"rittorusquare", 0x3351}, +{"rlinebelow", 0x1E5F}, +{"rlongleg", 0x027C}, +{"rlonglegturned", 0x027A}, +{"rmonospace", 0xFF52}, +{"rohiragana", 0x308D}, +{"rokatakana", 0x30ED}, +{"rokatakanahalfwidth", 0xFF9B}, +{"roruathai", 0x0E23}, +{"rparen", 0x24AD}, +{"rrabengali", 0x09DC}, +{"rradeva", 0x0931}, +{"rragurmukhi", 0x0A5C}, +{"rreharabic", 0x0691}, +{"rrehfinalarabic", 0xFB8D}, +{"rrvocalicbengali", 0x09E0}, +{"rrvocalicdeva", 0x0960}, +{"rrvocalicgujarati", 0x0AE0}, +{"rrvocalicvowelsignbengali", 0x09C4}, +{"rrvocalicvowelsigndeva", 0x0944}, +{"rrvocalicvowelsigngujarati", 0x0AC4}, +{"rsuperior", 0xF6F1}, +{"rtblock", 0x2590}, +{"rturned", 0x0279}, +{"rturnedsuperior", 0x02B4}, +{"ruhiragana", 0x308B}, +{"rukatakana", 0x30EB}, +{"rukatakanahalfwidth", 0xFF99}, +{"rupeemarkbengali", 0x09F2}, +{"rupeesignbengali", 0x09F3}, +{"rupiah", 0xF6DD}, +{"ruthai", 0x0E24}, +{"rvocalicbengali", 0x098B}, +{"rvocalicdeva", 0x090B}, +{"rvocalicgujarati", 0x0A8B}, +{"rvocalicvowelsignbengali", 0x09C3}, +{"rvocalicvowelsigndeva", 0x0943}, +{"rvocalicvowelsigngujarati", 0x0AC3}, +{"s", 0x0073}, +{"sabengali", 0x09B8}, +{"sacute", 0x015B}, +{"sacutedotaccent", 0x1E65}, +{"sadarabic", 0x0635}, +{"sadeva", 0x0938}, +{"sadfinalarabic", 0xFEBA}, +{"sadinitialarabic", 0xFEBB}, +{"sadmedialarabic", 0xFEBC}, +{"sagujarati", 0x0AB8}, +{"sagurmukhi", 0x0A38}, +{"sahiragana", 0x3055}, +{"sakatakana", 0x30B5}, +{"sakatakanahalfwidth", 0xFF7B}, +{"sallallahoualayhewasallamarabic", 0xFDFA}, +{"samekh", 0x05E1}, +{"samekhdagesh", 0xFB41}, +{"samekhdageshhebrew", 0xFB41}, +{"samekhhebrew", 0x05E1}, +{"saraaathai", 0x0E32}, +{"saraaethai", 0x0E41}, +{"saraaimaimalaithai", 0x0E44}, +{"saraaimaimuanthai", 0x0E43}, +{"saraamthai", 0x0E33}, +{"saraathai", 0x0E30}, +{"saraethai", 0x0E40}, +{"saraiileftthai", 0xF886}, +{"saraiithai", 0x0E35}, +{"saraileftthai", 0xF885}, +{"saraithai", 0x0E34}, +{"saraothai", 0x0E42}, +{"saraueeleftthai", 0xF888}, +{"saraueethai", 0x0E37}, +{"saraueleftthai", 0xF887}, +{"sarauethai", 0x0E36}, +{"sarauthai", 0x0E38}, +{"sarauuthai", 0x0E39}, +{"sbopomofo", 0x3119}, +{"scaron", 0x0161}, +{"scarondotaccent", 0x1E67}, +{"scedilla", 0x015F}, +{"schwa", 0x0259}, +{"schwacyrillic", 0x04D9}, +{"schwadieresiscyrillic", 0x04DB}, +{"schwahook", 0x025A}, +{"scircle", 0x24E2}, +{"scircumflex", 0x015D}, +{"scommaaccent", 0x0219}, +{"sdotaccent", 0x1E61}, +{"sdotbelow", 0x1E63}, +{"sdotbelowdotaccent", 0x1E69}, +{"seagullbelowcmb", 0x033C}, +{"second", 0x2033}, +{"secondtonechinese", 0x02CA}, +{"section", 0x00A7}, +{"seenarabic", 0x0633}, +{"seenfinalarabic", 0xFEB2}, +{"seeninitialarabic", 0xFEB3}, +{"seenmedialarabic", 0xFEB4}, +{"segol", 0x05B6}, +{"segol13", 0x05B6}, +{"segol1f", 0x05B6}, +{"segol2c", 0x05B6}, +{"segolhebrew", 0x05B6}, +{"segolnarrowhebrew", 0x05B6}, +{"segolquarterhebrew", 0x05B6}, +{"segoltahebrew", 0x0592}, +{"segolwidehebrew", 0x05B6}, +{"seharmenian", 0x057D}, +{"sehiragana", 0x305B}, +{"sekatakana", 0x30BB}, +{"sekatakanahalfwidth", 0xFF7E}, +{"semicolon", 0x003B}, +{"semicolonarabic", 0x061B}, +{"semicolonmonospace", 0xFF1B}, +{"semicolonsmall", 0xFE54}, +{"semivoicedmarkkana", 0x309C}, +{"semivoicedmarkkanahalfwidth", 0xFF9F}, +{"sentisquare", 0x3322}, +{"sentosquare", 0x3323}, +{"seven", 0x0037}, +{"sevenarabic", 0x0667}, +{"sevenbengali", 0x09ED}, +{"sevencircle", 0x2466}, +{"sevencircleinversesansserif", 0x2790}, +{"sevendeva", 0x096D}, +{"seveneighths", 0x215E}, +{"sevengujarati", 0x0AED}, +{"sevengurmukhi", 0x0A6D}, +{"sevenhackarabic", 0x0667}, +{"sevenhangzhou", 0x3027}, +{"sevenideographicparen", 0x3226}, +{"seveninferior", 0x2087}, +{"sevenmonospace", 0xFF17}, +{"sevenoldstyle", 0xF737}, +{"sevenparen", 0x247A}, +{"sevenperiod", 0x248E}, +{"sevenpersian", 0x06F7}, +{"sevenroman", 0x2176}, +{"sevensuperior", 0x2077}, +{"seventeencircle", 0x2470}, +{"seventeenparen", 0x2484}, +{"seventeenperiod", 0x2498}, +{"seventhai", 0x0E57}, +{"sfthyphen", 0x00AD}, +{"shaarmenian", 0x0577}, +{"shabengali", 0x09B6}, +{"shacyrillic", 0x0448}, +{"shaddaarabic", 0x0651}, +{"shaddadammaarabic", 0xFC61}, +{"shaddadammatanarabic", 0xFC5E}, +{"shaddafathaarabic", 0xFC60}, +{"shaddakasraarabic", 0xFC62}, +{"shaddakasratanarabic", 0xFC5F}, +{"shade", 0x2592}, +{"shadedark", 0x2593}, +{"shadelight", 0x2591}, +{"shademedium", 0x2592}, +{"shadeva", 0x0936}, +{"shagujarati", 0x0AB6}, +{"shagurmukhi", 0x0A36}, +{"shalshelethebrew", 0x0593}, +{"shbopomofo", 0x3115}, +{"shchacyrillic", 0x0449}, +{"sheenarabic", 0x0634}, +{"sheenfinalarabic", 0xFEB6}, +{"sheeninitialarabic", 0xFEB7}, +{"sheenmedialarabic", 0xFEB8}, +{"sheicoptic", 0x03E3}, +{"sheqel", 0x20AA}, +{"sheqelhebrew", 0x20AA}, +{"sheva", 0x05B0}, +{"sheva115", 0x05B0}, +{"sheva15", 0x05B0}, +{"sheva22", 0x05B0}, +{"sheva2e", 0x05B0}, +{"shevahebrew", 0x05B0}, +{"shevanarrowhebrew", 0x05B0}, +{"shevaquarterhebrew", 0x05B0}, +{"shevawidehebrew", 0x05B0}, +{"shhacyrillic", 0x04BB}, +{"shimacoptic", 0x03ED}, +{"shin", 0x05E9}, +{"shindagesh", 0xFB49}, +{"shindageshhebrew", 0xFB49}, +{"shindageshshindot", 0xFB2C}, +{"shindageshshindothebrew", 0xFB2C}, +{"shindageshsindot", 0xFB2D}, +{"shindageshsindothebrew", 0xFB2D}, +{"shindothebrew", 0x05C1}, +{"shinhebrew", 0x05E9}, +{"shinshindot", 0xFB2A}, +{"shinshindothebrew", 0xFB2A}, +{"shinsindot", 0xFB2B}, +{"shinsindothebrew", 0xFB2B}, +{"shook", 0x0282}, +{"sigma", 0x03C3}, +{"sigma1", 0x03C2}, +{"sigmafinal", 0x03C2}, +{"sigmalunatesymbolgreek", 0x03F2}, +{"sihiragana", 0x3057}, +{"sikatakana", 0x30B7}, +{"sikatakanahalfwidth", 0xFF7C}, +{"siluqhebrew", 0x05BD}, +{"siluqlefthebrew", 0x05BD}, +{"similar", 0x223C}, +{"sindothebrew", 0x05C2}, +{"siosacirclekorean", 0x3274}, +{"siosaparenkorean", 0x3214}, +{"sioscieuckorean", 0x317E}, +{"sioscirclekorean", 0x3266}, +{"sioskiyeokkorean", 0x317A}, +{"sioskorean", 0x3145}, +{"siosnieunkorean", 0x317B}, +{"siosparenkorean", 0x3206}, +{"siospieupkorean", 0x317D}, +{"siostikeutkorean", 0x317C}, +{"six", 0x0036}, +{"sixarabic", 0x0666}, +{"sixbengali", 0x09EC}, +{"sixcircle", 0x2465}, +{"sixcircleinversesansserif", 0x278F}, +{"sixdeva", 0x096C}, +{"sixgujarati", 0x0AEC}, +{"sixgurmukhi", 0x0A6C}, +{"sixhackarabic", 0x0666}, +{"sixhangzhou", 0x3026}, +{"sixideographicparen", 0x3225}, +{"sixinferior", 0x2086}, +{"sixmonospace", 0xFF16}, +{"sixoldstyle", 0xF736}, +{"sixparen", 0x2479}, +{"sixperiod", 0x248D}, +{"sixpersian", 0x06F6}, +{"sixroman", 0x2175}, +{"sixsuperior", 0x2076}, +{"sixteencircle", 0x246F}, +{"sixteencurrencydenominatorbengali", 0x09F9}, +{"sixteenparen", 0x2483}, +{"sixteenperiod", 0x2497}, +{"sixthai", 0x0E56}, +{"slash", 0x002F}, +{"slashmonospace", 0xFF0F}, +{"slong", 0x017F}, +{"slongdotaccent", 0x1E9B}, +{"smileface", 0x263A}, +{"smonospace", 0xFF53}, +{"sofpasuqhebrew", 0x05C3}, +{"softhyphen", 0x00AD}, +{"softsigncyrillic", 0x044C}, +{"sohiragana", 0x305D}, +{"sokatakana", 0x30BD}, +{"sokatakanahalfwidth", 0xFF7F}, +{"soliduslongoverlaycmb", 0x0338}, +{"solidusshortoverlaycmb", 0x0337}, +{"sorusithai", 0x0E29}, +{"sosalathai", 0x0E28}, +{"sosothai", 0x0E0B}, +{"sosuathai", 0x0E2A}, +{"space", 0x0020}, +{"spacehackarabic", 0x0020}, +{"spade", 0x2660}, +{"spadesuitblack", 0x2660}, +{"spadesuitwhite", 0x2664}, +{"sparen", 0x24AE}, +{"squarebelowcmb", 0x033B}, +{"squarecc", 0x33C4}, +{"squarecm", 0x339D}, +{"squarediagonalcrosshatchfill", 0x25A9}, +{"squarehorizontalfill", 0x25A4}, +{"squarekg", 0x338F}, +{"squarekm", 0x339E}, +{"squarekmcapital", 0x33CE}, +{"squareln", 0x33D1}, +{"squarelog", 0x33D2}, +{"squaremg", 0x338E}, +{"squaremil", 0x33D5}, +{"squaremm", 0x339C}, +{"squaremsquared", 0x33A1}, +{"squareorthogonalcrosshatchfill", 0x25A6}, +{"squareupperlefttolowerrightfill", 0x25A7}, +{"squareupperrighttolowerleftfill", 0x25A8}, +{"squareverticalfill", 0x25A5}, +{"squarewhitewithsmallblack", 0x25A3}, +{"srsquare", 0x33DB}, +{"ssabengali", 0x09B7}, +{"ssadeva", 0x0937}, +{"ssagujarati", 0x0AB7}, +{"ssangcieuckorean", 0x3149}, +{"ssanghieuhkorean", 0x3185}, +{"ssangieungkorean", 0x3180}, +{"ssangkiyeokkorean", 0x3132}, +{"ssangnieunkorean", 0x3165}, +{"ssangpieupkorean", 0x3143}, +{"ssangsioskorean", 0x3146}, +{"ssangtikeutkorean", 0x3138}, +{"ssuperior", 0xF6F2}, +{"sterling", 0x00A3}, +{"sterlingmonospace", 0xFFE1}, +{"strokelongoverlaycmb", 0x0336}, +{"strokeshortoverlaycmb", 0x0335}, +{"subset", 0x2282}, +{"subsetnotequal", 0x228A}, +{"subsetorequal", 0x2286}, +{"succeeds", 0x227B}, +{"suchthat", 0x220B}, +{"suhiragana", 0x3059}, +{"sukatakana", 0x30B9}, +{"sukatakanahalfwidth", 0xFF7D}, +{"sukunarabic", 0x0652}, +{"summation", 0x2211}, +{"sun", 0x263C}, +{"superset", 0x2283}, +{"supersetnotequal", 0x228B}, +{"supersetorequal", 0x2287}, +{"svsquare", 0x33DC}, +{"syouwaerasquare", 0x337C}, +{"t", 0x0074}, +{"tabengali", 0x09A4}, +{"tackdown", 0x22A4}, +{"tackleft", 0x22A3}, +{"tadeva", 0x0924}, +{"tagujarati", 0x0AA4}, +{"tagurmukhi", 0x0A24}, +{"taharabic", 0x0637}, +{"tahfinalarabic", 0xFEC2}, +{"tahinitialarabic", 0xFEC3}, +{"tahiragana", 0x305F}, +{"tahmedialarabic", 0xFEC4}, +{"taisyouerasquare", 0x337D}, +{"takatakana", 0x30BF}, +{"takatakanahalfwidth", 0xFF80}, +{"tatweelarabic", 0x0640}, +{"tau", 0x03C4}, +{"tav", 0x05EA}, +{"tavdages", 0xFB4A}, +{"tavdagesh", 0xFB4A}, +{"tavdageshhebrew", 0xFB4A}, +{"tavhebrew", 0x05EA}, +{"tbar", 0x0167}, +{"tbopomofo", 0x310A}, +{"tcaron", 0x0165}, +{"tccurl", 0x02A8}, +{"tcedilla", 0x0163}, +{"tcheharabic", 0x0686}, +{"tchehfinalarabic", 0xFB7B}, +{"tchehinitialarabic", 0xFB7C}, +{"tchehmedialarabic", 0xFB7D}, +{"tcircle", 0x24E3}, +{"tcircumflexbelow", 0x1E71}, +{"tcommaaccent", 0x0163}, +{"tdieresis", 0x1E97}, +{"tdotaccent", 0x1E6B}, +{"tdotbelow", 0x1E6D}, +{"tecyrillic", 0x0442}, +{"tedescendercyrillic", 0x04AD}, +{"teharabic", 0x062A}, +{"tehfinalarabic", 0xFE96}, +{"tehhahinitialarabic", 0xFCA2}, +{"tehhahisolatedarabic", 0xFC0C}, +{"tehinitialarabic", 0xFE97}, +{"tehiragana", 0x3066}, +{"tehjeeminitialarabic", 0xFCA1}, +{"tehjeemisolatedarabic", 0xFC0B}, +{"tehmarbutaarabic", 0x0629}, +{"tehmarbutafinalarabic", 0xFE94}, +{"tehmedialarabic", 0xFE98}, +{"tehmeeminitialarabic", 0xFCA4}, +{"tehmeemisolatedarabic", 0xFC0E}, +{"tehnoonfinalarabic", 0xFC73}, +{"tekatakana", 0x30C6}, +{"tekatakanahalfwidth", 0xFF83}, +{"telephone", 0x2121}, +{"telephoneblack", 0x260E}, +{"telishagedolahebrew", 0x05A0}, +{"telishaqetanahebrew", 0x05A9}, +{"tencircle", 0x2469}, +{"tenideographicparen", 0x3229}, +{"tenparen", 0x247D}, +{"tenperiod", 0x2491}, +{"tenroman", 0x2179}, +{"tesh", 0x02A7}, +{"tet", 0x05D8}, +{"tetdagesh", 0xFB38}, +{"tetdageshhebrew", 0xFB38}, +{"tethebrew", 0x05D8}, +{"tetsecyrillic", 0x04B5}, +{"tevirhebrew", 0x059B}, +{"tevirlefthebrew", 0x059B}, +{"thabengali", 0x09A5}, +{"thadeva", 0x0925}, +{"thagujarati", 0x0AA5}, +{"thagurmukhi", 0x0A25}, +{"thalarabic", 0x0630}, +{"thalfinalarabic", 0xFEAC}, +{"thanthakhatlowleftthai", 0xF898}, +{"thanthakhatlowrightthai", 0xF897}, +{"thanthakhatthai", 0x0E4C}, +{"thanthakhatupperleftthai", 0xF896}, +{"theharabic", 0x062B}, +{"thehfinalarabic", 0xFE9A}, +{"thehinitialarabic", 0xFE9B}, +{"thehmedialarabic", 0xFE9C}, +{"thereexists", 0x2203}, +{"therefore", 0x2234}, +{"theta", 0x03B8}, +{"theta1", 0x03D1}, +{"thetasymbolgreek", 0x03D1}, +{"thieuthacirclekorean", 0x3279}, +{"thieuthaparenkorean", 0x3219}, +{"thieuthcirclekorean", 0x326B}, +{"thieuthkorean", 0x314C}, +{"thieuthparenkorean", 0x320B}, +{"thirteencircle", 0x246C}, +{"thirteenparen", 0x2480}, +{"thirteenperiod", 0x2494}, +{"thonangmonthothai", 0x0E11}, +{"thook", 0x01AD}, +{"thophuthaothai", 0x0E12}, +{"thorn", 0x00FE}, +{"thothahanthai", 0x0E17}, +{"thothanthai", 0x0E10}, +{"thothongthai", 0x0E18}, +{"thothungthai", 0x0E16}, +{"thousandcyrillic", 0x0482}, +{"thousandsseparatorarabic", 0x066C}, +{"thousandsseparatorpersian", 0x066C}, +{"three", 0x0033}, +{"threearabic", 0x0663}, +{"threebengali", 0x09E9}, +{"threecircle", 0x2462}, +{"threecircleinversesansserif", 0x278C}, +{"threedeva", 0x0969}, +{"threeeighths", 0x215C}, +{"threegujarati", 0x0AE9}, +{"threegurmukhi", 0x0A69}, +{"threehackarabic", 0x0663}, +{"threehangzhou", 0x3023}, +{"threeideographicparen", 0x3222}, +{"threeinferior", 0x2083}, +{"threemonospace", 0xFF13}, +{"threenumeratorbengali", 0x09F6}, +{"threeoldstyle", 0xF733}, +{"threeparen", 0x2476}, +{"threeperiod", 0x248A}, +{"threepersian", 0x06F3}, +{"threequarters", 0x00BE}, +{"threequartersemdash", 0xF6DE}, +{"threeroman", 0x2172}, +{"threesuperior", 0x00B3}, +{"threethai", 0x0E53}, +{"thzsquare", 0x3394}, +{"tihiragana", 0x3061}, +{"tikatakana", 0x30C1}, +{"tikatakanahalfwidth", 0xFF81}, +{"tikeutacirclekorean", 0x3270}, +{"tikeutaparenkorean", 0x3210}, +{"tikeutcirclekorean", 0x3262}, +{"tikeutkorean", 0x3137}, +{"tikeutparenkorean", 0x3202}, +{"tilde", 0x02DC}, +{"tildebelowcmb", 0x0330}, +{"tildecmb", 0x0303}, +{"tildecomb", 0x0303}, +{"tildedoublecmb", 0x0360}, +{"tildeoperator", 0x223C}, +{"tildeoverlaycmb", 0x0334}, +{"tildeverticalcmb", 0x033E}, +{"timescircle", 0x2297}, +{"tipehahebrew", 0x0596}, +{"tipehalefthebrew", 0x0596}, +{"tippigurmukhi", 0x0A70}, +{"titlocyrilliccmb", 0x0483}, +{"tiwnarmenian", 0x057F}, +{"tlinebelow", 0x1E6F}, +{"tmonospace", 0xFF54}, +{"toarmenian", 0x0569}, +{"tohiragana", 0x3068}, +{"tokatakana", 0x30C8}, +{"tokatakanahalfwidth", 0xFF84}, +{"tonebarextrahighmod", 0x02E5}, +{"tonebarextralowmod", 0x02E9}, +{"tonebarhighmod", 0x02E6}, +{"tonebarlowmod", 0x02E8}, +{"tonebarmidmod", 0x02E7}, +{"tonefive", 0x01BD}, +{"tonesix", 0x0185}, +{"tonetwo", 0x01A8}, +{"tonos", 0x0384}, +{"tonsquare", 0x3327}, +{"topatakthai", 0x0E0F}, +{"tortoiseshellbracketleft", 0x3014}, +{"tortoiseshellbracketleftsmall", 0xFE5D}, +{"tortoiseshellbracketleftvertical", 0xFE39}, +{"tortoiseshellbracketright", 0x3015}, +{"tortoiseshellbracketrightsmall", 0xFE5E}, +{"tortoiseshellbracketrightvertical", 0xFE3A}, +{"totaothai", 0x0E15}, +{"tpalatalhook", 0x01AB}, +{"tparen", 0x24AF}, +{"trademark", 0x2122}, +{"trademarksans", 0xF8EA}, +{"trademarkserif", 0xF6DB}, +{"tretroflexhook", 0x0288}, +{"triagdn", 0x25BC}, +{"triaglf", 0x25C4}, +{"triagrt", 0x25BA}, +{"triagup", 0x25B2}, +{"ts", 0x02A6}, +{"tsadi", 0x05E6}, +{"tsadidagesh", 0xFB46}, +{"tsadidageshhebrew", 0xFB46}, +{"tsadihebrew", 0x05E6}, +{"tsecyrillic", 0x0446}, +{"tsere", 0x05B5}, +{"tsere12", 0x05B5}, +{"tsere1e", 0x05B5}, +{"tsere2b", 0x05B5}, +{"tserehebrew", 0x05B5}, +{"tserenarrowhebrew", 0x05B5}, +{"tserequarterhebrew", 0x05B5}, +{"tserewidehebrew", 0x05B5}, +{"tshecyrillic", 0x045B}, +{"tsuperior", 0xF6F3}, +{"ttabengali", 0x099F}, +{"ttadeva", 0x091F}, +{"ttagujarati", 0x0A9F}, +{"ttagurmukhi", 0x0A1F}, +{"tteharabic", 0x0679}, +{"ttehfinalarabic", 0xFB67}, +{"ttehinitialarabic", 0xFB68}, +{"ttehmedialarabic", 0xFB69}, +{"tthabengali", 0x09A0}, +{"tthadeva", 0x0920}, +{"tthagujarati", 0x0AA0}, +{"tthagurmukhi", 0x0A20}, +{"tturned", 0x0287}, +{"tuhiragana", 0x3064}, +{"tukatakana", 0x30C4}, +{"tukatakanahalfwidth", 0xFF82}, +{"tusmallhiragana", 0x3063}, +{"tusmallkatakana", 0x30C3}, +{"tusmallkatakanahalfwidth", 0xFF6F}, +{"twelvecircle", 0x246B}, +{"twelveparen", 0x247F}, +{"twelveperiod", 0x2493}, +{"twelveroman", 0x217B}, +{"twentycircle", 0x2473}, +{"twentyhangzhou", 0x5344}, +{"twentyparen", 0x2487}, +{"twentyperiod", 0x249B}, +{"two", 0x0032}, +{"twoarabic", 0x0662}, +{"twobengali", 0x09E8}, +{"twocircle", 0x2461}, +{"twocircleinversesansserif", 0x278B}, +{"twodeva", 0x0968}, +{"twodotenleader", 0x2025}, +{"twodotleader", 0x2025}, +{"twodotleadervertical", 0xFE30}, +{"twogujarati", 0x0AE8}, +{"twogurmukhi", 0x0A68}, +{"twohackarabic", 0x0662}, +{"twohangzhou", 0x3022}, +{"twoideographicparen", 0x3221}, +{"twoinferior", 0x2082}, +{"twomonospace", 0xFF12}, +{"twonumeratorbengali", 0x09F5}, +{"twooldstyle", 0xF732}, +{"twoparen", 0x2475}, +{"twoperiod", 0x2489}, +{"twopersian", 0x06F2}, +{"tworoman", 0x2171}, +{"twostroke", 0x01BB}, +{"twosuperior", 0x00B2}, +{"twothai", 0x0E52}, +{"twothirds", 0x2154}, +{"u", 0x0075}, +{"uacute", 0x00FA}, +{"ubar", 0x0289}, +{"ubengali", 0x0989}, +{"ubopomofo", 0x3128}, +{"ubreve", 0x016D}, +{"ucaron", 0x01D4}, +{"ucircle", 0x24E4}, +{"ucircumflex", 0x00FB}, +{"ucircumflexbelow", 0x1E77}, +{"ucyrillic", 0x0443}, +{"udattadeva", 0x0951}, +{"udblacute", 0x0171}, +{"udblgrave", 0x0215}, +{"udeva", 0x0909}, +{"udieresis", 0x00FC}, +{"udieresisacute", 0x01D8}, +{"udieresisbelow", 0x1E73}, +{"udieresiscaron", 0x01DA}, +{"udieresiscyrillic", 0x04F1}, +{"udieresisgrave", 0x01DC}, +{"udieresismacron", 0x01D6}, +{"udotbelow", 0x1EE5}, +{"ugrave", 0x00F9}, +{"ugujarati", 0x0A89}, +{"ugurmukhi", 0x0A09}, +{"uhiragana", 0x3046}, +{"uhookabove", 0x1EE7}, +{"uhorn", 0x01B0}, +{"uhornacute", 0x1EE9}, +{"uhorndotbelow", 0x1EF1}, +{"uhorngrave", 0x1EEB}, +{"uhornhookabove", 0x1EED}, +{"uhorntilde", 0x1EEF}, +{"uhungarumlaut", 0x0171}, +{"uhungarumlautcyrillic", 0x04F3}, +{"uinvertedbreve", 0x0217}, +{"ukatakana", 0x30A6}, +{"ukatakanahalfwidth", 0xFF73}, +{"ukcyrillic", 0x0479}, +{"ukorean", 0x315C}, +{"umacron", 0x016B}, +{"umacroncyrillic", 0x04EF}, +{"umacrondieresis", 0x1E7B}, +{"umatragurmukhi", 0x0A41}, +{"umonospace", 0xFF55}, +{"underscore", 0x005F}, +{"underscoredbl", 0x2017}, +{"underscoremonospace", 0xFF3F}, +{"underscorevertical", 0xFE33}, +{"underscorewavy", 0xFE4F}, +{"union", 0x222A}, +{"universal", 0x2200}, +{"uogonek", 0x0173}, +{"uparen", 0x24B0}, +{"upblock", 0x2580}, +{"upperdothebrew", 0x05C4}, +{"upsilon", 0x03C5}, +{"upsilondieresis", 0x03CB}, +{"upsilondieresistonos", 0x03B0}, +{"upsilonlatin", 0x028A}, +{"upsilontonos", 0x03CD}, +{"uptackbelowcmb", 0x031D}, +{"uptackmod", 0x02D4}, +{"uragurmukhi", 0x0A73}, +{"uring", 0x016F}, +{"ushortcyrillic", 0x045E}, +{"usmallhiragana", 0x3045}, +{"usmallkatakana", 0x30A5}, +{"usmallkatakanahalfwidth", 0xFF69}, +{"ustraightcyrillic", 0x04AF}, +{"ustraightstrokecyrillic", 0x04B1}, +{"utilde", 0x0169}, +{"utildeacute", 0x1E79}, +{"utildebelow", 0x1E75}, +{"uubengali", 0x098A}, +{"uudeva", 0x090A}, +{"uugujarati", 0x0A8A}, +{"uugurmukhi", 0x0A0A}, +{"uumatragurmukhi", 0x0A42}, +{"uuvowelsignbengali", 0x09C2}, +{"uuvowelsigndeva", 0x0942}, +{"uuvowelsigngujarati", 0x0AC2}, +{"uvowelsignbengali", 0x09C1}, +{"uvowelsigndeva", 0x0941}, +{"uvowelsigngujarati", 0x0AC1}, +{"v", 0x0076}, +{"vadeva", 0x0935}, +{"vagujarati", 0x0AB5}, +{"vagurmukhi", 0x0A35}, +{"vakatakana", 0x30F7}, +{"vav", 0x05D5}, +{"vavdagesh", 0xFB35}, +{"vavdagesh65", 0xFB35}, +{"vavdageshhebrew", 0xFB35}, +{"vavhebrew", 0x05D5}, +{"vavholam", 0xFB4B}, +{"vavholamhebrew", 0xFB4B}, +{"vavvavhebrew", 0x05F0}, +{"vavyodhebrew", 0x05F1}, +{"vcircle", 0x24E5}, +{"vdotbelow", 0x1E7F}, +{"vecyrillic", 0x0432}, +{"veharabic", 0x06A4}, +{"vehfinalarabic", 0xFB6B}, +{"vehinitialarabic", 0xFB6C}, +{"vehmedialarabic", 0xFB6D}, +{"vekatakana", 0x30F9}, +{"venus", 0x2640}, +{"verticalbar", 0x007C}, +{"verticallineabovecmb", 0x030D}, +{"verticallinebelowcmb", 0x0329}, +{"verticallinelowmod", 0x02CC}, +{"verticallinemod", 0x02C8}, +{"vewarmenian", 0x057E}, +{"vhook", 0x028B}, +{"vikatakana", 0x30F8}, +{"viramabengali", 0x09CD}, +{"viramadeva", 0x094D}, +{"viramagujarati", 0x0ACD}, +{"visargabengali", 0x0983}, +{"visargadeva", 0x0903}, +{"visargagujarati", 0x0A83}, +{"vmonospace", 0xFF56}, +{"voarmenian", 0x0578}, +{"voicediterationhiragana", 0x309E}, +{"voicediterationkatakana", 0x30FE}, +{"voicedmarkkana", 0x309B}, +{"voicedmarkkanahalfwidth", 0xFF9E}, +{"vokatakana", 0x30FA}, +{"vparen", 0x24B1}, +{"vtilde", 0x1E7D}, +{"vturned", 0x028C}, +{"vuhiragana", 0x3094}, +{"vukatakana", 0x30F4}, +{"w", 0x0077}, +{"wacute", 0x1E83}, +{"waekorean", 0x3159}, +{"wahiragana", 0x308F}, +{"wakatakana", 0x30EF}, +{"wakatakanahalfwidth", 0xFF9C}, +{"wakorean", 0x3158}, +{"wasmallhiragana", 0x308E}, +{"wasmallkatakana", 0x30EE}, +{"wattosquare", 0x3357}, +{"wavedash", 0x301C}, +{"wavyunderscorevertical", 0xFE34}, +{"wawarabic", 0x0648}, +{"wawfinalarabic", 0xFEEE}, +{"wawhamzaabovearabic", 0x0624}, +{"wawhamzaabovefinalarabic", 0xFE86}, +{"wbsquare", 0x33DD}, +{"wcircle", 0x24E6}, +{"wcircumflex", 0x0175}, +{"wdieresis", 0x1E85}, +{"wdotaccent", 0x1E87}, +{"wdotbelow", 0x1E89}, +{"wehiragana", 0x3091}, +{"weierstrass", 0x2118}, +{"wekatakana", 0x30F1}, +{"wekorean", 0x315E}, +{"weokorean", 0x315D}, +{"wgrave", 0x1E81}, +{"whitebullet", 0x25E6}, +{"whitecircle", 0x25CB}, +{"whitecircleinverse", 0x25D9}, +{"whitecornerbracketleft", 0x300E}, +{"whitecornerbracketleftvertical", 0xFE43}, +{"whitecornerbracketright", 0x300F}, +{"whitecornerbracketrightvertical", 0xFE44}, +{"whitediamond", 0x25C7}, +{"whitediamondcontainingblacksmalldiamond", 0x25C8}, +{"whitedownpointingsmalltriangle", 0x25BF}, +{"whitedownpointingtriangle", 0x25BD}, +{"whiteleftpointingsmalltriangle", 0x25C3}, +{"whiteleftpointingtriangle", 0x25C1}, +{"whitelenticularbracketleft", 0x3016}, +{"whitelenticularbracketright", 0x3017}, +{"whiterightpointingsmalltriangle", 0x25B9}, +{"whiterightpointingtriangle", 0x25B7}, +{"whitesmallsquare", 0x25AB}, +{"whitesmilingface", 0x263A}, +{"whitesquare", 0x25A1}, +{"whitestar", 0x2606}, +{"whitetelephone", 0x260F}, +{"whitetortoiseshellbracketleft", 0x3018}, +{"whitetortoiseshellbracketright", 0x3019}, +{"whiteuppointingsmalltriangle", 0x25B5}, +{"whiteuppointingtriangle", 0x25B3}, +{"wihiragana", 0x3090}, +{"wikatakana", 0x30F0}, +{"wikorean", 0x315F}, +{"wmonospace", 0xFF57}, +{"wohiragana", 0x3092}, +{"wokatakana", 0x30F2}, +{"wokatakanahalfwidth", 0xFF66}, +{"won", 0x20A9}, +{"wonmonospace", 0xFFE6}, +{"wowaenthai", 0x0E27}, +{"wparen", 0x24B2}, +{"wring", 0x1E98}, +{"wsuperior", 0x02B7}, +{"wturned", 0x028D}, +{"wynn", 0x01BF}, +{"x", 0x0078}, +{"xabovecmb", 0x033D}, +{"xbopomofo", 0x3112}, +{"xcircle", 0x24E7}, +{"xdieresis", 0x1E8D}, +{"xdotaccent", 0x1E8B}, +{"xeharmenian", 0x056D}, +{"xi", 0x03BE}, +{"xmonospace", 0xFF58}, +{"xparen", 0x24B3}, +{"xsuperior", 0x02E3}, +{"y", 0x0079}, +{"yaadosquare", 0x334E}, +{"yabengali", 0x09AF}, +{"yacute", 0x00FD}, +{"yadeva", 0x092F}, +{"yaekorean", 0x3152}, +{"yagujarati", 0x0AAF}, +{"yagurmukhi", 0x0A2F}, +{"yahiragana", 0x3084}, +{"yakatakana", 0x30E4}, +{"yakatakanahalfwidth", 0xFF94}, +{"yakorean", 0x3151}, +{"yamakkanthai", 0x0E4E}, +{"yasmallhiragana", 0x3083}, +{"yasmallkatakana", 0x30E3}, +{"yasmallkatakanahalfwidth", 0xFF6C}, +{"yatcyrillic", 0x0463}, +{"ycircle", 0x24E8}, +{"ycircumflex", 0x0177}, +{"ydieresis", 0x00FF}, +{"ydotaccent", 0x1E8F}, +{"ydotbelow", 0x1EF5}, +{"yeharabic", 0x064A}, +{"yehbarreearabic", 0x06D2}, +{"yehbarreefinalarabic", 0xFBAF}, +{"yehfinalarabic", 0xFEF2}, +{"yehhamzaabovearabic", 0x0626}, +{"yehhamzaabovefinalarabic", 0xFE8A}, +{"yehhamzaaboveinitialarabic", 0xFE8B}, +{"yehhamzaabovemedialarabic", 0xFE8C}, +{"yehinitialarabic", 0xFEF3}, +{"yehmedialarabic", 0xFEF4}, +{"yehmeeminitialarabic", 0xFCDD}, +{"yehmeemisolatedarabic", 0xFC58}, +{"yehnoonfinalarabic", 0xFC94}, +{"yehthreedotsbelowarabic", 0x06D1}, +{"yekorean", 0x3156}, +{"yen", 0x00A5}, +{"yenmonospace", 0xFFE5}, +{"yeokorean", 0x3155}, +{"yeorinhieuhkorean", 0x3186}, +{"yerahbenyomohebrew", 0x05AA}, +{"yerahbenyomolefthebrew", 0x05AA}, +{"yericyrillic", 0x044B}, +{"yerudieresiscyrillic", 0x04F9}, +{"yesieungkorean", 0x3181}, +{"yesieungpansioskorean", 0x3183}, +{"yesieungsioskorean", 0x3182}, +{"yetivhebrew", 0x059A}, +{"ygrave", 0x1EF3}, +{"yhook", 0x01B4}, +{"yhookabove", 0x1EF7}, +{"yiarmenian", 0x0575}, +{"yicyrillic", 0x0457}, +{"yikorean", 0x3162}, +{"yinyang", 0x262F}, +{"yiwnarmenian", 0x0582}, +{"ymonospace", 0xFF59}, +{"yod", 0x05D9}, +{"yoddagesh", 0xFB39}, +{"yoddageshhebrew", 0xFB39}, +{"yodhebrew", 0x05D9}, +{"yodyodhebrew", 0x05F2}, +{"yodyodpatahhebrew", 0xFB1F}, +{"yohiragana", 0x3088}, +{"yoikorean", 0x3189}, +{"yokatakana", 0x30E8}, +{"yokatakanahalfwidth", 0xFF96}, +{"yokorean", 0x315B}, +{"yosmallhiragana", 0x3087}, +{"yosmallkatakana", 0x30E7}, +{"yosmallkatakanahalfwidth", 0xFF6E}, +{"yotgreek", 0x03F3}, +{"yoyaekorean", 0x3188}, +{"yoyakorean", 0x3187}, +{"yoyakthai", 0x0E22}, +{"yoyingthai", 0x0E0D}, +{"yparen", 0x24B4}, +{"ypogegrammeni", 0x037A}, +{"ypogegrammenigreekcmb", 0x0345}, +{"yr", 0x01A6}, +{"yring", 0x1E99}, +{"ysuperior", 0x02B8}, +{"ytilde", 0x1EF9}, +{"yturned", 0x028E}, +{"yuhiragana", 0x3086}, +{"yuikorean", 0x318C}, +{"yukatakana", 0x30E6}, +{"yukatakanahalfwidth", 0xFF95}, +{"yukorean", 0x3160}, +{"yusbigcyrillic", 0x046B}, +{"yusbigiotifiedcyrillic", 0x046D}, +{"yuslittlecyrillic", 0x0467}, +{"yuslittleiotifiedcyrillic", 0x0469}, +{"yusmallhiragana", 0x3085}, +{"yusmallkatakana", 0x30E5}, +{"yusmallkatakanahalfwidth", 0xFF6D}, +{"yuyekorean", 0x318B}, +{"yuyeokorean", 0x318A}, +{"yyabengali", 0x09DF}, +{"yyadeva", 0x095F}, +{"z", 0x007A}, +{"zaarmenian", 0x0566}, +{"zacute", 0x017A}, +{"zadeva", 0x095B}, +{"zagurmukhi", 0x0A5B}, +{"zaharabic", 0x0638}, +{"zahfinalarabic", 0xFEC6}, +{"zahinitialarabic", 0xFEC7}, +{"zahiragana", 0x3056}, +{"zahmedialarabic", 0xFEC8}, +{"zainarabic", 0x0632}, +{"zainfinalarabic", 0xFEB0}, +{"zakatakana", 0x30B6}, +{"zaqefgadolhebrew", 0x0595}, +{"zaqefqatanhebrew", 0x0594}, +{"zarqahebrew", 0x0598}, +{"zayin", 0x05D6}, +{"zayindagesh", 0xFB36}, +{"zayindageshhebrew", 0xFB36}, +{"zayinhebrew", 0x05D6}, +{"zbopomofo", 0x3117}, +{"zcaron", 0x017E}, +{"zcircle", 0x24E9}, +{"zcircumflex", 0x1E91}, +{"zcurl", 0x0291}, +{"zdot", 0x017C}, +{"zdotaccent", 0x017C}, +{"zdotbelow", 0x1E93}, +{"zecyrillic", 0x0437}, +{"zedescendercyrillic", 0x0499}, +{"zedieresiscyrillic", 0x04DF}, +{"zehiragana", 0x305C}, +{"zekatakana", 0x30BC}, +{"zero", 0x0030}, +{"zeroarabic", 0x0660}, +{"zerobengali", 0x09E6}, +{"zerodeva", 0x0966}, +{"zerogujarati", 0x0AE6}, +{"zerogurmukhi", 0x0A66}, +{"zerohackarabic", 0x0660}, +{"zeroinferior", 0x2080}, +{"zeromonospace", 0xFF10}, +{"zerooldstyle", 0xF730}, +{"zeropersian", 0x06F0}, +{"zerosuperior", 0x2070}, +{"zerothai", 0x0E50}, +{"zerowidthjoiner", 0xFEFF}, +{"zerowidthnonjoiner", 0x200C}, +{"zerowidthspace", 0x200B}, +{"zeta", 0x03B6}, +{"zhbopomofo", 0x3113}, +{"zhearmenian", 0x056A}, +{"zhebrevecyrillic", 0x04C2}, +{"zhecyrillic", 0x0436}, +{"zhedescendercyrillic", 0x0497}, +{"zhedieresiscyrillic", 0x04DD}, +{"zihiragana", 0x3058}, +{"zikatakana", 0x30B8}, +{"zinorhebrew", 0x05AE}, +{"zlinebelow", 0x1E95}, +{"zmonospace", 0xFF5A}, +{"zohiragana", 0x305E}, +{"zokatakana", 0x30BE}, +{"zparen", 0x24B5}, +{"zretroflexhook", 0x0290}, +{"zstroke", 0x01B6}, +{"zuhiragana", 0x305A}, +{"zukatakana", 0x30BA}, + {0x00, 0} +}; + +double_glyph_list_t DoubleGlyphList[] = { +{"dalethatafpatah", {0x05D3, 0x05B2}}, +{"dalethatafpatahhebrew", {0x05D3, 0x05B2}}, +{"dalethatafsegol", {0x05D3, 0x05B1}}, +{"dalethatafsegolhebrew", {0x05D3, 0x05B1}}, +{"dalethiriq", {0x05D3, 0x05B4}}, +{"dalethiriqhebrew", {0x05D3, 0x05B4}}, +{"daletholam", {0x05D3, 0x05B9}}, +{"daletholamhebrew", {0x05D3, 0x05B9}}, +{"daletpatah", {0x05D3, 0x05B7}}, +{"daletpatahhebrew", {0x05D3, 0x05B7}}, +{"daletqamats", {0x05D3, 0x05B8}}, +{"daletqamatshebrew", {0x05D3, 0x05B8}}, +{"daletqubuts", {0x05D3, 0x05BB}}, +{"daletqubutshebrew", {0x05D3, 0x05BB}}, +{"daletsegol", {0x05D3, 0x05B6}}, +{"daletsegolhebrew", {0x05D3, 0x05B6}}, +{"daletsheva", {0x05D3, 0x05B0}}, +{"daletshevahebrew", {0x05D3, 0x05B0}}, +{"dalettsere", {0x05D3, 0x05B5}}, +{"dalettserehebrew", {0x05D3, 0x05B5}}, +{"finalkafqamats", {0x05DA, 0x05B8}}, +{"finalkafqamatshebrew", {0x05DA, 0x05B8}}, +{"finalkafsheva", {0x05DA, 0x05B0}}, +{"finalkafshevahebrew", {0x05DA, 0x05B0}}, +{"hamzadammaarabic", {0x0621, 0x064F}}, +{"hamzadammatanarabic", {0x0621, 0x064C}}, +{"hamzafathaarabic", {0x0621, 0x064E}}, +{"hamzafathatanarabic", {0x0621, 0x064B}}, +{"hamzalowkasraarabic", {0x0621, 0x0650}}, +{"hamzalowkasratanarabic", {0x0621, 0x064D}}, +{"hamzasukunarabic", {0x0621, 0x0652}}, +{"lamedholam", {0x05DC, 0x05B9}}, +{"lamedholamhebrew", {0x05DC, 0x05B9}}, +{"noonhehinitialarabic", {0xFEE7, 0xFEEC}}, +{"qofhatafpatah", {0x05E7, 0x05B2}}, +{"qofhatafpatahhebrew", {0x05E7, 0x05B2}}, +{"qofhatafsegol", {0x05E7, 0x05B1}}, +{"qofhatafsegolhebrew", {0x05E7, 0x05B1}}, +{"qofhiriq", {0x05E7, 0x05B4}}, +{"qofhiriqhebrew", {0x05E7, 0x05B4}}, +{"qofholam", {0x05E7, 0x05B9}}, +{"qofholamhebrew", {0x05E7, 0x05B9}}, +{"qofpatah", {0x05E7, 0x05B7}}, +{"qofpatahhebrew", {0x05E7, 0x05B7}}, +{"qofqamats", {0x05E7, 0x05B8}}, +{"qofqamatshebrew", {0x05E7, 0x05B8}}, +{"qofqubuts", {0x05E7, 0x05BB}}, +{"qofqubutshebrew", {0x05E7, 0x05BB}}, +{"qofsegol", {0x05E7, 0x05B6}}, +{"qofsegolhebrew", {0x05E7, 0x05B6}}, +{"qofsheva", {0x05E7, 0x05B0}}, +{"qofshevahebrew", {0x05E7, 0x05B0}}, +{"qoftsere", {0x05E7, 0x05B5}}, +{"qoftserehebrew", {0x05E7, 0x05B5}}, +{"reshhatafpatah", {0x05E8, 0x05B2}}, +{"reshhatafpatahhebrew", {0x05E8, 0x05B2}}, +{"reshhatafsegol", {0x05E8, 0x05B1}}, +{"reshhatafsegolhebrew", {0x05E8, 0x05B1}}, +{"reshhiriq", {0x05E8, 0x05B4}}, +{"reshhiriqhebrew", {0x05E8, 0x05B4}}, +{"reshholam", {0x05E8, 0x05B9}}, +{"reshholamhebrew", {0x05E8, 0x05B9}}, +{"reshpatah", {0x05E8, 0x05B7}}, +{"reshpatahhebrew", {0x05E8, 0x05B7}}, +{"reshqamats", {0x05E8, 0x05B8}}, +{"reshqamatshebrew", {0x05E8, 0x05B8}}, +{"reshqubuts", {0x05E8, 0x05BB}}, +{"reshqubutshebrew", {0x05E8, 0x05BB}}, +{"reshsegol", {0x05E8, 0x05B6}}, +{"reshsegolhebrew", {0x05E8, 0x05B6}}, +{"reshsheva", {0x05E8, 0x05B0}}, +{"reshshevahebrew", {0x05E8, 0x05B0}}, +{"reshtsere", {0x05E8, 0x05B5}}, +{"reshtserehebrew", {0x05E8, 0x05B5}}, +{"shaddafathatanarabic", {0x0651, 0x064B}}, +{"tchehmeeminitialarabic", {0xFB7C, 0xFEE4}}, + {0x00, {0,0}} +}; + +treble_glyph_list_t TrebleGlyphList[] = { + {"lamedholamdagesh", {0x05DC, 0x05B9, 0x05BC}}, + {"lamedholamdageshhebrew", {0x05DC, 0x05B9, 0x05BC}}, + {"lammeemjeeminitialarabic", {0xFEDF, 0xFEE4, 0xFEA0}}, + {"lammeemkhahinitialarabic", {0xFEDF, 0xFEE4, 0xFEA8}}, + {0x00, {0,0,0}} +}; + +quad_glyph_list_t QuadGlyphList[] = { + {"rehyehaleflamarabic", {0x0631, 0xFEF3, 0xFE8E, 0x0644}}, + {0x00, {0,0,0,0}} +}; diff --git a/base/gsagl.h b/base/gsagl.h new file mode 100644 index 00000000..949789a8 --- /dev/null +++ b/base/gsagl.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2001-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ +/* We need several tables, to hold the glyph names and a variable number of + * Unicode code points. + */ + +#ifndef gsagl_h_INCLUDED +#define gsagl_h_INCLUDED + +typedef struct single_glyph_list_s { + const char *Glyph; + unsigned short Unicode; +} single_glyph_list_t; + +typedef struct double_glyph_list_s { + const char *Glyph; + unsigned short Unicode[2]; +} double_glyph_list_t; + +typedef struct treble_glyph_list_s { + const char *Glyph; + unsigned short Unicode[3]; +} treble_glyph_list_t; + +typedef struct quad_glyph_list_s { + const char *Glyph; + unsigned short Unicode[4]; +} quad_glyph_list_t; + +#endif diff --git a/base/gsbitops.h b/base/gsbitops.h index 4087f19b..127c24aa 100644 --- a/base/gsbitops.h +++ b/base/gsbitops.h @@ -257,7 +257,7 @@ static int inline sample_store_next8(uint value, byte **dptr, int *dbit, int dbp if ( *dbit ^= 4 ) *dbbyte = (byte)(value << 4); else - *(*dptr)++ = *dbbyte | ((byte)value);\ + *(*dptr)++ = *dbbyte | ((byte)value); break; case 2: *(*dptr)++ = (byte)value; diff --git a/base/gscdevn.c b/base/gscdevn.c index 94ffc562..41febb7f 100644 --- a/base/gscdevn.c +++ b/base/gscdevn.c @@ -205,6 +205,31 @@ gs_attachcolorant(char *sep_name, gs_gstate * pgs) return 0; } +int +gs_attach_colorant_to_space(char *sep_name, gs_color_space *pcs, gs_color_space *colorant_space, gs_memory_t *mem) +{ + gs_device_n_colorant * patt; + + if (pcs->type != &gs_color_space_type_DeviceN) + return_error(gs_error_rangecheck); + + /* Allocate an attribute list element for our linked list of colorants */ + rc_alloc_struct_1(patt, gs_device_n_colorant, &st_device_n_colorant, + mem, return_error(gs_error_VMerror), + "gs_attachattributrescolorspace"); + + /* Point our attribute list entry to the attribute color space */ + patt->colorant_name = sep_name; + patt->cspace = colorant_space; + rc_increment_cs(patt->cspace); + + /* Link our new attribute color space to the DeviceN color space */ + patt->next = pcs->params.device_n.colorants; + pcs->params.device_n.colorants = patt; + + return 0; +} + #if 0 /* Unused; Unsupported by gx_serialize_device_n_map. */ /* * Set the DeviceN tint transformation procedure. @@ -557,6 +582,14 @@ check_DeviceN_component_names(const gs_color_space * pcs, gs_gstate * pgs) pcolor_component_map->cspace_id = pcs->id; pcolor_component_map->num_colorants = dev->color_info.num_components; pcolor_component_map->sep_type = SEP_OTHER; + + /* If the named color profile supports the components, don't use + the alternate tint transform. */ + if (gsicc_support_named_color(pcs, pgs)) { + pcolor_component_map->use_alt_cspace = false; + return 0; + } + /* * Always use the alternate color space if the current device is * using an additive color model. The exception is if we have a separation @@ -577,7 +610,6 @@ check_DeviceN_component_names(const gs_color_space * pcs, gs_gstate * pgs) * additive color space then use the alternate tint transform. */ - non_match = false; for(i = 0; i < num_comp; i++ ) { /* * Get the character string and length for the component name. @@ -748,11 +780,11 @@ gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_gstate * pgs) params.retain_any_comps = (pgs->overprint && pgs->is_fill_color) || (pgs->stroke_overprint && !pgs->is_fill_color); + params.drawn_comps = 0; if (params.retain_any_comps) { int i, ncomps = pcs->params.device_n.num_components; params.is_fill_color = pgs->is_fill_color; /* for fill_stroke */ - params.drawn_comps = 0; for (i = 0; i < ncomps; i++) { int mcomp = pcmap->color_map[i]; if (mcomp >= 0) @@ -770,7 +802,7 @@ gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_gstate * pgs) /* Finalize contents of a DeviceN color space. */ static void -gx_final_DeviceN(const gs_color_space * pcs) +gx_final_DeviceN(gs_color_space * pcs) { gs_device_n_colorant * pnextatt, * patt = pcs->params.device_n.colorants; uint num_proc_names = pcs->params.device_n.num_process_names; @@ -797,6 +829,10 @@ gx_final_DeviceN(const gs_color_space * pcs) rc_decrement(patt, "gx_adjust_DeviceN"); patt = pnextatt; } + if (pcs->params.device_n.devn_process_space) + rc_decrement_only(pcs->params.device_n.devn_process_space, "gx_final_DeviceN"); + /* Ensure idempotency */ + memset(&pcs->params.device_n, 0, sizeof(pcs->params.device_n)); } /* ---------------- Serialization. -------------------------------- */ diff --git a/base/gscdevn.h b/base/gscdevn.h index f35e9b0e..b2b6c5de 100644 --- a/base/gscdevn.h +++ b/base/gscdevn.h @@ -78,4 +78,14 @@ int gx_serialize_device_n_map(const gs_color_space * pcs, gs_device_n_map * m, s */ int gs_attachcolorant(char *sep_name, gs_gstate * pgs); +/* + * This is the same routine as above, but more general. Instead of assuming that + * the current coloru space is hte colorant space, and the saved graphics state + * contains the DeviceN space, we pass both those in, along with the memory + * allocater we want the routine to use. + * This is for the pdfi PDF interpreter (and potentially any other non-PostScript + * interpreter) + */ +int gs_attach_colorant_to_space(char *sep_name, gs_color_space *pcs, gs_color_space *colorant_space, gs_memory_t *mem); + #endif /* gscdevn_INCLUDED */ diff --git a/base/gscms.h b/base/gscms.h index caedcb90..7fb362fe 100644 --- a/base/gscms.h +++ b/base/gscms.h @@ -29,7 +29,7 @@ #define NUM_DEVICE_PROFILES 4 #define NUM_SOURCE_PROFILES 3 #define GS_DEFAULT_DEVICE_PROFILE 0 -#define GS_GRAPHIC_DEVICE_PROFILE 1 +#define GS_VECTOR_DEVICE_PROFILE 1 #define GS_IMAGE_DEVICE_PROFILE 2 #define GS_TEXT_DEVICE_PROFILE 3 @@ -210,7 +210,7 @@ typedef enum { GS_UNTOUCHED_TAG = 0x0, /* UNTOUCHED *must* be 0 -- transparency code relies on this */ GS_TEXT_TAG = 0x1, GS_IMAGE_TAG = 0x2, - GS_PATH_TAG = 0x4, + GS_VECTOR_TAG = 0x4, GS_UNKNOWN_TAG = 0x40, GS_DEVICE_ENCODES_TAGS = 0x80 } gs_graphics_type_tag_t; diff --git a/base/gscolor2.c b/base/gscolor2.c index 85238bf4..e730ae02 100644 --- a/base/gscolor2.c +++ b/base/gscolor2.c @@ -294,16 +294,18 @@ gx_set_overprint_Indexed(const gs_color_space * pcs, gs_gstate * pgs) /* Color space finalization ditto. */ static void -gx_final_Indexed(const gs_color_space * pcs) +gx_final_Indexed(gs_color_space * pcs) { if (pcs->params.indexed.use_proc) { rc_adjust_const(pcs->params.indexed.lookup.map, -1, "gx_adjust_Indexed"); + pcs->params.indexed.lookup.map = NULL; } else { byte *data = (byte *)pcs->params.indexed.lookup.table.data; /* Break 'const'. */ gs_free_string(pcs->rc.memory, data, pcs->params.indexed.lookup.table.size, "gx_final_Indexed"); + pcs->params.indexed.lookup.table.data = NULL; } } diff --git a/base/gscolor3.c b/base/gscolor3.c index 66cadecd..951f6741 100644 --- a/base/gscolor3.c +++ b/base/gscolor3.c @@ -109,7 +109,7 @@ gs_shfill(gs_gstate * pgs, const gs_shading_t * psh) /* make sure the tag gets set correctly */ if (pgs->show_gstate == NULL) - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ else ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ diff --git a/base/gscoord.c b/base/gscoord.c index 8343a091..f32e4cd3 100644 --- a/base/gscoord.c +++ b/base/gscoord.c @@ -130,16 +130,150 @@ gs_defaultmatrix(const gs_gstate * pgs, gs_matrix * pmat) int gs_setdefaultmatrix(gs_gstate * pgs, const gs_matrix * pmat) { - if (pmat == NULL) + if (pmat == NULL) { pgs->ctm_default_set = false; - else { + pgs->ctm_initial_set = false; + } else { + gx_device *dev; + pgs->ctm_default = *pmat; pgs->ctm_default_set = true; + + /* We also store the current 'initial' matrix, so we can spot + * changes in this in future. */ + dev = gs_currentdevice_inline(pgs); + gs_deviceinitialmatrix(dev, &pgs->ctm_initial); + pgs->ctm_initial_set = 1; } return 0; } int +gs_updatematrices(gs_gstate *pgs) +{ + gx_device *dev; + gs_matrix newdefault, init, t, inv, newctm; + int code; +#ifdef DEBUG + gs_matrix *mat; +#endif + + /* Read the current device initial matrix. */ + dev = gs_currentdevice_inline(pgs); + gs_deviceinitialmatrix(dev, &init); + +#ifdef DEBUG + if (gs_debug_c('x')) + dlprintf("[x]updatematrices\n"); +#endif + + if (pgs->ctm_default_set == 0 || + pgs->ctm_initial_set == 0) { + /* If neither default or initial are set, then store them for the + * first time. */ + pgs->ctm_initial = init; + pgs->ctm_initial_set = 1; + pgs->ctm_default = init; + pgs->ctm_default_set = 1; +#ifdef DEBUG + if (gs_debug_c('x')) { + mat = &pgs->ctm_initial; + dlprintf6("storing initial/default = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + } +#endif + return 0; + } + +#ifdef DEBUG + if (gs_debug_c('x')) { + mat = &init; + dlprintf6("initial = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + mat = &pgs->ctm_default; + dlprintf6("default = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + mat = (gs_matrix *)&pgs->ctm; + dlprintf6("ctm = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + mat = &pgs->ctm_initial; + dlprintf6("stored initial = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + } +#endif + /* If no change, then nothing else to do here. */ + if (init.xx == pgs->ctm_initial.xx && + init.xy == pgs->ctm_initial.xy && + init.yx == pgs->ctm_initial.yx && + init.yy == pgs->ctm_initial.yy && + init.tx == pgs->ctm_initial.tx && + init.ty == pgs->ctm_initial.ty) + return 0; + + /* So, the initial matrix has changed from what it was + * the last time the default matrix was set. The default + * matrix is some modification of the initial matrix + * (typically a scale, or a translation, or a flip or + * some combination thereof). Now the initial matrix + * has changed (possibly because of Nup, or because of + * a device doing Duplex etc), the default matrix is + * almost certainly wrong. We therefore adjust it here.*/ + + /* So originally: old_default = modification.old_init + * and we want: new_default = modification.new_init + * + * So: modification = old_default.INV(old_init) + * new_default = old_default.INV(old_init).new_init + */ + code = gs_matrix_invert(&pgs->ctm_initial, &inv); + if (code < 0) + return code; + code = gs_matrix_multiply(&pgs->ctm_default, &inv, &t); + if (code < 0) + return code; + code = gs_matrix_multiply(&t, &init, &newdefault); + if (code < 0) + return code; + + /* Now, the current ctm is similarly derived from the + * old default. We want to update it to be derived (in the + * same way) from the new default. + * + * So: old_ctm = modification.old_default + * old_ctm.INV(old_default) = modification + * And: new_ctm = modification.new_default + * = old_ctm.INV(old_default).new_default + */ + code = gs_matrix_invert(&pgs->ctm_default, &inv); + if (code < 0) + return code; + code = gs_matrix_multiply((gs_matrix *)&pgs->ctm, &inv, &t); + if (code < 0) + return code; + code = gs_matrix_multiply(&t, &newdefault, &newctm); + if (code < 0) + return code; + + pgs->ctm_initial = init; + pgs->ctm_default = newdefault; + gs_setmatrix(pgs, &newctm); + +#ifdef DEBUG + if (gs_debug_c('x')) { + mat = &pgs->ctm_default; + dlprintf6("new default = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + mat = (gs_matrix *)&pgs->ctm; + dlprintf6("new ctm = %g %g %g %g %g %g\n", mat->xx, mat->xy, mat->yx, mat->yy, mat->tx, mat->ty); + } +#endif + + /* This is a bit nasty. This resets the clipping box to the page. + * We need to do this, because otherwise the clipping box is + * not updated with the ctm, and (typically) the entire contents + * of the page end up clipped away. This will break usages where + * we run 1 file (or set of postscript commands) to set the clipping + * box, and then another file to actually draw stuff to be clipped. + * Given this will only go wrong in the case where the device is + * Nupping or Duplexing, we'll live with this for now. */ + return gs_initclip(pgs); +} + +int gs_currentmatrix(const gs_gstate * pgs, gs_matrix * pmat) { *pmat = ctm_only(pgs); diff --git a/base/gscoord.h b/base/gscoord.h index 0c18f6c6..af05c9af 100644 --- a/base/gscoord.h +++ b/base/gscoord.h @@ -38,7 +38,8 @@ int gs_initmatrix(gs_gstate *), int gs_setdefaultmatrix(gs_gstate *, const gs_matrix *), gs_currentcharmatrix(gs_gstate *, gs_matrix *, bool), gs_setcharmatrix(gs_gstate *, const gs_matrix *), - gs_settocharmatrix(gs_gstate *); + gs_settocharmatrix(gs_gstate *), + gs_updatematrices(gs_gstate *); /* Coordinate transformation */ int gs_transform(gs_gstate *, double, double, gs_point *), diff --git a/base/gscparam.c b/base/gscparam.c index 1b4522a8..b3934417 100644 --- a/base/gscparam.c +++ b/base/gscparam.c @@ -53,6 +53,7 @@ struct gs_c_param_s { gs_c_param_value value; gs_param_type type; void *alternate_typed_data; + int error; }; /* GC descriptor and procedures */ @@ -261,6 +262,7 @@ c_param_add(gs_c_param_list * plist, gs_param_name pkey) } pparam->key.size = len; pparam->alternate_typed_data = 0; + pparam->error = 0; return pparam; } @@ -450,6 +452,7 @@ static param_proc_xmit_typed(c_param_read_typed); static param_proc_next_key(c_param_get_next_key); static param_proc_get_policy(c_param_read_get_policy); static param_proc_signal_error(c_param_read_signal_error); +static param_proc_read_signalled_error(c_param_read_signalled_error); static param_proc_commit(c_param_read_commit); static const gs_param_list_procs c_read_procs = { @@ -461,7 +464,8 @@ static const gs_param_list_procs c_read_procs = NULL, /* requested, N/A */ c_param_read_get_policy, c_param_read_signal_error, - c_param_read_commit + c_param_read_commit, + c_param_read_signalled_error }; /* Switch a list from writing to reading. */ @@ -596,10 +600,24 @@ c_param_read_get_policy(gs_param_list * plist, gs_param_name pkey) static int c_param_read_signal_error(gs_param_list * plist, gs_param_name pkey, int code) { - return code; + gs_c_param_list *const cplist = (gs_c_param_list *)plist; + gs_c_param *pparam = c_param_find(cplist, pkey, false); + + if (pparam) + pparam->error = code; + + return 0; } static int c_param_read_commit(gs_param_list * plist) { return 0; } +static int +c_param_read_signalled_error(gs_param_list * plist, gs_param_name pkey) +{ + gs_c_param_list *const cplist = (gs_c_param_list *)plist; + gs_c_param *pparam = c_param_find(cplist, pkey, false); + + return (pparam ? pparam->error : 0); +} diff --git a/base/gscscie.c b/base/gscscie.c index 3bc94aed..d39f0244 100644 --- a/base/gscscie.c +++ b/base/gscscie.c @@ -148,59 +148,63 @@ gx_install_CIE(gs_color_space * pcs, gs_gstate * pgs) /* Free params for a CIE color space */ static void -gx_final_CIEDEFG(const gs_color_space * pcs) +gx_final_CIEDEFG(gs_color_space * pcs) { - gs_color_space *pcs_noconst = (gs_color_space *)pcs; - if (pcs->icc_equivalent != NULL) { - rc_decrement(pcs_noconst->icc_equivalent, "gx_final_CIEDEFG"); + rc_decrement(pcs->icc_equivalent, "gx_final_CIEDEFG"); + pcs->icc_equivalent = NULL; } if (pcs->cmm_icc_profile_data != NULL) { - gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEDEFG"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEDEFG"); + pcs->cmm_icc_profile_data = NULL; } - rc_decrement(pcs_noconst->params.defg, "gx_final_CIEDEFG"); + rc_decrement(pcs->params.defg, "gx_final_CIEDEFG"); + pcs->params.defg = NULL; } static void -gx_final_CIEDEF(const gs_color_space * pcs) +gx_final_CIEDEF(gs_color_space * pcs) { - gs_color_space *pcs_noconst = (gs_color_space *)pcs; - if (pcs->icc_equivalent != NULL) { - rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEDEF"); + rc_decrement(pcs->icc_equivalent,"gx_final_CIEDEF"); + pcs->icc_equivalent = NULL; } if (pcs->cmm_icc_profile_data != NULL) { - gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEDEF"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEDEF"); + pcs->cmm_icc_profile_data = NULL; } - rc_decrement(pcs_noconst->params.def, "gx_final_CIEDEF"); + rc_decrement(pcs->params.def, "gx_final_CIEDEF"); + pcs->params.def = NULL; } static void -gx_final_CIEABC(const gs_color_space * pcs) +gx_final_CIEABC(gs_color_space * pcs) { - gs_color_space *pcs_noconst = (gs_color_space *)pcs; - if (pcs->icc_equivalent != NULL) { - rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEABC"); + rc_decrement(pcs->icc_equivalent,"gx_final_CIEABC"); + pcs->icc_equivalent = NULL; } if (pcs->cmm_icc_profile_data != NULL) { - gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEABC"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEABC"); + pcs->cmm_icc_profile_data = NULL; } - rc_decrement(pcs_noconst->params.abc, "gx_final_CIEABC"); + rc_decrement(pcs->params.abc, "gx_final_CIEABC"); + pcs->params.abc = NULL; } static void -gx_final_CIEA(const gs_color_space * pcs) +gx_final_CIEA(gs_color_space * pcs) { - gs_color_space *pcs_noconst = (gs_color_space *)pcs; - if (pcs->icc_equivalent != NULL) { - rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEA"); + rc_decrement(pcs->icc_equivalent,"gx_final_CIEA"); + pcs->icc_equivalent = NULL; } if (pcs->cmm_icc_profile_data != NULL) { - gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEA"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEA"); + pcs->cmm_icc_profile_data = NULL; } - rc_decrement(pcs_noconst->params.a, "gx_adjust_cspace_CIEA"); + rc_decrement(pcs->params.a, "gx_adjust_cspace_CIEA"); + pcs->params.a = NULL; } /* ---------------- Procedures ---------------- */ diff --git a/base/gscsepr.c b/base/gscsepr.c index 34118988..10400106 100644 --- a/base/gscsepr.c +++ b/base/gscsepr.c @@ -210,11 +210,13 @@ gx_set_overprint_Separation(const gs_color_space * pcs, gs_gstate * pgs) /* Finalize contents of a Separation color space. */ static void -gx_final_Separation(const gs_color_space * pcs) +gx_final_Separation(gs_color_space * pcs) { rc_adjust_const(pcs->params.separation.map, -1, "gx_adjust_Separation"); + pcs->params.separation.map = NULL; gs_free_object(pcs->params.separation.mem, pcs->params.separation.sep_name, "gx_final_Separation"); + pcs->params.separation.sep_name = NULL; } /* ------ Constructors/accessors ------ */ @@ -454,9 +456,11 @@ check_Separation_component_name(const gs_color_space * pcs, gs_gstate * pgs) pcolor_component_map->sep_type = pcs->params.separation.sep_type; /* * If this is a None or All separation then we do not need to - * use the alternate color space. - */ - if (pcs->params.separation.sep_type != SEP_OTHER) { + * use the alternate color space. Also if the named color + * profile supports the component, don't use the alternate + * tint transform. */ + if (pcs->params.separation.sep_type != SEP_OTHER || + gsicc_support_named_color(pcs, pgs)) { pcolor_component_map->use_alt_cspace = false; return 0; } diff --git a/base/gscspace.c b/base/gscspace.c index 81baac9a..d662bc02 100644 --- a/base/gscspace.c +++ b/base/gscspace.c @@ -92,6 +92,8 @@ public_st_base_color_space(); /* ------ Create/copy/destroy ------ */ +/* Ghostscript object finalizers can be called many times and hence + * must be idempotent. */ static void gs_cspace_final(const gs_memory_t *cmem, void *vptr) { @@ -100,17 +102,20 @@ gs_cspace_final(const gs_memory_t *cmem, void *vptr) if (pcs->interpreter_free_cspace_proc != NULL) { (*pcs->interpreter_free_cspace_proc) ((gs_memory_t *)cmem, pcs); + pcs->interpreter_free_cspace_proc = NULL; } if (pcs->type->final) pcs->type->final(pcs); if_debug2m('c', cmem, "[c]cspace final "PRI_INTPTR" %d\n", (intptr_t)pcs, (int)pcs->id); rc_decrement_only_cs(pcs->base_space, "gs_cspace_final"); - if (pcs->params.device_n.devn_process_space != NULL) + pcs->base_space = NULL; + if (pcs->params.device_n.devn_process_space != NULL) { rc_decrement_only_cs(pcs->params.device_n.devn_process_space, "gs_cspace_final"); + pcs->params.device_n.devn_process_space = NULL; + } /* No need to decrement the ICC profile data. It is handled by the finalize of the ICC space which is called above using pcs->type->final(pcs); */ - } static gs_color_space * @@ -425,7 +430,8 @@ void cs_adjust_counts_icc(gs_gstate *pgs, int delta) gs_color_space *pcs = gs_currentcolorspace_inline(pgs); if (pcs) { - cs_adjust_counts(pgs, delta); + cs_adjust_color_count(pgs, delta); + rc_adjust_const(pcs, delta, "cs_adjust_counts_icc"); } } @@ -434,7 +440,8 @@ void cs_adjust_swappedcounts_icc(gs_gstate *pgs, int delta) gs_color_space *pcs = gs_swappedcolorspace_inline(pgs); if (pcs) { - cs_adjust_swappedcounts(pgs, delta); + cs_adjust_swappedcolor_count(pgs, delta); + rc_adjust_const(pcs, delta, "cs_adjust_swappedcounts_icc"); } } @@ -513,16 +520,7 @@ gx_set_spot_only_overprint(gs_gstate* pgs) { gs_overprint_params_t params = { 0 }; gx_device* dev = pgs->device; - gx_color_index drawn_comps = 0; - gx_device_color_info* pcinfo = (dev == 0 ? 0 : &dev->color_info); - - if (dev) { - /* check if color model behavior must be determined */ - if (pcinfo->opmode == GX_CINFO_OPMODE_UNKNOWN) - drawn_comps = check_cmyk_color_model_comps(dev); - else - drawn_comps = pcinfo->process_comps; - } + gx_color_index drawn_comps = dev == NULL ? 0 : gx_get_process_comps(dev); params.retain_any_comps = true; params.op_state = OP_STATE_NONE; @@ -595,10 +593,19 @@ check_cmyk_color_model_comps(gx_device * dev) gx_device_color_info * pcinfo = &dev->color_info; uchar ncomps = pcinfo->num_components; int cyan_c, magenta_c, yellow_c, black_c; - subclass_color_mappings scm; frac frac_14 = frac_1 / 4; frac out[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index process_comps; + const gx_cm_color_map_procs *cmprocs; + const gx_device *cmdev; + + + if (pcinfo->num_components < 4 || + pcinfo->polarity == GX_CINFO_POLARITY_ADDITIVE || + pcinfo->gray_index == GX_CINFO_COMP_NO_INDEX) { + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED_NOT; + return 0; + } /* check for the appropriate components */ if ( ncomps < 4 || @@ -629,26 +636,34 @@ check_cmyk_color_model_comps(gx_device * dev) return 0; /* check the mapping */ - scm = get_color_mapping_procs_subclass(dev); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); - map_cmyk_subclass(scm, frac_14, frac_0, frac_0, frac_0, out); - if (!check_single_comp(cyan_c, frac_14, ncomps, out)) + cmprocs->map_cmyk(cmdev, frac_14, frac_0, frac_0, frac_0, out); + if (!check_single_comp(cyan_c, frac_14, ncomps, out)) { + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED_NOT; return 0; - map_cmyk_subclass(scm, frac_0, frac_14, frac_0, frac_0, out); - if (!check_single_comp(magenta_c, frac_14, ncomps, out)) + } + cmprocs->map_cmyk(cmdev, frac_0, frac_14, frac_0, frac_0, out); + if (!check_single_comp(magenta_c, frac_14, ncomps, out)) { + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED_NOT; return 0; - map_cmyk_subclass(scm, frac_0, frac_0, frac_14, frac_0, out); - if (!check_single_comp(yellow_c, frac_14, ncomps, out)) - return false; - map_cmyk_subclass(scm, frac_0, frac_0, frac_0, frac_14, out); - if (!check_single_comp(black_c, frac_14, ncomps, out)) + } + cmprocs->map_cmyk(cmdev, frac_0, frac_0, frac_14, frac_0, out); + if (!check_single_comp(yellow_c, frac_14, ncomps, out)) { + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED_NOT; return 0; + } + cmprocs->map_cmyk(cmdev, frac_0, frac_0, frac_0, frac_14, out); + if (!check_single_comp(black_c, frac_14, ncomps, out)) { + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED_NOT; + return 0; + } process_comps = ((gx_color_index)1 << cyan_c) | ((gx_color_index)1 << magenta_c) | ((gx_color_index)1 << yellow_c) | ((gx_color_index)1 << black_c); - pcinfo->opmode = GX_CINFO_OPMODE; + pcinfo->opmsupported = GX_CINFO_OPMSUPPORTED; pcinfo->process_comps = process_comps; pcinfo->black_component = black_c; return process_comps; @@ -671,7 +686,7 @@ gx_set_overprint_DeviceCMYK(const gs_color_space * pcs, gs_gstate * pgs) if ( !pgs->overprint || pgs->overprint_mode != 1 || pcinfo == 0 || - pcinfo->opmode == GX_CINFO_OPMODE_NOT ) + pcinfo->opmsupported == GX_CINFO_OPMSUPPORTED_NOT) return gx_spot_colors_set_overprint(pcs, pgs); /* Share code with CMYK ICC case */ return gx_set_overprint_cmyk(pcs, pgs); @@ -695,7 +710,6 @@ gx_set_overprint_DeviceCMYK(const gs_color_space * pcs, gs_gstate * pgs) int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs) { gx_device * dev = pgs->device; - gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); gx_color_index drawn_comps = 0; gs_overprint_params_t params = { 0 }; gx_device_color *pdc; @@ -717,11 +731,7 @@ int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs) gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &(output_profile), &render_cond); - /* check if color model behavior must be determined */ - if (pcinfo->opmode == GX_CINFO_OPMODE_UNKNOWN) - drawn_comps = check_cmyk_color_model_comps(dev); - else - drawn_comps = pcinfo->process_comps; + drawn_comps = gx_get_process_comps(dev); } if_debug1m(gs_debug_flag_overprint, pgs->memory, diff --git a/base/gsdcolor.h b/base/gsdcolor.h index 367dcd48..253799ed 100644 --- a/base/gsdcolor.h +++ b/base/gsdcolor.h @@ -271,7 +271,6 @@ struct gx_device_color_s { ushort num_components; byte c_base[GX_DEVICE_COLOR_MAX_COMPONENTS]; uint c_level[GX_DEVICE_COLOR_MAX_COMPONENTS]; - ushort /*gx_color_value */ alpha; #if GX_DEVICE_COLOR_MAX_COMPONENTS <= ARCH_SIZEOF_SHORT * 8 ushort plane_mask; #else @@ -371,7 +370,6 @@ struct gx_device_color_saved_s { struct _svcol { byte c_base[GX_DEVICE_COLOR_MAX_COMPONENTS]; uint c_level[GX_DEVICE_COLOR_MAX_COMPONENTS]; - ushort alpha; } colored; struct _svdevn { ushort values[GX_DEVICE_COLOR_MAX_COMPONENTS]; diff --git a/base/gsdevice.c b/base/gsdevice.c index 630ed493..b02c324c 100644 --- a/base/gsdevice.c +++ b/base/gsdevice.c @@ -37,6 +37,7 @@ #include "gxcspace.h" #include "gsicc_manage.h" #include "gscms.h" +#include "gxgetbit.h" /* Include the extern for the device list. */ extern_gs_lib_device_list(); @@ -161,17 +162,6 @@ gx_device_reloc_ptr(gx_device * dev, gc_state_t * gcst) return RELOC_OBJ(dev); /* gcst implicit */ } -/* Set up the device procedures in the device structure. */ -/* Also copy old fields to new ones. */ -void -gx_device_set_procs(gx_device * dev) -{ - if (dev->static_procs != 0) { /* 0 if already populated */ - dev->procs = *dev->static_procs; - dev->static_procs = 0; - } -} - /* Flush buffered output to the device */ int gs_flushpage(gs_gstate * pgs) @@ -247,10 +237,27 @@ gs_copyscanlines(gx_device * dev, int start_y, byte * data, uint size, uint count = size / line_size; uint i; byte *dest = data; + gs_int_rect rect; + gs_get_bits_params_t params; - for (i = 0; i < count; i++, dest += line_size) { - int code = (*dev_proc(dev, get_bits)) (dev, start_y + i, dest, NULL); + rect.p.x = 0; + rect.q.x = dev->width; + params.x_offset = 0; + params.raster = bitmap_raster(dev->width * dev->color_info.depth); + for (i = 0; i < count; i++, dest += line_size) { + int code; + + rect.p.y = start_y+i; + rect.q.y = start_y+i+1; + + params.options = (GB_ALIGN_ANY | + GB_RETURN_COPY | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.data[0] = dest; + code = (*dev_proc(dev, get_bits_rectangle))(dev, &rect, ¶ms); if (code < 0) { /* Might just be an overrun. */ if (start_y + i == dev->height) @@ -356,7 +363,7 @@ gx_device_make_struct_type(gs_memory_struct_type_t *st, { if (dev->stype) *st = *dev->stype; - else if (dev_proc(dev, get_xfont_procs) == gx_forward_get_xfont_procs) + else if (dev_proc(dev, get_page_device) == gx_forward_get_page_device) *st = st_device_forward; else *st = st_device; @@ -409,34 +416,29 @@ gs_copydevice2(gx_device ** pnew_dev, const gx_device * dev, bool keep_open, gs_free_object(mem->non_gc_memory, a_std, "gs_copydevice(stype)"); return_error(gs_error_VMerror); } - gx_device_init(new_dev, dev, mem, false); - gx_device_set_procs(new_dev); + code = gx_device_init(new_dev, dev, mem, false); new_dev->stype = new_std; new_dev->stype_is_dynamic = new_std != std; /* * keep_open is very dangerous. On the other hand, so is copydevice in * general, since it just copies the bits without any regard to pointers - * (including self-pointers) that they may contain. We handle this by - * making the default finish_copydevice forbid copying of anything other - * than the device prototype. + * (including self-pointers) that they may contain. */ new_dev->is_open = dev->is_open && keep_open; - fill_dev_proc(new_dev, finish_copydevice, gx_default_finish_copydevice); - /* We really want to be able to interrogate the device for capabilities - * and/or preferences right from when it is created, so set dev_spec_op - * now (if not already set). - */ - fill_dev_proc(new_dev, dev_spec_op, gx_default_dev_spec_op); - code = dev_proc(new_dev, finish_copydevice)(new_dev, dev); if (code < 0) { gs_free_object(mem, new_dev, "gs_copydevice(device)"); #if 0 /* gs_free_object above calls gx_device_finalize, - which closes the device and releaszes its stype, i.e. a_std. */ + which closes the device and releases its stype, i.e. a_std. */ if (a_std) gs_free_object(dev->memory->non_gc_memory, a_std, "gs_copydevice(stype)"); #endif return code; } + /* We really want to be able to interrogate the device for capabilities + * and/or preferences right from when it is created, so set dev_spec_op + * now (if not already set). + */ + fill_dev_proc(new_dev, dev_spec_op, gx_default_dev_spec_op); *pnew_dev = new_dev; return 0; } @@ -619,15 +621,25 @@ gs_setdevice_no_init(gs_gstate * pgs, gx_device * dev) } /* Initialize a just-allocated device. */ -void +int gx_device_init(gx_device * dev, const gx_device * proto, gs_memory_t * mem, bool internal) { memcpy(dev, proto, proto->params_size); - dev->memory = mem; + dev->initialize_device_procs = proto->initialize_device_procs; + if (dev->initialize_device_procs != NULL) + dev->initialize_device_procs(dev); + dev->memory = mem; /* must precede initialize_device call so devices can use it */ + if (dev->procs.initialize_device) { + int code = dev->procs.initialize_device(dev); + if (code < 0) + return code; + } dev->retained = !internal; rc_init(dev, mem, (internal ? 0 : 1)); rc_increment(dev->icc_struct); + + return 0; } void @@ -635,6 +647,14 @@ gx_device_init_on_stack(gx_device * dev, const gx_device * proto, gs_memory_t * mem) { memcpy(dev, proto, proto->params_size); + dev->initialize_device_procs = proto->initialize_device_procs; + dev->initialize_device_procs(dev); + if (dev->procs.initialize_device) { + /* A condition of devices inited on the stack is that they can + * never fail to initialize! */ + (void)dev->procs.initialize_device(dev); + } + gx_device_fill_in_procs(dev); dev->memory = mem; dev->retained = 0; dev->pad = proto->pad; @@ -648,8 +668,10 @@ void gs_make_null_device(gx_device_null *dev_null, gx_device *dev, gs_memory_t * mem) { - gx_device_init((gx_device *)dev_null, (const gx_device *)&gs_null_device, - mem, true); + /* Can never fail */ + (void)gx_device_init((gx_device *)dev_null, + (const gx_device *)&gs_null_device, + mem, true); gx_device_fill_in_procs((gx_device *)dev_null); gx_device_set_target((gx_device_forward *)dev_null, dev); if (dev) { @@ -671,7 +693,6 @@ gs_make_null_device(gx_device_null *dev_null, gx_device *dev, set_dev_proc(dn, begin_transparency_mask, gx_default_begin_transparency_mask); set_dev_proc(dn, end_transparency_mask, gx_default_end_transparency_mask); set_dev_proc(dn, discard_transparency_layer, gx_default_discard_transparency_layer); - set_dev_proc(dn, pattern_manage, gx_default_pattern_manage); set_dev_proc(dn, push_transparency_state, gx_default_push_transparency_state); set_dev_proc(dn, pop_transparency_state, gx_default_pop_transparency_state); set_dev_proc(dn, put_image, gx_default_put_image); @@ -787,16 +808,28 @@ gx_set_device_only(gs_gstate * pgs, gx_device * dev) uint gx_device_raster(const gx_device * dev, bool pad) { - ulong bits = (ulong) dev->width * dev->color_info.depth; + int depth = dev->color_info.depth; + ulong bits = (ulong) dev->width * depth; ulong raster; int l2align; - if (dev->is_planar) - { - int has_tags = device_encodes_tags(dev); - bits /= (dev->color_info.num_components + has_tags); - } + if (dev->is_planar) { + int num_components = dev->color_info.num_components; + /* bpc accounts for unused bits, e.g. depth==4, num_comp==3, or depth==8, num_comps==5 */ + int bpc = depth / num_components; + /* depth can be <= num_components if planar and MEM_SET_PARAMS has changed it */ + if (depth <= num_components || bpc >= 8) { + /* tag plane requires at least 8 bits (per component as well as tags) */ + int has_tags = bpc >= 8 ? device_encodes_tags(dev): 0; + + bits /= (num_components + has_tags); + } + else { + /* depth is original depth, not the plane_depth since it is > num_components */ + bits /= (depth / bpc); + } + } raster = (uint)((bits + 7) >> 3); if (!pad) return raster; @@ -1360,7 +1393,7 @@ bool gx_color_info_equal(const gx_device_color_info * p1, const gx_device_color_ return false; if (p1->max_components != p2->max_components) return false; - if (p1->opmode != p2->opmode) + if (p1->opmsupported != p2->opmsupported) return false; if (p1->polarity != p2->polarity) return false; diff --git a/base/gsdparam.c b/base/gsdparam.c index b86dcfb4..f1827261 100644 --- a/base/gsdparam.c +++ b/base/gsdparam.c @@ -61,7 +61,6 @@ gs_get_device_or_hw_params(gx_device * orig_dev, gs_param_list * plist, if (code < 0) return code; } - gx_device_set_procs(dev); fill_dev_proc(dev, get_params, gx_default_get_params); fill_dev_proc(dev, get_page_device, gx_default_get_page_device); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); @@ -426,8 +425,8 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "OutputICCProfile") == 0) { return param_write_string(plist,"OutputICCProfile", &(profile_array[0])); } - if (strcmp(Param, "GraphicICCProfile") == 0) { - return param_write_string(plist,"GraphicICCProfile", &(profile_array[1])); + if (strcmp(Param, "VectorICCProfile") == 0) { + return param_write_string(plist,"VectorICCProfile", &(profile_array[1])); } if (strcmp(Param, "ImageICCProfile") == 0) { return param_write_string(plist,"ImageICCProfile", &(profile_array[2])); @@ -441,8 +440,8 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "RenderIntent") == 0) { return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0]))); } - if (strcmp(Param, "GraphicIntent") == 0) { - return param_write_int(plist,"GraphicIntent", (const int *) &(profile_intents[1])); + if (strcmp(Param, "VectorIntent") == 0) { + return param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1])); } if (strcmp(Param, "ImageIntent") == 0) { return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2])); @@ -453,8 +452,8 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "BlackPtComp") == 0) { return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0]))); } - if (strcmp(Param, "GraphicBlackPt") == 0) { - return param_write_int(plist,"GraphicBlackPt", (const int *) &(blackptcomps[1])); + if (strcmp(Param, "VectorBlackPt") == 0) { + return param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1])); } if (strcmp(Param, "ImageBlackPt") == 0) { return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2])); @@ -465,8 +464,8 @@ int gx_default_get_param(gx_device *dev, char *Param, void *list) if (strcmp(Param, "KPreserve") == 0) { return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0]))); } - if (strcmp(Param, "GraphicKPreserve") == 0) { - return param_write_int(plist,"GraphicKPreserve", (const int *) &(blackpreserve[1])); + if (strcmp(Param, "VectorKPreserve") == 0) { + return param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1])); } if (strcmp(Param, "ImageKPreserve") == 0) { return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2])); @@ -718,7 +717,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) (code = param_write_bool(plist, "BlackText", &blacktext)) < 0 || (code = param_write_bool(plist, "PreBandThreshold", &prebandthreshold)) < 0 || (code = param_write_string(plist,"OutputICCProfile", &(profile_array[0]))) < 0 || - (code = param_write_string(plist,"GraphicICCProfile", &(profile_array[1]))) < 0 || + (code = param_write_string(plist,"VectorICCProfile", &(profile_array[1]))) < 0 || (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 || (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 || (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 || @@ -728,15 +727,15 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 || (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 || (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 || - (code = param_write_int(plist,"GraphicIntent", (const int *) &(profile_intents[1]))) < 0 || + (code = param_write_int(plist,"VectorIntent", (const int *) &(profile_intents[1]))) < 0 || (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 || (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 || (code = param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0])))) < 0 || - (code = param_write_int(plist,"GraphicBlackPt", (const int *) &(blackptcomps[1]))) < 0 || + (code = param_write_int(plist,"VectorBlackPt", (const int *) &(blackptcomps[1]))) < 0 || (code = param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2]))) < 0 || (code = param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3]))) < 0 || (code = param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0])))) < 0 || - (code = param_write_int(plist,"GraphicKPreserve", (const int *) &(blackpreserve[1]))) < 0 || + (code = param_write_int(plist,"VectorKPreserve", (const int *) &(blackpreserve[1]))) < 0 || (code = param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2]))) < 0 || (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 || (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 || @@ -802,7 +801,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) if (dev->PageList) { gdev_pagelist *p = (gdev_pagelist *)dev->PageList; - param_string_from_string(pagelist, p->Pages); + param_string_from_transient_string(pagelist, p->Pages); } else { param_string_from_string(pagelist, null_str); } @@ -1056,7 +1055,6 @@ gs_putdeviceparams(gx_device * dev, gs_param_list * plist) /* gs_param_list_dump(plist); */ - gx_device_set_procs(dev); fill_dev_proc(dev, put_params, gx_default_put_params); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); code = (*dev_proc(dev, put_params)) (dev, plist); @@ -1737,10 +1735,10 @@ nce: } /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update this with the name of the profile */ - if ((code = param_read_string(plist, "GraphicICCProfile", &icc_pro)) != 1) { + if ((code = param_read_string(plist, "VectorICCProfile", &icc_pro)) != 1) { if ((code = gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE)) < 0) { ecode = code; - param_signal_error(plist, "GraphicICCProfile", ecode); + param_signal_error(plist, "VectorICCProfile", ecode); } } if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) { @@ -1772,7 +1770,7 @@ nce: ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_int(plist, (param_name = "GraphicIntent"), + if ((code = param_read_int(plist, (param_name = "VectorIntent"), &(rend_intent[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); @@ -1792,7 +1790,7 @@ nce: ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_int(plist, (param_name = "GraphicBlackPt"), + if ((code = param_read_int(plist, (param_name = "VectorBlackPt"), &(blackptcomp[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); @@ -1812,7 +1810,7 @@ nce: ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_int(plist, (param_name = "GraphicKPreserve"), + if ((code = param_read_int(plist, (param_name = "VectorKPreserve"), &(blackpreserve[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); @@ -1912,8 +1910,10 @@ label:\ } switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) { - CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < 0, bhe); + CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < -1, bhe); } + if (sp.band.BandHeight == -1) + sp.band.BandHeight = dev->height; /* 1 band for the page requested */ switch (code = param_read_size_t(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) { CHECK_PARAM_CASES(band.BandBufferSpace, 0, bbse); diff --git a/base/gsdps1.c b/base/gsdps1.c index 640853d5..06998b7b 100644 --- a/base/gsdps1.c +++ b/base/gsdps1.c @@ -201,7 +201,7 @@ gs_rectfill(gs_gstate * pgs, const gs_rect * pr, uint count) bool center_of_pixel = (pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0); /* Processing a fill object operation */ - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ code = gx_set_dev_color(pgs); if (code != 0) diff --git a/base/gsequivc.c b/base/gsequivc.c index e89e23ab..e2b9c33d 100644 --- a/base/gsequivc.c +++ b/base/gsequivc.c @@ -368,7 +368,6 @@ typedef struct color_capture_device_s { static cmap_proc_gray(cmap_gray_capture_cmyk_color); static cmap_proc_rgb(cmap_rgb_capture_cmyk_color); static cmap_proc_cmyk(cmap_cmyk_capture_cmyk_color); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_capture_cmyk_color); static cmap_proc_separation(cmap_separation_capture_cmyk_color); static cmap_proc_devicen(cmap_devicen_capture_cmyk_color); @@ -376,7 +375,6 @@ static const gx_color_map_procs cmap_capture_cmyk_color = { cmap_gray_capture_cmyk_color, cmap_rgb_capture_cmyk_color, cmap_cmyk_capture_cmyk_color, - cmap_rgb_alpha_capture_cmyk_color, cmap_separation_capture_cmyk_color, cmap_devicen_capture_cmyk_color }; @@ -426,14 +424,6 @@ cmap_cmyk_capture_cmyk_color(frac c, frac m, frac y, frac k, gx_device_color * p } static void -cmap_rgb_alpha_capture_cmyk_color(frac r, frac g, frac b, frac alpha, - gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, - gs_color_select_t select) -{ - cmap_rgb_capture_cmyk_color(r, g, b, pdc, pgs, dev, select); -} - -static void cmap_separation_capture_cmyk_color(frac all, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, const gs_color_space *pcs) diff --git a/base/gserrors.h b/base/gserrors.h index 1bdbb8a0..91b05cdf 100644 --- a/base/gserrors.h +++ b/base/gserrors.h @@ -119,7 +119,10 @@ enum gs_error_type { * subclasses should not perform any further action. Currently this is limited * to compositor creation. */ - gs_error_handled = -111 + gs_error_handled = -111, + +/* Internal error for the C-based PDF interpreter, to indicate a circular PDF reference */ + gs_error_circular_reference = -112, }; /* We do provide a typedef type for external API use */ diff --git a/base/gsfont.c b/base/gsfont.c index b8335c1d..3fcb8deb 100644 --- a/base/gsfont.c +++ b/base/gsfont.c @@ -283,11 +283,18 @@ gs_font_dir_finalize(const gs_memory_t *cmem, void *vptr) gx_bits_cache_chunk *chunk = pdir->ccache.chunks; gx_bits_cache_chunk *start_chunk = chunk; gx_bits_cache_chunk *prev_chunk; + int i; if (pdir == cmem->gs_lib_ctx->font_dir) { cmem->gs_lib_ctx->font_dir = NULL; } + for (i = 0; i < pdir->fmcache.mmax; i++) { + if (uid_is_XUID(&pdir->fmcache.mdata[i].UID)) { + gs_free_object(pdir->memory->stable_memory, pdir->fmcache.mdata[i].UID.xvalues, "gs_font_dir_finalize"); + } + } + /* free character cache machinery */ gs_free_object(pdir->memory, pdir->fmcache.mdata, "gs_font_dir_finalize"); gs_free_object(pdir->memory, pdir->ccache.table, "gs_font_dir_finalize"); diff --git a/base/gsfunc3.c b/base/gsfunc3.c index 11968efd..5ae33934 100644 --- a/base/gsfunc3.c +++ b/base/gsfunc3.c @@ -41,6 +41,9 @@ fn_free_functions(const gs_function_t *const * Functions, int count, { int i; + if (Functions == NULL) + return; + for (i = count; --i >= 0;) if (Functions[i]) gs_function_free((gs_function_t *)Functions[i], true, mem); diff --git a/base/gsfunc4.c b/base/gsfunc4.c index d5daf9ce..c2bddaf2 100644 --- a/base/gsfunc4.c +++ b/base/gsfunc4.c @@ -555,19 +555,22 @@ fn_PtCr_evaluate(const gs_function_t *pfn_common, const float *in, float *out) } } fin: - - if (vsp != vstack + pfn->params.n) - return_error(gs_error_rangecheck); - for (i = 0; i < pfn->params.n; ++i) { - switch (vstack[i + 1].type) { - case CVT_INT: - out[i] = (float)vstack[i + 1].value.i; - break; - case CVT_FLOAT: - out[i] = vstack[i + 1].value.f; - break; - default: - return_error(gs_error_typecheck); + { /* Following Acrobat, take the desired number of parameters */ + /* from the top of stack and ignore the rest. Bug 702950. */ + int extra_ops = vsp - vstack - pfn->params.n; + if (extra_ops < 0) + return_error(gs_error_rangecheck); + for (i = 0; i < pfn->params.n; ++i) { + switch (vstack[i + 1 + extra_ops].type) { + case CVT_INT: + out[i] = (float)vstack[i + 1 + extra_ops].value.i; + break; + case CVT_FLOAT: + out[i] = vstack[i + 1 + extra_ops].value.f; + break; + default: + return_error(gs_error_typecheck); + } } } return 0; diff --git a/base/gsgstate.c b/base/gsgstate.c index 6eb9b817..0f7d182a 100644 --- a/base/gsgstate.c +++ b/base/gsgstate.c @@ -112,7 +112,8 @@ gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) for (i = 0; i < gs_color_select_count; ++i) pgs->screen_phase[i].x = pgs->screen_phase[i].y = 0; } - pgs->dev_ht = 0; + for (i=0; i < HT_OBJTYPE_COUNT; i++) + pgs->dev_ht[i] = NULL; pgs->cie_render = 0; pgs->cie_to_xyz = false; pgs->black_generation = 0; @@ -159,8 +160,11 @@ gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) void gs_gstate_copied(gs_gstate * pgs) { + int i; + rc_increment(pgs->halftone); - rc_increment(pgs->dev_ht); + for (i=0; i < HT_OBJTYPE_COUNT; i++) + rc_increment(pgs->dev_ht[i]); rc_increment(pgs->cie_render); rc_increment(pgs->black_generation); rc_increment(pgs->undercolor_removal); @@ -183,6 +187,7 @@ void gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) { const char *const cname = "gs_gstate_pre_assign"; + int i; #define RCCOPY(element)\ rc_pre_assign(pto->element, pfrom->element, cname) @@ -196,7 +201,8 @@ gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) RCCOPY(undercolor_removal); RCCOPY(black_generation); RCCOPY(cie_render); - RCCOPY(dev_ht); + for (i=0; i < HT_OBJTYPE_COUNT; i++) + RCCOPY(dev_ht[i]); RCCOPY(halftone); RCCOPY(devicergb_cs); RCCOPY(devicecmyk_cs); @@ -212,7 +218,8 @@ void gs_gstate_release(gs_gstate * pgs) { const char *const cname = "gs_gstate_release"; - gx_device_halftone *pdht = pgs->dev_ht; + gx_device_halftone *pdht; + int i; #define RCDECR(element)\ rc_decrement(pgs->element, cname);\ @@ -227,13 +234,16 @@ gs_gstate_release(gs_gstate * pgs) RCDECR(black_generation); RCDECR(cie_render); /* - * If we're going to free the device halftone, make sure we free the + * If we're going to free a device halftone, make sure we free the * dependent structures as well. */ - if (pdht != 0 && pdht->rc.ref_count == 1) { - gx_device_halftone_release(pdht, pdht->rc.memory); + for (i=0; i < HT_OBJTYPE_COUNT; i++) { + pdht = pgs->dev_ht[i]; + if (pdht != NULL && pdht->rc.ref_count == 1) { + gx_device_halftone_release(pdht, pdht->rc.memory); + } + RCDECR(dev_ht[i]); } - RCDECR(dev_ht); RCDECR(halftone); RCDECR(devicergb_cs); RCDECR(devicecmyk_cs); diff --git a/base/gsht.c b/base/gsht.c index bc72f0e1..2b8567f9 100644 --- a/base/gsht.c +++ b/base/gsht.c @@ -17,6 +17,7 @@ /* setscreen operator for Ghostscript library */ #include "memory_.h" #include "string_.h" +#include "assert_.h" #include <stdlib.h> /* for qsort */ #include "gx.h" #include "gserrors.h" @@ -25,6 +26,7 @@ #include "gxarith.h" /* for igcd */ #include "gzstate.h" #include "gxdevice.h" /* for gzht.h */ +#include "gxdevsop.h" #include "gzht.h" #include "gxfmap.h" /* For effective transfer usage in threshold */ #include "gp.h" @@ -168,12 +170,12 @@ gs_currentscreenlevels(const gs_gstate * pgs) { int gi = 0; - if (pgs->device != 0) + if (pgs->device != NULL) gi = pgs->device->color_info.gray_index; if (gi != GX_CINFO_COMP_NO_INDEX) - return pgs->dev_ht->components[gi].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[gi].corder.num_levels; else - return pgs->dev_ht->components[0].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; } /* .setscreenphase */ @@ -321,9 +323,9 @@ gx_ht_copy_ht_order(gx_ht_order * pdest, gx_ht_order * psrc, gs_memory_t * mem) psrc->procs, mem); if (code < 0) return code; - if (pdest->levels != 0) + if (pdest->levels != NULL) memcpy(pdest->levels, psrc->levels, psrc->num_levels * sizeof(uint)); - if (pdest->bit_data != 0) + if (pdest->bit_data != NULL) memcpy(pdest->bit_data, psrc->bit_data, (size_t)psrc->num_bits * psrc->procs->bit_data_elt_size); pdest->transfer = psrc->transfer; @@ -576,13 +578,13 @@ gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache) { /* "free cache" is a proxy for "differs from default" */ if (free_cache) { - if (porder->cache != 0) + if (porder->cache != NULL) gx_ht_free_cache(mem, porder->cache); } porder->cache = 0; rc_decrement(porder->transfer, "gx_ht_order_release(transfer)"); porder->transfer = 0; - if (porder->data_memory != 0) { + if (porder->data_memory != NULL) { gs_free_object(porder->data_memory, porder->bit_data, "gx_ht_order_release(bit_data)"); gs_free_object(porder->data_memory, porder->levels, @@ -644,53 +646,53 @@ int gs_color_name_component_number(gx_device * dev, const char * pname, int name_size, int halftonetype) { - int num_colorant; + int num_colorant = -1; /* initialize to "unknown" */ + int color_component_type = NO_COMP_NAME_TYPE_HT; + bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0); -#define check_colorant_name(dev, name) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_COMP_NAME_TYPE_HT)) +#define check_colorant_name(dev, name, component_type) \ + ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), component_type)) -#define check_colorant_name_length(dev, name, length) \ - ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, NO_COMP_NAME_TYPE_HT)) +#define check_colorant_name_length(dev, name, length, component_type) \ + ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, component_type)) #define check_name(str, pname, length) \ ((strlen(str) == length) && (strncmp(pname, str, length) == 0)) /* - * Check if this is a device colorant. - */ - num_colorant = check_colorant_name_length(dev, pname, name_size); - if (num_colorant >= 0) { - /* - * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the - * colorant is logically present in the device but not being used - * because a SeparationOrder parameter is specified. Since we are - * using this value to indicate 'Default', we use -1 to indicate - * that the colorant is not really being used. - */ - if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) - num_colorant = -1; - return num_colorant; - } - - /* * Check if this is the default component */ if (check_name("Default", pname, name_size)) return GX_DEVICE_COLOR_MAX_COMPONENTS; + if (check_cmyk_color_model_comps(dev)) + color_component_type = SEPARATION_NAME; /* allow separations to be added */ + + /* + * Check if this is a device colorant. + */ /* Halftones set by setcolorscreen, and (we think) */ - /* Type 2 and Type 4 halftones, are supposed to work */ + /* Type 2, 4, and 5 halftones, are supposed to work */ /* for both RGB and CMYK, so we need a special check here. */ if (halftonetype == ht_type_colorscreen || - halftonetype == ht_type_multiple_colorscreen) { + halftonetype == ht_type_multiple_colorscreen || + (halftonetype == ht_type_multiple && devn)) { + /* Note that Red, Green, Blue and/or Gray can be added using setcolorspace */ + /* we just don't automatically add it as a result of sethalftone */ + /* The NO_COMP_NAME_TYPE_HT won't add colorants */ if (check_name("Red", pname, name_size)) - num_colorant = check_colorant_name(dev, "Cyan"); + num_colorant = check_colorant_name(dev, "Cyan", NO_COMP_NAME_TYPE_HT); else if (check_name("Green", pname, name_size)) - num_colorant = check_colorant_name(dev, "Magenta"); + num_colorant = check_colorant_name(dev, "Magenta", NO_COMP_NAME_TYPE_HT); else if (check_name("Blue", pname, name_size)) - num_colorant = check_colorant_name(dev, "Yellow"); + num_colorant = check_colorant_name(dev, "Yellow", NO_COMP_NAME_TYPE_HT); else if (check_name("Gray", pname, name_size)) - num_colorant = check_colorant_name(dev, "Black"); + num_colorant = check_colorant_name(dev, "Black", NO_COMP_NAME_TYPE_HT); + } + if (num_colorant < 0) + num_colorant = check_colorant_name_length(dev, pname, name_size, color_component_type); + + if (num_colorant >= 0) { /* * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the * colorant is logically present in the device but not being used @@ -700,12 +702,12 @@ gs_color_name_component_number(gx_device * dev, const char * pname, */ if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) num_colorant = -1; - + return num_colorant; + } #undef check_colorant_name #undef check_colorant_name_length #undef check_name - } return num_colorant; } @@ -949,7 +951,8 @@ gx_gstate_dev_ht_install( gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, - const gx_device * dev ) + const gx_device * dev, + gs_HT_objtype_t objtype ) { gx_device_halftone dht; int num_comps = pdht->num_dev_comp; @@ -960,6 +963,8 @@ gx_gstate_dev_ht_install( uint w, h; int dw, dh; + assert(objtype < HT_OBJTYPE_COUNT); + /* construct the new device halftone structure */ memset(&dht.order, 0, sizeof(dht.order)); /* the rc field is filled in later */ @@ -988,7 +993,7 @@ gx_gstate_dev_ht_install( * by clearing the corresponding pointers in the operand halftone's * orders. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps && code >= 0; i++) { @@ -1101,27 +1106,28 @@ gx_gstate_dev_ht_install( * we still need. */ if (code >= 0) { - gx_device_halftone * pgsdht = pgs->dev_ht; - rc_header tmp_rc; - - if (pgsdht != 0 && pgsdht->rc.ref_count == 1) { - if (pdht != pgsdht) - gx_device_halftone_release(pgsdht, pgsdht->rc.memory); + gx_device_halftone **ppgsdht; + rc_header tmp_rc; + + /* The pgsdht corresponds to the one we will be installing according to 'objtype' */ + ppgsdht = &(pgs->dev_ht[objtype]); + if (*ppgsdht != NULL && (*ppgsdht)->rc.ref_count == 1) { + if (pdht != *ppgsdht) + gx_device_halftone_release(*ppgsdht, (*ppgsdht)->rc.memory); } else { - rc_unshare_struct( pgs->dev_ht, + rc_unshare_struct( *ppgsdht, gx_device_halftone, &st_device_halftone, pgs->memory, BEGIN code = gs_error_VMerror; goto err; END, "gx_gstate_dev_ht_install" ); - pgsdht = pgs->dev_ht; } /* * Everything worked. "Assume ownership" of the appropriate * portions of the source device halftone by clearing the * associated references. Since we might have - * pdht == pgs->dev_ht, this must done before updating pgs->dev_ht. + * pdht == pgs->dev_ht[], this must done before updating pgs->dev_ht[]. * * If the default order has been used for a device component, and * any of the source component orders share their levels or bit_data @@ -1130,7 +1136,7 @@ gx_gstate_dev_ht_install( * be cleared immediately below, so subsequently it will not be * possible to tell if that this information is being shared. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps; i++) { @@ -1150,9 +1156,9 @@ gx_gstate_dev_ht_install( memset(&pdht->order, 0, sizeof(pdht->order)); } - tmp_rc = pgsdht->rc; - *pgsdht = dht; - pgsdht->rc = tmp_rc; + tmp_rc = (*ppgsdht)->rc; + **ppgsdht = dht; + (*ppgsdht)->rc = tmp_rc; /* update the effective transfer function array */ gx_gstate_set_effective_xfer(pgs); @@ -1180,6 +1186,22 @@ gx_gstate_dev_ht_install( } /* + * Copy the dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. + */ +int +gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype) +{ + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* the current dev_ht */ + + if (objtype >= HT_OBJTYPE_COUNT) { + return_error(gs_error_undefined); + } + rc_increment(pdht); + pgs->dev_ht[objtype] = pdht; + return 0; +} + +/* * Install a new halftone in the graphics state. Note that we copy the top * level of the gs_halftone and the gx_device_halftone, and take ownership * of any substructures. @@ -1194,7 +1216,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, int code; pdht->num_dev_comp = pgs->device->color_info.num_components; - if (old_ht != 0 && old_ht->rc.memory == mem && + if (old_ht != NULL && old_ht->rc.memory == mem && old_ht->rc.ref_count == 1 ) new_ht = old_ht; @@ -1203,7 +1225,8 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, mem, return_error(gs_error_VMerror), "gx_ht_install(new halftone)"); code = gx_gstate_dev_ht_install(pgs, - pdht, pht->type, gs_currentdevice_inline(pgs)); + pdht, pht->type, gs_currentdevice_inline(pgs), + pht->objtype); if (code < 0) { if (new_ht != old_ht) gs_free_object(mem, new_ht, "gx_ht_install(new halftone)"); @@ -1242,7 +1265,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, void gx_gstate_set_effective_xfer(gs_gstate * pgs) { - gx_device_halftone *pdht = pgs->dev_ht; + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; gx_transfer_map *pmap; gx_ht_order *porder; int i, component_num, non_id_count; diff --git a/base/gsht.h b/base/gsht.h index 05857f9f..f5280852 100644 --- a/base/gsht.h +++ b/base/gsht.h @@ -23,6 +23,15 @@ #include "gsgstate.h" #include "gstypes.h" +/* Define the ObjectType enum for Halftones */ +typedef enum { + HT_OBJTYPE_DEFAULT = 0, + HT_OBJTYPE_VECTOR, + HT_OBJTYPE_IMAGE, + HT_OBJTYPE_TEXT, + HT_OBJTYPE_COUNT /* Must be last */ +} gs_HT_objtype_t; + /* Client definition of (Type 1) halftones */ typedef struct gs_screen_halftone_s { float frequency; diff --git a/base/gsht1.c b/base/gsht1.c index 05fceb54..90f7e51b 100644 --- a/base/gsht1.c +++ b/base/gsht1.c @@ -169,6 +169,8 @@ gs_sethalftone_prepare(gs_gstate * pgs, gs_halftone * pht, gx_ht_order_component *pocs = 0; int code = 0; + if (pht->objtype >= HT_OBJTYPE_COUNT) + return_error(gs_error_limitcheck); switch (pht->type) { case ht_type_colorscreen: { diff --git a/base/gshtscr.c b/base/gshtscr.c index 34ca1240..6807a9f3 100644 --- a/base/gshtscr.c +++ b/base/gshtscr.c @@ -627,6 +627,7 @@ gs_screen_install(gs_screen_enum * penum) dev_ht.rc.memory = penum->halftone.rc.memory; dev_ht.order = penum->order; dev_ht.components = 0; + penum->halftone.objtype = HT_OBJTYPE_DEFAULT; if ((code = gx_ht_install(penum->pgs, &penum->halftone, &dev_ht)) < 0) gx_device_halftone_release(&dev_ht, dev_ht.rc.memory); return code; diff --git a/base/gshtx.c b/base/gshtx.c index c42f19ba..bf01fb24 100644 --- a/base/gshtx.c +++ b/base/gshtx.c @@ -95,6 +95,7 @@ gs_ht_build( /* initialize the halftone */ pht->type = ht_type_multiple; pht->rc.free = free_comps; + pht->objtype = HT_OBJTYPE_DEFAULT; pht->params.ht_multiple.components = phtc; pht->params.ht_multiple.num_comp = num_comps; diff --git a/base/gsicc.c b/base/gsicc.c index f77d7028..d8e2bd3a 100644 --- a/base/gsicc.c +++ b/base/gsicc.c @@ -427,9 +427,13 @@ gx_remap_ICC_with_link(const gs_client_color * pcc, const gs_color_space * pcs, the transfer function and potentially the halftoning */ /* Right now we need to go from unsigned short to frac. I really would like to avoid this sort of stuff. That will come. */ - for ( k = 0; k < num_des_comps; k++){ + for (k = 0; k < num_des_comps; k++){ conc[k] = ushort2frac(psrc_temp[k]); } + /* In case there are extra components beyond the ICC ones */ + for (k = num_des_comps; k < dev->color_info.num_components; k++) { + conc[k] = 0; + } gx_remap_concrete_ICC(pcs, conc, pdc, pgs, dev, select, dev_profile); /* Save original color space and color info into dev color */ @@ -535,9 +539,13 @@ gx_remap_ICC_imagelab(const gs_client_color * pcc, const gs_color_space * pcs, the transfer function and potentially the halftoning */ /* Right now we need to go from unsigned short to frac. I really would like to avoid this sort of stuff. That will come. */ - for ( k = 0; k < num_des_comps; k++){ + for (k = 0; k < num_des_comps; k++){ conc[k] = ushort2frac(psrc_temp[k]); } + /* We have to worry about extra colorants in the device. */ + for (k = num_des_comps; k < dev->color_info.num_components; k++) { + conc[k] = 0; + } gx_remap_concrete_ICC(pcs, conc, pdc, pgs, dev, select, dev_profile); /* Save original color space and color info into dev color */ @@ -599,9 +607,14 @@ gx_concretize_ICC( (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2); } /* This needs to be optimized */ - for (k = 0; k < num_des_comps; k++){ + for (k = 0; k < num_des_comps; k++) { pconc[k] = float2frac(((float) psrc_temp[k])/65535.0); } + /* We have to worry about extra colorants in the device. */ + for (k = num_des_comps; k < dev->color_info.num_components; k++) { + pconc[k] = 0; + } + /* Release the link */ gsicc_release_link(icc_link); return 0; @@ -615,10 +628,11 @@ gx_concretize_ICC( * unintuitive but otherwise legitimate state of affairs". */ static void -gx_final_ICC(const gs_color_space * pcs) +gx_final_ICC(gs_color_space * pcs) { if (pcs->cmm_icc_profile_data != NULL) { gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_ICC"); + pcs->cmm_icc_profile_data = NULL; } } @@ -681,7 +695,8 @@ gx_set_overprint_ICC(const gs_color_space * pcs, gs_gstate * pgs) bool gray_to_k; bool op = pgs->is_fill_color ? pgs->overprint : pgs->stroke_overprint; - if (dev == 0 || pcinfo == NULL) + if (dev == 0 || pcinfo == NULL || !op || + gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED_NOT) return gx_set_no_overprint(pgs); dev_proc(dev, get_profile)(dev, &dev_profile); @@ -697,22 +712,19 @@ gx_set_overprint_ICC(const gs_color_space * pcs, gs_gstate * pgs) "[overprint] gx_set_overprint_ICC. cs_ok = %d is_fill_color = %d overprint = %d stroke_overprint = %d \n", cs_ok, pgs->is_fill_color, pgs->overprint, pgs->stroke_overprint); - if (!op || pcinfo->opmode == GX_CINFO_OPMODE_NOT) { - return gx_set_no_overprint(pgs); - } else if (!cs_ok) { - /* In this case, we still need to maintain any spot - colorant channels. Per Table 7.14. */ - if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) { - return gx_set_spot_only_overprint(pgs); - } else { - return gx_set_no_overprint(pgs); - } - } else + if (cs_ok) return gx_set_overprint_cmyk(pcs, pgs); + + /* In this case, we still need to maintain any spot + colorant channels. Per Table 7.14. */ + if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) + return gx_set_spot_only_overprint(pgs); + + return gx_set_no_overprint(pgs); } int -gx_default_get_profile(gx_device *dev, cmm_dev_profile_t **profile) +gx_default_get_profile(const gx_device *dev, cmm_dev_profile_t **profile) { *profile = dev->icc_struct; return 0; diff --git a/base/gsicc_cache.c b/base/gsicc_cache.c index fda958aa..ba332060 100644 --- a/base/gsicc_cache.c +++ b/base/gsicc_cache.c @@ -635,7 +635,7 @@ gsicc_get_srcprofile(gsicc_colorbuffer_t data_cs, case GS_UNTOUCHED_TAG: default: break; - case GS_PATH_TAG: + case GS_VECTOR_TAG: if (data_cs == gsRGB) { (*profile) = srcgtag_profile->rgb_profiles[gsSRC_GRAPPRO]; *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_GRAPPRO]; @@ -870,6 +870,7 @@ gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, { gs_memory_t *cache_mem = icc_link_cache->memory; gsicc_link_t *link; + int retries = 0; *ret_link = NULL; /* First see if we can add a link */ @@ -908,6 +909,10 @@ gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, return true; gx_monitor_enter(icc_link_cache->lock); /* restore the lock */ + /* we will re-test the num_links above while locked to insure */ + /* that some other thread didn't grab the slot and max us out */ + if (retries++ > 10) + return false; } else { /* Remove the zero ref_count link profile we found. */ /* Even if we remove this link, we may still be maxed out so*/ @@ -1515,9 +1520,12 @@ gsicc_support_named_color(const gs_color_space *pcs, const gs_gstate *pgs) byte *pname = NULL; /* Silence compiler warning */ uint name_size = 0; /* Silence compiler warning */ bool is_supported; + bool none_colorant; /* Get the data for the named profile */ named_profile = pgs->icc_manager->device_named; + if (named_profile == NULL) + return false; if (named_profile->buffer != NULL && named_profile->profile_handle == NULL) { @@ -1547,8 +1555,10 @@ gsicc_support_named_color(const gs_color_space *pcs, const gs_gstate *pgs) name_size = strlen(names[i]); } + none_colorant = (strncmp((char*)pname, "None", name_size) == 0); + /* Classify */ - if (strncmp((char *)pname, "None", name_size) == 0 || + if (none_colorant || strncmp((char *)pname, "All", name_size) == 0) { num_other++; } else { @@ -1564,12 +1574,18 @@ gsicc_support_named_color(const gs_color_space *pcs, const gs_gstate *pgs) /* Check if the colorant is supported */ is_supported = false; - for (k = 0; k < num_entries; k++) { - if (name_size == namedcolor_table->named_color[k].name_size) { - if (strncmp((const char *)namedcolor_table->named_color[k].colorant_name, - (const char *)pname, name_size) == 0) { - is_supported = true; - break; + + /* If we have a none colorant name in the DeviceN list, just ignore it */ + if (none_colorant && type == gs_color_space_index_DeviceN) + is_supported = true; + else { + for (k = 0; k < num_entries; k++) { + if (name_size == namedcolor_table->named_color[k].name_size) { + if (strncmp((const char*)namedcolor_table->named_color[k].colorant_name, + (const char*)pname, name_size) == 0) { + is_supported = true; + break; + } } } } diff --git a/base/gsicc_cms.h b/base/gsicc_cms.h index 9d271f19..b9b38f93 100644 --- a/base/gsicc_cms.h +++ b/base/gsicc_cms.h @@ -62,6 +62,8 @@ gsicc_colorbuffer_t gscms_get_profile_data_space(gcmmhprofile_t profile, gs_memory_t *memory); int gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes); +int gscms_transform_color_const(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes); gcmmhlink_t gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, gsicc_rendering_param_t *rendering_params, diff --git a/base/gsicc_lcms2.c b/base/gsicc_lcms2.c index 5e9355e6..ccf1d705 100644 --- a/base/gsicc_lcms2.c +++ b/base/gsicc_lcms2.c @@ -462,6 +462,13 @@ int gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes) { + return gscms_transformm_color_const(dev, icclink, inputcolor, outputcolor, num_bytes); +} + +int +gscms_transform_color_const(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes) +{ cmsHTRANSFORM hTransform = (cmsHTRANSFORM)icclink->link_handle; cmsUInt32Number dwInputFormat,dwOutputFormat; diff --git a/base/gsicc_lcms2mt.c b/base/gsicc_lcms2mt.c index eb621b96..b0d85405 100644 --- a/base/gsicc_lcms2mt.c +++ b/base/gsicc_lcms2mt.c @@ -475,6 +475,13 @@ int gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes) { + return gscms_transform_color_const(dev, icclink, inputcolor, outputcolor, num_bytes); +} + +int +gscms_transform_color_const(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes) +{ gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; cmsUInt32Number dwInputFormat, dwOutputFormat; @@ -670,9 +677,25 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, rendering_params->rendering_intent, flag | cmm_flags); if (link_handle->hTransform == NULL) { - gs_free_object(memory, link_handle, "gscms_get_link"); + int k; + + /* Add a bit of robustness here. Some profiles are ill-formed and + do not have all the intents. If we failed due to a missing + intent, lets go ahead and try each and see if we can get something + that works. */ + for (k = 0; k <= gsABSOLUTECOLORIMETRIC; k++) { + link_handle->hTransform = cmsCreateTransform(ctx, lcms_srchandle, src_data_type, + lcms_deshandle, des_data_type, k, flag | cmm_flags); + if (link_handle->hTransform != NULL) + break; + } + + if (link_handle->hTransform == NULL) { + gs_free_object(memory, link_handle, "gscms_get_link"); return NULL; + } } + link_handle->next = NULL; link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, no endian swap */ sizeof(gx_color_value), sizeof(gx_color_value)); diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c index 4cf82e0c..0842628d 100644 --- a/base/gsicc_manage.c +++ b/base/gsicc_manage.c @@ -759,7 +759,7 @@ gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, /* Color tune profile. No intent */ srcgtag->color_warp_profile = icc_profile; break; - case GRAPHIC_CMYK: + case VECTOR_CMYK: srcgtag->cmyk_profiles[gsSRC_GRAPPRO] = icc_profile; srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { @@ -786,7 +786,7 @@ gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, return code; } break; - case GRAPHIC_RGB: + case VECTOR_RGB: srcgtag->rgb_profiles[gsSRC_GRAPPRO] = icc_profile; srcgtag->rgb_rend_cond[gsSRC_GRAPPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { @@ -813,7 +813,7 @@ gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, return code; } break; - case GRAPHIC_GRAY: + case VECTOR_GRAY: srcgtag->gray_profiles[gsSRC_GRAPPRO] = icc_profile; srcgtag->gray_rend_cond[gsSRC_GRAPPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { @@ -1586,8 +1586,15 @@ gsicc_set_device_profile_colorants(gx_device *dev, char *name_str) char temp_str[DEFAULT_ICC_COLORANT_LENGTH+2]; /* If names are already set then we do not want to set default ones */ - if (profile_struct->spotnames != NULL) - return 0; + if (profile_struct->spotnames != NULL) { + /* Check if we have at least as many spot names + as there are channels in the proFfile */ + if (num_comps > profile_struct->spotnames->count) { + gs_warn("ICC profile colorant names count insufficient"); + return_error(gs_error_rangecheck); + } else + return 0; + } free_str = true; /* Assume first 4 are CMYK */ @@ -1933,7 +1940,7 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, { cmm_profile_t *icc_profile; stream *str; - int code; + int code = 0; /* This is slightly silly, we have a device method for 'get_profile' we really ought to * have one for 'set_profile' as well. In its absence, make sure we are setting the profile @@ -2047,7 +2054,7 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, break; default: /* NCLR Profile. Set up default colorant names */ - gsicc_set_device_profile_colorants(pdev, NULL); + code = gsicc_set_device_profile_colorants(pdev, NULL); break; } if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n", @@ -2055,7 +2062,7 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, } else return gs_rethrow(-1, "cannot find device profile"); } - return 0; + return code; } /* Set the icc profile in the gs_color_space object */ @@ -2796,10 +2803,10 @@ gsicc_extract_profile(gs_graphics_type_tag_t graphics_type_tag, (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]; *render_cond = profile_struct->rendercond[GS_DEFAULT_DEVICE_PROFILE]; break; - case GS_PATH_TAG: - *render_cond = profile_struct->rendercond[GS_GRAPHIC_DEVICE_PROFILE]; - if (profile_struct->device_profile[GS_GRAPHIC_DEVICE_PROFILE] != NULL) { - (*profile) = profile_struct->device_profile[GS_GRAPHIC_DEVICE_PROFILE]; + case GS_VECTOR_TAG: + *render_cond = profile_struct->rendercond[GS_VECTOR_DEVICE_PROFILE]; + if (profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE] != NULL) { + (*profile) = profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE]; } else { (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]; } @@ -2863,7 +2870,7 @@ dump_icc_buffer(const gs_memory_t *mem, int buffersize, char filename[],byte *Bu gs_sprintf(full_file_name,"%d)%s_debug.icc",global_icc_index,filename); fid = gp_fopen(mem, full_file_name,"wb"); gp_fwrite(Buffer,sizeof(unsigned char),buffersize,fid); - fclose(fid); + gp_fclose(fid); } #endif diff --git a/base/gsicc_manage.h b/base/gsicc_manage.h index 437db045..bc5a0082 100644 --- a/base/gsicc_manage.h +++ b/base/gsicc_manage.h @@ -45,13 +45,13 @@ /* This enumeration has to be in sync with GSICC_SRCGTAG_KEYS */ typedef enum { COLOR_TUNE, - GRAPHIC_CMYK, + VECTOR_CMYK, IMAGE_CMYK, TEXT_CMYK, - GRAPHIC_RGB, + VECTOR_RGB, IMAGE_RGB, TEXT_RGB, - GRAPHIC_GRAY, + VECTOR_GRAY, IMAGE_GRAY, TEXT_GRAY } gsicc_srcgtagkey_t; diff --git a/base/gsicc_nocm.c b/base/gsicc_nocm.c index efea6c1c..a592e3b1 100644 --- a/base/gsicc_nocm.c +++ b/base/gsicc_nocm.c @@ -40,7 +40,7 @@ typedef struct nocm_link_s { gs_memory_t *memory; } nocm_link_t; -static void gsicc_nocm_transform_general(gx_device *dev, gsicc_link_t *icclink, +static void gsicc_nocm_transform_general(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out); @@ -51,7 +51,7 @@ static void gsicc_nocm_transform_general(gx_device *dev, gsicc_link_t *icclink, /* At most, we have 4 input and 4 output ptrs. Since this is used only in DeviceGray, DeviceRGB and DeviceCMYK cases */ static void -gsicc_nocm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, +gsicc_nocm_planar_to_planar(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -88,7 +88,7 @@ gsicc_nocm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, /* This is not really used yet */ static void -gsicc_nocm_planar_to_chunky(gx_device *dev, gsicc_link_t *icclink, +gsicc_nocm_planar_to_chunky(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -100,7 +100,7 @@ gsicc_nocm_planar_to_chunky(gx_device *dev, gsicc_link_t *icclink, /* This is used with the fast thresholding code when doing -dUseFastColor and going out to a planar device */ static void -gsicc_nocm_chunky_to_planar(gx_device *dev, gsicc_link_t *icclink, +gsicc_nocm_chunky_to_planar(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -156,7 +156,7 @@ gsicc_nocm_chunky_to_planar(gx_device *dev, gsicc_link_t *icclink, } static void -gsicc_nocm_chunky_to_chunky(gx_device *dev, gsicc_link_t *icclink, +gsicc_nocm_chunky_to_chunky(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -224,7 +224,7 @@ gsicc_nocm_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, /* Shared function between the single and buffer conversions */ static void -gsicc_nocm_transform_general(gx_device *dev, gsicc_link_t *icclink, +gsicc_nocm_transform_general(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out) { @@ -238,6 +238,9 @@ gsicc_nocm_transform_general(gx_device *dev, gsicc_link_t *icclink, frac frac_in[4]; frac frac_out[GX_DEVICE_COLOR_MAX_COMPONENTS]; int k; + const gx_device *map_dev; + const gx_cm_color_map_procs *procs; + if (num_bytes_in == 2) { unsigned short *data = (unsigned short *) inputcolor; @@ -253,14 +256,17 @@ gsicc_nocm_transform_general(gx_device *dev, gsicc_link_t *icclink, /* Use the device procedures to do the mapping */ switch (num_in) { case 1: - dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, frac_in[0], frac_out); + procs = dev_proc(dev, get_color_mapping_procs)(dev, &map_dev); + procs->map_gray(map_dev, frac_in[0], frac_out); break; case 3: - dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, link->pgs, frac_in[0], frac_in[1], + procs = dev_proc(dev, get_color_mapping_procs)(dev, &map_dev); + procs->map_rgb(map_dev, link->pgs, frac_in[0], frac_in[1], frac_in[2], frac_out); break; case 4: - dev_proc(dev, get_color_mapping_procs)(dev)->map_cmyk(dev, frac_in[0], frac_in[1], + procs = dev_proc(dev, get_color_mapping_procs)(dev, &map_dev); + procs->map_cmyk(map_dev, frac_in[0], frac_in[1], frac_in[2], frac_in[3], frac_out); break; default: diff --git a/base/gsicc_profilecache.c b/base/gsicc_profilecache.c index db2e8ae4..900a3440 100644 --- a/base/gsicc_profilecache.c +++ b/base/gsicc_profilecache.c @@ -95,6 +95,9 @@ gsicc_add_cs(gs_gstate * pgs, gs_color_space * colorspace, uint64_t dictkey) gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache; gs_memory_t *memory = pgs->memory; + if (dictkey == 0) + return; + /* The entry has to be added in stable memory. We want them to be maintained across the gsave and grestore process */ result = gs_alloc_struct(memory->stable_memory, gsicc_profile_entry_t, @@ -125,6 +128,9 @@ gsicc_find_cs(uint64_t key_test, gs_gstate * pgs) gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache; gsicc_profile_entry_t *prev = NULL, *curr = profile_cache->head; + if (key_test == 0) + return NULL; + /* Look through the cache for the key. If found, move to MRU */ while (curr != NULL ){ if (curr->key == key_test){ diff --git a/base/gsicc_replacecm.c b/base/gsicc_replacecm.c index e7cc7706..21a1c601 100644 --- a/base/gsicc_replacecm.c +++ b/base/gsicc_replacecm.c @@ -37,10 +37,11 @@ typedef struct rcm_link_s { gsicc_colorbuffer_t data_cs_in; gs_memory_t *memory; gx_cm_color_map_procs cm_procs; /* for the demo */ + const gx_device *cmdev; void *context; /* For a table and or a set of procs */ } rcm_link_t; -static void gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, +static void gsicc_rcm_transform_general(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out); @@ -48,7 +49,7 @@ static void gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, color conversions. Just putting in something that should work right now */ static void -gsicc_rcm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, +gsicc_rcm_planar_to_planar(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -85,7 +86,7 @@ gsicc_rcm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, /* This is not really used yet */ static void -gsicc_rcm_planar_to_chunky(gx_device *dev, gsicc_link_t *icclink, +gsicc_rcm_planar_to_chunky(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -97,7 +98,7 @@ gsicc_rcm_planar_to_chunky(gx_device *dev, gsicc_link_t *icclink, /* This is used with the fast thresholding code when doing -dUseFastColor and going out to a planar device */ static void -gsicc_rcm_chunky_to_planar(gx_device *dev, gsicc_link_t *icclink, +gsicc_rcm_chunky_to_planar(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -153,7 +154,7 @@ gsicc_rcm_chunky_to_planar(gx_device *dev, gsicc_link_t *icclink, } static void -gsicc_rcm_chunky_to_chunky(gx_device *dev, gsicc_link_t *icclink, +gsicc_rcm_chunky_to_chunky(const gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) @@ -223,7 +224,7 @@ gsicc_rcm_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, negative to show the effect of what using color replacement. We also use the device procs to map to the device value. */ static void -gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, +gsicc_rcm_transform_general(const gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out) { @@ -234,7 +235,6 @@ gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, frac frac_in[4]; frac frac_out[GX_DEVICE_COLOR_MAX_COMPONENTS]; int k; - gx_device *parentmost_dev = subclass_parentmost_device(dev); /* Make the negative for the demo.... */ if (num_bytes_in == 2) { @@ -251,14 +251,14 @@ gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, /* Use the device procedure */ switch (num_in) { case 1: - (link->cm_procs.map_gray)(parentmost_dev, frac_in[0], frac_out); + (link->cm_procs.map_gray)(link->cmdev, frac_in[0], frac_out); break; case 3: - (link->cm_procs.map_rgb)(parentmost_dev, NULL, frac_in[0], frac_in[1], + (link->cm_procs.map_rgb)(link->cmdev, NULL, frac_in[0], frac_in[1], frac_in[2], frac_out); break; case 4: - (link->cm_procs.map_cmyk)(parentmost_dev, frac_in[0], frac_in[1], frac_in[2], + (link->cm_procs.map_cmyk)(link->cmdev, frac_in[0], frac_in[1], frac_in[2], frac_in[3], frac_out); break; default: @@ -311,10 +311,10 @@ gsicc_rcm_get_link(const gs_gstate *pgs, gx_device *dev, rcm_link_t *rcm_link; gs_memory_t *mem; const gx_cm_color_map_procs * cm_procs; + const gx_device *cmdev; bool pageneutralcolor = false; cmm_dev_profile_t *dev_profile; int code; - subclass_color_mappings scm; if (dev == NULL) return NULL; @@ -328,8 +328,7 @@ gsicc_rcm_get_link(const gs_gstate *pgs, gx_device *dev, pageneutralcolor = dev_profile->pageneutralcolor; } - scm = get_color_mapping_procs_subclass(dev); - cm_procs = scm.procs; + cm_procs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); hash.rend_hash = gsCMM_REPLACE; hash.des_hash = dev->color_info.num_components; @@ -368,6 +367,7 @@ gsicc_rcm_get_link(const gs_gstate *pgs, gx_device *dev, rcm_link->cm_procs.map_cmyk = cm_procs->map_cmyk; rcm_link->cm_procs.map_rgb = cm_procs->map_rgb; rcm_link->cm_procs.map_gray = cm_procs->map_gray; + rcm_link->cmdev = cmdev; switch (data_cs) { case gsGRAY: diff --git a/base/gsimage.c b/base/gsimage.c index b3aefb93..25ae90b0 100644 --- a/base/gsimage.c +++ b/base/gsimage.c @@ -154,48 +154,40 @@ RELOC_PTRS_END static int is_image_visible(const gs_image_common_t * pic, gs_gstate * pgs, gx_clip_path *pcpath) { - /* HACK : We need the source image size here, - but gs_image_common_t doesn't pass it. - We would like to move Width, Height to gs_image_common, - but gs_image2_t appears to have those fields of double type. - */ - if (pic->type->begin_typed_image == gx_begin_image1) { - gs_image1_t *pim = (gs_image1_t *) pic; - gs_rect image_rect = {{0, 0}, {0, 0}}; - gs_rect device_rect; - gs_int_rect device_int_rect; - gs_matrix mat; - int code; - - image_rect.q.x = pim->Width; - image_rect.q.y = pim->Height; - if (pic->ImageMatrix.xx == ctm_only(pgs).xx && - pic->ImageMatrix.xy == ctm_only(pgs).xy && - pic->ImageMatrix.yx == ctm_only(pgs).yx && - pic->ImageMatrix.yy == ctm_only(pgs).yy) { - /* Handle common special case separately to accept singular matrix */ - mat.xx = mat.yy = 1.; - mat.yx = mat.xy = 0.; - mat.tx = ctm_only(pgs).tx - pic->ImageMatrix.tx; - mat.ty = ctm_only(pgs).ty - pic->ImageMatrix.ty; - } else { - code = gs_matrix_invert(&pic->ImageMatrix, &mat); - if (code < 0) - return code; - code = gs_matrix_multiply(&mat, &ctm_only(pgs), &mat); - if (code < 0) - return code; - } - code = gs_bbox_transform(&image_rect, &mat, &device_rect); + gs_rect image_rect = {{0, 0}, {0, 0}}; + gs_rect device_rect; + gs_int_rect device_int_rect; + gs_matrix mat; + int code; + + image_rect.q.x = pic->Width; + image_rect.q.y = pic->Height; + if (pic->ImageMatrix.xx == ctm_only(pgs).xx && + pic->ImageMatrix.xy == ctm_only(pgs).xy && + pic->ImageMatrix.yx == ctm_only(pgs).yx && + pic->ImageMatrix.yy == ctm_only(pgs).yy) { + /* Handle common special case separately to accept singular matrix */ + mat.xx = mat.yy = 1.; + mat.yx = mat.xy = 0.; + mat.tx = ctm_only(pgs).tx - pic->ImageMatrix.tx; + mat.ty = ctm_only(pgs).ty - pic->ImageMatrix.ty; + } else { + code = gs_matrix_invert(&pic->ImageMatrix, &mat); + if (code < 0) + return code; + code = gs_matrix_multiply(&mat, &ctm_only(pgs), &mat); if (code < 0) return code; - device_int_rect.p.x = (int)floor(device_rect.p.x); - device_int_rect.p.y = (int)floor(device_rect.p.y); - device_int_rect.q.x = (int)ceil(device_rect.q.x); - device_int_rect.q.y = (int)ceil(device_rect.q.y); - if (!gx_cpath_rect_visible(pcpath, &device_int_rect)) - return 0; } + code = gs_bbox_transform(&image_rect, &mat, &device_rect); + if (code < 0) + return code; + device_int_rect.p.x = (int)floor(device_rect.p.x); + device_int_rect.p.y = (int)floor(device_rect.p.y); + device_int_rect.q.x = (int)ceil(device_rect.q.x); + device_int_rect.q.y = (int)ceil(device_rect.q.y); + if (!gx_cpath_rect_visible(pcpath, &device_int_rect)) + return 0; return 1; } diff --git a/base/gsiparam.h b/base/gsiparam.h index 365c625a..bcf65371 100644 --- a/base/gsiparam.h +++ b/base/gsiparam.h @@ -43,20 +43,6 @@ */ typedef struct gx_image_type_s gx_image_type_t; -#define gs_image_common\ - const gx_image_type_t *type;\ - /*\ - * Define the transformation from user space to image space.\ - */\ - gs_matrix ImageMatrix -typedef struct gs_image_common_s { - gs_image_common; -} gs_image_common_t; - -#define public_st_gs_image_common() /* in gximage.c */\ - gs_public_st_simple(st_gs_image_common, gs_image_common_t,\ - "gs_image_common_t") - /* Parent image type enumerations. Since type3 images can give rise to type 1 image types, we want to know the origin of these to avoid doing different halftone methods to the image and the mask. */ @@ -87,7 +73,11 @@ typedef enum { * how the data are actually supplied. */ #define gs_data_image_common\ - gs_image_common;\ + const gx_image_type_t *type;\ + /*\ + * Define the transformation from user space to image space.\ + */\ + gs_matrix ImageMatrix;\ /*\ * Define the width of source image in pixels.\ */\ @@ -123,6 +113,9 @@ typedef struct gs_data_image_s { gs_public_st_simple(st_gs_data_image, gs_data_image_t,\ "gs_data_image_t") +/* Historically these were different. No longer. */ +typedef gs_data_image_t gs_image_common_t; + /* * Define the data common to ImageType 1 images, ImageType 3 DataDicts, * and ImageType 4 images -- i.e., all the image types that provide pixel diff --git a/base/gslib.c b/base/gslib.c index ef426b45..53d9db38 100644 --- a/base/gslib.c +++ b/base/gslib.c @@ -55,7 +55,6 @@ /* Test programs */ static int test1(gs_gstate *, gs_memory_t *); /* kaleidoscope */ static int test2(gs_gstate *, gs_memory_t *); /* pattern fill */ -static int test3(gs_gstate *, gs_memory_t *); /* RasterOp */ static int test4(gs_gstate *, gs_memory_t *); /* set resolution */ static int test5(gs_gstate *, gs_memory_t *); /* images */ static int test6(gs_gstate *, gs_memory_t *); /* CIE API, snapping */ @@ -69,7 +68,7 @@ static int test10(gs_gstate *, gs_memory_t *); /* captured data */ #endif static int (*tests[]) (gs_gstate *, gs_memory_t *) = { - test1, test2, test3, test4, test5, + test1, test2, test4, test5, test6, test7, test8, 0 #ifdef CAPTURE test10 @@ -408,45 +407,6 @@ test2(gs_gstate * pgs, gs_memory_t * mem) /* Exercise RasterOp a little. */ /* Currently, this only works with monobit devices. */ -static int -test3(gs_gstate * pgs, gs_memory_t * mem) -{ - gx_device *dev = gs_currentdevice(pgs); - gx_color_index black = gx_device_black(dev); - gx_color_index white = gx_device_white(dev); - gx_color_index black2[2]; - gx_color_index black_white[2]; - gx_color_index white_black[2]; - long pattern[max(align_bitmap_mod / sizeof(long), 1) * 4]; - -#define pbytes ((byte *)pattern) - gx_tile_bitmap tile; - - black2[0] = black2[1] = black; - black_white[0] = white_black[1] = black; - black_white[1] = white_black[0] = white; - pbytes[0] = 0xf0; - pbytes[align_bitmap_mod] = 0x90; - pbytes[align_bitmap_mod * 2] = 0x90; - pbytes[align_bitmap_mod * 3] = 0xf0; - tile.data = pbytes; - tile.raster = align_bitmap_mod; - tile.size.x = tile.size.y = 4; - tile.id = gs_next_ids(mem, 1); - tile.rep_width = tile.rep_height = 4; - (*dev_proc(dev, copy_rop)) - (dev, NULL, 0, 0, gx_no_bitmap_id, black2, - &tile, white_black, 100, 100, 150, 150, 0, 0, rop3_T); - (*dev_proc(dev, copy_rop)) - (dev, NULL, 0, 0, gx_no_bitmap_id, black2, - NULL, NULL, 120, 120, 110, 110, 0, 0, ~rop3_S & rop3_1); - (*dev_proc(dev, copy_rop)) - (dev, NULL, 0, 0, gx_no_bitmap_id, black2, - &tile, white_black, 110, 110, 130, 130, 0, 0, rop3_T ^ rop3_D); -#undef pbytes - return 0; -} - /* ---------------- Test program 4 ---------------- */ /* Set the resolution dynamically. */ @@ -576,10 +536,11 @@ test5(gs_gstate * pgs, gs_memory_t * mem) image1.Width = W; image1.Height = H; image1.BitsPerComponent = 8; + image1.format = gs_image_format_chunky; gs_translate(pgs, 0.5, 4.0); - code = gx_device_begin_image(dev, pgs, - &image1, gs_image_format_chunky, + code = gx_device_begin_typed_image(dev, pgs, NULL + (gs_image_common_t *)&image1, NULL, &dcolor, NULL, mem, &info1); /****** TEST code >= 0 ******/ planes[0].data = data3; diff --git a/base/gslibctx.c b/base/gslibctx.c index 6dfed6cd..318039fa 100644 --- a/base/gslibctx.c +++ b/base/gslibctx.c @@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s) int gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) { - char *fp, f[gp_file_name_sizeof]; - const int pipe = 124; /* ASCII code for '|' */ - const int len = strlen(fname); - int i, code; + char f[gp_file_name_sizeof]; + int code; /* Be sure the string copy will fit */ - if (len >= gp_file_name_sizeof) + if (strlen(fname) >= gp_file_name_sizeof) return gs_error_rangecheck; strcpy(f, fname); - fp = f; /* Try to rewrite any %d (or similar) in the string */ rewrite_percent_specifiers(f); - for (i = 0; i < len; i++) { - if (f[i] == pipe) { - fp = &f[i + 1]; - /* Because we potentially have to check file permissions at two levels - for the output file (gx_device_open_output_file and the low level - fopen API, if we're using a pipe, we have to add both the full string, - (including the '|', and just the command to which we pipe - since at - the pipe_fopen(), the leading '|' has been stripped. - */ - code = gs_add_control_path(mem, gs_permit_file_writing, f); - if (code < 0) - return code; - code = gs_add_control_path(mem, gs_permit_file_control, f); - if (code < 0) - return code; - break; - } - if (!IS_WHITESPACE(f[i])) - break; - } - code = gs_add_control_path(mem, gs_permit_file_control, fp); + + code = gs_add_control_path(mem, gs_permit_file_control, f); if (code < 0) return code; - return gs_add_control_path(mem, gs_permit_file_writing, fp); + return gs_add_control_path(mem, gs_permit_file_writing, f); } int gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) { - char *fp, f[gp_file_name_sizeof]; - const int pipe = 124; /* ASCII code for '|' */ - const int len = strlen(fname); - int i, code; + char f[gp_file_name_sizeof]; + int code; /* Be sure the string copy will fit */ - if (len >= gp_file_name_sizeof) + if (strlen(fname) >= gp_file_name_sizeof) return gs_error_rangecheck; strcpy(f, fname); - fp = f; /* Try to rewrite any %d (or similar) in the string */ - for (i = 0; i < len; i++) { - if (f[i] == pipe) { - fp = &f[i + 1]; - /* Because we potentially have to check file permissions at two levels - for the output file (gx_device_open_output_file and the low level - fopen API, if we're using a pipe, we have to add both the full string, - (including the '|', and just the command to which we pipe - since at - the pipe_fopen(), the leading '|' has been stripped. - */ - code = gs_remove_control_path(mem, gs_permit_file_writing, f); - if (code < 0) - return code; - code = gs_remove_control_path(mem, gs_permit_file_control, f); - if (code < 0) - return code; - break; - } - if (!IS_WHITESPACE(f[i])) - break; - } - code = gs_remove_control_path(mem, gs_permit_file_control, fp); + rewrite_percent_specifiers(f); + + code = gs_remove_control_path(mem, gs_permit_file_control, f); if (code < 0) return code; - return gs_remove_control_path(mem, gs_permit_file_writing, fp); + return gs_remove_control_path(mem, gs_permit_file_writing, f); } int diff --git a/base/gsmchunk.c b/base/gsmchunk.c index 1fec7acd..1d3e89d6 100644 --- a/base/gsmchunk.c +++ b/base/gsmchunk.c @@ -942,6 +942,7 @@ chunk_obj_alloc(gs_memory_t *mem, size_t size, gs_memory_type_ptr_t type, client memset((byte *)(obj) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t), 0xac, size); } + cmem->used += newsize; obj->size = newsize; /* actual size */ obj->padding = newsize - size; /* actual size - client requested size */ obj->type = type; /* and client desired type */ @@ -1095,9 +1096,11 @@ chunk_free_object(gs_memory_t *mem, void *ptr, client_name_t cname) } /* finalize may change the head_**_chunk doing free of stuff */ - if_debug3m('A', cmem->target, "[a-]chunk_free_object(%s) "PRI_INTPTR"(%u)\n", + if_debug3m('A', cmem->target, "[a-]chunk_free_object(%s) "PRI_INTPTR"(%"PRIuSIZE")\n", client_name_string(cname), (intptr_t)ptr, obj->size); + cmem->used -= obj->size; + if (SINGLE_OBJECT_CHUNK(obj->size - obj->padding)) { gs_free_object(cmem->target, obj, "chunk_free_object(single object)"); #ifdef DEBUG_CHUNK diff --git a/base/gsncdummy.c b/base/gsncdummy.c index 631bf2c4..aadc2d1c 100644 --- a/base/gsncdummy.c +++ b/base/gsncdummy.c @@ -526,7 +526,7 @@ convert_intensity_into_device_color(const frac intensity, cm = ck = 0; cc = cy = frac_1 - intensity; break; - case GS_PATH_TAG: /* Make lines and fills blue. */ + case GS_VECTOR_TAG: /* Make lines and fills blue. */ default: cy = ck = 0; cc = cm = frac_1 - intensity; diff --git a/base/gsovrc.c b/base/gsovrc.c index 16cd729c..745ebfbe 100644 --- a/base/gsovrc.c +++ b/base/gsovrc.c @@ -160,10 +160,10 @@ c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_devi } /* encoded the booleans in a single byte */ - if (pparams->retain_any_comps || pparams->is_fill_color || pparams->op_state) { + if (pparams->retain_any_comps || pparams->is_fill_color || pparams->op_state != OP_STATE_NONE) { flags |= (pparams->retain_any_comps) ? OVERPRINT_ANY_COMPS : 0; flags |= (pparams->is_fill_color) ? OVERPRINT_IS_FILL_COLOR : 0; - flags |= (pparams->op_state) << 2; + flags |= OVERPRINT_SET_FILL_COLOR & ((pparams->op_state) << 2); flags |= (pparams->effective_opm) << 4; /* write out the component bits */ @@ -181,11 +181,14 @@ c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_devi /* check for overflow */ *psize = used; - if (used > avail) - return_error(gs_error_rangecheck); + if (used > avail) { + if (avail != 0) + return_error(gs_error_rangecheck); + return gs_error_rangecheck; + } data[0] = flags; - if_debug2m('v', ((const gx_device *)cdev)->memory, "[v]c_overprint_write(%d), drawn_comps=0x%x\n", - flags, pparams->drawn_comps); + if_debug2m('v', ((const gx_device *)cdev)->memory, "[v]c_overprint_write(%d), drawn_comps=0x%"PRIx64"\n", + flags, (uint64_t)pparams->drawn_comps); return 0; } @@ -225,7 +228,7 @@ c_overprint_read( } if_debug1m('v', mem, ", retain_any_comps=%d", params.retain_any_comps); if_debug1m('v', mem, ", is_fill_color=%d", params.is_fill_color); - if_debug1m('v', mem, ", drawn_comps=0x%x", params.drawn_comps); + if_debug1m('v', mem, ", drawn_comps=0x%"PRIx64, (uint64_t)params.drawn_comps); if_debug1m('v', mem, ", op_state=%d", params.op_state); if_debug0m('v', mem, "\n"); code = gs_create_overprint(ppct, ¶ms, mem); @@ -381,7 +384,7 @@ gs_private_st_suffix_add0_final( st_overprint_device_t, /* * In the default (overprint false) case, the overprint device is almost - * a pure forwarding device: only the open_device and create_compositor + * a pure forwarding device: only the open_device and composite * methods are not pure-forwarding methods. The * gx_device_foward_fill_in_procs procedure does not fill in all of the * necessary procedures, so some of them are provided explicitly below. @@ -396,7 +399,7 @@ gs_private_st_suffix_add0_final( st_overprint_device_t, static dev_proc_open_device(overprint_open_device); static dev_proc_put_params(overprint_put_params); static dev_proc_get_page_device(overprint_get_page_device); -static dev_proc_create_compositor(overprint_create_compositor); +static dev_proc_composite(overprint_composite); static dev_proc_get_color_comp_index(overprint_get_color_comp_index); static dev_proc_fill_stroke_path(overprint_fill_stroke_path); static dev_proc_fill_path(overprint_fill_path); @@ -404,83 +407,24 @@ static dev_proc_stroke_path(overprint_stroke_path); static dev_proc_text_begin(overprint_text_begin); static dev_proc_dev_spec_op(overprint_dev_spec_op); -static const gx_device_procs no_overprint_procs = { - overprint_open_device, /* open_device */ - 0, /* get_initial_matrix */ - 0, /* sync_output */ - 0, /* output_page */ - 0, /* close_device */ - 0, /* map_rgb_color */ - 0, /* map_color_rgb */ - gx_forward_fill_rectangle, /* fill_rectangle */ - gx_forward_tile_rectangle, /* tile_rectangle */ - gx_forward_copy_mono, /* copy_mono */ - gx_forward_copy_color, /* copy_color */ - 0, /* draw_line (obsolete) */ - 0, /* get_bits */ - 0, /* get_params */ - overprint_put_params, /* put_params */ - 0, /* map_cmyk_color */ - 0, /* get_xfont_procs */ - 0, /* get_xfont_device */ - 0, /* map_rgb_alpha_color */ - overprint_get_page_device, /* get_page_device */ - 0, /* get_alpha_bits (obsolete) */ - 0, /* copy alpha */ - 0, /* get_band */ - 0, /* copy_rop */ - 0, /* fill_path */ - 0, /* stroke_path */ - 0, /* fill_mask */ - 0, /* fill_trapezoid */ - 0, /* fill_parallelogram */ - 0, /* fill_triangle */ - 0, /* draw_thin_line */ - 0, /* begin_image */ - 0, /* image_data (obsolete) */ - 0, /* end_image (obsolete) */ - gx_forward_strip_tile_rectangle, /* strip_tile_rectangle */ - 0, /* strip_copy_rop */ - 0, /* get_clipping_box */ - 0, /* begin_typed_image */ - 0, /* get_bits_rectangle */ - 0, /* map_color_rgb_alpha */ - overprint_create_compositor, /* create_compositor */ - 0, /* get_hardware_params */ - 0, /* text_begin */ - 0, /* gx_finish_copydevice */ - 0, /* begin_transparency_group */ - 0, /* end_transparency_group */ - 0, /* being_transparency_mask */ - 0, /* end_transparency_mask */ - 0, /* discard_transparency_layer */ - 0, /* get_color_mapping_procs */ - overprint_get_color_comp_index, /* get_color_comp_index */ - 0, /* encode_color */ - 0, /* decode_color */ - 0, /* pattern_manage */ - 0, /* fill_rectangle_hl_color */ - 0, /* include_color_space */ - 0, /* fill_linear_color_scanline */ - 0, /* fill_linear_color_trapezoid */ - 0, /* fill_linear_color_triangle */ - 0, /* update_spot_equivalent_colors */ - 0, /* ret_devn_params */ - gx_forward_fillpage, - 0, /* push_transparency_state */ - 0, /* pop_transparency_state */ - 0, /* put_image */ - overprint_dev_spec_op, /* dev_spec_op */ - gx_forward_copy_planes, - 0, /* get profile */ - 0, /* set graphics type tag */ - 0, /* strip_copy_rop2 */ - 0, /* strip_tile_rect_devn */ - gx_forward_copy_alpha_hl_color, /* copy_alpha_hl_color */ - NULL, /* process_page */\ - NULL, /* transform_pixel_region */\ - gx_forward_fill_stroke_path, /* fill_stroke */\ -}; +static void +nooverprint_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, overprint_open_device); + set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle); + set_dev_proc(dev, copy_mono, gx_forward_copy_mono); + set_dev_proc(dev, copy_color, gx_forward_copy_color); + set_dev_proc(dev, put_params, overprint_put_params); + set_dev_proc(dev, get_page_device, overprint_get_page_device); + set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle); + set_dev_proc(dev, composite, overprint_composite); + set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op); + set_dev_proc(dev, copy_planes, gx_forward_copy_planes); + set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color); + set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); +} /* * If overprint is set, the high and mid-level rendering methods are @@ -516,161 +460,75 @@ static dev_proc_copy_alpha_hl_color(overprint_copy_alpha_hl_color); /* other low-level overprint_sep_* rendering methods prototypes go here */ -static const gx_device_procs generic_overprint_procs = { - overprint_open_device, /* open_device */ - 0, /* get_initial_matrix */ - 0, /* sync_output */ - 0, /* output_page */ - 0, /* close_device */ - 0, /* map_rgb_color */ - 0, /* map_color_rgb */ - overprint_generic_fill_rectangle, /* fill_rectangle */ - gx_default_tile_rectangle, /* tile_rectangle */ - gx_default_copy_mono, /* copy_mono */ - gx_default_copy_color, /* copy_color */ - gx_default_draw_line, /* draw_line (obsolete) */ - 0, /* get_bits */ - 0, /* get_params */ - overprint_put_params, /* put_params */ - 0, /* map_cmyk_color */ - 0, /* get_xfont_procs */ - gx_default_get_xfont_device, /* get_xfont_device */ - 0, /* map_rgb_alpha_color */ - overprint_get_page_device, /* get_page_device */ - 0, /* get_alpha_bits (obsolete) */ - gx_default_copy_alpha, /* copy alpha */ - 0, /* get_band */ - gx_default_copy_rop, /* copy_rop */ - overprint_fill_path, /* fill_path */ - overprint_stroke_path, /* stroke_path */ - gx_default_fill_mask, /* fill_mask */ - gx_default_fill_trapezoid, /* fill_trapezoid */ - gx_default_fill_parallelogram, /* fill_parallelogram */ - gx_default_fill_triangle, /* fill_triangle */ - gx_default_draw_thin_line, /* draw_thin_line */ - gx_default_begin_image, /* begin_image */ - 0, /* image_data (obsolete) */ - 0, /* end_image (obsolete) */ - gx_default_strip_tile_rectangle, /* strip_tile_rectangle */ - gx_default_strip_copy_rop, /* strip_copy_rop */ - 0, /* get_clipping_box */ - gx_default_begin_typed_image, /* begin_typed_image */ - 0, /* get_bits_rectangle */ - 0, /* map_color_rgb_alpha */ - overprint_create_compositor, /* create_compositor */ - 0, /* get_hardware_params */ - overprint_text_begin, /* text_begin */ - 0, /* gx_finish_copydevice */ - 0, /* begin_transparency_group */ - 0, /* end_transparency_group */ - 0, /* begin_transparency_mask */ - 0, /* end_transparency_mask */ - 0, /* discard_transparency_layer */ - 0, /* get_color_mapping_procs */ - overprint_get_color_comp_index, /* get_color_comp_index */ - 0, /* encode_color */ - 0, /* decode_color */ - 0, /* pattern_manage */ - overprint_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - 0, /* include_color_space */ - 0, /* fill_linear_color_scanline */ - 0, /* fill_linear_color_trapezoid */ - 0, /* fill_linear_color_triangle */ - 0, /* update_spot_equivalent_colors */ - 0, /* ret_devn_params */ - 0, /* fillpage */ - 0, /* push_transparency_state */ - 0, /* pop_transparency_state */ - 0, /* put_image */ - overprint_dev_spec_op, /* dev_spec_op */ - gx_forward_copy_planes, - 0, /* get profile */ - 0, /* set graphics type tag */ - 0, /* strip_copy_rop2 */ - 0, /* strip_tile_rect_devn */ - gx_forward_copy_alpha_hl_color, /* copy_alpha_hl_color */ - NULL, /* process_page */\ - NULL, /* transform_pixel_region */\ - overprint_fill_stroke_path, /* fill_stroke */ -}; +static void +generic_overprint_initialize_device_procs(gx_device *dev) +{ + /* Note that we set lots of things to 'default' here. You can't + * omit them, because the caller for this particular initialization + * proc fills them in with 'forward' ones, rather than 'default' + * ones, and that doesn't work. Maybe look into this in future. */ + set_dev_proc(dev, open_device, overprint_open_device); + set_dev_proc(dev, fill_rectangle, overprint_generic_fill_rectangle); + set_dev_proc(dev, copy_mono, gx_default_copy_mono); + set_dev_proc(dev, copy_color, gx_default_copy_color); + set_dev_proc(dev, put_params, overprint_put_params); + set_dev_proc(dev, get_page_device, overprint_get_page_device); + set_dev_proc(dev, copy_alpha, gx_default_copy_alpha); + set_dev_proc(dev, fill_path, overprint_fill_path); + set_dev_proc(dev, stroke_path, overprint_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, composite, overprint_composite); + set_dev_proc(dev, text_begin, overprint_text_begin); + set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index); + set_dev_proc(dev, fill_rectangle_hl_color, overprint_fill_rectangle_hl_color); + set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op); + set_dev_proc(dev, copy_planes, gx_forward_copy_planes); + set_dev_proc(dev, copy_alpha_hl_color, dev->is_planar ? + overprint_copy_alpha_hl_color : + gx_forward_copy_alpha_hl_color); + set_dev_proc(dev, fill_stroke_path, overprint_fill_stroke_path); +} -static const gx_device_procs sep_overprint_procs = { - overprint_open_device, /* open_device */ - 0, /* get_initial_matrix */ - 0, /* sync_output */ - 0, /* output_page */ - 0, /* close_device */ - 0, /* map_rgb_color */ - 0, /* map_color_rgb */ - overprint_sep_fill_rectangle, /* fill_rectangle */ - gx_default_tile_rectangle, /* tile_rectangle */ - gx_default_copy_mono, /* copy_mono */ - gx_default_copy_color, /* copy_color */ - gx_default_draw_line, /* draw_line (obsolete) */ - 0, /* get_bits */ - 0, /* get_params */ - overprint_put_params, /* put_params */ - 0, /* map_cmyk_color */ - 0, /* get_xfont_procs */ - gx_default_get_xfont_device, /* get_xfont_device */ - 0, /* map_rgb_alpha_color */ - overprint_get_page_device, /* get_page_device */ - 0, /* get_alpha_bits (obsolete) */ - gx_default_copy_alpha, /* copy alpha */ - 0, /* get_band */ - gx_default_copy_rop, /* copy_rop */ - overprint_fill_path, /* fill_path */ - overprint_stroke_path, /* stroke_path */ - gx_default_fill_mask, /* fill_mask */ - gx_default_fill_trapezoid, /* fill_trapezoid */ - gx_default_fill_parallelogram, /* fill_parallelogram */ - gx_default_fill_triangle, /* fill_triangle */ - gx_default_draw_thin_line, /* draw_thin_line */ - gx_default_begin_image, /* begin_image */ - 0, /* image_data (obsolete) */ - 0, /* end_image (obsolete) */ - gx_default_strip_tile_rectangle, /* strip_tile_rectangle */ - gx_default_strip_copy_rop, /* strip_copy_rop */ - 0, /* get_clipping_box */ - gx_default_begin_typed_image, /* begin_typed_image */ - 0, /* get_bits_rectangle */ - 0, /* map_color_rgb_alpha */ - overprint_create_compositor, /* create_compositor */ - 0, /* get_hardware_params */ - overprint_text_begin, /* text_begin */ - 0, /* gx_finish_copydevice */ - 0, /* begin_transparency_group */ - 0, /* end_transparency_group */ - 0, /* begin_transparency_mask */ - 0, /* end_transparency_mask */ - 0, /* discard_transparency_layer */ - 0, /* get_color_mapping_procs */ - overprint_get_color_comp_index, /* get_color_comp_index */ - 0, /* encode_color */ - 0, /* decode_color */ - 0, /* pattern_manage */ - overprint_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - 0, /* include_color_space */ - 0, /* fill_linear_color_scanline */ - 0, /* fill_linear_color_trapezoid */ - 0, /* fill_linear_color_triangle */ - 0, /* update_spot_equivalent_colors */ - 0, /* ret_devn_params */ - 0, /* fillpage */ - 0, /* push_transparency_state */ - 0, /* pop_transparency_state */ - 0, /* put_image */ - overprint_dev_spec_op, /* dev_spec_op */ - overprint_copy_planes, /* copy planes */ - 0, /* get profile */ - 0, /* set graphics type tag */ - 0, /* strip_copy_rop2 */ - 0, /* strip_tile_rect_devn */ - overprint_copy_alpha_hl_color, /* copy_alpha_hl_color */ - NULL, /* process_page */\ - NULL, /* transform_pixel_region */\ - overprint_fill_stroke_path, /* fill_stroke */ -}; +static void +sep_overprint_initialize_device_procs(gx_device *dev) +{ + /* Note that we set lots of things to 'default' here. You can't + * omit them, because the caller for this particular initialization + * proc fills them in with 'forward' ones, rather than 'default' + * ones, and that doesn't work. Maybe look into this in future. */ + set_dev_proc(dev, open_device, overprint_open_device); + set_dev_proc(dev, fill_rectangle, overprint_sep_fill_rectangle); + set_dev_proc(dev, copy_mono, gx_default_copy_mono); + set_dev_proc(dev, copy_color, gx_default_copy_color); + set_dev_proc(dev, put_params, overprint_put_params); + set_dev_proc(dev, get_page_device, overprint_get_page_device); + set_dev_proc(dev, copy_alpha, gx_default_copy_alpha); + set_dev_proc(dev, fill_path, overprint_fill_path); + set_dev_proc(dev, stroke_path, overprint_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, composite, overprint_composite); + set_dev_proc(dev, text_begin, overprint_text_begin); + set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index); + set_dev_proc(dev, fill_rectangle_hl_color, overprint_fill_rectangle_hl_color); + set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op); + set_dev_proc(dev, copy_planes, overprint_copy_planes); + set_dev_proc(dev, copy_alpha_hl_color, overprint_copy_alpha_hl_color); + set_dev_proc(dev, fill_stroke_path, overprint_fill_stroke_path); +} /* * The prototype for the overprint device does not provide much @@ -679,7 +537,7 @@ static const gx_device_procs sep_overprint_procs = { */ const overprint_device_t gs_overprint_device = { std_device_std_body_open( overprint_device_t, /* device type */ - 0, /* static_procs */ + NULL, /* initialize */ "overprint_device", /* dname */ 0, 0, /* width, height */ 1, 1 ), /* HWResolution */ @@ -785,15 +643,16 @@ update_overprint_params( we will turn it off when setting one and turn on when setting the other (or vice versa) */ - /* Note if pparams is to set the opdev fill stroke state. Do that now and exit */ + /* Note if pparams->op_state is not NONE, set the opdev fill/stroke state. */ if (pparams->op_state != OP_STATE_NONE) { opdev->op_state = pparams->op_state; return 0; } if_debug4m(gs_debug_flag_overprint, opdev->memory, - "[overprint] update_overprint_params enter. retain_any_comps = %d, idle = %d, drawn_comps = 0x%x, is_fill_color = %d\n", - pparams->retain_any_comps, pparams->idle, pparams->drawn_comps, pparams->is_fill_color); + "[overprint] update_overprint_params enter. retain_any_comps = %d, idle = %d, drawn_comps = 0x%"PRIx64", is_fill_color = %d\n", + pparams->retain_any_comps, pparams->idle, + (uint64_t)pparams->drawn_comps, pparams->is_fill_color); /* check if overprint is to be turned off */ if (!pparams->retain_any_comps || pparams->idle) { @@ -820,8 +679,10 @@ update_overprint_params( } if_debug4m(gs_debug_flag_overprint, opdev->memory, - "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%x, drawn_comps_stroke = 0x%x, retain_none_fill = %d, retain_none_stroke = %d \n", - opdev->drawn_comps_fill, opdev->drawn_comps_stroke, opdev->retain_none_fill, opdev->retain_none_stroke); + "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%"PRIx64", drawn_comps_stroke = 0x%"PRIx64", retain_none_fill = %d, retain_none_stroke = %d \n", + (uint64_t)opdev->drawn_comps_fill, + (uint64_t)opdev->drawn_comps_stroke, + opdev->retain_none_fill, opdev->retain_none_stroke); return 0; } @@ -848,8 +709,10 @@ update_overprint_params( } if_debug4m(gs_debug_flag_overprint, opdev->memory, - "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%x, drawn_comps_stroke = 0x%x, retain_none_fill = %d, retain_none_stroke = %d \n", - opdev->drawn_comps_fill, opdev->drawn_comps_stroke, opdev->retain_none_fill, opdev->retain_none_stroke); + "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%"PRIx64", drawn_comps_stroke = 0x%"PRIx64", retain_none_fill = %d, retain_none_stroke = %d \n", + (uint64_t)opdev->drawn_comps_fill, + (uint64_t)opdev->drawn_comps_stroke, + opdev->retain_none_fill, opdev->retain_none_stroke); /* if appropriate, update the retain_mask field */ if (colors_are_separable_and_linear(&opdev->color_info)) @@ -942,11 +805,11 @@ overprint_get_page_device(gx_device * dev) } /* - * Calling create_compositor on the overprint device just updates the + * Calling composite on the overprint device just updates the * overprint parameters; no new device is created. */ static int -overprint_create_compositor( +overprint_composite( gx_device * dev, gx_device ** pcdev, const gs_composite_t * pct, @@ -955,7 +818,7 @@ overprint_create_compositor( gx_device * cdev) { if (pct->type != &gs_composite_overprint_type) - return gx_default_create_compositor(dev, pcdev, pct, pgs, memory, cdev); + return gx_default_composite(dev, pcdev, pct, pgs, memory, cdev); else { gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params; overprint_device_t *opdev = (overprint_device_t *)dev; @@ -972,8 +835,11 @@ overprint_create_compositor( params.idle = pct->idle; /* device must already exist, so just update the parameters if settings change */ if_debug6m(gs_debug_flag_overprint, opdev->memory, - "[overprint] overprint_create_compositor test for change. params.idle = %d vs. opdev->is_idle = %d \n params.is_fill_color = %d: params.drawn_comps = 0x%x vs. opdev->drawn_comps_fill = 0x%x OR opdev->drawn_comps_stroke = 0x%x\n", - params.idle, opdev->is_idle, params.is_fill_color, params.drawn_comps, opdev->drawn_comps_fill, opdev->drawn_comps_stroke); + "[overprint] overprint_composite test for change. params.idle = %d vs. opdev->is_idle = %d \n params.is_fill_color = %d: params.drawn_comps = 0x%"PRIx64" vs. opdev->drawn_comps_fill = 0x%"PRIx64" OR opdev->drawn_comps_stroke = 0x%"PRIx64"\n", + params.idle, opdev->is_idle, params.is_fill_color, + (uint64_t)params.drawn_comps, + (uint64_t)opdev->drawn_comps_fill, + (uint64_t)opdev->drawn_comps_stroke); if (update || params.idle != opdev->is_idle || params.op_state != OP_STATE_NONE) code = update_overprint_params(opdev, ¶ms); @@ -1006,7 +872,7 @@ overprint_generic_fill_rectangle( return 0; else { - assert(opdev->op_state != 0); + assert(opdev->op_state != OP_STATE_NONE); /* See if we even need to do any overprinting. We have to maintain the compositor active for fill/stroke cases even if we are only @@ -1118,7 +984,7 @@ overprint_copy_planes(gx_device * dev, const byte * data, int data_x, int raster gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * raster; code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, - &gb_params, 0); + &gb_params); if (code < 0) { gs_free_object(mem, gb_buff, "overprint_copy_planes" ); return code; @@ -1185,7 +1051,7 @@ overprint_fill_rectangle_hl_color(gx_device *dev, if (tdev == 0) return 0; - assert(opdev->op_state != 0); + assert(opdev->op_state != OP_STATE_NONE); /* See if we even need to do any overprinting. We have to maintain the compositor active for fill/stroke cases even if we are only @@ -1242,7 +1108,7 @@ overprint_fill_rectangle_hl_color(gx_device *dev, gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * raster; code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, - &gb_params, 0); + &gb_params); if (code < 0) { gs_free_object(mem, gb_buff, "overprint_fill_rectangle_hl_color" ); @@ -1288,7 +1154,7 @@ overprint_sep_fill_rectangle( else { int depth = tdev->color_info.depth; - assert(opdev->op_state != 0); + assert(opdev->op_state != OP_STATE_NONE); /* See if we even need to do any overprinting. We have to maintain the compositor active for fill/stroke cases even if we are only @@ -1341,10 +1207,13 @@ overprint_fill_path(gx_device* pdev, const gs_gstate* pgs, const gx_device_color* pdcolor, const gx_clip_path* pcpath) { overprint_device_t* opdev = (overprint_device_t*)pdev; + OP_FS_STATE save_op_state = opdev->op_state; + int code; opdev->op_state = OP_STATE_FILL; - return gx_default_fill_path(pdev, pgs, ppath, params_fill, - pdcolor, pcpath); + code = gx_default_fill_path(pdev, pgs, ppath, params_fill, pdcolor, pcpath); + opdev->op_state = save_op_state; + return code; } /* We need this to ensure the device knows we are doing a stroke */ @@ -1354,6 +1223,7 @@ overprint_stroke_path(gx_device* pdev, const gs_gstate* pgs, const gx_device_color* pdcolor, const gx_clip_path* pcpath) { overprint_device_t* opdev = (overprint_device_t*)pdev; + OP_FS_STATE save_op_state = opdev->op_state; int code; opdev->op_state = OP_STATE_STROKE; @@ -1361,9 +1231,9 @@ overprint_stroke_path(gx_device* pdev, const gs_gstate* pgs, /* Stroke methods use fill path so set that to default to avoid mix up of is_fill_color */ opdev->procs.fill_path = gx_default_fill_path; - code = gx_default_stroke_path(pdev, pgs, ppath, params_stroke, - pdcolor, pcpath); + code = gx_default_stroke_path(pdev, pgs, ppath, params_stroke, pdcolor, pcpath); opdev->procs.fill_path = overprint_fill_path; + opdev->op_state = save_op_state; return code; } @@ -1382,6 +1252,7 @@ overprint_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs, { int code; overprint_device_t *opdev = (overprint_device_t *)pdev; + OP_FS_STATE save_op_state = opdev->op_state; opdev->op_state = OP_STATE_FILL; code = dev_proc(pdev, fill_path)(pdev, pgs, ppath, params_fill, pdevc_fill, pcpath); @@ -1391,6 +1262,7 @@ overprint_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs, /* Set up for stroke */ opdev->op_state = OP_STATE_STROKE; code = dev_proc(pdev, stroke_path)(pdev, pgs, ppath, params_stroke, pdevc_stroke, pcpath); + opdev->op_state = save_op_state; return code; } @@ -1398,19 +1270,21 @@ overprint_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs, static int overprint_text_begin(gx_device* dev, gs_gstate* pgs, const gs_text_params_t* text, gs_font* font, - gx_path* path, const gx_device_color* pdcolor, const gx_clip_path* pcpath, - gs_memory_t* mem, gs_text_enum_t** ppte) + gs_text_enum_t** ppte) { overprint_device_t* opdev = (overprint_device_t*)dev; + OP_FS_STATE save_op_state = opdev->op_state; + int code = 0; if (pgs->text_rendering_mode == 0) opdev->op_state = OP_STATE_FILL; else if (pgs->text_rendering_mode == 1) opdev->op_state = OP_STATE_STROKE; - return gx_default_text_begin(dev, pgs, text, font, - path, pdcolor, pcpath, mem, ppte); + code = gx_default_text_begin(dev, pgs, text, font, pcpath, ppte); + opdev->op_state = save_op_state; + return code; } static int @@ -1443,10 +1317,12 @@ overprint_dev_spec_op(gx_device* pdev, int dev_spec_op, } /* complete a procedure set */ -static void -fill_in_procs(gx_device_procs * pprocs) +static int +fill_in_procs(gx_device_procs * pprocs, + dev_proc_initialize_device_procs(initialize_device_procs), + int is_planar) { - gx_device_forward tmpdev; + gx_device_forward tmpdev; /* * gx_device_forward_fill_in_procs calls gx_device_fill_in_procs, which @@ -1457,15 +1333,20 @@ fill_in_procs(gx_device_procs * pprocs) memcpy( &tmpdev.color_info, &gs_overprint_device.color_info, sizeof(tmpdev.color_info) ); + tmpdev.is_planar = is_planar; + /* * Prevent the check_device_separable routine from executing while we * fill in the procs. Our tmpdev is not complete enough for it. */ tmpdev.color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE; - tmpdev.static_procs = 0; - memcpy(&tmpdev.procs, pprocs, sizeof(tmpdev.procs)); + memset(&tmpdev.procs, 0, sizeof(tmpdev.procs)); + tmpdev.initialize_device_procs = initialize_device_procs; + initialize_device_procs((gx_device *)&tmpdev); gx_device_forward_fill_in_procs(&tmpdev); memcpy(pprocs, &tmpdev.procs, sizeof(tmpdev.procs)); + + return 0; } /* @@ -1506,30 +1387,33 @@ c_overprint_create_default_compositor( *popdev = (gx_device *)opdev; if (opdev == NULL) return_error(gs_error_VMerror); - gx_device_init((gx_device *)opdev, - (const gx_device *)&gs_overprint_device, - mem, - false ); - memcpy(&opdev->no_overprint_procs, - &no_overprint_procs, - sizeof(no_overprint_procs)); - memcpy(&opdev->generic_overprint_procs, - &generic_overprint_procs, - sizeof(generic_overprint_procs)); - memcpy(&opdev->sep_overprint_procs, - &sep_overprint_procs, - sizeof(sep_overprint_procs)); - fill_in_procs(&opdev->no_overprint_procs); - fill_in_procs(&opdev->generic_overprint_procs); - fill_in_procs(&opdev->sep_overprint_procs); + code = gx_device_init((gx_device *)opdev, + (const gx_device *)&gs_overprint_device, + mem, + false); + if (code < 0) + return code; + code = fill_in_procs(&opdev->no_overprint_procs, + nooverprint_initialize_device_procs, + tdev->is_planar); + if (code < 0) + return code; + code = fill_in_procs(&opdev->generic_overprint_procs, + generic_overprint_initialize_device_procs, + tdev->is_planar); + if (code < 0) + return code; + code = fill_in_procs(&opdev->sep_overprint_procs, + sep_overprint_initialize_device_procs, + tdev->is_planar); + if (code < 0) + return code; gx_device_copy_params((gx_device *)opdev, tdev); gx_device_set_target((gx_device_forward *)opdev, tdev); opdev->pad = tdev->pad; opdev->log2_align_mod = tdev->log2_align_mod; opdev->is_planar = tdev->is_planar; - if (opdev->is_planar) - opdev->generic_overprint_procs.copy_alpha_hl_color = overprint_copy_alpha_hl_color; params = ovrpct->params; params.idle = ovrpct->idle; diff --git a/base/gsovrc.h b/base/gsovrc.h index 790fcaf5..64e2a9d5 100644 --- a/base/gsovrc.h +++ b/base/gsovrc.h @@ -195,7 +195,7 @@ * state, cease to exist as as independent item. The only way to discard * the compositor is to change the current device. * - * Subsequent invocations of create_compositor will not create a new + * Subsequent invocations of composite will not create a new * compositor. Rather, they change the parameters of the existing * compositor device. The compositor functions with only a small * performance penalty if overprint is disabled, so there is no reason diff --git a/base/gspaint.c b/base/gspaint.c index 70ff0ce6..9c4e8210 100644 --- a/base/gspaint.c +++ b/base/gspaint.c @@ -295,7 +295,7 @@ static int do_fill(gs_gstate *pgs, int rule) segment structure (depending on how fine grained we require it to be). */ if (pgs->show_gstate == NULL) - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ else ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ @@ -415,7 +415,7 @@ do_stroke(gs_gstate * pgs) segment structure (depending on how fine grained we require it to be). */ if (pgs->show_gstate == NULL) - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ else ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ @@ -644,7 +644,7 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) segment structure (depending on how fine grained we require it to be). */ if (pgs->show_gstate == NULL) - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ else ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ @@ -684,7 +684,7 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) /* Have to set the fill color too */ if (pgs->show_gstate == NULL) - ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */ else ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ diff --git a/base/gsparam.c b/base/gsparam.c index e8a2f0c5..c8bfe7f9 100644 --- a/base/gsparam.c +++ b/base/gsparam.c @@ -102,7 +102,8 @@ static const byte xfer_item_sizes[] = { }; int gs_param_read_items(gs_param_list * plist, void *obj, - const gs_param_item_t * items) + const gs_param_item_t * items, + gs_memory_t *mem) { const gs_param_item_t *pi; int ecode = 0; @@ -123,8 +124,128 @@ gs_param_read_items(gs_param_list * plist, void *obj, case 0: if (typed.type != pi->type) /* shouldn't happen! */ ecode = gs_note_error(gs_error_typecheck); - else - memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]); + else { + switch(typed.type) + { + case gs_param_type_dict: + case gs_param_type_dict_int_keys: + case gs_param_type_array: + return_error(gs_error_rangecheck); + case gs_param_type_string: + case gs_param_type_name: + { + void *copy; + gs_string *s; + if (mem == NULL) { + /* Return pointers to the data in the param list. This + * means that if the caller wants to keep it around it + * needs to copy it itself, or run the risk of the + * param list going away. */ + goto copy_pointer; + } + /* Free any existing data before copying into it. */ + s = ((gs_string *)pvalue); + if (typed.value.s.size != s->size) { + gs_free_string(mem, s->data, s->size, "gs_param_read_items"); + s->data = NULL; + s->size = 0; + copy = gs_alloc_string(mem, typed.value.s.size, "gs_param_read_items"); + if (copy == NULL) + return_error(gs_error_VMerror); + s->size = typed.value.s.size; + } else { + copy = s->data; + } + memcpy(copy, typed.value.s.data, typed.value.s.size); + s->data = copy; + ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */ + break; + } + case gs_param_type_int_array: + case gs_param_type_float_array: + case gs_param_type_string_array: + case gs_param_type_name_array: + { + int eltsize; + gs_param_string_array *sa; + if (mem == NULL) { + /* Return pointers to the data in the param list. This + * means that if the caller wants to keep it around it + * needs to copy it itself, or run the risk of the + * param list going away. */ + goto copy_pointer; + } + /* Free any existing data before copying into it. */ + eltsize = gs_param_type_base_sizes[typed.type]; + sa = ((gs_param_string_array *)pvalue); + if (typed.value.ia.size != sa->size) { + void *copy; + if (typed.type == gs_param_type_name_array || + typed.type == gs_param_type_string_array) { + /* Free the strings. */ + int i; + gs_param_string *arr; + union { const gs_param_string *cs; gs_param_string *s; } u; + u.cs = sa->data; + arr = u.s; /* Hideous dodge to avoid the const. */ + for (i = 0; i < typed.value.sa.size; i++) { + /* Hideous hackery to get around the const nature of gs_param_strings. */ + gs_string *arr_non_const = (gs_string *)(void *)(&arr[i]); + if (arr[i].persistent == 0) + gs_free_string(mem, arr_non_const->data, arr_non_const->size, "gs_param_read_items"); + arr_non_const->data = NULL; + arr_non_const->size = 0; + } + } + gs_free_const_object(mem, sa->data, "gs_param_read_items"); + sa->data = NULL; + sa->size = 0; + copy = gs_alloc_bytes(mem, eltsize * typed.value.s.size, "gs_param_read_items"); + if (copy == NULL) + return_error(gs_error_VMerror); + memset(copy, 0, eltsize * typed.value.s.size); + sa->size = typed.value.s.size; + sa->data = copy; + } + /* Now copy the elements of the arrays. */ + if (typed.type == gs_param_type_name_array || + typed.type == gs_param_type_string_array) { + /* Free the strings. */ + int i; + const gs_param_string *src = typed.value.sa.data; + gs_param_string *dst; + union { const gs_param_string *cs; gs_param_string *s; } u; + u.cs = sa->data; + dst = u.s; /* Hideous dodge to avoid the const. */ + for (i = 0; i < typed.value.sa.size; i++) { + /* Hideous hackery to get around the const nature of gs_param_strings. */ + gs_string *dst_non_const = (gs_string *)(void *)(&dst[i]); + if (dst[i].persistent == 0) + gs_free_string(mem, dst_non_const->data, dst_non_const->size, "gs_param_read_items"); + dst_non_const->data = NULL; + dst_non_const->size = 0; + } + /* Copy values */ + for (i = 0; i < sa->size; i++) { + dst[i].data = gs_alloc_string(mem, src[i].size, "gs_param_read_items"); + if (dst[i].data == NULL) + return_error(gs_error_VMerror); + dst[i].size = src[i].size; + dst[i].persistent = 0; /* 0 => We own this copy */ + } + } else { + /* Hideous hackery to get around the const nature of gs_param_strings. */ + gs_string *s = (gs_string *)(void *)sa; + memcpy(s->data, typed.value.s.data, eltsize * typed.value.s.size); + } + ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */ + break; + } + default: + copy_pointer: + memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]); + } + } } } return ecode; @@ -150,6 +271,8 @@ gs_param_write_items(gs_param_list * plist, const void *obj, continue; memcpy(&typed.value, pvalue, size); typed.type = pi->type; + /* Ensure the list doesn't end up keeping a pointer to our values. */ + typed.value.s.persistent = 0; code = (*plist->procs->xmit_typed) (plist, key, &typed); if (code < 0) ecode = code; diff --git a/base/gsparam.h b/base/gsparam.h index 43cc92d8..df3b1c03 100644 --- a/base/gsparam.h +++ b/base/gsparam.h @@ -374,6 +374,15 @@ typedef struct gs_param_list_procs_s { #define param_commit(plist)\ (*(plist)->procs->commit)(plist) + /* + * Read the value of a previously signalled error. (Only used when reading.) + */ +#define param_proc_read_signalled_error(proc)\ + int proc(gs_param_list *, gs_param_name) + param_proc_read_signalled_error((*read_signalled_error)); +#define param_read_signalled_error(plist, pkey)\ + (*(plist)->procs->read_signalled_error)(plist, pkey) + } gs_param_list_procs; /* Transmit typed parameters. */ @@ -477,7 +486,8 @@ typedef struct gs_param_item_s { * the optional default_obj, the item isn't transferred. */ int gs_param_read_items(gs_param_list * plist, void *obj, - const gs_param_item_t * items); + const gs_param_item_t * items, + gs_memory_t *mem); int gs_param_write_items(gs_param_list * plist, const void *obj, const void *default_obj, const gs_param_item_t * items); diff --git a/base/gsparamx.c b/base/gsparamx.c index 2893253a..8ca19a5b 100644 --- a/base/gsparamx.c +++ b/base/gsparamx.c @@ -156,6 +156,8 @@ param_list_copy(gs_param_list *plto, gs_param_list *plfrom) coll_type = gs_param_collection_array; cc: copy.value.d.size = value.value.d.size; + /* FIXME: RJW: I suspect that this will go wrong, if size == 0. + * We should probably spot size == 0 and break. */ if ((code = param_begin_write_collection(plto, string_key, ©.value.d, coll_type)) < 0 || diff --git a/base/gspcolor.c b/base/gspcolor.c index 4fb53680..417fb139 100644 --- a/base/gspcolor.c +++ b/base/gspcolor.c @@ -293,7 +293,7 @@ gx_set_overprint_Pattern(const gs_color_space * pcs, gs_gstate * pgs) /* Adjust the reference counts for Pattern color spaces or colors. */ static void -gx_final_Pattern(const gs_color_space * pcs) +gx_final_Pattern(gs_color_space * pcs) { /* {csrc} really do nothing? */ } @@ -305,7 +305,7 @@ gx_adjust_color_Pattern(const gs_client_color * pcc, gs_pattern_instance_t *pinst = pcc->pattern; rc_adjust_only(pinst, delta, "gx_adjust_color_Pattern"); - if (pcs && pcs->params.pattern.has_base_space) + if (pcs && pcs->base_space && pcs->params.pattern.has_base_space) (pcs->base_space->type->adjust_color_count) (pcc, pcs->base_space, delta); } diff --git a/base/gsptype1.c b/base/gsptype1.c index c4589488..732047ec 100644 --- a/base/gsptype1.c +++ b/base/gsptype1.c @@ -184,7 +184,11 @@ gs_pattern1_make_pattern(gs_client_color * pcc, code = gs_note_error(gs_error_rangecheck); goto fsaved; } + inst.templat = *pcp; + /* Even if the pattern wants to use transparency, don't permit it if there is no device which will support it */ + inst.templat.uses_transparency &= dev_proc( gs_currentdevice_inline(pgs), dev_spec_op)( gs_currentdevice_inline(pgs), gxdso_supports_pattern_transparency, NULL, 0);; + code = compute_inst_matrix(&inst, &bbox, dev_width, dev_height, &bbw, &bbh); if (code < 0) goto fsaved; @@ -775,7 +779,7 @@ gs_pattern1_set_color(const gs_client_color * pcc, gs_gstate * pgs) params.retain_any_comps = false; params.effective_opm = pgs->color[0].effective_opm = 0; params.op_state = OP_STATE_NONE; - params.is_fill_color = false; + params.is_fill_color = pgs->is_fill_color; params.idle = false; return gs_gstate_update_overprint(pgs, ¶ms); diff --git a/base/gsptype2.c b/base/gsptype2.c index 878fbe64..b9ef6a05 100644 --- a/base/gsptype2.c +++ b/base/gsptype2.c @@ -158,13 +158,14 @@ gx_dc_is_pattern2_color(const gx_device_color *pdevc) } /* - * The device halftone used by a PatternType 2 patter is that current in + * The device halftone used by a PatternType 2 pattern is that current in * the graphic state at the time of the makepattern call. */ static const gx_device_halftone * gx_dc_pattern2_get_dev_halftone(const gx_device_color * pdevc) { - return ((gs_pattern2_instance_t *)pdevc->ccolor.pattern)->saved->dev_ht; + /* FIXME: Do we need to be objtype specific w.r.t. to the dev_ht ??? */ + return ((gs_pattern2_instance_t *)pdevc->ccolor.pattern)->saved->dev_ht[HT_OBJTYPE_DEFAULT]; } /* Load a PatternType 2 color into the cache. (No effect.) */ diff --git a/base/gsrefct.h b/base/gsrefct.h index bfdb1a6f..98d1896e 100644 --- a/base/gsrefct.h +++ b/base/gsrefct.h @@ -21,6 +21,7 @@ #include "memento.h" #include "std.h" +#include "gdebug.h" /* * A reference-counted object must include the following header: @@ -135,6 +136,7 @@ rc_free_proc(rc_free_struct_only); BEGIN\ IF_RC_DEBUG(rc_trace_adjust(vp, &(vp)->rc, delta, cname));\ (vp)->rc.ref_count += (delta);\ + (void)Memento_adjustRef((vp), delta);\ END #define rc_unshare_struct(vp, typ, pstype, mem, errstat, cname)\ BEGIN\ diff --git a/base/gsstate.c b/base/gsstate.c index e8077d07..3a4542d1 100644 --- a/base/gsstate.c +++ b/base/gsstate.c @@ -76,7 +76,7 @@ static void clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t c * * (3a) Objects that are logically connected to individual gstates. * We use reference counting to manage these. Currently these are: - * halftone, dev_ht, cie_render, black_generation, + * halftone, dev_ht(4), cie_render, black_generation, * undercolor_removal, set_transfer.*, cie_joint_caches, * clip_stack, {opacity,shape}.mask * effective_transfer.* may point to some of the same objects as @@ -277,7 +277,7 @@ gs_gstate_client_data(const gs_gstate * pgs) } /* Free the chain of gstates.*/ -int +void gs_gstate_free_chain(gs_gstate * pgs) { gs_gstate *saved = pgs, *tmp; @@ -287,16 +287,16 @@ gs_gstate_free_chain(gs_gstate * pgs) gs_gstate_free(saved); saved = tmp; } - return 0; } /* Free a graphics state. */ -int +void gs_gstate_free(gs_gstate * pgs) { + if (pgs == NULL) + return; gstate_free_contents(pgs); gs_free_object(pgs->memory, pgs, "gs_gstate_free"); - return 0; } /* Save the graphics state. */ @@ -571,7 +571,7 @@ gs_gstate_swap_memory(gs_gstate * pgs, gs_memory_t * mem) /* * Push an overprint compositor onto the current device. Note that if * the current device already is an overprint compositor, the - * create_compositor will update its parameters but not create a new + * composite will update its parameters but not create a new * compositor device. */ int @@ -584,7 +584,7 @@ gs_gstate_update_overprint(gs_gstate * pgs, const gs_overprint_params_t * pparam code = gs_create_overprint(&pct, pparams, pgs->memory); if (code >= 0) { - code = dev_proc(dev, create_compositor)( dev, + code = dev_proc(dev, composite)( dev, &ovptdev, pct, pgs, @@ -1317,11 +1317,11 @@ typedef struct { static gs_gstate * gstate_clone_core(const gs_gstate *pfrom, + gs_memory_t *mem, client_name_t cname, gs_gstate_clone_data *clone_data, gs_gstate_copy_reason_t reason) { - gs_memory_t *mem = pfrom->memory; gs_gstate *pgs = gstate_alloc(mem, cname, pfrom); void *pdata = NULL; @@ -1386,8 +1386,8 @@ gstate_clone_for_gsave(gs_gstate *pfrom, client_name_t cname) { gs_gstate_clone_data clone_data; - gs_gstate *pgs = gstate_clone_core(pfrom, cname, &clone_data, - copy_for_gsave); + gs_gstate *pgs = gstate_clone_core(pfrom, pfrom->memory, cname, + &clone_data, copy_for_gsave); if (pgs == NULL) return NULL; @@ -1407,7 +1407,7 @@ gstate_clone_for_gstate(const gs_gstate *pfrom, client_name_t cname) { gs_gstate_clone_data clone_data; - gs_gstate *pgs = gstate_clone_core(pfrom, cname, &clone_data, + gs_gstate *pgs = gstate_clone_core(pfrom, mem, cname, &clone_data, copy_for_gstate); if (pgs == NULL) @@ -1468,10 +1468,8 @@ gstate_free_contents(gs_gstate * pgs) if (pgs->client_data != 0) (*pgs->client_procs.free) (pgs->client_data, mem, pgs); pgs->client_data = 0; - gs_swapcolors_quick(pgs); - cs_adjust_counts_icc(pgs, -1); - gs_swapcolors_quick(pgs); cs_adjust_counts_icc(pgs, -1); + cs_adjust_swappedcounts_icc(pgs, -1); pgs->color[0].color_space = 0; pgs->color[1].color_space = 0; gs_free_object(mem, pgs->line_params.dash.pattern, cname); @@ -1503,9 +1501,7 @@ gstate_copy(gs_gstate * pto, const gs_gstate * pfrom, * Handle references from contents. */ cs_adjust_counts_icc(pto, -1); - gs_swapcolors_quick(pto); - cs_adjust_counts_icc(pto, -1); - gs_swapcolors_quick(pto); + cs_adjust_swappedcounts_icc(pto, -1); gx_path_assign_preserve(pto->path, pfrom->path); gx_cpath_assign_preserve(pto->clip_path, pfrom->clip_path); /* @@ -1556,9 +1552,7 @@ gstate_copy(gs_gstate * pto, const gs_gstate * pfrom, } GSTATE_ASSIGN_PARTS(pto, &parts); cs_adjust_counts_icc(pto, 1); - gs_swapcolors_quick(pto); - cs_adjust_counts_icc(pto, 1); - gs_swapcolors_quick(pto); + cs_adjust_swappedcounts_icc(pto, 1); pto->show_gstate = (pfrom->show_gstate == pfrom ? pto : 0); return 0; diff --git a/base/gsstate.h b/base/gsstate.h index b786dde4..7d9bde46 100644 --- a/base/gsstate.h +++ b/base/gsstate.h @@ -25,8 +25,8 @@ /* Initial allocation and freeing */ gs_gstate *gs_gstate_alloc(gs_memory_t *); /* 0 if fails */ -int gs_gstate_free(gs_gstate *); -int gs_gstate_free_chain(gs_gstate *); +void gs_gstate_free(gs_gstate *); +void gs_gstate_free_chain(gs_gstate *); /* Initialization, saving, restoring, and copying */ int gs_gsave(gs_gstate *), gs_grestore(gs_gstate *), gs_grestoreall(gs_gstate *); diff --git a/base/gstext.c b/base/gstext.c index e8373295..c4bf16a3 100644 --- a/base/gstext.c +++ b/base/gstext.c @@ -83,13 +83,13 @@ RELOC_PTRS_END static ENUM_PTRS_WITH(text_enum_enum_ptrs, gs_text_enum_t *eptr) { - if (index == 8) { + if (index == 6) { if (eptr->pair != 0) ENUM_RETURN(eptr->pair - eptr->pair->index); else ENUM_RETURN(0); } - index -= 9; + index -= 7; if (index <= eptr->fstack.depth) ENUM_RETURN(eptr->fstack.items[index].font); index -= eptr->fstack.depth + 1; @@ -97,8 +97,8 @@ static ENUM_PTRS_WITH(text_enum_enum_ptrs, gs_text_enum_t *eptr) } case 0: return ENUM_OBJ(gx_device_enum_ptr(eptr->dev)); case 1: return ENUM_OBJ(gx_device_enum_ptr(eptr->imaging_dev)); -ENUM_PTR3(2, gs_text_enum_t, pgs, orig_font, path); -ENUM_PTR3(5, gs_text_enum_t, pdcolor, pcpath, current_font); +ENUM_PTR2(2, gs_text_enum_t, pgs, orig_font); +ENUM_PTR2(4, gs_text_enum_t, pcpath, current_font); ENUM_PTRS_END static RELOC_PTRS_WITH(text_enum_reloc_ptrs, gs_text_enum_t *eptr) @@ -108,8 +108,8 @@ static RELOC_PTRS_WITH(text_enum_reloc_ptrs, gs_text_enum_t *eptr) RELOC_USING(st_gs_text_params, &eptr->text, sizeof(eptr->text)); eptr->dev = gx_device_reloc_ptr(eptr->dev, gcst); eptr->imaging_dev = gx_device_reloc_ptr(eptr->imaging_dev, gcst); - RELOC_PTR3(gs_text_enum_t, pgs, orig_font, path); - RELOC_PTR3(gs_text_enum_t, pdcolor, pcpath, current_font); + RELOC_PTR2(gs_text_enum_t, pgs, orig_font); + RELOC_PTR2(gs_text_enum_t, pcpath, current_font); if (eptr->pair != NULL) eptr->pair = (cached_fm_pair *)RELOC_OBJ(eptr->pair - eptr->pair->index) + eptr->pair->index; @@ -122,17 +122,12 @@ RELOC_PTRS_END int gx_device_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, - gx_path * path, /* unless DO_NONE & !RETURN_WIDTH */ - const gx_device_color * pdcolor, /* DO_DRAW */ const gx_clip_path * pcpath, /* DO_DRAW */ - gs_memory_t * mem, gs_text_enum_t ** ppte) + gs_text_enum_t ** ppte) { if (TEXT_PARAMS_ARE_INVALID(text)) return_error(gs_error_rangecheck); { - gx_path *tpath = - ((text->operation & TEXT_DO_NONE) && - !(text->operation & TEXT_RETURN_WIDTH) ? 0 : path); const gx_clip_path *tcpath = (text->operation & TEXT_DO_DRAW ? pcpath : 0); @@ -141,7 +136,7 @@ gx_device_text_begin(gx_device * dev, gs_gstate * pgs, Since the accumulation may happen while stringwidth. we pass the device color unconditionally. */ return dev_proc(dev, text_begin) - (dev, pgs, text, font, tpath, pdcolor, tcpath, mem, ppte); + (dev, pgs, text, font, tcpath, ppte); } } @@ -186,8 +181,8 @@ gs_text_enum_init_dynamic(gs_text_enum_t *pte, gs_font *font) int gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, gx_device *dev, gs_gstate *pgs, - const gs_text_params_t *text, gs_font *font, gx_path *path, - const gx_device_color *pdcolor, const gx_clip_path *pcpath, + const gs_text_params_t *text, gs_font *font, + const gx_clip_path *pcpath, gs_memory_t *mem) { int code; @@ -197,8 +192,6 @@ gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, pte->imaging_dev = NULL; pte->pgs = pgs; pte->orig_font = font; - pte->path = path; - pte->pdcolor = pdcolor; pte->pcpath = pcpath; pte->memory = mem; pte->procs = procs; @@ -406,9 +399,8 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, pgs->device->sgr.stroke_stored = false; code = gx_device_text_begin(pgs->device, pgs, - text, pgs->font, pgs->path, - gs_currentdevicecolor_inline(pgs), - pcpath, mem, ppte); + text, pgs->font, + pcpath, ppte); /* we need to know if we are doing a highlevel device. Also we need to know if we are doing any stroke @@ -438,18 +430,12 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, int gs_text_update_dev_color(gs_gstate * pgs, gs_text_enum_t * pte) { - /* - * The text enumerator holds a device color pointer, which may be a - * null pointer or a pointer to the same device color as the graphic - * state points to. In the former case the text is not to be - * rendered, and hence of no interest here. In the latter case the - * update of the graphic state color will update the text color as - * well. - */ /* Processing a text object operation */ ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ - if (pte->pdcolor != 0) { + if (pte->text.operation & TEXT_DO_DRAW) { + /* FIXME: It feels bad that we're setting the dev color in + * pgs, rather than pte->pgs. */ int code = gx_set_dev_color(pgs); if (code != 0) return code; diff --git a/base/gstext.h b/base/gstext.h index e8de9fea..630d16b8 100644 --- a/base/gstext.h +++ b/base/gstext.h @@ -159,10 +159,7 @@ typedef struct gs_text_enum_s gs_text_enum_t; gs_gstate *pgs,\ const gs_text_params_t *text,\ gs_font *font,\ - gx_path *path, /* unless DO_NONE */\ - const gx_device_color *pdcolor, /* if DO_DRAW */\ const gx_clip_path *pcpath, /* if DO_DRAW */\ - gs_memory_t *memory,\ gs_text_enum_t **ppte) #define dev_proc_text_begin(proc)\ dev_t_proc_text_begin(proc, gx_device) diff --git a/base/gstiffio.c b/base/gstiffio.c index 004f9feb..bb2ce85e 100644 --- a/base/gstiffio.c +++ b/base/gstiffio.c @@ -30,7 +30,6 @@ #include "gstiffio.h" - #define TIFF_PRINT_BUF_LENGTH 1024 static const char tifs_msg_truncated[] = "\n*** Previous line has been truncated.\n"; @@ -295,6 +294,8 @@ _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) #if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF) #include "gssprintf.h" +/* gets rid of compiler warning -- could include tiffiop.h, not sure which is better */ +int _TIFF_snprintf_f(char* buf, size_t size, const char* format, ...); int _TIFF_snprintf_f(char* buf, size_t size, const char* format, ...) { diff --git a/base/gstrans.c b/base/gstrans.c index cb201eba..d810524a 100644 --- a/base/gstrans.c +++ b/base/gstrans.c @@ -124,7 +124,7 @@ check_for_nontrans_pattern(gs_gstate *pgs, unsigned char *comp_name) /* * Push a PDF 1.4 transparency compositor onto the current device. Note that * if the current device already is a PDF 1.4 transparency compositor, the - * create_compositor will update its parameters but not create a new + * composite will update its parameters but not create a new * compositor device. */ static int @@ -207,7 +207,7 @@ gs_begin_transparency_group(gs_gstate *pgs, } /* * Put parameters into a compositor parameter and then call the - * create_compositor. This will pass the data to the PDF 1.4 + * composite. This will pass the data to the PDF 1.4 * transparency device. */ params.pdf14_op = group_type; @@ -810,6 +810,18 @@ gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain, if (depth < 0) params.overprint_sim_push = true; + /* If we have an NCLR ICC profile, the extra spot colorants do not + get included in the transparency buffers. This is also true + for any extra colorant names listed, which go beyond the profile. + Finally, we could have a CMYK profile with colorants listed, that + go beyond CMYK. To detect, simply look at dev_profile->spotnames */ + if (dev_profile->spotnames != NULL && dev_profile->spotnames->count > 4) { + /* Making an assumption here, that list is CMYK + extra. */ + int delta = dev_profile->spotnames->count - 4; + params.num_spot_colors_int -= delta; + params.num_spot_colors -= delta; + } + /* If we happen to be in a situation where we are going out to a device whose profile is CIELAB then we will need to make sure that we do our blending in RGB and convert to CIELAB when we do the put_image diff --git a/base/gstype42.c b/base/gstype42.c index dab1b52c..3cc92213 100644 --- a/base/gstype42.c +++ b/base/gstype42.c @@ -748,7 +748,9 @@ mac_glyph_ordering_t MacintoshOrdering[] = int gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gname) { - int code = 0; + /* READ_SFNTS() uses "code" in the macro, so we need code2 to keep track here */ + int code, code2 = gs_error_undefined; + if (pfont->FontType == ft_TrueType) { if (pfont->data.post_offset != 0) { byte ver[4]; @@ -760,6 +762,7 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam if (glyph > 257) glyph = 0; gname->data = (byte *)MacintoshOrdering[glyph].name; gname->size = strlen(MacintoshOrdering[glyph].name); + code2 = 0; } else if (!memcmp(ver, ver20, 4)) { byte val[2]; @@ -769,6 +772,7 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam if (gind < 258) { gname->data = (byte *)MacintoshOrdering[gind].name; gname->size = strlen(MacintoshOrdering[gind].name); + code2 = 0; } else { int i; @@ -784,8 +788,8 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam for (i = 0; i < numglyphs; i++) { if (i == gind) { READ_SFNTS(pfont, offs, 1, val); - code = pfont->data.string_proc(pfont, offs + 1, (uint)val[0], (const byte **)&(gname->data)); - if (code > 0) + code2 = pfont->data.string_proc(pfont, offs + 1, (uint)val[0], (const byte **)&(gname->data)); + if (code2 >= 0) gname->size = val[0]; break; } @@ -795,24 +799,14 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam } } } - else { - gname->data = (byte *)MacintoshOrdering[0].name; - gname->size = strlen(MacintoshOrdering[0].name); - } } } - else { - gname->data = (byte *)MacintoshOrdering[0].name; - gname->size = strlen(MacintoshOrdering[0].name); - } - } - else { - gname->data = (byte *)MacintoshOrdering[0].name; - gname->size = strlen(MacintoshOrdering[0].name); } } else - code = gs_note_error(gs_error_invalidfont); + code2 = gs_error_invalidfont; + + if (code2 < 0) code = gs_note_error(code2); return code; } diff --git a/base/gxacpath.c b/base/gxacpath.c index 36ff8c3f..8c3bf349 100644 --- a/base/gxacpath.c +++ b/base/gxacpath.c @@ -55,80 +55,24 @@ RELOC_PTRS_WITH(device_cpath_accum_reloc_ptrs, gx_device_cpath_accum *pdev) public_st_device_cpath_accum(); /* The device descriptor */ +static void +cpath_accum_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, accum_open_device); + set_dev_proc(dev, close_device, accum_close); + set_dev_proc(dev, fill_rectangle, accum_fill_rectangle); + set_dev_proc(dev, get_clipping_box, accum_get_clipping_box); + set_dev_proc(dev, get_color_mapping_procs, gx_default_DevGray_get_color_mapping_procs); + set_dev_proc(dev, dev_spec_op, accum_dev_spec_op); +} + + /* Many of these procedures won't be called; they are set to NULL. */ static const gx_device_cpath_accum gs_cpath_accum_device = -{std_device_std_body(gx_device_cpath_accum, 0, "clip list accumulator", - 0, 0, 1, 1), - {accum_open_device, - NULL, - NULL, - NULL, - accum_close, - NULL, - NULL, - accum_fill_rectangle, - NULL, - gx_default_copy_mono, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - gx_default_fill_path, - gx_default_stroke_path, - gx_default_fill_mask, - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - NULL, - NULL, - accum_get_clipping_box, - gx_default_begin_typed_image, - NULL, - NULL, - NULL, - NULL, - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - gx_default_DevGray_get_color_mapping_procs, - NULL, /* get_color_comp_index */ - NULL, /* encode_color */ - NULL, /* decode_color */ - NULL, /* pattern_manage */ - NULL, /* fill_rectangle_hl_color */ - NULL, /* ics */ - NULL, /* fill_lin_tri */ - NULL, /* fill_lin_tri */ - NULL, /* fill_lin_tri */ - NULL, /* up_spot_eq_col */ - NULL, /* ret_dev */ - NULL, /* fillpage */ - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - accum_dev_spec_op, - NULL, /* copy_planes */ - NULL, /* get_profile */ - gx_default_set_graphics_type_tag - } +{std_device_std_body(gx_device_cpath_accum, + cpath_accum_initialize_device_procs, + "clip list accumulator", + 0, 0, 1, 1) }; /* Start accumulating a clipping path. */ diff --git a/base/gxalpha.h b/base/gxalpha.h index 4134d857..6403ca4e 100644 --- a/base/gxalpha.h +++ b/base/gxalpha.h @@ -35,7 +35,6 @@ * are the following: * - alphaimage, if it doesn't assume premultiplication (see below) * - readimage - * - The cmap_rgb_alpha_ procedures in gxcmap.c * - [color]image, if they are supposed to use currentalpha (see below) * - The compositing code in gsalphac.c * diff --git a/base/gxblend.c b/base/gxblend.c index a7c22332..b2e61a42 100644 --- a/base/gxblend.c +++ b/base/gxblend.c @@ -5242,7 +5242,7 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, fn = mark_fill_rect_add_nospots_common; } else fn = mark_fill_rect_add_nospots; - } else if (!additive && num_spots == 0 && num_comp == 4 && num_spots == 0 && + } else if (!additive && num_spots == 0 && num_comp == 4 && first_blend_spot == 0 && blend_mode == BLEND_MODE_Normal && !overprint && tag_off == 0 && alpha_g_off == 0 && shape_off == 0) fn = mark_fill_rect_sub4_fast; diff --git a/base/gxblend.h b/base/gxblend.h index a1f62e18..276bf8dd 100644 --- a/base/gxblend.h +++ b/base/gxblend.h @@ -367,20 +367,20 @@ gx_color_index pdf14_encode_color16_tag(gx_device *dev, const gx_color_value col int pdf14_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out); int pdf14_decode_color16(gx_device * dev, gx_color_index color, gx_color_value * out); -void pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]); -void pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, +void pdf14_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[]); +void pdf14_rgb_cs_to_cmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); -void pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); +void pdf14_cmyk_cs_to_cmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); -void pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]); -void pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs, +void pdf14_gray_cs_to_rgbspot_cm(const gx_device * dev, frac gray, frac out[]); +void pdf14_rgb_cs_to_rgbspot_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); -void pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); +void pdf14_cmyk_cs_to_rgbspot_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); -void pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]); -void pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs, +void pdf14_gray_cs_to_grayspot_cm(const gx_device * dev, frac gray, frac out[]); +void pdf14_rgb_cs_to_grayspot_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); -void pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); +void pdf14_cmyk_cs_to_grayspot_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); void gx_build_blended_image_row(const byte *gs_restrict buf_ptr, int planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf); diff --git a/base/gxblend1.c b/base/gxblend1.c index c4f14e6c..3f8842a9 100644 --- a/base/gxblend1.c +++ b/base/gxblend1.c @@ -201,9 +201,9 @@ copy_extra_planes(byte *des_buf, pdf14_buf *des_info, byte *src_buf, pdf14_buf *src_info, int width, int height) { /* alpha_g and shape do not copy */ - des_buf += des_info->planestride * ((des_info->has_shape ? 1 : 0) + + des_buf += des_info->planestride * (size_t)((des_info->has_shape ? 1 : 0) + (des_info->has_alpha_g ? 1 : 0)); - src_buf += src_info->planestride * ((src_info->has_shape ? 1 : 0) + + src_buf += src_info->planestride * (size_t)((src_info->has_shape ? 1 : 0) + (src_info->has_alpha_g ? 1 : 0)); /* tags plane does copy */ if (des_info->has_tags) { @@ -261,20 +261,20 @@ pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, } else { if (knockout_buff) { buf_plane = buf->backdrop + ((x0 - buf->rect.p.x)<<deep) + - (y0 - buf->rect.p.y) * buf->rowstride; + (y0 - buf->rect.p.y) * (size_t)buf->rowstride; tos_plane = tos->backdrop + ((x0 - tos->rect.p.x)<<deep) + - (y0 - tos->rect.p.y) * tos->rowstride; - memset(buf->backdrop, 0, buf->n_chan * buf->planestride<<deep); + (y0 - tos->rect.p.y) * (size_t)tos->rowstride; + memset(buf->backdrop, 0, buf->n_chan * ((size_t)buf->planestride)<<deep); } else { buf_plane = buf->data + ((x0 - buf->rect.p.x)<<deep) + - (y0 - buf->rect.p.y) * buf->rowstride; + (y0 - buf->rect.p.y) * (size_t)buf->rowstride; tos_plane = tos->data + ((x0 - tos->rect.p.x)<<deep) + - (y0 - tos->rect.p.y) * tos->rowstride; + (y0 - tos->rect.p.y) * (size_t)tos->rowstride; /* First clear out everything. There are cases where the incoming buf has a region outside the existing tos group. Need to check if this is getting clipped in which case we need to fix the allocation of the buffer to be smaller */ - memset(buf->data, 0, buf->n_planes * buf->planestride<<deep); + memset(buf->data, 0, buf->n_planes * ((size_t)buf->planestride)<<deep); } /* Set up the buffer descriptors. */ gsicc_init_buffer(&input_buff_desc, tos_profile->num_comps, 1<<deep, false, @@ -291,8 +291,8 @@ pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, return gs_throw(gs_error_unknownerror, "ICC transform failed. Trans backdrop"); } /* Copy the alpha data */ - buf_plane += buf->planestride * (buf->n_chan - 1); - tos_plane += tos->planestride * (tos->n_chan - 1); + buf_plane += (buf->planestride) * (size_t)(buf->n_chan - 1); + tos_plane += (tos->planestride) * (size_t)(tos->n_chan - 1); copy_plane_part(buf_plane, buf->rowstride, tos_plane, tos->rowstride, width, height, deep); buf_plane += buf->planestride; @@ -304,7 +304,7 @@ pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, #if RAW_DUMP if (x0 < x1 && y0 < y1) { byte *buf_plane = buf->data + ((x0 - buf->rect.p.x)<<deep) + - (y0 - buf->rect.p.y) * buf->rowstride; + (y0 - buf->rect.p.y) * (size_t)buf->rowstride; dump_raw_buffer(dev->memory, y1 - y0, x1 - x0, buf->n_planes, buf->planestride, buf->rowstride, "BackDropInit_CM", buf_plane, deep); global_index++; @@ -349,7 +349,7 @@ pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool from_backdrop y0 > buf->rect.p.y || y1 < buf->rect.q.y) { /* FIXME: There is potential for more optimisation here, * but I don't know how often we hit this case. */ - memset(buf_plane, 0, (size_t)n_planes * buf->planestride); + memset(buf_plane, 0, n_planes * (size_t)buf->planestride); } else if (n_planes > tos->n_chan) { /* The next planes are alpha_g, shape, tags. We need to clear * alpha_g and shape, but don't need to clear the tag plane @@ -358,12 +358,12 @@ pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool from_backdrop if (!from_backdrop && n_planes > tag_plane_num) n_planes = tag_plane_num; if (n_planes > tos->n_chan) - memset(buf->data + (size_t)tos->n_chan * buf->planestride, 0, - (size_t)(n_planes - tos->n_chan) * buf->planestride); + memset(buf->data + tos->n_chan * (size_t)buf->planestride, 0, + (n_planes - tos->n_chan) * (size_t)buf->planestride); } - buf_plane += (y0 - buf->rect.p.y) * buf->rowstride + + buf_plane += (y0 - buf->rect.p.y) * (size_t)buf->rowstride + ((x0 - buf->rect.p.x)<<deep); - tos_plane += (y0 - tos->rect.p.y) * tos->rowstride + + tos_plane += (y0 - tos->rect.p.y) * (size_t)tos->rowstride + ((x0 - tos->rect.p.x)<<deep); /* Color and alpha plane */ for (i = 0; i < tos->n_chan; i++) { @@ -380,7 +380,7 @@ pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool from_backdrop byte *buf_plane = (from_backdrop ? buf->backdrop : buf->data); if (buf_plane != NULL) { buf_plane += ((x0 - buf->rect.p.x) << buf->deep) + - (y0 - buf->rect.p.y) * buf->rowstride; + (y0 - buf->rect.p.y) * (size_t)buf->rowstride; dump_raw_buffer(mem, y1 - y0, x1 - x0, buf->n_planes, buf->planestride, buf->rowstride, "BackDropInit", buf_plane, buf->deep); global_index++; @@ -494,7 +494,7 @@ pdf14_decode_color16(gx_device * dev, gx_color_index color, gx_color_value * out } void -pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) +pdf14_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -506,7 +506,7 @@ pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) /* These three must handle rgb + spot */ void -pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]) +pdf14_gray_cs_to_rgbspot_cm(const gx_device * dev, frac gray, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -516,7 +516,7 @@ pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]) } void -pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs, +pdf14_rgb_cs_to_rgbspot_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -529,7 +529,7 @@ pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs, } void -pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +pdf14_cmyk_cs_to_rgbspot_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -540,7 +540,7 @@ pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, fra /* These three must handle gray + spot */ void -pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]) +pdf14_gray_cs_to_grayspot_cm(const gx_device * dev, frac gray, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -550,7 +550,7 @@ pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]) } void -pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs, +pdf14_rgb_cs_to_grayspot_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -561,7 +561,7 @@ pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs, } void -pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +pdf14_cmyk_cs_to_grayspot_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -586,7 +586,7 @@ pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, fr * often they are { pop 0 }. */ void -pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, +pdf14_rgb_cs_to_cmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -607,7 +607,7 @@ pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, } void -pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +pdf14_cmyk_cs_to_cmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { uchar num_comp = dev->color_info.num_components; @@ -624,14 +624,14 @@ pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac o static int dump_planar_rgba(gs_memory_t *mem, const pdf14_buf *pbuf) { - int rowstride = pbuf->rowstride, planestride = pbuf->planestride; + size_t rowstride = pbuf->rowstride, planestride = pbuf->planestride; int rowbytes = width << 2; gs_int_rect rect = buf->rect; int x1 = min(pdev->width, rect.q.x); int y1 = min(pdev->height, rect.q.y); int width = x1 - rect.p.x; int height = y1 - rect.p.y; - byte *buf_ptr = buf->data + rect.p.y * buf->rowstride + rect.p.x; + byte *buf_ptr = buf->data + rect.p.y * (size_t)buf->rowstride + rect.p.x; byte *row = gs_malloc(mem, rowbytes, 1, "png raster buffer"); png_struct *png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -705,8 +705,8 @@ dump_planar_rgba(gs_memory_t *mem, const pdf14_buf *pbuf) for (x = 0; x < width; ++x) { row[(x << 2)] = buf_ptr[x]; row[(x << 2) + 1] = buf_ptr[x + planestride]; - row[(x << 2) + 2] = buf_ptr[x + planestride * 2]; - row[(x << 2) + 3] = buf_ptr[x + planestride * 3]; + row[(x << 2) + 2] = buf_ptr[x + planestride * (size_t)2]; + row[(x << 2) + 3] = buf_ptr[x + planestride * (size_t)3]; } png_write_row(png_ptr, row); buf_ptr += rowstride; @@ -729,7 +729,7 @@ void gx_build_blended_image_row(const byte *gs_restrict buf_ptr, int planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf) { - int inc = planestride * num_comp; + size_t inc = planestride * (size_t)num_comp; buf_ptr += inc - 1; for (; width > 0; width--) { @@ -767,12 +767,12 @@ gx_build_blended_image_row16(const byte *gs_restrict buf_ptr_, int planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf) { const uint16_t *gs_restrict buf_ptr = (const uint16_t *)(const void *)buf_ptr_; - int inc; + size_t inc; /* Note that we read in in native endian and blend, * then store out in big endian. */ planestride >>= 1; /* Array indexing, not byte indexing */ - inc = planestride * num_comp; + inc = planestride * (size_t)num_comp; buf_ptr += inc - 1; for (; width > 0; width--) { /* composite RGBA (or CMYKA, etc.) pixel with over solid background */ @@ -822,18 +822,18 @@ gx_blend_image_buffer(byte *buf_ptr, int width, int height, int rowstride, position = y * rowstride; for (x = 0; x < width; x++) { /* composite RGBA (or CMYKA, etc.) pixel with over solid background */ - a = buf_ptr[position + planestride * num_comp]; + a = buf_ptr[position + planestride * (size_t)num_comp]; if ((a + 1) & 0xfe) { a ^= 0xff; for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[position + planestride * comp_num]; + comp = buf_ptr[position + planestride * (size_t)comp_num]; tmp = ((bg - comp) * a) + 0x80; comp += (tmp + (tmp >> 8)) >> 8; - buf_ptr[position + planestride * comp_num] = comp; + buf_ptr[position + planestride * (size_t)comp_num] = comp; } } else if (a == 0) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - buf_ptr[position + planestride * comp_num] = bg; + buf_ptr[position + planestride * (size_t)comp_num] = bg; } } position+=1; @@ -865,19 +865,19 @@ gx_blend_image_buffer16(byte *buf_ptr_, int width, int height, int rowstride, position = y * rowstride; for (x = 0; x < width; x++) { /* composite RGBA (or CMYKA, etc.) pixel with over solid background */ - a = buf_ptr[position + planestride * num_comp]; + a = buf_ptr[position + planestride * (size_t)num_comp]; if (a == 0) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - buf_ptr[position + planestride * comp_num] = bebg; + buf_ptr[position + planestride * (size_t)comp_num] = bebg; } } else if (a == 0xffff) { #if ARCH_IS_BIG_ENDIAN #else if (!keep_native) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[position + planestride * comp_num]; - ((byte *)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8; - ((byte *)&buf_ptr[position + planestride * comp_num])[1] = comp; + comp = buf_ptr[position + planestride * (size_t)comp_num]; + ((byte *)&buf_ptr[position + planestride * (size_t)comp_num])[0] = comp >> 8; + ((byte *)&buf_ptr[position + planestride * (size_t)comp_num])[1] = comp; } } #endif @@ -886,12 +886,12 @@ gx_blend_image_buffer16(byte *buf_ptr_, int width, int height, int rowstride, a += a>>15; /* a is now 0 to 0x10000 */ a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */ for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[position + planestride * comp_num]; + comp = buf_ptr[position + planestride * (size_t)comp_num]; tmp = (((int)bg - comp) * a) + 0x4000; comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */ /* Store as big endian */ - ((byte *)&buf_ptr[position + planestride * comp_num])[0] = comp>>8; - ((byte *)&buf_ptr[position + planestride * comp_num])[1] = comp; + ((byte *)&buf_ptr[position + planestride * (size_t)comp_num])[0] = comp>>8; + ((byte *)&buf_ptr[position + planestride * (size_t)comp_num])[1] = comp; } } position+=1; @@ -913,26 +913,26 @@ gx_blend_image_buffer8to16(const byte *buf_ptr_in, unsigned short *buf_ptr_out, position = y * rowstride; for (x = 0; x < width; x++) { /* composite RGBA (or CMYKA, etc.) pixel with over solid background */ - a = buf_ptr_in[position + planestride * num_comp]; + a = buf_ptr_in[position + planestride * (size_t)num_comp]; if (a == 0xff) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr_in[position + planestride * comp_num]; - buf_ptr_out[position + planestride * comp_num] = (comp + (comp << 8)); + comp = buf_ptr_in[position + planestride * (size_t)comp_num]; + buf_ptr_out[position + planestride * (size_t)comp_num] = (comp + (comp << 8)); } } else if (a == 0) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - buf_ptr_out[position + planestride * comp_num] = bg_out; + buf_ptr_out[position + planestride * (size_t)comp_num] = bg_out; } } else { a ^= 0xff; a += (a << 8); for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr_in[position + planestride * comp_num]; + comp = buf_ptr_in[position + planestride * (size_t)comp_num]; comp += (comp << 8); tmp = ((bg_out - comp) * a) + 0x8000; comp += (tmp + (tmp >> 16)) >> 16; comp = ((comp & 0xff) << 8) + ((comp & 0xff00) >> 8); - buf_ptr_out[position + planestride * comp_num] = comp; + buf_ptr_out[position + planestride * (size_t)comp_num] = comp; } } position += 1; @@ -960,7 +960,7 @@ gx_put_blended_image_custom(gx_device *target, byte *buf_ptr_, /* composite CMYKA, etc. pixel with over solid background */ #define GET16(v) (*((uint16_t *)(void *)&(v))) - uint16_t a = GET16(buf_ptr[x + planestride * num_comp]); + uint16_t a = GET16(buf_ptr[x + planestride * (size_t)num_comp]); if (a == 0) { for (comp_num = 0; comp_num < num_comp; comp_num++) { @@ -968,13 +968,13 @@ gx_put_blended_image_custom(gx_device *target, byte *buf_ptr_, } } else if (a == 0xffff) { for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[x + planestride * comp_num]; + comp = buf_ptr[x + planestride * (size_t)comp_num]; cv[comp_num] = comp; } } else { a ^= 0xffff; for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = GET16(buf_ptr[x + planestride * comp_num]); + comp = GET16(buf_ptr[x + planestride * (size_t)comp_num]); tmp = ((bg - comp) * a) + 0x8000; cv[comp_num] = comp + ((tmp + (tmp>>16))>>16); } @@ -994,12 +994,12 @@ gx_put_blended_image_custom(gx_device *target, byte *buf_ptr_, for (x = 0; x < width; x++) { /* composite CMYKA, etc. pixel with over solid background */ - byte a = buf_ptr[x + planestride * num_comp]; + byte a = buf_ptr[x + planestride * (size_t)num_comp]; if ((a + 1) & 0xfe) { a ^= 0xff; for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[x + planestride * comp_num]; + comp = buf_ptr[x + planestride * (size_t)comp_num]; tmp = ((bg - comp) * a) + 0x80; comp += tmp + (tmp >> 8); cv[comp_num] = comp; @@ -1010,7 +1010,7 @@ gx_put_blended_image_custom(gx_device *target, byte *buf_ptr_, } } else { for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[x + planestride * comp_num]; + comp = buf_ptr[x + planestride * (size_t)comp_num]; cv[comp_num] = (comp << 8) + comp; } } @@ -1025,4 +1025,4 @@ gx_put_blended_image_custom(gx_device *target, byte *buf_ptr_, } } return code; -}
\ No newline at end of file +} diff --git a/base/gxccman.c b/base/gxccman.c index b31b6959..869fccdc 100644 --- a/base/gxccman.c +++ b/base/gxccman.c @@ -442,11 +442,12 @@ gs_purge_fm_pair(gs_font_dir * dir, cached_fm_pair * pair, int xfont_only) pair->num_chars); } #endif - { /* Free xvalues here because gx_add_fm_pair copied - them into the stable memory dir->memory. */ + if (uid_is_XUID(&pair->UID)) { gs_free_object(dir->memory->stable_memory, pair->UID.xvalues, "gs_purge_fm_pair"); - pair->UID.xvalues = 0; + pair->UID.id = 0; + pair->UID.xvalues = NULL; } + fm_pair_set_free(pair); code = fm_pair_remove_from_list(dir, pair, &dir->fmcache.used); if (code < 0) @@ -549,7 +550,6 @@ gx_alloc_char_bits(gs_font_dir * dir, gx_device_memory * dev, * as the conditions set up in gx_compute_text_oversampling * preclude this function ever being called in a way that * will cause this else clause to be executed. */ -#ifndef ENABLE_IMPOSSIBLE_ALPHA_CODE static int THIS_NEVER_HAPPENS = 0; if (THIS_NEVER_HAPPENS == 0) { @@ -560,28 +560,6 @@ gx_alloc_char_bits(gs_font_dir * dir, gx_device_memory * dev, THIS_NEVER_HAPPENS = 1; } return_error(gs_error_unknownerror); -#else /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ - /* Use an alpha-buffer device to compress as we go. */ - /* Preserve the reference counts, if any. */ - rc_header rc; - - rc = dev2->rc; - gs_make_mem_alpha_device(dev2, dev2->memory, NULL, depth); - dev2->rc = rc; - dev2->width = iwidth >> log2_xscale; - dev2->height = iheight >> log2_yscale; - rc = dev->rc; - gs_make_mem_abuf_device(dev, dev->memory, (gx_device *) dev2, - pscale, depth, 0, false); - dev->rc = rc; - dev->width = iwidth; - dev->height = 2 << log2_yscale; - gdev_mem_bitmap_size(dev, &isize); /* Assume less than max_ulong */ - gdev_mem_bitmap_size(dev2, &isize2); /* Assume less than max_ulong */ - isize += isize2; /* Assume less than max_ulong */ - dev->HWResolution[0] = HWResolution0 * (1 >> log2_xscale); - dev->HWResolution[1] = HWResolution1 * (1 >> log2_yscale); -#endif /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ } icdsize = isize + sizeof_cached_char; code = alloc_char(dir, icdsize, &cc); diff --git a/base/gxchar.c b/base/gxchar.c index 2332b70a..7704c91b 100644 --- a/base/gxchar.c +++ b/base/gxchar.c @@ -120,21 +120,21 @@ static const gs_text_enum_procs_t default_text_procs = { int gx_default_text_begin(gx_device * dev, gs_gstate * pgs1, const gs_text_params_t * text, gs_font * font, - gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, - gs_memory_t * mem, gs_text_enum_t ** ppte) + gs_text_enum_t ** ppte) { uint operation = text->operation; bool propagate_charpath = (operation & TEXT_DO_DRAW) != 0; int code; gs_gstate *pgs = (gs_gstate *)pgs1; gs_show_enum *penum; + gs_memory_t * mem = pgs->memory; penum = gs_show_enum_alloc(mem, pgs, "gx_default_text_begin"); if (!penum) return_error(gs_error_VMerror); code = gs_text_enum_init((gs_text_enum_t *)penum, &default_text_procs, - dev, pgs, text, font, path, pdcolor, pcpath, mem); + dev, pgs, text, font, pcpath, mem); if (code < 0) { gs_free_object(mem, penum, "gx_default_text_begin"); return code; @@ -210,7 +210,7 @@ gs_text_count_chars(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem) code = gs_text_enum_init(&tenum, &default_text_procs, NULL, NULL, text, pgs->root_font, - NULL, NULL, NULL, mem); + NULL, mem); if (code < 0) return code; while ((code = (*next_proc)(&tenum, &tchr, &tglyph)) != 2) { diff --git a/base/gxcht.c b/base/gxcht.c index dc1064a1..ed9868d3 100644 --- a/base/gxcht.c +++ b/base/gxcht.c @@ -85,7 +85,6 @@ gx_dc_ht_colored_save_dc(const gx_device_color * pdevc, memcpy( psdc->colors.colored.c_level, pdevc->colors.colored.c_level, sizeof(psdc->colors.colored.c_base) ); - psdc->colors.colored.alpha = pdevc->colors.colored.alpha; psdc->phase = pdevc->phase; } @@ -105,7 +104,6 @@ gx_dc_ht_colored_equal(const gx_device_color * pdevc1, if (pdevc2->type != pdevc1->type || pdevc1->colors.colored.c_ht != pdevc2->colors.colored.c_ht || - pdevc1->colors.colored.alpha != pdevc2->colors.colored.alpha || pdevc1->phase.x != pdevc2->phase.x || pdevc1->phase.y != pdevc2->phase.y || num_comp != pdevc2->colors.colored.num_components @@ -133,8 +131,6 @@ gx_dc_ht_colored_equal(const gx_device_color * pdevc1, */ static const int dc_ht_colored_has_base = 0x01; static const int dc_ht_colored_has_level = 0x02; -static const int dc_ht_colored_has_alpha = 0x04; -static const int dc_ht_colored_alpha_is_max = 0x08; /* * Serialize a device color that uses a traditional colored halftone. @@ -196,7 +192,6 @@ gx_dc_ht_colored_write( int num_comps = dev->color_info.num_components; int depth = dev->color_info.depth; gx_color_index plane_mask = pdevc->colors.colored.plane_mask; - gx_color_value alpha = pdevc->colors.colored.alpha; const gx_device_color_saved * psdc = psdc0; byte * pdata0 = pdata; @@ -248,15 +243,6 @@ gx_dc_ht_colored_write( } } - if (psdc == 0 || alpha != psdc->colors.colored.alpha) { - if (alpha == gx_max_color_value) - flag_bits |= dc_ht_colored_alpha_is_max; - else { - flag_bits |= dc_ht_colored_has_alpha; - req_size += enc_u_sizew(alpha); - } - } - /* see if there is anything to do */ if (flag_bits == 0) { *psize = 0; @@ -313,9 +299,6 @@ gx_dc_ht_colored_write( } } - if ((flag_bits & dc_ht_colored_has_alpha) != 0) - enc_u_putw(alpha, pdata); - *psize = pdata - pdata0; return 0; } @@ -379,7 +362,7 @@ gx_dc_ht_colored_read( /* the number of components is determined by the color model */ devc.colors.colored.num_components = num_comps; - devc.colors.colored.c_ht = pgs->dev_ht; + devc.colors.colored.c_ht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* * Verify that we have at least the flag bits. For performance @@ -447,23 +430,12 @@ gx_dc_ht_colored_read( size -= pdata - pdata_start; } - if ((flag_bits & dc_ht_colored_alpha_is_max) != 0) - devc.colors.colored.alpha = gx_max_color_value; - else if ((flag_bits & dc_ht_colored_has_alpha) != 0) { - const byte * pdata_start = pdata; - - if (size < 1) - return_error(gs_error_rangecheck); - enc_u_getw(devc.colors.colored.alpha, pdata); - size -= pdata - pdata_start; - } - /* set the phase as required (select value is arbitrary) */ color_set_phase_mod( &devc, pgs->screen_phase[0].x, pgs->screen_phase[0].y, - pgs->dev_ht->lcm_width, - pgs->dev_ht->lcm_height ); + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width, + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height ); /* everything looks OK */ *pdevc = devc; @@ -671,8 +643,8 @@ gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc, /* * If the LCM of the plane cell sizes is smaller than the rectangle - * being filled, compute a single tile and let tile_rectangle do the - * replication. + * being filled, compute a single tile and let strip_tile_rectangle + * do the replication. */ if ((w > lw || h > lh) && (raster = bitmap_raster(lw * depth)) <= tile_bytes / lh @@ -703,18 +675,7 @@ gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc, gx_no_color_index, pdevc->phase.x, pdevc->phase.y); - if (source->planar_height == 0) - return (*dev_proc(dev, strip_copy_rop)) - (dev, - source->sdata + (y - origy) * source->sraster, - source->sourcex + (x - origx), - source->sraster, source->id, - (source->use_scolors ? source->scolors : NULL), - &tiles, NULL, - x, y, w, h, - pdevc->phase.x, pdevc->phase.y, lop); - else - return (*dev_proc(dev, strip_copy_rop2)) + return (*dev_proc(dev, strip_copy_rop2)) (dev, source->sdata + (y - origy) * source->sraster, source->sourcex + (x - origx), @@ -779,16 +740,7 @@ fit: /* Now the tile will definitely fit. */ x, cy, dw, ch); } else { tiles.rep_height = tiles.size.y = ch; - if (source->planar_height == 0) - code = (*dev_proc(dev, strip_copy_rop)) - (dev, source->sdata + source->sraster * (cy-origy), - source->sourcex + (x - origx), - source->sraster, - source->id, - (source->use_scolors ? source->scolors : NULL), - &tiles, NULL, x, cy, dw, ch, 0, 0, lop); - else - code = (*dev_proc(dev, strip_copy_rop2)) + code = (*dev_proc(dev, strip_copy_rop2)) (dev, source->sdata + source->sraster * (cy-origy), source->sourcex + (x - origx), source->sraster, @@ -891,9 +843,6 @@ set_ht_colors_le_4(color_values_pair_t *pvp /* only used internally */, set_plane_color(2, pvp, pdc, sbits, caches, max_color, invert); } if (nplanes == 3) { - gx_color_value alpha = pdc->colors.colored.alpha; - - if (alpha == gx_max_color_value) { #define M(i)\ cvalues[0] = pvp->values[(i) & 1][0];\ cvalues[1] = pvp->values[((i) & 2) >> 1][1];\ @@ -902,14 +851,6 @@ set_ht_colors_le_4(color_values_pair_t *pvp /* only used internally */, M(0); M(1); M(2); M(3); M(4); M(5); M(6); M(7); #undef M - } else { -#define M(i)\ - colors[i] = dev_proc(dev, map_rgb_alpha_color)(dev, pvp->values[(i) & 1][0],\ - pvp->values[((i) & 2) >> 1][1],\ - pvp->values[(i) >> 2][2], alpha) - M(0); M(1); M(2); M(3); M(4); M(5); M(6); M(7); -#undef M - } } else if (nplanes > 3){ set_plane_color(3, pvp, pdc, sbits, caches, max_color, invert); if (nplanes > 4) { diff --git a/base/gxcldev.h b/base/gxcldev.h index 290c6cda..012c5bf6 100644 --- a/base/gxcldev.h +++ b/base/gxcldev.h @@ -316,7 +316,6 @@ dev_proc_copy_color(clist_copy_color); dev_proc_copy_alpha(clist_copy_alpha); dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle); dev_proc_strip_tile_rect_devn(clist_strip_tile_rect_devn); -dev_proc_strip_copy_rop(clist_strip_copy_rop); dev_proc_strip_copy_rop2(clist_strip_copy_rop2); dev_proc_fill_trapezoid(clist_fill_trapezoid); dev_proc_fill_linear_color_trapezoid(clist_fill_linear_color_trapezoid); @@ -330,7 +329,7 @@ dev_proc_process_page(clist_process_page); /* In gxclimag.c */ dev_proc_fill_mask(clist_fill_mask); dev_proc_begin_typed_image(clist_begin_typed_image); -dev_proc_create_compositor(clist_create_compositor); +dev_proc_composite(clist_composite); /* In gxclread.c */ dev_proc_get_bits_rectangle(clist_get_bits_rectangle); diff --git a/base/gxclimag.c b/base/gxclimag.c index d638bea6..3958e372 100644 --- a/base/gxclimag.c +++ b/base/gxclimag.c @@ -1287,7 +1287,7 @@ clist_image_end_image(gx_image_enum_common_t * info, bool draw_last) /* Create a compositor device. */ int -clist_create_compositor(gx_device * dev, +clist_composite(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, gs_gstate * pgs, gs_memory_t * mem, gx_device *cldev) { @@ -1375,7 +1375,7 @@ clist_create_compositor(gx_device * dev, return code; /* insert the command and compositor identifier */ - dp[1] = cmd_opv_ext_create_compositor; + dp[1] = cmd_opv_ext_composite; dp[2] = pcte->type->comp_id; /* serialize the remainder of the compositor */ @@ -1416,7 +1416,7 @@ clist_create_compositor(gx_device * dev, code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_extend, size); if (code >= 0) { size_dummy = size; - dp[1] = cmd_opv_ext_create_compositor; + dp[1] = cmd_opv_ext_composite; dp[2] = pcte->type->comp_id; code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev); } @@ -1585,7 +1585,7 @@ cmd_put_color_mapping(gx_device_clist_writer * cldev, const gs_gstate * pgs) { int code; - const gx_device_halftone *pdht = pgs->dev_ht; + const gx_device_halftone *pdht = gx_select_dev_ht(pgs); /* Put out the halftone, if present. */ if (pdht && pdht->id != cldev->device_halftone_id) { diff --git a/base/gxclip.c b/base/gxclip.c index 0b7939ef..3cad4695 100644 --- a/base/gxclip.c +++ b/base/gxclip.c @@ -41,7 +41,6 @@ static dev_proc_copy_alpha_hl_color(clip_copy_alpha_hl_color); static dev_proc_fill_mask(clip_fill_mask); static dev_proc_strip_tile_rectangle(clip_strip_tile_rectangle); static dev_proc_strip_tile_rect_devn(clip_strip_tile_rect_devn); -static dev_proc_strip_copy_rop(clip_strip_copy_rop); static dev_proc_strip_copy_rop2(clip_strip_copy_rop2); static dev_proc_get_clipping_box(clip_get_clipping_box); static dev_proc_get_bits_rectangle(clip_get_bits_rectangle); @@ -50,85 +49,68 @@ static dev_proc_transform_pixel_region(clip_transform_pixel_region); static dev_proc_fill_stroke_path(clip_fill_stroke_path); /* The device descriptor. */ +static void +clipper_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, clip_open); + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, clip_fill_rectangle); + set_dev_proc(dev, copy_mono, clip_copy_mono); + set_dev_proc(dev, copy_color, clip_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, gx_forward_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + set_dev_proc(dev, copy_alpha, clip_copy_alpha); + set_dev_proc(dev, fill_path, clip_fill_path); + set_dev_proc(dev, fill_mask, clip_fill_mask); + set_dev_proc(dev, strip_tile_rectangle, clip_strip_tile_rectangle); + set_dev_proc(dev, get_clipping_box, clip_get_clipping_box); + set_dev_proc(dev, get_bits_rectangle, clip_get_bits_rectangle); + set_dev_proc(dev, composite, gx_forward_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_forward_encode_color); + set_dev_proc(dev, decode_color, gx_forward_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, clip_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, gx_forward_include_color_space); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); + set_dev_proc(dev, copy_planes, clip_copy_planes); + set_dev_proc(dev, get_profile, gx_forward_get_profile); + set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dev, strip_copy_rop2, clip_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, clip_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, clip_copy_alpha_hl_color); + set_dev_proc(dev, transform_pixel_region, clip_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, clip_fill_stroke_path); + /* Ideally the following defaults would be filled in for us, but that + * doesn't work at the moment. */ + set_dev_proc(dev, sync_output, gx_default_sync_output); + set_dev_proc(dev, output_page, gx_default_output_page); + set_dev_proc(dev, close_device, gx_default_close_device); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, stroke_path, gx_default_stroke_path); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, text_begin, gx_default_text_begin); + set_dev_proc(dev, fill_linear_color_scanline, gx_default_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, gx_default_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, gx_default_fill_linear_color_triangle); +} static const gx_device_clip gs_clip_device = -{std_device_std_body(gx_device_clip, 0, "clipper", - 0, 0, 1, 1), - {clip_open, - gx_forward_get_initial_matrix, - gx_default_sync_output, - gx_default_output_page, - gx_default_close_device, - gx_forward_map_rgb_color, - gx_forward_map_color_rgb, - clip_fill_rectangle, - gx_default_tile_rectangle, - clip_copy_mono, - clip_copy_color, - gx_default_draw_line, - gx_default_get_bits, - gx_forward_get_params, - gx_forward_put_params, - gx_forward_map_cmyk_color, - gx_forward_get_xfont_procs, - gx_forward_get_xfont_device, - gx_forward_map_rgb_alpha_color, - gx_forward_get_page_device, - gx_forward_get_alpha_bits, - clip_copy_alpha, - gx_forward_get_band, - gx_default_copy_rop, - clip_fill_path, - gx_default_stroke_path, - clip_fill_mask, - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - clip_strip_tile_rectangle, - clip_strip_copy_rop, - clip_get_clipping_box, - gx_default_begin_typed_image, - clip_get_bits_rectangle, - gx_forward_map_color_rgb_alpha, - gx_forward_create_compositor, - gx_forward_get_hardware_params, - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color, - NULL, - clip_fill_rectangle_hl_color, - gx_forward_include_color_space, - gx_default_fill_linear_color_scanline, - gx_default_fill_linear_color_trapezoid, - gx_default_fill_linear_color_triangle, - gx_forward_update_spot_equivalent_colors, - gx_forward_ret_devn_params, - gx_forward_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - gx_forward_dev_spec_op, - clip_copy_planes, /* copy planes */ - gx_forward_get_profile, - gx_forward_set_graphics_type_tag, - clip_strip_copy_rop2, - clip_strip_tile_rect_devn, - clip_copy_alpha_hl_color, - NULL, /* process_page */ - clip_transform_pixel_region, - clip_fill_stroke_path, - } +{std_device_std_body(gx_device_clip, + clipper_initialize_device_procs, "clipper", + 0, 0, 1, 1) }; /* Make a clipping device. */ @@ -197,10 +179,14 @@ gx_make_clip_device_on_stack_if_needed(gx_device_clip * dev, const gx_clip_path return (gx_device *)dev; } void -gx_make_clip_device_in_heap(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target, - gs_memory_t *mem) +gx_make_clip_device_in_heap(gx_device_clip *dev, + const gx_clip_path *pcpath, + gx_device *target, + gs_memory_t *mem) { - gx_device_init((gx_device *)dev, (const gx_device *)&gs_clip_device, mem, true); + /* Can never fail */ + (void)gx_device_init((gx_device *)dev, + (const gx_device *)&gs_clip_device, mem, true); dev->list = *gx_cpath_list(pcpath); dev->translation.x = 0; dev->translation.y = 0; @@ -212,7 +198,8 @@ gx_make_clip_device_in_heap(gx_device_clip * dev, const gx_clip_path *pcpath, gx dev->is_planar = target->is_planar; gx_device_set_target((gx_device_forward *)dev, target); gx_device_retain((gx_device *)dev, true); /* will free explicitly */ - (*dev_proc(dev, open_device)) ((gx_device *)dev); + /* Can never fail */ + (void)(*dev_proc(dev, open_device)) ((gx_device *)dev); } /* Define debugging statistics for the clipping loops. */ #if defined(DEBUG) && !defined(GS_THREADSAFE) @@ -1346,35 +1333,6 @@ clip_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, /* Copy a rectangle with RasterOp and strip texture. */ int -clip_call_strip_copy_rop(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) -{ - return (*dev_proc(pccd->tdev, strip_copy_rop)) - (pccd->tdev, pccd->data + (yc - pccd->y) * pccd->raster, - pccd->sourcex + xc - pccd->x, pccd->raster, gx_no_bitmap_id, - pccd->scolors, pccd->textures, pccd->tcolors, - xc, yc, xec - xc, yec - yc, pccd->phase.x, pccd->phase.y, - pccd->lop); -} -static int -clip_strip_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint raster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, const gx_color_index * tcolors, - int x, int y, int w, int h, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_clip *rdev = (gx_device_clip *) dev; - clip_callback_data_t ccdata; - - ccdata.data = sdata, ccdata.sourcex = sourcex, ccdata.raster = raster; - ccdata.scolors = scolors, ccdata.textures = textures, - ccdata.tcolors = tcolors; - ccdata.phase.x = phase_x, ccdata.phase.y = phase_y, ccdata.lop = lop; - return clip_enumerate(rdev, x, y, w, h, clip_call_strip_copy_rop, &ccdata); -} - -/* Copy a rectangle with RasterOp and strip texture. */ -int clip_call_strip_copy_rop2(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) { return (*dev_proc(pccd->tdev, strip_copy_rop2)) @@ -1479,29 +1437,17 @@ clip_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) /* Get bits back from the device. */ static int clip_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_clip *rdev = (gx_device_clip *) dev; gx_device *tdev = rdev->target; int tx = rdev->translation.x, ty = rdev->translation.y; gs_int_rect rect; - int code; rect.p.x = prect->p.x - tx, rect.p.y = prect->p.y - ty; rect.q.x = prect->q.x - tx, rect.q.y = prect->q.y - ty; - code = (*dev_proc(tdev, get_bits_rectangle)) - (tdev, &rect, params, unread); - if (code > 0) { - /* Adjust unread rectangle coordinates */ - gs_int_rect *list = *unread; - int i; - - for (i = 0; i < code; ++list, ++i) { - list->p.x += tx, list->p.y += ty; - list->q.x += tx, list->q.y += ty; - } - } - return code; + return (*dev_proc(tdev, get_bits_rectangle)) + (tdev, &rect, params); } static int diff --git a/base/gxclip.h b/base/gxclip.h index 5d44bc00..f071864f 100644 --- a/base/gxclip.h +++ b/base/gxclip.h @@ -78,8 +78,6 @@ int int xc, int yc, int xec, int yec), clip_call_strip_tile_rect_devn(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec), - clip_call_strip_copy_rop(clip_callback_data_t * pccd, - int xc, int yc, int xec, int yec), clip_call_strip_copy_rop2(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec), clip_call_fill_rectangle_hl_color(clip_callback_data_t * pccd, diff --git a/base/gxclip2.c b/base/gxclip2.c index 38e79fab..ef3eb5b3 100644 --- a/base/gxclip2.c +++ b/base/gxclip2.c @@ -36,86 +36,69 @@ static dev_proc_copy_color(tile_clip_copy_color); static dev_proc_copy_planes(tile_clip_copy_planes); static dev_proc_copy_alpha(tile_clip_copy_alpha); static dev_proc_copy_alpha_hl_color(tile_clip_copy_alpha_hl_color); -static dev_proc_strip_copy_rop(tile_clip_strip_copy_rop); static dev_proc_strip_copy_rop2(tile_clip_strip_copy_rop2); /* The device descriptor. */ +static void +tile_clipper_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, tile_clip_fill_rectangle); + set_dev_proc(dev, copy_mono, tile_clip_copy_mono); + set_dev_proc(dev, copy_color, tile_clip_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, gx_forward_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + set_dev_proc(dev, copy_alpha, tile_clip_copy_alpha); + set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); + set_dev_proc(dev, composite, gx_no_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_forward_encode_color); + set_dev_proc(dev, decode_color, gx_forward_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, tile_clip_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, gx_forward_include_color_space); + set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); + set_dev_proc(dev, copy_planes, tile_clip_copy_planes); + set_dev_proc(dev, strip_copy_rop2, tile_clip_strip_copy_rop2); + set_dev_proc(dev, copy_alpha_hl_color, tile_clip_copy_alpha_hl_color); + + /* Ideally the following defaults would be set up for us, but this + * does not currently work. */ + set_dev_proc(dev, open_device, gx_default_open_device); + set_dev_proc(dev, sync_output, gx_default_sync_output); + set_dev_proc(dev, output_page, gx_default_output_page); + set_dev_proc(dev, close_device, gx_default_close_device); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, stroke_path, gx_default_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, text_begin, gx_default_text_begin); + set_dev_proc(dev, strip_tile_rect_devn, gx_default_strip_tile_rect_devn); +} + static const gx_device_tile_clip gs_tile_clip_device = -{std_device_std_body_open(gx_device_tile_clip, 0, "tile clipper", - 0, 0, 1, 1), - {gx_default_open_device, - gx_forward_get_initial_matrix, - gx_default_sync_output, - gx_default_output_page, - gx_default_close_device, - gx_forward_map_rgb_color, - gx_forward_map_color_rgb, - tile_clip_fill_rectangle, - gx_default_tile_rectangle, - tile_clip_copy_mono, - tile_clip_copy_color, - gx_default_draw_line, - gx_forward_get_bits, - gx_forward_get_params, - gx_forward_put_params, - gx_forward_map_cmyk_color, - gx_forward_get_xfont_procs, - gx_forward_get_xfont_device, - gx_forward_map_rgb_alpha_color, - gx_forward_get_page_device, - gx_forward_get_alpha_bits, - tile_clip_copy_alpha, - gx_forward_get_band, - gx_default_copy_rop, - gx_default_fill_path, - gx_default_stroke_path, - gx_default_fill_mask, - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - gx_default_strip_tile_rectangle, - tile_clip_strip_copy_rop, - gx_forward_get_clipping_box, - gx_default_begin_typed_image, - gx_forward_get_bits_rectangle, - gx_forward_map_color_rgb_alpha, - gx_no_create_compositor, - gx_forward_get_hardware_params, - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color, - NULL, /* pattern_manage */ - tile_clip_fill_rectangle_hl_color, - gx_forward_include_color_space, - gx_forward_fill_linear_color_scanline, - gx_forward_fill_linear_color_trapezoid, - gx_forward_fill_linear_color_triangle, - gx_forward_update_spot_equivalent_colors, - gx_forward_ret_devn_params, - gx_forward_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - gx_forward_dev_spec_op, - tile_clip_copy_planes, - NULL, /* get_profile */ - NULL, /* set_graphics_type_tag */ - tile_clip_strip_copy_rop2, - gx_default_strip_tile_rect_devn, - tile_clip_copy_alpha_hl_color - } +{std_device_std_body_open(gx_device_tile_clip, + tile_clipper_initialize_device_procs, + "tile clipper", + 0, 0, 1, 1) }; /* Initialize a tile clipping device from a mask. */ @@ -400,34 +383,6 @@ tile_clip_copy_alpha_hl_color(gx_device * dev, return 0; } -/* Copy a RasterOp rectangle similarly. */ -static int -tile_clip_strip_copy_rop(gx_device * dev, - const byte * data, int sourcex, uint raster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, const gx_color_index * tcolors, - int x, int y, int w, int h, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_tile_clip *cdev = (gx_device_tile_clip *) dev; - - fit_copy(dev, data, sourcex, raster, id, x, y, w, h); - { - FOR_RUNS(data_row, txrun, tx, ty) { - /* Copy the run. */ - int code = (*dev_proc(cdev->target, strip_copy_rop)) - (cdev->target, data_row, sourcex + txrun - x, raster, - gx_no_bitmap_id, scolors, textures, tcolors, - txrun, ty, tx - txrun, 1, phase_x, phase_y, lop); - - if (code < 0) - return code; - } - END_FOR_RUNS(); - } - return 0; -} - static int tile_clip_strip_copy_rop2(gx_device * dev, const byte * data, int sourcex, uint raster, gx_bitmap_id id, diff --git a/base/gxclipm.c b/base/gxclipm.c index 59f1e765..627f28a5 100644 --- a/base/gxclipm.c +++ b/base/gxclipm.c @@ -32,90 +32,74 @@ static dev_proc_copy_alpha(mask_clip_copy_alpha); static dev_proc_copy_alpha_hl_color(mask_clip_copy_alpha_hl_color); static dev_proc_strip_tile_rectangle(mask_clip_strip_tile_rectangle); static dev_proc_strip_tile_rect_devn(mask_clip_strip_tile_rect_devn); -static dev_proc_strip_copy_rop(mask_clip_strip_copy_rop); static dev_proc_strip_copy_rop2(mask_clip_strip_copy_rop2); static dev_proc_get_clipping_box(mask_clip_get_clipping_box); /* The device descriptor. */ -const gx_device_mask_clip gs_mask_clip_device = -{std_device_std_body_open(gx_device_mask_clip, 0, "mask clipper", - 0, 0, 1, 1), - {gx_default_open_device, - gx_forward_get_initial_matrix, - gx_default_sync_output, - gx_default_output_page, - gx_default_close_device, - gx_forward_map_rgb_color, - gx_forward_map_color_rgb, - mask_clip_fill_rectangle, - gx_default_tile_rectangle, - mask_clip_copy_mono, - mask_clip_copy_color, - gx_default_draw_line, - gx_forward_get_bits, - gx_forward_get_params, - gx_forward_put_params, - gx_forward_map_cmyk_color, - gx_forward_get_xfont_procs, - gx_forward_get_xfont_device, - gx_forward_map_rgb_alpha_color, - gx_forward_get_page_device, - gx_forward_get_alpha_bits, - mask_clip_copy_alpha, - gx_forward_get_band, - gx_default_copy_rop, - gx_default_fill_path, - gx_default_stroke_path, - gx_default_fill_mask, - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - mask_clip_strip_tile_rectangle, - mask_clip_strip_copy_rop, - mask_clip_get_clipping_box, - gx_default_begin_typed_image, - gx_forward_get_bits_rectangle, - gx_forward_map_color_rgb_alpha, - gx_no_create_compositor, - gx_forward_get_hardware_params, - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color, - NULL, /* pattern_manage */ - mask_clip_fill_rectangle_hl_color, - gx_forward_include_color_space, - gx_forward_fill_linear_color_scanline, - gx_forward_fill_linear_color_trapezoid, - gx_forward_fill_linear_color_triangle, - gx_forward_update_spot_equivalent_colors, - gx_forward_ret_devn_params, - gx_forward_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - gx_forward_dev_spec_op, - NULL, - gx_forward_get_profile, - gx_forward_set_graphics_type_tag, - mask_clip_strip_copy_rop2, - mask_clip_strip_tile_rect_devn, - mask_clip_copy_alpha_hl_color, - NULL, - gx_default_transform_pixel_region, - gx_forward_fill_stroke_path, + +static void +mask_clip_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, mask_clip_fill_rectangle); + set_dev_proc(dev, copy_mono, mask_clip_copy_mono); + set_dev_proc(dev, copy_color, mask_clip_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, gx_forward_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + set_dev_proc(dev, copy_alpha, mask_clip_copy_alpha); + set_dev_proc(dev, strip_tile_rectangle, mask_clip_strip_tile_rectangle); + set_dev_proc(dev, get_clipping_box, mask_clip_get_clipping_box); + set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); + set_dev_proc(dev, composite, gx_no_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_forward_encode_color); + set_dev_proc(dev, decode_color, gx_forward_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, mask_clip_fill_rectangle_hl_color); + set_dev_proc(dev, include_color_space, gx_forward_include_color_space); + set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); + set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, gx_forward_fillpage); + set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); + set_dev_proc(dev, get_profile, gx_forward_get_profile); + set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dev, strip_copy_rop2, mask_clip_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, mask_clip_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, mask_clip_copy_alpha_hl_color); + set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); + + /* Ideally these defaults would be set up automatically for us. */ + set_dev_proc(dev, open_device, gx_default_open_device); + set_dev_proc(dev, sync_output, gx_default_sync_output); + set_dev_proc(dev, output_page, gx_default_output_page); + set_dev_proc(dev, close_device, gx_default_close_device); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, stroke_path, gx_default_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, text_begin, gx_default_text_begin); + } + +const gx_device_mask_clip gs_mask_clip_device = +{std_device_std_body_open(gx_device_mask_clip, + mask_clip_initialize_device_procs, + "mask clipper", + 0, 0, 1, 1) }; /* Fill a rectangle with a hl color, painting through the mask */ @@ -453,26 +437,6 @@ mask_clip_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, } static int -mask_clip_strip_copy_rop(gx_device * dev, - const byte * data, int sourcex, uint raster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, const gx_color_index * tcolors, - int x, int y, int w, int h, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev; - clip_callback_data_t ccdata; - - ccdata.tdev = cdev->target; - ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h; - ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster; - ccdata.scolors = scolors, ccdata.textures = textures, - ccdata.tcolors = tcolors; - ccdata.phase.x = phase_x, ccdata.phase.y = phase_y, ccdata.lop = lop; - return clip_runs_enumerate(cdev, clip_call_strip_copy_rop, &ccdata); -} - -static int mask_clip_strip_copy_rop2(gx_device * dev, const byte * data, int sourcex, uint raster, gx_bitmap_id id, const gx_color_index * scolors, diff --git a/base/gxclist.c b/base/gxclist.c index 7c7f0aa4..a3b3ccb3 100644 --- a/base/gxclist.c +++ b/base/gxclist.c @@ -120,95 +120,65 @@ private_st_clist_icctable(); /* Forward declarations of driver procedures */ dev_proc_open_device(clist_open); dev_proc_output_page(clist_output_page); -static dev_proc_close_device(clist_close); -static dev_proc_get_band(clist_get_band); +dev_proc_close_device(clist_close); /* Driver procedures defined in other files are declared in gxcldev.h. */ /* Other forward declarations */ static int clist_put_current_params(gx_device_clist_writer *cldev); -/* The device procedures */ -const gx_device_procs gs_clist_device_procs = { - clist_open, - gx_forward_get_initial_matrix, - gx_default_sync_output, - clist_output_page, - clist_close, - gx_forward_map_rgb_color, - gx_forward_map_color_rgb, - clist_fill_rectangle, - gx_default_tile_rectangle, - clist_copy_mono, - clist_copy_color, - gx_default_draw_line, - gx_default_get_bits, - gx_forward_get_params, - gx_forward_put_params, - gx_forward_map_cmyk_color, - gx_forward_get_xfont_procs, - gx_forward_get_xfont_device, - gx_forward_map_rgb_alpha_color, - gx_forward_get_page_device, - gx_forward_get_alpha_bits, - clist_copy_alpha, - clist_get_band, - gx_default_copy_rop, - clist_fill_path, - clist_stroke_path, - clist_fill_mask, - clist_fill_trapezoid, - clist_fill_parallelogram, - clist_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - clist_strip_tile_rectangle, - clist_strip_copy_rop, - gx_forward_get_clipping_box, - clist_begin_typed_image, - clist_get_bits_rectangle, - gx_forward_map_color_rgb_alpha, - clist_create_compositor, - gx_forward_get_hardware_params, - gx_default_text_begin, - gx_default_finish_copydevice, - gx_default_begin_transparency_group, /* begin_transparency_group */ - gx_default_end_transparency_group, /* end_transparency_group */ - gx_default_begin_transparency_mask, /* begin_transparency_mask */ - gx_default_end_transparency_mask, /* end_transparency_mask */ - gx_default_discard_transparency_layer, /* discard_transparency_layer */ - gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color, - gx_default_pattern_manage, /* pattern_manage */ - clist_fill_rectangle_hl_color, - gx_default_include_color_space, - gx_default_fill_linear_color_scanline, - clist_fill_linear_color_trapezoid, - clist_fill_linear_color_triangle, - gx_forward_update_spot_equivalent_colors, - gx_forward_ret_devn_params, - clist_fillpage, - gx_default_push_transparency_state, /* push_transparency_state */ - gx_default_pop_transparency_state, /* pop_transparency_state */ - gx_default_put_image, /* put_image */ - clist_dev_spec_op, - clist_copy_planes, /* copy planes */ - gx_default_get_profile, - gx_default_set_graphics_type_tag, - clist_strip_copy_rop2, - clist_strip_tile_rect_devn, - clist_copy_alpha_hl_color, - clist_process_page, - gx_default_transform_pixel_region, - clist_fill_stroke_path, -}; +void +clist_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, clist_open); + set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + set_dev_proc(dev, sync_output, gx_default_sync_output); + set_dev_proc(dev, output_page, clist_output_page); + set_dev_proc(dev, close_device, clist_close); + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, fill_rectangle, clist_fill_rectangle); + set_dev_proc(dev, copy_mono, clist_copy_mono); + set_dev_proc(dev, copy_color, clist_copy_color); + set_dev_proc(dev, get_params, gx_forward_get_params); + set_dev_proc(dev, put_params, gx_forward_put_params); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, get_page_device, gx_forward_get_page_device); + set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + set_dev_proc(dev, copy_alpha, clist_copy_alpha); + set_dev_proc(dev, fill_path, clist_fill_path); + set_dev_proc(dev, stroke_path, clist_stroke_path); + set_dev_proc(dev, fill_mask, clist_fill_mask); + set_dev_proc(dev, fill_trapezoid, clist_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, clist_fill_parallelogram); + set_dev_proc(dev, fill_triangle, clist_fill_triangle); + set_dev_proc(dev, strip_tile_rectangle, clist_strip_tile_rectangle); + set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + set_dev_proc(dev, begin_typed_image, clist_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, clist_get_bits_rectangle); + set_dev_proc(dev, composite, clist_composite); + set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); + set_dev_proc(dev, encode_color, gx_forward_encode_color); + set_dev_proc(dev, decode_color, gx_forward_decode_color); + set_dev_proc(dev, fill_rectangle_hl_color, clist_fill_rectangle_hl_color); + set_dev_proc(dev, fill_linear_color_trapezoid, clist_fill_linear_color_trapezoid); + set_dev_proc(dev, fill_linear_color_triangle, clist_fill_linear_color_triangle); + set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); + set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); + set_dev_proc(dev, fillpage, clist_fillpage); + set_dev_proc(dev, dev_spec_op, clist_dev_spec_op); + set_dev_proc(dev, copy_planes, clist_copy_planes); + set_dev_proc(dev, strip_copy_rop2, clist_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, clist_strip_tile_rect_devn); + set_dev_proc(dev, copy_alpha_hl_color, clist_copy_alpha_hl_color); + set_dev_proc(dev, process_page, clist_process_page); + set_dev_proc(dev, fill_stroke_path, clist_fill_stroke_path); +} /*------------------- Choose the implementation ----------------------- - For chossing the clist i/o implementation by makefile options + For choosing the clist i/o implementation by makefile options we define global variables, which are initialized with file/memory io procs when they are included into the build. */ @@ -741,7 +711,7 @@ errxit: return code; } -static int +int clist_close(gx_device *dev) { int i; @@ -965,22 +935,6 @@ clist_put_current_params(gx_device_clist_writer *cldev) /* ---------------- Driver interface ---------------- */ -static int -clist_get_band(gx_device * dev, int y, int *band_start) -{ - gx_device_clist_writer * const cdev = - &((gx_device_clist *)dev)->writer; - int band_height = cdev->page_band_height; - int start; - - if (y < 0) - y = 0; - else if (y >= dev->height) - y = dev->height; - *band_start = start = y - y % band_height; - return min(dev->height - start, band_height); -} - /* ICC table operations. See gxclist.h for details */ /* This checks the table for a hash code entry */ bool @@ -1386,7 +1340,7 @@ clist_make_accum_device(gs_memory_t *mem, gx_device *target, const char *dname, return 0; memset(cdev, 0, sizeof(*cdev)); cwdev->params_size = sizeof(gx_device_clist); - cwdev->static_procs = NULL; + cwdev->initialize_device_procs = clist_initialize_device_procs; cwdev->dname = dname; cwdev->memory = mem->stable_memory; cwdev->stype = &st_device_clist; @@ -1413,7 +1367,8 @@ clist_make_accum_device(gs_memory_t *mem, gx_device *target, const char *dname, cwdev->icc_table = NULL; cwdev->UseCIEColor = target->UseCIEColor; cwdev->LockSafetyParams = true; - cwdev->procs = gs_clist_device_procs; + cwdev->initialize_device_procs((gx_device *)cwdev); + gx_device_fill_in_procs((gx_device *)cwdev); gx_device_copy_color_params((gx_device *)cwdev, target); rc_assign(cwdev->target, target, "clist_make_accum_device"); clist_init_io_procs(cdev, use_memory_clist); @@ -1550,7 +1505,7 @@ open_c: pdev->clist_disable_mask, pdev->page_uses_transparency, pdev->page_uses_overprint); - code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev ); + code = clist_open( (gx_device *)pcldev ); if (code < 0) { /* If there wasn't enough room, and we haven't */ /* already shrunk the buffer, try enlarging it. */ diff --git a/base/gxclist.h b/base/gxclist.h index a30331fb..bc63cc7f 100644 --- a/base/gxclist.h +++ b/base/gxclist.h @@ -433,8 +433,7 @@ extern_st(st_device_clist); (xclist)->writer.pinst = NULL;\ END -/* The device template itself is never used, only the procedures. */ -extern const gx_device_procs gs_clist_device_procs; +void clist_initialize_device_procs(gx_device *dev); void clist_init_io_procs(gx_device_clist *pclist_dev, bool in_memory); diff --git a/base/gxclpage.c b/base/gxclpage.c index 18ff9b81..0e358da3 100644 --- a/base/gxclpage.c +++ b/base/gxclpage.c @@ -24,6 +24,8 @@ #include "string_.h" #include <ctype.h> /* for isalpha, etc. */ +extern dev_proc_open_device(clist_open); + /* Save the current clist state into a saved page structure, * and optionally stashes the files into the given save_files * pointers. @@ -106,7 +108,7 @@ params_out: } } /* Now re-open the clist device so that we get new files for the next page */ - return (*gs_clist_device_procs.open_device) ((gx_device *) pdev); + return clist_open((gx_device *) pdev); } /* Save a page. The elements are allocated by this function in non_gc_memory */ diff --git a/base/gxclpath.h b/base/gxclpath.h index 7a393730..f5e9555c 100644 --- a/base/gxclpath.h +++ b/base/gxclpath.h @@ -175,7 +175,7 @@ typedef enum { */ typedef enum { cmd_opv_ext_put_params = 0x00, /* serialized parameter list */ - cmd_opv_ext_create_compositor = 0x01, /* compositor id, + cmd_opv_ext_composite = 0x01, /* compositor id, * serialized compositor */ cmd_opv_ext_put_halftone = 0x02, /* length of entire halftone */ cmd_opv_ext_put_ht_seg = 0x03, /* segment length, diff --git a/base/gxclrast.c b/base/gxclrast.c index f9f42d88..bfed7ddb 100644 --- a/base/gxclrast.c +++ b/base/gxclrast.c @@ -256,8 +256,8 @@ static int read_begin_image(command_buf_t *pcb, gs_image_common_t *pic, static int read_put_params(command_buf_t *pcb, gs_gstate *pgs, gx_device_clist_reader *cdev, gs_memory_t *mem); -static int read_create_compositor(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp); -static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, +static int read_composite(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp); +static int apply_composite(gx_device_clist_reader *cdev, gs_gstate *pgs, gs_memory_t *mem, gs_composite_t *pcomp, int x0, int y0, gx_device **ptarget); static int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *); @@ -382,7 +382,7 @@ execute_compositor_queue(gx_device_clist_reader *cdev, gx_device **target, gx_de if (code < 0) return code; pcomp->idle |= idle; - code = apply_create_compositor(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */ + code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */ if (code < 0) return code; *tdev = *target; @@ -809,7 +809,7 @@ in: /* Initialize for a new page. */ halftone_type, num_comp); #endif code = cmd_resize_halftone( - &gs_gstate.dev_ht, + &gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT], num_comp, mem); if (code < 0) goto out; @@ -1209,10 +1209,10 @@ set_phase: /* if (state_tile.size.x) tile_phase.x = (state.tile_phase.x + x0) % state_tile.size.x; - if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_width) + if (gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT] && gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width) color_phase.x = (state.tile_phase.x + x0) % - gs_gstate.dev_ht->lcm_width; + gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width; /* * The true tile height for shifted tiles is not * size.y: see gxbitmap.h for the computation. @@ -1230,10 +1230,10 @@ set_phase: /* tile_phase.y = (state.tile_phase.y + y0) % full_height; } - if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_height) + if (gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT] && gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height) color_phase.y = (state.tile_phase.y + y0) % - gs_gstate.dev_ht->lcm_height; + gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height; gx_gstate_setscreenphase(&gs_gstate, -(state.tile_phase.x + x0), -(state.tile_phase.y + y0), @@ -1615,8 +1615,8 @@ idata: data_size = 0; if (playback_action == playback_action_setup) goto out; break; - case cmd_opv_ext_create_compositor: - if_debug0m('L', mem, " ext_create_compositor\n"); + case cmd_opv_ext_composite: + if_debug0m('L', mem, " ext_composite\n"); cbuf.ptr = cbp; /* * The screen phase may have been changed during @@ -1637,12 +1637,12 @@ idata: data_size = 0; if (code < 0) goto out; } - if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_create_compositor) { + if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) { gs_composite_t *pcomp, *pcomp_opening; gs_compositor_closing_state closing_state; cbuf.ptr = cbp += 2; - code = read_create_compositor(&cbuf, mem, &pcomp); + code = read_composite(&cbuf, mem, &pcomp); if (code < 0) goto out; cbp = cbuf.ptr; @@ -1651,7 +1651,7 @@ idata: data_size = 0; if (gs_is_pdf14trans_compositor(pcomp) && playback_action == playback_action_render_no_pdf14) { /* free the compositor object */ - gs_free_object(mem, pcomp, "read_create_compositor"); + gs_free_object(mem, pcomp, "read_composite"); pcomp = NULL; continue; } @@ -2258,18 +2258,7 @@ idata: data_size = 0; colors[0] = colors[1] = state.colors[1]; log_op = state.lop; pcolor = colors; - do_rop:if (plane_height == 0) { - code = (*dev_proc(tdev, strip_copy_rop)) - (tdev, source, data_x, raster, gx_no_bitmap_id, - pcolor, &state_tile, - (state.tile_colors[0] == gx_no_color_index && - state.tile_colors[1] == gx_no_color_index ? - NULL : state.tile_colors), - state.rect.x - x0, state.rect.y - y0, - state.rect.width - data_x, state.rect.height, - tile_phase.x, tile_phase.y, log_op); - } else { - code = (*dev_proc(tdev, strip_copy_rop2)) + do_rop:code = (*dev_proc(tdev, strip_copy_rop2)) (tdev, source, data_x, raster, gx_no_bitmap_id, pcolor, &state_tile, (state.tile_colors[0] == gx_no_color_index && @@ -2280,7 +2269,6 @@ idata: data_size = 0; tile_phase.x, tile_phase.y, log_op, plane_height); plane_height = 0; - } data_x = 0; break; case cmd_op_tile_rect >> 4: @@ -2291,7 +2279,7 @@ idata: data_size = 0; } case cmd_op_tile_rect_short >> 4: case cmd_op_tile_rect_tiny >> 4: - /* Currently we don't use lop with tile_rectangle. */ + /* Currently we don't use lop with strip_tile_rectangle. */ code = (*dev_proc(tdev, strip_tile_rectangle)) (tdev, &state_tile, state.rect.x - x0, state.rect.y - y0, @@ -3030,7 +3018,7 @@ out: } /* - * Read a "create_compositor" command, and execute the command. + * Read a "composite" command, and execute the command. * * This code assumes that a the largest create compositor command, * including the compositor name size, is smaller than the data buffer @@ -3038,7 +3026,7 @@ out: * and the de-serializer interface, as no length field is provided. * * At the time of this writing, no compositor violates this assumption. - * The largest create_compositor is currently 1275 bytes, while the command + * The largest composite is currently 1275 bytes, while the command * data buffer is 4096 bytes. * * In the event that this assumption is violated, a change in the encoding @@ -3049,7 +3037,7 @@ out: extern_gs_find_compositor(); static int -read_create_compositor( +read_composite( command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp) { const byte * cbp = pcb->ptr; @@ -3081,7 +3069,7 @@ read_create_compositor( return code; } -static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, +static int apply_composite(gx_device_clist_reader *cdev, gs_gstate *pgs, gs_memory_t *mem, gs_composite_t *pcomp, int x0, int y0, gx_device **ptarget) { @@ -3095,7 +3083,7 @@ static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, * Apply the compositor to the target device; note that this may * change the target device. */ - code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev); + code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev); if (code == 1) { /* A new compositor was created that wrapped tdev. This should * be our new target. */ @@ -3112,7 +3100,7 @@ static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, return code; /* free the compositor object */ - gs_free_object(mem, pcomp, "read_create_compositor"); + gs_free_object(mem, pcomp, "read_composite"); return code; } diff --git a/base/gxclread.c b/base/gxclread.c index 2323b68c..23b07ac3 100644 --- a/base/gxclread.c +++ b/base/gxclread.c @@ -590,7 +590,7 @@ clist_render_init(gx_device_clist *dev) /* Copy a rasterized rectangle to the client, rasterizing if needed. */ int clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect, - gs_get_bits_params_t *params, gs_int_rect **unread) + gs_get_bits_params_t *params) { gx_device_clist *cldev = (gx_device_clist *)dev; gx_device_clist_reader *crdev = &cldev->reader; @@ -631,8 +631,7 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect, for (i = 0; i < num_planes; ++i) if (params->data[i]) { if (plane_index >= 0) /* >1 plane requested */ - return gx_default_get_bits_rectangle(dev, prect, params, - unread); + return gx_default_get_bits_rectangle(dev, prect, params); plane_index = i; } } @@ -655,7 +654,7 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect, band_rect.p.y = my; band_rect.q.y = my + lines_rasterized; code = dev_proc(bdev, get_bits_rectangle) - (bdev, &band_rect, params, unread); + (bdev, &band_rect, params); } cdev->buf_procs.destroy_buf_device(bdev); if (code < 0 || lines_rasterized == line_count) @@ -668,7 +667,7 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect, * rectangles, punt. */ if (!(options & GB_RETURN_COPY) || code > 0) - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); options = params->options; if (!(options & GB_RETURN_COPY)) { /* Redo the first piece with copying. */ @@ -703,7 +702,7 @@ clist_get_bits_rectangle(gx_device *dev, const gs_int_rect * prect, band_rect.p.y = my; band_rect.q.y = my + lines_rasterized; code = dev_proc(bdev, get_bits_rectangle) - (bdev, &band_rect, &band_params, unread); + (bdev, &band_rect, &band_params); if (code < 0) break; params->options = options = band_params.options; diff --git a/base/gxclrect.c b/base/gxclrect.c index bbfb40d8..a97cf0f6 100644 --- a/base/gxclrect.c +++ b/base/gxclrect.c @@ -1421,20 +1421,6 @@ copy:{ } int -clist_strip_copy_rop(gx_device * dev, - const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, - const gx_color_index * scolors, - const gx_strip_bitmap * textures, const gx_color_index * tcolors, - int rx, int ry, int rwidth, int rheight, - int phase_x, int phase_y, gs_logical_operation_t lop) -{ - return clist_strip_copy_rop2(dev, sdata, sourcex, sraster, id, - scolors, textures, tcolors, - rx, ry, rwidth, rheight, phase_x, phase_y, - lop, 0); -} - -int clist_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, @@ -1647,13 +1633,13 @@ clist_strip_copy_rop2(gx_device * dev, } continue; } - if (((phase_x != re.pcls->tile_phase.x) && (tiles->rep_width > 1)) || - ((phase_y != re.pcls->tile_phase.y) && (tiles->rep_height > 1))) { - code = cmd_set_tile_phase(cdev, re.pcls, phase_x, - phase_y); - if (code < 0) - return code; - } + } + if (((phase_x != re.pcls->tile_phase.x) && (tiles->rep_width > 1)) || + ((phase_y != re.pcls->tile_phase.y) && (tiles->rep_height > 1))) { + code = cmd_set_tile_phase(cdev, re.pcls, phase_x, + phase_y); + if (code < 0) + return code; } } /* Set the tile colors. */ diff --git a/base/gxclthrd.c b/base/gxclthrd.c index 088de2bf..a5835cc1 100644 --- a/base/gxclthrd.c +++ b/base/gxclthrd.c @@ -837,7 +837,7 @@ clist_get_band_from_thread(gx_device *dev, int band_needed, gx_process_page_opti /* rendering adjacent to the first band (forward or backward) */ static int clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, - gs_get_bits_params_t *params, gs_int_rect **unread) + gs_get_bits_params_t *params) { gx_device_printer *pdev = (gx_device_printer *)dev; gx_device_clist *cldev = (gx_device_clist *)dev; @@ -861,7 +861,7 @@ clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, /* This page might not want multiple threads */ /* Also we don't support plane extraction using multiple threads */ if (pdev->num_render_threads_requested < 1 || (options & GB_SELECT_PLANES)) - return clist_get_bits_rectangle(dev, prect, params, unread); + return clist_get_bits_rectangle(dev, prect, params); if (prect->p.x < 0 || prect->q.x > dev->width || y < 0 || end_y > dev->height @@ -878,12 +878,12 @@ clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, /* Haven't done any rendering yet, try to set up the threads */ if (clist_setup_render_threads(dev, y, NULL) < 0) /* problem setting up the threads, revert to single threaded */ - return clist_get_bits_rectangle(dev, prect, params, unread); + return clist_get_bits_rectangle(dev, prect, params); } else { if (crdev->render_threads == NULL) { /* If we get here with with ymin and ymax > 0 it's because we closed the threads */ /* while doing a page due to an error. Use single threaded mode. */ - return clist_get_bits_rectangle(dev, prect, params, unread); + return clist_get_bits_rectangle(dev, prect, params); } } /* If we already have the band's data, just return it */ @@ -905,7 +905,7 @@ clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, band_rect.p.y = 0; band_rect.q.y = lines_rasterized; code = dev_proc(bdev, get_bits_rectangle) - (bdev, &band_rect, params, unread); + (bdev, &band_rect, params); cdev->buf_procs.destroy_buf_device(bdev); if (code < 0) goto free_thread_out; @@ -924,7 +924,7 @@ clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, * rectangles, punt. */ if (!(options & GB_RETURN_COPY) || code > 0) - return gx_default_get_bits_rectangle(dev, prect, params, unread); + return gx_default_get_bits_rectangle(dev, prect, params); options = params->options; if (!(options & GB_RETURN_COPY)) { /* Redo the first piece with copying. */ @@ -952,7 +952,7 @@ clist_get_bits_rect_mt(gx_device *dev, const gs_int_rect * prect, band_rect.p.y = my; band_rect.q.y = my + lines_rasterized; code = dev_proc(bdev, get_bits_rectangle) - (bdev, &band_rect, &band_params, unread); + (bdev, &band_rect, &band_params); if (code < 0) break; params->options = band_params.options; diff --git a/base/gxclutil.c b/base/gxclutil.c index 055fbcf7..1884348e 100644 --- a/base/gxclutil.c +++ b/base/gxclutil.c @@ -83,7 +83,7 @@ cmd_uncount_op(int op, uint size) #endif /* Print statistics. */ -#if defined(DEBUG) && !defined(GS_THREADSAFE) +#if defined(DEBUG_CLIST_STATS) && !defined(GS_THREADSAFE) void cmd_print_stats(const gs_memory_t *mem) { @@ -287,7 +287,7 @@ cmd_write_buffer(gx_device_clist_writer * cldev, byte cmd_end) VALGRIND_MAKE_MEM_UNDEFINED(cldev->cbuf, cldev->cend - cldev->cbuf); #endif cldev->ccl = 0; -#if defined(DEBUG) && !defined(GS_THREADSAFE) +#if defined(DEBUG_CLIST_STATS) && !defined(GS_THREADSAFE) if (gs_debug_c('l')) cmd_print_stats(cldev->memory); #endif diff --git a/base/gxcmap.c b/base/gxcmap.c index cba4908e..a3c2443a 100644 --- a/base/gxcmap.c +++ b/base/gxcmap.c @@ -15,6 +15,7 @@ /* Color mapping for Ghostscript */ +#include "assert_.h" #include "gx.h" #include "gserrors.h" #include "gsccolor.h" @@ -27,6 +28,7 @@ #include "gxcmap.h" #include "gxlum.h" #include "gzstate.h" +#include "gzht.h" #include "gxdither.h" #include "gxcdevn.h" #include "string_.h" @@ -209,32 +211,32 @@ gx_backwards_compatible_gray_encode(gx_device *dev, /* -------- Default color space to color model conversion routines -------- */ void -gray_cs_to_gray_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_gray_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = gray; } static void -rgb_cs_to_gray_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_gray_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = color_rgb_to_gray(r, g, b, NULL); } static void -cmyk_cs_to_gray_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_gray_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { out[0] = color_cmyk_to_gray(c, m, y, k, NULL); } static void -gray_cs_to_rgb_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_rgb_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = gray; } void -rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_rgb_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = r; @@ -243,20 +245,20 @@ rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs, } static void -cmyk_cs_to_rgb_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_rgb_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { color_cmyk_to_rgb(c, m, y, k, NULL, out, dev->memory); } static void -gray_cs_to_rgbk_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_rgbk_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = frac_0; out[3] = gray; } static void -rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_rgbk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { if ((r == g) && (g == b)) { @@ -272,7 +274,7 @@ rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs, } static void -cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_rgbk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { frac rgb[3]; if ((c == frac_0) && (m == frac_0) && (y == frac_0)) { @@ -286,7 +288,7 @@ cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) } static void -gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = frac_0; out[3] = frac_1 - gray; @@ -308,7 +310,7 @@ gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) * often they are { pop 0 }. */ static void -rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_cmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { if (pgs != 0) @@ -325,7 +327,7 @@ rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, } void -cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_cmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { out[0] = c; out[1] = m; @@ -356,31 +358,40 @@ static const gx_cm_color_map_procs DeviceRGBK_procs = { * to color model conversion routines. */ const gx_cm_color_map_procs * -gx_default_DevGray_get_color_mapping_procs(const gx_device * dev) +gx_default_DevGray_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceGray_procs; } const gx_cm_color_map_procs * -gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev) +gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceRGB_procs; } const gx_cm_color_map_procs * -gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev) +gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceCMYK_procs; } const gx_cm_color_map_procs * -gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev) +gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceRGBK_procs; } const gx_cm_color_map_procs * -gx_error_get_color_mapping_procs(const gx_device * dev) +gx_error_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { /* * We should never get here. If we do then we do not have a "get_color_mapping_procs" @@ -392,14 +403,14 @@ gx_error_get_color_mapping_procs(const gx_device * dev) dev->dname); switch (dev->color_info.num_components) { case 1: /* DeviceGray or DeviceInvertGray */ - return gx_default_DevGray_get_color_mapping_procs(dev); + return gx_default_DevGray_get_color_mapping_procs(dev, tdev); case 3: - return gx_default_DevRGB_get_color_mapping_procs(dev); + return gx_default_DevRGB_get_color_mapping_procs(dev, tdev); case 4: default: /* Unknown color model - punt with CMYK */ - return gx_default_DevCMYK_get_color_mapping_procs(dev); + return gx_default_DevCMYK_get_color_mapping_procs(dev, tdev); } } @@ -497,13 +508,7 @@ static cmap_proc_rgb(cmap_rgb_direct); #define cmap_cmyk_halftoned cmap_cmyk_direct static cmap_proc_cmyk(cmap_cmyk_direct); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct); - /* Procedure names are only guaranteed unique to 23 characters.... */ -static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct); - static cmap_proc_separation(cmap_separation_halftoned); static cmap_proc_separation(cmap_separation_direct); @@ -517,7 +522,6 @@ static const gx_color_map_procs cmap_few = { cmap_gray_halftoned, cmap_rgb_halftoned, cmap_cmyk_halftoned, - cmap_rgb_alpha_halftoned, cmap_separation_halftoned, cmap_devicen_halftoned, cmap_halftoned_is_halftoned @@ -526,7 +530,6 @@ static const gx_color_map_procs cmap_many = { cmap_gray_direct, cmap_rgb_direct, cmap_cmyk_direct, - cmap_rgb_alpha_direct, cmap_separation_direct, cmap_devicen_direct, cmap_direct_is_halftoned @@ -888,6 +891,32 @@ gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs, return 0; } +/* ------ Utility for selecting the dev_ht from the pgs using the dev->graphics_type_tag ----- */ + +static gs_HT_objtype_t +tag_to_HT_objtype[8] = { HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_TEXT, /* GS_TEXT_TAG = 0x1 */ + HT_OBJTYPE_IMAGE, /* GS_IMAGE_TAG = 0x2 */ + HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_VECTOR, /* GS_VECTOR_TAG = 0x4 */ + HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT + }; + +/* Return the selected dev_ht[] or the pgs->dev_ht[HT_OBJTYPE_DEFAULT] */ +gx_device_halftone * +gx_select_dev_ht(const gs_gstate *pgs) +{ + gs_HT_objtype_t objtype; + + /* This function only works with 3 bits currently. Flag here in case we add object types */ + assert(HT_OBJTYPE_COUNT == 4); + + objtype = tag_to_HT_objtype[pgs->device->graphics_type_tag & 7]; + if (pgs->dev_ht[objtype] == NULL) + objtype = HT_OBJTYPE_DEFAULT; + return pgs->dev_ht[objtype]; +} + /* ------ Render Gray color. ------ */ static void @@ -896,24 +925,21 @@ cmap_gray_halftoned(frac gray, gx_device_color * pdc, { uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_gray_subclass(scm, gray, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_gray(cmdev, gray, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) cm_comps[i] = frac_1 - gx_map_color_frac(pgs, @@ -924,7 +950,7 @@ cmap_gray_halftoned(frac gray, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -937,16 +963,15 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_gray_subclass(scm, gray, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_gray(cmdev, gray, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) @@ -956,9 +981,7 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, cv[i] = frac2cv(cm_comps[i]); } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) cm_comps[i] = frac_1 - gx_map_color_frac(pgs, @@ -981,7 +1004,7 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -994,11 +1017,12 @@ cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, { uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count != 0) { @@ -1012,7 +1036,7 @@ cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1025,11 +1049,12 @@ cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { @@ -1056,7 +1081,7 @@ cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1076,11 +1101,12 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, cmm_dev_profile_t *dev_profile; gsicc_colorbuffer_t src_space = gsUNDEFINED; bool gray_to_k; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_cmyk_subclass(scm, c, m, y, k, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_cmyk(cmdev, c, m, y, k, cm_comps); /* apply the transfer function(s); convert to color values */ if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { @@ -1115,7 +1141,7 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, /* duplicating most of the code of this procedure. */ if (gx_device_must_halftone(dev)) { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); return; } @@ -1133,111 +1159,13 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, color_set_pure(pdc, color); else { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } } return; } -static void -cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha, - gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, - gs_color_select_t select) -{ - uchar i, ncomps = dev->color_info.num_components; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; - - /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); - - /* pre-multiply to account for the alpha weighting */ - if (alpha != frac_1) { -#ifdef PREMULTIPLY_TOWARDS_WHITE - frac alpha_bias = frac_1 - alpha; -#else - frac alpha_bias = 0; -#endif - - for (i = 0; i < ncomps; i++) - cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias; - } - - /* apply the transfer function(s); convert to color values */ - if (pgs->effective_transfer_non_identity_count != 0) { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pgs, - cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pgs, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); - } - - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, - &pgs->screen_phase[select]) == 1) - gx_color_load_select(pdc, pgs, dev, select); -} - -static void -cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) -{ - uchar i, ncomps = dev->color_info.num_components; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - subclass_color_mappings scm; - - /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); - - /* pre-multiply to account for the alpha weighting */ - if (alpha != frac_1) { -#ifdef PREMULTIPLY_TOWARDS_WHITE - frac alpha_bias = frac_1 - alpha; -#else - frac alpha_bias = 0; -#endif - - for (i = 0; i < ncomps; i++) - cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias; - } - - /* apply the transfer function(s); convert to color values */ - if (pgs->effective_transfer_non_identity_count == 0) - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); - else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pgs, - cm_comps[i], effective_transfer[i])); - else - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); - - /* encode as a color index */ - if (dev_proc(dev, map_rgb_alpha_color) != gx_default_map_rgb_alpha_color && - (cv_alpha = frac2cv(alpha)) != gx_max_color_value) - color = dev_proc(dev, map_rgb_alpha_color)(dev, cv[0], cv[1], cv[2], cv_alpha); - else - color = dev_proc(dev, encode_color)(dev, cv); - - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) { - color_set_pure(pdc, color); - return; - } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, - &pgs->screen_phase[select]) == 1) - gx_color_load_select(pdc, pgs, dev, select); -} - /* ------ Render Separation All color. ------ */ /* @@ -1249,19 +1177,26 @@ cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, * pcolor_component_map - Map from DeviceN to the Devices colorants. * A negative value indicates component is not to be mapped. * plist - Pointer to list for mapped components + * num_comps - num_comps that we need to zero (may be more than + * is set if we are mapping values for an NCLR ICC profile + * via an alternate tint transform for a sep value) -- + * i.e. cmyk+og values and we may have some spots that + * are supported but may have reached the limit and + * using the alt tint values. Need to make sure to zero all. * * Returns: * Mapped components in plist. */ static inline void map_components_to_colorants(const frac * pcc, - const gs_devicen_color_map * pcolor_component_map, frac * plist) + const gs_devicen_color_map * pcolor_component_map, frac * plist, + int num_colorants) { - int i = pcolor_component_map->num_colorants - 1; + int i; int pos; /* Clear all output colorants first */ - for (; i >= 0; i--) { + for (i = num_colorants - 1; i >= 0; i--) { plist[i] = frac_0; } @@ -1426,7 +1361,8 @@ cmap_separation_halftoned(frac all, gx_device_color * pdc, cm_comps[i] = comp_value; } else { /* map to the color model */ - map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } if (devicen_has_cmyk(dev, des_profile) && @@ -1447,7 +1383,7 @@ cmap_separation_halftoned(frac all, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1493,7 +1429,8 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, } else { /* map to the color model */ - map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } /* Check if we have the standard colorants. If yes, then we will apply @@ -1572,7 +1509,7 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1598,7 +1535,8 @@ cmap_devicen_halftoned(const frac * pcc, gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); /* map to the color model */ - map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); /* See comments in cmap_devicen_direct for details on below operations */ if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK && @@ -1618,7 +1556,7 @@ cmap_devicen_halftoned(const frac * pcc, } /* We need to finish halftoning */ - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1647,9 +1585,10 @@ cmap_devicen_direct(const frac * pcc, /* map to the color model */ if (dev_profile->spotnames != NULL && dev_profile->spotnames->equiv_cmyk_set) { map_components_to_colorants(pcc, dev_profile->spotnames->color_map, - cm_comps); + cm_comps, ncomps); } else { - map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } /* Check if we have the standard colorants. If yes, then we will apply ICC color management to those colorants. To understand why, consider @@ -1713,7 +1652,7 @@ cmap_devicen_direct(const frac * pcc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1814,6 +1753,21 @@ gx_default_w_b_map_color_rgb(gx_device * dev, gx_color_index color, return 0; } +gx_color_index +gx_default_w_b_mono_encode_color(gx_device *dev, const gx_color_value cv[]) +{ + return cv[0] > gx_max_color_value / 2 ? (gx_color_index)1 + : (gx_color_index)0; +} + +int +gx_default_w_b_mono_decode_color(gx_device * dev, gx_color_index color, + gx_color_value pgray[1]) +{ /* Map 0 to max_value, 1 to 0. */ + pgray[0] = -(gx_color_value) color; + return 0; +} + /* Black-on-white */ gx_color_index gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[]) @@ -1835,6 +1789,21 @@ gx_default_b_w_map_color_rgb(gx_device * dev, gx_color_index color, return 0; } +gx_color_index +gx_default_b_w_mono_encode_color(gx_device *dev, const gx_color_value cv[]) +{ + return cv[0] > gx_max_color_value / 2 ? (gx_color_index)0 + : (gx_color_index)1; +} + +int +gx_default_b_w_mono_decode_color(gx_device * dev, gx_color_index color, + gx_color_value pgray[1]) +{ /* Map 0 to max_value, 1 to 0. */ + pgray[0] = -((gx_color_value) color ^ 1); + return 0; +} + /* RGB mapping for gray-scale devices */ gx_color_index @@ -1865,6 +1834,26 @@ gx_default_gray_map_color_rgb(gx_device * dev, gx_color_index color, } gx_color_index +gx_default_gray_encode_color(gx_device * dev, const gx_color_value cv[]) +{ + gx_color_value gray = (cv[0] * dev->color_info.max_gray + + (gx_max_color_value / 2)) / gx_max_color_value; + + return gray; +} + +int +gx_default_gray_decode_color(gx_device * dev, gx_color_index color, + gx_color_value *cv) +{ + gx_color_value gray = (gx_color_value) + (color * gx_max_color_value / dev->color_info.max_gray); + + cv[0] = gray; + return 0; +} + +gx_color_index gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[]) { gx_color_index color = gx_color_value_to_byte(cv[0]); @@ -2042,23 +2031,22 @@ cmyk_16bit_map_color_cmyk(gx_device * dev, gx_color_index color, return 0; } -/* Default mapping between RGB+alpha and RGB. */ - -gx_color_index -gx_default_map_rgb_alpha_color(gx_device * dev, - gx_color_value r, gx_color_value g, gx_color_value b, gx_color_value alpha) -{ /* Colors have been premultiplied: we don't need to do it here. */ - gx_color_value cv[3]; - cv[0] = r; cv[1] = g; cv[2] = b; - return (*dev_proc(dev, map_rgb_color))(dev, cv); -} - int -gx_default_map_color_rgb_alpha(gx_device * dev, gx_color_index color, - gx_color_value prgba[4]) -{ - prgba[3] = gx_max_color_value; /* alpha = 1 */ - return (*dev_proc(dev, map_color_rgb)) (dev, color, prgba); +cmyk_16bit_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + gx_color_value c = ((color >> 24) >> 24) & 0xffff; + gx_color_value m = ((color >> 16) >> 16) & 0xffff; + gx_color_value y = ( color >> 16) & 0xffff; + gx_color_value not_k = (~color ) & 0xffff; + int r = not_k - c; + int g = not_k - m; + int b = not_k - y; + + prgb[0] = (r < 0 ? 0 : r); + prgb[1] = (g < 0 ? 0 : g); + prgb[2] = (b < 0 ? 0 : b); + return 0; } frac @@ -2093,7 +2081,7 @@ cmapper_transfer_halftone_add(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2122,7 +2110,7 @@ cmapper_transfer_halftone_op(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2146,7 +2134,7 @@ cmapper_transfer_halftone_sub(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2242,7 +2230,7 @@ cmapper_halftone(gx_cmapper_t *data) cv_frac[i] = cv2frac(pconc[i]); } if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2274,8 +2262,6 @@ gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs, data->select = select; data->devc.type = gx_dc_type_none; data->direct = 0; - if (has_transfer && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); /* Per spec. Images with soft mask, and the mask, do not use transfer function */ if (pgs->effective_transfer_non_identity_count == 0 || (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0) @@ -2286,7 +2272,7 @@ gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs, data->set_color = cmapper_transfer_halftone_add; else data->set_color = cmapper_transfer_add; - } else if (dev->color_info.opmode == GX_CINFO_OPMODE) { + } else if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { if (has_halftone) data->set_color = cmapper_transfer_halftone_op; else @@ -2327,8 +2313,6 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, /* apply the transfer function(s) */ if (has_transfer) { if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); for (i = 0; i < ncomps; i++) cv_frac[i] = cv2frac(pconc[i]); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { @@ -2338,10 +2322,7 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, frac_value, effective_transfer[i]); } } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ uint k = dev->color_info.black_component; for (i = 0; i < ncomps; i++) { frac_value = cv2frac(pconc[i]); @@ -2371,7 +2352,7 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, /* Halftoning */ if (has_halftone) { if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } else { /* We have a frac value from the transfer function. Do the encode. @@ -2396,17 +2377,12 @@ cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev) /* apply the transfer function(s) */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) pconc[i] = frac2cv(gx_map_color_frac(pgs, cv2frac(pconc[i]), effective_transfer[i])); else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, @@ -2433,10 +2409,7 @@ cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, cv_frac = gx_map_color_frac(pgs, frac_value, effective_transfer[plane]); pconc[0] = frac2cv(cv_frac); } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ uint k = dev->color_info.black_component; if (plane == k) { frac_value = cv2frac(pconc[0]); @@ -2457,7 +2430,6 @@ cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, bool gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs) { - subclass_color_mappings scm; const gx_cm_color_map_procs *pprocs; gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; @@ -2468,16 +2440,10 @@ gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs) dev_profile, &des_profile, &render_cond); if (des_profile != NULL) { - scm = get_color_mapping_procs_subclass(dev); - pprocs = scm.procs; - /* FIXME: This looks wrong to me. Presumably we should be finding - * the parentmost device, looking at the procs for that, and if - * they are forwarding ones, getting the procs for the forwarded - * device. This is NOT what this code does. */ + const gx_device *cmdev; + + pprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* Check if they are forwarding procs */ - if (fwd_uses_fwd_cmap_procs(dev)) { - pprocs = fwd_get_target_cmap_procs(dev); - } switch(des_profile->num_comps) { case 1: if (pprocs == &DeviceGray_procs) { diff --git a/base/gxcmap.h b/base/gxcmap.h index b626e632..4197a48d 100644 --- a/base/gxcmap.h +++ b/base/gxcmap.h @@ -38,9 +38,6 @@ void proc(frac, frac, frac, frac, gx_device_color *,\ const gs_gstate *, gx_device *, gs_color_select_t,\ const gs_color_space *) -#define cmap_proc_rgb_alpha(proc)\ - void proc(frac, frac, frac, frac, gx_device_color *,\ - const gs_gstate *, gx_device *, gs_color_select_t) #define cmap_proc_separation(proc)\ void proc(frac, gx_device_color *, const gs_gstate *,\ gx_device *, gs_color_select_t, const gs_color_space *) @@ -55,17 +52,17 @@ * device color model. Any unused component will be mapped to 0. */ #define cm_map_proc_gray(proc) \ - void proc (gx_device * dev, frac gray, \ + void proc (const gx_device * dev, frac gray, \ frac * out) #define cm_map_proc_rgb(proc) \ - void proc (gx_device * dev, \ + void proc (const gx_device * dev, \ const gs_gstate *pgs, \ frac r, frac g, frac b, \ frac * out) #define cm_map_proc_cmyk(proc) \ - void proc (gx_device * dev, \ + void proc (const gx_device * dev, \ frac c, frac m, frac y, frac k, \ frac * out) @@ -110,7 +107,6 @@ struct gx_color_map_procs_s { cmap_proc_gray((*map_gray)); cmap_proc_rgb((*map_rgb)); cmap_proc_cmyk((*map_cmyk)); - cmap_proc_rgb_alpha((*map_rgb_alpha)); cmap_proc_separation((*map_separation)); cmap_proc_devicen((*map_devicen)); cmap_proc_is_halftoned((*is_halftoned)); @@ -142,8 +138,6 @@ void gx_set_cmap_procs(gs_gstate *, const gx_device *); ((pgs)->cmap_procs->map_rgb)(cr, cg, cb, pdc, pgs, dev, select) #define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pgs, dev, select, pcs)\ ((pgs)->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pgs, dev, select, pcs) -#define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pgs, dev, select)\ - ((pgs)->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pgs, dev, select) #define gx_remap_concrete_separation(pcc, pdc, pgs, dev, select, pcs)\ ((pgs)->cmap_procs->map_separation)(pcc, pdc, pgs, dev, select, pcs) #define gx_remap_concrete_devicen(pcc, pdc, pgs, dev, select, pcs)\ @@ -158,7 +152,7 @@ void gx_set_cmap_procs(gs_gstate *, const gx_device *); color model. */ #define dev_t_proc_get_color_mapping_procs(proc, dev_t) \ - const gx_cm_color_map_procs * (proc)(const dev_t * dev) + const gx_cm_color_map_procs * (proc)(const dev_t * dev, const gx_device **) #define dev_proc_get_color_mapping_procs(proc) \ dev_t_proc_get_color_mapping_procs(proc, gx_device) @@ -262,8 +256,6 @@ frac gx_unit_frac(float fvalue); images */ bool gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs); -bool fwd_uses_fwd_cmap_procs(gx_device * dev); -const gx_cm_color_map_procs* fwd_get_target_cmap_procs(gx_device * dev); void cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, bool has_transfer, bool has_halftone, gs_color_select_t select); @@ -290,4 +282,8 @@ void gx_get_cmapper(gx_cmapper_t *cmapper, const gs_gstate *pgs, gx_device *dev, bool has_transfer, bool has_halftone, gs_color_select_t select); +/* Return the dev_ht[] selected by the pgs->device->graphics_tag */ +/* or the pgs->dev_ht[HT_OBJTYPE_DEFAULT] */ +gx_device_halftone *gx_select_dev_ht(const gs_gstate *pgs); + #endif /* gxcmap_INCLUDED */ diff --git a/base/gxcspace.h b/base/gxcspace.h index 40fbee16..56f2d183 100644 --- a/base/gxcspace.h +++ b/base/gxcspace.h @@ -152,7 +152,7 @@ struct gs_color_space_type_s { /* Free contents of composite colorspace objects. */ #define cs_proc_final(proc)\ - void proc(const gs_color_space *) + void proc(gs_color_space *) cs_proc_final((*final)); /* Adjust reference counts of indirect color components. */ @@ -166,29 +166,8 @@ struct gs_color_space_type_s { #define cs_proc_adjust_color_count(proc)\ void proc(const gs_client_color *, const gs_color_space *, int) - /* Adjust the color reference counts for the current space. */ -#define cs_adjust_color_count(pgs, delta)\ - (*gs_currentcolorspace_inline(pgs)->type->adjust_color_count)\ - (gs_currentcolor_inline(pgs), gs_currentcolorspace_inline(pgs), delta) - /* Adjust the color reference counts for the swapped space (i.e. - * the one that is not current). */ -#define cs_adjust_swappedcolor_count(pgs, delta)\ - (*gs_swappedcolorspace_inline(pgs)->type->adjust_color_count)\ - (gs_swappedcolor_inline(pgs), gs_swappedcolorspace_inline(pgs), delta) - cs_proc_adjust_color_count((*adjust_color_count)); -/* Adjust both reference counts for the current color/colorspace. */ -#define cs_adjust_counts(pgs, delta)\ - cs_adjust_color_count(pgs, delta); \ - rc_adjust_const(gs_currentcolorspace_inline(pgs), delta, "cs_adjust_counts") - -/* Adjust both reference counts for the swapped (i.e. non-current) - * color/colorspace. */ -#define cs_adjust_swappedcounts(pgs, delta)\ - cs_adjust_swappedcolor_count(pgs, delta); \ - rc_adjust_const(gs_swappedcolorspace_inline(pgs), delta, "cs_adjust_swappedcounts") - /* Serialization. */ /* * Note : We don't include *(pcs)->type into serialization, diff --git a/base/gxdcolor.c b/base/gxdcolor.c index 20116fd8..87de8001 100644 --- a/base/gxdcolor.c +++ b/base/gxdcolor.c @@ -107,14 +107,15 @@ gx_color_index gx_device_black(gx_device *dev) { if (dev->cached_colors.black == gx_no_color_index) { - subclass_color_mappings scm; uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; - scm = get_color_mapping_procs_subclass(dev); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* Get color components for black (gray = 0) */ - map_gray_subclass(scm, frac_0, cm_comps); + cmprocs->map_gray(cmdev, frac_0, cm_comps); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); @@ -127,14 +128,15 @@ gx_color_index gx_device_white(gx_device *dev) { if (dev->cached_colors.white == gx_no_color_index) { - subclass_color_mappings scm; uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; - scm = get_color_mapping_procs_subclass(dev); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* Get color components for white (gray = 1) */ - map_gray_subclass(scm, frac_1, cm_comps); + cmprocs->map_gray(cmdev, frac_1, cm_comps); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); @@ -563,14 +565,20 @@ gx_devn_write_color( uchar ncomps = cdev->clist_color_info.num_components; /* Could be different than target if 1.4 device */ gx_color_index mask = 0x1, comp_bits = 0; + if_debug1m(gs_debug_flag_clist_color, dev->memory, + "[clist_color] Writing devn color, %d components [ ", ncomps); + /* First find the number of non zero values */ for (i = 0; i < ncomps; i++, mask <<= 1) { + if_debug1m(gs_debug_flag_clist_color, dev->memory, + "%d ", pdevc->colors.devn.values[i]); if (pdevc->colors.devn.values[i] != 0) { comp_bits |= mask; count++; } } mask = comp_bits; + if_debug0m(gs_debug_flag_clist_color, dev->memory, "]\n"); num_bytes1 = sizeof(gx_color_index); num_bytes = num_bytes1 + count * 2 + 1; /* One for the tag byte */ @@ -706,6 +714,9 @@ gx_devn_read_color( pos++; num_bytes++; + if_debug1m(gs_debug_flag_clist_color, dev->memory, + "[clist_color] Reading devn color, %d components [ ", ncomps); + /* Now the data */ for (i = 0; i < ncomps; i++) { if (mask & 1) { @@ -717,8 +728,11 @@ gx_devn_read_color( } else { values[i] = 0; } + if_debug1m(gs_debug_flag_clist_color, dev->memory, + "%d ", values[i]); mask >>= 1; } + if_debug0m(gs_debug_flag_clist_color, dev->memory, "]\n"); return num_bytes; } @@ -826,13 +840,7 @@ gx_dc_pure_fill_rectangle(const gx_device_color * pdevc, int x, int y, colors[0] = colors[1] = pdevc->colors.pure; if (source == NULL) set_rop_no_source(source, no_source, dev); - if (source->planar_height == 0) - return (*dev_proc(dev, strip_copy_rop)) - (dev, source->sdata, source->sourcex, source->sraster, - source->id, (source->use_scolors ? source->scolors : NULL), - NULL /*arbitrary */ , colors, x, y, w, h, 0, 0, lop); - else - return (*dev_proc(dev, strip_copy_rop2)) + return (*dev_proc(dev, strip_copy_rop2)) (dev, source->sdata, source->sourcex, source->sraster, source->id, (source->use_scolors ? source->scolors : NULL), NULL /*arbitrary */ , colors, x, y, w, h, 0, 0, lop, source->planar_height); @@ -874,10 +882,10 @@ gx_dc_pure_fill_masked(const gx_device_color * pdevc, const byte * data, if (!rop3_uses_S(lop)) lop |= rop3_S; - return (*dev_proc(dev, strip_copy_rop)) + return (*dev_proc(dev, strip_copy_rop2)) (dev, data, data_x, raster, id, scolors, NULL, tcolors, x, y, w, h, 0, 0, - lop_sanitize(lop | lop_S_transparent)); + lop_sanitize(lop | lop_S_transparent), 0); } } @@ -1018,7 +1026,6 @@ gx_complete_halftone(gx_device_color *pdevc, int num_comps, gx_device_halftone * pdevc->type = gx_dc_type_ht_colored; pdevc->colors.colored.c_ht = pdht; pdevc->colors.colored.num_components = num_comps; - pdevc->colors.colored.alpha = max_ushort; for (i = 0; i < num_comps; i++) mask |= ((pdevc->colors.colored.c_level[i] != 0 ? 1 : 0) << i); pdevc->colors.colored.plane_mask = mask; @@ -1146,8 +1153,11 @@ gx_dc_write_color( /* check for adequate space */ if (*psize < num_bytes) { + uint x = *psize; *psize = num_bytes; - return_error(gs_error_rangecheck); + if (x != 0) + return_error(gs_error_rangecheck); + return gs_error_rangecheck; } *psize = num_bytes; diff --git a/base/gxdevcli.h b/base/gxdevcli.h index f41f8d11..9364349c 100644 --- a/base/gxdevcli.h +++ b/base/gxdevcli.h @@ -116,7 +116,7 @@ /* ---------------- Auxiliary types and structures ---------------- */ /* We need an abstract type for the pattern instance, */ -/* for pattern_manage. */ +/* for pattern management. */ typedef struct gs_pattern1_instance_s gs_pattern1_instance_t; /* Define the type for colors passed to the higher-level procedures. */ @@ -241,10 +241,10 @@ typedef enum { * */ typedef enum { - GX_CINFO_OPMODE_UNKNOWN = -1, - GX_CINFO_OPMODE_NOT = 0, - GX_CINFO_OPMODE = 1 -} gx_cm_opmode_t; + GX_CINFO_OPMSUPPORTED_UNKNOWN = -1, + GX_CINFO_OPMSUPPORTED_NOT = 0, + GX_CINFO_OPMSUPPORTED = 1 +} gx_cm_opmsupported_t; /* component index value used to indicate no color component. */ #define GX_CINFO_COMP_NO_INDEX 0xff @@ -420,15 +420,12 @@ typedef struct gx_device_color_info_s { * Most such color spaces will have the name DeviceCMYK, but it is * also possible for DeviceN color models this behavior. * - * If opmode has the value GX_CINFO_OPMODE, the process_comps will + * If opmsupported has the value GX_CINFO_OPMSUPPORTED, the process_comps will * be a bit mask, with the (1 << i) bit set if i'th component is the * cyan, magenta, yellow, or black component and black_component will * be set to the index of a black component. - * - * A new mode GX_CINFO_OPMODE_RGB was added so that an RGB device could - * simulate CMYK overprinting. */ - gx_cm_opmode_t opmode; + gx_cm_opmsupported_t opmsupported; gx_color_index process_comps; uint black_component; bool use_antidropout_downscaler; @@ -459,7 +456,7 @@ static inline int colors_are_separable_and_linear(gx_device_color_info *info) { 0 } /* component bits */, \ { 0 } /* component mask */, \ cn /* process color name */, \ - GX_CINFO_OPMODE_UNKNOWN /* opmode */, \ + GX_CINFO_OPMSUPPORTED_UNKNOWN /* opmsupported */, \ 0 /* process_cmps */ } /* @@ -643,21 +640,15 @@ typedef struct gx_stroked_gradient_recognizer_s { /* ---------------- Device structure ---------------- */ /* - * Define the generic device structure. The device procedures can - * have two different configurations: - * - * - Statically initialized devices predating release 2.8.1 - * set the static_procs pointer to point to a separate procedure record, - * and do not initialize procs. + * Define the generic device structure. * - * - Statically initialized devices starting with release 2.8.1, - * and all dynamically created device instances, - * set the static_procs pointer to 0, and initialize procs. + * All devices start off with no device procs. The initialize_device_procs + * function is called as soon as the device is copied from its prototype, + * and that fills in the procs table with the device procedure pointers. + * This can never fail. * - * The gx_device_set_procs procedure converts the first of these to - * the second, which is what all client code starting in 2.8.1 expects - * (using the procs record, not the static_procs pointer, to call the - * driver procedures). + * Next, the 'initialize_device' proc (if there is one) is called to do + * the minimal initialization required for a device. * * The choice of the name Margins (rather than, say, HWOffset), and the * specification in terms of a default device resolution rather than @@ -717,11 +708,16 @@ typedef struct gdev_pagelist_s { int PagesSize; } gdev_pagelist; +#define dev_t_proc_initialize_device_procs(proc, dev_t)\ + void proc(dev_t *dev) +#define dev_proc_initialize_device_procs(proc)\ + dev_t_proc_initialize_device_procs((proc), gx_device) + #define gx_device_common\ int params_size; /* OBSOLETE if stype != 0: */\ /* size of this structure */\ - const gx_device_procs *static_procs; /* OBSOLETE */\ - /* pointer to procs */\ + dev_proc_initialize_device_procs(*initialize_device_procs);\ + /* initialize_device_procs */\ const char *dname; /* the device name */\ gs_memory_t *memory; /* (0 iff static prototype) */\ gs_memory_type_ptr_t stype; /* memory manager structure type, */\ @@ -864,6 +860,11 @@ typedef enum FILTER_FLAGS { /* Define macros for declaring device procedures. */ +#define dev_t_proc_initialize_device(proc, dev_t)\ + int proc(dev_t *dev) +#define dev_proc_initialize_device(proc)\ + dev_t_proc_initialize_device(proc, gx_device) + #define dev_t_proc_open_device(proc, dev_t)\ int proc(dev_t *dev) #define dev_proc_open_device(proc)\ @@ -906,14 +907,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_fill_rectangle(proc)\ dev_t_proc_fill_rectangle(proc, gx_device) -#define dev_t_proc_tile_rectangle(proc, dev_t)\ - int proc(dev_t *dev,\ - const gx_tile_bitmap *tile, int x, int y, int width, int height,\ - gx_color_index color0, gx_color_index color1,\ - int phase_x, int phase_y) -#define dev_proc_tile_rectangle(proc)\ - dev_t_proc_tile_rectangle(proc, gx_device) - #define dev_t_proc_copy_mono(proc, dev_t)\ int proc(dev_t *dev,\ const byte *data, int data_x, int raster, gx_bitmap_id id,\ @@ -929,22 +922,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_copy_color(proc)\ dev_t_proc_copy_color(proc, gx_device) - /* OBSOLETED in release 3.66 */ - -#define dev_t_proc_draw_line(proc, dev_t)\ - int proc(dev_t *dev,\ - int x0, int y0, int x1, int y1, gx_color_index color) -#define dev_proc_draw_line(proc)\ - dev_t_proc_draw_line(proc, gx_device) - - /* Added in release 2.4 */ - -#define dev_t_proc_get_bits(proc, dev_t)\ - int proc(dev_t *dev,\ - int y, byte *data, byte **actual_data) -#define dev_proc_get_bits(proc)\ - dev_t_proc_get_bits(proc, gx_device) - /* Added in release 2.4, changed in 2.8, */ /* renamed in 2.9.6 */ @@ -965,27 +942,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_map_cmyk_color(proc)\ dev_t_proc_map_cmyk_color(proc, gx_device) -#define dev_t_proc_get_xfont_procs(proc, dev_t)\ - const gx_xfont_procs *proc(dev_t *dev) -#define dev_proc_get_xfont_procs(proc)\ - dev_t_proc_get_xfont_procs(proc, gx_device) - - /* Added in release 2.6.1 */ - -#define dev_t_proc_get_xfont_device(proc, dev_t)\ - gx_device *proc(dev_t *dev) -#define dev_proc_get_xfont_device(proc)\ - dev_t_proc_get_xfont_device(proc, gx_device) - - /* Added in release 2.7.1 */ - -#define dev_t_proc_map_rgb_alpha_color(proc, dev_t)\ - gx_color_index proc(dev_t *dev,\ - gx_color_value red, gx_color_value green, gx_color_value blue,\ - gx_color_value alpha) -#define dev_proc_map_rgb_alpha_color(proc)\ - dev_t_proc_map_rgb_alpha_color(proc, gx_device) - /* Added in release 2.8.1 */ #define dev_t_proc_get_page_device(proc, dev_t)\ @@ -994,6 +950,7 @@ typedef enum FILTER_FLAGS { dev_t_proc_get_page_device(proc, gx_device) /* Added in release 3.20, OBSOLETED in 5.65 */ + /* 'Unobsoleted' in 9.55. */ #define dev_t_proc_get_alpha_bits(proc, dev_t)\ int proc(dev_t *dev, graphics_object_type type) @@ -1009,25 +966,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_copy_alpha(proc)\ dev_t_proc_copy_alpha(proc, gx_device) - /* Added in release 3.38 */ - -#define dev_t_proc_get_band(proc, dev_t)\ - int proc(dev_t *dev, int y, int *band_start) -#define dev_proc_get_band(proc)\ - dev_t_proc_get_band(proc, gx_device) - - /* Added in release 3.44 */ - -#define dev_t_proc_copy_rop(proc, dev_t)\ - int proc(dev_t *dev,\ - const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id,\ - const gx_color_index *scolors,\ - const gx_tile_bitmap *texture, const gx_color_index *tcolors,\ - int x, int y, int width, int height,\ - int phase_x, int phase_y, gs_logical_operation_t lop) -#define dev_proc_copy_rop(proc)\ - dev_t_proc_copy_rop(proc, gx_device) - /* Added in release 3.60, changed in 3.68. */ #define dev_t_proc_fill_path(proc, dev_t)\ @@ -1107,37 +1045,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_draw_thin_line(proc)\ dev_t_proc_draw_thin_line(proc, gx_device) - /* Added in release 3.66 (as stubs); */ - /* changed in 3.68; */ - /* begin_image and image_data changed in 4.30, */ - /* begin_image changed in 5.23. */ - -#define dev_t_proc_begin_image(proc, dev_t)\ - int proc(dev_t *dev,\ - const gs_gstate *pgs, const gs_image_t *pim,\ - gs_image_format_t format, const gs_int_rect *prect,\ - const gx_drawing_color *pdcolor, const gx_clip_path *pcpath,\ - gs_memory_t *memory, gx_image_enum_common_t **pinfo) -#define dev_proc_begin_image(proc)\ - dev_t_proc_begin_image(proc, gx_device) - - /* OBSOLETED in release 5.23 */ - -#define dev_t_proc_image_data(proc, dev_t)\ - int proc(dev_t *dev,\ - gx_image_enum_common_t *info, const byte **planes, int data_x,\ - uint raster, int height) -#define dev_proc_image_data(proc)\ - dev_t_proc_image_data(proc, gx_device) - - /* OBSOLETED in release 5.23 */ - -#define dev_t_proc_end_image(proc, dev_t)\ - int proc(dev_t *dev,\ - gx_image_enum_common_t *info, bool draw_last) -#define dev_proc_end_image(proc)\ - dev_t_proc_end_image(proc, gx_device) - /* Added in release 3.68 */ #define dev_t_proc_strip_tile_rectangle(proc, dev_t)\ @@ -1148,16 +1055,6 @@ typedef enum FILTER_FLAGS { #define dev_proc_strip_tile_rectangle(proc)\ dev_t_proc_strip_tile_rectangle(proc, gx_device) -#define dev_t_proc_strip_copy_rop(proc, dev_t)\ - int proc(dev_t *dev,\ - const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id,\ - const gx_color_index *scolors,\ - const gx_strip_bitmap *textures, const gx_color_index *tcolors,\ - int x, int y, int width, int height,\ - int phase_x, int phase_y, gs_logical_operation_t lop) -#define dev_proc_strip_copy_rop(proc)\ - dev_t_proc_strip_copy_rop(proc, gx_device) - /* Added in release 4.20 */ #define dev_t_proc_get_clipping_box(proc, dev_t)\ @@ -1180,22 +1077,16 @@ typedef enum FILTER_FLAGS { #define dev_t_proc_get_bits_rectangle(proc, dev_t)\ int proc(dev_t *dev, const gs_int_rect *prect,\ - gs_get_bits_params_t *params, gs_int_rect **unread) + gs_get_bits_params_t *params) #define dev_proc_get_bits_rectangle(proc)\ dev_t_proc_get_bits_rectangle(proc, gx_device) -#define dev_t_proc_map_color_rgb_alpha(proc, dev_t)\ - int proc(dev_t *dev,\ - gx_color_index color, gx_color_value rgba[4]) -#define dev_proc_map_color_rgb_alpha(proc)\ - dev_t_proc_map_color_rgb_alpha(proc, gx_device) - -#define dev_t_proc_create_compositor(proc, dev_t)\ +#define dev_t_proc_composite(proc, dev_t)\ int proc(dev_t *dev,\ gx_device **pcdev, const gs_composite_t *pcte,\ gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) -#define dev_proc_create_compositor(proc)\ - dev_t_proc_create_compositor(proc, gx_device)\ +#define dev_proc_composite(proc)\ + dev_t_proc_composite(proc, gx_device)\ /* Added in release 5.23 */ @@ -1208,13 +1099,6 @@ typedef enum FILTER_FLAGS { /* ... text_begin ... see gstext.h for definition */ - /* Added in release 6.23 */ - -#define dev_t_proc_finish_copydevice(proc, dev_t)\ - int proc(dev_t *dev, const gx_device *from_dev) -#define dev_proc_finish_copydevice(proc)\ - dev_t_proc_finish_copydevice(proc, gx_device) - /* Added in release 6.61 (raph) */ /* @@ -1306,38 +1190,6 @@ typedef enum FILTER_FLAGS { /* (end of DeviceN color support) */ /* - Pattern management for high level devices. - Now we need it for PatternType 1 only. - Return codes : - 1 - the device handles high level patterns. - 0 - the device needs low level pattern tiles. - <0 - error. - - THIS IS NOW DEPRECATED, AND UNUSED. DO NOT USE THIS. USE THIS NOT. THIS - IS NOT TO BE USED. - - Pattern Management is now done using the dev_spec_op calls. -*/ - -/* High level device support. */ -typedef enum { - pattern_manage__can_accum, - pattern_manage__start_accum, - pattern_manage__finish_accum, - pattern_manage__load, - pattern_manage__shading_area, - pattern_manage__is_cpath_accum, - pattern_manage__shfill_doesnt_need_path, - pattern_manage__handles_clip_path -} pattern_manage_t; - -#define dev_t_proc_pattern_manage(proc, dev_t)\ - int proc(gx_device *pdev, gx_bitmap_id id,\ - gs_pattern1_instance_t *pinst, pattern_manage_t function) -#define dev_proc_pattern_manage(proc)\ - dev_t_proc_pattern_manage(proc, gx_device) - -/* Fill rectangle with a high level color. Return rangecheck, if the device can't handle the high level color. @@ -1457,6 +1309,8 @@ typedef struct gs_devn_params_s gs_devn_params; gs_devn_params * proc(dev_t *dev) #define dev_proc_ret_devn_params(proc)\ dev_t_proc_ret_devn_params(proc, gx_device) +#define dev_proc_ret_devn_params_const(proc)\ + const dev_t_proc_ret_devn_params(proc, const gx_device) /* * Erase page. @@ -1499,7 +1353,7 @@ typedef struct gs_devn_params_s gs_devn_params; dev_t_proc_copy_planes(proc, gx_device) #define dev_t_proc_get_profile(proc, dev_t)\ - int proc(dev_t *dev, cmm_dev_profile_t **dev_profile) + int proc(const dev_t *dev, cmm_dev_profile_t **dev_profile) #define dev_proc_get_profile(proc)\ dev_t_proc_get_profile(proc, gx_device) @@ -1592,7 +1446,9 @@ typedef struct { /* Define the device procedure vector template proper. */ #define gx_device_proc_struct(dev_t)\ -{ dev_t_proc_open_device((*open_device), dev_t);\ +{\ + dev_t_proc_initialize_device((*initialize_device), dev_t);\ + dev_t_proc_open_device((*open_device), dev_t);\ dev_t_proc_get_initial_matrix((*get_initial_matrix), dev_t);\ dev_t_proc_sync_output((*sync_output), dev_t);\ dev_t_proc_output_page((*output_page), dev_t);\ @@ -1600,22 +1456,14 @@ typedef struct { dev_t_proc_map_rgb_color((*map_rgb_color), dev_t);\ dev_t_proc_map_color_rgb((*map_color_rgb), dev_t);\ dev_t_proc_fill_rectangle((*fill_rectangle), dev_t);\ - dev_t_proc_tile_rectangle((*tile_rectangle), dev_t);\ dev_t_proc_copy_mono((*copy_mono), dev_t);\ dev_t_proc_copy_color((*copy_color), dev_t);\ - dev_t_proc_draw_line((*obsolete_draw_line), dev_t);\ - dev_t_proc_get_bits((*get_bits), dev_t);\ dev_t_proc_get_params((*get_params), dev_t);\ dev_t_proc_put_params((*put_params), dev_t);\ dev_t_proc_map_cmyk_color((*map_cmyk_color), dev_t);\ - dev_t_proc_get_xfont_procs((*get_xfont_procs), dev_t);\ - dev_t_proc_get_xfont_device((*get_xfont_device), dev_t);\ - dev_t_proc_map_rgb_alpha_color((*map_rgb_alpha_color), dev_t);\ dev_t_proc_get_page_device((*get_page_device), dev_t);\ dev_t_proc_get_alpha_bits((*get_alpha_bits), dev_t);\ dev_t_proc_copy_alpha((*copy_alpha), dev_t);\ - dev_t_proc_get_band((*get_band), dev_t);\ - dev_t_proc_copy_rop((*copy_rop), dev_t);\ dev_t_proc_fill_path((*fill_path), dev_t);\ dev_t_proc_stroke_path((*stroke_path), dev_t);\ dev_t_proc_fill_mask((*fill_mask), dev_t);\ @@ -1623,19 +1471,13 @@ typedef struct { dev_t_proc_fill_parallelogram((*fill_parallelogram), dev_t);\ dev_t_proc_fill_triangle((*fill_triangle), dev_t);\ dev_t_proc_draw_thin_line((*draw_thin_line), dev_t);\ - dev_t_proc_begin_image((*begin_image), dev_t);\ - dev_t_proc_image_data((*image_data), dev_t);\ - dev_t_proc_end_image((*end_image), dev_t);\ dev_t_proc_strip_tile_rectangle((*strip_tile_rectangle), dev_t);\ - dev_t_proc_strip_copy_rop((*strip_copy_rop), dev_t);\ dev_t_proc_get_clipping_box((*get_clipping_box), dev_t);\ dev_t_proc_begin_typed_image((*begin_typed_image), dev_t);\ dev_t_proc_get_bits_rectangle((*get_bits_rectangle), dev_t);\ - dev_t_proc_map_color_rgb_alpha((*map_color_rgb_alpha), dev_t);\ - dev_t_proc_create_compositor((*create_compositor), dev_t);\ + dev_t_proc_composite((*composite), dev_t);\ dev_t_proc_get_hardware_params((*get_hardware_params), dev_t);\ dev_t_proc_text_begin((*text_begin), dev_t);\ - dev_t_proc_finish_copydevice((*finish_copydevice), dev_t);\ dev_t_proc_begin_transparency_group((*begin_transparency_group), dev_t);\ dev_t_proc_end_transparency_group((*end_transparency_group), dev_t);\ dev_t_proc_begin_transparency_mask((*begin_transparency_mask), dev_t);\ @@ -1645,7 +1487,6 @@ typedef struct { dev_t_proc_get_color_comp_index((*get_color_comp_index), dev_t); \ dev_t_proc_encode_color((*encode_color), dev_t); \ dev_t_proc_decode_color((*decode_color), dev_t); \ - dev_t_proc_pattern_manage((*pattern_manage), dev_t); \ dev_t_proc_fill_rectangle_hl_color((*fill_rectangle_hl_color), dev_t); \ dev_t_proc_include_color_space((*include_color_space), dev_t); \ dev_t_proc_fill_linear_color_scanline((*fill_linear_color_scanline), dev_t); \ @@ -1682,9 +1523,6 @@ typedef struct gx_image_plane_s { uint raster; } gx_image_plane_t; -#define gx_device_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo)\ - ((*dev_proc(dev, begin_image))\ - (dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo)) #define gx_device_begin_typed_image(dev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)\ ((*dev_proc(dev, begin_typed_image))\ (dev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)) @@ -1704,13 +1542,6 @@ int gx_image_flush(gx_image_enum_common_t *info); bool gx_image_planes_wanted(const gx_image_enum_common_t *info, byte *wanted); int gx_image_end(gx_image_enum_common_t *info, bool draw_last); -/* - * Get the anti-aliasing parameters for a device. This replaces the - * obsolete get_alpha_bits device procedure. - */ -#define gx_device_get_alpha_bits(dev, type)\ - gx_default_get_alpha_bits(dev, type) - /* A generic device procedure record. */ struct gx_device_procs_s gx_device_proc_struct(gx_device); @@ -1778,70 +1609,6 @@ extern_st(st_device_forward); device_forward_reloc_ptrs, gx_device_finalize) #define st_device_forward_max_ptrs (st_device_max_ptrs + 1) -/* The color mapping procs were used in a way which defeats a 'pipeline' - * approach to devices. Certain graphics library routines (eg images) - * called the color mapping procs *directly* from the device procs of the - * current (ie terminal) device. This prevented any pipeline approach from - * working as earlier devices in the chain wouldn't see the call. In particular - * this prevented the use of such a device to do 'monochrome mode' in PCL - * (see pcpalet.c, pcl_update_mono). This macro walks back up the pipeline - * and retrieves the uppermost device color_mapping procs. - */ -typedef struct { - gx_cm_color_map_procs *procs; - gx_device *dev; -} subclass_color_mappings; - -static inline gx_device * -subclass_parentmost_device(gx_device *dev) -{ - while (dev->parent) - dev = dev->parent; - return dev; -} - -extern const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev); - -static inline -subclass_color_mappings get_color_mapping_procs_subclass(gx_device *dev) -{ - subclass_color_mappings sc; - gx_device *d; - sc.dev = NULL; - - d = subclass_parentmost_device(dev); - while (d->procs.get_color_mapping_procs == default_subclass_get_color_mapping_procs) { - if (d->child) - d = d->child; - else { - break; - } - } - sc.dev = d; - - sc.procs = (gx_cm_color_map_procs *)(dev_proc(sc.dev, get_color_mapping_procs) == NULL ? - NULL : dev_proc(sc.dev, get_color_mapping_procs)(sc.dev)); - return sc; -} - -static inline -void map_rgb_subclass(const subclass_color_mappings scm, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) -{ - scm.procs->map_rgb(scm.dev, pgs, r, g, b, out); -} - -static inline -void map_gray_subclass(const subclass_color_mappings scm, frac gray, frac out[]) -{ - scm.procs->map_gray(scm.dev, gray, out); -} - -static inline -void map_cmyk_subclass(const subclass_color_mappings scm, frac c, frac m, frac y, frac k, frac out[]) -{ - scm.procs->map_cmyk(scm.dev, c, m, y, k, out); -} - /* Test to see if the device wants to use tags */ static inline bool device_encodes_tags(const gx_device *dev) { @@ -1885,13 +1652,16 @@ extern_st(st_device_null); * about what this means. Normally, devices created for temporary use have * internal = true (retained = false). */ -void gx_device_init(gx_device * dev, const gx_device * proto, - gs_memory_t * mem, bool internal); +int gx_device_init(gx_device * dev, const gx_device * proto, + gs_memory_t * mem, bool internal); /* * Identical to gx_device_init, except that the reference counting is set * up so that it doesn't attempt to free the device structure when the last * instance is removed, and the device is always internal (never retained). + * + * If the device uses an initialize proc (and it should!) it can never + * fail. */ void gx_device_init_on_stack(gx_device * dev, const gx_device * proto, gs_memory_t * mem); @@ -1984,4 +1754,25 @@ bool gx_color_info_equal(const gx_device_color_info *p1, const gx_device_color_i /* Perform a callout to registered handlers from the device. */ int gx_callout(gx_device *dev, int id, int size, void *data); +static inline +gx_cm_opmsupported_t gx_get_opmsupported(gx_device *dev) +{ + if (dev->color_info.opmsupported != GX_CINFO_OPMSUPPORTED_UNKNOWN) + return dev->color_info.opmsupported; + + (void)check_cmyk_color_model_comps(dev); + + return dev->color_info.opmsupported; +} + +static inline +gx_color_index gx_get_process_comps(gx_device *dev) +{ + if (dev->color_info.opmsupported != GX_CINFO_OPMSUPPORTED_UNKNOWN) + return dev->color_info.process_comps; + + return check_cmyk_color_model_comps(dev); +} + + #endif /* gxdevcli_INCLUDED */ diff --git a/base/gxdevice.h b/base/gxdevice.h index c757fa2d..ce69c72d 100644 --- a/base/gxdevice.h +++ b/base/gxdevice.h @@ -98,8 +98,8 @@ * Note also that the macro does not initialize procs, which is * the next element of the structure. */ - #define std_device_part1_(devtype, ptr_procs, dev_name, stype, open_init)\ - sizeof(devtype), ptr_procs, dev_name,\ + #define std_device_part1_(devtype, init, dev_name, stype, open_init)\ + sizeof(devtype), init, dev_name,\ 0 /*memory*/, stype, 0 /*stype_is_dynamic*/, 0 /*finalize*/,\ { 0 } /*rc*/, 0 /*retained*/, 0 /* parent */, 0 /* child */, 0 /* subclass_data */, 0 /* PageList */,\ open_init() /*is_open, max_fill_band*/ @@ -118,7 +118,7 @@ { x_dpi, y_dpi }/*HWResolution*/ /* offsets and margins go here */ -#define std_device_part3_()\ +#define std_device_part3_sc(ins, bp, ep)\ 0/*FirstPage*/, 0/*LastPage*/, 0/*PageHandlerPushed*/, 0/*DisablePageHandler*/,\ 0/* Object Filter*/, 0/*ObjectHandlerPushed*/,\ 0, /* NupControl */ 0, /* NupHandlerPushed */\ @@ -135,7 +135,10 @@ 0/*Profile Array*/,\ 0/* graphics_type_tag default GS_UNTOUCHED_TAG */,\ 1/* interpolate_control default 1, uses image /Interpolate flag, full device resolution */,\ - { gx_default_install, gx_default_begin_page, gx_default_end_page } + { ins, bp, ep } +#define std_device_part3_()\ + std_device_part3_sc(gx_default_install, gx_default_begin_page, gx_default_end_page) + /* * We need a number of different variants of the std_device_ macro simply * because we can't pass the color_info or offsets/margins @@ -151,91 +154,101 @@ * 6 for margins/offset). * */ -#define std_device_body_with_macros_(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, open_init, dci_macro, margins_macro)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init),\ +#define std_device_body_with_macros_(dtype, init, dname, stype, w, h, xdpi, ydpi, open_init, dci_macro, margins_macro)\ + std_device_part1_(dtype, init, dname, stype, open_init),\ dci_macro(),\ std_device_part2_(w, h, xdpi, ydpi),\ margins_macro(),\ std_device_part3_() -#define std_device_std_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi)\ - std_device_body_with_macros_(dtype, pprocs, dname, stype,\ +#define std_device_std_body_type(dtype, init, dname, stype, w, h, xdpi, ydpi)\ + std_device_body_with_macros_(dtype, init, dname, stype,\ w, h, xdpi, ydpi,\ open_init_closed, dci_black_and_white_, no_margins_) -#define std_device_std_body(dtype, pprocs, dname, w, h, xdpi, ydpi)\ - std_device_std_body_type(dtype, pprocs, dname, 0, w, h, xdpi, ydpi) +#define std_device_std_body(dtype, init, dname, w, h, xdpi, ydpi)\ + std_device_std_body_type(dtype, init, dname, 0, w, h, xdpi, ydpi) -#define std_device_std_body_type_open(dtype, pprocs, dname, stype, w, h, xdpi, ydpi)\ - std_device_body_with_macros_(dtype, pprocs, dname, stype,\ +#define std_device_std_body_type_open(dtype, init, dname, stype, w, h, xdpi, ydpi)\ + std_device_body_with_macros_(dtype, init, dname, stype,\ w, h, xdpi, ydpi,\ open_init_open, dci_black_and_white_, no_margins_) -#define std_device_std_body_open(dtype, pprocs, dname, w, h, xdpi, ydpi)\ - std_device_std_body_type_open(dtype, pprocs, dname, 0, w, h, xdpi, ydpi) +#define std_device_std_body_open(dtype, init, dname, w, h, xdpi, ydpi)\ + std_device_std_body_type_open(dtype, init, dname, 0, w, h, xdpi, ydpi) -#define std_device_full_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\ +#define std_device_full_body_type(dtype, init, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ dci_values(ncomp, depth, mg, mc, dg, dc),\ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(xoff, yoff, lm, bm, rm, tm),\ std_device_part3_() -#define std_device_full_body_type_extended(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, xoff, yoff, lm, bm, rm, tm)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\ +#define std_device_full_body_type_extended(dtype, init, dname, stype, w, h, xdpi, ydpi, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, xoff, yoff, lm, bm, rm, tm)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ dci_extended_alpha_values(mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, 1, 1, ef, cn), \ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(xoff, yoff, lm, bm, rm, tm),\ std_device_part3_() -#define std_device_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\ - std_device_full_body_type(dtype, pprocs, dname, 0, w, h, xdpi, ydpi,\ +#define std_device_full_body(dtype, init, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm)\ + std_device_full_body_type(dtype, init, dname, 0, w, h, xdpi, ydpi,\ ncomp, depth, mg, mc, dg, dc, xoff, yoff, lm, bm, rm, tm) -#define std_device_dci_alpha_type_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, ta, ga)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\ +#define std_device_dci_alpha_type_body(dtype, init, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, ta, ga)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ dci_alpha_values(ncomp, depth, mg, mc, dg, dc, ta, ga),\ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(0, 0, 0, 0, 0, 0),\ std_device_part3_() +#define std_device_dci_alpha_type_body_sc(dtype, init, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, ta, ga, ins, bp, ep)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ + dci_alpha_values(ncomp, depth, mg, mc, dg, dc, ta, ga),\ + std_device_part2_(w, h, xdpi, ydpi),\ + offset_margin_values(0, 0, 0, 0, 0, 0),\ + std_device_part3_sc(ins, bp, ep) -#define std_device_dci_type_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\ - std_device_dci_alpha_type_body(dtype, pprocs, dname, stype, w, h,\ +#define std_device_dci_type_body(dtype, init, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\ + std_device_dci_alpha_type_body(dtype, init, dname, stype, w, h,\ xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, 1, 1) -#define std_device_dci_body(dtype, pprocs, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\ - std_device_dci_type_body(dtype, pprocs, dname, 0,\ +#define std_device_dci_type_body_sc(dtype, init, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, ins, bp, ep)\ + std_device_dci_alpha_type_body_sc(dtype, init, dname, stype, w, h,\ + xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, 1, 1, ins, bp, ep) + +#define std_device_dci_body(dtype, init, dname, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc)\ + std_device_dci_type_body(dtype, init, dname, 0,\ w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc) -#define std_device_color_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, depth, max_value, dither, xoff, yoff, lm, bm, rm, tm)\ - std_device_part1_(dtype, pprocs, dname, 0, open_init_closed),\ +#define std_device_color_full_body(dtype, init, dname, w, h, xdpi, ydpi, depth, max_value, dither, xoff, yoff, lm, bm, rm, tm)\ + std_device_part1_(dtype, init, dname, 0, open_init_closed),\ dci_color(depth, max_value, dither),\ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(xoff, yoff, lm, bm, rm, tm),\ std_device_part3_() -#define std_device_color_body(dtype, pprocs, dname, w, h, xdpi, ydpi, depth, max_value, dither)\ - std_device_color_full_body(dtype, pprocs, dname,\ +#define std_device_color_body(dtype, init, dname, w, h, xdpi, ydpi, depth, max_value, dither)\ + std_device_color_full_body(dtype, init, dname,\ w, h, xdpi, ydpi,\ depth, max_value, dither,\ 0, 0, 0, 0, 0, 0) -#define std_device_color_stype_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, depth, max_value, dither)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\ +#define std_device_color_stype_body(dtype, init, dname, stype, w, h, xdpi, ydpi, depth, max_value, dither)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ dci_color(depth, max_value, dither),\ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(0, 0, 0, 0, 0, 0),\ std_device_part3_() -#define std_device_std_color_full_body_type(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\ - std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\ +#define std_device_std_color_full_body_type(dtype, init, dname, stype, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\ + std_device_part1_(dtype, init, dname, stype, open_init_closed),\ dci_std_color(depth),\ std_device_part2_(w, h, xdpi, ydpi),\ offset_margin_values(xoff, yoff, lm, bm, rm, tm),\ std_device_part3_() -#define std_device_std_color_full_body(dtype, pprocs, dname, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\ - std_device_std_color_full_body_type(dtype, pprocs, dname, 0,\ +#define std_device_std_color_full_body(dtype, init, dname, w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm)\ + std_device_std_color_full_body_type(dtype, init, dname, 0,\ w, h, xdpi, ydpi, depth, xoff, yoff, lm, bm, rm, tm) /* ---------------- Default implementations ---------------- */ @@ -250,28 +263,20 @@ dev_proc_output_page(gx_default_output_page); dev_proc_close_device(gx_default_close_device); dev_proc_map_rgb_color(gx_default_w_b_map_rgb_color); dev_proc_map_color_rgb(gx_default_w_b_map_color_rgb); +dev_proc_encode_color(gx_default_w_b_mono_encode_color); +dev_proc_decode_color(gx_default_w_b_mono_decode_color); #define gx_default_map_rgb_color gx_default_w_b_map_rgb_color #define gx_default_map_color_rgb gx_default_w_b_map_color_rgb -dev_proc_tile_rectangle(gx_default_tile_rectangle); dev_proc_copy_mono(gx_default_copy_mono); dev_proc_copy_color(gx_default_copy_color); -dev_proc_draw_line(gx_default_draw_line); -dev_proc_get_bits(gx_no_get_bits); /* gives error */ -dev_proc_get_bits(gx_default_get_bits); dev_proc_get_params(gx_default_get_params); dev_proc_put_params(gx_default_put_params); dev_proc_map_cmyk_color(gx_default_map_cmyk_color); -dev_proc_get_xfont_procs(gx_default_get_xfont_procs); -dev_proc_get_xfont_device(gx_default_get_xfont_device); -dev_proc_map_rgb_alpha_color(gx_default_map_rgb_alpha_color); dev_proc_get_page_device(gx_default_get_page_device); /* returns NULL */ dev_proc_get_page_device(gx_page_device_get_page_device); /* returns dev */ dev_proc_get_alpha_bits(gx_default_get_alpha_bits); dev_proc_copy_alpha(gx_no_copy_alpha); /* gives error */ dev_proc_copy_alpha(gx_default_copy_alpha); -dev_proc_get_band(gx_default_get_band); -dev_proc_copy_rop(gx_no_copy_rop); /* gives error */ -dev_proc_copy_rop(gx_default_copy_rop); dev_proc_fill_path(gx_default_fill_path); dev_proc_stroke_path(gx_default_stroke_path); dev_proc_fill_mask(gx_default_fill_mask); @@ -279,26 +284,20 @@ dev_proc_fill_trapezoid(gx_default_fill_trapezoid); dev_proc_fill_parallelogram(gx_default_fill_parallelogram); dev_proc_fill_triangle(gx_default_fill_triangle); dev_proc_draw_thin_line(gx_default_draw_thin_line); -dev_proc_begin_image(gx_default_begin_image); -dev_proc_image_data(gx_default_image_data); -dev_proc_end_image(gx_default_end_image); dev_proc_strip_tile_rectangle(gx_default_strip_tile_rectangle); -dev_proc_strip_copy_rop(gx_no_strip_copy_rop); /* gives error */ -dev_proc_strip_copy_rop(gx_default_strip_copy_rop); +dev_proc_strip_copy_rop2(gx_no_strip_copy_rop2); dev_proc_get_clipping_box(gx_default_get_clipping_box); dev_proc_get_clipping_box(gx_get_largest_clipping_box); dev_proc_begin_typed_image(gx_default_begin_typed_image); -dev_proc_get_bits_rectangle(gx_no_get_bits_rectangle); /* gives error */ -dev_proc_get_bits_rectangle(gx_default_get_bits_rectangle); -dev_proc_map_color_rgb_alpha(gx_default_map_color_rgb_alpha); -dev_proc_create_compositor(gx_no_create_compositor); +dev_proc_get_bits_rectangle(gx_default_get_bits_rectangle); /* just returns error */ +dev_proc_get_bits_rectangle(gx_blank_get_bits_rectangle); +dev_proc_composite(gx_no_composite); /* default is for ordinary "leaf" devices, null is for */ /* devices that only care about coverage and not contents. */ -dev_proc_create_compositor(gx_default_create_compositor); -dev_proc_create_compositor(gx_null_create_compositor); +dev_proc_composite(gx_default_composite); +dev_proc_composite(gx_null_composite); dev_proc_get_hardware_params(gx_default_get_hardware_params); dev_proc_text_begin(gx_default_text_begin); -dev_proc_finish_copydevice(gx_default_finish_copydevice); dev_proc_dev_spec_op(gx_default_dev_spec_op); dev_proc_fill_rectangle_hl_color(gx_default_fill_rectangle_hl_color); dev_proc_include_color_space(gx_default_include_color_space); @@ -322,23 +321,28 @@ dev_proc_end_transparency_group(gx_default_end_transparency_group); dev_proc_begin_transparency_mask(gx_default_begin_transparency_mask); dev_proc_end_transparency_mask(gx_default_end_transparency_mask); dev_proc_discard_transparency_layer(gx_default_discard_transparency_layer); -dev_proc_pattern_manage(gx_default_pattern_manage); dev_proc_push_transparency_state(gx_default_push_transparency_state); dev_proc_pop_transparency_state(gx_default_pop_transparency_state); dev_proc_put_image(gx_default_put_image); dev_proc_copy_alpha_hl_color(gx_default_no_copy_alpha_hl_color); dev_proc_copy_planes(gx_default_copy_planes); +int gx_default_initialize_device(gx_device *dev); + /* BACKWARD COMPATIBILITY */ -#define gx_non_imaging_create_compositor gx_null_create_compositor +#define gx_non_imaging_composite gx_null_composite /* Color mapping routines for black-on-white, gray scale, true RGB, */ /* true CMYK, and 1-bit CMYK color. */ dev_proc_map_rgb_color(gx_default_b_w_map_rgb_color); dev_proc_map_color_rgb(gx_default_b_w_map_color_rgb); +dev_proc_encode_color(gx_default_b_w_mono_encode_color); +dev_proc_decode_color(gx_default_b_w_mono_decode_color); dev_proc_map_rgb_color(gx_default_gray_map_rgb_color); dev_proc_map_color_rgb(gx_default_gray_map_color_rgb); dev_proc_map_color_rgb(gx_default_rgb_map_color_rgb); +dev_proc_encode_color(gx_default_gray_encode_color); +dev_proc_decode_color(gx_default_gray_decode_color); #define gx_default_cmyk_map_cmyk_color cmyk_8bit_map_cmyk_color /*see below*/ /* * The following are defined as "standard" color mapping procedures @@ -353,11 +357,13 @@ dev_proc_map_cmyk_color(cmyk_8bit_map_cmyk_color); dev_proc_map_color_rgb(cmyk_8bit_map_color_rgb); dev_proc_decode_color(cmyk_8bit_map_color_cmyk); dev_proc_map_cmyk_color(cmyk_16bit_map_cmyk_color); +dev_proc_map_color_rgb(cmyk_16bit_map_color_rgb); dev_proc_decode_color(cmyk_16bit_map_color_cmyk); dev_proc_encode_color(gx_default_8bit_map_gray_color); dev_proc_decode_color(gx_default_8bit_map_color_gray); /* Default implementations for forwarding devices */ +void gx_forward_initialize_procs(gx_device *dev); dev_proc_close_device(gx_forward_close_device); dev_proc_get_initial_matrix(gx_forward_get_initial_matrix); dev_proc_sync_output(gx_forward_sync_output); @@ -365,21 +371,14 @@ dev_proc_output_page(gx_forward_output_page); dev_proc_map_rgb_color(gx_forward_map_rgb_color); dev_proc_map_color_rgb(gx_forward_map_color_rgb); dev_proc_fill_rectangle(gx_forward_fill_rectangle); -dev_proc_tile_rectangle(gx_forward_tile_rectangle); dev_proc_copy_mono(gx_forward_copy_mono); dev_proc_copy_color(gx_forward_copy_color); -dev_proc_get_bits(gx_forward_get_bits); dev_proc_get_params(gx_forward_get_params); dev_proc_put_params(gx_forward_put_params); dev_proc_map_cmyk_color(gx_forward_map_cmyk_color); -dev_proc_get_xfont_procs(gx_forward_get_xfont_procs); -dev_proc_get_xfont_device(gx_forward_get_xfont_device); -dev_proc_map_rgb_alpha_color(gx_forward_map_rgb_alpha_color); dev_proc_get_page_device(gx_forward_get_page_device); #define gx_forward_get_alpha_bits gx_default_get_alpha_bits dev_proc_copy_alpha(gx_forward_copy_alpha); -dev_proc_get_band(gx_forward_get_band); -dev_proc_copy_rop(gx_forward_copy_rop); dev_proc_fill_path(gx_forward_fill_path); dev_proc_stroke_path(gx_forward_stroke_path); dev_proc_fill_mask(gx_forward_fill_mask); @@ -387,16 +386,11 @@ dev_proc_fill_trapezoid(gx_forward_fill_trapezoid); dev_proc_fill_parallelogram(gx_forward_fill_parallelogram); dev_proc_fill_triangle(gx_forward_fill_triangle); dev_proc_draw_thin_line(gx_forward_draw_thin_line); -dev_proc_begin_image(gx_forward_begin_image); -#define gx_forward_image_data gx_default_image_data -#define gx_forward_end_image gx_default_end_image dev_proc_strip_tile_rectangle(gx_forward_strip_tile_rectangle); -dev_proc_strip_copy_rop(gx_forward_strip_copy_rop); dev_proc_get_clipping_box(gx_forward_get_clipping_box); dev_proc_begin_typed_image(gx_forward_begin_typed_image); dev_proc_get_bits_rectangle(gx_forward_get_bits_rectangle); -dev_proc_map_color_rgb_alpha(gx_forward_map_color_rgb_alpha); -/* There is no forward_create_compositor (see Drivers.htm). */ +/* There is no forward_composite (see Drivers.htm). */ dev_proc_get_hardware_params(gx_forward_get_hardware_params); dev_proc_text_begin(gx_forward_text_begin); dev_proc_get_color_mapping_procs(gx_forward_get_color_mapping_procs); @@ -414,7 +408,7 @@ dev_proc_ret_devn_params(gx_forward_ret_devn_params); dev_proc_fillpage(gx_forward_fillpage); dev_proc_put_image(gx_forward_put_image); dev_proc_copy_planes(gx_forward_copy_planes); -dev_proc_create_compositor(gx_forward_create_compositor); +dev_proc_composite(gx_forward_composite); dev_proc_get_profile(gx_forward_get_profile); dev_proc_set_graphics_type_tag(gx_forward_set_graphics_type_tag); dev_proc_strip_copy_rop2(gx_forward_strip_copy_rop2); @@ -422,13 +416,11 @@ dev_proc_strip_tile_rect_devn(gx_forward_strip_tile_rect_devn); dev_proc_copy_alpha_hl_color(gx_forward_copy_alpha_hl_color); dev_proc_transform_pixel_region(gx_forward_transform_pixel_region); dev_proc_fill_stroke_path(gx_forward_fill_stroke_path); +void gx_forward_device_initialize_procs(gx_device *dev); /* ---------------- Implementation utilities ---------------- */ int gx_default_get_param(gx_device *dev, char *Param, void *list); -/* Convert the device procedures to the proper form (see above). */ -void gx_device_set_procs(gx_device *); - /* Fill in defaulted procedures in a device procedure record. */ void gx_device_fill_in_procs(gx_device *); void gx_device_forward_fill_in_procs(gx_device_forward *); @@ -669,23 +661,22 @@ void gx_device_request_leadingedge(gx_device *dev, int le_req); int gs_is_pdf14trans_compositor(const gs_composite_t * pct); #define subclass_common\ - t_dev_proc_create_compositor *saved_compositor_method;\ + t_dev_proc_composite *saved_compositor_method;\ gx_device_forward *forwarding_dev -typedef int (t_dev_proc_create_compositor) (gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev); +typedef int (t_dev_proc_composite) (gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev); typedef struct { - t_dev_proc_create_compositor *saved_compositor_method; + t_dev_proc_composite *saved_compositor_method; gx_device_forward *forwarding_dev; } generic_subclass_data; - -int gx_copy_device_procs(gx_device *dest, gx_device *src, gx_device *prototype); +int gx_copy_device_procs(gx_device *dest, const gx_device *src, const gx_device *prototype); int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, unsigned int private_data_size); -int gx_device_unsubclass(gx_device *dev); +void gx_device_unsubclass(gx_device *dev); int gx_update_from_subclass(gx_device *dev); -int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, +int gx_subclass_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev); - +void gx_subclass_fill_in_page_procs(gx_device *dev); #endif /* gxdevice_INCLUDED */ diff --git a/base/gxdevmem.h b/base/gxdevmem.h index bb890a27..8141331c 100644 --- a/base/gxdevmem.h +++ b/base/gxdevmem.h @@ -202,6 +202,56 @@ int gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size, #define gdev_mem_raster(mdev)\ gx_device_raster((const gx_device *)(mdev), true) +typedef struct +{ + dev_proc_map_rgb_color((*map_rgb_color)); + dev_proc_map_color_rgb((*map_color_rgb)); + dev_proc_fill_rectangle((*fill_rectangle)); + dev_proc_copy_mono((*copy_mono)); + dev_proc_copy_color((*copy_color)); + dev_proc_copy_alpha((*copy_alpha)); + dev_proc_strip_tile_rectangle((*strip_tile_rectangle)); + dev_proc_strip_copy_rop2((*strip_copy_rop2)); + dev_proc_get_bits_rectangle((*get_bits_rectangle)); +} gdev_mem_functions; + +extern const gdev_mem_functions gdev_mem_fns_1; +extern const gdev_mem_functions gdev_mem_fns_2; +extern const gdev_mem_functions gdev_mem_fns_4; +extern const gdev_mem_functions gdev_mem_fns_8; +extern const gdev_mem_functions gdev_mem_fns_16; +extern const gdev_mem_functions gdev_mem_fns_24; +extern const gdev_mem_functions gdev_mem_fns_32; +extern const gdev_mem_functions gdev_mem_fns_40; +extern const gdev_mem_functions gdev_mem_fns_48; +extern const gdev_mem_functions gdev_mem_fns_56; +extern const gdev_mem_functions gdev_mem_fns_64; +#if ARCH_IS_BIG_ENDIAN +#define gdev_mem_fns_1w gdev_mem_fns_1 +#define gdev_mem_fns_2w gdev_mem_fns_2 +#define gdev_mem_fns_4w gdev_mem_fns_4 +#define gdev_mem_fns_8w gdev_mem_fns_8 +#define gdev_mem_fns_24w gdev_mem_fns_24 +#define gdev_mem_fns_32w gdev_mem_fns_32 +#define gdev_mem_fns_40w gdev_mem_fns_40 +#define gdev_mem_fns_48w gdev_mem_fns_48 +#define gdev_mem_fns_56w gdev_mem_fns_56 +#define gdev_mem_fns_64w gdev_mem_fns_64 +#else +extern const gdev_mem_functions gdev_mem_fns_1w; +extern const gdev_mem_functions gdev_mem_fns_2w; +extern const gdev_mem_functions gdev_mem_fns_4w; +extern const gdev_mem_functions gdev_mem_fns_8w; +extern const gdev_mem_functions gdev_mem_fns_24w; +extern const gdev_mem_functions gdev_mem_fns_32w; +extern const gdev_mem_functions gdev_mem_fns_40w; +extern const gdev_mem_functions gdev_mem_fns_48w; +extern const gdev_mem_functions gdev_mem_fns_56w; +extern const gdev_mem_functions gdev_mem_fns_64w; +#endif +const gdev_mem_functions *gdev_mem_functions_for_bits(int bits); +const gdev_mem_functions *gdev_mem_word_functions_for_bits(int bits); + /* Determine the appropriate memory device for a given */ /* number of bits per pixel (0 if none suitable). */ const gx_device_memory *gdev_mem_device_for_bits(int); @@ -230,8 +280,6 @@ void gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem, gx_device * target, const gs_log2_scale_point * pscale, int alpha_bits, int mapped_x, bool devn); -void gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem, - gx_device * target, int alpha_bits); /* * Create memory devices with copydevice. For now the destructor is @@ -249,8 +297,8 @@ int gs_make_mem_device_with_copydevice(gx_device_memory ** mdev, gx_device * target); /* - * TODO replace gs_make_mem_abuf_device, gs_make_mem_alpha_device with - * procedures that use copydevice. + * TODO replace gs_make_mem_abuf_device with + * procedure that uses copydevice. */ /* diff --git a/base/gxdevrop.h b/base/gxdevrop.h deleted file mode 100644 index 10e502a1..00000000 --- a/base/gxdevrop.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Extension of gxdevice.h for RasterOp */ - -#ifndef gxdevrop_INCLUDED -# define gxdevrop_INCLUDED - -#include "gxdevcli.h" - -/* Define an unaligned implementation of [strip_]copy_rop. */ -dev_proc_copy_rop(gx_copy_rop_unaligned); -dev_proc_strip_copy_rop(gx_strip_copy_rop_unaligned); - -#endif /* gxdevrop_INCLUDED */ diff --git a/base/gxdevsop.h b/base/gxdevsop.h index a5af0f41..0131d0e2 100644 --- a/base/gxdevsop.h +++ b/base/gxdevsop.h @@ -227,6 +227,8 @@ enum { */ gxdso_is_pdf14_device, + gxdso_supports_pattern_transparency, + /* gxdso_device_child: * data = pointer to gxdso_device_child_request struct * size = sizeof(gxdso_device_child_request) @@ -328,6 +330,13 @@ enum { gxdso_JPEG_passthrough_begin, gxdso_JPEG_passthrough_data, gxdso_JPEG_passthrough_end, + /* And similarly JPX passthrough requests/control. Currently used for the pdfwrite family only. + */ + gxdso_JPX_passthrough_query, + gxdso_JPX_passthrough_begin, + gxdso_JPX_passthrough_data, + gxdso_JPX_passthrough_end, + gxdso_supports_iccpostrender, /* Retrieve the last device in a device chain (either forwarding or subclass devices). @@ -430,6 +439,9 @@ enum { /* Determine if a given device is a clist one. Returns 1 if it is. */ gxdso_is_clist_device, + /* Determine if a given device is a null device. Returns 1 if it is. */ + gxdso_is_null_device, + /* Add new gxdso_ keys above this. */ gxdso_pattern__LAST }; diff --git a/base/gxdhtserial.c b/base/gxdhtserial.c index 6f8bb18f..cd851951 100644 --- a/base/gxdhtserial.c +++ b/base/gxdhtserial.c @@ -584,7 +584,7 @@ gx_ht_read_and_install( /* save since the 'install' copies the order, but then clears the source order */ for (i = 0; i < num_dev_comps; i++) components_save[i] = components[i]; - code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev); + code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev, HT_OBJTYPE_DEFAULT); if (code >= 0) { for (i = 0; i < num_dev_comps; i++) gx_ht_order_release(&components_save[i].corder, mem, false); diff --git a/base/gxdownscale.c b/base/gxdownscale.c index fd51a695..4e36c81a 100644 --- a/base/gxdownscale.c +++ b/base/gxdownscale.c @@ -1991,8 +1991,22 @@ static int getbits_chunky_line(gx_downscale_liner *liner_, void *buffer, int row) { liner_getbits_chunky *liner = (liner_getbits_chunky *)liner_; + gs_int_rect rect; + gs_get_bits_params_t params; - return (*dev_proc(liner->dev, get_bits))(liner->dev, row, buffer, NULL); + rect.p.x = 0; + rect.p.y = row; + rect.q.x = liner->dev->width; + rect.q.y = row+1; + params.x_offset = 0; + params.raster = bitmap_raster(liner->dev->width * liner->dev->color_info.depth); + params.options = (GB_ALIGN_ANY | + GB_RETURN_COPY | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.data[0] = buffer; + return (*dev_proc(liner->dev, get_bits_rectangle))(liner->dev, &rect, ¶ms); } static void @@ -2030,7 +2044,7 @@ getbits_planar_line(gx_downscale_liner *liner_, void *output, int row) params2 = *params; - code = (*dev_proc(liner->dev, get_bits_rectangle))(liner->dev, &rect, ¶ms2, NULL); + code = (*dev_proc(liner->dev, get_bits_rectangle))(liner->dev, &rect, ¶ms2); /* get_bits_rectangle doesn't like doing planar copies, only return * pointers. This is a problem for us, so fudge it here. */ @@ -2081,13 +2095,18 @@ claptrap_drop(gx_downscale_liner *liner_, gs_memory_t *mem) } #ifdef WITH_CAL +static unsigned char bg0[GX_DEVICE_COLOR_MAX_COMPONENTS] = {0}; +static unsigned char bg1[GX_DEVICE_COLOR_MAX_COMPONENTS] = { + 0xFF, 0xFF, 0xFF, 0xFF }; + typedef struct { gx_downscale_liner base; - cal_deskewer *deskewer; - cal_deskewer_bander *bander; + cal_deskewer *deskewer[GX_DEVICE_COLOR_MAX_COMPONENTS]; + cal_deskewer_bander *bander[GX_DEVICE_COLOR_MAX_COMPONENTS]; int height; int get_row; int got_row; + int num_planes; gx_downscale_liner *chain; } liner_skew; @@ -2103,7 +2122,7 @@ skew_line(gx_downscale_liner *liner_, void *buffer, int row) liner->got_row = row; while (1) { - code = cal_deskewer_band_pull(liner->bander, buffer); + code = cal_deskewer_band_pull(liner->bander[0], buffer); if (code == 1) return 0; /* We got a line! */ @@ -2112,7 +2131,7 @@ skew_line(gx_downscale_liner *liner_, void *buffer, int row) liner->get_row++); if (code < 0) return code; - code = cal_deskewer_band_push(liner->bander, + code = cal_deskewer_band_push(liner->bander[0], buffer); if (code < 0) return code; @@ -2124,11 +2143,70 @@ skew_drop(gx_downscale_liner *liner_, gs_memory_t *mem) { liner_skew *liner = (liner_skew *)liner_; gx_downscale_liner *next; + int i; if (!liner) return; - cal_deskewer_band_end(liner->bander, mem); - cal_deskewer_fin(liner->deskewer, mem); + for (i = 0; i < liner->num_planes; i++) { + cal_deskewer_band_end(liner->bander[i], mem); + cal_deskewer_fin(liner->deskewer[i], mem); + } + next = liner->chain; + gs_free_object(mem, liner, "liner_skew"); + if (next) + next->drop(next, mem); +} + +static int +planar_skew_line(gx_downscale_liner *liner_, void *params_, int row) +{ + liner_skew *liner = (liner_skew *)liner_; + int code; + gs_get_bits_params_t *params = (gs_get_bits_params_t *)params_; + int i; + + if (row < liner->got_row) + liner->get_row = 0; + + liner->got_row = row; + + while (1) { + for (i = 0; i < liner->num_planes; i++) { + code = cal_deskewer_band_pull(liner->bander[i], params->data[i]); + if (code < 0) + return code; + } + if (code == 1) + return 0; /* We got a line! */ + + code = liner->chain->get_line(liner->chain, + params, + liner->get_row++); + if (code < 0) + return code; + + for (i = 0; i < liner->num_planes; i++) { + code = cal_deskewer_band_push(liner->bander[i], + params->data[i]); + if (code < 0) + return code; + } + } +} + +static void +planar_skew_drop(gx_downscale_liner *liner_, gs_memory_t *mem) +{ + liner_skew *liner = (liner_skew *)liner_; + gx_downscale_liner *next; + int i; + + if (!liner) + return; + for (i = 0; i < liner->num_planes; i++) { + cal_deskewer_band_end(liner->bander[i], mem); + cal_deskewer_fin(liner->deskewer[i], mem); + } next = liner->chain; gs_free_object(mem, liner, "liner_skew"); if (next) @@ -2196,6 +2274,7 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, ds->apply_cm_arg = apply_cm_arg; ds->early_cm = dst_bpc < src_bpc; ds->post_cm_num_comps = post_cm_num_comps; + ds->do_skew_detection = params->do_skew_detection; if (apply_cm) { for (i = 0; i < post_cm_num_comps; i++) { @@ -2226,6 +2305,108 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, ds->liner = &gb_liner->base; } + memcpy(&ds->params, gb_params, sizeof(*gb_params)); + ds->params.raster = span; + for (i = 0; i < num_comps; i++) { + ds->pre_cm[i] = gs_alloc_bytes(dev->memory, + (size_t)span * downfactor, + "gx_downscaler(planar_data)"); + if (ds->pre_cm[i] == NULL) { + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + } + +#ifdef WITH_CAL + if (ds->do_skew_detection) { + /* Do a skew detection pass */ + int j; + int w = ds->dev->width; + int h = ds->dev->height; + cal_skew *skew; + + for (i = 0; i < num_comps; i++) { + ds->params.data[i] = ds->pre_cm[i]; + } + + skew = cal_skew_init(ds->dev->memory->gs_lib_ctx->core->cal_ctx, + ds->dev->memory, + w, h); + if (skew == NULL) + code = gs_error_VMerror; + for (j = 0; code >= 0 && j < h; j++) { + gs_get_bits_params_t params2 = ds->params; + code = ds->liner->get_line(ds->liner, ¶ms2, j); + /* Craply turn that into "greyscale" - this assumes 8 bit. */ + if (num_comps > 1) { + int i, k; + byte *dst = ds->params.data[0]; + for (i = 0; i < w; i++) { + int v = 0; + for (k = num_comps-1; k > 0; k--) + v += ((unsigned char *)params2.data[k])[i]; + *dst++ = (v+(num_comps>>1))/num_comps; + } + } + code = cal_skew_process(skew, ds->dev->memory, ds->params.data[0]); + } + if (code >= 0) { + ds->skew_angle = cal_skew_detect(skew, ds->dev->memory); + if (ds->skew_angle < -45 || ds->skew_angle > 45) + ds->skew_angle = 0; + } + cal_skew_fin(skew, ds->dev->memory); + if (code < 0) + goto cleanup; + + if (ds->skew_angle != 0) { + liner_skew *sk_liner; + unsigned int dw, dh; + + code = alloc_liner(dev->memory, + liner_skew, + planar_skew_line, + planar_skew_drop, + &sk_liner); + if (code < 0) + goto cleanup; + sk_liner->chain = ds->liner; + sk_liner->get_row = 0; + sk_liner->got_row = 0; + sk_liner->height = dev->height; + sk_liner->num_planes = num_comps; + ds->liner = &sk_liner->base; + for (i = 0; i < num_comps; i++) + { + sk_liner->deskewer[i] = cal_deskewer_init( + ds->dev->memory->gs_lib_ctx->core->cal_ctx, + ds->dev->memory, + ds->dev->width, ds->dev->height, + &dw, + &dh, + ds->skew_angle, + 1, /* Keep the page size constant */ + 1.0, 1.0, 1.0, 1.0, + bg0, + 1); + if (sk_liner->deskewer[i] == NULL) { + emprintf(dev->memory, "Deskewer initialisation failed"); + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + sk_liner->bander[i] = cal_deskewer_band_begin(sk_liner->deskewer[i], + ds->dev->memory, + 0, 0); + if (sk_liner->bander[i] == NULL) { + emprintf(dev->memory, "Deskewer initialisation(2) failed"); + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + } + } + } +#endif + code = check_trapping(dev->memory, params->trap_w, params->trap_h, num_comps, params->trap_order); if (code < 0) @@ -2263,17 +2444,6 @@ int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, } } - memcpy(&ds->params, gb_params, sizeof(*gb_params)); - ds->params.raster = span; - for (i = 0; i < num_comps; i++) { - ds->pre_cm[i] = gs_alloc_bytes(dev->memory, - (size_t)span * downfactor, - "gx_downscaler(planar_data)"); - if (ds->pre_cm[i] == NULL) { - code = gs_note_error(gs_error_VMerror); - goto cleanup; - } - } if (upfactor > 1) { ds->scaled_data = gs_alloc_bytes(dev->memory, (size_t)ds->scaled_span * upfactor * num_comps, @@ -2419,12 +2589,6 @@ select_8_to_8_core(int nc, int factor) return NULL; } -#ifdef WITH_CAL -static unsigned char bg0[GX_DEVICE_COLOR_MAX_COMPONENTS] = {0}; -static unsigned char bg1[GX_DEVICE_COLOR_MAX_COMPONENTS] = { - 0xFF, 0xFF, 0xFF, 0xFF }; -#endif - int gx_downscaler_init_cm_halftone(gx_downscaler_t *ds, gx_device *dev, @@ -2555,8 +2719,9 @@ gx_downscaler_init_cm_halftone(gx_downscaler_t *ds, sk_liner->get_row = 0; sk_liner->got_row = 0; sk_liner->height = dev->height; + sk_liner->num_planes = 1; ds->liner = &sk_liner->base; - sk_liner->deskewer = cal_deskewer_init( + sk_liner->deskewer[0] = cal_deskewer_init( ds->dev->memory->gs_lib_ctx->core->cal_ctx, ds->dev->memory, ds->dev->width, ds->dev->height, @@ -2567,15 +2732,15 @@ gx_downscaler_init_cm_halftone(gx_downscaler_t *ds, 1.0, 1.0, 1.0, 1.0, (ds->num_comps <= 3 ? bg1 : bg0), ds->num_comps); - if (sk_liner->deskewer == NULL) { + if (sk_liner->deskewer[0] == NULL) { emprintf(dev->memory, "Deskewer initialisation failed"); code = gs_note_error(gs_error_VMerror); goto cleanup; } - sk_liner->bander = cal_deskewer_band_begin(sk_liner->deskewer, + sk_liner->bander[0] = cal_deskewer_band_begin(sk_liner->deskewer[0], ds->dev->memory, 0, 0); - if (sk_liner->bander == NULL) { + if (sk_liner->bander[0] == NULL) { emprintf(dev->memory, "Deskewer initialisation(2) failed"); code = gs_note_error(gs_error_VMerror); goto cleanup; @@ -3051,7 +3216,7 @@ static int downscaler_process_fn(void *arg_, gx_device *dev, gx_device *bdev, co /* Where do we get the data from? */ params.options = GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_PACKING_CHUNKY | GB_RETURN_POINTER | GB_ALIGN_ANY | GB_OFFSET_0 | GB_RASTER_ANY; - code = dev_proc(bdev, get_bits_rectangle)(bdev, &in_rect, ¶ms, NULL); + code = dev_proc(bdev, get_bits_rectangle)(bdev, &in_rect, ¶ms); if (code < 0) return code; raster_in = params.raster; @@ -3059,7 +3224,7 @@ static int downscaler_process_fn(void *arg_, gx_device *dev, gx_device *bdev, co /* Where do we write it to? */ if (buffer->bdev) { - code = dev_proc(bdev, get_bits_rectangle)(buffer->bdev, &out_rect, ¶ms, NULL); + code = dev_proc(bdev, get_bits_rectangle)(buffer->bdev, &out_rect, ¶ms); if (code < 0) return code; raster_out = params.raster; @@ -3207,9 +3372,9 @@ int gx_downscaler_read_params(gs_param_list *plist, return code; } - switch (code = param_read_int(plist, - (param_name = "Deskew"), - &deskew)) { + switch (code = param_read_bool(plist, + (param_name = "Deskew"), + &deskew)) { case 1: break; case 0: @@ -3355,7 +3520,7 @@ int gx_downscaler_write_params(gs_param_list *plist, if ((code = param_write_int(plist, "DownScaleFactor", ¶ms->downscale_factor)) < 0) ecode = code; - if ((code = param_write_int(plist, "Deskew", ¶ms->do_skew_detection)) < 0) + if ((code = param_write_bool(plist, "Deskew", ¶ms->do_skew_detection)) < 0) ecode = code; if (features & GX_DOWNSCALER_PARAMS_MFS) { diff --git a/base/gxfapi.c b/base/gxfapi.c index 6b97d708..2bc385a3 100644 --- a/base/gxfapi.c +++ b/base/gxfapi.c @@ -33,6 +33,7 @@ #include "gsimage.h" #include "gsbittab.h" #include "gzpath.h" +#include "gxdevsop.h" #include "gxfapi.h" @@ -261,9 +262,7 @@ using_transparency_pattern(gs_gstate *pgs) { gx_device *dev = gs_currentdevice_inline(pgs); - return ((!gs_color_writes_pure(pgs)) - && dev_proc(dev, begin_transparency_group) != gx_default_begin_transparency_group - && dev_proc(dev, end_transparency_group) != gx_default_end_transparency_group); + return ((!gs_color_writes_pure(pgs)) && dev_proc(dev, dev_spec_op)(dev, gxdso_supports_pattern_transparency, NULL, 0)); } static inline bool @@ -428,7 +427,14 @@ gs_fapi_prepare_font(gs_font *pfont, gs_fapi_server *I, int subfont, const char < 0) return code; pbfont->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */ - if (I->ff.server_font_data != 0) { + + /* We only want to "refine" the FontBBox for fonts where we allow FAPI to be + treated as a "black box", handing over the entire font to the FAPI server. + That is, fonts where we give the server either the file, or a buffer with + the entire font description in it. + */ + if (I->ff.server_font_data != 0 + && (font_file_path != NULL || full_font_buf != NULL)) { if ((code = gs_fapi_renderer_retcode(mem, I, I->get_font_bbox(I, &I->ff, @@ -776,7 +782,7 @@ fapi_image_uncached_glyph(gs_font *pfont, gs_gstate *pgs, gs_show_enum *penum, gs_gstate *penum_pgs = (gs_gstate *) penum->pgs; int code; const gx_clip_path *pcpath = pgs->clip_path; - const gx_drawing_color *pdcolor = penum->pdcolor; + const gx_drawing_color *pdcolor = gs_currentdevicecolor_inline(penum->pgs); int rast_orig_x = rast->orig_x; int rast_orig_y = -rast->orig_y; gs_font_base *pbfont = (gs_font_base *)pfont; @@ -1485,7 +1491,7 @@ gs_fapi_do_char(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, char *fon } if (cr.metrics_type == gs_fapi_metrics_notdef && !bVertical) { code = - I->ff.fapi_get_metrics(&I->ff, &enc_char_name_string, index, sbw, + I->ff.fapi_get_metrics(&I->ff, &enc_char_name_string, (int)index, sbw, bVertical); if (code < 0) return code; diff --git a/base/gxfapi.h b/base/gxfapi.h index 728630e6..7f5dd03f 100644 --- a/base/gxfapi.h +++ b/base/gxfapi.h @@ -209,7 +209,7 @@ struct gs_fapi_font_s int (*get_glyphname_or_cid) (gs_text_enum_t *penum, gs_font_base *pbfont, gs_string *charstring, gs_string *name, gs_glyph ccode, gs_string *enc_char_name, - char *font_file_path, gs_fapi_char_ref *cr, + char *font_file_path, gs_fapi_char_ref *cr, bool bCID); int (*fapi_get_metrics) (gs_fapi_font *ff, gs_string *char_name, gs_glyph cid, double *m, bool vertical); diff --git a/base/gxfill.c b/base/gxfill.c index 921c2baf..88e44c99 100644 --- a/base/gxfill.c +++ b/base/gxfill.c @@ -196,7 +196,7 @@ is_spotan_device(gx_device * dev) { /* Use open_device procedure to identify the type of the device * instead of the standard gs_object_type() because gs_cpath_accum_device - * is allocaded on the stack i.e. has no block header with a descriptor + * is allocated on the stack i.e. has no block header with a descriptor * but has dev->memory set like a heap-allocated device. */ return dev_proc(dev, open_device) == san_open; diff --git a/base/gxgstate.h b/base/gxgstate.h index a6309d89..b1ce6a08 100644 --- a/base/gxgstate.h +++ b/base/gxgstate.h @@ -81,7 +81,7 @@ typedef struct gx_transfer_s { gs_halftone *halftone; /* (RC) */\ gs_int_point screen_phase[gs_color_select_count];\ /* dev_ht depends on halftone and device resolution. */\ - gx_device_halftone *dev_ht; /* (RC) */\ + gx_device_halftone *dev_ht[HT_OBJTYPE_COUNT]; /* (RC) */\ \ /* Color (device-dependent): */\ \ @@ -139,7 +139,10 @@ typedef struct gs_gstate_color_s { */ #define gs_cr_state_do_rc_ptrs(m)\ m(halftone) \ - m(dev_ht) \ + m(dev_ht[HT_OBJTYPE_DEFAULT]) \ + m(dev_ht[HT_OBJTYPE_VECTOR]) \ + m(dev_ht[HT_OBJTYPE_IMAGE]) \ + m(dev_ht[HT_OBJTYPE_TEXT]) \ m(cie_render) \ m(black_generation) \ m(undercolor_removal) \ @@ -155,19 +158,22 @@ typedef struct gs_gstate_color_s { /* Enumerate the pointers in a c.r. state. */ #define gs_cr_state_do_ptrs(m)\ m(0,halftone) \ - m(1,dev_ht) \ - m(2,cie_render) \ - m(3,black_generation) \ - m(4,undercolor_removal) \ - m(5,set_transfer.red) \ - m(6,set_transfer.green) \ - m(7,set_transfer.blue) \ - m(8,set_transfer.gray)\ - m(9,cie_joint_caches) \ - m(10,pattern_cache) \ - m(11,devicergb_cs) \ - m(12,devicecmyk_cs)\ - m(13,cie_joint_caches_alt) + m(1,dev_ht[HT_OBJTYPE_DEFAULT]) \ + m(2, dev_ht[HT_OBJTYPE_VECTOR]) \ + m(3, dev_ht[HT_OBJTYPE_IMAGE]) \ + m(4, dev_ht[HT_OBJTYPE_TEXT]) \ + m(5,cie_render) \ + m(6,black_generation) \ + m(7,undercolor_removal) \ + m(8,set_transfer.red) \ + m(9,set_transfer.green) \ + m(10,set_transfer.blue) \ + m(11,set_transfer.gray)\ + m(12,cie_joint_caches) \ + m(13,pattern_cache) \ + m(14,devicergb_cs) \ + m(15,devicecmyk_cs)\ + m(16,cie_joint_caches_alt) /* * We handle effective_transfer specially in gsistate.c since its pointers * are not enumerated for garbage collection but they are are relocated. @@ -176,7 +182,7 @@ typedef struct gs_gstate_color_s { * This count does not include the effective_transfer pointers since they * are not enumerated for GC. */ -#define st_cr_state_num_ptrs 14 +#define st_cr_state_num_ptrs 17 struct gs_devicen_color_map_s { bool use_alt_cspace; @@ -279,6 +285,9 @@ struct gs_gstate_s { gs_matrix ctm_default; bool ctm_default_set; /* if true, use ctm_default; */ /* if false, ask device */ + gs_matrix ctm_initial; /* The value of the device initial matrix at the time the default was set. */ + bool ctm_initial_set; /* if true, modification set. If not, assume identity. */ + /* Paths: */ gx_path *path; @@ -468,5 +477,25 @@ static inline void ensure_tag_is_set(gs_gstate *pgs, gx_device *dev, gs_graphics } } +/* Adjust the color reference counts for the current space. */ +static inline void +cs_adjust_color_count(gs_gstate *pgs, int delta) +{ + gs_color_space *pcs = gs_currentcolorspace_inline(pgs); + + (pcs->type->adjust_color_count)(gs_currentcolor_inline(pgs), + pcs, delta); +} + +/* Adjust the color reference counts for the swapped space (i.e. + * the one that is not current). */ +static inline void +cs_adjust_swappedcolor_count(gs_gstate *pgs, int delta) +{ + gs_color_space *pcs = gs_swappedcolorspace_inline(pgs); + + (pcs->type->adjust_color_count)(gs_swappedcolor_inline(pgs), + pcs, delta); +} #endif /* gxistate_INCLUDED */ diff --git a/base/gxht.c b/base/gxht.c index aeb23362..a57662ce 100644 --- a/base/gxht.c +++ b/base/gxht.c @@ -301,17 +301,7 @@ gx_dc_ht_binary_fill_rectangle(const gx_device_color * pdevc, int x, int y, lop = rop3_use_D_when_T_1(lop); if (source == NULL) set_rop_no_source(source, no_source, dev); - if (source->planar_height == 0) - return (*dev_proc(dev, strip_copy_rop)) - (dev, source->sdata, - source->sourcex, source->sraster, source->id, - (source->use_scolors ? source->scolors : NULL), - &pdevc->colors.binary.b_tile->tiles, - pdevc->colors.binary.color, - x, y, w, h, pdevc->phase.x, pdevc->phase.y, - lop); - else - return (*dev_proc(dev, strip_copy_rop2)) + return (*dev_proc(dev, strip_copy_rop2)) (dev, source->sdata, source->sourcex, source->sraster, source->id, (source->use_scolors ? source->scolors : NULL), @@ -555,7 +545,7 @@ gx_dc_ht_binary_read( devc.type = gx_dc_type_ht_binary; /* the halftone is always taken from the gs_gstate */ - devc.colors.binary.b_ht = pgs->dev_ht; + devc.colors.binary.b_ht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* cache is not porvided until the device color is used */ devc.colors.binary.b_tile = 0; @@ -602,14 +592,14 @@ gx_dc_ht_binary_read( devc.colors.binary.b_index = *pdata++; } - if (pgs->dev_ht == NULL) + if (pgs->dev_ht[HT_OBJTYPE_DEFAULT] == NULL) return_error(gs_error_unregistered); /* Must not happen. */ /* set the phase as required (select value is arbitrary) */ color_set_phase_mod( &devc, pgs->screen_phase[0].x, pgs->screen_phase[0].y, - pgs->dev_ht->lcm_width, - pgs->dev_ht->lcm_height ); + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width, + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height ); /* everything looks good */ *pdevc = devc; diff --git a/base/gxht.h b/base/gxht.h index b2743a5a..e22f4f9a 100644 --- a/base/gxht.h +++ b/base/gxht.h @@ -182,6 +182,7 @@ typedef struct gs_multiple_halftone_s { struct gs_halftone_s { gs_halftone_type type; rc_header rc; + gs_HT_objtype_t objtype; union { gs_screen_halftone screen; /* setscreen */ gs_colorscreen_halftone colorscreen; /* setcolorscreen */ diff --git a/base/gxht_thresh.c b/base/gxht_thresh.c index 348307ec..c981f81b 100644 --- a/base/gxht_thresh.c +++ b/base/gxht_thresh.c @@ -585,9 +585,11 @@ gxht_thresh_image_init(gx_image_enum *penum) gx_dda_fixed dda_ht; if (gx_device_must_halftone(penum->dev)) { - if (penum->pgs != NULL && penum->pgs->dev_ht != NULL) { - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + if (penum->pgs != NULL && penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT] != NULL) { + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); + + for (k = 0; k < pdht->num_comp; k++) { + d_order = &(pdht->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0 ) { @@ -871,6 +873,7 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, gx_color_index dev_black = gx_device_black(dev); int spp_out = dev->color_info.num_components; byte *contone_align = NULL; /* Init to silence compiler warnings */ + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); /* Go ahead and fill the threshold line buffer with tiled threshold values. First just grab the row or column that we are going to tile with and @@ -883,10 +886,10 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, /* Iterate over the vdi and fill up our threshold buffer. We also need to loop across the planes of data */ for (j = 0; j < spp_out; j++) { - bool threshold_inverted = penum->pgs->dev_ht->components[j].corder.threshold_inverted; + bool threshold_inverted = pdht->components[j].corder.threshold_inverted; - thresh_width = penum->pgs->dev_ht->components[j].corder.width; - thresh_height = penum->pgs->dev_ht->components[j].corder.full_height; + thresh_width = pdht->components[j].corder.width; + thresh_height = pdht->components[j].corder.full_height; halftone = penum->ht_buffer + j * vdi * dithered_stride; /* Compute the tiling positions with dest_width */ dx = (fixed2int_var_rounded(xrun) + penum->pgs->screen_phase[0].x) % thresh_width; @@ -901,7 +904,7 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, right_tile_width = dest_width - num_full_tiles * thresh_width - left_width; /* Get the proper threshold for the colorant count */ - threshold = penum->pgs->dev_ht->components[j].corder.threshold; + threshold = pdht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + contone_stride * j + offset_contone[j]; @@ -995,11 +998,11 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, for (j = 0; j < spp_out; j++) { halftone = penum->ht_buffer + j * penum->ht_plane_height * (LAND_BITS>>3); - thresh_width = penum->pgs->dev_ht->components[j].corder.width; + thresh_width = pdht->components[j].corder.width; thresh_height = - penum->pgs->dev_ht->components[j].corder.full_height; + pdht->components[j].corder.full_height; /* Get the proper threshold for the colorant count */ - threshold = penum->pgs->dev_ht->components[j].corder.threshold; + threshold = pdht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + offset_contone[j] + LAND_BITS * j * contone_stride; diff --git a/base/gxicolor.c b/base/gxicolor.c index 05820695..4785ab4f 100644 --- a/base/gxicolor.c +++ b/base/gxicolor.c @@ -108,7 +108,7 @@ color_halftone_init(gx_image_enum *penum) if (!gx_device_must_halftone(penum->dev)) return NULL; - if (penum->pgs == NULL || penum->pgs->dev_ht == NULL) + if (penum->pgs == NULL || penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT] == NULL) return NULL; dda_ht = penum->dda.pixel0.x; if (penum->dxx > 0) @@ -136,20 +136,20 @@ color_halftone_init(gx_image_enum *penum) if (cal_ht == NULL) goto fail; - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + for (k = 0; k < penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->num_comp; k++) { + d_order = &(penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0) goto fail; if (cal_halftone_add_screen(ctx, penum->memory->non_gc_memory, cal_ht, - penum->pgs->dev_ht->components[k].corder.threshold_inverted, - penum->pgs->dev_ht->components[k].corder.width, - penum->pgs->dev_ht->components[k].corder.full_height, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.threshold_inverted, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.width, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.full_height, -penum->pgs->screen_phase[k].x, -penum->pgs->screen_phase[k].y, - penum->pgs->dev_ht->components[k].corder.threshold) < 0) + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.threshold) < 0) goto fail; } diff --git a/base/gxifast.c b/base/gxifast.c index b93c5861..7ec7a1de 100644 --- a/base/gxifast.c +++ b/base/gxifast.c @@ -606,7 +606,7 @@ image_render_simple(gx_image_enum * penum, const byte * buffer, int data_x, line_size = (w + 7) >> 3; line_width = w; line_x = 0; - } else if (copy_mono == dev_proc(&mem_mono_device, copy_mono) && + } else if (copy_mono == mem_mono_copy_mono && dxx > 0 && gx_dc_is_pure(pdc1) && gx_dc_is_pure(pdc0) && /* We know the colors must be (0,1) or (1,0). */ (pdc0->colors.pure ^ pdc1->colors.pure) == 1 && diff --git a/base/gximag3x.c b/base/gximag3x.c index 3e6b4009..df0face5 100644 --- a/base/gximag3x.c +++ b/base/gximag3x.c @@ -45,7 +45,7 @@ private_st_gs_image3x(); /* Define the image type for ImageType 3x images. */ const gx_image_type_t gs_image_type_3x = { - &st_gs_image3x, gx_begin_image3x, gx_data_image_source_size, + &st_gs_image3x, gx_begin_image3x, gx_image_no_sput, gx_image_no_sget, gx_image_default_release, IMAGE3X_IMAGETYPE }; diff --git a/base/gximage.c b/base/gximage.c index 1d97ac26..90a60f4b 100644 --- a/base/gximage.c +++ b/base/gximage.c @@ -28,7 +28,6 @@ /* ---------------- Generic image support ---------------- */ /* Structure descriptors */ -public_st_gs_image_common(); public_st_gs_data_image(); public_st_gs_pixel_image(); @@ -112,18 +111,6 @@ gx_image_enum_common_init(gx_image_enum_common_t * piec, return 0; } -/* Compute the source size of an ordinary image with explicit data. */ -int -gx_data_image_source_size(const gs_gstate * pgs, - const gs_image_common_t * pim, gs_int_point * psize) -{ - const gs_data_image_t *pdi = (const gs_data_image_t *)pim; - - psize->x = pdi->Width; - psize->y = pdi->Height; - return 0; -} - /* Process the next piece of an image with no source data. */ /* This procedure should never be called. */ int diff --git a/base/gximage1.c b/base/gximage1.c index 787fb4a1..ddd2ef0e 100644 --- a/base/gximage1.c +++ b/base/gximage1.c @@ -34,7 +34,7 @@ static image_proc_sput(gx_image1_sput); static image_proc_sget(gx_image1_sget); static image_proc_release(gx_image1_release); const gx_image_type_t gs_image_type_1 = { - &st_gs_image1, gx_begin_image1, gx_data_image_source_size, + &st_gs_image1, gx_begin_image1, gx_image1_sput, gx_image1_sget, gx_image1_release, 1 }; static image_proc_sput(gx_image1_mask_sput); @@ -44,7 +44,7 @@ static image_proc_sget(gx_image1_mask_sget); * worry about releasing the color space. */ const gx_image_type_t gs_image_type_mask1 = { - &st_gs_image1, gx_begin_image1, gx_data_image_source_size, + &st_gs_image1, gx_begin_image1, gx_image1_mask_sput, gx_image1_mask_sget, gx_image_default_release, 1 }; diff --git a/base/gximage3.c b/base/gximage3.c index 9fd47798..8e39d7b1 100644 --- a/base/gximage3.c +++ b/base/gximage3.c @@ -42,7 +42,7 @@ private_st_gs_image3(); /* Define the image type for ImageType 3 images. */ const gx_image_type_t gs_image_type_3 = { - &st_gs_image3, gx_begin_image3, gx_data_image_source_size, + &st_gs_image3, gx_begin_image3, gx_image_no_sput, gx_image_no_sget, gx_image_default_release, 3 }; static const gx_image_enum_procs_t image3_enum_procs = { diff --git a/base/gximage4.c b/base/gximage4.c index 1a3a4761..0c96da49 100644 --- a/base/gximage4.c +++ b/base/gximage4.c @@ -35,7 +35,7 @@ static image_proc_sput(gx_image4_sput); static image_proc_sget(gx_image4_sget); static image_proc_release(gx_image4_release); const gx_image_type_t gs_image_type_4 = { - &st_gs_image4, gx_begin_image4, gx_data_image_source_size, + &st_gs_image4, gx_begin_image4, gx_image4_sput, gx_image4_sget, gx_image4_release, 4 }; /* @@ -66,7 +66,7 @@ gx_begin_image4(gx_device * dev, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) { - gx_image_enum *penum; + gx_image_enum *penum = NULL; const gs_image4_t *pim = (const gs_image4_t *)pic; int code = gx_image_enum_alloc(pic, prect, mem, &penum); @@ -109,6 +109,7 @@ gx_begin_image4(gx_device * dev, if (code >= 0) *pinfo = (gx_image_enum_common_t *)penum; else { + gs_free_object(mem, penum, "gx_begin_image4"); *pinfo = NULL; } return code; diff --git a/base/gximono.c b/base/gximono.c index 659a6ccb..7b40f3de 100644 --- a/base/gximono.c +++ b/base/gximono.c @@ -96,12 +96,14 @@ halftone_init(gx_image_enum *penum) byte *cache = (penum->color_cache != NULL ? penum->color_cache->device_contone : NULL); cal_matrix matrix; int clip_x, clip_y; + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); if (!gx_device_must_halftone(penum->dev)) return NULL; - if (penum->pgs == NULL || penum->pgs->dev_ht == NULL) + if (penum->pgs == NULL || pdht == NULL) return NULL; + dda_ht = penum->dda.pixel0.x; if (penum->dxx > 0) dda_translate(dda_ht, -fixed_epsilon); @@ -129,20 +131,20 @@ halftone_init(gx_image_enum *penum) if (cal_ht == NULL) goto fail; - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + for (k = 0; k < pdht->num_comp; k++) { + d_order = &(pdht->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0) goto fail; if (cal_halftone_add_screen(penum->memory->gs_lib_ctx->core->cal_ctx, penum->memory->non_gc_memory, cal_ht, - penum->pgs->dev_ht->components[k].corder.threshold_inverted, - penum->pgs->dev_ht->components[k].corder.width, - penum->pgs->dev_ht->components[k].corder.full_height, + pdht->components[k].corder.threshold_inverted, + pdht->components[k].corder.width, + pdht->components[k].corder.full_height, penum->pgs->screen_phase[k].x, -penum->pgs->screen_phase[k].y, - penum->pgs->dev_ht->components[k].corder.threshold) < 0) + pdht->components[k].corder.threshold) < 0) goto fail; } diff --git a/base/gxiparam.h b/base/gxiparam.h index 0336ca8a..250cbbc3 100644 --- a/base/gxiparam.h +++ b/base/gxiparam.h @@ -41,19 +41,6 @@ struct gx_image_type_s { dev_proc_begin_typed_image((*begin_typed_image)); /* - * Compute the width and height of the source data. For images with - * explicit data, this information is in the gs_data_image_t - * structure, but ImageType 2 images must compute it. - * NOTE: we no longer support ImageType 2, so maybe this could be - * simplified/refactored? - */ -#define image_proc_source_size(proc)\ - int proc(const gs_gstate *pgs, const gs_image_common_t *pic,\ - gs_int_point *psize) - - image_proc_source_size((*source_size)); - - /* * Put image parameters on a stream. Currently this is used * only for banding. If the parameters include a color space, * store it in *ppcs. @@ -91,11 +78,6 @@ struct gx_image_type_s { }; /* - * Define the procedure for getting the source size of an image with - * explicit data. - */ -image_proc_source_size(gx_data_image_source_size); -/* * Define dummy sput/sget/release procedures for image types that don't * implement these functions. */ diff --git a/base/gxmclip.c b/base/gxmclip.c index b2b59e35..02c90922 100644 --- a/base/gxmclip.c +++ b/base/gxmclip.c @@ -73,10 +73,13 @@ gx_mask_clip_initialize(gx_device_mask_clip * cdev, tile_clip_buffer_size / (bits->raster + sizeof(byte *)); if (mem == NULL) - gx_device_init_on_stack((gx_device *)cdev, (const gx_device *)proto, + gx_device_init_on_stack((gx_device *)cdev, + (const gx_device *)proto, tdev->memory); else - gx_device_init((gx_device *)cdev, (const gx_device *)proto, mem, true); + (void)gx_device_init((gx_device *)cdev, + (const gx_device *)proto, + mem, true); cdev->width = tdev->width; cdev->height = tdev->height; cdev->color_info = tdev->color_info; diff --git a/base/gxoprect.c b/base/gxoprect.c index 9b409e8c..08f64eb7 100644 --- a/base/gxoprect.c +++ b/base/gxoprect.c @@ -308,8 +308,7 @@ gx_overprint_generic_fill_rectangle( gb_rect.q.y = y; code = dev_proc(tdev, get_bits_rectangle)( tdev, &gb_rect, - &gb_params, - 0 ); + &gb_params ); if (code < 0) break; unpack_proc(pcolor_buff, gb_buff, 0, w, depth); @@ -496,8 +495,7 @@ gx_overprint_sep_fill_rectangle_1( gb_rect.q.y = y; code = dev_proc(tdev, get_bits_rectangle)( tdev, &gb_rect, - &gb_params, - 0 ); + &gb_params ); if (code < 0) break; bits_fill_rectangle_masked( gb_buff, @@ -586,8 +584,7 @@ gx_overprint_sep_fill_rectangle_2( gb_rect.q.y = y; code = dev_proc(tdev, get_bits_rectangle)( tdev, &gb_rect, - &gb_params, - 0 ); + &gb_params ); if (code < 0) break; for (i = 0, j = 0; i < byte_w; i++, cp++) { diff --git a/base/gxp1fill.c b/base/gxp1fill.c index dab8c333..99f05f5c 100644 --- a/base/gxp1fill.c +++ b/base/gxp1fill.c @@ -286,20 +286,7 @@ tile_colored_fill(const tile_fill_state_t * ptfs, data_tile.id = bits->id; data_tile.shift = data_tile.rep_shift = 0; data_tile.num_planes = (ptfs->num_planes > 1 ? ptfs->num_planes : 1); - if (source->planar_height == 0) { - code = (*dev_proc(ptfs->pcdev, strip_copy_rop)) - (ptfs->pcdev, - source->sdata + (y - ptfs->y0) * source->sraster, - source->sourcex + (x - ptfs->x0), - source->sraster, source_id, - (source->use_scolors ? source->scolors : NULL), - &data_tile, NULL, - x, y, w, h, - imod(xoff - x, data_tile.rep_width), - imod(yoff - y, data_tile.rep_height), - lop); - } else { - code = (*dev_proc(ptfs->pcdev, strip_copy_rop2)) + code = (*dev_proc(ptfs->pcdev, strip_copy_rop2)) (ptfs->pcdev, source->sdata + (y - ptfs->y0) * source->sraster, source->sourcex + (x - ptfs->x0), @@ -311,7 +298,6 @@ tile_colored_fill(const tile_fill_state_t * ptfs, imod(yoff - y, data_tile.rep_height), lop, source->planar_height); - } } return code; } @@ -393,13 +379,6 @@ gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y, code = (*dev_proc(state.pcdev, strip_tile_rectangle)) (state.pcdev, bits, x, y, w, h, gx_no_color_index, gx_no_color_index, px, py); - else if (rop_source->planar_height == 0) - code = (*dev_proc(state.pcdev, strip_copy_rop)) - (state.pcdev, - rop_source->sdata, rop_source->sourcex, - rop_source->sraster, rop_source->id, - (rop_source->use_scolors ? rop_source->scolors : NULL), - bits, NULL, x, y, w, h, px, py, lop); else code = (*dev_proc(state.pcdev, strip_copy_rop2)) (state.pcdev, diff --git a/base/gxpath.h b/base/gxpath.h index 90d62bed..21afd4bc 100644 --- a/base/gxpath.h +++ b/base/gxpath.h @@ -201,6 +201,7 @@ typedef enum { /* Path accessors */ gx_path *gx_current_path(const gs_gstate *); +bool gx_path_position_valid(const gx_path *ppath); int gx_path_current_point(const gx_path *, gs_fixed_point *), gx_path_bbox(gx_path *, gs_fixed_rect *), gx_path_bbox_set(gx_path *, gs_fixed_rect *); diff --git a/base/gxpath2.c b/base/gxpath2.c index 0f856f5a..0989f41f 100644 --- a/base/gxpath2.c +++ b/base/gxpath2.c @@ -27,6 +27,13 @@ /* Define the enumeration structure. */ public_st_path_enum(); +/* Check whether current path has valid point */ +bool +gx_path_position_valid(const gx_path *ppath) +{ + return path_position_valid(ppath); +} + /* Read the current point of a path. */ int gx_path_current_point(const gx_path * ppath, gs_fixed_point * ppt) diff --git a/base/gxpcmap.c b/base/gxpcmap.c index e6ec7b9a..bdcca0c8 100644 --- a/base/gxpcmap.c +++ b/base/gxpcmap.c @@ -101,97 +101,55 @@ static dev_proc_fill_rectangle_hl_color(pattern_accum_fill_rectangle_hl_color); dev_proc_dev_spec_op(pattern_accum_dev_spec_op); /* The device descriptor */ +static void +pattern_accum_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, pattern_accum_open); + set_dev_proc(dev, close_device, pattern_accum_close); + set_dev_proc(dev, fill_rectangle, pattern_accum_fill_rectangle); + set_dev_proc(dev, copy_mono, pattern_accum_copy_mono); + set_dev_proc(dev, copy_color, pattern_accum_copy_color); + set_dev_proc(dev, get_clipping_box, gx_get_largest_clipping_box); + set_dev_proc(dev, get_bits_rectangle, pattern_accum_get_bits_rectangle); + set_dev_proc(dev, fill_rectangle_hl_color, pattern_accum_fill_rectangle_hl_color); + set_dev_proc(dev, dev_spec_op, pattern_accum_dev_spec_op); + set_dev_proc(dev, copy_planes, pattern_accum_copy_planes); + + /* It would be much nicer if gx_device_init set the following + * defaults for us, but that doesn't work for some reason. */ + set_dev_proc(dev, copy_alpha, gx_default_copy_alpha); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, stroke_path, gx_default_stroke_path); + set_dev_proc(dev, fill_mask, gx_default_fill_mask); + set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + set_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + set_dev_proc(dev, composite, gx_default_composite); + set_dev_proc(dev, text_begin, gx_default_text_begin); + set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2); + set_dev_proc(dev, strip_tile_rect_devn, gx_default_strip_tile_rect_devn); + set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region); + set_dev_proc(dev, fill_stroke_path, gx_default_fill_stroke_path); +} + static const gx_device_pattern_accum gs_pattern_accum_device = -{std_device_std_body_type_open(gx_device_pattern_accum, 0, - "pattern accumulator", &st_device_pattern_accum, - 0, 0, 72, 72), - { - /* NOTE: all drawing procedures must be defaulted, not forwarded. */ - pattern_accum_open, - NULL, /* get_initial_matrix */ - NULL, /* sync_output */ - NULL, /* output_page */ - pattern_accum_close, - NULL, /* map_rgb_color */ - NULL, /* map_color_rgb */ - pattern_accum_fill_rectangle, - gx_default_tile_rectangle, - pattern_accum_copy_mono, - pattern_accum_copy_color, - NULL, /* obselete_draw_line */ - gx_default_get_bits, - NULL, /* get_params */ - NULL, /* put_params */ - NULL, /* map_cmyk_color */ - NULL, /* get_xfont_procs */ - NULL, /* get_xfont_device */ - NULL, /* map_rgb_alpha_color */ - NULL, /* get_page_device */ - NULL, /* get_alpha_bits */ - gx_default_copy_alpha, - NULL, /* get_band */ - gx_default_copy_rop, - gx_default_fill_path, - gx_default_stroke_path, - gx_default_fill_mask, - gx_default_fill_trapezoid, - gx_default_fill_parallelogram, - gx_default_fill_triangle, - gx_default_draw_thin_line, - gx_default_begin_image, - gx_default_image_data, - gx_default_end_image, - gx_default_strip_tile_rectangle, - gx_default_strip_copy_rop, - gx_get_largest_clipping_box, - gx_default_begin_typed_image, - pattern_accum_get_bits_rectangle, - NULL, /* map_color_rgb_alpha */ - gx_default_create_compositor, - NULL, /* create_compositor */ - gx_default_text_begin, - gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ - NULL, /* get_color_mapping_procs */ - NULL, /* get_color_comp_index */ - NULL, /* encode_color */ - NULL, /* decode_color */ - NULL, /* pattern_manage */ - pattern_accum_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ - NULL, /* include_color_space */ - NULL, /* fill_linear_color_scanline */ - NULL, /* fill_linear_color_trapezoid */ - NULL, /* fill_linear_color_triangle */ - NULL, /* update_spot_equivalent_colors */ - NULL, /* ret_devn_params */ - NULL, /* fillpage */ - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ - pattern_accum_dev_spec_op, /* dev_spec_op */ - pattern_accum_copy_planes, /* copy_planes */ - NULL, /* get_profile */ - NULL, /* set_graphics_type_tag */ - gx_default_strip_copy_rop2, - gx_default_strip_tile_rect_devn, - NULL, /* alpha_hl_color */ - NULL, /* process_page */ - gx_default_transform_pixel_region, /* NOT the default forwarding one */ - gx_default_fill_stroke_path, -}, - 0, /* target */ - 0, 0, 0, 0 /* bitmap_memory, bits, mask, instance */ +{std_device_std_body_type_open(gx_device_pattern_accum, + pattern_accum_initialize_device_procs, + "pattern accumulator", + &st_device_pattern_accum, + 0, 0, 72, 72) }; +extern dev_proc_open_device(clist_open); + int pattern_clist_open_device(gx_device *dev) { /* This function is defiled only for clist_init_bands. */ - return gs_clist_device_procs.open_device(dev); + return clist_open(dev); } static dev_proc_create_buf_device(dummy_create_buf_device) @@ -296,9 +254,9 @@ gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * storage_memory, emprintf(mem, "not using clist even though clist is requested\n"); #endif pinst->is_clist = false; - gx_device_init((gx_device *)adev, - (const gx_device *)&gs_pattern_accum_device, - mem, true); + (void)gx_device_init((gx_device *)adev, + (const gx_device *)&gs_pattern_accum_device, + mem, true); adev->instance = pinst; adev->bitmap_memory = storage_memory; fdev = (gx_device_forward *)adev; @@ -673,6 +631,8 @@ blank_unmasked_bits(gx_device * mask, int code = 0; byte *ptr; int blank = (polarity == GX_CINFO_POLARITY_ADDITIVE ? 255 : 0); + gs_int_rect rect; + gs_get_bits_params_t params; if ((p->options & required_options) != required_options) return_error(gs_error_rangecheck); @@ -681,6 +641,11 @@ blank_unmasked_bits(gx_device * mask, if (min == NULL) return_error(gs_error_VMerror); + rect.p.x = 0; + rect.q.x = mask->width; + params.x_offset = 0; + params.raster = bitmap_raster(mask->width * mask->color_info.depth); + if (p->options & GB_PACKING_CHUNKY) { if ((depth & 7) != 0 || depth > 64) @@ -691,9 +656,20 @@ blank_unmasked_bits(gx_device * mask, for (y = 0; y < h; y++) { byte *mine; - code = dev_proc(mask, get_bits)(mask, y+y0, min, &mine); + + rect.p.y = y+y0; + rect.q.y = y+y0+1; + params.options = (GB_ALIGN_ANY | + (GB_RETURN_COPY | GB_RETURN_POINTER) | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.data[0] = min; + code = (*dev_proc(mask, get_bits_rectangle))(mask, &rect, + ¶ms); if (code < 0) goto fail; + mine = params.data[0]; for (x = 0; x < w; x++) { int xx = x+x0; @@ -734,9 +710,21 @@ blank_unmasked_bits(gx_device * mask, { int c; byte *mine; - code = dev_proc(mask, get_bits)(mask, y+y0, min, &mine); + + rect.p.y = y+y0; + rect.q.y = y+y0+1; + params.options = (GB_ALIGN_ANY | + (GB_RETURN_COPY | GB_RETURN_POINTER) | + GB_OFFSET_0 | + GB_RASTER_STANDARD | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.data[0] = min; + code = (*dev_proc(mask, get_bits_rectangle))(mask, &rect, + ¶ms); if (code < 0) goto fail; + mine = params.data[0]; + for (c = 0; c < num_comps; c++) { if (p->data[c] == NULL) @@ -767,7 +755,7 @@ fail: /****** SHOULD USE MASK TO DEFINE UNREAD AREA *****/ static int pattern_accum_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - gs_get_bits_params_t * params, gs_int_rect ** unread) + gs_get_bits_params_t * params) { gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev; int code; @@ -777,7 +765,7 @@ pattern_accum_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, if (padev->mask) params2.options &= ~GB_RETURN_POINTER; code = (*dev_proc(padev->target, get_bits_rectangle)) - (padev->target, prect, ¶ms2, unread); + (padev->target, prect, ¶ms2); /* If we have a mask, then unmarked pixels of the bits * will be undefined. Strictly speaking it makes no * sense for us to return any value here, but the only diff --git a/base/gxsamplp.h b/base/gxsamplp.h index 143b240c..8d5e39f9 100644 --- a/base/gxsamplp.h +++ b/base/gxsamplp.h @@ -325,4 +325,3 @@ TEMPLATE_sample_unpack_8(byte * bptr, int *pdata_x, const byte * data, int data_ #else int dummy; #endif - diff --git a/base/gxshade.c b/base/gxshade.c index 80e3b742..69134fb0 100644 --- a/base/gxshade.c +++ b/base/gxshade.c @@ -87,6 +87,7 @@ shade_next_init(shade_coord_stream_t * cs, cs->is_eod = cs_eod; cs->left = 0; cs->ds_EOF = false; + cs->first_patch = 1; } /* Check for the End-Of-Data state form a stream. */ @@ -365,7 +366,7 @@ top: } if (num_colors <= 32) { /****** WRONG FOR MULTI-PLANE HALFTONES ******/ - num_colors *= pgs->dev_ht->components[0].corder.num_levels; + num_colors *= pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; } if (psh->head.type == 2 || psh->head.type == 3) { max_error *= 0.25; @@ -390,7 +391,7 @@ top: return code; } rendering_params.black_point_comp = pgs->blackptcomp; - rendering_params.graphics_type_tag = GS_PATH_TAG; + rendering_params.graphics_type_tag = GS_VECTOR_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; rendering_params.rendering_intent = pgs->renderingintent; diff --git a/base/gxshade.h b/base/gxshade.h index 4990b25e..3a2de811 100644 --- a/base/gxshade.h +++ b/base/gxshade.h @@ -122,6 +122,7 @@ struct shade_coord_stream_s { const float decode[2], float *pvalue); void (*align)(shade_coord_stream_t *cs, int radix); bool (*is_eod)(const shade_coord_stream_t *cs); + int first_patch; /* True, if we have not read a patch yet */ }; /* Define one vertex of a mesh. */ diff --git a/base/gxshade1.c b/base/gxshade1.c index c105f6cf..fc207718 100644 --- a/base/gxshade1.c +++ b/base/gxshade1.c @@ -175,6 +175,165 @@ typedef struct A_fill_state_s { /* Note t0 and t1 vary over [0..1], not the Domain. */ +typedef struct +{ + patch_curve_t curve[4]; + gs_point corners[4]; +} corners_and_curves; + +/* Ghostscript cannot possibly render any patch whose bounds aren't + * representable in fixed's. In fact, this is a larger limit than + * we need. We notionally have an area defined by coordinates + * that can be represented in fixed point with at least 1 bit to + * spare. + * + * Any patch that lies completely outside this region can be clipped + * away. Any patch that isn't representable by fixed points can be + * subdivided into 4. + * + * This avoids us subdividing patches huge numbers of times because + * one side is just outside the region we will accept. + */ + + +#define MIN_CLIP_LIMIT ((int)(fixed2int(min_fixed)/2)) +#define MAX_CLIP_LIMIT ((int)(fixed2int(max_fixed)/2)) + +static int not_clipped_away(const gs_point *p) +{ + if (p[0].x < MIN_CLIP_LIMIT && + p[1].x < MIN_CLIP_LIMIT && + p[2].x < MIN_CLIP_LIMIT && + p[3].x < MIN_CLIP_LIMIT) + return 0; /* Clipped away! */ + if (p[0].x > MAX_CLIP_LIMIT && + p[1].x > MAX_CLIP_LIMIT && + p[2].x > MAX_CLIP_LIMIT && + p[3].x > MAX_CLIP_LIMIT) + return 0; /* Clipped away! */ + if (p[0].y < MIN_CLIP_LIMIT && + p[1].y < MIN_CLIP_LIMIT && + p[2].y < MIN_CLIP_LIMIT && + p[3].y < MIN_CLIP_LIMIT) + return 0; /* Clipped away! */ + if (p[0].y > MAX_CLIP_LIMIT && + p[1].y > MAX_CLIP_LIMIT && + p[2].y > MAX_CLIP_LIMIT && + p[3].y > MAX_CLIP_LIMIT) + return 0; /* Clipped away! */ + return 1; +} + +#define f_fits_in_fixed(f) f_fits_in_bits(f, fixed_int_bits) + +static int +A_fill_region_floats(patch_fill_state_t *pfs1, corners_and_curves *cc, int depth) +{ + corners_and_curves sub[4]; + int code; + + if (depth == 32) + return gs_error_limitcheck; + + if (depth > 0 && + f_fits_in_fixed(cc->corners[0].x) && + f_fits_in_fixed(cc->corners[0].y) && + f_fits_in_fixed(cc->corners[1].x) && + f_fits_in_fixed(cc->corners[1].y) && + f_fits_in_fixed(cc->corners[2].x) && + f_fits_in_fixed(cc->corners[2].y) && + f_fits_in_fixed(cc->corners[3].x) && + f_fits_in_fixed(cc->corners[3].y)) + { + cc->curve[0].vertex.p.x = float2fixed(cc->corners[0].x); + cc->curve[0].vertex.p.y = float2fixed(cc->corners[0].y); + cc->curve[1].vertex.p.x = float2fixed(cc->corners[1].x); + cc->curve[1].vertex.p.y = float2fixed(cc->corners[1].y); + cc->curve[2].vertex.p.x = float2fixed(cc->corners[2].x); + cc->curve[2].vertex.p.y = float2fixed(cc->corners[2].y); + cc->curve[3].vertex.p.x = float2fixed(cc->corners[3].x); + cc->curve[3].vertex.p.y = float2fixed(cc->corners[3].y); + cc->curve[0].vertex.cc[1] = cc->curve[1].vertex.cc[1] = + cc->curve[2].vertex.cc[1] = + cc->curve[3].vertex.cc[1] = 0; + make_other_poles(cc->curve); + return patch_fill(pfs1, cc->curve, NULL, NULL); + } + + /* We have patches with corners: + * 0 1 + * 3 2 + * We subdivide these into 4 smaller patches: + * + * 0 10 1 Where 0123 are corners + * [0] [1] [0][1][2][3] are patches. + * 3 23 2 + * 0 10 1 + * [3] [2] + * 3 23 2 + */ + + sub[0].corners[0].x = cc->corners[0].x; + sub[0].corners[0].y = cc->corners[0].y; + sub[1].corners[1].x = cc->corners[1].x; + sub[1].corners[1].y = cc->corners[1].y; + sub[2].corners[2].x = cc->corners[2].x; + sub[2].corners[2].y = cc->corners[2].y; + sub[3].corners[3].x = cc->corners[3].x; + sub[3].corners[3].y = cc->corners[3].y; + sub[1].corners[0].x = sub[0].corners[1].x = (cc->corners[0].x + cc->corners[1].x)/2; + sub[1].corners[0].y = sub[0].corners[1].y = (cc->corners[0].y + cc->corners[1].y)/2; + sub[3].corners[2].x = sub[2].corners[3].x = (cc->corners[2].x + cc->corners[3].x)/2; + sub[3].corners[2].y = sub[2].corners[3].y = (cc->corners[2].y + cc->corners[3].y)/2; + sub[3].corners[0].x = sub[0].corners[3].x = (cc->corners[0].x + cc->corners[3].x)/2; + sub[3].corners[0].y = sub[0].corners[3].y = (cc->corners[0].y + cc->corners[3].y)/2; + sub[2].corners[1].x = sub[1].corners[2].x = (cc->corners[1].x + cc->corners[2].x)/2; + sub[2].corners[1].y = sub[1].corners[2].y = (cc->corners[1].y + cc->corners[2].y)/2; + sub[0].corners[2].x = sub[1].corners[3].x = + sub[2].corners[0].x = + sub[3].corners[1].x = (sub[0].corners[3].x + sub[1].corners[2].x)/2; + sub[0].corners[2].y = sub[1].corners[3].y = + sub[2].corners[0].y = + sub[3].corners[1].y = (sub[0].corners[3].y + sub[1].corners[2].y)/2; + sub[0].curve[0].vertex.cc[0] = sub[0].curve[3].vertex.cc[0] = + sub[3].curve[0].vertex.cc[0] = + sub[3].curve[3].vertex.cc[0] = cc->curve[0].vertex.cc[0]; + sub[1].curve[1].vertex.cc[0] = sub[1].curve[2].vertex.cc[0] = + sub[2].curve[1].vertex.cc[0] = + sub[2].curve[2].vertex.cc[0] = cc->curve[1].vertex.cc[0]; + sub[0].curve[1].vertex.cc[0] = sub[0].curve[2].vertex.cc[0] = + sub[1].curve[0].vertex.cc[0] = + sub[1].curve[3].vertex.cc[0] = + sub[2].curve[0].vertex.cc[0] = + sub[2].curve[3].vertex.cc[0] = + sub[3].curve[1].vertex.cc[0] = + sub[3].curve[2].vertex.cc[0] = (cc->curve[0].vertex.cc[0] + cc->curve[1].vertex.cc[0])/2; + + depth++; + if (not_clipped_away(sub[0].corners)) { + code = A_fill_region_floats(pfs1, &sub[0], depth); + if (code < 0) + return code; + } + if (not_clipped_away(sub[1].corners)) { + code = A_fill_region_floats(pfs1, &sub[1], depth); + if (code < 0) + return code; + } + if (not_clipped_away(sub[2].corners)) { + code = A_fill_region_floats(pfs1, &sub[2], depth); + if (code < 0) + return code; + } + if (not_clipped_away(sub[3].corners)) { + code = A_fill_region_floats(pfs1, &sub[3], depth); + if (code < 0) + return code; + } + + return 0; +} + static int A_fill_region(A_fill_state_t * pfs, patch_fill_state_t *pfs1) { @@ -184,31 +343,60 @@ A_fill_region(A_fill_state_t * pfs, patch_fill_state_t *pfs1) double x1 = psh->params.Coords[0] + pfs->delta.x * pfs->v1; double y1 = psh->params.Coords[1] + pfs->delta.y * pfs->v1; double h0 = pfs->u0, h1 = pfs->u1; - patch_curve_t curve[4]; + corners_and_curves cc; int code; - code = gs_point_transform2fixed(&pfs1->pgs->ctm, x0 + pfs->delta.y * h0, y0 - pfs->delta.x * h0, &curve[0].vertex.p); + double dx0 = pfs->delta.x * h0; + double dy0 = pfs->delta.y * h0; + double dx1 = pfs->delta.x * h1; + double dy1 = pfs->delta.y * h1; + + cc.curve[0].vertex.cc[0] = pfs->t0; /* The element cc[1] is set to a dummy value against */ + cc.curve[1].vertex.cc[0] = pfs->t1; /* interrupts while an idle priocessing in gxshade.6.c . */ + cc.curve[2].vertex.cc[0] = pfs->t1; + cc.curve[3].vertex.cc[0] = pfs->t0; + cc.curve[0].vertex.cc[1] = 0; /* The element cc[1] is set to a dummy value against */ + cc.curve[1].vertex.cc[1] = 0; /* interrupts while an idle priocessing in gxshade.6.c . */ + cc.curve[2].vertex.cc[1] = 0; + cc.curve[3].vertex.cc[1] = 0; + cc.corners[0].x = x0 + dy0; + cc.corners[0].y = y0 - dx0; + cc.corners[1].x = x1 + dy0; + cc.corners[1].y = y1 - dx0; + cc.corners[2].x = x1 + dy1; + cc.corners[2].y = y1 - dx1; + cc.corners[3].x = x0 + dy1; + cc.corners[3].y = y0 - dx1; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, cc.corners[0].x, cc.corners[0].y, &cc.curve[0].vertex.p); + if (code < 0) + goto fail; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, cc.corners[1].x, cc.corners[1].y, &cc.curve[1].vertex.p); + if (code < 0) + goto fail; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, cc.corners[2].x, cc.corners[2].y, &cc.curve[2].vertex.p); + if (code < 0) + goto fail; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, cc.corners[3].x, cc.corners[3].y, &cc.curve[3].vertex.p); + if (code < 0) + goto fail; + make_other_poles(cc.curve); + return patch_fill(pfs1, cc.curve, NULL, NULL); +fail: + if (code != gs_error_limitcheck) + return code; + code = gs_point_transform(cc.corners[0].x, cc.corners[0].y, (const gs_matrix *)&pfs1->pgs->ctm, &cc.corners[0]); if (code < 0) return code; - code = gs_point_transform2fixed(&pfs1->pgs->ctm, x1 + pfs->delta.y * h0, y1 - pfs->delta.x * h0, &curve[1].vertex.p); + code = gs_point_transform(cc.corners[1].x, cc.corners[1].y, (const gs_matrix *)&pfs1->pgs->ctm, &cc.corners[1]); if (code < 0) return code; - code = gs_point_transform2fixed(&pfs1->pgs->ctm, x1 + pfs->delta.y * h1, y1 - pfs->delta.x * h1, &curve[2].vertex.p); + code = gs_point_transform(cc.corners[2].x, cc.corners[2].y, (const gs_matrix *)&pfs1->pgs->ctm, &cc.corners[2]); if (code < 0) return code; - code = gs_point_transform2fixed(&pfs1->pgs->ctm, x0 + pfs->delta.y * h1, y0 - pfs->delta.x * h1, &curve[3].vertex.p); + code = gs_point_transform(cc.corners[3].x, cc.corners[3].y, (const gs_matrix *)&pfs1->pgs->ctm, &cc.corners[3]); if (code < 0) return code; - curve[0].vertex.cc[0] = pfs->t0; /* The element cc[1] is set to a dummy value against */ - curve[1].vertex.cc[0] = pfs->t1; /* interrupts while an idle priocessing in gxshade.6.c . */ - curve[2].vertex.cc[0] = pfs->t1; - curve[3].vertex.cc[0] = pfs->t0; - curve[0].vertex.cc[1] = 0; /* The element cc[1] is set to a dummy value against */ - curve[1].vertex.cc[1] = 0; /* interrupts while an idle priocessing in gxshade.6.c . */ - curve[2].vertex.cc[1] = 0; - curve[3].vertex.cc[1] = 0; - make_other_poles(curve); - return patch_fill(pfs1, curve, NULL, NULL); + return A_fill_region_floats(pfs1, &cc, 0); } static inline int diff --git a/base/gxshade6.c b/base/gxshade6.c index e8f9349b..334e05a6 100644 --- a/base/gxshade6.c +++ b/base/gxshade6.c @@ -169,7 +169,7 @@ shade_next_curve(shade_coord_stream_t * cs, patch_curve_t * curve) */ static int shade_next_patch(shade_coord_stream_t * cs, int BitsPerFlag, - patch_curve_t curve[4], gs_fixed_point interior[4] /* 0 for Coons patch */ ) + patch_curve_t curve[4], gs_fixed_point interior[4] /* 0 for Coons patch */) { int flag = shade_next_flag(cs, BitsPerFlag); int num_colors, code; @@ -179,6 +179,10 @@ shade_next_patch(shade_coord_stream_t * cs, int BitsPerFlag, return_error(gs_error_rangecheck); return 1; /* no more data */ } + if (cs->first_patch && (flag & 3) != 0) { + return_error(gs_error_rangecheck); + } + cs->first_patch = 0; switch (flag & 3) { default: return_error(gs_error_rangecheck); /* not possible */ diff --git a/base/gxtext.h b/base/gxtext.h index e6836ae7..babaaf1e 100644 --- a/base/gxtext.h +++ b/base/gxtext.h @@ -97,8 +97,6 @@ rc_free_proc(rc_free_text_enum); gx_device *imaging_dev; /* see note below */\ gs_gstate *pgs;\ gs_font *orig_font;\ - gx_path *path; /* unless DO_NONE & !RETURN_WIDTH */\ - const gx_device_color *pdcolor; /* if DO_DRAW */\ const gx_clip_path *pcpath; /* if DO_DRAW */\ gs_memory_t *memory;\ /* The following additional members are set at initialization. */\ @@ -175,6 +173,8 @@ struct gs_text_enum_s { gs_text_enum_common; }; +#define gs_text_enum_path(pte) ((pte)->pgs->path) + /* * Notes on the imaging_dev field of device enumeration structures: * @@ -227,8 +227,7 @@ int gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, - gs_font *font, gx_path *path, - const gx_device_color *pdcolor, + gs_font *font, const gx_clip_path *pcpath, gs_memory_t *mem); diff --git a/base/gzht.h b/base/gzht.h index 9c1e0fe8..358bd350 100644 --- a/base/gzht.h +++ b/base/gzht.h @@ -196,7 +196,14 @@ void gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cach int gx_gstate_dev_ht_install(gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, - const gx_device * dev); + const gx_device * dev, + gs_HT_objtype_t objtype); + +/* + * Copy the current dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. + */ +int +gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype); /* * Install a new halftone in the graphics state. Note that we copy the top diff --git a/base/gzspotan.c b/base/gzspotan.c index 847f3c9d..4deef1c8 100644 --- a/base/gzspotan.c +++ b/base/gzspotan.c @@ -205,63 +205,18 @@ trap_is_last(const gx_san_trap *list, const gx_san_trap *t) /* The device descriptor */ /* Many of these procedures won't be called; they are set to NULL. */ +static void +san_initialize_device_procs(gx_device *dev) +{ + set_dev_proc(dev, open_device, san_open); + set_dev_proc(dev, close_device, san_close); + set_dev_proc(dev, fill_path, gx_default_fill_path); + set_dev_proc(dev, get_clipping_box, san_get_clipping_box); +} static const gx_device_spot_analyzer gx_spot_analyzer_device = -{std_device_std_body(gx_device_spot_analyzer, 0, "spot analyzer", - 0, 0, 1, 1), - {san_open, - NULL, - NULL, - NULL, - san_close, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - gx_default_fill_path, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - san_get_clipping_box, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - gx_default_finish_copydevice, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - } +{std_device_std_body(gx_device_spot_analyzer, + san_initialize_device_procs, "spot analyzer", + 0, 0, 1, 1) }; int @@ -419,8 +374,11 @@ gx_san__obtain(gs_memory_t *mem, gx_device_spot_analyzer **ppadev) &st_device_spot_analyzer, "gx_san__obtain"); if (padev == 0) return_error(gs_error_VMerror); - gx_device_init((gx_device *)padev, (const gx_device *)&gx_spot_analyzer_device, - mem, false); + code = gx_device_init((gx_device *)padev, + (const gx_device *)&gx_spot_analyzer_device, + mem, false); + if (code < 0) + return code; code = gs_opendevice((gx_device *)padev); if (code < 0) { gs_free_object(mem, padev, "gx_san__obtain"); diff --git a/base/lcups.mak b/base/lcups.mak index 5189fe71..001b538c 100644 --- a/base/lcups.mak +++ b/base/lcups.mak @@ -30,7 +30,7 @@ LCUPSO_=$(O_)$(LIBCUPSOBJ) # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the cups source. -LCUPS_CC=$(CUPS_CC) $(I_)$(LIBCUPSSRC) $(I_)$(LIBCUPSGEN)$(D)cups $(I_)$(LCUPSSRCDIR)$(D)libs +LCUPS_CC=$(CUPS_CC) $(CUPSCFLAGS) $(I_)$(LIBCUPSSRC) $(I_)$(LIBCUPSGEN)$(D)cups $(I_)$(LCUPSSRCDIR)$(D)libs # Define the name of this makefile. LCUPS_MAK=$(GLSRC)lcups.mak $(TOP_MAKEFILES) diff --git a/base/leptonica.mak b/base/leptonica.mak index df72241d..5ffcee63 100644 --- a/base/leptonica.mak +++ b/base/leptonica.mak @@ -4,7 +4,7 @@ LEPTINCLUDES=\ $(I_)$(GLGENDIR)$(_I) LEPTCFLAGS_LOCAL=\ - -DLEPTONICA_INTERCEPT_MALLOC=1\ + -DLEPTONICA_INTERCEPT_ALLOC=1\ -DHAVE_LIBJPEG=0\ -DHAVE_LIBTIFF=0\ -DHAVE_LIBPNG=0\ @@ -15,7 +15,7 @@ LEPTCFLAGS_LOCAL=\ -DHAVE_LIBWEBP_ANIM=0\ -DHAVE_LIBJP2K=0 -LEPTCC = $(CC) $(CCFLAGS) $(LEPTINCLUDES) $(LEPTCFLAGS_LOCAL) +LEPTCC = $(CC) $(CCFLAGS) $(LEPTINCLUDES) $(LEPTCFLAGS_LOCAL) $(LEPTSUPPRESS) LEPTOBJ = $(GLOBJDIR)$(D)leptonica_ LEPTO_ = $(O_)$(LEPTOBJ) diff --git a/base/lib.mak b/base/lib.mak index f6845c97..e8d5719d 100644 --- a/base/lib.mak +++ b/base/lib.mak @@ -434,6 +434,7 @@ gsccolor_h=$(GLSRC)gsccolor.h # gscedata.[ch] are generated automatically by lib/encs2c.ps. gscedata_h=$(GLSRC)gscedata.h gscencs_h=$(GLSRC)gscencs.h +gsagl_h=$(GLSRC)gsagl.h gsclipsr_h=$(GLSRC)gsclipsr.h gscsel_h=$(GLSRC)gscsel.h gscolor1_h=$(GLSRC)gscolor1.h @@ -488,7 +489,6 @@ gxcoord_h=$(GLSRC)gxcoord.h gxcpath_h=$(GLSRC)gxcpath.h gxdda_h=$(GLSRC)gxdda.h gxdevbuf_h=$(GLSRC)gxdevbuf.h -gxdevrop_h=$(GLSRC)gxdevrop.h gxdevmem_h=$(GLSRC)gxdevmem.h gxdhtres_h=$(GLSRC)gxdhtres.h gxfont0_h=$(GLSRC)gxfont0.h @@ -1012,7 +1012,7 @@ $(GLOBJ)gsgcache.$(OBJ) : $(GLSRC)gsgcache.c $(AK) $(gx_h)\ $(GLCC) $(GLO_)gsgcache.$(OBJ) $(C_) $(GLSRC)gsgcache.c $(GLOBJ)gsht.$(OBJ) : $(GLSRC)gsht.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxarith_h)\ + $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxarith_h) $(gxdevsop_h)\ $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(gp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsht.$(OBJ) $(C_) $(GLSRC)gsht.c @@ -1969,8 +1969,9 @@ $(GLOBJ)sfilter1.$(OBJ) : $(GLSRC)sfilter1.c $(AK) $(stdio__h) $(memory__h)\ $(GLCC) $(GLO_)sfilter1.$(OBJ) $(C_) $(GLSRC)sfilter1.c $(GLD)psfilters.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)sfilter2.$(OBJ)\ - $(GLOBJ)sfilter1.$(OBJ) $(LIB_MAK) $(MAKEDIRS) - $(SETMOD) $(GLD)psfilters $(GLOBJ)sfilter1.$(OBJ) $(GLOBJ)sfilter2.$(OBJ) + $(GLOBJ)sfilter1.$(OBJ) $(GLOBJ)sa85d.$(OBJ) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)psfilters $(GLOBJ)sfilter1.$(OBJ) $(GLOBJ)sfilter2.$(OBJ) $(GLOBJ)sa85d.$(OBJ) + $(ADDMOD) $(GLD)psfilters $(GLOBJ)sa85d.$(OBJ) $(GLOBJ)sstring.$(OBJ) : $(GLSRC)sstring.c $(AK)\ $(stdio__h) $(memory__h) $(string__h)\ @@ -2407,13 +2408,13 @@ $(GLD)roplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(roplib_) $(LIB_MAK) $(MAKEDIRS) $(GLOBJ)gdevdrop_1.$(OBJ) : $(GLSRC)gdevdrop.c $(AK) $(gx_h) $(gserrors_h) \ $(memory__h) $(gxdevsop_h) $(gsbittab_h) $(gsropt_h) $(gxcindex_h) \ - $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h) $(gxgetbit_h) \ + $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) \ $(gdevmem_h) $(gdevmrop_h) $(gdevmpla_h) $(stdint__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(D_)WITH_CAL$(_D) $(I_)$(CALSRCDIR)$(_I) $(GLO_)gdevdrop_1.$(OBJ) $(C_) $(GLSRC)gdevdrop.c $(GLOBJ)gdevdrop_0.$(OBJ) : $(GLSRC)gdevdrop.c $(AK) $(gx_h) $(gserrors_h) \ $(memory__h) $(gxdevsop_h) $(gsbittab_h) $(gsropt_h) $(gxcindex_h) \ - $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h) $(gxgetbit_h) \ + $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) \ $(gdevmem_h) $(gdevmrop_h) $(gdevmpla_h) $(stdint__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdrop_0.$(OBJ) $(C_) $(GLSRC)gdevdrop.c @@ -3398,6 +3399,33 @@ $(GLGEN)xpsromfs0_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) $(GLGEN)xpsromfs0.c : $(GLGEN)xpsromfs0_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)xpsromfs0_$(UFST_BRIDGE).c $(GLGEN)xpsromfs0.c +# pdf +$(GLGEN)pdfromfs1_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdfromfs1_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(PDF_ROMFS_ARGS) $(PDF_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)pdfromfs1_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdfromfs1_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(PDF_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)pdfromfs1.c : $(GLGEN)pdfromfs1_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pdfromfs1_$(UFST_BRIDGE).c $(GLGEN)pdfromfs1.c + +$(GLGEN)pdfromfs0_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdfromfs0_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pdfromfs0_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdfromfs0_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pdfromfs0.c : $(GLGEN)pdfromfs0_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pdfromfs0_$(UFST_BRIDGE).c $(GLGEN)pdfromfs0.c + # pdl # We generate the pdl romfs in index + 4 lumps because of size @@ -3546,6 +3574,13 @@ $(GLOBJ)xpsromfs0.$(OBJ) : $(GLGEN)xpsromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIR $(GLOBJ)xpsromfs1.$(OBJ) : $(GLOBJ)xpsromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)xpsromfs1.$(OBJ) $(C_) $(GLOBJ)xpsromfs1.c +# A pdfromfs module with only ICC profiles for COMPILE_INITS=0 +$(GLOBJ)pdfromfs0.$(OBJ) : $(GLGEN)pdfromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pdfromfs0.$(OBJ) $(C_) $(GLGEN)pdfromfs0.c + +$(GLOBJ)pdfromfs1.$(OBJ) : $(GLOBJ)pdfromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pdfromfs1.$(OBJ) $(C_) $(GLOBJ)pdfromfs1.c + # A pdlromfs module with only ICC profiles for COMPILE_INITS=0 $(GLOBJ)pdlromfs0.$(OBJ) : $(GLGEN)pdlromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)pdlromfs0.$(OBJ) $(C_) $(GLGEN)pdlromfs0.c @@ -3719,6 +3754,16 @@ $(GLOBJ)gp_nxpsprn.$(OBJ) : $(GLSRC)gp_nxpsprn.c $(gp_h) $(std_h) $(LIB_MAK) \ $(AK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_nxpsprn.$(OBJ) $(C_) $(GLSRC)gp_nxpsprn.c +# ================ Adobe Glyph List ================ # + +gsagl_=$(GLOBJ)gsagl.$(OBJ) +$(GLD)gsagl.dev : $(LIB_MAK) $(ECHOGS_XE) $(gsagl_) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)gsagl $(gsagl_) + +$(GLOBJ)gsagl.$(OBJ) : $(GLSRC)gsagl.c $(GDEV)\ + $(gsagl_h) $(DEVS_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gsagl.$(OBJ) $(C_) $(GLSRC)gsagl.c + # ================ Dependencies for auxiliary programs ================ # GENARCH_DEPS=$(stdpre_h) @@ -5585,75 +5630,6 @@ $(GLSRC)gxdevbuf.h:$(GLSRC)std.h $(GLSRC)gxdevbuf.h:$(GLSRC)stdpre.h $(GLSRC)gxdevbuf.h:$(GLGEN)arch.h $(GLSRC)gxdevbuf.h:$(GLSRC)gs_dll_call.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxdevcli.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxcmap.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxtext.h -$(GLSRC)gxdevrop.h:$(GLSRC)gstext.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsnamecl.h -$(GLSRC)gxdevrop.h:$(GLSRC)gstparam.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxfmap.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsfunc.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxcspace.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxrplane.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscsel.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxfcache.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsfont.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsimage.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsdcolor.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxcvalue.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxbcache.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsropt.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxdda.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxpath.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxfrac.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxtmap.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxftype.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscms.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsrect.h -$(GLSRC)gxdevrop.h:$(GLSRC)gslparam.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsdevice.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscpm.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscspace.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsgstate.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsxfont.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsdsrc.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsiparam.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxfixed.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscompt.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsmatrix.h -$(GLSRC)gxdevrop.h:$(GLSRC)gspenum.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxhttile.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsparam.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsrefct.h -$(GLSRC)gxdevrop.h:$(GLSRC)gp.h -$(GLSRC)gxdevrop.h:$(GLSRC)memento.h -$(GLSRC)gxdevrop.h:$(GLSRC)memory_.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsuid.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsstruct.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxsync.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxbitmap.h -$(GLSRC)gxdevrop.h:$(GLSRC)srdline.h -$(GLSRC)gxdevrop.h:$(GLSRC)scommon.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsbitmap.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsccolor.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxarith.h -$(GLSRC)gxdevrop.h:$(GLSRC)stat_.h -$(GLSRC)gxdevrop.h:$(GLSRC)gpsync.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsstype.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsmemory.h -$(GLSRC)gxdevrop.h:$(GLSRC)gpgetenv.h -$(GLSRC)gxdevrop.h:$(GLSRC)gscdefs.h -$(GLSRC)gxdevrop.h:$(GLSRC)gslibctx.h -$(GLSRC)gxdevrop.h:$(GLSRC)gxcindex.h -$(GLSRC)gxdevrop.h:$(GLSRC)stdio_.h -$(GLSRC)gxdevrop.h:$(GLSRC)gsccode.h -$(GLSRC)gxdevrop.h:$(GLSRC)stdint_.h -$(GLSRC)gxdevrop.h:$(GLSRC)gssprintf.h -$(GLSRC)gxdevrop.h:$(GLSRC)gstypes.h -$(GLSRC)gxdevrop.h:$(GLSRC)std.h -$(GLSRC)gxdevrop.h:$(GLSRC)stdpre.h -$(GLSRC)gxdevrop.h:$(GLGEN)arch.h -$(GLSRC)gxdevrop.h:$(GLSRC)gs_dll_call.h $(GLSRC)gxdevmem.h:$(GLSRC)gxdevcli.h $(GLSRC)gxdevmem.h:$(GLSRC)gxcmap.h $(GLSRC)gxdevmem.h:$(GLSRC)gxtext.h diff --git a/base/memento.c b/base/memento.c index fddb17fe..56b7788b 100644 --- a/base/memento.c +++ b/base/memento.c @@ -1099,6 +1099,12 @@ static void Memento_addBlockTail(Memento_Blocks *blks, } typedef struct BlkCheckData { + /* found holds some bits: + * Bit 0 (1) -> At least one block has been checked. + * Bit 1 (2) -> We have found an "Allocated block". + * Bit 2 (4) -> We have found a "Freed block". + * Bit 3 (8) -> Trigger a breakpoint on completion. + */ int found; int preCorrupt; int postCorrupt; @@ -1639,6 +1645,7 @@ void Memento_blockInfo(void *p) #ifdef MEMENTO_DETAILS MEMENTO_LOCK(); Memento_appBlocks(&memento.used, showBlockInfo, p); + Memento_appBlocks(&memento.free, showBlockInfo, p); MEMENTO_UNLOCK(); #endif } @@ -1971,12 +1978,11 @@ static int Memento_containsAddr(Memento_BlkHeader *b, return 0; } -void Memento_info(void *addr) +static void Memento_infoLocked(void *addr) { #ifdef MEMENTO_DETAILS findBlkData data; - MEMENTO_LOCK(); data.addr = addr; data.blk = NULL; data.flags = 0; @@ -1988,12 +1994,18 @@ void Memento_info(void *addr) Memento_appBlocks(&memento.free, Memento_containsAddr, &data); if (data.blk != NULL) showInfo(data.blk, NULL); - MEMENTO_UNLOCK(); #else printf("Memento not compiled with details support\n"); #endif } +void Memento_info(void *addr) +{ + MEMENTO_LOCK(); + Memento_infoLocked(addr); + MEMENTO_UNLOCK(); +} + #ifdef MEMENTO_HAS_FORK #include <unistd.h> #include <sys/wait.h> @@ -2165,13 +2177,16 @@ static void Memento_startFailing(void) static int Memento_event(void) { + int ret = 0; + memento.sequence++; if ((memento.sequence >= memento.paranoidAt) && (memento.paranoidAt != 0)) { memento.paranoia = 1; memento.countdown = 1; } if (--memento.countdown == 0) { - Memento_checkAllMemoryLocked(); + ret = Memento_checkAllMemoryLocked(); + ret = (ret & 8) != 0; if (memento.paranoia > 0) memento.countdown = memento.paranoia; else @@ -2186,7 +2201,7 @@ static int Memento_event(void) fprintf(stderr, "Breaking at event %d\n", memento.breakAt); return 1; } - return 0; + return ret; } int Memento_sequence(void) @@ -2499,7 +2514,7 @@ static void do_reference(Memento_BlkHeader *blk, int event) #endif /* MEMENTO_DETAILS */ } -int Memento_checkPointerOrNull(void *blk) +static int checkPointerOrNullLocked(void *blk) { if (blk == NULL) return 0; @@ -2517,17 +2532,27 @@ int Memento_checkPointerOrNull(void *blk) fprintf(stderr, "Current backtrace:\n"); Memento_bt(); fprintf(stderr, "History:\n"); - Memento_info(blk); + Memento_infoLocked(blk); #endif + Memento_breakpointLocked(); return 1; } -int Memento_checkBytePointerOrNull(void *blk) +int Memento_checkPointerOrNull(void *blk) +{ + int ret; + MEMENTO_LOCK(); + ret = checkPointerOrNullLocked(blk); + MEMENTO_UNLOCK(); + return ret; +} + +static int checkBytePointerOrNullLocked(void *blk) { unsigned char i; if (blk == NULL) return 0; - Memento_checkPointerOrNull(blk); + checkPointerOrNullLocked(blk); i = *(unsigned char *)blk; @@ -2545,18 +2570,27 @@ int Memento_checkBytePointerOrNull(void *blk) fprintf(stderr, "Current backtrace:\n"); Memento_bt(); fprintf(stderr, "History:\n"); - Memento_info(blk); + Memento_infoLocked(blk); #endif - Memento_breakpoint(); + Memento_breakpointLocked(); return 1; } -int Memento_checkShortPointerOrNull(void *blk) +int Memento_checkBytePointerOrNull(void *blk) +{ + int ret; + MEMENTO_LOCK(); + ret = checkBytePointerOrNullLocked(blk); + MEMENTO_UNLOCK(); + return ret; +} + +static int checkShortPointerOrNullLocked(void *blk) { unsigned short i; if (blk == NULL) return 0; - Memento_checkPointerOrNull(blk); + checkPointerOrNullLocked(blk); i = *(unsigned short *)blk; @@ -2574,18 +2608,27 @@ int Memento_checkShortPointerOrNull(void *blk) fprintf(stderr, "Current backtrace:\n"); Memento_bt(); fprintf(stderr, "History:\n"); - Memento_info(blk); + Memento_infoLocked(blk); #endif - Memento_breakpoint(); + Memento_breakpointLocked(); return 1; } -int Memento_checkIntPointerOrNull(void *blk) +int Memento_checkShortPointerOrNull(void *blk) +{ + int ret; + MEMENTO_LOCK(); + ret = checkShortPointerOrNullLocked(blk); + MEMENTO_UNLOCK(); + return ret; +} + +static int checkIntPointerOrNullLocked(void *blk) { unsigned int i; if (blk == NULL) return 0; - Memento_checkPointerOrNull(blk); + checkPointerOrNullLocked(blk); i = *(unsigned int *)blk; @@ -2603,15 +2646,29 @@ int Memento_checkIntPointerOrNull(void *blk) fprintf(stderr, "Current backtrace:\n"); Memento_bt(); fprintf(stderr, "History:\n"); - Memento_info(blk); + Memento_infoLocked(blk); #endif - Memento_breakpoint(); + Memento_breakpointLocked(); return 1; } -static void *do_takeRef(void *blk) +int Memento_checkIntPointerOrNull(void *blk) { + int ret; MEMENTO_LOCK(); + ret = checkIntPointerOrNullLocked(blk); + MEMENTO_UNLOCK(); + return ret; +} + +static void *do_takeRef(void *blk) +{ + do_reference(safe_find_block(blk), Memento_EventType_takeRef); + return blk; +} + +static void *do_takeRefAndUnlock(void *blk) +{ do_reference(safe_find_block(blk), Memento_EventType_takeRef); MEMENTO_UNLOCK(); return blk; @@ -2622,14 +2679,17 @@ void *Memento_takeByteRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - (void)Memento_checkBytePointerOrNull(blk); + (void)checkBytePointerOrNullLocked(blk); - return do_takeRef(blk); + return do_takeRefAndUnlock(blk); } void *Memento_takeShortRef(void *blk) @@ -2637,14 +2697,17 @@ void *Memento_takeShortRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - (void)Memento_checkShortPointerOrNull(blk); + (void)checkShortPointerOrNullLocked(blk); - return do_takeRef(blk); + return do_takeRefAndUnlock(blk); } void *Memento_takeIntRef(void *blk) @@ -2652,14 +2715,17 @@ void *Memento_takeIntRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - (void)Memento_checkIntPointerOrNull(blk); + (void)checkIntPointerOrNullLocked(blk); - return do_takeRef(blk); + return do_takeRefAndUnlock(blk); } void *Memento_takeRef(void *blk) @@ -2667,17 +2733,25 @@ void *Memento_takeRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - return do_takeRef(blk); + return do_takeRefAndUnlock(blk); } static void *do_dropRef(void *blk) { - MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_dropRef); + return blk; +} + +static void *do_dropRefAndUnlock(void *blk) +{ do_reference(safe_find_block(blk), Memento_EventType_dropRef); MEMENTO_UNLOCK(); return blk; @@ -2688,14 +2762,17 @@ void *Memento_dropByteRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - Memento_checkBytePointerOrNull(blk); + checkBytePointerOrNullLocked(blk); - return do_dropRef(blk); + return do_dropRefAndUnlock(blk); } void *Memento_dropShortRef(void *blk) @@ -2703,14 +2780,17 @@ void *Memento_dropShortRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - Memento_checkShortPointerOrNull(blk); + checkShortPointerOrNullLocked(blk); - return do_dropRef(blk); + return do_dropRefAndUnlock(blk); } void *Memento_dropIntRef(void *blk) @@ -2718,14 +2798,17 @@ void *Memento_dropIntRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - Memento_checkIntPointerOrNull(blk); + checkIntPointerOrNullLocked(blk); - return do_dropRef(blk); + return do_dropRefAndUnlock(blk); } void *Memento_dropRef(void *blk) @@ -2733,20 +2816,29 @@ void *Memento_dropRef(void *blk) if (!memento.inited) Memento_init(); - if (Memento_event()) Memento_breakpoint(); + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); - if (!blk) + if (!blk) { + MEMENTO_UNLOCK(); return NULL; + } - return do_dropRef(blk); + return do_dropRefAndUnlock(blk); } void *Memento_adjustRef(void *blk, int adjust) { - if (Memento_event()) Memento_breakpoint(); + if (!memento.inited) + Memento_init(); - if (blk == NULL) + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); + + if (blk == NULL) { + MEMENTO_UNLOCK(); return NULL; + } while (adjust > 0) { @@ -2759,6 +2851,7 @@ void *Memento_adjustRef(void *blk, int adjust) adjust++; } + MEMENTO_UNLOCK(); return blk; } @@ -2829,8 +2922,7 @@ static int checkBlock(Memento_BlkHeader *memblk, const char *action) fprintf(stderr, "Attempt to %s invalid block ", action); showBlock(memblk, 32); fprintf(stderr, "\n"); - Memento_breakpointLocked(); - return 1; + return 2; } #ifndef MEMENTO_LEAKONLY @@ -2842,8 +2934,7 @@ static int checkBlock(Memento_BlkHeader *memblk, const char *action) fprintf(stderr, "Attempt to %s block ", action); showBlock(memblk, 32); fprintf(stderr, "\n"); - Memento_breakpointLocked(); - return 1; + return 2; } else if (data.preCorrupt || data.postCorrupt) { fprintf(stderr, "Block "); showBlock(memblk, ' '); @@ -2859,7 +2950,7 @@ static int checkBlock(Memento_BlkHeader *memblk, const char *action) if ((memblk->flags & Memento_Flag_Reported) == 0) { memblk->flags |= Memento_Flag_Reported; - Memento_breakpointLocked(); + return 2; } return 1; } @@ -2870,6 +2961,7 @@ static int checkBlock(Memento_BlkHeader *memblk, const char *action) static void do_free(void *blk, int eventType) { Memento_BlkHeader *memblk; + int ret; (void)eventType; @@ -2880,8 +2972,11 @@ static void do_free(void *blk, int eventType) memblk = MEMBLK_FROMBLK(blk); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); - if (checkBlock(memblk, "free")) + ret = checkBlock(memblk, "free"); + if (ret) { + if (ret & 2) + Memento_breakpoint(); if (memento.abortOnCorruption) { fprintf(stderr, "*** memblk corrupted, calling abort()\n"); abort(); @@ -2931,7 +3026,7 @@ static void *do_realloc(void *blk, size_t newsize, int type) { Memento_BlkHeader *memblk, *newmemblk; size_t newsizemem; - int flags; + int flags, ret; if (Memento_failThisEventLocked()) { errno = ENOMEM; @@ -2940,7 +3035,10 @@ static void *do_realloc(void *blk, size_t newsize, int type) memblk = MEMBLK_FROMBLK(blk); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); - if (checkBlock(memblk, "realloc")) { + ret = checkBlock(memblk, "realloc"); + if (ret) { + if (ret == 2) + Memento_breakpoint(); errno = ENOMEM; return NULL; } @@ -3070,7 +3168,7 @@ static int Memento_Internal_checkAllAlloced(Memento_BlkHeader *memblk, void *arg if ((memblk->flags & Memento_Flag_Reported) == 0) { memblk->flags |= Memento_Flag_Reported; - Memento_breakpointLocked(); + data->found |= 8; } } else @@ -3115,7 +3213,7 @@ static int Memento_Internal_checkAllFreed(Memento_BlkHeader *memblk, void *arg) if ((memblk->flags & Memento_Flag_Reported) == 0) { memblk->flags |= Memento_Flag_Reported; - Memento_breakpointLocked(); + data->found |= 8; } VALGRIND_MAKE_MEM_NOACCESS(memblk, sizeof(Memento_BlkHeader)); data->preCorrupt = 0; @@ -3150,7 +3248,7 @@ int Memento_checkAllMemory(void) MEMENTO_LOCK(); ret = Memento_checkAllMemoryLocked(); MEMENTO_UNLOCK(); - if (ret & 6) { + if (ret & 8) { Memento_breakpoint(); return 1; } diff --git a/base/msvclib.mak b/base/msvclib.mak index dbf49296..a9f57985 100644 --- a/base/msvclib.mak +++ b/base/msvclib.mak @@ -611,6 +611,31 @@ MS_TOOLSET_VERSION=14.28.29333 MSVC_VERSION=16 MS_TOOLSET_VERSION=14.28.29333 !endif +!if "$(_NMAKE_VER)" == "14.28.29913.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29914.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.28.29915.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.28.29333 +!endif +!if "$(_NMAKE_VER)" == "14.29.30038.1" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.29.30037 +!endif +!if "$(_NMAKE_VER)" == "14.29.30133.0" +# VS2019 (Toolset v142) +MSVC_VERSION=16 +MS_TOOLSET_VERSION=14.29.30133 +!endif !endif !ifndef MSVC_VERSION diff --git a/base/ocr.mak b/base/ocr.mak index 3c9e2787..6445a5ef 100644 --- a/base/ocr.mak +++ b/base/ocr.mak @@ -28,7 +28,7 @@ $(GLGEN)libocr.dev : $(LIBOCR_MAK) $(ECHOGS_XE)$(MAKEDIRS)\ # Tesseract veneer. $(GLGEN)tessocr.$(OBJ) : $(GLSRC)tessocr.cpp $(GLSRC)tessocr.h $(LIBOCR_MAK) \ $(gsmemory_h) $(gxiodev_h) $(stream_h) $(TESSDEPS) - $(TESSCXX) $(D_)LEPTONICA_INTERCEPT_MALLOC=1$(_D) $(I_)$(LEPTONICADIR)$(D)src$(_I) $(GLO_)tessocr.$(OBJ) $(C_) $(D_)TESSDATA="$(TESSDATA)"$(_D) $(GLSRC)tessocr.cpp + $(TESSCXX) $(D_)LEPTONICA_INTERCEPT_ALLOC=1$(_D) $(I_)$(LEPTONICADIR)$(D)src$(_I) $(GLO_)tessocr.$(OBJ) $(C_) $(D_)TESSDATA="$(TESSDATA)"$(_D) $(GLSRC)tessocr.cpp # 0 = No version. diff --git a/base/scfd.c b/base/scfd.c index 1ad2b5ad..03085fbf 100644 --- a/base/scfd.c +++ b/base/scfd.c @@ -62,20 +62,24 @@ s_CFD_init(stream_state * st) s_hcd_init_inline(ss); /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ - ss->lbuf = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lbuf"); + ss->lbufstart = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP * 2, "CFD lbuf"); ss->lprev = 0; - if (ss->lbuf == 0) + if (ss->lbufstart == 0) return ERRC; /****** WRONG ******/ + ss->lbuf = ss->lbufstart + CFD_BUFFER_SLOP; + memset(ss->lbufstart, 0xaa, CFD_BUFFER_SLOP); memset(ss->lbuf, white, raster); memset(ss->lbuf + raster, 0xaa, CFD_BUFFER_SLOP); /* for Valgrind */ if (ss->K != 0) { - ss->lprev = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lprev"); - if (ss->lprev == 0) + ss->lprevstart = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP * 2, "CFD lprev"); + if (ss->lprevstart == 0) return ERRC; /****** WRONG ******/ + ss->lprev = ss->lprevstart + CFD_BUFFER_SLOP; /* Clear the initial reference line for 2-D encoding. */ memset(ss->lprev, white, raster); /* Ensure that the scan of the reference line will stop. */ memset(ss->lprev + raster, 0xaa, CFD_BUFFER_SLOP); + memset(ss->lprevstart, 0xaa, CFD_BUFFER_SLOP); } ss->k_left = min(ss->K, 0); ss->run_color = 0; @@ -98,8 +102,8 @@ s_CFD_release(stream_state * st) { stream_CFD_state *const ss = (stream_CFD_state *) st; - gs_free_object(st->memory, ss->lprev, "CFD lprev(close)"); - gs_free_object(st->memory, ss->lbuf, "CFD lbuf(close)"); + gs_free_object(st->memory, ss->lprevstart, "CFD lprev(close)"); + gs_free_object(st->memory, ss->lbufstart, "CFD lbuf(close)"); } /* Declare the variables that hold the state. */ @@ -211,7 +215,7 @@ static inline int invert_data(stream_CFD_state *ss, stream_cursor_read *pr, int cfd_load_state(); (void)rlimit; - if (q >= ss->lbuf + ss->raster + CFD_BUFFER_SLOP) { + if (q >= ss->lbuf + ss->raster + CFD_BUFFER_SLOP || q < ss->lbufstart) { return(-1); } @@ -300,7 +304,11 @@ s_CFD_process(stream_state * st, stream_cursor_read * pr, #endif - top: + /* Update the pointers we actually use, in case GC moved the buffer */ + ss->lbuf = ss->lbufstart + CFD_BUFFER_SLOP; + ss->lprev = ss->lprevstart + CFD_BUFFER_SLOP; + +top: #ifdef DEBUG { hcd_declare_state; @@ -370,9 +378,12 @@ s_CFD_process(stream_state * st, stream_cursor_read * pr, goto ck_eol; /* handle EOD if it is present */ if (ss->K != 0) { byte *prev_bits = ss->lprev; + byte *prev_start = ss->lprevstart; ss->lprev = ss->lbuf; + ss->lprevstart = ss->lbufstart; ss->lbuf = prev_bits; + ss->lbufstart = prev_start; if (ss->K > 0) k_left = (k_left == 0 ? ss->K : k_left) - 1; } diff --git a/base/scfe.c b/base/scfe.c index 13e56fe7..15e1a490 100644 --- a/base/scfe.c +++ b/base/scfe.c @@ -150,21 +150,23 @@ s_CFE_init(register stream_state * st) /****** WRONG ******/ /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ - ss->lbuf = gs_alloc_bytes(st->memory, raster + 4, "CFE lbuf"); + ss->lbufstart = gs_alloc_bytes(st->memory, raster + 8, "CFE lbuf"); ss->lcode = gs_alloc_bytes(st->memory, code_bytes, "CFE lcode"); - if (ss->lbuf == 0 || ss->lcode == 0) { + if (ss->lbufstart == 0 || ss->lcode == 0) { s_CFE_release(st); return ERRC; /****** WRONG ******/ } + ss->lbuf = ss->lbufstart + 4; memset(ss->lbuf + raster, 0, 4); /* to pacify Valgrind */ if (ss->K != 0) { - ss->lprev = gs_alloc_bytes(st->memory, raster + 4, "CFE lprev"); - if (ss->lprev == 0) { + ss->lprevstart = gs_alloc_bytes(st->memory, raster + 8, "CFE lprev"); + if (ss->lprevstart == 0) { s_CFE_release(st); return ERRC; /****** WRONG ******/ } + ss->lprev = ss->lprevstart + 4; /* Clear the initial reference line for 2-D encoding. */ /* Make sure it is terminated properly. */ memset(ss->lprev, (ss->BlackIs1 ? 0 : 0xff), raster + 4); /* +4 to pacify Valgrind */ @@ -186,9 +188,9 @@ s_CFE_release(stream_state * st) { stream_CFE_state *const ss = (stream_CFE_state *) st; - gs_free_object(st->memory, ss->lprev, "CFE lprev(close)"); + gs_free_object(st->memory, ss->lprevstart, "CFE lprev(close)"); gs_free_object(st->memory, ss->lcode, "CFE lcode(close)"); - gs_free_object(st->memory, ss->lbuf, "CFE lbuf(close)"); + gs_free_object(st->memory, ss->lbufstart, "CFE lbuf(close)"); } /* Flush the buffer */ @@ -207,6 +209,10 @@ s_CFE_process(stream_state * st, stream_cursor_read * pr, byte end_mask = 1 << (-ss->Columns & 7); int status = 0; + /* Update the pointers we actually use, in case GC moved the buffer */ + ss->lbuf = ss->lbufstart + 4; + ss->lprev = ss->lprevstart + 4; + for (;;) { stream_cursor_write w; @@ -326,9 +332,12 @@ s_CFE_process(stream_state * st, stream_cursor_read * pr, if (ss->K != 0) { /* In 2-D modes, swap the current and previous scan lines. */ byte *temp = ss->lbuf; + byte *temp1 = ss->lbufstart; ss->lbuf = ss->lprev; + ss->lbufstart = ss->lprevstart; ss->lprev = temp; + ss->lprevstart = temp1; } /* Note that the input buffer needs refilling. */ ss->read_count = raster; @@ -382,7 +391,8 @@ s_CFE_process(stream_state * st, stream_cursor_read * pr, /* Encode a 1-D scan line. */ /* Attempt to stop coverity thinking skip_white_pixels() taints lbuf:*/ -/* coverity[ -tainted_data_argument : arg-1 ] */ +/* coverity[ -tainted_data_return ] */ +/* coverity[ -tainted_data_argument arg-2 ] */ static void cf_encode_1d(stream_CFE_state * ss, const byte * lbuf, stream_cursor_write * pw) { diff --git a/base/scfparam.c b/base/scfparam.c index d95ae98d..9f77603b 100644 --- a/base/scfparam.c +++ b/base/scfparam.c @@ -73,7 +73,7 @@ s_CF_put_params(gs_param_list * plist, stream_CF_state * ss) int code; state = *ss; - code = gs_param_read_items(plist, (void *)&state, s_CF_param_items); + code = gs_param_read_items(plist, (void *)&state, s_CF_param_items, NULL); if (code >= 0 && (state.K < -cf_max_height || state.K > cf_max_height || state.Columns < 0 || state.Columns > cfe_max_width || diff --git a/base/scfx.h b/base/scfx.h index a9e1e741..197d549b 100644 --- a/base/scfx.h +++ b/base/scfx.h @@ -40,9 +40,11 @@ int DecodedByteAlign;\ /* The init procedure sets the following. */\ uint raster;\ + byte *lbufstart; /* current line buffer, including pre-buffer slop to prevent underruns */\ byte *lbuf; /* current scan line buffer */\ /* (only if decoding or 2-D encoding) */\ byte *lprev; /* previous scan line buffer (only if 2-D) */\ + byte *lprevstart; /* current line buffer, including pre-buffer slop to prevent underruns */\ /* The following are updated dynamically. */\ int k_left /* number of next rows to encode in 2-D */\ /* (only if K > 0) */ @@ -67,7 +69,7 @@ typedef struct stream_CF_state_s { (ss)->DecodedByteAlign = 1,\ (ss)->ErrsAsEOD = false,\ /* Clear pointers */\ - (ss)->lbuf = 0, (ss)->lprev = 0,\ + (ss)->lbuf = (ss)->lbufstart = 0, (ss)->lprev = (ss)->lprevstart = 0,\ /* Clear errors */\ (ss)->error_string[0] = 0) @@ -85,7 +87,7 @@ typedef struct stream_CFE_state_s { #define private_st_CFE_state() /* in scfe.c */\ gs_private_st_ptrs3(st_CFE_state, stream_CFE_state, "CCITTFaxEncode state",\ - cfe_enum_ptrs, cfe_reloc_ptrs, lbuf, lprev, lcode) + cfe_enum_ptrs, cfe_reloc_ptrs, lbufstart, lprevstart, lcode) #define s_CFE_set_defaults_inline(ss)\ (s_CF_set_defaults_inline(ss), (ss)->lcode = 0) extern const stream_template s_CFE_template; @@ -121,7 +123,7 @@ typedef struct stream_CFD_state_s { #define private_st_CFD_state() /* in scfd.c */\ gs_private_st_ptrs2(st_CFD_state, stream_CFD_state, "CCITTFaxDecode state",\ - cfd_enum_ptrs, cfd_reloc_ptrs, lbuf, lprev) + cfd_enum_ptrs, cfd_reloc_ptrs, lbufstart, lprevstart) #define s_CFD_set_defaults_inline(ss)\ s_CF_set_defaults_inline(ss) extern const stream_template s_CFD_template; diff --git a/base/scommon.h b/base/scommon.h index d8bdda8c..542b960c 100644 --- a/base/scommon.h +++ b/base/scommon.h @@ -115,35 +115,28 @@ typedef union stream_cursor_s { * This allows localized disabling of the "array bounds" compiler * warning for this one specific case. */ -static inline void -stream_cursor_read_init(stream_cursor_read *r, const byte *buf, size_t length) -{ #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" #endif +static inline void +stream_cursor_read_init(stream_cursor_read *r, const byte *buf, size_t length) +{ /* starting pos for pointer is always one position back */ r->ptr = buf - 1; r->limit = r->ptr + length; -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif } static inline void stream_cursor_write_init(stream_cursor_write *w, const byte *buf, size_t length) { -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Warray-bounds" -#endif /* starting pos for pointer is always one position back */ w->ptr = (byte *)buf - 1; w->limit = (byte *)w->ptr + length; +} #ifdef __GNUC__ # pragma GCC diagnostic pop #endif -} /* * Define the prototype for the procedures known to both the generic diff --git a/base/sdcparam.c b/base/sdcparam.c index 18f663e4..74b8052b 100644 --- a/base/sdcparam.c +++ b/base/sdcparam.c @@ -434,11 +434,11 @@ int s_DCT_put_params(gs_param_list * plist, stream_DCT_state * pdct) { int code = - gs_param_read_items(plist, pdct, s_DCT_param_items); + gs_param_read_items(plist, pdct, s_DCT_param_items, NULL); if (code < 0) return code; - code = gs_param_read_items(plist, pdct->data.common, jsd_param_items); + code = gs_param_read_items(plist, pdct->data.common, jsd_param_items, NULL); if (code < 0) return code; if (pdct->data.common->Picky < 0 || pdct->data.common->Picky > 1 || diff --git a/base/sdeparam.c b/base/sdeparam.c index 8eaf44cd..b9b33094 100644 --- a/base/sdeparam.c +++ b/base/sdeparam.c @@ -196,7 +196,7 @@ s_DCTE_put_params(gs_param_list * plist, stream_DCT_state * pdct) * Required parameters for DCTEncode. * (DCTDecode gets the equivalent info from the SOF marker.) */ - code = gs_param_read_items(plist, ¶ms, s_DCTE_param_items); + code = gs_param_read_items(plist, ¶ms, s_DCTE_param_items, NULL); if (code < 0) return code; if (params.Columns <= 0 || params.Columns > 0xffff || @@ -277,6 +277,8 @@ s_DCTE_put_params(gs_param_list * plist, stream_DCT_state * pdct) break; } /* Optional encoding-only parameters */ + /* FIXME: This relies on the 'Markers' value in the param list + * being persistent enough. */ pdct->Markers.data = params.Markers.data; pdct->Markers.size = params.Markers.size; pdct->NoMarker = params.NoMarker; diff --git a/base/sjpx_openjpeg.c b/base/sjpx_openjpeg.c index bac505dd..deaccd80 100644 --- a/base/sjpx_openjpeg.c +++ b/base/sjpx_openjpeg.c @@ -236,7 +236,10 @@ static void sjpx_info_callback(const char *msg, void *ptr) static void sjpx_warning_callback(const char *msg, void *ptr) { +#ifdef DEBUG + /* prevent too many messages during normal build */ dlprintf1("openjpeg warning: %s", msg); +#endif } /* initialize the stream */ @@ -698,6 +701,14 @@ s_opjd_process(stream_state * ss, stream_cursor_read * pr, if (in_size > 0) { + if (state->PassThrough && state->PassThroughfn) { + if (state->PassThrough && state->PassThroughfn && !state->StartedPassThrough) { + state->StartedPassThrough = 1; + (state->PassThroughfn)(state->device, NULL, 1); + } + (state->PassThroughfn)(state->device, (byte *)pr->ptr + 1, (byte *)pr->limit - (byte *)pr->ptr); + } + /* buffer available data */ code = opj_lock(ss->memory); if (code < 0) return code; @@ -773,6 +784,10 @@ s_opjd_set_defaults(stream_state * ss) { state->alpha = false; state->colorspace = gs_jpx_cs_rgb; + state->StartedPassThrough = 0; + state->PassThrough = 0; + state->PassThroughfn = NULL; + state->device = (void *)NULL; } /* stream release. @@ -783,6 +798,10 @@ s_opjd_release(stream_state *ss) { stream_jpxd_state *const state = (stream_jpxd_state *) ss; + if (state->PassThrough && state->PassThroughfn && state->StartedPassThrough) { + state->StartedPassThrough = 0; + (state->PassThroughfn)(state->device, NULL, 0); + } /* empty stream or failed to accumulate */ if (state->codec == NULL) return; diff --git a/base/sjpx_openjpeg.h b/base/sjpx_openjpeg.h index 0ee57b64..aa8ddee7 100644 --- a/base/sjpx_openjpeg.h +++ b/base/sjpx_openjpeg.h @@ -41,6 +41,9 @@ typedef struct stream_block_s unsigned long fill; } stream_block; +#define JPXD_PassThrough(proc)\ + int proc(void *d, byte *Buffer, int Size) + /* Stream state for the jpx codec using openjpeg * We rely on our finalization call to free the * associated handle and pointers. @@ -68,6 +71,14 @@ typedef struct stream_jpxd_state_s int *sign_comps; /* compensate for signed data (signed => unsigned) */ unsigned char *row_data; + + int PassThrough; /* 0 or 1 */ + bool StartedPassThrough; /* Don't signal multiple starts for the same decode */ + JPXD_PassThrough((*PassThroughfn)); /* We don't want the stream code or + * JPEG code to have to handle devices + * so we use a function at the interpreter level + */ + void *device; /* The device we need to send PassThrough data to */ } stream_jpxd_state; extern const stream_template s_jpxd_template; diff --git a/base/spngp.c b/base/spngp.c index 90fe7be8..1180c148 100644 --- a/base/spngp.c +++ b/base/spngp.c @@ -76,6 +76,9 @@ s_pngp_init(stream_state * st, bool need_prev) if (ss->Colors > s_PNG_max_Colors) return ERRC; /* Too many colorants */ + if (bits_per_row < 1) + return ERRC; + ss->bpp = (bits_per_pixel + 7) >> 3; if (need_prev) { prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count, diff --git a/base/stdint_.h b/base/stdint_.h index fd425b44..555ec4a6 100644 --- a/base/stdint_.h +++ b/base/stdint_.h @@ -33,7 +33,7 @@ * but don't use the autoconf detection */ #ifndef HAVE_STDINT_H -# ifdef __MACOS__ +# if defined(__MACOS__) || (defined(__APPLE__) && defined(__MACH__)) # define HAVE_STDINT_H # endif #endif diff --git a/base/stream.c b/base/stream.c index 2073a12a..6f68d7c2 100644 --- a/base/stream.c +++ b/base/stream.c @@ -112,6 +112,7 @@ s_init(stream *s, gs_memory_t * mem) s->file_name.size = 0; s->close_strm = false; /* default */ s->close_at_eod = true; /* default */ + s->cbuf_string_memory = NULL; } stream * s_alloc(gs_memory_t * mem, client_name_t cname) @@ -125,6 +126,18 @@ s_alloc(gs_memory_t * mem, client_name_t cname) s_init(s, mem); return s; } +stream * +s_alloc_immovable(gs_memory_t * mem, client_name_t cname) +{ + stream *s = gs_alloc_struct_immovable(mem, stream, &st_stream, cname); + + if_debug2m('s', mem, "[s]alloc(%s) = "PRI_INTPTR"\n", + client_name_string(cname), (intptr_t) s); + if (s == 0) + return 0; + s_init(s, mem); + return s; +} /* Allocate a stream state and initialize it minimally. */ void @@ -179,6 +192,7 @@ s_std_init(register stream * s, byte * ptr, uint len, const stream_procs * pp, s->file = 0; s->file_name.data = 0; /* in case stream is on stack */ s->file_name.size = 0; + s->cbuf_string_memory = NULL; if (s->memory) { if_debug4m('s', s->memory, "[s]init "PRI_INTPTR", buf="PRI_INTPTR", len=%u, modes=%d\n", (intptr_t) s, (intptr_t) ptr, len, modes); @@ -1016,6 +1030,10 @@ static int stream_cursor_write *, bool); /* Initialize a stream for reading a string. */ +/* String ownership retained by the caller, for example + Postscript string objects owned by the Postscript + interpreter + */ void sread_string(register stream *s, const byte *ptr, uint len) { @@ -1027,9 +1045,31 @@ sread_string(register stream *s, const byte *ptr, uint len) s_std_init(s, (byte *)ptr, len, &p, s_mode_read + s_mode_seek); s->cbuf_string.data = (byte *)ptr; s->cbuf_string.size = len; + s->cbuf_string_memory = NULL; + s->end_status = EOFC; + s->cursor.r.limit = s->cursor.w.limit; +} + +/* The string ownership is transferred from caller to stream. + string_mem pointer must be allocator used to allocate the + "string" buffer. + */ +void +sread_transient_string(register stream *s, gs_memory_t *string_mem, const byte *ptr, uint len) +{ + static const stream_procs p = { + s_string_available, s_string_read_seek, s_std_read_reset, + s_std_read_flush, s_std_null, s_string_read_process + }; + + s_std_init(s, (byte *)ptr, len, &p, s_mode_read + s_mode_seek); + s->cbuf_string.data = (byte *)ptr; + s->cbuf_string.size = len; + s->cbuf_string_memory = string_mem; s->end_status = EOFC; s->cursor.r.limit = s->cursor.w.limit; } + /* Initialize a reusable stream for reading a string. */ static void s_string_reusable_reset(stream *s) @@ -1043,6 +1083,11 @@ s_string_reusable_flush(stream *s) s->cursor.r.ptr = s->cursor.r.limit = s->cbuf + s->bsize - 1; /* just set to the end */ return 0; } + +/* String ownership retained by the caller, for example + Postscript string objects owned by the Postscript + interpreter + */ void sread_string_reusable(stream *s, const byte *ptr, uint len) { @@ -1060,6 +1105,27 @@ sread_string_reusable(stream *s, const byte *ptr, uint len) s->close_at_eod = false; } +/* The string ownership is transferred from caller to stream. + string_mem pointer must be allocator used to allocate the + "string" buffer. + */ +void +sread_transient_string_reusable(stream *s, gs_memory_t *string_mem, const byte *ptr, uint len) +{ + /* + * Note that s->procs.close is s_close_disable, to parallel + * file_close_disable. + */ + static const stream_procs p = { + s_string_available, s_string_read_seek, s_string_reusable_reset, + s_string_reusable_flush, s_close_disable, s_string_read_process + }; + + sread_transient_string(s, string_mem, ptr, len); + s->procs = p; + s->close_at_eod = false; +} + /* Return the number of available bytes when reading from a string. */ static int s_string_available(stream *s, gs_offset_t *pl) @@ -1231,15 +1297,23 @@ s_close_filters(stream **ps, stream *target) while (*ps != target) { stream *s = *ps; gs_memory_t *mem = s->state->memory; + gs_memory_t *cbuf_string_memory = s->cbuf_string_memory; byte *sbuf = s->cbuf; + byte *cbuf = s->cbuf_string.data; stream *next = s->strm; int status = sclose(s); stream_state *ss = s->state; /* sclose may set this to s */ if (status < 0) return status; + + if (s->cbuf_string_memory != NULL) { /* stream owns string buffer, so free it */ + gs_free_object(cbuf_string_memory, cbuf, "s_close_filters(cbuf)"); + } + if (mem) { - gs_free_object(mem, sbuf, "s_close_filters(buf)"); + if (sbuf != cbuf) + gs_free_object(mem, sbuf, "s_close_filters(buf)"); gs_free_object(mem, s, "s_close_filters(stream)"); if (ss != (stream_state *)s) gs_free_object(mem, ss, "s_close_filters(state)"); diff --git a/base/stream.h b/base/stream.h index 04ef117d..ff6366dd 100644 --- a/base/stream.h +++ b/base/stream.h @@ -141,6 +141,7 @@ struct stream_s { #define s_can_seek(s) (((s)->modes & s_mode_seek) != 0) gs_string cbuf_string; /* cbuf/cbsize if cbuf is a string, */ /* 0/? if not */ + gs_memory_t *cbuf_string_memory; /* If != NULL, stream owns the string buffer */ gs_offset_t position; /* file position of beginning of */ /* buffer */ stream_procs procs; @@ -326,6 +327,7 @@ int spseek(stream *, gs_offset_t); /* Allocate a stream or a stream state. */ stream *s_alloc(gs_memory_t *, client_name_t); stream_state *s_alloc_state(gs_memory_t *, gs_memory_type_ptr_t, client_name_t); +stream *s_alloc_immovable(gs_memory_t *, client_name_t); /* * Initialize a separately allocated stream or stream state, as if allocated * by s_alloc[_state]. @@ -372,9 +374,23 @@ int file_close_finish(stream *); int file_close_disable(stream *); /* Create a stream on a string or a file. */ -void sread_string(stream *, const byte *, uint), - sread_string_reusable(stream *, const byte *, uint), - swrite_string(stream *, byte *, uint); +/* String ownership retained by the caller, for example + Postscript string objects owned by the Postscript + interpreter + */ +void sread_string(stream *, const byte *, uint); +void sread_string_reusable(stream *, const byte *, uint); + +/* The string ownership is transferred from caller to stream. + string_mem pointer must be allocator used to allocate the + "string" buffer. + */ +void +sread_transient_string(stream *s, gs_memory_t *string_mem, const byte *ptr, uint len); +void +sread_transient_string_reusable(stream *s, gs_memory_t *string_mem, const byte *ptr, uint len); + +void swrite_string(stream *, byte *, uint); void sread_file(stream *, gp_file *, byte *, uint), swrite_file(stream *, gp_file *, byte *, uint); int sappend_file(stream *, gp_file *, byte *, uint); diff --git a/base/tesseract.mak b/base/tesseract.mak index 9971c87b..048a7d70 100644 --- a/base/tesseract.mak +++ b/base/tesseract.mak @@ -1,5 +1,4 @@ TESSINCLUDES=\ - $(I_)$(TESSERACTDIR)$(_I)\ $(I_)$(TESSERACTDIR)/include$(_I)\ $(I_)$(TESSERACTDIR)/src/api$(_I)\ $(I_)$(TESSERACTDIR)/src/arch$(_I)\ @@ -24,7 +23,11 @@ TESSINCLUDES=\ # add -DDISABLED_LEGACY_ENGINE to TESSCXX # empty TESSERACT_LEGACY -TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED +# We set -DCLUSTER when doing builds for our testing cluster. Unfortunately, +# this conflicts with Tesseract's use of a CLUSTER type. We work around this +# here by undefining CLUSTER for the tesseract portion of the build. + +TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED -UCLUSTER #-DDISABLED_LEGACY_ENGINE TESSOBJ = $(GLOBJDIR)$(D)tesseract_ TESSO_ = $(O_)$(TESSOBJ) diff --git a/base/tessocr.cpp b/base/tessocr.cpp index fec5979d..9aba76ab 100644 --- a/base/tessocr.cpp +++ b/base/tessocr.cpp @@ -1,3 +1,46 @@ +/* Copyright (C) 2020-2021 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* This file is the veneer between GS and Leptonica/Tesseract. + * + * Leptonica's memory handling is intercepted via + * leptonica_{malloc,free,calloc,realloc} (though the last of these + * is not used) and forwarded to the GS memory handlers. Leptonica + * only makes calls when we're calling it, hence we use a leptonica_mem + * global to store the current memory pointer in. This will clearly not + * play nicely with multi-threaded use of Ghostscript, but that seems + * unlikely with OCR. + * + * Tesseract is trickier. For a start it uses new/delete/new[]/delete[] + * rather than malloc free. That's OK, cos we can intercept this - see + * the #ifdef TESSERACT_CUSTOM_ALLOCATOR section at the end of this file + * for how. + * + * The larger problem is that on startup, there is lots of 'static init' + * done in tesseract, which involves the system calling new. That happens + * before we have even entered main, so it's impossible to use any other + * allocator other than malloc. + * + * For now, we'll live with this; I believe that most of the 'bulk' + * allocations (pixmaps etc) are done via Leptonica. If we have an integrator + * that really needs to avoid malloc/free, then the section of code enclosed + * in #ifdef TESSERACT_CUSTOM_ALLOCATOR at the end of this file can be used, + * and tesseract_malloc/tesseract_free can be changed as required. + */ + + #include "tesseract/baseapi.h" extern "C" @@ -36,43 +79,44 @@ typedef struct } wrapped_api; -void *leptonica_malloc(size_t blocksize) +static gs_memory_t *leptonica_mem; + +void *leptonica_malloc(size_t size) { - void *ret = malloc(blocksize); + void *ret = gs_alloc_bytes(leptonica_mem, size, "leptonica_malloc"); #ifdef DEBUG_ALLOCS - printf("%d LEPTONICA_MALLOC %d -> %p\n", event++, (int)blocksize, ret); + printf("%d LEPTONICA_MALLOC(%p) %d -> %p\n", event++, leptonica_mem, (int)size, ret); fflush(stdout); #endif return ret; } -void *leptonica_calloc(size_t numelm, size_t elemsize) +void leptonica_free(void *ptr) { - void *ret = calloc(numelm, elemsize); #ifdef DEBUG_ALLOCS - printf("%d LEPTONICA_CALLOC %d,%d -> %p\n", event++, (int)numelm, (int)elemsize, ret); + printf("%d LEPTONICA_FREE(%p) %p\n", event++, leptonica_mem, ptr); fflush(stdout); #endif - return ret; + gs_free_object(leptonica_mem, ptr, "leptonica_free"); } -void *leptonica_realloc(void *ptr, size_t blocksize) +void *leptonica_calloc(size_t numelm, size_t elemsize) { - void *ret = realloc(ptr, blocksize); + void *ret = leptonica_malloc(numelm * elemsize); + + if (ret) + memset(ret, 0, numelm * elemsize); #ifdef DEBUG_ALLOCS - printf("%d LEPTONICA_REALLOC %p,%d -> %p\n", event++, ptr, (int)blocksize, ret); + printf("%d LEPTONICA_CALLOC %d,%d -> %p\n", event++, (int)numelm, (int)elemsize, ret); fflush(stdout); #endif return ret; } -void leptonica_free(void *ptr) +void *leptonica_realloc(void *ptr, size_t blocksize) { -#ifdef DEBUG_ALLOCS - printf("%d LEPTONICA_FREE %p\n", event++, ptr); - fflush(stdout); -#endif - free(ptr); + /* Never called in our usage. */ + return NULL; } /* Convert from gs format bitmaps to leptonica format bitmaps. */ @@ -98,27 +142,6 @@ static int convert2pix(l_uint32 *data, int w, int h, int raster) return w + extra*4; } -static gs_memory_t *leptonica_mem; - -static void *my_leptonica_malloc(size_t size) -{ - void *ret = gs_alloc_bytes(leptonica_mem, size, "leptonica_malloc"); -#ifdef DEBUG_ALLOCS - printf("%d MY_LEPTONICA_MALLOC(%p) %d -> %p\n", event++, leptonica_mem, (int)size, ret); - fflush(stdout); -#endif - return ret; -} - -static void my_leptonica_free(void *ptr) -{ -#ifdef DEBUG_ALLOCS - printf("%d MY_LEPTONICA_FREE(%p) %p\n", event++, leptonica_mem, ptr); - fflush(stdout); -#endif - gs_free_object(leptonica_mem, ptr, "leptonica_free"); -} - static bool load_file(const char* filename, std::vector<char>* data) { bool result = false; @@ -276,7 +299,7 @@ ocr_init_api(gs_memory_t *mem, const char *language, int engine, void **state) return gs_error_VMerror; leptonica_mem = mem; - setPixMemoryManager(my_leptonica_malloc, my_leptonica_free); + setPixMemoryManager(leptonica_malloc, leptonica_free); wrapped->mem = mem; wrapped->api = new tesseract::TessBaseAPI(); @@ -669,25 +692,54 @@ int ocr_bitmap_to_unicodes(void *state, }; +/* The following code is disabled by default. If enabled, nothing + * should change, except integrators can tweak tesseract_malloc + * and tesseract_free as required to avoid calling the normal + * system malloc/free. */ +#ifdef TESSERACT_CUSTOM_ALLOCATOR + +static void *tesseract_malloc(size_t blocksize) +{ + void *ret; + + ret = malloc(blocksize); +#ifdef DEBUG_ALLOCS + printf("%d LEPTONICA_MALLOC %d -> %p\n", event++, (int)blocksize, ret); + fflush(stdout); +#endif + return ret; +} + +static void tesseract_free(void *ptr) +{ +#ifdef DEBUG_ALLOCS + printf("%d LEPTONICA_FREE %p\n", event++, ptr); + fflush(stdout); +#endif + free(ptr); +} + /* Currently tesseract is the only C++ lib we have. * We may need to revisit this if this changes. */ void *operator new(size_t size) { - return leptonica_malloc(size); + return tesseract_malloc(size); } void operator_delete(void *ptr) { - leptonica_free(ptr); + tesseract_free(ptr); } void *operator new[](size_t size) { - return leptonica_malloc(size); + return tesseract_malloc(size); } void operator delete[](void *ptr) { - leptonica_free(ptr); + tesseract_free(ptr); } + +#endif diff --git a/base/unix-dll.mak b/base/unix-dll.mak index cae247ff..e83390c2 100644 --- a/base/unix-dll.mak +++ b/base/unix-dll.mak @@ -47,6 +47,10 @@ XPSSOC_XENAME=$(XPS_SO_BASE)c$(XE) XPSSOC_XE=$(BINDIR)/$(XPSSOC_XENAME) XPSSOC=$(BINDIR)/$(XPSSOC_XENAME) +PDFSOC_XENAME=$(PDF_SO_BASE)c$(XE) +PDFSOC_XE=$(BINDIR)/$(PDFSOC_XENAME) +PDFSOC=$(BINDIR)/$(PDFSOC_XENAME) + GPDLSOC_XENAME=$(GPDL_SO_BASE)c$(XE) GPDLSOC_XE=$(BINDIR)/$(GPDLSOC_XENAME) GPDLSOC=$(BINDIR)/$(GPDLSOC_XENAME) @@ -60,6 +64,7 @@ GSSOX=$(BINDIR)/$(GSSOX_XENAME) GS_SONAME_BASE=lib$(GS_SO_BASE) PCL_SONAME_BASE=lib$(PCL_SO_BASE) XPS_SONAME_BASE=lib$(XPS_SO_BASE) +PDF_SONAME_BASE=lib$(PDF_SO_BASE) GPDL_SONAME_BASE=lib$(GPDL_SO_BASE) # GNU/Linux @@ -78,6 +83,10 @@ GS_DLLEXT=$(DLL_EXT) #XPS_SONAME_MAJOR=$(XPS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) #XPS_SONAME_MAJOR_MINOR=$(XPS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) +#PDF_SONAME=$(PDF_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) +#PDF_SONAME_MAJOR=$(PDF_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) +#PDF_SONAME_MAJOR_MINOR=$(PDF_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) + #GPDL_SONAME=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) #GPDL_SONAME_MAJOR=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) #GPDL_SONAME_MAJOR_MINOR=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) @@ -111,6 +120,10 @@ XPS_SO=$(BINDIR)/$(XPS_SONAME) XPS_SO_MAJOR=$(BINDIR)/$(XPS_SONAME_MAJOR) XPS_SO_MAJOR_MINOR=$(BINDIR)/$(XPS_SONAME_MAJOR_MINOR) +PDF_SO=$(BINDIR)/$(PDF_SONAME) +PDF_SO_MAJOR=$(BINDIR)/$(PDF_SONAME_MAJOR) +PDF_SO_MAJOR_MINOR=$(BINDIR)/$(PDF_SONAME_MAJOR_MINOR) + GPDL_SO=$(BINDIR)/$(GPDL_SONAME) GPDL_SO_MAJOR=$(BINDIR)/$(GPDL_SONAME_MAJOR) GPDL_SO_MAJOR_MINOR=$(BINDIR)/$(GPDL_SONAME_MAJOR_MINOR) @@ -143,6 +156,14 @@ $(XPS_SO_MAJOR): $(XPS_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) $(RM_) $(XPS_SO_MAJOR) ln -s $(XPS_SONAME_MAJOR_MINOR) $(XPS_SO_MAJOR) +$(PDF_SO): $(PDF_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(PDF_SO) + ln -s $(PDF_SONAME_MAJOR_MINOR) $(PDF_SO) + +$(PDF_SO_MAJOR): $(PDF_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(PDF_SO_MAJOR) + ln -s $(PDF_SONAME_MAJOR_MINOR) $(PDF_SO_MAJOR) + $(GPDL_SO): $(GPDL_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) $(RM_) $(GPDL_SO) ln -s $(GPDL_SONAME_MAJOR_MINOR) $(GPDL_SO) @@ -161,6 +182,9 @@ gpcl6-so-links-subtarget: $(PCL_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) gxps-so-links-subtarget: $(XPS_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) $(NO_OP) +gpdf-so-links-subtarget: $(PDF_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + gpdl-so-links-subtarget: $(GPDL_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) $(NO_OP) @@ -183,8 +207,11 @@ $(PCLSOC_XE): gpcl6-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$ $(XPSSOC_XE): gxps-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) $(MAKEDIRS) $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(XPSSOC_XE) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) -l$(XPS_SO_BASE) -$(GPDLSOC_XE): gpdl-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) $(MAKEDIRS) - $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(GPDLSOC_XE) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) -l$(GPDL_SO_BASE) +$(PDFSOC_XE): gpdf-so-links-subtarget $(PLSRC)$(REALMAIN_SRC).c $(UNIX_DLL_MAK) $(MAKEDIRS) + $(GLCC) -g -o $(PDFSOC_XE) $(PLSRC)$(REALMAIN_SRC).c -L$(BINDIR) -l$(PDF_SO_BASE) + +$(GPDLSOC_XE): gpdl-so-links-subtarget $(PLSRC)$(REALMAIN_SRC).c $(UNIX_DLL_MAK) $(MAKEDIRS) + $(GLCC) -g -o $(GPDLSOC_XE) $(PLSRC)$(REALMAIN_SRC).c -L$(BINDIR) -l$(GPDL_SO_BASE) gpcl6-so-loader: $(PCLSOC_XE) $(NO_OP) @@ -192,6 +219,9 @@ gpcl6-so-loader: $(PCLSOC_XE) gxps-so-loader: $(XPSSOC_XE) $(NO_OP) +gpdf-so-loader: $(PDFSOC_XE) + $(NO_OP) + gpdl-so-loader: $(GPDLSOC_XE) $(NO_OP) @@ -209,6 +239,9 @@ gpcl6-so-strip: gxps-so-strip: $(STRIP_XE) $(STRIP_XE_OPTS) $(GXPS_XE) +gpdf-so-strip: + $(STRIP_XE) $(STRIP_XE_OPTS) $(GPDF_XE) + gpdl-so-strip: $(STRIP_XE)$(STRIP_XE_OPTS) $(GPDL_XE) @@ -225,6 +258,7 @@ SODEFS=\ GS_XE=$(BINDIR)/$(GS_SONAME_MAJOR_MINOR) \ GPCL_XE=$(BINDIR)/$(PCL_SONAME_MAJOR_MINOR) \ GXPS_XE=$(BINDIR)/$(XPS_SONAME_MAJOR_MINOR) \ + GPDF_XE=$(BINDIR)/$(PDF_SONAME_MAJOR_MINOR) \ GPDL_XE=$(BINDIR)/$(GPDL_SONAME_MAJOR_MINOR) \ DISPLAY_DEV=$(DD)display.dev \ BUILDDIRPREFIX=$(BUILDDIRPREFIX) @@ -252,6 +286,7 @@ so-only: $(MAKE) $(SUB_MAKE_OPTION) gs-so-links-subtarget \ $(PCL_TARGET)-so-links-subtarget \ $(XPS_TARGET)-so-links-subtarget \ + $(PDF_TARGET)-so-links-subtarget \ $(GPDL_TARGET)-so-links-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) @@ -260,6 +295,7 @@ so-only-stripped: $(MAKE) $(SUB_MAKE_OPTION) gs-so-links-subtarget \ $(PCL_TARGET)-so-links-subtarget \ $(XPS_TARGET)-so-links-subtarget \ + $(PDF_TARGET)-so-links-subtarget \ $(GPDL_TARGET)-so-links-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) # Debug shared object @@ -284,16 +320,16 @@ so-only-subtarget: $(AUXDIR)/echogs$(XEAUX) $(AUXDIR)/genarch$(XEAUX) $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) GENOPT='$(GENOPT)' GS_LDFLAGS='$(LDFLAGS) $(GS_LDFLAGS_SO)'\ PCL_LDFLAGS='$(LDFLAGS) $(PCL_LDFLAGS_SO)' XPS_LDFLAGS='$(LDFLAGS) $(XPS_LDFLAGS_SO)' \ - PDL_LDFLAGS='$(LDFLAGS) $(PDL_LDFLAGS_SO)' CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) \ - $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix) + PDL_LDFLAGS='$(LDFLAGS) $(PDL_LDFLAGS_SO)' PDF_LDFLAGS='$(LDFLAGS) $(PDF_LDFLAGS_SO)' \ + CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix) so-only-stripped-subtarget: so-only-subtarget - $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) gs-so-strip $(PCL_TARGET)-so-strip $(XPS_TARGET)-so-strip $(GPDL_TARGET)-so-strip + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) gs-so-strip $(PCL_TARGET)-so-strip $(XPS_TARGET)-so-strip $(GPDL_TARGET)-so-strip$ (PDF_TARGET)-so-strip so-subtarget: so-only-subtarget $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS_FINAL) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ CFLAGS='$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix)\ - $(GSSOC_XE) $(GSSOX_XE) $(PCL_TARGET)-so-loader $(XPS_TARGET)-so-loader $(GPDL_TARGET)-so-loader + $(GSSOC_XE) $(GSSOX_XE) $(PCL_TARGET)-so-loader $(XPS_TARGET)-so-loader $(GPDL_TARGET)-so-loader $(PDF_TARGET)-so-loader install-so-gs: $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) diff --git a/base/unix-end.mak b/base/unix-end.mak index d837d9ea..9302ce96 100644 --- a/base/unix-end.mak +++ b/base/unix-end.mak @@ -43,6 +43,12 @@ gxps: .xpssubtarget $(UNIX_END_MAK) gxpsclean: cleansub $(NO_OP) +gpdf: .pdfsubtarget $(UNIX_END_MAK) + $(NO_OP) + +gpdfclean: cleansub + $(NO_OP) + gpdl: .gpdlsubtarget $(UNIX_END_MAK) $(NO_OP) @@ -102,6 +108,12 @@ gxpspg: gxpspgclean: $(MAKE) $(PROFILEMAKEOPTS) cleansub +gpdfpg: + $(MAKE) $(PROFILEMAKEOPTS) .pdfsubtarget + +gpdfpgclean: + $(MAKE) $(PROFILEMAKEOPTS) cleansub + gpdlpg: $(MAKE) $(PROFILEMAKEOPTS) .gpdlsubtarget @@ -145,6 +157,12 @@ gxpsdebug: gxpsdebugclean: $(MAKE) $(DEBUGMAKEOPTS) cleansub +gpdfdebug: + $(MAKE) $(DEBUGMAKEOPTS) .pdfsubtarget + +gpdfdebugclean: + $(MAKE) $(DEBUGMAKEOPTS) cleansub + gpdldebug: $(MAKE) $(DEBUGMAKEOPTS) .gpdlsubtarget @@ -188,6 +206,9 @@ gpcl6memento: gxpsmemento: $(MAKE) $(MEMENTOMAKEOPTS) .xpssubtarget +gpdfmemento: + $(MAKE) $(MEMENTOMAKEOPTS) .pdfsubtarget + gpdlmemento: $(MAKE) $(MEMENTOMAKEOPTS) .gpdlsubtarget @@ -218,6 +239,9 @@ gxpsmementovg: gpdlmementovg: $(MAKE) $(MEMENTOVGMAKEOPTS) .gpdlsubtarget +gpdfmementovg: + $(MAKE) $(MEMENTOVGMAKEOPTS) .pdfsubtarget + mementovgclean: $(MAKE) $(MEMENTOVGMAKEOPTS) cleansub @@ -244,6 +268,9 @@ gpcl6sanitize: gxpssanitize: $(MAKE) $(SANITIZEMAKEOPTS) .xpssubtarget +gpdfsanitize: + $(MAKE) $(SANITIZEMAKEOPTS) .pdfsubtarget + gpdlsanitize: $(MAKE) $(SANITIZEMAKEOPTS) .gpdlsubtarget @@ -273,6 +300,9 @@ gxpsvg: gpdlvg: $(MAKE) $(VGMAKEOPTS) .gpdlsubtarget +gpdfvg: + $(MAKE) $(VGMAKEOPTS) .pdfsubtarget + vgclean: $(MAKE) $(VGMAKEOPTS) cleansub @@ -300,6 +330,9 @@ gxpsdebugvg: gpdldebugvg: $(MAKE) $(DEBUGVGMAKEOPTS) .gpdlsubtarget +gpdfdebugvg: + $(MAKE) $(DEBUGVGMAKEOPTS) .pdfsubtarget + debugvgclean: $(MAKE) $(DEBUGVGMAKEOPTS) cleansub diff --git a/base/unix-gcc.mak b/base/unix-gcc.mak index c8bc0659..0712aa27 100644 --- a/base/unix-gcc.mak +++ b/base/unix-gcc.mak @@ -53,6 +53,10 @@ XPSSRCDIR=./xps XPSGENDIR=./$(BUILDDIRPREFIX)obj XPSOBJDIR=./$(BUILDDIRPREFIX)obj +PDFSRCDIR=./pdf +PDFGENDIR=./$(BUILDDIRPREFIX)obj +PDFOBJDIR=./$(BUILDDIRPREFIX)obj + GPDLSRCDIR=./gpdl GPDLGENDIR=./$(BUILDDIRPREFIX)obj GPDLOBJDIR=./$(BUILDDIRPREFIX)obj @@ -173,6 +177,7 @@ GS_SO_BASE=gs PCL=gpcl6 XPS=gxps +PDF=gpdf GPDL=gpdl XE= @@ -406,10 +411,12 @@ LDFLAGS= $(AC_LDFLAGS) $(XLDFLAGS) GS_LDFLAGS=$(LDFLAGS) PCL_LDFLAGS=$(LDFLAGS) XPS_LDFLAGS=$(LDFLAGS) +PDF_LDFLAGS=$(LDFLAGS) GS_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(GS_SONAME_MAJOR) PCL_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(PCL_SONAME_MAJOR) XPS_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(XPS_SONAME_MAJOR) +PDF_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(PDF_SONAME_MAJOR) # Define any extra libraries to link into the executable. # ISC Unix 2.2 wants -linet. @@ -498,6 +505,8 @@ PCL_FEATURE_DEVS=$(PLOBJDIR)/pl.dev $(PLOBJDIR)/pjl.dev $(PXLOBJDIR)/pxl.dev $(P XPS_FEATURE_DEVS=$(XPSOBJDIR)/pl.dev $(XPSOBJDIR)/xps.dev +PDF_FEATURE_DEVS=$(PDFOBJDIR)/pl.dev $(PDFOBJDIR)/gpdf.dev + FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev $(GLD)psl2lib.dev \ $(GLD)dps2lib.dev $(GLD)path1lib.dev $(GLD)patlib.dev $(GLD)psl2cs.dev $(GLD)rld.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev\ $(GLD)ttflib.dev $(GLD)cielib.dev $(GLD)pipe.dev $(GLD)htxlib.dev $(GLD)sdct.dev $(GLD)libpng.dev\ @@ -622,6 +631,7 @@ include $(GLSRCDIR)/gs.mak # are available # include $(PLSRCDIR)$(D)plromfs.mak # plromfs.mak # include $(XPSSRCDIR)$(D)xpsromfs.mak # xpsromfs.mak +# include $(PDFSRCDIR)$(D)pdfromfs.mak # pdfromfs.mak include $(PSSRCDIR)/psromfs.mak include $(GLSRCDIR)/lib.mak @@ -636,6 +646,8 @@ include $(PSSRCDIR)/int.mak # include $(XPSSRCDIR)$(D)xps.mak # xps.mak +# include $(PDFSRCDIR)$(D)pdf.mak # pdf.mak + # include $(GPDLSRCDIR)$(D)gpdl.mak # gpdl.mak include $(GLSRCDIR)/freetype.mak diff --git a/base/unixlink.mak b/base/unixlink.mak index 4c65229e..ee91babd 100644 --- a/base/unixlink.mak +++ b/base/unixlink.mak @@ -227,6 +227,27 @@ $(GXPS_XE): $(ld_tr) $(xps_tr) $(REALMAIN_OBJ) $(MAIN_OBJ) $(XPS_TOP_OBJS) \ .xpssubtarget: $(GXPS_XE) $(NO_OP) +pdfldt_tr=$(PSOBJ)pdfldt.tr +$(GPDF_XE): $(ld_tr) $(pdf_tr) $(REALMAIN_OBJ) $(MAIN_OBJ) $(PDF_TOP_OBJS) \ + $(XOBJS) $(GLOBJDIR)/pdfromfs$(COMPILE_INITS).$(OBJ) \ + $(INT_ARCHIVE_SOME) $(UNIXLINK_MAK) + $(ECHOGS_XE) -w $(pdfldt_tr) -n - $(CCLD) $(PDF_LDFLAGS) $(XLIBDIRS) -o $(GPDF_XE) + $(ECHOGS_XE) -a $(pdfldt_tr) -n -s $(PDF_TOP_OBJS) $(INT_ARCHIVE_SOME) $(XOBJS) -s + cat $(pdfld_tr) >> $(pdfldt_tr) + $(ECHOGS_XE) -a $(pdfldt_tr) -s - $(GLOBJDIR)/pdfromfs$(COMPILE_INITS).$(OBJ) $(REALMAIN_OBJ) $(MAIN_OBJ) $(EXTRALIBS) $(STDLIBS) + if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \ + XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \ + PCL_FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ + DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \ + DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \ + DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \ + DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= \ + DEVICE_DEVS_EXTRA= \ + sh <$(pdfldt_tr) + +.pdfsubtarget: $(GPDF_XE) + $(NO_OP) + gpdlldt_tr=$(PSOBJ)gpdlldt.tr $(GPDL_XE): $(ld_tr) $(gpdl_tr) $(INT_ARCHIVE_ALL) $(REALMAIN_OBJ) $(MAIN_OBJ) \ $(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) \ diff --git a/base/version.mak b/base/version.mak index 88ea1634..45ee90f1 100644 --- a/base/version.mak +++ b/base/version.mak @@ -14,10 +14,10 @@ # Major, minor and patch version numbers. GS_VERSION_MAJOR=9 -GS_VERSION_MINOR=54 +GS_VERSION_MINOR=55 GS_VERSION_PATCH=0 # Revision date: year x 10000 + month x 100 + day. -GS_REVISIONDATE=20210330 +GS_REVISIONDATE=20210927 # Derived values GS_VERSION=$(GS_VERSION_MAJOR)$(GS_VERSION_MINOR)$(GS_VERSION_PATCH) GS_DOT_VERSION=$(GS_VERSION_MAJOR).$(GS_VERSION_MINOR).$(GS_VERSION_PATCH) |