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