fsconvert.c revision a96d7823
1a96d7823Smrg/* 2a96d7823Smrg * Copyright 1990 Network Computing Devices 3a96d7823Smrg * 4a96d7823Smrg * Permission to use, copy, modify, distribute, and sell this software and 5a96d7823Smrg * its documentation for any purpose is hereby granted without fee, provided 6a96d7823Smrg * that the above copyright notice appear in all copies and that both that 7a96d7823Smrg * copyright notice and this permission notice appear in supporting 8a96d7823Smrg * documentation, and that the name of Network Computing Devices not be used 9a96d7823Smrg * in advertising or publicity pertaining to distribution of the software 10a96d7823Smrg * without specific, written prior permission. Network Computing Devices 11a96d7823Smrg * makes no representations about the suitability of this software for any 12a96d7823Smrg * purpose. It is provided "as is" without express or implied warranty. 13a96d7823Smrg * 14a96d7823Smrg * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 15a96d7823Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 16a96d7823Smrg * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, 17a96d7823Smrg * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 18a96d7823Smrg * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 19a96d7823Smrg * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 20a96d7823Smrg * OR PERFORMANCE OF THIS SOFTWARE. 21a96d7823Smrg * 22a96d7823Smrg * Author: Dave Lemke, Network Computing Devices, Inc 23a96d7823Smrg */ 24a96d7823Smrg/* 25a96d7823Smrg * FS data conversion 26a96d7823Smrg */ 27a96d7823Smrg 28a96d7823Smrg#ifdef HAVE_CONFIG_H 29a96d7823Smrg#include <config.h> 30a96d7823Smrg#endif 31a96d7823Smrg#include "libxfontint.h" 32a96d7823Smrg#include <X11/X.h> 33a96d7823Smrg#include <X11/Xtrans/Xtrans.h> 34a96d7823Smrg#include <X11/Xpoll.h> 35a96d7823Smrg#include <X11/fonts/FS.h> 36a96d7823Smrg#include <X11/fonts/FSproto.h> 37a96d7823Smrg#include <X11/fonts/fontmisc.h> 38a96d7823Smrg#include <X11/fonts/fontstruct.h> 39a96d7823Smrg#include "fservestr.h" 40a96d7823Smrg#include <X11/fonts/fontutil.h> 41a96d7823Smrg#include "fslibos.h" 42a96d7823Smrg 43a96d7823Smrgextern char _fs_glyph_undefined; 44a96d7823Smrgextern char _fs_glyph_requested; 45a96d7823Smrg 46a96d7823Smrg/* 47a96d7823Smrg * converts data from font server form to X server form 48a96d7823Smrg */ 49a96d7823Smrg 50a96d7823Smrgvoid 51a96d7823Smrg_fs_convert_char_info(fsXCharInfo *src, xCharInfo *dst) 52a96d7823Smrg{ 53a96d7823Smrg dst->ascent = src->ascent; 54a96d7823Smrg dst->descent = src->descent; 55a96d7823Smrg dst->leftSideBearing = src->left; 56a96d7823Smrg dst->rightSideBearing = src->right; 57a96d7823Smrg dst->characterWidth = src->width; 58a96d7823Smrg dst->attributes = src->attributes; 59a96d7823Smrg} 60a96d7823Smrg 61a96d7823Smrgvoid 62a96d7823Smrg_fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi) 63a96d7823Smrg{ 64a96d7823Smrg if (conn->fsMajorVersion == 1) { 65a96d7823Smrg unsigned short n; 66a96d7823Smrg n = pfi->firstCol; 67a96d7823Smrg pfi->firstCol = pfi->firstRow; 68a96d7823Smrg pfi->firstRow = n; 69a96d7823Smrg n = pfi->lastCol; 70a96d7823Smrg pfi->lastCol = pfi->lastRow; 71a96d7823Smrg pfi->lastRow = n; 72a96d7823Smrg pfi->defaultCh = ((pfi->defaultCh >> 8) & 0xff) 73a96d7823Smrg + ((pfi->defaultCh & 0xff) << 8); 74a96d7823Smrg } 75a96d7823Smrg 76a96d7823Smrg if (FontCouldBeTerminal (pfi)) 77a96d7823Smrg { 78a96d7823Smrg pfi->terminalFont = TRUE; 79a96d7823Smrg pfi->minbounds.ascent = pfi->fontAscent; 80a96d7823Smrg pfi->minbounds.descent = pfi->fontDescent; 81a96d7823Smrg pfi->minbounds.leftSideBearing = 0; 82a96d7823Smrg pfi->minbounds.rightSideBearing = pfi->minbounds.characterWidth; 83a96d7823Smrg pfi->maxbounds = pfi->minbounds; 84a96d7823Smrg } 85a96d7823Smrg 86a96d7823Smrg FontComputeInfoAccelerators (pfi); 87a96d7823Smrg} 88a96d7823Smrg 89a96d7823Smrgint 90a96d7823Smrg_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, 91a96d7823Smrg FontInfoPtr pfi) 92a96d7823Smrg{ 93a96d7823Smrg FontPropPtr dprop; 94a96d7823Smrg int i, 95a96d7823Smrg nprops; 96a96d7823Smrg char *is_str; 97a96d7823Smrg fsPropOffset local_off; 98a96d7823Smrg char *off_adr; 99a96d7823Smrg char *pdc = pd; 100a96d7823Smrg 101a96d7823Smrg/* stolen from server/include/resource.h */ 102a96d7823Smrg#define BAD_RESOURCE 0xe0000000 103a96d7823Smrg 104a96d7823Smrg nprops = pfi->nprops = pi->num_offsets; 105a96d7823Smrg 106a96d7823Smrg if (nprops < 0 107a96d7823Smrg || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) 108a96d7823Smrg return -1; 109a96d7823Smrg 110a96d7823Smrg dprop = malloc(sizeof(FontPropRec) * nprops + sizeof (char) * nprops); 111a96d7823Smrg if (!dprop) 112a96d7823Smrg return -1; 113a96d7823Smrg 114a96d7823Smrg is_str = (char *) (dprop + nprops); 115a96d7823Smrg pfi->props = dprop; 116a96d7823Smrg pfi->isStringProp = is_str; 117a96d7823Smrg 118a96d7823Smrg off_adr = (char *)po; 119a96d7823Smrg for (i = 0; i < nprops; i++, dprop++, is_str++) 120a96d7823Smrg { 121a96d7823Smrg memcpy(&local_off, off_adr, SIZEOF(fsPropOffset)); 122a96d7823Smrg if ((local_off.name.position >= pi->data_len) || 123a96d7823Smrg (local_off.name.length > 124a96d7823Smrg (pi->data_len - local_off.name.position))) 125a96d7823Smrg goto bail; 126a96d7823Smrg dprop->name = MakeAtom(&pdc[local_off.name.position], 127a96d7823Smrg local_off.name.length, 1); 128a96d7823Smrg if (local_off.type != PropTypeString) { 129a96d7823Smrg *is_str = FALSE; 130a96d7823Smrg dprop->value = local_off.value.position; 131a96d7823Smrg } else { 132a96d7823Smrg *is_str = TRUE; 133a96d7823Smrg if ((local_off.value.position >= pi->data_len) || 134a96d7823Smrg (local_off.value.length > 135a96d7823Smrg (pi->data_len - local_off.value.position))) 136a96d7823Smrg goto bail; 137a96d7823Smrg dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position], 138a96d7823Smrg local_off.value.length, 1); 139a96d7823Smrg if (dprop->value == BAD_RESOURCE) 140a96d7823Smrg { 141a96d7823Smrg bail: 142a96d7823Smrg free (pfi->props); 143a96d7823Smrg pfi->nprops = 0; 144a96d7823Smrg pfi->props = 0; 145a96d7823Smrg pfi->isStringProp = 0; 146a96d7823Smrg return -1; 147a96d7823Smrg } 148a96d7823Smrg } 149a96d7823Smrg off_adr += SIZEOF(fsPropOffset); 150a96d7823Smrg } 151a96d7823Smrg 152a96d7823Smrg return nprops; 153a96d7823Smrg} 154a96d7823Smrg 155a96d7823Smrgvoid 156a96d7823Smrg_fs_free_props (FontInfoPtr pfi) 157a96d7823Smrg{ 158a96d7823Smrg if (pfi->props) 159a96d7823Smrg { 160a96d7823Smrg free (pfi->props); 161a96d7823Smrg pfi->nprops = 0; 162a96d7823Smrg pfi->props = 0; 163a96d7823Smrg } 164a96d7823Smrg} 165a96d7823Smrg 166a96d7823Smrgint 167a96d7823Smrg_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, 168a96d7823Smrg fsListFontsWithXInfoReply *fsrep, 169a96d7823Smrg fsPropInfo *pi, fsPropOffset *po, pointer pd) 170a96d7823Smrg{ 171a96d7823Smrg fsUnpack_XFontInfoHeader(fsrep, pfi); 172a96d7823Smrg _fs_init_fontinfo(conn, pfi); 173a96d7823Smrg 174a96d7823Smrg if (_fs_convert_props(pi, po, pd, pfi) == -1) 175a96d7823Smrg return AllocError; 176a96d7823Smrg 177a96d7823Smrg return Successful; 178a96d7823Smrg} 179a96d7823Smrg 180a96d7823Smrg 181a96d7823Smrg#define ENCODING_UNDEFINED(enc) \ 182a96d7823Smrg ((enc)->bits == &_fs_glyph_undefined ? \ 183a96d7823Smrg TRUE : \ 184a96d7823Smrg (access_done = access_done && (enc)->bits != &_fs_glyph_requested, \ 185a96d7823Smrg FALSE)) 186a96d7823Smrg 187a96d7823Smrg#define GLYPH_UNDEFINED(loc) ENCODING_UNDEFINED(encoding + (loc)) 188a96d7823Smrg 189a96d7823Smrg/* 190a96d7823Smrg * figures out what glyphs to request 191a96d7823Smrg * 192a96d7823Smrg * Includes logic to attempt to reduce number of round trips to the font 193a96d7823Smrg * server: when a glyph is requested, fs_build_range() requests a 194a96d7823Smrg * 16-glyph range of glyphs that contains the requested glyph. This is 195a96d7823Smrg * predicated on the belief that using a glyph increases the chances 196a96d7823Smrg * that nearby glyphs will be used: a good assumption for phonetic 197a96d7823Smrg * alphabets, but a questionable one for ideographic/pictographic ones. 198a96d7823Smrg */ 199a96d7823Smrg/* ARGSUSED */ 200a96d7823Smrgint 201a96d7823Smrgfs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, 202a96d7823Smrg int item_size, unsigned char *data, int *nranges, 203a96d7823Smrg fsRange **ranges) 204a96d7823Smrg{ 205a96d7823Smrg FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate); 206a96d7823Smrg FSFontPtr fsfont = (FSFontPtr) (pfont->fontPrivate); 207a96d7823Smrg register CharInfoPtr encoding = fsfont->encoding; 208a96d7823Smrg FontInfoPtr pfi = &(pfont->info); 209a96d7823Smrg fsRange range; 210a96d7823Smrg int access_done = TRUE; 211a96d7823Smrg int err; 212a96d7823Smrg register unsigned long firstrow, lastrow, firstcol, lastcol; 213a96d7823Smrg register unsigned long row; 214a96d7823Smrg register unsigned long col; 215a96d7823Smrg register unsigned long loc; 216a96d7823Smrg 217a96d7823Smrg if (!fsd->glyphs_to_get) 218a96d7823Smrg return AccessDone; 219a96d7823Smrg 220a96d7823Smrg firstrow = pfi->firstRow; 221a96d7823Smrg lastrow = pfi->lastRow; 222a96d7823Smrg firstcol = pfi->firstCol; 223a96d7823Smrg lastcol = pfi->lastCol; 224a96d7823Smrg 225a96d7823Smrg /* Make sure we have default char */ 226a96d7823Smrg if (fsfont->pDefault && ENCODING_UNDEFINED(fsfont->pDefault)) 227a96d7823Smrg { 228a96d7823Smrg loc = fsfont->pDefault - encoding; 229a96d7823Smrg row = loc / (lastcol - firstcol + 1) + firstrow; 230a96d7823Smrg col = loc % (lastcol - firstcol + 1) + firstcol; 231a96d7823Smrg 232a96d7823Smrg range.min_char_low = range.max_char_low = col; 233a96d7823Smrg range.min_char_high = range.max_char_high = row; 234a96d7823Smrg 235a96d7823Smrg if ((err = add_range(&range, nranges, ranges, FALSE)) != 236a96d7823Smrg Successful) return err; 237a96d7823Smrg encoding[loc].bits = &_fs_glyph_requested; 238a96d7823Smrg access_done = FALSE; 239a96d7823Smrg } 240a96d7823Smrg 241a96d7823Smrg if (!range_flag && item_size == 1) 242a96d7823Smrg { 243a96d7823Smrg if (firstrow != 0) return AccessDone; 244a96d7823Smrg while (count--) 245a96d7823Smrg { 246a96d7823Smrg col = *data++; 247a96d7823Smrg if (col >= firstcol && col <= lastcol && 248a96d7823Smrg GLYPH_UNDEFINED(col - firstcol)) 249a96d7823Smrg { 250a96d7823Smrg int col1, col2; 251a96d7823Smrg col1 = col & 0xf0; 252a96d7823Smrg col2 = col1 + 15; 253a96d7823Smrg if (col1 < firstcol) col1 = firstcol; 254a96d7823Smrg if (col2 > lastcol) col2 = lastcol; 255a96d7823Smrg /* Collect a 16-glyph neighborhood containing the requested 256a96d7823Smrg glyph... should in most cases reduce the number of round 257a96d7823Smrg trips to the font server. */ 258a96d7823Smrg for (col = col1; col <= col2; col++) 259a96d7823Smrg { 260a96d7823Smrg if (!GLYPH_UNDEFINED(col - firstcol)) continue; 261a96d7823Smrg range.min_char_low = range.max_char_low = col; 262a96d7823Smrg range.min_char_high = range.max_char_high = 0; 263a96d7823Smrg if ((err = add_range(&range, nranges, ranges, FALSE)) != 264a96d7823Smrg Successful) return err; 265a96d7823Smrg encoding[col - firstcol].bits = &_fs_glyph_requested; 266a96d7823Smrg access_done = FALSE; 267a96d7823Smrg } 268a96d7823Smrg } 269a96d7823Smrg } 270a96d7823Smrg } 271a96d7823Smrg else 272a96d7823Smrg { 273a96d7823Smrg fsRange fullrange[1]; 274a96d7823Smrg 275a96d7823Smrg if (range_flag && count == 0) 276a96d7823Smrg { 277a96d7823Smrg count = 2; 278a96d7823Smrg data = (unsigned char *)fullrange; 279a96d7823Smrg fullrange[0].min_char_high = firstrow; 280a96d7823Smrg fullrange[0].min_char_low = firstcol; 281a96d7823Smrg fullrange[0].max_char_high = lastrow; 282a96d7823Smrg fullrange[0].max_char_low = lastcol; 283a96d7823Smrg } 284a96d7823Smrg 285a96d7823Smrg while (count--) 286a96d7823Smrg { 287a96d7823Smrg int row1, col1, row2, col2; 288a96d7823Smrg row1 = row2 = *data++; 289a96d7823Smrg col1 = col2 = *data++; 290a96d7823Smrg if (range_flag) 291a96d7823Smrg { 292a96d7823Smrg if (count) 293a96d7823Smrg { 294a96d7823Smrg row2 = *data++; 295a96d7823Smrg col2 = *data++; 296a96d7823Smrg count--; 297a96d7823Smrg } 298a96d7823Smrg else 299a96d7823Smrg { 300a96d7823Smrg row2 = lastrow; 301a96d7823Smrg col2 = lastcol; 302a96d7823Smrg } 303a96d7823Smrg if (row1 < firstrow) row1 = firstrow; 304a96d7823Smrg if (row2 > lastrow) row2 = lastrow; 305a96d7823Smrg if (col1 < firstcol) col1 = firstcol; 306a96d7823Smrg if (col2 > lastcol) col2 = lastcol; 307a96d7823Smrg } 308a96d7823Smrg else 309a96d7823Smrg { 310a96d7823Smrg if (row1 < firstrow || row1 > lastrow || 311a96d7823Smrg col1 < firstcol || col1 > lastcol) 312a96d7823Smrg continue; 313a96d7823Smrg } 314a96d7823Smrg for (row = row1; row <= row2; row++) 315a96d7823Smrg { 316a96d7823Smrg expand_glyph_range: ; 317a96d7823Smrg loc = (row - firstrow) * (lastcol + 1 - firstcol) + 318a96d7823Smrg (col1 - firstcol); 319a96d7823Smrg for (col = col1; col <= col2; col++, loc++) 320a96d7823Smrg { 321a96d7823Smrg if (GLYPH_UNDEFINED(loc)) 322a96d7823Smrg { 323a96d7823Smrg if (row1 == row2 && 324a96d7823Smrg (((col1 & 0xf) && col1 > firstcol) || 325a96d7823Smrg (col2 & 0xf) != 0xf) && (col2 < lastcol)) 326a96d7823Smrg { 327a96d7823Smrg /* If we're loading from a single row, expand 328a96d7823Smrg range of glyphs loaded to a multiple of 329a96d7823Smrg a 16-glyph range -- attempt to reduce number 330a96d7823Smrg of round trips to the font server. */ 331a96d7823Smrg col1 &= 0xf0; 332a96d7823Smrg col2 = (col2 & 0xf0) + 15; 333a96d7823Smrg if (col1 < firstcol) col1 = firstcol; 334a96d7823Smrg if (col2 > lastcol) col2 = lastcol; 335a96d7823Smrg goto expand_glyph_range; 336a96d7823Smrg } 337a96d7823Smrg range.min_char_low = range.max_char_low = col; 338a96d7823Smrg range.min_char_high = range.max_char_high = row; 339a96d7823Smrg if ((err = add_range(&range, nranges, ranges, FALSE)) != 340a96d7823Smrg Successful) return err; 341a96d7823Smrg encoding[loc].bits = &_fs_glyph_requested; 342a96d7823Smrg access_done = FALSE; 343a96d7823Smrg } 344a96d7823Smrg } 345a96d7823Smrg } 346a96d7823Smrg } 347a96d7823Smrg } 348a96d7823Smrg 349a96d7823Smrg return access_done ? 350a96d7823Smrg AccessDone : 351a96d7823Smrg Successful; 352a96d7823Smrg} 353a96d7823Smrg 354a96d7823Smrg#undef GLYPH_UNDEFINED 355a96d7823Smrg#undef ENCODING_UNDEFINED 356a96d7823Smrg 357a96d7823Smrg 358a96d7823Smrg/* _fs_clean_aborted_loadglyphs(): Undoes the changes to the encoding array 359a96d7823Smrg performed by fs_build_range(); for use if the associated LoadGlyphs 360a96d7823Smrg requests needs to be cancelled. */ 361a96d7823Smrg 362a96d7823Smrgvoid 363a96d7823Smrg_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, 364a96d7823Smrg fsRange *expected_ranges) 365a96d7823Smrg{ 366a96d7823Smrg register FSFontPtr fsfont; 367a96d7823Smrg register int i; 368a96d7823Smrg 369a96d7823Smrg fsfont = (FSFontPtr) pfont->fontPrivate; 370a96d7823Smrg if (fsfont->encoding) 371a96d7823Smrg { 372a96d7823Smrg fsRange full_range[1]; 373a96d7823Smrg if (!num_expected_ranges) 374a96d7823Smrg { 375a96d7823Smrg full_range[0].min_char_low = pfont->info.firstCol; 376a96d7823Smrg full_range[0].min_char_high = pfont->info.firstRow; 377a96d7823Smrg full_range[0].max_char_low = pfont->info.lastCol; 378a96d7823Smrg full_range[0].max_char_high = pfont->info.lastRow; 379a96d7823Smrg num_expected_ranges = 1; 380a96d7823Smrg expected_ranges = full_range; 381a96d7823Smrg } 382a96d7823Smrg 383a96d7823Smrg for (i = 0; i < num_expected_ranges; i++) 384a96d7823Smrg { 385a96d7823Smrg int row, col; 386a96d7823Smrg for (row = expected_ranges[i].min_char_high; 387a96d7823Smrg row <= expected_ranges[i].max_char_high; 388a96d7823Smrg row++) 389a96d7823Smrg { 390a96d7823Smrg register CharInfoPtr encoding = fsfont->encoding + 391a96d7823Smrg ((row - pfont->info.firstRow) * 392a96d7823Smrg (pfont->info.lastCol - 393a96d7823Smrg pfont->info.firstCol + 1) + 394a96d7823Smrg expected_ranges[i].min_char_low - 395a96d7823Smrg pfont->info.firstCol); 396a96d7823Smrg for (col = expected_ranges[i].min_char_low; 397a96d7823Smrg col <= expected_ranges[i].max_char_low; 398a96d7823Smrg encoding++, col++) 399a96d7823Smrg { 400a96d7823Smrg if (encoding->bits == &_fs_glyph_requested) 401a96d7823Smrg encoding->bits = &_fs_glyph_undefined; 402a96d7823Smrg } 403a96d7823Smrg } 404a96d7823Smrg } 405a96d7823Smrg } 406a96d7823Smrg} 407a96d7823Smrg 408a96d7823Smrgstatic int 409a96d7823Smrg_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, 410a96d7823Smrg FontEncoding charEncoding, 411a96d7823Smrg unsigned long *glyphCount, /* RETURN */ 412a96d7823Smrg CharInfoPtr *glyphs) /* RETURN */ 413a96d7823Smrg{ 414a96d7823Smrg FSFontPtr fsdata; 415a96d7823Smrg unsigned int firstCol; 416a96d7823Smrg register unsigned int numCols; 417a96d7823Smrg unsigned int firstRow; 418a96d7823Smrg unsigned int numRows; 419a96d7823Smrg CharInfoPtr *glyphsBase; 420a96d7823Smrg register unsigned int c; 421a96d7823Smrg register CharInfoPtr pci; 422a96d7823Smrg unsigned int r; 423a96d7823Smrg CharInfoPtr encoding; 424a96d7823Smrg CharInfoPtr pDefault; 425a96d7823Smrg FSFontDataPtr fsd = (FSFontDataPtr) pFont->fpePrivate; 426a96d7823Smrg int err = Successful; 427a96d7823Smrg 428a96d7823Smrg fsdata = (FSFontPtr) pFont->fontPrivate; 429a96d7823Smrg encoding = fsdata->encoding; 430a96d7823Smrg pDefault = fsdata->pDefault; 431a96d7823Smrg firstCol = pFont->info.firstCol; 432a96d7823Smrg numCols = pFont->info.lastCol - firstCol + 1; 433a96d7823Smrg glyphsBase = glyphs; 434a96d7823Smrg 435a96d7823Smrg /* In this age of glyph caching, any glyphs gotten through this 436a96d7823Smrg procedure should already be loaded. If they are not, we are 437a96d7823Smrg dealing with someone (perhaps a ddx driver optimizing a font) 438a96d7823Smrg that doesn't understand the finer points of glyph caching. The 439a96d7823Smrg CHECK_ENCODING macro checks for this condition... if found, it 440a96d7823Smrg calls fs_load_all_glyphs(), which corrects it. Since the caller 441a96d7823Smrg of this code will not know how to handle a return value of 442a96d7823Smrg Suspended, the fs_load_all_glyphs() procedure will block and 443a96d7823Smrg freeze the server until the load operation is done. Moral: the 444a96d7823Smrg glyphCachingMode flag really must indicate the capabilities of 445a96d7823Smrg the ddx drivers. */ 446a96d7823Smrg 447a96d7823Smrg#define CHECK_ENCODING(cnum) \ 448a96d7823Smrg ( pci = encoding + (cnum), \ 449a96d7823Smrg fsd->glyphs_to_get ? \ 450a96d7823Smrg ( pci->bits == &_fs_glyph_undefined || pci->bits == &_fs_glyph_requested ? \ 451a96d7823Smrg ((err = fs_load_all_glyphs(pFont)), pci) : \ 452a96d7823Smrg pci ) : \ 453a96d7823Smrg pci ) 454a96d7823Smrg 455a96d7823Smrg switch (charEncoding) { 456a96d7823Smrg 457a96d7823Smrg case Linear8Bit: 458a96d7823Smrg case TwoD8Bit: 459a96d7823Smrg if (pFont->info.firstRow > 0) 460a96d7823Smrg break; 461a96d7823Smrg if (pFont->info.allExist && pDefault) { 462a96d7823Smrg while (err == Successful && count--) { 463a96d7823Smrg c = (*chars++) - firstCol; 464a96d7823Smrg if (c < numCols) 465a96d7823Smrg *glyphs++ = CHECK_ENCODING(c); 466a96d7823Smrg else 467a96d7823Smrg *glyphs++ = pDefault; 468a96d7823Smrg } 469a96d7823Smrg } else { 470a96d7823Smrg while (err == Successful && count--) { 471a96d7823Smrg c = (*chars++) - firstCol; 472a96d7823Smrg if (c < numCols && CHECK_ENCODING(c)->bits) 473a96d7823Smrg *glyphs++ = pci; 474a96d7823Smrg else if (pDefault) 475a96d7823Smrg *glyphs++ = pDefault; 476a96d7823Smrg } 477a96d7823Smrg } 478a96d7823Smrg break; 479a96d7823Smrg case Linear16Bit: 480a96d7823Smrg if (pFont->info.allExist && pDefault) { 481a96d7823Smrg while (err == Successful && count--) { 482a96d7823Smrg c = *chars++ << 8; 483a96d7823Smrg c = (c | *chars++) - firstCol; 484a96d7823Smrg if (c < numCols) 485a96d7823Smrg *glyphs++ = CHECK_ENCODING(c); 486a96d7823Smrg else 487a96d7823Smrg *glyphs++ = pDefault; 488a96d7823Smrg } 489a96d7823Smrg } else { 490a96d7823Smrg while (err == Successful && count--) { 491a96d7823Smrg c = *chars++ << 8; 492a96d7823Smrg c = (c | *chars++) - firstCol; 493a96d7823Smrg if (c < numCols && CHECK_ENCODING(c)->bits) 494a96d7823Smrg *glyphs++ = pci; 495a96d7823Smrg else if (pDefault) 496a96d7823Smrg *glyphs++ = pDefault; 497a96d7823Smrg } 498a96d7823Smrg } 499a96d7823Smrg break; 500a96d7823Smrg 501a96d7823Smrg case TwoD16Bit: 502a96d7823Smrg firstRow = pFont->info.firstRow; 503a96d7823Smrg numRows = pFont->info.lastRow - firstRow + 1; 504a96d7823Smrg while (err == Successful && count--) { 505a96d7823Smrg r = (*chars++) - firstRow; 506a96d7823Smrg c = (*chars++) - firstCol; 507a96d7823Smrg if (r < numRows && c < numCols && 508a96d7823Smrg CHECK_ENCODING(r * numCols + c)->bits) 509a96d7823Smrg *glyphs++ = pci; 510a96d7823Smrg else if (pDefault) 511a96d7823Smrg *glyphs++ = pDefault; 512a96d7823Smrg } 513a96d7823Smrg break; 514a96d7823Smrg } 515a96d7823Smrg *glyphCount = glyphs - glyphsBase; 516a96d7823Smrg return err; 517a96d7823Smrg} 518a96d7823Smrg 519a96d7823Smrg 520a96d7823Smrgstatic int 521a96d7823Smrg_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars, 522a96d7823Smrg FontEncoding charEncoding, 523a96d7823Smrg unsigned long *glyphCount, /* RETURN */ 524a96d7823Smrg xCharInfo **glyphs) /* RETURN */ 525a96d7823Smrg{ 526a96d7823Smrg FSFontPtr fsdata; 527a96d7823Smrg unsigned int firstCol; 528a96d7823Smrg register unsigned int numCols; 529a96d7823Smrg unsigned int firstRow; 530a96d7823Smrg unsigned int numRows; 531a96d7823Smrg xCharInfo **glyphsBase; 532a96d7823Smrg register unsigned int c; 533a96d7823Smrg unsigned int r; 534a96d7823Smrg CharInfoPtr encoding; 535a96d7823Smrg CharInfoPtr pDefault; 536a96d7823Smrg 537a96d7823Smrg fsdata = (FSFontPtr) pFont->fontPrivate; 538a96d7823Smrg encoding = fsdata->inkMetrics; 539a96d7823Smrg pDefault = fsdata->pDefault; 540a96d7823Smrg /* convert default bitmap metric to default ink metric */ 541a96d7823Smrg if (pDefault) 542a96d7823Smrg pDefault = encoding + (pDefault - fsdata->encoding); 543a96d7823Smrg firstCol = pFont->info.firstCol; 544a96d7823Smrg numCols = pFont->info.lastCol - firstCol + 1; 545a96d7823Smrg glyphsBase = glyphs; 546a96d7823Smrg 547a96d7823Smrg 548a96d7823Smrg /* XXX - this should be much smarter */ 549a96d7823Smrg /* make sure the glyphs are there */ 550a96d7823Smrg switch (charEncoding) { 551a96d7823Smrg 552a96d7823Smrg case Linear8Bit: 553a96d7823Smrg case TwoD8Bit: 554a96d7823Smrg if (pFont->info.firstRow > 0) 555a96d7823Smrg break; 556a96d7823Smrg if (pFont->info.allExist && pDefault) { 557a96d7823Smrg while (count--) { 558a96d7823Smrg c = (*chars++) - firstCol; 559a96d7823Smrg if (c < numCols) 560a96d7823Smrg *glyphs++ = (xCharInfo *)&encoding[c]; 561a96d7823Smrg else 562a96d7823Smrg *glyphs++ = (xCharInfo *)pDefault; 563a96d7823Smrg } 564a96d7823Smrg } else { 565a96d7823Smrg while (count--) { 566a96d7823Smrg c = (*chars++) - firstCol; 567a96d7823Smrg if (c < numCols) 568a96d7823Smrg *glyphs++ = (xCharInfo *)(encoding + c); 569a96d7823Smrg else if (pDefault) 570a96d7823Smrg *glyphs++ = (xCharInfo *)pDefault; 571a96d7823Smrg } 572a96d7823Smrg } 573a96d7823Smrg break; 574a96d7823Smrg case Linear16Bit: 575a96d7823Smrg if (pFont->info.allExist && pDefault) { 576a96d7823Smrg while (count--) { 577a96d7823Smrg c = *chars++ << 8; 578a96d7823Smrg c = (c | *chars++) - firstCol; 579a96d7823Smrg if (c < numCols) 580a96d7823Smrg *glyphs++ = (xCharInfo *)(encoding + c); 581a96d7823Smrg else 582a96d7823Smrg *glyphs++ = (xCharInfo *)pDefault; 583a96d7823Smrg } 584a96d7823Smrg } else { 585a96d7823Smrg while (count--) { 586a96d7823Smrg c = *chars++ << 8; 587a96d7823Smrg c = (c | *chars++) - firstCol; 588a96d7823Smrg if (c < numCols) 589a96d7823Smrg *glyphs++ = (xCharInfo *)(encoding + c); 590a96d7823Smrg else if (pDefault) 591a96d7823Smrg *glyphs++ = (xCharInfo *)pDefault; 592a96d7823Smrg } 593a96d7823Smrg } 594a96d7823Smrg break; 595a96d7823Smrg 596a96d7823Smrg case TwoD16Bit: 597a96d7823Smrg firstRow = pFont->info.firstRow; 598a96d7823Smrg numRows = pFont->info.lastRow - firstRow + 1; 599a96d7823Smrg while (count--) { 600a96d7823Smrg r = (*chars++) - firstRow; 601a96d7823Smrg c = (*chars++) - firstCol; 602a96d7823Smrg if (r < numRows && c < numCols) 603a96d7823Smrg *glyphs++ = (xCharInfo *)(encoding + (r * numCols + c)); 604a96d7823Smrg else if (pDefault) 605a96d7823Smrg *glyphs++ = (xCharInfo *)pDefault; 606a96d7823Smrg } 607a96d7823Smrg break; 608a96d7823Smrg } 609a96d7823Smrg *glyphCount = glyphs - glyphsBase; 610a96d7823Smrg return Successful; 611a96d7823Smrg} 612a96d7823Smrg 613a96d7823Smrg 614a96d7823Smrgstatic void 615a96d7823Smrg_fs_unload_font(FontPtr pfont) 616a96d7823Smrg{ 617a96d7823Smrg FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate; 618a96d7823Smrg FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate; 619a96d7823Smrg CharInfoPtr encoding = fsdata->encoding; 620a96d7823Smrg FSGlyphPtr glyphs; 621a96d7823Smrg 622a96d7823Smrg /* 623a96d7823Smrg * fsdata points at FSFontRec, FSFontDataRec and name 624a96d7823Smrg */ 625a96d7823Smrg if (encoding) 626a96d7823Smrg free(encoding); 627a96d7823Smrg 628a96d7823Smrg while ((glyphs = fsdata->glyphs)) 629a96d7823Smrg { 630a96d7823Smrg fsdata->glyphs = glyphs->next; 631a96d7823Smrg free (glyphs); 632a96d7823Smrg } 633a96d7823Smrg 634a96d7823Smrg /* XXX we may get called after the resource DB has been cleaned out */ 635a96d7823Smrg if (find_old_font(fsd->fontid)) 636a96d7823Smrg DeleteFontClientID (fsd->fontid); 637a96d7823Smrg 638a96d7823Smrg _fs_free_props (&pfont->info); 639a96d7823Smrg 640a96d7823Smrg free(fsdata); 641a96d7823Smrg 642a96d7823Smrg DestroyFontRec(pfont); 643a96d7823Smrg} 644a96d7823Smrg 645a96d7823SmrgFontPtr 646a96d7823Smrgfs_create_font (FontPathElementPtr fpe, 647a96d7823Smrg const char *name, 648a96d7823Smrg int namelen, 649a96d7823Smrg fsBitmapFormat format, 650a96d7823Smrg fsBitmapFormatMask fmask) 651a96d7823Smrg{ 652a96d7823Smrg FontPtr pfont; 653a96d7823Smrg FSFontPtr fsfont; 654a96d7823Smrg FSFontDataPtr fsd; 655a96d7823Smrg int bit, byte, scan, glyph; 656a96d7823Smrg 657a96d7823Smrg pfont = CreateFontRec (); 658a96d7823Smrg if (!pfont) 659a96d7823Smrg return 0; 660a96d7823Smrg fsfont = malloc (sizeof (FSFontRec) + sizeof (FSFontDataRec) + namelen + 1); 661a96d7823Smrg if (!fsfont) 662a96d7823Smrg { 663a96d7823Smrg DestroyFontRec (pfont); 664a96d7823Smrg return 0; 665a96d7823Smrg } 666a96d7823Smrg fsd = (FSFontDataPtr) (fsfont + 1); 667a96d7823Smrg bzero((char *) fsfont, sizeof(FSFontRec)); 668a96d7823Smrg bzero((char *) fsd, sizeof(FSFontDataRec)); 669a96d7823Smrg 670a96d7823Smrg pfont->fpe = fpe; 671a96d7823Smrg pfont->fontPrivate = (pointer) fsfont; 672a96d7823Smrg pfont->fpePrivate = (pointer) fsd; 673a96d7823Smrg 674a96d7823Smrg /* These font components will be needed in packGlyphs */ 675a96d7823Smrg CheckFSFormat(format, BitmapFormatMaskBit | 676a96d7823Smrg BitmapFormatMaskByte | 677a96d7823Smrg BitmapFormatMaskScanLineUnit | 678a96d7823Smrg BitmapFormatMaskScanLinePad, 679a96d7823Smrg &bit, 680a96d7823Smrg &byte, 681a96d7823Smrg &scan, 682a96d7823Smrg &glyph, 683a96d7823Smrg NULL); 684a96d7823Smrg pfont->format = format; 685a96d7823Smrg pfont->bit = bit; 686a96d7823Smrg pfont->byte = byte; 687a96d7823Smrg pfont->scan = scan; 688a96d7823Smrg pfont->glyph = glyph; 689a96d7823Smrg 690a96d7823Smrg pfont->info.nprops = 0; 691a96d7823Smrg pfont->info.props = 0; 692a96d7823Smrg pfont->info.isStringProp = 0; 693a96d7823Smrg 694a96d7823Smrg /* set font function pointers */ 695a96d7823Smrg pfont->get_glyphs = _fs_get_glyphs; 696a96d7823Smrg pfont->get_metrics = _fs_get_metrics; 697a96d7823Smrg pfont->unload_font = _fs_unload_font; 698a96d7823Smrg pfont->unload_glyphs = NULL; 699a96d7823Smrg 700a96d7823Smrg /* set the FPE private information */ 701a96d7823Smrg fsd->format = format; 702a96d7823Smrg fsd->fmask = fmask; 703a96d7823Smrg fsd->name = (char *) (fsd + 1); 704a96d7823Smrg memcpy (fsd->name, name, namelen); 705a96d7823Smrg fsd->name[namelen] = '\0'; 706a96d7823Smrg fsd->fontid = GetNewFontClientID (); 707a96d7823Smrg 708a96d7823Smrg /* save the ID */ 709a96d7823Smrg if (!StoreFontClientFont(pfont, fsd->fontid)) 710a96d7823Smrg { 711a96d7823Smrg free (fsfont); 712a96d7823Smrg DestroyFontRec (pfont); 713a96d7823Smrg return 0; 714a96d7823Smrg } 715a96d7823Smrg 716a96d7823Smrg return pfont; 717a96d7823Smrg} 718a96d7823Smrg 719a96d7823Smrgpointer 720a96d7823Smrgfs_alloc_glyphs (FontPtr pFont, int size) 721a96d7823Smrg{ 722a96d7823Smrg FSGlyphPtr glyphs; 723a96d7823Smrg FSFontPtr fsfont = (FSFontPtr) pFont->fontPrivate; 724a96d7823Smrg 725a96d7823Smrg if (size < (INT_MAX - sizeof (FSGlyphRec))) 726a96d7823Smrg glyphs = malloc (sizeof (FSGlyphRec) + size); 727a96d7823Smrg else 728a96d7823Smrg glyphs = NULL; 729a96d7823Smrg if (glyphs == NULL) 730a96d7823Smrg return NULL; 731a96d7823Smrg glyphs->next = fsfont->glyphs; 732a96d7823Smrg fsfont->glyphs = glyphs; 733a96d7823Smrg return (pointer) (glyphs + 1); 734a96d7823Smrg} 735