提供变宽样式的接口,未实现

dev-wuyize
wuyize 2023-03-23 23:09:51 +08:00
parent a3d39b32e5
commit b2e49dae17
9 changed files with 149 additions and 88 deletions

View File

@ -72,6 +72,7 @@
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level1</WarningLevel>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<TreatSpecificWarningsAsErrors>4715;</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

@ -557,7 +557,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s)
return num;
}
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd)
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd, out float t)
{
// switch points when near to end point to minimize numerical error
@ -794,7 +794,13 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn
{
roots[i] = clamp(roots[i], 0., 1.);
vec2 to_curve = uv - parametric_cub_bezier(roots[i], p0, p1, p2, p3);
d0 = min(d0, dot(to_curve, to_curve));
float d = dot(to_curve, to_curve);
if (d < d0)
{
d0 = d;
t = roots[i];
}
// d0 = min(d0, dot(to_curve, to_curve));
}
else
{
@ -893,11 +899,11 @@ bool angleLargeThanPi(vec2 a, vec2 b)
/************************************************************************************/
void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
{
elementColor = vec4(1);
metallicRoughness = vec2(0.8);
uint headUint = floatBitsToUint(style[styleIndex + 1]);
uint headUint = floatBitsToUint(style[styleHeadIndex]);
vec4 head = unpackUnorm4x8(headUint);
switch (int(head.a * 100) % 10)
// switch (2)
@ -905,7 +911,7 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
/// Plain
case 0: {
metallicRoughness = head.rg;
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 2])).rgb, 1);
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 1])).rgb, 1);
break;
}
/// RadialGradient
@ -913,16 +919,16 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
uint size = headUint % (1 << 15);
bool gradual = (headUint & (1 << 15)) != 0;
uint lastData = floatBitsToUint(style[styleIndex + 2 + 0 * 2]);
uint lastData = floatBitsToUint(style[styleHeadIndex + 1 + 0 * 2]);
float lastLevel = 0;
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + 0 * 2])).rgb, 1);
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 2 + 0 * 2])).rgb, 1);
for (uint i = 0; i < size; i++)
{
uint data = floatBitsToUint(style[styleIndex + 2 + i * 2]);
uint data = floatBitsToUint(style[styleHeadIndex + 1 + i * 2]);
float level = unpackUnorm2x16(data).y;
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + i * 2])).rgb, 1);
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 2 + i * 2])).rgb, 1);
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
if (d <= level)
{
@ -969,21 +975,24 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
}
}
/**
* @param styleIndex ÊäÈëstyleHeadµÄIndex£¬·µ»ØÏÂÒ»¸östyleµÄindex
*/
void nextStyleIndex(inout uint styleIndex)
{
uint headUint = floatBitsToUint(style[styleIndex + 1]);
uint headUint = floatBitsToUint(style[styleIndex]);
vec4 head = unpackUnorm4x8(headUint);
switch (int(head.a * 100) % 10)
{
/// Plain
case 0: {
styleIndex += 3;
styleIndex += 2;
break;
}
/// RadialGradient
case 1: {
uint size = headUint % (1 << 15);
styleIndex += 2 + size * 2;
styleIndex += 1 + size * 2;
break;
}
case 2: {
@ -998,9 +1007,9 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, ve
vec2 normal;
if (onVeryBegin)
{
if (endType%2 == 0)
if (endType % 2 == 0)
return true;
else if (endType%2 == 1)
else if (endType % 2 == 1)
normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
}
else
@ -1017,9 +1026,9 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
vec2 normal;
if (onVeryEnd)
{
if ((endType/2)%2 == 0)
if ((endType / 2) % 2 == 0)
return true;
else if ((endType/2)%2 == 1)
else if ((endType / 2) % 2 == 1)
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
}
else
@ -1034,11 +1043,7 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
void main()
{
uvec2 pixelLocation = gl_GlobalInvocationID.xy;
// imageStore(gBaseColor, ivec2(pixelLocation), vec4(vec2(pixelLocation)/vec2(imageSize(gBaseColor)), 1,1));
vec4 color = vec4(0);
// if(isinf(path[0].x)) imageStore(gBaseColor, ivec2(pixelLocation),
// vec4(vec2(pixelLocation)/vec2(imageSize(gBaseColor)), 1,1)); return;
for (uint styleIndex = 0; styleIndex < styleSize;)
{
styleIndex += 6;
@ -1063,7 +1068,7 @@ void main()
continue;
}
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
++pathIndex;
num_its += cubic_bezier_int_test(localUV, p[0], p[1], p[2], p[3]);
p3Last = p[3];
p2Last = p[2];
@ -1075,22 +1080,23 @@ void main()
vec4 head = unpackUnorm4x8(floatBitsToUint(style[styleIndex]));
if (head.z == 0)
{
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+1])).rgb, 1);
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1])).rgb, 1);
}
}
styleIndex += 2;
}
else // Stroke
{
uint widthMapSize = floatBitsToUint(style[styleIndex + 1]);
float minDistance = 1e38;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1]));
styleIndex += widthMapSize + 2;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex]));
float lineType = floor(styleHead.b * 10);
int endType = int(round(styleHead.b * 100)) % 10;
int debugBegin = 0;
bool onVeryBegin = false;
bool onVeryEnd = false;
vec2 tangentEndLast;
vec2 tangentEndLast = vec2(0);
vec2 tangentFirstBegin;
uint lastHitIndex = 0;
bool lastHitElement = false;
@ -1103,12 +1109,12 @@ void main()
pBegin = path[++pathIndex];
p3Last = pBegin;
p2Last = pBegin;
if(endType == 4 /*StrokeEndType::kClosed*/)
if (endType == 4 /*StrokeEndType::kClosed*/)
{
//onVeryBegin = false;
vec2 lastP1 = path[pathSize-3];
vec2 lastP2 = path[pathSize-2];
vec2 lastP3 = path[pathSize-1];
// onVeryBegin = false;
vec2 lastP1 = path[pathSize - 4];
vec2 lastP2 = path[pathSize - 3];
vec2 lastP3 = path[pathSize - 2];
if (lastP3 != lastP2)
tangentEndLast = normalize(lastP3 - lastP2);
else
@ -1119,13 +1125,13 @@ void main()
continue;
}
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
vec2 lengthRate = path[++pathIndex];
vec2 tangentBeginNext;
if (pathIndex + 1 < pathSize)
{
vec2 pTemp = path[pathIndex + 1];
if (isinf(pTemp.x))
{
{
onVeryEnd = true;
}
else
@ -1140,31 +1146,35 @@ void main()
}
else
{
if(endType == 4 /*StrokeEndType::kClosed*/)
if (endType == 4 /*StrokeEndType::kClosed*/)
{
//onVeryEnd = false;
// onVeryEnd = false;
tangentBeginNext = tangentFirstBegin;
}
else
onVeryEnd = true;
}
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
if (d <= strokeWidth)
vec2 tangentEnd;
if (p[3] != p[2])
tangentEnd = normalize(p[3] - p[2]);
else
tangentEnd = normalize(p[3] - p[1]);
float t;
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true, t);
float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t);
if (d <= localWidth)
{
bool onBegin = distance(localUV, p[0]) <= strokeWidth;
bool onEnd = distance(localUV, p[3]) <= strokeWidth;
bool onBegin = t<1e-5;
bool onEnd = t>1-1e-5;
//bool onBegin = true;
//bool onEnd = true;
vec2 tangentBegin;
vec2 tangentEnd;
if (p[0] != p[1])
tangentBegin = normalize(p[0] - p[1]);
else
tangentBegin = normalize(p[0] - p[2]);
if (p[3] != p[2])
tangentEnd = normalize(p[3] - p[2]);
else
tangentEnd = normalize(p[3] - p[1]);
bool hit = d < minDistance;
if (onBegin)
@ -1192,19 +1202,19 @@ void main()
hitElement = true;
// elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness);
}
}
tangentEndLast = tangentEnd;
if(pathIndex == 4)
if (pathIndex == 5)
tangentFirstBegin = tangentBegin;
}
tangentEndLast = tangentEnd;
p3Last = p[3];
p2Last = p[2];
onVeryBegin = false;
}
nextStyleIndex(styleIndex);
}
if (hitElement)
color = elementColor;

