增加了StrokeEndType::kClosed
parent
f25f2d2a81
commit
ae641bb87c
|
@ -1093,6 +1093,7 @@ void main()
|
||||||
bool onVeryBegin = false;
|
bool onVeryBegin = false;
|
||||||
bool onVeryEnd = false;
|
bool onVeryEnd = false;
|
||||||
vec2 tangentEndLast;
|
vec2 tangentEndLast;
|
||||||
|
vec2 tangentFirstBegin;
|
||||||
uint lastHitIndex = 0;
|
uint lastHitIndex = 0;
|
||||||
bool lastHitElement = false;
|
bool lastHitElement = false;
|
||||||
hitElement = false;
|
hitElement = false;
|
||||||
|
@ -1108,7 +1109,19 @@ void main()
|
||||||
pBegin = path[++pathIndex];
|
pBegin = path[++pathIndex];
|
||||||
p3Last = pBegin;
|
p3Last = pBegin;
|
||||||
p2Last = pBegin;
|
p2Last = pBegin;
|
||||||
onVeryBegin = true;
|
if(endType == 4)
|
||||||
|
{
|
||||||
|
//onVeryBegin = false;
|
||||||
|
vec2 lastP1 = path[pathSize-3];
|
||||||
|
vec2 lastP2 = path[pathSize-2];
|
||||||
|
vec2 lastP3 = path[pathSize-1];
|
||||||
|
if (lastP3 != lastP2)
|
||||||
|
tangentEndLast = normalize(lastP3 - lastP2);
|
||||||
|
else
|
||||||
|
tangentEndLast = normalize(lastP3 - lastP1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
onVeryBegin = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
||||||
|
@ -1119,7 +1132,13 @@ void main()
|
||||||
vec2 pTemp = path[pathIndex + 1];
|
vec2 pTemp = path[pathIndex + 1];
|
||||||
if (isinf(pTemp.x))
|
if (isinf(pTemp.x))
|
||||||
{
|
{
|
||||||
onVeryEnd = true;
|
if(endType == 4)
|
||||||
|
{
|
||||||
|
//onVeryEnd = false;
|
||||||
|
tangentBeginNext = tangentFirstBegin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
onVeryEnd = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1180,6 +1199,8 @@ void main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tangentEndLast = tangentEnd;
|
tangentEndLast = tangentEnd;
|
||||||
|
if(pathIndex == 0)
|
||||||
|
tangentFirstBegin = tangentBegin;
|
||||||
}
|
}
|
||||||
p3Last = p[3];
|
p3Last = p[3];
|
||||||
p2Last = p[2];
|
p2Last = p[2];
|
||||||
|
|
|
@ -83,9 +83,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
|
||||||
QPainterPath painterPath = pixelPath.getPainterPath();
|
QPainterPath painterPath = pixelPath.getPainterPath();
|
||||||
QRectF bound = painterPath.boundingRect();
|
QRectF bound = painterPath.boundingRect();
|
||||||
//qDebug() << leafLayer<<"------" << painterPath;
|
//qDebug() << leafLayer<<"------" << painterPath;
|
||||||
//qDebug() << transform;
|
// transform to -1£¬ 1
|
||||||
// transform to initial painterPath
|
|
||||||
// transfrom to -1£¬ 1
|
|
||||||
QTransform trans;
|
QTransform trans;
|
||||||
double maxLen = std::max(bound.width(), bound.height());
|
double maxLen = std::max(bound.width(), bound.height());
|
||||||
qDebug() << maxLen << bound;
|
qDebug() << maxLen << bound;
|
||||||
|
@ -102,22 +100,19 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
|
||||||
auto baseStyles = leafLayer->styles.toBaseStyles();
|
auto baseStyles = leafLayer->styles.toBaseStyles();
|
||||||
Renderer::BaseElement element;
|
Renderer::BaseElement element;
|
||||||
element.contour = contour;
|
element.contour = contour;
|
||||||
for (auto baseStyle : baseStyles) {
|
for (auto& baseStyle : baseStyles) {
|
||||||
double lineWidth = 0;
|
double lineWidth = 0;
|
||||||
if (baseStyle.material->type() == Renderer::MaterialStyleType::kStroke) {
|
if (baseStyle.material->type() == Renderer::MaterialStyleType::kStroke) {
|
||||||
auto material = dynamic_cast<MaterialStyleStroke*>(baseStyle.material.get());
|
auto material = std::static_pointer_cast<MaterialStyleStroke>(baseStyle.material);
|
||||||
material->halfWidth = material->halfWidth / maxLen;
|
material->halfWidth /= maxLen;
|
||||||
lineWidth = material->halfWidth;
|
lineWidth = material->halfWidth;
|
||||||
qDebug() << material->halfWidth;
|
qDebug() << material->halfWidth;
|
||||||
}
|
}
|
||||||
QRectF rect = painterPath.boundingRect();
|
QPainterPathStroker stroker;
|
||||||
rect.setX(-lineWidth + rect.x());
|
stroker.setWidth(lineWidth);
|
||||||
rect.setY(-lineWidth + rect.y());
|
stroker.setCapStyle(Qt::RoundCap);
|
||||||
rect.setWidth(lineWidth * 2 + rect.width());
|
QPainterPath strokePath = stroker.createStroke(painterPath);
|
||||||
rect.setHeight(lineWidth * 2 + rect.height());
|
auto rect = transform.map(strokePath).boundingRect();
|
||||||
QPainterPath path;
|
|
||||||
path.addRect(rect);
|
|
||||||
rect = transform.map(path).boundingRect();
|
|
||||||
elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
|
elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
|
||||||
qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z;
|
qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z;
|
||||||
transform = transform.inverted();
|
transform = transform.inverted();
|
||||||
|
@ -125,7 +120,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
|
||||||
transform.m11(), transform.m12(), transform.m21(),
|
transform.m11(), transform.m12(), transform.m21(),
|
||||||
transform.m22(), transform.m31(), transform.m32()
|
transform.m22(), transform.m31(), transform.m32()
|
||||||
);
|
);
|
||||||
qDebug() << transform;
|
//qDebug() << transform;
|
||||||
elementTransform.zIndex = 0;
|
elementTransform.zIndex = 0;
|
||||||
|
|
||||||
element.style = baseStyle.material;
|
element.style = baseStyle.material;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "MaterialStyleStroke.h"
|
#include "MaterialStyleStroke.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
|
||||||
|
@ -105,8 +106,8 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
||||||
|
|
||||||
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
||||||
{
|
{
|
||||||
return type() == m.type()
|
return type() == m.type()
|
||||||
&& halfWidth == static_cast<const MaterialStyleStroke&>(m).halfWidth
|
&& halfWidth == static_cast<const MaterialStyleStroke&>(m).halfWidth
|
||||||
&& strokeType == static_cast<const MaterialStyleStroke&>(m).strokeType
|
&& strokeType == static_cast<const MaterialStyleStroke&>(m).strokeType
|
||||||
&& endType == static_cast<const MaterialStyleStroke&>(m).endType
|
&& endType == static_cast<const MaterialStyleStroke&>(m).endType
|
||||||
&& *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
|
&& *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
|
||||||
|
@ -117,4 +118,10 @@ float Renderer::MaterialStyleStroke::getHalfWidth() const
|
||||||
return halfWidth;
|
return halfWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define endTypeBoxLabel(start, end) QStringLiteral(start##" -> "##end)
|
||||||
|
const std::array<std::pair<QString, StrokeEndType>, 4> Renderer::MaterialStyleStroke::strokeEndTypeNames = {
|
||||||
|
std::pair{endTypeBoxLabel("Բͷ", "Բͷ"), StrokeEndType::kRound},
|
||||||
|
std::pair{endTypeBoxLabel("ƽͷ", "Բͷ"), StrokeEndType::kFlatRound},
|
||||||
|
std::pair{endTypeBoxLabel("Բͷ", "ƽͷ"), StrokeEndType::kRoundFlat},
|
||||||
|
std::pair{endTypeBoxLabel("ƽͷ", "ƽͷ"), StrokeEndType::kFlat}
|
||||||
|
};
|
|
@ -43,7 +43,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 = 0b00, kFlat = 0b11, kRoundFlat = 0b10, kFlatRound = 0b01 };
|
enum class StrokeEndType { kRound = 0b00, kFlat = 0b11, kRoundFlat = 0b10, kFlatRound = 0b01, kClosed = 0b100/*用于封闭图形*/ };
|
||||||
|
|
||||||
class MaterialStyleStroke : public MaterialStyle
|
class MaterialStyleStroke : public MaterialStyle
|
||||||
{
|
{
|
||||||
|
@ -59,5 +59,6 @@ namespace Renderer
|
||||||
StrokeType strokeType;
|
StrokeType strokeType;
|
||||||
StrokeEndType endType;
|
StrokeEndType endType;
|
||||||
std::shared_ptr<MaterialStroke> materialStroke;
|
std::shared_ptr<MaterialStroke> materialStroke;
|
||||||
|
static const std::array<std::pair<QString, StrokeEndType>, 4> strokeEndTypeNames;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,38 @@ namespace UnitTest
|
||||||
{
|
{
|
||||||
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
{
|
{
|
||||||
|
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleFill>(
|
std::make_shared<MaterialStyleFill>(std::make_shared<FillPlain>(Material(QColor(255,255,0))))) };
|
||||||
std::make_shared<FillPlain>(Material(QColor(255,255,0))))) };
|
}
|
||||||
|
} style;
|
||||||
|
TestGLWidget w(style, path);
|
||||||
|
w.show();
|
||||||
|
a.exec();
|
||||||
|
}
|
||||||
|
TEST_METHOD(TestFillPlainAndStrokeRadialGradient)
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
class Style : 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<MaterialStyleFill>(
|
||||||
|
std::make_shared<FillPlain>(Material(QColor(255,255,0))))),
|
||||||
|
BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
|
std::make_shared<MaterialStyleStroke>(10, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
TestGLWidget w(style, path);
|
TestGLWidget w(style, path);
|
||||||
w.show();
|
w.show();
|
||||||
a.exec();
|
a.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CLASS(ElementRendererStokeTypeTest)
|
TEST_CLASS(ElementRendererStokeTypeTest)
|
||||||
|
|
|
@ -122,20 +122,6 @@ namespace UnitTest
|
||||||
};
|
};
|
||||||
TEST_CLASS(PaintingUtilTest)
|
TEST_CLASS(PaintingUtilTest)
|
||||||
{
|
{
|
||||||
TEST_METHOD(TransfromTest)
|
|
||||||
{
|
|
||||||
qInstallMessageHandler(messageHandler);
|
|
||||||
QPainterPath path;
|
|
||||||
path.addRect(0, 0, 20, 20);
|
|
||||||
QTransform trans;
|
|
||||||
qDebug() << path.boundingRect();
|
|
||||||
//qDebug() << trans;
|
|
||||||
//qDebug() << acos(-0.707107);
|
|
||||||
glm::vec2 scale;
|
|
||||||
float rotate;
|
|
||||||
PaintingUtil::decomposeTransform(trans, rotate, scale);
|
|
||||||
qDebug() << rotate;
|
|
||||||
qDebug() << scale.x << scale.y;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
"name": "Leaf2",
|
"name": "Leaf2",
|
||||||
"styles": [
|
"styles": [
|
||||||
{
|
{
|
||||||
"enableEachSideIndependent": false,
|
"enableEachSideIndependent": true,
|
||||||
"left": "AAAAQAEAIZwAf////1UA/w==",
|
"left": "AAAAQAEAIZwAf////1UA/w==",
|
||||||
"right": "AADgQAAACJw=",
|
"right": "AADgQAAACJw=",
|
||||||
"type": "stroke"
|
"type": "stroke"
|
||||||
|
|
Loading…
Reference in New Issue