@leafer-draw/miniapp 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/miniapp.cjs CHANGED
@@ -815,102 +815,163 @@ core.Platform.render = function(target, canvas, options) {
815
815
  if (options.topList.length) options.topList.forEach(item => item.__render(canvas, topOptions));
816
816
  };
817
817
 
818
- function fillText(ui, canvas) {
819
- const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
820
- if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
821
- let row;
822
- for (let i = 0, len = rows.length; i < len; i++) {
823
- row = rows[i];
824
- if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
825
- canvas.fillText(charData.char, charData.x, row.y);
826
- });
827
- }
828
- if (decorationY) {
829
- const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
830
- if (decorationColor) canvas.fillStyle = decorationColor;
831
- rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
832
- }
833
- }
834
-
835
- function fill(fill, ui, canvas) {
818
+ function fill(fill, ui, canvas, renderOptions) {
836
819
  canvas.fillStyle = fill;
837
- fillPathOrText(ui, canvas);
820
+ fillPathOrText(ui, canvas, renderOptions);
838
821
  }
839
822
 
840
- function fills(fills, ui, canvas) {
841
- let item;
823
+ function fills(fills, ui, canvas, renderOptions) {
824
+ let item, originPaint, countImage;
842
825
  for (let i = 0, len = fills.length; i < len; i++) {
843
- item = fills[i];
826
+ item = fills[i], originPaint = item.originPaint;
844
827
  if (item.image) {
845
- if (draw.PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
828
+ countImage ? countImage++ : countImage = 1;
829
+ if (draw.PaintImage.checkImage(item, !ui.__.__font, ui, canvas, renderOptions)) continue;
846
830
  if (!item.style) {
847
- if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
831
+ if (countImage === 1 && item.image.isPlacehold) ui.drawImagePlaceholder(item, canvas, renderOptions);
848
832
  continue;
849
833
  }
850
834
  }
851
835
  canvas.fillStyle = item.style;
852
- if (item.transform || item.scaleFixed) {
836
+ if (item.transform || originPaint.scaleFixed) {
853
837
  canvas.save();
854
838
  if (item.transform) canvas.transform(item.transform);
855
- if (item.scaleFixed) {
839
+ if (originPaint.scaleFixed) {
856
840
  const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
857
- if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
841
+ if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
858
842
  }
859
- if (item.blendMode) canvas.blendMode = item.blendMode;
860
- fillPathOrText(ui, canvas);
843
+ if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
844
+ fillPathOrText(ui, canvas, renderOptions);
861
845
  canvas.restore();
862
846
  } else {
863
- if (item.blendMode) {
864
- canvas.saveBlendMode(item.blendMode);
865
- fillPathOrText(ui, canvas);
847
+ if (originPaint.blendMode) {
848
+ canvas.saveBlendMode(originPaint.blendMode);
849
+ fillPathOrText(ui, canvas, renderOptions);
866
850
  canvas.restoreBlendMode();
867
- } else fillPathOrText(ui, canvas);
851
+ } else fillPathOrText(ui, canvas, renderOptions);
868
852
  }
869
853
  }
870
854
  }
871
855
 
872
- function fillPathOrText(ui, canvas) {
873
- ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
856
+ function fillPathOrText(ui, canvas, renderOptions) {
857
+ ui.__.__font ? draw.Paint.fillText(ui, canvas, renderOptions) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
874
858
  }
875
859
 
876
- function strokeText(stroke, ui, canvas) {
860
+ function fillText(ui, canvas, _renderOptions) {
861
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
862
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
863
+ let row;
864
+ for (let i = 0, len = rows.length; i < len; i++) {
865
+ row = rows[i];
866
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
867
+ canvas.fillText(charData.char, charData.x, row.y);
868
+ });
869
+ }
870
+ if (decorationY) {
871
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
872
+ if (decorationColor) canvas.fillStyle = decorationColor;
873
+ rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
874
+ }
875
+ }
876
+
877
+ function stroke(stroke, ui, canvas, renderOptions) {
878
+ const data = ui.__;
879
+ if (!data.__strokeWidth) return;
880
+ if (data.__font) {
881
+ draw.Paint.strokeText(stroke, ui, canvas, renderOptions);
882
+ } else {
883
+ switch (data.strokeAlign) {
884
+ case "center":
885
+ drawCenter$1(stroke, 1, ui, canvas, renderOptions);
886
+ break;
887
+
888
+ case "inside":
889
+ drawInside(stroke, ui, canvas, renderOptions);
890
+ break;
891
+
892
+ case "outside":
893
+ drawOutside(stroke, ui, canvas, renderOptions);
894
+ break;
895
+ }
896
+ }
897
+ }
898
+
899
+ function strokes(strokes, ui, canvas, renderOptions) {
900
+ draw.Paint.stroke(strokes, ui, canvas, renderOptions);
901
+ }
902
+
903
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas, renderOptions) {
904
+ const data = ui.__;
905
+ if (core.isObject(stroke)) {
906
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas, renderOptions);
907
+ } else {
908
+ canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
909
+ canvas.stroke();
910
+ }
911
+ if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas, renderOptions);
912
+ }
913
+
914
+ function drawInside(stroke, ui, canvas, renderOptions) {
915
+ canvas.save();
916
+ canvas.clipUI(ui);
917
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
918
+ canvas.restore();
919
+ }
920
+
921
+ function drawOutside(stroke, ui, canvas, renderOptions) {
922
+ const data = ui.__;
923
+ if (data.__fillAfterStroke) {
924
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
925
+ } else {
926
+ const {renderBounds: renderBounds} = ui.__layout;
927
+ const out = canvas.getSameCanvas(true, true);
928
+ ui.__drawRenderPath(out);
929
+ drawCenter$1(stroke, 2, ui, out, renderOptions);
930
+ out.clipUI(data);
931
+ out.clearWorld(renderBounds);
932
+ core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
933
+ out.recycle(ui.__nowWorld);
934
+ }
935
+ }
936
+
937
+ function strokeText(stroke, ui, canvas, renderOptions) {
877
938
  switch (ui.__.strokeAlign) {
878
939
  case "center":
879
- drawCenter$1(stroke, 1, ui, canvas);
940
+ drawCenter(stroke, 1, ui, canvas, renderOptions);
880
941
  break;
881
942
 
882
943
  case "inside":
883
- drawAlign(stroke, "inside", ui, canvas);
944
+ drawAlign(stroke, "inside", ui, canvas, renderOptions);
884
945
  break;
885
946
 
886
947
  case "outside":
887
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
948
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas, renderOptions) : drawAlign(stroke, "outside", ui, canvas, renderOptions);
888
949
  break;
889
950
  }
890
951
  }
891
952
 
892
- function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
953
+ function drawCenter(stroke, strokeWidthScale, ui, canvas, renderOptions) {
893
954
  const data = ui.__;
894
955
  if (core.isObject(stroke)) {
895
- drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
956
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas, renderOptions);
896
957
  } else {
897
958
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
898
- drawTextStroke(ui, canvas);
959
+ draw.Paint.drawTextStroke(ui, canvas, renderOptions);
899
960
  }
900
961
  }
