1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc. All Rights Reserved. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "path.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "stroker.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "polygon.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "bezier.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "matrix.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_context.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util_array.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "arc.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "path_utils.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "paint.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "shader.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <assert.h> 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_PATH 0 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct path { 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_object base; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGbitfield caps; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean dirty; 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean dirty_stroke; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathDatatype datatype; 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat scale; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat bias; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_segments; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array * segments; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array * control_points; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct { 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon_array polygon_array; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix matrix; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } fill_polys; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct { 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix matrix; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat stroke_width; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat miter_limit; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGCapStyle cap_style; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGJoinStyle join_style; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } stroked; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void data_at(void **data, 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *p, 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint start, VGint count, 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *out) 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathDatatype dt = p->datatype; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint end = start + count; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *itr = out; 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(dt) { 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_8: { 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGbyte **bdata = (VGbyte **)data; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = start; i < end; ++i) { 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *itr = (*bdata)[i]; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *bdata += count; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_16: { 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGshort **bdata = (VGshort **)data; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = start; i < end; ++i) { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *itr = (*bdata)[i]; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *bdata += count; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_32: { 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint **bdata = (VGint **)data; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = start; i < end; ++i) { 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *itr = (*bdata)[i]; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *bdata += count; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_F: { 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat **fdata = (VGfloat **)data; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = start; i < end; ++i) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *itr = (*fdata)[i]; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *fdata += count; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"Unknown path datatype!"); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid vg_float_to_datatype(VGPathDatatype datatype, 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte *common_data, 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *data, 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords) 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(datatype) { 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_8: { 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_coords; ++i) { 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org common_data[i] = (VGubyte)data[i]; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_16: { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGshort *buf = (VGshort*)common_data; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_coords; ++i) { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf[i] = (VGshort)data[i]; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_S_32: { 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint *buf = (VGint*)common_data; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_coords; ++i) { 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf[i] = (VGint)data[i]; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_PATH_DATATYPE_F: { 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(common_data, data, sizeof(VGfloat) * num_coords); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"Unknown path datatype!"); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void coords_adjust_by_scale_bias(struct path *p, 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *pdata, VGint num_coords, 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat scale, VGfloat bias, 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathDatatype datatype) 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords = (VGfloat *)pdata; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte *common_data = (VGubyte *)pdata; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint size_dst = size_for_datatype(datatype); 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_coords; ++i) { 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = data[0] * scale + bias; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(datatype, common_data, data, 1); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org common_data += size_dst; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct path * path_create(VGPathDatatype dt, VGfloat scale, VGfloat bias, 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint segmentCapacityHint, 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint coordCapacityHint, 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGbitfield capabilities) 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = CALLOC_STRUCT(path); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_init_object(&path->base, vg_current_context(), VG_OBJECT_PATH); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->caps = capabilities & VG_PATH_CAPABILITY_ALL; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_context_add_object(vg_current_context(), &path->base); 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->datatype = dt; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->scale = scale; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->bias = bias; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->segments = array_create(size_for_datatype(VG_PATH_DATATYPE_S_8)); 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->control_points = array_create(size_for_datatype(dt)); 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->dirty = VG_TRUE; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->dirty_stroke = VG_TRUE; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return path; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void polygon_array_cleanup(struct polygon_array *polyarray) 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (polyarray->array) { 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < polyarray->array->num_elements; i++) { 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon *p = ((struct polygon **) polyarray->array->data)[i]; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_destroy(p); 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(polyarray->array); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->array = NULL; 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_destroy(struct path *p) 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_context_remove_object(vg_current_context(), &p->base); 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(p->segments); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(p->control_points); 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_array_cleanup(&p->fill_polys.polygon_array); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (p->stroked.path) 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(p->stroked.path); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(p); 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGbitfield path_capabilities(struct path *p) 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->caps; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_set_capabilities(struct path *p, VGbitfield bf) 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->caps = (bf & VG_PATH_CAPABILITY_ALL); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_append_data(struct path *p, 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint numSegments, 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGubyte * pathSegments, 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const void * pathData) 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint old_segments = p->num_segments; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_new_coords = num_elements_for_segments(pathSegments, numSegments); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(p->segments, pathSegments, numSegments); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(p->control_points, pathData, num_new_coords); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->num_segments += numSegments; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!floatsEqual(p->scale, 1.f) || !floatsEqual(p->bias, 0.f)) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte *coords = (VGubyte*)p->control_points->data; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords_adjust_by_scale_bias(p, 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords + old_segments * p->control_points->datatype_size, 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_new_coords, 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->scale, p->bias, p->datatype); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty = VG_TRUE; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty_stroke = VG_TRUE; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGint path_num_segments(struct path *p) 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->num_segments; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void map_if_relative(VGfloat ox, VGfloat oy, 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean relative, 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *x, VGfloat *y) 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (relative) { 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (x) 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *x += ox; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (y) 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *y += oy; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void close_polygon(struct polygon *current, 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat sx, VGfloat sy, 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat ox, VGfloat oy, 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix *matrix) 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!floatsEqual(sx, ox) || 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !floatsEqual(sy, oy)) { 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0 = sx; 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat y0 = sy; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex_append(current, x0, y0); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void convert_path(struct path *p, 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathDatatype to, 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dst, 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords) 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords = (VGfloat *)p->control_points->data; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte *common_data = (VGubyte *)dst; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint size_dst = size_for_datatype(to); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_coords; ++i) { 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(to, common_data, data, 1); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org common_data += size_dst; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void polygon_array_calculate_bounds( struct polygon_array *polyarray ) 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *polys = polyarray->array; 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat min_x, max_x; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat min_y, max_y; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat bounds[4]; 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(polys); 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!polys->num_elements) { 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->min_x = 0.0f; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->min_y = 0.0f; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->max_x = 0.0f; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->max_y = 0.0f; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_bounding_rect((((struct polygon**)polys->data)[0]), bounds); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_x = bounds[0]; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_y = bounds[1]; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_x = bounds[0] + bounds[2]; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_y = bounds[1] + bounds[3]; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 1; i < polys->num_elements; ++i) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon *p = (((struct polygon**)polys->data)[i]); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_bounding_rect(p, bounds); 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_x = MIN2(min_x, bounds[0]); 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_y = MIN2(min_y, bounds[1]); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_x = MAX2(max_x, bounds[0] + bounds[2]); 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_y = MAX2(max_y, bounds[1] + bounds[3]); 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->min_x = min_x; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->min_y = min_y; 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->max_x = max_x; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polyarray->max_y = max_y; 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct polygon_array * path_get_fill_polygons(struct path *p, struct matrix *matrix) 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon *current = 0; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat sx, sy, px, py, ox, oy; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0, y0, x1, y1, x2, y2, x3, y3; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords = (VGfloat *)p->control_points->data; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *array; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(data, 0, sizeof(data)); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (p->fill_polys.polygon_array.array) 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (memcmp( &p->fill_polys.matrix, 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix, 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof *matrix ) == 0 && p->dirty == VG_FALSE) 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &p->fill_polys.polygon_array; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_array_cleanup(&p->fill_polys.polygon_array); 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* an array of pointers to polygons */ 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array = array_create(sizeof(struct polygon *)); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sx = sy = px = py = ox = oy = 0.f; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (p->num_segments) 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org current = polygon_create(32); 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < p->num_segments; ++i) { 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = ((VGubyte*)(p->segments->data))[i]; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint command = SEGMENT_COMMAND(segment); 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean relative = SEGMENT_ABS_REL(segment); 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(command) { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org close_polygon(current, sx, sy, ox, oy, matrix); 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = sx; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = sy; 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO: 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (current && polygon_vertex_count(current) > 0) { 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add polygon */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org close_polygon(current, sx, sy, ox, oy, matrix); 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(array, ¤t, 1); 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org current = polygon_create(32); 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[1]; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, &y0); 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sx = x0; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = y0; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex_append(current, x0, y0); 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO: 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[1]; 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, &y0); 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex_append(current, x0, y0); 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_HLINE_TO: 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, 0); 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex_append(current, x0, y0); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_VLINE_TO: 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[0]; 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, 0, &y0); 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex_append(current, x0, y0); 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO: { 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 6, data); 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[0]; 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[1]; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = data[2]; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = data[3]; 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[4]; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[5]; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x2, &y2); 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x2; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y2; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, x0, y0, x1, y1, 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2, y2, x3, y3); 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_add_to_polygon(&bezier, current); 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_QUAD_TO: { 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 4, data); 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[0]; 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[1]; 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, x0, y0, x1, y1, 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2, y2, x3, y3); 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_add_to_polygon(&bezier, current); 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SQUAD_TO: { 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2*ox-px; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2*oy-py; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[0]; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[1]; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, x0, y0, x1, y1, 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2, y2, x3, y3); 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_add_to_polygon(&bezier, current); 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCUBIC_TO: { 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 4, data); 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2*ox-px; 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2*oy-py; 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = data[0]; 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = data[1]; 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x2, &y2); 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x2; 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y2; 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, x0, y0, x1, y1, 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2, y2, x3, y3); 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_add_to_polygon(&bezier, current); 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat rh, rv, rot; 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 5, data); 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rh = data[0]; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rv = data[1]; 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rot = data[2]; 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[3]; 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[4]; 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("------- ARC (%f, %f), (%f, %f) %f, %f, %f\n", 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0, y0, x1, y1, rh, rv, rot); 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, command, x0, y0, x1, y1, 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rh, rv, rot); 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_add_to_polygon(&arc, current, 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix); 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x1; 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y1; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abort(); 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Unknown segment!"); 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (current) { 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (polygon_vertex_count(current) > 0) { 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org close_polygon(current, sx, sy, ox, oy, matrix); 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(array, ¤t, 1); 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_destroy(current); 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->fill_polys.polygon_array.array = array; 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->fill_polys.matrix = *matrix; 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_array_calculate_bounds( &p->fill_polys.polygon_array ); 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty = VG_FALSE; 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &p->fill_polys.polygon_array; 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGbyte path_datatype_size(struct path *p) 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return size_for_datatype(p->datatype); 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGPathDatatype path_datatype(struct path *p) 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->datatype; 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGfloat path_scale(struct path *p) 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->scale; 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGfloat path_bias(struct path *p) 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->bias; 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGint path_num_coords(struct path *p) 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return num_elements_for_segments((VGubyte*)p->segments->data, 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->num_segments); 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_modify_coords(struct path *p, 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint startIndex, 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint numSegments, 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const void * pathData) 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte *segments = (VGubyte*)(p->segments->data); 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint count = num_elements_for_segments(&segments[startIndex], numSegments); 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint start_cp = num_elements_for_segments(segments, startIndex); 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_change_data(p->control_points, pathData, start_cp, count); 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords_adjust_by_scale_bias(p, 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((VGubyte*)p->control_points->data) + 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (startIndex * p->control_points->datatype_size), 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_num_coords(p), 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->scale, p->bias, p->datatype); 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty = VG_TRUE; 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty_stroke = VG_TRUE; 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_for_each_segment(struct path *path, 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_for_each_cb cb, 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *user_data) 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_for_each_data p; 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords = (VGfloat *)path->control_points->data; 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.coords = data; 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.sx = p.sy = p.px = p.py = p.ox = p.oy = 0.f; 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.user_data = user_data; 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < path->num_segments; ++i) { 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint command; 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean relative; 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.segment = ((VGubyte*)(path->segments->data))[i]; 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org command = SEGMENT_COMMAND(p.segment); 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org relative = SEGMENT_ABS_REL(p.segment); 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(command) { 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO: 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 2, data); 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.sx = data[0]; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.sy = data[1]; 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[0]; 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[1]; 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO: 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 2, data); 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[0]; 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[1]; 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_HLINE_TO: 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 1, data); 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], 0); 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.segment = VG_LINE_TO; 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = p.oy; 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[0]; 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[1]; 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_VLINE_TO: 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 1, data); 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, 0, &data[0]); 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.segment = VG_LINE_TO; 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = data[0]; 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = p.ox; 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[0]; 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[1]; 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO: { 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 6, data); 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[2], &data[3]); 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[4], &data[5]); 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[2]; 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[3]; 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[4]; 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[5]; 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_QUAD_TO: { 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 4, data); 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[2], &data[3]); 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[2]; 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[3]; 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SQUAD_TO: { 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 2, data); 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = 2*p.ox-p.px; 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = 2*p.oy-p.py; 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[2]; 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[3]; 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCUBIC_TO: { 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 4, data); 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[0], &data[1]); 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[2], &data[3]); 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[0]; 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[1]; 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[2]; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[3]; 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, path, 0, 5, data); 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(p.ox, p.oy, relative, &data[3], &data[4]); 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("------- ARC (%f, %f), (%f, %f) %f, %f, %f\n", 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox, p.oy, data[3], data[4], data[0], data[1], data[2]); 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cb(path, &p); 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.ox = data[3]; 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.oy = data[4]; 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.px = data[3]; 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p.py = data[4]; 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abort(); 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Unknown segment!"); 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct transform_data { 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *segments; 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *coords; 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix *matrix; 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathDatatype datatype; 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean transform_cb(struct path *p, 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_for_each_data *pd) 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct transform_data *td = (struct transform_data *)pd->user_data; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords = num_elements_for_segments(&pd->segment, 1); 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = SEGMENT_COMMAND(pd->segment);/* abs bit is 0 */ 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte common_data[sizeof(VGfloat)*8]; 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(data, pd->coords, sizeof(VGfloat) * num_coords); 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(segment) { 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO: 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO: 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_HLINE_TO: 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_VLINE_TO: 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_QUAD_TO: 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2], data[3], &data[2], &data[3]); 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO: 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2], data[3], &data[2], &data[3]); 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[4], data[5], &data[4], &data[5]); 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SQUAD_TO: 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCUBIC_TO: 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], &data[0], &data[1]); 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(td->matrix, 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2], data[3], &data[2], &data[3]); 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = path_create(td->datatype, 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, segment, 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox, pd->oy, data[3], data[4], 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0], data[1], data[2]); 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_to_path(&arc, path, td->matrix); 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_coords = path_num_coords(path); 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(td->segments, path->segments->data, 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path->num_segments); 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(td->coords, path->control_points->data, 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_coords); 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(path); 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(td->datatype, common_data, data, num_coords); 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(td->segments, &pd->segment, 1); 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(td->coords, common_data, num_coords); 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_transform(struct path *dst, struct path *src) 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct transform_data data; 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_context *ctx = dst->base.ctx; 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.segments = dst->segments; 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.coords = dst->control_points; 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.matrix = &ctx->state.vg.path_user_to_surface_matrix; 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.datatype = dst->datatype; 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_for_each_segment(src, transform_cb, (void*)&data); 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->num_segments = dst->segments->num_elements; 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty = VG_TRUE; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty_stroke = VG_TRUE; 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_append_path(struct path *dst, 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *src) 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords = path_num_coords(src); 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *dst_data = malloc(size_for_datatype(dst->datatype) * num_coords); 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(dst->segments, 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src->segments->data, 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src->num_segments); 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org convert_path(src, dst->datatype, 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_data, num_coords); 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(dst->control_points, 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_data, 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_coords); 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(dst_data); 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->num_segments += src->num_segments; 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty = VG_TRUE; 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty_stroke = VG_TRUE; 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGboolean is_segment_arc(VGubyte segment) 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte scommand = SEGMENT_COMMAND(segment); 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (scommand == VG_SCCWARC_TO || 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scommand == VG_SCWARC_TO || 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scommand == VG_LCCWARC_TO || 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scommand == VG_LCWARC_TO); 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct path_iter_data { 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path; 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment; 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords; 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat px, py, ox, oy, sx, sy; 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGubyte normalize_coords(struct path_iter_data *pd, 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint *num_coords, 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *data) 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint command = SEGMENT_COMMAND(pd->segment); 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean relative = SEGMENT_ABS_REL(pd->segment); 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(command) { 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 0; 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = pd->sx; 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = pd->sy; 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_CLOSE_PATH; 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO: 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 2, data); 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[0], &data[1]); 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->sx = data[0]; 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->sy = data[1]; 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[0]; 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[1]; 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[0]; 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[1]; 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 2; 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_MOVE_TO_ABS; 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO: 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 2, data); 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[0], &data[1]); 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[0]; 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[1]; 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[0]; 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[1]; 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 2; 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_LINE_TO_ABS; 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_HLINE_TO: 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 1, data); 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[0], 0); 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = pd->oy; 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[0]; 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[1]; 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[0]; 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[1]; 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 2; 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_LINE_TO_ABS; 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_VLINE_TO: 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 1, data); 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, 0, &data[0]); 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = data[0]; 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = pd->ox; 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[0]; 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[1]; 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[0]; 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[1]; 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 2; 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_LINE_TO_ABS; 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO: { 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 6, data); 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[0], &data[1]); 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[2], &data[3]); 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[4], &data[5]); 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[2]; 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[3]; 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[4]; 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[5]; 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 6; 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_CUBIC_TO_ABS; 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_QUAD_TO: { 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0, y0, x1, y1, x2, y2, x3, y3; 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 4, data); 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = pd->ox; 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = pd->oy; 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[0]; 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[1]; 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &x1, &y1); 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &x3, &y3); 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = x1; 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = y1; 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = x3; 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = y3; 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = x1; 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = y1; 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2] = x2; 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[3] = y2; 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[4] = x3; 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[5] = y3; 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 6; 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_CUBIC_TO_ABS; 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SQUAD_TO: { 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0, y0, x1, y1, x2, y2, x3, y3; 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 2, data); 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = pd->ox; 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = pd->oy; 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2 * pd->ox - pd->px; 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2 * pd->oy - pd->py; 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[0]; 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[1]; 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &x3, &y3); 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = x1; 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = y1; 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = x3; 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = y3; 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = x1; 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = y1; 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2] = x2; 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[3] = y2; 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[4] = x3; 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[5] = y3; 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 6; 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_CUBIC_TO_ABS; 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCUBIC_TO: { 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0, y0, x1, y1, x2, y2, x3, y3; 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 4, data); 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = pd->ox; 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = pd->oy; 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2*pd->ox-pd->px; 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2*pd->oy-pd->py; 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = data[0]; 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = data[1]; 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &x2, &y2); 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &x3, &y3); 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = x3; 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = y3; 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = x2; 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = y2; 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = x1; 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = y1; 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2] = x2; 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[3] = y2; 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[4] = x3; 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[5] = y3; 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 6; 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_CUBIC_TO_ABS; 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&pd->coords, pd->path, 0, 5, data); 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(pd->ox, pd->oy, relative, &data[3], &data[4]); 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->ox = data[3]; 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->oy = data[4]; 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->px = data[3]; 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pd->py = data[4]; 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *num_coords = 5; 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return command | VG_ABSOLUTE; 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abort(); 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Unknown segment!"); 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void linearly_interpolate(VGfloat *result, 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *start, 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *end, 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat amount, 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint number) 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < number; ++i) { 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result[i] = start[i] + (end[i] - start[i]) * amount; 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGboolean path_interpolate(struct path *dst, 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *start, struct path *end, 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat amount) 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* temporary path that we can discard if it will turn 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * out that start is not compatible with end */ 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *res_path = path_create(dst->datatype, 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1.0, 0.0, 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, dst->caps); 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat start_coords[8]; 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat end_coords[8]; 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat results[8]; 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte common_data[sizeof(VGfloat)*8]; 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_iter_data start_iter, end_iter; 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&start_iter, 0, sizeof(struct path_iter_data)); 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&end_iter, 0, sizeof(struct path_iter_data)); 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_iter.path = start; 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_iter.coords = start->control_points->data; 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end_iter.path = end; 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end_iter.coords = end->control_points->data; 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < start->num_segments; ++i) { 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment; 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte ssegment, esegment; 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint snum_coords, enum_coords; 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_iter.segment = ((VGubyte*)(start->segments->data))[i]; 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end_iter.segment = ((VGubyte*)(end->segments->data))[i]; 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ssegment = normalize_coords(&start_iter, &snum_coords, 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_coords); 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org esegment = normalize_coords(&end_iter, &enum_coords, 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end_coords); 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_segment_arc(ssegment)) { 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!is_segment_arc(esegment)) { 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(res_path); 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (amount > 0.5) 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org segment = esegment; 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org segment = ssegment; 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (is_segment_arc(esegment)) { 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(res_path); 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ssegment != esegment) { 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(res_path); 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org segment = ssegment; 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linearly_interpolate(results, start_coords, end_coords, 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org amount, snum_coords); 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(dst->datatype, common_data, results, snum_coords); 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(res_path, 1, &segment, common_data); 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_path(dst, res_path); 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(res_path); 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty = VG_TRUE; 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->dirty_stroke = VG_TRUE; 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_clear(struct path *p, VGbitfield capabilities) 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_set_capabilities(p, capabilities); 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(p->segments); 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(p->control_points); 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->segments = array_create(size_for_datatype(VG_PATH_DATATYPE_S_8)); 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->control_points = array_create(size_for_datatype(p->datatype)); 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->num_segments = 0; 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty = VG_TRUE; 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty_stroke = VG_TRUE; 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct path * path_create_stroke(struct path *p, 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix *matrix) 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat sx, sy, px, py, ox, oy; 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0, y0, x1, y1, x2, y2, x3, y3; 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8]; 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *coords = (VGfloat *)p->control_points->data; 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int dashed = (p->base.ctx->state.vg.stroke.dash_pattern_num ? 1 : 0); 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dash_stroker stroker; 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_state *vg_state = &p->base.ctx->state.vg; 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (p->stroked.path) 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* ### compare the dash patterns to see if we can cache them. 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for now we simply always bail out if the path is dashed. 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (memcmp( &p->stroked.matrix, 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix, 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof *matrix ) == 0 && 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !dashed && !p->dirty_stroke && 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(p->stroked.stroke_width, vg_state->stroke.line_width.f) && 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(p->stroked.miter_limit, vg_state->stroke.miter_limit.f) && 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.cap_style == vg_state->stroke.cap_style && 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.join_style == vg_state->stroke.join_style) 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->stroked.path; 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy( p->stroked.path ); 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.path = NULL; 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sx = sy = px = py = ox = oy = 0.f; 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dashed) 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dash_stroker_init((struct stroker *)&stroker, vg_state); 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_init((struct stroker *)&stroker, vg_state); 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_begin((struct stroker *)&stroker); 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < p->num_segments; ++i) { 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = ((VGubyte*)(p->segments->data))[i]; 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint command = SEGMENT_COMMAND(segment); 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean relative = SEGMENT_ABS_REL(segment); 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(command) { 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: { 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x0 = sx; 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat y0 = sy; 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x0, y0); 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO: 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[1]; 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, &y0); 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sx = x0; 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = y0; 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_move_to((struct stroker *)&stroker, x0, y0); 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO: 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[1]; 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, &y0); 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x0, y0); 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_HLINE_TO: 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = data[0]; 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x0, 0); 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x0; 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x0, y0); 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_VLINE_TO: 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 1, data); 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = data[0]; 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, 0, &y0); 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y0; 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x0; 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y0; 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x0, y0); 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO: { 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 6, data); 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[0]; 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[1]; 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = data[2]; 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = data[3]; 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[4]; 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[5]; 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x2, &y2); 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(x1, ox) && floatsEqual(y1, oy) && 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x1, x2) && floatsEqual(y1, y2) && 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x2, x3) && floatsEqual(y2, y3)) { 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*ignore the empty segment */ 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (floatsEqual(x3, ox) && floatsEqual(y3, oy)) { 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if dup vertex, emit a line */ 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x3, y3); 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x2; 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y2; 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_curve_to((struct stroker *)&stroker, x1, y1, x2, y2, x3, y3); 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_QUAD_TO: { 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 4, data); 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[0]; 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[1]; 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(x1, ox) && floatsEqual(y1, oy) && 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x1, x2) && floatsEqual(y1, y2) && 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x2, x3) && floatsEqual(y2, y3)) { 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*ignore the empty segment */ 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (floatsEqual(x3, ox) && floatsEqual(y3, oy)) { 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if dup vertex, emit a line */ 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x3, y3); 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_curve_to((struct stroker *)&stroker, x1, y1, x2, y2, x3, y3); 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SQUAD_TO: { 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 2, data); 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2*ox-px; 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2*oy-py; 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[0]; 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[1]; 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /* form a cubic out of it */ 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = (x3 + 2*x1) / 3.f; 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = (y3 + 2*y1) / 3.f; 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = (x0 + 2*x1) / 3.f; 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = (y0 + 2*y1) / 3.f; 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(x1, ox) && floatsEqual(y1, oy) && 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x1, x2) && floatsEqual(y1, y2) && 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x2, x3) && floatsEqual(y2, y3)) { 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*ignore the empty segment */ 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (floatsEqual(x3, ox) && floatsEqual(y3, oy)) { 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if dup vertex, emit a line */ 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x3, y3); 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_curve_to((struct stroker *)&stroker, x1, y1, x2, y2, x3, y3); 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCUBIC_TO: { 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 4, data); 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = 2*ox-px; 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = 2*oy-py; 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x2 = data[0]; 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y2 = data[1]; 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x3 = data[2]; 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y3 = data[3]; 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x2, &y2); 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x3, &y3); 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(x1, ox) && floatsEqual(y1, oy) && 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x1, x2) && floatsEqual(y1, y2) && 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(x2, x3) && floatsEqual(y2, y3)) { 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*ignore the empty segment */ 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (floatsEqual(x3, ox) && floatsEqual(y3, oy)) { 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if dup vertex, emit a line */ 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x3, y3); 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x3; 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y3; 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x2; 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y2; 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(matrix_is_affine(matrix)); 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x0, y0, &x0, &y0); 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x2, y2, &x2, &y2); 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x3, y3, &x3, &y3); 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_curve_to((struct stroker *)&stroker, x1, y1, x2, y2, x3, y3); 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat rh, rv, rot; 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data_at(&coords, p, 0, 5, data); 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x0 = ox; 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y0 = oy; 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rh = data[0]; 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rv = data[1]; 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rot = data[2]; 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1 = data[3]; 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org y1 = data[4]; 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map_if_relative(ox, oy, relative, &x1, &y1); 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(x1, ox) && floatsEqual(y1, oy)) { 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if dup vertex, emit a line */ 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x1; 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y1; 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_map_point(matrix, x1, y1, &x1, &y1); 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to((struct stroker *)&stroker, x1, y1); 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, command, x0, y0, x1, y1, 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rh, rv, rot); 1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_stroke_cb(&arc, (struct stroker *)&stroker, 1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix); 1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = x1; 1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = y1; 1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px = x1; 1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org py = y1; 1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org abort(); 1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Unknown segment!"); 1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_end((struct stroker *)&stroker); 1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dashed) 1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dash_stroker_cleanup((struct dash_stroker *)&stroker); 1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cleanup((struct stroker *)&stroker); 1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.path = stroker.base.path; 1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.matrix = *matrix; 1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->dirty_stroke = VG_FALSE; 1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.stroke_width = vg_state->stroke.line_width.f; 1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.miter_limit = vg_state->stroke.miter_limit.f; 1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.cap_style = vg_state->stroke.cap_style; 1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p->stroked.join_style = vg_state->stroke.join_style; 1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return stroker.base.path; 1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_render(struct path *p, VGbitfield paintModes, 1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix *mat) 1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_context *ctx = vg_current_context(); 1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix paint_matrix; 1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_validate_state(ctx); 1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_drawing_image(ctx->shader, VG_FALSE); 1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_image(ctx->shader, 0); 1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Matrix(11=%f 12=%f 13=%f 21=%f 22=%f 23=%f 31=%f 32=%f 33=%f)\n", 1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat->m[0], mat->m[1], mat->m[2], 1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat->m[3], mat->m[4], mat->m[5], 1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat->m[6], mat->m[7], mat->m[8]); 1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((paintModes & VG_FILL_PATH) && 1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_get_paint_matrix(ctx, 1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ctx->state.vg.fill_paint_to_user_matrix, 1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat, 1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &paint_matrix)) { 1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* First the fill */ 1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_surface_matrix(ctx->shader, mat); 1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_paint(ctx->shader, ctx->state.vg.fill_paint); 1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_paint_matrix(ctx->shader, &paint_matrix); 1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_bind(ctx->shader); 1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_fill(p); 1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((paintModes & VG_STROKE_PATH) && 1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_get_paint_matrix(ctx, 1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ctx->state.vg.stroke_paint_to_user_matrix, 1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat, 1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &paint_matrix)) { 1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 8.7.5: "line width less than or equal to 0 prevents stroking from 1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * taking place."*/ 1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->state.vg.stroke.line_width.f <= 0) 1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_surface_matrix(ctx->shader, mat); 1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_paint(ctx->shader, ctx->state.vg.stroke_paint); 1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_set_paint_matrix(ctx->shader, &paint_matrix); 1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_bind(ctx->shader); 1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_stroke(p); 1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_fill(struct path *p) 1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_context *ctx = vg_current_context(); 1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon_array *polygon_array = path_get_fill_polygons(p, &identity); 1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *polys = polygon_array->array; 1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!polygon_array || !polys || !polys->num_elements) { 1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_array_fill(polygon_array, ctx); 1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_stroke(struct path *p) 1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_context *ctx = vg_current_context(); 1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGFillRule old_fill = ctx->state.vg.fill_rule; 1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *stroke; 1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke = path_create_stroke(p, &identity); 1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroke && !path_is_empty(stroke)) { 1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->state.vg.fill_rule = VG_NON_ZERO; 1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_fill(stroke); 1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->state.vg.fill_rule = old_fill; 1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_move_to(struct path *p, float x, float y) 1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = VG_MOVE_TO_ABS; 1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte common_data[sizeof(VGfloat) * 2]; 1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[2] = {x, y}; 1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(p->datatype, common_data, data, 2); 1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(p, 1, &segment, common_data); 1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_line_to(struct path *p, float x, float y) 1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = VG_LINE_TO_ABS; 1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte common_data[sizeof(VGfloat) * 2]; 1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[2] = {x, y}; 1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(p->datatype, common_data, data, 2); 1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(p, 1, &segment, common_data); 1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_cubic_to(struct path *p, float px1, float py1, 1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float px2, float py2, 1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float x, float y) 1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment = VG_CUBIC_TO_ABS; 1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte common_data[sizeof(VGfloat) * 6]; 1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[6]; 1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = px1; data[1] = py1; 1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[2] = px2; data[3] = py2; 1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[4] = x; data[5] = y; 1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vg_float_to_datatype(p->datatype, common_data, data, 6); 1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(p, 1, &segment, common_data); 1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void line_bounds(VGfloat *line /*x1,y1,x2,y2*/, 1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *bounds) 1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[0] = MIN2(line[0], line[2]); 1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[1] = MIN2(line[1], line[3]); 1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[2] = MAX2(line[0], line[2]) - bounds[0]; 1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[3] = MAX2(line[1], line[3]) - bounds[1]; 1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void unite_bounds(VGfloat *bounds, 1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *el) 1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat cx1, cy1, cx2, cy2; 1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat nx1, ny1, nx2, ny2; 1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx1 = bounds[0]; 1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cy1 = bounds[1]; 1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx2 = bounds[0] + bounds[2]; 1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cy2 = bounds[1] + bounds[3]; 1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nx1 = el[0]; 1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ny1 = el[1]; 1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nx2 = el[0] + el[2]; 1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ny2 = el[1] + el[3]; 1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[0] = MIN2(cx1, nx1); 1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[1] = MIN2(cy1, ny1); 1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[2] = MAX2(cx2, nx2) - bounds[0]; 1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[3] = MAX2(cy2, ny2) - bounds[1]; 1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void set_bounds(VGfloat *bounds, 1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *element_bounds, 1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean *initialized) 1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(*initialized)) { 1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(bounds, element_bounds, 4 * sizeof(VGfloat)); 1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *initialized = VG_TRUE; 1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unite_bounds(bounds, element_bounds); 1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_bounding_rect(struct path *p, float *x, float *y, 1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float *w, float *h) 1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8]; 1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_iter_data iter; 1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords; 1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat bounds[4]; 1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat element_bounds[4]; 1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat ox, oy; 1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean bounds_inited = VG_FALSE; 1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&iter, 0, sizeof(struct path_iter_data)); 1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&bounds, 0, sizeof(bounds)); 1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!p->num_segments) { 1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[2] = -1; 1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bounds[3] = -1; 1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.path = p; 1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.coords = p->control_points->data; 1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < p->num_segments; ++i) { 1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment; 1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.segment = ((VGubyte*)(p->segments->data))[i]; 1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = iter.ox; 1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = iter.oy; 1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org segment = normalize_coords(&iter, &num_coords, coords); 1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(segment) { 1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: 1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: { 1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {ox, oy, coords[0], coords[1]}; 1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_bounds(line, element_bounds); 1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_bounds(bounds, element_bounds, &bounds_inited); 1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: { 1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, ox, oy, 1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], 1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2], coords[3], 1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4], coords[5]); 1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_exact_bounds(&bezier, element_bounds); 1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_bounds(bounds, element_bounds, &bounds_inited); 1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = path_create(VG_PATH_DATATYPE_F, 1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, segment, 1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox, oy, coords[3], coords[4], 1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], coords[2]); 1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_to_path(&arc, path, &identity); 1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_bounding_rect(path, element_bounds + 0, element_bounds + 1, 1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_bounds + 2, element_bounds + 3); 1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_bounds(bounds, element_bounds, &bounds_inited); 1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *x = bounds[0]; 1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *y = bounds[1]; 1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *w = bounds[2]; 1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *h = bounds[3]; 1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat path_length(struct path *p, int start_segment, int num_segments) 1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8]; 1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_iter_data iter; 1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords; 1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat length = 0; 1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat ox, oy; 1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean in_range = VG_FALSE; 1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&iter, 0, sizeof(struct path_iter_data)); 1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.path = p; 1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.coords = p->control_points->data; 1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < (start_segment + num_segments); ++i) { 1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte segment; 1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.segment = ((VGubyte*)(p->segments->data))[i]; 1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox = iter.ox; 1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oy = iter.oy; 1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org segment = normalize_coords(&iter, &num_coords, coords); 1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org in_range = (i >= start_segment) && i <= (start_segment + num_segments); 1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!in_range) 1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(segment) { 1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: { 1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {ox, oy, iter.sx, iter.sy}; 1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length += line_lengthv(line); 1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: { 1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {ox, oy, coords[0], coords[1]}; 1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length += line_lengthv(line); 1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: { 1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, ox, oy, 1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], 1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2], coords[3], 1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4], coords[5]); 1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length += bezier_length(&bezier, BEZIER_DEFAULT_ERROR); 1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = path_create(VG_PATH_DATATYPE_F, 1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, segment, 1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ox, oy, coords[3], coords[4], 1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], coords[2]); 1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_to_path(&arc, path, &identity); 1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length += path_length(path, 0, path_num_segments(path)); 1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return length; 1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGboolean point_on_current_segment(VGfloat distance, 1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat length, 1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat segment_length) 1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (((floatIsZero(distance) || distance < 0) && floatIsZero(length)) || 1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((distance > length || floatsEqual(distance, length)) && 1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (floatsEqual(distance, length + segment_length) || 1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distance < (length + segment_length)))); 1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean path_point_segment(struct path_iter_data iter, 1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_iter_data prev_iter, 1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8], 1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat distance, 1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat length, VGfloat *current_length, 1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *point, VGfloat *normal) 1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (iter.segment) { 1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: { 1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {prev_iter.ox, prev_iter.oy, iter.sx, iter.sy}; 1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean on_current_segment = VG_FALSE; 1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length = line_lengthv(line); 1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org on_current_segment = point_on_current_segment(distance, 1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length, 1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length); 1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (on_current_segment) { 1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat at = (distance - length) / line_lengthv(line); 1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normal_vector(line, normal); 1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_point_at(line, at, point); 1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: { 1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {prev_iter.ox, prev_iter.oy, coords[0], coords[1]}; 1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean on_current_segment = VG_FALSE; 1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length = line_lengthv(line); 1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org on_current_segment = point_on_current_segment(distance, 1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length, 1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length); 1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (on_current_segment) { 1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat at = (distance - length) / line_lengthv(line); 1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normal_vector(line, normal); 1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_point_at(line, at, point); 1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: { 1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, prev_iter.ox, prev_iter.oy, 1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], 1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2], coords[3], 1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4], coords[5]); 1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length = bezier_length(&bezier, BEZIER_DEFAULT_ERROR); 1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (point_on_current_segment(distance, length, *current_length)) { 1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_point_at_length(&bezier, distance - length, 1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org point, normal); 1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = path_create(VG_PATH_DATATYPE_F, 1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, iter.segment, 1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_iter.ox, prev_iter.oy, coords[3], coords[4], 1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], coords[2]); 1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_to_path(&arc, path, &identity); 1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *current_length = path_length(path, 0, path_num_segments(path)); 1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (point_on_current_segment(distance, length, *current_length)) { 1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_point(path, 0, path_num_segments(path), 1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distance - length, point, normal); 1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid path_point(struct path *p, VGint start_segment, VGint num_segments, 1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat distance, VGfloat *point, VGfloat *normal) 1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8]; 1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path_iter_data iter, prev_iter; 1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords; 1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat length = 0; 1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat current_length = 0; 1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&iter, 0, sizeof(struct path_iter_data)); 1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&prev_iter, 0, sizeof(struct path_iter_data)); 1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org point[0] = 0; 1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org point[1] = 0; 1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org normal[0] = 0; 1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org normal[1] = -1; 1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.path = p; 1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.coords = p->control_points->data; 1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (distance < 0) 1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distance = 0; 1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < (start_segment + num_segments); ++i) { 1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean outside_range = (i < start_segment || 1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i >= (start_segment + num_segments)); 1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_iter = iter; 1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.segment = ((VGubyte*)(p->segments->data))[i]; 1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.segment = normalize_coords(&iter, &num_coords, coords); 2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (outside_range) 2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (path_point_segment(iter, prev_iter, coords, 2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distance, length, ¤t_length, 2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org point, normal)) 2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length += current_length; 2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *OpenVG 1.0 - 8.6.11 vgPointAlongPath 2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If distance is greater than or equal to the path length 2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(i.e., the value returned by vgPathLength when called with the same 2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *startSegment and numSegments parameters), the visual ending point of 2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *the path is used. 2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (iter.segment) { 2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CLOSE_PATH: { 2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {prev_iter.ox, prev_iter.oy, iter.sx, iter.sy}; 2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normal_vector(line, normal); 2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_point_at(line, 1.f, point); 2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: { 2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {prev_iter.ox, prev_iter.oy, coords[0], coords[1]}; 2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normal_vector(line, normal); 2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_point_at(line, 1.f, point); 2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: { 2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, prev_iter.ox, prev_iter.oy, 2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], 2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2], coords[3], 2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4], coords[5]); 2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_point_at_t(&bezier, 1.f, point, normal); 2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCCWARC_TO: 2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_SCWARC_TO: 2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCCWARC_TO: 2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LCWARC_TO: { 2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix identity; 2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct path *path = path_create(VG_PATH_DATATYPE_F, 2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&identity); 2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, iter.segment, 2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_iter.ox, prev_iter.oy, coords[3], coords[4], 2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0], coords[1], coords[2]); 2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_to_path(&arc, path, &identity); 2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_point(path, 0, path_num_segments(path), 2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* to make sure we're bigger than len * 2 it */ 2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2 * path_length(path, 0, path_num_segments(path)), 2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org point, normal); 2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgVGboolean path_is_empty(struct path *p) 2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return p->segments->num_elements == 0; 2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2077