fix retained glyph bottom clipping

This commit is contained in:
gamer147
2026-07-30 20:29:39 -04:00
parent d9f24c69ef
commit 49722c55fe
9 changed files with 185 additions and 13 deletions

View File

@@ -14,6 +14,7 @@ public readonly record struct GlyphTextLayoutOptions(
public sealed record GlyphTextLayoutResult(
IReadOnlyList<AdvRetainedGlyphRecord> Records,
IReadOnlyList<AdvRetainedGlyphPresentationRect> PresentationRects,
int CursorX,
int CursorY,
int ConsumedGlyphs,
@@ -40,6 +41,8 @@ public sealed class RetainedGlyphLayoutEngine
ArgumentNullException.ThrowIfNull(destination);
ArgumentNullException.ThrowIfNull(glyphs);
var records = new List<AdvRetainedGlyphRecord>(glyphs.Count);
var presentationRects =
new List<AdvRetainedGlyphPresentationRect>(glyphs.Count);
int cursorX = options.CursorX;
int cursorY = options.CursorY;
int wrappedLines = 0;
@@ -81,11 +84,59 @@ public sealed class RetainedGlyphLayoutEngine
AgeGlyphMaskCompositor.DrawGlyph(
destination, mask, cursorX, cursorY, request.PixelHeight, options.Style);
records.Add(new AdvRetainedGlyphRecord(0, cursorX, cursorY, right, bottom));
presentationRects.Add(PresentationRect(
destination.Height,
mask,
cursorX,
cursorY,
right,
bottom,
request.PixelHeight,
options.Style));
cursorX = checked(cursorX + mask.CellAdvanceX);
cursorY = checked(cursorY + mask.CellAdvanceY);
}
return new GlyphTextLayoutResult(
records, cursorX, cursorY, records.Count, wrappedLines, observed, stopped);
records, presentationRects, cursorX, cursorY, records.Count,
wrappedLines, observed, stopped);
}
private static AdvRetainedGlyphPresentationRect PresentationRect(
int surfaceHeight,
GlyphMask mask,
int cellLeft,
int cellTop,
int cellRight,
int cellBottom,
int topToBaseline,
AdvTextStyle style)
{
int minimumEffectY = 0;
int maximumEffectY = 0;
if (style.RenderMode == 1)
{
minimumEffectY = Math.Min(0, style.EffectOffsetY);
maximumEffectY = Math.Max(0, style.EffectOffsetY);
}
else if (style.RenderMode == 3)
{
foreach ((int _, int y) in AgeGlyphMaskCompositor.GetMode3OutlineOffsets(
style.EffectOffsetX, style.EffectOffsetY))
{
minimumEffectY = Math.Min(minimumEffectY, y);
maximumEffectY = Math.Max(maximumEffectY, y);
}
}
int inkTop = checked(
cellTop + topToBaseline - mask.OriginY + minimumEffectY);
int inkBottom = checked(
cellTop + topToBaseline - mask.OriginY + mask.Height + maximumEffectY);
return new AdvRetainedGlyphPresentationRect(
cellLeft,
Math.Clamp(Math.Min(cellTop, inkTop), 0, surfaceHeight),
cellRight,
Math.Clamp(Math.Max(cellBottom, inkBottom), 0, surfaceHeight));
}
}