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}"
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)
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}"
)
${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}
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}")
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 ()
+++ /dev/null
-# 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()
#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));
free(s->charLookup[g]);
}
FT_Done_Face (s->face);
+#ifdef VKVG_USE_HARFBUZZ
hb_font_destroy (s->hb_font);
+#endif
free(s->charLookup);
}
vkDestroyFence (dev->vkDev,cache->uploadFence,NULL);
FT_Done_FreeType(cache->library);
+#ifdef VKVG_USE_FONTCONFIG
FcConfigDestroy(cache->config);
FcFini();
+#endif
free (dev->fontCache);
_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;
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) {
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;
}
//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.
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();
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);
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};
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);
_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);
#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.
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 */
// 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 */
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);