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