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