Files
MuditaOS/module-gui/gui/core/renderers/ArcRenderer.cpp
Maciej Janicki e6fdf0e22c [EGD-5333] Change renderer to follow command design pattern
Changes draw command implementation to properly follow
command design pattern. All drawing commands have been
moved to separate inheriting draw commands from renderer.

Other changes:
- New draw methods overloads have been added to pixel renderer.
 Now pixel rendering methods are in one class.
- Simplified draw commands naming.
- Changed variable naming in draw commands to be more verbose.
- Changed {x,y} pairs to Points where possible.
2021-02-03 16:24:48 +01:00

94 lines
3.1 KiB
C++

// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ArcRenderer.hpp"
#include "PixelRenderer.hpp"
namespace gui::renderer
{
constexpr Length RadiusPrecisionLimit = 5;
auto ArcRenderer::DrawableStyle::from(const DrawArc &command) -> DrawableStyle
{
return DrawableStyle{command.width, command.borderColor};
}
void ArcRenderer::draw(Context *ctx,
Point center,
Length radius,
trigonometry::Degrees begin,
trigonometry::Degrees sweep,
const DrawableStyle &style)
{
if (style.penWidth == 1) {
draw(ctx, center, radius, begin, sweep, style.color);
}
else {
draw(ctx, center, radius, begin, sweep, style.color, style.penWidth);
}
}
void ArcRenderer::draw(Context *ctx,
Point center,
Length radius,
trigonometry::Degrees begin,
trigonometry::Degrees sweep,
Color color,
Length width)
{
if (width == 1) {
draw(ctx, center, radius, begin, sweep, color);
return;
}
const auto start = trigonometry::toRadians(begin);
const auto end = trigonometry::toRadians(begin + sweep);
double step;
if (radius < RadiusPrecisionLimit) {
step = 0.01;
}
else {
step = 0.001;
}
double cosine, sine;
for (double radians = start; radians <= end; radians += step) {
cosine = std::cos(radians);
sine = std::sin(radians);
for (Length i = 0; i < width; ++i) {
const auto r = radius - i;
const auto x = trigonometry::AdjacentSide::fromCosine(cosine, r);
const auto y = trigonometry::OppositeSide::fromSine(sine, r);
PixelRenderer::draw(ctx, Point(center.x + x, center.y + y), color);
}
}
}
void ArcRenderer::draw(Context *ctx,
Point center,
Length radius,
trigonometry::Degrees begin,
trigonometry::Degrees sweep,
Color color)
{
const auto start = trigonometry::toRadians(begin);
const auto end = trigonometry::toRadians(begin + sweep);
double step;
if (radius < RadiusPrecisionLimit) {
step = 0.01;
}
else {
step = 0.001;
}
long int x, y;
for (double radians = start; radians <= end; radians += step) {
x = trigonometry::AdjacentSide::fromAngle(radians, radius);
y = trigonometry::OppositeSide::fromAngle(radians, radius);
PixelRenderer::draw(ctx, Point(center.x + x, center.y + y), color);
}
}
} // namespace gui::renderer