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