gtk/gdk/broadway/broadway-demo.c
Alexander Larsson e6c340519c [broadway] Send diffs as bilevel rgba instead of true diff
The true diff only works if the destination keeps perfect 32bit
canvas data, which is not always true. So, instead we send only
changed pixels, masking the others to 0 via alpha 0.
2010-11-25 22:09:30 +01:00

231 lines
5.9 KiB
C

/* Build with
gcc -lm -lz -O2 -Wall `pkg-config --libs --cflags cairo` -o broadway broadway.c demo.c
*/
#include "broadway.h"
#include <math.h>
#include <unistd.h>
#include <stdint.h>
#include <cairo.h>
static void
diff_surfaces (cairo_surface_t *surface,
cairo_surface_t *old_surface)
{
uint8_t *data, *old_data;
uint32_t *line, *old_line;
int w, h, stride, old_stride;
int x, y;
data = cairo_image_surface_get_data (surface);
old_data = cairo_image_surface_get_data (old_surface);
w = cairo_image_surface_get_width (surface);
h = cairo_image_surface_get_height (surface);
stride = cairo_image_surface_get_stride (surface);
old_stride = cairo_image_surface_get_stride (old_surface);
for (y = 0; y < h; y++)
{
line = (uint32_t *)data;
old_line = (uint32_t *)old_data;
for (x = 0; x < w; x++)
{
if (*line & 0xffffff == *old_line & 0xffffff)
*old_line = 0;
else
*old_line = *line | 0xff000000;
line ++;
old_line ++;
}
data += stride;
old_data += old_stride;
}
}
static void
snippet(cairo_t *cr, int i)
{
if (1)
{
cairo_save(cr);
cairo_rotate (cr, i * 0.002);
/* a custom shape that could be wrapped in a function */
double x0 = 25.6, /* parameters like cairo_rectangle */
y0 = 25.6,
rect_width = 204.8,
rect_height = 204.8,
radius = 102.4; /* and an approximate curvature radius */
double x1,y1;
x1=x0+rect_width;
y1=y0+rect_height;
if (rect_width/2<radius) {
if (rect_height/2<radius) {
cairo_move_to (cr, x0, (y0 + y1)/2);
cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
} else {
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1 , y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
}
} else {
if (rect_height/2<radius) {
cairo_move_to (cr, x0, (y0 + y1)/2);
cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
} else {
cairo_move_to (cr, x0, y0 + radius);
cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
cairo_line_to (cr, x1 - radius, y0);
cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
cairo_line_to (cr, x1 , y1 - radius);
cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
cairo_line_to (cr, x0 + radius, y1);
cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
}
}
cairo_close_path (cr);
cairo_set_source_rgb (cr, 0.5, 0.5, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgba (cr, 0.5, 0, 0, 0.5);
cairo_set_line_width (cr, 10.0);
cairo_stroke (cr);
cairo_restore(cr);
}
if (1)
{
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = (45.0 + i * 5) * (M_PI/180.0); /* angles are specified */
double angle2 = (180.0 + i * 5) * (M_PI/180.0); /* in radians */
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_set_line_width (cr, 10.0);
cairo_arc (cr, xc, yc, radius, angle1, angle2);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_arc (cr, xc, yc, radius, angle1, angle1);
cairo_line_to (cr, xc, yc);
cairo_arc (cr, xc, yc, radius, angle2, angle2);
cairo_line_to (cr, xc, yc);
cairo_stroke (cr);
}
}
static void
demo2 (BroadwayClient *client)
{
cairo_t *cr;
cairo_surface_t *surface, *old_surface;
BroadwayRect rects[2];
double da = 0;
int i;
broadway_client_new_surface(client, 0, 100, 100, 800, 600);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
800, 600);
old_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
800, 600);
cr = cairo_create (old_surface);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_rectangle (cr, 0, 0, 800, 600);
cairo_fill (cr);
cairo_destroy (cr);
for (i = 0; i < 100; i++)
{
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
cairo_rectangle (cr, 0, 0, 800, 600);
cairo_fill (cr);
snippet(cr, i);
cairo_destroy (cr);
if (i == 0)
{
broadway_client_put_rgb (client, 0, 0, 0, 800, 600, 800*4,
cairo_image_surface_get_data(surface)
);
broadway_client_show_surface (client, 0);
}
else
{
diff_surfaces (surface,
old_surface);
broadway_client_put_rgba (client, 0, 0, 0, 800, 600, 800*4,
cairo_image_surface_get_data(old_surface));
}
broadway_client_move_surface (client, 0, 100 + i, 100 + i);
rects[0].x = 500;
rects[0].y = 0;
rects[0].width = 100;
rects[0].height = 100;
rects[1].x = 600;
rects[1].y = 100;
rects[1].width = 100;
rects[1].height = 100;
broadway_client_copy_rectangles (client,
0,
rects, 2,
400, 0);
broadway_client_flush (client);
cr = cairo_create (old_surface);
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
da += 10;
usleep (50 * 1000);
}
cairo_surface_destroy (surface);
broadway_client_destroy_surface(client, 0);
broadway_client_flush (client);
}
int
main (int argc, char *argv[])
{
BroadwayClient *client;
client = broadway_client_new (STDOUT_FILENO);
demo2(client);
return 0;
}