mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JRE-482 Java_sun_font_CStrike_getNativeGlyphOutline takes too much time in scrolling
Replaced glyph outlines with bounding boxes for glyph boundaries calculation for most common usages. Also, skipped unnecessary OGL flushes in OGL rendering queue
(cherry picked from commit c58dc052af48887338a38beb0c721eddca3af481)
(cherry picked from commit 7f6be7cfb907bbf1c3572b911df5690fa3039fde)
(cherry picked from commit c68913d82c0ba4b4c509179123f0a4bf7971f857)
(cherry picked from commit 9cfa04c93ad416a8177d9e7ca410850bd3ff880f)
(cherry picked from commit 0e930841704e4e98ecc0c888b144245e74218799)
(cherry picked from commit 8ffc190fbdb059d5a24842115c0bc3ade8b351b9)
(cherry picked from commit 0f7c26186a)
with fix for JBR-5300 Change source code and test files to use GPL license
This commit is contained in:
@@ -60,6 +60,11 @@ public final class CStrike extends PhysicalStrike {
|
||||
double x,
|
||||
double y);
|
||||
|
||||
private static native void getNativeGlyphOutlineBounds(long nativeStrikePtr,
|
||||
int glyphCode,
|
||||
Rectangle.Float result,
|
||||
double x, double y);
|
||||
|
||||
// returns the bounding rect for a glyph
|
||||
private static native void getNativeGlyphImageBounds(long nativeStrikePtr,
|
||||
int glyphCode,
|
||||
@@ -173,18 +178,8 @@ public final class CStrike extends PhysicalStrike {
|
||||
}
|
||||
|
||||
Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
|
||||
GeneralPath gp = getGlyphOutline(glyphCode, 0f, 0f);
|
||||
Rectangle2D r2d = gp.getBounds2D();
|
||||
Rectangle2D.Float r2df;
|
||||
if (r2d instanceof Rectangle2D.Float) {
|
||||
r2df = (Rectangle2D.Float)r2d;
|
||||
} else {
|
||||
float x = (float)r2d.getX();
|
||||
float y = (float)r2d.getY();
|
||||
float w = (float)r2d.getWidth();
|
||||
float h = (float)r2d.getHeight();
|
||||
r2df = new Rectangle2D.Float(x, y, w, h);
|
||||
}
|
||||
Rectangle2D.Float r2df = new Rectangle2D.Float();
|
||||
getNativeGlyphOutlineBounds(getNativeStrikePtr(), glyphCode, r2df, 0, 0);
|
||||
return r2df;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,6 +297,61 @@ JNI_COCOA_EXIT(env);
|
||||
return generalPath;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_font_CStrike
|
||||
* Method: getNativeGlyphOutlineBounds
|
||||
* Signature: (JILjava/awt/geom/Rectangle2D/Float;DD)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_font_CStrike_getNativeGlyphOutlineBounds
|
||||
(JNIEnv *env, jclass clazz, jlong awtStrikePtr, jint glyphCode,
|
||||
jobject result, jdouble xPos, jdouble yPos)
|
||||
{
|
||||
JNI_COCOA_ENTER(env);
|
||||
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
|
||||
AWTFont *awtfont = awtStrike->fAWTFont;
|
||||
|
||||
AWT_FONT_CLEANUP_SETUP;
|
||||
AWT_FONT_CLEANUP_CHECK(awtfont);
|
||||
|
||||
// get the right font and glyph for this "Java GlyphCode"
|
||||
CGGlyph glyph;
|
||||
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(
|
||||
awtfont, glyphCode, &glyph);
|
||||
|
||||
CGAffineTransform tx = CGAffineTransformConcat(awtStrike->fTx,
|
||||
sInverseTX);
|
||||
|
||||
CGPathRef cgPath = CTFontCreatePathForGlyph((CTFontRef) font, glyph,
|
||||
&tx);
|
||||
|
||||
CGRect bbox = CGPathGetPathBoundingBox(cgPath);
|
||||
CFRelease(font);
|
||||
CGPathRelease(cgPath);
|
||||
|
||||
if (CGRectIsNull(bbox)) {
|
||||
bbox.origin.x = 0;
|
||||
bbox.origin.y = 0;
|
||||
bbox.size.width = 0;
|
||||
bbox.size.height = 0;
|
||||
}
|
||||
|
||||
DECLARE_CLASS(sjc_Rectangle2D_Float,
|
||||
"java/awt/geom/Rectangle2D$Float");
|
||||
DECLARE_METHOD(sjr_Rectangle2DFloat_setRect,
|
||||
sjc_Rectangle2D_Float, "setRect", "(FFFF)V");
|
||||
|
||||
(*env)->CallVoidMethod(env, result, sjr_Rectangle2DFloat_setRect,
|
||||
(jfloat) (bbox.origin.x + xPos),
|
||||
(jfloat) (yPos - bbox.origin.y - bbox.size.height),
|
||||
(jfloat) bbox.size.width,
|
||||
(jfloat) bbox.size.height);
|
||||
|
||||
// Cleanup
|
||||
cleanup:
|
||||
AWT_FONT_CLEANUP_FINISH;
|
||||
|
||||
JNI_COCOA_EXIT(env);
|
||||
}
|
||||
/*
|
||||
* Class: sun_font_CStrike
|
||||
* Method: getGlyphImagePtrsNative
|
||||
|
||||
@@ -1783,9 +1783,19 @@ public class StandardGlyphVector extends GlyphVector {
|
||||
result = new Rectangle2D.Float();
|
||||
result.setRect(strike.getGlyphOutlineBounds(glyphID)); // don't mutate cached rect
|
||||
} else {
|
||||
GeneralPath gp = strike.getGlyphOutline(glyphID, 0, 0);
|
||||
gp.transform(sgv.invdtx);
|
||||
result = gp.getBounds2D();
|
||||
if (sgv.invdtx.getShearX() == 0 && sgv.invdtx.getShearY() == 0 &&
|
||||
sgv.invdtx.getScaleX() > 0 && sgv.invdtx.getScaleY() > 0) {
|
||||
final Rectangle2D.Float rect = strike.getGlyphOutlineBounds(glyphID);
|
||||
result = new Rectangle2D.Float(
|
||||
(float)(rect.x*sgv.invdtx.getScaleX() + sgv.invdtx.getTranslateX()),
|
||||
(float)(rect.y*sgv.invdtx.getScaleY() + sgv.invdtx.getTranslateY()),
|
||||
(float)(rect.width*sgv.invdtx.getScaleX()),
|
||||
(float)(rect.height*sgv.invdtx.getScaleY()));
|
||||
} else {
|
||||
GeneralPath gp = strike.getGlyphOutline(glyphID, 0, 0);
|
||||
gp.transform(sgv.invdtx);
|
||||
result = gp.getBounds2D();
|
||||
}
|
||||
}
|
||||
/* Since x is the logical advance of the glyph to this point.
|
||||
* Because of the way that Rectangle.union is specified, this
|
||||
|
||||
@@ -83,6 +83,8 @@ Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer
|
||||
return;
|
||||
}
|
||||
|
||||
if (limit == 0) return;
|
||||
|
||||
INIT_PREVIOUS_OP();
|
||||
end = b + limit;
|
||||
|
||||
|
||||
95
test/jdk/jbu/quality/text/TextMetricsTest.java
Normal file
95
test/jdk/jbu/quality/text/TextMetricsTest.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2017-2023 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.
|
||||
*/
|
||||
|
||||
package quality.text;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import quality.util.RenderUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class TextMetricsTest {
|
||||
|
||||
@Test
|
||||
public void testTextBounds() throws Exception {
|
||||
final Font font = new Font("Menlo", Font.PLAIN, 22);
|
||||
|
||||
|
||||
BufferedImage bi = RenderUtil.capture(120, 120,
|
||||
g2 -> {
|
||||
String s = "A";
|
||||
String s1 = "q";
|
||||
|
||||
g2.setFont(font);
|
||||
|
||||
FontRenderContext frc = g2.getFontRenderContext();
|
||||
Rectangle2D bnd = font.getStringBounds(s, frc);
|
||||
TextLayout textLayout = new TextLayout(s, font, frc);
|
||||
Rectangle2D bnd1 = textLayout.getBounds();
|
||||
GlyphVector gv = font.createGlyphVector(frc, s);
|
||||
Rectangle2D bnd2 = gv.getGlyphVisualBounds(0).getBounds2D();
|
||||
textLayout = new TextLayout(s1, font, frc);
|
||||
Rectangle2D bnd3 = textLayout.getBounds();
|
||||
|
||||
|
||||
g2.drawString(s, 5, 50);
|
||||
g2.draw(new Path2D.Double(bnd,
|
||||
AffineTransform.getTranslateInstance(5, 50 )));
|
||||
|
||||
g2.drawString(s, 30, 50);
|
||||
g2.draw(new Path2D.Double(bnd1,
|
||||
AffineTransform.getTranslateInstance(30, 50 )));
|
||||
|
||||
g2.drawString(s, 50, 50);
|
||||
g2.draw(new Path2D.Double(bnd2,
|
||||
AffineTransform.getTranslateInstance(50, 50 )));
|
||||
|
||||
g2.drawString(s1, 75, 50);
|
||||
g2.draw(new Path2D.Double(bnd3,
|
||||
AffineTransform.getTranslateInstance(75, 50 )));
|
||||
});
|
||||
|
||||
RenderUtil.checkImage(bi, "text", "bndtext.png");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpaceTextBounds() {
|
||||
final Font font = new Font("Menlo", Font.PLAIN, 22);
|
||||
|
||||
GlyphVector gv = font.createGlyphVector(
|
||||
new FontRenderContext(null, false, false), " ");
|
||||
Rectangle2D bnd = gv.getGlyphVisualBounds(0).getBounds2D();
|
||||
|
||||
Assert.assertTrue(bnd.getX() == 0.0 && bnd.getY() == 0.0 &&
|
||||
bnd.getWidth() == 0.0 && bnd.getHeight() == 0.0);
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/jbu/testdata/quality/text/osx_lowres_rendering/bndtext.png
vendored
Normal file
BIN
test/jdk/jbu/testdata/quality/text/osx_lowres_rendering/bndtext.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 382 B |
BIN
test/jdk/jbu/testdata/quality/text/osx_sierra_rendering/bndtext.png
vendored
Normal file
BIN
test/jdk/jbu/testdata/quality/text/osx_sierra_rendering/bndtext.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 921 B |
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/bndtext.png
vendored
Normal file
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/bndtext.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 382 B |
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/cnclcd.png
vendored
Normal file
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/cnclcd.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/lcdgray.png
vendored
Normal file
BIN
test/jdk/jbu/testdata/quality/text/osx_software_rendering/lcdgray.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Reference in New Issue
Block a user