@leafer-ui/worker 1.6.2 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/worker.cjs CHANGED
@@ -161,17 +161,15 @@ class Watcher {
161
161
  this.target.emitEvent(new core.WatchEvent(core.WatchEvent.DATA, { updatedList: this.updatedList }));
162
162
  this.__updatedList = new core.LeafList();
163
163
  this.totalTimes++;
164
- this.changed = false;
165
- this.hasVisible = false;
166
- this.hasRemove = false;
167
- this.hasAdd = false;
164
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
168
165
  }
169
166
  __listenEvents() {
170
- const { target } = this;
171
167
  this.__eventIds = [
172
- target.on_(core.PropertyEvent.CHANGE, this.__onAttrChange, this),
173
- target.on_([core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this),
174
- target.on_(core.WatchEvent.REQUEST, this.__onRquestData, this)
168
+ this.target.on_([
169
+ [core.PropertyEvent.CHANGE, this.__onAttrChange, this],
170
+ [[core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this],
171
+ [core.WatchEvent.REQUEST, this.__onRquestData, this]
172
+ ])
175
173
  ];
176
174
  }
177
175
  __removeListenEvents() {
@@ -181,8 +179,7 @@ class Watcher {
181
179
  if (this.target) {
182
180
  this.stop();
183
181
  this.__removeListenEvents();
184
- this.target = null;
185
- this.__updatedList = null;
182
+ this.target = this.__updatedList = null;
186
183
  }
187
184
  }
188
185
  }
@@ -287,7 +284,7 @@ class Layouter {
287
284
  this.disabled = true;
288
285
  }
289
286
  layout() {
290
- if (!this.running)
287
+ if (this.layouting || !this.running)
291
288
  return;
292
289
  const { target } = this;
293
290
  this.times = 0;
@@ -370,12 +367,10 @@ class Layouter {
370
367
  }
371
368
  static fullLayout(target) {
372
369
  updateAllMatrix(target, true);
373
- if (target.isBranch) {
370
+ if (target.isBranch)
374
371
  core.BranchHelper.updateBounds(target);
375
- }
376
- else {
372
+ else
377
373
  core.LeafHelper.updateBounds(target);
378
- }
379
374
  updateAllChange(target);
380
375
  }
381
376
  addExtra(leaf) {
@@ -398,11 +393,12 @@ class Layouter {
398
393
  this.__updatedList = event.data.updatedList;
399
394
  }
400
395
  __listenEvents() {
401
- const { target } = this;
402
396
  this.__eventIds = [
403
- target.on_(core.LayoutEvent.REQUEST, this.layout, this),
404
- target.on_(core.LayoutEvent.AGAIN, this.layoutAgain, this),
405
- target.on_(core.WatchEvent.DATA, this.__onReceiveWatchData, this)
397
+ this.target.on_([
398
+ [core.LayoutEvent.REQUEST, this.layout, this],
399
+ [core.LayoutEvent.AGAIN, this.layoutAgain, this],
400
+ [core.WatchEvent.DATA, this.__onReceiveWatchData, this]
401
+ ])
406
402
  ];
407
403
  }
408
404
  __removeListenEvents() {
@@ -633,12 +629,13 @@ class Renderer {
633
629
  this.target.emitEvent(new core.RenderEvent(type, this.times, bounds, options));
634
630
  }
635
631
  __listenEvents() {
636
- const { target } = this;
637
632
  this.__eventIds = [
638
- target.on_(core.RenderEvent.REQUEST, this.update, this),
639
- target.on_(core.LayoutEvent.END, this.__onLayoutEnd, this),
640
- target.on_(core.RenderEvent.AGAIN, this.renderAgain, this),
641
- target.on_(core.ResizeEvent.RESIZE, this.__onResize, this)
633
+ this.target.on_([
634
+ [core.RenderEvent.REQUEST, this.update, this],
635
+ [core.LayoutEvent.END, this.__onLayoutEnd, this],
636
+ [core.RenderEvent.AGAIN, this.renderAgain, this],
637
+ [core.ResizeEvent.RESIZE, this.__onResize, this]
638
+ ])
642
639
  ];
643
640
  }
644
641
  __removeListenEvents() {
@@ -881,32 +878,34 @@ function fillPathOrText(ui, canvas) {
881
878
  ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
882
879
  }
883
880
 
881
+ const Paint = {};
882
+
884
883
  function strokeText(stroke, ui, canvas) {
885
- const { strokeAlign } = ui.__;
886
- const isStrokes = typeof stroke !== 'string';
887
- switch (strokeAlign) {
884
+ switch (ui.__.strokeAlign) {
888
885
  case 'center':
889
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
890
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
886
+ drawCenter$1(stroke, 1, ui, canvas);
891
887
  break;
892
888
  case 'inside':
893
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
889
+ drawAlign(stroke, 'inside', ui, canvas);
894
890
  break;
895
891
  case 'outside':
896
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
892
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
897
893
  break;
898
894
  }
899
895
  }
900
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
901
- const { __strokeWidth, __font } = ui.__;
896
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
897
+ const data = ui.__;
898
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
899
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
900
+ }
901
+ function drawAlign(stroke, align, ui, canvas) {
902
902
  const out = canvas.getSameCanvas(true, true);
903
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
904
- out.font = __font;
905
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
903
+ out.font = ui.__.__font;
904
+ drawCenter$1(stroke, 2, ui, out);
906
905
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
907
906
  fillText(ui, out);
908
907
  out.blendMode = 'normal';
909
- if (ui.__worldFlipped)
908
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
910
909
  canvas.copyWorldByReset(out, ui.__nowWorld);
911
910
  else
912
911
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -948,90 +947,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
948
947
  }
949
948
 
950
949
  function stroke(stroke, ui, canvas) {
951
- const options = ui.__;
952
- const { __strokeWidth, strokeAlign, __font } = options;
953
- if (!__strokeWidth)
950
+ const data = ui.__;
951
+ if (!data.__strokeWidth)
954
952
  return;
955
- if (__font) {
953
+ if (data.__font) {
956
954
  strokeText(stroke, ui, canvas);
957
955
  }
958
956
  else {
959
- switch (strokeAlign) {
957
+ switch (data.strokeAlign) {
960
958
  case 'center':
961
- canvas.setStroke(stroke, __strokeWidth, options);
962
- canvas.stroke();
963
- if (options.__useArrow)
964
- strokeArrow(ui, canvas);
959
+ drawCenter(stroke, 1, ui, canvas);
965
960
  break;
966
961
  case 'inside':
967
- canvas.save();
968
- canvas.setStroke(stroke, __strokeWidth * 2, options);
969
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
970
- canvas.stroke();
971
- canvas.restore();
962
+ drawInside(stroke, ui, canvas);
972
963
  break;
973
964
  case 'outside':
974
- const out = canvas.getSameCanvas(true, true);
975
- out.setStroke(stroke, __strokeWidth * 2, options);
976
- ui.__drawRenderPath(out);
977
- out.stroke();
978
- options.windingRule ? out.clip(options.windingRule) : out.clip();
979
- out.clearWorld(ui.__layout.renderBounds);
980
- if (ui.__worldFlipped)
981
- canvas.copyWorldByReset(out, ui.__nowWorld);
982
- else
983
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
984
- out.recycle(ui.__nowWorld);
965
+ drawOutside(stroke, ui, canvas);
985
966
  break;
986
967
  }
987
968
  }
988
969
  }
989
970
  function strokes(strokes, ui, canvas) {
990
- const options = ui.__;
991
- const { __strokeWidth, strokeAlign, __font } = options;
992
- if (!__strokeWidth)
993
- return;
994
- if (__font) {
995
- strokeText(strokes, ui, canvas);
971
+ stroke(strokes, ui, canvas);
972
+ }
973
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
974
+ const data = ui.__;
975
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
976
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
977
+ if (data.__useArrow)
978
+ Paint.strokeArrow(stroke, ui, canvas);
979
+ }
980
+ function drawInside(stroke, ui, canvas) {
981
+ const data = ui.__;
982
+ canvas.save();
983
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
984
+ drawCenter(stroke, 2, ui, canvas);
985
+ canvas.restore();
986
+ }
987
+ function drawOutside(stroke, ui, canvas) {
988
+ const data = ui.__;
989
+ if (data.__fillAfterStroke) {
990
+ drawCenter(stroke, 2, ui, canvas);
996
991
  }
997
992
  else {
998
- switch (strokeAlign) {
999
- case 'center':
1000
- canvas.setStroke(undefined, __strokeWidth, options);
1001
- drawStrokesStyle(strokes, false, ui, canvas);
1002
- if (options.__useArrow)
1003
- strokeArrow(ui, canvas);
1004
- break;
1005
- case 'inside':
1006
- canvas.save();
1007
- canvas.setStroke(undefined, __strokeWidth * 2, options);
1008
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1009
- drawStrokesStyle(strokes, false, ui, canvas);
1010
- canvas.restore();
1011
- break;
1012
- case 'outside':
1013
- const { renderBounds } = ui.__layout;
1014
- const out = canvas.getSameCanvas(true, true);
1015
- ui.__drawRenderPath(out);
1016
- out.setStroke(undefined, __strokeWidth * 2, options);
1017
- drawStrokesStyle(strokes, false, ui, out);
1018
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1019
- out.clearWorld(renderBounds);
1020
- if (ui.__worldFlipped)
1021
- canvas.copyWorldByReset(out, ui.__nowWorld);
1022
- else
1023
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1024
- out.recycle(ui.__nowWorld);
1025
- break;
1026
- }
1027
- }
1028
- }
1029
- function strokeArrow(ui, canvas) {
1030
- if (ui.__.dashPattern) {
1031
- canvas.beginPath();
1032
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
1033
- canvas.dashPattern = null;
1034
- canvas.stroke();
993
+ const { renderBounds } = ui.__layout;
994
+ const out = canvas.getSameCanvas(true, true);
995
+ ui.__drawRenderPath(out);
996
+ drawCenter(stroke, 2, ui, out);
997
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
998
+ out.clearWorld(renderBounds);
999
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
1000
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1001
+ else
1002
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1003
+ out.recycle(ui.__nowWorld);
1035
1004
  }
1036
1005
  }
1037
1006
 
@@ -1078,9 +1047,10 @@ function shape(ui, current, options) {
1078
1047
  }
1079
1048
 
1080
1049
  let recycleMap;
1050
+ const { stintSet } = core.DataHelper, { hasTransparent: hasTransparent$1 } = draw.ColorConvert;
1081
1051
  function compute(attrName, ui) {
1082
1052
  const data = ui.__, leafPaints = [];
1083
- let paints = data.__input[attrName], hasOpacityPixel;
1053
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
1084
1054
  if (!(paints instanceof Array))
1085
1055
  paints = [paints];
1086
1056
  recycleMap = draw.PaintImage.recycleImage(attrName, data);
@@ -1090,29 +1060,55 @@ function compute(attrName, ui) {
1090
1060
  leafPaints.push(item);
1091
1061
  }
1092
1062
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1093
- if (leafPaints.length && leafPaints[0].image)
1094
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1095
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
1063
+ if (leafPaints.length) {
1064
+ if (leafPaints.every(item => item.isTransparent)) {
1065
+ if (leafPaints.some(item => item.image))
1066
+ isAlphaPixel = true;
1067
+ isTransparent = true;
1068
+ }
1069
+ }
1070
+ if (attrName === 'fill') {
1071
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
1072
+ stintSet(data, '__isTransparentFill', isTransparent);
1073
+ }
1074
+ else {
1075
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
1076
+ stintSet(data, '__isTransparentStroke', isTransparent);
1077
+ }
1096
1078
  }
1097
1079
  function getLeafPaint(attrName, paint, ui) {
1098
1080
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1099
1081
  return undefined;
1082
+ let data;
1100
1083
  const { boxBounds } = ui.__layout;
1101
1084
  switch (paint.type) {
1102
- case 'solid':
1103
- let { type, blendMode, color, opacity } = paint;
1104
- return { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
1105
1085
  case 'image':
1106
- return draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1086
+ data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1087
+ break;
1107
1088
  case 'linear':
1108
- return draw.PaintGradient.linearGradient(paint, boxBounds);
1089
+ data = draw.PaintGradient.linearGradient(paint, boxBounds);
1090
+ break;
1109
1091
  case 'radial':
1110
- return draw.PaintGradient.radialGradient(paint, boxBounds);
1092
+ data = draw.PaintGradient.radialGradient(paint, boxBounds);
1093
+ break;
1111
1094
  case 'angular':
1112
- return draw.PaintGradient.conicGradient(paint, boxBounds);
1095
+ data = draw.PaintGradient.conicGradient(paint, boxBounds);
1096
+ break;
1097
+ case 'solid':
1098
+ const { type, blendMode, color, opacity } = paint;
1099
+ data = { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
1100
+ break;
1113
1101
  default:
1114
- return paint.r !== undefined ? { type: 'solid', style: draw.ColorConvert.string(paint) } : undefined;
1102
+ if (paint.r !== undefined)
1103
+ data = { type: 'solid', style: draw.ColorConvert.string(paint) };
1115
1104
  }
1105
+ if (data) {
1106
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
1107
+ data.isTransparent = true;
1108
+ if (paint.blendMode)
1109
+ data.blendMode = paint.blendMode;
1110
+ }
1111
+ return data;
1116
1112
  }
1117
1113
 
1118
1114
  const PaintModule = {
@@ -1178,12 +1174,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1178
1174
 
1179
1175
  const { get: get$2, translate } = core.MatrixHelper;
1180
1176
  const tempBox = new core.Bounds();
1181
- const tempPoint = {};
1182
1177
  const tempScaleData = {};
1178
+ const tempImage = {};
1183
1179
  function createData(leafPaint, image, paint, box) {
1184
- const { blendMode, changeful, sync } = paint;
1185
- if (blendMode)
1186
- leafPaint.blendMode = blendMode;
1180
+ const { changeful, sync } = paint;
1187
1181
  if (changeful)
1188
1182
  leafPaint.changeful = changeful;
1189
1183
  if (sync)
@@ -1191,38 +1185,38 @@ function createData(leafPaint, image, paint, box) {
1191
1185
  leafPaint.data = getPatternData(paint, box, image);
1192
1186
  }
1193
1187
  function getPatternData(paint, box, image) {
1194
- let { width, height } = image;
1195
1188
  if (paint.padding)
1196
1189
  box = tempBox.set(box).shrink(paint.padding);
1197
1190
  if (paint.mode === 'strench')
1198
1191
  paint.mode = 'stretch';
1192
+ let { width, height } = image;
1199
1193
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1200
1194
  const sameBox = box.width === width && box.height === height;
1201
1195
  const data = { mode };
1202
1196
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1203
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1204
- let x = 0, y = 0, scaleX, scaleY;
1197
+ core.BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1198
+ let scaleX, scaleY;
1205
1199
  if (!mode || mode === 'cover' || mode === 'fit') {
1206
1200
  if (!sameBox || rotation) {
1207
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1208
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1209
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1201
+ scaleX = scaleY = core.BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1202
+ core.BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1203
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1210
1204
  }
1211
1205
  }
1212
- else if (scale || size) {
1213
- core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1214
- scaleX = tempScaleData.scaleX;
1215
- scaleY = tempScaleData.scaleY;
1216
- }
1217
- if (align) {
1218
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1219
- if (scaleX)
1220
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1221
- core.AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1222
- x += tempPoint.x, y += tempPoint.y;
1206
+ else {
1207
+ if (scale || size) {
1208
+ core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1209
+ scaleX = tempScaleData.scaleX;
1210
+ scaleY = tempScaleData.scaleY;
1211
+ }
1212
+ if (align) {
1213
+ if (scaleX)
1214
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1215
+ core.AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1216
+ }
1223
1217
  }
1224
1218
  if (offset)
1225
- x += offset.x, y += offset.y;
1219
+ core.PointHelper.move(tempImage, offset);
1226
1220
  switch (mode) {
1227
1221
  case 'stretch':
1228
1222
  if (!sameBox)
@@ -1230,12 +1224,12 @@ function getPatternData(paint, box, image) {
1230
1224
  break;
1231
1225
  case 'normal':
1232
1226
  case 'clip':
1233
- if (x || y || scaleX || rotation)
1234
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1227
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1228
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1235
1229
  break;
1236
1230
  case 'repeat':
1237
1231
  if (!sameBox || scaleX || rotation)
1238
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1232
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1239
1233
  if (!repeat)
1240
1234
  data.repeat = 'repeat';
1241
1235
  break;
@@ -1243,7 +1237,7 @@ function getPatternData(paint, box, image) {
1243
1237
  case 'cover':
1244
1238
  default:
1245
1239
  if (scaleX)
1246
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1240
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1247
1241
  }
1248
1242
  if (!data.transform) {
1249
1243
  if (box.x || box.y) {
@@ -1276,6 +1270,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1276
1270
  }
1277
1271
  else {
1278
1272
  leafPaint = { type: paint.type, image };
1273
+ if (image.hasAlphaPixel)
1274
+ leafPaint.isTransparent = true;
1279
1275
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1280
1276
  }
1281
1277
  if (firstUse || image.loading)
@@ -1300,7 +1296,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1300
1296
  ignoreRender(ui, false);
1301
1297
  if (!ui.destroyed) {
1302
1298
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1303
- if (image.hasOpacityPixel)
1299
+ if (image.hasAlphaPixel)
1304
1300
  ui.__layout.hitCanvasChanged = true;
1305
1301
  ui.forceUpdate('surface');
1306
1302
  }
@@ -1312,13 +1308,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1312
1308
  onLoadError(ui, event, error);
1313
1309
  leafPaint.loadId = null;
1314
1310
  });
1315
- if (ui.placeholderColor)
1316
- setTimeout(() => {
1317
- if (!(image.ready || image.isPlacehold)) {
1318
- image.isPlacehold = true;
1319
- ui.forceUpdate('surface');
1320
- }
1321
- }, 100);
1311
+ if (ui.placeholderColor) {
1312
+ if (!ui.placeholderDelay)
1313
+ image.isPlacehold = true;
1314
+ else
1315
+ setTimeout(() => {
1316
+ if (!image.ready) {
1317
+ image.isPlacehold = true;
1318
+ ui.forceUpdate('surface');
1319
+ }
1320
+ }, ui.placeholderDelay);
1321
+ }
1322
1322
  }
1323
1323
  return leafPaint;
1324
1324
  }
@@ -1556,32 +1556,33 @@ const PaintImageModule = {
1556
1556
  repeatMode
1557
1557
  };
1558
1558
 
1559
- const { toPoint: toPoint$2 } = core.AroundHelper;
1559
+ const { toPoint: toPoint$2 } = core.AroundHelper, { hasTransparent } = draw.ColorConvert;
1560
1560
  const realFrom$2 = {};
1561
1561
  const realTo$2 = {};
1562
1562
  function linearGradient(paint, box) {
1563
- let { from, to, type, blendMode, opacity } = paint;
1563
+ let { from, to, type, opacity } = paint;
1564
1564
  toPoint$2(from || 'top', box, realFrom$2);
1565
1565
  toPoint$2(to || 'bottom', box, realTo$2);
1566
1566
  const style = core.Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1567
- applyStops(style, paint.stops, opacity);
1568
1567
  const data = { type, style };
1569
- if (blendMode)
1570
- data.blendMode = blendMode;
1568
+ applyStops(data, style, paint.stops, opacity);
1571
1569
  return data;
1572
1570
  }
1573
- function applyStops(gradient, stops, opacity) {
1571
+ function applyStops(data, gradient, stops, opacity) {
1574
1572
  if (stops) {
1575
- let stop;
1573
+ let stop, color, offset, isTransparent;
1576
1574
  for (let i = 0, len = stops.length; i < len; i++) {
1577
1575
  stop = stops[i];
1578
- if (typeof stop === 'string') {
1579
- gradient.addColorStop(i / (len - 1), draw.ColorConvert.string(stop, opacity));
1580
- }
1581
- else {
1582
- gradient.addColorStop(stop.offset, draw.ColorConvert.string(stop.color, opacity));
1583
- }
1576
+ if (typeof stop === 'string')
1577
+ offset = i / (len - 1), color = draw.ColorConvert.string(stop, opacity);
1578
+ else
1579
+ offset = stop.offset, color = draw.ColorConvert.string(stop.color, opacity);
1580
+ gradient.addColorStop(offset, color);
1581
+ if (!isTransparent && hasTransparent(color))
1582
+ isTransparent = true;
1584
1583
  }
1584
+ if (isTransparent)
1585
+ data.isTransparent = true;
1585
1586
  }
1586
1587
  }
1587
1588
 
@@ -1591,17 +1592,15 @@ const { toPoint: toPoint$1 } = core.AroundHelper;
1591
1592
  const realFrom$1 = {};
1592
1593
  const realTo$1 = {};
1593
1594
  function radialGradient(paint, box) {
1594
- let { from, to, type, opacity, blendMode, stretch } = paint;
1595
+ let { from, to, type, opacity, stretch } = paint;
1595
1596
  toPoint$1(from || 'center', box, realFrom$1);
1596
1597
  toPoint$1(to || 'bottom', box, realTo$1);
1597
1598
  const style = core.Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1598
- applyStops(style, paint.stops, opacity);
1599
1599
  const data = { type, style };
1600
+ applyStops(data, style, paint.stops, opacity);
1600
1601
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1601
1602
  if (transform)
1602
1603
  data.transform = transform;
1603
- if (blendMode)
1604
- data.blendMode = blendMode;
1605
1604
  return data;
1606
1605
  }
1607
1606
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1627,17 +1626,15 @@ const { toPoint } = core.AroundHelper;
1627
1626
  const realFrom = {};
1628
1627
  const realTo = {};
1629
1628
  function conicGradient(paint, box) {
1630
- let { from, to, type, opacity, blendMode, stretch } = paint;
1629
+ let { from, to, type, opacity, stretch } = paint;
1631
1630
  toPoint(from || 'center', box, realFrom);
1632
1631
  toPoint(to || 'bottom', box, realTo);
1633
1632
  const style = core.Platform.conicGradientSupport ? core.Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : core.Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
1634
- applyStops(style, paint.stops, opacity);
1635
1633
  const data = { type, style };
1634
+ applyStops(data, style, paint.stops, opacity);
1636
1635
  const transform = getTransform(box, realFrom, realTo, stretch || 1, core.Platform.conicGradientRotate90);
1637
1636
  if (transform)
1638
1637
  data.transform = transform;
1639
- if (blendMode)
1640
- data.blendMode = blendMode;
1641
1638
  return data;
1642
1639
  }
1643
1640
 
@@ -1970,6 +1967,8 @@ function createRows(drawData, content, style) {
1970
1967
  lastCharType = null;
1971
1968
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1972
1969
  word = { data: [] }, row = { words: [] };
1970
+ if (__letterSpacing)
1971
+ content = [...content];
1973
1972
  for (let i = 0, len = content.length; i < len; i++) {
1974
1973
  char = content[i];
1975
1974
  if (char === '\n') {