@leafer-draw/worker 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.
@@ -1,10 +1,10 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, isObject, BoundsHelper, FourNumberHelper, Matrix, isUndefined, isString, getMatrixData, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4, isNumber } from "@leafer/core";
1
+ import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, isObject, BoundsHelper, FourNumberHelper, Matrix, isUndefined, isString, ImageEvent, MatrixHelper, MathHelper, AlignHelper, PointHelper, getMatrixData, AroundHelper, Direction4, isNumber } from "@leafer/core";
2
2
 
3
3
  export * from "@leafer/core";
4
4
 
5
5
  export { LeaferImage } from "@leafer/core";
6
6
 
7
- import { PaintImage, Paint, ColorConvert, PaintGradient, Export, Effect, Group, TextConvert } from "@leafer-ui/draw";
7
+ import { Paint, PaintImage, ColorConvert, PaintGradient, Effect, Group, TextConvert } from "@leafer-ui/draw";
8
8
 
9
9
  export * from "@leafer-ui/draw";
10
10
 
@@ -666,102 +666,163 @@ Platform.render = function(target, canvas, options) {
666
666
  if (options.topList.length) options.topList.forEach(item => item.__render(canvas, topOptions));
667
667
  };
668
668
 
669
- function fillText(ui, canvas) {
670
- const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
671
- if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
672
- let row;
673
- for (let i = 0, len = rows.length; i < len; i++) {
674
- row = rows[i];
675
- if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
676
- canvas.fillText(charData.char, charData.x, row.y);
677
- });
678
- }
679
- if (decorationY) {
680
- const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
681
- if (decorationColor) canvas.fillStyle = decorationColor;
682
- rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
683
- }
684
- }
685
-
686
- function fill(fill, ui, canvas) {
669
+ function fill(fill, ui, canvas, renderOptions) {
687
670
  canvas.fillStyle = fill;
688
- fillPathOrText(ui, canvas);
671
+ fillPathOrText(ui, canvas, renderOptions);
689
672
  }
690
673
 
691
- function fills(fills, ui, canvas) {
692
- let item;
674
+ function fills(fills, ui, canvas, renderOptions) {
675
+ let item, originPaint, countImage;
693
676
  for (let i = 0, len = fills.length; i < len; i++) {
694
- item = fills[i];
677
+ item = fills[i], originPaint = item.originPaint;
695
678
  if (item.image) {
696
- if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
679
+ countImage ? countImage++ : countImage = 1;
680
+ if (PaintImage.checkImage(item, !ui.__.__font, ui, canvas, renderOptions)) continue;
697
681
  if (!item.style) {
698
- if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
682
+ if (countImage === 1 && item.image.isPlacehold) ui.drawImagePlaceholder(item, canvas, renderOptions);
699
683
  continue;
700
684
  }
701
685
  }
702
686
  canvas.fillStyle = item.style;
703
- if (item.transform || item.scaleFixed) {
687
+ if (item.transform || originPaint.scaleFixed) {
704
688
  canvas.save();
705
689
  if (item.transform) canvas.transform(item.transform);
706
- if (item.scaleFixed) {
690
+ if (originPaint.scaleFixed) {
707
691
  const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
708
- if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
692
+ if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
709
693
  }
710
- if (item.blendMode) canvas.blendMode = item.blendMode;
711
- fillPathOrText(ui, canvas);
694
+ if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
695
+ fillPathOrText(ui, canvas, renderOptions);
712
696
  canvas.restore();
713
697
  } else {
714
- if (item.blendMode) {
715
- canvas.saveBlendMode(item.blendMode);
716
- fillPathOrText(ui, canvas);
698
+ if (originPaint.blendMode) {
699
+ canvas.saveBlendMode(originPaint.blendMode);
700
+ fillPathOrText(ui, canvas, renderOptions);
717
701
  canvas.restoreBlendMode();
718
- } else fillPathOrText(ui, canvas);
702
+ } else fillPathOrText(ui, canvas, renderOptions);
719
703
  }
720
704
  }
721
705
  }
722
706
 
723
- function fillPathOrText(ui, canvas) {
724
- ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
707
+ function fillPathOrText(ui, canvas, renderOptions) {
708
+ ui.__.__font ? Paint.fillText(ui, canvas, renderOptions) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
709
+ }
710
+
711
+ function fillText(ui, canvas, _renderOptions) {
712
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
713
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
714
+ let row;
715
+ for (let i = 0, len = rows.length; i < len; i++) {
716
+ row = rows[i];
717
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
718
+ canvas.fillText(charData.char, charData.x, row.y);
719
+ });
720
+ }
721
+ if (decorationY) {
722
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
723
+ if (decorationColor) canvas.fillStyle = decorationColor;
724
+ rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
725
+ }
726
+ }
727
+
728
+ function stroke(stroke, ui, canvas, renderOptions) {
729
+ const data = ui.__;
730
+ if (!data.__strokeWidth) return;
731
+ if (data.__font) {
732
+ Paint.strokeText(stroke, ui, canvas, renderOptions);
733
+ } else {
734
+ switch (data.strokeAlign) {
735
+ case "center":
736
+ drawCenter$1(stroke, 1, ui, canvas, renderOptions);
737
+ break;
738
+
739
+ case "inside":
740
+ drawInside(stroke, ui, canvas, renderOptions);
741
+ break;
742
+
743
+ case "outside":
744
+ drawOutside(stroke, ui, canvas, renderOptions);
745
+ break;
746
+ }
747
+ }
748
+ }
749
+
750
+ function strokes(strokes, ui, canvas, renderOptions) {
751
+ Paint.stroke(strokes, ui, canvas, renderOptions);
752
+ }
753
+
754
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas, renderOptions) {
755
+ const data = ui.__;
756
+ if (isObject(stroke)) {
757
+ Paint.drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas, renderOptions);
758
+ } else {
759
+ canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
760
+ canvas.stroke();
761
+ }
762
+ if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas, renderOptions);
763
+ }
764
+
765
+ function drawInside(stroke, ui, canvas, renderOptions) {
766
+ canvas.save();
767
+ canvas.clipUI(ui);
768
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
769
+ canvas.restore();
770
+ }
771
+
772
+ function drawOutside(stroke, ui, canvas, renderOptions) {
773
+ const data = ui.__;
774
+ if (data.__fillAfterStroke) {
775
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
776
+ } else {
777
+ const {renderBounds: renderBounds} = ui.__layout;
778
+ const out = canvas.getSameCanvas(true, true);
779
+ ui.__drawRenderPath(out);
780
+ drawCenter$1(stroke, 2, ui, out, renderOptions);
781
+ out.clipUI(data);
782
+ out.clearWorld(renderBounds);
783
+ LeafHelper.copyCanvasByWorld(ui, canvas, out);
784
+ out.recycle(ui.__nowWorld);
785
+ }
725
786
  }
