diff --git a/code/Drawing/Raster.cpp b/code/Drawing/Raster.cpp index eff36844be..6d817483da 100644 --- a/code/Drawing/Raster.cpp +++ b/code/Drawing/Raster.cpp @@ -24,10 +24,26 @@ #include #include "Core/Containers/AlignedVector.h" #include "Core/Log/Log.h" +#include "Core/Math/Envelope.h" #include "Core/Misc/Align.h" #include "Drawing/Image.h" #include "Drawing/Raster.h" +namespace traktor +{ + +Color4f operator * (float v, const Color4f& c) +{ + return c * Scalar(v); +} + +Color4f operator * (const Color4f& c, float v) +{ + return c * Scalar(v); +} + +} + namespace traktor::drawing { @@ -141,29 +157,25 @@ class SolidStyle< agg::rgba8 > : public IStyle< agg::rgba8 > class LinearGradientStyle : public IStyle< agg::rgba8 > { public: - LinearGradientStyle(const Matrix33& gradientMatrix, const AlignedVector< std::pair< Color4f, float > >& colors) + explicit LinearGradientStyle(const Matrix33& gradientMatrix, const AlignedVector< std::pair< Color4f, float > >& colors) : m_gradientMatrix(gradientMatrix) - , m_colors(colors) { - // Premultiply to be in "byte range". - for (AlignedVector< std::pair< Color4f, float > >::iterator i = m_colors.begin(); i != m_colors.end(); ++i) - i->first *= Scalar(255.0f); + for (const auto& p : colors) + m_envelope.addKey(p.second, p.first * 255.0_simd); } virtual void generateSpan(agg::rgba8* span, int x, int y, unsigned len) const override final { - float s = m_colors.front().second; - float e = m_colors.back().second; - float n = 1.0f / (e - s); + float s = 0.0f; + float n = 1.0f; Vector2 pt = m_gradientMatrix * Vector2(float(x), float(y)); Vector2 dt = m_gradientMatrix * Vector2(float(x + 1.0f), float(y)) - pt; for (unsigned i = 0; i < len; ++i) { - float f = clamp((pt.x - s) * n, 0.0f, 1.0f); - - Color4f c(lerp(m_colors.front().first, m_colors.back().first, Scalar(f))); + const float f = clamp((pt.x - s) * n, 0.0f, 1.0f); + const Color4f c = m_envelope(f); span[i] = agg::rgba8( agg::int8u(c.getRed()), @@ -178,36 +190,32 @@ class LinearGradientStyle : public IStyle< agg::rgba8 > private: Matrix33 m_gradientMatrix; - AlignedVector< std::pair< Color4f, float > > m_colors; + Envelope< Color4f, LinearEvaluator< Color4f > > m_envelope; }; /*! Radial gradient style for 32-bit colors. */ class RadialGradientStyle : public IStyle< agg::rgba8 > { public: - RadialGradientStyle(const Matrix33& gradientMatrix, const AlignedVector< std::pair< Color4f, float > >& colors) + explicit RadialGradientStyle(const Matrix33& gradientMatrix, const AlignedVector< std::pair< Color4f, float > >& colors) : m_gradientMatrix(gradientMatrix) - , m_colors(colors) { - // Premultiply to be in "byte range". - for (AlignedVector< std::pair< Color4f, float > >::iterator i = m_colors.begin(); i != m_colors.end(); ++i) - i->first *= Scalar(255.0f); + for (const auto& p : colors) + m_envelope.addKey(p.second, p.first * 255.0_simd); } virtual void generateSpan(agg::rgba8* span, int x, int y, unsigned len) const override final { - float s = m_colors.front().second; - float e = m_colors.back().second; - float n = 1.0f / (e - s); + float s = 0.0f; + float n = 1.0f; Vector2 pt = m_gradientMatrix * Vector2(float(x), float(y)); Vector2 dt = m_gradientMatrix * Vector2(float(x + 1.0f), float(y)) - pt; for (unsigned i = 0; i < len; ++i) { - float f = clamp(((pt * pt).length() - s) * n, 0.0f, 1.0f); - - Color4f c(lerp(m_colors.front().first, m_colors.back().first, Scalar(f))); + const float f = clamp(((pt * pt).length() - s) * n, 0.0f, 1.0f); + const Color4f c = m_envelope(f); span[i] = agg::rgba8( agg::int8u(c.getRed()), @@ -222,7 +230,7 @@ class RadialGradientStyle : public IStyle< agg::rgba8 > private: Matrix33 m_gradientMatrix; - AlignedVector< std::pair< Color4f, float > > m_colors; + Envelope< Color4f, LinearEvaluator< Color4f > > m_envelope; }; /*! Image style for 32-bit colors. */ @@ -435,7 +443,6 @@ class RasterImpl : public RefCountImpl< IRasterImpl > : m_rbuffer((agg::int8u*)image->getData(), image->getWidth(), image->getHeight(), image->getWidth() * image->getPixelFormat().getByteSize()) , m_pf(m_rbuffer) , m_renderer(m_pf) - // , m_closed(false) { } @@ -656,13 +663,13 @@ bool Raster::setImage(Image* image) m_impl = nullptr; if (image->getPixelFormat() == PixelFormat::getA8B8G8R8()) - m_impl = new RasterImpl< agg::pixfmt_rgba32, agg::rgba8 >(image); + m_impl = new RasterImpl< agg::pixfmt_rgba32_plain, agg::rgba8 >(image); else if (image->getPixelFormat() == PixelFormat::getB8G8R8A8()) - m_impl = new RasterImpl< agg::pixfmt_argb32, agg::rgba8 >(image); + m_impl = new RasterImpl< agg::pixfmt_argb32_plain, agg::rgba8 >(image); else if (image->getPixelFormat() == PixelFormat::getA8R8G8B8()) - m_impl = new RasterImpl< agg::pixfmt_bgra32, agg::rgba8 >(image); + m_impl = new RasterImpl< agg::pixfmt_bgra32_plain, agg::rgba8 >(image); else if (image->getPixelFormat() == PixelFormat::getR8G8B8A8()) - m_impl = new RasterImpl< agg::pixfmt_abgr32, agg::rgba8 >(image); + m_impl = new RasterImpl< agg::pixfmt_abgr32_plain, agg::rgba8 >(image); else if (image->getPixelFormat() == PixelFormat::getA8()) m_impl = new RasterImpl< agg::pixfmt_gray8, agg::gray8 >(image); diff --git a/code/Svg/ClassFactory.cpp b/code/Svg/ClassFactory.cpp index d400dedc82..a234c2b13e 100644 --- a/code/Svg/ClassFactory.cpp +++ b/code/Svg/ClassFactory.cpp @@ -90,6 +90,11 @@ class ShapeVisitorDelegate : public IShapeVisitor Ref< IRuntimeDelegate > m_delegateLeave; }; +Ref< Shape > Parser_parse(Parser* self, xml::Document* doc) +{ + return self->parse(doc); +} + RefArray< BoxedSubPath > Path_getSubPaths(Path* self) { RefArray< BoxedSubPath > bsp; @@ -124,6 +129,11 @@ void Shape_visit(Shape* self, IRuntimeDelegate* enter, IRuntimeDelegate* leave) self->visit(&visitor); } +Ref< drawing::Image > Rasterizer_raster(Rasterizer* self, const Document* document) +{ + return self->raster(document); +} + } T_IMPLEMENT_RTTI_FACTORY_CLASS(L"traktor.svg.ClassFactory", 0, ClassFactory, IRuntimeClassFactory) @@ -150,7 +160,7 @@ void ClassFactory::createClasses(IRuntimeClassRegistrar* registrar) const auto classParser = new AutoRuntimeClass< Parser >(); classParser->addConstructor(); - //classParser->addMethod("parse", &Parser::parse); + classParser->addMethod("parse", &Parser_parse); registrar->registerClass(classParser); auto classPath = new AutoRuntimeClass< Path >(); @@ -211,7 +221,7 @@ void ClassFactory::createClasses(IRuntimeClassRegistrar* registrar) const auto classRasterizer = new AutoRuntimeClass< Rasterizer >(); classRasterizer->addConstructor(); - // classRasterizer->addMethod("raster", &Rasterizer::raster); + classRasterizer->addMethod("raster", &Rasterizer_raster); registrar->registerClass(classRasterizer); } diff --git a/code/Svg/Parser.cpp b/code/Svg/Parser.cpp index 0c2ef05d3f..234d6f8a1c 100644 --- a/code/Svg/Parser.cpp +++ b/code/Svg/Parser.cpp @@ -347,7 +347,7 @@ Ref< Shape > Parser::parseRect(const xml::Element* elm) const float y = parseAttr(elm, L"y"); const float width = parseAttr(elm, L"width"); const float height = parseAttr(elm, L"height"); - const float round = parseAttr(elm, L"ry"); + const float round = parseAttr(elm, L"ry") * 2.0f; Path path; diff --git a/code/Svg/Rasterizer.cpp b/code/Svg/Rasterizer.cpp index befd0619e9..80fca7d789 100644 --- a/code/Svg/Rasterizer.cpp +++ b/code/Svg/Rasterizer.cpp @@ -9,6 +9,7 @@ #include #include "Drawing/Image.h" #include "Drawing/Raster.h" +#include "Drawing/Filters/ScaleFilter.h" #include "Svg/Document.h" #include "Svg/Gradient.h" #include "Svg/IShapeVisitor.h" @@ -171,12 +172,29 @@ Ref< drawing::Image > Rasterizer::raster(const Document* document, float scale, if (width <= 0 || height <= 0) return nullptr; - Ref< drawing::Image > image = new drawing::Image(drawing::PixelFormat::getR8G8B8A8(), width, height); - image->clear(Color4f(1.0f, 1.0f, 1.0f, 0.0f)); + const int32_t ss = 1; + + Ref< drawing::Image > image = new drawing::Image( + drawing::PixelFormat::getR8G8B8A8(), + width * ss, + height * ss + ); + image->clear(Color4f(0.0f, 0.0f, 0.0f, 0.0f)); if (!raster(document, image, pageOffsetX, pageOffsetY)) return nullptr; + if (ss > 1) + { + const drawing::ScaleFilter scaleFilter( + width, + height, + drawing::ScaleFilter::MnAverage, + drawing::ScaleFilter::MgLinear + ); + image->apply(&scaleFilter); + } + return image; } diff --git a/resources/runtime/themes/Dark/New/Shader/Tools.svg b/resources/runtime/themes/Dark/New/Shader/Tools.svg index 7d23537b7a..ac5ed408af 100644 --- a/resources/runtime/themes/Dark/New/Shader/Tools.svg +++ b/resources/runtime/themes/Dark/New/Shader/Tools.svg @@ -7,7 +7,7 @@ viewBox="0 0 576 32" id="svg2" version="1.1" - inkscape:version="1.3 (0e150ed6c4, 2023-07-21)" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" sodipodi:docname="Tools.svg" inkscape:export-filename="C:\private\traktor\res\icons-new\g4486.png" inkscape:export-xdpi="90" @@ -27,19 +27,19 @@ borderopacity="1" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:zoom="4.1519427" - inkscape:cx="144.39024" - inkscape:cy="5.7804266" + inkscape:zoom="2.0759714" + inkscape:cx="121.14811" + inkscape:cy="-11.320002" inkscape:document-units="px" - inkscape:current-layer="layer27" + inkscape:current-layer="g5948" showgrid="true" inkscape:snap-global="true" inkscape:snap-grids="true" inkscape:snap-to-guides="false" - inkscape:window-width="5120" - inkscape:window-height="1387" - inkscape:window-x="-8" - inkscape:window-y="-8" + inkscape:window-width="1440" + inkscape:window-height="777" + inkscape:window-x="0" + inkscape:window-y="32" inkscape:window-maximized="1" units="px" inkscape:showpageshadow="false" @@ -165,82 +165,6 @@ y1="232.88951" x2="-74.915131" y2="232.88951" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -