diff --git a/uppsrc/Draw/Font.cpp b/uppsrc/Draw/Font.cpp index bf82e1aee..92e9c73e1 100644 --- a/uppsrc/Draw/Font.cpp +++ b/uppsrc/Draw/Font.cpp @@ -1,379 +1,379 @@ -#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 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::Register(); -} - -const Vector& Font::List() -{ - static Vector *q; - ONCELOCK { - static Vector 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& l = List(); - if(index >= 0 && index < l.GetCount()) - return l[index].name; - return Null; -} - -dword Font::GetFaceInfo(int index) -{ - const Vector& 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(); -} - -void Font::InitStdFont() -{ - ONCELOCK { - DrawLock __; - List(); - AStdFont = Arial(12); - String name; - int height = 0; - GetStdFontSys(name, height); - int q = FindFaceNameIndex(name); - if(q > 0) { - AStdFont = Font(q, max(height, 1)); - SyncStdFont(); - } - } -} - -Font Font::GetStdFont() -{ - InitStdFont(); - return AStdFont; -} - -Size Font::GetStdFontSize() -{ - InitStdFont(); - return StdFontSize; -} - -Font StdFont() -{ - return Font(0, 0); -} - -int Font::GetHeight() const -{ - return v.height || v.face ? v.height : GetStdFont().GetHeight(); -} - -String Font::GetFaceName() const { - if(IsNull()) return String(); - if(GetFace() == 0) - return "STDFONT"; - return GetFaceName(GetFace()); -} - -dword Font::GetFaceInfo() const { - if(IsNull()) 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(IsNull()) - Face(COURIER); - } - } - s % v.flags % v.height % v.width; -} - -template<> -String AsString(const Font& f) { - if(IsNull(f)) return ""; - 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 -{ - 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 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::Register(); +} + +const Vector& Font::List() +{ + static Vector *q; + ONCELOCK { + static Vector 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& l = List(); + if(index >= 0 && index < l.GetCount()) + return l[index].name; + return Null; +} + +dword Font::GetFaceInfo(int index) +{ + const Vector& 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(); +} + +void Font::InitStdFont() +{ + ONCELOCK { + DrawLock __; + List(); + AStdFont = Arial(12); + String name; + int height = 0; + GetStdFontSys(name, height); + int q = FindFaceNameIndex(name); + if(q > 0) { + AStdFont = Font(q, max(height, 1)); + SyncStdFont(); + } + } +} + +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(IsNull()) return String(); + if(GetFace() == 0) + return "STDFONT"; + return GetFaceName(GetFace()); +} + +dword Font::GetFaceInfo() const { + if(IsNull()) 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(IsNull()) + Face(COURIER); + } + } + s % v.flags % v.height % v.width; +} + +template<> +String AsString(const Font& f) { + if(IsNull(f)) return ""; + 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 +{ + 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 diff --git a/uppsrc/ide/Browser/ItemDisplay.cpp b/uppsrc/ide/Browser/ItemDisplay.cpp index bbf1eccb5..a06f1f627 100644 --- a/uppsrc/ide/Browser/ItemDisplay.cpp +++ b/uppsrc/ide/Browser/ItemDisplay.cpp @@ -162,7 +162,7 @@ int CppItemInfoDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, DrawHighlightImage(w, xx, yy, BrowserImg::Ref()); if(cnt > 1) { String txt = AsString(cnt); - Font fnt = Arial(VertLayoutZoom(10)).Bold(); + Font fnt = Arial(Ctrl::VertLayoutZoom(10)).Bold(); Size tsz = GetTextSize(txt, fnt); Point p(xx + (sz.cx - tsz.cx) / 2, yy + (sz.cy - tsz.cy) / 2); for(int ax = -1; ax <= 1; ax++)