726
787
 
727
- function strokeText(stroke, ui, canvas) {
788
+ function strokeText(stroke, ui, canvas, renderOptions) {
728
789
  switch (ui.__.strokeAlign) {
729
790
  case "center":
730
- drawCenter$1(stroke, 1, ui, canvas);
791
+ drawCenter(stroke, 1, ui, canvas, renderOptions);
731
792
  break;
732
793
 
733
794
  case "inside":
734
- drawAlign(stroke, "inside", ui, canvas);
795
+ drawAlign(stroke, "inside", ui, canvas, renderOptions);
735
796
  break;
736
797
 
737
798
  case "outside":
738
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
799
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas, renderOptions) : drawAlign(stroke, "outside", ui, canvas, renderOptions);
739
800
  break;
740
801
  }
741
802
  }
742
803
 
743
- function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
804
+ function drawCenter(stroke, strokeWidthScale, ui, canvas, renderOptions) {
744
805
  const data = ui.__;
745
806
  if (isObject(stroke)) {
746
- drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
807
+ Paint.drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas, renderOptions);
747
808
  } else {
748
809
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
749
- drawTextStroke(ui, canvas);
810
+ Paint.drawTextStroke(ui, canvas, renderOptions);
750
811
  }
751
812
  }
752
813
 
753
- function drawAlign(stroke, align, ui, canvas) {
814
+ function drawAlign(stroke, align, ui, canvas, renderOptions) {
754
815
  const out = canvas.getSameCanvas(true, true);
755
816
  out.font = ui.__.__font;
756
- drawCenter$1(stroke, 2, ui, out);
817
+ drawCenter(stroke, 2, ui, out, renderOptions);
757
818
  out.blendMode = align === "outside" ? "destination-out" : "destination-in";
758
- fillText(ui, out);
819
+ Paint.fillText(ui, out, renderOptions);
759
820
  out.blendMode = "normal";
760
821
  LeafHelper.copyCanvasByWorld(ui, canvas, out);
761
822
  out.recycle(ui.__nowWorld);
762
823
  }
763
824
 
764
- function drawTextStroke(ui, canvas) {
825
+ function drawTextStroke(ui, canvas, _renderOptions) {
765
826
  let row, data = ui.__.__textDrawData;
766
827
  const {rows: rows, decorationY: decorationY} = data;
767
828
  for (let i = 0, len = rows.length; i < len; i++) {
@@ -776,89 +837,29 @@ function drawTextStroke(ui, canvas) {
776
837
  }
777
838
  }
778
839
 
779
- function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
840
+ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas, renderOptions) {
780
841
  let item;
781
842
  const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
782
843
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
783
844
  for (let i = 0, len = strokes.length; i < len; i++) {
784
845
  item = strokes[i];
785
- if (item.image && PaintImage.checkImage(ui, canvas, item, false)) continue;
846
+ if (item.image && PaintImage.checkImage(item, false, ui, canvas, renderOptions)) continue;
786
847
  if (item.style) {
787
848
  if (__hasMultiStrokeStyle) {
788
849
  const {strokeStyle: strokeStyle} = item;
789
850
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
790
851
  } else canvas.strokeStyle = item.style;
791
- if (item.blendMode) {
792
- canvas.saveBlendMode(item.blendMode);
793
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
852
+ if (item.originPaint.blendMode) {
853
+ canvas.saveBlendMode(item.originPaint.blendMode);
854
+ isText ? Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
794
855
  canvas.restoreBlendMode();
795
856
  } else {
796
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
857
+ isText ? Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
797
858
  }
798
859
  }
799
860
  }
800
861
  }
801
862
 
802
- function stroke(stroke, ui, canvas) {
803
- const data = ui.__;
804
- if (!data.__strokeWidth) return;
805
- if (data.__font) {
806
- strokeText(stroke, ui, canvas);
807
- } else {
808
- switch (data.strokeAlign) {
809
- case "center":
810
- drawCenter(stroke, 1, ui, canvas);
811
- break;
812
-
813
- case "inside":
814
- drawInside(stroke, ui, canvas);
815
- break;
816
-
817
- case "outside":
818
- drawOutside(stroke, ui, canvas);
819
- break;
820
- }
821
- }
822
- }
823
-
824
- function strokes(strokes, ui, canvas) {
825
- stroke(strokes, ui, canvas);
826
- }
827
-
828
- function drawCenter(stroke, strokeWidthScale, ui, canvas) {
829
- const data = ui.__;
830
- if (isObject(stroke)) {
831
- drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
832
- } else {
833
- canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
834
- canvas.stroke();
835
- }
836
- if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas);
837
- }
838
-
839
- function drawInside(stroke, ui, canvas) {
840
- canvas.save();
841
- canvas.clipUI(ui);
842
- drawCenter(stroke, 2, ui, canvas);
843
- canvas.restore();
844
- }
845
-
846
- function drawOutside(stroke, ui, canvas) {
847
- const data = ui.__;
848
- if (data.__fillAfterStroke) {
849
- drawCenter(stroke, 2, ui, canvas);
850
- } else {
851
- const {renderBounds: renderBounds} = ui.__layout;
852
- const out = canvas.getSameCanvas(true, true);
853
- ui.__drawRenderPath(out);
854
- drawCenter(stroke, 2, ui, out);
855
- out.clipUI(data);
856
- out.clearWorld(renderBounds);
857
- LeafHelper.copyCanvasByWorld(ui, canvas, out);
858
- out.recycle(ui.__nowWorld);
859
- }
860
- }
861
-
862
863
  const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = BoundsHelper;
863
864
 
864
865
  const tempBounds$1 = {};
@@ -946,62 +947,63 @@ function compute(attrName, ui) {
946
947
  if (leafPaints.some(item => item.image)) isAlphaPixel = true;
947
948
  isTransparent = true;
948
949
  }
949
- }
950
- if (attrName === "fill") {
951
- stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
952
- stintSet(data, "__isTransparentFill", isTransparent);
950
+ if (attrName === "fill") {
951
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
952
+ stintSet(data, "__isTransparentFill", isTransparent);
953
+ } else {
954
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
955
+ stintSet(data, "__isTransparentStroke", isTransparent);
956
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
957
+ }
953
958
  } else {
954
- stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
955
- stintSet(data, "__isTransparentStroke", isTransparent);
956
- stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
959
+ data.__removePaint(attrName, false);
957
960
  }
958
961
  }
