@visactor/vrender-core 0.21.0-alpha.3 → 0.21.0-alpha.4

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 (118) hide show
  1. package/cjs/common/3d-interceptor.js +1 -2
  2. package/cjs/common/bounds-context.js +2 -1
  3. package/cjs/common/morphing-utils.js +1 -1
  4. package/cjs/common/path-svg.js +1 -1
  5. package/cjs/common/polygon.js +2 -2
  6. package/cjs/common/rect-utils.js +1 -1
  7. package/cjs/common/render-area.js +1 -1
  8. package/cjs/common/render-command-list.js +1 -2
  9. package/cjs/common/render-curve.js +1 -1
  10. package/cjs/common/render-utils.js +1 -1
  11. package/cjs/common/seg-context.js +1 -1
  12. package/cjs/common/simplify.js +1 -1
  13. package/cjs/common/sort.js +1 -1
  14. package/cjs/common/split-path.js +1 -1
  15. package/cjs/common/store.js +1 -1
  16. package/cjs/common/text.js.map +1 -1
  17. package/cjs/core/application.js +2 -1
  18. package/cjs/core/camera.js +1 -1
  19. package/cjs/core/constants.js +1 -1
  20. package/cjs/core/contributions/textMeasure/AtextMeasure.d.ts +4 -55
  21. package/cjs/core/contributions/textMeasure/AtextMeasure.js +13 -92
  22. package/cjs/core/contributions/textMeasure/AtextMeasure.js.map +1 -1
  23. package/cjs/core/contributions/textMeasure/layout.d.ts +1 -0
  24. package/cjs/core/contributions/textMeasure/layout.js +30 -20
  25. package/cjs/core/contributions/textMeasure/layout.js.map +1 -1
  26. package/cjs/core/core-modules.js +1 -1
  27. package/cjs/core/global-module.js +2 -0
  28. package/cjs/core/global.js +1 -1
  29. package/cjs/core/graphic-utils.js +1 -1
  30. package/cjs/core/index.js +1 -1
  31. package/cjs/core/layer-service.js +1 -1
  32. package/cjs/core/layer.js +1 -1
  33. package/cjs/core/light.js +1 -1
  34. package/cjs/core/stage.js +1 -1
  35. package/cjs/core/window.js +1 -1
  36. package/cjs/graphic/config.js +0 -1
  37. package/cjs/graphic/config.js.map +1 -1
  38. package/cjs/graphic/text.d.ts +11 -10
  39. package/cjs/graphic/text.js +174 -91
  40. package/cjs/graphic/text.js.map +1 -1
  41. package/cjs/graphic/wrap-text.js +4 -12
  42. package/cjs/graphic/wrap-text.js.map +1 -1
  43. package/cjs/interface/graphic/text.d.ts +3 -3
  44. package/cjs/interface/graphic/text.js.map +1 -1
  45. package/cjs/interface/text.d.ts +1 -6
  46. package/cjs/interface/text.js.map +1 -1
  47. package/cjs/render/contributions/render/contributions/image-contribution-render.d.ts +1 -1
  48. package/cjs/render/contributions/render/contributions/image-contribution-render.js +3 -2
  49. package/cjs/render/contributions/render/contributions/image-contribution-render.js.map +1 -1
  50. package/cjs/render/contributions/render/image-render.js +6 -4
  51. package/cjs/render/contributions/render/image-render.js.map +1 -1
  52. package/cjs/render/contributions/render/text-render.js +23 -1
  53. package/cjs/render/contributions/render/text-render.js.map +1 -1
  54. package/cjs/resource-loader/loader.js +1 -1
  55. package/cjs/resource-loader/loader.js.map +1 -1
  56. package/dist/index.es.js +431 -340
  57. package/es/common/3d-interceptor.js +1 -2
  58. package/es/common/bounds-context.js +2 -1
  59. package/es/common/morphing-utils.js +1 -1
  60. package/es/common/path-svg.js +1 -1
  61. package/es/common/polygon.js +1 -1
  62. package/es/common/rect-utils.js +1 -1
  63. package/es/common/render-area.js +1 -1
  64. package/es/common/render-command-list.js +1 -2
  65. package/es/common/render-curve.js +1 -1
  66. package/es/common/render-utils.js +1 -1
  67. package/es/common/seg-context.js +1 -1
  68. package/es/common/simplify.js +1 -1
  69. package/es/common/sort.js +1 -1
  70. package/es/common/split-path.js +1 -1
  71. package/es/common/store.js +1 -1
  72. package/es/common/text.js.map +1 -1
  73. package/es/core/application.js +2 -1
  74. package/es/core/camera.js +1 -1
  75. package/es/core/constants.js +1 -1
  76. package/es/core/contributions/textMeasure/AtextMeasure.d.ts +4 -55
  77. package/es/core/contributions/textMeasure/AtextMeasure.js +13 -92
  78. package/es/core/contributions/textMeasure/AtextMeasure.js.map +1 -1
  79. package/es/core/contributions/textMeasure/layout.d.ts +1 -0
  80. package/es/core/contributions/textMeasure/layout.js +30 -20
  81. package/es/core/contributions/textMeasure/layout.js.map +1 -1
  82. package/es/core/core-modules.js +1 -1
  83. package/es/core/global-module.js +2 -0
  84. package/es/core/global.js +1 -1
  85. package/es/core/graphic-utils.js +1 -1
  86. package/es/core/index.js +1 -1
  87. package/es/core/layer-service.js +1 -1
  88. package/es/core/layer.js +1 -1
  89. package/es/core/light.js +1 -1
  90. package/es/core/stage.js +1 -1
  91. package/es/core/window.js +1 -1
  92. package/es/graphic/config.js +0 -1
  93. package/es/graphic/config.js.map +1 -1
  94. package/es/graphic/text.d.ts +11 -10
  95. package/es/graphic/text.js +169 -90
  96. package/es/graphic/text.js.map +1 -1
  97. package/es/graphic/wrap-text.js +4 -12
  98. package/es/graphic/wrap-text.js.map +1 -1
  99. package/es/interface/graphic/text.d.ts +3 -3
  100. package/es/interface/graphic/text.js.map +1 -1
  101. package/es/interface/text.d.ts +1 -6
  102. package/es/interface/text.js.map +1 -1
  103. package/es/render/contributions/render/contributions/image-contribution-render.d.ts +1 -1
  104. package/es/render/contributions/render/contributions/image-contribution-render.js +3 -2
  105. package/es/render/contributions/render/contributions/image-contribution-render.js.map +1 -1
  106. package/es/render/contributions/render/image-render.js +6 -4
  107. package/es/render/contributions/render/image-render.js.map +1 -1
  108. package/es/render/contributions/render/text-render.js +23 -1
  109. package/es/render/contributions/render/text-render.js.map +1 -1
  110. package/es/resource-loader/loader.js +1 -1
  111. package/es/resource-loader/loader.js.map +1 -1
  112. package/package.json +2 -2
  113. package/cjs/graphic/text2.d.ts +0 -81
  114. package/cjs/graphic/text2.js +0 -288
  115. package/cjs/graphic/text2.js.map +0 -1
  116. package/es/graphic/text2.d.ts +0 -81
  117. package/es/graphic/text2.js +0 -293
  118. package/es/graphic/text2.js.map +0 -1
@@ -47,5 +47,4 @@ const vutils_1 = require("@visactor/vutils"), constants_1 = require("../graphic/
47
47
  return result;
48
48
  };
49
49
 
50
- exports.draw3dItem = draw3dItem;
51
- //# sourceMappingURL=3d-interceptor.js.map
50
+ exports.draw3dItem = draw3dItem;
@@ -56,4 +56,5 @@ class BoundsContext {
56
56
  release(...params) {}
57
57
  }
58
58
 
59
- exports.BoundsContext = BoundsContext;
59
+ exports.BoundsContext = BoundsContext;
60
+ //# sourceMappingURL=bounds-context.js.map
@@ -292,4 +292,4 @@ function bezierCurversToPath(bezierCurves) {
292
292
 
293
293
  exports.pathToBezierCurves = pathToBezierCurves, exports.applyTransformOnBezierCurves = applyTransformOnBezierCurves,
294
294
  exports.bezierCurversToPath = bezierCurversToPath;
295
- //# sourceMappingURL=morphing-utils.js.map
295
+ //# sourceMappingURL=morphing-utils.js.map
@@ -61,4 +61,4 @@ exports.enumCommandMap = {
61
61
  Q: 7,
62
62
  R: 8
63
63
  }, exports.parseSvgPath = parseSvgPath;
64
- //# sourceMappingURL=path-svg.js.map
64
+ //# sourceMappingURL=path-svg.js.map
@@ -39,8 +39,8 @@ function getProportionPoint(point, segment, length, dx, dy) {
39
39
  };
40
40
  }
41
41
 
42
+ //# sourceMappingURL=polygon.js.map
42
43
  Object.defineProperty(exports, "__esModule", {
43
44
  value: !0
44
45
  }), exports.drawRoundedPolygon = exports.drawPolygon = void 0, exports.drawPolygon = drawPolygon,
