Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / state_trackers / vega / api_params.c
1 /**************************************************************************
2  *
3  * Copyright 2009 VMware, Inc.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 #include "VG/openvg.h"
28
29 #include "vg_context.h"
30 #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
45 static 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
54 static 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
69 void 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
129 void 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
261 void 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
389 void 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
513 VGfloat 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
575 VGint 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
690 VGint 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
764 void 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
865 void 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
971 void 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
1025 void 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
1100 void 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          if (ctx->state.vg.fill_paint == paint ||
1139              ctx->state.vg.stroke_paint == paint)
1140             ctx->state.dirty |= PAINT_DIRTY;
1141       }
1142    }
1143       break;
1144    case VG_PAINT_COLOR_RAMP_STOPS: {
1145       if (count && count < 4)
1146          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1147       else {
1148          struct vg_paint *paint = handle_to_paint(object);
1149          count = MIN2(count, VEGA_MAX_COLOR_RAMP_STOPS);
1150          paint_set_ramp_stops(paint, values, count);
1151          {
1152             VGint stopsi[VEGA_MAX_COLOR_RAMP_STOPS];
1153             int i = 0;
1154             for (i = 0; i < count; ++i) {
1155                stopsi[i] = float_to_int_floor(*((VGuint*)(values + i)));
1156             }
1157             paint_set_ramp_stopsi(paint, stopsi, count);
1158          }
1159       }
1160    }
1161       break;
1162    case VG_PAINT_LINEAR_GRADIENT: {
1163       if (count != 4)
1164          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1165       else {
1166          struct vg_paint *paint = handle_to_paint(object);
1167          paint_set_linear_gradient(paint, values);
1168          {
1169             VGint vals[4];
1170             vals[0] = FLT_TO_INT(values[0]);
1171             vals[1] = FLT_TO_INT(values[1]);
1172             vals[2] = FLT_TO_INT(values[2]);
1173             vals[3] = FLT_TO_INT(values[3]);
1174             paint_set_linear_gradienti(paint, vals);
1175          }
1176       }
1177    }
1178       break;
1179    case VG_PAINT_RADIAL_GRADIENT: {
1180       if (count != 5)
1181          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1182       else {
1183          struct vg_paint *paint = handle_to_paint(object);
1184          paint_set_radial_gradient(paint, values);
1185          {
1186             VGint vals[5];
1187             vals[0] = FLT_TO_INT(values[0]);
1188             vals[1] = FLT_TO_INT(values[1]);
1189             vals[2] = FLT_TO_INT(values[2]);
1190             vals[3] = FLT_TO_INT(values[3]);
1191             vals[4] = FLT_TO_INT(values[4]);
1192             paint_set_radial_gradienti(paint, vals);
1193          }
1194       }
1195    }
1196       break;
1197
1198    case VG_PATH_DATATYPE:
1199    case VG_PATH_FORMAT:
1200    case VG_PATH_SCALE:
1201    case VG_PATH_BIAS:
1202    case VG_PATH_NUM_SEGMENTS:
1203    case VG_PATH_NUM_COORDS:
1204
1205 #ifdef OPENVG_VERSION_1_1
1206    case VG_FONT_NUM_GLYPHS:
1207       /* read only don't produce an error */
1208       break;
1209 #endif
1210    default:
1211       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1212       return;
1213    }
1214 }
1215
1216 void vegaSetParameteriv(VGHandle object,
1217                         VGint paramType,
1218                         VGint count,
1219                         const VGint * values)
1220 {
1221    struct vg_context *ctx = vg_current_context();
1222    void *ptr = handle_to_pointer(object);
1223    VGint real_count = vegaGetParameterVectorSize(object, paramType);
1224
1225    if (object == VG_INVALID_HANDLE || !is_aligned(ptr)) {
1226       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1227       return;
1228    }
1229
1230    if (count < 0 || count < real_count ||
1231        (values == NULL && count != 0) ||
1232        !is_aligned(values)) {
1233       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1234       return;
1235    }
1236
1237    switch(paramType) {
1238    case VG_PAINT_TYPE:
1239    case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1240    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1241    case VG_PAINT_PATTERN_TILING_MODE:
1242       if (count != 1)
1243          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1244       else
1245          vegaSetParameteri(object, paramType, values[0]);
1246       return;
1247       break;
1248    case VG_PAINT_COLOR: {
1249       if (count != 4)
1250          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1251       else {
1252          struct vg_paint *paint = handle_to_paint(object);
1253          paint_set_coloriv(paint, values);
1254          if (ctx->state.vg.fill_paint == paint ||
1255              ctx->state.vg.stroke_paint == paint)
1256             ctx->state.dirty |= PAINT_DIRTY;
1257       }
1258    }
1259       break;
1260    case VG_PAINT_COLOR_RAMP_STOPS: {
1261       if ((count % 5))
1262          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1263       else {
1264          VGfloat *vals = 0;
1265          int i;
1266          struct vg_paint *paint = handle_to_paint(object);
1267          if (count) {
1268             vals = malloc(sizeof(VGfloat)*count);
1269             for (i = 0; i < count; ++i)
1270                vals[i] = values[i];
1271          }
1272
1273          paint_set_ramp_stopsi(paint, values, count);
1274          paint_set_ramp_stops(paint, vals, count);
1275          free(vals);
1276       }
1277    }
1278       break;
1279    case VG_PAINT_LINEAR_GRADIENT: {
1280       if (count != 4)
1281          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1282       else {
1283          VGfloat vals[4];
1284          struct vg_paint *paint = handle_to_paint(object);
1285          vals[0] = values[0];
1286          vals[1] = values[1];
1287          vals[2] = values[2];
1288          vals[3] = values[3];
1289          paint_set_linear_gradient(paint, vals);
1290          paint_set_linear_gradienti(paint, values);
1291       }
1292    }
1293       break;
1294    case VG_PAINT_RADIAL_GRADIENT: {
1295       if (count != 5)
1296          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1297       else {
1298          VGfloat vals[5];
1299          struct vg_paint *paint = handle_to_paint(object);
1300          vals[0] = values[0];
1301          vals[1] = values[1];
1302          vals[2] = values[2];
1303          vals[3] = values[3];
1304          vals[4] = values[4];
1305          paint_set_radial_gradient(paint, vals);
1306          paint_set_radial_gradienti(paint, values);
1307       }
1308    }
1309       break;
1310    case VG_PATH_DATATYPE:
1311    case VG_PATH_FORMAT:
1312    case VG_PATH_SCALE:
1313    case VG_PATH_BIAS:
1314    case VG_PATH_NUM_SEGMENTS:
1315    case VG_PATH_NUM_COORDS:
1316       /* read only don't produce an error */
1317       break;
1318    default:
1319       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1320       return;
1321    }
1322 }
1323
1324 VGint vegaGetParameterVectorSize(VGHandle object,
1325                                  VGint paramType)
1326 {
1327    struct vg_context *ctx = vg_current_context();
1328
1329    if (object == VG_INVALID_HANDLE) {
1330       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1331       return 0;
1332    }
1333
1334    switch(paramType) {
1335    case VG_PAINT_TYPE:
1336    case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1337    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1338    case VG_PAINT_PATTERN_TILING_MODE:
1339       return 1;
1340    case VG_PAINT_COLOR:
1341       return 4;
1342    case VG_PAINT_COLOR_RAMP_STOPS: {
1343       struct vg_paint *p = handle_to_paint(object);
1344       return paint_num_ramp_stops(p);
1345    }
1346       break;
1347    case VG_PAINT_LINEAR_GRADIENT:
1348       return 4;
1349    case VG_PAINT_RADIAL_GRADIENT:
1350       return 5;
1351
1352
1353    case VG_PATH_FORMAT:
1354    case VG_PATH_DATATYPE:
1355    case VG_PATH_SCALE:
1356    case VG_PATH_BIAS:
1357    case VG_PATH_NUM_SEGMENTS:
1358    case VG_PATH_NUM_COORDS:
1359       return 1;
1360
1361    case VG_IMAGE_FORMAT:
1362    case VG_IMAGE_WIDTH:
1363    case VG_IMAGE_HEIGHT:
1364       return 1;
1365
1366 #ifdef OPENVG_VERSION_1_1
1367    case VG_FONT_NUM_GLYPHS:
1368       return 1;
1369 #endif
1370
1371    default:
1372       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1373       break;
1374    }
1375    return 0;
1376 }
1377
1378
1379 VGfloat vegaGetParameterf(VGHandle object,
1380                           VGint paramType)
1381 {
1382    struct vg_context *ctx = vg_current_context();
1383
1384    if (object == VG_INVALID_HANDLE) {
1385       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1386       return 0;
1387    }
1388
1389    switch(paramType) {
1390    case VG_PAINT_TYPE:
1391    case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1392    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1393    case VG_PAINT_PATTERN_TILING_MODE:
1394       return vegaGetParameteri(object, paramType);
1395       break;
1396    case VG_PAINT_COLOR:
1397    case VG_PAINT_COLOR_RAMP_STOPS:
1398    case VG_PAINT_LINEAR_GRADIENT:
1399    case VG_PAINT_RADIAL_GRADIENT:
1400       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1401       break;
1402
1403    case VG_PATH_FORMAT:
1404       return VG_PATH_FORMAT_STANDARD;
1405    case VG_PATH_SCALE: {
1406       struct path *p = handle_to_path(object);
1407       return path_scale(p);
1408    }
1409    case VG_PATH_BIAS: {
1410       struct path *p = handle_to_path(object);
1411       return path_bias(p);
1412    }
1413    case VG_PATH_DATATYPE:
1414    case VG_PATH_NUM_SEGMENTS:
1415    case VG_PATH_NUM_COORDS:
1416       return vegaGetParameteri(object, paramType);
1417       break;
1418
1419    case VG_IMAGE_FORMAT:
1420    case VG_IMAGE_WIDTH:
1421    case VG_IMAGE_HEIGHT:
1422 #ifdef OPENVG_VERSION_1_1
1423    case VG_FONT_NUM_GLYPHS: 
1424       return vegaGetParameteri(object, paramType);
1425       break;
1426 #endif
1427
1428    default:
1429       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1430       break;
1431    }
1432    return 0;
1433 }
1434
1435 VGint vegaGetParameteri(VGHandle object,
1436                         VGint paramType)
1437 {
1438    struct vg_context *ctx = vg_current_context();
1439
1440    if (object == VG_INVALID_HANDLE) {
1441       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1442       return 0;
1443    }
1444
1445    switch(paramType) {
1446    case VG_PAINT_TYPE: {
1447          struct vg_paint *paint = handle_to_paint(object);
1448          return paint_type(paint);
1449    }
1450       break;
1451    case VG_PAINT_COLOR_RAMP_SPREAD_MODE: {
1452       struct vg_paint *p = handle_to_paint(object);
1453       return paint_spread_mode(p);
1454    }
1455    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
1456       struct vg_paint *p = handle_to_paint(object);
1457       return paint_color_ramp_premultiplied(p);
1458    }
1459       break;
1460    case VG_PAINT_PATTERN_TILING_MODE: {
1461       struct vg_paint *p = handle_to_paint(object);
1462       return paint_pattern_tiling(p);
1463    }
1464       break;
1465    case VG_PAINT_COLOR:
1466    case VG_PAINT_COLOR_RAMP_STOPS:
1467    case VG_PAINT_LINEAR_GRADIENT:
1468    case VG_PAINT_RADIAL_GRADIENT:
1469       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1470       break;
1471
1472    case VG_PATH_FORMAT:
1473       return VG_PATH_FORMAT_STANDARD;
1474    case VG_PATH_SCALE:
1475    case VG_PATH_BIAS:
1476       return vegaGetParameterf(object, paramType);
1477    case VG_PATH_DATATYPE: {
1478       struct path *p = handle_to_path(object);
1479       return path_datatype(p);
1480    }
1481    case VG_PATH_NUM_SEGMENTS: {
1482       struct path *p = handle_to_path(object);
1483       return path_num_segments(p);
1484    }
1485    case VG_PATH_NUM_COORDS: {
1486       struct path *p = handle_to_path(object);
1487       return path_num_coords(p);
1488    }
1489       break;
1490
1491    case VG_IMAGE_FORMAT: {
1492       struct vg_image *img = handle_to_image(object);
1493       return img->format;
1494    }
1495       break;
1496    case VG_IMAGE_WIDTH: {
1497       struct vg_image *img = handle_to_image(object);
1498       return img->width;
1499    }
1500       break;
1501    case VG_IMAGE_HEIGHT: {
1502       struct vg_image *img = handle_to_image(object);
1503       return img->height;
1504    }
1505       break;
1506
1507 #ifdef OPENVG_VERSION_1_1
1508    case VG_FONT_NUM_GLYPHS: {
1509       struct vg_font *font = handle_to_font(object);
1510       return font_num_glyphs(font);
1511    }
1512       break;
1513 #endif
1514
1515    default:
1516       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1517       break;
1518    }
1519    return 0;
1520 }
1521
1522 void vegaGetParameterfv(VGHandle object,
1523                         VGint paramType,
1524                         VGint count,
1525                         VGfloat * values)
1526 {
1527    struct vg_context *ctx = vg_current_context();
1528    VGint real_count = vegaGetParameterVectorSize(object, paramType);
1529
1530    if (object == VG_INVALID_HANDLE) {
1531       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1532       return;
1533    }
1534
1535    if (!values || count <= 0 || count > real_count ||
1536        !is_aligned(values)) {
1537       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1538       return;
1539    }
1540
1541    switch(paramType) {
1542    case VG_PAINT_TYPE: {
1543       struct vg_paint *p = handle_to_paint(object);
1544       values[0] = paint_type(p);
1545    }
1546       break;
1547    case VG_PAINT_COLOR_RAMP_SPREAD_MODE: {
1548       struct vg_paint *p = handle_to_paint(object);
1549       values[0] = paint_spread_mode(p);
1550    }
1551       break;
1552    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: {
1553       struct vg_paint *p = handle_to_paint(object);
1554       values[0] = paint_color_ramp_premultiplied(p);
1555    }
1556       break;
1557    case VG_PAINT_PATTERN_TILING_MODE: {
1558       values[0] = vegaGetParameterf(object, paramType);
1559    }
1560       break;
1561    case VG_PAINT_COLOR: {
1562       struct vg_paint *paint = handle_to_paint(object);
1563       paint_get_color(paint, values);
1564    }
1565       break;
1566    case VG_PAINT_COLOR_RAMP_STOPS: {
1567       struct vg_paint *paint = handle_to_paint(object);
1568       paint_ramp_stops(paint, values, count);
1569    }
1570       break;
1571    case VG_PAINT_LINEAR_GRADIENT: {
1572       struct vg_paint *paint = handle_to_paint(object);
1573       paint_linear_gradient(paint, values);
1574    }
1575       break;
1576    case VG_PAINT_RADIAL_GRADIENT: {
1577       struct vg_paint *paint = handle_to_paint(object);
1578       paint_radial_gradient(paint, values);
1579    }
1580       break;
1581
1582    case VG_PATH_FORMAT:
1583    case VG_PATH_DATATYPE:
1584    case VG_PATH_NUM_SEGMENTS:
1585    case VG_PATH_NUM_COORDS:
1586       values[0] = vegaGetParameteri(object, paramType);
1587       break;
1588    case VG_PATH_SCALE:
1589    case VG_PATH_BIAS:
1590       values[0] = vegaGetParameterf(object, paramType);
1591       break;
1592
1593    case VG_IMAGE_FORMAT:
1594    case VG_IMAGE_WIDTH:
1595    case VG_IMAGE_HEIGHT:
1596 #ifdef OPENVG_VERSION_1_1
1597    case VG_FONT_NUM_GLYPHS:
1598       values[0] = vegaGetParameteri(object, paramType);
1599       break;
1600 #endif
1601
1602    default:
1603       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1604       break;
1605    }
1606 }
1607
1608 void vegaGetParameteriv(VGHandle object,
1609                         VGint paramType,
1610                         VGint count,
1611                         VGint * values)
1612 {
1613    struct vg_context *ctx = vg_current_context();
1614    VGint real_count = vegaGetParameterVectorSize(object, paramType);
1615
1616    if (object || object == VG_INVALID_HANDLE) {
1617       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
1618       return;
1619    }
1620
1621    if (!values || count <= 0 || count > real_count ||
1622        !is_aligned(values)) {
1623       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1624       return;
1625    }
1626
1627    switch(paramType) {
1628    case VG_PAINT_TYPE:
1629    case VG_PAINT_COLOR_RAMP_SPREAD_MODE:
1630    case VG_PAINT_COLOR_RAMP_PREMULTIPLIED:
1631    case VG_PAINT_PATTERN_TILING_MODE:
1632 #ifdef OPENVG_VERSION_1_1
1633    case VG_FONT_NUM_GLYPHS:
1634       values[0] = vegaGetParameteri(object, paramType);
1635       break;
1636 #endif
1637    case VG_PAINT_COLOR: {
1638       struct vg_paint *paint = handle_to_paint(object);
1639       paint_get_coloriv(paint, values);
1640    }
1641       break;
1642    case VG_PAINT_COLOR_RAMP_STOPS: {
1643       struct vg_paint *paint = handle_to_paint(object);
1644       paint_ramp_stopsi(paint, values, count);
1645    }
1646       break;
1647    case VG_PAINT_LINEAR_GRADIENT: {
1648       struct vg_paint *paint = handle_to_paint(object);
1649       paint_linear_gradienti(paint, values);
1650    }
1651       break;
1652    case VG_PAINT_RADIAL_GRADIENT: {
1653       struct vg_paint *paint = handle_to_paint(object);
1654       paint_radial_gradienti(paint, values);
1655    }
1656       break;
1657
1658    case VG_PATH_SCALE:
1659    case VG_PATH_BIAS:
1660       values[0] = vegaGetParameterf(object, paramType);
1661       break;
1662    case VG_PATH_FORMAT:
1663    case VG_PATH_DATATYPE:
1664    case VG_PATH_NUM_SEGMENTS:
1665    case VG_PATH_NUM_COORDS:
1666       values[0] = vegaGetParameteri(object, paramType);
1667       break;
1668
1669    case VG_IMAGE_FORMAT:
1670    case VG_IMAGE_WIDTH:
1671    case VG_IMAGE_HEIGHT:
1672       values[0] = vegaGetParameteri(object, paramType);
1673       break;
1674
1675    default:
1676       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
1677       break;
1678    }
1679 }