Browse Source

fixed memory leaks, child glyph data is kept

Iver 5 months ago
parent
commit
1cbfb8d252
3 changed files with 70 additions and 28 deletions
  1. 1 1
      readme.md
  2. 11 1
      src/headers/sourparse.h
  3. 58 26
      src/library/sourparse.c

+ 1 - 1
readme.md

@@ -5,7 +5,7 @@ World's Best TTF Parser, 2025
 
 
 ### Todo List
 ### Todo List
 
 
-- [ ] fix memory leaks
+- [x] fix memory leaks
 - [ ] read composite glyphs' child glyphs into memory as positions (I actualy might make it just be references to glyphs and then just compute the values at runtime, but with a whole ttf file loaded i think its only like 1mb super maximum of memory so it really doesn't matter)
 - [ ] read composite glyphs' child glyphs into memory as positions (I actualy might make it just be references to glyphs and then just compute the values at runtime, but with a whole ttf file loaded i think its only like 1mb super maximum of memory so it really doesn't matter)
 - [ ] add support for other formats
 - [ ] add support for other formats
 - [ ] add complete TTF support (all the platforms and encodings. Well not the deprecated/obscure ones probably)
 - [ ] add complete TTF support (all the platforms and encodings. Well not the deprecated/obscure ones probably)

+ 11 - 1
src/headers/sourparse.h

