diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp index 6df36af92b..1a6cba8a01 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp @@ -471,19 +471,8 @@ public: if (fillType.isGradient()) { - auto p1 = fillType.gradient->point1; - auto p2 = fillType.gradient->point2; - - if (transform.isOnlyTranslation()) - { - Point translation { transform.getTranslationX(), transform.getTranslationY() }; - p1 += translation; - p2 += translation; - } - else - { - currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); - } + const auto p1 = fillType.gradient->point1; + const auto p2 = fillType.gradient->point2; if (fillType.gradient->isRadial) { @@ -498,11 +487,8 @@ public: linearGradient->SetEndPoint ({ p2.x, p2.y }); } } - else - { - currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); - } + currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); currentBrush->SetOpacity (fillType.getOpacity()); return currentBrush; diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index efd547698b..628ee1bc0c 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -1386,6 +1386,13 @@ public: testGradientFillTransform (1.0f); testGradientFillTransform (1.5f); } + + beginTest ("Text gradient fill transform should compose with world transform correctly"); + { + testTextGradientFillTransform (2.0f); + testTextGradientFillTransform (1.5f); + testTextGradientFillTransform (1.0f); + } } static Image createEdgeMask (int sourceWidth, @@ -1487,14 +1494,6 @@ public: return p.toFloat().transformedBy (AffineTransform::scale (scale)).roundToInt(); }; - const auto approximatelyEqual = [] (const Colour& a, const Colour& b) - { - return std::abs (a.getRed() - b.getRed()) < 2 - && std::abs (a.getGreen() - b.getGreen()) < 2 - && std::abs (a.getBlue() - b.getBlue()) < 2 - && std::abs (a.getAlpha() - b.getAlpha()) < 2; - }; - const Point centre { circleSize / 2, circleSize / 2 }; const Point brushOffset { brushTranslation, brushTranslation }; @@ -1512,6 +1511,68 @@ public: expect (image.getPixelAt (blackPosition.getX(), blackPosition.getY()) == Colours::black); } } + + void testTextGradientFillTransform (float scale) + { + const auto typeface = loadTypeface (FontBinaryData::Karla_Regular_Typo_Off_Offsets_Off); + + constexpr int size = 500; + + Image image { Image::RGB, + roundToInt (size * scale), + roundToInt (size * scale), + true }; + + const auto fillCol1 = Colours::cyan; + const auto fillCol2 = Colours::magenta; + const auto fillColMiddle = fillCol1.interpolatedWith (fillCol2, 0.5f); + + { + Graphics g { image }; + g.addTransform (AffineTransform::scale (scale)); + + g.setFont (FontOptions { typeface }.withPointHeight (50)); + g.setGradientFill ({ fillCol1, { size * 0.5f - 80, 0 }, fillCol2, { size * 0.5f + 80, 0.0f }, false }); + + for (auto i = 0; i != 10; ++i) + { + g.drawText (String::repeatedString ("-", 100), + Rectangle { size * 2, size }.translated (i * 50 - 500, i * 50), + Justification::topLeft, + false); + } + } + + const auto getPixelAtScaled = [&image, scale] (Point p) + { + const auto scaled = p.toFloat().transformedBy (AffineTransform::scale (scale)).roundToInt(); + return image.getPixelAt (scaled.x, scaled.y); + }; + + expect (approximatelyEqual (getPixelAtScaled ({ 15, 27 }), fillCol1)); + expect (approximatelyEqual (getPixelAtScaled ({ 485, 27 }), fillCol2)); + + expect (approximatelyEqual (getPixelAtScaled ({ 15, 77 }), fillCol1)); + expect (approximatelyEqual (getPixelAtScaled ({ 485, 77 }), fillCol2)); + expect (approximatelyEqual (getPixelAtScaled ({ 250, 77 }), fillColMiddle)); + + expect (approximatelyEqual (getPixelAtScaled ({ 15, 477 }), fillCol1)); + expect (approximatelyEqual (getPixelAtScaled ({ 485, 477 }), fillCol2)); + expect (approximatelyEqual (getPixelAtScaled ({ 250, 477 }), fillColMiddle)); + } + + static bool approximatelyEqual (const Colour& a, const Colour& b) + { + return std::abs (a.getRed() - b.getRed()) < 2 + && std::abs (a.getGreen() - b.getGreen()) < 2 + && std::abs (a.getBlue() - b.getBlue()) < 2 + && std::abs (a.getAlpha() - b.getAlpha()) < 2; + } + + static Typeface::Ptr loadTypeface (Span data) + { + return Typeface::createSystemTypefaceFor (data.data(), data.size()); + } }; static Direct2DGraphicsContextTests direct2DGraphicsContextTests;