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