mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
wip
This commit is contained in:
parent
40f20687be
commit
28ff6d9f00
6 changed files with 163 additions and 36 deletions
|
|
@ -10,6 +10,7 @@ using Dalamud.Configuration.Internal;
|
|||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Support;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
using PInvoke;
|
||||
using Serilog;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Dalamud.Utility.Timing;
|
|||
using ImGuiNET;
|
||||
using Lumina.Data.Files;
|
||||
using Serilog;
|
||||
using static Dalamud.Interface.ImGuiHelpers;
|
||||
|
||||
namespace Dalamud.Interface.GameFonts
|
||||
{
|
||||
|
|
@ -134,15 +135,18 @@ namespace Dalamud.Interface.GameFonts
|
|||
unsafe
|
||||
{
|
||||
var font = fontPtr.NativePtr;
|
||||
for (int i = 0, i_ = font->IndexAdvanceX.Size; i < i_; ++i)
|
||||
((float*)font->IndexAdvanceX.Data)[i] /= fontScale;
|
||||
font->FallbackAdvanceX /= fontScale;
|
||||
for (int i = 0, i_ = font->IndexedHotData.Size; i < i_; ++i)
|
||||
{
|
||||
font->IndexedHotData.Ref<ImFontGlyphHotDataReal>(i).AdvanceX /= fontScale;
|
||||
font->IndexedHotData.Ref<ImFontGlyphHotDataReal>(i).OccupiedWidth /= fontScale;
|
||||
}
|
||||
|
||||
font->FontSize /= fontScale;
|
||||
font->Ascent /= fontScale;
|
||||
font->Descent /= fontScale;
|
||||
if (font->ConfigData != null)
|
||||
font->ConfigData->SizePixels /= fontScale;
|
||||
var glyphs = (ImGuiHelpers.ImFontGlyphReal*)font->Glyphs.Data;
|
||||
var glyphs = (ImFontGlyphReal*)font->Glyphs.Data;
|
||||
for (int i = 0, i_ = font->Glyphs.Size; i < i_; i++)
|
||||
{
|
||||
var glyph = &glyphs[i];
|
||||
|
|
@ -152,6 +156,11 @@ namespace Dalamud.Interface.GameFonts
|
|||
glyph->Y1 /= fontScale;
|
||||
glyph->AdvanceX /= fontScale;
|
||||
}
|
||||
|
||||
for (int i = 0, i_ = font->KerningPairs.Size; i < i_; i++)
|
||||
font->KerningPairs.Ref<ImFontKerningPair>(i).AdvanceXAdjustment /= fontScale;
|
||||
for (int i = 0, i_ = font->FrequentKerningPairs.Size; i < i_; i++)
|
||||
font->FrequentKerningPairs.Ref<float>(i) /= fontScale;
|
||||
}
|
||||
|
||||
if (rebuildLookupTable)
|
||||
|
|
@ -253,8 +262,11 @@ namespace Dalamud.Interface.GameFonts
|
|||
this.glyphRectIds.Clear();
|
||||
this.fonts.Clear();
|
||||
|
||||
foreach (var style in this.fontUseCounter.Keys)
|
||||
this.EnsureFont(style);
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
foreach (var style in this.fontUseCounter.Keys)
|
||||
this.EnsureFont(style);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -279,10 +291,18 @@ namespace Dalamud.Interface.GameFonts
|
|||
{
|
||||
var interfaceManager = Service<InterfaceManager>.Get();
|
||||
var ioFonts = ImGui.GetIO().Fonts;
|
||||
ioFonts.GetTexDataAsRGBA32(0, out byte* pixels8, out var width, out var height);
|
||||
var pixels32 = (uint*)pixels8;
|
||||
var fontGamma = interfaceManager.FontGamma;
|
||||
|
||||
var pixels8s = new byte*[ioFonts.Textures.Size];
|
||||
var pixels32s = new uint*[ioFonts.Textures.Size];
|
||||
var widths = new int[ioFonts.Textures.Size];
|
||||
var heights = new int[ioFonts.Textures.Size];
|
||||
for (var i = 0; i < pixels8s.Length; i++)
|
||||
{
|
||||
ioFonts.GetTexDataAsRGBA32(i, out pixels8s[i], out widths[i], out heights[i]);
|
||||
pixels32s[i] = (uint*)pixels8s[i];
|
||||
}
|
||||
|
||||
foreach (var (style, font) in this.fonts)
|
||||
{
|
||||
var fdt = this.fdts[(int)(this.isBuildingAsFallbackFontMode ? style.FamilyWithMinimumSize : style.FamilyAndSize)];
|
||||
|
|
@ -302,7 +322,10 @@ namespace Dalamud.Interface.GameFonts
|
|||
var glyph = font.FindGlyphNoFallback(fallbackCharCandidate);
|
||||
if ((IntPtr)glyph.NativePtr != IntPtr.Zero)
|
||||
{
|
||||
font.SetFallbackChar(fallbackCharCandidate);
|
||||
var ptr = font.NativePtr;
|
||||
ptr->FallbackChar = fallbackCharCandidate;
|
||||
ptr->FallbackGlyph = glyph.NativePtr;
|
||||
ptr->FallbackHotData = (ImFontGlyphHotData*)ptr->IndexedHotData.Address<ImFontGlyphHotDataReal>(fallbackCharCandidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -323,7 +346,11 @@ namespace Dalamud.Interface.GameFonts
|
|||
|
||||
foreach (var (c, (rectId, glyph)) in this.glyphRectIds[style])
|
||||
{
|
||||
var rc = ioFonts.GetCustomRectByIndex(rectId);
|
||||
var rc = (ImFontAtlasCustomRectReal*)ioFonts.GetCustomRectByIndex(rectId).NativePtr;
|
||||
var pixels8 = pixels8s[rc->TextureIndex];
|
||||
var pixels32 = pixels32s[rc->TextureIndex];
|
||||
var width = widths[rc->TextureIndex];
|
||||
var height = heights[rc->TextureIndex];
|
||||
var sourceBuffer = this.texturePixels[glyph.TextureFileIndex];
|
||||
var sourceBufferDelta = glyph.TextureChannelByteIndex;
|
||||
var widthAdjustment = style.CalculateBaseWidthAdjustment(fdt, glyph);
|
||||
|
|
@ -334,7 +361,7 @@ namespace Dalamud.Interface.GameFonts
|
|||
for (var x = 0; x < glyph.BoundingWidth; x++)
|
||||
{
|
||||
var a = sourceBuffer[sourceBufferDelta + (4 * (((glyph.TextureOffsetY + y) * fdt.FontHeader.TextureWidth) + glyph.TextureOffsetX + x))];
|
||||
pixels32[((rc.Y + y) * width) + rc.X + x] = (uint)(a << 24) | 0xFFFFFFu;
|
||||
pixels32[((rc->Y + y) * width) + rc->X + x] = (uint)(a << 24) | 0xFFFFFFu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -343,7 +370,7 @@ namespace Dalamud.Interface.GameFonts
|
|||
for (var y = 0; y < glyph.BoundingHeight; y++)
|
||||
{
|
||||
for (var x = 0; x < glyph.BoundingWidth + widthAdjustment; x++)
|
||||
pixels32[((rc.Y + y) * width) + rc.X + x] = 0xFFFFFFu;
|
||||
pixels32[((rc->Y + y) * width) + rc->X + x] = 0xFFFFFFu;
|
||||
}
|
||||
|
||||
for (int xbold = 0, xbold_ = Math.Max(1, (int)Math.Ceiling(style.Weight + 1)); xbold < xbold_; xbold++)
|
||||
|
|
@ -364,7 +391,7 @@ namespace Dalamud.Interface.GameFonts
|
|||
var a1 = sourceBuffer[sourceBufferDelta + (4 * sourcePixelIndex)];
|
||||
var a2 = x == glyph.BoundingWidth - 1 ? 0 : sourceBuffer[sourceBufferDelta + (4 * (sourcePixelIndex + 1))];
|
||||
var n = (a1 * xness) + (a2 * (1 - xness));
|
||||
var targetOffset = ((rc.Y + y) * width) + rc.X + x + xDeltaInt;
|
||||
var targetOffset = ((rc->Y + y) * width) + rc->X + x + xDeltaInt;
|
||||
pixels8[(targetOffset * 4) + 3] = Math.Max(pixels8[(targetOffset * 4) + 3], (byte)(boldStrength * n));
|
||||
}
|
||||
}
|
||||
|
|
@ -374,9 +401,9 @@ namespace Dalamud.Interface.GameFonts
|
|||
if (Math.Abs(fontGamma - 1.4f) >= 0.001)
|
||||
{
|
||||
// Gamma correction (stbtt/FreeType would output in linear space whereas most real world usages will apply 1.4 or 1.8 gamma; Windows/XIV prebaked uses 1.4)
|
||||
for (int y = rc.Y, y_ = rc.Y + rc.Height; y < y_; y++)
|
||||
for (int y = rc->Y, y_ = rc->Y + rc->Height; y < y_; y++)
|
||||
{
|
||||
for (int x = rc.X, x_ = rc.X + rc.Width; x < x_; x++)
|
||||
for (int x = rc->X, x_ = rc->X + rc->Width; x < x_; x++)
|
||||
{
|
||||
var i = (((y * width) + x) * 4) + 3;
|
||||
pixels8[i] = (byte)(Math.Pow(pixels8[i] / 255.0f, 1.4f / fontGamma) * 255.0f);
|
||||
|
|
@ -435,12 +462,15 @@ namespace Dalamud.Interface.GameFonts
|
|||
io.Fonts.AddCustomRectFontGlyph(
|
||||
font,
|
||||
c,
|
||||
glyph.BoundingWidth + widthAdjustment + 1,
|
||||
glyph.BoundingHeight + 1,
|
||||
glyph.BoundingWidth + widthAdjustment,
|
||||
glyph.BoundingHeight,
|
||||
glyph.AdvanceWidth,
|
||||
new Vector2(0, glyph.CurrentOffsetY)),
|
||||
glyph);
|
||||
}
|
||||
|
||||
foreach (var kernPair in fdt.Distances)
|
||||
font.AddKerningPair(kernPair.Left, kernPair.Right, kernPair.RightOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ namespace Dalamud.Interface
|
|||
return;
|
||||
|
||||
var scale = target.Value!.FontSize / source.Value!.FontSize;
|
||||
var addedCodepoints = new HashSet<int>();
|
||||
unsafe
|
||||
{
|
||||
var glyphs = (ImFontGlyphReal*)source.Value!.Glyphs.Data;
|
||||
|
|
@ -168,10 +169,11 @@ namespace Dalamud.Interface
|
|||
var prevGlyphPtr = (ImFontGlyphReal*)target.Value!.FindGlyphNoFallback((ushort)glyph->Codepoint).NativePtr;
|
||||
if ((IntPtr)prevGlyphPtr == IntPtr.Zero)
|
||||
{
|
||||
addedCodepoints.Add(glyph->Codepoint);
|
||||
target.Value!.AddGlyph(
|
||||
target.Value!.ConfigData,
|
||||
(ushort)glyph->Codepoint,
|
||||
0,
|
||||
glyph->TextureIndex,
|
||||
glyph->X0 * scale,
|
||||
((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent,
|
||||
glyph->X1 * scale,
|
||||
|
|
@ -184,6 +186,7 @@ namespace Dalamud.Interface
|
|||
}
|
||||
else if (!missingOnly)
|
||||
{
|
||||
addedCodepoints.Add(glyph->Codepoint);
|
||||
prevGlyphPtr->X0 = glyph->X0 * scale;
|
||||
prevGlyphPtr->Y0 = ((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent;
|
||||
prevGlyphPtr->X1 = glyph->X1 * scale;
|
||||
|
|
@ -195,6 +198,16 @@ namespace Dalamud.Interface
|
|||
prevGlyphPtr->AdvanceX = glyph->AdvanceX * scale;
|
||||
}
|
||||
}
|
||||
|
||||
var kernPairs = source.Value!.KerningPairs;
|
||||
for (int j = 0, k = kernPairs.Size; j < k; j++)
|
||||
{
|
||||
if (!addedCodepoints.Contains(kernPairs[j].Left))
|
||||
continue;
|
||||
if (!addedCodepoints.Contains(kernPairs[j].Right))
|
||||
continue;
|
||||
target.Value.AddKerningPair(kernPairs[j].Left, kernPairs[j].Right, kernPairs[j].AdvanceXAdjustment);
|
||||
}
|
||||
}
|
||||
|
||||
if (rebuildLookupTable)
|
||||
|
|
@ -215,7 +228,7 @@ namespace Dalamud.Interface
|
|||
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "ImGui internals")]
|
||||
public struct ImFontGlyphReal
|
||||
{
|
||||
public uint ColoredVisibleCodepoint;
|
||||
public uint ColoredVisibleTextureIndexCodepoint;
|
||||
public float AdvanceX;
|
||||
public float X0;
|
||||
public float Y0;
|
||||
|
|
@ -226,23 +239,110 @@ namespace Dalamud.Interface
|
|||
public float U1;
|
||||
public float V1;
|
||||
|
||||
private const uint ColoredMask /*****/ = 0b_00000000_00000000_00000000_00000001u;
|
||||
private const uint VisibleMask /*****/ = 0b_00000000_00000000_00000000_00000010u;
|
||||
private const uint TextureMask /*****/ = 0b_00000000_00000000_00000111_11111100u;
|
||||
private const uint CodepointMask /***/ = 0b_11111111_11111111_11111000_00000000u;
|
||||
|
||||
private const int ColoredShift = 0;
|
||||
private const int VisibleShift = 1;
|
||||
private const int TextureShift = 2;
|
||||
private const int CodepointShift = 11;
|
||||
|
||||
public bool Colored
|
||||
{
|
||||
get => ((this.ColoredVisibleCodepoint >> 0) & 1) != 0;
|
||||
set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFEu) | (value ? 1u : 0u);
|
||||
get => (int)((this.ColoredVisibleTextureIndexCodepoint & ColoredMask) >> ColoredShift) != 0;
|
||||
set => this.ColoredVisibleTextureIndexCodepoint = (this.ColoredVisibleTextureIndexCodepoint & ~ColoredMask) | (value ? 1u << ColoredShift : 0u);
|
||||
}
|
||||
|
||||
public bool Visible
|
||||
{
|
||||
get => ((this.ColoredVisibleCodepoint >> 1) & 1) != 0;
|
||||
set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFDu) | (value ? 2u : 0u);
|
||||
get => (int)((this.ColoredVisibleTextureIndexCodepoint & VisibleMask) >> VisibleShift) != 0;
|
||||
set => this.ColoredVisibleTextureIndexCodepoint = (this.ColoredVisibleTextureIndexCodepoint & ~VisibleMask) | (value ? 1u << VisibleShift : 0u);
|
||||
}
|
||||
|
||||
public int TextureIndex
|
||||
{
|
||||
get => (int)(this.ColoredVisibleTextureIndexCodepoint & TextureMask) >> TextureShift;
|
||||
set => this.ColoredVisibleTextureIndexCodepoint = (this.ColoredVisibleTextureIndexCodepoint & ~TextureMask) | ((uint)value << TextureShift);
|
||||
}
|
||||
|
||||
public int Codepoint
|
||||
{
|
||||
get => (int)(this.ColoredVisibleCodepoint >> 2);
|
||||
set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 3u) | ((uint)value << 2);
|
||||
get => (int)(this.ColoredVisibleTextureIndexCodepoint & CodepointMask) >> CodepointShift;
|
||||
set => this.ColoredVisibleTextureIndexCodepoint = (this.ColoredVisibleTextureIndexCodepoint & ~CodepointMask) | ((uint)value << CodepointShift);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ImFontGlyphHotData the correct version.
|
||||
/// </summary>
|
||||
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "ImGui internals")]
|
||||
public struct ImFontGlyphHotDataReal
|
||||
{
|
||||
public float AdvanceX;
|
||||
public float OccupiedWidth;
|
||||
public uint KerningPairInfo;
|
||||
|
||||
private const uint UseBisectMask /***/ = 0b_00000000_00000000_00000000_00000001u;
|
||||
private const uint OffsetMask /******/ = 0b_00000000_00001111_11111111_11111110u;
|
||||
private const uint CountMask /*******/ = 0b_11111111_11110000_00000111_11111100u;
|
||||
|
||||
private const int UseBisectShift = 0;
|
||||
private const int OffsetShift = 1;
|
||||
private const int CountShift = 20;
|
||||
|
||||
public bool UseBisect
|
||||
{
|
||||
get => (int)((this.KerningPairInfo & UseBisectMask) >> UseBisectShift) != 0;
|
||||
set => this.KerningPairInfo = (this.KerningPairInfo & ~UseBisectMask) | (value ? 1u << UseBisectShift : 0u);
|
||||
}
|
||||
|
||||
public bool Offset
|
||||
{
|
||||
get => (int)((this.KerningPairInfo & OffsetMask) >> OffsetShift) != 0;
|
||||
set => this.KerningPairInfo = (this.KerningPairInfo & ~OffsetMask) | (value ? 1u << OffsetShift : 0u);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get => (int)(this.KerningPairInfo & CountMask) >> CountShift;
|
||||
set => this.KerningPairInfo = (this.KerningPairInfo & ~CountMask) | ((uint)value << CountShift);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ImFontAtlasCustomRect the correct version.
|
||||
/// </summary>
|
||||
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "ImGui internals")]
|
||||
public unsafe struct ImFontAtlasCustomRectReal
|
||||
{
|
||||
public ushort Width;
|
||||
public ushort Height;
|
||||
public ushort X;
|
||||
public ushort Y;
|
||||
public uint TextureIndexAndGlyphID;
|
||||
public float GlyphAdvanceX;
|
||||
public Vector2 GlyphOffset;
|
||||
public ImFont* Font;
|
||||
|
||||
private const uint TextureIndexMask /***/ = 0b_00000000_00000000_00000111_11111100u;
|
||||
private const uint GlyphIDMask /********/ = 0b_11111111_11111111_11111000_00000000u;
|
||||
|
||||
private const int TextureIndexShift = 2;
|
||||
private const int GlyphIDShift = 11;
|
||||
|
||||
public int TextureIndex
|
||||
{
|
||||
get => (int)(this.TextureIndexAndGlyphID & TextureIndexMask) >> TextureIndexShift;
|
||||
set => this.TextureIndexAndGlyphID = (this.TextureIndexAndGlyphID & ~TextureIndexMask) | ((uint)value << TextureIndexShift);
|
||||
}
|
||||
|
||||
public int GlyphID
|
||||
{
|
||||
get => (int)(this.TextureIndexAndGlyphID & GlyphIDMask) >> GlyphIDShift;
|
||||
set => this.TextureIndexAndGlyphID = (this.TextureIndexAndGlyphID & ~GlyphIDMask) | ((uint)value << GlyphIDShift);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -848,6 +848,12 @@ namespace Dalamud.Interface.Internal
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0, i_ = ioFonts.ConfigData.Size; i < i_; i++)
|
||||
{
|
||||
var config = ioFonts.ConfigData[i];
|
||||
config.RasterizerGamma = config.RasterizerGamma * fontGamma;
|
||||
}
|
||||
|
||||
Log.Verbose("[FONT] ImGui.IO.Build will be called.");
|
||||
ioFonts.Build();
|
||||
gameFontManager.AfterIoFontsBuild();
|
||||
|
|
@ -881,14 +887,6 @@ namespace Dalamud.Interface.Internal
|
|||
if (!disableBigFonts)
|
||||
this.IsFallbackFontMode = false;
|
||||
|
||||
if (Math.Abs(fontGamma - 1.0f) >= 0.001)
|
||||
{
|
||||
// Gamma correction (stbtt/FreeType would output in linear space whereas most real world usages will apply 1.4 or 1.8 gamma; Windows/XIV prebaked uses 1.4)
|
||||
ioFonts.GetTexDataAsRGBA32(0, out byte* texPixels, out var texWidth, out var texHeight);
|
||||
for (int i = 3, i_ = texWidth * texHeight * 4; i < i_; i += 4)
|
||||
texPixels[i] = (byte)(Math.Pow(texPixels[i] / 255.0f, 1.0f / fontGamma) * 255.0f);
|
||||
}
|
||||
|
||||
gameFontManager.AfterBuildFonts();
|
||||
|
||||
foreach (var (font, mod) in this.loadedFontInfo)
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
}
|
||||
|
||||
if (!ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows |
|
||||
ImGuiHoveredFlags.AllowWhenOverlapped |
|
||||
ImGuiHoveredFlags.AllowWhenBlockedByActiveItem))
|
||||
{
|
||||
this.state = State.FadeOut;
|
||||
|
|
@ -188,7 +187,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
ImGui.PopStyleVar();
|
||||
|
||||
var isHover = ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows |
|
||||
ImGuiHoveredFlags.AllowWhenOverlapped |
|
||||
ImGuiHoveredFlags.AllowWhenBlockedByActiveItem);
|
||||
|
||||
if (!isHover && this.fadeOutEasing!.IsDone)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 4a58aef6683b12685ed064df286a6aa77fd04521
|
||||
Subproject commit cd6300cd7944b24643ed7381fbe5ae15efc10448
|
||||
Loading…
Add table
Add a link
Reference in a new issue