#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
#include "RenderLogo.h"
typedef struct _XLineDouble {
XPointDouble p1, p2;
} XLineDouble;
static void
intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection);
void
RenderLogo(Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat *maskFormat,
int x, int y, unsigned int width, unsigned int height)
{
unsigned int size;
double thin, thick, gap, d31;
XPointDouble poly[6];
XLineDouble thick_left, thick_right, thin_left, thin_right, gap_left, gap_right;
size = width;
if (height < width)
size = height;
size &= ~1;
x += (width - size) >> 1;
y += (height - size) >> 1;
thin = (size / 11.0);
thick = (size / 4.0);
gap = thin / 4.0;
d31 = thin + thin + gap;
thick_left.p1.x = x; thick_left.p1.y = y;
thick_left.p2.x = x + size - thick; thick_left.p2.y = y + size;
thick_right.p1.x = x + thick; thick_right.p1.y = y;
thick_right.p2.x = x + size; thick_right.p2.y = y + size;
thin_left.p1.x = x + size-d31; thin_left.p1.y = y;
thin_left.p2.x = x + 0; thin_left.p2.y = y + size;
thin_right.p1.x = x + size; thin_right.p1.y = y;
thin_right.p2.x = x + d31; thin_right.p2.y = y + size;
gap_left.p1.x = x + size-( thin+gap); gap_left.p1.y = y;
gap_left.p2.x = x + thin; gap_left.p2.y = y + size;
gap_right.p1.x = x + size- thin; gap_right.p1.y = y;
gap_right.p2.x = x + thin + gap; gap_right.p2.y = y + size;
poly[0] = thick_left.p1;
poly[1] = thick_right.p1;
intersect(&thick_right, &gap_left, &poly[2]);
poly[3] = gap_left.p2;
poly[4] = thin_left.p2;
intersect(&thick_left, &thin_left, &poly[5]);
XRenderCompositeDoublePoly(dpy, op,
src, dst, maskFormat,
0, 0, 0, 0,
poly, 6, 0);
poly[0] = thin_right.p1;
poly[1] = gap_right.p1;
intersect(&thick_left, &gap_right, &poly[2]);
poly[3] = thick_left.p2;
poly[4] = thick_right.p2;
intersect(&thick_right, &thin_right, &poly[5]);
XRenderCompositeDoublePoly(dpy, op,
src, dst, maskFormat,
0, 0, 0, 0,
poly, 6, 0);
}
static double
compute_inverse_slope (XLineDouble *l)
{
return ((l->p2.x - l->p1.x) /
(l->p2.y - l->p1.y));
}
static double
compute_x_intercept(XLineDouble *l, double inverse_slope)
{
return (l->p1.x) - inverse_slope * l->p1.y;
}
static void
intersect(XLineDouble *l1, XLineDouble *l2, XPointDouble *intersection)
{
double check;
double m1 = compute_inverse_slope (l1);
double b1 = compute_x_intercept (l1, m1);
double m2 = compute_inverse_slope (l2);
double b2 = compute_x_intercept (l2, m2);
intersection->y = (b2 - b1) / (m1 - m2);
intersection->x = m1 * intersection->y + b1;
check = m2 * intersection->y + b2;
if (check >= intersection->x)
check -= intersection->x;
else
check = intersection->x - check;
if (check > (1/(double)(1<<16))) {
fprintf(stderr, "intersect: intersection is off by %f\n", check);
}
}