Skip to content

Commit ca989f6

Browse files
committed
feat(playground): add layout diagnostics and update text_styled snapshot
Add contentW, intrinsicW, shapedW, resolvedTypeface diagnostic fields to LayoutNode and playground layout JSON for text rendering debugging. Update text_styled snapshot for LinearMetrics change.
1 parent 22af127 commit ca989f6

5 files changed

Lines changed: 53 additions & 1 deletion

File tree

src/FlexRender.Core/Layout/LayoutEngine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ private LayoutNode LayoutTextElement(TextElement text, LayoutContext context)
481481
var border = BorderParser.Resolve(text, context.ContainerWidth, context.FontSize);
482482

483483
float contentWidth;
484+
var diagIntrinsicW = 0f;
485+
var diagShapedW = 0f;
484486
if (!string.IsNullOrEmpty(text.Width.Value))
485487
{
486488
contentWidth = context.ResolveWidth(text.Width.Value) ?? context.ContainerWidth;
@@ -490,6 +492,7 @@ private LayoutNode LayoutTextElement(TextElement text, LayoutContext context)
490492
&& intrinsic.MaxWidth > 0)
491493
{
492494
contentWidth = intrinsic.MaxWidth;
495+
diagIntrinsicW = intrinsic.MaxWidth;
493496
}
494497
else
495498
{
@@ -518,6 +521,7 @@ private LayoutNode LayoutTextElement(TextElement text, LayoutContext context)
518521
? Math.Min(contentWidth, context.ContainerWidth)
519522
: float.MaxValue;
520523
var shaped = TextShaper.ShapeText(text, fontSize, measureWidth);
524+
diagShapedW = shaped.TotalSize.Width;
521525
textLines = shaped.Lines;
522526
computedLineHeight = shaped.LineHeight;
523527
textBaseline = shaped.Baseline;
@@ -534,6 +538,7 @@ private LayoutNode LayoutTextElement(TextElement text, LayoutContext context)
534538
? Math.Min(contentWidth, context.ContainerWidth)
535539
: float.MaxValue;
536540
var shaped = TextShaper.ShapeText(text, fontSize, measureWidth);
541+
diagShapedW = shaped.TotalSize.Width;
537542
contentHeight = shaped.TotalSize.Height;
538543
textLines = shaped.Lines;
539544
computedLineHeight = shaped.LineHeight;
@@ -582,6 +587,9 @@ private LayoutNode LayoutTextElement(TextElement text, LayoutContext context)
582587
node.ComputedLineHeight = computedLineHeight;
583588
node.Baseline = padding.Top + border.Top.Width + textBaseline;
584589
node.ComputedFontSize = resolvedFontSize;
590+
node.DiagContentWidth = contentWidth;
591+
node.DiagIntrinsicWidth = diagIntrinsicW;
592+
node.DiagShapedWidth = diagShapedW;
585593
return node;
586594
}
587595

src/FlexRender.Core/Layout/LayoutNode.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ public sealed class LayoutNode
6161
/// </summary>
6262
public float ComputedFontSize { get; set; }
6363

64+
/// <summary>
65+
/// Diagnostic: intrinsic width from IntrinsicMeasurer (before scaling).
66+
/// Only populated for text elements during layout when diagnostics are enabled.
67+
/// </summary>
68+
public float DiagIntrinsicWidth { get; set; }
69+
70+
/// <summary>
71+
/// Diagnostic: shaped width from TextShaper at final font size.
72+
/// Only populated for text elements during layout when diagnostics are enabled.
73+
/// </summary>
74+
public float DiagShapedWidth { get; set; }
75+
76+
/// <summary>
77+
/// Diagnostic: final content width used in layout calculation.
78+
/// </summary>
79+
public float DiagContentWidth { get; set; }
80+
81+
/// <summary>
82+
/// Diagnostic: resolved typeface family name from FontManager.
83+
/// </summary>
84+
public string? DiagResolvedTypeface { get; set; }
85+
6486
/// <summary>Right edge (X + Width).</summary>
6587
public float Right => X + Width;
6688

src/FlexRender.Playground/PlaygroundApi.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,16 @@ private static JsonObject SerializeLayoutNode(LayoutNode node)
378378
if (node.Direction != TextDirection.Ltr)
379379
obj["direction"] = node.Direction.ToString().ToLowerInvariant();
380380

381+
// Diagnostic fields for text debugging
382+
if (node.DiagContentWidth > 0)
383+
obj["contentW"] = Math.Round(node.DiagContentWidth, 2);
384+
if (node.DiagIntrinsicWidth > 0)
385+
obj["intrinsicW"] = Math.Round(node.DiagIntrinsicWidth, 2);
386+
if (node.DiagShapedWidth > 0)
387+
obj["shapedW"] = Math.Round(node.DiagShapedWidth, 2);
388+
if (!string.IsNullOrEmpty(node.DiagResolvedTypeface))
389+
obj["resolvedTypeface"] = node.DiagResolvedTypeface;
390+
381391
// Element-specific properties
382392
SerializeElementProperties(obj, node.Element);
383393

@@ -425,6 +435,14 @@ private static void SerializeElementProperties(JsonObject obj, TemplateElement e
425435
if (!string.IsNullOrEmpty(t.Color.Value))
426436
obj["color"] = t.Color.Value;
427437

438+
// Resolve typeface name for diagnostics
439+
if (_render is SkiaRender skiaRender)
440+
{
441+
var typeface = skiaRender.FontManager.GetTypeface(
442+
t.Font.Value, t.FontFamily.Value, t.FontWeight.Value, t.FontStyle.Value);
443+
obj["resolvedTypeface"] = typeface.FamilyName;
444+
}
445+
428446
break;
429447

430448
case ImageElement:

src/FlexRender.Playground/wwwroot/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ function buildLayoutTree(node, depth, parentAbsX, parentAbsY) {
569569
if (node.justify) props.push(`justify=${escHtml(node.justify)}`);
570570
if (node.fontSize) props.push(`fontSize=${escHtml(String(node.fontSize))}px`);
571571
if (node.textLines) props.push(`lines=${escHtml(String(node.textLines))}`);
572+
if (node.contentW) props.push(`contentW=${node.contentW}`);
573+
if (node.intrinsicW) props.push(`intrinsicW=${node.intrinsicW}`);
574+
if (node.shapedW) props.push(`shapedW=${node.shapedW}`);
575+
if (node.resolvedTypeface) props.push(`tf=${escHtml(node.resolvedTypeface)}`);
572576

573577
const propsStr = props.length > 0 ? ` <span class="node-props">[${props.join(', ')}]</span>` : '';
574578
const safeType = escHtml(node.type);
Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)