@leafer-ui/node 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/node.cjs CHANGED
@@ -804,6 +804,7 @@ class Picker {
804
804
  hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
805
805
  if (child.isBranch) {
806
806
  if (hit || child.__ignoreHitWorld) {
807
+ if (child.isBranchLeaf && child.__.__clipAfterFill && !child.__hitWorld(point)) continue;
807
808
  if (child.topChildren) this.eachFind(child.topChildren, false);
808
809
  this.eachFind(child.children, child.__onlyHitMask);
809
810
  if (child.isBranchLeaf) this.hitChild(child, point);
@@ -884,102 +885,163 @@ core.Platform.render = function(target, canvas, options) {
884
885
  if (options.topList.length) options.topList.forEach(item => item.__render(canvas, topOptions));
885
886
  };
886
887
 
887
- function fillText(ui, canvas) {
888
- const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
889
- if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
890
- let row;
891
- for (let i = 0, len = rows.length; i < len; i++) {
892
- row = rows[i];
893
- if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
894
- canvas.fillText(charData.char, charData.x, row.y);
895
- });
896
- }
897
- if (decorationY) {
898
- const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
899
- if (decorationColor) canvas.fillStyle = decorationColor;
900
- rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
901
- }
902
- }
903
-
904
- function fill(fill, ui, canvas) {
888
+ function fill(fill, ui, canvas, renderOptions) {
905
889
  canvas.fillStyle = fill;
906
- fillPathOrText(ui, canvas);
890
+ fillPathOrText(ui, canvas, renderOptions);
907
891
  }
908
892
 
909
- function fills(fills, ui, canvas) {
910
- let item;
893
+ function fills(fills, ui, canvas, renderOptions) {
894
+ let item, originPaint, countImage;
911
895
  for (let i = 0, len = fills.length; i < len; i++) {
912
- item = fills[i];
896
+ item = fills[i], originPaint = item.originPaint;
913
897
  if (item.image) {
914
- if (draw.PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
898
+ countImage ? countImage++ : countImage = 1;
899
+ if (draw.PaintImage.checkImage(item, !ui.__.__font, ui, canvas, renderOptions)) continue;
915
900
  if (!item.style) {
916
- if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
901
+ if (countImage === 1 && item.image.isPlacehold) ui.drawImagePlaceholder(item, canvas, renderOptions);
917
902
  continue;
918
903
  }
919
904
  }
920
905
  canvas.fillStyle = item.style;
921
- if (item.transform || item.scaleFixed) {
906
+ if (item.transform || originPaint.scaleFixed) {
922
907
  canvas.save();
923
908
  if (item.transform) canvas.transform(item.transform);
924
- if (item.scaleFixed) {
909
+ if (originPaint.scaleFixed) {
925
910
  const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
926
- if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
911
+ if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
927
912
  }
928
- if (item.blendMode) canvas.blendMode = item.blendMode;
929
- fillPathOrText(ui, canvas);
913
+ if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
914
+ fillPathOrText(ui, canvas, renderOptions);
930
915
  canvas.restore();
931
916
  } else {
932
- if (item.blendMode) {
933
- canvas.saveBlendMode(item.blendMode);
934
- fillPathOrText(ui, canvas);
917
+ if (originPaint.blendMode) {
918
+ canvas.saveBlendMode(originPaint.blendMode);
919
+ fillPathOrText(ui, canvas, renderOptions);
935
920
  canvas.restoreBlendMode();
936
- } else fillPathOrText(ui, canvas);
921
+ } else fillPathOrText(ui, canvas, renderOptions);
922
+ }
923
+ }
924
+ }
925
+
926
+ function fillPathOrText(ui, canvas, renderOptions) {
927
+ ui.__.__font ? draw.Paint.fillText(ui, canvas, renderOptions) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
928
+ }
929
+
930
+ function fillText(ui, canvas, _renderOptions) {
931
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
932
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
933
+ let row;
934
+ for (let i = 0, len = rows.length; i < len; i++) {
935
+ row = rows[i];
936
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
937
+ canvas.fillText(charData.char, charData.x, row.y);
938
+ });
939
+ }
940
+ if (decorationY) {
941
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
942
+ if (decorationColor) canvas.fillStyle = decorationColor;
943
+ rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
944
+ }
945
+ }
946
+
947
+ function stroke(stroke, ui, canvas, renderOptions) {
948
+ const data = ui.__;
949
+ if (!data.__strokeWidth) return;
950
+ if (data.__font) {
951
+ draw.Paint.strokeText(stroke, ui, canvas, renderOptions);
952
+ } else {
953
+ switch (data.strokeAlign) {
954
+ case "center":
955
+ drawCenter$1(stroke, 1, ui, canvas, renderOptions);
956
+ break;
957
+
958
+ case "inside":
959
+ drawInside(stroke, ui, canvas, renderOptions);
960
+ break;
961
+
962
+ case "outside":
963
+ drawOutside(stroke, ui, canvas, renderOptions);
964
+ break;
937
965
  }
938
966
  }
939
967
  }
940
968
 
941
- function fillPathOrText(ui, canvas) {
942
- ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
969
+ function strokes(strokes, ui, canvas, renderOptions) {
970
+ draw.Paint.stroke(strokes, ui, canvas, renderOptions);
971
+ }
972
+
973
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas, renderOptions) {
974
+ const data = ui.__;
975
+ if (core.isObject(stroke)) {
976
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas, renderOptions);
977
+ } else {
978
+ canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
979
+ canvas.stroke();
980
+ }
981
+ if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas, renderOptions);
982
+ }
983
+
984
+ function drawInside(stroke, ui, canvas, renderOptions) {
985
+ canvas.save();
986
+ canvas.clipUI(ui);
987
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
988
+ canvas.restore();
989
+ }
990
+
991
+ function drawOutside(stroke, ui, canvas, renderOptions) {
992
+ const data = ui.__;
993
+ if (data.__fillAfterStroke) {
994
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
995
+ } else {
996
+ const {renderBounds: renderBounds} = ui.__layout;
997
+ const out = canvas.getSameCanvas(true, true);
998
+ ui.__drawRenderPath(out);
999
+ drawCenter$1(stroke, 2, ui, out, renderOptions);
1000
+ out.clipUI(data);
1001
+ out.clearWorld(renderBounds);
1002
+ core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1003
+ out.recycle(ui.__nowWorld);
1004
+ }
943
1005
  }
944
1006
 
945
- function strokeText(stroke, ui, canvas) {
1007
+ function strokeText(stroke, ui, canvas, renderOptions) {
946
1008
  switch (ui.__.strokeAlign) {
947
1009
  case "center":
948
- drawCenter$1(stroke, 1, ui, canvas);
1010
+ drawCenter(stroke, 1, ui, canvas, renderOptions);
949
1011
  break;
950
1012
 
951
1013
  case "inside":
952
- drawAlign(stroke, "inside", ui, canvas);
1014
+ drawAlign(stroke, "inside", ui, canvas, renderOptions);
953
1015
  break;
954
1016
 
955
1017
  case "outside":
956
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
1018
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas, renderOptions) : drawAlign(stroke, "outside", ui, canvas, renderOptions);
957
1019
  break;
958
1020
  }
959
1021
  }
960
1022
 
961
- function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
1023
+ function drawCenter(stroke, strokeWidthScale, ui, canvas, renderOptions) {
962
1024
  const data = ui.__;
963
1025
  if (core.isObject(stroke)) {
964
- drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
1026
+ draw.Paint.drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas, renderOptions);
965
1027
  } else {
966
1028
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
967
- drawTextStroke(ui, canvas);
1029
+ draw.Paint.drawTextStroke(ui, canvas, renderOptions);
968
1030
  }
969
1031
  }
970
1032
 
971
- function drawAlign(stroke, align, ui, canvas) {
1033
+ function drawAlign(stroke, align, ui, canvas, renderOptions) {
972
1034
  const out = canvas.getSameCanvas(true, true);
973
1035
  out.font = ui.__.__font;
974
- drawCenter$1(stroke, 2, ui, out);
1036
+ drawCenter(stroke, 2, ui, out, renderOptions);
975
1037
  out.blendMode = align === "outside" ? "destination-out" : "destination-in";
976
- fillText(ui, out);
1038
+ draw.Paint.fillText(ui, out, renderOptions);
977
1039
  out.blendMode = "normal";
978
1040
  core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
979
1041
  out.recycle(ui.__nowWorld);
980
1042
  }
981
1043
 
982
- function drawTextStroke(ui, canvas) {
1044
+ function drawTextStroke(ui, canvas, _renderOptions) {
983
1045
  let row, data = ui.__.__textDrawData;
984
1046
  const {rows: rows, decorationY: decorationY} = data;
985
1047
  for (let i = 0, len = rows.length; i < len; i++) {
@@ -994,89 +1056,29 @@ function drawTextStroke(ui, canvas) {
994
1056
  }
995
1057
  }
996
1058
 
997
- function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
1059
+ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas, renderOptions) {
998
1060
  let item;
999
1061
  const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
1000
1062
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
1001
1063
  for (let i = 0, len = strokes.length; i < len; i++) {
1002
1064
  item = strokes[i];
1003
- if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false)) continue;
1065
+ if (item.image && draw.PaintImage.checkImage(item, false, ui, canvas, renderOptions)) continue;
1004
1066
  if (item.style) {
1005
1067
  if (__hasMultiStrokeStyle) {
1006
1068
  const {strokeStyle: strokeStyle} = item;
1007
1069
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
1008
1070
  } else canvas.strokeStyle = item.style;
1009
- if (item.blendMode) {
1010
- canvas.saveBlendMode(item.blendMode);
1011
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1071
+ if (item.originPaint.blendMode) {
1072
+ canvas.saveBlendMode(item.originPaint.blendMode);
1073
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1012
1074
  canvas.restoreBlendMode();
1013
1075
  } else {
1014
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1076
+ isText ? draw.Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1015
1077
  }
1016
1078
  }
1017
1079
  }
1018
1080
  }
1019
1081
 
1020
- function stroke(stroke, ui, canvas) {
1021
- const data = ui.__;
1022
- if (!data.__strokeWidth) return;
1023
- if (data.__font) {
1024
- strokeText(stroke, ui, canvas);
1025
- } else {
1026
- switch (data.strokeAlign) {
1027
- case "center":
1028
- drawCenter(stroke, 1, ui, canvas);
1029
- break;
1030
-
1031
- case "inside":
1032
- drawInside(stroke, ui, canvas);
1033
- break;
1034
-
1035
- case "outside":
1036
- drawOutside(stroke, ui, canvas);
1037
- break;
1038
- }
1039
- }
1040
- }
1041
-
1042
- function strokes(strokes, ui, canvas) {
1043
- stroke(strokes, ui, canvas);
1044
- }
1045
-
1046
- function drawCenter(stroke, strokeWidthScale, ui, canvas) {
1047
- const data = ui.__;
1048
- if (core.isObject(stroke)) {
1049
- drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
1050
- } else {
1051
- canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1052
- canvas.stroke();
1053
- }
1054
- if (data.__useArrow) draw.Paint.strokeArrow(stroke, ui, canvas);
1055
- }
1056
-
1057
- function drawInside(stroke, ui, canvas) {
1058
- canvas.save();
1059
- canvas.clipUI(ui);
1060
- drawCenter(stroke, 2, ui, canvas);
1061
- canvas.restore();
1062
- }
1063
-
1064
- function drawOutside(stroke, ui, canvas) {
1065
- const data = ui.__;
1066
- if (data.__fillAfterStroke) {
1067
- drawCenter(stroke, 2, ui, canvas);
1068
- } else {
1069
- const {renderBounds: renderBounds} = ui.__layout;
1070
- const out = canvas.getSameCanvas(true, true);
1071
- ui.__drawRenderPath(out);
1072
- drawCenter(stroke, 2, ui, out);
1073
- out.clipUI(data);
1074
- out.clearWorld(renderBounds);
1075
- core.LeafHelper.copyCanvasByWorld(ui, canvas, out);
1076
- out.recycle(ui.__nowWorld);
1077
- }
1078
- }
1079
-
1080
1082
  const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
1081
1083
 
1082
1084
  const tempBounds$1 = {};
@@ -1164,62 +1166,63 @@ function compute(attrName, ui) {
1164
1166
  if (leafPaints.some(item => item.image)) isAlphaPixel = true;
1165
1167
  isTransparent = true;
1166
1168
  }
1167
- }
1168
- if (attrName === "fill") {
1169
- stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1170
- stintSet(data, "__isTransparentFill", isTransparent);
1169
+ if (attrName === "fill") {
1170
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1171
+ stintSet(data, "__isTransparentFill", isTransparent);
1172
+ } else {
1173
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1174
+ stintSet(data, "__isTransparentStroke", isTransparent);
1175
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1176
+ }
1171
1177
  } else {
1172
- stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1173
- stintSet(data, "__isTransparentStroke", isTransparent);
1174
- stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1178
+ data.__removePaint(attrName, false);
1175
1179
  }
1176
1180
  }
