@leafer-ui/miniapp 1.9.12 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { LeaferCanvasBase, isString, Platform, isNumber, canvasPatch, DataHelper, canvasSizeAttrs, isUndefined, ResizeEvent, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Plugin, isObject, FourNumberHelper, Matrix, getMatrixData, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from "@leafer/core";
1
+ import { LeaferCanvasBase, isString, Platform, isNumber, canvasPatch, DataHelper, canvasSizeAttrs, isUndefined, ResizeEvent, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Plugin, isObject, FourNumberHelper, Matrix, ImageEvent, MatrixHelper, MathHelper, AlignHelper, PointHelper, getMatrixData, AroundHelper, Direction4 } from "@leafer/core";
2
2
 
3
3
  export * from "@leafer/core";
4
4
 
@@ -8,7 +8,7 @@ import { InteractionHelper, InteractionBase, isUndefined as isUndefined$1, HitCa
8
8
 
9
9
  export * from "@leafer-ui/core";
10
10
 
11
- import { PaintImage, Paint, ColorConvert, PaintGradient, Export, Effect, Group, TextConvert, Leafer } from "@leafer-ui/draw";
11
+ import { Paint, PaintImage, ColorConvert, PaintGradient, Effect, Group, TextConvert, Leafer } from "@leafer-ui/draw";
12
12
 
13
13
  class LeaferCanvas extends LeaferCanvasBase {
14
14
  get allowBackgroundColor() {
@@ -936,6 +936,7 @@ class Picker {
936
936
  hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
937
937
  if (child.isBranch) {
938
938
  if (hit || child.__ignoreHitWorld) {
939
+ if (child.isBranchLeaf && child.__.__clipAfterFill && !child.__hitWorld(point)) continue;
939
940
  if (child.topChildren) this.eachFind(child.topChildren, false);
940
941
  this.eachFind(child.children, child.__onlyHitMask);
941
942
  if (child.isBranchLeaf) this.hitChild(child, point);
@@ -1128,102 +1129,163 @@ class Interaction extends InteractionBase {
1128
1129
  }
1129
1130
  }
1130
1131
 
1131
- function fillText(ui, canvas) {
1132
- const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
1133
- if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
1134
- let row;
1135
- for (let i = 0, len = rows.length; i < len; i++) {
1136
- row = rows[i];
1137
- if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
1138
- canvas.fillText(charData.char, charData.x, row.y);
1139
- });
1140
- }
1141
- if (decorationY) {
1142
- const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
1143
- if (decorationColor) canvas.fillStyle = decorationColor;
1144
- rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
1145
- }
1146
- }
1147
-
1148
- function fill(fill, ui, canvas) {
1132
+ function fill(fill, ui, canvas, renderOptions) {
1149
1133
  canvas.fillStyle = fill;
1150
- fillPathOrText(ui, canvas);
1134
+ fillPathOrText(ui, canvas, renderOptions);
1151
1135
  }
1152
1136
 
1153
- function fills(fills, ui, canvas) {
1154
- let item;
1137
+ function fills(fills, ui, canvas, renderOptions) {
1138
+ let item, originPaint, countImage;
1155
1139
  for (let i = 0, len = fills.length; i < len; i++) {
1156
- item = fills[i];
1140
+ item = fills[i], originPaint = item.originPaint;
1157
1141
  if (item.image) {
1158
- if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
1142
+ countImage ? countImage++ : countImage = 1;
1143
+ if (PaintImage.checkImage(item, !ui.__.__font, ui, canvas, renderOptions)) continue;
1159
1144
  if (!item.style) {
1160
- if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
1145
+ if (countImage === 1 && item.image.isPlacehold) ui.drawImagePlaceholder(item, canvas, renderOptions);
1161
1146
  continue;
1162
1147
  }
1163
1148
  }
1164
1149
  canvas.fillStyle = item.style;
1165
- if (item.transform || item.scaleFixed) {
1150
+ if (item.transform || originPaint.scaleFixed) {
1166
1151
  canvas.save();
1167
1152
  if (item.transform) canvas.transform(item.transform);
1168
- if (item.scaleFixed) {
1153
+ if (originPaint.scaleFixed) {
1169
1154
  const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
1170
- if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
1155
+ if (originPaint.scaleFixed === true || originPaint.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
1171
1156
  }
1172
- if (item.blendMode) canvas.blendMode = item.blendMode;
1173
- fillPathOrText(ui, canvas);
1157
+ if (originPaint.blendMode) canvas.blendMode = originPaint.blendMode;
1158
+ fillPathOrText(ui, canvas, renderOptions);
1174
1159
  canvas.restore();
1175
1160
  } else {
1176
- if (item.blendMode) {
1177
- canvas.saveBlendMode(item.blendMode);
1178
- fillPathOrText(ui, canvas);
1161
+ if (originPaint.blendMode) {
1162
+ canvas.saveBlendMode(originPaint.blendMode);
1163
+ fillPathOrText(ui, canvas, renderOptions);
1179
1164
  canvas.restoreBlendMode();
1180
- } else fillPathOrText(ui, canvas);
1165
+ } else fillPathOrText(ui, canvas, renderOptions);
1181
1166
  }
1182
1167
  }
1183
1168
  }
1184
1169
 
1185
- function fillPathOrText(ui, canvas) {
1186
- ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
1170
+ function fillPathOrText(ui, canvas, renderOptions) {
1171
+ ui.__.__font ? Paint.fillText(ui, canvas, renderOptions) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
1187
1172
  }
1188
1173
 
1189
- function strokeText(stroke, ui, canvas) {
1174
+ function fillText(ui, canvas, _renderOptions) {
1175
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
1176
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
1177
+ let row;
1178
+ for (let i = 0, len = rows.length; i < len; i++) {
1179
+ row = rows[i];
1180
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
1181
+ canvas.fillText(charData.char, charData.x, row.y);
1182
+ });
1183
+ }
1184
+ if (decorationY) {
1185
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
1186
+ if (decorationColor) canvas.fillStyle = decorationColor;
1187
+ rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
1188
+ }
1189
+ }
1190
+
1191
+ function stroke(stroke, ui, canvas, renderOptions) {
1192
+ const data = ui.__;
1193
+ if (!data.__strokeWidth) return;
1194
+ if (data.__font) {
1195
+ Paint.strokeText(stroke, ui, canvas, renderOptions);
1196
+ } else {
1197
+ switch (data.strokeAlign) {
1198
+ case "center":
1199
+ drawCenter$1(stroke, 1, ui, canvas, renderOptions);
1200
+ break;
1201
+
1202
+ case "inside":
1203
+ drawInside(stroke, ui, canvas, renderOptions);
1204
+ break;
1205
+
1206
+ case "outside":
1207
+ drawOutside(stroke, ui, canvas, renderOptions);
1208
+ break;
1209
+ }
1210
+ }
1211
+ }
1212
+
1213
+ function strokes(strokes, ui, canvas, renderOptions) {
1214
+ Paint.stroke(strokes, ui, canvas, renderOptions);
1215
+ }
1216
+
1217
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas, renderOptions) {
1218
+ const data = ui.__;
1219
+ if (isObject(stroke)) {
1220
+ Paint.drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas, renderOptions);
1221
+ } else {
1222
+ canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1223
+ canvas.stroke();
1224
+ }
1225
+ if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas, renderOptions);
1226
+ }
1227
+
1228
+ function drawInside(stroke, ui, canvas, renderOptions) {
1229
+ canvas.save();
1230
+ canvas.clipUI(ui);
1231
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
1232
+ canvas.restore();
1233
+ }
1234
+
1235
+ function drawOutside(stroke, ui, canvas, renderOptions) {
1236
+ const data = ui.__;
1237
+ if (data.__fillAfterStroke) {
1238
+ drawCenter$1(stroke, 2, ui, canvas, renderOptions);
1239
+ } else {
1240
+ const {renderBounds: renderBounds} = ui.__layout;
1241
+ const out = canvas.getSameCanvas(true, true);
1242
+ ui.__drawRenderPath(out);
1243
+ drawCenter$1(stroke, 2, ui, out, renderOptions);
1244
+ out.clipUI(data);
1245
+ out.clearWorld(renderBounds);
1246
+ LeafHelper.copyCanvasByWorld(ui, canvas, out);
1247
+ out.recycle(ui.__nowWorld);
1248
+ }
1249
+ }
1250
+
1251
+ function strokeText(stroke, ui, canvas, renderOptions) {
1190
1252
  switch (ui.__.strokeAlign) {
1191
1253
  case "center":
1192
- drawCenter$1(stroke, 1, ui, canvas);
1254
+ drawCenter(stroke, 1, ui, canvas, renderOptions);
1193
1255
  break;
1194
1256
 
1195
1257
  case "inside":
1196
- drawAlign(stroke, "inside", ui, canvas);
1258
+ drawAlign(stroke, "inside", ui, canvas, renderOptions);
1197
1259
  break;
1198
1260
 
1199
1261
  case "outside":
1200
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
1262
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas, renderOptions) : drawAlign(stroke, "outside", ui, canvas, renderOptions);
1201
1263
  break;
1202
1264
  }
1203
1265
  }
1204
1266
 
1205
- function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
1267
+ function drawCenter(stroke, strokeWidthScale, ui, canvas, renderOptions) {
1206
1268
  const data = ui.__;
1207
1269
  if (isObject(stroke)) {
1208
- drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
1270
+ Paint.drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas, renderOptions);
1209
1271
  } else {
1210
1272
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1211
- drawTextStroke(ui, canvas);
1273
+ Paint.drawTextStroke(ui, canvas, renderOptions);
1212
1274
  }
1213
1275
  }
1214
1276
 
1215
- function drawAlign(stroke, align, ui, canvas) {
1277
+ function drawAlign(stroke, align, ui, canvas, renderOptions) {
1216
1278
  const out = canvas.getSameCanvas(true, true);
1217
1279
  out.font = ui.__.__font;
1218
- drawCenter$1(stroke, 2, ui, out);
1280
+ drawCenter(stroke, 2, ui, out, renderOptions);
1219
1281
  out.blendMode = align === "outside" ? "destination-out" : "destination-in";
1220
- fillText(ui, out);
1282
+ Paint.fillText(ui, out, renderOptions);
1221
1283
  out.blendMode = "normal";
1222
1284
  LeafHelper.copyCanvasByWorld(ui, canvas, out);
1223
1285
  out.recycle(ui.__nowWorld);
1224
1286
  }
1225
1287
 
1226
- function drawTextStroke(ui, canvas) {
1288
+ function drawTextStroke(ui, canvas, _renderOptions) {
1227
1289
  let row, data = ui.__.__textDrawData;
1228
1290
  const {rows: rows, decorationY: decorationY} = data;
1229
1291
  for (let i = 0, len = rows.length; i < len; i++) {
@@ -1238,89 +1300,29 @@ function drawTextStroke(ui, canvas) {
1238
1300
  }
1239
1301
  }
1240
1302
 
1241
- function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
1303
+ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas, renderOptions) {
1242
1304
  let item;
1243
1305
  const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
1244
1306
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
1245
1307
  for (let i = 0, len = strokes.length; i < len; i++) {
1246
1308
  item = strokes[i];
1247
- if (item.image && PaintImage.checkImage(ui, canvas, item, false)) continue;
1309
+ if (item.image && PaintImage.checkImage(item, false, ui, canvas, renderOptions)) continue;
1248
1310
  if (item.style) {
1249
1311
  if (__hasMultiStrokeStyle) {
1250
1312
  const {strokeStyle: strokeStyle} = item;
1251
1313
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
1252
1314
  } else canvas.strokeStyle = item.style;
1253
- if (item.blendMode) {
1254
- canvas.saveBlendMode(item.blendMode);
1255
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1315
+ if (item.originPaint.blendMode) {
1316
+ canvas.saveBlendMode(item.originPaint.blendMode);
1317
+ isText ? Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1256
1318
  canvas.restoreBlendMode();
1257
1319
  } else {
1258
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1320
+ isText ? Paint.drawTextStroke(ui, canvas, renderOptions) : canvas.stroke();
1259
1321
  }
1260
1322
  }
1261
1323
  }
1262
1324
  }
1263
1325
 
1264
- function stroke(stroke, ui, canvas) {
1265
- const data = ui.__;
1266
- if (!data.__strokeWidth) return;
1267
- if (data.__font) {
1268
- strokeText(stroke, ui, canvas);
1269
- } else {
1270
- switch (data.strokeAlign) {
1271
- case "center":
1272
- drawCenter(stroke, 1, ui, canvas);
1273
- break;
1274
-
1275
- case "inside":
1276
- drawInside(stroke, ui, canvas);
1277
- break;
1278
-
1279
- case "outside":
1280
- drawOutside(stroke, ui, canvas);
1281
- break;
1282
- }
1283
- }
1284
- }
1285
-
1286
- function strokes(strokes, ui, canvas) {
1287
- stroke(strokes, ui, canvas);
1288
- }
1289
-
1290
- function drawCenter(stroke, strokeWidthScale, ui, canvas) {
1291
- const data = ui.__;
1292
- if (isObject(stroke)) {
1293
- drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
1294
- } else {
1295
- canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
1296
- canvas.stroke();
1297
- }
1298
- if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas);
1299
- }
1300
-
1301
- function drawInside(stroke, ui, canvas) {
1302
- canvas.save();
1303
- canvas.clipUI(ui);
1304
- drawCenter(stroke, 2, ui, canvas);
1305
- canvas.restore();
1306
- }
1307
-
1308
- function drawOutside(stroke, ui, canvas) {
1309
- const data = ui.__;
1310
- if (data.__fillAfterStroke) {
1311
- drawCenter(stroke, 2, ui, canvas);
1312
- } else {
1313
- const {renderBounds: renderBounds} = ui.__layout;
1314
- const out = canvas.getSameCanvas(true, true);
1315
- ui.__drawRenderPath(out);
1316
- drawCenter(stroke, 2, ui, out);
1317
- out.clipUI(data);
1318
- out.clearWorld(renderBounds);
1319
- LeafHelper.copyCanvasByWorld(ui, canvas, out);
1320
- out.recycle(ui.__nowWorld);
1321
- }
1322
- }
1323
-
1324
1326
  const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = BoundsHelper;
1325
1327
 
1326
1328
  const tempBounds$1 = {};
@@ -1408,62 +1410,63 @@ function compute(attrName, ui) {
1408
1410
  if (leafPaints.some(item => item.image)) isAlphaPixel = true;
1409
1411
  isTransparent = true;
1410
1412
  }
1411
- }
1412
- if (attrName === "fill") {
1413
- stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1414
- stintSet(data, "__isTransparentFill", isTransparent);
1413
+ if (attrName === "fill") {
1414
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
1415
+ stintSet(data, "__isTransparentFill", isTransparent);
1416
+ } else {
1417
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1418
+ stintSet(data, "__isTransparentStroke", isTransparent);
1419
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1420
+ }
1415
1421
  } else {
1416
- stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
1417
- stintSet(data, "__isTransparentStroke", isTransparent);
1418
- stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
1422
+ data.__removePaint(attrName, false);
1419
1423
  }
1420
1424
  }
1421
1425
 
1422
1426
  function getLeafPaint(attrName, paint, ui) {
1423
1427
  if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
1424
- let data;
1428
+ let leafPaint;
1425
1429
  const {boxBounds: boxBounds} = ui.__layout;
1426
1430
  switch (paint.type) {
1427
1431
  case "image":
1428
- data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1432
+ leafPaint = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1429
1433
  break;
1430
1434
 
1431
1435
  case "linear":
1432
- data = PaintGradient.linearGradient(paint, boxBounds);
1436
+ leafPaint = PaintGradient.linearGradient(paint, boxBounds);
1433
1437
  break;
1434
1438
 
1435
1439
  case "radial":
1436
- data = PaintGradient.radialGradient(paint, boxBounds);
1440
+ leafPaint = PaintGradient.radialGradient(paint, boxBounds);
1437
1441
  break;
1438
1442
 
1439
1443
  case "angular":
1440
- data = PaintGradient.conicGradient(paint, boxBounds);
1444
+ leafPaint = PaintGradient.conicGradient(paint, boxBounds);
1441
1445
  break;
1442
1446
 
1443
1447
  case "solid":
1444
1448
  const {type: type, color: color, opacity: opacity} = paint;
1445
- data = {
1449
+ leafPaint = {
1446
1450
  type: type,
1447
1451
  style: ColorConvert.string(color, opacity)
1448
1452
  };
1449
1453
  break;
1450
1454
 
1451
1455
  default:
1452
- if (!isUndefined(paint.r)) data = {
1456
+ if (!isUndefined(paint.r)) leafPaint = {
1453
1457
  type: "solid",
1454
1458
  style: ColorConvert.string(paint)
1455
1459
  };
1456
1460
  }
1457
- if (data) {
1458
- if (isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
1461
+ if (leafPaint) {
1462
+ leafPaint.originPaint = paint;
1463
+ if (isString(leafPaint.style) && hasTransparent$1(leafPaint.style)) leafPaint.isTransparent = true;
1459
1464
  if (paint.style) {
1460
1465
  if (paint.style.strokeWidth === 0) return undefined;
1461
- data.strokeStyle = paint.style;
1466
+ leafPaint.strokeStyle = paint.style;
1462
1467
  }
1463
- if (paint.editing) data.editing = paint.editing;
1464
- if (paint.blendMode) data.blendMode = paint.blendMode;
1465
1468
  }
1466
- return data;
1469
+ return leafPaint;
1467
1470
  }
1468
1471
 
1469
1472
  const PaintModule = {
@@ -1476,88 +1479,118 @@ const PaintModule = {
1476
1479
  strokes: strokes,
1477
1480
  strokeText: strokeText,
1478
1481
  drawTextStroke: drawTextStroke,
1482
+ drawStrokesStyle: drawStrokesStyle,
1479
1483
  shape: shape
1480
1484
  };
1481
1485
 
1482
- let origin = {}, tempMatrix$1 = getMatrixData();
1486
+ let cache, box = new Bounds;
1483
1487
 
1484
- const {get: get$3, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
1488
+ const {isSame: isSame} = BoundsHelper;
1485
1489
 
1486
- function stretchMode(data, box, scaleX, scaleY) {
1487
- const transform = get$3();
1488
- translate$1(transform, box.x, box.y);
1489
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1490
- data.transform = transform;
1490
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1491
+ let leafPaint, event;
1492
+ const image = ImageManager.get(paint);
1493
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1494
+ leafPaint = cache.leafPaint;
1495
+ } else {
1496
+ leafPaint = {
1497
+ type: paint.type,
1498
+ image: image
1499
+ };
1500
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1501
+ cache = image.use > 1 ? {
1502
+ leafPaint: leafPaint,
1503
+ paint: paint,
1504
+ boxBounds: box.set(boxBounds)
1505
+ } : null;
1506
+ }
1507
+ if (firstUse || image.loading) event = {
1508
+ image: image,
1509
+ attrName: attrName,
1510
+ attrValue: paint
1511
+ };
1512
+ if (image.ready) {
1513
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1514
+ if (firstUse) {
1515
+ onLoad(ui, event);
1516
+ onLoadSuccess(ui, event);
1517
+ }
1518
+ } else if (image.error) {
1519
+ if (firstUse) onLoadError(ui, event, image.error);
1520
+ } else {
1521
+ if (firstUse) {
1522
+ ignoreRender(ui, true);
1523
+ onLoad(ui, event);
1524
+ }
1525
+ leafPaint.loadId = image.load(() => {
1526
+ ignoreRender(ui, false);
1527
+ if (!ui.destroyed) {
1528
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1529
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1530
+ ui.forceUpdate("surface");
1531
+ }
1532
+ onLoadSuccess(ui, event);
1533
+ }
1534
+ leafPaint.loadId = undefined;
1535
+ }, error => {
1536
+ ignoreRender(ui, false);
1537
+ onLoadError(ui, event, error);
1538
+ leafPaint.loadId = undefined;
1539
+ });
1540
+ if (ui.placeholderColor) {
1541
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1542
+ if (!image.ready) {
1543
+ image.isPlacehold = true;
1544
+ ui.forceUpdate("surface");
1545
+ }
1546
+ }, ui.placeholderDelay);
1547
+ }
1548
+ }
1549
+ return leafPaint;
1491
1550
  }
1492
1551
 
1493
- function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1494
- const transform = get$3();
1495
- translate$1(transform, box.x + x, box.y + y);
1496
- scaleHelper(transform, scaleX, scaleY);
1497
- if (rotation) rotateOfOuter$1(transform, {
1498
- x: box.x + box.width / 2,
1499
- y: box.y + box.height / 2
1500
- }, rotation);
1501
- data.transform = transform;
1552
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1553
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1554
+ const data = ui.__;
1555
+ data.__naturalWidth = image.width / data.pixelRatio;
1556
+ data.__naturalHeight = image.height / data.pixelRatio;
1557
+ if (data.__autoSide) {
1558
+ ui.forceUpdate("width");
1559
+ if (ui.__proxyData) {
1560
+ ui.setProxyAttr("width", data.width);
1561
+ ui.setProxyAttr("height", data.height);
1562
+ }
1563
+ return false;
1564
+ }
1565
+ }
1566
+ if (!leafPaint.data) PaintImage.createData(leafPaint, image, paint, boxBounds);
1567
+ return true;
1502
1568
  }
1503
1569
 
1504
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1505
- const transform = get$3();
1506
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1507
- if (clipScaleX) {
1508
- if (rotation || skew) {
1509
- set(tempMatrix$1);
1510
- scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1511
- multiplyParent(transform, tempMatrix$1);
1512
- } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1513
- }
1514
- data.transform = transform;
1570
+ function onLoad(ui, event) {
1571
+ emit(ui, ImageEvent.LOAD, event);
1515
1572
  }
1516
1573
 
1517
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1518
- const transform = get$3();
1519
- if (freeTransform) {
1520
- layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1521
- } else {
1522
- if (rotation) {
1523
- if (align === "center") {
1524
- rotateOfOuter$1(transform, {
1525
- x: width / 2,
1526
- y: height / 2
1527
- }, rotation);
1528
- } else {
1529
- rotate(transform, rotation);
1530
- switch (rotation) {
1531
- case 90:
1532
- translate$1(transform, height, 0);
1533
- break;
1574
+ function onLoadSuccess(ui, event) {
1575
+ emit(ui, ImageEvent.LOADED, event);
1576
+ }
1534
1577
 
1535
- case 180:
1536
- translate$1(transform, width, height);
1537
- break;
1578
+ function onLoadError(ui, event, error) {
1579
+ event.error = error;
1580
+ ui.forceUpdate("surface");
1581
+ emit(ui, ImageEvent.ERROR, event);
1582
+ }
1538
1583
 
1539
- case 270:
1540
- translate$1(transform, 0, width);
1541
- break;
1542
- }
1543
- }
1544
- }
1545
- origin.x = box.x + x;
1546
- origin.y = box.y + y;
1547
- translate$1(transform, origin.x, origin.y);
1548
- if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1549
- }
1550
- data.transform = transform;
1584
+ function emit(ui, type, data) {
1585
+ if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1551
1586
  }
1552
1587
 
1553
- function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1554
- if (rotation) rotate(transform, rotation);
1555
- if (skew) skewHelper(transform, skew.x, skew.y);
1556
- if (scaleX) scaleHelper(transform, scaleX, scaleY);
1557
- translate$1(transform, box.x + x, box.y + y);
1588
+ function ignoreRender(ui, value) {
1589
+ const {leafer: leafer} = ui;
1590
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1558
1591
  }
1559
1592
 
1560
- const {get: get$2, translate: translate} = MatrixHelper;
1593
+ const {get: get$3, translate: translate$1} = MatrixHelper;
1561
1594
 
1562
1595
  const tempBox = new Bounds;
1563
1596
 
@@ -1566,17 +1599,13 @@ const tempScaleData = {};
1566
1599
  const tempImage = {};
1567
1600
 
1568
1601
  function createData(leafPaint, image, paint, box) {
1569
- const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1570
- if (changeful) leafPaint.changeful = changeful;
1571
- if (sync) leafPaint.sync = sync;
1572
- if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1573
- leafPaint.data = getPatternData(paint, box, image);
1602
+ leafPaint.data = PaintImage.getPatternData(paint, box, image);
1574
1603
  }
1575
1604
 
1576
1605
  function getPatternData(paint, box, image) {
1577
1606
  if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1578
1607
  if (paint.mode === "strench") paint.mode = "stretch";
1579
- let {width: width, height: height} = image;
1608
+ const {width: width, height: height} = image;
1580
1609
  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;
1581
1610
  const sameBox = box.width === width && box.height === height;
1582
1611
  const data = {
@@ -1607,8 +1636,8 @@ function getPatternData(paint, box, image) {
1607
1636
  case "stretch":
1608
1637
  if (!sameBox) {
1609
1638
  scaleX = box.width / width, scaleY = box.height / height;
1610
- stretchMode(data, box, scaleX, scaleY);
1611
- }
1639
+ PaintImage.stretchMode(data, box, scaleX, scaleY);
1640
+ } else if (scaleX) scaleX = scaleY = undefined;
1612
1641
  break;
1613
1642
 
1614
1643
  case "normal":
@@ -1616,13 +1645,13 @@ function getPatternData(paint, box, image) {
1616
1645
  if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1617
1646
  let clipScaleX, clipScaleY;
1618
1647
  if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1619
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1648
+ PaintImage.clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1620
1649
  if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : clipScaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1621
1650
  }
1622
1651
  break;
1623
1652
 
1624
1653
  case "repeat":
1625
- if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1654
+ if (!sameBox || scaleX || rotation || skew) PaintImage.repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1626
1655
  if (!repeat) data.repeat = "repeat";
1627
1656
  const count = isObject(repeat);
1628
1657
  if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
@@ -1631,18 +1660,16 @@ function getPatternData(paint, box, image) {
1631
1660
  case "fit":
1632
1661
  case "cover":
1633
1662
  default:
1634
- if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1663
+ if (scaleX) PaintImage.fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1635
1664
  }
1636
1665
  if (!data.transform) {
1637
- if (box.x || box.y) translate(data.transform = get$2(), box.x, box.y);
1666
+ if (box.x || box.y) translate$1(data.transform = get$3(), box.x, box.y);
1638
1667
  }
1639
- data.width = width;
1640
- data.height = height;
1641
1668
  if (scaleX) {
1642
1669
  data.scaleX = scaleX;
1643
1670
  data.scaleY = scaleY;
1644
1671
  }
1645
- if (opacity) data.opacity = opacity;
1672
+ if (opacity && opacity < 1) data.opacity = opacity;
1646
1673
  if (filters) data.filters = filters;
1647
1674
  if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1648
1675
  return data;
@@ -1664,180 +1691,82 @@ function getGapValue(gap, size, totalSize, rows) {
1664
1691
  return gap === "auto" ? value < 0 ? 0 : value : value;
1665
1692
  }
1666
1693
 
1667
- let cache, box = new Bounds;
1668
-
1669
- const {isSame: isSame} = BoundsHelper;
1670
-
1671
- function image(ui, attrName, paint, boxBounds, firstUse) {
1672
- let leafPaint, event;
1673
- const image = ImageManager.get(paint);
1674
- if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1675
- leafPaint = cache.leafPaint;
1676
- } else {
1677
- leafPaint = {
1678
- type: paint.type,
1679
- image: image
1680
- };
1681
- if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1682
- cache = image.use > 1 ? {
1683
- leafPaint: leafPaint,
1684
- paint: paint,
1685
- boxBounds: box.set(boxBounds)
1686
- } : null;
1687
- }
1688
- if (firstUse || image.loading) event = {
1689
- image: image,
1690
- attrName: attrName,
1691
- attrValue: paint
1692
- };
1693
- if (image.ready) {
1694
- checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1695
- if (firstUse) {
1696
- onLoad(ui, event);
1697
- onLoadSuccess(ui, event);
1698
- }
1699
- } else if (image.error) {
1700
- if (firstUse) onLoadError(ui, event, image.error);
1701
- } else {
1702
- if (firstUse) {
1703
- ignoreRender(ui, true);
1704
- onLoad(ui, event);
1705
- }
1706
- leafPaint.loadId = image.load(() => {
1707
- ignoreRender(ui, false);
1708
- if (!ui.destroyed) {
1709
- if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1710
- if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1711
- ui.forceUpdate("surface");
1712
- }
1713
- onLoadSuccess(ui, event);
1714
- }
1715
- leafPaint.loadId = undefined;
1716
- }, error => {
1717
- ignoreRender(ui, false);
1718
- onLoadError(ui, event, error);
1719
- leafPaint.loadId = undefined;
1720
- });
1721
- if (ui.placeholderColor) {
1722
- if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1723
- if (!image.ready) {
1724
- image.isPlacehold = true;
1725
- ui.forceUpdate("surface");
1726
- }
1727
- }, ui.placeholderDelay);
1728
- }
1729
- }
1730
- return leafPaint;
1731
- }
1732
-
1733
- function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1734
- if (attrName === "fill" && !ui.__.__naturalWidth) {
1735
- const data = ui.__;
1736
- data.__naturalWidth = image.width / data.pixelRatio;
1737
- data.__naturalHeight = image.height / data.pixelRatio;
1738
- if (data.__autoSide) {
1739
- ui.forceUpdate("width");
1740
- if (ui.__proxyData) {
1741
- ui.setProxyAttr("width", data.width);
1742
- ui.setProxyAttr("height", data.height);
1743
- }
1744
- return false;
1745
- }
1746
- }
1747
- if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1748
- return true;
1749
- }
1750
-
1751
- function onLoad(ui, event) {
1752
- emit(ui, ImageEvent.LOAD, event);
1753
- }
1694
+ let origin = {}, tempMatrix$1 = getMatrixData();
1754
1695
 
1755
- function onLoadSuccess(ui, event) {
1756
- emit(ui, ImageEvent.LOADED, event);
1757
- }
1696
+ const {get: get$2, set: set, rotateOfOuter: rotateOfOuter$1, translate: translate, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
1758
1697
 
1759
- function onLoadError(ui, event, error) {
1760
- event.error = error;
1761
- ui.forceUpdate("surface");
1762
- emit(ui, ImageEvent.ERROR, event);
1698
+ function stretchMode(data, box, scaleX, scaleY) {
1699
+ const transform = get$2(), {x: x, y: y} = box;
1700
+ if (x || y) translate(transform, x, y); else transform.onlyScale = true;
1701
+ scaleHelper(transform, scaleX, scaleY);
1702
+ data.transform = transform;
1763
1703
  }
1764
1704
 
1765
- function emit(ui, type, data) {
1766
- if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1705
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1706
+ const transform = get$2();
1707
+ translate(transform, box.x + x, box.y + y);
1708
+ scaleHelper(transform, scaleX, scaleY);
1709
+ if (rotation) rotateOfOuter$1(transform, {
1710
+ x: box.x + box.width / 2,
1711
+ y: box.y + box.height / 2
1712
+ }, rotation);
1713
+ data.transform = transform;
1767
1714
  }
1768
1715
 
1769
- function ignoreRender(ui, value) {
1770
- const {leafer: leafer} = ui;
1771
- if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1716
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1717
+ const transform = get$2();
1718
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1719
+ if (clipScaleX) {
1720
+ if (rotation || skew) {
1721
+ set(tempMatrix$1);
1722
+ scaleOfOuter$1(tempMatrix$1, box, clipScaleX, clipScaleY);
1723
+ multiplyParent(transform, tempMatrix$1);
1724
+ } else scaleOfOuter$1(transform, box, clipScaleX, clipScaleY);
1725
+ }
1726
+ data.transform = transform;
1772
1727
  }
1773
1728
 
1774
- const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1729
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1730
+ const transform = get$2();
1731
+ if (freeTransform) {
1732
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1733
+ } else {
1734
+ if (rotation) {
1735
+ if (align === "center") {
1736
+ rotateOfOuter$1(transform, {
1737
+ x: width / 2,
1738
+ y: height / 2
1739
+ }, rotation);
1740
+ } else {
1741
+ rotate(transform, rotation);
1742
+ switch (rotation) {
1743
+ case 90:
1744
+ translate(transform, height, 0);
1745
+ break;
1775
1746
 
1776
- const {floor: floor, ceil: ceil, max: max$1, abs: abs$1} = Math;
1747
+ case 180:
1748
+ translate(transform, width, height);
1749
+ break;
1777
1750
 
1778
- function createPattern(ui, paint, pixelRatio) {
1779
- let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1780
- const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1781
- if (paint.patternId !== id && !ui.destroyed) {
1782
- const {image: image, data: data} = paint;
1783
- let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1784
- scaleX *= pixelRatio;
1785
- scaleY *= pixelRatio;
1786
- if (sx) {
1787
- sx = abs$1(sx);
1788
- sy = abs$1(sy);
1789
- imageMatrix = get$1();
1790
- copy$1(imageMatrix, transform);
1791
- scale(imageMatrix, 1 / sx, 1 / sy);
1792
- scaleX *= sx;
1793
- scaleY *= sy;
1794
- }
1795
- width *= scaleX;
1796
- height *= scaleY;
1797
- const size = width * height;
1798
- if (!repeat) {
1799
- if (size > Platform.image.maxCacheSize) return false;
1800
- }
1801
- let maxSize = Platform.image.maxPatternSize;
1802
- if (image.isSVG) {
1803
- const ws = width / image.width;
1804
- if (ws > 1) imageScale = ws / ceil(ws);
1805
- } else {
1806
- const imageSize = image.width * image.height;
1807
- if (maxSize > imageSize) maxSize = imageSize;
1808
- }
1809
- if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1810
- if (imageScale) {
1811
- scaleX /= imageScale;
1812
- scaleY /= imageScale;
1813
- width /= imageScale;
1814
- height /= imageScale;
1815
- }
1816
- if (sx) {
1817
- scaleX /= sx;
1818
- scaleY /= sy;
1819
- }
1820
- const xGap = gap && gap.x * scaleX;
1821
- const yGap = gap && gap.y * scaleY;
1822
- if (transform || scaleX !== 1 || scaleY !== 1) {
1823
- const canvasWidth = width + (xGap || 0);
1824
- const canvasHeight = height + (yGap || 0);
1825
- scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1826
- scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1827
- if (!imageMatrix) {
1828
- imageMatrix = get$1();
1829
- if (transform) copy$1(imageMatrix, transform);
1751
+ case 270:
1752
+ translate(transform, 0, width);
1753
+ break;
1754
+ }
1830
1755
  }
1831
- scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1832
1756
  }
1833
- const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1834
- const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1835
- paint.style = pattern;
1836
- paint.patternId = id;
1837
- return true;
1838
- } else {
1839
- return false;
1757
+ origin.x = box.x + x;
1758
+ origin.y = box.y + y;
1759
+ translate(transform, origin.x, origin.y);
1760
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1840
1761
  }
1762
+ data.transform = transform;
1763
+ }
1764
+
1765
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1766
+ if (rotation) rotate(transform, rotation);
1767
+ if (skew) skewHelper(transform, skew.x, skew.y);
1768
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1769
+ translate(transform, box.x + x, box.y + y);
1841
1770
  }
1842
1771
 
1843
1772
  function __awaiter(thisArg, _arguments, P, generator) {
@@ -1873,58 +1802,116 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
1873
1802
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1874
1803
  };
1875
1804
 
1876
- function checkImage(ui, canvas, paint, allowDraw) {
1877
- const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1878
- const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1879
- if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !Export.running) {
1805
+ const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1806
+
1807
+ const {getFloorScale: getFloorScale} = MathHelper, {abs: abs$1} = Math;
1808
+
1809
+ function createPatternTask(paint, ui, canvas, renderOptions) {
1810
+ if (!paint.patternTask) {
1811
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1812
+ paint.patternTask = null;
1813
+ if (canvas.bounds.hit(ui.__nowWorld)) PaintImage.createPattern(paint, ui, canvas, renderOptions);
1814
+ ui.forceUpdate("surface");
1815
+ }), 300);
1816
+ }
1817
+ }
1818
+
1819
+ function createPattern(paint, ui, canvas, renderOptions) {
1820
+ let {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions), id = scaleX + "-" + scaleY;
1821
+ if (paint.patternId !== id && !ui.destroyed) {
1822
+ if (!(Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)) {
1823
+ const {image: image, data: data} = paint, {transform: transform, gap: gap} = data, fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
1824
+ let imageMatrix, xGap, yGap, {width: width, height: height} = image;
1825
+ if (fixScale) scaleX *= fixScale, scaleY *= fixScale;
1826
+ width *= scaleX;
1827
+ height *= scaleY;
1828
+ if (gap) {
1829
+ xGap = gap.x * scaleX / abs$1(data.scaleX || 1);
1830
+ yGap = gap.y * scaleY / abs$1(data.scaleY || 1);
1831
+ }
1832
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1833
+ scaleX *= getFloorScale(width + (xGap || 0));
1834
+ scaleY *= getFloorScale(height + (yGap || 0));
1835
+ imageMatrix = get$1();
1836
+ if (transform) copy$1(imageMatrix, transform);
1837
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1838
+ }
1839
+ const imageCanvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap, ui.leafer && ui.leafer.config.smooth);
1840
+ const pattern = image.getPattern(imageCanvas, data.repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1841
+ paint.style = pattern;
1842
+ paint.patternId = id;
1843
+ }
1844
+ }
1845
+ }
1846
+
1847
+ function getPatternFixScale(paint, imageScaleX, imageScaleY) {
1848
+ const {image: image} = paint;
1849
+ let fixScale, maxSize = Platform.image.maxPatternSize, imageSize = image.width * image.height;
1850
+ if (image.isSVG) {
1851
+ if (imageScaleX > 1) fixScale = Math.ceil(imageScaleX) / imageScaleX;
1852
+ } else {
1853
+ if (maxSize > imageSize) maxSize = imageSize;
1854
+ }
1855
+ if ((imageSize *= imageScaleX * imageScaleY) > maxSize) fixScale = Math.sqrt(maxSize / imageSize);
1856
+ return fixScale;
1857
+ }
1858
+
1859
+ function checkImage(paint, drawImage, ui, canvas, renderOptions) {
1860
+ const {scaleX: scaleX, scaleY: scaleY} = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
1861
+ const {image: image, data: data, originPaint: originPaint} = paint, {exporting: exporting} = renderOptions;
1862
+ if (!data || paint.patternId === scaleX + "-" + scaleY && !exporting) {
1880
1863
  return false;
1881
1864
  } else {
1882
- if (allowDraw) {
1865
+ if (drawImage) {
1883
1866
  if (data.repeat) {
1884
- allowDraw = false;
1885
- } else if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
1886
- let {width: width, height: height} = data;
1887
- width *= scaleX * pixelRatio;
1888
- height *= scaleY * pixelRatio;
1889
- if (data.scaleX) {
1890
- width *= data.scaleX;
1891
- height *= data.scaleY;
1892
- }
1893
- allowDraw = width * height > Platform.image.maxCacheSize;
1867
+ drawImage = false;
1868
+ } else if (!(originPaint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || exporting)) {
1869
+ drawImage = Platform.image.isLarge(image, scaleX, scaleY);
1894
1870
  }
1895
1871
  }
1896
- if (allowDraw) {
1872
+ if (drawImage) {
1897
1873
  if (ui.__.__isFastShadow) {
1898
1874
  canvas.fillStyle = paint.style || "#000";
1899
1875
  canvas.fill();
1900
1876
  }
1901
- drawImage(ui, canvas, paint, data);
1877
+ PaintImage.drawImage(paint, scaleX, scaleY, ui, canvas, renderOptions);
1902
1878
  return true;
1903
1879
  } else {
1904
- if (!paint.style || paint.sync || Export.running) {
1905
- createPattern(ui, paint, pixelRatio);
1906
- } else {
1907
- if (!paint.patternTask) {
1908
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1909
- paint.patternTask = null;
1910
- if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1911
- ui.forceUpdate("surface");
1912
- }), 300);
1913
- }
1914
- }
1880
+ if (!paint.style || originPaint.sync || exporting) PaintImage.createPattern(paint, ui, canvas, renderOptions); else PaintImage.createPatternTask(paint, ui, canvas, renderOptions);
1915
1881
  return false;
1916
1882
  }
1917
1883
  }
1918
1884
  }
