From 0bd1cf2af993e86a5ee9024d6036ba3fc4fc5e71 Mon Sep 17 00:00:00 2001 From: ExMix Date: Mon, 23 Sep 2013 19:10:18 +0300 Subject: [PATCH] draw circles behind symbols if rules provide this --- graphics/circled_symbol.cpp | 33 +++++++++++++++++ graphics/circled_symbol.hpp | 21 +++++++++++ graphics/graphics.pro | 2 + graphics/overlay_renderer.cpp | 14 +++++++ graphics/overlay_renderer.hpp | 3 ++ graphics/symbol_element.hpp | 5 ++- map/drawer.cpp | 69 ++++++++++++++++++++++++++++++++++- map/drawer.hpp | 6 +++ 8 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 graphics/circled_symbol.cpp create mode 100644 graphics/circled_symbol.hpp diff --git a/graphics/circled_symbol.cpp b/graphics/circled_symbol.cpp new file mode 100644 index 0000000000..1a6ad1c6f2 --- /dev/null +++ b/graphics/circled_symbol.cpp @@ -0,0 +1,33 @@ +#include "circled_symbol.hpp" + +namespace graphics +{ + CircledSymbol::CircledSymbol(SymbolElement::Params const & symbolElement, + CircleElement::Params const & circleElement) + : SymbolElement(symbolElement) + , m_circle(circleElement) {} + + vector const & CircledSymbol::boundRects() const + { + if (isDirtyRect()) + { + SymbolElement::boundRects(); + vector circleBounds = m_circle.boundRects(); + m_boundRects.insert(m_boundRects.end(), circleBounds.begin(), circleBounds.end()); + } + + return SymbolElement::boundRects(); + } + + void CircledSymbol::draw(OverlayRenderer * s, math::Matrix const & m) const + { + m_circle.draw(s, m); + SymbolElement::draw(s, m); + } + + void CircledSymbol::setTransformation(const math::Matrix & m) + { + m_circle.setTransformation(m); + SymbolElement::setTransformation(m); + } +} diff --git a/graphics/circled_symbol.hpp b/graphics/circled_symbol.hpp new file mode 100644 index 0000000000..a4384abc09 --- /dev/null +++ b/graphics/circled_symbol.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "symbol_element.hpp" +#include "circle_element.hpp" + +namespace graphics +{ + class CircledSymbol : public SymbolElement + { + public: + CircledSymbol(SymbolElement::Params const & symbolElement, + CircleElement::Params const & circleElement); + + vector const & boundRects() const; + void draw(OverlayRenderer * s, math::Matrix const & m) const; + void setTransformation(const math::Matrix & m); + + private: + CircleElement m_circle; + }; +} diff --git a/graphics/graphics.pro b/graphics/graphics.pro index 3e3bdfb591..24b0519d78 100644 --- a/graphics/graphics.pro +++ b/graphics/graphics.pro @@ -75,6 +75,7 @@ SOURCES += \ pipeline_manager.cpp \ geometry_pipeline.cpp \ path_view.cpp \ + circled_symbol.cpp HEADERS += \ opengl/opengl.hpp \ @@ -145,6 +146,7 @@ HEADERS += \ path_view.hpp \ path.hpp \ depth_constants.hpp \ + circled_symbol.hpp win32* { SOURCES += opengl/opengl_win32.cpp diff --git a/graphics/overlay_renderer.cpp b/graphics/overlay_renderer.cpp index 228f4381e2..4a23641faa 100644 --- a/graphics/overlay_renderer.cpp +++ b/graphics/overlay_renderer.cpp @@ -5,6 +5,7 @@ #include "path_text_element.hpp" #include "symbol_element.hpp" #include "circle_element.hpp" +#include "circled_symbol.hpp" #include "overlay.hpp" #include "resource_manager.hpp" @@ -79,6 +80,19 @@ namespace graphics drawCircle(params); } + void OverlayRenderer::drawCircledSymbol(SymbolElement::Params const & symParams, + CircleElement::Params const & circleParams) + { + shared_ptr oe(new CircledSymbol(symParams, circleParams)); + + math::Matrix id = math::Identity(); + + if (!m_overlay.get()) + oe->draw(this, id); + else + m_overlay->processOverlayElement(oe); + } + void OverlayRenderer::drawText(FontDesc const & fontDesc, m2::PointD const & pt, graphics::EPosition pos, diff --git a/graphics/overlay_renderer.hpp b/graphics/overlay_renderer.hpp index 6e3e6df76b..5a643f907e 100644 --- a/graphics/overlay_renderer.hpp +++ b/graphics/overlay_renderer.hpp @@ -45,6 +45,9 @@ namespace graphics EPosition pos, double depth); + void drawCircledSymbol(SymbolElement::Params const & symParams, + CircleElement::Params const & circleParams); + /// drawing straight text void drawText(FontDesc const & fontDesc, m2::PointD const & pt, diff --git a/graphics/symbol_element.hpp b/graphics/symbol_element.hpp index 49f58b517a..455cc0e501 100644 --- a/graphics/symbol_element.hpp +++ b/graphics/symbol_element.hpp @@ -14,10 +14,11 @@ namespace graphics Icon::Info m_info; m2::RectU m_symbolRect; - mutable vector m_boundRects; - m2::AnyRectD const boundRect() const; + protected: + mutable vector m_boundRects; + public: typedef OverlayElement base_t; diff --git a/map/drawer.cpp b/map/drawer.cpp index 2950fb96a5..0c597a651c 100644 --- a/map/drawer.cpp +++ b/map/drawer.cpp @@ -128,6 +128,38 @@ void Drawer::drawSymbol(m2::PointD const & pt, m_pScreen->drawSymbol(params); } +void Drawer::drawCircledSymbol(m2::PointD const & pt, + graphics::EPosition pos, + di::DrawRule const & symbolRule, + di::DrawRule const & circleRule, + FeatureID const & id) +{ + graphics::Icon::Info info; + ConvertStyle(symbolRule.m_rule->GetSymbol(), info); + + graphics::Circle::Info ci; + ConvertStyle(circleRule.m_rule->GetCircle(), m_visualScale, ci); + + graphics::SymbolElement::Params symParams; + symParams.m_depth = symbolRule.m_depth; + symParams.m_position = pos; + symParams.m_pivot = pt; + symParams.m_info = info; + symParams.m_renderer = m_pScreen.get(); + symParams.m_userInfo.m_mwmID = id.m_mwm; + symParams.m_userInfo.m_offset = id.m_offset; + + graphics::CircleElement::Params circleParams; + circleParams.m_depth = circleRule.m_depth; + circleParams.m_position = pos; + circleParams.m_pivot = pt; + circleParams.m_ci = ci; + circleParams.m_userInfo.m_mwmID = id.m_mwm; + circleParams.m_userInfo.m_offset = id.m_offset; + + m_pScreen->drawCircledSymbol(symParams, circleParams); +} + void Drawer::drawPath(di::PathInfo const & path, di::DrawRule const * rules, size_t count) { // if any rule needs caching - cache as a whole vector @@ -313,6 +345,11 @@ void Drawer::Draw(di::FeatureInfo const & fi) bool const isPath = !fi.m_pathes.empty(); bool const isArea = !fi.m_areas.empty(); + bool isCircleAndSymbol = false; + drule::BaseRule const * pCircleRule = NULL; + double circleDepth = graphics::minDepth; + drule::BaseRule const * pSymbolRule = NULL; + double symbolDepth = graphics::minDepth; // separating path rules from other for (size_t i = 0; i < rules.size(); ++i) @@ -322,10 +359,24 @@ void Drawer::Draw(di::FeatureInfo const & fi) bool const hasSymbol = pRule->GetSymbol() != 0; bool const isCaption = pRule->GetCaption(0) != 0; + if (pSymbolRule == NULL && pRule->GetSymbol() != 0) + { + pSymbolRule = pRule; + symbolDepth = rules[i].m_depth; + } + + if (pCircleRule == NULL && pRule->GetCircle() != 0) + { + pCircleRule = pRule; + circleDepth = rules[i].m_depth; + } + if (!isCaption && isPath && !hasSymbol && (pRule->GetLine() != 0)) pathRules.push_back(rules[i]); } + isCircleAndSymbol = pSymbolRule != NULL && pCircleRule != NULL; + if (!pathRules.empty()) { for (list::const_iterator i = fi.m_pathes.begin(); i != fi.m_pathes.end(); ++i) @@ -352,6 +403,14 @@ void Drawer::Draw(di::FeatureInfo const & fi) { if (isFill) drawArea(*i, di::DrawRule(pRule, depth, false)); + else if (isCircleAndSymbol) + { + drawCircledSymbol(i->GetCenter(), + graphics::EPosCenter, + di::DrawRule(pSymbolRule, symbolDepth, false), + di::DrawRule(pCircleRule, circleDepth, false), + id); + } else if (isSymbol) drawSymbol(i->GetCenter(), graphics::EPosCenter, di::DrawRule(pRule, depth, false), id); else if (isCircle) @@ -362,7 +421,15 @@ void Drawer::Draw(di::FeatureInfo const & fi) // draw point symbol if (!isPath && !isArea && ((pRule->GetType() & drule::node) != 0)) { - if (isSymbol) + if (isCircleAndSymbol) + { + drawCircledSymbol(fi.m_point, + graphics::EPosCenter, + di::DrawRule(pSymbolRule, symbolDepth, false), + di::DrawRule(pCircleRule, circleDepth, false), + id); + } + else if (isSymbol) drawSymbol(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id); else if (isCircle) drawCircle(fi.m_point, graphics::EPosCenter, di::DrawRule(pRule, depth, false), id); diff --git a/map/drawer.hpp b/map/drawer.hpp index 181487ef20..700f7b86f6 100644 --- a/map/drawer.hpp +++ b/map/drawer.hpp @@ -50,6 +50,12 @@ protected: di::DrawRule const & rule, FeatureID const & id); + void drawCircledSymbol(m2::PointD const & pt, + graphics::EPosition pos, + di::DrawRule const & symbolRule, + di::DrawRule const & circleRule, + FeatureID const & id); + void drawPath(di::PathInfo const & path, di::DrawRule const * rules, size_t count);