/************************************************************************** * * Copyright 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ #include "VG/openvg.h" #include "vg_context.h" #include "paint.h" #include "path.h" #include "handle.h" #include "image.h" #include "text.h" #include "matrix.h" #include "api_consts.h" #include "api.h" #include "pipe/p_compiler.h" #include "util/u_pointer.h" #include "util/u_math.h" #include static INLINE struct vg_state *current_state() { struct vg_context *ctx = vg_current_context(); if (!ctx) return 0; else return &ctx->state.vg; } static INLINE VGboolean count_in_bounds(VGParamType type, VGint count) { if (count < 0) return VG_FALSE; if (type == VG_SCISSOR_RECTS) return (!(count % 4) && (count >= 0 || count <= VEGA_MAX_SCISSOR_RECTS * 4)); else if (type == VG_STROKE_DASH_PATTERN) { return count <= VEGA_MAX_DASH_COUNT; } else { VGint real_count = vegaGetVectorSize(type); return count == real_count; } } void vegaSetf (VGParamType type, VGfloat value) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); VGErrorCode error = VG_NO_ERROR; switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: case VG_MAX_FLOAT: vegaSeti(type, floor(value)); return; break; case VG_STROKE_LINE_WIDTH: state->stroke.line_width.f = value; state->stroke.line_width.i = float_to_int_floor(*((VGuint*)(&value))); break; case VG_STROKE_MITER_LIMIT: state->stroke.miter_limit.f = value; state->stroke.miter_limit.i = float_to_int_floor(*((VGuint*)(&value))); break; case VG_STROKE_DASH_PHASE: state->stroke.dash_phase.f = value; state->stroke.dash_phase.i = float_to_int_floor(*((VGuint*)(&value))); break; default: error = VG_ILLEGAL_ARGUMENT_ERROR; break; } vg_set_error(ctx, error); } void vegaSeti (VGParamType type, VGint value) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); VGErrorCode error = VG_NO_ERROR; switch(type) { case VG_MATRIX_MODE: if (value < VG_MATRIX_PATH_USER_TO_SURFACE || #ifdef OPENVG_VERSION_1_1 value > VG_MATRIX_GLYPH_USER_TO_SURFACE) #else value > VG_MATRIX_STROKE_PAINT_TO_USER) #endif error = VG_ILLEGAL_ARGUMENT_ERROR; else state->matrix_mode = value; break; case VG_FILL_RULE: if (value < VG_EVEN_ODD || value > VG_NON_ZERO) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->fill_rule = value; break; case VG_IMAGE_QUALITY: state->image_quality = value; break; case VG_RENDERING_QUALITY: if (value < VG_RENDERING_QUALITY_NONANTIALIASED || value > VG_RENDERING_QUALITY_BETTER) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->rendering_quality = value; break; case VG_BLEND_MODE: if (value < VG_BLEND_SRC || value > VG_BLEND_ADDITIVE) error = VG_ILLEGAL_ARGUMENT_ERROR; else { ctx->state.dirty |= BLEND_DIRTY; state->blend_mode = value; } break; case VG_IMAGE_MODE: if (value < VG_DRAW_IMAGE_NORMAL || value > VG_DRAW_IMAGE_STENCIL) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->image_mode = value; break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: state->color_transform = value; #endif break; case VG_STROKE_LINE_WIDTH: state->stroke.line_width.f = value; state->stroke.line_width.i = value; break; case VG_STROKE_CAP_STYLE: if (value < VG_CAP_BUTT || value > VG_CAP_SQUARE) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->stroke.cap_style = value; break; case VG_STROKE_JOIN_STYLE: if (value < VG_JOIN_MITER || value > VG_JOIN_BEVEL) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->stroke.join_style = value; break; case VG_STROKE_MITER_LIMIT: state->stroke.miter_limit.f = value; state->stroke.miter_limit.i = value; break; case VG_STROKE_DASH_PHASE: state->stroke.dash_phase.f = value; state->stroke.dash_phase.i = value; break; case VG_STROKE_DASH_PHASE_RESET: state->stroke.dash_phase_reset = value; break; case VG_MASKING: state->masking = value; break; case VG_SCISSORING: state->scissoring = value; ctx->state.dirty |= DEPTH_STENCIL_DIRTY; break; case VG_PIXEL_LAYOUT: if (value < VG_PIXEL_LAYOUT_UNKNOWN || value > VG_PIXEL_LAYOUT_BGR_HORIZONTAL) error = VG_ILLEGAL_ARGUMENT_ERROR; else state->pixel_layout = value; break; case VG_SCREEN_LAYOUT: /* read only ignore */ break; case VG_FILTER_FORMAT_LINEAR: state->filter_format_linear = value; break; case VG_FILTER_FORMAT_PREMULTIPLIED: state->filter_format_premultiplied = value; break; case VG_FILTER_CHANNEL_MASK: state->filter_channel_mask = value; break; case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: case VG_MAX_FLOAT: /* read only ignore */ break; default: error = VG_ILLEGAL_ARGUMENT_ERROR; break; } vg_set_error(ctx, error); } void vegaSetfv(VGParamType type, VGint count, const VGfloat * values) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); VGErrorCode error = VG_NO_ERROR; if ((count && !values) || !count_in_bounds(type, count) || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: vegaSeti(type, floor(values[0])); return; break; case VG_SCISSOR_RECTS: { VGint i; VGuint *x = (VGuint*)values; for (i = 0; i < count; ++i) { state->scissor_rects[i].f = values[i]; state->scissor_rects[i].i = float_to_int_floor(x[i]); } state->scissor_rects_num = count / 4; ctx->state.dirty |= DEPTH_STENCIL_DIRTY; } break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM_VALUES: { VGint i; for (i = 0; i < count; ++i) { state->color_transform_values[i] = values[i]; } } break; #endif case VG_STROKE_LINE_WIDTH: state->stroke.line_width.f = values[0]; state->stroke.line_width.i = float_to_int_floor(*((VGuint*)(values))); break; case VG_STROKE_MITER_LIMIT: state->stroke.miter_limit.f = values[0]; state->stroke.miter_limit.i = float_to_int_floor(*((VGuint*)(values))); break; case VG_STROKE_DASH_PATTERN: { int i; for (i = 0; i < count; ++i) { state->stroke.dash_pattern[i].f = values[i]; state->stroke.dash_pattern[i].i = float_to_int_floor(*((VGuint*)(values + i))); } state->stroke.dash_pattern_num = count; } break; case VG_STROKE_DASH_PHASE: state->stroke.dash_phase.f = values[0]; state->stroke.dash_phase.i = float_to_int_floor(*((VGuint*)(values))); break; case VG_TILE_FILL_COLOR: state->tile_fill_color[0] = values[0]; state->tile_fill_color[1] = values[1]; state->tile_fill_color[2] = values[2]; state->tile_fill_color[3] = values[3]; state->tile_fill_colori[0] = float_to_int_floor(*((VGuint*)(values + 0))); state->tile_fill_colori[1] = float_to_int_floor(*((VGuint*)(values + 1))); state->tile_fill_colori[2] = float_to_int_floor(*((VGuint*)(values + 2))); state->tile_fill_colori[3] = float_to_int_floor(*((VGuint*)(values + 3))); break; case VG_CLEAR_COLOR: state->clear_color[0] = values[0]; state->clear_color[1] = values[1]; state->clear_color[2] = values[2]; state->clear_color[3] = values[3]; state->clear_colori[0] = float_to_int_floor(*((VGuint*)(values + 0))); state->clear_colori[1] = float_to_int_floor(*((VGuint*)(values + 1))); state->clear_colori[2] = float_to_int_floor(*((VGuint*)(values + 2))); state->clear_colori[3] = float_to_int_floor(*((VGuint*)(values + 3))); break; #ifdef OPENVG_VERSION_1_1 case VG_GLYPH_ORIGIN: state->glyph_origin[0].f = values[0]; state->glyph_origin[1].f = values[1]; state->glyph_origin[0].i = float_to_int_floor(*((VGuint*)(values + 0))); state->glyph_origin[1].i = float_to_int_floor(*((VGuint*)(values + 1))); break; #endif case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: case VG_MAX_FLOAT: break; default: error = VG_ILLEGAL_ARGUMENT_ERROR; break; } vg_set_error(ctx, error); } void vegaSetiv(VGParamType type, VGint count, const VGint * values) { struct vg_context *ctx = vg_current_context(); struct vg_state *state = current_state(); if ((count && !values) || !count_in_bounds(type, count) || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: vegaSeti(type, values[0]); return; break; case VG_SCISSOR_RECTS: { VGint i; for (i = 0; i < count; ++i) { state->scissor_rects[i].i = values[i]; state->scissor_rects[i].f = values[i]; } state->scissor_rects_num = count / 4; ctx->state.dirty |= DEPTH_STENCIL_DIRTY; } break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM_VALUES: { VGint i; for (i = 0; i < count; ++i) { state->color_transform_values[i] = values[i]; } } break; #endif case VG_STROKE_LINE_WIDTH: state->stroke.line_width.f = values[0]; state->stroke.line_width.i = values[0]; break; case VG_STROKE_MITER_LIMIT: state->stroke.miter_limit.f = values[0]; state->stroke.miter_limit.i = values[0]; break; case VG_STROKE_DASH_PATTERN: { int i; for (i = 0; i < count; ++i) { state->stroke.dash_pattern[i].f = values[i]; state->stroke.dash_pattern[i].i = values[i]; } state->stroke.dash_pattern_num = count; } break; case VG_STROKE_DASH_PHASE: state->stroke.dash_phase.f = values[0]; state->stroke.dash_phase.i = values[0]; break; case VG_TILE_FILL_COLOR: state->tile_fill_color[0] = values[0]; state->tile_fill_color[1] = values[1]; state->tile_fill_color[2] = values[2]; state->tile_fill_color[3] = values[3]; state->tile_fill_colori[0] = values[0]; state->tile_fill_colori[1] = values[1]; state->tile_fill_colori[2] = values[2]; state->tile_fill_colori[3] = values[3]; break; case VG_CLEAR_COLOR: state->clear_color[0] = values[0]; state->clear_color[1] = values[1]; state->clear_color[2] = values[2]; state->clear_color[3] = values[3]; state->clear_colori[0] = values[0]; state->clear_colori[1] = values[1]; state->clear_colori[2] = values[2]; state->clear_colori[3] = values[3]; break; #ifdef OPENVG_VERSION_1_1 case VG_GLYPH_ORIGIN: state->glyph_origin[0].f = values[0]; state->glyph_origin[1].f = values[1]; state->glyph_origin[0].i = values[0]; state->glyph_origin[1].i = values[1]; break; #endif case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: case VG_MAX_FLOAT: break; default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } } VGfloat vegaGetf(VGParamType type) { struct vg_context *ctx = vg_current_context(); const struct vg_state *state = current_state(); VGErrorCode error = VG_NO_ERROR; VGfloat value = 0.0f; switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: return vegaGeti(type); break; case VG_STROKE_LINE_WIDTH: value = state->stroke.line_width.f; break; case VG_STROKE_MITER_LIMIT: value = state->stroke.miter_limit.f; break; case VG_STROKE_DASH_PHASE: value = state->stroke.dash_phase.f; break; case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: return vegaGeti(type); break; case VG_MAX_FLOAT: value = 1e+10;/*must be at least 1e+10*/ break; default: error = VG_ILLEGAL_ARGUMENT_ERROR; break; } vg_set_error(ctx, error); return value; } VGint vegaGeti(VGParamType type) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); VGErrorCode error = VG_NO_ERROR; VGint value = 0; switch(type) { case VG_MATRIX_MODE: value = state->matrix_mode; break; case VG_FILL_RULE: value = state->fill_rule; break; case VG_IMAGE_QUALITY: value = state->image_quality; break; case VG_RENDERING_QUALITY: value = state->rendering_quality; break; case VG_BLEND_MODE: value = state->blend_mode; break; case VG_IMAGE_MODE: value = state->image_mode; break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: value = state->color_transform; break; #endif case VG_STROKE_LINE_WIDTH: value = state->stroke.line_width.i; break; case VG_STROKE_CAP_STYLE: value = state->stroke.cap_style; break; case VG_STROKE_JOIN_STYLE: value = state->stroke.join_style; break; case VG_STROKE_MITER_LIMIT: value = state->stroke.miter_limit.i; break; case VG_STROKE_DASH_PHASE: value = state->stroke.dash_phase.i; break; case VG_STROKE_DASH_PHASE_RESET: value = state->stroke.dash_phase_reset; break; case VG_MASKING: value = state->masking; break; case VG_SCISSORING: value = state->scissoring; break; case VG_PIXEL_LAYOUT: value = state->pixel_layout; break; case VG_SCREEN_LAYOUT: value = state->screen_layout; break; case VG_FILTER_FORMAT_LINEAR: value = state->filter_format_linear; break; case VG_FILTER_FORMAT_PREMULTIPLIED: value = state->filter_format_premultiplied; break; case VG_FILTER_CHANNEL_MASK: value = state->filter_channel_mask; break; case VG_MAX_SCISSOR_RECTS: value = 32; /*must be at least 32*/ break; case VG_MAX_DASH_COUNT: value = 16; /*must be at least 16*/ break; case VG_MAX_KERNEL_SIZE: value = 7; /*must be at least 7*/ break; case VG_MAX_SEPARABLE_KERNEL_SIZE: value = 15; /*must be at least 15*/ break; case VG_MAX_COLOR_RAMP_STOPS: value = 256; /*must be at least 32*/ break; case VG_MAX_IMAGE_WIDTH: value = 2048; break; case VG_MAX_IMAGE_HEIGHT: value = 2048; break; case VG_MAX_IMAGE_PIXELS: value = 2048*2048; break; case VG_MAX_IMAGE_BYTES: value = 2048*2048 * 4; break; case VG_MAX_GAUSSIAN_STD_DEVIATION: value = 128; /*must be at least 128*/ break; case VG_MAX_FLOAT: { VGfloat val = vegaGetf(type); value = float_to_int_floor(*((VGuint*)&val)); } break; default: error = VG_ILLEGAL_ARGUMENT_ERROR; break; } vg_set_error(ctx, error); return value; } VGint vegaGetVectorSize(VGParamType type) { struct vg_context *ctx = vg_current_context(); const struct vg_state *state = current_state(); switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: return 1; case VG_SCISSOR_RECTS: return state->scissor_rects_num * 4; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: return 1; case VG_COLOR_TRANSFORM_VALUES: return 8; #endif case VG_STROKE_LINE_WIDTH: case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_MITER_LIMIT: return 1; case VG_STROKE_DASH_PATTERN: return state->stroke.dash_pattern_num; case VG_STROKE_DASH_PHASE: return 1; case VG_STROKE_DASH_PHASE_RESET: return 1; case VG_TILE_FILL_COLOR: return 4; case VG_CLEAR_COLOR: return 4; #ifdef OPENVG_VERSION_1_1 case VG_GLYPH_ORIGIN: return 2; #endif case VG_MASKING: return 1; case VG_SCISSORING: return 1; case VG_PIXEL_LAYOUT: return 1; case VG_SCREEN_LAYOUT: return 1; case VG_FILTER_FORMAT_LINEAR: return 1; case VG_FILTER_FORMAT_PREMULTIPLIED: return 1; case VG_FILTER_CHANNEL_MASK: return 1; case VG_MAX_COLOR_RAMP_STOPS: return 1; case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_FLOAT: case VG_MAX_GAUSSIAN_STD_DEVIATION: return 1; default: if (ctx) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return 0; } } void vegaGetfv(VGParamType type, VGint count, VGfloat * values) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); VGint real_count = vegaGetVectorSize(type); if (!values || count <= 0 || count > real_count || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: values[0] = vegaGeti(type); break; case VG_MAX_FLOAT: values[0] = vegaGetf(type); break; case VG_SCISSOR_RECTS: { VGint i; for (i = 0; i < count; ++i) { values[i] = state->scissor_rects[i].f; } } break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM_VALUES: { memcpy(values, state->color_transform_values, sizeof(VGfloat) * count); } break; #endif case VG_STROKE_LINE_WIDTH: values[0] = state->stroke.line_width.f; break; case VG_STROKE_MITER_LIMIT: values[0] = state->stroke.miter_limit.f; break; case VG_STROKE_DASH_PATTERN: { VGint i; for (i = 0; i < count; ++i) { values[i] = state->stroke.dash_pattern[i].f; } } break; case VG_STROKE_DASH_PHASE: values[0] = state->stroke.dash_phase.f; break; case VG_TILE_FILL_COLOR: values[0] = state->tile_fill_color[0]; values[1] = state->tile_fill_color[1]; values[2] = state->tile_fill_color[2]; values[3] = state->tile_fill_color[3]; break; case VG_CLEAR_COLOR: values[0] = state->clear_color[0]; values[1] = state->clear_color[1]; values[2] = state->clear_color[2]; values[3] = state->clear_color[3]; break; #ifdef OPENVG_VERSION_1_1 case VG_GLYPH_ORIGIN: values[0] = state->glyph_origin[0].f; values[1] = state->glyph_origin[1].f; break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } } void vegaGetiv(VGParamType type, VGint count, VGint * values) { const struct vg_state *state = current_state(); struct vg_context *ctx = vg_current_context(); VGint real_count = vegaGetVectorSize(type); if (!values || count <= 0 || count > real_count || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(type) { case VG_MATRIX_MODE: case VG_FILL_RULE: case VG_IMAGE_QUALITY: case VG_RENDERING_QUALITY: case VG_BLEND_MODE: case VG_IMAGE_MODE: #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM: #endif case VG_STROKE_CAP_STYLE: case VG_STROKE_JOIN_STYLE: case VG_STROKE_DASH_PHASE_RESET: case VG_MASKING: case VG_SCISSORING: case VG_PIXEL_LAYOUT: case VG_SCREEN_LAYOUT: case VG_FILTER_FORMAT_LINEAR: case VG_FILTER_FORMAT_PREMULTIPLIED: case VG_FILTER_CHANNEL_MASK: case VG_MAX_SCISSOR_RECTS: case VG_MAX_DASH_COUNT: case VG_MAX_KERNEL_SIZE: case VG_MAX_SEPARABLE_KERNEL_SIZE: case VG_MAX_COLOR_RAMP_STOPS: case VG_MAX_IMAGE_WIDTH: case VG_MAX_IMAGE_HEIGHT: case VG_MAX_IMAGE_PIXELS: case VG_MAX_IMAGE_BYTES: case VG_MAX_GAUSSIAN_STD_DEVIATION: values[0] = vegaGeti(type); break; case VG_MAX_FLOAT: { VGfloat val = vegaGetf(type); values[0] = float_to_int_floor(*((VGuint*)&val)); } break; case VG_SCISSOR_RECTS: { VGint i; for (i = 0; i < count; ++i) { values[i] = state->scissor_rects[i].i; } } break; #ifdef OPENVG_VERSION_1_1 case VG_COLOR_TRANSFORM_VALUES: { VGint i; VGuint *x = (VGuint*)state->color_transform_values; for (i = 0; i < count; ++i) { values[i] = float_to_int_floor(x[i]); } } break; #endif case VG_STROKE_LINE_WIDTH: values[0] = state->stroke.line_width.i; break; case VG_STROKE_MITER_LIMIT: values[0] = state->stroke.miter_limit.i; break; case VG_STROKE_DASH_PATTERN: { VGint i; for (i = 0; i < count; ++i) { values[i] = state->stroke.dash_pattern[i].i; } } break; case VG_STROKE_DASH_PHASE: values[0] = state->stroke.dash_phase.i; break; case VG_TILE_FILL_COLOR: values[0] = state->tile_fill_colori[0]; values[1] = state->tile_fill_colori[1]; values[2] = state->tile_fill_colori[2]; values[3] = state->tile_fill_colori[3]; break; case VG_CLEAR_COLOR: values[0] = state->clear_colori[0]; values[1] = state->clear_colori[1]; values[2] = state->clear_colori[2]; values[3] = state->clear_colori[3]; break; #ifdef OPENVG_VERSION_1_1 case VG_GLYPH_ORIGIN: values[0] = state->glyph_origin[0].i; values[1] = state->glyph_origin[1].i; break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } } void vegaSetParameterf(VGHandle object, VGint paramType, VGfloat value) { struct vg_context *ctx = vg_current_context(); void *ptr = handle_to_pointer(object); if (object == VG_INVALID_HANDLE || !is_aligned(ptr)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_PATTERN_TILING_MODE: vegaSetParameteri(object, paramType, floor(value)); return; break; case VG_PAINT_COLOR: case VG_PAINT_COLOR_RAMP_STOPS: case VG_PAINT_LINEAR_GRADIENT: case VG_PAINT_RADIAL_GRADIENT: /* it's an error if paramType refers to a vector parameter */ vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: { struct vg_paint *p = handle_to_paint(object); paint_set_color_ramp_premultiplied(p, value); } break; case VG_PATH_DATATYPE: case VG_PATH_FORMAT: case VG_PATH_SCALE: case VG_PATH_BIAS: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: /* read only don't produce an error */ break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } } void vegaSetParameteri(VGHandle object, VGint paramType, VGint value) { struct vg_context *ctx = vg_current_context(); void *ptr = handle_to_pointer(object); if (object == VG_INVALID_HANDLE || !is_aligned(ptr)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: if (value < VG_PAINT_TYPE_COLOR || value > VG_PAINT_TYPE_PATTERN) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_type(paint, value); } break; case VG_PAINT_COLOR: case VG_PAINT_COLOR_RAMP_STOPS: case VG_PAINT_LINEAR_GRADIENT: case VG_PAINT_RADIAL_GRADIENT: /* it's an error if paramType refers to a vector parameter */ vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; case VG_PAINT_COLOR_RAMP_SPREAD_MODE: if (value < VG_COLOR_RAMP_SPREAD_PAD || value > VG_COLOR_RAMP_SPREAD_REFLECT) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_spread_mode(paint, value); } break; case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: { struct vg_paint *p = handle_to_paint(object); paint_set_color_ramp_premultiplied(p, value); } break; case VG_PAINT_PATTERN_TILING_MODE: if (value < VG_TILE_FILL || value > VG_TILE_REFLECT) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_pattern_tiling(paint, value); } break; case VG_PATH_DATATYPE: case VG_PATH_FORMAT: case VG_PATH_SCALE: case VG_PATH_BIAS: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: /* read only don't produce an error */ break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } } void vegaSetParameterfv(VGHandle object, VGint paramType, VGint count, const VGfloat * values) { struct vg_context *ctx = vg_current_context(); void *ptr = handle_to_pointer(object); VGint real_count = vegaGetParameterVectorSize(object, paramType); if (object == VG_INVALID_HANDLE || !is_aligned(ptr)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (count < 0 || count < real_count || (values == NULL && count != 0) || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: case VG_PAINT_PATTERN_TILING_MODE: if (count != 1) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else vegaSetParameterf(object, paramType, values[0]); return; break; case VG_PAINT_COLOR: { if (count != 4) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_color(paint, values); if (ctx->state.vg.fill_paint == paint || ctx->state.vg.stroke_paint == paint) ctx->state.dirty |= PAINT_DIRTY; } } break; case VG_PAINT_COLOR_RAMP_STOPS: { if (count && count < 4) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); count = MIN2(count, VEGA_MAX_COLOR_RAMP_STOPS); paint_set_ramp_stops(paint, values, count); { VGint stopsi[VEGA_MAX_COLOR_RAMP_STOPS]; int i = 0; for (i = 0; i < count; ++i) { stopsi[i] = float_to_int_floor(*((VGuint*)(values + i))); } paint_set_ramp_stopsi(paint, stopsi, count); } } } break; case VG_PAINT_LINEAR_GRADIENT: { if (count != 4) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_linear_gradient(paint, values); { VGint vals[4]; vals[0] = FLT_TO_INT(values[0]); vals[1] = FLT_TO_INT(values[1]); vals[2] = FLT_TO_INT(values[2]); vals[3] = FLT_TO_INT(values[3]); paint_set_linear_gradienti(paint, vals); } } } break; case VG_PAINT_RADIAL_GRADIENT: { if (count != 5) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_radial_gradient(paint, values); { VGint vals[5]; vals[0] = FLT_TO_INT(values[0]); vals[1] = FLT_TO_INT(values[1]); vals[2] = FLT_TO_INT(values[2]); vals[3] = FLT_TO_INT(values[3]); vals[4] = FLT_TO_INT(values[4]); paint_set_radial_gradienti(paint, vals); } } } break; case VG_PATH_DATATYPE: case VG_PATH_FORMAT: case VG_PATH_SCALE: case VG_PATH_BIAS: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: /* read only don't produce an error */ break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } } void vegaSetParameteriv(VGHandle object, VGint paramType, VGint count, const VGint * values) { struct vg_context *ctx = vg_current_context(); void *ptr = handle_to_pointer(object); VGint real_count = vegaGetParameterVectorSize(object, paramType); if (object == VG_INVALID_HANDLE || !is_aligned(ptr)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (count < 0 || count < real_count || (values == NULL && count != 0) || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: case VG_PAINT_PATTERN_TILING_MODE: if (count != 1) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else vegaSetParameteri(object, paramType, values[0]); return; break; case VG_PAINT_COLOR: { if (count != 4) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { struct vg_paint *paint = handle_to_paint(object); paint_set_coloriv(paint, values); if (ctx->state.vg.fill_paint == paint || ctx->state.vg.stroke_paint == paint) ctx->state.dirty |= PAINT_DIRTY; } } break; case VG_PAINT_COLOR_RAMP_STOPS: { if ((count % 5)) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { VGfloat *vals = 0; int i; struct vg_paint *paint = handle_to_paint(object); if (count) { vals = malloc(sizeof(VGfloat)*count); for (i = 0; i < count; ++i) vals[i] = values[i]; } paint_set_ramp_stopsi(paint, values, count); paint_set_ramp_stops(paint, vals, count); free(vals); } } break; case VG_PAINT_LINEAR_GRADIENT: { if (count != 4) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { VGfloat vals[4]; struct vg_paint *paint = handle_to_paint(object); vals[0] = values[0]; vals[1] = values[1]; vals[2] = values[2]; vals[3] = values[3]; paint_set_linear_gradient(paint, vals); paint_set_linear_gradienti(paint, values); } } break; case VG_PAINT_RADIAL_GRADIENT: { if (count != 5) vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); else { VGfloat vals[5]; struct vg_paint *paint = handle_to_paint(object); vals[0] = values[0]; vals[1] = values[1]; vals[2] = values[2]; vals[3] = values[3]; vals[4] = values[4]; paint_set_radial_gradient(paint, vals); paint_set_radial_gradienti(paint, values); } } break; case VG_PATH_DATATYPE: case VG_PATH_FORMAT: case VG_PATH_SCALE: case VG_PATH_BIAS: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: /* read only don't produce an error */ break; default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } } VGint vegaGetParameterVectorSize(VGHandle object, VGint paramType) { struct vg_context *ctx = vg_current_context(); if (object == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return 0; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: case VG_PAINT_PATTERN_TILING_MODE: return 1; case VG_PAINT_COLOR: return 4; case VG_PAINT_COLOR_RAMP_STOPS: { struct vg_paint *p = handle_to_paint(object); return paint_num_ramp_stops(p); } break; case VG_PAINT_LINEAR_GRADIENT: return 4; case VG_PAINT_RADIAL_GRADIENT: return 5; case VG_PATH_FORMAT: case VG_PATH_DATATYPE: case VG_PATH_SCALE: case VG_PATH_BIAS: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: return 1; case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: return 1; #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: return 1; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } return 0; } VGfloat vegaGetParameterf(VGHandle object, VGint paramType) { struct vg_context *ctx = vg_current_context(); if (object == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return 0; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: case VG_PAINT_PATTERN_TILING_MODE: return vegaGetParameteri(object, paramType); break; case VG_PAINT_COLOR: case VG_PAINT_COLOR_RAMP_STOPS: case VG_PAINT_LINEAR_GRADIENT: case VG_PAINT_RADIAL_GRADIENT: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; case VG_PATH_FORMAT: return VG_PATH_FORMAT_STANDARD; case VG_PATH_SCALE: { struct path *p = handle_to_path(object); return path_scale(p); } case VG_PATH_BIAS: { struct path *p = handle_to_path(object); return path_bias(p); } case VG_PATH_DATATYPE: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: return vegaGetParameteri(object, paramType); break; case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: return vegaGetParameteri(object, paramType); break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } return 0; } VGint vegaGetParameteri(VGHandle object, VGint paramType) { struct vg_context *ctx = vg_current_context(); if (object == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return 0; } switch(paramType) { case VG_PAINT_TYPE: { struct vg_paint *paint = handle_to_paint(object); return paint_type(paint); } break; case VG_PAINT_COLOR_RAMP_SPREAD_MODE: { struct vg_paint *p = handle_to_paint(object); return paint_spread_mode(p); } case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: { struct vg_paint *p = handle_to_paint(object); return paint_color_ramp_premultiplied(p); } break; case VG_PAINT_PATTERN_TILING_MODE: { struct vg_paint *p = handle_to_paint(object); return paint_pattern_tiling(p); } break; case VG_PAINT_COLOR: case VG_PAINT_COLOR_RAMP_STOPS: case VG_PAINT_LINEAR_GRADIENT: case VG_PAINT_RADIAL_GRADIENT: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; case VG_PATH_FORMAT: return VG_PATH_FORMAT_STANDARD; case VG_PATH_SCALE: case VG_PATH_BIAS: return vegaGetParameterf(object, paramType); case VG_PATH_DATATYPE: { struct path *p = handle_to_path(object); return path_datatype(p); } case VG_PATH_NUM_SEGMENTS: { struct path *p = handle_to_path(object); return path_num_segments(p); } case VG_PATH_NUM_COORDS: { struct path *p = handle_to_path(object); return path_num_coords(p); } break; case VG_IMAGE_FORMAT: { struct vg_image *img = handle_to_image(object); return img->format; } break; case VG_IMAGE_WIDTH: { struct vg_image *img = handle_to_image(object); return img->width; } break; case VG_IMAGE_HEIGHT: { struct vg_image *img = handle_to_image(object); return img->height; } break; #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: { struct vg_font *font = handle_to_font(object); return font_num_glyphs(font); } break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } return 0; } void vegaGetParameterfv(VGHandle object, VGint paramType, VGint count, VGfloat * values) { struct vg_context *ctx = vg_current_context(); VGint real_count = vegaGetParameterVectorSize(object, paramType); if (object == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!values || count <= 0 || count > real_count || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: { struct vg_paint *p = handle_to_paint(object); values[0] = paint_type(p); } break; case VG_PAINT_COLOR_RAMP_SPREAD_MODE: { struct vg_paint *p = handle_to_paint(object); values[0] = paint_spread_mode(p); } break; case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: { struct vg_paint *p = handle_to_paint(object); values[0] = paint_color_ramp_premultiplied(p); } break; case VG_PAINT_PATTERN_TILING_MODE: { values[0] = vegaGetParameterf(object, paramType); } break; case VG_PAINT_COLOR: { struct vg_paint *paint = handle_to_paint(object); paint_get_color(paint, values); } break; case VG_PAINT_COLOR_RAMP_STOPS: { struct vg_paint *paint = handle_to_paint(object); paint_ramp_stops(paint, values, count); } break; case VG_PAINT_LINEAR_GRADIENT: { struct vg_paint *paint = handle_to_paint(object); paint_linear_gradient(paint, values); } break; case VG_PAINT_RADIAL_GRADIENT: { struct vg_paint *paint = handle_to_paint(object); paint_radial_gradient(paint, values); } break; case VG_PATH_FORMAT: case VG_PATH_DATATYPE: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: values[0] = vegaGetParameteri(object, paramType); break; case VG_PATH_SCALE: case VG_PATH_BIAS: values[0] = vegaGetParameterf(object, paramType); break; case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: values[0] = vegaGetParameteri(object, paramType); break; #endif default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } } void vegaGetParameteriv(VGHandle object, VGint paramType, VGint count, VGint * values) { struct vg_context *ctx = vg_current_context(); VGint real_count = vegaGetParameterVectorSize(object, paramType); if (object || object == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!values || count <= 0 || count > real_count || !is_aligned(values)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } switch(paramType) { case VG_PAINT_TYPE: case VG_PAINT_COLOR_RAMP_SPREAD_MODE: case VG_PAINT_COLOR_RAMP_PREMULTIPLIED: case VG_PAINT_PATTERN_TILING_MODE: #ifdef OPENVG_VERSION_1_1 case VG_FONT_NUM_GLYPHS: values[0] = vegaGetParameteri(object, paramType); break; #endif case VG_PAINT_COLOR: { struct vg_paint *paint = handle_to_paint(object); paint_get_coloriv(paint, values); } break; case VG_PAINT_COLOR_RAMP_STOPS: { struct vg_paint *paint = handle_to_paint(object); paint_ramp_stopsi(paint, values, count); } break; case VG_PAINT_LINEAR_GRADIENT: { struct vg_paint *paint = handle_to_paint(object); paint_linear_gradienti(paint, values); } break; case VG_PAINT_RADIAL_GRADIENT: { struct vg_paint *paint = handle_to_paint(object); paint_radial_gradienti(paint, values); } break; case VG_PATH_SCALE: case VG_PATH_BIAS: values[0] = vegaGetParameterf(object, paramType); break; case VG_PATH_FORMAT: case VG_PATH_DATATYPE: case VG_PATH_NUM_SEGMENTS: case VG_PATH_NUM_COORDS: values[0] = vegaGetParameteri(object, paramType); break; case VG_IMAGE_FORMAT: case VG_IMAGE_WIDTH: case VG_IMAGE_HEIGHT: values[0] = vegaGetParameteri(object, paramType); break; default: vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); break; } }