1 /**************************************************************************
3 * Copyright 2010 LunarG, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
27 #include "util/u_memory.h"
28 #include "cso_cache/cso_hash.h"
35 #ifdef OPENVG_VERSION_1_1
38 struct vg_object base
;
39 struct cso_hash
*glyphs
;
43 struct vg_object
*object
; /* it could be NULL */
45 VGfloat glyph_origin
[2];
46 VGfloat escapement
[2];
49 static VGboolean
del_glyph(struct vg_font
*font
,
52 struct vg_glyph
*glyph
;
54 glyph
= (struct vg_glyph
*)
55 cso_hash_take(font
->glyphs
, (unsigned) glyphIndex
);
59 return (glyph
!= NULL
);
62 static void add_glyph(struct vg_font
*font
,
64 struct vg_object
*obj
,
66 const VGfloat glyphOrigin
[2],
67 const VGfloat escapement
[2])
69 struct vg_glyph
*glyph
;
71 /* remove the existing one */
72 del_glyph(font
, glyphIndex
);
74 glyph
= CALLOC_STRUCT(vg_glyph
);
76 glyph
->is_hinted
= isHinted
;
77 memcpy(glyph
->glyph_origin
, glyphOrigin
, sizeof(glyphOrigin
));
78 memcpy(glyph
->escapement
, escapement
, sizeof(escapement
));
80 cso_hash_insert(font
->glyphs
, (unsigned) glyphIndex
, glyph
);
83 static struct vg_glyph
*get_glyph(struct vg_font
*font
,
86 struct cso_hash_iter iter
;
88 iter
= cso_hash_find(font
->glyphs
, (unsigned) glyphIndex
);
89 return (struct vg_glyph
*) cso_hash_iter_data(iter
);
92 static void vg_render_glyph(struct vg_context
*ctx
,
93 struct vg_glyph
*glyph
,
94 VGbitfield paintModes
,
95 VGboolean allowAutoHinting
)
97 if (glyph
->object
&& paintModes
) {
98 struct vg_state
*state
= &ctx
->state
.vg
;
101 m
= state
->glyph_user_to_surface_matrix
;
103 state
->glyph_origin
[0].f
- glyph
->glyph_origin
[0],
104 state
->glyph_origin
[1].f
- glyph
->glyph_origin
[1]);
106 if (glyph
->object
->type
== VG_OBJECT_PATH
) {
107 path_render((struct path
*) glyph
->object
, paintModes
, &m
);
110 assert(glyph
->object
->type
== VG_OBJECT_IMAGE
);
111 image_draw((struct vg_image
*) glyph
->object
, &m
);
116 static void vg_advance_glyph(struct vg_context
*ctx
,
117 struct vg_glyph
*glyph
,
118 VGfloat adjustment_x
,
119 VGfloat adjustment_y
,
122 struct vg_value
*glyph_origin
= ctx
->state
.vg
.glyph_origin
;
124 glyph_origin
[0].f
+= glyph
->escapement
[0] + adjustment_x
;
125 glyph_origin
[1].f
+= glyph
->escapement
[1] + adjustment_y
;
128 glyph_origin
[0].i
= float_to_int_floor(glyph_origin
[0].f
);
129 glyph_origin
[1].i
= float_to_int_floor(glyph_origin
[1].f
);
133 struct vg_font
*font_create(VGint glyphCapacityHint
)
135 struct vg_context
*ctx
= vg_current_context();
136 struct vg_font
*font
;
138 font
= CALLOC_STRUCT(vg_font
);
139 vg_init_object(&font
->base
, ctx
, VG_OBJECT_FONT
);
140 font
->glyphs
= cso_hash_create();
142 vg_context_add_object(ctx
, VG_OBJECT_FONT
, font
);
147 void font_destroy(struct vg_font
*font
)
149 struct vg_context
*ctx
= vg_current_context();
150 struct cso_hash_iter iter
;
152 vg_context_remove_object(ctx
, VG_OBJECT_FONT
, font
);
154 iter
= cso_hash_first_node(font
->glyphs
);
155 while (!cso_hash_iter_is_null(iter
)) {
156 struct vg_glyph
*glyph
= (struct vg_glyph
*) cso_hash_iter_data(iter
);
158 iter
= cso_hash_iter_next(iter
);
160 cso_hash_delete(font
->glyphs
);
165 void font_set_glyph_to_path(struct vg_font
*font
,
169 const VGfloat glyphOrigin
[2],
170 const VGfloat escapement
[2])
172 add_glyph(font
, glyphIndex
, (struct vg_object
*) path
,
173 isHinted
, glyphOrigin
, escapement
);
176 void font_set_glyph_to_image(struct vg_font
*font
,
178 struct vg_image
*image
,
179 const VGfloat glyphOrigin
[2],
180 const VGfloat escapement
[2])
182 add_glyph(font
, glyphIndex
, (struct vg_object
*) image
,
183 VG_TRUE
, glyphOrigin
, escapement
);
186 void font_clear_glyph(struct vg_font
*font
,
189 if (!del_glyph(font
, glyphIndex
)) {
190 struct vg_context
*ctx
= vg_current_context();
191 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
195 void font_draw_glyph(struct vg_font
*font
,
197 VGbitfield paintModes
,
198 VGboolean allowAutoHinting
)
200 struct vg_context
*ctx
= vg_current_context();
201 struct vg_glyph
*glyph
;
203 glyph
= get_glyph(font
, glyphIndex
);
205 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
209 vg_render_glyph(ctx
, glyph
, paintModes
, allowAutoHinting
);
210 vg_advance_glyph(ctx
, glyph
, 0.0f
, 0.0f
, VG_TRUE
);
213 void font_draw_glyphs(struct vg_font
*font
,
215 const VGuint
*glyphIndices
,
216 const VGfloat
*adjustments_x
,
217 const VGfloat
*adjustments_y
,
218 VGbitfield paintModes
,
219 VGboolean allowAutoHinting
)
221 struct vg_context
*ctx
= vg_current_context();
224 for (i
= 0; i
< glyphCount
; ++i
) {
225 if (!get_glyph(font
, glyphIndices
[i
])) {
226 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
231 for (i
= 0; i
< glyphCount
; ++i
) {
232 struct vg_glyph
*glyph
;
233 VGfloat adj_x
, adj_y
;
235 glyph
= get_glyph(font
, glyphIndices
[i
]);
237 vg_render_glyph(ctx
, glyph
, paintModes
, allowAutoHinting
);
239 adj_x
= (adjustments_x
) ? adjustments_x
[i
] : 0.0f
;
240 adj_y
= (adjustments_y
) ? adjustments_y
[i
] : 0.0f
;
241 vg_advance_glyph(ctx
, glyph
, adj_x
, adj_y
, (i
== glyphCount
- 1));
245 VGint
font_num_glyphs(struct vg_font
*font
)
247 return cso_hash_size(font
->glyphs
);
250 #endif /* OPENVG_VERSION_1_1 */