Mercurial > kinput2.yaz
comparison lib/xwstr.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 /* | |
2 * xwstr.c | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (c) 1989 Software Research Associates, Inc. | |
7 * | |
8 * Permission to use, copy, modify, and distribute this software and its | |
9 * documentation for any purpose and without fee is hereby granted, provided | |
10 * that the above copyright notice appear in all copies and that both that | |
11 * copyright notice and this permission notice appear in supporting | |
12 * documentation, and that the name of Software Research Associates not be | |
13 * used in advertising or publicity pertaining to distribution of the | |
14 * software without specific, written prior permission. Software Research | |
15 * Associates makes no representations about the suitability of this software | |
16 * for any purpose. It is provided "as is" without express or implied | |
17 * warranty. | |
18 * | |
19 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
20 * ishisone@sra.co.jp | |
21 */ | |
22 | |
23 /* | |
24 * wide character string $B$rMQ$$$F%F%-%9%H$rI=<($9$k$?$a$N%i%$%V%i%j(B | |
25 * | |
26 * wide character $B$NFCD9$r@8$+$7!":GBgF1;~$K(B 4 $B<oN`$N%U%)%s%H$r(B | |
27 * $B07$&$3$H$,$G$-$k!#(B | |
28 * | |
29 * GSet bit $BI=8=(B UJIS $B$G$N3d$jEv$F(B | |
30 * ---------------------------------------------- | |
31 * G0 0xxxxxxx0xxxxxxx ASCII | |
32 * G1 1xxxxxxx1xxxxxxx $B4A;z(B | |
33 * G2 0xxxxxxx1xxxxxxx $BH>3Q$+$J(B | |
34 * G3 1xxxxxxx0xxxxxxx $B30;z(B | |
35 * | |
36 * XWSGC XWSSetGCSet(GC gc0, GC gc1, GC gc2, GC gc3) | |
37 * $B;XDj$5$l$?(B 4$B$D$N(B GC $B$rAH$_9g$o$;$F(B XWSGC $B$r:n$k!#(B | |
38 * G0, G1, G2, G3 $B$NJ8;z$KBP$7$F$=$l$>$l(B gc0, gc1, gc2, gc3 $B$,(B | |
39 * $B;H$o$l$k!#0z?t(B gc? $B$K$O(B NULL $B$r;XDj$7$F$b$h$$!#$=$N>l9g$K$O(B | |
40 * $BBP1~$9$k%-%c%i%/%?%;%C%H$NJ8;z$O=q$+$l$J$$!#(B | |
41 * $B$J$*(B Xt $B$NCf$G;HMQ$9$k;~$K$O!"(Bxtwstr.c $B$NCf$N(B XtWSGetGCSet() | |
42 * $B$r;H$&J}$,$h$$$@$m$&!#(B | |
43 * | |
44 * void XWSSetMapping(XWSGC gcset, int g0map, int g1map, int g2map, int g3map) | |
45 * G0, G1, G2, G3 $B$NJ8;z$rIA2h$9$k;~$K%U%)%s%H$N(B GL / GR $B$N$I$A$i$r(B | |
46 * $B;HMQ$9$k$+$r@_Dj$9$k!#(B0 $B$r;XDj$9$k$H(B GL $B$,;HMQ$5$l!"(B1 $B$r;XDj$9$k$H(B | |
47 * GR $B$,;HMQ$5$l$k!#(B-1 $B$,;XDj$5$l$?>l9g$K$OA0$N@_Dj$,$=$N$^$^;H$o$l$k!#(B | |
48 * $B%G%U%)%k%H$N@_Dj(B ($B$D$^$j(B XWSSetGCSet() $B$^$?$O(B XtWSGetGCSet() $B$G(B | |
49 * gcset $B$,:n$i$l$?;~(B) $B$O$9$Y$F(B GL $B$r;HMQ$9$k$h$&$K$J$C$F$$$k!#(B | |
50 * | |
51 * int XWSDrawString(Display *d, Drawable w, XWSGC gcset, | |
52 * int x, int y, wchar *wstr, int len) | |
53 * int XWSDrawImageString(Display *d, Drawable w, XWSGC gcset, | |
54 * int x, int y, wchar *wstr, int len) | |
55 * $B$=$l$>$l!"(BXlib $B$N(B XDrawString() / XDrawImageString() $B$K(B | |
56 * $BBP1~$9$k4X?t!#;XDj$5$l$?0LCV$K;XDj$5$l$?(B GC $B%;%C%H$rMQ$$$F(B | |
57 * $B%F%-%9%H$r=q$/!#0z?t(B len $B$OJ8;zNs(B wstr $B$NJ8;z?t$G$"$k!#(B | |
58 * $B%P%$%H?t$G$O$J$$$3$H$KCm0U!#(B | |
59 * $B$J$*!"(BXDrawString() $B$J$I$H$O0[$J$j!"%j%?!<%s%P%j%e!<$H$7$F(B | |
60 * $B=q$$$?J8;z$NI}$rJV$9!#(B | |
61 * | |
62 * int XWSTextWidth(XWSGC gcset, wchar *wstr, int len) | |
63 * void XWSTextExtents(XWSGC gcset, wchar *wstr, int len, | |
64 * int *ascent, int *descent, XCharStruct *overall) | |
65 * $B$=$l$>$l!"(BXlib $B$N(B XTextWidth() / XTextExtents() $B$KBP1~$9$k(B | |
66 * $B4X?t!#;XDj$5$l$?J8;zNs$NI}!&Bg$-$5$rJV$9!#(B | |
67 * | |
68 * void XWSFontHeight(XWSGC gcset, wchar *wstr, int len, | |
69 * int *ascent, int *descent) | |
70 * $B0z?t(B wstr $B$G;XDj$5$l$?J8;z$KBP1~$9$k%U%)%s%H$N(B ascent/descent $B$N(B | |
71 * $B:GBgCM$rJV$9!#(Bwstr $B$K(B NULL $B$r;XDj$9$k$H!"(BXWSGC $B$K%;%C%H$5$l$?(B | |
72 * $B$9$Y$F$N%U%)%s%H$N(B ascent/descent $B$N:GBgCM$rJV$9!#(B | |
73 */ | |
74 | |
75 #ifndef lint | |
76 static char *rcsid = "$Id: xwstr.c,v 2.9 1999/01/07 03:13:03 ishisone Exp $"; | |
77 #endif | |
78 | |
79 #include <X11/Xlib.h> | |
80 #if defined(XlibSpecificationRelease) && XlibSpecificationRelease > 4 | |
81 #include <X11/Xfuncs.h> | |
82 #endif | |
83 #include "WStr.h" | |
84 #include "XWStr.h" | |
85 | |
86 #ifdef __STDC__ | |
87 #include <stdlib.h> | |
88 #else | |
89 extern char *malloc(); | |
90 #endif | |
91 | |
92 #define G0MASK 0x0000 | |
93 #define G1MASK 0x8080 | |
94 #define G2MASK 0x0080 | |
95 #define G3MASK 0x8000 | |
96 | |
97 #define IS2B(f) (((f)->max_byte1 > 0) || ((f)->max_char_or_byte2 > 255)) | |
98 #define MIN(a, b) ((a) > (b) ? (b) : (a)) | |
99 #define MAX(a, b) ((a) > (b) ? (a) : (b)) | |
100 | |
101 #ifndef NULL | |
102 #define NULL 0 | |
103 #endif | |
104 | |
105 #define bufsize 256 | |
106 | |
107 #ifdef __STDC__ | |
108 /* static function prototype */ | |
109 static int flushstr(Display *, Drawable, FontEnt *, int, int, | |
110 XChar2b *, XChar2b *, int); | |
111 static int wsdrawstring(Display *, Drawable, XWSGC, int, int, | |
112 wchar *, int, int); | |
113 #else | |
114 static int flushstr(); | |
115 static int wsdrawstring(); | |
116 #endif | |
117 | |
118 XWSGC | |
119 XWSSetGCSet(dpy, gc0, gc1, gc2, gc3) | |
120 Display *dpy; | |
121 GC gc0; | |
122 GC gc1; | |
123 GC gc2; | |
124 GC gc3; | |
125 { | |
126 XWSGC gcset; | |
127 int i; | |
128 | |
129 gcset = (XWSGC)malloc(sizeof(XWSGCSet)); | |
130 if (gcset == NULL) | |
131 return (XWSGC)NULL; | |
132 | |
133 gcset->fe[0].gc = gc0; | |
134 gcset->fe[1].gc = gc1; | |
135 gcset->fe[2].gc = gc2; | |
136 gcset->fe[3].gc = gc3; | |
137 | |
138 for (i = 0; i < 4; i++) { | |
139 if (gcset->fe[i].gc == NULL) { | |
140 gcset->fe[i].font = NULL; | |
141 } else { | |
142 XFontStruct *font; | |
143 gcset->fe[i].font = font = XQueryFont(dpy, XGContextFromGC(gcset->fe[i].gc)); | |
144 gcset->fe[i].flag = FONTQUERY; | |
145 if (IS2B(font)) | |
146 gcset->fe[i].flag = TWOB; | |
147 } | |
148 } | |
149 | |
150 return gcset; | |
151 } | |
152 | |
153 void | |
154 XWSSetMapping(gcset, g0map, g1map, g2map, g3map) | |
155 XWSGC gcset; | |
156 int g0map; | |
157 int g1map; | |
158 int g2map; | |
159 int g3map; | |
160 { | |
161 int map[4]; | |
162 int i; | |
163 | |
164 map[0] = g0map; map[1] = g1map; map[2] = g2map; map[3] = g3map; | |
165 for (i = 0; i < 4; i++) { | |
166 if (map[i] < 0) | |
167 continue; | |
168 else if (map[i] == 0) | |
169 gcset->fe[i].flag &= ~GRMAPPING; | |
170 else | |
171 gcset->fe[i].flag |= GRMAPPING; | |
172 } | |
173 } | |
174 | |
175 int | |
176 XWSDrawString(d, w, gcset, x, y, wstr, len) | |
177 Display *d; | |
178 Drawable w; | |
179 XWSGC gcset; | |
180 int x; | |
181 int y; | |
182 wchar *wstr; | |
183 int len; | |
184 { | |
185 return wsdrawstring(d, w, gcset, x, y, wstr, len, 0); | |
186 } | |
187 | |
188 int | |
189 XWSDrawImageString(d, w, gcset, x, y, wstr, len) | |
190 Display *d; | |
191 Drawable w; | |
192 XWSGC gcset; | |
193 int x; | |
194 int y; | |
195 wchar *wstr; | |
196 int len; | |
197 { | |
198 return wsdrawstring(d, w, gcset, x, y, wstr, len, 1); | |
199 } | |
200 | |
201 void | |
202 XWSFontHeight(gcset, wstr, len, ascent, descent) | |
203 XWSGC gcset; | |
204 wchar *wstr; | |
205 int len; | |
206 int *ascent; | |
207 int *descent; | |
208 { | |
209 FontEnt *fep = &(gcset->fe[0]); | |
210 int i; | |
211 int asc = 0; | |
212 int dsc = 0; | |
213 | |
214 if (wstr) { | |
215 while (len-- > 0) { | |
216 i = GSET(*wstr++); | |
217 if (fep[i].font) { | |
218 if ((fep[i].font)->ascent > asc) | |
219 asc = (fep[i].font)->ascent; | |
220 if ((fep[i].font)->descent > dsc) | |
221 dsc = (fep[i].font)->descent; | |
222 } | |
223 } | |
224 } else { | |
225 for (i = 0; i < 4; i++) { | |
226 if (fep[i].font) { | |
227 if ((fep[i].font)->ascent > asc) | |
228 asc = (fep[i].font)->ascent; | |
229 if ((fep[i].font)->descent > dsc) | |
230 dsc = (fep[i].font)->descent; | |
231 } | |
232 } | |
233 } | |
234 *ascent = asc; | |
235 *descent = dsc; | |
236 } | |
237 | |
238 int | |
239 XWSTextWidth(gcset, wstr, len) | |
240 XWSGC gcset; | |
241 wchar *wstr; | |
242 int len; | |
243 { | |
244 XChar2b buf[bufsize]; | |
245 XChar2b *cp; | |
246 wchar *wstr1 = wstr + len; | |
247 XChar2b *cpend = buf + bufsize; | |
248 int c; | |
249 int width = 0; | |
250 int gmask, gset; | |
251 FontEnt *fe; | |
252 int is2b; | |
253 int grmap; | |
254 | |
255 while (wstr < wstr1) { | |
256 gmask = *wstr & 0x8080; | |
257 | |
258 switch (gmask) { | |
259 case G0MASK: | |
260 gset = 0; | |
261 break; | |
262 case G1MASK: | |
263 gset = 1; | |
264 break; | |
265 case G2MASK: | |
266 gset = 2; | |
267 break; | |
268 case G3MASK: | |
269 gset = 3; | |
270 break; | |
271 } | |
272 | |
273 fe = &gcset->fe[gset]; | |
274 is2b = fe->flag & TWOB; | |
275 grmap = (fe->flag & GRMAPPING) ? 0x80 : 0; | |
276 cp = buf; | |
277 | |
278 if (fe->font == NULL) { | |
279 while (wstr < wstr1 && (*wstr & 0x8080) == gmask) | |
280 wstr++; | |
281 continue; | |
282 } | |
283 | |
284 while (wstr < wstr1 && ((c = *wstr) & 0x8080) == gmask) { | |
285 if (cp >= cpend - 1) { | |
286 /* flush */ | |
287 width += XTextWidth16(fe->font, buf, cp - buf); | |
288 cp = buf; | |
289 } | |
290 if (is2b) | |
291 cp->byte1 = ((c >> 8) & 0x7f) | grmap; | |
292 else | |
293 cp->byte1 = 0; | |
294 cp->byte2 = (c & 0x7f) | grmap; | |
295 cp++; | |
296 wstr++; | |
297 } | |
298 | |
299 if (cp == buf) | |
300 continue; | |
301 | |
302 /* flush */ | |
303 width += XTextWidth16(fe->font, buf, cp - buf); | |
304 } | |
305 | |
306 return width; | |
307 } | |
308 | |
309 void | |
310 XWSTextExtents(gcset, wstr, len, ascent, descent, overall) | |
311 XWSGC gcset; | |
312 wchar *wstr; | |
313 int len; | |
314 int *ascent; | |
315 int *descent; | |
316 XCharStruct *overall; | |
317 { | |
318 XChar2b buf[bufsize]; | |
319 XChar2b *cp; | |
320 wchar *wstr1 = wstr + len; | |
321 XChar2b *cpend = buf + bufsize; | |
322 int c; | |
323 int gmask, gset; | |
324 FontEnt *fe; | |
325 int is2b; | |
326 int grmap; | |
327 int dir, as, ds; | |
328 XCharStruct oa; | |
329 | |
330 *ascent = *descent = 0; | |
331 (void)bzero(overall, sizeof(XCharStruct)); | |
332 | |
333 while (wstr < wstr1) { | |
334 gmask = *wstr & 0x8080; | |
335 | |
336 switch (gmask) { | |
337 case G0MASK: | |
338 gset = 0; | |
339 break; | |
340 case G1MASK: | |
341 gset = 1; | |
342 break; | |
343 case G2MASK: | |
344 gset = 2; | |
345 break; | |
346 case G3MASK: | |
347 gset = 3; | |
348 break; | |
349 } | |
350 | |
351 fe = &gcset->fe[gset]; | |
352 is2b = fe->flag & TWOB; | |
353 grmap = (fe->flag & GRMAPPING) ? 0x80 : 0; | |
354 cp = buf; | |
355 | |
356 if (fe->font == NULL) { | |
357 while (wstr < wstr1 && (*wstr & 0x8080) == gmask) | |
358 wstr++; | |
359 continue; | |
360 } | |
361 | |
362 while (wstr < wstr1 && ((c = *wstr) & 0x8080) == gmask) { | |
363 if (cp >= cpend - 1) { | |
364 /* flush */ | |
365 XTextExtents16(fe->font, buf, cp - buf, | |
366 &dir, &as, &ds, &oa); | |
367 cp = buf; | |
368 *ascent = MAX(*ascent, as); | |
369 *descent = MAX(*descent, ds); | |
370 overall->lbearing = MIN(overall->lbearing, | |
371 overall->width + oa.lbearing); | |
372 overall->rbearing = MAX(overall->rbearing, | |
373 overall->width + oa.rbearing); | |
374 overall->width += oa.width; | |
375 overall->ascent = MAX(overall->ascent, oa.ascent); | |
376 overall->descent = MAX(overall->descent, oa.descent); | |
377 } | |
378 if (is2b) | |
379 cp->byte1 = ((c >> 8) & 0x7f) | grmap; | |
380 else | |
381 cp->byte1 = 0; | |
382 cp->byte2 = (c & 0x7f) | grmap; | |
383 cp++; | |
384 wstr++; | |
385 } | |
386 | |
387 if (cp == buf) | |
388 continue; | |
389 | |
390 /* flush */ | |
391 XTextExtents16(fe->font, buf, cp - buf, &dir, &as, &ds, &oa); | |
392 *ascent = MAX(*ascent, as); | |
393 *descent = MAX(*descent, ds); | |
394 overall->lbearing = MIN(overall->lbearing, | |
395 overall->width + oa.lbearing); | |
396 overall->rbearing = MAX(overall->rbearing, | |
397 overall->width + oa.rbearing); | |
398 overall->width += oa.width; | |
399 overall->ascent = MAX(overall->ascent, oa.ascent); | |
400 overall->descent = MAX(overall->descent, oa.descent); | |
401 } | |
402 } | |
403 | |
404 | |
405 /* | |
406 * private functions | |
407 */ | |
408 | |
409 static int | |
410 wsdrawstring(d, w, gcset, x, y, wstr, len, image) | |
411 Display *d; | |
412 Drawable w; | |
413 XWSGC gcset; | |
414 int x; | |
415 int y; | |
416 wchar *wstr; | |
417 int len; | |
418 int image; | |
419 { | |
420 XChar2b buf[bufsize]; | |
421 XChar2b *cp; | |
422 wchar *wstr1 = wstr + len; | |
423 XChar2b *cpend = buf + bufsize; | |
424 int c; | |
425 int sx = x; | |
426 int gmask, gset; | |
427 FontEnt *fe; | |
428 int is2b; | |
429 int grmap; | |
430 | |
431 while (wstr < wstr1) { | |
432 gmask = *wstr & 0x8080; | |
433 | |
434 switch (gmask) { | |
435 case G0MASK: | |
436 gset = 0; | |
437 break; | |
438 case G1MASK: | |
439 gset = 1; | |
440 break; | |
441 case G2MASK: | |
442 gset = 2; | |
443 break; | |
444 case G3MASK: | |
445 gset = 3; | |
446 break; | |
447 } | |
448 | |
449 fe = &gcset->fe[gset]; | |
450 is2b = fe->flag & TWOB; | |
451 grmap = (fe->flag & GRMAPPING) ? 0x80 : 0; | |
452 cp = buf; | |
453 | |
454 if (fe->gc == NULL) { | |
455 while (wstr < wstr1 && (*wstr & 0x8080) == gmask) | |
456 wstr++; | |
457 continue; | |
458 } | |
459 while (wstr < wstr1 && ((c = *wstr) & 0x8080) == gmask) { | |
460 if (cp >= cpend - 1) { | |
461 /* flush */ | |
462 x += flushstr(d, w, fe, x, y, buf, cp, image); | |
463 cp = buf; | |
464 } | |
465 if (is2b) | |
466 cp->byte1 = ((c >> 8) & 0x7f) | grmap; | |
467 else | |
468 cp->byte1 = 0; | |
469 cp->byte2 = (c & 0x7f) | grmap; | |
470 cp++; | |
471 wstr++; | |
472 } | |
473 /* flush */ | |
474 x += flushstr(d, w, fe, x, y, buf, cp, image); | |
475 cp = buf; | |
476 } | |
477 | |
478 return x - sx; | |
479 } | |
480 | |
481 static int | |
482 flushstr(d, w, fe, x, y, cp0, cp1, image) | |
483 Display *d; | |
484 Drawable w; | |
485 FontEnt *fe; | |
486 int x; | |
487 int y; | |
488 XChar2b *cp0; | |
489 XChar2b *cp1; | |
490 int image; | |
491 { | |
492 if (cp0 >= cp1 || fe->gc == NULL) | |
493 return 0; | |
494 | |
495 if (image) | |
496 XDrawImageString16(d, w, fe->gc, x, y, cp0, cp1 - cp0); | |
497 else | |
498 XDrawString16(d, w, fe->gc, x, y, cp0, cp1 - cp0); | |
499 return XTextWidth16(fe->font, cp0, cp1 - cp0); | |
500 } |