[libbluray-devel] BD-J: add Win32 font resolving

hpi1 git at videolan.org
Mon Dec 1 09:17:24 CET 2014


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Mon Nov 24 13:13:08 2014 +0200| [7686436e7ed1001883ab27fca168ac4ff79dd8b2] | committer: hpi1

BD-J: add Win32 font resolving

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=7686436e7ed1001883ab27fca168ac4ff79dd8b2
---

 configure.ac                                      |    5 +-
 src/file/dirs.h                                   |    1 +
 src/file/dirs_win32.c                             |   16 ++++
 src/libbluray/bdj/native/java_awt_BDFontMetrics.c |  105 +++++++++++++++++++++
 4 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 347e15a..e90d418 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,9 @@ AS_IF([test "x$with_freetype" != "xno"], [
       PKG_CHECK_MODULES([FONTCONFIG], [fontconfig],
         [with_fontconfig=yes; AC_DEFINE([HAVE_FONTCONFIG], 1, [Define this if you have fontconfig library])])
     ])
+  ],[
+    FONTCONFIG_LIBS="-lgdi32"
+    AC_SUBST([FONTCONFIG_LIBS])
   ])
 ])
 
@@ -275,7 +278,7 @@ if [[ $use_bdjava = "yes" ]]; then
 if test "${SYS}" != "mingw32"; then
 echo "  Use system fonts (fontconfig): $with_fontconfig"
 else
-echo "  Use system fonts:              no"
+echo "  Use system fonts:              yes"
 fi
 fi
 fi
diff --git a/src/file/dirs.h b/src/file/dirs.h
index 304701b..ed2f526 100644
--- a/src/file/dirs.h
+++ b/src/file/dirs.h
@@ -24,6 +24,7 @@
 
 #ifdef _WIN32
 BD_PRIVATE int         win32_mkdir(const char *dir);
+BD_PRIVATE char       *win32_get_font_dir(const char *font_file);
 #endif
 
 /*
diff --git a/src/file/dirs_win32.c b/src/file/dirs_win32.c
index e800611..dcce076 100644
--- a/src/file/dirs_win32.c
+++ b/src/file/dirs_win32.c
@@ -43,6 +43,22 @@ int win32_mkdir(const char *dir)
     return _wmkdir(wdir);
 }
 
+char *win32_get_font_dir(const char *font_file)
+{
+    wchar_t wdir[MAX_PATH];
+    if (S_OK != SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, wdir)) {
+        GetWindowsDirectoryW(wdir, MAX_PATH);
+        wcscat(wdir, L"\\fonts");
+    }
+
+    int   len  = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0, NULL, NULL);
+    char *path = malloc(len + strlen(font_file) + 2);
+    WideCharToMultiByte(CP_UTF8, 0, wdir, -1, path, len, NULL, NULL);
+    path[len] = '\\';
+    strcpy(path + len + 1, font_file);
+    return path;
+}
+
 const char *file_get_config_home(void)
 {
     return file_get_data_home();
diff --git a/src/libbluray/bdj/native/java_awt_BDFontMetrics.c b/src/libbluray/bdj/native/java_awt_BDFontMetrics.c
index ca0871c..ca9d3f5 100644
--- a/src/libbluray/bdj/native/java_awt_BDFontMetrics.c
+++ b/src/libbluray/bdj/native/java_awt_BDFontMetrics.c
@@ -38,6 +38,11 @@
 #include <fontconfig/fontconfig.h>
 #endif
 
+#ifdef _WIN32
+#include "file/dirs.h"  // win32_get_font_dir
+#include <windows.h>
+#endif
+
 #include "java_awt_BDFontMetrics.h"
 
 /* Disable some warnings */
@@ -52,6 +57,104 @@
 #endif
 
 /*
+ * Windows fonts
+ */
+
+#ifdef _WIN32
+
+typedef struct {
+    int   bold;
+    int   italic;
+    char *filename;
+} SEARCH_DATA;
+
+static int CALLBACK EnumFontCallback(const ENUMLOGFONTEXA *lpelfe, const NEWTEXTMETRICEX *metric,
+                                     DWORD type, LPARAM lParam)
+{
+    const LOGFONT *lplf = &lpelfe->elfLogFont;
+    const char    *font_name = (const char *)lpelfe->elfFullName;
+    SEARCH_DATA   *data = (SEARCH_DATA *)lParam;
+    int            index = 0;
+    HKEY           hKey;
+    wchar_t        wvalue[MAX_PATH];
+    wchar_t        wdata[256];
+
+    if (type & RASTER_FONTTYPE) {
+        return 1;
+    }
+
+    /* match attributes */
+    if (data->italic >= 0 && (!!lplf->lfItalic != !!data->italic)) {
+        return 1;
+    }
+    if (data->bold >= 0 &&
+        ((data->bold && lplf->lfWeight <= FW_MEDIUM) ||
+         (!data->bold && lplf->lfWeight >= FW_SEMIBOLD))) {
+        return 1;
+    }
+
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
+                     0, KEY_READ, &hKey) != ERROR_SUCCESS) {
+        return 0;
+    }
+
+    while (!data->filename) {
+        DWORD wvalue_len = MAX_PATH - 1;
+        DWORD wdata_len  = 255;
+
+        LONG result = RegEnumValueW(hKey, index++, wvalue, &wvalue_len,
+                                   NULL, NULL, (LPBYTE)wdata, &wdata_len);
+        if (result != ERROR_SUCCESS) {
+            RegCloseKey(hKey);
+            return result;
+        }
+
+        char value[MAX_PATH];
+        WideCharToMultiByte(CP_UTF8, 0, wvalue, -1, value, MAX_PATH, NULL, NULL);
+
+        if (!strcasecmp(value, font_name)) {
+            size_t len = WideCharToMultiByte(CP_UTF8, 0, wdata, -1, NULL, 0, NULL, NULL);
+            if (len != 0) {
+                data->filename = (char *)malloc(len);
+                WideCharToMultiByte(CP_UTF8, 0, wdata, -1, data->filename, len, NULL, NULL);
+                break;
+            }
+        }
+    }
+
+    RegCloseKey(hKey);
+    return 0;
+}
+
+static char *_win32_resolve_font(const char *family, int style)
+{
+    LOGFONT lf;
+    HDC     hDC;
+    SEARCH_DATA data = {style & 2, style & 1, NULL};
+
+    memset(&lf, 0, sizeof(lf));
+    lf.lfCharSet = DEFAULT_CHARSET;
+    strncpy(lf.lfFaceName, family, LF_FACESIZE);
+
+    hDC = GetDC(NULL);
+    EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)&EnumFontCallback, (LPARAM)&data, 0);
+    ReleaseDC(NULL, hDC);
+
+    if (!data.filename) {
+        return win32_get_font_dir("arial.ttf");
+    }
+
+    if (!strchr(data.filename, '\\')) {
+        char *tmp = win32_get_font_dir(data.filename);
+        X_FREE(data.filename);
+        return tmp;
+    }
+    return data.filename;
+}
+
+#endif /* _WIN32 */
+
+/*
  * fontconfig
  */
 
@@ -168,6 +271,8 @@ Java_java_awt_BDFontMetrics_resolveFontN(JNIEnv * env, jclass cls, jstring jfont
     if (lib) {
         filename = _fontconfig_resolve_font(lib, font_family, font_style);
     }
+#elif defined(_WIN32)
+    filename = _win32_resolve_font(font_family, font_style);
 #else
     BD_DEBUG(DBG_BDJ | DBG_CRIT, "BD-J font config support not compiled in\n");
 #endif



More information about the libbluray-devel mailing list