diff options
author | nyamatongwe <unknown> | 2000-06-29 06:57:24 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2000-06-29 06:57:24 +0000 |
commit | 46299d2f6ad3b01670f8936f54a885a7e1b3562c (patch) | |
tree | c1ca0aeb42ce8e2e0ab1c326025a0f0a50e34977 /win32/PlatWin.cxx | |
parent | e5b6aac51dfa0b48a1c283127e7c4d6e0c2f18d9 (diff) | |
download | scintilla-mirror-46299d2f6ad3b01670f8936f54a885a7e1b3562c.tar.gz |
Added font caching.
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r-- | win32/PlatWin.cxx | 123 |
1 files changed, 113 insertions, 10 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index a6dfb8dd6..7e91f42a2 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -121,6 +121,105 @@ void Palette::Allocate(Window &) { } } +void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, int size, bool bold, bool italic) { + memset(&lf, 0, sizeof(lf)); + // The negative is to allow for leading + lf.lfHeight = -(abs(size)); + lf.lfWeight = bold ? FW_BOLD : FW_NORMAL; + lf.lfItalic = static_cast<BYTE>(italic ? 1 : 0); + lf.lfCharSet = characterSet; + strcpy(lf.lfFaceName, faceName); +} + +// Create a hash from the parameters for a font to allow easy checking for identity. +// If one font is the same as another, its hash will be the same, but if the hash is the +// same then they may still be different. +int HashFont(const char *faceName, int characterSet, int size, bool bold, bool italic) { + return + size ^ + (characterSet << 10) ^ + (bold ? 0x10000000 : 0) ^ + (italic ? 0x20000000 : 0) ^ + faceName[0]; +} + +class FontCached : Font { + FontCached *next; + int usage; + LOGFONT lf; + int hash; + FontCached(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_); + ~FontCached() {} + bool SameAs(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_); + virtual void Release(); + + static FontCached *first; +public: + static FontID FindOrCreate(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_); + static void ReleaseId(FontID id_); +}; + +FontCached *FontCached::first = 0; + +FontCached::FontCached(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_) : + next(0), usage(0), hash(0) { + SetLogFont(lf, faceName_, characterSet_, size_, bold_, italic_); + hash = HashFont(faceName_, characterSet_, size_, bold_, italic_); + id = ::CreateFontIndirect(&lf); + usage = 1; +} + +bool FontCached::SameAs(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_) { + return + (lf.lfHeight == -(abs(size_))) && + (lf.lfWeight == (bold_ ? FW_BOLD : FW_NORMAL)) && + (lf.lfItalic == static_cast<BYTE>(italic_ ? 1 : 0)) && + (lf.lfCharSet == characterSet_) && + 0 == strcmp(lf.lfFaceName,faceName_); +} + +void FontCached::Release() { + if (id) + ::DeleteObject(id); + id = 0; +} + +FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_) { + int hashFind = HashFont(faceName_, characterSet_, size_, bold_, italic_); + for (FontCached *cur=first; cur; cur=cur->next) { + if ((cur->hash == hashFind) && + cur->SameAs(faceName_, characterSet_, size_, bold_, italic_)) { + cur->usage++; + return cur->id; + } + } + FontCached *fc = new FontCached(faceName_, characterSet_, size_, bold_, italic_); + if (fc) { + fc->next = first; + first = fc; + return fc->id; + } else { + return 0; + } +} + +void FontCached::ReleaseId(FontID id_) { + FontCached **pcur=&first; + for (FontCached *cur=first; cur; cur=cur->next) { + if (cur->id == id_) { + cur->usage--; + if (cur->usage == 0) { + *pcur = cur->next; + cur->Release(); + cur->next = 0; + delete cur; + } + return; + } + pcur=&cur->next; + } +} + Font::Font() { id = 0; } @@ -128,24 +227,28 @@ Font::Font() { Font::~Font() { } +#define FONTS_CACHED + void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic) { +#ifndef FONTS_CACHED Release(); LOGFONT lf; - memset(&lf, 0, sizeof(lf)); - // The negative is to allow for leading - lf.lfHeight = -(abs(size)); - lf.lfWeight = bold ? FW_BOLD : FW_NORMAL; - lf.lfItalic = static_cast<BYTE>(italic ? 1 : 0); - lf.lfCharSet = characterSet; - strcpy(lf.lfFaceName, faceName); - - id = ::CreateFontIndirect(&lf); + SetLogFont(lf, faceName, characterSet, size, bold, italic); + id = ::CreateFontIndirect(&lf); +#else + id = FontCached::FindOrCreate(faceName, characterSet, size, bold, italic); +#endif } void Font::Release() { +#ifndef FONTS_CACHED if (id) ::DeleteObject(id); +#else + if (id) + FontCached::ReleaseId(id); +#endif id = 0; } @@ -721,7 +824,7 @@ int Platform::Maximum(int a, int b) { return b; } -//#define TRACE +#define TRACE #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) { |