glyph.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. /*
  2. *
  3. * Copyright © 2000 SuSE, Inc.
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and its
  6. * documentation for any purpose is hereby granted without fee, provided that
  7. * the above copyright notice appear in all copies and that both that
  8. * copyright notice and this permission notice appear in supporting
  9. * documentation, and that the name of SuSE not be used in advertising or
  10. * publicity pertaining to distribution of the software without specific,
  11. * written prior permission. SuSE makes no representations about the
  12. * suitability of this software for any purpose. It is provided "as is"
  13. * without express or implied warranty.
  14. *
  15. * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
  17. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Author: Keith Packard, SuSE, Inc.
  23. */
  24. #ifdef HAVE_DIX_CONFIG_H
  25. #include <dix-config.h>
  26. #endif
  27. #include "misc.h"
  28. #include "scrnintstr.h"
  29. #include "os.h"
  30. #include "regionstr.h"
  31. #include "validate.h"
  32. #include "windowstr.h"
  33. #include "input.h"
  34. #include "resource.h"
  35. #include "colormapst.h"
  36. #include "cursorstr.h"
  37. #include "dixstruct.h"
  38. #include "gcstruct.h"
  39. #include "servermd.h"
  40. #include "picturestr.h"
  41. #include "glyphstr.h"
  42. /*
  43. * From Knuth -- a good choice for hash/rehash values is p, p-2 where
  44. * p and p-2 are both prime. These tables are sized to have an extra 10%
  45. * free to avoid exponential performance degradation as the hash table fills
  46. */
  47. static GlyphHashSetRec glyphHashSets[] = {
  48. {32, 43, 41},
  49. {64, 73, 71},
  50. {128, 151, 149},
  51. {256, 283, 281},
  52. {512, 571, 569},
  53. {1024, 1153, 1151},
  54. {2048, 2269, 2267},
  55. {4096, 4519, 4517},
  56. {8192, 9013, 9011},
  57. {16384, 18043, 18041},
  58. {32768, 36109, 36107},
  59. {65536, 72091, 72089},
  60. {131072, 144409, 144407},
  61. {262144, 288361, 288359},
  62. {524288, 576883, 576881},
  63. {1048576, 1153459, 1153457},
  64. {2097152, 2307163, 2307161},
  65. {4194304, 4613893, 4613891},
  66. {8388608, 9227641, 9227639},
  67. {16777216, 18455029, 18455027},
  68. {33554432, 36911011, 36911009},
  69. {67108864, 73819861, 73819859},
  70. {134217728, 147639589, 147639587},
  71. {268435456, 295279081, 295279079},
  72. {536870912, 590559793, 590559791}
  73. };
  74. #define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
  75. const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
  76. GlyphHashRec globalGlyphs[GlyphFormatNum];
  77. int globalTotalGlyphPrivateSize = 0;
  78. static void
  79. SetGlyphScreenPrivateOffsets(void)
  80. {
  81. PictureScreenPtr ps;
  82. int offset = 0;
  83. int i;
  84. for (i = 0; i < screenInfo.numScreens; i++) {
  85. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  86. if (ps && ps->totalGlyphPrivateSize) {
  87. ps->glyphPrivateOffset = offset;
  88. offset += ps->totalGlyphPrivateSize / sizeof(DevUnion);
  89. }
  90. }
  91. }
  92. static void
  93. SetGlyphPrivatePointers(GlyphPtr glyph)
  94. {
  95. PictureScreenPtr ps;
  96. int i;
  97. char *ptr;
  98. DevUnion *ppriv;
  99. unsigned *sizes;
  100. unsigned size;
  101. int len;
  102. for (i = 0; i < screenInfo.numScreens; i++) {
  103. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  104. if (ps && ps->totalGlyphPrivateSize) {
  105. ppriv = glyph->devPrivates + ps->glyphPrivateOffset;
  106. sizes = ps->glyphPrivateSizes;
  107. ptr = (char *) (ppriv + ps->glyphPrivateLen);
  108. for (len = ps->glyphPrivateLen; --len >= 0; ppriv++, sizes++) {
  109. if ((size = *sizes) != 0) {
  110. ppriv->ptr = (pointer) ptr;
  111. ptr += size;
  112. }
  113. else
  114. ppriv->ptr = (pointer) 0;
  115. }
  116. }
  117. }
  118. }
  119. static Bool
  120. ReallocGlobalGlyphPrivate(GlyphPtr glyph)
  121. {
  122. PictureScreenPtr ps;
  123. DevUnion *devPrivates;
  124. char *ptr;
  125. int i;
  126. devPrivates = malloc(globalTotalGlyphPrivateSize);
  127. if (!devPrivates)
  128. return FALSE;
  129. ptr = (char *) devPrivates;
  130. for (i = 0; i < screenInfo.numScreens; i++) {
  131. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  132. if (ps && ps->totalGlyphPrivateSize) {
  133. if (ps->glyphPrivateOffset != -1) {
  134. memcpy(ptr, glyph->devPrivates + ps->glyphPrivateOffset,
  135. ps->totalGlyphPrivateSize);
  136. }
  137. else if (ps->totalGlyphPrivateSize) {
  138. memset(ptr, 0, ps->totalGlyphPrivateSize);
  139. }
  140. ptr += ps->totalGlyphPrivateSize;
  141. }
  142. }
  143. if (glyph->devPrivates)
  144. free(glyph->devPrivates);
  145. glyph->devPrivates = devPrivates;
  146. return TRUE;
  147. }
  148. Bool
  149. GlyphInit(ScreenPtr pScreen)
  150. {
  151. PictureScreenPtr ps = GetPictureScreen(pScreen);
  152. ps->totalGlyphPrivateSize = 0;
  153. ps->glyphPrivateSizes = 0;
  154. ps->glyphPrivateLen = 0;
  155. ps->glyphPrivateOffset = -1;
  156. return TRUE;
  157. }
  158. Bool
  159. GlyphFinishInit(ScreenPtr pScreen)
  160. {
  161. PictureScreenPtr ps = GetPictureScreen(pScreen);
  162. if (ps->totalGlyphPrivateSize) {
  163. GlyphPtr glyph;
  164. int fdepth, i;
  165. globalTotalGlyphPrivateSize += ps->totalGlyphPrivateSize;
  166. for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) {
  167. if (!globalGlyphs[fdepth].hashSet)
  168. continue;
  169. for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) {
  170. glyph = globalGlyphs[fdepth].table[i].glyph;
  171. if (glyph && glyph != DeletedGlyph) {
  172. if (!ReallocGlobalGlyphPrivate(glyph))
  173. return FALSE;
  174. }
  175. }
  176. }
  177. SetGlyphScreenPrivateOffsets();
  178. for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) {
  179. if (!globalGlyphs[fdepth].hashSet)
  180. continue;
  181. for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) {
  182. glyph = globalGlyphs[fdepth].table[i].glyph;
  183. if (glyph && glyph != DeletedGlyph) {
  184. SetGlyphPrivatePointers(glyph);
  185. if (!(*ps->RealizeGlyph) (pScreen, glyph))
  186. return FALSE;
  187. }
  188. }
  189. }
  190. }
  191. else
  192. ps->glyphPrivateOffset = 0;
  193. return TRUE;
  194. }
  195. void
  196. GlyphUninit(ScreenPtr pScreen)
  197. {
  198. PictureScreenPtr ps = GetPictureScreen(pScreen);
  199. GlyphPtr glyph;
  200. int fdepth, i;
  201. globalTotalGlyphPrivateSize -= ps->totalGlyphPrivateSize;
  202. for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) {
  203. if (!globalGlyphs[fdepth].hashSet)
  204. continue;
  205. for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) {
  206. glyph = globalGlyphs[fdepth].table[i].glyph;
  207. if (glyph && glyph != DeletedGlyph) {
  208. (*ps->UnrealizeGlyph) (pScreen, glyph);
  209. if (globalTotalGlyphPrivateSize) {
  210. if (!ReallocGlobalGlyphPrivate(glyph))
  211. return;
  212. }
  213. else {
  214. if (glyph->devPrivates)
  215. free(glyph->devPrivates);
  216. glyph->devPrivates = NULL;
  217. }
  218. }
  219. }
  220. }
  221. if (globalTotalGlyphPrivateSize)
  222. SetGlyphScreenPrivateOffsets();
  223. for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) {
  224. if (!globalGlyphs[fdepth].hashSet)
  225. continue;
  226. for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) {
  227. glyph = globalGlyphs[fdepth].table[i].glyph;
  228. if (glyph && glyph != DeletedGlyph) {
  229. if (globalTotalGlyphPrivateSize)
  230. SetGlyphPrivatePointers(glyph);
  231. }
  232. }
  233. }
  234. if (ps->glyphPrivateSizes)
  235. free(ps->glyphPrivateSizes);
  236. }
  237. GlyphHashSetPtr
  238. FindGlyphHashSet(CARD32 filled)
  239. {
  240. int i;
  241. for (i = 0; i < NGLYPHHASHSETS; i++)
  242. if (glyphHashSets[i].entries >= filled)
  243. return &glyphHashSets[i];
  244. return 0;
  245. }
  246. static int _GlyphSetPrivateAllocateIndex = 0;
  247. void
  248. ResetGlyphSetPrivateIndex(void)
  249. {
  250. _GlyphSetPrivateAllocateIndex = 0;
  251. }
  252. Bool
  253. _GlyphSetSetNewPrivate(GlyphSetPtr glyphSet, int n, pointer ptr)
  254. {
  255. pointer *new;
  256. if (n > glyphSet->maxPrivate) {
  257. if (glyphSet->devPrivates &&
  258. glyphSet->devPrivates != (pointer) (&glyphSet[1])) {
  259. new = (pointer *) realloc(glyphSet->devPrivates,
  260. (n + 1) * sizeof(pointer));
  261. if (!new)
  262. return FALSE;
  263. }
  264. else {
  265. new = malloc((n + 1) * sizeof(pointer));
  266. if (!new)
  267. return FALSE;
  268. if (glyphSet->devPrivates)
  269. memcpy(new,
  270. glyphSet->devPrivates,
  271. (glyphSet->maxPrivate + 1) * sizeof(pointer));
  272. }
  273. glyphSet->devPrivates = new;
  274. /* Zero out new, uninitialize privates */
  275. while (++glyphSet->maxPrivate < n)
  276. glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer) 0;
  277. }
  278. glyphSet->devPrivates[n] = ptr;
  279. return TRUE;
  280. }
  281. GlyphRefPtr
  282. FindGlyphRef(GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
  283. {
  284. CARD32 elt, step, s;
  285. GlyphPtr glyph;
  286. GlyphRefPtr table, gr, del;
  287. CARD32 tableSize = hash->hashSet->size;
  288. table = hash->table;
  289. elt = signature % tableSize;
  290. step = 0;
  291. del = 0;
  292. for (;;) {
  293. gr = &table[elt];
  294. s = gr->signature;
  295. glyph = gr->glyph;
  296. if (!glyph) {
  297. if (del)
  298. gr = del;
  299. break;
  300. }
  301. if (glyph == DeletedGlyph) {
  302. if (!del)
  303. del = gr;
  304. else if (gr == del)
  305. break;
  306. }
  307. else if (s == signature &&
  308. (!match ||
  309. memcmp(&compare->info, &glyph->info, compare->size) == 0)) {
  310. break;
  311. }
  312. if (!step) {
  313. step = signature % hash->hashSet->rehash;
  314. if (!step)
  315. step = 1;
  316. }
  317. elt += step;
  318. if (elt >= tableSize)
  319. elt -= tableSize;
  320. }
  321. return gr;
  322. }
  323. CARD32
  324. HashGlyph(GlyphPtr glyph)
  325. {
  326. CARD32 *bits = (CARD32 *) &(glyph->info);
  327. CARD32 hash;
  328. int n = glyph->size / sizeof(CARD32);
  329. hash = 0;
  330. while (n--)
  331. hash ^= *bits++;
  332. return hash;
  333. }
  334. #ifdef CHECK_DUPLICATES
  335. void
  336. DuplicateRef(GlyphPtr glyph, char *where)
  337. {
  338. ErrorF("Duplicate Glyph 0x%x from %s\n", glyph, where);
  339. }
  340. void
  341. CheckDuplicates(GlyphHashPtr hash, char *where)
  342. {
  343. GlyphPtr g;
  344. int i, j;
  345. for (i = 0; i < hash->hashSet->size; i++) {
  346. g = hash->table[i].glyph;
  347. if (!g || g == DeletedGlyph)
  348. continue;
  349. for (j = i + 1; j < hash->hashSet->size; j++)
  350. if (hash->table[j].glyph == g)
  351. DuplicateRef(g, where);
  352. }
  353. }
  354. #else
  355. #define CheckDuplicates(a,b)
  356. #define DuplicateRef(a,b)
  357. #endif
  358. void
  359. FreeGlyph(GlyphPtr glyph, int format)
  360. {
  361. CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
  362. if (--glyph->refcnt == 0) {
  363. PictureScreenPtr ps;
  364. GlyphRefPtr gr;
  365. int i;
  366. int first;
  367. first = -1;
  368. for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
  369. if (globalGlyphs[format].table[i].glyph == glyph) {
  370. if (first != -1)
  371. DuplicateRef(glyph, "FreeGlyph check");
  372. first = i;
  373. }
  374. gr = FindGlyphRef(&globalGlyphs[format], HashGlyph(glyph), TRUE, glyph);
  375. if (gr - globalGlyphs[format].table != first)
  376. DuplicateRef(glyph, "Found wrong one");
  377. if (gr->glyph && gr->glyph != DeletedGlyph) {
  378. gr->glyph = DeletedGlyph;
  379. gr->signature = 0;
  380. globalGlyphs[format].tableEntries--;
  381. }
  382. for (i = 0; i < screenInfo.numScreens; i++) {
  383. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  384. if (ps)
  385. (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
  386. }
  387. if (glyph->devPrivates)
  388. free(glyph->devPrivates);
  389. free(glyph);
  390. }
  391. }
  392. void
  393. AddGlyph(GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
  394. {
  395. GlyphRefPtr gr;
  396. CARD32 hash;
  397. CheckDuplicates(&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
  398. /* Locate existing matching glyph */
  399. hash = HashGlyph(glyph);
  400. gr = FindGlyphRef(&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
  401. if (gr->glyph && gr->glyph != DeletedGlyph) {
  402. PictureScreenPtr ps;
  403. int i;
  404. for (i = 0; i < screenInfo.numScreens; i++) {
  405. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  406. if (ps)
  407. (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
  408. }
  409. if (glyph->devPrivates)
  410. free(glyph->devPrivates);
  411. free(glyph);
  412. glyph = gr->glyph;
  413. }
  414. else {
  415. gr->glyph = glyph;
  416. gr->signature = hash;
  417. globalGlyphs[glyphSet->fdepth].tableEntries++;
  418. }
  419. /* Insert/replace glyphset value */
  420. gr = FindGlyphRef(&glyphSet->hash, id, FALSE, 0);
  421. ++glyph->refcnt;
  422. if (gr->glyph && gr->glyph != DeletedGlyph)
  423. FreeGlyph(gr->glyph, glyphSet->fdepth);
  424. else
  425. glyphSet->hash.tableEntries++;
  426. gr->glyph = glyph;
  427. gr->signature = id;
  428. CheckDuplicates(&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
  429. }
  430. Bool
  431. DeleteGlyph(GlyphSetPtr glyphSet, Glyph id)
  432. {
  433. GlyphRefPtr gr;
  434. GlyphPtr glyph;
  435. gr = FindGlyphRef(&glyphSet->hash, id, FALSE, 0);
  436. glyph = gr->glyph;
  437. if (glyph && glyph != DeletedGlyph) {
  438. gr->glyph = DeletedGlyph;
  439. glyphSet->hash.tableEntries--;
  440. FreeGlyph(glyph, glyphSet->fdepth);
  441. return TRUE;
  442. }
  443. return FALSE;
  444. }
  445. GlyphPtr
  446. FindGlyph(GlyphSetPtr glyphSet, Glyph id)
  447. {
  448. GlyphPtr glyph;
  449. glyph = FindGlyphRef(&glyphSet->hash, id, FALSE, 0)->glyph;
  450. if (glyph == DeletedGlyph)
  451. glyph = 0;
  452. return glyph;
  453. }
  454. GlyphPtr
  455. AllocateGlyph(xGlyphInfo * gi, int fdepth)
  456. {
  457. PictureScreenPtr ps;
  458. int size;
  459. GlyphPtr glyph;
  460. int i;
  461. size = gi->height * PixmapBytePad(gi->width, glyphDepths[fdepth]);
  462. glyph = malloc(size + sizeof(GlyphRec));
  463. if (!glyph)
  464. return 0;
  465. glyph->refcnt = 0;
  466. glyph->size = size + sizeof(xGlyphInfo);
  467. glyph->info = *gi;
  468. if (globalTotalGlyphPrivateSize) {
  469. glyph->devPrivates = malloc(globalTotalGlyphPrivateSize);
  470. if (!glyph->devPrivates)
  471. return 0;
  472. SetGlyphPrivatePointers(glyph);
  473. }
  474. else
  475. glyph->devPrivates = NULL;
  476. for (i = 0; i < screenInfo.numScreens; i++) {
  477. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  478. if (ps) {
  479. if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) {
  480. while (i--) {
  481. ps = GetPictureScreenIfSet(screenInfo.screens[i]);
  482. if (ps)
  483. (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
  484. }
  485. if (glyph->devPrivates)
  486. free(glyph->devPrivates);
  487. free(glyph);
  488. return 0;
  489. }
  490. }
  491. }
  492. return glyph;
  493. }
  494. Bool
  495. AllocateGlyphHash(GlyphHashPtr hash, GlyphHashSetPtr hashSet)
  496. {
  497. hash->table = malloc(hashSet->size * sizeof(GlyphRefRec));
  498. if (!hash->table)
  499. return FALSE;
  500. memset(hash->table, 0, hashSet->size * sizeof(GlyphRefRec));
  501. hash->hashSet = hashSet;
  502. hash->tableEntries = 0;
  503. return TRUE;
  504. }
  505. Bool
  506. ResizeGlyphHash(GlyphHashPtr hash, CARD32 change, Bool global)
  507. {
  508. CARD32 tableEntries;
  509. GlyphHashSetPtr hashSet;
  510. GlyphHashRec newHash;
  511. GlyphRefPtr gr;
  512. GlyphPtr glyph;
  513. int i;
  514. int oldSize;
  515. CARD32 s;
  516. tableEntries = hash->tableEntries + change;
  517. hashSet = FindGlyphHashSet(tableEntries);
  518. if (hashSet == hash->hashSet)
  519. return TRUE;
  520. if (global)
  521. CheckDuplicates(hash, "ResizeGlyphHash top");
  522. if (!AllocateGlyphHash(&newHash, hashSet))
  523. return FALSE;
  524. if (hash->table) {
  525. oldSize = hash->hashSet->size;
  526. for (i = 0; i < oldSize; i++) {
  527. glyph = hash->table[i].glyph;
  528. if (glyph && glyph != DeletedGlyph) {
  529. s = hash->table[i].signature;
  530. gr = FindGlyphRef(&newHash, s, global, glyph);
  531. gr->signature = s;
  532. gr->glyph = glyph;
  533. ++newHash.tableEntries;
  534. }
  535. }
  536. free(hash->table);
  537. }
  538. *hash = newHash;
  539. if (global)
  540. CheckDuplicates(hash, "ResizeGlyphHash bottom");
  541. return TRUE;
  542. }
  543. Bool
  544. ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change)
  545. {
  546. return (ResizeGlyphHash(&glyphSet->hash, change, FALSE) &&
  547. ResizeGlyphHash(&globalGlyphs[glyphSet->fdepth], change, TRUE));
  548. }
  549. GlyphSetPtr
  550. AllocateGlyphSet(int fdepth, PictFormatPtr format)
  551. {
  552. GlyphSetPtr glyphSet;
  553. int size;
  554. if (!globalGlyphs[fdepth].hashSet) {
  555. if (!AllocateGlyphHash(&globalGlyphs[fdepth], &glyphHashSets[0]))
  556. return FALSE;
  557. }
  558. size = (sizeof(GlyphSetRec) +
  559. (sizeof(pointer) * _GlyphSetPrivateAllocateIndex));
  560. glyphSet = malloc(size);
  561. if (!glyphSet)
  562. return FALSE;
  563. bzero((char *) glyphSet, size);
  564. glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
  565. if (_GlyphSetPrivateAllocateIndex)
  566. glyphSet->devPrivates = (pointer) (&glyphSet[1]);
  567. if (!AllocateGlyphHash(&glyphSet->hash, &glyphHashSets[0])) {
  568. free(glyphSet);
  569. return FALSE;
  570. }
  571. glyphSet->refcnt = 1;
  572. glyphSet->fdepth = fdepth;
  573. glyphSet->format = format;
  574. return glyphSet;
  575. }
  576. int
  577. FreeGlyphSet(pointer value, XID gid)
  578. {
  579. GlyphSetPtr glyphSet = (GlyphSetPtr) value;
  580. if (--glyphSet->refcnt == 0) {
  581. CARD32 i, tableSize = glyphSet->hash.hashSet->size;
  582. GlyphRefPtr table = glyphSet->hash.table;
  583. GlyphPtr glyph;
  584. for (i = 0; i < tableSize; i++) {
  585. glyph = table[i].glyph;
  586. if (glyph && glyph != DeletedGlyph)
  587. FreeGlyph(glyph, glyphSet->fdepth);
  588. }
  589. if (!globalGlyphs[glyphSet->fdepth].tableEntries) {
  590. free(globalGlyphs[glyphSet->fdepth].table);
  591. globalGlyphs[glyphSet->fdepth].table = 0;
  592. globalGlyphs[glyphSet->fdepth].hashSet = 0;
  593. }
  594. else
  595. ResizeGlyphHash(&globalGlyphs[glyphSet->fdepth], 0, TRUE);
  596. free(table);
  597. if (glyphSet->devPrivates &&
  598. glyphSet->devPrivates != (pointer) (&glyphSet[1]))
  599. free(glyphSet->devPrivates);
  600. free(glyphSet);
  601. }
  602. return Success;
  603. }