leafer-ui 1.9.12 → 1.10.1

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/web.cjs CHANGED
@@ -985,6 +985,7 @@ class Picker {
985
985
  hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
986
986
  if (child.isBranch) {
987
987
  if (hit || child.__ignoreHitWorld) {
988
+ if (child.isBranchLeaf && child.__.__clipAfterFill && !child.__hitWorld(point)) continue;
988
989
  if (child.topChildren) this.eachFind(child.topChildren, false);
989
990
  this.eachFind(child.children, child.__onlyHitMask);
990
991
  if (child.isBranchLeaf) this.hitChild(child, point);
@@ -1393,102 +1394,163 @@ class Interaction extends core$1.InteractionBase {
1393
1394
  }
1394
1395
  }
1395
1396
 
1396
- function fillText(ui, canvas) {
1397
- const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
1398
- if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
1399
- let row;
1400
- for (let i = 0, len = rows.length; i < len; i++) {
1401
- row = rows[i];
1402
- if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
1403
- canvas.fillText(charData.char, charData.x, row.y);
1404
- });
1405
- }
1406
- if (decorationY) {
1407
- const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
1408
- if (decorationColor) canvas.fillStyle = decorationColor;
1409
- rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
1410
- }
1411
- }
1412
-
1413
- function fill(fill, ui, canvas) {
1397
+ function fill(fill, ui, canvas, renderOptions) {
1414
1398
  canvas.fillStyle = fill;
1415
- fillPathOrText(ui, canvas);
1399
+ fillPathOrText(ui, canvas, renderOptions);
1416
1400
  }
1417
1401
 
1418
- function fills(fills, ui, canvas) {
1419
- let item;
1402
+ function fills(fills, ui, canvas, renderOptions) {
1403
+ let item, originPaint, countImage;
1420
1404
  for (let i = 0, len = fills.length; i < len; i++) {
1421
- item = fills[i];
1405
+ item = fills[i], originPaint = item.originPaint;
1422
1406
  if (item.image) {
1423
- if (draw.PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
1407
+ countImage ? countImage++ : countImage = 1;
1408
+ if (draw.PaintImage.checkImage(item, !ui.__.__font, ui, canvas, renderOptions)) continue;
1424
1409
  if (!item.style) {
1425
- if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
1410
+ if (countImage === 1 && item.image.isPlacehold) ui.drawImagePlaceholder(item, canvas, renderOptions);
1426
1411
  continue;
1427
1412
  }
1428
1413
  }
1429
1414
  canvas.fillStyle = item.style;
1430
- if (item.transform || item.scaleFixed) {
1415
+ if (item.transform || originPaint.scaleFixed) {
1431
1416
  canvas.save();
1432
1417
  if (item.transform) canvas.transform(item.transform);
1433
- if (item.scaleFixed) {
1418
+ if (originPaint.scaleFixed) {
1434
1419
  const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
1435
- if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
1420
+ if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
1436
1421
  }
1437
- if (item.blendMode) canvas.blendMode = item.blendMode;
1438
- fillPathOrText(ui, canvas);
1422
+ if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
1423
+ fillPathOrText(ui, canvas, renderOptions);
1439
1424
  canvas.restore();
1440
1425
  } else {
1441
- if (item.blendMode) {
1442
- canvas.saveBlendMode(item.blendMode);
1443
- fillPathOrText(ui, canvas);
1426
+ if (originPaint.blendMode) {
1427
+ canvas.saveBlendMode(originPaint.blendMode);
1428
+ fillPathOrText(ui, canvas, renderOptions);
1444
1429
  canvas.restoreBlendMode();
1445
- } else fillPathOrText(ui, canvas);
1430
+ } else fillPathOrText(ui, canvas, renderOptions);
1446
1431
  }
1447
1432
  }
1448
1433
  }
1449
1434
 
1450
- function fillPathOrText(ui, canvas) {
1451
- ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
1435
+ function fillPathOrText(ui, canvas, renderOptions) {
1436
+ ui.__.__font ? draw.Paint.fillText(ui, canvas, renderOptions) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
1452
1437
  }
1453
1438
 
1454
- function strokeText(stroke, ui, canvas) {
1439
+ function fillText(ui, canvas, _renderOptions) {
1440
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
1441
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
1442
+ let row;
1443
+ for (let i = 0, len = rows.length; i < len; i++) {
1444
+ row = rows[i];
1445
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
1446
+ canvas.fillText(charData.char, charData.x, row.y);
1447
+ });
1448
+ }
1449
+ if (decorationY) {
1450
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
1451
+ if (decorationColor) canvas.fillStyle = decorationColor;
1452
+ rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
1453
+ }
1454
+ }
1455
+
1456
+ function stroke(stroke, ui, canvas, renderOptions) {
1457
+ const data = ui.__;
1458
+ if (!data.__strokeWidth) return;
1459
+ if (data.__font) {
1460
+ draw.Paint.strokeText(stroke, ui, canvas, renderOptions);
1461
+ } else {
1462
+ switch (data.strokeAlign) {
1463
+ case "center":
1464
+ drawCenter$1(stroke, 1, ui, canvas, renderOptions);
1465
+ break;
1466
+
1467
+ case "inside":
1468
+ drawInside(stroke, ui, canvas, renderOptions);
1469
+ break;
1470
+
1471
+ case "outside":
1472
+ drawOutside(stroke, ui, canvas, renderOptions);
1473
+ break;
1474
+ }
1475
+ }
1476
+ }
1477
+
1478
+ function strokes(strokes, ui, canvas, renderOptions) {
1479
+ draw.Paint.stroke(strokes, ui, canvas, renderOptions);
1480
+ }
1481
+
1482
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas, renderOptions) {
1483
+ const data = ui.__;
1484
+ if (core.isObject(stroke)) {
1485
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas, renderOptions);
1486
+ } else {
1487
+ canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1488
+ canvas.stroke();
1489
+ }
1490
+ if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas, renderOptions);
1491
+ }
1492
+
1493
+ function drawInside(stroke, ui, canvas, renderOptions) {
1494
+ canvas.save();
1495
+ canvas.clipUI(ui);
1496
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
1497
+ canvas.restore();
1498
+ }
1499
+
1500
+ function drawOutside(stroke, ui, canvas, renderOptions) {
1501
+ const data = ui.__;
1502
+ if (data.__fillAfterStroke) {
1503
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
1504
+ } else {
1505
+ const {renderBounds: renderBounds} = ui.__layout;
1506
+ const out = canvas.getSameCanvas(true, true);
1507
+ ui.__drawRenderPath(out);
1508
+ drawCenter$1(stroke, 2, ui, out, renderOptions);
1509
+ out.clipUI(data);
1510
+ out.clearWorld(renderBounds);
1511
+ core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1512
+ out.recycle(ui.__nowWorld);
1513
+ }
1514
+ }
1515
+
1516
+ function strokeText(stroke, ui, canvas, renderOptions) {
1455
1517
  switch (ui.__.strokeAlign) {
1456
1518
  case "center":
1457
- drawCenter$1(stroke, 1, ui, canvas);
1519
+ drawCenter(stroke, 1, ui, canvas, renderOptions);
1458
1520
  break;
1459
1521
 
1460
1522
  case "inside":
1461
- drawAlign(stroke, "inside", ui, canvas);
1523
+ drawAlign(stroke, "inside", ui, canvas, renderOptions);
1462
1524
  break;
1463
1525
 
1464
1526
  case "outside":
1465
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
1527
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas, renderOptions) : drawAlign(stroke, "outside", ui, canvas, renderOptions);
1466
1528
  break;
1467
1529
  }
1468
1530
  }
1469
1531
 
1470
- function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
1532
+ function drawCenter(stroke, strokeWidthScale, ui, canvas, renderOptions) {
1471
1533
  const data = ui.__;
1472
1534
  if (core.isObject(stroke)) {
1473
- drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
1535
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas, renderOptions);
1474
1536
  } else {
1475
1537
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1476
- drawTextStroke(ui, canvas);
1538
+ draw.Paint.drawTextStroke(ui, canvas, renderOptions);
1477
1539
  }
1478
1540
  }
