* Drawing routine for drawing a laid out line of text. * @param line String to draw. * @param y The top most position to draw on. * @param left The left most position to draw on. * @param right The right most position to draw on. * @param align The alignment of the string when drawing left-to-right. In the * case a right-to-left language is chosen t
| 504 | * In case of right alignment the left most pixel we have drawn to. |
| 505 | */ |
| 506 | static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation, TextColour default_colour) |
| 507 | { |
| 508 | if (line.CountRuns() == 0) return 0; |
| 509 | |
| 510 | int w = line.GetWidth(); |
| 511 | int h = line.GetLeading(); |
| 512 | |
| 513 | /* |
| 514 | * The following is needed for truncation. |
| 515 | * Depending on the text direction, we either remove bits at the rear |
| 516 | * or the front. For this we shift the entire area to draw so it fits |
| 517 | * within the left/right bounds and the side we do not truncate it on. |
| 518 | * Then we determine the truncation location, i.e. glyphs that fall |
| 519 | * outside of the range min_x - max_x will not be drawn; they are thus |
| 520 | * the truncated glyphs. |
| 521 | * |
| 522 | * At a later step we insert the dots. |
| 523 | */ |
| 524 | |
| 525 | int max_w = right - left + 1; // The maximum width. |
| 526 | |
| 527 | int offset_x = 0; // The offset we need for positioning the glyphs |
| 528 | int min_x = left; // The minimum x position to draw normal glyphs on. |
| 529 | int max_x = right; // The maximum x position to draw normal glyphs on. |
| 530 | |
| 531 | truncation &= max_w < w; // Whether we need to do truncation. |
| 532 | int truncation_width = 0; // Width of the ellipsis string. |
| 533 | |
| 534 | std::optional<Layouter> truncation_layout; ///< Layout for truncation ellipsis. |
| 535 | if (truncation) { |
| 536 | /* |
| 537 | * Assumption may be made that all fonts of a run are of the same size. |
| 538 | * In any case, we'll use these dots for the abbreviation, so even if |
| 539 | * another size would be chosen it won't have truncated too little for |
| 540 | * the truncation dots. |
| 541 | */ |
| 542 | truncation_layout.emplace(GetEllipsis(), INT32_MAX, line.GetVisualRun(0).GetFont()->fc->GetSize()); |
| 543 | truncation_width = truncation_layout->GetBounds().width; |
| 544 | |
| 545 | /* Is there enough space even for an ellipsis? */ |
| 546 | if (max_w < truncation_width) return (_current_text_dir == TD_RTL) ? left : right; |
| 547 | |
| 548 | if (_current_text_dir == TD_RTL) { |
| 549 | min_x += truncation_width; |
| 550 | offset_x = w - max_w; |
| 551 | } else { |
| 552 | max_x -= truncation_width; |
| 553 | } |
| 554 | |
| 555 | w = max_w; |
| 556 | } |
| 557 | |
| 558 | /* In case we have a RTL language we swap the alignment. */ |
| 559 | if (!(align & SA_FORCE) && _current_text_dir == TD_RTL && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT; |
| 560 | |
| 561 | /* right is the right most position to draw on. In this case we want to do |
| 562 | * calculations with the width of the string. In comparison right can be |
| 563 | * seen as lastof(todraw) and width as lengthof(todraw). They differ by 1. |
no test coverage detected