View File

@ -959,11 +959,11 @@ bool angleLargeThanPi(vec2 a, vec2 b)
return a.x * b.y - b.x * a.y < 0;
}
void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
{
elementColor = vec4(1);
metallicRoughness = vec2(0.8);
uint headUint = floatBitsToUint(elementData[styleIndex + 1]);
uint headUint = floatBitsToUint(elementData[styleHeadIndex]);
vec4 head = unpackUnorm4x8(headUint);
switch (int(head.a * 100) % 10)
// switch (2)
@ -971,7 +971,7 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
/// Plain
case 0: {
metallicRoughness = head.rg;
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 2])).rgb, 1);
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 1])).rgb, 1);
break;
}
/// RadialGradient
@ -979,16 +979,16 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
uint size = headUint % (1 << 15);
bool gradual = (headUint & (1 << 15)) != 0;
uint lastData = floatBitsToUint(elementData[styleIndex + 2 + 0 * 2]);
uint lastData = floatBitsToUint(elementData[styleHeadIndex + 1 + 0 * 2]);
float lastLevel = 0;
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 3 + 0 * 2])).rgb, 1);
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 2 + 0 * 2])).rgb, 1);
for (uint i = 0; i < size; i++)
{
uint data = floatBitsToUint(elementData[styleIndex + 2 + i * 2]);
uint data = floatBitsToUint(elementData[styleHeadIndex + 1 + i * 2]);
float level = unpackUnorm2x16(data).y;
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 3 + i * 2])).rgb, 1);
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 2 + i * 2])).rgb, 1);
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
if (d <= level)
{
@ -1152,7 +1152,9 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
float minDistance = 1e38;
uint lineCount = elementIndexs[contourIndex];
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 1]));
uint widthMapSize = floatBitsToUint(elementData[styleIndex + 1]);
styleIndex += widthMapSize + 2;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex]));
float lineType = floor(styleHead.b * 10);
int endType = int(round(styleHead.b * 100)) % 10;
vec2 p3Last = vec2(1e38);

