Commit 2aad332a authored by hpi1's avatar hpi1

BD-J: use fontconfig to locate system fonts when JVM fonts are not available

Alternative would be to implement parser for jre/lib/fontconfig.properties
parent e11b6108
......@@ -89,6 +89,9 @@ AC_ARG_WITH([libxml2],
AC_ARG_WITH([freetype],
[AS_HELP_STRING([--without-freetype], [build without freetype support @<:@default=with@:>@])])
AC_ARG_WITH([fontconfig],
[AS_HELP_STRING([--without-fontconfig], [build without fontconfig support @<:@default=with@:>@])])
AC_ARG_WITH([bdj-type],
[AS_HELP_STRING([--with-bdj-type=TYPE],
[Specify the type of BD-J implementation (j2se, j2me). Default is j2se.])],
......@@ -148,6 +151,14 @@ dnl FreeType2
AS_IF([test "x$with_freetype" != "xno"], [
PKG_CHECK_MODULES([FT2], [freetype2],
[with_freetype=yes; AC_DEFINE([HAVE_FT2], 1, [Define this if you have FreeType2 library])])
dnl fontconfig support
AS_IF([test "${SYS}" != "mingw32"], [
AS_IF([test "x$with_fontconfig" != "xno"], [
PKG_CHECK_MODULES([FONTCONFIG], [fontconfig],
[with_fontconfig=yes; AC_DEFINE([HAVE_FONTCONFIG], 1, [Define this if you have fontconfig library])])
])
])
])
CC_CHECK_CFLAGS_APPEND([-Wall -Wdisabled-optimization -Wpointer-arith ]dnl
......@@ -259,6 +270,15 @@ echo " BD-J bootclasspath: $BDJ_BOOTCLASSPATH"
fi
fi
echo " Font support (freetype2): $with_freetype"
if [[ $with_freetype = "yes" ]]; then
if [[ $use_bdjava = "yes" ]]; then
if test "${SYS}" != "mingw32"; then
echo " Use system fonts (fontconfig): $with_fontconfig"
else
echo " Use system fonts: no"
fi
fi
fi
echo " Metadata support (libxml2): $with_libxml2"
echo " Build examples: $use_examples"
SET_FEATURES = -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -D_REENTRANT
SET_INCLUDES = -I$(top_srcdir) -Ifile -Ilibbluray -Ilibbluray/bdnav $(BDJAVA_CFLAGS)
AM_CFLAGS = -std=c99 $(SET_FEATURES) $(SET_INCLUDES) $(LIBXML2_CFLAGS) $(FT2_CFLAGS)
AM_CFLAGS = -std=c99 $(SET_FEATURES) $(SET_INCLUDES) $(LIBXML2_CFLAGS) $(FT2_CFLAGS) $(FONTCONFIG_CFLAGS)
EXTRA_DIST = \
libbluray/bdj/build.xml \
......@@ -121,7 +121,7 @@ endif
libbluray_la_LDFLAGS= -version-info $(LT_VERSION_INFO)
libbluray_la_LIBADD= $(LIBXML2_LIBS) $(FT2_LIBS)
libbluray_la_LIBADD= $(LIBXML2_LIBS) $(FT2_LIBS) $(FONTCONFIG_LIBS)
pkginclude_HEADERS = \
file/filesystem.h \
......
......@@ -23,15 +23,47 @@ import java.io.*;
import java.security.*;
import java.util.*;
import org.videolan.Logger;
public class BDFontMetrics extends FontMetrics {
static final long serialVersionUID = -4956160226949100590L;
private static long ftLib = 0;
private static long fcLib = 0;
private static Map fontNameMap;
private static final Logger logger = Logger.getLogger(BDFontMetrics.class.getName());
private static native long initN();
private static native void destroyN(long ftLib);
private native static String resolveFontN(String fontFamily, int fontStyle);
private native static void unloadFontConfigN();
private static void addSystemFont(String alias, int style, String family, String defaultPath) {
alias = alias + "." + style;
/* default to jre fonts, if available */
if (new File(defaultPath).exists()) {
logger.info("mapping " + alias + " (" + family + ") to " + defaultPath);
fontNameMap.put(alias, defaultPath);
return;
}
/* try fontconfig */
String path = resolveFontN(family, style);
if (path != null) {
logger.info("fontconfig: mapping " + alias + " (" + family + ") to " + path);
fontNameMap.put(alias, path);
return;
}
logger.error("Can't resolve font " + alias + ": file " + defaultPath + " does not exist");
/* useless ? font file does not exist ... */
fontNameMap.put(alias, defaultPath);
}
public synchronized static void init() {
//System.loadLibrary("bluray");
......@@ -41,7 +73,7 @@ public class BDFontMetrics extends FontMetrics {
ftLib = initN();
if (ftLib == 0) {
System.err.println("freetype library not loaded");
logger.error("freetype library not loaded");
throw new AWTError("freetype lib not loaded");
}
......@@ -52,33 +84,27 @@ public class BDFontMetrics extends FontMetrics {
}
);
File f = new File(javaHome, "lib" + File.separator + "fonts");
String dir = f.getAbsolutePath() + File.separator;
String defaultFontPath = f.getAbsolutePath() + File.separator;
final Object[][] sfd = {
{ "serif", "Arial", new String[] {"LucidaBrightRegular.ttf", "LucidaBrightDemiBold.ttf", "LucidaBrightItalic.ttf", "LucidaBrightDemiItalic.ttf"}},
{ "sansserif", "Times New Roman", new String[] {"LucidaSansRegular.ttf", "LucidaSansDemiBold.ttf", "LucidaSansOblique.ttf", "LucidaSansDemiOblique.ttf"}},
{ "monospaced", "Courier New", new String[] {"LucidaTypewriterRegular.ttf", "LucidaTypewriterBold.ttf", "LucidaTypewriterOblique.ttf", "LucidaTypewriterBoldOblique.ttf"}},
{ "dialog", "Times New Roman", new String[] {"LucidaSansRegular.ttf", "LucidaSansDemiBold.ttf", "LucidaSansOblique.ttf", "LucidaSansDemiOblique.ttf"}},
{ "dialoginput", "Courier New", new String[] {"LucidaTypewriterRegular.ttf", "LucidaTypewriterBold.ttf", "LucidaTypewriterOblique.ttf", "LucidaTypewriterBoldOblique.ttf"}},
{ "default", "Times New Roman", new String[] {"LucidaSansRegular.ttf", "LucidaSansDemiBold.ttf", "LucidaSansOblique.ttf", "LucidaSansDemiOblique.ttf"}},
};
fontNameMap = new HashMap(24);
fontNameMap.put("serif.0", dir + "LucidaBrightRegular.ttf");
fontNameMap.put("serif.1", dir + "LucidaBrightDemiBold.ttf");
fontNameMap.put("serif.2", dir + "LucidaBrightItalic.ttf");
fontNameMap.put("serif.3", dir + "LucidaBrightDemiItalic.ttf");
fontNameMap.put("sansserif.0", dir + "LucidaSansRegular.ttf");
fontNameMap.put("sansserif.1", dir + "LucidaSansDemiBold.ttf");
fontNameMap.put("sansserif.2", dir + "LucidaSansOblique.ttf");
fontNameMap.put("sansserif.3", dir + "LucidaSansDemiOblique.ttf");
fontNameMap.put("monospaced.0", dir + "LucidaTypewriterRegular.ttf");
fontNameMap.put("monospaced.1", dir + "LucidaTypewriterBold.ttf");
fontNameMap.put("monospaced.2", dir + "LucidaTypewriterOblique.ttf");
fontNameMap.put("monospaced.3", dir + "LucidaTypewriterBoldOblique.ttf");
fontNameMap.put("dialog.0", dir + "LucidaSansRegular.ttf");
fontNameMap.put("dialog.1", dir + "LucidaSansDemiBold.ttf");
fontNameMap.put("dialog.2", dir + "LucidaSansOblique.ttf");
fontNameMap.put("dialog.3", dir + "LucidaSansDemiOblique.ttf");
fontNameMap.put("dialoginput.0", dir + "LucidaTypewriterRegular.ttf");
fontNameMap.put("dialoginput.1", dir + "LucidaTypewriterBold.ttf");
fontNameMap.put("dialoginput.2", dir + "LucidaTypewriterOblique.ttf");
fontNameMap.put("dialoginput.3", dir + "LucidaTypewriterBoldOblique.ttf");
fontNameMap.put("default.0", dir + "LucidaSansRegular.ttf");
fontNameMap.put("default.1", dir + "LucidaSansDemiBold.ttf");
fontNameMap.put("default.2", dir + "LucidaSansOblique.ttf");
fontNameMap.put("default.3", dir + "LucidaSansDemiOblique.ttf");
for (int type = 0; type < sfd.length; type++) {
for (int style = 0; style < 4; style++) {
addSystemFont((String)sfd[type][0], style, (String)sfd[type][1],
defaultFontPath + ((String[])sfd[type][2])[style]);
}
}
unloadFontConfigN();
}
public synchronized static void shutdown() {
......@@ -150,7 +176,7 @@ public class BDFontMetrics extends FontMetrics {
public synchronized static boolean registerFont(File f) {
//TODO
org.videolan.Logger.unimplemented("BDFontMetrics", "registerFont");
logger.unimplemented("registerFont");
return false;
}
......
......@@ -30,6 +30,10 @@
#include FT_FREETYPE_H
#endif
#ifdef HAVE_FONTCONFIG
#include <fontconfig/fontconfig.h>
#endif
#include "java_awt_BDFontMetrics.h"
/* Disable some warnings */
......@@ -43,6 +47,112 @@
#define CPP_EXTERN
#endif
/*
* fontconfig
*/
#ifdef HAVE_FONTCONFIG
static FcConfig *getFcLib(JNIEnv * env, jclass cls)
{
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "fcLib", "J");
jlong fcLib = (*env)->GetStaticLongField (env, cls, fid);
FcConfig *lib = (FcConfig *)(intptr_t)fcLib;
if (lib) {
return lib;
}
lib = FcInitLoadConfigAndFonts();
(*env)->SetStaticLongField (env, cls, fid, (jlong)(intptr_t)lib);
if (!lib) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Loading fontconfig failed\n");
}
return lib;
}
#endif
JNIEXPORT void JNICALL
Java_java_awt_BDFontMetrics_unloadFontConfigN(JNIEnv * env, jclass cls)
{
#ifdef HAVE_FONTCONFIG
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "fcLib", "J");
jlong fcLib = (*env)->GetStaticLongField (env, cls, fid);
if (fcLib) {
FcConfig *lib = (FcConfig *)(intptr_t)fcLib;
(*env)->SetStaticLongField (env, cls, fid, 0);
FcConfigDestroy(lib);
}
#endif
}
#ifdef HAVE_FONTCONFIG
static void _fill_fc_pattern(JNIEnv *env, FcPattern *pat, jstring fontFamily, jint fontStyle)
{
const char *family = (*env)->GetStringUTFChars(env, fontFamily, NULL);
int weight = (fontStyle & 1) ? FC_WEIGHT_EXTRABOLD : FC_WEIGHT_NORMAL;
int slant = (fontStyle & 2) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN;
if (strncmp(family, "mono", 4)) { /* mono, monospace, monospaced */
FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)family);
} else {
FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)"monospace");
}
FcPatternAddBool (pat, FC_OUTLINE, FcTrue);
FcPatternAddInteger(pat, FC_SLANT, slant);
FcPatternAddInteger(pat, FC_WEIGHT, weight);
(*env)->ReleaseStringUTFChars(env, fontFamily, family);
}
#endif
JNIEXPORT jstring JNICALL
Java_java_awt_BDFontMetrics_resolveFontN(JNIEnv * env, jclass cls, jstring fontFamily, jint fontStyle)
{
jstring file = NULL;
#ifdef HAVE_FONTCONFIG
FcConfig *lib = getFcLib(env, cls);
if (lib) {
FcResult result = FcResultMatch;
FcPattern *pat, *font;
FcChar8 *filename = NULL;
pat = FcPatternCreate();
if (!pat) return NULL;
_fill_fc_pattern(env, pat, fontFamily, fontStyle);
FcDefaultSubstitute(pat);
if (!FcConfigSubstitute(lib, pat, FcMatchPattern)) {
FcPatternDestroy(pat);
return NULL;
}
font = FcFontMatch(lib, pat, &result);
FcPatternDestroy(pat);
if (!font || result == FcResultNoMatch) {
return NULL;
}
if (FcResultMatch == FcPatternGetString(font, FC_FILE, 0, &filename)) {
file = (*env)->NewStringUTF(env, (const char*)filename);
}
FcPatternDestroy(font);
}
#else
BD_DEBUG(DBG_BDJ | DBG_CRIT, "BD-J font config support not compiled in\n");
#endif
return file;
}
/*
*
*/
JNIEXPORT jlong JNICALL
Java_java_awt_BDFontMetrics_initN(JNIEnv * env, jclass cls)
{
......@@ -69,6 +179,8 @@ Java_java_awt_BDFontMetrics_destroyN(JNIEnv * env, jclass cls, jlong ftLib)
}
FT_Done_FreeType(lib);
Java_java_awt_BDFontMetrics_unloadFontConfigN(env, cls);
#endif
}
......@@ -230,6 +342,16 @@ Java_java_awt_BDFontMetrics_methods[] =
CC("(J)V"),
VC(Java_java_awt_BDFontMetrics_destroyN),
},
{
CC("resolveFontN"),
CC("(Ljava/lang/String;I)Ljava/lang/String;"),
VC(Java_java_awt_BDFontMetrics_resolveFontN),
},
{
CC("unloadFontConfigN"),
CC("()V"),
VC(Java_java_awt_BDFontMetrics_unloadFontConfigN),
},
{
CC("loadFontN"),
CC("(JLjava/lang/String;I)J"),
......
......@@ -30,6 +30,22 @@ JNIEXPORT jlong JNICALL Java_java_awt_BDFontMetrics_initN
JNIEXPORT void JNICALL Java_java_awt_BDFontMetrics_destroyN
(JNIEnv *, jclass, jlong);
/*
* Class: java_awt_BDFontMetrics
* Method: resolveFontN
* Signature: (Ljava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_java_awt_BDFontMetrics_resolveFontN
(JNIEnv *, jclass, jstring, jint);
/*
* Class: java_awt_BDFontMetrics
* Method: unloadFontConfigN
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_awt_BDFontMetrics_unloadFontConfigN
(JNIEnv *, jclass);
/*
* Class: java_awt_BDFontMetrics
* Method: loadFontN
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment