Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-06-15 10:20:24 +0300
committerr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-06-16 14:19:03 +0300
commitab8d3579d50fddbc9296c769ec99cff06164f3cc (patch)
tree874f361ee405983c8ed6d147571a50863628bece
parent8606c53a1c1f19da6e736b5a71a6830cbd02a8af (diff)
Improved metaline rendering
-rw-r--r--drape/color.hpp1
-rw-r--r--drape/dynamic_texture.hpp57
-rw-r--r--drape/font_texture.hpp3
-rw-r--r--drape/glyph_manager.cpp72
-rw-r--r--drape/glyph_manager.hpp22
-rw-r--r--drape/overlay_handle.cpp10
-rw-r--r--drape/overlay_handle.hpp9
-rw-r--r--drape/overlay_tree.cpp7
-rw-r--r--drape/render_bucket.cpp4
-rw-r--r--drape/stipple_pen_resource.cpp8
-rw-r--r--drape/texture.cpp2
-rw-r--r--drape/texture.hpp8
-rw-r--r--drape/texture_manager.cpp45
-rw-r--r--drape/texture_manager.hpp51
-rw-r--r--drape_frontend/apply_feature_functors.cpp308
-rw-r--r--drape_frontend/apply_feature_functors.hpp45
-rw-r--r--drape_frontend/colored_symbol_shape.cpp150
-rw-r--r--drape_frontend/colored_symbol_shape.hpp4
-rw-r--r--drape_frontend/path_text_shape.cpp155
-rw-r--r--drape_frontend/path_text_shape.hpp35
-rw-r--r--drape_frontend/poi_symbol_shape.cpp80
-rw-r--r--drape_frontend/poi_symbol_shape.hpp10
-rw-r--r--drape_frontend/rule_drawer.cpp18
-rw-r--r--drape_frontend/rule_drawer.hpp5
-rw-r--r--drape_frontend/shape_view_params.hpp7
-rw-r--r--drape_frontend/stylist.cpp9
-rw-r--r--drape_frontend/stylist.hpp1
-rw-r--r--drape_frontend/text_layout.cpp148
-rw-r--r--drape_frontend/text_layout.hpp34
-rw-r--r--drape_frontend/text_shape.cpp11
-rw-r--r--geometry/spline.cpp8
-rw-r--r--geometry/spline.hpp2
-rw-r--r--indexer/road_shields_parser.hpp17
33 files changed, 802 insertions, 544 deletions
diff --git a/drape/color.hpp b/drape/color.hpp
index f000f2becd..b198796a76 100644
--- a/drape/color.hpp
+++ b/drape/color.hpp
@@ -38,6 +38,7 @@ struct Color
static Color White() { return Color(255, 255, 255, 255); }
static Color Red() { return Color(255, 0, 0, 255); }
static Color Green() { return Color(0, 255, 0, 255); }
+ static Color Yellow() { return Color(255, 255, 0, 255); }
static Color Transparent() { return Color(0, 0, 0, 0); }
private:
diff --git a/drape/dynamic_texture.hpp b/drape/dynamic_texture.hpp
index 22c33aae30..f0b23ab4cf 100644
--- a/drape/dynamic_texture.hpp
+++ b/drape/dynamic_texture.hpp
@@ -3,19 +3,20 @@
#include "drape/texture.hpp"
#include "drape/glconstants.hpp"
+#include <vector>
+
namespace dp
{
-
template<typename TIndexer, typename TResourceKey, Texture::ResourceType TResourceType>
class DynamicTexture : public Texture
{
public:
- virtual ~DynamicTexture()
+ ~DynamicTexture() override
{
ASSERT(m_indexer == nullptr, ());
}
- virtual ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource)
+ ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) override
{
ASSERT(m_indexer != nullptr, ());
if (key.GetType() != TResourceType)
@@ -24,13 +25,36 @@ public:
return m_indexer->MapResource(static_cast<TResourceKey const &>(key), newResource);
}
- virtual void UpdateState()
+ void UpdateState() override
{
+ // Create texture before first uploading.
+ if (m_hwTexture == nullptr)
+ {
+ std::vector<uint8_t> initData(m_params.m_width * m_params.m_height *
+ GetBytesPerPixel(m_params.m_format), 0);
+ Create(m_params, initData.data());
+ }
+
ASSERT(m_indexer != nullptr, ());
Bind();
m_indexer->UploadResources(make_ref(this));
}
+ TextureFormat GetFormat() const override
+ {
+ return m_hwTexture == nullptr ? m_params.m_format : Texture::GetFormat();
+ }
+
+ uint32_t GetWidth() const override
+ {
+ return m_hwTexture == nullptr ? m_params.m_width : Texture::GetWidth();
+ }
+
+ uint32_t GetHeight() const override
+ {
+ return m_hwTexture == nullptr ? m_params.m_height : Texture::GetHeight();
+ }
+
protected:
DynamicTexture() {}
@@ -45,22 +69,13 @@ protected:
void Init(ref_ptr<HWTextureAllocator> allocator, ref_ptr<TIndexer> indexer,
TextureParams const & params)
{
- Init(allocator, indexer, params, nullptr);
- }
-
- void Init(ref_ptr<HWTextureAllocator> allocator, ref_ptr<TIndexer> indexer,
- TextureParams const & params, ref_ptr<void> data)
- {
m_indexer = indexer;
- Texture::Params p;
- p.m_allocator = allocator;
- p.m_width = params.m_size.x;
- p.m_height = params.m_size.y;
- p.m_format = params.m_format;
- p.m_filter = params.m_filter;
- p.m_usePixelBuffer = params.m_usePixelBuffer;
-
- Create(p, data);
+ m_params.m_allocator = allocator;
+ m_params.m_width = params.m_size.x;
+ m_params.m_height = params.m_size.y;
+ m_params.m_format = params.m_format;
+ m_params.m_filter = params.m_filter;
+ m_params.m_usePixelBuffer = params.m_usePixelBuffer;
}
void Reset()
@@ -69,6 +84,6 @@ protected:
}
ref_ptr<TIndexer> m_indexer;
+ Texture::Params m_params;
};
-
-}
+} // namespace dp
diff --git a/drape/font_texture.hpp b/drape/font_texture.hpp
index c18267436c..b4e4a0144e 100644
--- a/drape/font_texture.hpp
+++ b/drape/font_texture.hpp
@@ -153,8 +153,7 @@ public:
: m_index(size, glyphMng)
{
TBase::TextureParams params{size, TextureFormat::ALPHA, gl_const::GLLinear, true /* m_usePixelBuffer */};
- vector<uint8_t> initData(params.m_size.x * params.m_size.y, 0);
- TBase::Init(allocator, make_ref(&m_index), params, make_ref(initData.data()));
+ TBase::Init(allocator, make_ref(&m_index), params);
}
~FontTexture() { TBase::Reset(); }
diff --git a/drape/glyph_manager.cpp b/drape/glyph_manager.cpp
index 338a0db5d1..de016f6905 100644
--- a/drape/glyph_manager.cpp
+++ b/drape/glyph_manager.cpp
@@ -10,10 +10,10 @@
#include "base/math.hpp"
#include "base/timer.hpp"
-#include "std/limits.hpp"
-#include "std/sstream.hpp"
-#include "std/unique_ptr.hpp"
-#include "std/unordered_set.hpp"
+#include <limits>
+#include <memory>
+#include <set>
+#include <sstream>
#include <ft2build.h>
#include FT_TYPES_H
@@ -61,10 +61,8 @@
namespace dp
{
-
namespace
{
-
int const kInvalidFont = -1;
template <typename ToDo>
@@ -81,7 +79,7 @@ void ParseUniBlocks(string const & uniBlocksFile, ToDo toDo)
return;
}
- istringstream fin(uniBlocks);
+ std::istringstream fin(uniBlocks);
while (true)
{
string name;
@@ -109,7 +107,7 @@ void ParseFontList(string const & fontListFile, ToDo toDo)
return;
}
- istringstream fin(fontList);
+ std::istringstream fin(fontList);
while (true)
{
string ubName;
@@ -196,7 +194,7 @@ public:
FT_Bitmap bitmap = m_fontFace->glyph->bitmap;
- float const scale = isSdf ? 1.0f / m_sdfScale : 1.0;
+ float const scale = isSdf ? 1.0f / m_sdfScale : 1.0f;
SharedBufferManager::shared_buffer_ptr_t data;
uint32_t imageWidth = bitmap.width;
@@ -251,8 +249,8 @@ public:
};
result.m_code = unicodePoint;
- result.m_fixedSize = isSdf ? GlyphManager::kDynamicGlyphSize : baseHeight;
-
+ result.m_fixedSize = isSdf ? GlyphManager::kDynamicGlyphSize
+ : static_cast<int>(baseHeight);
FT_Done_Glyph(glyph);
return result;
@@ -342,24 +340,22 @@ private:
std::set<pair<strings::UniChar, int>> m_readyGlyphs;
};
-
}
-/// Information about single unicode block.
+// Information about single unicode block.
struct UnicodeBlock
{
string m_name;
strings::UniChar m_start;
strings::UniChar m_end;
- vector<int> m_fontsWeight;
+ std::vector<int> m_fontsWeight;
UnicodeBlock(string const & name, strings::UniChar start, strings::UniChar end)
: m_name(name)
, m_start(start)
, m_end(end)
- {
- }
+ {}
int GetFontOffset(int idx) const
{
@@ -367,12 +363,12 @@ struct UnicodeBlock
return kInvalidFont;
int maxWeight = 0;
- int upperBoundWeight = numeric_limits<int>::max();
+ int upperBoundWeight = std::numeric_limits<int>::max();
if (idx != kInvalidFont)
upperBoundWeight = m_fontsWeight[idx];
int index = kInvalidFont;
- ASSERT_LESS(m_fontsWeight.size(), static_cast<size_t>(numeric_limits<int>::max()), ());
+ ASSERT_LESS(m_fontsWeight.size(), static_cast<size_t>(std::numeric_limits<int>::max()), ());
for (size_t i = 0; i < m_fontsWeight.size(); ++i)
{
int w = m_fontsWeight[i];
@@ -392,8 +388,8 @@ struct UnicodeBlock
}
};
-typedef vector<UnicodeBlock> TUniBlocks;
-typedef TUniBlocks::const_iterator TUniBlockIter;
+using TUniBlocks = std::vector<UnicodeBlock>;
+using TUniBlockIter = TUniBlocks::const_iterator;
const int GlyphManager::kDynamicGlyphSize = -1;
@@ -402,7 +398,7 @@ struct GlyphManager::Impl
FT_Library m_library;
TUniBlocks m_blocks;
TUniBlockIter m_lastUsedBlock;
- vector<unique_ptr<Font>> m_fonts;
+ std::vector<std::unique_ptr<Font>> m_fonts;
uint32_t m_baseGlyphHeight;
};
@@ -412,24 +408,25 @@ GlyphManager::GlyphManager(GlyphManager::Params const & params)
{
m_impl->m_baseGlyphHeight = params.m_baseGlyphHeight;
- typedef pair<string, string> TFontAndBlockName;
- typedef buffer_vector<TFontAndBlockName, 64> TFontLst;
+ using TFontAndBlockName = pair<std::string, std::string>;
+ using TFontLst = buffer_vector<TFontAndBlockName, 64>;
TFontLst whitelst;
TFontLst blacklst;
m_impl->m_blocks.reserve(160);
- ParseUniBlocks(params.m_uniBlocks, [this](string const & name, strings::UniChar start, strings::UniChar end)
+ ParseUniBlocks(params.m_uniBlocks, [this](std::string const & name,
+ strings::UniChar start, strings::UniChar end)
{
m_impl->m_blocks.push_back(UnicodeBlock(name, start, end));
});
- ParseFontList(params.m_whitelist, [&whitelst](string const & ubName, string const & fontName)
+ ParseFontList(params.m_whitelist, [&whitelst](std::string const & ubName, std::string const & fontName)
{
whitelst.push_back(TFontAndBlockName(fontName, ubName));
});
- ParseFontList(params.m_blacklist, [&blacklst](string const & ubName, string const & fontName)
+ ParseFontList(params.m_blacklist, [&blacklst](std::string const & ubName, std::string const & fontName)
{
blacklst.push_back(TFontAndBlockName(fontName, ubName));
});
@@ -438,7 +435,7 @@ GlyphManager::GlyphManager(GlyphManager::Params const & params)
FREETYPE_CHECK(FT_Init_FreeType(&m_impl->m_library));
- for (string const & fontName : params.m_fonts)
+ for (auto const & fontName : params.m_fonts)
{
bool ignoreFont = false;
for_each(blacklst.begin(), blacklst.end(), [&ignoreFont, &fontName](TFontAndBlockName const & p)
@@ -450,10 +447,11 @@ GlyphManager::GlyphManager(GlyphManager::Params const & params)
if (ignoreFont)
continue;
- vector<FT_ULong> charCodes;
+ std::vector<FT_ULong> charCodes;
try
{
- m_impl->m_fonts.emplace_back(make_unique<Font>(params.m_sdfScale, GetPlatform().GetReader(fontName), m_impl->m_library));
+ m_impl->m_fonts.emplace_back(my::make_unique<Font>(params.m_sdfScale, GetPlatform().GetReader(fontName),
+ m_impl->m_library));
m_impl->m_fonts.back()->GetCharcodes(charCodes);
}
catch(RootException const & e)
@@ -462,10 +460,10 @@ GlyphManager::GlyphManager(GlyphManager::Params const & params)
continue;
}
- typedef size_t TBlockIndex;
- typedef int TCharCounter;
- typedef pair<TBlockIndex, TCharCounter> TCoverNode;
- typedef vector<TCoverNode> TCoverInfo;
+ using TBlockIndex = size_t;
+ using TCharCounter = int;
+ using TCoverNode = std::pair<TBlockIndex, TCharCounter>;
+ using TCoverInfo = std::vector<TCoverNode>;
size_t currentUniBlock = 0;
TCoverInfo coverInfo;
@@ -487,7 +485,7 @@ GlyphManager::GlyphManager(GlyphManager::Params const & params)
++coverInfo.back().second;
}
- typedef function<void (UnicodeBlock const & uniBlock, TCoverNode & node)> TUpdateCoverInfoFn;
+ using TUpdateCoverInfoFn = std::function<void(UnicodeBlock const & uniBlock, TCoverNode & node)>;
auto enumerateFn = [this, &coverInfo, &fontName] (TFontLst const & lst, TUpdateCoverInfoFn const & fn)
{
for (TFontAndBlockName const & b : lst)
@@ -588,7 +586,8 @@ int GlyphManager::GetFontIndexImmutable(strings::UniChar unicodePoint) const
int GlyphManager::FindFontIndexInBlock(UnicodeBlock const & block, strings::UniChar unicodePoint) const
{
ASSERT(block.HasSymbol(unicodePoint), ());
- for (int fontIndex = block.GetFontOffset(kInvalidFont); fontIndex != kInvalidFont; fontIndex = block.GetFontOffset(fontIndex))
+ for (int fontIndex = block.GetFontOffset(kInvalidFont); fontIndex != kInvalidFont;
+ fontIndex = block.GetFontOffset(fontIndex))
{
ASSERT_LESS(fontIndex, static_cast<int>(m_impl->m_fonts.size()), ());
auto const & f = m_impl->m_fonts[fontIndex];
@@ -671,5 +670,4 @@ GlyphManager::Glyph GlyphManager::GetInvalidGlyph(int fixedSize) const
return s_glyph;
}
-
-}
+} // namespace dp
diff --git a/drape/glyph_manager.hpp b/drape/glyph_manager.hpp
index fbbacf19d7..a120064fa3 100644
--- a/drape/glyph_manager.hpp
+++ b/drape/glyph_manager.hpp
@@ -3,15 +3,12 @@
#include "base/shared_buffer_manager.hpp"
#include "base/string_utils.hpp"
-#include "std/unique_ptr.hpp"
-#include "std/string.hpp"
-#include "std/vector.hpp"
-
-#include "std/function.hpp"
+#include <string>
+#include <vector>
+#include <functional>
namespace dp
{
-
uint32_t constexpr kSdfBorder = 4;
struct UnicodeBlock;
@@ -23,11 +20,11 @@ public:
struct Params
{
- string m_uniBlocks;
- string m_whitelist;
- string m_blacklist;
+ std::string m_uniBlocks;
+ std::string m_whitelist;
+ std::string m_blacklist;
- vector<string> m_fonts;
+ std::vector<std::string> m_fonts;
uint32_t m_baseGlyphHeight = 22;
uint32_t m_sdfScale = 4;
@@ -85,7 +82,7 @@ public:
void MarkGlyphReady(Glyph const & glyph);
bool AreGlyphsReady(strings::UniString const & str, int fixedSize) const;
- typedef function<void (strings::UniChar start, strings::UniChar end)> TUniBlockCallback;
+ using TUniBlockCallback = std::function<void(strings::UniChar start, strings::UniChar end)>;
void ForEachUnicodeBlock(TUniBlockCallback const & fn) const;
Glyph GetInvalidGlyph(int fixedSize) const;
@@ -102,5 +99,4 @@ private:
struct Impl;
Impl * m_impl;
};
-
-}
+} // namespace dp
diff --git a/drape/overlay_handle.cpp b/drape/overlay_handle.cpp
index 3dc72915c5..8ca15e7591 100644
--- a/drape/overlay_handle.cpp
+++ b/drape/overlay_handle.cpp
@@ -199,11 +199,13 @@ uint64_t OverlayHandle::GetPriorityInFollowingMode() const
return GetPriority();
}
SquareHandle::SquareHandle(OverlayID const & id, dp::Anchor anchor, m2::PointD const & gbPivot,
- m2::PointD const & pxSize, uint64_t priority, bool isBound,
- string const & debugStr, bool isBillboard)
+ m2::PointD const & pxSize, m2::PointD const & pxOffset,
+ uint64_t priority, bool isBound, string const & debugStr,
+ bool isBillboard)
: TBase(id, anchor, priority, isBillboard)
, m_gbPivot(gbPivot)
, m_pxHalfSize(pxSize.x / 2.0, pxSize.y / 2.0)
+ , m_pxOffset(pxOffset)
, m_isBound(isBound)
#ifdef DEBUG_OVERLAYS_OUTPUT
, m_debugStr(debugStr)
@@ -215,8 +217,8 @@ m2::RectD SquareHandle::GetPixelRect(ScreenBase const & screen, bool perspective
if (perspective)
return GetPixelRectPerspective(screen);
- m2::PointD const pxPivot = screen.GtoP(m_gbPivot);
- m2::RectD result(pxPivot - m_pxHalfSize, pxPivot + m_pxHalfSize);
+ m2::PointD const pxPivot = screen.GtoP(m_gbPivot) + m_pxOffset;
+ m2::RectD result(pxPivot - m_pxHalfSize, pxPivot + m_pxHalfSize);
m2::PointD offset(0.0, 0.0);
if (m_anchor & dp::Left)
diff --git a/drape/overlay_handle.hpp b/drape/overlay_handle.hpp
index 762f63aeb4..17f5b604a7 100644
--- a/drape/overlay_handle.hpp
+++ b/drape/overlay_handle.hpp
@@ -141,6 +141,9 @@ public:
void SetCachingEnable(bool enable);
+ void SetReady(bool isReady) { m_isReady = isReady; }
+ bool IsReady() const { return m_isReady; }
+
#ifdef DEBUG_OVERLAYS_OUTPUT
virtual string GetOverlayDebugInfo() { return ""; }
#endif
@@ -182,6 +185,8 @@ private:
mutable bool m_extendedShapeDirty;
mutable m2::RectD m_extendedRectCache;
mutable bool m_extendedRectDirty;
+
+ bool m_isReady = false;
};
class SquareHandle : public OverlayHandle
@@ -190,7 +195,8 @@ class SquareHandle : public OverlayHandle
public:
SquareHandle(OverlayID const & id, dp::Anchor anchor, m2::PointD const & gbPivot,
- m2::PointD const & pxSize, uint64_t priority, bool isBound, string const & debugStr,
+ m2::PointD const & pxSize, m2::PointD const & pxOffset,
+ uint64_t priority, bool isBound, string const & debugStr,
bool isBillboard = false);
m2::RectD GetPixelRect(ScreenBase const & screen, bool perspective) const override;
@@ -204,6 +210,7 @@ public:
private:
m2::PointD m_gbPivot;
m2::PointD m_pxHalfSize;
+ m2::PointD m_pxOffset;
bool m_isBound;
#ifdef DEBUG_OVERLAYS_OUTPUT
diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp
index 6f4de7928c..ff822bf11c 100644
--- a/drape/overlay_tree.cpp
+++ b/drape/overlay_tree.cpp
@@ -146,7 +146,14 @@ void OverlayTree::Add(ref_ptr<OverlayHandle> handle)
// Skip not-ready handles.
if (!handle->Update(modelView))
+ {
+ handle->SetReady(false);
return;
+ }
+ else
+ {
+ handle->SetReady(true);
+ }
// Clip handles which are out of screen.
double const kScreenRectScale = 1.2;
diff --git a/drape/render_bucket.cpp b/drape/render_bucket.cpp
index 12bf972c86..fbcf3c1df2 100644
--- a/drape/render_bucket.cpp
+++ b/drape/render_bucket.cpp
@@ -131,7 +131,9 @@ void RenderBucket::RenderDebug(ScreenBase const & screen) const
continue;
DebugRectRenderer::Instance().DrawRect(screen, rect, handle->IsVisible() ?
- dp::Color::Green() : dp::Color::Red());
+ dp::Color::Green() :
+ (handle->IsReady() ? dp::Color::Red() :
+ dp::Color::Yellow()));
}
}
}
diff --git a/drape/stipple_pen_resource.cpp b/drape/stipple_pen_resource.cpp
index c78308cadc..9a0c886022 100644
--- a/drape/stipple_pen_resource.cpp
+++ b/drape/stipple_pen_resource.cpp
@@ -11,7 +11,6 @@
namespace dp
{
-
uint32_t const kMaxStipplePenLength = 512;
uint32_t const kStippleHeight = 1;
@@ -124,7 +123,8 @@ void StipplePenRasterizator::Rasterize(void * buffer)
pixels[offset] = pixels[offset - 1];
}
-ref_ptr<Texture::ResourceInfo> StipplePenIndex::ReserveResource(bool predefined, StipplePenKey const & key, bool & newResource)
+ref_ptr<Texture::ResourceInfo> StipplePenIndex::ReserveResource(bool predefined, StipplePenKey const & key,
+ bool & newResource)
{
lock_guard<mutex> g(m_mappingLock);
@@ -203,6 +203,4 @@ string DebugPrint(StipplePenHandle const & key)
out << "0x" << hex << key.m_keyValue;
return out.str();
}
-
-}
-
+} // namespace dp
diff --git a/drape/texture.cpp b/drape/texture.cpp
index e764f5e17b..4b679cd230 100644
--- a/drape/texture.cpp
+++ b/drape/texture.cpp
@@ -6,8 +6,6 @@
#include "base/math.hpp"
-#define ASSERT_ID ASSERT(GetID() != -1, ())
-
namespace dp
{
Texture::ResourceInfo::ResourceInfo(m2::RectF const & texRect) : m_texRect(texRect) {}
diff --git a/drape/texture.hpp b/drape/texture.hpp
index b795855793..dc3a3927db 100644
--- a/drape/texture.hpp
+++ b/drape/texture.hpp
@@ -57,9 +57,10 @@ public:
void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data);
- TextureFormat GetFormat() const;
- uint32_t GetWidth() const;
- uint32_t GetHeight() const;
+ virtual TextureFormat GetFormat() const;
+ virtual uint32_t GetWidth() const;
+ virtual uint32_t GetHeight() const;
+
float GetS(uint32_t x) const;
float GetT(uint32_t y) const;
int32_t GetID() const;
@@ -75,7 +76,6 @@ protected:
void Destroy();
bool AllocateTexture(ref_ptr<HWTextureAllocator> allocator);
-private:
drape_ptr<HWTexture> m_hwTexture;
};
} // namespace dp
diff --git a/drape/texture_manager.cpp b/drape/texture_manager.cpp
index 6c6acc5554..3bf01400b9 100644
--- a/drape/texture_manager.cpp
+++ b/drape/texture_manager.cpp
@@ -272,11 +272,13 @@ bool TextureManager::UpdateDynamicTextures()
ref_ptr<Texture> TextureManager::AllocateGlyphTexture()
{
m2::PointU size(m_maxTextureSize, m_maxTextureSize);
- m_glyphTextures.push_back(make_unique_dp<FontTexture>(size, make_ref(m_glyphManager), make_ref(m_textureAllocator)));
+ m_glyphTextures.push_back(make_unique_dp<FontTexture>(size, make_ref(m_glyphManager),
+ make_ref(m_textureAllocator)));
return make_ref(m_glyphTextures.back());
}
-void TextureManager::GetRegionBase(ref_ptr<Texture> tex, TextureManager::BaseRegion & region, Texture::Key const & key)
+void TextureManager::GetRegionBase(ref_ptr<Texture> tex, TextureManager::BaseRegion & region,
+ Texture::Key const & key)
{
bool isNew = false;
region.SetResourceInfo(tex != nullptr ? tex->FindResource(key, isNew) : nullptr);
@@ -288,7 +290,8 @@ void TextureManager::GetRegionBase(ref_ptr<Texture> tex, TextureManager::BaseReg
size_t TextureManager::FindGlyphsGroup(strings::UniChar const & c) const
{
- auto const iter = lower_bound(m_glyphGroups.begin(), m_glyphGroups.end(), c, [](GlyphGroup const & g, strings::UniChar const & c)
+ auto const iter = std::lower_bound(m_glyphGroups.begin(), m_glyphGroups.end(), c,
+ [](GlyphGroup const & g, strings::UniChar const & c)
{
return g.m_endChar < c;
});
@@ -296,7 +299,7 @@ size_t TextureManager::FindGlyphsGroup(strings::UniChar const & c) const
if (iter == m_glyphGroups.end())
return kInvalidGlyphGroup;
- return distance(m_glyphGroups.begin(), iter);
+ return static_cast<size_t>(std::distance(m_glyphGroups.begin(), iter));
}
size_t TextureManager::FindGlyphsGroup(strings::UniString const & text) const
@@ -304,7 +307,7 @@ size_t TextureManager::FindGlyphsGroup(strings::UniString const & text) const
size_t groupIndex = kInvalidGlyphGroup;
for (auto const & c : text)
{
- // skip glyphs which can be duplicated
+ // Skip glyphs which can be duplicated.
if (c < kDuplicatedGlyphsCount)
continue;
@@ -319,7 +322,7 @@ size_t TextureManager::FindGlyphsGroup(strings::UniString const & text) const
return kInvalidGlyphGroup;
}
- // check if each glyph in text id in one group
+ // Check if each glyph in text id in one group.
if (groupIndex == kInvalidGlyphGroup)
groupIndex = currentIndex;
else if (groupIndex != currentIndex)
@@ -331,7 +334,7 @@ size_t TextureManager::FindGlyphsGroup(strings::UniString const & text) const
}
}
- // all glyphs in duplicated range
+ // All glyphs in duplicated range.
if (groupIndex == kInvalidGlyphGroup)
groupIndex = FindGlyphsGroup(text[0]);
@@ -346,7 +349,8 @@ size_t TextureManager::FindGlyphsGroup(TMultilineText const & text) const
return FindGlyphsGroup(combinedString);
}
-uint32_t TextureManager::GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight, HybridGlyphGroup const & group) const
+uint32_t TextureManager::GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight,
+ HybridGlyphGroup const & group) const
{
uint32_t cnt = 0;
for (auto const & c : text)
@@ -356,7 +360,8 @@ uint32_t TextureManager::GetNumberOfUnfoundCharacters(strings::UniString const &
return cnt;
}
-void TextureManager::MarkCharactersUsage(strings::UniString const & text, int fixedHeight, HybridGlyphGroup & group)
+void TextureManager::MarkCharactersUsage(strings::UniString const & text, int fixedHeight,
+ HybridGlyphGroup & group)
{
for (auto const & c : text)
group.m_glyphs.emplace(make_pair(c, fixedHeight));
@@ -375,7 +380,8 @@ size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text, in
if (group.m_texture != nullptr)
hasEnoughSpace = group.m_texture->HasEnoughSpace(static_cast<uint32_t>(text.size()));
- // if we have got the only hybrid texture (in most cases it is) we can omit checking of glyphs usage
+ // If we have got the only hybrid texture (in most cases it is)
+ // we can omit checking of glyphs usage.
if (hasEnoughSpace)
{
size_t const glyphsCount = group.m_glyphs.size() + text.size();
@@ -383,12 +389,12 @@ size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text, in
return 0;
}
- // looking for a hybrid texture which contains text entirely
+ // Looking for a hybrid texture which contains text entirely.
for (size_t i = 0; i < m_hybridGlyphGroups.size() - 1; i++)
if (GetNumberOfUnfoundCharacters(text, fixedHeight, m_hybridGlyphGroups[i]) == 0)
return i;
- // check if we can contain text in the last hybrid texture
+ // Check if we can contain text in the last hybrid texture.
uint32_t const unfoundChars = GetNumberOfUnfoundCharacters(text, fixedHeight, group);
uint32_t const newCharsCount = static_cast<uint32_t>(group.m_glyphs.size()) + unfoundChars;
if (newCharsCount >= m_maxGlypsCount || !group.m_texture->HasEnoughSpace(unfoundChars))
@@ -544,17 +550,23 @@ void TextureManager::GetColorRegion(Color const & color, ColorRegion & region)
GetRegionBase(make_ref(m_colorTexture), region, ColorKey(color));
}
-void TextureManager::GetGlyphRegions(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers)
+void TextureManager::GetGlyphRegions(TMultilineText const & text, int fixedHeight,
+ TMultilineGlyphsBuffer & buffers)
{
+ std::lock_guard<std::mutex> lock(m_calcGlyphsMutex);
CalcGlyphRegions<TMultilineText, TMultilineGlyphsBuffer>(text, fixedHeight, buffers);
}
-void TextureManager::GetGlyphRegions(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & regions)
+void TextureManager::GetGlyphRegions(strings::UniString const & text, int fixedHeight,
+ TGlyphsBuffer & regions)
{
+ std::lock_guard<std::mutex> lock(m_calcGlyphsMutex);
CalcGlyphRegions<strings::UniString, TGlyphsBuffer>(text, fixedHeight, regions);
}
-uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text, int fixedHeight)
+uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture,
+ strings::UniString const & text,
+ int fixedHeight) const
{
if (texture == nullptr)
return 0;
@@ -563,7 +575,8 @@ uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings:
return static_cast<FontTexture *>(texture.get())->GetAbsentGlyphsCount(text, fixedHeight);
}
-uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text, int fixedHeight)
+uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text,
+ int fixedHeight) const
{
if (texture == nullptr)
return 0;
diff --git a/drape/texture_manager.hpp b/drape/texture_manager.hpp
index fa9edb7167..7255dcb218 100644
--- a/drape/texture_manager.hpp
+++ b/drape/texture_manager.hpp
@@ -10,12 +10,12 @@
#include <atomic>
#include <list>
+#include <mutex>
#include <string>
#include <vector>
namespace dp
{
-
extern std::string const kDefaultSymbolsTexture;
class HWTextureAllocator;
@@ -71,10 +71,10 @@ public:
struct Params
{
- string m_resPostfix;
+ std::string m_resPostfix;
double m_visualScale;
- string m_colors;
- string m_patterns;
+ std::string m_colors;
+ std::string m_patterns;
GlyphManager::Params m_glyphMngParams;
};
@@ -84,27 +84,27 @@ public:
void Init(Params const & params);
void OnSwitchMapStyle();
- void GetSymbolRegion(string const & symbolName, SymbolRegion & region);
+ void GetSymbolRegion(std::string const & symbolName, SymbolRegion & region);
typedef buffer_vector<uint8_t, 8> TStipplePattern;
void GetStippleRegion(TStipplePattern const & pen, StippleRegion & region);
void GetColorRegion(Color const & color, ColorRegion & region);
- typedef buffer_vector<strings::UniString, 4> TMultilineText;
- typedef buffer_vector<GlyphRegion, 128> TGlyphsBuffer;
- typedef buffer_vector<TGlyphsBuffer, 4> TMultilineGlyphsBuffer;
+ using TMultilineText = buffer_vector<strings::UniString, 4>;
+ using TGlyphsBuffer = buffer_vector<GlyphRegion, 128>;
+ using TMultilineGlyphsBuffer = buffer_vector<TGlyphsBuffer, 4>;
void GetGlyphRegions(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers);
void GetGlyphRegions(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & regions);
+ // This method must be called only on Frontend renderer's thread.
+ bool AreGlyphsReady(strings::UniString const & str, int fixedHeight) const;
- /// On some devices OpenGL driver can't resolve situation when we upload on texture from one thread
- /// and use this texture to render on other thread. By this we move UpdateDynamicTextures call into render thread
- /// If you implement some kind of dynamic texture, you must synchronyze UploadData and index creation operations
+ // On some devices OpenGL driver can't resolve situation when we upload to a texture on a thread
+ // and use this texture to render on another thread. By this we move UpdateDynamicTextures call
+ // into render thread. If you implement some kind of dynamic texture, you must synchronize UploadData
+ // and index creation operations.
bool UpdateDynamicTextures();
- /// This method must be called only on Frontend renderer's thread.
- bool AreGlyphsReady(strings::UniString const & str, int fixedHeight) const;
-
ref_ptr<Texture> GetSymbolsTexture() const;
ref_ptr<Texture> GetTrafficArrowTexture() const;
ref_ptr<Texture> GetHatchingTexture() const;
@@ -133,7 +133,7 @@ private:
: m_texture(nullptr)
{}
- std::set<pair<strings::UniChar, int> > m_glyphs;
+ std::set<std::pair<strings::UniChar, int>> m_glyphs;
ref_ptr<Texture> m_texture;
};
@@ -150,14 +150,16 @@ private:
size_t FindHybridGlyphsGroup(strings::UniString const & text, int fixedHeight);
size_t FindHybridGlyphsGroup(TMultilineText const & text, int fixedHeight);
- uint32_t GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight, HybridGlyphGroup const & group) const;
+ uint32_t GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight,
+ HybridGlyphGroup const & group) const;
void MarkCharactersUsage(strings::UniString const & text, int fixedHeight, HybridGlyphGroup & group);
- /// it's a dummy method to support generic code
+ // It's a dummy method to support generic code.
void MarkCharactersUsage(strings::UniString const & text, int fixedHeight, GlyphGroup & group) {}
template<typename TGlyphGroup>
- void FillResultBuffer(strings::UniString const & text, int fixedHeight, TGlyphGroup & group, TGlyphsBuffer & regions)
+ void FillResultBuffer(strings::UniString const & text, int fixedHeight, TGlyphGroup & group,
+ TGlyphsBuffer & regions)
{
if (group.m_texture == nullptr)
group.m_texture = AllocateGlyphTexture();
@@ -172,14 +174,16 @@ private:
}
template<typename TGlyphGroup>
- void FillResults(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & buffers, TGlyphGroup & group)
+ void FillResults(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & buffers,
+ TGlyphGroup & group)
{
MarkCharactersUsage(text, fixedHeight, group);
FillResultBuffer<TGlyphGroup>(text, fixedHeight, group, buffers);
}
template<typename TGlyphGroup>
- void FillResults(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers, TGlyphGroup & group)
+ void FillResults(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers,
+ TGlyphGroup & group)
{
buffers.resize(text.size());
for (size_t i = 0; i < text.size(); ++i)
@@ -218,8 +222,10 @@ private:
}
}
- uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text, int fixedHeight);
- uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text, int fixedHeight);
+ uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text,
+ int fixedHeight) const;
+ uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text,
+ int fixedHeight) const;
template<typename TGlyphGroups>
void UpdateGlyphTextures(TGlyphGroups & groups)
@@ -260,6 +266,7 @@ private:
buffer_vector<HybridGlyphGroup, 4> m_hybridGlyphGroups;
std::atomic_flag m_nothingToUpload;
+ std::mutex m_calcGlyphsMutex;
};
} // namespace dp
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp
index 18bd89160d..4973d64434 100644
--- a/drape_frontend/apply_feature_functors.cpp
+++ b/drape_frontend/apply_feature_functors.cpp
@@ -7,6 +7,7 @@
#include "drape_frontend/path_symbol_shape.hpp"
#include "drape_frontend/path_text_shape.hpp"
#include "drape_frontend/poi_symbol_shape.hpp"
+#include "drape_frontend/text_layout.hpp"
#include "drape_frontend/text_shape.hpp"
#include "drape_frontend/visual_params.hpp"
@@ -132,7 +133,7 @@ void Extract(::LineDefProto const * lineRule, df::LineViewParams & params)
{
double const scale = df::VisualParams::Instance().GetVisualScale();
params.m_color = ToDrapeColor(lineRule->color());
- params.m_width = max(lineRule->width() * scale, 1.0);
+ params.m_width = static_cast<float>(std::max(lineRule->width() * scale, 1.0));
if (lineRule->has_dashdot())
{
@@ -141,7 +142,7 @@ void Extract(::LineDefProto const * lineRule, df::LineViewParams & params)
int const count = dd.dd_size();
params.m_pattern.reserve(count);
for (int i = 0; i < count; ++i)
- params.m_pattern.push_back(dd.dd(i) * scale);
+ params.m_pattern.push_back(static_cast<uint8_t>(dd.dd(i) * scale));
}
switch(lineRule->cap())
@@ -173,7 +174,7 @@ void CaptionDefProtoToFontDecl(CaptionDefProto const * capRule, dp::FontDecl & p
{
double const vs = df::VisualParams::Instance().GetVisualScale();
params.m_color = ToDrapeColor(capRule->color());
- params.m_size = max(kMinVisibleFontSize, capRule->height() * vs);
+ params.m_size = static_cast<float>(std::max(kMinVisibleFontSize, capRule->height() * vs));
if (capRule->has_stroke_color())
params.m_outlineColor = ToDrapeColor(capRule->stroke_color());
@@ -185,7 +186,7 @@ void ShieldRuleProtoToFontDecl(ShieldRuleProto const * shieldRule, dp::FontDecl
{
double const vs = df::VisualParams::Instance().GetVisualScale();
params.m_color = ToDrapeColor(shieldRule->text_color());
- params.m_size = max(kMinVisibleFontSize, shieldRule->height() * vs);
+ params.m_size = static_cast<float>(std::max(kMinVisibleFontSize, shieldRule->height() * vs));
if (shieldRule->has_text_stroke_color())
params.m_outlineColor = ToDrapeColor(shieldRule->text_stroke_color());
@@ -328,10 +329,61 @@ float GetRoadShieldOutlineWidth(float baseWidth, ftypes::RoadShield const & shie
return baseWidth;
}
-} // namespace
-BaseApplyFeature::BaseApplyFeature(TileKey const & tileKey, TInsertShapeFn const & insertShape, FeatureID const & id,
- int minVisibleScale, uint8_t rank, CaptionDescription const & captions)
+dp::Anchor GetShieldAnchor(uint8_t shieldIndex, uint8_t shieldCount)
+{
+ switch (shieldCount)
+ {
+ case 2:
+ if (shieldIndex == 0) return dp::Bottom;
+ return dp::Top;
+ case 3:
+ if (shieldIndex == 0) return dp::RightBottom;
+ else if (shieldIndex == 1) return dp::LeftBottom;
+ return dp::Top;
+ case 4:
+ if (shieldIndex == 0) return dp::RightBottom;
+ else if (shieldIndex == 1) return dp::LeftBottom;
+ else if (shieldIndex == 2) return dp::RightTop;
+ return dp::LeftTop;
+ }
+ return dp::Center;
+}
+
+m2::PointF GetShieldOffset(dp::Anchor anchor)
+{
+ m2::PointF offset(0.0f, 0.0f);
+ if (anchor & dp::Left)
+ offset.x = 2.0f;
+ else if (anchor & dp::Right)
+ offset.x = -2.0f;
+
+ if (anchor & dp::Top)
+ offset.y = 2.0f;
+ else if (anchor & dp::Bottom)
+ offset.y = -2.0f;
+ return offset;
+}
+
+m2::PointF GetShieldTextOffset(dp::Anchor anchor, double bordrWidth, double borderHeight)
+{
+ m2::PointF offset(0.0f, 0.0f);
+ if (anchor & dp::Left)
+ offset.x = static_cast<float>(bordrWidth);
+ else if (anchor & dp::Right)
+ offset.x = -static_cast<float>(bordrWidth);
+
+ if (anchor & dp::Top)
+ offset.y = static_cast<float>(borderHeight);
+ else if (anchor & dp::Bottom)
+ offset.y = -static_cast<float>(borderHeight);
+ return offset;
+}
+} // namespace
+
+BaseApplyFeature::BaseApplyFeature(TileKey const & tileKey, TInsertShapeFn const & insertShape,
+ FeatureID const & id, int minVisibleScale, uint8_t rank,
+ CaptionDescription const & captions)
: m_insertShape(insertShape)
, m_id(id)
, m_captions(captions)
@@ -419,7 +471,7 @@ void ApplyPointFeature::operator()(m2::PointD const & point, bool hasArea)
m_centerPoint = point;
}
-void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
+void ApplyPointFeature::ProcessPointRule(Stylist::TRuleWrapper const & rule)
{
if (!m_hasPoint)
return;
@@ -469,7 +521,8 @@ void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
}
}
-void ApplyPointFeature::Finish(ref_ptr<dp::TextureManager> texMng, CustomSymbolsContextPtr const & customSymbolsContext)
+void ApplyPointFeature::Finish(ref_ptr<dp::TextureManager> texMng,
+ CustomSymbolsContextPtr const & customSymbolsContext)
{
m2::PointF symbolSize(0.0f, 0.0f);
@@ -688,7 +741,7 @@ void ApplyAreaFeature::CalculateBuildingOutline(bool calculateNormals, BuildingO
}
}
-void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
+void ApplyAreaFeature::ProcessAreaRule(Stylist::TRuleWrapper const & rule)
{
drule::BaseRule const * pRule = rule.first;
float const depth = static_cast<float>(rule.second);
@@ -724,7 +777,7 @@ void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
}
else
{
- TBase::ProcessRule(rule);
+ TBase::ProcessPointRule(rule);
}
}
@@ -781,7 +834,7 @@ bool ApplyLineFeatureGeometry::HasGeometry() const
return m_spline->IsValid();
}
-void ApplyLineFeatureGeometry::ProcessRule(Stylist::TRuleWrapper const & rule)
+void ApplyLineFeatureGeometry::ProcessLineRule(Stylist::TRuleWrapper const & rule)
{
ASSERT(HasGeometry(), ());
drule::BaseRule const * pRule = rule.first;
@@ -845,94 +898,87 @@ ApplyLineFeatureAdditional::ApplyLineFeatureAdditional(TileKey const & tileKey,
: TBase(tileKey, insertShape, id, minVisibleScale, rank, captions)
, m_clippedSplines(clippedSplines)
, m_currentScaleGtoP(static_cast<float>(currentScaleGtoP))
- , m_shieldDepth(0.0f)
+ , m_depth(0.0f)
+ , m_captionRule(nullptr)
, m_shieldRule(nullptr)
{}
-void ApplyLineFeatureAdditional::ProcessRule(Stylist::TRuleWrapper const & rule)
+void ApplyLineFeatureAdditional::ProcessLineRule(Stylist::TRuleWrapper const & rule)
{
if (m_clippedSplines.empty())
return;
drule::BaseRule const * pRule = rule.first;
- float const depth = static_cast<float>(rule.second);
+ m_depth = static_cast<float>(rule.second);
+
ShieldRuleProto const * pShieldRule = pRule->GetShield();
if (pShieldRule != nullptr)
- {
- m_shieldDepth = depth;
m_shieldRule = pShieldRule;
- }
bool const isWay = (pRule->GetType() & drule::way) != 0;
if (!isWay)
return;
CaptionDefProto const * pCaptionRule = pRule->GetCaption(0);
- if (pCaptionRule == nullptr || pCaptionRule->height() <= 2 || m_captions.GetPathName().empty())
- return;
-
- dp::FontDecl fontDecl;
- CaptionDefProtoToFontDecl(pCaptionRule, fontDecl);
- PathTextViewParams params;
- params.m_tileCenter = m_tileRect.Center();
- params.m_featureID = m_id;
- params.m_depth = depth;
- params.m_minVisibleScale = m_minVisibleScale;
- params.m_rank = m_rank;
- params.m_text = m_captions.GetPathName();
- params.m_textFont = fontDecl;
- params.m_baseGtoPScale = m_currentScaleGtoP;
-
- uint32_t baseTextIndex = kPathTextBaseTextIndex;
- for (auto const & spline : m_clippedSplines)
- {
- m_insertShape(make_unique_dp<PathTextShape>(spline, params, m_tileKey, baseTextIndex));
- baseTextIndex += kPathTextBaseTextStep;
- }
+ if (pCaptionRule != nullptr && pCaptionRule->height() > 2 && !m_captions.GetMainText().empty())
+ m_captionRule = pCaptionRule;
}
-void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ftypes::RoadShield const & shield,
+void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ref_ptr<dp::TextureManager> texMng,
+ ftypes::RoadShield const & shield,
+ uint8_t shieldIndex, uint8_t shieldCount,
TextViewParams & textParams,
ColoredSymbolViewParams & symbolParams,
- PoiSymbolViewParams & poiParams)
+ PoiSymbolViewParams & poiParams,
+ m2::PointD & shieldPixelSize)
{
ASSERT (m_shieldRule != nullptr, ());
string const & roadNumber = shield.m_name;
double const mainScale = df::VisualParams::Instance().GetVisualScale();
double const fontScale = df::VisualParams::Instance().GetFontScale();
+ auto const anchor = GetShieldAnchor(shieldIndex, shieldCount);
+ m2::PointF const shieldOffset = GetShieldOffset(anchor);
+ double const borderWidth = 5.0 * mainScale;
+ double const borderHeight = 1.5 * mainScale;
+ m2::PointF const shieldTextOffset = GetShieldTextOffset(anchor, borderWidth, borderHeight);
// Text properties.
dp::FontDecl baseFont;
ShieldRuleProtoToFontDecl(m_shieldRule, baseFont);
dp::FontDecl font = GetRoadShieldTextFont(baseFont, shield);
textParams.m_tileCenter = m_tileRect.Center();
- textParams.m_depth = m_shieldDepth;
+ textParams.m_depth = m_depth;
textParams.m_minVisibleScale = m_minVisibleScale;
textParams.m_rank = m_rank;
- textParams.m_anchor = dp::Center;
+ textParams.m_anchor = anchor;
textParams.m_featureID = m_id;
textParams.m_primaryText = roadNumber;
textParams.m_primaryTextFont = font;
- textParams.m_primaryOffset = m2::PointF(0, 0);
+ textParams.m_primaryOffset = shieldOffset + shieldTextOffset;
textParams.m_primaryOptional = false;
textParams.m_secondaryOptional = false;
textParams.m_extendingSize = 0;
+ TextLayout textLayout;
+ textLayout.Init(strings::MakeUniString(roadNumber), font.m_size, font.m_isSdf, texMng);
+
// Calculate width and height of a shield.
- double const shieldWidth = (font.m_size * 0.5 * roadNumber.size() + 10.0 * mainScale) * fontScale;
- double const shieldHeight = (font.m_size + 3.0 * mainScale) * fontScale;
+ shieldPixelSize.x = textLayout.GetPixelLength() + 2.0 * borderWidth;
+ shieldPixelSize.y = textLayout.GetPixelHeight() + 2.0 * borderHeight;
textParams.m_limitedText = true;
- textParams.m_limits = m2::PointD(shieldWidth, shieldHeight) * 0.9;
+ textParams.m_limits = shieldPixelSize * 0.9;
if (IsColoredRoadShield(shield))
{
// Generated symbol properties.
symbolParams.m_featureID = m_id;
symbolParams.m_tileCenter = m_tileRect.Center();
- symbolParams.m_depth = m_shieldDepth;
+ symbolParams.m_depth = m_depth;
symbolParams.m_minVisibleScale = m_minVisibleScale;
symbolParams.m_rank = m_rank;
+ symbolParams.m_anchor = anchor;
+ symbolParams.m_offset = shieldOffset;
symbolParams.m_shape = ColoredSymbolViewParams::Shape::RoundedRectangle;
symbolParams.m_radiusInPixels = static_cast<float>(2.5 * mainScale);
symbolParams.m_color = ToDrapeColor(m_shieldRule->color());
@@ -941,7 +987,7 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ftypes::RoadShield con
symbolParams.m_outlineColor = ToDrapeColor(m_shieldRule->stroke_color());
symbolParams.m_outlineWidth = static_cast<float>(1.0 * mainScale);
}
- symbolParams.m_sizeInPixels = m2::PointD(shieldWidth, shieldHeight);
+ symbolParams.m_sizeInPixels = shieldPixelSize;
symbolParams.m_outlineWidth = GetRoadShieldOutlineWidth(symbolParams.m_outlineWidth, shield);
symbolParams.m_color = GetRoadShieldColor(symbolParams.m_color, shield);
}
@@ -950,20 +996,8 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ftypes::RoadShield con
if (IsSymbolRoadShield(shield))
{
std::string symbolName = GetRoadShieldSymbolName(shield, fontScale);
- if (!symbolName.empty() && !shield.m_additionalText.empty())
- {
- textParams.m_anchor = dp::Top;
- textParams.m_secondaryText = shield.m_additionalText;
- textParams.m_secondaryTextFont = textParams.m_primaryTextFont;
- textParams.m_secondaryTextFont.m_color = df::GetColorConstant(kRoadShieldBlackTextColor);
- textParams.m_secondaryTextFont.m_outlineColor = df::GetColorConstant(kRoadShieldWhiteTextColor);
- textParams.m_primaryOffset = m2::PointF(0.0f, -0.5f * textParams.m_primaryTextFont.m_size);
- textParams.m_secondaryTextFont.m_size *= 0.9f;
- textParams.m_secondaryOffset = m2::PointD(0.0f, 3.0 * mainScale);
- }
-
poiParams.m_tileCenter = m_tileRect.Center();
- poiParams.m_depth = m_shieldDepth;
+ poiParams.m_depth = m_depth;
poiParams.m_minVisibleScale = m_minVisibleScale;
poiParams.m_rank = m_rank;
poiParams.m_symbolName = symbolName;
@@ -972,63 +1006,141 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ftypes::RoadShield con
poiParams.m_hasArea = false;
poiParams.m_prioritized = false;
poiParams.m_obsoleteInEditor = false;
+ poiParams.m_anchor = anchor;
+ poiParams.m_offset = shieldOffset;
+
+ dp::TextureManager::SymbolRegion region;
+ texMng->GetSymbolRegion(poiParams.m_symbolName, region);
+ float const symBorderWidth = (region.GetPixelSize().x - textLayout.GetPixelLength()) * 0.5f;
+ float const symBorderHeight = (region.GetPixelSize().y - textLayout.GetPixelHeight()) * 0.5f;
+ textParams.m_primaryOffset = shieldOffset + GetShieldTextOffset(anchor, symBorderWidth,
+ symBorderHeight);
+ shieldPixelSize = m2::PointD(symBorderWidth, symBorderHeight);
+
+ if (!symbolName.empty() && !shield.m_additionalText.empty() &&
+ (anchor & dp::Top || anchor & dp::Center))
+ {
+ textParams.m_secondaryText = shield.m_additionalText;
+ textParams.m_secondaryTextFont = textParams.m_primaryTextFont;
+ textParams.m_secondaryTextFont.m_color = df::GetColorConstant(kRoadShieldBlackTextColor);
+ textParams.m_secondaryTextFont.m_outlineColor = df::GetColorConstant(kRoadShieldWhiteTextColor);
+ textParams.m_secondaryTextFont.m_size *= 0.9f;
+ textParams.m_secondaryOffset = m2::PointD(0.0f, 3.0 * mainScale);
+ }
+ }
+}
+
+bool ApplyLineFeatureAdditional::CheckShieldsNearby(m2::PointD const & shieldPos,
+ m2::PointD const & shieldPixelSize,
+ std::vector<m2::RectD> & shields)
+{
+ // Here we calculate extended rect to skip the same shields nearby.
+ static double const kExtension = 5.0;
+ m2::PointD const shieldMercatorHalfSize = shieldPixelSize / m_currentScaleGtoP * 0.5;
+ m2::RectD shieldRect(shieldPos - shieldMercatorHalfSize, shieldPos + shieldMercatorHalfSize);
+ shieldRect.Scale(kExtension);
+ for (auto const & r : shields)
+ {
+ if (r.IsIntersect(shieldRect))
+ return false;
}
+ shields.push_back(shieldRect);
+ return true;
}
-void ApplyLineFeatureAdditional::Finish(std::set<ftypes::RoadShield> && roadShields)
+void ApplyLineFeatureAdditional::Finish(ref_ptr<dp::TextureManager> texMng,
+ std::set<ftypes::RoadShield> && roadShields,
+ GeneratedRoadShields & generatedRoadShields)
{
- if (m_shieldRule == nullptr || m_clippedSplines.empty())
+ if (m_clippedSplines.empty())
return;
- int32_t constexpr kDefaultMinDistance = 50;
- double const mainScale = df::VisualParams::Instance().GetVisualScale();
+ std::vector<m2::PointD> shieldPositions;
+ if (m_shieldRule != nullptr && !roadShields.empty())
+ shieldPositions.reserve(m_clippedSplines.size() * 3);
- m2::PointD shieldOffset(0.0, 0.0);
- uint32_t shieldIndex = 0;
- for (ftypes::RoadShield const & shield : roadShields)
+ if (m_captionRule != nullptr)
{
- TextViewParams textParams;
- ColoredSymbolViewParams symbolParams;
- PoiSymbolViewParams poiParams(m_id);
- GetRoadShieldsViewParams(shield, textParams, symbolParams, poiParams);
-
- uint32_t minDistanceInPixels = static_cast<uint32_t>(mainScale * (m_shieldRule->has_min_distance() ?
- m_shieldRule->min_distance() : kDefaultMinDistance));
- if (minDistanceInPixels == 0)
- minDistanceInPixels = static_cast<uint32_t>(mainScale * kDefaultMinDistance);
+ dp::FontDecl fontDecl;
+ CaptionDefProtoToFontDecl(m_captionRule, fontDecl);
+ PathTextViewParams params;
+ params.m_tileCenter = m_tileRect.Center();
+ params.m_featureID = m_id;
+ params.m_depth = m_depth;
+ params.m_minVisibleScale = m_minVisibleScale;
+ params.m_rank = m_rank;
+ params.m_mainText = m_captions.GetMainText();
+ params.m_auxText = m_captions.GetAuxText();
+ params.m_textFont = fontDecl;
+ params.m_baseGtoPScale = m_currentScaleGtoP;
- uint32_t textIndex = kShieldBaseTextIndex * (++shieldIndex);
+ uint32_t baseTextIndex = kPathTextBaseTextIndex;
for (auto const & spline : m_clippedSplines)
{
- double const pathPixelLength = spline->GetLength() * m_currentScaleGtoP;
- uint32_t const shieldsCount = static_cast<uint32_t>(pathPixelLength / minDistanceInPixels);
- if (shieldsCount == 0)
+ auto shape = make_unique_dp<PathTextShape>(spline, params, m_tileKey, baseTextIndex);
+
+ if (!shape->CalculateLayout(texMng))
continue;
- double const splineStep = spline->GetLength() / (shieldsCount + 1);
- m2::Spline::iterator it = spline.CreateIterator();
- it.Advance(splineStep);
- for (uint32_t i = 0; i < shieldsCount && !it.BeginAgain(); i++)
+ if (m_shieldRule != nullptr && !roadShields.empty())
{
- m_insertShape(make_unique_dp<TextShape>(shieldOffset + it.m_pos, textParams, m_tileKey,
- true /* hasPOI */, m2::PointF(0.0f, 0.0f) /* symbolSize */, textIndex,
- false /* affectedByZoomPriority */));
- if (IsColoredRoadShield(shield))
+ auto const & offsets = shape->GetOffsets();
+ ASSERT(!offsets.empty(), ());
+ if (offsets.size() == 1)
{
- m_insertShape(make_unique_dp<ColoredSymbolShape>(shieldOffset + it.m_pos,
- symbolParams, m_tileKey, textIndex));
+ shieldPositions.push_back(spline->GetPoint(0.5 * spline->GetLength()).m_pos);
}
- else if (IsSymbolRoadShield(shield))
+ else
{
- m_insertShape(make_unique_dp<PoiSymbolShape>(shieldOffset + it.m_pos,
- poiParams, m_tileKey, textIndex));
+ for (size_t i = 0; i + 1 < offsets.size(); i++)
+ {
+ double const p = 0.5 * (offsets[i] + offsets[i + 1]);
+ shieldPositions.push_back(spline->GetPoint(p).m_pos);
+ }
}
- it.Advance(splineStep);
- textIndex++;
}
+
+ m_insertShape(std::move(shape));
+ baseTextIndex += kPathTextBaseTextStep;
}
+ }
+
+ if (shieldPositions.empty())
+ return;
+
+ uint8_t shieldIndex = 0;
+ for (ftypes::RoadShield const & shield : roadShields)
+ {
+ TextViewParams textParams;
+ ColoredSymbolViewParams symbolParams;
+ PoiSymbolViewParams poiParams(m_id);
+ m2::PointD shieldPixelSize;
+ GetRoadShieldsViewParams(texMng, shield, shieldIndex, static_cast<uint8_t>(roadShields.size()),
+ textParams, symbolParams, poiParams, shieldPixelSize);
+
+ auto & generatedShieldRects = generatedRoadShields[shield];
+ generatedShieldRects.reserve(10);
+ uint32_t textIndex = kShieldBaseTextIndex * (++shieldIndex);
+ for (auto const & shieldPos : shieldPositions)
+ {
+ if (!CheckShieldsNearby(shieldPos, shieldPixelSize, generatedShieldRects))
+ continue;
- shieldOffset += m2::PointD(symbolParams.m_sizeInPixels.x / m_currentScaleGtoP, 0.0);
+ m_insertShape(make_unique_dp<TextShape>(shieldPos, textParams, m_tileKey, true /* hasPOI */,
+ m2::PointF(0.0f, 0.0f) /* symbolSize */, textIndex,
+ false /* affectedByZoomPriority */));
+ if (IsColoredRoadShield(shield))
+ {
+ m_insertShape(make_unique_dp<ColoredSymbolShape>(shieldPos, symbolParams,
+ m_tileKey, textIndex));
+ }
+ else if (IsSymbolRoadShield(shield))
+ {
+ m_insertShape(make_unique_dp<PoiSymbolShape>(shieldPos, poiParams,
+ m_tileKey, textIndex));
+ }
+ textIndex++;
+ }
}
}
} // namespace df
diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp
index afc81863bc..de80970114 100644
--- a/drape_frontend/apply_feature_functors.hpp
+++ b/drape_frontend/apply_feature_functors.hpp
@@ -8,6 +8,7 @@
#include "drape/pointers.hpp"
#include "indexer/ftypes_matcher.hpp"
+#include "indexer/road_shields_parser.hpp"
#include "coding/point_to_integer.hpp"
@@ -15,7 +16,7 @@
#include "geometry/polyline2d.hpp"
#include "geometry/spline.hpp"
-#include "std/unordered_map.hpp"
+#include <vector>
class CaptionDefProto;
class ShieldRuleProto;
@@ -23,11 +24,6 @@ class SymbolRuleProto;
//#define CALC_FILTERED_POINTS
-namespace ftypes
-{
-struct RoadShield;
-}
-
namespace dp
{
class TextureManager;
@@ -45,8 +41,9 @@ using TInsertShapeFn = function<void(drape_ptr<MapShape> && shape)>;
class BaseApplyFeature
{
public:
- BaseApplyFeature(TileKey const & tileKey, TInsertShapeFn const & insertShape, FeatureID const & id,
- int minVisibleScale, uint8_t rank, CaptionDescription const & captions);
+ BaseApplyFeature(TileKey const & tileKey, TInsertShapeFn const & insertShape,
+ FeatureID const & id, int minVisibleScale, uint8_t rank,
+ CaptionDescription const & captions);
virtual ~BaseApplyFeature() {}
@@ -88,8 +85,9 @@ public:
int displacementMode);
void operator()(m2::PointD const & point, bool hasArea);
- void ProcessRule(Stylist::TRuleWrapper const & rule);
- void Finish(ref_ptr<dp::TextureManager> texMng, CustomSymbolsContextPtr const & customSymbolsContext);
+ void ProcessPointRule(Stylist::TRuleWrapper const & rule);
+ void Finish(ref_ptr<dp::TextureManager> texMng,
+ CustomSymbolsContextPtr const & customSymbolsContext);
protected:
float const m_posZ;
@@ -119,7 +117,7 @@ public:
using TBase::operator ();
void operator()(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3);
- void ProcessRule(Stylist::TRuleWrapper const & rule);
+ void ProcessAreaRule(Stylist::TRuleWrapper const & rule);
private:
using TEdge = pair<int, int>;
@@ -132,7 +130,7 @@ private:
bool FindEdge(TEdge const & edge);
m2::PointD CalculateNormal(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) const;
- vector<m2::PointD> m_triangles;
+ std::vector<m2::PointD> m_triangles;
buffer_vector<m2::PointD, kBuildingOutlineSize> m_points;
buffer_vector<pair<TEdge, int>, kBuildingOutlineSize> m_edges;
@@ -155,14 +153,14 @@ public:
void operator() (m2::PointD const & point);
bool HasGeometry() const;
- void ProcessRule(Stylist::TRuleWrapper const & rule);
+ void ProcessLineRule(Stylist::TRuleWrapper const & rule);
void Finish();
std::vector<m2::SharedSpline> const & GetClippedSplines() const { return m_clippedSplines; }
private:
m2::SharedSpline m_spline;
- vector<m2::SharedSpline> m_clippedSplines;
+ std::vector<m2::SharedSpline> m_clippedSplines;
float m_currentScaleGtoP;
double m_sqrScale;
m2::PointD m_lastAddedPoint;
@@ -184,21 +182,28 @@ public:
uint8_t rank, CaptionDescription const & captions,
std::vector<m2::SharedSpline> const & clippedSplines);
- void ProcessRule(Stylist::TRuleWrapper const & rule);
- void Finish(std::set<ftypes::RoadShield> && roadShields);
+ void ProcessLineRule(Stylist::TRuleWrapper const & rule);
+ void Finish(ref_ptr<dp::TextureManager> texMng, std::set<ftypes::RoadShield> && roadShields,
+ GeneratedRoadShields & generatedRoadShields);
private:
- void GetRoadShieldsViewParams(ftypes::RoadShield const & shield,
+ void GetRoadShieldsViewParams(ref_ptr<dp::TextureManager> texMng,
+ ftypes::RoadShield const & shield,
+ uint8_t shieldIndex, uint8_t shieldCount,
TextViewParams & textParams,
ColoredSymbolViewParams & symbolParams,
- PoiSymbolViewParams & poiParams);
+ PoiSymbolViewParams & poiParams,
+ m2::PointD & shieldPixelSize);
+ bool CheckShieldsNearby(m2::PointD const & shieldPos,
+ m2::PointD const & shieldPixelSize,
+ std::vector<m2::RectD> & shields);
std::vector<m2::SharedSpline> m_clippedSplines;
float m_currentScaleGtoP;
- float m_shieldDepth;
+ float m_depth;
+ CaptionDefProto const * m_captionRule;
ShieldRuleProto const * m_shieldRule;
};
extern dp::Color ToDrapeColor(uint32_t src);
-
} // namespace df
diff --git a/drape_frontend/colored_symbol_shape.cpp b/drape_frontend/colored_symbol_shape.cpp
index 05ca606c67..c336711acd 100644
--- a/drape_frontend/colored_symbol_shape.cpp
+++ b/drape_frontend/colored_symbol_shape.cpp
@@ -13,6 +13,30 @@
namespace df
{
+namespace
+{
+glsl::vec2 ShiftNormal(glsl::vec2 const & n, ColoredSymbolViewParams const & params)
+{
+ glsl::vec2 result = n + glsl::vec2(params.m_offset.x, params.m_offset.y);
+ m2::PointF halfPixelSize;
+ if (params.m_shape == ColoredSymbolViewParams::Shape::Circle)
+ halfPixelSize = m2::PointF(params.m_radiusInPixels, params.m_radiusInPixels);
+ else
+ halfPixelSize = m2::PointF(0.5f * params.m_sizeInPixels.x, 0.5f * params.m_sizeInPixels.y);
+
+ if (params.m_anchor & dp::Top)
+ result.y += halfPixelSize.y;
+ else if (params.m_anchor & dp::Bottom)
+ result.y -= halfPixelSize.y;
+
+ if (params.m_anchor & dp::Left)
+ result.x += halfPixelSize.x;
+ else if (params.m_anchor & dp::Right)
+ result.x -= halfPixelSize.x;
+
+ return result;
+}
+} // namespace
ColoredSymbolShape::ColoredSymbolShape(m2::PointD const & mercatorPt, ColoredSymbolViewParams const & params,
TileKey const & tileKey, uint32_t textIndex, bool needOverlay,
@@ -26,7 +50,8 @@ ColoredSymbolShape::ColoredSymbolShape(m2::PointD const & mercatorPt, ColoredSym
, m_specialModePriority(specialModePriority)
{}
-void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const
+void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher,
+ ref_ptr<dp::TextureManager> textures) const
{
dp::TextureManager::ColorRegion colorRegion;
textures->GetColorRegion(m_params.m_color, colorRegion);
@@ -40,30 +65,38 @@ void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureM
V::TTexCoord const uv(colorUv.x, colorUv.y, 0.0f, 0.0f);
V::TTexCoord const uvOutline(outlineUv.x, outlineUv.y, 0.0f, 0.0f);
- glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_point, m_params.m_tileCenter, kShapeCoordScalar));
+ glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_point, m_params.m_tileCenter,
+ kShapeCoordScalar));
glsl::vec3 const position = glsl::vec3(pt, m_params.m_depth);
buffer_vector<V, 48> buffer;
+ auto norm = [this](float x, float y)
+ {
+ return ShiftNormal(glsl::vec2(x, y), m_params);
+ };
+
m2::PointU pixelSize;
if (m_params.m_shape == ColoredSymbolViewParams::Shape::Circle)
{
pixelSize = m2::PointU(2 * static_cast<uint32_t>(m_params.m_radiusInPixels),
2 * static_cast<uint32_t>(m_params.m_radiusInPixels));
// Here we use an equilateral triangle to render circle (incircle of a triangle).
- static float const kSqrt3 = sqrt(3.0f);
+ static float const kSqrt3 = static_cast<float>(sqrt(3.0f));
float r = m_params.m_radiusInPixels - m_params.m_outlineWidth;
- buffer.push_back(V(position, V::TNormal(-r * kSqrt3, -r, r, 1.0f), uv));
- buffer.push_back(V(position, V::TNormal(r * kSqrt3, -r, r, 1.0f), uv));
- buffer.push_back(V(position, V::TNormal(0.0f, 2.0f * r, r, 1.0f), uv));
+ V::TTexCoord uv2(uv.x, uv.y, norm(0.0, 0.0));
+ buffer.push_back(V(position, V::TNormal(-r * kSqrt3, -r, r, 1.0f), uv2));
+ buffer.push_back(V(position, V::TNormal(r * kSqrt3, -r, r, 1.0f), uv2));
+ buffer.push_back(V(position, V::TNormal(0.0f, 2.0f * r, r, 1.0f), uv2));
if (m_params.m_outlineWidth >= 1e-5)
{
r = m_params.m_radiusInPixels;
- buffer.push_back(V(position, V::TNormal(-r * kSqrt3, -r, r, 1.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(r * kSqrt3, -r, r, 1.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(0.0f, 2.0f * r, r, 1.0f), uvOutline));
+ V::TTexCoord uvOutline2(uvOutline.x, uvOutline.y, norm(0.0, 0.0));
+ buffer.push_back(V(position, V::TNormal(-r * kSqrt3, -r, r, 1.0f), uvOutline2));
+ buffer.push_back(V(position, V::TNormal(r * kSqrt3, -r, r, 1.0f), uvOutline2));
+ buffer.push_back(V(position, V::TNormal(0.0f, 2.0f * r, r, 1.0f), uvOutline2));
}
}
else if (m_params.m_shape == ColoredSymbolViewParams::Shape::Rectangle)
@@ -76,21 +109,21 @@ void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureM
float const halfWidthInside = halfWidth - m_params.m_outlineWidth;
float const halfHeightInside = halfHeight - m_params.m_outlineWidth;
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, -halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, -halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, -halfHeightInside, v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, -halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, -halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, -halfHeightInside), v, 0.0f), uv));
if (m_params.m_outlineWidth >= 1e-5)
{
- buffer.push_back(V(position, V::TNormal(-halfWidth, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, -halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidth, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidth, -halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, -halfHeight, v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, -halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, -halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, -halfHeight), v, 0.0f), uvOutline));
}
}
else if (m_params.m_shape == ColoredSymbolViewParams::Shape::RoundedRectangle)
@@ -107,43 +140,43 @@ void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureM
if (halfWidthBody > 0.0f && halfHeightInside > 0.0f)
{
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, -halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, -halfHeightInside, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, -halfHeightInside, v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, -halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, -halfHeightInside), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, -halfHeightInside), v, 0.0f), uv));
}
- if (halfHeightBody > 0.0f && halfHeightBody > 0.0f)
+ if (halfWidthInside > 0.0f && halfHeightBody > 0.0f)
{
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, halfHeightBody, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, -halfHeightBody, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, halfHeightBody, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, halfHeightBody, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(-halfWidthInside, -halfHeightBody, v, 0.0f), uv));
- buffer.push_back(V(position, V::TNormal(halfWidthInside, -halfHeightBody, v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, halfHeightBody), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, -halfHeightBody), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, halfHeightBody), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, halfHeightBody), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthInside, -halfHeightBody), v, 0.0f), uv));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthInside, -halfHeightBody), v, 0.0f), uv));
}
// Here we use an right triangle to render a quarter of circle.
- static float const kSqrt2 = sqrt(2.0f);
+ static float const kSqrt2 = static_cast<float>(sqrt(2.0f));
float r = m_params.m_radiusInPixels - m_params.m_outlineWidth;
- V::TTexCoord uv2(uv.x, uv.y, -halfWidthBody, halfHeightBody);
+ V::TTexCoord uv2(uv.x, uv.y, norm(-halfWidthBody, halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, r * kSqrt2, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(-r * kSqrt2, 0.0, r, 0.0f), uv2));
- uv2 = V::TTexCoord(uv.x, uv.y, halfWidthBody, halfHeightBody);
+ uv2 = V::TTexCoord(uv.x, uv.y, norm(halfWidthBody, halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(r * kSqrt2, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, r * kSqrt2, r, 0.0f), uv2));
- uv2 = V::TTexCoord(uv.x, uv.y, halfWidthBody, -halfHeightBody);
+ uv2 = V::TTexCoord(uv.x, uv.y, norm(halfWidthBody, -halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, -r * kSqrt2, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(r * kSqrt2, 0.0, r, 0.0f), uv2));
- uv2 = V::TTexCoord(uv.x, uv.y, -halfWidthBody, -halfHeightBody);
+ uv2 = V::TTexCoord(uv.x, uv.y, norm(-halfWidthBody, -halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(-r * kSqrt2, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, -r * kSqrt2, r, 0.0f), uv2));
@@ -152,41 +185,41 @@ void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureM
{
if (halfWidthBody > 0.0f && halfHeight > 0.0f)
{
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, -halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidthBody, -halfHeight, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidthBody, -halfHeight, v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, -halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidthBody, -halfHeight), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidthBody, -halfHeight), v, 0.0f), uvOutline));
}
if (halfWidth > 0.0f && halfHeightBody > 0.0f)
{
- buffer.push_back(V(position, V::TNormal(-halfWidth, halfHeightBody, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, -halfHeightBody, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, halfHeightBody, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidth, halfHeightBody, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(-halfWidth, -halfHeightBody, v, 0.0f), uvOutline));
- buffer.push_back(V(position, V::TNormal(halfWidth, -halfHeightBody, v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, halfHeightBody), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, -halfHeightBody), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, halfHeightBody), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, halfHeightBody), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(-halfWidth, -halfHeightBody), v, 0.0f), uvOutline));
+ buffer.push_back(V(position, V::TNormal(norm(halfWidth, -halfHeightBody), v, 0.0f), uvOutline));
}
r = m_params.m_radiusInPixels;
- V::TTexCoord const uvOutline2(outlineUv.x, outlineUv.y, -halfWidthBody, halfHeightBody);
+ V::TTexCoord const uvOutline2(outlineUv.x, outlineUv.y, norm(-halfWidthBody, halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uvOutline2));
buffer.push_back(V(position, V::TNormal(0.0, r * kSqrt2, r, 0.0f), uvOutline2));
buffer.push_back(V(position, V::TNormal(-r * kSqrt2, 0.0, r, 0.0f), uvOutline2));
- uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, halfWidthBody, halfHeightBody);
+ uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, norm(halfWidthBody, halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(r * kSqrt2, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, r * kSqrt2, r, 0.0f), uv2));
- uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, halfWidthBody, -halfHeightBody);
+ uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, norm(halfWidthBody, -halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, -r * kSqrt2, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(r * kSqrt2, 0.0, r, 0.0f), uv2));
- uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, -halfWidthBody, -halfHeightBody);
+ uv2 = V::TTexCoord(outlineUv.x, outlineUv.y, norm(-halfWidthBody, -halfHeightBody));
buffer.push_back(V(position, V::TNormal(0.0, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(-r * kSqrt2, 0.0, r, 0.0f), uv2));
buffer.push_back(V(position, V::TNormal(0.0, -r * kSqrt2, r, 0.0f), uv2));
@@ -201,8 +234,9 @@ void ColoredSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureM
strings::to_string(m_textIndex);
drape_ptr<dp::OverlayHandle> handle = m_needOverlay ?
- make_unique_dp<dp::SquareHandle>(overlayId, dp::Center, m_point, pixelSize, GetOverlayPriority(),
- true /* isBound */, debugName, true /* isBillboard */) : nullptr;
+ make_unique_dp<dp::SquareHandle>(overlayId, m_params.m_anchor, m_point, pixelSize,
+ m_params.m_offset, GetOverlayPriority(), true /* isBound */,
+ debugName, true /* isBillboard */) : nullptr;
dp::GLState state(gpu::COLORED_SYMBOL_PROGRAM, dp::GLState::OverlayLayer);
state.SetProgram3dIndex(gpu::COLORED_SYMBOL_BILLBOARD_PROGRAM);
@@ -222,4 +256,4 @@ uint64_t ColoredSymbolShape::GetOverlayPriority() const
return dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, m_params.m_depth);
}
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/colored_symbol_shape.hpp b/drape_frontend/colored_symbol_shape.hpp
index ca18049f51..f6e76718f9 100644
--- a/drape_frontend/colored_symbol_shape.hpp
+++ b/drape_frontend/colored_symbol_shape.hpp
@@ -7,7 +7,6 @@
namespace df
{
-
class ColoredSymbolShape : public MapShape
{
public:
@@ -28,5 +27,4 @@ private:
bool const m_specialDisplacementMode;
uint16_t const m_specialModePriority;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/path_text_shape.cpp b/drape_frontend/path_text_shape.cpp
index 36cdcc21da..6e12d27470 100644
--- a/drape_frontend/path_text_shape.cpp
+++ b/drape_frontend/path_text_shape.cpp
@@ -2,7 +2,6 @@
#include "drape_frontend/intrusive_vector.hpp"
#include "drape_frontend/shader_def.hpp"
#include "drape_frontend/text_handle.hpp"
-#include "drape_frontend/text_layout.hpp"
#include "drape/attribute_provider.hpp"
#include "drape/batcher.hpp"
@@ -18,14 +17,10 @@
#include "geometry/transformations.hpp"
-#include "std/algorithm.hpp"
-#include "std/vector.hpp"
-
using m2::Spline;
namespace
{
-
class PathTextHandle : public df::TextHandle
{
public:
@@ -55,8 +50,8 @@ public:
{
if (!df::TextHandle::Update(screen))
return false;
-
- vector<m2::PointD> const & globalPoints = m_spline->GetPath();
+
+ auto const & globalPoints = m_spline->GetPath();
m2::Spline pixelSpline(m_spline->GetSize());
m2::Spline::iterator centerPointIter;
@@ -197,9 +192,11 @@ private:
return false;
float offset = 0.0f;
- if (!df::PathTextLayout::CalculatePerspectivePosition(pixelSpline.GetLength(),
+ if (!df::PathTextLayout::CalculatePerspectivePosition(static_cast<float>(pixelSpline.GetLength()),
m_layout->GetPixelLength(), offset))
+ {
return false;
+ }
pixelOffset = offset;
return true;
@@ -214,13 +211,12 @@ private:
float const m_depth;
uint64_t const m_priorityFollowingMode;
};
-
-}
+} // namespace
namespace df
{
-
-PathTextShape::PathTextShape(m2::SharedSpline const & spline, PathTextViewParams const & params,
+PathTextShape::PathTextShape(m2::SharedSpline const & spline,
+ PathTextViewParams const & params,
TileKey const & tileKey, uint32_t baseTextIndex)
: m_spline(spline)
, m_params(params)
@@ -228,7 +224,29 @@ PathTextShape::PathTextShape(m2::SharedSpline const & spline, PathTextViewParams
, m_baseTextIndex(baseTextIndex)
{}
-uint64_t PathTextShape::GetOverlayPriority(uint32_t textIndex, bool followingMode) const
+bool PathTextShape::CalculateLayout(ref_ptr<dp::TextureManager> textures)
+{
+ std::string text = m_params.m_mainText;
+ if (!m_params.m_auxText.empty())
+ text += " " + m_params.m_auxText;
+
+ m_layout = SharedTextLayout(new PathTextLayout(m_params.m_tileCenter,
+ strings::MakeUniString(text),
+ m_params.m_textFont.m_size,
+ m_params.m_textFont.m_isSdf,
+ textures));
+ uint32_t const glyphCount = m_layout->GetGlyphCount();
+ if (glyphCount == 0)
+ return false;
+
+ PathTextLayout::CalculatePositions(static_cast<float>(m_spline->GetLength()),
+ m_params.m_baseGtoPScale, m_layout->GetPixelLength(),
+ m_offsets);
+ return !m_offsets.empty();
+}
+
+uint64_t PathTextShape::GetOverlayPriority(uint32_t textIndex, size_t textLength,
+ bool followingMode) const
{
// Overlay priority for path text shapes considers length of the text and index of text.
// Greater text length has more priority, because smaller texts have more chances to be shown along the road.
@@ -238,58 +256,56 @@ uint64_t PathTextShape::GetOverlayPriority(uint32_t textIndex, bool followingMod
if (!followingMode)
priority = dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, m_params.m_depth);
priority &= kMask;
- priority |= (static_cast<uint8_t>(m_params.m_text.size()) << 8);
+ priority |= (static_cast<uint8_t>(textLength) << 8);
priority |= static_cast<uint8_t>(textIndex);
return priority;
}
void PathTextShape::DrawPathTextPlain(ref_ptr<dp::TextureManager> textures,
- ref_ptr<dp::Batcher> batcher,
- unique_ptr<PathTextLayout> && layout,
- vector<float> const & offsets) const
+ ref_ptr<dp::Batcher> batcher) const
{
+ ASSERT(!m_layout.IsNull(), ());
+ ASSERT(!m_offsets.empty(), ());
+
dp::TextureManager::ColorRegion color;
textures->GetColorRegion(m_params.m_textFont.m_color, color);
- dp::GLState state(layout->GetFixedHeight() > 0 ? gpu::TEXT_FIXED_PROGRAM : gpu::TEXT_PROGRAM, dp::GLState::OverlayLayer);
- state.SetProgram3dIndex(layout->GetFixedHeight() > 0 ? gpu::TEXT_FIXED_BILLBOARD_PROGRAM : gpu::TEXT_BILLBOARD_PROGRAM);
+ dp::GLState state(m_layout->GetFixedHeight() > 0 ? gpu::TEXT_FIXED_PROGRAM : gpu::TEXT_PROGRAM,
+ dp::GLState::OverlayLayer);
+ state.SetProgram3dIndex(m_layout->GetFixedHeight() > 0 ? gpu::TEXT_FIXED_BILLBOARD_PROGRAM :
+ gpu::TEXT_BILLBOARD_PROGRAM);
state.SetColorTexture(color.GetTexture());
- state.SetMaskTexture(layout->GetMaskTexture());
+ state.SetMaskTexture(m_layout->GetMaskTexture());
- ASSERT(!offsets.empty(), ());
gpu::TTextStaticVertexBuffer staticBuffer;
gpu::TTextDynamicVertexBuffer dynBuffer;
- SharedTextLayout layoutPtr(layout.release());
- for (uint32_t textIndex = 0; textIndex < static_cast<uint32_t>(offsets.size()); ++textIndex)
+
+ for (uint32_t textIndex = 0; textIndex < static_cast<uint32_t>(m_offsets.size()); ++textIndex)
{
- float offset = offsets[textIndex];
+ float const offset = m_offsets[textIndex];
staticBuffer.clear();
dynBuffer.clear();
- layoutPtr->CacheStaticGeometry(color, staticBuffer);
+ m_layout->CacheStaticGeometry(color, staticBuffer);
dynBuffer.resize(staticBuffer.size());
dp::AttributeProvider provider(2, static_cast<uint32_t>(staticBuffer.size()));
- provider.InitStream(0, gpu::TextStaticVertex::GetBindingInfo(), make_ref(staticBuffer.data()));
- provider.InitStream(1, gpu::TextDynamicVertex::GetBindingInfo(), make_ref(dynBuffer.data()));
-
- dp::OverlayID const overlayId = dp::OverlayID(m_params.m_featureID, m_tileCoords, m_baseTextIndex + textIndex);
- drape_ptr<dp::OverlayHandle> handle = make_unique_dp<PathTextHandle>(overlayId, m_spline,
- layoutPtr, offset, m_params.m_depth, textIndex,
- GetOverlayPriority(textIndex, false /* followingMode */),
- GetOverlayPriority(textIndex, true /* followingMode */),
- layoutPtr->GetFixedHeight(),
- textures, true);
- batcher->InsertListOfStrip(state, make_ref(&provider), move(handle), 4);
+ provider.InitStream(0, gpu::TextStaticVertex::GetBindingInfo(),
+ make_ref(staticBuffer.data()));
+ provider.InitStream(1, gpu::TextDynamicVertex::GetBindingInfo(),
+ make_ref(dynBuffer.data()));
+ batcher->InsertListOfStrip(state, make_ref(&provider),
+ CreateOverlayHandle(m_layout, textIndex, offset, textures), 4);
}
}
void PathTextShape::DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures,
- ref_ptr<dp::Batcher> batcher,
- unique_ptr<PathTextLayout> && layout,
- vector<float> const & offsets) const
+ ref_ptr<dp::Batcher> batcher) const
{
+ ASSERT(!m_layout.IsNull(), ());
+ ASSERT(!m_offsets.empty(), ());
+
dp::TextureManager::ColorRegion color;
dp::TextureManager::ColorRegion outline;
textures->GetColorRegion(m_params.m_textFont.m_color, color);
@@ -298,55 +314,52 @@ void PathTextShape::DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures,
dp::GLState state(gpu::TEXT_OUTLINED_PROGRAM, dp::GLState::OverlayLayer);
state.SetProgram3dIndex(gpu::TEXT_OUTLINED_BILLBOARD_PROGRAM);
state.SetColorTexture(color.GetTexture());
- state.SetMaskTexture(layout->GetMaskTexture());
+ state.SetMaskTexture(m_layout->GetMaskTexture());
- ASSERT(!offsets.empty(), ());
gpu::TTextOutlinedStaticVertexBuffer staticBuffer;
gpu::TTextDynamicVertexBuffer dynBuffer;
- SharedTextLayout layoutPtr(layout.release());
- for (uint32_t textIndex = 0; textIndex < static_cast<uint32_t>(offsets.size()); ++textIndex)
+ for (uint32_t textIndex = 0; textIndex < static_cast<uint32_t>(m_offsets.size()); ++textIndex)
{
- float offset = offsets[textIndex];
+ float const offset = m_offsets[textIndex];
staticBuffer.clear();
dynBuffer.clear();
- layoutPtr->CacheStaticGeometry(color, outline, staticBuffer);
+ m_layout->CacheStaticGeometry(color, outline, staticBuffer);
dynBuffer.resize(staticBuffer.size());
dp::AttributeProvider provider(2, static_cast<uint32_t>(staticBuffer.size()));
- provider.InitStream(0, gpu::TextOutlinedStaticVertex::GetBindingInfo(), make_ref(staticBuffer.data()));
- provider.InitStream(1, gpu::TextDynamicVertex::GetBindingInfo(), make_ref(dynBuffer.data()));
-
- dp::OverlayID const overlayId = dp::OverlayID(m_params.m_featureID, m_tileCoords, m_baseTextIndex + textIndex);
- drape_ptr<dp::OverlayHandle> handle = make_unique_dp<PathTextHandle>(overlayId, m_spline, layoutPtr, offset,
- m_params.m_depth, textIndex,
- GetOverlayPriority(textIndex, false /* followingMode */),
- GetOverlayPriority(textIndex, true /* followingMode */),
- layoutPtr->GetFixedHeight(),
- textures, true);
- batcher->InsertListOfStrip(state, make_ref(&provider), move(handle), 4);
+ provider.InitStream(0, gpu::TextOutlinedStaticVertex::GetBindingInfo(),
+ make_ref(staticBuffer.data()));
+ provider.InitStream(1, gpu::TextDynamicVertex::GetBindingInfo(),
+ make_ref(dynBuffer.data()));
+ batcher->InsertListOfStrip(state, make_ref(&provider),
+ CreateOverlayHandle(m_layout, textIndex, offset, textures), 4);
}
}
-void PathTextShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const
+drape_ptr<dp::OverlayHandle> PathTextShape::CreateOverlayHandle(SharedTextLayout const & layoutPtr,
+ uint32_t textIndex, float offset,
+ ref_ptr<dp::TextureManager> textures) const
{
- auto layout = make_unique<PathTextLayout>(m_params.m_tileCenter, strings::MakeUniString(m_params.m_text),
- m_params.m_textFont.m_size, m_params.m_textFont.m_isSdf, textures);
-
- uint32_t glyphCount = layout->GetGlyphCount();
- if (glyphCount == 0)
- return;
+ dp::OverlayID const overlayId = dp::OverlayID(m_params.m_featureID, m_tileCoords,
+ m_baseTextIndex + textIndex);
+ auto const priority = GetOverlayPriority(textIndex, layoutPtr->GetText().size(),
+ false /* followingMode */);
+ auto const followPriority = GetOverlayPriority(textIndex, layoutPtr->GetText().size(),
+ true /* followingMode */);
+ return make_unique_dp<PathTextHandle>(overlayId, m_spline, layoutPtr, offset, m_params.m_depth,
+ textIndex, priority, followPriority, layoutPtr->GetFixedHeight(),
+ textures, true /* isBillboard */);
+}
- vector<float> offsets;
- PathTextLayout::CalculatePositions(offsets, m_spline->GetLength(), m_params.m_baseGtoPScale,
- layout->GetPixelLength());
- if (offsets.empty())
+void PathTextShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const
+{
+ if (m_layout.IsNull() || m_offsets.empty())
return;
if (m_params.m_textFont.m_outlineColor == dp::Color::Transparent())
- DrawPathTextPlain(textures, batcher, move(layout), offsets);
+ DrawPathTextPlain(textures, batcher);
else
- DrawPathTextOutlined(textures, batcher, move(layout), offsets);
-}
-
+ DrawPathTextOutlined(textures, batcher);
}
+} // namespace df
diff --git a/drape_frontend/path_text_shape.hpp b/drape_frontend/path_text_shape.hpp
index 27c942f76b..c61d2a86df 100644
--- a/drape_frontend/path_text_shape.hpp
+++ b/drape_frontend/path_text_shape.hpp
@@ -2,38 +2,49 @@
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/shape_view_params.hpp"
+#include "drape_frontend/text_layout.hpp"
#include "geometry/spline.hpp"
-namespace df
-{
+#include <memory>
+#include <vector>
-class PathTextLayout;
+namespace dp
+{
+class OverlayHandle;
+} // namespace dp
+namespace df
+{
class PathTextShape : public MapShape
{
public:
PathTextShape(m2::SharedSpline const & spline, PathTextViewParams const & params,
TileKey const & tileKey, uint32_t baseTextIndex);
+ bool CalculateLayout(ref_ptr<dp::TextureManager> textures);
+
+ std::vector<float> GetOffsets() const { return m_offsets; }
+
void Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> textures) const override;
MapShapeType GetType() const override { return MapShapeType::OverlayType; }
private:
- uint64_t GetOverlayPriority(uint32_t textIndex, bool followingMode) const;
+ uint64_t GetOverlayPriority(uint32_t textIndex, size_t textLength,
+ bool followingMode) const;
void DrawPathTextPlain(ref_ptr<dp::TextureManager> textures,
- ref_ptr<dp::Batcher> batcher,
- unique_ptr<PathTextLayout> && layout,
- vector<float> const & offests) const;
+ ref_ptr<dp::Batcher> batcher) const;
void DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures,
- ref_ptr<dp::Batcher> batcher,
- unique_ptr<PathTextLayout> && layout,
- vector<float> const & offsets) const;
+ ref_ptr<dp::Batcher> batcher) const;
+ drape_ptr<dp::OverlayHandle> CreateOverlayHandle(SharedTextLayout const & layoutPtr,
+ uint32_t textIndex, float offset,
+ ref_ptr<dp::TextureManager> textures) const;
m2::SharedSpline m_spline;
PathTextViewParams m_params;
m2::PointI const m_tileCoords;
uint32_t const m_baseTextIndex;
+ SharedTextLayout m_layout;
+ std::vector<float> m_offsets;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp
index db146519bc..12f50b748c 100644
--- a/drape_frontend/poi_symbol_shape.cpp
+++ b/drape_frontend/poi_symbol_shape.cpp
@@ -7,6 +7,8 @@
#include "drape/texture_manager.hpp"
#include "drape/utils/vertex_decl.hpp"
+#include <utility>
+
namespace
{
df::ColorConstant const kPoiDeletedMaskColor = "PoiDeletedMask";
@@ -14,9 +16,28 @@ df::ColorConstant const kPoiDeletedMaskColor = "PoiDeletedMask";
using SV = gpu::SolidTexturingVertex;
using MV = gpu::MaskedTexturingVertex;
+glsl::vec2 ShiftNormal(glsl::vec2 const & n, df::PoiSymbolViewParams const & params,
+ m2::PointF const & pixelSize)
+{
+ glsl::vec2 result = n + glsl::vec2(params.m_offset.x, params.m_offset.y);
+ m2::PointF const halfPixelSize = pixelSize * 0.5f;
+
+ if (params.m_anchor & dp::Top)
+ result.y += halfPixelSize.y;
+ else if (params.m_anchor & dp::Bottom)
+ result.y -= halfPixelSize.y;
+
+ if (params.m_anchor & dp::Left)
+ result.x += halfPixelSize.x;
+ else if (params.m_anchor & dp::Right)
+ result.x -= halfPixelSize.x;
+
+ return result;
+}
+
template<typename TVertex>
void Batch(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && handle,
- glsl::vec4 const & position,
+ glsl::vec4 const & position, df::PoiSymbolViewParams const & params,
dp::TextureManager::SymbolRegion const & symbolRegion,
dp::TextureManager::ColorRegion const & colorRegion)
{
@@ -25,7 +46,7 @@ void Batch(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && handle,
template<>
void Batch<SV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && handle,
- glsl::vec4 const & position,
+ glsl::vec4 const & position, df::PoiSymbolViewParams const & params,
dp::TextureManager::SymbolRegion const & symbolRegion,
dp::TextureManager::ColorRegion const & colorRegion)
{
@@ -35,13 +56,13 @@ void Batch<SV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && han
SV vertexes[] =
{
- SV{ position, glsl::vec2(-halfSize.x, halfSize.y),
+ SV{ position, ShiftNormal(glsl::vec2(-halfSize.x, halfSize.y), params, pixelSize),
glsl::vec2(texRect.minX(), texRect.maxY()) },
- SV{ position, glsl::vec2(-halfSize.x, -halfSize.y),
+ SV{ position, ShiftNormal(glsl::vec2(-halfSize.x, -halfSize.y), params, pixelSize),
glsl::vec2(texRect.minX(), texRect.minY()) },
- SV{ position, glsl::vec2(halfSize.x, halfSize.y),
+ SV{ position, ShiftNormal(glsl::vec2(halfSize.x, halfSize.y), params, pixelSize),
glsl::vec2(texRect.maxX(), texRect.maxY()) },
- SV{ position, glsl::vec2(halfSize.x, -halfSize.y),
+ SV{ position, ShiftNormal(glsl::vec2(halfSize.x, -halfSize.y), params, pixelSize),
glsl::vec2(texRect.maxX(), texRect.minY()) },
};
@@ -57,7 +78,7 @@ void Batch<SV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && han
template<>
void Batch<MV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && handle,
- glsl::vec4 const & position,
+ glsl::vec4 const & position, df::PoiSymbolViewParams const & params,
dp::TextureManager::SymbolRegion const & symbolRegion,
dp::TextureManager::ColorRegion const & colorRegion)
{
@@ -68,13 +89,13 @@ void Batch<MV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && han
MV vertexes[] =
{
- MV{ position, glsl::vec2(-halfSize.x, halfSize.y),
+ MV{ position, ShiftNormal(glsl::vec2(-halfSize.x, halfSize.y), params, pixelSize),
glsl::vec2(texRect.minX(), texRect.maxY()), maskColorCoords },
- MV{ position, glsl::vec2(-halfSize.x, -halfSize.y),
+ MV{ position, ShiftNormal(glsl::vec2(-halfSize.x, -halfSize.y), params, pixelSize),
glsl::vec2(texRect.minX(), texRect.minY()), maskColorCoords },
- MV{ position, glsl::vec2(halfSize.x, halfSize.y),
+ MV{ position, ShiftNormal(glsl::vec2(halfSize.x, halfSize.y), params, pixelSize),
glsl::vec2(texRect.maxX(), texRect.maxY()), maskColorCoords },
- MV{ position, glsl::vec2(halfSize.x, -halfSize.y),
+ MV{ position, ShiftNormal(glsl::vec2(halfSize.x, -halfSize.y), params, pixelSize),
glsl::vec2(texRect.maxX(), texRect.minY()), maskColorCoords },
};
@@ -88,8 +109,7 @@ void Batch<MV>(ref_ptr<dp::Batcher> batcher, drape_ptr<dp::OverlayHandle> && han
provider.InitStream(0 /* streamIndex */, MV::GetBindingInfo(), make_ref(vertexes));
batcher->InsertTriangleStrip(state, make_ref(&provider), move(handle));
}
-
-} // namespace
+} // namespace
namespace df
{
@@ -113,29 +133,34 @@ void PoiSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManag
glsl::vec4 const position = glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ);
m2::PointF const pixelSize = region.GetPixelSize();
- dp::OverlayID overlayId = dp::OverlayID(m_params.m_id, m_tileCoords, m_textIndex);
- drape_ptr<dp::OverlayHandle> handle = make_unique_dp<dp::SquareHandle>(overlayId,
- dp::Center,
- m_pt, pixelSize,
- GetOverlayPriority(),
- true /* isBound */,
- m_params.m_symbolName,
- true /* isBillboard */);
- handle->SetPivotZ(m_params.m_posZ);
- handle->SetExtendingSize(m_params.m_extendingSize);
-
if (m_params.m_obsoleteInEditor)
{
dp::TextureManager::ColorRegion maskColorRegion;
textures->GetColorRegion(df::GetColorConstant(kPoiDeletedMaskColor), maskColorRegion);
- Batch<MV>(batcher, move(handle), position, region, maskColorRegion);
+ Batch<MV>(batcher, CreateOverlayHandle(pixelSize), position, m_params,
+ region, maskColorRegion);
}
else
{
- Batch<SV>(batcher, move(handle), position, region, dp::TextureManager::ColorRegion());
+ Batch<SV>(batcher, CreateOverlayHandle(pixelSize), position, m_params,
+ region, dp::TextureManager::ColorRegion());
}
}
+drape_ptr<dp::OverlayHandle> PoiSymbolShape::CreateOverlayHandle(m2::PointF const & pixelSize) const
+{
+ dp::OverlayID overlayId = dp::OverlayID(m_params.m_id, m_tileCoords, m_textIndex);
+ drape_ptr<dp::OverlayHandle> handle = make_unique_dp<dp::SquareHandle>(overlayId, m_params.m_anchor,
+ m_pt, pixelSize, m_params.m_offset,
+ GetOverlayPriority(),
+ true /* isBound */,
+ m_params.m_symbolName,
+ true /* isBillboard */);
+ handle->SetPivotZ(m_params.m_posZ);
+ handle->SetExtendingSize(m_params.m_extendingSize);
+ return handle;
+}
+
uint64_t PoiSymbolShape::GetOverlayPriority() const
{
// Set up maximum priority for some POI.
@@ -152,5 +177,4 @@ uint64_t PoiSymbolShape::GetOverlayPriority() const
return dp::CalculateOverlayPriority(m_params.m_minVisibleScale, m_params.m_rank, m_params.m_depth);
}
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/poi_symbol_shape.hpp b/drape_frontend/poi_symbol_shape.hpp
index cc386de698..32c7c693c8 100644
--- a/drape_frontend/poi_symbol_shape.hpp
+++ b/drape_frontend/poi_symbol_shape.hpp
@@ -5,9 +5,13 @@
#include "drape/constants.hpp"
-namespace df
+namespace dp
{
+class OverlayHandle;
+} // namespace dp
+namespace df
+{
class PoiSymbolShape : public MapShape
{
public:
@@ -20,6 +24,7 @@ public:
private:
uint64_t GetOverlayPriority() const;
+ drape_ptr<dp::OverlayHandle> CreateOverlayHandle(m2::PointF const & pixelSize) const;
m2::PointD const m_pt;
PoiSymbolViewParams const m_params;
@@ -28,6 +33,5 @@ private:
m2::PointI const m_tileCoords;
uint32_t const m_textIndex;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp
index 904178a162..740980bb83 100644
--- a/drape_frontend/rule_drawer.cpp
+++ b/drape_frontend/rule_drawer.cpp
@@ -27,8 +27,12 @@
#include "base/string_utils.hpp"
#endif
+#include <functional>
+#include <utility>
#include <vector>
+using namespace std::placeholders;
+
namespace
{
// The first zoom level in kAverageSegmentsCount.
@@ -243,7 +247,8 @@ bool RuleDrawer::CheckCoastlines(FeatureType const & f, Stylist const & s)
return true;
}
-void RuleDrawer::ProcessAreaStyle(FeatureType const & f, Stylist const & s, TInsertShapeFn const & insertShape,
+void RuleDrawer::ProcessAreaStyle(FeatureType const & f, Stylist const & s,
+ TInsertShapeFn const & insertShape,
int & minVisibleScale)
{
bool isBuilding = false;
@@ -315,7 +320,7 @@ void RuleDrawer::ProcessAreaStyle(FeatureType const & f, Stylist const & s, TIns
if (CheckCancelled())
return;
- s.ForEachRule(bind(&ApplyAreaFeature::ProcessRule, &apply, _1));
+ s.ForEachRule(std::bind(&ApplyAreaFeature::ProcessAreaRule, &apply, _1));
apply.Finish(m_context->GetTextureManager(), m_customSymbolsContext);
}
@@ -334,7 +339,7 @@ void RuleDrawer::ProcessLineStyle(FeatureType const & f, Stylist const & s,
return;
if (applyGeom.HasGeometry())
- s.ForEachRule(bind(&ApplyLineFeatureGeometry::ProcessRule, &applyGeom, _1));
+ s.ForEachRule(std::bind(&ApplyLineFeatureGeometry::ProcessLineRule, &applyGeom, _1));
applyGeom.Finish();
std::vector<m2::SharedSpline> clippedSplines;
@@ -365,8 +370,9 @@ void RuleDrawer::ProcessLineStyle(FeatureType const & f, Stylist const & s,
ApplyLineFeatureAdditional applyAdditional(m_context->GetTileKey(), insertShape, f.GetID(),
m_currentScaleGtoP, minVisibleScale, f.GetRank(),
s.GetCaptionDescription(), clippedSplines);
- s.ForEachRule(bind(&ApplyLineFeatureAdditional::ProcessRule, &applyAdditional, _1));
- applyAdditional.Finish(ftypes::GetRoadShields(f));
+ s.ForEachRule(std::bind(&ApplyLineFeatureAdditional::ProcessLineRule, &applyAdditional, _1));
+ applyAdditional.Finish(m_context->GetTextureManager(), ftypes::GetRoadShields(f),
+ m_generatedRoadShields);
}
if (m_context->IsTrafficEnabled() && zoomLevel >= kRoadClass0ZoomLevel)
@@ -421,7 +427,7 @@ void RuleDrawer::ProcessPointStyle(FeatureType const & f, Stylist const & s, TIn
if (CheckCancelled())
return;
- s.ForEachRule(bind(&ApplyPointFeature::ProcessRule, &apply, _1));
+ s.ForEachRule(bind(&ApplyPointFeature::ProcessPointRule, &apply, _1));
apply.Finish(m_context->GetTextureManager(), m_customSymbolsContext);
}
diff --git a/drape_frontend/rule_drawer.hpp b/drape_frontend/rule_drawer.hpp
index ee3bd6148f..674540b6bf 100644
--- a/drape_frontend/rule_drawer.hpp
+++ b/drape_frontend/rule_drawer.hpp
@@ -8,11 +8,14 @@
#include "drape/pointers.hpp"
+#include "indexer/road_shields_parser.hpp"
+
#include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp"
#include <array>
#include <functional>
+#include <map>
#include <string>
#include <unordered_set>
@@ -71,5 +74,7 @@ private:
std::array<TMapShapes, df::MapShapeTypeCount> m_mapShapes;
bool m_wasCancelled;
+
+ GeneratedRoadShields m_generatedRoadShields;
};
} // namespace df
diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp
index 22bb31c2ce..fde5123bf8 100644
--- a/drape_frontend/shape_view_params.hpp
+++ b/drape_frontend/shape_view_params.hpp
@@ -34,6 +34,8 @@ struct PoiSymbolViewParams : CommonViewParams
bool m_hasArea = false;
bool m_prioritized = false;
bool m_obsoleteInEditor = false;
+ dp::Anchor m_anchor = dp::Center;
+ m2::PointF m_offset = m2::PointF(0.0f, 0.0f);
};
struct AreaViewParams : CommonViewParams
@@ -84,7 +86,8 @@ struct PathTextViewParams : CommonViewParams
{
FeatureID m_featureID;
dp::FontDecl m_textFont;
- string m_text;
+ std::string m_mainText;
+ std::string m_auxText;
float m_baseGtoPScale = 1.0f;
};
@@ -106,11 +109,13 @@ struct ColoredSymbolViewParams : CommonViewParams
FeatureID m_featureID;
Shape m_shape = Shape::Circle;
+ dp::Anchor m_anchor = dp::Center;
dp::Color m_color;
dp::Color m_outlineColor;
float m_radiusInPixels = 0.0f;
m2::PointF m_sizeInPixels = m2::PointF(0.0f, 0.0f);
float m_outlineWidth = 0.0f;
+ m2::PointF m_offset = m2::PointF(0.0f, 0.0f);
};
} // namespace df
diff --git a/drape_frontend/stylist.cpp b/drape_frontend/stylist.cpp
index f87a697066..270ca66821 100644
--- a/drape_frontend/stylist.cpp
+++ b/drape_frontend/stylist.cpp
@@ -249,15 +249,6 @@ string const & CaptionDescription::GetRoadNumber() const
return m_roadNumber;
}
-string CaptionDescription::GetPathName() const
-{
- // Always concat names for linear features because we process only one draw rule now.
- if (m_mainText.empty())
- return m_mainText;
- else
- return m_mainText + " " + m_auxText;
-}
-
bool CaptionDescription::IsNameExists() const
{
return !m_mainText.empty() || !m_houseNumber.empty();
diff --git a/drape_frontend/stylist.hpp b/drape_frontend/stylist.hpp
index b6efaead30..bd5c99e5c5 100644
--- a/drape_frontend/stylist.hpp
+++ b/drape_frontend/stylist.hpp
@@ -49,7 +49,6 @@ struct CaptionDescription
string const & GetMainText() const;
string const & GetAuxText() const;
string const & GetRoadNumber() const;
- string GetPathName() const;
bool IsNameExists() const;
private:
diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp
index 515c33a7d9..d91cd9eb73 100644
--- a/drape_frontend/text_layout.cpp
+++ b/drape_frontend/text_layout.cpp
@@ -6,18 +6,14 @@
#include "drape/glsl_func.hpp"
#include "drape/overlay_handle.hpp"
-#include "std/algorithm.hpp"
-#include "std/bind.hpp"
-#include "std/iterator.hpp"
-#include "std/numeric.hpp"
-
+#include <algorithm>
+#include <iterator>
+#include <numeric>
namespace df
{
-
namespace
{
-
float const kValidSplineTurn = 0.96f;
class TextGeometryGenerator
@@ -27,17 +23,17 @@ public:
gpu::TTextStaticVertexBuffer & buffer)
: m_colorCoord(glsl::ToVec2(color.GetTexRect().Center()))
, m_buffer(buffer)
- {
- }
+ {}
void operator() (dp::TextureManager::GlyphRegion const & glyph)
{
m2::RectF const & mask = glyph.GetTexRect();
- m_buffer.emplace_back(gpu::TextStaticVertex(m_colorCoord, glsl::ToVec2(mask.LeftTop())));
- m_buffer.emplace_back(gpu::TextStaticVertex(m_colorCoord, glsl::ToVec2(mask.LeftBottom())));
- m_buffer.emplace_back(gpu::TextStaticVertex(m_colorCoord, glsl::ToVec2(mask.RightTop())));
- m_buffer.emplace_back(gpu::TextStaticVertex(m_colorCoord, glsl::ToVec2(mask.RightBottom())));
+ using TSV = gpu::TextStaticVertex;
+ m_buffer.emplace_back(TSV(m_colorCoord, glsl::ToVec2(mask.LeftTop())));
+ m_buffer.emplace_back(TSV(m_colorCoord, glsl::ToVec2(mask.LeftBottom())));
+ m_buffer.emplace_back(TSV(m_colorCoord, glsl::ToVec2(mask.RightTop())));
+ m_buffer.emplace_back(TSV(m_colorCoord, glsl::ToVec2(mask.RightBottom())));
}
protected:
@@ -50,7 +46,8 @@ class StraightTextGeometryGenerator : public TParentGenerator
{
public:
template<typename... TParentGeneratorParams>
- StraightTextGeometryGenerator(glsl::vec4 const & pivot, glsl::vec2 const & pixelOffset, float textRatio,
+ StraightTextGeometryGenerator(glsl::vec4 const & pivot,
+ glsl::vec2 const & pixelOffset, float textRatio,
gpu::TTextDynamicVertexBuffer & dynBuffer,
TParentGeneratorParams & ... parentGeneratorParams)
: TParentGenerator(parentGeneratorParams...)
@@ -78,10 +75,11 @@ public:
m_penPosition.x -= (xOffset + dp::kSdfBorder * m_textRatio);
}
- m_buffer.emplace_back(gpu::TextDynamicVertex(m_pivot, m_penPosition + glsl::vec2(xOffset, bottomVector)));
- m_buffer.emplace_back(gpu::TextDynamicVertex(m_pivot, m_penPosition + glsl::vec2(xOffset, upVector)));
- m_buffer.emplace_back(gpu::TextDynamicVertex(m_pivot, m_penPosition + glsl::vec2(pixelSize.x + xOffset, bottomVector)));
- m_buffer.emplace_back(gpu::TextDynamicVertex(m_pivot, m_penPosition + glsl::vec2(pixelSize.x + xOffset, upVector)));
+ using TDV = gpu::TextDynamicVertex;
+ m_buffer.emplace_back(TDV(m_pivot, m_penPosition + glsl::vec2(xOffset, bottomVector)));
+ m_buffer.emplace_back(TDV(m_pivot, m_penPosition + glsl::vec2(xOffset, upVector)));
+ m_buffer.emplace_back(TDV(m_pivot, m_penPosition + glsl::vec2(pixelSize.x + xOffset, bottomVector)));
+ m_buffer.emplace_back(TDV(m_pivot, m_penPosition + glsl::vec2(pixelSize.x + xOffset, upVector)));
m_penPosition += glsl::vec2(glyph.GetAdvanceX() * m_textRatio, glyph.GetAdvanceY() * m_textRatio);
TParentGenerator::operator()(glyph);
@@ -104,16 +102,16 @@ public:
: m_colorCoord(glsl::ToVec2(color.GetTexRect().Center()))
, m_outlineCoord(glsl::ToVec2(outline.GetTexRect().Center()))
, m_buffer(buffer)
- {
- }
+ {}
void operator() (dp::TextureManager::GlyphRegion const & glyph)
{
+ using TOSV = gpu::TextOutlinedStaticVertex;
m2::RectF const & mask = glyph.GetTexRect();
- m_buffer.emplace_back(gpu::TextOutlinedStaticVertex(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftTop())));
- m_buffer.emplace_back(gpu::TextOutlinedStaticVertex(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftBottom())));
- m_buffer.emplace_back(gpu::TextOutlinedStaticVertex(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightTop())));
- m_buffer.emplace_back(gpu::TextOutlinedStaticVertex(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightBottom())));
+ m_buffer.emplace_back(TOSV(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftTop())));
+ m_buffer.emplace_back(TOSV(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftBottom())));
+ m_buffer.emplace_back(TOSV(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightTop())));
+ m_buffer.emplace_back(TOSV(m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightBottom())));
}
protected:
@@ -122,9 +120,7 @@ protected:
gpu::TTextOutlinedStaticVertexBuffer & m_buffer;
};
-///Old code
-void SplitText(strings::UniString & visText,
- buffer_vector<size_t, 2> & delimIndexes)
+void SplitText(strings::UniString & visText, buffer_vector<size_t, 2> & delimIndexes)
{
char const * delims = " \n\t";
size_t count = visText.size();
@@ -132,30 +128,30 @@ void SplitText(strings::UniString & visText,
{
// split on two parts
typedef strings::UniString::iterator TIter;
- TIter const iMiddle = visText.begin() + count/2;
+ auto const iMiddle = visText.begin() + count / 2;
size_t const delimsSize = strlen(delims);
// find next delimeter after middle [m, e)
- TIter iNext = find_first_of(iMiddle,
- visText.end(),
- delims, delims + delimsSize);
+ auto iNext = std::find_first_of(iMiddle,
+ visText.end(),
+ delims, delims + delimsSize);
// find last delimeter before middle [b, m)
- TIter iPrev = find_first_of(reverse_iterator<TIter>(iMiddle),
- reverse_iterator<TIter>(visText.begin()),
- delims, delims + delimsSize).base();
+ auto iPrev = std::find_first_of(std::reverse_iterator<TIter>(iMiddle),
+ std::reverse_iterator<TIter>(visText.begin()),
+ delims, delims + delimsSize).base();
// don't do split like this:
// xxxx
// xxxxxxxxxxxx
- if (4 * distance(visText.begin(), iPrev) <= static_cast<long>(count))
+ if (4 * std::distance(visText.begin(), iPrev) <= static_cast<long>(count))
iPrev = visText.end();
else
--iPrev;
// get closest delimiter to the middle
if (iNext == visText.end() ||
- (iPrev != visText.end() && distance(iPrev, iMiddle) < distance(iMiddle, iNext)))
+ (iPrev != visText.end() && std::distance(iPrev, iMiddle) < std::distance(iMiddle, iNext)))
{
iNext = iPrev;
}
@@ -167,7 +163,7 @@ void SplitText(strings::UniString & visText,
TIter delimSymbol = iNext;
TIter secondPart = iNext + 1;
- delimIndexes.push_back(distance(visText.begin(), delimSymbol));
+ delimIndexes.push_back(static_cast<size_t>(std::distance(visText.begin(), delimSymbol)));
if (secondPart != visText.end())
{
@@ -176,7 +172,6 @@ void SplitText(strings::UniString & visText,
visText = result;
delimIndexes.push_back(visText.size());
}
-
return;
}
}
@@ -189,8 +184,7 @@ class XLayouter
public:
XLayouter(dp::Anchor anchor)
: m_anchor(anchor)
- {
- }
+ {}
float operator()(float currentLength, float maxLength)
{
@@ -284,16 +278,17 @@ void CalculateOffsets(dp::Anchor anchor, float textRatio,
pixelSize = m2::PointF(maxLength, summaryHeight);
}
-
-} // namespace
+} // namespace
void TextLayout::Init(strings::UniString const & text, float fontSize, bool isSdf,
ref_ptr<dp::TextureManager> textures)
{
m_text = text;
- double const fontScale = VisualParams::Instance().GetFontScale();
- m_textSizeRatio = isSdf ? (fontSize * fontScale / VisualParams::Instance().GetGlyphBaseSize()) : 1.0;
- m_fixedHeight = isSdf ? dp::GlyphManager::kDynamicGlyphSize : fontSize * fontScale;
+ float const fontScale = static_cast<float>(VisualParams::Instance().GetFontScale());
+ float const baseSize = static_cast<float>(VisualParams::Instance().GetGlyphBaseSize());
+ m_textSizeRatio = isSdf ? (fontSize * fontScale / baseSize) : 1.0f;
+ m_fixedHeight = isSdf ? dp::GlyphManager::kDynamicGlyphSize
+ : static_cast<int>(fontSize * fontScale);
textures->GetGlyphRegions(text, m_fixedHeight, m_metrics);
}
@@ -318,15 +313,17 @@ uint32_t TextLayout::GetGlyphCount() const
float TextLayout::GetPixelLength() const
{
- return m_textSizeRatio * accumulate(m_metrics.begin(), m_metrics.end(), 0.0, [](double const & v, GlyphRegion const & glyph)
+ return m_textSizeRatio * std::accumulate(m_metrics.begin(), m_metrics.end(), 0.0f,
+ [](double const & v, GlyphRegion const & glyph) -> float
{
- return v + glyph.GetAdvanceX();
+ return static_cast<float>(v) + glyph.GetAdvanceX();
});
}
float TextLayout::GetPixelHeight() const
{
- return m_fixedHeight > 0 ? m_fixedHeight : m_textSizeRatio * VisualParams::Instance().GetGlyphBaseSize();
+ return m_fixedHeight > 0 ? m_fixedHeight
+ : m_textSizeRatio * VisualParams::Instance().GetGlyphBaseSize();
}
strings::UniString const & TextLayout::GetText() const
@@ -401,21 +398,23 @@ void PathTextLayout::CacheStaticGeometry(dp::TextureManager::ColorRegion const &
gpu::TTextOutlinedStaticVertexBuffer & staticBuffer) const
{
TextOutlinedGeometryGenerator gen(colorRegion, outlineRegion, staticBuffer);
- for_each(m_metrics.begin(), m_metrics.end(), gen);
+ std::for_each(m_metrics.begin(), m_metrics.end(), gen);
}
void PathTextLayout::CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion,
gpu::TTextStaticVertexBuffer & staticBuffer) const
{
TextGeometryGenerator gen(colorRegion, staticBuffer);
- for_each(m_metrics.begin(), m_metrics.end(), gen);
+ std::for_each(m_metrics.begin(), m_metrics.end(), gen);
}
bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, float depth,
m2::PointD const & globalPivot,
gpu::TTextDynamicVertexBuffer & buffer) const
{
- float const halfLength = 0.5 * GetPixelLength();
+ using TDV = gpu::TextDynamicVertex;
+
+ float const halfLength = 0.5f * GetPixelLength();
m2::Spline::iterator beginIter = iter;
beginIter.Advance(-halfLength);
@@ -424,7 +423,7 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo
if (beginIter.BeginAgain() || endIter.BeginAgain())
return false;
- float const halfFontSize = 0.5 * GetPixelHeight();
+ float const halfFontSize = 0.5f * GetPixelHeight();
float advanceSign = 1.0f;
m2::Spline::iterator penIter = beginIter;
if (beginIter.m_pos.x > endIter.m_pos.x)
@@ -436,7 +435,8 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo
glsl::vec2 pxPivot = glsl::ToVec2(iter.m_pos);
buffer.resize(4 * m_metrics.size());
- glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertToLocal(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f);
+ glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertToLocal(globalPivot, m_tileCenter,
+ kShapeCoordScalar)), depth, 0.0f);
for (size_t i = 0; i < m_metrics.size(); ++i)
{
GlyphRegion const & g = m_metrics[i];
@@ -457,10 +457,10 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo
size_t baseIndex = 4 * i;
- buffer[baseIndex + 0] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * xOffset);
- buffer[baseIndex + 1] = gpu::TextDynamicVertex(pivot, formingVector + normal * upVector + tangent * xOffset);
- buffer[baseIndex + 2] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * (pxSize.x + xOffset));
- buffer[baseIndex + 3] = gpu::TextDynamicVertex(pivot, formingVector + normal * upVector + tangent * (pxSize.x + xOffset));
+ buffer[baseIndex + 0] = TDV(pivot, formingVector + normal * bottomVector + tangent * xOffset);
+ buffer[baseIndex + 1] = TDV(pivot, formingVector + normal * upVector + tangent * xOffset);
+ buffer[baseIndex + 2] = TDV(pivot, formingVector + normal * bottomVector + tangent * (pxSize.x + xOffset));
+ buffer[baseIndex + 3] = TDV(pivot, formingVector + normal * upVector + tangent * (pxSize.x + xOffset));
float const xAdvance = g.GetAdvanceX() * m_textSizeRatio;
glsl::vec2 currentTangent = glsl::ToVec2(penIter.m_dir);
@@ -469,19 +469,18 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo
if (dotProduct < kValidSplineTurn)
return false;
}
-
return true;
}
float PathTextLayout::CalculateTextLength(float textPixelLength)
{
- //we leave a little space on either side of the text that would
- //remove the comparison for equality of spline portions
+ // We leave a little space on each side of the text.
float const kTextBorder = 4.0f;
return kTextBorder + textPixelLength;
}
-bool PathTextLayout::CalculatePerspectivePosition(float splineLength, float textPixelLength, float & offset)
+bool PathTextLayout::CalculatePerspectivePosition(float splineLength, float textPixelLength,
+ float & offset)
{
float const textLength = CalculateTextLength(textPixelLength);
if (textLength > splineLength * 2.0f)
@@ -491,26 +490,27 @@ bool PathTextLayout::CalculatePerspectivePosition(float splineLength, float text
return true;
}
-void PathTextLayout::CalculatePositions(vector<float> & offsets, float splineLength,
- float splineScaleToPixel, float textPixelLength)
+void PathTextLayout::CalculatePositions(float splineLength, float splineScaleToPixel,
+ float textPixelLength, std::vector<float> & offsets)
{
float const textLength = CalculateTextLength(textPixelLength);
- // on next readable scale m_scaleGtoP will be twice
+ // On the next scale m_scaleGtoP will be twice.
if (textLength > splineLength * 2.0f * splineScaleToPixel)
return;
float const kPathLengthScalar = 0.75;
float const pathLength = kPathLengthScalar * splineScaleToPixel * splineLength;
- float const etalonEmpty = max(300 * df::VisualParams::Instance().GetVisualScale(), (double)textLength);
+ float const vs = static_cast<float>(df::VisualParams::Instance().GetVisualScale());
+ float const etalonEmpty = std::max(300.0f * vs, textLength);
float const minPeriodSize = etalonEmpty + textLength;
- float const twoTextAndEmpty = minPeriodSize + textLength;
+ float const twoTextsAndEmpty = minPeriodSize + textLength;
- if (pathLength < twoTextAndEmpty)
+ if (pathLength < twoTextsAndEmpty)
{
- // if we can't place 2 text and empty part on path
- // we place only one text on center of path
+ // If we can't place 2 texts and empty part along the path,
+ // we place only one text at the center of the path.
offsets.push_back(splineLength * 0.5f);
}
else
@@ -518,18 +518,17 @@ void PathTextLayout::CalculatePositions(vector<float> & offsets, float splineLen
double const textCount = max(floor(static_cast<double>(pathLength / minPeriodSize)), 1.0);
double const glbTextLen = splineLength / textCount;
for (double offset = 0.5 * glbTextLen; offset < splineLength; offset += glbTextLen)
- offsets.push_back(offset);
+ offsets.push_back(static_cast<float>(offset));
}
}
SharedTextLayout::SharedTextLayout(PathTextLayout * layout)
: m_layout(layout)
-{
-}
+{}
bool SharedTextLayout::IsNull() const
{
- return m_layout == NULL;
+ return m_layout == nullptr;
}
void SharedTextLayout::Reset(PathTextLayout * layout)
@@ -551,5 +550,4 @@ PathTextLayout const * SharedTextLayout::operator->() const
{
return m_layout.get();
}
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/text_layout.hpp b/drape_frontend/text_layout.hpp
index 96545a1233..87b261bb19 100644
--- a/drape_frontend/text_layout.hpp
+++ b/drape_frontend/text_layout.hpp
@@ -14,39 +14,34 @@
#include "base/string_utils.hpp"
#include "base/buffer_vector.hpp"
-#include "std/vector.hpp"
-#include "std/shared_ptr.hpp"
+#include <memory>
+#include <vector>
namespace dp
{
- class OverlayHandle;
-}
+class OverlayHandle;
+} // namespace dp
namespace df
{
-
class TextLayout
{
-
public:
virtual ~TextLayout() {}
- ref_ptr<dp::Texture> GetMaskTexture() const;
+ void Init(strings::UniString const & text,
+ float fontSize, bool isSdf,
+ ref_ptr<dp::TextureManager> textures);
+ ref_ptr<dp::Texture> GetMaskTexture() const;
uint32_t GetGlyphCount() const;
-
float GetPixelLength() const;
float GetPixelHeight() const;
-
int GetFixedHeight() const { return m_fixedHeight; }
-
strings::UniString const & GetText() const;
protected:
- void Init(strings::UniString const & text, float fontSize, bool isSdf, ref_ptr<dp::TextureManager> textures);
-
-protected:
- typedef dp::TextureManager::GlyphRegion GlyphRegion;
+ using GlyphRegion = dp::TextureManager::GlyphRegion;
dp::TextureManager::TGlyphsBuffer m_metrics;
strings::UniString m_text;
@@ -103,9 +98,8 @@ public:
static bool CalculatePerspectivePosition(float splineLength, float textPixelLength,
float & offset);
- static void CalculatePositions(vector<float> & offsets, float splineLength,
- float splineScaleToPixel, float textPixelLength);
-
+ static void CalculatePositions(float splineLength, float splineScaleToPixel,
+ float textPixelLength, std::vector<float> & offsets);
private:
static float CalculateTextLength(float textPixelLength);
@@ -115,6 +109,7 @@ private:
class SharedTextLayout
{
public:
+ SharedTextLayout() = default;
SharedTextLayout(PathTextLayout * layout);
bool IsNull() const;
@@ -125,7 +120,6 @@ public:
PathTextLayout const * operator->() const;
private:
- shared_ptr<PathTextLayout> m_layout;
+ std::shared_ptr<PathTextLayout> m_layout;
};
-
-}
+} // namespace df
diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp
index 480af7abeb..96db75cdef 100644
--- a/drape_frontend/text_shape.cpp
+++ b/drape_frontend/text_shape.cpp
@@ -12,8 +12,6 @@
#include "base/string_utils.hpp"
-#include "std/vector.hpp"
-
namespace df
{
namespace
@@ -118,7 +116,6 @@ private:
bool m_isOptional;
bool m_affectedByZoomPriority;
};
-
} // namespace
TextShape::TextShape(m2::PointD const & basePoint, TextViewParams const & params,
@@ -163,8 +160,8 @@ void TextShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t
glsl::vec2 primaryOffset(0.0f, 0.0f);
glsl::vec2 secondaryOffset(0.0f, 0.0f);
- float const halfSymbolW = m_symbolSize.x / 2.0;
- float const halfSymbolH = m_symbolSize.y / 2.0;
+ float const halfSymbolW = m_symbolSize.x / 2.0f;
+ float const halfSymbolH = m_symbolSize.y / 2.0f;
if (m_params.m_anchor & dp::Top)
{
@@ -234,13 +231,9 @@ void TextShape::DrawSubString(StraightTextLayout const & layout, dp::FontDecl co
: m_params.m_secondaryTextFont.m_outlineColor;
if (outlineColor == dp::Color::Transparent())
- {
DrawSubStringPlain(layout, font, baseOffset, batcher, textures, isPrimary, isOptional);
- }
else
- {
DrawSubStringOutlined(layout, font, baseOffset, batcher, textures, isPrimary, isOptional);
- }
}
void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDecl const & font,
diff --git a/geometry/spline.cpp b/geometry/spline.cpp
index fd59e3ebe4..c74df1013a 100644
--- a/geometry/spline.cpp
+++ b/geometry/spline.cpp
@@ -92,6 +92,14 @@ bool Spline::IsValid() const
return m_position.size() > 1;
}
+Spline::iterator Spline::GetPoint(double step) const
+{
+ iterator it;
+ it.Attach(*this);
+ it.Advance(step);
+ return it;
+}
+
Spline const & Spline::operator = (Spline const & spl)
{
if(&spl != this)
diff --git a/geometry/spline.hpp b/geometry/spline.hpp
index da5879c180..dedf5505f8 100644
--- a/geometry/spline.hpp
+++ b/geometry/spline.hpp
@@ -56,6 +56,8 @@ public:
size_t GetSize() const;
vector<PointD> const & GetPath() const { return m_position; }
+ iterator GetPoint(double step) const;
+
template <typename TFunctor>
void ForEachNode(iterator const & begin, iterator const & end, TFunctor & f) const
{
diff --git a/indexer/road_shields_parser.hpp b/indexer/road_shields_parser.hpp
index 9133ab083d..1fd01aa001 100644
--- a/indexer/road_shields_parser.hpp
+++ b/indexer/road_shields_parser.hpp
@@ -2,6 +2,9 @@
#include "indexer/feature.hpp"
+#include "geometry/rect2d.hpp"
+
+#include <map>
#include <string>
#include <vector>
@@ -32,13 +35,20 @@ struct RoadShield
RoadShield(RoadShieldType const & type, std::string const & name)
: m_type(type), m_name(name)
{}
- RoadShield(RoadShieldType const & type, std::string const & name, std::string const & additionalText)
+ RoadShield(RoadShieldType const & type, std::string const & name,
+ std::string const & additionalText)
: m_type(type), m_name(name), m_additionalText(additionalText)
{}
inline bool operator<(RoadShield const & other) const
{
- return m_type < other.m_type || m_name < other.m_name || m_additionalText < other.m_additionalText;
+ if (m_type == other.m_type)
+ {
+ if (m_name == other.m_name)
+ return m_additionalText < other.m_additionalText;
+ return m_name < other.m_name;
+ }
+ return m_type < other.m_type;
}
};
@@ -46,3 +56,6 @@ std::set<RoadShield> GetRoadShields(FeatureType const & f);
std::string DebugPrint(RoadShieldType shieldType);
std::string DebugPrint(RoadShield const & shield);
} // namespace ftypes
+
+using GeneratedRoadShields = std::map<ftypes::RoadShield, std::vector<m2::RectD>>;
+