changeset 14415:5e357683237b

8261867: Backport relevant test changes & additions from JDK-8130125 Summary: Backport changes to bug6980209.java, JSplitPaneOverlapping.java, TestXEmbedServer.java, plus 3 new tests. Reviewed-by: phh, serb
author andrew
date Wed, 31 Mar 2021 22:03:54 +0000
parents 1e0a8a4669bc
children a364726474e6
files test/java/awt/EventQueue/6980209/bug6980209.java test/java/awt/Frame/NonEDT_GUI_DeadlockTest/NonEDT_GUI_Deadlock.html test/java/awt/Frame/NonEDT_GUI_DeadlockTest/NonEDT_GUI_Deadlock.java test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java test/java/awt/font/GlyphVector/TestLayoutFlags.java test/java/awt/font/Underline/UnderlineTest.java test/java/awt/xembed/server/TestXEmbedServer.java
diffstat 7 files changed, 749 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/test/java/awt/EventQueue/6980209/bug6980209.java	Tue Oct 20 12:42:21 2015 +0300
+++ b/test/java/awt/EventQueue/6980209/bug6980209.java	Wed Mar 31 22:03:54 2021 +0000
@@ -27,18 +27,17 @@
    @author Semyon Sadetsky
   */
 
-import sun.util.logging.PlatformLogger;
-
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
+import java.util.logging.Logger;
 
 public class bug6980209 implements ActionListener {
-    private final static PlatformLogger log =
-            PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport");
+    private final static Logger log =
+            Logger.getLogger("java.awt.event.WaitDispatchSupport");
     public static final int ATTEMPTS = 100;
     public static final int EVENTS = 5;
 
@@ -52,8 +51,8 @@
     public static void main(String[] args) throws Exception {
         System.out.println(
                 "PLEASE DO NOT TOUCH KEYBOARD AND MOUSE DURING THE TEST RUN!");
-        // log.setLevel(PlatformLogger.Level.FINE);
-        // log.setLevel(PlatformLogger.Level.FINEST);
+        // log.setLevel(java.util.logging.Level.FINE);
+        // log.setLevel(java.util.logging.Level.FINEST);
         try {
             SwingUtilities.invokeAndWait(new Runnable() {
                 public void run() {
@@ -238,4 +237,4 @@
         }
         log.fine("\n---TEST END---");
     }
-}
\ No newline at end of file
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Frame/NonEDT_GUI_DeadlockTest/NonEDT_GUI_Deadlock.html	Wed Mar 31 22:03:54 2021 +0000
@@ -0,0 +1,44 @@
+<html>
+<!--
+ Copyright (c) 2003, 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 4828019
+  @summary Frame/Window deadlock
+  @author yan@sparc.spb.su: area=
+  @run applet/timeout=9999 NonEDT_GUI_Deadlock.html
+  -->
+<head>
+<title>  </title>
+</head>
+<body>
+
+<h1>NonEDT_GUI_Deadlock<br>Bug ID: 4828019</h1>
+
+<p> This is an AUTOMATIC test, simply wait for completion </p>
+
+<APPLET CODE="NonEDT_GUI_Deadlock.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Frame/NonEDT_GUI_DeadlockTest/NonEDT_GUI_Deadlock.java	Wed Mar 31 22:03:54 2021 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2003, 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 4828019
+  @summary Frame/Window deadlock
+  @author yan@sparc.spb.su: area=
+  @run applet NonEDT_GUI_Deadlock.html
+*/
+
+// Note there is no @ in front of test above.  This is so that the
+//  harness will not mistake this file as a test file.  It should
+//  only see the html file as a test file. (the harness runs all
+//  valid test files, so it would run this test twice if this file
+//  were valid as well as the html file.)
+// Also, note the area= after Your Name in the author tag.  Here, you
+//  should put which functional area the test falls in.  See the
+//  AWT-core home page -> test areas and/or -> AWT team  for a list of
+//  areas.
+// Note also the 'AutomaticAppletTest.html' in the run tag.  This should
+//  be changed to the name of the test.
+
+
+/**
+ * NonEDT_GUI_Deadlock.java
+ *
+ * summary:
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.net.*;
+import java.io.*;
+
+
+//Automated tests should run as applet tests if possible because they
+// get their environments cleaned up, including AWT threads, any
+// test created threads, and any system resources used by the test
+// such as file descriptors.  (This is normally not a problem as
+// main tests usually run in a separate VM, however on some platforms
+// such as the Mac, separate VMs are not possible and non-applet
+// tests will cause problems).  Also, you don't have to worry about
+// synchronisation stuff in Applet tests they way you do in main
+// tests...
+
+
+public class NonEDT_GUI_Deadlock extends Applet
+{
+    //Declare things used in the test, like buttons and labels here
+    boolean bOK = false;
+    Thread badThread = null;
+
+    public void init()
+    {
+        //Create instructions for the user here, as well as set up
+        // the environment -- set the layout manager, add buttons,
+        // etc.
+
+
+        String[] instructions =
+        {
+            "This is an AUTOMATIC test",
+            "simply wait until it is done"
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+    }//End  init()
+
+    public void start ()
+    {
+        //Get things going.  Request focus, set size, et cetera
+
+        setSize (200,300);
+        setVisible(true);
+        validate();
+
+        final Frame theFrame = new Frame("Window test");
+        theFrame.setSize(240, 200);
+
+        Thread thKiller = new Thread() {
+           public void run() {
+              try {
+                 Thread.sleep( 9000 );
+              }catch( Exception ex ) {
+              }
+              if( !bOK ) {
+                 // oops,
+                 //Sysout.println("Deadlock!");
+                 Runtime.getRuntime().halt(0);
+              }else{
+                 //Sysout.println("Passed ok.");
+              }
+           }
+        };
+        thKiller.setName("Killer thread");
+        thKiller.start();
+        Window w = new TestWindow(theFrame);
+        theFrame.toBack();
+        theFrame.setVisible(true);
+
+        theFrame.setLayout(new FlowLayout(FlowLayout.CENTER));
+        EventQueue.invokeLater(new Runnable() {
+           public void run() {
+               bOK = true;
+           }
+        });
+
+
+
+    }// start()
+    class TestWindow extends Window implements Runnable {
+
+        TestWindow(Frame f) {
+            super(f);
+
+            //setSize(240, 75);
+            setLocation(0, 75);
+
+            show();
+            toFront();
+
+            badThread = new Thread(this);
+            badThread.setName("Bad Thread");
+            badThread.start();
+
+        }
+
+        public void paint(Graphics g) {
+            g.drawString("Deadlock or no deadlock?",20,80);
+        }
+
+        public void run() {
+
+            long ts = System.currentTimeMillis();
+
+            while (true) {
+                if ((System.currentTimeMillis()-ts)>3000) {
+                    this.setVisible( false );
+                    dispose();
+                    break;
+                }
+
+                toFront();
+                try {
+                    Thread.sleep(80);
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+
+
+    public static void main(String args[]) {
+       NonEDT_GUI_Deadlock imt = new NonEDT_GUI_Deadlock();
+       imt.init();
+       imt.start();
+    }
+
+
+}// class NonEDT_GUI_Deadlock
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        pack();
+
+        show();
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+}// TestDialog  class
--- a/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java	Tue Oct 20 12:42:21 2015 +0300
+++ b/test/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java	Wed Mar 31 22:03:54 2021 +0000
@@ -40,7 +40,8 @@
 
 /**
  * AWT/Swing overlapping test for {@link javax.swing.JSplitPane } component.
- * <p>This test creates puts heavyweight and lightweight components into different panels and test if splitter image and components itself are drawn correctly.
+ * <p>This test puts heavyweight and lightweight components into different
+ * panels and test if splitter image and components itself are drawn correctly.
  * <p>See base class for test info.
  */
 /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/font/GlyphVector/TestLayoutFlags.java	Wed Mar 31 22:03:54 2021 +0000
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2004, 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 4328745 5090704
+   @summary exercise getLayoutFlags, getGlyphCharIndex, getGlyphCharIndices
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+
+public class TestLayoutFlags {
+
+    static public void main(String[] args) {
+        new TestLayoutFlags().runTest();
+    }
+
+    void runTest() {
+
+        Font font = new Font("Lucida Sans", Font.PLAIN, 24);
+
+        String latin1 = "This is a latin1 string"; // none
+        String hebrew = "\u05d0\u05d1\u05d2\u05d3"; // rtl
+        String arabic = "\u0646\u0644\u0622\u0646"; // rtl + mc/g
+        String hindi = "\u0939\u093f\u0923\u094d\u0921\u0940"; // ltr + reorder
+        //      String tamil = "\u0b9c\u0bcb"; // ltr + mg/c + split
+
+        FontRenderContext frc = new FontRenderContext(null, true, true);
+
+        // get glyph char indices needs to initializes layoutFlags before use (5090704)
+        {
+          GlyphVector gv = font.createGlyphVector(frc, "abcde");
+          int ix = gv.getGlyphCharIndex(0);
+          if (ix != 0) {
+            throw new Error("glyph 0 incorrectly mapped to char " + ix);
+          }
+          int[] ixs = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+          for (int i = 0; i < ixs.length; ++i) {
+            if (ixs[i] != i) {
+              throw new Error("glyph " + i + " incorrectly mapped to char " + ixs[i]);
+            }
+          }
+        }
+
+        GlyphVector latinGV = makeGlyphVector("Lucida Sans", frc, latin1, false, 1 /* ScriptRun.LATIN */);
+        GlyphVector hebrewGV = makeGlyphVector("Lucida Sans", frc, hebrew, true, 5 /* ScriptRun.HEBREW */);
+        GlyphVector arabicGV = makeGlyphVector("Lucida Sans", frc, arabic, true, 6 /* ScriptRun.ARABIC */);
+        GlyphVector hindiGV = makeGlyphVector("Lucida Sans", frc, hindi, false, 7 /* ScriptRun.DEVANAGARI */);
+        //      GlyphVector tamilGV = makeGlyphVector("Devanagari MT for IBM", frc, tamil, false, 12 /* ScriptRun.TAMIL */);
+
+        GlyphVector latinPos = font.createGlyphVector(frc, latin1);
+        Point2D pt = latinPos.getGlyphPosition(0);
+        pt.setLocation(pt.getX(), pt.getY() + 1.0);
+        latinPos.setGlyphPosition(0, pt);
+
+        GlyphVector latinTrans = font.createGlyphVector(frc, latin1);
+        latinTrans.setGlyphTransform(0, AffineTransform.getRotateInstance(.15));
+
+        test("latin", latinGV, GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+        test("hebrew", hebrewGV, GlyphVector.FLAG_RUN_RTL |
+             GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+        test("arabic", arabicGV, GlyphVector.FLAG_RUN_RTL |
+             GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+        test("hindi", hindiGV, GlyphVector.FLAG_COMPLEX_GLYPHS |
+             GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+        //      test("tamil", tamilGV, GlyphVector.FLAG_COMPLEX_GLYPHS);
+        test("pos", latinPos, GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+        test("trans", latinTrans, GlyphVector.FLAG_HAS_TRANSFORMS);
+    }
+
+    GlyphVector makeGlyphVector(String fontname, FontRenderContext frc, String text, boolean rtl, int script) {
+        Font font = new Font(fontname, Font.PLAIN, 14);
+        System.out.println("asking for " + fontname + " and got " + font.getFontName());
+        int flags = rtl ? 1 : 0;
+        return font.layoutGlyphVector(frc, text.toCharArray(), 0, text.length(), flags);
+    }
+
+    void test(String name, GlyphVector gv, int expectedFlags) {
+        expectedFlags &= gv.FLAG_MASK;
+        int computedFlags = computeFlags(gv) & gv.FLAG_MASK;
+        int actualFlags = gv.getLayoutFlags() & gv.FLAG_MASK;
+
+        System.out.println("\n*** " + name + " ***");
+        System.out.println(" test flags");
+        System.out.print("expected ");
+        printFlags(expectedFlags);
+        System.out.print("computed ");
+        printFlags(computedFlags);
+        System.out.print("  actual ");
+        printFlags(actualFlags);
+
+        if (expectedFlags != actualFlags) {
+            throw new Error("layout flags in test: " + name +
+                            " expected: " + Integer.toHexString(expectedFlags) +
+                            " but got: " + Integer.toHexString(actualFlags));
+        }
+    }
+
+    static public void printFlags(int flags) {
+        System.out.print("flags:");
+        if ((flags & GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) != 0) {
+            System.out.print(" pos");
+        }
+        if ((flags & GlyphVector.FLAG_HAS_TRANSFORMS) != 0) {
+            System.out.print(" trans");
+        }
+        if ((flags & GlyphVector.FLAG_RUN_RTL) != 0) {
+            System.out.print(" rtl");
+        }
+        if ((flags & GlyphVector.FLAG_COMPLEX_GLYPHS) != 0) {
+            System.out.print(" complex");
+        }
+        if ((flags & GlyphVector.FLAG_MASK) == 0) {
+            System.out.print(" none");
+        }
+        System.out.println();
+    }
+
+    int computeFlags(GlyphVector gv) {
+        validateCharIndexMethods(gv);
+
+        int result = 0;
+        if (glyphsAreRTL(gv)) {
+            result |= GlyphVector.FLAG_RUN_RTL;
+        }
+        if (hasComplexGlyphs(gv)) {
+            result |= GlyphVector.FLAG_COMPLEX_GLYPHS;
+        }
+
+        return result;
+    }
+
+    /**
+     * throw an exception if getGlyphCharIndices returns a different result than
+     * you get from iterating through getGlyphCharIndex one at a time.
+     */
+    void validateCharIndexMethods(GlyphVector gv) {
+        int[] indices = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+        for (int i = 0; i < gv.getNumGlyphs(); ++i) {
+            if (gv.getGlyphCharIndex(i) != indices[i]) {
+                throw new Error("glyph index mismatch at " + i);
+            }
+        }
+    }
+
+    /**
+     * Return true if the glyph indices are pure ltr
+     */
+    boolean glyphsAreLTR(GlyphVector gv) {
+        int[] indices = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+        for (int i = 0; i < indices.length; ++i) {
+            if (indices[i] != i) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Return true if the glyph indices are pure rtl
+     */
+    boolean glyphsAreRTL(GlyphVector gv) {
+        int[] indices = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+        for (int i = 0; i < indices.length; ++i) {
+            if (indices[i] != indices.length - i - 1) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Return true if there is a local reordering (the run is not ltr or rtl).
+     * !!! We can't have mixed bidi runs in the glyphs.
+     */
+    boolean hasComplexGlyphs(GlyphVector gv) {
+        return !glyphsAreLTR(gv) && !glyphsAreRTL(gv);
+    }
+}
+
+/*
+rect getPixelBounds(frc, x, y)
+rect getGlyphPixelBounds(frc, int, x, y)
+getGlyphOutline(int index, x, y)
+getGlyphInfo()
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/font/Underline/UnderlineTest.java	Wed Mar 31 22:03:54 2021 +0000
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006, 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 6216010
+ * @summary check to see that underline thickness scales.
+ * @run main UnderlineTest
+ */
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridLayout;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.util.HashMap;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+
+public class UnderlineTest {
+    static class FontsPanel extends Container {
+        FontsPanel(Font[] fonts) {
+            setLayout(new GridLayout(0, 1));
+            for (int i = 0; i < fonts.length; ++i) {
+              add(new FontPanel(fonts[i]));
+            }
+        }
+    }
+
+    static String fps = "Stellar glyphs";
+    static Dimension fpd = new Dimension(600, 120);
+    static class FontPanel extends JComponent {
+        Font f;
+        FontPanel(Font f) {
+            this.f = f;
+            setPreferredSize(fpd);
+            setMinimumSize(fpd);
+            setMaximumSize(fpd);
+            setSize(fpd);
+        }
+
+        public void paintComponent(Graphics g) {
+            g.setColor(Color.WHITE);
+            g.fillRect(0, 0, fpd.width, fpd.height);
+
+            g.setColor(Color.RED);
+            FontRenderContext frc = ((Graphics2D)g).getFontRenderContext();
+            LineMetrics lm = f.getLineMetrics(fps, frc);
+            int h = (int)(fpd.height - 20 - lm.getAscent());
+            g.drawLine(20, h, fpd.width - 20, h);
+            h = fpd.height - 20;
+            g.drawLine(20, h, fpd.width - 20, h);
+            h = (int)(fpd.height - 20 + lm.getDescent());
+            g.drawLine(20, h, fpd.width - 20, h);
+
+            g.setColor(Color.BLACK);
+            g.setFont(f);
+            g.drawString(fps, 50, fpd.height - 20);
+        }
+    }
+
+    public static void main(String args[]) {
+        String fontName = "Lucida Sans";
+        if (args.length > 0) {
+            fontName = args[0];
+        }
+        FontRenderContext frc = new FontRenderContext(null, false, false);
+        FontRenderContext frc2 = new FontRenderContext(AffineTransform.getScaleInstance(1.5, 1.5), false, false);
+
+        Font font0 = new Font(fontName, 0, 20);
+        HashMap map = new HashMap();
+        map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+        map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+        Font font = font0.deriveFont(map);
+
+        System.out.println("Using font: " + font);
+
+        double rot = -Math.PI/4;
+        AffineTransform scrtx = AffineTransform.getRotateInstance(rot);
+        scrtx.scale(1, 2);
+
+        Font[] fonts = {
+            font.deriveFont(1f),
+            font.deriveFont(20f),
+            font.deriveFont(40f),
+            font.deriveFont(80f),
+            font.deriveFont(AffineTransform.getRotateInstance(rot)),
+            font.deriveFont(AffineTransform.getScaleInstance(1, 2)),
+            font.deriveFont(AffineTransform.getScaleInstance(2, 4)),
+            font.deriveFont(scrtx),
+        };
+
+        LineMetrics[] metrics = new LineMetrics[fonts.length * 2];
+        for (int i = 0; i < metrics.length; ++i) {
+            Font f = fonts[i % fonts.length];
+            FontRenderContext frcx = i < fonts.length ? frc : frc2;
+            metrics[i] = f.getLineMetrics("X", frcx);
+      //       dumpMetrics("Metrics for " + f.getSize2D() + " pt. font,\n  tx: " +
+      //       f.getTransform() + ",\n   frctx: " + frcx.getTransform(), metrics[i]);
+        }
+
+        // test for linear scale
+        // this seems to work, might need to get fancy to deal with last-significant-bit issues?
+        double ds1 = metrics[2].getStrikethroughOffset() - metrics[1].getStrikethroughOffset();
+        double du1 = metrics[2].getUnderlineThickness() - metrics[1].getUnderlineThickness();
+        double ds2 = metrics[3].getStrikethroughOffset() - metrics[2].getStrikethroughOffset();
+        double du2 = metrics[3].getUnderlineThickness() - metrics[2].getUnderlineThickness();
+        if (ds2 != ds1 * 2 || du2 != du1 * 2) {
+            throw new IllegalStateException("non-linear scale: " + ds1 + " / " + ds2 + ", " +
+                                            du1 + " / " + du2);
+        }
+
+        JFrame jf = new JFrame("Fonts");
+        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        jf.add(new JScrollPane(new FontsPanel(fonts)));
+        jf.pack();
+        jf.setVisible(true);
+    }
+
+    static void dumpMetrics(String header, LineMetrics lm) {
+        if (header != null) {
+            System.out.println(header);
+        }
+        System.out.println("asc: " + lm.getAscent());
+        System.out.println("dsc: " + lm.getDescent());
+        System.out.println("ulo: " + lm.getUnderlineOffset());
+        System.out.println("ult: " + lm.getUnderlineThickness());
+        System.out.println("sto: " + lm.getStrikethroughOffset());
+        System.out.println("stt: " + lm.getStrikethroughThickness());
+    }
+}
--- a/test/java/awt/xembed/server/TestXEmbedServer.java	Tue Oct 20 12:42:21 2015 +0300
+++ b/test/java/awt/xembed/server/TestXEmbedServer.java	Wed Mar 31 22:03:54 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -27,6 +27,8 @@
 import java.io.*;
 import java.util.logging.*;
 import sun.awt.WindowIDProvider;
+import sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.ComponentAccessor;
 import java.awt.dnd.*;
 import java.awt.datatransfer.*;
 
@@ -182,7 +184,8 @@
         client.setBackground(new Color(30, 220, 40));
         clientCont.add(client);
         clientCont.validate();
-        WindowIDProvider pid = (WindowIDProvider)client.getPeer();
+        final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
+        WindowIDProvider pid = (WindowIDProvider)acc.getPeer(client);
         log.fine("Added XEmbed server(Canvas) with X window ID " + pid.getWindow());
         Rectangle toFocusBounds = toFocus.getBounds();
         toFocusBounds.setLocation(toFocus.getLocationOnScreen());