1479
1541
 
1480
- function drawAlign(stroke, align, ui, canvas) {
1542
+ function drawAlign(stroke, align, ui, canvas, renderOptions) {
1481
1543
  const out = canvas.getSameCanvas(true, true);
1482
1544
  out.font = ui.__.__font;
1483
- drawCenter$1(stroke, 2, ui, out);
1545
+ drawCenter(stroke, 2, ui, out, renderOptions);
1484
1546
  out.blendMode = align === "outside" ? "destination-out" : "destination-in";
1485
- fillText(ui, out);
1547
+ draw.Paint.fillText(ui, out, renderOptions);
1486
1548
  out.blendMode = "normal";
1487
1549
  core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1488
1550
  out.recycle(ui.__nowWorld);
1489
1551
  }
1490
1552
 
1491
- function drawTextStroke(ui, canvas) {
1553
+ function drawTextStroke(ui, canvas, _renderOptions) {
1492
1554
  let row, data = ui.__.__textDrawData;
1493
1555
  const {rows: rows, decorationY: decorationY} = data;
1494
1556
  for (let i = 0, len = rows.length; i < len; i++) {
@@ -1503,89 +1565,29 @@ function drawTextStroke(ui, canvas) {
1503
1565
  }
1504
1566
  }
1505
1567
 
1506
- function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
1568
+ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas, renderOptions) {
1507
1569
  let item;
1508
1570
  const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
1509
1571
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
1510
1572
  for (let i = 0, len = strokes.length; i < len; i++) {
1511
1573
  item = strokes[i];
1512
- if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false)) continue;
1574
+ if (item.image && draw.PaintImage.checkImage(item, false, ui, canvas, renderOptions)) continue;
1513
1575
  if (item.style) {
1514
1576
  if (__hasMultiStrokeStyle) {
1515
1577
  const {strokeStyle: strokeStyle} = item;
1516
1578
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
1517
1579
  } else canvas.strokeStyle = item.style;
1518
- if (item.blendMode) {
1519
- canvas.saveBlendMode(item.blendMode);
1520
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1580
+ if (item.originPaint.blendMode) {
1581
+ canvas.saveBlendMode(item.originPaint.blendMode);
1582
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1521
1583
  canvas.restoreBlendMode();
1522
1584
  } else {
1523
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1585
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1524
1586
  }
1525
1587
  }
1526
1588
  }
1527
1589
  }
1528
1590
 
1529
- function stroke(stroke, ui, canvas) {
1530
- const data = ui.__;
1531
- if (!data.__strokeWidth) return;
1532
- if (data.__font) {
1533
- strokeText(stroke, ui, canvas);
1534
- } else {
1535
- switch (data.strokeAlign) {
1536
- case "center":
1537
- drawCenter(stroke, 1, ui, canvas);
1538
- break;
1539
-
1540
- case "inside":
1541
- drawInside(stroke, ui, canvas);
1542
- break;
1543
-
1544
- case "outside":
1545
- drawOutside(stroke, ui, canvas);
1546
- break;
1547
- }
1548
- }
1549
- }
1550
-
1551
- function strokes(strokes, ui, canvas) {
1552
- stroke(strokes, ui, canvas);
1553
- }
1554
-
1555
- function drawCenter(stroke, strokeWidthScale, ui, canvas) {
1556
- const data = ui.__;
1557
- if (core.isObject(stroke)) {
1558
- drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
1559
- } else {
1560
- canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1561
- canvas.stroke();
1562
- }
1563
- if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas);
1564
- }
1565
-
1566
- function drawInside(stroke, ui, canvas) {
1567
- canvas.save();
1568
- canvas.clipUI(ui);
1569
- drawCenter(stroke, 2, ui, canvas);
1570
- canvas.restore();
1571
- }
1572
-
1573
- function drawOutside(stroke, ui, canvas) {
1574
- const data = ui.__;
1575
- if (data.__fillAfterStroke) {
1576
- drawCenter(stroke, 2, ui, canvas);
1577
- } else {
1578
- const {renderBounds: renderBounds} = ui.__layout;
1579
- const out = canvas.getSameCanvas(true, true);
1580
- ui.__drawRenderPath(out);
1581
- drawCenter(stroke, 2, ui, out);
1582
- out.clipUI(data);
1583
- out.clearWorld(renderBounds);
1584
- core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1585
- out.recycle(ui.__nowWorld);
1586
- }
1587
- }
1588
-
1589
1591
  const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