901
962
 
902
- function drawAlign(stroke, align, ui, canvas) {
963
+ function drawAlign(stroke, align, ui, canvas, renderOptions) {
903
964
  const out = canvas.getSameCanvas(true, true);
904
965
  out.font = ui.__.__font;
905
- drawCenter$1(stroke, 2, ui, out);
966
+ drawCenter(stroke, 2, ui, out, renderOptions);
906
967
  out.blendMode = align === "outside" ? "destination-out" : "destination-in";
907
- fillText(ui, out);
968
+ draw.Paint.fillText(ui, out, renderOptions);
908
969
  out.blendMode = "normal";
909
970
  core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
910
971
  out.recycle(ui.__nowWorld);
911
972
  }
912
973
 
913
- function drawTextStroke(ui, canvas) {
974
+ function drawTextStroke(ui, canvas, _renderOptions) {
914
975
  let row, data = ui.__.__textDrawData;
915
976
  const {rows: rows, decorationY: decorationY} = data;
916
977
  for (let i = 0, len = rows.length; i < len; i++) {
@@ -925,89 +986,29 @@ function drawTextStroke(ui, canvas) {
925
986
  }
926
987
  }
927
988
 
928
- function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
989
+ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas, renderOptions) {
929
990
  let item;
930
991
  const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
931
992
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
932
993
  for (let i = 0, len = strokes.length; i < len; i++) {
933
994
  item = strokes[i];
934
- if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false)) continue;
995
+ if (item.image && draw.PaintImage.checkImage(item, false, ui, canvas, renderOptions)) continue;
935
996
  if (item.style) {
936
997
  if (__hasMultiStrokeStyle) {
937
998
  const {strokeStyle: strokeStyle} = item;
938
999
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
939
1000
  } else canvas.strokeStyle = item.style;
940
- if (item.blendMode) {
941
- canvas.saveBlendMode(item.blendMode);
942
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1001
+ if (item.originPaint.blendMode) {
1002
+ canvas.saveBlendMode(item.originPaint.blendMode);
1003
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
943
1004
  canvas.restoreBlendMode();
944
1005
  } else {
945
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1006
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
946
1007
  }
947
1008
  }
948
1009
  }
949
1010
  }
950
1011
 
951
- function stroke(stroke, ui, canvas) {
952
- const data = ui.__;
953
- if (!data.__strokeWidth) return;
954
- if (data.__font) {
955
- strokeText(stroke, ui, canvas);
956
- } else {
957
- switch (data.strokeAlign) {
958
- case "center":
959
- drawCenter(stroke, 1, ui, canvas);
960
- break;
961
-
962
- case "inside":
963
- drawInside(stroke, ui, canvas);
964
- break;
965
-
966
- case "outside":
967
- drawOutside(stroke, ui, canvas);
968
- break;
969
- }
970
- }
971
- }
972
-
973
- function strokes(strokes, ui, canvas) {
974
- stroke(strokes, ui, canvas);
975
- }
976
-
977
- function drawCenter(stroke, strokeWidthScale, ui, canvas) {
978
- const data = ui.__;
979
- if (core.isObject(stroke)) {
980
- drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
981
- } else {
982
- canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
983
- canvas.stroke();
984
- }
985
- if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas);
986
- }
987
-
988
- function drawInside(stroke, ui, canvas) {
989
- canvas.save();
990
- canvas.clipUI(ui);
991
- drawCenter(stroke, 2, ui, canvas);
992
- canvas.restore();
993
- }
994
-
995
- function drawOutside(stroke, ui, canvas) {
996
- const data = ui.__;
997
- if (data.__fillAfterStroke) {
998
- drawCenter(stroke, 2, ui, canvas);
999
- } else {
1000
- const {renderBounds: renderBounds} = ui.__layout;
1001
- const out = canvas.getSameCanvas(true, true);
1002
- ui.__drawRenderPath(out);
1003
- drawCenter(stroke, 2, ui, out);
1004
- out.clipUI(data);
1005
- out.clearWorld(renderBounds);
1006
- core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1007
- out.recycle(ui.__nowWorld);
1008
- }
1009
- }
1010
-
1011
1012
  const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
