Fix 1:1 scale cursors being Australian

This commit is contained in:
Kae 2023-06-26 18:05:00 +10:00
parent c6cb370c13
commit 32411daa67
2 changed files with 21 additions and 12 deletions

View File

@ -681,20 +681,22 @@ private:
auto& entry = m_cursorCache.get(m_currentCursor = { scale, offset, id }, [&](auto const&) { auto& entry = m_cursorCache.get(m_currentCursor = { scale, offset, id }, [&](auto const&) {
auto entry = std::make_shared<CursorEntry>(); auto entry = std::make_shared<CursorEntry>();
if (scale != 1) { List<ImageOperation> operations;
List<ImageOperation> operations{ if (scale != 1)
FlipImageOperation{FlipImageOperation::Mode::FlipY}, // SDL wants an Australian cursor. operations = {
BorderImageOperation{1, Vec4B(), Vec4B(), false, false}, // Nearest scaling fucks up and clips half off the edges, work around this with border+crop for now. FlipImageOperation{ FlipImageOperation::Mode::FlipY }, // SDL wants an Australian cursor.
ScaleImageOperation{ScaleImageOperation::Mode::Nearest, Vec2F::filled(scale)}, BorderImageOperation{ 1, Vec4B(), Vec4B(), false, false }, // Nearest scaling fucks up and clips half off the edges, work around this with border+crop for now.
CropImageOperation{RectI::withSize(Vec2I::filled(ceilf((float)scale / 2)), Vec2I(imageSize))} ScaleImageOperation{ ScaleImageOperation::Mode::Nearest, Vec2F::filled(scale) },
CropImageOperation{ RectI::withSize(Vec2I::filled(ceilf((float)scale / 2)), Vec2I(imageSize)) }
}; };
auto newImage = std::make_shared<Image>(move(processImageOperations(operations, *image)));
// Fix fully transparent pixels inverting the underlying display pixel on Windows (allowing this could be made configurable per cursor later!)
newImage->forEachPixel([](unsigned x, unsigned y, Vec4B& pixel) { if (!pixel[3]) pixel[0] = pixel[1] = pixel[2] = 0; });
entry->image = move(newImage);
}
else else
entry->image = image; operations = { FlipImageOperation{ FlipImageOperation::Mode::FlipY } };
auto newImage = std::make_shared<Image>(move(processImageOperations(operations, *image)));
// Fix fully transparent pixels inverting the underlying display pixel on Windows (allowing this could be made configurable per cursor later!)
newImage->forEachPixel([](unsigned x, unsigned y, Vec4B& pixel) { if (!pixel[3]) pixel[0] = pixel[1] = pixel[2] = 0; });
entry->image = move(newImage);
auto size = entry->image->size(); auto size = entry->image->size();
uint32_t pixelFormat; uint32_t pixelFormat;

View File

@ -6,6 +6,8 @@
#include "StarImage.hpp" #include "StarImage.hpp"
#include "StarStringView.hpp" #include "StarStringView.hpp"
#include "StarEncode.hpp" #include "StarEncode.hpp"
//#include "StarTime.hpp"
//#include "StarLogging.hpp"
namespace Star { namespace Star {
@ -150,12 +152,15 @@ FadeToColorImageOperation::FadeToColorImageOperation(Vec3B color, float amount)
ImageOperation imageOperationFromString(StringView string) { ImageOperation imageOperationFromString(StringView string) {
try { try {
std::string_view view = string.utf8(); std::string_view view = string.utf8();
//double time = view.size() > 10000 ? Time::monotonicTime() : 0.0;
auto firstBitEnd = view.find_first_of("=;"); auto firstBitEnd = view.find_first_of("=;");
if (view.substr(0, firstBitEnd).compare("replace") == 0 && (firstBitEnd + 1) != view.size()) { if (view.substr(0, firstBitEnd).compare("replace") == 0 && (firstBitEnd + 1) != view.size()) {
//Perform optimized replace parse //Perform optimized replace parse
ColorReplaceImageOperation operation; ColorReplaceImageOperation operation;
std::string_view bits = view.substr(firstBitEnd + 1); std::string_view bits = view.substr(firstBitEnd + 1);
operation.colorReplaceMap.reserve(bits.size() / 8);
char const* hexPtr = nullptr; char const* hexPtr = nullptr;
unsigned int hexLen = 0; unsigned int hexLen = 0;
@ -207,6 +212,8 @@ ImageOperation imageOperationFromString(StringView string) {
break; break;
} }
//if (time != 0.0)
// Logger::logf(LogLevel::Debug, "Parsed %u long directives to %u replace operations in %fs", view.size(), operation.colorReplaceMap.size(), Time::monotonicTime() - time);
return move(operation); return move(operation);
} }