1919
1885
 
1920
- function drawImage(ui, canvas, paint, data) {
1921
- canvas.save();
1922
- canvas.clipUI(ui);
1923
- if (paint.blendMode) canvas.blendMode = paint.blendMode;
1924
- if (data.opacity) canvas.opacity *= data.opacity;
1925
- if (data.transform) canvas.transform(data.transform);
1926
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1927
- canvas.restore();
1886
+ function drawImage(paint, _imageScaleX, _imageScaleY, ui, canvas, _renderOptions) {
1887
+ const {data: data, image: image} = paint, {blendMode: blendMode} = paint.originPaint, {opacity: opacity, transform: transform} = data, view = image.getFull(data.filters), u = ui.__;
1888
+ let {width: width, height: height} = image, clipUI;
1889
+ if ((clipUI = transform && !transform.onlyScale || u.path || u.cornerRadius) || opacity || blendMode) {
1890
+ canvas.save();
1891
+ clipUI && canvas.clipUI(ui);
1892
+ blendMode && (canvas.blendMode = blendMode);
1893
+ opacity && (canvas.opacity *= opacity);
1894
+ transform && canvas.transform(transform);
1895
+ canvas.drawImage(view, 0, 0, width, height);
1896
+ canvas.restore();
1897
+ } else {
1898
+ if (data.scaleX) width *= data.scaleX, height *= data.scaleY;
1899
+ canvas.drawImage(view, 0, 0, width, height);
1900
+ }
1901
+ }
1902
+
1903
+ function getImageRenderScaleData(paint, ui, canvas, _renderOptions) {
1904
+ const scaleData = ui.getRenderScaleData(true, paint.originPaint.scaleFixed), {data: data} = paint;
1905
+ if (canvas) {
1906
+ const {pixelRatio: pixelRatio} = canvas;
1907
+ scaleData.scaleX *= pixelRatio;
1908
+ scaleData.scaleY *= pixelRatio;
1909
+ }
1910
+ if (data && data.scaleX) {
1911
+ scaleData.scaleX *= Math.abs(data.scaleX);
1912
+ scaleData.scaleY *= Math.abs(data.scaleY);
1913
+ }
1914
+ return scaleData;
1928
1915
  }
1929
1916
 
1930
1917
  function recycleImage(attrName, data) {
@@ -1956,8 +1943,12 @@ function recycleImage(attrName, data) {
1956
1943
  const PaintImageModule = {
1957
1944
  image: image,
1958
1945
  checkImage: checkImage,
1959
- createPattern: createPattern,
1946
+ drawImage: drawImage,
1947
+ getImageRenderScaleData: getImageRenderScaleData,
1960
1948
  recycleImage: recycleImage,
1949
+ createPatternTask: createPatternTask,
1950
+ createPattern: createPattern,
1951
+ getPatternFixScale: getPatternFixScale,
1961
1952
  createData: createData,
1962
1953
  getPatternData: getPatternData,
1963
1954
  stretchMode: stretchMode,
@@ -2413,10 +2404,8 @@ function createRows(drawData, content, style) {
2413
2404
  bounds = drawData.bounds;
2414
2405
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
2415
2406
  const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
2416
- const {canvas: canvas} = Platform;
2417
- const {width: width, height: height} = bounds;
2418
- const charMode = width || height || __letterSpacing || textCase !== "none";
2419
- if (charMode) {
2407
+ const {canvas: canvas} = Platform, {width: width} = bounds;
2408
+ if (style.__isCharMode) {
2420
2409
  const wrap = style.textWrap !== "none";
2421
2410
  const breakAll = style.textWrap === "break";
2422
2411
  paraStart = true;
@@ -2545,12 +2534,19 @@ const TextMode = 2;
2545
2534
  function layoutChar(drawData, style, width, _height) {
2546
2535
  const {rows: rows} = drawData;
2547
2536
  const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
2548
- let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2537
+ const justifyLast = width && textAlign.includes("both");
2538
+ const justify = justifyLast || width && textAlign.includes("justify");
2539
+ const justifyLetter = justify && textAlign.includes("letter");
2540
+ let charX, remainingWidth, addWordWidth, addLetterWidth, indentWidth, mode, wordChar, wordsLength, isLastWord, canJustify;
2549
2541
  rows.forEach(row => {
2550
2542
  if (row.words) {
2551
2543
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2552
- addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2553
- mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2544
+ if (justify) {
2545
+ canJustify = !row.paraEnd || justifyLast;
2546
+ remainingWidth = width - row.width - indentWidth;
2547
+ if (justifyLetter) addLetterWidth = remainingWidth / (row.words.reduce((total, item) => total + item.data.length, 0) - 1); else addWordWidth = wordsLength > 1 ? remainingWidth / (wordsLength - 1) : 0;
2548
+ }
2549
+ mode = letterSpacing || row.isOverflow || justifyLetter ? CharMode : addWordWidth ? WordMode : TextMode;
2554
2550
  if (row.isOverflow && !letterSpacing) row.textMode = true;
2555
2551
  if (mode === TextMode) {
2556
2552
  row.x += indentWidth;
@@ -2568,11 +2564,15 @@ function layoutChar(drawData, style, width, _height) {
2568
2564
  charX = toWordChar(word.data, charX, wordChar);
2569
2565
  if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2570
2566
  } else {
2571
- charX = toChar(word.data, charX, row.data, row.isOverflow);
2567
+ charX = toChar(word.data, charX, row.data, row.isOverflow, canJustify && addLetterWidth);
2572
2568
  }
2573
- if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
2574
- charX += addWordWidth;
2575
- row.width += addWordWidth;
2569
+ if (canJustify) {
2570
+ isLastWord = index === wordsLength - 1;
2571
+ if (addWordWidth) {
2572
+ if (!isLastWord) charX += addWordWidth, row.width += addWordWidth;
2573
+ } else if (addLetterWidth) {
2574
+ row.width += addLetterWidth * (word.data.length - (isLastWord ? 1 : 0));
2575
+ }
2576
2576
  }
2577
2577
  });
2578
2578
  }
@@ -2598,13 +2598,14 @@ function toWordChar(data, charX, wordChar) {
2598
2598
  return charX;
2599
2599
  }
2600
2600
 
2601
- function toChar(data, charX, rowData, isOverflow) {
2601
+ function toChar(data, charX, rowData, isOverflow, addLetterWidth) {
2602
2602
  data.forEach(char => {
2603
2603
  if (isOverflow || char.char !== " ") {
2604
2604
  char.x = charX;
2605
2605
  rowData.push(char);
2606
2606
  }
2607
2607
  charX += char.width;
2608
+ addLetterWidth && (charX += addLetterWidth);
2608
2609
  });
2609
2610
  return charX;
2610
2611
  }
@@ -2746,10 +2747,10 @@ function getDrawData(content, style) {
2746
2747
  let x = 0, y = 0;
2747
2748
  let width = style.__getInput("width") || 0;
2748
2749
  let height = style.__getInput("height") || 0;
2749
- const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2750
+ const {__padding: padding} = style;
2750
2751
  if (padding) {
2751
- if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2752
- if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2752
+ if (width) x = padding[left], width -= padding[right] + padding[left], !width && (width = .01); else if (!style.autoSizeAlign) x = padding[left];
2753
+ if (height) y = padding[top], height -= padding[top] + padding[bottom], !height && (height = .01); else if (!style.autoSizeAlign) y = padding[top];
2753
2754
  }
2754
2755
  const drawData = {
2755
2756
  bounds: {
@@ -2760,14 +2761,14 @@ function getDrawData(content, style) {
2760
2761
  },
2761
2762
  rows: [],
2762
2763
  paraNumber: 0,
2763
- font: Platform.canvas.font = __font
2764
+ font: Platform.canvas.font = style.__font
2764
2765
  };
2765
2766
  createRows(drawData, content, style);
2766
2767
  if (padding) padAutoText(padding, drawData, style, width, height);
2767
2768
  layoutText(drawData, style);
2768
- layoutChar(drawData, style, width);
2769
+ if (style.__isCharMode) layoutChar(drawData, style, width);
2769
2770
  if (drawData.overflow) clipText(drawData, style, x, width);
2770
- if (textDecoration !== "none") decorationText(drawData, style);
2771
+ if (style.textDecoration !== "none") decorationText(drawData, style);
2771
2772
  return drawData;
2772
2773
  }
2773
2774