1590
1592
 
1591
1593
  const tempBounds$1 = {};
@@ -1673,62 +1675,63 @@ function compute(attrName, ui) {
1673
1675
  if (leafPaints.some(item => item.image)) isAlphaPixel = true;
1674
1676
  isTransparent = true;
1675
1677
  }
1676
- }
1677
- if (attrName === "fill") {
1678
- stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1679
- stintSet(data, "__isTransparentFill", isTransparent);
1678
+ if (attrName === "fill") {
1679
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1680
+ stintSet(data, "__isTransparentFill", isTransparent);
1681
+ } else {
1682
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1683
+ stintSet(data, "__isTransparentStroke", isTransparent);
1684
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1685
+ }
1680
1686
  } else {
1681
- stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1682
- stintSet(data, "__isTransparentStroke", isTransparent);
1683
- stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1687
+ data.__removePaint(attrName, false);
1684
1688
  }
1685
1689
  }
1686
1690
 
1687
1691
  function getLeafPaint(attrName, paint, ui) {
1688
1692
  if (!core.isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1689
- let data;
1693
+ let leafPaint;
1690
1694
  const {boxBounds: boxBounds} = ui.__layout;
1691
1695
  switch (paint.type) {
1692
1696
  case "image":
1693
- data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1697
+ leafPaint = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1694
1698
  break;
1695
1699
 
1696
1700
  case "linear":
1697
- data = draw.PaintGradient.linearGradient(paint, boxBounds);
1701
+ leafPaint = draw.PaintGradient.linearGradient(paint, boxBounds);
1698
1702
  break;
1699
1703
 
1700
1704
  case "radial":
1701
- data = draw.PaintGradient.radialGradient(paint, boxBounds);
1705
+ leafPaint = draw.PaintGradient.radialGradient(paint, boxBounds);
1702
1706
  break;
1703
1707
 
1704
1708
  case "angular":
1705
- data = draw.PaintGradient.conicGradient(paint, boxBounds);
1709
+ leafPaint = draw.PaintGradient.conicGradient(paint, boxBounds);
1706
1710
  break;
1707
1711
 
1708
1712
  case "solid":
1709
1713
  const {type: type, color: color, opacity: opacity} = paint;
1710
- data = {
1714
+ leafPaint = {
1711
1715
  type: type,
1712
1716
  style: draw.ColorConvert.string(color, opacity)
1713
1717
  };
1714
1718
  break;
1715
1719
 
1716
1720
  default:
1717
- if (!core.isUndefined(paint.r)) data = {
1721
+ if (!core.isUndefined(paint.r)) leafPaint = {
1718
1722
  type: "solid",
1719
1723
  style: draw.ColorConvert.string(paint)
1720
1724
  };
1721
1725
  }
1722
- if (data) {
1723
- if (core.isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
1726
+ if (leafPaint) {
1727
+ leafPaint.originPaint = paint;
1728
+ if (core.isString(leafPaint.style) && hasTransparent$1(leafPaint.style)) leafPaint.isTransparent = true;
1724
1729
  if (paint.style) {
1725
1730
  if (paint.style.strokeWidth === 0) return undefined;
1726
- data.strokeStyle = paint.style;
1731
+ leafPaint.strokeStyle = paint.style;
1727
1732
  }
1728
- if (paint.editing) data.editing = paint.editing;
1729
- if (paint.blendMode) data.blendMode = paint.blendMode;
1730
1733
  }
1731
- return data;
1734
+ return leafPaint;
1732
1735
  }
1733
1736
 
1734
1737
  const PaintModule = {
@@ -1741,88 +1744,118 @@ const PaintModule = {
1741
1744
  strokes: strokes,
1742
1745
  strokeText: strokeText,
1743
1746
  drawTextStroke: drawTextStroke,
1747
+ drawStrokesStyle: drawStrokesStyle,
1744
1748
  shape: shape
1745
1749
  };
1746
1750
 
1747
- let origin = {}, tempMatrix$1 = core.getMatrixData();
1751
+ let cache, box = new core.Bounds;
1748
1752
 
1749
- const {get: get$3, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1753
+ const {isSame: isSame} = core.BoundsHelper;
1750
1754
 
1751
- function stretchMode(data, box, scaleX, scaleY) {
1752
- const transform = get$3();
1753
- translate$1(transform, box.x, box.y);
1754
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1755
- data.transform = transform;
1755
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1756
+ let leafPaint, event;
1757
+ const image = core.ImageManager.get(paint);
1758
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1759
+ leafPaint = cache.leafPaint;
1760
+ } else {
1761
+ leafPaint = {
1762
+ type: paint.type,
1763
+ image: image
1764
+ };
1765
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1766
+ cache = image.use > 1 ? {
1767
+ leafPaint: leafPaint,
1768
+ paint: paint,
1769
+ boxBounds: box.set(boxBounds)
1770
+ } : null;
1771
+ }
1772
+ if (firstUse || image.loading) event = {
1773
+ image: image,
1774
+ attrName: attrName,
1775
+ attrValue: paint
1776
+ };
1777
+ if (image.ready) {
1778
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1779
+ if (firstUse) {
1780
+ onLoad(ui, event);
1781
+ onLoadSuccess(ui, event);
1782
+ }
1783
+ } else if (image.error) {
1784
+ if (firstUse) onLoadError(ui, event, image.error);
1785
+ } else {
1786
+ if (firstUse) {
1787
+ ignoreRender(ui, true);
1788
+ onLoad(ui, event);
1789
+ }
1790
+ leafPaint.loadId = image.load(() => {
1791
+ ignoreRender(ui, false);
1792
+ if (!ui.destroyed) {
1793
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1794
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1795
+ ui.forceUpdate("surface");
1796
+ }
1797
+ onLoadSuccess(ui, event);
1798
+ }
1799
+ leafPaint.loadId = undefined;
1800
+ }, error => {
1801
+ ignoreRender(ui, false);
1802
+ onLoadError(ui, event, error);
1803
+ leafPaint.loadId = undefined;
1804
+ });
1805
+ if (ui.placeholderColor) {
1806
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1807
+ if (!image.ready) {
1808
+ image.isPlacehold = true;
1809
+ ui.forceUpdate("surface");
1810
+ }
1811
+ }, ui.placeholderDelay);
1812
+ }
1813
+ }
1814
+ return leafPaint;
1756
1815
  }
1757
1816
 
1758
- function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1759
- const transform = get$3();
1760
- translate$1(transform, box.x + x, box.y + y);
1761
- scaleHelper(transform, scaleX, scaleY);
1762
- if (rotation) rotateOfOuter$1(transform, {
1763
- x: box.x + box.width / 2,
1764
- y: box.y + box.height / 2
1765
- }, rotation);
1766
- data.transform = transform;
1817
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1818
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1819
+ const data = ui.__;
1820
+ data.__naturalWidth = image.width / data.pixelRatio;
1821
+ data.__naturalHeight = image.height / data.pixelRatio;
1822
+ if (data.__autoSide) {
1823
+ ui.forceUpdate("width");
1824
+ if (ui.__proxyData) {
1825
+ ui.setProxyAttr("width", data.width);
1826
+ ui.setProxyAttr("height", data.height);
1827
+ }
1828
+ return false;
1829
+ }
1830
+ }
1831
+ if (!leafPaint.data) draw.PaintImage.createData(leafPaint, image, paint, boxBounds);
1832
+ return true;
1767
1833
  }
1768
1834
 
1769
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1770
- const transform = get$3();
1771
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1772
- if (clipScaleX) {
1773
- if (rotation || skew) {
1774
- set(tempMatrix$1);
1775
- scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1776
- multiplyParent(transform, tempMatrix$1);
1777
- } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1778
- }
1779
- data.transform = transform;
1835
+ function onLoad(ui, event) {
1836
+ emit(ui, core.ImageEvent.LOAD, event);
1780
1837
  }
1781
1838
 
1782
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1783
- const transform = get$3();
1784
- if (freeTransform) {
1785
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1786
- } else {
1787
- if (rotation) {
1788
- if (align === "center") {
1789
- rotateOfOuter$1(transform, {
1790
- x: width / 2,
1791
- y: height / 2
1792
- }, rotation);
1793
- } else {
1794
- rotate(transform, rotation);
1795
- switch (rotation) {
1796
- case 90:
1797
- translate$1(transform, height, 0);
1798
- break;
1839
+ function onLoadSuccess(ui, event) {
1840
+ emit(ui, core.ImageEvent.LOADED, event);
1841
+ }
1799
1842
 
1800
- case 180:
1801
- translate$1(transform, width, height);
1802
- break;
1843
+ function onLoadError(ui, event, error) {
1844
+ event.error = error;
1845
+ ui.forceUpdate("surface");
1846
+ emit(ui, core.ImageEvent.ERROR, event);
1847
+ }
1803
1848
 
1804
- case 270:
1805
- translate$1(transform, 0, width);
1806
- break;
1807
- }
1808
- }
1809
- }
1810
- origin.x = box.x + x;
1811
- origin.y = box.y + y;
1812
- translate$1(transform, origin.x, origin.y);
1813
- if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1814
- }
1815
- data.transform = transform;
1849
+ function emit(ui, type, data) {
1850
+ if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1816
1851
  }
1817
1852
 
1818
- function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1819
- if (rotation) rotate(transform, rotation);
1820
- if (skew) skewHelper(transform, skew.x, skew.y);
1821
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1822
- translate$1(transform, box.x + x, box.y + y);
1853
+ function ignoreRender(ui, value) {
1854
+ const {leafer: leafer} = ui;
1855
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1823
1856
  }
1824
1857
 
1825
- const {get: get$2, translate: translate} = core.MatrixHelper;
1858
+ const {get: get$3, translate: translate$1} = core.MatrixHelper;
1826
1859
 
1827
1860
  const tempBox = new core.Bounds;
1828
1861
 
@@ -1831,17 +1864,13 @@ const tempScaleData = {};
1831
1864
  const tempImage = {};
1832
1865
 
1833
1866
  function createData(leafPaint, image, paint, box) {
1834
- const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1835
- if (changeful) leafPaint.changeful = changeful;
1836
- if (sync) leafPaint.sync = sync;
1837
- if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1838
- leafPaint.data = getPatternData(paint, box, image);
1867
+ leafPaint.data = draw.PaintImage.getPatternData(paint, box, image);
1839
1868
  }
1840
1869
 
1841
1870
  function getPatternData(paint, box, image) {
1842
1871
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1843
1872
  if (paint.mode === "strench") paint.mode = "stretch";
1844
- let {width: width, height: height} = image;
1873
+ const {width: width, height: height} = image;
1845
1874
  const {opacity: opacity, mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, filters: filters} = paint;
1846
1875
  const sameBox = box.width === width && box.height === height;
1847
1876
  const data = {
@@ -1872,8 +1901,8 @@ function getPatternData(paint, box, image) {
1872
1901
  case "stretch":
1873
1902
  if (!sameBox) {
1874
1903
  scaleX = box.width / width, scaleY = box.height / height;
1875
- stretchMode(data, box, scaleX, scaleY);
1876
- }
1904
+ draw.PaintImage.stretchMode(data, box, scaleX, scaleY);
1905
+ } else if (scaleX) scaleX = scaleY = undefined;
1877
1906
  break;
1878
1907
 
1879
1908
  case "normal":
@@ -1881,13 +1910,13 @@ function getPatternData(paint, box, image) {
1881
1910
  if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1882
1911
  let clipScaleX, clipScaleY;
1883
1912
  if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1884
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1913
+ draw.PaintImage.clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1885
1914
  if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : clipScaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1886
1915
  }
1887
1916
  break;
1888
1917
 
1889
1918
  case "repeat":
1890
- if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1919
+ if (!sameBox || scaleX || rotation || skew) draw.PaintImage.repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1891
1920
  if (!repeat) data.repeat = "repeat";
1892
1921
  const count = core.isObject(repeat);
1893
1922
  if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
@@ -1896,18 +1925,16 @@ function getPatternData(paint, box, image) {
1896
1925
  case "fit":
1897
1926
  case "cover":
1898
1927
  default:
1899
- if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1928
+ if (scaleX) draw.PaintImage.fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1900
1929
  }
1901
1930
  if (!data.transform) {
1902
- if (box.x || box.y) translate(data.transform = get$2(), box.x, box.y);
1931
+ if (box.x || box.y) translate$1(data.transform = get$3(), box.x, box.y);
1903
1932
  }
1904
- data.width = width;
1905
- data.height = height;
1906
1933
  if (scaleX) {
1907
1934
  data.scaleX = scaleX;
1908
1935
  data.scaleY = scaleY;
1909
1936
  }
1910
- if (opacity) data.opacity = opacity;
1937
+ if (opacity && opacity < 1) data.opacity = opacity;
1911
1938
  if (filters) data.filters = filters;
1912
1939
  if (repeat) data.repeat = core.isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1913
1940
  return data;
@@ -1929,180 +1956,82 @@ function getGapValue(gap, size, totalSize, rows) {
1929
1956
  return gap === "auto" ? value < 0 ? 0 : value : value;
1930
1957
  }
1931
1958
 
1932
- let cache, box = new core.Bounds;
1933
-
1934
- const {isSame: isSame} = core.BoundsHelper;
1935
-
1936
- function image(ui, attrName, paint, boxBounds, firstUse) {
1937
- let leafPaint, event;
1938
- const image = core.ImageManager.get(paint);
1939
- if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1940
- leafPaint = cache.leafPaint;
1941
- } else {
1942
- leafPaint = {
1943
- type: paint.type,
1944
- image: image
1945
- };
1946
- if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1947
- cache = image.use > 1 ? {
1948
- leafPaint: leafPaint,
1949
- paint: paint,
1950
- boxBounds: box.set(boxBounds)
1951
- } : null;
1952
- }
1953
- if (firstUse || image.loading) event = {
1954
- image: image,
1955
- attrName: attrName,
1956
- attrValue: paint
1957
- };
1958
- if (image.ready) {
1959
- checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1960
- if (firstUse) {
1961
- onLoad(ui, event);
1962
- onLoadSuccess(ui, event);
1963
- }
1964
- } else if (image.error) {
1965
- if (firstUse) onLoadError(ui, event, image.error);
1966
- } else {
1967
- if (firstUse) {
1968
- ignoreRender(ui, true);
1969
- onLoad(ui, event);
1970
- }
1971
- leafPaint.loadId = image.load(() => {
1972
- ignoreRender(ui, false);
1973
- if (!ui.destroyed) {
1974
- if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1975
- if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1976
- ui.forceUpdate("surface");
1977
- }
1978
- onLoadSuccess(ui, event);
1979
- }
1980
- leafPaint.loadId = undefined;
1981
- }, error => {
1982
- ignoreRender(ui, false);
1983
- onLoadError(ui, event, error);
1984
- leafPaint.loadId = undefined;
1985
- });
1986
- if (ui.placeholderColor) {
1987
- if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1988
- if (!image.ready) {
1989
- image.isPlacehold = true;
1990
- ui.forceUpdate("surface");
1991
- }
1992
- }, ui.placeholderDelay);
1993
- }
1994
- }
1995
- return leafPaint;
1996
- }
1997
-
1998
- function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1999
- if (attrName === "fill" && !ui.__.__naturalWidth) {
2000
- const data = ui.__;
2001
- data.__naturalWidth = image.width / data.pixelRatio;
2002
- data.__naturalHeight = image.height / data.pixelRatio;
2003
- if (data.__autoSide) {
2004
- ui.forceUpdate("width");
2005
- if (ui.__proxyData) {
2006
- ui.setProxyAttr("width", data.width);
2007
- ui.setProxyAttr("height", data.height);
2008
- }
2009
- return false;
2010
- }
2011
- }
2012
- if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
2013
- return true;
2014
- }
2015
-
2016
- function onLoad(ui, event) {
2017
- emit(ui, core.ImageEvent.LOAD, event);
2018
- }
1959
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
2019
1960
 
