diff --git a/specter/include/Specter/TextView.hpp b/specter/include/Specter/TextView.hpp index 502f2e03b..03b77be7b 100644 --- a/specter/include/Specter/TextView.hpp +++ b/specter/include/Specter/TextView.hpp @@ -74,8 +74,11 @@ public: int nominalWidth() const {return m_width;} int nominalHeight() const {return m_fontAtlas.FT_LineHeight() >> 6;} + std::pair queryGlyphDimensions(size_t pos) const; + private: std::vector m_glyphs; + std::vector> m_glyphDims; }; } diff --git a/specter/include/Specter/ViewResources.hpp b/specter/include/Specter/ViewResources.hpp index 35d374e4e..08a87784b 100644 --- a/specter/include/Specter/ViewResources.hpp +++ b/specter/include/Specter/ViewResources.hpp @@ -74,8 +74,8 @@ public: ViewResources& operator=(const ViewResources& other) = delete; ViewResources& operator=(ViewResources&& other) = default; - void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const ThemeData& theme, unsigned dpi); - void resetDPI(unsigned dpi); + void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const ThemeData& theme, float pixelFactor); + void resetPixelFactor(float pixelFactor); void resetTheme(const ThemeData& theme); void resetLanguage(const ThemeData& theme); diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index 0b6cef0e8..c72e34c6e 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -49,7 +49,7 @@ void Button::setText(const std::string& text) m_textStr = text; m_text->typesetGlyphs(text, rootView().themeData().uiText()); - float pf = rootView().window()->getVirtualPixelFactor(); + float pf = rootView().viewRes().pixelFactor(); float width = m_text->nominalWidth() + 10 * pf; float height = 20 * pf; m_verts[0].m_pos.assign(1, height+1, 0); @@ -186,7 +186,7 @@ void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) boo::SWindowRect textRect = sub; m_bBlock.setViewRect(root, sub); m_bBlockBuf->load(&m_bBlock, sizeof(ViewBlock)); - float pf = rootView().window()->getVirtualPixelFactor(); + float pf = rootView().viewRes().pixelFactor(); textRect.location[0] += 5 * pf; textRect.location[1] += 8 * pf; m_text->resized(root, textRect); diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index 3cd85a7a6..66cc14aa8 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -352,6 +352,8 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default uint32_t lCh = -1; m_glyphs.clear(); m_glyphs.reserve(str.size()); + m_glyphDims.clear(); + m_glyphDims.reserve(str.size()); int adv = 0; while (rem) @@ -374,6 +376,7 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default if (lCh != -1) adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas); m_glyphs.emplace_back(adv, *glyph, defaultColor); + m_glyphDims.emplace_back(glyph->m_width, glyph->m_height); lCh = glyph->m_glyphIdx; rem -= sz; @@ -393,6 +396,8 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul uint32_t lCh = -1; m_glyphs.clear(); m_glyphs.reserve(str.size()); + m_glyphDims.clear(); + m_glyphDims.reserve(str.size()); int adv = 0; for (wchar_t ch : str) @@ -407,6 +412,7 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul if (lCh != -1) adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas); m_glyphs.emplace_back(adv, *glyph, defaultColor); + m_glyphDims.emplace_back(glyph->m_width, glyph->m_height); lCh = glyph->m_glyphIdx; @@ -453,5 +459,15 @@ void TextView::draw(boo::IGraphicsCommandQueue* gfxQ) } } +std::pair TextView::queryGlyphDimensions(size_t pos) const +{ + if (pos >= m_glyphDims.size()) + Log.report(LogVisor::FatalError, + "TextView::queryGlyphWidth(%" PRISize ") out of bounds: %" PRISize, + pos, m_glyphDims.size()); + + return m_glyphDims[pos]; +} + } diff --git a/specter/lib/Tooltip.cpp b/specter/lib/Tooltip.cpp index 29617fbd8..648954b0c 100644 --- a/specter/lib/Tooltip.cpp +++ b/specter/lib/Tooltip.cpp @@ -7,7 +7,6 @@ namespace Specter #define TOOLTIP_MAX_WIDTH 316 #define TOOLTIP_MAX_TEXT_WIDTH 300 -#define TOOLTIP_MARGIN 8 Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title, const std::string& message) @@ -45,32 +44,30 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title, resetResources(res); } -#define EDGE_EPSILON 0.25 - void Tooltip::setVerts(int width, int height, float pf) { - int margin = TOOLTIP_MARGIN * pf; - width = std::max(width, margin*2); - height = std::max(height, margin*2); + std::pair margin = m_cornersFilled[0]->queryGlyphDimensions(0); + width = std::max(width, margin.first*2); + height = std::max(height, margin.second*2); - m_ttVerts[0].m_pos.assign(0, height-margin-EDGE_EPSILON, 0); - m_ttVerts[1].m_pos.assign(0, margin+EDGE_EPSILON, 0); - m_ttVerts[2].m_pos.assign(width, height-margin-EDGE_EPSILON, 0); - m_ttVerts[3].m_pos.assign(width, margin+EDGE_EPSILON, 0); - m_ttVerts[4].m_pos.assign(width, margin+EDGE_EPSILON, 0); + m_ttVerts[0].m_pos.assign(0, height-margin.second, 0); + m_ttVerts[1].m_pos.assign(0, margin.second, 0); + m_ttVerts[2].m_pos.assign(width, height-margin.second, 0); + m_ttVerts[3].m_pos.assign(width, margin.second, 0); + m_ttVerts[4].m_pos.assign(width, margin.second, 0); - m_ttVerts[5].m_pos.assign(margin+EDGE_EPSILON, height, 0); - m_ttVerts[6].m_pos.assign(margin+EDGE_EPSILON, height, 0); - m_ttVerts[7].m_pos.assign(margin+EDGE_EPSILON, height-margin+EDGE_EPSILON, 0); - m_ttVerts[8].m_pos.assign(width-margin-EDGE_EPSILON, height, 0); - m_ttVerts[9].m_pos.assign(width-margin-EDGE_EPSILON, height-margin+EDGE_EPSILON, 0); - m_ttVerts[10].m_pos.assign(width-margin-EDGE_EPSILON, height-margin+EDGE_EPSILON, 0); + m_ttVerts[5].m_pos.assign(margin.first, height, 0); + m_ttVerts[6].m_pos.assign(margin.first, height, 0); + m_ttVerts[7].m_pos.assign(margin.first, height-margin.second, 0); + m_ttVerts[8].m_pos.assign(width-margin.first, height, 0); + m_ttVerts[9].m_pos.assign(width-margin.first, height-margin.second, 0); + m_ttVerts[10].m_pos.assign(width-margin.first, height-margin.second, 0); - m_ttVerts[11].m_pos.assign(margin+EDGE_EPSILON, margin-EDGE_EPSILON, 0); - m_ttVerts[12].m_pos.assign(margin+EDGE_EPSILON, margin-EDGE_EPSILON, 0); - m_ttVerts[13].m_pos.assign(margin+EDGE_EPSILON, 0, 0); - m_ttVerts[14].m_pos.assign(width-margin-EDGE_EPSILON, margin-EDGE_EPSILON, 0); - m_ttVerts[15].m_pos.assign(width-margin-EDGE_EPSILON, 0, 0); + m_ttVerts[11].m_pos.assign(margin.first, margin.second, 0); + m_ttVerts[12].m_pos.assign(margin.first, margin.second, 0); + m_ttVerts[13].m_pos.assign(margin.first, 0, 0); + m_ttVerts[14].m_pos.assign(width-margin.first, margin.second, 0); + m_ttVerts[15].m_pos.assign(width-margin.first, 0, 0); m_ttVertsBuf->load(m_ttVerts, sizeof(SolidShaderVert) * 16); } @@ -83,25 +80,27 @@ void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) m_ttBlock.setViewRect(root, sub); m_ttBlockBuf->load(&m_ttBlock, sizeof(ViewBlock)); + std::pair margin = m_cornersFilled[0]->queryGlyphDimensions(0); + boo::SWindowRect textRect = sub; - textRect.location[0] += TOOLTIP_MARGIN * pf; - textRect.location[1] += TOOLTIP_MARGIN * 1.5 * pf; + textRect.location[0] += margin.first; + textRect.location[1] += margin.second * 1.5; m_message->resized(root, textRect); - textRect.location[1] += m_message->nominalHeight() + TOOLTIP_MARGIN * pf; + textRect.location[1] += m_message->nominalHeight() + margin.second; m_title->resized(root, textRect); boo::SWindowRect cornerRect = sub; - cornerRect.location[1] += m_nomHeight - TOOLTIP_MARGIN * pf; + cornerRect.location[1] += m_nomHeight - margin.second; // Upper left m_cornersOutline[0]->resized(root, cornerRect); m_cornersFilled[0]->resized(root, cornerRect); - cornerRect.location[0] += m_nomWidth - TOOLTIP_MARGIN * pf; + cornerRect.location[0] += m_nomWidth - margin.first; // Upper right m_cornersOutline[1]->resized(root, cornerRect); m_cornersFilled[1]->resized(root, cornerRect); - cornerRect.location[1] = sub.location[1]; + cornerRect.location[1] = sub.location[1]; // Lower right m_cornersOutline[2]->resized(root, cornerRect); m_cornersFilled[2]->resized(root, cornerRect); - cornerRect.location[0] = sub.location[0]; + cornerRect.location[0] = sub.location[0]; // Lower left m_cornersOutline[3]->resized(root, cornerRect); m_cornersFilled[3]->resized(root, cornerRect); } @@ -126,12 +125,13 @@ void Tooltip::resetResources(ViewResources& res) m_title->typesetGlyphs(m_titleStr); m_message.reset(new MultiLineTextView(res, *this, res.m_mainFont)); m_message->typesetGlyphs(m_messageStr, Zeus::CColor::skWhite, - int(TOOLTIP_MAX_TEXT_WIDTH * rootView().viewRes().pixelFactor())); + int(TOOLTIP_MAX_TEXT_WIDTH * res.pixelFactor())); float pf = res.pixelFactor(); + std::pair margin = m_cornersOutline[0]->queryGlyphDimensions(0); m_nomWidth = std::min(int(TOOLTIP_MAX_WIDTH * pf), - int(std::max(m_title->nominalWidth(), m_message->nominalWidth()) + TOOLTIP_MARGIN * 2 * pf)); - m_nomHeight = m_title->nominalHeight() + m_message->nominalHeight() + TOOLTIP_MARGIN * 3 * pf; + int(std::max(m_title->nominalWidth(), m_message->nominalWidth()) + margin.first * 2)); + m_nomHeight = m_title->nominalHeight() + m_message->nominalHeight() + margin.second * 3; } void Tooltip::draw(boo::IGraphicsCommandQueue* gfxQ) diff --git a/specter/lib/ViewResources.cpp b/specter/lib/ViewResources.cpp index 9f5d9f8a5..6b81aa76f 100644 --- a/specter/lib/ViewResources.cpp +++ b/specter/lib/ViewResources.cpp @@ -5,9 +5,10 @@ namespace Specter static LogVisor::LogModule Log("Specter::ViewResources"); void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, - const ThemeData& theme, unsigned dpi) + const ThemeData& theme, float pf) { - m_pixelFactor = dpi / 72.f; + m_pixelFactor = pf; + unsigned dpi = 72.f * pf; m_theme = theme; m_factory = factory; m_fcache = fcache; @@ -15,7 +16,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, m_monoFont = fcache->prepMonoFont(factory, AllCharFilter, false, 10.f, dpi); m_heading14 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 14.f, dpi); m_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.f, dpi); - m_curveFont = fcache->prepCurvesFont(factory, AllCharFilter, false, 11.f, dpi); + m_curveFont = fcache->prepCurvesFont(factory, AllCharFilter, false, 8.f, dpi); m_fontData = factory->commit(); switch (factory->platform()) { @@ -39,9 +40,10 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, m_resData = factory->commit(); } -void ViewResources::resetDPI(unsigned dpi) +void ViewResources::resetPixelFactor(float pf) { - m_pixelFactor = dpi / 72.f; + m_pixelFactor = pf; + unsigned dpi = 72.f * pf; m_mainFont = m_fcache->prepMainFont(m_factory, AllCharFilter, false, 10.f, dpi); m_monoFont = m_fcache->prepMonoFont(m_factory, AllCharFilter, false, 10.f, dpi); m_heading14 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 14.f, dpi); diff --git a/specter/resources/fonts/SpecterCurveGlyphs.ttf.gz b/specter/resources/fonts/SpecterCurveGlyphs.ttf.gz index 6b7590570..e9d3a7c91 100644 Binary files a/specter/resources/fonts/SpecterCurveGlyphs.ttf.gz and b/specter/resources/fonts/SpecterCurveGlyphs.ttf.gz differ