api_text.c revision 56f02cedfaca9755d2855ec3fe075ccfe5e85c0a
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#include "api.h"
31
32#include "util/u_memory.h"
33
34#ifdef OPENVG_VERSION_1_1
35
36struct vg_font {
37   struct vg_object base;
38
39   VGint glyph_indices[200];
40   VGint num_glyphs;
41};
42
43VGFont vegaCreateFont(VGint glyphCapacityHint)
44{
45   struct vg_font *font = 0;
46   struct vg_context *ctx = vg_current_context();
47
48   if (glyphCapacityHint < 0) {
49      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
50      return VG_INVALID_HANDLE;
51   }
52
53   font = CALLOC_STRUCT(vg_font);
54   vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
55   vg_context_add_object(ctx, VG_OBJECT_FONT, font);
56   return (VGFont)font;
57}
58
59void vegaDestroyFont(VGFont f)
60{
61   struct vg_font *font = (struct vg_font *)f;
62   struct vg_context *ctx = vg_current_context();
63
64   if (f == VG_INVALID_HANDLE) {
65      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
66      return;
67   }
68
69   vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
70   /*free(font);*/
71}
72
73void vegaSetGlyphToPath(VGFont font,
74                        VGuint glyphIndex,
75                        VGPath path,
76                        VGboolean isHinted,
77                        const VGfloat glyphOrigin[2],
78                        const VGfloat escapement[2])
79{
80   struct vg_context *ctx = vg_current_context();
81   struct vg_object *pathObj;
82   struct vg_font *f;
83
84   if (font == VG_INVALID_HANDLE ||
85       !vg_context_is_object_valid(ctx, VG_OBJECT_FONT, (void *)font)) {
86      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
87      return;
88   }
89   if (!glyphOrigin || !escapement ||
90       !is_aligned(glyphOrigin) || !is_aligned(escapement)) {
91      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
92      return;
93   }
94   if (path != VG_INVALID_HANDLE &&
95       !vg_context_is_object_valid(ctx, VG_OBJECT_PATH, (void *)path)) {
96      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
97      return;
98   }
99   pathObj = (struct vg_object*)path;
100   if (pathObj && pathObj->type != VG_OBJECT_PATH) {
101      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
102      return;
103   }
104
105   f = (struct vg_font*)font;
106   f->glyph_indices[f->num_glyphs] = glyphIndex;
107   ++f->num_glyphs;
108}
109
110void vegaSetGlyphToImage(VGFont font,
111                         VGuint glyphIndex,
112                         VGImage image,
113                         const VGfloat glyphOrigin[2],
114                         const VGfloat escapement[2])
115{
116   struct vg_context *ctx = vg_current_context();
117   struct vg_object *img_obj;
118   struct vg_font *f;
119
120   if (font == VG_INVALID_HANDLE ||
121       !vg_context_is_object_valid(ctx, VG_OBJECT_FONT, (void *)font)) {
122      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
123      return;
124   }
125   if (!glyphOrigin || !escapement ||
126       !is_aligned(glyphOrigin) || !is_aligned(escapement)) {
127      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
128      return;
129   }
130   if (image != VG_INVALID_HANDLE &&
131       !vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, (void *)image)) {
132      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
133      return;
134   }
135   img_obj = (struct vg_object*)image;
136   if (img_obj && img_obj->type != VG_OBJECT_IMAGE) {
137      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
138      return;
139   }
140   f = (struct vg_font*)font;
141   f->glyph_indices[f->num_glyphs] = glyphIndex;
142   ++f->num_glyphs;
143}
144
145static INLINE VGboolean font_contains_glyph(struct vg_font *font,
146                                            VGuint glyph_index)
147{
148   VGint i;
149   for (i = 0; i < font->num_glyphs; ++i) {
150      if (font->glyph_indices[i] == glyph_index) {
151         return VG_TRUE;
152      }
153   }
154   return VG_FALSE;
155}
156
157void vegaClearGlyph(VGFont font,
158                    VGuint glyphIndex)
159{
160   struct vg_context *ctx = vg_current_context();
161   struct vg_font *f;
162   VGint i;
163
164   if (font == VG_INVALID_HANDLE) {
165      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
166      return;
167   }
168   if (glyphIndex <= 0) {
169      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
170      return;
171   }
172   f = (struct vg_font*)font;
173   if (!font_contains_glyph(f, glyphIndex)) {
174      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
175      return;
176   }
177
178   for (i = 0; i < f->num_glyphs; ++i) {
179      if (f->glyph_indices[i] == glyphIndex) {
180         /*FIXME*/
181         f->glyph_indices[f->num_glyphs] = 0;
182         --f->num_glyphs;
183         return;
184      }
185   }
186}
187
188void vegaDrawGlyph(VGFont font,
189                   VGuint glyphIndex,
190                   VGbitfield paintModes,
191                   VGboolean allowAutoHinting)
192{
193   struct vg_context *ctx = vg_current_context();
194   struct vg_font *f;
195
196   if (font == VG_INVALID_HANDLE) {
197      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
198      return;
199   }
200   if (glyphIndex <= 0) {
201      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
202      return;
203   }
204   if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
205      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
206      return;
207   }
208   f = (struct vg_font*)font;
209   if (!font_contains_glyph(f, glyphIndex)) {
210      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
211      return;
212   }
213}
214
215void vegaDrawGlyphs(VGFont font,
216                    VGint glyphCount,
217                    const VGuint *glyphIndices,
218                    const VGfloat *adjustments_x,
219                    const VGfloat *adjustments_y,
220                    VGbitfield paintModes,
221                    VGboolean allowAutoHinting)
222{
223   struct vg_context *ctx = vg_current_context();
224   VGint i;
225   struct vg_font *f;
226
227   if (font == VG_INVALID_HANDLE) {
228      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
229      return;
230   }
231   if (glyphCount <= 0) {
232      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
233      return;
234   }
235   if (!glyphIndices || !is_aligned(glyphIndices)) {
236      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
237      return;
238   }
239   if (!adjustments_x || !is_aligned(adjustments_x) ||
240       !adjustments_y || !is_aligned(adjustments_y)) {
241      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
242      return;
243   }
244   if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
245      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
246      return;
247   }
248
249   f = (struct vg_font*)font;
250   for (i = 0; i < glyphCount; ++i) {
251      VGuint glyph_index = glyphIndices[i];
252      if (!font_contains_glyph(f, glyph_index)) {
253         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
254         return;
255      }
256   }
257}
258
259#endif
260