959
962
 
960
963
  function getLeafPaint(attrName, paint, ui) {
961
964
  if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
962
- let data;
965
+ let leafPaint;
963
966
  const {boxBounds: boxBounds} = ui.__layout;
964
967
  switch (paint.type) {
965
968
  case "image":
966
- data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
969
+ leafPaint = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
967
970
  break;
968
971
 
969
972
  case "linear":
970
- data = PaintGradient.linearGradient(paint, boxBounds);
973
+ leafPaint = PaintGradient.linearGradient(paint, boxBounds);
971
974
  break;
972
975
 
973
976
  case "radial":
974
- data = PaintGradient.radialGradient(paint, boxBounds);
977
+ leafPaint = PaintGradient.radialGradient(paint, boxBounds);
975
978
  break;
976
979
 
977
980
  case "angular":
978
- data = PaintGradient.conicGradient(paint, boxBounds);
981
+ leafPaint = PaintGradient.conicGradient(paint, boxBounds);
979
982
  break;
980
983
 
981
984
  case "solid":
982
985
  const {type: type, color: color, opacity: opacity} = paint;
983
- data = {
986
+ leafPaint = {
984
987
  type: type,
985
988
  style: ColorConvert.string(color, opacity)
986
989
  };
987
990
  break;
988
991
 
989
992
  default:
990
- if (!isUndefined(paint.r)) data = {
993
+ if (!isUndefined(paint.r)) leafPaint = {
991
994
  type: "solid",
992
995
  style: ColorConvert.string(paint)
993
996
  };
994
997
  }
995
- if (data) {
996
- if (isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
998
+ if (leafPaint) {
999
+ leafPaint.originPaint = paint;
1000
+ if (isString(leafPaint.style) && hasTransparent$1(leafPaint.style)) leafPaint.isTransparent = true;
997
1001
  if (paint.style) {
998
1002
  if (paint.style.strokeWidth === 0) return undefined;
999
- data.strokeStyle = paint.style;
1003
+ leafPaint.strokeStyle = paint.style;
1000
1004
  }
1001
- if (paint.editing) data.editing = paint.editing;
1002
- if (paint.blendMode) data.blendMode = paint.blendMode;
1003
1005
  }
1004
- return data;
1006
+ return leafPaint;
1005
1007
  }
1006
1008
 
1007
1009
  const PaintModule = {
@@ -1014,88 +1016,118 @@ const PaintModule = {
1014
1016
  strokes: strokes,
1015
1017
  strokeText: strokeText,
1016
1018
  drawTextStroke: drawTextStroke,
1019
+ drawStrokesStyle: drawStrokesStyle,
1017
1020
  shape: shape
1018
1021
  };
1019
1022
 
1020
- let origin = {}, tempMatrix$1 = getMatrixData();
1023
+ let cache, box = new Bounds;
1021
1024
 
1022
- const {get: get$3, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
1025
+ const {isSame: isSame} = BoundsHelper;
1023
1026
 
1024
- function stretchMode(data, box, scaleX, scaleY) {
1025
- const transform = get$3();
1026
- translate$1(transform, box.x, box.y);
1027
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1028
- data.transform = transform;
1027
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1028
+ let leafPaint, event;
1029
+ const image = ImageManager.get(paint);
1030
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1031
+ leafPaint = cache.leafPaint;
1032
+ } else {
1033
+ leafPaint = {
1034
+ type: paint.type,
1035
+ image: image
1036
+ };
1037
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1038
+ cache = image.use > 1 ? {
1039
+ leafPaint: leafPaint,
1040
+ paint: paint,
1041
+ boxBounds: box.set(boxBounds)
1042
+ } : null;
1043
+ }
1044
+ if (firstUse || image.loading) event = {
1045
+ image: image,
1046
+ attrName: attrName,
1047
+ attrValue: paint
1048
+ };
1049
+ if (image.ready) {
1050
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1051
+ if (firstUse) {
1052
+ onLoad(ui, event);
1053
+ onLoadSuccess(ui, event);
1054
+ }
1055
+ } else if (image.error) {
1056
+ if (firstUse) onLoadError(ui, event, image.error);
1057
+ } else {
1058
+ if (firstUse) {
1059
+ ignoreRender(ui, true);
1060
+ onLoad(ui, event);
1061
+ }
1062
+ leafPaint.loadId = image.load(() => {
1063
+ ignoreRender(ui, false);
1064
+ if (!ui.destroyed) {
1065
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1066
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1067
+ ui.forceUpdate("surface");
1068
+ }
1069
+ onLoadSuccess(ui, event);
1070
+ }
1071
+ leafPaint.loadId = undefined;
1072
+ }, error => {
1073
+ ignoreRender(ui, false);
1074
+ onLoadError(ui, event, error);
1075
+ leafPaint.loadId = undefined;
1076
+ });
1077
+ if (ui.placeholderColor) {
1078
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1079
+ if (!image.ready) {
1080
+ image.isPlacehold = true;
1081
+ ui.forceUpdate("surface");
1082
+ }
1083
+ }, ui.placeholderDelay);
1084
+ }
1085
+ }
1086
+ return leafPaint;
1029
1087
  }
1030
1088
 
1031
- function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1032
- const transform = get$3();
1033
- translate$1(transform, box.x + x, box.y + y);
1034
- scaleHelper(transform, scaleX, scaleY);
1035
- if (rotation) rotateOfOuter$1(transform, {
1036
- x: box.x + box.width / 2,
1037
- y: box.y + box.height / 2
1038
- }, rotation);
1039
- data.transform = transform;
1089
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1090
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1091
+ const data = ui.__;
1092
+ data.__naturalWidth = image.width / data.pixelRatio;
1093
+ data.__naturalHeight = image.height / data.pixelRatio;
1094
+ if (data.__autoSide) {
1095
+ ui.forceUpdate("width");
1096
+ if (ui.__proxyData) {
1097
+ ui.setProxyAttr("width", data.width);
1098
+ ui.setProxyAttr("height", data.height);
1099
+ }
1100
+ return false;
1101
+ }
1102
+ }
1103
+ if (!leafPaint.data) PaintImage.createData(leafPaint, image, paint, boxBounds);
1104
+ return true;
1040
1105
  }
