Skip to content

Commit

Permalink
8269223: -Xcheck:jni WARNINGs working with fonts on Linux
Browse files Browse the repository at this point in the history
Reviewed-by: prr, serb
  • Loading branch information
mkartashev authored and mrserb committed Aug 23, 2021
1 parent 2ff4c01 commit 9bc0232
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 7 deletions.
20 changes: 19 additions & 1 deletion src/java.desktop/share/native/libfontmanager/freetypeScaler.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@

#include "fontscaler.h"

#define CHECK_EXCEPTION(env, describe) \
if ((*(env))->ExceptionCheck(env)) { \
if (describe) (*(env))->ExceptionDescribe(env);\
else (*(env))->ExceptionClear(env); \
}

#define ftFixed1 (FT_Fixed) (1 << 16)
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
Expand Down Expand Up @@ -97,12 +103,18 @@ void z_error(char *s) {}
/**************** Error handling utilities *****************/

static jmethodID invalidateScalerMID;
static jboolean debugFonts; // Stores the value of FontUtilities.debugFonts()

JNIEXPORT void JNICALL
Java_sun_font_FreetypeFontScaler_initIDs(
JNIEnv *env, jobject scaler, jclass FFSClass) {
invalidateScalerMID =
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");

jboolean ignoreException;
debugFonts = JNU_CallStaticMethodByName(env, &ignoreException,
"sun/font/FontUtilities",
"debugFonts", "()Z").z;
}

static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
Expand Down Expand Up @@ -137,6 +149,9 @@ static void invalidateJavaScaler(JNIEnv *env,
FTScalerInfo* scalerInfo) {
freeNativeResources(env, scalerInfo);
(*env)->CallVoidMethod(env, scaler, invalidateScalerMID);
// NB: Exceptions must not be cleared (and therefore no JNI calls
// performed) after calling this method because it intentionally
// leaves an exception pending.
}

/******************* I/O handlers ***************************/
Expand Down Expand Up @@ -187,6 +202,7 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
scalerInfo->font2D,
sunFontIDs.ttReadBlockMID,
bBuffer, offset, numBytes);
CHECK_EXCEPTION(env, debugFonts);
if (bread < 0) {
return 0;
} else {
Expand All @@ -206,7 +222,8 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
(*env)->CallObjectMethod(env, scalerInfo->font2D,
sunFontIDs.ttReadBytesMID,
offset, numBytes);
/* If there's an OutofMemoryError then byteArray will be null */
CHECK_EXCEPTION(env, debugFonts);
/* If there's an OutOfMemoryError then byteArray will be null */
if (byteArray == NULL) {
return 0;
} else {
Expand Down Expand Up @@ -239,6 +256,7 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
sunFontIDs.ttReadBlockMID,
bBuffer, offset,
scalerInfo->fontDataLength);
CHECK_EXCEPTION(env, debugFonts);
if (bread <= 0) {
return 0;
} else if ((unsigned long)bread < numBytes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,11 @@ void D3DRQ_FlushBuffer(void *pParam)

if (!JNU_IsNull(env, pFlush->runnable)) {
J2dTraceLn(J2D_TRACE_VERBOSE, " executing runnable");
JNU_CallMethodByName(env, NULL, pFlush->runnable, "run", "()V");
jboolean hasException;
JNU_CallMethodByName(env, &hasException, pFlush->runnable, "run", "()V");
if (hasException) {
J2dTraceLn(J2D_TRACE_ERROR, " exception occurred while executing runnable");
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6569,11 +6569,11 @@ JNIEXPORT void JNICALL
Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
{
TRY;
jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");
CHECK_NULL(inputEventClazz);
jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");
CHECK_NULL(getButtonDownMasksID);
jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);
jboolean ignoreException;
jintArray obj = (jintArray)JNU_CallStaticMethodByName(env, &ignoreException,
"java/awt/event/InputEvent",
"getButtonDownMasks", "()[I").l;
CHECK_NULL(obj);
jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);
CHECK_NULL(tmp);
jsize len = env->GetArrayLength(obj);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
key, jValue);
GetEnv()->DeleteLocalRef(jValue);
GetEnv()->DeleteLocalRef(key);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
Expand All @@ -764,6 +765,7 @@ void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
AwtDesktopProperties::setIntegerPropertyID,
key, (jint)value);
GetEnv()->DeleteLocalRef(key);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
Expand All @@ -775,6 +777,7 @@ void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
AwtDesktopProperties::setBooleanPropertyID,
key, value ? JNI_TRUE : JNI_FALSE);
GetEnv()->DeleteLocalRef(key);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
Expand All @@ -787,6 +790,7 @@ void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
key, GetRValue(value), GetGValue(value),
GetBValue(value));
GetEnv()->DeleteLocalRef(key);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
Expand Down Expand Up @@ -849,6 +853,7 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
key, fontName, style, pointSize);
GetEnv()->DeleteLocalRef(key);
GetEnv()->DeleteLocalRef(fontName);
(void)safe_ExceptionOccurred(GetEnv());
}
}
delete[] face;
Expand Down Expand Up @@ -896,6 +901,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
key, fontName, style, pointSize);
GetEnv()->DeleteLocalRef(key);
GetEnv()->DeleteLocalRef(fontName);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
Expand All @@ -913,6 +919,7 @@ void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventNa
key, event);
GetEnv()->DeleteLocalRef(event);
GetEnv()->DeleteLocalRef(key);
(void)safe_ExceptionOccurred(GetEnv());
}

void AwtDesktopProperties::PlayWindowsSound(LPCTSTR event) {
Expand Down
69 changes: 69 additions & 0 deletions test/jdk/java/awt/font/JNICheck/FreeTypeScalerJNICheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, JetBrains s.r.o.. 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 8269223
* @summary Verifies that -Xcheck:jni issues no warnings from freetypeScaler.c
* @library /test/lib
* @run main FreeTypeScalerJNICheck
*/
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsEnvironment;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;

public class FreeTypeScalerJNICheck {
public static void main(String[] args) throws Exception {
if (args.length > 0 && args[0].equals("runtest")) {
runTest();
} else {
ProcessBuilder pb = ProcessTools.createTestJvm("-Xcheck:jni", FreeTypeScalerJNICheck.class.getName(), "runtest");
OutputAnalyzer oa = ProcessTools.executeProcess(pb);
oa.shouldContain("Done").shouldNotContain("WARNING").shouldHaveExitValue(0);
}
}

public static void runTest() {
String families[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();

for (String ff : families)
{
Font font = new Font(ff, Font.PLAIN, 12);
Rectangle2D bounds = font.getStringBounds("test", g2d.getFontRenderContext());
g2d.setFont(font);
FontMetrics metrics = g2d.getFontMetrics(font);
System.out.println(bounds.getHeight() + metrics.getHeight()); // use bounds and metrics
}

System.out.println("Done");
}
}

1 comment on commit 9bc0232

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.