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