@leafer-draw/node 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.
package/dist/node.cjs CHANGED
@@ -3,6 +3,7 @@
3
3
  var core = require('@leafer/core');
4
4
  var fs = require('fs');
5
5
  var draw = require('@leafer-ui/draw');
6
+ var core$1 = require('@leafer-ui/core');
6
7
 
7
8
  /******************************************************************************
8
9
  Copyright (c) Microsoft Corporation.
@@ -173,17 +174,15 @@ class Watcher {
173
174
  this.target.emitEvent(new core.WatchEvent(core.WatchEvent.DATA, { updatedList: this.updatedList }));
174
175
  this.__updatedList = new core.LeafList();
175
176
  this.totalTimes++;
176
- this.changed = false;
177
- this.hasVisible = false;
178
- this.hasRemove = false;
179
- this.hasAdd = false;
177
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
180
178
  }
181
179
  __listenEvents() {
182
- const { target } = this;
183
180
  this.__eventIds = [
184
- target.on_(core.PropertyEvent.CHANGE, this.__onAttrChange, this),
185
- target.on_([core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this),
186
- target.on_(core.WatchEvent.REQUEST, this.__onRquestData, this)
181
+ this.target.on_([
182
+ [core.PropertyEvent.CHANGE, this.__onAttrChange, this],
183
+ [[core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this],
184
+ [core.WatchEvent.REQUEST, this.__onRquestData, this]
185
+ ])
187
186
  ];
188
187
  }
189
188
  __removeListenEvents() {
@@ -193,13 +192,12 @@ class Watcher {
193
192
  if (this.target) {
194
193
  this.stop();
195
194
  this.__removeListenEvents();
196
- this.target = null;
197
- this.__updatedList = null;
195
+ this.target = this.__updatedList = null;
198
196
  }
199
197
  }
200
198
  }
201
199
 
202
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = core.LeafHelper;
200
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = core.LeafHelper;
203
201
  const { pushAllChildBranch, pushAllParent } = core.BranchHelper;
204
202
  function updateMatrix(updateList, levelList) {
205
203
  let layout;
@@ -242,15 +240,7 @@ function updateBounds(boundsList) {
242
240
  });
243
241
  }
244
242
  function updateChange(updateList) {
245
- let layout;
246
- updateList.list.forEach(leaf => {
247
- layout = leaf.__layout;
248
- if (layout.opacityChanged)
249
- updateAllWorldOpacity(leaf);
250
- if (layout.stateStyleChanged)
251
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
252
- leaf.__updateChange();
253
- });
243
+ updateList.list.forEach(updateOneChange);
254
244
  }
255
245
 
256
246
  const { worldBounds } = core.LeafBoundsHelper;
@@ -307,7 +297,7 @@ class Layouter {
307
297
  this.disabled = true;
308
298
  }
309
299
  layout() {
310
- if (!this.running)
300
+ if (this.layouting || !this.running)
311
301
  return;
312
302
  const { target } = this;
313
303
  this.times = 0;
@@ -390,12 +380,10 @@ class Layouter {
390
380
  }
391
381
  static fullLayout(target) {
392
382
  updateAllMatrix(target, true);
393
- if (target.isBranch) {
383
+ if (target.isBranch)
394
384
  core.BranchHelper.updateBounds(target);
395
- }
396
- else {
385
+ else
397
386
  core.LeafHelper.updateBounds(target);
398
- }
399
387
  updateAllChange(target);
400
388
  }
401
389
  addExtra(leaf) {
@@ -418,11 +406,12 @@ class Layouter {
418
406
  this.__updatedList = event.data.updatedList;
419
407
  }
420
408
  __listenEvents() {
421
- const { target } = this;
422
409
  this.__eventIds = [
423
- target.on_(core.LayoutEvent.REQUEST, this.layout, this),
424
- target.on_(core.LayoutEvent.AGAIN, this.layoutAgain, this),
425
- target.on_(core.WatchEvent.DATA, this.__onReceiveWatchData, this)
410
+ this.target.on_([
411
+ [core.LayoutEvent.REQUEST, this.layout, this],
412
+ [core.LayoutEvent.AGAIN, this.layoutAgain, this],
413
+ [core.WatchEvent.DATA, this.__onReceiveWatchData, this]
414
+ ])
426
415
  ];
427
416
  }
428
417
  __removeListenEvents() {
@@ -653,12 +642,13 @@ class Renderer {
653
642
  this.target.emitEvent(new core.RenderEvent(type, this.times, bounds, options));
654
643
  }
655
644
  __listenEvents() {
656
- const { target } = this;
657
645
  this.__eventIds = [
658
- target.on_(core.RenderEvent.REQUEST, this.update, this),
659
- target.on_(core.LayoutEvent.END, this.__onLayoutEnd, this),
660
- target.on_(core.RenderEvent.AGAIN, this.renderAgain, this),
661
- target.on_(core.ResizeEvent.RESIZE, this.__onResize, this)
646
+ this.target.on_([
647
+ [core.RenderEvent.REQUEST, this.update, this],
648
+ [core.LayoutEvent.END, this.__onLayoutEnd, this],
649
+ [core.RenderEvent.AGAIN, this.renderAgain, this],
650
+ [core.ResizeEvent.RESIZE, this.__onResize, this]
651
+ ])
662
652
  ];
663
653
  }
664
654
  __removeListenEvents() {
@@ -684,8 +674,10 @@ Object.assign(core.Creator, {
684
674
  core.Platform.layout = Layouter.fullLayout;
685
675
 
686
676
  function fillText(ui, canvas) {
687
- let row, data = ui.__.__textDrawData;
688
- const { rows, decorationY } = data;
677
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
678
+ if (data.__isPlacehold && data.placeholderColor)
679
+ canvas.fillStyle = data.placeholderColor;
680
+ let row;
689
681
  for (let i = 0, len = rows.length; i < len; i++) {
690
682
  row = rows[i];
691
683
  if (row.text)
@@ -694,7 +686,7 @@ function fillText(ui, canvas) {
694
686
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
695
687
  }
696
688
  if (decorationY) {
697
- const { decorationColor, decorationHeight } = data;
689
+ const { decorationColor, decorationHeight } = data.__textDrawData;
698
690
  if (decorationColor)
699
691
  canvas.fillStyle = decorationColor;
700
692
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -703,65 +695,73 @@ function fillText(ui, canvas) {
703
695
 
704
696
  function fill(fill, ui, canvas) {
705
697
  canvas.fillStyle = fill;
706
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
698
+ fillPathOrText(ui, canvas);
707
699
  }
708
700
  function fills(fills, ui, canvas) {
709
701
  let item;
710
- const { windingRule, __font } = ui.__;
711
702
  for (let i = 0, len = fills.length; i < len; i++) {
712
703
  item = fills[i];
713
- if (item.image && draw.PaintImage.checkImage(ui, canvas, item, !__font))
714
- continue;
715
- if (item.style) {
716
- canvas.fillStyle = item.style;
717
- if (item.transform) {
718
- canvas.save();
719
- canvas.transform(item.transform);
720
- if (item.blendMode)
721
- canvas.blendMode = item.blendMode;
722
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
723
- canvas.restore();
704
+ if (item.image) {
705
+ if (draw.PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
706
+ continue;
707
+ if (!item.style) {
708
+ if (!i && item.image.isPlacehold)
709
+ ui.drawImagePlaceholder(canvas, item.image);
710
+ continue;
724
711
  }
725
- else {
726
- if (item.blendMode) {
727
- canvas.saveBlendMode(item.blendMode);
728
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
729
- canvas.restoreBlendMode();
730
- }
731
- else {
732
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
733
- }
712
+ }
713
+ canvas.fillStyle = item.style;
714
+ if (item.transform) {
715
+ canvas.save();
716
+ canvas.transform(item.transform);
717
+ if (item.blendMode)
718
+ canvas.blendMode = item.blendMode;
719
+ fillPathOrText(ui, canvas);
720
+ canvas.restore();
721
+ }
722
+ else {
723
+ if (item.blendMode) {
724
+ canvas.saveBlendMode(item.blendMode);
725
+ fillPathOrText(ui, canvas);
726
+ canvas.restoreBlendMode();
734
727
  }
728
+ else
729
+ fillPathOrText(ui, canvas);
735
730
  }
736
731
  }
737
732
  }
733
+ function fillPathOrText(ui, canvas) {
734
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
735
+ }
736
+
737
+ const Paint = {};
738
738
 
739
739
  function strokeText(stroke, ui, canvas) {
740
- const { strokeAlign } = ui.__;
741
- const isStrokes = typeof stroke !== 'string';
742
- switch (strokeAlign) {
740
+ switch (ui.__.strokeAlign) {
743
741
  case 'center':
744
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
745
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
742
+ drawCenter$1(stroke, 1, ui, canvas);
746
743
  break;
747
744
  case 'inside':
748
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
745
+ drawAlign(stroke, 'inside', ui, canvas);
749
746
  break;
750
747
  case 'outside':
751
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
748
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
752
749
  break;
753
750
  }
754
751
  }
755
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
756
- const { __strokeWidth, __font } = ui.__;
752
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
753
+ const data = ui.__;
754
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
755
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
756
+ }
757
+ function drawAlign(stroke, align, ui, canvas) {
757
758
  const out = canvas.getSameCanvas(true, true);
758
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
759
- out.font = __font;
760
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
759
+ out.font = ui.__.__font;
760
+ drawCenter$1(stroke, 2, ui, out);
761
761
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
762
762
  fillText(ui, out);
763
763
  out.blendMode = 'normal';
764
- if (ui.__worldFlipped)
764
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
765
765
  canvas.copyWorldByReset(out, ui.__nowWorld);
766
766
  else
767
767
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -803,90 +803,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
803
803
  }
804
804
 
805
805
  function stroke(stroke, ui, canvas) {
806
- const options = ui.__;
807
- const { __strokeWidth, strokeAlign, __font } = options;
808
- if (!__strokeWidth)
806
+ const data = ui.__;
807
+ if (!data.__strokeWidth)
809
808
  return;
810
- if (__font) {
809
+ if (data.__font) {
811
810
  strokeText(stroke, ui, canvas);
812
811
  }
813
812
  else {
814
- switch (strokeAlign) {
813
+ switch (data.strokeAlign) {
815
814
  case 'center':
816
- canvas.setStroke(stroke, __strokeWidth, options);
817
- canvas.stroke();
818
- if (options.__useArrow)
819
- strokeArrow(ui, canvas);
815
+ drawCenter(stroke, 1, ui, canvas);
820
816
  break;
821
817
  case 'inside':
822
- canvas.save();
823
- canvas.setStroke(stroke, __strokeWidth * 2, options);
824
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
825
- canvas.stroke();
826
- canvas.restore();
818
+ drawInside(stroke, ui, canvas);
827
819
  break;
828
820
  case 'outside':
829
- const out = canvas.getSameCanvas(true, true);
830
- out.setStroke(stroke, __strokeWidth * 2, options);
831
- ui.__drawRenderPath(out);
832
- out.stroke();
833
- options.windingRule ? out.clip(options.windingRule) : out.clip();
834
- out.clearWorld(ui.__layout.renderBounds);
835
- if (ui.__worldFlipped)
836
- canvas.copyWorldByReset(out, ui.__nowWorld);
837
- else
838
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
839
- out.recycle(ui.__nowWorld);
821
+ drawOutside(stroke, ui, canvas);
840
822
  break;
841
823
  }
842
824
  }
843
825
  }
844
826
  function strokes(strokes, ui, canvas) {
845
- const options = ui.__;
846
- const { __strokeWidth, strokeAlign, __font } = options;
847
- if (!__strokeWidth)
848
- return;
849
- if (__font) {
850
- strokeText(strokes, ui, canvas);
827
+ stroke(strokes, ui, canvas);
828
+ }
829
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
830
+ const data = ui.__;
831
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
832
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
833
+ if (data.__useArrow)
834
+ Paint.strokeArrow(stroke, ui, canvas);
835
+ }
836
+ function drawInside(stroke, ui, canvas) {
837
+ const data = ui.__;
838
+ canvas.save();
839
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
840
+ drawCenter(stroke, 2, ui, canvas);
841
+ canvas.restore();
842
+ }
843
+ function drawOutside(stroke, ui, canvas) {
844
+ const data = ui.__;
845
+ if (data.__fillAfterStroke) {
846
+ drawCenter(stroke, 2, ui, canvas);
851
847
  }
852
848
  else {
853
- switch (strokeAlign) {
854
- case 'center':
855
- canvas.setStroke(undefined, __strokeWidth, options);
856
- drawStrokesStyle(strokes, false, ui, canvas);
857
- if (options.__useArrow)
858
- strokeArrow(ui, canvas);
859
- break;
860
- case 'inside':
861
- canvas.save();
862
- canvas.setStroke(undefined, __strokeWidth * 2, options);
863
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
864
- drawStrokesStyle(strokes, false, ui, canvas);
865
- canvas.restore();
866
- break;
867
- case 'outside':
868
- const { renderBounds } = ui.__layout;
869
- const out = canvas.getSameCanvas(true, true);
870
- ui.__drawRenderPath(out);
871
- out.setStroke(undefined, __strokeWidth * 2, options);
872
- drawStrokesStyle(strokes, false, ui, out);
873
- options.windingRule ? out.clip(options.windingRule) : out.clip();
874
- out.clearWorld(renderBounds);
875
- if (ui.__worldFlipped)
876
- canvas.copyWorldByReset(out, ui.__nowWorld);
877
- else
878
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
879
- out.recycle(ui.__nowWorld);
880
- break;
881
- }
882
- }
883
- }
884
- function strokeArrow(ui, canvas) {
885
- if (ui.__.dashPattern) {
886
- canvas.beginPath();
887
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
888
- canvas.dashPattern = null;
889
- canvas.stroke();
849
+ const { renderBounds } = ui.__layout;
850
+ const out = canvas.getSameCanvas(true, true);
851
+ ui.__drawRenderPath(out);
852
+ drawCenter(stroke, 2, ui, out);
853
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
854
+ out.clearWorld(renderBounds);
855
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
856
+ canvas.copyWorldByReset(out, ui.__nowWorld);
857
+ else
858
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
859
+ out.recycle(ui.__nowWorld);
890
860
  }
891
861
  }
892
862
 
@@ -933,9 +903,10 @@ function shape(ui, current, options) {
933
903
  }
934
904
 
935
905
  let recycleMap;
906
+ const { stintSet } = core.DataHelper, { hasTransparent: hasTransparent$1 } = draw.ColorConvert;
936
907
  function compute(attrName, ui) {
937
908
  const data = ui.__, leafPaints = [];
938
- let paints = data.__input[attrName], hasOpacityPixel;
909
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
939
910
  if (!(paints instanceof Array))
940
911
  paints = [paints];
941
912
  recycleMap = draw.PaintImage.recycleImage(attrName, data);
@@ -945,35 +916,62 @@ function compute(attrName, ui) {
945
916
  leafPaints.push(item);
946
917
  }
947
918
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
948
- if (leafPaints.length && leafPaints[0].image)
949
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
950
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
919
+ if (leafPaints.length) {
920
+ if (leafPaints.every(item => item.isTransparent)) {
921
+ if (leafPaints.some(item => item.image))
922
+ isAlphaPixel = true;
923
+ isTransparent = true;
924
+ }
925
+ }
926
+ if (attrName === 'fill') {
927
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
928
+ stintSet(data, '__isTransparentFill', isTransparent);
929
+ }
930
+ else {
931
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
932
+ stintSet(data, '__isTransparentStroke', isTransparent);
933
+ }
951
934
  }
952
935
  function getLeafPaint(attrName, paint, ui) {
953
936
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
954
937
  return undefined;
938
+ let data;
955
939
  const { boxBounds } = ui.__layout;
956
940
  switch (paint.type) {
957
- case 'solid':
958
- let { type, blendMode, color, opacity } = paint;
959
- return { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
960
941
  case 'image':
961
- return draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
942
+ data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
943
+ break;
962
944
  case 'linear':
963
- return draw.PaintGradient.linearGradient(paint, boxBounds);
945
+ data = draw.PaintGradient.linearGradient(paint, boxBounds);
946
+ break;
964
947
  case 'radial':
965
- return draw.PaintGradient.radialGradient(paint, boxBounds);
948
+ data = draw.PaintGradient.radialGradient(paint, boxBounds);
949
+ break;
966
950
  case 'angular':
967
- return draw.PaintGradient.conicGradient(paint, boxBounds);
951
+ data = draw.PaintGradient.conicGradient(paint, boxBounds);
952
+ break;
953
+ case 'solid':
954
+ const { type, blendMode, color, opacity } = paint;
955
+ data = { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
956
+ break;
968
957
  default:
969
- return paint.r !== undefined ? { type: 'solid', style: draw.ColorConvert.string(paint) } : undefined;
958
+ if (paint.r !== undefined)
959
+ data = { type: 'solid', style: draw.ColorConvert.string(paint) };
960
+ }
961
+ if (data) {
962
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
963
+ data.isTransparent = true;
964
+ if (paint.blendMode)
965
+ data.blendMode = paint.blendMode;
970
966
  }
967
+ return data;
971
968
  }
972
969
 
973
970
  const PaintModule = {
974
971
  compute,
975
972
  fill,
976
973
  fills,
974
+ fillPathOrText,
977
975
  fillText,
978
976
  stroke,
979
977
  strokes,
@@ -1032,12 +1030,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1032
1030
 
1033
1031
  const { get: get$2, translate } = core.MatrixHelper;
1034
1032
  const tempBox = new core.Bounds();
1035
- const tempPoint = {};
1036
1033
  const tempScaleData = {};
1034
+ const tempImage = {};
1037
1035
  function createData(leafPaint, image, paint, box) {
1038
- const { blendMode, changeful, sync } = paint;
1039
- if (blendMode)
1040
- leafPaint.blendMode = blendMode;
1036
+ const { changeful, sync } = paint;
1041
1037
  if (changeful)
1042
1038
  leafPaint.changeful = changeful;
1043
1039
  if (sync)
@@ -1045,38 +1041,38 @@ function createData(leafPaint, image, paint, box) {
1045
1041
  leafPaint.data = getPatternData(paint, box, image);
1046
1042
  }
1047
1043
  function getPatternData(paint, box, image) {
1048
- let { width, height } = image;
1049
1044
  if (paint.padding)
1050
1045
  box = tempBox.set(box).shrink(paint.padding);
1051
1046
  if (paint.mode === 'strench')
1052
1047
  paint.mode = 'stretch';
1048
+ let { width, height } = image;
1053
1049
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1054
1050
  const sameBox = box.width === width && box.height === height;
1055
1051
  const data = { mode };
1056
1052
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1057
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1058
- let x = 0, y = 0, scaleX, scaleY;
1053
+ core.BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1054
+ let scaleX, scaleY;
1059
1055
  if (!mode || mode === 'cover' || mode === 'fit') {
1060
1056
  if (!sameBox || rotation) {
1061
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1062
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1063
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1057
+ scaleX = scaleY = core.BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1058
+ core.BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1059
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1064
1060
  }
1065
1061
  }
1066
- else if (scale || size) {
1067
- core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1068
- scaleX = tempScaleData.scaleX;
1069
- scaleY = tempScaleData.scaleY;
1070
- }
1071
- if (align) {
1072
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1073
- if (scaleX)
1074
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1075
- core.AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1076
- x += tempPoint.x, y += tempPoint.y;
1062
+ else {
1063
+ if (scale || size) {
1064
+ core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1065
+ scaleX = tempScaleData.scaleX;
1066
+ scaleY = tempScaleData.scaleY;
1067
+ }
1068
+ if (align) {
1069
+ if (scaleX)
1070
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1071
+ core.AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1072
+ }
1077
1073
  }
1078
1074
  if (offset)
1079
- x += offset.x, y += offset.y;
1075
+ core.PointHelper.move(tempImage, offset);
1080
1076
  switch (mode) {
1081
1077
  case 'stretch':
1082
1078
  if (!sameBox)
@@ -1084,12 +1080,12 @@ function getPatternData(paint, box, image) {
1084
1080
  break;
1085
1081
  case 'normal':
1086
1082
  case 'clip':
1087
- if (x || y || scaleX || rotation)
1088
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1083
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1084
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1089
1085
  break;
1090
1086
  case 'repeat':
1091
1087
  if (!sameBox || scaleX || rotation)
1092
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1088
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1093
1089
  if (!repeat)
1094
1090
  data.repeat = 'repeat';
1095
1091
  break;
@@ -1097,7 +1093,7 @@ function getPatternData(paint, box, image) {
1097
1093
  case 'cover':
1098
1094
  default:
1099
1095
  if (scaleX)
1100
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1096
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1101
1097
  }
1102
1098
  if (!data.transform) {
1103
1099
  if (box.x || box.y) {
@@ -1130,6 +1126,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1130
1126
  }
1131
1127
  else {
1132
1128
  leafPaint = { type: paint.type, image };
1129
+ if (image.hasAlphaPixel)
1130
+ leafPaint.isTransparent = true;
1133
1131
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1134
1132
  }
1135
1133
  if (firstUse || image.loading)
@@ -1154,7 +1152,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1154
1152
  ignoreRender(ui, false);
1155
1153
  if (!ui.destroyed) {
1156
1154
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1157
- if (image.hasOpacityPixel)
1155
+ if (image.hasAlphaPixel)
1158
1156
  ui.__layout.hitCanvasChanged = true;
1159
1157
  ui.forceUpdate('surface');
1160
1158
  }
@@ -1166,6 +1164,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1166
1164
  onLoadError(ui, event, error);
1167
1165
  leafPaint.loadId = null;
1168
1166
  });
1167
+ if (ui.placeholderColor) {
1168
+ if (!ui.placeholderDelay)
1169
+ image.isPlacehold = true;
1170
+ else
1171
+ setTimeout(() => {
1172
+ if (!image.ready) {
1173
+ image.isPlacehold = true;
1174
+ ui.forceUpdate('surface');
1175
+ }
1176
+ }, ui.placeholderDelay);
1177
+ }
1169
1178
  }
1170
1179
  return leafPaint;
1171
1180
  }
@@ -1371,32 +1380,33 @@ const PaintImageModule = {
1371
1380
  repeatMode
1372
1381
  };
1373
1382
 
1374
- const { toPoint: toPoint$2 } = core.AroundHelper;
1383
+ const { toPoint: toPoint$2 } = core.AroundHelper, { hasTransparent } = draw.ColorConvert;
1375
1384
  const realFrom$2 = {};
1376
1385
  const realTo$2 = {};
1377
1386
  function linearGradient(paint, box) {
1378
- let { from, to, type, blendMode, opacity } = paint;
1387
+ let { from, to, type, opacity } = paint;
1379
1388
  toPoint$2(from || 'top', box, realFrom$2);
1380
1389
  toPoint$2(to || 'bottom', box, realTo$2);
1381
1390
  const style = core.Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1382
- applyStops(style, paint.stops, opacity);
1383
1391
  const data = { type, style };
1384
- if (blendMode)
1385
- data.blendMode = blendMode;
1392
+ applyStops(data, style, paint.stops, opacity);
1386
1393
  return data;
1387
1394
  }
1388
- function applyStops(gradient, stops, opacity) {
1395
+ function applyStops(data, gradient, stops, opacity) {
1389
1396
  if (stops) {
1390
- let stop;
1397
+ let stop, color, offset, isTransparent;
1391
1398
  for (let i = 0, len = stops.length; i < len; i++) {
1392
1399
  stop = stops[i];
1393
- if (typeof stop === 'string') {
1394
- gradient.addColorStop(i / (len - 1), draw.ColorConvert.string(stop, opacity));
1395
- }
1396
- else {
1397
- gradient.addColorStop(stop.offset, draw.ColorConvert.string(stop.color, opacity));
1398
- }
1400
+ if (typeof stop === 'string')
1401
+ offset = i / (len - 1), color = draw.ColorConvert.string(stop, opacity);
1402
+ else
1403
+ offset = stop.offset, color = draw.ColorConvert.string(stop.color, opacity);
1404
+ gradient.addColorStop(offset, color);
1405
+ if (!isTransparent && hasTransparent(color))
1406
+ isTransparent = true;
1399
1407
  }
1408
+ if (isTransparent)
1409
+ data.isTransparent = true;
1400
1410
  }
1401
1411
  }
1402
1412
 
@@ -1406,17 +1416,15 @@ const { toPoint: toPoint$1 } = core.AroundHelper;
1406
1416
  const realFrom$1 = {};
1407
1417
  const realTo$1 = {};
1408
1418
  function radialGradient(paint, box) {
1409
- let { from, to, type, opacity, blendMode, stretch } = paint;
1419
+ let { from, to, type, opacity, stretch } = paint;
1410
1420
  toPoint$1(from || 'center', box, realFrom$1);
1411
1421
  toPoint$1(to || 'bottom', box, realTo$1);
1412
1422
  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));
1413
- applyStops(style, paint.stops, opacity);
1414
1423
  const data = { type, style };
1424
+ applyStops(data, style, paint.stops, opacity);
1415
1425
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1416
1426
  if (transform)
1417
1427
  data.transform = transform;
1418
- if (blendMode)
1419
- data.blendMode = blendMode;
1420
1428
  return data;
1421
1429
  }
1422
1430
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1442,17 +1450,15 @@ const { toPoint } = core.AroundHelper;
1442
1450
  const realFrom = {};
1443
1451
  const realTo = {};
1444
1452
  function conicGradient(paint, box) {
1445
- let { from, to, type, opacity, blendMode, stretch } = paint;
1453
+ let { from, to, type, opacity, stretch } = paint;
1446
1454
  toPoint(from || 'center', box, realFrom);
1447
1455
  toPoint(to || 'bottom', box, realTo);
1448
1456
  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));
1449
- applyStops(style, paint.stops, opacity);
1450
1457
  const data = { type, style };
1458
+ applyStops(data, style, paint.stops, opacity);
1451
1459
  const transform = getTransform(box, realFrom, realTo, stretch || 1, core.Platform.conicGradientRotate90);
1452
1460
  if (transform)
1453
1461
  data.transform = transform;
1454
- if (blendMode)
1455
- data.blendMode = blendMode;
1456
1462
  return data;
1457
1463
  }
1458
1464
 
@@ -1785,6 +1791,8 @@ function createRows(drawData, content, style) {
1785
1791
  lastCharType = null;
1786
1792
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1787
1793
  word = { data: [] }, row = { words: [] };
1794
+ if (__letterSpacing)
1795
+ content = [...content];
1788
1796
  for (let i = 0, len = content.length; i < len; i++) {
1789
1797
  char = content[i];
1790
1798
  if (char === '\n') {
@@ -2234,10 +2242,9 @@ const ExportModule = {
2234
2242
  else {
2235
2243
  let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2236
2244
  const { worldTransform, isLeafer, leafer, isFrame } = leaf;
2237
- const { slice, trim, padding, onCanvas } = options;
2245
+ const { slice, clip, trim, screenshot, padding, onCanvas } = options;
2238
2246
  const smooth = options.smooth === undefined ? (leafer ? leafer.config.smooth : true) : options.smooth;
2239
2247
  const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined);
2240
- const screenshot = options.screenshot || leaf.isApp;
2241
2248
  const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2242
2249
  const needFill = draw.FileHelper.isOpaqueImage(filename) || fill, matrix = new draw.Matrix();
2243
2250
  if (screenshot) {
@@ -2273,12 +2280,9 @@ const ExportModule = {
2273
2280
  const scaleData = { scaleX: 1, scaleY: 1 };
2274
2281
  draw.MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData);
2275
2282
  let pixelRatio = options.pixelRatio || 1;
2276
- if (leaf.isApp) {
2277
- scaleData.scaleX *= pixelRatio;
2278
- scaleData.scaleY *= pixelRatio;
2279
- pixelRatio = leaf.app.pixelRatio;
2280
- }
2281
- const { x, y, width, height } = new draw.Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2283
+ let { x, y, width, height } = new draw.Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2284
+ if (clip)
2285
+ x += clip.x, y += clip.y, width = clip.width, height = clip.height;
2282
2286
  const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
2283
2287
  let canvas = draw.Creator.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings });
2284
2288
  let sliceLeaf;
@@ -2426,4 +2430,3 @@ Object.keys(draw).forEach(function (k) {
2426
2430
  get: function () { return draw[k]; }
2427
2431
  });
2428
2432
  });
2429
- //# sourceMappingURL=node.cjs.map