1012
1013
 
1013
1014
  const tempBounds$1 = {};
@@ -1095,62 +1096,63 @@ function compute(attrName, ui) {
1095
1096
  if (leafPaints.some(item => item.image)) isAlphaPixel = true;
1096
1097
  isTransparent = true;
1097
1098
  }
1098
- }
1099
- if (attrName === "fill") {
1100
- stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1101
- stintSet(data, "__isTransparentFill", isTransparent);
1099
+ if (attrName === "fill") {
1100
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1101
+ stintSet(data, "__isTransparentFill", isTransparent);
1102
+ } else {
1103
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1104
+ stintSet(data, "__isTransparentStroke", isTransparent);
1105
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1106
+ }
1102
1107
  } else {
1103
- stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1104
- stintSet(data, "__isTransparentStroke", isTransparent);
1105
- stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1108
+ data.__removePaint(attrName, false);
1106
1109
  }
1107
1110
  }
1108
1111
 
1109
1112
  function getLeafPaint(attrName, paint, ui) {
1110
1113
  if (!core.isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1111
- let data;
1114
+ let leafPaint;
1112
1115
  const {boxBounds: boxBounds} = ui.__layout;
1113
1116
  switch (paint.type) {
1114
1117
  case "image":
1115
- data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1118
+ leafPaint = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1116
1119
  break;
1117
1120
 
1118
1121
  case "linear":
1119
- data = draw.PaintGradient.linearGradient(paint, boxBounds);
1122
+ leafPaint = draw.PaintGradient.linearGradient(paint, boxBounds);
1120
1123
  break;
1121
1124
 
1122
1125
  case "radial":
1123
- data = draw.PaintGradient.radialGradient(paint, boxBounds);
1126
+ leafPaint = draw.PaintGradient.radialGradient(paint, boxBounds);
1124
1127
  break;
1125
1128
 
1126
1129
  case "angular":
1127
- data = draw.PaintGradient.conicGradient(paint, boxBounds);
1130
+ leafPaint = draw.PaintGradient.conicGradient(paint, boxBounds);
1128
1131
  break;
1129
1132
 
1130
1133
  case "solid":
1131
1134
  const {type: type, color: color, opacity: opacity} = paint;
1132
- data = {
1135
+ leafPaint = {
1133
1136
  type: type,
1134
1137
  style: draw.ColorConvert.string(color, opacity)
1135
1138
  };
1136
1139
  break;
1137
1140
 
1138
1141
  default:
1139
- if (!core.isUndefined(paint.r)) data = {
1142
+ if (!core.isUndefined(paint.r)) leafPaint = {
1140
1143
  type: "solid",
1141
1144
  style: draw.ColorConvert.string(paint)
1142
1145
  };
1143
1146
  }
1144
- if (data) {
1145
- if (core.isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
1147
+ if (leafPaint) {
1148
+ leafPaint.originPaint = paint;
1149
+ if (core.isString(leafPaint.style) && hasTransparent$1(leafPaint.style)) leafPaint.isTransparent = true;
1146
1150
  if (paint.style) {
1147
1151
  if (paint.style.strokeWidth === 0) return undefined;
1148
- data.strokeStyle = paint.style;
1152
+ leafPaint.strokeStyle = paint.style;
1149
1153
  }
1150
- if (paint.editing) data.editing = paint.editing;
1151
- if (paint.blendMode) data.blendMode = paint.blendMode;
1152
1154
  }
1153
- return data;
1155
+ return leafPaint;
1154
1156
  }
1155
1157
 
1156
1158
  const PaintModule = {
@@ -1163,88 +1165,118 @@ const PaintModule = {
1163
1165
  strokes: strokes,
1164
1166
  strokeText: strokeText,
1165
1167
  drawTextStroke: drawTextStroke,
1168
+ drawStrokesStyle: drawStrokesStyle,
1166
1169
  shape: shape
1167
1170
  };
1168
1171
 
1169
- let origin = {}, tempMatrix$1 = core.getMatrixData();
1172
+ let cache, box = new core.Bounds;
1170
1173
 
1171
- 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;
1174
+ const {isSame: isSame} = core.BoundsHelper;
1172
1175
 
1173
- function stretchMode(data, box, scaleX, scaleY) {
1174
- const transform = get$3();
1175
- translate$1(transform, box.x, box.y);
1176
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1177
- data.transform = transform;
1176
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1177
+ let leafPaint, event;
1178
+ const image = core.ImageManager.get(paint);
1179
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1180
+ leafPaint = cache.leafPaint;
1181
+ } else {
1182
+ leafPaint = {
1183
+ type: paint.type,
1184
+ image: image
1185
+ };
1186
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1187
+ cache = image.use > 1 ? {
1188
+ leafPaint: leafPaint,
1189
+ paint: paint,
1190
+ boxBounds: box.set(boxBounds)
1191
+ } : null;
1192
+ }
1193
+ if (firstUse || image.loading) event = {
1194
+ image: image,
1195
+ attrName: attrName,
1196
+ attrValue: paint
1197
+ };
1198
+ if (image.ready) {
1199
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1200
+ if (firstUse) {
1201
+ onLoad(ui, event);
1202
+ onLoadSuccess(ui, event);
1203
+ }
1204
+ } else if (image.error) {
1205
+ if (firstUse) onLoadError(ui, event, image.error);
1206
+ } else {
1207
+ if (firstUse) {
1208
+ ignoreRender(ui, true);
1209
+ onLoad(ui, event);
1210
+ }
1211
+ leafPaint.loadId = image.load(() => {
1212
+ ignoreRender(ui, false);
1213
+ if (!ui.destroyed) {
1214
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1215
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1216
+ ui.forceUpdate("surface");
1217
+ }
1218
+ onLoadSuccess(ui, event);
1219
+ }
1220
+ leafPaint.loadId = undefined;
1221
+ }, error => {
1222
+ ignoreRender(ui, false);
1223
+ onLoadError(ui, event, error);
1224
+ leafPaint.loadId = undefined;
1225
+ });
1226
+ if (ui.placeholderColor) {
1227
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1228
+ if (!image.ready) {
1229
+ image.isPlacehold = true;
1230
+ ui.forceUpdate("surface");
1231
+ }
1232
+ }, ui.placeholderDelay);
1233
+ }
1234
+ }
1235
+ return leafPaint;
1178
1236
  }
1179
1237
 
1180
- function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1181
- const transform = get$3();
1182
- translate$1(transform, box.x + x, box.y + y);
1183
- scaleHelper(transform, scaleX, scaleY);
1184
- if (rotation) rotateOfOuter$1(transform, {
1185
- x: box.x + box.width / 2,
1186
- y: box.y + box.height / 2
1187
- }, rotation);
1188
- data.transform = transform;
1238
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1239
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1240
+ const data = ui.__;
1241
+ data.__naturalWidth = image.width / data.pixelRatio;
1242
+ data.__naturalHeight = image.height / data.pixelRatio;
1243
+ if (data.__autoSide) {
1244
+ ui.forceUpdate("width");
1245
+ if (ui.__proxyData) {
1246
+ ui.setProxyAttr("width", data.width);
1247
+ ui.setProxyAttr("height", data.height);
1248
+ }
1249
+ return false;
1250
+ }
1251
+ }
1252
+ if (!leafPaint.data) draw.PaintImage.createData(leafPaint, image, paint, boxBounds);
1253
+ return true;
1189
1254
  }
