Browse Source

fixed empty glyph reading bug

IverMartinson 4 months ago
parent
commit
cbe5ee2bdd
6 changed files with 36 additions and 22 deletions
  1. BIN
      build/libsourparse.so
  2. BIN
      build/main.bin
  3. 3 2
      readme.md
  4. 1 0
      src/headers/sourparse.h
  5. 2 2
      src/launch_program/main.c
  6. 30 18
      src/library/sourparse.c

BIN
build/libsourparse.so


BIN
build/main.bin


+ 3 - 2
readme.md

@@ -6,6 +6,7 @@ World's Best TTF Parser, 2025
 ### Todo List
 ### Todo List
 
 
 - [x] 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)
+- [x] [NOTE: not doing this. It's fine for the user to just read it themselves] 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)
+- [x] read glyph position data (kerning, width to move, etc)

+ 1 - 0
src/headers/sourparse.h

@@ -12,6 +12,7 @@ typedef struct {
 typedef struct {
 typedef struct {
     int *x_coords, *y_coords, *contour_end_indicies; 
     int *x_coords, *y_coords, *contour_end_indicies; 
     int number_of_points, number_of_contours, number_of_components;
     int number_of_points, number_of_contours, number_of_components;
+    int advance_width;
     uint8_t *flags;
     uint8_t *flags;
     int16_t x_min, y_min, x_max, y_max;
     int16_t x_min, y_min, x_max, y_max;
     SP_component *components;
     SP_component *components;

+ 2 - 2
src/launch_program/main.c

@@ -2,10 +2,10 @@
 
 
 int main(){
 int main(){
     SP_font *cal_sans = SP_load_font("fonts/CalSans-Regular.ttf");
     SP_font *cal_sans = SP_load_font("fonts/CalSans-Regular.ttf");
-    SP_font *jetbrains_mono = SP_load_font("fonts/JetBrainsMono-Regular.ttf");
+    // SP_font *jetbrains_mono = SP_load_font("fonts/JetBrainsMono-Regular.ttf");
     
     
     SP_free_font(cal_sans);
     SP_free_font(cal_sans);
-    SP_free_font(jetbrains_mono);
+    // SP_free_font(jetbrains_mono);
 
 
     return 0;
     return 0;
 }
 }

+ 30 - 18
src/library/sourparse.c

@@ -106,9 +106,15 @@ void read_glyph(SP_font *font, int current_glyph){
     int glyph_end   = font->glyph_offsets[current_glyph + 1];
     int glyph_end   = font->glyph_offsets[current_glyph + 1];
     
     
     font->current_byte = glyph_start;
     font->current_byte = glyph_start;
-
+    
     SP_glyph *glyph = &font->glyphs[current_glyph];
     SP_glyph *glyph = &font->glyphs[current_glyph];
-
+    
+    if (glyph_start == glyph_end){
+        glyph->number_of_contours = 0;
+        
+        return;
+    }
+    
     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
@@ -116,7 +122,7 @@ void read_glyph(SP_font *font, int current_glyph){
     glyph->y_min = get_i16(font);
     glyph->y_min = get_i16(font);
     glyph->x_max = get_i16(font);
     glyph->x_max = get_i16(font);
     glyph->y_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;
         glyph->is_composite = 1;
@@ -212,7 +218,13 @@ void read_glyph(SP_font *font, int current_glyph){
         }
         }
     }
     }
 
 
-    if (glyph->number_of_contours == 0) return; // we still want to skip the instructions so that we dont get offset
+    // we still want to skip the instructions so that we dont get offset.
+    // also set point count to 0
+    if (glyph->number_of_contours == 0){
+        glyph->number_of_points = 0;
+        
+        return; 
+    } 
 
 
     // add one because these are 0-indexed indicies.
     // add one because these are 0-indexed indicies.
     // the last one is the highest index
     // the last one is the highest index
@@ -386,26 +398,26 @@ SP_font* SP_load_font(char *filename){
             
             
             int highest_code = end_codes[seg_count - 1];
             int highest_code = end_codes[seg_count - 1];
 
 
-            font->unicode_to_glyph_indicies = malloc(sizeof(uint16_t) * highest_code);
+            font->unicode_to_glyph_indicies = malloc(sizeof(uint16_t) * highest_code + 10);
 
 
             // loop over segments.
             // loop over segments.
             // a segment is a range of unicode characters that are all mapped with the same formula.
             // a segment is a range of unicode characters that are all mapped with the same formula.
             // i dont understand this at all
             // i dont understand this at all
-            for (int i = 0; i < (int)seg_count; ++i) {
-                int start_code = start_codes[i];
-                int end_code = end_codes[i];
-                
-                uint16_t glyph_index = 0;
-
-                for (int j = start_code; j < end_code; j++){
-                    // if range offset is zero, the id comes from glyph id array
-                    if (id_range_offsets[i] == 0){
-                        glyph_index = (j + id_deltas[i]) % 65536;
+            for (int i = 0; i < seg_count; i++) {
+                for (int j = start_codes[i]; j <= end_codes[i]; j++) {
+                    uint16_t glyph_index = 0;
+                    if (id_range_offsets[i] == 0) {
+                        glyph_index = (j + id_deltas[i]) & 0xFFFF;
                     } else {
                     } else {
-                        glyph_index = *(id_range_offsets[i]/2 + (j - start_codes[i]) + &id_range_offsets[i]);
-                        glyph_index = (glyph_index + id_deltas[i]) % 65536;
+                        // Compute address relative to this idRangeOffset word
+                        int offset = id_range_offsets[i]/2 + (j - start_codes[i]);
+                        int16_t *glyphIdArray = (int16_t *)(&id_range_offsets[i]);
+                        glyph_index = glyphIdArray[offset];
+
+                        if (glyph_index != 0) {
+                            glyph_index = (glyph_index + id_deltas[i]) & 0xFFFF;
+                        }
                     }
                     }
-                
                     font->unicode_to_glyph_indicies[j] = glyph_index;
                     font->unicode_to_glyph_indicies[j] = glyph_index;
                 }
                 }
             }
             }