Skip to content

Commit

Permalink
LibWeb: Draw dashed and dotted lines in Skia painter
Browse files Browse the repository at this point in the history
Use the `SkDashPathEffect` path effect, to implement dashed and dotted
line styles.
  • Loading branch information
BenJilks authored and kalenikaliaksandr committed Jul 12, 2024
1 parent 24bed02 commit a8c1bb0
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include <core/SkMaskFilter.h>
#include <core/SkPath.h>
#include <core/SkPathBuilder.h>
#include <core/SkPathEffect.h>
#include <core/SkRRect.h>
#include <core/SkSurface.h>
#include <effects/SkDashPathEffect.h>
#include <effects/SkGradientShader.h>
#include <effects/SkImageFilters.h>
#include <gpu/GrDirectContext.h>
Expand Down Expand Up @@ -923,9 +925,44 @@ CommandResult DisplayListPlayerSkia::draw_line(DrawLine const& command)
auto from = to_skia_point(command.from);
auto to = to_skia_point(command.to);
auto& canvas = surface().canvas();

SkPaint paint;
paint.setStrokeWidth(command.thickness);
paint.setColor(to_skia_color(command.color));

switch (command.style) {
case Gfx::LineStyle::Solid:
break;
case Gfx::LineStyle::Dotted: {
auto length = command.to.distance_from(command.from);
auto dot_count = floor(length / (static_cast<float>(command.thickness) * 2));
auto interval = length / dot_count;
SkScalar intervals[] = { 0, interval };
paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
paint.setStrokeCap(SkPaint::Cap::kRound_Cap);

// NOTE: As Skia doesn't render a dot exactly at the end of a line, we need
// to extend it by less then an interval.
auto direction = to - from;
direction.normalize();
to += direction * (interval / 2.0f);
break;
}
case Gfx::LineStyle::Dashed: {
auto length = command.to.distance_from(command.from) + command.thickness;
auto dash_count = floor(length / static_cast<float>(command.thickness) / 4) * 2 + 1;
auto interval = length / dash_count;
SkScalar intervals[] = { interval, interval };
paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));

auto direction = to - from;
direction.normalize();
from -= direction * (command.thickness / 2.0f);
to += direction * (command.thickness / 2.0f);
break;
}
}

canvas.drawLine(from, to, paint);
return CommandResult::Continue;
}
Expand Down

0 comments on commit a8c1bb0

Please sign in to comment.