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:
authorRoman Kuznetsov <r.kuznetsow@gmail.com>2017-01-09 14:40:18 +0300
committerGitHub <noreply@github.com>2017-01-09 14:40:18 +0300
commit8b5398dbd1904d03542fa5560d2288f0f9efc5fc (patch)
tree4e5896ca1590f152a7334a0bc987d743a22ed8af
parentd001d0e42479a61772ad235e69113b07f92f5d38 (diff)
parentef4348e4bad8127ff79998835ef292da59237e8f (diff)
Merge pull request #5141 from darina/text-non-sdf-supportbeta-561
Non-sdf text support for ldpi and mdpi devices.
-rw-r--r--drape/drape.pro2
-rw-r--r--drape/drape_global.hpp4
-rw-r--r--drape/drape_tests/font_texture_tests.cpp18
-rw-r--r--drape/drape_tests/glyph_mng_tests.cpp2
-rw-r--r--drape/font_texture.cpp18
-rw-r--r--drape/font_texture.hpp22
-rw-r--r--drape/glyph_manager.cpp110
-rw-r--r--drape/glyph_manager.hpp9
-rw-r--r--drape/shaders/shader_index.txt2
-rwxr-xr-xdrape/shaders/text_fixed_fragment_shader.fsh24
-rw-r--r--drape/texture_manager.cpp38
-rw-r--r--drape/texture_manager.hpp48
-rw-r--r--drape_frontend/apply_feature_functors.cpp6
-rw-r--r--drape_frontend/gui/gui_text.cpp8
-rw-r--r--drape_frontend/path_text_shape.cpp12
-rw-r--r--drape_frontend/text_handle.cpp8
-rw-r--r--drape_frontend/text_handle.hpp5
-rw-r--r--drape_frontend/text_layout.cpp18
-rw-r--r--drape_frontend/text_layout.hpp11
-rw-r--r--drape_frontend/text_shape.cpp18
-rw-r--r--drape_head/testing_engine.cpp2
21 files changed, 245 insertions, 140 deletions
diff --git a/drape/drape.pro b/drape/drape.pro
index d3498eef8f..bcdf1d71be 100644
--- a/drape/drape.pro
+++ b/drape/drape.pro
@@ -43,6 +43,8 @@ OTHER_FILES += \
shaders/shader_index.txt \
shaders/solid_color_fragment_shader.fsh \
shaders/text_billboard_vertex_shader.vsh \
+ shaders/text_fixed_fragment_shader.fsh \
+ shaders/text_fixed_vertex_shader.vsh \
shaders/text_fragment_shader.fsh \
shaders/text_outlined_billboard_vertex_shader.vsh \
shaders/text_outlined_gui_vertex_shader.vsh \
diff --git a/drape/drape_global.hpp b/drape/drape_global.hpp
index 8487ad7f8d..4b6899b927 100644
--- a/drape/drape_global.hpp
+++ b/drape/drape_global.hpp
@@ -63,16 +63,18 @@ enum LineJoin
struct FontDecl
{
FontDecl() = default;
- FontDecl(Color const & color, float size, Color const & outlineColor = Color::Transparent())
+ FontDecl(Color const & color, float size, bool isSdf = true, Color const & outlineColor = Color::Transparent())
: m_color(color)
, m_outlineColor(outlineColor)
, m_size(size)
+ , m_isSdf(isSdf)
{
}
Color m_color = Color::Transparent();
Color m_outlineColor = Color::Transparent();
float m_size = 0;
+ bool m_isSdf = true;
};
}
diff --git a/drape/drape_tests/font_texture_tests.cpp b/drape/drape_tests/font_texture_tests.cpp
index 0e29360365..b6b7882fd2 100644
--- a/drape/drape_tests/font_texture_tests.cpp
+++ b/drape/drape_tests/font_texture_tests.cpp
@@ -97,9 +97,9 @@ UNIT_TEST(UploadingGlyphs)
GlyphManager mng(args);
DummyGlyphIndex index(m2::PointU(128, 128), make_ref(&mng));
size_t count = 1; // invalid symbol glyph has mapped internally.
- count += (index.MapResource(GlyphKey(0x58)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x59)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x61)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x58, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x59, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x61, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
while (index.GetPendingNodesCount() < count);
Texture::Params p;
@@ -113,12 +113,12 @@ UNIT_TEST(UploadingGlyphs)
index.UploadResources(make_ref(&tex));
count = 0;
- count += (index.MapResource(GlyphKey(0x68)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x30)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x62)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x65)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x400)) != nullptr) ? 1 : 0;
- count += (index.MapResource(GlyphKey(0x401)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x68, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x30, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x62, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x65, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x400, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
+ count += (index.MapResource(GlyphKey(0x401, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
while (index.GetPendingNodesCount() < count);
EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _)).WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
diff --git a/drape/drape_tests/glyph_mng_tests.cpp b/drape/drape_tests/glyph_mng_tests.cpp
index 326750e25d..3e3e2fbd9c 100644
--- a/drape/drape_tests/glyph_mng_tests.cpp
+++ b/drape/drape_tests/glyph_mng_tests.cpp
@@ -39,7 +39,7 @@ namespace
vector<dp::GlyphManager::Glyph> glyphs;
auto generateGlyph = [this, &glyphs](strings::UniChar c)
{
- dp::GlyphManager::Glyph g = m_mng->GetGlyph(c);
+ dp::GlyphManager::Glyph g = m_mng->GetGlyph(c, dp::GlyphManager::kDynamicGlyphSize);
glyphs.push_back(m_mng->GenerateGlyph(g));
g.m_image.Destroy();
};
diff --git a/drape/font_texture.cpp b/drape/font_texture.cpp
index 65365fc6cb..5e4b59ade8 100644
--- a/drape/font_texture.cpp
+++ b/drape/font_texture.cpp
@@ -157,7 +157,7 @@ GlyphIndex::GlyphIndex(m2::PointU size, ref_ptr<GlyphManager> mng)
, m_generator(new GlyphGenerator(mng, bind(&GlyphIndex::OnGlyphGenerationCompletion, this, _1, _2)))
{
// Cache invalid glyph.
- GlyphKey const key = GlyphKey(m_mng->GetInvalidGlyph().m_code);
+ GlyphKey const key = GlyphKey(m_mng->GetInvalidGlyph(GlyphManager::kDynamicGlyphSize).m_code, GlyphManager::kDynamicGlyphSize);
bool newResource = false;
MapResource(key, newResource);
}
@@ -178,21 +178,21 @@ GlyphIndex::~GlyphIndex()
ref_ptr<Texture::ResourceInfo> GlyphIndex::MapResource(GlyphKey const & key, bool & newResource)
{
newResource = false;
- strings::UniChar uniChar = key.GetUnicodePoint();
- auto it = m_index.find(uniChar);
+ auto it = m_index.find(key);
if (it != m_index.end())
return make_ref(&it->second);
newResource = true;
- GlyphManager::Glyph glyph = m_mng->GetGlyph(uniChar);
+ GlyphManager::Glyph glyph = m_mng->GetGlyph(key.GetUnicodePoint(), key.GetFixedSize());
m2::RectU r;
if (!m_packer.PackGlyph(glyph.m_image.m_width, glyph.m_image.m_height, r))
{
glyph.m_image.Destroy();
- LOG(LWARNING, ("Glyphs packer could not pack a glyph", uniChar));
+ LOG(LWARNING, ("Glyphs packer could not pack a glyph", key.GetUnicodePoint()));
- auto invalidGlyph = m_index.find(m_mng->GetInvalidGlyph().m_code);
+ auto invalidGlyph = m_index.find(GlyphKey(m_mng->GetInvalidGlyph(key.GetFixedSize()).m_code,
+ key.GetFixedSize()));
if (invalidGlyph != m_index.end())
return make_ref(&invalidGlyph->second);
@@ -201,7 +201,7 @@ ref_ptr<Texture::ResourceInfo> GlyphIndex::MapResource(GlyphKey const & key, boo
m_generator->GenerateGlyph(r, glyph);
- auto res = m_index.emplace(uniChar, GlyphInfo(m_packer.MapTextureCoords(r), glyph.m_metrics));
+ auto res = m_index.emplace(key, GlyphInfo(m_packer.MapTextureCoords(r), glyph.m_metrics));
ASSERT(res.second, ());
return make_ref(&res.first->second);
}
@@ -280,12 +280,12 @@ void GlyphIndex::UploadResources(ref_ptr<Texture> texture)
}
}
-uint32_t GlyphIndex::GetAbsentGlyphsCount(strings::UniString const & text) const
+uint32_t GlyphIndex::GetAbsentGlyphsCount(strings::UniString const & text, int fixedHeight) const
{
uint32_t count = 0;
for (strings::UniChar const & c : text)
{
- if (m_index.find(c) == m_index.end())
+ if (m_index.find(GlyphKey(c, fixedHeight)) == m_index.end())
count++;
}
return count;
diff --git a/drape/font_texture.hpp b/drape/font_texture.hpp
index 4b120ccfa9..f70a98e383 100644
--- a/drape/font_texture.hpp
+++ b/drape/font_texture.hpp
@@ -36,13 +36,25 @@ private:
class GlyphKey : public Texture::Key
{
public:
- GlyphKey(strings::UniChar unicodePoint) : m_unicodePoint(unicodePoint) {}
+ GlyphKey(strings::UniChar unicodePoint, int fixedSize)
+ : m_unicodePoint(unicodePoint)
+ , m_fixedSize(fixedSize)
+ {}
Texture::ResourceType GetType() const { return Texture::Glyph; }
strings::UniChar GetUnicodePoint() const { return m_unicodePoint; }
+ int GetFixedSize() const { return m_fixedSize; }
+
+ bool operator<(GlyphKey const & g) const
+ {
+ if (m_unicodePoint == g.m_unicodePoint)
+ return m_fixedSize < g.m_fixedSize;
+ return m_unicodePoint < g.m_unicodePoint;
+ }
private:
strings::UniChar m_unicodePoint;
+ int m_fixedSize;
};
class GlyphInfo : public Texture::ResourceInfo
@@ -113,7 +125,7 @@ public:
bool HasAsyncRoutines() const;
- uint32_t GetAbsentGlyphsCount(strings::UniString const & text) const;
+ uint32_t GetAbsentGlyphsCount(strings::UniString const & text, int fixedHeight) const;
// ONLY for unit-tests. DO NOT use this function anywhere else.
size_t GetPendingNodesCount();
@@ -125,7 +137,7 @@ private:
ref_ptr<GlyphManager> m_mng;
unique_ptr<GlyphGenerator> m_generator;
- typedef map<strings::UniChar, GlyphInfo> TResourceMapping;
+ typedef map<GlyphKey, GlyphInfo> TResourceMapping;
typedef pair<m2::RectU, GlyphManager::Glyph> TPendingNode;
typedef vector<TPendingNode> TPendingNodes;
@@ -162,9 +174,9 @@ public:
return m_index.HasAsyncRoutines();
}
- uint32_t GetAbsentGlyphsCount(strings::UniString const & text) const
+ uint32_t GetAbsentGlyphsCount(strings::UniString const & text, int fixedHeight) const
{
- return m_index.GetAbsentGlyphsCount(text);
+ return m_index.GetAbsentGlyphsCount(text, fixedHeight);
}
private:
diff --git a/drape/glyph_manager.cpp b/drape/glyph_manager.cpp
index 32556a3075..cf5330c1d9 100644
--- a/drape/glyph_manager.cpp
+++ b/drape/glyph_manager.cpp
@@ -66,6 +66,7 @@ namespace
{
uint32_t const kSdfBorder = 4;
+double const kNonSdfBorder = 0.2;
int const kInvalidFont = -1;
template <typename ToDo>
@@ -182,9 +183,11 @@ public:
return FT_Get_Char_Index(m_fontFace, unicodePoint) != 0;
}
- GlyphManager::Glyph GetGlyph(strings::UniChar unicodePoint, uint32_t baseHeight) const
+ GlyphManager::Glyph GetGlyph(strings::UniChar unicodePoint, uint32_t baseHeight, bool isSdf) const
{
- FREETYPE_CHECK(FT_Set_Pixel_Sizes(m_fontFace, m_sdfScale * baseHeight, m_sdfScale * baseHeight));
+ uint32_t glyphHeight = isSdf ? baseHeight * m_sdfScale : baseHeight;
+
+ FREETYPE_CHECK(FT_Set_Pixel_Sizes(m_fontFace, glyphHeight, glyphHeight));
FREETYPE_CHECK(FT_Load_Glyph(m_fontFace, FT_Get_Char_Index(m_fontFace, unicodePoint), FT_LOAD_RENDER));
FT_Glyph glyph;
@@ -195,20 +198,42 @@ public:
FT_Bitmap bitmap = m_fontFace->glyph->bitmap;
- float const scale = 1.0f / m_sdfScale;
+ float const scale = isSdf ? 1.0f / m_sdfScale : 1.0;
SharedBufferManager::shared_buffer_ptr_t data;
int imageWidth = bitmap.width;
int imageHeight = bitmap.rows;
+ int border = 0;
if (bitmap.buffer != nullptr)
{
- sdf_image::SdfImage img(bitmap.rows, bitmap.pitch, bitmap.buffer, m_sdfScale * kSdfBorder);
- imageWidth = img.GetWidth() * scale;
- imageHeight = img.GetHeight() * scale;
+ if (isSdf)
+ {
+ sdf_image::SdfImage img(bitmap.rows, bitmap.pitch, bitmap.buffer, m_sdfScale * kSdfBorder);
+ imageWidth = img.GetWidth() * scale;
+ imageHeight = img.GetHeight() * scale;
- size_t bufferSize = bitmap.rows * bitmap.pitch;
- data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
- memcpy(&(*data)[0], bitmap.buffer, bufferSize);
+ size_t const bufferSize = bitmap.rows * bitmap.pitch;
+ data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
+ memcpy(&(*data)[0], bitmap.buffer, bufferSize);
+ }
+ else
+ {
+ border = glyphHeight * kNonSdfBorder;
+ imageHeight += 2 * border;
+ imageWidth += 2 * border;
+
+ size_t const bufferSize = imageWidth * imageHeight;
+ data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
+ memset(data->data(), 0, data->size());
+
+ for (size_t row = border; row < bitmap.rows + border; ++row)
+ {
+ size_t const dstBaseIndex = row * imageWidth + border;
+ size_t const srcBaseIndex = (row - border) * bitmap.pitch;
+ for (size_t column = 0; column < bitmap.pitch; ++column)
+ data->data()[dstBaseIndex + column] = bitmap.buffer[srcBaseIndex + column];
+ }
+ }
}
GlyphManager::Glyph result;
@@ -222,13 +247,14 @@ public:
result.m_metrics = GlyphManager::GlyphMetrics
{
static_cast<float>(glyph->advance.x >> 16) * scale,
- static_cast<float>(glyph->advance.y >> 16) * scale,
- static_cast<float>(bbox.xMin) * scale,
- static_cast<float>(bbox.yMin) * scale,
+ static_cast<float>(glyph->advance.y >> 16) * scale,
+ static_cast<float>(bbox.xMin) * scale + border,
+ static_cast<float>(bbox.yMin) * scale + border,
true
};
result.m_code = unicodePoint;
+ result.m_fixedSize = isSdf ? GlyphManager::kDynamicGlyphSize : baseHeight;
FT_Done_Glyph(glyph);
@@ -243,23 +269,35 @@ public:
resultGlyph.m_metrics = glyph.m_metrics;
resultGlyph.m_fontIndex = glyph.m_fontIndex;
resultGlyph.m_code = glyph.m_code;
+ resultGlyph.m_fixedSize = glyph.m_fixedSize;
+
+ if (glyph.m_fixedSize < 0)
+ {
+ sdf_image::SdfImage img(glyph.m_image.m_bitmapRows, glyph.m_image.m_bitmapPitch,
+ glyph.m_image.m_data->data(), m_sdfScale * kSdfBorder);
- sdf_image::SdfImage img(glyph.m_image.m_bitmapRows, glyph.m_image.m_bitmapPitch,
- glyph.m_image.m_data->data(), m_sdfScale * kSdfBorder);
+ img.GenerateSDF(1.0f / (float)m_sdfScale);
- img.GenerateSDF(1.0f / (float)m_sdfScale);
+ ASSERT(img.GetWidth() == glyph.m_image.m_width, ());
+ ASSERT(img.GetHeight() == glyph.m_image.m_height, ());
- ASSERT(img.GetWidth() == glyph.m_image.m_width, ());
- ASSERT(img.GetHeight() == glyph.m_image.m_height, ());
+ size_t bufferSize = my::NextPowOf2(glyph.m_image.m_width * glyph.m_image.m_height);
+ resultGlyph.m_image.m_data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
+
+ img.GetData(*resultGlyph.m_image.m_data);
+ }
+ else
+ {
+ size_t bufferSize = my::NextPowOf2(glyph.m_image.m_width * glyph.m_image.m_height);
+ resultGlyph.m_image.m_data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
+ resultGlyph.m_image.m_data->assign(glyph.m_image.m_data->begin(), glyph.m_image.m_data->end());
+ }
- size_t bufferSize = my::NextPowOf2(glyph.m_image.m_width * glyph.m_image.m_height);
resultGlyph.m_image.m_width = glyph.m_image.m_width;
resultGlyph.m_image.m_height = glyph.m_image.m_height;
resultGlyph.m_image.m_bitmapRows = 0;
resultGlyph.m_image.m_bitmapPitch = 0;
- resultGlyph.m_image.m_data = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
- img.GetData(*resultGlyph.m_image.m_data);
return resultGlyph;
}
return glyph;
@@ -289,14 +327,14 @@ public:
static void Close(FT_Stream){}
- void MarkGlyphReady(strings::UniChar code)
+ void MarkGlyphReady(strings::UniChar code, int fixedHeight)
{
- m_readyGlyphs.insert(code);
+ m_readyGlyphs.insert(make_pair(code, fixedHeight));
}
- bool IsGlyphReady(strings::UniChar code) const
+ bool IsGlyphReady(strings::UniChar code, int fixedHeight) const
{
- return m_readyGlyphs.find(code) != m_readyGlyphs.end();
+ return m_readyGlyphs.find(make_pair(code, fixedHeight)) != m_readyGlyphs.end();
}
private:
@@ -305,7 +343,7 @@ private:
FT_Face m_fontFace;
uint32_t m_sdfScale;
- unordered_set<strings::UniChar> m_readyGlyphs;
+ std::set<pair<strings::UniChar, int>> m_readyGlyphs;
};
}
@@ -359,6 +397,8 @@ struct UnicodeBlock
typedef vector<UnicodeBlock> TUniBlocks;
typedef TUniBlocks::const_iterator TUniBlockIter;
+const int GlyphManager::kDynamicGlyphSize = -1;
+
struct GlyphManager::Impl
{
FT_Library m_library;
@@ -561,14 +601,15 @@ int GlyphManager::FindFontIndexInBlock(UnicodeBlock const & block, strings::UniC
return kInvalidFont;
}
-GlyphManager::Glyph GlyphManager::GetGlyph(strings::UniChar unicodePoint)
+GlyphManager::Glyph GlyphManager::GetGlyph(strings::UniChar unicodePoint, int fixedHeight)
{
int const fontIndex = GetFontIndex(unicodePoint);
if (fontIndex == kInvalidFont)
- return GetInvalidGlyph();
+ return GetInvalidGlyph(fixedHeight);
auto const & f = m_impl->m_fonts[fontIndex];
- Glyph glyph = f->GetGlyph(unicodePoint, m_impl->m_baseGlyphHeight);
+ bool const isSdf = fixedHeight < 0;
+ Glyph glyph = f->GetGlyph(unicodePoint, isSdf ? m_impl->m_baseGlyphHeight : fixedHeight, isSdf);
glyph.m_fontIndex = fontIndex;
return glyph;
}
@@ -591,10 +632,10 @@ void GlyphManager::MarkGlyphReady(Glyph const & glyph)
{
ASSERT_GREATER_OR_EQUAL(glyph.m_fontIndex, 0, ());
ASSERT_LESS(glyph.m_fontIndex, m_impl->m_fonts.size(), ());
- m_impl->m_fonts[glyph.m_fontIndex]->MarkGlyphReady(glyph.m_code);
+ m_impl->m_fonts[glyph.m_fontIndex]->MarkGlyphReady(glyph.m_code, glyph.m_fixedSize);
}
-bool GlyphManager::AreGlyphsReady(strings::UniString const & str) const
+bool GlyphManager::AreGlyphsReady(strings::UniString const & str, int fixedSize) const
{
for (auto const & code : str)
{
@@ -602,14 +643,14 @@ bool GlyphManager::AreGlyphsReady(strings::UniString const & str) const
if (fontIndex == kInvalidFont)
continue;
- if (!m_impl->m_fonts[fontIndex]->IsGlyphReady(code))
+ if (!m_impl->m_fonts[fontIndex]->IsGlyphReady(code, fixedSize))
return false;
}
return true;
}
-GlyphManager::Glyph GlyphManager::GetInvalidGlyph() const
+GlyphManager::Glyph GlyphManager::GetInvalidGlyph(int fixedSize) const
{
strings::UniChar const kInvalidGlyphCode = 0x9;
int const kFontId = 0;
@@ -620,7 +661,10 @@ GlyphManager::Glyph GlyphManager::GetInvalidGlyph() const
if (!s_inited)
{
ASSERT(!m_impl->m_fonts.empty(), ());
- s_glyph = m_impl->m_fonts[kFontId]->GetGlyph(kInvalidGlyphCode, m_impl->m_baseGlyphHeight);
+ bool const isSdf = fixedSize < 0 ;
+ s_glyph = m_impl->m_fonts[kFontId]->GetGlyph(kInvalidGlyphCode,
+ isSdf ? m_impl->m_baseGlyphHeight : fixedSize,
+ isSdf);
s_glyph.m_metrics.m_isValid = false;
s_glyph.m_fontIndex = kFontId;
s_glyph.m_code = kInvalidGlyphCode;
diff --git a/drape/glyph_manager.hpp b/drape/glyph_manager.hpp
index 0c28b373dc..259564845a 100644
--- a/drape/glyph_manager.hpp
+++ b/drape/glyph_manager.hpp
@@ -17,6 +17,8 @@ struct UnicodeBlock;
class GlyphManager
{
public:
+ static const int kDynamicGlyphSize;
+
struct Params
{
string m_uniBlocks;
@@ -69,21 +71,22 @@ public:
GlyphImage m_image;
int m_fontIndex;
strings::UniChar m_code;
+ int m_fixedSize;
};
GlyphManager(Params const & params);
~GlyphManager();
- Glyph GetGlyph(strings::UniChar unicodePoints);
+ Glyph GetGlyph(strings::UniChar unicodePoints, int fixedHeight);
Glyph GenerateGlyph(Glyph const & glyph) const;
void MarkGlyphReady(Glyph const & glyph);
- bool AreGlyphsReady(strings::UniString const & str) const;
+ bool AreGlyphsReady(strings::UniString const & str, int fixedSize) const;
typedef function<void (strings::UniChar start, strings::UniChar end)> TUniBlockCallback;
void ForEachUnicodeBlock(TUniBlockCallback const & fn) const;
- Glyph GetInvalidGlyph() const;
+ Glyph GetInvalidGlyph(int fixedSize) const;
uint32_t GetBaseGlyphHeight() const;
diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt
index 2c2e29abce..5fbb2ccab3 100644
--- a/drape/shaders/shader_index.txt
+++ b/drape/shaders/shader_index.txt
@@ -1,5 +1,6 @@
TEXT_OUTLINED_PROGRAM text_outlined_vertex_shader.vsh text_fragment_shader.fsh
TEXT_PROGRAM text_vertex_shader.vsh text_fragment_shader.fsh
+TEXT_FIXED_PROGRAM text_vertex_shader.vsh text_fixed_fragment_shader.fsh
TEXT_OUTLINED_GUI_PROGRAM text_outlined_gui_vertex_shader.vsh text_fragment_shader.fsh
AREA_PROGRAM area_vertex_shader.vsh solid_color_fragment_shader.fsh
AREA_OUTLINE_PROGRAM area_vertex_shader.vsh solid_color_fragment_shader.fsh
@@ -28,6 +29,7 @@ TEXTURING_BILLBOARD_PROGRAM texturing_billboard_vertex_shader.vsh texturing_frag
MASKED_TEXTURING_BILLBOARD_PROGRAM masked_texturing_billboard_vertex_shader.vsh masked_texturing_fragment_shader.fsh
TEXT_OUTLINED_BILLBOARD_PROGRAM text_outlined_billboard_vertex_shader.vsh text_fragment_shader.fsh
TEXT_BILLBOARD_PROGRAM text_billboard_vertex_shader.vsh text_fragment_shader.fsh
+TEXT_FIXED_BILLBOARD_PROGRAM text_billboard_vertex_shader.vsh text_fixed_fragment_shader.fsh
BOOKMARK_BILLBOARD_PROGRAM user_mark_billboard.vsh texturing_fragment_shader.fsh
TRAFFIC_PROGRAM traffic_vertex_shader.vsh traffic_fragment_shader.fsh
TRAFFIC_LINE_PROGRAM traffic_line_vertex_shader.vsh traffic_line_fragment_shader.fsh
diff --git a/drape/shaders/text_fixed_fragment_shader.fsh b/drape/shaders/text_fixed_fragment_shader.fsh
new file mode 100755
index 0000000000..7931b21546
--- /dev/null
+++ b/drape/shaders/text_fixed_fragment_shader.fsh
@@ -0,0 +1,24 @@
+varying vec2 v_maskTexCoord;
+
+#ifdef ENABLE_VTF
+varying lowp vec4 v_color;
+#else
+varying vec2 v_colorTexCoord;
+uniform sampler2D u_colorTex;
+#endif
+
+uniform sampler2D u_maskTex;
+uniform float u_opacity;
+uniform vec2 u_contrastGamma;
+
+void main (void)
+{
+#ifdef ENABLE_VTF
+ lowp vec4 glyphColor = v_color;
+#else
+ lowp vec4 glyphColor = texture2D(u_colorTex, v_colorTexCoord);
+#endif
+ float alpha = texture2D(u_maskTex, v_maskTexCoord).a;
+ glyphColor.a *= u_opacity * alpha;
+ gl_FragColor = glyphColor;
+}
diff --git a/drape/texture_manager.cpp b/drape/texture_manager.cpp
index e1cfb9948f..b9fe9913b4 100644
--- a/drape/texture_manager.cpp
+++ b/drape/texture_manager.cpp
@@ -313,23 +313,23 @@ size_t TextureManager::FindGlyphsGroup(TMultilineText const & text) const
return FindGlyphsGroup(combinedString);
}
-size_t TextureManager::GetNumberOfUnfoundCharacters(strings::UniString const & text, HybridGlyphGroup const & group) const
+size_t TextureManager::GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight, HybridGlyphGroup const & group) const
{
size_t cnt = 0;
for (auto const & c : text)
- if (group.m_glyphs.find(c) == group.m_glyphs.end())
+ if (group.m_glyphs.find(make_pair(c, fixedHeight)) == group.m_glyphs.end())
cnt++;
return cnt;
}
-void TextureManager::MarkCharactersUsage(strings::UniString const & text, HybridGlyphGroup & group)
+void TextureManager::MarkCharactersUsage(strings::UniString const & text, int fixedHeight, HybridGlyphGroup & group)
{
for (auto const & c : text)
- group.m_glyphs.emplace(c);
+ group.m_glyphs.emplace(make_pair(c, fixedHeight));
}
-size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text)
+size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text, int fixedHeight)
{
if (m_hybridGlyphGroups.empty())
{
@@ -352,11 +352,11 @@ size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text)
// looking for a hybrid texture which contains text entirely
for (size_t i = 0; i < m_hybridGlyphGroups.size() - 1; i++)
- if (GetNumberOfUnfoundCharacters(text, m_hybridGlyphGroups[i]) == 0)
+ if (GetNumberOfUnfoundCharacters(text, fixedHeight, m_hybridGlyphGroups[i]) == 0)
return i;
// check if we can contain text in the last hybrid texture
- size_t const unfoundChars = GetNumberOfUnfoundCharacters(text, group);
+ size_t const unfoundChars = GetNumberOfUnfoundCharacters(text, fixedHeight, group);
size_t const newCharsCount = group.m_glyphs.size() + unfoundChars;
if (newCharsCount >= m_maxGlypsCount || !group.m_texture->HasEnoughSpace(unfoundChars))
m_hybridGlyphGroups.push_back(HybridGlyphGroup());
@@ -364,12 +364,12 @@ size_t TextureManager::FindHybridGlyphsGroup(strings::UniString const & text)
return m_hybridGlyphGroups.size() - 1;
}
-size_t TextureManager::FindHybridGlyphsGroup(TMultilineText const & text)
+size_t TextureManager::FindHybridGlyphsGroup(TMultilineText const & text, int fixedHeight)
{
strings::UniString combinedString;
MultilineTextToUniString(text, combinedString);
- return FindHybridGlyphsGroup(combinedString);
+ return FindHybridGlyphsGroup(combinedString, fixedHeight);
}
void TextureManager::Init(Params const & params)
@@ -477,39 +477,39 @@ void TextureManager::GetColorRegion(Color const & color, ColorRegion & region)
GetRegionBase(make_ref(m_colorTexture), region, ColorKey(color));
}
-void TextureManager::GetGlyphRegions(TMultilineText const & text, TMultilineGlyphsBuffer & buffers)
+void TextureManager::GetGlyphRegions(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers)
{
- CalcGlyphRegions<TMultilineText, TMultilineGlyphsBuffer>(text, buffers);
+ CalcGlyphRegions<TMultilineText, TMultilineGlyphsBuffer>(text, fixedHeight, buffers);
}
-void TextureManager::GetGlyphRegions(strings::UniString const & text, TGlyphsBuffer & regions)
+void TextureManager::GetGlyphRegions(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & regions)
{
- CalcGlyphRegions<strings::UniString, TGlyphsBuffer>(text, regions);
+ CalcGlyphRegions<strings::UniString, TGlyphsBuffer>(text, fixedHeight, regions);
}
-uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text)
+uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text, int fixedHeight)
{
if (texture == nullptr)
return 0;
ASSERT(dynamic_cast<FontTexture *>(texture.get()) != nullptr, ());
- return static_cast<FontTexture *>(texture.get())->GetAbsentGlyphsCount(text);
+ return static_cast<FontTexture *>(texture.get())->GetAbsentGlyphsCount(text, fixedHeight);
}
-uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text)
+uint32_t TextureManager::GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text, int fixedHeight)
{
if (texture == nullptr)
return 0;
uint32_t count = 0;
for (size_t i = 0; i < text.size(); ++i)
- count += GetAbsentGlyphsCount(texture, text[i]);
+ count += GetAbsentGlyphsCount(texture, text[i], fixedHeight);
return count;
}
-bool TextureManager::AreGlyphsReady(strings::UniString const & str) const
+bool TextureManager::AreGlyphsReady(strings::UniString const & str, int fixedHeight) const
{
- return m_glyphManager->AreGlyphsReady(str);
+ return m_glyphManager->AreGlyphsReady(str, fixedHeight);
}
ref_ptr<Texture> TextureManager::GetSymbolsTexture() const
diff --git a/drape/texture_manager.hpp b/drape/texture_manager.hpp
index daac7c7fc5..e7308a8aa7 100644
--- a/drape/texture_manager.hpp
+++ b/drape/texture_manager.hpp
@@ -90,8 +90,8 @@ public:
typedef buffer_vector<GlyphRegion, 128> TGlyphsBuffer;
typedef buffer_vector<TGlyphsBuffer, 4> TMultilineGlyphsBuffer;
- void GetGlyphRegions(TMultilineText const & text, TMultilineGlyphsBuffer & buffers);
- void GetGlyphRegions(strings::UniString const & text, TGlyphsBuffer & regions);
+ void GetGlyphRegions(TMultilineText const & text, int fixedHeight, TMultilineGlyphsBuffer & buffers);
+ void GetGlyphRegions(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & regions);
/// 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
@@ -99,7 +99,7 @@ public:
bool UpdateDynamicTextures();
/// This method must be called only on Frontend renderer's thread.
- bool AreGlyphsReady(strings::UniString const & str) const;
+ bool AreGlyphsReady(strings::UniString const & str, int fixedHeight) const;
ref_ptr<Texture> GetSymbolsTexture() const;
ref_ptr<Texture> GetTrafficArrowTexture() const;
@@ -126,7 +126,7 @@ private:
: m_texture(nullptr)
{}
- unordered_set<strings::UniChar> m_glyphs;
+ std::set<pair<strings::UniChar, int> > m_glyphs;
ref_ptr<Texture> m_texture;
};
@@ -140,17 +140,17 @@ private:
size_t FindGlyphsGroup(strings::UniString const & text) const;
size_t FindGlyphsGroup(TMultilineText const & text) const;
- size_t FindHybridGlyphsGroup(strings::UniString const & text);
- size_t FindHybridGlyphsGroup(TMultilineText const & text);
+ size_t FindHybridGlyphsGroup(strings::UniString const & text, int fixedHeight);
+ size_t FindHybridGlyphsGroup(TMultilineText const & text, int fixedHeight);
- size_t GetNumberOfUnfoundCharacters(strings::UniString const & text, HybridGlyphGroup const & group) const;
+ size_t GetNumberOfUnfoundCharacters(strings::UniString const & text, int fixedHeight, HybridGlyphGroup const & group) const;
- void MarkCharactersUsage(strings::UniString const & text, HybridGlyphGroup & group);
+ void MarkCharactersUsage(strings::UniString const & text, int fixedHeight, HybridGlyphGroup & group);
/// it's a dummy method to support generic code
- void MarkCharactersUsage(strings::UniString const &, GlyphGroup &) {}
+ void MarkCharactersUsage(strings::UniString const & text, int fixedHeight, GlyphGroup & group) {}
template<typename TGlyphGroup>
- void FillResultBuffer(strings::UniString const & text, 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();
@@ -159,41 +159,41 @@ private:
for (strings::UniChar const & c : text)
{
GlyphRegion reg;
- GetRegionBase(group.m_texture, reg, GlyphKey(c));
+ GetRegionBase(group.m_texture, reg, GlyphKey(c, fixedHeight));
regions.push_back(reg);
}
}
template<typename TGlyphGroup>
- void FillResults(strings::UniString const & text, TGlyphsBuffer & buffers, TGlyphGroup & group)
+ void FillResults(strings::UniString const & text, int fixedHeight, TGlyphsBuffer & buffers, TGlyphGroup & group)
{
- MarkCharactersUsage(text, group);
- FillResultBuffer<TGlyphGroup>(text, group, buffers);
+ MarkCharactersUsage(text, fixedHeight, group);
+ FillResultBuffer<TGlyphGroup>(text, fixedHeight, group, buffers);
}
template<typename TGlyphGroup>
- void FillResults(TMultilineText const & text, 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)
{
strings::UniString const & str = text[i];
TGlyphsBuffer & buffer = buffers[i];
- FillResults<TGlyphGroup>(str, buffer, group);
+ FillResults<TGlyphGroup>(str, fixedHeight, buffer, group);
}
}
template<typename TText, typename TBuffer>
- void CalcGlyphRegions(TText const & text, TBuffer & buffers)
+ void CalcGlyphRegions(TText const & text, int fixedHeight, TBuffer & buffers)
{
size_t const groupIndex = FindGlyphsGroup(text);
bool useHybridGroup = false;
- if (groupIndex != GetInvalidGlyphGroup())
+ if (fixedHeight < 0 && groupIndex != GetInvalidGlyphGroup())
{
GlyphGroup & group = m_glyphGroups[groupIndex];
- uint32_t const absentGlyphs = GetAbsentGlyphsCount(group.m_texture, text);
+ uint32_t const absentGlyphs = GetAbsentGlyphsCount(group.m_texture, text, fixedHeight);
if (group.m_texture == nullptr || group.m_texture->HasEnoughSpace(absentGlyphs))
- FillResults<GlyphGroup>(text, buffers, group);
+ FillResults<GlyphGroup>(text, fixedHeight, buffers, group);
else
useHybridGroup = true;
}
@@ -204,15 +204,15 @@ private:
if (useHybridGroup)
{
- size_t const hybridGroupIndex = FindHybridGlyphsGroup(text);
+ size_t const hybridGroupIndex = FindHybridGlyphsGroup(text, fixedHeight);
ASSERT(hybridGroupIndex != GetInvalidGlyphGroup(), ());
HybridGlyphGroup & group = m_hybridGlyphGroups[hybridGroupIndex];
- FillResults<HybridGlyphGroup>(text, buffers, group);
+ FillResults<HybridGlyphGroup>(text, fixedHeight, buffers, group);
}
}
- uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, strings::UniString const & text);
- uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text);
+ 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);
template<typename TGlyphGroups>
void UpdateGlyphTextures(TGlyphGroups & groups)
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp
index e5c00fdcf2..19ca1d5cb3 100644
--- a/drape_frontend/apply_feature_functors.cpp
+++ b/drape_frontend/apply_feature_functors.cpp
@@ -154,11 +154,14 @@ void Extract(::LineDefProto const * lineRule, df::LineViewParams & params)
void CaptionDefProtoToFontDecl(CaptionDefProto const * capRule, dp::FontDecl &params)
{
+ double const vs = df::VisualParams::Instance().GetVisualScale();
params.m_color = ToDrapeColor(capRule->color());
- params.m_size = max(kMinVisibleFontSize, capRule->height() * df::VisualParams::Instance().GetVisualScale());
+ params.m_size = max(kMinVisibleFontSize, capRule->height() * vs);
if (capRule->has_stroke_color())
params.m_outlineColor = ToDrapeColor(capRule->stroke_color());
+ else if (vs < df::VisualParams::kHdpiScale)
+ params.m_isSdf = false;
}
void ShieldRuleProtoToFontDecl(ShieldRuleProto const * shieldRule, dp::FontDecl &params)
@@ -185,7 +188,6 @@ dp::Anchor GetAnchor(CaptionDefProto const * capRule)
return dp::Right;
else
return dp::Left;
-
}
return dp::Center;
diff --git a/drape_frontend/gui/gui_text.cpp b/drape_frontend/gui/gui_text.cpp
index e92b01c2f5..d8fbcc799c 100644
--- a/drape_frontend/gui/gui_text.cpp
+++ b/drape_frontend/gui/gui_text.cpp
@@ -127,7 +127,7 @@ void StaticLabel::CacheStaticText(string const & text, char const * delim,
result.m_alphabet.insert(str.begin(), str.end());
dp::TextureManager::TMultilineGlyphsBuffer buffers;
- mng->GetGlyphRegions(textParts, buffers);
+ mng->GetGlyphRegions(textParts, dp::GlyphManager::kDynamicGlyphSize, buffers);
#ifdef DEBUG
ASSERT_EQUAL(textParts.size(), buffers.size(), ());
@@ -301,7 +301,7 @@ ref_ptr<dp::Texture> MutableLabel::SetAlphabet(string const & alphabet, ref_ptr<
str.resize(distance(str.begin(), it));
dp::TextureManager::TGlyphsBuffer buffer;
- mng->GetGlyphRegions(str, buffer);
+ mng->GetGlyphRegions(str, dp::GlyphManager::kDynamicGlyphSize, buffer);
m_alphabet.reserve(buffer.size());
ASSERT_EQUAL(str.size(), buffer.size(), ());
@@ -489,7 +489,7 @@ bool MutableLabelHandle::Update(ScreenBase const & screen)
for (auto const & node : m_textView->GetAlphabet())
alphabetStr.push_back(node.first);
- m_glyphsReady = m_textureManager->AreGlyphsReady(alphabetStr);
+ m_glyphsReady = m_textureManager->AreGlyphsReady(alphabetStr, dp::GlyphManager::kDynamicGlyphSize);
}
if (!m_glyphsReady)
@@ -581,7 +581,7 @@ StaticLabelHandle::StaticLabelHandle(uint32_t id, ref_ptr<dp::TextureManager> te
bool StaticLabelHandle::Update(ScreenBase const & screen)
{
if (!m_glyphsReady)
- m_glyphsReady = m_textureManager->AreGlyphsReady(m_alphabet);
+ m_glyphsReady = m_textureManager->AreGlyphsReady(m_alphabet, dp::GlyphManager::kDynamicGlyphSize);
if (!m_glyphsReady)
return false;
diff --git a/drape_frontend/path_text_shape.cpp b/drape_frontend/path_text_shape.cpp
index bf357e00cc..9f3c4c31d1 100644
--- a/drape_frontend/path_text_shape.cpp
+++ b/drape_frontend/path_text_shape.cpp
@@ -33,10 +33,10 @@ public:
df::SharedTextLayout const & layout,
float mercatorOffset, float depth,
uint32_t textIndex, uint64_t priority,
- uint64_t priorityFollowingMode,
+ uint64_t priorityFollowingMode, int fixedHeight,
ref_ptr<dp::TextureManager> textureManager,
bool isBillboard)
- : TextHandle(id, layout->GetText(), dp::Center, priority, textureManager, isBillboard)
+ : TextHandle(id, layout->GetText(), dp::Center, priority, fixedHeight, textureManager, isBillboard)
, m_spline(spl)
, m_layout(layout)
, m_textIndex(textIndex)
@@ -250,8 +250,8 @@ void PathTextShape::DrawPathTextPlain(ref_ptr<dp::TextureManager> textures,
dp::TextureManager::ColorRegion color;
textures->GetColorRegion(m_params.m_textFont.m_color, color);
- dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::OverlayLayer);
- state.SetProgram3dIndex(gpu::TEXT_BILLBOARD_PROGRAM);
+ 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);
state.SetColorTexture(color.GetTexture());
state.SetMaskTexture(layout->GetMaskTexture());
@@ -276,6 +276,7 @@ void PathTextShape::DrawPathTextPlain(ref_ptr<dp::TextureManager> textures,
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);
}
@@ -317,6 +318,7 @@ void PathTextShape::DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures,
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);
}
@@ -325,7 +327,7 @@ void PathTextShape::DrawPathTextOutlined(ref_ptr<dp::TextureManager> textures,
void PathTextShape::Draw(ref_ptr<dp::Batcher> batcher, 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, textures);
+ m_params.m_textFont.m_size, m_params.m_textFont.m_isSdf, textures);
uint32_t glyphCount = layout->GetGlyphCount();
if (glyphCount == 0)
diff --git a/drape_frontend/text_handle.cpp b/drape_frontend/text_handle.cpp
index f256158f7f..213f164b1a 100644
--- a/drape_frontend/text_handle.cpp
+++ b/drape_frontend/text_handle.cpp
@@ -8,7 +8,7 @@ namespace df
{
TextHandle::TextHandle(FeatureID const & id, strings::UniString const & text,
- dp::Anchor anchor, uint64_t priority,
+ dp::Anchor anchor, uint64_t priority, int fixedHeight,
ref_ptr<dp::TextureManager> textureManager,
bool isBillboard)
: OverlayHandle(id, anchor, priority, isBillboard)
@@ -17,10 +17,11 @@ TextHandle::TextHandle(FeatureID const & id, strings::UniString const & text,
, m_text(text)
, m_textureManager(textureManager)
, m_glyphsReady(false)
+ , m_fixedHeight(fixedHeight)
{}
TextHandle::TextHandle(FeatureID const & id, strings::UniString const & text,
- dp::Anchor anchor, uint64_t priority,
+ dp::Anchor anchor, uint64_t priority, int fixedHeight,
ref_ptr<dp::TextureManager> textureManager,
gpu::TTextDynamicVertexBuffer && normals,
bool isBillboard)
@@ -31,6 +32,7 @@ TextHandle::TextHandle(FeatureID const & id, strings::UniString const & text,
, m_text(text)
, m_textureManager(textureManager)
, m_glyphsReady(false)
+ , m_fixedHeight(fixedHeight)
{}
void TextHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const
@@ -61,7 +63,7 @@ void TextHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutato
bool TextHandle::Update(ScreenBase const & screen)
{
if (!m_glyphsReady)
- m_glyphsReady = m_textureManager->AreGlyphsReady(m_text);
+ m_glyphsReady = m_textureManager->AreGlyphsReady(m_text, m_fixedHeight);
return m_glyphsReady;
}
diff --git a/drape_frontend/text_handle.hpp b/drape_frontend/text_handle.hpp
index 4ec3e993c5..848d70193a 100644
--- a/drape_frontend/text_handle.hpp
+++ b/drape_frontend/text_handle.hpp
@@ -18,12 +18,12 @@ class TextHandle : public dp::OverlayHandle
{
public:
TextHandle(FeatureID const & id, strings::UniString const & text,
- dp::Anchor anchor, uint64_t priority,
+ dp::Anchor anchor, uint64_t priority, int fixedHeight,
ref_ptr<dp::TextureManager> textureManager,
bool isBillboard = false);
TextHandle(FeatureID const & id, strings::UniString const & text,
- dp::Anchor anchor, uint64_t priority,
+ dp::Anchor anchor, uint64_t priority, int fixedHeight,
ref_ptr<dp::TextureManager> textureManager,
gpu::TTextDynamicVertexBuffer && normals,
bool IsBillboard = false);
@@ -50,6 +50,7 @@ private:
strings::UniString m_text;
ref_ptr<dp::TextureManager> m_textureManager;
bool m_glyphsReady;
+ int m_fixedHeight;
};
diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp
index c433d76d13..aeb8adb2b1 100644
--- a/drape_frontend/text_layout.cpp
+++ b/drape_frontend/text_layout.cpp
@@ -341,12 +341,14 @@ void CalculateOffsets(dp::Anchor anchor,
} // namespace
-void TextLayout::Init(strings::UniString const & text, float fontSize,
+void TextLayout::Init(strings::UniString const & text, float fontSize, bool isSdf,
ref_ptr<dp::TextureManager> textures)
{
m_text = text;
- m_textSizeRatio = fontSize * VisualParams::Instance().GetFontScale() / VisualParams::Instance().GetGlyphBaseSize();
- textures->GetGlyphRegions(text, m_metrics);
+ m_textSizeRatio = isSdf ? (fontSize / VisualParams::Instance().GetGlyphBaseSize()) : 1.0;
+ m_textSizeRatio *= VisualParams::Instance().GetFontScale();
+ m_fixedHeight = isSdf ? dp::GlyphManager::kDynamicGlyphSize : fontSize;
+ textures->GetGlyphRegions(text, m_fixedHeight, m_metrics);
}
ref_ptr<dp::Texture> TextLayout::GetMaskTexture() const
@@ -378,7 +380,7 @@ float TextLayout::GetPixelLength() const
float TextLayout::GetPixelHeight() const
{
- return m_textSizeRatio * VisualParams::Instance().GetGlyphBaseSize();
+ return m_fixedHeight > 0 ? m_fixedHeight : m_textSizeRatio * VisualParams::Instance().GetGlyphBaseSize();
}
strings::UniString const & TextLayout::GetText() const
@@ -386,7 +388,7 @@ strings::UniString const & TextLayout::GetText() const
return m_text;
}
-StraightTextLayout::StraightTextLayout(strings::UniString const & text, float fontSize,
+StraightTextLayout::StraightTextLayout(strings::UniString const & text, float fontSize, bool isSdf,
ref_ptr<dp::TextureManager> textures, dp::Anchor anchor)
{
strings::UniString visibleText = fribidi::log2vis(text);
@@ -396,7 +398,7 @@ StraightTextLayout::StraightTextLayout(strings::UniString const & text, float fo
else
delimIndexes.push_back(visibleText.size());
- TBase::Init(visibleText, fontSize, textures);
+ TBase::Init(visibleText, fontSize, isSdf, textures);
CalculateOffsets(anchor, m_textSizeRatio, m_metrics, delimIndexes, m_offsets, m_pixelSize);
}
@@ -438,10 +440,10 @@ void StraightTextLayout::Cache(glm::vec4 const & pivot, glm::vec2 const & pixelO
}
PathTextLayout::PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text,
- float fontSize, ref_ptr<dp::TextureManager> textures)
+ float fontSize, bool isSdf, ref_ptr<dp::TextureManager> textures)
: m_tileCenter(tileCenter)
{
- Init(fribidi::log2vis(text), fontSize, textures);
+ Init(fribidi::log2vis(text), fontSize, isSdf, textures);
}
void PathTextLayout::CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion,
diff --git a/drape_frontend/text_layout.hpp b/drape_frontend/text_layout.hpp
index 9b11365ba2..4d6ec971de 100644
--- a/drape_frontend/text_layout.hpp
+++ b/drape_frontend/text_layout.hpp
@@ -38,12 +38,12 @@ public:
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,
- ref_ptr<dp::TextureManager> textures);
+ void Init(strings::UniString const & text, float fontSize, bool isSdf, ref_ptr<dp::TextureManager> textures);
protected:
typedef dp::TextureManager::GlyphRegion GlyphRegion;
@@ -51,6 +51,7 @@ protected:
dp::TextureManager::TGlyphsBuffer m_metrics;
strings::UniString m_text;
float m_textSizeRatio = 0.0f;
+ int m_fixedHeight = dp::GlyphManager::kDynamicGlyphSize;
};
class StraightTextLayout : public TextLayout
@@ -58,7 +59,7 @@ class StraightTextLayout : public TextLayout
using TBase = TextLayout;
public:
StraightTextLayout(strings::UniString const & text,
- float fontSize,
+ float fontSize, bool isSdf,
ref_ptr<dp::TextureManager> textures,
dp::Anchor anchor);
@@ -85,7 +86,7 @@ class PathTextLayout : public TextLayout
using TBase = TextLayout;
public:
PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text,
- float fontSize, ref_ptr<dp::TextureManager> textures);
+ float fontSize, bool isSdf, ref_ptr<dp::TextureManager> textures);
void CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion,
dp::TextureManager::ColorRegion const & outlineRegion,
diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp
index 1147282e66..09687ff787 100644
--- a/drape_frontend/text_shape.cpp
+++ b/drape_frontend/text_shape.cpp
@@ -28,10 +28,11 @@ public:
StraightTextHandle(FeatureID const & id, strings::UniString const & text,
dp::Anchor anchor, glsl::vec2 const & pivot,
glsl::vec2 const & pxSize, glsl::vec2 const & offset,
- uint64_t priority, ref_ptr<dp::TextureManager> textureManager,
+ uint64_t priority, int fixedHeight,
+ ref_ptr<dp::TextureManager> textureManager,
bool isOptional, bool affectedByZoomPriority,
gpu::TTextDynamicVertexBuffer && normals, bool isBillboard = false)
- : TextHandle(id, text, anchor, priority, textureManager, move(normals), isBillboard)
+ : TextHandle(id, text, anchor, priority, fixedHeight, textureManager, move(normals), isBillboard)
, m_pivot(glsl::ToPoint(pivot))
, m_offset(glsl::ToPoint(offset))
, m_size(glsl::ToPoint(pxSize))
@@ -138,13 +139,15 @@ void TextShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t
{
ASSERT(!m_params.m_primaryText.empty(), ());
StraightTextLayout primaryLayout(strings::MakeUniString(m_params.m_primaryText),
- m_params.m_primaryTextFont.m_size, textures, m_params.m_anchor);
+ m_params.m_primaryTextFont.m_size, m_params.m_primaryTextFont.m_isSdf,
+ textures, m_params.m_anchor);
glsl::vec2 primaryOffset = glsl::ToVec2(m_params.m_primaryOffset);
if (!m_params.m_secondaryText.empty())
{
StraightTextLayout secondaryLayout(strings::MakeUniString(m_params.m_secondaryText),
- m_params.m_secondaryTextFont.m_size, textures, m_params.m_anchor);
+ m_params.m_secondaryTextFont.m_size, m_params.m_secondaryTextFont.m_isSdf,
+ textures, m_params.m_anchor);
glsl::vec2 secondaryOffset = primaryOffset;
@@ -201,8 +204,9 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe
layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ),
baseOffset, color, staticBuffer, dynamicBuffer);
- dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::OverlayLayer);
- state.SetProgram3dIndex(gpu::TEXT_BILLBOARD_PROGRAM);
+ 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);
+
ASSERT(color.GetTexture() == outline.GetTexture(), ());
state.SetColorTexture(color.GetTexture());
state.SetMaskTexture(layout.GetMaskTexture());
@@ -218,6 +222,7 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe
glsl::vec2(pixelSize.x, pixelSize.y),
baseOffset,
GetOverlayPriority(),
+ layout.GetFixedHeight(),
textures,
isOptional,
m_affectedByZoomPriority,
@@ -266,6 +271,7 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon
glsl::vec2(pixelSize.x, pixelSize.y),
baseOffset,
GetOverlayPriority(),
+ layout.GetFixedHeight(),
textures,
isOptional,
m_affectedByZoomPriority,
diff --git a/drape_head/testing_engine.cpp b/drape_head/testing_engine.cpp
index 3b9eb8c7e0..0ff65a8cc7 100644
--- a/drape_head/testing_engine.cpp
+++ b/drape_head/testing_engine.cpp
@@ -457,7 +457,7 @@ void TestingEngine::DrawImpl()
ptvp.m_minVisibleScale = 1;
ptvp.m_rank = 0;
ptvp.m_text = "Some text";
- ptvp.m_textFont = dp::FontDecl(dp::Color::Black(), 40, dp::Color::Red());
+ ptvp.m_textFont = dp::FontDecl(dp::Color::Black(), 40, true, dp::Color::Red());
PathTextShape(spline, ptvp).Draw(make_ref(m_batcher), make_ref(m_textures));
LineViewParams lvp;