实现线的平头样式

dev-VirtualTexture
wuyize 2023-02-15 15:37:30 +08:00
parent 315083cd52
commit 3fe7bab969
9 changed files with 256 additions and 59 deletions

View File

@ -896,39 +896,39 @@ bool angleLargeThanPi(vec2 a, vec2 b)
void drawLine(in float d, inout uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness) void drawLine(in float d, inout uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
{ {
elementColor = vec4(1); elementColor = vec4(1);
metallicRoughness = vec2(0.8); metallicRoughness = vec2(0.8);
uint headUint = floatBitsToUint(style[styleIndex+1]); uint headUint = floatBitsToUint(style[styleIndex + 1]);
vec4 head = unpackUnorm4x8(headUint); vec4 head = unpackUnorm4x8(headUint);
switch (int(head.a*100)%10) switch (int(head.a * 100) % 10)
//switch (2) // switch (2)
{ {
/// Plain /// Plain
case 0: { case 0: {
metallicRoughness = head.rg; metallicRoughness = head.rg;
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+2])).rgb, 1); elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 2])).rgb, 1);
break; break;
} }
/// RadialGradient /// RadialGradient
case 1: { case 1: {
uint size = headUint%(1<<15); uint size = headUint % (1 << 15);
bool gradual = (headUint&(1<<15))!=0; bool gradual = (headUint & (1 << 15)) != 0;
uint lastData = floatBitsToUint(style[styleIndex+2+0*2]); uint lastData = floatBitsToUint(style[styleIndex + 2 + 0 * 2]);
float lastLevel = 0; float lastLevel = 0;
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg; vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+3+0*2])).rgb, 1); vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + 0 * 2])).rgb, 1);
for(uint i = 0; i < size; i++) for (uint i = 0; i < size; i++)
{ {
uint data = floatBitsToUint(style[styleIndex+2+i*2]); uint data = floatBitsToUint(style[styleIndex + 2 + i * 2]);
float level = unpackUnorm2x16(data).y; float level = unpackUnorm2x16(data).y;
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+3+i*2])).rgb, 1); vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + i * 2])).rgb, 1);
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg; vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
if (d <= level) if (d <= level)
{ {
if(gradual) if (gradual)
{ {
float a = (d-lastLevel)/(level-lastLevel); float a = (d - lastLevel) / (level - lastLevel);
elementColor = mix(lastColor, currentColor, a); elementColor = mix(lastColor, currentColor, a);
metallicRoughness = mix(lastMetallicRoughness, currentMetallicRoughness, a); metallicRoughness = mix(lastMetallicRoughness, currentMetallicRoughness, a);
} }
@ -969,6 +969,35 @@ void drawLine(in float d, inout uint styleIndex, out vec4 elementColor, out vec2
} }
} }
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, vec2 tangentBegin, vec2 tangentEndLast)
{
vec2 normal;
if (onVeryBegin)
{
if (endType == 0)
return true;
else if (endType == 1)
normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
}
else
{
vec2 normalLast = normalize(mat2(0, 1, -1, 0) * tangentEndLast);
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
normal = normalLast + normalNow;
}
return angleLargeThanPi(normal, localUV - p3);
}
bool shouldFillEndCap(vec2 localUV, int endType, vec2 p0, vec2 tangentEnd)
{
vec2 normal;
if (endType == 0)
return true;
else if (endType == 1)
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
return angleLargeThanPi(localUV - p0, normal);
}
void main() void main()
{ {
uvec2 pixelLocation = gl_GlobalInvocationID.xy; uvec2 pixelLocation = gl_GlobalInvocationID.xy;
@ -1022,19 +1051,30 @@ void main()
else // Stroke else // Stroke
{ {
float minDistance = 1e38; float minDistance = 1e38;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex+1])); vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1]));
float lineType = floor(styleHead.b*10); float lineType = floor(styleHead.b * 10);
//float lineType = 2; // float lineType = 2;
int endType = int(round(styleHead.b * 100)) % 10;
//endType = 1;
int debugBegin = 0; int debugBegin = 0;
bool onVeryBegin = false;
vec2 tangentEndLast;
for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++) for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++)
// for (uint pathIndex = 0; pathIndex < 4; pathIndex++)
{ {
vec2 pTemp = path[pathIndex]; vec2 pTemp = path[pathIndex];
if (isinf(pTemp.x)) if (isinf(pTemp.x))
{ {
// TODO: ¼ì²âÊÇ·ñ·â±Õ²¢´¦Àí // TODO: ¼ì²âÊÇ·ñ·â±Õ²¢´¦Àí
if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{
hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast);
}
pBegin = path[++pathIndex]; pBegin = path[++pathIndex];
p3Last = pBegin; p3Last = pBegin;
p2Last = pBegin;
onVeryBegin = true;
continue; continue;
} }
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]); mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
@ -1043,22 +1083,24 @@ void main()
if (d <= strokeWidth) if (d <= strokeWidth)
{ {
bool onBegin = distance(localUV, p[0]) <= strokeWidth && p3Last == p[0]; bool onBegin = distance(localUV, p[0]) <= strokeWidth && p3Last == p[0];
bool fill = true; vec2 tangentBegin;
if (onBegin) vec2 tangentEnd;
{ if (p[0] != p[1])
vec2 normalLast = normalize(mat2(0, 1, -1, 0) * (p3Last - p2Last)); tangentBegin = normalize(p[0] - p[1]);
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (p[1] - p[0])); else
vec2 normal = normalLast + normalNow; tangentBegin = normalize(p[0] - p[2]);
fill = angleLargeThanPi(normal, localUV - p[0]); if (p[3] != p[2])
} tangentEnd = normalize(p[3] - p[2]);
if (onBegin ? fill : d < minDistance) else
tangentEnd = normalize(p[3] - p[1]);
if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, p3Last - p2Last)
: d < minDistance)
{ {
minDistance = min(minDistance, d); minDistance = min(minDistance, d);
bool reverse = p[3].y - p[0].y < 0.; bool reverse = p[3].y - p[0].y < 0.;
vec2 tangentBegin = normalize(p[0] - p[1]);
vec2 tangentEnd = normalize(p[3] - p[2]);
if (tangentBegin.y == 0.) if (tangentBegin.y == 0.)
tangentBegin.y = reverse ? eps : -eps; tangentBegin.y = reverse ? eps : -eps;
if (tangentEnd.y == 0.) if (tangentEnd.y == 0.)
@ -1066,19 +1108,26 @@ void main()
int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) + int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) +
ray_int_test(localUV, p[0], tangentBegin, reverse) + ray_int_test(localUV, p[0], tangentBegin, reverse) +
ray_int_test(localUV, p[3], tangentEnd, reverse); ray_int_test(localUV, p[3], tangentEnd, reverse);
if (lineType == 2 || intTest % 2 == int(lineType))
if (lineType == 2 || (intTest % 2 == int(lineType)))
{ {
hitElement = true; hitElement = true;
//elementColor = vec4(1, 1, 0, 1); // elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness; vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
} }
else if (p3Last == p[0]) else if (p3Last == p[0])
hitElement = false; hitElement = false;
} }
tangentEndLast = tangentEnd;
} }
p3Last = p[3]; p3Last = p[3];
p2Last = p[2]; p2Last = p[2];
onVeryBegin = false;
}
if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{
hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast);
} }
} }
if (hitElement) if (hitElement)

