Compare commits

..

91 Commits

Author SHA1 Message Date
d38d7c6628 TODO update + internals: changed order or ImGuiLayoutType enums to allow using them for indexing. 2019-01-15 15:06:24 +01:00
b8c6e31c2d Fixed cursor issue caused by 6890e08b when calling BeginChild/EndChild multiple times to reappend into a same child window. (#2282) 2019-01-15 15:05:56 +01:00
7a5058e3bf Version 1.67 2019-01-14 17:41:44 +01:00
1da40df279 DragFloat: Fixed broken mouse direction change with power!=1.0. (#2174, #2206) [@Joshhua5] 2019-01-14 17:38:19 +01:00
6e41745f31 Added a bunch of diagnostic ignore to cope with Clang -Weverything being absurd. Also fixed two legit warnings. (#2277) 2019-01-13 18:57:46 +01:00
abdd39b700 Merge branch 'atlas_fixes' 2019-01-13 14:19:07 +01:00
7e78865613 Demo: Fixed bounds of DragFloat in Clipping section to avoid passing zero-sized to InvisibleButton(). 2019-01-12 19:48:07 +01:00
49994ceb6e FAQ entry, moved ImTextureId, Gallery links. 2019-01-12 19:48:07 +01:00
8df8482ef4 imgui_freetype: Fixed redundant FT_Load_Glyph() calls, unused parameters, and compilation warning/error. (#2270) 2019-01-12 11:45:58 +01:00
651130002f ImFontAtlas: Fixed allocating for last bit (would only affect is that last codepoint is a multiple of 32). (#2270) 2019-01-11 15:25:43 +01:00
21828b08a0 ImFontAtlas: Rewrote FreeType based builder.
- Fixed abnormally high atlas height. (#618)
- Fixed support for any values of TexGlyphPadding (not just only 1). (#618)
- Atlas width is now properly based on total surface rather than glyph count (unless overridden with TexDesiredWidth). (#618)
- Fixed atlas builder so missing glyphs won't influence the atlas texture width. (#2233, #618)
- Fixed atlas builder so duplicate glyphs (when merging fonts) won't be included in the rasterized atlas. (#618)
2019-01-10 22:30:34 +01:00
9a9712807e ImFontAtlas: Rewrote stb_truetype based builder.
- Atlas width is now properly based on total surface rather than glyph count (unless overridden with TexDesiredWidth).
- Fixed atlas builder so missing glyphs won't influence the atlas texture width. (#2233)
- Fixed atlas builder so duplicate glyphs (when merging fonts) won't be included in the rasterized atlas.
2019-01-10 22:23:05 +01:00
e3ccc96789 Internals: Added ImBoolVector helper. 2019-01-10 16:10:02 +01:00
56caf7da29 imgui_freetype: Minor tweaks and comments. 2019-01-10 16:10:02 +01:00
7ed8e55fc7 ImVector: Added size_in_bytes() helper. 2019-01-10 16:10:02 +01:00
e4c19f5af1 ImFontGlyphRangesBuilder: Using 32-bits fields for storage instead of 8-bit ones, comments, todo. 2019-01-10 16:00:26 +01:00
7ffbcfe467 ImVector: Made reserve() another silly one-liner. It's not longer than other functions and our weird obsessions deserve to be carried with stringent consistence. + Comments 2019-01-10 15:51:09 +01:00
1f6e0b2f98 ImVector: Made a struct. Using T/T* in the code instead of value_type/iterator. Renamed index_from_pointer() to index_from_ptr() (was not documented, added in 1.63, users not supposed to use ImVector, hopefully not a big deal). 2019-01-10 15:51:08 +01:00
81eaa49773 Internals: Added comment index in imgui_internal.h 2019-01-10 15:51:08 +01:00
289569ef27 Update link to Magnum bindings. (#2269)
The various community projects that integrated Dear ImGui into Magnum
were merged together and are now an official part of the engine.
2019-01-10 14:58:59 +01:00
61a99f994e Minot internal tweaks, comments 2019-01-08 23:11:54 +01:00
9ad341902d ImDrawList: Optimized some of the functions for performance of debug builds where non-inline function call cost are non-negligible. 2019-01-08 17:37:22 +01:00
f53cd3ee0f Internals: LowerBound: Use raw pointer typedefs, we never use iterator anywhere else in the codebase.
Demo: Typo.
C98 fix.
2019-01-08 17:37:07 +01:00
57b1622afc Added IMGUI_USE_STB_SPRINTF (undocumented) (#1038) 2019-01-08 15:28:33 +01:00
b33977bc15 Tests: Reworking hook prototypes for imgui-test to be faster and multi-context friendly. 2019-01-07 23:59:05 +01:00
c2db7f63bd Selectable() should have an ID even though they are disabled, to be consistent with other widgets. Not sure of the reasoning ~1.41 which made this turn to 0. 2019-01-07 23:48:50 +01:00
3997e8b555 Fixed animated window titles from being updated when displayed in the CTRL+Tab list. + Adding overkill helpers for reusing buffers. (#787) 2019-01-07 22:46:42 +01:00
1ae7f88495 Tabs: Added ImGuiTabBarFlags_NoTooltip flag. (#261, #351) + added helpful assert 2019-01-07 18:07:09 +01:00
50faccf764 Demo: Log: Comments. Using clipper. Not linking with rand() anymore. 2019-01-07 17:33:02 +01:00
acfa4050ec Tweak changelog + tweak internal render helper functions. 2019-01-07 16:43:55 +01:00
5cb7ce2085 Renamed ImFont::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Keep redirection typedef (will obsolete). 2019-01-06 16:59:51 +01:00
1353c74dcf Comments/formatting on obsolete stuff 2019-01-06 16:37:57 +01:00
c3af134cc8 IO: Renamed InputCharacters[], marked internal as was always intended. AddInputCharacter() goes into a queue which can receive as many characters as needed during the frame. This is useful for automation to not have an upper limit on typing speed. Will later transition key/mouse to use the event queue later. 2019-01-06 16:37:42 +01:00
1705a81efb Moved ImVector higher up in imgui :( because we will need it in ImGuiIO. 2019-01-06 16:29:40 +01:00
8b5f635624 Added alternative Rust bindings 2019-01-06 14:43:43 +01:00
9ba202821f Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary keep the focus on the parent window, which could steal it from newly appearing windows. (#787) 2019-01-04 19:03:56 +01:00
d223d1e951 Added bindings in Readme. Added internal IMGUI_DEBUG_LOG() helper. Comments, missing breaking changes note relative to imgui_impl_xxxx changes, not really part of core but worth adding in the imgui.cpp breaking change section. 2019-01-04 18:01:43 +01:00
4483320f0a Examples: Allegro 5: Properly destroy all globals on shutdown. (#2262) 2019-01-04 13:30:55 +01:00
6777544855 Added sanity check to debug parent/child ordering issues (they would generally manifest with an assert/crash in EndFrame bu tthis assert will catch some earlier). 2019-01-03 21:42:36 +01:00
ca6ac34f9d Natvis: Added Hidden info about ImGuiWindow. 2019-01-03 18:38:41 +01:00
25ac85f15d Examples: Downgrading projects to xcode 9.2 (maybe 8.0) (#2134)
* example_apple_opengl2: The deployment target was set to 10.12 from XCode 9.2.
* imgui_impl_metal: header not found by XCode 9.2.
* example_apple_metal: The deployment target was set to 10.12 from XCode 9.2.
2019-01-03 14:01:14 +01:00
64c66529ae Moving issue/pr template to docs/. Added links in README. 2019-01-03 13:35:53 +01:00
237109caa5 Internals: Extracted code out of EndFrame() into UpdateMouseMovingWindowEndFrame() 2019-01-02 23:08:32 +01:00
b3469fa94b Alternative fix for bug introduced in d845135 (#1651), fix CTRL+Tab and fallback tooltip. 2019-01-02 23:08:32 +01:00
3e30bfd6c9 Revert "Fixes crash/assert bug introduced in d845135 (#1651): would assert when showing the CTRL+Tab list and or fallback "...." tooltip."
This reverts commit 1b0e38df47.
2019-01-02 22:56:17 +01:00
1b0e38df47 Fixes crash/assert bug introduced in d845135 (#1651): would assert when showing the CTRL+Tab list and or fallback "...." tooltip. 2019-01-02 22:14:28 +01:00
d9a4cbc429 Examples: Comments about GLFW/SDL versions 2019-01-02 16:04:13 +01:00
c017a4fb5f Moved guidelines to issue #2261 to Pin and increase visibility for now. 2019-01-02 14:28:49 +01:00
acacd93836 Renamed extra_flags to flags in InputXXX parameters. 2019-01-02 11:08:14 +01:00
c738f9ef92 InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257) 2019-01-02 11:03:56 +01:00
6b97ded438 Happy new year! & comments 2019-01-02 10:57:57 +01:00
e21bc44684 Comments: fixed missing line in the "how a simple rendering function may look like" section (#2258) 2019-01-02 09:57:25 +01:00
d845135273 Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function itself at the call site (instead of being reported in EndFrame). Past the assert, they don't lead to crashes any more. Missing calls to End(), pass the assert, should not lead to crashes any more, nor to the fallback/debug window appearing on screen. (#1651). 2018-12-23 18:00:37 +01:00
a9a60a24c1 Tweaked asserts 2018-12-23 17:51:50 +01:00
2889a14f86 Build fix for master. 2018-12-21 16:45:24 +01:00
b1cd52b674 Examples: SDL: Avoid testing for SDL_GetKeyboardFocus() on Android and iOS (like Emscripten). (#421) 2018-12-21 16:41:29 +01:00
d5b22fb635 Examples: Setting up style before bindings, so in complex binding (vulkan/dx12) it isn't miles away from the context creation. 2018-12-20 22:58:34 +01:00
b471813f54 Made it illegal to call Begin("") with an empty string. This somehow accidentally worked before but had various undesirable side-effect as the window would have ID zero. In particular it is causing problems in viewport/docking branches. 2018-12-20 20:01:02 +01:00
39dde66b21 IO: Realigned all fields, very minor comments change. This is nearly a no-op if you don't ignore Spaces. 2018-12-20 11:48:52 +01:00
5691385a33 IO: Added BackendPlatformUserData, BackendRendererUserData, BackendLanguageUserData void* for storage use by back-ends. (#2004 + for cimgui) 2018-12-20 11:41:24 +01:00
8399fb5071 Changed ImGuiCol_ChildBg to (0,0,0,0) in Dark style instead of (1,1,1,0), to match other styles. Shouldn't have any effect for the end-user. 2018-12-19 15:20:18 +01:00
6890e08bc5 Fixed using SetNextWindowPos() on a child window (which wasn't really documented) position the cursor as expected in the parent window, so there is no mismatch between the layout in parent and the position of the child window. Demo tweak and adding some child window stuff 2018-12-19 15:19:31 +01:00
89ac0ea7c1 Various user-facing comments 2018-12-19 11:19:55 +01:00
84d1ce3958 Tidying up README, moved entries to FAQ, updated screenshots, removed comma in title. 2018-12-18 16:17:27 +01:00
ca953f0fee Fix merge issue on master. 2018-12-18 15:11:11 +01:00
ae76a1fda7 Window, Focus, Popup: Fixed an issue where closing a popup by clicking another window with the _NoMove flag would refocus the parent window of the popup instead of the newly clicked window. 2018-12-18 15:01:15 +01:00
510ca373a2 Moved setting up NavHideHighlightOneFrame from lower-level ClosePopupToLevel() to CloseCurrentPopup() with an explanation. (Followup on 68d3e139a7) 2018-12-18 14:59:22 +01:00
1a6ec208cc Docs: various updates, rewording, clarifying the purpose of a PR. 2018-12-18 12:02:55 +01:00
65dac02171 Internals: Popups: Renamed CurrentPopupStack to BeginPopupStack which is much less ambiguous. 2018-12-14 18:44:17 +01:00
f6f5c51106 Internals: Popups: EndMenu() calls ClosePopupToLevel(g.CurrentPopupStack.Size) which is more correct. 2018-12-14 18:42:28 +01:00
f1c7596409 Internals: Popup related comments. Renamed the misleading internal ClosePopup() function. Added bool* test to BeginPopupModal in demo. 2018-12-14 18:42:22 +01:00
587506dd57 Tests: Changed prototype of ImGuiTestEngineHook_ItemAdd to match functions called in same spot. Made ButtonBehavior submit fallback item info if ItemAdd() was not called (for resize grips, resize borders, scrollbar, columns, etc.) 2018-12-14 11:27:02 +01:00
8497948ba0 Comments, minor tweaks. 2018-12-13 19:17:36 +01:00
1b263f6ab0 Tabs: Fixed support for drag and drop ImGuiButtonFlags_PressedOnDragDropHold. (#261) incorrectly missing from the merge from Docking branch. 2018-12-11 19:37:22 +01:00
febc3e6aa1 Internals: Windows hidden with HiddenFramesRegular (but NOT HiddenFramesForResize) preserve their SizeContents, so restoring a auto-resize window after it's been hidden by tabs won't reset its size for a frame. Arguable. Let's see how it goes. (Followup to b48e295bddbf965d7382ec5578ed05d2fe601114) 2018-12-11 19:19:12 +01:00
d9a84de9d9 Contents size is preserved while a window collapsed. Fix auto-resizing window losing their size for one frame when uncollapsed. 2018-12-11 19:08:06 +01:00
ccce47c6a2 Demo: Using Tabs in Style Editor and Simple Layout example. + Adding missing early out in About and Documents examples. 2018-12-11 18:10:43 +01:00
5a6b8e00db BeginTabBar: Fix to push the expected ID into the ID stack (instead of a hash's hash). (#261) 2018-12-11 15:22:10 +01:00
95dcc534ed Demo: Fix collateral damage of 54a60aa 2018-12-11 13:25:16 +01:00
54a60aaa40 Added BETA api for Tab Bar/Tabs widgets. (#261, #351) (merged this feature from the from Docking branch so it can be used earlier as as standalone feature)
- Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API.
- Added ImGuiTabBarFlags flags for BeginTabBar().
- Added ImGuiTabItemFlags flags for BeginTabItem().
- Style: Added ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive colors.
- Demo: Added Layout->Tabs demo code.
- Demo: Added "Documents" example app showcasing possible use for tabs.
2018-12-11 12:36:47 +01:00
cc1283fb78 Added ImGuiWindowFlags_UnsavedDocument window flag to append '*' to title without altering the ID, as a convenience to avoid using the ### operator. (merged from Docking branch) 2018-12-11 12:20:48 +01:00
15447f5b7b Using named flags instead of 0 + shallow formatting tweaks from other branches. 2018-12-11 12:14:27 +01:00
9476e07d5a Added io.ConfigWindowsMoveFromTitleBarOnly option. Still is ignored by window with no title bars (often popups). This affects clamping window within the visible area: with this option enabled title bars need to be visible. (#899)
Tweaked default value of style.DisplayWindowPadding from (20,20) to (19,19) so the default style as a value which is the same as the title bar height.
2018-12-10 16:05:30 +01:00
59f3c4fc20 Renamed io.ConfigResizeWindowsFromEdges to io.ConfigWindowsResizeFromEdges and removed its [Beta] mark. Resizing windows from edge is now enabled by default (io.ConfigWindowsResizeFromEdges=true). Note that it only works _if_ the back-end sets ImGuiBackendFlags_HasMouseCursors, which the standard back-end do. 2018-12-10 15:41:01 +01:00
d20e3ee710 Tests: Adding imgui-test engine hooks (experimental) to provide missing widget state to the testing system. 2018-12-10 14:30:41 +01:00
125e62491e Internals: Nav: Added ImGuiNavLayer_ to clarify semantic of previously integer NavLayer values, and not pretend that increment/decrement operators on them super flexible. + Storage tweaks. 2018-12-04 14:34:49 +01:00
b58bd5b311 Version 1.67 WIP + todo notes 2018-12-04 13:49:29 +01:00
fb6ef8b1db Comments, tweak 2018-12-03 23:50:59 +01:00
eb311abc92 Fixed IMGUI_API tag on ImFontAtlas::IsBuilt() preventing to build as DLL on some setups. (#2226) 2018-12-03 17:49:38 +01:00
8d58055a54 Examples: DirectX10/11/12: Made imgui_impl_dx10/dx11/dx12.cpp link d3dcompiler.lib from the .cpp file to ease integration. 2018-12-03 17:47:10 +01:00
10e13dd6bb Version 1.67 WIP (again, this time IMGUI_VERSION_NUM has leeway for another hot-fix). 2018-12-03 12:19:23 +01:00
44 changed files with 3616 additions and 1511 deletions

View File

@ -1,42 +0,0 @@
## How to create an Issue
Hello!
You may use the Issue Tracker to submit bug reports, feature requests or suggestions. You may ask for help or advice as well. However please read this wall of text before doing so. The amount of incomplete or ambiguous requests due to people not following those guidelines is often overwhelming. Please do your best to clarify your request. Thank you!
**IF YOU ARE HAVING AN ISSUE COMPILING/LINKING/RUNNING/DISPLAYING/ADDING FONTS/WIRING INPUTS**
- Please post on the "Getting Started" Discourse forum: https://discourse.dearimgui.org/c/getting-started
**Prerequisites for new users of dear imgui:**
- Please read the FAQ in imgui.cpp.
- Please read misc/fonts/README.txt if your question relates to fonts or text.
- Please run ImGui::ShowDemoWindow() to explore the demo and its sources.
- Please use the Search function of GitHub to look for similar issues. You may also browse issues by tags.
- Please use the Search function of your IDE to search in the code for comments related to your situation.
- If you get a assert, use a debugger to locate the line triggering it and read the comments around the assert.
**Guidelines to report an issue or ask a question:**
- Please provide your imgui version number.
- Please state if you have made substantial modifications to your copy of imgui.
- Try to be explicit with your Goals, your Expectations and what you have Tried. What you have in mind or in your code is not obvious to other people. People frequently discuss problems without first mentioning their goal.
- If you are discussing an assert or a crash, please provide a debugger callstack. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful.
- Please make sure that your compilation settings have asserts enabled. Calls to IM_ASSERT() are scattered in the code to help catch common issues. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application report an error, it means that your asserts are disabled. Please make sure they are enabled.
- When discussing issues related to rendering or inputs, please state the OS/back-end/renderer you are using. Please state if you are using a vanilla copy of the example back-ends (imgui_impl_XXX files), or a modified one, or if you built your own.
- Please provide a Minimal, Complete and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem. An ideal submission includes a small piece of code that anyone can paste in one of the examples/ application (e.g. in main.cpp or imgui_demo.cpp) to understand and reproduce it. Narrowing your problem to its shortest and purest form is the easiest way to understand it. Please test your shortened code to ensure it actually exhibit the problem. Often while creating the MCVE you will end up solving the problem! Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
- Try to attach screenshots to clarify the context. They often convey useful information that are omitted by the description. You can drag pictures/files here (prefer github attachments over 3rd party hosting).
- When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.).
**Some unfortunate words of warning**
- If you are or were involved in cheating schemes (e.g. DLL injection) for competitive online multi-player games, please don't post here. We won't answer and you will be blocked. We've had too many of you.
- Due to frequent abuse of this service from aforementioned users, if your GitHub account is anonymous and was created five minutes ago please understand that your post will receive more scrutiny and incomplete questions may be dismissed.
If you have been using dear imgui for a while or have been using C/C++ for several years or have demonstrated good behavior here, it is ok to not fullfill every item to the letter. Those are guidelines and experienced users or members of the community will know which information are useful in a given context.
## How to create an Pull Request
- When adding a feature, please describe the usage context (how you intend to use it, why you need it, etc.).
- When fixing a warning or compilation problem, please post the compiler log and specify the version and OS you are using.
- Try to attach screenshots to clarify the context and demonstrate the feature at a glance. You can drag pictures/files here (prefer github attachments over 3rd party hosting).
- Make sure your code follows the coding style already used in imgui (spaces instead of tabs, "local_variable", "FunctionName", "MemberName", etc.). We don't use modern C++ idioms and can compile without C++11.
- Make sure you create a branch for the pull request. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits).
Thank you for reading!

View File

@ -1,8 +0,0 @@
- Please read https://github.com/ocornut/imgui/blob/master/.github/CONTRIBUTING.md
- When adding a feature, please describe the usage context (how you intend to use it, why you need it, etc.).
- When adding a feature, try to attach screenshots/gifs to clarify the context and demonstrate the feature at a glance.
- When fixing a warning or compilation problem, post the compiler log and specify the version and OS you are using.
- Make sure your code follows the coding style already used in the codebase (4 spaces identation, no tabs, `type* name`, `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment()`, etc.). We don't use modern C++ idioms, we don't use C++ style cast, we don't use C++ headers, and we can compile without a C++11 compatible compiler.
- Make sure you create a branch for the pull request. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR.
(Clear this form before submitting your PR)

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2018 Omar Cornut
Copyright (c) 2014-2019 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -29,6 +29,69 @@ HOW TO UPDATE?
- Please report any issue!
-----------------------------------------------------------------------
VERSION 1.67 (In Progress)
-----------------------------------------------------------------------
Breaking Changes:
- Made it illegal to call Begin("") with an empty string. This somehow half-worked before but had various undesirable
side-effect because the window would have ID zero. In particular it is causing problems in viewport/docking branches.
- Renamed io.ConfigResizeWindowsFromEdges to io.ConfigWindowsResizeFromEdges and removed its [Beta] mark.
The addition of new configuration options in the Docking branch is pushing for a little reorganization of those names.
- Renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Keep redirection typedef (will obsolete).
Other Changes:
- Added BETA api for Tab Bar/Tabs widgets: (#261, #351)
- Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API.
- Added ImGuiTabBarFlags flags for BeginTabBar().
- Added ImGuiTabItemFlags flags for BeginTabItem().
- Style: Added ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive colors.
- Demo: Added Layout->Tabs demo code.
- Demo: Added "Documents" example app showcasing possible use for tabs.
This feature was merged from the Docking branch in order to allow the use of regular tabs in your code.
(It does not provide the docking/splitting/merging of windows available in the Docking branch)
- Added ImGuiWindowFlags_UnsavedDocument window flag to append '*' to title without altering the ID, as a convenience
to avoid using the ### operator. In the Docking branch this also has an effect on tab closing behavior.
- Window, Focus, Popup: Fixed an issue where closing a popup by clicking another window with the _NoMove flag would refocus
the parent window of the popup instead of the newly clicked window.
- Window: Contents size is preserved while a window collapsed. Fix auto-resizing window losing their size for one frame when uncollapsed.
- Window: Contents size is preserved while a window contents is hidden (unless it is hidden for resizing purpose).
- Window: Resizing windows from edge is now enabled by default (io.ConfigWindowsResizeFromEdges=true). Note that
it only works _if_ the back-end sets ImGuiBackendFlags_HasMouseCursors, which the standard back-ends do.
- Window: Added io.ConfigWindowsMoveFromTitleBarOnly option. This is ignored by window with no title bars (often popups).
This affects clamping window within the visible area: with this option enabled title bars need to be visible. (#899)
- Window: Fixed using SetNextWindowPos() on a child window (which wasn't really documented) position the cursor as expected
in the parent window, so there is no mismatch between the layout in parent and the position of the child window.
- InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257)
- DragFloat: Fixed broken mouse direction change with power!=1.0. (#2174, #2206) [@Joshhua5]
- Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary
keep the focus on the parent window, which could steal it from newly appearing windows. (#787)
- Nav: Fixed animated window titles from being updated when displayed in the CTRL+Tab list. (#787)
- Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function closer
to the user call site (instead of being reported in EndFrame). Past the assert, they don't lead to crashes any more. (#1651)
Missing calls to End(), past the assert, should not lead to crashes or to the fallback Debug window appearing on screen.
Those changes makes it easier to integrate dear imgui with a scripting language allowing, given asserts are redirected
into e.g. an error log and stopping the script execution.
- ImFontAtlas: Stb and FreeType: Atlas width is now properly based on total surface rather than glyph count (unless overridden with TexDesiredWidth).
- ImFontAtlas: Stb and FreeType: Fixed atlas builder so missing glyphs won't influence the atlas texture width. (#2233)
- ImFontAtlas: Stb and FreeType: Fixed atlas builder so duplicate glyphs (when merging fonts) won't be included in the rasterized atlas.
- ImFontAtlas: FreeType: Fixed abnormally high atlas height.
- ImFontAtlas: FreeType: Fixed support for any values of TexGlyphPadding (not just only 1).
- ImDrawList: Optimized some of the functions for performance of debug builds where non-inline function call cost are non-negligible.
(Our test UI scene on VS2015 Debug Win64 with /RTC1 went ~5.9 ms -> ~4.9 ms. In Release same scene stays at ~0.3 ms.)
- IO: Added BackendPlatformUserData, BackendRendererUserData, BackendLanguageUserData void* for storage use by back-ends.
- IO: Renamed InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
- IO: AddInputCharacter() goes into a queue which can receive as many characters as needed during the frame. This is useful
for automation to not have an upper limit on typing speed. Will later transition key/mouse to use the event queue later.
- Style: Tweaked default value of style.DisplayWindowPadding from (20,20) to (19,19) so the default style as a value
which is the same as the title bar height.
- Demo: "Simple Layout" and "Style Editor" are now using tabs.
- Demo: Added a few more things under "Child windows" (changing ImGuiCol_ChildBg, positioning child, using IsItemHovered after a child).
- Examples: DirectX10/11/12: Made imgui_impl_dx10/dx11/dx12.cpp link d3dcompiler.lib from the .cpp file to ease integration.
- Examples: Allegro 5: Properly destroy globals on shutdown to allow for restart. (#2262) [@DomRe]
-----------------------------------------------------------------------
VERSION 1.66b (Released 2018-12-01)
-----------------------------------------------------------------------
@ -681,6 +744,7 @@ Breaking Changes:
- Removed `IsItemRectHovered()`, `IsWindowRectHovered()` recently introduced in 1.51 which were merely the more consistent/correct names for the above functions which are now obsolete anyway. (#1382)
- Changed `IsWindowHovered()` default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. (#1382)
- Renamed imconfig.h's `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS` to `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` for consistency.
- Renamed ImFont::Glyph to ImFontGlyph. Keep redirection typedef (will obsolete).
Other Changes:

View File

@ -1,15 +1,18 @@
dear imgui,
dear imgui
=====
[![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui)
[![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720)
_(This library is free but needs your support to sustain its development. There are many desirable features and maintenance ahead. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. If your company is using dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for technical support, custom development etc. Email: omarcornut at gmail)._
_(This library is free as in freedom, but needs your support to sustain its development. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for invoiced financial support. If you are an individual using dear imgui, please consider donating via Patreon or PayPal.)_
Monthly donations via Patreon:
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via the monthly Patreon:
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui)
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
Businesses: support continued maintenance and development via support contracts or sponsoring:
<br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_
Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
@ -17,7 +20,7 @@ Dear ImGui is designed to enable fast iterations and to empower programmers to c
Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
See [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui), [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Gallery](https://github.com/ocornut/imgui/issues/1902) pages to get an idea of its use cases.
See [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui), [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Gallery](https://github.com/ocornut/imgui/issues/2265) pages to get an idea of its use cases.
Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine:
- imgui.cpp
@ -124,7 +127,8 @@ Languages: (third-party bindings)
- Pascal: [imgui-pas](https://github.com/dpethes/imgui-pas)
- PureBasic: [pb-cimgui](https://github.com/hippyau/pb-cimgui)
- Python [CyImGui](https://github.com/chromy/cyimgui) or [pyimgui](https://github.com/swistakm/pyimgui)
- Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs)
- Ruby: [ruby-imgui](https://github.com/vaiorabbit/ruby-imgui)
- Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs) or [imgui-rust](https://github.com/nsf/imgui-rust)
- Swift [swift-imgui](https://github.com/mnmly/Swift-imgui)
Frameworks:
@ -143,7 +147,7 @@ Frameworks:
- OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c)
- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843)
- LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui)
- Magnum: [magnum-imgui](https://github.com/lecopivo/magnum-imgui), [MagnumImguiPort](https://github.com/lecopivo/MagnumImguiPort)
- Magnum: [ImGuiIntegration](https://doc.magnum.graphics/magnum/namespaceMagnum_1_1ImGuiIntegration.html) ([example](https://doc.magnum.graphics/magnum/examples-imgui.html))
- NanoRT: [syoyo/imgui](https://github.com/syoyo/imgui/tree/nanort)
- Qt3d: [imgui-qt3d](https://github.com/alpqr/imgui-qt3d), QOpenGLWindow [qtimgui](https://github.com/ocornut/imgui/issues/1910)
- SFML: [imgui-sfml](https://github.com/EliasD/imgui-sfml)
@ -158,7 +162,7 @@ Some of the goals for 2019 are:
- Finish work on docking, tabs. (see [#2109](https://github.com/ocornut/imgui/issues/2109), public branch looking for feedback)
- Finish work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), public branch looking for feedback)
- Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
- Add an automation and testing system, both to test the library and end-user apps.
- Add an automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435))
- Make Columns better. (they are currently pretty terrible!)
- Make the examples look better, improve styles, improve font support, make the examples hi-DPI aware.
@ -171,36 +175,21 @@ User screenshots:
<br>[Gallery Part 4](https://github.com/ocornut/imgui/issues/973) (Jan 2017 to Aug 2017)
<br>[Gallery Part 5](https://github.com/ocornut/imgui/issues/1269) (Aug 2017 to Feb 2018)
<br>[Gallery Part 6](https://github.com/ocornut/imgui/issues/1607) (Feb 2018 to June 2018)
<br>[Gallery Part 7](https://github.com/ocornut/imgui/issues/1902) (June 2018 onward)
<br>[Gallery Part 7](https://github.com/ocornut/imgui/issues/1902) (June 2018 to January 2018)
<br>[Gallery Part 8](https://github.com/ocornut/imgui/issues/2265) (January 2018 onward)
<br>Also see the [Mega screenshots](https://github.com/ocornut/imgui/issues/1273) for an idea of the available features.
Various tools
Custom engine
[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
Custom engine
[![screenshot tool](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white_preview.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white.png)
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/v160-misc-classic.png)
Demo window
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png)
[![screenshot profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler-880.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
Dear ImGui can load TTF/OTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with:
Code:
```cpp
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
```
```cpp
ImGui::Text(u8"こんにちは!テスト %d", 123);
if (ImGui::Button(u8"ロード"))
{
// do stuff
}
ImGui::InputText("string", buf, IM_ARRAYSIZE(buf));
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
```
Result:
<br>![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png)
<br>_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_
[Tracy Profiler](https://bitbucket.org/wolfpld/tracy)
![tracy profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/tracy_profiler.png)
References
----------
@ -218,7 +207,7 @@ See the [Wiki](https://github.com/ocornut/imgui/wiki) for more references and [B
Support Forums
--------------
If you have issues with: compiling, linking, adding fonts, running or displaying Dear ImGui, or wiring inputs: please post on the Discourse forum: https://discourse.dearimgui.org.
If you have issues with: compiling, linking, adding fonts, running or displaying Dear ImGui, or wiring inputs: please post on the Discourse forums: https://discourse.dearimgui.org.
For any other questions, bug reports, requests, feedback, you may post on https://github.com/ocornut/imgui/issues. Please read and fill the New Issue template carefully.
@ -243,33 +232,27 @@ You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issue
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) pages for an (incomplete) list of games/software which are publicly known to use dear imgui. Please add yours if you can!
**Why the odd dual naming, "dear imgui" vs "ImGui"?**
**Why the odd dual naming, "Dear ImGui" vs "ImGui"?**
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
**How can I tell whether to dispatch mouse/keyboard to imgui or to my application?**
<br>**How can I display an image? What is ImTextureID, how does it works?**
<br>**How can I have multiple widgets with the same label or without a label? A primer on labels and the ID Stack.**
<br>**How can I have multiple widgets with the same label or with an empty label? A primer on labels and the ID Stack.**
<br>**How can I use my own math types instead of ImVec2/ImVec4?**
<br>**How can I load a different font than the default?**
<br>**How can I easily use icons in my application?**
<br>**How can I load multiple fonts?**
<br>**How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?**
<br>**How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?** ([example](https://github.com/ocornut/imgui/wiki/Loading-Font-Example))
<br>**How can I interact with standard C++ types (such as std::string and std::vector)?**
<br>**How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API)**
<br>**How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)**
<br>**I integrated Dear ImGui in my engine and the text or lines are blurry..**
<br>**I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around..**
<br>**How can I help?**
See the FAQ in imgui.cpp for answers.
**How do you use Dear ImGui on a platform that may not have a mouse or keyboard?**
You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`).
You can share your computer mouse seamlessly with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the preferred solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC using Synergy 1.x. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui).
For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimizing for screen real-estate and precision.
**Can you create elaborate/serious tools with Dear ImGui?**
Yes. People have written game editors, data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library.
@ -291,30 +274,39 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci
Support dear imgui
------------------
**How can I help?**
- You may participate in the [Discourse forums](https://discourse.dearimgui.org) and the GitHub [issues tracker](https://github.com/ocornut/imgui/issues).
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it.
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
- Convince your company to financially support this project.
**How can I help financing further development of Dear ImGui?**
Your contributions are keeping the library alive. If you are an individual using dear imgui, please consider donating to enable me to spend more time improving the library.
Your contributions are keeping this project alive. The library is free as in freedom, but continued maintenance and development are a full-time endeavor. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for financial support. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. Thank you!
Monthly donations via Patreon:
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via the monthly Patreon:
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui)
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
Ongoing dear imgui development is financially supported on [**Patreon**](http://www.patreon.com/imgui) and by private sponsors.
If your company uses dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development. I can also invoice for private support, custom development etc. contact me for details: omarcornut at gmail). Thanks!
Businesses: support continued maintenance and development via support contracts or sponsoring:
<br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_
Ongoing dear imgui development is financially supported by users and private sponsors (past and present):
**Platinum-chocolate sponsors**
- Blizzard Entertainment.
- **Blizzard Entertainment**.
**Double-chocolate sponsors**
- Media Molecule, Mobigame, Insomniac Games, Aras Pranckevičius, Lizardcube, Greggman, DotEmu, Nadeo, Supercell, Runner.
- Media Molecule, Mobigame, Insomniac Games, Aras Pranckevičius, Lizardcube, Greggman, DotEmu, Nadeo, Supercell, Runner, Aiden Koss, Kylotonn.
**Salty caramel supporters**
- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts.
- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc.
**Caramel supporters**
- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Astrofra, Jonas Lehmann, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa.
- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Astrofra, Jonas Lehmann, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos.
And all other supporters; THANK YOU!
(Please contact me if you would like to be added or removed from this list)
@ -324,7 +316,7 @@ Credits
Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect contributors to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com).
I first discovered imgui principles at [Q-Games](http://www.q-games.com) where Atman had dropped his own simple imgui implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating on it.
I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating on it.
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).

View File

@ -8,16 +8,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- doc/test: add a proper documentation+regression testing system (#435)
- doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.).
- doc/tips: tips of the day: website? applet in imgui_club?
- project: folder or separate repository with maintained helpers (e.g. imgui_memory_editor.h, imgui_stl.h, maybe imgui_dock would be there?)
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
- window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify.
- window: allow resizing of child windows (possibly given min/max for each axis?.)
- window: background options for child windows, border option (disable rounding).
- window: resizing from any sides? done. > need backends to honor mouse cursors properly. (#822)
- window: resize from borders: support some form of outer padding to make it easier to grab borders. (#822)
- window: fix resize glitch when collapsing an AlwaysAutoResize window.
- window: begin with *p_open == false could return false.
- window: get size/pos helpers given names (see discussion in #249)
- window: a collapsed window can be stuck behind the main menu bar?
@ -28,8 +24,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- window: expose contents size. (#1045)
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
- window: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate.
- window: investigate better auto-positioning for new windows.
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate.
- window/child: the first draw command of a child window could be moved into the current draw command of the parent window (unless child+tooltip?).
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
- scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse)
- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet.
- scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro)
- scrolling/style: shadows on scrollable areas to denote that there is more contents
@ -74,6 +73,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
- input text: what's the easiest way to implement a nice IP/Mac address input editor?
- input text: Global callback system so user can plug in an expression evaluator easily.
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: support for cut/paste without selection (cut/paste the current line)
- input text multi-line: line numbers? status bar? (follow up on #200)
@ -96,7 +96,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
- columns: add a conditional parameter to SetColumnOffset() (#513, #125)
- columns: headers. reorderable. (#513, #125)
- columns: headers. re-orderable. (#513, #125)
- columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-criteria. notify user when sort order changed.
- columns: option to alternate background colors on odd/even scanlines.
- columns: allow columns to recurse.
@ -123,14 +123,15 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- dock: docking extension
- dock: merge docking branch (#2109)
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
- tabs: re-ordering, close buttons, context menu, persistent order (#261, #351)
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
- ext: stl-ish friendly extension (imgui_stl.h) that has wrapper for std::string, std::vector etc.
- button: provide a button that looks framed.
- button: provide a button that looks framed. (?)
- image/image button: misalignment on padded/bordered button?
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
- image button: not taking an explicit id is odd.
@ -142,7 +143,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- slider: step option (#1183)
- slider style: fill % of the bar instead of positioning a drag.
- knob: rotating knob widget (#942)
- drag float: power/logarithmic slider and drags are weird. (#1316)
- drag float: up/down axis
- drag float: power != 0.0f with current value being outside the the range keeps the value stuck.
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- combo: use clipper: make it easier to disable clipper with a single flag.
@ -198,7 +201,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437)
- stb: add defines to disable stb implementations
!- style: better default styles. (#707)
- style: better default styles. (#707)
- style: add a highlighted text color (for headers, etc.)
- style: border types: out-screen, in-screen, etc. (#447)
- style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier)
@ -219,6 +222,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725)
- drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov.
- drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725)
- drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637)
@ -231,9 +235,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- pie menus patterns (#434)
- markup: simple markup language for color change? (#902)
!- font: need handling of missing glyphs by not packing/rasterizing glyph 0 of a given font.
- font: MergeMode: flags to select overwriting or not.
- font: MergeMode: duplicate glyphs are stored in the atlas texture which is suboptimal.
- font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype)
- font: free the Alpha buffer if user only requested RGBA.
!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y
@ -241,6 +243,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data
- font: PushFontSize API (#1018)
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
- font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs.
- font/demo: demonstrate use of ImFontGlyphRangesBuilder.
- font/atlas: add a missing Glyphs.reserve()
- font/atlas: incremental updates
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
@ -248,13 +252,16 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
- font/draw: need to be able to specify wrap start position.
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines)
- font: imgui_freetype.h alternative renderer (#618)
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct).
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before font has been built.
- font: (api breaking) removed "TTF" from symbol names. also because it now supports OTF.
- font: what would it take to support codepoint higher than 0xFFFF? (smileys, etc.)
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
- nav: patterns to make it possible for arrows key to update selection
- nav: restore/find nearest navid when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
@ -266,8 +273,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child
- nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..).
- nav: Left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?)
- nav: menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons.
- nav: menus: allow pressing Menu to leave a sub-menu.
- nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons.
- nav/menus: allow pressing Menu to leave a sub-menu.
- nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB)
- nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it?
- nav: simulate right-click or context activation? (SHIFT+F10)
- nav: tabs should go through most/all widgets (in submission order?).
- nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
@ -285,13 +294,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
- misc: idle refresh: expose cursor blink animation timer for backend to be able to lower framerate.
- misc: idle: expose "woken up" boolean (set by inputs) and/or animation time (for cursor blink) for back-end to be able stop refreshing easily.
- misc: idle: if cursor blink if the _only_ visible animation, core imgui could rewrite vertex alpha to avoid CPU pass on ImGui:: calls.
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
- misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
- misc: use more size_t in public api?
- misc: ImVector: erase_unsorted() helper
- misc: imgui_cpp: perhaps a misc/ header file with more friendly helper (e.g. type-infer versions of DragScalar, vector<> variants if appropriate for some functions).
- backend: bgfx? https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
- web/emscriptem: refactor some examples to facilitate integration with emscripten main loop system. (#1713, #336)
@ -302,7 +310,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- demo: find a way to demonstrate textures in the examples application, as it such a a common issue for new users.
- demo: add vertical separator demo
- demo: add virtual scrolling example?
- demo: demonstration Plot offset
- demo: demonstrate Plot offset
- examples: window minimize, maximize (#583)
- examples: provide a zero frame-rate/idle example.
- examples: apple: example_apple should be using modern GL3.
@ -310,6 +318,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038)
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
- optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
- optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering.
- optimization: use another hash function than crc32, e.g. FNV1a
- optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
- optimization: turn some the various stack vectors into statically-sized arrays

View File

@ -1,11 +1,12 @@
(Click "Preview" to turn any http URL into a clickable link)
1. IF YOU ARE HAVING AN ISSUE COMPILING/LINKING/RUNNING/DISPLAYING/ADDING FONTS/WIRING INPUTS, please post on the "Getting Started" Discourse forum:
1. PLEASE CAREFULLY READ:
https://github.com/ocornut/imgui/issues/2261
2. IF YOU ARE HAVING AN ISSUE COMPILING/LINKING/RUNNING/DISPLAYING/ADDING FONTS, please post on the "Getting Started" Discourse forum:
https://discourse.dearimgui.org/c/getting-started
2. You may use this Issue Tracker to ask for help and submit bug reports, feature requests or suggestions that don't fit in any category of (1). PLEASE CAREFULLY READ THE CONTRIBUTING DOCUMENT before submitting any issue: https://github.com/ocornut/imgui/blob/master/.github/CONTRIBUTING.md
3. PLEASE MAKE SURE that you have: read the FAQ in imgui.cpp; explored the contents of ShowDemoWindow() including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the CONTRIBUTING.md file linked above.
3. PLEASE MAKE SURE that you have: read the FAQ in imgui.cpp; explored the contents of ShowDemoWindow() including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the link provided in (1).
4. Delete points 1-4 and PLEASE FILL THE TEMPLATE BELOW before submitting your issue.
@ -21,19 +22,21 @@ Branch: XXX _(master/viewport/docking/etc.)_
**Back-end/Renderer/Compiler/OS**
Back-ends: imgui_impl_XXX.cpp + imgui_impl_XXX.cpp _(or specify if using a custom engine/back-end)_
Compiler: XXX _(if the question is related to building)_
Compiler: XXX _(if the question is related to building or platform specific features)_
Operating System: XXX
**My Issue/Question:** _(please provide context)_
**My Issue/Question:**
XXX
XXX _(please provide as much context as possible)_
**Standalone, minimal, complete and verifiable example:** _(see CONTRIBUTING.md)_
**Screenshots/Video**
XXX _(you can drag files here)_
**Standalone, minimal, complete and verifiable example:** _(see https://github.com/ocornut/imgui/issues/2261)_
```
// Please do not forget this!
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
```
**Screenshots/Video** _(you can drag files here)_

View File

@ -0,0 +1,6 @@
(Click "Preview" to turn any http URL into a clickable link)
PLEASE CAREFULLY READ:
https://github.com/ocornut/imgui/issues/2261
(Clear this template before submitting your PR)

View File

@ -28,13 +28,13 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Platform/Renderer bindings
ImGui_ImplAllegro5_Init(display);
// Setup Style
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplAllegro5_Init(display);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -26,11 +26,9 @@
IMGUI_CHECKVERSION();
ImGui::CreateContext();
(void)ImGui::GetIO();
ImGui_ImplMetal_Init(_device);
ImGui::StyleColorsDark();
ImGui_ImplMetal_Init(_device);
}
return self;

View File

@ -231,14 +231,16 @@
TargetAttributes = {
8307E7C320E9F9C900473790 = {
CreatedOnToolsVersion = 9.4.1;
ProvisioningStyle = Automatic;
};
8307E7D920E9F9C900473790 = {
CreatedOnToolsVersion = 9.4.1;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 8307E7B920E9F9C700473790 /* Build configuration list for PBXProject "example_apple_metal" */;
compatibilityVersion = "Xcode 9.3";
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@ -444,10 +446,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
PRODUCT_NAME = example_apple_metal;
SDKROOT = iphoneos;
@ -463,10 +462,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
PRODUCT_NAME = example_apple_metal;
SDKROOT = iphoneos;
@ -483,11 +479,8 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
PRODUCT_NAME = example_apple_metal;
SDKROOT = macosx;
@ -502,11 +495,8 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
PRODUCT_NAME = example_apple_metal;
SDKROOT = macosx;

View File

@ -135,11 +135,12 @@
TargetAttributes = {
4080A96A20B029B00036BA46 = {
CreatedOnToolsVersion = 9.3.1;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl2" */;
compatibilityVersion = "Xcode 9.3";
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@ -286,6 +287,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_NAME = "$(TARGET_NAME)";
SYSTEM_HEADER_SEARCH_PATHS = ../libs/gl3w;
USER_HEADER_SEARCH_PATHS = ../..;
@ -296,6 +298,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_NAME = "$(TARGET_NAME)";
SYSTEM_HEADER_SEARCH_PATHS = ../libs/gl3w;
USER_HEADER_SEARCH_PATHS = ../..;

View File

@ -243,14 +243,14 @@
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplOSX_Init();
ImGui_ImplOpenGL2_Init();
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -100,15 +100,15 @@ int main(int argc, char** argv)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplFreeGLUT_Init();
ImGui_ImplFreeGLUT_InstallFuncs();
ImGui_ImplOpenGL2_Init();
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -43,14 +43,14 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL2_Init();
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -89,14 +89,14 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -357,6 +357,10 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForVulkan(window, true);
ImGui_ImplVulkan_InitInfo init_info = {};
@ -371,10 +375,6 @@ int main(int, char**)
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -22,13 +22,13 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Platform/Renderer bindings
ImGui_Marmalade_Init(true);
// Setup Style
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_Marmalade_Init(true);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -40,14 +40,14 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL2_Init();
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -80,14 +80,14 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -338,6 +338,10 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForVulkan(window);
ImGui_ImplVulkan_InitInfo init_info = {};
@ -352,10 +356,6 @@ int main(int, char**)
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -116,14 +116,14 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX10_Init(g_pd3dDevice);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -119,14 +119,14 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -292,6 +292,10 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT,
@ -299,10 +303,6 @@ int main(int, char**)
g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(),
g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -81,14 +81,14 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX9_Init(g_pd3dDevice);
// Setup Style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.

View File

@ -280,9 +280,14 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
void ImGui_ImplAllegro5_Shutdown()
{
ImGui_ImplAllegro5_InvalidateDeviceObjects();
g_Display = NULL;
// Destroy last known clipboard data
g_Display = NULL;
g_Time = 0.0;
if (g_VertexDecl)
al_destroy_vertex_decl(g_VertexDecl);
g_VertexDecl = NULL;
if (g_ClipboardTextData)
al_free(g_ClipboardTextData);
g_ClipboardTextData = NULL;

View File

@ -10,6 +10,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions.
// 2018-06-08: Misc: Extracted imgui_impl_dx10.cpp/.h away from the old combined DX10+Win32 example.
@ -27,6 +28,9 @@
#include <d3d10_1.h>
#include <d3d10.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
static ID3D10Device* g_pd3dDevice = NULL;

View File

@ -10,6 +10,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
@ -26,6 +27,9 @@
#include <stdio.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
static ID3D11Device* g_pd3dDevice = NULL;

View File

@ -12,6 +12,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData().
// 2018-06-08: Misc: Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example.
@ -25,6 +26,9 @@
#include <d3d12.h>
#include <dxgi1_4.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
static ID3D12Device* g_pd3dDevice = NULL;

View File

@ -1,6 +1,7 @@
// dear imgui: Platform Binding for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// (Requires: GLFW 3.1+)
// Implemented features:
// [X] Platform: Clipboard support.
@ -267,9 +268,9 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
void ImGui_ImplGlfw_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt()); // Font atlas needs to be built, call renderer _NewFrame() function e.g. ImGui_ImplOpenGL3_NewFrame()
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// Setup display size
// Setup display size (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(g_Window, &w, &h);

View File

@ -17,7 +17,7 @@
#include "imgui_impl_metal.h"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
// #import <QuartzCore/CAMetalLayer.h> // Not suported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...)
#import <simd/simd.h>
#pragma mark - Support classes

View File

@ -1,6 +1,7 @@
// dear imgui: Platform Binding for SDL2
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
// (Requires: SDL 2.0. Prefer SDL 2.0.4+ for full feature support.)
// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
@ -16,6 +17,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'.
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
@ -42,10 +44,12 @@
// (the multi-viewports feature requires SDL features supported from SDL 2.0.5+)
#include <SDL.h>
#include <SDL_syswm.h>
#if defined(__APPLE__)
#include "TargetConditionals.h"
#endif
#define SDL_HAS_CAPTURE_MOUSE SDL_VERSION_ATLEAST(2,0,4)
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE SDL_VERSION_ATLEAST(2,0,4)
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
#define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH SDL_VERSION_ATLEAST(2,0,5)
#if !SDL_HAS_VULKAN
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
#endif
@ -182,9 +186,9 @@ bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
{
#if !SDL_HAS_VULKAN
#if !SDL_HAS_VULKAN
IM_ASSERT(0 && "Unsupported");
#endif
#endif
return ImGui_ImplSDL2_Init(window);
}
@ -220,7 +224,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false;
#if SDL_HAS_CAPTURE_MOUSE && !defined(__EMSCRIPTEN__)
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)
SDL_Window* focused_window = SDL_GetKeyboardFocus();
if (g_Window == focused_window)
{
@ -267,7 +271,7 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt()); // Font atlas needs to be built, call renderer _NewFrame() function e.g. ImGui_ImplOpenGL3_NewFrame()
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// Setup display size (every frame to accommodate for window resizing)
int w, h;

View File

@ -142,6 +142,7 @@ static void ImGui_ImplWin32_UpdateMousePos()
void ImGui_ImplWin32_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// Setup display size (every frame to accommodate for window resizing)
RECT rect;

814
imgui.cpp

File diff suppressed because it is too large Load Diff

590
imgui.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.66b
// dear imgui, v1.67
// (drawing and font code)
/*
@ -12,7 +12,8 @@ Index of this file:
// [SECTION] Helpers ShadeVertsXXX functions
// [SECTION] ImFontConfig
// [SECTION] ImFontAtlas
// [SECTION] ImFontAtlas glyph ranges helpers + GlyphRangesBuilder
// [SECTION] ImFontAtlas glyph ranges helpers
// [SECTION] ImFontGlyphRangesBuilder
// [SECTION] ImFont
// [SECTION] Internal Render Helpers
// [SECTION] Decompression code
@ -56,6 +57,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
#if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here //
#endif
@ -63,7 +65,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@ -175,7 +177,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f);
colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
@ -205,6 +207,11 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -255,6 +262,11 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -306,6 +318,11 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
@ -640,7 +657,13 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
_IdxWritePtr += 6;
}
// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds.
// Those macros expects l-values.
#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } }
#define IM_NORMALIZE2F_OVER_EPSILON_CLAMP(VX,VY,EPS,INVLENMAX) { float d2 = VX*VX + VY*VY; if (d2 > EPS) { float inv_len = 1.0f / ImSqrt(d2); if (inv_len > INVLENMAX) inv_len = INVLENMAX; VX *= inv_len; VY *= inv_len; } }
// 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)
{
if (points_count < 2)
@ -670,10 +693,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
for (int i1 = 0; i1 < count; i1++)
{
const int i2 = (i1+1) == points_count ? 0 : i1+1;
ImVec2 diff = points[i2] - points[i1];
diff *= ImInvLength(diff, 1.0f);
temp_normals[i1].x = diff.y;
temp_normals[i1].y = -diff.x;
float dx = points[i2].x - points[i1].x;
float dy = points[i2].y - points[i1].y;
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
temp_normals[i1].x = dy;
temp_normals[i1].y = -dx;
}
if (!closed)
temp_normals[points_count-1] = temp_normals[points_count-2];
@ -696,17 +720,18 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3;
// Average normals
ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
float dmr2 = dm.x*dm.x + dm.y*dm.y;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 100.0f) scale = 100.0f;
dm *= scale;
}
dm *= AA_SIZE;
temp_points[i2*2+0] = points[i2] + dm;
temp_points[i2*2+1] = points[i2] - dm;
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f)
dm_x *= AA_SIZE;
dm_y *= AA_SIZE;
// Add temporary vertexes
ImVec2* out_vtx = &temp_points[i2*2];
out_vtx[0].x = points[i2].x + dm_x;
out_vtx[0].y = points[i2].y + dm_y;
out_vtx[1].x = points[i2].x - dm_x;
out_vtx[1].y = points[i2].y - dm_y;
// Add indexes
_IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
@ -750,20 +775,24 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4;
// Average normals
ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
float dmr2 = dm.x*dm.x + dm.y*dm.y;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 100.0f) scale = 100.0f;
dm *= scale;
}
ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE);
ImVec2 dm_in = dm * half_inner_thickness;
temp_points[i2*4+0] = points[i2] + dm_out;
temp_points[i2*4+1] = points[i2] + dm_in;
temp_points[i2*4+2] = points[i2] - dm_in;
temp_points[i2*4+3] = points[i2] - dm_out;
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f);
float dm_out_x = dm_x * (half_inner_thickness + AA_SIZE);
float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE);
float dm_in_x = dm_x * half_inner_thickness;
float dm_in_y = dm_y * half_inner_thickness;
// Add temporary vertexes
ImVec2* out_vtx = &temp_points[i2*4];
out_vtx[0].x = points[i2].x + dm_out_x;
out_vtx[0].y = points[i2].y + dm_out_y;
out_vtx[1].x = points[i2].x + dm_in_x;
out_vtx[1].y = points[i2].y + dm_in_y;
out_vtx[2].x = points[i2].x - dm_in_x;
out_vtx[2].y = points[i2].y - dm_in_y;
out_vtx[3].x = points[i2].x - dm_out_x;
out_vtx[3].y = points[i2].y - dm_out_y;
// Add indexes
_IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
@ -801,11 +830,13 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
const int i2 = (i1+1) == points_count ? 0 : i1+1;
const ImVec2& p1 = points[i1];
const ImVec2& p2 = points[i2];
ImVec2 diff = p2 - p1;
diff *= ImInvLength(diff, 1.0f);
const float dx = diff.x * (thickness * 0.5f);
const float dy = diff.y * (thickness * 0.5f);
float dx = p2.x - p1.x;
float dy = p2.y - p1.y;
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
dx *= (thickness * 0.5f);
dy *= (thickness * 0.5f);
_VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col;
@ -820,6 +851,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
}
}
// We intentionally avoid using ImVec2 and its math operators here to reduce cost to a minimum for debug/non-inlined builds.
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
{
if (points_count < 3)
@ -851,10 +883,11 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
{
const ImVec2& p0 = points[i0];
const ImVec2& p1 = points[i1];
ImVec2 diff = p1 - p0;
diff *= ImInvLength(diff, 1.0f);
temp_normals[i0].x = diff.y;
temp_normals[i0].y = -diff.x;
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
temp_normals[i0].x = dy;
temp_normals[i0].y = -dx;
}
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
@ -862,19 +895,15 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
// Average normals
const ImVec2& n0 = temp_normals[i0];
const ImVec2& n1 = temp_normals[i1];
ImVec2 dm = (n0 + n1) * 0.5f;
float dmr2 = dm.x*dm.x + dm.y*dm.y;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 100.0f) scale = 100.0f;
dm *= scale;
}
dm *= AA_SIZE * 0.5f;
float dm_x = (n0.x + n1.x) * 0.5f;
float dm_y = (n0.y + n1.y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f);
dm_x *= AA_SIZE * 0.5f;
dm_y *= AA_SIZE * 0.5f;
// Add vertices
_VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
_VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
_VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
_VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
_VtxWritePtr += 2;
// Add indexes for fringes
@ -1513,11 +1542,11 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
if (!font_cfg->MergeMode)
Fonts.push_back(IM_NEW(ImFont));
else
IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
IM_ASSERT(!Fonts.empty() && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
ConfigData.push_back(*font_cfg);
ImFontConfig& new_font_cfg = ConfigData.back();
if (!new_font_cfg.DstFont)
if (new_font_cfg.DstFont == NULL)
new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.FontDataOwnedByAtlas)
{
@ -1705,139 +1734,220 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
data[i] = table[data[i]];
}
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
struct ImFontBuildSrcData
{
stbtt_fontinfo FontInfo;
stbtt_pack_range PackRange; // Hold the list of codepoints to pack (essentially points to Codepoints.Data)
stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position.
stbtt_packedchar* PackedChars; // Output glyphs
const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF)
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
int GlyphsHighest; // Highest requested codepoint
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
ImBoolVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
ImVector<int> GlyphsList; // Glyph codepoints list (flattened version of GlyphsMap)
};
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
struct ImFontBuildDstData
{
int SrcCount; // Number of source fonts targeting this destination font.
int GlyphsHighest;
int GlyphsCount;
ImBoolVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
};
static void UnpackBoolVectorToFlatIndexList(const ImBoolVector* in, ImVector<int>* out)
{
IM_ASSERT(sizeof(in->Storage.Data[0]) == sizeof(int));
const int* it_begin = in->Storage.begin();
const int* it_end = in->Storage.end();
for (const int* it = it_begin; it < it_end; it++)
if (int entries_32 = *it)
for (int bit_n = 0; bit_n < 32; bit_n++)
if (entries_32 & (1 << bit_n))
out->push_back((int)((it - it_begin) << 5) + bit_n);
}
bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
ImFontAtlasBuildRegisterDefaultCustomRects(atlas);
// Clear atlas
atlas->TexID = (ImTextureID)NULL;
atlas->TexWidth = atlas->TexHeight = 0;
atlas->TexUvScale = ImVec2(0.0f, 0.0f);
atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
atlas->ClearTexData();
// Count glyphs/ranges
int total_glyphs_count = 0;
int total_ranges_count = 0;
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// Temporary storage for building
ImVector<ImFontBuildSrcData> src_tmp_array;
ImVector<ImFontBuildDstData> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
dst_tmp_array.resize(atlas->Fonts.Size);
memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
// 1. Initialize font loading structure, check font data validity
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
if (!cfg.GlyphRanges)
cfg.GlyphRanges = atlas->GetGlyphRangesDefault();
for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++)
total_glyphs_count += (in_range[1] - in_range[0]) + 1;
}
// We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish.
// Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512;
atlas->TexHeight = 0;
// Start packing
const int max_tex_height = 1024*32;
stbtt_pack_context spc = {};
if (!stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL))
return false;
stbtt_PackSetOversampling(&spc, 1, 1);
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info);
// Initialize font information (so we can error without any cleanup)
struct ImFontTempBuildData
{
stbtt_fontinfo FontInfo;
stbrp_rect* Rects;
int RectsCount;
stbtt_pack_range* Ranges;
int RangesCount;
};
ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)atlas->ConfigData.Size * sizeof(ImFontTempBuildData));
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
ImFontTempBuildData& tmp = tmp_array[input_i];
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
src_tmp.DstIndex = -1;
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
if (src_tmp.DstIndex == -1)
return false;
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
{
atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure
ImGui::MemFree(tmp_array);
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
return false;
}
// Measure highest codepoints
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
dst_tmp.SrcCount++;
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
}
// 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs.
int total_glyphs_count = 0;
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
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())
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)
continue;
if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font?
continue;
// Add to avail set/counters
src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++;
}
}
// 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another)
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
UnpackBoolVectorToFlatIndexList(&src_tmp.GlyphsSet, &src_tmp.GlyphsList);
src_tmp.GlyphsSet.Clear();
IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
}
for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++)
dst_tmp_array[dst_i].GlyphsSet.Clear();
dst_tmp_array.clear();
// Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0;
stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbtt_packedchar));
stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbrp_rect));
stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_ranges_count * sizeof(stbtt_pack_range));
memset(buf_packedchars, 0, total_glyphs_count * sizeof(stbtt_packedchar));
memset(buf_rects, 0, total_glyphs_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity.
memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range));
// (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity)
ImVector<stbrp_rect> buf_rects;
ImVector<stbtt_packedchar> buf_packedchars;
buf_rects.resize(total_glyphs_count);
buf_packedchars.resize(total_glyphs_count);
memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes());
memset(buf_packedchars.Data, 0, (size_t)buf_packedchars.size_in_bytes());
// First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point)
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// 4. Gather glyphs sizes so we can pack them in our virtual canvas.
int total_surface = 0;
int buf_rects_out_n = 0;
int buf_packedchars_out_n = 0;
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
ImFontTempBuildData& tmp = tmp_array[input_i];
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
// Setup ranges
int font_glyphs_count = 0;
int font_ranges_count = 0;
for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, font_ranges_count++)
font_glyphs_count += (in_range[1] - in_range[0]) + 1;
tmp.Ranges = buf_ranges + buf_ranges_n;
tmp.RangesCount = font_ranges_count;
buf_ranges_n += font_ranges_count;
for (int i = 0; i < font_ranges_count; i++)
src_tmp.Rects = &buf_rects[buf_rects_out_n];
src_tmp.PackedChars = &buf_packedchars[buf_packedchars_out_n];
buf_rects_out_n += src_tmp.GlyphsCount;
buf_packedchars_out_n += src_tmp.GlyphsCount;
// Convert our ranges in the format stb_truetype wants
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.PackRange.font_size = cfg.SizePixels;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH;
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels);
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
{
const ImWchar* in_range = &cfg.GlyphRanges[i * 2];
stbtt_pack_range& range = tmp.Ranges[i];
range.font_size = cfg.SizePixels;
range.first_unicode_codepoint_in_range = in_range[0];
range.num_chars = (in_range[1] - in_range[0]) + 1;
range.chardata_for_range = buf_packedchars + buf_packedchars_n;
buf_packedchars_n += range.num_chars;
}
// Gather the sizes of all rectangle we need
tmp.Rects = buf_rects + buf_rects_n;
tmp.RectsCount = font_glyphs_count;
buf_rects_n += font_glyphs_count;
stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV);
int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects);
IM_ASSERT(n == font_glyphs_count);
// Detect missing glyphs and replace them with a zero-sized box instead of relying on the default glyphs
// This allows us merging overlapping icon fonts more easily.
int rect_i = 0;
for (int range_i = 0; range_i < tmp.RangesCount; range_i++)
for (int char_i = 0; char_i < tmp.Ranges[range_i].num_chars; char_i++, rect_i++)
if (stbtt_FindGlyphIndex(&tmp.FontInfo, tmp.Ranges[range_i].first_unicode_codepoint_in_range + char_i) == 0)
tmp.Rects[rect_i].w = tmp.Rects[rect_i].h = 0;
// Pack
stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n);
// Extend texture height
// Also mark missing glyphs as non-packed so we don't attempt to render into them
for (int i = 0; i < n; i++)
{
if (tmp.Rects[i].w == 0 && tmp.Rects[i].h == 0)
tmp.Rects[i].was_packed = 0;
if (tmp.Rects[i].was_packed)
atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h);
int x0, y0, x1, y1;
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
IM_ASSERT(glyph_index_in_font != 0);
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + padding + cfg.OversampleH - 1);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + padding + cfg.OversampleV - 1);
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
}
}
IM_ASSERT(buf_rects_n == total_glyphs_count);
IM_ASSERT(buf_packedchars_n == total_glyphs_count);
IM_ASSERT(buf_ranges_n == total_ranges_count);
// Create texture
// We need a width for the skyline algorithm, any width!
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
// User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface.
const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1;
atlas->TexHeight = 0;
if (atlas->TexDesiredWidth > 0)
atlas->TexWidth = atlas->TexDesiredWidth;
else
atlas->TexWidth = (surface_sqrt >= 4096*0.7f) ? 4096 : (surface_sqrt >= 2048*0.7f) ? 2048 : (surface_sqrt >= 1024*0.7f) ? 1024 : 512;
// 5. Start packing
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
const int TEX_HEIGHT_MAX = 1024 * 32;
stbtt_pack_context spc = {};
stbtt_PackBegin(&spc, NULL, atlas->TexWidth, TEX_HEIGHT_MAX, 0, atlas->TexGlyphPadding, NULL);
ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info);
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
stbrp_pack_rects((stbrp_context*)spc.pack_info, src_tmp.Rects, src_tmp.GlyphsCount);
// Extend texture height and mark missing glyphs as non-packed so we won't render them.
// FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?)
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
if (src_tmp.Rects[glyph_i].was_packed)
atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h);
}
// 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight);
@ -1845,41 +1955,46 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
spc.pixels = atlas->TexPixelsAlpha8;
spc.height = atlas->TexHeight;
// Second pass: render font characters
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// 8. Render/rasterize font characters into the texture
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
ImFontTempBuildData& tmp = tmp_array[input_i];
stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV);
stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects);
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
stbtt_PackFontRangesRenderIntoRects(&spc, &src_tmp.FontInfo, &src_tmp.PackRange, 1, src_tmp.Rects);
// Apply multiply operator
if (cfg.RasterizerMultiply != 1.0f)
{
unsigned char multiply_table[256];
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
for (const stbrp_rect* r = tmp.Rects; r != tmp.Rects + tmp.RectsCount; r++)
stbrp_rect* r = &src_tmp.Rects[0];
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++, r++)
if (r->was_packed)
ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, spc.pixels, r->x, r->y, r->w, r->h, spc.stride_in_bytes);
ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, atlas->TexPixelsAlpha8, r->x, r->y, r->w, r->h, atlas->TexWidth * 1);
}
tmp.Rects = NULL;
src_tmp.Rects = NULL;
}
// End packing
stbtt_PackEnd(&spc);
ImGui::MemFree(buf_rects);
buf_rects = NULL;
buf_rects.clear();
// Third pass: setup ImFont and glyphs for runtime
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// 9. Setup ImFont and glyphs for runtime
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
ImFontTempBuildData& tmp = tmp_array[input_i];
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
if (cfg.MergeMode)
dst_font->BuildLookupTable();
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels);
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels);
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
const float ascent = ImFloor(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
@ -1887,40 +2002,30 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f);
for (int i = 0; i < tmp.RangesCount; i++)
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{
stbtt_pack_range& range = tmp.Ranges[i];
for (int char_idx = 0; char_idx < range.num_chars; char_idx += 1)
{
const stbtt_packedchar& pc = range.chardata_for_range[char_idx];
if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1)
continue;
const int codepoint = src_tmp.GlyphsList[glyph_i];
const stbtt_packedchar& pc = src_tmp.PackedChars[glyph_i];
const int codepoint = range.first_unicode_codepoint_in_range + char_idx;
if (cfg.MergeMode && dst_font->FindGlyphNoFallback((ImWchar)codepoint))
continue;
float char_advance_x_org = pc.xadvance;
float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
float char_off_x = font_off_x;
if (char_advance_x_org != char_advance_x_mod)
char_off_x += cfg.PixelSnapH ? (float)(int)((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
stbtt_aligned_quad q;
float dummy_x = 0.0f, dummy_y = 0.0f;
stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0);
dst_font->AddGlyph((ImWchar)codepoint, q.x0 + char_off_x, q.y0 + font_off_y, q.x1 + char_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, char_advance_x_mod);
}
const float char_advance_x_org = pc.xadvance;
const float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
float char_off_x = font_off_x;
if (char_advance_x_org != char_advance_x_mod)
char_off_x += cfg.PixelSnapH ? (float)(int)((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
// Register glyph
stbtt_aligned_quad q;
float dummy_x = 0.0f, dummy_y = 0.0f;
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &dummy_x, &dummy_y, &q, 0);
dst_font->AddGlyph((ImWchar)codepoint, q.x0 + char_off_x, q.y0 + font_off_y, q.x1 + char_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, char_advance_x_mod);
}
}
// Cleanup temporaries
ImGui::MemFree(buf_packedchars);
ImGui::MemFree(buf_ranges);
ImGui::MemFree(tmp_array);
// Cleanup temporary (ImVector doesn't honor destructor)
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
src_tmp_array[src_i].~ImFontBuildSrcData();
ImFontAtlasBuildFinish(atlas);
return true;
}
@ -1948,16 +2053,16 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
font->ConfigDataCount++;
}
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaque)
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
{
stbrp_context* pack_context = (stbrp_context*)pack_context_opaque;
stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque;
ImVector<ImFontAtlas::CustomRect>& user_rects = atlas->CustomRects;
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
ImVector<stbrp_rect> pack_rects;
pack_rects.resize(user_rects.Size);
memset(pack_rects.Data, 0, sizeof(stbrp_rect) * user_rects.Size);
memset(pack_rects.Data, 0, (size_t)pack_rects.size_in_bytes());
for (int i = 0; i < user_rects.Size; i++)
{
pack_rects[i].w = user_rects[i].Width;
@ -2077,7 +2182,7 @@ static void UnpackAccumulativeOffsetsIntoRanges(int base_codepoint, const short*
}
//-------------------------------------------------------------------------
// [SECTION] ImFontAtlas glyph ranges helpers + GlyphRangesBuilder
// [SECTION] ImFontAtlas glyph ranges helpers
//-------------------------------------------------------------------------
const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
@ -2085,7 +2190,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
// Store 2500 regularly used characters for Simplified Chinese.
// Sourced from https://zh.wiktionary.org/wiki/%E9%99%84%E5%BD%95:%E7%8E%B0%E4%BB%A3%E6%B1%89%E8%AF%AD%E5%B8%B8%E7%94%A8%E5%AD%97%E8%A1%A8
// This table covers 97.97% of all characters used during the month in July, 1987.
// You can use ImFontAtlas::GlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
// You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
// (Stored as accumulative offsets from the initial unicode codepoint 0x4E00. This encoding is designed to helps us compact the source code size.)
static const short accumulative_offsets_from_0x4E00[] =
{
@ -2151,7 +2256,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
// 1946 common ideograms code points for Japanese
// Sourced from http://theinstructionlimit.com/common-kanji-character-ranges-for-xna-spritefont-rendering
// FIXME: Source a list of the revised 2136 Joyo Kanji list from 2010 and rebuild this.
// You can use ImFontAtlas::GlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
// You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
// (Stored as accumulative offsets from the initial unicode codepoint 0x4E00. This encoding is designed to helps us compact the source code size.)
static const short accumulative_offsets_from_0x4E00[] =
{
@ -2229,7 +2334,11 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai()
return &ranges[0];
}
void ImFontAtlas::GlyphRangesBuilder::AddText(const char* text, const char* text_end)
//-----------------------------------------------------------------------------
// [SECTION] ImFontGlyphRangesBuilder
//-----------------------------------------------------------------------------
void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end)
{
while (text_end ? (text < text_end) : *text)
{
@ -2243,14 +2352,14 @@ void ImFontAtlas::GlyphRangesBuilder::AddText(const char* text, const char* text
}
}
void ImFontAtlas::GlyphRangesBuilder::AddRanges(const ImWchar* ranges)
void ImFontGlyphRangesBuilder::AddRanges(const ImWchar* ranges)
{
for (; ranges[0]; ranges += 2)
for (ImWchar c = ranges[0]; c <= ranges[1]; c++)
AddChar(c);
}
void ImFontAtlas::GlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
{
for (int n = 0; n < 0x10000; n++)
if (GetBit(n))
@ -2402,7 +2511,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const
{
if (c >= IndexLookup.Size)
return FallbackGlyph;
const ImWchar i = IndexLookup[c];
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
return FallbackGlyph;
return &Glyphs.Data[i];
@ -2412,7 +2521,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
{
if (c >= IndexLookup.Size)
return NULL;
const ImWchar i = IndexLookup[c];
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
return NULL;
return &Glyphs.Data[i];
@ -2472,7 +2581,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
}
}
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX);
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX);
if (ImCharIsBlankW(c))
{
if (inside_word)
@ -2589,7 +2698,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
continue;
}
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale;
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale;
if (line_width + char_width >= max_width)
{
s = prev_s;
@ -2821,6 +2930,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
// - RenderMouseCursor()
// - RenderArrowPointingAt()
// - RenderRectFilledRangeH()
// - RenderPixelEllipsis()
//-----------------------------------------------------------------------------
void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor)
@ -2929,6 +3039,16 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
draw_list->PathFillConvex(col);
}
// FIXME: Rendering an ellipsis "..." is a surprisingly tricky problem for us... we cannot rely on font glyph having it,
// and regular dot are typically too wide. If we render a dot/shape ourselves it comes with the risk that it wouldn't match
// the boldness or positioning of what the font uses...
void ImGui::RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col)
{
ImFont* font = draw_list->_Data->Font;
pos.y += (float)(int)(font->DisplayOffset.y + font->Ascent + 0.5f - 1.0f);
for (int dot_n = 0; dot_n < count; dot_n++)
draw_list->AddRectFilled(ImVec2(pos.x + dot_n * 2.0f, pos.y), ImVec2(pos.x + dot_n * 2.0f + 1.0f, pos.y + 1.0f), col);
}
//-----------------------------------------------------------------------------
// [SECTION] Decompression code

View File

@ -1,4 +1,4 @@
// dear imgui, v1.66b
// dear imgui, v1.67
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -6,8 +6,27 @@
// #define IMGUI_DEFINE_MATH_OPERATORS
// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
/*
Index of this file:
// Header mess
// Forward declarations
// STB libraries includes
// Context pointer
// Generic helpers
// Misc data structures
// Main imgui context
// Tab bar, tab item
// Internal API
*/
#pragma once
//-----------------------------------------------------------------------------
// Header mess
//-----------------------------------------------------------------------------
#ifndef IMGUI_VERSION
#error Must include imgui.h before imgui_internal.h
#endif
@ -24,13 +43,17 @@
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion"
#endif
#endif
//-----------------------------------------------------------------------------
// Forward Declarations
// Forward declarations
//-----------------------------------------------------------------------------
struct ImRect; // An axis-aligned rectangle (2 points)
@ -49,6 +72,8 @@ struct ImGuiNextWindowData; // Storage for SetNexWindow** functions
struct ImGuiPopupRef; // Storage for current popup stack
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
struct ImGuiTabBar; // Storage for a tab bar
struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
struct ImGuiWindow; // Storage for one window
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame)
struct ImGuiWindowSettings; // Storage for window settings stored in .ini file (we keep one of those even if the actual window wasn't instanced during this session)
@ -66,7 +91,7 @@ typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags:
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
//-------------------------------------------------------------------------
// STB libraries
// STB libraries includes
//-------------------------------------------------------------------------
namespace ImGuiStb
@ -82,7 +107,7 @@ namespace ImGuiStb
} // namespace ImGuiStb
//-----------------------------------------------------------------------------
// Context
// Context pointer
//-----------------------------------------------------------------------------
#ifndef GImGui
@ -90,7 +115,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
#endif
//-----------------------------------------------------------------------------
// Helpers
// Generic helpers
//-----------------------------------------------------------------------------
#define IM_PI 3.14159265358979323846f
@ -99,6 +124,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
#else
#define IM_NEWLINE "\n"
#endif
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
@ -140,6 +166,7 @@ IMGUI_API int ImStricmp(const char* str1, const char* str2);
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count);
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count);
IMGUI_API char* ImStrdup(const char* str);
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str);
IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
IMGUI_API int ImStrlenW(const ImWchar* str);
IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line
@ -213,6 +240,18 @@ static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a)
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
// Helper: ImBoolVector. Store 1-bit per value.
// Note that Resize() currently clears the whole vector.
struct ImBoolVector
{
ImVector<int> Storage;
ImBoolVector() { }
void Resize(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
void Clear() { Storage.clear(); }
bool GetBit(int n) const { int off = (n >> 5); int mask = 1 << (n & 31); return (Storage[off] & mask) != 0; }
void SetBit(int n, bool v) { int off = (n >> 5); int mask = 1 << (n & 31); if (v) Storage[off] |= mask; else Storage[off] &= ~mask; }
};
// Helper: ImPool<>. Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a dense/hot buffer,
// Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object.
typedef int ImPoolIdx;
@ -238,15 +277,15 @@ struct IMGUI_API ImPool
};
//-----------------------------------------------------------------------------
// Types
// Misc data structures
//-----------------------------------------------------------------------------
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D and maintenance of some patches)
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
struct ImVec1
{
float x;
ImVec1() { x = 0.0f; }
ImVec1(float _x) { x = _x; }
float x;
ImVec1() { x = 0.0f; }
ImVec1(float _x) { x = _x; }
};
enum ImGuiButtonFlags_
@ -314,15 +353,25 @@ enum ImGuiItemStatusFlags_
ImGuiItemStatusFlags_HoveredRect = 1 << 0,
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1,
ImGuiItemStatusFlags_Edited = 1 << 2 // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
#ifdef IMGUI_ENABLE_TEST_ENGINE
, // [imgui-test only]
ImGuiItemStatusFlags_Openable = 1 << 10, //
ImGuiItemStatusFlags_Opened = 1 << 11, //
ImGuiItemStatusFlags_Checkable = 1 << 12, //
ImGuiItemStatusFlags_Checked = 1 << 13 //
#endif
};
// FIXME: this is in development, not exposed/functional as a generic feature yet.
// Horizontal/Vertical enums are fixed to 0/1 so they may be used to index ImVec2
enum ImGuiLayoutType_
{
ImGuiLayoutType_Vertical,
ImGuiLayoutType_Horizontal
ImGuiLayoutType_Horizontal = 0,
ImGuiLayoutType_Vertical = 1
};
// X/Y enums are fixed to 0/1 so they may be used to index ImVec2
enum ImGuiAxis
{
ImGuiAxis_None = -1,
@ -392,6 +441,13 @@ enum ImGuiNavForward
ImGuiNavForward_ForwardActive
};
enum ImGuiNavLayer
{
ImGuiNavLayer_Main = 0, // Main scrolling layer
ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu)
ImGuiNavLayer_COUNT
};
enum ImGuiPopupPositionPolicy
{
ImGuiPopupPositionPolicy_Default,
@ -664,11 +720,21 @@ struct ImGuiNextWindowData
}
};
struct ImGuiTabBarSortItem
{
int Index;
float Width;
};
//-----------------------------------------------------------------------------
// Main imgui context
//-----------------------------------------------------------------------------
struct ImGuiContext
{
bool Initialized;
bool FrameScopeActive; // Set by NewFrame(), cleared by EndFrame()/Render()
bool FrameScopeActive; // Set by NewFrame(), cleared by EndFrame()
bool FrameScopePushedImplicitWindow; // Set by NewFrame(), cleared by EndFrame()
bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
ImGuiIO IO;
ImGuiStyle Style;
@ -717,7 +783,7 @@ struct ImGuiContext
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
ImVector<ImGuiPopupRef> OpenPopupStack; // Which popups are open (persistent)
ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame)
ImVector<ImGuiPopupRef> BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions
ImGuiCond NextTreeNodeOpenCond;
@ -741,7 +807,7 @@ struct ImGuiContext
float NavWindowingTimer;
float NavWindowingHighlightAlpha;
bool NavWindowingToggleLayer;
int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later.
ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later.
int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid
bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
@ -786,6 +852,11 @@ struct ImGuiContext
ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly
unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads
// Tab bars
ImPool<ImGuiTabBar> TabBars;
ImVector<ImGuiTabBar*> CurrentTabBar;
ImVector<ImGuiTabBarSortItem> TabSortByWidthBuffer;
// Widget state
ImGuiInputTextState InputTextState;
ImFont InputTextPasswordFont;
@ -798,6 +869,8 @@ struct ImGuiContext
ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
int TooltipOverrideCount;
ImVector<char> PrivateClipboard; // If no custom clipboard handler is defined
// Platform support
ImVec2 PlatformImePos, PlatformImeLastPos; // Cursor position request & last passed to the OS Input Method Editor
// Settings
@ -826,7 +899,7 @@ struct ImGuiContext
ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL)
{
Initialized = false;
FrameScopeActive = false;
FrameScopeActive = FrameScopePushedImplicitWindow = false;
Font = NULL;
FontSize = FontBaseSize = 0.0f;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
@ -872,7 +945,7 @@ struct ImGuiContext
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingList = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false;
NavLayer = 0;
NavLayer = ImGuiNavLayer_Main;
NavIdTabCounter = INT_MAX;
NavIdIsAlive = false;
NavMousePosDirty = false;
@ -961,12 +1034,12 @@ struct IMGUI_API ImGuiWindowTempData
ImGuiItemStatusFlags LastItemStatusFlags;
ImRect LastItemRect; // Interaction rect
ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect)
bool NavHideHighlightOneFrame;
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
int NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
int NavLayerCurrentMask; // = (1 << NavLayerCurrent) used by ItemAdd prior to clipping.
int NavLayerActiveMask; // Which layer have been written to (result from previous frame)
int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame)
bool NavHideHighlightOneFrame;
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
bool MenuBarAppending; // FIXME: Remove this
ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs.
ImVector<ImGuiWindow*> ChildWindows;
@ -982,7 +1055,7 @@ struct IMGUI_API ImGuiWindowTempData
ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack;
ImVector<ImGuiGroupData>GroupStack;
int StackSizesBackup[6]; // Store size of various stacks for asserting
short StackSizesBackup[6]; // Store size of various stacks for asserting
ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
ImVec1 GroupOffset;
@ -1000,11 +1073,11 @@ struct IMGUI_API ImGuiWindowTempData
LastItemId = 0;
LastItemStatusFlags = 0;
LastItemRect = LastItemDisplayRect = ImRect();
NavLayerActiveMask = NavLayerActiveMaskNext = 0x00;
NavLayerCurrent = ImGuiNavLayer_Main;
NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
NavHideHighlightOneFrame = false;
NavHasScroll = false;
NavLayerActiveMask = NavLayerActiveMaskNext = 0x00;
NavLayerCurrent = 0;
NavLayerCurrentMask = 1 << 0;
MenuBarAppending = false;
MenuBarOffset = ImVec2(0.0f, 0.0f);
StateStorage = NULL;
@ -1036,6 +1109,7 @@ struct IMGUI_API ImGuiWindow
ImVec2 WindowPadding; // Window padding at the time of begin.
float WindowRounding; // Window rounding at the time of begin.
float WindowBorderSize; // Window border size at the time of begin.
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
ImGuiID MoveId; // == window->GetID("#MOVE")
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
ImVec2 Scroll;
@ -1052,9 +1126,9 @@ struct IMGUI_API ImGuiWindow
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
bool Hidden; // Do not display (== (HiddenFramesForResize > 0) ||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
short BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
short BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
int AutoFitFramesX, AutoFitFramesY;
bool AutoFitOnlyGrows;
@ -1090,8 +1164,8 @@ struct IMGUI_API ImGuiWindow
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.)
ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1)
ImRect NavRectRel[2]; // Reference rectangle, in window relative space
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space
// Navigation / Focus
// FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext
@ -1134,6 +1208,59 @@ struct ImGuiItemHoveredDataBackup
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; }
};
//-----------------------------------------------------------------------------
// Tab bar, tab item
//-----------------------------------------------------------------------------
enum ImGuiTabBarFlagsPrivate_
{
ImGuiTabBarFlags_DockNode = 1 << 20, // [Docking: Unused in Master Branch] Part of a dock node
ImGuiTabBarFlags_DockNodeIsDockSpace = 1 << 21, // [Docking: Unused in Master Branch] Part of an explicit dockspace node node
ImGuiTabBarFlags_IsFocused = 1 << 22,
ImGuiTabBarFlags_SaveSettings = 1 << 23 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs
};
// Storage for one active tab item (sizeof() 26~32 bytes)
struct ImGuiTabItem
{
ImGuiID ID;
ImGuiTabItemFlags Flags;
int LastFrameVisible;
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
float Offset; // Position relative to beginning of tab
float Width; // Width currently displayed
float WidthContents; // Width of actual contents, stored during BeginTabItem() call
ImGuiTabItem() { ID = Flags = 0; LastFrameVisible = LastFrameSelected = -1; Offset = Width = WidthContents = 0.0f; }
};
// Storage for a tab bar (sizeof() 92~96 bytes)
struct ImGuiTabBar
{
ImVector<ImGuiTabItem> Tabs;
ImGuiID ID; // Zero for tab-bars used by docking
ImGuiID SelectedTabId; // Selected tab
ImGuiID NextSelectedTabId;
ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for CTRL+TAB preview)
int CurrFrameVisible;
int PrevFrameVisible;
ImRect BarRect;
float ContentsHeight;
float OffsetMax; // Distance from BarRect.Min.x, locked during layout
float OffsetNextTab; // Distance from BarRect.Min.x, incremented with each BeginTabItem() call, not used if ImGuiTabBarFlags_Reorderable if set.
float ScrollingAnim;
float ScrollingTarget;
ImGuiTabBarFlags Flags;
ImGuiID ReorderRequestTabId;
int ReorderRequestDir;
bool WantLayout;
bool VisibleTabWasSubmitted;
short LastTabItemIdx; // For BeginTabItem()/EndTabItem()
ImGuiTabBar();
int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); }
};
//-----------------------------------------------------------------------------
// Internal API
// No guarantee of forward compatibility here.
@ -1163,6 +1290,7 @@ namespace ImGui
IMGUI_API float GetWindowScrollMaxX(ImGuiWindow* window);
IMGUI_API float GetWindowScrollMaxY(ImGuiWindow* window);
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window);
IMGUI_API void SetCurrentFont(ImFont* font);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
@ -1173,7 +1301,8 @@ namespace ImGui
// NewFrame
IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
IMGUI_API void UpdateMouseMovingWindow();
IMGUI_API void UpdateMouseMovingWindowNewFrame();
IMGUI_API void UpdateMouseMovingWindowEndFrame();
// Settings
IMGUI_API void MarkIniSettingsDirty();
@ -1210,10 +1339,9 @@ namespace ImGui
// Popups, Modals, Tooltips
IMGUI_API void OpenPopupEx(ImGuiID id);
IMGUI_API void ClosePopup(ImGuiID id);
IMGUI_API void ClosePopupToLevel(int remaining);
IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window);
IMGUI_API bool IsPopupOpen(ImGuiID id);
IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack!
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
IMGUI_API ImGuiWindow* GetFrontMostPopupModal();
@ -1249,12 +1377,24 @@ namespace ImGui
IMGUI_API void EndColumns(); // close columns
IMGUI_API void PushColumnClipRect(int column_index = -1);
// Tab Bars
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
IMGUI_API void TabBarQueueChangeTabOrder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir);
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags);
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button);
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
IMGUI_API bool TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, const char* label, ImGuiID tab_id, ImGuiID close_button_id);
// Render helpers
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
// NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL);
IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
@ -1269,6 +1409,7 @@ namespace ImGui
IMGUI_API void RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor = ImGuiMouseCursor_Arrow);
IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
IMGUI_API void RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col);
// Widgets
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
@ -1317,11 +1458,23 @@ namespace ImGui
IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
// Test engine hooks (imgui-test)
//#define IMGUI_ENABLE_TEST_ENGINE
#ifdef IMGUI_ENABLE_TEST_ENGINE
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, int flags);
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register status flags
#else
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) do { } while (0)
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif

File diff suppressed because it is too large Load Diff

View File

@ -119,8 +119,8 @@ Mind the fact that some graphics drivers have texture size limitation.
If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
Some solutions:
- 1) Reduce glyphs ranges by calculating them from source localization data. You can use ImFont::GlyphRangesBuilder for this purpose,
this will be the biggest win.
- 1) Reduce glyphs ranges by calculating them from source localization data.
You can use ImFontGlyphRangesBuilder for this purpose, this will be the biggest win!
- 2) You may reduce oversampling, e.g. config.OversampleH = config.OversampleV = 1, this will largely reduce your texture size.
- 3) Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function).
- 4) Set io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight; to disable rounding the texture height to the next power of two.
@ -177,11 +177,11 @@ Also note that correct sRGB space blending will have an important effect on your
BUILDING CUSTOM GLYPH RANGES
---------------------------------------
You can use the ImFontAtlas::GlyphRangesBuilder helper to create glyph ranges based on text input.
You can use the ImFontGlyphRangesBuilder helper to create glyph ranges based on text input.
For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
ImVector<ImWchar> ranges;
ImFontAtlas::GlyphRangesBuilder builder;
ImFontGlyphRangesBuilder builder;
builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters)
builder.AddChar(0x7262); // Add a specific character
builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges

View File

@ -1,14 +1,14 @@
# imgui_freetype
This is an attempt to replace stb_truetype (the default imgui's font rasterizer) with FreeType.
Currently not optimal and probably has some limitations or bugs.
By [Vuhdo](https://github.com/Vuhdo) (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut.
Build font atlases using FreeType instead of stb_truetype (the default imgui's font rasterizer).
<br>by @vuhdo, @mikesart, @ocornut.
**Usage**
1. Get latest FreeType binaries or build yourself.
### Usage
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`).
2. Add imgui_freetype.h/cpp alongside your imgui sources.
3. Include imgui_freetype.h after imgui.h.
4. Call ImGuiFreeType::BuildFontAtlas() *BEFORE* calling ImFontAtlas::GetTexDataAsRGBA32() or ImFontAtlas::Build() (so normal Build() won't be called):
4. Call `ImGuiFreeType::BuildFontAtlas()` *BEFORE* calling `ImFontAtlas::GetTexDataAsRGBA32()` or `ImFontAtlas::Build()` (so normal Build() won't be called):
```cpp
// See ImGuiFreeType::RasterizationFlags
@ -17,13 +17,14 @@ ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
```
**Gamma Correct Blending**
### Gamma Correct Blending
FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
The default imgui styles will be impacted by this change (alpha values will need tweaking).
**Test code Usage**
### Test code Usage
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
@ -42,16 +43,15 @@ while (true)
if (freetype_test.UpdateRebuild())
{
// REUPLOAD FONT TEXTURE TO GPU
// e.g ImGui_ImplGlfwGL3_InvalidateDeviceObjects() + ImGui_ImplGlfwGL3_CreateDeviceObjects()
// e.g ImGui_ImplOpenGL3_DestroyDeviceObjects() + ImGui_ImplOpenGL3_CreateDeviceObjects()
}
ImGui::NewFrame();
freetype_test.ShowFreetypeOptionsWindow();
...
}
}
```
**Test code**
### Test code
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
@ -61,7 +61,7 @@ struct FreeTypeTest
enum FontBuildMode
{
FontBuildMode_FreeType,
FontBuildMode_Stb,
FontBuildMode_Stb
};
FontBuildMode BuildMode;
@ -120,14 +120,7 @@ struct FreeTypeTest
};
```
**Known issues**
- Output texture has excessive resolution (lots of vertical waste).
### Known issues
- FreeType's memory allocator is not overridden.
- `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).
**Obligatory comparison screenshots**
Using Windows built-in segoeui.ttf font. Open in new browser tabs, view at 1080p+.
![freetype rasterizer](https://raw.githubusercontent.com/wiki/ocornut/imgui_club/images/freetype_20170817.png)

View File

@ -1,6 +1,6 @@
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
// Wrapper to use FreeType (instead of stb_truetype) for Dear ImGui
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @Vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained and v0.60+ by @ocornut.
// Changelog:
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
@ -10,6 +10,7 @@
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// Gamma Correct Blending:
// FreeType assumes blending in linear space rather than gamma space.
@ -17,18 +18,16 @@
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// The default imgui styles will be impacted by this change (alpha values will need tweaking).
// TODO:
// - Output texture has excessive resolution (lots of vertical waste).
// - FreeType's memory allocator is not overridden.
// - cfg.OversampleH, OversampleV are ignored (but perhaps not so necessary with this rasterizer).
// FIXME: FreeType's memory allocator is not overridden.
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
#include "imgui_freetype.h"
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
#include <stdint.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_SYNTHESIS_H
#include FT_FREETYPE_H // <freetype/freetype.h>
#include FT_GLYPH_H // <freetype/ftglyph.h>
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
#ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
@ -74,15 +73,15 @@ namespace
/// A structure that describe a glyph.
struct GlyphInfo
{
float Width; // Glyph's width in pixels.
float Height; // Glyph's height in pixels.
float OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
float OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
int Width; // Glyph's width in pixels.
int Height; // Glyph's height in pixels.
FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
};
// Font parameters and metrics.
struct FontInfo
struct FontInfo
{
uint32_t PixelHeight; // Size this font was generated with.
float Ascender; // The pixel extents above the baseline in pixels (typically positive).
@ -96,82 +95,80 @@ namespace
// NB: No ctor/dtor, explicitly call Init()/Shutdown()
struct FreeTypeFont
{
bool Init(const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
void Shutdown();
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
bool CalcGlyphInfo(uint32_t codepoint, GlyphInfo& glyph_info, FT_Glyph& ft_glyph, FT_BitmapGlyph& ft_bitmap);
void BlitGlyph(FT_BitmapGlyph ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
void CloseFont();
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
~FreeTypeFont() { CloseFont(); }
// [Internals]
FontInfo Info; // Font descriptor of the current font.
FT_Face Face;
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
FT_Library FreetypeLibrary;
FT_Face FreetypeFace;
FT_Int32 FreetypeLoadFlags;
FT_Int32 LoadFlags;
};
// From SDL_ttf: Handy routines for converting from fixed point
#define FT_CEIL(X) (((X + 63) & -64) / 64)
bool FreeTypeFont::Init(const ImFontConfig& cfg, unsigned int extra_user_flags)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
{
// FIXME: substitute allocator
FT_Error error = FT_Init_FreeType(&FreetypeLibrary);
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
if (error != 0)
return false;
error = FT_New_Memory_Face(FreetypeLibrary, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &FreetypeFace);
if (error != 0)
return false;
error = FT_Select_Charmap(FreetypeFace, FT_ENCODING_UNICODE);
error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
if (error != 0)
return false;
memset(&Info, 0, sizeof(Info));
SetPixelHeight((uint32_t)cfg.SizePixels);
// Convert to freetype flags (nb: Bold and Oblique are processed separately)
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
UserFlags = cfg.RasterizerFlags | extra_user_flags;
FreetypeLoadFlags = FT_LOAD_NO_BITMAP;
if (UserFlags & ImGuiFreeType::NoHinting) FreetypeLoadFlags |= FT_LOAD_NO_HINTING;
if (UserFlags & ImGuiFreeType::NoAutoHint) FreetypeLoadFlags |= FT_LOAD_NO_AUTOHINT;
if (UserFlags & ImGuiFreeType::ForceAutoHint) FreetypeLoadFlags |= FT_LOAD_FORCE_AUTOHINT;
if (UserFlags & ImGuiFreeType::LightHinting)
FreetypeLoadFlags |= FT_LOAD_TARGET_LIGHT;
else if (UserFlags & ImGuiFreeType::MonoHinting)
FreetypeLoadFlags |= FT_LOAD_TARGET_MONO;
LoadFlags = FT_LOAD_NO_BITMAP;
if (UserFlags & ImGuiFreeType::NoHinting)
LoadFlags |= FT_LOAD_NO_HINTING;
if (UserFlags & ImGuiFreeType::NoAutoHint)
LoadFlags |= FT_LOAD_NO_AUTOHINT;
if (UserFlags & ImGuiFreeType::ForceAutoHint)
LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
if (UserFlags & ImGuiFreeType::LightHinting)
LoadFlags |= FT_LOAD_TARGET_LIGHT;
else if (UserFlags & ImGuiFreeType::MonoHinting)
LoadFlags |= FT_LOAD_TARGET_MONO;
else
FreetypeLoadFlags |= FT_LOAD_TARGET_NORMAL;
LoadFlags |= FT_LOAD_TARGET_NORMAL;
return true;
}
void FreeTypeFont::Shutdown()
void FreeTypeFont::CloseFont()
{
if (FreetypeFace)
if (Face)
{
FT_Done_Face(FreetypeFace);
FreetypeFace = NULL;
FT_Done_FreeType(FreetypeLibrary);
FreetypeLibrary = NULL;
FT_Done_Face(Face);
Face = NULL;
}
}
void FreeTypeFont::SetPixelHeight(int pixel_height)
{
// I'm not sure how to deal with font sizes properly.
// As far as I understand, currently ImGui assumes that the 'pixel_height' is a maximum height of an any given glyph,
// i.e. it's the sum of font's ascender and descender. Seems strange to me.
// Vuhdo: I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
// NB: FT_Set_Pixel_Sizes() doesn't seem to get us the same result.
FT_Size_RequestRec req;
req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
req.width = 0;
req.height = (uint32_t)pixel_height * 64;
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(FreetypeFace, &req);
FT_Request_Size(Face, &req);
// update font info
FT_Size_Metrics metrics = FreetypeFace->size->metrics;
// Update font info
FT_Size_Metrics metrics = Face->size->metrics;
Info.PixelHeight = (uint32_t)pixel_height;
Info.Ascender = (float)FT_CEIL(metrics.ascender);
Info.Descender = (float)FT_CEIL(metrics.descender);
@ -180,52 +177,58 @@ namespace
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance);
}
bool FreeTypeFont::CalcGlyphInfo(uint32_t codepoint, GlyphInfo &glyph_info, FT_Glyph& ft_glyph, FT_BitmapGlyph& ft_bitmap)
const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
{
uint32_t glyph_index = FT_Get_Char_Index(FreetypeFace, codepoint);
uint32_t glyph_index = FT_Get_Char_Index(Face, codepoint);
if (glyph_index == 0)
return false;
FT_Error error = FT_Load_Glyph(FreetypeFace, glyph_index, FreetypeLoadFlags);
return NULL;
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
if (error)
return false;
return NULL;
// Need an outline for this to work
FT_GlyphSlot slot = FreetypeFace->glyph;
FT_GlyphSlot slot = Face->glyph;
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
if (UserFlags & ImGuiFreeType::Bold)
FT_GlyphSlot_Embolden(slot);
if (UserFlags & ImGuiFreeType::Oblique)
{
FT_GlyphSlot_Oblique(slot);
//FT_BBox bbox;
//FT_Outline_Get_BBox(&slot->outline, &bbox);
//slot->metrics.width = bbox.xMax - bbox.xMin;
//slot->metrics.height = bbox.yMax - bbox.yMin;
}
// Retrieve the glyph
error = FT_Get_Glyph(slot, &ft_glyph);
if (error != 0)
return false;
// Rasterize
error = FT_Glyph_To_Bitmap(&ft_glyph, FT_RENDER_MODE_NORMAL, NULL, true);
if (error != 0)
return false;
ft_bitmap = (FT_BitmapGlyph)ft_glyph;
glyph_info.AdvanceX = (float)FT_CEIL(slot->advance.x);
glyph_info.OffsetX = (float)ft_bitmap->left;
glyph_info.OffsetY = -(float)ft_bitmap->top;
glyph_info.Width = (float)ft_bitmap->bitmap.width;
glyph_info.Height = (float)ft_bitmap->bitmap.rows;
return true;
return &slot->metrics;
}
void FreeTypeFont::BlitGlyph(FT_BitmapGlyph ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
{
FT_GlyphSlot slot = Face->glyph;
FT_Error error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
if (error != 0)
return NULL;
FT_Bitmap* ft_bitmap = &Face->glyph->bitmap;
out_glyph_info->Width = (int)ft_bitmap->width;
out_glyph_info->Height = (int)ft_bitmap->rows;
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
return ft_bitmap;
}
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
{
IM_ASSERT(ft_bitmap != NULL);
const uint32_t w = ft_bitmap->bitmap.width;
const uint32_t h = ft_bitmap->bitmap.rows;
const uint8_t* src = ft_bitmap->bitmap.buffer;
const uint32_t src_pitch = ft_bitmap->bitmap.pitch;
const uint32_t w = ft_bitmap->width;
const uint32_t h = ft_bitmap->rows;
const uint8_t* src = ft_bitmap->buffer;
const uint32_t src_pitch = ft_bitmap->pitch;
if (multiply_table == NULL)
{
@ -246,143 +249,332 @@ namespace
#define STB_RECT_PACK_IMPLEMENTATION
#include "imstb_rectpack.h"
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
struct ImFontBuildSrcGlyphFT
{
GlyphInfo Info;
uint32_t Codepoint;
unsigned char* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
};
struct ImFontBuildSrcDataFT
{
FreeTypeFont Font;
stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position.
const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF)
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
int GlyphsHighest; // Highest requested codepoint
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
ImBoolVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
ImVector<ImFontBuildSrcGlyphFT> GlyphsList;
};
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
struct ImFontBuildDstDataFT
{
int SrcCount; // Number of source fonts targeting this destination font.
int GlyphsHighest;
int GlyphsCount;
ImBoolVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
};
bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
IM_ASSERT(atlas->TexGlyphPadding == 1); // Not supported
ImFontAtlasBuildRegisterDefaultCustomRects(atlas);
atlas->TexID = NULL;
// Clear atlas
atlas->TexID = (ImTextureID)NULL;
atlas->TexWidth = atlas->TexHeight = 0;
atlas->TexUvScale = ImVec2(0.0f, 0.0f);
atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
atlas->ClearTexData();
ImVector<FreeTypeFont> fonts;
fonts.resize(atlas->ConfigData.Size);
// Temporary storage for building
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
dst_tmp_array.resize(atlas->Fonts.Size);
memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
ImVec2 max_glyph_size(1.0f, 1.0f);
// Count glyphs/ranges, initialize font
int total_glyphs_count = 0;
int total_ranges_count = 0;
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// 1. Initialize font loading structure, check font data validity
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
FreeTypeFont& font_face = fonts[input_i];
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
FreeTypeFont& font_face = src_tmp.Font;
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
if (!font_face.Init(cfg, extra_flags))
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
src_tmp.DstIndex = -1;
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
if (src_tmp.DstIndex == -1)
return false;
max_glyph_size.x = ImMax(max_glyph_size.x, font_face.Info.MaxAdvanceWidth);
max_glyph_size.y = ImMax(max_glyph_size.y, font_face.Info.Ascender - font_face.Info.Descender);
// Load font
if (!font_face.InitFont(ft_library, cfg, extra_flags))
return false;
if (!cfg.GlyphRanges)
cfg.GlyphRanges = atlas->GetGlyphRangesDefault();
for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[ 1 ]; in_range += 2, total_ranges_count++)
total_glyphs_count += (in_range[1] - in_range[0]) + 1;
// Measure highest codepoints
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
dst_tmp.SrcCount++;
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
}
// We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish.
// Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512;
// 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs.
int total_glyphs_count = 0;
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
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())
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
// We don't do the original first pass to determine texture height, but just rough estimate.
// Looks ugly inaccurate and excessive, but AFAIK with FreeType we actually need to render glyphs to get exact sizes.
// Alternatively, we could just render all glyphs into a big shadow buffer, get their sizes, do the rectangle packing and just copy back from the
// shadow buffer to the texture buffer. Will give us an accurate texture height, but eat a lot of temp memory. Probably no one will notice.)
const int total_rects = total_glyphs_count + atlas->CustomRects.size();
float min_rects_per_row = ceilf((atlas->TexWidth / (max_glyph_size.x + 1.0f)));
float min_rects_per_column = ceilf(total_rects / min_rects_per_row);
atlas->TexHeight = (int)(min_rects_per_column * (max_glyph_size.y + 1.0f));
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)
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)
continue;
// Create texture
// Add to avail set/counters
src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++;
}
}
// 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another)
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(int));
const int* it_begin = src_tmp.GlyphsSet.Storage.begin();
const int* it_end = src_tmp.GlyphsSet.Storage.end();
for (const int* it = it_begin; it < it_end; it++)
if (int entries_32 = *it)
for (int bit_n = 0; bit_n < 32; bit_n++)
if (entries_32 & (1 << bit_n))
{
ImFontBuildSrcGlyphFT src_glyph;
memset(&src_glyph, 0, sizeof(src_glyph));
src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
//src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
src_tmp.GlyphsList.push_back(src_glyph);
}
src_tmp.GlyphsSet.Clear();
IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
}
for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++)
dst_tmp_array[dst_i].GlyphsSet.Clear();
dst_tmp_array.clear();
// Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
// (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity)
ImVector<stbrp_rect> buf_rects;
buf_rects.resize(total_glyphs_count);
memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes());
// Allocate temporary rasterization data buffers.
// We could not find a way to retrieve accurate glyph size without rendering them.
// (e.g. slot->metrics->width not always matching bitmap->width, especially considering the Oblique transform)
// We allocate in chunks of 256 KB to not waste too much extra memory ahead. Hopefully users of FreeType won't find the temporary allocations.
const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024;
int buf_bitmap_current_used_bytes = 0;
ImVector<unsigned char*> buf_bitmap_buffers;
buf_bitmap_buffers.push_back((unsigned char*)ImGui::MemAlloc(BITMAP_BUFFERS_CHUNK_SIZE));
// 4. Gather glyphs sizes so we can pack them in our virtual canvas.
// 8. Render/rasterize font characters into the texture
int total_surface = 0;
int buf_rects_out_n = 0;
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontConfig& cfg = atlas->ConfigData[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
src_tmp.Rects = &buf_rects[buf_rects_out_n];
buf_rects_out_n += src_tmp.GlyphsCount;
// Compute multiply table if requested
const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
unsigned char multiply_table[256];
if (multiply_enabled)
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
// Gather the sizes of all rectangles we will need to pack
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
{
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
IM_ASSERT(metrics != NULL);
if (metrics == NULL)
continue;
// Render glyph into a bitmap (currently held by FreeType)
const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info);
IM_ASSERT(ft_bitmap);
// Allocate new temporary chunk if needed
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height;
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
{
buf_bitmap_current_used_bytes = 0;
buf_bitmap_buffers.push_back((unsigned char*)ImGui::MemAlloc(BITMAP_BUFFERS_CHUNK_SIZE));
}
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
src_glyph.BitmapData = buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes;
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width * 1, multiply_enabled ? multiply_table : NULL);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
}
}
// We need a width for the skyline algorithm, any width!
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
// User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface.
const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1;
atlas->TexHeight = 0;
if (atlas->TexDesiredWidth > 0)
atlas->TexWidth = atlas->TexDesiredWidth;
else
atlas->TexWidth = (surface_sqrt >= 4096*0.7f) ? 4096 : (surface_sqrt >= 2048*0.7f) ? 2048 : (surface_sqrt >= 1024*0.7f) ? 1024 : 512;
// 5. Start packing
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
const int TEX_HEIGHT_MAX = 1024 * 32;
const int num_nodes_for_packing_algorithm = atlas->TexWidth - atlas->TexGlyphPadding;
ImVector<stbrp_node> pack_nodes;
pack_nodes.resize(num_nodes_for_packing_algorithm);
stbrp_context pack_context;
stbrp_init_target(&pack_context, atlas->TexWidth, TEX_HEIGHT_MAX, pack_nodes.Data, pack_nodes.Size);
ImFontAtlasBuildPackCustomRects(atlas, &pack_context);
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
// Extend texture height and mark missing glyphs as non-packed so we won't render them.
// FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?)
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
if (src_tmp.Rects[glyph_i].was_packed)
atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h);
}
// 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
// Start packing
ImVector<stbrp_node> pack_nodes;
pack_nodes.resize(total_rects);
stbrp_context context;
stbrp_init_target(&context, atlas->TexWidth, atlas->TexHeight, pack_nodes.Data, total_rects);
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
ImFontAtlasBuildPackCustomRects(atlas, &context);
// Render characters, setup ImFont and glyphs for runtime
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
// 8. Copy rasterized font characters back into the main texture
// 9. Setup ImFont and glyphs for runtime
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{
ImFontConfig& cfg = atlas->ConfigData[input_i];
FreeTypeFont& font_face = fonts[input_i];
ImFont* dst_font = cfg.DstFont;
if (cfg.MergeMode)
dst_font->BuildLookupTable();
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
const float ascent = font_face.Info.Ascender;
const float descent = font_face.Info.Descender;
ImFontConfig& cfg = atlas->ConfigData[src_i];
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
const float ascent = src_tmp.Font.Info.Ascender;
const float descent = src_tmp.Font.Info.Descender;
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f);
bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
unsigned char multiply_table[256];
if (multiply_enabled)
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2)
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{
for (uint32_t codepoint = in_range[0]; codepoint <= in_range[1]; ++codepoint)
{
if (cfg.MergeMode && dst_font->FindGlyphNoFallback((ImWchar)codepoint))
continue;
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
IM_ASSERT(pack_rect.was_packed);
FT_Glyph ft_glyph = NULL;
FT_BitmapGlyph ft_glyph_bitmap = NULL; // NB: will point to bitmap within FT_Glyph
GlyphInfo glyph_info;
if (!font_face.CalcGlyphInfo(codepoint, glyph_info, ft_glyph, ft_glyph_bitmap))
continue;
GlyphInfo& info = src_glyph.Info;
IM_ASSERT(info.Width + padding <= pack_rect.w);
IM_ASSERT(info.Height + padding <= pack_rect.h);
const int tx = pack_rect.x + padding;
const int ty = pack_rect.y + padding;
// Pack rectangle
stbrp_rect rect;
rect.w = (uint16_t)glyph_info.Width + 1; // Account for texture filtering
rect.h = (uint16_t)glyph_info.Height + 1;
stbrp_pack_rects(&context, &rect, 1);
// Blit from temporary buffer to final texture
size_t blit_src_stride = (size_t)src_glyph.Info.Width;
size_t blit_dst_stride = (size_t)atlas->TexWidth;
unsigned char* blit_src = src_glyph.BitmapData;
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
memcpy(blit_dst, blit_src, blit_src_stride);
// Copy rasterized pixels to main texture
uint8_t* blit_dst = atlas->TexPixelsAlpha8 + rect.y * atlas->TexWidth + rect.x;
font_face.BlitGlyph(ft_glyph_bitmap, blit_dst, atlas->TexWidth, multiply_enabled ? multiply_table : NULL);
FT_Done_Glyph(ft_glyph);
float char_advance_x_org = glyph_info.AdvanceX;
float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
float char_off_x = font_off_x;
if (char_advance_x_org != char_advance_x_mod)
char_off_x += cfg.PixelSnapH ? (float)(int)((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
// Register glyph
dst_font->AddGlyph((ImWchar)codepoint,
glyph_info.OffsetX + char_off_x,
glyph_info.OffsetY + font_off_y,
glyph_info.OffsetX + char_off_x + glyph_info.Width,
glyph_info.OffsetY + font_off_y + glyph_info.Height,
rect.x / (float)atlas->TexWidth,
rect.y / (float)atlas->TexHeight,
(rect.x + glyph_info.Width) / (float)atlas->TexWidth,
(rect.y + glyph_info.Height) / (float)atlas->TexHeight,
char_advance_x_mod);
}
float char_advance_x_org = info.AdvanceX;
float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
float char_off_x = font_off_x;
if (char_advance_x_org != char_advance_x_mod)
char_off_x += cfg.PixelSnapH ? (float)(int)((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
// Register glyph
float x0 = info.OffsetX + char_off_x;
float y0 = info.OffsetY + font_off_y;
float x1 = x0 + info.Width;
float y1 = y0 + info.Height;
float u0 = (tx) / (float)atlas->TexWidth;
float v0 = (ty) / (float)atlas->TexHeight;
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
dst_font->AddGlyph((ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, char_advance_x_mod);
}
src_tmp.Rects = NULL;
}
// Cleanup
for (int n = 0; n < fonts.Size; n++)
fonts[n].Shutdown();
for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++)
ImGui::MemFree(buf_bitmap_buffers[buf_i]);
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
src_tmp_array[src_i].~ImFontBuildSrcDataFT();
ImFontAtlasBuildFinish(atlas);
return true;
}
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
{
FT_Library ft_library;
FT_Error error = FT_Init_FreeType(&ft_library);
if (error != 0)
return false;
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
FT_Done_FreeType(ft_library);
return ret;
}

View File

@ -1,4 +1,4 @@
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
// Wrapper to use FreeType (instead of stb_truetype) for Dear ImGui
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut

View File

@ -33,7 +33,7 @@
</Type>
<Type Name="ImGuiWindow">
<DisplayString>{{Name={Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags &amp; 0x01000000)?1:0,d} Popup {(Flags &amp; 0x04000000)?1:0,d}}</DisplayString>
<DisplayString>{{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags &amp; 0x01000000)?1:0,d} Popup {(Flags &amp; 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}}</DisplayString>
</Type>
</AutoVisualizer>