11ab64890Smrg/*
21ab64890Smrg * Copyright 1992, 1993 by TOSHIBA Corp.
31ab64890Smrg *
41ab64890Smrg * Permission to use, copy, modify, and distribute this software and its
51ab64890Smrg * documentation for any purpose and without fee is hereby granted, provided
61ab64890Smrg * that the above copyright notice appear in all copies and that both that
71ab64890Smrg * copyright notice and this permission notice appear in supporting
81ab64890Smrg * documentation, and that the name of TOSHIBA not be used in advertising
91ab64890Smrg * or publicity pertaining to distribution of the software without specific,
101ab64890Smrg * written prior permission. TOSHIBA make no representations about the
111ab64890Smrg * suitability of this software for any purpose.  It is provided "as is"
121ab64890Smrg * without express or implied warranty.
131ab64890Smrg *
141ab64890Smrg * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
151ab64890Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
161ab64890Smrg * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
171ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
181ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
191ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
201ab64890Smrg * SOFTWARE.
211ab64890Smrg *
221ab64890Smrg * Author: Katsuhisa Yano	TOSHIBA Corp.
231ab64890Smrg *			   	mopi@osa.ilab.toshiba.co.jp
241ab64890Smrg */
251ab64890Smrg/*
261ab64890Smrg * Copyright 1995 by FUJITSU LIMITED
271ab64890Smrg * This is source code modified by FUJITSU LIMITED under the Joint
281ab64890Smrg * Development Agreement for the CDE/Motif PST.
291ab64890Smrg *
301ab64890Smrg * Modifier: Takanori Tateno   FUJITSU LIMITED
311ab64890Smrg *
321ab64890Smrg */
331ab64890Smrg/*
341ab64890Smrg * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
351ab64890Smrg */
361ab64890Smrg
371ab64890Smrg#ifdef HAVE_CONFIG_H
381ab64890Smrg#include <config.h>
391ab64890Smrg#endif
401ab64890Smrg#include "Xlibint.h"
411ab64890Smrg#include "XlcPublic.h"
421ab64890Smrg#include "XomGeneric.h"
431ab64890Smrg#include <stdio.h>
441ab64890Smrg
451ab64890Smrg/* for VW/UDC start */
461ab64890Smrgstatic Bool
471ab64890Smrgismatch_scopes(
481ab64890Smrg    FontData      fontdata,
491ab64890Smrg    unsigned long *value,
501ab64890Smrg    Bool	  is_shift)
511ab64890Smrg{
521ab64890Smrg    register int scopes_num = fontdata->scopes_num;
531ab64890Smrg    FontScope scopes = fontdata->scopes;
541ab64890Smrg    if (!scopes_num)
551ab64890Smrg        return False;
561ab64890Smrg
571ab64890Smrg    if(fontdata->font == NULL)
581ab64890Smrg	return False;
591ab64890Smrg
601ab64890Smrg    for(;scopes_num--;scopes++)
611ab64890Smrg        if ((scopes->start <= (*value & 0x7f7f)) &&
621ab64890Smrg                        ((scopes->end) >= (*value & 0x7f7f))){
631ab64890Smrg	    if(is_shift == True) {
641ab64890Smrg                if(scopes->shift){
651ab64890Smrg                    if(scopes->shift_direction == '+'){
661ab64890Smrg                        *value += scopes->shift ;
671ab64890Smrg                    } else if( scopes->shift_direction == '-'){
681ab64890Smrg                        *value -= scopes->shift ;
691ab64890Smrg                    }
701ab64890Smrg                }
711ab64890Smrg            }
721ab64890Smrg            return True;
731ab64890Smrg        }
741ab64890Smrg
751ab64890Smrg    return False;
761ab64890Smrg}
771ab64890Smrg
781ab64890Smrgstatic int
791ab64890Smrgcheck_vertical_fonttype(
801ab64890Smrg    char	*name)
811ab64890Smrg{
821ab64890Smrg    char	*ptr;
831ab64890Smrg    int		type = 0;
841ab64890Smrg
851ab64890Smrg    if(name == (char *)NULL || (int) strlen(name) <= 0)
861ab64890Smrg	return False;
871ab64890Smrg
881ab64890Smrg    /* Obtains the pointer of CHARSET_ENCODING_FIELD. */
891ab64890Smrg    if((ptr = strchr(name, '-')) == (char *) NULL)
901ab64890Smrg	return False;
911ab64890Smrg    ptr++;
921ab64890Smrg
931ab64890Smrg    /* Obtains the pointer of vertical_map font type. */
941ab64890Smrg    if((ptr = strchr(ptr, '.')) == (char *) NULL)
951ab64890Smrg	return False;
961ab64890Smrg    ptr++;
971ab64890Smrg
981ab64890Smrg    switch(*ptr) {
991ab64890Smrg      case '1':
1001ab64890Smrg	type = 1;	break;
1011ab64890Smrg      case '2':
1021ab64890Smrg	type = 2;	break;
1031ab64890Smrg      case '3':
1041ab64890Smrg	type = 3;	break;
1051ab64890Smrg    }
1061ab64890Smrg    return type;
1071ab64890Smrg}
1081ab64890Smrg
1091ab64890Smrg/*
1101ab64890Smrg*/
1111ab64890Smrg#define VMAP          0
1121ab64890Smrg#define VROTATE       1
1131ab64890Smrg#define FONTSCOPE     2
1141ab64890Smrg
1151ab64890SmrgFontData
1161ab64890Smrg_XomGetFontDataFromFontSet(
1171ab64890Smrg    FontSet fs,
1181ab64890Smrg    unsigned char *str,
1191ab64890Smrg    int len,
1201ab64890Smrg    int *len_ret,
12161b2299dSmrg    int is2b,
1221ab64890Smrg    int type)          /* VMAP , VROTATE , else */
1231ab64890Smrg{
1241ab64890Smrg    unsigned long value;
1251ab64890Smrg    int num,i,hit,csize;
1261ab64890Smrg    FontData fontdata;
1271ab64890Smrg    unsigned char *c;
1281ab64890Smrg    int vfont_type;
12961b2299dSmrg
1301ab64890Smrg    c = str;
1311ab64890Smrg    hit = -1;
1321ab64890Smrg    if(type == VMAP){
1331ab64890Smrg	fontdata = fs->vmap;
1341ab64890Smrg	num      = fs->vmap_num;
1351ab64890Smrg    } else if(type == VROTATE){
1361ab64890Smrg        fontdata = (FontData)fs->vrotate;
1371ab64890Smrg	num      = fs->vrotate_num;
1381ab64890Smrg    } else {
1391ab64890Smrg	if(fs->font_data_count <= 0 || fs->font_data == (FontData)NULL) {
1401ab64890Smrg	    fontdata = fs->substitute;
1411ab64890Smrg	    num      = fs->substitute_num;
1421ab64890Smrg	}else {
1431ab64890Smrg            fontdata = fs->font_data;
1441ab64890Smrg	    num      = fs->font_data_count;
1451ab64890Smrg	}
1461ab64890Smrg	/* CDExc20229 fix */
1471ab64890Smrg	if(fontdata == NULL || num == 0){
1481ab64890Smrg	    return(NULL);
1491ab64890Smrg	}
1501ab64890Smrg    }
1511ab64890Smrg
1521ab64890Smrg
1531ab64890Smrg    if(is2b){
1541ab64890Smrg        csize = 2;
1551ab64890Smrg    } else {
1561ab64890Smrg        csize = 1;
1571ab64890Smrg    }
1581ab64890Smrg
1591ab64890Smrg    for(;len;len--){
1601ab64890Smrg        if(is2b){
1611ab64890Smrg            value = (((unsigned long)*c) << 8)|(unsigned long)*(c + 1);
1621ab64890Smrg        } else {
1631ab64890Smrg            value = (unsigned long)*c;
1641ab64890Smrg        }
16561b2299dSmrg
1661ab64890Smrg       /* ### NOTE: This routine DOES NOT WORK!
1671ab64890Smrg	* ###       We can work around the problem in the calling routine,
1681ab64890Smrg	* ###       but we really need to understand this better.  As it
1691ab64890Smrg	* ###       stands, the algorithm ALWAYS returns "fontdata[0]"
1701ab64890Smrg	* ###       for non-VW text!  This is clearly wrong.  In fact,
1711ab64890Smrg	* ###       given the new parse_font[name|data]() algorithms,
1721ab64890Smrg	* ###       we may not even need this routine to do anything
1731ab64890Smrg	* ###       for non-VW text (since font_set->font always contains
1741ab64890Smrg	* ###       the best font for this fontset).  -- jjw/pma (HP)
1751ab64890Smrg	*/
1761ab64890Smrg        for (i=0;i<num;i++) {
1771ab64890Smrg	    if(type == VROTATE) {
1781ab64890Smrg		if(fontdata[i].font) {
1791ab64890Smrg		    /* If the num_cr equal zero, all character is rotated. */
1801ab64890Smrg		    if(fontdata[i].scopes_num == 0) {
1811ab64890Smrg			break;
1821ab64890Smrg		    } else {
1831ab64890Smrg			/* The vertical rotate glyph is not have code shift. */
1841ab64890Smrg			if (ismatch_scopes(&(fontdata[i]),&value,False)) {
1851ab64890Smrg			    break;
1861ab64890Smrg			}
1871ab64890Smrg		    }
1881ab64890Smrg		}
1891ab64890Smrg	    } else if(type == VMAP) {
1901ab64890Smrg		if(fontdata[i].font) {
1911ab64890Smrg		    vfont_type = check_vertical_fonttype(fontdata[i].name);
1921ab64890Smrg		    if(vfont_type == 0 || vfont_type == 1) {
1931ab64890Smrg			break;
1941ab64890Smrg		    } else if(vfont_type == 2 || vfont_type == 3) {
1951ab64890Smrg			if(fontdata[i].scopes_num <= 0)
1961ab64890Smrg			    break;
1971ab64890Smrg
1981ab64890Smrg			if (ismatch_scopes(&(fontdata[i]),&value,True)) {
1991ab64890Smrg			    break;
2001ab64890Smrg			}
2011ab64890Smrg		    }
2021ab64890Smrg		}
2031ab64890Smrg	    } else { /* FONTSCOPE */
2041ab64890Smrg		if(fontdata[i].font) {
2051ab64890Smrg		    if(fontdata[i].scopes_num <= 0)
2061ab64890Smrg                        break;
2071ab64890Smrg		    if (ismatch_scopes(&(fontdata[i]),&value,True)){
2081ab64890Smrg		        break;
2091ab64890Smrg                    }
2101ab64890Smrg		}
2111ab64890Smrg	    }
2121ab64890Smrg        }
2131ab64890Smrg        if((hit != -1) && (i != hit)){
2141ab64890Smrg            break;
2151ab64890Smrg        }
2161ab64890Smrg        if(i == num){
2171ab64890Smrg            if( type == VROTATE || type == VMAP){
2181ab64890Smrg		/* Change 1996.01.23 start */
2191ab64890Smrg		if(fs->font_data_count <= 0 ||
2201ab64890Smrg		   fs->font_data == (FontData)NULL)
2211ab64890Smrg		    fontdata = fs->substitute;
2221ab64890Smrg		else
2231ab64890Smrg		    fontdata = fs->font_data;
2241ab64890Smrg		/* Change 1996.01.23 end */
2251ab64890Smrg	    }
2261ab64890Smrg	    hit = 0;
2271ab64890Smrg            c += csize;
2281ab64890Smrg	    break;
2291ab64890Smrg        }
2301ab64890Smrg        if( hit == -1 ) hit = i;
2311ab64890Smrg        if(is2b){
2321ab64890Smrg            *c = (unsigned char)(value >> 8);
2331ab64890Smrg            *(c + 1) = (unsigned char)(value);
2341ab64890Smrg        } else {
2351ab64890Smrg            *c = (unsigned char)value;
2361ab64890Smrg        }
2371ab64890Smrg        c += csize;
2381ab64890Smrg    }
2391ab64890Smrg    *len_ret = (c - str);
2401ab64890Smrg    return(&(fontdata[hit]));
2411ab64890Smrg}
2421ab64890Smrg/* for VW/UDC end   */
2431ab64890Smrg
2441ab64890Smrgstatic FontSet
2451ab64890Smrg_XomGetFontSetFromCharSet(
2461ab64890Smrg    XOC oc,
2471ab64890Smrg    XlcCharSet charset)
2481ab64890Smrg{
2491ab64890Smrg    register FontSet font_set = XOC_GENERIC(oc)->font_set;
2501ab64890Smrg    register int num = XOC_GENERIC(oc)->font_set_num;
2511ab64890Smrg    XlcCharSet *charset_list;
2521ab64890Smrg    int charset_count;
2531ab64890Smrg
2541ab64890Smrg    for ( ; num-- > 0; font_set++) {
2551ab64890Smrg	charset_count = font_set->charset_count;
2561ab64890Smrg	charset_list = font_set->charset_list;
2571ab64890Smrg	for ( ; charset_count-- > 0; charset_list++)
2581ab64890Smrg	    if (*charset_list == charset)
2591ab64890Smrg		return font_set;
2601ab64890Smrg    }
2611ab64890Smrg
2621ab64890Smrg    return (FontSet) NULL;
2631ab64890Smrg}
2641ab64890Smrg
2651ab64890Smrgstatic void
2661ab64890Smrgshift_to_gl(
2671ab64890Smrg    register char *text,
2681ab64890Smrg    register int length)
2691ab64890Smrg{
2701ab64890Smrg    while (length-- > 0)
2711ab64890Smrg	*text++ &= 0x7f;
2721ab64890Smrg}
2731ab64890Smrg
2741ab64890Smrgstatic void
2751ab64890Smrgshift_to_gr(
2761ab64890Smrg    register char *text,
2771ab64890Smrg    register int length)
2781ab64890Smrg{
2791ab64890Smrg    while (length-- > 0)
2801ab64890Smrg	*text++ |= 0x80;
2811ab64890Smrg}
2821ab64890Smrg
2831ab64890Smrgstatic Bool
2841ab64890Smrgload_font(
2851ab64890Smrg    XOC oc,
2861ab64890Smrg    FontSet font_set)
2871ab64890Smrg{
2881ab64890Smrg    font_set->font = XLoadQueryFont(oc->core.om->core.display,
2891ab64890Smrg			oc->core.font_info.font_name_list[font_set->id]);
2901ab64890Smrg    if (font_set->font == NULL)
2911ab64890Smrg	return False;
29261b2299dSmrg
2931ab64890Smrg    oc->core.font_info.font_struct_list[font_set->id] = font_set->font;
2941ab64890Smrg    XFreeFontInfo(NULL, font_set->info, 1);
2951ab64890Smrg    font_set->info = NULL;
2961ab64890Smrg
2971ab64890Smrg    if (font_set->font->min_byte1 || font_set->font->max_byte1)
2981ab64890Smrg	font_set->is_xchar2b = True;
2991ab64890Smrg    else
3001ab64890Smrg	font_set->is_xchar2b = False;
3011ab64890Smrg
3021ab64890Smrg    return True;
3031ab64890Smrg}
3041ab64890Smrg
3051ab64890Smrgint
3061ab64890Smrg_XomConvert(
3071ab64890Smrg    XOC oc,
3081ab64890Smrg    XlcConv conv,
3091ab64890Smrg    XPointer *from,
3101ab64890Smrg    int *from_left,
3111ab64890Smrg    XPointer *to,
3121ab64890Smrg    int *to_left,
3131ab64890Smrg    XPointer *args,
3141ab64890Smrg    int num_args)
3151ab64890Smrg{
3161ab64890Smrg    XPointer cs, lc_args[1];
3171ab64890Smrg    XlcCharSet charset;
3181ab64890Smrg    int length, cs_left, ret;
3191ab64890Smrg    FontSet font_set;
32061b2299dSmrg
3211ab64890Smrg    cs = *to;
3221ab64890Smrg    cs_left = *to_left;
3231ab64890Smrg    lc_args[0] = (XPointer) &charset;
3241ab64890Smrg
3251ab64890Smrg    ret = _XlcConvert(conv, from, from_left, &cs, &cs_left, lc_args, 1);
3261ab64890Smrg    if (ret < 0)
3271ab64890Smrg	return -1;
3281ab64890Smrg
3291ab64890Smrg    font_set = _XomGetFontSetFromCharSet(oc, charset);
3301ab64890Smrg    if (font_set == NULL)
3311ab64890Smrg	return -1;
3321ab64890Smrg
3331ab64890Smrg    if (font_set->font == NULL && load_font(oc, font_set) == False)
3341ab64890Smrg	return -1;
3351ab64890Smrg
3361ab64890Smrg    length = *to_left - cs_left;
3371ab64890Smrg
338eb411b4bSmrg    if (font_set->side != charset->side) {
339eb411b4bSmrg	if (font_set->side == XlcGL)
340eb411b4bSmrg	    shift_to_gl(*to, length);
3411ab64890Smrg	else if (font_set->side == XlcGR)
342eb411b4bSmrg	    shift_to_gr(*to, length);
3431ab64890Smrg    }
3441ab64890Smrg
345eb411b4bSmrg    if (font_set->is_xchar2b)
346eb411b4bSmrg	length >>= 1;
347eb411b4bSmrg    *to = cs;
348eb411b4bSmrg    *to_left -= length;
349eb411b4bSmrg
3501ab64890Smrg    *((XFontStruct **) args[0]) = font_set->font;
3511ab64890Smrg    *((Bool *) args[1]) = font_set->is_xchar2b;
3521ab64890Smrg    if(num_args >= 3){
3531ab64890Smrg        *((FontSet *) args[2]) = font_set;
3541ab64890Smrg    }
3551ab64890Smrg
3561ab64890Smrg    return ret;
3571ab64890Smrg}
3581ab64890Smrg
3591ab64890SmrgXlcConv
3601ab64890Smrg_XomInitConverter(
3611ab64890Smrg    XOC oc,
3621ab64890Smrg    XOMTextType type)
3631ab64890Smrg{
3641ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
3651ab64890Smrg    XlcConv *convp;
3661ab64890Smrg    const char *conv_type;
3671ab64890Smrg    XlcConv conv;
3681ab64890Smrg    XLCd lcd;
3691ab64890Smrg
3701ab64890Smrg    switch (type) {
3711ab64890Smrg    case XOMWideChar:
3721ab64890Smrg	convp = &gen->wcs_to_cs;
3731ab64890Smrg	conv_type = XlcNWideChar;
3741ab64890Smrg	break;
3751ab64890Smrg    case XOMMultiByte:
3761ab64890Smrg	convp = &gen->mbs_to_cs;
3771ab64890Smrg	conv_type = XlcNMultiByte;
3781ab64890Smrg	break;
3791ab64890Smrg    case XOMUtf8String:
3801ab64890Smrg	convp = &gen->utf8_to_cs;
3811ab64890Smrg	conv_type = XlcNUtf8String;
3821ab64890Smrg	break;
3831ab64890Smrg    default:
3841ab64890Smrg	return (XlcConv) NULL;
3851ab64890Smrg    }
3861ab64890Smrg
3871ab64890Smrg    conv = *convp;
3881ab64890Smrg    if (conv) {
3891ab64890Smrg	_XlcResetConverter(conv);
3901ab64890Smrg	return conv;
3911ab64890Smrg    }
3921ab64890Smrg
3931ab64890Smrg    lcd = oc->core.om->core.lcd;
3941ab64890Smrg
3951ab64890Smrg    conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNFontCharSet);
3961ab64890Smrg    if (conv == (XlcConv) NULL) {
3971ab64890Smrg        conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNCharSet);
3981ab64890Smrg        if (conv == (XlcConv) NULL)
3991ab64890Smrg	    return (XlcConv) NULL;
4001ab64890Smrg    }
4011ab64890Smrg
4021ab64890Smrg    *convp = conv;
4031ab64890Smrg    return conv;
4041ab64890Smrg}
405