[Commit] papers/xr_ols2003/examples .cvsignore,NONE,1.1 Makefile,NONE,1.1 outline.c,NONE,1.1 spiral.c,NONE,1.1 write_png.c,NONE,1.1 write_png.h,NONE,1.1

Carl Worth commit@keithp.com
Wed, 14 May 2003 14:04:24 -0700


Committed by: cworth

Update of /local/src/CVS/papers/xr_ols2003/examples
In directory home.keithp.com:/tmp/cvs-serv7090/examples

Added Files:
	.cvsignore Makefile outline.c spiral.c write_png.c write_png.h 
Log Message:
Added a couple of figures along with their example code

--- NEW FILE: .cvsignore ---
outline
spiral
*.png

--- NEW FILE: Makefile ---
EXAMPLES=outline spiral

CFLAGS=-g -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls `pkg-config --cflags Xr`
LDFLAGS=write_png.o `pkg-config --libs Xr` -lpng

all: ${EXAMPLES}

clean:
	rm -f ${EXAMPLES} *.o

--- NEW FILE: outline.c ---
#include <string.h> /* for memset */

#include <Xr.h>

#include "write_png.h"

void
draw_outlines (XrState *xrs, int surface_width, int surface_height);

void
draw_flat (XrState *xrs, double width, double height);

void
draw_tent (XrState *xrs, double width, double height);

void
draw_cylinder (XrState *xrs, double width, double height);

XrSurface *
create_gradient (XrState *xrs, double width, double height);

int
main (void)
{
    const int width = 600;
    const int height = 400;
    const int stride = width * 4;
    char image[stride*height];
    XrState *xrs;
    XrSurface *s;

    memset (image, 0, stride*height);

    xrs = XrCreate ();

    s = XrSurfaceCreateForImage (image, XrFormatARGB32,
				 width, height, stride);

    XrSetTargetSurface (xrs, s);

    draw_outlines (xrs, width, height);

    write_png_argb32 (image, "outline.png", width, height, stride);

    XrSurfaceDestroy (s);
    XrDestroy (xrs);

    return 0;
}

XrSurface *
create_gradient (XrState *xrs, double width, double height)
{
    XrSurface *gradient;
    XrMatrix *matrix;

    XrSave (xrs);

    gradient = XrSurfaceCreateNextTo (XrGetTargetSurface (xrs),
				      XrFormatARGB32,
				      3, 2);
    XrSetTargetSurface (xrs, gradient);

    XrSetRGBColor (xrs, 0, 0, 0);
    XrRectangle (xrs, 0, 0, 1, 2);
    XrFill (xrs);

    XrSetRGBColor (xrs, 1, 1, 1);
    XrRectangle (xrs, 1, 0, 1, 2);
    XrFill (xrs);

    XrSetRGBColor (xrs, 0, 0, 0);
    XrRectangle (xrs, 2, 0, 1, 2);
    XrFill (xrs);

    XrRestore (xrs);

    matrix = XrMatrixCreate ();
    XrMatrixScale (matrix,
		   2.0 / width,
		   1.0 / height);
    XrSurfaceSetMatrix (gradient, matrix);
    XrSurfaceSetFilter (gradient, XrFilterBilinear);
    XrMatrixDestroy (matrix);

    return gradient;
}

void
draw_outlines (XrState *xrs, int surface_width, int surface_height)
{
    XrSurface *gradient;
    double width, height, pad;

    width = surface_width / 4.0;
    pad = (surface_width - (3 * width)) / 2.0;
    height = surface_height;

    XrSetRGBColor (xrs, 1, 1, 1);
    XrRectangle (xrs, 0, 0, surface_width, surface_height);
    XrFill (xrs);

    gradient = create_gradient (xrs, width, height);

    XrSetPattern (xrs, gradient);
    draw_flat (xrs, width, height);

    XrTranslate (xrs, width + pad, 0);
    XrSetPattern (xrs, gradient);
    draw_tent (xrs, width, height);

    XrTranslate (xrs, width + pad, 0);
    XrSetPattern (xrs, gradient);
    draw_cylinder (xrs, width, height);

    XrRestore (xrs);

    XrSurfaceDestroy (gradient);
}

void
draw_flat (XrState *xrs, double width, double height)
{
    XrRectangle (xrs, 0, 0, width, height);

    XrFill (xrs);
}

void
draw_tent (XrState *xrs, double width, double height)
{
    double hwidth = width / 2.0;

    XrMoveTo    (xrs,       0,  hwidth);
    XrRelLineTo (xrs,  hwidth, -hwidth);
    XrRelLineTo (xrs,  hwidth,  hwidth);
    XrRelLineTo (xrs,       0,  height - hwidth);
    XrRelLineTo (xrs, -hwidth, -hwidth);
    XrRelLineTo (xrs, -hwidth,  hwidth);
    XrClosePath (xrs);

    XrFill (xrs);
}

