TODO: Thickness anti-aliased lines cap are missing their AA fringe. We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
| 713 | // TODO: Thickness anti-aliased lines cap are missing their AA fringe. |
| 714 | // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. |
| 715 | void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness) |
| 716 | { |
| 717 | if (points_count < 2) |
| 718 | return; |
| 719 | |
| 720 | const bool closed = (flags & ImDrawFlags_Closed) != 0; |
| 721 | const ImVec2 opaque_uv = _Data->TexUvWhitePixel; |
| 722 | const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw |
| 723 | const bool thick_line = (thickness > _FringeScale); |
| 724 | |
| 725 | if (Flags & ImDrawListFlags_AntiAliasedLines) |
| 726 | { |
| 727 | // Anti-aliased stroke |
| 728 | const float AA_SIZE = _FringeScale; |
| 729 | const ImU32 col_trans = col & ~IM_COL32_A_MASK; |
| 730 | |
| 731 | // Thicknesses <1.0 should behave like thickness 1.0 |
| 732 | thickness = ImMax(thickness, 1.0f); |
| 733 | const int integer_thickness = (int)thickness; |
| 734 | const float fractional_thickness = thickness - integer_thickness; |
| 735 | |
| 736 | // Do we want to draw this line using a texture? |
| 737 | // - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved. |
| 738 | // - If AA_SIZE is not 1.0f we cannot use the texture path. |
| 739 | const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f); |
| 740 | |
| 741 | // We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off |
| 742 | IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)); |
| 743 | |
| 744 | const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12); |
| 745 | const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3); |
| 746 | PrimReserve(idx_count, vtx_count); |
| 747 | |
| 748 | // Temporary buffer |
| 749 | // The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point |
| 750 | _Data->TempBuffer.reserve_discard(points_count * ((use_texture || !thick_line) ? 3 : 5)); |
| 751 | ImVec2* temp_normals = _Data->TempBuffer.Data; |
| 752 | ImVec2* temp_points = temp_normals + points_count; |
| 753 | |
| 754 | // Calculate normals (tangents) for each line segment |
| 755 | for (int i1 = 0; i1 < count; i1++) |
| 756 | { |
| 757 | const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; |
| 758 | float dx = points[i2].x - points[i1].x; |
| 759 | float dy = points[i2].y - points[i1].y; |
| 760 | IM_NORMALIZE2F_OVER_ZERO(dx, dy); |
| 761 | temp_normals[i1].x = dy; |
| 762 | temp_normals[i1].y = -dx; |
| 763 | } |
| 764 | if (!closed) |
| 765 | temp_normals[points_count - 1] = temp_normals[points_count - 2]; |
| 766 | |
| 767 | // If we are drawing a one-pixel-wide line without a texture, or a textured line of any width, we only need 2 or 3 vertices per point |
| 768 | if (use_texture || !thick_line) |
| 769 | { |
| 770 | // [PATH 1] Texture-based lines (thick or non-thick) |
| 771 | // [PATH 2] Non texture-based lines (non-thick) |
| 772 |
no test coverage detected