2020
- function onLoadSuccess(ui, event) {
2021
- emit(ui, core.ImageEvent.LOADED, event);
2022
- }
1961
+ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
2023
1962
 
2024
- function onLoadError(ui, event, error) {
2025
- event.error = error;
2026
- ui.forceUpdate("surface");
2027
- emit(ui, core.ImageEvent.ERROR, event);
1963
+ function stretchMode(data, box, scaleX, scaleY) {
1964
+ const transform = get$2(), {x: x, y: y} = box;
1965
+ if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1966
+ scaleHelper(transform, scaleX, scaleY);
1967
+ data.transform = transform;
2028
1968
  }
2029
1969
 
2030
- function emit(ui, type, data) {
2031
- if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1970
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1971
+ const transform = get$2();
1972
+ translate(transform, box.x + x, box.y + y);
1973
+ scaleHelper(transform, scaleX, scaleY);
1974
+ if (rotation) rotateOfOuter$1(transform, {
1975
+ x: box.x + box.width / 2,
1976
+ y: box.y + box.height / 2
1977
+ }, rotation);
1978
+ data.transform = transform;
2032
1979
  }
2033
1980
 
2034
- function ignoreRender(ui, value) {
2035
- const {leafer: leafer} = ui;
2036
- if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1981
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1982
+ const transform = get$2();
1983
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1984
+ if (clipScaleX) {
1985
+ if (rotation || skew) {
1986
+ set(tempMatrix$1);
1987
+ scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1988
+ multiplyParent(transform, tempMatrix$1);
1989
+ } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1990
+ }
1991
+ data.transform = transform;
2037
1992
  }
2038
1993
 
2039
- const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1994
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1995
+ const transform = get$2();
1996
+ if (freeTransform) {
1997
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1998
+ } else {
1999
+ if (rotation) {
2000
+ if (align === "center") {
2001
+ rotateOfOuter$1(transform, {
2002
+ x: width / 2,
2003
+ y: height / 2
2004
+ }, rotation);
2005
+ } else {
2006
+ rotate(transform, rotation);
2007
+ switch (rotation) {
2008
+ case 90:
2009
+ translate(transform, height, 0);
2010
+ break;
2040
2011
 
2041
- const {floor: floor, ceil: ceil, max: max$1, abs: abs$1} = Math;
2012
+ case 180:
2013
+ translate(transform, width, height);
2014
+ break;
2042
2015
 
2043
- function createPattern(ui, paint, pixelRatio) {
2044
- let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
2045
- const id = scaleX + "-" + scaleY + "-" + pixelRatio;
2046
- if (paint.patternId !== id && !ui.destroyed) {
2047
- const {image: image, data: data} = paint;
2048
- let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
2049
- scaleX *= pixelRatio;
2050
- scaleY *= pixelRatio;
2051
- if (sx) {
2052
- sx = abs$1(sx);
2053
- sy = abs$1(sy);
2054
- imageMatrix = get$1();
2055
- copy$1(imageMatrix, transform);
2056
- scale(imageMatrix, 1 / sx, 1 / sy);
2057
- scaleX *= sx;
2058
- scaleY *= sy;
2059
- }
2060
- width *= scaleX;
2061
- height *= scaleY;
2062
- const size = width * height;
2063
- if (!repeat) {
2064
- if (size > core.Platform.image.maxCacheSize) return false;
2065
- }
2066
- let maxSize = core.Platform.image.maxPatternSize;
2067
- if (image.isSVG) {
2068
- const ws = width / image.width;
2069
- if (ws > 1) imageScale = ws / ceil(ws);
2070
- } else {
2071
- const imageSize = image.width * image.height;
2072
- if (maxSize > imageSize) maxSize = imageSize;
2073
- }
2074
- if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
2075
- if (imageScale) {
2076
- scaleX /= imageScale;
2077
- scaleY /= imageScale;
2078
- width /= imageScale;
2079
- height /= imageScale;
2080
- }
2081
- if (sx) {
2082
- scaleX /= sx;
2083
- scaleY /= sy;
2084
- }
2085
- const xGap = gap && gap.x * scaleX;
2086
- const yGap = gap && gap.y * scaleY;
2087
- if (transform || scaleX !== 1 || scaleY !== 1) {
2088
- const canvasWidth = width + (xGap || 0);
2089
- const canvasHeight = height + (yGap || 0);
2090
- scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
2091
- scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
2092
- if (!imageMatrix) {
2093
- imageMatrix = get$1();
2094
- if (transform) copy$1(imageMatrix, transform);
2016
+ case 270:
2017
+ translate(transform, 0, width);
2018
+ break;
2019
+ }
2095
2020
  }
2096
- scale(imageMatrix, 1 / scaleX, 1 / scaleY);
2097
2021
  }
2098
- const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
2099
- const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
2100
- paint.style = pattern;
2101
- paint.patternId = id;
2102
- return true;
2103
- } else {
2104
- return false;
2022
+ origin.x = box.x + x;
2023
+ origin.y = box.y + y;
2024
+ translate(transform, origin.x, origin.y);
2025
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
2105
2026
  }
2027
+ data.transform = transform;
2028
+ }
2029
+
2030
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
2031
+ if (rotation) rotate(transform, rotation);
2032
+ if (skew) skewHelper(transform, skew.x, skew.y);
2033
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
2034
+ translate(transform, box.x + x, box.y + y);
2106
2035
  }
2107
2036
 
2108
2037
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -2138,58 +2067,116 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
2138
2067
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2139
2068
  };
2140
2069
 
2141
- function checkImage(ui, canvas, paint, allowDraw) {
2142
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
2143
- const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
2144
- if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !draw.Export.running) {
2070
+ const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
2071
+
2072
+ const {getFloorScale: getFloorScale} = core.MathHelper, {abs: abs$1} = Math;
2073
+
2074
+ function createPatternTask(paint, ui, canvas, renderOptions) {
2075
+ if (!paint.patternTask) {
2076
+ paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
2077
+ paint.patternTask = null;
2078
+ if (canvas.bounds.hit(ui.__nowWorld)) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions);
2079
+ ui.forceUpdate("surface");
2080
+ }), 300);
2081
+ }
2082
+ }
2083
+
2084
+ function createPattern(paint, ui, canvas, renderOptions) {
2085
+ let {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
2086
+ if (paint.patternId !== id && !ui.destroyed) {
2087
+ if (!(core.Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
2088
+ const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = draw.PaintImage.getPatternFixScale(paint, scaleX, scaleY);
2089
+ let imageMatrix, xGap, yGap, {width: width, height: height} = image;
2090
+ if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
2091
+ width *= scaleX;
2092
+ height *= scaleY;
2093
+ if (gap) {
2094
+ xGap = gap.x * scaleX / abs$1(data.scaleX || 1);
2095
+ yGap = gap.y * scaleY / abs$1(data.scaleY || 1);
2096
+ }
2097
+ if (transform || scaleX !== 1 || scaleY !== 1) {
2098
+ scaleX *= getFloorScale(width + (xGap || 0));
2099
+ scaleY *= getFloorScale(height + (yGap || 0));
2100
+ imageMatrix = get$1();
2101
+ if (transform) copy$1(imageMatrix, transform);
2102
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
2103
+ }
2104
+ const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
2105
+ const pattern = image.getPattern(imageCanvas, data.repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
2106
+ paint.style = pattern;
2107
+ paint.patternId = id;
2108
+ }
2109
+ }
2110
+ }
2111
+
2112
+ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
2113
+ const {image: image} = paint;
2114
+ let fixScale, maxSize = core.Platform.image.maxPatternSize, imageSize = image.width * image.height;
2115
+ if (image.isSVG) {
2116
+ if (imageScaleX > 1) fixScale = Math.ceil(imageScaleX) / imageScaleX;
2117
+ } else {
2118
+ if (maxSize > imageSize) maxSize = imageSize;
2119
+ }
2120
+ if ((imageSize *= imageScaleX * imageScaleY) > maxSize) fixScale = Math.sqrt(maxSize / imageSize);
2121
+ return fixScale;
2122
+ }
2123
+
2124
+ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
2125
+ const {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
2126
+ const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting} = renderOptions;
2127
+ if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting) {
2145
2128
  return false;
2146
2129
  } else {
2147
- if (allowDraw) {
2130
+ if (drawImage) {
2148
2131
  if (data.repeat) {
2149
- allowDraw = false;
2150
- } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
2151
- let {width: width, height: height} = data;
2152
- width *= scaleX * pixelRatio;
2153
- height *= scaleY * pixelRatio;
2154
- if (data.scaleX) {
2155
- width *= data.scaleX;
2156
- height *= data.scaleY;
2157
- }
2158
- allowDraw = width * height > core.Platform.image.maxCacheSize;
2132
+ drawImage = false;
2133
+ } else if (!(originPaint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || exporting)) {
2134
+ drawImage = core.Platform.image.isLarge(image, scaleX, scaleY);
2159
2135
  }
2160
2136
  }
2161
- if (allowDraw) {
2137
+ if (drawImage) {
2162
2138
  if (ui.__.__isFastShadow) {
2163
2139
  canvas.fillStyle = paint.style || "#000";
2164
2140
  canvas.fill();
2165
2141
  }
2166
- drawImage(ui, canvas, paint, data);
2142
+ draw.PaintImage.drawImage(paint, scaleX, scaleY, ui, canvas, renderOptions);
2167
2143
  return true;
2168
2144
  } else {
2169
- if (!paint.style || paint.sync || draw.Export.running) {
2170
- createPattern(ui, paint, pixelRatio);
2171
- } else {
2172
- if (!paint.patternTask) {
2173
- paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
2174
- paint.patternTask = null;
2175
- if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
2176
- ui.forceUpdate("surface");
2177
- }), 300);
2178
- }
2179
- }
2145
+ if (!paint.style || originPaint.sync || exporting) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions); else draw.PaintImage.createPatternTask(paint, ui, canvas, renderOptions);
2180
2146
  return false;