1190
1255
 
1191
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1192
- const transform = get$3();
1193
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1194
- if (clipScaleX) {
1195
- if (rotation || skew) {
1196
- set(tempMatrix$1);
1197
- scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1198
- multiplyParent(transform, tempMatrix$1);
1199
- } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1200
- }
1201
- data.transform = transform;
1256
+ function onLoad(ui, event) {
1257
+ emit(ui, core.ImageEvent.LOAD, event);
1202
1258
  }
1203
1259
 
1204
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1205
- const transform = get$3();
1206
- if (freeTransform) {
1207
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1208
- } else {
1209
- if (rotation) {
1210
- if (align === "center") {
1211
- rotateOfOuter$1(transform, {
1212
- x: width / 2,
1213
- y: height / 2
1214
- }, rotation);
1215
- } else {
1216
- rotate(transform, rotation);
1217
- switch (rotation) {
1218
- case 90:
1219
- translate$1(transform, height, 0);
1220
- break;
1260
+ function onLoadSuccess(ui, event) {
1261
+ emit(ui, core.ImageEvent.LOADED, event);
1262
+ }
1221
1263
 
1222
- case 180:
1223
- translate$1(transform, width, height);
1224
- break;
1264
+ function onLoadError(ui, event, error) {
1265
+ event.error = error;
1266
+ ui.forceUpdate("surface");
1267
+ emit(ui, core.ImageEvent.ERROR, event);
1268
+ }
1225
1269
 
1226
- case 270:
1227
- translate$1(transform, 0, width);
1228
- break;
1229
- }
1230
- }
1231
- }
1232
- origin.x = box.x + x;
1233
- origin.y = box.y + y;
1234
- translate$1(transform, origin.x, origin.y);
1235
- if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1236
- }
1237
- data.transform = transform;
1270
+ function emit(ui, type, data) {
1271
+ if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1238
1272
  }
1239
1273
 
1240
- function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1241
- if (rotation) rotate(transform, rotation);
1242
- if (skew) skewHelper(transform, skew.x, skew.y);
1243
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1244
- translate$1(transform, box.x + x, box.y + y);
1274
+ function ignoreRender(ui, value) {
1275
+ const {leafer: leafer} = ui;
1276
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1245
1277
  }
1246
1278
 
1247
- const {get: get$2, translate: translate} = core.MatrixHelper;
1279
+ const {get: get$3, translate: translate$1} = core.MatrixHelper;
1248
1280
 
1249
1281
  const tempBox = new core.Bounds;
1250
1282
 
@@ -1253,17 +1285,13 @@ const tempScaleData = {};
1253
1285
  const tempImage = {};
1254
1286
 
1255
1287
  function createData(leafPaint, image, paint, box) {
1256
- const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1257
- if (changeful) leafPaint.changeful = changeful;
1258
- if (sync) leafPaint.sync = sync;
1259
- if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1260
- leafPaint.data = getPatternData(paint, box, image);
1288
+ leafPaint.data = draw.PaintImage.getPatternData(paint, box, image);
1261
1289
  }
1262
1290
 
