BR: Drawing Text with a gradient is broken on Windows

I’m trying to draw text with a gradient. The white box surrounds the component and the gradient should go from the first white line to the second white line, this works fine on macOS, but the gradient is in the wrong spot on Windows.

macOS:

Windows:

I tried two methods. Create a gradient with a smaller rect, or a gradient with a larger rect, and use addColour to define the position of the gradient.

Code is here: juce_bugs/TextGrad/Source/MainComponent.h at master · FigBug/juce_bugs · GitHub

I should note that this behavior is not consistent, it fails on my machine but works fine on my co-workers machine.

I’m not too familiar with the Direct2D code, but I think the problem is somewhere in this area.

diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
index 4ffa939266..addbe5c4f2 100644
--- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
+++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp
@@ -1680,7 +1680,11 @@ void Direct2DGraphicsContext::drawGlyphs (Span<const uint16_t> glyphNumbers,
     if (fontFace == nullptr)
         return;

-    const auto brush = currentState->getBrush (SavedState::BrushTransformFlags::applyFillTypeTransform);
+    const auto fillTransform = currentState->currentTransform.isOnlyTranslated
+                             ? SavedState::BrushTransformFlags::applyWorldAndFillTypeTransforms
+                             : SavedState::BrushTransformFlags::applyFillTypeTransform;
+
+    const auto brush = currentState->getBrush (fillTransform);

     if (! brush)
         return;

Do these machines have different windows dpi scaling settings? Or different GPUs?

Hmm, indeed, I can repro the issue only if the scaling is 1. Thank you for posting about this and for the repro code.

A fix is out on develop

1 Like

It’s still broken on my machine. I use a desktop scale of 200%. Before this change, the gradient was in the wrong location, now it doesn’t apply a gradient at all, or the transform is different, so only the color on the left side of the gradient is used everwhere.

I’ve added a g.fillRect () (for debugging/demonstration) right above the g.drawText call. The lines with the gradient on the right, should also affect the text, but as you can see, the text stays the same color.

The boxes without a gradient in them, only use g.setColour and as such work as intended.

I have updated the test program to show the issue still exists. The inner component is now scaled, when you resize the window, the scale is adjusted. When scale = 1.0 it works, otherwise it is broken. Note, I believe the issue is the gradient isn’t taking the position the text is being drawn at into account. On Line 29, change gradRect to getLocalBounds() and it works fine.

Screen Recording 2025-03-17 at 2.39.19 PM 2

Thank you for the updated test.

I have a new fix, would you mind taking a look to see if it fixes all issues for you? I think it’s right, but I thought that about the previous one too.

d2d-text-gradient.patch (7.7 KB)

Seems good on my machine, I’ll get Mike to test on his as well.

Edit: Mike confirms fixed on his machine.

1 Like

Yep, works now:

1 Like

Will this be merged soon? The version in the development branch is broken. Even though not every possible case (rotation, shearing, etc.) was tested, this is still better than the current version.

The fix is now live on develop

2 Likes