2181
2147
  }
2182
2148
  }
2183
2149
  }
2184
2150
 
2185
- function drawImage(ui, canvas, paint, data) {
2186
- canvas.save();
2187
- canvas.clipUI(ui);
2188
- if (paint.blendMode) canvas.blendMode = paint.blendMode;
2189
- if (data.opacity) canvas.opacity *= data.opacity;
2190
- if (data.transform) canvas.transform(data.transform);
2191
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
2192
- canvas.restore();
2151
+ function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
2152
+ const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
2153
+ let {width: width, height: height} = image, clipUI;
2154
+ if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
2155
+ canvas.save();
2156
+ clipUI && canvas.clipUI(ui);
2157
+ blendMode && (canvas.blendMode = blendMode);
2158
+ opacity && (canvas.opacity *= opacity);
2159
+ transform && canvas.transform(transform);
2160
+ canvas.drawImage(view, 0, 0, width, height);
2161
+ canvas.restore();
2162
+ } else {
2163
+ if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
2164
+ canvas.drawImage(view, 0, 0, width, height);
2165
+ }
2166
+ }
2167
+
2168
+ function getImageRenderScaleData(paint, ui, canvas, _renderOptions) {
2169
+ const scaleData = ui.getRenderScaleData(true, paint.originPaint.scaleFixed), {data: data} = paint;
2170
+ if (canvas) {
2171
+ const {pixelRatio: pixelRatio} = canvas;
2172
+ scaleData.scaleX *= pixelRatio;
2173
+ scaleData.scaleY *= pixelRatio;
2174
+ }
2175
+ if (data && data.scaleX) {
2176
+ scaleData.scaleX *= Math.abs(data.scaleX);
2177
+ scaleData.scaleY *= Math.abs(data.scaleY);
2178
+ }
2179
+ return scaleData;
2193
2180
  }
