leafer-ui 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/README.md CHANGED
@@ -4,7 +4,7 @@ Leafer UI 是基于 Leafer 开发的一套绚丽多彩的 UI 绘图框架,可
4
4
 
5
5
  提供了常用的 UI 绘图组件,和开箱即用的功能,方便与 Figma、Sketch 等产品进行数据交换,并为跨平台开发提供了统一、丰富的交互事件,如拖拽、旋转、缩放手势等。
6
6
 
7
- 1.0.0-rc.4 已发布 🎉🎉🎉,查看 [更新日志](https://leaferjs.com/ui/update/)。
7
+ 1.0.0-rc.6 已发布 🎉🎉🎉,查看 [更新日志](https://leaferjs.com/ui/update/)。
8
8
 
9
9
  目前产品已经逐步稳定,正式版即将到来,感谢所有参与的朋友们~
10
10
 
package/dist/web.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, BoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, Platform, AnimateEvent, ResizeEvent, Creator, LeaferCanvasBase, Cursor, canvasSizeAttrs, canvasPatch, InteractionHelper, MathHelper, InteractionBase, LeaferImage, FileHelper, MatrixHelper, ImageEvent, PointHelper, 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 { ColorConvert as ColorConvert$1, ImageManager as ImageManager$1, Paint, Effect, TextConvert as TextConvert$1, Export as Export$1 } from '@leafer-ui/core';
5
5
  export * from '@leafer-ui/core';
6
6
 
7
7
  class Watcher {
@@ -105,7 +105,7 @@ function updateMatrix(updateList, levelList) {
105
105
  let layout;
106
106
  updateList.list.forEach(leaf => {
107
107
  layout = leaf.__layout;
108
- if (levelList.without(leaf) && !layout.useZoomProxy) {
108
+ if (levelList.without(leaf) && !layout.proxyZoom) {
109
109
  if (layout.matrixChanged) {
110
110
  updateAllWorldMatrix$1(leaf);
111
111
  levelList.push(leaf);
@@ -424,8 +424,7 @@ class Renderer {
424
424
  const { canvas, updateBlocks: list } = this;
425
425
  if (!list)
426
426
  return debug$1.warn('PartRender: need update attr');
427
- if (list.some(block => block.includes(this.target.__world)))
428
- this.mergeBlocks();
427
+ this.mergeBlocks();
429
428
  list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
430
429
  this.clipRender(block); });
431
430
  }
@@ -444,7 +443,7 @@ class Renderer {
444
443
  canvas.clearWorld(bounds, true);
445
444
  canvas.clipWorld(bounds, true);
446
445
  }
447
- this.__render(bounds, realBounds);
446
+ this.__render(bounds, includes, realBounds);
448
447
  canvas.restore();
449
448
  Run.end(t);
450
449
  }
@@ -453,12 +452,12 @@ class Renderer {
453
452
  const { canvas } = this;
454
453
  canvas.save();
455
454
  canvas.clear();
456
- this.__render(canvas.bounds);
455
+ this.__render(canvas.bounds, true);
457
456
  canvas.restore();
458
457
  Run.end(t);
459
458
  }
460
- __render(bounds, realBounds) {
461
- const options = (bounds === null || bounds === void 0 ? void 0 : bounds.includes(this.target.__world)) ? {} : { bounds };
459
+ __render(bounds, includes, realBounds) {
460
+ const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
462
461
  if (this.needFill)
463
462
  this.canvas.fillWorld(bounds, this.config.fill);
464
463
  if (Debug.showRepaint)
@@ -559,7 +558,7 @@ class Renderer {
559
558
  }
560
559
 
561
560
  const { hitRadiusPoint } = BoundsHelper;
562
- class FindPath {
561
+ class Pather {
563
562
  constructor(target, selector) {
564
563
  this.target = target;
565
564
  this.selector = selector;
@@ -679,117 +678,108 @@ class FindPath {
679
678
  class Selector {
680
679
  constructor(target, userConfig) {
681
680
  this.config = {};
682
- this.innerIdList = {};
683
- this.idList = {};
684
- this.classNameList = {};
685
- this.tagNameList = {};
681
+ this.innerIdMap = {};
682
+ this.idMap = {};
683
+ this.methods = {
684
+ id: (leaf, name) => leaf.id === name ? this.idMap[name] = leaf : 0,
685
+ innerId: (leaf, innerId) => leaf.innerId === innerId ? this.innerIdMap[innerId] = leaf : 0,
686
+ className: (leaf, name) => leaf.className === name ? 1 : 0,
687
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0
688
+ };
686
689
  this.target = target;
687
690
  if (userConfig)
688
691
  this.config = DataHelper.default(userConfig, this.config);
689
- this.findPath = new FindPath(target, this);
692
+ this.pather = new Pather(target, this);
690
693
  this.__listenEvents();
691
694
  }
692
695
  getByPoint(hitPoint, hitRadius, options) {
693
696
  if (Platform.name === 'node')
694
697
  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);
698
+ return this.pather.getByPoint(hitPoint, hitRadius, options);
699
+ }
700
+ getBy(condition, branch, one, options) {
701
+ switch (typeof condition) {
702
+ case 'number':
703
+ const leaf = this.getByInnerId(condition, branch);
704
+ return one ? leaf : (leaf ? [leaf] : []);
705
+ case 'string':
706
+ switch (condition[0]) {
707
+ case '#':
708
+ const leaf = this.getById(condition.substring(1), branch);
709
+ return one ? leaf : (leaf ? [leaf] : []);
710
+ case '.':
711
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
712
+ default:
713
+ return this.getByMethod(this.methods.tag, branch, one, condition);
714
+ }
715
+ case 'function':
716
+ return this.getByMethod(condition, branch, one, options);
709
717
  }
710
718
  }
711
- getByInnerId(name, branch) {
712
- let cache = this.innerIdList[name];
719
+ getByInnerId(innerId, branch) {
720
+ const cache = this.innerIdMap[innerId];
713
721
  if (cache)
714
722
  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;
723
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
724
+ return this.findLeaf;
729
725
  }
730
- getById(name, branch) {
731
- let cache = this.idList[name];
732
- if (cache)
726
+ getById(id, branch) {
727
+ const cache = this.idMap[id];
728
+ if (cache && LeafHelper.hasParent(cache, branch || this.target))
733
729
  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;
730
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id);
731
+ return this.findLeaf;
770
732
  }
771
- loopFind(branch, find) {
772
- if (find(branch))
773
- return;
774
- const { children } = branch;
733
+ getByClassName(className, branch) {
734
+ return this.getByMethod(this.methods.className, branch, false, className);
735
+ }
736
+ getByTag(tag, branch) {
737
+ return this.getByMethod(this.methods.tag, branch, false, tag);
738
+ }
739
+ getByMethod(method, branch, one, options) {
740
+ const list = one ? null : [];
741
+ this.eachFind(this.toChildren(branch), method, list, options);
742
+ return list || this.findLeaf;
743
+ }
744
+ eachFind(children, method, list, options) {
745
+ let child;
775
746
  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);
747
+ child = children[i];
748
+ if (method(child, options)) {
749
+ if (list) {
750
+ list.push(child);
751
+ }
752
+ else {
753
+ this.findLeaf = child;
754
+ return;
755
+ }
756
+ }
757
+ if (child.isBranch)
758
+ this.eachFind(child.children, method, list, options);
781
759
  }
782
760
  }
761
+ toChildren(branch) {
762
+ this.findLeaf = null;
763
+ return [branch || this.target];
764
+ }
783
765
  __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;
766
+ const { id, innerId } = event.child;
767
+ if (this.idMap[id])
768
+ delete this.idMap[id];
769
+ if (this.innerIdMap[innerId])
770
+ delete this.innerIdMap[innerId];
771
+ }
772
+ __checkIdChange(event) {
773
+ if (event.attrName === 'id') {
774
+ const id = event.oldValue;
775
+ if (this.idMap[id])
776
+ delete this.idMap[id];
777
+ }
789
778
  }
790
779
  __listenEvents() {
791
780
  this.__eventIds = [
792
- this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this)
781
+ this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
782
+ this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
793
783
  ];
794
784
  }
795
785
  __removeListenEvents() {
@@ -799,11 +789,10 @@ class Selector {
799
789
  destroy() {
800
790
  if (this.__eventIds.length) {
801
791
  this.__removeListenEvents();
802
- this.findPath.destroy();
803
- this.innerIdList = {};
804
- this.idList = {};
805
- this.classNameList = {};
806
- this.tagNameList = {};
792
+ this.pather.destroy();
793
+ this.findLeaf = null;
794
+ this.innerIdMap = {};
795
+ this.idMap = {};
807
796
  }
808
797
  }
809
798
  }
@@ -1025,7 +1014,7 @@ const WheelEventHelper = {
1025
1014
  let { zoomMode, zoomSpeed } = config;
1026
1015
  const delta = e.deltaY || e.deltaX;
1027
1016
  if (zoomMode) {
1028
- zoom = !e.deltaX && (Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta);
1017
+ zoom = (zoomMode === 'mouse') ? true : (!e.deltaX && (Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta));
1029
1018
  if (e.shiftKey || e.metaKey || e.ctrlKey)
1030
1019
  zoom = true;
1031
1020
  }
@@ -1062,6 +1051,7 @@ class Interaction extends InteractionBase {
1062
1051
  'pointerdown': this.onPointerDown,
1063
1052
  'mousedown': this.onMouseDown,
1064
1053
  'touchstart': this.onTouchStart,
1054
+ 'contextmenu': this.onContextMenu,
1065
1055
  'wheel': this.onWheel,
1066
1056
  'gesturestart': this.onGesturestart,
1067
1057
  'gesturechange': this.onGesturechange,
@@ -1134,6 +1124,9 @@ class Interaction extends InteractionBase {
1134
1124
  onKeyUp(e) {
1135
1125
  this.keyUp(KeyEventHelper.convert(e));
1136
1126
  }
1127
+ onContextMenu(e) {
1128
+ this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
1129
+ }
1137
1130
  onScroll() {
1138
1131
  this.canvas.updateClientBounds();
1139
1132
  }
@@ -1338,6 +1331,11 @@ function useCanvas(_canvasType, _power) {
1338
1331
  });
1339
1332
  }
1340
1333
  };
1334
+ Platform.event = {
1335
+ stopDefault(origin) { origin.preventDefault(); },
1336
+ stopNow(origin) { origin.stopImmediatePropagation(); },
1337
+ stop(origin) { origin.stopPropagation(); }
1338
+ };
1341
1339
  Platform.canvas = Creator.canvas();
1342
1340
  Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
1343
1341
  }
@@ -1642,10 +1640,14 @@ function checkImage(ui, canvas, paint, allowPaint) {
1642
1640
  createPattern(ui, paint, canvas.pixelRatio);
1643
1641
  }
1644
1642
  else {
1645
- ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1646
- if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
1643
+ if (!paint.patternTask) {
1644
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1645
+ paint.patternTask = null;
1646
+ if (canvas.bounds.hit(ui.__world))
1647
+ createPattern(ui, paint, canvas.pixelRatio);
1647
1648
  ui.forceUpdate('surface');
1648
- }), 300);
1649
+ }), 300);
1650
+ }
1649
1651
  }
1650
1652
  return false;
1651
1653
  }
@@ -2009,17 +2011,30 @@ function conicGradient(paint, box) {
2009
2011
  let recycleMap;
2010
2012
  function compute(attrName, ui) {
2011
2013
  const value = [];
2014
+ const data = ui.__;
2012
2015
  let item;
2013
- let paints = ui.__.__input[attrName];
2016
+ let paints = data.__input[attrName];
2014
2017
  if (!(paints instanceof Array))
2015
2018
  paints = [paints];
2016
- recycleMap = recycleImage(attrName, ui.__);
2019
+ recycleMap = recycleImage(attrName, data);
2017
2020
  for (let i = 0, len = paints.length; i < len; i++) {
2018
2021
  item = getLeafPaint(attrName, paints[i], ui);
2019
2022
  if (item)
2020
2023
  value.push(item);
2021
2024
  }
2022
- ui.__['_' + attrName] = value.length ? value : undefined;
2025
+ data['_' + attrName] = value.length ? value : undefined;
2026
+ let isPixel;
2027
+ if (paints.length === 1) {
2028
+ const paint = paints[0];
2029
+ if (paint.type === 'image')
2030
+ isPixel = ImageManager$1.isPixel(paint);
2031
+ }
2032
+ if (attrName === 'fill') {
2033
+ data.__pixelFill = isPixel;
2034
+ }
2035
+ else {
2036
+ data.__pixelStroke = isPixel;
2037
+ }
2023
2038
  }
2024
2039
  function getLeafPaint(attrName, paint, ui) {
2025
2040
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
@@ -2294,6 +2309,8 @@ function createRows(drawData, content, style) {
2294
2309
  const { width, height } = bounds;
2295
2310
  const charMode = width || height || __letterSpacing || (textCase !== 'none');
2296
2311
  if (charMode) {
2312
+ const wrap = style.textWrap !== 'none';
2313
+ const breakAll = style.textWrap === 'break';
2297
2314
  paraStart = true;
2298
2315
  lastCharType = null;
2299
2316
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
@@ -2320,16 +2337,23 @@ function createRows(drawData, content, style) {
2320
2337
  langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
2321
2338
  afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
2322
2339
  realWidth = paraStart && paraIndent ? width - paraIndent : width;
2323
- if (width && rowWidth + wordWidth + charWidth > realWidth) {
2324
- if (!afterBreak)
2325
- afterBreak = charType === Letter && lastCharType == After;
2326
- if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2340
+ if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
2341
+ if (breakAll) {
2327
2342
  if (wordWidth)
2328
2343
  addWord();
2329
2344
  addRow();
2330
2345
  }
2331
2346
  else {
2332
- addRow();
2347
+ if (!afterBreak)
2348
+ afterBreak = charType === Letter && lastCharType == After;
2349
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2350
+ if (wordWidth)
2351
+ addWord();
2352
+ addRow();
2353
+ }
2354
+ else {
2355
+ addRow();
2356
+ }
2333
2357
  }
2334
2358
  }
2335
2359
  if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
@@ -2399,7 +2423,7 @@ function addRow() {
2399
2423
 
2400
2424
  const CharMode = 0;
2401
2425
  const WordMode = 1;
2402
- const RowMode = 2;
2426
+ const TextMode = 2;
2403
2427
  function layoutChar(drawData, style, width, _height) {
2404
2428
  const { rows } = drawData;
2405
2429
  const { textAlign, paraIndent, letterSpacing } = style;
@@ -2408,15 +2432,12 @@ function layoutChar(drawData, style, width, _height) {
2408
2432
  if (row.words) {
2409
2433
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
2410
2434
  addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
2411
- mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : RowMode);
2412
- if (mode === RowMode) {
2413
- row.text = '';
2435
+ mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
2436
+ if (row.isOverflow && !letterSpacing)
2437
+ row.textMode = true;
2438
+ if (mode === TextMode) {
2414
2439
  row.x += indentWidth;
2415
- row.words.forEach(word => {
2416
- word.data.forEach(char => {
2417
- row.text += char.char;
2418
- });
2419
- });
2440
+ toTextChar$1(row);
2420
2441
  }
2421
2442
  else {
2422
2443
  row.x += indentWidth;
@@ -2442,6 +2463,14 @@ function layoutChar(drawData, style, width, _height) {
2442
2463
  }
2443
2464
  });
2444
2465
  }
2466
+ function toTextChar$1(row) {
2467
+ row.text = '';
2468
+ row.words.forEach(word => {
2469
+ word.data.forEach(char => {
2470
+ row.text += char.char;
2471
+ });
2472
+ });
2473
+ }
2445
2474
  function toWordChar(data, charX, wordChar) {
2446
2475
  data.forEach(char => {
2447
2476
  wordChar.char += char.char;
@@ -2462,10 +2491,10 @@ function toChar(data, charX, rowData) {
2462
2491
 
2463
2492
  function layoutText(drawData, style) {
2464
2493
  const { rows, bounds } = drawData;
2465
- const { __lineHeight, __baseLine, __letterSpacing, textAlign, verticalAlign, paraSpacing, textOverflow } = style;
2494
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2466
2495
  let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2467
2496
  let starY = __baseLine;
2468
- if (textOverflow !== 'show' && realHeight > height) {
2497
+ if (__clipText && realHeight > height) {
2469
2498
  realHeight = Math.max(height, __lineHeight);
2470
2499
  drawData.overflow = rows.length;
2471
2500
  }
@@ -2514,39 +2543,58 @@ function layoutText(drawData, style) {
2514
2543
  bounds.x = rowX;
2515
2544
  if (rowWidth > bounds.width)
2516
2545
  bounds.width = rowWidth;
2546
+ if (__clipText && width && width < rowWidth) {
2547
+ row.isOverflow = true;
2548
+ if (!drawData.overflow)
2549
+ drawData.overflow = rows.length;
2550
+ }
2517
2551
  }
2518
2552
  bounds.y = y;
2519
2553
  bounds.height = realHeight;
2520
2554
  }
2521
2555
 
2522
- function clipText(drawData, textOverflow) {
2556
+ function clipText(drawData, style) {
2523
2557
  const { rows, overflow } = drawData;
2558
+ let { textOverflow } = style;
2524
2559
  rows.splice(overflow);
2525
2560
  if (textOverflow !== 'hide') {
2526
2561
  if (textOverflow === 'ellipsis')
2527
2562
  textOverflow = '...';
2563
+ let char, charRight;
2528
2564
  const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2529
- const row = rows[overflow - 1];
2530
- let char, end = row.data.length - 1, charRight;
2531
- const { x, width } = drawData.bounds;
2532
- const right = x + width - ellipsisWidth;
2533
- for (let i = end; i > -1; i--) {
2534
- char = row.data[i];
2535
- charRight = char.x + char.width;
2536
- if (i === end && charRight < right) {
2537
- break;
2538
- }
2539
- else if (charRight < right && char.char !== ' ') {
2540
- row.data.splice(i + 1);
2541
- row.width -= char.width;
2542
- break;
2565
+ const right = style.x + style.width - ellipsisWidth;
2566
+ const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2567
+ list.forEach(row => {
2568
+ if (row.isOverflow && row.data) {
2569
+ let end = row.data.length - 1;
2570
+ for (let i = end; i > -1; i--) {
2571
+ char = row.data[i];
2572
+ charRight = char.x + char.width;
2573
+ if (i === end && charRight < right) {
2574
+ break;
2575
+ }
2576
+ else if (charRight < right && char.char !== ' ') {
2577
+ row.data.splice(i + 1);
2578
+ row.width -= char.width;
2579
+ break;
2580
+ }
2581
+ row.width -= char.width;
2582
+ }
2583
+ row.width += ellipsisWidth;
2584
+ row.data.push({ char: textOverflow, x: charRight });
2585
+ if (row.textMode)
2586
+ toTextChar(row);
2543
2587
  }
2544
- row.width -= char.width;
2545
- }
2546
- row.width += ellipsisWidth;
2547
- row.data.push({ char: textOverflow, x: charRight });
2588
+ });
2548
2589
  }
2549
2590
  }
2591
+ function toTextChar(row) {
2592
+ row.text = '';
2593
+ row.data.forEach(char => {
2594
+ row.text += char.char;
2595
+ });
2596
+ row.data = null;
2597
+ }
2550
2598
 
2551
2599
  function decorationText(drawData, style) {
2552
2600
  const { fontSize } = style;
@@ -2567,7 +2615,7 @@ const TextConvert = {
2567
2615
  let x = 0, y = 0;
2568
2616
  let width = style.__getInput('width') || 0;
2569
2617
  let height = style.__getInput('height') || 0;
2570
- const { textDecoration, textOverflow, __font, padding } = style;
2618
+ const { textDecoration, __font, padding } = style;
2571
2619
  if (padding) {
2572
2620
  const [top, right, bottom, left] = MathHelper.fourNumber(padding);
2573
2621
  if (width) {
@@ -2589,7 +2637,7 @@ const TextConvert = {
2589
2637
  layoutText(drawData, style);
2590
2638
  layoutChar(drawData, style, width);
2591
2639
  if (drawData.overflow)
2592
- clipText(drawData, textOverflow);
2640
+ clipText(drawData, style);
2593
2641
  if (textDecoration !== 'none')
2594
2642
  decorationText(drawData, style);
2595
2643
  return drawData;