[OpenJDK 2D-Dev] HiDPI support issues on Windows
Anton Tarasov
anton.tarasov at jetbrains.com
Tue Oct 4 20:46:25 UTC 2016
On 10/4/2016 11:30 PM, Jim Graham wrote:
> I wasn't familiar with the test code for this particular case. Is it
> in a bug report somewhere?
Jim, I'm re-attaching it (it was in my first e-mail).
Thanks,
Anton.
>
> ...jim
>
> On 10/4/16 1:01 PM, Anton Tarasov wrote:
>> Also, the problem with primitives rendering
>> (http://cr.openjdk.java.net/%7Eant/hidpi_pics/Scaling-150-percent.png)
>> is
>> still there. But it seems to relate to line-thikness
>> (border-thickness) rounding inaccuracy. What we can do with that?...
-------------- next part --------------
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package testscalingrectangles;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class MinimalSwingApplication {
public static void main(String[] args) {
MinimalSwingApplication app = new MinimalSwingApplication();
app.buildAndDisplayGui();
}
private void buildAndDisplayGui(){
JFrame frame = new JFrame("Test Frame");
frame.setPreferredSize(new Dimension(240, 120));
buildContent(frame);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
frame.repaint();
}
});
}
private void buildContent(JFrame aFrame){
JButton repaintButton = new JButton();
repaintButton.setText("Repaint");
repaintButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
aFrame.repaint();
}
});
JLabel scaleFactorLabel = new JLabel();
JPanel topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
topPanel.add(new JLabel());
topPanel.add(Box.createHorizontalGlue());
topPanel.add(scaleFactorLabel);
topPanel.add(Box.createHorizontalGlue());
topPanel.add(new JLabel());
JPanel panel = new JPanel(new BorderLayout());
panel.add(topPanel, BorderLayout.NORTH);
panel.add(new MyPanel(scaleFactorLabel), BorderLayout.CENTER);
panel.add(repaintButton, BorderLayout.SOUTH);
aFrame.getContentPane().add(panel);
}
private class MyPanel extends JPanel {
private JLabel myLabel;
public MyPanel(JLabel label) {
super();
myLabel = label;
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBorder(new LineBorder(Color.BLUE, 2));
Map<RenderingHints.Key,Object> renderingHints1 = new HashMap<>();
renderingHints1.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
add(new MyPaintRectPanel(renderingHints1));
Map<RenderingHints.Key,Object> renderingHints2 = new HashMap<>();
renderingHints1.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
add(new MyPaintRectPanel(renderingHints2));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D)g;
myLabel.setText("Scale=" + (int)(g2d.getTransform().getScaleX() * 100) + "%");
}
// int wRect = 5;
// int hRect = 5;
// int xRect0 = this.getSize().width / 2 - wRect;
// int yRect0 = this.getSize().height / 2 - hRect;
// int xRect1 = xRect0 + wRect + 1;
// int yRect1 = yRect0 + hRect + 1;
//myLabel2.setText("X=" + xRect0 + ", Y= " + yRect0);
}
}
private class MyPaintRectPanel extends JPanel {
private Map<RenderingHints.Key, ?> myRenderingHints;
public MyPaintRectPanel(Map<RenderingHints.Key, Object> renderingHints) {
myRenderingHints = renderingHints;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D)g;
for (RenderingHints.Key key : myRenderingHints.keySet()) {
g2d.setRenderingHint(key, myRenderingHints.get(key));
}
//((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
//g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
int wRect = 5;
int hRect = 5;
int xRect0 = this.getSize().width / 2 - wRect;
int yRect0 = this.getSize().height / 2 - hRect;
int xRect1 = xRect0 + wRect + 1;
int yRect1 = yRect0 + hRect + 1;
//myLabel.setText("X=" + xRect0 + ", Y= " + yRect0);
// Fill the background as RED to illustrate the problem. We are filling
// a red rectangle of size (0, 0, w, h * 2 + 1)
// This happens` because of the way rounding works in the default transform.
// From a API perspective, you would not expect any "red" to remain, since
// we cover it up
g.setColor(Color.RED);
g.fillRect(xRect0, yRect0, wRect * 2 + 1, hRect * 2 + 1);
// Draw 4 rectangles
g.setColor(Color.PINK);
g.fillRect(xRect0, yRect0, wRect, hRect);
g.fillRect(xRect1, yRect0, wRect, hRect);
g.fillRect(xRect0, yRect1, wRect, hRect);
g.fillRect(xRect1, yRect1, wRect, hRect);
// Draw borders of 4 rectangles
g.setColor(Color.GREEN);
g.drawRect(xRect0, yRect0, wRect - 1, hRect - 1);
g.drawRect(xRect1, yRect0, wRect - 1, hRect - 1);
g.drawRect(xRect0, yRect1, wRect - 1, hRect - 1);
g.drawRect(xRect1, yRect1, wRect - 1, hRect - 1);
// Draw horiz/vert lines in the middle of the 4 rectangles
g.setColor(Color.BLUE);
int xMiddle = xRect1 - 1;
int yMiddle = yRect1 - 1;
g.drawLine(xRect0, yMiddle, xRect0 + wRect * 2, yMiddle);
g.drawLine(xMiddle, yRect0, xMiddle, yRect0 + hRect * 2);
}
}
}
More information about the 2d-dev
mailing list