Texture-based thick lines: Remove unnecessary indirection in fetching UV data, removed lerp call, renames, tweaks.
diff --git a/imgui.cpp b/imgui.cpp
index e6fe118..b9c300f 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -935,7 +935,7 @@
     DisplaySafeAreaPadding  = ImVec2(3,3);      // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
     MouseCursorScale        = 1.0f;             // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
     AntiAliasedLines        = true;             // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
-    AntiAliasedLinesUseTexData = true;          // Draw anti-aliased lines using textures where possible.
+    AntiAliasedLinesUseTex  = true;             // Enable anti-aliased lines/borders using textures where possible. Requires back-end to render with bilinear filtering.
     AntiAliasedFill         = true;             // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
     CurveTessellationTol    = 1.25f;            // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
     CircleSegmentMaxError   = 1.60f;            // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
@@ -3689,8 +3689,8 @@
     g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
     if (g.Style.AntiAliasedLines)
         g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
-    if (g.Style.AntiAliasedLinesUseTexData && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoAALines))
-        g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTexData;
+    if (g.Style.AntiAliasedLinesUseTex && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoAntiAliasedLines))
+        g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
     if (g.Style.AntiAliasedFill)
         g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
     if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
@@ -6161,7 +6161,7 @@
 
     ImFontAtlas* atlas = g.Font->ContainerAtlas;
     g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
-    g.DrawListSharedData.TexUvAALines = &atlas->TexUvAALines;
+    g.DrawListSharedData.TexUvAALines = atlas->TexUvAALines;
     g.DrawListSharedData.Font = g.Font;
     g.DrawListSharedData.FontSize = g.FontSize;
 }
diff --git a/imgui.h b/imgui.h
index e5e5429..5e86bae 100644
--- a/imgui.h
+++ b/imgui.h
@@ -1439,7 +1439,7 @@
     ImVec2      DisplaySafeAreaPadding;     // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
     float       MouseCursorScale;           // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
     bool        AntiAliasedLines;           // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
-    bool        AntiAliasedLinesUseTexData; // Draw anti-aliased lines using textures where possible.
+    bool        AntiAliasedLinesUseTex;     // Enable anti-aliased lines/borders using textures where possible. Requires back-end to render with bilinear filtering.
     bool        AntiAliasedFill;            // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU.
     float       CurveTessellationTol;       // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
     float       CircleSegmentMaxError;      // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
@@ -1897,6 +1897,11 @@
 // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
 //-----------------------------------------------------------------------------
 
+// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoAALines to disable baking.
+#ifndef IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX
+#define IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX      (63)
+#endif
+
 // ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
 // NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
 // you can poke into the draw list for that! Draw callback may be useful for example to:
@@ -2000,8 +2005,8 @@
     ImDrawListFlags_None                    = 0,
     ImDrawListFlags_AntiAliasedLines        = 1 << 0,  // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles)
     ImDrawListFlags_AntiAliasedFill         = 1 << 1,  // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
-    ImDrawListFlags_AllowVtxOffset          = 1 << 2,  // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
-    ImDrawListFlags_AntiAliasedLinesUseTexData  = 1 << 3   // Should anti-aliased lines be drawn using textures where possible?
+    ImDrawListFlags_AntiAliasedLinesUseTex  = 1 << 2,  // Should anti-aliased lines be drawn using textures where possible?
+    ImDrawListFlags_AllowVtxOffset          = 1 << 3   // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
 };
 
 // Draw command list
@@ -2221,7 +2226,7 @@
     ImFontAtlasFlags_None               = 0,
     ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0,   // Don't round the height to next power of two
     ImFontAtlasFlags_NoMouseCursors     = 1 << 1,   // Don't build software mouse cursors into the atlas (save a little texture memory)
-    ImFontAtlasFlags_NoAALines          = 1 << 2    // Don't build anti-aliased line textures into the atlas
+    ImFontAtlasFlags_NoAntiAliasedLines = 1 << 2    // Don't build anti-aliased line textures into the atlas (save a little texture memory). They will be rendered using polygons (a little bit more expensive)
 };
 
 // Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding:
@@ -2322,11 +2327,11 @@
     ImVector<ImFont*>           Fonts;              // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
     ImVector<ImFontAtlasCustomRect> CustomRects;    // Rectangles for packing custom texture data into the atlas.
     ImVector<ImFontConfig>      ConfigData;         // Configuration data
+    ImVec4                      TexUvAALines[IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 1];   // UVs for anti-aliased line textures
 
     // [Internal] Packing data
     int                         PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
-    int                         AALineRectId;       // Custom texture rectangle ID for anti-aliased lines
-    ImVector<ImVec4>            TexUvAALines;       // UVs for anti-aliased line textures
+    int                         PackIdAALines;      // Custom texture rectangle ID for anti-aliased lines
 
 #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
     typedef ImFontAtlasCustomRect    CustomRect;         // OBSOLETED in 1.72+
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index f599e03..8b5d57d 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -3698,7 +3698,7 @@
             ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f");
             ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f");
             ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f");
-            ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 4.0f, "%.1f");
+            ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
             ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
             ImGui::Text("Rounding");
             ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
@@ -3831,7 +3831,7 @@
         {
             ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
             ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
-            ImGui::Checkbox("Anti-aliased lines use texture data", &style.AntiAliasedLinesUseTexData);
+            ImGui::Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex);
             ImGui::SameLine(); HelpMarker("Faster lines using texture data. Requires texture to use bilinear sampling (not nearest).");
             ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
             ImGui::PushItemWidth(100);
diff --git a/imgui_draw.cpp b/imgui_draw.cpp
index a4f68f9..24e8a65 100644
--- a/imgui_draw.cpp
+++ b/imgui_draw.cpp
@@ -668,7 +668,6 @@
 
     const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
     const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
-
     const bool thick_line = (thickness > 1.0f);
 
     if (Flags & ImDrawListFlags_AntiAliasedLines)
@@ -679,12 +678,11 @@
 
         // Thicknesses <1.0 should behave like thickness 1.0
         thickness = ImMax(thickness, 1.0f);
-
-        const int integer_thickness = (int)thickness ;
-        const float fractional_thickness = (thickness) - integer_thickness;
+        const int integer_thickness = (int)thickness;
+        const float fractional_thickness = thickness - integer_thickness;
 
         // Do we want to draw this line using a texture?
-        const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTexData) && (integer_thickness < IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX);
+        const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX);
 
         // We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTexData unless ImFontAtlasFlags_NoAALines is off
         IM_ASSERT_PARANOID((!use_texture) || (!(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoAALines)));
@@ -712,8 +710,11 @@
             temp_normals[points_count - 1] = temp_normals[points_count - 2];
 
         // 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
