Merge branch 'master' into docking

This commit is contained in:
omar 2019-02-18 12:16:13 +01:00
commit 5bf9029bf9
7 changed files with 56 additions and 39 deletions

View File

@ -137,6 +137,7 @@ Other Changes:
calculated text width. Among noticeable side-effects, it would make sequences of repeated Text/SameLine calls
not align the same as a single call, and create mismatch between high-level size calculation and those performed
with the lower-level ImDrawList api. (#792) [@SlNPacifist]
- Font: Fixed building atlas when specifying duplicate/overlapping ranges within a same font. (#2353, #2233)
- ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle"
with a small number of segments (e.g. an hexagon). (#2287) [@baktery]
- ImGuiTextBuffer: Added append() function (unformatted).
@ -145,8 +146,8 @@ Other Changes:
- ImFontAtlas: FreeType: Fixed using imgui_freetype.cpp in unity builds. (#2302)
- Demo: Fixed "Log" demo not initializing properly, leading to the first line not showing before a Clear. (#2318) [@bluescan]
- Demo: Added "Auto-scroll" option in Log/Console demos. (#2300) [@nicolasnoble, @ocornut]
- Examples: Metal, OpenGL2, OpenGL3: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0) when
the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch,
- Examples: Metal, OpenGL2, OpenGL3, Vulkan: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0)
when the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch,
this is effectively fixing support for multi-viewport with Mac Retina Displays on those examples. (#2306) [@rasky, @ocornut]
Also using ImDrawData::FramebufferScale instead of io.DisplayFramebufferScale.
- Examples: Clarified the use the ImDrawData::DisplayPos to offset clipping rectangles.

View File

@ -91,7 +91,6 @@
ImGui::Render();
[[self openGLContext] makeCurrentContext];
ImGuiIO& io = ImGui::GetIO();
ImDrawData* draw_data = ImGui::GetDrawData();
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);

View File

@ -14,6 +14,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case.
// 2018-06-22: Inverted the parameters to ImGui_ImplVulkan_RenderDrawData() to be consistent with other bindings.
@ -207,10 +208,13 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer)
{
VkResult err;
if (draw_data->TotalVtxCount == 0)
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
return;
VkResult err;
FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex];
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
@ -271,8 +275,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
VkViewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = draw_data->DisplaySize.x;
viewport.height = draw_data->DisplaySize.y;
viewport.width = (float)fb_width;
viewport.height = (float)fb_height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
@ -291,10 +295,13 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate);
}
// Render the command lists:
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists
int vtx_offset = 0;
int idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -307,17 +314,26 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
}
else
{
// Apply scissor/clipping rectangle
// FIXME: We could clamp width/height based on clamped min/max values.
VkRect2D scissor;
scissor.offset.x = (int32_t)(pcmd->ClipRect.x - clip_off.x) > 0 ? (int32_t)(pcmd->ClipRect.x - clip_off.x) : 0;
scissor.offset.y = (int32_t)(pcmd->ClipRect.y - clip_off.y) > 0 ? (int32_t)(pcmd->ClipRect.y - clip_off.y) : 0;
scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
// Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
// Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{
// Apply scissor/clipping rectangle
VkRect2D scissor;
scissor.offset.x = (int32_t)(clip_rect.x);
scissor.offset.y = (int32_t)(clip_rect.y);
scissor.extent.width = (uint32_t)(clip_rect.z - clip_rect.x);
scissor.extent.height = (uint32_t)(clip_rect.w - clip_rect.y);
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
// Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
}
}
idx_offset += pcmd->ElemCount;
}

16
imgui.h
View File

@ -2171,26 +2171,26 @@ struct ImFontAtlas
// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32().
struct ImFont
{
// Members: Hot ~24/32 bytes (for CalcTextSize)
ImVector<float> IndexAdvanceX; // 12/16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this this info, and are often bottleneck in large UI).
float FontSize; // 4 // in // <user set> // Height of characters, set during loading (don't change after loading)
// Members: Hot ~20/24 bytes (for CalcTextSize)
ImVector<float> IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this this info, and are often bottleneck in large UI).
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
ImWchar FallbackChar; // 2 // in // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
// Members: Hot ~36/48 bytes (for CalcTextSize + render loop)
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
ImVec2 DisplayOffset; // 8 // in // = (0,0) // Offset font rendering by xx pixels
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
ImVec2 DisplayOffset; // 8 // in // = (0,0) // Offset font rendering by xx pixels
// Members: Cold ~28/40 bytes
// Members: Cold ~32/40 bytes
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData
short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
bool DirtyLookupTables; // 1 // out //
ImWchar FallbackChar; // 2 // in // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
float Ascent, Descent; // 8 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
bool DirtyLookupTables; // 1 // out //
// Methods
IMGUI_API ImFont();

View File

@ -1846,15 +1846,14 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty())
if (dst_tmp.GlyphsSet.Storage.empty())
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
{
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true)
continue;
if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font?
continue;
@ -1863,8 +1862,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true);
dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++;
}
}

View File

@ -67,6 +67,7 @@ struct FreeTypeTest
FontBuildMode BuildMode;
bool WantRebuild;
float FontsMultiply;
int FontsPadding;
unsigned int FontsFlags;
FreeTypeTest()
@ -74,6 +75,7 @@ struct FreeTypeTest
BuildMode = FontBuildMode_FreeType;
WantRebuild = true;
FontsMultiply = 1.0f;
FontsPadding = 1;
FontsFlags = 0;
}
@ -85,8 +87,10 @@ struct FreeTypeTest
ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < io.Fonts->Fonts.Size; n++)
{
io.Fonts->Fonts[n]->ConfigData->RasterizerMultiply = FontsMultiply;
io.Fonts->Fonts[n]->ConfigData->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
ImFontConfig* font_config = (ImFontConfig*)io.Fonts->Fonts[n]->ConfigData;
io.Fonts->TexGlyphPadding = FontsPadding;
font_config->RasterizerMultiply = FontsMultiply;
font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
}
if (BuildMode == FontBuildMode_FreeType)
ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
@ -105,6 +109,7 @@ struct FreeTypeTest
ImGui::SameLine();
WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
WantRebuild |= ImGui::DragInt("Padding", &FontsPadding, 0.1f, 0, 16);
if (BuildMode == FontBuildMode_FreeType)
{
WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting);

View File

@ -336,15 +336,14 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty())
if (dst_tmp.GlyphsSet.Storage.empty())
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
{
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
continue;
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
if (glyph_index == 0)
@ -354,8 +353,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true);
dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++;
}
}