1177
1181
 
1178
1182
  function getLeafPaint(attrName, paint, ui) {
1179
1183
  if (!core.isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1180
- let data;
1184
+ let leafPaint;
1181
1185
  const {boxBounds: boxBounds} = ui.__layout;
1182
1186
  switch (paint.type) {
1183
1187
  case "image":
1184
- data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1188
+ leafPaint = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1185
1189
  break;
1186
1190
 
1187
1191
  case "linear":
1188
- data = draw.PaintGradient.linearGradient(paint, boxBounds);
1192
+ leafPaint = draw.PaintGradient.linearGradient(paint, boxBounds);
1189
1193
  break;
1190
1194
 
1191
1195
  case "radial":
1192
- data = draw.PaintGradient.radialGradient(paint, boxBounds);
1196
+ leafPaint = draw.PaintGradient.radialGradient(paint, boxBounds);
1193
1197
  break;
1194
1198
 
1195
1199
  case "angular":
1196
- data = draw.PaintGradient.conicGradient(paint, boxBounds);
1200
+ leafPaint = draw.PaintGradient.conicGradient(paint, boxBounds);
1197
1201
  break;
1198
1202
 
1199
1203
  case "solid":
1200
1204
  const {type: type, color: color, opacity: opacity} = paint;
1201
- data = {
1205
+ leafPaint = {
1202
1206
  type: type,
1203
1207
  style: draw.ColorConvert.string(color, opacity)
1204
1208
  };
1205
1209
  break;
1206
1210
 
1207
1211
  default:
1208
- if (!core.isUndefined(paint.r)) data = {
1212
+ if (!core.isUndefined(paint.r)) leafPaint = {
1209
1213
  type: "solid",
1210
1214
  style: draw.ColorConvert.string(paint)
1211
1215
  };
1212
1216
  }
1213
- if (data) {
1214
- if (core.isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
1217
+ if (leafPaint) {
1218
+ leafPaint.originPaint = paint;
1219
+ if (core.isString(leafPaint.style) && hasTransparent$1(leafPaint.style)) leafPaint.isTransparent = true;
1215
1220
  if (paint.style) {
1216
1221
  if (paint.style.strokeWidth === 0) return undefined;
1217
- data.strokeStyle = paint.style;
1222
+ leafPaint.strokeStyle = paint.style;
1218
1223
  }
1219
- if (paint.editing) data.editing = paint.editing;
1220
- if (paint.blendMode) data.blendMode = paint.blendMode;
1221
1224
  }
1222
- return data;
1225
+ return leafPaint;
1223
1226
  }
1224
1227
 
1225
1228
  const PaintModule = {
@@ -1232,88 +1235,118 @@ const PaintModule = {
1232
1235
  strokes: strokes,
1233
1236
  strokeText: strokeText,
1234
1237
  drawTextStroke: drawTextStroke,
1238
+ drawStrokesStyle: drawStrokesStyle,
1235
1239
  shape: shape
1236
1240
  };
1237
1241
 
1238
- let origin = {}, tempMatrix$1 = core.getMatrixData();
1242
+ let cache, box = new core.Bounds;
1239
1243
 
1240
- 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;
1244
+ const {isSame: isSame} = core.BoundsHelper;
1241
1245
 
1242
- function stretchMode(data, box, scaleX, scaleY) {
1243
- const transform = get$3();
1244
- translate$1(transform, box.x, box.y);
1245
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1246
- data.transform = transform;
1246
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1247
+ let leafPaint, event;
1248
+ const image = core.ImageManager.get(paint);
1249
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1250
+ leafPaint = cache.leafPaint;
1251
+ } else {
1252
+ leafPaint = {
1253
+ type: paint.type,
1254
+ image: image
1255
+ };
1256
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1257
+ cache = image.use > 1 ? {
1258
+ leafPaint: leafPaint,
1259
+ paint: paint,
1260
+ boxBounds: box.set(boxBounds)
1261
+ } : null;
1262
+ }
1263
+ if (firstUse || image.loading) event = {
1264
+ image: image,
1265
+ attrName: attrName,
1266
+ attrValue: paint
1267
+ };
1268
+ if (image.ready) {
1269
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1270
+ if (firstUse) {
1271
+ onLoad(ui, event);
1272
+ onLoadSuccess(ui, event);
1273
+ }
1274
+ } else if (image.error) {
1275
+ if (firstUse) onLoadError(ui, event, image.error);
1276
+ } else {
1277
+ if (firstUse) {
1278
+ ignoreRender(ui, true);
1279
+ onLoad(ui, event);
1280
+ }
1281
+ leafPaint.loadId = image.load(() => {
1282
+ ignoreRender(ui, false);
1283
+ if (!ui.destroyed) {
1284
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1285
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1286
+ ui.forceUpdate("surface");
1287
+ }
1288
+ onLoadSuccess(ui, event);
1289
+ }
1290
+ leafPaint.loadId = undefined;
1291
+ }, error => {
1292
+ ignoreRender(ui, false);
1293
+ onLoadError(ui, event, error);
1294
+ leafPaint.loadId = undefined;
1295
+ });
1296
+ if (ui.placeholderColor) {
1297
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1298
+ if (!image.ready) {
1299
+ image.isPlacehold = true;
1300
+ ui.forceUpdate("surface");
1301
+ }
1302
+ }, ui.placeholderDelay);
1303
+ }
1304
+ }
1305
+ return leafPaint;
1247
1306
  }
1248
1307
 
1249
- function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1250
- const transform = get$3();
1251
- translate$1(transform, box.x + x, box.y + y);
1252
- scaleHelper(transform, scaleX, scaleY);
1253
- if (rotation) rotateOfOuter$1(transform, {
1254
- x: box.x + box.width / 2,
1255
- y: box.y + box.height / 2
1256
- }, rotation);
1257
- data.transform = transform;
1308
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1309
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1310
+ const data = ui.__;
1311
+ data.__naturalWidth = image.width / data.pixelRatio;
1312
+ data.__naturalHeight = image.height / data.pixelRatio;
1313
+ if (data.__autoSide) {
1314
+ ui.forceUpdate("width");
1315
+ if (ui.__proxyData) {
1316
+ ui.setProxyAttr("width", data.width);
1317
+ ui.setProxyAttr("height", data.height);
1318
+ }
1319
+ return false;
1320
+ }
1321
+ }
1322
+ if (!leafPaint.data) draw.PaintImage.createData(leafPaint, image, paint, boxBounds);
1323
+ return true;
1258
1324
  }
