@leafer-ui/worker 1.6.1 → 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.
@@ -1,9 +1,9 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, MatrixHelper, MathHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4 } from '@leafer/core';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
- import { HitCanvasManager, InteractionBase } from '@leafer-ui/core';
4
+ import { Platform as Platform$1, HitCanvasManager, InteractionBase } from '@leafer-ui/core';
5
5
  export * from '@leafer-ui/core';
6
- import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
6
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint as Paint$1, Effect } from '@leafer-ui/draw';
7
7
 
8
8
  class LeaferCanvas extends LeaferCanvasBase {
9
9
  get allowBackgroundColor() { return true; }
@@ -162,17 +162,15 @@ class Watcher {
162
162
  this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
163
163
  this.__updatedList = new LeafList();
164
164
  this.totalTimes++;
165
- this.changed = false;
166
- this.hasVisible = false;
167
- this.hasRemove = false;
168
- this.hasAdd = false;
165
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
169
166
  }
170
167
  __listenEvents() {
171
- const { target } = this;
172
168
  this.__eventIds = [
173
- target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
174
- target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
175
- target.on_(WatchEvent.REQUEST, this.__onRquestData, this)
169
+ this.target.on_([
170
+ [PropertyEvent.CHANGE, this.__onAttrChange, this],
171
+ [[ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this],
172
+ [WatchEvent.REQUEST, this.__onRquestData, this]
173
+ ])
176
174
  ];
177
175
  }
178
176
  __removeListenEvents() {
@@ -182,13 +180,12 @@ class Watcher {
182
180
  if (this.target) {
183
181
  this.stop();
184
182
  this.__removeListenEvents();
185
- this.target = null;
186
- this.__updatedList = null;
183
+ this.target = this.__updatedList = null;
187
184
  }
188
185
  }
189
186
  }
190
187
 
191
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
188
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = LeafHelper;
192
189
  const { pushAllChildBranch, pushAllParent } = BranchHelper;
193
190
  function updateMatrix(updateList, levelList) {
194
191
  let layout;
@@ -231,15 +228,7 @@ function updateBounds(boundsList) {
231
228
  });
232
229
  }
233
230
  function updateChange(updateList) {
234
- let layout;
235
- updateList.list.forEach(leaf => {
236
- layout = leaf.__layout;
237
- if (layout.opacityChanged)
238
- updateAllWorldOpacity(leaf);
239
- if (layout.stateStyleChanged)
240
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
241
- leaf.__updateChange();
242
- });
231
+ updateList.list.forEach(updateOneChange);
243
232
  }
244
233
 
245
234
  const { worldBounds } = LeafBoundsHelper;
@@ -296,7 +285,7 @@ class Layouter {
296
285
  this.disabled = true;
297
286
  }
298
287
  layout() {
299
- if (!this.running)
288
+ if (this.layouting || !this.running)
300
289
  return;
301
290
  const { target } = this;
302
291
  this.times = 0;
@@ -379,12 +368,10 @@ class Layouter {
379
368
  }
380
369
  static fullLayout(target) {
381
370
  updateAllMatrix(target, true);
382
- if (target.isBranch) {
371
+ if (target.isBranch)
383
372
  BranchHelper.updateBounds(target);
384
- }
385
- else {
373
+ else
386
374
  LeafHelper.updateBounds(target);
387
- }
388
375
  updateAllChange(target);
389
376
  }
390
377
  addExtra(leaf) {
@@ -407,11 +394,12 @@ class Layouter {
407
394
  this.__updatedList = event.data.updatedList;
408
395
  }
409
396
  __listenEvents() {
410
- const { target } = this;
411
397
  this.__eventIds = [
412
- target.on_(LayoutEvent.REQUEST, this.layout, this),
413
- target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
414
- target.on_(WatchEvent.DATA, this.__onReceiveWatchData, this)
398
+ this.target.on_([
399
+ [LayoutEvent.REQUEST, this.layout, this],
400
+ [LayoutEvent.AGAIN, this.layoutAgain, this],
401
+ [WatchEvent.DATA, this.__onReceiveWatchData, this]
402
+ ])
415
403
  ];
416
404
  }
417
405
  __removeListenEvents() {
@@ -642,12 +630,13 @@ class Renderer {
642
630
  this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
643
631
  }
644
632
  __listenEvents() {
645
- const { target } = this;
646
633
  this.__eventIds = [
647
- target.on_(RenderEvent.REQUEST, this.update, this),
648
- target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
649
- target.on_(RenderEvent.AGAIN, this.renderAgain, this),
650
- target.on_(ResizeEvent.RESIZE, this.__onResize, this)
634
+ this.target.on_([
635
+ [RenderEvent.REQUEST, this.update, this],
636
+ [LayoutEvent.END, this.__onLayoutEnd, this],
637
+ [RenderEvent.AGAIN, this.renderAgain, this],
638
+ [ResizeEvent.RESIZE, this.__onResize, this]
639
+ ])
651
640
  ];
652
641
  }
653
642
  __removeListenEvents() {
@@ -830,8 +819,10 @@ Object.assign(Creator, {
830
819
  Platform.layout = Layouter.fullLayout;
831
820
 
832
821
  function fillText(ui, canvas) {
833
- let row, data = ui.__.__textDrawData;
834
- const { rows, decorationY } = data;
822
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
823
+ if (data.__isPlacehold && data.placeholderColor)
824
+ canvas.fillStyle = data.placeholderColor;
825
+ let row;
835
826
  for (let i = 0, len = rows.length; i < len; i++) {
836
827
  row = rows[i];
837
828
  if (row.text)
@@ -840,7 +831,7 @@ function fillText(ui, canvas) {
840
831
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
841
832
  }
842
833
  if (decorationY) {
843
- const { decorationColor, decorationHeight } = data;
834
+ const { decorationColor, decorationHeight } = data.__textDrawData;
844
835
  if (decorationColor)
845
836
  canvas.fillStyle = decorationColor;
846
837
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -849,65 +840,73 @@ function fillText(ui, canvas) {
849
840
 
850
841
  function fill(fill, ui, canvas) {
851
842
  canvas.fillStyle = fill;
852
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
843
+ fillPathOrText(ui, canvas);
853
844
  }
854
845
  function fills(fills, ui, canvas) {
855
846
  let item;
856
- const { windingRule, __font } = ui.__;
857
847
  for (let i = 0, len = fills.length; i < len; i++) {
858
848
  item = fills[i];
859
- if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
860
- continue;
861
- if (item.style) {
862
- canvas.fillStyle = item.style;
863
- if (item.transform) {
864
- canvas.save();
865
- canvas.transform(item.transform);
866
- if (item.blendMode)
867
- canvas.blendMode = item.blendMode;
868
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
869
- canvas.restore();
849
+ if (item.image) {
850
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
851
+ continue;
852
+ if (!item.style) {
853
+ if (!i && item.image.isPlacehold)
854
+ ui.drawImagePlaceholder(canvas, item.image);
855
+ continue;
870
856
  }
871
- else {
872
- if (item.blendMode) {
873
- canvas.saveBlendMode(item.blendMode);
874
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
875
- canvas.restoreBlendMode();
876
- }
877
- else {
878
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
879
- }
857
+ }
858
+ canvas.fillStyle = item.style;
859
+ if (item.transform) {
860
+ canvas.save();
861
+ canvas.transform(item.transform);
862
+ if (item.blendMode)
863
+ canvas.blendMode = item.blendMode;
864
+ fillPathOrText(ui, canvas);
865
+ canvas.restore();
866
+ }
867
+ else {
868
+ if (item.blendMode) {
869
+ canvas.saveBlendMode(item.blendMode);
870
+ fillPathOrText(ui, canvas);
871
+ canvas.restoreBlendMode();
880
872
  }
873
+ else
874
+ fillPathOrText(ui, canvas);
881
875
  }
882
876
  }
883
877
  }
878
+ function fillPathOrText(ui, canvas) {
879
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
880
+ }
881
+
882
+ const Paint = {};
884
883
 
885
884
  function strokeText(stroke, ui, canvas) {
886
- const { strokeAlign } = ui.__;
887
- const isStrokes = typeof stroke !== 'string';
888
- switch (strokeAlign) {
885
+ switch (ui.__.strokeAlign) {
889
886
  case 'center':
890
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
891
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
887
+ drawCenter$1(stroke, 1, ui, canvas);
892
888
  break;
893
889
  case 'inside':
894
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
890
+ drawAlign(stroke, 'inside', ui, canvas);
895
891
  break;
896
892
  case 'outside':
897
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
893
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
898
894
  break;
899
895
  }
900
896
  }
901
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
902
- const { __strokeWidth, __font } = ui.__;
897
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
898
+ const data = ui.__;
899
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
900
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
901
+ }
902
+ function drawAlign(stroke, align, ui, canvas) {
903
903
  const out = canvas.getSameCanvas(true, true);
904
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
905
- out.font = __font;
906
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
904
+ out.font = ui.__.__font;
905
+ drawCenter$1(stroke, 2, ui, out);
907
906
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
908
907
  fillText(ui, out);
909
908
  out.blendMode = 'normal';
910
- if (ui.__worldFlipped)
909
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
911
910
  canvas.copyWorldByReset(out, ui.__nowWorld);
912
911
  else
913
912
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -949,90 +948,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
949
948
  }
950
949
 
951
950
  function stroke(stroke, ui, canvas) {
952
- const options = ui.__;
953
- const { __strokeWidth, strokeAlign, __font } = options;
954
- if (!__strokeWidth)
951
+ const data = ui.__;
952
+ if (!data.__strokeWidth)
955
953
  return;
956
- if (__font) {
954
+ if (data.__font) {
957
955
  strokeText(stroke, ui, canvas);
958
956
  }
959
957
  else {
960
- switch (strokeAlign) {
958
+ switch (data.strokeAlign) {
961
959
  case 'center':
962
- canvas.setStroke(stroke, __strokeWidth, options);
963
- canvas.stroke();
964
- if (options.__useArrow)
965
- strokeArrow(ui, canvas);
960
+ drawCenter(stroke, 1, ui, canvas);
966
961
  break;
967
962
  case 'inside':
968
- canvas.save();
969
- canvas.setStroke(stroke, __strokeWidth * 2, options);
970
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
971
- canvas.stroke();
972
- canvas.restore();
963
+ drawInside(stroke, ui, canvas);
973
964
  break;
974
965
  case 'outside':
975
- const out = canvas.getSameCanvas(true, true);
976
- out.setStroke(stroke, __strokeWidth * 2, options);
977
- ui.__drawRenderPath(out);
978
- out.stroke();
979
- options.windingRule ? out.clip(options.windingRule) : out.clip();
980
- out.clearWorld(ui.__layout.renderBounds);
981
- if (ui.__worldFlipped)
982
- canvas.copyWorldByReset(out, ui.__nowWorld);
983
- else
984
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
985
- out.recycle(ui.__nowWorld);
966
+ drawOutside(stroke, ui, canvas);
986
967
  break;
987
968
  }
988
969
  }
989
970
  }
990
971
  function strokes(strokes, ui, canvas) {
991
- const options = ui.__;
992
- const { __strokeWidth, strokeAlign, __font } = options;
993
- if (!__strokeWidth)
994
- return;
995
- if (__font) {
996
- strokeText(strokes, ui, canvas);
972
+ stroke(strokes, ui, canvas);
973
+ }
974
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
975
+ const data = ui.__;
976
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
977
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
978
+ if (data.__useArrow)
979
+ Paint.strokeArrow(stroke, ui, canvas);
980
+ }
981
+ function drawInside(stroke, ui, canvas) {
982
+ const data = ui.__;
983
+ canvas.save();
984
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
985
+ drawCenter(stroke, 2, ui, canvas);
986
+ canvas.restore();
987
+ }
988
+ function drawOutside(stroke, ui, canvas) {
989
+ const data = ui.__;
990
+ if (data.__fillAfterStroke) {
991
+ drawCenter(stroke, 2, ui, canvas);
997
992
  }
998
993
  else {
999
- switch (strokeAlign) {
1000
- case 'center':
1001
- canvas.setStroke(undefined, __strokeWidth, options);
1002
- drawStrokesStyle(strokes, false, ui, canvas);
1003
- if (options.__useArrow)
1004
- strokeArrow(ui, canvas);
1005
- break;
1006
- case 'inside':
1007
- canvas.save();
1008
- canvas.setStroke(undefined, __strokeWidth * 2, options);
1009
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1010
- drawStrokesStyle(strokes, false, ui, canvas);
1011
- canvas.restore();
1012
- break;
1013
- case 'outside':
1014
- const { renderBounds } = ui.__layout;
1015
- const out = canvas.getSameCanvas(true, true);
1016
- ui.__drawRenderPath(out);
1017
- out.setStroke(undefined, __strokeWidth * 2, options);
1018
- drawStrokesStyle(strokes, false, ui, out);
1019
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1020
- out.clearWorld(renderBounds);
1021
- if (ui.__worldFlipped)
1022
- canvas.copyWorldByReset(out, ui.__nowWorld);
1023
- else
1024
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1025
- out.recycle(ui.__nowWorld);
1026
- break;
1027
- }
1028
- }
1029
- }
1030
- function strokeArrow(ui, canvas) {
1031
- if (ui.__.dashPattern) {
1032
- canvas.beginPath();
1033
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
1034
- canvas.dashPattern = null;
1035
- canvas.stroke();
994
+ const { renderBounds } = ui.__layout;
995
+ const out = canvas.getSameCanvas(true, true);
996
+ ui.__drawRenderPath(out);
997
+ drawCenter(stroke, 2, ui, out);
998
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
999
+ out.clearWorld(renderBounds);
1000
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
1001
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1002
+ else
1003
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1004
+ out.recycle(ui.__nowWorld);
1036
1005
  }
1037
1006
  }
1038
1007
 
@@ -1079,9 +1048,10 @@ function shape(ui, current, options) {
1079
1048
  }
1080
1049
 
1081
1050
  let recycleMap;
1051
+ const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
1082
1052
  function compute(attrName, ui) {
1083
1053
  const data = ui.__, leafPaints = [];
1084
- let paints = data.__input[attrName], hasOpacityPixel;
1054
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
1085
1055
  if (!(paints instanceof Array))
1086
1056
  paints = [paints];
1087
1057
  recycleMap = PaintImage.recycleImage(attrName, data);
@@ -1091,35 +1061,62 @@ function compute(attrName, ui) {
1091
1061
  leafPaints.push(item);
1092
1062
  }
1093
1063
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1094
- if (leafPaints.length && leafPaints[0].image)
1095
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1096
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
1064
+ if (leafPaints.length) {
1065
+ if (leafPaints.every(item => item.isTransparent)) {
1066
+ if (leafPaints.some(item => item.image))
1067
+ isAlphaPixel = true;
1068
+ isTransparent = true;
1069
+ }
1070
+ }
1071
+ if (attrName === 'fill') {
1072
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
1073
+ stintSet(data, '__isTransparentFill', isTransparent);
1074
+ }
1075
+ else {
1076
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
1077
+ stintSet(data, '__isTransparentStroke', isTransparent);
1078
+ }
1097
1079
  }
1098
1080
  function getLeafPaint(attrName, paint, ui) {
1099
1081
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1100
1082
  return undefined;
1083
+ let data;
1101
1084
  const { boxBounds } = ui.__layout;
1102
1085
  switch (paint.type) {
1103
- case 'solid':
1104
- let { type, blendMode, color, opacity } = paint;
1105
- return { type, blendMode, style: ColorConvert.string(color, opacity) };
1106
1086
  case 'image':
1107
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1087
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1088
+ break;
1108
1089
  case 'linear':
1109
- return PaintGradient.linearGradient(paint, boxBounds);
1090
+ data = PaintGradient.linearGradient(paint, boxBounds);
1091
+ break;
1110
1092
  case 'radial':
1111
- return PaintGradient.radialGradient(paint, boxBounds);
1093
+ data = PaintGradient.radialGradient(paint, boxBounds);
1094
+ break;
1112
1095
  case 'angular':
1113
- return PaintGradient.conicGradient(paint, boxBounds);
1096
+ data = PaintGradient.conicGradient(paint, boxBounds);
1097
+ break;
1098
+ case 'solid':
1099
+ const { type, blendMode, color, opacity } = paint;
1100
+ data = { type, blendMode, style: ColorConvert.string(color, opacity) };
1101
+ break;
1114
1102
  default:
1115
- return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1103
+ if (paint.r !== undefined)
1104
+ data = { type: 'solid', style: ColorConvert.string(paint) };
1105
+ }
1106
+ if (data) {
1107
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
1108
+ data.isTransparent = true;
1109
+ if (paint.blendMode)
1110
+ data.blendMode = paint.blendMode;
1116
1111
  }
1112
+ return data;
1117
1113
  }
1118
1114
 
1119
1115
  const PaintModule = {
1120
1116
  compute,
1121
1117
  fill,
1122
1118
  fills,
1119
+ fillPathOrText,
1123
1120
  fillText,
1124
1121
  stroke,
1125
1122
  strokes,
@@ -1178,12 +1175,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1178
1175
 
1179
1176
  const { get: get$2, translate } = MatrixHelper;
1180
1177
  const tempBox = new Bounds();
1181
- const tempPoint = {};
1182
1178
  const tempScaleData = {};
1179
+ const tempImage = {};
1183
1180
  function createData(leafPaint, image, paint, box) {
1184
- const { blendMode, changeful, sync } = paint;
1185
- if (blendMode)
1186
- leafPaint.blendMode = blendMode;
1181
+ const { changeful, sync } = paint;
1187
1182
  if (changeful)
1188
1183
  leafPaint.changeful = changeful;
1189
1184
  if (sync)
@@ -1191,38 +1186,38 @@ function createData(leafPaint, image, paint, box) {
1191
1186
  leafPaint.data = getPatternData(paint, box, image);
1192
1187
  }
1193
1188
  function getPatternData(paint, box, image) {
1194
- let { width, height } = image;
1195
1189
  if (paint.padding)
1196
1190
  box = tempBox.set(box).shrink(paint.padding);
1197
1191
  if (paint.mode === 'strench')
1198
1192
  paint.mode = 'stretch';
1193
+ let { width, height } = image;
1199
1194
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1200
1195
  const sameBox = box.width === width && box.height === height;
1201
1196
  const data = { mode };
1202
1197
  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;
1198
+ BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1199
+ let scaleX, scaleY;
1205
1200
  if (!mode || mode === 'cover' || mode === 'fit') {
1206
1201
  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;
1202
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1203
+ BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1204
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1210
1205
  }
1211
1206
  }
1212
- else if (scale || size) {
1213
- 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
- AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1222
- x += tempPoint.x, y += tempPoint.y;
1207
+ else {
1208
+ if (scale || size) {
1209
+ MathHelper.getScaleData(scale, size, image, tempScaleData);
1210
+ scaleX = tempScaleData.scaleX;
1211
+ scaleY = tempScaleData.scaleY;
1212
+ }
1213
+ if (align) {
1214
+ if (scaleX)
1215
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1216
+ AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1217
+ }
1223
1218
  }
1224
1219
  if (offset)
1225
- x += offset.x, y += offset.y;
1220
+ PointHelper.move(tempImage, offset);
1226
1221
  switch (mode) {
1227
1222
  case 'stretch':
1228
1223
  if (!sameBox)
@@ -1230,12 +1225,12 @@ function getPatternData(paint, box, image) {
1230
1225
  break;
1231
1226
  case 'normal':
1232
1227
  case 'clip':
1233
- if (x || y || scaleX || rotation)
1234
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1228
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1229
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1235
1230
  break;
1236
1231
  case 'repeat':
1237
1232
  if (!sameBox || scaleX || rotation)
1238
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1233
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1239
1234
  if (!repeat)
1240
1235
  data.repeat = 'repeat';
1241
1236
  break;
@@ -1243,7 +1238,7 @@ function getPatternData(paint, box, image) {
1243
1238
  case 'cover':
1244
1239
  default:
1245
1240
  if (scaleX)
1246
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1241
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1247
1242
  }
1248
1243
  if (!data.transform) {
1249
1244
  if (box.x || box.y) {
@@ -1276,6 +1271,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1276
1271
  }
1277
1272
  else {
1278
1273
  leafPaint = { type: paint.type, image };
1274
+ if (image.hasAlphaPixel)
1275
+ leafPaint.isTransparent = true;
1279
1276
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1280
1277
  }
1281
1278
  if (firstUse || image.loading)
@@ -1300,7 +1297,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1300
1297
  ignoreRender(ui, false);
1301
1298
  if (!ui.destroyed) {
1302
1299
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1303
- if (image.hasOpacityPixel)
1300
+ if (image.hasAlphaPixel)
1304
1301
  ui.__layout.hitCanvasChanged = true;
1305
1302
  ui.forceUpdate('surface');
1306
1303
  }
@@ -1312,6 +1309,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1312
1309
  onLoadError(ui, event, error);
1313
1310
  leafPaint.loadId = null;
1314
1311
  });
1312
+ if (ui.placeholderColor) {
1313
+ if (!ui.placeholderDelay)
1314
+ image.isPlacehold = true;
1315
+ else
1316
+ setTimeout(() => {
1317
+ if (!image.ready) {
1318
+ image.isPlacehold = true;
1319
+ ui.forceUpdate('surface');
1320
+ }
1321
+ }, ui.placeholderDelay);
1322
+ }
1315
1323
  }
1316
1324
  return leafPaint;
1317
1325
  }
@@ -1549,32 +1557,33 @@ const PaintImageModule = {
1549
1557
  repeatMode
1550
1558
  };
1551
1559
 
1552
- const { toPoint: toPoint$2 } = AroundHelper;
1560
+ const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1553
1561
  const realFrom$2 = {};
1554
1562
  const realTo$2 = {};
1555
1563
  function linearGradient(paint, box) {
1556
- let { from, to, type, blendMode, opacity } = paint;
1564
+ let { from, to, type, opacity } = paint;
1557
1565
  toPoint$2(from || 'top', box, realFrom$2);
1558
1566
  toPoint$2(to || 'bottom', box, realTo$2);
1559
1567
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1560
- applyStops(style, paint.stops, opacity);
1561
1568
  const data = { type, style };
1562
- if (blendMode)
1563
- data.blendMode = blendMode;
1569
+ applyStops(data, style, paint.stops, opacity);
1564
1570
  return data;
1565
1571
  }
1566
- function applyStops(gradient, stops, opacity) {
1572
+ function applyStops(data, gradient, stops, opacity) {
1567
1573
  if (stops) {
1568
- let stop;
1574
+ let stop, color, offset, isTransparent;
1569
1575
  for (let i = 0, len = stops.length; i < len; i++) {
1570
1576
  stop = stops[i];
1571
- if (typeof stop === 'string') {
1572
- gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1573
- }
1574
- else {
1575
- gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1576
- }
1577
+ if (typeof stop === 'string')
1578
+ offset = i / (len - 1), color = ColorConvert.string(stop, opacity);
1579
+ else
1580
+ offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
1581
+ gradient.addColorStop(offset, color);
1582
+ if (!isTransparent && hasTransparent(color))
1583
+ isTransparent = true;
1577
1584
  }
1585
+ if (isTransparent)
1586
+ data.isTransparent = true;
1578
1587
  }
1579
1588
  }
1580
1589
 
@@ -1584,17 +1593,15 @@ const { toPoint: toPoint$1 } = AroundHelper;
1584
1593
  const realFrom$1 = {};
1585
1594
  const realTo$1 = {};
1586
1595
  function radialGradient(paint, box) {
1587
- let { from, to, type, opacity, blendMode, stretch } = paint;
1596
+ let { from, to, type, opacity, stretch } = paint;
1588
1597
  toPoint$1(from || 'center', box, realFrom$1);
1589
1598
  toPoint$1(to || 'bottom', box, realTo$1);
1590
1599
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1591
- applyStops(style, paint.stops, opacity);
1592
1600
  const data = { type, style };
1601
+ applyStops(data, style, paint.stops, opacity);
1593
1602
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1594
1603
  if (transform)
1595
1604
  data.transform = transform;
1596
- if (blendMode)
1597
- data.blendMode = blendMode;
1598
1605
  return data;
1599
1606
  }
1600
1607
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1620,17 +1627,15 @@ const { toPoint } = AroundHelper;
1620
1627
  const realFrom = {};
1621
1628
  const realTo = {};
1622
1629
  function conicGradient(paint, box) {
1623
- let { from, to, type, opacity, blendMode, stretch } = paint;
1630
+ let { from, to, type, opacity, stretch } = paint;
1624
1631
  toPoint(from || 'center', box, realFrom);
1625
1632
  toPoint(to || 'bottom', box, realTo);
1626
1633
  const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
1627
- applyStops(style, paint.stops, opacity);
1628
1634
  const data = { type, style };
1635
+ applyStops(data, style, paint.stops, opacity);
1629
1636
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1630
1637
  if (transform)
1631
1638
  data.transform = transform;
1632
- if (blendMode)
1633
- data.blendMode = blendMode;
1634
1639
  return data;
1635
1640
  }
1636
1641
 
@@ -1963,6 +1968,8 @@ function createRows(drawData, content, style) {
1963
1968
  lastCharType = null;
1964
1969
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1965
1970
  word = { data: [] }, row = { words: [] };
1971
+ if (__letterSpacing)
1972
+ content = [...content];
1966
1973
  for (let i = 0, len = content.length; i < len; i++) {
1967
1974
  char = content[i];
1968
1975
  if (char === '\n') {
@@ -2369,7 +2376,7 @@ const ColorConvertModule = {
2369
2376
 
2370
2377
  Object.assign(TextConvert, TextConvertModule);
2371
2378
  Object.assign(ColorConvert, ColorConvertModule);
2372
- Object.assign(Paint, PaintModule);
2379
+ Object.assign(Paint$1, PaintModule);
2373
2380
  Object.assign(PaintImage, PaintImageModule);
2374
2381
  Object.assign(PaintGradient, PaintGradientModule);
2375
2382
  Object.assign(Effect, EffectModule);
@@ -2382,4 +2389,3 @@ Object.assign(Creator, {
2382
2389
  useCanvas();
2383
2390
 
2384
2391
  export { Layouter, LeaferCanvas, Picker, Renderer, Selector, Watcher, useCanvas };
2385
- //# sourceMappingURL=worker.esm.js.map