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
);
58 return (glyph
!= NULL
);
61 static void add_glyph(struct vg_font
*font
,
63 struct vg_object
*obj
,
65 const VGfloat glyphOrigin
[2],
66 const VGfloat escapement
[2])
68 struct vg_glyph
*glyph
;
70 /* remove the existing one */
71 del_glyph(font
, glyphIndex
);
73 glyph
= CALLOC_STRUCT(vg_glyph
);
75 glyph
->is_hinted
= isHinted
;
76 memcpy(glyph
->glyph_origin
, glyphOrigin
, sizeof(glyphOrigin
[0])*2);
77 memcpy(glyph
->escapement
, escapement
, sizeof(escapement
[0])*2);
79 cso_hash_insert(font
->glyphs
, (unsigned) glyphIndex
, glyph
);
82 static struct vg_glyph
*get_glyph(struct vg_font
*font
,
85 struct cso_hash_iter iter
;
87 iter
= cso_hash_find(font
->glyphs
, (unsigned) glyphIndex
);
88 return (struct vg_glyph
*) cso_hash_iter_data(iter
);
91 static void vg_render_glyph(struct vg_context
*ctx
,
92 struct vg_glyph
*glyph
,
93 VGbitfield paintModes
,
94 VGboolean allowAutoHinting
)
96 if (glyph
->object
&& paintModes
) {
97 struct vg_state
*state
= &ctx
->state
.vg
;
100 m
= state
->glyph_user_to_surface_matrix
;
102 state
->glyph_origin
[0].f
- glyph
->glyph_origin
[0],
103 state
->glyph_origin
[1].f
- glyph
->glyph_origin
[1]);
105 if (glyph
->object
->type
== VG_OBJECT_PATH
) {
106 path_render((struct path
*) glyph
->object
, paintModes
, &m
);
109 assert(glyph
->object
->type
== VG_OBJECT_IMAGE
);
110 image_draw((struct vg_image
*) glyph
->object
, &m
);
115 static void vg_advance_glyph(struct vg_context
*ctx
,
116 struct vg_glyph
*glyph
,
117 VGfloat adjustment_x
,
118 VGfloat adjustment_y
,
121 struct vg_value
*glyph_origin
= ctx
->state
.vg
.glyph_origin
;
123 glyph_origin
[0].f
+= glyph
->escapement
[0] + adjustment_x
;
124 glyph_origin
[1].f
+= glyph
->escapement
[1] + adjustment_y
;
127 glyph_origin
[0].i
= float_to_int_floor(glyph_origin
[0].f
);
128 glyph_origin
[1].i
= float_to_int_floor(glyph_origin
[1].f
);
132 struct vg_font
*font_create(VGint glyphCapacityHint
)
134 struct vg_context
*ctx
= vg_current_context();
135 struct vg_font
*font
;
137 font
= CALLOC_STRUCT(vg_font
);
138 vg_init_object(&font
->base
, ctx
, VG_OBJECT_FONT
);
139 font
->glyphs
= cso_hash_create();
141 vg_context_add_object(ctx
, VG_OBJECT_FONT
, font
);
146 void font_destroy(struct vg_font
*font
)
148 struct vg_context
*ctx
= vg_current_context();
149 struct cso_hash_iter iter
;
151 vg_context_remove_object(ctx
, VG_OBJECT_FONT
, font
);
153 iter
= cso_hash_first_node(font
->glyphs
);
154 while (!cso_hash_iter_is_null(iter
)) {
155 struct vg_glyph
*glyph
= (struct vg_glyph
*) cso_hash_iter_data(iter
);
157 iter
= cso_hash_iter_next(iter
);
159 cso_hash_delete(font
->glyphs
);
164 void font_set_glyph_to_path(struct vg_font
*font
,
168 const VGfloat glyphOrigin
[2],
169 const VGfloat escapement
[2])
171 add_glyph(font
, glyphIndex
, (struct vg_object
*) path
,
172 isHinted
, glyphOrigin
, escapement
);
175 void font_set_glyph_to_image(struct vg_font
*font
,
177 struct vg_image
*image
,
178 const VGfloat glyphOrigin
[2],
179 const VGfloat escapement
[2])
181 add_glyph(font
, glyphIndex
, (struct vg_object
*) image
,
182 VG_TRUE
, glyphOrigin
, escapement
);
185 void font_clear_glyph(struct vg_font
*font
,
188 if (!del_glyph(font
, glyphIndex
)) {
189 struct vg_context
*ctx
= vg_current_context();
190 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
194 void font_draw_glyph(struct vg_font
*font
,
196 VGbitfield paintModes
,
197 VGboolean allowAutoHinting
)
199 struct vg_context
*ctx
= vg_current_context();
200 struct vg_glyph
*glyph
;
202 glyph
= get_glyph(font
, glyphIndex
);
204 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
208 vg_render_glyph(ctx
, glyph
, paintModes
, allowAutoHinting
);
209 vg_advance_glyph(ctx
, glyph
, 0.0f
, 0.0f
, VG_TRUE
);
212 void font_draw_glyphs(struct vg_font
*font
,
214 const VGuint
*glyphIndices
,
215 const VGfloat
*adjustments_x
,
216 const VGfloat
*adjustments_y
,
217 VGbitfield paintModes
,
218 VGboolean allowAutoHinting
)
220 struct vg_context
*ctx
= vg_current_context();
223 for (i
= 0; i
< glyphCount
; ++i
) {
224 if (!get_glyph(font
, glyphIndices
[i
])) {
225 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
230 for (i
= 0; i
< glyphCount
; ++i
) {
231 struct vg_glyph
*glyph
;
232 VGfloat adj_x
, adj_y
;
234 glyph
= get_glyph(font
, glyphIndices
[i
]);
236 vg_render_glyph(ctx
, glyph
, paintModes
, allowAutoHinting
);
238 adj_x
= (adjustments_x
) ? adjustments_x
[i
] : 0.0f
;
239 adj_y
= (adjustments_y
) ? adjustments_y
[i
] : 0.0f
;
240 vg_advance_glyph(ctx
, glyph
, adj_x
, adj_y
, (i
== glyphCount
- 1));
244 VGint
font_num_glyphs(struct vg_font
*font
)
246 return cso_hash_size(font
->glyphs
);
249 #endif /* OPENVG_VERSION_1_1 */