Skip to content

Commit d42fb9e

Browse files
committed
Rm textColor, change offsetY testcase, add ColorGradientSetter
1 parent 5d9e432 commit d42fb9e

File tree

13 files changed

+148
-68
lines changed

13 files changed

+148
-68
lines changed

src/apps/qutils/canvas.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ void BaseCanvas::init(QPaintDevice *device)
9292

9393
void BaseCanvas::setBrushColor(const Gfx::Color &color)
9494
{
95-
brush = QBrush(toQColor(color));
96-
painter.setBrush(brush);
95+
painter.setBrush(toQColor(color));
96+
painter.setPen(brushToPen(painter.brush()));
9797
}
9898

9999
void BaseCanvas::setLineColor(const Gfx::Color &color)
@@ -162,12 +162,6 @@ void BaseCanvas::setFont(const Gfx::Font &newFont)
162162
painter.setFont(fromGfxFont(newFont, painter.font()));
163163
}
164164

165-
void BaseCanvas::setTextColor(const Gfx::Color &color)
166-
{
167-
textPen = colorToPen(color);
168-
painter.setPen(textPen);
169-
}
170-
171165
void BaseCanvas::beginDropShadow() {}
172166

173167
void BaseCanvas::setDropShadowBlur(double) {}
@@ -199,7 +193,7 @@ void BaseCanvas::rectangle(const Geom::Rect &rect)
199193

200194
void BaseCanvas::text(const Geom::Rect &rect, const std::string &text)
201195
{
202-
painter.setPen(textPen);
196+
painter.setPen(brushToPen(painter.brush()));
203197
painter.drawText(toQRect(rect),
204198
Qt::AlignLeft,
205199
QString::fromStdString(text));
@@ -214,14 +208,15 @@ void BaseCanvas::setBrushGradient(const Geom::Line &line,
214208
qGradient.setColorAt(stop.pos, toQColor(stop.value));
215209
}
216210
painter.setBrush(QBrush(qGradient));
211+
painter.setPen(brushToPen(painter.brush()));
217212
}
218213

219-
QPen BaseCanvas::colorToPen(const Gfx::Color &color)
214+
QPen BaseCanvas::colorToPen(const Gfx::Color &color) const
220215
{
221216
return brushToPen(QBrush(toQColor(color)));
222217
}
223218

224-
QPen BaseCanvas::brushToPen(const QBrush &brush)
219+
QPen BaseCanvas::brushToPen(const QBrush &brush) const
225220
{
226221
auto pen = painter.pen();
227222
pen.setBrush(brush);

src/apps/qutils/canvas.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class BaseCanvas : public Gfx::ICanvas, public Vizzu::Draw::Painter
2626
void setLineColor(const Gfx::Color &color) override;
2727
void setLineWidth(double width) override;
2828
void setFont(const Gfx::Font &newFont) override;
29-
void setTextColor(const Gfx::Color &color) override;
3029

3130
void beginDropShadow() override;
3231
void setDropShadowBlur(double radius) override;
@@ -70,11 +69,9 @@ class BaseCanvas : public Gfx::ICanvas, public Vizzu::Draw::Painter
7069
QFont font;
7170
QPainterPath polygon;
7271
QPen linePen;
73-
QPen textPen;
74-
QBrush brush;
7572

76-
QPen colorToPen(const Gfx::Color &color);
77-
QPen brushToPen(const QBrush &brush);
73+
[[nodiscard]] QPen colorToPen(const Gfx::Color &color) const;
74+
[[nodiscard]] QPen brushToPen(const QBrush &brush) const;
7875
};
7976

8077
using Canvas = BaseCanvas;

src/apps/weblib/jscriptcanvas.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,6 @@ void JScriptCanvas::setFont(const Gfx::Font &font)
8585
}
8686
}
8787

