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"
34 #ifdef OPENVG_VERSION_1_1
37 struct vg_object base
;
38 struct cso_hash
*glyphs
;
42 struct vg_object
*object
; /* it could be NULL */
44 VGfloat glyph_origin
[2];
45 VGfloat escapement
[2];
48 static VGboolean
del_glyph(struct vg_font
*font
,
51 struct vg_glyph
*glyph
;
53 glyph
= (struct vg_glyph
*)
54 cso_hash_take(font
->glyphs
, (unsigned) glyphIndex
);
57 return (glyph
!= NULL
);
60 static void add_glyph(struct vg_font
*font
,
62 struct vg_object
*obj
,
64 const VGfloat glyphOrigin
[2],
65 const VGfloat escapement
[2])
67 struct vg_glyph
*glyph
;
69 /* remove the existing one */
70 del_glyph(font
, glyphIndex
);
72 glyph
= CALLOC_STRUCT(vg_glyph
);
74 glyph
->is_hinted
= isHinted
;
75 memcpy(glyph
->glyph_origin
, glyphOrigin
, sizeof(glyph
->glyph_origin
));
76 memcpy(glyph
->escapement
, escapement
, sizeof(glyph
->glyph_origin
));
78 cso_hash_insert(font
->glyphs
, (unsigned) glyphIndex
, glyph
);
81 static struct vg_glyph
*get_glyph(struct vg_font
*font
,
84 struct cso_hash_iter iter
;
86 iter
= cso_hash_find(font
->glyphs
, (unsigned) glyphIndex
);
87 return (struct vg_glyph
*) cso_hash_iter_data(iter
);
90 static void vg_render_glyph(struct vg_context
*ctx
,
91 struct vg_glyph
*glyph
,
92 VGbitfield paintModes
,
93 VGboolean allowAutoHinting
)
95 if (glyph
->object
&& paintModes
) {
96 struct vg_state
*state
= &ctx
->state
.vg
;
99 m
= state
->glyph_user_to_surface_matrix
;
101 state
->glyph_origin
[0].f
- glyph
->glyph_origin
[0],
102 state
->glyph_origin
[1].f
- glyph
->glyph_origin
[1]);
104 if (glyph
->object
->type
== VG_OBJECT_PATH
) {
105 path_render((struct path
*) glyph
->object
, paintModes
, &m
);
108 assert(glyph
->object
->type
== VG_OBJECT_IMAGE
);
109 image_draw((struct vg_image
*) glyph
->object
, &m
);
114 static void vg_advance_glyph(struct vg_context
*ctx
,
115 struct vg_glyph
*glyph
,
116 VGfloat adjustment_x
,
117 VGfloat adjustment_y
,
120 struct vg_value
*glyph_origin
= ctx
->state
.vg
.glyph_origin
;
122 glyph_origin
[0].f
+= glyph
->escapement
[0] + adjustment_x
;
123 glyph_origin
[1].f
+= glyph
->escapement
[1] + adjustment_y
;
126 glyph_origin
[0].i
= float_to_int_floor(glyph_origin
[0].f
);
127 glyph_origin
[1].i
= float_to_int_floor(glyph_origin
[1].f
);
131 struct vg_font
*font_create(VGint glyphCapacityHint
)
133 struct vg_context
*ctx
= vg_current_context();
134 struct vg_font
*font
;
136 font
= CALLOC_STRUCT(vg_font
);
137 vg_init_object(&font
->base
, ctx
, VG_OBJECT_FONT
);
138 font
->glyphs
= cso_hash_create();
140 vg_context_add_object(ctx
, &font
->base
);
145 void font_destroy(struct vg_font
*font
)
147 struct vg_context
*ctx
= vg_current_context();
148 struct cso_hash_iter iter
;
150 vg_context_remove_object(ctx
, &font
->base
);
152 iter
= cso_hash_first_node(font
->glyphs
);
153 while (!cso_hash_iter_is_null(iter
)) {
154 struct vg_glyph
*glyph
= (struct vg_glyph
*) cso_hash_iter_data(iter
);
156 iter
= cso_hash_iter_next(iter
);
158 cso_hash_delete(font
->glyphs
);
160 vg_free_object(&font
->base
);
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 */