View File

@ -413,6 +413,8 @@ int CubicBezierSignedDistance::solve_quadric(dvec2 coeffs, dvec2& roots) {
return 2;
}
else
return 0;
}
void CubicBezierSignedDistance::sort_roots3(dvec3& roots) {

View File

@ -77,8 +77,8 @@ bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
}
Renderer::MaterialStyleStroke::MaterialStyleStroke(float halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
Renderer::MaterialStyleStroke::MaterialStyleStroke(float halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke, std::map<float, float> widthMap)
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke), widthMap(widthMap)
{
}
@ -89,7 +89,9 @@ MaterialStyleType Renderer::MaterialStyleStroke::type() const
std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
{
std::vector<GLfloat> v = { halfWidth };
std::vector<GLfloat> v = { halfWidth, glm::uintBitsToFloat(widthMap.size()) };
for(auto& [lengthRate, widthRate] : widthMap)
v.emplace_back(glm::uintBitsToFloat(glm::packUnorm2x16(glm::vec2(lengthRate, widthRate))));
auto encoded = materialStroke->encoded();
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
head.b = (float)strokeType / 10. + (float)endType / 100.;

View File

@ -48,7 +48,7 @@ namespace Renderer
class MaterialStyleStroke : public MaterialStyle
{
public:
MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke);
MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke, std::map<float, float> widthMap = {});
virtual MaterialStyleType type() const override;
virtual std::vector<GLfloat> encoded() const override;
virtual std::unique_ptr<MaterialStyle> clone() const override;
@ -59,6 +59,7 @@ namespace Renderer
StrokeType strokeType;
StrokeEndType endType;
std::shared_ptr<MaterialStroke> materialStroke;
std::map<float, float> widthMap;
static const std::array<std::pair<QString, StrokeEndType>, 4> strokeEndTypeNames;
};
}

