RenderLogo.c revision 3fe82118
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 31#ifdef XRENDER 32#include <stdio.h> 33 34#include <X11/Xlib.h> 35#include <X11/extensions/Xrender.h> 36 37#include "RenderLogo.h" 38 39typedef struct _XLineDouble { 40 XPointDouble p1, p2; 41} XLineDouble; 42 43static void 44intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection); 45 46/* 47 * Draw the "official" X Window System Logo, designed by Danny Chong 48 * 49 * Written by Ollie Jones, Apollo Computer 50 * 51 * Does some fancy stuff to make the logo look acceptable even 52 * if it is tiny. Also makes the various linear elements of 53 * the logo line up as well as possible considering rasterization. 54 * 55 * Munged to draw anti-aliased logo using Render extension. 56 * Carl Worth, 2002-05-16 57 */ 58void 59RenderLogo(Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat *maskFormat, 60 int x, int y, unsigned int width, unsigned int height) 61{ 62 unsigned int size; 63 double thin, thick, gap, d31; 64 XPointDouble poly[6]; 65 XLineDouble thick_left, thick_right, thin_left, thin_right, gap_left, gap_right; 66 67 /* for now, do a centered even-sized square, at least for now */ 68 size = width; 69 if (height < width) 70 size = height; 71 size &= ~1; 72 x += (width - size) >> 1; 73 y += (height - size) >> 1; 74 75 thin = (size / 11.0); 76 thick = (size / 4.0); 77 gap = thin / 4.0; 78 d31 = thin + thin + gap; 79 80 thick_left.p1.x = x; thick_left.p1.y = y; 81 thick_left.p2.x = x + size - thick; thick_left.p2.y = y + size; 82 83 thick_right.p1.x = x + thick; thick_right.p1.y = y; 84 thick_right.p2.x = x + size; thick_right.p2.y = y + size; 85 86 thin_left.p1.x = x + size-d31; thin_left.p1.y = y; 87 thin_left.p2.x = x + 0; thin_left.p2.y = y + size; 88 89 thin_right.p1.x = x + size; thin_right.p1.y = y; 90 thin_right.p2.x = x + d31; thin_right.p2.y = y + size; 91 92 gap_left.p1.x = x + size-( thin+gap); gap_left.p1.y = y; 93 gap_left.p2.x = x + thin; gap_left.p2.y = y + size; 94 95 gap_right.p1.x = x + size- thin; gap_right.p1.y = y; 96 gap_right.p2.x = x + thin + gap; gap_right.p2.y = y + size; 97 98 poly[0] = thick_left.p1; 99 poly[1] = thick_right.p1; 100 intersect(&thick_right, &gap_left, &poly[2]); 101 poly[3] = gap_left.p2; 102 poly[4] = thin_left.p2; 103 intersect(&thick_left, &thin_left, &poly[5]); 104 105 XRenderCompositeDoublePoly(dpy, op, 106 src, dst, maskFormat, 107 0, 0, 0, 0, 108 poly, 6, 0); 109 110 poly[0] = thin_right.p1; 111 poly[1] = gap_right.p1; 112 intersect(&thick_left, &gap_right, &poly[2]); 113 poly[3] = thick_left.p2; 114 poly[4] = thick_right.p2; 115 intersect(&thick_right, &thin_right, &poly[5]); 116 117 XRenderCompositeDoublePoly(dpy, op, 118 src, dst, maskFormat, 119 0, 0, 0, 0, 120 poly, 6, 0); 121} 122 123static double 124compute_inverse_slope (XLineDouble *l) 125{ 126 return ((l->p2.x - l->p1.x) / 127 (l->p2.y - l->p1.y)); 128} 129 130static double 131compute_x_intercept(XLineDouble *l, double inverse_slope) 132{ 133 return (l->p1.x) - inverse_slope * l->p1.y; 134} 135 136static void 137intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection) 138{ 139 double check; 140 /* 141 * x = m1y + b1 142 * x = m2y + b2 143 * m1y + b1 = m2y + b2 144 * y * (m1 - m2) = b2 - b1 145 * y = (b2 - b1) / (m1 - m2) 146 */ 147 double m1 = compute_inverse_slope (l1); 148 double b1 = compute_x_intercept (l1, m1); 149 double m2 = compute_inverse_slope (l2); 150 double b2 = compute_x_intercept (l2, m2); 151 152 intersection->y = (b2 - b1) / (m1 - m2); 153 intersection->x = m1 * intersection->y + b1; 154 155 check = m2 * intersection->y + b2; 156 if (check >= intersection->x) 157 check -= intersection->x; 158 else 159 check = intersection->x - check; 160 if (check > (1/(double)(1<<16))) { 161 fprintf(stderr, "intersect: intersection is off by %f\n", check); 162 } 163} 164#endif /* XRENDER */ 165