api_params.c revision 544dd4b11f7be76bb00fe29a60eaf2772dcc69ca
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 "paint.h"
31#include "path.h"
32#include "image.h"
33#include "matrix.h"
34#include "api_consts.h"
35
36#include "pipe/p_compiler.h"
37#include "util/u_pointer.h"
38#include "util/u_math.h"
39
40#include <math.h>
41
42static INLINE struct vg_state *current_state()
43{
44   struct vg_context *ctx = vg_current_context();
45   if (!ctx)
46      return 0;
47   else
48      return &ctx->state.vg;
49}
50
51static INLINE VGboolean count_in_bounds(VGParamType type, VGint count)
52{
53   if (count < 0)
54      return VG_FALSE;
55
56   if (type == VG_SCISSOR_RECTS)
57      return (!(count % 4) && (count >= 0 || count <= VEGA_MAX_SCISSOR_RECTS * 4));
58   else if (type == VG_STROKE_DASH_PATTERN) {
59      return count <= VEGA_MAX_DASH_COUNT;
60   } else {
61      VGint real_count = vgGetVectorSize(type);
62      return count == real_count;
63   }
64}
65
66void vgSetf (VGParamType type, VGfloat value)
67{
68   struct vg_context *ctx = vg_current_context();
69   struct vg_state *state = current_state();
70   VGErrorCode error = VG_NO_ERROR;
71
72   switch(type) {
73   case VG_MATRIX_MODE:
74   case VG_FILL_RULE:
75   case VG_IMAGE_QUALITY:
76   case VG_RENDERING_QUALITY:
77   case VG_BLEND_MODE:
78   case VG_IMAGE_MODE:
79#ifdef OPENVG_VERSION_1_1
80   case VG_COLOR_TRANSFORM:
81#endif
82   case VG_STROKE_CAP_STYLE:
83   case VG_STROKE_JOIN_STYLE:
84   case VG_STROKE_DASH_PHASE_RESET:
85   case VG_MASKING:
86   case VG_SCISSORING:
87   case VG_PIXEL_LAYOUT:
88   case VG_SCREEN_LAYOUT:
89   case VG_FILTER_FORMAT_LINEAR:
90   case VG_FILTER_FORMAT_PREMULTIPLIED:
91   case VG_FILTER_CHANNEL_MASK:
92
93   case VG_MAX_SCISSOR_RECTS:
94   case VG_MAX_DASH_COUNT:
95   case VG_MAX_KERNEL_SIZE:
96   case VG_MAX_SEPARABLE_KERNEL_SIZE:
97   case VG_MAX_COLOR_RAMP_STOPS:
98   case VG_MAX_IMAGE_WIDTH:
99   case VG_MAX_IMAGE_HEIGHT:
100   case VG_MAX_IMAGE_PIXELS:
101   case VG_MAX_IMAGE_BYTES:
102   case VG_MAX_GAUSSIAN_STD_DEVIATION:
103   case VG_MAX_FLOAT:
104      vgSeti(type, floor(value));
105      return;
106      break;
107   case VG_STROKE_LINE_WIDTH:
108      state->stroke.line_width.f = value;
109      state->stroke.line_width.i = float_to_int_floor(*((VGuint*)(&value)));
110      break;
111   case VG_STROKE_MITER_LIMIT:
112      state->stroke.miter_limit.f = value;
113      state->stroke.miter_limit.i = float_to_int_floor(*((VGuint*)(&value)));
114      break;
115   case VG_STROKE_DASH_PHASE:
116      state->stroke.dash_phase.f = value;
117      state->stroke.dash_phase.i = float_to_int_floor(*((VGuint*)(&value)));
118      break;
119   default:
120      error = VG_ILLEGAL_ARGUMENT_ERROR;
121      break;
122   }
123   vg_set_error(ctx, error);
124}
125
126void vgSeti (VGParamType type, VGint value)
127{
128   struct vg_context *ctx = vg_current_context();
129   struct vg_state *state = current_state();
130   VGErrorCode error = VG_NO_ERROR;
131
132   switch(type) {
133   case VG_MATRIX_MODE:
134      if (value < VG_MATRIX_PATH_USER_TO_SURFACE ||
135#ifdef OPENVG_VERSION_1_1
136          value > VG_MATRIX_GLYPH_USER_TO_SURFACE)
137#else
138          value > VG_MATRIX_STROKE_PAINT_TO_USER)
139#endif
140         error = VG_ILLEGAL_ARGUMENT_ERROR;
141      else
142         state->matrix_mode = value;
143      break;
144   case VG_FILL_RULE:
145      if (value < VG_EVEN_ODD ||
146          value > VG_NON_ZERO)
147         error = VG_ILLEGAL_ARGUMENT_ERROR;
148      else
149         state->fill_rule = value;
150      break;
151   case VG_IMAGE_QUALITY:
152      state->image_quality = value;
153      break;
154   case VG_RENDERING_QUALITY:
155      if (value < VG_RENDERING_QUALITY_NONANTIALIASED ||
156          value > VG_RENDERING_QUALITY_BETTER)
157         error = VG_ILLEGAL_ARGUMENT_ERROR;
158      else
159         state->rendering_quality = value;
160      break;
161   case VG_BLEND_MODE:
162      if (value < VG_BLEND_SRC ||
163          value > VG_BLEND_ADDITIVE)
164         error = VG_ILLEGAL_ARGUMENT_ERROR;
165      else {
166         ctx->state.dirty |= BLEND_DIRTY;
167         state->blend_mode = value;
168      }
169      break;
170   case VG_IMAGE_MODE:
171      if (value < VG_DRAW_IMAGE_NORMAL ||
172          value > VG_DRAW_IMAGE_STENCIL)
173         error = VG_ILLEGAL_ARGUMENT_ERROR;
174      else
175         state->image_mode = value;
176#ifdef OPENVG_VERSION_1_1
177   case VG_COLOR_TRANSFORM:
178      state->color_transform = value;
179#endif
180      break;
181   case VG_STROKE_LINE_WIDTH:
182      state->stroke.line_width.f = value;
183      state->stroke.line_width.i = value;
184      break;
185   case VG_STROKE_CAP_STYLE:
186      if (value < VG_CAP_BUTT ||
187          value > VG_CAP_SQUARE)
188         error = VG_ILLEGAL_ARGUMENT_ERROR;
189      else
190         state->stroke.cap_style = value;
191      break;
192   case VG_STROKE_JOIN_STYLE:
193      if (value < VG_JOIN_MITER ||
194          value > VG_JOIN_BEVEL)
195         error = VG_ILLEGAL_ARGUMENT_ERROR;
196      else
197         state->stroke.join_style = value;
198      break;
199   case VG_STROKE_MITER_LIMIT:
200      state->stroke.miter_limit.f = value;
201      state->stroke.miter_limit.i = value;
202      break;
203   case VG_STROKE_DASH_PHASE:
204      state->stroke.dash_phase.f = value;
205      state->stroke.dash_phase.i = value;
206      break;
207   case VG_STROKE_DASH_PHASE_RESET:
208      state->stroke.dash_phase_reset = value;
209      break;
210   case VG_MASKING:
211      state->masking = value;
212      break;
213   case VG_SCISSORING:
214      state->scissoring = value;
215      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
216      break;
217   case VG_PIXEL_LAYOUT:
218      if (value < VG_PIXEL_LAYOUT_UNKNOWN ||
219          value > VG_PIXEL_LAYOUT_BGR_HORIZONTAL)
220         error = VG_ILLEGAL_ARGUMENT_ERROR;
221      else
222         state->pixel_layout = value;
223      break;
224   case VG_SCREEN_LAYOUT:
225      /* read only ignore */
226      break;
227   case VG_FILTER_FORMAT_LINEAR:
228      state->filter_format_linear = value;
229      break;
230   case VG_FILTER_FORMAT_PREMULTIPLIED:
231      state->filter_format_premultiplied = value;
232      break;
233   case VG_FILTER_CHANNEL_MASK:
234      state->filter_channel_mask = value;
235      break;
236
237   case VG_MAX_SCISSOR_RECTS:
238   case VG_MAX_DASH_COUNT:
239   case VG_MAX_KERNEL_SIZE:
240   case VG_MAX_SEPARABLE_KERNEL_SIZE:
241   case VG_MAX_COLOR_RAMP_STOPS:
242   case VG_MAX_IMAGE_WIDTH:
243   case VG_MAX_IMAGE_HEIGHT:
244   case VG_MAX_IMAGE_PIXELS:
245   case VG_MAX_IMAGE_BYTES:
246   case VG_MAX_GAUSSIAN_STD_DEVIATION:
247   case VG_MAX_FLOAT:
248      /* read only ignore */
249      break;
250   default:
251      error = VG_ILLEGAL_ARGUMENT_ERROR;
252      break;
253   }
254   vg_set_error(ctx, error);
255}
256
257void vgSetfv(VGParamType type, VGint count,
258             const VGfloat * values)
259{
260   struct vg_context *ctx = vg_current_context();
261   struct vg_state *state = current_state();
262   VGErrorCode error = VG_NO_ERROR;
263
264   if ((count && !values) || !count_in_bounds(type, count) || !is_aligned(values)) {
265      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
266      return;
267   }
268
269   switch(type) {
270   case VG_MATRIX_MODE:
271   case VG_FILL_RULE:
272   case VG_IMAGE_QUALITY:
273   case VG_RENDERING_QUALITY:
274   case VG_BLEND_MODE:
275   case VG_IMAGE_MODE:
276#ifdef OPENVG_VERSION_1_1
277   case VG_COLOR_TRANSFORM:
278#endif
279   case VG_STROKE_CAP_STYLE:
280   case VG_STROKE_JOIN_STYLE:
281   case VG_STROKE_DASH_PHASE_RESET:
282   case VG_MASKING:
283   case VG_SCISSORING:
284   case VG_PIXEL_LAYOUT:
285   case VG_SCREEN_LAYOUT:
286   case VG_FILTER_FORMAT_LINEAR:
287   case VG_FILTER_FORMAT_PREMULTIPLIED:
288   case VG_FILTER_CHANNEL_MASK:
289      vgSeti(type, floor(values[0]));
290      return;
291      break;
292   case VG_SCISSOR_RECTS: {
293      VGint i;
294      VGuint *x = (VGuint*)values;
295      for (i = 0; i < count; ++i) {
296         state->scissor_rects[i].f =  values[i];
297         state->scissor_rects[i].i =  float_to_int_floor(x[i]);
298      }
299      state->scissor_rects_num = count / 4;
300      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
301   }
302      break;
303#ifdef OPENVG_VERSION_1_1
304   case VG_COLOR_TRANSFORM_VALUES: {
305      VGint i;
306      for (i = 0; i < count; ++i) {
307         state->color_transform_values[i] =  values[i];
308      }
309   }
310      break;
311#endif
312   case VG_STROKE_LINE_WIDTH:
313      state->stroke.line_width.f = values[0];
314      state->stroke.line_width.i = float_to_int_floor(*((VGuint*)(values)));
315      break;
316   case VG_STROKE_MITER_LIMIT:
317      state->stroke.miter_limit.f = values[0];
318      state->stroke.miter_limit.i = float_to_int_floor(*((VGuint*)(values)));
319      break;
320   case VG_STROKE_DASH_PATTERN: {
321      int i;
322      for (i = 0; i < count; ++i) {
323         state->stroke.dash_pattern[i].f = values[i];
324         state->stroke.dash_pattern[i].i =
325            float_to_int_floor(*((VGuint*)(values + i)));
326      }
327      state->stroke.dash_pattern_num = count;
328   }
329      break;
330   case VG_STROKE_DASH_PHASE:
331      state->stroke.dash_phase.f = values[0];
332      state->stroke.dash_phase.i = float_to_int_floor(*((VGuint*)(values)));
333      break;
334   case VG_TILE_FILL_COLOR:
335      state->tile_fill_color[0] = values[0];
336      state->tile_fill_color[1] = values[1];
337      state->tile_fill_color[2] = values[2];
338      state->tile_fill_color[3] = values[3];
339
340      state->tile_fill_colori[0] = float_to_int_floor(*((VGuint*)(values + 0)));
341      state->tile_fill_colori[1] = float_to_int_floor(*((VGuint*)(values + 1)));
342      state->tile_fill_colori[2] = float_to_int_floor(*((VGuint*)(values + 2)));
343      state->tile_fill_colori[3] = float_to_int_floor(*((VGuint*)(values + 3)));
344      break;
345   case VG_CLEAR_COLOR:
346      state->clear_color[0] = values[0];
347      state->clear_color[1] = values[1];
348      state->clear_color[2] = values[2];
349      state->clear_color[3] = values[3];
350
351      state->clear_colori[0] = float_to_int_floor(*((VGuint*)(values + 0)));
352      state->clear_colori[1] = float_to_int_floor(*((VGuint*)(values + 1)));
353      state->clear_colori[2] = float_to_int_floor(*((VGuint*)(values + 2)));
354      state->clear_colori[3] = float_to_int_floor(*((VGuint*)(values + 3)));
355      break;
356#ifdef OPENVG_VERSION_1_1
357   case VG_GLYPH_ORIGIN:
358      state->glyph_origin[0].f = values[0];
359      state->glyph_origin[1].f = values[1];
360
361      state->glyph_origin[0].i = float_to_int_floor(*((VGuint*)(values + 0)));
362      state->glyph_origin[1].i = float_to_int_floor(*((VGuint*)(values + 1)));
363      break;
364#endif
365
366   case VG_MAX_SCISSOR_RECTS:
367   case VG_MAX_DASH_COUNT:
368   case VG_MAX_KERNEL_SIZE:
369   case VG_MAX_SEPARABLE_KERNEL_SIZE:
370   case VG_MAX_COLOR_RAMP_STOPS:
371   case VG_MAX_IMAGE_WIDTH:
372   case VG_MAX_IMAGE_HEIGHT:
373   case VG_MAX_IMAGE_PIXELS:
374   case VG_MAX_IMAGE_BYTES:
375   case VG_MAX_GAUSSIAN_STD_DEVIATION:
376   case VG_MAX_FLOAT:
377      break;
378   default:
379      error = VG_ILLEGAL_ARGUMENT_ERROR;
380      break;
381   }
382   vg_set_error(ctx, error);
383}
384
385void vgSetiv(VGParamType type, VGint count,
386             const VGint * values)
387{
388   struct vg_context *ctx = vg_current_context();
389   struct vg_state *state = current_state();
390
391   if ((count && !values) || !count_in_bounds(type, count) || !is_aligned(values)) {
392      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
393      return;
394   }
395
396   switch(type) {
397   case VG_MATRIX_MODE:
398   case VG_FILL_RULE:
399   case VG_IMAGE_QUALITY:
400   case VG_RENDERING_QUALITY:
401   case VG_BLEND_MODE:
402   case VG_IMAGE_MODE:
403#ifdef OPENVG_VERSION_1_1
404   case VG_COLOR_TRANSFORM:
405#endif
406   case VG_STROKE_CAP_STYLE:
407   case VG_STROKE_JOIN_STYLE:
408   case VG_STROKE_DASH_PHASE_RESET:
409   case VG_MASKING:
410   case VG_SCISSORING:
411   case VG_PIXEL_LAYOUT:
412   case VG_SCREEN_LAYOUT:
413   case VG_FILTER_FORMAT_LINEAR:
414   case VG_FILTER_FORMAT_PREMULTIPLIED:
415   case VG_FILTER_CHANNEL_MASK:
416      vgSeti(type, values[0]);
417      return;
418      break;
419   case VG_SCISSOR_RECTS: {
420      VGint i;
421      for (i = 0; i < count; ++i) {
422         state->scissor_rects[i].i =  values[i];
423         state->scissor_rects[i].f =  values[i];
424      }
425      state->scissor_rects_num = count / 4;
426      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
427   }
428      break;
429#ifdef OPENVG_VERSION_1_1
430   case VG_COLOR_TRANSFORM_VALUES: {
431      VGint i;
432      for (i = 0; i < count; ++i) {
433         state->color_transform_values[i] =  values[i];
434      }
435   }
436      break;
437#endif
438   case VG_STROKE_LINE_WIDTH:
439      state->stroke.line_width.f = values[0];
440      state->stroke.line_width.i = values[0];
441      break;
442   case VG_STROKE_MITER_LIMIT:
443      state->stroke.miter_limit.f = values[0];
444      state->stroke.miter_limit.i = values[0];
445      break;
446   case VG_STROKE_DASH_PATTERN: {
447      int i;
448      for (i = 0; i < count; ++i) {
449         state->stroke.dash_pattern[i].f = values[i];
450         state->stroke.dash_pattern[i].i = values[i];
451      }
452      state->stroke.dash_pattern_num = count;
453   }
454      break;
455   case VG_STROKE_DASH_PHASE:
456      state->stroke.dash_phase.f = values[0];
457      state->stroke.dash_phase.i = values[0];
458      break;
459   case VG_TILE_FILL_COLOR:
460      state->tile_fill_color[0] = values[0];
461      state->tile_fill_color[1] = values[1];
462      state->tile_fill_color[2] = values[2];
463      state->tile_fill_color[3] = values[3];
464
465      state->tile_fill_colori[0] = values[0];
466      state->tile_fill_colori[1] = values[1];
467      state->tile_fill_colori[2] = values[2];
468      state->tile_fill_colori[3] = values[3];
469      break;
470   case VG_CLEAR_COLOR:
471      state->clear_color[0] = values[0];
472      state->clear_color[1] = values[1];
473      state->clear_color[2] = values[2];
474      state->clear_color[3] = values[3];
475
476      state->clear_colori[0] = values[0];
477      state->clear_colori[1] = values[1];
478      state->clear_colori[2] = values[2];
479      state->clear_colori[3] = values[3];
480      break;
481#ifdef OPENVG_VERSION_1_1
482   case VG_GLYPH_ORIGIN:
483      state->glyph_origin[0].f = values[0];
484      state->glyph_origin[1].f = values[1];
485      state->glyph_origin[0].i = values[0];
486      state->glyph_origin[1].i = values[1];
487      break;
488#endif
489
490   case VG_MAX_SCISSOR_RECTS:
491   case VG_MAX_DASH_COUNT:
492   case VG_MAX_KERNEL_SIZE:
493   case VG_MAX_SEPARABLE_KERNEL_SIZE:
494   case VG_MAX_COLOR_RAMP_STOPS:
495   case VG_MAX_IMAGE_WIDTH:
496   case VG_MAX_IMAGE_HEIGHT:
497   case VG_MAX_IMAGE_PIXELS:
498   case VG_MAX_IMAGE_BYTES:
499   case VG_MAX_GAUSSIAN_STD_DEVIATION:
500   case VG_MAX_FLOAT:
501      break;
502
503   default:
504      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
505      break;
506   }
507}
508
509VGfloat vgGetf(VGParamType type)
510{
511   struct vg_context *ctx = vg_current_context();
512   const struct vg_state *state = current_state();
513   VGErrorCode error = VG_NO_ERROR;
514   VGfloat value = 0.0f;
515
516   switch(type) {
517   case VG_MATRIX_MODE:
518   case VG_FILL_RULE:
519   case VG_IMAGE_QUALITY:
520   case VG_RENDERING_QUALITY:
521   case VG_BLEND_MODE:
522   case VG_IMAGE_MODE:
523#ifdef OPENVG_VERSION_1_1
524   case VG_COLOR_TRANSFORM:
525#endif
526   case VG_STROKE_CAP_STYLE:
527   case VG_STROKE_JOIN_STYLE:
528   case VG_STROKE_DASH_PHASE_RESET:
529   case VG_MASKING:
530   case VG_SCISSORING:
531   case VG_PIXEL_LAYOUT:
532   case VG_SCREEN_LAYOUT:
533   case VG_FILTER_FORMAT_LINEAR:
534   case VG_FILTER_FORMAT_PREMULTIPLIED:
535   case VG_FILTER_CHANNEL_MASK:
536      return vgGeti(type);
537      break;
538   case VG_STROKE_LINE_WIDTH:
539      value = state->stroke.line_width.f;
540      break;
541   case VG_STROKE_MITER_LIMIT:
542      value = state->stroke.miter_limit.f;
543      break;
544   case VG_STROKE_DASH_PHASE:
545      value = state->stroke.dash_phase.f;
546      break;
547
548   case VG_MAX_SCISSOR_RECTS:
549   case VG_MAX_DASH_COUNT:
550   case VG_MAX_KERNEL_SIZE:
551   case VG_MAX_SEPARABLE_KERNEL_SIZE:
552   case VG_MAX_COLOR_RAMP_STOPS:
553   case VG_MAX_IMAGE_WIDTH:
554   case VG_MAX_IMAGE_HEIGHT:
555   case VG_MAX_IMAGE_PIXELS:
556   case VG_MAX_IMAGE_BYTES:
557   case VG_MAX_GAUSSIAN_STD_DEVIATION:
558      return vgGeti(type);
559      break;
560   case VG_MAX_FLOAT:
561      value = 1e+10;/*must be at least 1e+10*/
562      break;
563   default:
564      error = VG_ILLEGAL_ARGUMENT_ERROR;
565      break;
566   }
567   vg_set_error(ctx, error);
568   return value;
569}
570
571VGint vgGeti(VGParamType type)
572{
573   const struct vg_state *state = current_state();
574   struct vg_context *ctx = vg_current_context();
575   VGErrorCode error = VG_NO_ERROR;
576   VGint value = 0;
577
578   switch(type) {
579   case VG_MATRIX_MODE:
580      value = state->matrix_mode;
581      break;
582   case VG_FILL_RULE:
583      value = state->fill_rule;
584      break;
585   case VG_IMAGE_QUALITY:
586      value = state->image_quality;
587      break;
588   case VG_RENDERING_QUALITY:
589      value = state->rendering_quality;
590      break;
591   case VG_BLEND_MODE:
592      value = state->blend_mode;
593      break;
594   case VG_IMAGE_MODE:
595      value = state->image_mode;
596      break;
597#ifdef OPENVG_VERSION_1_1
598   case VG_COLOR_TRANSFORM:
599      value = state->color_transform;
600      break;
601#endif
602   case VG_STROKE_LINE_WIDTH:
603      value = state->stroke.line_width.i;
604      break;
605   case VG_STROKE_CAP_STYLE:
606      value = state->stroke.cap_style;
607      break;
608   case VG_STROKE_JOIN_STYLE:
609      value = state->stroke.join_style;
610      break;
611   case VG_STROKE_MITER_LIMIT:
612      value = state->stroke.miter_limit.i;
613      break;
614   case VG_STROKE_DASH_PHASE:
615      value = state->stroke.dash_phase.i;
616      break;
617   case VG_STROKE_DASH_PHASE_RESET:
618      value = state->stroke.dash_phase_reset;
619      break;
620   case VG_MASKING:
621      value = state->masking;
622      break;
623   case VG_SCISSORING:
624      value = state->scissoring;
625      break;
626   case VG_PIXEL_LAYOUT:
627      value = state->pixel_layout;
628      break;
629   case VG_SCREEN_LAYOUT:
630      value = state->screen_layout;
631      break;
632   case VG_FILTER_FORMAT_LINEAR:
633      value = state->filter_format_linear;
634      break;
635   case VG_FILTER_FORMAT_PREMULTIPLIED:
636      value = state->filter_format_premultiplied;
637      break;
638   case VG_FILTER_CHANNEL_MASK:
639      value = state->filter_channel_mask;
640      break;
641
642   case VG_MAX_SCISSOR_RECTS:
643      value = 32; /*must be at least 32*/
644      break;
645   case VG_MAX_DASH_COUNT:
646      value = 16; /*must be at least 16*/
647      break;
648   case VG_MAX_KERNEL_SIZE:
649      value = 7; /*must be at least 7*/
650      break;
651   case VG_MAX_SEPARABLE_KERNEL_SIZE:
652      value = 15; /*must be at least 15*/
653      break;
654   case VG_MAX_COLOR_RAMP_STOPS:
655      value = 256; /*must be at least 32*/
656      break;
657   case VG_MAX_IMAGE_WIDTH:
658      value = 2048;
659      break;
660   case VG_MAX_IMAGE_HEIGHT:
661      value = 2048;
662      break;
663   case VG_MAX_IMAGE_PIXELS:
664      value = 2048*2048;
665      break;
666   case VG_MAX_IMAGE_BYTES:
667      value = 2048*2048 * 4;
668      break;
669   case VG_MAX_GAUSSIAN_STD_DEVIATION:
670      value = 128; /*must be at least 128*/
671      break;
672
673   case VG_MAX_FLOAT: {
674      VGfloat val = vgGetf(type);
675      value = float_to_int_floor(*((VGuint*)&val));
676   }
677      break;
678   default:
679      error = VG_ILLEGAL_ARGUMENT_ERROR;
680      break;
681   }
682   vg_set_error(ctx, error);
683   return value;
684}
685
686VGint vgGetVectorSize(VGParamType type)
687{
688   struct vg_context *ctx = vg_current_context();
689   const struct vg_state *state = current_state();
690   switch(type) {
691   case VG_MATRIX_MODE:
692   case VG_FILL_RULE:
693   case VG_IMAGE_QUALITY:
694   case VG_RENDERING_QUALITY:
695   case VG_BLEND_MODE:
696   case VG_IMAGE_MODE:
697      return 1;
698   case VG_SCISSOR_RECTS:
699      return state->scissor_rects_num * 4;
700#ifdef OPENVG_VERSION_1_1
701   case VG_COLOR_TRANSFORM:
702      return 1;
703   case VG_COLOR_TRANSFORM_VALUES:
704      return 8;
705#endif
706   case VG_STROKE_LINE_WIDTH:
707   case VG_STROKE_CAP_STYLE:
708   case VG_STROKE_JOIN_STYLE:
709   case VG_STROKE_MITER_LIMIT:
710      return 1;
711   case VG_STROKE_DASH_PATTERN:
712      return state->stroke.dash_pattern_num;
713   case VG_STROKE_DASH_PHASE:
714      return 1;
715   case VG_STROKE_DASH_PHASE_RESET:
716      return 1;
717   case VG_TILE_FILL_COLOR:
718      return 4;
719   case VG_CLEAR_COLOR:
720      return 4;
721#ifdef OPENVG_VERSION_1_1
722   case VG_GLYPH_ORIGIN:
723      return 2;
724#endif
725   case VG_MASKING:
726      return 1;
727   case VG_SCISSORING:
728      return 1;
729   case VG_PIXEL_LAYOUT:
730      return 1;
731   case VG_SCREEN_LAYOUT:
732      return 1;
733   case VG_FILTER_FORMAT_LINEAR:
734      return 1;
735   case VG_FILTER_FORMAT_PREMULTIPLIED:
736      return 1;
737   case VG_FILTER_CHANNEL_MASK:
738      return 1;
739
740   case VG_MAX_COLOR_RAMP_STOPS:
741      return 1;
742   case VG_MAX_SCISSOR_RECTS:
743   case VG_MAX_DASH_COUNT:
744   case VG_MAX_KERNEL_SIZE:
745   case VG_MAX_SEPARABLE_KERNEL_SIZE:
746   case VG_MAX_IMAGE_WIDTH:
747   case VG_MAX_IMAGE_HEIGHT:
748   case VG_MAX_IMAGE_PIXELS:
749   case VG_MAX_IMAGE_BYTES:
750   case VG_MAX_FLOAT:
751   case VG_MAX_GAUSSIAN_STD_DEVIATION:
752      return 1;
753   default:
754      if (ctx)
755         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
756      return 0;
757   }
758}
759
760void vgGetfv(VGParamType type, VGint count,
761             VGfloat * values)
762{
763   const struct vg_state *state = current_state();
764   struct vg_context *ctx = vg_current_context();
765   VGint real_count = vgGetVectorSize(type);
766
767   if (!values || count <= 0 || count > real_count || !is_aligned(values)) {
768      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
769      return;
770   }
771
772   switch(type) {
773   case VG_MATRIX_MODE:
774   case VG_FILL_RULE:
775   case VG_IMAGE_QUALITY:
776   case VG_RENDERING_QUALITY:
777   case VG_BLEND_MODE:
778   case VG_IMAGE_MODE:
779#ifdef OPENVG_VERSION_1_1
780   case VG_COLOR_TRANSFORM:
781#endif
782   case VG_STROKE_CAP_STYLE:
783   case VG_STROKE_JOIN_STYLE:
784   case VG_STROKE_DASH_PHASE_RESET:
785   case VG_MASKING:
786   case VG_SCISSORING:
787   case VG_PIXEL_LAYOUT:
788   case VG_SCREEN_LAYOUT:
789   case VG_FILTER_FORMAT_LINEAR:
790   case VG_FILTER_FORMAT_PREMULTIPLIED:
791   case VG_FILTER_CHANNEL_MASK:
792   case VG_MAX_SCISSOR_RECTS:
793   case VG_MAX_DASH_COUNT:
794   case VG_MAX_KERNEL_SIZE:
795   case VG_MAX_SEPARABLE_KERNEL_SIZE:
796   case VG_MAX_COLOR_RAMP_STOPS:
797   case VG_MAX_IMAGE_WIDTH:
798   case VG_MAX_IMAGE_HEIGHT:
799   case VG_MAX_IMAGE_PIXELS:
800   case VG_MAX_IMAGE_BYTES:
801   case VG_MAX_GAUSSIAN_STD_DEVIATION:
802      values[0] = vgGeti(type);
803      break;
804   case VG_MAX_FLOAT:
805      values[0] = vgGetf(type);
806      break;
807   case VG_SCISSOR_RECTS: {
808      VGint i;
809      for (i = 0; i < count; ++i) {
810         values[i] = state->scissor_rects[i].f;
811      }
812   }
813      break;
814#ifdef OPENVG_VERSION_1_1
815   case VG_COLOR_TRANSFORM_VALUES: {
816      memcpy(values, state->color_transform_values,
817             sizeof(VGfloat) * count);
818   }
819      break;
820#endif
821   case VG_STROKE_LINE_WIDTH:
822      values[0] = state->stroke.line_width.f;
823      break;
824   case VG_STROKE_MITER_LIMIT:
825      values[0] = state->stroke.miter_limit.f;
826      break;
827   case VG_STROKE_DASH_PATTERN: {
828      VGint i;
829      for (i = 0; i < count; ++i) {
830         values[i] = state->stroke.dash_pattern[i].f;
831      }
832   }
833      break;
834   case VG_STROKE_DASH_PHASE:
835      values[0] = state->stroke.dash_phase.f;
836      break;
837   case VG_TILE_FILL_COLOR:
838      values[0] = state->tile_fill_color[0];
839      values[1] = state->tile_fill_color[1];
840      values[2] = state->tile_fill_color[2];
841      values[3] = state->tile_fill_color[3];
842      break;
843   case VG_CLEAR_COLOR:
844      values[0] = state->clear_color[0];
845      values[1] = state->clear_color[1];
846      values[2] = state->clear_color[2];
847      values[3] = state->clear_color[3];
848      break;
849#ifdef OPENVG_VERSION_1_1
850   case VG_GLYPH_ORIGIN:
851      values[0] = state->glyph_origin[0].f;
852      values[1] = state->glyph_origin[1].f;
853      break;
854#endif
855   default:
856      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
857      break;
858   }
859}
860
861void vgGetiv(VGParamType type, VGint count,
862             VGint * values)
863{
864   const struct vg_state *state = current_state();
865   struct vg_context *ctx = vg_current_context();
866   VGint real_count = vgGetVectorSize(type);
867
868   if (!values || count <= 0 || count > real_count || !is_aligned(values)) {
869      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
870      return;
871   }
872
873   switch(type) {
874   case VG_MATRIX_MODE:
875   case VG_FILL_RULE:
876   case VG_IMAGE_QUALITY:
877   case VG_RENDERING_QUALITY:
878   case VG_BLEND_MODE:
879   case VG_IMAGE_MODE:
880#ifdef OPENVG_VERSION_1_1
881   case VG_COLOR_TRANSFORM:
882#endif
883   case VG_STROKE_CAP_STYLE:
884   case VG_STROKE_JOIN_STYLE:
885   case VG_STROKE_DASH_PHASE_RESET:
886   case VG_MASKING:
887   case VG_SCISSORING:
888   case VG_PIXEL_LAYOUT:
889   case VG_SCREEN_LAYOUT:
890   case VG_FILTER_FORMAT_LINEAR:
891   case VG_FILTER_FORMAT_PREMULTIPLIED:
892   case VG_FILTER_CHANNEL_MASK:
893   case VG_MAX_SCISSOR_RECTS:
894   case VG_MAX_DASH_COUNT:
895   case VG_MAX_KERNEL_SIZE:
896   case VG_MAX_SEPARABLE_KERNEL_SIZE:
897   case VG_MAX_COLOR_RAMP_STOPS:
898   case VG_MAX_IMAGE_WIDTH:
899   case VG_MAX_IMAGE_HEIGHT:
900   case VG_MAX_IMAGE_PIXELS:
901   case VG_MAX_IMAGE_BYTES:
902   case VG_MAX_GAUSSIAN_STD_DEVIATION:
903      values[0] = vgGeti(type);
904      break;
905   case VG_MAX_FLOAT: {
906      VGfloat val = vgGetf(type);
907      values[0] = float_to_int_floor(*((VGuint*)&val));
908   }
909      break;
910   case VG_SCISSOR_RECTS: {
911      VGint i;
912      for (i = 0; i < count; ++i) {
913         values[i] = state->scissor_rects[i].i;
914      }
915   }
916      break;
917#ifdef OPENVG_VERSION_1_1
918   case VG_COLOR_TRANSFORM_VALUES: {
919      VGint i;
920      VGuint *x = (VGuint*)state->color_transform_values;
921      for (i = 0; i < count; ++i) {
922         values[i] = float_to_int_floor(x[i]);
923      }
924   }
925      break;
926#endif
927   case VG_STROKE_LINE_WIDTH:
928      values[0] = state->stroke.line_width.i;
929      break;
930   case VG_STROKE_MITER_LIMIT:
931      values[0] = state->stroke.miter_limit.i;
932      break;
933   case VG_STROKE_DASH_PATTERN: {
934      VGint i;
935      for (i = 0; i < count; ++i) {
936         values[i] = state->stroke.dash_pattern[i].i;
937      }
938   }
939      break;
940   case VG_STROKE_DASH_PHASE:
941      values[0] = state->stroke.dash_phase.i;
942      break;
943   case VG_TILE_FILL_COLOR:
944      values[0] = state->tile_fill_colori[0];
945      values[1] = state->tile_fill_colori[1];
946      values[2] = state->tile_fill_colori[2];
947      values[3] = state->tile_fill_colori[3];
948      break;
949   case VG_CLEAR_COLOR:
950      values[0] = state->clear_colori[0];
951      values[1] = state->clear_colori[1];
952      values[2] = state->clear_colori[2];
953      values[3] = state->clear_colori[3];
954      break;
955#ifdef OPENVG_VERSION_1_1
956   case VG_GLYPH_ORIGIN:
957      values[0] = state->glyph_origin[0].i;
958      values[1] = state->glyph_origin[1].i;
959      break;
960#endif
961   default:
962      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
963      break;
964   }
965}
966
967void vgSetParameterf(VGHandle object,
968                     VGint paramType,
969                     VGfloat value)
970{
971   struct vg_context *ctx = vg_current_context();
972   void *ptr = (void*)object;
973
974   if (!object || object == VG_INVALID_HANDLE || !is_aligned(ptr)) {
975      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
976      return;
977   }
978
979   switch(paramType) {
980   case VG_PAINT_TYPE:
981   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
982   case VG_PAINT_PATTERN_TILING_MODE:
983      vgSetParameteri(object, paramType, floor(value));
984      return;
985      break;
986   case VG_PAINT_COLOR:
987   case VG_PAINT_COLOR_RAMP_STOPS:
988   case VG_PAINT_LINEAR_GRADIENT:
989   case VG_PAINT_RADIAL_GRADIENT:
990      /* it's an error if paramType refers to a vector parameter */
991      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
992      break;
993   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
994      struct vg_paint *p = (struct vg_paint *)object;
995      paint_set_color_ramp_premultiplied(p, value);
996   }
997      break;
998
999   case VG_PATH_DATATYPE:
1000   case VG_PATH_FORMAT:
1001   case VG_PATH_SCALE:
1002   case VG_PATH_BIAS:
1003   case VG_PATH_NUM_SEGMENTS:
1004   case VG_PATH_NUM_COORDS:
1005
1006   case VG_IMAGE_FORMAT:
1007   case VG_IMAGE_WIDTH:
1008   case VG_IMAGE_HEIGHT:
1009
1010#ifdef OPENVG_VERSION_1_1
1011   case VG_FONT_NUM_GLYPHS:
1012      /* read only don't produce an error */
1013      break;
1014#endif
1015   default:
1016      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1017      break;
1018   }
1019}
1020
1021void vgSetParameteri(VGHandle object,
1022                     VGint paramType,
1023                     VGint value)
1024{
1025   struct vg_context *ctx = vg_current_context();
1026   void *ptr = (void*)object;
1027
1028   if (!object || object == VG_INVALID_HANDLE || !is_aligned(ptr)) {
1029      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1030      return;
1031   }
1032
1033   switch(paramType) {
1034   case VG_PAINT_TYPE:
1035      if (value < VG_PAINT_TYPE_COLOR ||
1036          value > VG_PAINT_TYPE_PATTERN)
1037         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1038      else {
1039         struct vg_paint *paint = (struct vg_paint *)ptr;
1040         paint_set_type(paint, value);
1041      }
1042      break;
1043   case VG_PAINT_COLOR:
1044   case VG_PAINT_COLOR_RAMP_STOPS:
1045   case VG_PAINT_LINEAR_GRADIENT:
1046   case VG_PAINT_RADIAL_GRADIENT:
1047      /* it's an error if paramType refers to a vector parameter */
1048      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1049      break;
1050   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1051      if (value < VG_COLOR_RAMP_SPREAD_PAD ||
1052          value > VG_COLOR_RAMP_SPREAD_REFLECT)
1053         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1054      else {
1055         struct vg_paint *paint = (struct vg_paint *)ptr;
1056         paint_set_spread_mode(paint, value);
1057      }
1058      break;
1059   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
1060      struct vg_paint *p = (struct vg_paint *)object;
1061      paint_set_color_ramp_premultiplied(p, value);
1062   }
1063      break;
1064   case VG_PAINT_PATTERN_TILING_MODE:
1065      if (value < VG_TILE_FILL ||
1066          value > VG_TILE_REFLECT)
1067         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1068      else {
1069         struct vg_paint *paint = (struct vg_paint *)ptr;
1070         paint_set_pattern_tiling(paint, value);
1071      }
1072      break;
1073
1074   case VG_PATH_DATATYPE:
1075   case VG_PATH_FORMAT:
1076   case VG_PATH_SCALE:
1077   case VG_PATH_BIAS:
1078   case VG_PATH_NUM_SEGMENTS:
1079   case VG_PATH_NUM_COORDS:
1080
1081   case VG_IMAGE_FORMAT:
1082   case VG_IMAGE_WIDTH:
1083   case VG_IMAGE_HEIGHT:
1084
1085#ifdef OPENVG_VERSION_1_1
1086   case VG_FONT_NUM_GLYPHS:
1087      /* read only don't produce an error */
1088      break;
1089#endif
1090   default:
1091      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1092      return;
1093   }
1094}
1095
1096void vgSetParameterfv(VGHandle object,
1097                      VGint paramType,
1098                      VGint count,
1099                      const VGfloat * values)
1100{
1101   struct vg_context *ctx = vg_current_context();
1102   void *ptr = (void*)object;
1103   VGint real_count = vgGetParameterVectorSize(object, paramType);
1104
1105   if (!object || object == VG_INVALID_HANDLE || !is_aligned(ptr)) {
1106      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1107      return;
1108   }
1109
1110   if (count < 0 || count < real_count ||
1111       (values == NULL && count != 0) ||
1112       !is_aligned(values)) {
1113      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1114      return;
1115   }
1116
1117   switch(paramType) {
1118   case VG_PAINT_TYPE:
1119   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1120   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1121   case VG_PAINT_PATTERN_TILING_MODE:
1122      if (count != 1)
1123         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1124      else
1125         vgSetParameterf(object, paramType, values[0]);
1126      return;
1127      break;
1128   case VG_PAINT_COLOR: {
1129      if (count != 4)
1130         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1131      else {
1132         struct vg_paint *paint = (struct vg_paint *)object;
1133         paint_set_color(paint, values);
1134      }
1135   }
1136      break;
1137   case VG_PAINT_COLOR_RAMP_STOPS: {
1138      if (count && count < 4)
1139         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1140      else {
1141         struct vg_paint *paint = (struct vg_paint *)object;
1142         count = MIN2(count, VEGA_MAX_COLOR_RAMP_STOPS);
1143         paint_set_ramp_stops(paint, values, count);
1144         {
1145            VGint stopsi[VEGA_MAX_COLOR_RAMP_STOPS];
1146            int i = 0;
1147            for (i = 0; i < count; ++i) {
1148               stopsi[i] = float_to_int_floor(*((VGuint*)(values + i)));
1149            }
1150            paint_set_ramp_stopsi(paint, stopsi, count);
1151         }
1152      }
1153   }
1154      break;
1155   case VG_PAINT_LINEAR_GRADIENT: {
1156      if (count != 4)
1157         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1158      else {
1159         struct vg_paint *paint = (struct vg_paint *)object;
1160         paint_set_linear_gradient(paint, values);
1161         {
1162            VGint vals[4];
1163            vals[0] = FLT_TO_INT(values[0]);
1164            vals[1] = FLT_TO_INT(values[1]);
1165            vals[2] = FLT_TO_INT(values[2]);
1166            vals[3] = FLT_TO_INT(values[3]);
1167            paint_set_linear_gradienti(paint, vals);
1168         }
1169      }
1170   }
1171      break;
1172   case VG_PAINT_RADIAL_GRADIENT: {
1173      if (count != 5)
1174         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1175      else {
1176         struct vg_paint *paint = (struct vg_paint *)object;
1177         paint_set_radial_gradient(paint, values);
1178         {
1179            VGint vals[5];
1180            vals[0] = FLT_TO_INT(values[0]);
1181            vals[1] = FLT_TO_INT(values[1]);
1182            vals[2] = FLT_TO_INT(values[2]);
1183            vals[3] = FLT_TO_INT(values[3]);
1184            vals[4] = FLT_TO_INT(values[4]);
1185            paint_set_radial_gradienti(paint, vals);
1186         }
1187      }
1188   }
1189      break;
1190
1191   case VG_PATH_DATATYPE:
1192   case VG_PATH_FORMAT:
1193   case VG_PATH_SCALE:
1194   case VG_PATH_BIAS:
1195   case VG_PATH_NUM_SEGMENTS:
1196   case VG_PATH_NUM_COORDS:
1197
1198#ifdef OPENVG_VERSION_1_1
1199   case VG_FONT_NUM_GLYPHS:
1200      /* read only don't produce an error */
1201      break;
1202#endif
1203   default:
1204      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1205      return;
1206   }
1207}
1208
1209void vgSetParameteriv(VGHandle object,
1210                      VGint paramType,
1211                      VGint count,
1212                      const VGint * values)
1213{
1214   struct vg_context *ctx = vg_current_context();
1215   void *ptr = (void*)object;
1216   VGint real_count = vgGetParameterVectorSize(object, paramType);
1217
1218   if (!object || object == VG_INVALID_HANDLE || !is_aligned(ptr)) {
1219      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1220      return;
1221   }
1222
1223   if (count < 0 || count < real_count ||
1224       (values == NULL && count != 0) ||
1225       !is_aligned(values)) {
1226      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1227      return;
1228   }
1229
1230   switch(paramType) {
1231   case VG_PAINT_TYPE:
1232   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1233   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1234   case VG_PAINT_PATTERN_TILING_MODE:
1235      if (count != 1)
1236         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1237      else
1238         vgSetParameteri(object, paramType, values[0]);
1239      return;
1240      break;
1241   case VG_PAINT_COLOR: {
1242      if (count != 4)
1243         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1244      else {
1245         struct vg_paint *paint = (struct vg_paint *)object;
1246         paint_set_coloriv(paint, values);
1247      }
1248   }
1249      break;
1250   case VG_PAINT_COLOR_RAMP_STOPS: {
1251      if ((count % 5))
1252         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1253      else {
1254         VGfloat *vals = 0;
1255         int i;
1256         struct vg_paint *paint = (struct vg_paint *)object;
1257         if (count) {
1258            vals = malloc(sizeof(VGfloat)*count);
1259            for (i = 0; i < count; ++i)
1260               vals[i] = values[i];
1261         }
1262
1263         paint_set_ramp_stopsi(paint, values, count);
1264         paint_set_ramp_stops(paint, vals, count);
1265         free(vals);
1266      }
1267   }
1268      break;
1269   case VG_PAINT_LINEAR_GRADIENT: {
1270      if (count != 4)
1271         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1272      else {
1273         VGfloat vals[4];
1274         struct vg_paint *paint = (struct vg_paint *)object;
1275         vals[0] = values[0];
1276         vals[1] = values[1];
1277         vals[2] = values[2];
1278         vals[3] = values[3];
1279         paint_set_linear_gradient(paint, vals);
1280         paint_set_linear_gradienti(paint, values);
1281      }
1282   }
1283      break;
1284   case VG_PAINT_RADIAL_GRADIENT: {
1285      if (count != 5)
1286         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1287      else {
1288         VGfloat vals[5];
1289         struct vg_paint *paint = (struct vg_paint *)object;
1290         vals[0] = values[0];
1291         vals[1] = values[1];
1292         vals[2] = values[2];
1293         vals[3] = values[3];
1294         vals[4] = values[4];
1295         paint_set_radial_gradient(paint, vals);
1296         paint_set_radial_gradienti(paint, values);
1297      }
1298   }
1299      break;
1300   case VG_PATH_DATATYPE:
1301   case VG_PATH_FORMAT:
1302   case VG_PATH_SCALE:
1303   case VG_PATH_BIAS:
1304   case VG_PATH_NUM_SEGMENTS:
1305   case VG_PATH_NUM_COORDS:
1306      /* read only don't produce an error */
1307      break;
1308   default:
1309      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1310      return;
1311   }
1312}
1313
1314VGint vgGetParameterVectorSize(VGHandle object,
1315                               VGint paramType)
1316{
1317   struct vg_context *ctx = vg_current_context();
1318   void *ptr = (void*)object;
1319
1320   if (!ptr || object == VG_INVALID_HANDLE) {
1321      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1322      return 0;
1323   }
1324
1325   switch(paramType) {
1326   case VG_PAINT_TYPE:
1327   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1328   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1329   case VG_PAINT_PATTERN_TILING_MODE:
1330      return 1;
1331   case VG_PAINT_COLOR:
1332      return 4;
1333   case VG_PAINT_COLOR_RAMP_STOPS: {
1334      struct vg_paint *p = (struct vg_paint *)object;
1335      return paint_num_ramp_stops(p);
1336   }
1337      break;
1338   case VG_PAINT_LINEAR_GRADIENT:
1339      return 4;
1340   case VG_PAINT_RADIAL_GRADIENT:
1341      return 5;
1342
1343
1344   case VG_PATH_FORMAT:
1345   case VG_PATH_DATATYPE:
1346   case VG_PATH_SCALE:
1347   case VG_PATH_BIAS:
1348   case VG_PATH_NUM_SEGMENTS:
1349   case VG_PATH_NUM_COORDS:
1350      return 1;
1351
1352   case VG_IMAGE_FORMAT:
1353   case VG_IMAGE_WIDTH:
1354   case VG_IMAGE_HEIGHT:
1355      return 1;
1356
1357#ifdef OPENVG_VERSION_1_1
1358   case VG_FONT_NUM_GLYPHS:
1359      return 1;
1360#endif
1361
1362   default:
1363      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1364      break;
1365   }
1366   return 0;
1367}
1368
1369
1370VGfloat vgGetParameterf(VGHandle object,
1371                        VGint paramType)
1372{
1373   struct vg_context *ctx = vg_current_context();
1374   void *ptr = (void*)object;
1375
1376   if (!ptr || object == VG_INVALID_HANDLE) {
1377      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1378      return 0;
1379   }
1380
1381   switch(paramType) {
1382   case VG_PAINT_TYPE:
1383   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1384   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1385   case VG_PAINT_PATTERN_TILING_MODE:
1386      return vgGetParameteri(object, paramType);
1387      break;
1388   case VG_PAINT_COLOR:
1389   case VG_PAINT_COLOR_RAMP_STOPS:
1390   case VG_PAINT_LINEAR_GRADIENT:
1391   case VG_PAINT_RADIAL_GRADIENT:
1392      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1393      break;
1394
1395   case VG_PATH_FORMAT:
1396      return VG_PATH_FORMAT_STANDARD;
1397   case VG_PATH_SCALE: {
1398      struct path *p = (struct path*)object;
1399      return path_scale(p);
1400   }
1401   case VG_PATH_BIAS: {
1402      struct path *p = (struct path*)object;
1403      return path_bias(p);
1404   }
1405   case VG_PATH_DATATYPE:
1406   case VG_PATH_NUM_SEGMENTS:
1407   case VG_PATH_NUM_COORDS:
1408      return vgGetParameteri(object, paramType);
1409      break;
1410
1411   case VG_IMAGE_FORMAT:
1412   case VG_IMAGE_WIDTH:
1413   case VG_IMAGE_HEIGHT:
1414#ifdef OPENVG_VERSION_1_1
1415   case VG_FONT_NUM_GLYPHS:
1416      return vgGetParameteri(object, paramType);
1417      break;
1418#endif
1419
1420   default:
1421      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1422      break;
1423   }
1424   return 0;
1425}
1426
1427VGint vgGetParameteri(VGHandle object,
1428                      VGint paramType)
1429{
1430   struct vg_context *ctx = vg_current_context();
1431   void *ptr = (void*)object;
1432
1433   if (!ptr || object == VG_INVALID_HANDLE) {
1434      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1435      return 0;
1436   }
1437
1438   switch(paramType) {
1439   case VG_PAINT_TYPE: {
1440         struct vg_paint *paint = (struct vg_paint *)ptr;
1441         return paint_type(paint);
1442   }
1443      break;
1444   case VG_PAINT_COLOR_RAMP_SPREAD_MODE: {
1445      struct vg_paint *p = (struct vg_paint *)object;
1446      return paint_spread_mode(p);
1447   }
1448   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
1449      struct vg_paint *p = (struct vg_paint *)object;
1450      return paint_color_ramp_premultiplied(p);
1451   }
1452      break;
1453   case VG_PAINT_PATTERN_TILING_MODE: {
1454      struct vg_paint *p = (struct vg_paint *)object;
1455      return paint_pattern_tiling(p);
1456   }
1457      break;
1458   case VG_PAINT_COLOR:
1459   case VG_PAINT_COLOR_RAMP_STOPS:
1460   case VG_PAINT_LINEAR_GRADIENT:
1461   case VG_PAINT_RADIAL_GRADIENT:
1462      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1463      break;
1464
1465   case VG_PATH_FORMAT:
1466      return VG_PATH_FORMAT_STANDARD;
1467   case VG_PATH_SCALE:
1468   case VG_PATH_BIAS:
1469      return vgGetParameterf(object, paramType);
1470   case VG_PATH_DATATYPE: {
1471      struct path *p = (struct path*)object;
1472      return path_datatype(p);
1473   }
1474   case VG_PATH_NUM_SEGMENTS: {
1475      struct path *p = (struct path*)object;
1476      return path_num_segments(p);
1477   }
1478   case VG_PATH_NUM_COORDS: {
1479      struct path *p = (struct path*)object;
1480      return path_num_coords(p);
1481   }
1482      break;
1483
1484   case VG_IMAGE_FORMAT: {
1485      struct vg_image *img = (struct vg_image*)object;
1486      return img->format;
1487   }
1488      break;
1489   case VG_IMAGE_WIDTH: {
1490      struct vg_image *img = (struct vg_image*)object;
1491      return img->width;
1492   }
1493      break;
1494   case VG_IMAGE_HEIGHT: {
1495      struct vg_image *img = (struct vg_image*)object;
1496      return img->height;
1497   }
1498      break;
1499
1500#ifdef OPENVG_VERSION_1_1
1501   case VG_FONT_NUM_GLYPHS: {
1502      return 1;
1503   }
1504      break;
1505#endif
1506
1507   default:
1508      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1509      break;
1510   }
1511   return 0;
1512}
1513
1514void vgGetParameterfv(VGHandle object,
1515                      VGint paramType,
1516                      VGint count,
1517                      VGfloat * values)
1518{
1519   struct vg_context *ctx = vg_current_context();
1520   void *ptr = (void*)object;
1521   VGint real_count = vgGetParameterVectorSize(object, paramType);
1522
1523   if (!ptr || object == VG_INVALID_HANDLE) {
1524      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1525      return;
1526   }
1527
1528   if (!values || count <= 0 || count > real_count ||
1529       !is_aligned(values)) {
1530      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1531      return;
1532   }
1533
1534   switch(paramType) {
1535   case VG_PAINT_TYPE: {
1536      struct vg_paint *p = (struct vg_paint *)object;
1537      values[0] = paint_type(p);
1538   }
1539      break;
1540   case VG_PAINT_COLOR_RAMP_SPREAD_MODE: {
1541      struct vg_paint *p = (struct vg_paint *)object;
1542      values[0] = paint_spread_mode(p);
1543   }
1544      break;
1545   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
1546      struct vg_paint *p = (struct vg_paint *)object;
1547      values[0] = paint_color_ramp_premultiplied(p);
1548   }
1549      break;
1550   case VG_PAINT_PATTERN_TILING_MODE: {
1551      values[0] = vgGetParameterf(object, paramType);
1552   }
1553      break;
1554   case VG_PAINT_COLOR: {
1555      struct vg_paint *paint = (struct vg_paint *)object;
1556      paint_get_color(paint, values);
1557   }
1558      break;
1559   case VG_PAINT_COLOR_RAMP_STOPS: {
1560      struct vg_paint *paint = (struct vg_paint *)object;
1561      paint_ramp_stops(paint, values, count);
1562   }
1563      break;
1564   case VG_PAINT_LINEAR_GRADIENT: {
1565      struct vg_paint *paint = (struct vg_paint *)object;
1566      paint_linear_gradient(paint, values);
1567   }
1568      break;
1569   case VG_PAINT_RADIAL_GRADIENT: {
1570      struct vg_paint *paint = (struct vg_paint *)object;
1571      paint_radial_gradient(paint, values);
1572   }
1573      break;
1574
1575   case VG_PATH_FORMAT:
1576   case VG_PATH_DATATYPE:
1577   case VG_PATH_NUM_SEGMENTS:
1578   case VG_PATH_NUM_COORDS:
1579      values[0] = vgGetParameteri(object, paramType);
1580      break;
1581   case VG_PATH_SCALE:
1582   case VG_PATH_BIAS:
1583      values[0] = vgGetParameterf(object, paramType);
1584      break;
1585
1586   case VG_IMAGE_FORMAT:
1587   case VG_IMAGE_WIDTH:
1588   case VG_IMAGE_HEIGHT:
1589#ifdef OPENVG_VERSION_1_1
1590   case VG_FONT_NUM_GLYPHS:
1591      values[0] = vgGetParameteri(object, paramType);
1592      break;
1593#endif
1594
1595   default:
1596      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1597      break;
1598   }
1599}
1600
1601void vgGetParameteriv(VGHandle object,
1602                      VGint paramType,
1603                      VGint count,
1604                      VGint * values)
1605{
1606   struct vg_context *ctx = vg_current_context();
1607   void *ptr = (void*)object;
1608   VGint real_count = vgGetParameterVectorSize(object, paramType);
1609
1610   if (!ptr || object == VG_INVALID_HANDLE) {
1611      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1612      return;
1613   }
1614
1615   if (!values || count <= 0 || count > real_count ||
1616       !is_aligned(values)) {
1617      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1618      return;
1619   }
1620
1621   switch(paramType) {
1622   case VG_PAINT_TYPE:
1623   case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1624   case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1625   case VG_PAINT_PATTERN_TILING_MODE:
1626#ifdef OPENVG_VERSION_1_1
1627   case VG_FONT_NUM_GLYPHS:
1628      values[0] = vgGetParameteri(object, paramType);
1629      break;
1630#endif
1631   case VG_PAINT_COLOR: {
1632      struct vg_paint *paint = (struct vg_paint *)object;
1633      paint_get_coloriv(paint, values);
1634   }
1635      break;
1636   case VG_PAINT_COLOR_RAMP_STOPS: {
1637      struct vg_paint *paint = (struct vg_paint *)object;
1638      paint_ramp_stopsi(paint, values, count);
1639   }
1640      break;
1641   case VG_PAINT_LINEAR_GRADIENT: {
1642      struct vg_paint *paint = (struct vg_paint *)object;
1643      paint_linear_gradienti(paint, values);
1644   }
1645      break;
1646   case VG_PAINT_RADIAL_GRADIENT: {
1647      struct vg_paint *paint = (struct vg_paint *)object;
1648      paint_radial_gradienti(paint, values);
1649   }
1650      break;
1651
1652   case VG_PATH_SCALE:
1653   case VG_PATH_BIAS:
1654      values[0] = vgGetParameterf(object, paramType);
1655      break;
1656   case VG_PATH_FORMAT:
1657   case VG_PATH_DATATYPE:
1658   case VG_PATH_NUM_SEGMENTS:
1659   case VG_PATH_NUM_COORDS:
1660      values[0] = vgGetParameteri(object, paramType);
1661      break;
1662
1663   case VG_IMAGE_FORMAT:
1664   case VG_IMAGE_WIDTH:
1665   case VG_IMAGE_HEIGHT:
1666      values[0] = vgGetParameteri(object, paramType);
1667      break;
1668
1669   default:
1670      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1671      break;
1672   }
1673}
1674