MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / Shape

Method Shape

src/gfx_layout_icu.cpp:150–211  ·  view source on GitHub ↗

* Shape a single run. * * @param buff The buffer of which a partial (depending on start/length of the run) will be shaped. * @param length The length of the buffer. */

Source from the content-addressed store, hash-verified

148 * @param length The length of the buffer.
149 */
150void ICURun::Shape(UChar *buff, size_t buff_length)
151{
152 auto hbfont = hb_ft_font_create_referenced(*(static_cast<const FT_Face *>(font->fc->GetOSHandle())));
153 /* Match the flags with how we render the glyphs. */
154 hb_ft_font_set_load_flags(hbfont, GetFontAAState() ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO);
155
156 /* ICU buffer is in UTF-16. */
157 auto hbbuf = hb_buffer_create();
158 hb_buffer_add_utf16(hbbuf, reinterpret_cast<uint16_t *>(buff), buff_length, this->start, this->length);
159
160 /* Set all the properties of this segment. */
161 hb_buffer_set_direction(hbbuf, (this->level & 1) == 1 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
162 hb_buffer_set_script(hbbuf, hb_script_from_string(uscript_getShortName(this->script), -1));
163 hb_buffer_set_language(hbbuf, hb_language_from_string(_current_language->isocode, -1));
164 hb_buffer_set_cluster_level(hbbuf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES);
165
166 /* Shape the segment. */
167 hb_shape(hbfont, hbbuf, nullptr, 0);
168
169 unsigned int glyph_count;
170 auto glyph_info = hb_buffer_get_glyph_infos(hbbuf, &glyph_count);
171 auto glyph_pos = hb_buffer_get_glyph_positions(hbbuf, &glyph_count);
172
173 /* Make sure any former run is lost. */
174 this->glyphs.clear();
175 this->glyph_to_char.clear();
176 this->positions.clear();
177 this->advance.clear();
178
179 /* Reserve space, as we already know the size. */
180 this->glyphs.reserve(glyph_count);
181 this->glyph_to_char.reserve(glyph_count);
182 this->positions.reserve(glyph_count);
183 this->advance.reserve(glyph_count);
184
185 /* Prepare the glyphs/position. ICUVisualRun will give the position an offset if needed. */
186 hb_position_t advance = 0;
187 for (unsigned int i = 0; i < glyph_count; i++) {
188 int x_advance;
189
190 if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
191 auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
192 x_advance = this->font->fc->GetGlyphWidth(glyph);
193 this->glyphs.push_back(glyph);
194 this->positions.emplace_back(advance, advance + x_advance - 1, (this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
195 } else {
196 x_advance = glyph_pos[i].x_advance / FONT_SCALE;
197 this->glyphs.push_back(glyph_info[i].codepoint);
198 this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].x_offset / FONT_SCALE + advance + x_advance - 1, glyph_pos[i].y_offset / FONT_SCALE);
199 }
200
201 this->glyph_to_char.push_back(glyph_info[i].cluster);
202 this->advance.push_back(x_advance);
203 advance += x_advance;
204 }
205
206 /* Track the total advancement we made. */
207 this->total_advance = advance;

Callers 2

GetParagraphLayoutMethod · 0.80
NextLineMethod · 0.80

Calls 10

GetFontAAStateFunction · 0.85
ScaleSpriteTradFunction · 0.85
reserveMethod · 0.80
push_backMethod · 0.80
GetOSHandleMethod · 0.45
clearMethod · 0.45
MapCharToGlyphMethod · 0.45
GetGlyphWidthMethod · 0.45
GetHeightMethod · 0.45
GetSizeMethod · 0.45

Tested by

no test coverage detected