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