]> O.S.I.I.S - jp/vkvg.git/commitdiff
split text functions to prevent harfbuz code duplication and expose them in vkvg.h
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 13 Jun 2018 12:35:24 +0000 (14:35 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 13 Jun 2018 12:35:24 +0000 (14:35 +0200)
include/vkvg.h
src/vkvg_context.c
src/vkvg_fonts.c
src/vkvg_fonts.h

index 359db621a7ee817c019487097a180f9f692714e4..b73f3cefab90910903a2fbb6ef70de73eef2e29a 100644 (file)
@@ -125,6 +125,8 @@ typedef struct {
     float y_advance;
 } vkvg_text_extents_t;
 
+typedef struct _vkvg_text_run_t* VkvgText;
+
 typedef struct _vkvg_context_t* VkvgContext;
 typedef struct _vkvg_surface_t* VkvgSurface;
 typedef struct _vkvg_device_t*  VkvgDevice;
@@ -248,6 +250,12 @@ void vkvg_show_text                        (VkvgContext ctx, const char* text);
 void vkvg_text_extents      (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents);
 void vkvg_font_extents      (VkvgContext ctx, vkvg_font_extents_t* extents);
 
+//text run holds harfbuz datas, and prevent recreating them multiple times for the same line of text.
+VkvgText    vkvg_text_run_create    (VkvgContext ctx, const char* text);
+void        vkvg_text_run_destroy   (VkvgText textRun);
+void        vkvg_show_text_run      (VkvgContext ctx, VkvgText textRun);
+vkvg_text_extents_t* vkvg_text_run_get_extents (VkvgText textRun);
+
 //pattern
 VkvgPattern vkvg_pattern_create             ();
 VkvgPattern vkvg_pattern_reference          (VkvgPattern pat);
index 8c98b0f8ab04bf994c81e448957c5858c18678e5..99ebcf9de874174115d7523e2d002776d147a067 100644 (file)
@@ -614,6 +614,22 @@ void vkvg_show_text (VkvgContext ctx, const char* text){
     _record_draw_cmd (ctx);
 }
 
+VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) {
+    VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t));
+    _create_text_run(ctx, text, tr);
+    return tr;
+}
+void vkvg_text_run_destroy (VkvgText textRun) {
+    _destroy_text_run (textRun);
+    free (textRun);
+}
+void vkvg_show_text_run (VkvgContext ctx, VkvgText textRun) {
+    _show_text_run(ctx, textRun);
+}
+vkvg_text_extents_t* vkvg_text_run_get_extents (VkvgText textRun) {
+    return &textRun->extents;
+}
+
 void vkvg_text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) {
     _text_extents(ctx, text, extents);
 }
@@ -629,7 +645,7 @@ void vkvg_save (VkvgContext ctx){
     VkvgDevice dev = ctx->pSurf->dev;
     vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t));
 
