[NUI] Add RenderScale to TextLabel
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 27 Mar 2025 07:37:34 +0000 (16:37 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 14 May 2025 06:35:12 +0000 (15:35 +0900)
Added RenderScale to prevent text rendering quality degradation when scaling up with View.Scale.

Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
src/Tizen.NUI/src/internal/Interop/Interop.TextLabel.cs
src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs

index d33d861481d89053c67c24d315bc858c35c252b3..edac835088a81ae2c9d0ce15f3dab8a0f05591db 100755 (executable)
@@ -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);
 
index ce930ad95a010405ab06e5997ed093cff84f1741..bcec3c012fd92ac9f3ea636d0511841b2c490978 100755 (executable)
@@ -2278,6 +2278,113 @@ namespace Tizen.NUI.BaseComponents
             get => Object.InternalGetPropertyBool(SwigCPtr, Property.IsScrolling);
         }
 
+        /// <summary>
+        /// Renders a texture at a specified scale to prevent text rendering quality degradation when scaling up with View.Scale.
+        /// </summary>
+        /// <remarks>
+        /// RenderScale is only available in TextRenderMode.AsyncAuto and TextRenderMode.AsyncManual.<br />
+        /// It is only valid when set to 1.0 or greater.<br />
+        /// This property scales up the point size and texture size to the specified scale.<br />
+        /// For example, the results of the rendered textures below are nearly identical:<br />
+        /// FontSize: 20, RenderScale: 1.5<br />
+        /// FontSize: 20, FontSizeScale: 1.5<br />
+        /// However, the texture rendered with the specified RenderScale is downscaled to the original(1.0 scale) size and applied to the visual transform.<br />
+        /// When the texture is increased by View.Scale, its size becomes 100%, ensuring high-quality rendering.<br />
+        /// To achieve optimal text rendering results when using View.Scale, RenderScale should be set to the same value.
+        /// </remarks>
+        /// <example>
+        /// The following example demonstrates how to use the RenderScale.
+        /// <code>
+        /// 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();
+        /// };
+        /// </code>
+        /// </example>
+        [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();
+            }
+        }
+
+        /// <summary>
+        /// A factor of pixel snap.
+        /// </summary>
+        /// <remarks>
+        /// It should be 0.0 ~ 1.0.<br />
+        /// Controls the degree of pixel snapping applied to the visual position.<br />
+        /// A value of 0.0 means no snapping is applied (original position is preserved), while 1.0 applies full pixel alignment.<br />
+        /// Intermediate values blend smoothly between the original and snapped positions using linear interpolation (mix) in the vertex shader.<br />
+        /// Typical usage:<br />
+        /// To ensure both smooth animations and sharp visual alignment,<br />
+        /// transition the pixelSnapFactor value gradually from 0.0 to 1.0 during or after animations.<br />
+        /// This allows the snapping to engage seamlessly without visible jitter or popping, maintaining both visual quality and motion fluidity.<br />
+        /// Use 0.0 during animation to avoid snapping artifacts.<br />
+        /// Gradually increase to 1.0 as the animation settles, for crisp pixel alignment.
+        /// </remarks>
+        /// <example>
+        /// The following example demonstrates how to use the PixelSnapFactor with RenderScale.
+        /// <code>
+        /// 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();
+        /// };
+        /// </code>
+        /// </example>
+        [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();
+            }
+        }
+
         /// <summary>
         /// The AutoScrollLoopDelay property.<br />
         /// The amount of time to delay the starting time of auto scrolling and further loops.<br />
@@ -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()