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:
Diffstat (limited to 'drape_frontend/text_layout.cpp')
-rw-r--r--drape_frontend/text_layout.cpp100
1 files changed, 87 insertions, 13 deletions
diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp
index a477bbe30b..1b177b6f68 100644
--- a/drape_frontend/text_layout.cpp
+++ b/drape_frontend/text_layout.cpp
@@ -16,6 +16,7 @@ namespace
{
float const BASE_HEIGHT = 20.0f;
+float const VALID_SPLINE_TURN = 0.96f;
class TextGeometryGenerator
{
@@ -70,9 +71,7 @@ public:
void operator()(dp::TextureManager::GlyphRegion const & glyph)
{
- m2::PointU pixelSize(m2::PointU::Zero());
- glyph.GetPixelSize(pixelSize);
- pixelSize *= m_textRatio;
+ m2::PointF pixelSize = m2::PointF(glyph.GetPixelSize()) * m_textRatio;
float const xOffset = glyph.GetOffsetX() * m_textRatio;
float const yOffset = glyph.GetOffsetY() * m_textRatio;
@@ -251,11 +250,6 @@ void CalculateOffsets(dp::Anchor anchor,
} // namespace
-TextLayout::TextLayout(df::TextLayout::LayoutType type)
- : m_type(type)
-{
-}
-
void TextLayout::Init(strings::UniString const & text, float fontSize,
dp::RefPointer<dp::TextureManager> textures)
{
@@ -295,7 +289,6 @@ float TextLayout::GetPixelHeight() const
StraightTextLayout::StraightTextLayout(strings::UniString const & text, float fontSize,
dp::RefPointer<dp::TextureManager> textures, dp::Anchor anchor)
- : TBase(TextLayout::LayoutType::StraightLayout)
{
strings::UniString visibleText = fribidi::log2vis(text);
buffer_vector<size_t, 2> delimIndexes;
@@ -327,8 +320,84 @@ void StraightTextLayout::Cache(glm::vec3 const & pivot, glm::vec2 const & pixelO
}
}
+PathTextLayout::PathTextLayout(strings::UniString const & text, float fontSize,
+ dp::RefPointer<dp::TextureManager> textures)
+{
+ Init(fribidi::log2vis(text), fontSize, textures);
+}
+
+void PathTextLayout::CacheStaticGeometry(glm::vec3 const & pivot,
+ dp::TextureManager::ColorRegion const & colorRegion,
+ dp::TextureManager::ColorRegion const & outlineRegion,
+ gpu::TTextStaticVertexBuffer & staticBuffer) const
+{
+ TextGeometryGenerator gen(pivot, colorRegion, outlineRegion, staticBuffer);
+ for_each(m_metrics.begin(), m_metrics.end(), gen);
+}
+
+bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, ScreenBase const & screen,
+ gpu::TTextDynamicVertexBuffer & buffer) const
+{
+ float const scalePtoG = screen.GetScale();
+ float const glbHalfLength = 0.5 * GetPixelLength() * scalePtoG;
+
+ m2::Spline::iterator beginIter = iter;
+ beginIter.Advance(-glbHalfLength);
+ m2::Spline::iterator endIter = iter;
+ endIter.Advance(glbHalfLength);
+ if (beginIter.BeginAgain() || endIter.BeginAgain())
+ return false;
+
+ float const halfFontSize = 0.5 * GetPixelHeight();
+ float advanceSign = 1.0f;
+ m2::Spline::iterator penIter = beginIter;
+ if (screen.GtoP(beginIter.m_pos).x > screen.GtoP(endIter.m_pos).x)
+ {
+ advanceSign = -advanceSign;
+ penIter = endIter;
+ }
+
+ glsl::vec2 pxPivot = glsl::ToVec2(screen.GtoP(iter.m_pos));
+ buffer.resize(4 * m_metrics.size());
+ for (size_t i = 0; i < m_metrics.size(); ++i)
+ {
+ GlyphRegion const & g = m_metrics[i];
+ m2::PointF pxSize = m2::PointF(g.GetPixelSize()) * m_textSizeRatio;
+
+ m2::PointD const pxBase = screen.GtoP(penIter.m_pos);
+ m2::PointD const pxShiftBase = screen.GtoP(penIter.m_pos + penIter.m_dir);
+
+ glsl::vec2 tangent = advanceSign * glsl::normalize(glsl::ToVec2(pxShiftBase - pxBase));
+ glsl::vec2 normal = glsl::normalize(glsl::vec2(-tangent.y, tangent.x));
+ glsl::vec2 formingVector = (glsl::ToVec2(pxBase) - pxPivot) + (halfFontSize * normal);
+
+ float const xOffset = g.GetOffsetX() * m_textSizeRatio;
+ float const yOffset = g.GetOffsetY() * m_textSizeRatio;
+
+ float const upVector = - (pxSize.y + yOffset);
+ float const bottomVector = - yOffset;
+
+ size_t baseIndex = 4 * i;
+
+ buffer[baseIndex + 0] = gpu::TextDynamicVertex(formingVector + normal * upVector + tangent * xOffset);
+ buffer[baseIndex + 1] = gpu::TextDynamicVertex(formingVector + normal * bottomVector + tangent * xOffset);
+ buffer[baseIndex + 2] = gpu::TextDynamicVertex(formingVector + normal * upVector + tangent * (pxSize.x + xOffset));
+ buffer[baseIndex + 3] = gpu::TextDynamicVertex(formingVector + normal * bottomVector + tangent * (pxSize.x + xOffset));
+
+
+ float const xAdvance = g.GetAdvanceX() * m_textSizeRatio;
+ glsl::vec2 currentTangent = glsl::ToVec2(penIter.m_dir);
+ penIter.Advance(advanceSign * xAdvance * scalePtoG);
+ float const dotProduct = glsl::dot(currentTangent, glsl::ToVec2(penIter.m_dir));
+ if (dotProduct < VALID_SPLINE_TURN)
+ return false;
+ }
+
+ return true;
+}
+
///////////////////////////////////////////////////////////////
-SharedTextLayout::SharedTextLayout(TextLayout * layout)
+SharedTextLayout::SharedTextLayout(PathTextLayout * layout)
: m_layout(layout)
{
}
@@ -338,17 +407,22 @@ bool SharedTextLayout::IsNull() const
return m_layout == NULL;
}
-void SharedTextLayout::Reset(TextLayout * layout)
+void SharedTextLayout::Reset(PathTextLayout * layout)
{
m_layout.reset(layout);
}
-TextLayout * SharedTextLayout::operator->()
+PathTextLayout * SharedTextLayout::GetRaw()
+{
+ return m_layout.get();
+}
+
+PathTextLayout * SharedTextLayout::operator->()
{
return m_layout.get();
}
-TextLayout const * SharedTextLayout::operator->() const
+PathTextLayout const * SharedTextLayout::operator->() const
{
return m_layout.get();
}