From aece990ed92c5e3b57baf8206cd02c536c8eaa0f Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Thu, 27 Mar 2025 16:37:34 +0900 Subject: [PATCH] [NUI] Add RenderScale to TextLabel Added RenderScale to prevent text rendering quality degradation when scaling up with View.Scale. Signed-off-by: Bowon Ryu --- .../src/internal/Interop/Interop.TextLabel.cs | 6 + .../src/public/BaseComponents/TextLabel.cs | 109 ++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs b/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs index d33d86148..edac83508 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs @@ -209,6 +209,12 @@ namespace Tizen.NUI [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_Property_ASYNC_LINE_COUNT_get")] public static extern int AsyncLineCountGet(); + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_Property_RENDER_SCALE_get")] + public static extern int RenderScaleGet(); + + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_Property_PIXEL_SNAP_FACTOR_get")] + public static extern int PixelSnapFactorGet(); + [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_TextLabel_RequestAsyncRenderWithFixedSize")] public static extern void RequestAsyncRenderWithFixedSize(HandleRef textLabelRef, float width, float height); diff --git a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs index ce930ad95..bcec3c012 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs @@ -2278,6 +2278,113 @@ namespace Tizen.NUI.BaseComponents get => Object.InternalGetPropertyBool(SwigCPtr, Property.IsScrolling); } + /// + /// Renders a texture at a specified scale to prevent text rendering quality degradation when scaling up with View.Scale. + /// + /// + /// RenderScale is only available in TextRenderMode.AsyncAuto and TextRenderMode.AsyncManual.
+ /// It is only valid when set to 1.0 or greater.
+ /// This property scales up the point size and texture size to the specified scale.
+ /// For example, the results of the rendered textures below are nearly identical:
+ /// FontSize: 20, RenderScale: 1.5
+ /// FontSize: 20, FontSizeScale: 1.5
+ /// However, the texture rendered with the specified RenderScale is downscaled to the original(1.0 scale) size and applied to the visual transform.
+ /// When the texture is increased by View.Scale, its size becomes 100%, ensuring high-quality rendering.
+ /// To achieve optimal text rendering results when using View.Scale, RenderScale should be set to the same value. + ///
+ /// + /// The following example demonstrates how to use the RenderScale. + /// + /// label.FocusGained += (s, e) => + /// { + /// float scaleUp = 1.5f; + /// label.RenderScale = scaleUp; + /// scaleAnimation = new Animation(200); + /// scaleAnimation.AnimateTo(label, "scale", new Vector3(scaleUp, scaleUp, 1.0f)); + /// scaleAnimation.Play(); + /// }; + /// label.FocusLost += (s, e) => + /// { + /// float normalScale = 1.0f; + /// label.RenderScale = normalScale; + /// scaleAnimation = new Animation(200); + /// scaleAnimation.AnimateTo(label, "scale", new Vector3(normalScale, normalScale, 1.0f)); + /// scaleAnimation.Play(); + /// }; + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float RenderScale + { + get + { + return (float)Object.InternalGetPropertyFloat(this.SwigCPtr, Property.RenderScale); + } + set + { + Object.InternalSetPropertyFloat(this.SwigCPtr, Property.RenderScale, (float)value); + NotifyPropertyChanged(); + } + } + + /// + /// A factor of pixel snap. + /// + /// + /// It should be 0.0 ~ 1.0.
+ /// Controls the degree of pixel snapping applied to the visual position.
+ /// A value of 0.0 means no snapping is applied (original position is preserved), while 1.0 applies full pixel alignment.
+ /// Intermediate values blend smoothly between the original and snapped positions using linear interpolation (mix) in the vertex shader.
+ /// Typical usage:
+ /// To ensure both smooth animations and sharp visual alignment,
+ /// transition the pixelSnapFactor value gradually from 0.0 to 1.0 during or after animations.
+ /// This allows the snapping to engage seamlessly without visible jitter or popping, maintaining both visual quality and motion fluidity.
+ /// Use 0.0 during animation to avoid snapping artifacts.
+ /// Gradually increase to 1.0 as the animation settles, for crisp pixel alignment. + ///
+ /// + /// The following example demonstrates how to use the PixelSnapFactor with RenderScale. + /// + /// label.FocusGained += (s, e) => + /// { + /// float scaleUp = 1.5f; + /// label.RenderScale = scaleUp; + /// scaleAnimation = new Animation(200); + /// scaleAnimation.AnimateTo(label, "scale", new Vector3(scaleUp, scaleUp, 1.0f)); + /// scaleAnimation.Play(); + /// + /// pixelSnapAnimation = new Animation(200); + /// pixelSnapAnimation.AnimateTo(label, "pixelSnapFactor", 1.0f); + /// pixelSnapAnimation.Play(); + /// }; + /// label.FocusLost += (s, e) => + /// { + /// float normalScale = 1.0f; + /// label.RenderScale = normalScale; + /// scaleAnimation = new Animation(200); + /// scaleAnimation.AnimateTo(label, "scale", new Vector3(normalScale, normalScale, 1.0f)); + /// scaleAnimation.Play(); + /// + /// pixelSnapAnimation = new Animation(200); + /// pixelSnapAnimation.AnimateTo(label, "pixelSnapFactor", 0.0f); + /// pixelSnapAnimation.Play(); + /// }; + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public float PixelSnapFactor + { + get + { + return (float)Object.InternalGetPropertyFloat(this.SwigCPtr, Property.PixelSnapFactor); + } + set + { + Object.InternalSetPropertyFloat(this.SwigCPtr, Property.PixelSnapFactor, (float)value); + NotifyPropertyChanged(); + } + } + /// /// The AutoScrollLoopDelay property.
/// The amount of time to delay the starting time of auto scrolling and further loops.
@@ -3532,6 +3639,8 @@ namespace Tizen.NUI.BaseComponents internal static readonly int AsyncLineCount = Interop.TextLabel.AsyncLineCountGet(); internal static readonly int EllipsisMode = Interop.TextLabel.EllipsisModeGet(); internal static readonly int IsScrolling = Interop.TextLabel.IsScrollingGet(); + internal static readonly int RenderScale = Interop.TextLabel.RenderScaleGet(); + internal static readonly int PixelSnapFactor = Interop.TextLabel.PixelSnapFactorGet(); internal static void Preload() -- 2.34.1