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