@leafer-draw/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,8 +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, 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, 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 { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
4
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint as Paint$1, Effect } from '@leafer-ui/draw';
5
5
  export * from '@leafer-ui/draw';
6
+ import { Platform as Platform$1 } from '@leafer-ui/core';
6
7
 
7
8
  class LeaferCanvas extends LeaferCanvasBase {
8
9
  get allowBackgroundColor() { return true; }
@@ -161,17 +162,15 @@ class Watcher {
161
162
  this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
162
163
  this.__updatedList = new LeafList();
163
164
  this.totalTimes++;
164
- this.changed = false;
165
- this.hasVisible = false;
166
- this.hasRemove = false;
167
- this.hasAdd = false;
165
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
168
166
  }
169
167
  __listenEvents() {
170
- const { target } = this;
171
168
  this.__eventIds = [
172
- target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
173
- target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
174
- 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
+ ])
175
174
  ];
176
175
  }
177
176
  __removeListenEvents() {
@@ -181,13 +180,12 @@ class Watcher {
181
180
  if (this.target) {
182
181
  this.stop();
183
182
  this.__removeListenEvents();
184
- this.target = null;
185
- this.__updatedList = null;
183
+ this.target = this.__updatedList = null;
186
184
  }
187
185
  }
188
186
  }
189
187
 
190
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
188
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = LeafHelper;
191
189
  const { pushAllChildBranch, pushAllParent } = BranchHelper;
192
190
  function updateMatrix(updateList, levelList) {
193
191
  let layout;
@@ -230,15 +228,7 @@ function updateBounds(boundsList) {
230
228
  });
231
229
  }
232
230
  function updateChange(updateList) {
233
- let layout;
234
- updateList.list.forEach(leaf => {
235
- layout = leaf.__layout;
236
- if (layout.opacityChanged)
237
- updateAllWorldOpacity(leaf);
238
- if (layout.stateStyleChanged)
239
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
240
- leaf.__updateChange();
241
- });
231
+ updateList.list.forEach(updateOneChange);
242
232
  }
243
233
 
244
234
  const { worldBounds } = LeafBoundsHelper;
@@ -295,7 +285,7 @@ class Layouter {
295
285
  this.disabled = true;
296
286
  }
297
287
  layout() {
298
- if (!this.running)
288
+ if (this.layouting || !this.running)
299
289
  return;
300
290
  const { target } = this;
301
291
  this.times = 0;
@@ -378,12 +368,10 @@ class Layouter {
378
368
  }
379
369
  static fullLayout(target) {
380
370
  updateAllMatrix(target, true);
381
- if (target.isBranch) {
371
+ if (target.isBranch)
382
372
  BranchHelper.updateBounds(target);
383
- }
384
- else {
373
+ else
385
374
  LeafHelper.updateBounds(target);
386
- }
387
375
  updateAllChange(target);
388
376
  }
389
377
  addExtra(leaf) {
@@ -406,11 +394,12 @@ class Layouter {
406
394
  this.__updatedList = event.data.updatedList;
407
395
  }
408
396
  __listenEvents() {
409
- const { target } = this;
410
397
  this.__eventIds = [
411
- target.on_(LayoutEvent.REQUEST, this.layout, this),
412
- target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
413
- 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
+ ])
414
403
  ];
415
404
  }
416
405
  __removeListenEvents() {
@@ -641,12 +630,13 @@ class Renderer {
641
630
  this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
642
631
  }
643
632
  __listenEvents() {
644
- const { target } = this;
645
633
  this.__eventIds = [
646
- target.on_(RenderEvent.REQUEST, this.update, this),
647
- target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
648
- target.on_(RenderEvent.AGAIN, this.renderAgain, this),
649
- 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
+ ])
650
640
  ];
651
641
  }
