Question

Can anyone help me find a way to scale a string / character in Java (Graphics2D) to exactly fit a rectangle of a given size (so that it touches the rectangle from the inside)?

This is what I have so far:

String s = "S"; // always a single character!
Rectangle rect = getRect(); // defines the desired size and position
AffineTransform transform = new AffineTransform();
transform.setToTranslation(rect.getX(), rect.getY());
transform.scale(rect.getWidth() / (double) fm.stringWidth(s), 
                rect.getHeight() / (double) fm.getAscent());
FontRenderContext frc = image.getFontRenderContext();
TextLayout tl = new TextLayout(s, g2d.getFont(), frc);
Shape shape = tl.getOutline(transform);
g2d.setClip(shape);
g2d.fill(shape.getBounds());

The problem I have running this code is that although the string is scaled to fit the rectangles size approximately, it does not fit it exactly, ie. it does not touch the rectangles boundaries from the inside (which is what I want it to do!).

Does it help using a different Font? I am using a monospace-font at the moment. Or, do I have to do the scaling differently?

Thanks for your help!

Was it helpful?

Solution

I figured out a way to do what I want to do, and thought I might share it:

My main problem was the height of different characters, so instead of using a Font's ascent, I used its outline's max and min Y-coordinates to calculate its height. See below.

String s = "S"; // always a single character!
Rectangle rect = getRect(); // defines the desired size and position
FontMetrics fm = g2d.getFontMetrics();
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout tl = new TextLayout(s, g2d.getFont(), frc);
AffineTransform transform = new AffineTransform();
transform.setToTranslation(rect.getX(), rect.getY());
double scaleY = 
   rect.getHeight() / (double) (tl.getOutline(null).getBounds().getMaxY() 
                                - tl.getOutline(null).getBounds().getMinY());
transform.scale(rect.getWidth() / (double) fm.stringWidth(s), scaleY);
Shape shape = tl.getOutline(transform);
g2d.setClip(shape);
g2d.fill(shape.getBounds());

I hope that helps someone with a similar problem!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top