1041
1106
 
1042
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1043
- const transform = get$3();
1044
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1045
- if (clipScaleX) {
1046
- if (rotation || skew) {
1047
- set(tempMatrix$1);
1048
- scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1049
- multiplyParent(transform, tempMatrix$1);
1050
- } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1051
- }
1052
- data.transform = transform;
1107
+ function onLoad(ui, event) {
1108
+ emit(ui, ImageEvent.LOAD, event);
1053
1109
  }
1054
1110
 
1055
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1056
- const transform = get$3();
1057
- if (freeTransform) {
1058
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1059
- } else {
1060
- if (rotation) {
1061
- if (align === "center") {
1062
- rotateOfOuter$1(transform, {
1063
- x: width / 2,
1064
- y: height / 2
1065
- }, rotation);
1066
- } else {
1067
- rotate(transform, rotation);
1068
- switch (rotation) {
1069
- case 90:
1070
- translate$1(transform, height, 0);
1071
- break;
1111
+ function onLoadSuccess(ui, event) {
1112
+ emit(ui, ImageEvent.LOADED, event);
1113
+ }
1072
1114
 
1073
- case 180:
1074
- translate$1(transform, width, height);
1075
- break;
1115
+ function onLoadError(ui, event, error) {
1116
+ event.error = error;
1117
+ ui.forceUpdate("surface");
1118
+ emit(ui, ImageEvent.ERROR, event);
1119
+ }
1076
1120
 
1077
- case 270:
1078
- translate$1(transform, 0, width);
1079
- break;
1080
- }
1081
- }
1082
- }
1083
- origin.x = box.x + x;
1084
- origin.y = box.y + y;
1085
- translate$1(transform, origin.x, origin.y);
1086
- if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1087
- }
1088
- data.transform = transform;
1121
+ function emit(ui, type, data) {
1122
+ if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1089
1123
  }
1090
1124
 
1091
- function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1092
- if (rotation) rotate(transform, rotation);
1093
- if (skew) skewHelper(transform, skew.x, skew.y);
1094
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1095
- translate$1(transform, box.x + x, box.y + y);
1125
+ function ignoreRender(ui, value) {
1126
+ const {leafer: leafer} = ui;
1127
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1096
1128
  }
1097
1129
 
1098
- const {get: get$2, translate: translate} = MatrixHelper;
1130
+ const {get: get$3, translate: translate$1} = MatrixHelper;
1099
1131
 
1100
1132
  const tempBox = new Bounds;
1101
1133
 
@@ -1104,17 +1136,13 @@ const tempScaleData = {};
1104
1136
  const tempImage = {};
1105
1137
 
1106
1138
  function createData(leafPaint, image, paint, box) {
1107
- const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1108
- if (changeful) leafPaint.changeful = changeful;
1109
- if (sync) leafPaint.sync = sync;
1110
- if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1111
- leafPaint.data = getPatternData(paint, box, image);
1139
+ leafPaint.data = PaintImage.getPatternData(paint, box, image);
1112
1140
  }
1113
1141
 