45
- exports.drawRoundedPolygon = drawRoundedPolygon;
46
- //# sourceMappingURL=polygon.js.map
46
+ exports.drawRoundedPolygon = drawRoundedPolygon;
@@ -24,4 +24,4 @@ const vutils_1 = require("@visactor/vutils"), normalizeRectAttributes = attribut
24
24
  };
25
25
 
26
26
  exports.normalizeRectAttributes = normalizeRectAttributes;
27
- //# sourceMappingURL=rect-utils.js.map
27
+ //# sourceMappingURL=rect-utils.js.map
@@ -121,5 +121,5 @@ function drawAreaBlock(path, topList, bottomList, params) {
121
121
  path.closePath();
122
122
  }
123
123
 
124
- exports.drawAreaSegments = drawAreaSegments;
125
124
  //# sourceMappingURL=render-area.js.map
125
+ exports.drawAreaSegments = drawAreaSegments;
@@ -13,5 +13,4 @@ function renderCommandList(commandList, context, x = 0, y = 0, sx = 1, sy = 1, z
13
13
  }
14
14
  }
15
15
 
16
- exports.renderCommandList = renderCommandList;
17
- //# sourceMappingURL=render-command-list.js.map
16
+ exports.renderCommandList = renderCommandList;
@@ -99,4 +99,4 @@ function drawIncrementalAreaSegments(path, lastSeg, segments, params) {
99
99
 
100
100
  exports.drawSegments = drawSegments, exports.drawIncrementalSegments = drawIncrementalSegments,
101
101
  exports.drawIncrementalAreaSegments = drawIncrementalAreaSegments;
102
- //# sourceMappingURL=render-curve.js.map
102
+ //# sourceMappingURL=render-curve.js.map
@@ -19,4 +19,4 @@ function drawSegItem(ctx, curve, endPercent, params) {
19
19
  }
20
20
 
21
21
  exports.drawSegItem = drawSegItem;
22
- //# sourceMappingURL=render-utils.js.map
22
+ //# sourceMappingURL=render-utils.js.map
@@ -95,4 +95,4 @@ class ReflectSegContext extends SegContext {
95
95
  }
96
96
 
97
97
  exports.ReflectSegContext = ReflectSegContext;
98
- //# sourceMappingURL=seg-context.js.map
98
+ //# sourceMappingURL=seg-context.js.map
@@ -36,4 +36,4 @@ function flatten_simplify(points, tolerance, highestQuality) {
36
36
  Object.defineProperty(exports, "__esModule", {
37
37
  value: !0
38
38
  }), exports.flatten_simplify = void 0, exports.flatten_simplify = flatten_simplify;
39
- //# sourceMappingURL=simplify.js.map
39
+ //# sourceMappingURL=simplify.js.map
@@ -101,4 +101,4 @@ Object.defineProperty(exports, "__esModule", {
101
101
  value: !0
102
102
  }), exports.findNextGraphic = exports.foreachAsync = exports.foreach = void 0, exports.foreach = foreach,
103
103
  exports.foreachAsync = foreachAsync, exports.findNextGraphic = findNextGraphic;
104
- //# sourceMappingURL=sort.js.map
104
+ //# sourceMappingURL=sort.js.map
@@ -269,4 +269,4 @@ const splitPath = (path, count) => {
269
269
  };
270
270
 
271
271
  exports.splitPath = splitPath;
272
- //# sourceMappingURL=split-path.js.map
272
+ //# sourceMappingURL=split-path.js.map
@@ -1,2 +1,2 @@
1
1
  class StageStore {}
2
- //# sourceMappingURL=store.js.map
2
+ //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/text.ts"],"names":[],"mappings":"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","file":"text.js","sourcesContent":["// 存放一些公共方法,公共配置\n\nimport { isNil, isString, isValid, lowerCamelCaseToMiddle } from '@visactor/vutils';\nimport type { IText, ITextGraphicAttribute, TextAlignType, TextBaselineType } from '../interface';\n\n// TODO: 更好的方案\n/**\n * 用于绘制的时候偏移\n * 经验值,来源于 https://github.com/vega/vega/blob/b45cf431cd6c0d0c0e1567f087f9b3b55bc236fa/packages/vega-scenegraph/src/util/text.js\n * @param baseline\n * @param h\n * @returns\n */\nexport function textDrawOffsetY(baseline: TextBaselineType, h: number): number {\n const offset =\n baseline === 'top'\n ? Math.ceil(0.79 * h)\n : baseline === 'middle'\n ? Math.round(0.3 * h)\n : baseline === 'bottom'\n ? Math.round(-0.21 * h)\n : 0;\n return offset;\n}\n\n/**\n * 用于绘制的时候偏移\n * @param textAlign\n * @param width\n * @returns\n */\nexport function textDrawOffsetX(textAlign: TextAlignType, width: number): number {\n if (textAlign === 'end' || textAlign === 'right') {\n return -width;\n } else if (textAlign === 'center') {\n return -width / 2;\n }\n return 0;\n}\n\n/**\n * 用于计算布局的偏移,相对于xy的偏移\n * 经验值,来源于 https://github.com/vega/vega/blob/b45cf431cd6c0d0c0e1567f087f9b3b55bc236fa/packages/vega-scenegraph/src/util/text.js\n * @param baseline\n * @param lineHeight\n * @returns\n */\nexport function textLayoutOffsetY(\n baseline: TextBaselineType,\n lineHeight: number,\n fontSize: number,\n buf: number = 0\n): number {\n if (baseline === 'middle') {\n return -lineHeight / 2;\n }\n if (baseline === 'top') {\n return 0;\n }\n if (baseline === 'bottom') {\n return buf - lineHeight;\n }\n if (!baseline || baseline === 'alphabetic') {\n if (!fontSize) {\n fontSize = lineHeight;\n }\n return -(lineHeight - fontSize) / 2 - 0.79 * fontSize;\n }\n return 0;\n}\n\nexport function textAttributesToStyle(attrs: ITextGraphicAttribute) {\n const stringTypes = ['textAlign', 'fontFamily', 'fontVariant', 'fontStyle', 'fontWeight'];\n const pxKeys = ['fontSize', 'lineHeight'];\n const style: any = {};\n const parsePxValue = (value: string | number) => {\n return /^\\d+(\\.\\d+)?$/.test(`${value}`) ? `${value}px` : `${value}`;\n };\n\n stringTypes.forEach(key => {\n if ((attrs as any)[key]) {\n style[lowerCamelCaseToMiddle(key)] = (attrs as any)[key];\n }\n });\n\n pxKeys.forEach(key => {\n const styleKey = lowerCamelCaseToMiddle(key);\n if (!isNil((attrs as any)[key])) {\n style[styleKey] = parsePxValue((attrs as any)[key]);\n }\n });\n\n if (isValid(attrs.maxLineWidth)) {\n style['max-width'] = parsePxValue(attrs.maxLineWidth);\n }\n\n if (attrs.underline) {\n style['text-decoration'] = 'underline';\n } else if (attrs.lineThrough) {\n style['text-decoration'] = 'line-through';\n }\n\n if (attrs.fill) {\n if (isString(attrs.fill)) {\n style.color = attrs.fill;\n }\n }\n\n return style;\n}\n"]}
1
+ {"version":3,"sources":["../src/common/text.ts"],"names":[],"mappings":"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","file":"text.js","sourcesContent":["// 存放一些公共方法,公共配置\n\nimport { isNil, isString, isValid, lowerCamelCaseToMiddle } from '@visactor/vutils';\nimport type { ITextGraphicAttribute, TextAlignType, TextBaselineType } from '../interface';\n\n// TODO: 更好的方案\n/**\n * 用于绘制的时候偏移\n * 经验值,来源于 https://github.com/vega/vega/blob/b45cf431cd6c0d0c0e1567f087f9b3b55bc236fa/packages/vega-scenegraph/src/util/text.js\n * @param baseline\n * @param h\n * @returns\n */\nexport function textDrawOffsetY(baseline: TextBaselineType, h: number): number {\n const offset =\n baseline === 'top'\n ? Math.ceil(0.79 * h)\n : baseline === 'middle'\n ? Math.round(0.3 * h)\n : baseline === 'bottom'\n ? Math.round(-0.21 * h)\n : 0;\n return offset;\n}\n\n/**\n * 用于绘制的时候偏移\n * @param textAlign\n * @param width\n * @returns\n */\nexport function textDrawOffsetX(textAlign: TextAlignType, width: number): number {\n if (textAlign === 'end' || textAlign === 'right') {\n return -width;\n } else if (textAlign === 'center') {\n return -width / 2;\n }\n return 0;\n}\n\n/**\n * 用于计算布局的偏移\n * 经验值,来源于 https://github.com/vega/vega/blob/b45cf431cd6c0d0c0e1567f087f9b3b55bc236fa/packages/vega-scenegraph/src/util/text.js\n * @param baseline\n * @param lineHeight\n * @returns\n */\nexport function textLayoutOffsetY(\n baseline: TextBaselineType,\n lineHeight: number,\n fontSize: number,\n buf: number = 0\n): number {\n if (baseline === 'middle') {\n return -lineHeight / 2;\n }\n if (baseline === 'top') {\n return 0;\n }\n if (baseline === 'bottom') {\n return buf - lineHeight;\n }\n if (!baseline || baseline === 'alphabetic') {\n if (!fontSize) {\n fontSize = lineHeight;\n }\n return -(lineHeight - fontSize) / 2 - 0.79 * fontSize;\n }\n return 0;\n}\n\nexport function textAttributesToStyle(attrs: ITextGraphicAttribute) {\n const stringTypes = ['textAlign', 'fontFamily', 'fontVariant', 'fontStyle', 'fontWeight'];\n const pxKeys = ['fontSize', 'lineHeight'];\n const style: any = {};\n const parsePxValue = (value: string | number) => {\n return /^\\d+(\\.\\d+)?$/.test(`${value}`) ? `${value}px` : `${value}`;\n };\n\n stringTypes.forEach(key => {\n if (attrs[key]) {\n style[lowerCamelCaseToMiddle(key)] = attrs[key];\n }\n });\n\n pxKeys.forEach(key => {\n const styleKey = lowerCamelCaseToMiddle(key);\n if (!isNil(attrs[key])) {\n style[styleKey] = parsePxValue(attrs[key]);\n }\n });\n\n if (isValid(attrs.maxLineWidth)) {\n style['max-width'] = parsePxValue(attrs.maxLineWidth);\n }\n\n if (attrs.underline) {\n style['text-decoration'] = 'underline';\n } else if (attrs.lineThrough) {\n style['text-decoration'] = 'line-through';\n }\n\n if (attrs.fill) {\n if (isString(attrs.fill)) {\n style.color = attrs.fill;\n }\n }\n\n return style;\n}\n"]}
@@ -2,4 +2,5 @@
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: !0
5
- }), exports.ApplicationContribution = void 0, exports.ApplicationContribution = Symbol("ApplicationContribution");
5
+ }), exports.ApplicationContribution = void 0, exports.ApplicationContribution = Symbol("ApplicationContribution");
6
+ //# sourceMappingURL=application.js.map
@@ -71,4 +71,4 @@ const registerOrthoCamera = () => {
71
71
  };
