1 /*
2 * wmslib/src/but/write.c, part of wmslib (Library functions)
3 * Copyright (C) 1994 William Shubert.
4 * See "configure.h.in" for more copyright information.
5 */
6
7 #include <configure.h>
8
9 #ifdef X11_DISP
10
11 #ifdef STDC_HEADERS
12 #include <stdlib.h>
13 #include <unistd.h>
14 #endif /* STDC_HEADERS */
15 #include <stdio.h>
16 #include <X11/Xlib.h>
17 #include <X11/Xutil.h>
18 #include <X11/cursorfont.h>
19 #include <X11/Xatom.h>
20 #include <X11/keysym.h>
21 #include <sys/time.h>
22 #ifdef HAVE_SYS_SELECT_H
23 #include <sys/select.h>
24 #endif
25 #include <wms.h>
26 #include <but/but.h>
27 #include <but/write.h>
28
29
butEnv_setChar(ButEnv * env,double width,const char * id,void (* draw)(void * packet,ButWin * win,int x,int y,int w,int h),void * packet)30 void butEnv_setChar(ButEnv *env, double width, const char *id,
31 void (*draw)(void *packet, ButWin *win,
32 int x, int y, int w, int h), void *packet) {
33 int idval;
34
35 idval = ((int)(uchar)id[0] << 8) + (uchar)id[1] - 256;
36 env->write[idval].width = width;
37 env->write[idval].packet = packet;
38 env->write[idval].draw = draw;
39 }
40
41
butEnv_textWidth(ButEnv * env,const char * text,int fnum)42 int butEnv_textWidth(ButEnv *env, const char *text, int fnum) {
43 uchar c;
44 int special;
45 int total = 0, min_char, std_width;
46 XCharStruct *charlist;
47
48 if (env->fonts[fnum]->per_char != NULL) {
49 charlist = env->fonts[fnum]->per_char;
50 min_char = env->fonts[fnum]->min_char_or_byte2;
51 for (;;) {
52 c = text[0];
53 ++text;
54 switch(c) {
55 case '\0':
56 return(total);
57 break;
58 case '\1':
59 case '\2':
60 special = 256 * (c - 1) + text[0];
61 ++text;
62 assert(env->write[special].draw != NULL);
63 total += (env->fonts[fnum]->ascent + env->fonts[fnum]->descent) *
64 env->write[special].width + 0.5;
65 break;
66 default:
67 assert((c >= min_char) && (c <= env->fonts[fnum]->max_char_or_byte2));
68 total += charlist[c - min_char].width;
69 break;
70 }
71 }
72 } else { /* All chars are the same width. */
73 std_width = env->fonts[fnum]->min_bounds.width;
74 for (;;) {
75 c = text[0];
76 ++text;
77 switch(c) {
78 case '\0':
79 return(total);
80 break;
81 case '\1':
82 case '\2':
83 special = 256 * (c - 1) + text[0];
84 ++text;
85 assert(env->write[special].draw != NULL);
86 total += (env->fonts[fnum]->ascent + env->fonts[fnum]->descent) *
87 env->write[special].width + 0.5;
88 break;
89 default:
90 total += std_width;
91 break;
92 }
93 }
94 }
95 }
96
97
butEnv_charWidth(ButEnv * env,const char * text,int fnum)98 int butEnv_charWidth(ButEnv *env, const char *text, int fnum) {
99 uchar c, special;
100 int width;
101
102 c = text[0];
103 assert(c != '\0');
104 switch(c) {
105 case '\1':
106 case '\2':
107 special = 256 * (c - 1) + text[1];
108 assert(env->write[special].draw != NULL);
109 width = (env->fonts[fnum]->ascent + env->fonts[fnum]->descent) *
110 env->write[special].width + 0.5;
111 break;
112 default:
113 if (env->fonts[fnum]->per_char != NULL)
114 width = env->fonts[fnum]->per_char[c -
115 env->fonts[fnum]->min_char_or_byte2].
116 width;
117 else
118 width = env->fonts[fnum]->min_bounds.width;
119 break;
120 }
121 return(width);
122 }
123
124
butWin_write(ButWin * win,int x,int y,const char * text,int font)125 void butWin_write(ButWin *win, int x, int y, const char *text, int font) {
126 int wlen;
127 ButEnv *env = win->env;
128 int ascent = env->fonts[font]->ascent, special;
129 int w, h = ascent + env->fonts[font]->descent;
130 uchar c;
131
132 XSetFont(env->dpy, env->gc, env->fonts[font]->fid);
133 for (;;) {
134 for (wlen = 0; (uchar)(text[wlen]) > BUTWRITE_MINPRINT; ++wlen);
135 if (wlen > 0) {
136 XDrawString(env->dpy, win->win, env->gc,
137 x-win->xOff, y+ascent-win->yOff, text, wlen);
138 x += XTextWidth(env->fonts[font], text, wlen);
139 text += wlen;
140 }
141 switch(c = text[0]) {
142 case '\0':
143 return;
144 break;
145 case '\1':
146 case '\2':
147 special = 256 * (c-1) + text[1];
148 text += 2;
149 assert(env->write[special].draw != NULL);
150 w = h * env->write[special].width + 0.5;
151 env->write[special].draw(env->write[special].packet, win,
152 x-win->xOff,y-win->yOff, w,h);
153 x += w;
154 break;
155 }
156 }
157 }
158
159
butWin_writeTabs(ButWin * win,int startX,int y,const char * text,int font,const int * tabList,const ButTextAlign * aligns)160 void butWin_writeTabs(ButWin *win, int startX, int y, const char *text,
161 int font, const int *tabList,
162 const ButTextAlign *aligns) {
163 int wlen;
164 ButEnv *env = win->env;
165 int ascent = env->fonts[font]->ascent, special;
166 int w, h = ascent + env->fonts[font]->descent;
167 int x = startX;
168 uchar c;
169 int tabNum = 0;
170 ButTextAlign align = butText_left;
171
172 XSetFont(env->dpy, env->gc, env->fonts[font]->fid);
173 for (;;) {
174 for (wlen = 0; (uchar)(text[wlen]) > BUTWRITE_MINPRINT; ++wlen);
175 if (wlen > 0) {
176 w = XTextWidth(env->fonts[font], text, wlen);
177 switch(align) {
178 case butText_left:
179 break;
180 case butText_center:
181 x -= w / 2;
182 break;
183 case butText_right:
184 x -= w;
185 break;
186 case butText_just:
187 assert(0);
188 break;
189 }
190 XDrawString(env->dpy, win->win, env->gc,
191 x - win->xOff, y+ascent-win->yOff, text, wlen);
192 x += w;
193 text += wlen;
194 }
195 switch(c = text[0]) {
196 case '\0':
197 return;
198 break;
199 case '\1':
200 case '\2':
201 special = 256 * (c-1) + text[1];
202 text += 2;
203 assert(env->write[special].draw != NULL);
204 w = h * env->write[special].width + 0.5;
205 env->write[special].draw(env->write[special].packet, win,
206 x-win->xOff,y-win->yOff, w,h);
207 x += w;
208 break;
209 case '\t':
210 x = startX + tabList[tabNum];
211 align = aligns[tabNum];
212 ++tabNum;
213 ++text;
214 break;
215 }
216 }
217 }
218
219
220 #endif /* X11_DISP */
221