| 696 | // ### TextRenderable ### |
| 697 | |
| 698 | TextRenderable::TextRenderable(const TextSymbol* symbol, const TextObject* text_object, const MapColor* color, double anchor_x, double anchor_y) |
| 699 | : Renderable { color } |
| 700 | , anchor_x { anchor_x } |
| 701 | , anchor_y { anchor_y } |
| 702 | , rotation { 0.0 } |
| 703 | , scale_factor { symbol->getFontSize() / TextSymbol::internal_point_size } |
| 704 | { |
| 705 | path.setFillRule(Qt::WindingFill); // Otherwise, when text and an underline intersect, holes appear |
| 706 | |
| 707 | const QFont& font(symbol->getQFont()); |
| 708 | const QFontMetricsF& metrics(symbol->getFontMetrics()); |
| 709 | |
| 710 | int num_lines = text_object->getNumLines(); |
| 711 | for (int i=0; i < num_lines; i++) |
| 712 | { |
| 713 | const TextObjectLineInfo* line_info = text_object->getLineInfo(i); |
| 714 | |
| 715 | double line_y = line_info->line_y; |
| 716 | |
| 717 | double underline_x0 = 0.0; |
| 718 | double underline_y0 = line_info->line_y + metrics.underlinePos(); |
| 719 | double underline_y1 = underline_y0 + metrics.lineWidth(); |
| 720 | |
| 721 | auto num_parts = line_info->part_infos.size(); |
| 722 | for (std::size_t j=0; j < num_parts; j++) |
| 723 | { |
| 724 | const TextObjectPartInfo& part(line_info->part_infos.at(j)); |
| 725 | if (font.underline()) |
| 726 | { |
| 727 | if (j > 0) |
| 728 | { |
| 729 | // draw underline for gap between parts as rectangle |
| 730 | // TODO: watch out for inconsistency between text and gap underline |
| 731 | path.moveTo(underline_x0, underline_y0); |
| 732 | path.lineTo(part.part_x, underline_y0); |
| 733 | path.lineTo(part.part_x, underline_y1); |
| 734 | path.lineTo(underline_x0, underline_y1); |
| 735 | path.closeSubpath(); |
| 736 | } |
| 737 | underline_x0 = part.part_x; |
| 738 | } |
| 739 | path.addText(part.part_x, line_y, font, part.part_text); |
| 740 | } |
| 741 | } |
| 742 | |
| 743 | QTransform t { 1.0, 0.0, 0.0, 1.0, anchor_x, anchor_y }; |
| 744 | t.scale(scale_factor, scale_factor); |
| 745 | |
| 746 | auto rotation_rad = text_object->getRotation(); |
| 747 | if (!qIsNull(rotation_rad)) |
| 748 | { |
| 749 | rotation = -qRadiansToDegrees(rotation_rad); |
| 750 | t.rotate(rotation); |
| 751 | } |
| 752 | |
| 753 | extent = t.mapRect(path.controlPointRect()); |
| 754 | } |
| 755 |
nothing calls this directly
no test coverage detected