Search code examples
javatextawtbufferedimagejava-2d

No feature of AttributedString is working other than strikethrough


I have to write a string to BufferedImage. I am using AtrributedString. TextAttribute.STRIKETHROUGH is working. Superscript, Subscript and others are not working.

public class TextAttributesSuperscript  {

    static String Background = "input.png";
    static int curX = 10;
    static int curY = 50;

    public static void main(String[] args) throws Exception {
        AttributedString attributedString= new AttributedString("this is data. this data should be super script");

        attributedString.addAttribute(TextAttribute.FONT, new Font("TimesRoman", Font.PLAIN, 18));
        attributedString.addAttribute(TextAttribute.FOREGROUND, Color.BLACK);


        attributedString.addAttribute(TextAttribute.FONT, new Font("TimesRoman", Font.BOLD, 18), 30,33);
        attributedString.addAttribute(TextAttribute.FOREGROUND, Color.BLUE, 29,33);
    attributedString.addAttribute(TextAttribute.SUPERSCRIPT,TextAttribute.SUPERSCRIPT_SUPER,30,33);

        final BufferedImage image = ImageIO.read(new File(Background));
        Graphics g = image.getGraphics();
        g.drawString(attributedString.getIterator(), curX, curY);
        g.dispose();
        ImageIO.write(image, "png", new File("output.png"));
    }
}

While executing above code. The superscript part was not working(the text was not getting printed like superscript)


Solution

  • I'm not really sure why your code doesn't work, as it does seem completely logical to do it this way. And I don't understand why some attributes work and some don't.

    But according to the Java 2D Tutorial: Using Text Attributes to Style Text, the SUPERSCRIPT attribute should be set on the font, rather than on the text itself. Ie. using Font.deriveFont(Map<Attribute, ?> attributes).

    The following works for me (I modified your code slightly to not depend on your background file):

    public class TextAttributesSuperscript  {
    
        static int curX = 10;
        static int curY = 50;
    
        public static void main(String[] args) throws Exception {
            AttributedString attributedString = new AttributedString("this is data. this data should be super script");
    
            attributedString.addAttribute(TextAttribute.FONT, new Font("TimesRoman", Font.PLAIN, 18));
            attributedString.addAttribute(TextAttribute.FOREGROUND, Color.BLACK);
    
            Font superScript = new Font("TimesRoman", Font.BOLD, 18)
                    .deriveFont(Collections.singletonMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER));
            attributedString.addAttribute(TextAttribute.FONT, superScript, 30, 33);
            attributedString.addAttribute(TextAttribute.FOREGROUND, Color.BLUE, 30,33);
    
            BufferedImage image = new BufferedImage(400, 100, BufferedImage.TYPE_INT_ARGB);
    
            Graphics2D g = image.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
            g.setColor(Color.WHITE);
    
            g.fillRect(0, 0, image.getWidth(), image.getHeight());
            g.drawString(attributedString.getIterator(), curX, curY);
            g.dispose();
    
            ImageIO.write(image, "png", new File("output.png"));
        }
    }