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