~aleteoryx/muditaos

muditaos/module-gui/gui/core/renderers/ArcRenderer.cpp -rw-r--r-- 3.2 KiB
a405cad6Aleteoryx trim readme 7 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/blob/master/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);
        trigonometry::Radians step;

        if (radius < RadiusPrecisionLimit) {
            step = 0.01f;
        }
        else {
            step = 0.001f;
        }

        trigonometry::Radians cosine, sine;
        for (trigonometry::Radians 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);
        trigonometry::Radians step;

        if (radius < RadiusPrecisionLimit) {
            step = 0.01f;
        }
        else {
            step = 0.001f;
        }

        long int x, y;
        for (trigonometry::Radians 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