FlowArithmeticCalculator 1.0.0
Flow Arithmetic Calculator
Loading...
Searching...
No Matches
SkiaRendererImpl.cpp
Go to the documentation of this file.
1#include "SkiaRendererImpl.h"
2
3#include <utility>
4
5namespace gui::renderer {
7 std::shared_ptr<business_logic::BlocksManager> blocksManager)
8 : gui::renderer::delegate::UIRendererDelegate<SkCanvas>(),
9
10 blocksManager(std::move(blocksManager)),
11 window(window),
12 uiRendererDelegatePtr(
13 static_cast<gui::renderer::delegate::UIRendererDelegate<SkCanvas>*>(this)) {
14 if (window == nullptr) {
15 throw std::runtime_error("Invalid window handle provided to SkiaRendererImpl");
16 }
17
19
20 if (skSurface == nullptr) {
21 throw std::runtime_error(
22 "Failed to create Skia surface (SkSurfaces::RenderTarget returned null)");
23 }
24 }
25
27 auto windowSize = window->getWindowSize();
28
29 if (windowSize.width == 0 && windowSize.height == 0) {
30 return;
31 }
32
33 logger->info("Reinitializing Skia surface with width {} and height {}",
34 windowSize.width,
35 windowSize.height);
36
37 sk_sp<const GrGLInterface> const interface = GrGLMakeNativeInterface();
38 if (!interface) {
39 throw std::runtime_error("Failed to create GL interface");
40 }
41
42 grContext = GrDirectContexts::MakeGL(interface);
43
44 GrGLFramebufferInfo framebufferInfo;
45 framebufferInfo.fFBOID = 0;
46 framebufferInfo.fFormat = GL_RGBA8;
47
48 auto framebufferSize = window->getFramebufferSize();
49 GrBackendRenderTarget const renderTarget = GrBackendRenderTargets::MakeGL(
50 framebufferSize.width, framebufferSize.height, 0, 8, framebufferInfo);
51
52 skSurface = SkSurfaces::WrapBackendRenderTarget(grContext.get(),
53 renderTarget,
54 kBottomLeft_GrSurfaceOrigin,
55 kRGBA_8888_SkColorType,
56 nullptr,
57 nullptr);
58 }
59
64
66 SkCanvas* canvas = skSurface->getCanvas();
68
69 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
72
73 grContext->flush();
74 }
75
77 float xScale,
78 float yScale) {
80
81 skSurface->getCanvas()->scale(xScale, yScale);
82
83 auto windowSize = window->getWindowSize();
84
86 static_cast<float>(windowSize.width) /
88 static_cast<float>(windowSize.height) /
90 xScale,
91 yScale);
92 }
93
95 SkCanvas* canvas,
97 const std::vector<components::UITextsRow>& rows) {
98 // calculate a list of heights of rows (each height is the max height of a text in the row)
99 auto rowsHeights = std::vector<SkScalar>(rows.size());
100 std::transform(
101 rows.begin(), rows.end(), rowsHeights.begin(), [](const components::UITextsRow& row) {
102 SkScalar const maxHeight = std::accumulate(
103 row.getUiTexts().begin(),
104 row.getUiTexts().end(),
105 0.0F,
106 [](SkScalar currentMax, const auto& text) {
107 return std::max(
108 currentMax,
109 FontManager::getFontForVariant(text.getVariant()).getSize());
110 });
111
112 return maxHeight *
114 // between rows
115 });
116
117 auto sumOfHeights =
118 std::accumulate(rowsHeights.begin(), rowsHeights.end(), static_cast<SkScalar>(0.0F));
119
120 auto screenCenterX = static_cast<SkScalar>(size.width) / 2.0F;
121 auto screenCenterY = static_cast<SkScalar>(size.height) / 2.0F;
122
123 // Y start, will be updated as we render each row
124 auto renderY = screenCenterY -
125 (sumOfHeights * (1.0F + CENTERED_TEXT_ROWS_MARGIN_VERTICAL_NORM_PERCENT) /
126 2.0F); // apply a margin
127 // between rows
128
129 int rowIndex = 0;
130 for (const auto& row : rows) {
131 // calculate a list of widths of rows (each width is the sum of the widths of the texts
132 // in the row)
133 auto textsWidths = std::vector<SkScalar>(row.getUiTexts().size());
134 std::transform(row.getUiTexts().begin(),
135 row.getUiTexts().end(),
136 textsWidths.begin(),
137 [](const components::UIText& uiText) {
138 return FontManager::getFontForVariant(uiText.getVariant())
139 .measureText(uiText.getText().c_str(),
140 uiText.getText().length(),
141 SkTextEncoding::kUTF8);
142 });
143
144 const auto sumOfWidths = std::accumulate(
145 textsWidths.begin(), textsWidths.end(), static_cast<SkScalar>(0.0F));
146
147 // X start, will be updated as we render each text
148 auto renderX =
149 screenCenterX -
151 2.0F); // apply a margin
152 // between texts
153
154 auto halfMarginY =
155 rowsHeights[rowIndex] * CENTERED_TEXT_ROWS_MARGIN_VERTICAL_NORM_PERCENT / 2.0F;
156
157 // apply 1st half of the margin between rows
158 renderY += halfMarginY;
159
160 // render the texts in this row
161 int textIndex = 0;
162 for (const auto& uiText : row.getUiTexts()) {
163 auto font = FontManager::getFontForVariant(uiText.getVariant());
164 const auto& text = uiText.getText();
165
166 auto halfMarginX = textsWidths[textIndex] *
168 // apply 1st half of the margin before the element
169 renderX += halfMarginX;
170
171 // render stroke
172 canvas->drawString(
173 text.c_str(), renderX, renderY, font, FontManager::textFontStrokePaint);
174
175 // render fill on top of stroke
176 canvas->drawString(
177 text.c_str(), renderX, renderY, font, FontManager::textFontFillPaint);
178
179 // apply 2nd half of the margin after the element
180 renderX += textsWidths[textIndex] + halfMarginX;
181
182 textIndex++;
183 }
184
185 // apply 2nd half of the margin between rows
186 renderY += rowsHeights[rowIndex] + halfMarginY;
187
188 rowIndex++;
189 }
190 }
191} // namespace gui::renderer
constexpr float CENTERED_TEXT_ROWS_MARGIN_HORIZONTAL_NORM_PERCENT
constexpr float CENTERED_TEXT_ROWS_MARGIN_VERTICAL_NORM_PERCENT
std::shared_ptr< spdlog::logger > logger
Definition Loggable.h:75
The UI renderable text primitive.
Definition UIText.h:14
The UI renderable row of UITexts primitive.
Definition UITextsRow.h:15
Class that extends business_logic::BlocksManager and adds rendering logic.
static void recalculateFontSizes(float aspectX, float aspectY, float xScale, float yScale)
Recalculates the font sizes.
static SkPaint textFontFillPaint
The paint for the text font fill.
Definition FontManager.h:43
static const SkFont & getFontForVariant(const business_logic::components::UIText::Variant &variant)
Gets the font for the given variant.
static SkPaint textFontStrokePaint
The paint for the text font stroke.
Definition FontManager.h:48
void render()
Renders the current frame.
void handleWindowResized(gui::window::WindowBase< SkCanvas > *window, float xScale, float yScale)
Handles window resize events.
std::shared_ptr< business_logic::BlocksManager > blocksManager
The blocks manager.
void reinitializeSurface()
Reinitializes the Skia surface using the current width and height.
void renderCenteredTextsRows(SkCanvas *canvas, const business_logic::geometry::Size2D &size, const std::vector< components::UITextsRow > &rows) override
Renders the texts on the canvas around the center horizontally, centered vertically.
sk_sp< GrDirectContext > grContext
The Skia context.
gui::window::WindowBase< SkCanvas > * window
The window.
SkiaRendererImpl(gui::window::WindowBase< SkCanvas > *window, std::shared_ptr< business_logic::BlocksManager > blocksManager)
Constructs a new SkiaRendererImpl.
~SkiaRendererImpl() override
Destructor.
sk_sp< SkSurface > skSurface
The Skia surface.
gui::renderer::delegate::UIRendererDelegate< SkCanvas > * uiRendererDelegatePtr
The UI renderer delegate.
The abstract base class for implementing a window.
Definition WindowBase.h:27
business_logic::geometry::Size2D getFramebufferSize() override
Get the framebuffer size.
Definition WindowBase.h:141
business_logic::geometry::Size2D getWindowSize() override
Get the window size.
Definition WindowBase.h:136
constexpr int FONT_ASPECT_BASE_WINDOW_WIDTH
The base window width that the current width is divided by to obtain a scaling factor for font size.
Definition constants.h:17
constexpr int FONT_ASPECT_BASE_WINDOW_HEIGHT
The base window height that the current height is divided by to obtain a scaling factor for font size...
Definition constants.h:22
const SkColor WINDOW_BACKGROUND_COLOR
Definition colors.cpp:12
The GUI renderer and renderer-supporting implementation module.
Definition colors.cpp:3
The actual GUI / renderer implementation counterpart.
Definition constants.h:7
STL namespace.
A basic struct representing a 2D size.
Definition Size2D.h:8