fix glyph-exists? for label
svn: r1601
This commit is contained in:
parent
b4a2f0570e
commit
029e7e85a3
|
@ -50,6 +50,9 @@ class wxFont: public wxbFont
|
|||
|
||||
Bool GlyphAvailableNow(int c, HDC hdc, int screen_font);
|
||||
wxFont *Substitute(int c, HDC hdc, int screen_font);
|
||||
|
||||
Bool ScreenGlyphAvailabilityCached(int c, Bool for_label, Bool *avail);
|
||||
void CacheScreenGlyphAvailability(int c, Bool for_label, Bool avail);
|
||||
};
|
||||
|
||||
class wxColourMap: public wxObject
|
||||
|
|
|
@ -34,6 +34,8 @@ int pen_count, brush_count, font_count, bitmap_count;
|
|||
# define COUNT_M(c)
|
||||
#endif
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
void RegisterGDIObject(HANDLE x);
|
||||
void DeleteRegisteredGDIObject(HANDLE x);
|
||||
|
||||
|
@ -196,6 +198,7 @@ static int glyph_exists_in_selected_font(HDC hdc, int c)
|
|||
typedef struct {
|
||||
HDC hdc;
|
||||
int c;
|
||||
int just_face;
|
||||
int just_tt;
|
||||
wchar_t *face;
|
||||
} GlyphFindData;
|
||||
|
@ -214,7 +217,10 @@ static int CALLBACK glyph_exists(ENUMLOGFONTW FAR* lpelf,
|
|||
/* This font might work... */
|
||||
int ok = 1;
|
||||
|
||||
if (gfd->just_tt)
|
||||
if (gfd->just_face)
|
||||
ok = !memcmp(gfd->face, lpelf->elfLogFont.lfFaceName,
|
||||
wx_wstrlen(gfd->face));
|
||||
else if (gfd->just_tt)
|
||||
ok = (type == TRUETYPE_FONTTYPE);
|
||||
else
|
||||
ok = (type != TRUETYPE_FONTTYPE);
|
||||
|
@ -242,7 +248,7 @@ static int CALLBACK glyph_exists(ENUMLOGFONTW FAR* lpelf,
|
|||
|
||||
DeleteObject(cfont);
|
||||
|
||||
if (gfd->face) {
|
||||
if (gfd->face && !gfd->just_face) {
|
||||
memcpy(gfd->face, lpelf->elfLogFont.lfFaceName, LF_FACESIZE * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
|
@ -263,6 +269,7 @@ Bool wxFont::GlyphAvailable(int c, HDC hdc, int screen_font)
|
|||
gfd.hdc = hdc;
|
||||
gfd.c = c;
|
||||
gfd.face = NULL;
|
||||
gfd.just_face = 0;
|
||||
|
||||
gfd.just_tt = 1;
|
||||
if (!EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW)glyph_exists, (LPARAM)&gfd))
|
||||
|
@ -275,6 +282,36 @@ Bool wxFont::GlyphAvailable(int c, HDC hdc, int screen_font)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Bool wxFont::ScreenGlyphAvailabilityCached(int c, Bool for_label, Bool *avail)
|
||||
{
|
||||
if (glyph_cache) {
|
||||
Scheme_Hash_Table *ht;
|
||||
Scheme_Object *v;
|
||||
ht = (Scheme_Hash_Table *)glyph_cache;
|
||||
if (for_label)
|
||||
c = -(c + 1);
|
||||
v = scheme_hash_get(ht, scheme_make_integer(c));
|
||||
if (v) {
|
||||
*avail = SCHEME_TRUEP(v);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void wxFont::CacheScreenGlyphAvailability(int c, Bool for_label, Bool avail)
|
||||
{
|
||||
Scheme_Hash_Table *ht;
|
||||
ht = (Scheme_Hash_Table *)glyph_cache;
|
||||
if (!ht) {
|
||||
ht = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||
glyph_cache = ht;
|
||||
}
|
||||
if (for_label)
|
||||
c = -(c + 1);
|
||||
scheme_hash_set(ht, scheme_make_integer(c), avail ? scheme_true : scheme_false);
|
||||
}
|
||||
|
||||
Bool wxFont::GlyphAvailableNow(int c, HDC hdc, int screen_font)
|
||||
{
|
||||
Bool avail;
|
||||
|
@ -282,26 +319,15 @@ Bool wxFont::GlyphAvailableNow(int c, HDC hdc, int screen_font)
|
|||
if (redirect)
|
||||
return redirect->GlyphAvailableNow(c, hdc, screen_font);
|
||||
|
||||
if (screen_font && glyph_cache) {
|
||||
Scheme_Hash_Table *ht;
|
||||
Scheme_Object *v;
|
||||
ht = (Scheme_Hash_Table *)glyph_cache;
|
||||
v = scheme_hash_get(ht, scheme_make_integer(c));
|
||||
if (v) {
|
||||
return SCHEME_TRUEP(v);
|
||||
}
|
||||
if (screen_font) {
|
||||
if (ScreenGlyphAvailabilityCached(c, 0, &avail))
|
||||
return avail;
|
||||
}
|
||||
|
||||
avail = glyph_exists_in_selected_font(hdc, c);
|
||||
|
||||
if (screen_font) {
|
||||
Scheme_Hash_Table *ht;
|
||||
ht = (Scheme_Hash_Table *)glyph_cache;
|
||||
if (!ht) {
|
||||
ht = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||
glyph_cache = ht;
|
||||
}
|
||||
scheme_hash_set(ht, scheme_make_integer(c), avail ? scheme_true : scheme_false);
|
||||
CacheScreenGlyphAvailability(c, 0, avail);
|
||||
}
|
||||
|
||||
return avail;
|
||||
|
@ -310,11 +336,14 @@ Bool wxFont::GlyphAvailableNow(int c, HDC hdc, int screen_font)
|
|||
Bool wxFont::ScreenGlyphAvailable(int c, Bool for_label)
|
||||
{
|
||||
HDC hdc;
|
||||
Bool r;
|
||||
Bool r, avail;
|
||||
|
||||
if (redirect)
|
||||
return redirect->ScreenGlyphAvailable(c, for_label);
|
||||
|
||||
if (ScreenGlyphAvailabilityCached(c, for_label, &avail))
|
||||
return avail;
|
||||
|
||||
hdc = ::GetDC(NULL);
|
||||
|
||||
if (for_label) {
|
||||
|
@ -324,12 +353,85 @@ Bool wxFont::ScreenGlyphAvailable(int c, Bool for_label)
|
|||
old = (HFONT)::SelectObject(hdc, cfont);
|
||||
r = glyph_exists_in_selected_font(hdc, c);
|
||||
::SelectObject(hdc, old);
|
||||
|
||||
if (!r) {
|
||||
/* Look for font links */
|
||||
HKEY key;
|
||||
DWORD nlen, vlen, vlen2;
|
||||
wchar_t value_name[256], *value;
|
||||
char *face;
|
||||
face = wxTheFontNameDirectory->GetScreenName(fontid, weight, style);
|
||||
if (face) {
|
||||
if (ERROR_SUCCESS
|
||||
== RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",
|
||||
0, KEY_READ,
|
||||
&key)) {
|
||||
int i = 0;
|
||||
nlen = 256;
|
||||
vlen = 0;
|
||||
while (ERROR_SUCCESS
|
||||
== RegEnumValueW(key, i, value_name, &nlen,
|
||||
NULL, NULL, NULL, &vlen)) {
|
||||
if (!strcmp(face, wxNARROW_STRING(value_name))) {
|
||||
value = (wchar_t *)(new WXGC_ATOMIC char[vlen]);
|
||||
vlen2 = vlen;
|
||||
nlen++;
|
||||
if (ERROR_SUCCESS
|
||||
== RegEnumValueW(key, i, value_name, &nlen,
|
||||
NULL, NULL, (BYTE *)value, &vlen2)) {
|
||||
if (vlen2 == vlen) {
|
||||
int j, k;
|
||||
vlen >>= 1;
|
||||
r = 0;
|
||||
for (j = 0; j < vlen; j++) {
|
||||
if (value[j] == ',') {
|
||||
j++;
|
||||
for (k = j; k < vlen; k++) {
|
||||
if (!value[k])
|
||||
break;
|
||||
}
|
||||
/* Range from j (inclusive) to k (exclusive) is a font name */
|
||||
{
|
||||
GlyphFindData gfd;
|
||||
wchar_t *face;
|
||||
face = (wchar_t *)(new WXGC_ATOMIC char[(k - j + 1) * sizeof(wchar_t)]);
|
||||
memcpy(face, value + j, (k - j) * sizeof(wchar_t));
|
||||
face[k - j] = 0;
|
||||
|
||||
gfd.hdc = hdc;
|
||||
gfd.c = c;
|
||||
gfd.face = face;
|
||||
gfd.just_tt = 0;
|
||||
gfd.just_face = 1;
|
||||
|
||||
if (!EnumFontFamiliesW(hdc, NULL, (FONTENUMPROCW)glyph_exists, (LPARAM)&gfd)) {
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r = GlyphAvailable(c, hdc, 1);
|
||||
}
|
||||
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
CacheScreenGlyphAvailability(c, for_label, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -359,7 +461,8 @@ wxFont *wxFont::Substitute(int c, HDC dc, Bool screen_font)
|
|||
gfd.hdc = dc;
|
||||
gfd.c = c;
|
||||
gfd.face = facebuf;
|
||||
|
||||
gfd.just_face = 0;
|
||||
|
||||
gfd.just_tt = 1;
|
||||
found = !EnumFontFamiliesW(dc, NULL, (FONTENUMPROCW)glyph_exists, (LPARAM)&gfd);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user