@visactor/vrender-core 0.21.0-alpha.10 → 0.21.0-alpha.12

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.
Files changed (46) hide show
  1. package/cjs/color-string/interpolate.js +1 -1
  2. package/cjs/color-string/store.js +1 -1
  3. package/cjs/common/3d-interceptor.js +2 -1
  4. package/cjs/common/canvas-utils.js +0 -1
  5. package/cjs/common/render-command-list.js +2 -1
  6. package/cjs/common/simplify.js +1 -2
  7. package/cjs/common/text.js +1 -1
  8. package/cjs/common/utils.d.ts +1 -0
  9. package/cjs/common/utils.js +10 -3
  10. package/cjs/common/utils.js.map +1 -1
  11. package/cjs/core/contributions/textMeasure/layout.d.ts +1 -0
  12. package/cjs/core/contributions/textMeasure/layout.js +18 -13
  13. package/cjs/core/contributions/textMeasure/layout.js.map +1 -1
  14. package/cjs/graphic/config.js +2 -1
  15. package/cjs/graphic/config.js.map +1 -1
  16. package/cjs/graphic/text.d.ts +1 -1
  17. package/cjs/graphic/text.js +16 -11
  18. package/cjs/graphic/text.js.map +1 -1
  19. package/cjs/graphic/wrap-text.js +8 -4
  20. package/cjs/graphic/wrap-text.js.map +1 -1
  21. package/cjs/interface/graphic/text.d.ts +2 -0
  22. package/cjs/interface/graphic/text.js.map +1 -1
  23. package/dist/index.es.js +52 -32
  24. package/es/color-string/interpolate.js +1 -1
  25. package/es/color-string/store.js +1 -1
  26. package/es/common/3d-interceptor.js +2 -1
  27. package/es/common/canvas-utils.js +1 -2
  28. package/es/common/render-command-list.js +2 -1
  29. package/es/common/simplify.js +1 -2
  30. package/es/common/text.js +1 -1
  31. package/es/common/utils.d.ts +1 -0
  32. package/es/common/utils.js +7 -2
  33. package/es/common/utils.js.map +1 -1
  34. package/es/core/contributions/textMeasure/layout.d.ts +1 -0
  35. package/es/core/contributions/textMeasure/layout.js +18 -13
  36. package/es/core/contributions/textMeasure/layout.js.map +1 -1
  37. package/es/graphic/config.js +2 -1
  38. package/es/graphic/config.js.map +1 -1
  39. package/es/graphic/text.d.ts +1 -1
  40. package/es/graphic/text.js +16 -11
  41. package/es/graphic/text.js.map +1 -1
  42. package/es/graphic/wrap-text.js +8 -4
  43. package/es/graphic/wrap-text.js.map +1 -1
  44. package/es/interface/graphic/text.d.ts +2 -0
  45. package/es/interface/graphic/text.js.map +1 -1
  46. package/package.json +3 -3
package/dist/index.es.js CHANGED
@@ -3068,7 +3068,8 @@ const DefaultTextStyle = {
3068
3068
  underlineDash: [],
3069
3069
  underlineOffset: 0,
3070
3070
  disableAutoClipedPoptip: undefined,
3071
- measureMode: MeasureModeEnum.fontBounding
3071
+ measureMode: MeasureModeEnum.fontBounding,
3072
+ keepCenterInLine: false
3072
3073
  };
3073
3074
  const DefaultPickStyle = {
3074
3075
  pickStrokeBuffer: 0
@@ -8406,13 +8407,17 @@ class RafBasedSTO {
8406
8407
  }
8407
8408
  RafBasedSTO.TimeOut = 1000 / 60;
8408
8409
  const rafBasedSto = new RafBasedSTO();
8409
- const calculateLineHeight = (lineHeight, fontSize) => {
8410
+ const _calculateLineHeight = (lineHeight, fontSize) => {
8410
8411
  if (isString(lineHeight) && lineHeight[lineHeight.length - 1] === '%') {
8411
8412
  const scale = Number.parseFloat(lineHeight.substring(0, lineHeight.length - 1)) / 100;
8412
8413
  return fontSize * scale;
8413
8414
  }
8414
8415
  return lineHeight;
8415
8416
  };
8417
+ const calculateLineHeight = (lineHeight, fontSize) => {
8418
+ const _lh = _calculateLineHeight(lineHeight, fontSize);
8419
+ return isNaN(_lh) ? _lh : Math.max(fontSize, _lh);
8420
+ };
8416
8421
 
8417
8422
  class IncreaseCount extends ACustomAnimate {
8418
8423
  constructor(from, to, duration, easing, params) {
@@ -19155,7 +19160,7 @@ class CanvasTextLayout {
19155
19160
  bbox.xOffset = -bbox.width;
19156
19161
  }
19157
19162
  else {
19158
- throw new Error('非法的textAlign');
19163
+ bbox.xOffset = 0;
19159
19164
  }
19160
19165
  if (textBaseline === 'top') {
19161
19166
  bbox.yOffset = 0;
@@ -19177,7 +19182,7 @@ class CanvasTextLayout {
19177
19182
  return bbox;
19178
19183
  }
19179
19184
  GetLayoutByLines(lines, textAlign, textBaseline, lineHeight, suffix = '', wordBreak, params) {
19180
- const { lineWidth, suffixPosition = 'end', measureMode = MeasureModeEnum.actualBounding } = params !== null && params !== void 0 ? params : {};
19185
+ const { lineWidth, suffixPosition = 'end', measureMode = MeasureModeEnum.actualBounding, keepCenterInLine = false } = params !== null && params !== void 0 ? params : {};
19181
19186
  lines = lines.map(l => l.toString());
19182
19187
  const linesLayout = [];
19183
19188
  const bboxWH = [0, 0];
@@ -19192,7 +19197,8 @@ class CanvasTextLayout {
19192
19197
  : this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
19193
19198
  width,
19194
19199
  ascent: metrics.ascent,
19195
- descent: metrics.descent
19200
+ descent: metrics.descent,
19201
+ keepCenterInLine
19196
19202
  });
19197
19203
  }
19198
19204
  bboxWH[0] = lineWidth;
@@ -19206,7 +19212,7 @@ class CanvasTextLayout {
19206
19212
  const metrics = this.textMeasure.measureTextPixelADscentAndWidth(lines[i], this.textOptions, measureMode);
19207
19213
  width = metrics.width;
19208
19214
  _lineWidth = Math.max(_lineWidth, width);
19209
- linesLayout.push({ str: text, width, ascent: metrics.ascent, descent: metrics.descent });
19215
+ linesLayout.push({ str: text, width, ascent: metrics.ascent, descent: metrics.descent, keepCenterInLine });
19210
19216
  }
19211
19217
  bboxWH[0] = _lineWidth;
19212
19218
  }
@@ -19256,15 +19262,22 @@ class CanvasTextLayout {
19256
19262
  line.leftOffset = bbox.width - line.width;
19257
19263
  }
19258
19264
  line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1];
19259
- const actualHeight = line.ascent + line.descent;
19260
- const buf = 0;
19261
- const actualHeightWithBuf = actualHeight + buf;
19262
- if (actualHeightWithBuf < lineHeight - buf) {
19263
- if (textBaseline === 'bottom') {
19264
- line.topOffset += (lineHeight - actualHeightWithBuf) / 2;
19265
+ if (!line.keepCenterInLine) {
19266
+ const actualHeight = line.ascent + line.descent;
19267
+ const buf = 0;
19268
+ const actualHeightWithBuf = actualHeight + buf;
19269
+ if (actualHeightWithBuf < lineHeight - buf) {
19270
+ if (textBaseline === 'bottom') {
19271
+ line.topOffset += (lineHeight - actualHeightWithBuf) / 2;
19272
+ }
19273
+ else if (textBaseline === 'top') {
19274
+ line.topOffset -= (lineHeight - actualHeightWithBuf) / 2;
19275
+ }
19265
19276
  }
19266
- else if (textBaseline === 'top') {
19267
- line.topOffset -= (lineHeight - actualHeightWithBuf) / 2;
19277
+ if (textBaseline === 'alphabetic') {
19278
+ const fontBoundingHeight = line.ascent + line.descent;
19279
+ const ratio = lineHeight / fontBoundingHeight;
19280
+ line.topOffset = lineHeight / 2 + ((line.ascent - line.descent) / 2) * ratio + origin[1];
19268
19281
  }
19269
19282
  }
19270
19283
  origin[1] += lineHeight;
@@ -19414,7 +19427,7 @@ class Text extends Graphic {
19414
19427
  updateSingallineAABBBounds(text) {
19415
19428
  this.updateMultilineAABBBounds([text]);
19416
19429
  const layoutData = this.cache.layoutData;
19417
- if (layoutData) {
19430
+ if (layoutData && layoutData.lines && layoutData.lines.length) {
19418
19431
  const line = layoutData.lines[0];
19419
19432
  this.cache.clipedText = line.str;
19420
19433
  this.cache.clipedWidth = line.width;
@@ -19441,9 +19454,9 @@ class Text extends Graphic {
19441
19454
  var _a;
19442
19455
  const textTheme = this.getGraphicTheme();
19443
19456
  const attribute = this.attribute;
19444
- const { fontFamily = textTheme.fontFamily, textAlign = textTheme.textAlign, textBaseline = textTheme.textBaseline, fontSize = textTheme.fontSize, fontWeight = textTheme.fontWeight, ellipsis = textTheme.ellipsis, maxLineWidth, stroke = textTheme.stroke, wrap = textTheme.wrap, measureMode = textTheme.measureMode, lineWidth = textTheme.lineWidth, whiteSpace = textTheme.whiteSpace, suffixPosition = textTheme.suffixPosition, ignoreBuf = textTheme.ignoreBuf } = attribute;
19457
+ const { fontFamily = textTheme.fontFamily, textAlign = textTheme.textAlign, textBaseline = textTheme.textBaseline, fontSize = textTheme.fontSize, fontWeight = textTheme.fontWeight, ellipsis = textTheme.ellipsis, maxLineWidth, stroke = textTheme.stroke, wrap = textTheme.wrap, measureMode = textTheme.measureMode, lineWidth = textTheme.lineWidth, whiteSpace = textTheme.whiteSpace, suffixPosition = textTheme.suffixPosition, ignoreBuf = textTheme.ignoreBuf, keepCenterInLine = textTheme.keepCenterInLine } = attribute;
19445
19458
  const buf = ignoreBuf ? 0 : this.guessLineHeightBuf(fontSize);
19446
- const lineHeight = this.getLineHeight(attribute, textTheme) + buf;
19459
+ const lineHeight = this.getLineHeight(attribute, textTheme, buf);
19447
19460
  if (whiteSpace === 'normal' || wrap) {
19448
19461
  return this.updateWrapAABBBounds(text);
19449
19462
  }
@@ -19460,7 +19473,8 @@ class Text extends Graphic {
19460
19473
  const layoutData = layoutObj.GetLayoutByLines(text, textAlign, textBaseline, lineHeight, ellipsis === true ? textTheme.ellipsis : ellipsis || undefined, false, {
19461
19474
  lineWidth: maxLineWidth,
19462
19475
  suffixPosition,
19463
- measureMode
19476
+ measureMode,
19477
+ keepCenterInLine
19464
19478
  });
19465
19479
  const { bbox } = layoutData;
19466
19480
  this.cache.layoutData = layoutData;
@@ -19474,9 +19488,9 @@ class Text extends Graphic {
19474
19488
  updateWrapAABBBounds(text) {
19475
19489
  var _a, _b, _c;
19476
19490
  const textTheme = this.getGraphicTheme();
19477
- const { fontFamily = textTheme.fontFamily, textAlign = textTheme.textAlign, textBaseline = textTheme.textBaseline, fontSize = textTheme.fontSize, ellipsis = textTheme.ellipsis, maxLineWidth, stroke = textTheme.stroke, lineWidth = textTheme.lineWidth, wordBreak = textTheme.wordBreak, fontWeight = textTheme.fontWeight, ignoreBuf = textTheme.ignoreBuf, measureMode = textTheme.measureMode, suffixPosition = textTheme.suffixPosition, heightLimit = 0, lineClamp } = this.attribute;
19491
+ const { fontFamily = textTheme.fontFamily, textAlign = textTheme.textAlign, textBaseline = textTheme.textBaseline, fontSize = textTheme.fontSize, ellipsis = textTheme.ellipsis, maxLineWidth, stroke = textTheme.stroke, lineWidth = textTheme.lineWidth, wordBreak = textTheme.wordBreak, fontWeight = textTheme.fontWeight, ignoreBuf = textTheme.ignoreBuf, measureMode = textTheme.measureMode, suffixPosition = textTheme.suffixPosition, heightLimit = 0, lineClamp, keepCenterInLine = textTheme.keepCenterInLine } = this.attribute;
19478
19492
  const buf = ignoreBuf ? 0 : this.guessLineHeightBuf(fontSize);
19479
- const lineHeight = this.getLineHeight(this.attribute, textTheme) + buf;
19493
+ const lineHeight = this.getLineHeight(this.attribute, textTheme, buf);
19480
19494
  if (!this.shouldUpdateShape() && ((_a = this.cache) === null || _a === void 0 ? void 0 : _a.layoutData)) {
19481
19495
  const bbox = this.cache.layoutData.bbox;
19482
19496
  this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height);
@@ -19510,7 +19524,8 @@ class Text extends Graphic {
19510
19524
  str: clip.str,
19511
19525
  width: clip.width,
19512
19526
  ascent: matrics.ascent,
19513
- descent: matrics.descent
19527
+ descent: matrics.descent,
19528
+ keepCenterInLine
19514
19529
  });
19515
19530
  break;
19516
19531
  }
@@ -19532,7 +19547,8 @@ class Text extends Graphic {
19532
19547
  str: clip.str,
19533
19548
  width: clip.width,
19534
19549
  ascent: matrics.ascent,
19535
- descent: matrics.descent
19550
+ descent: matrics.descent,
19551
+ keepCenterInLine
19536
19552
  });
19537
19553
  let cutLength = clip.str.length;
19538
19554
  if (clip.wordBreaked && !(str !== '' && clip.str === '')) {
@@ -19564,7 +19580,8 @@ class Text extends Graphic {
19564
19580
  str: clip.str,
19565
19581
  width: clip.width,
19566
19582
  ascent: matrics.ascent,
19567
- descent: matrics.descent
19583
+ descent: matrics.descent,
19584
+ keepCenterInLine
19568
19585
  });
19569
19586
  lineWidth = Math.max(lineWidth, clip.width);
19570
19587
  break;
@@ -19573,7 +19590,7 @@ class Text extends Graphic {
19573
19590
  width = textMeasure.measureTextWidth(text, textOptions);
19574
19591
  lineWidth = Math.max(lineWidth, width);
19575
19592
  const matrics = textMeasure.measureTextPixelADscentAndWidth(text, textOptions, measureMode);
19576
- linesLayout.push({ str: text, width, ascent: matrics.ascent, descent: matrics.descent });
19593
+ linesLayout.push({ str: text, width, ascent: matrics.ascent, descent: matrics.descent, keepCenterInLine });
19577
19594
  }
19578
19595
  bboxWH[0] = lineWidth;
19579
19596
  }
@@ -19601,7 +19618,7 @@ class Text extends Graphic {
19601
19618
  let width;
19602
19619
  const attribute = this.attribute;
19603
19620
  const { maxLineWidth = textTheme.maxLineWidth, ellipsis = textTheme.ellipsis, fontFamily = textTheme.fontFamily, fontSize = textTheme.fontSize, fontWeight = textTheme.fontWeight, stroke = textTheme.stroke, lineWidth = textTheme.lineWidth, verticalMode = textTheme.verticalMode, suffixPosition = textTheme.suffixPosition } = attribute;
19604
- const lineHeight = this.getLineHeight(attribute, textTheme);
19621
+ const lineHeight = this.getLineHeight(attribute, textTheme, 0);
19605
19622
  let { textAlign = textTheme.textAlign, textBaseline = textTheme.textBaseline } = attribute;
19606
19623
  if (!verticalMode) {
19607
19624
  const t = textAlign;
@@ -19671,9 +19688,9 @@ class Text extends Graphic {
19671
19688
  const attribute = this.attribute;
19672
19689
  return (_b = (_a = attribute.maxLineWidth) !== null && _a !== void 0 ? _a : attribute.maxWidth) !== null && _b !== void 0 ? _b : theme.maxWidth;
19673
19690
  }
19674
- getLineHeight(attribute, textTheme) {
19691
+ getLineHeight(attribute, textTheme, buf) {
19675
19692
  var _a;
19676
- return ((_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) !== null && _a !== void 0 ? _a : (attribute.fontSize || textTheme.fontSize));
19693
+ return ((_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) !== null && _a !== void 0 ? _a : (attribute.fontSize || textTheme.fontSize) + buf);
19677
19694
  }
19678
19695
  needUpdateTags(keys, k = TEXT_UPDATE_TAG_KEY) {
19679
19696
  return super.needUpdateTags(keys, k);
@@ -19758,7 +19775,8 @@ class WrapText extends Text {
19758
19775
  str: clip.str,
19759
19776
  width: clip.width,
19760
19777
  ascent: 0,
19761
- descent: 0
19778
+ descent: 0,
19779
+ keepCenterInLine: false
19762
19780
  });
19763
19781
  break;
19764
19782
  }
@@ -19779,7 +19797,8 @@ class WrapText extends Text {
19779
19797
  str: clip.str,
19780
19798
  width: clip.width,
19781
19799
  ascent: 0,
19782
- descent: 0
19800
+ descent: 0,
19801
+ keepCenterInLine: false
19783
19802
  });
19784
19803
  if (clip.str.length === str.length) ;
19785
19804
  else if (needCut) {
@@ -19805,7 +19824,8 @@ class WrapText extends Text {
19805
19824
  str: clip.str,
19806
19825
  width: clip.width,
19807
19826
  ascent: 0,
19808
- descent: 0
19827
+ descent: 0,
19828
+ keepCenterInLine: false
19809
19829
  });
19810
19830
  lineWidth = Math.max(lineWidth, clip.width);
19811
19831
  break;
@@ -19813,7 +19833,7 @@ class WrapText extends Text {
19813
19833
  text = lines[i];
19814
19834
  width = layoutObj.textMeasure.measureTextWidth(text, layoutObj.textOptions, wordBreak === 'break-word');
19815
19835
  lineWidth = Math.max(lineWidth, width);
19816
- linesLayout.push({ str: text, width, ascent: 0, descent: 0 });
19836
+ linesLayout.push({ str: text, width, ascent: 0, descent: 0, keepCenterInLine: false });
19817
19837
  }
19818
19838
  bboxWH[0] = lineWidth;
19819
19839
  }
@@ -28718,4 +28738,4 @@ const registerFlexLayoutPlugin = () => {
28718
28738
  Factory.registerPlugin('FlexLayoutPlugin', FlexLayoutPlugin);
28719
28739
  };
28720
28740
 
28721
- export { ACustomAnimate, ARC3D_NUMBER_TYPE, ARC_NUMBER_TYPE, AREA_NUMBER_TYPE, AbstractGraphicRender, Animate, AnimateGroup, AnimateGroup1, AnimateMode, AnimateStatus, AnimateStepType, Application, Arc, Arc3d, Arc3dRender, ArcRender, ArcRenderContribution, Area, AreaRender, AreaRenderContribution, AttributeAnimate, AttributeUpdateType, AutoEnablePlugins, BaseCanvas, BaseEnvContribution, BaseRender, BaseRenderContributionTime, BaseWindowHandlerContribution, Basis, BeforeRenderConstribution, BoundsContext, BoundsPicker, CIRCLE_NUMBER_TYPE, Canvas3DDrawItemInterceptor, Canvas3DPickItemInterceptor, CanvasFactory, CanvasTextLayout, CbAnimate, Circle, CircleRender, CircleRenderContribution, ClipAngleAnimate, ClipDirectionAnimate, ClipGraphicAnimate, ClipRadiusAnimate, ColorInterpolate, ColorStore, ColorType, CommonDrawItemInterceptorContribution, CommonRenderContribution, Container, ContainerModule, Context2dFactory, ContributionProvider, CurveContext, CurveTypeEnum, CustomEvent, CustomPath2D, CustomSymbolClass, DebugDrawItemInterceptorContribution, DefaultArcAllocate, DefaultArcAttribute, DefaultArcRenderContribution, DefaultAreaAllocate, DefaultAreaAttribute, DefaultAreaTextureRenderContribution, DefaultAttribute, DefaultBaseBackgroundRenderContribution, DefaultBaseInteractiveRenderContribution, DefaultBaseTextureRenderContribution, DefaultCanvasAllocate, DefaultCanvasArcRender, DefaultCanvasAreaRender, DefaultCanvasCircleRender, DefaultCanvasGroupRender, DefaultCanvasImageRender, DefaultCanvasLineRender, DefaultCanvasPathRender, DefaultCanvasPolygonRender, DefaultCanvasRectRender, DefaultCanvasSymbolRender, DefaultCanvasTextRender, DefaultCircleAllocate, DefaultCircleAttribute, DefaultCircleRenderContribution, DefaultConnectAttribute, DefaultDebugAttribute, DefaultFillStyle, DefaultGlobal, DefaultGlobalPickerService, DefaultGlyphAttribute, DefaultGraphicAllocate, DefaultGraphicMemoryManager, DefaultGraphicService, DefaultGraphicUtil, DefaultGroupAttribute, DefaultGroupBackgroundRenderContribution, DefaultImageAttribute, DefaultImageBackgroundRenderContribution, DefaultImageRenderContribution, DefaultLayerService, DefaultLayout, DefaultLineAllocate, DefaultLineAttribute, DefaultMat4Allocate, DefaultMatrixAllocate, DefaultMorphingAnimateConfig, DefaultPathAllocate, DefaultPathAttribute, DefaultPickService, DefaultPickStyle, DefaultPolygonAttribute, DefaultRect3dAttribute, DefaultRectAllocate, DefaultRectAttribute, DefaultRectRenderContribution, DefaultRenderService, DefaultRichTextAttribute, DefaultRichTextIconAttribute, DefaultStateAnimateConfig, DefaultStrokeStyle, DefaultStyle, DefaultSymbolAllocate, DefaultSymbolAttribute, DefaultSymbolRenderContribution, DefaultTextAllocate, DefaultTextAttribute, DefaultTextMeasureContribution, DefaultTextStyle, DefaultTicker, DefaultTimeline, DefaultTransform, DefaultTransformUtil, DefaultWindow, Direction$1 as Direction, DirectionalLight, DrawContribution, DrawItemInterceptor, DynamicLayerHandlerContribution, Edge, EmptyContext2d, EnvContribution, EventManager, EventSystem, EventTarget, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, Factory, FadeInPlus, FederatedEvent, FederatedMouseEvent, FederatedPointerEvent, FederatedWheelEvent, FlexLayoutPlugin, GLYPH_NUMBER_TYPE, GRAPHIC_UPDATE_TAG_KEY, GROUP_NUMBER_TYPE, Generator, GlobalPickerService, Glyph, GlyphRender, Graphic, GraphicAnimate, GraphicCreator$1 as GraphicCreator, GraphicPicker, GraphicRender, GraphicService, GraphicUtil, Group, GroupFadeIn, GroupFadeOut, GroupRender, GroupRenderContribution, GroupUpdateAABBBoundsMode, HtmlAttributePlugin, IContainPointMode, IMAGE_NUMBER_TYPE, Image, ImageRender, ImageRenderContribution, IncreaseCount, IncrementalDrawContribution, InputText, InteractiveDrawItemInterceptorContribution, InteractivePickItemInterceptorContribution, InteractiveSubRenderContribution, LINE_NUMBER_TYPE, Layer, LayerService, Line$1 as Line, LineRender, Linear, LinearClosed, ManualTickHandler, ManualTicker, Mat4Allocate, MatrixAllocate, MeasureModeEnum, Meteor, MonotoneX, MonotoneY, MorphingPath, MotionPath, MultiToOneMorphingPath, NOWORK_ANIMATE_ATTR, Node, OrthoCamera, PATH_NUMBER_TYPE, POLYGON_NUMBER_TYPE, PURE_STYLE_KEY, PYRAMID3D_NUMBER_TYPE, Path, PathRender, PathRenderContribution, PickItemInterceptor, PickerService, PluginService, Polygon, PolygonRender, PolygonRenderContribution, Pyramid3d, Pyramid3dRender, RAFTickHandler, RECT3D_NUMBER_TYPE, RECT_NUMBER_TYPE, RICHTEXT_NUMBER_TYPE, RafBasedSTO, ReactAttributePlugin, Rect, Rect3DRender, Rect3d, RectRender, RectRenderContribution, ReflectSegContext, RenderSelector, RenderService, ResourceLoader, RichText, RichTextEditPlugin, RichTextRender, RotateBySphereAnimate, SVG_ATTRIBUTE_MAP, SVG_ATTRIBUTE_MAP_KEYS, SVG_PARSE_ATTRIBUTE_MAP, SVG_PARSE_ATTRIBUTE_MAP_KEYS, SYMBOL_NUMBER_TYPE, SegContext, ShadowRoot, ShadowRootDrawItemInterceptorContribution, ShadowRootPickItemInterceptorContribution, SplitRectAfterRenderContribution, SplitRectBeforeRenderContribution, Stage, StaticLayerHandlerContribution, Step$1 as Step, StreamLight, SubAnimate, Symbol$1 as Symbol, SymbolRender, SymbolRenderContribution, TEXT_NUMBER_TYPE, TagPointsUpdate, Text, TextDirection, TextMeasureContribution, TextRender, TextRenderContribution, Theme, TimeOutTickHandler, TransformUtil, UpdateTag, VGlobal, VWindow, ViewTransform3dPlugin, VirtualLayerHandlerContribution, WILDCARD, WindowHandlerContribution, WrapText, XMLParser, _interpolateColor, addArcToBezierPath, addAttributeToPrototype, alignBezierCurves, alignSubpath, application, applyTransformOnBezierCurves, arc3dModule, arcModule, areaModule, bezier, bezierCurversToPath, binarySplitPolygon, bindContributionProvider, bindContributionProviderNoSingletonScope, boundStroke, builtInSymbolStrMap, builtinSymbols, builtinSymbolsMap, calcLineCache, calculateArcCornerRadius, calculateLineHeight, canvasAllocate, centroidOfSubpath, circleBounds, circleModule, clock, cloneGraphic, colorEqual, colorStringInterpolationToStr, container, cornerTangents, createArc, createArc3d, createArea, createCircle, createColor, createConicalGradient, createGlyph, createGroup, createImage, createLine, createMat4, createPath, createPolygon, createPyramid3d, createRect, createRect3d, createRectPath, createRichText, createShadowRoot, createStage, createSymbol, createText, createWrapText, cubicCalc, cubicLength, cubicPointAt, cubicSubdivide, defaultArcAllocate, defaultArcBackgroundRenderContribution, defaultArcRenderContribution, defaultArcTextureRenderContribution, defaultAreaAllocate, defaultBaseBackgroundRenderContribution, defaultBaseTextureRenderContribution, defaultCircleAllocate, defaultCircleBackgroundRenderContribution, defaultCircleRenderContribution, defaultCircleTextureRenderContribution, defaultGraphicMemoryManager, defaultGroupBackgroundRenderContribution, defaultImageBackgroundRenderContribution, defaultImageRenderContribution, defaultLineAllocate, defaultPathAllocate, defaultRectAllocate, defaultRectBackgroundRenderContribution, defaultRectRenderContribution, defaultRectTextureRenderContribution, defaultSymbolAllocate, defaultSymbolBackgroundRenderContribution, defaultSymbolRenderContribution, defaultSymbolTextureRenderContribution, defaultTextAllocate, defaultTicker, defaultTimeline, drawArc, drawArcPath$1 as drawArcPath, drawAreaSegments, drawIncrementalAreaSegments, drawIncrementalSegments, drawPathProxy, drawSegments, enumCommandMap, fillVisible, findBestMorphingRotation, findNextGraphic, flatten_simplify, foreach, foreachAsync, genBasisSegments, genBasisTypeSegments, genLinearClosedSegments, genLinearClosedTypeSegments, genLinearSegments, genLinearTypeSegments, genMonotoneXSegments, genMonotoneXTypeSegments, genMonotoneYSegments, genMonotoneYTypeSegments, genNumberType, genStepSegments, genStepTypeSegments, getAttributeFromDefaultAttrList, getConicGradientAt, getCurrentEnv, getExtraModelMatrix, getModelMatrix, getRichTextBounds, getScaledStroke, getTextBounds, getTheme, getThemeFromGroup, globalTheme, glyphModule, graphicCreator, graphicService, graphicUtil, identityMat4, imageModule, incrementalAddTo, inject, injectable, interpolateColor, interpolateGradientConicalColor, interpolateGradientLinearColor, interpolateGradientRadialColor, interpolatePureColorArray, intersect, isBrowserEnv, isNodeEnv, isSvg, isTransformKey, isXML, layerService, lineModule, lookAt, mat3Tomat4, mat4Allocate, matrixAllocate, morphPath, multiInject, multiToOneMorph, multiplyMat4Mat3, multiplyMat4Mat4, named, newThemeObj, oneToMultiMorph, ortho, parsePadding, parseStroke, parseSvgPath, pathModule, pathToBezierCurves, point$3 as point, pointEqual, pointInterpolation, pointInterpolationHighPerformance, pointsEqual, pointsInterpolation, polygonModule, preLoadAllModule, pyramid3dModule, rafBasedSto, rect3dModule, rectFillVisible, rectModule, rectStrokeVisible, recursiveCallBinarySplit, registerArc3dGraphic, registerArcGraphic, registerAreaGraphic, registerCircleGraphic, registerDirectionalLight, registerFlexLayoutPlugin, registerGlyphGraphic, registerGroupGraphic, registerHtmlAttributePlugin, registerImageGraphic, registerLineGraphic, registerOrthoCamera, registerPathGraphic, registerPolygonGraphic, registerPyramid3dGraphic, registerReactAttributePlugin, registerRect3dGraphic, registerRectGraphic, registerRichtextGraphic, registerShadowRootGraphic, registerSymbolGraphic, registerTextGraphic, registerViewTransform3dPlugin, registerWrapTextGraphic, renderCommandList, rewriteProto, richtextModule, rotateX, rotateY, rotateZ, runFill, runStroke, scaleMat4, segments, shouldUseMat4, snapLength, splitArc, splitArea, splitCircle, splitGraphic, splitLine, splitPath, splitPolygon, splitRect, splitToGrids, strCommandMap, strokeVisible, symbolModule, textAttributesToStyle, textDrawOffsetX, textDrawOffsetY, textLayoutOffsetY, textModule, transformKeys, transformMat4, transformUtil, translate, verticalLayout, vglobal, waitForAllSubLayers, wrapCanvas, wrapContext, xul };
28741
+ export { ACustomAnimate, ARC3D_NUMBER_TYPE, ARC_NUMBER_TYPE, AREA_NUMBER_TYPE, AbstractGraphicRender, Animate, AnimateGroup, AnimateGroup1, AnimateMode, AnimateStatus, AnimateStepType, Application, Arc, Arc3d, Arc3dRender, ArcRender, ArcRenderContribution, Area, AreaRender, AreaRenderContribution, AttributeAnimate, AttributeUpdateType, AutoEnablePlugins, BaseCanvas, BaseEnvContribution, BaseRender, BaseRenderContributionTime, BaseWindowHandlerContribution, Basis, BeforeRenderConstribution, BoundsContext, BoundsPicker, CIRCLE_NUMBER_TYPE, Canvas3DDrawItemInterceptor, Canvas3DPickItemInterceptor, CanvasFactory, CanvasTextLayout, CbAnimate, Circle, CircleRender, CircleRenderContribution, ClipAngleAnimate, ClipDirectionAnimate, ClipGraphicAnimate, ClipRadiusAnimate, ColorInterpolate, ColorStore, ColorType, CommonDrawItemInterceptorContribution, CommonRenderContribution, Container, ContainerModule, Context2dFactory, ContributionProvider, CurveContext, CurveTypeEnum, CustomEvent, CustomPath2D, CustomSymbolClass, DebugDrawItemInterceptorContribution, DefaultArcAllocate, DefaultArcAttribute, DefaultArcRenderContribution, DefaultAreaAllocate, DefaultAreaAttribute, DefaultAreaTextureRenderContribution, DefaultAttribute, DefaultBaseBackgroundRenderContribution, DefaultBaseInteractiveRenderContribution, DefaultBaseTextureRenderContribution, DefaultCanvasAllocate, DefaultCanvasArcRender, DefaultCanvasAreaRender, DefaultCanvasCircleRender, DefaultCanvasGroupRender, DefaultCanvasImageRender, DefaultCanvasLineRender, DefaultCanvasPathRender, DefaultCanvasPolygonRender, DefaultCanvasRectRender, DefaultCanvasSymbolRender, DefaultCanvasTextRender, DefaultCircleAllocate, DefaultCircleAttribute, DefaultCircleRenderContribution, DefaultConnectAttribute, DefaultDebugAttribute, DefaultFillStyle, DefaultGlobal, DefaultGlobalPickerService, DefaultGlyphAttribute, DefaultGraphicAllocate, DefaultGraphicMemoryManager, DefaultGraphicService, DefaultGraphicUtil, DefaultGroupAttribute, DefaultGroupBackgroundRenderContribution, DefaultImageAttribute, DefaultImageBackgroundRenderContribution, DefaultImageRenderContribution, DefaultLayerService, DefaultLayout, DefaultLineAllocate, DefaultLineAttribute, DefaultMat4Allocate, DefaultMatrixAllocate, DefaultMorphingAnimateConfig, DefaultPathAllocate, DefaultPathAttribute, DefaultPickService, DefaultPickStyle, DefaultPolygonAttribute, DefaultRect3dAttribute, DefaultRectAllocate, DefaultRectAttribute, DefaultRectRenderContribution, DefaultRenderService, DefaultRichTextAttribute, DefaultRichTextIconAttribute, DefaultStateAnimateConfig, DefaultStrokeStyle, DefaultStyle, DefaultSymbolAllocate, DefaultSymbolAttribute, DefaultSymbolRenderContribution, DefaultTextAllocate, DefaultTextAttribute, DefaultTextMeasureContribution, DefaultTextStyle, DefaultTicker, DefaultTimeline, DefaultTransform, DefaultTransformUtil, DefaultWindow, Direction$1 as Direction, DirectionalLight, DrawContribution, DrawItemInterceptor, DynamicLayerHandlerContribution, Edge, EmptyContext2d, EnvContribution, EventManager, EventSystem, EventTarget, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, Factory, FadeInPlus, FederatedEvent, FederatedMouseEvent, FederatedPointerEvent, FederatedWheelEvent, FlexLayoutPlugin, GLYPH_NUMBER_TYPE, GRAPHIC_UPDATE_TAG_KEY, GROUP_NUMBER_TYPE, Generator, GlobalPickerService, Glyph, GlyphRender, Graphic, GraphicAnimate, GraphicCreator$1 as GraphicCreator, GraphicPicker, GraphicRender, GraphicService, GraphicUtil, Group, GroupFadeIn, GroupFadeOut, GroupRender, GroupRenderContribution, GroupUpdateAABBBoundsMode, HtmlAttributePlugin, IContainPointMode, IMAGE_NUMBER_TYPE, Image, ImageRender, ImageRenderContribution, IncreaseCount, IncrementalDrawContribution, InputText, InteractiveDrawItemInterceptorContribution, InteractivePickItemInterceptorContribution, InteractiveSubRenderContribution, LINE_NUMBER_TYPE, Layer, LayerService, Line$1 as Line, LineRender, Linear, LinearClosed, ManualTickHandler, ManualTicker, Mat4Allocate, MatrixAllocate, MeasureModeEnum, Meteor, MonotoneX, MonotoneY, MorphingPath, MotionPath, MultiToOneMorphingPath, NOWORK_ANIMATE_ATTR, Node, OrthoCamera, PATH_NUMBER_TYPE, POLYGON_NUMBER_TYPE, PURE_STYLE_KEY, PYRAMID3D_NUMBER_TYPE, Path, PathRender, PathRenderContribution, PickItemInterceptor, PickerService, PluginService, Polygon, PolygonRender, PolygonRenderContribution, Pyramid3d, Pyramid3dRender, RAFTickHandler, RECT3D_NUMBER_TYPE, RECT_NUMBER_TYPE, RICHTEXT_NUMBER_TYPE, RafBasedSTO, ReactAttributePlugin, Rect, Rect3DRender, Rect3d, RectRender, RectRenderContribution, ReflectSegContext, RenderSelector, RenderService, ResourceLoader, RichText, RichTextEditPlugin, RichTextRender, RotateBySphereAnimate, SVG_ATTRIBUTE_MAP, SVG_ATTRIBUTE_MAP_KEYS, SVG_PARSE_ATTRIBUTE_MAP, SVG_PARSE_ATTRIBUTE_MAP_KEYS, SYMBOL_NUMBER_TYPE, SegContext, ShadowRoot, ShadowRootDrawItemInterceptorContribution, ShadowRootPickItemInterceptorContribution, SplitRectAfterRenderContribution, SplitRectBeforeRenderContribution, Stage, StaticLayerHandlerContribution, Step$1 as Step, StreamLight, SubAnimate, Symbol$1 as Symbol, SymbolRender, SymbolRenderContribution, TEXT_NUMBER_TYPE, TagPointsUpdate, Text, TextDirection, TextMeasureContribution, TextRender, TextRenderContribution, Theme, TimeOutTickHandler, TransformUtil, UpdateTag, VGlobal, VWindow, ViewTransform3dPlugin, VirtualLayerHandlerContribution, WILDCARD, WindowHandlerContribution, WrapText, XMLParser, _calculateLineHeight, _interpolateColor, addArcToBezierPath, addAttributeToPrototype, alignBezierCurves, alignSubpath, application, applyTransformOnBezierCurves, arc3dModule, arcModule, areaModule, bezier, bezierCurversToPath, binarySplitPolygon, bindContributionProvider, bindContributionProviderNoSingletonScope, boundStroke, builtInSymbolStrMap, builtinSymbols, builtinSymbolsMap, calcLineCache, calculateArcCornerRadius, calculateLineHeight, canvasAllocate, centroidOfSubpath, circleBounds, circleModule, clock, cloneGraphic, colorEqual, colorStringInterpolationToStr, container, cornerTangents, createArc, createArc3d, createArea, createCircle, createColor, createConicalGradient, createGlyph, createGroup, createImage, createLine, createMat4, createPath, createPolygon, createPyramid3d, createRect, createRect3d, createRectPath, createRichText, createShadowRoot, createStage, createSymbol, createText, createWrapText, cubicCalc, cubicLength, cubicPointAt, cubicSubdivide, defaultArcAllocate, defaultArcBackgroundRenderContribution, defaultArcRenderContribution, defaultArcTextureRenderContribution, defaultAreaAllocate, defaultBaseBackgroundRenderContribution, defaultBaseTextureRenderContribution, defaultCircleAllocate, defaultCircleBackgroundRenderContribution, defaultCircleRenderContribution, defaultCircleTextureRenderContribution, defaultGraphicMemoryManager, defaultGroupBackgroundRenderContribution, defaultImageBackgroundRenderContribution, defaultImageRenderContribution, defaultLineAllocate, defaultPathAllocate, defaultRectAllocate, defaultRectBackgroundRenderContribution, defaultRectRenderContribution, defaultRectTextureRenderContribution, defaultSymbolAllocate, defaultSymbolBackgroundRenderContribution, defaultSymbolRenderContribution, defaultSymbolTextureRenderContribution, defaultTextAllocate, defaultTicker, defaultTimeline, drawArc, drawArcPath$1 as drawArcPath, drawAreaSegments, drawIncrementalAreaSegments, drawIncrementalSegments, drawPathProxy, drawSegments, enumCommandMap, fillVisible, findBestMorphingRotation, findNextGraphic, flatten_simplify, foreach, foreachAsync, genBasisSegments, genBasisTypeSegments, genLinearClosedSegments, genLinearClosedTypeSegments, genLinearSegments, genLinearTypeSegments, genMonotoneXSegments, genMonotoneXTypeSegments, genMonotoneYSegments, genMonotoneYTypeSegments, genNumberType, genStepSegments, genStepTypeSegments, getAttributeFromDefaultAttrList, getConicGradientAt, getCurrentEnv, getExtraModelMatrix, getModelMatrix, getRichTextBounds, getScaledStroke, getTextBounds, getTheme, getThemeFromGroup, globalTheme, glyphModule, graphicCreator, graphicService, graphicUtil, identityMat4, imageModule, incrementalAddTo, inject, injectable, interpolateColor, interpolateGradientConicalColor, interpolateGradientLinearColor, interpolateGradientRadialColor, interpolatePureColorArray, intersect, isBrowserEnv, isNodeEnv, isSvg, isTransformKey, isXML, layerService, lineModule, lookAt, mat3Tomat4, mat4Allocate, matrixAllocate, morphPath, multiInject, multiToOneMorph, multiplyMat4Mat3, multiplyMat4Mat4, named, newThemeObj, oneToMultiMorph, ortho, parsePadding, parseStroke, parseSvgPath, pathModule, pathToBezierCurves, point$3 as point, pointEqual, pointInterpolation, pointInterpolationHighPerformance, pointsEqual, pointsInterpolation, polygonModule, preLoadAllModule, pyramid3dModule, rafBasedSto, rect3dModule, rectFillVisible, rectModule, rectStrokeVisible, recursiveCallBinarySplit, registerArc3dGraphic, registerArcGraphic, registerAreaGraphic, registerCircleGraphic, registerDirectionalLight, registerFlexLayoutPlugin, registerGlyphGraphic, registerGroupGraphic, registerHtmlAttributePlugin, registerImageGraphic, registerLineGraphic, registerOrthoCamera, registerPathGraphic, registerPolygonGraphic, registerPyramid3dGraphic, registerReactAttributePlugin, registerRect3dGraphic, registerRectGraphic, registerRichtextGraphic, registerShadowRootGraphic, registerSymbolGraphic, registerTextGraphic, registerViewTransform3dPlugin, registerWrapTextGraphic, renderCommandList, rewriteProto, richtextModule, rotateX, rotateY, rotateZ, runFill, runStroke, scaleMat4, segments, shouldUseMat4, snapLength, splitArc, splitArea, splitCircle, splitGraphic, splitLine, splitPath, splitPolygon, splitRect, splitToGrids, strCommandMap, strokeVisible, symbolModule, textAttributesToStyle, textDrawOffsetX, textDrawOffsetY, textLayoutOffsetY, textModule, transformKeys, transformMat4, transformUtil, translate, verticalLayout, vglobal, waitForAllSubLayers, wrapCanvas, wrapContext, xul };
@@ -97,4 +97,4 @@ export function colorStringInterpolationToStr(fromColor, toColor, ratio) {
97
97
  return ColorStore.Get(fromColor, ColorType.Color255, _fromColorRGB), ColorStore.Get(toColor, ColorType.Color255, _toColorRGB),
98
98
  `rgba(${Math.round(_fromColorRGB[0] + (_toColorRGB[0] - _fromColorRGB[0]) * ratio)},${Math.round(_fromColorRGB[1] + (_toColorRGB[1] - _fromColorRGB[1]) * ratio)},${Math.round(_fromColorRGB[2] + (_toColorRGB[2] - _fromColorRGB[2]) * ratio)},${_fromColorRGB[3] + (_toColorRGB[3] - _fromColorRGB[3]) * ratio})`;
99
99
  }
100
- //# sourceMappingURL=interpolate.js.map
100
+ //# sourceMappingURL=interpolate.js.map
@@ -45,4 +45,4 @@ export class ColorStore {
45
45
  }
46
46
 
47
47
  ColorStore.store255 = {}, ColorStore.store1 = {};
48
- //# sourceMappingURL=store.js.map
48
+ //# sourceMappingURL=store.js.map
@@ -43,4 +43,5 @@ export const draw3dItem = (context, graphic, callback, output) => {
43
43
  }));
44
44
  } else result = callback(isPie, is3d);
45
45
  return result;
46
- };
46
+ };
47
+ //# sourceMappingURL=3d-interceptor.js.map
@@ -48,5 +48,4 @@ function createConicGradient(context, color, x, y, w, h) {
48
48
  return color.stops.forEach((stop => {
49
49
  canvasGradient.addColorStop(stop.offset, stop.color);
50
50
  })), canvasGradient.GetPattern(w + x, h + y, undefined);
51
- }
52
- //# sourceMappingURL=canvas-utils.js.map
51
+ }
@@ -5,4 +5,5 @@ export function renderCommandList(commandList, context, x = 0, y = 0, sx = 1, sy
5
5
  const command = commandList[i];
6
6
  commandFuncs[command[0]](command, context, x, y, sx, sy, z);
7
7
  }
8
- }
8
+ }
9
+ //# sourceMappingURL=render-command-list.js.map
@@ -29,5 +29,4 @@ function simplifyDouglasPeucker(points, sqTolerance) {
29
29
  export function flatten_simplify(points, tolerance, highestQuality) {
30
30
  if (points.length <= 10) return points;
31
31
  return points = highestQuality ? points : simplifyRadialDist(points, void 0 !== tolerance ? tolerance * tolerance : 1);
32
- }
33
- //# sourceMappingURL=simplify.js.map
32
+ }
package/es/common/text.js CHANGED
@@ -24,4 +24,4 @@ export function textAttributesToStyle(attrs) {
24
24
  attrs.underline ? style["text-decoration"] = "underline" : attrs.lineThrough && (style["text-decoration"] = "line-through"),
25
25
  attrs.fill && isString(attrs.fill) && (style.color = attrs.fill), style;
26
26
  }
27
- //# sourceMappingURL=text.js.map
27
+ //# sourceMappingURL=text.js.map
@@ -38,4 +38,5 @@ export declare class RafBasedSTO {
38
38
  appendDuration(d: number): void;
39
39
  }
40
40
  export declare const rafBasedSto: RafBasedSTO;
41
+ export declare const _calculateLineHeight: (lineHeight: string | number, fontSize: number) => number;
41
42
  export declare const calculateLineHeight: (lineHeight: string | number, fontSize: number) => number;
@@ -141,10 +141,15 @@ RafBasedSTO.TimeOut = 1e3 / 60;
141
141
 
142
142
  export const rafBasedSto = new RafBasedSTO;
143
143
 
144
- export const calculateLineHeight = (lineHeight, fontSize) => {
144
+ export const _calculateLineHeight = (lineHeight, fontSize) => {
145
145
  if (isString(lineHeight) && "%" === lineHeight[lineHeight.length - 1]) {
146
146
  return fontSize * (Number.parseFloat(lineHeight.substring(0, lineHeight.length - 1)) / 100);
147
147
  }
148
148
  return lineHeight;
149
149
  };
150
- //# sourceMappingURL=utils.js.map
150
+
151
+ export const calculateLineHeight = (lineHeight, fontSize) => {
152
+ const _lh = _calculateLineHeight(lineHeight, fontSize);
153
+ return isNaN(_lh) ? _lh : Math.max(fontSize, _lh);
154
+ };
155
+ //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK3G,MAAM,CAAN,IAAY,IAOX;AAPD,WAAY,IAAI;IACd,6BAAc,CAAA;IACd,iCAAgB,CAAA;IAChB,mCAAiB,CAAA;IACjB,+BAAe,CAAA;IAEf,8BAAc,CAAA;AAChB,CAAC,EAPW,IAAI,KAAJ,IAAI,QAOf;AAGD,MAAM,WAAW,GAA6E;IAC5F,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAMF,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAA8B,EAI9B,EAAE;;IACF,IAAI,YAAY,GAAY,IAAI,CAAC;IAEjC,IAAI,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,WAAW,CAAC,CAAC,CAAC,GAAG,MAAiB,CAAC;YACnC,YAAY,KAAZ,YAAY,GAAK,CAAC,CAAC,CAAC,MAAA,WAAW,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC,EAAC;SAC7C;QACD,YAAY,GAAG,MAAiB,CAAC;KAClC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC7B,YAAY,KAAZ,YAAY,GAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAC;SACnC;KACF;SAAM;QACL,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACvB,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACvB,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACvB,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;KACxB;IAED,OAAO;QACL,YAAY;QACZ,MAAM,EAAE,WAAW;KACpB,CAAC;AACJ,CAAC,CAAC;AAGF,MAAM,YAAY,GAAqC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAMpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAA2C,EACA,EAAE;IAC7C,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,CAAC,CAAC;KACV;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QACpB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACxB,OAAO,CAAC,CAAC;SACV;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;SACnB;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/B,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,OAAO,YAAY,CAAC;SACrB;QAED,OAAO,OAA2C,CAAC;KACpD;IAED,OAAO,OAAiB,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,OAAO,GAAqD;IAChE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IACd,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IACd,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IACd,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;CACf,CAAC;AACF,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAQ3C,MAAM,UAAU,YAAY,CAAC,UAAkB,EAAE,QAAgB,EAAE,MAAc,EAAE,MAAe;IAGhG,OAAO,UAAU,IAAI,GAAG,EAAE;QACxB,UAAU,IAAI,GAAG,CAAC;KACnB;IACD,OAAO,UAAU,GAAG,CAAC,EAAE;QACrB,UAAU,IAAI,GAAG,CAAC;KACnB;IACD,OAAO,UAAU,GAAG,QAAQ,EAAE;QAC5B,QAAQ,IAAI,GAAG,CAAC;KACjB;IACD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAGtB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IAGvB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IAIvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEhD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC;IAC3D,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,GAAG,UAAU,GAAG,EAAE,EAAE;QACrD,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACzC,IAAI,CAAC,KAAK,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE;gBACvC,KAAK,GAAG,IAAI,CAAC;gBACb,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrB,SAAS;aACV;iBAAM,IAAI,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE;gBAC3C,MAAM;aACP;YACD,IAAI,KAAK,EAAE;gBACT,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aACtB;SACF;KACF;AAiBH,CAAC;AAOD,MAAM,UAAU,WAAW,CAAC,OAAkC,EAAE,OAAkC;IAChG,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAEpD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE;YACrC,OAAO,KAAK,CAAC;SACd;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC3E;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAE,OAAsB,CAAC,CAAC,GAAI,OAAsB,CAAC,CAAC,CAAC,EAAE;QAExE,OAAO,UAAU,CAAC,OAAqB,EAAE,OAAqB,CAAC,CAAC;KACjE;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,MAAM,UAAU,UAAU,CAAC,MAAkB,EAAE,MAAkB;IAC/D,OAAO,CACL,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;QACvB,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE;QACvB,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAClC,CAAC;AACJ,CAAC;AAQD,MAAM,UAAU,kBAAkB,CAAC,MAAkB,EAAE,MAAkB,EAAE,KAAa;IACtF,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACxE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAEpF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAW,EAAE,CAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,OAAO,KAAK,CAAC;AACf,CAAC;AAQD,MAAM,UAAU,iCAAiC,CAC/C,MAAkB,EAClB,MAAkB,EAClB,KAAa,EACb,KAAiB;IAEjB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACxE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAEpF,KAAK,CAAC,CAAC,GAAG,CAAW,CAAC;IACtB,KAAK,CAAC,CAAC,GAAG,CAAW,CAAC;IACtB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,OAAO,KAAK,CAAC;AACf,CAAC;AAQD,MAAM,UAAU,mBAAmB,CACjC,OAAkC,EAClC,OAAkC,EAClC,KAAa;IAEb,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE;QACxB,OAAO,EAAE,CAAC;KACX;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;KACrB;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;KACrB;IAED,IAAI,MAAM,GAAiB,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;QAEnC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC3B,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACvC,MAAM,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;SAC/D;KACF;SAAM;QAEL,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC3B,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACvC,MAAM,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;SAC/D;KACF;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,SAAS;IACT,SAAS;CACV,CAAC;AACF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE;IAC5C,OAAO,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,UAAU,+BAA+B,CAAC,IAAiD,EAAE,GAAW;IAC5G,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;QACjB,IAAI,GAAG,CAAC;QACR,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC,EAAE,EAAE;YACzD,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACpB;QACD,OAAO,GAAG,CAAC;KACZ;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,OAAO,WAAW;IAOtB,YAAY,UAAkB,WAAW,CAAC,OAAO;QAC/C,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,EAAwB;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,OAAO,UAAU,CACf,GAAG,EAAE;YACH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,EAAE,CAAC,CAAC,CAAC,CAAC;QACR,CAAC,EACD,IAAI,CAAC,OAAO,EACZ,IAAI,CACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,CAAS;QACb,YAAY,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,cAAc,CAAC,CAAS;QACtB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,sBAAsB,EAAE;YACvD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;SACxB;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CACrB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC,EACtF,IAAI,GAAG,EAAE,CACV,CAAC;IACJ,CAAC;;AAvCM,mBAAO,GAAG,IAAI,GAAG,EAAE,CAAC;AA0C7B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,UAA2B,EAAE,QAAgB,EAAU,EAAE;IAC3F,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACtF,OAAO,QAAQ,GAAG,KAAK,CAAC;KACzB;IACD,OAAO,UAAoB,CAAC;AAC9B,CAAC,CAAC","file":"utils.js","sourcesContent":["import type { IBounds, IPointLike } from '@visactor/vutils';\nimport { isBoolean, halfPi, pi, pi2, sin, cos, isArray, pointAt, Point, isString } from '@visactor/vutils';\nimport type { IGraphicAttribute, IStrokeStyle } from '../interface';\n\n// todo: 迁移到@visactor/vutils\n\nexport enum Edge {\n Top = 0b000001,\n Right = 0b000010,\n Bottom = 0b000100,\n Left = 0b001000,\n\n ALL = 0b001111\n}\n\n// 公共的stroke数组,避免大量数组生成\nconst _strokeVec4: [boolean | string, boolean | string, boolean | string, boolean | string] = [\n false,\n false,\n false,\n false\n];\n/**\n * 解析stroke配置\n * @param stroke\n * @returns\n */\nexport const parseStroke = (\n stroke: IStrokeStyle['stroke']\n): {\n isFullStroke: boolean;\n stroke: (boolean | string)[];\n} => {\n let isFullStroke: boolean = true;\n // 首先判断\n if (isBoolean(stroke, true)) {\n for (let i = 0; i < 4; i++) {\n _strokeVec4[i] = stroke as boolean;\n isFullStroke &&= !!(_strokeVec4[i] ?? true);\n }\n isFullStroke = stroke as boolean;\n } else if (Array.isArray(stroke)) {\n // array\n for (let i = 0; i < 4; i++) {\n _strokeVec4[i] = !!stroke[i];\n isFullStroke &&= !!_strokeVec4[i];\n }\n } else {\n _strokeVec4[0] = false;\n _strokeVec4[1] = false;\n _strokeVec4[2] = false;\n _strokeVec4[3] = false;\n }\n\n return {\n isFullStroke,\n stroke: _strokeVec4\n };\n};\n\n// 公共的padding数组,避免大量数组生成\nconst _paddingVec4: [number, number, number, number] = [0, 0, 0, 0];\n/**\n * 解析padding配置\n * @param padding\n * @returns\n */\nexport const parsePadding = (\n padding: IGraphicAttribute['boundsPadding']\n): number | [number, number, number, number] => {\n if (!padding) {\n return 0;\n }\n if (isArray(padding)) {\n if (padding.length === 0) {\n return 0;\n } else if (padding.length === 1) {\n return padding[0];\n } else if (padding.length === 2) {\n _paddingVec4[0] = padding[0];\n _paddingVec4[2] = padding[0];\n _paddingVec4[1] = padding[1];\n _paddingVec4[3] = padding[1];\n return _paddingVec4;\n }\n // 不考虑三个数的情况,三个数是用户传错了\n return padding as [number, number, number, number];\n }\n\n return padding as number;\n};\n\nconst _coords: [IPointLike, IPointLike, IPointLike, IPointLike] = [\n { x: 0, y: 0 },\n { x: 0, y: 0 },\n { x: 0, y: 0 },\n { x: 0, y: 0 }\n];\nconst indexList = [1, 2, 3, 0, 1, 2, 3, 0];\n/**\n * 计算circle一段弧线的bounds\n * @param startAngle 小于2pi\n * @param endAngle\n * @param radius\n * @param bounds\n */\nexport function circleBounds(startAngle: number, endAngle: number, radius: number, bounds: IBounds) {\n // startAngle小于2pi\n // endAngle - startAngle小于2pi\n while (startAngle >= pi2) {\n startAngle -= pi2;\n }\n while (startAngle < 0) {\n startAngle += pi2;\n }\n while (startAngle > endAngle) {\n endAngle += pi2;\n }\n _coords[0].x = radius;\n // _coords[0].y = 0;\n // _coords[1].x = 0;\n _coords[1].y = radius;\n _coords[2].x = -radius;\n // _coords[2].y = -radius;\n // _coords[3].x = 0;\n _coords[3].y = -radius;\n\n // (0,pi/2], (pi/2, pi], (pi, pi/2*3], (pi/2*3, 2pi]\n // 1, 2, 3, 0\n const startIdx = Math.ceil(startAngle / halfPi) % 4;\n const endIdx = Math.ceil(endAngle / halfPi) % 4;\n // console.log(startAngle, endAngle, cos(startAngle), sin(startAngle), cos(endAngle), sin(endAngle));\n bounds.add(cos(startAngle) * radius, sin(startAngle) * radius);\n bounds.add(cos(endAngle) * radius, sin(endAngle) * radius);\n if (startIdx !== endIdx || endAngle - startAngle > pi) {\n let match = false;\n for (let i = 0; i < indexList.length; i++) {\n if (!match && startIdx === indexList[i]) {\n match = true;\n const p = _coords[startIdx];\n bounds.add(p.x, p.y);\n continue;\n } else if (match && endIdx === indexList[i]) {\n break;\n }\n if (match) {\n const p = _coords[indexList[i]];\n bounds.add(p.x, p.y);\n }\n }\n }\n // const delta = Math.floor((endAngle - startAngle) / halfPi);\n // for (let i = 0; i < delta; i++) {\n // const p = _coords[(startIdx + i) % 4];\n // bounds.add(p.x, p.y);\n // }\n\n // // 计算y1, y2\n // const y2 = halfPi >= startAngle && halfPi <= endAngle ? radius : max(sin(startAngle), sin(endAngle)) * radius;\n // const y1 =\n // halfPi + pi >= startAngle && halfPi + pi <= endAngle ? -radius : min(sin(startAngle), sin(endAngle)) * radius;\n // const x2 = pi2 >= startAngle && pi2 <= endAngle ? radius : max(cos(startAngle), cos(endAngle)) * radius;\n // const x1 = pi >= startAngle && pi <= endAngle ? -radius : min(cos(startAngle), cos(endAngle)) * radius;\n\n // // bounds.set(x1, y1, x2, y2);\n // bounds.add(x1, y1);\n // bounds.add(x2, y2);\n}\n\n/**\n * 比较两个点数组是否相同\n * @param pointsA 数组A\n * @param pointsB 数组B\n */\nexport function pointsEqual(pointsA: IPointLike[] | IPointLike, pointsB: IPointLike[] | IPointLike): boolean {\n if (!pointsA || !pointsB) {\n return false;\n } // 需要传入pointsA和pointsB\n if (Array.isArray(pointsA) && Array.isArray(pointsB)) {\n // 如果pointsA和pointsB是数组\n if (pointsA.length !== pointsB.length) {\n return false;\n }\n return pointsA.every((point, index) => pointEqual(point, pointsB[index]));\n }\n if (!Number.isNaN((pointsA as IPointLike).x + (pointsA as IPointLike).y)) {\n // 如果pointA是IPoint(防止参数是undefined)\n return pointEqual(pointsA as IPointLike, pointsB as IPointLike);\n }\n return false;\n}\n\n/**\n * 比较两个点是否相同\n * @param pointA 点A\n * @param pointB 点B\n */\nexport function pointEqual(pointA: IPointLike, pointB: IPointLike): boolean {\n return (\n pointA.x === pointB.x &&\n pointA.y === pointB.y &&\n pointA.x1 === pointB.x1 &&\n pointA.y1 === pointB.y1 &&\n pointA.defined === pointB.defined\n );\n}\n\n/**\n * 两点插值\n * @param pointA 点A\n * @param pointB 点B\n * @param ratio 比例\n */\nexport function pointInterpolation(pointA: IPointLike, pointB: IPointLike, ratio: number): IPointLike {\n const { x, y } = pointAt(pointA.x, pointA.y, pointB.x, pointB.y, ratio);\n const { x: x1, y: y1 } = pointAt(pointA.x1, pointA.y1, pointB.x1, pointB.y1, ratio);\n\n const point = new Point(x as number, y as number, x1, y1);\n point.defined = pointB.defined;\n return point;\n}\n\n/**\n * 两点插值\n * @param pointA 点A\n * @param pointB 点B\n * @param ratio 比例\n */\nexport function pointInterpolationHighPerformance(\n pointA: IPointLike,\n pointB: IPointLike,\n ratio: number,\n point: IPointLike\n): IPointLike {\n const { x, y } = pointAt(pointA.x, pointA.y, pointB.x, pointB.y, ratio);\n const { x: x1, y: y1 } = pointAt(pointA.x1, pointA.y1, pointB.x1, pointB.y1, ratio);\n // const point = new Point(x as number, y as number, x1, y1);\n point.x = x as number;\n point.y = y as number;\n point.x1 = x1;\n point.y1 = y1;\n point.defined = pointB.defined;\n return point;\n}\n\n/**\n * 点数组插值\n * @param pointsA 点数组A\n * @param pointsB 点数组B\n * @param ratio 比例\n */\nexport function pointsInterpolation(\n pointsA: IPointLike[] | IPointLike,\n pointsB: IPointLike[] | IPointLike,\n ratio: number\n): IPointLike[] {\n if (!pointsA || !pointsB) {\n return [];\n } // 需要传入pointsA和pointsB\n if (!Array.isArray(pointsA)) {\n pointsA = [pointsA];\n }\n if (!Array.isArray(pointsB)) {\n pointsB = [pointsB];\n }\n\n let points: IPointLike[] = [];\n if (pointsA.length > pointsB.length) {\n // 如果变短了,那么后面点的直接clip\n points = pointsB.map(point => {\n const p = new Point(point.x, point.y, point.x1, point.y1);\n p.defined = point.defined;\n return p;\n });\n for (let i = 0; i < pointsB.length; i++) {\n points[i] = pointInterpolation(pointsA[i], pointsB[i], ratio);\n }\n } else {\n // 如果变长了,加上后面的点\n points = pointsB.map(point => {\n const p = new Point(point.x, point.y, point.x1, point.y1);\n p.defined = point.defined;\n return p;\n });\n for (let i = 0; i < pointsA.length; i++) {\n points[i] = pointInterpolation(pointsA[i], pointsB[i], ratio);\n }\n }\n return points;\n}\n\nexport const transformKeys = [\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'scaleX',\n 'scaleY',\n 'angle',\n 'anchor',\n 'postMatrix',\n 'scrollX',\n 'scrollY'\n];\nexport const isTransformKey = (key: string) => {\n return transformKeys.includes(key);\n};\n\nexport function getAttributeFromDefaultAttrList(attr: Record<string, any> | Record<string, any>[], key: string) {\n if (isArray(attr)) {\n let val;\n for (let i = 0; i < attr.length && val === undefined; i++) {\n val = attr[i][key];\n }\n return val;\n }\n return attr[key];\n}\n\nexport class RafBasedSTO {\n static TimeOut = 1000 / 60;\n durations: number[];\n timeout: number;\n lastDate: number;\n durationsListThreshold: number;\n\n constructor(timeout: number = RafBasedSTO.TimeOut) {\n this.durations = [];\n this.timeout = timeout;\n this.lastDate = 0;\n this.durationsListThreshold = 30;\n }\n\n call(cb: FrameRequestCallback) {\n this.lastDate = Date.now();\n return setTimeout(\n () => {\n this.appendDuration(Date.now() - this.lastDate);\n cb(0);\n },\n this.timeout,\n true\n );\n }\n\n clear(h: number) {\n clearTimeout(h);\n }\n\n appendDuration(d: number) {\n this.durations.push(d);\n if (this.durations.length > this.durationsListThreshold) {\n this.durations.shift();\n }\n // 最多60fps, 最少30fps\n this.timeout = Math.min(\n Math.max(this.durations.reduce((a, b) => a + b, 0) / this.durations.length, 1000 / 60),\n 1000 / 30\n );\n }\n}\n\nexport const rafBasedSto = new RafBasedSTO();\n\nexport const calculateLineHeight = (lineHeight: string | number, fontSize: number): number => {\n if (isString(lineHeight) && lineHeight[lineHeight.length - 1] === '%') {\n const scale = Number.parseFloat(lineHeight.substring(0, lineHeight.length - 1)) / 100;\n return fontSize * scale;\n }\n return lineHeight as number;\n};\n"]}
1
+ {"version":3,"sources":["../src/common/utils.ts"],"names":[],"mappings":"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","file":"utils.js","sourcesContent":["import type { IBounds, IPointLike } from '@visactor/vutils';\nimport { isBoolean, halfPi, pi, pi2, sin, cos, isArray, pointAt, Point, isString } from '@visactor/vutils';\nimport type { IGraphicAttribute, IStrokeStyle } from '../interface';\n\n// todo: 迁移到@visactor/vutils\n\nexport enum Edge {\n Top = 0b000001,\n Right = 0b000010,\n Bottom = 0b000100,\n Left = 0b001000,\n\n ALL = 0b001111\n}\n\n// 公共的stroke数组,避免大量数组生成\nconst _strokeVec4: [boolean | string, boolean | string, boolean | string, boolean | string] = [\n false,\n false,\n false,\n false\n];\n/**\n * 解析stroke配置\n * @param stroke\n * @returns\n */\nexport const parseStroke = (\n stroke: IStrokeStyle['stroke']\n): {\n isFullStroke: boolean;\n stroke: (boolean | string)[];\n} => {\n let isFullStroke: boolean = true;\n // 首先判断\n if (isBoolean(stroke, true)) {\n for (let i = 0; i < 4; i++) {\n _strokeVec4[i] = stroke as boolean;\n isFullStroke &&= !!(_strokeVec4[i] ?? true);\n }\n isFullStroke = stroke as boolean;\n } else if (Array.isArray(stroke)) {\n // array\n for (let i = 0; i < 4; i++) {\n _strokeVec4[i] = !!stroke[i];\n isFullStroke &&= !!_strokeVec4[i];\n }\n } else {\n _strokeVec4[0] = false;\n _strokeVec4[1] = false;\n _strokeVec4[2] = false;\n _strokeVec4[3] = false;\n }\n\n return {\n isFullStroke,\n stroke: _strokeVec4\n };\n};\n\n// 公共的padding数组,避免大量数组生成\nconst _paddingVec4: [number, number, number, number] = [0, 0, 0, 0];\n/**\n * 解析padding配置\n * @param padding\n * @returns\n */\nexport const parsePadding = (\n padding: IGraphicAttribute['boundsPadding']\n): number | [number, number, number, number] => {\n if (!padding) {\n return 0;\n }\n if (isArray(padding)) {\n if (padding.length === 0) {\n return 0;\n } else if (padding.length === 1) {\n return padding[0];\n } else if (padding.length === 2) {\n _paddingVec4[0] = padding[0];\n _paddingVec4[2] = padding[0];\n _paddingVec4[1] = padding[1];\n _paddingVec4[3] = padding[1];\n return _paddingVec4;\n }\n // 不考虑三个数的情况,三个数是用户传错了\n return padding as [number, number, number, number];\n }\n\n return padding as number;\n};\n\nconst _coords: [IPointLike, IPointLike, IPointLike, IPointLike] = [\n { x: 0, y: 0 },\n { x: 0, y: 0 },\n { x: 0, y: 0 },\n { x: 0, y: 0 }\n];\nconst indexList = [1, 2, 3, 0, 1, 2, 3, 0];\n/**\n * 计算circle一段弧线的bounds\n * @param startAngle 小于2pi\n * @param endAngle\n * @param radius\n * @param bounds\n */\nexport function circleBounds(startAngle: number, endAngle: number, radius: number, bounds: IBounds) {\n // startAngle小于2pi\n // endAngle - startAngle小于2pi\n while (startAngle >= pi2) {\n startAngle -= pi2;\n }\n while (startAngle < 0) {\n startAngle += pi2;\n }\n while (startAngle > endAngle) {\n endAngle += pi2;\n }\n _coords[0].x = radius;\n // _coords[0].y = 0;\n // _coords[1].x = 0;\n _coords[1].y = radius;\n _coords[2].x = -radius;\n // _coords[2].y = -radius;\n // _coords[3].x = 0;\n _coords[3].y = -radius;\n\n // (0,pi/2], (pi/2, pi], (pi, pi/2*3], (pi/2*3, 2pi]\n // 1, 2, 3, 0\n const startIdx = Math.ceil(startAngle / halfPi) % 4;\n const endIdx = Math.ceil(endAngle / halfPi) % 4;\n // console.log(startAngle, endAngle, cos(startAngle), sin(startAngle), cos(endAngle), sin(endAngle));\n bounds.add(cos(startAngle) * radius, sin(startAngle) * radius);\n bounds.add(cos(endAngle) * radius, sin(endAngle) * radius);\n if (startIdx !== endIdx || endAngle - startAngle > pi) {\n let match = false;\n for (let i = 0; i < indexList.length; i++) {\n if (!match && startIdx === indexList[i]) {\n match = true;\n const p = _coords[startIdx];\n bounds.add(p.x, p.y);\n continue;\n } else if (match && endIdx === indexList[i]) {\n break;\n }\n if (match) {\n const p = _coords[indexList[i]];\n bounds.add(p.x, p.y);\n }\n }\n }\n // const delta = Math.floor((endAngle - startAngle) / halfPi);\n // for (let i = 0; i < delta; i++) {\n // const p = _coords[(startIdx + i) % 4];\n // bounds.add(p.x, p.y);\n // }\n\n // // 计算y1, y2\n // const y2 = halfPi >= startAngle && halfPi <= endAngle ? radius : max(sin(startAngle), sin(endAngle)) * radius;\n // const y1 =\n // halfPi + pi >= startAngle && halfPi + pi <= endAngle ? -radius : min(sin(startAngle), sin(endAngle)) * radius;\n // const x2 = pi2 >= startAngle && pi2 <= endAngle ? radius : max(cos(startAngle), cos(endAngle)) * radius;\n // const x1 = pi >= startAngle && pi <= endAngle ? -radius : min(cos(startAngle), cos(endAngle)) * radius;\n\n // // bounds.set(x1, y1, x2, y2);\n // bounds.add(x1, y1);\n // bounds.add(x2, y2);\n}\n\n/**\n * 比较两个点数组是否相同\n * @param pointsA 数组A\n * @param pointsB 数组B\n */\nexport function pointsEqual(pointsA: IPointLike[] | IPointLike, pointsB: IPointLike[] | IPointLike): boolean {\n if (!pointsA || !pointsB) {\n return false;\n } // 需要传入pointsA和pointsB\n if (Array.isArray(pointsA) && Array.isArray(pointsB)) {\n // 如果pointsA和pointsB是数组\n if (pointsA.length !== pointsB.length) {\n return false;\n }\n return pointsA.every((point, index) => pointEqual(point, pointsB[index]));\n }\n if (!Number.isNaN((pointsA as IPointLike).x + (pointsA as IPointLike).y)) {\n // 如果pointA是IPoint(防止参数是undefined)\n return pointEqual(pointsA as IPointLike, pointsB as IPointLike);\n }\n return false;\n}\n\n/**\n * 比较两个点是否相同\n * @param pointA 点A\n * @param pointB 点B\n */\nexport function pointEqual(pointA: IPointLike, pointB: IPointLike): boolean {\n return (\n pointA.x === pointB.x &&\n pointA.y === pointB.y &&\n pointA.x1 === pointB.x1 &&\n pointA.y1 === pointB.y1 &&\n pointA.defined === pointB.defined\n );\n}\n\n/**\n * 两点插值\n * @param pointA 点A\n * @param pointB 点B\n * @param ratio 比例\n */\nexport function pointInterpolation(pointA: IPointLike, pointB: IPointLike, ratio: number): IPointLike {\n const { x, y } = pointAt(pointA.x, pointA.y, pointB.x, pointB.y, ratio);\n const { x: x1, y: y1 } = pointAt(pointA.x1, pointA.y1, pointB.x1, pointB.y1, ratio);\n\n const point = new Point(x as number, y as number, x1, y1);\n point.defined = pointB.defined;\n return point;\n}\n\n/**\n * 两点插值\n * @param pointA 点A\n * @param pointB 点B\n * @param ratio 比例\n */\nexport function pointInterpolationHighPerformance(\n pointA: IPointLike,\n pointB: IPointLike,\n ratio: number,\n point: IPointLike\n): IPointLike {\n const { x, y } = pointAt(pointA.x, pointA.y, pointB.x, pointB.y, ratio);\n const { x: x1, y: y1 } = pointAt(pointA.x1, pointA.y1, pointB.x1, pointB.y1, ratio);\n // const point = new Point(x as number, y as number, x1, y1);\n point.x = x as number;\n point.y = y as number;\n point.x1 = x1;\n point.y1 = y1;\n point.defined = pointB.defined;\n return point;\n}\n\n/**\n * 点数组插值\n * @param pointsA 点数组A\n * @param pointsB 点数组B\n * @param ratio 比例\n */\nexport function pointsInterpolation(\n pointsA: IPointLike[] | IPointLike,\n pointsB: IPointLike[] | IPointLike,\n ratio: number\n): IPointLike[] {\n if (!pointsA || !pointsB) {\n return [];\n } // 需要传入pointsA和pointsB\n if (!Array.isArray(pointsA)) {\n pointsA = [pointsA];\n }\n if (!Array.isArray(pointsB)) {\n pointsB = [pointsB];\n }\n\n let points: IPointLike[] = [];\n if (pointsA.length > pointsB.length) {\n // 如果变短了,那么后面点的直接clip\n points = pointsB.map(point => {\n const p = new Point(point.x, point.y, point.x1, point.y1);\n p.defined = point.defined;\n return p;\n });\n for (let i = 0; i < pointsB.length; i++) {\n points[i] = pointInterpolation(pointsA[i], pointsB[i], ratio);\n }\n } else {\n // 如果变长了,加上后面的点\n points = pointsB.map(point => {\n const p = new Point(point.x, point.y, point.x1, point.y1);\n p.defined = point.defined;\n return p;\n });\n for (let i = 0; i < pointsA.length; i++) {\n points[i] = pointInterpolation(pointsA[i], pointsB[i], ratio);\n }\n }\n return points;\n}\n\nexport const transformKeys = [\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'scaleX',\n 'scaleY',\n 'angle',\n 'anchor',\n 'postMatrix',\n 'scrollX',\n 'scrollY'\n];\nexport const isTransformKey = (key: string) => {\n return transformKeys.includes(key);\n};\n\nexport function getAttributeFromDefaultAttrList(attr: Record<string, any> | Record<string, any>[], key: string) {\n if (isArray(attr)) {\n let val;\n for (let i = 0; i < attr.length && val === undefined; i++) {\n val = attr[i][key];\n }\n return val;\n }\n return attr[key];\n}\n\nexport class RafBasedSTO {\n static TimeOut = 1000 / 60;\n durations: number[];\n timeout: number;\n lastDate: number;\n durationsListThreshold: number;\n\n constructor(timeout: number = RafBasedSTO.TimeOut) {\n this.durations = [];\n this.timeout = timeout;\n this.lastDate = 0;\n this.durationsListThreshold = 30;\n }\n\n call(cb: FrameRequestCallback) {\n this.lastDate = Date.now();\n return setTimeout(\n () => {\n this.appendDuration(Date.now() - this.lastDate);\n cb(0);\n },\n this.timeout,\n true\n );\n }\n\n clear(h: number) {\n clearTimeout(h);\n }\n\n appendDuration(d: number) {\n this.durations.push(d);\n if (this.durations.length > this.durationsListThreshold) {\n this.durations.shift();\n }\n // 最多60fps, 最少30fps\n this.timeout = Math.min(\n Math.max(this.durations.reduce((a, b) => a + b, 0) / this.durations.length, 1000 / 60),\n 1000 / 30\n );\n }\n}\n\nexport const rafBasedSto = new RafBasedSTO();\n\nexport const _calculateLineHeight = (lineHeight: string | number, fontSize: number): number => {\n if (isString(lineHeight) && lineHeight[lineHeight.length - 1] === '%') {\n const scale = Number.parseFloat(lineHeight.substring(0, lineHeight.length - 1)) / 100;\n return fontSize * scale;\n }\n return lineHeight as number;\n};\n\nexport const calculateLineHeight = (lineHeight: string | number, fontSize: number): number => {\n const _lh = _calculateLineHeight(lineHeight, fontSize);\n return isNaN(_lh) ? _lh : Math.max(fontSize, _lh);\n};\n"]}
@@ -11,6 +11,7 @@ export declare class CanvasTextLayout {
11
11
  lineWidth?: number;
12
12
  suffixPosition?: 'start' | 'end' | 'middle';
13
13
  measureMode?: MeasureModeEnum;
14
+ keepCenterInLine?: boolean;
14
15
  }): LayoutType;
15
16
  layoutWithBBox(bbox: TextLayoutBBox, lines: LayoutItemType[], textAlign: TextAlignType, textBaseline: TextBaselineType, lineHeight: number): LayoutType;
16
17
  private lineOffset;
@@ -5,11 +5,8 @@ export class CanvasTextLayout {
5
5
  this.fontFamily = fontFamily, this.textOptions = options, this.textMeasure = textMeasure;
6
6
  }
7
7
  LayoutBBox(bbox, textAlign, textBaseline, linesLayout) {
8
- if ("left" === textAlign || "start" === textAlign) bbox.xOffset = 0; else if ("center" === textAlign) bbox.xOffset = bbox.width / -2; else {
9
- if ("right" !== textAlign && "end" !== textAlign) throw new Error("非法的textAlign");
10
- bbox.xOffset = -bbox.width;
11
- }
12
- if ("top" === textBaseline) bbox.yOffset = 0; else if ("middle" === textBaseline) bbox.yOffset = bbox.height / -2; else if ("alphabetic" === textBaseline) {
8
+ if (bbox.xOffset = "left" === textAlign || "start" === textAlign ? 0 : "center" === textAlign ? bbox.width / -2 : "right" === textAlign || "end" === textAlign ? -bbox.width : 0,
9
+ "top" === textBaseline) bbox.yOffset = 0; else if ("middle" === textBaseline) bbox.yOffset = bbox.height / -2; else if ("alphabetic" === textBaseline) {
13
10
  let percent = .79;
14
11
  if (1 === linesLayout.length) {
15
12
  const lineInfo = linesLayout[0];
@@ -20,7 +17,7 @@ export class CanvasTextLayout {
20
17
  return bbox;
21
18
  }
22
19
  GetLayoutByLines(lines, textAlign, textBaseline, lineHeight, suffix = "", wordBreak, params) {
23
- const {lineWidth: lineWidth, suffixPosition: suffixPosition = "end", measureMode: measureMode = MeasureModeEnum.actualBounding} = null != params ? params : {};
20
+ const {lineWidth: lineWidth, suffixPosition: suffixPosition = "end", measureMode: measureMode = MeasureModeEnum.actualBounding, keepCenterInLine: keepCenterInLine = !1} = null != params ? params : {};
24
21
  lines = lines.map((l => l.toString()));
25
22
  const linesLayout = [], bboxWH = [ 0, 0 ];
26
23
  if ("number" == typeof lineWidth && lineWidth !== 1 / 0) {
@@ -31,7 +28,8 @@ export class CanvasTextLayout {
31
28
  str: metrics.width <= lineWidth ? lines[i].toString() : this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
32
29
  width: width,
33
30
  ascent: metrics.ascent,
34
- descent: metrics.descent
31
+ descent: metrics.descent,
32
+ keepCenterInLine: keepCenterInLine
35
33
  });
36
34
  }
37
35
  bboxWH[0] = lineWidth;
@@ -44,7 +42,8 @@ export class CanvasTextLayout {
44
42
  str: text,
45
43
  width: width,
46
44
  ascent: metrics.ascent,
47
- descent: metrics.descent
45
+ descent: metrics.descent,
46
+ keepCenterInLine: keepCenterInLine
48
47
  });
49
48
  }
50
49
  bboxWH[0] = _lineWidth;
@@ -74,11 +73,17 @@ export class CanvasTextLayout {
74
73
  };
75
74
  }
76
75
  lineOffset(bbox, line, textAlign, textBaseline, lineHeight, origin) {
77
- "left" === textAlign || "start" === textAlign ? line.leftOffset = 0 : "center" === textAlign ? line.leftOffset = (bbox.width - line.width) / 2 : "right" !== textAlign && "end" !== textAlign || (line.leftOffset = bbox.width - line.width),
78
- line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1];
79
- const actualHeightWithBuf = line.ascent + line.descent + 0;
80
- return actualHeightWithBuf < lineHeight - 0 && ("bottom" === textBaseline ? line.topOffset += (lineHeight - actualHeightWithBuf) / 2 : "top" === textBaseline && (line.topOffset -= (lineHeight - actualHeightWithBuf) / 2)),
81
- origin[1] += lineHeight, line;
76
+ if ("left" === textAlign || "start" === textAlign ? line.leftOffset = 0 : "center" === textAlign ? line.leftOffset = (bbox.width - line.width) / 2 : "right" !== textAlign && "end" !== textAlign || (line.leftOffset = bbox.width - line.width),
77
+ line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1],
78
+ !line.keepCenterInLine) {
79
+ const buf = 0, actualHeightWithBuf = line.ascent + line.descent + buf;
80
+ if (actualHeightWithBuf < lineHeight - buf && ("bottom" === textBaseline ? line.topOffset += (lineHeight - actualHeightWithBuf) / 2 : "top" === textBaseline && (line.topOffset -= (lineHeight - actualHeightWithBuf) / 2)),
81
+ "alphabetic" === textBaseline) {
82
+ const ratio = lineHeight / (line.ascent + line.descent);
83
+ line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 * ratio + origin[1];
84
+ }
85
+ }
86
+ return origin[1] += lineHeight, line;
82
87
  }