-    sav->stencilMS = vkh_image_ms_create(dev,VK_FORMAT_S8_UINT,VKVG_SAMPLES,ctx->pSurf->width,ctx->pSurf->height,
+    sav->stencilMS = vkh_image_ms_create (dev,VK_FORMAT_S8_UINT, VKVG_SAMPLES, ctx->pSurf->width, ctx->pSurf->height,
                         VMA_MEMORY_USAGE_GPU_ONLY,
                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
 
index 42c3182fea387c0d82a80b205eba85795ae33dd8..3fdb8f3b198a2e814ed7ca15f203b54f07b144b3 100644 (file)
@@ -322,7 +322,7 @@ void _update_current_font (VkvgContext ctx) {
             assert(!FT_New_Face(cache->library, nf.fontFile, 0, &nf.face));
             assert(!FT_Set_Char_Size(nf.face, 0, nf.charSize, dev->hdpi, dev->vdpi ));
             nf.hb_font = hb_ft_font_create(nf.face, NULL);
-            nf.charLookup = (_char_ref*)calloc(nf.face->num_glyphs,sizeof(_char_ref));
+            nf.charLookup = (_char_ref**)calloc(nf.face->num_glyphs,sizeof(_char_ref*));
 
             //nf.curLine.height = (nf.face->bbox.xMax - nf.face->bbox.xMin) >> 6;
             if (FT_IS_SCALABLE(nf.face))
@@ -369,45 +369,42 @@ void _font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) {
 void _text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t *extents) {
     _update_current_font (ctx);
 
-    hb_buffer_t*    buf = _get_hb_buffer (ctx, text);
-    _vkvg_font_t*   f   = ctx->currentFont;
-    VkvgDevice      dev = ctx->pSurf->dev;
-    unsigned int    glyph_count;
+    vkvg_text_run_t tr = {};
+    _create_text_run (ctx, text, &tr);
 
-    hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions   (buf, &glyph_count);
+    *extents = tr.extents;
 
-    unsigned int string_width_in_pixels = 0;
-    for (int i=0; i < glyph_count; ++i)
-        string_width_in_pixels += glyph_pos[i].x_advance >> 6;
-
-    FT_Size_Metrics* metrics = &ctx->currentFont->face->size->metrics;
-    extents->x_advance = string_width_in_pixels;
-    extents->y_advance = glyph_pos[glyph_count-1].y_advance >> 6;
-    extents->x_bearing = -(glyph_pos[0].x_offset >> 6);
-    extents->y_bearing = -(glyph_pos[0].y_offset >> 6);
-
-    extents->height = (metrics->ascender + metrics->descender) >> 6;
-    extents->width  = extents->x_advance;
-
-    //todo: populate other fields
-    hb_buffer_destroy (buf);
+    _destroy_text_run (&tr);
 }
-void _show_text (VkvgContext ctx, const char* text){
+void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) {
 
     _update_current_font (ctx);
 
-    hb_buffer_t*    buf = _get_hb_buffer (ctx, text);
-    _vkvg_font_t*   f   = ctx->currentFont;
-    VkvgDevice      dev = ctx->pSurf->dev;
+    textRun->hbBuf = _get_hb_buffer (ctx, text);
+    textRun->font = ctx->currentFont;
+    textRun->dev = ctx->pSurf->dev;
 
-    unsigned int         glyph_count;
-    hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions   (buf, &glyph_count);
+    textRun->glyph_pos = hb_buffer_get_glyph_positions   (textRun->hbBuf, &textRun->glyph_count);
 
     unsigned int string_width_in_pixels = 0;
-    for (int i=0; i < glyph_count; ++i)
-        string_width_in_pixels += glyph_pos[i].x_advance >> 6;
+    for (int i=0; i < textRun->glyph_count; ++i)
+        string_width_in_pixels += textRun->glyph_pos[i].x_advance >> 6;
+
+    FT_Size_Metrics* metrics = &ctx->currentFont->face->size->metrics;
+    textRun->extents.x_advance = string_width_in_pixels;
+    textRun->extents.y_advance = textRun->glyph_pos[textRun->glyph_count-1].y_advance >> 6;
+    textRun->extents.x_bearing = -(textRun->glyph_pos[0].x_offset >> 6);
+    textRun->extents.y_bearing = -(textRun->glyph_pos[0].y_offset >> 6);
 
-    hb_glyph_info_t     *glyph_info   = hb_buffer_get_glyph_infos       (buf, &glyph_count);
+    textRun->extents.height = (metrics->ascender + metrics->descender) >> 6;
+    textRun->extents.width  = textRun->extents.x_advance;
+}
+void _destroy_text_run (VkvgText textRun) {
+    hb_buffer_destroy (textRun->hbBuf);
+}
+void _show_text_run (VkvgContext ctx, VkvgText tr) {
+    unsigned int glyph_count;
+    hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos (tr->hbBuf, &glyph_count);
 
     Vertex v = {};
     vec2 pen = {0,0};
@@ -416,17 +413,17 @@ void _show_text (VkvgContext ctx, const char* text){
         pen = _get_current_position(ctx);
 
     for (int i=0; i < glyph_count; ++i) {
-        _char_ref* cr = f->charLookup[glyph_info[i].codepoint];
+        _char_ref* cr = tr->font->charLookup[glyph_info[i].codepoint];
 
         if (cr==NULL)
-            cr = _prepare_char(dev,f,glyph_info[i].codepoint);
+            cr = _prepare_char(tr->dev, tr->font, glyph_info[i].codepoint);
 
         //continue;
         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 + (glyph_pos[i].x_offset >> 6),
-                       pen.y - cr->bmpDiff.y + (glyph_pos[i].y_offset >> 6)};
+            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)};
             v.pos = p0;
 
             uint32_t firstIdx = ctx->vertCount;
@@ -453,18 +450,27 @@ void _show_text (VkvgContext ctx, const char* text){
             _add_tri_indices_for_rect (ctx, firstIdx);
         }
 
-        pen.x += (glyph_pos[i].x_advance >> 6);
-        pen.y -= (glyph_pos[i].y_advance >> 6);
+        pen.x += (tr->glyph_pos[i].x_advance >> 6);
+        pen.y -= (tr->glyph_pos[i].y_advance >> 6);
     }
 
     vkvg_move_to(ctx, pen.x, pen.y);
 
-    _flush_chars_to_tex(dev,f);
-    hb_buffer_destroy (buf);
+    _flush_chars_to_tex(tr->dev, tr->font);
+}
+void _show_text (VkvgContext ctx, const char* text){
+
+    vkvg_text_run_t tr = {};
+    _create_text_run (ctx, text, &tr);
+
+    _show_text_run (ctx, &tr);
+
+    _destroy_text_run (&tr);
+
     //_show_texture(ctx); return;
 }
 
