1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Anti-Grain Geometry - Version 2.3 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission to copy, use, modify, sell and distribute this software 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is granted provided this copyright notice appears in all copies. 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This software is provided "as is" without express or implied 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// warranty, and with no claim as to its suitability for any purpose. 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Contact: mcseem@antigrain.com 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// mcseemagg@yahoo.com 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// http://www.antigrain.com 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Stroke math 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_STROKE_MATH_INCLUDED 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_STROKE_MATH_INCLUDED 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "agg_math.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "agg_vertex_sequence.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace agg 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum line_cap_e { 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov butt_cap, 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov square_cap, 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov round_cap 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum line_join_e { 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_join = 0, 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_join_revert = 1, 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_join_round = 4, 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov round_join = 2, 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bevel_join = 3 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum inner_join_e { 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_bevel, 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_miter, 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_jag, 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_round 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_FLOAT stroke_theta = 1.0f / 1000.0f; 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexConsumer> 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid stroke_calc_arc(VertexConsumer& out_vertices, 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT x, FX_FLOAT y, 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx1, FX_FLOAT dy1, 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx2, FX_FLOAT dy2, 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT width, 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT approximation_scale) 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef typename VertexConsumer::value_type coord_type; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT a1 = FXSYS_atan2(dy1, dx1); 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT a2 = FXSYS_atan2(dy2, dx2); 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT da = a1 - a2; 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bool ccw = da > 0 && da < FX_PI; 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(width < 0) { 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = -width; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov da = FXSYS_acos(FXSYS_Div(width, width + FXSYS_Div(1.0f / 8, approximation_scale))) * 2; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(x + dx1, y + dy1)); 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(!ccw) { 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(a1 > a2) { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a2 += 2 * FX_PI; 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a2 -= da / 4; 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 += da; 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(a1 < a2) { 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y + FXSYS_Mul(width, FXSYS_sin(a1)))); 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 += da; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(a1 < a2) { 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a2 -= 2 * FX_PI; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a2 += da / 4; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 -= da; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(a1 > a2) { 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(x + FXSYS_Mul(width, FXSYS_cos(a1)), 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y + FXSYS_Mul(width, FXSYS_sin(a1)))); 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 -= da; 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(x + dx2, y + dy2)); 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexConsumer> 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid stroke_calc_miter(VertexConsumer& out_vertices, 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v0, 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v1, 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v2, 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx1, FX_FLOAT dy1, 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx2, FX_FLOAT dy2, 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT width, 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_join_e line_join, 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT miter_limit, 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT approximation_scale) 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef typename VertexConsumer::value_type coord_type; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT xi = v1.x; 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT yi = v1.y; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bool miter_limit_exceeded = true; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(calc_intersection(v0.x + dx1, v0.y - dy1, 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.x + dx1, v1.y - dy1, 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.x + dx2, v1.y - dy2, 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v2.x + dx2, v2.y - dy2, 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &xi, &yi)) { 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT d1 = calc_distance(v1.x, v1.y, xi, yi); 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT lim = FXSYS_Mul(width, miter_limit); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(d1 <= lim) { 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(xi, yi)); 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_limit_exceeded = false; 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT x2 = v1.x + dx1; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT y2 = v1.y - dy1; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((FXSYS_Mul(x2 - v0.x, dy1) - FXSYS_Mul(v0.y - y2, dx1) < 0) != 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FXSYS_Mul(x2 - v2.x, dy1) - FXSYS_Mul(v2.y - y2, dx1) < 0)) { 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_limit_exceeded = false; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(miter_limit_exceeded) { 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch(line_join) { 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case miter_join_revert: 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case miter_join_round: 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_arc(out_vertices, 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.x, v1.y, dx1, -dy1, dx2, -dy2, 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, approximation_scale); 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1 + FXSYS_Mul(dy1, miter_limit), 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.y - dy1 + FXSYS_Mul(dx1, miter_limit))); 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2 - FXSYS_Mul(dy2, miter_limit), 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.y - dy2 - FXSYS_Mul(dx2, miter_limit))); 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexConsumer> 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid stroke_calc_cap(VertexConsumer& out_vertices, 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v0, 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v1, 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT len, 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_cap_e line_cap, 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT width, 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT approximation_scale) 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef typename VertexConsumer::value_type coord_type; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.remove_all(); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx1 = FXSYS_Div(v1.y - v0.y, len); 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dy1 = FXSYS_Div(v1.x - v0.x, len); 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx2 = 0; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dy2 = 0; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx1 = FXSYS_Mul(dx1, width); 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy1 = FXSYS_Mul(dy1, width); 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(line_cap != round_cap) { 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(line_cap == square_cap) { 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx2 = dy1; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy2 = dx1; 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2)); 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2)); 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT a1 = FXSYS_atan2(dy1, -dx1); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT a2 = a1 + FX_PI; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT da = FXSYS_acos(FXSYS_Div(width, width + 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_Div(1.0f / 8, approximation_scale))) * 2; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v0.x - dx1, v0.y + dy1)); 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 += da; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a2 -= da / 4; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(a1 < a2) { 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v0.x + FXSYS_Mul(width, FXSYS_cos(a1)), 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v0.y + FXSYS_Mul(width, FXSYS_sin(a1)))); 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a1 += da; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class VertexConsumer> 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid stroke_calc_join(VertexConsumer& out_vertices, 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v0, 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v1, 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const vertex_dist& v2, 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT len1, 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT len2, 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT width, 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_join_e line_join, 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_join_e inner_join, 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT miter_limit, 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT inner_miter_limit, 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT approximation_scale) 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef typename VertexConsumer::value_type coord_type; 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dx1, dy1, dx2, dy2; 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx1 = FXSYS_MulDiv(width, v1.y - v0.y, len1); 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy1 = FXSYS_MulDiv(width, v1.x - v0.x, len1); 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx2 = FXSYS_MulDiv(width, v2.y - v1.y, len2); 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy2 = FXSYS_MulDiv(width, v2.x - v1.x, len2); 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.remove_all(); 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0) { 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch(inner_join) { 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case inner_miter: 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_miter(out_vertices, 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v0, v1, v2, dx1, dy1, dx2, dy2, 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_join_revert, 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_miter_limit, 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1.0f); 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case inner_jag: 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case inner_round: { 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT d = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2); 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(d < len1 * len1 && d < len2 * len2) { 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_miter(out_vertices, 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v0, v1, v2, dx1, dy1, dx2, dy2, 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_join_revert, 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inner_miter_limit, 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1.0f); 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(inner_join == inner_jag) { 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x, v1.y )); 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x, v1.y )); 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_arc(out_vertices, 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.x, v1.y, dx2, -dy2, dx1, -dy1, 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, approximation_scale); 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x, v1.y )); 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch(line_join) { 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case miter_join: 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case miter_join_revert: 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case miter_join_round: 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_miter(out_vertices, 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v0, v1, v2, dx1, dy1, dx2, dy2, 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_join, 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov miter_limit, 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov approximation_scale); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case round_join: 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_calc_arc(out_vertices, 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v1.x, v1.y, dx1, -dy1, dx2, -dy2, 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width, approximation_scale); 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 273