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