1259
1325
 
1260
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1261
- const transform = get$3();
1262
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1263
- if (clipScaleX) {
1264
- if (rotation || skew) {
1265
- set(tempMatrix$1);
1266
- scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1267
- multiplyParent(transform, tempMatrix$1);
1268
- } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1269
- }
1270
- data.transform = transform;
1326
+ function onLoad(ui, event) {
1327
+ emit(ui, core.ImageEvent.LOAD, event);
1271
1328
  }
1272
1329
 
1273
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1274
- const transform = get$3();
1275
- if (freeTransform) {
1276
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1277
- } else {
1278
- if (rotation) {
1279
- if (align === "center") {
1280
- rotateOfOuter$1(transform, {
1281
- x: width / 2,
1282
- y: height / 2
1283
- }, rotation);
1284
- } else {
1285
- rotate(transform, rotation);
1286
- switch (rotation) {
1287
- case 90:
1288
- translate$1(transform, height, 0);
1289
- break;
1330
+ function onLoadSuccess(ui, event) {
1331
+ emit(ui, core.ImageEvent.LOADED, event);
1332
+ }
1290
1333
 
1291
- case 180:
1292
- translate$1(transform, width, height);
1293
- break;
1334
+ function onLoadError(ui, event, error) {
1335
+ event.error = error;
1336
+ ui.forceUpdate("surface");
1337
+ emit(ui, core.ImageEvent.ERROR, event);
1338
+ }
1294
1339
 
1295
- case 270:
1296
- translate$1(transform, 0, width);
1297
- break;
1298
- }
1299
- }
1300
- }
1301
- origin.x = box.x + x;
1302
- origin.y = box.y + y;
1303
- translate$1(transform, origin.x, origin.y);
1304
- if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1305
- }
1306
- data.transform = transform;
1340
+ function emit(ui, type, data) {
1341
+ if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1307
1342
  }