88-
void JScriptCanvas::setTextColor(const Gfx::Color &color)
89-
{
90-
if (color != brushColor) {
91-
brushColor = color;
92-
::canvas_setBrushColor(this,
93-
color.red,
94-
color.green,
95-
color.blue,
96-
color.alpha);
97-
}
98-
}
99-
10088
void JScriptCanvas::beginDropShadow()
10189
{
10290
::canvas_beginDropShadow(this);
@@ -186,6 +174,7 @@ void JScriptCanvas::setBrushGradient(const Geom::Line &line,
186174
const Gfx::ColorGradient &gradient)
187175
{
188176
typedef decltype(gradient.stops)::value_type Stop;
177+
static_assert(sizeof(double) == 8);
189178
static_assert(sizeof(Stop) == sizeof(double) * 5);
190179

191180
static_assert(offsetof(Stop, pos) == 0);

src/apps/weblib/jscriptcanvas.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class JScriptCanvas : public Gfx::ICanvas, public Draw::Painter
2323
void setLineColor(const Gfx::Color &color) override;
2424
void setLineWidth(double width) override;
2525
void setFont(const Gfx::Font &font) override;
26-
void setTextColor(const Gfx::Color &color) override;
2726

2827
void beginDropShadow() override;
2928
void setDropShadowBlur(double radius) override;

src/base/gfx/canvas.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ struct ICanvas
2828
virtual void setClipPolygon() = 0;
2929
virtual void setBrushColor(const Gfx::Color &color) = 0;
3030
virtual void setLineColor(const Gfx::Color &color) = 0;
31-
virtual void setTextColor(const Gfx::Color &color) = 0;
3231
virtual void setLineWidth(double width) = 0;
3332
virtual void setFont(const Gfx::Font &font) = 0;
3433

src/base/gfx/draw/textbox.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ void TextBox::draw(ICanvas &canvas, double opacity)
156156
canvas.setLineColor(background);
157157
canvas.rectangle(
158158
{{xpos, ypos}, {text.width, line.height}});
159-
canvas.setTextColor(foreground);
159+
canvas.setBrushColor(foreground);
160160
canvas.text({{xpos, ypos}, {10000, 10000}}, text.content);
161161
xpos += text.width;
162162
}

src/chart/rendering/drawlabel.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ void DrawLabel::draw(Gfx::ICanvas &canvas,
3030
if (!style.backgroundColor->isTransparent()) {
3131
canvas.save();
3232
auto bgColor = *style.backgroundColor * options.bgAlpha;
33-
canvas.setBrushColor(bgColor);
34-
canvas.setLineColor(bgColor);
33+
if (options.gradient)
34+
options.gradient(canvas,
35+
fullRect.transform.inverse(),
36+
bgColor);
37+
else
38+
canvas.setBrushColor(bgColor);
3539
canvas.transform(fullRect.transform);
3640
canvas.rectangle(relativeRect);
3741
canvas.restore();
@@ -47,8 +51,6 @@ void DrawLabel::draw(Gfx::ICanvas &canvas,
4751
canvas.save();
4852

4953
canvas.setFont(font);
50-
if (options.alpha)
51-
canvas.setTextColor(*style.color * *options.alpha);
5254

5355
auto copyRect = fullRect;
5456

@@ -57,16 +59,26 @@ void DrawLabel::draw(Gfx::ICanvas &canvas,
5759
1.0,
5860
-std::numbers::pi);
5961

62+
auto textTransform =
63+
copyRect.transform
64+
* Geom::AffineTransform(alignRect.bottomLeft());
65+
66+
if (options.alpha) {
67+
if (auto textColor = *style.color * *options.alpha;
68+
options.gradient)
69+
options.gradient(canvas,
70+
textTransform.inverse(),
71+
textColor);
72+
else
73+
canvas.setBrushColor(textColor);
74+
}
75+
6076
if (onDraw.invoke(Events::OnTextDrawEvent{*eventTarget,
6177
copyRect,
6278
paddedRect,
6379
alignConstant,
6480
text})) {
6581

66-
auto textTransform =
67-
copyRect.transform
68-
* Geom::AffineTransform(alignRect.bottomLeft());
69-
7082
canvas.transform(textTransform);
7183

7284
canvas.text({{}, alignRect.size}, text);

src/chart/rendering/drawlabel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class DrawLabel : public DrawingContext
1919
std::optional<double> alpha{1.0};
2020
double bgAlpha{1.0};
2121
bool flip{false};
22+
std::function<void(Gfx::ICanvas &,
23+
const Geom::AffineTransform &,
24+
const Gfx::Color &)>
25+
gradient{};
2226
};
2327

2428
void draw(Gfx::ICanvas &canvas,

src/chart/rendering/drawlegend.cpp

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
#include <algorithm>
44
#include <cmath>
55
#include <cstddef>
6+
#include <functional>
67
#include <string>
78
#include <string_view>
89
#include <utility>
910

1011
#include "base/anim/interpolated.h"
12+
#include "base/geom/affinetransform.h"
1113
#include "base/geom/rect.h"
1214
#include "base/geom/transformedrect.h"
1315
#include "base/gfx/canvas.h"
16+
#include "base/gfx/color.h"
1417
#include "base/gfx/draw/roundedrect.h"
1518
#include "base/math/floating.h"
1619
#include "base/text/smartstring.h"
@@ -29,30 +32,46 @@ void DrawLegend::draw(Gfx::ICanvas &canvas,
2932
Gen::ChannelId channelType,
3033
double weight) const
3134
{
32-
auto contentRect =
35+
auto markerWindowRect =
3336
style.contentRect(legendLayout, rootStyle.calculatedSize());
3437

35-
auto markerWindowRect = contentRect;
3638
auto titleRect =
3739
markerWindowRect.popBottom(style.title.getHeight());
40+
auto markerWindowHeight = markerWindowRect.height();
41+
auto itemHeight = style.label.getHeight();
42+
auto markerSize = style.marker.size->get(itemHeight,
43+
style.label.calculatedSize());
3844

39-
auto &&info = Info{
40-
.canvas = canvas,
45+
auto fadeHeight = markerSize;
46+
markerWindowRect =
47+
markerWindowRect
48+
+ Geom::Rect{{0, -fadeHeight}, {0, 2 * fadeHeight}};
49+
50+
auto fadeElementPercent = fadeHeight / markerWindowRect.height();
51+
52+
auto &&info = Info{.canvas = canvas,
4153
.titleRect = titleRect,
4254
.markerWindowRect = markerWindowRect,
55+
.fadeHeight = fadeHeight,
4356
.yOverflow = {},
4457
.yOffset = {},
4558
.type = channelType,
4659
.weight = weight,
47-
.itemHeight = style.label.getHeight(),
48-
.markerSize = style.marker.size->get(contentRect.size.y,
49-
style.label.calculatedSize()),
60+
.itemHeight = itemHeight,
61+
.markerSize = markerSize,
5062
.measure = plot->axises.at(channelType).measure,
5163
.dimension = plot->axises.at(channelType).dimension,
52-
};
53-
54-
info.yOverflow =
55-
markersLegendFullSize(info) - markerWindowRect.height();
64+
.colorGradientSetter = {markerWindowRect.leftSide(),
65+
Gfx::ColorGradient{{
66+
{0.0, {}},
67+
{fadeElementPercent / 2.0, {}},
68+
{fadeElementPercent, {}},
69+
{1.0 - fadeElementPercent, {}},
70+
{1.0 - fadeElementPercent / 2.0, {}},
71+
{1.0, {}},
72+
}}}};
73+
74+
info.yOverflow = markersLegendFullSize(info) - markerWindowHeight;
5675
if (std::signbit(info.yOverflow)) info.yOverflow = 0.0;
5776
info.yOffset =
5877
style.translateY->get(info.yOverflow, info.itemHeight);
@@ -64,15 +83,38 @@ void DrawLegend::draw(Gfx::ICanvas &canvas,
6483
Events::Targets::legend(channelType, info.yOverflow));
6584

6685
canvas.save();
67-
canvas.setClipRect(contentRect);
6886

69-
drawTitle(info);
87+
canvas.setClipRect(markerWindowRect);
7088

7189
drawDimension(info);
7290

7391
drawMeasure(info);
7492

7593
canvas.restore();
94+
95+
canvas.save();
96+
97+
canvas.setClipRect(titleRect);
98+
99+
drawTitle(info);
100+
101+
canvas.restore();
102+
}
103+
104+
void DrawLegend::ColorGradientSetter::operator()(Gfx::ICanvas &canvas,
105+
const Geom::AffineTransform &transform,
106+
const Gfx::Color &color) const
107+
{
108+
for (auto &stop : modifiableStops) stop.value = color;
109+
110+
modifiableStops[0].value.alpha = 0.0;
111+
modifiableStops[1].value.alpha *= 0.27;
112+
modifiableStops[4].value.alpha *= 0.27;
113+
modifiableStops[5].value.alpha = 0.0;
114+
115+
canvas.setBrushGradient(
116+
{transform(line.begin), transform(line.end)},
117+
gradient);
76118
}
77119

78120
void DrawLegend::drawTitle(const Info &info) const
@@ -110,8 +152,8 @@ void DrawLegend::drawDimension(const Info &info) const
110152
auto itemRect =
111153
getItemRect(info, value.second.range.getMin());
112154

113-
if (itemRect.y().getMax() > info.markerWindowRect.y().getMax()
114-
|| itemRect.y().getMin()
155+
if (itemRect.y().getMin() > info.markerWindowRect.y().getMax()
156+
|| itemRect.y().getMax()
115157
< info.markerWindowRect.y().getMin())
116158
continue;
117159

@@ -138,16 +180,21 @@ void DrawLegend::drawDimension(const Info &info) const
138180
value.second.categoryValue,
139181
info.type,
140182
info.yOverflow),
141-
{.alpha = double{
142-
alpha && Math::FuzzyBool{weighted.weight}}});
183+
{.alpha =
184+
double{
185+
alpha
186+
&& Math::FuzzyBool{weighted.weight}},
187+
.gradient =
188+
std::ref(info.colorGradientSetter)});
143189
});
144190
}
145191
}
146192

