📄 dixfonts.c
字号:
/************************************************************************Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights ReservedPermission to use, copy, modify, and distribute this software and itsdocumentation for any purpose and without fee is hereby granted,provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear insupporting documentation, and that the name of Digital not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission.DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THISSOFTWARE.************************************************************************//* $XConsortium: dixfonts.c /main/58 1996/09/28 17:11:55 rws $ *//* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.6 1996/12/23 06:29:40 dawes Exp $ */#define NEED_REPLIES#include "X.h"#include "Xmd.h"#include "Xproto.h"#include "scrnintstr.h"#include "resource.h"#include "dixstruct.h"#include "cursorstr.h"#include "misc.h"#include "opaque.h"#include "dixfontstr.h"#include "closestr.h"#ifdef DEBUG#include <stdio.h>#endif#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metricsstatic Mask FontFormat = #if IMAGE_BYTE_ORDER == LSBFirst BitmapFormatByteOrderLSB |#else BitmapFormatByteOrderMSB |#endif#if BITMAP_BIT_ORDER == LSBFirst BitmapFormatBitOrderLSB |#else BitmapFormatBitOrderMSB |#endif BitmapFormatImageRectMin |#if GLYPHPADBYTES == 1 BitmapFormatScanlinePad8 |#endif#if GLYPHPADBYTES == 2 BitmapFormatScanlinePad16 |#endif#if GLYPHPADBYTES == 4 BitmapFormatScanlinePad32 |#endif#if GLYPHPADBYTES == 8 BitmapFormatScanlinePad64 |#endif BitmapFormatScanlineUnit8;extern pointer fosNaturalParams;extern FontPtr defaultFont;static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;static int num_fpes = 0;static FPEFunctions *fpe_functions = (FPEFunctions *) 0;static int num_fpe_types = 0;static unsigned char *font_path_string;static int num_slept_fpes = 0;static int size_slept_fpes = 0;static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;static FontPatternCachePtr patternCache;intFontToXError(err) int err;{ switch (err) { case Successful: return Success; case AllocError: return BadAlloc; case BadFontName: case BadFontPath: return BadName; case BadFontFormat: /* is there something better? */ case BadCharRange: return BadValue; default: return err; }}/* * adding RT_FONT prevents conflict with default cursor font */BoolSetDefaultFont(defaultfontname) char *defaultfontname;{ int err; FontPtr pf; XID fid; fid = FakeClientID(0); err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync, (unsigned) strlen(defaultfontname), defaultfontname); if (err != Success) return FALSE; pf = (FontPtr) LookupIDByType(fid, RT_FONT); if (pf == (FontPtr) NULL) return FALSE; defaultFont = pf; return TRUE;}/* * note that the font wakeup queue is not refcounted. this is because * an fpe needs to be added when it's inited, and removed when it's finally * freed, in order to handle any data that isn't requested, like FS events. * * since the only thing that should call these routines is the renderer's * init_fpe() and free_fpe(), there shouldn't be any problem in using * freed data. */voidQueueFontWakeup(fpe) FontPathElementPtr fpe;{ int i; FontPathElementPtr *new; for (i = 0; i < num_slept_fpes; i++) { if (slept_fpes[i] == fpe) {#ifdef DEBUG fprintf(stderr, "re-queueing fpe wakeup\n");#endif return; } } if (num_slept_fpes == size_slept_fpes) { new = (FontPathElementPtr *) xrealloc(slept_fpes, sizeof(FontPathElementPtr) * (size_slept_fpes + 4)); if (!new) return; slept_fpes = new; size_slept_fpes += 4; } slept_fpes[num_slept_fpes] = fpe; num_slept_fpes++;}voidRemoveFontWakeup(fpe) FontPathElementPtr fpe;{ int i, j; for (i = 0; i < num_slept_fpes; i++) { if (slept_fpes[i] == fpe) { for (j = i; j < num_slept_fpes; j++) { slept_fpes[j] = slept_fpes[j + 1]; } num_slept_fpes--; return; } }}/* ARGSUSED */voidFontWakeup(data, count, LastSelectMask) pointer data; int count; pointer LastSelectMask;{ int i; FontPathElementPtr fpe; if (count < 0) return; /* wake up any fpe's that may be waiting for information */ for (i = 0; i < num_slept_fpes; i++) { fpe = slept_fpes[i]; (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask); }}/* XXX -- these two funcs may want to be broken into macros */static void#if NeedFunctionPrototypesUseFPE(FontPathElementPtr fpe)#elseUseFPE(fpe) FontPathElementPtr fpe;#endif{ fpe->refcount++;}static void#if NeedFunctionPrototypesFreeFPE (FontPathElementPtr fpe)#elseFreeFPE (fpe) FontPathElementPtr fpe;#endif{ fpe->refcount--; if (fpe->refcount == 0) { (*fpe_functions[fpe->type].free_fpe) (fpe); xfree(fpe->name); xfree(fpe); }}static Bool#if NeedFunctionPrototypesdoOpenFont(ClientPtr client, OFclosurePtr c)#elsedoOpenFont(client, c) ClientPtr client; OFclosurePtr c;#endif{ FontPtr pfont = NullFont; FontPathElementPtr fpe; ScreenPtr pScr; int err = Successful; int i; char *alias, *newname; int newlen; int aliascount = 20; if (client->clientGone) { if (c->current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current_fpe]; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); } err = Successful; goto bail; } while (c->current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current_fpe]; err = (*fpe_functions[fpe->type].open_font) ((pointer) client, fpe, c->flags, c->fontname, c->fnamelen, FontFormat, BitmapFormatMaskByte | BitmapFormatMaskBit | BitmapFormatMaskImageRectangle | BitmapFormatMaskScanLinePad | BitmapFormatMaskScanLineUnit, c->fontid, &pfont, &alias, c->non_cachable_font && c->non_cachable_font->fpe == fpe ? c->non_cachable_font : (FontPtr)0); if (err == FontNameAlias && alias) { newlen = strlen(alias); newname = (char *) xrealloc(c->fontname, newlen); if (!newname) { err = AllocError; break; } memmove(newname, alias, newlen); c->fontname = newname; c->fnamelen = newlen; c->current_fpe = 0; if (--aliascount <= 0) break; continue; } if (err == BadFontName) { c->current_fpe++; continue; } if (err == Suspended) { if (!c->slept) { c->slept = TRUE; ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c); } return TRUE; } break; } if (err != Successful) goto bail; if (!pfont) { err = BadFontName; goto bail; } if (!pfont->fpe) pfont->fpe = fpe; pfont->refcnt++; if (pfont->refcnt == 1) { UseFPE(pfont->fpe); for (i = 0; i < screenInfo.numScreens; i++) { pScr = screenInfo.screens[i]; if (pScr->RealizeFont) { if (!(*pScr->RealizeFont) (pScr, pfont)) { CloseFont (pfont, (Font) 0); err = AllocError; goto bail; } } } } if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) { err = AllocError; goto bail; } if (patternCache && pfont != c->non_cachable_font) CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen, pfont);bail: if (err != Successful && c->client != serverClient) { SendErrorToClient(c->client, X_OpenFont, 0, c->fontid, FontToXError(err)); } if (c->slept) ClientWakeup(c->client); for (i = 0; i < c->num_fpes; i++) { FreeFPE(c->fpe_list[i]); } xfree(c->fpe_list); xfree(c->fontname); xfree(c); return TRUE;}intOpenFont(client, fid, flags, lenfname, pfontname) ClientPtr client; XID fid; Mask flags; unsigned lenfname; char *pfontname;{ OFclosurePtr c; int i; FontPtr cached = (FontPtr)0;#ifdef FONTDEBUG char *f; f = (char *)xalloc(lenfname + 1); memmove(f, pfontname, lenfname); f[lenfname] = '\0'; ErrorF("OpenFont: fontname is \"%s\"\n", f); xfree(f);#endif if (!lenfname) return BadName; if (patternCache) { /* ** Check name cache. If we find a cached version of this font that ** is cachable, immediately satisfy the request with it. If we find ** a cached version of this font that is non-cachable, we do not ** satisfy the request with it. Instead, we pass the FontPtr to the ** FPE's open_font code (the fontfile FPE in turn passes the ** information to the rasterizer; the fserve FPE ignores it). ** ** Presumably, the font is marked non-cachable because the FPE has ** put some licensing restrictions on it. If the FPE, using ** whatever logic it relies on, determines that it is willing to ** share this existing font with the client, then it has the option ** to return the FontPtr we passed it as the newly-opened font. ** This allows the FPE to exercise its licensing logic without ** having to create another instance of a font that already exists. */ cached = FindCachedFontPattern(patternCache, pfontname, lenfname); if (cached && cached->info.cachable) { if (!AddResource(fid, RT_FONT, (pointer) cached)) return BadAlloc; cached->refcnt++; return Success; } } c = (OFclosurePtr) xalloc(sizeof(OFclosureRec)); if (!c) return BadAlloc; c->fontname = (char *) xalloc(lenfname); c->origFontName = pfontname; c->origFontNameLen = lenfname; if (!c->fontname) { xfree(c); return BadAlloc; } /* * copy the current FPE list, so that if it gets changed by another client * while we're blocking, the request still appears atomic */ c->fpe_list = (FontPathElementPtr *) xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c->fontname); xfree(c); return BadAlloc; } memmove(c->fontname, pfontname, lenfname); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->fontid = fid; c->current_fpe = 0; c->num_fpes = num_fpes; c->fnamelen = lenfname; c->slept = FALSE; c->flags = flags; c->non_cachable_font = cached; (void) doOpenFont(client, c); return Success;}/* * Decrement font's ref count, and free storage if ref count equals zero *//*ARGSUSED*/intCloseFont(value, fid) pointer value; /* must conform to DeleteType */ XID fid;{ int nscr; ScreenPtr pscr; FontPathElementPtr fpe; FontPtr pfont = (FontPtr)value; if (pfont == NullFont) return (Success); if (--pfont->refcnt == 0) { if (patternCache && pfont->info.cachable) RemoveCachedFontPattern (patternCache, pfont); /* * since the last reference is gone, ask each screen to free any * storage it may have allocated locally for it. */ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; if (pscr->UnrealizeFont) (*pscr->UnrealizeFont) (pscr, pfont); } if (pfont == defaultFont) defaultFont = NULL;#ifdef LBX LbxFreeFontTag(pfont);#endif fpe = pfont->fpe; (*fpe_functions[fpe->type].close_font) (fpe, pfont); FreeFPE(fpe); } return (Success);}/***====================================================================***/ /* * \ Sets up pReply as the correct QueryFontReply for pFont with the first * nProtoCCIStructs char infos. \ */voidQueryFont(pFont, pReply, nProtoCCIStructs) FontPtr pFont; xQueryFontReply *pReply; /* caller must allocate this storage */ int nProtoCCIStructs;{ FontPropPtr pFP; int r, c, i; xFontProp *prFP; xCharInfo *prCI; xCharInfo *charInfos[256]; unsigned char chars[512]; int ninfos; unsigned long ncols; unsigned long count; /* pr->length set in dispatch */ pReply->minCharOrByte2 = pFont->info.firstCol; pReply->defaultChar = pFont->info.defaultCh; pReply->maxCharOrByte2 = pFont->info.lastCol; pReply->drawDirection = pFont->info.drawDirection; pReply->allCharsExist = pFont->info.allExist; pReply->minByte1 = pFont->info.firstRow; pReply->maxByte1 = pFont->info.lastRow; pReply->fontAscent = pFont->info.fontAscent; pReply->fontDescent = pFont->info.fontDescent; pReply->minBounds = pFont->info.ink_minbounds; pReply->maxBounds = pFont->info.ink_maxbounds; pReply->nFontProps = pFont->info.nprops; pReply->nCharInfos = nProtoCCIStructs; for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]); i < pFont->info.nprops; i++, pFP++, prFP++) { prFP->name = pFP->name; prFP->value = pFP->value; } ninfos = 0; ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1); prCI = (xCharInfo *) (prFP); for (r = pFont->info.firstRow; ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow; r++) { i = 0; for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) { chars[i++] = r; chars[i++] = c; } (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit, &count, charInfos); i = 0; for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) { *prCI = *charInfos[i]; prCI++; ninfos++; } } return;}static Bool#if NeedFunctionPrototypesdoListFontsAndAliases(ClientPtr client, LFclosurePtr c)#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -