leafer-draw 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/web.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var core = require('@leafer/core');
4
4
  var draw = require('@leafer-ui/draw');
5
+ var core$1 = require('@leafer-ui/core');
5
6
 
6
7
  const debug$2 = core.Debug.get('LeaferCanvas');
7
8
  class LeaferCanvas extends core.LeaferCanvasBase {
@@ -341,17 +342,15 @@ class Watcher {
341
342
  this.target.emitEvent(new core.WatchEvent(core.WatchEvent.DATA, { updatedList: this.updatedList }));
342
343
  this.__updatedList = new core.LeafList();
343
344
  this.totalTimes++;
344
- this.changed = false;
345
- this.hasVisible = false;
346
- this.hasRemove = false;
347
- this.hasAdd = false;
345
+ this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
348
346
  }
349
347
  __listenEvents() {
350
- const { target } = this;
351
348
  this.__eventIds = [
352
- target.on_(core.PropertyEvent.CHANGE, this.__onAttrChange, this),
353
- target.on_([core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this),
354
- target.on_(core.WatchEvent.REQUEST, this.__onRquestData, this)
349
+ this.target.on_([
350
+ [core.PropertyEvent.CHANGE, this.__onAttrChange, this],
351
+ [[core.ChildEvent.ADD, core.ChildEvent.REMOVE], this.__onChildEvent, this],
352
+ [core.WatchEvent.REQUEST, this.__onRquestData, this]
353
+ ])
355
354
  ];
356
355
  }
357
356
  __removeListenEvents() {
@@ -361,13 +360,12 @@ class Watcher {
361
360
  if (this.target) {
362
361
  this.stop();
363
362
  this.__removeListenEvents();
364
- this.target = null;
365
- this.__updatedList = null;
363
+ this.target = this.__updatedList = null;
366
364
  }
367
365
  }
368
366
  }
369
367
 
370
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = core.LeafHelper;
368
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = core.LeafHelper;
371
369
  const { pushAllChildBranch, pushAllParent } = core.BranchHelper;
372
370
  function updateMatrix(updateList, levelList) {
373
371
  let layout;
@@ -410,15 +408,7 @@ function updateBounds(boundsList) {
410
408
  });
411
409
  }
412
410
  function updateChange(updateList) {
413
- let layout;
414
- updateList.list.forEach(leaf => {
415
- layout = leaf.__layout;
416
- if (layout.opacityChanged)
417
- updateAllWorldOpacity(leaf);
418
- if (layout.stateStyleChanged)
419
- setTimeout(() => layout.stateStyleChanged && leaf.updateState());
420
- leaf.__updateChange();
421
- });
411
+ updateList.list.forEach(updateOneChange);
422
412
  }
423
413
 
424
414
  const { worldBounds } = core.LeafBoundsHelper;
@@ -475,7 +465,7 @@ class Layouter {
475
465
  this.disabled = true;
476
466
  }
477
467
  layout() {
478
- if (!this.running)
468
+ if (this.layouting || !this.running)
479
469
  return;
480
470
  const { target } = this;
481
471
  this.times = 0;
@@ -558,12 +548,10 @@ class Layouter {
558
548
  }
559
549
  static fullLayout(target) {
560
550
  updateAllMatrix(target, true);
561
- if (target.isBranch) {
551
+ if (target.isBranch)
562
552
  core.BranchHelper.updateBounds(target);
563
- }
564
- else {
553
+ else
565
554
  core.LeafHelper.updateBounds(target);
566
- }
567
555
  updateAllChange(target);
568
556
  }
569
557
  addExtra(leaf) {
@@ -586,11 +574,12 @@ class Layouter {
586
574
  this.__updatedList = event.data.updatedList;
587
575
  }
588
576
  __listenEvents() {
589
- const { target } = this;
590
577
  this.__eventIds = [
591
- target.on_(core.LayoutEvent.REQUEST, this.layout, this),
592
- target.on_(core.LayoutEvent.AGAIN, this.layoutAgain, this),
593
- target.on_(core.WatchEvent.DATA, this.__onReceiveWatchData, this)
578
+ this.target.on_([
579
+ [core.LayoutEvent.REQUEST, this.layout, this],
580
+ [core.LayoutEvent.AGAIN, this.layoutAgain, this],
581
+ [core.WatchEvent.DATA, this.__onReceiveWatchData, this]
582
+ ])
594
583
  ];
595
584
  }
596
585
  __removeListenEvents() {
@@ -821,12 +810,13 @@ class Renderer {
821
810
  this.target.emitEvent(new core.RenderEvent(type, this.times, bounds, options));
822
811
  }
823
812
  __listenEvents() {
824
- const { target } = this;
825
813
  this.__eventIds = [
826
- target.on_(core.RenderEvent.REQUEST, this.update, this),
827
- target.on_(core.LayoutEvent.END, this.__onLayoutEnd, this),
828
- target.on_(core.RenderEvent.AGAIN, this.renderAgain, this),
829
- target.on_(core.ResizeEvent.RESIZE, this.__onResize, this)
814
+ this.target.on_([
815
+ [core.RenderEvent.REQUEST, this.update, this],
816
+ [core.LayoutEvent.END, this.__onLayoutEnd, this],
817
+ [core.RenderEvent.AGAIN, this.renderAgain, this],
818
+ [core.ResizeEvent.RESIZE, this.__onResize, this]
819
+ ])
830
820
  ];
831
821
  }
832
822
  __removeListenEvents() {
@@ -852,8 +842,10 @@ Object.assign(core.Creator, {
852
842
  core.Platform.layout = Layouter.fullLayout;
853
843
 
854
844
  function fillText(ui, canvas) {
855
- let row, data = ui.__.__textDrawData;
856
- const { rows, decorationY } = data;
845
+ const data = ui.__, { rows, decorationY } = data.__textDrawData;
846
+ if (data.__isPlacehold && data.placeholderColor)
847
+ canvas.fillStyle = data.placeholderColor;
848
+ let row;
857
849
  for (let i = 0, len = rows.length; i < len; i++) {
858
850
  row = rows[i];
859
851
  if (row.text)
@@ -862,7 +854,7 @@ function fillText(ui, canvas) {
862
854
  row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
863
855
  }
864
856
  if (decorationY) {
865
- const { decorationColor, decorationHeight } = data;
857
+ const { decorationColor, decorationHeight } = data.__textDrawData;
866
858
  if (decorationColor)
867
859
  canvas.fillStyle = decorationColor;
868
860
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
@@ -871,65 +863,73 @@ function fillText(ui, canvas) {
871
863
 
872
864
  function fill(fill, ui, canvas) {
873
865
  canvas.fillStyle = fill;
874
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
866
+ fillPathOrText(ui, canvas);
875
867
  }
876
868
  function fills(fills, ui, canvas) {
877
869
  let item;
878
- const { windingRule, __font } = ui.__;
879
870
  for (let i = 0, len = fills.length; i < len; i++) {
880
871
  item = fills[i];
881
- if (item.image && draw.PaintImage.checkImage(ui, canvas, item, !__font))
882
- continue;
883
- if (item.style) {
884
- canvas.fillStyle = item.style;
885
- if (item.transform) {
886
- canvas.save();
887
- canvas.transform(item.transform);
888
- if (item.blendMode)
889
- canvas.blendMode = item.blendMode;
890
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
891
- canvas.restore();
872
+ if (item.image) {
873
+ if (draw.PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
874
+ continue;
875
+ if (!item.style) {
876
+ if (!i && item.image.isPlacehold)
877
+ ui.drawImagePlaceholder(canvas, item.image);
878
+ continue;
892
879
  }
893
- else {
894
- if (item.blendMode) {
895
- canvas.saveBlendMode(item.blendMode);
896
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
897
- canvas.restoreBlendMode();
898
- }
899
- else {
900
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
901
- }
880
+ }
881
+ canvas.fillStyle = item.style;
882
+ if (item.transform) {
883
+ canvas.save();
884
+ canvas.transform(item.transform);
885
+ if (item.blendMode)
886
+ canvas.blendMode = item.blendMode;
887
+ fillPathOrText(ui, canvas);
888
+ canvas.restore();
889
+ }
890
+ else {
891
+ if (item.blendMode) {
892
+ canvas.saveBlendMode(item.blendMode);
893
+ fillPathOrText(ui, canvas);
894
+ canvas.restoreBlendMode();
902
895
  }
896
+ else
897
+ fillPathOrText(ui, canvas);
903
898
  }
904
899
  }
905
900
  }
901
+ function fillPathOrText(ui, canvas) {
902
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
903
+ }
904
+
905
+ const Paint = {};
906
906
 
907
907
  function strokeText(stroke, ui, canvas) {
908
- const { strokeAlign } = ui.__;
909
- const isStrokes = typeof stroke !== 'string';
910
- switch (strokeAlign) {
908
+ switch (ui.__.strokeAlign) {
911
909
  case 'center':
912
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
913
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
910
+ drawCenter$1(stroke, 1, ui, canvas);
914
911
  break;
915
912
  case 'inside':
916
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
913
+ drawAlign(stroke, 'inside', ui, canvas);
917
914
  break;
918
915
  case 'outside':
919
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
916
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
920
917
  break;
921
918
  }
922
919
  }
923
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
924
- const { __strokeWidth, __font } = ui.__;
920
+ function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
921
+ const data = ui.__;
922
+ canvas.setStroke(!data.__isStrokes && stroke, data.strokeWidth * strokeWidthScale, data);
923
+ data.__isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
924
+ }
925
+ function drawAlign(stroke, align, ui, canvas) {
925
926
  const out = canvas.getSameCanvas(true, true);
926
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
927
- out.font = __font;
928
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
927
+ out.font = ui.__.__font;
928
+ drawCenter$1(stroke, 2, ui, out);
929
929
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
930
930
  fillText(ui, out);
931
931
  out.blendMode = 'normal';
932
- if (ui.__worldFlipped)
932
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
933
933
  canvas.copyWorldByReset(out, ui.__nowWorld);
934
934
  else
935
935
  canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
@@ -971,90 +971,60 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
971
971
  }
972
972
 
973
973
  function stroke(stroke, ui, canvas) {
974
- const options = ui.__;
975
- const { __strokeWidth, strokeAlign, __font } = options;
976
- if (!__strokeWidth)
974
+ const data = ui.__;
975
+ if (!data.__strokeWidth)
977
976
  return;
978
- if (__font) {
977
+ if (data.__font) {
979
978
  strokeText(stroke, ui, canvas);
980
979
  }
981
980
  else {
982
- switch (strokeAlign) {
981
+ switch (data.strokeAlign) {
983
982
  case 'center':
984
- canvas.setStroke(stroke, __strokeWidth, options);
985
- canvas.stroke();
986
- if (options.__useArrow)
987
- strokeArrow(ui, canvas);
983
+ drawCenter(stroke, 1, ui, canvas);
988
984
  break;
989
985
  case 'inside':
990
- canvas.save();
991
- canvas.setStroke(stroke, __strokeWidth * 2, options);
992
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
993
- canvas.stroke();
994
- canvas.restore();
986
+ drawInside(stroke, ui, canvas);
995
987
  break;
996
988
  case 'outside':
997
- const out = canvas.getSameCanvas(true, true);
998
- out.setStroke(stroke, __strokeWidth * 2, options);
999
- ui.__drawRenderPath(out);
1000
- out.stroke();
1001
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1002
- out.clearWorld(ui.__layout.renderBounds);
1003
- if (ui.__worldFlipped)
1004
- canvas.copyWorldByReset(out, ui.__nowWorld);
1005
- else
1006
- canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1007
- out.recycle(ui.__nowWorld);
989
+ drawOutside(stroke, ui, canvas);
1008
990
  break;
1009
991
  }
1010
992
  }
1011
993
  }
1012
994
  function strokes(strokes, ui, canvas) {
1013
- const options = ui.__;
1014
- const { __strokeWidth, strokeAlign, __font } = options;
1015
- if (!__strokeWidth)
1016
- return;
1017
- if (__font) {
1018
- strokeText(strokes, ui, canvas);
995
+ stroke(strokes, ui, canvas);
996
+ }
997
+ function drawCenter(stroke, strokeWidthScale, ui, canvas) {
998
+ const data = ui.__;
999
+ canvas.setStroke(!data.__isStrokes && stroke, data.__strokeWidth * strokeWidthScale, data);
1000
+ data.__isStrokes ? drawStrokesStyle(stroke, false, ui, canvas) : canvas.stroke();
1001
+ if (data.__useArrow)
1002
+ Paint.strokeArrow(stroke, ui, canvas);
1003
+ }
1004
+ function drawInside(stroke, ui, canvas) {
1005
+ const data = ui.__;
1006
+ canvas.save();
1007
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip();
1008
+ drawCenter(stroke, 2, ui, canvas);
1009
+ canvas.restore();
1010
+ }
1011
+ function drawOutside(stroke, ui, canvas) {
1012
+ const data = ui.__;
1013
+ if (data.__fillAfterStroke) {
1014
+ drawCenter(stroke, 2, ui, canvas);
1019
1015
  }
1020
1016
  else {
1021
- switch (strokeAlign) {
1022
- case 'center':
1023
- canvas.setStroke(undefined, __strokeWidth, options);
1024
- drawStrokesStyle(strokes, false, ui, canvas);
1025
- if (options.__useArrow)
1026
- strokeArrow(ui, canvas);
1027
- break;
1028
- case 'inside':
1029
- canvas.save();
1030
- canvas.setStroke(undefined, __strokeWidth * 2, options);
1031
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1032
- drawStrokesStyle(strokes, false, ui, canvas);
1033
- canvas.restore();
1034
- break;
1035
- case 'outside':
1036
- const { renderBounds } = ui.__layout;
1037
- const out = canvas.getSameCanvas(true, true);
1038
- ui.__drawRenderPath(out);
1039
- out.setStroke(undefined, __strokeWidth * 2, options);
1040
- drawStrokesStyle(strokes, false, ui, out);
1041
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1042
- out.clearWorld(renderBounds);
1043
- if (ui.__worldFlipped)
1044
- canvas.copyWorldByReset(out, ui.__nowWorld);
1045
- else
1046
- canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1047
- out.recycle(ui.__nowWorld);
1048
- break;
1049
- }
1050
- }
1051
- }
1052
- function strokeArrow(ui, canvas) {
1053
- if (ui.__.dashPattern) {
1054
- canvas.beginPath();
1055
- ui.__drawPathByData(canvas, ui.__.__pathForArrow);
1056
- canvas.dashPattern = null;
1057
- canvas.stroke();
1017
+ const { renderBounds } = ui.__layout;
1018
+ const out = canvas.getSameCanvas(true, true);
1019
+ ui.__drawRenderPath(out);
1020
+ drawCenter(stroke, 2, ui, out);
1021
+ data.windingRule ? out.clip(data.windingRule) : out.clip();
1022
+ out.clearWorld(renderBounds);
1023
+ if (ui.__worldFlipped || core$1.Platform.fullImageShadow)
1024
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1025
+ else
1026
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1027
+ out.recycle(ui.__nowWorld);
1058
1028
  }
1059
1029
  }
1060
1030
 
@@ -1101,9 +1071,10 @@ function shape(ui, current, options) {
1101
1071
  }
1102
1072
 
1103
1073
  let recycleMap;
1074
+ const { stintSet } = core.DataHelper, { hasTransparent: hasTransparent$1 } = draw.ColorConvert;
1104
1075
  function compute(attrName, ui) {
1105
1076
  const data = ui.__, leafPaints = [];
1106
- let paints = data.__input[attrName], hasOpacityPixel;
1077
+ let paints = data.__input[attrName], isAlphaPixel, isTransparent;
1107
1078
  if (!(paints instanceof Array))
1108
1079
  paints = [paints];
1109
1080
  recycleMap = draw.PaintImage.recycleImage(attrName, data);
@@ -1113,35 +1084,62 @@ function compute(attrName, ui) {
1113
1084
  leafPaints.push(item);
1114
1085
  }
1115
1086
  data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1116
- if (leafPaints.length && leafPaints[0].image)
1117
- hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1118
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel;
1087
+ if (leafPaints.length) {
1088
+ if (leafPaints.every(item => item.isTransparent)) {
1089
+ if (leafPaints.some(item => item.image))
1090
+ isAlphaPixel = true;
1091
+ isTransparent = true;
1092
+ }
1093
+ }
1094
+ if (attrName === 'fill') {
1095
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
1096
+ stintSet(data, '__isTransparentFill', isTransparent);
1097
+ }
1098
+ else {
1099
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
1100
+ stintSet(data, '__isTransparentStroke', isTransparent);
1101
+ }
1119
1102
  }
1120
1103
  function getLeafPaint(attrName, paint, ui) {
1121
1104
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1122
1105
  return undefined;
1106
+ let data;
1123
1107
  const { boxBounds } = ui.__layout;
1124
1108
  switch (paint.type) {
1125
- case 'solid':
1126
- let { type, blendMode, color, opacity } = paint;
1127
- return { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
1128
1109
  case 'image':
1129
- return draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1110
+ data = draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1111
+ break;
1130
1112
  case 'linear':
1131
- return draw.PaintGradient.linearGradient(paint, boxBounds);
1113
+ data = draw.PaintGradient.linearGradient(paint, boxBounds);
1114
+ break;
1132
1115
  case 'radial':
1133
- return draw.PaintGradient.radialGradient(paint, boxBounds);
1116
+ data = draw.PaintGradient.radialGradient(paint, boxBounds);
1117
+ break;
1134
1118
  case 'angular':
1135
- return draw.PaintGradient.conicGradient(paint, boxBounds);
1119
+ data = draw.PaintGradient.conicGradient(paint, boxBounds);
1120
+ break;
1121
+ case 'solid':
1122
+ const { type, blendMode, color, opacity } = paint;
1123
+ data = { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
1124
+ break;
1136
1125
  default:
1137
- return paint.r !== undefined ? { type: 'solid', style: draw.ColorConvert.string(paint) } : undefined;
1126
+ if (paint.r !== undefined)
1127
+ data = { type: 'solid', style: draw.ColorConvert.string(paint) };
1128
+ }
1129
+ if (data) {
1130
+ if (typeof data.style === 'string' && hasTransparent$1(data.style))
1131
+ data.isTransparent = true;
1132
+ if (paint.blendMode)
1133
+ data.blendMode = paint.blendMode;
1138
1134
  }
1135
+ return data;
1139
1136
  }
1140
1137
 
1141
1138
  const PaintModule = {
1142
1139
  compute,
1143
1140
  fill,
1144
1141
  fills,
1142
+ fillPathOrText,
1145
1143
  fillText,
1146
1144
  stroke,
1147
1145
  strokes,
@@ -1200,12 +1198,10 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1200
1198
 
1201
1199
  const { get: get$2, translate } = core.MatrixHelper;
1202
1200
  const tempBox = new core.Bounds();
1203
- const tempPoint = {};
1204
1201
  const tempScaleData = {};
1202
+ const tempImage = {};
1205
1203
  function createData(leafPaint, image, paint, box) {
1206
- const { blendMode, changeful, sync } = paint;
1207
- if (blendMode)
1208
- leafPaint.blendMode = blendMode;
1204
+ const { changeful, sync } = paint;
1209
1205
  if (changeful)
1210
1206
  leafPaint.changeful = changeful;
1211
1207
  if (sync)
@@ -1213,38 +1209,38 @@ function createData(leafPaint, image, paint, box) {
1213
1209
  leafPaint.data = getPatternData(paint, box, image);
1214
1210
  }
1215
1211
  function getPatternData(paint, box, image) {
1216
- let { width, height } = image;
1217
1212
  if (paint.padding)
1218
1213
  box = tempBox.set(box).shrink(paint.padding);
1219
1214
  if (paint.mode === 'strench')
1220
1215
  paint.mode = 'stretch';
1216
+ let { width, height } = image;
1221
1217
  const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1222
1218
  const sameBox = box.width === width && box.height === height;
1223
1219
  const data = { mode };
1224
1220
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1225
- const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1226
- let x = 0, y = 0, scaleX, scaleY;
1221
+ core.BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1222
+ let scaleX, scaleY;
1227
1223
  if (!mode || mode === 'cover' || mode === 'fit') {
1228
1224
  if (!sameBox || rotation) {
1229
- const sw = box.width / swapWidth, sh = box.height / swapHeight;
1230
- scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1231
- x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1225
+ scaleX = scaleY = core.BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1226
+ core.BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1227
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1232
1228
  }
1233
1229
  }
1234
- else if (scale || size) {
1235
- core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1236
- scaleX = tempScaleData.scaleX;
1237
- scaleY = tempScaleData.scaleY;
1238
- }
1239
- if (align) {
1240
- const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1241
- if (scaleX)
1242
- imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1243
- core.AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1244
- x += tempPoint.x, y += tempPoint.y;
1230
+ else {
1231
+ if (scale || size) {
1232
+ core.MathHelper.getScaleData(scale, size, image, tempScaleData);
1233
+ scaleX = tempScaleData.scaleX;
1234
+ scaleY = tempScaleData.scaleY;
1235
+ }
1236
+ if (align) {
1237
+ if (scaleX)
1238
+ core.BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1239
+ core.AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1240
+ }
1245
1241
  }
1246
1242
  if (offset)
1247
- x += offset.x, y += offset.y;
1243
+ core.PointHelper.move(tempImage, offset);
1248
1244
  switch (mode) {
1249
1245
  case 'stretch':
1250
1246
  if (!sameBox)
@@ -1252,12 +1248,12 @@ function getPatternData(paint, box, image) {
1252
1248
  break;
1253
1249
  case 'normal':
1254
1250
  case 'clip':
1255
- if (x || y || scaleX || rotation)
1256
- clipMode(data, box, x, y, scaleX, scaleY, rotation);
1251
+ if (tempImage.x || tempImage.y || scaleX || rotation)
1252
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1257
1253
  break;
1258
1254
  case 'repeat':
1259
1255
  if (!sameBox || scaleX || rotation)
1260
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1256
+ repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1261
1257
  if (!repeat)
1262
1258
  data.repeat = 'repeat';
1263
1259
  break;
@@ -1265,7 +1261,7 @@ function getPatternData(paint, box, image) {
1265
1261
  case 'cover':
1266
1262
  default:
1267
1263
  if (scaleX)
1268
- fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1264
+ fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1269
1265
  }
1270
1266
  if (!data.transform) {
1271
1267
  if (box.x || box.y) {
@@ -1298,6 +1294,8 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1298
1294
  }
1299
1295
  else {
1300
1296
  leafPaint = { type: paint.type, image };
1297
+ if (image.hasAlphaPixel)
1298
+ leafPaint.isTransparent = true;
1301
1299
  cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1302
1300
  }
1303
1301
  if (firstUse || image.loading)
@@ -1322,7 +1320,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1322
1320
  ignoreRender(ui, false);
1323
1321
  if (!ui.destroyed) {
1324
1322
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1325
- if (image.hasOpacityPixel)
1323
+ if (image.hasAlphaPixel)
1326
1324
  ui.__layout.hitCanvasChanged = true;
1327
1325
  ui.forceUpdate('surface');
1328
1326
  }
@@ -1334,6 +1332,17 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1334
1332
  onLoadError(ui, event, error);
1335
1333
  leafPaint.loadId = null;
1336
1334
  });
1335
+ if (ui.placeholderColor) {
1336
+ if (!ui.placeholderDelay)
1337
+ image.isPlacehold = true;
1338
+ else
1339
+ setTimeout(() => {
1340
+ if (!image.ready) {
1341
+ image.isPlacehold = true;
1342
+ ui.forceUpdate('surface');
1343
+ }
1344
+ }, ui.placeholderDelay);
1345
+ }
1337
1346
  }
1338
1347
  return leafPaint;
1339
1348
  }
@@ -1571,32 +1580,33 @@ const PaintImageModule = {
1571
1580
  repeatMode
1572
1581
  };
1573
1582
 
1574
- const { toPoint: toPoint$2 } = core.AroundHelper;
1583
+ const { toPoint: toPoint$2 } = core.AroundHelper, { hasTransparent } = draw.ColorConvert;
1575
1584
  const realFrom$2 = {};
1576
1585
  const realTo$2 = {};
1577
1586
  function linearGradient(paint, box) {
1578
- let { from, to, type, blendMode, opacity } = paint;
1587
+ let { from, to, type, opacity } = paint;
1579
1588
  toPoint$2(from || 'top', box, realFrom$2);
1580
1589
  toPoint$2(to || 'bottom', box, realTo$2);
1581
1590
  const style = core.Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1582
- applyStops(style, paint.stops, opacity);
1583
1591
  const data = { type, style };
1584
- if (blendMode)
1585
- data.blendMode = blendMode;
1592
+ applyStops(data, style, paint.stops, opacity);
1586
1593
  return data;
1587
1594
  }
1588
- function applyStops(gradient, stops, opacity) {
1595
+ function applyStops(data, gradient, stops, opacity) {
1589
1596
  if (stops) {
1590
- let stop;
1597
+ let stop, color, offset, isTransparent;
1591
1598
  for (let i = 0, len = stops.length; i < len; i++) {
1592
1599
  stop = stops[i];
1593
- if (typeof stop === 'string') {
1594
- gradient.addColorStop(i / (len - 1), draw.ColorConvert.string(stop, opacity));
1595
- }
1596
- else {
1597
- gradient.addColorStop(stop.offset, draw.ColorConvert.string(stop.color, opacity));
1598
- }
1600
+ if (typeof stop === 'string')
1601
+ offset = i / (len - 1), color = draw.ColorConvert.string(stop, opacity);
1602
+ else
1603
+ offset = stop.offset, color = draw.ColorConvert.string(stop.color, opacity);
1604
+ gradient.addColorStop(offset, color);
1605
+ if (!isTransparent && hasTransparent(color))
1606
+ isTransparent = true;
1599
1607
  }
1608
+ if (isTransparent)
1609
+ data.isTransparent = true;
1600
1610
  }
1601
1611
  }
1602
1612
 
@@ -1606,17 +1616,15 @@ const { toPoint: toPoint$1 } = core.AroundHelper;
1606
1616
  const realFrom$1 = {};
1607
1617
  const realTo$1 = {};
1608
1618
  function radialGradient(paint, box) {
1609
- let { from, to, type, opacity, blendMode, stretch } = paint;
1619
+ let { from, to, type, opacity, stretch } = paint;
1610
1620
  toPoint$1(from || 'center', box, realFrom$1);
1611
1621
  toPoint$1(to || 'bottom', box, realTo$1);
1612
1622
  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));
1613
- applyStops(style, paint.stops, opacity);
1614
1623
  const data = { type, style };
1624
+ applyStops(data, style, paint.stops, opacity);
1615
1625
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1616
1626
  if (transform)
1617
1627
  data.transform = transform;
1618
- if (blendMode)
1619
- data.blendMode = blendMode;
1620
1628
  return data;
1621
1629
  }
1622
1630
  function getTransform(box, from, to, stretch, rotate90) {
@@ -1642,17 +1650,15 @@ const { toPoint } = core.AroundHelper;
1642
1650
  const realFrom = {};
1643
1651
  const realTo = {};
1644
1652
  function conicGradient(paint, box) {
1645
- let { from, to, type, opacity, blendMode, stretch } = paint;
1653
+ let { from, to, type, opacity, stretch } = paint;
1646
1654
  toPoint(from || 'center', box, realFrom);
1647
1655
  toPoint(to || 'bottom', box, realTo);
1648
1656
  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));
1649
- applyStops(style, paint.stops, opacity);
1650
1657
  const data = { type, style };
1658
+ applyStops(data, style, paint.stops, opacity);
1651
1659
  const transform = getTransform(box, realFrom, realTo, stretch || 1, core.Platform.conicGradientRotate90);
1652
1660
  if (transform)
1653
1661
  data.transform = transform;
1654
- if (blendMode)
1655
- data.blendMode = blendMode;
1656
1662
  return data;
1657
1663
  }
1658
1664
 
@@ -1985,6 +1991,8 @@ function createRows(drawData, content, style) {
1985
1991
  lastCharType = null;
1986
1992
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1987
1993
  word = { data: [] }, row = { words: [] };
1994
+ if (__letterSpacing)
1995
+ content = [...content];
1988
1996
  for (let i = 0, len = content.length; i < len; i++) {
1989
1997
  char = content[i];
1990
1998
  if (char === '\n') {
@@ -2419,4 +2427,3 @@ Object.keys(draw).forEach(function (k) {
2419
2427
  get: function () { return draw[k]; }
2420
2428
  });
2421
2429
  });
2422
- //# sourceMappingURL=web.cjs.map