]> O.S.I.I.S - jp/vkvg.git/commitdiff
optional fontconfig and harfbuzz
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 25 Dec 2021 11:11:55 +0000 (12:11 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 25 Dec 2021 11:11:55 +0000 (12:11 +0100)
CMakeLists.txt
appveyor.yml
cmake/FindFontconfig.cmake [deleted file]
src/vkvg_context_internal.h
src/vkvg_fonts.c
src/vkvg_fonts.h

index 0c2c816fc6b65fbda0db4f9436626ea0e0718386..42092462bec7848842ab8755d583686eda41aed6 100644 (file)
@@ -1,9 +1,10 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 3.21)
 
 SET(LANG "CXX")
+SET(CMAKE_C_STANDARD 11)
 SET(CMAKE_CXX_STANDARD 11)
 
-PROJECT(vkvg VERSION 0.2.0 DESCRIPTION "Vulkan Vector Graphic")
+PROJECT(vkvg VERSION 0.3.0 DESCRIPTION "Vulkan Vector Graphic")
 
 ADD_COMPILE_DEFINITIONS(
        "VKVG_VERSION_MAJOR=${vkvg_VERSION_MAJOR}"
@@ -91,11 +92,32 @@ IF (ENABLE_DBG_UTILS)
        ADD_DEFINITIONS (-DVKVG_DBG_UTILS)
 ENDIF ()
 
+OPTION(VKVG_USE_FONTCONFIG "use FontConfig to resolve font names" ON)
 
 FIND_PACKAGE(Vulkan REQUIRED)
 FIND_PACKAGE(Freetype REQUIRED)
-FIND_PACKAGE(Fontconfig REQUIRED)
-FIND_PACKAGE(HarfBuzz REQUIRED)
+
+FIND_PACKAGE(Fontconfig)
+IF (Fontconfig_FOUND)
+       OPTION(VKVG_USE_FONTCONFIG "use FontConfig to resolve font names" ON)
+ELSE ()
+       OPTION(VKVG_USE_FONTCONFIG "use FontConfig to resolve font names" OFF)
+       UNSET(VKVG_USE_FONTCONFIG CACHE)
+ENDIF ()
+IF (VKVG_USE_FONTCONFIG)
+       ADD_DEFINITIONS (-DVKVG_USE_FONTCONFIG)
+ENDIF ()
+
+FIND_PACKAGE(HarfBuzz)
+IF (HarfBuzz_FOUND)
+       OPTION(VKVG_USE_HARFBUZZ "use Harbuzz for text layouting" ON)
+ELSE ()
+       OPTION(VKVG_USE_HARFBUZZ "use Harbuzz for text layouting" OFF)
+       UNSET(VKVG_USE_HARFBUZZ CACHE)
+ENDIF ()
+IF (VKVG_USE_HARFBUZZ)
+       ADD_DEFINITIONS (-DVKVG_USE_HARFBUZZ)
+ENDIF ()
 
 FIND_PACKAGE(GLFW3)
 FIND_PACKAGE(Doxygen)
@@ -180,7 +202,7 @@ FUNCTION (setup_lib LibName)
                        VERSION ${vkvg_VERSION_MAJOR}.${vkvg_VERSION_MINOR}
                        SOVERSION ${vkvg_VERSION_MAJOR}
                        C_STANDARD 11
-                       C_EXTENSIONS OFF
+                       #C_EXTENSIONS OFF
                        PUBLIC_HEADER "${VKVG_PUBLIC_HEADERS}"
        )
 
@@ -201,6 +223,15 @@ FUNCTION (setup_lib LibName)
                ${Fontconfig_LIBRARIES}
                vkh_static
        )
