Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.