1263
1291
  function getPatternData(paint, box, image) {
1264
1292
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1265
1293
  if (paint.mode === "strench") paint.mode = "stretch";
1266
- let {width: width, height: height} = image;
1294
+ const {width: width, height: height} = image;
1267
1295
  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;
1268
1296
  const sameBox = box.width === width && box.height === height;
1269
1297
  const data = {
@@ -1294,8 +1322,8 @@ function getPatternData(paint, box, image) {
1294
1322
  case "stretch":
1295
1323
  if (!sameBox) {
1296
1324
  scaleX = box.width / width, scaleY = box.height / height;
1297
- stretchMode(data, box, scaleX, scaleY);
1298
- }
1325
+ draw.PaintImage.stretchMode(data, box, scaleX, scaleY);
1326
+ } else if (scaleX) scaleX = scaleY = undefined;
1299
1327
  break;
1300
1328
 
1301
1329
  case "normal":
@@ -1303,13 +1331,13 @@ function getPatternData(paint, box, image) {
1303
1331
  if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1304
1332
  let clipScaleX, clipScaleY;
1305
1333
  if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1306
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1334
+ draw.PaintImage.clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1307
1335
  if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : clipScaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1308
1336
  }
1309
1337
  break;
1310
1338
 
1311
1339
  case "repeat":
1312
- if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1340
+ if (!sameBox || scaleX || rotation || skew) draw.PaintImage.repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1313
1341
  if (!repeat) data.repeat = "repeat";
1314
1342
  const count = core.isObject(repeat);
1315
1343
  if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
@@ -1318,18 +1346,16 @@ function getPatternData(paint, box, image) {
1318
1346
  case "fit":
1319
1347
  case "cover":
1320
1348
  default:
1321
- if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1349
+ if (scaleX) draw.PaintImage.fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1322
1350
  }
1323
1351
  if (!data.transform) {
1324
- if (box.x || box.y) translate(data.transform = get$2(), box.x, box.y);
1352
+ if (box.x || box.y) translate$1(data.transform = get$3(), box.x, box.y);
1325
1353
  }
1326
- data.width = width;
1327
- data.height = height;
1328
1354
  if (scaleX) {
1329
1355
  data.scaleX = scaleX;
1330
1356
  data.scaleY = scaleY;
1331
1357
  }
1332
- if (opacity) data.opacity = opacity;
1358
+ if (opacity && opacity < 1) data.opacity = opacity;
1333
1359
  if (filters) data.filters = filters;
1334
1360
  if (repeat) data.repeat = core.isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1335
1361
  return data;
@@ -1351,180 +1377,82 @@ function getGapValue(gap, size, totalSize, rows) {
1351
1377
  return gap === "auto" ? value < 0 ? 0 : value : value;
1352
1378
  }
1353
1379
 
1354
- let cache, box = new core.Bounds;
1355
-
1356
- const {isSame: isSame} = core.BoundsHelper;
1357
-
1358
- function image(ui, attrName, paint, boxBounds, firstUse) {
1359
- let leafPaint, event;
1360
- const image = core.ImageManager.get(paint);
1361
- if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1362
- leafPaint = cache.leafPaint;
1363
- } else {
1364
- leafPaint = {
1365
- type: paint.type,
1366
- image: image
1367
- };
1368
- if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1369
- cache = image.use > 1 ? {
1370
- leafPaint: leafPaint,
1371
- paint: paint,
1372
- boxBounds: box.set(boxBounds)
1373
- } : null;
1374
- }
1375
- if (firstUse || image.loading) event = {
1376
- image: image,
1377
- attrName: attrName,
1378
- attrValue: paint
1379
- };
1380
- if (image.ready) {
1381
- checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1382
- if (firstUse) {
1383
- onLoad(ui, event);
1384
- onLoadSuccess(ui, event);
1385
- }
1386
- } else if (image.error) {
1387
- if (firstUse) onLoadError(ui, event, image.error);
1388
- } else {
1389
- if (firstUse) {
1390
- ignoreRender(ui, true);
1391
- onLoad(ui, event);
1392
- }
1393
- leafPaint.loadId = image.load(() => {
1394
- ignoreRender(ui, false);
1395
- if (!ui.destroyed) {
1396
- if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1397
- if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1398
- ui.forceUpdate("surface");
1399
- }
1400
- onLoadSuccess(ui, event);
1401
- }
1402
- leafPaint.loadId = undefined;
1403
- }, error => {
1404
- ignoreRender(ui, false);
1405
- onLoadError(ui, event, error);
1406
- leafPaint.loadId = undefined;
1407
- });
1408
- if (ui.placeholderColor) {
1409
- if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1410
- if (!image.ready) {
1411
- image.isPlacehold = true;
1412
- ui.forceUpdate("surface");
1413
- }
1414
- }, ui.placeholderDelay);
1415
- }
1416
- }
1417
- return leafPaint;
1418
- }
1419
-
1420
- function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1421
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1422
- const data = ui.__;
1423
- data.__naturalWidth = image.width / data.pixelRatio;
1424
- data.__naturalHeight = image.height / data.pixelRatio;
1425
- if (data.__autoSide) {
1426
- ui.forceUpdate("width");
1427
- if (ui.__proxyData) {
1428
- ui.setProxyAttr("width", data.width);
1429
- ui.setProxyAttr("height", data.height);
1430
- }
1431
- return false;
1432
- }
1433
- }
1434
- if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1435
- return true;
1436
- }
1437
-
1438
- function onLoad(ui, event) {
1439
- emit(ui, core.ImageEvent.LOAD, event);
1440
- }
1380
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
1441
1381
 
1442
- function onLoadSuccess(ui, event) {
1443
- emit(ui, core.ImageEvent.LOADED, event);
1444
- }
1382
+ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1445
1383
 
