]> git.cworth.org Git - spritext/blob - spritext.c
Rip out the libcgic stuff
[spritext] / spritext.c
1 /* XXX: Copyright/license blurb needed here */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <libgen.h>
7 #include <cairo.h>
8 #include <cairo-ft.h>
9
10 #ifndef CAIRO_HAS_PNG_FUNCTIONS
11 #error This program requires cairo with PNG support
12 #endif
13
14 #include <ft2build.h>
15 #include FT_FREETYPE_H
16
17 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
18
19 #define TRUE (1==1)
20 #define FALSE (!TRUE)
21
22 #if USE_CGIC
23 static cairo_status_t
24 stdio_write (void *closure, const unsigned char *data, unsigned int length);
25 #endif
26
27 double
28 get_max_width (cairo_t *cr, char *characters);
29
30 double
31 get_max_height (cairo_t *cr, char *characters);
32
33 int
34 main (void)
35 {
36     char outputJson = FALSE;
37
38     char characters[] = {
39         '!', '"', '#', '$', '%', '&','\'', '(',
40         ')', '*', '+', ',', '-', '.', '/', '0',
41         '1', '2', '3', '4', '5', '6', '7', '8',
42         '9', ':', ';', '<', '=', '>', '?', '@',
43         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
44         'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
45         'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
46         'Y', 'Z', '[','\\', ']', '^', '_', '`',
47         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
48         'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
49         'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
50         'y', 'z', '{', '|', '}', '~'
51     };
52
53     int i;
54
55     /* QueryString */
56     int fontsize;
57     char format[5];
58     char fillcolor[20];
59
60 #if USE_CGIG
61     char fontname[20];
62     cgiFormStringNoNewlines("fontname", fontname, 20);
63     cgiFormInteger("fontsize", &fontsize, 50);
64     cgiFormStringNoNewlines("format", format, 5);
65     cgiFormStringNoNewlines("fillcolor", fillcolor, 20);
66 #endif
67
68     int fillcolor_red;
69     int fillcolor_green;
70     int fillcolor_blue;
71     sscanf (fillcolor, " rgb : %d , %d , %d ", &fillcolor_red, &fillcolor_green, &fillcolor_blue);
72
73     if ( format[0] == 'j' && format[1] == 's' && format[2] == 'o' && format[3] == 'n' )
74         outputJson = TRUE;
75
76 #if USE_CGIC
77     if (outputJson)
78     {
79         cgiHeaderContentType("application/json");
80     } else {
81         cgiHeaderContentType("image/png");
82     }
83 #endif
84
85     int error;  
86     FT_Library  library;
87     FT_Face     ft_face;
88     FT_Bool     use_kerning;
89     FT_UInt     left_index, right_index;
90     FT_Vector   kerning;
91
92     error = FT_Init_FreeType( &library );
93     if ( error )
94         printf("error");
95
96     error = FT_New_Face( library,"/srv/rdworth.org/cgi-bin/Verdana.ttf",
97                          0,
98                          &ft_face );
99     if ( error == FT_Err_Unknown_File_Format )
100         printf("File opened. Font format unsupported.");
101     else if ( error )
102         printf("Could not be open or read or broken.");
103
104     use_kerning = FT_HAS_KERNING( ft_face );
105
106     /* Compute max-width and max-height */
107     cairo_surface_t *surface;
108     cairo_t *cr;
109     cairo_font_face_t *cr_face;
110
111     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
112                                           1, 1);
113
114     cr = cairo_create (surface);
115
116 /*
117   cairo_select_font_face (cr, fontname,
118   CAIRO_FONT_SLANT_NORMAL,
119   CAIRO_FONT_WEIGHT_NORMAL);
120 */
121     cr_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
122     cairo_set_font_face (cr, cr_face);
123
124     cairo_set_font_size (cr, fontsize);
125
126     cairo_set_line_width (cr, 1.0);
127
128     double max_width = get_max_width(cr, characters);
129     double max_height = get_max_height(cr, characters);
130
131     cairo_font_face_destroy (cr_face);
132
133     cairo_destroy (cr);
134
135     cairo_surface_destroy(surface);
136
137     /* Draw */
138     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
139                                           (max_width + 8) * 10,
140                                           (max_height + 8) * 10);
141
142     cr = cairo_create (surface);
143
144 /*
145   cairo_select_font_face (cr, fontname,
146   CAIRO_FONT_SLANT_NORMAL,
147   CAIRO_FONT_WEIGHT_NORMAL);
148 */
149     cr_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
150     cairo_set_font_face (cr, cr_face);
151
152     cairo_set_font_size (cr, fontsize);
153
154     cairo_text_extents_t extents;
155     double x = 0.0;
156     double y = 0.0;
157
158     if (outputJson)
159         printf("{");
160
161     cairo_translate (cr, 0, -(max_height / 2.50));
162
163 //    cairo_translate (cr, 0, -5.0);
164
165     char string[2];
166     string[1] = '\0';
167     for (i = 0; i < ARRAY_SIZE(characters); i++)
168     {
169         if (i % 10 == 0)
170         {
171             x = 0.;
172             y += max_height + 8;
173         }
174         string[0] = characters[i];
175
176         cairo_text_extents (cr, string, &extents);
177
178         if (outputJson)
179         {
180             if (i > 0)
181                 printf (",\n");
182             printf ("u%i:{", characters[i]);
183             printf ("x:%.1f,y:%.1f,w:%.1f,h:%.1f",
184                     x,
185                     y - (max_height * 1.15),
186                     extents.width + extents.x_bearing,
187                     extents.height);
188             int j;
189             for ( j = 0; j < ARRAY_SIZE(characters); j++ )
190             {
191                 right_index = FT_Get_Char_Index( ft_face, characters[i] );
192                 left_index = FT_Get_Char_Index( ft_face, characters[j] );
193     
194                 FT_Get_Kerning( ft_face, left_index, right_index,
195                                 FT_KERNING_UNSCALED, &kerning );
196     
197                 if ( kerning.x )
198                     printf(",k%d:%ld", characters[j], kerning.x);
199             }
200
201             printf ("}");
202         }
203
204         x -= extents.x_bearing;
205   
206         cairo_move_to (cr, x, y);
207         cairo_set_source_rgb (cr, 0., 0., 0.); // black
208         if ( 0 <= fillcolor_red && fillcolor_red <= 255.0
209              && 0 <= fillcolor_green && fillcolor_green <= 255.0
210              && 0 <= fillcolor_blue && fillcolor_blue <= 255.0 )
211             cairo_set_source_rgb (cr, fillcolor_red / 255.0, fillcolor_green / 255.0, fillcolor_blue / 255.0);
212         cairo_text_path (cr, string);
213         cairo_fill (cr);
214
215         x += extents.x_bearing;
216         x += max_width + 8;
217     }
218
219 /*
220   int thick_width = 4;
221   int thin_width = 0;
222
223   for (c = 'A'; c <= 'I'; c++)
224   {
225   string[0] = c;
226   int spacing = ((c - 'A') * letterspacing) + 1;
227
228
229   cairo_save(cr);
230
231   cairo_move_to (cr, spacing, 0);
232   cairo_text_path (cr, string);
233 //      cairo_set_source_rgb (cr, 0.1, 0.2, 0.2); // gray
234 cairo_set_source_rgb (cr, 0.8, 0.8, 0.85); // silver
235 cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
236
237 cairo_push_group (cr);
238 cairo_set_line_width (cr, thick_width);
239 cairo_stroke_preserve (cr);
240 cairo_set_line_width (cr, thin_width);
241 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
242 cairo_stroke_preserve (cr);
243 cairo_fill (cr);
244 cairo_pop_group_to_source (cr);
245
246 cairo_paint (cr);
247
248 cairo_restore(cr);
249
250 cairo_move_to (cr, spacing, 0);
251 cairo_text_path (cr, string);
252 cairo_set_source_rgb (cr, 0.4, 0.45, 0.7); // blue
253
254 cairo_fill (cr);
255 }
256 */
257
258     cairo_scale (cr, 1, -1);
259     cairo_push_group (cr);
260 /*
261
262 cairo_pattern_t *gradient;
263
264 for (i = 0; i < 9; i++)
265 {
266 char c[2];
267 strncpy(c, STRING + i, 1);
268 c[1] = '\0';
269 int spacing = (i * letterspacing) + 1;
270 cairo_move_to (cr, spacing, -3);
271 cairo_show_text (cr, c);
272
273 }
274 cairo_pop_group_to_source (cr);
275
276 gradient = cairo_pattern_create_linear (0, 0, 0, -fontsize);
277 cairo_pattern_add_color_stop_rgba (gradient, 0.0, 1, 1, 1, 0.5);
278 cairo_pattern_add_color_stop_rgba (gradient, 0.7, 1, 1, 1, 0.0);
279
280 cairo_mask (cr, gradient);
281
282 cairo_pattern_destroy (gradient);
283 */
284
285 #if USE_CGIC
286     if (outputJson)
287     {
288         printf("}");
289     } else {
290         cairo_surface_write_to_png_stream (surface, stdio_write, cgiOut);
291     }
292 #endif
293
294     cairo_destroy (cr);
295
296     cairo_surface_destroy (surface);
297
298     return 0;
299 }
300
301 #if USE_CGIC
302 static cairo_status_t
303 stdio_write (void *closure, const unsigned char *data, unsigned int length)
304 {
305     FILE *file = closure;
306     if (fwrite (data, 1, length, file) == length)
307         return CAIRO_STATUS_SUCCESS;
308     else
309         return CAIRO_STATUS_WRITE_ERROR;
310 }
311 #endif
312
313 double
314 get_max_width(cairo_t *cr, char *characters)
315 {
316     int i;
317     double max_width = 0.;
318     char string[2];
319     string[1] = '\0';
320     for (i = 0; i < ARRAY_SIZE(characters); i++) {
321         cairo_text_extents_t extents;
322         string[0] = characters[i];
323         cairo_text_extents (cr, string, &extents);
324         if ((extents.width + (extents.x_bearing * 2)) > max_width)
325             max_width = extents.width + (extents.x_bearing * 2);
326     }
327     return max_width;
328 }
329
330 double
331 get_max_height(cairo_t *cr, char *characters)
332 {
333     int i;
334     double max_height = 0.;
335     char string[2];
336     string[1] = '\0';
337     for (i = 0; i < ARRAY_SIZE(characters); i++) {
338         cairo_text_extents_t extents;
339         string[0] = characters[i];
340         cairo_text_extents (cr, string, &extents);
341 //    if ((extents.height - extents.y_bearing) > max_height)
342 //      max_height = extents.height - extents.y_bearing;
343         if ((extents.height) > max_height)
344             max_height = extents.height;
345     }
346     return max_height;
347 }
348