]> git.cworth.org Git - spritext/blobdiff - spritext.c
Move font loading into its own function
[spritext] / spritext.c
index ebfa8ead044fef4a1b32ea23c08159b6229750ff..62e1d2f681539976672a8c3103c18bd414801604 100644 (file)
@@ -6,7 +6,6 @@
 #include <libgen.h>
 #include <cairo.h>
 #include <cairo-ft.h>
-#include <cgic.h>
 
 #ifndef CAIRO_HAS_PNG_FUNCTIONS
 #error This program requires cairo with PNG support
 #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
 
 double
 get_max_width (cairo_t *cr, char *characters);
@@ -29,8 +30,85 @@ get_max_width (cairo_t *cr, char *characters);
 double
 get_max_height (cairo_t *cr, char *characters);
 
+typedef struct {
+    char *family;
+    double size;
+    struct {
+       double red;
+       double green;
+       double blue;
+    } color;
+} args_t;
+
+static void
+parse_args (args_t *args)
+{
+    /* First some defaults */
+    args->family = "Vera";
+    args->size = 20;
+    args->color.red = 0.0;
+    args->color.green = 0.0;
+    args->color.blue = 0.0;
+
+    /* XXX: Next, we should override the defaults based on
+     * command-line arguments. */
+
+    /* XXX: Finally, we'll want to allow CGI-based arguments as
+     * well. */
+#if USE_CGIG
+    /* QueryString */
+    int fontsize;
+    char format[5];
+    char fillcolor[20];
+    char fontname[20];
+    cgiFormStringNoNewlines("fontname", fontname, 20);
+    cgiFormInteger("fontsize", &fontsize, 50);
+    cgiFormStringNoNewlines("format", format, 5);
+    cgiFormStringNoNewlines("fillcolor", fillcolor, 20);
+
+    int fillcolor_red;
+    int fillcolor_green;
+    int fillcolor_blue;
+    sscanf (fillcolor, " rgb : %d , %d , %d ", &fillcolor_red, &fillcolor_green, &fillcolor_blue);
+    if ( format[0] == 'j' && format[1] == 's' && format[2] == 'o' && format[3] == 'n' )
+       outputJson = TRUE;
+#endif
+}
+
+static FT_Face
+load_ft_face_for_family (const char *family)
+{
+    /* XXX: Instead of a hard-coded filename here, we should really be
+     * taking family and using fontconfig to map that to a
+     * filename. */
+    const char font_filename[] = "./Vera.ttf";
+
+    int error;
+    FT_Face     ft_face;
+    FT_Library         library;
+
+    error = FT_Init_FreeType( &library );
+    if ( error ) {
+       fprintf (stderr, "Fatal error initializing freetype.\n");
+       exit (1);
+    }
+
+    error = FT_New_Face( library, font_filename,
+                         0,
+                         &ft_face );
+    if ( error == FT_Err_Unknown_File_Format ) {
+        fprintf (stderr, "Unsupported font format: %s\n", font_filename);
+       exit (1);
+    } else if ( error ) {
+        fprintf (stderr, "Failed to open file: %s\n", font_filename);
+       exit (1);
+    }
+
+    return ft_face;
+}
+
 int
-cgiMain ()
+main (void)
 {
     char outputJson = FALSE;
 
@@ -50,50 +128,24 @@ cgiMain ()
     };
 
     int i;
+    args_t args;
+    FT_Face ft_face;
+    FT_UInt     left_index, right_index;
+    FT_Bool     use_kerning;
+    FT_Vector   kerning;
 
-    /* QueryString */
-    char fontname[20];
-    int fontsize;
-    char format[5];
-    char fillcolor[20];
-    cgiFormStringNoNewlines("fontname", fontname, 20);
-    cgiFormInteger("fontsize", &fontsize, 50);
-    cgiFormStringNoNewlines("format", format, 5);
-    cgiFormStringNoNewlines("fillcolor", fillcolor, 20);
-
-    int fillcolor_red;
-    int fillcolor_green;
-    int fillcolor_blue;
-    sscanf (fillcolor, " rgb : %d , %d , %d ", &fillcolor_red, &fillcolor_green, &fillcolor_blue);
-
-    if ( format[0] == 'j' && format[1] == 's' && format[2] == 'o' && format[3] == 'n' )
-       outputJson = TRUE;
+    parse_args (&args);
 
+#if USE_CGIC
     if (outputJson)
     {
        cgiHeaderContentType("application/json");
     } else {
        cgiHeaderContentType("image/png");
     }
+#endif
 
-    int error;  
-    FT_Library         library;
-    FT_Face    ft_face;
-    FT_Bool     use_kerning;
-    FT_UInt     left_index, right_index;
-    FT_Vector   kerning;
-
-    error = FT_Init_FreeType( &library );
-    if ( error )
-       printf("error");
-
-    error = FT_New_Face( library,"/srv/rdworth.org/cgi-bin/Verdana.ttf",
-                         0,
-                         &ft_face );
-    if ( error == FT_Err_Unknown_File_Format )
-        printf("File opened. Font format unsupported.");
-    else if ( error )
-        printf("Could not be open or read or broken.");
+    ft_face = load_ft_face_for_family (args.family);
 
     use_kerning = FT_HAS_KERNING( ft_face );
 
@@ -115,7 +167,7 @@ cgiMain ()
     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, fontsize);
+    cairo_set_font_size (cr, args.size);
 
     cairo_set_line_width (cr, 1.0);
 
@@ -143,7 +195,7 @@ cgiMain ()
     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, fontsize);
+    cairo_set_font_size (cr, args.size);
 
     cairo_text_extents_t extents;
     double x = 0.0;
@@ -189,7 +241,7 @@ cgiMain ()
                                FT_KERNING_UNSCALED, &kerning );
     
                if ( kerning.x )
-                   printf(",k%d:%d", characters[j], kerning.x);
+                   printf(",k%d:%ld", characters[j], kerning.x);
            }
 
            printf ("}");
@@ -199,10 +251,10 @@ cgiMain ()
   
        cairo_move_to (cr, x, y);
        cairo_set_source_rgb (cr, 0., 0., 0.); // black
-       if ( 0 <= fillcolor_red && fillcolor_red <= 255.0
-            && 0 <= fillcolor_green && fillcolor_green <= 255.0
-            && 0 <= fillcolor_blue && fillcolor_blue <= 255.0 )
-           cairo_set_source_rgb (cr, fillcolor_red / 255.0, fillcolor_green / 255.0, fillcolor_blue / 255.0);
+       cairo_set_source_rgb (cr,
+                             args.color.red,
+                             args.color.green,
+                             args.color.blue);
        cairo_text_path (cr, string);
        cairo_fill (cr);
 
@@ -275,12 +327,18 @@ 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
+
+    cairo_surface_write_to_png (surface, "spritext-output.png");
+    printf ("Result written to spritext-output.png\n");
 
     cairo_destroy (cr);
 
@@ -289,6 +347,7 @@ cairo_pattern_destroy (gradient);
     return 0;
 }
 
+#if USE_CGIC
 static cairo_status_t
 stdio_write (void *closure, const unsigned char *data, unsigned int length)
 {
@@ -298,6 +357,7 @@ stdio_write (void *closure, const unsigned char *data, unsigned int length)
     else
        return CAIRO_STATUS_WRITE_ERROR;
 }
+#endif
 
 double
 get_max_width(cairo_t *cr, char *characters)