text-like symbol filtering. filters symbols with the same name, so they doesn't overlap each other. symbols with different names *can* overlap.

This commit is contained in:
rachytski 2011-02-03 01:04:14 +02:00 committed by Alex Zolotarev
parent a0d22c5a8f
commit c25de88fed
8 changed files with 176 additions and 55 deletions

View file

@ -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<m2::PointD> const & pts, rule_ptr_t pRule, int depth)

View file

@ -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)

View file

@ -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);

108
yg/symbol_renderer.cpp Normal file
View file

@ -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();
}
}
}

47
yg/symbol_renderer.hpp Normal file
View file

@ -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<uint32_t, m4::Tree<SymbolObject> > 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();
};
}
}

View file

@ -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());
}
}

View file

@ -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 {

View file

@ -917,6 +917,15 @@ namespace
}
};
struct TestDrawSymbolFiltering
{
void DoDraw(shared_ptr<yg::gl::Screen> 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);
}