1446
- function onLoadError(ui, event, error) {
1447
- event.error = error;
1448
- ui.forceUpdate("surface");
1449
- emit(ui, core.ImageEvent.ERROR, event);
1384
+ function stretchMode(data, box, scaleX, scaleY) {
1385
+ const transform = get$2(), {x: x, y: y} = box;
1386
+ if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1387
+ scaleHelper(transform, scaleX, scaleY);
1388
+ data.transform = transform;
1450
1389
  }
1451
1390
 
1452
- function emit(ui, type, data) {
1453
- if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1391
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1392
+ const transform = get$2();
1393
+ translate(transform, box.x + x, box.y + y);
1394
+ scaleHelper(transform, scaleX, scaleY);
1395
+ if (rotation) rotateOfOuter$1(transform, {
1396
+ x: box.x + box.width / 2,
1397
+ y: box.y + box.height / 2
1398
+ }, rotation);
1399
+ data.transform = transform;
1454
1400
  }
1455
1401
 
1456
- function ignoreRender(ui, value) {
1457
- const {leafer: leafer} = ui;
1458
- if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1402
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1403
+ const transform = get$2();
1404
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1405
+ if (clipScaleX) {
1406
+ if (rotation || skew) {
1407
+ set(tempMatrix$1);
1408
+ scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1409
+ multiplyParent(transform, tempMatrix$1);
1410
+ } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1411
+ }
1412
+ data.transform = transform;
1459
1413
  }
1460
1414
 
1461
- const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1415
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1416
+ const transform = get$2();
1417
+ if (freeTransform) {
1418
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1419
+ } else {
1420
+ if (rotation) {
1421
+ if (align === "center") {
1422
+ rotateOfOuter$1(transform, {
1423
+ x: width / 2,
1424
+ y: height / 2
1425
+ }, rotation);
1426
+ } else {
1427
+ rotate(transform, rotation);
1428
+ switch (rotation) {
1429
+ case 90:
1430
+ translate(transform, height, 0);
1431
+ break;
1462
1432
 
1463
- const {floor: floor, ceil: ceil, max: max$1, abs: abs$1} = Math;
1433
+ case 180:
1434
+ translate(transform, width, height);
1435
+ break;
1464
1436
 
1465
- function createPattern(ui, paint, pixelRatio) {
1466
- let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1467
- const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1468
- if (paint.patternId !== id && !ui.destroyed) {
1469
- const {image: image, data: data} = paint;
1470
- let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1471
- scaleX *= pixelRatio;
1472
- scaleY *= pixelRatio;
1473
- if (sx) {
1474
- sx = abs$1(sx);
1475
- sy = abs$1(sy);
1476
- imageMatrix = get$1();
1477
- copy$1(imageMatrix, transform);
1478
- scale(imageMatrix, 1 / sx, 1 / sy);
1479
- scaleX *= sx;
1480
- scaleY *= sy;
1481
- }
1482
- width *= scaleX;
1483
- height *= scaleY;
1484
- const size = width * height;
1485
- if (!repeat) {
1486
- if (size > core.Platform.image.maxCacheSize) return false;
1487
- }
1488
- let maxSize = core.Platform.image.maxPatternSize;
1489
- if (image.isSVG) {
1490
- const ws = width / image.width;
1491
- if (ws > 1) imageScale = ws / ceil(ws);
1492
- } else {
1493
- const imageSize = image.width * image.height;
1494
- if (maxSize > imageSize) maxSize = imageSize;
1495
- }
1496
- if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1497
- if (imageScale) {
1498
- scaleX /= imageScale;
1499
- scaleY /= imageScale;
1500
- width /= imageScale;
1501
- height /= imageScale;
1502
- }
1503
- if (sx) {
1504
- scaleX /= sx;
1505
- scaleY /= sy;
1506
- }
1507
- const xGap = gap && gap.x * scaleX;
1508
- const yGap = gap && gap.y * scaleY;
1509
- if (transform || scaleX !== 1 || scaleY !== 1) {
1510
- const canvasWidth = width + (xGap || 0);
1511
- const canvasHeight = height + (yGap || 0);
1512
- scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1513
- scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1514
- if (!imageMatrix) {
1515
- imageMatrix = get$1();
1516
- if (transform) copy$1(imageMatrix, transform);
1437
+ case 270:
1438
+ translate(transform, 0, width);
1439
+ break;
1440
+ }
1517
1441
  }
1518
- scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1519
1442
  }
1520
- const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1521
- const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1522
- paint.style = pattern;
1523
- paint.patternId = id;
1524
- return true;
1525
- } else {
1526
- return false;
1443
+ origin.x = box.x + x;
1444
+ origin.y = box.y + y;
1445
+ translate(transform, origin.x, origin.y);
1446
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1527
1447
  }
1448
+ data.transform = transform;
1449
+ }
1450
+
1451
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1452
+ if (rotation) rotate(transform, rotation);
1453
+ if (skew) skewHelper(transform, skew.x, skew.y);
1454
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1455
+ translate(transform, box.x + x, box.y + y);
1528
1456
  }
1529
1457
 
1530
1458
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -1560,58 +1488,116 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
1560
1488
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1561
1489
  };
1562
1490
 
1563
- function checkImage(ui, canvas, paint, allowDraw) {
1564
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1565
- const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1566
- if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !draw.Export.running) {
1491
+ const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1492
+
1493
+ const {getFloorScale: getFloorScale} = core.MathHelper, {abs: abs$1} = Math;
1494
+
1495
+ function createPatternTask(paint, ui, canvas, renderOptions) {
1496
+ if (!paint.patternTask) {
1497
+ paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1498
+ paint.patternTask = null;
1499
+ if (canvas.bounds.hit(ui.__nowWorld)) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions);
1500
+ ui.forceUpdate("surface");
1501
+ }), 300);
1502
+ }
1503
+ }
1504
+
1505
+ function createPattern(paint, ui, canvas, renderOptions) {
1506
+ let {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1507
+ if (paint.patternId !== id && !ui.destroyed) {
1508
+ if (!(core.Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1509
+ const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = draw.PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1510
+ let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1511
+ if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1512
+ width *= scaleX;
1513
+ height *= scaleY;
1514
+ if (gap) {
1515
+ xGap = gap.x * scaleX / abs$1(data.scaleX || 1);
1516
+ yGap = gap.y * scaleY / abs$1(data.scaleY || 1);
1517
+ }
1518
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1519
+ scaleX *= getFloorScale(width + (xGap || 0));
1520
+ scaleY *= getFloorScale(height + (yGap || 0));
1521
+ imageMatrix = get$1();
1522
+ if (transform) copy$1(imageMatrix, transform);
1523
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1524
+ }
1525
+ const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1526
+ const pattern = image.getPattern(imageCanvas, data.repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1527
+ paint.style = pattern;
1528
+ paint.patternId = id;
1529
+ }
1530
+ }
1531
+ }
1532
+
1533
+ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1534
+ const {image: image} = paint;
1535
+ let fixScale, maxSize = core.Platform.image.maxPatternSize, imageSize = image.width * image.height;
1536
+ if (image.isSVG) {
1537
+ if (imageScaleX > 1) fixScale = Math.ceil(imageScaleX) / imageScaleX;
1538
+ } else {
1539
+ if (maxSize > imageSize) maxSize = imageSize;
1540
+ }
1541
+ if ((imageSize *= imageScaleX * imageScaleY) > maxSize) fixScale = Math.sqrt(maxSize / imageSize);
1542
+ return fixScale;
1543
+ }
1544
+
1545
+ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1546
+ const {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1547
+ const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting} = renderOptions;
1548
+ if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting) {
1567
1549
  return false;
1568
1550
  } else {
1569
- if (allowDraw) {
1551
+ if (drawImage) {
1570
1552
  if (data.repeat) {
1571
- allowDraw = false;
1572
- } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1573
- let {width: width, height: height} = data;
1574
- width *= scaleX * pixelRatio;
1575
- height *= scaleY * pixelRatio;
1576
- if (data.scaleX) {
1577
- width *= data.scaleX;
1578
- height *= data.scaleY;
1579
- }
1580
- allowDraw = width * height > core.Platform.image.maxCacheSize;
1553
+ drawImage = false;
1554
+ } else if (!(originPaint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || exporting)) {
1555
+ drawImage = core.Platform.image.isLarge(image, scaleX, scaleY);
1581
1556
  }
1582
1557
  }
1583
- if (allowDraw) {
1558
+ if (drawImage) {
1584
1559
  if (ui.__.__isFastShadow) {
1585
1560
  canvas.fillStyle = paint.style || "#000";
1586
1561
  canvas.fill();
1587
1562
  }
1588
- drawImage(ui, canvas, paint, data);
1563
+ draw.PaintImage.drawImage(paint, scaleX, scaleY, ui, canvas, renderOptions);
1589
1564
  return true;
1590
1565
  } else {
1591
- if (!paint.style || paint.sync || draw.Export.running) {
1592
- createPattern(ui, paint, pixelRatio);
1593
- } else {
1594
- if (!paint.patternTask) {
1595
- paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1596
- paint.patternTask = null;
1597
- if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1598
- ui.forceUpdate("surface");
1599
- }), 300);
1600
- }
1601
- }
1566
+ if (!paint.style || originPaint.sync || exporting) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions); else draw.PaintImage.createPatternTask(paint, ui, canvas, renderOptions);
1602
1567
  return false;
