omText.c revision 1ab64890
1/* $Xorg: omText.c,v 1.3 2000/08/17 19:45:22 cpqbld Exp $ */
2/*
3 * Copyright 1992, 1993 by TOSHIBA Corp.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation for any purpose and without fee is hereby granted, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of TOSHIBA not be used in advertising
10 * or publicity pertaining to distribution of the software without specific,
11 * written prior permission. TOSHIBA make no representations about the
12 * suitability of this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 *
15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 * SOFTWARE.
22 *
23 * Author: Katsuhisa Yano	TOSHIBA Corp.
24 *			   	mopi@osa.ilab.toshiba.co.jp
25 */
26/* $XFree86: xc/lib/X11/omText.c,v 1.9 2003/04/22 13:57:45 pascal Exp $ */
27/*
28 * Copyright 1995 by FUJITSU LIMITED
29 * This is source code modified by FUJITSU LIMITED under the Joint
30 * Development Agreement for the CDE/Motif PST.
31 */
32/*
33 * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
34 */
35
36#ifdef HAVE_CONFIG_H
37#include <config.h>
38#endif
39#include "Xlibint.h"
40#include "XomGeneric.h"
41#include <stdio.h>
42
43/* For VW/UDC */
44
45static int
46is_rotate(
47    XOC		oc,
48    XFontStruct	*font)
49{
50    XOCGenericPart	*gen = XOC_GENERIC(oc);
51    FontSet		font_set;
52    VRotate		vrotate;
53    int			font_set_count;
54    int			vrotate_num;
55
56    font_set = gen->font_set;
57    font_set_count = gen->font_set_num;
58    for( ; font_set_count-- ; font_set++) {
59	if((font_set->vrotate_num > 0) && (font_set->vrotate)) {
60	    vrotate = font_set->vrotate;
61	    vrotate_num = font_set->vrotate_num;
62	    for( ; vrotate_num-- ; vrotate++)
63		if(vrotate->font == font)
64		    return True;
65	}
66    }
67    return False;
68}
69
70static int
71is_codemap(
72    XOC		oc,
73    XFontStruct	*font)
74{
75    XOCGenericPart	*gen = XOC_GENERIC(oc);
76    FontSet		font_set;
77    FontData		vmap;
78    int			font_set_count;
79    int			vmap_num;
80
81    font_set = gen->font_set;
82    font_set_count = gen->font_set_num;
83    for( ; font_set_count-- ; font_set++) {
84	if(font_set->vmap_num > 0) {
85	    vmap = font_set->vmap;
86	    vmap_num = font_set->vmap_num;
87	    for( ; vmap_num-- ; vmap++)
88		if(vmap->font == font)
89		    return True;
90	}
91    }
92    return False;
93}
94
95static int
96draw_vertical(
97    Display	*dpy,
98    Drawable	d,
99    XOC		oc,
100    GC		gc,
101    XFontStruct	*font,
102    Bool	is_xchar2b,
103    int		x, int y,
104    XPointer	text,
105    int		length)
106{
107    XChar2b	*buf2b;
108    char	*buf;
109    int		wx = 0, wy = 0;
110    int		direction = 0;
111    int		font_ascent_return = 0, font_descent_return = 0;
112    int		i;
113    XCharStruct	overall;
114
115    wy = y;
116    if (is_xchar2b) {
117	for(i = 0, buf2b = (XChar2b *) text ; i < length ; i++, buf2b++) {
118	    if(is_rotate(oc, font) == True) {
119		XTextExtents16(font, buf2b, 1,
120			       &direction, &font_ascent_return,
121			       &font_descent_return, &overall);
122		wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) -
123			 (int) overall.lbearing;
124		wy += overall.ascent;
125		XDrawString16(dpy, d, gc, wx, wy, buf2b, 1);
126		wy += overall.descent;
127	    } else {
128		wx = x - (int)((font->max_bounds.rbearing -
129				font->min_bounds.lbearing) >> 1) -
130			 (int) font->min_bounds.lbearing;
131		wy += font->max_bounds.ascent;
132		XDrawString16(dpy, d, gc, wx, wy, buf2b, 1);
133		wy += font->max_bounds.descent;
134	    }
135	}
136    } else {
137	for(i = 0, buf = (char *)text ; i < length && *buf ; i++, buf++) {
138	    if(is_rotate(oc, font) == True) {
139		XTextExtents(font, buf, 1,
140			     &direction, &font_ascent_return,
141			     &font_descent_return, &overall);
142		wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) -
143			 (int) overall.lbearing;
144		wy += overall.ascent;
145		XDrawString(dpy, d, gc, wx, wy, buf, 1);
146		wy += overall.descent;
147	    } else {
148		wx = x - (int)((font->max_bounds.rbearing -
149				font->min_bounds.lbearing) >> 1) -
150			 (int) font->min_bounds.lbearing;
151		wy += font->max_bounds.ascent;
152		XDrawString(dpy, d, gc, wx, wy, buf, 1);
153		wy += font->max_bounds.descent;
154	    }
155	}
156    }
157    return wy;
158}
159
160#define VMAP          0
161#define VROTATE       1
162#define FONTSCOPE     2
163
164static int
165DrawStringWithFontSet(
166    Display *dpy,
167    Drawable d,
168    XOC oc,
169    FontSet fs,
170    GC gc,
171    int x, int y,
172    XPointer text,
173    int length)
174{
175    XFontStruct *font;
176    Bool is_xchar2b;
177    unsigned char *ptr;
178    int ptr_len, char_len = 0;
179    FontData fd;
180    int ret = 0;
181
182    ptr = (unsigned char *)text;
183    is_xchar2b = fs->is_xchar2b;
184
185    while (length > 0) {
186        fd = _XomGetFontDataFromFontSet(fs,
187			ptr,length,&ptr_len,is_xchar2b,FONTSCOPE);
188	if(ptr_len <= 0)
189	    break;
190
191       /* First, see if the "Best Match" font for the FontSet was set.
192	* If it was, use that font.  If it was not set, then use the
193	* font defined by font_set->font_data[0] (which is what
194	* _XomGetFontDataFromFontSet() always seems to return for
195	* non-VW text).  Note that given the new algorithm in
196	* parse_fontname() and parse_fontdata(), fs->font will
197	* *always* contain good data.   We should probably remove
198	* the check for "fd->font", but we won't :-) -- jjw/pma (HP)
199	*/
200        if((font = fs->font) == (XFontStruct *) NULL){
201
202	    if(fd == (FontData) NULL ||
203	       (font = fd->font) == (XFontStruct *) NULL)
204		break;
205        }
206
207	switch(oc->core.orientation) {
208	  case XOMOrientation_LTR_TTB:
209	  case XOMOrientation_RTL_TTB:
210            XSetFont(dpy, gc, font->fid);
211
212	    if (is_xchar2b) {
213		char_len = ptr_len / sizeof(XChar2b);
214		XDrawString16(dpy, d, gc, x, y, (XChar2b *)ptr, char_len);
215		x += XTextWidth16(font, (XChar2b *)ptr, char_len);
216            } else {
217		char_len = ptr_len;
218		XDrawString(dpy, d, gc, x, y, (char *)ptr, char_len);
219		x += XTextWidth(font, (char *)ptr, char_len);
220	    }
221	    break;
222	  case XOMOrientation_TTB_RTL:
223	  case XOMOrientation_TTB_LTR:
224	    if(fs->font == font) {
225		fd = _XomGetFontDataFromFontSet(fs,
226			ptr,length,&ptr_len,is_xchar2b,VMAP);
227		if(ptr_len <= 0)
228		    break;
229		if(fd == (FontData) NULL ||
230		   (font = fd->font) == (XFontStruct *) NULL)
231		    break;
232
233		if(is_codemap(oc, fd->font) == False) {
234		    fd = _XomGetFontDataFromFontSet(fs,
235			     ptr,length,&ptr_len,is_xchar2b,VROTATE);
236		    if(ptr_len <= 0)
237			break;
238		    if(fd == (FontData) NULL ||
239		       (font = fd->font) == (XFontStruct *) NULL)
240			break;
241		}
242	    }
243
244	    if(is_xchar2b)
245		char_len = ptr_len / sizeof(XChar2b);
246	    else
247		char_len = ptr_len;
248            XSetFont(dpy, gc, font->fid);
249	    y = draw_vertical(dpy, d, oc, gc, font, is_xchar2b, x, y,
250			       (char *)ptr, char_len);
251	    break;
252
253	  case XOMOrientation_Context:
254	    /* never used? */
255	    break;
256	}
257
258	if(char_len <= 0)
259	    break;
260
261        length -= char_len;
262        ptr += ptr_len;
263    }
264
265    switch(oc->core.orientation) {
266      case XOMOrientation_LTR_TTB:
267      case XOMOrientation_RTL_TTB:
268	ret = x;
269	break;
270      case XOMOrientation_TTB_RTL:
271      case XOMOrientation_TTB_LTR:
272	ret = y;
273	break;
274      case XOMOrientation_Context:
275	/* not used? */
276	break;
277    }
278    return ret;
279}
280
281/* For VW/UDC */
282
283int
284_XomGenericDrawString(
285    Display *dpy,
286    Drawable d,
287    XOC oc,
288    GC gc,
289    int x, int y,
290    XOMTextType type,
291    XPointer text,
292    int length)
293{
294    XlcConv conv;
295    XFontStruct *font;
296    Bool is_xchar2b;
297/* VW/UDC */
298    XPointer args[3];
299    FontSet fs;
300/* VW/UDC */
301    XChar2b xchar2b_buf[BUFSIZ], *buf;
302    int start_x = x;
303    int start_y = y;
304    int left = 0, buf_len = 0;
305    int next = 0;
306
307    conv = _XomInitConverter(oc, type);
308    if (conv == NULL)
309	return -1;
310
311    args[0] = (XPointer) &font;
312    args[1] = (XPointer) &is_xchar2b;
313    args[2] = (XPointer) &fs;
314
315    while (length > 0) {
316	buf = xchar2b_buf;
317	left = buf_len = BUFSIZ;
318
319	if (_XomConvert(oc, conv, (XPointer *) &text, &length,
320			(XPointer *) &buf, &left, args, 3) < 0)
321	    break;
322	buf_len -= left;
323
324/* For VW/UDC */
325	next = DrawStringWithFontSet(dpy, d, oc, fs, gc, x, y,
326				     (XPointer)xchar2b_buf, buf_len);
327
328	switch(oc->core.orientation) {
329	  case XOMOrientation_LTR_TTB:
330	  case XOMOrientation_RTL_TTB:
331	    x = next;
332	    break;
333	  case XOMOrientation_TTB_RTL:
334	  case XOMOrientation_TTB_LTR:
335	    y = next;
336	    break;
337          case XOMOrientation_Context:
338	    /* not used */
339	    break;
340	}
341/* For VW/UDC */
342    }
343
344    x -= start_x;
345    y -= start_y;
346
347    return x;
348}
349
350int
351_XmbGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
352		      _Xconst char *text, int length)
353{
354    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMMultiByte,
355				 (XPointer) text, length);
356}
357
358int
359_XwcGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
360		      _Xconst wchar_t *text, int length)
361{
362    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMWideChar,
363				 (XPointer) text, length);
364}
365
366int
367_Xutf8GenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
368			_Xconst char *text, int length)
369{
370    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMUtf8String,
371				 (XPointer) text, length);
372}
373