utf8 file handling fixes (#721)
This commit is contained in:
@@ -266,7 +266,9 @@ void GeneralWindow::Create(EditorComponent* _editor)
|
||||
params.extensions.push_back("xml");
|
||||
wi::helper::FileDialog(params, [=](std::string fileName) {
|
||||
editor->GetGUI().ExportLocalization(editor->current_localization);
|
||||
editor->current_localization.Export(wi::helper::ForceExtension(fileName, params.extensions.back()));
|
||||
std::string filenameExt = wi::helper::ForceExtension(fileName, params.extensions.back());
|
||||
editor->current_localization.Export(filenameExt);
|
||||
editor->PostSaveText("Localization template created: ", filenameExt);
|
||||
});
|
||||
});
|
||||
AddWidget(&localizationButton);
|
||||
|
||||
+11
-10
@@ -546,16 +546,17 @@ The Dump to header () option will use embedding and create a C++ header file
|
||||
<entry id="6">Erőtér </entry>
|
||||
<entry id="7">Matrica </entry>
|
||||
<entry id="8">Hang </entry>
|
||||
<entry id="9">Időjárás </entry>
|
||||
<entry id="10">Emitter </entry>
|
||||
<entry id="11">Haj Részecske </entry>
|
||||
<entry id="12">Kamera </entry>
|
||||
<entry id="13">Kocka </entry>
|
||||
<entry id="14">Sík </entry>
|
||||
<entry id="15">Animáció </entry>
|
||||
<entry id="16">Szkript </entry>
|
||||
<entry id="17">Ütköző </entry>
|
||||
<entry id="18">Terep </entry>
|
||||
<entry id="9">Videó </entry>
|
||||
<entry id="10">Időjárás </entry>
|
||||
<entry id="11">Emitter </entry>
|
||||
<entry id="12">Haj Részecske </entry>
|
||||
<entry id="13">Kamera </entry>
|
||||
<entry id="14">Kocka </entry>
|
||||
<entry id="15">Sík </entry>
|
||||
<entry id="16">Animáció </entry>
|
||||
<entry id="17">Szkript </entry>
|
||||
<entry id="18">Ütköző </entry>
|
||||
<entry id="19">Terep </entry>
|
||||
</section>
|
||||
</section>
|
||||
<section name="Materials" hint="Window">
|
||||
|
||||
+11
-10
@@ -547,16 +547,17 @@ The Dump to header () option will use embedding and create a C++ header file
|
||||
<entry id="6">フォース </entry>
|
||||
<entry id="7">デカル </entry>
|
||||
<entry id="8">音 </entry>
|
||||
<entry id="9">天気 </entry>
|
||||
<entry id="10">エミッター </entry>
|
||||
<entry id="11">ヘアパーティクル </entry>
|
||||
<entry id="12">カメラ </entry>
|
||||
<entry id="13">三乗 </entry>
|
||||
<entry id="14">プレーぬ </entry>
|
||||
<entry id="15">アニメーション </entry>
|
||||
<entry id="16">スクリプト </entry>
|
||||
<entry id="17">コライダー </entry>
|
||||
<entry id="18">地形 </entry>
|
||||
<entry id="9">ビデオ </entry>
|
||||
<entry id="10">天気 </entry>
|
||||
<entry id="11">エミッター </entry>
|
||||
<entry id="12">ヘアパーティクル </entry>
|
||||
<entry id="13">カメラ </entry>
|
||||
<entry id="14">三乗 </entry>
|
||||
<entry id="15">プレーぬ </entry>
|
||||
<entry id="16">アニメーション </entry>
|
||||
<entry id="17">スクリプト </entry>
|
||||
<entry id="18">コライダー </entry>
|
||||
<entry id="19">地形 </entry>
|
||||
</section>
|
||||
</section>
|
||||
<section name="Materials" hint="Window">
|
||||
|
||||
@@ -362,21 +362,17 @@ namespace wi::backlog
|
||||
}
|
||||
refitscroll = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
OutputDebugStringA(str.c_str());
|
||||
#endif // _WIN32
|
||||
|
||||
switch (level)
|
||||
{
|
||||
default:
|
||||
case LogLevel::Default:
|
||||
std::cout << str;
|
||||
wi::helper::DebugOut(str, wi::helper::DebugLevel::Normal);
|
||||
break;
|
||||
case LogLevel::Warning:
|
||||
std::clog << str;
|
||||
wi::helper::DebugOut(str, wi::helper::DebugLevel::Warning);
|
||||
break;
|
||||
case LogLevel::Error:
|
||||
std::cerr << str;
|
||||
wi::helper::DebugOut(str, wi::helper::DebugLevel::Error);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -324,6 +324,13 @@ namespace wi::font
|
||||
wi::backlog::post("wi::font Initialized (" + std::to_string((int)std::round(timer.elapsed())) + " ms)");
|
||||
}
|
||||
|
||||
void InvalidateAtlas()
|
||||
{
|
||||
texture = {};
|
||||
glyph_lookup.clear();
|
||||
rect_lookup.clear();
|
||||
bitmap_lookup.clear();
|
||||
}
|
||||
void UpdateAtlas(float upscaling)
|
||||
{
|
||||
std::scoped_lock locker(glyphLock);
|
||||
@@ -334,10 +341,7 @@ namespace wi::font
|
||||
if (upscaling_prev != upscaling)
|
||||
{
|
||||
// If upscaling changed (DPI change), clear glyph caches, they will need to be re-rendered:
|
||||
texture = {};
|
||||
glyph_lookup.clear();
|
||||
rect_lookup.clear();
|
||||
bitmap_lookup.clear();
|
||||
InvalidateAtlas();
|
||||
upscaling_prev = upscaling;
|
||||
}
|
||||
|
||||
@@ -483,6 +487,7 @@ namespace wi::font
|
||||
}
|
||||
fontStyles.push_back(std::make_unique<FontStyle>());
|
||||
fontStyles.back()->Create(fontName);
|
||||
InvalidateAtlas(); // invalidate atlas, in case there were missing glyphs, upon adding new font style they could become valid
|
||||
return int(fontStyles.size() - 1);
|
||||
}
|
||||
int AddFontStyle(const std::string& fontName, const uint8_t* data, size_t size)
|
||||
@@ -497,6 +502,7 @@ namespace wi::font
|
||||
}
|
||||
fontStyles.push_back(std::make_unique<FontStyle>());
|
||||
fontStyles.back()->Create(fontName, data, size);
|
||||
InvalidateAtlas(); // invalidate atlas, in case there were missing glyphs, upon adding new font style they could become valid
|
||||
return int(fontStyles.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -2318,9 +2318,7 @@ using namespace dx12_internal;
|
||||
if (FAILED(hr) || !allowTearing)
|
||||
{
|
||||
tearingSupported = false;
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("WARNING: Variable refresh rate displays not supported\n");
|
||||
#endif
|
||||
wi::helper::DebugOut("WARNING: Variable refresh rate displays not supported\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+61
-26
@@ -19,6 +19,7 @@ extern basist::etc1_global_selector_codebook g_basis_global_codebook;
|
||||
#include <codecvt> // string conversion
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
@@ -77,7 +78,7 @@ namespace wi::helper
|
||||
// UWP can only show message box on main thread:
|
||||
wi::eventhandler::Subscribe_Once(wi::eventhandler::EVENT_THREAD_SAFE_POINT, [=](uint64_t userdata) {
|
||||
winrt::Windows::UI::Popups::MessageDialog(wmessage, wcaption).ShowAsync();
|
||||
});
|
||||
});
|
||||
#endif // PLATFORM_UWP
|
||||
#elif SDL2
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption.c_str(), msg.c_str(), NULL);
|
||||
@@ -96,7 +97,7 @@ namespace wi::helper
|
||||
directory = GetDirectoryFromPath(name);
|
||||
}
|
||||
|
||||
if(!directory.empty()) //PE: Crash if only filename is used with no folder.
|
||||
if (!directory.empty()) //PE: Crash if only filename is used with no folder.
|
||||
DirectoryCreate(directory);
|
||||
|
||||
std::string filename = name;
|
||||
@@ -737,6 +738,18 @@ namespace wi::helper
|
||||
return filename.substr(0, idx);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// On windows we need to expand UTF8 strings to UTF16 when passing it to WinAPI:
|
||||
std::wstring ToNativeString(const std::string& fileName)
|
||||
{
|
||||
std::wstring fileName_wide;
|
||||
StringConvert(fileName, fileName_wide);
|
||||
return fileName_wide;
|
||||
}
|
||||
#else
|
||||
#define ToNativeString(x) (x)
|
||||
#endif // _WIN32
|
||||
|
||||
void MakePathRelative(const std::string& rootdir, std::string& path)
|
||||
{
|
||||
if (rootdir.empty() || path.empty())
|
||||
@@ -754,14 +767,14 @@ namespace wi::helper
|
||||
|
||||
#else
|
||||
|
||||
std::filesystem::path filepath = path;
|
||||
std::filesystem::path filepath = ToNativeString(path);
|
||||
if (filepath.is_absolute())
|
||||
{
|
||||
std::filesystem::path rootpath = rootdir;
|
||||
std::filesystem::path relative = std::filesystem::relative(path, rootdir);
|
||||
std::filesystem::path rootpath = ToNativeString(rootdir);
|
||||
std::filesystem::path relative = std::filesystem::relative(filepath, rootpath);
|
||||
if (!relative.empty())
|
||||
{
|
||||
path = relative.string();
|
||||
path = relative.generic_u8string();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,17 +784,16 @@ namespace wi::helper
|
||||
|
||||
void MakePathAbsolute(std::string& path)
|
||||
{
|
||||
std::filesystem::path filepath = path;
|
||||
std::filesystem::path absolute = std::filesystem::absolute(path);
|
||||
std::filesystem::path absolute = std::filesystem::absolute(ToNativeString(path));
|
||||
if (!absolute.empty())
|
||||
{
|
||||
path = absolute.string();
|
||||
path = absolute.generic_u8string();
|
||||
}
|
||||
}
|
||||
|
||||
void DirectoryCreate(const std::string& path)
|
||||
{
|
||||
std::filesystem::create_directories(path);
|
||||
std::filesystem::create_directories(ToNativeString(path));
|
||||
}
|
||||
|
||||
template<template<typename T, typename A> typename vector_interface>
|
||||
@@ -790,18 +802,10 @@ namespace wi::helper
|
||||
#ifndef PLATFORM_UWP
|
||||
#ifdef SDL_FILESYSTEM_UNIX
|
||||
std::string filepath = fileName;
|
||||
std::replace(filepath.begin(), filepath.end(), '\\', '/');
|
||||
std::replace(filepath.begin(), filepath.end(), '\\', '/'); // Linux cannot handle backslash in file path, need to convert it to forward slash
|
||||
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
|
||||
#else
|
||||
|
||||
#ifdef _WIN32
|
||||
std::wstring fileName_wide;
|
||||
StringConvert(fileName, fileName_wide);
|
||||
std::ifstream file(fileName_wide, std::ios::binary | std::ios::ate);
|
||||
#else
|
||||
std::ifstream file(fileName, std::ios::binary | std::ios::ate);
|
||||
#endif //_WIN32
|
||||
|
||||
std::ifstream file(ToNativeString(fileName), std::ios::binary | std::ios::ate);
|
||||
#endif // SDL_FILESYSTEM_UNIX
|
||||
if (file.is_open())
|
||||
{
|
||||
@@ -888,7 +892,7 @@ namespace wi::helper
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_UWP
|
||||
std::ofstream file(fileName, std::ios::binary | std::ios::trunc);
|
||||
std::ofstream file(ToNativeString(fileName), std::ios::binary | std::ios::trunc);
|
||||
if (file.is_open())
|
||||
{
|
||||
file.write((const char*)data, (std::streamsize)size);
|
||||
@@ -956,7 +960,7 @@ namespace wi::helper
|
||||
bool FileExists(const std::string& fileName)
|
||||
{
|
||||
#ifndef PLATFORM_UWP
|
||||
bool exists = std::filesystem::exists(fileName);
|
||||
bool exists = std::filesystem::exists(ToNativeString(fileName));
|
||||
return exists;
|
||||
#else
|
||||
using namespace winrt::Windows::Storage;
|
||||
@@ -1001,16 +1005,22 @@ namespace wi::helper
|
||||
#endif // PLATFORM_UWP
|
||||
}
|
||||
|
||||
uint64_t FileTimestamp(const std::string& fileName)
|
||||
{
|
||||
auto tim = std::filesystem::last_write_time(ToNativeString(fileName));
|
||||
return std::chrono::duration_cast<std::chrono::duration<uint64_t>>(tim.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
std::string GetTempDirectoryPath()
|
||||
{
|
||||
auto path = std::filesystem::temp_directory_path();
|
||||
return path.string();
|
||||
return path.generic_u8string();
|
||||
}
|
||||
|
||||
std::string GetCurrentPath()
|
||||
{
|
||||
auto path = std::filesystem::current_path();
|
||||
return path.string();
|
||||
return path.generic_u8string();
|
||||
}
|
||||
|
||||
void FileDialog(const FileDialogParams& params, std::function<void(std::string fileName)> onSuccess)
|
||||
@@ -1221,10 +1231,11 @@ namespace wi::helper
|
||||
|
||||
void GetFileNamesInDirectory(const std::string& directory, std::function<void(std::string fileName)> onSuccess, const std::string& filter_extension)
|
||||
{
|
||||
if (!std::filesystem::exists(directory))
|
||||
std::filesystem::path directory_path = ToNativeString(directory);
|
||||
if (!std::filesystem::exists(directory_path))
|
||||
return;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory))
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory_path))
|
||||
{
|
||||
std::string filename = entry.path().filename().generic_u8string();
|
||||
if (filter_extension.empty() || wi::helper::toUpper(wi::helper::GetExtensionFromFileName(filename)).compare(filter_extension) == 0)
|
||||
@@ -1314,6 +1325,30 @@ namespace wi::helper
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void DebugOut(const std::string& str, DebugLevel level)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifdef _WIN32
|
||||
std::wstring wstr = ToNativeString(str);
|
||||
OutputDebugString(wstr.c_str());
|
||||
#else
|
||||
switch (level)
|
||||
{
|
||||
default:
|
||||
case DebugLevel::Normal:
|
||||
std::cout << str;
|
||||
break;
|
||||
case DebugLevel::Warning:
|
||||
std::clog << str;
|
||||
break;
|
||||
case DebugLevel::Error:
|
||||
std::cerr << str;
|
||||
break;
|
||||
}
|
||||
#endif // _WIN32
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
void Sleep(float milliseconds)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((int)milliseconds));
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace wi::helper
|
||||
|
||||
bool FileExists(const std::string& fileName);
|
||||
|
||||
uint64_t FileTimestamp(const std::string& fileName);
|
||||
|
||||
std::string GetTempDirectoryPath();
|
||||
std::string GetCurrentPath();
|
||||
|
||||
@@ -129,6 +131,15 @@ namespace wi::helper
|
||||
// returns result string length
|
||||
int StringConvert(const wchar_t* from, char* to);
|
||||
|
||||
// Prints debug info to the console output
|
||||
enum class DebugLevel
|
||||
{
|
||||
Normal,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
void DebugOut(const std::string& str, DebugLevel level = DebugLevel::Normal);
|
||||
|
||||
// Puts the current thread to sleeping state for a given time (OS can overtake)
|
||||
void Sleep(float milliseconds);
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "wiUnorderedSet.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef PLATFORM_WINDOWS_DESKTOP
|
||||
#define SHADERCOMPILER_ENABLED
|
||||
@@ -741,7 +740,7 @@ namespace wi::shadercompiler
|
||||
return false; // no metadata file = no dependency, up to date (for example packaged builds)
|
||||
}
|
||||
|
||||
const auto tim = std::filesystem::last_write_time(filepath);
|
||||
const uint64_t tim = wi::helper::FileTimestamp(filepath);
|
||||
|
||||
wi::Archive dependencyLibrary(dependencylibrarypath);
|
||||
if (dependencyLibrary.IsOpen())
|
||||
@@ -756,7 +755,7 @@ namespace wi::shadercompiler
|
||||
wi::helper::MakePathAbsolute(dependencypath);
|
||||
if (wi::helper::FileExists(dependencypath))
|
||||
{
|
||||
const auto dep_tim = std::filesystem::last_write_time(dependencypath);
|
||||
const uint64_t dep_tim = wi::helper::FileTimestamp(dependencypath);
|
||||
|
||||
if (tim < dep_tim)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 71;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 270;
|
||||
const int revision = 271;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
@@ -89,6 +89,7 @@ Contributors
|
||||
- Fixes
|
||||
- Dennis Brakhane | https://github.com/brakhane
|
||||
- Added Liberation Sans default font
|
||||
- Vulkan improvements
|
||||
- Cop46 | https://github.com/Cop46
|
||||
- Brightness, Contrast, Saturation post process
|
||||
|
||||
@@ -131,6 +132,7 @@ Patreon supporters
|
||||
- Dominik Madarász
|
||||
- Segfault
|
||||
- Mike amanfo
|
||||
- Dennis Brakhane
|
||||
)";
|
||||
|
||||
return credits;
|
||||
|
||||
Reference in New Issue
Block a user