1603
1568
  }
1604
1569
  }
1605
1570
  }
1606
1571
 
1607
- function drawImage(ui, canvas, paint, data) {
1608
- canvas.save();
1609
- canvas.clipUI(ui);
1610
- if (paint.blendMode) canvas.blendMode = paint.blendMode;
1611
- if (data.opacity) canvas.opacity *= data.opacity;
1612
- if (data.transform) canvas.transform(data.transform);
1613
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1614
- canvas.restore();
1572
+ function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1573
+ const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1574
+ let {width: width, height: height} = image, clipUI;
1575
+ if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1576
+ canvas.save();
1577
+ clipUI && canvas.clipUI(ui);
1578
+ blendMode && (canvas.blendMode = blendMode);
1579
+ opacity && (canvas.opacity *= opacity);
1580
+ transform && canvas.transform(transform);
1581
+ canvas.drawImage(view, 0, 0, width, height);
1582
+ canvas.restore();
1583
+ } else {
1584
+ if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1585
+ canvas.drawImage(view, 0, 0, width, height);
1586
+ }
1587
+ }
1588
+
1589
+ function getImageRenderScaleData(paint, ui, canvas, _renderOptions) {
1590
+ const scaleData = ui.getRenderScaleData(true, paint.originPaint.scaleFixed), {data: data} = paint;
1591
+ if (canvas) {
1592
+ const {pixelRatio: pixelRatio} = canvas;
1593
+ scaleData.scaleX *= pixelRatio;
1594
+ scaleData.scaleY *= pixelRatio;
1595
+ }
1596
+ if (data && data.scaleX) {
1597
+ scaleData.scaleX *= Math.abs(data.scaleX);
1598
+ scaleData.scaleY *= Math.abs(data.scaleY);
1599
+ }
1600
+ return scaleData;
1615
1601
  }
1616
1602
 
