changeset 3144:93a1398d268f

S6611637: NullPointerException in sun.font.GlyphLayout$EngineRecord.init S6727719: Performance of TextLayout.getBounds() S6745225: Memory leak while drawing Attributed String S6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space. S7183251: Netbeans editor renders text wrong on JDK 7u6 build 2014-05-28 Andrew John Hughes <gnu.andrew@redhat.com> * Makefile.am: (ICEDTEA_PATCHES): Add new patches. * NEWS: Updated. * patches/openjdk/6611637-npe_in_glyphlayout.patch, * patches/openjdk/6727719-performance_of_textlayout_getbounds.patch, * patches/openjdk/6745225-memory_leak_in_attributed_string.patch, * patches/openjdk/6904962-getvisualbounds_affected_by_white_space.patch, * patches/openjdk/7183251-netbeans_renders_text_wrong.patch: Backport text layout fixes.
author Andrew John Hughes <gnu.andrew@redhat.com>
date Mon, 02 Jun 2014 14:48:27 +0100
parents 1da0a61f16a1
children 755d4509b7d6
files ChangeLog Makefile.am NEWS patches/openjdk/6611637-npe_in_glyphlayout.patch patches/openjdk/6727719-performance_of_textlayout_getbounds.patch patches/openjdk/6745225-memory_leak_in_attributed_string.patch patches/openjdk/6904962-getvisualbounds_affected_by_white_space.patch patches/openjdk/7183251-netbeans_renders_text_wrong.patch
diffstat 8 files changed, 393 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri May 23 02:08:32 2014 +0100
+++ b/ChangeLog	Mon Jun 02 14:48:27 2014 +0100
@@ -1,3 +1,15 @@
+2014-05-28  Andrew John Hughes  <gnu.andrew@redhat.com>
+
+	* Makefile.am:
+	(ICEDTEA_PATCHES): Add new patches.
+	* NEWS: Updated.
+	* patches/openjdk/6611637-npe_in_glyphlayout.patch,
+	* patches/openjdk/6727719-performance_of_textlayout_getbounds.patch,
+	* patches/openjdk/6745225-memory_leak_in_attributed_string.patch,
+	* patches/openjdk/6904962-getvisualbounds_affected_by_white_space.patch,
+	* patches/openjdk/7183251-netbeans_renders_text_wrong.patch:
+	Backport text layout fixes.
+
 2014-05-22  Andrew John Hughes  <gnu.andrew@redhat.com>
 
 	* Makefile.am:
--- a/Makefile.am	Fri May 23 02:08:32 2014 +0100
+++ b/Makefile.am	Mon Jun 02 14:48:27 2014 +0100
@@ -615,7 +615,12 @@
 	patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch \
 	patches/openjdk/8013057-detect_mmap_commit_failures.patch \
 	patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch \
-	patches/openjdk/7027300-unsync_hashmap_causes_endless_loop.patch
+	patches/openjdk/7027300-unsync_hashmap_causes_endless_loop.patch \
+	patches/openjdk/7183251-netbeans_renders_text_wrong.patch \
+	patches/openjdk/6904962-getvisualbounds_affected_by_white_space.patch \
+	patches/openjdk/6611637-npe_in_glyphlayout.patch \
+	patches/openjdk/6727719-performance_of_textlayout_getbounds.patch \
+	patches/openjdk/6745225-memory_leak_in_attributed_string.patch
 
 if WITH_RHINO
 ICEDTEA_PATCHES += \
--- a/NEWS	Fri May 23 02:08:32 2014 +0100
+++ b/NEWS	Mon Jun 02 14:48:27 2014 +0100
@@ -15,8 +15,13 @@
 New in release 1.14.0 (201X-XX-XX):
 
 * Backports
+  - S6611637: NullPointerException in sun.font.GlyphLayout$EngineRecord.init
+  - S6727719: Performance of TextLayout.getBounds()
+  - S6745225: Memory leak while drawing Attributed String
+  - S6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
   - S7027300, RH1098399: Unsynchronized HashMap access causes endless loop
   - S7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
