]> git.cworth.org Git - spritext/blobdiff - spritext.c
Account for x_bearing/y_bearing to align each glyph properly
[spritext] / spritext.c
index 39c05a59cf3417056d899ea23acd245b840d500a..21d77f54df6e9036cd690566c716a97751a62313 100644 (file)
 #define TRUE (1==1)
 #define FALSE (!TRUE)
 
-#if USE_CGIC
-static cairo_status_t
-stdio_write (void *closure, const unsigned char *data, unsigned int length);
-#endif
-
 static double
-get_max_width (cairo_t *cr, const char *characters)
+get_max_width (cairo_t *cr, const char *characters, int num_characters)
 {
     int i;
     double max_width = 0.;
     char string[2];
     string[1] = '\0';
-    for (i = 0; i < ARRAY_SIZE(characters); i++) {
+    for (i = 0; i < num_characters; i++) {
        cairo_text_extents_t extents;
        string[0] = characters[i];
        cairo_text_extents (cr, string, &extents);
@@ -42,18 +37,16 @@ get_max_width (cairo_t *cr, const char *characters)
 }
 
 static double
-get_max_height (cairo_t *cr, const char *characters)
+get_max_height (cairo_t *cr, const char *characters, int num_characters)
 {
     int i;
     double max_height = 0.;
     char string[2];
     string[1] = '\0';
-    for (i = 0; i < ARRAY_SIZE(characters); i++) {
+    for (i = 0; i < num_characters; i++) {
        cairo_text_extents_t extents;
        string[0] = characters[i];
        cairo_text_extents (cr, string, &extents);
-//    if ((extents.height - extents.y_bearing) > max_height)
-//      max_height = extents.height - extents.y_bearing;
        if ((extents.height) > max_height)
            max_height = extents.height;
     }
@@ -75,9 +68,9 @@ parse_args (args_t *args)
 {
     /* First some defaults */
     args->family = "Vera";
-    args->size = 20;
+    args->size = 40;
     args->color.red = 0.0;
-    args->color.green = 0.0;
+    args->color.green = 0.3;
     args->color.blue = 0.0;
 
     /* XXX: Next, we should override the defaults based on
@@ -139,7 +132,7 @@ load_ft_face_for_family (const char *family)
 
 static void
 get_characters_max_width_height (FT_Face ft_face, double size,
-                                const char *characters,
+                                const char *characters, int num_characters,
                                 double *max_width, double *max_height)
 {
     cairo_surface_t *surface;
@@ -151,11 +144,6 @@ get_characters_max_width_height (FT_Face ft_face, double size,
 
     cr = cairo_create (surface);
 
-/*
-  cairo_select_font_face (cr, fontname,
-  CAIRO_FONT_SLANT_NORMAL,
-  CAIRO_FONT_WEIGHT_NORMAL);
-*/
     cr_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
     cairo_set_font_face (cr, cr_face);
 
@@ -163,8 +151,8 @@ get_characters_max_width_height (FT_Face ft_face, double size,
 
     cairo_set_line_width (cr, 1.0);
 
-    *max_width = get_max_width(cr, characters);
-    *max_height = get_max_height(cr, characters);
+    *max_width = get_max_width(cr, characters, num_characters);
+    *max_height = get_max_height(cr, characters, num_characters);
 
     cairo_font_face_destroy (cr_face);
 
@@ -173,11 +161,60 @@ get_characters_max_width_height (FT_Face ft_face, double size,
     cairo_surface_destroy(surface);
 }
 
+static void
+draw_character_table (cairo_t *cr,
+                     FT_Face ft_face, double size,
+                     const char *characters, int num_characters,
+                     double character_width, double character_height)
+{
+    cairo_font_face_t *cr_face;
+    int i;
+
+    cr_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
+    cairo_set_font_face (cr, cr_face);
+
+    cairo_set_font_size (cr, size);
+
+    cairo_text_extents_t extents;
+    double x = 0.0;
+    double y = 0.0;
+
+    char string[2];
+    string[1] = '\0';
+
+    cairo_set_line_width (cr, 2.0);
+    for (i = 0; i < num_characters; i++)
+    {
+       cairo_rectangle (cr, x, y, character_width, character_height);
+       cairo_stroke_preserve (cr);
+       cairo_save (cr);
+       cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+       cairo_fill (cr);
+       cairo_restore (cr);
+
+       string[0] = characters[i];
+
+       cairo_text_extents (cr, string, &extents);
+
+       cairo_move_to (cr, x - extents.x_bearing, y - extents.y_bearing);
+       cairo_show_text (cr, string);
+
+       if ((i+1) % 10 == 0)
+       {
+           x = 0.;
+           y += character_height;
+       } else {
+           x += character_width;
+       }
+    }
+
+    cairo_scale (cr, 1, -1);
+    cairo_push_group (cr);
+}
+
 int
 main (void)
 {
-    char outputJson = FALSE;
-
     char characters[] = {
        '!', '"', '#', '$', '%', '&','\'', '(',
        ')', '*', '+', ',', '-', '.', '/', '0',
@@ -193,192 +230,35 @@ main (void)
        'y', 'z', '{', '|', '}', '~'
     };
 
-    int i;
     args_t args;
     FT_Face ft_face;
-    FT_UInt     left_index, right_index;
-    FT_Bool     use_kerning;
-    FT_Vector   kerning;
     double max_width, max_height;
     cairo_surface_t *surface;
     cairo_t *cr;
-    cairo_font_face_t *cr_face;
 
     parse_args (&args);
 
-#if USE_CGIC
-    if (outputJson)
-    {
-       cgiHeaderContentType("application/json");
-    } else {
-       cgiHeaderContentType("image/png");
-    }
-#endif
-
     ft_face = load_ft_face_for_family (args.family);
 
-    use_kerning = FT_HAS_KERNING( ft_face );
-
     get_characters_max_width_height (ft_face, args.size,
-                                    characters,
+                                    characters, ARRAY_SIZE (characters),
                                     &max_width, &max_height);
 
     /* Draw */
     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                         (max_width + 8) * 10,
-                                         (max_height + 8) * 10);
+                                         max_width * 10,
+                                         max_height * 10);
 
     cr = cairo_create (surface);
 
-/*
-  cairo_select_font_face (cr, fontname,
-  CAIRO_FONT_SLANT_NORMAL,
-  CAIRO_FONT_WEIGHT_NORMAL);
-*/
-    cr_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
-    cairo_set_font_face (cr, cr_face);
-
-    cairo_set_font_size (cr, args.size);
-
-    cairo_text_extents_t extents;
-    double x = 0.0;
-    double y = 0.0;
-
-    if (outputJson)
-       printf("{");
-
-    cairo_translate (cr, 0, -(max_height / 2.50));
-
-//    cairo_translate (cr, 0, -5.0);
-
-    char string[2];
-    string[1] = '\0';
-    for (i = 0; i < ARRAY_SIZE(characters); i++)
-    {
-       if (i % 10 == 0)
-       {
-           x = 0.;
-           y += max_height + 8;
-       }
-       string[0] = characters[i];
-
-       cairo_text_extents (cr, string, &extents);
-
-       if (outputJson)
-       {
-           if (i > 0)
-               printf (",\n");
-           printf ("u%i:{", characters[i]);
-           printf ("x:%.1f,y:%.1f,w:%.1f,h:%.1f",
-                   x,
-                   y - (max_height * 1.15),
-                   extents.width + extents.x_bearing,
-                   extents.height);
-           int j;
-           for ( j = 0; j < ARRAY_SIZE(characters); j++ )
-           {
-               right_index = FT_Get_Char_Index( ft_face, characters[i] );
-               left_index = FT_Get_Char_Index( ft_face, characters[j] );
-    
-               FT_Get_Kerning( ft_face, left_index, right_index,
-                               FT_KERNING_UNSCALED, &kerning );
-    
-               if ( kerning.x )
-                   printf(",k%d:%ld", characters[j], kerning.x);
-           }
-
-           printf ("}");
-       }
-
-       x -= extents.x_bearing;
-  
-       cairo_move_to (cr, x, y);
-       cairo_set_source_rgb (cr, 0., 0., 0.); // black
-       cairo_set_source_rgb (cr,
-                             args.color.red,
-                             args.color.green,
-                             args.color.blue);
-       cairo_text_path (cr, string);
-       cairo_fill (cr);
-
-       x += extents.x_bearing;
-       x += max_width + 8;
-    }
-
-/*
-  int thick_width = 4;
-  int thin_width = 0;
-
-  for (c = 'A'; c <= 'I'; c++)
-  {
-  string[0] = c;
-  int spacing = ((c - 'A') * letterspacing) + 1;
-
-
-  cairo_save(cr);
+    cairo_set_source_rgb (cr,
+                         args.color.red,
+                         args.color.green,
+                         args.color.blue);
 
-  cairo_move_to (cr, spacing, 0);
-  cairo_text_path (cr, string);
-//      cairo_set_source_rgb (cr, 0.1, 0.2, 0.2); // gray
-cairo_set_source_rgb (cr, 0.8, 0.8, 0.85); // silver
-cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
-
-cairo_push_group (cr);
-cairo_set_line_width (cr, thick_width);
-cairo_stroke_preserve (cr);
-cairo_set_line_width (cr, thin_width);
-cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-cairo_stroke_preserve (cr);
-cairo_fill (cr);
-cairo_pop_group_to_source (cr);
-
-cairo_paint (cr);
-
-cairo_restore(cr);
-
-cairo_move_to (cr, spacing, 0);
-cairo_text_path (cr, string);
-cairo_set_source_rgb (cr, 0.4, 0.45, 0.7); // blue
-
-cairo_fill (cr);
-}
-*/
-
-    cairo_scale (cr, 1, -1);
-    cairo_push_group (cr);
-/*
-
-cairo_pattern_t *gradient;
-
-for (i = 0; i < 9; i++)
-{
-char c[2];
-strncpy(c, STRING + i, 1);
-c[1] = '\0';
-int spacing = (i * letterspacing) + 1;
-cairo_move_to (cr, spacing, -3);
-cairo_show_text (cr, c);
-
-}
-cairo_pop_group_to_source (cr);
-
-gradient = cairo_pattern_create_linear (0, 0, 0, -fontsize);
-cairo_pattern_add_color_stop_rgba (gradient, 0.0, 1, 1, 1, 0.5);
-cairo_pattern_add_color_stop_rgba (gradient, 0.7, 1, 1, 1, 0.0);
-
-cairo_mask (cr, gradient);
-
-cairo_pattern_destroy (gradient);
-*/
-
-#if USE_CGIC
-    if (outputJson)
-    {
-       printf("}");
-    } else {
-       cairo_surface_write_to_png_stream (surface, stdio_write, cgiOut);
-    }
-#endif
+    draw_character_table (cr, ft_face, args.size,
+                         characters, ARRAY_SIZE (characters),
+                         max_width, max_height);
 
     cairo_surface_write_to_png (surface, "spritext-output.png");
     printf ("Result written to spritext-output.png\n");
@@ -389,15 +269,3 @@ cairo_pattern_destroy (gradient);
 
     return 0;
 }
-
-#if USE_CGIC
-static cairo_status_t
-stdio_write (void *closure, const unsigned char *data, unsigned int length)
-{
-    FILE *file = closure;
-    if (fwrite (data, 1, length, file) == length)
-       return CAIRO_STATUS_SUCCESS;
-    else
-       return CAIRO_STATUS_WRITE_ERROR;
-}
-#endif