jmeter-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Philippe Mouawad <philippe.moua...@gmail.com>
Subject Fwd: JAVA8u20 and JAVA8u25 Regression in Graphics2D drawing of derived Fonts ?
Date Wed, 19 Nov 2014 14:36:56 GMT
Hello Rory,
For information, I submitted this question on Swing-dev , I am not sure it
is the right list, if so hope you can help.

Regards
Philippe
---------- Forwarded message ----------
From: Philippe Mouawad <philippe.mouawad@gmail.com>
Date: Wed, Nov 19, 2014 at 3:34 PM
Subject: JAVA8u20 and JAVA8u25 Regression in Graphics2D drawing of derived
Fonts ?
To: swing-dev@openjdk.java.net


Hello,
We had recently a report of a bug on Apache JMeter:

   - https://issues.apache.org/bugzilla/show_bug.cgi?id=57221

The bug only occurs on Java 8 (u20 and u25).

We use jCharts library.

I narrowed the bug and it seems to come from the way derived fonts are
drawn:

Library uses:

    public static final AffineTransform VERTICAL_ROTATION =
AffineTransform.getRotateInstance( -Math.PI / 2 );

Then

        this.affineTransform= VERTICAL_ROTATION;
this.font.deriveFont( this.affineTransform )

So I build a stupid and ugly isolated class to show issue, run it on Java 7
display is fine , run it on Java8 result is strange.

package org.jCharts;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;

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

public class Test extends JPanel {
    Rectangle2D.Float rect = new Rectangle2D.Float(200, 200, 220, 35);
    // float theta = 1.1748778437843f;
    double theta = Math.PI / 6;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                RenderingHints.VALUE_STROKE_PURE);
        g2.setPaint(Color.blue);
        Font font = g2.getFont().deriveFont(18f);
        g2.setFont(font);
        FontRenderContext frc = g2.getFontRenderContext();
        String s = "This text should be rotated";
        float width = (float) font.getStringBounds(s, frc).getWidth();
        LineMetrics lm = font.getLineMetrics(s, frc);
        float height = lm.getAscent() + lm.getDescent();
        // Scale text into rect.
        float xScale = rect.width / width;
        float yScale = rect.height / height;
        float scale = (xScale > yScale) ? yScale : xScale;
        // Locate string origin.
        double x = rect.x;
        double y = rect.y + (rect.height + scale * height) / 2 - scale
                * lm.getDescent();
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
        at.scale(scale, scale);
        AffineTransform rotator = new AffineTransform();
        rotator.rotate(theta, rect.getCenterX(), rect.getCenterY());
        GeneralPath rect2 = new GeneralPath(
                rotator.createTransformedShape(rect));
        // Draw with no rotation.
        g2.draw(rect);
        g2.setPaint(Color.red);
        g2.setFont(font.deriveFont(at));
        g2.drawString(s, 0, 0);
        // Rotate once.
        g2.setPaint(Color.blue);
        g2.draw(rect2);
        rotator.concatenate(at);
        g2.setFont(font.deriveFont(rotator));
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        // Rotate again.
        rotator.setToIdentity();
        rotator.rotate(2 * theta, rect.getCenterX(), rect.getCenterY());
        rect2 = new GeneralPath(rotator.createTransformedShape(rect));
        g2.setPaint(Color.blue);
        g2.draw(rect2);
        rotator.concatenate(at);
        g2.setFont(font.deriveFont(rotator));
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        // Check scaled string bounds.
        // this was handled by the fractional metrics rendering hint
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.setPreferredSize(new Dimension(800, 600));
        JFrame f = new JFrame();
        f.getContentPane().add(test);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}

Regards
Philippe M.



-- 
Cordialement.
Philippe Mouawad.





-- 
Cordialement.
Philippe Mouawad.

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message