Skip to content

Commit

Permalink
gral_draw_context_stroke_linear_gradient
Browse files Browse the repository at this point in the history
  • Loading branch information
eyelash committed Nov 6, 2024
1 parent 02f1145 commit de40885
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
1 change: 1 addition & 0 deletions gral.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ void gral_draw_context_curve_to(struct gral_draw_context *draw_context, float x1
void gral_draw_context_fill(struct gral_draw_context *draw_context, float red, float green, float blue, float alpha);
void gral_draw_context_fill_linear_gradient(struct gral_draw_context *draw_context, float start_x, float start_y, float end_x, float end_y, struct gral_gradient_stop const *stops, int count);
void gral_draw_context_stroke(struct gral_draw_context *draw_context, float line_width, float red, float green, float blue, float alpha);
void gral_draw_context_stroke_linear_gradient(struct gral_draw_context *draw_context, float line_width, float start_x, float start_y, float end_x, float end_y, struct gral_gradient_stop const *stops, int count);
void gral_draw_context_draw_clipped(struct gral_draw_context *draw_context, void (*callback)(struct gral_draw_context *draw_context, void *user_data), void *user_data);
void gral_draw_context_draw_transformed(struct gral_draw_context *draw_context, float a, float b, float c, float d, float e, float f, void (*callback)(struct gral_draw_context *draw_context, void *user_data), void *user_data);

Expand Down
14 changes: 14 additions & 0 deletions gral_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,20 @@ void gral_draw_context_stroke(struct gral_draw_context *draw_context, float line
cairo_stroke((cairo_t *)draw_context);
}

void gral_draw_context_stroke_linear_gradient(struct gral_draw_context *draw_context, float line_width, float start_x, float start_y, float end_x, float end_y, struct gral_gradient_stop const *stops, int count) {
cairo_set_line_width((cairo_t *)draw_context, line_width);
cairo_set_line_cap((cairo_t *)draw_context, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join((cairo_t *)draw_context, CAIRO_LINE_JOIN_ROUND);
cairo_pattern_t *gradient = cairo_pattern_create_linear(start_x, start_y, end_x, end_y);
int i;
for (i = 0; i < count; i++) {
cairo_pattern_add_color_stop_rgba(gradient, stops[i].position, stops[i].red, stops[i].green, stops[i].blue, stops[i].alpha);
}
cairo_set_source((cairo_t *)draw_context, gradient);
cairo_stroke((cairo_t *)draw_context);
cairo_pattern_destroy(gradient);
}

void gral_draw_context_draw_clipped(struct gral_draw_context *draw_context, void (*callback)(struct gral_draw_context *draw_context, void *user_data), void *user_data) {
cairo_save((cairo_t *)draw_context);
cairo_clip((cairo_t *)draw_context);
Expand Down
8 changes: 8 additions & 0 deletions gral_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,14 @@ void gral_draw_context_stroke(struct gral_draw_context *draw_context, float line
CGContextStrokePath((CGContextRef)draw_context);
}

void gral_draw_context_stroke_linear_gradient(struct gral_draw_context *draw_context, float line_width, float start_x, float start_y, float end_x, float end_y, struct gral_gradient_stop const *stops, int count) {
CGContextSetLineWidth((CGContextRef)draw_context, line_width);
CGContextSetLineCap((CGContextRef)draw_context, kCGLineCapRound);
CGContextSetLineJoin((CGContextRef)draw_context, kCGLineJoinRound);
CGContextReplacePathWithStrokedPath((CGContextRef)draw_context);
gral_draw_context_fill_linear_gradient(draw_context, start_x, start_y, end_y, end_y, stops, count);
}

void gral_draw_context_draw_clipped(struct gral_draw_context *draw_context, void (*callback)(struct gral_draw_context *draw_context, void *user_data), void *user_data) {
CGContextSaveGState((CGContextRef)draw_context);
CGContextClip((CGContextRef)draw_context);
Expand Down
40 changes: 31 additions & 9 deletions gral_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,19 @@ void gral_draw_context_curve_to(gral_draw_context *draw_context, float x1, float
draw_context->sink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(x1, y1), D2D1::Point2F(x2, y2), point));
}

static ComPointer<ID2D1LinearGradientBrush> create_linear_gradient_brush(gral_draw_context *draw_context, float start_x, float start_y, float end_x, float end_y, gral_gradient_stop const *stops, int count) {
Buffer<D2D1_GRADIENT_STOP> gradient_stops(count);
for (int i = 0; i < count; i++) {
gradient_stops[i].position = stops[i].position;
gradient_stops[i].color = D2D1::ColorF(stops[i].red, stops[i].green, stops[i].blue, stops[i].alpha);
}
ComPointer<ID2D1GradientStopCollection> gradient_stop_collection;
draw_context->target->CreateGradientStopCollection(gradient_stops, count, &gradient_stop_collection);
ComPointer<ID2D1LinearGradientBrush> brush;
draw_context->target->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(start_x, start_y), D2D1::Point2F(end_x, end_y)), gradient_stop_collection, &brush);
return brush;
}

