xref: /plan9/sys/src/cmd/gs/src/gsgdata.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 2001 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: gsgdata.c,v 1.3 2002/02/21 22:24:52 giles Exp $ */
18 /* Support for glyph data access */
19 
20 #include "memory_.h"
21 #include "gx.h"
22 #include "gsgdata.h"
23 #include "gserrors.h"
24 #include "gsmatrix.h"		/* for gsfont.h */
25 #include "gsstruct.h"
26 #include "gxfont.h"
27 
28 /* GC structure descriptor */
29 private ENUM_PTRS_WITH(gs_glyph_data_enum_ptrs, gs_glyph_data_t *pgd)
30     case 0: return ENUM_CONST_BYTESTRING(&pgd->bits);
31     case 1: return ENUM_OBJ(pgd->proc_data);
32 ENUM_PTRS_END
RELOC_PTRS_WITH(gs_glyph_data_reloc_ptrs,gs_glyph_data_t * pgd)33 private RELOC_PTRS_WITH(gs_glyph_data_reloc_ptrs, gs_glyph_data_t *pgd)
34 {
35     RELOC_CONST_BYTESTRING_VAR(pgd->bits);
36     RELOC_OBJ_VAR(pgd->proc_data);
37 } RELOC_PTRS_END
38 gs_public_st_composite(st_glyph_data, gs_glyph_data_t, "gs_glyph_data_t",
39 		       gs_glyph_data_enum_ptrs, gs_glyph_data_reloc_ptrs);
40 
41 /* ------ Client facilities ------ */
42 
43 /* Replace glyph data by a substring. */
44 int
gs_glyph_data_substring(gs_glyph_data_t * pgd,uint offset,uint size)45 gs_glyph_data_substring(gs_glyph_data_t *pgd, uint offset, uint size)
46 {
47     if (offset > pgd->bits.size || size > pgd->bits.size - offset)
48 	return_error(gs_error_rangecheck);
49     return pgd->procs->substring(pgd, offset, size);
50 }
51 
52 /* Free the data for a glyph. */
53 void
gs_glyph_data_free(gs_glyph_data_t * pgd,client_name_t cname)54 gs_glyph_data_free(gs_glyph_data_t *pgd, client_name_t cname)
55 {
56     pgd->procs->free(pgd, cname);
57     gs_glyph_data_from_null(pgd);
58 }
59 
60 /* ------ Implementor support ------ */
61 
62 /* Don't manage the glyph data. */
63 private void
glyph_data_free_permanent(gs_glyph_data_t * pgd,client_name_t cname)64 glyph_data_free_permanent(gs_glyph_data_t *pgd, client_name_t cname)
65 {
66 }
67 private int
glyph_data_substring_permanent(gs_glyph_data_t * pgd,uint offset,uint size)68 glyph_data_substring_permanent(gs_glyph_data_t *pgd, uint offset, uint size)
69 {
70     pgd->bits.data += offset;
71     pgd->bits.size = size;
72     return 0;
73 }
74 
75 /* Manage the glyph data using the font's allocator. */
76 private void
glyph_data_free_by_font(gs_glyph_data_t * pgd,client_name_t cname)77 glyph_data_free_by_font(gs_glyph_data_t *pgd, client_name_t cname)
78 {
79     gs_free_const_bytestring(((gs_font *)pgd->proc_data)->memory,
80 			     &pgd->bits, cname);
81 }
82 private int
glyph_data_substring_by_font(gs_glyph_data_t * pgd,uint offset,uint size)83 glyph_data_substring_by_font(gs_glyph_data_t *pgd, uint offset, uint size)
84 {
85     gs_font *const font = pgd->proc_data;
86     byte *data = (byte *)pgd->bits.data; /* break const */
87 
88     if (pgd->bits.bytes)	/* object, not string */
89 	return glyph_data_substring_permanent(pgd, offset, size);
90     if (offset > 0)
91 	memmove(data, data + offset, size);
92     pgd->bits.data =
93 	gs_resize_string(font->memory, data, pgd->bits.size, size,
94 			 "glyph_data_substring"); /* shortening, can't fail */
95     pgd->bits.size = size;
96     return 0;
97 }
98 
99 private const gs_glyph_data_procs_t no_free_procs = {
100     glyph_data_free_permanent, glyph_data_substring_permanent
101 };
102 private const gs_glyph_data_procs_t free_by_font_procs = {
103     glyph_data_free_by_font, glyph_data_substring_by_font
104 };
105 
106 /*
107  * Initialize glyph data from a string or from bytes.  If the font is NULL
108  * (for glyph data that is part of the font), set the glyph data freeing
109  * procedure to "do not free"; if the font is not NULL (for just-allocated
110  * glyph data), set the freeing procedure to "free using the font's
111  * allocator."
112  */
113 void
gs_glyph_data_from_string(gs_glyph_data_t * pgd,const byte * data,uint size,gs_font * font)114 gs_glyph_data_from_string(gs_glyph_data_t *pgd, const byte *data,
115 			  uint size, gs_font *font)
116 {
117     gs_bytestring_from_string(&pgd->bits, data, size);
118     pgd->proc_data = font;
119     pgd->procs = (font ? &free_by_font_procs : &no_free_procs);
120 }
121 void
gs_glyph_data_from_bytes(gs_glyph_data_t * pgd,const byte * bytes,uint offset,uint size,gs_font * font)122 gs_glyph_data_from_bytes(gs_glyph_data_t *pgd, const byte *bytes,
123 			 uint offset, uint size, gs_font *font)
124 {
125     gs_bytestring_from_bytes(&pgd->bits, bytes, offset, size);
126     pgd->proc_data = font;
127     pgd->procs = (font ? &free_by_font_procs : &no_free_procs);
128 }
129 void
gs_glyph_data_from_null(gs_glyph_data_t * pgd)130 gs_glyph_data_from_null(gs_glyph_data_t *pgd)
131 {
132     gs_glyph_data_from_string(pgd, NULL, 0, NULL);
133 }
134