mirror of
https://github.com/swordbluesword/PalWorld-NetCrack.git
synced 2025-04-29 02:47:17 +09:00
update(IMGUI): Updated imgui to latest
This commit is contained in:
parent
218e03c487
commit
dbed2fbd9e
@ -1,5 +1,5 @@
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -9,7 +9,7 @@
|
|||||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -26,21 +26,21 @@
|
|||||||
//#define IMGUI_API __declspec( dllexport )
|
//#define IMGUI_API __declspec( dllexport )
|
||||||
//#define IMGUI_API __declspec( dllimport )
|
//#define IMGUI_API __declspec( dllimport )
|
||||||
|
|
||||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
|
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
|
||||||
|
|
||||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
|
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||||
|
|
||||||
//---- Don't implement some functions to reduce linkage requirements.
|
//---- Don't implement some functions to reduce linkage requirements.
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||||
@ -50,30 +50,40 @@
|
|||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||||
|
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||||
|
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||||
|
|
||||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
|
||||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||||
//#define IMGUI_USE_WCHAR32
|
//#define IMGUI_USE_WCHAR32
|
||||||
|
|
||||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||||
|
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
|
|
||||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||||
// #define IMGUI_USE_STB_SPRINTF
|
//#define IMGUI_USE_STB_SPRINTF
|
||||||
|
|
||||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||||
//#define IMGUI_ENABLE_FREETYPE
|
//#define IMGUI_ENABLE_FREETYPE
|
||||||
|
|
||||||
|
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
||||||
|
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
||||||
|
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||||
|
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
|
|
||||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||||
@ -82,13 +92,15 @@
|
|||||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||||
/*
|
/*
|
||||||
#define IM_VEC2_CLASS_EXTRA \
|
#define IM_VEC2_CLASS_EXTRA \
|
||||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||||
operator MyVec2() const { return MyVec2(x,y); }
|
operator MyVec2() const { return MyVec2(x,y); }
|
||||||
|
|
||||||
#define IM_VEC4_CLASS_EXTRA \
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||||
*/
|
*/
|
||||||
|
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||||
|
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||||
@ -102,23 +114,18 @@
|
|||||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||||
//#define ImDrawCallback MyImDrawCallback
|
//#define ImDrawCallback MyImDrawCallback
|
||||||
|
|
||||||
//---- Debug Tools: Macro to break in Debugger
|
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||||
//#define IM_DEBUG_BREAK __debugbreak()
|
//#define IM_DEBUG_BREAK __debugbreak()
|
||||||
|
|
||||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
|
||||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
|
||||||
// This adds a small runtime cost which is why it is not enabled by default.
|
|
||||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
|
||||||
|
|
||||||
//---- Debug Tools: Enable slower asserts
|
//---- Debug Tools: Enable slower asserts
|
||||||
//#define IMGUI_DEBUG_PARANOID
|
//#define IMGUI_DEBUG_PARANOID
|
||||||
|
|
||||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||||
/*
|
/*
|
||||||
namespace ImGui
|
namespace ImGui
|
||||||
{
|
{
|
||||||
void MyFunction(const char* name, const MyMatrix44& v);
|
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
7030
libs/ImGui/imgui.cpp
7030
libs/ImGui/imgui.cpp
File diff suppressed because it is too large
Load Diff
1551
libs/ImGui/imgui.h
1551
libs/ImGui/imgui.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,15 +4,19 @@
|
|||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
// Learn about Dear ImGui:
|
||||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||||
@ -31,6 +35,7 @@
|
|||||||
// 2016-05-07: DirectX11: Disabling depth-write.
|
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
#include "imgui_impl_dx11.h"
|
#include "imgui_impl_dx11.h"
|
||||||
|
|
||||||
// DirectX
|
// DirectX
|
||||||
@ -61,10 +66,10 @@ struct ImGui_ImplDX11_Data
|
|||||||
int VertexBufferSize;
|
int VertexBufferSize;
|
||||||
int IndexBufferSize;
|
int IndexBufferSize;
|
||||||
|
|
||||||
ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VERTEX_CONSTANT_BUFFER
|
struct VERTEX_CONSTANT_BUFFER_DX11
|
||||||
{
|
{
|
||||||
float mvp[4][4];
|
float mvp[4][4];
|
||||||
};
|
};
|
||||||
@ -73,7 +78,7 @@ struct VERTEX_CONSTANT_BUFFER
|
|||||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||||
{
|
{
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
@ -98,14 +103,14 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
|||||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ctx->VSSetShader(bd->pVertexShader, NULL, 0);
|
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
ctx->PSSetShader(bd->pPixelShader, NULL, 0);
|
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||||
ctx->GSSetShader(NULL, NULL, 0);
|
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||||
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
|
||||||
// Setup blend state
|
// Setup blend state
|
||||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
@ -127,7 +132,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// Create and grow vertex/index buffers if needed
|
// Create and grow vertex/index buffers if needed
|
||||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
{
|
{
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
D3D11_BUFFER_DESC desc;
|
D3D11_BUFFER_DESC desc;
|
||||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||||
@ -136,12 +141,12 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
desc.MiscFlags = 0;
|
desc.MiscFlags = 0;
|
||||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0)
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
{
|
{
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
D3D11_BUFFER_DESC desc;
|
D3D11_BUFFER_DESC desc;
|
||||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||||
@ -149,7 +154,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0)
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +183,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||||
return;
|
return;
|
||||||
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
|
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||||
float L = draw_data->DisplayPos.x;
|
float L = draw_data->DisplayPos.x;
|
||||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
float T = draw_data->DisplayPos.y;
|
float T = draw_data->DisplayPos.y;
|
||||||
@ -253,7 +258,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != NULL)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
@ -327,13 +332,13 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
desc.CPUAccessFlags = 0;
|
desc.CPUAccessFlags = 0;
|
||||||
|
|
||||||
ID3D11Texture2D* pTexture = NULL;
|
ID3D11Texture2D* pTexture = nullptr;
|
||||||
D3D11_SUBRESOURCE_DATA subResource;
|
D3D11_SUBRESOURCE_DATA subResource;
|
||||||
subResource.pSysMem = pixels;
|
subResource.pSysMem = pixels;
|
||||||
subResource.SysMemPitch = desc.Width * 4;
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
subResource.SysMemSlicePitch = 0;
|
subResource.SysMemSlicePitch = 0;
|
||||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||||
IM_ASSERT(pTexture != NULL);
|
IM_ASSERT(pTexture != nullptr);
|
||||||
|
|
||||||
// Create texture view
|
// Create texture view
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
@ -350,6 +355,7 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||||
|
|
||||||
// Create texture sampler
|
// Create texture sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
{
|
{
|
||||||
D3D11_SAMPLER_DESC desc;
|
D3D11_SAMPLER_DESC desc;
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
@ -410,9 +416,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
}";
|
}";
|
||||||
|
|
||||||
ID3DBlob* vertexShaderBlob;
|
ID3DBlob* vertexShaderBlob;
|
||||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL)))
|
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK)
|
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||||
{
|
{
|
||||||
vertexShaderBlob->Release();
|
vertexShaderBlob->Release();
|
||||||
return false;
|
return false;
|
||||||
@ -421,9 +427,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
// Create the input layout
|
// Create the input layout
|
||||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||||
{
|
{
|
||||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
};
|
};
|
||||||
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||||
{
|
{
|
||||||
@ -435,12 +441,12 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
// Create the constant buffer
|
// Create the constant buffer
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC desc;
|
D3D11_BUFFER_DESC desc;
|
||||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
desc.MiscFlags = 0;
|
desc.MiscFlags = 0;
|
||||||
bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer);
|
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,9 +469,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
}";
|
}";
|
||||||
|
|
||||||
ID3DBlob* pixelShaderBlob;
|
ID3DBlob* pixelShaderBlob;
|
||||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL)))
|
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK)
|
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||||
{
|
{
|
||||||
pixelShaderBlob->Release();
|
pixelShaderBlob->Release();
|
||||||
return false;
|
return false;
|
||||||
@ -525,23 +531,23 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
|||||||
if (!bd->pd3dDevice)
|
if (!bd->pd3dDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; }
|
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; }
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; }
|
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||||
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; }
|
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||||
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; }
|
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||||
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; }
|
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||||
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; }
|
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||||
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; }
|
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||||
@ -550,9 +556,9 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
// Get factory from device
|
// Get factory from device
|
||||||
IDXGIDevice* pDXGIDevice = NULL;
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
IDXGIFactory* pFactory = NULL;
|
IDXGIFactory* pFactory = nullptr;
|
||||||
|
|
||||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||||
@ -573,23 +579,28 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
void ImGui_ImplDX11_Shutdown()
|
void ImGui_ImplDX11_Shutdown()
|
||||||
{
|
{
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||||
io.BackendRendererName = NULL;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = NULL;
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplDX11_NewFrame()
|
void ImGui_ImplDX11_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?");
|
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
|
||||||
|
|
||||||
if (!bd->pFontSampler)
|
if (!bd->pFontSampler)
|
||||||
ImGui_ImplDX11_CreateDeviceObjects();
|
ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@ -3,15 +3,19 @@
|
|||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
// Learn about Dear ImGui:
|
||||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
struct ID3D11Device;
|
struct ID3D11Device;
|
||||||
struct ID3D11DeviceContext;
|
struct ID3D11DeviceContext;
|
||||||
@ -24,3 +28,5 @@ IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
|||||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@ -1,24 +1,30 @@
|
|||||||
#include "../../pch.h"
|
#include "../../pch.h"
|
||||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
// Learn about Dear ImGui:
|
||||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
#include "imgui_impl_win32.h"
|
#include "imgui_impl_win32.h"
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
|
||||||
@ -34,6 +40,22 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||||
|
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||||
|
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||||
|
// 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
|
||||||
|
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
|
||||||
|
// 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
|
||||||
|
// 2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode).
|
||||||
|
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||||
|
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||||
|
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||||
|
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||||
|
// 2022-01-17: Inputs: always update key mods next and before a key event (not in NewFrame) to fix input queue with very low framerates.
|
||||||
|
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
|
||||||
|
// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||||
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
||||||
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
|
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
|
||||||
@ -68,26 +90,28 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||||||
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
|
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
|
||||||
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
|
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
|
||||||
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||||
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.
|
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
|
||||||
|
|
||||||
struct ImGui_ImplWin32_Data
|
struct ImGui_ImplWin32_Data
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
HWND MouseHwnd;
|
HWND MouseHwnd;
|
||||||
bool MouseTracked;
|
int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
|
||||||
|
int MouseButtonsDown;
|
||||||
INT64 Time;
|
INT64 Time;
|
||||||
INT64 TicksPerSecond;
|
INT64 TicksPerSecond;
|
||||||
ImGuiMouseCursor LastMouseCursor;
|
ImGuiMouseCursor LastMouseCursor;
|
||||||
bool HasGamepad;
|
UINT32 KeyboardCodePage;
|
||||||
bool WantUpdateHasGamepad;
|
|
||||||
|
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
bool HasGamepad;
|
||||||
|
bool WantUpdateHasGamepad;
|
||||||
HMODULE XInputDLL;
|
HMODULE XInputDLL;
|
||||||
PFN_XInputGetCapabilities XInputGetCapabilities;
|
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||||
PFN_XInputGetState XInputGetState;
|
PFN_XInputGetState XInputGetState;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui_ImplWin32_Data() { memset(this, 0, sizeof(*this)); }
|
ImGui_ImplWin32_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||||
@ -96,14 +120,24 @@ struct ImGui_ImplWin32_Data
|
|||||||
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
||||||
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
||||||
{
|
{
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
bool ImGui_ImplWin32_Init(void* hwnd)
|
static void ImGui_ImplWin32_UpdateKeyboardCodePage()
|
||||||
|
{
|
||||||
|
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
|
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
||||||
|
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
||||||
|
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
||||||
|
bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails.
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
|
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||||
|
|
||||||
INT64 perf_frequency, perf_counter;
|
INT64 perf_frequency, perf_counter;
|
||||||
if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
|
if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
|
||||||
@ -119,16 +153,18 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
|||||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||||
|
|
||||||
bd->hWnd = (HWND)hwnd;
|
bd->hWnd = (HWND)hwnd;
|
||||||
bd->WantUpdateHasGamepad = true;
|
|
||||||
bd->TicksPerSecond = perf_frequency;
|
bd->TicksPerSecond = perf_frequency;
|
||||||
bd->Time = perf_counter;
|
bd->Time = perf_counter;
|
||||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||||
|
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||||
|
|
||||||
// Set platform dependent data in viewport
|
// Set platform dependent data in viewport
|
||||||
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
|
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
|
||||||
|
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
|
||||||
|
|
||||||
// Dynamically load XInput library
|
// Dynamically load XInput library
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
bd->WantUpdateHasGamepad = true;
|
||||||
const char* xinput_dll_names[] =
|
const char* xinput_dll_names[] =
|
||||||
{
|
{
|
||||||
"xinput1_4.dll", // Windows 8+
|
"xinput1_4.dll", // Windows 8+
|
||||||
@ -150,10 +186,21 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd)
|
||||||
|
{
|
||||||
|
return ImGui_ImplWin32_InitEx(hwnd, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd)
|
||||||
|
{
|
||||||
|
// OpenGL needs CS_OWNDC
|
||||||
|
return ImGui_ImplWin32_InitEx(hwnd, true);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplWin32_Shutdown()
|
void ImGui_ImplWin32_Shutdown()
|
||||||
{
|
{
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
// Unload XInput library
|
// Unload XInput library
|
||||||
@ -162,8 +209,9 @@ void ImGui_ImplWin32_Shutdown()
|
|||||||
::FreeLibrary(bd->XInputDLL);
|
::FreeLibrary(bd->XInputDLL);
|
||||||
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
|
||||||
io.BackendPlatformName = NULL;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = NULL;
|
io.BackendPlatformUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +225,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
|||||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||||
{
|
{
|
||||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||||
::SetCursor(NULL);
|
::SetCursor(nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -195,7 +243,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
|||||||
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||||
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||||
}
|
}
|
||||||
::SetCursor(::LoadCursor(NULL, win32_cursor));
|
::SetCursor(::LoadCursor(nullptr, win32_cursor));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -231,46 +279,39 @@ static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
|||||||
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiKeyModFlags key_mods =
|
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
||||||
((IsVkDown(VK_LCONTROL) || IsVkDown(VK_RCONTROL)) ? ImGuiKeyModFlags_Ctrl : 0) |
|
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
||||||
((IsVkDown(VK_LSHIFT) || IsVkDown(VK_RSHIFT)) ? ImGuiKeyModFlags_Shift : 0) |
|
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
||||||
((IsVkDown(VK_LMENU) || IsVkDown(VK_RMENU)) ? ImGuiKeyModFlags_Alt : 0) |
|
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_APPS));
|
||||||
((IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN)) ? ImGuiKeyModFlags_Super : 0);
|
|
||||||
io.AddKeyModsEvent(key_mods);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_UpdateMousePos()
|
static void ImGui_ImplWin32_UpdateMouseData()
|
||||||
{
|
{
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
IM_ASSERT(bd->hWnd != 0);
|
IM_ASSERT(bd->hWnd != 0);
|
||||||
|
|
||||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
|
||||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
||||||
|
|
||||||
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
|
|
||||||
HWND focused_window = ::GetForegroundWindow();
|
HWND focused_window = ::GetForegroundWindow();
|
||||||
HWND hovered_window = bd->MouseHwnd;
|
const bool is_app_focused = (focused_window == bd->hWnd);
|
||||||
HWND mouse_window = NULL;
|
if (is_app_focused)
|
||||||
if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd)))
|
{
|
||||||
mouse_window = hovered_window;
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||||
else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd)))
|
|
||||||
mouse_window = focused_window;
|
|
||||||
if (mouse_window == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
{
|
{
|
||||||
POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
|
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||||
if (::ClientToScreen(bd->hWnd, &pos))
|
if (::ClientToScreen(bd->hWnd, &pos))
|
||||||
::SetCursorPos(pos.x, pos.y);
|
::SetCursorPos(pos.x, pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Dear ImGui mouse position from OS position
|
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||||
|
// This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
|
||||||
|
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0)
|
||||||
|
{
|
||||||
POINT pos;
|
POINT pos;
|
||||||
if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos))
|
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
||||||
io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
io.AddMousePosEvent((float)pos.x, (float)pos.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gamepad navigation mapping
|
// Gamepad navigation mapping
|
||||||
@ -279,47 +320,54 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
|||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
// return;
|
||||||
return;
|
|
||||||
|
|
||||||
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
||||||
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||||
if (bd->WantUpdateHasGamepad)
|
if (bd->WantUpdateHasGamepad)
|
||||||
{
|
{
|
||||||
XINPUT_CAPABILITIES caps;
|
XINPUT_CAPABILITIES caps = {};
|
||||||
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
||||||
bd->WantUpdateHasGamepad = false;
|
bd->WantUpdateHasGamepad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||||
XINPUT_STATE xinput_state;
|
XINPUT_STATE xinput_state;
|
||||||
if (bd->HasGamepad && bd->XInputGetState && bd->XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
|
XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||||
{
|
if (!bd->HasGamepad || bd->XInputGetState == nullptr || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
|
||||||
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
return;
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||||
|
|
||||||
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
|
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||||
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
#define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
|
||||||
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
|
#define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn)); }
|
||||||
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
|
MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START);
|
||||||
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
|
MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK);
|
||||||
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
|
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X);
|
||||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
|
MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B);
|
||||||
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
|
MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y);
|
||||||
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
|
MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A);
|
||||||
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
|
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
|
||||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
|
||||||
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP);
|
||||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
|
||||||
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||||
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||||
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||||
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
|
MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB);
|
||||||
|
MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||||
|
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
#undef MAP_BUTTON
|
#undef MAP_BUTTON
|
||||||
#undef MAP_ANALOG
|
#undef MAP_ANALOG
|
||||||
}
|
|
||||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +375,7 @@ void ImGui_ImplWin32_NewFrame()
|
|||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?");
|
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWin32_Init()?");
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
RECT rect = { 0, 0, 0, 0 };
|
RECT rect = { 0, 0, 0, 0 };
|
||||||
@ -340,15 +388,12 @@ void ImGui_ImplWin32_NewFrame()
|
|||||||
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
|
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
|
||||||
bd->Time = current_time;
|
bd->Time = current_time;
|
||||||
|
|
||||||
|
// Update OS mouse position
|
||||||
|
ImGui_ImplWin32_UpdateMouseData();
|
||||||
|
|
||||||
// Process workarounds for known Windows key handling issues
|
// Process workarounds for known Windows key handling issues
|
||||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
||||||
|
|
||||||
// Update key modifiers
|
|
||||||
ImGui_ImplWin32_UpdateKeyModifiers();
|
|
||||||
|
|
||||||
// Update OS mouse position
|
|
||||||
ImGui_ImplWin32_UpdateMousePos();
|
|
||||||
|
|
||||||
// Update OS mouse cursor with the cursor requested by imgui
|
// Update OS mouse cursor with the cursor requested by imgui
|
||||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||||
if (bd->LastMouseCursor != mouse_cursor)
|
if (bd->LastMouseCursor != mouse_cursor)
|
||||||
@ -417,11 +462,11 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||||||
case VK_ADD: return ImGuiKey_KeypadAdd;
|
case VK_ADD: return ImGuiKey_KeypadAdd;
|
||||||
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||||
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
||||||
case VK_LCONTROL: return ImGuiKey_LeftControl;
|
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
|
||||||
case VK_LMENU: return ImGuiKey_LeftAlt;
|
case VK_LMENU: return ImGuiKey_LeftAlt;
|
||||||
case VK_LWIN: return ImGuiKey_LeftSuper;
|
case VK_LWIN: return ImGuiKey_LeftSuper;
|
||||||
case VK_RSHIFT: return ImGuiKey_RightShift;
|
case VK_RSHIFT: return ImGuiKey_RightShift;
|
||||||
case VK_RCONTROL: return ImGuiKey_RightControl;
|
case VK_RCONTROL: return ImGuiKey_RightCtrl;
|
||||||
case VK_RMENU: return ImGuiKey_RightAlt;
|
case VK_RMENU: return ImGuiKey_RightAlt;
|
||||||
case VK_RWIN: return ImGuiKey_RightSuper;
|
case VK_RWIN: return ImGuiKey_RightSuper;
|
||||||
case VK_APPS: return ImGuiKey_Menu;
|
case VK_APPS: return ImGuiKey_Menu;
|
||||||
@ -473,6 +518,20 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||||||
case VK_F10: return ImGuiKey_F10;
|
case VK_F10: return ImGuiKey_F10;
|
||||||
case VK_F11: return ImGuiKey_F11;
|
case VK_F11: return ImGuiKey_F11;
|
||||||
case VK_F12: return ImGuiKey_F12;
|
case VK_F12: return ImGuiKey_F12;
|
||||||
|
case VK_F13: return ImGuiKey_F13;
|
||||||
|
case VK_F14: return ImGuiKey_F14;
|
||||||
|
case VK_F15: return ImGuiKey_F15;
|
||||||
|
case VK_F16: return ImGuiKey_F16;
|
||||||
|
case VK_F17: return ImGuiKey_F17;
|
||||||
|
case VK_F18: return ImGuiKey_F18;
|
||||||
|
case VK_F19: return ImGuiKey_F19;
|
||||||
|
case VK_F20: return ImGuiKey_F20;
|
||||||
|
case VK_F21: return ImGuiKey_F21;
|
||||||
|
case VK_F22: return ImGuiKey_F22;
|
||||||
|
case VK_F23: return ImGuiKey_F23;
|
||||||
|
case VK_F24: return ImGuiKey_F24;
|
||||||
|
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
||||||
|
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
||||||
default: return ImGuiKey_None;
|
default: return ImGuiKey_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,10 +545,10 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||||
// Call from your application's message handler.
|
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||||
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||||
@ -497,9 +556,22 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||||||
// Copy this line into your .cpp file to forward declare the function.
|
// Copy this line into your .cpp file to forward declare the function.
|
||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
||||||
|
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
||||||
|
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||||
|
{
|
||||||
|
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||||
|
return ImGuiMouseSource_Pen;
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||||
|
return ImGuiMouseSource_TouchScreen;
|
||||||
|
return ImGuiMouseSource_Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (ImGui::GetCurrentContext() == NULL)
|
if (ImGui::GetCurrentContext() == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
@ -508,33 +580,57 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
case WM_NCMOUSEMOVE:
|
||||||
bd->MouseHwnd = hwnd;
|
|
||||||
if (!bd->MouseTracked)
|
|
||||||
{
|
{
|
||||||
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
|
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||||
::TrackMouseEvent(&tme);
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
bd->MouseTracked = true;
|
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||||
|
bd->MouseHwnd = hwnd;
|
||||||
|
if (bd->MouseTrackedArea != area)
|
||||||
|
{
|
||||||
|
TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
|
||||||
|
TRACKMOUSEEVENT tme_track = { sizeof(tme_track), (DWORD)((area == 2) ? (TME_LEAVE | TME_NONCLIENT) : TME_LEAVE), hwnd, 0 };
|
||||||
|
if (bd->MouseTrackedArea != 0)
|
||||||
|
::TrackMouseEvent(&tme_cancel);
|
||||||
|
::TrackMouseEvent(&tme_track);
|
||||||
|
bd->MouseTrackedArea = area;
|
||||||
|
}
|
||||||
|
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||||
|
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
|
||||||
|
break;
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
case WM_NCMOUSELEAVE:
|
||||||
|
{
|
||||||
|
const int area = (msg == WM_MOUSELEAVE) ? 1 : 2;
|
||||||
|
if (bd->MouseTrackedArea == area)
|
||||||
|
{
|
||||||
|
if (bd->MouseHwnd == hwnd)
|
||||||
|
bd->MouseHwnd = nullptr;
|
||||||
|
bd->MouseTrackedArea = 0;
|
||||||
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_MOUSELEAVE:
|
}
|
||||||
if (bd->MouseHwnd == hwnd)
|
|
||||||
bd->MouseHwnd = NULL;
|
|
||||||
bd->MouseTracked = false;
|
|
||||||
break;
|
|
||||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||||
{
|
{
|
||||||
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
int button = 0;
|
int button = 0;
|
||||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
|
||||||
::SetCapture(hwnd);
|
::SetCapture(hwnd);
|
||||||
io.MouseDown[button] = true;
|
bd->MouseButtonsDown |= 1 << button;
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMouseButtonEvent(button, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
@ -542,21 +638,24 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
{
|
{
|
||||||
|
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||||
int button = 0;
|
int button = 0;
|
||||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||||
if (msg == WM_MBUTTONUP) { button = 2; }
|
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||||
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||||
io.MouseDown[button] = false;
|
bd->MouseButtonsDown &= ~(1 << button);
|
||||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
|
||||||
::ReleaseCapture();
|
::ReleaseCapture();
|
||||||
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
|
io.AddMouseButtonEvent(button, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_MOUSEHWHEEL:
|
case WM_MOUSEHWHEEL:
|
||||||
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
io.AddMouseWheelEvent(-(float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
@ -564,18 +663,24 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
{
|
{
|
||||||
const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
||||||
|
|
||||||
if (wParam < 256)
|
if (wParam < 256)
|
||||||
{
|
{
|
||||||
|
// Submit modifiers
|
||||||
|
ImGui_ImplWin32_UpdateKeyModifiers();
|
||||||
|
|
||||||
// Obtain virtual key code
|
// Obtain virtual key code
|
||||||
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
||||||
int vk = (int)wParam;
|
int vk = (int)wParam;
|
||||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||||
vk = IM_VK_KEYPAD_ENTER;
|
vk = IM_VK_KEYPAD_ENTER;
|
||||||
|
|
||||||
// Submit key event
|
|
||||||
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
||||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||||
|
|
||||||
|
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
||||||
|
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
||||||
|
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
|
||||||
|
|
||||||
|
// Submit key event
|
||||||
if (key != ImGuiKey_None)
|
if (key != ImGuiKey_None)
|
||||||
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
||||||
|
|
||||||
@ -588,8 +693,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
}
|
}
|
||||||
else if (vk == VK_CONTROL)
|
else if (vk == VK_CONTROL)
|
||||||
{
|
{
|
||||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftControl, is_key_down, VK_LCONTROL, scancode); }
|
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightControl, is_key_down, VK_RCONTROL, scancode); }
|
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||||
}
|
}
|
||||||
else if (vk == VK_MENU)
|
else if (vk == VK_MENU)
|
||||||
{
|
{
|
||||||
@ -603,18 +708,33 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||||
return 0;
|
return 0;
|
||||||
|
case WM_INPUTLANGCHANGE:
|
||||||
|
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||||
|
return 0;
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
|
if (::IsWindowUnicode(hwnd))
|
||||||
|
{
|
||||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||||
if (wParam > 0 && wParam < 0x10000)
|
if (wParam > 0 && wParam < 0x10000)
|
||||||
io.AddInputCharacterUTF16((unsigned short)wParam);
|
io.AddInputCharacterUTF16((unsigned short)wParam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar_t wch = 0;
|
||||||
|
::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
|
||||||
|
io.AddInputCharacter(wch);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case WM_SETCURSOR:
|
case WM_SETCURSOR:
|
||||||
|
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
||||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DEVICECHANGE:
|
case WM_DEVICECHANGE:
|
||||||
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
||||||
bd->WantUpdateHasGamepad = true;
|
bd->WantUpdateHasGamepad = true;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -640,11 +760,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||||
{
|
{
|
||||||
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||||
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = NULL;
|
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
|
||||||
if (RtlVerifyVersionInfoFn == NULL)
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||||
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||||
if (RtlVerifyVersionInfoFn == NULL)
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
RTL_OSVERSIONINFOEXW versionInfo = { };
|
RTL_OSVERSIONINFOEXW versionInfo = { };
|
||||||
@ -713,10 +833,10 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
|||||||
if (_IsWindows8Point1OrGreater())
|
if (_IsWindows8Point1OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
static PFN_GetDpiForMonitor GetDpiForMonitorFn = NULL;
|
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
||||||
if (GetDpiForMonitorFn == NULL && shcore_dll != NULL)
|
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
||||||
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||||
if (GetDpiForMonitorFn != NULL)
|
if (GetDpiForMonitorFn != nullptr)
|
||||||
{
|
{
|
||||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
@ -724,11 +844,11 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NOGDI
|
#ifndef NOGDI
|
||||||
const HDC dc = ::GetDC(NULL);
|
const HDC dc = ::GetDC(nullptr);
|
||||||
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
||||||
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
||||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
::ReleaseDC(NULL, dc);
|
::ReleaseDC(nullptr, dc);
|
||||||
#endif
|
#endif
|
||||||
return xdpi / 96.0f;
|
return xdpi / 96.0f;
|
||||||
}
|
}
|
||||||
@ -780,3 +900,5 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
@ -1,27 +1,35 @@
|
|||||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
// Learn about Dear ImGui:
|
||||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
|
||||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||||
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||||
|
|
||||||
// Win32 message handler your application need to call.
|
// Win32 message handler your application need to call.
|
||||||
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.
|
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.
|
||||||
// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
|
// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
|
||||||
|
// - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
#endif
|
#endif
|
||||||
@ -40,3 +48,5 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); //
|
|||||||
// - Use to enable alpha compositing transparency with the desktop.
|
// - Use to enable alpha compositing transparency with the desktop.
|
||||||
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
||||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,19 @@
|
|||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
// This is a slightly modified version of stb_rect_pack.h 1.00.
|
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||||
// Those changes would need to be pushed into nothings/stb:
|
|
||||||
// - Added STBRP__CDECL
|
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
//
|
||||||
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||||
// Sean Barrett 2014
|
// Sean Barrett 2014
|
||||||
//
|
//
|
||||||
// Useful for e.g. packing rectangular textures into an atlas.
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||||||
// Does not do rotation.
|
// Does not do rotation.
|
||||||
//
|
//
|
||||||
|
// Before #including,
|
||||||
|
//
|
||||||
|
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//
|
||||||
|
// in the file that you want to have the implementation.
|
||||||
|
//
|
||||||
// Not necessarily the awesomest packing method, but better than
|
// Not necessarily the awesomest packing method, but better than
|
||||||
// the totally naive one in stb_truetype (which is primarily what
|
// the totally naive one in stb_truetype (which is primarily what
|
||||||
// this is meant to replace).
|
// this is meant to replace).
|
||||||
@ -41,6 +45,7 @@
|
|||||||
//
|
//
|
||||||
// Version history:
|
// Version history:
|
||||||
//
|
//
|
||||||
|
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||||
// 0.99 (2019-02-07) warning fixes
|
// 0.99 (2019-02-07) warning fixes
|
||||||
// 0.11 (2017-03-03) return packing success/fail result
|
// 0.11 (2017-03-03) return packing success/fail result
|
||||||
@ -81,11 +86,10 @@ typedef struct stbrp_context stbrp_context;
|
|||||||
typedef struct stbrp_node stbrp_node;
|
typedef struct stbrp_node stbrp_node;
|
||||||
typedef struct stbrp_rect stbrp_rect;
|
typedef struct stbrp_rect stbrp_rect;
|
||||||
|
|
||||||
#ifdef STBRP_LARGE_RECTS
|
|
||||||
typedef int stbrp_coord;
|
typedef int stbrp_coord;
|
||||||
#else
|
|
||||||
typedef unsigned short stbrp_coord;
|
#define STBRP__MAXVAL 0x7fffffff
|
||||||
#endif
|
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||||
|
|
||||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||||
// Assign packed locations to rectangles. The rectangles are of type
|
// Assign packed locations to rectangles. The rectangles are of type
|
||||||
@ -213,7 +217,6 @@ struct stbrp_context
|
|||||||
#define STBRP_ASSERT assert
|
#define STBRP_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// [DEAR IMGUI] Added STBRP__CDECL
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define STBRP__NOTUSED(v) (void)(v)
|
#define STBRP__NOTUSED(v) (void)(v)
|
||||||
#define STBRP__CDECL __cdecl
|
#define STBRP__CDECL __cdecl
|
||||||
@ -262,9 +265,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
|
|||||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
#ifndef STBRP_LARGE_RECTS
|
|
||||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i=0; i < num_nodes-1; ++i)
|
for (i=0; i < num_nodes-1; ++i)
|
||||||
nodes[i].next = &nodes[i+1];
|
nodes[i].next = &nodes[i+1];
|
||||||
@ -283,11 +283,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
|
|||||||
context->extra[0].y = 0;
|
context->extra[0].y = 0;
|
||||||
context->extra[0].next = &context->extra[1];
|
context->extra[0].next = &context->extra[1];
|
||||||
context->extra[1].x = (stbrp_coord) width;
|
context->extra[1].x = (stbrp_coord) width;
|
||||||
#ifdef STBRP_LARGE_RECTS
|
|
||||||
context->extra[1].y = (1<<30);
|
context->extra[1].y = (1<<30);
|
||||||
#else
|
|
||||||
context->extra[1].y = 65535;
|
|
||||||
#endif
|
|
||||||
context->extra[1].next = NULL;
|
context->extra[1].next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +429,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
|
|||||||
if (y <= best_y) {
|
if (y <= best_y) {
|
||||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||||
best_x = xpos;
|
best_x = xpos;
|
||||||
STBRP_ASSERT(y <= best_y);
|
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||||
best_y = y;
|
best_y = y;
|
||||||
best_waste = waste;
|
best_waste = waste;
|
||||||
best = prev;
|
best = prev;
|
||||||
@ -529,7 +525,6 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [DEAR IMGUI] Added STBRP__CDECL
|
|
||||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||||
@ -541,7 +536,6 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
|||||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [DEAR IMGUI] Added STBRP__CDECL
|
|
||||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||||
@ -549,12 +543,6 @@ static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
|||||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STBRP_LARGE_RECTS
|
|
||||||
#define STBRP__MAXVAL 0xffffffff
|
|
||||||
#else
|
|
||||||
#define STBRP__MAXVAL 0xffff
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||||
{
|
{
|
||||||
int i, all_rects_packed = 1;
|
int i, all_rects_packed = 1;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
// This is a slightly modified version of stb_textedit.h 1.13.
|
// This is a slightly modified version of stb_textedit.h 1.14.
|
||||||
// Those changes would need to be pushed into nothings/stb:
|
// Those changes would need to be pushed into nothings/stb:
|
||||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||||
|
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||||
|
|
||||||
// stb_textedit.h - v1.13 - public domain - Sean Barrett
|
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
||||||
// Development of this library was sponsored by RAD Game Tools
|
// Development of this library was sponsored by RAD Game Tools
|
||||||
//
|
//
|
||||||
// This C header file implements the guts of a multi-line text-editing
|
// This C header file implements the guts of a multi-line text-editing
|
||||||
@ -29,12 +31,13 @@
|
|||||||
// DEPENDENCIES
|
// DEPENDENCIES
|
||||||
//
|
//
|
||||||
// Uses the C runtime function 'memmove', which you can override
|
// Uses the C runtime function 'memmove', which you can override
|
||||||
// by defining STB_TEXTEDIT_memmove before the implementation.
|
// by defining IMSTB_TEXTEDIT_memmove before the implementation.
|
||||||
// Uses no other functions. Performs no runtime allocations.
|
// Uses no other functions. Performs no runtime allocations.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// VERSION HISTORY
|
// VERSION HISTORY
|
||||||
//
|
//
|
||||||
|
// 1.14 (2021-07-11) page up/down, various fixes
|
||||||
// 1.13 (2019-02-07) fix bug in undo size management
|
// 1.13 (2019-02-07) fix bug in undo size management
|
||||||
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
||||||
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
||||||
@ -58,6 +61,7 @@
|
|||||||
// Ulf Winklemann: move-by-word in 1.1
|
// Ulf Winklemann: move-by-word in 1.1
|
||||||
// Fabian Giesen: secondary key inputs in 1.5
|
// Fabian Giesen: secondary key inputs in 1.5
|
||||||
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
|
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
|
||||||
|
// Louis Schnellbach: page up/down in 1.14
|
||||||
//
|
//
|
||||||
// Bugfixes:
|
// Bugfixes:
|
||||||
// Scott Graham
|
// Scott Graham
|
||||||
@ -93,8 +97,8 @@
|
|||||||
// moderate sizes. The undo system does no memory allocations, so
|
// moderate sizes. The undo system does no memory allocations, so
|
||||||
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
|
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
|
||||||
//
|
//
|
||||||
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT
|
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATECOUNT
|
||||||
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT
|
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHARCOUNT
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Implementation mode:
|
// Implementation mode:
|
||||||
@ -271,8 +275,8 @@
|
|||||||
////
|
////
|
||||||
////
|
////
|
||||||
|
|
||||||
#ifndef INCLUDE_STB_TEXTEDIT_H
|
#ifndef INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
#define INCLUDE_STB_TEXTEDIT_H
|
#define INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -283,33 +287,33 @@
|
|||||||
// and undo state.
|
// and undo state.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
|
||||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
|
||||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_CHARTYPE
|
#ifndef IMSTB_TEXTEDIT_CHARTYPE
|
||||||
#define STB_TEXTEDIT_CHARTYPE int
|
#define IMSTB_TEXTEDIT_CHARTYPE int
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_POSITIONTYPE
|
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
|
||||||
#define STB_TEXTEDIT_POSITIONTYPE int
|
#define IMSTB_TEXTEDIT_POSITIONTYPE int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// private data
|
// private data
|
||||||
STB_TEXTEDIT_POSITIONTYPE where;
|
IMSTB_TEXTEDIT_POSITIONTYPE where;
|
||||||
STB_TEXTEDIT_POSITIONTYPE insert_length;
|
IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||||
STB_TEXTEDIT_POSITIONTYPE delete_length;
|
IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||||
int char_storage;
|
int char_storage;
|
||||||
} StbUndoRecord;
|
} StbUndoRecord;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// private data
|
// private data
|
||||||
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
|
||||||
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
|
||||||
short undo_point, redo_point;
|
short undo_point, redo_point;
|
||||||
int undo_char_point, redo_char_point;
|
int undo_char_point, redo_char_point;
|
||||||
} StbUndoState;
|
} StbUndoState;
|
||||||
@ -368,7 +372,7 @@ typedef struct
|
|||||||
float ymin,ymax; // height of row above and below baseline
|
float ymin,ymax; // height of row above and below baseline
|
||||||
int num_chars;
|
int num_chars;
|
||||||
} StbTexteditRow;
|
} StbTexteditRow;
|
||||||
#endif //INCLUDE_STB_TEXTEDIT_H
|
#endif //INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -381,11 +385,11 @@ typedef struct
|
|||||||
|
|
||||||
// implementation isn't include-guarded, since it might have indirectly
|
// implementation isn't include-guarded, since it might have indirectly
|
||||||
// included just the "header" portion
|
// included just the "header" portion
|
||||||
#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_memmove
|
#ifndef IMSTB_TEXTEDIT_memmove
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#define STB_TEXTEDIT_memmove memmove
|
#define IMSTB_TEXTEDIT_memmove memmove
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -395,7 +399,7 @@ typedef struct
|
|||||||
//
|
//
|
||||||
|
|
||||||
// traverse the layout to locate the nearest character to a display position
|
// traverse the layout to locate the nearest character to a display position
|
||||||
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||||
{
|
{
|
||||||
StbTexteditRow r;
|
StbTexteditRow r;
|
||||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
@ -455,7 +459,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
||||||
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||||
{
|
{
|
||||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||||
// goes off the top or bottom of the text
|
// goes off the top or bottom of the text
|
||||||
@ -473,7 +477,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
||||||
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||||
{
|
{
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
|
||||||
@ -499,11 +503,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
|||||||
//
|
//
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -515,36 +519,21 @@ typedef struct
|
|||||||
|
|
||||||
// find the x/y location of a character, and remember info about the previous row in
|
// find the x/y location of a character, and remember info about the previous row in
|
||||||
// case we get a move-up event (for page up, we'll have to rescan)
|
// case we get a move-up event (for page up, we'll have to rescan)
|
||||||
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||||
{
|
{
|
||||||
StbTexteditRow r;
|
StbTexteditRow r;
|
||||||
int prev_start = 0;
|
int prev_start = 0;
|
||||||
int z = STB_TEXTEDIT_STRINGLEN(str);
|
int z = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
int i=0, first;
|
int i=0, first;
|
||||||
|
|
||||||
if (n == z) {
|
if (n == z && single_line) {
|
||||||
// if it's at the end, then find the last line -- simpler than trying to
|
// special case if it's at the end (may not be needed?)
|
||||||
// explicitly handle this case in the regular code
|
|
||||||
if (single_line) {
|
|
||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||||
find->y = 0;
|
find->y = 0;
|
||||||
find->first_char = 0;
|
find->first_char = 0;
|
||||||
find->length = z;
|
find->length = z;
|
||||||
find->height = r.ymax - r.ymin;
|
find->height = r.ymax - r.ymin;
|
||||||
find->x = r.x1;
|
find->x = r.x1;
|
||||||
} else {
|
|
||||||
find->y = 0;
|
|
||||||
find->x = 0;
|
|
||||||
find->height = 1;
|
|
||||||
while (i < z) {
|
|
||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
|
||||||
prev_start = i;
|
|
||||||
i += r.num_chars;
|
|
||||||
}
|
|
||||||
find->first_char = i;
|
|
||||||
find->length = 0;
|
|
||||||
find->prev_first = prev_start;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,9 +544,16 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
|||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||||
if (n < i + r.num_chars)
|
if (n < i + r.num_chars)
|
||||||
break;
|
break;
|
||||||
|
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
|
||||||
|
break; // [DEAR IMGUI]
|
||||||
prev_start = i;
|
prev_start = i;
|
||||||
i += r.num_chars;
|
i += r.num_chars;
|
||||||
find->y += r.baseline_y_delta;
|
find->y += r.baseline_y_delta;
|
||||||
|
if (i == z) // [DEAR IMGUI]
|
||||||
|
{
|
||||||
|
r.num_chars = 0; // [DEAR IMGUI]
|
||||||
|
break; // [DEAR IMGUI]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find->first_char = first = i;
|
find->first_char = first = i;
|
||||||
@ -574,7 +570,7 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
|||||||
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
||||||
|
|
||||||
// make the selection/cursor state valid if client altered the string
|
// make the selection/cursor state valid if client altered the string
|
||||||
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
@ -588,7 +584,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete characters while updating undo
|
// delete characters while updating undo
|
||||||
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||||
{
|
{
|
||||||
stb_text_makeundo_delete(str, state, where, len);
|
stb_text_makeundo_delete(str, state, where, len);
|
||||||
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
||||||
@ -596,7 +592,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete the section
|
// delete the section
|
||||||
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
@ -633,7 +629,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// move cursor to last character of selection
|
// move cursor to last character of selection
|
||||||
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
stb_textedit_sortselection(state);
|
stb_textedit_sortselection(state);
|
||||||
@ -645,13 +641,13 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||||
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||||
{
|
{
|
||||||
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||||
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||||
{
|
{
|
||||||
--c; // always move at least one character
|
--c; // always move at least one character
|
||||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
while( c >= 0 && !is_word_boundary( str, c ) )
|
||||||
@ -666,7 +662,7 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||||
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
|
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||||
{
|
{
|
||||||
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
++c; // always move at least one character
|
++c; // always move at least one character
|
||||||
@ -693,7 +689,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API cut: delete selection
|
// API cut: delete selection
|
||||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||||
@ -704,7 +700,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API paste: replace existing selection with passed-in text
|
// API paste: replace existing selection with passed-in text
|
||||||
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
|
||||||
{
|
{
|
||||||
// if there's a selection, the paste should delete it
|
// if there's a selection, the paste should delete it
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
@ -716,10 +712,6 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
|||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// [DEAR IMGUI]
|
|
||||||
//// remove the undo since we didn't actually insert the characters
|
|
||||||
//if (state->undostate.undo_point)
|
|
||||||
// --state->undostate.undo_point;
|
|
||||||
// note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
|
// note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -729,14 +721,14 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// API key: process a keyboard input
|
// API key: process a keyboard input
|
||||||
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
switch (key) {
|
switch (key) {
|
||||||
default: {
|
default: {
|
||||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
||||||
|
|
||||||
// can't add newline in single-line mode
|
// can't add newline in single-line mode
|
||||||
if (c == '\n' && state->single_line)
|
if (c == '\n' && state->single_line)
|
||||||
@ -901,8 +893,8 @@ retry:
|
|||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ++i) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
x += dx;
|
x += dx;
|
||||||
@ -963,8 +955,8 @@ retry:
|
|||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ++i) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
x += dx;
|
x += dx;
|
||||||
@ -1121,8 +1113,8 @@ retry:
|
|||||||
|
|
||||||
static void stb_textedit_flush_redo(StbUndoState *state)
|
static void stb_textedit_flush_redo(StbUndoState *state)
|
||||||
{
|
{
|
||||||
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||||
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// discard the oldest entry in the undo list
|
// discard the oldest entry in the undo list
|
||||||
@ -1134,13 +1126,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
|||||||
int n = state->undo_rec[0].insert_length, i;
|
int n = state->undo_rec[0].insert_length, i;
|
||||||
// delete n characters from all other records
|
// delete n characters from all other records
|
||||||
state->undo_char_point -= n;
|
state->undo_char_point -= n;
|
||||||
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||||
for (i=0; i < state->undo_point; ++i)
|
for (i=0; i < state->undo_point; ++i)
|
||||||
if (state->undo_rec[i].char_storage >= 0)
|
if (state->undo_rec[i].char_storage >= 0)
|
||||||
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
||||||
}
|
}
|
||||||
--state->undo_point;
|
--state->undo_point;
|
||||||
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1150,7 +1142,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
|||||||
// fill up even though the undo buffer didn't
|
// fill up even though the undo buffer didn't
|
||||||
static void stb_textedit_discard_redo(StbUndoState *state)
|
static void stb_textedit_discard_redo(StbUndoState *state)
|
||||||
{
|
{
|
||||||
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||||
|
|
||||||
if (state->redo_point <= k) {
|
if (state->redo_point <= k) {
|
||||||
// if the k'th undo state has characters, clean those up
|
// if the k'th undo state has characters, clean those up
|
||||||
@ -1158,7 +1150,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
|||||||
int n = state->undo_rec[k].insert_length, i;
|
int n = state->undo_rec[k].insert_length, i;
|
||||||
// move the remaining redo character data to the end of the buffer
|
// move the remaining redo character data to the end of the buffer
|
||||||
state->redo_char_point += n;
|
state->redo_char_point += n;
|
||||||
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||||
// adjust the position of all the other records to account for above memmove
|
// adjust the position of all the other records to account for above memmove
|
||||||
for (i=state->redo_point; i < k; ++i)
|
for (i=state->redo_point; i < k; ++i)
|
||||||
if (state->undo_rec[i].char_storage >= 0)
|
if (state->undo_rec[i].char_storage >= 0)
|
||||||
@ -1166,12 +1158,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
|||||||
}
|
}
|
||||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||||
|
|
||||||
// now move redo_point to point to the new one
|
// now move redo_point to point to the new one
|
||||||
++state->redo_point;
|
++state->redo_point;
|
||||||
@ -1185,32 +1177,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
|
|||||||
|
|
||||||
// if we have no free records, we have to make room, by sliding the
|
// if we have no free records, we have to make room, by sliding the
|
||||||
// existing records down
|
// existing records down
|
||||||
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
stb_textedit_discard_undo(state);
|
stb_textedit_discard_undo(state);
|
||||||
|
|
||||||
// if the characters to store won't possibly fit in the buffer, we can't undo
|
// if the characters to store won't possibly fit in the buffer, we can't undo
|
||||||
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||||
state->undo_point = 0;
|
state->undo_point = 0;
|
||||||
state->undo_char_point = 0;
|
state->undo_char_point = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have enough free characters in the buffer, we have to make room
|
// if we don't have enough free characters in the buffer, we have to make room
|
||||||
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
|
||||||
stb_textedit_discard_undo(state);
|
stb_textedit_discard_undo(state);
|
||||||
|
|
||||||
return &state->undo_rec[state->undo_point++];
|
return &state->undo_rec[state->undo_point++];
|
||||||
}
|
}
|
||||||
|
|
||||||
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||||
{
|
{
|
||||||
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
r->where = pos;
|
r->where = pos;
|
||||||
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||||
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||||
|
|
||||||
if (insert_len == 0) {
|
if (insert_len == 0) {
|
||||||
r->char_storage = -1;
|
r->char_storage = -1;
|
||||||
@ -1222,7 +1214,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
StbUndoState *s = &state->undostate;
|
StbUndoState *s = &state->undostate;
|
||||||
StbUndoRecord u, *r;
|
StbUndoRecord u, *r;
|
||||||
@ -1249,7 +1241,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
// characters stored for *undoing* don't leave room for redo
|
// characters stored for *undoing* don't leave room for redo
|
||||||
// if the last is true, we have to bail
|
// if the last is true, we have to bail
|
||||||
|
|
||||||
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||||
// the undo records take up too much character space; there's no space to store the redo characters
|
// the undo records take up too much character space; there's no space to store the redo characters
|
||||||
r->insert_length = 0;
|
r->insert_length = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -1258,7 +1250,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
// there's definitely room to store the characters eventually
|
// there's definitely room to store the characters eventually
|
||||||
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
||||||
// should never happen:
|
// should never happen:
|
||||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
return;
|
return;
|
||||||
// there's currently not enough room, so discard a redo record
|
// there's currently not enough room, so discard a redo record
|
||||||
stb_textedit_discard_redo(s);
|
stb_textedit_discard_redo(s);
|
||||||
@ -1290,11 +1282,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|||||||
s->redo_point--;
|
s->redo_point--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
StbUndoState *s = &state->undostate;
|
StbUndoState *s = &state->undostate;
|
||||||
StbUndoRecord *u, r;
|
StbUndoRecord *u, r;
|
||||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we need to do two things: apply the redo record, and create an undo record
|
// we need to do two things: apply the redo record, and create an undo record
|
||||||
@ -1346,20 +1338,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
|
|||||||
stb_text_createundo(&state->undostate, where, 0, length);
|
stb_text_createundo(&state->undostate, where, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||||
if (p) {
|
if (p) {
|
||||||
for (i=0; i < length; ++i)
|
for (i=0; i < length; ++i)
|
||||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||||
if (p) {
|
if (p) {
|
||||||
for (i=0; i < old_length; ++i)
|
for (i=0; i < old_length; ++i)
|
||||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||||
@ -1371,8 +1363,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
|||||||
{
|
{
|
||||||
state->undostate.undo_point = 0;
|
state->undostate.undo_point = 0;
|
||||||
state->undostate.undo_char_point = 0;
|
state->undostate.undo_char_point = 0;
|
||||||
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||||
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||||
state->select_end = state->select_start = 0;
|
state->select_end = state->select_start = 0;
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@ -1395,16 +1387,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
|
|||||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||||
{
|
{
|
||||||
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif//STB_TEXTEDIT_IMPLEMENTATION
|
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
// This is a slightly modified version of stb_truetype.h 1.20.
|
// This is a slightly modified version of stb_truetype.h 1.26.
|
||||||
// Mostly fixing for compiler and static analyzer warnings.
|
// Mostly fixing for compiler and static analyzer warnings.
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
|
||||||
// stb_truetype.h - v1.20 - public domain
|
// stb_truetype.h - v1.26 - public domain
|
||||||
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
|
// authored from 2009-2021 by Sean Barrett / RAD Game Tools
|
||||||
|
//
|
||||||
|
// =======================================================================
|
||||||
|
//
|
||||||
|
// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
|
||||||
|
//
|
||||||
|
// This library does no range checking of the offsets found in the file,
|
||||||
|
// meaning an attacker can use it to read arbitrary memory.
|
||||||
|
//
|
||||||
|
// =======================================================================
|
||||||
//
|
//
|
||||||
// This library processes TrueType files:
|
// This library processes TrueType files:
|
||||||
// parse files
|
// parse files
|
||||||
@ -37,11 +46,11 @@
|
|||||||
// Daniel Ribeiro Maciel
|
// Daniel Ribeiro Maciel
|
||||||
//
|
//
|
||||||
// Bug/warning reports/fixes:
|
// Bug/warning reports/fixes:
|
||||||
// "Zer" on mollyrocket Fabian "ryg" Giesen
|
// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe
|
||||||
// Cass Everitt Martins Mozeiko
|
// Cass Everitt Martins Mozeiko github:aloucks
|
||||||
// stoiko (Haemimont Games) Cap Petschulat
|
// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam
|
||||||
// Brian Hook Omar Cornut
|
// Brian Hook Omar Cornut github:vassvik
|
||||||
// Walter van Niftrik github:aloucks
|
// Walter van Niftrik Ryan Griege
|
||||||
// David Gow Peter LaValle
|
// David Gow Peter LaValle
|
||||||
// David Given Sergey Popov
|
// David Given Sergey Popov
|
||||||
// Ivan-Assen Ivanov Giumo X. Clanjor
|
// Ivan-Assen Ivanov Giumo X. Clanjor
|
||||||
@ -49,11 +58,17 @@
|
|||||||
// Johan Duparc Thomas Fields
|
// Johan Duparc Thomas Fields
|
||||||
// Hou Qiming Derek Vinyard
|
// Hou Qiming Derek Vinyard
|
||||||
// Rob Loach Cort Stratton
|
// Rob Loach Cort Stratton
|
||||||
// Kenney Phillis Jr. github:oyvindjam
|
// Kenney Phillis Jr. Brian Costabile
|
||||||
// Brian Costabile github:vassvik
|
// Ken Voskuil (kaesve)
|
||||||
//
|
//
|
||||||
// VERSION HISTORY
|
// VERSION HISTORY
|
||||||
//
|
//
|
||||||
|
// 1.26 (2021-08-28) fix broken rasterizer
|
||||||
|
// 1.25 (2021-07-11) many fixes
|
||||||
|
// 1.24 (2020-02-05) fix warning
|
||||||
|
// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
|
||||||
|
// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
|
||||||
|
// 1.21 (2019-02-25) fix warning
|
||||||
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
||||||
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
|
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
|
||||||
// 1.18 (2018-01-29) add missing function
|
// 1.18 (2018-01-29) add missing function
|
||||||
@ -248,19 +263,6 @@
|
|||||||
// recommend it.
|
// recommend it.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// SOURCE STATISTICS (based on v0.6c, 2050 LOC)
|
|
||||||
//
|
|
||||||
// Documentation & header file 520 LOC \___ 660 LOC documentation
|
|
||||||
// Sample code 140 LOC /
|
|
||||||
// Truetype parsing 620 LOC ---- 620 LOC TrueType
|
|
||||||
// Software rasterization 240 LOC \.
|
|
||||||
// Curve tessellation 120 LOC \__ 550 LOC Bitmap creation
|
|
||||||
// Bitmap management 100 LOC /
|
|
||||||
// Baked bitmap interface 70 LOC /
|
|
||||||
// Font name matching & access 150 LOC ---- 150
|
|
||||||
// C runtime library abstraction 60 LOC ---- 60
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// PERFORMANCE MEASUREMENTS FOR 1.06:
|
// PERFORMANCE MEASUREMENTS FOR 1.06:
|
||||||
//
|
//
|
||||||
// 32-bit 64-bit
|
// 32-bit 64-bit
|
||||||
@ -275,8 +277,8 @@
|
|||||||
//// SAMPLE PROGRAMS
|
//// SAMPLE PROGRAMS
|
||||||
////
|
////
|
||||||
//
|
//
|
||||||
// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
|
// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless.
|
||||||
//
|
// See "tests/truetype_demo_win32.c" for a complete version.
|
||||||
#if 0
|
#if 0
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
|
#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
|
||||||
#include "stb_truetype.h"
|
#include "stb_truetype.h"
|
||||||
@ -302,6 +304,8 @@ void my_stbtt_initfont(void)
|
|||||||
void my_stbtt_print(float x, float y, char *text)
|
void my_stbtt_print(float x, float y, char *text)
|
||||||
{
|
{
|
||||||
// assume orthographic projection with units = screen pixels, origin at top left
|
// assume orthographic projection with units = screen pixels, origin at top left
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, ftex);
|
glBindTexture(GL_TEXTURE_2D, ftex);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
@ -309,10 +313,10 @@ void my_stbtt_print(float x, float y, char *text)
|
|||||||
if (*text >= 32 && *text < 128) {
|
if (*text >= 32 && *text < 128) {
|
||||||
stbtt_aligned_quad q;
|
stbtt_aligned_quad q;
|
||||||
stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
|
stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
|
||||||
glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
|
glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
|
||||||
glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
|
glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
|
||||||
glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
|
glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
|
||||||
glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
|
glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
|
||||||
}
|
}
|
||||||
++text;
|
++text;
|
||||||
}
|
}
|
||||||
@ -719,7 +723,7 @@ struct stbtt_fontinfo
|
|||||||
|
|
||||||
int numGlyphs; // number of glyphs, needed for range checking
|
int numGlyphs; // number of glyphs, needed for range checking
|
||||||
|
|
||||||
int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf
|
int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
|
||||||
int index_map; // a cmap mapping for our chosen character encoding
|
int index_map; // a cmap mapping for our chosen character encoding
|
||||||
int indexToLocFormat; // format needed to map from glyph index to glyph
|
int indexToLocFormat; // format needed to map from glyph index to glyph
|
||||||
|
|
||||||
@ -802,6 +806,18 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
|
|||||||
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
|
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
|
||||||
// as above, but takes one or more glyph indices for greater efficiency
|
// as above, but takes one or more glyph indices for greater efficiency
|
||||||
|
|
||||||
|
typedef struct stbtt_kerningentry
|
||||||
|
{
|
||||||
|
int glyph1; // use stbtt_FindGlyphIndex
|
||||||
|
int glyph2;
|
||||||
|
int advance;
|
||||||
|
} stbtt_kerningentry;
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
|
||||||
|
STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
|
||||||
|
// Retrieves a complete list of all of the kerning pairs provided by the font
|
||||||
|
// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
|
||||||
|
// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -846,6 +862,12 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
|
|||||||
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
|
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
|
||||||
// frees the data allocated above
|
// frees the data allocated above
|
||||||
|
|
||||||
|
STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl);
|
||||||
|
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
|
||||||
|
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
|
||||||
|
// fills svg with the character's SVG data.
|
||||||
|
// returns data size or 0 if SVG not found.
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// BITMAP RENDERING
|
// BITMAP RENDERING
|
||||||
@ -1347,6 +1369,22 @@ static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
|
|||||||
return stbtt__cff_get_index(&cff);
|
return stbtt__cff_get_index(&cff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// since most people won't use this, find this table the first time it's needed
|
||||||
|
static int stbtt__get_svg(stbtt_fontinfo *info)
|
||||||
|
{
|
||||||
|
stbtt_uint32 t;
|
||||||
|
if (info->svg < 0) {
|
||||||
|
t = stbtt__find_table(info->data, info->fontstart, "SVG ");
|
||||||
|
if (t) {
|
||||||
|
stbtt_uint32 offset = ttULONG(info->data + t + 2);
|
||||||
|
info->svg = t + offset;
|
||||||
|
} else {
|
||||||
|
info->svg = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info->svg;
|
||||||
|
}
|
||||||
|
|
||||||
static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
|
static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
|
||||||
{
|
{
|
||||||
stbtt_uint32 cmap, t;
|
stbtt_uint32 cmap, t;
|
||||||
@ -1426,6 +1464,8 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in
|
|||||||
else
|
else
|
||||||
info->numGlyphs = 0xffff;
|
info->numGlyphs = 0xffff;
|
||||||
|
|
||||||
|
info->svg = -1;
|
||||||
|
|
||||||
// find a cmap encoding table we understand *now* to avoid searching
|
// find a cmap encoding table we understand *now* to avoid searching
|
||||||
// later. (todo: could make this installable)
|
// later. (todo: could make this installable)
|
||||||
// the same regardless of glyph.
|
// the same regardless of glyph.
|
||||||
@ -1509,12 +1549,12 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
|
|||||||
search += 2;
|
search += 2;
|
||||||
|
|
||||||
{
|
{
|
||||||
stbtt_uint16 offset, start;
|
stbtt_uint16 offset, start, last;
|
||||||
stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
|
stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
|
||||||
|
|
||||||
STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
|
|
||||||
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
|
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
|
||||||
if (unicode_codepoint < start)
|
last = ttUSHORT(data + endCount + 2*item);
|
||||||
|
if (unicode_codepoint < start || unicode_codepoint > last)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
|
offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
|
||||||
@ -1774,7 +1814,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
|
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
|
||||||
} else if (numberOfContours == -1) {
|
} else if (numberOfContours < 0) {
|
||||||
// Compound shapes.
|
// Compound shapes.
|
||||||
int more = 1;
|
int more = 1;
|
||||||
stbtt_uint8 *comp = data + g + 10;
|
stbtt_uint8 *comp = data + g + 10;
|
||||||
@ -1841,7 +1881,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
|
|||||||
if (comp_verts) STBTT_free(comp_verts, info->userdata);
|
if (comp_verts) STBTT_free(comp_verts, info->userdata);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); //-V595
|
if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
|
||||||
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
|
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
|
||||||
if (vertices) STBTT_free(vertices, info->userdata);
|
if (vertices) STBTT_free(vertices, info->userdata);
|
||||||
vertices = tmp;
|
vertices = tmp;
|
||||||
@ -1851,9 +1891,6 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
|
|||||||
// More components ?
|
// More components ?
|
||||||
more = flags & (1<<5);
|
more = flags & (1<<5);
|
||||||
}
|
}
|
||||||
} else if (numberOfContours < 0) {
|
|
||||||
// @TODO other compound variations?
|
|
||||||
STBTT_assert(0);
|
|
||||||
} else {
|
} else {
|
||||||
// numberOfCounters == 0, do nothing
|
// numberOfCounters == 0, do nothing
|
||||||
}
|
}
|
||||||
@ -1971,7 +2008,7 @@ static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int gly
|
|||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fdselector == -1) stbtt__new_buf(NULL, 0);
|
if (fdselector == -1) return stbtt__new_buf(NULL, 0); // [DEAR IMGUI] fixed, see #6007 and nothings/stb#1422
|
||||||
return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
|
return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2107,7 +2144,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st
|
|||||||
subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
|
subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
|
||||||
has_subrs = 1;
|
has_subrs = 1;
|
||||||
}
|
}
|
||||||
// fallthrough
|
// FALLTHROUGH
|
||||||
case 0x1D: // callgsubr
|
case 0x1D: // callgsubr
|
||||||
if (sp < 1) return STBTT__CSERR("call(g|)subr stack");
|
if (sp < 1) return STBTT__CSERR("call(g|)subr stack");
|
||||||
v = (int) s[--sp];
|
v = (int) s[--sp];
|
||||||
@ -2212,7 +2249,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) //-V560
|
if (b0 != 255 && b0 != 28 && b0 < 32)
|
||||||
return STBTT__CSERR("reserved operator");
|
return STBTT__CSERR("reserved operator");
|
||||||
|
|
||||||
// push immediate
|
// push immediate
|
||||||
@ -2282,6 +2319,48 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
|
||||||
|
{
|
||||||
|
stbtt_uint8 *data = info->data + info->kern;
|
||||||
|
|
||||||
|
// we only look at the first table. it must be 'horizontal' and format 0.
|
||||||
|
if (!info->kern)
|
||||||
|
return 0;
|
||||||
|
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
|
||||||
|
return 0;
|
||||||
|
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ttUSHORT(data+10);
|
||||||
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length)
|
||||||
|
{
|
||||||
|
stbtt_uint8 *data = info->data + info->kern;
|
||||||
|
int k, length;
|
||||||
|
|
||||||
|
// we only look at the first table. it must be 'horizontal' and format 0.
|
||||||
|
if (!info->kern)
|
||||||
|
return 0;
|
||||||
|
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
|
||||||
|
return 0;
|
||||||
|
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
length = ttUSHORT(data+10);
|
||||||
|
if (table_length < length)
|
||||||
|
length = table_length;
|
||||||
|
|
||||||
|
for (k = 0; k < length; k++)
|
||||||
|
{
|
||||||
|
table[k].glyph1 = ttUSHORT(data+18+(k*6));
|
||||||
|
table[k].glyph2 = ttUSHORT(data+20+(k*6));
|
||||||
|
table[k].advance = ttSHORT(data+22+(k*6));
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
|
static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
|
||||||
{
|
{
|
||||||
stbtt_uint8 *data = info->data + info->kern;
|
stbtt_uint8 *data = info->data + info->kern;
|
||||||
@ -2315,7 +2394,7 @@ static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph
|
|||||||
static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
|
static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
|
||||||
{
|
{
|
||||||
stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
|
stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
|
||||||
switch(coverageFormat) {
|
switch (coverageFormat) {
|
||||||
case 1: {
|
case 1: {
|
||||||
stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
|
stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
|
||||||
|
|
||||||
@ -2336,7 +2415,8 @@ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyp
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 2: {
|
case 2: {
|
||||||
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
|
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
|
||||||
@ -2360,12 +2440,10 @@ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyp
|
|||||||
return startCoverageIndex + glyph - strawStart;
|
return startCoverageIndex + glyph - strawStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: return -1; // unsupported
|
||||||
// There are no other cases.
|
|
||||||
STBTT_assert(0);
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -2374,7 +2452,7 @@ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyp
|
|||||||
static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
||||||
{
|
{
|
||||||
stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
|
stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
|
||||||
switch(classDefFormat)
|
switch (classDefFormat)
|
||||||
{
|
{
|
||||||
case 1: {
|
case 1: {
|
||||||
stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
|
stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
|
||||||
@ -2383,10 +2461,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
|||||||
|
|
||||||
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
|
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
|
||||||
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
|
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
|
||||||
|
break;
|
||||||
// [DEAR IMGUI] Commented to fix static analyzer warning
|
}
|
||||||
//classDefTable = classDef1ValueArray + 2 * glyphCount;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 2: {
|
case 2: {
|
||||||
stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
|
stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
|
||||||
@ -2408,18 +2484,15 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
|||||||
else
|
else
|
||||||
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
|
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
// [DEAR IMGUI] Commented to fix static analyzer warning
|
|
||||||
//classDefTable = classRangeRecords + 6 * classRangeCount;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
// There are no other cases.
|
|
||||||
STBTT_assert(0);
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
default:
|
||||||
|
return -1; // Unsupported definition type, return an error.
|
||||||
|
}
|
||||||
|
|
||||||
|
// "All glyphs not assigned to a class fall into class 0". (OpenType spec)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define to STBTT_assert(x) if you want to break on unimplemented formats.
|
// Define to STBTT_assert(x) if you want to break on unimplemented formats.
|
||||||
@ -2431,7 +2504,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
|||||||
stbtt_uint8 *lookupList;
|
stbtt_uint8 *lookupList;
|
||||||
stbtt_uint16 lookupCount;
|
stbtt_uint16 lookupCount;
|
||||||
stbtt_uint8 *data;
|
stbtt_uint8 *data;
|
||||||
stbtt_int32 i;
|
stbtt_int32 i, sti;
|
||||||
|
|
||||||
if (!info->gpos) return 0;
|
if (!info->gpos) return 0;
|
||||||
|
|
||||||
@ -2451,9 +2524,9 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
|||||||
stbtt_uint16 lookupType = ttUSHORT(lookupTable);
|
stbtt_uint16 lookupType = ttUSHORT(lookupTable);
|
||||||
stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
|
stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
|
||||||
stbtt_uint8 *subTableOffsets = lookupTable + 6;
|
stbtt_uint8 *subTableOffsets = lookupTable + 6;
|
||||||
switch(lookupType) {
|
if (lookupType != 2) // Pair Adjustment Positioning Subtable
|
||||||
case 2: { // Pair Adjustment Positioning Subtable
|
continue;
|
||||||
stbtt_int32 sti;
|
|
||||||
for (sti=0; sti<subTableCount; sti++) {
|
for (sti=0; sti<subTableCount; sti++) {
|
||||||
stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
|
stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
|
||||||
stbtt_uint8 *table = lookupTable + subtableOffset;
|
stbtt_uint8 *table = lookupTable + subtableOffset;
|
||||||
@ -2468,20 +2541,15 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
|||||||
int straw, needle;
|
int straw, needle;
|
||||||
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
||||||
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
||||||
|
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
|
||||||
stbtt_int32 valueRecordPairSizeInBytes = 2;
|
stbtt_int32 valueRecordPairSizeInBytes = 2;
|
||||||
stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
|
stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
|
||||||
stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
|
stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
|
||||||
stbtt_uint8 *pairValueTable = table + pairPosOffset;
|
stbtt_uint8 *pairValueTable = table + pairPosOffset;
|
||||||
stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
|
stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
|
||||||
stbtt_uint8 *pairValueArray = pairValueTable + 2;
|
stbtt_uint8 *pairValueArray = pairValueTable + 2;
|
||||||
// TODO: Support more formats.
|
|
||||||
STBTT_GPOS_TODO_assert(valueFormat1 == 4);
|
|
||||||
if (valueFormat1 != 4) return 0;
|
|
||||||
STBTT_GPOS_TODO_assert(valueFormat2 == 0);
|
|
||||||
if (valueFormat2 != 0) return 0;
|
|
||||||
|
|
||||||
STBTT_assert(coverageIndex < pairSetCount);
|
if (coverageIndex >= pairSetCount) return 0;
|
||||||
STBTT__NOTUSED(pairSetCount);
|
|
||||||
|
|
||||||
needle=glyph2;
|
needle=glyph2;
|
||||||
r=pairValueCount-1;
|
r=pairValueCount-1;
|
||||||
@ -2504,12 +2572,15 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
|||||||
return xAdvance;
|
return xAdvance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 2: {
|
case 2: {
|
||||||
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
|
||||||
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
|
||||||
|
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
|
||||||
stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
|
stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
|
||||||
stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
|
stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
|
||||||
int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
|
int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
|
||||||
@ -2517,36 +2588,24 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
|||||||
|
|
||||||
stbtt_uint16 class1Count = ttUSHORT(table + 12);
|
stbtt_uint16 class1Count = ttUSHORT(table + 12);
|
||||||
stbtt_uint16 class2Count = ttUSHORT(table + 14);
|
stbtt_uint16 class2Count = ttUSHORT(table + 14);
|
||||||
STBTT_assert(glyph1class < class1Count);
|
stbtt_uint8 *class1Records, *class2Records;
|
||||||
STBTT_assert(glyph2class < class2Count);
|
stbtt_int16 xAdvance;
|
||||||
|
|
||||||
// TODO: Support more formats.
|
if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
|
||||||
STBTT_GPOS_TODO_assert(valueFormat1 == 4);
|
if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
|
||||||
if (valueFormat1 != 4) return 0;
|
|
||||||
STBTT_GPOS_TODO_assert(valueFormat2 == 0);
|
|
||||||
if (valueFormat2 != 0) return 0;
|
|
||||||
|
|
||||||
if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) {
|
class1Records = table + 16;
|
||||||
stbtt_uint8 *class1Records = table + 16;
|
class2Records = class1Records + 2 * (glyph1class * class2Count);
|
||||||
stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
|
xAdvance = ttSHORT(class2Records + 2 * glyph2class);
|
||||||
stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
|
|
||||||
return xAdvance;
|
return xAdvance;
|
||||||
}
|
} else
|
||||||
} break;
|
return 0;
|
||||||
|
|
||||||
default: {
|
|
||||||
// There are no other cases.
|
|
||||||
STBTT_assert(0);
|
|
||||||
break;
|
break;
|
||||||
} // [DEAR IMGUI] removed ;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
} // [DEAR IMGUI] removed ;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// TODO: Implement other stuff.
|
return 0; // Unsupported position format
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2559,8 +2618,7 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int
|
|||||||
|
|
||||||
if (info->gpos)
|
if (info->gpos)
|
||||||
xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
|
xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
|
||||||
|
else if (info->kern)
|
||||||
if (info->kern)
|
|
||||||
xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
|
xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
|
||||||
|
|
||||||
return xAdvance;
|
return xAdvance;
|
||||||
@ -2621,6 +2679,45 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
|
|||||||
STBTT_free(v, info->userdata);
|
STBTT_free(v, info->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
stbtt_uint8 *data = info->data;
|
||||||
|
stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
|
||||||
|
|
||||||
|
int numEntries = ttUSHORT(svg_doc_list);
|
||||||
|
stbtt_uint8 *svg_docs = svg_doc_list + 2;
|
||||||
|
|
||||||
|
for(i=0; i<numEntries; i++) {
|
||||||
|
stbtt_uint8 *svg_doc = svg_docs + (12 * i);
|
||||||
|
if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
|
||||||
|
return svg_doc;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg)
|
||||||
|
{
|
||||||
|
stbtt_uint8 *data = info->data;
|
||||||
|
stbtt_uint8 *svg_doc;
|
||||||
|
|
||||||
|
if (info->svg == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
svg_doc = stbtt_FindSVGDoc(info, gl);
|
||||||
|
if (svg_doc != NULL) {
|
||||||
|
*svg = (char *) data + info->svg + ttULONG(svg_doc + 4);
|
||||||
|
return ttULONG(svg_doc + 8);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg)
|
||||||
|
{
|
||||||
|
return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// antialiasing software rasterizer
|
// antialiasing software rasterizer
|
||||||
@ -2970,6 +3067,23 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)
|
||||||
|
{
|
||||||
|
STBTT_assert(top_width >= 0);
|
||||||
|
STBTT_assert(bottom_width >= 0);
|
||||||
|
return (top_width + bottom_width) / 2.0f * height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)
|
||||||
|
{
|
||||||
|
return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float stbtt__sized_triangle_area(float height, float width)
|
||||||
|
{
|
||||||
|
return height * width / 2;
|
||||||
|
}
|
||||||
|
|
||||||
static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
|
static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
|
||||||
{
|
{
|
||||||
float y_bottom = y_top+1;
|
float y_bottom = y_top+1;
|
||||||
@ -3024,13 +3138,13 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
|
|||||||
float height;
|
float height;
|
||||||
// simple case, only spans one pixel
|
// simple case, only spans one pixel
|
||||||
int x = (int) x_top;
|
int x = (int) x_top;
|
||||||
height = sy1 - sy0;
|
height = (sy1 - sy0) * e->direction;
|
||||||
STBTT_assert(x >= 0 && x < len);
|
STBTT_assert(x >= 0 && x < len);
|
||||||
scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
|
scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
|
||||||
scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
|
scanline_fill[x] += height; // everything right of this pixel is filled
|
||||||
} else {
|
} else {
|
||||||
int x,x1,x2;
|
int x,x1,x2;
|
||||||
float y_crossing, step, sign, area;
|
float y_crossing, y_final, step, sign, area;
|
||||||
// covers 2+ pixels
|
// covers 2+ pixels
|
||||||
if (x_top > x_bottom) {
|
if (x_top > x_bottom) {
|
||||||
// flip scanline vertically; signed area is the same
|
// flip scanline vertically; signed area is the same
|
||||||
@ -3042,32 +3156,83 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
|
|||||||
dx = -dx;
|
dx = -dx;
|
||||||
dy = -dy;
|
dy = -dy;
|
||||||
t = x0, x0 = xb, xb = t;
|
t = x0, x0 = xb, xb = t;
|
||||||
// [DEAR IMGUI] Fix static analyzer warning
|
|
||||||
(void)dx; // [ImGui: fix static analyzer warning]
|
|
||||||
}
|
}
|
||||||
|
STBTT_assert(dy >= 0);
|
||||||
|
STBTT_assert(dx >= 0);
|
||||||
|
|
||||||
x1 = (int) x_top;
|
x1 = (int) x_top;
|
||||||
x2 = (int) x_bottom;
|
x2 = (int) x_bottom;
|
||||||
// compute intersection with y axis at x1+1
|
// compute intersection with y axis at x1+1
|
||||||
y_crossing = (x1+1 - x0) * dy + y_top;
|
y_crossing = y_top + dy * (x1+1 - x0);
|
||||||
|
|
||||||
|
// compute intersection with y axis at x2
|
||||||
|
y_final = y_top + dy * (x2 - x0);
|
||||||
|
|
||||||
|
// x1 x_top x2 x_bottom
|
||||||
|
// y_top +------|-----+------------+------------+--------|---+------------+
|
||||||
|
// | | | | | |
|
||||||
|
// | | | | | |
|
||||||
|
// sy0 | Txxxxx|............|............|............|............|
|
||||||
|
// y_crossing | *xxxxx.......|............|............|............|
|
||||||
|
// | | xxxxx..|............|............|............|
|
||||||
|
// | | /- xx*xxxx........|............|............|
|
||||||
|
// | | dy < | xxxxxx..|............|............|
|
||||||
|
// y_final | | \- | xx*xxx.........|............|
|
||||||
|
// sy1 | | | | xxxxxB...|............|
|
||||||
|
// | | | | | |
|
||||||
|
// | | | | | |
|
||||||
|
// y_bottom +------------+------------+------------+------------+------------+
|
||||||
|
//
|
||||||
|
// goal is to measure the area covered by '.' in each pixel
|
||||||
|
|
||||||
|
// if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
|
||||||
|
// @TODO: maybe test against sy1 rather than y_bottom?
|
||||||
|
if (y_crossing > y_bottom)
|
||||||
|
y_crossing = y_bottom;
|
||||||
|
|
||||||
sign = e->direction;
|
sign = e->direction;
|
||||||
// area of the rectangle covered from y0..y_crossing
|
|
||||||
area = sign * (y_crossing-sy0);
|
|
||||||
// area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
|
|
||||||
scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
|
|
||||||
|
|
||||||
step = sign * dy;
|
// area of the rectangle covered from sy0..y_crossing
|
||||||
|
area = sign * (y_crossing-sy0);
|
||||||
|
|
||||||
|
// area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
|
||||||
|
scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
|
||||||
|
|
||||||
|
// check if final y_crossing is blown up; no test case for this
|
||||||
|
if (y_final > y_bottom) {
|
||||||
|
int denom = (x2 - (x1+1));
|
||||||
|
y_final = y_bottom;
|
||||||
|
if (denom != 0) { // [DEAR IMGUI] Avoid div by zero (https://github.com/nothings/stb/issues/1316)
|
||||||
|
dy = (y_final - y_crossing ) / denom; // if denom=0, y_final = y_crossing, so y_final <= y_bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// in second pixel, area covered by line segment found in first pixel
|
||||||
|
// is always a rectangle 1 wide * the height of that line segment; this
|
||||||
|
// is exactly what the variable 'area' stores. it also gets a contribution
|
||||||
|
// from the line segment within it. the THIRD pixel will get the first
|
||||||
|
// pixel's rectangle contribution, the second pixel's rectangle contribution,
|
||||||
|
// and its own contribution. the 'own contribution' is the same in every pixel except
|
||||||
|
// the leftmost and rightmost, a trapezoid that slides down in each pixel.
|
||||||
|
// the second pixel's contribution to the third pixel will be the
|
||||||
|
// rectangle 1 wide times the height change in the second pixel, which is dy.
|
||||||
|
|
||||||
|
step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
|
||||||
|
// which multiplied by 1-pixel-width is how much pixel area changes for each step in x
|
||||||
|
// so the area advances by 'step' every time
|
||||||
|
|
||||||
for (x = x1+1; x < x2; ++x) {
|
for (x = x1+1; x < x2; ++x) {
|
||||||
scanline[x] += area + step/2;
|
scanline[x] += area + step/2; // area of trapezoid is 1*step/2
|
||||||
area += step;
|
area += step;
|
||||||
}
|
}
|
||||||
y_crossing += dy * (x2 - (x1+1));
|
STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down
|
||||||
|
STBTT_assert(sy1 > y_final-0.01f);
|
||||||
|
|
||||||
STBTT_assert(STBTT_fabs(area) <= 1.01f);
|
// area covered in the last pixel is the rectangle from all the pixels to the left,
|
||||||
|
// plus the trapezoid filled by the line segment in this pixel all the way to the right edge
|
||||||
scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
|
scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f);
|
||||||
|
|
||||||
|
// the rest of the line is filled based on the total height of the line segment in this pixel
|
||||||
scanline_fill[x2] += sign * (sy1-sy0);
|
scanline_fill[x2] += sign * (sy1-sy0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3075,6 +3240,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
|
|||||||
// clipping logic. since this does not match the intended use
|
// clipping logic. since this does not match the intended use
|
||||||
// of this library, we use a different, very slow brute
|
// of this library, we use a different, very slow brute
|
||||||
// force implementation
|
// force implementation
|
||||||
|
// note though that this does happen some of the time because
|
||||||
|
// x_top and x_bottom can be extrapolated at the top & bottom of
|
||||||
|
// the shape and actually lie outside the bounding box
|
||||||
int x;
|
int x;
|
||||||
for (x=0; x < len; ++x) {
|
for (x=0; x < len; ++x) {
|
||||||
// cases:
|
// cases:
|
||||||
@ -3989,6 +4157,7 @@ static float stbtt__oversample_shift(int oversample)
|
|||||||
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
||||||
{
|
{
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
|
int missing_glyph_added = 0;
|
||||||
|
|
||||||
k=0;
|
k=0;
|
||||||
for (i=0; i < num_ranges; ++i) {
|
for (i=0; i < num_ranges; ++i) {
|
||||||
@ -4000,7 +4169,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
|||||||
int x0,y0,x1,y1;
|
int x0,y0,x1,y1;
|
||||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||||
int glyph = stbtt_FindGlyphIndex(info, codepoint);
|
int glyph = stbtt_FindGlyphIndex(info, codepoint);
|
||||||
if (glyph == 0 && spc->skip_missing) {
|
if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
|
||||||
rects[k].w = rects[k].h = 0;
|
rects[k].w = rects[k].h = 0;
|
||||||
} else {
|
} else {
|
||||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||||
@ -4010,6 +4179,8 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
|||||||
&x0,&y0,&x1,&y1);
|
&x0,&y0,&x1,&y1);
|
||||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||||
|
if (glyph == 0)
|
||||||
|
missing_glyph_added = 1;
|
||||||
}
|
}
|
||||||
++k;
|
++k;
|
||||||
}
|
}
|
||||||
@ -4044,7 +4215,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info
|
|||||||
// rects array must be big enough to accommodate all characters in the given ranges
|
// rects array must be big enough to accommodate all characters in the given ranges
|
||||||
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
|
||||||
{
|
{
|
||||||
int i,j,k, return_value = 1;
|
int i,j,k, missing_glyph = -1, return_value = 1;
|
||||||
|
|
||||||
// save current values
|
// save current values
|
||||||
int old_h_over = spc->h_oversample;
|
int old_h_over = spc->h_oversample;
|
||||||
@ -4109,6 +4280,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
|
|||||||
bc->yoff = (float) y0 * recip_v + sub_y;
|
bc->yoff = (float) y0 * recip_v + sub_y;
|
||||||
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
|
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
|
||||||
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
|
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
|
||||||
|
|
||||||
|
if (glyph == 0)
|
||||||
|
missing_glyph = j;
|
||||||
|
} else if (spc->skip_missing) {
|
||||||
|
return_value = 0;
|
||||||
|
} else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
|
||||||
|
ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
|
||||||
} else {
|
} else {
|
||||||
return_value = 0; // if any fail, report failure
|
return_value = 0; // if any fail, report failure
|
||||||
}
|
}
|
||||||
@ -4132,7 +4310,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect
|
|||||||
STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
|
STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
|
||||||
{
|
{
|
||||||
stbtt_fontinfo info;
|
stbtt_fontinfo info;
|
||||||
int i,j,n, return_value; // [DEAR IMGUI] removed = 1
|
int i, j, n, return_value; // [DEAR IMGUI] removed = 1;
|
||||||
//stbrp_context *context = (stbrp_context *) spc->pack_info;
|
//stbrp_context *context = (stbrp_context *) spc->pack_info;
|
||||||
stbrp_rect *rects;
|
stbrp_rect *rects;
|
||||||
|
|
||||||
@ -4301,15 +4479,14 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
|
|||||||
float y_frac;
|
float y_frac;
|
||||||
int winding = 0;
|
int winding = 0;
|
||||||
|
|
||||||
orig[0] = x;
|
|
||||||
//orig[1] = y; // [DEAR IMGUI] commented double assignment
|
|
||||||
|
|
||||||
// make sure y never passes through a vertex of the shape
|
// make sure y never passes through a vertex of the shape
|
||||||
y_frac = (float) STBTT_fmod(y, 1.0f);
|
y_frac = (float) STBTT_fmod(y, 1.0f);
|
||||||
if (y_frac < 0.01f)
|
if (y_frac < 0.01f)
|
||||||
y += 0.01f;
|
y += 0.01f;
|
||||||
else if (y_frac > 0.99f)
|
else if (y_frac > 0.99f)
|
||||||
y -= 0.01f;
|
y -= 0.01f;
|
||||||
|
|
||||||
|
orig[0] = x;
|
||||||
orig[1] = y;
|
orig[1] = y;
|
||||||
|
|
||||||
// test a ray from (-infinity,y) to (x,y)
|
// test a ray from (-infinity,y) to (x,y)
|
||||||
@ -4371,7 +4548,7 @@ static float stbtt__cuberoot( float x )
|
|||||||
return (float) STBTT_pow( x,1.0f/3.0f);
|
return (float) STBTT_pow( x,1.0f/3.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// x^3 + c*x^2 + b*x + a = 0
|
// x^3 + a*x^2 + b*x + c = 0
|
||||||
static int stbtt__solve_cubic(float a, float b, float c, float* r)
|
static int stbtt__solve_cubic(float a, float b, float c, float* r)
|
||||||
{
|
{
|
||||||
float s = -a / 3;
|
float s = -a / 3;
|
||||||
@ -4410,12 +4587,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||||||
int w,h;
|
int w,h;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
// if one scale is 0, use same scale for both
|
if (scale == 0) return NULL;
|
||||||
if (scale_x == 0) scale_x = scale_y;
|
|
||||||
if (scale_y == 0) {
|
|
||||||
if (scale_x == 0) return NULL; // if both scales are 0, return NULL
|
|
||||||
scale_y = scale_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
|
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
|
||||||
|
|
||||||
@ -4481,18 +4653,17 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||||||
for (i=0; i < num_verts; ++i) {
|
for (i=0; i < num_verts; ++i) {
|
||||||
float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
|
float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
|
||||||
|
|
||||||
// check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve
|
if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
|
||||||
float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
|
float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
|
||||||
|
|
||||||
|
float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
|
||||||
if (dist2 < min_dist*min_dist)
|
if (dist2 < min_dist*min_dist)
|
||||||
min_dist = (float) STBTT_sqrt(dist2);
|
min_dist = (float) STBTT_sqrt(dist2);
|
||||||
|
|
||||||
if (verts[i].type == STBTT_vline) {
|
|
||||||
float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
|
|
||||||
|
|
||||||
// coarse culling against bbox
|
// coarse culling against bbox
|
||||||
//if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
|
//if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
|
||||||
// sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
|
// sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
|
||||||
float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
|
dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
|
||||||
STBTT_assert(i != 0);
|
STBTT_assert(i != 0);
|
||||||
if (dist < min_dist) {
|
if (dist < min_dist) {
|
||||||
// check position along line
|
// check position along line
|
||||||
@ -4519,7 +4690,8 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||||||
float ax = x1-x0, ay = y1-y0;
|
float ax = x1-x0, ay = y1-y0;
|
||||||
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
|
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
|
||||||
float mx = x0 - sx, my = y0 - sy;
|
float mx = x0 - sx, my = y0 - sy;
|
||||||
float res[3],px,py,t,it;
|
float res[3] = {0.f,0.f,0.f};
|
||||||
|
float px,py,t,it,dist2;
|
||||||
float a_inv = precompute[i];
|
float a_inv = precompute[i];
|
||||||
if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
|
if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
|
||||||
float a = 3*(ax*bx + ay*by);
|
float a = 3*(ax*bx + ay*by);
|
||||||
@ -4546,6 +4718,10 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
|||||||
float d = (mx*ax+my*ay) * a_inv;
|
float d = (mx*ax+my*ay) * a_inv;
|
||||||
num = stbtt__solve_cubic(b, c, d, res);
|
num = stbtt__solve_cubic(b, c, d, res);
|
||||||
}
|
}
|
||||||
|
dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
|
||||||
|
if (dist2 < min_dist*min_dist)
|
||||||
|
min_dist = (float) STBTT_sqrt(dist2);
|
||||||
|
|
||||||
if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
|
if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
|
||||||
t = res[0], it = 1.0f - t;
|
t = res[0], it = 1.0f - t;
|
||||||
px = it*it*x0 + 2*t*it*x1 + t*t*x2;
|
px = it*it*x0 + 2*t*it*x1 + t*t*x2;
|
||||||
@ -4805,6 +4981,12 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
|
|||||||
|
|
||||||
// FULL VERSION HISTORY
|
// FULL VERSION HISTORY
|
||||||
//
|
//
|
||||||
|
// 1.25 (2021-07-11) many fixes
|
||||||
|
// 1.24 (2020-02-05) fix warning
|
||||||
|
// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
|
||||||
|
// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
|
||||||
|
// 1.21 (2019-02-25) fix warning
|
||||||
|
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
||||||
// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
|
// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
|
||||||
// 1.18 (2018-01-29) add missing function
|
// 1.18 (2018-01-29) add missing function
|
||||||
// 1.17 (2017-07-23) make more arguments const; doc fix
|
// 1.17 (2017-07-23) make more arguments const; doc fix
|
||||||
|
32
src/Menu.cpp
32
src/Menu.cpp
@ -182,7 +182,7 @@ namespace DX11_Base {
|
|||||||
//Creadit Mokobake
|
//Creadit Mokobake
|
||||||
//ImGui::Checkbox("MuteKiGodmode", &Config.IsMuteki);
|
//ImGui::Checkbox("MuteKiGodmode", &Config.IsMuteki);
|
||||||
|
|
||||||
if (ImGui::Button("ToggleInfAmmo",ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("ToggleInfAmmo",ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
if (Config.GetPalPlayerCharacter()->ShooterComponent != NULL && Config.GetPalPlayerCharacter()->ShooterComponent->CanShoot())
|
if (Config.GetPalPlayerCharacter()->ShooterComponent != NULL && Config.GetPalPlayerCharacter()->ShooterComponent->CanShoot())
|
||||||
{
|
{
|
||||||
@ -197,7 +197,7 @@ namespace DX11_Base {
|
|||||||
ImGui::SliderInt("AttackModifilers", &Config.DamageUp, 0, 200000);
|
ImGui::SliderInt("AttackModifilers", &Config.DamageUp, 0, 200000);
|
||||||
ImGui::SliderInt("defenseModifilers", &Config.DefuseUp, 0, 200000);
|
ImGui::SliderInt("defenseModifilers", &Config.DefuseUp, 0, 200000);
|
||||||
|
|
||||||
if (ImGui::Button("PrintPlayerAddr", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("PrintPlayerAddr", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -217,7 +217,7 @@ namespace DX11_Base {
|
|||||||
ImGui::InputInt("EXP:", &Config.EXP);
|
ImGui::InputInt("EXP:", &Config.EXP);
|
||||||
ImGui::InputText("Item Name", Config.ItemName,sizeof(Config.ItemName));
|
ImGui::InputText("Item Name", Config.ItemName,sizeof(Config.ItemName));
|
||||||
ImGui::InputInt("Item Num", &Config.Item);
|
ImGui::InputInt("Item Num", &Config.Item);
|
||||||
if (ImGui::Button("Give item", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("Give item", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -244,7 +244,7 @@ namespace DX11_Base {
|
|||||||
if (!Config.IsMonster){ImGui::InputInt("Pal Rank", &Config.PalRank);}
|
if (!Config.IsMonster){ImGui::InputInt("Pal Rank", &Config.PalRank);}
|
||||||
if (Config.IsMonster) { ImGui::InputInt("Pal Count", &Config.PalNum); }
|
if (Config.IsMonster) { ImGui::InputInt("Pal Count", &Config.PalNum); }
|
||||||
ImGui::InputInt("Pal lvl", &Config.PalLvL);
|
ImGui::InputInt("Pal lvl", &Config.PalLvL);
|
||||||
if (ImGui::Button("Spawn Pal", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("Spawn Pal", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
if (Config.GetPalPlayerCharacter() != NULL)
|
if (Config.GetPalPlayerCharacter() != NULL)
|
||||||
{
|
{
|
||||||
@ -261,7 +261,7 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("HomeTP", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("HomeTP", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -283,7 +283,7 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("AnywhereTP", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("AnywhereTP", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
if (Config.GetPalPlayerCharacter()!= NULL)
|
if (Config.GetPalPlayerCharacter()!= NULL)
|
||||||
{
|
{
|
||||||
@ -297,12 +297,12 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("ToggleFly", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("ToggleFly", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
Config.IsToggledFly = !Config.IsToggledFly;
|
Config.IsToggledFly = !Config.IsToggledFly;
|
||||||
ExploitFly(Config.IsToggledFly);
|
ExploitFly(Config.IsToggledFly);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("DeleteSelf", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("DeleteSelf", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -316,7 +316,7 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("GodHealth", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if (ImGui::Button("GodHealth", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -334,7 +334,7 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Creadit WoodgamerHD
|
//Creadit WoodgamerHD
|
||||||
if(ImGui::Button("Give exp", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20)))
|
if(ImGui::Button("Give exp", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20)))
|
||||||
{
|
{
|
||||||
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
SDK::APalPlayerCharacter* p_appc = Config.GetPalPlayerCharacter();
|
||||||
if (p_appc != NULL)
|
if (p_appc != NULL)
|
||||||
@ -361,7 +361,7 @@ namespace DX11_Base {
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::Button("UNHOOK DLL", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("UNHOOK DLL", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
g_Console->printdbg("\n\n[+] UNHOOK INITIALIZED [+]\n\n", g_Console->color.red);
|
g_Console->printdbg("\n\n[+] UNHOOK INITIALIZED [+]\n\n", g_Console->color.red);
|
||||||
|
|
||||||
@ -393,19 +393,19 @@ namespace DX11_Base {
|
|||||||
}
|
}
|
||||||
void TABQuick()//Creadit:asashi
|
void TABQuick()//Creadit:asashi
|
||||||
{
|
{
|
||||||
if (ImGui::Button("Basic Items stack", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("Basic Items stack", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
Spawn_Multiple(config::QuickItemSet::basic_items_stackable);
|
Spawn_Multiple(config::QuickItemSet::basic_items_stackable);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Basic Items single", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("Basic Items single", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
Spawn_Multiple(config::QuickItemSet::basic_items_single);
|
Spawn_Multiple(config::QuickItemSet::basic_items_single);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Unlock Pal skills", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("Unlock Pal skills", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
Spawn_Multiple(config::QuickItemSet::pal_unlock_skills);
|
Spawn_Multiple(config::QuickItemSet::pal_unlock_skills);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Spheres", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("Spheres", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
Spawn_Multiple(config::QuickItemSet::spheres);
|
Spawn_Multiple(config::QuickItemSet::spheres);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Tools", ImVec2(ImGui::GetWindowContentRegionWidth() - 3, 20))) {
|
if (ImGui::Button("Tools", ImVec2(ImGui::GetContentRegionAvail().x - 3, 20))) {
|
||||||
Spawn_Multiple(config::QuickItemSet::tools);
|
Spawn_Multiple(config::QuickItemSet::tools);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user