View File

@ -15,6 +15,8 @@ using namespace Renderer;
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
{
float lastLength = 0;
glm::vec2 lastPoint;
std::vector<glm::vec2> pathBuffer;
for (int i = 0; i < path.elementCount(); i++)
{
@ -24,18 +26,24 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
case QPainterPath::MoveToElement:
//qDebug() << "MoveToElement";
//qDebug() << element;
pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity()));
pathBuffer.push_back(glm::vec2(element.x, element.y));
pathBuffer.emplace_back(std::numeric_limits<float>::infinity());
pathBuffer.emplace_back(element.x, element.y);
lastLength = 0;
lastPoint = glm::vec2(element.x, element.y);
break;
case QPainterPath::LineToElement:
{
//qDebug() << "LineToElement";
//qDebug() << element;
glm::vec2 end = glm::vec2(element.x, element.y);
glm::vec2 mid = (pathBuffer.back() + end) / 2.f;
glm::vec2 mid = (lastPoint + end) / 2.f;
pathBuffer.push_back(mid);
pathBuffer.push_back(mid);
pathBuffer.push_back(end);
float length = (i + 1.) / path.elementCount();
pathBuffer.emplace_back(lastLength, length);
lastLength = length;
lastPoint = end;
break;
}
case QPainterPath::CurveToElement:
@ -49,16 +57,20 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
element = path.elementAt(++i);
//qDebug() << element;
glm::vec2 p3 = glm::vec2(element.x, element.y);
if (p3 != pathBuffer.back())
if (p3 != lastPoint)
{
pathBuffer.push_back(p1);
pathBuffer.push_back(p2);
pathBuffer.push_back(p3);
float length = (i + 1.) / path.elementCount();
pathBuffer.emplace_back(lastLength, length);
lastLength = length;
lastPoint = p3;
}
break;
}
case QPainterPath::CurveToDataElement:
pathBuffer.push_back(glm::vec2(element.x, element.y));
qCritical() << "Read QPainterPath Error";
break;
}
}

View File

@ -206,9 +206,9 @@ namespace UnitTest
}
TEST_METHOD(TestBothSidesClosed)
{
QPainterPath closedPath;
SvgFileLoader().loadSvgFile("../../svg/4_L0.svg", closedPath);
closedPath = QTransform::fromScale(5, 5).map(closedPath);
QPainterPath testPath;
SvgFileLoader().loadSvgFile("../../svg/4_L0.svg", testPath);
testPath = QTransform::fromScale(5, 5).map(testPath);
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
@ -220,11 +220,60 @@ namespace UnitTest
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(20, StrokeType::kLeftSide, StrokeEndType::kClosed,
std::make_shared<MaterialStyleStroke>(10, StrokeType::kBothSides, StrokeEndType::kClosed,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style, closedPath);
TestGLWidget w(style, testPath);
w.show();
a.exec();
}
TEST_METHOD(TestAcuteAngle)
{
QPainterPath testPath;
testPath.moveTo(50, 50);
testPath.lineTo(300, 300);
testPath.lineTo(300, 50);
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>(20, StrokeType::kRightSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style, testPath);
w.show();
a.exec();
}
TEST_METHOD(TestBothSidesGradientWidth)
{
QPainterPath testPath;
testPath.moveTo(50, 50);
testPath.cubicTo(50, 200, 200, 300, 300, 300);
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>(20, StrokeType::kLeftSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style, testPath);
w.show();
a.exec();
}

View File

@ -343,24 +343,6 @@
</QtMoc>
<ClInclude Include="qtmaterialtoggle_p.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="release\moc_predefs.h.cbt">
<FileType>Document</FileType>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\fonts\Roboto\Roboto-Black.ttf" />
<None Include="..\fonts\Roboto\Roboto-Bold.ttf" />