|
Packit |
0ec9dd |
/* Pango
|
|
Packit |
0ec9dd |
* pangowin32-fontcache.c: Cache of HFONTs by LOGFONTW
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Copyright (C) 2000 Red Hat Software
|
|
Packit |
0ec9dd |
* Copyright (C) 2000 Tor Lillqvist
|
|
Packit |
0ec9dd |
* Copyright (C) 2007 Novell, Inc.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is free software; you can redistribute it and/or
|
|
Packit |
0ec9dd |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License as published by the Free Software Foundation; either
|
|
Packit |
0ec9dd |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
0ec9dd |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0ec9dd |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0ec9dd |
* Library General Public License for more details.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License along with this library; if not, write to the
|
|
Packit |
0ec9dd |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
0ec9dd |
* Boston, MA 02111-1307, USA.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include "config.h"
|
|
Packit |
0ec9dd |
#include <stdio.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include "pangowin32-private.h"
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Font cache
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Number of fonts to retain after they are not otherwise referenced.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
#define CACHE_SIZE 16
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
typedef struct _CacheEntry CacheEntry;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* PangoWin32FontCache:
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* A #PangoWin32FontCache caches HFONTs by their LOGFONT descriptions.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
struct _PangoWin32FontCache
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
GHashTable *forward;
|
|
Packit |
0ec9dd |
GHashTable *back;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
GList *mru;
|
|
Packit |
0ec9dd |
GList *mru_tail;
|
|
Packit |
0ec9dd |
int mru_count;
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
struct _CacheEntry
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
LOGFONTW logfontw;
|
|
Packit |
0ec9dd |
HFONT hfont;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
gint ref_count;
|
|
Packit |
0ec9dd |
GList *mru;
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
free_cache_entry (LOGFONTW *logfont,
|
|
Packit |
0ec9dd |
CacheEntry *entry,
|
|
Packit |
0ec9dd |
PangoWin32FontCache *cache)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
if (!DeleteObject (entry->hfont))
|
|
Packit |
0ec9dd |
PING (("DeleteObject for hfont %p failed", entry->hfont));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_slice_free (CacheEntry, entry);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_free:
|
|
Packit |
0ec9dd |
* @cache: a #PangoWin32FontCache
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Frees a #PangoWin32FontCache and all associated memory. All fonts loaded
|
|
Packit |
0ec9dd |
* through this font cache will be freed along with the cache.
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
void
|
|
Packit |
0ec9dd |
pango_win32_font_cache_free (PangoWin32FontCache *cache)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_if_fail (cache != NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_hash_table_destroy (cache->forward);
|
|
Packit |
0ec9dd |
g_hash_table_destroy (cache->back);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_list_free (cache->mru);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_slice_free (PangoWin32FontCache, cache);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static guint
|
|
Packit |
0ec9dd |
wcs_hash (gconstpointer v)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
/* 31 bit hash function */
|
|
Packit |
0ec9dd |
const wchar_t *p = v;
|
|
Packit |
0ec9dd |
guint32 h = *p;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (h)
|
|
Packit |
0ec9dd |
for (p += 1; *p != '\0'; p++)
|
|
Packit |
0ec9dd |
h = (h << 5) - h + *p;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return h;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static guint
|
|
Packit |
0ec9dd |
logfontw_hash (gconstpointer v)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
const LOGFONTW *lfp = v;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return wcs_hash (lfp->lfFaceName) +
|
|
Packit |
0ec9dd |
(lfp->lfItalic != 0) +
|
|
Packit |
0ec9dd |
lfp->lfWeight/10 +
|
|
Packit |
0ec9dd |
lfp->lfOrientation +
|
|
Packit |
0ec9dd |
abs (lfp->lfHeight) * 10;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gint
|
|
Packit |
0ec9dd |
logfontw_equal (gconstpointer v1,
|
|
Packit |
0ec9dd |
gconstpointer v2)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
const LOGFONTW *lfp1 = v1, *lfp2 = v2;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return (wcscmp (lfp1->lfFaceName, lfp2->lfFaceName) == 0
|
|
Packit |
0ec9dd |
&& lfp1->lfPitchAndFamily == lfp2->lfPitchAndFamily
|
|
Packit |
0ec9dd |
&& lfp1->lfStrikeOut == lfp2->lfStrikeOut
|
|
Packit |
0ec9dd |
&& lfp1->lfUnderline == lfp2->lfUnderline
|
|
Packit |
0ec9dd |
&& (lfp1->lfItalic != 0) == (lfp2->lfItalic != 0)
|
|
Packit |
0ec9dd |
&& lfp1->lfWeight == lfp2->lfWeight
|
|
Packit |
0ec9dd |
&& lfp1->lfOrientation == lfp2->lfOrientation
|
|
Packit |
0ec9dd |
&& lfp1->lfEscapement == lfp2->lfEscapement
|
|
Packit |
0ec9dd |
&& lfp1->lfWidth == lfp2->lfWidth
|
|
Packit |
0ec9dd |
&& lfp1->lfHeight == lfp2->lfHeight);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_new:
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Creates a font cache.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: The new font cache. This must be freed with
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_free().
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
PangoWin32FontCache *
|
|
Packit |
0ec9dd |
pango_win32_font_cache_new (void)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PangoWin32FontCache *cache;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache = g_slice_new (PangoWin32FontCache);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache->forward = g_hash_table_new (logfontw_hash, logfontw_equal);
|
|
Packit |
0ec9dd |
cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache->mru = NULL;
|
|
Packit |
0ec9dd |
cache->mru_tail = NULL;
|
|
Packit |
0ec9dd |
cache->mru_count = 0;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return cache;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cache_entry_unref (PangoWin32FontCache *cache,
|
|
Packit |
0ec9dd |
CacheEntry *entry)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
if (g_atomic_int_dec_and_test (&entry->ref_count))
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PING (("removing cache entry %p", entry->hfont));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_hash_table_remove (cache->forward, &entry->logfontw);
|
|
Packit |
0ec9dd |
g_hash_table_remove (cache->back, entry->hfont);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
free_cache_entry (NULL, entry, cache);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_load:
|
|
Packit |
0ec9dd |
* @cache: a #PangoWin32FontCache
|
|
Packit |
0ec9dd |
* @logfont: a pointer to a LOGFONTA structure describing the font to load.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Creates a HFONT from a LOGFONTA. The
|
|
Packit |
0ec9dd |
* result may be newly loaded, or it may have been previously
|
|
Packit |
0ec9dd |
* stored
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: (nullable): The font structure, or %NULL if the font
|
|
Packit |
0ec9dd |
* could not be loaded. In order to free this structure, you must call
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_unload().
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
HFONT
|
|
Packit |
0ec9dd |
pango_win32_font_cache_load (PangoWin32FontCache *cache,
|
|
Packit |
0ec9dd |
const LOGFONTA *lfp)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
LOGFONTW lf;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* We know that the lfFaceName is the last member in the structs */
|
|
Packit |
0ec9dd |
*(LOGFONTA *)&lf = *lfp;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
|
|
Packit |
0ec9dd |
lfp->lfFaceName, -1,
|
|
Packit |
0ec9dd |
lf.lfFaceName, G_N_ELEMENTS (lf.lfFaceName)))
|
|
Packit |
0ec9dd |
return NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return pango_win32_font_cache_loadw (cache, &lf);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_loadw:
|
|
Packit |
0ec9dd |
* @cache: a #PangoWin32FontCache
|
|
Packit |
0ec9dd |
* @logfont: a pointer to a LOGFONTW structure describing the font to load.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Creates a HFONT from a LOGFONTW. The
|
|
Packit |
0ec9dd |
* result may be newly loaded, or it may have been previously
|
|
Packit |
0ec9dd |
* stored
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: (nullable): The font structure, or %NULL if the font
|
|
Packit |
0ec9dd |
* could not be loaded. In order to free this structure, you must call
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_unload().
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Since: 1.16
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
HFONT
|
|
Packit |
0ec9dd |
pango_win32_font_cache_loadw (PangoWin32FontCache *cache,
|
|
Packit |
0ec9dd |
const LOGFONTW *lfp)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CacheEntry *entry;
|
|
Packit |
0ec9dd |
LOGFONTW lf;
|
|
Packit |
0ec9dd |
HFONT hfont;
|
|
Packit |
0ec9dd |
int tries;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_return_val_if_fail (cache != NULL, NULL);
|
|
Packit |
0ec9dd |
g_return_val_if_fail (lfp != NULL, NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry = g_hash_table_lookup (cache->forward, lfp);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (entry)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_atomic_int_inc (&entry->ref_count);
|
|
Packit |
0ec9dd |
PING (("increased refcount for cache entry %p: %d", entry->hfont, entry->ref_count));
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
BOOL font_smoothing;
|
|
Packit |
0ec9dd |
lf = *lfp;
|
|
Packit |
0ec9dd |
SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0);
|
|
Packit |
0ec9dd |
/* If on XP or better, try to use ClearType if the global system
|
|
Packit |
0ec9dd |
* settings ask for it.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
if (font_smoothing &&
|
|
Packit |
0ec9dd |
(_pango_win32_os_version_info.dwMajorVersion > 5 ||
|
|
Packit |
0ec9dd |
(_pango_win32_os_version_info.dwMajorVersion == 5 &&
|
|
Packit |
0ec9dd |
_pango_win32_os_version_info.dwMinorVersion >= 1)))
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
UINT smoothing_type;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#ifndef SPI_GETFONTSMOOTHINGTYPE
|
|
Packit |
0ec9dd |
#define SPI_GETFONTSMOOTHINGTYPE 0x200a
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifndef FE_FONTSMOOTHINGCLEARTYPE
|
|
Packit |
0ec9dd |
#define FE_FONTSMOOTHINGCLEARTYPE 2
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifndef CLEARTYPE_QUALITY
|
|
Packit |
0ec9dd |
#define CLEARTYPE_QUALITY 5
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE, 0, &smoothing_type, 0);
|
|
Packit |
0ec9dd |
lf.lfQuality =
|
|
Packit |
0ec9dd |
(font_smoothing ?
|
|
Packit |
0ec9dd |
(smoothing_type == FE_FONTSMOOTHINGCLEARTYPE ?
|
|
Packit |
0ec9dd |
CLEARTYPE_QUALITY : ANTIALIASED_QUALITY) :
|
|
Packit |
0ec9dd |
DEFAULT_QUALITY);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
lf.lfQuality = (font_smoothing ? ANTIALIASED_QUALITY : DEFAULT_QUALITY);
|
|
Packit |
0ec9dd |
lf.lfCharSet = DEFAULT_CHARSET;
|
|
Packit |
0ec9dd |
for (tries = 0; ; tries++)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PING (("... trying CreateFontIndirect "
|
|
Packit |
0ec9dd |
"height=%ld,width=%ld,escapement=%ld,orientation=%ld,"
|
|
Packit |
0ec9dd |
"weight=%ld,%s%s%s"
|
|
Packit |
0ec9dd |
"charset=%d,outprecision=%d,clipprecision=%d,"
|
|
Packit |
0ec9dd |
"quality=%d,pitchandfamily=%#.02x,facename=\"%S\")",
|
|
Packit |
0ec9dd |
lf.lfHeight, lf.lfWidth, lf.lfEscapement, lf.lfOrientation,
|
|
Packit |
0ec9dd |
lf.lfWeight, (lf.lfItalic ? "italic," : ""),
|
|
Packit |
0ec9dd |
(lf.lfUnderline ? "underline," : ""),
|
|
Packit |
0ec9dd |
(lf.lfStrikeOut ? "strikeout," : ""),
|
|
Packit |
0ec9dd |
lf.lfCharSet, lf.lfOutPrecision, lf.lfClipPrecision,
|
|
Packit |
0ec9dd |
lf.lfQuality, lf.lfPitchAndFamily, lf.lfFaceName));
|
|
Packit |
0ec9dd |
hfont = CreateFontIndirectW (&lf);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (hfont != NULL)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PING (("Success! hfont=%p", hfont));
|
|
Packit |
0ec9dd |
break;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* If we fail, try some similar fonts often found on Windows. */
|
|
Packit |
0ec9dd |
if (tries == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
gchar *p = g_utf16_to_utf8 (lf.lfFaceName, -1, NULL, NULL, NULL);
|
|
Packit |
0ec9dd |
if (!p)
|
|
Packit |
0ec9dd |
; /* Nothing */
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "helvetica") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"arial");
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "new century schoolbook") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"century schoolbook");
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "courier") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"courier new");
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "lucida") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"lucida sans unicode");
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "lucidatypewriter") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"lucida console");
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "times") == 0)
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"times new roman");
|
|
Packit |
0ec9dd |
g_free (p);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else if (tries == 1)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
gchar *p = g_utf16_to_utf8 (lf.lfFaceName, -1, NULL, NULL, NULL);
|
|
Packit |
0ec9dd |
if (!p)
|
|
Packit |
0ec9dd |
; /* Nothing */
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "courier") == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"");
|
|
Packit |
0ec9dd |
lf.lfPitchAndFamily |= FF_MODERN;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "times new roman") == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"");
|
|
Packit |
0ec9dd |
lf.lfPitchAndFamily |= FF_ROMAN;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else if (g_ascii_strcasecmp (p, "helvetica") == 0
|
|
Packit |
0ec9dd |
|| g_ascii_strcasecmp (p, "lucida") == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"");
|
|
Packit |
0ec9dd |
lf.lfPitchAndFamily |= FF_SWISS;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
wcscpy (lf.lfFaceName, L"");
|
|
Packit |
0ec9dd |
lf.lfPitchAndFamily = (lf.lfPitchAndFamily & 0x0F) | FF_DONTCARE;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
g_free (p);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
break;
|
|
Packit |
0ec9dd |
tries++;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (!hfont)
|
|
Packit |
0ec9dd |
return NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry = g_slice_new (CacheEntry);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry->logfontw = lf;
|
|
Packit |
0ec9dd |
entry->hfont = hfont;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry->ref_count = 1;
|
|
Packit |
0ec9dd |
entry->mru = NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_hash_table_insert (cache->forward, &entry->logfontw, entry);
|
|
Packit |
0ec9dd |
g_hash_table_insert (cache->back, entry->hfont, entry);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (entry->mru)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
if (cache->mru_count > 1 && entry->mru->prev)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
/* Move to the head of the mru list */
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (entry->mru == cache->mru_tail)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cache->mru_tail = cache->mru_tail->prev;
|
|
Packit |
0ec9dd |
cache->mru_tail->next = NULL;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
entry->mru->prev->next = entry->mru->next;
|
|
Packit |
0ec9dd |
entry->mru->next->prev = entry->mru->prev;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry->mru->next = cache->mru;
|
|
Packit |
0ec9dd |
entry->mru->prev = NULL;
|
|
Packit |
0ec9dd |
cache->mru->prev = entry->mru;
|
|
Packit |
0ec9dd |
cache->mru = entry->mru;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_atomic_int_inc (&entry->ref_count);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Insert into the mru list */
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (cache->mru_count == CACHE_SIZE)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CacheEntry *old_entry = cache->mru_tail->data;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache->mru_tail = cache->mru_tail->prev;
|
|
Packit |
0ec9dd |
cache->mru_tail->next = NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_list_free_1 (old_entry->mru);
|
|
Packit |
0ec9dd |
old_entry->mru = NULL;
|
|
Packit |
0ec9dd |
cache_entry_unref (cache, old_entry);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
cache->mru_count++;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache->mru = g_list_prepend (cache->mru, entry);
|
|
Packit |
0ec9dd |
if (!cache->mru_tail)
|
|
Packit |
0ec9dd |
cache->mru_tail = cache->mru;
|
|
Packit |
0ec9dd |
entry->mru = cache->mru;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return entry->hfont;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_win32_font_cache_unload:
|
|
Packit |
0ec9dd |
* @cache: a #PangoWin32FontCache
|
|
Packit |
0ec9dd |
* @hfont: the HFONT to unload
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Frees a font structure previously loaded with pango_win32_font_cache_load().
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
void
|
|
Packit |
0ec9dd |
pango_win32_font_cache_unload (PangoWin32FontCache *cache,
|
|
Packit |
0ec9dd |
HFONT hfont)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CacheEntry *entry;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_return_if_fail (cache != NULL);
|
|
Packit |
0ec9dd |
g_return_if_fail (hfont != NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
entry = g_hash_table_lookup (cache->back, hfont);
|
|
Packit |
0ec9dd |
g_return_if_fail (entry != NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cache_entry_unref (cache, entry);
|
|
Packit |
0ec9dd |
}
|