---
name: "asgrad"
section: "3x"
platform: "linux"
package: "libafterimage-dev"
version: "2.2.12-18"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/asgrad"
---

# asgrad(3x)

demonstrates rendering of multi point linear gradients libAfterImage/tutorials/ASGrad

## NAME

**asgrad** - demonstrates rendering of multi point linear gradients libAfterImage/tutorials/ASGrad

## NAMEASGrad

## SYNOPSIS

libAfterImage application for drawing multipoint linear gradients.

## DESCRIPTION

New steps described in this tutorial are : ASGrad.1. Building gradient specs. ASGrad.2. Actual rendering gradient.

## SEE ALSO

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.

## 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 1. Building gradient specs.

## DESCRIPTION

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.

## 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\]

## SYNOPSIS

Step 2. Actually rendering gradient.

## 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 );

## NOTES

make\_gradient(), ASScanline, ASImage.