View File

@ -7,7 +7,7 @@ using Renderer::Line;
using std::vector; using std::vector;
using std::shared_ptr; using std::shared_ptr;
vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterPath) { vector<vector<Point>> PainterPathUtil::transformToLines(QPainterPath& painterPath) {
vector<Point> line; line.clear(); vector<Point> line; line.clear();
vector<vector<Point> > lines; lines.clear(); vector<vector<Point> > lines; lines.clear();
QPointF startPoint(0, 0); QPointF startPoint(0, 0);
@ -48,16 +48,16 @@ QPainterPath PainterPathUtil::monotonization(QPainterPath& painterPath) {
vector<vector<Point> > lines = transformToLines(painterPath); vector<vector<Point> > lines = transformToLines(painterPath);
vector<shared_ptr<Line>> linePtrVector; vector<shared_ptr<Line>> linePtrVector;
Renderer::LineTree::monotonization(lines, linePtrVector); Renderer::LineTree::monotonization(lines, linePtrVector);
for (auto linePtr : linePtrVector) { Point lastPoint(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity());
for (auto& linePtr : linePtrVector) {
vector<Point> line = linePtr->toPointVector(); vector<Point> line = linePtr->toPointVector();
if (line.size() == 2) { if (line[0] != lastPoint)
resPath.moveTo(line[0]); resPath.moveTo(line[0]);
if (line.size() == 2)
resPath.lineTo(line[1]); resPath.lineTo(line[1]);
} else if (line.size() == 4)
if (line.size() == 4) {
resPath.moveTo(line[0]);
resPath.cubicTo(line[1], line[2], line[3]); resPath.cubicTo(line[1], line[2], line[3]);
} lastPoint = line.back();
} }
return resPath; return resPath;
} }

View File

@ -3,12 +3,10 @@
#include <QPainterPath> #include <QPainterPath>
#include "../Renderer/Painting/Line.h" #include "../Renderer/Painting/Line.h"
using Renderer::Point;
class PainterPathUtil class PainterPathUtil
{ {
public: public:
static std::vector<std::vector<Point> > transformToLines(QPainterPath& painterPath); static std::vector<std::vector<Renderer::Point> > transformToLines(QPainterPath& painterPath);
static QPainterPath monotonization(QPainterPath& painterPath); static QPainterPath monotonization(QPainterPath& painterPath);
}; };

View File

@ -38,7 +38,7 @@ namespace Renderer
}; };
enum class StrokeType { kBothSides = 2, kLeftSide = 1, kRightSide = 0 }; enum class StrokeType { kBothSides = 2, kLeftSide = 1, kRightSide = 0 };
enum class StrokeEndType { kRound = 0 }; enum class StrokeEndType { kRound = 0, kFlat = 1 };
class MaterialStyleStroke : public MaterialStyle class MaterialStyleStroke : public MaterialStyle
{ {

View File

@ -37,11 +37,15 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
switch (element.type) switch (element.type)
{ {
case QPainterPath::MoveToElement: case QPainterPath::MoveToElement:
qDebug() << "MoveToElement";
qDebug() << element;
pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity())); pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity()));
pathBuffer.push_back(glm::vec2(element.x, element.y)); pathBuffer.push_back(glm::vec2(element.x, element.y));
break; break;
case QPainterPath::LineToElement: case QPainterPath::LineToElement:
{ {
qDebug() << "LineToElement";
qDebug() << element;
glm::vec2 end = glm::vec2(element.x, element.y); glm::vec2 end = glm::vec2(element.x, element.y);
glm::vec2 mid = (pathBuffer.back() + end) / 2.f; glm::vec2 mid = (pathBuffer.back() + end) / 2.f;
pathBuffer.push_back(mid); pathBuffer.push_back(mid);
@ -50,8 +54,24 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
break; break;
} }
case QPainterPath::CurveToElement: case QPainterPath::CurveToElement:
pathBuffer.push_back(glm::vec2(element.x, element.y)); {
qDebug() << "CurveToElement";
qDebug() << element;
glm::vec2 p1 = glm::vec2(element.x, element.y);
element = path.elementAt(++i);
qDebug() << element;
glm::vec2 p2 = glm::vec2(element.x, element.y);
element = path.elementAt(++i);
qDebug() << element;
glm::vec2 p3 = glm::vec2(element.x, element.y);
if (p3 != pathBuffer.back())
{
pathBuffer.push_back(p1);
pathBuffer.push_back(p2);
pathBuffer.push_back(p3);
}
break; break;
}
case QPainterPath::CurveToDataElement: case QPainterPath::CurveToDataElement:
pathBuffer.push_back(glm::vec2(element.x, element.y)); pathBuffer.push_back(glm::vec2(element.x, element.y));
break; break;

