1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
#include "xlib.h"
extern XDrawText(), XDrawText16();
static Object Sym_1byte, Sym_2byte;
static Two_Byte (format) Object format; {
Check_Type (format, T_Symbol);
if (EQ(format, Sym_1byte))
return 0;
else if (EQ(format, Sym_2byte))
return 1;
Primitive_Error ("index format must be '1-byte or '2-byte");
/*NOTREACHED*/
}
static Get_1_Byte_Char (x) Object x; {
register c = Get_Integer (x);
if (c < 0 || c > 255)
Range_Error (x);
return c;
}
static Get_2_Byte_Char (x) Object x; {
register c = Get_Integer (x);
if (c < 0 || c > 65535)
Range_Error (x);
return c;
}
/* Calculation of text widths and extents should not be done using
* the Xlib functions. For instance, the values returned by
* XTextExtents() are only shorts and can therefore overflow for
* long strings.
*/
static Object Internal_Text_Metrics (font, t, f, width) Object font, t, f; {
char *s;
XChar2b *s2;
XFontStruct *info;
Object *data;
register i, n;
int dir, fasc, fdesc;
Alloca_Begin;
Check_Type (font, T_Font);
info = FONT(font)->info;
Check_Type (t, T_Vector);
n = VECTOR(t)->size;
data = VECTOR(t)->data;
if (Two_Byte (f)) {
Alloca (s2, XChar2b*, n * sizeof (XChar2b));
for (i = 0; i < n; i++) {
register c = Get_2_Byte_Char (data[i]);
s2[i].byte1 = (c >> 8) & 0xff;
s2[i].byte2 = c & 0xff;
}
if (width)
i = XTextWidth16 (info, s2, n);
else
XTextExtents16 (info, s2, n, &dir, &fasc, &fdesc, &CI);
} else {
Alloca (s, char*, n);
for (i = 0; i < n; i++)
s[i] = Get_1_Byte_Char (data[i]);
if (width)
i = XTextWidth (info, s, n);
else
XTextExtents (info, s, n, &dir, &fasc, &fdesc, &CI);
}
Alloca_End;
return width ? Make_Integer (i) : Record_To_Vector (Char_Info_Rec,
Char_Info_Size, Sym_Char_Info, FONT(font)->dpy, ~0L);
}
static Object P_Text_Width (font, t, f) Object font, t, f; {
return Internal_Text_Metrics (font, t, f, 1);
}
static Object P_Text_Extents (font, t, f) Object font, t, f; {
return Internal_Text_Metrics (font, t, f, 0);
}
static Object P_Draw_Image_Text (d, gc, x, y, t, f) Object d, gc, x, y, t, f; {
Display *dpy;
Drawable dr = Get_Drawable (d, &dpy);
Object *data;
register i, n;
char *s;
XChar2b *s2;
Alloca_Begin;
Check_Type (gc, T_Gc);
Check_Type (t, T_Vector);
n = VECTOR(t)->size;
data = VECTOR(t)->data;
if (Two_Byte (f)) {
Alloca (s2, XChar2b*, n * sizeof (XChar2b));
for (i = 0; i < n; i++) {
register c = Get_2_Byte_Char (data[i]);
s2[i].byte1 = (c >> 8) & 0xff;
s2[i].byte2 = c & 0xff;
}
XDrawImageString16 (dpy, dr, GCONTEXT(gc)->gc, Get_Integer (x),
Get_Integer (y), s2, n);
} else {
Alloca (s, char*, n);
for (i = 0; i < n; i++)
s[i] = Get_1_Byte_Char (data[i]);
XDrawImageString (dpy, dr, GCONTEXT(gc)->gc, Get_Integer (x),
Get_Integer (y), s, n);
}
Alloca_End;
return Void;
}
static Object P_Draw_Poly_Text (d, gc, x, y, t, f) Object d, gc, x, y, t, f; {
Display *dpy;
Drawable dr = Get_Drawable (d, &dpy);
Object *data;
register i, n, j, k;
int twobyte, nitems;
XTextItem *items;
int (*func)();
Alloca_Begin;
Check_Type (gc, T_Gc);
twobyte = Two_Byte (f);
func = twobyte ? (int(*)())XDrawText16 : (int(*)())XDrawText;
Check_Type (t, T_Vector);
if ((n = VECTOR(t)->size) == 0)
return Void;
for (data = VECTOR(t)->data, i = 0, nitems = 1; i < n; i++)
if (TYPE(data[i]) == T_Font) nitems++;
Alloca (items, XTextItem*, nitems * sizeof (XTextItem));
items[0].delta = 0;
items[0].font = None;
for (j = k = i = 0; i <= n; i++) {
if (i == n || TYPE(data[i]) == T_Font) {
items[j].nchars = i-k;
if (twobyte) {
register XChar2b *p;
Alloca (p, XChar2b*, (i-k) * sizeof (XChar2b));
((XTextItem16 *)items)[j].chars = p;
for ( ; k < i; k++, p++) {
register c = Get_2_Byte_Char (data[k]);
p->byte1 = (c >> 8) & 0xff;
p->byte2 = c & 0xff;
}
} else {
register char *p;
Alloca (p, char*, i-k);
items[j].chars = p;
for ( ; k < i; k++)
*p++ = Get_1_Byte_Char (data[k]);
}
k++;
j++;
if (i < n) {
items[j].delta = 0;
Open_Font_Maybe (data[i]);
items[j].font = FONT(data[i])->id;
}
}
}
(*func)(dpy, dr, GCONTEXT(gc)->gc, Get_Integer (x), Get_Integer (y),
items, nitems);
Alloca_End;
return Void;
}
elk_init_xlib_text () {
Define_Primitive (P_Text_Width, "text-width", 3, 3, EVAL);
Define_Primitive (P_Text_Extents, "xlib-text-extents", 3, 3, EVAL);
Define_Primitive (P_Draw_Image_Text, "draw-image-text", 6, 6, EVAL);
Define_Primitive (P_Draw_Poly_Text, "draw-poly-text", 6, 6, EVAL);
Define_Symbol (&Sym_1byte, "1-byte");
Define_Symbol (&Sym_2byte, "2-byte");
}
|