72
72
 
73
73
  exports.registerOrthoCamera = registerOrthoCamera;
74
- //# sourceMappingURL=camera.js.map
74
+ //# sourceMappingURL=camera.js.map
@@ -7,4 +7,4 @@ exports.TransformUtil = Symbol.for("TransformUtil"), exports.GraphicUtil = Symbo
7
7
  exports.LayerService = Symbol.for("LayerService"), exports.StaticLayerHandlerContribution = Symbol.for("StaticLayerHandlerContribution"),
8
8
  exports.DynamicLayerHandlerContribution = Symbol.for("DynamicLayerHandlerContribution"),
9
9
  exports.VirtualLayerHandlerContribution = Symbol.for("VirtualLayerHandlerContribution");
10
- //# sourceMappingURL=constants.js.map
10
+ //# sourceMappingURL=constants.js.map
@@ -6,64 +6,13 @@ export declare class ATextMeasure implements ITextMeasure {
6
6
  protected canvas?: ICanvas;
7
7
  protected context?: IContext2d | null;
8
8
  configure(service: IGraphicUtil, env: EnvType): void;
9
- protected _measureTextWithoutAlignBaseline(text: string, options: TextOptionsType, compatible?: boolean): {
10
- width: number;
11
- } | TextMetrics;
12
- protected _measureTextWithAlignBaseline(text: string, options: TextOptionsType, compatible?: boolean): {
13
- width: number;
14
- } | TextMetrics;
15
- protected compatibleMetrics(metrics: TextMetrics | {
16
- width: number;
17
- }, options: TextOptionsType): TextMetrics | {
18
- width: number;
19
- };
20
- protected estimate(text: string, { fontSize }: TextOptionsType): {
9
+ measureTextWidth(text: string, options: TextOptionsType): number;
10
+ estimate(text: string, { fontSize }: TextOptionsType): {
21
11
  width: number;
22
12
  height: number;
23
13
  };
24
- measureTextWidth(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
25
- width: number;
26
- }): number;
27
- measureTextBoundsWidth(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
28
- width: number;
29
- }): number;
30
- measureTextBoundsLeftRight(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
31
- width: number;
32
- }): {
33
- left: any;
34
- right: any;
35
- };
36
- measureTextPixelHeight(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
37
- width: number;
38
- }): number;
39
- measureTextPixelADscent(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
40
- width: number;
41
- }): {
42
- ascent: any;
43
- descent: any;
44
- };
45
- measureTextBoundHieght(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
46
- width: number;
47
- }): number;
48
- measureTextBoundADscent(text: string, options: TextOptionsType, textMeasure?: TextMetrics | {
49
- width: number;
50
- }): {
51
- ascent: any;
52
- descent: any;
53
- };
54
- protected measureTextBoundADscentEstimate(options: TextOptionsType): {
55
- ascent: number;
56
- descent: number;
57
- };
58
- protected measureTextBoundLeftRightEstimate(options: TextOptionsType): {
59
- left: number;
60
- right: number;
61
- };
62
- measureTextPixelADscentAndWidth(text: string, options: TextOptionsType): {
63
- width: number;
64
- ascent: number;
65
- descent: number;
66
- };
14
+ measureTextPixelHeight(text: string, options: TextOptionsType): number;
15
+ measureTextBoundHieght(text: string, options: TextOptionsType): number;
67
16
  measureText(text: string, options: TextOptionsType): TextMetrics | {
68
17
  width: number;
69
18
  };
@@ -16,27 +16,10 @@ let ATextMeasure = class {
16
16
  configure(service, env) {
17
17
  this.canvas = service.canvas, this.context = service.context, service.bindTextMeasure(this);
18
18
  }
19
- _measureTextWithoutAlignBaseline(text, options, compatible) {
19
+ measureTextWidth(text, options) {
20
+ if (!this.context) return this.estimate(text, options).width;
20
21
  this.context.setTextStyleWithoutAlignBaseline(options);
21
- const metrics = this.context.measureText(text);
22
- return compatible ? this.compatibleMetrics(metrics, options) : metrics;
23
- }
24
- _measureTextWithAlignBaseline(text, options, compatible) {
25
- this.context.setTextStyle(options);
26
- const metrics = this.context.measureText(text);
27
- return compatible ? this.compatibleMetrics(metrics, options) : metrics;
28
- }
29
- compatibleMetrics(metrics, options) {
30
- if (null == metrics.actualBoundingBoxAscent || null == metrics.actualBoundingBoxDescent || null == metrics.fontBoundingBoxAscent || null == metrics.fontBoundingBoxDescent) {
31
- const {ascent: ascent, descent: descent} = this.measureTextBoundADscentEstimate(options);
32
- metrics.actualBoundingBoxAscent = ascent, metrics.actualBoundingBoxDescent = descent,
33
- metrics.fontBoundingBoxAscent = ascent, metrics.fontBoundingBoxDescent = descent;
34
- }
35
- if (null == metrics.actualBoundingBoxLeft || null == metrics.actualBoundingBoxRight) {
36
- const {left: left, right: right} = this.measureTextBoundLeftRightEstimate(options);
37
- metrics.actualBoundingBoxLeft = left, metrics.actualBoundingBoxRight = right;
38
- }
39
- return metrics;
22
+ return this.context.measureText(text).width;
40
23
  }
41
24
  estimate(text, {fontSize: fontSize = config_1.DefaultTextAttribute.fontSize}) {
42
25
  let eCharLen = 0, cCharLen = 0;
@@ -46,81 +29,19 @@ let ATextMeasure = class {
46
29
  height: fontSize
47
30
  };
48
31
  }
49
- measureTextWidth(text, options, textMeasure) {
50
- return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options)).width : this.estimate(text, options).width;
51
- }
52
- measureTextBoundsWidth(text, options, textMeasure) {
53
- return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options)).width : this.estimate(text, options).width;
54
- }
55
- measureTextBoundsLeftRight(text, options, textMeasure) {
56
- return this.context ? {
57
- left: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).actualBoundingBoxLeft,
58
- right: textMeasure.actualBoundingBoxRight
59
- } : this.measureTextBoundLeftRightEstimate(options);
60
- }
61
- measureTextPixelHeight(text, options, textMeasure) {
32
+ measureTextPixelHeight(text, options) {
62
33
  var _a;
63
- return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options, !0),
64
- Math.abs(textMeasure.actualBoundingBoxAscent - textMeasure.actualBoundingBoxDescent)) : null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize;
65
- }
66
- measureTextPixelADscent(text, options, textMeasure) {
67
- return this.context ? {
68
- ascent: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).actualBoundingBoxAscent,
69
- descent: textMeasure.actualBoundingBoxDescent
70
- } : this.measureTextBoundADscentEstimate(options);
71
- }
72
- measureTextBoundHieght(text, options, textMeasure) {
73
- var _a;
74
- return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options, !0),
75
- Math.abs(textMeasure.fontBoundingBoxAscent - textMeasure.fontBoundingBoxDescent)) : null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize;
76
- }
77
- measureTextBoundADscent(text, options, textMeasure) {
78
- return this.context ? {
79
- ascent: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).fontBoundingBoxAscent,
80
- descent: textMeasure.fontBoundingBoxDescent
81
- } : this.measureTextBoundADscentEstimate(options);
82
- }
83
- measureTextBoundADscentEstimate(options) {
84
- var _a;
85
- const fontSize = null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize, {textBaseline: textBaseline} = options;
86
- return "bottom" === textBaseline ? {
87
- ascent: fontSize,
88
- descent: 0
89
- } : "middle" === textBaseline ? {
90
- ascent: fontSize / 2,
91
- descent: fontSize / 2
92
- } : "alphabetic" === textBaseline ? {
93
- ascent: .79 * fontSize,
94
- descent: .21 * fontSize
95
- } : {
96
- ascent: 0,
97
- descent: fontSize
98
- };
34
+ if (!this.context) return null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize;
35
+ this.context.setTextStyleWithoutAlignBaseline(options);
36
+ const textMeasure = this.context.measureText(text);
37
+ return Math.abs(textMeasure.actualBoundingBoxAscent - textMeasure.actualBoundingBoxDescent);
99
38
  }
