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