1asgrad(1) AfterStep X11 window manager asgrad(1)
2
3
4
6 asgrad - demonstrates rendering of multi point linear gradients libAfâ
7 terImage/tutorials/ASGrad
8
11 libAfterImage application for drawing multipoint linear gradients.
12
14 New steps described in this tutorial are :
15 ASGrad.1. Building gradient specs.
16 ASGrad.2. Actual rendering gradient.
17
19 Tutorial 1: ASView - explanation of basic steps needed to use
20 libAfterImage and some other simple things.
21 Tutorial 2: ASScale - image scaling basics.
22 Tutorial 3: ASTile - image tiling and tinting.
23 Tutorial 4: ASMerge - scaling and blending of arbitrary number of
24 images.
25
27 Source :
28 #include "../afterbase.h"
29 #include "../afterimage.h"
30 #include "common.h"
31
32 ARGB32 default_colors[] = {
33 0xFF000000,
34 0xFF700070, /* violet */
35 0xFF0000FF, /* blue */
36 0xFF00FFFF, /* cyan */
37 0xFF00FF00,
38 0XFFFFFF00,
39 0XFF700000,
40 0XFFFF0000,
41 0xFF8080A0,
42 0xFFE0E0FF,
43 0xFFa0a0FF,
44 };
45 double default_offsets[] = { 0, 0.1, 0.15, 0.20, 0.35, 0.45, 0.55, 0.50,
46 0.65, 0.8, 1.0} ;
47
48
49 void usage()
50 {
51 printf( " Usage: asgrad -h | <geometry> <gradient_type> <color1> "
52 "<offset2> <color2> [ <offset3> <color3> ...]0);
53 printf( " Where: geometry - size of the resulting image and window;0);
54 printf( " gradient_type - One of the fiollowing values :0);
55 printf( " 0 - linear left-to-right gradient,0);
56 printf( " 1 - diagonal lefttop-to-rightbottom,0);
57 printf( " 2 - linear top-to-bottom gradient,0);
58 printf( " 3 - diagonal righttop-to-leftbottom;0);
59 printf( " offset - floating point value from 0.0 to 1.00);
60 }
61
62 int main(int argc, char* argv[])
63 {
64 ASVisual *asv ;
65 int screen = 0, depth = 0;
66 int dummy, geom_flags = 0;
67 unsigned int to_width, to_height ;
68 ASGradient grad ;
69 ASGradient default_grad = { 1, 11, &(default_colors[0]),
70 &(default_offsets[0])} ;
71 ASImage *grad_im = NULL;
72
73 /* see ASView.1 : */
74 set_application_name( argv[0] );
75 #if (HAVE_AFTERBASE_FLAG==1)
76 set_output_threshold(OUTPUT_LEVEL_DEBUG);
77 #endif
78
79 if( argc > 1 )
80 {
81 if( strcmp( argv[1], "-h") == 0 )
82 {
83 usage();
84 return 0;
85 }
86 /* see ASScale.1 : */
87 geom_flags = XParseGeometry( argv[1], &dummy, &dummy,
88 &to_width, &to_height );
89 }else
90 usage();
91 memset( &grad, 0x00, sizeof(ASGradient));
92
93 #ifndef X_DISPLAY_MISSING
94 dpy = XOpenDisplay(NULL);
95 _XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
96 screen = DefaultScreen(dpy);
97 depth = DefaultDepth( dpy, screen );
98 #endif
99
100 if( argc >= 5 )
101 {
102 int i = 2;
103 /* see ASGrad.1 : */
104 grad.type = atoi( argv[2] );
105 grad.npoints = 0 ;
106 grad.color = safemalloc( ((argc-2)/2)*sizeof(ARGB32));
107 grad.offset = safemalloc( ((argc-2)/2)*sizeof(double));
108 while( ++i < argc )
109 {
110 if( grad.npoints > 0 )
111 {
112 if( i == argc-1 )
113 grad.offset[grad.npoints] = 1.0;
114 else
115 grad.offset[grad.npoints] = atof( argv[i] );
116 ++i ;
117 }
118
119 /* see ASTile.1 : */
120 if( parse_argb_color( argv[i], &(grad.color[grad.npoints]))
121 != argv[i] )
122 if( grad.offset[grad.npoints] >= 0. &&
123 grad.offset[grad.npoints]<= 1.0 )
124 grad.npoints++ ;
125 }
126 }else
127 {
128 grad = default_grad ;
129 if( argc >= 3 )
130 grad.type = atoi( argv[2] );
131 }
132
133 if( grad.npoints <= 0 )
134 {
135 show_error( " not enough gradient points specified.");
136 return 1;
137 }
138
139 /* Making sure tiling geometry is sane : */
140 #ifndef X_DISPLAY_MISSING
141 if( !get_flags(geom_flags, WidthValue ) )
142 to_width = DisplayWidth(dpy, screen)*2/3 ;
143 if( !get_flags(geom_flags, HeightValue ) )
144 to_height = DisplayHeight(dpy, screen)*2/3 ;
145 #else
146 if( !get_flags(geom_flags, WidthValue ) )
147 to_width = 500 ;
148 if( !get_flags(geom_flags, HeightValue ) )
149 to_height = 500 ;
150 #endif
151 printf( "%s: rendering gradient of type %d to %dx%d0,
152 get_application_name(), grad.type&GRADIENT_TYPE_MASK,
153 to_width, to_height );
154
155 /* see ASView.3 : */
156 asv = create_asvisual( dpy, screen, depth, NULL );
157 /* see ASGrad.2 : */
158 grad_im = make_gradient( asv, &grad, to_width, to_height,
159 SCL_DO_ALL,
160 #ifndef X_DISPLAY_MISSING
161 ASA_XImage,
162 #else
163 ASA_ASImage,
164 #endif
165 0, ASIMAGE_QUALITY_DEFAULT );
166 if( grad_im )
167 {
168 #ifndef X_DISPLAY_MISSING
169 /* see ASView.4 : */
170 Window w = create_top_level_window( asv,
171 DefaultRootWindow(dpy), 32, 32,
172 to_width, to_height, 1, 0, NULL,
173 "ASGradient", NULL );
174 if( w != None )
175 {
176 Pixmap p ;
177
178 XMapRaised (dpy, w);
179 /* see ASView.5 : */
180 p = asimage2pixmap( asv, DefaultRootWindow(dpy), grad_im,
181 NULL, True );
182 destroy_asimage( &grad_im );
183 /* see common.c: set_window_background_and_free() : */
184 p = set_window_background_and_free( w, p );
185 /* see common.c: wait_closedown() : */
186 wait_closedown(w);
187 }
188 if( dpy )
189 XCloseDisplay (dpy);
190 #else
191 ASImage2file( grad_im, NULL, "asgrad.jpg", ASIT_Jpeg, NULL );
192 destroy_asimage( &grad_im );
193 #endif
194 }
195 return 0 ;
196 }
197
199 Step 1. Building gradient specs.
200
202 Multipoint gradient is defined as set of color values with offsets
203 of each point from the beginning of the gradient on 1.0 scale.
204 Offsets of the first and last point in gradient should always be
205 0. and 1.0 respectively, and other points should go in between.
206 For example 2 point gradient will have always offsets 0. and 1.0,
207 3 points gradient will have 0. for first color, 1.0 for last color
208 and anything in between for middle color.
209 If offset is incorrect - point will be skipped at the time of
210 rendering.
211
212 There are 4 types of gradients supported : horizontal, top-left to
213 bottom-right diagonal, vertical and top-right to bottom-left diagonal.
214 Any cilindrical gradient could be drawn as a 3 point gradient with
215 border colors being the same.
216
217 Each gradient point has ARGB color, which means that it is possible
218 to draw gradients in alpha channel as well as RGB. That makes for
219 semitransparent gradients, fading gradients, etc.
220
222 grad.type = atoi( argv[2] );
223 grad.npoints = 0 ;
224 grad.color = safemalloc( ((argc-2)/2)*sizeof(ARGB32));
225 grad.offset = safemalloc( ((argc-2)/2)*sizeof(double));
226 while( ++i < argc )
227 {
228 if( grad.npoints > 0 )
229 {
230 if( i == argc-1 )
231 grad.offset[grad.npoints] = 1.0;
232 else
233 grad.offset[grad.npoints] = atof( argv[i] );
234 ++i ;
235 }
236 if( parse_argb_color( argv[i], &(grad.color[grad.npoints]))
237 != argv[i] )
238 if(grad.offset[grad.npoints] >= 0. &&
239 grad.offset[grad.npoints]<= 1.0 )
240 grad.npoints++ ;
241 }
242
244 ARGB32, parse_argb_color(), ASGradient
245
247 Step 2. Actually rendering gradient.
248
250 All that is needed to draw gradient is to call make_gradient(),
251 passing pointer to ASGradient structure, that describes gradient.
252 Naturally size of the gradient is needed too. Another parameter is
253 filter - that is a bit mask that allows to draw gradient using only a
254 subset of the channels, represented by set bits. SCL_DO_ALL means
255 that all 4 channels must be rendered.
256 make_gradient() creates ASImage of requested size and fills it with
257 gradient. Special techinque based on error diffusion is utilized to
258 avoid sharp steps between grades of colors when limited range of
259 colors is used for gradient.
260
262 grad_im = make_gradient( asv, &grad, to_width, to_height,
263 SCL_DO_ALL,
264 ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT );
265
267 make_gradient(), ASScanline, ASImage.
268
269
270
2713rd Berkeley Distribution AfterStep v.2.2.6 asgrad(1)