2194
2181
 
2195
2182
  function recycleImage(attrName, data) {
@@ -2221,8 +2208,12 @@ function recycleImage(attrName, data) {
2221
2208
  const PaintImageModule = {
2222
2209
  image: image,
2223
2210
  checkImage: checkImage,
2224
- createPattern: createPattern,
2211
+ drawImage: drawImage,
2212
+ getImageRenderScaleData: getImageRenderScaleData,
2225
2213
  recycleImage: recycleImage,
2214
+ createPatternTask: createPatternTask,
2215
+ createPattern: createPattern,
2216
+ getPatternFixScale: getPatternFixScale,
2226
2217
  createData: createData,
2227
2218
  getPatternData: getPatternData,
2228
2219
  stretchMode: stretchMode,
@@ -2678,10 +2669,8 @@ function createRows(drawData, content, style) {
2678
2669
  bounds = drawData.bounds;
2679
2670
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
2680
2671
  const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
2681
- const {canvas: canvas} = core.Platform;
2682
- const {width: width, height: height} = bounds;
2683
- const charMode = width || height || __letterSpacing || textCase !== "none";
2684
- if (charMode) {
2672
+ const {canvas: canvas} = core.Platform, {width: width} = bounds;
2673
+ if (style.__isCharMode) {
2685
2674
  const wrap = style.textWrap !== "none";
2686
2675
  const breakAll = style.textWrap === "break";
2687
2676
  paraStart = true;
@@ -2810,12 +2799,19 @@ const TextMode = 2;
2810
2799
  function layoutChar(drawData, style, width, _height) {
2811
2800
  const {rows: rows} = drawData;
2812
2801
  const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
2813
- let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2802
+ const justifyLast = width && textAlign.includes("both");
2803
+ const justify = justifyLast || width && textAlign.includes("justify");
2804
+ const justifyLetter = justify && textAlign.includes("letter");
2805
+ let charX, remainingWidth, addWordWidth, addLetterWidth, indentWidth, mode, wordChar, wordsLength, isLastWord, canJustify;
2814
2806
  rows.forEach(row => {
2815
2807
  if (row.words) {
2816
2808
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2817
- addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2818
- mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2809
+ if (justify) {
2810
+ canJustify = !row.paraEnd || justifyLast;
2811
+ remainingWidth = width - row.width - indentWidth;
2812
+ if (justifyLetter) addLetterWidth = remainingWidth / (row.words.reduce((total, item) => total + item.data.length, 0) - 1); else addWordWidth = wordsLength > 1 ? remainingWidth / (wordsLength - 1) : 0;
2813
+ }
2814
+ mode = letterSpacing || row.isOverflow || justifyLetter ? CharMode : addWordWidth ? WordMode : TextMode;
2819
2815
  if (row.isOverflow && !letterSpacing) row.textMode = true;
2820
2816
  if (mode === TextMode) {
2821
2817
  row.x += indentWidth;
@@ -2833,11 +2829,15 @@ function layoutChar(drawData, style, width, _height) {
2833
2829
  charX = toWordChar(word.data, charX, wordChar);
2834
2830
  if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2835
2831
  } else {
2836
- charX = toChar(word.data, charX, row.data, row.isOverflow);
2832
+ charX = toChar(word.data, charX, row.data, row.isOverflow, canJustify && addLetterWidth);
2837
2833
  }
2838
- if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
2839
- charX += addWordWidth;
2840
- row.width += addWordWidth;
2834
+ if (canJustify) {
2835
+ isLastWord = index === wordsLength - 1;
2836
+ if (addWordWidth) {
2837
+ if (!isLastWord) charX += addWordWidth, row.width += addWordWidth;
2838
+ } else if (addLetterWidth) {
2839
+ row.width += addLetterWidth * (word.data.length - (isLastWord ? 1 : 0));
2840
+ }
2841
2841
  }
2842
2842
  });
2843
2843
  }
@@ -2863,13 +2863,14 @@ function toWordChar(data, charX, wordChar) {
2863
2863
  return charX;
2864
2864
  }
2865
2865
 
2866
- function toChar(data, charX, rowData, isOverflow) {
2866
+ function toChar(data, charX, rowData, isOverflow, addLetterWidth) {
2867
2867
  data.forEach(char => {
2868
2868
  if (isOverflow || char.char !== " ") {
2869
2869
  char.x = charX;
2870
2870
  rowData.push(char);
2871
2871
  }
2872
2872
  charX += char.width;
2873
+ addLetterWidth && (charX += addLetterWidth);
2873
2874
  });
2874
2875
  return charX;
2875
2876
  }
@@ -3011,10 +3012,10 @@ function getDrawData(content, style) {
3011
3012
  let x = 0, y = 0;
3012
3013
  let width = style.__getInput("width") || 0;
3013
3014
  let height = style.__getInput("height") || 0;
3014
- const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
3015
+ const {__padding: padding} = style;
3015
3016
  if (padding) {
3016
- if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
3017
- if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
3017
+ if (width) x = padding[left], width -= padding[right] + padding[left], !width && (width = .01); else if (!style.autoSizeAlign) x = padding[left];
3018
+ if (height) y = padding[top], height -= padding[top] + padding[bottom], !height && (height = .01); else if (!style.autoSizeAlign) y = padding[top];
3018
3019
  }
3019
3020
  const drawData = {
3020
3021
  bounds: {
@@ -3025,14 +3026,14 @@ function getDrawData(content, style) {
3025
3026
  },
3026
3027
  rows: [],
3027
3028
  paraNumber: 0,
3028
- font: core.Platform.canvas.font = __font
3029
+ font: core.Platform.canvas.font = style.__font
3029
3030
  };
3030
3031
  createRows(drawData, content, style);
3031
3032
  if (padding) padAutoText(padding, drawData, style, width, height);
3032
3033
  layoutText(drawData, style);
3033
- layoutChar(drawData, style, width);
3034
+ if (style.__isCharMode) layoutChar(drawData, style, width);
3034
3035
  if (drawData.overflow) clipText(drawData, style, x, width);
3035
- if (textDecoration !== "none") decorationText(drawData, style);
3036
+ if (style.textDecoration !== "none") decorationText(drawData, style);
3036
3037
  return drawData;
3037
3038
  }
3038
3039