8328115: Convert java/awt/font/TextLayout/TestJustification.html applet test to main

Reviewed-by: aivanov
This commit is contained in:
Harshitha Onkar 2024-03-15 18:56:35 +00:00
parent 9bc1b065db
commit 0204aacb03
3 changed files with 230 additions and 270 deletions

View File

@ -792,7 +792,7 @@ java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java 8172245 linux-all
java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java 8185429 macosx-all
java/awt/Frame/FrameStateTest/FrameStateTest.html 8203920 macosx-all,linux-all
java/awt/print/PrinterJob/ScaledText/ScaledText.java 8231226 macosx-all
java/awt/font/TextLayout/TestJustification.html 8250791 macosx-all
java/awt/font/TextLayout/TestJustification.java 8250791 macosx-all
java/awt/TrayIcon/DragEventSource/DragEventSource.java 8252242 macosx-all
java/awt/FileDialog/DefaultFocusOwner/DefaultFocusOwner.java 7187728 macosx-all,linux-all
java/awt/print/PageFormat/Orient.java 8016055 macosx-all

View File

@ -1,52 +0,0 @@
<!--
Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<html>
<head>
<title>Test Justification</title>
</head>
<body>
<!--
@test
@bug 4211728 4178140 8145542
@summary Justify several lines of text and verify that the lines are the same
length and cursor positions are correct.
Bug 4211728: TextLayout.draw() draws characters at wrong position.
Bug 4178140: TextLayout does not justify
@run applet/manual=yesno TestJustification.html
-->
<h3>Test Justification</h1>
<hr>
<p>Five lines of text should appear, all justified to the same width,
followed by a sixth line containing only roman characters and no spaces
which is not justified, and instead is centered.
Carets should appear between all characters. Pass the test if this is
true.
<p>
<applet code=TestJustification.class width=500 height=500>
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet>
</body>
</html>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,229 +21,241 @@
* questions.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
/*
*
* See TestJustification.html for main test.
* @test
* @bug 4211728 4178140 8145542
* @summary Justify several lines of text and verify that the lines are the same
length and cursor positions are correct.
Bug 4211728: TextLayout.draw() draws characters at wrong position.
Bug 4178140: TextLayout does not justify.
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual TestJustification
*/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.text.*;
public class TestJustification {
private static final String INSTRUCTIONS = """
Five lines of text should appear, all justified to the same width,
followed by a sixth line containing only roman characters and
no spaces which is not justified, and instead is centered.
Carets should appear between all characters.
public class TestJustification extends Applet {
JustificationPanel panel;
PASS the test if this is true, else press FAIL.
""";
public void init() {
setLayout(new BorderLayout());
panel = new JustificationPanel("Bitstream Cyberbit");
add("Center", panel);
}
public static void main(String[] args) throws Exception {
public void destroy() {
remove(panel);
}
// calls system.exit, not for use in tests.
public static void main(String args[]) {
TestJustification justificationTest = new TestJustification();
justificationTest.init();
justificationTest.start();
Frame f = new Frame("Test Justification");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add("Center", justificationTest);
f.setSize(500, 500);
f.show();
}
public String getAppletInfo() {
return "Test TextLayout.getJustifiedLayout()";
}
static class JustificationPanel extends Panel {
TextLayout[] layouts;
String fontname;
float height;
float oldfsize;
AttributedCharacterIterator lineText;
TextLayout[] lines;
int linecount;
float oldwidth;
JustificationPanel(String fontname) {
this.fontname = fontname;
PassFailJFrame.builder()
.title("Test Instructions")
.instructions(INSTRUCTIONS)
.rows((int) INSTRUCTIONS.lines().count() + 2)
.columns(35)
.testUI(TestJustification::createUI)
.build()
.awaitAndCheck();
}
private static final String[] texts = {
"This is an english Highlighting demo.", "Highlighting",
"This is an arabic \u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e demo.", "arabic \u0627\u0628\u062a\u062c",
"This is a hebrew \u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5 demo.", "hebrew \u05d0\u05d1\u05d2",
"This is a cjk \u4e00\u4e01\u4e02\uac00\uac01\uc4fa\uf900\uf901\uf902 demo.", "cjk",
"NoSpaceCJK:\u4e00\u4e01\u4e02and\uac00\uac01\uc4faand\uf900\uf901\uf902", "No",
"NoSpaceRoman", "Space"
};
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
Dimension d = getSize();
Insets insets = getInsets();
float w = d.width - insets.left - insets.right;
float h = d.height - insets.top - insets.bottom;
int fsize = (int)w/25;
FontRenderContext frc = g2d.getFontRenderContext();
if (layouts == null || fsize != oldfsize) {
oldfsize = fsize;
Font f0 = new Font(fontname, Font.PLAIN, fsize);
Font f1 = new Font(fontname, Font.ITALIC, (int)(fsize * 1.5));
if (layouts == null) {
layouts = new TextLayout[texts.length / 2];
}
height = 0;
for (int i = 0; i < layouts.length; ++i) {
String text = texts[i*2];
String target = texts[i*2+1];
AttributedString astr = new AttributedString(text);
astr.addAttribute(TextAttribute.FONT, f0, 0, text.length());
int start = text.indexOf(target);
int limit = start + target.length();
astr.addAttribute(TextAttribute.FONT, f1, start, limit);
TextLayout layout = new TextLayout(astr.getIterator(), frc);
layout = layout.getJustifiedLayout(w - 20);
layouts[i] = layout;
height += layout.getAscent() + layout.getDescent() + layout.getLeading();
}
}
g2d.setColor(Color.white);
g2d.fill(new Rectangle.Float(insets.left, insets.top, w, h));
float basey = 20;
for (int i = 0; i < layouts.length; ++i) {
TextLayout layout = layouts[i];
float la = layout.getAscent();
float ld = layout.getDescent();
float ll = layout.getLeading();
float lw = layout.getAdvance();
float lh = la + ld + ll;
float lx = (w - lw) / 2f;
float ly = basey + layout.getAscent();
g2d.setColor(Color.black);
g2d.translate(insets.left + lx, insets.top + ly);
Rectangle2D bounds = new Rectangle2D.Float(0, -la, lw, lh);
g2d.draw(bounds);
layout.draw(g2d, 0, 0);
g2d.setColor(Color.red);
for (int j = 0, e = layout.getCharacterCount(); j <= e; ++j) {
Shape[] carets = layout.getCaretShapes(j, bounds);
g2d.draw(carets[0]);
}
g2d.translate(-insets.left - lx, -insets.top - ly);
basey += layout.getAscent() + layout.getDescent() + layout.getLeading();
}
// add LineBreakMeasurer-generated layouts
if (lineText == null) {
String text = "This is a long line of text that should be broken across multiple "
+ "lines and then justified to fit the break width. This test should pass if "
+ "these lines are justified to the same width, and fail otherwise. It should "
+ "also format the hebrew (\u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5) and arabic "
+ "(\u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e) and CJK "
+ "(\u4e00\u4e01\u4e02\uac00\uac01\uc4fa\u67b1\u67b2\u67b3\u67b4\u67b5\u67b6\u67b7"
+ "\u67b8\u67b9) text correctly.";
Float regular = new Float(16.0);
Float big = new Float(24.0);
AttributedString astr = new AttributedString(text);
astr.addAttribute(TextAttribute.SIZE, regular, 0, text.length());
astr.addAttribute(TextAttribute.FAMILY, fontname, 0, text.length());
int ix = text.indexOf("broken");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("hebrew");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("arabic");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("CJK");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 3);
lineText = astr.getIterator();
}
float width = w - 20;
if (lines == null || width != oldwidth) {
oldwidth = width;
lines = new TextLayout[10];
linecount = 0;
LineBreakMeasurer measurer = new LineBreakMeasurer(lineText, frc);
for (;;) {
TextLayout layout = measurer.nextLayout(width);
if (layout == null) {
break;
}
// justify all but last line
if (linecount > 0) {
lines[linecount - 1] = lines[linecount - 1].getJustifiedLayout(width);
}
if (linecount == lines.length) {
TextLayout[] nlines = new TextLayout[lines.length * 2];
System.arraycopy(lines, 0, nlines, 0, lines.length);
lines = nlines;
}
lines[linecount++] = layout;
}
}
float basex = insets.left + 10;
basey += 10;
g2d.setColor(Color.black);
for (int i = 0; i < linecount; ++i) {
TextLayout layout = lines[i];
basey += layout.getAscent();
float adv = layout.getAdvance();
float dx = layout.isLeftToRight() ? 0 : width - adv;
layout.draw(g2d, basex + dx, basey);
basey += layout.getDescent() + layout.getLeading();
}
private static Frame createUI() {
Frame frame= new Frame("Test Text Justification");
JustificationPanel panel = new JustificationPanel("Bitstream Cyberbit");
frame.add(panel);
frame.add("Center", panel);
frame.setSize(500, 450);
return frame;
}
static class JustificationPanel extends Panel {
TextLayout[] layouts;
String fontname;
float height;
float oldfsize;
AttributedCharacterIterator lineText;
TextLayout[] lines;
int linecount;
float oldwidth;
JustificationPanel(String fontname) {
this.fontname = fontname;
}
private static final String[] texts = {
"This is an english Highlighting demo.", "Highlighting",
"This is an arabic \u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e demo.", "arabic \u0627\u0628\u062a\u062c",
"This is a hebrew \u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5 demo.", "hebrew \u05d0\u05d1\u05d2",
"This is a cjk \u4e00\u4e01\u4e02\uac00\uac01\uc4fa\uf900\uf901\uf902 demo.", "cjk",
"NoSpaceCJK:\u4e00\u4e01\u4e02and\uac00\uac01\uc4faand\uf900\uf901\uf902", "No",
"NoSpaceRoman", "Space"
};
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
Dimension d = getSize();
Insets insets = getInsets();
float w = d.width - insets.left - insets.right;
float h = d.height - insets.top - insets.bottom;
int fsize = (int)w/25;
FontRenderContext frc = g2d.getFontRenderContext();
if (layouts == null || fsize != oldfsize) {
oldfsize = fsize;
Font f0 = new Font(fontname, Font.PLAIN, fsize);
Font f1 = new Font(fontname, Font.ITALIC, (int)(fsize * 1.5));
if (layouts == null) {
layouts = new TextLayout[texts.length / 2];
}
height = 0;
for (int i = 0; i < layouts.length; ++i) {
String text = texts[i*2];
String target = texts[i*2+1];
AttributedString astr = new AttributedString(text);
astr.addAttribute(TextAttribute.FONT, f0, 0, text.length());
int start = text.indexOf(target);
int limit = start + target.length();
astr.addAttribute(TextAttribute.FONT, f1, start, limit);
TextLayout layout = new TextLayout(astr.getIterator(), frc);
layout = layout.getJustifiedLayout(w - 20);
layouts[i] = layout;
height += layout.getAscent() + layout.getDescent() + layout.getLeading();
}
}
g2d.setColor(Color.white);
g2d.fill(new Rectangle.Float(insets.left, insets.top, w, h));
float basey = 20;
for (TextLayout layout : layouts) {
float la = layout.getAscent();
float ld = layout.getDescent();
float ll = layout.getLeading();
float lw = layout.getAdvance();
float lh = la + ld + ll;
float lx = (w - lw) / 2f;
float ly = basey + layout.getAscent();
g2d.setColor(Color.black);
g2d.translate(insets.left + lx, insets.top + ly);
Rectangle2D bounds = new Rectangle2D.Float(0, -la, lw, lh);
g2d.draw(bounds);
layout.draw(g2d, 0, 0);
g2d.setColor(Color.red);
for (int j = 0, e = layout.getCharacterCount(); j <= e; ++j) {
Shape[] carets = layout.getCaretShapes(j, bounds);
g2d.draw(carets[0]);
}
g2d.translate(-insets.left - lx, -insets.top - ly);
basey += layout.getAscent() + layout.getDescent() + layout.getLeading();
}
// add LineBreakMeasurer-generated layouts
if (lineText == null) {
String text = "This is a long line of text that should be broken across multiple "
+ "lines and then justified to fit the break width. This test should pass if "
+ "these lines are justified to the same width, and fail otherwise. It should "
+ "also format the hebrew (\u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5) and arabic "
+ "(\u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e) and CJK "
+ "(\u4e00\u4e01\u4e02\uac00\uac01\uc4fa\u67b1\u67b2\u67b3\u67b4\u67b5\u67b6\u67b7"
+ "\u67b8\u67b9) text correctly.";
Float regular = 16.0F;
Float big = 24.0F;
AttributedString astr = new AttributedString(text);
astr.addAttribute(TextAttribute.SIZE, regular, 0, text.length());
astr.addAttribute(TextAttribute.FAMILY, fontname, 0, text.length());
int ix = text.indexOf("broken");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("hebrew");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("arabic");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
ix = text.indexOf("CJK");
astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 3);
lineText = astr.getIterator();
}
float width = w - 20;
if (lines == null || width != oldwidth) {
oldwidth = width;
lines = new TextLayout[10];
linecount = 0;
LineBreakMeasurer measurer = new LineBreakMeasurer(lineText, frc);
for (;;) {
TextLayout layout = measurer.nextLayout(width);
if (layout == null) {
break;
}
// justify all but last line
if (linecount > 0) {
lines[linecount - 1] = lines[linecount - 1].getJustifiedLayout(width);
}
if (linecount == lines.length) {
TextLayout[] nlines = new TextLayout[lines.length * 2];
System.arraycopy(lines, 0, nlines, 0, lines.length);
lines = nlines;
}
lines[linecount++] = layout;
}
}
float basex = insets.left + 10;
basey += 10;
g2d.setColor(Color.black);
for (int i = 0; i < linecount; ++i) {
TextLayout layout = lines[i];
basey += layout.getAscent();
float adv = layout.getAdvance();
float dx = layout.isLeftToRight() ? 0 : width - adv;
layout.draw(g2d, basex + dx, basey);
basey += layout.getDescent() + layout.getLeading();
}
}
}
}
}