Skip to content

Commit

Permalink
Add dash-array #14
Browse files Browse the repository at this point in the history
  • Loading branch information
sammycage committed Nov 21, 2020
1 parent ec669c0 commit a62da25
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 6 deletions.
1 change: 1 addition & 0 deletions 3rdparty/plutovg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/plutovg-geometry.c"
"${CMAKE_CURRENT_LIST_DIR}/plutovg-blend.c"
"${CMAKE_CURRENT_LIST_DIR}/plutovg-rle.c"
"${CMAKE_CURRENT_LIST_DIR}/plutovg-dash.c"
)

target_include_directories(lunasvg
Expand Down
109 changes: 109 additions & 0 deletions 3rdparty/plutovg/plutovg-dash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "plutovg-private.h"

#include <math.h>

plutovg_dash_t* plutovg_dash_create(double offset, const double* data, int size)
{
if(data==NULL || size==0)
return NULL;

plutovg_dash_t* dash = malloc(sizeof(plutovg_dash_t));
dash->offset = offset;
dash->data = malloc((size_t)size * sizeof(double));
dash->size = size;
memcpy(dash->data, data, (size_t)size * sizeof(double));
return dash;
}

plutovg_dash_t* plutovg_dash_clone(const plutovg_dash_t* dash)
{
if(dash==NULL)
return NULL;

return plutovg_dash_create(dash->offset, dash->data, dash->size);
}

void plutovg_dash_destroy(plutovg_dash_t* dash)
{
if(dash==NULL)
return;

free(dash->data);
free(dash);
}

plutovg_path_t* plutovg_dash_path(const plutovg_dash_t* dash, const plutovg_path_t* path)
{
plutovg_path_t* flat = plutovg_path_clone_flat(path);
plutovg_path_t* result = plutovg_path_create();

plutovg_array_ensure(result->elements, flat->elements.size);
plutovg_array_ensure(result->points, flat->points.size);

int toggle = 1;
int offset = 0;
double phase = dash->offset;
while(phase >= dash->data[offset])
{
toggle = !toggle;
phase -= dash->data[offset];
if(++offset==dash->size) offset = 0;
}

plutovg_path_element_t* elements = flat->elements.data;
plutovg_path_element_t* end = elements + flat->elements.size;
plutovg_point_t* points = flat->points.data;
while(elements < end)
{
int itoggle = toggle;
int ioffset = offset;
double iphase = phase;

double x0 = points->x;
double y0 = points->y;

if(itoggle)
plutovg_path_move_to(result, x0, y0);

++elements;
++points;

while(elements < end && *elements==plutovg_path_element_line_to)
{
double dx = points->x - x0;
double dy = points->y - y0;
double dist0 = sqrt(dx*dx + dy*dy);
double dist1 = 0;
while(dist0 - dist1 > dash->data[ioffset] - iphase)
{
dist1 += dash->data[ioffset] - iphase;
double a = dist1 / dist0;
double x = x0 + a * dx;
double y = y0 + a * dy;

if(itoggle)
plutovg_path_line_to(result, x, y);
else
plutovg_path_move_to(result, x, y);

itoggle = !itoggle;
iphase = 0;
if(++ioffset==dash->size) ioffset = 0;
}

iphase += dist0 - dist1;

x0 = points->x;
y0 = points->y;

if(itoggle)
plutovg_path_line_to(result, x0, y0);

++elements;
++points;
}
}

plutovg_path_destroy(flat);
return result;
}
2 changes: 1 addition & 1 deletion 3rdparty/plutovg/plutovg-geometry.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ static void flatten_curve(plutovg_path_t* path, const plutovg_point_t* p0, const
else
{
d = fabs(b->x1 - b->x2) + fabs(b->y1 - b->y2) + fabs(b->x1 - b->x3) + fabs(b->y1 - b->y3);
l = 1.;
l = 1.0;
}

if(d < threshold*l || b == beziers + 31)
Expand Down
20 changes: 16 additions & 4 deletions 3rdparty/plutovg/plutovg-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,18 @@ typedef struct {
int h;
} plutovg_rle_t;

typedef struct {
double offset;
double* data;
int size;
} plutovg_dash_t;

typedef struct {
double width;
double miterlimit;
plutovg_line_cap_t cap;
plutovg_line_join_t join;
plutovg_dash_t* dash;
} plutovg_stroke_data_t;

typedef struct plutovg_state {
Expand All @@ -103,10 +110,6 @@ typedef struct plutovg_state {
struct plutovg_state* next;
} plutovg_state_t;

plutovg_state_t* plutovg_state_create(void);
plutovg_state_t* plutovg_state_clone(const plutovg_state_t* state);
void plutovg_state_destroy(plutovg_state_t* state);

struct plutovg {
int ref;
plutovg_surface_t* surface;
Expand All @@ -122,6 +125,15 @@ plutovg_rle_t* plutovg_rle_intersection(const plutovg_rle_t* a, const plutovg_rl
void plutovg_rle_clip_path(plutovg_rle_t* rle, const plutovg_rle_t* clip);
plutovg_rle_t* plutovg_rle_clone(const plutovg_rle_t* rle);

plutovg_dash_t* plutovg_dash_create(double offset, const double* data, int size);
plutovg_dash_t* plutovg_dash_clone(const plutovg_dash_t* dash);
void plutovg_dash_destroy(plutovg_dash_t* dash);
plutovg_path_t* plutovg_dash_path(const plutovg_dash_t* dash, const plutovg_path_t* path);

plutovg_state_t* plutovg_state_create(void);
plutovg_state_t* plutovg_state_clone(const plutovg_state_t* state);
void plutovg_state_destroy(plutovg_state_t* state);

void plutovg_blend(plutovg_t* pluto, const plutovg_rle_t* rle);
void plutovg_blend_color(plutovg_t* pluto, const plutovg_rle_t* rle, const plutovg_color_t* color);
void plutovg_blend_gradient(plutovg_t* pluto, const plutovg_rle_t* rle, const plutovg_gradient_t* gradient);
Expand Down
10 changes: 9 additions & 1 deletion 3rdparty/plutovg/plutovg-rle.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ static SW_FT_Outline* sw_ft_outline_convert(const plutovg_path_t* path, const pl
return outline;
}

static SW_FT_Outline* sw_ft_outline_convert_dash(const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_dash_t* dash)
{
plutovg_path_t* dashed = plutovg_dash_path(dash, path);
SW_FT_Outline* outline = sw_ft_outline_convert(dashed, matrix);
plutovg_path_destroy(dashed);
return outline;
}

static void generation_callback(int count, const SW_FT_Span* spans, void* user)
{
plutovg_rle_t* rle = user;
Expand Down Expand Up @@ -172,7 +180,7 @@ plutovg_rle_t* plutovg_rasterize(const plutovg_path_t* path, const plutovg_matri

if(stroke)
{
SW_FT_Outline* outline = sw_ft_outline_convert(path, matrix);
SW_FT_Outline* outline = stroke->dash ? sw_ft_outline_convert_dash(path, matrix, stroke->dash) : sw_ft_outline_convert(path, matrix);
SW_FT_Stroker_LineCap ftCap;
SW_FT_Stroker_LineJoin ftJoin;
SW_FT_Fixed ftWidth;
Expand Down
9 changes: 9 additions & 0 deletions 3rdparty/plutovg/plutovg.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ plutovg_state_t* plutovg_state_create(void)
state->stroke.miterlimit = 4.0;
state->stroke.cap = plutovg_line_cap_butt;
state->stroke.join = plutovg_line_join_miter;
state->stroke.dash = NULL;
state->op = plutovg_operator_src_over;
state->opacity = 1.0;
state->next = NULL;
Expand All @@ -98,6 +99,7 @@ plutovg_state_t* plutovg_state_clone(const plutovg_state_t* state)
newstate->stroke.miterlimit = state->stroke.miterlimit;
newstate->stroke.cap = state->stroke.cap;
newstate->stroke.join = state->stroke.join;
newstate->stroke.dash = plutovg_dash_clone(state->stroke.dash);
newstate->op = state->op;
newstate->opacity = state->opacity;
newstate->next = NULL;
Expand All @@ -108,6 +110,7 @@ void plutovg_state_destroy(plutovg_state_t* state)
{
plutovg_rle_destroy(state->clippath);
plutovg_paint_destroy(state->source);
plutovg_dash_destroy(state->stroke.dash);
free(state);
}

Expand Down Expand Up @@ -276,6 +279,12 @@ void plutovg_set_miter_limit(plutovg_t* pluto, double limit)
pluto->state->stroke.miterlimit = limit;
}

void plutovg_set_dash(plutovg_t* pluto, double offset, const double* data, int size)
{
plutovg_dash_destroy(pluto->state->stroke.dash);
pluto->state->stroke.dash = plutovg_dash_create(offset, data, size);
}

double plutovg_get_line_width(const plutovg_t* pluto)
{
return pluto->state->stroke.width;
Expand Down
1 change: 1 addition & 0 deletions 3rdparty/plutovg/plutovg.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ void plutovg_set_line_width(plutovg_t* pluto, double width);
void plutovg_set_line_cap(plutovg_t* pluto, plutovg_line_cap_t cap);
void plutovg_set_line_join(plutovg_t* pluto, plutovg_line_join_t join);
void plutovg_set_miter_limit(plutovg_t* pluto, double limit);
void plutovg_set_dash(plutovg_t* pluto, double offset, const double* data, int size);
double plutovg_get_line_width(const plutovg_t* pluto);
plutovg_line_cap_t plutovg_get_line_cap(const plutovg_t* pluto);
plutovg_line_join_t plutovg_get_line_join(const plutovg_t* pluto);
Expand Down
1 change: 1 addition & 0 deletions source/graphics/canvasimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ void CanvasImpl::draw(const Path& path, const AffineTransform& matrix, WindRule
plutovg_set_line_cap(m_pluto, to_plutovg_line_cap(strokeData.cap()));
plutovg_set_line_join(m_pluto, to_plutovg_line_join(strokeData.join()));
plutovg_set_line_width(m_pluto, strokeData.width());
plutovg_set_dash(m_pluto, strokeData.dashOffset(), strokeData.dash().data(), int(strokeData.dash().size()));
plutovg_set_source(m_pluto, paint);
plutovg_stroke_preserve(m_pluto);
plutovg_paint_destroy(paint);
Expand Down

0 comments on commit a62da25

Please sign in to comment.