3789983e89
Reviewed-by: darcy, ihse
250 lines
7.8 KiB
Java
250 lines
7.8 KiB
Java
/*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
*
|
|
* See TestJustification.html for main test.
|
|
*/
|
|
|
|
import java.applet.*;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.awt.font.*;
|
|
import java.awt.geom.*;
|
|
import java.text.*;
|
|
|
|
public class TestJustification extends Applet {
|
|
JustificationPanel panel;
|
|
|
|
public void init() {
|
|
setLayout(new BorderLayout());
|
|
panel = new JustificationPanel("Bitstream Cyberbit");
|
|
add("Center", panel);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|