View File

@ -23,5 +23,17 @@
已实现由图元数据建立完整彩绘编码 已实现由图元数据建立完整彩绘编码
已实现面的纯色样式,线的纯色、径向渐变/分层、单侧等样式 #### 已实现的图元样式MaterialStyle
##### 面MaterialStyleFill
纯色
##### 线MaterialStyleStroke
双侧/左侧/右侧
圆头/平头
纯色/渐变/分层

View File

@ -9,7 +9,116 @@ using namespace Renderer;
namespace UnitTest namespace UnitTest
{ {
TEST_CLASS(ElementRendererTest) TEST_CLASS(ElementRendererStokeTypeTest)
{
public:
TEST_METHOD(TestBothSidesRound)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.20, Material{QColor(255,255,255)}},
{0.60, Material{QColor(165,176,207)}},
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
TEST_METHOD(TestBothSidesFlat)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.20, Material{QColor(255,255,255)}},
{0.60, Material{QColor(165,176,207)}},
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kFlat,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
TEST_METHOD(TestLeftSideRound)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.20, Material{QColor(255,255,255)}},
{0.60, Material{QColor(165,176,207)}},
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
TEST_METHOD(TestLeftSideFlat)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.20, Material{QColor(255,255,255)}},
{0.60, Material{QColor(165,176,207)}},
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kFlat,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
};
TEST_CLASS(ElementRendererStokeMaterialTest)
{ {
public: public:
TEST_METHOD(TestStrokePlain) TEST_METHOD(TestStrokePlain)
@ -20,7 +129,15 @@ namespace UnitTest
char* argv[] = { (char*)"" }; char* argv[] = { (char*)"" };
int argc = 1; int argc = 1;
QApplication a(argc, argv); QApplication a(argc, argv);
Renderer::ElementStyleStrokeDemo style(2); class StyleStrokePlain : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
std::make_shared<StrokePlain>(QColor(255,255,255),1,1))) };
}
} style;
TestGLWidget w(style); TestGLWidget w(style);
w.show(); w.show();
a.exec(); a.exec();
@ -37,14 +154,13 @@ namespace UnitTest
{ {
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{ {
std::map<float, Material> materialMap = { std::map<float, Material> materialMap = {
{0.25, Material{QColor(255,0,0)}}, {0.20, Material{QColor(255,255,255)}},
{0.50, Material{QColor(0,255,0)}}, {0.60, Material{QColor(165,176,207)}},
{0.75, Material{QColor(0,0,255)}}, {1.00, Material{QColor(58,64,151)}}
{1.00, Material{QColor(255,255,0)}},
}; };
return { BaseStyle(std::make_shared<TransformStyle>(), return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(4, StrokeType::kLeftSide, StrokeEndType::kRound, std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) }; std::make_shared<StrokeRadialGradient>(materialMap, false))) };
} }
} style; } style;
@ -65,12 +181,12 @@ namespace UnitTest
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{ {
std::map<float, Material> materialMap = { std::map<float, Material> materialMap = {
{0.50, Material{QColor(0,255,0)}}, {0.00, Material{QColor(255,255,255)}},
{0.75, Material{QColor(0,0,255)}}, {0.50, Material{QColor(165,176,207)}},
{1.00, Material{QColor(255,255,0)}}, {1.00, Material{QColor(58,64,151)}}
}; };
return { BaseStyle(std::make_shared<TransformStyle>(), return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(30, StrokeType::kLeftSide, StrokeEndType::kRound, std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, true))) }; std::make_shared<StrokeRadialGradient>(materialMap, true))) };
} }
} style; } style;

