-
-
Notifications
You must be signed in to change notification settings - Fork 870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[drape] Integrate Harfbuzz text shaping #8473
base: master
Are you sure you want to change the base?
Conversation
b1b21dd
to
e80bcb9
Compare
delimIndexes.push_back(visibleText.size()); | ||
// if (visibleText == text && !forceNoWrap) | ||
// SplitText(visibleText, delimIndexes); | ||
// else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the problem with keeping an existing SplitText logic? How does it break HB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not break, just a bit more complex computation. I will implement it.
@vng can you please review newly added commits?
ff02cb7
to
142d093
Compare
Some statistics about the length and count of rendered strings in displayed data after zooming in/out in China and Switzerland (longer strings are NOT split into two):
Conclusion: using buffer_vector with size 50 should cover most of the cases. |
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
…he first match fails Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Rendering without a cache is several times slower than without Harfbuzz. Experiments showed that the hit rate for the same rendered strings is very high. Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
Signed-off-by: Alexander Borsuk <[email protected]>
#ifdef DEBUG | ||
static int const fontSize = fontPixelHeight; | ||
ASSERT_EQUAL(fontSize, fontPixelHeight, | ||
("Cache relies on the same font height/metrics for each glyph", fontSize, fontPixelHeight)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't get here. If fontPixelHeight should be always the same, why not set it once into GlyphManager and don't pass into ShapeText?
But is it true that font height should always be the same during the app's lifetime?
{ | ||
LOG(LINFO, ("Clearing text metrics cache")); | ||
// TODO(AB): Is there a better way? E.g. clear a half of the cache? | ||
m_impl->m_textMetricsCache.clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LRU cache.
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, hbLanguage); | ||
|
||
auto u32CharacterIter{text.begin() + substring.m_start}; | ||
auto const end{text.begin() + substring.m_start + substring.m_length}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really like this {} notation instead of a natural language wise assignment?
auto const end = u32CharacterIter + substring.m_length;
@@ -34,7 +35,12 @@ struct TextMetrics | |||
|
|||
void AddGlyphMetrics(int16_t font, uint16_t glyphId, int32_t xOffset, int32_t yOffset, int32_t xAdvance, int32_t height) | |||
{ | |||
m_glyphs.push_back({font, glyphId, xOffset, yOffset, xAdvance}); | |||
m_glyphs.push_back({{font, glyphId}, xOffset, yOffset, xAdvance}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: emplace_back(GlyphFontAndId(font, glyphId), xOffset, yOffset, xAdvance)
LOG(LWARNING, ("No font was found for character", NumToHex(u32Character))); | ||
else | ||
{ | ||
// TODO(AB): Mapping font only by the first character in a string may fail in theory in some cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, why TODO then? :)
@@ -26,7 +25,7 @@ class TextGeometryGenerator | |||
|
|||
void SetPenPosition(glsl::vec2 const & penOffset) {} | |||
|
|||
void operator() (dp::TextureManager::GlyphRegion const & glyph) | |||
void operator() (dp::TextureManager::GlyphRegion const & glyph, dp::text::GlyphMetrics const & metrics) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dp::text::GlyphMetrics const &
because unused?
@@ -107,7 +107,7 @@ class TextOutlinedGeometryGenerator | |||
|
|||
void SetPenPosition(glsl::vec2 const & penOffset) {} | |||
|
|||
void operator() (dp::TextureManager::GlyphRegion const & glyph) | |||
void operator() (dp::TextureManager::GlyphRegion const & glyph, dp::text::GlyphMetrics const & metrics) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dp::text::GlyphMetrics const &
because unused?
|
||
//using TGlyph = std::pair<int16_t /* fontIndex */, uint16_t /* glyphId */>; | ||
// TODO(AB): Measure if 32 is the best value here. | ||
using TGlyphs = buffer_vector<GlyphFontAndId, 32>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that GetGlyphs functions return by value -> so using move ctor -> the longer in-place buffer -> stranger moving :)
- Use regular vector, especially with reserve
or - Use GetGlyphs(TGlyphs & res) notation.
Fixes #4281
Fixes #516
Fixes #1723
What should be done:
There are many TODOs in the code which can be optimized later. Proper profiling and caching may increase the rendering speed.