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