1617
1603
  function recycleImage(attrName, data) {
@@ -1643,8 +1629,12 @@ function recycleImage(attrName, data) {
1643
1629
  const PaintImageModule = {
1644
1630
  image: image,
1645
1631
  checkImage: checkImage,
1646
- createPattern: createPattern,
1632
+ drawImage: drawImage,
1633
+ getImageRenderScaleData: getImageRenderScaleData,
1647
1634
  recycleImage: recycleImage,
1635
+ createPatternTask: createPatternTask,
1636
+ createPattern: createPattern,
1637
+ getPatternFixScale: getPatternFixScale,
1648
1638
  createData: createData,
1649
1639
  getPatternData: getPatternData,
1650
1640
  stretchMode: stretchMode,
@@ -2100,10 +2090,8 @@ function createRows(drawData, content, style) {
2100
2090
  bounds = drawData.bounds;
2101
2091
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
2102
2092
  const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
2103
- const {canvas: canvas} = core.Platform;
2104
- const {width: width, height: height} = bounds;
2105
- const charMode = width || height || __letterSpacing || textCase !== "none";
2106
- if (charMode) {
2093
+ const {canvas: canvas} = core.Platform, {width: width} = bounds;
2094
+ if (style.__isCharMode) {
2107
2095
  const wrap = style.textWrap !== "none";
2108
2096
  const breakAll = style.textWrap === "break";
2109
2097
  paraStart = true;
@@ -2232,12 +2220,19 @@ const TextMode = 2;
2232
2220
  function layoutChar(drawData, style, width, _height) {
2233
2221
  const {rows: rows} = drawData;
2234
2222
  const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
2235
- let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2223
+ const justifyLast = width && textAlign.includes("both");
2224
+ const justify = justifyLast || width && textAlign.includes("justify");
2225
+ const justifyLetter = justify && textAlign.includes("letter");
2226
+ let charX, remainingWidth, addWordWidth, addLetterWidth, indentWidth, mode, wordChar, wordsLength, isLastWord, canJustify;
2236
2227
  rows.forEach(row => {
2237
2228
  if (row.words) {
2238
2229
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2239
- addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2240
- mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2230
+ if (justify) {
2231
+ canJustify = !row.paraEnd || justifyLast;
2232
+ remainingWidth = width - row.width - indentWidth;
2233
+ if (justifyLetter) addLetterWidth = remainingWidth / (row.words.reduce((total, item) => total + item.data.length, 0) - 1); else addWordWidth = wordsLength > 1 ? remainingWidth / (wordsLength - 1) : 0;
2234
+ }
2235
+ mode = letterSpacing || row.isOverflow || justifyLetter ? CharMode : addWordWidth ? WordMode : TextMode;
2241
2236
  if (row.isOverflow && !letterSpacing) row.textMode = true;
2242
2237
  if (mode === TextMode) {
2243
2238
  row.x += indentWidth;
@@ -2255,11 +2250,15 @@ function layoutChar(drawData, style, width, _height) {
2255
2250
  charX = toWordChar(word.data, charX, wordChar);
2256
2251
  if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2257
2252
  } else {
2258
- charX = toChar(word.data, charX, row.data, row.isOverflow);
2253
+ charX = toChar(word.data, charX, row.data, row.isOverflow, canJustify && addLetterWidth);
2259
2254
  }
2260
- if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
2261
- charX += addWordWidth;
2262
- row.width += addWordWidth;
2255
+ if (canJustify) {
2256
+ isLastWord = index === wordsLength - 1;
2257
+ if (addWordWidth) {
2258
+ if (!isLastWord) charX += addWordWidth, row.width += addWordWidth;
2259
+ } else if (addLetterWidth) {
2260
+ row.width += addLetterWidth * (word.data.length - (isLastWord ? 1 : 0));
2261
+ }
2263
2262
  }
2264
2263
  });
2265
2264
  }
@@ -2285,13 +2284,14 @@ function toWordChar(data, charX, wordChar) {
2285
2284
  return charX;
2286
2285
  }
2287
2286
 
2288
- function toChar(data, charX, rowData, isOverflow) {
2287
+ function toChar(data, charX, rowData, isOverflow, addLetterWidth) {
2289
2288
  data.forEach(char => {
2290
2289
  if (isOverflow || char.char !== " ") {
2291
2290
  char.x = charX;
2292
2291
  rowData.push(char);
2293
2292
  }
2294
2293
  charX += char.width;
2294
+ addLetterWidth && (charX += addLetterWidth);
2295
2295
  });
2296
2296
  return charX;
2297
2297
  }
@@ -2433,10 +2433,10 @@ function getDrawData(content, style) {
2433
2433
  let x = 0, y = 0;
2434
2434
  let width = style.__getInput("width") || 0;
2435
2435
  let height = style.__getInput("height") || 0;
2436
- const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2436
+ const {__padding: padding} = style;
2437
2437
  if (padding) {
2438
- if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2439
- if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2438
+ if (width) x = padding[left], width -= padding[right] + padding[left], !width && (width = .01); else if (!style.autoSizeAlign) x = padding[left];
2439
+ if (height) y = padding[top], height -= padding[top] + padding[bottom], !height && (height = .01); else if (!style.autoSizeAlign) y = padding[top];
2440
2440
  }
2441
2441
  const drawData = {
2442
2442
  bounds: {
@@ -2447,14 +2447,14 @@ function getDrawData(content, style) {
2447
2447
  },
2448
2448
  rows: [],
2449
2449
  paraNumber: 0,
2450
- font: core.Platform.canvas.font = __font
2450
+ font: core.Platform.canvas.font = style.__font
2451
2451
  };
2452
2452
  createRows(drawData, content, style);
2453
2453
  if (padding) padAutoText(padding, drawData, style, width, height);
2454
2454
  layoutText(drawData, style);
2455
- layoutChar(drawData, style, width);
2455
+ if (style.__isCharMode) layoutChar(drawData, style, width);
2456
2456
  if (drawData.overflow) clipText(drawData, style, x, width);
2457
- if (textDecoration !== "none") decorationText(drawData, style);
2457
+ if (style.textDecoration !== "none") decorationText(drawData, style);
2458
2458
  return drawData;
2459
2459
  }
2460
2460