asgrad(3x)
β¨ NAME β¨
okay so bestie, meet asgrad(3x) β yes, section 3x, and it's living in the AfterStep X11 window manager household π. Her whole thing? She demonstrates rendering of multi point linear gradients. that's it, that's the vibe. She hangs out at libAfterImage/tutorials/ASGrad, no cap. π
π« NAMEASGrad π«
(don't come for me, the page literally has this second heading called NAMEASGrad β we respect the lore.) it's just more name energy for the exact same beautiful program. π¦
πΈ SYNOPSIS πΈ
libAfterImage application for drawing multipoint linear gradients. that's the whole tea, periodt. β¨
π DESCRIPTION π
New steps described in this tutorial are:
ASGrad.1.Building gradient specs.ASGrad.2.Actual rendering gradient.
two steps, two moods, both iconic. π
π₯ SEE ALSO π₯
- Tutorial 1:
ASViewβ explanation of basic steps needed to uselibAfterImageand 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.
go read your siblings too, they're all slaying in their own lanes π
π SOURCE π
here's the actual source, literally verbatim, do not touch a single character bestie:
#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] π«Ά
π ASGrad.1 [5.1] π
β¨ SYNOPSIS β¨
Step 1. Building gradient specs.
π DESCRIPTION π
so a multipoint gradient is literally just a set of color values, each one with an offset marking how far that point sits from the beginning of the gradient β all on a 1.0 scale, bestie. and the rules? the first and last point in the gradient should always be at 0. and 1.0 respectively, and every other point has to live in between them. like, a 2 point gradient will always have offsets 0. and 1.0. a 3 point gradient gets 0. for the first color, 1.0 for the last color, and anything in between for the middle color. π«
and if an offset is incorrect?? the point gets skipped at the time of rendering. no warning, just gone. tragic but that's the deal π
There are 4 types of gradients supported:
- horizontal
- top-left to bottom-right diagonal
- vertical
- top-right to bottom-left diagonal
also, any cilindrical gradient could be drawn as a 3 point gradient with the border colors being the same. cute little trick, iykyk π
and here's the slay part: each gradient point has an ARGB color, which means it's possible to draw gradients in the alpha channel as well as RGB. that means semitransparent gradients, fading gradients, etc. etc. iconique β¨
π EXAMPLE π
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++ ;
}
π SEE ALSO π
ARGB32, parse_argb_color(), ASGradient
libAfterImage/tutorials/ASGrad.2 [5.2] π¦
π¦ ASGrad.2 [5.2] π¦
β¨ SYNOPSIS β¨
Step 2. Actually rendering gradient.
π DESCRIPTION π
okay so the entire fandom of actually drawing a gradient is: call make_gradient() and hand her a pointer to the ASGradient structure that describes your gradient. obviously you also need the size of the gradient, duh. another parameter is the filter β that's a bit mask that lets you draw the gradient using only a subset of the channels, represented by the set bits. SCL_DO_ALL means all 4 channels must be rendered, periodt. π
make_gradient() creates an ASImage of the requested size and fills it with the gradient. and because the devs ate, a special techinque based on error diffusion is utilized to avoid sharp steps between grades of colors when a limited range of colors is used for the gradient. no ugly banding, we don't know her π«Ά
π EXAMPLE π
grad_im = make_gradient( asv, &grad, to_width, to_height,
SCL_DO_ALL,
ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT );
π NOTES π
make_gradient(), ASScanline, ASImage.
and that's the page bestie π this whole tutorial came to you from the 3rd Berkeley Distribution, running AfterStep v.2.2.12, and it's filed under the asgrad(3x) header. go forth and gradient, you're the main character now β¨ππ
π¦ where this page comes from
- ubuntu resolute: libafterimage-dev 2.2.12-19 Β· GPL-2.0-or-later
- ubuntu stonking: libafterimage-dev 2.2.12-19 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms