mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
CtrlCore: ReSkin (former SyncCh) now public, refactored SetStdFont handling
git-svn-id: svn://ultimatepp.org/upp/trunk@3894 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
0a11740d8f
commit
fc74aa11af
6 changed files with 434 additions and 422 deletions
|
|
@ -548,7 +548,6 @@ bool Ctrl::IsOcxChild()
|
|||
|
||||
Ctrl::Ctrl() {
|
||||
GuiLock __;
|
||||
SyncCh();
|
||||
LLOG("Ctrl::Ctrl");
|
||||
GuiPlatformConstruct();
|
||||
destroying = false;
|
||||
|
|
@ -710,7 +709,7 @@ Size Ctrl::Csize;
|
|||
void InitRichTextZoom()
|
||||
{
|
||||
SetRichTextStdScreenZoom(Ctrl::HorzLayoutZoom(96), 600);
|
||||
ChInvalidate();
|
||||
Ctrl::ReSkin();
|
||||
}
|
||||
|
||||
void Ctrl::Csizeinit()
|
||||
|
|
@ -732,14 +731,14 @@ void Ctrl::SetZoomSize(Size sz, Size bsz)
|
|||
GuiLock __;
|
||||
Csize = sz;
|
||||
Dsize = bsz;
|
||||
ChInvalidate();
|
||||
ReSkin();
|
||||
}
|
||||
|
||||
void Ctrl::NoLayoutZoom()
|
||||
{
|
||||
GuiLock __;
|
||||
Csize = Dsize = Size(1, 1);
|
||||
ChInvalidate();
|
||||
ReSkin();
|
||||
}
|
||||
|
||||
void Ctrl::GetZoomRatio(Size& m, Size& d)
|
||||
|
|
@ -880,6 +879,12 @@ void Modality::End()
|
|||
active = NULL;
|
||||
}
|
||||
|
||||
extern void (*whenSetStdFont)();
|
||||
|
||||
INITBLOCK {
|
||||
whenSetStdFont = &Ctrl::ReSkin;
|
||||
}
|
||||
|
||||
void (*s_chdefault)();
|
||||
|
||||
void (*Ctrl::skin)();
|
||||
|
|
@ -895,17 +900,16 @@ void Ctrl::SetSkin(void (*_skin)())
|
|||
{
|
||||
GuiLock __;
|
||||
skin = _skin;
|
||||
ChSync();
|
||||
Vector<Ctrl *> ctrl = GetTopCtrls();
|
||||
for(int i = 0; i < ctrl.GetCount(); i++) {
|
||||
ctrl[i]->RefreshLayoutDeep();
|
||||
ctrl[i]->RefreshFrame();
|
||||
}
|
||||
ReSkin();
|
||||
}
|
||||
|
||||
void Ctrl::ChSync()
|
||||
void Ctrl::ReSkin()
|
||||
{
|
||||
GuiLock __;
|
||||
static int lock;
|
||||
if(lock)
|
||||
return;
|
||||
lock++;
|
||||
if(s_chdefault)
|
||||
(*s_chdefault)();
|
||||
if(skin)
|
||||
|
|
@ -913,12 +917,12 @@ void Ctrl::ChSync()
|
|||
Csize.cx = Dsize.cx = 0;
|
||||
Csizeinit();
|
||||
ChFinish();
|
||||
}
|
||||
|
||||
void Ctrl::SyncCh()
|
||||
{
|
||||
if(ChIsInvalidated())
|
||||
ChSync();
|
||||
Vector<Ctrl *> ctrl = GetTopCtrls();
|
||||
for(int i = 0; i < ctrl.GetCount(); i++) {
|
||||
ctrl[i]->RefreshLayoutDeep();
|
||||
ctrl[i]->RefreshFrame();
|
||||
}
|
||||
lock--;
|
||||
}
|
||||
|
||||
void Ctrl::Xmlize(XmlIO xml)
|
||||
|
|
|
|||
|
|
@ -497,9 +497,6 @@ private:
|
|||
|
||||
void RemoveChild0(Ctrl *q);
|
||||
|
||||
static void SyncCh();
|
||||
static void ChSync();
|
||||
|
||||
static int FindMoveCtrl(const VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x);
|
||||
static MoveCtrl *FindMoveCtrlPtr(VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x);
|
||||
|
||||
|
|
@ -1221,6 +1218,8 @@ public:
|
|||
static void GlobalBackPaintHint();
|
||||
static void GlobalBackBuffer(bool b = true);
|
||||
|
||||
static void ReSkin();
|
||||
|
||||
String Name() const;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
|
|||
#endif
|
||||
case WM_SETTINGCHANGE:
|
||||
case 0x031A: // WM_THEMECHANGED
|
||||
ChSync();
|
||||
ReSkin();
|
||||
RefreshLayoutDeep();
|
||||
RefreshFrame();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ void Ctrl::InitWin32(HINSTANCE hInstance)
|
|||
ILOG("Windows");
|
||||
Windows(); //?? TRC: what's the use of this?
|
||||
|
||||
ChSync();
|
||||
ReSkin();
|
||||
|
||||
OleInitialize(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ void Ctrl::InitX11(const char *display)
|
|||
|
||||
SetStdFont(Arial(12));
|
||||
|
||||
ChSync();
|
||||
ReSkin();
|
||||
|
||||
GUI_GlobalStyle_Write(GUISTYLE_XP);
|
||||
GUI_DragFullWindow_Write(1);
|
||||
|
|
|
|||
|
|
@ -1,399 +1,408 @@
|
|||
#include "Draw.h"
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
CommonFontInfo GetFontInfoSys(Font font);
|
||||
GlyphInfo GetGlyphInfoSys(Font font, int chr);
|
||||
void GetStdFontSys(String& name, int& height);
|
||||
Vector<FaceInfo> GetAllFacesSys();
|
||||
|
||||
bool Replace(Font fnt, int chr, Font& rfnt);
|
||||
|
||||
void Std(Font& font)
|
||||
{
|
||||
if(IsNull(font))
|
||||
font = StdFont();
|
||||
if(font.GetFace() == 0)
|
||||
font.Face(GetStdFont().GetFace());
|
||||
if(font.GetHeight() == 0)
|
||||
font.Height(GetStdFont().GetHeight());
|
||||
}
|
||||
|
||||
Size Font::StdFontSize;
|
||||
Font Font::AStdFont;
|
||||
|
||||
INITBLOCK {
|
||||
RichValue<Font>::Register();
|
||||
}
|
||||
|
||||
const Vector<FaceInfo>& Font::List()
|
||||
{
|
||||
static Vector<FaceInfo> *q;
|
||||
ONCELOCK {
|
||||
static Vector<FaceInfo> x;
|
||||
x = GetAllFacesSys();
|
||||
q = &x;
|
||||
}
|
||||
return *q;
|
||||
}
|
||||
|
||||
void sInitFonts()
|
||||
{
|
||||
Font::List();
|
||||
GetStdFont();
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
sInitFonts();
|
||||
}
|
||||
|
||||
int Font::GetFaceCount()
|
||||
{
|
||||
return List().GetCount();
|
||||
}
|
||||
|
||||
String Font::GetFaceName(int index)
|
||||
{
|
||||
if(index == 0)
|
||||
return "STDFONT";
|
||||
const Vector<FaceInfo>& l = List();
|
||||
if(index >= 0 && index < l.GetCount())
|
||||
return l[index].name;
|
||||
return Null;
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo(int index)
|
||||
{
|
||||
const Vector<FaceInfo>& l = List();
|
||||
if(index >= 0 && index < l.GetCount())
|
||||
return l[index].info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FontFilter(int c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z' || c >= '0' && c <= '9' ? c : c >= 'A' && c <= 'Z' ? ToLower(c) : 0;
|
||||
}
|
||||
|
||||
int Font::FindFaceNameIndex(const String& name) {
|
||||
if(name == "STDFONT")
|
||||
return 0;
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(GetFaceName(i) == name)
|
||||
return i;
|
||||
String n = Filter(name, FontFilter);
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(Filter(GetFaceName(i), FontFilter) == n)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Font::SyncStdFont()
|
||||
{
|
||||
DrawLock __;
|
||||
StdFontSize = Size(AStdFont.GetAveWidth(), AStdFont().Bold().GetCy());
|
||||
}
|
||||
|
||||
void Font::SetStdFont(Font font)
|
||||
{
|
||||
DrawLock __;
|
||||
InitStdFont();
|
||||
AStdFont = font;
|
||||
SyncStdFont();
|
||||
ChInvalidate();
|
||||
}
|
||||
|
||||
void Font::InitStdFont()
|
||||
{
|
||||
ONCELOCK {
|
||||
DrawLock __;
|
||||
List();
|
||||
AStdFont = Arial(12);
|
||||
String name;
|
||||
int height = 0;
|
||||
GetStdFontSys(name, height);
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifdef flagWINGL
|
||||
AStdFont = Font(FindFaceNameIndex("Tahoma"), 12);
|
||||
#else
|
||||
int q = FindFaceNameIndex(name);
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("Tahoma");
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("Microsoft Sans Serif");
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("MS Sans Serif");
|
||||
if(q > 0)
|
||||
AStdFont = Font(q, max(height, 1));
|
||||
#endif
|
||||
SyncStdFont();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Font Font::GetStdFont()
|
||||
{
|
||||
InitStdFont();
|
||||
return AStdFont;
|
||||
}
|
||||
|
||||
Size Font::GetStdFontSize()
|
||||
{
|
||||
InitStdFont();
|
||||
return StdFontSize;
|
||||
}
|
||||
|
||||
Font StdFont()
|
||||
{
|
||||
return Font(0, -32000);
|
||||
}
|
||||
|
||||
int Font::GetHeight() const
|
||||
{
|
||||
return v.height == -32000 ? GetStdFont().GetHeight() : v.height;
|
||||
}
|
||||
|
||||
String Font::GetFaceName() const {
|
||||
if(IsNullInstance()) return String();
|
||||
if(GetFace() == 0)
|
||||
return "STDFONT";
|
||||
return GetFaceName(GetFace());
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo() const {
|
||||
if(IsNullInstance()) return 0;
|
||||
return GetFaceInfo(GetFace());
|
||||
}
|
||||
|
||||
Font& Font::FaceName(const String& name) {
|
||||
int n = FindFaceNameIndex(name);
|
||||
Face(n < 0 ? 0xffff : n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Font::Serialize(Stream& s) {
|
||||
int version = 1;
|
||||
s / version;
|
||||
if(version >= 1) {
|
||||
enum {
|
||||
OLD_STDFONT, OLD_SCREEN_SERIF, OLD_SCREEN_SANS, OLD_SCREEN_FIXED,
|
||||
OLD_ROMAN,
|
||||
OLD_ARIAL,
|
||||
OLD_COURIER,
|
||||
};
|
||||
int f = GetFace();
|
||||
if(f > COURIER)
|
||||
f = -1;
|
||||
s / f;
|
||||
String name;
|
||||
if(f == OLD_ROMAN)
|
||||
f = ROMAN;
|
||||
if(f == OLD_ARIAL)
|
||||
f = ARIAL;
|
||||
if(f == OLD_COURIER)
|
||||
f = COURIER;
|
||||
if(f < 0) {
|
||||
name = GetFaceName();
|
||||
s % name;
|
||||
}
|
||||
if(s.IsLoading())
|
||||
if(f >= 0)
|
||||
Face(f);
|
||||
else
|
||||
FaceName(name);
|
||||
}
|
||||
else {
|
||||
String name = GetFaceName();
|
||||
s % name;
|
||||
if(s.IsLoading()) {
|
||||
FaceName(name);
|
||||
if(IsNullInstance())
|
||||
Face(COURIER);
|
||||
}
|
||||
}
|
||||
s % v.flags % v.height % v.width;
|
||||
}
|
||||
|
||||
template<>
|
||||
String AsString(const Font& f) {
|
||||
if(IsNull(f)) return "<null>";
|
||||
String s = "<" + f.GetFaceName() + Format(":%d", f.GetHeight());
|
||||
if(f.IsBold())
|
||||
s += " Bold";
|
||||
if(f.IsItalic())
|
||||
s += " Italic";
|
||||
if(f.IsUnderline())
|
||||
s += " Underline";
|
||||
if(f.IsStrikeout())
|
||||
s += " Strikeout";
|
||||
return s + '>';
|
||||
}
|
||||
|
||||
struct CharEntry {
|
||||
int64 font;
|
||||
GlyphInfo info;
|
||||
word chr;
|
||||
};
|
||||
|
||||
CharEntry fc_cache_global[4093];
|
||||
|
||||
bool IsNormal(Font font, int chr)
|
||||
{
|
||||
DrawLock __;
|
||||
CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093];
|
||||
if(e.font == font.AsInt64() || e.chr == chr)
|
||||
return e.info.IsNormal();
|
||||
return GetGlyphInfoSys(font, chr).IsNormal();
|
||||
}
|
||||
|
||||
CharEntry GetGlyphEntry(Font font, int chr, unsigned hash)
|
||||
{
|
||||
DrawLock __;
|
||||
CharEntry& e = fc_cache_global[hash % 4093];
|
||||
if(e.font != font.AsInt64() || e.chr != chr) {
|
||||
e.font = font.AsInt64();
|
||||
e.chr = chr;
|
||||
e.info = GetGlyphInfoSys(font, chr);
|
||||
if(!e.info.IsNormal()) {
|
||||
ComposedGlyph cg;
|
||||
Font rfnt;
|
||||
if(Compose(font, chr, cg)) {
|
||||
e.info.lspc = -1;
|
||||
e.info.rspc = cg.basic_char;
|
||||
}
|
||||
else
|
||||
if(Replace(font, chr, rfnt)) {
|
||||
e.info.lspc = rfnt.GetFace();
|
||||
e.info.rspc = rfnt.GetHeight();
|
||||
}
|
||||
else
|
||||
e.info.lspc = -2;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
thread__ CharEntry fc_cache[512];
|
||||
|
||||
GlyphInfo GetGlyphInfo(Font font, int chr)
|
||||
{
|
||||
Std(font);
|
||||
unsigned hash = CombineHash(font.GetHashValue(), chr);
|
||||
CharEntry& e = fc_cache[hash & 511];
|
||||
if(e.font != font.AsInt64() || e.chr != chr)
|
||||
e = GetGlyphEntry(font, chr, hash);
|
||||
return e.info;
|
||||
}
|
||||
|
||||
bool Font::IsNormal(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsNormal();
|
||||
}
|
||||
|
||||
bool Font::IsComposed(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsComposed();
|
||||
}
|
||||
|
||||
bool Font::IsReplaced(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsReplaced();
|
||||
}
|
||||
|
||||
bool Font::IsMissing(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsMissing();
|
||||
}
|
||||
|
||||
int Font::HasChar(int ch) const
|
||||
{
|
||||
return !GetGlyphInfo(*this, ch).IsMissing();
|
||||
}
|
||||
|
||||
void GlyphMetrics(GlyphInfo& f, Font font, int chr)
|
||||
{
|
||||
if(f.IsReplaced())
|
||||
f = GetGlyphInfo(font().Face(f.lspc).Height(f.rspc), chr);
|
||||
if(f.IsComposed()) {
|
||||
f = GetGlyphInfo(font, f.rspc);
|
||||
if(f.IsComposedLM())
|
||||
f.rspc += f.width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
GlyphInfo GetGlyphMetrics(Font font, int chr)
|
||||
{
|
||||
GlyphInfo f = GetGlyphInfo(font, chr);
|
||||
if(f.IsMissing())
|
||||
f = GetGlyphInfo(font, '?');
|
||||
GlyphMetrics(f, font, chr);
|
||||
return f;
|
||||
}
|
||||
|
||||
struct FontEntry {
|
||||
CommonFontInfo info;
|
||||
int64 font;
|
||||
};
|
||||
|
||||
thread__ FontEntry fi_cache[64];
|
||||
|
||||
const CommonFontInfo& GetFontInfo(Font font)
|
||||
{
|
||||
Std(font);
|
||||
unsigned hash = font.GetHashValue() & 63;
|
||||
FontEntry& e = fi_cache[hash];
|
||||
if(e.font != font.AsInt64()) {
|
||||
DrawLock __;
|
||||
e.font = font.AsInt64();
|
||||
e.info = GetFontInfoSys(font);
|
||||
}
|
||||
return e.info;
|
||||
}
|
||||
|
||||
int Font::GetWidth(int c) const {
|
||||
return GetGlyphMetrics(*this, c).width;
|
||||
}
|
||||
|
||||
int Font::GetLeftSpace(int c) const {
|
||||
return GetGlyphMetrics(*this, c).lspc;
|
||||
}
|
||||
|
||||
int Font::GetRightSpace(int c) const {
|
||||
return GetGlyphMetrics(*this, c).rspc;
|
||||
}
|
||||
|
||||
thread__ int64 lastFiFont = INT_MIN;
|
||||
thread__ CommonFontInfo lastFontInfo;
|
||||
thread__ int64 lastStdFont = INT_MIN;
|
||||
|
||||
|
||||
const CommonFontInfo& Font::Fi() const
|
||||
{
|
||||
#ifdef PLATFORM_OSX11
|
||||
// known leak on MacOSX here: getAllCarbonLazyValues2000 calls Core.h op new()
|
||||
// should not call UPP op new()
|
||||
// from GetFontInfo() ... XftFontOpenPattern() ... getAllCarbonLazyValues2000() -> new()
|
||||
MemoryIgnoreLeaksBlock __;
|
||||
#endif
|
||||
|
||||
if(lastStdFont != AStdFont.AsInt64()) {
|
||||
lastFiFont = INT_MIN;
|
||||
lastStdFont = AStdFont.AsInt64();
|
||||
}
|
||||
if(AsInt64() == lastFiFont)
|
||||
return lastFontInfo;
|
||||
lastFontInfo = GetFontInfo(*this);
|
||||
lastFiFont = AsInt64();
|
||||
return lastFontInfo;
|
||||
}
|
||||
|
||||
FontInfo Font::Info() const
|
||||
{
|
||||
FontInfo h;
|
||||
h.font = *this;
|
||||
return h;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
#include "Draw.h"
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
CommonFontInfo GetFontInfoSys(Font font);
|
||||
GlyphInfo GetGlyphInfoSys(Font font, int chr);
|
||||
void GetStdFontSys(String& name, int& height);
|
||||
Vector<FaceInfo> GetAllFacesSys();
|
||||
|
||||
bool Replace(Font fnt, int chr, Font& rfnt);
|
||||
|
||||
void Std(Font& font)
|
||||
{
|
||||
if(IsNull(font))
|
||||
font = StdFont();
|
||||
if(font.GetFace() == 0)
|
||||
font.Face(GetStdFont().GetFace());
|
||||
if(font.GetHeight() == 0)
|
||||
font.Height(GetStdFont().GetHeight());
|
||||
}
|
||||
|
||||
Size Font::StdFontSize;
|
||||
Font Font::AStdFont;
|
||||
|
||||
INITBLOCK {
|
||||
RichValue<Font>::Register();
|
||||
}
|
||||
|
||||
const Vector<FaceInfo>& Font::List()
|
||||
{
|
||||
static Vector<FaceInfo> *q;
|
||||
ONCELOCK {
|
||||
static Vector<FaceInfo> x;
|
||||
x = GetAllFacesSys();
|
||||
q = &x;
|
||||
}
|
||||
return *q;
|
||||
}
|
||||
|
||||
void sInitFonts()
|
||||
{
|
||||
Font::List();
|
||||
GetStdFont();
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
sInitFonts();
|
||||
}
|
||||
|
||||
int Font::GetFaceCount()
|
||||
{
|
||||
return List().GetCount();
|
||||
}
|
||||
|
||||
String Font::GetFaceName(int index)
|
||||
{
|
||||
if(index == 0)
|
||||
return "STDFONT";
|
||||
const Vector<FaceInfo>& l = List();
|
||||
if(index >= 0 && index < l.GetCount())
|
||||
return l[index].name;
|
||||
return Null;
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo(int index)
|
||||
{
|
||||
const Vector<FaceInfo>& l = List();
|
||||
if(index >= 0 && index < l.GetCount())
|
||||
return l[index].info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FontFilter(int c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z' || c >= '0' && c <= '9' ? c : c >= 'A' && c <= 'Z' ? ToLower(c) : 0;
|
||||
}
|
||||
|
||||
int Font::FindFaceNameIndex(const String& name) {
|
||||
if(name == "STDFONT")
|
||||
return 0;
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(GetFaceName(i) == name)
|
||||
return i;
|
||||
String n = Filter(name, FontFilter);
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(Filter(GetFaceName(i), FontFilter) == n)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Font::SyncStdFont()
|
||||
{
|
||||
DrawLock __;
|
||||
StdFontSize = Size(AStdFont.GetAveWidth(), AStdFont().Bold().GetCy());
|
||||
DDUMP(StdFontSize);
|
||||
DDUMP(AStdFont.GetHeight());
|
||||
}
|
||||
|
||||
void (*whenSetStdFont)();
|
||||
|
||||
void Font::SetStdFont(Font font)
|
||||
{
|
||||
DrawLock __;
|
||||
static int x = 0;
|
||||
if(x) return;
|
||||
x++;
|
||||
InitStdFont();
|
||||
AStdFont = font;
|
||||
SyncStdFont();
|
||||
if(whenSetStdFont)
|
||||
(*whenSetStdFont)();
|
||||
x--;
|
||||
}
|
||||
|
||||
void Font::InitStdFont()
|
||||
{
|
||||
ONCELOCK {
|
||||
DrawLock __;
|
||||
List();
|
||||
AStdFont = Arial(12);
|
||||
String name;
|
||||
int height = 0;
|
||||
GetStdFontSys(name, height);
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifdef flagWINGL
|
||||
AStdFont = Font(FindFaceNameIndex("Tahoma"), 12);
|
||||
#else
|
||||
int q = FindFaceNameIndex(name);
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("Tahoma");
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("Microsoft Sans Serif");
|
||||
if(q <= 0)
|
||||
q = FindFaceNameIndex("MS Sans Serif");
|
||||
if(q > 0)
|
||||
AStdFont = Font(q, max(height, 1));
|
||||
#endif
|
||||
SyncStdFont();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Font Font::GetStdFont()
|
||||
{
|
||||
InitStdFont();
|
||||
return AStdFont;
|
||||
}
|
||||
|
||||
Size Font::GetStdFontSize()
|
||||
{
|
||||
InitStdFont();
|
||||
return StdFontSize;
|
||||
}
|
||||
|
||||
Font StdFont()
|
||||
{
|
||||
return Font(0, -32000);
|
||||
}
|
||||
|
||||
int Font::GetHeight() const
|
||||
{
|
||||
return v.height == -32000 ? GetStdFont().GetHeight() : v.height;
|
||||
}
|
||||
|
||||
String Font::GetFaceName() const {
|
||||
if(IsNullInstance()) return String();
|
||||
if(GetFace() == 0)
|
||||
return "STDFONT";
|
||||
return GetFaceName(GetFace());
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo() const {
|
||||
if(IsNullInstance()) return 0;
|
||||
return GetFaceInfo(GetFace());
|
||||
}
|
||||
|
||||
Font& Font::FaceName(const String& name) {
|
||||
int n = FindFaceNameIndex(name);
|
||||
Face(n < 0 ? 0xffff : n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Font::Serialize(Stream& s) {
|
||||
int version = 1;
|
||||
s / version;
|
||||
if(version >= 1) {
|
||||
enum {
|
||||
OLD_STDFONT, OLD_SCREEN_SERIF, OLD_SCREEN_SANS, OLD_SCREEN_FIXED,
|
||||
OLD_ROMAN,
|
||||
OLD_ARIAL,
|
||||
OLD_COURIER,
|
||||
};
|
||||
int f = GetFace();
|
||||
if(f > COURIER)
|
||||
f = -1;
|
||||
s / f;
|
||||
String name;
|
||||
if(f == OLD_ROMAN)
|
||||
f = ROMAN;
|
||||
if(f == OLD_ARIAL)
|
||||
f = ARIAL;
|
||||
if(f == OLD_COURIER)
|
||||
f = COURIER;
|
||||
if(f < 0) {
|
||||
name = GetFaceName();
|
||||
s % name;
|
||||
}
|
||||
if(s.IsLoading())
|
||||
if(f >= 0)
|
||||
Face(f);
|
||||
else
|
||||
FaceName(name);
|
||||
}
|
||||
else {
|
||||
String name = GetFaceName();
|
||||
s % name;
|
||||
if(s.IsLoading()) {
|
||||
FaceName(name);
|
||||
if(IsNullInstance())
|
||||
Face(COURIER);
|
||||
}
|
||||
}
|
||||
s % v.flags % v.height % v.width;
|
||||
}
|
||||
|
||||
template<>
|
||||
String AsString(const Font& f) {
|
||||
if(IsNull(f)) return "<null>";
|
||||
String s = "<" + f.GetFaceName() + Format(":%d", f.GetHeight());
|
||||
if(f.IsBold())
|
||||
s += " Bold";
|
||||
if(f.IsItalic())
|
||||
s += " Italic";
|
||||
if(f.IsUnderline())
|
||||
s += " Underline";
|
||||
if(f.IsStrikeout())
|
||||
s += " Strikeout";
|
||||
return s + '>';
|
||||
}
|
||||
|
||||
struct CharEntry {
|
||||
int64 font;
|
||||
GlyphInfo info;
|
||||
word chr;
|
||||
};
|
||||
|
||||
CharEntry fc_cache_global[4093];
|
||||
|
||||
bool IsNormal(Font font, int chr)
|
||||
{
|
||||
DrawLock __;
|
||||
CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093];
|
||||
if(e.font == font.AsInt64() || e.chr == chr)
|
||||
return e.info.IsNormal();
|
||||
return GetGlyphInfoSys(font, chr).IsNormal();
|
||||
}
|
||||
|
||||
CharEntry GetGlyphEntry(Font font, int chr, unsigned hash)
|
||||
{
|
||||
DrawLock __;
|
||||
CharEntry& e = fc_cache_global[hash % 4093];
|
||||
if(e.font != font.AsInt64() || e.chr != chr) {
|
||||
e.font = font.AsInt64();
|
||||
e.chr = chr;
|
||||
e.info = GetGlyphInfoSys(font, chr);
|
||||
if(!e.info.IsNormal()) {
|
||||
ComposedGlyph cg;
|
||||
Font rfnt;
|
||||
if(Compose(font, chr, cg)) {
|
||||
e.info.lspc = -1;
|
||||
e.info.rspc = cg.basic_char;
|
||||
}
|
||||
else
|
||||
if(Replace(font, chr, rfnt)) {
|
||||
e.info.lspc = rfnt.GetFace();
|
||||
e.info.rspc = rfnt.GetHeight();
|
||||
}
|
||||
else
|
||||
e.info.lspc = -2;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
thread__ CharEntry fc_cache[512];
|
||||
|
||||
GlyphInfo GetGlyphInfo(Font font, int chr)
|
||||
{
|
||||
Std(font);
|
||||
unsigned hash = CombineHash(font.GetHashValue(), chr);
|
||||
CharEntry& e = fc_cache[hash & 511];
|
||||
if(e.font != font.AsInt64() || e.chr != chr)
|
||||
e = GetGlyphEntry(font, chr, hash);
|
||||
return e.info;
|
||||
}
|
||||
|
||||
bool Font::IsNormal(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsNormal();
|
||||
}
|
||||
|
||||
bool Font::IsComposed(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsComposed();
|
||||
}
|
||||
|
||||
bool Font::IsReplaced(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsReplaced();
|
||||
}
|
||||
|
||||
bool Font::IsMissing(int ch) const
|
||||
{
|
||||
return GetGlyphInfo(*this, ch).IsMissing();
|
||||
}
|
||||
|
||||
int Font::HasChar(int ch) const
|
||||
{
|
||||
return !GetGlyphInfo(*this, ch).IsMissing();
|
||||
}
|
||||
|
||||
void GlyphMetrics(GlyphInfo& f, Font font, int chr)
|
||||
{
|
||||
if(f.IsReplaced())
|
||||
f = GetGlyphInfo(font().Face(f.lspc).Height(f.rspc), chr);
|
||||
if(f.IsComposed()) {
|
||||
f = GetGlyphInfo(font, f.rspc);
|
||||
if(f.IsComposedLM())
|
||||
f.rspc += f.width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
GlyphInfo GetGlyphMetrics(Font font, int chr)
|
||||
{
|
||||
GlyphInfo f = GetGlyphInfo(font, chr);
|
||||
if(f.IsMissing())
|
||||
f = GetGlyphInfo(font, '?');
|
||||
GlyphMetrics(f, font, chr);
|
||||
return f;
|
||||
}
|
||||
|
||||
struct FontEntry {
|
||||
CommonFontInfo info;
|
||||
int64 font;
|
||||
};
|
||||
|
||||
thread__ FontEntry fi_cache[64];
|
||||
|
||||
const CommonFontInfo& GetFontInfo(Font font)
|
||||
{
|
||||
Std(font);
|
||||
unsigned hash = font.GetHashValue() & 63;
|
||||
FontEntry& e = fi_cache[hash];
|
||||
if(e.font != font.AsInt64()) {
|
||||
DrawLock __;
|
||||
e.font = font.AsInt64();
|
||||
e.info = GetFontInfoSys(font);
|
||||
}
|
||||
return e.info;
|
||||
}
|
||||
|
||||
int Font::GetWidth(int c) const {
|
||||
return GetGlyphMetrics(*this, c).width;
|
||||
}
|
||||
|
||||
int Font::GetLeftSpace(int c) const {
|
||||
return GetGlyphMetrics(*this, c).lspc;
|
||||
}
|
||||
|
||||
int Font::GetRightSpace(int c) const {
|
||||
return GetGlyphMetrics(*this, c).rspc;
|
||||
}
|
||||
|
||||
thread__ int64 lastFiFont = INT_MIN;
|
||||
thread__ CommonFontInfo lastFontInfo;
|
||||
thread__ int64 lastStdFont = INT_MIN;
|
||||
|
||||
|
||||
const CommonFontInfo& Font::Fi() const
|
||||
{
|
||||
#ifdef PLATFORM_OSX11
|
||||
// known leak on MacOSX here: getAllCarbonLazyValues2000 calls Core.h op new()
|
||||
// should not call UPP op new()
|
||||
// from GetFontInfo() ... XftFontOpenPattern() ... getAllCarbonLazyValues2000() -> new()
|
||||
MemoryIgnoreLeaksBlock __;
|
||||
#endif
|
||||
|
||||
if(lastStdFont != AStdFont.AsInt64()) {
|
||||
lastFiFont = INT_MIN;
|
||||
lastStdFont = AStdFont.AsInt64();
|
||||
}
|
||||
if(AsInt64() == lastFiFont)
|
||||
return lastFontInfo;
|
||||
lastFontInfo = GetFontInfo(*this);
|
||||
lastFiFont = AsInt64();
|
||||
return lastFontInfo;
|
||||
}
|
||||
|
||||
FontInfo Font::Info() const
|
||||
{
|
||||
FontInfo h;
|
||||
h.font = *this;
|
||||
return h;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue