diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index 8ebde1b060..fbf7988485 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -81,7 +81,7 @@ void DrawerYG::onSize(int w, int h) void DrawerYG::drawSymbol(m2::PointD const & pt, string const & symbolName, yg::EPosition pos, int depth) { - m_pScreen->drawPoint(pt, m_pSkin->mapSymbol(symbolName.c_str()), pos, depth); + m_pScreen->drawSymbol(pt, m_pSkin->mapSymbol(symbolName.c_str()), pos, depth); } void DrawerYG::drawSymbol(m2::PointD const & pt, rule_ptr_t pRule, yg::EPosition pos, int depth) @@ -105,7 +105,7 @@ void DrawerYG::drawSymbol(m2::PointD const & pt, rule_ptr_t pRule, yg::EPosition } } - m_pScreen->drawPoint(pt, id, pos, depth); + m_pScreen->drawSymbol(pt, id, pos, depth); } void DrawerYG::drawPath(vector const & pts, rule_ptr_t pRule, int depth) diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index 1299600856..edca146902 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -205,39 +205,6 @@ namespace yg // } } - void GeometryBatcher::drawPoint(m2::PointD const & pt, uint32_t styleID, EPosition pos, double depth) - { - ResourceStyle const * style(m_skin->fromID(styleID)); - - if (!hasRoom(4, 6, style->m_pageID)) - flush(style->m_pageID); - - m2::RectU texRect(style->m_texRect); - texRect.Inflate(-1, -1); - - m2::PointD posPt; - - if (pos & EPosLeft) - posPt.x = pt.x - texRect.SizeX(); - else if (pos & EPosRight) - posPt.x = pt.x; - else - posPt.x = pt.x - texRect.SizeX() / 2; - - if (pos & EPosAbove) - posPt.y = pt.y - texRect.SizeY(); - else if (pos & EPosUnder) - posPt.y = pt.y; - else - posPt.y = pt.y - texRect.SizeY() / 2; - - - drawTexturedPolygon(m2::PointD(0.0, 0.0), 0.0, - texRect.minX(), texRect.minY(), texRect.maxX(), texRect.maxY(), - posPt.x, posPt.y, posPt.x + texRect.SizeX(), posPt.y + texRect.SizeY(), - depth, - style->m_pageID); - } void GeometryBatcher::drawTrianglesList(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth) diff --git a/yg/shape_renderer.hpp b/yg/shape_renderer.hpp index c89bd5bf21..0e0f8dd6cb 100644 --- a/yg/shape_renderer.hpp +++ b/yg/shape_renderer.hpp @@ -1,15 +1,15 @@ #pragma once -#include "text_renderer.hpp" +#include "symbol_renderer.hpp" namespace yg { namespace gl { - class ShapeRenderer : public TextRenderer + class ShapeRenderer : public SymbolRenderer { private: - typedef TextRenderer base_t; + typedef SymbolRenderer base_t; public: ShapeRenderer(base_t::Params const & params); diff --git a/yg/symbol_renderer.cpp b/yg/symbol_renderer.cpp new file mode 100644 index 0000000000..26560ebe0a --- /dev/null +++ b/yg/symbol_renderer.cpp @@ -0,0 +1,108 @@ +#include "../base/SRC_FIRST.hpp" +#include "symbol_renderer.hpp" +#include "skin.hpp" +#include "../std/bind.hpp" + +namespace yg +{ + namespace gl + { + SymbolRenderer::SymbolRenderer(base_t::Params const & params) : base_t(params) + {} + + SymbolRenderer::SymbolObject::SymbolObject(m2::PointD const & pt, uint32_t styleID, EPosition pos, double depth) + : m_pt(pt), m_pos(pos), m_styleID(styleID), m_depth(depth) + {} + + m2::RectD const SymbolRenderer::SymbolObject::GetLimitRect(SymbolRenderer * p) const + { + ResourceStyle const * style = p->skin()->fromID(m_styleID); + + m2::RectU texRect(style->m_texRect); + texRect.Inflate(-1, -1); + + m2::PointD posPt = p->getPosPt(m_pt, m2::RectD(texRect), m_pos); + + return m2::RectD(posPt, posPt + m2::PointD(texRect.SizeX(), texRect.SizeY())); + } + + void SymbolRenderer::SymbolObject::Draw(SymbolRenderer * p) const + { + p->drawSymbolImpl(m_pt, m_styleID, m_pos, m_depth); + } + + m2::PointD const SymbolRenderer::getPosPt(m2::PointD const & pt, m2::RectD const & texRect, EPosition pos) + { + m2::PointD posPt; + + if (pos & EPosLeft) + posPt.x = pt.x - texRect.SizeX(); + else if (pos & EPosRight) + posPt.x = pt.x; + else + posPt.x = pt.x - texRect.SizeX() / 2; + + if (pos & EPosAbove) + posPt.y = pt.y - texRect.SizeY(); + else if (pos & EPosUnder) + posPt.y = pt.y; + else + posPt.y = pt.y - texRect.SizeY() / 2; + + return posPt; + } + + void SymbolRenderer::drawSymbolImpl(m2::PointD const & pt, uint32_t styleID, EPosition pos, int depth) + { + ResourceStyle const * style(skin()->fromID(styleID)); + + m2::RectU texRect(style->m_texRect); + texRect.Inflate(-1, -1); + + m2::PointD posPt = getPosPt(pt, m2::RectD(texRect), pos); + + drawTexturedPolygon(m2::PointD(0.0, 0.0), 0.0, + texRect.minX(), texRect.minY(), texRect.maxX(), texRect.maxY(), + posPt.x, posPt.y, posPt.x + texRect.SizeX(), posPt.y + texRect.SizeY(), + depth, + style->m_pageID); + } + + void mark_intersect(bool & flag) + { + flag = true; + } + + void SymbolRenderer::drawSymbol(m2::PointD const & pt, uint32_t styleID, EPosition pos, int depth) + { + SymbolObject obj(pt, styleID, pos, depth); + m2::RectD r = obj.GetLimitRect(this); + + bool isIntersect = false; + + m_symbolsMap[styleID].ForEachInRect(obj.GetLimitRect(this), bind(&mark_intersect, ref(isIntersect))); + + if (!isIntersect) + m_symbolsMap[styleID].Add(obj, r); + } + + void SymbolRenderer::setClipRect(m2::RectI const & rect) + { + for (symbols_map_t::const_iterator it = m_symbolsMap.begin(); it != m_symbolsMap.end(); ++it) + it->second.ForEach(bind(&SymbolObject::Draw, _1, this)); + m_symbolsMap.clear(); + + base_t::setClipRect(rect); + } + + void SymbolRenderer::endFrame() + { + for (symbols_map_t::const_iterator it = m_symbolsMap.begin(); it != m_symbolsMap.end(); ++it) + it->second.ForEach(bind(&SymbolObject::Draw, _1, this)); + m_symbolsMap.clear(); + + base_t::endFrame(); + } + + } +} diff --git a/yg/symbol_renderer.hpp b/yg/symbol_renderer.hpp new file mode 100644 index 0000000000..91eeb5f714 --- /dev/null +++ b/yg/symbol_renderer.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "text_renderer.hpp" +#include "../geometry/tree4d.hpp" +#include "../std/map.hpp" + +namespace yg +{ + namespace gl + { + class SymbolRenderer : public TextRenderer + { + private: + + struct SymbolObject + { + m2::PointD m_pt; + EPosition m_pos; + uint32_t m_styleID; + double m_depth; + + SymbolObject(m2::PointD const & pt, uint32_t styleID, EPosition pos, double depth); + + m2::RectD const GetLimitRect(SymbolRenderer * p) const; + void Draw(SymbolRenderer * p) const; + }; + + typedef map > symbols_map_t; + symbols_map_t m_symbolsMap; + + m2::PointD const getPosPt(m2::PointD const & pt, m2::RectD const & texRect, EPosition pos); + + void drawSymbolImpl(m2::PointD const & pt, uint32_t styleID, EPosition pos, int depth); + + public: + + typedef TextRenderer base_t; + + SymbolRenderer(base_t::Params const & params); + + void drawSymbol(m2::PointD const & pt, uint32_t styleID, EPosition pos, int depth); + + void setClipRect(m2::RectI const & rect); + void endFrame(); + }; + } +} diff --git a/yg/text_renderer.cpp b/yg/text_renderer.cpp index b984798103..7d568b8a07 100644 --- a/yg/text_renderer.cpp +++ b/yg/text_renderer.cpp @@ -53,19 +53,6 @@ namespace yg { TextObj obj(pt, utf8Text, fontSize, color, isMasked, maskColor, depth, isFixedFont, log2vis); m2::RectD r = obj.GetLimitRect(this); - /* - m2::PointD pts[5] = - { - m2::PointD(r.minX(), r.minY()), - m2::PointD(r.minX(), r.maxY()), - m2::PointD(r.maxX(), r.maxY()), - m2::PointD(r.maxX(), r.minY()), - m2::PointD(r.minX(), r.minY()) - }; - - drawPath(pts, 5, skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 2, 0, 0, 0)), depth); - */ - m_tree.ReplaceIf(obj, r, TextObj::better_depth()); } } diff --git a/yg/yg.pro b/yg/yg.pro index c22a601673..85f4b8c0b8 100644 --- a/yg/yg.pro +++ b/yg/yg.pro @@ -58,7 +58,8 @@ SOURCES += \ text_renderer.cpp \ layer_manager.cpp \ path_renderer.cpp \ - shape_renderer.cpp + shape_renderer.cpp \ + symbol_renderer.cpp HEADERS += \ internal/opengl.hpp \ @@ -104,7 +105,8 @@ HEADERS += \ gpu_state.hpp \ defines.hpp \ path_renderer.hpp \ - shape_renderer.hpp + shape_renderer.hpp \ + symbol_renderer.hpp !iphonesimulator-g++42 { !iphonedevice-g++42 { diff --git a/yg/yg_tests/screengl_test.cpp b/yg/yg_tests/screengl_test.cpp index aea95f3fce..37af0a988d 100644 --- a/yg/yg_tests/screengl_test.cpp +++ b/yg/yg_tests/screengl_test.cpp @@ -917,6 +917,15 @@ namespace } }; + struct TestDrawSymbolFiltering + { + void DoDraw(shared_ptr const & p) + { + for (int i = 0; i < 40; ++i) + p->drawSymbol(m2::PointD(100 + i, 100), p->skin()->mapSymbol("hospital"), yg::EPosCenter, 0); + } + }; + // UNIT_TEST_GL(TestDrawPolyOverflow); // UNIT_TEST_GL(TestDrawText); // UNIT_TEST_GL(TestDrawSingleSymbol); @@ -924,7 +933,7 @@ namespace // UNIT_TEST_GL(TestDrawSingleSymbolAndSolidPath); // UNIT_TEST_GL(TestDrawString); // UNIT_TEST_GL(TestDrawStringWithFixedFont); - UNIT_TEST_GL(TestDrawStringWithColor); +// UNIT_TEST_GL(TestDrawStringWithColor); // UNIT_TEST_GL(TestDrawUnicodeSymbols); // UNIT_TEST_GL(TestDrawTextRectWithFixedFont); // UNIT_TEST_GL(TestDrawStringOnString); @@ -932,7 +941,7 @@ namespace // UNIT_TEST_GL(TestDrawTextOnPathWithOffset); // UNIT_TEST_GL(TestDrawTextOverflow); // UNIT_TEST_GL(TestDrawTextFiltering); - UNIT_TEST_GL(TestDrawRandomTextFiltering); +// UNIT_TEST_GL(TestDrawRandomTextFiltering); // UNIT_TEST_GL(TestDrawSGIConvex); // UNIT_TEST_GL(TestDrawPoly); // UNIT_TEST_GL(TestDrawSolidRect); @@ -948,4 +957,5 @@ namespace // UNIT_TEST_GL(TestDrawPathSolidWithClipRect); // UNIT_TEST_GL(TestDrawUtilsRect); // UNIT_TEST_GL(TestDrawUtilsRectFilledTexture); + UNIT_TEST_GL(TestDrawSymbolFiltering); }