head 1.5; access; symbols; locks; strict; comment @ * @; 1.5 date 2005.05.17.15.19.39; author cworth; state Exp; branches; next 1.4; commitid 1f30428a0b8a4567; 1.4 date 2005.04.02.02.06.37; author cworth; state Exp; branches; next 1.3; 1.3 date 2005.01.30.15.29.30; author oandrieu; state Exp; branches; next 1.2; 1.2 date 2005.01.24.20.02.25; author krh; state Exp; branches; next 1.1; 1.1 date 2005.01.24.16.16.51; author cworth; state Exp; branches; next ; desc @@ 1.5 log @ * Makefile: * kapow.c: (bend_it), (make_text_path), (stdio_write), (main): Update to all the latest cairo API changes. @ text @#include #include #include #include #include #include #ifndef CAIRO_HAS_PNG_FUNCTIONS #error This program requires cairo with PNG support #endif #include const char filename[] = "kapow.png"; const char fontname[] = "Sans"; const char default_text[] = "KAPOW"; #define IMAGE_WIDTH 384 #define IMAGE_HEIGHT 256 #define SPIKES 10 #define SHADOW_OFFSET 10 #define X_FUZZ 16 #define Y_FUZZ 16 #define X_OUTER_RADIUS (IMAGE_WIDTH / 2 - X_FUZZ - SHADOW_OFFSET) #define Y_OUTER_RADIUS (IMAGE_HEIGHT / 2 - Y_FUZZ - SHADOW_OFFSET) #define X_INNER_RADIUS (X_OUTER_RADIUS * 0.7) #define Y_INNER_RADIUS (Y_OUTER_RADIUS * 0.7) static void make_star_path (cairo_t *cr) { double x; double y; int i; srand (45); for (i = 0; i < SPIKES * 2; i++) { x = IMAGE_WIDTH / 2 + cos (M_PI * i / SPIKES) * X_INNER_RADIUS + (double) rand() * X_FUZZ / RAND_MAX; y = IMAGE_HEIGHT / 2 + sin (M_PI * i / SPIKES) * Y_INNER_RADIUS + (double) rand() * Y_FUZZ / RAND_MAX; if (i == 0) cairo_move_to (cr, x, y); else cairo_line_to (cr, x, y); i++; x = IMAGE_WIDTH / 2 + cos (M_PI * i / SPIKES) * X_OUTER_RADIUS + (double) rand() * X_FUZZ / RAND_MAX; y = IMAGE_HEIGHT / 2 + sin (M_PI * i / SPIKES) * Y_OUTER_RADIUS + (double) rand() * Y_FUZZ / RAND_MAX; cairo_line_to (cr, x, y); } cairo_close_path (cr); } struct ctx { int first; cairo_t *cr; }; static void bend_it (double *x, double *y) { const double cx = IMAGE_WIDTH / 2, cy = 500; double angle, radius, t; /* We're going to wrap the points around a big circle with center * at (cx, cy), with cy being somewhere well below the visible area. * On top of that, we'll scale up the letters going left to right. */ angle = M_PI / 2 - (double) (*x - cx) / IMAGE_WIDTH; t = 3 * M_PI / 4 - angle + 0.05; angle = 3 * M_PI / 4 - pow (t, 1.8); radius = cy - (IMAGE_HEIGHT / 2 + (*y - IMAGE_HEIGHT / 2) * t * 2); *x = cx + cos (angle) * radius; *y = cy - sin (angle) * radius; } static void make_text_path (cairo_t *cr, double x, double y, const char *text) { cairo_path_t *path; cairo_path_data_t *data; int i; cairo_move_to (cr, x, y); cairo_text_path (cr, text); path = cairo_copy_path_flat (cr); cairo_new_path (cr); for (i=0; i < path->num_data; i += path->data[i].header.length) { data = &path->data[i]; switch (data->header.type) { case CAIRO_PATH_MOVE_TO: x = data[1].point.x; y = data[1].point.y; bend_it (&x, &y); cairo_move_to (cr, x, y); break; case CAIRO_PATH_LINE_TO: x = data[1].point.x; y = data[1].point.y; bend_it (&x, &y); cairo_line_to (cr, x, y); break; case CAIRO_PATH_CLOSE_PATH: cairo_close_path (cr); break; default: assert(0); } } free (path); } 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; } int main (int argc, char *argv[]) { FILE *fp; double x; double y; char text[20]; cairo_text_extents_t extents; cairo_pattern_t *pattern; cairo_surface_t *surface; cairo_t *cr; char *query_string; query_string = getenv ("QUERY_STRING"); if (query_string != NULL) { fp = stdout; sscanf (query_string, "text=%19s", text); } else { fp = fopen (filename, "w"); if (argc == 2) { strncpy (text, argv[1], sizeof text - 1); text [sizeof text - 1] = '\0'; } else { fprintf (stderr, "Usage: %s \n", basename (argv[0])); strcpy (text, default_text); fprintf (stderr, "No exclamation provided, using \"%s\"\n", text); } } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT); cr = cairo_create (surface); cairo_set_line_width (cr, 2); cairo_save (cr); cairo_translate (cr, SHADOW_OFFSET, SHADOW_OFFSET); make_star_path (cr); cairo_set_source_rgba (cr, 0., 0., 0., 0.5); cairo_fill (cr); cairo_restore (cr); make_star_path (cr); pattern = cairo_pattern_create_radial (IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, 10, IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, 230); cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 0.2, 1); cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 0, 0, 1); cairo_set_source (cr, pattern); cairo_fill (cr); make_star_path (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); cairo_select_font_face (cr, fontname, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 50); cairo_text_extents (cr, text, &extents); x = IMAGE_WIDTH / 2 - (extents.width / 2 + extents.x_bearing); y = IMAGE_HEIGHT / 2 - (extents.height / 2 + extents.y_bearing); make_text_path (cr, x, y, text); pattern = cairo_pattern_create_linear (IMAGE_WIDTH / 2 - 10, IMAGE_HEIGHT / 4, IMAGE_WIDTH / 2 + 10, 3 * IMAGE_HEIGHT / 4); cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, 1); cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0.4, 1); cairo_set_source (cr, pattern); cairo_fill (cr); make_text_path (cr, x, y, text); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); if (query_string != NULL) printf ("Content-Type: image/png\n\n"); cairo_surface_write_to_png_stream (surface, stdio_write, fp); cairo_destroy (cr); cairo_surface_destroy (surface); fclose (fp); return 0; } @ 1.4 log @ * kapow.c: (main): Track removal of cairo_set_target_png. @ text @d1 1 d7 1 a7 3 #ifdef CAIRO_HAS_PNG_FUNCTIONS #include #else d31 1 a31 1 void d70 2 a71 2 void bend_it (double x, double y, double *new_x, double *new_y) d81 1 a81 1 angle = M_PI / 2 - (double) (x - cx) / IMAGE_WIDTH; d84 1 a84 1 radius = cy - (IMAGE_HEIGHT / 2 + (y - IMAGE_HEIGHT / 2) * t * 2); d86 2 a87 2 *new_x = cx + cos (angle) * radius; *new_y = cy - sin (angle) * radius; d90 2 a91 2 void move_to_callback(void *data, double x, double y) d93 3 a95 2 struct ctx *ctx = data; double new_x, new_y; d97 2 a98 4 if (ctx->first) { cairo_new_path (ctx->cr); ctx->first = 0; } d100 1 a100 3 bend_it (x, y, &new_x, &new_y); cairo_move_to (ctx->cr, new_x, new_y); } d102 1 a102 5 void line_to_callback(void *data, double x, double y) { struct ctx *ctx = data; double new_x, new_y; d104 22 a125 8 bend_it (x, y, &new_x, &new_y); cairo_line_to (ctx->cr, new_x, new_y); } void close_path_callback(void *data) { struct ctx *ctx = data; d127 1 a127 1 cairo_close_path (ctx->cr); d130 2 a131 2 void make_text_path (cairo_t *cr, double x, double y, const char *text) d133 5 a137 8 struct ctx ctx; cairo_move_to (cr, x, y); cairo_text_path (cr, text); ctx.first = 1; ctx.cr = cr; cairo_current_path_flat (cr, move_to_callback, line_to_callback, close_path_callback, &ctx); d149 1 d173 2 a174 1 cr = cairo_create (); d176 1 a176 2 cairo_set_target_image_no_data (cr, CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT); d183 1 a183 2 cairo_set_alpha (cr, 0.5); cairo_set_rgb_color (cr, 0, 0, 0); a187 1 cairo_set_alpha (cr, 1); d191 3 a193 3 cairo_pattern_add_color_stop (pattern, 0, 1, 1, 0.2, 1); cairo_pattern_add_color_stop (pattern, 1, 1, 0, 0, 1); cairo_set_pattern (cr, pattern); d197 1 a197 1 cairo_set_rgb_color (cr, 0, 0, 0); d200 1 a200 1 cairo_select_font (cr, fontname, d204 1 a204 1 cairo_scale_font (cr, 50); d214 3 a216 3 cairo_pattern_add_color_stop (pattern, 0, 1, 1, 1, 1); cairo_pattern_add_color_stop (pattern, 1, 0, 0, 0.4, 1); cairo_set_pattern (cr, pattern); d221 1 a221 1 cairo_set_rgb_color (cr, 0, 0, 0); d227 1 a227 1 cairo_surface_write_png (cairo_get_target_surface (cr), fp); d230 1 @ 1.3 log @add includes for cairo-png.h and string.h @ text @d6 1 a6 1 #ifdef CAIRO_HAS_PNG_SURFACE d9 1 a9 1 #error This program requires the PNG backend d171 2 a172 2 cairo_set_target_png (cr, fp, CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT); d225 1 a225 1 cairo_show_page (cr); @ 1.2 log @2005-01-24 Kristian Høgsberg * kapow.c (main): Add support for runing as a CGI script. @ text @d3 1 d6 5 @ 1.1 log @ * kapow.c (main): Print usage message if not argument is given. Default to text of kapow. @ text @d2 2 d9 1 a9 1 const char TEXT_DEFAULT[] = "kapow"; d14 3 d20 2 a21 2 #define X_INNER_RADIUS 140.0 #define Y_INNER_RADIUS 80.0 d23 2 a24 4 #define X_OUTER_RADIUS 190.0 #define Y_OUTER_RADIUS 110.0 #define SPIKES 10 d68 1 a68 1 const double dist = 500; d72 2 a73 3 * at (IMAGE_WIDTH / 2, dist), dist being somewhere well below the * visible area. On top of that, we'll scale up the letters going * left to right. d76 1 a76 1 angle = M_PI / 2 - (double) (x - IMAGE_WIDTH / 2) / IMAGE_WIDTH; d79 1 a79 1 radius = dist - (IMAGE_HEIGHT / 2 + (y - IMAGE_HEIGHT / 2) * t * 2); d81 2 a82 2 *new_x = (IMAGE_WIDTH / 2) + cos (angle) * radius; *new_y = dist - sin (angle) * radius; d118 13 d137 1 a137 1 const char *text; d141 9 a149 1 struct ctx ctx; d151 9 a159 6 if (argc > 1) { text = argv[1]; } else { text = TEXT_DEFAULT; fprintf (stderr, "Usage: %s \n", argv[0]); fprintf (stderr, "No exclamation provided, using \"%s\"\n", text); a161 1 fp = fopen (filename, "w"); d170 2 a171 1 cairo_translate (cr, 10, 10); d176 1 a176 2 cairo_translate (cr, -10, -10); d201 1 a201 2 cairo_move_to (cr, x, y); cairo_text_path (cr, text); d203 6 a208 5 srand (10); ctx.first = 1; ctx.cr = cr; cairo_current_path_flat (cr, move_to_callback, line_to_callback, close_path_callback, &ctx); a209 1 cairo_set_rgb_color (cr, 1, 0, 0); d212 1 a212 2 cairo_move_to (cr, x, y); cairo_text_path (cr, text); d214 1 d216 2 a217 8 srand (10); ctx.first = 1; ctx.cr = cr; cairo_current_path_flat (cr, move_to_callback, line_to_callback, close_path_callback, &ctx); cairo_stroke (cr); @