Prechádzať zdrojové kódy

Merge pull request #8823 from RaananW/textBlockWrapUnicode

Text block wrap with unicode strings
David Catuhe 5 rokov pred
rodič
commit
89e04e4267

+ 1 - 0
dist/preview release/what's new.md

@@ -294,6 +294,7 @@
 - Fix an issue with sound updateOptions not updating the underlying sound buffer/html element ([RaananW](https://github.com/RaananW))
 - Fixed bug in sphereBuilder where top and bottom segments added 6 indices per triangle instead of 3. ([aWeirdo](https://github.com/aWeirdo))
 - Fixed issue with Babylon scene export of loaded glTF meshes.([Drigax]/(https://github.com/drigax))
+- Fixed an issue with text block wrap and unicode strings (not working in IE11) ([#8822](https://github.com/BabylonJS/Babylon.js/issues/8822)) ([RaananW](https://github.com/RaananW))
 
 ## Breaking changes
 - `FollowCamera.target` was renamed to `FollowCamera.meshTarget` to not be in conflict with `TargetCamera.target` ([Deltakosh](https://github.com/deltakosh))

+ 35 - 27
gui/src/2D/controls/textBlock.ts

@@ -2,8 +2,8 @@ import { Observable } from "babylonjs/Misc/observable";
 import { Measure } from "../measure";
 import { ValueAndUnit } from "../valueAndUnit";
 import { Control } from "./control";
-import { _TypeStore } from 'babylonjs/Misc/typeStore';
-import { Nullable } from 'babylonjs/types';
+import { _TypeStore } from "babylonjs/Misc/typeStore";
+import { Nullable } from "babylonjs/types";
 
 /**
  * Enum that determines the text-wrapping mode to use.
@@ -42,13 +42,13 @@ export class TextBlock extends Control {
     private _underline: boolean = false;
     private _lineThrough: boolean = false;
     /**
-    * An event triggered after the text is changed
-    */
+     * An event triggered after the text is changed
+     */
     public onTextChangedObservable = new Observable<TextBlock>();
 
     /**
-    * An event triggered after the text was broken up into lines
-    */
+     * An event triggered after the text was broken up into lines
+     */
     public onLinesReadyObservable = new Observable<TextBlock>();
 
     /**
@@ -261,7 +261,8 @@ export class TextBlock extends Control {
          * Defines the name of the control
          */
         public name?: string,
-        text: string = "") {
+        text: string = ""
+    ) {
         super(name);
 
         this.text = text;
@@ -307,7 +308,7 @@ export class TextBlock extends Control {
                 if (this._lineSpacing.isPixel) {
                     lineSpacing = this._lineSpacing.getValue(this._host);
                 } else {
-                    lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                    lineSpacing = this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
                 }
 
                 newHeight += (this._lines.length - 1) * lineSpacing;
@@ -407,29 +408,39 @@ export class TextBlock extends Control {
         return lines;
     }
 
-    protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
+    protected _parseLine(line: string = "", context: CanvasRenderingContext2D): object {
         return { text: line, width: context.measureText(line).width };
     }
 
-    protected _parseLineEllipsis(line: string = '', width: number,
-        context: CanvasRenderingContext2D): object {
+    protected _parseLineEllipsis(line: string = "", width: number, context: CanvasRenderingContext2D): object {
         var lineWidth = context.measureText(line).width;
 
         if (lineWidth > width) {
-            line += '…';
+            line += "…";
         }
-        while (line.length > 2 && lineWidth > width) {
-            line = line.slice(0, -2) + '…';
-            lineWidth = context.measureText(line).width;
+        // unicode support. split('') does not work with unicode!
+        // make sure Array.from is available
+        const characters = Array.from && Array.from(line);
+        if (!characters) {
+            // no array.from, use the old method
+            while (line.length > 2 && lineWidth > width) {
+                line = line.slice(0, -2) + "…";
+                lineWidth = context.measureText(line).width;
+            }
+        } else {
+            while (characters.length && lineWidth > width) {
+                characters.pop();
+                line = `${characters.join()}...`;
+                lineWidth = context.measureText(line).width;
+            }
         }
 
         return { text: line, width: lineWidth };
     }
 
-    protected _parseLineWordWrap(line: string = '', width: number,
-        context: CanvasRenderingContext2D): object[] {
+    protected _parseLineWordWrap(line: string = "", width: number, context: CanvasRenderingContext2D): object[] {
         var lines = [];
-        var words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(' ');
+        var words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(" ");
         var lineWidth = 0;
 
         for (var n = 0; n < words.length; n++) {
@@ -440,8 +451,7 @@ export class TextBlock extends Control {
                 lines.push({ text: line, width: lineWidth });
                 line = words[n];
                 lineWidth = context.measureText(line).width;
-            }
-            else {
+            } else {
                 lineWidth = testWidth;
                 line = testLine;
             }
@@ -472,11 +482,10 @@ export class TextBlock extends Control {
             const line = this._lines[i];
 
             if (i !== 0 && this._lineSpacing.internalValue !== 0) {
-
                 if (this._lineSpacing.isPixel) {
                     rootY += this._lineSpacing.getValue(this._host);
                 } else {
-                    rootY = rootY + (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                    rootY = rootY + this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
                 }
             }
 
@@ -491,14 +500,13 @@ export class TextBlock extends Control {
      */
     public computeExpectedHeight(): number {
         if (this.text && this.widthInPixels) {
-            const context = document.createElement('canvas').getContext('2d');
+            const context = document.createElement("canvas").getContext("2d");
             if (context) {
                 this._applyStates(context);
                 if (!this._fontOffset) {
                     this._fontOffset = Control._GetFontOffset(context.font);
                 }
-                const lines = this._lines ? this._lines : this._breakLines(
-                    this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
+                const lines = this._lines ? this._lines : this._breakLines(this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
 
                 let newHeight = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
 
@@ -507,7 +515,7 @@ export class TextBlock extends Control {
                     if (this._lineSpacing.isPixel) {
                         lineSpacing = this._lineSpacing.getValue(this._host);
                     } else {
-                        lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                        lineSpacing = this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height);
                     }
 
                     newHeight += (lines.length - 1) * lineSpacing;
@@ -525,4 +533,4 @@ export class TextBlock extends Control {
         this.onTextChangedObservable.clear();
     }
 }
-_TypeStore.RegisteredTypes["BABYLON.GUI.TextBlock"] = TextBlock;
+_TypeStore.RegisteredTypes["BABYLON.GUI.TextBlock"] = TextBlock;