1114
1142
  function getPatternData(paint, box, image) {
1115
1143
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1116
1144
  if (paint.mode === "strench") paint.mode = "stretch";
1117
- let {width: width, height: height} = image;
1145
+ const {width: width, height: height} = image;
1118
1146
  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;
1119
1147
  const sameBox = box.width === width && box.height === height;
1120
1148
  const data = {
@@ -1145,8 +1173,8 @@ function getPatternData(paint, box, image) {
1145
1173
  case "stretch":
1146
1174
  if (!sameBox) {
1147
1175
  scaleX = box.width / width, scaleY = box.height / height;
1148
- stretchMode(data, box, scaleX, scaleY);
1149
- }
1176
+ PaintImage.stretchMode(data, box, scaleX, scaleY);
1177
+ } else if (scaleX) scaleX = scaleY = undefined;
1150
1178
  break;
1151
1179
 
1152
1180
  case "normal":
@@ -1154,13 +1182,13 @@ function getPatternData(paint, box, image) {
1154
1182
  if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1155
1183
  let clipScaleX, clipScaleY;
1156
1184
  if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1157
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1185
+ PaintImage.clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1158
1186
  if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : clipScaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1159
1187
  }
1160
1188
  break;
1161
1189
 
1162
1190
  case "repeat":
1163
- if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1191
+ if (!sameBox || scaleX || rotation || skew) PaintImage.repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1164
1192
  if (!repeat) data.repeat = "repeat";
1165
1193
  const count = isObject(repeat);
1166
1194
  if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
@@ -1169,18 +1197,16 @@ function getPatternData(paint, box, image) {
1169
1197
  case "fit":
1170
1198
  case "cover":
1171
1199
  default:
1172
- if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1200
+ if (scaleX) PaintImage.fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1173
1201
  }
1174
1202
  if (!data.transform) {
1175
- if (box.x || box.y) translate(data.transform = get$2(), box.x, box.y);
1203
+ if (box.x || box.y) translate$1(data.transform = get$3(), box.x, box.y);
1176
1204
  }
1177
- data.width = width;
1178
- data.height = height;
1179
1205
  if (scaleX) {
1180
1206
  data.scaleX = scaleX;
1181
1207
  data.scaleY = scaleY;
1182
1208
  }
1183
- if (opacity) data.opacity = opacity;
1209
+ if (opacity && opacity < 1) data.opacity = opacity;
1184
1210
  if (filters) data.filters = filters;
1185
1211
  if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1186
1212
  return data;
@@ -1202,180 +1228,82 @@ function getGapValue(gap, size, totalSize, rows) {
1202
1228
  return gap === "auto" ? value < 0 ? 0 : value : value;
1203
1229
  }
1204
1230
 
1205
- let cache, box = new Bounds;
1206
-
1207
- const {isSame: isSame} = BoundsHelper;
1208
-
1209
- function image(ui, attrName, paint, boxBounds, firstUse) {
1210
- let leafPaint, event;
1211
- const image = ImageManager.get(paint);
1212
- if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1213
- leafPaint = cache.leafPaint;
1214
- } else {
1215
- leafPaint = {
1216
- type: paint.type,
1217
- image: image
1218
- };
1219
- if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1220
- cache = image.use > 1 ? {
1221
- leafPaint: leafPaint,
1222
- paint: paint,
1223
- boxBounds: box.set(boxBounds)
1224
- } : null;
1225
- }
1226
- if (firstUse || image.loading) event = {
1227
- image: image,
1228
- attrName: attrName,
1229
- attrValue: paint
1230
- };
1231
- if (image.ready) {
1232
- checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1233
- if (firstUse) {
1234
- onLoad(ui, event);
1235
- onLoadSuccess(ui, event);
1236
- }
1237
- } else if (image.error) {
1238
- if (firstUse) onLoadError(ui, event, image.error);
1239
- } else {
1240
- if (firstUse) {
1241
- ignoreRender(ui, true);
1242
- onLoad(ui, event);
1243
- }
1244
- leafPaint.loadId = image.load(() => {
1245
- ignoreRender(ui, false);
1246
- if (!ui.destroyed) {
1247
- if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1248
- if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1249
- ui.forceUpdate("surface");
1250
- }
1251
- onLoadSuccess(ui, event);
1252
- }
1253
- leafPaint.loadId = undefined;
1254
- }, error => {
1255
- ignoreRender(ui, false);
1256
- onLoadError(ui, event, error);
1257
- leafPaint.loadId = undefined;
1258
- });
1259
- if (ui.placeholderColor) {
1260
- if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1261
- if (!image.ready) {
1262
- image.isPlacehold = true;
1263
- ui.forceUpdate("surface");
1264
- }
1265
- }, ui.placeholderDelay);
1266
- }
1267
- }
1268
- return leafPaint;
1269
- }
1270
-
1271
- function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1272
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1273
- const data = ui.__;
1274
- data.__naturalWidth = image.width / data.pixelRatio;
1275
- data.__naturalHeight = image.height / data.pixelRatio;
1276
- if (data.__autoSide) {
1277
- ui.forceUpdate("width");
1278
- if (ui.__proxyData) {
1279
- ui.setProxyAttr("width", data.width);
1280
- ui.setProxyAttr("height", data.height);
1281
- }
1282
- return false;
1283
- }
1284
- }
1285
- if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1286
- return true;
1287
- }
1288
-
1289
- function onLoad(ui, event) {
1290
- emit(ui, ImageEvent.LOAD, event);
1291
- }
1231
+ let origin = {}, tempMatrix$1 = getMatrixData();
1292
1232
 
1293
- function onLoadSuccess(ui, event) {
1294
- emit(ui, ImageEvent.LOADED, event);
1295
- }
1233
+ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
1296
1234
 