1308
1343
 
1309
- function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1310
- if (rotation) rotate(transform, rotation);
1311
- if (skew) skewHelper(transform, skew.x, skew.y);
1312
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1313
- translate$1(transform, box.x + x, box.y + y);
1344
+ function ignoreRender(ui, value) {
1345
+ const {leafer: leafer} = ui;
1346
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1314
1347
  }
1315
1348
 
1316
- const {get: get$2, translate: translate} = core.MatrixHelper;
1349
+ const {get: get$3, translate: translate$1} = core.MatrixHelper;
1317
1350
 
1318
1351
  const tempBox = new core.Bounds;
1319
1352
 
@@ -1322,17 +1355,13 @@ const tempScaleData = {};
1322
1355
  const tempImage = {};
1323
1356
 
1324
1357
  function createData(leafPaint, image, paint, box) {
1325
- const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1326
- if (changeful) leafPaint.changeful = changeful;
1327
- if (sync) leafPaint.sync = sync;
1328
- if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1329
- leafPaint.data = getPatternData(paint, box, image);
1358
+ leafPaint.data = draw.PaintImage.getPatternData(paint, box, image);
1330
1359
  }
1331
1360
 
1332
1361
  function getPatternData(paint, box, image) {
1333
1362
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1334
1363
  if (paint.mode === "strench") paint.mode = "stretch";
1335
- let {width: width, height: height} = image;
1364
+ const {width: width, height: height} = image;
1336
1365
  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;
1337
1366
  const sameBox = box.width === width && box.height === height;
1338
1367
  const data = {
@@ -1363,8 +1392,8 @@ function getPatternData(paint, box, image) {
1363
1392
  case "stretch":
1364
1393
  if (!sameBox) {
1365
1394
  scaleX = box.width / width, scaleY = box.height / height;
1366
- stretchMode(data, box, scaleX, scaleY);
1367
- }
1395
+ draw.PaintImage.stretchMode(data, box, scaleX, scaleY);
1396
+ } else if (scaleX) scaleX = scaleY = undefined;
1368
1397
  break;
1369
1398
 
1370
1399
  case "normal":
@@ -1372,13 +1401,13 @@ function getPatternData(paint, box, image) {
1372
1401
  if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1373
1402
  let clipScaleX, clipScaleY;
1374
1403
  if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1375
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1404
+ draw.PaintImage.clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1376
1405
  if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : clipScaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1377
1406
  }
1378
1407
  break;
1379
1408
 
1380
1409
  case "repeat":
1381
- if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1410
+ if (!sameBox || scaleX || rotation || skew) draw.PaintImage.repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1382
1411
  if (!repeat) data.repeat = "repeat";
1383
1412
  const count = core.isObject(repeat);
1384
1413
  if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
@@ -1387,18 +1416,16 @@ function getPatternData(paint, box, image) {
1387
1416
  case "fit":
1388
1417
  case "cover":
1389
1418
  default:
1390
- if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1419
+ if (scaleX) draw.PaintImage.fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1391
1420
  }
1392
1421
  if (!data.transform) {
1393
- if (box.x || box.y) translate(data.transform = get$2(), box.x, box.y);
1422
+ if (box.x || box.y) translate$1(data.transform = get$3(), box.x, box.y);
1394
1423
  }
1395
- data.width = width;
1396
- data.height = height;
1397
1424
  if (scaleX) {
1398
1425
  data.scaleX = scaleX;
1399
1426
  data.scaleY = scaleY;
1400
1427
  }
1401
- if (opacity) data.opacity = opacity;
1428
+ if (opacity && opacity < 1) data.opacity = opacity;
1402
1429
  if (filters) data.filters = filters;
1403
1430
  if (repeat) data.repeat = core.isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1404
1431
  return data;
@@ -1420,234 +1447,194 @@ function getGapValue(gap, size, totalSize, rows) {
1420
1447
  return gap === "auto" ? value < 0 ? 0 : value : value;
1421
1448
  }
1422
1449
 
1423
- let cache, box = new core.Bounds;
1450
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
1424
1451
 
1425
- const {isSame: isSame} = core.BoundsHelper;
1452
+ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1426
1453
 
1427
- function image(ui, attrName, paint, boxBounds, firstUse) {
1428
- let leafPaint, event;
1429
- const image = core.ImageManager.get(paint);
1430
- if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1431
- leafPaint = cache.leafPaint;
1432
- } else {
1433
- leafPaint = {
1434
- type: paint.type,
1435
- image: image
1436
- };
1437
- if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1438
- cache = image.use > 1 ? {
1439
- leafPaint: leafPaint,
1440
- paint: paint,
1441
- boxBounds: box.set(boxBounds)
1442
- } : null;
1443
- }
1444
- if (firstUse || image.loading) event = {
1445
- image: image,
1446
- attrName: attrName,
1447
- attrValue: paint
1448
- };
1449
- if (image.ready) {
1450
- checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1451
- if (firstUse) {
1452
- onLoad(ui, event);
1453
- onLoadSuccess(ui, event);
1454
- }
1455
- } else if (image.error) {
1456
- if (firstUse) onLoadError(ui, event, image.error);
1457
- } else {
1458
- if (firstUse) {
1459
- ignoreRender(ui, true);
1460
- onLoad(ui, event);
1461
- }
1462
- leafPaint.loadId = image.load(() => {
1463
- ignoreRender(ui, false);
1464
- if (!ui.destroyed) {
1465
- if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1466
- if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1467
- ui.forceUpdate("surface");
1468
- }
1469
- onLoadSuccess(ui, event);
1470
- }
1471
- leafPaint.loadId = undefined;
1472
- }, error => {
1473
- ignoreRender(ui, false);
1474
- onLoadError(ui, event, error);
1475
- leafPaint.loadId = undefined;
1476
- });
1477
- if (ui.placeholderColor) {
1478
- if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1479
- if (!image.ready) {
1480
- image.isPlacehold = true;
1481
- ui.forceUpdate("surface");
1482
- }
1483
- }, ui.placeholderDelay);
1484
- }
1485
- }
1486
- return leafPaint;
1454
+ function stretchMode(data, box, scaleX, scaleY) {
1455
+ const transform = get$2(), {x: x, y: y} = box;
1456
+ if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1457
+ scaleHelper(transform, scaleX, scaleY);
1458
+ data.transform = transform;
1487
1459
  }
