/* * Copyright © 2004 David Reveman, Peter Nilsson * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the names of * David Reveman and Peter Nilsson not be used in advertising or * publicity pertaining to distribution of the software without * specific, written prior permission. David Reveman and Peter Nilsson * makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: David Reveman * Peter Nilsson */ #include #include #include #include static cairo_surface_t *bg_surface; static cairo_surface_t *comp_surface; static int bg_width, bg_height; static int comp_width, comp_height; void comp_setup (cairo_surface_t *target, int w, int h) { cairo_surface_t *image; cairo_t *cr; image = cairo_image_surface_create_from_png ("bg.png"); if (cairo_surface_status (image)) { printf ("error reading bg.png: %s\n", cairo_status_to_string (cairo_surface_status (image))); exit(1); } bg_width = cairo_image_surface_get_width (image); bg_height = cairo_image_surface_get_height (image); bg_surface = cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA, bg_width, bg_height); cr = cairo_create (bg_surface); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface (cr, image, 0.0, 0.0); cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (image); image = cairo_image_surface_create_from_png ("fg.png"); if (cairo_surface_status (image)) { printf ("error reading fg.png: %s\n", cairo_status_to_string (cairo_surface_status (image))); exit(1); } comp_width = cairo_image_surface_get_width (image); comp_height = cairo_image_surface_get_height (image); comp_surface = cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA, comp_width, comp_height); cr = cairo_create (comp_surface); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface (cr, image, 0.0, 0.0); cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (image); } static double comp_x = 400 - 256 / 2; static double comp_y = 200 - 256 / 2; static double comp_x_dir = 5.0; static double comp_y_dir = 5.0; static double oversize = 1.0; static double oversize_dir = 0.001; void comp_render (cairo_t *cr, int w, int h) { double scale_x, scale_y; cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_move_to (cr, 0, 0); scale_x = ((double) w) / (double) bg_width; scale_y = ((double) h) / (double) bg_height; cairo_translate (cr, -((oversize - 1.0) * (double) w) / 2.0, -((oversize - 1.0) * (double) h) / 2.0); cairo_scale (cr, scale_x * oversize, scale_y * oversize); cairo_set_source_surface (cr, bg_surface, 0.0, 0.0); cairo_paint (cr); cairo_restore (cr); oversize += oversize_dir; if (oversize >= 1.2) oversize_dir = -oversize_dir; if (oversize <= 1.0) oversize_dir = -oversize_dir; cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_move_to (cr, 0, 0); if (comp_x_dir < 0) { if (comp_x_dir < -1.0) comp_x_dir += 10.0 / w; } else { if (comp_x_dir > 1.0) comp_x_dir -= 10.0 / w; } if (comp_y_dir < 0) { if (comp_y_dir < -1.0) comp_y_dir += 10.0 / h; } else { if (comp_y_dir > 1.0) comp_y_dir -= 10.0 / h; } comp_x += comp_x_dir; comp_y += comp_y_dir; if (comp_x >= (w - comp_width)) comp_x_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0); else if (comp_x <= 0) comp_x_dir = (drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0); if (comp_y >= (h - comp_height)) comp_y_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0); else if (comp_y <= 0) comp_y_dir = drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0; cairo_translate (cr, (int) comp_x, (int) comp_y); cairo_move_to (cr, 0.0, 0.0); cairo_set_source_surface (cr, comp_surface, 0.0, 0.0); cairo_paint (cr); cairo_restore (cr); }