From bd50c59b0e0790a9f191974deee99761d076b17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 14 Jul 2025 16:14:29 +0200 Subject: [PATCH 1/2] Avoid recursive filter application --- src/Svg.Model/Drawables/DrawableBase.cs | 9 +++++++- .../Drawables/Elements/TextDrawable.cs | 23 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Svg.Model/Drawables/DrawableBase.cs b/src/Svg.Model/Drawables/DrawableBase.cs index d7dca42016..d7d594757b 100644 --- a/src/Svg.Model/Drawables/DrawableBase.cs +++ b/src/Svg.Model/Drawables/DrawableBase.cs @@ -418,6 +418,11 @@ public virtual void DebugDrawBounds(SKCanvas canvas) | DrawAttributes.Opacity | DrawAttributes.Filter; + // When a filter references 'SourceGraphic', we must draw the element + // without applying its filter again to avoid infinite recursion. + private const DrawAttributes FilterSourceInput = + DrawAttributes.Filter; + protected virtual void PostProcessChildren(SKRect? clip, SKMatrix totalMatrix) { } @@ -425,7 +430,9 @@ protected virtual void PostProcessChildren(SKRect? clip, SKMatrix totalMatrix) SKPicture? IFilterSource.SourceGraphic(SKRect? clip) { PostProcessChildren(clip, SKMatrix.Identity); - return RecordGraphic(this, clip, DrawAttributes.None); + // Ignore the element's filter when rendering the source graphic so + // that filter primitives do not recursively re-enter filtering. + return RecordGraphic(this, clip, FilterSourceInput); } SKPicture? IFilterSource.BackgroundImage(SKRect? clip) => RecordBackground(this, clip, FilterBackgroundInput); diff --git a/src/Svg.Model/Drawables/Elements/TextDrawable.cs b/src/Svg.Model/Drawables/Elements/TextDrawable.cs index c98ecf7b02..e1384d0d30 100644 --- a/src/Svg.Model/Drawables/Elements/TextDrawable.cs +++ b/src/Svg.Model/Drawables/Elements/TextDrawable.cs @@ -70,8 +70,17 @@ private void Initialize() var paint = new SKPaint(); PaintingService.SetPaintText(Text, OwnerBounds, paint); - // Measure text metrics using asset loader - var fontMetrics = AssetLoader.GetFontMetrics(paint); + // Measure text metrics using asset loader with a fallback to Skia APIs + var fontMetrics = default(SKFontMetrics); + try + { + fontMetrics = AssetLoader.GetFontMetrics(paint); + } + catch (NotSupportedException) + { + paint.GetFontMetrics(out var skMetrics); + fontMetrics = skMetrics; + } var metricsAscent = fontMetrics.Ascent; var metricsDescent = fontMetrics.Descent; @@ -84,7 +93,15 @@ private void Initialize() y += dy; var bounds = new SKRect(); - var width = AssetLoader.MeasureText(text, paint, ref bounds); + var width = 0f; + try + { + width = AssetLoader.MeasureText(text, paint, ref bounds); + } + catch (NotSupportedException) + { + width = paint.MeasureText(text, ref bounds); + } GeometryBounds = new SKRect(x, y + metricsAscent, x + width, y + metricsDescent); Transform = TransformsService.ToMatrix(Text.Transforms); From 55d4afbbd99e095acce6cf10a3278c429d5081ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 14 Jul 2025 16:20:11 +0200 Subject: [PATCH 2/2] Remove unnecessary metrics fallback --- .../Drawables/Elements/TextDrawable.cs | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/Svg.Model/Drawables/Elements/TextDrawable.cs b/src/Svg.Model/Drawables/Elements/TextDrawable.cs index e1384d0d30..c98ecf7b02 100644 --- a/src/Svg.Model/Drawables/Elements/TextDrawable.cs +++ b/src/Svg.Model/Drawables/Elements/TextDrawable.cs @@ -70,17 +70,8 @@ private void Initialize() var paint = new SKPaint(); PaintingService.SetPaintText(Text, OwnerBounds, paint); - // Measure text metrics using asset loader with a fallback to Skia APIs - var fontMetrics = default(SKFontMetrics); - try - { - fontMetrics = AssetLoader.GetFontMetrics(paint); - } - catch (NotSupportedException) - { - paint.GetFontMetrics(out var skMetrics); - fontMetrics = skMetrics; - } + // Measure text metrics using asset loader + var fontMetrics = AssetLoader.GetFontMetrics(paint); var metricsAscent = fontMetrics.Ascent; var metricsDescent = fontMetrics.Descent; @@ -93,15 +84,7 @@ private void Initialize() y += dy; var bounds = new SKRect(); - var width = 0f; - try - { - width = AssetLoader.MeasureText(text, paint, ref bounds); - } - catch (NotSupportedException) - { - width = paint.MeasureText(text, ref bounds); - } + var width = AssetLoader.MeasureText(text, paint, ref bounds); GeometryBounds = new SKRect(x, y + metricsAscent, x + width, y + metricsDescent); Transform = TransformsService.ToMatrix(Text.Transforms);