glyph.c revision 4202a189
105b261ecSmrg/* 205b261ecSmrg * 305b261ecSmrg * Copyright © 2000 SuSE, Inc. 405b261ecSmrg * 505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 705b261ecSmrg * the above copyright notice appear in all copies and that both that 805b261ecSmrg * copyright notice and this permission notice appear in supporting 905b261ecSmrg * documentation, and that the name of SuSE not be used in advertising or 1005b261ecSmrg * publicity pertaining to distribution of the software without specific, 1105b261ecSmrg * written prior permission. SuSE makes no representations about the 1205b261ecSmrg * suitability of this software for any purpose. It is provided "as is" 1305b261ecSmrg * without express or implied warranty. 1405b261ecSmrg * 1505b261ecSmrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 1605b261ecSmrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 1705b261ecSmrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1805b261ecSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1905b261ecSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 2005b261ecSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg * 2205b261ecSmrg * Author: Keith Packard, SuSE, Inc. 2305b261ecSmrg */ 2405b261ecSmrg 2505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2605b261ecSmrg#include <dix-config.h> 2705b261ecSmrg#endif 2805b261ecSmrg 294202a189Smrg#include "xsha1.h" 304642e01fSmrg 3105b261ecSmrg#include "misc.h" 3205b261ecSmrg#include "scrnintstr.h" 3305b261ecSmrg#include "os.h" 3405b261ecSmrg#include "regionstr.h" 3505b261ecSmrg#include "validate.h" 3605b261ecSmrg#include "windowstr.h" 3705b261ecSmrg#include "input.h" 3805b261ecSmrg#include "resource.h" 3905b261ecSmrg#include "colormapst.h" 4005b261ecSmrg#include "cursorstr.h" 4105b261ecSmrg#include "dixstruct.h" 4205b261ecSmrg#include "gcstruct.h" 4305b261ecSmrg#include "servermd.h" 4405b261ecSmrg#include "picturestr.h" 4505b261ecSmrg#include "glyphstr.h" 464642e01fSmrg#include "mipict.h" 4705b261ecSmrg 4805b261ecSmrg/* 4905b261ecSmrg * From Knuth -- a good choice for hash/rehash values is p, p-2 where 5005b261ecSmrg * p and p-2 are both prime. These tables are sized to have an extra 10% 5105b261ecSmrg * free to avoid exponential performance degradation as the hash table fills 5205b261ecSmrg */ 5305b261ecSmrgstatic GlyphHashSetRec glyphHashSets[] = { 5405b261ecSmrg { 32, 43, 41 }, 5505b261ecSmrg { 64, 73, 71 }, 5605b261ecSmrg { 128, 151, 149 }, 5705b261ecSmrg { 256, 283, 281 }, 5805b261ecSmrg { 512, 571, 569 }, 5905b261ecSmrg { 1024, 1153, 1151 }, 6005b261ecSmrg { 2048, 2269, 2267 }, 6105b261ecSmrg { 4096, 4519, 4517 }, 6205b261ecSmrg { 8192, 9013, 9011 }, 6305b261ecSmrg { 16384, 18043, 18041 }, 6405b261ecSmrg { 32768, 36109, 36107 }, 6505b261ecSmrg { 65536, 72091, 72089 }, 6605b261ecSmrg { 131072, 144409, 144407 }, 6705b261ecSmrg { 262144, 288361, 288359 }, 6805b261ecSmrg { 524288, 576883, 576881 }, 6905b261ecSmrg { 1048576, 1153459, 1153457 }, 7005b261ecSmrg { 2097152, 2307163, 2307161 }, 7105b261ecSmrg { 4194304, 4613893, 4613891 }, 7205b261ecSmrg { 8388608, 9227641, 9227639 }, 7305b261ecSmrg { 16777216, 18455029, 18455027 }, 7405b261ecSmrg { 33554432, 36911011, 36911009 }, 7505b261ecSmrg { 67108864, 73819861, 73819859 }, 7605b261ecSmrg { 134217728, 147639589, 147639587 }, 7705b261ecSmrg { 268435456, 295279081, 295279079 }, 7805b261ecSmrg { 536870912, 590559793, 590559791 } 7905b261ecSmrg}; 8005b261ecSmrg 8105b261ecSmrg#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0])) 8205b261ecSmrg 8305b261ecSmrgstatic const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 }; 8405b261ecSmrg 8505b261ecSmrgstatic GlyphHashRec globalGlyphs[GlyphFormatNum]; 8605b261ecSmrg 8705b261ecSmrgvoid 8805b261ecSmrgGlyphUninit (ScreenPtr pScreen) 8905b261ecSmrg{ 9005b261ecSmrg PictureScreenPtr ps = GetPictureScreen (pScreen); 9105b261ecSmrg GlyphPtr glyph; 9205b261ecSmrg int fdepth, i; 934202a189Smrg int scrno = pScreen->myNum; 9405b261ecSmrg 9505b261ecSmrg for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) 9605b261ecSmrg { 9705b261ecSmrg if (!globalGlyphs[fdepth].hashSet) 9805b261ecSmrg continue; 9905b261ecSmrg 10005b261ecSmrg for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) 10105b261ecSmrg { 10205b261ecSmrg glyph = globalGlyphs[fdepth].table[i].glyph; 10305b261ecSmrg if (glyph && glyph != DeletedGlyph) 10405b261ecSmrg { 1054202a189Smrg if (GlyphPicture(glyph)[scrno]) 1064202a189Smrg { 1074202a189Smrg FreePicture ((pointer) GlyphPicture (glyph)[scrno], 0); 1084202a189Smrg GlyphPicture(glyph)[scrno] = NULL; 1094202a189Smrg } 11005b261ecSmrg (*ps->UnrealizeGlyph) (pScreen, glyph); 11105b261ecSmrg } 11205b261ecSmrg } 11305b261ecSmrg } 11405b261ecSmrg} 11505b261ecSmrg 11605b261ecSmrgGlyphHashSetPtr 11705b261ecSmrgFindGlyphHashSet (CARD32 filled) 11805b261ecSmrg{ 11905b261ecSmrg int i; 12005b261ecSmrg 12105b261ecSmrg for (i = 0; i < NGLYPHHASHSETS; i++) 12205b261ecSmrg if (glyphHashSets[i].entries >= filled) 12305b261ecSmrg return &glyphHashSets[i]; 12405b261ecSmrg return 0; 12505b261ecSmrg} 12605b261ecSmrg 12705b261ecSmrgGlyphRefPtr 1284642e01fSmrgFindGlyphRef (GlyphHashPtr hash, 1294642e01fSmrg CARD32 signature, 1304642e01fSmrg Bool match, 1314642e01fSmrg unsigned char sha1[20]) 13205b261ecSmrg{ 13305b261ecSmrg CARD32 elt, step, s; 13405b261ecSmrg GlyphPtr glyph; 13505b261ecSmrg GlyphRefPtr table, gr, del; 13605b261ecSmrg CARD32 tableSize = hash->hashSet->size; 13705b261ecSmrg 13805b261ecSmrg table = hash->table; 13905b261ecSmrg elt = signature % tableSize; 14005b261ecSmrg step = 0; 14105b261ecSmrg del = 0; 14205b261ecSmrg for (;;) 14305b261ecSmrg { 14405b261ecSmrg gr = &table[elt]; 14505b261ecSmrg s = gr->signature; 14605b261ecSmrg glyph = gr->glyph; 14705b261ecSmrg if (!glyph) 14805b261ecSmrg { 14905b261ecSmrg if (del) 15005b261ecSmrg gr = del; 15105b261ecSmrg break; 15205b261ecSmrg } 15305b261ecSmrg if (glyph == DeletedGlyph) 15405b261ecSmrg { 15505b261ecSmrg if (!del) 15605b261ecSmrg del = gr; 15705b261ecSmrg else if (gr == del) 15805b261ecSmrg break; 15905b261ecSmrg } 16005b261ecSmrg else if (s == signature && 16105b261ecSmrg (!match || 1624642e01fSmrg memcmp (glyph->sha1, sha1, 20) == 0)) 16305b261ecSmrg { 16405b261ecSmrg break; 16505b261ecSmrg } 16605b261ecSmrg if (!step) 16705b261ecSmrg { 16805b261ecSmrg step = signature % hash->hashSet->rehash; 16905b261ecSmrg if (!step) 17005b261ecSmrg step = 1; 17105b261ecSmrg } 17205b261ecSmrg elt += step; 17305b261ecSmrg if (elt >= tableSize) 17405b261ecSmrg elt -= tableSize; 17505b261ecSmrg } 17605b261ecSmrg return gr; 17705b261ecSmrg} 17805b261ecSmrg 1794642e01fSmrgint 1804642e01fSmrgHashGlyph (xGlyphInfo *gi, 1814642e01fSmrg CARD8 *bits, 1824642e01fSmrg unsigned long size, 1834642e01fSmrg unsigned char sha1[20]) 18405b261ecSmrg{ 1854202a189Smrg void *ctx = x_sha1_init(); 1864642e01fSmrg int success; 1874642e01fSmrg 1884202a189Smrg if (!ctx) 1894642e01fSmrg return BadAlloc; 1904642e01fSmrg 1914202a189Smrg success = x_sha1_update(ctx, gi, sizeof(xGlyphInfo)); 1924202a189Smrg if (!success) 1934642e01fSmrg return BadAlloc; 1944202a189Smrg success = x_sha1_update(ctx, bits, size); 1954202a189Smrg if (!success) 1964642e01fSmrg return BadAlloc; 1974202a189Smrg success = x_sha1_final(ctx, sha1); 1984202a189Smrg if (!success) 1994642e01fSmrg return BadAlloc; 2004642e01fSmrg return Success; 2014642e01fSmrg} 2024642e01fSmrg 2034642e01fSmrgGlyphPtr 2044642e01fSmrgFindGlyphByHash (unsigned char sha1[20], int format) 2054642e01fSmrg{ 2064642e01fSmrg GlyphRefPtr gr; 2074642e01fSmrg CARD32 signature = *(CARD32 *) sha1; 2084642e01fSmrg 209ad5464f4Smrg if (!globalGlyphs[format].hashSet) 2104202a189Smrg return NULL; 211ad5464f4Smrg 2124642e01fSmrg gr = FindGlyphRef (&globalGlyphs[format], 2134642e01fSmrg signature, TRUE, sha1); 2144642e01fSmrg 2154642e01fSmrg if (gr->glyph && gr->glyph != DeletedGlyph) 2164642e01fSmrg return gr->glyph; 2174642e01fSmrg else 2184642e01fSmrg return NULL; 21905b261ecSmrg} 22005b261ecSmrg 22105b261ecSmrg#ifdef CHECK_DUPLICATES 22205b261ecSmrgvoid 22305b261ecSmrgDuplicateRef (GlyphPtr glyph, char *where) 22405b261ecSmrg{ 22505b261ecSmrg ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where); 22605b261ecSmrg} 22705b261ecSmrg 22805b261ecSmrgvoid 22905b261ecSmrgCheckDuplicates (GlyphHashPtr hash, char *where) 23005b261ecSmrg{ 23105b261ecSmrg GlyphPtr g; 23205b261ecSmrg int i, j; 23305b261ecSmrg 23405b261ecSmrg for (i = 0; i < hash->hashSet->size; i++) 23505b261ecSmrg { 23605b261ecSmrg g = hash->table[i].glyph; 23705b261ecSmrg if (!g || g == DeletedGlyph) 23805b261ecSmrg continue; 23905b261ecSmrg for (j = i + 1; j < hash->hashSet->size; j++) 24005b261ecSmrg if (hash->table[j].glyph == g) 24105b261ecSmrg DuplicateRef (g, where); 24205b261ecSmrg } 24305b261ecSmrg} 24405b261ecSmrg#else 24505b261ecSmrg#define CheckDuplicates(a,b) 24605b261ecSmrg#define DuplicateRef(a,b) 24705b261ecSmrg#endif 24805b261ecSmrg 2494202a189Smrgstatic void 2504202a189SmrgFreeGlyphPicture(GlyphPtr glyph) 2514202a189Smrg{ 2524202a189Smrg PictureScreenPtr ps; 2534202a189Smrg int i; 2544202a189Smrg 2554202a189Smrg for (i = 0; i < screenInfo.numScreens; i++) 2564202a189Smrg { 2574202a189Smrg ScreenPtr pScreen = screenInfo.screens[i]; 2584202a189Smrg 2594202a189Smrg if (GlyphPicture(glyph)[i]) 2604202a189Smrg FreePicture ((pointer) GlyphPicture (glyph)[i], 0); 2614202a189Smrg 2624202a189Smrg ps = GetPictureScreenIfSet (pScreen); 2634202a189Smrg if (ps) 2644202a189Smrg (*ps->UnrealizeGlyph) (pScreen, glyph); 2654202a189Smrg } 2664202a189Smrg} 2674202a189Smrg 2684202a189Smrg 26905b261ecSmrgvoid 27005b261ecSmrgFreeGlyph (GlyphPtr glyph, int format) 27105b261ecSmrg{ 27205b261ecSmrg CheckDuplicates (&globalGlyphs[format], "FreeGlyph"); 27305b261ecSmrg if (--glyph->refcnt == 0) 27405b261ecSmrg { 27505b261ecSmrg GlyphRefPtr gr; 27605b261ecSmrg int i; 27705b261ecSmrg int first; 2784642e01fSmrg CARD32 signature; 27905b261ecSmrg 28005b261ecSmrg first = -1; 28105b261ecSmrg for (i = 0; i < globalGlyphs[format].hashSet->size; i++) 28205b261ecSmrg if (globalGlyphs[format].table[i].glyph == glyph) 28305b261ecSmrg { 28405b261ecSmrg if (first != -1) 28505b261ecSmrg DuplicateRef (glyph, "FreeGlyph check"); 28605b261ecSmrg first = i; 28705b261ecSmrg } 28805b261ecSmrg 2894642e01fSmrg signature = *(CARD32 *) glyph->sha1; 2904642e01fSmrg gr = FindGlyphRef (&globalGlyphs[format], signature, 2914642e01fSmrg TRUE, glyph->sha1); 29205b261ecSmrg if (gr - globalGlyphs[format].table != first) 29305b261ecSmrg DuplicateRef (glyph, "Found wrong one"); 29405b261ecSmrg if (gr->glyph && gr->glyph != DeletedGlyph) 29505b261ecSmrg { 29605b261ecSmrg gr->glyph = DeletedGlyph; 29705b261ecSmrg gr->signature = 0; 29805b261ecSmrg globalGlyphs[format].tableEntries--; 29905b261ecSmrg } 30005b261ecSmrg 3014202a189Smrg FreeGlyphPicture(glyph); 3024202a189Smrg dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH); 30305b261ecSmrg } 30405b261ecSmrg} 30505b261ecSmrg 30605b261ecSmrgvoid 30705b261ecSmrgAddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) 30805b261ecSmrg{ 30905b261ecSmrg GlyphRefPtr gr; 3104642e01fSmrg CARD32 signature; 31105b261ecSmrg 31205b261ecSmrg CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); 31305b261ecSmrg /* Locate existing matching glyph */ 3144642e01fSmrg signature = *(CARD32 *) glyph->sha1; 3154642e01fSmrg gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, 3164642e01fSmrg TRUE, glyph->sha1); 3174642e01fSmrg if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) 31805b261ecSmrg { 3194202a189Smrg FreeGlyphPicture(glyph); 3204202a189Smrg dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH); 32105b261ecSmrg glyph = gr->glyph; 32205b261ecSmrg } 3234642e01fSmrg else if (gr->glyph != glyph) 32405b261ecSmrg { 32505b261ecSmrg gr->glyph = glyph; 3264642e01fSmrg gr->signature = signature; 32705b261ecSmrg globalGlyphs[glyphSet->fdepth].tableEntries++; 32805b261ecSmrg } 32905b261ecSmrg 33005b261ecSmrg /* Insert/replace glyphset value */ 33105b261ecSmrg gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0); 33205b261ecSmrg ++glyph->refcnt; 33305b261ecSmrg if (gr->glyph && gr->glyph != DeletedGlyph) 33405b261ecSmrg FreeGlyph (gr->glyph, glyphSet->fdepth); 33505b261ecSmrg else 33605b261ecSmrg glyphSet->hash.tableEntries++; 33705b261ecSmrg gr->glyph = glyph; 33805b261ecSmrg gr->signature = id; 33905b261ecSmrg CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom"); 34005b261ecSmrg} 34105b261ecSmrg 34205b261ecSmrgBool 34305b261ecSmrgDeleteGlyph (GlyphSetPtr glyphSet, Glyph id) 34405b261ecSmrg{ 34505b261ecSmrg GlyphRefPtr gr; 34605b261ecSmrg GlyphPtr glyph; 34705b261ecSmrg 34805b261ecSmrg gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0); 34905b261ecSmrg glyph = gr->glyph; 35005b261ecSmrg if (glyph && glyph != DeletedGlyph) 35105b261ecSmrg { 35205b261ecSmrg gr->glyph = DeletedGlyph; 35305b261ecSmrg glyphSet->hash.tableEntries--; 35405b261ecSmrg FreeGlyph (glyph, glyphSet->fdepth); 35505b261ecSmrg return TRUE; 35605b261ecSmrg } 35705b261ecSmrg return FALSE; 35805b261ecSmrg} 35905b261ecSmrg 36005b261ecSmrgGlyphPtr 36105b261ecSmrgFindGlyph (GlyphSetPtr glyphSet, Glyph id) 36205b261ecSmrg{ 36305b261ecSmrg GlyphPtr glyph; 36405b261ecSmrg 36505b261ecSmrg glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph; 36605b261ecSmrg if (glyph == DeletedGlyph) 36705b261ecSmrg glyph = 0; 36805b261ecSmrg return glyph; 36905b261ecSmrg} 37005b261ecSmrg 37105b261ecSmrgGlyphPtr 37205b261ecSmrgAllocateGlyph (xGlyphInfo *gi, int fdepth) 37305b261ecSmrg{ 37405b261ecSmrg PictureScreenPtr ps; 37505b261ecSmrg int size; 37605b261ecSmrg GlyphPtr glyph; 37705b261ecSmrg int i; 3784202a189Smrg int head_size; 3794642e01fSmrg 3804202a189Smrg head_size = sizeof (GlyphRec) + screenInfo.numScreens * sizeof (PicturePtr); 3814202a189Smrg size = (head_size + dixPrivatesSize(PRIVATE_GLYPH)); 3824202a189Smrg glyph = (GlyphPtr) malloc (size); 38305b261ecSmrg if (!glyph) 38405b261ecSmrg return 0; 38505b261ecSmrg glyph->refcnt = 0; 38605b261ecSmrg glyph->size = size + sizeof (xGlyphInfo); 38705b261ecSmrg glyph->info = *gi; 3884202a189Smrg dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH); 38905b261ecSmrg 39005b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 39105b261ecSmrg { 3924202a189Smrg GlyphPicture(glyph)[i] = NULL; 39305b261ecSmrg ps = GetPictureScreenIfSet (screenInfo.screens[i]); 3944642e01fSmrg 39505b261ecSmrg if (ps) 39605b261ecSmrg { 39705b261ecSmrg if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) 3984642e01fSmrg goto bail; 39905b261ecSmrg } 40005b261ecSmrg } 40105b261ecSmrg 40205b261ecSmrg return glyph; 4034642e01fSmrg 4044642e01fSmrgbail: 4054642e01fSmrg while (i--) 4064642e01fSmrg { 4074642e01fSmrg ps = GetPictureScreenIfSet (screenInfo.screens[i]); 4084642e01fSmrg if (ps) 4094642e01fSmrg (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); 4104642e01fSmrg } 4114642e01fSmrg 4124202a189Smrg dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH); 4134642e01fSmrg return 0; 41405b261ecSmrg} 41505b261ecSmrg 41605b261ecSmrgBool 41705b261ecSmrgAllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet) 41805b261ecSmrg{ 4194202a189Smrg hash->table = calloc(hashSet->size, sizeof (GlyphRefRec)); 42005b261ecSmrg if (!hash->table) 42105b261ecSmrg return FALSE; 42205b261ecSmrg hash->hashSet = hashSet; 42305b261ecSmrg hash->tableEntries = 0; 42405b261ecSmrg return TRUE; 42505b261ecSmrg} 42605b261ecSmrg 42705b261ecSmrgBool 42805b261ecSmrgResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) 42905b261ecSmrg{ 43005b261ecSmrg CARD32 tableEntries; 43105b261ecSmrg GlyphHashSetPtr hashSet; 43205b261ecSmrg GlyphHashRec newHash; 43305b261ecSmrg GlyphRefPtr gr; 43405b261ecSmrg GlyphPtr glyph; 43505b261ecSmrg int i; 43605b261ecSmrg int oldSize; 43705b261ecSmrg CARD32 s; 43805b261ecSmrg 43905b261ecSmrg tableEntries = hash->tableEntries + change; 44005b261ecSmrg hashSet = FindGlyphHashSet (tableEntries); 44105b261ecSmrg if (hashSet == hash->hashSet) 44205b261ecSmrg return TRUE; 44305b261ecSmrg if (global) 44405b261ecSmrg CheckDuplicates (hash, "ResizeGlyphHash top"); 44505b261ecSmrg if (!AllocateGlyphHash (&newHash, hashSet)) 44605b261ecSmrg return FALSE; 44705b261ecSmrg if (hash->table) 44805b261ecSmrg { 44905b261ecSmrg oldSize = hash->hashSet->size; 45005b261ecSmrg for (i = 0; i < oldSize; i++) 45105b261ecSmrg { 45205b261ecSmrg glyph = hash->table[i].glyph; 45305b261ecSmrg if (glyph && glyph != DeletedGlyph) 45405b261ecSmrg { 45505b261ecSmrg s = hash->table[i].signature; 4564642e01fSmrg gr = FindGlyphRef (&newHash, s, global, glyph->sha1); 45705b261ecSmrg gr->signature = s; 45805b261ecSmrg gr->glyph = glyph; 45905b261ecSmrg ++newHash.tableEntries; 46005b261ecSmrg } 46105b261ecSmrg } 4624202a189Smrg free(hash->table); 46305b261ecSmrg } 46405b261ecSmrg *hash = newHash; 46505b261ecSmrg if (global) 46605b261ecSmrg CheckDuplicates (hash, "ResizeGlyphHash bottom"); 46705b261ecSmrg return TRUE; 46805b261ecSmrg} 46905b261ecSmrg 47005b261ecSmrgBool 47105b261ecSmrgResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change) 47205b261ecSmrg{ 47305b261ecSmrg return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) && 47405b261ecSmrg ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE)); 47505b261ecSmrg} 47605b261ecSmrg 47705b261ecSmrgGlyphSetPtr 47805b261ecSmrgAllocateGlyphSet (int fdepth, PictFormatPtr format) 47905b261ecSmrg{ 48005b261ecSmrg GlyphSetPtr glyphSet; 48105b261ecSmrg 48205b261ecSmrg if (!globalGlyphs[fdepth].hashSet) 48305b261ecSmrg { 48405b261ecSmrg if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0])) 48505b261ecSmrg return FALSE; 48605b261ecSmrg } 48705b261ecSmrg 4884202a189Smrg glyphSet = dixAllocateObjectWithPrivates(GlyphSetRec, PRIVATE_GLYPHSET); 48905b261ecSmrg if (!glyphSet) 49005b261ecSmrg return FALSE; 49105b261ecSmrg 49205b261ecSmrg if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0])) 49305b261ecSmrg { 4944202a189Smrg free(glyphSet); 49505b261ecSmrg return FALSE; 49605b261ecSmrg } 49705b261ecSmrg glyphSet->refcnt = 1; 49805b261ecSmrg glyphSet->fdepth = fdepth; 49905b261ecSmrg glyphSet->format = format; 50005b261ecSmrg return glyphSet; 50105b261ecSmrg} 50205b261ecSmrg 50305b261ecSmrgint 50405b261ecSmrgFreeGlyphSet (pointer value, 50505b261ecSmrg XID gid) 50605b261ecSmrg{ 50705b261ecSmrg GlyphSetPtr glyphSet = (GlyphSetPtr) value; 50805b261ecSmrg 50905b261ecSmrg if (--glyphSet->refcnt == 0) 51005b261ecSmrg { 51105b261ecSmrg CARD32 i, tableSize = glyphSet->hash.hashSet->size; 51205b261ecSmrg GlyphRefPtr table = glyphSet->hash.table; 51305b261ecSmrg GlyphPtr glyph; 51405b261ecSmrg 51505b261ecSmrg for (i = 0; i < tableSize; i++) 51605b261ecSmrg { 51705b261ecSmrg glyph = table[i].glyph; 51805b261ecSmrg if (glyph && glyph != DeletedGlyph) 51905b261ecSmrg FreeGlyph (glyph, glyphSet->fdepth); 52005b261ecSmrg } 52105b261ecSmrg if (!globalGlyphs[glyphSet->fdepth].tableEntries) 52205b261ecSmrg { 5234202a189Smrg free(globalGlyphs[glyphSet->fdepth].table); 52405b261ecSmrg globalGlyphs[glyphSet->fdepth].table = 0; 52505b261ecSmrg globalGlyphs[glyphSet->fdepth].hashSet = 0; 52605b261ecSmrg } 52705b261ecSmrg else 52805b261ecSmrg ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE); 5294202a189Smrg free(table); 5304202a189Smrg dixFreeObjectWithPrivates(glyphSet, PRIVATE_GLYPHSET); 53105b261ecSmrg } 53205b261ecSmrg return Success; 53305b261ecSmrg} 5344642e01fSmrg 5354642e01fSmrgstatic void 5364642e01fSmrgGlyphExtents (int nlist, 5374642e01fSmrg GlyphListPtr list, 5384642e01fSmrg GlyphPtr *glyphs, 5394642e01fSmrg BoxPtr extents) 5404642e01fSmrg{ 5414642e01fSmrg int x1, x2, y1, y2; 5424642e01fSmrg int n; 5434642e01fSmrg GlyphPtr glyph; 5444642e01fSmrg int x, y; 5454642e01fSmrg 5464642e01fSmrg x = 0; 5474642e01fSmrg y = 0; 5484642e01fSmrg extents->x1 = MAXSHORT; 5494642e01fSmrg extents->x2 = MINSHORT; 5504642e01fSmrg extents->y1 = MAXSHORT; 5514642e01fSmrg extents->y2 = MINSHORT; 5524642e01fSmrg while (nlist--) 5534642e01fSmrg { 5544642e01fSmrg x += list->xOff; 5554642e01fSmrg y += list->yOff; 5564642e01fSmrg n = list->len; 5574642e01fSmrg list++; 5584642e01fSmrg while (n--) 5594642e01fSmrg { 5604642e01fSmrg glyph = *glyphs++; 5614642e01fSmrg x1 = x - glyph->info.x; 5624642e01fSmrg if (x1 < MINSHORT) 5634642e01fSmrg x1 = MINSHORT; 5644642e01fSmrg y1 = y - glyph->info.y; 5654642e01fSmrg if (y1 < MINSHORT) 5664642e01fSmrg y1 = MINSHORT; 5674642e01fSmrg x2 = x1 + glyph->info.width; 5684642e01fSmrg if (x2 > MAXSHORT) 5694642e01fSmrg x2 = MAXSHORT; 5704642e01fSmrg y2 = y1 + glyph->info.height; 5714642e01fSmrg if (y2 > MAXSHORT) 5724642e01fSmrg y2 = MAXSHORT; 5734642e01fSmrg if (x1 < extents->x1) 5744642e01fSmrg extents->x1 = x1; 5754642e01fSmrg if (x2 > extents->x2) 5764642e01fSmrg extents->x2 = x2; 5774642e01fSmrg if (y1 < extents->y1) 5784642e01fSmrg extents->y1 = y1; 5794642e01fSmrg if (y2 > extents->y2) 5804642e01fSmrg extents->y2 = y2; 5814642e01fSmrg x += glyph->info.xOff; 5824642e01fSmrg y += glyph->info.yOff; 5834642e01fSmrg } 5844642e01fSmrg } 5854642e01fSmrg} 5864642e01fSmrg 5874642e01fSmrg#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) 5884642e01fSmrg 5894202a189Smrgvoid 5904642e01fSmrgCompositeGlyphs (CARD8 op, 5914642e01fSmrg PicturePtr pSrc, 5924642e01fSmrg PicturePtr pDst, 5934642e01fSmrg PictFormatPtr maskFormat, 5944642e01fSmrg INT16 xSrc, 5954642e01fSmrg INT16 ySrc, 5964642e01fSmrg int nlist, 5974642e01fSmrg GlyphListPtr lists, 5984642e01fSmrg GlyphPtr *glyphs) 5994642e01fSmrg{ 6004642e01fSmrg PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); 6014642e01fSmrg 6024642e01fSmrg ValidatePicture (pSrc); 6034642e01fSmrg ValidatePicture (pDst); 6044642e01fSmrg (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); 6054642e01fSmrg} 6064642e01fSmrg 6074642e01fSmrgBool 6084642e01fSmrgmiRealizeGlyph (ScreenPtr pScreen, 6094642e01fSmrg GlyphPtr glyph) 6104642e01fSmrg{ 6114642e01fSmrg return TRUE; 6124642e01fSmrg} 6134642e01fSmrg 6144642e01fSmrgvoid 6154642e01fSmrgmiUnrealizeGlyph (ScreenPtr pScreen, 6164642e01fSmrg GlyphPtr glyph) 6174642e01fSmrg{ 6184642e01fSmrg} 6194642e01fSmrg 6204202a189Smrgvoid 6214642e01fSmrgmiGlyphs (CARD8 op, 6224642e01fSmrg PicturePtr pSrc, 6234642e01fSmrg PicturePtr pDst, 6244642e01fSmrg PictFormatPtr maskFormat, 6254642e01fSmrg INT16 xSrc, 6264642e01fSmrg INT16 ySrc, 6274642e01fSmrg int nlist, 6284642e01fSmrg GlyphListPtr list, 6294642e01fSmrg GlyphPtr *glyphs) 6304642e01fSmrg{ 6314642e01fSmrg PicturePtr pPicture; 6324642e01fSmrg PixmapPtr pMaskPixmap = 0; 6334642e01fSmrg PicturePtr pMask; 6344642e01fSmrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 6354642e01fSmrg int width = 0, height = 0; 6364642e01fSmrg int x, y; 6374642e01fSmrg int xDst = list->xOff, yDst = list->yOff; 6384642e01fSmrg int n; 6394642e01fSmrg GlyphPtr glyph; 6404642e01fSmrg int error; 6414642e01fSmrg BoxRec extents = {0, 0, 0, 0}; 6424642e01fSmrg CARD32 component_alpha; 6434642e01fSmrg 6444642e01fSmrg if (maskFormat) 6454642e01fSmrg { 6464642e01fSmrg GCPtr pGC; 6474642e01fSmrg xRectangle rect; 6484642e01fSmrg 6494642e01fSmrg GlyphExtents (nlist, list, glyphs, &extents); 6504642e01fSmrg 6514642e01fSmrg if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) 6524642e01fSmrg return; 6534642e01fSmrg width = extents.x2 - extents.x1; 6544642e01fSmrg height = extents.y2 - extents.y1; 6554642e01fSmrg pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 6564642e01fSmrg maskFormat->depth, 6574642e01fSmrg CREATE_PIXMAP_USAGE_SCRATCH); 6584642e01fSmrg if (!pMaskPixmap) 6594642e01fSmrg return; 6604642e01fSmrg component_alpha = NeedsComponent(maskFormat->format); 6614642e01fSmrg pMask = CreatePicture (0, &pMaskPixmap->drawable, 6624642e01fSmrg maskFormat, CPComponentAlpha, &component_alpha, 6634642e01fSmrg serverClient, &error); 6644642e01fSmrg if (!pMask) 6654642e01fSmrg { 6664642e01fSmrg (*pScreen->DestroyPixmap) (pMaskPixmap); 6674642e01fSmrg return; 6684642e01fSmrg } 6694642e01fSmrg pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); 6704642e01fSmrg ValidateGC (&pMaskPixmap->drawable, pGC); 6714642e01fSmrg rect.x = 0; 6724642e01fSmrg rect.y = 0; 6734642e01fSmrg rect.width = width; 6744642e01fSmrg rect.height = height; 6754642e01fSmrg (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); 6764642e01fSmrg FreeScratchGC (pGC); 6774642e01fSmrg x = -extents.x1; 6784642e01fSmrg y = -extents.y1; 6794642e01fSmrg } 6804642e01fSmrg else 6814642e01fSmrg { 6824642e01fSmrg pMask = pDst; 6834642e01fSmrg x = 0; 6844642e01fSmrg y = 0; 6854642e01fSmrg } 6864642e01fSmrg while (nlist--) 6874642e01fSmrg { 6884642e01fSmrg x += list->xOff; 6894642e01fSmrg y += list->yOff; 6904642e01fSmrg n = list->len; 6914642e01fSmrg while (n--) 6924642e01fSmrg { 6934642e01fSmrg glyph = *glyphs++; 6944642e01fSmrg pPicture = GlyphPicture (glyph)[pScreen->myNum]; 6954642e01fSmrg 6964202a189Smrg if (pPicture) 6974642e01fSmrg { 6984202a189Smrg if (maskFormat) 6994202a189Smrg { 7004202a189Smrg CompositePicture (PictOpAdd, 7014202a189Smrg pPicture, 7024202a189Smrg None, 7034202a189Smrg pMask, 7044202a189Smrg 0, 0, 7054202a189Smrg 0, 0, 7064202a189Smrg x - glyph->info.x, 7074202a189Smrg y - glyph->info.y, 7084202a189Smrg glyph->info.width, 7094202a189Smrg glyph->info.height); 7104202a189Smrg } 7114202a189Smrg else 7124202a189Smrg { 7134202a189Smrg CompositePicture (op, 7144202a189Smrg pSrc, 7154202a189Smrg pPicture, 7164202a189Smrg pDst, 7174202a189Smrg xSrc + (x - glyph->info.x) - xDst, 7184202a189Smrg ySrc + (y - glyph->info.y) - yDst, 7194202a189Smrg 0, 0, 7204202a189Smrg x - glyph->info.x, 7214202a189Smrg y - glyph->info.y, 7224202a189Smrg glyph->info.width, 7234202a189Smrg glyph->info.height); 7244202a189Smrg } 7254642e01fSmrg } 7264642e01fSmrg 7274642e01fSmrg x += glyph->info.xOff; 7284642e01fSmrg y += glyph->info.yOff; 7294642e01fSmrg } 7304642e01fSmrg list++; 7314642e01fSmrg } 7324642e01fSmrg if (maskFormat) 7334642e01fSmrg { 7344642e01fSmrg x = extents.x1; 7354642e01fSmrg y = extents.y1; 7364642e01fSmrg CompositePicture (op, 7374642e01fSmrg pSrc, 7384642e01fSmrg pMask, 7394642e01fSmrg pDst, 7404642e01fSmrg xSrc + x - xDst, 7414642e01fSmrg ySrc + y - yDst, 7424642e01fSmrg 0, 0, 7434642e01fSmrg x, y, 7444642e01fSmrg width, height); 7454642e01fSmrg FreePicture ((pointer) pMask, (XID) 0); 7464642e01fSmrg (*pScreen->DestroyPixmap) (pMaskPixmap); 7474642e01fSmrg } 7484642e01fSmrg} 749