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

Method NextLine

src/os/windows/string_uniscribe.cpp:319–442  ·  view source on GitHub ↗

virtual */

Source from the content-addressed store, hash-verified

317}
318
319/* virtual */ std::unique_ptr<const ParagraphLayouter::Line> UniscribeParagraphLayout::NextLine(int max_width)
320{
321 std::vector<UniscribeRun>::iterator start_run = this->cur_range;
322 std::vector<UniscribeRun>::iterator last_run = this->cur_range;
323
324 if (start_run == this->ranges.end()) return nullptr;
325
326 /* Add remaining width of the first run if it is a broken run. */
327 int cur_width = 0;
328 if (this->cur_range_offset != 0) {
329 std::vector<int> dx(start_run->len);
330 ScriptGetLogicalWidths(&start_run->sa, start_run->len, (int)start_run->glyphs.size(), &start_run->advances[0], &start_run->char_to_glyph[0], &start_run->vis_attribs[0], &dx[0]);
331
332 for (std::vector<int>::const_iterator c = dx.begin() + this->cur_range_offset; c != dx.end(); c++) {
333 cur_width += *c;
334 }
335 ++last_run;
336 }
337
338 /* Gather runs until the line is full. */
339 while (last_run != this->ranges.end() && cur_width <= max_width) {
340 cur_width += last_run->total_advance;
341 ++last_run;
342 }
343
344 /* If the text does not fit into the available width, find a suitable breaking point. */
345 int remaining_offset = (last_run - 1)->len + 1;
346 int whitespace_count = 0;
347 if (cur_width > max_width) {
348 std::vector<SCRIPT_LOGATTR> log_attribs;
349
350 /* Get word break information. */
351 int width_avail = max_width;
352 int num_chars = this->cur_range_offset;
353 int start_offs = this->cur_range_offset;
354 int last_cluster = this->cur_range_offset + 1;
355 for (std::vector<UniscribeRun>::iterator r = start_run; r != last_run; r++) {
356 log_attribs.resize(r->pos - start_run->pos + r->len);
357 if (FAILED(ScriptBreak(this->text_buffer + r->pos + start_offs, r->len - start_offs, &r->sa, &log_attribs[r->pos - start_run->pos + start_offs]))) return nullptr;
358
359 std::vector<int> dx(r->len);
360 ScriptGetLogicalWidths(&r->sa, r->len, (int)r->glyphs.size(), &r->advances[0], &r->char_to_glyph[0], &r->vis_attribs[0], &dx[0]);
361
362 /* Count absolute max character count on the line. */
363 for (int c = start_offs; c < r->len && width_avail > 0; c++, num_chars++) {
364 if (c > start_offs && log_attribs[num_chars].fCharStop) last_cluster = num_chars;
365 width_avail -= dx[c];
366 }
367
368 start_offs = 0;
369 }
370
371 /* Walk backwards to find the last suitable breaking point. */
372 while (--num_chars > this->cur_range_offset && !log_attribs[num_chars].fSoftBreak && !log_attribs[num_chars].fWhiteSpace) {}
373
374 if (num_chars == this->cur_range_offset) {
375 /* Didn't find any suitable word break point, just break on the last cluster boundary. */
376 num_chars = last_cluster;

Callers

nothing calls this directly

Calls 6

UniscribeShapeRunFunction · 0.85
resizeMethod · 0.80
push_backMethod · 0.80
endMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected