1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00

Update ImGUI to 1.82 + docking.

This commit is contained in:
Bartosz Taudul
2021-03-15 21:13:01 +01:00
parent 753c007557
commit 06b1214aff
12 changed files with 1059 additions and 661 deletions
+239 -79
View File
@@ -1,4 +1,4 @@
// dear imgui, v1.81
// dear imgui, v1.82
// (drawing and font code)
/*
@@ -380,19 +380,22 @@ ImDrawListSharedData::ImDrawListSharedData()
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
}
ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError);
}
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
{
if (CircleSegmentMaxError == max_error)
return;
IM_ASSERT(max_error > 0.0f);
CircleSegmentMaxError = max_error;
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
{
const float radius = (float)i;
const int segment_count = (i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0;
CircleSegmentCounts[i] = (ImU8)ImMin(segment_count, 255);
CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0);
}
ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError);
}
// Initialize before use in a new frame. We always have a command ready in the buffer.
@@ -549,6 +552,16 @@ void ImDrawList::_OnChangedVtxOffset()
curr_cmd->VtxOffset = _CmdHeader.VtxOffset;
}
int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
{
// Automatic segment count
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
}
// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
{
@@ -686,11 +699,12 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
// 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.
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness)
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness)
{
if (points_count < 2)
return;
const bool closed = (flags & ImDrawFlags_Closed) != 0;
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 > _FringeScale);
@@ -1022,33 +1036,88 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
}
}
void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12)
void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step)
{
if (radius == 0.0f)
if (radius <= 0.0f)
{
_Path.push_back(center);
return;
}
IM_ASSERT(a_min_of_12 <= a_max_of_12);
IM_ASSERT(a_min_sample <= a_max_sample);
// For legacy reason the PathArcToFast() always takes angles where 2*PI is represented by 12,
// but it is possible to set IM_DRAWLIST_ARCFAST_TESSELATION_MULTIPLIER to a higher value. This should compile to a no-op otherwise.
#if IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER != 1
a_min_of_12 *= IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER;
a_max_of_12 *= IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER;
#endif
// Calculate arc auto segment step size
if (a_step <= 0)
a_step = IM_DRAWLIST_ARCFAST_SAMPLE_MAX / _CalcCircleAutoSegmentCount(radius);
_Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1));
for (int a = a_min_of_12; a <= a_max_of_12; a++)
// Make sure we never do steps larger than one quarter of the circle
a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4);
// Normalize a_min_sample to always start lie in [0..IM_DRAWLIST_ARCFAST_SAMPLE_MAX] range.
if (a_min_sample < 0)
{
const ImVec2& c = _Data->ArcFastVtx[a % IM_ARRAYSIZE(_Data->ArcFastVtx)];
_Path.push_back(ImVec2(center.x + c.x * radius, center.y + c.y * radius));
int normalized_sample = a_min_sample % IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
if (normalized_sample < 0)
normalized_sample += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
a_max_sample += (normalized_sample - a_min_sample);
a_min_sample = normalized_sample;
}
const int sample_range = a_max_sample - a_min_sample;
const int a_next_step = a_step;
int samples = sample_range + 1;
bool extra_max_sample = false;
if (a_step > 1)
{
samples = sample_range / a_step + 1;
const int overstep = sample_range % a_step;
if (overstep > 0)
{
extra_max_sample = true;
samples++;
// When we have overstep to avoid awkwardly looking one long line and one tiny one at the end,
// distribute first step range evenly between them by reducing first step size.
if (sample_range > 0)
a_step -= (a_step - overstep) / 2;
}
}
_Path.resize(_Path.Size + samples);
ImVec2* out_ptr = _Path.Data + (_Path.Size - samples);
int sample_index = a_min_sample;
for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step)
{
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX)
sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[sample_index];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
if (extra_max_sample)
{
int normalized_max_sample = a_max_sample % IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
if (normalized_max_sample < 0)
normalized_max_sample += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[normalized_max_sample];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
IM_ASSERT_PARANOID(_Path.Data + _Path.Size == out_ptr);
}
void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments)
void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments)
{
if (radius == 0.0f)
if (radius <= 0.0f)
{
_Path.push_back(center);
return;
@@ -1065,6 +1134,64 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
}
}
// 0: East, 3: South, 6: West, 9: North, 12: East
void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12)
{
if (radius <= 0.0f)
{
_Path.push_back(center);
return;
}
IM_ASSERT(a_min_of_12 <= a_max_of_12);
_PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0);
}
void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments)
{
if (radius <= 0.0f)
{
_Path.push_back(center);
return;
}
IM_ASSERT(a_min <= a_max);
if (num_segments > 0)
{
_PathArcToN(center, radius, a_min, a_max, num_segments);
return;
}
// Automatic segment count
if (radius <= _Data->ArcFastRadiusCutoff)
{
// We are going to use precomputed values for mid samples.
// Determine first and last sample in lookup table that belong to the arc.
const int a_min_sample = (int)ImCeil(IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f));
const int a_max_sample = (int)( IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f));
const int a_mid_samples = ImMax(a_max_sample - a_min_sample, 0);
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const bool a_emit_start = (a_min_segment_angle - a_min) > 0.0f;
const bool a_emit_end = (a_max - a_max_segment_angle) > 0.0f;
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
if (a_emit_start)
_Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius));
if (a_max_sample >= a_min_sample)
_PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0);
if (a_emit_end)
_Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius));
}
else
{
const float arc_length = a_max - a_min;
const int circle_segment_count = _CalcCircleAutoSegmentCount(radius);
const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length));
_PathArcToN(center, radius, a_min, a_max, arc_segment_count);
}
}
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
{
float u = 1.0f - t;
@@ -1158,12 +1285,47 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3,
}
}
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawCornerFlags rounding_corners)
IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4));
static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
{
rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f);
rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All)
// ~0 --> ImDrawFlags_RoundCornersAll or 0
if (flags == ~0)
return ImDrawFlags_RoundCornersAll;
if (rounding <= 0.0f || rounding_corners == 0)
// Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations)
// 0x01 --> ImDrawFlags_RoundCornersTopLeft (VALUE 0x01 OVERLAPS ImDrawFlags_Closed but ImDrawFlags_Closed is never valid in this path!)
// 0x02 --> ImDrawFlags_RoundCornersTopRight
// 0x03 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight
// 0x04 --> ImDrawFlags_RoundCornersBotLeft
// 0x05 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBotLeft
// ...
// 0x0F --> ImDrawFlags_RoundCornersAll or 0
// (See all values in ImDrawCornerFlags_)
if (flags >= 0x01 && flags <= 0x0F)
return (flags << 4);
// We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'
#endif
// If this triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values.
// Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc...
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
flags |= ImDrawFlags_RoundCornersAll;
return flags;
}
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags)
{
flags = FixRectCornerFlags(flags);
rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f ) - 1.0f);
rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f ) - 1.0f);
if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
{
PathLineTo(a);
PathLineTo(ImVec2(b.x, a.y));
@@ -1172,10 +1334,10 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDr
}
else
{
const float rounding_tl = (rounding_corners & ImDrawCornerFlags_TopLeft) ? rounding : 0.0f;
const float rounding_tr = (rounding_corners & ImDrawCornerFlags_TopRight) ? rounding : 0.0f;
const float rounding_br = (rounding_corners & ImDrawCornerFlags_BotRight) ? rounding : 0.0f;
const float rounding_bl = (rounding_corners & ImDrawCornerFlags_BotLeft) ? rounding : 0.0f;
const float rounding_tl = (flags & ImDrawFlags_RoundCornersTopLeft) ? rounding : 0.0f;
const float rounding_tr = (flags & ImDrawFlags_RoundCornersTopRight) ? rounding : 0.0f;
const float rounding_br = (flags & ImDrawFlags_RoundCornersBottomRight) ? rounding : 0.0f;
const float rounding_bl = (flags & ImDrawFlags_RoundCornersBottomLeft) ? rounding : 0.0f;
PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9);
PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12);
PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3);
@@ -1189,36 +1351,36 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th
return;
PathLineTo(p1 + ImVec2(0.5f, 0.5f));
PathLineTo(p2 + ImVec2(0.5f, 0.5f));
PathStroke(col, false, thickness);
PathStroke(col, 0, thickness);
}
// p_min = upper-left, p_max = lower-right
// Note we don't render 1 pixels sized rectangles properly.
void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners, float thickness)
void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (Flags & ImDrawListFlags_AntiAliasedLines)
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, rounding_corners);
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags);
else
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, rounding_corners); // Better looking lower-right corner and rounded non-AA shapes.
PathStroke(col, true, thickness);
PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags); // Better looking lower-right corner and rounded non-AA shapes.
PathStroke(col, ImDrawFlags_Closed, thickness);
}
void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners)
void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (rounding > 0.0f)
{
PathRect(p_min, p_max, rounding, rounding_corners);
PathFillConvex(col);
}
else
if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
{
PrimReserve(6, 4);
PrimRect(p_min, p_max, col);
}
else
{
PathRect(p_min, p_max, rounding, flags);
PathFillConvex(col);
}
}
// p_min = upper-left, p_max = lower-right
@@ -1246,7 +1408,7 @@ void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, c
PathLineTo(p2);
PathLineTo(p3);
PathLineTo(p4);
PathStroke(col, true, thickness);
PathStroke(col, ImDrawFlags_Closed, thickness);
}
void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col)
@@ -1269,7 +1431,7 @@ void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p
PathLineTo(p1);
PathLineTo(p2);
PathLineTo(p3);
PathStroke(col, true, thickness);
PathStroke(col, ImDrawFlags_Closed, thickness);
}
void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col)
@@ -1292,11 +1454,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
num_segments = _CalcCircleAutoSegmentCount(radius);
}
else
{
@@ -1310,7 +1468,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
PathArcToFast(center, radius - 0.5f, 0, 12 - 1);
else
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness);
PathStroke(col, ImDrawFlags_Closed, thickness);
}
void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments)
@@ -1322,11 +1480,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
num_segments = _CalcCircleAutoSegmentCount(radius);
}
else
{
@@ -1352,7 +1506,7 @@ void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_
// Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness);
PathStroke(col, ImDrawFlags_Closed, thickness);
}
// Guaranteed to honor 'num_segments'
@@ -1375,7 +1529,7 @@ void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2
PathLineTo(p1);
PathBezierCubicCurveTo(p2, p3, p4, num_segments);
PathStroke(col, false, thickness);
PathStroke(col, 0, thickness);
}
// Quadratic Bezier takes 3 controls points
@@ -1386,7 +1540,7 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
PathLineTo(p1);
PathBezierQuadraticCurveTo(p2, p3, num_segments);
PathStroke(col, false, thickness);
PathStroke(col, 0, thickness);
}
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
@@ -1455,23 +1609,24 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, con
PopTextureID();
}
void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners)
void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (rounding <= 0.0f || (rounding_corners & ImDrawCornerFlags_All) == 0)
flags = FixRectCornerFlags(flags);
if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
{
AddImage(user_texture_id, p_min, p_max, uv_min, uv_max, col);
return;
}
const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back();
const bool push_texture_id = user_texture_id != _CmdHeader.TextureId;
if (push_texture_id)
PushTextureID(user_texture_id);
int vert_start_idx = VtxBuffer.Size;
PathRect(p_min, p_max, rounding, rounding_corners);
PathRect(p_min, p_max, rounding, flags);
PathFillConvex(col);
int vert_end_idx = VtxBuffer.Size;
ImGui::ShadeVertsLinearUV(this, vert_start_idx, vert_end_idx, p_min, p_max, uv_min, uv_max, true);
@@ -1829,6 +1984,7 @@ void ImFontAtlas::ClearTexData()
IM_FREE(TexPixelsRGBA32);
TexPixelsAlpha8 = NULL;
TexPixelsRGBA32 = NULL;
TexPixelsUseColors = false;
}
void ImFontAtlas::ClearFonts()
@@ -3590,7 +3746,7 @@ void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float
draw_list->PathLineTo(ImVec2(bx - third, by - third));
draw_list->PathLineTo(ImVec2(bx, by));
draw_list->PathLineTo(ImVec2(bx + third * 2.0f, by - third * 2.0f));
draw_list->PathStroke(col, false, thickness);
draw_list->PathStroke(col, 0, thickness);
}
void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow)
@@ -3710,27 +3866,29 @@ void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect
const bool fill_R = (inner.Max.x < outer.Max.x);
const bool fill_U = (inner.Min.y > outer.Min.y);
const bool fill_D = (inner.Max.y < outer.Max.y);
if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawCornerFlags_TopLeft) | (fill_D ? 0 : ImDrawCornerFlags_BotLeft));
if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawCornerFlags_TopRight) | (fill_D ? 0 : ImDrawCornerFlags_BotRight));
if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, (fill_L ? 0 : ImDrawCornerFlags_TopLeft) | (fill_R ? 0 : ImDrawCornerFlags_TopRight));
if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, (fill_L ? 0 : ImDrawCornerFlags_BotLeft) | (fill_R ? 0 : ImDrawCornerFlags_BotRight));
if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawCornerFlags_TopLeft);
if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawCornerFlags_TopRight);
if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawCornerFlags_BotLeft);
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawCornerFlags_BotRight);
if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft));
if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight));
if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight));
if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight));
if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopLeft);
if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopRight);
if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomLeft);
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight);
}
// Helper for ColorPicker4()
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
// FIXME: uses ImGui::GetColorU32
void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, int rounding_corners_flags)
void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags)
{
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
flags = ImDrawFlags_RoundCornersDefault_;
if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF)
{
ImU32 col_bg1 = ImGui::GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col));
ImU32 col_bg2 = ImGui::GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col));
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags);
ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col));
ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col));
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
int yi = 0;
for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++)
@@ -3743,17 +3901,19 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p
float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x);
if (x2 <= x1)
continue;
int rounding_corners_flags_cell = 0;
if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopRight; }
if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotRight; }
rounding_corners_flags_cell &= rounding_corners_flags;
draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell);
ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone;
if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; }
if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; }
// Combine flags
cell_flags = (flags == ImDrawFlags_RoundCornersNone || cell_flags == ImDrawFlags_RoundCornersNone) ? ImDrawFlags_RoundCornersNone : (cell_flags & flags);
draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding, cell_flags);
}
}
}
else
{
draw_list->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags);
draw_list->AddRectFilled(p_min, p_max, col, rounding, flags);
}
}