asgrad - demonstrates rendering of multi point linear gradients libAfterImage/tutorials/ASGrad
Contents
Description
All that is needed to draw gradient is to call make_gradient(), passing pointer to ASGradient structure,
that describes gradient. Naturally size of the gradient is needed too. Another parameter is filter -
that is a bit mask that allows one to draw gradient using only a subset of the channels, represented by
set bits. SCL_DO_ALL means that all 4 channels must be rendered. make_gradient() creates ASImage of
requested size and fills it with gradient. Special techinque based on error diffusion is utilized to
avoid sharp steps between grades of colors when limited range of colors is used for gradient.
Example
grad_im = make_gradient( asv, &grad, to_width, to_height,
SCL_DO_ALL,
ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT );
Name
asgrad - demonstrates rendering of multi point linear gradients libAfterImage/tutorials/ASGrad
Nameasgrad
Notes
make_gradient(), ASScanline, ASImage.
3rd Berkeley Distribution AfterStep v.2.2.12 asgrad(3x)
See Also
ARGB32, parse_argb_color(), ASGradient
libAfterImage/tutorials/ASGrad.2 [5.2]
Source
#include "../afterbase.h" #include "../afterimage.h" #include "common.h"
ARGB32 default_colors[] = {
0xFF000000,
0xFF700070, /* violet */
0xFF0000FF, /* blue */
0xFF00FFFF, /* cyan */
0xFF00FF00,
0XFFFFFF00,
0XFF700000,
0XFFFF0000,
0xFF8080A0,
0xFFE0E0FF,
0xFFa0a0FF, }; double default_offsets[] = { 0, 0.1, 0.15, 0.20, 0.35, 0.45, 0.55, 0.50,
0.65, 0.8, 1.0} ;
void usage() {
printf( " Usage: asgrad -h | <geometry> <gradient_type> <color1> "
"<offset2> <color2> [ <offset3> <color3> ...]\n");
printf( " Where: geometry - size of the resulting image and window;\n");
printf( " gradient_type - One of the fiollowing values :\n");
printf( " 0 - linear left-to-right gradient,\n");
printf( " 1 - diagonal lefttop-to-rightbottom,\n");
printf( " 2 - linear top-to-bottom gradient,\n");
printf( " 3 - diagonal righttop-to-leftbottom;\n");
printf( " offset - floating point value from 0.0 to 1.0\n"); }
int main(int argc, char* argv[]) {
Display *dpy = NULL;
ASVisual *asv ;
int screen = 0, depth = 0;
int dummy, geom_flags = 0;
unsigned int to_width, to_height ;
ASGradient grad ;
ASGradient default_grad = { 1, 11, &(default_colors[0]),
&(default_offsets[0])} ;
ASImage *grad_im = NULL;
/* see ASView.1 : */
set_application_name( argv[0] ); #if (HAVE_AFTERBASE_FLAG==1)
set_output_threshold(OUTPUT_LEVEL_DEBUG); #endif
if( argc > 1 )
{
if( strcmp( argv[1], "-h") == 0 )
{
usage();
return 0;
}
/* see ASScale.1 : */
geom_flags = XParseGeometry( argv[1], &dummy, &dummy,
&to_width, &to_height );
}else
usage();
memset( &grad, 0x00, sizeof(ASGradient));
#ifndef X_DISPLAY_MISSING
dpy = XOpenDisplay(NULL);
_XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
screen = DefaultScreen(dpy);
depth = DefaultDepth( dpy, screen ); #endif
if( argc >= 5 )
{
int i = 2;
/* see ASGrad.1 : */
grad.type = atoi( argv[2] );
grad.npoints = 0 ;
grad.color = safemalloc( ((argc-2)/2)*sizeof(ARGB32));
grad.offset = safemalloc( ((argc-2)/2)*sizeof(double));
while( ++i < argc )
{
if( grad.npoints > 0 )
{
if( i == argc-1 )
grad.offset[grad.npoints] = 1.0;
else
grad.offset[grad.npoints] = atof( argv[i] );
++i ;
}
/* see ASTile.1 : */
if( parse_argb_color( argv[i], &(grad.color[grad.npoints]))
!= argv[i] )
if( grad.offset[grad.npoints] >= 0. &&
grad.offset[grad.npoints]<= 1.0 )
grad.npoints++ ;
}
}else
{
grad = default_grad ;
if( argc >= 3 )
grad.type = atoi( argv[2] );
}
if( grad.npoints <= 0 )
{
show_error( " not enough gradient points specified.");
return 1;
}
/* Making sure tiling geometry is sane : */ #ifndef X_DISPLAY_MISSING
if( !get_flags(geom_flags, WidthValue ) )
to_width = DisplayWidth(dpy, screen)*2/3 ;
if( !get_flags(geom_flags, HeightValue ) )
to_height = DisplayHeight(dpy, screen)*2/3 ; #else
if( !get_flags(geom_flags, WidthValue ) )
to_width = 500 ;
if( !get_flags(geom_flags, HeightValue ) )
to_height = 500 ; #endif
printf( "%s: rendering gradient of type %d to %dx%d\n",
get_application_name(), grad.type&GRADIENT_TYPE_MASK,
to_width, to_height );
/* see ASView.3 : */
asv = create_asvisual( dpy, screen, depth, NULL );
/* see ASGrad.2 : */
grad_im = make_gradient( asv, &grad, to_width, to_height,
SCL_DO_ALL, #ifndef X_DISPLAY_MISSING
ASA_XImage, #else
ASA_ASImage, #endif
0, ASIMAGE_QUALITY_DEFAULT );
if( grad_im )
{ #ifndef X_DISPLAY_MISSING
/* see ASView.4 : */
Window w = create_top_level_window( asv,
DefaultRootWindow(dpy), 32, 32,
to_width, to_height, 1, 0, NULL,
"ASGradient", NULL );
if( w != None )
{
Pixmap p ;
XMapRaised (dpy, w);
/* see ASView.5 : */
p = asimage2pixmap( asv, DefaultRootWindow(dpy), grad_im,
NULL, True );
destroy_asimage( &grad_im );
/* see common.c: set_window_background_and_free() : */
p = set_window_background_and_free( w, p );
/* see common.c: wait_closedown() : */
}
wait_closedown(w);
dpy = NULL; #else
ASImage2file( grad_im, NULL, "asgrad.jpg", ASIT_Jpeg, NULL );
destroy_asimage( &grad_im ); #endif
}
return 0 ; }
libAfterImage/tutorials/ASGrad.1 [5.1]
Synopsis
Step 2. Actually rendering gradient.