147193
Geom::Rect DrawLegend::getItemRect(const Info &info, double index)
148194
{
149195
Geom::Rect res = info.markerWindowRect;
150-
res.pos.y += index * info.itemHeight - info.yOffset;
196+
res.pos.y +=
197+
info.fadeHeight + index * info.itemHeight - info.yOffset;
151198
res.size.y = info.itemHeight;
152199
if (std::signbit(res.size.x)) res.size.x = 0;
153200
return res;
@@ -179,7 +226,7 @@ void DrawLegend::drawMarker(const Info &info,
179226
{
180227
info.canvas.save();
181228

182-
info.canvas.setBrushColor(color);
229+
info.colorGradientSetter(info.canvas, {}, color);
183230
info.canvas.setLineColor(color);
184231
info.canvas.setLineWidth(0);
185232

@@ -259,7 +306,7 @@ void DrawLegend::extremaLabel(const Info &info,
259306
Geom::Rect DrawLegend::getBarRect(const Info &info)
260307
{
261308
Geom::Rect res = info.markerWindowRect;
262-
res.pos.y += info.itemHeight / 2.0;
309+
res.pos.y += info.fadeHeight + info.itemHeight / 2.0;
263310
res.size.y = 5 * info.itemHeight;
264311
res.size.x = info.markerSize;
265312
return res;

src/chart/rendering/drawlegend.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,23 @@ class DrawLegend : public DrawingContext
2525
*rootStyle.plot.marker.colorGradient};
2626

2727
private:
28+
struct ColorGradientSetter
29+
{
30+
Geom::Line line;
31+
Gfx::ColorGradient gradient;
32+
std::span<Gfx::ColorGradient::Stop> modifiableStops =
33+
gradient.stops;
34+
35+
void operator()(Gfx::ICanvas &,
36+
const Geom::AffineTransform &,
37+
const Gfx::Color &) const;
38+
};
2839
struct Info
2940
{
3041
Gfx::ICanvas &canvas;
3142
Geom::Rect titleRect;
3243
Geom::Rect markerWindowRect;
44+
double fadeHeight{};
3345
double yOverflow{};
3446
double yOffset{};
3547
Gen::ChannelId type{};
@@ -41,6 +53,7 @@ class DrawLegend : public DrawingContext
4153
double measureEnabled = measure.enabled.calculate<double>();
4254
bool dimensionEnabled = dimension.enabled;
4355
double measureWeight = weight * measureEnabled;
56+
ColorGradientSetter colorGradientSetter;
4457
};
4558

4659
void drawTitle(const Info &info) const;

0 commit comments

Comments
 (0)