1297
- function onLoadError(ui, event, error) {
1298
- event.error = error;
1299
- ui.forceUpdate("surface");
1300
- emit(ui, ImageEvent.ERROR, event);
1235
+ function stretchMode(data, box, scaleX, scaleY) {
1236
+ const transform = get$2(), {x: x, y: y} = box;
1237
+ if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1238
+ scaleHelper(transform, scaleX, scaleY);
1239
+ data.transform = transform;
1301
1240
  }
1302
1241
 
1303
- function emit(ui, type, data) {
1304
- if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1242
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1243
+ const transform = get$2();
1244
+ translate(transform, box.x + x, box.y + y);
1245
+ scaleHelper(transform, scaleX, scaleY);
1246
+ if (rotation) rotateOfOuter$1(transform, {
1247
+ x: box.x + box.width / 2,
1248
+ y: box.y + box.height / 2
1249
+ }, rotation);
1250
+ data.transform = transform;
1305
1251
  }
1306
1252
 
1307
- function ignoreRender(ui, value) {
1308
- const {leafer: leafer} = ui;
1309
- if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1253
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1254
+ const transform = get$2();
1255
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1256
+ if (clipScaleX) {
1257
+ if (rotation || skew) {
1258
+ set(tempMatrix$1);
1259
+ scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1260
+ multiplyParent(transform, tempMatrix$1);
1261
+ } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1262
+ }
1263
+ data.transform = transform;
1310
1264
  }
1311
1265
 
1312
- const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1266
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1267
+ const transform = get$2();
1268
+ if (freeTransform) {
1269
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1270
+ } else {
1271
+ if (rotation) {
1272
+ if (align === "center") {
1273
+ rotateOfOuter$1(transform, {
1274
+ x: width / 2,
1275
+ y: height / 2
1276
+ }, rotation);
1277
+ } else {
1278
+ rotate(transform, rotation);
1279
+ switch (rotation) {
1280
+ case 90:
1281
+ translate(transform, height, 0);
1282
+ break;
1313
1283
 
1314
- const {floor: floor, ceil: ceil, max: max$1, abs: abs$1} = Math;
1284
+ case 180:
1285
+ translate(transform, width, height);
1286
+ break;
1315
1287
 
1316
- function createPattern(ui, paint, pixelRatio) {
1317
- let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1318
- const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1319
- if (paint.patternId !== id && !ui.destroyed) {
1320
- const {image: image, data: data} = paint;
1321
- let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1322
- scaleX *= pixelRatio;
1323
- scaleY *= pixelRatio;
1324
- if (sx) {
1325
- sx = abs$1(sx);
1326
- sy = abs$1(sy);
1327
- imageMatrix = get$1();
1328
- copy$1(imageMatrix, transform);
1329
- scale(imageMatrix, 1 / sx, 1 / sy);
1330
- scaleX *= sx;
1331
- scaleY *= sy;
1332
- }
1333
- width *= scaleX;
1334
- height *= scaleY;
1335
- const size = width * height;
1336
- if (!repeat) {
1337
- if (size > Platform.image.maxCacheSize) return false;
1338
- }
1339
- let maxSize = Platform.image.maxPatternSize;
1340
- if (image.isSVG) {
1341
- const ws = width / image.width;
1342
- if (ws > 1) imageScale = ws / ceil(ws);
1343
- } else {
1344
- const imageSize = image.width * image.height;
1345
- if (maxSize > imageSize) maxSize = imageSize;
1346
- }
1347
- if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1348
- if (imageScale) {
1349
- scaleX /= imageScale;
1350
- scaleY /= imageScale;
1351
- width /= imageScale;
1352
- height /= imageScale;
1353
- }
1354
- if (sx) {
1355
- scaleX /= sx;
1356
- scaleY /= sy;
1357
- }
1358
- const xGap = gap && gap.x * scaleX;
1359
- const yGap = gap && gap.y * scaleY;
1360
- if (transform || scaleX !== 1 || scaleY !== 1) {
1361
- const canvasWidth = width + (xGap || 0);
1362
- const canvasHeight = height + (yGap || 0);
1363
- scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1364
- scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1365
- if (!imageMatrix) {
1366
- imageMatrix = get$1();
1367
- if (transform) copy$1(imageMatrix, transform);
1288
+ case 270:
1289
+ translate(transform, 0, width);
1290
+ break;
1291
+ }
1368
1292
  }
1369
- scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1370
1293
  }
1371
- const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1372
- const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1373
- paint.style = pattern;
1374
- paint.patternId = id;
1375
- return true;
1376
- } else {
1377
- return false;
1294
+ origin.x = box.x + x;
1295
+ origin.y = box.y + y;
1296
+ translate(transform, origin.x, origin.y);
1297
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1378
1298
  }
1299
+ data.transform = transform;
1300
+ }
1301
+
1302
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1303
+ if (rotation) rotate(transform, rotation);
1304
+ if (skew) skewHelper(transform, skew.x, skew.y);
1305
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1306
+ translate(transform, box.x + x, box.y + y);
1379
1307
  }
1380
1308
 
1381
1309
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -1411,58 +1339,116 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
1411
1339
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1412
1340
  };
1413
1341
 
1414
- function checkImage(ui, canvas, paint, allowDraw) {
1415
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1416
- const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1417
- if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !Export.running) {
1342
+ const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1343
+
1344
+ const {getFloorScale: getFloorScale} = MathHelper, {abs: abs$1} = Math;
1345
+
1346
+ function createPatternTask(paint, ui, canvas, renderOptions) {
1347
+ if (!paint.patternTask) {
1348
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1349
+ paint.patternTask = null;
1350
+ if (canvas.bounds.hit(ui.__nowWorld)) PaintImage.createPattern(paint, ui, canvas, renderOptions);
1351
+ ui.forceUpdate("surface");
1352
+ }), 300);
1353
+ }
1354
+ }
1355
+
1356
+ function createPattern(paint, ui, canvas, renderOptions) {
1357
+ let {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1358
+ if (paint.patternId !== id && !ui.destroyed) {
1359
+ if (!(Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1360
+ const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1361
+ let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1362
+ if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1363
+ width *= scaleX;
1364
+ height *= scaleY;
1365
+ if (gap) {
1366
+ xGap = gap.x * scaleX / abs$1(data.scaleX || 1);
1367
+ yGap = gap.y * scaleY / abs$1(data.scaleY || 1);
1368
+ }
1369
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1370
+ scaleX *= getFloorScale(width + (xGap || 0));
1371
+ scaleY *= getFloorScale(height + (yGap || 0));
1372
+ imageMatrix = get$1();
1373
+ if (transform) copy$1(imageMatrix, transform);
1374
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1375
+ }
1376
+ const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1377
+ const pattern = image.getPattern(imageCanvas, data.repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1378
+ paint.style = pattern;
1379
+ paint.patternId = id;
1380
+ }
1381
+ }
1382
+ }
1383
+
1384
+ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1385
+ const {image: image} = paint;
1386
+ let fixScale, maxSize = Platform.image.maxPatternSize, imageSize = image.width * image.height;
1387
+ if (image.isSVG) {
1388
+ if (imageScaleX > 1) fixScale = Math.ceil(imageScaleX) / imageScaleX;
1389
+ } else {
1390
+ if (maxSize > imageSize) maxSize = imageSize;
1391
+ }
1392
+ if ((imageSize *= imageScaleX * imageScaleY) > maxSize) fixScale = Math.sqrt(maxSize / imageSize);
1393
+ return fixScale;
1394
+ }
1395
+
1396
+ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1397
+ const {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1398
+ const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting} = renderOptions;
1399
+ if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting) {
1418
1400
  return false;
1419
1401
  } else {
1420
- if (allowDraw) {
1402
+ if (drawImage) {
1421
1403
  if (data.repeat) {
1422
- allowDraw = false;
1423
- } else if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
1424
- let {width: width, height: height} = data;
1425
- width *= scaleX * pixelRatio;
1426
- height *= scaleY * pixelRatio;
1427
- if (data.scaleX) {
1428
- width *= data.scaleX;
1429
- height *= data.scaleY;
1430
- }
1431
- allowDraw = width * height > Platform.image.maxCacheSize;
1404
+ drawImage = false;
1405
+ } else if (!(originPaint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || exporting)) {
1406
+ drawImage = Platform.image.isLarge(image, scaleX, scaleY);
1432
1407
  }
1433
1408
  }
1434
- if (allowDraw) {
1409
+ if (drawImage) {
1435
1410
  if (ui.__.__isFastShadow) {
1436
1411
  canvas.fillStyle = paint.style || "#000";
1437
1412
  canvas.fill();
1438
1413
  }
1439
- drawImage(ui, canvas, paint, data);
1414
+ PaintImage.drawImage(paint, scaleX, scaleY, ui, canvas, renderOptions);
1440
1415
  return true;
1441
1416
  } else {
1442
- if (!paint.style || paint.sync || Export.running) {
1443
- createPattern(ui, paint, pixelRatio);
1444
- } else {
1445
- if (!paint.patternTask) {
1446
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1447
- paint.patternTask = null;
1448
- if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1449
- ui.forceUpdate("surface");
1450
- }), 300);
1451
- }
1452
- }
1417
+ if (!paint.style || originPaint.sync || exporting) PaintImage.createPattern(paint, ui, canvas, renderOptions); else PaintImage.createPatternTask(paint, ui, canvas, renderOptions);
1453
1418
  return false;