+       IF (VKVG_USE_FONTCONFIG)
+               TARGET_INCLUDE_DIRECTORIES(${LibName} PRIVATE
+                       ${Fontconfig_INCLUDE_DIRS}
+               )
+               TARGET_LINK_LIBRARIES(${LibName}
+                       ${Fontconfig_LIBRARIES}
+               )
+       ENDIF ()
+
        INSTALL(TARGETS ${LibName}
                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -275,9 +306,6 @@ IF (VKVG_BUILD_DOCS)
        ENDIF ()
 ENDIF (VKVG_BUILD_DOCS)
 
-MESSAGE(STATUS "VKVG_PUBLIC_HEADERS = ${VKVG_PUBLIC_HEADERS}")
-MESSAGE(STATUS "Vulkan_LIBRARIES = ${Vulkan_LIBRARIES}")
-
 MESSAGE(STATUS "VKVG version\t\t= ${vkvg_VERSION_MAJOR}.${vkvg_VERSION_MINOR}.${vkvg_VERSION_PATCH}")
 MESSAGE(STATUS "comp flags\t\t= ${CMAKE_${LANG}_FLAGS}")
 
@@ -314,6 +342,16 @@ IF (VKVG_PREMULT_ALPHA)
 ELSE ()
        MESSAGE(STATUS "Premult Alpha\t= disabled.")
 ENDIF ()
+IF (VKVG_USE_FONTCONFIG)
+       MESSAGE(STATUS "FontConfig\t\t= enabled.")
+ELSE ()
+       MESSAGE(STATUS "FontConfig\t\t= disabled.")
+ENDIF ()
+IF (VKVG_USE_HARFBUZZ)
+       MESSAGE(STATUS "Harfbuzz\t\t= enabled.")
+ELSE ()
+       MESSAGE(STATUS "Harfbuzz\t\t= disabled.")
+ENDIF ()
 IF (VKVG_LCD_FONT_FILTER)
        MESSAGE(STATUS "Font filtering\t= LCD.")
 ELSE ()
index b31862d7c2d68795fcd0fc5ef9e3c43fce7b6ba3..369028b351e19c344f68f1b790aeb7f129197fa1 100644 (file)
@@ -1,4 +1,4 @@
-version: 0.1.{build}
+version: 0.3.{build}
 
 image:
   - Visual Studio 2019
@@ -55,7 +55,7 @@ for:
         - cpack
     after_build:
         - cd ..
-        - appveyor PushArtifact build/vkvg_0.2.0.deb
+               - appveyor PushArtifact build/vkvg_0.3.0.deb
 
 
 
diff --git a/cmake/FindFontconfig.cmake b/cmake/FindFontconfig.cmake
deleted file mode 100644 (file)
index a6f0180..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#[=======================================================================[.rst:
-FindFontconfig
---------------
-
-Find Fontconfig headers and library.
-
-Imported Targets
-^^^^^^^^^^^^^^^^
-
-``Fontconfig::Fontconfig``
-  The Fontconfig library, if found.
-
-Result Variables
-^^^^^^^^^^^^^^^^
-
-This will define the following variables in your project:
-
-``Fontconfig_FOUND``
-  true if (the requested version of) Fontconfig is available.
-``Fontconfig_VERSION``
-  the version of Fontconfig.
-``Fontconfig_LIBRARIES``
-  the libraries to link against to use Fontconfig.
-``Fontconfig_INCLUDE_DIRS``
-  where to find the Fontconfig headers.
-``Fontconfig_COMPILE_OPTIONS``
-  this should be passed to target_compile_options(), if the
-  target is not used for linking
-
-#]=======================================================================]
-
-
-# use pkg-config to get the directories and then use these values
-# in the FIND_PATH() and FIND_LIBRARY() calls
-find_package(PkgConfig QUIET)
-pkg_check_modules(PKG_FONTCONFIG QUIET fontconfig)
-set(Fontconfig_COMPILE_OPTIONS ${PKG_FONTCONFIG_CFLAGS_OTHER})
-set(Fontconfig_VERSION ${PKG_FONTCONFIG_VERSION})
-
-find_path( Fontconfig_INCLUDE_DIR
-  NAMES
-    fontconfig/fontconfig.h
-  HINTS
-    ${PKG_FONTCONFIG_INCLUDE_DIRS}
-    /usr/X11/include
-)
-
-find_library( Fontconfig_LIBRARY
-  NAMES
-    fontconfig
-  PATHS
-    ${PKG_FONTCONFIG_LIBRARY_DIRS}
-)
-
-if (Fontconfig_INCLUDE_DIR AND NOT Fontconfig_VERSION)
-  file(STRINGS ${Fontconfig_INCLUDE_DIR}/fontconfig/fontconfig.h _contents REGEX "^#define[ \t]+FC_[A-Z]+[ \t]+[0-9]+$")
-  unset(Fontconfig_VERSION)
-  foreach(VPART MAJOR MINOR REVISION)
-    foreach(VLINE ${_contents})
-      if(VLINE MATCHES "^#define[\t ]+FC_${VPART}[\t ]+([0-9]+)$")
-        set(Fontconfig_VERSION_PART "${CMAKE_MATCH_1}")
-        if(Fontconfig_VERSION)
-          string(APPEND Fontconfig_VERSION ".${Fontconfig_VERSION_PART}")
-        else()
-          set(Fontconfig_VERSION "${Fontconfig_VERSION_PART}")
-        endif()
-      endif()
-    endforeach()
-  endforeach()
-endif ()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Fontconfig
-  FOUND_VAR
-    Fontconfig_FOUND
-  REQUIRED_VARS
-    Fontconfig_LIBRARY
-    Fontconfig_INCLUDE_DIR
-  VERSION_VAR
-    Fontconfig_VERSION
-)
-
-
-if(Fontconfig_FOUND AND NOT TARGET Fontconfig::Fontconfig)
-  add_library(Fontconfig::Fontconfig UNKNOWN IMPORTED)
-  set_target_properties(Fontconfig::Fontconfig PROPERTIES
-    IMPORTED_LOCATION "${Fontconfig_LIBRARY}"
-    INTERFACE_COMPILE_OPTIONS "${Fontconfig_COMPILE_OPTIONS}"
-    INTERFACE_INCLUDE_DIRECTORIES "${Fontconfig_INCLUDE_DIR}"
-  )
-endif()
-
-mark_as_advanced(Fontconfig_LIBRARY Fontconfig_INCLUDE_DIR)
-
-if(Fontconfig_FOUND)
-  set(Fontconfig_LIBRARIES ${Fontconfig_LIBRARY})
-  set(Fontconfig_INCLUDE_DIRS ${Fontconfig_INCLUDE_DIR})
-endif()
index 644be23c02a1a14fed26febd83d37d5449d017ce..a5e6fcd549186ba3eb2efb08d7a03a3aef864596 100644 (file)
@@ -170,7 +170,7 @@ typedef struct _vkvg_context_t {
        char*                           selectedFontName;
        //_vkvg_font_t            selectedFont;         //hold current face and size before cache addition
        _vkvg_font_identity_t*           currentFont;           //font pointing to cached fonts identity
-       _vkvg_font_t*   currentFontSize;        //font structure by size ready for lookup
+       _vkvg_font_t*           currentFontSize;        //font structure by size ready for lookup
        vkvg_direction_t        textDirection;
 
        push_constants          pushConsts;
index 24b30360c28c20b2e34580e75454e2c8bb736655..1bfee072f15d702b0ee1cf561397470ba36a49c8 100644 (file)
 
 #include "vkh.h"
 
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+
 static int defaultFontCharSize = 12<<6;
 
 void _init_fonts_cache (VkvgDevice dev){
        _font_cache_t* cache = (_font_cache_t*)calloc(1, sizeof(_font_cache_t));
 
+#ifdef VKVG_USE_FONTCONFIG
        cache->config = FcInitLoadConfigAndFonts();
        if (!cache->config) {
                fprintf(stderr, "Font config initialisation failed, consider using 'FONTCONFIG_PATH' and 'FONTCONFIG_FILE' environmane\
                                           variables to point to 'fonts.conf' needed for FontConfig startup");
                assert(cache->config);
        }
+#endif
 
        FT_CHECK_RESULT(FT_Init_FreeType(&cache->library));
 
@@ -175,7 +181,9 @@ void _destroy_font_cache (VkvgDevice dev){
                                        free(s->charLookup[g]);
                        }
                        FT_Done_Face (s->face);
+#ifdef VKVG_USE_HARFBUZZ
                        hb_font_destroy (s->hb_font);
+#endif
 
                        free(s->charLookup);
                }
@@ -197,8 +205,10 @@ void _destroy_font_cache (VkvgDevice dev){
        vkDestroyFence          (dev->vkDev,cache->uploadFence,NULL);
 
        FT_Done_FreeType(cache->library);
+#ifdef VKVG_USE_FONTCONFIG
        FcConfigDestroy(cache->config);
        FcFini();
+#endif
 
        free (dev->fontCache);
 
@@ -309,14 +319,15 @@ _char_ref* _prepare_char (VkvgDevice dev, _vkvg_font_t* f, FT_UInt gindex){
 
        _char_ref* cr = (_char_ref*)malloc(sizeof(_char_ref));
        vec4 uvBounds = {
-               (float)(penX + f->curLine.penX) / (float)FONT_PAGE_SIZE,
-               (float)f->curLine.penY / (float)FONT_PAGE_SIZE,
-               (float)bmpWidth,
-               (float)bmp.rows};
-       cr->bounds = uvBounds;
-       cr->pageIdx = f->curLine.pageIdx;
-       cr->bmpDiff.x = (int16_t)slot->bitmap_left;
-       cr->bmpDiff.y = (int16_t)slot->bitmap_top;
+               {(float)(penX + f->curLine.penX) / (float)FONT_PAGE_SIZE},
+               {(float)f->curLine.penY / (float)FONT_PAGE_SIZE},
+               {(float)bmpWidth},
+               {(float)bmp.rows}};
+       cr->bounds              = uvBounds;
+       cr->pageIdx             = f->curLine.pageIdx;
+       cr->bmpDiff.x   = (int16_t)slot->bitmap_left;
+       cr->bmpDiff.y   = (int16_t)slot->bitmap_top;
+       cr->advance             = slot->advance;
 
        f->charLookup[gindex] = cr;
        dev->fontCache->stagingX += bmpWidth;
@@ -333,12 +344,13 @@ void _select_font_face (VkvgContext ctx, const char* name){
        ctx->currentFont = NULL;
        ctx->currentFontSize = NULL;
 }
-void _font_add_fc_name (_vkvg_font_identity_t* font, const char* fcname) {
+void _font_add_fc_name (_vkvg_font_identity_t* font, const char* fcname, int nameLength) {
        if (++font->fcNamesCount == 1)
                font->fcNames = (char**) malloc (sizeof(char*));
        else
                font->fcNames = (char**) realloc (font->fcNames, font->fcNamesCount * sizeof(char*));
-       font->fcNames[font->fcNamesCount-1] = (char*)calloc(FONT_NAME_MAX_SIZE, sizeof (char));
+
+       font->fcNames[font->fcNamesCount-1] = (char*)calloc(nameLength, sizeof (char));
        strcpy (font->fcNames[font->fcNamesCount-1], fcname);
 }
 _vkvg_font_t* _find_or_create_font_size (VkvgContext ctx, _vkvg_font_identity_t* font, FT_F26Dot6 charSize) {
@@ -358,12 +370,16 @@ _vkvg_font_t* _find_or_create_font_size (VkvgContext ctx, _vkvg_font_identity_t*
 
        FT_CHECK_RESULT(FT_New_Face(cache->library, font->fontFile, 0, &newSize.face));
        FT_CHECK_RESULT(FT_Set_Char_Size(newSize.face, 0, newSize.charSize, dev->hdpi, dev->vdpi ));
+
+#ifdef VKVG_USE_HARFBUZZ
        newSize.hb_font = hb_ft_font_create(newSize.face, NULL);
+#endif
+
        newSize.charLookup = (_char_ref**)calloc(newSize.face->num_glyphs,sizeof(_char_ref*));
 
        //nf.curLine.height = (nf.face->bbox.xMax - nf.face->bbox.xMin) >> 6;
        if (FT_IS_SCALABLE(newSize.face))
-               newSize.curLine.height = FT_MulFix(newSize.face->height, newSize.face->size->metrics.y_scale) >> 6;// nf.face->size->metrics.height >> 6;
+               newSize.curLine.height = FT_MulFix(newSize.face->height, newSize.face->size->metrics.y_scale) >> 6;
        else
                newSize.curLine.height = newSize.face->height >> 6;
 
@@ -374,66 +390,74 @@ _vkvg_font_t* _find_or_create_font_size (VkvgContext ctx, _vkvg_font_identity_t*
 }
 
 //try find font already resolved with fontconfig by font name
-_vkvg_font_identity_t* _tryFindFontByName (VkvgContext ctx, const char* fontName){
+_vkvg_font_identity_t* _tryFindFontByName (VkvgContext ctx){
        _font_cache_t*  cache = (_font_cache_t*)ctx->pSurf->dev->fontCache;
        for (int i = 0; i < cache->fontsCount; ++i) {
                for (uint32_t j = 0; j < cache->fonts[i].fcNamesCount; j++) {
-                       if (strcmp (cache->fonts[i].fcNames[j], fontName) == 0)
+                       if (strcmp (cache->fonts[i].fcNames[j], ctx->selectedFontName) == 0)
                                return &cache->fonts[i];
                }
        }
        return NULL;
 }
-_vkvg_font_identity_t* _tryResolveFontNameWithFontConfig (VkvgContext ctx, const char* fontName) {
+_vkvg_font_identity_t* _tryResolveFontNameWithFontConfig (VkvgContext ctx) {
        _vkvg_font_identity_t* resolvedFont = NULL;
        _font_cache_t*  cache = (_font_cache_t*)ctx->pSurf->dev->fontCache;
+       char* fontFile = NULL;
+
+#ifdef VKVG_USE_FONTCONFIG
        FcPattern* pat = FcNameParse((const FcChar8*)ctx->selectedFontName);
        FcConfigSubstitute(cache->config, pat, FcMatchPattern);
        FcDefaultSubstitute(pat);
        FcResult result;
        FcPattern* font = FcFontMatch(cache->config, pat, &result);
-       char* fontFile;
-       if (font) {
-               if (FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile) == FcResultMatch) {
-                       //try find font in cache by path
-                       for (int i = 0; i < cache->fontsCount; ++i) {
-                               if (strcmp (cache->fonts[i].fontFile, fontFile) == 0) {
-                                       _font_add_fc_name (&cache->fonts[i], ctx->selectedFontName);
-                                       resolvedFont = &cache->fonts[i];
-                                       break;;
-                               }
+       if (font)
+               FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile);
+#endif
+       if (fontFile) {
+               //try find font in cache by path
+               for (int i = 0; i < cache->fontsCount; ++i) {
+                       if (strcmp (cache->fonts[i].fontFile, fontFile) == 0) {
+                               int fflength = strlen(fontFile) + 1;
+                               _font_add_fc_name (&cache->fonts[i], ctx->selectedFontName, fflength);
+                               resolvedFont = &cache->fonts[i];
+                               break;;
                        }
-                       if (!resolvedFont) {
-                               //if not found, create a new vkvg_font
-                               cache->fontsCount++;
+               }
+               if (!resolvedFont) {
+                       //if not found, create a new vkvg_font
+                       cache->fontsCount++;
 
-                               if (cache->fontsCount == 1)
-                                       cache->fonts = (_vkvg_font_identity_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_identity_t));
-                               else
-                                       cache->fonts = (_vkvg_font_identity_t*) realloc (cache->fonts, cache->fontsCount * sizeof(_vkvg_font_identity_t));
+                       if (cache->fontsCount == 1)
+                               cache->fonts = (_vkvg_font_identity_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_identity_t));
+                       else
+                               cache->fonts = (_vkvg_font_identity_t*) realloc (cache->fonts, cache->fontsCount * sizeof(_vkvg_font_identity_t));
 
-                               _vkvg_font_identity_t nf = {0};
+                       _vkvg_font_identity_t nf = {0};
 
-                               nf.fontFile = (char*)malloc (FONT_FILE_NAME_MAX_SIZE * sizeof(char));
-                               memcpy (nf.fontFile, fontFile, FONT_FILE_NAME_MAX_SIZE);
-                               _font_add_fc_name (&nf, ctx->selectedFontName);
+                       int fflength = strlen(fontFile) + 1;
+                       nf.fontFile = (char*)malloc (fflength * sizeof(char));
+                       strcpy (nf.fontFile, fontFile);
+                       _font_add_fc_name (&nf, ctx->selectedFontName, fflength);
 
-                               cache->fonts[cache->fontsCount-1] = nf;
-                               resolvedFont = &cache->fonts[cache->fontsCount-1];
-                       }
+                       cache->fonts[cache->fontsCount-1] = nf;
+                       resolvedFont = &cache->fonts[cache->fontsCount-1];
                }
        }
+
+#ifdef VKVG_USE_FONTCONFIG
        FcPatternDestroy(pat);
        FcPatternDestroy(font);
+#endif
        return resolvedFont;
 }
 
 
 //try to find font in cache with same font file path and font size as selected in context.
 _vkvg_font_identity_t* _find_or_create_font (VkvgContext ctx){
-       _vkvg_font_identity_t* resolvedFont = _tryFindFontByName(ctx, ctx->selectedFontName);
+       _vkvg_font_identity_t* resolvedFont = _tryFindFontByName(ctx);
        if (!resolvedFont)
-               resolvedFont = _tryResolveFontNameWithFontConfig(ctx, ctx->selectedFontName);
+               resolvedFont = _tryResolveFontNameWithFontConfig(ctx);
        return resolvedFont;
 }
 //try to find corresponding font in cache (defined by context selectedFont) and create a new font entry if not found.
@@ -446,6 +470,8 @@ void _update_current_font (VkvgContext ctx) {
                ctx->currentFontSize = _find_or_create_font_size (ctx, ctx->currentFont, ctx->selectedCharSize);
        }       
 }
+
+#ifdef VKVG_USE_HARFBUZZ
 //Get harfBuzz buffer for provided text.
 hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text) {
        hb_buffer_t *buf = hb_buffer_create();
@@ -464,6 +490,8 @@ hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text) {
        hb_shape (font->hb_font, buf, NULL, 0);
        return buf;
 }
+#endif
+
 //retrieve global font extends of context's current font as defined by FreeType
 void _font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) {
        _update_current_font (ctx);
@@ -508,31 +536,67 @@ void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) {
        if (ctx->status)
                return;
 
-       textRun->hbBuf = _get_hb_buffer (ctx->currentFontSize, text);
        textRun->font = ctx->currentFontSize;
        textRun->dev = ctx->pSurf->dev;
 
-       textRun->glyph_pos = hb_buffer_get_glyph_positions       (textRun->hbBuf, &textRun->glyph_count);
+#ifdef VKVG_USE_HARFBUZZ
+       textRun->hbBuf = _get_hb_buffer (ctx->currentFontSize, text);
+       textRun->glyphs = hb_buffer_get_glyph_positions  (textRun->hbBuf, &textRun->glyph_count);
+#else
+       int textByteLength = strlen (text);
+       if (textByteLength > 0) {
+               size_t wsize = mbstowcs(NULL, text, 0);
+               wchar_t *tmp = (wchar_t*)malloc((wsize+1) * sizeof (wchar_t));
+               textRun->glyph_count = mbstowcs (tmp, text, wsize);
+               textRun->glyphs = (vkvg_glyph_info_t*)malloc(textRun->glyph_count * sizeof (vkvg_glyph_info_t));
+               for (unsigned int i=0; i<textRun->glyph_count; i++) {
+                       FT_UInt gindex = FT_Get_Char_Index( textRun->font->face, tmp[i]);
+                       _char_ref* cr = textRun->font->charLookup[gindex];
+                       if (cr==NULL)
+                               cr = _prepare_char(textRun->dev, textRun->font, gindex);
+                       textRun->glyphs[i].codepoint = gindex;
+                       textRun->glyphs[i].x_advance = cr->advance.x;
+                       textRun->glyphs[i].y_advance = cr->advance.y;
+                       textRun->glyphs[i].x_offset      = 0;
+                       textRun->glyphs[i].y_offset      = 0;
+                       /*textRun->glyphs[i].x_offset    = cr->bmpDiff.x;
+                       textRun->glyphs[i].y_offset      = cr->bmpDiff.y;*/
+               }
+               free (tmp);
+       }
+#endif
 
        unsigned int string_width_in_pixels = 0;
        for (uint32_t i=0; i < textRun->glyph_count; ++i)
-               string_width_in_pixels += textRun->glyph_pos[i].x_advance >> 6;
+               string_width_in_pixels += textRun->glyphs[i].x_advance >> 6;
 
        FT_Size_Metrics* metrics = &ctx->currentFontSize->face->size->metrics;
        textRun->extents.x_advance = (float)string_width_in_pixels;
-       textRun->extents.y_advance = (float)(textRun->glyph_pos[textRun->glyph_count-1].y_advance >> 6);
-       textRun->extents.x_bearing = -(float)(textRun->glyph_pos[0].x_offset >> 6);
-       textRun->extents.y_bearing = -(float)(textRun->glyph_pos[0].y_offset >> 6);
+       if (textRun->glyph_count > 0) {
+               textRun->extents.y_advance = (float)(textRun->glyphs[textRun->glyph_count-1].y_advance >> 6);
+               textRun->extents.x_bearing = -(float)(textRun->glyphs[0].x_offset >> 6);
+               textRun->extents.y_bearing = -(float)(textRun->glyphs[0].y_offset >> 6);
+       }
 
        textRun->extents.height = (float)(FT_MulFix(ctx->currentFontSize->face->height, metrics->y_scale) >> 6);// (metrics->ascender + metrics->descender) >> 6;
        textRun->extents.width  = textRun->extents.x_advance;
 }
 void _destroy_text_run (VkvgText textRun) {
+#ifdef VKVG_USE_HARFBUZZ
        hb_buffer_destroy (textRun->hbBuf);
+#else
+       if (textRun->glyph_count > 0)
+               free (textRun->glyphs);
+#endif
 }
 void _show_text_run (VkvgContext ctx, VkvgText tr) {
        unsigned int glyph_count;
+#ifdef VKVG_USE_HARFBUZZ
        hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos (tr->hbBuf, &glyph_count);
+#else
+       vkvg_glyph_info_t* glyph_info = tr->glyphs;
+       glyph_count = tr->glyph_count;
+#endif
 
        Vertex v = {{0},ctx->curColor,{0,0,-1}};
        vec2 pen = {0,0};
@@ -550,8 +614,8 @@ void _show_text_run (VkvgContext ctx, VkvgText tr) {
                if (cr!=NULL){
                        float uvWidth = cr->bounds.width / (float)FONT_PAGE_SIZE;
                        float uvHeight = cr->bounds.height / (float)FONT_PAGE_SIZE;
-                       vec2 p0 = {pen.x + cr->bmpDiff.x + (tr->glyph_pos[i].x_offset >> 6),
-                                          pen.y - cr->bmpDiff.y + (tr->glyph_pos[i].y_offset >> 6)};
+                       vec2 p0 = {pen.x + cr->bmpDiff.x + (tr->glyphs[i].x_offset >> 6),
+                                          pen.y - cr->bmpDiff.y + (tr->glyphs[i].y_offset >> 6)};
                        v.pos = p0;
 
                        VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
@@ -579,8 +643,8 @@ void _show_text_run (VkvgContext ctx, VkvgText tr) {
                        _add_tri_indices_for_rect (ctx, firstIdx);
                }
 
-               pen.x += (tr->glyph_pos[i].x_advance >> 6);
-               pen.y -= (tr->glyph_pos[i].y_advance >> 6);
+               pen.x += (tr->glyphs[i].x_advance >> 6);
+               pen.y -= (tr->glyphs[i].y_advance >> 6);
        }
 
        vkvg_move_to(ctx, pen.x, pen.y);
index 5c88447c8c1f994aef2cdac791cd1f00ae39ddc3..02b0a7f9ed6482bb27c1ecdf1c1cecf5480b7a2a 100644 (file)
 #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
 #include <freetype/ftlcdfil.h>
 #endif
-
+#ifdef VKVG_USE_HARFBUZZ
 #include <harfbuzz/hb.h>
 #include <harfbuzz/hb-ft.h>
+#else
+#endif
 
+#ifdef VKVG_USE_FONTCONFIG
 #include <fontconfig/fontconfig.h>
+#endif
 
 #define FONT_PAGE_SIZE                 1024
 #define FONT_CACHE_INIT_LAYERS 1
 
 //texture coordinates of one character in font cache array texture.
 typedef struct {
-       vec4    bounds;                                 /* normalized float bounds of character bitmap in font cache texture. */
-       vec2i16 bmpDiff;                                /* Difference in pixel between char bitmap top left corner and char glyph*/
-       uint8_t pageIdx;                                /* Page index in font cache texture array */
+       vec4            bounds;                         /* normalized float bounds of character bitmap in font cache texture. */
+       vec2i16         bmpDiff;                        /* Difference in pixel between char bitmap top left corner and char glyph*/
+       uint8_t         pageIdx;                        /* Page index in font cache texture array */
+       FT_Vector       advance;                        /* horizontal or vertical advance */
 }_char_ref;
 // Current location in font cache texture array for new character addition. Each font holds such structure to locate
 // where to upload new chars.
@@ -76,11 +81,14 @@ typedef struct {
 typedef struct {
        FT_F26Dot6      charSize;                       /* Font size*/
        FT_Face         face;                           /* FreeType face*/
+#ifdef VKVG_USE_HARFBUZZ
        hb_font_t*      hb_font;                        /* HarfBuzz font instance*/
+#endif
        _char_ref** charLookup;                 /* Lookup table of characteres in cache, if not found, upload is queued*/
 
        _tex_ref_t      curLine;                        /* tex coord where to add new char bmp's */
 }_vkvg_font_t;
+
 /* Font identification structure */
 typedef struct {
        char**                          fcNames;                /* Resolved Input names to this font by fontConfig */
@@ -93,7 +101,9 @@ typedef struct {
 // Font cache global structure, entry point for all font related operations.
 typedef struct {
        FT_Library              library;                /* FreeType library*/
+#ifdef VKVG_USE_FONTCONFIG
        FcConfig*               config;                 /* Font config, used to find font files by font names*/
+#endif
 
        int                             stagingX;               /* x pen in host buffer */
        uint8_t*                hostBuff;               /* host memory where bitmaps are first loaded */
@@ -107,18 +117,31 @@ typedef struct {
        int*                    pensY;                  /* array of current y pen positions for each texture in cache 2d array */
        VkFence                 uploadFence;    /* Signaled when upload is finished */
 
-       _vkvg_font_identity_t*  fonts;                  /* Loaded fonts structure array */
+       _vkvg_font_identity_t*  fonts;  /* Loaded fonts structure array */
        int32_t                 fontsCount;             /* Loaded fonts array count*/
 }_font_cache_t;
+#ifndef VKVG_USE_HARFBUZZ
+typedef struct _glyph_info_t {
+  int32_t x_advance;
+  int32_t y_advance;
+  int32_t x_offset;
+  int32_t y_offset;
+  FT_UInt codepoint;//should be named glyphIndex, but for harfbuzz compatibility...
+} vkvg_glyph_info_t;
+#endif
 // Precompute everything necessary to draw one line of text, usefull to draw the same text multiple times.
 typedef struct _vkvg_text_run_t {
-       hb_buffer_t*            hbBuf;          /* HarfBuzz buffer of text */
        _vkvg_font_t*   font;           /* vkvg font structure pointer */
        VkvgDevice                      dev;            /* vkvg device associated with this text run */
        vkvg_text_extents_t extents;    /* store computed text extends */
        const char*                     text;           /* utf8 char array of text*/
        unsigned int            glyph_count;/* Total glyph count */
-       hb_glyph_position_t *glyph_pos; /* HarfBuzz computed glyph positions array */
+#ifdef VKVG_USE_HARFBUZZ
+       hb_buffer_t*            hbBuf;          /* HarfBuzz buffer of text */
+       hb_glyph_position_t *glyphs; /* HarfBuzz computed glyph positions array */
+#else
+       vkvg_glyph_info_t       *glyphs; /* computed glyph positions array */
+#endif
 } vkvg_text_run_t;
 //Create font cache.
 void _init_fonts_cache         (VkvgDevice dev);