undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
103
test/jdk/java/awt/font/TextLayout/ArabicBox.java
Normal file
103
test/jdk/java/awt/font/TextLayout/ArabicBox.java
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4427483
|
||||
* @summary Arabic text followed by newline should have no missing glyphs
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual ArabicBox
|
||||
*/
|
||||
public final class ArabicBox {
|
||||
|
||||
private static final String TEXT =
|
||||
"\u0627\u0644\u0639\u0631\u0628\u064A\u0629\n";
|
||||
|
||||
private static final String FONT_NAME = Font.DIALOG;
|
||||
|
||||
private static final String INSTRUCTIONS = """
|
||||
In the below panel, you should see the following text:
|
||||
|
||||
"""
|
||||
+ TEXT + """
|
||||
(It's \u2018Arabic\u2019 in Arabic.)
|
||||
|
||||
If there are no 'box glyphs' for missing glyphs,
|
||||
press Pass; otherwise, press Fail.""";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Font font = new Font(FONT_NAME, Font.PLAIN, 24);
|
||||
System.out.println("asked for " + FONT_NAME + " and got: " + font.getFontName());
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("Arabic Box")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.rows(7)
|
||||
.columns(40)
|
||||
.splitUIBottom(() -> createPanel(font))
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
private static JPanel createPanel(Font font) {
|
||||
return new TextPanel(font);
|
||||
}
|
||||
|
||||
private static final class TextPanel extends JPanel {
|
||||
private TextLayout layout;
|
||||
|
||||
private TextPanel(Font font) {
|
||||
setForeground(Color.black);
|
||||
setBackground(Color.white);
|
||||
setFont(font);
|
||||
setPreferredSize(new Dimension(300, 150));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
if (layout == null) {
|
||||
Font font = g2d.getFont();
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
|
||||
layout = new TextLayout(TEXT, font, frc);
|
||||
System.out.println(layout.getBounds());
|
||||
}
|
||||
|
||||
layout.draw(g2d, 10, 50);
|
||||
g2d.drawString(TEXT, 10, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
test/jdk/java/awt/font/TextLayout/ArabicDiacriticTest.java
Normal file
95
test/jdk/java/awt/font/TextLayout/ArabicDiacriticTest.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2020, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary verify Arab Diacritic Positioning
|
||||
* @bug 8168759 8248352
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.util.Locale;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
public class ArabicDiacriticTest {
|
||||
|
||||
static final String SAMPLE =
|
||||
"\u0627\u0644\u0639\u064e\u0631\u064e\u0628\u0650\u064a\u064e\u0651\u0629";
|
||||
|
||||
static final String STR1 = "\u0644\u0639\u064e\u0629";
|
||||
static final String STR2 = "\u0644\u0639\u0629";
|
||||
|
||||
static final String FONT = "DejaVu Sans";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if ((args.length > 0) && (args[0].equals("-show"))) {
|
||||
showText(); // for a human
|
||||
}
|
||||
measureText(); // for the test harness
|
||||
}
|
||||
|
||||
static void showText() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame frame = new JFrame();
|
||||
JLabel label = new JLabel(SAMPLE);
|
||||
Font font = new Font(FONT, Font.PLAIN, 36);
|
||||
label.setFont(font);
|
||||
frame.setLayout(new GridLayout(3,1));
|
||||
frame.add(label);
|
||||
label = new JLabel(STR1);
|
||||
label.setFont(font);
|
||||
frame.add(label);
|
||||
label = new JLabel(STR2);
|
||||
label.setFont(font);
|
||||
frame.add(label);
|
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
static void measureText() {
|
||||
Font font = new Font(FONT, Font.PLAIN, 36);
|
||||
if (!font.getFamily(Locale.ENGLISH).equals(FONT)) {
|
||||
return;
|
||||
}
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
TextLayout tl1 = new TextLayout(STR1, font, frc);
|
||||
TextLayout tl2 = new TextLayout(STR2, font, frc);
|
||||
Rectangle r1 = tl1.getPixelBounds(frc, 0f, 0f);
|
||||
Rectangle r2 = tl2.getPixelBounds(frc, 0f, 0f);
|
||||
if (r1.height > r2.height) {
|
||||
System.out.println(font);
|
||||
System.out.println(r1);
|
||||
System.out.println(r2);
|
||||
throw new RuntimeException("BAD BOUNDS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2007, 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.
|
||||
*/
|
||||
|
||||
|
||||
/* @test
|
||||
* @summary verify cast in AttributeValues fails silently - regression
|
||||
* @bug 6603975
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
public class AttributeValuesCastTest
|
||||
{
|
||||
public static void main (String [] args)
|
||||
{
|
||||
System.out.println ("java.version = " + System.getProperty ("java.version"));
|
||||
try {
|
||||
Map attributes = new HashMap();
|
||||
attributes.put("Something","Somethign Else");
|
||||
Font f = new Font(attributes);
|
||||
System.out.println("PASS: was able to create font. ");
|
||||
} catch(Throwable t) {
|
||||
throw new RuntimeException("FAIL: caught "+t.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
98
test/jdk/java/awt/font/TextLayout/DecorationBoundsTest.java
Normal file
98
test/jdk/java/awt/font/TextLayout/DecorationBoundsTest.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary verify bounds enclose rendering of decorations.
|
||||
* @bug 6751621
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
|
||||
public class DecorationBoundsTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BufferedImage bi =
|
||||
new BufferedImage(600, 300, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = bi.createGraphics();
|
||||
g2d.setColor(Color.white);
|
||||
g2d.fillRect(0, 0, 600, 300);
|
||||
|
||||
float x = 10;
|
||||
float y = 90;
|
||||
Map map = new HashMap();
|
||||
map.put(TextAttribute.STRIKETHROUGH,
|
||||
TextAttribute.STRIKETHROUGH_ON);
|
||||
map.put(TextAttribute.SIZE, new Float(80));
|
||||
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
|
||||
String text = "Welcome to ";
|
||||
TextLayout tl = new TextLayout(text, map, frc);
|
||||
g2d.translate(x, y);
|
||||
g2d.setColor(Color.RED);
|
||||
tl.draw(g2d, 0, 0);
|
||||
g2d.setColor(Color.GREEN);
|
||||
Rectangle2D bds = tl.getBounds();
|
||||
/* Since due to pixelisation the glyphs may touch above
|
||||
* or below the theoretical outline bounds, pad in the
|
||||
* y direction to avoid spurious failures.
|
||||
*/
|
||||
bds.setRect(bds.getX(), bds.getY()-1,
|
||||
bds.getWidth(), bds.getHeight()+2);
|
||||
g2d.fill(bds);
|
||||
|
||||
map = new HashMap();
|
||||
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||
map.put(TextAttribute.SIZE, new Float(80));
|
||||
tl = new TextLayout(text, map, frc);
|
||||
g2d.translate(0, 100);
|
||||
g2d.setColor(Color.RED);
|
||||
tl.draw(g2d, 0, 0);
|
||||
|
||||
g2d.setColor(Color.GREEN);
|
||||
bds = tl.getBounds();
|
||||
bds.setRect(bds.getX(), bds.getY()-1,
|
||||
bds.getWidth(), bds.getHeight()+2);
|
||||
g2d.fill(bds);
|
||||
|
||||
checkBI(bi, Color.RED);
|
||||
}
|
||||
|
||||
static void checkBI(BufferedImage bi, Color badColor) {
|
||||
int badrgb = badColor.getRGB();
|
||||
int w = bi.getWidth(null);
|
||||
int h = bi.getHeight(null);
|
||||
for (int x=0; x<w; x++) {
|
||||
for (int y=0; y<h; y++) {
|
||||
int col = bi.getRGB(x, y);
|
||||
if (col == badrgb) {
|
||||
throw new RuntimeException("Got " + col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
test/jdk/java/awt/font/TextLayout/DiacriticsDrawingTest.java
Normal file
74
test/jdk/java/awt/font/TextLayout/DiacriticsDrawingTest.java
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2017 JetBrains s.r.o.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8170552
|
||||
* @summary verify enabling text layout for complex text on macOS
|
||||
* @requires os.family == "mac"
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class DiacriticsDrawingTest {
|
||||
private static final Font FONT = new Font("Menlo", Font.PLAIN, 12);
|
||||
private static final int IMAGE_WIDTH = 20;
|
||||
private static final int IMAGE_HEIGHT = 20;
|
||||
private static final int TEXT_X = 5;
|
||||
private static final int TEXT_Y = 15;
|
||||
|
||||
public static void main(String[] args) {
|
||||
BufferedImage composed = drawString("\u00e1"); // latin small letter a with acute
|
||||
BufferedImage decomposed = drawString("a\u0301"); // same letter in decomposed form
|
||||
|
||||
if (!imagesAreEqual(composed, decomposed)) {
|
||||
throw new RuntimeException("Text rendering is supposed to be the same");
|
||||
}
|
||||
}
|
||||
|
||||
private static BufferedImage drawString(String text) {
|
||||
BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = image.createGraphics();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(FONT);
|
||||
g.drawString(text, TEXT_X, TEXT_Y);
|
||||
g.dispose();
|
||||
return image;
|
||||
}
|
||||
|
||||
private static boolean imagesAreEqual(BufferedImage i1, BufferedImage i2) {
|
||||
if (i1.getWidth() != i2.getWidth() || i1.getHeight() != i2.getHeight()) return false;
|
||||
for (int i = 0; i < i1.getWidth(); i++) {
|
||||
for (int j = 0; j < i1.getHeight(); j++) {
|
||||
if (i1.getRGB(i, j) != i2.getRGB(i, j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
89
test/jdk/java/awt/font/TextLayout/FontGlyphCompare.java
Normal file
89
test/jdk/java/awt/font/TextLayout/FontGlyphCompare.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8214002
|
||||
* @requires (os.family == "windows")
|
||||
* @summary verify MS Mincho's Plain & Italic style
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class FontGlyphCompare {
|
||||
|
||||
static BufferedImage getFontImage(Font font, String text) {
|
||||
int x = 1;
|
||||
int y = 15;
|
||||
int w = 10;
|
||||
int h = 18;
|
||||
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = (Graphics2D)bi.getGraphics();
|
||||
g.setColor(Color.black);
|
||||
g.fillRect(0, 0, w, h);
|
||||
g.setColor(Color.white);
|
||||
g.setFont(font);
|
||||
g.drawString(text, x, y);
|
||||
return bi;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String osName = System.getProperty("os.name");
|
||||
System.out.println("OS is " + osName);
|
||||
osName = osName.toLowerCase();
|
||||
if (!osName.startsWith("windows")) {
|
||||
return;
|
||||
}
|
||||
Font msMincho = new Font("MS Mincho", Font.PLAIN, 16);
|
||||
String family = msMincho.getFamily(java.util.Locale.ENGLISH);
|
||||
if (!family.equalsIgnoreCase("MS Mincho")) {
|
||||
System.out.println("Japanese fonts not installed");
|
||||
return;
|
||||
}
|
||||
String s = "|";
|
||||
BufferedImage bi1 = getFontImage(new Font("MS Mincho", Font.PLAIN, 16), s);
|
||||
int h1 = bi1.getHeight();
|
||||
int w1 = bi1.getWidth();
|
||||
BufferedImage bi2 = getFontImage(new Font("MS Mincho", Font.ITALIC, 16), s);
|
||||
int h2 = bi2.getHeight();
|
||||
int w2 = bi2.getWidth();
|
||||
if ((h1 == h2) && (w1 == w2)) {
|
||||
int cnt = 0;
|
||||
for(int yy = 0; yy < h1; yy++) {
|
||||
for(int xx = 0; xx < w1; xx++) {
|
||||
if (bi1.getRGB(xx, yy) != bi2.getRGB(xx, yy)) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cnt == 0) {
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
test/jdk/java/awt/font/TextLayout/FontLayoutStressTest.java
Normal file
88
test/jdk/java/awt/font/TextLayout/FontLayoutStressTest.java
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (C) 2019 JetBrains s.r.o.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8220231
|
||||
* @summary Cache HarfBuzz face object for same font's text layout calls
|
||||
* @comment Test layout operations for the same font performed simultaneously
|
||||
* from multiple threads
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class FontLayoutStressTest {
|
||||
private static final int NUMBER_OF_THREADS =
|
||||
Runtime.getRuntime().availableProcessors() * 2;
|
||||
private static final long TIME_TO_RUN_NS = 1_000_000_000; // 1 second
|
||||
private static final Font FONT = new Font(Font.SERIF, Font.PLAIN, 12);
|
||||
private static final FontRenderContext FRC = new FontRenderContext(null,
|
||||
false, false);
|
||||
private static final char[] TEXT = "Lorem ipsum dolor sit amet, ..."
|
||||
.toCharArray();
|
||||
|
||||
private static double doLayout() {
|
||||
GlyphVector gv = FONT.layoutGlyphVector(FRC, TEXT, 0, TEXT.length,
|
||||
Font.LAYOUT_LEFT_TO_RIGHT);
|
||||
return gv.getGlyphPosition(gv.getNumGlyphs()).getX();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
double expectedWidth = doLayout();
|
||||
AtomicReference<Throwable> throwableRef = new AtomicReference<>();
|
||||
CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_THREADS);
|
||||
List<Thread> threads = new ArrayList<>();
|
||||
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
barrier.await();
|
||||
long timeToStop = System.nanoTime() + TIME_TO_RUN_NS;
|
||||
while (System.nanoTime() < timeToStop) {
|
||||
double width = doLayout();
|
||||
if (width != expectedWidth) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected layout result");
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throwableRef.set(e);
|
||||
}
|
||||
});
|
||||
threads.add(thread);
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
Throwable throwable = throwableRef.get();
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
}
|
||||
392
test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java
Normal file
392
test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java
Normal file
File diff suppressed because one or more lines are too long
49
test/jdk/java/awt/font/TextLayout/HitTest.java
Normal file
49
test/jdk/java/awt/font/TextLayout/HitTest.java
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary verify Hit index with supplementary characters.
|
||||
* @bug 8173028
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.font.TextLayout;
|
||||
|
||||
public class HitTest {
|
||||
|
||||
public static void main(String args[]) {
|
||||
String s = new String(new int[]{0x1d400, 0x61}, 0, 2);
|
||||
Font font = new Font("Dialog", Font.PLAIN, 12);
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
TextLayout tl = new TextLayout(s, font, frc);
|
||||
TextHitInfo currHit = TextHitInfo.beforeOffset(3);
|
||||
TextHitInfo prevHit = tl.getNextLeftHit(currHit);
|
||||
System.out.println("index=" + prevHit.getCharIndex()+
|
||||
" leading edge=" + prevHit.isLeadingEdge());
|
||||
if (prevHit.getCharIndex() != 2) {
|
||||
throw new RuntimeException("Expected 2 for hit index");
|
||||
}
|
||||
}
|
||||
}
|
||||
67
test/jdk/java/awt/font/TextLayout/KernCrash.java
Normal file
67
test/jdk/java/awt/font/TextLayout/KernCrash.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Shows (top) with kerning, (middle) without, (bottom) also without.
|
||||
*
|
||||
* @bug 7017324
|
||||
*/
|
||||
public class KernCrash extends Frame {
|
||||
private static Font font0;
|
||||
private static Font font1;
|
||||
private static Font font2;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
HashMap attrs = new HashMap();
|
||||
font0 = Font.createFont(Font.TRUETYPE_FONT, new File("Vera.ttf"));
|
||||
System.out.println("using " + font0);
|
||||
attrs.put(TextAttribute.SIZE, new Float(58f));
|
||||
font1 = font0.deriveFont(attrs);
|
||||
attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
|
||||
font2 = font0.deriveFont(attrs);
|
||||
|
||||
KernCrash f = new KernCrash();
|
||||
f.setTitle("Kerning Crash");
|
||||
f.setSize(600, 300);
|
||||
f.setForeground(Color.black);
|
||||
f.show();
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
FontRenderContext frc = g2.getFontRenderContext();
|
||||
TextLayout layout = new TextLayout("text", font2, frc);
|
||||
layout.draw(g2, 10, 150);
|
||||
|
||||
String s = "WAVATastic";
|
||||
TextLayout layout2 = new TextLayout(s, font1, frc);
|
||||
layout2.draw(g2, 10, 200);
|
||||
TextLayout layout3 = new TextLayout(s, font2, frc);
|
||||
layout3.draw(g2, 10, 100);
|
||||
}
|
||||
}
|
||||
66
test/jdk/java/awt/font/TextLayout/KerningLeak.java
Normal file
66
test/jdk/java/awt/font/TextLayout/KerningLeak.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @bug 8015334
|
||||
* @summary Memory leak with kerning.
|
||||
*/
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class KerningLeak {
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
leak();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void leak() {
|
||||
Map<TextAttribute, Object> textAttributes = new HashMap<>();
|
||||
textAttributes.put(TextAttribute.FAMILY, "Sans Serif");
|
||||
textAttributes.put(TextAttribute.SIZE, 12);
|
||||
textAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
|
||||
Font font = Font.getFont(textAttributes);
|
||||
JLabel label = new JLabel();
|
||||
int dummy = 0;
|
||||
for (int i = 0; i < 500; i++) {
|
||||
if (i % 10 == 0) System.out.println("Starting iter " + (i+1));
|
||||
for (int j = 0; j <1000; j++) {
|
||||
FontMetrics fm = label.getFontMetrics(font);
|
||||
dummy += SwingUtilities.computeStringWidth(fm, Integer.toString(j));
|
||||
}
|
||||
}
|
||||
System.out.println("done " + dummy);
|
||||
}
|
||||
}
|
||||
190
test/jdk/java/awt/font/TextLayout/LigatureCaretTest.java
Normal file
190
test/jdk/java/awt/font/TextLayout/LigatureCaretTest.java
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4178145 8144015
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1998 IBM Corp. All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This test ensures that TextLayout will not place a caret within
|
||||
* an Arabic lam-alef ligature, and will correctly caret through
|
||||
* bidirectional text with numbers.
|
||||
*/
|
||||
|
||||
public class LigatureCaretTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
testBidiWithNumbers();
|
||||
testLamAlef();
|
||||
System.out.println("LigatureCaretTest PASSED");
|
||||
}
|
||||
|
||||
private static final FontRenderContext frc =
|
||||
new FontRenderContext(null, false, false);
|
||||
|
||||
private static Font getFontForText(String s) {
|
||||
GraphicsEnvironment ge =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
Font[] fonts = ge.getAllFonts();
|
||||
|
||||
for (Font f : fonts) {
|
||||
if (f.canDisplayUpTo(s) == -1) {
|
||||
return f.deriveFont(Font.PLAIN, 24);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caret through text mixed-direction text and check the results.
|
||||
* If the test fails an Error is thrown.
|
||||
* @exception an Error is thrown if the test fails
|
||||
*/
|
||||
public static void testBidiWithNumbers() {
|
||||
|
||||
String bidiWithNumbers = "abc\u05D0\u05D1\u05D2123abc";
|
||||
Font font = getFontForText(bidiWithNumbers);
|
||||
if (font == null) {
|
||||
return;
|
||||
}
|
||||
Hashtable map = new Hashtable();
|
||||
map.put(TextAttribute.FONT, font);
|
||||
|
||||
// visual order for the text:
|
||||
// abc123<gimel><bet><aleph>abc
|
||||
|
||||
int[] carets = { 0, 1, 2, 3, 7, 8, 6, 5, 4, 9, 10, 11, 12 };
|
||||
TextLayout layout = new TextLayout(bidiWithNumbers, map, frc);
|
||||
|
||||
// Caret through TextLayout in both directions and check results.
|
||||
for (int i=0; i < carets.length-1; i++) {
|
||||
|
||||
TextHitInfo hit = layout.getNextRightHit(carets[i]);
|
||||
if (hit.getInsertionIndex() != carets[i+1]) {
|
||||
throw new Error("right hit failed within layout");
|
||||
}
|
||||
}
|
||||
|
||||
if (layout.getNextRightHit(carets[carets.length-1]) != null) {
|
||||
throw new Error("right hit failed at end of layout");
|
||||
}
|
||||
|
||||
for (int i=carets.length-1; i > 0; i--) {
|
||||
|
||||
TextHitInfo hit = layout.getNextLeftHit(carets[i]);
|
||||
if (hit.getInsertionIndex() != carets[i-1]) {
|
||||
throw new Error("left hit failed within layout");
|
||||
}
|
||||
}
|
||||
|
||||
if (layout.getNextLeftHit(carets[0]) != null) {
|
||||
throw new Error("left hit failed at end of layout");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure proper careting and hit-testing behavior with
|
||||
* a lam-alef ligature.
|
||||
* If the test fails, an Error is thrown.
|
||||
* @exception an Error is thrown if the test fails
|
||||
*/
|
||||
public static void testLamAlef() {
|
||||
|
||||
// lam-alef form a mandantory ligature.
|
||||
final String lamAlef = "\u0644\u0627";
|
||||
final String ltrText = "abcd";
|
||||
|
||||
Font font = getFontForText(lamAlef+ltrText);
|
||||
if (font == null) {
|
||||
return;
|
||||
}
|
||||
Hashtable map = new Hashtable();
|
||||
map.put(TextAttribute.FONT, font);
|
||||
|
||||
// Create a TextLayout with just a lam-alef sequence. There
|
||||
// should only be two valid caret positions: one at
|
||||
// insertion offset 0 and the other at insertion offset 2.
|
||||
TextLayout layout = new TextLayout(lamAlef, map, frc);
|
||||
|
||||
TextHitInfo hit;
|
||||
|
||||
hit = layout.getNextLeftHit(0);
|
||||
if (hit.getInsertionIndex() != 2) {
|
||||
throw new Error("Left hit failed. Hit:" + hit);
|
||||
}
|
||||
|
||||
hit = layout.getNextRightHit(2);
|
||||
if (hit.getInsertionIndex() != 0) {
|
||||
throw new Error("Right hit failed. Hit:" + hit);
|
||||
}
|
||||
|
||||
hit = layout.hitTestChar(layout.getAdvance()/2, 0);
|
||||
if (hit.getInsertionIndex() != 0 && hit.getInsertionIndex() != 2) {
|
||||
throw new Error("Hit-test allowed incorrect caret. Hit:" + hit);
|
||||
}
|
||||
|
||||
|
||||
// Create a TextLayout with some left-to-right text
|
||||
// before the lam-alef sequence. There should not be
|
||||
// a caret position between the lam and alef.
|
||||
layout = new TextLayout(ltrText+lamAlef, map, frc);
|
||||
|
||||
final int ltrLen = ltrText.length();
|
||||
final int layoutLen = layout.getCharacterCount();
|
||||
|
||||
for (int i=0; i < ltrLen; i++) {
|
||||
hit = layout.getNextRightHit(i);
|
||||
if (hit.getInsertionIndex() != i+1) {
|
||||
throw new Error("Right hit failed in ltr text.");
|
||||
}
|
||||
}
|
||||
|
||||
hit = layout.getNextRightHit(ltrLen);
|
||||
if (layoutLen != hit.getInsertionIndex()) {
|
||||
throw new Error("Right hit failed at direction boundary.");
|
||||
}
|
||||
|
||||
hit = layout.getNextLeftHit(layoutLen);
|
||||
if (hit.getInsertionIndex() != ltrLen) {
|
||||
throw new Error("Left hit failed at end of text.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Verify no exception for unsupported code point.
|
||||
* @bug 8172967
|
||||
*/
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
|
||||
public class MissingCodePointLayoutTest {
|
||||
public static void main(String[] args) {
|
||||
Font font = new Font("Tahoma", Font.PLAIN, 12);
|
||||
String text = "\ude00";
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
TextLayout layout = new TextLayout(text, font, frc);
|
||||
layout.getCaretShapes(0);
|
||||
}
|
||||
}
|
||||
|
||||
144
test/jdk/java/awt/font/TextLayout/MyanmarTextTest.java
Normal file
144
test/jdk/java/awt/font/TextLayout/MyanmarTextTest.java
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8223558
|
||||
* @key headful
|
||||
* @summary Verifies that Myanmar script is rendered correctly:
|
||||
* two characters combined into one glyph
|
||||
* @library /test/lib
|
||||
* @build jtreg.SkippedException
|
||||
* @run main MyanmarTextTest
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.plaf.TextUI;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Position;
|
||||
|
||||
import jtreg.SkippedException;
|
||||
|
||||
public class MyanmarTextTest {
|
||||
private static final String TEXT = "\u1000\u103C";
|
||||
|
||||
private static final List<String> FONT_CANDIDATES =
|
||||
List.of("Myanmar MN",
|
||||
"Padauk",
|
||||
"Myanmar Text",
|
||||
"Noto Sans Myanmar");
|
||||
|
||||
private static final String FONT_NAME = selectFontName();
|
||||
|
||||
private final JFrame frame;
|
||||
private final JTextField myanmarTF;
|
||||
|
||||
private static volatile MyanmarTextTest mtt;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (FONT_NAME == null) {
|
||||
throw new SkippedException("No suitable font found out of the list: "
|
||||
+ String.join(", ", FONT_CANDIDATES));
|
||||
}
|
||||
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(MyanmarTextTest::createUI);
|
||||
SwingUtilities.invokeAndWait(mtt::checkPositions);
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(mtt::dispose);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createUI() {
|
||||
mtt = new MyanmarTextTest();
|
||||
mtt.show();
|
||||
}
|
||||
|
||||
private MyanmarTextTest() {
|
||||
frame = new JFrame("Myanmar Text");
|
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
myanmarTF = new JTextField(TEXT);
|
||||
myanmarTF.setFont(new Font(FONT_NAME, Font.PLAIN, 40));
|
||||
|
||||
JPanel main = new JPanel();
|
||||
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
|
||||
main.add(myanmarTF);
|
||||
|
||||
main.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7));
|
||||
|
||||
frame.getContentPane().add(main);
|
||||
}
|
||||
|
||||
private void show() {
|
||||
frame.pack();
|
||||
frame.setLocationByPlatform(true);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
frame.dispose();
|
||||
}
|
||||
|
||||
private void checkPositions() {
|
||||
final TextUI ui = myanmarTF.getUI();
|
||||
final Position.Bias[] biasRet = new Position.Bias[1];
|
||||
try {
|
||||
if (2 != ui.getNextVisualPositionFrom(myanmarTF, 0,
|
||||
Position.Bias.Forward, SwingConstants.EAST, biasRet)) {
|
||||
throw new RuntimeException("For 0, next position should be 2");
|
||||
}
|
||||
if (2 != ui.getNextVisualPositionFrom(myanmarTF, 1,
|
||||
Position.Bias.Forward, SwingConstants.EAST, biasRet)) {
|
||||
throw new RuntimeException("For 1, next position should be 2");
|
||||
}
|
||||
if (0 != ui.getNextVisualPositionFrom(myanmarTF, 2,
|
||||
Position.Bias.Forward, SwingConstants.WEST, biasRet)) {
|
||||
throw new RuntimeException("For 2, prev position should be 0");
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String selectFontName() {
|
||||
return Arrays.stream(GraphicsEnvironment
|
||||
.getLocalGraphicsEnvironment()
|
||||
.getAvailableFontFamilyNames())
|
||||
.filter(FONT_CANDIDATES::contains)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
82
test/jdk/java/awt/font/TextLayout/OSXLigatureTest.java
Normal file
82
test/jdk/java/awt/font/TextLayout/OSXLigatureTest.java
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7162125
|
||||
* @summary Test ligatures form on OS X.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class OSXLigatureTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (!System.getProperty("os.name").startsWith("Mac")) {
|
||||
return;
|
||||
}
|
||||
String ligStr = "ffi";
|
||||
int w = 50, h = 50;
|
||||
|
||||
BufferedImage bi1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D bi1Graphics = bi1.createGraphics();
|
||||
bi1Graphics.setColor(Color.white);
|
||||
bi1Graphics.fillRect(0, 0, w, h);
|
||||
bi1Graphics.setColor(Color.black);
|
||||
Font noLigFont = new Font("Gill Sans", Font.PLAIN, 30);
|
||||
bi1Graphics.setFont(noLigFont);
|
||||
bi1Graphics.drawString(ligStr, 10, 40);
|
||||
|
||||
BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D bi2Graphics = bi2.createGraphics();
|
||||
bi2Graphics.setColor(Color.white);
|
||||
bi2Graphics.fillRect(0, 0, w, h);
|
||||
bi2Graphics.setColor(Color.black);
|
||||
Map<TextAttribute, Object> attributes = new HashMap<>();
|
||||
attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
|
||||
Font ligFont = noLigFont.deriveFont(attributes);
|
||||
bi2Graphics.setFont(ligFont);
|
||||
bi2Graphics.drawString(ligStr, 10, 40);
|
||||
|
||||
boolean same = true;
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
int c1 = bi1.getRGB(x, y);
|
||||
int c2 = bi2.getRGB(x, y);
|
||||
same &= (c1 == c2);
|
||||
}
|
||||
if (!same) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (same) {
|
||||
throw new RuntimeException("Images do not differ - no ligature");
|
||||
}
|
||||
}
|
||||
}
|
||||
257
test/jdk/java/awt/font/TextLayout/RotFontBoundsTest.java
Normal file
257
test/jdk/java/awt/font/TextLayout/RotFontBoundsTest.java
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import static javax.swing.BorderFactory.createEmptyBorder;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4650997
|
||||
* @summary rotate a TextLayout and verify that the bounds are correct
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual RotFontBoundsTest
|
||||
*/
|
||||
public final class RotFontBoundsTest {
|
||||
private static final String TEXT = ".This is a STRINg.";
|
||||
|
||||
private static final String INSTRUCTIONS =
|
||||
"A string \u201C" + TEXT + "\u201D is drawn at eight different "
|
||||
+ "angles, and eight boxes that surround the bounds of the text "
|
||||
+ "layouts (give or take a pixel) are drawn in red. The boxes "
|
||||
+ "are always composed of horizontal and vertical lines \u2014 "
|
||||
+ "they are not rotated.\n"
|
||||
+ "\n"
|
||||
+ "By default, all the rotations are displayed. Select or clear "
|
||||
+ "a check box with an angle to show or hide a particular "
|
||||
+ "rotation. Click \"Select All\" or \"Clear All\" to show all "
|
||||
+ "the rotations or to hide them.\n"
|
||||
+ "\n"
|
||||
+ "Click the Pass button if each box encloses its corresponding "
|
||||
+ "text layout.\n"
|
||||
+ "Otherwise, click Screenshot to save a screenshot for failure "
|
||||
+ "analysis and then click Fail.";
|
||||
|
||||
private static boolean verbose;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
verbose = (args.length > 0 && args[0].equalsIgnoreCase("verbose"));
|
||||
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.instructions(INSTRUCTIONS)
|
||||
.rows(20)
|
||||
.columns(50)
|
||||
.testTimeOut(15)
|
||||
.screenCapture()
|
||||
.testUI(RotFontBoundsTest::createUI)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
private static final int ROTATIONS = 8;
|
||||
|
||||
private static JComponent createUI() {
|
||||
final RotatedTextBounds rotatedText = new RotatedTextBounds();
|
||||
|
||||
final JPanel checkBoxes = new JPanel(new FlowLayout(FlowLayout.CENTER,
|
||||
4, 4));
|
||||
checkBoxes.setBorder(createEmptyBorder(0, 8, 8, 8));
|
||||
for (int i = 0; i < ROTATIONS; i++) {
|
||||
checkBoxes.add(new JCheckBox(new SelectRotationAction(i, rotatedText)));
|
||||
}
|
||||
|
||||
JButton selectAll = new JButton("Select All");
|
||||
selectAll.addActionListener(
|
||||
e -> selectAllCheckBoxes(checkBoxes.getComponents(), true));
|
||||
selectAll.setMnemonic('S');
|
||||
|
||||
JButton clearAll = new JButton("Clear All");
|
||||
clearAll.addActionListener(
|
||||
e -> selectAllCheckBoxes(checkBoxes.getComponents(), false));
|
||||
clearAll.setMnemonic('C');
|
||||
|
||||
Box controls = Box.createHorizontalBox();
|
||||
controls.add(new JLabel("Visible Rotations:"));
|
||||
controls.add(Box.createHorizontalGlue());
|
||||
controls.add(selectAll);
|
||||
controls.add(Box.createHorizontalStrut(4));
|
||||
controls.add(clearAll);
|
||||
controls.setBorder(createEmptyBorder(8, 8, 0, 8));
|
||||
|
||||
Box controlPanel = Box.createVerticalBox();
|
||||
controlPanel.add(controls);
|
||||
controlPanel.add(checkBoxes);
|
||||
|
||||
Box javaVersion = Box.createHorizontalBox();
|
||||
javaVersion.setBorder(createEmptyBorder(8, 8, 8, 8));
|
||||
javaVersion.add(new JLabel("Java version: "
|
||||
+ System.getProperty("java.runtime.version")));
|
||||
javaVersion.add(Box.createHorizontalGlue());
|
||||
|
||||
Box main = Box.createVerticalBox();
|
||||
main.setName("Rotated TextLayout Test");
|
||||
main.add(controlPanel);
|
||||
main.add(rotatedText);
|
||||
main.add(javaVersion);
|
||||
|
||||
return main;
|
||||
}
|
||||
|
||||
private static final class RotatedTextBounds extends JComponent {
|
||||
private final Font font = new Font(Font.DIALOG, Font.PLAIN, 24);
|
||||
|
||||
private final boolean[] rotationVisible = new boolean[ROTATIONS];
|
||||
|
||||
private RotatedTextBounds() {
|
||||
setBackground(Color.WHITE);
|
||||
setPreferredSize(new Dimension(400, 400));
|
||||
Arrays.fill(rotationVisible, true);
|
||||
}
|
||||
|
||||
public void setRotationVisible(int rotation, boolean visible) {
|
||||
rotationVisible[rotation] = visible;
|
||||
repaint();
|
||||
}
|
||||
|
||||
// Counts the number of paints
|
||||
private int counter = 0;
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics _g) {
|
||||
Graphics2D g = (Graphics2D) _g;
|
||||
Dimension d = getSize();
|
||||
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
|
||||
counter++;
|
||||
int x = d.width / 2;
|
||||
int y = d.height / 2;
|
||||
FontRenderContext frc = g.getFontRenderContext();
|
||||
|
||||
for (int i = 0; i < ROTATIONS; i++) {
|
||||
if (!rotationVisible[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double angle = -Math.PI / 4.0 * i;
|
||||
AffineTransform flip = AffineTransform.getRotateInstance(angle);
|
||||
Font flippedFont = font.deriveFont(flip);
|
||||
TextLayout tl = new TextLayout(TEXT, flippedFont, frc);
|
||||
Rectangle2D bb = tl.getBounds();
|
||||
g.setPaint(Color.BLACK);
|
||||
tl.draw(g, x, y);
|
||||
g.setPaint(Color.RED);
|
||||
g.drawRect(x + (int) bb.getX(), y + (int) bb.getY(),
|
||||
(int) bb.getWidth(), (int) bb.getHeight());
|
||||
|
||||
if (verbose) {
|
||||
if (counter == 1) {
|
||||
printDetails(angle, tl);
|
||||
} else if (i == 0) {
|
||||
System.out.println("Paint, counter=" + counter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printDetails(double angle, TextLayout tl) {
|
||||
System.out.println("Angle: " + angle);
|
||||
System.out.println("getAscent: " + tl.getAscent());
|
||||
System.out.println("getAdvance: " + tl.getAdvance());
|
||||
System.out.println("getBaseline: " + tl.getBaseline());
|
||||
System.out.println("getBounds: " + tl.getBounds());
|
||||
System.out.println("getDescent: " + tl.getDescent());
|
||||
System.out.println("getLeading: " + tl.getLeading());
|
||||
System.out.println("getVisibleAdvance: " + tl.getVisibleAdvance());
|
||||
System.out.println(".");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SelectRotationAction
|
||||
extends AbstractAction
|
||||
implements PropertyChangeListener {
|
||||
private final int rotation;
|
||||
private final RotatedTextBounds rotatedText;
|
||||
|
||||
private SelectRotationAction(int rotation,
|
||||
RotatedTextBounds rotatedText) {
|
||||
super(rotation * (360 / ROTATIONS) + "\u00B0");
|
||||
this.rotation = rotation;
|
||||
this.rotatedText = rotatedText;
|
||||
|
||||
putValue(SELECTED_KEY, true);
|
||||
|
||||
addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateRotationVisible() {
|
||||
rotatedText.setRotationVisible(rotation,
|
||||
(Boolean) getValue(SELECTED_KEY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateRotationVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(SELECTED_KEY)) {
|
||||
updateRotationVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void selectAllCheckBoxes(Component[] checkBoxes,
|
||||
boolean visible) {
|
||||
Arrays.stream(checkBoxes)
|
||||
.forEach(c -> ((JCheckBox) c).setSelected(visible));
|
||||
}
|
||||
}
|
||||
118
test/jdk/java/awt/font/TextLayout/StyledFontLayoutTest.java
Normal file
118
test/jdk/java/awt/font/TextLayout/StyledFontLayoutTest.java
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8139176
|
||||
* @summary Test layout uses correct styled font.
|
||||
* @run main StyledFontLayoutTest
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
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.GlyphVector;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
public class StyledFontLayoutTest extends JPanel {
|
||||
|
||||
static final int W=600, H=400;
|
||||
static boolean interactive;
|
||||
static BufferedImage im;
|
||||
public static void main(String[] args) {
|
||||
|
||||
interactive = args.length > 0;
|
||||
|
||||
runTest();
|
||||
|
||||
if (!interactive) {
|
||||
return;
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame frame = new JFrame("Styled Font Layout Test");
|
||||
frame.add(new StyledFontLayoutTest());
|
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
frame.setSize(W, H);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.drawImage(im, 0, 0, null);
|
||||
}
|
||||
|
||||
private static void runTest() {
|
||||
im = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = im.createGraphics();
|
||||
g2d.setColor(Color.white);
|
||||
g2d.fillRect(0, 0, W, H);
|
||||
g2d.setColor(Color.black);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
char[] chs = "Sample Text.".toCharArray();
|
||||
int len = chs.length;
|
||||
|
||||
int x = 50, y = 100;
|
||||
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
Font plain = new Font("Serif", Font.PLAIN, 48);
|
||||
GlyphVector pgv = plain.layoutGlyphVector(frc, chs, 0, len, 0);
|
||||
g2d.setFont(plain);
|
||||
g2d.drawChars(chs, 0, len, x, y); y +=50;
|
||||
|
||||
g2d.drawGlyphVector(pgv, x, y); y += 50;
|
||||
Rectangle2D plainStrBounds = plain.getStringBounds(chs, 0, len, frc);
|
||||
Rectangle2D plainGVBounds = pgv.getLogicalBounds();
|
||||
Font bold = new Font("Serif", Font.BOLD, 48);
|
||||
GlyphVector bgv = bold.layoutGlyphVector(frc, chs, 0, len, 0);
|
||||
Rectangle2D boldStrBounds = bold.getStringBounds(chs, 0, len, frc);
|
||||
Rectangle2D boldGVBounds = bgv.getLogicalBounds();
|
||||
g2d.setFont(bold);
|
||||
g2d.drawChars(chs, 0, len, x, y); y +=50;
|
||||
g2d.drawGlyphVector(bgv, x, y);
|
||||
System.out.println("Plain String Bounds = " + plainStrBounds);
|
||||
System.out.println("Bold String Bounds = " + boldStrBounds);
|
||||
System.out.println("Plain GlyphVector Bounds = " + plainGVBounds);
|
||||
System.out.println("Bold GlyphVector Bounds = " + boldGVBounds);
|
||||
if (!plainStrBounds.equals(boldStrBounds) &&
|
||||
plainGVBounds.equals(boldGVBounds))
|
||||
{
|
||||
System.out.println("Test failed: Plain GV bounds same as Bold");
|
||||
if (!interactive) {
|
||||
throw new RuntimeException("Plain GV bounds same as Bold");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
80
test/jdk/java/awt/font/TextLayout/TestAATMorxFont.java
Normal file
80
test/jdk/java/awt/font/TextLayout/TestAATMorxFont.java
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2018, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8031462 8198406
|
||||
* @requires (os.family == "mac")
|
||||
* @summary verify rendering of MORX fonts on OS X.
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
|
||||
|
||||
public class TestAATMorxFont {
|
||||
public static void main(String[] args) {
|
||||
String osName = System.getProperty("os.name");
|
||||
System.out.println("OS is " + osName);
|
||||
osName = osName.toLowerCase();
|
||||
if (!osName.startsWith("mac")) {
|
||||
return;
|
||||
}
|
||||
BufferedImage bi = new BufferedImage(1200, 400, TYPE_INT_ARGB);
|
||||
Graphics g = bi.getGraphics();
|
||||
test(g);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
private static void test(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
int y = 50;
|
||||
g.setFont(new Font("Gujarati MT", Font.PLAIN, 40));
|
||||
System.out.println(g.getFont());
|
||||
g.drawString("\u0A95\u0ACD \u0A95\u0A95\u0A95 \u0A95\u0ACD\u0A95\u0ACD\u0A95", 20, y);
|
||||
y += 50;
|
||||
g.setFont(new Font("Tamil Sangam MN", Font.PLAIN, 40));
|
||||
System.out.println(g.getFont());
|
||||
g.drawString("\u0b95\u0bCD \u0b95\u0b95\u0b95 \u0b95\u0bCD\u0b95\u0bCD\u0b95", 20, y);
|
||||
y += 50;
|
||||
g.setFont(new Font("Telugu Sangam MN", Font.PLAIN, 40));
|
||||
System.out.println(g.getFont());
|
||||
g.drawString("\u0c15\u0c4D \u0c15\u0c15\u0c15 \u0c15\u0c4D\u0c15\u0c4D\u0c15", 20, y);
|
||||
y += 50;
|
||||
g.setFont(new Font("Devanagari Sangam MN", Font.PLAIN, 40));
|
||||
System.out.println(g.getFont());
|
||||
g.drawString("\u0915\u0940 \u0915\u0947 \u0915\u0942", 20, y);
|
||||
y += 50;
|
||||
g.drawString("\u0907\u0930\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915", 20, y);
|
||||
y += 50;
|
||||
g.drawString("\u0930\u093F\u0935\u094D\u092F\u0942 \u0915\u0947 \u092C\u093E\u0926 \u0935\u093F\u0915\u093E\u0938 \u0913\u0932\u0902\u092A\u093F\u0915 \u0938\u0947 \u092C\u093E\u0939\u0930 (\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940) (\u0939\u093F\u0928\u094D\u0926\u0940) \u0907\u0930\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915", 20, y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
113
test/jdk/java/awt/font/TextLayout/TestGASPHint.java
Normal file
113
test/jdk/java/awt/font/TextLayout/TestGASPHint.java
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6320502
|
||||
* @summary Display laid out text which substitutes invisible glyphs correctly.
|
||||
* @library /java/awt/regtesthelpers /test/lib
|
||||
* @build PassFailJFrame jtreg.SkippedException
|
||||
* @run main/manual TestGASPHint
|
||||
*/
|
||||
|
||||
public class TestGASPHint extends JPanel {
|
||||
private static final String text = "\u0905\u0901\u0917\u094d\u0930\u0947\u091c\u093c\u0940";
|
||||
private static final Font font = getPhysicalFontForText(text, Font.PLAIN, 36);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (font == null) {
|
||||
throw new jtreg.SkippedException("No Devanagari font found. Test Skipped");
|
||||
}
|
||||
|
||||
final String INSTRUCTIONS = """
|
||||
A short piece of Devanagari text should appear without any
|
||||
artifacts. In particular there should be no "empty rectangles"
|
||||
representing the missing glyph.
|
||||
|
||||
If the above condition is true, press Pass, else Fail.""";
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("TestGASPHint Instruction")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.columns(32)
|
||||
.splitUI(TestGASPHint::new)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(200, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
|
||||
|
||||
g2d.setFont(font);
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.drawString(text, 10, 50);
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches the available system fonts for a font which can display all the
|
||||
* glyphs in the input text correctly. Returns null, if not found.
|
||||
*/
|
||||
private static Font getPhysicalFontForText(String text, int style, int size) {
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
String[] names = ge.getAvailableFontFamilyNames();
|
||||
|
||||
for (String n : names) {
|
||||
switch (n.toLowerCase()) {
|
||||
case "dialog":
|
||||
case "dialoginput":
|
||||
case "serif":
|
||||
case "sansserif":
|
||||
case "monospaced":
|
||||
break;
|
||||
default:
|
||||
Font f = new Font(n, style, size);
|
||||
if (f.canDisplayUpTo(text) == -1) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
261
test/jdk/java/awt/font/TextLayout/TestGetPixelBounds.java
Normal file
261
test/jdk/java/awt/font/TextLayout/TestGetPixelBounds.java
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2015, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6271221 8145584
|
||||
* @summary ask a text layout for its pixel bounds, then render it and
|
||||
* compute the actual pixel bounds when rendering-- the actual pixel bounds
|
||||
* must be contained within the bounds reported by the text layout, or there
|
||||
* will be an exception.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2005 IBM Corp. All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import static java.awt.Font.*;
|
||||
import static java.awt.font.GraphicAttribute.*;
|
||||
import static java.awt.font.ShapeGraphicAttribute.*;
|
||||
import static java.awt.font.TextAttribute.*;
|
||||
|
||||
public class TestGetPixelBounds {
|
||||
static final boolean DEBUG;
|
||||
static final boolean DUMP;
|
||||
static {
|
||||
String dbg = null;
|
||||
String dmp = null;
|
||||
try {
|
||||
dbg = System.getProperty("DEBUG");
|
||||
dmp = System.getProperty("DUMP");
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
dbg = dmp = null;
|
||||
}
|
||||
|
||||
DEBUG = dbg != null;
|
||||
DUMP = dmp != null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
boolean rotate = false;
|
||||
boolean underline = false;
|
||||
boolean graphic = false;
|
||||
String text = "Ping";
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
String arg = args[i];
|
||||
if (arg.startsWith("-x")) {
|
||||
x = Float.parseFloat(args[++i]);
|
||||
} else if (arg.startsWith("-y")) {
|
||||
y = Float.parseFloat(args[++i]);
|
||||
} else if (arg.startsWith("-r")) {
|
||||
rotate = true;
|
||||
} else if (arg.startsWith("-u")) {
|
||||
underline = true;
|
||||
} else if (arg.startsWith("-g")) {
|
||||
graphic = true;
|
||||
} else if (arg.startsWith("-t")) {
|
||||
text = args[++i];
|
||||
}
|
||||
}
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
Map<TextAttribute, Object> m = new HashMap<TextAttribute, Object>();
|
||||
m.put(FAMILY, SANS_SERIF);
|
||||
m.put(SIZE, 16);
|
||||
if (underline) {
|
||||
m.put(UNDERLINE, UNDERLINE_ON);
|
||||
}
|
||||
if (rotate) {
|
||||
m.put(TRANSFORM, AffineTransform.getRotateInstance(Math.PI/4));
|
||||
}
|
||||
Font font = Font.getFont(m);
|
||||
|
||||
AttributedString as;
|
||||
if (graphic) {
|
||||
GraphicAttribute sga = new ShapeGraphicAttribute(
|
||||
new Ellipse2D.Float(0,-10,10,20), TOP_ALIGNMENT, STROKE);
|
||||
as = new AttributedString(text + '*' + text, m);
|
||||
as.addAttribute(CHAR_REPLACEMENT, sga, text.length(), text.length() + 1);
|
||||
} else {
|
||||
as = new AttributedString(text, m);
|
||||
}
|
||||
TextLayout tl = new TextLayout(as.getIterator(), frc);
|
||||
System.out.println("tl bounds: " + tl.getBounds());
|
||||
System.out.println("tl compute: " + computeLayoutBounds(tl, x, y, frc));
|
||||
System.out.println("tl pixel bounds: " + tl.getPixelBounds(frc, x, y));
|
||||
System.out.println(" again int off: " + tl.getPixelBounds(frc, x+2, y - 2));
|
||||
System.out.println(" again frac off: " + tl.getPixelBounds(frc, x+.5f, y + .2f));
|
||||
System.out.println(" again frc: " + tl.getPixelBounds(
|
||||
new FontRenderContext(AffineTransform.getScaleInstance(100, 100), true, true), x, y));
|
||||
System.out.println(" again int off: " + tl.getPixelBounds(frc, x-2, y+2));
|
||||
|
||||
GlyphVector gv = font.createGlyphVector(frc, text);
|
||||
System.out.println("gv bounds: " + gv.getPixelBounds(frc, x, y));
|
||||
System.out.println("gv compute: " + computeLayoutBounds(gv, x, y, frc));
|
||||
|
||||
if (!tl.getPixelBounds(frc, x, y).contains(computeLayoutBounds(tl, x, y, frc))) {
|
||||
throw new RuntimeException("error, tl.bounds does not contain computed bounds");
|
||||
}
|
||||
}
|
||||
|
||||
static Rectangle computeLayoutBounds(TextLayout tl, float x, float y, FontRenderContext frc) {
|
||||
Rectangle bounds = tl.getBounds().getBounds();
|
||||
BufferedImage im = new BufferedImage(bounds.width + 4, bounds.height + 4,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D g2d = im.createGraphics();
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.fillRect(0, 0, im.getWidth(), im.getHeight());
|
||||
|
||||
float fx = (float)Math.IEEEremainder(x,1);
|
||||
float fy = (float)Math.IEEEremainder(y,1);
|
||||
g2d.setColor(Color.BLACK);
|
||||
tl.draw(g2d, fx + 2 - bounds.x, fy + 2 - bounds.y);
|
||||
|
||||
Rectangle r = computePixelBounds(im);
|
||||
r.x += (int)Math.floor(x) - 2 + bounds.x;
|
||||
r.y += (int)Math.floor(y) - 2 + bounds.y;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static Rectangle computeLayoutBounds(GlyphVector gv, float x, float y, FontRenderContext frc) {
|
||||
Rectangle bounds = gv.getVisualBounds().getBounds();
|
||||
BufferedImage im = new BufferedImage(bounds.width + 4, bounds.height + 4,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D g2d = im.createGraphics();
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.fillRect(0, 0, im.getWidth(), im.getHeight());
|
||||
|
||||
float fx = (float)Math.IEEEremainder(x,1);
|
||||
float fy = (float)Math.IEEEremainder(y,1);
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.drawGlyphVector(gv, fx + 2 - bounds.x, fy + 2 - bounds.y);
|
||||
|
||||
Rectangle r = computePixelBounds(im);
|
||||
r.x += (int)Math.floor(x) - 2 + bounds.x;
|
||||
r.y += (int)Math.floor(y) - 2 + bounds.y;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static Rectangle computePixelBounds(BufferedImage im) {
|
||||
int w = im.getWidth();
|
||||
int h = im.getHeight();
|
||||
|
||||
Formatter fmt = DEBUG ? new Formatter(System.err) : null;
|
||||
|
||||
// dump
|
||||
if (DUMP && DEBUG) {
|
||||
fmt.format(" ");
|
||||
for (int j = 0; j < w; ++j) {
|
||||
fmt.format("%2d", j);
|
||||
}
|
||||
for (int i = 0; i < h; ++i) {
|
||||
fmt.format("\n[%2d] ", i);
|
||||
for (int j = 0; j < w; ++j) {
|
||||
fmt.format("%c ", im.getRGB(j, i) == -1 ? ' ' : '*');
|
||||
}
|
||||
}
|
||||
fmt.format("\n");
|
||||
}
|
||||
|
||||
int l = -1, t = -1, r = w, b = h;
|
||||
|
||||
{
|
||||
// get top
|
||||
int[] buf = new int[w];
|
||||
loop:
|
||||
while (++t < h) {
|
||||
im.getRGB(0, t, buf.length, 1, buf, 0, w); // w ignored
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
if (buf[i] != -1) {
|
||||
if (DEBUG) fmt.format("top pixel at %d,%d = 0x%08x\n", i, t, buf[i]);
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) fmt.format("t: %d\n", t);
|
||||
}
|
||||
|
||||
// get bottom
|
||||
{
|
||||
int[] buf = new int[w];
|
||||
loop:
|
||||
while (--b > t) {
|
||||
im.getRGB(0, b, buf.length, 1, buf, 0, w); // w ignored
|
||||
for (int i = 0; i < buf.length; ++i) {
|
||||
if (buf[i] != -1) {
|
||||
if (DEBUG) fmt.format("bottom pixel at %d,%d = 0x%08x\n", i, b, buf[i]);
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
++b;
|
||||
if (DEBUG) fmt.format("b: %d\n", b);
|
||||
}
|
||||
|
||||
// get left
|
||||
{
|
||||
loop:
|
||||
while (++l < r) {
|
||||
for (int i = t; i < b; ++i) {
|
||||
int v = im.getRGB(l, i);
|
||||
if (v != -1) {
|
||||
if (DEBUG) fmt.format("left pixel at %d,%d = 0x%08x\n", l, i, v);
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) fmt.format("l: %d\n", l);
|
||||
}
|
||||
|
||||
// get right
|
||||
{
|
||||
loop:
|
||||
while (--r > l) {
|
||||
for (int i = t; i < b; ++i) {
|
||||
int v = im.getRGB(r, i);
|
||||
if (v != -1) {
|
||||
if (DEBUG) fmt.format("right pixel at %d,%d = 0x%08x\n", r, i, v);
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
++r;
|
||||
if (DEBUG) fmt.format("r: %d\n", r);
|
||||
}
|
||||
|
||||
return new Rectangle(l, t, r-l, b-t);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2026, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6562639
|
||||
* @summary Verify correct getPixelBounds() behavior regardless of text color.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestGetPixelBoundsWithColors {
|
||||
|
||||
private static final Color TRANSPARENT_BLACK = new Color(0, 0, 0, 0);
|
||||
private static final Color TRANSPARENT_WHITE = new Color(255, 255, 255, 0);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Color[] colors = new Color[] {
|
||||
Color.WHITE, Color.BLACK, Color.YELLOW, Color.RED, Color.GREEN,
|
||||
Color.GRAY, Color.LIGHT_GRAY, Color.DARK_GRAY, Color.PINK,
|
||||
Color.CYAN, Color.MAGENTA, Color.BLUE, null
|
||||
};
|
||||
|
||||
for (Color color : colors) {
|
||||
test(color);
|
||||
}
|
||||
|
||||
testTransparent(TRANSPARENT_BLACK);
|
||||
testTransparent(TRANSPARENT_WHITE);
|
||||
}
|
||||
|
||||
private static void test(Color c) {
|
||||
Map< TextAttribute, Object > underline = new HashMap<>();
|
||||
underline.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||
Font font1 = new Font(Font.DIALOG, Font.PLAIN, 60).deriveFont(underline);
|
||||
Map< TextAttribute, Object > foreground = new HashMap<>();
|
||||
foreground.put(TextAttribute.FOREGROUND, c);
|
||||
Font font2 = font1.deriveFont(foreground);
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
TextLayout layout1 = new TextLayout("TEST", font1, frc);
|
||||
TextLayout layout2 = new TextLayout("TEST", font2, frc);
|
||||
Rectangle r1 = layout1.getPixelBounds(frc, 0, 0);
|
||||
Rectangle r2 = layout2.getPixelBounds(frc, 0, 0);
|
||||
if (!r1.equals(r2)) {
|
||||
throw new RuntimeException("For color " + c + ", " + r1 + " != " + r2);
|
||||
}
|
||||
Rectangle2D bounds = layout1.getBounds();
|
||||
if (Math.abs(bounds.getX() - r1.x) > 3 ||
|
||||
Math.abs(bounds.getY() - r1.y) > 3 ||
|
||||
Math.abs(bounds.getWidth() - r1.width) > 6 ||
|
||||
Math.abs(bounds.getHeight() - r1.height) > 6) {
|
||||
throw new RuntimeException("For color " + c + ", pixel bounds " +
|
||||
r1 + " not similar to " + bounds);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testTransparent(Color c) {
|
||||
Font font1 = new Font(Font.DIALOG, Font.PLAIN, 60);
|
||||
Map< TextAttribute, Object > attributes = new HashMap<>();
|
||||
attributes.put(TextAttribute.FOREGROUND, c);
|
||||
Font font2 = font1.deriveFont(attributes);
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
TextLayout layout = new TextLayout("TEST", font2, frc);
|
||||
Rectangle r = layout.getPixelBounds(frc, 0, 0);
|
||||
if (!r.isEmpty()) {
|
||||
throw new RuntimeException("Expected empty pixel bounds for " + c + " but got " + r);
|
||||
}
|
||||
}
|
||||
}
|
||||
155
test/jdk/java/awt/font/TextLayout/TestGraphicOutline.java
Normal file
155
test/jdk/java/awt/font/TextLayout/TestGraphicOutline.java
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GraphicAttribute;
|
||||
import java.awt.font.ShapeGraphicAttribute;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4915565 4920820 4920952
|
||||
* @summary Display graphics (circles) embedded in text, and draw both the outline (top)
|
||||
* and black box bounds (bottom) of the result. The circles should each display at a
|
||||
* different height. The outline and frames should approximately (within a pixel
|
||||
* or two) surround each character.
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual TestGraphicOutline
|
||||
*/
|
||||
|
||||
public class TestGraphicOutline {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final String INSTRUCTIONS = """
|
||||
Display graphics (circles) embedded in text, and draw both the
|
||||
outline (top) and black box bounds (bottom) of the result.
|
||||
|
||||
The circles should each display at a different height.
|
||||
The outline and frames should approximately (within a pixel or two)
|
||||
surround each character.
|
||||
|
||||
Pass the test if these conditions hold.
|
||||
|
||||
'Black box bounds' is a term that refers to the bounding rectangles
|
||||
of each glyph, see the TextLayout API getBlackBoxBounds. It does not
|
||||
mean that the rendered outlines in the test are supposed to be black.
|
||||
The color of the outlines does not matter and is not part of the test
|
||||
conditions. Since there is no API for embedded graphics to return an
|
||||
outline that matches the shape of the graphics, the outlines of the
|
||||
graphics are their visual bounding boxes, which are rectangles.
|
||||
|
||||
This is not an error. These outlines, as stated, should surround each
|
||||
character's graphic.""";
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("TestGraphicOutline Instruction")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.columns(40)
|
||||
.testUI(TestGraphicsPanel::new)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
private static final class TestGraphicsPanel extends JPanel {
|
||||
|
||||
TextLayout tl;
|
||||
|
||||
public TestGraphicsPanel() {
|
||||
setBackground(Color.white);
|
||||
setPreferredSize(new Dimension(650, 300));
|
||||
setName("2D Text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
int w = getSize().width;
|
||||
int h = getSize().height;
|
||||
|
||||
g2.setColor(getBackground());
|
||||
g2.fillRect(0, 0, w, h);
|
||||
|
||||
Font f1 = new Font(Font.SANS_SERIF, Font.BOLD, 60);
|
||||
Font f2 = new Font(Font.SERIF, Font.ITALIC, 80);
|
||||
String str = "The Starry Night ok?";
|
||||
|
||||
AttributedString ats = new AttributedString(str);
|
||||
|
||||
Shape s = new Ellipse2D.Float(0, -10, 12, 12);
|
||||
GraphicAttribute iga1 = new ShapeGraphicAttribute(s, GraphicAttribute.TOP_ALIGNMENT, false);
|
||||
GraphicAttribute iga2 = new ShapeGraphicAttribute(s, GraphicAttribute.HANGING_BASELINE, false);
|
||||
GraphicAttribute iga3 = new ShapeGraphicAttribute(s, GraphicAttribute.CENTER_BASELINE, false);
|
||||
GraphicAttribute iga4 = new ShapeGraphicAttribute(s, GraphicAttribute.ROMAN_BASELINE, false);
|
||||
GraphicAttribute iga5 = new ShapeGraphicAttribute(s, GraphicAttribute.BOTTOM_ALIGNMENT, false);
|
||||
|
||||
ats.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga1, 1, 2);
|
||||
ats.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga2, 3, 4);
|
||||
ats.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga3, 7, 8);
|
||||
ats.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga4, 10, 11);
|
||||
ats.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga5, 14, 15);
|
||||
ats.addAttribute(TextAttribute.FONT, f1, 0, 20);
|
||||
ats.addAttribute(TextAttribute.FONT, f2, 4, 10);
|
||||
AttributedCharacterIterator iter = ats.getIterator();
|
||||
|
||||
FontRenderContext frc = g2.getFontRenderContext();
|
||||
tl = new TextLayout(iter, frc);
|
||||
Rectangle2D bounds = tl.getBounds();
|
||||
float sw = (float) bounds.getWidth();
|
||||
float sh = (float) bounds.getHeight();
|
||||
|
||||
g2.translate((w - sw) / 2f, h / 2f - sh + tl.getAscent() - 2);
|
||||
|
||||
g2.setColor(Color.blue);
|
||||
tl.draw(g2, 0, 0);
|
||||
g2.draw(bounds);
|
||||
|
||||
g2.setColor(Color.black);
|
||||
Shape shape = tl.getOutline(null);
|
||||
g2.draw(shape);
|
||||
|
||||
g2.translate(0, sh + 5);
|
||||
|
||||
g2.setColor(Color.blue);
|
||||
tl.draw(g2, 0, 0);
|
||||
g2.draw(bounds);
|
||||
|
||||
g2.setColor(Color.red);
|
||||
shape = tl.getBlackBoxBounds(0, tl.getCharacterCount());
|
||||
g2.draw(shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
test/jdk/java/awt/font/TextLayout/TestHebrewMark.java
Normal file
84
test/jdk/java/awt/font/TextLayout/TestHebrewMark.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 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.
|
||||
*/
|
||||
/* @test
|
||||
* @summary verify TextLayout handles Hebrew marks correctly
|
||||
* @bug 6529141
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
|
||||
public class TestHebrewMark {
|
||||
|
||||
public static void main(String args[]) {
|
||||
FontRenderContext frc = new FontRenderContext(null,false,false);
|
||||
final String fonts[] = { "Arial", "Arial Hebrew", "Arial Unicode" };
|
||||
final char ALEF = '\u05D0'; // a letter
|
||||
final char QAMATS = '\u05B8'; // a combining mark, should show up UNDER the alef (no advance)
|
||||
final String string1 = "\u05DE\u05B8\u05E9\u05C1\u05B0\u05DB\u05B5\u05E0\u05B4\u05D9\u05D0\u05B7\u05D7\u05B2\u05E8\u05B6\u05D9\u05DA\u05B8\u05E0\u05BC\u05B8\u05E8\u05D5\u05BC\u05E6\u05B8\u05D4\u05D4\u05B1\u05D1\u05B4\u05D9\u05D0\u05B7\u05E0\u05B4\u05D9\u05D4\u05B7\u05DE\u05BC\u05B6\u05DC\u05B6\u05DA\u05B0\u05D7\u05B2\u05D3\u05B8\u05E8\u05B8\u05D9\u05D5\u05E0\u05B8\u05D2\u05B4\u05D9\u05DC\u05B8\u05D4\u05D5\u05B0\u05E0\u05B4\u05E9\u05C2\u05B0\u05DE\u05B0\u05D7\u05B8\u05D4\u0020\u05D1\u05BC\u05B8\u05DA\u05B0\u05E0\u05B7\u05D6\u05B0\u05DB\u05BC\u05B4\u05D9\u05E8\u05B8\u05D4\u05D3\u05B9\u05D3\u05B6\u05D9\u05DA\u05B8\u05DE\u05B4\u05D9\u05BC\u05B7\u05D9\u05B4\u05DF\u05DE\u05B5\u05D9\u05E9\u05C1\u05B8\u05E8\u05B4\u05D9\u05DD\u05D0\u05B2\u05D4\u05B5\u05D1\u05D5\u05BC\u05DA\u05B8";
|
||||
final String string2 = string1.replaceAll("\u05B8", ""); // remove qamats
|
||||
int string1len = string1.length();
|
||||
int string2len = string2.length();
|
||||
System.out.println("String1 has " + string1len+" chars, and string2 (without the QAMATS) has " + string2.length());
|
||||
if(string1len == string2len) {
|
||||
throw new RuntimeException("Hey, string1 and string2 are both " + string1len + " chars long - shouldn't happen.");
|
||||
}
|
||||
Font f = null;
|
||||
// try to find a font that will work
|
||||
for(String fontname : fonts ) {
|
||||
System.err.println("trying: " +fontname);
|
||||
Font afont = new Font(fontname,Font.PLAIN,18);
|
||||
if(!afont.getFontName().equals(fontname)) {
|
||||
System.out.println(fontname + ": is actually " + afont.getFontName() + " - skipping this font.");
|
||||
continue;
|
||||
}
|
||||
if(!afont.canDisplay(ALEF) || !afont.canDisplay(QAMATS)) {
|
||||
System.out.println(fontname + ": can't display ALEF or QAMATS - skipping this font");
|
||||
continue;
|
||||
}
|
||||
f = afont;
|
||||
System.err.println("Might be OK: " + fontname);
|
||||
System.out.println("Using font " + f.getFontName());
|
||||
TextLayout tl = new TextLayout(string1, f, frc);
|
||||
TextLayout tl2 = new TextLayout(string2, f, frc);
|
||||
Rectangle2D tlBounds = tl.getBounds();
|
||||
Rectangle2D tlBounds2 = tl2.getBounds();
|
||||
System.out.println("tlbounds="+tlBounds);
|
||||
System.out.println("tl.getAdvance()="+tl.getAdvance());
|
||||
System.out.println("tl2bounds="+tlBounds2);
|
||||
System.out.println("tl2.getAdvance()="+tl2.getAdvance());
|
||||
|
||||
if(tl.getAdvance() != tl2.getAdvance()) {
|
||||
throw new RuntimeException("Advance of string with and without QAMATS differs: " + tl.getAdvance() + " vs. " + tl2.getAdvance());
|
||||
} else {
|
||||
System.out.println("6529141 OK, widths are same.");
|
||||
}
|
||||
}
|
||||
// print a notice if none of them worked.
|
||||
if(f == null) {
|
||||
System.out.println("Could not find a suitable font - skipping this test.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
261
test/jdk/java/awt/font/TextLayout/TestJustification.java
Normal file
261
test/jdk/java/awt/font/TextLayout/TestJustification.java
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
PASS the test if this is true, else press FAIL.
|
||||
""";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("Test Instructions")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.rows((int) INSTRUCTIONS.lines().count() + 2)
|
||||
.columns(35)
|
||||
.testUI(TestJustification::createUI)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
test/jdk/java/awt/font/TextLayout/TestOldHangul.java
Normal file
82
test/jdk/java/awt/font/TextLayout/TestOldHangul.java
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Verify Old Hangul display
|
||||
* @bug 6886358
|
||||
* @ignore Requires a special font installed.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class TestOldHangul {
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new TestOldHangul().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
public static boolean AUTOMATIC_TEST=true; // true; run test automatically, else manually at button push
|
||||
|
||||
private void run() {
|
||||
Font ourFont = null;
|
||||
final String fontName = "UnBatangOdal.ttf"; // download from http://chem.skku.ac.kr/~wkpark/project/font/GSUB/UnbatangOdal/ and place in {user.home}/fonts/
|
||||
try {
|
||||
ourFont = Font.createFont(Font.TRUETYPE_FONT, new java.io.File(new java.io.File(System.getProperty("user.home"),"fonts"), fontName));
|
||||
ourFont = ourFont.deriveFont((float)48.0);
|
||||
} catch(Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.err.println("Fail: " + t);
|
||||
return;
|
||||
}
|
||||
JFrame frame = new JFrame(System.getProperty("java.version"));
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
JPanel panel = new JPanel();
|
||||
final JTextArea label = new JTextArea("(empty)");
|
||||
label.setSize(400, 300);
|
||||
label.setBorder(new LineBorder(Color.black));
|
||||
label.setFont(ourFont);
|
||||
final String str = "\u110A\u119E\u11B7\u0020\u1112\u119E\u11AB\uAE00\u0020\u1100\u119E\u11F9\u0020\u112B\u119E\u11BC\n";
|
||||
|
||||
if(AUTOMATIC_TEST) { /* run the test automatically (else, manually) */
|
||||
label.setText(str);
|
||||
} else {
|
||||
JButton button = new JButton("Old Hangul");
|
||||
button.addActionListener(new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
label.setText(str);
|
||||
}
|
||||
});
|
||||
panel.add(button);
|
||||
}
|
||||
panel.add(label);
|
||||
|
||||
frame.getContentPane().add(panel);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
134
test/jdk/java/awt/font/TextLayout/TestSelection.java
Normal file
134
test/jdk/java/awt/font/TextLayout/TestSelection.java
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.text.AttributedString;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4221422
|
||||
* @summary Display several TextLayouts with various selections.
|
||||
* All the selections should be between non-italic and italic text,
|
||||
* and the top and bottom of the selection region should be horizontal.
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual TestSelection
|
||||
*/
|
||||
|
||||
public final class TestSelection extends JPanel {
|
||||
private static final float MARGIN = 20;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final String INSTRUCTIONS = """
|
||||
Several TextLayouts are displayed along with selections.
|
||||
The selection regions should have horizontal top and bottom segments.
|
||||
|
||||
If above condition is true, press Pass else Fail.""";
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("TestSelection Instruction")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.columns(40)
|
||||
.splitUI(TestSelection::new)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(300, 300);
|
||||
}
|
||||
|
||||
private float drawSelectionAndLayout(Graphics2D g2d,
|
||||
TextLayout layout,
|
||||
float y,
|
||||
int selStart,
|
||||
int selLimit) {
|
||||
Color selectionColor = Color.PINK;
|
||||
Color textColor = Color.BLACK;
|
||||
|
||||
y += layout.getAscent();
|
||||
|
||||
g2d.translate(MARGIN, y);
|
||||
Shape hl = layout.getLogicalHighlightShape(selStart, selLimit);
|
||||
g2d.setColor(selectionColor);
|
||||
g2d.fill(hl);
|
||||
g2d.setColor(textColor);
|
||||
layout.draw(g2d, 0, 0);
|
||||
g2d.translate(-MARGIN, -y);
|
||||
|
||||
y += layout.getDescent() + layout.getLeading() + 10;
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
String text = "Hello world";
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
AttributedString attrStr = new AttributedString(text);
|
||||
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
|
||||
final int midPoint = text.indexOf('w');
|
||||
final int selStart = midPoint / 2;
|
||||
final int selLimit = text.length() - selStart;
|
||||
final Font italic = new Font(Font.SANS_SERIF, Font.ITALIC, 24);
|
||||
|
||||
float y = MARGIN;
|
||||
|
||||
attrStr.addAttribute(TextAttribute.FONT, italic, 0, midPoint);
|
||||
TextLayout layout = new TextLayout(attrStr.getIterator(), frc);
|
||||
|
||||
y = drawSelectionAndLayout(g2d, layout, y, selStart - 1, selLimit);
|
||||
y = drawSelectionAndLayout(g2d, layout, y, selStart, selLimit);
|
||||
y = drawSelectionAndLayout(g2d, layout, y, selStart + 1, selLimit);
|
||||
|
||||
attrStr = new AttributedString(text);
|
||||
attrStr.addAttribute(TextAttribute.FONT,
|
||||
italic, midPoint, text.length());
|
||||
layout = new TextLayout(attrStr.getIterator(), frc);
|
||||
|
||||
y = drawSelectionAndLayout(g2d, layout, y, selStart, selLimit);
|
||||
|
||||
attrStr = new AttributedString(text);
|
||||
attrStr.addAttribute(TextAttribute.FONT, italic, 0, midPoint);
|
||||
attrStr.addAttribute(TextAttribute.SIZE, 48f, midPoint, text.length());
|
||||
layout = new TextLayout(attrStr.getIterator(), frc);
|
||||
|
||||
y = drawSelectionAndLayout(g2d, layout, y, selStart, selLimit);
|
||||
}
|
||||
}
|
||||
72
test/jdk/java/awt/font/TextLayout/TestSinhalaChar.java
Normal file
72
test/jdk/java/awt/font/TextLayout/TestSinhalaChar.java
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @summary verify lack of crash on U+0DDD.
|
||||
* @bug 6795060
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class TestSinhalaChar {
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new TestSinhalaChar().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
public static boolean AUTOMATIC_TEST=true; // true; run test automatically, else manually at button push
|
||||
|
||||
private void run() {
|
||||
JFrame frame = new JFrame("Test Character (no crash = PASS)");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
JPanel panel = new JPanel();
|
||||
final JLabel label = new JLabel("(empty)");
|
||||
label.setSize(400, 100);
|
||||
label.setBorder(new LineBorder(Color.black));
|
||||
label.setFont(new Font(Font.DIALOG, Font.PLAIN, 12));
|
||||
if(AUTOMATIC_TEST) { /* run the test automatically (else, manually) */
|
||||
label.setText(Character.toString('\u0DDD'));
|
||||
} else {
|
||||
JButton button = new JButton("Set Char x0DDD");
|
||||
button.addActionListener(new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
label.setText(Character.toString('\u0DDD'));
|
||||
}
|
||||
});
|
||||
panel.add(button);
|
||||
}
|
||||
panel.add(label);
|
||||
|
||||
frame.getContentPane().add(panel);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
92
test/jdk/java/awt/font/TextLayout/TestStrikethrough.java
Normal file
92
test/jdk/java/awt/font/TextLayout/TestStrikethrough.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6426360
|
||||
* @summary Display a TextLayout with strikethrough at a number of
|
||||
* different offsets relative to the pixel grid.
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual TestStrikethrough
|
||||
*/
|
||||
|
||||
public class TestStrikethrough extends JPanel {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final String INSTRUCTIONS = """
|
||||
Display text with strikethrough at a number of different positions.
|
||||
|
||||
Press Fail if any line is missing a strikethrough else press Pass.""";
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.title("TestStrikethrough Instruction")
|
||||
.instructions(INSTRUCTIONS)
|
||||
.columns(35)
|
||||
.splitUI(TestStrikethrough::new)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(200, 120);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics aContext) {
|
||||
Graphics2D g2d = (Graphics2D) aContext;
|
||||
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
Font font = new Font(Font.DIALOG, Font.PLAIN, 9);
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
String str = "Where is the strikethrough?";
|
||||
AttributedString as = new AttributedString(str);
|
||||
as.addAttribute(TextAttribute.FONT, font);
|
||||
as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
|
||||
AttributedCharacterIterator aci = as.getIterator();
|
||||
TextLayout tl = new TextLayout(aci, frc);
|
||||
float delta = (float) (Math.ceil(tl.getAscent() + tl.getDescent() + tl.getLeading()) + .1);
|
||||
float y = delta - .1f;
|
||||
g2d.setColor(Color.BLACK);
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
tl.draw(g2d, 10f, y);
|
||||
y += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
86
test/jdk/java/awt/font/TextLayout/TestTibetan.java
Normal file
86
test/jdk/java/awt/font/TextLayout/TestTibetan.java
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary verify tibetan output
|
||||
* @bug 6886358
|
||||
* @ignore Requires a special font installed
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class TestTibetan {
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new TestTibetan().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
public static boolean AUTOMATIC_TEST=true; // true; run test automatically, else manually at button push
|
||||
|
||||
private void run() {
|
||||
Font ourFont = null;
|
||||
try {
|
||||
//For best results: Font from: http://download.savannah.gnu.org/releases/free-tibetan/jomolhari/
|
||||
// place in $(user.home)/fonts/
|
||||
ourFont = Font.createFont(Font.TRUETYPE_FONT, new java.io.File(new java.io.File(System.getProperty("user.home"),"fonts"), "Jomolhari-alpha3c-0605331.ttf"));
|
||||
|
||||
//ourFont = new Font("serif",Font.PLAIN, 24);
|
||||
ourFont = ourFont.deriveFont((float)24.0);
|
||||
} catch(Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.err.println("Fail: " + t);
|
||||
return;
|
||||
}
|
||||
JFrame frame = new JFrame(System.getProperty("java.version"));
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
JPanel panel = new JPanel();
|
||||
final JTextArea label = new JTextArea("(empty)");
|
||||
label.setSize(400, 300);
|
||||
label.setBorder(new LineBorder(Color.black));
|
||||
label.setFont(ourFont);
|
||||
|
||||
final String str = "\u0F04\u0F05\u0F0D\u0F0D\u0020\u0F4F\u0F72\u0F53\u0F0B\u0F4F\u0F72\u0F53\u0F0B\u0F42\u0FB1\u0F72\u0F0B\u0F51\u0F54\u0F60\u0F0B\u0F62\u0FA9\u0F63"; // TinTin.
|
||||
|
||||
if(AUTOMATIC_TEST) { /* run the test automatically (else, manually) */
|
||||
label.setText(str);
|
||||
} else {
|
||||
JButton button = new JButton("Set Char x0DDD");
|
||||
button.addActionListener(new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
label.setText(str);
|
||||
}
|
||||
});
|
||||
panel.add(button);
|
||||
}
|
||||
panel.add(label);
|
||||
|
||||
frame.getContentPane().add(panel);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/java/awt/font/TextLayout/TestVS-expect.png
Normal file
BIN
test/jdk/java/awt/font/TextLayout/TestVS-expect.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
92
test/jdk/java/awt/font/TextLayout/TestVS.java
Normal file
92
test/jdk/java/awt/font/TextLayout/TestVS.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Verify Variation Selector matches an expected image
|
||||
* @bug 8187100
|
||||
* @ignore Requires a special font installed.
|
||||
*/
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.ImageIcon;
|
||||
import java.awt.Font;
|
||||
import java.awt.Color;
|
||||
|
||||
public class TestVS {
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new TestVS().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void run() {
|
||||
Font ourFont = null;
|
||||
final String fontName = "ipaexm.ttf";
|
||||
// download from https://ipafont.ipa.go.jp/node26#en
|
||||
// and place in {user.home}/fonts/
|
||||
try {
|
||||
ourFont = Font.createFont(Font.TRUETYPE_FONT,
|
||||
new java.io.File(new java.io.File(
|
||||
System.getProperty("user.home"),
|
||||
"fonts"), fontName));
|
||||
ourFont = ourFont.deriveFont((float)48.0);
|
||||
final String actualFontName = ourFont.getFontName();
|
||||
if (!actualFontName.equals("IPAexMincho")) {
|
||||
System.err.println("*** Warning: missing font IPAexMincho.");
|
||||
System.err.println("*** Using font: " + actualFontName);
|
||||
}
|
||||
} catch(Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.err.println("Fail: " + t);
|
||||
return;
|
||||
}
|
||||
JFrame frame = new JFrame(System.getProperty("java.version"));
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
JPanel panel = new JPanel();
|
||||
final JTextArea label = new JTextArea("empty");
|
||||
label.setSize(400, 300);
|
||||
label.setBorder(new LineBorder(Color.black));
|
||||
label.setFont(ourFont);
|
||||
|
||||
final String str = "\u845b\udb40\udd00\u845b\udb40\udd01\n";
|
||||
|
||||
label.setText(str);
|
||||
|
||||
panel.add(label);
|
||||
panel.add(new JLabel(ourFont.getFamily()));
|
||||
|
||||
// Show the expected result.
|
||||
panel.add(new JLabel(new ImageIcon("TestVS-expect.png")));
|
||||
|
||||
frame.getContentPane().add(panel);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
53
test/jdk/java/awt/font/TextLayout/TextLayoutBounds.java
Normal file
53
test/jdk/java/awt/font/TextLayout/TextLayoutBounds.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2007, 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.
|
||||
*/
|
||||
/* @test
|
||||
* @summary verify TextLayout.getBounds() return visual bounds
|
||||
* @bug 6323611 6761856
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
|
||||
public class TextLayoutBounds {
|
||||
|
||||
public static void main(String args[]) {
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
Font f = new Font("SansSerif",Font.BOLD,32);
|
||||
String s = new String("JAVA");
|
||||
TextLayout tl = new TextLayout(s, f, frc);
|
||||
Rectangle2D tlBounds = tl.getBounds();
|
||||
GlyphVector gv = f.createGlyphVector(frc, s);
|
||||
Rectangle2D gvvBounds = gv.getVisualBounds();
|
||||
Rectangle2D oBounds = tl.getOutline(null).getBounds2D();
|
||||
System.out.println("tlbounds="+tlBounds);
|
||||
System.out.println("gvbounds="+gvvBounds);
|
||||
System.out.println("outlineBounds="+oBounds);
|
||||
if (!gvvBounds.equals(tlBounds)) {
|
||||
throw new RuntimeException("Bounds differ [gvv != tl]");
|
||||
}
|
||||
if (!tlBounds.equals(oBounds)) {
|
||||
throw new RuntimeException("Bounds differ [tl != outline]");
|
||||
}
|
||||
}
|
||||
}
|
||||
316
test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java
Normal file
316
test/jdk/java/awt/font/TextLayout/TextLayoutConstructorTest.java
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4138921
|
||||
* @summary Confirm constructor behavior for various edge cases.
|
||||
*/
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TextLayoutConstructorTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testFontConstructor();
|
||||
testMapConstructor();
|
||||
testIteratorConstructor();
|
||||
}
|
||||
|
||||
private static void testFontConstructor() {
|
||||
|
||||
// new TextLayout(String, Font, FontRenderContext)
|
||||
|
||||
Font font = new Font(Font.DIALOG, Font.PLAIN, 20);
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
|
||||
assertThrows(() -> new TextLayout(null, font, frc),
|
||||
IllegalArgumentException.class,
|
||||
"Null string passed to TextLayout constructor.");
|
||||
|
||||
assertThrows(() -> new TextLayout("test", (Font) null, frc),
|
||||
IllegalArgumentException.class,
|
||||
"Null font passed to TextLayout constructor.");
|
||||
|
||||
assertThrows(() -> new TextLayout("test", font, null),
|
||||
IllegalArgumentException.class,
|
||||
"Null font render context passed to TextLayout constructor.");
|
||||
|
||||
Function< String, TextLayout > creator = (s) -> new TextLayout(s, font, frc);
|
||||
assertEmptyTextLayoutBehavior(creator);
|
||||
}
|
||||
|
||||
private static void testMapConstructor() {
|
||||
|
||||
// new TextLayout(String, Map, FontRenderContext)
|
||||
|
||||
Map< TextAttribute, Object > attributes = Map.of(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
|
||||
assertThrows(() -> new TextLayout(null, attributes, frc),
|
||||
IllegalArgumentException.class,
|
||||
"Null string passed to TextLayout constructor.");
|
||||
|
||||
assertThrows(() -> new TextLayout("test", (Map) null, frc),
|
||||
IllegalArgumentException.class,
|
||||
"Null map passed to TextLayout constructor.");
|
||||
|
||||
assertThrows(() -> new TextLayout("test", attributes, null),
|
||||
IllegalArgumentException.class,
|
||||
"Null font render context passed to TextLayout constructor.");
|
||||
|
||||
Function< String, TextLayout > creator = (s) -> new TextLayout(s, attributes, frc);
|
||||
assertEmptyTextLayoutBehavior(creator);
|
||||
}
|
||||
|
||||
private static void testIteratorConstructor() {
|
||||
|
||||
// new TextLayout(AttributedCharacterIterator, FontRenderContext)
|
||||
|
||||
Map< TextAttribute, Object > attributes = Map.of();
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
|
||||
assertThrows(() -> new TextLayout(null, frc),
|
||||
IllegalArgumentException.class,
|
||||
"Null iterator passed to TextLayout constructor.");
|
||||
|
||||
AttributedCharacterIterator it1 = new AttributedString("test", attributes).getIterator();
|
||||
assertThrows(() -> new TextLayout(it1, null),
|
||||
IllegalArgumentException.class,
|
||||
"Null font render context passed to TextLayout constructor.");
|
||||
|
||||
Function< String, TextLayout > creator = (s) -> {
|
||||
AttributedCharacterIterator it2 = new AttributedString(s, attributes).getIterator();
|
||||
return new TextLayout(it2, frc);
|
||||
};
|
||||
assertEmptyTextLayoutBehavior(creator);
|
||||
}
|
||||
|
||||
private static void assertEmptyTextLayoutBehavior(Function< String, TextLayout > creator) {
|
||||
|
||||
TextLayout tl = creator.apply("");
|
||||
TextLayout ref = creator.apply(" "); // space
|
||||
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||
Rectangle zero = new Rectangle(0, 0, 0, 0);
|
||||
Rectangle2D.Float zero2D = new Rectangle2D.Float(0, 0, 0, 0);
|
||||
Rectangle2D.Float oneTwo = new Rectangle2D.Float(1, 2, 0, 0);
|
||||
Rectangle2D.Float kilo = new Rectangle2D.Float(0, 0, 1000, 1000);
|
||||
AffineTransform identity = new AffineTransform();
|
||||
TextLayout.CaretPolicy policy = new TextLayout.CaretPolicy();
|
||||
TextHitInfo start = TextHitInfo.trailing(-1);
|
||||
TextHitInfo end = TextHitInfo.leading(0);
|
||||
|
||||
assertEqual(0, tl.getJustifiedLayout(100).getAdvance(), "justified advance");
|
||||
assertEqual(0, tl.getBaseline(), "baseline");
|
||||
|
||||
float[] offsets = tl.getBaselineOffsets();
|
||||
float[] refOffsets = ref.getBaselineOffsets();
|
||||
assertEqual(3, offsets.length, "baseline offsets");
|
||||
assertEqual(refOffsets[0], offsets[0], "baseline offset 1");
|
||||
assertEqual(refOffsets[1], offsets[1], "baseline offset 2");
|
||||
assertEqual(refOffsets[2], offsets[2], "baseline offset 3");
|
||||
|
||||
assertEqual(0, tl.getAdvance(), "advance");
|
||||
assertEqual(0, tl.getVisibleAdvance(), "visible advance");
|
||||
assertEqual(ref.getAscent(), tl.getAscent(), "ascent");
|
||||
assertEqual(ref.getDescent(), tl.getDescent(), "descent");
|
||||
assertEqual(ref.getLeading(), tl.getLeading(), "leading");
|
||||
assertEqual(zero2D, tl.getBounds(), "bounds");
|
||||
assertEqual(zero2D, tl.getPixelBounds(frc, 0, 0), "pixel bounds 1");
|
||||
assertEqual(oneTwo, tl.getPixelBounds(frc, 1, 2), "pixel bounds 2");
|
||||
assertEqual(true, tl.isLeftToRight(), "left to right");
|
||||
assertEqual(false, tl.isVertical(), "is vertical");
|
||||
assertEqual(0, tl.getCharacterCount(), "character count");
|
||||
|
||||
float[] caretInfo = tl.getCaretInfo(start, kilo);
|
||||
float[] refCaretInfo = ref.getCaretInfo(start, kilo);
|
||||
assertEqual(6, caretInfo.length, "caret info length 1");
|
||||
assertEqual(refCaretInfo[0], caretInfo[0], "first caret info 1");
|
||||
assertEqual(refCaretInfo[1], caretInfo[1], "second caret info 1");
|
||||
assertEqual(refCaretInfo[2], caretInfo[2], "third caret info 1");
|
||||
assertEqual(refCaretInfo[3], caretInfo[3], "fourth caret info 1");
|
||||
assertEqual(refCaretInfo[4], caretInfo[4], "fifth caret info 1");
|
||||
assertEqual(refCaretInfo[5], caretInfo[5], "sixth caret info 1");
|
||||
|
||||
float[] caretInfo2 = tl.getCaretInfo(start);
|
||||
float[] refCaretInfo2 = ref.getCaretInfo(start);
|
||||
assertEqual(6, caretInfo2.length, "caret info length 2");
|
||||
assertEqual(refCaretInfo2[0], caretInfo2[0], "first caret info 2");
|
||||
assertEqual(refCaretInfo2[1], caretInfo2[1], "second caret info 2");
|
||||
assertEqual(refCaretInfo2[2], caretInfo2[2], "third caret info 2");
|
||||
assertEqual(refCaretInfo2[3], caretInfo2[3], "fourth caret info 2");
|
||||
assertEqual(refCaretInfo2[4], caretInfo2[4], "fifth caret info 2");
|
||||
assertEqual(refCaretInfo2[5], caretInfo2[5], "sixth caret info 2");
|
||||
|
||||
assertEqual(null, tl.getNextRightHit(start), "next right hit 1");
|
||||
assertEqual(null, tl.getNextRightHit(end), "next right hit 2");
|
||||
assertEqual(null, tl.getNextRightHit(0, policy), "next right hit 3");
|
||||
assertEqual(null, tl.getNextRightHit(0), "next right hit 4");
|
||||
assertEqual(null, tl.getNextLeftHit(start), "next left hit 1");
|
||||
assertEqual(null, tl.getNextLeftHit(end), "next left hit 2");
|
||||
assertEqual(null, tl.getNextLeftHit(0, policy), "next left hit 3");
|
||||
assertEqual(null, tl.getNextLeftHit(0), "next left hit 4");
|
||||
assertEqual(end, tl.getVisualOtherHit(start), "visual other hit");
|
||||
|
||||
Shape caretShape = tl.getCaretShape(start, kilo);
|
||||
Shape refCaretShape = ref.getCaretShape(start, kilo);
|
||||
assertEqual(refCaretShape.getBounds(), caretShape.getBounds(), "caret shape 1");
|
||||
|
||||
Shape caretShape2 = tl.getCaretShape(start);
|
||||
Shape refCaretShape2 = ref.getCaretShape(start);
|
||||
assertEqual(refCaretShape2.getBounds(), caretShape2.getBounds(), "caret shape 2");
|
||||
|
||||
assertEqual(0, tl.getCharacterLevel(0), "character level");
|
||||
|
||||
Shape[] caretShapes = tl.getCaretShapes(0, kilo, policy);
|
||||
Shape[] refCaretShapes = ref.getCaretShapes(0, kilo, policy);
|
||||
assertEqual(2, caretShapes.length, "caret shapes length 1");
|
||||
assertEqual(refCaretShapes[0].getBounds(), caretShapes[0].getBounds(), "caret shapes strong 1");
|
||||
assertEqual(refCaretShapes[1], caretShapes[1], "caret shapes weak 1");
|
||||
assertEqual(null, caretShapes[1], "caret shapes weak 1");
|
||||
|
||||
Shape[] caretShapes2 = tl.getCaretShapes(0, kilo);
|
||||
Shape[] refCaretShapes2 = ref.getCaretShapes(0, kilo);
|
||||
assertEqual(2, caretShapes2.length, "caret shapes length 2");
|
||||
assertEqual(refCaretShapes2[0].getBounds(), caretShapes2[0].getBounds(), "caret shapes strong 2");
|
||||
assertEqual(refCaretShapes2[1], caretShapes2[1], "caret shapes weak 2");
|
||||
assertEqual(null, caretShapes2[1], "caret shapes weak 2");
|
||||
|
||||
Shape[] caretShapes3 = tl.getCaretShapes(0);
|
||||
Shape[] refCaretShapes3 = ref.getCaretShapes(0);
|
||||
assertEqual(2, caretShapes3.length, "caret shapes length 3");
|
||||
assertEqual(refCaretShapes3[0].getBounds(), caretShapes3[0].getBounds(), "caret shapes strong 3");
|
||||
assertEqual(refCaretShapes3[1], caretShapes3[1], "caret shapes weak 3");
|
||||
assertEqual(null, caretShapes3[1], "caret shapes weak 3");
|
||||
|
||||
assertEqual(0, tl.getLogicalRangesForVisualSelection(start, start).length, "logical ranges for visual selection");
|
||||
assertEqual(zero2D, tl.getVisualHighlightShape(start, start, kilo).getBounds(), "visual highlight shape 1");
|
||||
assertEqual(zero2D, tl.getVisualHighlightShape(start, start).getBounds(), "visual highlight shape 2");
|
||||
assertEqual(zero, tl.getLogicalHighlightShape(0, 0, kilo).getBounds(), "logical highlight shape 1");
|
||||
assertEqual(zero, tl.getLogicalHighlightShape(0, 0).getBounds(), "logical highlight shape 2");
|
||||
assertEqual(zero, tl.getBlackBoxBounds(0, 0).getBounds(), "black box bounds");
|
||||
|
||||
TextHitInfo hit = tl.hitTestChar(0, 0);
|
||||
assertEqual(-1, hit.getCharIndex(), "hit test char index 1");
|
||||
assertEqual(false, hit.isLeadingEdge(), "hit test leading edge 1");
|
||||
|
||||
TextHitInfo hit2 = tl.hitTestChar(0, 0, kilo);
|
||||
assertEqual(-1, hit2.getCharIndex(), "hit test char index 2");
|
||||
assertEqual(false, hit2.isLeadingEdge(), "hit test leading edge 2");
|
||||
|
||||
assertEqual(false, tl.equals(creator.apply("")), "equals");
|
||||
assertEqual(false, tl.toString().isEmpty(), "to string");
|
||||
assertDoesNotDraw(tl);
|
||||
assertEqual(zero2D, tl.getOutline(identity).getBounds(), "outline");
|
||||
assertEqual(null, tl.getLayoutPath(), "layout path");
|
||||
|
||||
Point2D.Float point = new Point2D.Float(7, 7);
|
||||
tl.hitToPoint(start, point);
|
||||
assertEqual(0, point.x, "hit to point x");
|
||||
assertEqual(0, point.y, "hit to point y");
|
||||
}
|
||||
|
||||
private static void assertEqual(int expected, int actual, String name) {
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertEqual(float expected, float actual, String name) {
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertEqual(boolean expected, boolean actual, String name) {
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertEqual(Object expected, Object actual, String name) {
|
||||
if (!Objects.equals(expected, actual)) {
|
||||
throw new RuntimeException("Expected " + name + " = " + expected + ", but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertThrows(Runnable r, Class< ? > type, String message) {
|
||||
Class< ? > actualType;
|
||||
String actualMessage;
|
||||
Exception actualException;
|
||||
try {
|
||||
r.run();
|
||||
actualType = null;
|
||||
actualMessage = null;
|
||||
actualException = null;
|
||||
} catch (Exception e) {
|
||||
actualType = e.getClass();
|
||||
actualMessage = e.getMessage();
|
||||
actualException = e;
|
||||
}
|
||||
if (!Objects.equals(type, actualType)) {
|
||||
throw new RuntimeException(type + " != " + actualType, actualException);
|
||||
}
|
||||
if (!Objects.equals(message, actualMessage)) {
|
||||
throw new RuntimeException(message + " != " + actualMessage, actualException);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertDoesNotDraw(TextLayout layout) {
|
||||
|
||||
int w = 200;
|
||||
int h = 200;
|
||||
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
int expected = image.getRGB(0, 0);
|
||||
|
||||
layout.draw(g2d, w / 2f, h / 2f); // should not actually draw anything
|
||||
|
||||
int[] rowPixels = new int[w];
|
||||
for (int y = 0; y < h; y++) {
|
||||
image.getRGB(0, y, w, 1, rowPixels, 0, w);
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (rowPixels[x] != expected) {
|
||||
throw new RuntimeException(
|
||||
"pixel (" + x + ", " + y +"): " + expected + " != " + rowPixels[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
test/jdk/java/awt/font/TextLayout/TextLayoutEqualsTest.java
Normal file
55
test/jdk/java/awt/font/TextLayout/TextLayoutEqualsTest.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4497648
|
||||
* @summary Test equals methods on TextLayout
|
||||
*/
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextLayout;
|
||||
|
||||
public class TextLayoutEqualsTest {
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
String text = "hello world";
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
TextLayout tl1 = new TextLayout(text, font, frc);
|
||||
TextLayout tl2 = new TextLayout(text, font, frc);
|
||||
if (tl1.equals(tl2) ||
|
||||
tl2.equals(tl1) ||
|
||||
tl1.equals((Object)tl2) ||
|
||||
tl2.equals((Object)tl1))
|
||||
{
|
||||
throw new RuntimeException("Equal TextLayouts");
|
||||
}
|
||||
if (!tl1.equals(tl1) ||
|
||||
!tl1.equals((Object)tl1))
|
||||
{
|
||||
throw new RuntimeException("Non-Equal TextLayouts");
|
||||
}
|
||||
}
|
||||
}
|
||||
88
test/jdk/java/awt/font/TextLayout/UnderlinePositionTest.java
Normal file
88
test/jdk/java/awt/font/TextLayout/UnderlinePositionTest.java
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary verify outline and stroking of underline match.
|
||||
* @bug 6751616
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
|
||||
public class UnderlinePositionTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BufferedImage bi =
|
||||
new BufferedImage(600, 150, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = bi.createGraphics();
|
||||
g2d.setColor(Color.white);
|
||||
g2d.fillRect(0, 0, 600, 150);
|
||||
|
||||
float x = 10;
|
||||
float y = 90;
|
||||
Map map = new HashMap();
|
||||
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||
map.put(TextAttribute.SIZE, new Float(80));
|
||||
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
|
||||
// Use all spaces for the text so we know we are dealing
|
||||
// only with pixels from the underline.
|
||||
String text = " ";
|
||||
TextLayout tl = new TextLayout(text, map, frc);
|
||||
Shape outline = tl.getOutline(null);
|
||||
Rectangle2D bounds = outline.getBounds();
|
||||
|
||||
g2d.translate(x, y);
|
||||
g2d.setColor(Color.RED);
|
||||
tl.draw(g2d, 0, 0);
|
||||
|
||||
/* By getting the outline, then its bounds, then filling
|
||||
* according to the same pixelisation rules, this ought to
|
||||
* match the position of the original underline. If any
|
||||
* red pixels are left, then the test will fail.
|
||||
*/
|
||||
g2d.setColor(Color.BLUE);
|
||||
g2d.fill(bounds);
|
||||
g2d.dispose();
|
||||
|
||||
checkBI(bi, Color.RED);
|
||||
}
|
||||
|
||||
static void checkBI(BufferedImage bi, Color badColor) {
|
||||
int badrgb = badColor.getRGB();
|
||||
int w = bi.getWidth(null);
|
||||
int h = bi.getHeight(null);
|
||||
for (int x=0; x<w; x++) {
|
||||
for (int y=0; y<h; y++) {
|
||||
int col = bi.getRGB(x, y);
|
||||
if (col == badrgb) {
|
||||
throw new RuntimeException("Got " + col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
test/jdk/java/awt/font/TextLayout/VariationSelectorTest.java
Normal file
65
test/jdk/java/awt/font/TextLayout/VariationSelectorTest.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* @test
|
||||
* @summary Verify two identical 'a's are rendered
|
||||
* @bug 8187100
|
||||
* @ignore Requires a special font installed.
|
||||
*/
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
|
||||
public class VariationSelectorTest {
|
||||
// A font supporting Unicode variation selectors is required
|
||||
// At least DejaVu 2.20 from 2007
|
||||
private static final Font FONT = new Font("DejaVu Sans", Font.PLAIN, 12);
|
||||
|
||||
public static void main(String[] args) {
|
||||
final String fontName = FONT.getFontName();
|
||||
if (!fontName.equals("DejaVuSans")) {
|
||||
System.err.println("*** Warning: Font DejaVuSans not installed.");
|
||||
System.err.println("*** Using font: " + fontName);
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame frame = new JFrame();
|
||||
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
frame.add(new MyComponent());
|
||||
frame.setSize(200, 200);
|
||||
frame.setVisible(true);
|
||||
frame.setLocationRelativeTo(null);
|
||||
});
|
||||
}
|
||||
|
||||
private static class MyComponent extends JComponent {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
FontRenderContext frc = g2d.getFontRenderContext();
|
||||
String text = "a";
|
||||
GlyphVector gv = FONT.layoutGlyphVector(
|
||||
frc, text.toCharArray(), 0, text.length(),
|
||||
Font.LAYOUT_LEFT_TO_RIGHT);
|
||||
System.out.println("'a'=" + gv.getNumGlyphs());
|
||||
g2d.drawString("=" + gv.getNumGlyphs() + " ('a')", 100, 50);
|
||||
g2d.drawGlyphVector(gv, 80, 50);
|
||||
String text2 = "a\ufe00";
|
||||
GlyphVector gv2 = FONT.layoutGlyphVector(
|
||||
frc, text2.toCharArray(), 0, text2.length(),
|
||||
Font.LAYOUT_LEFT_TO_RIGHT);
|
||||
g2d.drawGlyphVector(gv2, 80, 100);
|
||||
System.out.println("'a'+VS=" + gv2.getNumGlyphs());
|
||||
g2d.drawString("=" + gv2.getNumGlyphs() + " ('a'+VS)", 100, 100);
|
||||
if ((gv.getNumGlyphs() == 1) && (gv2.getNumGlyphs() == 1)) {
|
||||
System.out.println("PASS");
|
||||
g2d.drawString("PASS", 10, 15);
|
||||
} else {
|
||||
System.err.println("FAIL");
|
||||
g2d.drawString("FAIL", 10, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
test/jdk/java/awt/font/TextLayout/VisibleAdvance.java
Normal file
107
test/jdk/java/awt/font/TextLayout/VisibleAdvance.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2008, 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.
|
||||
*/
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.*;
|
||||
import java.awt.geom.*;
|
||||
import java.text.*;
|
||||
|
||||
/* @test
|
||||
* @summary verify TextLine advance
|
||||
* @bug 6582460 8164818
|
||||
*/
|
||||
|
||||
/*
|
||||
Sample correct output:
|
||||
Left-to-right (One style): Advance = 127.30078, Visible advance = 118.30078
|
||||
Right-to-left (One style): Advance = 127.30078, Visible advance = 118.30078
|
||||
Left-to-right (Multiple styles): Advance = 127.30078, Visible advance = 118.30078
|
||||
Right-to-left (Multiple styles): Advance = 127.30078, Visible advance = 118.30078
|
||||
*/
|
||||
|
||||
public class VisibleAdvance
|
||||
{
|
||||
public static void main (String [] args)
|
||||
{
|
||||
System.out.println ("java.version = " + System.getProperty ("java.version"));
|
||||
|
||||
float advances[] = null;
|
||||
advances = showAndCalculateAdvance ("Left-to-right (One style): ", getString (TextAttribute.RUN_DIRECTION_LTR, false), advances);
|
||||
advances = showAndCalculateAdvance ("Right-to-left (One style): ", getString (TextAttribute.RUN_DIRECTION_RTL, false), advances);
|
||||
|
||||
advances = showAndCalculateAdvance ("Left-to-right (Multiple styles): ", getString (TextAttribute.RUN_DIRECTION_LTR, true), advances);
|
||||
advances = showAndCalculateAdvance ("Right-to-left (Multiple styles): ", getString (TextAttribute.RUN_DIRECTION_RTL, true), advances);
|
||||
}
|
||||
|
||||
private static final String textA = "Text with trailing ";
|
||||
private static final String textB = "spaces";
|
||||
private static final String textC = " ";
|
||||
private static final String text = textA + textB + textC;
|
||||
|
||||
private static final int startOfTextB = textA.length ();
|
||||
private static final int endOfTextB = startOfTextB + textB.length ();
|
||||
|
||||
private static final Font font = new Font ("Serif", Font.PLAIN, 12);
|
||||
|
||||
private static AttributedString getString (Boolean direction,
|
||||
boolean multipleStyles)
|
||||
{
|
||||
AttributedString as = new AttributedString (text);
|
||||
as.addAttribute (TextAttribute.FONT, font);
|
||||
as.addAttribute (TextAttribute.RUN_DIRECTION, direction);
|
||||
|
||||
if (multipleStyles)
|
||||
as.addAttribute (TextAttribute.FOREGROUND, Color.RED, startOfTextB, endOfTextB);
|
||||
|
||||
return as;
|
||||
}
|
||||
|
||||
private static FontRenderContext fontRenderContext =
|
||||
new FontRenderContext (new AffineTransform (), true, true);
|
||||
|
||||
/*
|
||||
* @param advances on input, null or float[2]. On output: { advance, visibleAdvance }
|
||||
* @param return new float array
|
||||
*/
|
||||
private static float[] showAndCalculateAdvance (String what,
|
||||
AttributedString as,
|
||||
float advances[])
|
||||
{
|
||||
TextLayout layout = new TextLayout (as.getIterator (), fontRenderContext);
|
||||
|
||||
System.out.println (what + "Advance = " + layout.getAdvance () +
|
||||
", Visible advance = " + layout.getVisibleAdvance ());
|
||||
float advance = layout.getAdvance();
|
||||
float visAdvance = layout.getVisibleAdvance();
|
||||
if(advances == null) {
|
||||
advances = new float[2];
|
||||
} else if( Float.compare(advances[0],advance)!=0 || Float.compare(advances[1],visAdvance)!=0) {
|
||||
throw new RuntimeException("MISMATCH in advance.. " + what + "Advance = " + layout.getAdvance () +
|
||||
", Visible advance = " + layout.getVisibleAdvance () + ", previous values were: ["+advances[0]+","+advances[1]+"]");
|
||||
}
|
||||
advances[0] = advance;
|
||||
advances[1] = visAdvance;
|
||||
return advances;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue