Canon/Canon.Visualization/Services/SyntaxTreePresentationService.cs
Ichirinko dbbab1c761 feat-visualization (#33)
尽管里面有点粪,但还是生成了漂亮的树,就当给树施肥了
剩下一个小问题:未考虑节点的宽度(因为名称不一样长),但目前未发现对图生成的明显影响

Co-authored-by: jackfiled <xcrenchangjun@outlook.com>
Reviewed-on: PostGuard/Canon#33
Co-authored-by: Ichirinko <1621543655@qq.com>
Co-committed-by: Ichirinko <1621543655@qq.com>
2024-04-19 14:59:45 +08:00

55 lines
1.4 KiB
C#

using Canon.Core.SyntaxNodes;
using Canon.Visualization.Models;
using SkiaSharp;
namespace Canon.Visualization.Services;
public class SyntaxTreePresentationService
{
private const float Scale = 150;
public Stream Present(ProgramStruct root)
{
PresentableTreeNode presentableTreeRoot = PresentableTreeNode.Build(root);
ScaleTree(presentableTreeRoot);
(float height, float width) = presentableTreeRoot.CalculateImageSize();
using SKSurface surface = SKSurface.Create(
new SKImageInfo((int)(width + 2 * Scale), (int)(height * Scale)));
surface.Canvas.Clear(SKColors.White);
using Brush brush = new(surface.Canvas);
DrawNode(presentableTreeRoot, brush);
using SKImage image = surface.Snapshot();
SKData data = image.Encode();
return data.AsStream();
}
private void DrawNode(PresentableTreeNode node, Brush brush)
{
foreach (PresentableTreeNode child in node.Children)
{
brush.DrawLine(node.Position, child.Position);
DrawNode(child, brush);
}
brush.DrawText(node.Position, node.DisplayText);
}
private void ScaleTree(PresentableTreeNode node)
{
node.X *= Scale;
node.X += Scale;
node.Y *= Scale;
node.Y += Scale;
foreach (PresentableTreeNode child in node.Children)
{
ScaleTree(child);
}
}
}