-//debug function
+#if DEBUG
 void _show_texture (vkvg_context* ctx){
     Vertex vs[] = {
         {{0,0},                             {0,0,1}},
@@ -480,6 +486,7 @@ void _show_texture (vkvg_context* ctx){
 
     _add_tri_indices_for_rect (ctx, 0);
 }
+#endif
 /*void testfonts(){
     FT_Library      library;
     FT_Face         face;
@@ -518,8 +525,3 @@ void _show_texture (vkvg_context* ctx){
     FT_Done_FreeType( library );
 }*/
 
-
-//void main(){
-//    testfonts();
-//}
-
index 93e959c2b7855e8d1f503aa9a39815e3b5223b86..89233276af240b74181fc3c1c6b33911c22827d0 100644 (file)
@@ -83,6 +83,16 @@ typedef struct {
     uint8_t                    fontsCount;
 }_font_cache_t;
 
+typedef struct _vkvg_text_run_t {
+    hb_buffer_t*        hbBuf;
+    _vkvg_font_t*       font;
+    VkvgDevice          dev;
+    vkvg_text_extents_t extents;
+    const char*         text;
+    unsigned int         glyph_count;
+    hb_glyph_position_t *glyph_pos;
+} vkvg_text_run_t;
+
 void _init_fonts_cache         (VkvgDevice dev);
 void _destroy_font_cache       (VkvgDevice dev);
 void _select_font_face         (VkvgContext ctx, const char* name);
@@ -90,4 +100,8 @@ void _set_font_size         (VkvgContext ctx, uint32_t size);
 void _show_text                                (VkvgContext ctx, const char* text);
 void _text_extents           (VkvgContext ctx, const char* text, vkvg_text_extents_t *extents);
 void _font_extents           (VkvgContext ctx, vkvg_font_extents_t* extents);
+
+void _create_text_run   (VkvgContext ctx, const char* text, VkvgText textRun);
+void _destroy_text_run  (VkvgText textRun);
+void _show_text_run     (VkvgContext ctx, VkvgText tr);
 #endif