MCPcopy Create free account
hub / github.com/comaps/comaps / SplitText

Function SplitText

libs/drape_frontend/text_layout.cpp:138–195  ·  view source on GitHub ↗

Scan longer shaped glyphs, and try to split them into two strings if a space glyph is present. NOTE: Works only for LTR texts. Implementation should be mirrored for RTL.

Source from the content-addressed store, hash-verified

136// Scan longer shaped glyphs, and try to split them into two strings if a space glyph is present.
137// NOTE: Works only for LTR texts. Implementation should be mirrored for RTL.
138buffer_vector<LineMetrics, 2> SplitText(bool forceNoWrap, float textScale, dp::GlyphFontAndId space,
139 dp::text::TextMetrics const & str)
140{
141 // Add the whole line by default.
142 buffer_vector<LineMetrics, 2> lines{
143 {str.m_glyphs.size(), textScale * str.m_lineWidthInPixels, textScale * str.m_maxLineHeightInPixels}};
144
145 size_t const count = str.m_glyphs.size();
146 if (forceNoWrap || count <= 15)
147 return lines;
148
149 auto const begin = str.m_glyphs.begin();
150 auto const end = str.m_glyphs.end();
151
152 // Naive split on two parts using spaces as delimiters.
153 // Doesn't take into an account the width of glyphs/string.
154 auto const iMiddle = begin + count / 2;
155
156 auto const isSpaceGlyph = [space](auto const & metrics) { return metrics.m_key == space; };
157 // Find next delimiter after middle [m, e)
158 auto iNext = std::find_if(iMiddle, end, isSpaceGlyph);
159
160 // Find last delimiter before middle [b, m)
161 auto iPrev = std::find_if(std::reverse_iterator(iMiddle), std::reverse_iterator(begin), isSpaceGlyph).base();
162 // Don't split like this:
163 // xxxx
164 // xxxxxxxxxxxx
165 if (4 * (iPrev - begin) <= static_cast<long>(count))
166 iPrev = end;
167 else
168 --iPrev;
169
170 // Get the closest space to the middle.
171 if (iNext == end || (iPrev != end && iMiddle - iPrev < iNext - iMiddle))
172 iNext = iPrev;
173
174 if (iNext == end)
175 return lines;
176
177 // Split string (actually, glyphs) into 2 parts.
178 ASSERT(iNext != begin, ());
179 ASSERT(space == iNext->m_key, ());
180
181 auto const spaceIndex = iNext;
182 auto const afterSpace = iNext + 1;
183 ASSERT(afterSpace != end, ());
184
185 lines.push_back(LineMetrics{
186 count,
187 textScale * std::accumulate(afterSpace, end, 0, [](auto acc, auto const & m) { return m.m_xAdvance + acc; }),
188 textScale * str.m_maxLineHeightInPixels});
189
190 // Update the first line too.
191 lines[0].m_nextLineStartIndex = afterSpace - begin;
192 auto const spaceWidth = textScale * spaceIndex->m_xAdvance;
193 lines[0].m_scaledLength -= lines[1].m_scaledLength + spaceWidth;
194 return lines;
195}

Callers 1

StraightTextLayoutMethod · 0.85

Calls 5

ASSERTFunction · 0.85
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected