7

While playing around with the Java font class and Swing, I set the font size to a negative value.

I discovered that this makes the text be drawn upside down. Is this a bug or a feature? Can anyone explain why this behavior happens?

Try it out:

import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class UpsideDown extends JFrame{

    public UpsideDown(){
        setSize(500,500);
        setContentPane(new Panel());
        setVisible(true);
    }

    public class Panel extends JPanel{
        public void paintComponent(Graphics g){
            Font f = new Font("Sans-Serif", Font.PLAIN, -50);
            g.setFont(f);
            g.drawString("Upside Down", 400, 100);
        }
    }

    public static void main(String args[]){
        new UpsideDown();
    }
}

Upside Down

2
  • For vetor fonts coordinates are calculated wih the font size as part of the equation. Commented Sep 8, 2013 at 9:50
  • @ThorbjørnRavnAndersen Prefixed with WTE 'not a bug' - I'd consider that an answer. Commented Sep 8, 2013 at 9:51

2 Answers 2

6

Seems like this is happening:

  1. Swing draws your font's height downwards, because it multiplies the font size with the glyph height of the font. -50 * glyph_height is negative -> drawing downwards instead of upwards.
  2. It also draws the glyph's (the letter's) width to the left, again because it multiplies your font size with the glyph width specified by the font.
Sign up to request clarification or add additional context in comments.

4 Comments

While technically true, it would probably be tagged either "invalid operation" or "undefined behavior", because there is no such thing as a 'negative font size'. Compare with RGB colors: what if some implementation allowed you to set a negative value for red?
@Jongware That would be a problem since graphics drivers usually use just a byte for each color. It would either cause your graphics driver to crash or then it would wrap around red = -1 to red = 255 :)
yes, but that is because RGB is implemented that way (fortunately you added "usually"). If 'font size' was stored in an unsigned type you wouldn't have this issue either.
@Jongware Unfortunately Java does not have unsigned primitive types, and the coders didn't add a check to Font constructor.
3

It is a feature.

In Swing there are very few, if any, absolute quantities. Virtually all quantities are algebraic, meaning that they can be negative, and they can participate in algebraic calculations which may change their sign, as the case is when you multiply by -1. For example, a rectangle can have a negative width, and that's perfectly fine. A font is not an exception to this rule.

By all means, do try this at home:

  • Take any piece of code that you might have lying around which draws 2D graphics in a Graphics2D graphics context. (That would be a component that overrides paintComponent( Graphics g ) and begins with Graphics2D g2 = (Graphics2D)g;) For example, you might have a component that draws a graph, like so:

enter image description here

  • Before the drawing operations, insert the following two lines:

              g2.scale( -1.0, -1.0 );
              g2.translate( -getWidth(), -getHeight() );
    
  • Now check the result. It will all be perfectly up-side down, like this:

enter image description here

Needless to say, if you double the x scale without doubling the y scale, everything will be elongated, including the characters of the text, like so:

enter image description here

This demonstrates how everything, all the way down to the individual coordinates of character glyphs, is an algebraic quantity in Swing.

This gives a great degree of freedom. If you want to invert the graph but keep the text upright, one way to achieve it is to make the font size negative.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.