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