omText.c revision 1ab64890
11ab64890Smrg/* $Xorg: omText.c,v 1.3 2000/08/17 19:45:22 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/* $XFree86: xc/lib/X11/omText.c,v 1.9 2003/04/22 13:57:45 pascal Exp $ */
271ab64890Smrg/*
281ab64890Smrg * Copyright 1995 by FUJITSU LIMITED
291ab64890Smrg * This is source code modified by FUJITSU LIMITED under the Joint
301ab64890Smrg * Development Agreement for the CDE/Motif PST.
311ab64890Smrg */
321ab64890Smrg/*
331ab64890Smrg * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
341ab64890Smrg */
351ab64890Smrg
361ab64890Smrg#ifdef HAVE_CONFIG_H
371ab64890Smrg#include <config.h>
381ab64890Smrg#endif
391ab64890Smrg#include "Xlibint.h"
401ab64890Smrg#include "XomGeneric.h"
411ab64890Smrg#include <stdio.h>
421ab64890Smrg
431ab64890Smrg/* For VW/UDC */
441ab64890Smrg
451ab64890Smrgstatic int
461ab64890Smrgis_rotate(
471ab64890Smrg    XOC		oc,
481ab64890Smrg    XFontStruct	*font)
491ab64890Smrg{
501ab64890Smrg    XOCGenericPart	*gen = XOC_GENERIC(oc);
511ab64890Smrg    FontSet		font_set;
521ab64890Smrg    VRotate		vrotate;
531ab64890Smrg    int			font_set_count;
541ab64890Smrg    int			vrotate_num;
551ab64890Smrg
561ab64890Smrg    font_set = gen->font_set;
571ab64890Smrg    font_set_count = gen->font_set_num;
581ab64890Smrg    for( ; font_set_count-- ; font_set++) {
591ab64890Smrg	if((font_set->vrotate_num > 0) && (font_set->vrotate)) {
601ab64890Smrg	    vrotate = font_set->vrotate;
611ab64890Smrg	    vrotate_num = font_set->vrotate_num;
621ab64890Smrg	    for( ; vrotate_num-- ; vrotate++)
631ab64890Smrg		if(vrotate->font == font)
641ab64890Smrg		    return True;
651ab64890Smrg	}
661ab64890Smrg    }
671ab64890Smrg    return False;
681ab64890Smrg}
691ab64890Smrg
701ab64890Smrgstatic int
711ab64890Smrgis_codemap(
721ab64890Smrg    XOC		oc,
731ab64890Smrg    XFontStruct	*font)
741ab64890Smrg{
751ab64890Smrg    XOCGenericPart	*gen = XOC_GENERIC(oc);
761ab64890Smrg    FontSet		font_set;
771ab64890Smrg    FontData		vmap;
781ab64890Smrg    int			font_set_count;
791ab64890Smrg    int			vmap_num;
801ab64890Smrg
811ab64890Smrg    font_set = gen->font_set;
821ab64890Smrg    font_set_count = gen->font_set_num;
831ab64890Smrg    for( ; font_set_count-- ; font_set++) {
841ab64890Smrg	if(font_set->vmap_num > 0) {
851ab64890Smrg	    vmap = font_set->vmap;
861ab64890Smrg	    vmap_num = font_set->vmap_num;
871ab64890Smrg	    for( ; vmap_num-- ; vmap++)
881ab64890Smrg		if(vmap->font == font)
891ab64890Smrg		    return True;
901ab64890Smrg	}
911ab64890Smrg    }
921ab64890Smrg    return False;
931ab64890Smrg}
941ab64890Smrg
951ab64890Smrgstatic int
961ab64890Smrgdraw_vertical(
971ab64890Smrg    Display	*dpy,
981ab64890Smrg    Drawable	d,
991ab64890Smrg    XOC		oc,
1001ab64890Smrg    GC		gc,
1011ab64890Smrg    XFontStruct	*font,
1021ab64890Smrg    Bool	is_xchar2b,
1031ab64890Smrg    int		x, int y,
1041ab64890Smrg    XPointer	text,
1051ab64890Smrg    int		length)
1061ab64890Smrg{
1071ab64890Smrg    XChar2b	*buf2b;
1081ab64890Smrg    char	*buf;
1091ab64890Smrg    int		wx = 0, wy = 0;
1101ab64890Smrg    int		direction = 0;
1111ab64890Smrg    int		font_ascent_return = 0, font_descent_return = 0;
1121ab64890Smrg    int		i;
1131ab64890Smrg    XCharStruct	overall;
1141ab64890Smrg
1151ab64890Smrg    wy = y;
1161ab64890Smrg    if (is_xchar2b) {
1171ab64890Smrg	for(i = 0, buf2b = (XChar2b *) text ; i < length ; i++, buf2b++) {
1181ab64890Smrg	    if(is_rotate(oc, font) == True) {
1191ab64890Smrg		XTextExtents16(font, buf2b, 1,
1201ab64890Smrg			       &direction, &font_ascent_return,
1211ab64890Smrg			       &font_descent_return, &overall);
1221ab64890Smrg		wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) -
1231ab64890Smrg			 (int) overall.lbearing;
1241ab64890Smrg		wy += overall.ascent;
1251ab64890Smrg		XDrawString16(dpy, d, gc, wx, wy, buf2b, 1);
1261ab64890Smrg		wy += overall.descent;
1271ab64890Smrg	    } else {
1281ab64890Smrg		wx = x - (int)((font->max_bounds.rbearing -
1291ab64890Smrg				font->min_bounds.lbearing) >> 1) -
1301ab64890Smrg			 (int) font->min_bounds.lbearing;
1311ab64890Smrg		wy += font->max_bounds.ascent;
1321ab64890Smrg		XDrawString16(dpy, d, gc, wx, wy, buf2b, 1);
1331ab64890Smrg		wy += font->max_bounds.descent;
1341ab64890Smrg	    }
1351ab64890Smrg	}
1361ab64890Smrg    } else {
1371ab64890Smrg	for(i = 0, buf = (char *)text ; i < length && *buf ; i++, buf++) {
1381ab64890Smrg	    if(is_rotate(oc, font) == True) {
1391ab64890Smrg		XTextExtents(font, buf, 1,
1401ab64890Smrg			     &direction, &font_ascent_return,
1411ab64890Smrg			     &font_descent_return, &overall);
1421ab64890Smrg		wx = x - (int)((overall.rbearing - overall.lbearing) >> 1) -
1431ab64890Smrg			 (int) overall.lbearing;
1441ab64890Smrg		wy += overall.ascent;
1451ab64890Smrg		XDrawString(dpy, d, gc, wx, wy, buf, 1);
1461ab64890Smrg		wy += overall.descent;
1471ab64890Smrg	    } else {
1481ab64890Smrg		wx = x - (int)((font->max_bounds.rbearing -
1491ab64890Smrg				font->min_bounds.lbearing) >> 1) -
1501ab64890Smrg			 (int) font->min_bounds.lbearing;
1511ab64890Smrg		wy += font->max_bounds.ascent;
1521ab64890Smrg		XDrawString(dpy, d, gc, wx, wy, buf, 1);
1531ab64890Smrg		wy += font->max_bounds.descent;
1541ab64890Smrg	    }
1551ab64890Smrg	}
1561ab64890Smrg    }
1571ab64890Smrg    return wy;
1581ab64890Smrg}
1591ab64890Smrg
1601ab64890Smrg#define VMAP          0
1611ab64890Smrg#define VROTATE       1
1621ab64890Smrg#define FONTSCOPE     2
1631ab64890Smrg
1641ab64890Smrgstatic int
1651ab64890SmrgDrawStringWithFontSet(
1661ab64890Smrg    Display *dpy,
1671ab64890Smrg    Drawable d,
1681ab64890Smrg    XOC oc,
1691ab64890Smrg    FontSet fs,
1701ab64890Smrg    GC gc,
1711ab64890Smrg    int x, int y,
1721ab64890Smrg    XPointer text,
1731ab64890Smrg    int length)
1741ab64890Smrg{
1751ab64890Smrg    XFontStruct *font;
1761ab64890Smrg    Bool is_xchar2b;
1771ab64890Smrg    unsigned char *ptr;
1781ab64890Smrg    int ptr_len, char_len = 0;
1791ab64890Smrg    FontData fd;
1801ab64890Smrg    int ret = 0;
1811ab64890Smrg
1821ab64890Smrg    ptr = (unsigned char *)text;
1831ab64890Smrg    is_xchar2b = fs->is_xchar2b;
1841ab64890Smrg
1851ab64890Smrg    while (length > 0) {
1861ab64890Smrg        fd = _XomGetFontDataFromFontSet(fs,
1871ab64890Smrg			ptr,length,&ptr_len,is_xchar2b,FONTSCOPE);
1881ab64890Smrg	if(ptr_len <= 0)
1891ab64890Smrg	    break;
1901ab64890Smrg
1911ab64890Smrg       /* First, see if the "Best Match" font for the FontSet was set.
1921ab64890Smrg	* If it was, use that font.  If it was not set, then use the
1931ab64890Smrg	* font defined by font_set->font_data[0] (which is what
1941ab64890Smrg	* _XomGetFontDataFromFontSet() always seems to return for
1951ab64890Smrg	* non-VW text).  Note that given the new algorithm in
1961ab64890Smrg	* parse_fontname() and parse_fontdata(), fs->font will
1971ab64890Smrg	* *always* contain good data.   We should probably remove
1981ab64890Smrg	* the check for "fd->font", but we won't :-) -- jjw/pma (HP)
1991ab64890Smrg	*/
2001ab64890Smrg        if((font = fs->font) == (XFontStruct *) NULL){
2011ab64890Smrg
2021ab64890Smrg	    if(fd == (FontData) NULL ||
2031ab64890Smrg	       (font = fd->font) == (XFontStruct *) NULL)
2041ab64890Smrg		break;
2051ab64890Smrg        }
2061ab64890Smrg
2071ab64890Smrg	switch(oc->core.orientation) {
2081ab64890Smrg	  case XOMOrientation_LTR_TTB:
2091ab64890Smrg	  case XOMOrientation_RTL_TTB:
2101ab64890Smrg            XSetFont(dpy, gc, font->fid);
2111ab64890Smrg
2121ab64890Smrg	    if (is_xchar2b) {
2131ab64890Smrg		char_len = ptr_len / sizeof(XChar2b);
2141ab64890Smrg		XDrawString16(dpy, d, gc, x, y, (XChar2b *)ptr, char_len);
2151ab64890Smrg		x += XTextWidth16(font, (XChar2b *)ptr, char_len);
2161ab64890Smrg            } else {
2171ab64890Smrg		char_len = ptr_len;
2181ab64890Smrg		XDrawString(dpy, d, gc, x, y, (char *)ptr, char_len);
2191ab64890Smrg		x += XTextWidth(font, (char *)ptr, char_len);
2201ab64890Smrg	    }
2211ab64890Smrg	    break;
2221ab64890Smrg	  case XOMOrientation_TTB_RTL:
2231ab64890Smrg	  case XOMOrientation_TTB_LTR:
2241ab64890Smrg	    if(fs->font == font) {
2251ab64890Smrg		fd = _XomGetFontDataFromFontSet(fs,
2261ab64890Smrg			ptr,length,&ptr_len,is_xchar2b,VMAP);
2271ab64890Smrg		if(ptr_len <= 0)
2281ab64890Smrg		    break;
2291ab64890Smrg		if(fd == (FontData) NULL ||
2301ab64890Smrg		   (font = fd->font) == (XFontStruct *) NULL)
2311ab64890Smrg		    break;
2321ab64890Smrg
2331ab64890Smrg		if(is_codemap(oc, fd->font) == False) {
2341ab64890Smrg		    fd = _XomGetFontDataFromFontSet(fs,
2351ab64890Smrg			     ptr,length,&ptr_len,is_xchar2b,VROTATE);
2361ab64890Smrg		    if(ptr_len <= 0)
2371ab64890Smrg			break;
2381ab64890Smrg		    if(fd == (FontData) NULL ||
2391ab64890Smrg		       (font = fd->font) == (XFontStruct *) NULL)
2401ab64890Smrg			break;
2411ab64890Smrg		}
2421ab64890Smrg	    }
2431ab64890Smrg
2441ab64890Smrg	    if(is_xchar2b)
2451ab64890Smrg		char_len = ptr_len / sizeof(XChar2b);
2461ab64890Smrg	    else
2471ab64890Smrg		char_len = ptr_len;
2481ab64890Smrg            XSetFont(dpy, gc, font->fid);
2491ab64890Smrg	    y = draw_vertical(dpy, d, oc, gc, font, is_xchar2b, x, y,
2501ab64890Smrg			       (char *)ptr, char_len);
2511ab64890Smrg	    break;
2521ab64890Smrg
2531ab64890Smrg	  case XOMOrientation_Context:
2541ab64890Smrg	    /* never used? */
2551ab64890Smrg	    break;
2561ab64890Smrg	}
2571ab64890Smrg
2581ab64890Smrg	if(char_len <= 0)
2591ab64890Smrg	    break;
2601ab64890Smrg
2611ab64890Smrg        length -= char_len;
2621ab64890Smrg        ptr += ptr_len;
2631ab64890Smrg    }
2641ab64890Smrg
2651ab64890Smrg    switch(oc->core.orientation) {
2661ab64890Smrg      case XOMOrientation_LTR_TTB:
2671ab64890Smrg      case XOMOrientation_RTL_TTB:
2681ab64890Smrg	ret = x;
2691ab64890Smrg	break;
2701ab64890Smrg      case XOMOrientation_TTB_RTL:
2711ab64890Smrg      case XOMOrientation_TTB_LTR:
2721ab64890Smrg	ret = y;
2731ab64890Smrg	break;
2741ab64890Smrg      case XOMOrientation_Context:
2751ab64890Smrg	/* not used? */
2761ab64890Smrg	break;
2771ab64890Smrg    }
2781ab64890Smrg    return ret;
2791ab64890Smrg}
2801ab64890Smrg
2811ab64890Smrg/* For VW/UDC */
2821ab64890Smrg
2831ab64890Smrgint
2841ab64890Smrg_XomGenericDrawString(
2851ab64890Smrg    Display *dpy,
2861ab64890Smrg    Drawable d,
2871ab64890Smrg    XOC oc,
2881ab64890Smrg    GC gc,
2891ab64890Smrg    int x, int y,
2901ab64890Smrg    XOMTextType type,
2911ab64890Smrg    XPointer text,
2921ab64890Smrg    int length)
2931ab64890Smrg{
2941ab64890Smrg    XlcConv conv;
2951ab64890Smrg    XFontStruct *font;
2961ab64890Smrg    Bool is_xchar2b;
2971ab64890Smrg/* VW/UDC */
2981ab64890Smrg    XPointer args[3];
2991ab64890Smrg    FontSet fs;
3001ab64890Smrg/* VW/UDC */
3011ab64890Smrg    XChar2b xchar2b_buf[BUFSIZ], *buf;
3021ab64890Smrg    int start_x = x;
3031ab64890Smrg    int start_y = y;
3041ab64890Smrg    int left = 0, buf_len = 0;
3051ab64890Smrg    int next = 0;
3061ab64890Smrg
3071ab64890Smrg    conv = _XomInitConverter(oc, type);
3081ab64890Smrg    if (conv == NULL)
3091ab64890Smrg	return -1;
3101ab64890Smrg
3111ab64890Smrg    args[0] = (XPointer) &font;
3121ab64890Smrg    args[1] = (XPointer) &is_xchar2b;
3131ab64890Smrg    args[2] = (XPointer) &fs;
3141ab64890Smrg
3151ab64890Smrg    while (length > 0) {
3161ab64890Smrg	buf = xchar2b_buf;
3171ab64890Smrg	left = buf_len = BUFSIZ;
3181ab64890Smrg
3191ab64890Smrg	if (_XomConvert(oc, conv, (XPointer *) &text, &length,
3201ab64890Smrg			(XPointer *) &buf, &left, args, 3) < 0)
3211ab64890Smrg	    break;
3221ab64890Smrg	buf_len -= left;
3231ab64890Smrg
3241ab64890Smrg/* For VW/UDC */
3251ab64890Smrg	next = DrawStringWithFontSet(dpy, d, oc, fs, gc, x, y,
3261ab64890Smrg				     (XPointer)xchar2b_buf, buf_len);
3271ab64890Smrg
3281ab64890Smrg	switch(oc->core.orientation) {
3291ab64890Smrg	  case XOMOrientation_LTR_TTB:
3301ab64890Smrg	  case XOMOrientation_RTL_TTB:
3311ab64890Smrg	    x = next;
3321ab64890Smrg	    break;
3331ab64890Smrg	  case XOMOrientation_TTB_RTL:
3341ab64890Smrg	  case XOMOrientation_TTB_LTR:
3351ab64890Smrg	    y = next;
3361ab64890Smrg	    break;
3371ab64890Smrg          case XOMOrientation_Context:
3381ab64890Smrg	    /* not used */
3391ab64890Smrg	    break;
3401ab64890Smrg	}
3411ab64890Smrg/* For VW/UDC */
3421ab64890Smrg    }
3431ab64890Smrg
3441ab64890Smrg    x -= start_x;
3451ab64890Smrg    y -= start_y;
3461ab64890Smrg
3471ab64890Smrg    return x;
3481ab64890Smrg}
3491ab64890Smrg
3501ab64890Smrgint
3511ab64890Smrg_XmbGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
3521ab64890Smrg		      _Xconst char *text, int length)
3531ab64890Smrg{
3541ab64890Smrg    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMMultiByte,
3551ab64890Smrg				 (XPointer) text, length);
3561ab64890Smrg}
3571ab64890Smrg
3581ab64890Smrgint
3591ab64890Smrg_XwcGenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
3601ab64890Smrg		      _Xconst wchar_t *text, int length)
3611ab64890Smrg{
3621ab64890Smrg    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMWideChar,
3631ab64890Smrg				 (XPointer) text, length);
3641ab64890Smrg}
3651ab64890Smrg
3661ab64890Smrgint
3671ab64890Smrg_Xutf8GenericDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
3681ab64890Smrg			_Xconst char *text, int length)
3691ab64890Smrg{
3701ab64890Smrg    return _XomGenericDrawString(dpy, d, oc, gc, x, y, XOMUtf8String,
3711ab64890Smrg				 (XPointer) text, length);
3721ab64890Smrg}
373