@leafer-ui/node 1.0.0-rc.4 → 1.0.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.cjs CHANGED
@@ -1,8 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@leafer/core');
4
+ var fs = require('fs');
4
5
  var core$1 = require('@leafer-ui/core');
5
6
 
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol */
22
+
23
+
24
+ function __awaiter(thisArg, _arguments, P, generator) {
25
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26
+ return new (P || (P = Promise))(function (resolve, reject) {
27
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
31
+ });
32
+ }
33
+
34
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
35
+ var e = new Error(message);
36
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
37
+ };
38
+
6
39
  class Watcher {
7
40
  get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
8
41
  get updatedList() {
@@ -104,7 +137,7 @@ function updateMatrix(updateList, levelList) {
104
137
  let layout;
105
138
  updateList.list.forEach(leaf => {
106
139
  layout = leaf.__layout;
107
- if (levelList.without(leaf) && !layout.useZoomProxy) {
140
+ if (levelList.without(leaf) && !layout.proxyZoom) {
108
141
  if (layout.matrixChanged) {
109
142
  updateAllWorldMatrix$1(leaf);
110
143
  levelList.push(leaf);
@@ -423,8 +456,7 @@ class Renderer {
423
456
  const { canvas, updateBlocks: list } = this;
424
457
  if (!list)
425
458
  return debug.warn('PartRender: need update attr');
426
- if (list.some(block => block.includes(this.target.__world)))
427
- this.mergeBlocks();
459
+ this.mergeBlocks();
428
460
  list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
429
461
  this.clipRender(block); });
430
462
  }
@@ -443,7 +475,7 @@ class Renderer {
443
475
  canvas.clearWorld(bounds, true);
444
476
  canvas.clipWorld(bounds, true);
445
477
  }
446
- this.__render(bounds, realBounds);
478
+ this.__render(bounds, includes, realBounds);
447
479
  canvas.restore();
448
480
  core.Run.end(t);
449
481
  }
@@ -452,12 +484,12 @@ class Renderer {
452
484
  const { canvas } = this;
453
485
  canvas.save();
454
486
  canvas.clear();
455
- this.__render(canvas.bounds);
487
+ this.__render(canvas.bounds, true);
456
488
  canvas.restore();
457
489
  core.Run.end(t);
458
490
  }
459
- __render(bounds, realBounds) {
460
- const options = (bounds === null || bounds === void 0 ? void 0 : bounds.includes(this.target.__world)) ? {} : { bounds };
491
+ __render(bounds, includes, realBounds) {
492
+ const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
461
493
  if (this.needFill)
462
494
  this.canvas.fillWorld(bounds, this.config.fill);
463
495
  if (core.Debug.showRepaint)
@@ -558,7 +590,7 @@ class Renderer {
558
590
  }
559
591
 
560
592
  const { hitRadiusPoint } = core.BoundsHelper;
561
- class FindPath {
593
+ class Pather {
562
594
  constructor(target, selector) {
563
595
  this.target = target;
564
596
  this.selector = selector;
@@ -678,117 +710,108 @@ class FindPath {
678
710
  class Selector {
679
711
  constructor(target, userConfig) {
680
712
  this.config = {};
681
- this.innerIdList = {};
682
- this.idList = {};
683
- this.classNameList = {};
684
- this.tagNameList = {};
713
+ this.innerIdMap = {};
714
+ this.idMap = {};
715
+ this.methods = {
716
+ id: (leaf, name) => leaf.id === name ? this.idMap[name] = leaf : 0,
717
+ innerId: (leaf, innerId) => leaf.innerId === innerId ? this.innerIdMap[innerId] = leaf : 0,
718
+ className: (leaf, name) => leaf.className === name ? 1 : 0,
719
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0
720
+ };
685
721
  this.target = target;
686
722
  if (userConfig)
687
723
  this.config = core.DataHelper.default(userConfig, this.config);
688
- this.findPath = new FindPath(target, this);
724
+ this.pather = new Pather(target, this);
689
725
  this.__listenEvents();
690
726
  }
691
727
  getByPoint(hitPoint, hitRadius, options) {
692
728
  if (core.Platform.name === 'node')
693
729
  this.target.emit(core.LayoutEvent.CHECK_UPDATE);
694
- return this.findPath.getByPoint(hitPoint, hitRadius, options);
695
- }
696
- find(name, branch) {
697
- if (typeof name === 'number') {
698
- return this.getByInnerId(name, branch);
699
- }
700
- else if (name.startsWith('#')) {
701
- return this.getById(name.substring(1), branch);
702
- }
703
- else if (name.startsWith('.')) {
704
- return this.getByClassName(name.substring(1), branch);
705
- }
706
- else {
707
- return this.getByTagName(name, branch);
730
+ return this.pather.getByPoint(hitPoint, hitRadius, options);
731
+ }
732
+ getBy(condition, branch, one, options) {
733
+ switch (typeof condition) {
734
+ case 'number':
735
+ const leaf = this.getByInnerId(condition, branch);
736
+ return one ? leaf : (leaf ? [leaf] : []);
737
+ case 'string':
738
+ switch (condition[0]) {
739
+ case '#':
740
+ const leaf = this.getById(condition.substring(1), branch);
741
+ return one ? leaf : (leaf ? [leaf] : []);
742
+ case '.':
743
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
744
+ default:
745
+ return this.getByMethod(this.methods.tag, branch, one, condition);
746
+ }
747
+ case 'function':
748
+ return this.getByMethod(condition, branch, one, options);
708
749
  }
709
750
  }
710
- getByInnerId(name, branch) {
711
- let cache = this.innerIdList[name];
751
+ getByInnerId(innerId, branch) {
752
+ const cache = this.innerIdMap[innerId];
712
753
  if (cache)
713
754
  return cache;
714
- if (!branch)
715
- branch = this.target;
716
- let find;
717
- this.loopFind(branch, (leaf) => {
718
- if (leaf.innerId === name) {
719
- find = leaf;
720
- this.innerIdList[name] = find;
721
- return true;
722
- }
723
- else {
724
- return false;
725
- }
726
- });
727
- return find;
755
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
756
+ return this.findLeaf;
728
757
  }
729
- getById(name, branch) {
730
- let cache = this.idList[name];
731
- if (cache)
758
+ getById(id, branch) {
759
+ const cache = this.idMap[id];
760
+ if (cache && core.LeafHelper.hasParent(cache, branch || this.target))
732
761
  return cache;
733
- if (!branch)
734
- branch = this.target;
735
- let find;
736
- this.loopFind(branch, (leaf) => {
737
- if (leaf.id === name) {
738
- find = leaf;
739
- this.idList[name] = find;
740
- return true;
741
- }
742
- else {
743
- return false;
744
- }
745
- });
746
- return find;
747
- }
748
- getByClassName(name, branch) {
749
- if (!branch)
750
- branch = this.target;
751
- let find = [];
752
- this.loopFind(branch, (leaf) => {
753
- if (leaf.className === name)
754
- find.push(leaf);
755
- return false;
756
- });
757
- return find;
758
- }
759
- getByTagName(name, branch) {
760
- if (!branch)
761
- branch = this.target;
762
- let find = [];
763
- this.loopFind(branch, (leaf) => {
764
- if (leaf.__tag === name)
765
- find.push(leaf);
766
- return false;
767
- });
768
- return find;
762
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id);
763
+ return this.findLeaf;
769
764
  }
770
- loopFind(branch, find) {
771
- if (find(branch))
772
- return;
773
- const { children } = branch;
765
+ getByClassName(className, branch) {
766
+ return this.getByMethod(this.methods.className, branch, false, className);
767
+ }
768
+ getByTag(tag, branch) {
769
+ return this.getByMethod(this.methods.tag, branch, false, tag);
770
+ }
771
+ getByMethod(method, branch, one, options) {
772
+ const list = one ? null : [];
773
+ this.eachFind(this.toChildren(branch), method, list, options);
774
+ return list || this.findLeaf;
775
+ }
776
+ eachFind(children, method, list, options) {
777
+ let child;
774
778
  for (let i = 0, len = children.length; i < len; i++) {
775
- branch = children[i];
776
- if (find(branch))
777
- return;
778
- if (branch.isBranch)
779
- this.loopFind(branch, find);
779
+ child = children[i];
780
+ if (method(child, options)) {
781
+ if (list) {
782
+ list.push(child);
783
+ }
784
+ else {
785
+ this.findLeaf = child;
786
+ return;
787
+ }
788
+ }
789
+ if (child.isBranch)
790
+ this.eachFind(child.children, method, list, options);
780
791
  }
781
792
  }
793
+ toChildren(branch) {
794
+ this.findLeaf = null;
795
+ return [branch || this.target];
796
+ }
782
797
  __onRemoveChild(event) {
783
- const target = event.target;
784
- if (this.idList[target.id])
785
- this.idList[target.id] = null;
786
- if (this.innerIdList[target.id])
787
- this.innerIdList[target.innerId] = null;
798
+ const { id, innerId } = event.child;
799
+ if (this.idMap[id])
800
+ delete this.idMap[id];
801
+ if (this.innerIdMap[innerId])
802
+ delete this.innerIdMap[innerId];
803
+ }
804
+ __checkIdChange(event) {
805
+ if (event.attrName === 'id') {
806
+ const id = event.oldValue;
807
+ if (this.idMap[id])
808
+ delete this.idMap[id];
809
+ }
788
810
  }
789
811
  __listenEvents() {
790
812
  this.__eventIds = [
791
- this.target.on_(core.ChildEvent.REMOVE, this.__onRemoveChild, this)
813
+ this.target.on_(core.ChildEvent.REMOVE, this.__onRemoveChild, this),
814
+ this.target.on_(core.PropertyEvent.CHANGE, this.__checkIdChange, this)
792
815
  ];
793
816
  }
794
817
  __removeListenEvents() {
@@ -798,11 +821,10 @@ class Selector {
798
821
  destroy() {
799
822
  if (this.__eventIds.length) {
800
823
  this.__removeListenEvents();
801
- this.findPath.destroy();
802
- this.innerIdList = {};
803
- this.idList = {};
804
- this.classNameList = {};
805
- this.tagNameList = {};
824
+ this.pather.destroy();
825
+ this.findLeaf = null;
826
+ this.innerIdMap = {};
827
+ this.idMap = {};
806
828
  }
807
829
  }
808
830
  }
@@ -821,6 +843,10 @@ class LeaferCanvas extends core.LeaferCanvasBase {
821
843
  this.__createView();
822
844
  this.__createContext();
823
845
  this.resize(this.config);
846
+ if (core.Platform.roundRectPatch) {
847
+ this.context.__proto__.roundRect = null;
848
+ core.canvasPatch(this.context.__proto__);
849
+ }
824
850
  }
825
851
  __createView() {
826
852
  this.view = core.Platform.origin.createCanvas(1, 1);
@@ -833,6 +859,7 @@ class LeaferCanvas extends core.LeaferCanvasBase {
833
859
  }
834
860
  }
835
861
 
862
+ const { mineType, fileType } = core.FileHelper;
836
863
  Object.assign(core.Creator, {
837
864
  canvas: (options, manager) => new LeaferCanvas(options, manager),
838
865
  image: (options) => new core.LeaferImage(options),
@@ -840,6 +867,7 @@ Object.assign(core.Creator, {
840
867
  interaction: (target, canvas, selector, options) => { return new core.InteractionBase(target, canvas, selector, options); }
841
868
  });
842
869
  function useCanvas(canvasType, power) {
870
+ core.Platform.canvasType = canvasType;
843
871
  if (!core.Platform.origin) {
844
872
  if (canvasType === 'skia') {
845
873
  const { Canvas, loadImage } = power;
@@ -850,7 +878,24 @@ function useCanvas(canvasType, power) {
850
878
  canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
851
879
  loadImage
852
880
  };
881
+ core.Platform.roundRectPatch = true;
853
882
  }
883
+ else if (canvasType === 'napi') {
884
+ const { Canvas, loadImage } = power;
885
+ core.Platform.origin = {
886
+ createCanvas: (width, height, format) => new Canvas(width, height, format),
887
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
888
+ canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function* () { return canvas.toBuffer(mineType(type), quality); }),
889
+ canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function* () { return fs.writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality)); }),
890
+ loadImage
891
+ };
892
+ }
893
+ core.Platform.ellipseToCurve = true;
894
+ core.Platform.event = {
895
+ stopDefault(_origin) { },
896
+ stopNow(_origin) { },
897
+ stop(_origin) { }
898
+ };
854
899
  core.Platform.canvas = core.Creator.canvas();
855
900
  }
856
901
  }
@@ -1006,38 +1051,6 @@ function emit(type, data) {
1006
1051
  data.target.emitEvent(new core.ImageEvent(type, data));
1007
1052
  }
1008
1053
 
1009
- /******************************************************************************
1010
- Copyright (c) Microsoft Corporation.
1011
-
1012
- Permission to use, copy, modify, and/or distribute this software for any
1013
- purpose with or without fee is hereby granted.
1014
-
1015
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1016
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1017
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1018
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1019
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1020
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1021
- PERFORMANCE OF THIS SOFTWARE.
1022
- ***************************************************************************** */
1023
- /* global Reflect, Promise, SuppressedError, Symbol */
1024
-
1025
-
1026
- function __awaiter(thisArg, _arguments, P, generator) {
1027
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1028
- return new (P || (P = Promise))(function (resolve, reject) {
1029
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1030
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1031
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1032
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1033
- });
1034
- }
1035
-
1036
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1037
- var e = new Error(message);
1038
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1039
- };
1040
-
1041
1054
  const { get: get$2, scale: scaleHelper, copy: copy$1 } = core.MatrixHelper;
1042
1055
  function createPattern(ui, paint, pixelRatio) {
1043
1056
  let { scaleX, scaleY } = ui.__world;
@@ -1136,10 +1149,14 @@ function checkImage(ui, canvas, paint, allowPaint) {
1136
1149
  createPattern(ui, paint, canvas.pixelRatio);
1137
1150
  }
1138
1151
  else {
1139
- core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1140
- if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
1152
+ if (!paint.patternTask) {
1153
+ paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1154
+ paint.patternTask = null;
1155
+ if (canvas.bounds.hit(ui.__world))
1156
+ createPattern(ui, paint, canvas.pixelRatio);
1141
1157
  ui.forceUpdate('surface');
1142
- }), 300);
1158
+ }), 300);
1159
+ }
1143
1160
  }
1144
1161
  return false;
1145
1162
  }
@@ -1503,17 +1520,30 @@ function conicGradient(paint, box) {
1503
1520
  let recycleMap;
1504
1521
  function compute(attrName, ui) {
1505
1522
  const value = [];
1523
+ const data = ui.__;
1506
1524
  let item;
1507
- let paints = ui.__.__input[attrName];
1525
+ let paints = data.__input[attrName];
1508
1526
  if (!(paints instanceof Array))
1509
1527
  paints = [paints];
1510
- recycleMap = recycleImage(attrName, ui.__);
1528
+ recycleMap = recycleImage(attrName, data);
1511
1529
  for (let i = 0, len = paints.length; i < len; i++) {
1512
1530
  item = getLeafPaint(attrName, paints[i], ui);
1513
1531
  if (item)
1514
1532
  value.push(item);
1515
1533
  }
1516
- ui.__['_' + attrName] = value.length ? value : undefined;
1534
+ data['_' + attrName] = value.length ? value : undefined;
1535
+ let isPixel;
1536
+ if (paints.length === 1) {
1537
+ const paint = paints[0];
1538
+ if (paint.type === 'image')
1539
+ isPixel = core$1.ImageManager.isPixel(paint);
1540
+ }
1541
+ if (attrName === 'fill') {
1542
+ data.__pixelFill = isPixel;
1543
+ }
1544
+ else {
1545
+ data.__pixelStroke = isPixel;
1546
+ }
1517
1547
  }
1518
1548
  function getLeafPaint(attrName, paint, ui) {
1519
1549
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
@@ -1788,6 +1818,8 @@ function createRows(drawData, content, style) {
1788
1818
  const { width, height } = bounds;
1789
1819
  const charMode = width || height || __letterSpacing || (textCase !== 'none');
1790
1820
  if (charMode) {
1821
+ const wrap = style.textWrap !== 'none';
1822
+ const breakAll = style.textWrap === 'break';
1791
1823
  paraStart = true;
1792
1824
  lastCharType = null;
1793
1825
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
@@ -1814,16 +1846,23 @@ function createRows(drawData, content, style) {
1814
1846
  langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
1815
1847
  afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
1816
1848
  realWidth = paraStart && paraIndent ? width - paraIndent : width;
1817
- if (width && rowWidth + wordWidth + charWidth > realWidth) {
1818
- if (!afterBreak)
1819
- afterBreak = charType === Letter && lastCharType == After;
1820
- if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
1849
+ if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
1850
+ if (breakAll) {
1821
1851
  if (wordWidth)
1822
1852
  addWord();
1823
1853
  addRow();
1824
1854
  }
1825
1855
  else {
1826
- addRow();
1856
+ if (!afterBreak)
1857
+ afterBreak = charType === Letter && lastCharType == After;
1858
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
1859
+ if (wordWidth)
1860
+ addWord();
1861
+ addRow();
1862
+ }
1863
+ else {
1864
+ addRow();
1865
+ }
1827
1866
  }
1828
1867
  }
1829
1868
  if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
@@ -1893,7 +1932,7 @@ function addRow() {
1893
1932
 
1894
1933
  const CharMode = 0;
1895
1934
  const WordMode = 1;
1896
- const RowMode = 2;
1935
+ const TextMode = 2;
1897
1936
  function layoutChar(drawData, style, width, _height) {
1898
1937
  const { rows } = drawData;
1899
1938
  const { textAlign, paraIndent, letterSpacing } = style;
@@ -1902,15 +1941,12 @@ function layoutChar(drawData, style, width, _height) {
1902
1941
  if (row.words) {
1903
1942
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
1904
1943
  addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
1905
- mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : RowMode);
1906
- if (mode === RowMode) {
1907
- row.text = '';
1944
+ mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
1945
+ if (row.isOverflow && !letterSpacing)
1946
+ row.textMode = true;
1947
+ if (mode === TextMode) {
1908
1948
  row.x += indentWidth;
1909
- row.words.forEach(word => {
1910
- word.data.forEach(char => {
1911
- row.text += char.char;
1912
- });
1913
- });
1949
+ toTextChar$1(row);
1914
1950
  }
1915
1951
  else {
1916
1952
  row.x += indentWidth;
@@ -1936,6 +1972,14 @@ function layoutChar(drawData, style, width, _height) {
1936
1972
  }
1937
1973
  });
1938
1974
  }
1975
+ function toTextChar$1(row) {
1976
+ row.text = '';
1977
+ row.words.forEach(word => {
1978
+ word.data.forEach(char => {
1979
+ row.text += char.char;
1980
+ });
1981
+ });
1982
+ }
1939
1983
  function toWordChar(data, charX, wordChar) {
1940
1984
  data.forEach(char => {
1941
1985
  wordChar.char += char.char;
@@ -1956,10 +2000,10 @@ function toChar(data, charX, rowData) {
1956
2000
 
1957
2001
  function layoutText(drawData, style) {
1958
2002
  const { rows, bounds } = drawData;
1959
- const { __lineHeight, __baseLine, __letterSpacing, textAlign, verticalAlign, paraSpacing, textOverflow } = style;
2003
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
1960
2004
  let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
1961
2005
  let starY = __baseLine;
1962
- if (textOverflow !== 'show' && realHeight > height) {
2006
+ if (__clipText && realHeight > height) {
1963
2007
  realHeight = Math.max(height, __lineHeight);
1964
2008
  drawData.overflow = rows.length;
1965
2009
  }
@@ -2008,39 +2052,58 @@ function layoutText(drawData, style) {
2008
2052
  bounds.x = rowX;
2009
2053
  if (rowWidth > bounds.width)
2010
2054
  bounds.width = rowWidth;
2055
+ if (__clipText && width && width < rowWidth) {
2056
+ row.isOverflow = true;
2057
+ if (!drawData.overflow)
2058
+ drawData.overflow = rows.length;
2059
+ }
2011
2060
  }
2012
2061
  bounds.y = y;
2013
2062
  bounds.height = realHeight;
2014
2063
  }
2015
2064
 
2016
- function clipText(drawData, textOverflow) {
2065
+ function clipText(drawData, style) {
2017
2066
  const { rows, overflow } = drawData;
2067
+ let { textOverflow } = style;
2018
2068
  rows.splice(overflow);
2019
2069
  if (textOverflow !== 'hide') {
2020
2070
  if (textOverflow === 'ellipsis')
2021
2071
  textOverflow = '...';
2072
+ let char, charRight;
2022
2073
  const ellipsisWidth = core.Platform.canvas.measureText(textOverflow).width;
2023
- const row = rows[overflow - 1];
2024
- let char, end = row.data.length - 1, charRight;
2025
- const { x, width } = drawData.bounds;
2026
- const right = x + width - ellipsisWidth;
2027
- for (let i = end; i > -1; i--) {
2028
- char = row.data[i];
2029
- charRight = char.x + char.width;
2030
- if (i === end && charRight < right) {
2031
- break;
2032
- }
2033
- else if (charRight < right && char.char !== ' ') {
2034
- row.data.splice(i + 1);
2035
- row.width -= char.width;
2036
- break;
2074
+ const right = style.x + style.width - ellipsisWidth;
2075
+ const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2076
+ list.forEach(row => {
2077
+ if (row.isOverflow && row.data) {
2078
+ let end = row.data.length - 1;
2079
+ for (let i = end; i > -1; i--) {
2080
+ char = row.data[i];
2081
+ charRight = char.x + char.width;
2082
+ if (i === end && charRight < right) {
2083
+ break;
2084
+ }
2085
+ else if (charRight < right && char.char !== ' ') {
2086
+ row.data.splice(i + 1);
2087
+ row.width -= char.width;
2088
+ break;
2089
+ }
2090
+ row.width -= char.width;
2091
+ }
2092
+ row.width += ellipsisWidth;
2093
+ row.data.push({ char: textOverflow, x: charRight });
2094
+ if (row.textMode)
2095
+ toTextChar(row);
2037
2096
  }
2038
- row.width -= char.width;
2039
- }
2040
- row.width += ellipsisWidth;
2041
- row.data.push({ char: textOverflow, x: charRight });
2097
+ });
2042
2098
  }
2043
2099
  }
2100
+ function toTextChar(row) {
2101
+ row.text = '';
2102
+ row.data.forEach(char => {
2103
+ row.text += char.char;
2104
+ });
2105
+ row.data = null;
2106
+ }
2044
2107
 
2045
2108
  function decorationText(drawData, style) {
2046
2109
  const { fontSize } = style;
@@ -2061,7 +2124,7 @@ const TextConvert = {
2061
2124
  let x = 0, y = 0;
2062
2125
  let width = style.__getInput('width') || 0;
2063
2126
  let height = style.__getInput('height') || 0;
2064
- const { textDecoration, textOverflow, __font, padding } = style;
2127
+ const { textDecoration, __font, padding } = style;
2065
2128
  if (padding) {
2066
2129
  const [top, right, bottom, left] = core.MathHelper.fourNumber(padding);
2067
2130
  if (width) {
@@ -2083,7 +2146,7 @@ const TextConvert = {
2083
2146
  layoutText(drawData, style);
2084
2147
  layoutChar(drawData, style, width);
2085
2148
  if (drawData.overflow)
2086
- clipText(drawData, textOverflow);
2149
+ clipText(drawData, style);
2087
2150
  if (textDecoration !== 'none')
2088
2151
  decorationText(drawData, style);
2089
2152
  return drawData;