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.
199 lines
7 KiB
Java
199 lines
7 KiB
Java
/*
|
|
* 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. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
*
|
|
* Copyright 1999 IBM Corp. All Rights Reserved.
|
|
*/
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Image;
|
|
import java.awt.Shape;
|
|
import java.text.AttributedString;
|
|
import java.awt.font.FontRenderContext;
|
|
import java.awt.font.GraphicAttribute;
|
|
import java.awt.font.ImageGraphicAttribute;
|
|
import java.awt.font.ShapeGraphicAttribute;
|
|
import java.awt.font.TextLayout;
|
|
import java.awt.font.TextAttribute;
|
|
import java.awt.geom.Rectangle2D;
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
/*
|
|
* @test
|
|
* @bug 4202637
|
|
* @summary This test ensures that graphics in a TextLayout are positioned correctly.
|
|
* @library /java/awt/regtesthelpers
|
|
* @build PassFailJFrame
|
|
* @run main/manual TestGraphicPlacement
|
|
*/
|
|
|
|
public class TestGraphicPlacement extends JPanel {
|
|
private static final int GRAPHIC_COUNT = 5;
|
|
private static final float BASE_SIZE = 5;
|
|
private static final boolean SHAPE = false;
|
|
private static final boolean IMAGE = true;
|
|
|
|
private final AttributedString[] strings;
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
final String INSTRUCTIONS = """
|
|
This test has text strings enclosed in boxes, in each box there is
|
|
a sequence of square graphics to the right of the text string.
|
|
|
|
This test is concerned with the placement of these graphics relative
|
|
to the text string.
|
|
|
|
Squares after 'TOP' should be placed in the top-right corner of the
|
|
box with their tops aligned to the top of the box.
|
|
|
|
Graphics after 'BOTTOM' should be placed in the bottom-right corner of its
|
|
box with their bottoms aligned to the bottom of the box.
|
|
|
|
Graphics after 'BASELINE' should have their tops (not bottoms) aligned to
|
|
the baseline of the text.
|
|
|
|
If all these are true, pass the test.""";
|
|
|
|
PassFailJFrame.builder()
|
|
.instructions(INSTRUCTIONS)
|
|
.columns(45)
|
|
.testUI(TestGraphicPlacement::new)
|
|
.build()
|
|
.awaitAndCheck();
|
|
}
|
|
|
|
public TestGraphicPlacement() {
|
|
setBackground(Color.WHITE);
|
|
|
|
strings = new AttributedString[]{
|
|
makeString(GraphicAttribute.TOP_ALIGNMENT, SHAPE),
|
|
makeString(GraphicAttribute.BOTTOM_ALIGNMENT, SHAPE),
|
|
makeString(GraphicAttribute.ROMAN_BASELINE, SHAPE),
|
|
makeString(GraphicAttribute.TOP_ALIGNMENT, IMAGE),
|
|
makeString(GraphicAttribute.BOTTOM_ALIGNMENT, IMAGE),
|
|
makeString(GraphicAttribute.ROMAN_BASELINE, IMAGE),
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public Dimension getPreferredSize() {
|
|
return new Dimension(350, 450);
|
|
}
|
|
|
|
private Image makeImage(int size) {
|
|
Image img = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
|
|
Graphics2D g2d = (Graphics2D) img.getGraphics();
|
|
g2d.setColor(Color.BLUE);
|
|
g2d.fillRect(0, 0, size, size);
|
|
g2d.setColor(Color.RED);
|
|
g2d.drawRect(0, 0, size - 1, size - 1);
|
|
return img;
|
|
}
|
|
|
|
/**
|
|
* Create an AttributedString with a descriptive word (TOP, BOTTOM,
|
|
* or BASELINE) and several graphics of varying sizes following the
|
|
* word.
|
|
*
|
|
* @param alignment the alignment of the graphics
|
|
* @param image whether to create Shape or Image graphics
|
|
*/
|
|
private AttributedString makeString(int alignment, boolean image) {
|
|
String name;
|
|
if (alignment == GraphicAttribute.TOP_ALIGNMENT) {
|
|
name = "TOP";
|
|
} else if (alignment == GraphicAttribute.BOTTOM_ALIGNMENT) {
|
|
name = "BOTTOM";
|
|
} else {
|
|
name = "BASELINE";
|
|
}
|
|
|
|
// Append the Unicode graphic replacement character to the name.
|
|
String nameWithUnicode = name.concat("\uFFFC".repeat(GRAPHIC_COUNT));
|
|
|
|
AttributedString as = new AttributedString(nameWithUnicode);
|
|
|
|
// Make the descriptive text large.
|
|
as.addAttribute(TextAttribute.SIZE, 48f, 0, name.length());
|
|
|
|
// Add the graphic attributes to the end of the AttributedString.
|
|
for (int i = 0; i < GRAPHIC_COUNT; i++) {
|
|
|
|
float size = (i + 1) * BASE_SIZE;
|
|
GraphicAttribute attribute;
|
|
|
|
if (image == IMAGE) {
|
|
Image img = makeImage((int) size);
|
|
attribute = new ImageGraphicAttribute(img, alignment);
|
|
} else {
|
|
Shape shape = new Rectangle2D.Float(0, 0, size, size);
|
|
attribute = new ShapeGraphicAttribute(shape,
|
|
alignment,
|
|
ShapeGraphicAttribute.STROKE);
|
|
}
|
|
|
|
as.addAttribute(TextAttribute.CHAR_REPLACEMENT,
|
|
attribute,
|
|
i + name.length(),
|
|
i + name.length() + 1);
|
|
}
|
|
|
|
return as;
|
|
}
|
|
|
|
/**
|
|
* Draw each AttributedString, with a bounding box enclosing
|
|
* the string.
|
|
*/
|
|
@Override
|
|
public void paint(Graphics g) {
|
|
super.paint(g);
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
FontRenderContext frc = g2d.getFontRenderContext();
|
|
|
|
final float drawX = 20;
|
|
float drawY = 20;
|
|
|
|
for (int i = 0; i < strings.length; i++) {
|
|
TextLayout layout = new TextLayout(strings[i].getIterator(), frc);
|
|
float ascent = layout.getAscent();
|
|
drawY += ascent;
|
|
|
|
Rectangle2D boundsRect = new Rectangle2D.Float(drawX,
|
|
drawY - ascent,
|
|
layout.getAdvance(),
|
|
ascent + layout.getDescent());
|
|
g2d.draw(boundsRect);
|
|
layout.draw(g2d, drawX, drawY);
|
|
drawY += layout.getDescent() + layout.getLeading();
|
|
}
|
|
}
|
|
}
|