[cairo-commit] cairo-demo/kapow ChangeLog, NONE, 1.1 Makefile, NONE, 1.1 kapow.c, NONE, 1.1

Carl Worth commit at pdx.freedesktop.org
Mon Jan 24 08:16:53 PST 2005


Committed by: cworth

Update of /cvs/cairo/cairo-demo/kapow
In directory gabe:/tmp/cvs-serv19556

Added Files:
	ChangeLog Makefile kapow.c 
Log Message:

        * kapow.c (main): Print usage message if not argument is
        given. Default to text of kapow.


--- NEW FILE: ChangeLog ---
2005-01-24  Carl Worth  <cworth at cworth.org>

	* kapow.c (main): Print usage message if not argument is
	given. Default to text of "kapow".


--- NEW FILE: Makefile ---
CFLAGS	= $(shell pkg-config --cflags cairo libpng) -Wall -g
LDLIBS	= $(shell pkg-config --libs cairo libpng) -g

kapow : kapow.o

clean :
	rm kapow.o kapow

--- NEW FILE: kapow.c ---
#include <stdio.h>
#include <cairo.h>
#include <math.h>

const char filename[] = "kapow.png";
const char fontname[] = "Sans";
const char TEXT_DEFAULT[] = "kapow";

#define IMAGE_WIDTH 384
#define IMAGE_HEIGHT 256

#define X_FUZZ 16
#define Y_FUZZ 16

#define X_INNER_RADIUS 140.0
#define Y_INNER_RADIUS 80.0

#define X_OUTER_RADIUS 190.0
#define Y_OUTER_RADIUS 110.0

#define SPIKES 10

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;
};

void
bend_it (double x, double y, double *new_x, double *new_y)
{
    const double dist = 500;
    double angle, radius, t;

    /* We're going to wrap the points around a big circle with center
     * 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.
     */

    angle = M_PI / 2 - (double) (x - IMAGE_WIDTH / 2) / IMAGE_WIDTH;
    t = 3 * M_PI / 4 - angle + 0.05;
    angle = 3 * M_PI / 4 - pow (t, 1.8);
    radius = dist - (IMAGE_HEIGHT / 2 + (y - IMAGE_HEIGHT / 2) * t * 2);

    *new_x = (IMAGE_WIDTH / 2) + cos (angle) * radius;
    *new_y = dist - sin (angle) * radius;
}

void
move_to_callback(void *data, double x, double y)
{
    struct ctx *ctx = data;
    double new_x, new_y;

    if (ctx->first) {
	cairo_new_path (ctx->cr);
	ctx->first = 0;
    }

    bend_it (x, y, &new_x, &new_y);
    cairo_move_to (ctx->cr, new_x, new_y);
}

void
line_to_callback(void *data, double x, double y)
{
    struct ctx *ctx = data;
    double new_x, new_y;

    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;

    cairo_close_path (ctx->cr);
}

int
main (int argc, char *argv[])
{
    FILE *fp;
    double x;
    double y;
    const char *text;
    cairo_text_extents_t extents;
    cairo_pattern_t *pattern;
    cairo_t *cr;
    struct ctx ctx;

    if (argc > 1) {
	text = argv[1];
    } else {
	text = TEXT_DEFAULT;
	fprintf (stderr, "Usage: %s <exclamation>\n", argv[0]);
	fprintf (stderr, "No exclamation provided, using \"%s\"\n", text);
    }

    fp = fopen (filename, "w");

    cr = cairo_create ();

    cairo_set_target_png (cr, fp, CAIRO_FORMAT_ARGB32,
			  IMAGE_WIDTH, IMAGE_HEIGHT);

    cairo_set_line_width (cr, 2);

    cairo_translate (cr, 10, 10);
    make_star_path (cr);
    cairo_set_alpha (cr, 0.5);
    cairo_set_rgb_color (cr, 0, 0, 0);
    cairo_fill (cr);

    cairo_translate (cr, -10, -10);

    make_star_path (cr);
    cairo_set_alpha (cr, 1);
    pattern =
	cairo_pattern_create_radial (IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, 10,
				     IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, 230);
    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);
    cairo_fill (cr);

    make_star_path (cr);
    cairo_set_rgb_color (cr, 0, 0, 0);
    cairo_stroke (cr);

    cairo_select_font (cr, fontname,
		       CAIRO_FONT_SLANT_NORMAL,
		       CAIRO_FONT_WEIGHT_BOLD);

    cairo_scale_font (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);

    cairo_move_to (cr, x, y);
    cairo_text_path (cr, text);

    srand (10);
    ctx.first = 1;
    ctx.cr = cr;
    cairo_current_path_flat (cr, move_to_callback, line_to_callback,
			     close_path_callback, &ctx);

    cairo_set_rgb_color (cr, 1, 0, 0);
    cairo_fill (cr);

    cairo_move_to (cr, x, y);
    cairo_text_path (cr, text);
    cairo_set_rgb_color (cr, 0, 0, 0);

    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);

    cairo_show_page (cr);

    cairo_destroy (cr);
    fclose (fp);

    return 0;
}




More information about the cairo-commit mailing list