Merge branch 'lp-offset-twoside'
[mesa.git] / src / gallium / state_trackers / vega / api_text.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
4 *
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:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
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.
24 *
25 **************************************************************************/
26
27 #include "VG/openvg.h"
28
29 #include "vg_context.h"
30
31 #include "util/u_memory.h"
32
33 #ifdef OPENVG_VERSION_1_1
34
35 struct vg_font {
36 struct vg_object base;
37
38 VGint glyph_indices[200];
39 VGint num_glyphs;
40 };
41
42 VGFont vegaCreateFont(VGint glyphCapacityHint)
43 {
44 struct vg_font *font = 0;
45 struct vg_context *ctx = vg_current_context();
46
47 if (glyphCapacityHint < 0) {
48 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
49 return VG_INVALID_HANDLE;
50 }
51
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);
55 return (VGFont)font;
56 }
57
58 void vegaDestroyFont(VGFont f)
59 {
60 struct vg_font *font = (struct vg_font *)f;
61 struct vg_context *ctx = vg_current_context();
62
63 if (f == VG_INVALID_HANDLE) {
64 vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
65 return;
66 }
67
68 vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
69 /*free(font);*/
70 }
71
72 void vegaSetGlyphToPath(VGFont font,
73 VGuint glyphIndex,
74 VGPath path,
75 VGboolean isHinted,
76 VGfloat glyphOrigin [2],
77 VGfloat escapement[2])
78 {
79 struct vg_context *ctx = vg_current_context();
80 struct vg_object *pathObj;
81 struct vg_font *f;
82
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);
86 return;
87 }
88 if (!glyphOrigin || !escapement ||
89 !is_aligned(glyphOrigin) || !is_aligned(escapement)) {
90 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
91 return;
92 }
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);
96 return;
97 }
98 pathObj = (struct vg_object*)path;
99 if (pathObj && pathObj->type != VG_OBJECT_PATH) {
100 vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
101 return;
102 }
103
104 f = (struct vg_font*)font;
105 f->glyph_indices[f->num_glyphs] = glyphIndex;
106 ++f->num_glyphs;
107 }
108
109 void vegaSetGlyphToImage(VGFont font,
110 VGuint glyphIndex,
111 VGImage image,
112 VGfloat glyphOrigin [2],
113 VGfloat escapement[2])
114 {
115 struct vg_context *ctx = vg_current_context();
116 struct vg_object *img_obj;
117 struct vg_font *f;
118
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);
122 return;
123 }
124 if (!glyphOrigin || !escapement ||
125 !is_aligned(glyphOrigin) || !is_aligned(escapement)) {
126 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
127 return;
128 }
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);
132 return;
133 }
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);
137 return;
138 }
139 f = (struct vg_font*)font;
140 f->glyph_indices[f->num_glyphs] = glyphIndex;
141 ++f->num_glyphs;
142 }
143
144 static INLINE VGboolean font_contains_glyph(struct vg_font *font,
145 VGuint glyph_index)
146 {
147 VGint i;
148 for (i = 0; i < font->num_glyphs; ++i) {
149 if (font->glyph_indices[i] == glyph_index) {
150 return VG_TRUE;
151 }
152 }
153 return VG_FALSE;
154 }
155
156 void vegaClearGlyph(VGFont font,
157 VGuint glyphIndex)
158 {
159 struct vg_context *ctx = vg_current_context();
160 struct vg_font *f;
161 VGint i;
162
163 if (font == VG_INVALID_HANDLE) {
164 vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
165 return;
166 }
167 if (glyphIndex <= 0) {
168 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
169 return;
170 }
171 f = (struct vg_font*)font;
172 if (!font_contains_glyph(f, glyphIndex)) {
173 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
174 return;
175 }
176
177 for (i = 0; i < f->num_glyphs; ++i) {
178 if (f->glyph_indices[i] == glyphIndex) {
179 /*FIXME*/
180 f->glyph_indices[f->num_glyphs] = 0;
181 --f->num_glyphs;
182 return;
183 }
184 }
185 }
186
187 void vegaDrawGlyph(VGFont font,
188 VGuint glyphIndex,
189 VGbitfield paintModes,
190 VGboolean allowAutoHinting)
191 {
192 struct vg_context *ctx = vg_current_context();
193 struct vg_font *f;
194
195 if (font == VG_INVALID_HANDLE) {
196 vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
197 return;
198 }
199 if (glyphIndex <= 0) {
200 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
201 return;
202 }
203 if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
204 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
205 return;
206 }
207 f = (struct vg_font*)font;
208 if (!font_contains_glyph(f, glyphIndex)) {
209 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
210 return;
211 }
212 }
213
214 void vegaDrawGlyphs(VGFont font,
215 VGint glyphCount,
216 VGuint *glyphIndices,
217 VGfloat *adjustments_x,
218 VGfloat *adjustments_y,
219 VGbitfield paintModes,
220 VGboolean allowAutoHinting)
221 {
222 struct vg_context *ctx = vg_current_context();
223 VGint i;
224 struct vg_font *f;
225
226 if (font == VG_INVALID_HANDLE) {
227 vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
228 return;
229 }
230 if (glyphCount <= 0) {
231 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
232 return;
233 }
234 if (!glyphIndices || !is_aligned(glyphIndices)) {
235 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
236 return;
237 }
238 if (!adjustments_x || !is_aligned(adjustments_x) ||
239 !adjustments_y || !is_aligned(adjustments_y)) {
240 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
241 return;
242 }
243 if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
244 vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
245 return;
246 }
247
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);
253 return;
254 }
255 }
256 }
257
258 #endif