1454
1419
  }
1455
1420
  }
1456
1421
  }
1457
1422
 
1458
- function drawImage(ui, canvas, paint, data) {
1459
- canvas.save();
1460
- canvas.clipUI(ui);
1461
- if (paint.blendMode) canvas.blendMode = paint.blendMode;
1462
- if (data.opacity) canvas.opacity *= data.opacity;
1463
- if (data.transform) canvas.transform(data.transform);
1464
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1465
- canvas.restore();
1423
+ function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1424
+ const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1425
+ let {width: width, height: height} = image, clipUI;
1426
+ if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1427
+ canvas.save();
1428
+ clipUI && canvas.clipUI(ui);
1429
+ blendMode && (canvas.blendMode = blendMode);
1430
+ opacity && (canvas.opacity *= opacity);
1431
+ transform && canvas.transform(transform);
1432
+ canvas.drawImage(view, 0, 0, width, height);
1433
+ canvas.restore();
1434
+ } else {
1435
+ if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1436
+ canvas.drawImage(view, 0, 0, width, height);
1437
+ }
1438
+ }
1439
+
1440
+ function getImageRenderScaleData(paint, ui, canvas, _renderOptions) {
1441
+ const scaleData = ui.getRenderScaleData(true, paint.originPaint.scaleFixed), {data: data} = paint;
1442
+ if (canvas) {
1443
+ const {pixelRatio: pixelRatio} = canvas;
1444
+ scaleData.scaleX *= pixelRatio;
1445
+ scaleData.scaleY *= pixelRatio;
1446
+ }
1447
+ if (data && data.scaleX) {
1448
+ scaleData.scaleX *= Math.abs(data.scaleX);
1449
+ scaleData.scaleY *= Math.abs(data.scaleY);
1450
+ }
1451
+ return scaleData;
1466
1452
  }
1467
1453
 