1488
1460
 
1489
- function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1490
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1491
- const data = ui.__;
1492
- data.__naturalWidth = image.width / data.pixelRatio;
1493
- data.__naturalHeight = image.height / data.pixelRatio;
1494
- if (data.__autoSide) {
1495
- ui.forceUpdate("width");
1496
- if (ui.__proxyData) {
1497
- ui.setProxyAttr("width", data.width);
1498
- ui.setProxyAttr("height", data.height);
1499
- }
1500
- return false;
1501
- }
1502
- }
1503
- if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1504
- return true;
1461
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1462
+ const transform = get$2();
1463
+ translate(transform, box.x + x, box.y + y);
1464
+ scaleHelper(transform, scaleX, scaleY);
1465
+ if (rotation) rotateOfOuter$1(transform, {
1466
+ x: box.x + box.width / 2,
1467
+ y: box.y + box.height / 2
1468
+ }, rotation);
1469
+ data.transform = transform;
1505
1470
  }
1506
1471
 
1507
- function onLoad(ui, event) {
1508
- emit(ui, core.ImageEvent.LOAD, event);
1472
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1473
+ const transform = get$2();
1474
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1475
+ if (clipScaleX) {
1476
+ if (rotation || skew) {
1477
+ set(tempMatrix$1);
1478
+ scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1479
+ multiplyParent(transform, tempMatrix$1);
1480
+ } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1481
+ }
1482
+ data.transform = transform;
1509
1483
  }