-        if (!thick_line || use_texture)
+        if (use_texture || !thick_line)
         {
+            // [PATH 1] Texture-based lines (thick or non-thick)
+            // [PATH 2] Non texture-based lines (non-thick)
+
             // The width of the geometry we need to draw - this is essentially <thickness> pixels for the line itself, plus one pixel for AA
             // We don't use AA_SIZE here because the +1 is tied to the generated texture and so alternate values won't work without changes to that code
             const float half_draw_size = use_texture ? ((thickness * 0.5f) + 1) : 1.0f;
@@ -734,7 +735,7 @@
             for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment
             {
                 const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; // i2 is the second point of the line segment
-                unsigned int idx2 = ((i1 + 1) == points_count) ? _VtxCurrentIdx : (idx1 + (use_texture ? 2 : 3)); // Vertex index for end of segment
+                const unsigned int idx2 = ((i1 + 1) == points_count) ? _VtxCurrentIdx : (idx1 + (use_texture ? 2 : 3)); // Vertex index for end of segment
 
                 // Average normals
                 float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
@@ -774,32 +775,30 @@
             if (use_texture)
             {
                 // If we're using textures we only need to emit the left/right edge vertices
-
-                ImVec4 tex_uvs;
-
-                if (fractional_thickness == 0.0f) // Fast path for pure integer widths
-                    tex_uvs = (*_Data->TexUvAALines)[integer_thickness];
-                else
+                ImVec4 tex_uvs = _Data->TexUvAALines[integer_thickness];
+                if (fractional_thickness != 0.0f)
                 {
-                    // Calculate UV by interpolating between the two nearest integer line widths
-                    const ImVec4 tex_uvs_0 = (*_Data->TexUvAALines)[integer_thickness];
-                    const ImVec4 tex_uvs_1 = (*_Data->TexUvAALines)[integer_thickness + 1];
-                    tex_uvs = ImLerp(tex_uvs_0, tex_uvs_1, fractional_thickness);
+                    const ImVec4 tex_uvs_1 = _Data->TexUvAALines[integer_thickness + 1];
+                    tex_uvs.x = tex_uvs.x + (tex_uvs_1.x - tex_uvs.x) * fractional_thickness; // inlined ImLerp()
+                    tex_uvs.y = tex_uvs.y + (tex_uvs_1.y - tex_uvs.y) * fractional_thickness;
+                    tex_uvs.z = tex_uvs.z + (tex_uvs_1.z - tex_uvs.z) * fractional_thickness;
+                    tex_uvs.w = tex_uvs.w + (tex_uvs_1.w - tex_uvs.w) * fractional_thickness;
                 }
-
+                ImVec2 tex_uv0(tex_uvs.x, tex_uvs.y);
+                ImVec2 tex_uv1(tex_uvs.z, tex_uvs.w);
                 for (int i = 0; i < points_count; i++)
                 {
-                    _VtxWritePtr[0].pos = temp_points[i * 2 + 0]; _VtxWritePtr[0].uv = ImVec2(tex_uvs.x, tex_uvs.y); _VtxWritePtr[0].col = col; // Left-side outer edge
-                    _VtxWritePtr[1].pos = temp_points[i * 2 + 1]; _VtxWritePtr[1].uv = ImVec2(tex_uvs.z, tex_uvs.y); _VtxWritePtr[1].col = col; // Right-side outer edge
+                    _VtxWritePtr[0].pos = temp_points[i * 2 + 0]; _VtxWritePtr[0].uv = tex_uv0; _VtxWritePtr[0].col = col; // Left-side outer edge
+                    _VtxWritePtr[1].pos = temp_points[i * 2 + 1]; _VtxWritePtr[1].uv = tex_uv1; _VtxWritePtr[1].col = col; // Right-side outer edge
                     _VtxWritePtr += 2;
                 }
             }
             else
             {
-                // If we're not using a texture, we need the centre vertex as well
+                // If we're not using a texture, we need the center vertex as well
                 for (int i = 0; i < points_count; i++)
                 {
-                    _VtxWritePtr[0].pos = points[i];              _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; // Centre of line
+                    _VtxWritePtr[0].pos = points[i];              _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col;       // Center of line
                     _VtxWritePtr[1].pos = temp_points[i * 2 + 0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; // Left-side outer edge
                     _VtxWritePtr[2].pos = temp_points[i * 2 + 1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; // Right-side outer edge
                     _VtxWritePtr += 3;
@@ -808,7 +807,7 @@
         }
         else
         {
-            // For untextured lines that are greater than a pixel in width, we need to draw the solid line core and thus require four vertices per point
+            // [PATH 2] Non texture-based lines (thick): we need to draw the solid line core and thus require four vertices per point
             const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
 
             // If line is not closed, the first and last points need to be generated differently as there are no normals to blend
@@ -880,7 +879,7 @@
     }
     else
     {
-        // Non texture-based, Non anti-aliased lines
+        // [PATH 4] Non texture-based, Non anti-aliased lines
         const int idx_count = count * 6;
         const int vtx_count = count * 4;    // FIXME-OPT: Not sharing edges
         PrimReserve(idx_count, vtx_count);
@@ -1720,7 +1719,7 @@
     TexWidth = TexHeight = 0;
     TexUvScale = ImVec2(0.0f, 0.0f);
     TexUvWhitePixel = ImVec2(0.0f, 0.0f);
-    PackIdMouseCursors = -1;
+    PackIdMouseCursors = PackIdAALines = -1;
 }
 
 ImFontAtlas::~ImFontAtlas()
@@ -1748,7 +1747,7 @@
         }
     ConfigData.clear();
     CustomRects.clear();
-    PackIdMouseCursors = -1;
+    PackIdMouseCursors = PackIdAALines = -1;
 }
 
 void    ImFontAtlas::ClearTexData()
@@ -2390,41 +2389,38 @@
 
 static void ImFontAtlasBuildRegisterAALineCustomRects(ImFontAtlas* atlas)
 {
-    if ((atlas->Flags & ImFontAtlasFlags_NoAALines))
+    if (atlas->Flags & ImFontAtlasFlags_NoAntiAliasedLines)
         return;
 
-    // The "max_width + 2" here is to give space for the end caps, whilst height (IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX+1) is to accommodate the fact we have a zero-width row
-    const int max_width = IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX; // The maximum line width we want to generate
-    atlas->AALineRectId = atlas->AddCustomRectRegular(max_width + 2, IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 1);
+    // The +2 here is to give space for the end caps, whilst height +1 is to accommodate the fact we have a zero-width row
+    atlas->PackIdAALines = atlas->AddCustomRectRegular(IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 2, IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 1);
 }
 
 static void ImFontAtlasBuildRenderAALinesTexData(ImFontAtlas* atlas)
 {
     IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
-    IM_ASSERT(atlas->TexUvAALines.Size == 0);
-
-    if (atlas->Flags & ImFontAtlasFlags_NoAALines)
+    if (atlas->Flags & ImFontAtlasFlags_NoAntiAliasedLines)
         return;
 
-    ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->AALineRectId];
-    IM_ASSERT(r.IsPacked());
+    ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdAALines);
+    IM_ASSERT(r->IsPacked());
 
     // This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them
     const int w = atlas->TexWidth;
-    for (unsigned int n = 0; n < (IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 1); n++) // +1 because of the zero-width row
+    for (unsigned int n = 0; n < IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row
     {
+        // Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle
         unsigned int y = n;
         unsigned int line_width = n;
-        // Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle
-        unsigned int pad_left = (r.Width - line_width) / 2;
-        unsigned int pad_right = r.Width - (pad_left + line_width);
+        unsigned int pad_left = (r->Width - line_width) / 2;
+        unsigned int pad_right = r->Width - (pad_left + line_width);
 
         // Make sure we're inside the texture bounds before we start writing pixels
         IM_ASSERT_PARANOID(pad_left + line_width + pad_right == r.Width);
         IM_ASSERT_PARANOID(y < r.Height);
 
         // Write each slice
-        unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r.X + ((r.Y + y) * w)];
+        unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * w)];
         for (unsigned int x = 0; x < pad_left; x++)
             *(write_ptr++) = 0;
         for (unsigned int x = 0; x < line_width; x++)
@@ -2433,16 +2429,16 @@
             *(write_ptr++) = 0;
 
         // Calculate UVs for this line
-        ImFontAtlasCustomRect line_rect = r;
+        ImFontAtlasCustomRect line_rect = *r;
         line_rect.X += (unsigned short)(pad_left - 1);
-        line_rect.Width = (unsigned short)(line_width + 2);
         line_rect.Y += (unsigned short)y;
+        line_rect.Width = (unsigned short)(line_width + 2);
         line_rect.Height = 1;
 
         ImVec2 uv0, uv1;
         atlas->CalcCustomRectUV(&line_rect, &uv0, &uv1);
-        float halfV = (uv0.y + uv1.y) * 0.5f; // Calculate a constant V in the middle of the row to avoid sampling artifacts
-        atlas->TexUvAALines.push_back(ImVec4(uv0.x, halfV, uv1.x, halfV));
+        float half_v = (uv0.y + uv1.y) * 0.5f; // Calculate a constant V in the middle of the row to avoid sampling artifacts
+        atlas->TexUvAALines[n] = ImVec4(uv0.x, half_v, uv1.x, half_v);
     }
 }
 
diff --git a/imgui_internal.h b/imgui_internal.h
index 4f3882c..629ddc3 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -529,9 +529,6 @@
 #define IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER             1
 #endif
 
-// The maximum line width to build anti-aliased textures for (note that this needs to be one greater than the maximum line width you want to be able to draw using the textured path)
-#define IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX                      65
-
 // Data shared between all ImDrawList instances
 // You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure.
 struct IMGUI_API ImDrawListSharedData
@@ -548,7 +545,7 @@
     ImVec2          ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER];  // FIXME: Bake rounded corners fill/borders in atlas
     ImU8            CircleSegmentCounts[64];    // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
 
-    ImVector<ImVec4>* TexUvAALines;             // UV of anti-aliased lines in the atlas
+    const ImVec4*   TexUvAALines;               // UV of anti-aliased lines in the atlas
 
     ImDrawListSharedData();
     void SetCircleSegmentMaxError(float max_error);