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#ifdef HAVE_CONFIG_H 27#include <config.h> 28#endif 29#include "Xlibint.h" 30#include "XomGeneric.h" 31#include <stdio.h> 32 33static Status 34_XomGenericTextPerCharExtents( 35 XOC oc, 36 XOMTextType type, 37 XPointer text, 38 int length, 39 XRectangle *ink_buf, 40 XRectangle *logical_buf, 41 int buf_size, 42 int *num_chars, 43 XRectangle *overall_ink, 44 XRectangle *overall_logical) 45{ 46 XlcConv conv; 47 XFontStruct *font; 48 Bool is_xchar2b; 49 XPointer args[2]; 50 XChar2b xchar2b_buf[BUFSIZ], *xchar2b_ptr; 51 char *xchar_ptr = NULL; 52 XCharStruct *def, *cs, overall; 53 int buf_len, left, require_num; 54 int logical_ascent, logical_descent; 55 Bool first = True; 56 57 conv = _XomInitConverter(oc, type); 58 if (conv == NULL) 59 return 0; 60 61 bzero((char *) &overall, sizeof(XCharStruct)); 62 logical_ascent = logical_descent = require_num = *num_chars = 0; 63 64 args[0] = (XPointer) &font; 65 args[1] = (XPointer) &is_xchar2b; 66 67 while (length > 0) { 68 xchar2b_ptr = xchar2b_buf; 69 left = buf_len = BUFSIZ; 70 71 if (_XomConvert(oc, conv, (XPointer *) &text, &length, 72 (XPointer *) &xchar2b_ptr, &left, args, 2) < 0) 73 break; 74 buf_len -= left; 75 76 if (require_num) { 77 require_num += buf_len; 78 continue; 79 } 80 if (buf_size < buf_len) { 81 require_num = *num_chars + buf_len; 82 continue; 83 } 84 buf_size -= buf_len; 85 86 if (first) { 87 logical_ascent = font->ascent; 88 logical_descent = font->descent; 89 } else { 90 logical_ascent = max(logical_ascent, font->ascent); 91 logical_descent = max(logical_descent, font->descent); 92 } 93 94 if (is_xchar2b) { 95 CI_GET_DEFAULT_INFO_2D(font, def); 96 xchar2b_ptr = xchar2b_buf; 97 } else { 98 CI_GET_DEFAULT_INFO_1D(font, def); 99 xchar_ptr = (char *) xchar2b_buf; 100 } 101 102 while (buf_len-- > 0) { 103 if (is_xchar2b) { 104 CI_GET_CHAR_INFO_2D(font, xchar2b_ptr->byte1, 105 xchar2b_ptr->byte2, def, cs); 106 xchar2b_ptr++; 107 } else { 108 CI_GET_CHAR_INFO_1D(font, *xchar_ptr, def, cs); 109 xchar_ptr++; 110 } 111 if (cs == NULL) 112 continue; 113 114 ink_buf->x = overall.width + cs->lbearing; 115 ink_buf->y = -(cs->ascent); 116 ink_buf->width = cs->rbearing - cs->lbearing; 117 ink_buf->height = cs->ascent + cs->descent; 118 ink_buf++; 119 120 logical_buf->x = overall.width; 121 logical_buf->y = -(font->ascent); 122 logical_buf->width = cs->width; 123 logical_buf->height = font->ascent + font->descent; 124 logical_buf++; 125 126 if (first) { 127 overall = *cs; 128 first = False; 129 } else { 130 overall.ascent = max(overall.ascent, cs->ascent); 131 overall.descent = max(overall.descent, cs->descent); 132 overall.lbearing = min(overall.lbearing, 133 overall.width + cs->lbearing); 134 overall.rbearing = max(overall.rbearing, 135 overall.width + cs->rbearing); 136 overall.width += cs->width; 137 } 138 139 (*num_chars)++; 140 } 141 } 142 143 if (require_num) { 144 *num_chars = require_num; 145 return 0; 146 } else { 147 if (overall_ink) { 148 overall_ink->x = overall.lbearing; 149 overall_ink->y = -(overall.ascent); 150 overall_ink->width = overall.rbearing - overall.lbearing; 151 overall_ink->height = overall.ascent + overall.descent; 152 } 153 154 if (overall_logical) { 155 overall_logical->x = 0; 156 overall_logical->y = -(logical_ascent); 157 overall_logical->width = overall.width; 158 overall_logical->height = logical_ascent + logical_descent; 159 } 160 } 161 162 return 1; 163} 164 165Status 166_XmbGenericTextPerCharExtents(XOC oc, _Xconst char *text, int length, 167 XRectangle *ink_buf, XRectangle *logical_buf, 168 int buf_size, int *num_chars, 169 XRectangle *overall_ink, 170 XRectangle *overall_logical) 171{ 172 return _XomGenericTextPerCharExtents(oc, XOMMultiByte, (XPointer) text, 173 length, ink_buf, logical_buf, buf_size, 174 num_chars, overall_ink, 175 overall_logical); 176} 177 178Status 179_XwcGenericTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, 180 XRectangle *ink_buf, XRectangle *logical_buf, 181 int buf_size, int *num_chars, 182 XRectangle *overall_ink, 183 XRectangle *overall_logical) 184{ 185 return _XomGenericTextPerCharExtents(oc, XOMWideChar, (XPointer) text, 186 length, ink_buf, logical_buf, buf_size, 187 num_chars, overall_ink, 188 overall_logical); 189} 190 191Status 192_Xutf8GenericTextPerCharExtents(XOC oc, _Xconst char *text, int length, 193 XRectangle *ink_buf, XRectangle *logical_buf, 194 int buf_size, int *num_chars, 195 XRectangle *overall_ink, 196 XRectangle *overall_logical) 197{ 198 return _XomGenericTextPerCharExtents(oc, XOMUtf8String, (XPointer) text, 199 length, ink_buf, logical_buf, buf_size, 200 num_chars, overall_ink, 201 overall_logical); 202} 203