83
88
  }
84
89
  //# sourceMappingURL=layout.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/contributions/textMeasure/layout.ts"],"names":[],"mappings":"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","file":"layout.js","sourcesContent":["import type { vec2 } from '@visactor/vutils';\nimport type { ITextMeasure, TextOptionsType } from '../../../interface/text';\nimport type { TextLayoutBBox, LayoutItemType, LayoutType, TextAlignType, TextBaselineType } from '../../../interface';\nimport { MeasureModeEnum } from '../../../interface';\n\nexport class CanvasTextLayout {\n private fontFamily: string;\n private textOptions: TextOptionsType;\n private textMeasure: ITextMeasure;\n\n constructor(fontFamily: string, options: TextOptionsType, textMeasure: ITextMeasure) {\n this.fontFamily = fontFamily;\n this.textOptions = options;\n this.textMeasure = textMeasure;\n }\n\n /**\n * 布局外部的盒子,盒子的alphabetic属性模拟文字的效果\n * @param bbox\n * @param textAlign\n * @param textBaseline\n * @returns\n */\n LayoutBBox(\n bbox: TextLayoutBBox,\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n linesLayout: LayoutItemType[]\n ): TextLayoutBBox {\n if (textAlign === 'left' || textAlign === 'start') {\n bbox.xOffset = 0;\n } else if (textAlign === 'center') {\n bbox.xOffset = bbox.width / -2;\n } else if (textAlign === 'right' || textAlign === 'end') {\n bbox.xOffset = -bbox.width;\n } else {\n throw new Error('非法的textAlign');\n }\n\n if (textBaseline === 'top') {\n bbox.yOffset = 0;\n } else if (textBaseline === 'middle') {\n bbox.yOffset = bbox.height / -2;\n } else if (textBaseline === 'alphabetic') {\n // 如果仅有一行,要保证和直接使用canvas绘制的textBaseline一致\n let percent = 0.79;\n if (linesLayout.length === 1) {\n const lineInfo = linesLayout[0];\n percent = lineInfo.ascent / (lineInfo.ascent + lineInfo.descent);\n }\n bbox.yOffset = bbox.height * -percent;\n } else {\n bbox.yOffset = -bbox.height;\n }\n\n return bbox;\n }\n\n /**\n * 给定拆分好的每行字符串进行布局,如果传入lineWidth,那么后面的字符就拆分\n * @param lines\n * @param lineWidth\n */\n GetLayoutByLines(\n lines: (string | number)[],\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number,\n suffix: string = '',\n wordBreak: boolean,\n params?: {\n lineWidth?: number;\n suffixPosition?: 'start' | 'end' | 'middle';\n measureMode?: MeasureModeEnum;\n }\n ): LayoutType {\n const { lineWidth, suffixPosition = 'end', measureMode = MeasureModeEnum.actualBounding } = params ?? {};\n lines = lines.map(l => l.toString()) as string[];\n const linesLayout: LayoutItemType[] = [];\n // bbox高度可能大于totalHeight\n const bboxWH: vec2 = [0, 0];\n if (typeof lineWidth === 'number' && lineWidth !== Infinity) {\n // 直接使用lineWidth,并拆分字符串\n let width: number;\n for (let i = 0, len = lines.length; i < len; i++) {\n const metrics = this.textMeasure.measureTextPixelADscentAndWidth(\n lines[i] as string,\n this.textOptions,\n measureMode\n );\n width = Math.min(metrics.width, lineWidth);\n linesLayout.push({\n str:\n metrics.width <= lineWidth\n ? lines[i].toString()\n : this.textMeasure.clipTextWithSuffix(\n lines[i] as string,\n this.textOptions,\n width,\n suffix,\n wordBreak,\n suffixPosition\n ).str,\n width,\n ascent: metrics.ascent,\n descent: metrics.descent\n });\n }\n bboxWH[0] = lineWidth;\n } else {\n // 使用所有行中最长的作为lineWidth\n let _lineWidth = 0;\n let width: number;\n let text: string;\n for (let i = 0, len = lines.length; i < len; i++) {\n text = lines[i] as string;\n const metrics = this.textMeasure.measureTextPixelADscentAndWidth(\n lines[i] as string,\n this.textOptions,\n measureMode\n );\n width = metrics.width;\n _lineWidth = Math.max(_lineWidth, width);\n linesLayout.push({ str: text, width, ascent: metrics.ascent, descent: metrics.descent });\n }\n bboxWH[0] = _lineWidth;\n }\n bboxWH[1] = linesLayout.length * lineHeight;\n\n bboxWH[0] = linesLayout.reduce((a, b) => Math.max(a, b.width), 0);\n\n const bbox: TextLayoutBBox = {\n xOffset: 0,\n yOffset: 0,\n width: bboxWH[0],\n height: bboxWH[1]\n };\n\n this.LayoutBBox(bbox, textAlign, textBaseline, linesLayout);\n\n return this.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);\n }\n\n /**\n * 给定了bbox,使用拆分好的每行字符串进行布局\n * @param bbox\n * @param lines\n * @param textAlign\n * @param textBaseline\n * @param lineHeight\n * @returns\n */\n layoutWithBBox(\n bbox: TextLayoutBBox,\n lines: LayoutItemType[],\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number\n ): LayoutType {\n const origin: vec2 = [0, 0];\n const totalLineHeight = lines.length * lineHeight; // 总高度\n // origin在y方向需要初始化,然后递增即可\n if (textBaseline === 'top') {\n // origin[1] = 0;\n } else if (textBaseline === 'middle') {\n origin[1] = (bbox.height - totalLineHeight) / 2;\n } else if (textBaseline === 'bottom') {\n origin[1] = bbox.height - totalLineHeight;\n }\n\n for (let i = 0; i < lines.length; i++) {\n this.lineOffset(bbox, lines[i], textAlign, textBaseline, lineHeight, origin);\n }\n\n return {\n bbox,\n lines,\n fontFamily: this.fontFamily,\n fontSize: this.textOptions.fontSize,\n fontWeight: this.textOptions.fontWeight,\n lineHeight,\n textAlign,\n textBaseline\n };\n }\n\n /**\n * 计算line在bbox中的位置,需要配合layoutWithBBox使用\n * @param bbox\n * @param line\n * @param textAlign\n * @param textBaseline\n * @param lineHeight\n * @param origin 这个line的左上角位置,会复用并修改\n */\n private lineOffset(\n bbox: TextLayoutBBox,\n line: LayoutItemType,\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number,\n origin: vec2\n ): LayoutItemType {\n if (textAlign === 'left' || textAlign === 'start') {\n line.leftOffset = 0;\n } else if (textAlign === 'center') {\n line.leftOffset = (bbox.width - line.width) / 2;\n } else if (textAlign === 'right' || textAlign === 'end') {\n line.leftOffset = bbox.width - line.width;\n }\n\n line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1];\n\n const actualHeight = line.ascent + line.descent;\n const buf = 0;\n const actualHeightWithBuf = actualHeight + buf;\n if (actualHeightWithBuf < lineHeight - buf) {\n if (textBaseline === 'bottom') {\n line.topOffset += (lineHeight - actualHeightWithBuf) / 2;\n } else if (textBaseline === 'top') {\n line.topOffset -= (lineHeight - actualHeightWithBuf) / 2;\n }\n }\n origin[1] += lineHeight;\n\n return line;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/core/contributions/textMeasure/layout.ts"],"names":[],"mappings":"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","file":"layout.js","sourcesContent":["import type { vec2 } from '@visactor/vutils';\nimport type { ITextMeasure, TextOptionsType } from '../../../interface/text';\nimport type { TextLayoutBBox, LayoutItemType, LayoutType, TextAlignType, TextBaselineType } from '../../../interface';\nimport { MeasureModeEnum } from '../../../interface';\n\nexport class CanvasTextLayout {\n private fontFamily: string;\n private textOptions: TextOptionsType;\n private textMeasure: ITextMeasure;\n\n constructor(fontFamily: string, options: TextOptionsType, textMeasure: ITextMeasure) {\n this.fontFamily = fontFamily;\n this.textOptions = options;\n this.textMeasure = textMeasure;\n }\n\n /**\n * 布局外部的盒子,盒子的alphabetic属性模拟文字的效果\n * @param bbox\n * @param textAlign\n * @param textBaseline\n * @returns\n */\n LayoutBBox(\n bbox: TextLayoutBBox,\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n linesLayout: LayoutItemType[]\n ): TextLayoutBBox {\n if (textAlign === 'left' || textAlign === 'start') {\n bbox.xOffset = 0;\n } else if (textAlign === 'center') {\n bbox.xOffset = bbox.width / -2;\n } else if (textAlign === 'right' || textAlign === 'end') {\n bbox.xOffset = -bbox.width;\n } else {\n bbox.xOffset = 0;\n }\n\n if (textBaseline === 'top') {\n bbox.yOffset = 0;\n } else if (textBaseline === 'middle') {\n bbox.yOffset = bbox.height / -2;\n } else if (textBaseline === 'alphabetic') {\n // 如果仅有一行,要保证和直接使用canvas绘制的textBaseline一致\n let percent = 0.79;\n if (linesLayout.length === 1) {\n const lineInfo = linesLayout[0];\n percent = lineInfo.ascent / (lineInfo.ascent + lineInfo.descent);\n }\n bbox.yOffset = bbox.height * -percent;\n } else {\n bbox.yOffset = -bbox.height;\n }\n\n return bbox;\n }\n\n /**\n * 给定拆分好的每行字符串进行布局,如果传入lineWidth,那么后面的字符就拆分\n * @param lines\n * @param lineWidth\n */\n GetLayoutByLines(\n lines: (string | number)[],\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number,\n suffix: string = '',\n wordBreak: boolean,\n params?: {\n lineWidth?: number;\n suffixPosition?: 'start' | 'end' | 'middle';\n measureMode?: MeasureModeEnum;\n keepCenterInLine?: boolean;\n }\n ): LayoutType {\n const {\n lineWidth,\n suffixPosition = 'end',\n measureMode = MeasureModeEnum.actualBounding,\n keepCenterInLine = false\n } = params ?? {};\n lines = lines.map(l => l.toString()) as string[];\n const linesLayout: LayoutItemType[] = [];\n // bbox高度可能大于totalHeight\n const bboxWH: vec2 = [0, 0];\n if (typeof lineWidth === 'number' && lineWidth !== Infinity) {\n // 直接使用lineWidth,并拆分字符串\n let width: number;\n for (let i = 0, len = lines.length; i < len; i++) {\n const metrics = this.textMeasure.measureTextPixelADscentAndWidth(\n lines[i] as string,\n this.textOptions,\n measureMode\n );\n width = Math.min(metrics.width, lineWidth);\n linesLayout.push({\n str:\n metrics.width <= lineWidth\n ? lines[i].toString()\n : this.textMeasure.clipTextWithSuffix(\n lines[i] as string,\n this.textOptions,\n width,\n suffix,\n wordBreak,\n suffixPosition\n ).str,\n width,\n ascent: metrics.ascent,\n descent: metrics.descent,\n keepCenterInLine\n });\n }\n bboxWH[0] = lineWidth;\n } else {\n // 使用所有行中最长的作为lineWidth\n let _lineWidth = 0;\n let width: number;\n let text: string;\n for (let i = 0, len = lines.length; i < len; i++) {\n text = lines[i] as string;\n const metrics = this.textMeasure.measureTextPixelADscentAndWidth(\n lines[i] as string,\n this.textOptions,\n measureMode\n );\n width = metrics.width;\n _lineWidth = Math.max(_lineWidth, width);\n linesLayout.push({ str: text, width, ascent: metrics.ascent, descent: metrics.descent, keepCenterInLine });\n }\n bboxWH[0] = _lineWidth;\n }\n bboxWH[1] = linesLayout.length * lineHeight;\n\n bboxWH[0] = linesLayout.reduce((a, b) => Math.max(a, b.width), 0);\n\n const bbox: TextLayoutBBox = {\n xOffset: 0,\n yOffset: 0,\n width: bboxWH[0],\n height: bboxWH[1]\n };\n\n this.LayoutBBox(bbox, textAlign, textBaseline, linesLayout);\n\n return this.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);\n }\n\n /**\n * 给定了bbox,使用拆分好的每行字符串进行布局\n * @param bbox\n * @param lines\n * @param textAlign\n * @param textBaseline\n * @param lineHeight\n * @returns\n */\n layoutWithBBox(\n bbox: TextLayoutBBox,\n lines: LayoutItemType[],\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number\n ): LayoutType {\n const origin: vec2 = [0, 0];\n const totalLineHeight = lines.length * lineHeight; // 总高度\n // origin在y方向需要初始化,然后递增即可\n if (textBaseline === 'top') {\n // origin[1] = 0;\n } else if (textBaseline === 'middle') {\n origin[1] = (bbox.height - totalLineHeight) / 2;\n } else if (textBaseline === 'bottom') {\n origin[1] = bbox.height - totalLineHeight;\n }\n\n for (let i = 0; i < lines.length; i++) {\n this.lineOffset(bbox, lines[i], textAlign, textBaseline, lineHeight, origin);\n }\n\n return {\n bbox,\n lines,\n fontFamily: this.fontFamily,\n fontSize: this.textOptions.fontSize,\n fontWeight: this.textOptions.fontWeight,\n lineHeight,\n textAlign,\n textBaseline\n };\n }\n\n /**\n * 计算line在bbox中的位置,需要配合layoutWithBBox使用\n * @param bbox\n * @param line\n * @param textAlign\n * @param textBaseline\n * @param lineHeight\n * @param origin 这个line的左上角位置,会复用并修改\n */\n private lineOffset(\n bbox: TextLayoutBBox,\n line: LayoutItemType,\n textAlign: TextAlignType,\n textBaseline: TextBaselineType,\n lineHeight: number,\n origin: vec2\n ): LayoutItemType {\n if (textAlign === 'left' || textAlign === 'start') {\n line.leftOffset = 0;\n } else if (textAlign === 'center') {\n line.leftOffset = (bbox.width - line.width) / 2;\n } else if (textAlign === 'right' || textAlign === 'end') {\n line.leftOffset = bbox.width - line.width;\n }\n\n line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1];\n\n // 在行内进行偏移\n if (!line.keepCenterInLine) {\n const actualHeight = line.ascent + line.descent;\n const buf = 0;\n const actualHeightWithBuf = actualHeight + buf;\n if (actualHeightWithBuf < lineHeight - buf) {\n if (textBaseline === 'bottom') {\n line.topOffset += (lineHeight - actualHeightWithBuf) / 2;\n } else if (textBaseline === 'top') {\n line.topOffset -= (lineHeight - actualHeightWithBuf) / 2;\n }\n }\n if (textBaseline === 'alphabetic') {\n const fontBoundingHeight = line.ascent + line.descent;\n const ratio = lineHeight / fontBoundingHeight;\n line.topOffset = lineHeight / 2 + ((line.ascent - line.descent) / 2) * ratio + origin[1];\n }\n }\n\n origin[1] += lineHeight;\n\n return line;\n }\n}\n"]}
@@ -87,7 +87,8 @@ export const DefaultTextStyle = {
87
87
  underlineDash: [],
88
88
  underlineOffset: 0,
89
89
  disableAutoClipedPoptip: void 0,
90
- measureMode: MeasureModeEnum.fontBounding
90
+ measureMode: MeasureModeEnum.fontBounding,
91
+ keepCenterInLine: !1
91
92
  };
92
93
 
93
94
  export const DefaultPickStyle = {