/* sdl-freetype, a text rendering library for SDL. * Copyright (C) 2006 luojinghua * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * THANKS FOR ALL CAIRO AUTHORS, MOST OF IDEAS AND IMPLEMENT DTAILS ARE * STOLEN FROM CAIRO. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "cache.h" #include #include #include #include struct _sdl_freetype_cache { sdl_freetype_hash_t hash; int freeze_count; int maxsize; int size; }; sdl_freetype_cache_t * sdl_freetype_cache_create (int maxsize, const sdl_freetype_cache_ops_t * ops) { sdl_freetype_cache_t * cache; cache = malloc(sizeof(sdl_freetype_cache_t)); if (!cache) goto errquit0; if (!sdl_freetype_hash_init (&cache->hash, maxsize, ops)) goto errquit1; cache->freeze_count = 0; cache->maxsize = maxsize; cache->size = 0; return cache; errquit1: free(cache); errquit0: return cache; } void sdl_freetype_cache_shrink (sdl_freetype_cache_t * cache, int size) { sdl_freetype_cache_entry_t * entry; if (cache->freeze_count) return; assert(cache->size + size >= 0); while (cache->size + size > cache->maxsize) { entry = (sdl_freetype_cache_entry_t *) sdl_freetype_hash_any_entry (&cache->hash, NULL); if (!entry) break; cache->size -= entry->size; sdl_freetype_hash_remove (&cache->hash, &entry->base); } } void sdl_freetype_cache_freeze (sdl_freetype_cache_t * cache) { cache->freeze_count++; } void sdl_freetype_cache_thaw (sdl_freetype_cache_t * cache) { assert(cache->freeze_count > 0); cache->freeze_count--; if (!cache->freeze_count) sdl_freetype_cache_shrink (cache, 0); } sdl_freetype_cache_entry_t * sdl_freetype_cache_lookup (sdl_freetype_cache_t * cache, sdl_freetype_cache_entry_t * key) { return (sdl_freetype_cache_entry_t *) sdl_freetype_hash_lookup (&cache->hash, &key->base); } int sdl_freetype_cache_insert (sdl_freetype_cache_t * cache, sdl_freetype_cache_entry_t * entry) { if (!sdl_freetype_hash_lookup (&cache->hash, &entry->base)) { sdl_freetype_cache_shrink (cache, entry->size); if (sdl_freetype_hash_insert (&cache->hash, &entry->base) < 0) return -1; cache->size += entry->size; } return 0; } int sdl_freetype_cache_foreach (sdl_freetype_cache_t * cache, sdl_freetype_cache_callback_func_t func, void * closure) { sdl_freetype_hash_foreach (&cache->hash, (sdl_freetype_hash_callback_func_t)func, closure); return 0; } void sdl_freetype_cache_empty (sdl_freetype_cache_t * cache) { if (!cache) return; sdl_freetype_hash_remove_all (&cache->hash); cache->size = 0; } void sdl_freetype_cache_destroy (sdl_freetype_cache_t * cache) { if (!cache) return; sdl_freetype_hash_fini (&cache->hash); free (cache); }