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
current_state()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
count_in_bounds(VGParamType type,VGint count)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
vegaSetf(VGParamType type,VGfloat value)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
vegaSeti(VGParamType type,VGint value)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
vegaSetfv(VGParamType type,VGint count,const VGfloat * values)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
vegaSetiv(VGParamType type,VGint count,const VGint * values)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
vegaGetf(VGParamType type)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
vegaGeti(VGParamType type)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
vegaGetVectorSize(VGParamType type)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
vegaGetfv(VGParamType type,VGint count,VGfloat * values)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
vegaGetiv(VGParamType type,VGint count,VGint * values)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
vegaSetParameterf(VGHandle object,VGint paramType,VGfloat value)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
vegaSetParameteri(VGHandle object,VGint paramType,VGint value)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
vegaSetParameterfv(VGHandle object,VGint paramType,VGint count,const VGfloat * values)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
vegaSetParameteriv(VGHandle object,VGint paramType,VGint count,const VGint * values)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
vegaGetParameterVectorSize(VGHandle object,VGint paramType)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
vegaGetParameterf(VGHandle object,VGint paramType)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
vegaGetParameteri(VGHandle object,VGint paramType)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
vegaGetParameterfv(VGHandle object,VGint paramType,VGint count,VGfloat * values)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
vegaGetParameteriv(VGHandle object,VGint paramType,VGint count,VGint * values)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 }
1680