fcc12ff3c256b1f2b73a6b73491bd1fc9fe6ea46
[xscreensaver] / utils / logo.c
1 /* xscreensaver, Copyright (c) 2001 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* This draws the XScreenSaver logo.
13    Logo designed by Angela Goodman <rzr_grl@yahoo.com>
14
15    The reason this C looks a lot like PostScript is that the logo was
16    designed in Illustrator, and then I (jwz) translated the EPS to C
17    by hand.
18  */
19
20 #include "utils.h"
21 #include "resources.h"
22 #include "yarandom.h"
23 #include "spline.h"
24
25 extern const char *progname;
26
27 typedef struct {
28   Display *dpy;
29   Drawable drawable;
30   GC gc;
31
32   double x_scale;
33   double y_scale;
34   double translate_x;
35   double translate_y;
36   double current_x;
37   double current_y;
38   double path_x;
39   double path_y;
40
41   int y_origin;
42
43   unsigned long logo_bg_pixel;
44   unsigned long logo_fg_pixel;
45   unsigned long monitor_fg_pixel;
46   unsigned long monitor_bg_pixel;
47   unsigned long flame1_fg_pixel;
48   unsigned long flame1_bg_pixel;
49   unsigned long flame2_fg_pixel;
50   unsigned long flame2_bg_pixel;
51
52   XPoint points[1024];
53   int npoints;
54
55 } logo_state;
56
57
58 #undef UNDEF
59 #define UNDEF -65535
60
61 static void
62 reset (logo_state *state)
63 {
64   state->x_scale = 1;
65   state->y_scale = 1;
66   state->translate_x = 0;
67   state->translate_y = 0;
68   state->current_x = UNDEF;
69   state->current_y = UNDEF;
70   state->path_x = UNDEF;
71   state->path_y = UNDEF;
72   state->npoints = 0;
73 }
74
75 static void
76 scale (logo_state *state, double x, double y)
77 {
78   state->x_scale *= x;
79   state->y_scale *= y;
80 }
81
82 static void
83 translate (logo_state *state, double x, double y)
84 {
85   state->translate_x += x;
86   state->translate_y += y;
87 }
88
89 static void
90 newpath (logo_state *state)
91 {
92   state->current_x = UNDEF;
93   state->current_y = UNDEF;
94   state->path_x = UNDEF;
95   state->path_y = UNDEF;
96
97   state->npoints = 0;
98 }
99
100 static void
101 moveto (logo_state *state, double x, double y)
102 {
103   x += state->translate_x;
104   y += state->translate_y;
105   if (state->path_x == UNDEF)
106     {
107       state->path_x = x;
108       state->path_y = y;
109     }
110   state->current_x = x;
111   state->current_y = y;
112 }
113
114 static void
115 lineto (logo_state *state, double x, double y)
116 {
117   int x1 =                   (int) (state->x_scale * state->current_x);
118   int y1 = state->y_origin - (int) (state->y_scale * state->current_y);
119   int x2 =                   (int) (state->x_scale * (x + state->translate_x));
120   int y2 = state->y_origin - (int) (state->y_scale * (y + state->translate_y));
121
122   if (state->current_x == UNDEF) abort();
123
124   if (state->npoints == 0 ||
125       state->points[state->npoints-1].x != x1 ||
126       state->points[state->npoints-1].y != y1)
127     {
128       state->points[state->npoints].x = x1;
129       state->points[state->npoints].y = y1;
130       state->npoints++;
131     }
132   state->points[state->npoints].x = x2;
133   state->points[state->npoints].y = y2;
134   state->npoints++;
135
136   moveto(state, x, y);
137 }
138
139 static void
140 curveto (logo_state *state,
141          double x1, double y1,
142          double x2, double y2,
143          double x3, double y3)
144 {
145   spline s;
146   double sx[4], sy[4];
147   int i;
148
149   if (state->current_x == UNDEF) abort();
150
151   sx[0] =                    state->x_scale * state->current_x;
152   sy[0] = state->y_origin - (state->y_scale * state->current_y);
153   sx[1] =                    state->x_scale * (x1 + state->translate_x);
154   sy[1] = state->y_origin - (state->y_scale * (y1 + state->translate_y));
155   sx[2] =                    state->x_scale * (x2 + state->translate_x);
156   sy[2] = state->y_origin - (state->y_scale * (y2 + state->translate_y));
157   sx[3] =                    state->x_scale * (x3 + state->translate_x);
158   sy[3] = state->y_origin - (state->y_scale * (y3 + state->translate_y));
159
160   memset(&s, 0, sizeof(s));
161   s.control_x = sx;
162   s.control_y = sy;
163   s.n_controls = 4;
164
165   s.allocated_points = 50;  /* just the initial buffer size */
166   s.points = (XPoint *) calloc (s.allocated_points, sizeof (*s.points));
167   compute_spline(&s);
168
169   for (i = 0; i < s.n_points; i++)
170     {
171       state->points[state->npoints].x = s.points[i].x;
172       state->points[state->npoints].y = s.points[i].y;
173       state->npoints++;
174     }
175
176   state->current_x = (state->points[state->npoints-1].x
177                       / state->x_scale);
178   state->current_y = ((state->y_origin - state->points[state->npoints-1].y)
179                       / state->y_scale);
180   free (s.points);
181 }
182
183
184 static void
185 closepath (logo_state *state)
186 {
187   if (state->current_x != UNDEF)
188     lineto (state,
189             state->path_x - state->translate_x,
190             state->path_y - state->translate_y);
191 }
192
193 static void
194 stroke (logo_state *state)
195 {
196   XDrawLines (state->dpy, state->drawable, state->gc,
197               state->points, state->npoints,
198               CoordModeOrigin);
199 }
200
201 static void
202 fill (logo_state *state)
203 {
204   XFillPolygon (state->dpy, state->drawable, state->gc,
205                 state->points, state->npoints,
206                 Complex, CoordModeOrigin);
207 }
208
209 static void
210 setlinewidth (logo_state *state, double w)
211 {
212   XSetLineAttributes (state->dpy, state->gc,
213                       (int) (w * state->x_scale),
214                       LineSolid, CapRound, JoinRound);
215 }
216
217 static void
218 setcolor (logo_state *state, unsigned long pixel)
219 {
220   XSetForeground (state->dpy, state->gc, pixel);
221 }
222
223
224 static void
225 border (logo_state *state)
226 {
227   setlinewidth(state, 4);
228
229   newpath (state);
230   moveto (state, 390.7588, 335.9102);
231   lineto (state, 390.7588, 333.4834);
232   lineto (state, 388.5283, 331.5156);
233   lineto (state, 385.7754, 331.5156);
234   lineto (state, 220.2090, 331.5156);
235   lineto (state, 217.4570, 331.5156);
236   lineto (state, 215.2256, 333.4834);
237   lineto (state, 215.2256, 335.9102);
238   lineto (state, 215.2256, 481.3916);
239   lineto (state, 215.2256, 483.8184);
240   lineto (state, 217.4570, 485.7856);
241   lineto (state, 220.2090, 485.7856);
242   lineto (state, 385.7754, 485.7856);
243   lineto (state, 388.5283, 485.7856);
244   lineto (state, 390.7588, 483.8184);
245   lineto (state, 390.7588, 481.3916);
246   lineto (state, 390.7588, 335.9102);
247   closepath (state);
248
249   setcolor (state, state->logo_bg_pixel);
250   fill (state);
251
252   setcolor (state, state->logo_fg_pixel);
253   stroke (state);
254 }
255
256 static void
257 monitor (logo_state *state)
258 {
259   setlinewidth (state, 0);
260
261   setcolor (state, state->monitor_fg_pixel);
262
263   newpath (state);
264   moveto (state, 377.3408, 366.4893);
265   lineto (state, 377.3408, 363.1758);
266   lineto (state, 374.6543, 360.4893);
267   lineto (state, 371.3408, 360.4893);
268   lineto (state, 234.6743, 360.4893);
269   lineto (state, 231.3608, 360.4893);
270   lineto (state, 228.6743, 363.1758);
271   lineto (state, 228.6743, 366.4893);
272   lineto (state, 228.6743, 461.1563);
273   lineto (state, 228.6743, 464.4697);
274   lineto (state, 231.3608, 467.1563);
275   lineto (state, 234.6743, 467.1563);
276   lineto (state, 371.3408, 467.1563);
277   lineto (state, 374.6543, 467.1563);
278   lineto (state, 377.3408, 464.4697);
279   lineto (state, 377.3408, 461.1563);
280   lineto (state, 377.3408, 366.4893);
281   closepath (state);
282   fill (state);
283
284   newpath (state);
285   moveto (state, 325.7354, 369.5391);
286   lineto (state, 322.2354, 375.0391);
287   lineto (state, 318.2354, 351.5391);
288   lineto (state, 342.2354, 344.5391);
289   lineto (state, 265.4619, 344.5391);
290   lineto (state, 289.4619, 351.5391);
291   lineto (state, 285.4619, 375.0391);
292   lineto (state, 281.9619, 369.5391);
293   lineto (state, 325.7354, 369.5391);
294   closepath (state);
295   fill (state);
296
297   newpath (state);
298   moveto (state, 342.9453, 343.0273);
299   lineto (state, 342.9453, 342.1924);
300   lineto (state, 342.2539, 341.5156);
301   lineto (state, 341.4043, 341.5156);
302   lineto (state, 266.0039, 341.5156);
303   lineto (state, 265.1523, 341.5156);
304   lineto (state, 264.4639, 342.1924);
305   lineto (state, 264.4639, 343.0273);
306   lineto (state, 264.4639, 343.0273);
307   lineto (state, 264.4639, 343.8623);
308   lineto (state, 265.1523, 344.5391);
309   lineto (state, 266.0039, 344.5391);
310   lineto (state, 341.4043, 344.5391);
311   lineto (state, 342.2539, 344.5391);
312   lineto (state, 342.9453, 343.8623);
313   lineto (state, 342.9453, 343.0273);
314   lineto (state, 342.9453, 343.0273);
315   closepath (state);
316   stroke (state);
317   fill (state);
318
319   newpath (state);
320   moveto (state, 360.3711, 382.1641);
321   lineto (state, 360.3711, 378.8506);
322   lineto (state, 357.6846, 376.1641);
323   lineto (state, 354.3711, 376.1641);
324   lineto (state, 253.0381, 376.1641);
325   lineto (state, 249.7246, 376.1641);
326   lineto (state, 247.0381, 378.8506);
327   lineto (state, 247.0381, 382.1641);
328   lineto (state, 247.0381, 444.1641);
329   lineto (state, 247.0381, 447.4775);
330   lineto (state, 249.7246, 450.1641);
331   lineto (state, 253.0381, 450.1641);
332   lineto (state, 354.3711, 450.1641);
333   lineto (state, 357.6846, 450.1641);
334   lineto (state, 360.3711, 447.4775);
335   lineto (state, 360.3711, 444.1641);
336   lineto (state, 360.3711, 382.1641);
337   closepath (state);
338
339   setcolor (state, state->monitor_bg_pixel);
340   fill (state);
341 }
342
343
344 static void
345 flames_0a (logo_state *state)
346 {
347   setlinewidth (state, 2);
348
349   newpath (state);
350   moveto (state, 268.1118, 375.1055);
351   lineto (state, 278.0723, 371.9902);
352   lineto (state, 285.0166, 362.1172);
353   lineto (state, 307.6953, 356.7012);
354   lineto (state, 328.5361, 364.6758);
355   lineto (state, 339.9619, 383.5098);
356   lineto (state, 345.8936, 389.6660);
357   lineto (state, 343.8018, 403.9888);
358   lineto (state, 340.0576, 432.1499);
359   lineto (state, 332.6553, 443.0522);
360   lineto (state, 319.5771, 453.9092);
361   lineto (state, 308.0566, 485.2700);
362   lineto (state, 318.7891, 505.4521);
363   lineto (state, 325.9775, 515.9902);
364   lineto (state, 288.2168, 468.6289);
365   lineto (state, 304.2290, 442.3589);
366   lineto (state, 318.9365, 416.1494);
367   lineto (state, 313.5049, 417.6880);
368   lineto (state, 311.5088, 418.7856);
369   lineto (state, 306.4565, 424.1489);
370   lineto (state, 308.7578, 428.8916);
371   lineto (state, 297.6426, 440.9727);
372   lineto (state, 282.4565, 457.4297);
373   lineto (state, 280.1528, 461.7734);
374   lineto (state, 296.6025, 495.0522);
375   lineto (state, 301.0166, 499.0298);
376   lineto (state, 277.2920, 523.6685);
377   lineto (state, 275.7539, 530.4106);
378   lineto (state, 277.2920, 523.6685);
379   lineto (state, 293.3374, 492.3101);
380   lineto (state, 277.8828, 480.4922);
381   lineto (state, 265.1763, 462.8696);
382   lineto (state, 265.9390, 450.7354);
383   lineto (state, 264.7095, 445.1323);
384   lineto (state, 268.3765, 438.5493);
385   lineto (state, 275.4170, 425.7495);
386   lineto (state, 278.5762, 413.9326);
387   lineto (state, 284.3765, 406.5493);
388   lineto (state, 284.7471, 391.6973);
389   lineto (state, 275.8027, 404.2261);
390   lineto (state, 273.8164, 414.5488);
391   lineto (state, 252.3760, 431.5088);
392   lineto (state, 257.4292, 460.0386);
393   lineto (state, 269.9766, 491.3496);
394   lineto (state, 240.8564, 433.4292);
395   lineto (state, 244.6030, 410.4658);
396   lineto (state, 256.2168, 392.4688);
397   lineto (state, 270.3921, 380.3086);
398   lineto (state, 268.1118, 375.1055);
399   closepath (state);
400
401   setcolor (state, state->flame1_bg_pixel);
402   fill (state);
403
404   setcolor (state, state->flame1_fg_pixel);
405   stroke (state);
406 }
407
408
409 static void
410 flames_0b (logo_state *state)
411 {
412   setlinewidth (state, 0.8);
413
414   newpath (state);
415   moveto (state, 263.0464, 378.707);
416   curveto (state, 271.0464, 370.0410, 280.3799, 358.7070, 303.0464, 360.0410);
417   curveto (state, 325.7129, 361.3730, 339.7129, 382.0410, 341.7129, 392.7070);
418   curveto (state, 343.7129, 403.3740, 337.7129, 432.7080, 327.0459, 444.0410);
419   curveto (state, 316.3799, 455.3740, 304.3794, 488.0410, 313.7129, 504.0410);
420   curveto (state, 323.0469, 520.0410, 283.7129, 470.7070, 299.7129, 443.3740);
421   curveto (state, 315.7129, 416.0410, 310.0547, 417.6440, 306.7129, 420.7075);
422   curveto (state, 302.7129, 424.3740, 305.1094, 429.3140, 293.3799, 442.0410);
423   curveto (state, 277.7129, 459.0410, 275.3135, 463.5659, 292.3799, 494.0410);
424
425   /* y = "2 copy curveto", e.g., curveto(x1, y1, x2, y2, x2, y2) */
426   curveto (state, 297.0464, 502.3740, 272.3330, 528.0396, 272.3330, 528.0396);
427   /* v = "currentpoint 6 2 roll curveto", e.g.,
428      curveto (current_x, current_y, x1, x2, y1, y2) */
429   curveto (state, 272.3330, 528.0396, 289.0469, 495.3745, 274.3799, 480.0410);
430   curveto (state, 259.7129, 464.7075, 260.5073, 452.0679, 261.7129, 446.0410);
431   curveto (state, 263.0464, 439.3740, 270.3799, 426.0410, 275.0464, 416.0410);
432   curveto (state, 279.7129, 406.0410, 280.0986, 390.5684, 272.3799, 406.7075);
433   curveto (state, 268.7129, 414.3740, 246.3794, 432.0405, 254.7129, 460.3740);
434   curveto (state, 264.7129, 494.3740, 234.3799, 434.0410, 242.3799, 412.7075);
435   curveto (state, 250.3799, 391.3730, 263.0464, 378.7070, 263.0464, 378.7070);
436   closepath (state);
437
438   setcolor (state, state->flame2_bg_pixel);
439   fill (state);
440
441   setcolor (state, state->flame2_fg_pixel);
442   stroke (state);
443 }
444
445
446 static void
447 flames_1a (logo_state *state)
448 {
449   setlinewidth (state, 2);
450
451   newpath (state);
452   moveto (state, 268.1118, 375.1055);
453   lineto (state, 278.0723, 371.9902);
454   lineto (state, 285.0166, 362.1172);
455   lineto (state, 307.6953, 356.7012);
456   lineto (state, 328.5361, 364.6758);
457   lineto (state, 339.9619, 383.5098);
458   lineto (state, 345.8936, 389.666);
459   lineto (state, 343.8018, 403.9888);
460   lineto (state, 340.0576, 432.1499);
461   lineto (state, 332.6553, 443.0522);
462   lineto (state, 319.5771, 453.9092);
463   lineto (state, 308.0566, 485.27);
464   lineto (state, 318.7891, 505.4521);
465   lineto (state, 325.9775, 515.9902);
466   lineto (state, 288.2168, 468.6289);
467   lineto (state, 304.229, 442.3589);
468   lineto (state, 318.9365, 416.1494);
469   lineto (state, 313.5049, 417.688);
470   lineto (state, 311.5088, 418.7856);
471   lineto (state, 306.4565, 424.1489);
472   lineto (state, 308.7578, 428.8916);
473   lineto (state, 297.6426, 440.9727);
474   lineto (state, 282.4565, 457.4297);
475   lineto (state, 280.1528, 461.7734);
476   lineto (state, 296.6025, 495.0522);
477   lineto (state, 301.0166, 499.0298);
478   lineto (state, 277.292, 523.6685);
479   lineto (state, 275.7539, 530.4106);
480   lineto (state, 277.292, 523.6685);
481   lineto (state, 293.3374, 492.3101);
482   lineto (state, 277.8828, 480.4922);
483   lineto (state, 265.1763, 462.8696);
484   lineto (state, 265.939, 450.7354);
485   lineto (state, 264.7095, 445.1323);
486   lineto (state, 268.3765, 438.5493);
487   lineto (state, 275.417, 425.7495);
488   lineto (state, 278.5762, 413.9326);
489   lineto (state, 284.3765, 406.5493);
490   lineto (state, 284.7471, 391.6973);
491   lineto (state, 275.8027, 404.2261);
492   lineto (state, 273.8164, 414.5488);
493   lineto (state, 252.376, 431.5088);
494   lineto (state, 257.4292, 460.0386);
495   lineto (state, 269.9766, 491.3496);
496   lineto (state, 240.8564, 433.4292);
497   lineto (state, 244.603, 410.4658);
498   lineto (state, 256.2168, 392.4688);
499   lineto (state, 270.3921, 380.3086);
500   lineto (state, 268.1118, 375.1055);
501   closepath (state);
502
503   setcolor (state, state->flame1_bg_pixel);
504   fill (state);
505
506   setcolor (state, state->flame1_fg_pixel);
507   stroke (state);
508 }
509
510 static void
511 flames_1b (logo_state *state)
512 {
513   setlinewidth (state, 0.8);
514
515   newpath (state);
516   moveto (state, 271.0469, 382.041);
517   curveto (state, 279.0469, 373.375, 288.3804, 362.041, 311.0469, 363.375);
518   curveto (state, 333.7129, 364.707, 347.7129, 385.375, 349.7129, 396.0405);
519   curveto (state, 351.7129, 406.707, 347.3818, 437.8853, 335.0469, 447.374);
520   curveto (state, 313.0, 464.3335, 312.3789, 491.374, 321.7129, 507.374);
521   curveto (state, 331.0469, 523.374, 291.7134, 474.04, 307.7129, 446.707);
522   curveto (state, 323.7129, 419.374, 318.0547, 420.9771, 314.7129, 424.0405);
523   curveto (state, 310.7129, 427.707, 313.1094, 432.647, 301.3804, 445.374);
524   curveto (state, 285.7134, 462.374, 283.314, 466.8989, 300.3804, 497.374);
525   curveto (state, 305.0474, 505.707, 277.667, 518.9995, 277.667, 518.9995);
526   curveto (state, 277.667, 518.9995, 297.0474, 498.7075, 282.3804, 483.374);
527   curveto (state, 267.7134, 468.0405, 268.5078, 455.4009, 269.7134, 449.374);
528   curveto (state, 271.0469, 442.707, 278.3804, 429.374, 283.0469, 419.374);
529   curveto (state, 287.7134, 409.374, 288.0991, 393.9023, 280.3804, 410.0405);
530   curveto (state, 276.7134, 417.707, 254.3799, 435.3735, 262.7134, 463.707);
531   curveto (state, 272.7134, 497.707, 246.3335, 428.3335, 254.3335, 407.0);
532   curveto (state, 262.3335, 385.666, 271.0469, 382.041, 271.0469, 382.041);
533   closepath (state);
534
535   setcolor (state, state->flame2_bg_pixel);
536   fill (state);
537
538   setcolor (state, state->flame2_fg_pixel);
539   stroke (state);
540 }
541
542
543 static void
544 flames_2a (logo_state *state)
545 {
546   setlinewidth (state, 2);
547
548   newpath (state);
549   moveto (state, 268.1118, 375.1055);
550   lineto (state, 278.0723, 371.9902);
551   lineto (state, 285.0166, 362.1172);
552   lineto (state, 307.6953, 356.7012);
553   lineto (state, 328.5361, 364.6758);
554   lineto (state, 335.0684, 383.8438);
555   lineto (state, 341.0, 390.0);
556   lineto (state, 338.9082, 404.3228);
557   lineto (state, 340.0576, 432.1499);
558   lineto (state, 332.6553, 443.0522);
559   lineto (state, 319.5771, 453.9092);
560   lineto (state, 312.6006, 479.4844);
561   lineto (state, 323.333, 499.6665);
562   lineto (state, 330.5215, 510.2046);
563   lineto (state, 288.2168, 468.6289);
564   lineto (state, 304.229, 442.3589);
565   lineto (state, 318.9365, 416.1494);
566   lineto (state, 313.5049, 417.688);
567   lineto (state, 311.5088, 418.7856);
568   lineto (state, 306.4565, 424.1489);
569   lineto (state, 308.7578, 428.8916);
570   lineto (state, 297.6426, 440.9727);
571   lineto (state, 282.4565, 457.4297);
572   lineto (state, 280.1528, 461.7734);
573   lineto (state, 296.6025, 495.0522);
574   lineto (state, 301.0166, 499.0298);
575   lineto (state, 277.292, 523.6685);
576   lineto (state, 275.7539, 530.4106);
577   lineto (state, 277.292, 523.6685);
578   lineto (state, 293.3374, 492.3101);
579   lineto (state, 277.8828, 480.4922);
580   lineto (state, 265.1763, 462.8696);
581   lineto (state, 265.939, 450.7354);
582   lineto (state, 264.7095, 445.1323);
583   lineto (state, 268.3765, 438.5493);
584   lineto (state, 275.417, 425.7495);
585   lineto (state, 278.5762, 413.9326);
586   lineto (state, 284.3765, 406.5493);
587   lineto (state, 284.7471, 391.6973);
588   lineto (state, 275.8027, 404.2261);
589   lineto (state, 273.8164, 414.5488);
590   lineto (state, 251.8291, 429.9214);
591   lineto (state, 255.3203, 464.5493);
592   lineto (state, 254.7437, 462.4072);
593   lineto (state, 247.2534, 427.2969);
594   lineto (state, 251.0, 404.3335);
595   lineto (state, 262.6138, 386.3359);
596   lineto (state, 270.3921, 380.3086);
597   lineto (state, 268.1118, 375.1055);
598   closepath (state);
599
600   setcolor (state, state->flame1_bg_pixel);
601   fill (state);
602
603   setcolor (state, state->flame1_fg_pixel);
604   stroke (state);
605 }
606
607 static void
608 flames_2b (logo_state *state)
609 {
610   setlinewidth (state, 0.8);
611
612   newpath (state);
613   moveto (state, 271.0469, 382.041);
614   curveto (state, 279.0469, 373.375, 288.3804, 362.041, 311.0469, 363.375);
615   curveto (state, 333.7129, 364.707, 336.333, 386.334, 338.333, 397.0);
616   curveto (state, 340.333, 407.6665, 347.3818, 437.8853, 335.0469, 447.374);
617   curveto (state, 313.0, 464.3335, 312.3789, 491.374, 321.7129, 507.374);
618   curveto (state, 331.0469, 523.374, 291.7134, 474.04, 307.7129, 446.707);
619   curveto (state, 323.7129, 419.374, 318.0547, 420.9771, 314.7129, 424.0405);
620   curveto (state, 310.7129, 427.707, 313.1094, 432.647, 301.3804, 445.374);
621   curveto (state, 285.7134, 462.374, 283.314, 466.8989, 300.3804, 497.374);
622   curveto (state, 305.0474, 505.707, 277.667, 518.9995, 277.667, 518.9995);
623   curveto (state, 277.667, 518.9995, 297.0474, 498.7075, 282.3804, 483.374);
624   curveto (state, 267.7134, 468.0405, 268.5078, 455.4009, 269.7134, 449.374);
625   curveto (state, 271.0469, 442.707, 278.3804, 429.374, 283.0469, 419.374);
626   curveto (state, 287.7134, 409.374, 288.0991, 393.9023, 280.3804, 410.0405);
627   curveto (state, 276.7134, 417.707, 254.3799, 435.3735, 262.7134, 463.707);
628   curveto (state, 272.7134, 497.707, 246.3335, 428.3335, 254.3335, 407.0);
629   curveto (state, 262.3335, 385.666, 271.0469, 382.041, 271.0469, 382.041);
630   closepath (state);
631
632   setcolor (state, state->flame2_bg_pixel);
633   fill (state);
634
635   setcolor (state, state->flame2_fg_pixel);
636   stroke (state);
637 }
638
639
640 static void
641 flames_3a (logo_state *state)
642 {
643   setlinewidth (state, 2);
644
645   newpath (state);
646   moveto (state, 268.1118, 375.1055);
647   lineto (state, 278.0723, 371.9902);
648   lineto (state, 285.0166, 362.1172);
649   lineto (state, 307.6953, 356.7012);
650   lineto (state, 328.5361, 364.6758);
651   lineto (state, 339.9619, 383.5098);
652   lineto (state, 345.8936, 389.666);
653   lineto (state, 343.8018, 403.9888);
654   lineto (state, 334.4023, 428.0977);
655   lineto (state, 327.0, 439.0);
656   lineto (state, 309.667, 469.6665);
657   lineto (state, 308.2676, 473.4844);
658   lineto (state, 319.0, 493.6665);
659   lineto (state, 307.667, 482.0);
660   lineto (state, 288.2168, 468.6289);
661   lineto (state, 304.229, 442.3589);
662   lineto (state, 318.9365, 416.1494);
663   lineto (state, 313.5049, 417.688);
664   lineto (state, 311.5088, 418.7856);
665   lineto (state, 306.4565, 424.1489);
666   lineto (state, 305.4487, 426.2524);
667   lineto (state, 294.3335, 438.3335);
668   lineto (state, 279.1475, 454.7905);
669   lineto (state, 280.1528, 461.7734);
670   lineto (state, 296.6025, 495.0522);
671   lineto (state, 301.0166, 499.0298);
672   lineto (state, 299.5381, 511.5913);
673   lineto (state, 298.0, 518.3335);
674   lineto (state, 299.5381, 511.5913);
675   lineto (state, 293.3374, 492.3101);
676   lineto (state, 277.8828, 480.4922);
677   lineto (state, 265.1763, 462.8696);
678   lineto (state, 265.939, 450.7354);
679   lineto (state, 264.7095, 445.1323);
680   lineto (state, 268.3765, 438.5493);
681   lineto (state, 275.417, 425.7495);
682   lineto (state, 278.5762, 413.9326);
683   lineto (state, 284.3765, 406.5493);
684   lineto (state, 284.7471, 391.6973);
685   lineto (state, 275.8027, 404.2261);
686   lineto (state, 273.8164, 414.5488);
687   lineto (state, 252.376, 431.5088);
688   lineto (state, 257.4292, 460.0386);
689   lineto (state, 269.9766, 491.3496);
690   lineto (state, 240.8564, 433.4292);
691   lineto (state, 244.603, 410.4658);
692   lineto (state, 256.2168, 392.4688);
693   lineto (state, 270.3921, 380.3086);
694   lineto (state, 268.1118, 375.1055);
695   closepath (state);
696
697   setcolor (state, state->flame1_bg_pixel);
698   fill (state);
699
700   setcolor (state, state->flame1_fg_pixel);
701   stroke (state);
702 }
703
704 static void
705 flames_3b (logo_state *state)
706 {
707   setlinewidth (state, 0.8);
708
709   newpath (state);
710   moveto (state, 263.0464, 378.707);
711   curveto (state, 271.0464, 370.041, 280.3799, 358.707, 303.0464, 360.041);
712   curveto (state, 325.7129, 361.373, 340.4473, 381.9297, 341.7129, 392.707);
713   curveto (state, 343.0, 403.6665, 331.667, 428.3335, 321.0, 439.6665);
714   curveto (state, 310.334, 450.9995, 308.584, 461.5942, 310.667, 480.0);
715   curveto (state, 312.667, 497.6665, 299.9536, 463.626, 304.6665, 438.3335);
716   lineto (state, 305.3335, 432.3335);
717   curveto (state, 309.0, 419.3335, 316.667, 408.3335, 288.0, 436.6665);
718   curveto (state, 271.5576, 452.9175, 275.3135, 463.5659, 292.3799, 494.041);
719   curveto (state, 297.0464, 502.374, 272.333, 528.0396, 272.333, 528.0396);
720   curveto (state, 272.333, 528.0396, 289.0469, 495.3745, 274.3799, 480.041);
721   curveto (state, 259.7129, 464.7075, 260.5073, 452.0679, 261.7129, 446.041);
722   curveto (state, 263.0464, 439.374, 270.3799, 426.041, 275.0464, 416.041);
723   curveto (state, 279.7129, 406.041, 283.3696, 392.5908, 272.3799, 406.7075);
724   curveto (state, 268.0, 412.3335, 246.3794, 432.0405, 254.7129, 460.374);
725   curveto (state, 264.7129, 494.374, 240.6665, 435.0, 248.6665, 413.6665);
726   curveto (state, 256.6665, 392.332, 263.0464, 378.707, 263.0464, 378.707);
727   closepath (state);
728
729   setcolor (state, state->flame2_bg_pixel);
730   fill (state);
731
732   setcolor (state, state->flame2_fg_pixel);
733   stroke (state);
734 }
735
736
737 static void
738 flames_4a (logo_state *state)
739 {
740   flames_3a (state);
741 }
742
743 static void
744 flames_4b (logo_state *state)
745 {
746   setlinewidth (state, 0.8);
747
748   newpath (state);
749   moveto (state, 263.0464, 378.707);
750   curveto (state, 271.0464, 370.041, 280.3799, 358.707, 303.0464, 360.041);
751   curveto (state, 325.7129, 361.373, 340.4473, 381.9297, 341.7129, 392.707);
752   curveto (state, 343.0, 403.6665, 331.667, 428.3335, 321.0, 439.6665);
753   curveto (state, 310.334, 450.9995, 306.5693, 463.2358, 319.667, 476.3335);
754   curveto (state, 320.667, 477.3335, 299.9536, 463.626, 304.6665, 438.3335);
755   lineto (state, 305.3335, 432.3335);
756   curveto (state, 309.0, 419.3335, 316.667, 408.3335, 288.0, 436.6665);
757   curveto (state, 271.5576, 452.9175, 275.3135, 463.5659, 292.3799, 494.041);
758   curveto (state, 297.0464, 502.374, 272.333, 528.0396, 272.333, 528.0396);
759   curveto (state, 272.333, 528.0396, 289.0469, 495.3745, 274.3799, 480.041);
760   curveto (state, 259.7129, 464.7075, 260.5073, 452.0679, 261.7129, 446.041);
761   curveto (state, 263.0464, 439.374, 270.3799, 426.041, 275.0464, 416.041);
762   curveto (state, 279.7129, 406.041, 313.667, 376.333, 272.3799, 406.7075);
763   curveto (state, 265.9966, 411.4038, 251.333, 417.0, 259.6665, 445.3335);
764   curveto (state, 269.6665, 479.3335, 247.6665, 417.0, 248.6665, 413.6665);
765   curveto (state, 255.2134, 391.8418, 263.0464, 378.707, 263.0464, 378.707);
766   closepath (state);
767
768   setcolor (state, state->flame2_bg_pixel);
769   fill (state);
770
771   setcolor (state, state->flame2_fg_pixel);
772   stroke (state);
773 }
774
775
776 static void flames_6a (logo_state *);
777 static void flames_6b (logo_state *);
778
779 static void
780 flames_5a (logo_state *state)
781 {
782   unsigned long a = state->flame1_bg_pixel;
783   unsigned long b = state->flame2_bg_pixel;
784   state->flame1_bg_pixel = b;
785   state->flame2_bg_pixel = a;
786   flames_6a (state);
787   state->flame1_bg_pixel = a;
788   state->flame2_bg_pixel = b;
789 }
790
791 static void
792 flames_5b (logo_state *state)
793 {
794   unsigned long a = state->flame1_bg_pixel;
795   unsigned long b = state->flame2_bg_pixel;
796   state->flame1_bg_pixel = b;
797   state->flame2_bg_pixel = a;
798   flames_6b (state);
799   state->flame1_bg_pixel = a;
800   state->flame2_bg_pixel = b;
801 }
802
803
804 static void
805 flames_6a (logo_state *state)
806 {
807   flames_3a (state);
808 }
809
810 static void
811 flames_6b (logo_state *state)
812 {
813   setlinewidth (state, 0.8);
814
815   newpath (state);
816   moveto (state, 263.0464, 378.707);
817   curveto (state, 271.0464, 370.041, 280.3799, 358.707, 303.0464, 360.041);
818   curveto (state, 325.7129, 361.373, 340.4473, 381.9297, 341.7129, 392.707);
819   curveto (state, 343.0, 403.6665, 331.667, 428.3335, 321.0, 439.6665);
820   curveto (state, 310.334, 450.9995, 306.5693, 463.2358, 319.667, 476.3335);
821   curveto (state, 320.667, 477.3335, 299.9536, 463.626, 304.6665, 438.3335);
822   lineto (state, 305.3335, 432.3335);
823   curveto (state, 309.0, 419.3335, 316.667, 408.3335, 288.0, 436.6665);
824   curveto (state, 271.5576, 452.9175, 275.3135, 463.5659, 292.3799, 494.041);
825   curveto (state, 297.0464, 502.374, 272.333, 528.0396, 272.333, 528.0396);
826   curveto (state, 272.333, 528.0396, 289.0469, 495.3745, 274.3799, 480.041);
827   curveto (state, 259.7129, 464.7075, 260.5073, 452.0679, 261.7129, 446.041);
828   curveto (state, 263.0464, 439.374, 270.3799, 426.041, 275.0464, 416.041);
829   curveto (state, 279.7129, 406.041, 313.667, 376.333, 272.3799, 406.7075);
830   curveto (state, 265.9966, 411.4038, 251.333, 417.0, 259.6665, 445.3335);
831   curveto (state, 269.6665, 479.3335, 247.6665, 417.0, 248.6665, 413.6665);
832   curveto (state, 255.2134, 391.8418, 263.0464, 378.707, 263.0464, 378.707);
833   closepath (state);
834
835   setcolor (state, state->flame2_bg_pixel);
836   fill (state);
837
838   setcolor (state, state->flame2_fg_pixel);
839   stroke (state);
840 }
841
842 static void
843 flames_6c (logo_state *state)
844 {
845   setlinewidth (state, 0.8);
846
847   newpath (state);
848   moveto (state, 293.7134, 370.5859);
849   curveto (state, 299.6665, 366.333, 303.9854, 362.6934, 317.7656, 359.4023);
850   curveto (state, 331.0, 361.667, 337.3711, 375.6924, 340.9766, 379.4326);
851   curveto (state, 339.7051, 388.1357, 333.9941, 402.7852, 329.4961, 409.4097);
852   curveto (state, 318.9629, 428.0435, 310.1455, 425.4028, 316.667, 437.6665);
853   curveto (state, 309.7803, 430.5771, 305.9297, 427.4131, 315.6602, 411.4507);
854   curveto (state, 324.5957, 395.5244, 321.2949, 396.46, 320.082, 397.127);
855   curveto (state, 317.0137, 400.3857, 316.4004, 401.6636, 309.6465, 409.0044);
856   curveto (state, 300.4189, 419.0044, 299.2461, 416.7344, 309.2402, 436.9556);
857   curveto (state, 310.2539, 440.3984, 315.3184, 446.2725, 314.1016, 457.4121);
858   curveto (state, 315.0371, 453.3154, 309.041, 441.8022, 299.6504, 434.6216);
859   curveto (state, 291.9297, 423.9136, 292.3931, 416.54, 291.646, 413.1357);
860   curveto (state, 293.874, 409.1357, 298.1523, 401.3579, 300.0718, 394.1777);
861   curveto (state, 303.5962, 389.6914, 289.9995, 396.4463, 289.9995, 396.4463);
862   curveto (state, 285.3413, 401.5103, 269.5962, 401.9976, 272.6665, 419.3335);
863   curveto (state, 269.3335, 402.0, 277.1523, 406.0244, 279.4287, 392.0713);
864   curveto (state, 286.4858, 381.1357, 291.6665, 375.0, 293.7134, 370.5859);
865   closepath (state);
866
867   setcolor (state, state->flame1_bg_pixel);
868   fill (state);
869
870   setcolor (state, state->flame1_fg_pixel);
871   stroke (state);
872 }
873
874
875 static void
876 flames_7a (logo_state *state)
877 {
878   setlinewidth (state, 2);
879
880   newpath (state);
881   moveto (state, 268.1118, 375.1055);
882   lineto (state, 278.0723, 371.9902);
883   lineto (state, 285.0166, 362.1172);
884   lineto (state, 307.6953, 356.7012);
885   lineto (state, 328.5361, 364.6758);
886   lineto (state, 339.9619, 383.5098);
887   lineto (state, 345.8936, 389.666);
888   lineto (state, 343.8018, 403.9888);
889   lineto (state, 340.0576, 432.1499);
890   lineto (state, 332.6553, 443.0522);
891   lineto (state, 319.5771, 453.9092);
892   lineto (state, 308.0566, 485.27);
893   lineto (state, 318.7891, 505.4521);
894   lineto (state, 325.9775, 515.9902);
895   lineto (state, 288.2168, 468.6289);
896   lineto (state, 304.229, 442.3589);
897   lineto (state, 318.9365, 416.1494);
898   lineto (state, 313.5049, 417.688);
899   lineto (state, 311.5088, 418.7856);
900   lineto (state, 306.4565, 424.1489);
901   lineto (state, 308.7578, 428.8916);
902   lineto (state, 297.6426, 440.9727);
903   lineto (state, 282.4565, 457.4297);
904   lineto (state, 280.1528, 461.7734);
905   lineto (state, 296.6025, 495.0522);
906   lineto (state, 301.0166, 499.0298);
907   lineto (state, 277.292, 523.6685);
908   lineto (state, 275.7539, 530.4106);
909   lineto (state, 277.292, 523.6685);
910   lineto (state, 293.3374, 492.3101);
911   lineto (state, 277.8828, 480.4922);
912   lineto (state, 265.1763, 462.8696);
913   lineto (state, 265.939, 450.7354);
914   lineto (state, 264.7095, 445.1323);
915   lineto (state, 268.3765, 438.5493);
916   lineto (state, 275.417, 425.7495);
917   lineto (state, 278.5762, 413.9326);
918   lineto (state, 284.3765, 406.5493);
919   lineto (state, 284.7471, 391.6973);
920   lineto (state, 275.8027, 404.2261);
921   lineto (state, 273.8164, 414.5488);
922   lineto (state, 252.376, 431.5088);
923   lineto (state, 257.4292, 460.0386);
924   lineto (state, 269.9766, 491.3496);
925   lineto (state, 240.8564, 433.4292);
926   lineto (state, 244.603, 410.4658);
927   lineto (state, 256.2168, 392.4688);
928   lineto (state, 270.3921, 380.3086);
929   lineto (state, 268.1118, 375.1055);
930   closepath (state);
931
932   setcolor (state, state->flame1_bg_pixel);
933   fill (state);
934
935   setcolor (state, state->flame1_fg_pixel);
936   stroke (state);
937 }
938
939
940 static void
941 flames_7b (logo_state *state)
942 {
943   setlinewidth (state, 0.8);
944
945   newpath (state);
946   moveto (state,  262.0464, 374.7109);
947   curveto (state, 270.0464, 366.9424, 279.3799, 356.7822, 302.0469, 357.9785);
948   curveto (state, 324.7129, 359.1719, 338.7129, 377.6992, 340.7129, 387.2607);
949   curveto (state, 342.7129, 396.8228, 336.7129, 423.1182, 326.0459, 433.2773);
950   curveto (state, 315.3799, 443.4365, 303.3789, 472.7197, 312.7129, 487.0625);
951   curveto (state, 322.0469, 501.4053, 282.7129, 457.1812, 298.7129, 432.6797);
952   curveto (state, 314.7129, 408.1777, 309.0547, 409.6147, 305.7129, 412.3608);
953   curveto (state, 301.7129, 415.6475, 304.1094, 420.0757, 292.3799, 431.4844);
954   curveto (state, 276.7129, 446.7236, 274.3135, 450.7798, 291.3799, 478.0981);
955   curveto (state, 296.0464, 485.5684, 271.333, 508.5752, 271.333, 508.5752);
956   curveto (state, 271.333, 508.5752, 288.0469, 479.2935, 273.3799, 465.5483);
957   curveto (state, 258.7129, 451.8032, 259.5073, 440.4727, 260.7129, 435.0703);
958   curveto (state, 262.0464, 429.0938, 269.3799, 417.1416, 274.0464, 408.1777);
959   curveto (state, 278.7129, 399.2134, 279.0986, 385.3438, 271.3799, 399.811);
960   curveto (state, 267.7129, 406.6831, 245.3794, 422.52, 253.7129, 447.9185);
961   curveto (state, 263.7129, 478.397, 233.3799, 424.313, 241.3799, 405.1895);
962   curveto (state, 249.3799, 386.0645, 262.0464, 374.7109, 262.0464, 374.7109);
963   closepath (state);
964
965   setcolor (state, state->flame2_bg_pixel);
966   fill (state);
967
968   setcolor (state, state->flame2_fg_pixel);
969   stroke (state);
970 }
971
972
973 static unsigned long
974 alloccolor (Display *dpy, Colormap cmap, char *s)
975 {
976   XColor color;
977   if (!XParseColor (dpy, cmap, s, &color))
978     {
979       fprintf (stderr, "%s: can't parse color %s\n", progname, s);
980       return -1;
981     }
982   if (! XAllocColor (dpy, cmap, &color))
983     {
984       fprintf (stderr, "%s: couldn't allocate color %s\n", progname, s);
985       return -1;
986     }
987   return color.pixel;
988 }
989
990
991 /* Draws the logo centered in the given Drawable (presumably a Pixmap.)
992    next_frame_p means randomize the flame shape.
993  */
994 void
995 xscreensaver_logo (Display *dpy, Drawable dest, Colormap cmap,
996                    Bool next_frame_p)
997 {
998   XGCValues gcv;
999   logo_state S;
1000   logo_state *state = &S;
1001   int mono_p;
1002
1003   unsigned int w, h, depth;
1004   unsigned long bg;
1005
1006   state->dpy = dpy;
1007   state->drawable = dest;
1008   state->gc = XCreateGC (dpy, dest, 0, &gcv);
1009
1010   {
1011     Window root;
1012     int x, y;
1013     unsigned int bw;
1014     XGetGeometry (dpy, dest, &root, &x, &y, &w, &h, &bw, &depth);
1015     mono_p = (depth == 1);
1016     state->y_origin = h;
1017   }
1018
1019   if (mono_p)
1020     {
1021       unsigned long white = 1;
1022       unsigned long black = 0;
1023       bg = black;
1024       state->logo_bg_pixel    = white;
1025       state->logo_fg_pixel    = black;
1026       state->monitor_bg_pixel = white;
1027       state->monitor_fg_pixel = black;
1028       state->flame1_bg_pixel  = white;
1029       state->flame1_fg_pixel  = black;
1030       state->flame2_bg_pixel  = white;
1031       state->flame2_fg_pixel  = black;
1032     }
1033   else
1034     {
1035       bg = get_pixel_resource ("background", "Background", dpy, cmap);
1036       state->logo_bg_pixel    = alloccolor (dpy, cmap, "#FFFFFF");
1037       state->logo_fg_pixel    = alloccolor (dpy, cmap, "#000000");
1038 /*      state->monitor_bg_pixel = alloccolor (dpy, cmap, "#00AA00");*/
1039       state->monitor_bg_pixel = alloccolor (dpy, cmap, "#FFFFFF");
1040       state->monitor_fg_pixel = alloccolor (dpy, cmap, "#000000");
1041       state->flame1_bg_pixel  = alloccolor (dpy, cmap, "#FFA500");
1042       state->flame1_fg_pixel  = alloccolor (dpy, cmap, "#000000");
1043       state->flame2_bg_pixel  = alloccolor (dpy, cmap, "#FF0000");
1044       state->flame2_fg_pixel  = alloccolor (dpy, cmap, "#000000");
1045     }
1046
1047   setcolor (state, bg);
1048   XFillRectangle (dpy, dest, state->gc, 0, 0, w, h);
1049
1050   reset (state);
1051   scale (state, w / 220.0, w / 220.0);
1052   translate (state, -193, -315);
1053
1054   border (state);
1055   monitor (state);
1056
1057   if (!next_frame_p)
1058     {
1059       flames_0a (state);
1060       flames_0b (state);
1061     }
1062   else
1063     {
1064       static int tick = 0;
1065       static int tick2 = 0;
1066       if (++tick2 > 3) tick2 = 0;
1067       if (tick2 == 0)
1068         if (++tick > 7) tick = 0;
1069       switch (tick) {
1070       case 0: flames_0a (state); flames_0b (state); break;
1071       case 1: flames_1a (state); flames_1b (state); break;
1072       case 2: flames_2a (state); flames_2b (state); break;
1073       case 3: flames_3a (state); flames_3b (state); break;
1074       case 4: flames_4a (state); flames_4b (state); break;
1075       case 5: flames_5a (state); flames_5b (state); break;
1076       case 6: flames_6a (state); flames_6b (state); flames_6c (state); break;
1077       case 7: flames_7a (state); flames_7b (state); break;
1078       default: abort(); break;
1079       }
1080     }
1081
1082   XFreeGC (dpy, state->gc);
1083 }