1468
1454
  function recycleImage(attrName, data) {
@@ -1494,8 +1480,12 @@ function recycleImage(attrName, data) {
1494
1480
  const PaintImageModule = {
1495
1481
  image: image,
1496
1482
  checkImage: checkImage,
1497
- createPattern: createPattern,
1483
+ drawImage: drawImage,
1484
+ getImageRenderScaleData: getImageRenderScaleData,
1498
1485
  recycleImage: recycleImage,
1486
+ createPatternTask: createPatternTask,
1487
+ createPattern: createPattern,
1488
+ getPatternFixScale: getPatternFixScale,
1499
1489
  createData: createData,
1500
1490
  getPatternData: getPatternData,
1501
1491
  stretchMode: stretchMode,
@@ -1951,10 +1941,8 @@ function createRows(drawData, content, style) {
1951
1941
  bounds = drawData.bounds;
1952
1942
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
1953
1943
  const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
1954
- const {canvas: canvas} = Platform;
1955
- const {width: width, height: height} = bounds;
1956
- const charMode = width || height || __letterSpacing || textCase !== "none";
1957
- if (charMode) {
1944
+ const {canvas: canvas} = Platform, {width: width} = bounds;
1945
+ if (style.__isCharMode) {
1958
1946
  const wrap = style.textWrap !== "none";
1959
1947
  const breakAll = style.textWrap === "break";
1960
1948
  paraStart = true;
@@ -2083,12 +2071,19 @@ const TextMode = 2;
2083
2071
  function layoutChar(drawData, style, width, _height) {
2084
2072
  const {rows: rows} = drawData;
2085
2073
  const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
2086
- let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2074
+ const justifyLast = width && textAlign.includes("both");
2075
+ const justify = justifyLast || width && textAlign.includes("justify");
2076
+ const justifyLetter = justify && textAlign.includes("letter");
2077
+ let charX, remainingWidth, addWordWidth, addLetterWidth, indentWidth, mode, wordChar, wordsLength, isLastWord, canJustify;
2087
2078
  rows.forEach(row => {
2088
2079
  if (row.words) {
2089
2080
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2090
- addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2091
- mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2081
+ if (justify) {
2082
+ canJustify = !row.paraEnd || justifyLast;
2083
+ remainingWidth = width - row.width - indentWidth;
2084
+ if (justifyLetter) addLetterWidth = remainingWidth / (row.words.reduce((total, item) => total + item.data.length, 0) - 1); else addWordWidth = wordsLength > 1 ? remainingWidth / (wordsLength - 1) : 0;
2085
+ }
2086
+ mode = letterSpacing || row.isOverflow || justifyLetter ? CharMode : addWordWidth ? WordMode : TextMode;
2092
2087
  if (row.isOverflow && !letterSpacing) row.textMode = true;
2093
2088
  if (mode === TextMode) {
2094
2089
  row.x += indentWidth;
@@ -2106,11 +2101,15 @@ function layoutChar(drawData, style, width, _height) {
2106
2101
  charX = toWordChar(word.data, charX, wordChar);
2107
2102
  if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2108
2103
  } else {
2109
- charX = toChar(word.data, charX, row.data, row.isOverflow);
2104
+ charX = toChar(word.data, charX, row.data, row.isOverflow, canJustify && addLetterWidth);
2110
2105
  }
2111
- if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
2112
- charX += addWordWidth;
2113
- row.width += addWordWidth;
2106
+ if (canJustify) {
2107
+ isLastWord = index === wordsLength - 1;
2108
+ if (addWordWidth) {
2109
+ if (!isLastWord) charX += addWordWidth, row.width += addWordWidth;
2110
+ } else if (addLetterWidth) {
2111
+ row.width += addLetterWidth * (word.data.length - (isLastWord ? 1 : 0));
2112
+ }
2114
2113
  }
2115
2114
  });
2116
2115
  }
@@ -2136,13 +2135,14 @@ function toWordChar(data, charX, wordChar) {
2136
2135
  return charX;
2137
2136
  }
2138
2137
 
2139
- function toChar(data, charX, rowData, isOverflow) {
2138
+ function toChar(data, charX, rowData, isOverflow, addLetterWidth) {
2140
2139
  data.forEach(char => {
2141
2140
  if (isOverflow || char.char !== " ") {
2142
2141
  char.x = charX;
2143
2142
  rowData.push(char);
2144
2143
  }
2145
2144
  charX += char.width;
2145
+ addLetterWidth && (charX += addLetterWidth);
2146
2146
  });
2147
2147
  return charX;
2148
2148
  }
@@ -2284,10 +2284,10 @@ function getDrawData(content, style) {
2284
2284
  let x = 0, y = 0;
2285
2285
  let width = style.__getInput("width") || 0;
2286
2286
  let height = style.__getInput("height") || 0;
2287
- const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2287
+ const {__padding: padding} = style;
2288
2288
  if (padding) {
2289
- if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2290
- if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2289
+ if (width) x = padding[left], width -= padding[right] + padding[left], !width && (width = .01); else if (!style.autoSizeAlign) x = padding[left];
2290
+ if (height) y = padding[top], height -= padding[top] + padding[bottom], !height && (height = .01); else if (!style.autoSizeAlign) y = padding[top];
2291
2291
  }
2292
2292
  const drawData = {
2293
2293
  bounds: {
@@ -2298,14 +2298,14 @@ function getDrawData(content, style) {
2298
2298
  },
2299
2299
  rows: [],
2300
2300
  paraNumber: 0,
2301
- font: Platform.canvas.font = __font
2301
+ font: Platform.canvas.font = style.__font
2302
2302
  };
2303
2303
  createRows(drawData, content, style);
2304
2304
  if (padding) padAutoText(padding, drawData, style, width, height);
2305
2305
  layoutText(drawData, style);
2306
- layoutChar(drawData, style, width);
2306
+ if (style.__isCharMode) layoutChar(drawData, style, width);
2307
2307
  if (drawData.overflow) clipText(drawData, style, x, width);
2308
- if (textDecoration !== "none") decorationText(drawData, style);
2308
+ if (style.textDecoration !== "none") decorationText(drawData, style);
2309
2309
  return drawData;
2310
2310
  }
2311
2311