void gral_draw_context_fill(gral_draw_context *draw_context, float red, float green, float blue, float alpha) {
if (draw_context->open) {
draw_context->sink->EndFigure(D2D1_FIGURE_END_OPEN);
Expand All @@ -846,15 +859,7 @@ void gral_draw_context_fill_linear_gradient(gral_draw_context *draw_context, flo
}
draw_context->sink->Close();

Buffer<D2D1_GRADIENT_STOP> gradient_stops(count);
for (int i = 0; i < count; i++) {
gradient_stops[i].position = stops[i].position;
gradient_stops[i].color = D2D1::ColorF(stops[i].red, stops[i].green, stops[i].blue, stops[i].alpha);
}
ComPointer<ID2D1GradientStopCollection> gradient_stop_collection;
draw_context->target->CreateGradientStopCollection(gradient_stops, count, &gradient_stop_collection);
ComPointer<ID2D1LinearGradientBrush> brush;
draw_context->target->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(start_x, start_y), D2D1::Point2F(end_x, end_y)), gradient_stop_collection, &brush);
ComPointer<ID2D1LinearGradientBrush> brush = create_linear_gradient_brush(draw_context, start_x, start_y, end_x, end_y, stops, count);
draw_context->target->FillGeometry(draw_context->path, brush);

draw_context->sink->Release();
Expand Down Expand Up @@ -882,6 +887,23 @@ void gral_draw_context_stroke(gral_draw_context *draw_context, float line_width,
draw_context->sink->SetFillMode(D2D1_FILL_MODE_WINDING);
}

void gral_draw_context_stroke_linear_gradient(gral_draw_context *draw_context, float line_width, float start_x, float start_y, float end_x, float end_y, gral_gradient_stop const *stops, int count) {
if (draw_context->open) {
draw_context->sink->EndFigure(D2D1_FIGURE_END_OPEN);
draw_context->open = false;
}
draw_context->sink->Close();

ComPointer<ID2D1LinearGradientBrush> brush = create_linear_gradient_brush(draw_context, start_x, start_y, end_x, end_y, stops, count);
draw_context->target->DrawGeometry(draw_context->path, brush, line_width, stroke_style);

draw_context->sink->Release();
draw_context->path->Release();
factory->CreatePathGeometry(&draw_context->path);
draw_context->path->Open(&draw_context->sink);
draw_context->sink->SetFillMode(D2D1_FILL_MODE_WINDING);
}

void gral_draw_context_draw_clipped(gral_draw_context *draw_context, void (*callback)(gral_draw_context *draw_context, void *user_data), void *user_data) {
if (draw_context->open) {
draw_context->sink->EndFigure(D2D1_FIGURE_END_OPEN);
Expand Down

0 comments on commit de40885

Please sign in to comment.