aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/PlatWin.cxx
diff options
context:
space:
mode:
authornyamatongwe <unknown>2000-06-29 06:57:24 +0000
committernyamatongwe <unknown>2000-06-29 06:57:24 +0000
commit46299d2f6ad3b01670f8936f54a885a7e1b3562c (patch)
treec1ca0aeb42ce8e2e0ab1c326025a0f0a50e34977 /win32/PlatWin.cxx
parente5b6aac51dfa0b48a1c283127e7c4d6e0c2f18d9 (diff)
downloadscintilla-mirror-46299d2f6ad3b01670f8936f54a885a7e1b3562c.tar.gz
Added font caching.
Diffstat (limited to 'win32/PlatWin.cxx')
-rw-r--r--win32/PlatWin.cxx123
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, ...) {