omXChar.c revision 1ab64890
1/* $Xorg: omXChar.c,v 1.3 2000/08/17 19:45:23 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/*
27 * Copyright 1995 by FUJITSU LIMITED
28 * This is source code modified by FUJITSU LIMITED under the Joint
29 * Development Agreement for the CDE/Motif PST.
30 *
31 * Modifier: Takanori Tateno   FUJITSU LIMITED
32 *
33 */
34/*
35 * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
36 */
37/* $XFree86: xc/lib/X11/omXChar.c,v 1.6tsi Exp $ */
38
39#ifdef HAVE_CONFIG_H
40#include <config.h>
41#endif
42#include "Xlibint.h"
43#include "XlcPublic.h"
44#include "XomGeneric.h"
45#include <stdio.h>
46
47/* for VW/UDC start */
48static Bool
49ismatch_scopes(
50    FontData      fontdata,
51    unsigned long *value,
52    Bool	  is_shift)
53{
54    register int scopes_num = fontdata->scopes_num;
55    FontScope scopes = fontdata->scopes;
56    if (!scopes_num)
57        return False;
58
59    if(fontdata->font == NULL)
60	return False;
61
62    for(;scopes_num--;scopes++)
63        if ((scopes->start <= (*value & 0x7f7f)) &&
64                        ((scopes->end) >= (*value & 0x7f7f))){
65	    if(is_shift == True) {
66                if(scopes->shift){
67                    if(scopes->shift_direction == '+'){
68                        *value += scopes->shift ;
69                    } else if( scopes->shift_direction == '-'){
70                        *value -= scopes->shift ;
71                    }
72                }
73            }
74            return True;
75        }
76
77    return False;
78}
79
80static int
81check_vertical_fonttype(
82    char	*name)
83{
84    char	*ptr;
85    int		type = 0;
86
87    if(name == (char *)NULL || (int) strlen(name) <= 0)
88	return False;
89
90    /* Obtains the pointer of CHARSET_ENCODING_FIELD. */
91    if((ptr = strchr(name, '-')) == (char *) NULL)
92	return False;
93    ptr++;
94
95    /* Obtains the pointer of vertical_map font type. */
96    if((ptr = strchr(ptr, '.')) == (char *) NULL)
97	return False;
98    ptr++;
99
100    switch(*ptr) {
101      case '1':
102	type = 1;	break;
103      case '2':
104	type = 2;	break;
105      case '3':
106	type = 3;	break;
107    }
108    return type;
109}
110
111/*
112*/
113#define VMAP          0
114#define VROTATE       1
115#define FONTSCOPE     2
116
117FontData
118_XomGetFontDataFromFontSet(
119    FontSet fs,
120    unsigned char *str,
121    int len,
122    int *len_ret,
123    int is2b,
124    int type)          /* VMAP , VROTATE , else */
125{
126    unsigned long value;
127    int num,i,hit,csize;
128    FontData fontdata;
129    unsigned char *c;
130    int vfont_type;
131
132    c = str;
133    hit = -1;
134    if(type == VMAP){
135	fontdata = fs->vmap;
136	num      = fs->vmap_num;
137    } else if(type == VROTATE){
138        fontdata = (FontData)fs->vrotate;
139	num      = fs->vrotate_num;
140    } else {
141	if(fs->font_data_count <= 0 || fs->font_data == (FontData)NULL) {
142	    fontdata = fs->substitute;
143	    num      = fs->substitute_num;
144	}else {
145            fontdata = fs->font_data;
146	    num      = fs->font_data_count;
147	}
148	/* CDExc20229 fix */
149	if(fontdata == NULL || num == 0){
150	    return(NULL);
151	}
152    }
153
154
155    if(is2b){
156        csize = 2;
157    } else {
158        csize = 1;
159    }
160
161    for(;len;len--){
162        if(is2b){
163            value = (((unsigned long)*c) << 8)|(unsigned long)*(c + 1);
164        } else {
165            value = (unsigned long)*c;
166        }
167
168       /* ### NOTE: This routine DOES NOT WORK!
169	* ###       We can work around the problem in the calling routine,
170	* ###       but we really need to understand this better.  As it
171	* ###       stands, the algorithm ALWAYS returns "fontdata[0]"
172	* ###       for non-VW text!  This is clearly wrong.  In fact,
173	* ###       given the new parse_font[name|data]() algorithms,
174	* ###       we may not even need this routine to do anything
175	* ###       for non-VW text (since font_set->font always contains
176	* ###       the best font for this fontset).  -- jjw/pma (HP)
177	*/
178        for (i=0;i<num;i++) {
179	    if(type == VROTATE) {
180		if(fontdata[i].font) {
181		    /* If the num_cr equal zero, all character is rotated. */
182		    if(fontdata[i].scopes_num == 0) {
183			break;
184		    } else {
185			/* The vertical rotate glyph is not have code shift. */
186			if (ismatch_scopes(&(fontdata[i]),&value,False)) {
187			    break;
188			}
189		    }
190		}
191	    } else if(type == VMAP) {
192		if(fontdata[i].font) {
193		    vfont_type = check_vertical_fonttype(fontdata[i].name);
194		    if(vfont_type == 0 || vfont_type == 1) {
195			break;
196		    } else if(vfont_type == 2 || vfont_type == 3) {
197			if(fontdata[i].scopes_num <= 0)
198			    break;
199
200			if (ismatch_scopes(&(fontdata[i]),&value,True)) {
201			    break;
202			}
203		    }
204		}
205	    } else { /* FONTSCOPE */
206		if(fontdata[i].font) {
207		    if(fontdata[i].scopes_num <= 0)
208                        break;
209		    if (ismatch_scopes(&(fontdata[i]),&value,True)){
210		        break;
211                    }
212		}
213	    }
214        }
215        if((hit != -1) && (i != hit)){
216            break;
217        }
218        if(i == num){
219            if( type == VROTATE || type == VMAP){
220		/* Change 1996.01.23 start */
221		if(fs->font_data_count <= 0 ||
222		   fs->font_data == (FontData)NULL)
223		    fontdata = fs->substitute;
224		else
225		    fontdata = fs->font_data;
226		/* Change 1996.01.23 end */
227	    }
228	    hit = 0;
229            c += csize;
230	    break;
231        }
232        if( hit == -1 ) hit = i;
233        if(is2b){
234            *c = (unsigned char)(value >> 8);
235            *(c + 1) = (unsigned char)(value);
236        } else {
237            *c = (unsigned char)value;
238        }
239        c += csize;
240    }
241    *len_ret = (c - str);
242    return(&(fontdata[hit]));
243}
244/* for VW/UDC end   */
245
246static FontSet
247_XomGetFontSetFromCharSet(
248    XOC oc,
249    XlcCharSet charset)
250{
251    register FontSet font_set = XOC_GENERIC(oc)->font_set;
252    register int num = XOC_GENERIC(oc)->font_set_num;
253    XlcCharSet *charset_list;
254    int charset_count;
255
256    for ( ; num-- > 0; font_set++) {
257	charset_count = font_set->charset_count;
258	charset_list = font_set->charset_list;
259	for ( ; charset_count-- > 0; charset_list++)
260	    if (*charset_list == charset)
261		return font_set;
262    }
263
264    return (FontSet) NULL;
265}
266
267#ifdef MUSTCOPY
268static void
269cs_to_xchar2b(
270    register char *from,
271    register XChar2b *to,
272    register length)
273{
274    while (length-- > 0) {
275	to->byte1 = *from++;
276	to->byte2 = *from++;
277	to++;
278    }
279}
280
281static void
282cs_to_xchar2b_gl(
283    register char *from,
284    register XChar2b *to,
285    register length)
286{
287    while (length-- > 0) {
288	to->byte1 = *from++ & 0x7f;
289	to->byte2 = *from++ & 0x7f;
290	to++;
291    }
292}
293
294static void
295cs_to_xchar2b_gr(
296    register char *from,
297    register XChar2b *to,
298    register length)
299{
300    while (length-- > 0) {
301	to->byte1 = *from++ | 0x80;
302	to->byte2 = *from++ | 0x80;
303	to++;
304    }
305}
306#endif
307
308static void
309shift_to_gl(
310    register char *text,
311    register int length)
312{
313    while (length-- > 0)
314	*text++ &= 0x7f;
315}
316
317static void
318shift_to_gr(
319    register char *text,
320    register int length)
321{
322    while (length-- > 0)
323	*text++ |= 0x80;
324}
325
326static Bool
327load_font(
328    XOC oc,
329    FontSet font_set)
330{
331    font_set->font = XLoadQueryFont(oc->core.om->core.display,
332			oc->core.font_info.font_name_list[font_set->id]);
333    if (font_set->font == NULL)
334	return False;
335
336    oc->core.font_info.font_struct_list[font_set->id] = font_set->font;
337    XFreeFontInfo(NULL, font_set->info, 1);
338    font_set->info = NULL;
339
340    if (font_set->font->min_byte1 || font_set->font->max_byte1)
341	font_set->is_xchar2b = True;
342    else
343	font_set->is_xchar2b = False;
344
345    return True;
346}
347
348int
349_XomConvert(
350    XOC oc,
351    XlcConv conv,
352    XPointer *from,
353    int *from_left,
354    XPointer *to,
355    int *to_left,
356    XPointer *args,
357    int num_args)
358{
359    XPointer cs, lc_args[1];
360    XlcCharSet charset;
361    int length, cs_left, ret;
362    FontSet font_set;
363#ifdef MUSTCOPY
364    XChar2b *xchar2b;
365    char *buf, buf_local[BUFSIZ];
366#endif
367
368    cs = *to;
369    cs_left = *to_left;
370    lc_args[0] = (XPointer) &charset;
371
372    ret = _XlcConvert(conv, from, from_left, &cs, &cs_left, lc_args, 1);
373    if (ret < 0)
374	return -1;
375
376    font_set = _XomGetFontSetFromCharSet(oc, charset);
377    if (font_set == NULL)
378	return -1;
379
380    if (font_set->font == NULL && load_font(oc, font_set) == False)
381	return -1;
382
383    length = *to_left - cs_left;
384
385#ifdef MUSTCOPY
386    if (font_set->is_xchar2b) {
387	buf = (length > BUFSIZ) ? Xmalloc(length) : buf_local;
388	if (buf == NULL)
389	    return -1;
390	memcpy(buf, (char *) *to, length);
391
392	xchar2b = (XChar2b *) *to;
393	length >>= 1;
394
395	if (font_set->side == charset->side)
396	    cs_to_xchar2b(buf, xchar2b, length);
397	else if (font_set->side == XlcGL)
398	    cs_to_xchar2b_gl(buf, xchar2b, length);
399	else if (font_set->side == XlcGR)
400	    cs_to_xchar2b_gr(buf, xchar2b, length);
401	else
402	    cs_to_xchar2b(buf, xchar2b, length);
403
404	if (buf != buf_local)
405	    Xfree(buf);
406
407	*to = (XPointer) (xchar2b + length);
408	*to_left -= length;
409    } else
410#endif
411    {
412	if (font_set->side != charset->side) {
413	    if (font_set->side == XlcGL)
414		shift_to_gl(*to, length);
415	    else if (font_set->side == XlcGR)
416		shift_to_gr(*to, length);
417	}
418
419	if (font_set->is_xchar2b)
420	    length >>= 1;
421	*to = cs;
422	*to_left -= length;
423    }
424
425    *((XFontStruct **) args[0]) = font_set->font;
426    *((Bool *) args[1]) = font_set->is_xchar2b;
427    if(num_args >= 3){
428        *((FontSet *) args[2]) = font_set;
429    }
430
431    return ret;
432}
433
434XlcConv
435_XomInitConverter(
436    XOC oc,
437    XOMTextType type)
438{
439    XOCGenericPart *gen = XOC_GENERIC(oc);
440    XlcConv *convp;
441    const char *conv_type;
442    XlcConv conv;
443    XLCd lcd;
444
445    switch (type) {
446    case XOMWideChar:
447	convp = &gen->wcs_to_cs;
448	conv_type = XlcNWideChar;
449	break;
450    case XOMMultiByte:
451	convp = &gen->mbs_to_cs;
452	conv_type = XlcNMultiByte;
453	break;
454    case XOMUtf8String:
455	convp = &gen->utf8_to_cs;
456	conv_type = XlcNUtf8String;
457	break;
458    default:
459	return (XlcConv) NULL;
460    }
461
462    conv = *convp;
463    if (conv) {
464	_XlcResetConverter(conv);
465	return conv;
466    }
467
468    lcd = oc->core.om->core.lcd;
469
470    conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNFontCharSet);
471    if (conv == (XlcConv) NULL) {
472        conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNCharSet);
473        if (conv == (XlcConv) NULL)
474	    return (XlcConv) NULL;
475    }
476
477    *convp = conv;
478    return conv;
479}
480