mirror of
https://github.com/CDAGaming/blizzget
synced 2025-11-09 19:15:58 +03:00
172 lines
5.4 KiB
C++
172 lines
5.4 KiB
C++
#include "fontsys.h"
|
|
#include <algorithm>
|
|
|
|
FontSys FontSys::instance;
|
|
|
|
//#define MKSIZE(s) (-MulDiv(s,instance.logPixelsY,72))
|
|
#define MKSIZE(s) (-(s))
|
|
|
|
FontSys::FontStruct::FontStruct(LOGFONT const& lf) {
|
|
font = CreateFontIndirect(&lf);
|
|
face = lf.lfFaceName;
|
|
size = lf.lfHeight;
|
|
flags = 0;
|
|
if (lf.lfWeight > FW_NORMAL) flags |= FONT_BOLD;
|
|
if (lf.lfItalic) flags |= FONT_ITALIC;
|
|
if (lf.lfUnderline) flags |= FONT_UNDERLINE;
|
|
if (lf.lfStrikeOut) flags |= FONT_STRIKEOUT;
|
|
}
|
|
|
|
bool operator<(FontSys::FontStruct const& lhs, FontSys::FontStruct const& rhs) {
|
|
if (lhs.size != rhs.size) return lhs.size < rhs.size;
|
|
if (lhs.flags != rhs.flags) return lhs.flags < rhs.flags;
|
|
return lhs.face < rhs.face;
|
|
}
|
|
bool operator==(FontSys::FontStruct const& lhs, FontSys::FontStruct const& rhs) {
|
|
if (lhs.size != rhs.size) return false;
|
|
if (lhs.flags != rhs.flags) return false;
|
|
return lhs.face == rhs.face;
|
|
}
|
|
|
|
FontSys::FontSys() {
|
|
LOGFONT lf;
|
|
memset (&lf, 0, sizeof lf);
|
|
lf.lfHeight = -11;
|
|
lf.lfWeight = FW_NORMAL;
|
|
strcpy(lf.lfFaceName, "MS Shell Dlg 2");
|
|
lf.lfCharSet = DEFAULT_CHARSET;
|
|
|
|
fonts.emplace_back(lf);
|
|
|
|
hDC = CreateCompatibleDC(NULL);
|
|
logPixelsY = GetDeviceCaps(hDC, LOGPIXELSY);
|
|
}
|
|
|
|
FontSys::~FontSys() {
|
|
DeleteDC(hDC);
|
|
}
|
|
|
|
HFONT FontSys::getSysFont() {
|
|
return instance.fonts[0].font;
|
|
}
|
|
HFONT FontSys::_getFont(int height, std::string const& face, int flags) {
|
|
FontStruct fs;
|
|
fs.size = height;
|
|
fs.flags = flags;
|
|
fs.face = face;
|
|
|
|
auto pos = std::lower_bound(fonts.begin() + 1, fonts.end(), fs);
|
|
if (pos != fonts.end() && *pos == fs) {
|
|
return pos->font;
|
|
}
|
|
|
|
LOGFONT lf;
|
|
getLogFont(&lf, -height, face, flags);
|
|
return fonts.emplace(pos, lf)->font;
|
|
}
|
|
|
|
void FontSys::getLogFont(LOGFONT* lf, int size, std::string const& face, int flags) {
|
|
GetObject(instance.fonts[0].font, sizeof(LOGFONT), lf);
|
|
lf->lfHeight = MKSIZE(size);
|
|
strcpy(lf->lfFaceName, face.c_str());
|
|
lf->lfWeight = (flags & FONT_BOLD ? FW_BOLD : FW_NORMAL);
|
|
lf->lfItalic = (flags & FONT_ITALIC ? TRUE : FALSE);
|
|
lf->lfUnderline = (flags & FONT_UNDERLINE ? TRUE : FALSE);
|
|
lf->lfStrikeOut = (flags & FONT_STRIKEOUT ? TRUE : FALSE);
|
|
}
|
|
HFONT FontSys::getFont(int size, std::string const& face, int flags) {
|
|
return instance._getFont(MKSIZE(size), face, flags);
|
|
}
|
|
HFONT FontSys::getFont(int size, int flags) {
|
|
return instance._getFont(MKSIZE(size), instance.fonts[0].face, flags);
|
|
}
|
|
HFONT FontSys::changeSize(int size, HFONT oldFont) {
|
|
if (oldFont == NULL) oldFont = getSysFont();
|
|
LOGFONT lf;
|
|
GetObject(oldFont, sizeof lf, &lf);
|
|
int flags = 0;
|
|
if (lf.lfWidth > FW_NORMAL) flags |= FONT_BOLD;
|
|
if (lf.lfItalic) flags |= FONT_ITALIC;
|
|
if (lf.lfUnderline) flags |= FONT_UNDERLINE;
|
|
if (lf.lfStrikeOut) flags |= FONT_STRIKEOUT;
|
|
return instance._getFont(MKSIZE(size), lf.lfFaceName, flags);
|
|
}
|
|
HFONT FontSys::changeFlags(int flags, HFONT oldFont) {
|
|
if (oldFont == NULL) oldFont = getSysFont();
|
|
LOGFONT lf;
|
|
GetObject(oldFont, sizeof lf, &lf);
|
|
return instance._getFont(lf.lfHeight, lf.lfFaceName, flags);
|
|
}
|
|
|
|
SIZE FontSys::getTextSize(HFONT font, std::string const& text) {
|
|
SIZE sz;
|
|
SelectObject(instance.hDC, font);
|
|
GetTextExtentPoint32(instance.hDC, text.c_str(), text.length(), &sz);
|
|
return sz;
|
|
}
|
|
SIZE FontSys::getTextSize(HFONT font, char const* text, int length) {
|
|
SIZE sz;
|
|
SelectObject(instance.hDC, font);
|
|
GetTextExtentPoint32(instance.hDC, text, length, &sz);
|
|
return sz;
|
|
}
|
|
int FontSys::getMTextHeight(HFONT font, int width, std::string const& text) {
|
|
SIZE sz;
|
|
SelectObject(instance.hDC, font);
|
|
std::string word;
|
|
std::string curline;
|
|
int height = 0;
|
|
for (int i = 0; i <= text.length (); i++) {
|
|
if (text[i] && text[i] != '\n' && !isspace((uint8)text[i])) {
|
|
word += text[i];
|
|
}
|
|
if (text[i] == 0 || isspace((uint8) text[i])) {
|
|
std::string tmp = curline + word;
|
|
GetTextExtentPoint32(instance.hDC, tmp.c_str(), tmp.length(), &sz);
|
|
int wd = sz.cx;
|
|
if (text[i] == '\n' || (wd > width && !curline.empty())) {
|
|
GetTextExtentPoint32(instance.hDC, curline.c_str(), curline.length(), &sz);
|
|
height += sz.cy;
|
|
curline.clear();
|
|
}
|
|
curline += word;
|
|
if (text[i]) curline += text[i];
|
|
word.clear();
|
|
}
|
|
}
|
|
if (!curline.empty()) {
|
|
GetTextExtentPoint32(instance.hDC, curline.c_str(), curline.length(), &sz);
|
|
height += sz.cy;
|
|
}
|
|
return height;
|
|
}
|
|
|
|
int FontSys::getFlags(HFONT font) {
|
|
if (font == NULL) font = getSysFont();
|
|
LOGFONT lf;
|
|
GetObject(font, sizeof lf, &lf);
|
|
int flags = 0;
|
|
if (lf.lfWidth > FW_NORMAL) flags |= FONT_BOLD;
|
|
if (lf.lfItalic) flags |= FONT_ITALIC;
|
|
if (lf.lfUnderline) flags |= FONT_UNDERLINE;
|
|
if (lf.lfStrikeOut) flags |= FONT_STRIKEOUT;
|
|
return flags;
|
|
}
|
|
|
|
void FontSys::setFontName(HFONT hFont, std::string const& name) {
|
|
instance.byName[name] = hFont;
|
|
}
|
|
HFONT FontSys::getFontByName(std::string const& name) {
|
|
auto it = instance.byName.find(name);
|
|
return (it == instance.byName.end() ? instance.fonts[0].font : it->second);
|
|
}
|
|
|
|
HFONT FontSys::getFont(LOGFONT const& lf) {
|
|
int flags = 0;
|
|
if (lf.lfWidth > FW_NORMAL) flags |= FONT_BOLD;
|
|
if (lf.lfItalic) flags |= FONT_ITALIC;
|
|
if (lf.lfUnderline) flags |= FONT_UNDERLINE;
|
|
if (lf.lfStrikeOut) flags |= FONT_STRIKEOUT;
|
|
return instance._getFont(lf.lfHeight, lf.lfFaceName, flags);
|
|
}
|