mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
fix: Remaining Subpixel rendering issues
This commit is contained in:
@@ -423,10 +423,10 @@ void ImGui_ImplOpenGL3_NewFrame()
|
||||
bool useFontShaders = false;
|
||||
|
||||
void FontShadersOn(const ImDrawList *parent_list, const ImDrawCmd *cmd) {
|
||||
useFontShaders = !useFontShaders;
|
||||
useFontShaders = true;
|
||||
}
|
||||
void FontShadersOff(const ImDrawList *parent_list, const ImDrawCmd *cmd) {
|
||||
useFontShaders = !useFontShaders;
|
||||
useFontShaders = false;
|
||||
}
|
||||
ImDrawCallback ImGui_ImplOpenGL3_TurnFontShadersOn = &FontShadersOn;
|
||||
ImDrawCallback ImGui_ImplOpenGL3_TurnFontShadersOff = &FontShadersOff;
|
||||
|
||||
@@ -1716,6 +1716,15 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
font_size = _Data->FontSize;
|
||||
|
||||
IM_ASSERT(font->ContainerAtlas->TexID == _CmdHeader.TextureId); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
|
||||
ImVec4 clip_rect = _CmdHeader.ClipRect;
|
||||
if (cpu_fine_clip_rect)
|
||||
{
|
||||
clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x);
|
||||
clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y);
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||
}
|
||||
|
||||
// IMHEX PATCH BEGIN
|
||||
int flags;
|
||||
bool is_subpixel = false;
|
||||
@@ -1726,15 +1735,9 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
if (is_subpixel)
|
||||
AddCallback(ImGui_ImplOpenGL3_TurnFontShadersOn, NULL);
|
||||
// IMHEX PATCH END
|
||||
ImVec4 clip_rect = _CmdHeader.ClipRect;
|
||||
if (cpu_fine_clip_rect)
|
||||
{
|
||||
clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x);
|
||||
clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y);
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||
}
|
||||
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
|
||||
|
||||
// IMHEX PATCH BEGIN
|
||||
if (is_subpixel)
|
||||
AddCallback(ImGui_ImplOpenGL3_TurnFontShadersOff, NULL);
|
||||
@@ -3329,15 +3332,8 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid
|
||||
TexPixelsRGBA32 = (unsigned int*)IM_ALLOC((size_t)TexWidth * (size_t)TexHeight * 4);
|
||||
const unsigned char* src = pixels;
|
||||
unsigned int* dst = TexPixelsRGBA32;
|
||||
// IMHEX PATCH BEGIN
|
||||
if (FontBuilderFlags & ImGuiFreeTypeBuilderFlags_SubPixel) {
|
||||
for (int n = TexWidth * TexHeight; n > 0; n--,src++)
|
||||
*dst++ = IM_COL32(*src, *src, *src, *src);
|
||||
} else {
|
||||
for (int n = TexWidth * TexHeight; n > 0; n--)
|
||||
*dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++));
|
||||
}
|
||||
// IMHEX PATCH END
|
||||
for (int n = TexWidth * TexHeight; n > 0; n--)
|
||||
*dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace hex::fonts {
|
||||
}
|
||||
|
||||
float calculateFontDescend(FT_Library ft, float fontSize) const {
|
||||
|
||||
if (ft == nullptr) {
|
||||
log::fatal("FreeType not initialized");
|
||||
return 0.0f;
|
||||
@@ -46,14 +45,17 @@ namespace hex::fonts {
|
||||
if (m_font->FontSize > 0.0F)
|
||||
size = m_font->FontSize * std::max(1.0F, std::floor(ImHexApi::System::getGlobalScale()));
|
||||
else
|
||||
size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize;
|
||||
size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize * std::floor(ImHexApi::System::getGlobalScale());
|
||||
|
||||
if (FT_Set_Pixel_Sizes(face, size, size) != 0) {
|
||||
log::fatal("Failed to set pixel size");
|
||||
return 0.0f;
|
||||
}
|
||||
FT_Size_RequestRec req;
|
||||
req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)(IM_ROUND(size) * 64.0F);
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(face, &req);
|
||||
|
||||
return face->size->metrics.descender / 64.0F;
|
||||
return face->size->metrics.ascender / 64.0F;
|
||||
}
|
||||
|
||||
ImFont* getFont() { return m_font; }
|
||||
@@ -249,18 +251,13 @@ namespace hex::fonts {
|
||||
log::fatal("Failed to load face");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Calculate the expected font size
|
||||
auto size = fontSize;
|
||||
if (font.defaultSize.has_value())
|
||||
size = font.defaultSize.value() * std::max(1.0F, std::floor(ImHexApi::System::getGlobalScale()));
|
||||
else
|
||||
size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize;
|
||||
|
||||
if (FT_Set_Pixel_Sizes(face, size, size) != 0) {
|
||||
log::fatal("Failed to set pixel size");
|
||||
return false;
|
||||
}
|
||||
FT_Size_RequestRec req;
|
||||
req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)(IM_ROUND(fontSize) * 64.0F);
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(face, &req);
|
||||
|
||||
return face->size->metrics.descender / 64.0F;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace hex::fonts {
|
||||
|
||||
bool BuildSubPixelAtlas(FontAtlas *fontAtlas, float fontSize) {
|
||||
bool BuildSubPixelAtlas(FontAtlas *fontAtlas) {
|
||||
FT_Library ft = nullptr;
|
||||
if (FT_Init_FreeType(&ft) != 0) {
|
||||
log::fatal("Failed to initialize FreeType");
|
||||
@@ -41,10 +41,10 @@ namespace hex::fonts {
|
||||
std::map<ImS32, ft::Bitmap> bitmapLCD;
|
||||
ImU32 fontCount = io.Fonts->ConfigData.Size;
|
||||
for (ImU32 i = 0; i < fontCount; i++) {
|
||||
std::string fontName = io.Fonts->ConfigData[i].Name;
|
||||
const auto config = io.Fonts->ConfigData[i];
|
||||
const auto &fontName = config.Name;
|
||||
|
||||
std::ranges::transform(fontName.begin(), fontName.end(), fontName.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
if (fontName == "nonscalable") {
|
||||
if (hex::equalsIgnoreCase(fontName, "nonscalable")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,25 +53,20 @@ namespace hex::fonts {
|
||||
return false;
|
||||
}
|
||||
|
||||
float actualFontSize;
|
||||
if (fontName.find("icon") != std::string::npos)
|
||||
actualFontSize = ImHexApi::Fonts::pointsToPixels(fontSize);
|
||||
else
|
||||
actualFontSize = fontSize;
|
||||
|
||||
if (FT_Set_Pixel_Sizes(face, actualFontSize, actualFontSize) != 0) {
|
||||
log::fatal("Failed to set pixel size");
|
||||
return false;
|
||||
}
|
||||
FT_Size_RequestRec req;
|
||||
req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)(IM_ROUND(config.SizePixels) * 64.0F);
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(face, &req);
|
||||
|
||||
FT_UInt gIndex;
|
||||
FT_ULong charCode = FT_Get_First_Char(face, &gIndex);
|
||||
|
||||
while (gIndex != 0) {
|
||||
|
||||
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, charCode);
|
||||
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD | FT_LOAD_TARGET_LIGHT | FT_LOAD_RENDER) != 0) {
|
||||
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD | FT_LOAD_TARGET_LIGHT | FT_LOAD_RENDER) != 0) {
|
||||
IM_ASSERT(true && "Failed to load glyph");
|
||||
return false;
|
||||
}
|
||||
@@ -82,17 +77,15 @@ namespace hex::fonts {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto width = bitmap_lcd.getWidth() / 3;
|
||||
auto width = bitmap_lcd.getWidth() / 3.0F;
|
||||
auto height = bitmap_lcd.getHeight();
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Size size = face->size;
|
||||
|
||||
ImVec2 offset = ImVec2((slot->metrics.horiBearingX / 64.0f), (size->metrics.ascender - slot->metrics.horiBearingY) / 64.0f);
|
||||
if (fontName.find("codicon") != std::string::npos)
|
||||
offset.x -= 1.0f;
|
||||
ImS32 advance = (float) slot->advance.x / 64.0f;
|
||||
if (offset.x+width > advance && advance >= (int) width)
|
||||
offset.x = advance - width;
|
||||
ImVec2 offset = ImVec2(face->glyph->bitmap_left, -face->glyph->bitmap_top);
|
||||
offset.x += config.GlyphOffset.x;
|
||||
offset.y += size->metrics.ascender / 64.0F;
|
||||
ImS32 advance = (float) slot->advance.x / 64.0F;
|
||||
|
||||
ImS32 rect_id = io.Fonts->AddCustomRectFontGlyph(io.Fonts->Fonts[0], charCode, width, height, advance, offset);
|
||||
rect_ids.push_back(rect_id);
|
||||
@@ -154,6 +147,7 @@ namespace hex::fonts {
|
||||
u32 fontIndex = 0;
|
||||
auto io = ImGui::GetIO();
|
||||
io.Fonts = fontAtlas->getAtlas();
|
||||
|
||||
// Check if Unicode support is enabled in the settings and that the user doesn't use the No GPU version on Windows
|
||||
// The Mesa3D software renderer on Windows identifies itself as "VMware, Inc."
|
||||
bool shouldLoadUnicode = ContentRegistry::Settings::read<bool>("hex.fonts.setting.font", "hex.fonts.setting.font.load_all_unicode_chars", false) && ImHexApi::System::getGPUVendor() != "VMware, Inc.";
|
||||
@@ -221,13 +215,16 @@ namespace hex::fonts {
|
||||
glyphRanges.push_back(glyphRange);
|
||||
|
||||
// Calculate the glyph offset for the font
|
||||
const ImVec2 offset = { font.offset.x, font.offset.y - (defaultFont->calculateFontDescend(ft, realFontSize) - fontAtlas->calculateFontDescend(ft, font, realFontSize)) };
|
||||
|
||||
// Load the font
|
||||
float size = realFontSize;
|
||||
if (font.defaultSize.has_value())
|
||||
size = font.defaultSize.value() * ImHexApi::System::getBackingScaleFactor();
|
||||
|
||||
const ImVec2 offset = { font.offset.x, font.offset.y + ImCeil(4_scaled) };
|
||||
|
||||
fontAtlas->addFontFromMemory(font.fontData, size, !font.defaultSize.has_value(), offset, glyphRanges.back());
|
||||
|
||||
if (!font.scalable.value_or(true)) {
|
||||
std::string fontName = "NonScalable";
|
||||
auto nameSize = fontName.size();
|
||||
@@ -252,6 +249,6 @@ namespace hex::fonts {
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return BuildSubPixelAtlas(fontAtlas,fontSize);
|
||||
return BuildSubPixelAtlas(fontAtlas);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user