.\" t .\" @(#)asgrad.3 01/28/2021 .TH asgrad 3x "AfterStep v.2.2.12" "Jan 28 2021" "AfterStep X11 window manager" .UC .SH NAME \fBasgrad\fP\ \- demonstrates rendering of multi point linear gradients libAfterImage/tutorials/ASGrad .SH NAMEASGrad .SH SYNOPSIS .fi libAfterImage application for drawing multipoint linear gradients\&. .fi .SH DESCRIPTION .fi New steps described in this tutorial are : ASGrad\&.1\&. Building gradient specs\&. ASGrad\&.2\&. Actual rendering gradient\&. .fi .SH SEE ALSO .fi Tutorial 1: ASView \- explanation of basic steps needed to use libAfterImage and some other simple things\&. Tutorial 2: ASScale \- image scaling basics\&. Tutorial 3: ASTile \- image tiling and tinting\&. Tutorial 4: ASMerge \- scaling and blending of arbitrary number of images\&. .fi .SH SOURCE .in +4n .fi #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 | " " [ \&.\&.\&.]\\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 ; } .fi .in libAfterImage/tutorials/ASGrad\&.1 [5\&.1] .SH SYNOPSIS .fi Step 1\&. Building gradient specs\&. .fi .SH DESCRIPTION .fi Multipoint gradient is defined as set of color values with offsets of each point from the beginning of the gradient on 1\&.0 scale\&. Offsets of the first and last point in gradient should always be 0\&. and 1\&.0 respectively, and other points should go in between\&. For example 2 point gradient will have always offsets 0\&. and 1\&.0, 3 points gradient will have 0\&. for first color, 1\&.0 for last color and anything in between for middle color\&. If offset is incorrect \- point will be skipped at the time of rendering\&. There are 4 types of gradients supported : horizontal, top\-left to bottom\-right diagonal, vertical and top\-right to bottom\-left diagonal\&. Any cilindrical gradient could be drawn as a 3 point gradient with border colors being the same\&. Each gradient point has ARGB color, which means that it is possible to draw gradients in alpha channel as well as RGB\&. That makes for semitransparent gradients, fading gradients, etc\&. .fi .SH EXAMPLE .fi 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 ; } 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++ ; } .fi .SH SEE ALSO .fi ARGB32, parse_argb_color(), ASGradient .fi libAfterImage/tutorials/ASGrad\&.2 [5\&.2] .SH SYNOPSIS .fi Step 2\&. Actually rendering gradient\&. .fi .SH DESCRIPTION .fi 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\&. .fi .SH EXAMPLE .fi grad_im = make_gradient( asv, &grad, to_width, to_height, SCL_DO_ALL, ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT ); .fi .SH NOTES .fi make_gradient(), ASScanline, ASImage\&. .fi