@@ -4,8 +4,18 @@
 #include "stdint.h"
 #include "stdint.h"
 
 
 typedef struct {
 typedef struct {
-    int *x_coords, *y_coords, *contour_end_indicies, number_of_points, number_of_contours;
+    int scale_x, scale01, scale10, scale_y;
+    int glyph_index;
+    int16_t arg1, arg2;
+} SP_component;
+
+typedef struct {
+    int *x_coords, *y_coords, *contour_end_indicies; 
+    int number_of_points, number_of_contours, number_of_components;
     uint8_t *flags;
     uint8_t *flags;
+    int16_t x_min, y_min, x_max, y_max;
+    SP_component *components;
+    int is_composite;
 } SP_glyph;
 } SP_glyph;
 
 
 typedef struct {
 typedef struct {

+ 58 - 26
src/library/sourparse.c

@@ -112,56 +112,74 @@ void read_glyph(SP_font *font, int current_glyph){
     glyph->number_of_contours = (int)get_i16(font);
     glyph->number_of_contours = (int)get_i16(font);
 
 
     // do i need these? i dont think so
     // do i need these? i dont think so
-    int16_t x_min = get_i16(font);
-    int16_t y_min = get_i16(font);
-    int16_t x_max = get_i16(font);
-    int16_t y_max = get_i16(font);
-
+    glyph->x_min = get_i16(font);
+    glyph->y_min = get_i16(font);
+    glyph->x_max = get_i16(font);
+    glyph->y_max = get_i16(font);
+        
     // glyph is composite :(
     // glyph is composite :(
-    if (glyph->number_of_contours < 0){     
+    if (glyph->number_of_contours < 0){    
+        glyph->is_composite = 1;
+        
         uint16_t flags;
         uint16_t flags;
+
+        glyph->number_of_components = 0;
         
         
+        int current_allocated_components = 5;
+
+        // assume the glyph has 5 children components
+        glyph->components = malloc(sizeof(SP_component) * current_allocated_components);
+
         int reading_glyphs = 1;
         int reading_glyphs = 1;
         while (reading_glyphs) {
         while (reading_glyphs) {
+            glyph->number_of_components++;
+            
+            // we use number of components as the current component because we're iteratiing it anyways.
+            // A better name would be more fitting, but it wouldn't make sense to use another var
+            if (glyph->number_of_components >= current_allocated_components){
+                current_allocated_components += 5;
+
+                glyph->components = realloc(glyph->components, current_allocated_components);
+            }
+
+            SP_component *c_glyph = &glyph->components[glyph->number_of_components];
+
             flags = get_u16(font);
             flags = get_u16(font);
             uint16_t glyph_index = get_u16(font);
             uint16_t glyph_index = get_u16(font);
 
 
-            int16_t arg1, arg2;
-
-            int x_scale, y_scale, scale01, scale10;
-            x_scale = y_scale = scale01 = scale10 = 1;
+            c_glyph->scale_x = c_glyph->scale_y = c_glyph->scale01 = c_glyph->scale10 = 1;
 
 
             if (flags & ARG_1_AND_2_ARE_WORDS) { // args are words
             if (flags & ARG_1_AND_2_ARE_WORDS) { // args are words
                 if (flags & ARGS_ARE_XY_VALUES) { // args are signed offsets
                 if (flags & ARGS_ARE_XY_VALUES) { // args are signed offsets
-                    arg1 = get_i16(font);
-                    arg2 = get_i16(font);
+                    c_glyph->arg1 = get_i16(font);
+                    c_glyph->arg2 = get_i16(font);
                 } else { // ------------------------ args are point indecies
                 } else { // ------------------------ args are point indecies
-                    arg1 = get_u16(font);
-                    arg2 = get_u16(font);
+                    c_glyph->arg1 = get_u16(font);
+                    c_glyph->arg2 = get_u16(font);
                 }
                 }
             } else { // args are bytes
             } else { // args are bytes
                 if (flags & ARGS_ARE_XY_VALUES) {
                 if (flags & ARGS_ARE_XY_VALUES) {
-                    arg1 = get_i8(font);
-                    arg2 = get_i8(font);
+                    c_glyph->arg1 = get_i8(font);
+                    c_glyph->arg2 = get_i8(font);
                 } else {
                 } else {
-                    arg1 = get_u8(font);
-                    arg2 = get_u8(font);
+                    c_glyph->arg1 = get_u8(font);
+                    c_glyph->arg2 = get_u8(font);
                 }
                 }
             }
             }
 
 
             if (flags & WE_HAVE_A_SCALE) { // we have a scale
             if (flags & WE_HAVE_A_SCALE) { // we have a scale
-                x_scale = y_scale = (int)get_F2DOT14(font);
+                c_glyph->scale_x = c_glyph->scale_y = (int)get_F2DOT14(font);
             } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { // seperate x and y scales
             } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { // seperate x and y scales
-                x_scale = (int)get_F2DOT14(font);
-                y_scale = (int)get_F2DOT14(font);
+                c_glyph->scale_x = (int)get_F2DOT14(font);
+                c_glyph->scale_y = (int)get_F2DOT14(font);
             } else if (flags & WE_HAVE_A_TWO_BY_TWO) { // 2x2 transform
             } else if (flags & WE_HAVE_A_TWO_BY_TWO) { // 2x2 transform
-                x_scale = (int)get_F2DOT14(font);
-                scale01 = (int)get_F2DOT14(font);
-                scale10 = (int)get_F2DOT14(font);
-                y_scale = (int)get_F2DOT14(font);
+                c_glyph->scale_x = (int)get_F2DOT14(font);
+                c_glyph->scale01 = (int)get_F2DOT14(font);
+                c_glyph->scale10 = (int)get_F2DOT14(font);
+                c_glyph->scale_y = (int)get_F2DOT14(font);
             }
             }
 
 
-            if (!(flags & MORE_COMPONENTS)) { // this is the last glyph, stop reading (please&thankyou)
+            if (!(flags & MORE_COMPONENTS)) { // this is the last c_glyph, stop reading (please&thankyou)
                 reading_glyphs = 0;
                 reading_glyphs = 0;
             }
             }
         }
         }
@@ -177,6 +195,8 @@ void read_glyph(SP_font *font, int current_glyph){
         return;
         return;
     }
     }
 
 
+    glyph->is_composite = 0;
+
     glyph->contour_end_indicies = malloc(sizeof(int) * glyph->number_of_contours);
     glyph->contour_end_indicies = malloc(sizeof(int) * glyph->number_of_contours);
 
 
     for (int i = 0; i < (int)glyph->number_of_contours; ++i){
     for (int i = 0; i < (int)glyph->number_of_contours; ++i){
@@ -406,6 +426,18 @@ SP_font SP_load_font(char *filename){
 void SP_free_font(SP_font *font){
 void SP_free_font(SP_font *font){
     free(font->buffer);
     free(font->buffer);
     free(font->glyph_offsets);
     free(font->glyph_offsets);
+    
+    for (int i = 0; i < font->number_of_glyphs; ++i){
+        if (font->glyphs[i].is_composite){
+            free(font->glyphs[i].contour_end_indicies);
+            free(font->glyphs[i].flags);
+            free(font->glyphs[i].x_coords);
+            free(font->glyphs[i].y_coords);
+        } else {
+            free(font->glyphs[i].components);
+        }    
+    }
+    
     free(font->glyphs);
     free(font->glyphs);
     free(font->unicode_to_glyph_indicies);
     free(font->unicode_to_glyph_indicies);
 }
 }