1 /*
2  * Copyright 1992, 1993 by TOSHIBA Corp.
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of TOSHIBA not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission. TOSHIBA make no representations about the
11  * suitability of this software for any purpose.  It is provided "as is"
12  * without express or implied warranty.
13  *
14  * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16  * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20  * SOFTWARE.
21  *
22  * Author: Katsuhisa Yano	TOSHIBA Corp.
23  *			   	mopi@osa.ilab.toshiba.co.jp
24  */
25 /*
26  * Copyright 1995 by FUJITSU LIMITED
27  * This is source code modified by FUJITSU LIMITED under the Joint
28  * Development Agreement for the CDE/Motif PST.
29  *
30  * Modifier: Takanori Tateno   FUJITSU LIMITED
31  *
32  */
33 /*
34  * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
35  */
36 
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40 #include "Xlibint.h"
41 #include "XlcPublic.h"
42 #include "XomGeneric.h"
43 #include <stdio.h>
44 
45 /* for VW/UDC start */
46 static Bool
ismatch_scopes(FontData fontdata,unsigned long * value,Bool is_shift)47 ismatch_scopes(
48     FontData      fontdata,
49     unsigned long *value,
50     Bool	  is_shift)
51 {
52     register int scopes_num = fontdata->scopes_num;
53     FontScope scopes = fontdata->scopes;
54     if (!scopes_num)
55         return False;
56 
57     if(fontdata->font == NULL)
58 	return False;
59 
60     for(;scopes_num--;scopes++)
61         if ((scopes->start <= (*value & 0x7f7f)) &&
62                         ((scopes->end) >= (*value & 0x7f7f))){
63 	    if(is_shift == True) {
64                 if(scopes->shift){
65                     if(scopes->shift_direction == '+'){
66                         *value += scopes->shift ;
67                     } else if( scopes->shift_direction == '-'){
68                         *value -= scopes->shift ;
69                     }
70                 }
71             }
72             return True;
73         }
74 
75     return False;
76 }
77 
78 static int
check_vertical_fonttype(char * name)79 check_vertical_fonttype(
80     char	*name)
81 {
82     char	*ptr;
83     int		type = 0;
84 
85     if(name == (char *)NULL || (int) strlen(name) <= 0)
86 	return False;
87 
88     /* Obtains the pointer of CHARSET_ENCODING_FIELD. */
89     if((ptr = strchr(name, '-')) == (char *) NULL)
90 	return False;
91     ptr++;
92 
93     /* Obtains the pointer of vertical_map font type. */
94     if((ptr = strchr(ptr, '.')) == (char *) NULL)
95 	return False;
96     ptr++;
97 
98     switch(*ptr) {
99       case '1':
100 	type = 1;	break;
101       case '2':
102 	type = 2;	break;
103       case '3':
104 	type = 3;	break;
105     }
106     return type;
107 }
108 
109 /*
110 */
111 #define VMAP          0
112 #define VROTATE       1
113 #define FONTSCOPE     2
114 
115 FontData
_XomGetFontDataFromFontSet(FontSet fs,unsigned char * str,int len,int * len_ret,int is2b,int type)116 _XomGetFontDataFromFontSet(
117     FontSet fs,
118     unsigned char *str,
119     int len,
120     int *len_ret,
121     int is2b,
122     int type)          /* VMAP , VROTATE , else */
123 {
124     unsigned long value;
125     int num,i,hit,csize;
126     FontData fontdata;
127     unsigned char *c;
128     int vfont_type;
129 
130     c = str;
131     hit = -1;
132     if(type == VMAP){
133 	fontdata = fs->vmap;
134 	num      = fs->vmap_num;
135     } else if(type == VROTATE){
136         fontdata = (FontData)fs->vrotate;
137 	num      = fs->vrotate_num;
138     } else {
139 	if(fs->font_data_count <= 0 || fs->font_data == (FontData)NULL) {
140 	    fontdata = fs->substitute;
141 	    num      = fs->substitute_num;
142 	}else {
143             fontdata = fs->font_data;
144 	    num      = fs->font_data_count;
145 	}
146 	/* CDExc20229 fix */
147 	if(fontdata == NULL || num == 0){
148 	    return(NULL);
149 	}
150     }
151 
152 
153     if(is2b){
154         csize = 2;
155     } else {
156         csize = 1;
157     }
158 
159     for(;len;len--){
160         if(is2b){
161             value = (((unsigned long)*c) << 8)|(unsigned long)*(c + 1);
162         } else {
163             value = (unsigned long)*c;
164         }
165 
166        /* ### NOTE: This routine DOES NOT WORK!
167 	* ###       We can work around the problem in the calling routine,
168 	* ###       but we really need to understand this better.  As it
169 	* ###       stands, the algorithm ALWAYS returns "fontdata[0]"
170 	* ###       for non-VW text!  This is clearly wrong.  In fact,
171 	* ###       given the new parse_font[name|data]() algorithms,
172 	* ###       we may not even need this routine to do anything
173 	* ###       for non-VW text (since font_set->font always contains
174 	* ###       the best font for this fontset).  -- jjw/pma (HP)
175 	*/
176         for (i=0;i<num;i++) {
177 	    if(type == VROTATE) {
178 		if(fontdata[i].font) {
179 		    /* If the num_cr equal zero, all character is rotated. */
180 		    if(fontdata[i].scopes_num == 0) {
181 			break;
182 		    } else {
183 			/* The vertical rotate glyph is not have code shift. */
184 			if (ismatch_scopes(&(fontdata[i]),&value,False)) {
185 			    break;
186 			}
187 		    }
188 		}
189 	    } else if(type == VMAP) {
190 		if(fontdata[i].font) {
191 		    vfont_type = check_vertical_fonttype(fontdata[i].name);
192 		    if(vfont_type == 0 || vfont_type == 1) {
193 			break;
194 		    } else if(vfont_type == 2 || vfont_type == 3) {
195 			if(fontdata[i].scopes_num <= 0)
196 			    break;
197 
198 			if (ismatch_scopes(&(fontdata[i]),&value,True)) {
199 			    break;
200 			}
201 		    }
202 		}
203 	    } else { /* FONTSCOPE */
204 		if(fontdata[i].font) {
205 		    if(fontdata[i].scopes_num <= 0)
206                         break;
207 		    if (ismatch_scopes(&(fontdata[i]),&value,True)){
208 		        break;
209                     }
210 		}
211 	    }
212         }
213         if((hit != -1) && (i != hit)){
214             break;
215         }
216         if(i == num){
217             if( type == VROTATE || type == VMAP){
218 		/* Change 1996.01.23 start */
219 		if(fs->font_data_count <= 0 ||
220 		   fs->font_data == (FontData)NULL)
221 		    fontdata = fs->substitute;
222 		else
223 		    fontdata = fs->font_data;
224 		/* Change 1996.01.23 end */
225 	    }
226 	    hit = 0;
227             c += csize;
228 	    break;
229         }
230         if( hit == -1 ) hit = i;
231         if(is2b){
232             *c = (unsigned char)(value >> 8);
233             *(c + 1) = (unsigned char)(value);
234         } else {
235             *c = (unsigned char)value;
236         }
237         c += csize;
238     }
239     *len_ret = (c - str);
240     return(&(fontdata[hit]));
241 }
242 /* for VW/UDC end   */
243 
244 static FontSet
_XomGetFontSetFromCharSet(XOC oc,XlcCharSet charset)245 _XomGetFontSetFromCharSet(
246     XOC oc,
247     XlcCharSet charset)
248 {
249     register FontSet font_set = XOC_GENERIC(oc)->font_set;
250     register int num = XOC_GENERIC(oc)->font_set_num;
251     XlcCharSet *charset_list;
252     int charset_count;
253 
254     for ( ; num-- > 0; font_set++) {
255 	charset_count = font_set->charset_count;
256 	charset_list = font_set->charset_list;
257 	for ( ; charset_count-- > 0; charset_list++)
258 	    if (*charset_list == charset)
259 		return font_set;
260     }
261 
262     return (FontSet) NULL;
263 }
264 
265 static void
shift_to_gl(register char * text,register int length)266 shift_to_gl(
267     register char *text,
268     register int length)
269 {
270     while (length-- > 0)
271 	*text++ &= 0x7f;
272 }
273 
274 static void
shift_to_gr(register char * text,register int length)275 shift_to_gr(
276     register char *text,
277     register int length)
278 {
279     while (length-- > 0)
280 	*text++ |= 0x80;
281 }
282 
283 static Bool
load_font(XOC oc,FontSet font_set)284 load_font(
285     XOC oc,
286     FontSet font_set)
287 {
288     font_set->font = XLoadQueryFont(oc->core.om->core.display,
289 			oc->core.font_info.font_name_list[font_set->id]);
290     if (font_set->font == NULL)
291 	return False;
292 
293     oc->core.font_info.font_struct_list[font_set->id] = font_set->font;
294     XFreeFontInfo(NULL, font_set->info, 1);
295     font_set->info = NULL;
296 
297     if (font_set->font->min_byte1 || font_set->font->max_byte1)
298 	font_set->is_xchar2b = True;
299     else
300 	font_set->is_xchar2b = False;
301 
302     return True;
303 }
304 
305 int
_XomConvert(XOC oc,XlcConv conv,XPointer * from,int * from_left,XPointer * to,int * to_left,XPointer * args,int num_args)306 _XomConvert(
307     XOC oc,
308     XlcConv conv,
309     XPointer *from,
310     int *from_left,
311     XPointer *to,
312     int *to_left,
313     XPointer *args,
314     int num_args)
315 {
316     XPointer cs, lc_args[1];
317     XlcCharSet charset;
318     int length, cs_left, ret;
319     FontSet font_set;
320 
321     cs = *to;
322     cs_left = *to_left;
323     lc_args[0] = (XPointer) &charset;
324 
325     ret = _XlcConvert(conv, from, from_left, &cs, &cs_left, lc_args, 1);
326     if (ret < 0)
327 	return -1;
328 
329     font_set = _XomGetFontSetFromCharSet(oc, charset);
330     if (font_set == NULL)
331 	return -1;
332 
333     if (font_set->font == NULL && load_font(oc, font_set) == False)
334 	return -1;
335 
336     length = *to_left - cs_left;
337 
338     if (font_set->side != charset->side) {
339 	if (font_set->side == XlcGL)
340 	    shift_to_gl(*to, length);
341 	else if (font_set->side == XlcGR)
342 	    shift_to_gr(*to, length);
343     }
344 
345     if (font_set->is_xchar2b)
346 	length >>= 1;
347     *to = cs;
348     *to_left -= length;
349 
350     *((XFontStruct **) args[0]) = font_set->font;
351     *((Bool *) args[1]) = font_set->is_xchar2b;
352     if(num_args >= 3){
353         *((FontSet *) args[2]) = font_set;
354     }
355 
356     return ret;
357 }
358 
359 XlcConv
_XomInitConverter(XOC oc,XOMTextType type)360 _XomInitConverter(
361     XOC oc,
362     XOMTextType type)
363 {
364     XOCGenericPart *gen = XOC_GENERIC(oc);
365     XlcConv *convp;
366     const char *conv_type;
367     XlcConv conv;
368     XLCd lcd;
369 
370     switch (type) {
371     case XOMWideChar:
372 	convp = &gen->wcs_to_cs;
373 	conv_type = XlcNWideChar;
374 	break;
375     case XOMMultiByte:
376 	convp = &gen->mbs_to_cs;
377 	conv_type = XlcNMultiByte;
378 	break;
379     case XOMUtf8String:
380 	convp = &gen->utf8_to_cs;
381 	conv_type = XlcNUtf8String;
382 	break;
383     default:
384 	return (XlcConv) NULL;
385     }
386 
387     conv = *convp;
388     if (conv) {
389 	_XlcResetConverter(conv);
390 	return conv;
391     }
392 
393     lcd = oc->core.om->core.lcd;
394 
395     conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNFontCharSet);
396     if (conv == (XlcConv) NULL) {
397         conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNCharSet);
398         if (conv == (XlcConv) NULL)
399 	    return (XlcConv) NULL;
400     }
401 
402     *convp = conv;
403     return conv;
404 }
405