Draw rotated text

Hi,

What is the correct way to draw roated text in Juce? And is it possible, that the function Graphics::addTransform has changed some time ago and is now resetting the bounds?

I am doing the following:

void MyCompoment::paint (Graphics& g)
{
   g.drawSingleLineText("Text One", 70, 30, Justification::left);
   //"Text One" is drawn OK
   float dbg_bounds = g.getClipBounds().getRight();
   //dbg_bounds is 750, just as I set it 
   g.addTransform(AffineTransform::identity.rotated(-float_Pi / 2.0f));
   dbg_bounds = g.getClipBounds().getRight();
   //strangely, dbg_bounds is 1 now. It seems, addTransform resetted it
   g.drawSingleLineText("Text Two",30,190,Justification::left);
   //because the bounds has size 1, the "Text Two" is not shown 
}

So basically I am using addTransform in order to draw rotated text. The problem is: After I call addTransform, the bounds of my Graphics object are reset to 1. As a result, no text is drawn, because everything is clipped.

I guess, I am missing something simple here? :-)

The physical clip bounds of a Graphics don't change, but when you apply a transform, then obviously those bounds will appear to be in a different place, because the whole coordinate space has now changed.

Thanks! Did not think about that. Works now. 

One question: has that behaviour changed some time ago? I seem to remember it worked differently before.

Don't think it has changed, unless it was broken before. I think it's all working as intended now.

Here is a simple way of doing it;

drawMultiLineText(). Just set a width about half of font size, works like a charm, except I can’t seem to get it to make a new line if there is a ‘space’ character!

g.setFont (fontSize);
g.drawMultiLineText ("Vertical", x , fontSize, fontSize / 2, Justification::centred);

:thinking: won’t that simply force each letter to be on a separate line, but still with their horizontal baseline?

What do you mean “still with their horizontal baseline”?

Anyways I am using it right now in an app I am designing, looks fine.

I believe he is saying that the letters still draw with normal orientation, not actually rotated. If that is the case, it’s not ‘rotated’.

Oops my bad, I thought the discussion was about drawing text on a different axis, but each character still in “normal” rotation.

Thanks for your tips.
Have to admit, I don’t really remember the exact use case from then. Already five years ago :slight_smile:
But in case I get into the same situation again, I will test your hint.

You’ll most likely have to convert your string of text into a GlyphArrangement and then from there, convert it to a Path object, which you can then apply a transform to.

RotateFont

struct MainComponent : Component
{
    MainComponent()
    {
        rotationSlider.setNormalisableRange(NormalisableRange<double>(-90.0, 90.0));
        addAndMakeVisible(rotationSlider);

        rotationSlider.onValueChange = [this]() { this->repaint(); };
        setSize (300, 200);
    }

    void paint (Graphics&) override;
    void resized() override
    {
        rotationSlider.setBounds(0, 0, 30, getHeight());
    }
private:
    Slider rotationSlider { Slider::LinearVertical, Slider::NoTextBox };

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
void MainComponent::paint (Graphics& g)
{
    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));

    GlyphArrangement ga;
    ga.addLineOfText(Font(32.0f), "Hello World!", 0, 0);
    Path p;
    ga.createPath(p);

    auto pathBounds = p.getBounds();

    p.applyTransform(AffineTransform()
                     .rotated(degreesToRadians(rotationSlider.getValue()),
                              pathBounds.getCentreX(),
                              pathBounds.getCentreY())
                     .translated(getWidth() * 0.25f, getHeight() * 0.5f)
                     );

    g.setColour (Colours::white);
    g.fillPath(p);
}
7 Likes