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 "stroker.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "path.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vg_state.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util_array.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "arc.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "bezier.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "matrix.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "path_utils.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "polygon.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef M_2PI 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define M_2PI 6.28318530717958647692528676655900576 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define STROKE_SEGMENTS 0 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define STROKE_DEBUG 0 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_EMITS 0 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const VGfloat curve_threshold = 0.25f; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const VGfloat zero_coords[] = {0.f, 0.f}; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum intersection_type { 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NoIntersections, 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BoundedIntersection, 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UnboundedIntersection, 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum line_join_mode { 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FlatJoin, 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SquareJoin, 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MiterJoin, 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RoundJoin, 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RoundCap 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct stroke_iterator { 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void (*next)(struct stroke_iterator *); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean (*has_next)(struct stroke_iterator *); 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand (*current_command)(struct stroke_iterator *it); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void (*current_coords)(struct stroke_iterator *it, VGfloat *coords); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint position; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint coord_position; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGubyte *cmds; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *coords; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_commands; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct polygon *curve_poly; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint curve_index; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGPathCommand stroke_itr_command(struct stroke_iterator *itr) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return itr->current_command(itr); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_itr_coords(struct stroke_iterator *itr, VGfloat *coords) 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_coords(itr, coords); 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_fw_itr_coords(struct stroke_iterator *itr, VGfloat *coords) 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->position >= itr->num_commands) 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (stroke_itr_command(itr)) { 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2] = itr->coords[itr->coord_position + 2]; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[3] = itr->coords[itr->coord_position + 3]; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4] = itr->coords[itr->coord_position + 4]; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[5] = itr->coords[itr->coord_position + 5]; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"invalid command!\n"); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_bw_itr_coords(struct stroke_iterator *itr, VGfloat *coords) 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->position >= itr->num_commands) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (stroke_itr_command(itr)) { 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position + 4]; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 5]; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2] = itr->coords[itr->coord_position + 2]; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[3] = itr->coords[itr->coord_position + 3]; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4] = itr->coords[itr->coord_position + 0]; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[5] = itr->coords[itr->coord_position + 1]; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"invalid command!\n"); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGPathCommand stroke_fw_current_command(struct stroke_iterator *it) 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return it->cmds[it->position]; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGPathCommand stroke_bw_current_command(struct stroke_iterator *it) 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand prev_cmd; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (it->position == it->num_commands -1) 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_MOVE_TO_ABS; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_cmd = it->cmds[it->position + 1]; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return prev_cmd; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean stroke_fw_has_next(struct stroke_iterator *itr) 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return itr->position < (itr->num_commands - 1); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean stroke_bw_has_next(struct stroke_iterator *itr) 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return itr->position > 0; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_fw_next(struct stroke_iterator *itr) 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmd; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(stroke_fw_has_next(itr)); 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(itr); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position += num_elements_for_segments(&cmd, 1); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr->position; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_bw_next(struct stroke_iterator *itr) 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmd; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(stroke_bw_has_next(itr)); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --itr->position; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(itr); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position -= num_elements_for_segments(&cmd, 1); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_itr_common_init(struct stroke_iterator *itr, 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *cmds, 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *coords) 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->cmds = (VGubyte*)cmds->data; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->num_commands = cmds->num_elements; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coords = (VGfloat*)coords->data; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->num_coords = coords->num_elements; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_forward_iterator(struct stroke_iterator *itr, 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *cmds, 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *coords) 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_common_init(itr, cmds, coords); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->position = 0; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position = 0; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->next = stroke_fw_next; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->has_next = stroke_fw_has_next; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_command = stroke_fw_current_command; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_coords = stroke_fw_itr_coords; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_backward_iterator(struct stroke_iterator *itr, 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *cmds, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *coords) 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmd; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_common_init(itr, cmds, coords); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->position = itr->num_commands - 1; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_bw_current_command(itr); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position = itr->num_coords - 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_elements_for_segments(&cmd, 1); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->next = stroke_bw_next; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->has_next = stroke_bw_has_next; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_command = stroke_bw_current_command; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_coords = stroke_bw_itr_coords; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_flat_next(struct stroke_iterator *itr) 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmd; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->curve_index >= 0) { 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr->curve_index; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->curve_index >= polygon_vertex_count(itr->curve_poly)) { 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_index = -1; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_destroy(itr->curve_poly); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_poly = 0; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(stroke_fw_has_next(itr)); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = itr->cmds[itr->position]; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position += num_elements_for_segments(&cmd, 1); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++itr->position; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = itr->cmds[itr->position]; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmd == VG_CUBIC_TO_ABS) { 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat bez[8]; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[0] = itr->coords[itr->coord_position - 2]; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[1] = itr->coords[itr->coord_position - 1]; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[2] = itr->coords[itr->coord_position]; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[3] = itr->coords[itr->coord_position + 1]; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[4] = itr->coords[itr->coord_position + 2]; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[5] = itr->coords[itr->coord_position + 3]; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[6] = itr->coords[itr->coord_position + 4]; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[7] = itr->coords[itr->coord_position + 5]; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[0], bez[1], 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[2], bez[3], 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[4], bez[5], 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez[6], bez[7]); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* skip the first one, it's the same as the prev point */ 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_index = 1; 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->curve_poly) { 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_destroy(itr->curve_poly); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_poly = 0; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_poly = bezier_to_polygon(&bezier); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean stroke_flat_has_next(struct stroke_iterator *itr) 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (itr->curve_index >= 0 && 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_index < (polygon_vertex_count(itr->curve_poly)-1)) 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || itr->position < (itr->num_commands - 1); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGPathCommand stroke_flat_current_command(struct stroke_iterator *it) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (it->cmds[it->position] == VG_CUBIC_TO_ABS) { 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_LINE_TO_ABS; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return it->cmds[it->position]; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_flat_itr_coords(struct stroke_iterator *itr, VGfloat *coords) 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->curve_index <= -1 && itr->position >= itr->num_commands) 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (itr->curve_index >= 0) { 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_vertex(itr->curve_poly, itr->curve_index, 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords); 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (stroke_itr_command(itr)) { 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[0] = itr->coords[itr->coord_position]; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[1] = itr->coords[itr->coord_position + 1]; 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"invalid command!\n"); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroke_flat_iterator(struct stroke_iterator *itr, 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *cmds, 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct array *coords) 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_common_init(itr, cmds, coords); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->position = 0; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->coord_position = 0; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->next = stroke_flat_next; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->has_next = stroke_flat_has_next; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_command = stroke_flat_current_command; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->current_coords = stroke_flat_itr_coords; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_index = -1; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org itr->curve_poly = 0; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGboolean finite_coords4(const VGfloat *c) 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isfinite(c[0]) && isfinite(c[1]) && 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isfinite(c[2]) && isfinite(c[3]); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* from Graphics Gems II */ 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SAME_SIGNS(a, b) ((a) * (b) >= 0) 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean do_lines_intersect(VGfloat x1, VGfloat y1, VGfloat x2, VGfloat y2, 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x3, VGfloat y3, VGfloat x4, VGfloat y4) 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns */ 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat r1, r2, r3, r4; /* 'sign' values */ 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a1 = y2 - y1; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b1 = x1 - x2; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c1 = x2 * y1 - x1 * y2; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r3 = a1 * x3 + b1 * y3 + c1; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r4 = a1 * x4 + b1 * y4 + c1; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r3 != 0 && r4 != 0 && SAME_SIGNS(r3, r4)) 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a2 = y4 - y3; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b2 = x3 - x4; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c2 = x4 * y3 - x3 * y4; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r1 = a2 * x1 + b2 * y1 + c2; 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r2 = a2 * x2 + b2 * y2 + c2; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (r1 != 0 && r2 != 0 && SAME_SIGNS(r1, r2)) 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat line_dx(const VGfloat *l) 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return l[2] - l[0]; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat line_dy(const VGfloat *l) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return l[3] - l[1]; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat line_angle(const VGfloat *l) 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat dx = line_dx(l); 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat dy = line_dy(l); 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat theta = atan2(-dy, dx) * 360.0 / M_2PI; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat theta_normalized = theta < 0 ? theta + 360 : theta; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(theta_normalized, 360.f)) 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return theta_normalized; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void line_set_length(VGfloat *l, VGfloat len) 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat uv[] = {l[0], l[1], l[2], l[3]}; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (null_line(l)) 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normalize(uv); 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[2] = l[0] + line_dx(uv) * len; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[3] = l[1] + line_dy(uv) * len; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void line_translate(VGfloat *l, VGfloat x, VGfloat y) 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[0] += x; 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[1] += y; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[2] += x; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l[3] += y; 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat line_angle_to(const VGfloat *l1, 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *l2) 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat a1, a2, delta, delta_normalized; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (null_line(l1) || null_line(l1)) 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a1 = line_angle(l1); 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a2 = line_angle(l2); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delta = a2 - a1; 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delta_normalized = delta < 0 ? delta + 360 : delta; 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(delta, 360.f)) 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return delta_normalized; 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat line_angles(const VGfloat *l1, 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *l2) 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat cos_line, rad = 0; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (null_line(l1) || null_line(l2)) 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cos_line = (line_dx(l1)*line_dx(l2) + line_dy(l1)*line_dy(l2)) / 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (line_lengthv(l1)*line_lengthv(l2)); 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rad = 0; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cos_line >= -1.0 && cos_line <= 1.0) 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rad = acos(cos_line); 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rad * 360 / M_2PI; 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat adapted_angle_on_x(const VGfloat *line) 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat identity[] = {0, 0, 1, 0}; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat angle = line_angles(line, identity); 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (line_dy(line) > 0) 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org angle = 360 - angle; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return angle; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum intersection_type line_intersect(const VGfloat *l1, 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *l2, 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float *intersection_point) 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat isect[2] = { 0 }; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum intersection_type type; 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean dx_zero, ldx_zero; 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (null_line(l1) || null_line(l2) || 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !finite_coords4(l1) || !finite_coords4(l2)) 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NoIntersections; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = do_lines_intersect(l1[0], l1[1], l1[2], l1[3], l2[0], l2[1], l2[2], l2[3]) 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? BoundedIntersection : UnboundedIntersection; 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dx_zero = floatsEqual(line_dx(l1) + 1, 1); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ldx_zero = floatsEqual(line_dx(l2) + 1, 1); 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* one of the lines is vertical */ 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dx_zero && ldx_zero) { 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = NoIntersections; 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (dx_zero) { 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat la = line_dy(l2) / line_dx(l2); 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[0] = l1[0]; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[1] = la * l1[0] + l2[1] - la * l2[0]; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (ldx_zero) { 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat ta = line_dy(l1) / line_dx(l1); 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[0] = l2[0]; 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[1] = ta * l2[0] + l1[1] - ta*l1[0]; 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat ta = line_dy(l1) / line_dx(l1); 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat la = line_dy(l2) / line_dx(l2); 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ta == la) 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NoIntersections; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x = ( - l2[1] + la * l2[0] + l1[1] - ta * l1[0] ) / (la - ta); 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[0] = x; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[1] = ta*(x - l1[0]) + l1[1]; 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (intersection_point) { 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org intersection_point[0] = isect[0]; 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org intersection_point[1] = isect[1]; 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE enum line_join_mode stroker_join_mode(struct stroker *s) 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(s->join_style) { 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_JOIN_MITER: 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return MiterJoin; 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_JOIN_ROUND: 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RoundJoin; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_JOIN_BEVEL: 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FlatJoin; 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FlatJoin; 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE enum line_join_mode stroker_cap_mode(struct stroker *s) 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(s->cap_style) { 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CAP_BUTT: 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FlatJoin; 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CAP_ROUND: 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RoundCap; 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CAP_SQUARE: 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SquareJoin; 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FlatJoin; 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_emit_move_to(struct stroker *stroker, VGfloat x, VGfloat y) 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmds = VG_MOVE_TO_ABS; 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[2] = {x, y}; 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_EMITS 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("emit move %f, %f\n", x, y); 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = stroker->back1_x; 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = stroker->back1_y; 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_x = x; 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_y = y; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(stroker->path, 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &cmds, &coords); 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_emit_line_to(struct stroker *stroker, VGfloat x, VGfloat y) 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmds = VG_LINE_TO_ABS; 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[2] = {x, y}; 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_EMITS 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("emit line %f, %f\n", x, y); 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = stroker->back1_x; 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = stroker->back1_y; 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_x = x; 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_y = y; 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(stroker->path, 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &cmds, &coords); 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_emit_curve_to(struct stroker *stroker, VGfloat px1, VGfloat py1, 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat px2, VGfloat py2, 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x, VGfloat y) 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGubyte cmds = VG_CUBIC_TO_ABS; 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[6] = {px1, py1, px2, py2, x, y}; 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_EMITS 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("emit curve %f, %f, %f, %f, %f, %f\n", px1, py1, 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px2, py2, x, y); 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (px2 == x && py2 == y) { 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (px1 == x && py1 == y) { 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = stroker->back1_x; 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = stroker->back1_y; 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = px1; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = py1; 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = px2; 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = py2; 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_x = x; 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_y = y; 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_append_data(stroker->path, 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &cmds, &coords); 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void create_round_join(struct stroker *stroker, 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x1, VGfloat y1, 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x2, VGfloat y2, 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat width, VGfloat height) 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix matrix; 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&matrix); 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*stroker_emit_line_to(stroker, nx, ny);*/ 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, VG_SCCWARC_TO, 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x1, y1, x2, y2, width/2, height/2, 0); 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_stroker_emit(&arc, stroker, &matrix); 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void create_joins(struct stroker *stroker, 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat focal_x, VGfloat focal_y, 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *next_line, enum line_join_mode join) 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_EMITS 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("create_joins: focal=[%f, %f], next_line=[%f, %f,%f, %f]\n", 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org focal_x, focal_y, 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[0], next_line[1], next_line[2], next_line[3]); 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if we're alredy connected do nothing */ 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(stroker->back1_x, next_line[0]) && 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(stroker->back1_y, next_line[1])) 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (join == FlatJoin) { 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat prev_line[] = {stroker->back2_x, stroker->back2_y, 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_x, stroker->back1_y}; 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat isect[2] = { 0 }; 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum intersection_type type = line_intersect(prev_line, next_line, isect); 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (join == SquareJoin) { 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset = stroker->stroke_width / 2; 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat l1[4] = {prev_line[0], 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[1], 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[2], 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[3]}; 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat l2[4] = {next_line[2], 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[3], 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[0], 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[1]}; 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(l1, line_dx(l1), line_dy(l1)); 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_set_length(l1, offset); 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(l2, line_dx(l2), line_dy(l2)); 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_set_length(l2, offset); 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, l1[2], l1[3]); 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, l2[2], l2[3]); 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, l2[0], l2[1]); 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (join == RoundJoin) { 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset = stroker->stroke_width / 2; 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat short_cut[4] = {prev_line[2], prev_line[3], 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[0], next_line[1]}; 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat angle = line_angles(prev_line, short_cut); 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == BoundedIntersection || 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (angle > 90 && !floatsEqual(angle, 90.f))) { 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_round_join(stroker, prev_line[2], prev_line[3], 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[0], next_line[1], 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset * 2, offset * 2); 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (join == RoundCap) { 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset = stroker->stroke_width / 2; 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat l1[4] = { prev_line[0], prev_line[1], 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[2], prev_line[3] }; 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat l2[4] = {focal_x, focal_y, 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[2], prev_line[3]}; 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(l1, line_dx(l1), line_dy(l1)); 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_set_length(l1, KAPPA * offset); 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* normal between prev_line and focal */ 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(l2, -line_dy(l2), line_dx(l2)); 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_set_length(l2, KAPPA * offset); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_curve_to(stroker, l1[2], l1[3], 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[2], l2[3], 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[0], l2[1]); 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[0] = l2[0]; 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[1] = l2[1]; 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[2] = l2[0] - line_dx(l2); 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[3] = l2[1] - line_dy(l2); 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(l1, next_line[0] - l1[0], next_line[1] - l1[1]); 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_curve_to(stroker, 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l2[2], l2[3], 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l1[2], l1[3], 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l1[0], l1[1]); 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (join == MiterJoin) { 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat miter_line[4] = {stroker->back1_x, stroker->back1_y, 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org isect[0], isect[1]}; 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat sl = (stroker->stroke_width * stroker->miter_limit); 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat inside_line[4] = {prev_line[2], prev_line[3], 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_line[0], next_line[1]}; 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat angle = line_angle_to(inside_line, prev_line); 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == BoundedIntersection || 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (angle > 90 && !floatsEqual(angle, 90.f))) { 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("f = %f, nl = %f, pl = %f, is = %f\n", 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org focal_x, next_line[0], 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_line[2], isect[0]);*/ 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NoIntersections || line_lengthv(miter_line) > sl) { 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, isect[0], isect[1]); 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, next_line[0], next_line[1]); 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"create_joins bad join style"); 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroker_add_segment(struct stroker *stroker, 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand cmd, 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VGfloat *coords, 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint num_coords) 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* skip duplicated points */ 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->segments->num_elements && 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->last_cmd == cmd) { 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *data = stroker->control_points->data; 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data += stroker->control_points->num_elements; 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data -= num_coords; 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (cmd) { 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(coords[0], data[0]) && 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], data[1])) 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(coords[0], data[0]) && 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], data[1])) 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(coords[0], data[0]) && 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], data[1]) && 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[2], data[2]) && 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[3], data[3]) && 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[4], data[4]) && 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[5], data[5])) 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(!"Invalid stroke segment"); 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (stroker->last_cmd == VG_CUBIC_TO_ABS && 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd == VG_LINE_TO_ABS) { 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *data = stroker->control_points->data; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data += stroker->control_points->num_elements; 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data -= 2; 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(coords[0], data[0]) && 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], data[1])) 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->last_cmd = cmd; 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(stroker->segments, &cmd, 1); 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_append_data(stroker->control_points, coords, num_coords); 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_move_to(struct stroker *stroker, VGfloat x, VGfloat y) 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[2] = {x, y}; 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_SEGMENTS 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("stroker_move_to(%f, %f)\n", x, y); 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->segments->num_elements > 0) 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->process_subpath(stroker); 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_reset(stroker->segments); 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_reset(stroker->control_points); 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_add_segment(stroker, VG_MOVE_TO_ABS, coords, 2); 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_line_to(struct stroker *stroker, VGfloat x, VGfloat y) 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[] = {x, y}; 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_SEGMENTS 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("stroker_line_to(%f, %f)\n", x, y); 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!stroker->segments->num_elements) 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_add_segment(stroker, VG_MOVE_TO_ABS, zero_coords, 2); 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_add_segment(stroker, VG_LINE_TO_ABS, coords, 2); 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_curve_to(struct stroker *stroker, VGfloat px1, VGfloat py1, 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat px2, VGfloat py2, 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat x, VGfloat y) 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[] = {px1, py1, 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px2, py2, 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x, y}; 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_SEGMENTS 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("stroker_curve_to(%f, %f, %f, %f, %f, %f)\n", 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org px1, py1, px2, py2, x, y); 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!stroker->segments->num_elements) 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_add_segment(stroker, VG_MOVE_TO_ABS, zero_coords, 2); 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_add_segment(stroker, VG_CUBIC_TO_ABS, coords, 6); 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGboolean is_segment_null(VGPathCommand cmd, 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *coords, 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *res) 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(cmd) { 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_MOVE_TO_ABS: 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_LINE_TO_ABS: 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return floatsEqual(coords[0], res[0]) && 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], res[1]); 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case VG_CUBIC_TO_ABS: 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return floatsEqual(coords[0], res[0]) && 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[1], res[1]) && 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[2], res[0]) && 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[3], res[1]) && 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[4], res[0]) && 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(coords[5], res[1]); 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic VGboolean vg_stroke_outline(struct stroke_iterator *it, 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct stroker *stroker, 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean cap_first, 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat *start_tangent) 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_OFFSET 16 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier offset_curves[MAX_OFFSET]; 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand first_element; 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat start[2], prev[2]; 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean first = VG_TRUE; 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset; 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_element = stroke_itr_command(it); 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first_element != VG_MOVE_TO_ABS) { 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_move_to(stroker, 0.f, 0.f); 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0] = 0.f; 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[1] = 0.f; 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(it, start); 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_DEBUG 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf(" -> (side) [%.2f, %.2f]\n", 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start[0], 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start[1]); 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0] = start[0]; 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[1] = start[1]; 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset = stroker->stroke_width / 2; 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!it->has_next(it)) { 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* single point */ 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (it->has_next(it)) { 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand cmd; 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8]; 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it->next(it); 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(it); 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(it, coords); 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmd == VG_LINE_TO_ABS) { 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line[4] = {prev[0], prev[1], coords[0], coords[1]}; 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat normal[4]; 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_normal(line, normal); 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_DEBUG 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("\n ---> (side) lineto [%.2f, %.2f]\n", coords[0], coords[1]); 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_set_length(normal, offset); 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(line, line_dx(normal), line_dy(normal)); 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if we are starting a new subpath, move to correct starting point */ 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first) { 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cap_first) 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, prev[0], prev[1], line, 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cap_mode(stroker)); 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_move_to(stroker, line[0], line[1]); 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(start_tangent, line, 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof(VGfloat) * 4); 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first = VG_FALSE; 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, prev[0], prev[1], line, 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_join_mode(stroker)); 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add the stroke for this line */ 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, line[2], line[3]); 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0] = coords[0]; 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[1] = coords[1]; 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (cmd == VG_CUBIC_TO_ABS) { 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_DEBUG 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("\n ---> (side) cubicTo [%.2f, %.2f]\n", 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[4], 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[5]); 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier bezier; 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int count; 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_init(&bezier, 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0], prev[1], coords[0], coords[1], 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coords[2], coords[3], coords[4], coords[5]); 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count = bezier_translate_by_normal(&bezier, 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset_curves, 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MAX_OFFSET, 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curve_threshold); 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (count) { 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if we are starting a new subpath, move to correct starting point */ 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat tangent[4]; 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bezier_start_tangent(&bezier, tangent); 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_translate(tangent, 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset_curves[0].x1 - bezier.x1, 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset_curves[0].y1 - bezier.y1); 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first) { 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat pt[2] = {offset_curves[0].x1, 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset_curves[0].y1}; 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cap_first) { 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, prev[0], prev[1], tangent, 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cap_mode(stroker)); 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_move_to(stroker, pt[0], pt[1]); 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_tangent[0] = tangent[0]; 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_tangent[1] = tangent[1]; 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_tangent[2] = tangent[2]; 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start_tangent[3] = tangent[3]; 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first = VG_FALSE; 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, prev[0], prev[1], tangent, 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_join_mode(stroker)); 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add these beziers */ 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < count; ++i) { 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct bezier *bez = &offset_curves[i]; 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_curve_to(stroker, 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez->x2, bez->y2, 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez->x3, bez->y3, 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bez->x4, bez->y4); 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0] = coords[4]; 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[1] = coords[5]; 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatsEqual(start[0], prev[0]) && 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org floatsEqual(start[1], prev[1])) { 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* closed subpath, join first and last point */ 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_DEBUG 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("\n stroker: closed subpath\n"); 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, prev[0], prev[1], start_tangent, 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_join_mode(stroker)); 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_TRUE; 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if STROKE_DEBUG 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("\n stroker: open subpath\n"); 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return VG_FALSE; 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef MAX_OFFSET 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void stroker_process_subpath(struct stroker *stroker) 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean fwclosed, bwclosed; 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat fw_start_tangent[4], bw_start_tangent[4]; 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct stroke_iterator fwit; 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct stroke_iterator bwit; 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(stroker->segments->num_elements > 0); 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(fw_start_tangent, 0, 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof(VGfloat)*4); 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(bw_start_tangent, 0, 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof(VGfloat)*4); 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_forward_iterator(&fwit, stroker->segments, 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->control_points); 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_backward_iterator(&bwit, stroker->segments, 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->control_points); 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(fwit.cmds[0] == VG_MOVE_TO_ABS); 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fwclosed = vg_stroke_outline(&fwit, stroker, VG_FALSE, fw_start_tangent); 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bwclosed = vg_stroke_outline(&bwit, stroker, !fwclosed, bw_start_tangent); 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!bwclosed) 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org create_joins(stroker, 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fwit.coords[0], fwit.coords[1], fw_start_tangent, 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cap_mode(stroker)); 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* hack to handle the requirement of the VG spec that says that strokes 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of len==0 that have butt cap or round cap still need 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to be rendered. (8.7.4 Stroke Generation) */ 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->segments->num_elements <= 3) { 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand cmd; 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat data[8], coords[8]; 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct stroke_iterator *it = &fwit; 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_forward_iterator(it, stroker->segments, 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->control_points); 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(it); 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(it, coords); 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmd != VG_MOVE_TO_ABS) { 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(data, 0, sizeof(VGfloat) * 8); 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!is_segment_null(cmd, coords, data)) 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[0] = coords[0]; 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] = coords[1]; 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (it->has_next(it)) { 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it->next(it); 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(it); 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(it, coords); 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!is_segment_null(cmd, coords, data)) 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* generate the square/round cap */ 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->cap_style == VG_CAP_SQUARE) { 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset = stroker->stroke_width / 2; 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_move_to(stroker, data[0] - offset, 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] - offset); 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, data[0] + offset, 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] - offset); 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, data[0] + offset, 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] + offset); 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, data[0] - offset, 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] + offset); 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_line_to(stroker, data[0] - offset, 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data[1] - offset); 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (stroker->cap_style == VG_CAP_ROUND) { 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat offset = stroker->stroke_width / 2; 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat cx = data[0], cy = data[1]; 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { /*circle */ 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct arc arc; 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct matrix matrix; 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matrix_load_identity(&matrix); 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_emit_move_to(stroker, cx + offset, cy); 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, VG_SCCWARC_TO, 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx + offset, cy, 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx - offset, cy, 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, offset, 0); 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_stroker_emit(&arc, stroker, &matrix); 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_init(&arc, VG_SCCWARC_TO, 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx - offset, cy, 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cx + offset, cy, 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset, offset, 0); 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arc_stroker_emit(&arc, stroker, &matrix); 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE VGfloat dash_pattern(struct dash_stroker *stroker, 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint idx) 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->dash_pattern[idx] < 0) 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0.f; 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return stroker->dash_pattern[idx]; 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void dash_stroker_process_subpath(struct stroker *str) 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dash_stroker *stroker = (struct dash_stroker *)str; 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat sum_length = 0; 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint i; 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint idash = 0; 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat pos = 0; 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat elen = 0; 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat doffset = stroker->dash_phase; 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat estart = 0; 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat estop = 0; 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat cline[4]; 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct stroke_iterator it; 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat prev[2]; 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat move_to_pos[2]; 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat line_to_pos[2]; 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean has_move_to = VG_FALSE; 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_flat_iterator(&it, stroker->base.segments, 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.control_points); 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(&it, prev); 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_to_pos[0] = prev[0]; 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_to_pos[1] = prev[1]; 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(stroker->dash_pattern_num > 0); 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < stroker->dash_pattern_num; ++i) { 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sum_length += dash_pattern(stroker, i); 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (floatIsZero(sum_length)) { 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org doffset -= floorf(doffset / sum_length) * sum_length; 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (!floatIsZero(doffset) && doffset >= dash_pattern(stroker, idash)) { 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org doffset -= dash_pattern(stroker, idash); 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org idash = (idash + 1) % stroker->dash_pattern_num; 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (it.has_next(&it)) { 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGPathCommand cmd; 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat coords[8]; 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean done; 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it.next(&it); 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmd = stroke_itr_command(&it); 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroke_itr_coords(&it, coords); 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(cmd == VG_LINE_TO_ABS); 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cline[0] = prev[0]; 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cline[1] = prev[1]; 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cline[2] = coords[0]; 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cline[3] = coords[1]; 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elen = line_lengthv(cline); 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org estop = estart + elen; 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org done = pos >= estop; 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (!done) { 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat p2[2]; 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGint idash_incr = 0; 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGboolean has_offset = doffset > 0; 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VGfloat dpos = pos + dash_pattern(stroker, idash) - doffset - estart; 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(dpos >= 0); 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dpos > elen) { /* dash extends this line */ 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org doffset = dash_pattern(stroker, idash) - (dpos - elen); 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pos = estop; 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org done = VG_TRUE; 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p2[0] = cline[2]; 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p2[1] = cline[3]; 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { /* Dash is on this line */ 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_point_at(cline, dpos/elen, p2); 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pos = dpos + estart; 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org done = pos >= estop; 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org idash_incr = 1; 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org doffset = 0; 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (idash % 2 == 0) { 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_to_pos[0] = p2[0]; 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org line_to_pos[1] = p2[1]; 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!has_offset || !has_move_to) { 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_move_to(&stroker->stroker, move_to_pos[0], move_to_pos[1]); 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org has_move_to = VG_TRUE; 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_line_to(&stroker->stroker, line_to_pos[0], line_to_pos[1]); 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_to_pos[0] = p2[0]; 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_to_pos[1] = p2[1]; 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org idash = (idash + idash_incr) % stroker->dash_pattern_num; 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org estart = estop; 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[0] = coords[0]; 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev[1] = coords[1]; 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (it.curve_poly) { 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org polygon_destroy(it.curve_poly); 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it.curve_poly = 0; 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.path = stroker->stroker.path; 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void default_begin(struct stroker *stroker) 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_reset(stroker->segments); 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_reset(stroker->control_points); 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void default_end(struct stroker *stroker) 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stroker->segments->num_elements > 0) 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->process_subpath(stroker); 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void dash_stroker_begin(struct stroker *stroker) 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dash_stroker *dasher = 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (struct dash_stroker *)stroker; 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default_begin(&dasher->stroker); 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default_begin(stroker); 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void dash_stroker_end(struct stroker *stroker) 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dash_stroker *dasher = 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (struct dash_stroker *)stroker; 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default_end(stroker); 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default_end(&dasher->stroker); 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_init(struct stroker *stroker, 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_state *state) 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->stroke_width = state->stroke.line_width.f; 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->miter_limit = state->stroke.miter_limit.f; 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->cap_style = state->stroke.cap_style; 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->join_style = state->stroke.join_style; 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->begin = default_begin; 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->process_subpath = stroker_process_subpath; 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->end = default_end; 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->segments = array_create(sizeof(VGubyte)); 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->control_points = array_create(sizeof(VGfloat)); 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_x = 0; 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back1_y = 0; 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_x = 0; 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->back2_y = 0; 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->path = path_create(VG_PATH_DATATYPE_F, 1.0f, 0.0f, 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, VG_PATH_CAPABILITY_ALL); 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Initialize with an invalid value */ 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->last_cmd = (VGPathCommand)0; 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid dash_stroker_init(struct stroker *str, 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vg_state *state) 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dash_stroker *stroker = (struct dash_stroker *)str; 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_init(str, state); 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_init(&stroker->stroker, state); 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int real_num = state->stroke.dash_pattern_num; 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (real_num % 2)/* if odd, ignore the last one */ 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --real_num; 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < real_num; ++i) 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->dash_pattern[i] = state->stroke.dash_pattern[i].f; 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->dash_pattern_num = real_num; 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->dash_phase = state->stroke.dash_phase.f; 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->dash_phase_reset = state->stroke.dash_phase_reset; 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.begin = dash_stroker_begin; 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.process_subpath = dash_stroker_process_subpath; 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.end = dash_stroker_end; 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(stroker->base.path); 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->base.path = NULL; 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_begin(struct stroker *stroker) 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->begin(stroker); 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_end(struct stroker *stroker) 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker->end(stroker); 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid stroker_cleanup(struct stroker *stroker) 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(stroker->segments); 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array_destroy(stroker->control_points); 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid dash_stroker_cleanup(struct dash_stroker *stroker) 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if stroker->base.path is null means we never 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * processed a valid path so delete the temp one 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we already created */ 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!stroker->base.path) 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org path_destroy(stroker->stroker.path); 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cleanup(&stroker->stroker); 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stroker_cleanup((struct stroker*)stroker); 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1352