Reputation: 1776
I am trying to zoom out a text using the code below, but scaling does not scale the font of the text properly. I believe it does not keep the result the same.
My goal is to zoom html strings, but the issue still remains there, too. For example, if I paint the html text (different foreground and background in a JTextPane), it will be as if the string is dancing. :(
In other words, it does not scale smoothly.
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;
public class scaledText extends javax.swing.JDialog {
public scaledText(java.awt.Frame parent, boolean modal) {
super(parent, modal);
setSize(800, 450);
setLocationRelativeTo(null);
setContentPane(new JPanel() {
private float timer = 0.001f;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
timer += 0.01f;
if (timer > 2.7) {
timer = 0.001f;
}
float t = Math.min(timer, 2.5f);
g2.setFont(new Font("Arial", 0, 60));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
String text = "This is a text";
FontMetrics fm = new FontMetrics(g2.getFont()) {
};
g2.translate((600 - g2.getFontMetrics(g2.getFont()).stringWidth(text)) / 2, (450 - fm.getHeight()) / 2);
g2.scale(t, t);
g2.drawString(text, 0f, 0f);
g2.draw(new Ellipse2D.Double(0, 0, 100, 100));
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
}
this.repaint();
}
});
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
scaledText dialog = new scaledText(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
}
Upvotes: 1
Views: 1488
Reputation: 1776
Here is another way which enables me to draw strings. However, It does not allow me to preserve font style, and colors :( That gives me just the shape of the text. But it scales perfectly.
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedString;
import javax.swing.JPanel;
public class scaledText extends javax.swing.JDialog {
public static Shape getTextShape(Graphics2D g2d, String text, Font font, boolean ltr) {
AttributedString attstring = new AttributedString(text);
attstring.addAttribute(TextAttribute.FONT, font);
attstring.addAttribute(TextAttribute.RUN_DIRECTION, ltr ? TextAttribute.RUN_DIRECTION_LTR : TextAttribute.RUN_DIRECTION_RTL);
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout t = new TextLayout(attstring.getIterator(), frc);
return t.getOutline(null);
}
public scaledText(java.awt.Frame parent, boolean modal) {
super(parent, modal);
setSize(800, 450);
setLocationRelativeTo(null);
setContentPane(new JPanel() {
private float timer = 1.001f;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
timer += 0.005f;
if (timer > 2.7) {
timer = 1.001f;
}
float t = Math.min(timer, 2.5f);
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
g2.setFont(new Font("Arial", 0, 100));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
String text = "This is a text مرحبا";
Shape shape = getTextShape(g2, text, g2.getFont(), true);
FontMetrics fm = new FontMetrics(g2.getFont()) {
};
g2.translate(10, (450 - fm.getHeight()) / 2);
g2.scale(t / 2.5, t / 2.5);
g2.fill(shape);
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
}
this.repaint();
}
});
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
scaledText dialog = new scaledText(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
}
Upvotes: 1