1 /**************************************************************************
3 * Copyright 2009 VMware, 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 "VG/openvg.h"
29 #include "vg_context.h"
31 #include "util/u_memory.h"
33 #ifdef OPENVG_VERSION_1_1
36 struct vg_object base
;
38 VGint glyph_indices
[200];
42 VGFont
vgCreateFont(VGint glyphCapacityHint
)
44 struct vg_font
*font
= 0;
45 struct vg_context
*ctx
= vg_current_context();
47 if (glyphCapacityHint
< 0) {
48 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
49 return VG_INVALID_HANDLE
;
52 font
= CALLOC_STRUCT(vg_font
);
53 vg_init_object(&font
->base
, ctx
, VG_OBJECT_FONT
);
54 vg_context_add_object(ctx
, VG_OBJECT_FONT
, font
);
58 void vgDestroyFont(VGFont f
)
60 struct vg_font
*font
= (struct vg_font
*)f
;
61 struct vg_context
*ctx
= vg_current_context();
63 if (f
== VG_INVALID_HANDLE
) {
64 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
68 vg_context_remove_object(ctx
, VG_OBJECT_FONT
, font
);
72 void vgSetGlyphToPath(VGFont font
,
76 VGfloat glyphOrigin
[2],
77 VGfloat escapement
[2])
79 struct vg_context
*ctx
= vg_current_context();
80 struct vg_object
*pathObj
;
83 if (font
== VG_INVALID_HANDLE
||
84 !vg_context_is_object_valid(ctx
, VG_OBJECT_FONT
, (void *)font
)) {
85 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
88 if (!glyphOrigin
|| !escapement
||
89 !is_aligned(glyphOrigin
) || !is_aligned(escapement
)) {
90 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
93 if (path
!= VG_INVALID_HANDLE
&&
94 !vg_context_is_object_valid(ctx
, VG_OBJECT_PATH
, (void *)path
)) {
95 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
98 pathObj
= (struct vg_object
*)path
;
99 if (pathObj
&& pathObj
->type
!= VG_OBJECT_PATH
) {
100 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
104 f
= (struct vg_font
*)font
;
105 f
->glyph_indices
[f
->num_glyphs
] = glyphIndex
;
109 void vgSetGlyphToImage(VGFont font
,
112 VGfloat glyphOrigin
[2],
113 VGfloat escapement
[2])
115 struct vg_context
*ctx
= vg_current_context();
116 struct vg_object
*img_obj
;
119 if (font
== VG_INVALID_HANDLE
||
120 !vg_context_is_object_valid(ctx
, VG_OBJECT_FONT
, (void *)font
)) {
121 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
124 if (!glyphOrigin
|| !escapement
||
125 !is_aligned(glyphOrigin
) || !is_aligned(escapement
)) {
126 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
129 if (image
!= VG_INVALID_HANDLE
&&
130 !vg_context_is_object_valid(ctx
, VG_OBJECT_IMAGE
, (void *)image
)) {
131 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
134 img_obj
= (struct vg_object
*)image
;
135 if (img_obj
&& img_obj
->type
!= VG_OBJECT_IMAGE
) {
136 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
139 f
= (struct vg_font
*)font
;
140 f
->glyph_indices
[f
->num_glyphs
] = glyphIndex
;
144 static INLINE VGboolean
font_contains_glyph(struct vg_font
*font
,
148 for (i
= 0; i
< font
->num_glyphs
; ++i
) {
149 if (font
->glyph_indices
[i
] == glyph_index
) {
156 void vgClearGlyph(VGFont font
,
159 struct vg_context
*ctx
= vg_current_context();
163 if (font
== VG_INVALID_HANDLE
) {
164 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
167 if (glyphIndex
<= 0) {
168 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
171 f
= (struct vg_font
*)font
;
172 if (!font_contains_glyph(f
, glyphIndex
)) {
173 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
177 for (i
= 0; i
< f
->num_glyphs
; ++i
) {
178 if (f
->glyph_indices
[i
] == glyphIndex
) {
180 f
->glyph_indices
[f
->num_glyphs
] = 0;
187 void vgDrawGlyph(VGFont font
,
189 VGbitfield paintModes
,
190 VGboolean allowAutoHinting
)
192 struct vg_context
*ctx
= vg_current_context();
195 if (font
== VG_INVALID_HANDLE
) {
196 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
199 if (glyphIndex
<= 0) {
200 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
203 if (paintModes
& (~(VG_STROKE_PATH
|VG_FILL_PATH
))) {
204 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
207 f
= (struct vg_font
*)font
;
208 if (!font_contains_glyph(f
, glyphIndex
)) {
209 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
214 void vgDrawGlyphs(VGFont font
,
216 VGuint
*glyphIndices
,
217 VGfloat
*adjustments_x
,
218 VGfloat
*adjustments_y
,
219 VGbitfield paintModes
,
220 VGboolean allowAutoHinting
)
222 struct vg_context
*ctx
= vg_current_context();
226 if (font
== VG_INVALID_HANDLE
) {
227 vg_set_error(ctx
, VG_BAD_HANDLE_ERROR
);
230 if (glyphCount
<= 0) {
231 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
234 if (!glyphIndices
|| !is_aligned(glyphIndices
)) {
235 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
238 if (!adjustments_x
|| !is_aligned(adjustments_x
) ||
239 !adjustments_y
|| !is_aligned(adjustments_y
)) {
240 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
243 if (paintModes
& (~(VG_STROKE_PATH
|VG_FILL_PATH
))) {
244 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);
248 f
= (struct vg_font
*)font
;
249 for (i
= 0; i
< glyphCount
; ++i
) {
250 VGuint glyph_index
= glyphIndices
[i
];
251 if (!font_contains_glyph(f
, glyph_index
)) {
252 vg_set_error(ctx
, VG_ILLEGAL_ARGUMENT_ERROR
);