1510
1484
 
1511
- function onLoadSuccess(ui, event) {
1512
- emit(ui, core.ImageEvent.LOADED, event);
1513
- }
1485
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1486
+ const transform = get$2();
1487
+ if (freeTransform) {
1488
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1489
+ } else {
1490
+ if (rotation) {
1491
+ if (align === "center") {
1492
+ rotateOfOuter$1(transform, {
1493
+ x: width / 2,
1494
+ y: height / 2
1495
+ }, rotation);
1496
+ } else {
1497
+ rotate(transform, rotation);
1498
+ switch (rotation) {
1499
+ case 90:
1500
+ translate(transform, height, 0);
1501
+ break;
1514
1502
 
1515
- function onLoadError(ui, event, error) {
1516
- event.error = error;
1517
- ui.forceUpdate("surface");
1518
- emit(ui, core.ImageEvent.ERROR, event);
1519
- }
1503
+ case 180:
1504
+ translate(transform, width, height);
1505
+ break;
1520
1506
 
1521
- function emit(ui, type, data) {
1522
- if (ui.hasEvent(type)) ui.emitEvent(new core.ImageEvent(type, data));
1507
+ case 270:
1508
+ translate(transform, 0, width);
1509
+ break;
1510
+ }
1511
+ }
1512
+ }
1513
+ origin.x = box.x + x;
1514
+ origin.y = box.y + y;
1515
+ translate(transform, origin.x, origin.y);
1516
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1517
+ }
1518
+ data.transform = transform;
1523
1519
  }
1524
1520
 
1525
- function ignoreRender(ui, value) {
1526
- const {leafer: leafer} = ui;
1527
- if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1521
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1522
+ if (rotation) rotate(transform, rotation);
1523
+ if (skew) skewHelper(transform, skew.x, skew.y);
1524
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1525
+ translate(transform, box.x + x, box.y + y);
1528
1526
  }
1529
1527
 
1530
1528
  const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1531
1529
 
1532
- const {floor: floor, ceil: ceil, max: max$1, abs: abs$1} = Math;
1530
+ const {getFloorScale: getFloorScale} = core.MathHelper, {abs: abs$1} = Math;
1533
1531
 
