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.
| 815 | // TODO: Thickness anti-aliased lines cap are missing their AA fringe. |
| 816 | // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. |
| 817 | void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, float thickness, ImDrawFlags flags) |
| 818 | { |
| 819 | if (points_count < 2 || (col & IM_COL32_A_MASK) == 0) |
| 820 | return; |
| 821 | |
| 822 | const bool closed = (flags & ImDrawFlags_Closed) != 0; |
| 823 | const ImVec2 opaque_uv = _Data->TexUvWhitePixel; |
| 824 | const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw |
| 825 | const bool thick_line = (thickness > _FringeScale); |
| 826 | IM_ASSERT((flags & ImDrawFlags_InvalidMask_) == 0 && "Incorrect parameter. Did you swapped 'thickness' and 'flags'?"); |
| 827 | |
| 828 | if (Flags & ImDrawListFlags_AntiAliasedLines) |
| 829 | { |
| 830 | // Anti-aliased stroke |
| 831 | const float AA_SIZE = _FringeScale; |
| 832 | const ImU32 col_trans = col & ~IM_COL32_A_MASK; |
| 833 | |
| 834 | // Thicknesses <1.0 should behave like thickness 1.0 |
| 835 | thickness = ImMax(thickness, 1.0f); |
| 836 | const int integer_thickness = (int)thickness; |
| 837 | const float fractional_thickness = thickness - integer_thickness; |
| 838 | |
| 839 | // Do we want to draw this line using a texture? |
| 840 | // - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved. |
| 841 | // - If AA_SIZE is not 1.0f we cannot use the texture path. |
| 842 | const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f); |
| 843 | |
| 844 | // We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off |
| 845 | IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)); |
| 846 | |
| 847 | const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12); |
| 848 | const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3); |
| 849 | PrimReserve(idx_count, vtx_count); |
| 850 | |
| 851 | // Temporary buffer |
| 852 | // 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 |
| 853 | _Data->TempBuffer.reserve_discard(points_count * ((use_texture || !thick_line) ? 3 : 5)); |
| 854 | ImVec2* temp_normals = _Data->TempBuffer.Data; |
| 855 | ImVec2* temp_points = temp_normals + points_count; |
| 856 | |
| 857 | // Calculate normals (tangents) for each line segment |
| 858 | for (int i1 = 0; i1 < count; i1++) |
| 859 | { |
| 860 | const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; |
| 861 | float dx = points[i2].x - points[i1].x; |
| 862 | float dy = points[i2].y - points[i1].y; |
| 863 | IM_NORMALIZE2F_OVER_ZERO(dx, dy); |
| 864 | temp_normals[i1].x = dy; |
| 865 | temp_normals[i1].y = -dx; |
| 866 | } |
| 867 | if (!closed) |
| 868 | temp_normals[points_count - 1] = temp_normals[points_count - 2]; |
| 869 | |
| 870 | // 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 |
| 871 | if (use_texture || !thick_line) |
| 872 | { |
| 873 | // [PATH 1] Texture-based lines (thick or non-thick) |
| 874 | // [PATH 2] Non texture-based lines (non-thick) |
no test coverage detected