652
642
  __removeListenEvents() {
@@ -672,8 +662,10 @@ Object.assign(Creator, {
672
662
  Platform.layout = Layouter.fullLayout;
673
663
 
674
664
  function fillText(ui, canvas) {
675
- let row, data = ui.__.__textDrawData;
676
- const { rows, decorationY } = data;
665
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
666
+ if (data.__isPlacehold && data.placeholderColor)
667
+ canvas.fillStyle = data.placeholderColor;
668
+ let row;
677
669
  for (let i = 0, len = rows.length; i < len; i++) {
678
670
  row = rows[i];
679
671
  if (row.text)
@@ -682,7 +674,7 @@ function fillText(ui, canvas) {
682
674
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
683
675
  }
684
676
  if (decorationY) {
685
- const { decorationColor, decorationHeight } = data;
677
+ const { decorationColor, decorationHeight } = data.__textDrawData;
686
678
  if (decorationColor)
687
679
  canvas.fillStyle = decorationColor;
688
680
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -691,65 +683,73 @@ function fillText(ui, canvas) {
691
683
 
692
684
  function fill(fill, ui, canvas) {
693
685
  canvas.fillStyle = fill;
694
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
686
+ fillPathOrText(ui, canvas);
695
687
  }
696
688
  function fills(fills, ui, canvas) {
697
689
  let item;
698
- const { windingRule, __font } = ui.__;
699
690
  for (let i = 0, len = fills.length; i < len; i++) {
700
691
  item = fills[i];
701
- if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
702
- continue;
703
- if (item.style) {
704
- canvas.fillStyle = item.style;
705
- if (item.transform) {
706
- canvas.save();
707
- canvas.transform(item.transform);
708
- if (item.blendMode)
709
- canvas.blendMode = item.blendMode;
710
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
711
- canvas.restore();
692
+ if (item.image) {
693
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
694
+ continue;
695
+ if (!item.style) {
696
+ if (!i && item.image.isPlacehold)
697
+ ui.drawImagePlaceholder(canvas, item.image);
698
+ continue;
712
699
  }
713
- else {
714
- if (item.blendMode) {
715
- canvas.saveBlendMode(item.blendMode);
716
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
717
- canvas.restoreBlendMode();
718
- }
719
- else {
720
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
721
- }
700
+ }
701
+ canvas.fillStyle = item.style;
702
+ if (item.transform) {
703
+ canvas.save();
704
+ canvas.transform(item.transform);
705
+ if (item.blendMode)
706
+ canvas.blendMode = item.blendMode;
707
+ fillPathOrText(ui, canvas);
708
+ canvas.restore();
709
+ }
710
+ else {
711
+ if (item.blendMode) {
712
+ canvas.saveBlendMode(item.blendMode);
713
+ fillPathOrText(ui, canvas);
714
+ canvas.restoreBlendMode();
722
715
  }
716
+ else
717
+ fillPathOrText(ui, canvas);
723
718
  }
724
719
  }
725
720
  }
721
+ function fillPathOrText(ui, canvas) {
722
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
723
+ }
724
+
725
+ const Paint = {};
726
726
 
727
727
  function strokeText(stroke, ui, canvas) {
728
- const { strokeAlign } = ui.__;
729
- const isStrokes = typeof stroke !== 'string';
730
- switch (strokeAlign) {
728
+ switch (ui.__.strokeAlign) {
731
729
  case 'center':
732
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
733
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
730
+ drawCenter$1(stroke, 1, ui, canvas);
734
731
  break;
735
732
  case 'inside':
736
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
733
+ drawAlign(stroke, 'inside', ui, canvas);
737
734
  break;
738
735
  case 'outside':
739
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
736
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
740
737
  break;
741
738
  }
742
739
  }
743
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
744
- const { __strokeWidth, __font } = ui.__;
740
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
741
+ const data = ui.__;
742
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
743
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
744
+ }
745
+ function drawAlign(stroke, align, ui, canvas) {
745
746
  const out = canvas.getSameCanvas(true, true);
746
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
747
- out.font = __font;
748
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
747
+ out.font = ui.__.__font;
748
+ drawCenter$1(stroke, 2, ui, out);
749
749
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
750
750
  fillText(ui, out);
751
751
  out.blendMode = 'normal';
752
- if (ui.__worldFlipped)
752
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
753
753
  canvas.copyWorldByReset(out, ui.__nowWorld);
754
754
  else
755
755
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -791,90 +791,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
791
791
  }
792
792
 
793
793
  function stroke(stroke, ui, canvas) {
794
- const options = ui.__;
795
- const { __strokeWidth, strokeAlign, __font } = options;
796
- if (!__strokeWidth)
794
+ const data = ui.__;
795
+ if (!data.__strokeWidth)
797
796
  return;
798
- if (__font) {
797
+ if (data.__font) {
799
798
  strokeText(stroke, ui, canvas);
800
799
  }
801
800
  else {
802
- switch (strokeAlign) {
801
+ switch (data.strokeAlign) {
803
802
  case 'center':
804
- canvas.setStroke(stroke, __strokeWidth, options);
805
- canvas.stroke();
806
- if (options.__useArrow)
807
- strokeArrow(ui, canvas);
803
+ drawCenter(stroke, 1, ui, canvas);
808
804
  break;
809
805
  case 'inside':
810
- canvas.save();
811
- canvas.setStroke(stroke, __strokeWidth * 2, options);
812
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
813
- canvas.stroke();
814
- canvas.restore();
806
+ drawInside(stroke, ui, canvas);
815
807
  break;
816
808
  case 'outside':
817
- const out = canvas.getSameCanvas(true, true);
818
- out.setStroke(stroke, __strokeWidth * 2, options);
819
- ui.__drawRenderPath(out);
820
- out.stroke();
821
- options.windingRule ? out.clip(options.windingRule) : out.clip();
822
- out.clearWorld(ui.__layout.renderBounds);
823
- if (ui.__worldFlipped)
824
- canvas.copyWorldByReset(out, ui.__nowWorld);
825
- else
826
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
827
- out.recycle(ui.__nowWorld);
809
+ drawOutside(stroke, ui, canvas);
828
810
  break;
829
811
  }
830
812
  }
831
813
  }
832
814
  function strokes(strokes, ui, canvas) {
833
- const options = ui.__;
834
- const { __strokeWidth, strokeAlign, __font } = options;
835
- if (!__strokeWidth)
836
- return;
837
- if (__font) {
838
- strokeText(strokes, ui, canvas);
815
+ stroke(strokes, ui, canvas);
816
+ }
817
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
818
+ const data = ui.__;
819
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
820
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
821
+ if (data.__useArrow)
822
+ Paint.strokeArrow(stroke, ui, canvas);
823
+ }
824
+ function drawInside(stroke, ui, canvas) {
825
+ const data = ui.__;
826
+ canvas.save();
827
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
828
+ drawCenter(stroke, 2, ui, canvas);
829
+ canvas.restore();
830
+ }
831
+ function drawOutside(stroke, ui, canvas) {
832
+ const data = ui.__;
833
+ if (data.__fillAfterStroke) {
834
+ drawCenter(stroke, 2, ui, canvas);
839
835
  }
840
836
  else {
841
- switch (strokeAlign) {
842
- case 'center':
843
- canvas.setStroke(undefined, __strokeWidth, options);
844
- drawStrokesStyle(strokes, false, ui, canvas);
845
- if (options.__useArrow)
846
- strokeArrow(ui, canvas);
847
- break;
848
- case 'inside':
849
- canvas.save();
850
- canvas.setStroke(undefined, __strokeWidth * 2, options);
851
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
852
- drawStrokesStyle(strokes, false, ui, canvas);
853
- canvas.restore();
854
- break;
855
- case 'outside':
856
- const { renderBounds } = ui.__layout;
857
- const out = canvas.getSameCanvas(true, true);
858
- ui.__drawRenderPath(out);
859
- out.setStroke(undefined, __strokeWidth * 2, options);
860
- drawStrokesStyle(strokes, false, ui, out);
861
- options.windingRule ? out.clip(options.windingRule) : out.clip();
862
- out.clearWorld(renderBounds);
863
- if (ui.__worldFlipped)
864
- canvas.copyWorldByReset(out, ui.__nowWorld);
865
- else
866
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
867
- out.recycle(ui.__nowWorld);
868
- break;
869
- }
870
- }
871
- }
872
- function strokeArrow(ui, canvas) {
873
- if (ui.__.dashPattern) {
874
- canvas.beginPath();
875
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
876
- canvas.dashPattern = null;
877
- canvas.stroke();
837
+ const { renderBounds } = ui.__layout;
838
+ const out = canvas.getSameCanvas(true, true);
839
+ ui.__drawRenderPath(out);
840
+ drawCenter(stroke, 2, ui, out);
841
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
842
+ out.clearWorld(renderBounds);
843
+ if (ui.__worldFlipped || Platform$1.fullImageShadow)
844
+ canvas.copyWorldByReset(out, ui.__nowWorld);
845
+ else
846
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
847
+ out.recycle(ui.__nowWorld);
878
848
  }
879
849
  }
880
850
 
@@ -921,9 +891,10 @@ function shape(ui, current, options) {
921
891
  }
922
892
 
923
893
  let recycleMap;
894
+ const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
924
895
  function compute(attrName, ui) {
925
896
  const data = ui.__, leafPaints = [];
926
- let paints = data.__input[attrName], hasOpacityPixel;
897
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
927
898
  if (!(paints instanceof Array))
928
899
  paints = [paints];
929
900
  recycleMap = PaintImage.recycleImage(attrName, data);
@@ -933,35 +904,62 @@ function compute(attrName, ui) {
933
904
  leafPaints.push(item);
934
905
  }
935
906
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
936
- if (leafPaints.length && leafPaints[0].image)
937
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
938
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
907
+ if (leafPaints.length) {
908
+ if (leafPaints.every(item => item.isTransparent)) {
909
+ if (leafPaints.some(item => item.image))
910
+ isAlphaPixel = true;
911
+ isTransparent = true;
912
+ }
913
+ }
914
+ if (attrName === 'fill') {
915
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
916
+ stintSet(data, '__isTransparentFill', isTransparent);
917
+ }
918
+ else {
919
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
920
+ stintSet(data, '__isTransparentStroke', isTransparent);
921
+ }
939
922
  }
940
923
  function getLeafPaint(attrName, paint, ui) {
941
924
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
942
925
  return undefined;
926
+ let data;
943
927
  const { boxBounds } = ui.__layout;
944
928
  switch (paint.type) {
945
- case 'solid':
946
- let { type, blendMode, color, opacity } = paint;
947
- return { type, blendMode, style: ColorConvert.string(color, opacity) };
948
929
  case 'image':
949
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
930
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
931
+ break;
950
932
  case 'linear':
951
- return PaintGradient.linearGradient(paint, boxBounds);
933
+ data = PaintGradient.linearGradient(paint, boxBounds);
934
+ break;
952
935
  case 'radial':
953
- return PaintGradient.radialGradient(paint, boxBounds);
936
+ data = PaintGradient.radialGradient(paint, boxBounds);
937
+ break;
954
938
  case 'angular':
955
- return PaintGradient.conicGradient(paint, boxBounds);
939
+ data = PaintGradient.conicGradient(paint, boxBounds);
940
+ break;
941
+ case 'solid':
942
+ const { type, blendMode, color, opacity } = paint;
943
+ data = { type, blendMode, style: ColorConvert.string(color, opacity) };
944
+ break;
956
945
  default:
957
- return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
946
+ if (paint.r !== undefined)
947
+ data = { type: 'solid', style: ColorConvert.string(paint) };
948
+ }
949
+ if (data) {
950
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
951
+ data.isTransparent = true;
952
+ if (paint.blendMode)
953
+ data.blendMode = paint.blendMode;
958
954
  }
955
+ return data;
959
956
  }
960
957
 
961
958
  const PaintModule = {
962
959
  compute,
963
960
  fill,
964
961
  fills,
962
+ fillPathOrText,
965
963
  fillText,
966
964
  stroke,
967
965
  strokes,
@@ -1020,12 +1018,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1020
1018
 
1021
1019
  const { get: get$2, translate } = MatrixHelper;
1022
1020
  const tempBox = new Bounds();
1023
- const tempPoint = {};
1024
1021
  const tempScaleData = {};
1022
+ const tempImage = {};
1025
1023
  function createData(leafPaint, image, paint, box) {
1026
- const { blendMode, changeful, sync } = paint;
1027
- if (blendMode)
1028
- leafPaint.blendMode = blendMode;
1024
+ const { changeful, sync } = paint;
1029
1025
  if (changeful)
1030
1026
  leafPaint.changeful = changeful;
1031
1027
  if (sync)
@@ -1033,38 +1029,38 @@ function createData(leafPaint, image, paint, box) {
1033
1029
  leafPaint.data = getPatternData(paint, box, image);
1034
1030
  }
1035
1031
  function getPatternData(paint, box, image) {
1036
- let { width, height } = image;
1037
1032
  if (paint.padding)
1038
1033
  box = tempBox.set(box).shrink(paint.padding);
1039
1034
  if (paint.mode === 'strench')
1040
1035
  paint.mode = 'stretch';
1036
+ let { width, height } = image;
1041
1037
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1042
1038
  const sameBox = box.width === width && box.height === height;
1043
1039
  const data = { mode };
1044
1040
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1045
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1046
- let x = 0, y = 0, scaleX, scaleY;
1041
+ BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1042
+ let scaleX, scaleY;
1047
1043
  if (!mode || mode === 'cover' || mode === 'fit') {
1048
1044
  if (!sameBox || rotation) {
1049
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1050
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1051
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1045
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1046
+ BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1047
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1052
1048
  }
1053
1049
  }
1054
- else if (scale || size) {
1055
- MathHelper.getScaleData(scale, size, image, tempScaleData);
1056
- scaleX = tempScaleData.scaleX;
1057
- scaleY = tempScaleData.scaleY;
1058
- }
1059
- if (align) {
1060
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1061
- if (scaleX)
1062
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1063
- AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1064
- x += tempPoint.x, y += tempPoint.y;
1050
+ else {
1051
+ if (scale || size) {
1052
+ MathHelper.getScaleData(scale, size, image, tempScaleData);
1053
+ scaleX = tempScaleData.scaleX;
1054
+ scaleY = tempScaleData.scaleY;
1055
+ }
1056
+ if (align) {
1057
+ if (scaleX)
1058
+ BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1059
+ AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1060
+ }
1065
1061
  }
1066
1062
  if (offset)
1067
- x += offset.x, y += offset.y;
1063
+ PointHelper.move(tempImage, offset);
1068
1064
  switch (mode) {
1069
1065
  case 'stretch':
1070
1066
  if (!sameBox)
@@ -1072,12 +1068,12 @@ function getPatternData(paint, box, image) {
1072
1068
  break;
1073
1069
  case 'normal':
1074
1070
  case 'clip':
1075
- if (x || y || scaleX || rotation)
1076
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1071
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1072
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1077
1073
  break;
1078
1074
  case 'repeat':
1079
1075
  if (!sameBox || scaleX || rotation)
1080
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1076
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1081
1077
  if (!repeat)
1082
1078
  data.repeat = 'repeat';
1083
1079
  break;
@@ -1085,7 +1081,7 @@ function getPatternData(paint, box, image) {
1085
1081
  case 'cover':
1086
1082
  default:
1087
1083
  if (scaleX)
1088
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1084
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1089
1085
  }
1090
1086
  if (!data.transform) {
1091
1087
  if (box.x || box.y) {
@@ -1118,6 +1114,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1118
1114
  }
1119
1115
  else {
1120
1116
  leafPaint = { type: paint.type, image };
1117
+ if (image.hasAlphaPixel)
1118
+ leafPaint.isTransparent = true;
1121
1119
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1122
1120
  }
1123
1121
  if (firstUse || image.loading)
@@ -1142,7 +1140,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1142
1140
  ignoreRender(ui, false);
1143
1141
  if (!ui.destroyed) {
1144
1142
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1145
- if (image.hasOpacityPixel)
1143
+ if (image.hasAlphaPixel)
1146
1144
  ui.__layout.hitCanvasChanged = true;
1147
1145
  ui.forceUpdate('surface');
1148
1146
  }
@@ -1154,6 +1152,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1154
1152
  onLoadError(ui, event, error);
1155
1153
  leafPaint.loadId = null;
1156
1154
  });
1155
+ if (ui.placeholderColor) {
1156
+ if (!ui.placeholderDelay)
1157
+ image.isPlacehold = true;
1158
+ else
1159
+ setTimeout(() => {
1160
+ if (!image.ready) {
1161
+ image.isPlacehold = true;
1162
+ ui.forceUpdate('surface');
1163
+ }
1164
+ }, ui.placeholderDelay);
1165
+ }
1157
1166
  }
1158
1167
  return leafPaint;
1159
1168
  }
@@ -1391,32 +1400,33 @@ const PaintImageModule = {
1391
1400
  repeatMode
1392
1401
  };
1393
1402
 
1394
- const { toPoint: toPoint$2 } = AroundHelper;
1403
+ const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1395
1404
  const realFrom$2 = {};
1396
1405
  const realTo$2 = {};
1397
1406
  function linearGradient(paint, box) {
1398
- let { from, to, type, blendMode, opacity } = paint;
1407
+ let { from, to, type, opacity } = paint;
1399
1408
  toPoint$2(from || 'top', box, realFrom$2);
1400
1409
  toPoint$2(to || 'bottom', box, realTo$2);
1401
1410
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1402
- applyStops(style, paint.stops, opacity);
1403
1411
  const data = { type, style };
1404
- if (blendMode)
1405
- data.blendMode = blendMode;
1412
+ applyStops(data, style, paint.stops, opacity);
1406
1413
  return data;
1407
1414
  }
1408
- function applyStops(gradient, stops, opacity) {
1415
+ function applyStops(data, gradient, stops, opacity) {
1409
1416
  if (stops) {
1410
- let stop;
1417
+ let stop, color, offset, isTransparent;
1411
1418
  for (let i = 0, len = stops.length; i < len; i++) {
1412
1419
  stop = stops[i];
1413
- if (typeof stop === 'string') {
1414
- gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1415
- }
1416
- else {
1417
- gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1418
- }
1420
+ if (typeof stop === 'string')
1421
+ offset = i / (len - 1), color = ColorConvert.string(stop, opacity);
1422
+ else
1423
+ offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
1424
+ gradient.addColorStop(offset, color);
1425
+ if (!isTransparent && hasTransparent(color))
1426
+ isTransparent = true;
1419
1427
  }
1428
+ if (isTransparent)
1429
+ data.isTransparent = true;
1420
1430
  }
1421
1431
  }
1422
1432
 
@@ -1426,17 +1436,15 @@ const { toPoint: toPoint$1 } = AroundHelper;
1426
1436
  const realFrom$1 = {};
1427
1437
  const realTo$1 = {};
1428
1438
  function radialGradient(paint, box) {
1429
- let { from, to, type, opacity, blendMode, stretch } = paint;
1439
+ let { from, to, type, opacity, stretch } = paint;
1430
1440
  toPoint$1(from || 'center', box, realFrom$1);
1431
1441
  toPoint$1(to || 'bottom', box, realTo$1);
1432
1442
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1433
- applyStops(style, paint.stops, opacity);
1434
1443
  const data = { type, style };
1444
+ applyStops(data, style, paint.stops, opacity);
1435
1445
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1436
1446
  if (transform)
1437
1447
  data.transform = transform;
1438
- if (blendMode)
1439
- data.blendMode = blendMode;
1440
1448
  return data;
1441
1449
  }
1442
1450
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1462,17 +1470,15 @@ const { toPoint } = AroundHelper;
1462
1470
  const realFrom = {};
1463
1471
  const realTo = {};
1464
1472
  function conicGradient(paint, box) {
1465
- let { from, to, type, opacity, blendMode, stretch } = paint;
1473
+ let { from, to, type, opacity, stretch } = paint;
1466
1474
  toPoint(from || 'center', box, realFrom);
1467
1475
  toPoint(to || 'bottom', box, realTo);
1468
1476
  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));
1469
- applyStops(style, paint.stops, opacity);
1470
1477
  const data = { type, style };
1478
+ applyStops(data, style, paint.stops, opacity);
1471
1479
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1472
1480
  if (transform)
1473
1481
  data.transform = transform;
1474
- if (blendMode)
1475
- data.blendMode = blendMode;
1476
1482
  return data;
1477
1483
  }
1478
1484
 
@@ -1805,6 +1811,8 @@ function createRows(drawData, content, style) {
1805
1811
  lastCharType = null;
1806
1812
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1807
1813
  word = { data: [] }, row = { words: [] };
1814
+ if (__letterSpacing)
1815
+ content = [...content];
1808
1816
  for (let i = 0, len = content.length; i < len; i++) {
1809
1817
  char = content[i];
1810
1818
  if (char === '\n') {
@@ -2211,7 +2219,7 @@ const ColorConvertModule = {
2211
2219
 
2212
2220
  Object.assign(TextConvert, TextConvertModule);
2213
2221
  Object.assign(ColorConvert, ColorConvertModule);
2214
- Object.assign(Paint, PaintModule);
2222
+ Object.assign(Paint$1, PaintModule);
2215
2223
  Object.assign(PaintImage, PaintImageModule);
2216
2224
  Object.assign(PaintGradient, PaintGradientModule);
2217
2225
  Object.assign(Effect, EffectModule);
@@ -2219,4 +2227,3 @@ Object.assign(Effect, EffectModule);
2219
2227
  useCanvas();
2220
2228
 
2221
2229
  export { Layouter, LeaferCanvas, Renderer, Watcher, useCanvas };
2222
- //# sourceMappingURL=worker.esm.js.map