RenderLogo.c revision e531b1a7
1/*
2
3Copyright 1988, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <stdio.h>
31
32#include <X11/Xlib.h>
33#include <X11/extensions/Xrender.h>
34
35#include "RenderLogo.h"
36
37typedef struct _XLineDouble {
38    XPointDouble  p1, p2;
39} XLineDouble;
40
41static void
42intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection);
43
44/*
45 *  Draw the "official" X Window System Logo, designed by Danny Chong
46 *
47 *  Written by Ollie Jones, Apollo Computer
48 *
49 *  Does some fancy stuff to make the logo look acceptable even
50 *  if it is tiny.  Also makes the various linear elements of
51 *  the logo line up as well as possible considering rasterization.
52 *
53 *  Munged to draw anti-aliased logo using Render extension.
54 *  Carl Worth, 2002-05-16
55 */
56void
57RenderLogo(Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat *maskFormat,
58	   int x, int y, unsigned int width, unsigned int height)
59{
60    unsigned int size;
61    double thin, thick, gap, d31;
62    XPointDouble poly[6];
63    XLineDouble thick_left, thick_right, thin_left, thin_right, gap_left, gap_right;
64
65    /* for now, do a centered even-sized square, at least for now */
66    size = width;
67    if (height < width)
68	 size = height;
69    size &= ~1;
70    x += (width - size) >> 1;
71    y += (height - size) >> 1;
72
73    thin = (size / 11.0);
74    thick = (size / 4.0);
75    gap = thin / 4.0;
76    d31 = thin + thin + gap;
77
78    thick_left.p1.x = x;		thick_left.p1.y = y;
79    thick_left.p2.x = x + size - thick;	thick_left.p2.y = y + size;
80
81    thick_right.p1.x = x + thick;	thick_right.p1.y = y;
82    thick_right.p2.x = x + size;	thick_right.p2.y = y + size;
83
84    thin_left.p1.x = x + size-d31;	thin_left.p1.y = y;
85    thin_left.p2.x = x + 0;		thin_left.p2.y = y + size;
86
87    thin_right.p1.x = x + size;		thin_right.p1.y = y;
88    thin_right.p2.x = x + d31;		thin_right.p2.y = y + size;
89
90    gap_left.p1.x = x + size-( thin+gap);	gap_left.p1.y = y;
91    gap_left.p2.x = x + thin;			gap_left.p2.y = y + size;
92
93    gap_right.p1.x = x + size- thin;	gap_right.p1.y = y;
94    gap_right.p2.x = x + thin + gap;	gap_right.p2.y = y + size;
95
96    poly[0] = thick_left.p1;
97    poly[1] = thick_right.p1;
98    intersect(&thick_right, &gap_left, &poly[2]);
99    poly[3] = gap_left.p2;
100    poly[4] = thin_left.p2;
101    intersect(&thick_left, &thin_left, &poly[5]);
102
103    XRenderCompositeDoublePoly(dpy, op,
104			       src, dst, maskFormat,
105			       0, 0, 0, 0,
106			       poly, 6, 0);
107
108    poly[0] = thin_right.p1;
109    poly[1] = gap_right.p1;
110    intersect(&thick_left, &gap_right, &poly[2]);
111    poly[3] = thick_left.p2;
112    poly[4] = thick_right.p2;
113    intersect(&thick_right, &thin_right, &poly[5]);
114
115    XRenderCompositeDoublePoly(dpy, op,
116			       src, dst, maskFormat,
117			       0, 0, 0, 0,
118			       poly, 6, 0);
119}
120
121static double
122compute_inverse_slope (XLineDouble *l)
123{
124    return ((l->p2.x - l->p1.x) /
125	    (l->p2.y - l->p1.y));
126}
127
128static double
129compute_x_intercept(XLineDouble *l, double inverse_slope)
130{
131    return (l->p1.x) - inverse_slope * l->p1.y;
132}
133
134static void
135intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection)
136{
137    double check;
138    /*
139     * x = m1y + b1
140     * x = m2y + b2
141     * m1y + b1 = m2y + b2
142     * y * (m1 - m2) = b2 - b1
143     * y = (b2 - b1) / (m1 - m2)
144     */
145    double  m1 = compute_inverse_slope (l1);
146    double  b1 = compute_x_intercept (l1, m1);
147    double  m2 = compute_inverse_slope (l2);
148    double  b2 = compute_x_intercept (l2, m2);
149
150    intersection->y = (b2 - b1) / (m1 - m2);
151    intersection->x = m1 * intersection->y + b1;
152
153    check = m2 * intersection->y + b2;
154    if (check >= intersection->x)
155	check -= intersection->x;
156    else
157	check = intersection->x - check;
158    if (check > (1/(double)(1<<16))) {
159	fprintf(stderr, "intersect: intersection is off by %f\n", check);
160    }
161}
162
163