1534
- function createPattern(ui, paint, pixelRatio) {
1535
- let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1536
- const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1532
+ function createPatternTask(paint, ui, canvas, renderOptions) {
1533
+ if (!paint.patternTask) {
1534
+ paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1535
+ paint.patternTask = null;
1536
+ if (canvas.bounds.hit(ui.__nowWorld)) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions);
1537
+ ui.forceUpdate("surface");
1538
+ }), 300);
1539
+ }
1540
+ }
1541
+
1542
+ function createPattern(paint, ui, canvas, renderOptions) {
1543
+ let {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1537
1544
  if (paint.patternId !== id && !ui.destroyed) {
1538
- const {image: image, data: data} = paint;
1539
- let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1540
- scaleX *= pixelRatio;
1541
- scaleY *= pixelRatio;
1542
- if (sx) {
1543
- sx = abs$1(sx);
1544
- sy = abs$1(sy);
1545
- imageMatrix = get$1();
1546
- copy$1(imageMatrix, transform);
1547
- scale(imageMatrix, 1 / sx, 1 / sy);
1548
- scaleX *= sx;
1549
- scaleY *= sy;
1550
- }
1551
- width *= scaleX;
1552
- height *= scaleY;
1553
- const size = width * height;
1554
- if (!repeat) {
1555
- if (size > core.Platform.image.maxCacheSize) return false;
1556
- }
1557
- let maxSize = core.Platform.image.maxPatternSize;
1558
- if (image.isSVG) {
1559
- const ws = width / image.width;
1560
- if (ws > 1) imageScale = ws / ceil(ws);
1561
- } else {
1562
- const imageSize = image.width * image.height;
1563
- if (maxSize > imageSize) maxSize = imageSize;
1564
- }
1565
- if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1566
- if (imageScale) {
1567
- scaleX /= imageScale;
1568
- scaleY /= imageScale;
1569
- width /= imageScale;
1570
- height /= imageScale;
1571
- }
1572
- if (sx) {
1573
- scaleX /= sx;
1574
- scaleY /= sy;
1575
- }
1576
- const xGap = gap && gap.x * scaleX;
1577
- const yGap = gap && gap.y * scaleY;
1578
- if (transform || scaleX !== 1 || scaleY !== 1) {
1579
- const canvasWidth = width + (xGap || 0);
1580
- const canvasHeight = height + (yGap || 0);
1581
- scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1582
- scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1583
- if (!imageMatrix) {
1545
+ if (!(core.Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1546
+ const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = draw.PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1547
+ let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1548
+ if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1549
+ width *= scaleX;
1550
+ height *= scaleY;
1551
+ if (gap) {
1552
+ xGap = gap.x * scaleX / abs$1(data.scaleX || 1);
1553
+ yGap = gap.y * scaleY / abs$1(data.scaleY || 1);
1554
+ }
1555
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1556
+ scaleX *= getFloorScale(width + (xGap || 0));
1557
+ scaleY *= getFloorScale(height + (yGap || 0));
1584
1558
  imageMatrix = get$1();
1585
1559
  if (transform) copy$1(imageMatrix, transform);
1560
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1586
1561
  }
1587
- scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1562
+ const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1563
+ const pattern = image.getPattern(imageCanvas, data.repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1564
+ paint.style = pattern;
1565
+ paint.patternId = id;
1588
1566
  }
1589
- const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1590
- const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1591
- paint.style = pattern;
1592
- paint.patternId = id;
1593
- return true;
1567
+ }
1568
+ }
1569
+
1570
+ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1571
+ const {image: image} = paint;
1572
+ let fixScale, maxSize = core.Platform.image.maxPatternSize, imageSize = image.width * image.height;
1573
+ if (image.isSVG) {
1574
+ if (imageScaleX > 1) fixScale = Math.ceil(imageScaleX) / imageScaleX;
1594
1575
  } else {
1595
- return false;
1576
+ if (maxSize > imageSize) maxSize = imageSize;
1596
1577
  }
1578
+ if ((imageSize *= imageScaleX * imageScaleY) > maxSize) fixScale = Math.sqrt(maxSize / imageSize);
1579
+ return fixScale;
1597
1580
  }
1598
1581
 
1599
- function checkImage(ui, canvas, paint, allowDraw) {
1600
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1601
- const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1602
- if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !draw.Export.running) {
1582
+ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1583
+ const {scaleX: scaleX, scaleY: scaleY} = draw.PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1584
+ const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting} = renderOptions;
1585
+ if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting) {
1603
1586
  return false;
1604
1587
  } else {
1605
- if (allowDraw) {
1588
+ if (drawImage) {
1606
1589
  if (data.repeat) {
1607
- allowDraw = false;
1608
- } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1609
- let {width: width, height: height} = data;
1610
- width *= scaleX * pixelRatio;
1611
- height *= scaleY * pixelRatio;
1612
- if (data.scaleX) {
1613
- width *= data.scaleX;
1614
- height *= data.scaleY;
1615
- }
1616
- allowDraw = width * height > core.Platform.image.maxCacheSize;
1590
+ drawImage = false;
1591
+ } else if (!(originPaint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || exporting)) {
1592
+ drawImage = core.Platform.image.isLarge(image, scaleX, scaleY);
1617
1593
  }
1618
1594
  }
1619
- if (allowDraw) {
1595
+ if (drawImage) {
1620
1596
  if (ui.__.__isFastShadow) {
1621
1597
  canvas.fillStyle = paint.style || "#000";
1622
1598
  canvas.fill();
1623
1599
  }
1624
- drawImage(ui, canvas, paint, data);
1600
+ draw.PaintImage.drawImage(paint, scaleX, scaleY, ui, canvas, renderOptions);
1625
1601
  return true;
1626
1602
  } else {
1627
- if (!paint.style || paint.sync || draw.Export.running) {
1628
- createPattern(ui, paint, pixelRatio);
1629
- } else {
1630
- if (!paint.patternTask) {
1631
- paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1632
- paint.patternTask = null;
1633
- if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1634
- ui.forceUpdate("surface");
1635
- }), 300);
1636
- }
1637
- }
1603
+ if (!paint.style || originPaint.sync || exporting) draw.PaintImage.createPattern(paint, ui, canvas, renderOptions); else draw.PaintImage.createPatternTask(paint, ui, canvas, renderOptions);
1638
1604
  return false;
1639
1605
  }
1640
1606
  }
1641
1607
  }
1642
1608
 
1643
- function drawImage(ui, canvas, paint, data) {
1644
- canvas.save();
1645
- canvas.clipUI(ui);
1646
- if (paint.blendMode) canvas.blendMode = paint.blendMode;
1647
- if (data.opacity) canvas.opacity *= data.opacity;
1648
- if (data.transform) canvas.transform(data.transform);
1649
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1650
- canvas.restore();
1609
+ function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1610
+ const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1611
+ let {width: width, height: height} = image, clipUI;
1612
+ if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1613
+ canvas.save();
1614
+ clipUI && canvas.clipUI(ui);
1615
+ blendMode && (canvas.blendMode = blendMode);
1616
+ opacity && (canvas.opacity *= opacity);
1617
+ transform && canvas.transform(transform);
1618
+ canvas.drawImage(view, 0, 0, width, height);
1619
+ canvas.restore();
1620
+ } else {
1621
+ if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1622
+ canvas.drawImage(view, 0, 0, width, height);
1623
+ }
1624
+ }
1625
+
1626
+ function getImageRenderScaleData(paint, ui, canvas, _renderOptions) {
1627
+ const scaleData = ui.getRenderScaleData(true, paint.originPaint.scaleFixed), {data: data} = paint;
1628
+ if (canvas) {
1629
+ const {pixelRatio: pixelRatio} = canvas;
1630
+ scaleData.scaleX *= pixelRatio;
1631
+ scaleData.scaleY *= pixelRatio;
1632
+ }
1633
+ if (data && data.scaleX) {
1634
+ scaleData.scaleX *= Math.abs(data.scaleX);
1635
+ scaleData.scaleY *= Math.abs(data.scaleY);
1636
+ }
1637
+ return scaleData;
1651
1638
  }
1652
1639
 
