Initialize Tizen 2.3
[framework/uifw/xorg/lib/libx11.git] / modules / om / generic / omTextEsc.c
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
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 #include "Xlibint.h"
35 #include "XomGeneric.h"
36 #include <stdio.h>
37
38 /* For VW/UDC start */
39
40 #define VMAP            0
41 #define VROTATE         1
42 #define FONTSCOPE       2
43
44 static int
45 is_rotate(
46     XOC         oc,
47     XFontStruct *font)
48 {
49     XOCGenericPart      *gen = XOC_GENERIC(oc);
50     FontSet             font_set;
51     VRotate             vrotate;
52     int                 font_set_count;
53     int                 vrotate_num;
54
55     font_set = gen->font_set;
56     font_set_count = gen->font_set_num;
57     for( ; font_set_count-- ; font_set++) {
58         if((font_set->vrotate_num > 0) && (font_set->vrotate != NULL)) {
59             vrotate = font_set->vrotate;
60             vrotate_num = font_set->vrotate_num;
61             for( ; vrotate_num-- ; vrotate++)
62                 if(vrotate->font == font)
63                     return True;
64         }
65     }
66     return False;
67 }
68
69 static int
70 is_codemap(
71     XOC         oc,
72     XFontStruct *font)
73 {
74     XOCGenericPart      *gen = XOC_GENERIC(oc);
75     FontSet             font_set;
76     FontData            vmap;
77     int                 font_set_count;
78     int                 vmap_num;
79
80     font_set = gen->font_set;
81     font_set_count = gen->font_set_num;
82     for( ; font_set_count-- ; font_set++) {
83         if(font_set->vmap_num > 0) {
84             vmap = font_set->vmap;
85             vmap_num = font_set->vmap_num;
86             for( ; vmap_num-- ; vmap++)
87                 if(vmap->font == font)
88                     return True;
89         }
90     }
91     return False;
92 }
93
94 static int
95 escapement_vertical(
96     XOC         oc,
97     XFontStruct *font,
98     Bool        is_xchar2b,
99     XPointer    text,
100     int         length)
101 {
102     XChar2b     *buf2b;
103     char        *buf;
104     int         escapement = 0, i;
105
106     if(is_xchar2b) {
107         for(i = 0, buf2b = (XChar2b *) text ; i < length ; i++, buf2b++) {
108             if(is_rotate(oc, font) == True) {
109                 escapement += _XTextHeight16(font, buf2b, 1);
110             } else {
111                 escapement += (int) (font->max_bounds.ascent +
112                                      font->max_bounds.descent);
113             }
114         }
115     } else {
116         for(i = 0, buf = (char *)text ; i < length && *buf ; i++, buf++) {
117             if(is_rotate(oc, font) == True) {
118                 escapement += _XTextHeight(font, buf, 1);
119             } else {
120                 escapement += (int) (font->max_bounds.ascent +
121                                      font->max_bounds.descent);
122             }
123         }
124     }
125     return escapement;
126 }
127
128
129 static int
130 TextWidthWithFontSet(
131     FontSet     font_set,
132     XOC         oc,
133     XPointer    text,
134     int         length)
135 {
136     FontData            fd;
137     XFontStruct         *font;
138     unsigned char       *ptr = (unsigned char *)text;
139     Bool                is_xchar2b;
140     int                 ptr_len = length;
141     int                 escapement = 0, char_len = 0;
142
143     if(font_set == (FontSet) NULL)
144         return escapement;
145
146     is_xchar2b = font_set->is_xchar2b;
147
148     while(length > 0) {
149         fd = _XomGetFontDataFromFontSet(font_set, ptr, length, &ptr_len,
150                                                is_xchar2b, FONTSCOPE);
151         if(ptr_len <= 0)
152             break;
153
154         /*
155          * First, see if the "Best Match" font for the FontSet was set.
156          * If it was, use that font.  If it was not set, then use the
157          * font defined by font_set->font_data[0] (which is what
158          * _XomGetFontDataFromFontSet() always seems to return for
159          * non-VW text).  Note that given the new algorithm in
160          * parse_fontname() and parse_fontdata(), fs->font will
161          * *always* contain good data.   We should probably remove
162          * the check for "fd->font", but we won't :-) -- jjw/pma (HP)
163          *
164          * Above comment and way this is done propagated from omText.c
165          * Note that fd->font is junk so using the result of the
166          * above call /needs/ to be ignored.
167          *
168          * Owen Taylor <otaylor@redhat.com>     12 Jul 2000
169          *
170          */
171
172         if(fd == (FontData) NULL ||
173            (font = font_set->font) == (XFontStruct *) NULL) {
174
175             if((font = fd->font) == (XFontStruct *) NULL)
176                 break;
177         }
178
179         switch(oc->core.orientation) {
180           case XOMOrientation_LTR_TTB:
181           case XOMOrientation_RTL_TTB:
182             if (is_xchar2b) {
183                 char_len = ptr_len / sizeof(XChar2b);
184                 escapement += XTextWidth16(font, (XChar2b *)ptr, char_len);
185             } else {
186                 char_len = ptr_len;
187                 escapement += XTextWidth(font, (char *)ptr, char_len);
188             }
189             break;
190
191           case XOMOrientation_TTB_LTR:
192           case XOMOrientation_TTB_RTL:
193             if(font_set->font == font) {
194                 fd = _XomGetFontDataFromFontSet(font_set, ptr, length, &ptr_len,
195                                                 is_xchar2b, VMAP);
196                 if(ptr_len <= 0)
197                     break;
198                 if(fd == (FontData) NULL ||
199                    (font = fd->font) == (XFontStruct *) NULL)
200                     break;
201
202                 if(is_codemap(oc, fd->font) == False) {
203                     fd = _XomGetFontDataFromFontSet(font_set, ptr, length,
204                                                     &ptr_len, is_xchar2b,
205                                                     VROTATE);
206                     if(ptr_len <= 0)
207                         break;
208                     if(fd == (FontData) NULL ||
209                        (font = fd->font) == (XFontStruct *) NULL)
210                         break;
211                 }
212             }
213
214             if(is_xchar2b)
215                 char_len = ptr_len / sizeof(XChar2b);
216             else
217                 char_len = ptr_len;
218             escapement += escapement_vertical(oc, font, is_xchar2b,
219                                               (XPointer) ptr, char_len);
220             break;
221
222           case XOMOrientation_Context:
223             /* not used? */
224             break;
225         }
226
227         if(char_len <= 0)
228             break;
229
230         length -= char_len;
231         ptr += ptr_len;
232     }
233
234     return escapement;
235 }
236
237 /* For VW/UDC end */
238
239 static int
240 _XomGenericTextEscapement(
241     XOC oc,
242     XOMTextType type,
243     XPointer text,
244     int length)
245 {
246     XlcConv conv;
247     XFontStruct *font;
248     Bool is_xchar2b;
249 /* VW/UDC */
250     XPointer args[3];
251     FontSet font_set;
252 /* VW/UDC */
253     XChar2b xchar2b_buf[BUFSIZ], *buf;
254     int escapement = 0;
255     int buf_len = 0, left = 0;
256
257     conv = _XomInitConverter(oc, type);
258     if (conv == NULL)
259         return escapement;
260
261     args[0] = (XPointer) &font;
262     args[1] = (XPointer) &is_xchar2b;
263     args[2] = (XPointer) &font_set;
264
265     while (length > 0) {
266         buf = xchar2b_buf;
267         left = buf_len = BUFSIZ;
268
269         if (_XomConvert(oc, conv, (XPointer *) &text, &length,
270                         (XPointer *) &buf, &left, args, 3) < 0)
271             break;
272         buf_len -= left;
273
274 /* VW/UDC */
275         escapement += TextWidthWithFontSet(font_set, oc,
276                                            (XPointer) xchar2b_buf, buf_len);
277 /* VW/UDC */
278     }
279
280     return escapement;
281 }
282
283 int
284 _XmbGenericTextEscapement(XOC oc, _Xconst char *text, int length)
285 {
286     return _XomGenericTextEscapement(oc, XOMMultiByte, (XPointer) text, length);
287 }
288
289 int
290 _XwcGenericTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
291 {
292     return _XomGenericTextEscapement(oc, XOMWideChar, (XPointer) text, length);
293 }
294
295 int
296 _Xutf8GenericTextEscapement(XOC oc, _Xconst char *text, int length)
297 {
298     return _XomGenericTextEscapement(oc, XOMUtf8String, (XPointer) text,
299                                      length);
300 }