View File

@ -4,6 +4,7 @@
#include <QPainter> #include <QPainter>
#include "Renderer/Preview/ElementRenderer.h" #include "Renderer/Preview/ElementRenderer.h"
#include "Editor/ThirdPartyLib/qquick/qquicksvgparser_p.h" #include "Editor/ThirdPartyLib/qquick/qquicksvgparser_p.h"
#include "Editor/util/PainterPathUtil.h"
#include "Renderer/Painting/MaterialStyleStroke.h" #include "Renderer/Painting/MaterialStyleStroke.h"
#include "Renderer/Painting/ElementStyle.h" #include "Renderer/Painting/ElementStyle.h"
@ -25,12 +26,13 @@ namespace UnitTest
}; };
void paintGL() override void paintGL() override
{ {
glClearColor(1.0, 1.0, 1.0, 1.0); glClearColor(219/255., 78/255., 32/255., 1.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
QPainterPath path; QPainterPath path;
QQuickSvgParser::parsePathDataFast("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", path); QQuickSvgParser::parsePathDataFast("M292.82,107.78s0,0,0,0,0,3.59,0,7.62c0,3.85,0,5.78.06,6.43a19.94,19.94,0,0,0,2.87,7.58,15.85,15.85,0,0,0,6.61,6.23A14.75,14.75,0,0,0,310,137a11.69,11.69,0,0,0,7.59-2.92,11,11,0,0,0,3.2-6.84c.15-1.27.58-4.84-1.79-7.64a8.54,8.54,0,0,0-3.56-2.44c-1.32-.52-3.32-1.31-5.06-.33a5.41,5.41,0,0,0-2.14,3,3.48,3.48,0,0,0-.16,2.71c.78,1.86,3.36,2.14,3.47,2.15", path);
path = PainterPathUtil::monotonization(path);
QTransform transform; QTransform transform;
transform.scale(5, 5); transform.scale(10, 10);
path = transform.map(path); path = transform.map(path);
float pixelRatio = devicePixelRatioF(); float pixelRatio = devicePixelRatioF();
auto [img, pos] = renderer.drawElement(path, style, pixelRatio, false); auto [img, pos] = renderer.drawElement(path, style, pixelRatio, false);

View File

@ -69,7 +69,7 @@
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\*.obj;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperCore\debug\FramelessHelperCore.lib;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperWidgets\debug\FramelessHelperWidgets.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(SolutionDIr)ArchitectureColoredPainting\x64\Debug\*.obj;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperCore\debug\FramelessHelperCore.lib;$(SolutionDIr)FramelessHelper\qmake\FramelessHelperWidgets\debug\FramelessHelperWidgets.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">