From 00c4bb1e0b267887b7e28f1f4a60a9e63754da87 Mon Sep 17 00:00:00 2001 From: rachytski Date: Tue, 22 Nov 2011 19:39:08 +0400 Subject: [PATCH] drawing secondary text for POI's and road names. --- map/draw_processor.cpp | 3 ++- map/drawer_yg.cpp | 47 +++++++++++++++++++++++++++--------- map/drawer_yg.hpp | 14 ++++++++--- yg/glyph_layout.cpp | 6 +++++ yg/glyph_layout.hpp | 1 + yg/overlay_renderer.cpp | 47 +++++++++++++++++++++++++++++++----- yg/overlay_renderer.hpp | 10 ++++++++ yg/straight_text_element.cpp | 39 ++++++++++++++++++------------ yg/text_element.cpp | 24 ++++++++++++++++++ yg/text_element.hpp | 13 ++++++++++ 10 files changed, 166 insertions(+), 38 deletions(-) diff --git a/map/draw_processor.cpp b/map/draw_processor.cpp index 71c3dad376..37b60abe93 100644 --- a/map/draw_processor.cpp +++ b/map/draw_processor.cpp @@ -304,6 +304,7 @@ namespace fwork shared_ptr ptr(new di::DrawInfo( f.GetPreferredDrawableName(languages::GetCurrentPriorities()), + f.GetPreferredDrawableName(0), f.GetRoadNumber(), (m_zoom > 5) ? f.GetPopulationDrawRank() : 0.0)); @@ -364,7 +365,7 @@ namespace fwork if (fontSize != 0) { - double textLength = m_glyphCache->getTextLength(fontSize, ptr->m_name); + double textLength = m_glyphCache->getTextLength(fontSize, ptr->GetPathName()); typedef calc_length functor_t; functor_t::params p1; p1.m_convertor = &m_convertor; diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index 1d8d02e9b2..1dcbf9eb69 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -25,6 +25,24 @@ DrawerYG::Params::Params() { } +di::DrawInfo::DrawInfo(string const & name, + string const & secondaryName, + string const & road, + double rank) + : m_name(name), + m_secondaryName(secondaryName), + m_road(road), + m_rank(rank) +{} + +string const di::DrawInfo::GetPathName() const +{ + if (m_secondaryName.empty()) + return m_name; + else + return m_name + " " + m_secondaryName; +} + uint32_t di::DrawRule::GetID(size_t threadID) const { return (m_transparent ? m_rule->GetID2(threadID) : m_rule->GetID(threadID)); @@ -249,29 +267,34 @@ void DrawerYG::drawText(m2::PointD const & pt, di::DrawInfo const * pInfo, rule_ yg::FontDesc fontDesc(get_text_font(pRule)); fontDesc.SetRank(pInfo->m_rank); + yg::FontDesc smallFontDesc(fontDesc); + smallFontDesc.m_size *= 0.75; + if (!filter_text_size(pRule)) - m_pScreen->drawText( + m_pScreen->drawTextEx( fontDesc, + smallFontDesc, pt, pos, pInfo->m_name, + pInfo->m_secondaryName, depth, true, true); } -bool DrawerYG::drawPathText(di::PathInfo const & info, string const & name, rule_ptr_t pRule, int depth) +bool DrawerYG::drawPathText(di::PathInfo const & info, di::DrawInfo const * pInfo, rule_ptr_t pRule, int depth) { - yg::FontDesc fontDesc(get_text_font(pRule)); + yg::FontDesc primaryFont(get_text_font(pRule)); - return m_pScreen->drawPathText( fontDesc, - &info.m_path[0], - info.m_path.size(), - name, - info.GetFullLength(), - info.GetOffset(), - yg::EPosCenter, - depth); + return m_pScreen->drawPathText(primaryFont, + &info.m_path[0], + info.m_path.size(), + pInfo->GetPathName(), + info.GetFullLength(), + info.GetOffset(), + yg::EPosCenter, + depth); } void DrawerYG::drawPathNumber(di::PathInfo const & path, di::DrawInfo const * pInfo) @@ -419,7 +442,7 @@ void DrawerYG::Draw(di::DrawInfo const * pInfo, di::DrawRule const * rules, size if (filter_text_size(pRule)) continue; - drawPathText(*i, pInfo->m_name, pRule, depth); + drawPathText(*i, pInfo, pRule, depth); } } diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index baf0ecaca0..bdeae02371 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -32,15 +32,21 @@ namespace di class DrawInfo { public: - DrawInfo(string const & name, string const & road, double rank) - : m_name(name), m_road(road), m_rank(rank) {} + DrawInfo(string const & name, + string const & secondaryName, + string const & road, + double rank); list m_pathes; list m_areas; m2::PointD m_point; - string m_name, m_road; + string m_name; + string m_secondaryName; + string m_road; double m_rank; + + string const GetPathName() const; }; struct DrawRule @@ -80,7 +86,7 @@ protected: void drawArea(vector const & pts, rule_ptr_t pRule, int depth); void drawText(m2::PointD const & pt, di::DrawInfo const * pInfo, rule_ptr_t pRule, yg::EPosition pos, int depth); - bool drawPathText(di::PathInfo const & info, string const & name, rule_ptr_t pRule, int depth); + bool drawPathText(di::PathInfo const & info, di::DrawInfo const * pInfo, rule_ptr_t pRule, int depth); void drawPathNumber(di::PathInfo const & path, di::DrawInfo const * pInfo); typedef shared_ptr texture_t; diff --git a/yg/glyph_layout.cpp b/yg/glyph_layout.cpp index 11368cb1d5..0edb65742f 100644 --- a/yg/glyph_layout.cpp +++ b/yg/glyph_layout.cpp @@ -66,6 +66,7 @@ namespace yg yg::EPosition pos) : m_firstVisible(0), m_lastVisible(visText.size()), + m_fontDesc(fontDesc), m_pivot(pt) { m2::RectD boundRect; @@ -404,4 +405,9 @@ namespace yg m_pivot = pivot; } + + yg::FontDesc const & GlyphLayout::fontDesc() const + { + return m_fontDesc; + } } diff --git a/yg/glyph_layout.hpp b/yg/glyph_layout.hpp index de83d0b4b9..ad2fab1f48 100644 --- a/yg/glyph_layout.hpp +++ b/yg/glyph_layout.hpp @@ -91,6 +91,7 @@ namespace yg vector const & boundRects() const; m2::PointD const & pivot() const; + yg::FontDesc const & fontDesc() const; void setPivot(m2::PointD const & pv); }; diff --git a/yg/overlay_renderer.cpp b/yg/overlay_renderer.cpp index 243ab9bfd5..9069f1b47d 100644 --- a/yg/overlay_renderer.cpp +++ b/yg/overlay_renderer.cpp @@ -77,12 +77,12 @@ namespace yg } void OverlayRenderer::drawText(FontDesc const & fontDesc, - m2::PointD const & pt, - yg::EPosition pos, - string const & utf8Text, - double depth, - bool log2vis, - bool doSplit) + m2::PointD const & pt, + yg::EPosition pos, + string const & utf8Text, + double depth, + bool log2vis, + bool doSplit) { if (!m_drawTexts) return; @@ -107,6 +107,41 @@ namespace yg m_infoLayer->processOverlayElement(oe); } + void OverlayRenderer::drawTextEx(FontDesc const & primaryFont, + FontDesc const & secondaryFont, + m2::PointD const & pt, + yg::EPosition pos, + string const & text, + string const & secondaryText, + double depth, + bool log2vis, + bool doSplit) + { + if (!m_drawTexts) + return; + + StraightTextElement::Params params; + params.m_depth = depth; + params.m_fontDesc = primaryFont; + params.m_auxFontDesc = secondaryFont; + params.m_log2vis = log2vis; + params.m_pivot = pt; + params.m_position = pos; + params.m_glyphCache = glyphCache(); + params.m_logText = strings::MakeUniString(text); + params.m_auxLogText = strings::MakeUniString(secondaryText); + params.m_doSplit = doSplit; + + shared_ptr oe(new StraightTextElement(params)); + + math::Matrix id = math::Identity(); + + if (!m_infoLayer.get()) + oe->draw(this, id); + else + m_infoLayer->processOverlayElement(oe); + } + bool OverlayRenderer::drawPathText( FontDesc const & fontDesc, m2::PointD const * path, size_t s, string const & utf8Text, double fullLength, double pathOffset, yg::EPosition pos, double depth) diff --git a/yg/overlay_renderer.hpp b/yg/overlay_renderer.hpp index cc7a88d613..8a47251f79 100644 --- a/yg/overlay_renderer.hpp +++ b/yg/overlay_renderer.hpp @@ -47,6 +47,16 @@ namespace yg bool log2vis, bool doSplit = false); + void drawTextEx(FontDesc const & primaryFont, + FontDesc const & secondaryFont, + m2::PointD const & pt, + yg::EPosition pos, + string const & text, + string const & secondaryText, + double depth, + bool log2vis, + bool doSplit = false); + /// drawing text on the path bool drawPathText(FontDesc const & fontDesc, m2::PointD const * path, diff --git a/yg/straight_text_element.cpp b/yg/straight_text_element.cpp index 99a5c239bf..10e265d54b 100644 --- a/yg/straight_text_element.cpp +++ b/yg/straight_text_element.cpp @@ -107,11 +107,19 @@ namespace yg allElemHeight += r.SizeY(); } + if (!auxVisText().empty()) + { + m_glyphLayouts.push_back(GlyphLayout(p.m_glyphCache, p.m_auxFontDesc, m2::PointD(0, 0), auxVisText(), yg::EPosCenter)); + m2::RectD r = m_glyphLayouts.back().boundRects().back().GetGlobalRect(); + allElemWidth = max(r.SizeX(), allElemWidth); + allElemHeight += r.SizeY(); + } + double curShift = allElemHeight / 2; /// performing aligning of glyphLayouts as for the center position - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) { double elemSize = m_glyphLayouts[i].boundRects().back().GetGlobalRect().SizeY(); m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, -curShift + elemSize / 2)); @@ -119,22 +127,22 @@ namespace yg } if (position() & yg::EPosLeft) - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(-allElemWidth / 2, 0)); if (position() & yg::EPosRight) - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(allElemWidth / 2, 0)); if (position() & yg::EPosAbove) - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, -allElemHeight / 2)); if (position() & yg::EPosUnder) - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, allElemHeight / 2)); - for (unsigned i = 0; i < res.size(); ++i) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) { m_offsets.push_back(m_glyphLayouts[i].pivot()); m_glyphLayouts[i].setPivot(m_offsets[i] + pivot()); @@ -149,7 +157,8 @@ namespace yg m_doSplit(false) {} - StraightTextElement::StraightTextElement(StraightTextElement const & src, math::Matrix const & m) + StraightTextElement::StraightTextElement(StraightTextElement const & src, + math::Matrix const & m) : TextElement(src), m_glyphLayouts(src.m_glyphLayouts) { @@ -198,18 +207,18 @@ namespace yg if (!isNeedRedraw()) return; - yg::FontDesc desc = m_fontDesc; - - if (m_fontDesc.m_isMasked) + for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) { - for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) - drawTextImpl(m_glyphLayouts[i], screen, m, true, m_fontDesc, yg::maxDepth - 1); - - desc.m_isMasked = false; + if (m_glyphLayouts[i].fontDesc().m_isMasked) + drawTextImpl(m_glyphLayouts[i], screen, m, true, m_glyphLayouts[i].fontDesc(), yg::maxDepth - 1); } for (unsigned i = 0; i < m_glyphLayouts.size(); ++i) - drawTextImpl(m_glyphLayouts[i], screen, m, true, desc, yg::maxDepth); + { + yg::FontDesc fontDesc = m_glyphLayouts[i].fontDesc(); + fontDesc.m_isMasked = false; + drawTextImpl(m_glyphLayouts[i], screen, m, true, fontDesc, yg::maxDepth); + } } void StraightTextElement::offset(m2::PointD const & offs) diff --git a/yg/text_element.cpp b/yg/text_element.cpp index e17fc5347d..406b506bfe 100644 --- a/yg/text_element.cpp +++ b/yg/text_element.cpp @@ -14,14 +14,23 @@ namespace yg TextElement::TextElement(Params const & p) : OverlayElement(p), m_fontDesc(p.m_fontDesc), + m_auxFontDesc(p.m_auxFontDesc), m_logText(p.m_logText), + m_auxLogText(p.m_auxLogText), m_log2vis(p.m_log2vis), m_glyphCache(p.m_glyphCache) { if (m_log2vis) + { m_visText = m_glyphCache->log2vis(m_logText); + if (!m_auxLogText.empty()) + m_auxVisText = m_glyphCache->log2vis(m_auxLogText); + } else + { m_visText = m_logText; + m_auxVisText = m_auxLogText; + } } strings::UniString const & TextElement::logText() const @@ -29,16 +38,31 @@ namespace yg return m_logText; } + strings::UniString const & TextElement::auxLogText() const + { + return m_auxLogText; + } + strings::UniString const & TextElement::visText() const { return m_visText; } + strings::UniString const & TextElement::auxVisText() const + { + return m_auxVisText; + } + FontDesc const & TextElement::fontDesc() const { return m_fontDesc; } + FontDesc const & TextElement::auxFontDesc() const + { + return m_auxFontDesc; + } + bool TextElement::isBidi() const { return m_logText != m_visText; diff --git a/yg/text_element.hpp b/yg/text_element.hpp index 591a8cf85d..cc9100460e 100644 --- a/yg/text_element.hpp +++ b/yg/text_element.hpp @@ -29,8 +29,14 @@ namespace yg /// text-element specific FontDesc m_fontDesc; + FontDesc m_auxFontDesc; + strings::UniString m_logText; //< logical string + strings::UniString m_auxLogText; + strings::UniString m_visText; //< visual string, BIDI processed + strings::UniString m_auxVisText; + bool m_log2vis; GlyphCache * m_glyphCache; @@ -63,6 +69,10 @@ namespace yg { FontDesc m_fontDesc; strings::UniString m_logText; + + FontDesc m_auxFontDesc; + strings::UniString m_auxLogText; + bool m_log2vis; GlyphCache * m_glyphCache; }; @@ -76,7 +86,10 @@ namespace yg FontDesc const & desc, double depth) const; strings::UniString const & logText() const; + strings::UniString const & auxLogText() const; strings::UniString const & visText() const; + strings::UniString const & auxVisText() const; FontDesc const & fontDesc() const; + FontDesc const & auxFontDesc() const; }; }