void
draw_cylinder (XrState *xrs, double width, double height)
{
    double hwidth = width / 2.0;

    XrMoveTo (xrs, 0, hwidth);
    XrRelCurveTo (xrs,
		      0, -hwidth,
		  width, -hwidth,
		  width, 0);
    XrRelLineTo (xrs, 0, height - hwidth);
    XrRelCurveTo (xrs,
		       0, -hwidth,
		  -width, -hwidth,
		  -width, 0);
    XrClosePath (xrs);

    XrFill (xrs);
}

--- NEW FILE: spiral.c ---
#include <string.h> /* for memset */

#include <Xr.h>

#include "write_png.h"

void
draw_spiral (XrState *xrs, int surface_width, int surface_height);

int
main (void)
{
    const int width = 600;
    const int height = 600;
    const int stride = width * 4;
    char image[stride*height];
    XrState *xrs;
    XrSurface *s;

    memset (image, 0, stride*height);

    xrs = XrCreate ();

    s = XrSurfaceCreateForImage (image, XrFormatARGB32,
				 width, height, stride);

    XrSetTargetSurface (xrs, s);

    XrRectangle (xrs, 0, 0, width, height);
    XrSetRGBColor (xrs, 1, 1, 1);
    XrFill (xrs);

    draw_spiral (xrs, width, height);

    write_png_argb32 (image, "spiral.png", width, height, stride);

    XrSurfaceDestroy (s);
    XrDestroy (xrs);

    return 0;
}

void
draw_spiral (XrState *xrs, int width, int height)
{
#define BOXES (9)
#define DECAY (1.0 / (6.0 * (BOXES - 1)))

    int wdelta = DECAY * width;
    int hdelta = DECAY * height;
    int i;

    XrTranslate (xrs, 1, 1);
    width -= 2;
    height -= 2;

    XrMoveTo (xrs, width, -hdelta);
    for (i=0; i < BOXES; i++) {
	XrRelLineTo (xrs, 0, height - hdelta * (2 * i - 1));
	XrRelLineTo (xrs, - (width - wdelta * (2 *i)), 0);
	XrRelLineTo (xrs, 0, - (height - hdelta * (2*i)));
	XrRelLineTo (xrs, width - wdelta * (2 * i + 1), 0);
    }

    XrSetRGBColor (xrs, 0, 0, 1);
    XrStroke (xrs);
}

--- NEW FILE: write_png.c ---
#include <stdio.h>
#include <png.h>
#include <stdlib.h>

#include "write_png.h"

static void
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
{
    int i;

    for (i = 0; i < row_info->rowbytes; i += 4) {
        unsigned char *b = &data[i];
        unsigned char alpha = b[3];
        unsigned long pixel;
        unsigned long *p;
        if (alpha == 0)
            pixel = 0;
        else
            pixel = ((((b[0] * 255) / alpha) << 0) |
                     (((b[1] * 255) / alpha) << 8) |
                     (((b[2] * 255) / alpha) << 16) |
                     (alpha << 24));
        p = (unsigned long *) b;
        *p = pixel;
    }
}

void
write_png_argb32 (char *buffer, char* filename,
		  int width, int height, int stride)
{
    FILE* f;
    png_struct* png;
    png_info* info;
    png_byte** rows;
    int       i;
    png_color_16 white;
    
    f = fopen (filename, "w");
    rows = malloc (height*sizeof (png_byte*));

    for (i=0;i<height;i++) {
	rows[i]=buffer+i*stride;
    }

    png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    info = png_create_info_struct (png);

    png_init_io (png, f);
    png_set_IHDR (png, info,
		  width, height, 8,
		  PNG_COLOR_TYPE_RGB_ALPHA, 
		  PNG_INTERLACE_NONE,
		  PNG_COMPRESSION_TYPE_DEFAULT,
		  PNG_FILTER_TYPE_DEFAULT);

    white.red=0xff;
    white.blue=0xff;
    white.green=0xff;
    png_set_bKGD (png, info, &white);

    png_set_write_user_transform_fn (png, unpremultiply_data);
    png_set_bgr (png);

    png_write_info (png, info);
    png_write_image (png, rows);
    png_write_end (png, info);

    png_destroy_write_struct (&png, &info);

    free (rows);
    fclose (f);
}

--- NEW FILE: write_png.h ---
#ifndef WRITE_PNG_H
#define WRITE_PNG_H

void
write_png_argb32 (char *buffer, char* filename,
		  int width, int height, int stride);

#endif