[Bf-blender-cvs] [4f7dc4c9187] blender-v2.83-release: Fix T89241: 3D Text "Scale to Fit" wraps onto the second line

Campbell Barton noreply at git.blender.org
Mon Aug 16 10:02:38 CEST 2021


Commit: 4f7dc4c91872b5d339e848066ee188a99df005f5
Author: Campbell Barton
Date:   Fri Aug 13 01:00:50 2021 +1000
Branches: blender-v2.83-release
https://developer.blender.org/rB4f7dc4c91872b5d339e848066ee188a99df005f5

Fix T89241: 3D Text "Scale to Fit" wraps onto the second line

Disable wrapping when "scale to fit" is used, assert the error is
small so an invalid scale-to-fit value wont go by unnoticed.

===================================================================

M	source/blender/blenkernel/intern/font.c

===================================================================

diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index b0bc5cf7e0f..1c619297064 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -680,6 +680,11 @@ typedef struct VFontToCurveIter {
     float max;
   } bisect;
   bool ok;
+  /**
+   * Disables checking if word wrapping is needed to fit the text-box width.
+   * Currently only used when scale-to-fit is enabled.
+   */
+  bool word_wrap;
   int status;
 } VFontToCurveIter;
 
@@ -740,6 +745,7 @@ static bool vfont_to_curve(Object *ob,
   char32_t ascii;
   bool ok = false;
   const float font_size = cu->fsize * iter_data->scale_to_fit;
+  const bool word_wrap = iter_data->word_wrap;
   const float xof_scale = cu->xof / font_size;
   const float yof_scale = cu->yof / font_size;
   int last_line = -1;
@@ -911,42 +917,64 @@ static bool vfont_to_curve(Object *ob,
     twidth = char_width(cu, che, info);
 
     /* Calculate positions */
-    if ((tb_scale.w != 0.0f) && (ct->dobreak == 0) &&
-        (((xof - tb_scale.x) + twidth) > xof_scale + tb_scale.w)) {
-      //      CLOG_WARN(&LOG, "linewidth exceeded: %c%c%c...", mem[i], mem[i+1], mem[i+2]);
-      for (j = i; j && (mem[j] != '\n') && (chartransdata[j].dobreak == 0); j--) {
-        bool dobreak = false;
-        if (mem[j] == ' ' || mem[j] == '-') {
-          ct -= (i - (j - 1));
-          cnr -= (i - (j - 1));
-          if (mem[j] == ' ') {
-            wsnr--;
+    if ((tb_scale.w != 0.0f) && (ct->dobreak == 0)) { /* May need wrapping. */
+      const float x_available = xof_scale + tb_scale.w;
+      const float x_used = (xof - tb_scale.x) + twidth;
+
+      if (word_wrap == false) {
+        /* When scale to fit is used, don't do any wrapping.
+         *
+         * Floating precision error can cause the text to be slightly larger.
+         * Assert this is a small value as large values indicate incorrect
+         * calculations with scale-to-fit which shouldn't be ignored. See T89241. */
+        if (x_used > x_available) {
+          // "VFontToCurveIter.scale_to_fit not set correctly!"
+          BLI_assert(compare_ff_relative(x_used, x_available, FLT_EPSILON, 64));
+        }
+      }
+      else if (x_used > x_available) {
+        // CLOG_WARN(&LOG, "linewidth exceeded: %c%c%c...", mem[i], mem[i+1], mem[i+2]);
+        for (j = i; j && (mem[j] != '\n') && (chartransdata[j].dobreak == 0); j--) {
+          bool dobreak = false;
+          if (mem[j] == ' ' || mem[j] == '-') {
+            ct -= (i - (j - 1));
+            cnr -= (i - (j - 1));
+            if (mem[j] == ' ') {
+              wsnr--;
+            }
+            else if (chartransdata[j].dobreak) {
+              // CLOG_WARN(&LOG, "word too long: %c%c%c...", mem[j], mem[j+1], mem[j+2]);
+              ct->dobreak = 1;
+              custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
+              ct -= 1;
+              cnr -= 1;
+              i--;
+              xof = ct->xof;
+              dobreak = true;
+            }
+            i = j - 1;
+            xof = ct->xof;
+            ct[1].dobreak = 1;
+            custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
+            dobreak = true;
           }
-          if (mem[j] == '-') {
-            wsnr++;
+          else if (chartransdata[j].dobreak) {
+            // CLOG_WARN(&LOG, "word too long: %c%c%c...", mem[j], mem[j+1], mem[j+2]);
+            ct->dobreak = 1;
+            custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
+            ct -= 1;
+            cnr -= 1;
+            i--;
+            xof = ct->xof;
+            dobreak = true;
           }
-          i = j - 1;
-          xof = ct->xof;
-          ct[1].dobreak = 1;
-          custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
-          dobreak = true;
-        }
-        else if (chartransdata[j].dobreak) {
-          //              CLOG_WARN(&LOG, "word too long: %c%c%c...", mem[j], mem[j+1], mem[j+2]);
-          ct->dobreak = 1;
-          custrinfo[i + 1].flag |= CU_CHINFO_WRAP;
-          ct -= 1;
-          cnr -= 1;
-          i--;
-          xof = ct->xof;
-          dobreak = true;
-        }
-        if (dobreak) {
-          if (tb_scale.h == 0.0f) {
-            /* Note: If underlined text is truncated away, the extra space is also truncated. */
-            custrinfo[i + 1].flag |= CU_CHINFO_OVERFLOW;
+          if (dobreak) {
+            if (tb_scale.h == 0.0f) {
+              /* Note: If underlined text is truncated away, the extra space is also truncated. */
+              custrinfo[i + 1].flag |= CU_CHINFO_OVERFLOW;
+            }
+            goto makebreak;
           }
-          goto makebreak;
         }
       }
     }
@@ -1497,6 +1525,7 @@ static bool vfont_to_curve(Object *ob,
           const float total_text_height = lnr * linedist;
           iter_data->scale_to_fit = tb_scale.h / total_text_height;
           iter_data->status = VFONT_TO_CURVE_SCALE_ONCE;
+          iter_data->word_wrap = false;
         }
       }
       else if (tb_scale.h == 0.0f) {
@@ -1504,10 +1533,10 @@ static bool vfont_to_curve(Object *ob,
         if (longest_line_length > tb_scale.w) {
           /* We make sure longest line before it broke can fit here. */
           float scale_to_fit = tb_scale.w / longest_line_length;
-          scale_to_fit -= FLT_EPSILON;
 
           iter_data->scale_to_fit = scale_to_fit;
           iter_data->status = VFONT_TO_CURVE_SCALE_ONCE;
+          iter_data->word_wrap = false;
         }
       }
     }
@@ -1568,6 +1597,7 @@ static bool vfont_to_curve(Object *ob,
           else {
             iter_data->scale_to_fit = iter_data->bisect.min;
             iter_data->status = VFONT_TO_CURVE_SCALE_ONCE;
+            iter_data->word_wrap = false;
           }
         }
       }
@@ -1637,6 +1667,7 @@ bool BKE_vfont_to_curve_ex(Object *ob,
   VFontToCurveIter data = {
       .iteraction = cu->totbox * FONT_TO_CURVE_SCALE_ITERATIONS,
       .scale_to_fit = 1.0f,
+      .word_wrap = true,
       .ok = true,
       .status = VFONT_TO_CURVE_INIT,
   };



More information about the Bf-blender-cvs mailing list