+  - S7183251: Netbeans editor renders text wrong on JDK 7u6 build
   - S8013057: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory()
   - S8026887: Make issues due to failed large pages allocations easier to debug
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6611637-npe_in_glyphlayout.patch	Mon Jun 02 14:48:27 2014 +0100
@@ -0,0 +1,21 @@
+# HG changeset patch
+# User prr
+# Date 1211221532 25200
+#      Mon May 19 11:25:32 2008 -0700
+# Node ID 075152aa892eda98de7530b761bb347e44a58ba6
+# Parent  bf2c66511d1bf7c2a4d04b3f8bda635466abae44
+6611637: NullPointerException in sun.font.GlyphLayout$EngineRecord.init
+Reviewed-by: tdv, jgodinez
+
+diff -r bf2c66511d1b -r 075152aa892e src/share/classes/sun/font/GlyphLayout.java
+--- openjdk/jdk/src/share/classes/sun/font/GlyphLayout.java	Fri May 16 03:10:58 2008 +0400
++++ openjdk/jdk/src/share/classes/sun/font/GlyphLayout.java	Mon May 19 11:25:32 2008 -0700
+@@ -85,7 +85,7 @@
+     private GVData _gvdata;
+ 
+     // cached glyph layout data for reuse
+-    private static GlyphLayout cache;  // reusable
++    private static volatile GlyphLayout cache;  // reusable
+ 
+     private LayoutEngineFactory _lef;  // set when get is called, unset when done is called
+     private TextRecord _textRecord;    // the text we're working on, used by iterators
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6727719-performance_of_textlayout_getbounds.patch	Mon Jun 02 14:48:27 2014 +0100
@@ -0,0 +1,36 @@
+# HG changeset patch
+# User prr
+# Date 1236884509 25200
+#      Thu Mar 12 12:01:49 2009 -0700
+# Node ID 59696dfd545508d75e1cb89446fb7074fd50fdab
+# Parent  8d5144dfc642e4da0e5b91bd28b7fa1e4e5e133b
+6727719: Performance of TextLayout.getBounds()
+Reviewed-by: jgodinez, dougfelt
+
+diff -r 8d5144dfc642 -r 59696dfd5455 src/share/classes/sun/font/FileFontStrike.java
+--- openjdk/jdk/src/share/classes/sun/font/FileFontStrike.java	Thu Mar 05 10:56:06 2009 -0800
++++ openjdk/jdk/src/share/classes/sun/font/FileFontStrike.java	Thu Mar 12 12:01:49 2009 -0700
+@@ -842,8 +842,22 @@
+         return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode);
+     }
+ 
++    private ConcurrentHashMap<Integer, GeneralPath> outlineMap;
++
+     GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
+-        return fileFont.getGlyphOutline(pScalerContext, glyphCode, x, y);
++        if (outlineMap == null) {
++            outlineMap = new ConcurrentHashMap<Integer, GeneralPath>();
++        }
++        GeneralPath gp = (GeneralPath)outlineMap.get(glyphCode);
++        if (gp == null) {
++            gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0);
++            outlineMap.put(glyphCode, gp);
++        }
++        gp = (GeneralPath)gp.clone(); // mutable!
++        if (x != 0f || y != 0f) {
++            gp.transform(AffineTransform.getTranslateInstance(x, y));
++        }
++        return gp;
+     }
+ 
+     GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6745225-memory_leak_in_attributed_string.patch	Mon Jun 02 14:48:27 2014 +0100
@@ -0,0 +1,160 @@
+# HG changeset patch
+# User prr
+# Date 1237830054 25200
+#      Mon Mar 23 10:40:54 2009 -0700
+# Node ID e43ea83ca69672b961ed71d85ba78e112ce63877
+# Parent  467e4f25965c37adf1fbdeb93b494bd05449dbc3
+6745225: Memory leak while drawing Attributed String
+Reviewed-by: jgodinez, dougfelt
+
+diff -r 467e4f25965c -r e43ea83ca696 src/share/classes/sun/font/FileFontStrike.java
+--- openjdk/jdk/src/share/classes/sun/font/FileFontStrike.java	Fri Mar 20 20:05:22 2009 +0300
++++ openjdk/jdk/src/share/classes/sun/font/FileFontStrike.java	Mon Mar 23 10:40:54 2009 -0700
+@@ -26,6 +26,7 @@
+ package sun.font;
+ 
+ import java.lang.ref.SoftReference;
++import java.lang.ref.WeakReference;
+ import java.awt.Font;
+ import java.awt.GraphicsEnvironment;
+ import java.awt.Rectangle;
+@@ -842,15 +843,29 @@
+         return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode);
+     }
+ 
+-    private ConcurrentHashMap<Integer, GeneralPath> outlineMap;
++    private
++        WeakReference<ConcurrentHashMap<Integer,GeneralPath>> outlineMapRef;
+ 
+     GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
+-        if (outlineMap == null) {
+-            outlineMap = new ConcurrentHashMap<Integer, GeneralPath>();
++
++        GeneralPath gp = null;
++        ConcurrentHashMap<Integer, GeneralPath> outlineMap = null;
++
++        if (outlineMapRef != null) {
++            outlineMap = outlineMapRef.get();
++            if (outlineMap != null) {
++                gp = (GeneralPath)outlineMap.get(glyphCode);
++            }
+         }
+-        GeneralPath gp = (GeneralPath)outlineMap.get(glyphCode);
++
+         if (gp == null) {
+             gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0);
++            if (outlineMap == null) {
++                outlineMap = new ConcurrentHashMap<Integer, GeneralPath>();
++                outlineMapRef =
++                   new WeakReference
++                       <ConcurrentHashMap<Integer,GeneralPath>>(outlineMap);
++            }
+             outlineMap.put(glyphCode, gp);
+         }
+         gp = (GeneralPath)gp.clone(); // mutable!
+diff -r 467e4f25965c -r e43ea83ca696 src/share/classes/sun/font/GlyphLayout.java
+--- openjdk/jdk/src/share/classes/sun/font/GlyphLayout.java	Fri Mar 20 20:05:22 2009 +0300
++++ openjdk/jdk/src/share/classes/sun/font/GlyphLayout.java	Mon Mar 23 10:40:54 2009 -0700
+@@ -338,6 +338,8 @@
+                     cache = new ConcurrentHashMap<SDKey, SDCache>(10);
+                     cacheRef = new
+                        SoftReference<ConcurrentHashMap<SDKey, SDCache>>(cache);
++                } else if (cache.size() >= 512) {
++                    cache.clear();
+                 }
+                 cache.put(key, res);
+             }
+diff -r 467e4f25965c -r e43ea83ca696 test/java/awt/font/LineBreakMeasurer/FRCTest.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/java/awt/font/LineBreakMeasurer/FRCTest.java	Mon Mar 23 10:40:54 2009 -0700
+@@ -0,0 +1,90 @@
++/*
++ * Copyright 2008-9 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/*
++ * @test
++ * @bug 6448405 6519513 6745225
++ * @summary static HashMap cache in LineBreakMeasurer can grow wihout bounds
++ * @run main/othervm/timeout=600 -client -Xms16m -Xmx16m FRCTest
++ */
++import java.awt.*;
++import java.awt.image.*;
++import java.awt.font.*;
++import java.awt.geom.*;
++import java.text.*;
++import java.util.Hashtable;
++
++public class FRCTest {
++
++    static AttributedString vanGogh = new AttributedString(
++        "Many people believe that Vincent van Gogh painted his best works " +
++        "during the two-year period he spent in Provence. Here is where he " +
++        "painted The Starry Night--which some consider to be his greatest " +
++        "work of all. However, as his artistic brilliance reached new " +
++        "heights in Provence, his physical and mental health plummeted. ",
++        new Hashtable());
++
++    public static void main(String[] args) {
++
++        // First test the behaviour of Graphics2D.getFontRenderContext();
++        BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
++        Graphics2D g2d = bi.createGraphics();
++        AffineTransform g2dTx = new AffineTransform(2,0,2,0,1,1);
++        g2d.setTransform(g2dTx);
++        AffineTransform frcTx = g2d.getFontRenderContext().getTransform();
++        AffineTransform frcExpected = new AffineTransform(2,0,2,0,0,0);
++        if (!frcTx.equals(frcExpected)) {
++            throw new RuntimeException("FRC Tx may have translate?");
++        }
++
++        // Now test that using different translates with LBM is OK
++        // This test doesn't prove a lot since showing a leak really
++        // requires a basher test that can run for a long time.
++        for (int x=0;x<100;x++) {
++            for (int y=0;y<100;y++) {
++                AttributedCharacterIterator aci = vanGogh.getIterator();
++                AffineTransform tx = AffineTransform.getTranslateInstance(x, y);
++                FontRenderContext frc = new FontRenderContext(tx, false, false);
++                LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
++                lbm.setPosition(aci.getBeginIndex());
++                while (lbm.getPosition() < aci.getEndIndex()) {
++                    lbm.nextLayout(100f);
++                }
++            }
++        }
++
++        for (int x=0;x<25;x++) {
++            for (int y=0;y<25;y++) {
++                AttributedCharacterIterator aci = vanGogh.getIterator();
++                double rot = Math.random()*.4*Math.PI - .2*Math.PI;
++                AffineTransform tx = AffineTransform.getRotateInstance(rot);
++                FontRenderContext frc = new FontRenderContext(tx, false, false);
++                LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
++                lbm.setPosition(aci.getBeginIndex());
++                while (lbm.getPosition() < aci.getEndIndex()) {
++                    lbm.nextLayout(100f);
++                }
++            }
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/6904962-getvisualbounds_affected_by_white_space.patch	Mon Jun 02 14:48:27 2014 +0100
@@ -0,0 +1,129 @@
+# HG changeset patch
+# User prr
+# Date 1259620775 28800
+#      Mon Nov 30 14:39:35 2009 -0800
+# Node ID 479c14bec7f18baa769a9f8598c1b17884487f7a
+# Parent  ba01efbf7c70428f8791ee577d98283123fc0c8a
+6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
+Reviewed-by: igor, dougfelt
+
+diff -r ba01efbf7c70 -r 479c14bec7f1 src/share/classes/sun/font/StandardGlyphVector.java
+--- openjdk/jdk/src/share/classes/sun/font/StandardGlyphVector.java	Mon Nov 09 14:23:49 2009 -0800
++++ openjdk/jdk/src/share/classes/sun/font/StandardGlyphVector.java	Mon Nov 30 14:39:35 2009 -0800
+@@ -396,12 +396,19 @@
+ 
+     // !!! not cached, assume TextLayout will cache if necessary
+     public Rectangle2D getVisualBounds() {
+-        if (glyphs.length == 0) {
+-            return new Rectangle2D.Float(0, 0, 0, 0);
++        Rectangle2D result = null;
++        for (int i = 0; i < glyphs.length; ++i) {
++            Rectangle2D glyphVB = getGlyphVisualBounds(i).getBounds2D();
++            if (!glyphVB.isEmpty()) {
++                if (result == null) {
++                    result = glyphVB;
++                } else {
++                    Rectangle2D.union(result, glyphVB, result);
++                }
++            }
+         }
+-        Rectangle2D result = getGlyphVisualBounds(0).getBounds2D();
+-        for (int i = 1; i < glyphs.length; ++i) {
+-            Rectangle2D.union(result, getGlyphVisualBounds(i).getBounds2D(), result);
++        if (result == null) {
++            result = new Rectangle2D.Float(0, 0, 0, 0);
+         }
+         return result;
+     }
+@@ -1787,8 +1794,19 @@
+                 gp.transform(sgv.invdtx);
+                 result = gp.getBounds2D();
+             }
+-            result.setRect(result.getMinX() + x + dx, result.getMinY() + y + dy,
+-                           result.getWidth(), result.getHeight());
++            /* Since x is the logical advance of the glyph to this point.
++             * Because of the way that Rectangle.union is specified, this
++             * means that subsequent unioning of a rect including that
++             * will be affected, even if the glyph is empty. So skip such
++             * cases. This alone isn't a complete solution since x==0
++             * may also not be what is wanted. The code that does the
++             * unioning also needs to be aware to ignore empty glyphs.
++             */
++            if (!result.isEmpty()) {
++                result.setRect(result.getMinX() + x + dx,
++                               result.getMinY() + y + dy,
++                               result.getWidth(), result.getHeight());
++            }
+             return result;
+         }
+ 
+diff -r ba01efbf7c70 -r 479c14bec7f1 test/java/awt/font/GlyphVector/VisualBounds.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/java/awt/font/GlyphVector/VisualBounds.java	Mon Nov 30 14:39:35 2009 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/* @test
++ * @summary leading and trailing spaces must not affect visual bounds
++ * @bug 6904962
++ */
++
++
++import java.awt.*;
++import java.awt.font.*;
++import java.awt.geom.*;
++
++public class VisualBounds {
++
++    public static void main(String args[]) {
++
++        String s1 = "a";
++        String s2 = s1+" ";
++        String s3 = " "+s1;
++        Font f = new Font("Dialog", Font.PLAIN, 12);
++        FontRenderContext frc = new FontRenderContext(null, false, false);
++        GlyphVector gv1 = f.createGlyphVector(frc, s1);
++        GlyphVector gv2 = f.createGlyphVector(frc, s2);
++        GlyphVector gv3 = f.createGlyphVector(frc, s3);
++        Rectangle2D bds1 = gv1.getVisualBounds();
++        Rectangle2D bds2 = gv2.getVisualBounds();
++        Rectangle2D bds3 = gv3.getVisualBounds();
++        GlyphVector gv4 = f.createGlyphVector(frc, " ");
++        Rectangle2D bds4 = gv4.getVisualBounds();
++        System.out.println(bds1);
++        System.out.println(bds2);
++        System.out.println(bds3);
++        System.out.println(bds4);
++
++        if (!bds1.equals(bds2)) {
++          throw new RuntimeException("Trailing space: Visual bounds differ");
++        }
++        if (bds2.getWidth() != bds3.getWidth()) {
++          throw new RuntimeException("Leading space: Visual widths differ");
++       }
++        if (!bds4.isEmpty()) {
++          throw new RuntimeException("Non empty bounds for space");
++       }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7183251-netbeans_renders_text_wrong.patch	Mon Jun 02 14:48:27 2014 +0100
@@ -0,0 +1,24 @@
+# HG changeset patch
+# User prr
+# Date 1342804653 25200
+#      Fri Jul 20 10:17:33 2012 -0700
+# Node ID 84d5cdbe7bce2caf907ec842ac7b4fa2097fb295
+# Parent  bf5bf37108c14d1d01b8a1043f9e3ff0e3727869
+7183251: Netbeans editor renders text wrong on JDK 7u6 build
+Reviewed-by: igor, jgodinez
+
+diff -r bf5bf37108c1 -r 84d5cdbe7bce src/share/classes/sun/font/SunLayoutEngine.java
+--- openjdk/jdk/src/share/classes/sun/font/SunLayoutEngine.java	Fri Jul 20 13:58:52 2012 +0400
++++ openjdk/jdk/src/share/classes/sun/font/SunLayoutEngine.java	Fri Jul 20 10:17:33 2012 -0700
+@@ -137,8 +137,9 @@
+ 
+         LayoutEngine e = (LayoutEngine)cache.get(key);
+         if (e == null) {
+-            e = new SunLayoutEngine(key.copy());
+-            cache.put(key, e);
++            LayoutEngineKey copy = key.copy();
++            e = new SunLayoutEngine(copy);
++            cache.put(copy, e);
+         }
+         return e;
+     }