Skip to content

Commit a8c1bb0

Browse files
BenJilkskalenikaliaksandr
authored andcommitted
LibWeb: Draw dashed and dotted lines in Skia painter
Use the `SkDashPathEffect` path effect, to implement dashed and dotted line styles.
1 parent 24bed02 commit a8c1bb0

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include <core/SkMaskFilter.h>
1414
#include <core/SkPath.h>
1515
#include <core/SkPathBuilder.h>
16+
#include <core/SkPathEffect.h>
1617
#include <core/SkRRect.h>
1718
#include <core/SkSurface.h>
19+
#include <effects/SkDashPathEffect.h>
1820
#include <effects/SkGradientShader.h>
1921
#include <effects/SkImageFilters.h>
2022
#include <gpu/GrDirectContext.h>
@@ -923,9 +925,44 @@ CommandResult DisplayListPlayerSkia::draw_line(DrawLine const& command)
923925
auto from = to_skia_point(command.from);
924926
auto to = to_skia_point(command.to);
925927
auto& canvas = surface().canvas();
928+
926929
SkPaint paint;
927930
paint.setStrokeWidth(command.thickness);
928931
paint.setColor(to_skia_color(command.color));
932+
933+
switch (command.style) {
934+
case Gfx::LineStyle::Solid:
935+
break;
936+
case Gfx::LineStyle::Dotted: {
937+
auto length = command.to.distance_from(command.from);
938+
auto dot_count = floor(length / (static_cast<float>(command.thickness) * 2));
939+
auto interval = length / dot_count;
940+
SkScalar intervals[] = { 0, interval };
941+
paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
942+
paint.setStrokeCap(SkPaint::Cap::kRound_Cap);
943+
944+
// NOTE: As Skia doesn't render a dot exactly at the end of a line, we need
945+
// to extend it by less then an interval.
946+
auto direction = to - from;
947+
direction.normalize();
948+
to += direction * (interval / 2.0f);
949+
break;
950+
}
951+
case Gfx::LineStyle::Dashed: {
952+
auto length = command.to.distance_from(command.from) + command.thickness;
953+
auto dash_count = floor(length / static_cast<float>(command.thickness) / 4) * 2 + 1;
954+
auto interval = length / dash_count;
955+
SkScalar intervals[] = { interval, interval };
956+
paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
957+
958+
auto direction = to - from;
959+
direction.normalize();
960+
from -= direction * (command.thickness / 2.0f);
961+
to += direction * (command.thickness / 2.0f);
962+
break;
963+
}
964+
}
965+
929966
canvas.drawLine(from, to, paint);
930967
return CommandResult::Continue;
931968
}

0 commit comments

Comments
 (0)