1653
1640
  function recycleImage(attrName, data) {
@@ -1679,8 +1666,12 @@ function recycleImage(attrName, data) {
1679
1666
  const PaintImageModule = {
1680
1667
  image: image,
1681
1668
  checkImage: checkImage,
1682
- createPattern: createPattern,
1669
+ drawImage: drawImage,
1670
+ getImageRenderScaleData: getImageRenderScaleData,
1683
1671
  recycleImage: recycleImage,
1672
+ createPatternTask: createPatternTask,
1673
+ createPattern: createPattern,
1674
+ getPatternFixScale: getPatternFixScale,
1684
1675
  createData: createData,
1685
1676
  getPatternData: getPatternData,
1686
1677
  stretchMode: stretchMode,
@@ -2136,10 +2127,8 @@ function createRows(drawData, content, style) {
2136
2127
  bounds = drawData.bounds;
2137
2128
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
2138
2129
  const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
2139
- const {canvas: canvas} = core.Platform;
2140
- const {width: width, height: height} = bounds;
2141
- const charMode = width || height || __letterSpacing || textCase !== "none";
2142
- if (charMode) {
2130
+ const {canvas: canvas} = core.Platform, {width: width} = bounds;
2131
+ if (style.__isCharMode) {
2143
2132
  const wrap = style.textWrap !== "none";
2144
2133
  const breakAll = style.textWrap === "break";
2145
2134
  paraStart = true;
@@ -2268,12 +2257,19 @@ const TextMode = 2;
2268
2257
  function layoutChar(drawData, style, width, _height) {
2269
2258
  const {rows: rows} = drawData;
2270
2259
  const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
2271
- let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2260
+ const justifyLast = width && textAlign.includes("both");
2261
+ const justify = justifyLast || width && textAlign.includes("justify");
2262
+ const justifyLetter = justify && textAlign.includes("letter");
2263
+ let charX, remainingWidth, addWordWidth, addLetterWidth, indentWidth, mode, wordChar, wordsLength, isLastWord, canJustify;
2272
2264
  rows.forEach(row => {
2273
2265
  if (row.words) {
2274
2266
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2275
- addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2276
- mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2267
+ if (justify) {
2268
+ canJustify = !row.paraEnd || justifyLast;
2269
+ remainingWidth = width - row.width - indentWidth;
2270
+ if (justifyLetter) addLetterWidth = remainingWidth / (row.words.reduce((total, item) => total + item.data.length, 0) - 1); else addWordWidth = wordsLength > 1 ? remainingWidth / (wordsLength - 1) : 0;
2271
+ }
2272
+ mode = letterSpacing || row.isOverflow || justifyLetter ? CharMode : addWordWidth ? WordMode : TextMode;
2277
2273
  if (row.isOverflow && !letterSpacing) row.textMode = true;
2278
2274
  if (mode === TextMode) {
2279
2275
  row.x += indentWidth;
@@ -2291,11 +2287,15 @@ function layoutChar(drawData, style, width, _height) {
2291
2287
  charX = toWordChar(word.data, charX, wordChar);
2292
2288
  if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2293
2289
  } else {
2294
- charX = toChar(word.data, charX, row.data, row.isOverflow);
2290
+ charX = toChar(word.data, charX, row.data, row.isOverflow, canJustify && addLetterWidth);
2295
2291
  }
2296
- if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
2297
- charX += addWordWidth;
2298
- row.width += addWordWidth;
2292
+ if (canJustify) {
2293
+ isLastWord = index === wordsLength - 1;
2294
+ if (addWordWidth) {
2295
+ if (!isLastWord) charX += addWordWidth, row.width += addWordWidth;
2296
+ } else if (addLetterWidth) {
2297
+ row.width += addLetterWidth * (word.data.length - (isLastWord ? 1 : 0));
2298
+ }
2299
2299
  }
2300
2300
  });
2301
2301
  }
@@ -2321,13 +2321,14 @@ function toWordChar(data, charX, wordChar) {
2321
2321
  return charX;
2322
2322
  }
2323
2323
 
2324
- function toChar(data, charX, rowData, isOverflow) {
2324
+ function toChar(data, charX, rowData, isOverflow, addLetterWidth) {
2325
2325
  data.forEach(char => {
2326
2326
  if (isOverflow || char.char !== " ") {
2327
2327
  char.x = charX;
2328
2328
  rowData.push(char);
2329
2329
  }
2330
2330
  charX += char.width;
2331
+ addLetterWidth && (charX += addLetterWidth);
2331
2332
  });
2332
2333
  return charX;
2333
2334
  }
@@ -2469,10 +2470,10 @@ function getDrawData(content, style) {
2469
2470
  let x = 0, y = 0;
2470
2471
  let width = style.__getInput("width") || 0;
2471
2472
  let height = style.__getInput("height") || 0;
2472
- const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2473
+ const {__padding: padding} = style;
2473
2474
  if (padding) {
2474
- if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2475
- if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2475
+ if (width) x = padding[left], width -= padding[right] + padding[left], !width && (width = .01); else if (!style.autoSizeAlign) x = padding[left];
2476
+ if (height) y = padding[top], height -= padding[top] + padding[bottom], !height && (height = .01); else if (!style.autoSizeAlign) y = padding[top];
2476
2477
  }
2477
2478
  const drawData = {
2478
2479
  bounds: {
@@ -2483,14 +2484,14 @@ function getDrawData(content, style) {
2483
2484
  },
2484
2485
  rows: [],
2485
2486
  paraNumber: 0,
2486
- font: core.Platform.canvas.font = __font
2487
+ font: core.Platform.canvas.font = style.__font
2487
2488
  };
2488
2489
  createRows(drawData, content, style);
2489
2490
  if (padding) padAutoText(padding, drawData, style, width, height);
2490
2491
  layoutText(drawData, style);
2491
- layoutChar(drawData, style, width);
2492
+ if (style.__isCharMode) layoutChar(drawData, style, width);
2492
2493
  if (drawData.overflow) clipText(drawData, style, x, width);
2493
- if (textDecoration !== "none") decorationText(drawData, style);
2494
+ if (style.textDecoration !== "none") decorationText(drawData, style);
2494
2495
  return drawData;
2495
2496
  }
2496
2497