100
- measureTextBoundLeftRightEstimate(options) {
39
+ measureTextBoundHieght(text, options) {
101
40
  var _a;
102
- const fontSize = null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize, {textAlign: textAlign} = options;
103
- return "center" === textAlign ? {
104
- left: fontSize / 2,
105
- right: fontSize / 2
106
- } : "right" === textAlign || "end" === textAlign ? {
107
- left: fontSize,
108
- right: 0
109
- } : {
110
- left: 0,
111
- right: fontSize
112
- };
113
- }
114
- measureTextPixelADscentAndWidth(text, options) {
115
- if (!this.context) return Object.assign(Object.assign({}, this.measureTextBoundADscentEstimate(options)), {
116
- width: this.estimate(text, options).width
117
- });
118
- const out = this._measureTextWithoutAlignBaseline(text, options, !0);
119
- return {
120
- ascent: out.actualBoundingBoxAscent,
121
- descent: out.actualBoundingBoxDescent,
122
- width: out.width
123
- };
41
+ if (!this.context) return null !== (_a = options.fontSize) && void 0 !== _a ? _a : config_1.DefaultTextStyle.fontSize;
42
+ this.context.setTextStyleWithoutAlignBaseline(options);
43
+ const textMeasure = this.context.measureText(text);
44
+ return Math.abs(textMeasure.fontBoundingBoxAscent - textMeasure.fontBoundingBoxDescent);
124
45
  }
125
46
  measureText(text, options) {
126
47
  return this.context ? (this.context.setTextStyleWithoutAlignBaseline(options), this.context.measureText(text)) : this.estimate(text, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/contributions/textMeasure/AtextMeasure.ts"],"names":[],"mappings":"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","file":"AtextMeasure.js","sourcesContent":["import { injectable } from '../../../common/inversify-lite';\nimport type { IGraphicUtil } from '../../../interface/core';\nimport type { ICanvas, IContext2d, EnvType } from '../../../interface';\nimport type { TextOptionsType, ITextMeasure } from '../../../interface/text';\nimport { DefaultTextAttribute, DefaultTextStyle } from '../../../graphic/config';\nimport { testLetter } from '../../../graphic/richtext/utils';\nimport { Logger } from '@visactor/vutils';\n\n@injectable()\nexport class ATextMeasure implements ITextMeasure {\n release: (...params: any) => void;\n protected canvas?: ICanvas;\n protected context?: IContext2d | null;\n\n configure(service: IGraphicUtil, env: EnvType): void {\n this.canvas = service.canvas;\n this.context = service.context;\n service.bindTextMeasure(this);\n }\n\n protected _measureTextWithoutAlignBaseline(text: string, options: TextOptionsType, compatible?: boolean) {\n this.context.setTextStyleWithoutAlignBaseline(options);\n const metrics = this.context.measureText(text);\n\n return compatible ? this.compatibleMetrics(metrics, options) : metrics;\n }\n\n protected _measureTextWithAlignBaseline(text: string, options: TextOptionsType, compatible?: boolean) {\n this.context.setTextStyle(options);\n const metrics = this.context.measureText(text);\n\n return compatible ? this.compatibleMetrics(metrics, options) : metrics;\n }\n\n protected compatibleMetrics(metrics: TextMetrics | { width: number }, options: TextOptionsType) {\n if (\n (metrics as any).actualBoundingBoxAscent == null ||\n (metrics as any).actualBoundingBoxDescent == null ||\n (metrics as any).fontBoundingBoxAscent == null ||\n (metrics as any).fontBoundingBoxDescent == null\n ) {\n const { ascent, descent } = this.measureTextBoundADscentEstimate(options);\n (metrics as any).actualBoundingBoxAscent = ascent;\n (metrics as any).actualBoundingBoxDescent = descent;\n (metrics as any).fontBoundingBoxAscent = ascent;\n (metrics as any).fontBoundingBoxDescent = descent;\n }\n if ((metrics as any).actualBoundingBoxLeft == null || (metrics as any).actualBoundingBoxRight == null) {\n const { left, right } = this.measureTextBoundLeftRightEstimate(options);\n (metrics as any).actualBoundingBoxLeft = left;\n (metrics as any).actualBoundingBoxRight = right;\n }\n return metrics;\n }\n\n // 估算文字长度\n protected estimate(\n text: string,\n { fontSize = DefaultTextAttribute.fontSize }: TextOptionsType\n ): { width: number; height: number } {\n // 假设只有英文和中文字符\n let eCharLen = 0; // 英文字符\n let cCharLen = 0; // 中文字符\n // 判断ascii码,如果是\n for (let i = 0; i < text.length; i++) {\n text.charCodeAt(i) < 128 ? eCharLen++ : cCharLen++;\n }\n return {\n width: ~~(0.8 * eCharLen * fontSize + cCharLen * fontSize),\n height: fontSize\n };\n }\n\n /**\n * 获取text宽度,measureText.width\n * @param text\n * @param options\n */\n measureTextWidth(text: string, options: TextOptionsType, textMeasure?: TextMetrics | { width: number }): number {\n if (!this.context) {\n return this.estimate(text, options).width;\n }\n textMeasure = textMeasure ?? this._measureTextWithoutAlignBaseline(text, options);\n return textMeasure.width;\n }\n /**\n * 获取text宽度,measureText.width\n * @param text\n * @param options\n */\n measureTextBoundsWidth(\n text: string,\n options: TextOptionsType,\n textMeasure?: TextMetrics | { width: number }\n ): number {\n if (!this.context) {\n return this.estimate(text, options).width;\n }\n textMeasure = textMeasure ?? this._measureTextWithoutAlignBaseline(text, options);\n return textMeasure.width;\n }\n\n measureTextBoundsLeftRight(text: string, options: TextOptionsType, textMeasure?: TextMetrics | { width: number }) {\n if (!this.context) {\n return this.measureTextBoundLeftRightEstimate(options);\n }\n textMeasure = textMeasure ?? this._measureTextWithAlignBaseline(text, options, true);\n return {\n left: (textMeasure as any).actualBoundingBoxLeft,\n right: (textMeasure as any).actualBoundingBoxRight\n };\n }\n\n /**\n * 获取text像素高度,基于actualBoundingBoxAscent和actualBoundingBoxDescent\n * @param text\n * @param options\n */\n measureTextPixelHeight(\n text: string,\n options: TextOptionsType,\n textMeasure?: TextMetrics | { width: number }\n ): number {\n if (!this.context) {\n return options.fontSize ?? DefaultTextStyle.fontSize;\n }\n textMeasure = textMeasure ?? this._measureTextWithoutAlignBaseline(text, options, true);\n return Math.abs((textMeasure as any).actualBoundingBoxAscent - (textMeasure as any).actualBoundingBoxDescent);\n }\n\n measureTextPixelADscent(text: string, options: TextOptionsType, textMeasure?: TextMetrics | { width: number }) {\n if (!this.context) {\n return this.measureTextBoundADscentEstimate(options);\n }\n textMeasure = textMeasure ?? this._measureTextWithAlignBaseline(text, options, true);\n return {\n ascent: (textMeasure as any).actualBoundingBoxAscent,\n descent: (textMeasure as any).actualBoundingBoxDescent\n };\n }\n\n /**\n * 获取text包围盒的高度,基于fontBoundingBoxAscent和fontBoundingBoxDescent\n * @param text\n * @param options\n */\n measureTextBoundHieght(\n text: string,\n options: TextOptionsType,\n textMeasure?: TextMetrics | { width: number }\n ): number {\n if (!this.context) {\n return options.fontSize ?? DefaultTextStyle.fontSize;\n }\n textMeasure = textMeasure ?? this._measureTextWithoutAlignBaseline(text, options, true);\n return Math.abs((textMeasure as any).fontBoundingBoxAscent - (textMeasure as any).fontBoundingBoxDescent);\n }\n\n measureTextBoundADscent(text: string, options: TextOptionsType, textMeasure?: TextMetrics | { width: number }) {\n if (!this.context) {\n return this.measureTextBoundADscentEstimate(options);\n }\n textMeasure = textMeasure ?? this._measureTextWithAlignBaseline(text, options, true);\n return {\n ascent: (textMeasure as any).fontBoundingBoxAscent,\n descent: (textMeasure as any).fontBoundingBoxDescent\n };\n }\n\n protected measureTextBoundADscentEstimate(options: TextOptionsType) {\n const fontSize = options.fontSize ?? DefaultTextStyle.fontSize;\n const { textBaseline } = options;\n if (textBaseline === 'bottom') {\n return {\n ascent: fontSize,\n descent: 0\n };\n } else if (textBaseline === 'middle') {\n return {\n ascent: fontSize / 2,\n descent: fontSize / 2\n };\n } else if (textBaseline === 'alphabetic') {\n return {\n ascent: 0.79 * fontSize,\n descent: 0.21 * fontSize\n };\n }\n\n return {\n ascent: 0,\n descent: fontSize\n };\n }\n\n protected measureTextBoundLeftRightEstimate(options: TextOptionsType) {\n const fontSize = options.fontSize ?? DefaultTextStyle.fontSize;\n const { textAlign } = options;\n\n if (textAlign === 'center') {\n return {\n left: fontSize / 2,\n right: fontSize / 2\n };\n } else if (textAlign === 'right' || textAlign === 'end') {\n return {\n left: fontSize,\n right: 0\n };\n }\n return {\n left: 0,\n right: fontSize\n };\n }\n\n measureTextPixelADscentAndWidth(\n text: string,\n options: TextOptionsType\n ): { width: number; ascent: number; descent: number } {\n if (!this.context) {\n return {\n ...this.measureTextBoundADscentEstimate(options),\n width: this.estimate(text, options).width\n };\n }\n const out = this._measureTextWithoutAlignBaseline(text, options, true);\n return {\n ascent: (out as any).actualBoundingBoxAscent,\n descent: (out as any).actualBoundingBoxDescent,\n width: (out as any).width\n };\n }\n\n /**\n * 获取text测量对象\n * @param text\n * @param options\n */\n measureText(text: string, options: TextOptionsType): TextMetrics | { width: number } {\n if (!this.context) {\n return this.estimate(text, options);\n }\n this.context.setTextStyleWithoutAlignBaseline(options);\n return this.context.measureText(text);\n }\n\n clipTextVertical(\n verticalList: { text: string; width?: number; direction: number }[],\n options: TextOptionsType,\n width: number,\n wordBreak: boolean\n ): {\n verticalList: { text: string; width?: number; direction: number }[];\n width: number;\n } {\n if (verticalList.length === 0) {\n return { verticalList, width: 0 };\n }\n const { fontSize = 12 } = options;\n // 计算每一个区域的width\n verticalList.forEach(item => {\n item.width = item.direction === 0 ? fontSize : this.measureTextWidth(item.text, options);\n });\n const out: { text: string; width?: number; direction: number }[] = [];\n let length = 0;\n let i = 0;\n for (; i < verticalList.length; i++) {\n if (length + verticalList[i].width < width) {\n length += verticalList[i].width;\n out.push(verticalList[i]);\n } else {\n break;\n }\n }\n if (verticalList[i] && verticalList[i].text.length > 1) {\n const clipedData = this._clipText(\n verticalList[i].text,\n options,\n width - length,\n 0,\n verticalList[i].text.length - 1,\n 'end',\n false\n );\n if (wordBreak && clipedData.str !== verticalList[i].text) {\n let text = '';\n let length = 0;\n for (let j = 0; j < i; j++) {\n const item = verticalList[j];\n text += item.text;\n length += item.text.length;\n }\n text += verticalList[i].text;\n const totalLength = length + clipedData.str.length;\n let index = testLetter(text, totalLength);\n index = index - length;\n if (index !== clipedData.str.length - 1) {\n clipedData.str = clipedData.str.substring(0, index);\n clipedData.width = this.measureTextWidth(clipedData.str, options);\n }\n }\n out.push({ ...verticalList[i], text: clipedData.str, width: clipedData.width });\n length += clipedData.width;\n }\n\n return {\n verticalList: out,\n width: length\n };\n }\n\n /**\n * 将文本裁剪到width宽\n * @param text\n * @param options\n * @param width\n */\n clipText(\n text: string,\n options: TextOptionsType,\n width: number,\n wordBreak: boolean,\n keepAllBreak?: boolean\n ): {\n str: string;\n width: number;\n wordBreaked?: number;\n } {\n if (text.length === 0) {\n return { str: '', width: 0 };\n }\n let length = this.measureTextWidth(text, options);\n if (length <= width) {\n return { str: text, width: length };\n }\n length = this.measureTextWidth(text[0], options);\n if (length > width) {\n return { str: '', width: 0 };\n }\n const data = this._clipText(text, options, width, 0, text.length - 1, 'end', false);\n // 如果需要文字截断\n if (wordBreak && data.str !== text) {\n let index = testLetter(text, data.str.length, keepAllBreak);\n if (index !== data.str.length) {\n if (index > data.str.length) {\n (data as any).wordBreaked = index;\n index = data.str.length;\n }\n data.str = text.substring(0, index);\n data.width = this.measureTextWidth(data.str, options);\n }\n }\n return data;\n }\n\n // 二分法找到最佳宽\n // TODO: 后续考虑代码合并\n private _clipText(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number,\n position: 'start' | 'end' | 'middle',\n suffix: string | false\n ): { str: string; width: number; result?: string } {\n let data: { str: string; width: number; result?: string };\n if (position === 'start') {\n data = this._clipTextStart(text, options, width, leftIdx, rightIdx);\n suffix && (data.result = suffix + data.str);\n } else if (position === 'middle') {\n const d = this._clipTextMiddle(text, options, width, '', '', 0, 0, 1);\n data = { str: 'none', width: d.width, result: d.left + suffix + d.right };\n } else {\n data = this._clipTextEnd(text, options, width, leftIdx, rightIdx);\n suffix && (data.result = data.str + suffix);\n }\n return data;\n }\n\n private _clipTextEnd(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number\n ): { str: string; width: number } {\n // 添加退出条件,如果leftIdx和rightIdx相等,那么就返回这个字符串(理论上这时出问题了)\n if (leftIdx === rightIdx) {\n Logger.getInstance().warn(`【_clipTextEnd】不应该走到这里${text}, ${leftIdx}, ${rightIdx}`);\n // console.warn(`【_clipTextEnd】不应该走到这里${text}, ${leftIdx}, ${rightIdx}`);\n const subText = text.substring(0, rightIdx + 1);\n return { str: subText, width: this.measureTextWidth(subText, options) };\n }\n const middleIdx = Math.floor((leftIdx + rightIdx) / 2);\n const subText = text.substring(0, middleIdx + 1);\n const strWidth = this.measureTextWidth(subText, options);\n let length: number;\n if (strWidth > width) {\n // 如果字符串的宽度大于限制宽度\n if (subText.length <= 1) {\n return { str: '', width: 0 };\n } // 如果子字符串长度小于1,而且大于给定宽的话,返回空字符串\n // 先判断是不是左侧的那个字符\n const str = text.substring(0, middleIdx);\n // 如果到左侧的字符小于或等于width,那么说明就是左侧的字符\n length = this.measureTextWidth(str, options);\n if (length <= width) {\n return { str, width: length };\n }\n // 返回leftIdx到middleIdx\n return this._clipTextEnd(text, options, width, leftIdx, middleIdx);\n } else if (strWidth < width) {\n // 如果字符串的宽度小于限制宽度\n if (middleIdx >= text.length - 1) {\n return { str: text, width: this.measureTextWidth(text, options) };\n } // 如果已经到结尾了,返回text\n // 先判断是不是右侧的那个字符\n const str = text.substring(0, middleIdx + 2);\n // 如果到右侧的字符大于或等于width,那么说明就是这个字符串\n length = this.measureTextWidth(str, options);\n if (length >= width) {\n return { str: subText, width: strWidth };\n }\n // 返回middleIdx到rightIdx\n return this._clipTextEnd(text, options, width, middleIdx, rightIdx);\n }\n // 如果相同,那么就找到text\n return { str: subText, width: strWidth };\n }\n\n private _clipTextStart(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number\n ): { str: string; width: number } {\n const middleIdx = Math.ceil((leftIdx + rightIdx) / 2);\n const subText = text.substring(middleIdx - 1, text.length);\n const strWidth = this.measureTextWidth(subText, options);\n let length: number;\n if (strWidth > width) {\n // 如果字符串的宽度大于限制宽度\n if (subText.length <= 1) {\n return { str: '', width: 0 };\n } // 如果子字符串长度小于1,而且大于给定宽的话,返回空字符串\n // 先判断是不是左侧的那个字符\n const str = text.substring(middleIdx, text.length);\n // 如果到左侧的字符小于或等于width,那么说明就是左侧的字符\n length = this.measureTextWidth(str, options);\n if (length <= width) {\n return { str, width: length };\n }\n // 返回leftIdx到middleIdx\n return this._clipTextStart(text, options, width, middleIdx, text.length);\n } else if (strWidth < width) {\n // 如果字符串的宽度小于限制宽度\n if (middleIdx <= 0) {\n return { str: text, width: this.measureTextWidth(text, options) };\n } // 如果已经到结尾了,返回text\n // 先判断是不是右侧的那个字符\n const str = text.substring(middleIdx - 2, text.length);\n // 如果到右侧的字符大于或等于width,那么说明就是这个字符串\n length = this.measureTextWidth(str, options);\n if (length >= width) {\n return { str: subText, width: strWidth };\n }\n // 返回middleIdx到rightIdx\n return this._clipTextStart(text, options, width, leftIdx, middleIdx);\n }\n // 如果相同,那么就找到text\n return { str: subText, width: strWidth };\n }\n\n private _clipTextMiddle(\n text: string,\n options: TextOptionsType,\n width: number,\n left: string,\n right: string,\n leftW: number,\n rightW: number,\n buffer: number\n ): { left: string; right: string; width: number } {\n const subLeftText = text.substring(0, buffer);\n const strLeftWidth = this.measureTextWidth(subLeftText, options);\n if (strLeftWidth + rightW > width) {\n return { left, right, width: leftW + rightW };\n }\n const subRightText = text.substring(text.length - buffer, text.length);\n const strRightWidth = this.measureTextWidth(subRightText, options);\n if (strLeftWidth + strRightWidth > width) {\n return { left: subLeftText, right, width: strLeftWidth + rightW };\n }\n return this._clipTextMiddle(\n text,\n options,\n width,\n subLeftText,\n subRightText,\n strLeftWidth,\n strRightWidth,\n buffer + 1\n );\n }\n\n clipTextWithSuffixVertical(\n verticalList: { text: string; width?: number; direction: number }[],\n options: TextOptionsType,\n width: number,\n suffix: string,\n wordBreak: boolean,\n suffixPosition: 'start' | 'end' | 'middle'\n ): {\n verticalList: { text: string; width?: number; direction: number }[];\n width: number;\n } {\n if (suffix === '') {\n return this.clipTextVertical(verticalList, options, width, wordBreak);\n }\n if (verticalList.length === 0) {\n return { verticalList, width: 0 };\n }\n\n const output = this.clipTextVertical(verticalList, options, width, wordBreak);\n if (\n output.verticalList.length === verticalList.length &&\n output.verticalList[output.verticalList.length - 1].width === verticalList[verticalList.length - 1].width\n ) {\n return output;\n }\n\n const suffixWidth = this.measureTextWidth(suffix, options);\n if (suffixWidth > width) {\n return output;\n }\n\n width -= suffixWidth;\n\n let out;\n if (suffixPosition === 'start') {\n const nextVerticalList = this.revertVerticalList(verticalList);\n out = this.clipTextVertical(nextVerticalList, options, width, wordBreak);\n const v = this.revertVerticalList(out.verticalList);\n v.unshift({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n out.verticalList = v;\n } else if (suffixPosition === 'middle') {\n const leftOut = this.clipTextVertical(verticalList, options, width / 2, wordBreak);\n const nextVerticalList = this.revertVerticalList(verticalList);\n const rightOut = this.clipTextVertical(nextVerticalList, options, width / 2, wordBreak);\n // 添加suffix\n leftOut.verticalList.push({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n this.revertVerticalList(rightOut.verticalList).forEach(v => leftOut.verticalList.push(v));\n out = {\n verticalList: leftOut.verticalList,\n width: leftOut.width + rightOut.width\n };\n } else {\n out = this.clipTextVertical(verticalList, options, width, wordBreak);\n out.verticalList.push({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n }\n out.width += suffixWidth;\n return out;\n }\n\n revertVerticalList(\n verticalList: {\n text: string;\n width?: number;\n direction: number;\n }[]\n ) {\n return verticalList.reverse().map(l => {\n const t = l.text.split('').reverse().join('');\n return {\n ...l,\n text: t\n };\n });\n }\n\n clipTextWithSuffix(\n text: string,\n options: TextOptionsType,\n width: number,\n suffix: string,\n wordBreak: boolean,\n position: 'start' | 'end' | 'middle',\n forceSuffix: boolean = false\n ): {\n str: string;\n width: number;\n } {\n if (suffix === '') {\n return this.clipText(text, options, width, wordBreak);\n }\n if (text.length === 0) {\n return { str: '', width: 0 };\n }\n const length = this.measureTextWidth(text, options);\n if (!forceSuffix && length <= width) {\n return { str: text, width: length };\n }\n const suffixWidth = this.measureTextWidth(suffix, options);\n if (suffixWidth > width) {\n return { str: '', width: 0 };\n }\n if (forceSuffix && length + suffixWidth <= width) {\n return { str: text + suffix, width: length + suffixWidth };\n }\n width -= suffixWidth;\n const data = this._clipText(text, options, width, 0, text.length - 1, position, suffix);\n\n // 如果需要文字截断\n if (wordBreak && data.str !== text) {\n const index = testLetter(text, data.str.length);\n if (index !== data.str.length) {\n data.result = text.substring(0, index);\n data.width = this.measureTextWidth(data.str, options);\n }\n } else if (forceSuffix && data.str === text) {\n data.result = text + suffix;\n }\n data.str = data.result!;\n data.width += suffixWidth;\n return data;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/core/contributions/textMeasure/AtextMeasure.ts"],"names":[],"mappings":"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","file":"AtextMeasure.js","sourcesContent":["import { injectable } from '../../../common/inversify-lite';\nimport type { IGraphicUtil } from '../../../interface/core';\nimport type { ICanvas, IContext2d, EnvType } from '../../../interface';\nimport type { TextOptionsType, ITextMeasure } from '../../../interface/text';\nimport { DefaultTextAttribute, DefaultTextStyle } from '../../../graphic/config';\nimport { testLetter } from '../../../graphic/richtext/utils';\nimport { Logger } from '@visactor/vutils';\n\n@injectable()\nexport class ATextMeasure implements ITextMeasure {\n release: (...params: any) => void;\n protected canvas?: ICanvas;\n protected context?: IContext2d | null;\n\n configure(service: IGraphicUtil, env: EnvType): void {\n this.canvas = service.canvas;\n this.context = service.context;\n service.bindTextMeasure(this);\n }\n\n /**\n * 获取text宽度,measureText.width\n * @param text\n * @param options\n */\n measureTextWidth(text: string, options: TextOptionsType): number {\n if (!this.context) {\n return this.estimate(text, options).width;\n }\n this.context.setTextStyleWithoutAlignBaseline(options);\n const textMeasure = this.context.measureText(text);\n return textMeasure.width;\n }\n\n // 估算文字长度\n estimate(\n text: string,\n { fontSize = DefaultTextAttribute.fontSize }: TextOptionsType\n ): { width: number; height: number } {\n // 假设只有英文和中文字符\n let eCharLen = 0; // 英文字符\n let cCharLen = 0; // 中文字符\n // 判断ascii码,如果是\n for (let i = 0; i < text.length; i++) {\n text.charCodeAt(i) < 128 ? eCharLen++ : cCharLen++;\n }\n return {\n width: ~~(0.8 * eCharLen * fontSize + cCharLen * fontSize),\n height: fontSize\n };\n }\n\n /**\n * 获取text像素高度,基于actualBoundingBoxAscent和actualBoundingBoxDescent\n * @param text\n * @param options\n */\n measureTextPixelHeight(text: string, options: TextOptionsType): number {\n if (!this.context) {\n return options.fontSize ?? DefaultTextStyle.fontSize;\n }\n this.context.setTextStyleWithoutAlignBaseline(options);\n const textMeasure = this.context.measureText(text);\n return Math.abs((textMeasure as any).actualBoundingBoxAscent - (textMeasure as any).actualBoundingBoxDescent);\n }\n\n /**\n * 获取text包围盒的高度,基于fontBoundingBoxAscent和fontBoundingBoxDescent\n * @param text\n * @param options\n */\n measureTextBoundHieght(text: string, options: TextOptionsType): number {\n if (!this.context) {\n return options.fontSize ?? DefaultTextStyle.fontSize;\n }\n this.context.setTextStyleWithoutAlignBaseline(options);\n const textMeasure = this.context.measureText(text);\n return Math.abs((textMeasure as any).fontBoundingBoxAscent - (textMeasure as any).fontBoundingBoxDescent);\n }\n\n /**\n * 获取text测量对象\n * @param text\n * @param options\n */\n measureText(text: string, options: TextOptionsType): TextMetrics | { width: number } {\n if (!this.context) {\n return this.estimate(text, options);\n }\n this.context.setTextStyleWithoutAlignBaseline(options);\n return this.context.measureText(text);\n }\n\n clipTextVertical(\n verticalList: { text: string; width?: number; direction: number }[],\n options: TextOptionsType,\n width: number,\n wordBreak: boolean\n ): {\n verticalList: { text: string; width?: number; direction: number }[];\n width: number;\n } {\n if (verticalList.length === 0) {\n return { verticalList, width: 0 };\n }\n const { fontSize = 12 } = options;\n // 计算每一个区域的width\n verticalList.forEach(item => {\n item.width = item.direction === 0 ? fontSize : this.measureTextWidth(item.text, options);\n });\n const out: { text: string; width?: number; direction: number }[] = [];\n let length = 0;\n let i = 0;\n for (; i < verticalList.length; i++) {\n if (length + verticalList[i].width < width) {\n length += verticalList[i].width;\n out.push(verticalList[i]);\n } else {\n break;\n }\n }\n if (verticalList[i] && verticalList[i].text.length > 1) {\n const clipedData = this._clipText(\n verticalList[i].text,\n options,\n width - length,\n 0,\n verticalList[i].text.length - 1,\n 'end',\n false\n );\n if (wordBreak && clipedData.str !== verticalList[i].text) {\n let text = '';\n let length = 0;\n for (let j = 0; j < i; j++) {\n const item = verticalList[j];\n text += item.text;\n length += item.text.length;\n }\n text += verticalList[i].text;\n const totalLength = length + clipedData.str.length;\n let index = testLetter(text, totalLength);\n index = index - length;\n if (index !== clipedData.str.length - 1) {\n clipedData.str = clipedData.str.substring(0, index);\n clipedData.width = this.measureTextWidth(clipedData.str, options);\n }\n }\n out.push({ ...verticalList[i], text: clipedData.str, width: clipedData.width });\n length += clipedData.width;\n }\n\n return {\n verticalList: out,\n width: length\n };\n }\n\n /**\n * 将文本裁剪到width宽\n * @param text\n * @param options\n * @param width\n */\n clipText(\n text: string,\n options: TextOptionsType,\n width: number,\n wordBreak: boolean,\n keepAllBreak?: boolean\n ): {\n str: string;\n width: number;\n wordBreaked?: number;\n } {\n if (text.length === 0) {\n return { str: '', width: 0 };\n }\n let length = this.measureTextWidth(text, options);\n if (length <= width) {\n return { str: text, width: length };\n }\n length = this.measureTextWidth(text[0], options);\n if (length > width) {\n return { str: '', width: 0 };\n }\n const data = this._clipText(text, options, width, 0, text.length - 1, 'end', false);\n // 如果需要文字截断\n if (wordBreak && data.str !== text) {\n let index = testLetter(text, data.str.length, keepAllBreak);\n if (index !== data.str.length) {\n if (index > data.str.length) {\n (data as any).wordBreaked = index;\n index = data.str.length;\n }\n data.str = text.substring(0, index);\n data.width = this.measureTextWidth(data.str, options);\n }\n }\n return data;\n }\n\n // 二分法找到最佳宽\n // TODO: 后续考虑代码合并\n private _clipText(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number,\n position: 'start' | 'end' | 'middle',\n suffix: string | false\n ): { str: string; width: number; result?: string } {\n let data: { str: string; width: number; result?: string };\n if (position === 'start') {\n data = this._clipTextStart(text, options, width, leftIdx, rightIdx);\n suffix && (data.result = suffix + data.str);\n } else if (position === 'middle') {\n const d = this._clipTextMiddle(text, options, width, '', '', 0, 0, 1);\n data = { str: 'none', width: d.width, result: d.left + suffix + d.right };\n } else {\n data = this._clipTextEnd(text, options, width, leftIdx, rightIdx);\n suffix && (data.result = data.str + suffix);\n }\n return data;\n }\n\n private _clipTextEnd(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number\n ): { str: string; width: number } {\n // 添加退出条件,如果leftIdx和rightIdx相等,那么就返回这个字符串(理论上这时出问题了)\n if (leftIdx === rightIdx) {\n Logger.getInstance().warn(`【_clipTextEnd】不应该走到这里${text}, ${leftIdx}, ${rightIdx}`);\n // console.warn(`【_clipTextEnd】不应该走到这里${text}, ${leftIdx}, ${rightIdx}`);\n const subText = text.substring(0, rightIdx + 1);\n return { str: subText, width: this.measureTextWidth(subText, options) };\n }\n const middleIdx = Math.floor((leftIdx + rightIdx) / 2);\n const subText = text.substring(0, middleIdx + 1);\n const strWidth = this.measureTextWidth(subText, options);\n let length: number;\n if (strWidth > width) {\n // 如果字符串的宽度大于限制宽度\n if (subText.length <= 1) {\n return { str: '', width: 0 };\n } // 如果子字符串长度小于1,而且大于给定宽的话,返回空字符串\n // 先判断是不是左侧的那个字符\n const str = text.substring(0, middleIdx);\n // 如果到左侧的字符小于或等于width,那么说明就是左侧的字符\n length = this.measureTextWidth(str, options);\n if (length <= width) {\n return { str, width: length };\n }\n // 返回leftIdx到middleIdx\n return this._clipTextEnd(text, options, width, leftIdx, middleIdx);\n } else if (strWidth < width) {\n // 如果字符串的宽度小于限制宽度\n if (middleIdx >= text.length - 1) {\n return { str: text, width: this.measureTextWidth(text, options) };\n } // 如果已经到结尾了,返回text\n // 先判断是不是右侧的那个字符\n const str = text.substring(0, middleIdx + 2);\n // 如果到右侧的字符大于或等于width,那么说明就是这个字符串\n length = this.measureTextWidth(str, options);\n if (length >= width) {\n return { str: subText, width: strWidth };\n }\n // 返回middleIdx到rightIdx\n return this._clipTextEnd(text, options, width, middleIdx, rightIdx);\n }\n // 如果相同,那么就找到text\n return { str: subText, width: strWidth };\n }\n\n private _clipTextStart(\n text: string,\n options: TextOptionsType,\n width: number,\n leftIdx: number,\n rightIdx: number\n ): { str: string; width: number } {\n const middleIdx = Math.ceil((leftIdx + rightIdx) / 2);\n const subText = text.substring(middleIdx - 1, text.length);\n const strWidth = this.measureTextWidth(subText, options);\n let length: number;\n if (strWidth > width) {\n // 如果字符串的宽度大于限制宽度\n if (subText.length <= 1) {\n return { str: '', width: 0 };\n } // 如果子字符串长度小于1,而且大于给定宽的话,返回空字符串\n // 先判断是不是左侧的那个字符\n const str = text.substring(middleIdx, text.length);\n // 如果到左侧的字符小于或等于width,那么说明就是左侧的字符\n length = this.measureTextWidth(str, options);\n if (length <= width) {\n return { str, width: length };\n }\n // 返回leftIdx到middleIdx\n return this._clipTextStart(text, options, width, middleIdx, text.length);\n } else if (strWidth < width) {\n // 如果字符串的宽度小于限制宽度\n if (middleIdx <= 0) {\n return { str: text, width: this.measureTextWidth(text, options) };\n } // 如果已经到结尾了,返回text\n // 先判断是不是右侧的那个字符\n const str = text.substring(middleIdx - 2, text.length);\n // 如果到右侧的字符大于或等于width,那么说明就是这个字符串\n length = this.measureTextWidth(str, options);\n if (length >= width) {\n return { str: subText, width: strWidth };\n }\n // 返回middleIdx到rightIdx\n return this._clipTextStart(text, options, width, leftIdx, middleIdx);\n }\n // 如果相同,那么就找到text\n return { str: subText, width: strWidth };\n }\n\n private _clipTextMiddle(\n text: string,\n options: TextOptionsType,\n width: number,\n left: string,\n right: string,\n leftW: number,\n rightW: number,\n buffer: number\n ): { left: string; right: string; width: number } {\n const subLeftText = text.substring(0, buffer);\n const strLeftWidth = this.measureTextWidth(subLeftText, options);\n if (strLeftWidth + rightW > width) {\n return { left, right, width: leftW + rightW };\n }\n const subRightText = text.substring(text.length - buffer, text.length);\n const strRightWidth = this.measureTextWidth(subRightText, options);\n if (strLeftWidth + strRightWidth > width) {\n return { left: subLeftText, right, width: strLeftWidth + rightW };\n }\n return this._clipTextMiddle(\n text,\n options,\n width,\n subLeftText,\n subRightText,\n strLeftWidth,\n strRightWidth,\n buffer + 1\n );\n }\n\n clipTextWithSuffixVertical(\n verticalList: { text: string; width?: number; direction: number }[],\n options: TextOptionsType,\n width: number,\n suffix: string,\n wordBreak: boolean,\n suffixPosition: 'start' | 'end' | 'middle'\n ): {\n verticalList: { text: string; width?: number; direction: number }[];\n width: number;\n } {\n if (suffix === '') {\n return this.clipTextVertical(verticalList, options, width, wordBreak);\n }\n if (verticalList.length === 0) {\n return { verticalList, width: 0 };\n }\n\n const output = this.clipTextVertical(verticalList, options, width, wordBreak);\n if (\n output.verticalList.length === verticalList.length &&\n output.verticalList[output.verticalList.length - 1].width === verticalList[verticalList.length - 1].width\n ) {\n return output;\n }\n\n const suffixWidth = this.measureTextWidth(suffix, options);\n if (suffixWidth > width) {\n return output;\n }\n\n width -= suffixWidth;\n\n let out;\n if (suffixPosition === 'start') {\n const nextVerticalList = this.revertVerticalList(verticalList);\n out = this.clipTextVertical(nextVerticalList, options, width, wordBreak);\n const v = this.revertVerticalList(out.verticalList);\n v.unshift({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n out.verticalList = v;\n } else if (suffixPosition === 'middle') {\n const leftOut = this.clipTextVertical(verticalList, options, width / 2, wordBreak);\n const nextVerticalList = this.revertVerticalList(verticalList);\n const rightOut = this.clipTextVertical(nextVerticalList, options, width / 2, wordBreak);\n // 添加suffix\n leftOut.verticalList.push({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n this.revertVerticalList(rightOut.verticalList).forEach(v => leftOut.verticalList.push(v));\n out = {\n verticalList: leftOut.verticalList,\n width: leftOut.width + rightOut.width\n };\n } else {\n out = this.clipTextVertical(verticalList, options, width, wordBreak);\n out.verticalList.push({\n text: suffix,\n direction: 1,\n width: suffixWidth\n });\n }\n out.width += suffixWidth;\n return out;\n }\n\n revertVerticalList(\n verticalList: {\n text: string;\n width?: number;\n direction: number;\n }[]\n ) {\n return verticalList.reverse().map(l => {\n const t = l.text.split('').reverse().join('');\n return {\n ...l,\n text: t\n };\n });\n }\n\n clipTextWithSuffix(\n text: string,\n options: TextOptionsType,\n width: number,\n suffix: string,\n wordBreak: boolean,\n position: 'start' | 'end' | 'middle',\n forceSuffix: boolean = false\n ): {\n str: string;\n width: number;\n } {\n if (suffix === '') {\n return this.clipText(text, options, width, wordBreak);\n }\n if (text.length === 0) {\n return { str: '', width: 0 };\n }\n const length = this.measureTextWidth(text, options);\n if (!forceSuffix && length <= width) {\n return { str: text, width: length };\n }\n const suffixWidth = this.measureTextWidth(suffix, options);\n if (suffixWidth > width) {\n return { str: '', width: 0 };\n }\n if (forceSuffix && length + suffixWidth <= width) {\n return { str: text + suffix, width: length + suffixWidth };\n }\n width -= suffixWidth;\n const data = this._clipText(text, options, width, 0, text.length - 1, position, suffix);\n\n // 如果需要文字截断\n if (wordBreak && data.str !== text) {\n const index = testLetter(text, data.str.length);\n if (index !== data.str.length) {\n data.result = text.substring(0, index);\n data.width = this.measureTextWidth(data.str, options);\n }\n } else if (forceSuffix && data.str === text) {\n data.result = text + suffix;\n }\n data.str = data.result!;\n data.width += suffixWidth;\n return data;\n }\n}\n"]}
@@ -6,6 +6,7 @@ export declare class CanvasTextLayout {
6
6
  private textMeasure;
7
7
  constructor(fontFamily: string, options: TextOptionsType, textMeasure: ITextMeasure);
8
8
  LayoutBBox(bbox: TextLayoutBBox, textAlign: TextAlignType, textBaseline: TextBaselineType): TextLayoutBBox;
9
+ GetLayout(str: string, width: number, height: number, textAlign: TextAlignType, textBaseline: TextBaselineType, lineHeight: number, suffix: string, wordBreak: boolean, suffixPosition: 'start' | 'end' | 'middle'): LayoutType;
9
10
  GetLayoutByLines(lines: (string | number)[], textAlign: TextAlignType, textBaseline: TextBaselineType, lineHeight: number, suffix: string, wordBreak: boolean, lineWidth?: number, suffixPosition?: 'start' | 'end' | 'middle'): LayoutType;
10
11
  layoutWithBBox(bbox: TextLayoutBBox, lines: LayoutItemType[], textAlign: TextAlignType, textBaseline: TextBaselineType, lineHeight: number): LayoutType;
11
12
  private lineOffset;
@@ -16,34 +16,44 @@ class CanvasTextLayout {
16
16
  return bbox.yOffset = "top" === textBaseline ? 0 : "middle" === textBaseline ? bbox.height / -2 : "alphabetic" === textBaseline ? -.79 * bbox.height : -bbox.height,
17
17
  bbox;
18
18
  }
19
+ GetLayout(str, width, height, textAlign, textBaseline, lineHeight, suffix, wordBreak, suffixPosition) {
20
+ const linesLayout = [], bboxWH = [ width, height ], bboxOffset = [ 0, 0 ];
21
+ for (;str.length > 0; ) {
22
+ const {str: clipText} = this.textMeasure.clipTextWithSuffix(str, this.textOptions, width, suffix, wordBreak, suffixPosition);
23
+ linesLayout.push({
24
+ str: clipText,
25
+ width: this.textMeasure.measureTextWidth(clipText, this.textOptions)
26
+ }), str = str.substring(clipText.length);
27
+ }
28
+ "left" === textAlign || "start" === textAlign || ("center" === textAlign ? bboxOffset[0] = bboxWH[0] / -2 : "right" !== textAlign && "end" !== textAlign || (bboxOffset[0] = -bboxWH[0])),
29
+ "top" === textBaseline || ("middle" === textBaseline ? bboxOffset[1] = bboxWH[1] / -2 : "bottom" === textBaseline && (bboxOffset[1] = -bboxWH[1]));
30
+ const bbox = {
31
+ xOffset: bboxOffset[0],
32
+ yOffset: bboxOffset[1],
33
+ width: bboxWH[0],
34
+ height: bboxWH[1]
35
+ };
36
+ return this.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);
37
+ }
19
38
  GetLayoutByLines(lines, textAlign, textBaseline, lineHeight, suffix = "", wordBreak, lineWidth, suffixPosition = "end") {
20
39
  lines = lines.map((l => l.toString()));
21
40
  const linesLayout = [], bboxWH = [ 0, 0 ];
22
41
  if ("number" == typeof lineWidth && lineWidth !== 1 / 0) {
23
42
  let width;
24
- for (let i = 0, len = lines.length; i < len; i++) {
25
- const metrics = this.textMeasure.measureTextPixelADscentAndWidth(lines[i], this.textOptions);
26
- width = Math.min(metrics.width, lineWidth), linesLayout.push({
27
- str: this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
28
- width: width,
29
- ascent: metrics.ascent,
30
- descent: metrics.descent
31
- });
32
- }
43
+ for (let i = 0, len = lines.length; i < len; i++) width = Math.min(this.textMeasure.measureTextWidth(lines[i], this.textOptions), lineWidth),
44
+ linesLayout.push({
45
+ str: this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
46
+ width: width
47
+ });
33
48
  bboxWH[0] = lineWidth;
34
49
  } else {
35
50
  let width, text;
36
51
  lineWidth = 0;
37
- for (let i = 0, len = lines.length; i < len; i++) {
38
- text = lines[i];
39
- const metrics = this.textMeasure.measureTextPixelADscentAndWidth(lines[i], this.textOptions);
40
- width = metrics.width, lineWidth = Math.max(lineWidth, width), linesLayout.push({
41
- str: text,
42
- width: width,
43
- ascent: metrics.ascent,
44
- descent: metrics.descent
45
- });
46
- }
52
+ for (let i = 0, len = lines.length; i < len; i++) text = lines[i], width = this.textMeasure.measureTextWidth(text, this.textOptions),
53
+ lineWidth = Math.max(lineWidth, width), linesLayout.push({
54
+ str: text,
55
+ width: width
56
+ });
47
57
  bboxWH[0] = lineWidth;
48
58
  }
49
59
  bboxWH[1] = linesLayout.length * lineHeight, bboxWH[0] = linesLayout.reduce(((a, b) => Math.max(a, b.width)), 0);
@@ -72,7 +82,7 @@ class CanvasTextLayout {
72
82
  }
73
83
  lineOffset(bbox, line, textAlign, textBaseline, lineHeight, origin) {
74
84
  return "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),
75
- line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1],
85
+ line.topOffset = (lineHeight - this.textOptions.fontSize) / 2 + .79 * this.textOptions.fontSize + origin[1],
76
86
  origin[1] += lineHeight, line;
77
87
  }
78
88
  }