1 /* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gxmclip.c,v 1.4 2002/02/21 22:24:53 giles Exp $ */
18 /* Mask clipping support */
19 #include "gx.h"
20 #include "gxdevice.h"
21 #include "gxdevmem.h"
22 #include "gxmclip.h"
23
24 /* Structure descriptor */
25 public_st_device_mask_clip();
26
27 /* GC procedures */
ENUM_PTRS_WITH(device_mask_clip_enum_ptrs,gx_device_mask_clip * mcdev)28 private ENUM_PTRS_WITH(device_mask_clip_enum_ptrs, gx_device_mask_clip *mcdev)
29 {
30 if (index < st_gx_strip_bitmap_max_ptrs) {
31 return ENUM_USING(st_gx_strip_bitmap, &mcdev->tiles,
32 sizeof(mcdev->tiles), index);
33 }
34 index -= st_gx_strip_bitmap_max_ptrs;
35 if (index < st_device_memory_max_ptrs) {
36 return ENUM_USING(st_device_memory, &mcdev->mdev,
37 sizeof(mcdev->mdev), index);
38 }
39 ENUM_PREFIX(st_device_forward, st_device_memory_max_ptrs);
40 }
41 ENUM_PTRS_END
RELOC_PTRS_WITH(device_mask_clip_reloc_ptrs,gx_device_mask_clip * mcdev)42 private RELOC_PTRS_WITH(device_mask_clip_reloc_ptrs, gx_device_mask_clip *mcdev)
43 {
44 RELOC_PREFIX(st_device_forward);
45 RELOC_USING(st_gx_strip_bitmap, &mcdev->tiles, sizeof(mcdev->tiles));
46 RELOC_USING(st_device_memory, &mcdev->mdev, sizeof(mcdev->mdev));
47 if (mcdev->mdev.base != 0) {
48 /*
49 * Update the line pointers specially, since they point into the
50 * buffer that is part of the mask clipping device itself.
51 */
52 long diff = (char *)RELOC_OBJ(mcdev) - (char *)mcdev;
53 int i;
54
55 for (i = 0; i < mcdev->mdev.height; ++i)
56 mcdev->mdev.line_ptrs[i] += diff;
57 mcdev->mdev.base = mcdev->mdev.line_ptrs[0];
58 mcdev->mdev.line_ptrs =
59 (void *)((char *)(mcdev->mdev.line_ptrs) + diff);
60 }
61 }
62 RELOC_PTRS_END
63
64 /* Initialize a mask clipping device. */
65 int
gx_mask_clip_initialize(gx_device_mask_clip * cdev,const gx_device_mask_clip * proto,const gx_bitmap * bits,gx_device * tdev,int tx,int ty,gs_memory_t * mem)66 gx_mask_clip_initialize(gx_device_mask_clip * cdev,
67 const gx_device_mask_clip * proto,
68 const gx_bitmap * bits, gx_device * tdev,
69 int tx, int ty, gs_memory_t *mem)
70 {
71 int buffer_width = bits->size.x;
72 int buffer_height =
73 tile_clip_buffer_size / (bits->raster + sizeof(byte *));
74
75 gx_device_init((gx_device *)cdev, (const gx_device *)proto,
76 mem, true);
77 cdev->width = tdev->width;
78 cdev->height = tdev->height;
79 cdev->color_info = tdev->color_info;
80 gx_device_set_target((gx_device_forward *)cdev, tdev);
81 cdev->phase.x = -tx;
82 cdev->phase.y = -ty;
83 if (buffer_height > bits->size.y)
84 buffer_height = bits->size.y;
85 gs_make_mem_mono_device(&cdev->mdev, 0, 0);
86 for (;;) {
87 if (buffer_height <= 0) {
88 /*
89 * The tile is too wide to buffer even one scan line.
90 * We could do copy_mono in chunks, but for now, we punt.
91 */
92 cdev->mdev.base = 0;
93 return 0;
94 }
95 cdev->mdev.width = buffer_width;
96 cdev->mdev.height = buffer_height;
97 if (gdev_mem_bitmap_size(&cdev->mdev) <= tile_clip_buffer_size)
98 break;
99 buffer_height--;
100 }
101 cdev->mdev.base = cdev->buffer.bytes;
102 return (*dev_proc(&cdev->mdev, open_device))((gx_device *)&cdev->mdev);
103 }
104