@hailin-zheng/editor-core 2.1.19 → 2.1.21

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 (55) hide show
  1. package/index-cjs.js +752 -1842
  2. package/index-cjs.js.map +1 -1
  3. package/index.js +742 -1843
  4. package/index.js.map +1 -1
  5. package/med_editor/framework/ast-parser.d.ts +2 -1
  6. package/med_editor/framework/common-util.d.ts +2 -0
  7. package/med_editor/framework/document-arrange.d.ts +4 -1
  8. package/med_editor/framework/document-paint.d.ts +0 -4
  9. package/med_editor/framework/{dynamic-executer.d.ts → dynamic-execute.d.ts} +6 -7
  10. package/med_editor/framework/element-define.d.ts +36 -2
  11. package/med_editor/framework/element-props.d.ts +8 -0
  12. package/med_editor/framework/element-reader.d.ts +1 -0
  13. package/med_editor/framework/element-serialize.d.ts +1 -0
  14. package/med_editor/framework/element-trace-manage.d.ts +5 -0
  15. package/med_editor/framework/element-util.d.ts +3 -0
  16. package/med_editor/framework/impl/checkbox/checkbox-impl.d.ts +2 -3
  17. package/med_editor/framework/impl/comments/comment-content-impl.d.ts +1 -2
  18. package/med_editor/framework/impl/comments/comment-element-impl.d.ts +1 -2
  19. package/med_editor/framework/impl/comments/comments-container-impl.d.ts +2 -6
  20. package/med_editor/framework/impl/comments/validate-msg-impl.d.ts +1 -2
  21. package/med_editor/framework/impl/data-element/data-decorate-impl.d.ts +1 -2
  22. package/med_editor/framework/impl/data-element/data-element-barcode.d.ts +2 -5
  23. package/med_editor/framework/impl/data-element/data-element-base-impl.d.ts +0 -1
  24. package/med_editor/framework/impl/data-element/data-element-check-impl.d.ts +1 -2
  25. package/med_editor/framework/impl/data-element/data-element-group-impl.d.ts +1 -2
  26. package/med_editor/framework/impl/data-element/data-element-image-impl.d.ts +2 -5
  27. package/med_editor/framework/impl/decorate/fill-null-space-imple.d.ts +1 -2
  28. package/med_editor/framework/impl/document/doc-body-impl.d.ts +1 -2
  29. package/med_editor/framework/impl/document/doc-body-part-impl.d.ts +1 -2
  30. package/med_editor/framework/impl/document/doc-container-impl.d.ts +1 -2
  31. package/med_editor/framework/impl/document/doc-footer-impl.d.ts +1 -2
  32. package/med_editor/framework/impl/document/doc-header-impl.d.ts +1 -2
  33. package/med_editor/framework/impl/document/doc-impl.d.ts +1 -2
  34. package/med_editor/framework/impl/index.d.ts +2 -0
  35. package/med_editor/framework/impl/media-formula/menstrual-history.d.ts +1 -2
  36. package/med_editor/framework/impl/media-formula/permanent-teeth.d.ts +6 -4
  37. package/med_editor/framework/impl/paragraph/p-impl.d.ts +0 -2
  38. package/med_editor/framework/impl/picture/RectEle.d.ts +1 -6
  39. package/med_editor/framework/impl/picture/image-impl.d.ts +2 -5
  40. package/med_editor/framework/impl/radio/radio-impl.d.ts +1 -2
  41. package/med_editor/framework/impl/svg/svg-impl.d.ts +20 -0
  42. package/med_editor/framework/impl/symbol/br-symbol-impl.d.ts +1 -2
  43. package/med_editor/framework/impl/symbol/p-symbol-impl.d.ts +1 -2
  44. package/med_editor/framework/impl/symbol/page-br-symbol-impl.d.ts +1 -2
  45. package/med_editor/framework/impl/symbol/tab-symbol-impl.d.ts +1 -2
  46. package/med_editor/framework/impl/table/table-cell-impl.d.ts +1 -2
  47. package/med_editor/framework/impl/table/table-impl.d.ts +1 -2
  48. package/med_editor/framework/impl/table/table-row-impl.d.ts +1 -2
  49. package/med_editor/framework/impl/text/text-impl.d.ts +1 -2
  50. package/med_editor/framework/impl/text/track-run-impl.d.ts +1 -2
  51. package/med_editor/framework/paragraph-arrange.d.ts +18 -1
  52. package/med_editor/framework/render-define.d.ts +0 -2
  53. package/package.json +1 -1
  54. package/med_editor/framework/element-measure.d.ts +0 -94
  55. package/med_editor/framework/element-render-cut.d.ts +0 -59
package/index-cjs.js CHANGED
@@ -275,8 +275,6 @@ class RenderObject {
275
275
  this.margin = new MarginProps();
276
276
  this.padding = new PaddingProps();
277
277
  }
278
- pagePaintCompleted(e) {
279
- }
280
278
  destroy() {
281
279
  //this.parent = null;
282
280
  //this.margin = null;
@@ -660,10 +658,61 @@ class CommonUtil {
660
658
  return reg.test(str);
661
659
  }
662
660
  static cloneValue(val) {
663
- if (typeof val === 'object' && val) {
664
- return JSON.parse(JSON.stringify(val));
661
+ return CommonUtil.cloneDeep(val);
662
+ }
663
+ // @ts-ignore
664
+ static cloneDeep(source, visited = new WeakMap()) {
665
+ if (source === null || typeof source !== 'object') {
666
+ // 如果是基本类型或 null,则直接返回
667
+ return source;
668
+ }
669
+ // 处理循环引用
670
+ if (visited.has(source)) {
671
+ return visited.get(source);
672
+ }
673
+ if (Array.isArray(source)) {
674
+ // 如果是数组,则递归复制数组元素
675
+ const arrayClone = [];
676
+ visited.set(source, arrayClone);
677
+ source.forEach((item, index) => {
678
+ arrayClone[index] = CommonUtil.cloneDeep(item, visited);
679
+ });
680
+ return arrayClone;
681
+ }
682
+ if (source instanceof Date) {
683
+ // 如果是 Date 对象,则直接创建一个新的 Date 对象
684
+ return new Date(source.getTime());
685
+ }
686
+ if (source instanceof Map) {
687
+ // 如果是 Map 对象,则递归复制键值对
688
+ const mapClone = new Map();
689
+ visited.set(source, mapClone);
690
+ source.forEach((value, key) => {
691
+ mapClone.set(CommonUtil.cloneDeep(key, visited), CommonUtil.cloneDeep(value, visited));
692
+ });
693
+ return mapClone;
694
+ }
695
+ if (source instanceof Set) {
696
+ // 如果是 Set 对象,则递归复制元素
697
+ const setClone = new Set();
698
+ visited.set(source, setClone);
699
+ source.forEach(value => {
700
+ setClone.add(CommonUtil.cloneDeep(value, visited));
701
+ });
702
+ return setClone;
665
703
  }
666
- return val;
704
+ if (Object.prototype.toString.call(source) === '[object Object]') {
705
+ // 如果是普通对象,则递归复制对象属性
706
+ const objectClone = {};
707
+ visited.set(source, objectClone);
708
+ for (const key in source) {
709
+ if (source.hasOwnProperty(key)) {
710
+ objectClone[key] = CommonUtil.cloneDeep(source[key], visited);
711
+ }
712
+ }
713
+ return objectClone;
714
+ }
715
+ return source;
667
716
  }
668
717
  static isConstructor(f) {
669
718
  try {
@@ -743,6 +792,9 @@ class CommonUtil {
743
792
  return btoa(unescape(encodeURIComponent(str)));
744
793
  //return btoa(str.replace(/[\u00A0-\u2666]/g, c => `&#${c.charCodeAt(0)};`));
745
794
  }
795
+ static isEqual(a, b) {
796
+ return JSON.stringify(a) === JSON.stringify(b);
797
+ }
746
798
  }
747
799
 
748
800
  const docOpsMap = new Map();
@@ -1214,6 +1266,8 @@ class Element {
1214
1266
  disposed;
1215
1267
  //加载完毕
1216
1268
  loaded;
1269
+ visibleExpr;
1270
+ attribute;
1217
1271
  _parent;
1218
1272
  get parent() {
1219
1273
  return this._parent;
@@ -1286,7 +1340,6 @@ class Element {
1286
1340
  listeners.forEach(item => item(evt));
1287
1341
  }
1288
1342
  beginMeasure(data) {
1289
- this.paintRenders.length = 0;
1290
1343
  }
1291
1344
  endMeasure() {
1292
1345
  }
@@ -1702,6 +1755,7 @@ class ViewOptions {
1702
1755
  printHeaderFooterLine = false;
1703
1756
  //显示段落回车符号
1704
1757
  showEnterSymbol = false;
1758
+ enableVisibleExpression = false;
1705
1759
  get fullPageView() {
1706
1760
  return this._fullPageView;
1707
1761
  }
@@ -1815,6 +1869,30 @@ class BorderProps {
1815
1869
  return new BorderProps(this.width, this.color, this.style);
1816
1870
  }
1817
1871
  }
1872
+ /**
1873
+ * 克隆元素的基本属性
1874
+ * @param ele
1875
+ * @param target
1876
+ */
1877
+ function cloneElementBase(ele, target) {
1878
+ target.attribute = ele.attribute ? CommonUtil.cloneValue(ele.attribute) : undefined;
1879
+ }
1880
+ /**
1881
+ * 克隆元素的子元素
1882
+ * @param ele
1883
+ * @param target
1884
+ * @param data
1885
+ */
1886
+ function cloneChildren(ele, target, data) {
1887
+ if (!data) {
1888
+ return;
1889
+ }
1890
+ for (let i = 0; i < ele.length; i++) {
1891
+ const child = ele.getChild(i);
1892
+ const cloneChild = child.clone(true);
1893
+ target.addChild(cloneChild);
1894
+ }
1895
+ }
1818
1896
  class IDispose {
1819
1897
  }
1820
1898
  class ResizeLeafRenderObject extends LeafRenderObject {
@@ -2252,6 +2330,32 @@ class PictureProps extends INotifyPropertyChanged {
2252
2330
  return props;
2253
2331
  }
2254
2332
  }
2333
+ class SVGProps extends INotifyPropertyChanged {
2334
+ title;
2335
+ width = 5;
2336
+ height = 5;
2337
+ value;
2338
+ clone(dest) {
2339
+ const clone = dest ?? new SVGProps();
2340
+ super.cloneAttachedProperty(clone);
2341
+ clone.width = this.width;
2342
+ clone.height = this.height;
2343
+ clone.value = this.value;
2344
+ clone.title = this.title;
2345
+ return clone;
2346
+ }
2347
+ getSerializeProps(viewOptions) {
2348
+ const props = {
2349
+ width: this.width,
2350
+ height: this.height,
2351
+ value: this.value,
2352
+ };
2353
+ if (this.title) {
2354
+ props['title'] = this.title;
2355
+ }
2356
+ return props;
2357
+ }
2358
+ }
2255
2359
  class DataDecorateProps extends INotifyPropertyChanged {
2256
2360
  content;
2257
2361
  size;
@@ -2795,26 +2899,15 @@ class CommsContainerElement extends BlockContainerElement {
2795
2899
  }
2796
2900
  clone(data) {
2797
2901
  const clone = new CommsContainerElement();
2798
- if (data) {
2799
- for (let i = 0; i < this.length; i++) {
2800
- clone.addChild(this.getChild(i).clone(true));
2801
- }
2802
- }
2902
+ cloneElementBase(this, clone);
2903
+ cloneChildren(this, clone, data);
2803
2904
  return clone;
2804
2905
  }
2805
2906
  }
2806
2907
  class CommsContainerRenderObject extends BlockContainerRenderObject {
2807
2908
  //批注内容是否已经重组,只要重新绘制的时候组合一次即可
2808
2909
  isMeasureComm;
2809
- selectedSet;
2810
- commentRangeStatus = [];
2811
2910
  commsMarks = [];
2812
- render(e) {
2813
- if (this.rect.height === 0) {
2814
- return;
2815
- }
2816
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, 'black', 0.5);
2817
- }
2818
2911
  clone() {
2819
2912
  const clone = new CommsContainerRenderObject(this.element);
2820
2913
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -2890,14 +2983,11 @@ class DataDecorateElement extends LeafElement {
2890
2983
  clone() {
2891
2984
  const clone = new DataDecorateElement(this.dataEle, this.isPrefix);
2892
2985
  this.props.clone(clone.props);
2893
- //clone.renderCtx = this.renderCtx;
2986
+ cloneElementBase(this, clone);
2894
2987
  return clone;
2895
2988
  }
2896
2989
  }
2897
2990
  class DataDecorateRenderObject extends LeafRenderObject {
2898
- render(e) {
2899
- this.renderDecorRect(e.render, e.position);
2900
- }
2901
2991
  renderDecorRect(ctx, position) {
2902
2992
  if (ctx.drawMode === 'print') {
2903
2993
  return;
@@ -2968,7 +3058,7 @@ class DataDecorateRenderObject extends LeafRenderObject {
2968
3058
  }
2969
3059
  }
2970
3060
 
2971
- function parser(code) {
3061
+ function parser(code, objects) {
2972
3062
  const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
2973
3063
  estraverse__default["default"].traverse(node, {
2974
3064
  enter: (child, parent) => {
@@ -2976,6 +3066,7 @@ function parser(code) {
2976
3066
  const identifierName = child['name'];
2977
3067
  if (identifierName.startsWith('$')) {
2978
3068
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3069
+ objects?.push(identifierName.slice(1));
2979
3070
  }
2980
3071
  }
2981
3072
  }
@@ -3002,6 +3093,28 @@ function parser(code) {
3002
3093
  });
3003
3094
  return astring.generate(node);
3004
3095
  }
3096
+ //判断代码的语句,如果最后一个语句不是return,那么加上return
3097
+ function addReturn(code) {
3098
+ const node = acor__namespace.parse(code, { ecmaVersion: 'latest' });
3099
+ estraverse__default["default"].replace(node, {
3100
+ leave: (child) => {
3101
+ //函数调用
3102
+ if (child.type == 'Program') {
3103
+ const body = child['body'];
3104
+ const lastNode = body[body.length - 1];
3105
+ if (lastNode.type !== 'ReturnStatement') {
3106
+ body[body.length - 1] = {
3107
+ type: 'ReturnStatement',
3108
+ start: -1, end: -1,
3109
+ argument: lastNode
3110
+ };
3111
+ }
3112
+ return child;
3113
+ }
3114
+ }
3115
+ });
3116
+ return astring.generate(node);
3117
+ }
3005
3118
  /**
3006
3119
  * 将参数转为函数调用arg => ()=>arg
3007
3120
  * @param nodes
@@ -3095,11 +3208,8 @@ class ParagraphElement extends BlockContentElement {
3095
3208
  clone(data) {
3096
3209
  const clone = new ParagraphElement();
3097
3210
  this.props.clone(clone.props);
3098
- if (data) {
3099
- for (let i = 0; i < this.length; i++) {
3100
- clone.addChild(this.getChild(i).clone(true));
3101
- }
3102
- }
3211
+ cloneElementBase(this, clone);
3212
+ cloneChildren(this, clone, data);
3103
3213
  return clone;
3104
3214
  }
3105
3215
  static createElement() {
@@ -3107,10 +3217,6 @@ class ParagraphElement extends BlockContentElement {
3107
3217
  }
3108
3218
  }
3109
3219
  class ParagraphRenderObject extends MuiltBlockLineRenderObject {
3110
- render(e) {
3111
- e.nextRender();
3112
- this.drawProjectNumber(e.render, e.docCtx.viewOptions, e);
3113
- }
3114
3220
  /**
3115
3221
  * 绘制项目符号
3116
3222
  */
@@ -3188,8 +3294,6 @@ class ParagraphLineRectRenderObject extends BlockLineRectRenderObject {
3188
3294
  baseTopLine = 0;
3189
3295
  baseBottomLine = 0;
3190
3296
  startX = 0;
3191
- render(e) {
3192
- }
3193
3297
  clone() {
3194
3298
  const cloneRender = new ParagraphLineRectRenderObject(this.element);
3195
3299
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -3301,9 +3405,8 @@ class DocumentElement extends BlockContainerElement {
3301
3405
  clone() {
3302
3406
  const clone = new DocumentElement();
3303
3407
  this.props.clone(clone.props);
3304
- for (let i = 0; i < this.length; i++) {
3305
- clone.addChild(this.getChild(i).clone(true));
3306
- }
3408
+ cloneElementBase(this, clone);
3409
+ cloneChildren(this, clone, true);
3307
3410
  return clone;
3308
3411
  }
3309
3412
  /**
@@ -3391,21 +3494,6 @@ class DocumentRenderObject extends BlockContainerRenderObject {
3391
3494
  }
3392
3495
  headerLine;
3393
3496
  footerLine;
3394
- render(e) {
3395
- const { render, position, docCtx: { viewOptions } } = e;
3396
- const { width: docWidth, height: docHeight } = viewOptions.docPageSettings;
3397
- render.overlaysContext.fillRect(position.x, position.y, docWidth, this.rect.height, 'white', 5, 'black');
3398
- e.render.tran(() => {
3399
- e.render.contentContext.ctx.fillStyle = e.docCtx.viewOptions.defaultColor;
3400
- this.checkPrintMode(e);
3401
- e.nextRender();
3402
- this.drawCopyRight(viewOptions, render, position);
3403
- this.drawDocPageNum(render, viewOptions, position);
3404
- //绘制文档边距线
3405
- this.drawMarginLine(position, render, docWidth, docHeight);
3406
- this.drawWatermark(render, viewOptions, position);
3407
- });
3408
- }
3409
3497
  /**
3410
3498
  * 打印模式检查
3411
3499
  * 如果是续打模式,需要进行裁剪打印范围,页眉页脚都不需要打印
@@ -3695,6 +3783,7 @@ class InlineGroupInputElement extends InlineGroupElement {
3695
3783
  }
3696
3784
  cloneSelf(data, constr) {
3697
3785
  const clone = new constr();
3786
+ cloneElementBase(this, clone);
3698
3787
  this.props['clone'](clone.props);
3699
3788
  //cloneFunc.apply(this, clone.props);
3700
3789
  if (data) {
@@ -3817,7 +3906,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
3817
3906
  const code = parser(this.props.expression);
3818
3907
  this.expressFn = new Function(`with(this){ ${code} }`);
3819
3908
  }
3820
- this.expressFn.bind(data.parser)();
3909
+ this.expressFn.bind(data.execute)();
3821
3910
  //this.expressFn();
3822
3911
  }
3823
3912
  catch (e) {
@@ -3841,45 +3930,6 @@ function getCurrOptions(ele) {
3841
3930
  return doc?.viewOptions;
3842
3931
  }
3843
3932
  class DataElementRenderObject extends InlineGroupRenderObject {
3844
- render(e) {
3845
- const { render, position, docCtx: { viewOptions } } = e;
3846
- this.paintPos = e.position;
3847
- //数据元不打印
3848
- if (!this.element.props.printable && render.drawMode === 'print') {
3849
- return;
3850
- }
3851
- render.contentContext.tran(() => {
3852
- //绘制数据元区域底色
3853
- let bgColor = '';
3854
- if (this.element.isMouseenter) {
3855
- bgColor = this.element.props.editable ? viewOptions.dataEleOverlaysColor : viewOptions.dataEleReadOnlyOverlayColor;
3856
- }
3857
- if (this.element.isFocused) {
3858
- bgColor = e.docCtx.viewOptions.dataEleFocusedBgColor;
3859
- }
3860
- if (this.element.errorTip) {
3861
- bgColor = viewOptions.dataEleErrorBgColor;
3862
- }
3863
- if (bgColor) {
3864
- render.contentContext.fillRect(position.x, position.y, this.rect.width, this.rect.height, bgColor);
3865
- }
3866
- if (this.element.props.secretBrowse && viewOptions.secretBrowse) {
3867
- render.contentContext.ctx.filter = "blur(10px)";
3868
- }
3869
- if (this.element.props.underline) {
3870
- const y = position.y + 2 + this.rect.height;
3871
- render.contentContext.strokeLines([{ x: position.x, y }, {
3872
- x: position.x + this.rect.width,
3873
- y
3874
- }], 1, '#595959');
3875
- }
3876
- e.nextRender();
3877
- this.drawCaption(e);
3878
- });
3879
- e.render.onRenderCompleted.subscribe(() => {
3880
- drawDecorator(e, this);
3881
- });
3882
- }
3883
3933
  exportHTML(event) {
3884
3934
  const node = super.exportHTML(event);
3885
3935
  exportDecoratorHTML(event, this);
@@ -4150,11 +4200,8 @@ class DocumentBodyElement extends BlockContainerElement {
4150
4200
  }
4151
4201
  clone(data) {
4152
4202
  const clone = new DocumentBodyElement();
4153
- if (data) {
4154
- for (let i = 0; i < this.length; i++) {
4155
- clone.addChild(this.getChild(i).clone(true));
4156
- }
4157
- }
4203
+ cloneElementBase(this, clone);
4204
+ cloneChildren(this, clone, data);
4158
4205
  return clone;
4159
4206
  }
4160
4207
  beginMeasure(data) {
@@ -4165,15 +4212,6 @@ class DocumentBodyElement extends BlockContainerElement {
4165
4212
  }
4166
4213
  }
4167
4214
  class DocumentBodyRenderObject extends MuiltBlockLineRenderObject {
4168
- render(e) {
4169
- const { render, position } = e;
4170
- render.tran(() => {
4171
- if (this.element.disableClick && render.drawMode === 'view') {
4172
- render.contentContext.setGlobalAlpha(0.5);
4173
- }
4174
- e.nextRender();
4175
- });
4176
- }
4177
4215
  clone(cloneData = true) {
4178
4216
  const cloneRender = new DocumentBodyRenderObject(this.element);
4179
4217
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4213,11 +4251,8 @@ class DocumentFooterElement extends BlockContainerElement {
4213
4251
  }
4214
4252
  clone(data) {
4215
4253
  const clone = new DocumentFooterElement();
4216
- if (data) {
4217
- for (let i = 0; i < this.length; i++) {
4218
- clone.addChild(this.getChild(i).clone(true));
4219
- }
4220
- }
4254
+ cloneElementBase(this, clone);
4255
+ cloneChildren(this, clone, data);
4221
4256
  return clone;
4222
4257
  }
4223
4258
  beginMeasure(data) {
@@ -4243,22 +4278,6 @@ class DocumentFooterElement extends BlockContainerElement {
4243
4278
  }
4244
4279
  }
4245
4280
  class DocumentFooterRenderObject extends BlockContainerRenderObject {
4246
- render(e) {
4247
- const { render, position } = e;
4248
- render.tran(() => {
4249
- //判断页眉是否为输入内容
4250
- const isFooterEmpty = ElementUtil.checkEmptyRenderContent(this);
4251
- if (this.element.disableClick && render.drawMode === 'view') {
4252
- if (isFooterEmpty) {
4253
- render.contentContext.setGlobalAlpha(0);
4254
- }
4255
- else {
4256
- render.contentContext.setGlobalAlpha(0.5);
4257
- }
4258
- }
4259
- e.nextRender();
4260
- });
4261
- }
4262
4281
  clone() {
4263
4282
  const cloneRender = new DocumentFooterRenderObject(this.element);
4264
4283
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4309,11 +4328,8 @@ class DocumentHeaderElement extends BlockContainerElement {
4309
4328
  }
4310
4329
  clone(data) {
4311
4330
  const clone = new DocumentHeaderElement();
4312
- if (data) {
4313
- for (let i = 0; i < this.length; i++) {
4314
- clone.addChild(this.getChild(i).clone(true));
4315
- }
4316
- }
4331
+ cloneElementBase(this, clone);
4332
+ cloneChildren(this, clone, data);
4317
4333
  return clone;
4318
4334
  }
4319
4335
  switchEditMode(evt) {
@@ -4339,27 +4355,6 @@ class DocumentHeaderElement extends BlockContainerElement {
4339
4355
  }
4340
4356
  }
4341
4357
  class DocumentHeaderRenderObject extends BlockContainerRenderObject {
4342
- render(e) {
4343
- const { render, position } = e;
4344
- render.tran(() => {
4345
- //判断页眉是否为输入内容
4346
- const isHeaderEmpty = ElementUtil.checkEmptyRenderContent(this);
4347
- //存在输入内容时,绘制页眉-页体分割线
4348
- if (!isHeaderEmpty || !this.element.disableClick) {
4349
- const headerLineY = this.rect.height;
4350
- render.contentContext.drawHoriLine(position.x, position.y + headerLineY, this.rect.width, 'black', 0.5);
4351
- }
4352
- if (this.element.disableClick && render.drawMode === 'view') {
4353
- if (isHeaderEmpty) {
4354
- render.contentContext.setGlobalAlpha(0);
4355
- }
4356
- else {
4357
- render.contentContext.setGlobalAlpha(0.5);
4358
- }
4359
- }
4360
- e.nextRender();
4361
- });
4362
- }
4363
4358
  clone() {
4364
4359
  const cloneRender = new DocumentHeaderRenderObject(this.element);
4365
4360
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -4432,6 +4427,7 @@ class PSymbolElement extends LeafElement {
4432
4427
  clone() {
4433
4428
  const clone = new PSymbolElement();
4434
4429
  clone.defaultHeight = this.defaultHeight;
4430
+ cloneElementBase(this, clone);
4435
4431
  return clone;
4436
4432
  }
4437
4433
  getSelfLength(pure) {
@@ -4439,13 +4435,6 @@ class PSymbolElement extends LeafElement {
4439
4435
  }
4440
4436
  }
4441
4437
  class PSymbolRenderObject extends LeafRenderObject {
4442
- render(e) {
4443
- const { render, position } = e;
4444
- if (render.drawMode === 'print' || !e.docCtx.viewOptions.showParaSymbol) {
4445
- return;
4446
- }
4447
- render.contentContext.drawText('↩', this.element.textProps, position.x, position.y, 20, this.rect.height);
4448
- }
4449
4438
  exportHTML(event) {
4450
4439
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4451
4440
  return null;
@@ -4520,11 +4509,8 @@ class TableCellElement extends BlockContainerElement {
4520
4509
  clone(data) {
4521
4510
  const clone = new TableCellElement();
4522
4511
  this.props.clone(clone.props);
4523
- if (data) {
4524
- for (let i = 0; i < this.length; i++) {
4525
- clone.addChild(this.getChild(i).clone(true));
4526
- }
4527
- }
4512
+ cloneElementBase(this, clone);
4513
+ cloneChildren(this, clone, data);
4528
4514
  return clone;
4529
4515
  }
4530
4516
  getCellWidth() {
@@ -4558,22 +4544,6 @@ class TableCellElement extends BlockContainerElement {
4558
4544
  }
4559
4545
  }
4560
4546
  class TableCellRenderObject extends InlineMuiltBlockLineRenderObject {
4561
- render(e) {
4562
- const { render, position } = e;
4563
- render.tran(() => {
4564
- render.contentContext.clip(position.x, position.y, this.rect.width, this.rect.height);
4565
- const { hMerge, vMerge, backgroundColor, diagonal } = this.element.props;
4566
- if (hMerge === 'continue' || vMerge === 'continue') {
4567
- render.contentContext.setGlobalAlpha(0);
4568
- render.overlaysContext.setGlobalAlpha(0);
4569
- }
4570
- if (backgroundColor && this.rect.width && this.rect.height) {
4571
- render.contentContext.fillRect(position.x, position.y, this.rect.width, this.rect.height, backgroundColor);
4572
- }
4573
- this.renderDiagonal(render, diagonal, position);
4574
- e.nextRender();
4575
- });
4576
- }
4577
4547
  /**
4578
4548
  * 绘制对角线
4579
4549
  * @private
@@ -4742,8 +4712,6 @@ class TableRowRenderObject extends MuiltBlockLineRenderObject {
4742
4712
  remeasureState = true;
4743
4713
  //当前行是否存在合并单元格
4744
4714
  hasMergeCells = undefined;
4745
- render(e) {
4746
- }
4747
4715
  clone() {
4748
4716
  const cloneRender = new TableRowRenderObject(this.element);
4749
4717
  cloneRender.remeasureState = this.remeasureState;
@@ -4772,17 +4740,6 @@ class DocumentContainerRender extends BlockContainerRenderObject {
4772
4740
  constructor() {
4773
4741
  super(null);
4774
4742
  }
4775
- render(e) {
4776
- const { render, nextRender, docCtx: { viewOptions } } = e;
4777
- const { viewSettings, docPageSettings, viewBackcolor, scale } = viewOptions;
4778
- render.clear();
4779
- //render.overlaysContext.fillRect(0, 0, viewSettings.width, viewSettings.height, viewBackcolor);
4780
- render.tran(() => {
4781
- render.overlaysContext.ctx.scale(scale, scale);
4782
- render.contentContext.ctx.scale(scale, scale);
4783
- nextRender();
4784
- });
4785
- }
4786
4743
  clone() {
4787
4744
  throw new Error("Method not implemented.");
4788
4745
  }
@@ -4861,6 +4818,7 @@ class TextGroupElement extends LeafElement {
4861
4818
  const clone = new TextGroupElement();
4862
4819
  this.props.clone(clone.props);
4863
4820
  clone.text = this.text;
4821
+ cloneElementBase(this, clone);
4864
4822
  return clone;
4865
4823
  }
4866
4824
  destroy() {
@@ -4899,17 +4857,6 @@ class TextGroupElement extends LeafElement {
4899
4857
  }
4900
4858
  class TextGroupRenderObject extends LeafRenderObject {
4901
4859
  textMeasures;
4902
- render(e) {
4903
- const { render, position } = e;
4904
- //null-text不打印
4905
- if (render.drawMode === 'print' && this.element.isDecorate) {
4906
- return;
4907
- }
4908
- if (this.element.props.border) {
4909
- render.contentContext.strokeRect(position.x, position.y, this.rect.width, this.rect.height);
4910
- }
4911
- render.contentContext.drawTextUnits(this, position.x, position.y + (this.rect.height - this.element.props.fontSize) / 2);
4912
- }
4913
4860
  constructor(element) {
4914
4861
  super(element);
4915
4862
  }
@@ -6597,11 +6544,8 @@ class TableElement extends BlockContainerElement {
6597
6544
  clone(data) {
6598
6545
  const clone = new TableElement();
6599
6546
  this.props.clone(clone.props);
6600
- if (data) {
6601
- for (let i = 0; i < this.length; i++) {
6602
- clone.addChild(this.getChild(i).clone(true));
6603
- }
6604
- }
6547
+ cloneElementBase(this, clone);
6548
+ cloneChildren(this, clone, data);
6605
6549
  return clone;
6606
6550
  }
6607
6551
  createRenderObject() {
@@ -6625,56 +6569,6 @@ class TableRenderObject extends MuiltBlockLineRenderObject {
6625
6569
  setRenderWidth(maxWidth) {
6626
6570
  super.setRenderWidth(maxWidth);
6627
6571
  }
6628
- render(e) {
6629
- const { render, position } = e;
6630
- //绘制表格线
6631
- const border = this.element.props.border;
6632
- if (border === 'none') {
6633
- return;
6634
- }
6635
- const lineDash = border === 'dashed' ? [2, 2] : [];
6636
- for (let i = 0; i < this.length; i++) {
6637
- const rowRender = this.getChild(i);
6638
- const rowPos = { x: rowRender.rect.x + position.x, y: rowRender.rect.y + position.y };
6639
- for (let j = 0; j < rowRender.length; j++) {
6640
- const cellRender = rowRender.getChild(j);
6641
- const cellPos = { x: cellRender.rect.x + rowPos.x, y: cellRender.rect.y + rowPos.y };
6642
- //绘制单元格上边框
6643
- if (i === 0) {
6644
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y, cellRender.rect.width, 1);
6645
- render.contentContext.fillLines([{ x: cellPos.x, y: cellPos.y }, {
6646
- x: cellPos.x + cellRender.rect.width,
6647
- y: cellPos.y
6648
- }], 1, '#000', lineDash);
6649
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y });
6650
- }
6651
- //绘制左边框
6652
- if (j === 0) {
6653
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y, 1, cellRender.rect.height);
6654
- render.contentContext.fillLines([{ x: cellPos.x, y: cellPos.y }, {
6655
- x: cellPos.x,
6656
- y: cellPos.y + cellRender.rect.height
6657
- }], 1, '#000', lineDash);
6658
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y }, { x: cellPos.x, y: cellPos.y + cellRender.rect.height });
6659
- }
6660
- //绘制右边框
6661
- //ctx.contentContext.fillRect(cellPos.x + cellRender.rect.width, cellPos.y, 1, cellRender.rect.height);
6662
- render.contentContext.fillLines([{
6663
- x: cellPos.x + cellRender.rect.width,
6664
- y: cellPos.y
6665
- }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height }], 1, '#000', lineDash);
6666
- //this.drawLine(ctx, { x: cellPos.x + cellRender.rect.width, y: cellPos.y }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height });
6667
- //绘制下边框
6668
- //ctx.contentContext.fillRect(cellPos.x, cellPos.y + cellRender.rect.height, cellRender.rect.width, 1);
6669
- render.contentContext.fillLines([{
6670
- x: cellPos.x,
6671
- y: cellPos.y + cellRender.rect.height
6672
- }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height }], 1, '#000', lineDash);
6673
- //this.drawLine(ctx, { x: cellPos.x, y: cellPos.y + cellRender.rect.height }, { x: cellPos.x + cellRender.rect.width, y: cellPos.y + cellRender.rect.height });
6674
- //cellRender.beginRender(ctx, { x: position.x + cellRender.offsetX, y: position.y + cellRender.offsetY });
6675
- }
6676
- }
6677
- }
6678
6572
  exportTableBorder() {
6679
6573
  //绘制表格线
6680
6574
  const border = this.element.props.border;
@@ -6940,6 +6834,7 @@ class CheckBoxElement extends LeafElement {
6940
6834
  }
6941
6835
  clone() {
6942
6836
  const clone = new CheckBoxElement();
6837
+ cloneElementBase(this, clone);
6943
6838
  this.props.clone(clone.props);
6944
6839
  return clone;
6945
6840
  }
@@ -6959,10 +6854,7 @@ class CheckBoxFactory extends ElementFactory {
6959
6854
  }
6960
6855
  }
6961
6856
  class CheckBoxRenderObject extends LeafRenderObject {
6962
- render(e) {
6963
- e.render.contentContext.drawCheckBox(e.position.x + 2, e.position.y, this.element.props.size, this.element.props.size, this.element.props.isChecked);
6964
- }
6965
- clone(cloneData = true) {
6857
+ clone() {
6966
6858
  const clone = new CheckBoxRenderObject(this.element);
6967
6859
  clone.rect = ElementUtil.cloneRect(this.rect);
6968
6860
  return clone;
@@ -7046,11 +6938,8 @@ class CommContentElement extends CommContentBaseElement {
7046
6938
  clone(data) {
7047
6939
  const clone = new CommContentElement();
7048
6940
  this.props.clone(clone.props);
7049
- if (data) {
7050
- for (let i = 0; i < this.length; i++) {
7051
- clone.addChild(this.getChild(i).clone(true));
7052
- }
7053
- }
6941
+ cloneElementBase(this, clone);
6942
+ cloneChildren(this, clone, data);
7054
6943
  return clone;
7055
6944
  }
7056
6945
  beginMeasure(data) {
@@ -7061,34 +6950,6 @@ class CommContentElement extends CommContentBaseElement {
7061
6950
  }
7062
6951
  }
7063
6952
  class CommContentRenderObject extends CommContentBaseRenderObject {
7064
- render(e) {
7065
- let borderColor = this.element.focus ? '#fa8c16' : '#ffd591';
7066
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, borderColor);
7067
- e.render.contentContext.fillRect(e.position.x, e.position.y, 8, this.rect.height, '#871400');
7068
- const docRender = ElementUtil.getParentRender(this.commMarkRender.render, DocumentRenderObject);
7069
- //获取审阅标记的绘制坐标
7070
- let commMarkPos = ElementUtil.getRenderAbsolutePaintPos(this.commMarkRender.render, {
7071
- x: 0,
7072
- y: -e.docCtx.viewOptions.pageOffset.y
7073
- });
7074
- const commMarkLinePos = ElementUtil.getParaLinePos(this.commMarkRender.render, commMarkPos);
7075
- commMarkPos.y = commMarkLinePos.y + 2;
7076
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, {
7077
- x: 0,
7078
- y: -e.docCtx.viewOptions.pageOffset.y
7079
- });
7080
- const marginLeft = commMarkPos.x - docRenderPos.x - docRender.padding.left;
7081
- const marginRight = e.docCtx.viewOptions.docPageSettings.width - marginLeft - docRender.padding.right * 2;
7082
- e.render.overlaysContext.drawDashLine([commMarkPos, {
7083
- x: commMarkPos.x + marginRight,
7084
- y: commMarkPos.y
7085
- }], [1, 1], 'red');
7086
- e.render.overlaysContext.drawDashLine([{
7087
- x: commMarkPos.x + marginRight,
7088
- y: commMarkPos.y
7089
- }, e.position], [1, 1], 'red');
7090
- this.renderTitle(e.render, e.position);
7091
- }
7092
6953
  exportHTML(event) {
7093
6954
  const t = super.exportHTML(event);
7094
6955
  t.children = [];
@@ -7355,20 +7216,11 @@ class CommentElement extends LeafElement {
7355
7216
  clone() {
7356
7217
  const clone = new CommentElement();
7357
7218
  this.props.clone(clone.props);
7219
+ cloneElementBase(this, clone);
7358
7220
  return clone;
7359
7221
  }
7360
7222
  }
7361
7223
  class CommentRenderObject extends LeafRenderObject {
7362
- //renderPos!: Position;
7363
- render(e) {
7364
- // if (!e.docCtx.viewOptions.showReviewWindow) {
7365
- // return;
7366
- // }
7367
- // this.renderPos = e.position;
7368
- // const paraLinePos = ElementUtil.getParaLinePos(this, {x: e.position.x, y: e.position.y});
7369
- // const color = '#ff4d4f';
7370
- // e.render.contentContext.fillRect(e.position.x - 1, paraLinePos.y, 2, paraLinePos.height, color)
7371
- }
7372
7224
  exportHTML(event) {
7373
7225
  const renderPos = { ...event.relativePagePos };
7374
7226
  const paraLinePos = ElementUtil.getParaLinePos(this, { x: renderPos.x, y: renderPos.y });
@@ -7514,11 +7366,8 @@ class ValidateElement extends CommContentBaseElement {
7514
7366
  clone(data) {
7515
7367
  const clone = new ValidateElement();
7516
7368
  this.props.clone(clone.props);
7517
- if (data) {
7518
- for (let i = 0; i < this.length; i++) {
7519
- clone.addChild(this.getChild(i).clone(true));
7520
- }
7521
- }
7369
+ cloneElementBase(this, clone);
7370
+ cloneChildren(this, clone, data);
7522
7371
  return clone;
7523
7372
  }
7524
7373
  setContent(content) {
@@ -7534,31 +7383,6 @@ class ValidateElement extends CommContentBaseElement {
7534
7383
  }
7535
7384
  }
7536
7385
  class ValidateRenderObject extends CommContentBaseRenderObject {
7537
- render(e) {
7538
- let borderColor = this.element.focus ? '#fa8c16' : '#ffd591';
7539
- e.render.contentContext.strokeRect(e.position.x, e.position.y, this.rect.width, this.rect.height, borderColor);
7540
- e.render.contentContext.fillRect(e.position.x, e.position.y, 8, this.rect.height, '#871400');
7541
- const docRender = ElementUtil.getParentRender(this.commMarkRender.render, DocumentRenderObject);
7542
- //获取审阅标记的绘制坐标
7543
- let commMarkPos = ElementUtil.getRenderAbsolutePaintPos(this.commMarkRender.render, {
7544
- x: 0,
7545
- y: -e.docCtx.viewOptions.pageOffset.y
7546
- });
7547
- const commMarkLinePos = ElementUtil.getParaLinePos(this.commMarkRender.render, commMarkPos);
7548
- commMarkPos.y = commMarkLinePos.y + 2;
7549
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender, { x: 0, y: -e.docCtx.viewOptions.pageOffset.y });
7550
- const marginLeft = commMarkPos.x - docRenderPos.x - docRender.padding.left;
7551
- const marginRight = e.docCtx.viewOptions.docPageSettings.width - marginLeft - docRender.padding.right * 2;
7552
- e.render.overlaysContext.drawDashLine([commMarkPos, {
7553
- x: commMarkPos.x + marginRight,
7554
- y: commMarkPos.y
7555
- }], [1, 1], 'red');
7556
- e.render.overlaysContext.drawDashLine([{
7557
- x: commMarkPos.x + marginRight,
7558
- y: commMarkPos.y
7559
- }, e.position], [1, 1], 'red');
7560
- this.renderTitle(e.render, e.position);
7561
- }
7562
7386
  renderTitle(ctx, position) {
7563
7387
  const topPadding = 24;
7564
7388
  const textProps = new TextProps();
@@ -8471,6 +8295,7 @@ class DataElementBarcode extends DataElementLeaf {
8471
8295
  clone(data) {
8472
8296
  const clone = new DataElementBarcode();
8473
8297
  this.props.clone(clone.props);
8298
+ cloneElementBase(this, clone);
8474
8299
  return clone;
8475
8300
  }
8476
8301
  setValue(val) {
@@ -8484,40 +8309,11 @@ class DataElementBarcode extends DataElementLeaf {
8484
8309
  }
8485
8310
  }
8486
8311
  class DataElementBarcodeRenderObject extends ResizeLeafRenderObject {
8487
- render(e) {
8488
- // const barcodeEle = this.element as DataElementBarcode;
8489
- // barcodeEle.drawBarcode(e.render, e.position);
8490
- }
8491
8312
  clone() {
8492
8313
  const clone = new DataElementBarcodeRenderObject(this.element);
8493
8314
  clone.rect = ElementUtil.cloneRect(this.rect);
8494
8315
  return clone;
8495
8316
  }
8496
- pagePaintCompleted(e) {
8497
- if (this.element.isFocused) {
8498
- const { render, position: pos } = e;
8499
- const { width, height } = this.rect;
8500
- render.contentContext.strokeRect(pos.x, pos.y, this.rect.width, this.rect.height, '#1890ff', 0.5);
8501
- this.drawResizeCircle(render, pos.x, pos.y);
8502
- this.drawResizeCircle(render, pos.x + width, pos.y);
8503
- this.drawResizeCircle(render, pos.x, pos.y + height);
8504
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
8505
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
8506
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
8507
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
8508
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
8509
- }
8510
- }
8511
- drawResizeCircle(ctx, x, y) {
8512
- const ctxNative = ctx.contentContext.ctx;
8513
- ctxNative.save();
8514
- ctxNative.fillStyle = '#69c0ff';
8515
- ctxNative.beginPath();
8516
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
8517
- ctxNative.closePath();
8518
- ctxNative.fill();
8519
- ctxNative.restore();
8520
- }
8521
8317
  exportHTML(event) {
8522
8318
  const t = super.exportHTML(event);
8523
8319
  if (this.element.props.type === 'qrcode') {
@@ -8653,6 +8449,7 @@ class DataElementCheck extends DataElementLeaf {
8653
8449
  clone(data) {
8654
8450
  const clone = new DataElementCheck();
8655
8451
  this.props.clone(clone.props);
8452
+ cloneElementBase(this, clone);
8656
8453
  return clone;
8657
8454
  }
8658
8455
  setValue(val) {
@@ -8682,27 +8479,6 @@ class DataElementCheckRenderObject extends LeafRenderObject {
8682
8479
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
8683
8480
  return cloneRender;
8684
8481
  }
8685
- render(e) {
8686
- const { render, position } = e;
8687
- const element = this.element;
8688
- if (element.props.drawStateChar) {
8689
- const font = `${element.props.size - 2}px 微软雅黑`;
8690
- const str = element.props.checked ? element.props.trueChar : element.props.falseChar;
8691
- const color = element.props.checked ? element.props.trueStateColor : element.props.falseStateColor;
8692
- e.render.contentContext.drawText2(str, font, color, position.x, position.y, element.props.size, element.props.size);
8693
- if (element.props.border) {
8694
- e.render.contentContext.strokeRect(position.x + 2, position.y, element.props.size, element.props.size);
8695
- }
8696
- }
8697
- else {
8698
- if (element.props.multiSelect) {
8699
- render.contentContext.drawCheckBox(position.x + 2, position.y, element.props.size, element.props.size, element.props.checked);
8700
- }
8701
- else {
8702
- render.contentContext.drawRadioBox(position.x + 2, position.y, element.props.size, element.props.size, element.props.checked);
8703
- }
8704
- }
8705
- }
8706
8482
  exportHTML(event) {
8707
8483
  const t = super.exportHTML(event);
8708
8484
  const props = this.element.props;
@@ -8993,12 +8769,6 @@ class DataElementGroupElement extends InlineGroupInputElement {
8993
8769
  }
8994
8770
  }
8995
8771
  class DataElementGroupRenderObject extends InlineGroupRenderObject {
8996
- render(e) {
8997
- this.paintPos = e.position;
8998
- e.render.onRenderCompleted.subscribe(() => {
8999
- drawDecorator(e, this);
9000
- });
9001
- }
9002
8772
  clone() {
9003
8773
  const cloneRender = new DataElementGroupRenderObject(this.element);
9004
8774
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -9050,6 +8820,7 @@ class DataElementImage extends DataElementLeaf {
9050
8820
  clone(data) {
9051
8821
  const clone = new DataElementImage();
9052
8822
  this.props.clone(clone.props);
8823
+ cloneElementBase(this, clone);
9053
8824
  return clone;
9054
8825
  }
9055
8826
  destroy() {
@@ -9066,38 +8837,11 @@ class DataElementImage extends DataElementLeaf {
9066
8837
  }
9067
8838
  }
9068
8839
  class DataImageRenderObject extends ResizeLeafRenderObject {
9069
- render(e) {
9070
- }
9071
8840
  clone() {
9072
8841
  const clone = new DataImageRenderObject(this.element);
9073
8842
  clone.rect = ElementUtil.cloneRect(this.rect);
9074
8843
  return clone;
9075
8844
  }
9076
- pagePaintCompleted(e) {
9077
- if (this.element.isFocused) {
9078
- const { render, position: pos } = e;
9079
- const { width, height } = this.rect;
9080
- render.contentContext.strokeRect(pos.x, pos.y, this.rect.width, this.rect.height, '#1890ff', 0.5);
9081
- this.drawResizeCircle(render, pos.x, pos.y);
9082
- this.drawResizeCircle(render, pos.x + width, pos.y);
9083
- this.drawResizeCircle(render, pos.x, pos.y + height);
9084
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
9085
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
9086
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
9087
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
9088
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
9089
- }
9090
- }
9091
- drawResizeCircle(ctx, x, y) {
9092
- const ctxNative = ctx.contentContext.ctx;
9093
- ctxNative.save();
9094
- ctxNative.fillStyle = '#69c0ff';
9095
- ctxNative.beginPath();
9096
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
9097
- ctxNative.closePath();
9098
- ctxNative.fill();
9099
- ctxNative.restore();
9100
- }
9101
8845
  exportHTML(event) {
9102
8846
  const t = super.exportHTML(event);
9103
8847
  t.children = [{
@@ -9328,18 +9072,11 @@ class BreakElement extends LeafElement {
9328
9072
  }
9329
9073
  clone() {
9330
9074
  const clone = new BreakElement();
9331
- //clone.renderCtx = this.renderCtx;
9075
+ cloneElementBase(this, clone);
9332
9076
  return clone;
9333
9077
  }
9334
9078
  }
9335
9079
  class BreakRenderObject extends LeafRenderObject {
9336
- render(e) {
9337
- const { render, position } = e;
9338
- if (render.drawMode === 'print') {
9339
- return;
9340
- }
9341
- render.contentContext.drawText('↓', this.element.textProps, position.x, position.y, 20, this.rect.height);
9342
- }
9343
9080
  exportHTML(event) {
9344
9081
  if (!event.options.showEnterSymbol || event.mode === 'print') {
9345
9082
  return null;
@@ -9505,8 +9242,6 @@ class FillNullSpaceRenderObject extends LeafRenderObject {
9505
9242
  super(null);
9506
9243
  this.disableClick = true;
9507
9244
  }
9508
- render(e) {
9509
- }
9510
9245
  clone() {
9511
9246
  const clone = new FillNullSpaceRenderObject();
9512
9247
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -9558,20 +9293,12 @@ class DocumentBodyPartElement extends BlockContainerElement {
9558
9293
  clone(data) {
9559
9294
  const clone = new DocumentBodyPartElement();
9560
9295
  clone.props.partId = this.props.partId;
9561
- if (data) {
9562
- for (let i = 0; i < this.length; i++) {
9563
- clone.addChild(this.getChild(i).clone(true));
9564
- }
9565
- }
9296
+ cloneElementBase(this, clone);
9297
+ cloneChildren(this, clone, data);
9566
9298
  return clone;
9567
9299
  }
9568
9300
  }
9569
9301
  class DocumentBodyPartRenderObject extends MuiltBlockLineRenderObject {
9570
- render(e) {
9571
- const { render, position } = e;
9572
- const bgColor = (this.element.isFocused || this.element.isMouseenter) ? '#d9d9d9' : '#ffffff';
9573
- render.overlaysContext.fillRect(position.x - 2, position.y - 2, this.rect.width + 4, this.rect.height + 4, bgColor, 5, 'black');
9574
- }
9575
9302
  clone(cloneData = true) {
9576
9303
  const cloneRender = new DocumentBodyPartRenderObject(this.element);
9577
9304
  cloneRender.rect = ElementUtil.cloneRect(this.rect);
@@ -9665,6 +9392,7 @@ class DataElementMH extends DataElementLeaf {
9665
9392
  clone(data) {
9666
9393
  const element = new DataElementMH();
9667
9394
  this.props.clone(element.props);
9395
+ cloneElementBase(this, element);
9668
9396
  return element;
9669
9397
  }
9670
9398
  getCurrentLayoutItem() {
@@ -9711,9 +9439,6 @@ function getMHItem(kind) {
9711
9439
  return mhLayoutItems[kindIndex];
9712
9440
  }
9713
9441
  class DataRenderMH extends LeafRenderObject {
9714
- render(e) {
9715
- renderMH(this.element, e.render, e.position, true);
9716
- }
9717
9442
  exportHTML(event) {
9718
9443
  const t = super.exportHTML(event);
9719
9444
  const children = [];
@@ -9913,6 +9638,152 @@ function renderMHHTML(event, element, isPaint, nodes = []) {
9913
9638
  }
9914
9639
  }
9915
9640
 
9641
+ const fontSize = 12;
9642
+ const verPadding = 2;
9643
+ /**
9644
+ * 恒牙牙位图
9645
+ */
9646
+ class PermanentTeethElement extends DataElementLeaf {
9647
+ constructor() {
9648
+ super('permanent-teeth');
9649
+ this.props = new PermanentTeethProps();
9650
+ this.props.topLeft = '';
9651
+ this.props.topRight = '';
9652
+ this.props.bottomLeft = '';
9653
+ this.props.bottomRight = '';
9654
+ }
9655
+ setValue(val) {
9656
+ if (typeof val === 'string' && val) {
9657
+ const items = val.split(';');
9658
+ if (items.length >= 4) {
9659
+ this.props.topLeft = items[0];
9660
+ this.props.topRight = items[1];
9661
+ this.props.bottomLeft = items[2];
9662
+ this.props.bottomRight = items[3];
9663
+ }
9664
+ }
9665
+ else if (typeof val === 'object') {
9666
+ this.props.topLeft = val?.topLeft ?? '';
9667
+ this.props.topRight = val?.topRight ?? '';
9668
+ this.props.bottomLeft = val?.bottomLeft ?? '';
9669
+ this.props.bottomRight = val?.bottomRight ?? '';
9670
+ }
9671
+ }
9672
+ getValue() {
9673
+ const { topLeft, topRight, bottomLeft, bottomRight } = this.props;
9674
+ return `${topLeft};${topRight};${bottomLeft};${bottomRight}`;
9675
+ }
9676
+ clone(data) {
9677
+ const clone = new PermanentTeethElement();
9678
+ clone.props = this.props.clone();
9679
+ cloneElementBase(this, clone);
9680
+ return clone;
9681
+ }
9682
+ createRenderObject(data) {
9683
+ const clone = new PermanentTeethRenderObject(this);
9684
+ clone.rect.width = 150;
9685
+ //字体大小*2+上下间距2*2
9686
+ clone.rect.height = fontSize * 2 + verPadding * 2;
9687
+ //clone.rect= ElementUtil.cloneRect(this.rect);
9688
+ return clone;
9689
+ }
9690
+ serialize(viewOptions) {
9691
+ return {
9692
+ type: this.type,
9693
+ props: this.props.getSerializeProps(viewOptions)
9694
+ };
9695
+ }
9696
+ }
9697
+ class PermanentTeethRenderObject extends LeafRenderObject {
9698
+ clone() {
9699
+ const clone = new PermanentTeethRenderObject(this.element);
9700
+ clone.rect = ElementUtil.cloneRect(this.rect);
9701
+ return clone;
9702
+ }
9703
+ // measure(): { width: number, height: number } {
9704
+ // const ele = this.element;
9705
+ //
9706
+ // }
9707
+ exportHTML(event) {
9708
+ const ele = this.element;
9709
+ const g = super.exportHTML(event);
9710
+ const contentHorPadding = 4;
9711
+ g.children = [];
9712
+ // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
9713
+ // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
9714
+ //
9715
+ g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
9716
+ g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
9717
+ const getSvgText = (text, x, y) => {
9718
+ return {
9719
+ sel: 'text',
9720
+ text: text,
9721
+ data: {
9722
+ ns: "http://www.w3.org/2000/svg",
9723
+ attrs: {
9724
+ 'dominant-baseline': 'hanging',
9725
+ 'font-family': 'Arial',
9726
+ 'font-size': fontSize,
9727
+ x,
9728
+ y,
9729
+ }
9730
+ },
9731
+ };
9732
+ };
9733
+ const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
9734
+ fontSize: fontSize,
9735
+ fontName: 'Arial'
9736
+ });
9737
+ const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
9738
+ fontSize: fontSize,
9739
+ fontName: 'Arial'
9740
+ });
9741
+ g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
9742
+ g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
9743
+ g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
9744
+ g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
9745
+ return g;
9746
+ }
9747
+ }
9748
+ class PermanentTeethFactory extends ElementFactory {
9749
+ match(type) {
9750
+ return type === 'permanent-teeth';
9751
+ }
9752
+ createElement(data) {
9753
+ const ele = new PermanentTeethElement();
9754
+ ele.props.bottomLeft = data.props?.bottomLeft ?? '';
9755
+ ele.props.bottomRight = data.props?.bottomRight ?? '';
9756
+ ele.props.topLeft = data.props?.topLeft ?? '';
9757
+ ele.props.topRight = data.props?.topRight ?? '';
9758
+ return ele;
9759
+ }
9760
+ }
9761
+ /**
9762
+ * 恒牙牙位图属性
9763
+ */
9764
+ class PermanentTeethProps extends INotifyPropertyChanged {
9765
+ topLeft;
9766
+ topRight;
9767
+ bottomLeft;
9768
+ bottomRight;
9769
+ getSerializeProps(viewOptions) {
9770
+ return {
9771
+ topLeft: this.topLeft,
9772
+ topRight: this.topRight,
9773
+ bottomLeft: this.bottomLeft,
9774
+ bottomRight: this.bottomRight,
9775
+ };
9776
+ }
9777
+ clone(dest) {
9778
+ dest = dest || new PermanentTeethProps();
9779
+ dest.topLeft = this.topLeft;
9780
+ dest.topRight = this.topRight;
9781
+ dest.bottomLeft = this.bottomLeft;
9782
+ dest.bottomRight = this.bottomRight;
9783
+ return dest;
9784
+ }
9785
+ }
9786
+
9916
9787
  class PictureElement extends LeafElement {
9917
9788
  //props: PictureProps;
9918
9789
  status = 'no';
@@ -9941,6 +9812,7 @@ class PictureElement extends LeafElement {
9941
9812
  clone(data) {
9942
9813
  const clone = new PictureElement();
9943
9814
  this.props.clone(clone.props);
9815
+ cloneElementBase(this, clone);
9944
9816
  return clone;
9945
9817
  }
9946
9818
  destroy() {
@@ -9948,36 +9820,11 @@ class PictureElement extends LeafElement {
9948
9820
  }
9949
9821
  }
9950
9822
  class PictureRenderObject extends ResizeLeafRenderObject {
9951
- render(e) {
9952
- }
9953
9823
  clone() {
9954
9824
  const clone = new PictureRenderObject(this.element);
9955
9825
  clone.rect = ElementUtil.cloneRect(this.rect);
9956
9826
  return clone;
9957
9827
  }
9958
- pagePaintCompleted(e) {
9959
- if (this.element.isFocused) {
9960
- const { render, position: pos } = e;
9961
- const { width, height } = this.rect;
9962
- render.contentContext.strokeRect(pos.x, pos.y, width, height, '#1890ff', 0.5);
9963
- this.drawResizeCircle(render, pos.x, pos.y);
9964
- this.drawResizeCircle(render, pos.x + width, pos.y);
9965
- this.drawResizeCircle(render, pos.x, pos.y + height);
9966
- this.drawResizeCircle(render, pos.x + width, pos.y + height);
9967
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y);
9968
- this.drawResizeCircle(render, pos.x + (Math.floor(width / 2)), pos.y + height);
9969
- this.drawResizeCircle(render, pos.x, pos.y + (Math.floor(height / 2)));
9970
- this.drawResizeCircle(render, pos.x + width, pos.y + (Math.floor(height / 2)));
9971
- }
9972
- }
9973
- drawResizeCircle(ctx, x, y) {
9974
- const ctxNative = ctx.contentContext.ctx;
9975
- ctxNative.fillStyle = '#69c0ff';
9976
- ctxNative.beginPath();
9977
- ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
9978
- ctxNative.closePath();
9979
- ctxNative.fill();
9980
- }
9981
9828
  exportHTML(event) {
9982
9829
  const picElement = this.element;
9983
9830
  const picProps = picElement.props;
@@ -10091,6 +9938,7 @@ class RadioBoxElement extends LeafElement {
10091
9938
  clone() {
10092
9939
  const clone = new RadioBoxElement();
10093
9940
  this.props.clone(clone.props);
9941
+ cloneElementBase(this, clone);
10094
9942
  return clone;
10095
9943
  }
10096
9944
  }
@@ -10109,10 +9957,6 @@ class RadioBoxFactory extends ElementFactory {
10109
9957
  }
10110
9958
  }
10111
9959
  class RadioBoxRenderObject extends LeafRenderObject {
10112
- render(e) {
10113
- const { render, position } = e;
10114
- render.contentContext.drawRadioBox(position.x + 2, position.y, this.element.props.size, this.element.props.size, this.element.props.isChecked);
10115
- }
10116
9960
  clone(cloneData = true) {
10117
9961
  const clone = new RadioBoxRenderObject(this.element);
10118
9962
  clone.rect = ElementUtil.cloneRect(this.rect);
@@ -10146,18 +9990,11 @@ class PageBreakElement extends LeafElement {
10146
9990
  }
10147
9991
  clone() {
10148
9992
  const clone = new PageBreakElement();
10149
- //clone.renderCtx = this.renderCtx;
9993
+ cloneElementBase(this, clone);
10150
9994
  return clone;
10151
9995
  }
10152
9996
  }
10153
9997
  class PageBreakRenderObject extends LeafRenderObject {
10154
- render(e) {
10155
- const { render, position } = e;
10156
- if (render.drawMode === 'print') {
10157
- return;
10158
- }
10159
- render.contentContext.drawText('↩', this.element.textProps, position.x, position.y, 20, this.rect.height);
10160
- }
10161
9998
  clone() {
10162
9999
  const render = new PageBreakRenderObject(this.element);
10163
10000
  render.rect = ElementUtil.cloneRect(this.rect);
@@ -10190,17 +10027,12 @@ class TabElement extends LeafElement {
10190
10027
  };
10191
10028
  }
10192
10029
  clone() {
10193
- return new TabElement();
10030
+ const clone = new TabElement();
10031
+ cloneElementBase(this, clone);
10032
+ return clone;
10194
10033
  }
10195
10034
  }
10196
10035
  class TabRenderObject extends LeafRenderObject {
10197
- render(e) {
10198
- const { render, position } = e;
10199
- if (render.drawMode === 'print') {
10200
- return;
10201
- }
10202
- //render.contentContext.fillRect(position.x,position.y,this.rect.width,this.rect.height,'red');
10203
- }
10204
10036
  clone() {
10205
10037
  const render = new TabRenderObject(this.element);
10206
10038
  render.rect = ElementUtil.cloneRect(this.rect);
@@ -10766,6 +10598,116 @@ class TableSplitCell {
10766
10598
  }
10767
10599
  }
10768
10600
 
10601
+ class SVGElement extends LeafElement {
10602
+ resizeable = true;
10603
+ constructor() {
10604
+ super('svg');
10605
+ this.props = new SVGProps();
10606
+ //this.addPropValueChangedSub(this.props);
10607
+ this.cursorType = 'move';
10608
+ this.focusable = true;
10609
+ }
10610
+ createRenderObject() {
10611
+ const render = new SVGRenderObject(this);
10612
+ render.rect.width = this.props.width;
10613
+ render.rect.height = this.props.height;
10614
+ return render;
10615
+ }
10616
+ serialize(options) {
10617
+ return {
10618
+ type: 'svg',
10619
+ props: {
10620
+ ...this.props.getSerializeProps(options)
10621
+ }
10622
+ };
10623
+ }
10624
+ clone(data) {
10625
+ const clone = new SVGElement();
10626
+ this.props.clone(clone.props);
10627
+ cloneElementBase(this, clone);
10628
+ return clone;
10629
+ }
10630
+ destroy() {
10631
+ super.destroy();
10632
+ }
10633
+ }
10634
+ class SVGRenderObject extends ResizeLeafRenderObject {
10635
+ clone() {
10636
+ const clone = new SVGRenderObject(this.element);
10637
+ clone.rect = ElementUtil.cloneRect(this.rect);
10638
+ return clone;
10639
+ }
10640
+ drawResizeCircle(ctx, x, y) {
10641
+ const ctxNative = ctx.contentContext.ctx;
10642
+ ctxNative.fillStyle = '#69c0ff';
10643
+ ctxNative.beginPath();
10644
+ ctxNative.arc(x, y, Math.floor(4 / 5 * 4), 0, 2 * Math.PI);
10645
+ ctxNative.closePath();
10646
+ ctxNative.fill();
10647
+ }
10648
+ exportHTML(event) {
10649
+ const props = this.element.props;
10650
+ const t = super.exportHTML(event);
10651
+ t.children = [{
10652
+ sel: 'svg',
10653
+ data: {
10654
+ ns: "http://www.w3.org/2000/svg",
10655
+ attrs: {
10656
+ width: this.rect.width,
10657
+ height: this.rect.height
10658
+ }
10659
+ },
10660
+ children: [{
10661
+ sel: 'image',
10662
+ data: {
10663
+ ns: "http://www.w3.org/2000/svg",
10664
+ attrs: {
10665
+ "xlink:href": props.value,
10666
+ width: Math.min(this.rect.width, this.rect.height),
10667
+ height: Math.min(this.rect.width, this.rect.height)
10668
+ }
10669
+ }
10670
+ }]
10671
+ }];
10672
+ //绘制拖动圆圈
10673
+ if (this.element.isFocused) {
10674
+ const { width, height } = this.rect;
10675
+ const circlePoints = [{ x: 0, y: 0 }, { x: width, y: 0 }, { x: 0, y: height }, { x: width, y: height }, { x: Math.floor(width / 2), y: 0 }, { x: Math.floor(width / 2), y: height }, { x: 0, y: Math.floor(height / 2) }, { x: width, y: Math.floor(height / 2) }];
10676
+ circlePoints.forEach((p) => {
10677
+ t.children.push({
10678
+ sel: 'circle',
10679
+ data: {
10680
+ ns: "http://www.w3.org/2000/svg",
10681
+ attrs: {
10682
+ cx: p.x,
10683
+ cy: p.y,
10684
+ r: Math.floor(4 / 5 * 4),
10685
+ fill: '#69c0ff'
10686
+ }
10687
+ }
10688
+ });
10689
+ });
10690
+ }
10691
+ return t;
10692
+ }
10693
+ }
10694
+ class SVGFactory extends ElementFactory {
10695
+ match(type) {
10696
+ return type === 'svg';
10697
+ }
10698
+ createElement(data) {
10699
+ const props = data.props;
10700
+ const pic = new SVGElement();
10701
+ const picProps = pic.props;
10702
+ picProps.width = props.width;
10703
+ picProps.height = props.height;
10704
+ picProps.value = props.value;
10705
+ picProps.title = props.title;
10706
+ pic.props = picProps;
10707
+ return pic;
10708
+ }
10709
+ }
10710
+
10769
10711
  class ElementSerialize {
10770
10712
  /**
10771
10713
  * 将当前文档对象构建并输出到标准的JSON对象
@@ -10809,6 +10751,9 @@ class ElementSerialize {
10809
10751
  if (element.props && element.props['__attachedProperty'] && !result.props['__attachedProperty']) {
10810
10752
  result.props['__attachedProperty'] = CommonUtil.cloneValue(element.props['__attachedProperty']);
10811
10753
  }
10754
+ if (element.attribute) {
10755
+ result['attribute'] = this.serializeAttribute(element);
10756
+ }
10812
10757
  return result;
10813
10758
  }
10814
10759
  static serializeString(element, options = { all: false }) {
@@ -10818,6 +10763,9 @@ class ElementSerialize {
10818
10763
  if (element instanceof TextGroupElement && !element.isDecorate) {
10819
10764
  return element.text;
10820
10765
  }
10766
+ if (element instanceof PSymbolElement) {
10767
+ return '\n';
10768
+ }
10821
10769
  if (element instanceof BranchElement) {
10822
10770
  const items = [];
10823
10771
  for (let i = 0; i < element.length; i++) {
@@ -10828,6 +10776,21 @@ class ElementSerialize {
10828
10776
  }
10829
10777
  return "";
10830
10778
  }
10779
+ static serializeAttribute(element) {
10780
+ if (element.attribute) {
10781
+ const result = {};
10782
+ for (const key in element.attribute) {
10783
+ if (element.attribute[key] !== undefined && element.attribute[key] !== null) {
10784
+ result[key] = element.attribute[key];
10785
+ }
10786
+ }
10787
+ if (Object.keys(result).length === 0) {
10788
+ return null;
10789
+ }
10790
+ return CommonUtil.cloneValue(result);
10791
+ }
10792
+ return null;
10793
+ }
10831
10794
  /**
10832
10795
  * 获取选中的结构
10833
10796
  * @param ss
@@ -10926,12 +10889,8 @@ class TrackRunElement extends InlineGroupElement {
10926
10889
  clone(data) {
10927
10890
  const clone = new TrackRunElement(this.type);
10928
10891
  this.props.clone(clone.props);
10929
- if (data) {
10930
- const length = this.length;
10931
- for (let i = 0; i < length; i++) {
10932
- clone.addChild(this.getChild(i).clone(true));
10933
- }
10934
- }
10892
+ cloneElementBase(this, clone);
10893
+ cloneChildren(this, clone, data);
10935
10894
  return clone;
10936
10895
  }
10937
10896
  createRenderObject(data) {
@@ -10968,32 +10927,6 @@ class TrackRunRenderObject extends InlineGroupRenderObject {
10968
10927
  constructor(ele) {
10969
10928
  super(ele);
10970
10929
  }
10971
- render(e) {
10972
- const { render, position, docCtx: { viewOptions } } = e;
10973
- render.tran(() => {
10974
- let fillColor = viewOptions.showTrackChanges ? this.element.type === 'ins-run' ? viewOptions.trackInsColor : viewOptions.trackDelColor : '';
10975
- if (fillColor) {
10976
- render.contentContext.ctx.fillStyle = fillColor;
10977
- }
10978
- e.nextRender();
10979
- });
10980
- const { x, y } = position;
10981
- //不显示痕迹
10982
- if (!viewOptions.showTrackChanges) {
10983
- return;
10984
- }
10985
- const color = this.element.type === 'ins-run' ? 'green' : 'red';
10986
- for (let i = 0; i < this.length; i++) {
10987
- const childRender = this.getChild(i);
10988
- const { rect } = childRender;
10989
- if (childRender.element && childRender.element.type === 'del-run') {
10990
- continue;
10991
- }
10992
- let lineY = y + rect.y + rect.height;
10993
- lineY = this.element.type === 'ins-run' ? lineY : lineY - rect.height / 2;
10994
- render.contentContext.drawHoriLine(x + rect.x, lineY, rect.width, color, 1);
10995
- }
10996
- }
10997
10930
  exportHTML(event) {
10998
10931
  const { options } = event;
10999
10932
  const t = super.exportHTML(event);
@@ -12556,9 +12489,9 @@ class ElementUtil {
12556
12489
  return this.getTextRenderOffset(render, x);
12557
12490
  }
12558
12491
  else {
12559
- if (render.element && render.element.type === 'psym') {
12560
- return 0;
12561
- }
12492
+ // if (render.element && render.element.type === 'psym') {
12493
+ // return 0;
12494
+ // }
12562
12495
  return (render.rect.width / 2) >= x ? 0 : 1;
12563
12496
  }
12564
12497
  }
@@ -12841,6 +12774,26 @@ class ElementUtil {
12841
12774
  ss.resetRange(ele.getChild(ele.length - 2), -1);
12842
12775
  }
12843
12776
  }
12777
+ static setEleAttribute(ele, attr, value) {
12778
+ if (!ele.attribute) {
12779
+ ele.attribute = {};
12780
+ }
12781
+ if (ele.attribute[attr] === value) {
12782
+ return;
12783
+ }
12784
+ ele.attribute[attr] = value;
12785
+ }
12786
+ static getEleAttribute(ele, attr) {
12787
+ if (ele.attribute) {
12788
+ return ele.attribute[attr];
12789
+ }
12790
+ return undefined;
12791
+ }
12792
+ static removeEleAttribute(ele, attr) {
12793
+ if (ele.attribute) {
12794
+ delete ele.attribute[attr];
12795
+ }
12796
+ }
12844
12797
  }
12845
12798
 
12846
12799
  class RenderContext {
@@ -13288,12 +13241,12 @@ class ElementPaint {
13288
13241
  }
13289
13242
  }
13290
13243
  });
13291
- docContainer.render({
13292
- render: this.renderCtx,
13293
- position: { x: docContainer.rect.x, y: docContainer.rect.y },
13294
- nextRender: nextRenderFn,
13295
- docCtx: this.docCtx
13296
- });
13244
+ // docContainer.render({
13245
+ // render: this.renderCtx,
13246
+ // position: { x: docContainer.rect.x, y: docContainer.rect.y },
13247
+ // nextRender: nextRenderFn,
13248
+ // docCtx: this.docCtx
13249
+ // })
13297
13250
  nextRenderFn();
13298
13251
  const { scale, viewSettings: { width, height } } = this.viewOptions;
13299
13252
  while (this.renderCtx.onRenderCompleted.subs.length > 0) {
@@ -13322,25 +13275,25 @@ class ElementPaint {
13322
13275
  this.drawRenderObject(child, currPosition, inViewPort);
13323
13276
  }
13324
13277
  });
13325
- const renderData = {
13278
+ ({
13326
13279
  position: currPosition,
13327
13280
  nextRender: nextRenderFn,
13328
13281
  render: this.renderCtx,
13329
13282
  docCtx: this.docCtx
13330
- };
13331
- renderObject.render(renderData);
13283
+ });
13284
+ //renderObject.render(renderData);
13332
13285
  nextRenderFn();
13333
13286
  }
13334
13287
  }
13335
13288
  else if (renderObject instanceof LeafRenderObject) {
13336
13289
  if (inViewPort) {
13337
- const renderData = {
13290
+ ({
13338
13291
  position: currPosition,
13339
13292
  nextRender: () => { },
13340
13293
  render: this.renderCtx,
13341
13294
  docCtx: this.docCtx
13342
- };
13343
- renderObject.render(renderData);
13295
+ });
13296
+ //renderObject.render(renderData);
13344
13297
  }
13345
13298
  }
13346
13299
  //处理选中拖蓝
@@ -13393,14 +13346,14 @@ class ElementPaint {
13393
13346
  * 触发页面绘制结束事件
13394
13347
  */
13395
13348
  invokedPagePaintCompleted(renderObject, parent) {
13396
- const { x: rx, y: ry, width: rw, height: rh } = renderObject.rect;
13397
- const currPosition = { x: rx + parent.x, y: ry + parent.y };
13398
- renderObject.pagePaintCompleted({ render: this.renderCtx, position: currPosition, docCtx: this.docCtx });
13399
- if (renderObject instanceof BranchRenderObject) {
13400
- for (let i = 0; i < renderObject.length; i++) {
13401
- this.invokedPagePaintCompleted(renderObject.getChild(i), currPosition);
13402
- }
13403
- }
13349
+ // const { x: rx, y: ry, width: rw, height: rh } = renderObject.rect;
13350
+ // const currPosition = { x: rx + parent.x, y: ry + parent.y };
13351
+ // renderObject.pagePaintCompleted({ render: this.renderCtx, position: currPosition, docCtx: this.docCtx })
13352
+ // if (renderObject instanceof BranchRenderObject) {
13353
+ // for (let i = 0; i < renderObject.length; i++) {
13354
+ // this.invokedPagePaintCompleted(renderObject.getChild(i), currPosition);
13355
+ // }
13356
+ // }
13404
13357
  }
13405
13358
  static drawPage(renderCtx, docCtx, renderObject, parent) {
13406
13359
  const { x: rx, y: ry } = renderObject.rect;
@@ -13412,24 +13365,9 @@ class ElementPaint {
13412
13365
  this.drawPage(renderCtx, docCtx, child, currPosition);
13413
13366
  }
13414
13367
  });
13415
- const renderData = {
13416
- position: currPosition,
13417
- nextRender: nextRenderFn,
13418
- render: renderCtx,
13419
- docCtx
13420
- };
13421
- renderObject.render(renderData);
13368
+ //renderObject.render(renderData);
13422
13369
  nextRenderFn();
13423
13370
  }
13424
- else if (renderObject instanceof LeafRenderObject) {
13425
- const renderData = {
13426
- position: currPosition,
13427
- nextRender: () => { },
13428
- render: renderCtx,
13429
- docCtx: docCtx
13430
- };
13431
- renderObject.render(renderData);
13432
- }
13433
13371
  }
13434
13372
  }
13435
13373
 
@@ -13490,10 +13428,7 @@ class EditorContext {
13490
13428
  isDirty = false;
13491
13429
  cursorRect;
13492
13430
  _document;
13493
- //文档刷新的订阅事件
13494
- //refSub!: Subscription;
13495
13431
  syncRefresh;
13496
- //imageLoader: IImageLoader;
13497
13432
  dynamicFunc;
13498
13433
  docChange;
13499
13434
  clearPrevDocCb;
@@ -13547,6 +13482,7 @@ class EditorContext {
13547
13482
  //this.imageLoader.clear();
13548
13483
  this.dynamicFunc.destroyScripts();
13549
13484
  this.isDirty = false;
13485
+ //this.clearEleDepMaps();
13550
13486
  }
13551
13487
  get defaultCtx() {
13552
13488
  return new DocumentContext(this._document, this.selectionState);
@@ -13621,17 +13557,6 @@ class EditorContext {
13621
13557
  return this._document.modifyFlag === exports.ModifyFlag.None ? 'appearance' : 'content';
13622
13558
  }
13623
13559
  }
13624
- // export interface IImageLoader {
13625
- // clear(): void;
13626
- //
13627
- // loadImage(src: string, onCallback: (status: ImgLoadStatus) => void): void;
13628
- //
13629
- // getImage(src: string): HTMLImageElement | undefined;
13630
- //
13631
- // imagesLoadCompleted(): boolean;
13632
- //
13633
- // getLoadTasks(): Array<Promise<void>>;
13634
- // }
13635
13560
  /**
13636
13561
  * 文档上下文
13637
13562
  */
@@ -13894,13 +13819,23 @@ class DocumentContext {
13894
13819
  }
13895
13820
  }
13896
13821
 
13897
- class DynamicContextParser {
13822
+ class DynamicExecute {
13898
13823
  doc;
13899
13824
  ss;
13825
+ current;
13826
+ depItems;
13900
13827
  constructor(doc, ss) {
13901
13828
  this.doc = doc;
13902
13829
  this.ss = ss;
13903
13830
  }
13831
+ setCurrentCtx(ele, depItems) {
13832
+ this.current = ele;
13833
+ this.depItems = depItems;
13834
+ }
13835
+ clearCurrentCtx() {
13836
+ this.current = undefined;
13837
+ this.depItems = undefined;
13838
+ }
13904
13839
  cacheList;
13905
13840
  getControlById(id) {
13906
13841
  if (!this.cacheList) {
@@ -13912,6 +13847,10 @@ class DynamicContextParser {
13912
13847
  //return this.cacheList.find(item => item['props']['id'] === id);
13913
13848
  }
13914
13849
  getObject(id) {
13850
+ //如果当前存在编译缓存,则直接从缓存中获取
13851
+ if (this.depItems && this.depItems.has(id)) {
13852
+ return this.depItems.get(id);
13853
+ }
13915
13854
  new DocumentContext(this.doc, this.ss);
13916
13855
  if (id.startsWith('$')) {
13917
13856
  id = id.slice(1);
@@ -13930,6 +13869,9 @@ class DynamicContextParser {
13930
13869
  if (control) {
13931
13870
  control.setValue(val);
13932
13871
  }
13872
+ },
13873
+ get ref() {
13874
+ return control;
13933
13875
  }
13934
13876
  };
13935
13877
  }
@@ -14001,9 +13943,12 @@ class DynamicContextParser {
14001
13943
  class ParagraphMeasure {
14002
13944
  options;
14003
13945
  renderCtx;
14004
- constructor(options, renderCtx) {
13946
+ execute;
13947
+ constructor(options, renderCtx, execute) {
14005
13948
  this.options = options;
14006
13949
  this.renderCtx = renderCtx;
13950
+ this.execute = execute;
13951
+ this.execute = execute;
14007
13952
  }
14008
13953
  /**
14009
13954
  * 段落排版:
@@ -14099,7 +14044,10 @@ class ParagraphMeasure {
14099
14044
  const paraRenders = [];
14100
14045
  for (let i = 0; i < paraModels.length; i++) {
14101
14046
  const innerLineRects = paraModels[i].innerLine;
14102
- let render = p.createRenderObject();
14047
+ let render = this.createRenderObject(p);
14048
+ if (!render) {
14049
+ return [];
14050
+ }
14103
14051
  render.setRenderWidth(limitWidth);
14104
14052
  paraRenders.push(render);
14105
14053
  for (let j = 0; j < innerLineRects.length; j++) {
@@ -14240,7 +14188,7 @@ class ParagraphMeasure {
14240
14188
  }
14241
14189
  arrangeInlineGroupElement(parentLine, ele) {
14242
14190
  const { options, renderCtx } = this;
14243
- let render = ele.createRenderObject({ options, renderCtx });
14191
+ let render = this.createRenderObject(ele);
14244
14192
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
14245
14193
  const inlineGroupRenders = [];
14246
14194
  ele.cacheRender = render;
@@ -14294,10 +14242,7 @@ class ParagraphMeasure {
14294
14242
  const baseTextProps = ele.props;
14295
14243
  nullText.text = baseTextProps.nullText;
14296
14244
  baseTextProps.nullTextProps.clone(nullText.props);
14297
- const nullTextRender = nullText.createRenderObject({
14298
- options: this.options,
14299
- renderCtx: this.renderCtx
14300
- });
14245
+ const nullTextRender = this.createRenderObject(nullText);
14301
14246
  //inlineGroupRender.insertChild(nullTextRender, 1);
14302
14247
  this.arrangeLeafRender(data, nullTextRender);
14303
14248
  }
@@ -14326,7 +14271,7 @@ class ParagraphMeasure {
14326
14271
  }
14327
14272
  }
14328
14273
  arrangeLeafElement(parentLine, ele) {
14329
- ele.cacheRender = ele.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
14274
+ ele.cacheRender = this.createRenderObject(ele);
14330
14275
  if (ele.cacheRender) {
14331
14276
  this.arrangeLeafRender(parentLine, ele.cacheRender);
14332
14277
  }
@@ -14523,6 +14468,80 @@ class ParagraphMeasure {
14523
14468
  }
14524
14469
  throw new Error('未到达计算位置');
14525
14470
  }
14471
+ /**
14472
+ * 解析可见性表达式
14473
+ * @param ele
14474
+ * @param execute
14475
+ * @private
14476
+ */
14477
+ parseVisibleExpression(ele, execute) {
14478
+ if (ele.visibleExpr)
14479
+ return;
14480
+ if (!ele.attribute?.visibleExpr)
14481
+ return;
14482
+ const reactiveMode = this.renderCtx.drawMode !== 'print';
14483
+ try {
14484
+ const depIdItems = [];
14485
+ const depEleMap = new Map();
14486
+ let compliedCode = parser(ele.attribute?.visibleExpr, depIdItems);
14487
+ compliedCode = addReturn(compliedCode);
14488
+ if (depIdItems.length) {
14489
+ depIdItems.forEach(dep => {
14490
+ const refCtx = execute.getObject(dep);
14491
+ if (refCtx.ref) {
14492
+ const refEle = refCtx.ref.item;
14493
+ depEleMap.set(dep, refCtx);
14494
+ //当前有可能是checkbox数组
14495
+ const refEles = Array.isArray(refEle) ? refEle : [refEle];
14496
+ reactiveMode && refEles.forEach(item => {
14497
+ //求值依赖元素更改的时候,发布当前元素重新计算的指令
14498
+ item.onChangeSubject.subscribe(() => {
14499
+ ele.pubOnChange('self');
14500
+ });
14501
+ });
14502
+ }
14503
+ });
14504
+ }
14505
+ ele.visibleExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14506
+ }
14507
+ catch (e) {
14508
+ console.error('解析表达式出错', ele.attribute?.visibleExpr);
14509
+ }
14510
+ }
14511
+ /**
14512
+ * 元素可见行求值
14513
+ * @param ele
14514
+ * @param executeCtx
14515
+ * @private
14516
+ */
14517
+ evalVisibleExpr(ele, executeCtx) {
14518
+ if (ele.visibleExpr && ele.visibleExpr.func) {
14519
+ try {
14520
+ executeCtx.setCurrentCtx(ele, ele.visibleExpr.depItems);
14521
+ const func = ele.visibleExpr.func.bind(executeCtx);
14522
+ return func() === true;
14523
+ }
14524
+ catch (e) {
14525
+ console.error(e, "表达式执行出错", ele.visibleExpr.compliedCode);
14526
+ }
14527
+ finally {
14528
+ executeCtx.clearCurrentCtx();
14529
+ }
14530
+ }
14531
+ return true;
14532
+ }
14533
+ createRenderObject(element) {
14534
+ if (this.options.enableVisibleExpression) {
14535
+ this.parseVisibleExpression(element, this.execute);
14536
+ if (!this.evalVisibleExpr(element, this.execute)) {
14537
+ return null;
14538
+ }
14539
+ }
14540
+ return element.createRenderObject({
14541
+ options: this.options,
14542
+ renderCtx: this.renderCtx
14543
+ });
14544
+ }
14526
14545
  }
14527
14546
 
14528
14547
  /**
@@ -14654,6 +14673,8 @@ class DocumentArrange {
14654
14673
  renderCtx;
14655
14674
  seo;
14656
14675
  options;
14676
+ execute;
14677
+ pMeasure;
14657
14678
  constructor(docCtx, renderCtx, seo) {
14658
14679
  this.docCtx = docCtx;
14659
14680
  this.renderCtx = renderCtx;
@@ -14673,10 +14694,12 @@ class DocumentArrange {
14673
14694
  //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
14674
14695
  return suppressTracking(() => {
14675
14696
  const doc = this.docCtx.document;
14697
+ this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14698
+ this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
14676
14699
  const data = {
14677
14700
  doc,
14678
14701
  viewOptions: this.options,
14679
- parser: new DynamicContextParser(doc, this.docCtx.selectionState),
14702
+ execute: this.execute,
14680
14703
  createParaFn: () => this.createDefaultPara()
14681
14704
  };
14682
14705
  doc.clearMarkItems();
@@ -14792,15 +14815,6 @@ class DocumentArrange {
14792
14815
  cloneFooterRender.rect.x = limitRect.x;
14793
14816
  cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
14794
14817
  currColumn === 0 && documentRender.addChild(cloneFooterRender);
14795
- // //审阅模式,添加审阅窗口
14796
- // if (this.options.showReviewWindow && commentsRender) {
14797
- // const commentsContainer = this.createRenderObject(commentsRender.element) as CommsContainerRenderObject;
14798
- // commentsContainer.padding.top = bodyMarginTop;
14799
- // commentsContainer.rect.height = documentRender.rect.height;
14800
- // documentRender.addChild(commentsContainer);
14801
- // commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
14802
- // documentRender.rect.width += this.options.reviewWindowWidth;
14803
- // }
14804
14818
  currColumn++;
14805
14819
  if (currColumn === docColumns) {
14806
14820
  currColumn = 0;
@@ -14811,7 +14825,7 @@ class DocumentArrange {
14811
14825
  return docPages;
14812
14826
  }
14813
14827
  createEmptyBodyRender(bodyRender, limitRect) {
14814
- const pageBodyRender = this.createRenderObject(bodyRender.element);
14828
+ const pageBodyRender = this.pMeasure.createRenderObject(bodyRender.element);
14815
14829
  pageBodyRender.rect.width = limitRect.width;
14816
14830
  const bodyInnerLimitRect = pageBodyRender.getInnerRect();
14817
14831
  if (this.options.fullPageView) {
@@ -14827,12 +14841,11 @@ class DocumentArrange {
14827
14841
  return element.cacheRender;
14828
14842
  }
14829
14843
  if (element instanceof BlockContentElement) {
14830
- const pRange = new ParagraphMeasure(this.options, this.renderCtx);
14831
- return pRange.measureParagraph(element, maxWidth);
14844
+ return this.pMeasure.measureParagraph(element, maxWidth);
14832
14845
  }
14833
14846
  else if (element instanceof BlockContainerElement) {
14834
14847
  const renders = [];
14835
- let render = this.createRenderObject(element);
14848
+ let render = this.pMeasure.createRenderObject(element);
14836
14849
  if (!render) {
14837
14850
  element.cacheRender = null;
14838
14851
  return null;
@@ -14845,8 +14858,8 @@ class DocumentArrange {
14845
14858
  const innerMaxWidth = render.getInnerMaxWidth();
14846
14859
  for (let i = 0; i < element.length; i++) {
14847
14860
  const child = element.getChild(i);
14848
- const blockContentELement = child;
14849
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
14861
+ const blockContentElement = child;
14862
+ const childRender = this.measureControl(blockContentElement, innerMaxWidth);
14850
14863
  if (!childRender) {
14851
14864
  continue;
14852
14865
  }
@@ -14856,7 +14869,7 @@ class DocumentArrange {
14856
14869
  }
14857
14870
  for (let j = 0; j < childRender.length; j++) {
14858
14871
  if (j > 0) {
14859
- render = this.createRenderObject(element);
14872
+ render = this.pMeasure.createRenderObject(element);
14860
14873
  if (!render.rect.width) {
14861
14874
  render.setRenderWidth(maxWidth);
14862
14875
  }
@@ -14884,12 +14897,6 @@ class DocumentArrange {
14884
14897
  textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx });
14885
14898
  }
14886
14899
  }
14887
- createRenderObject(element) {
14888
- return element.createRenderObject({
14889
- options: this.options,
14890
- renderCtx: this.renderCtx
14891
- });
14892
- }
14893
14900
  getDocInnerRect(documentRender) {
14894
14901
  const render = documentRender.element.createRenderObject();
14895
14902
  render.padding = documentRender.padding;
@@ -14908,7 +14915,7 @@ class DocumentArrange {
14908
14915
  if (render instanceof TableRenderObject) {
14909
14916
  return this.cutTable(render, limitHeight);
14910
14917
  }
14911
- const cloneRender = this.createRenderObject(render.element);
14918
+ const cloneRender = this.pMeasure.createRenderObject(render.element);
14912
14919
  cloneRender.setRenderWidth(render.rect.width);
14913
14920
  if (render instanceof MuiltBlockLineRenderObject) {
14914
14921
  let sumHeight = 0;
@@ -14993,10 +15000,11 @@ class DocumentArrange {
14993
15000
  let currRow = rows[j];
14994
15001
  const cutRows = [];
14995
15002
  while (currRow) {
15003
+ const minHeight = currRow.element.props.minHeight;
14996
15004
  const rowContentHeight = this.getBlockLineHeight(currRow);
14997
15005
  if (rowContentHeight + sumHeight > limitHeight) {
14998
- //行存在最小高度,且当前行跨页的情况下,不截断该行
14999
- if (currRow.element.props.minHeight) {
15006
+ //行存在最小高度,且当前行内容的高度小于最小高度,且当前行跨页的情况下,不截断该行
15007
+ if (minHeight > 0 && minHeight > rowContentHeight) {
15000
15008
  break;
15001
15009
  }
15002
15010
  //限制的外框尺寸
@@ -15084,7 +15092,7 @@ class DocumentArrange {
15084
15092
  for (let i = 0; i < cutCellRenders.length; i++) {
15085
15093
  let cellRender = cutCellRenders[i];
15086
15094
  if (!cellRender) {
15087
- cellRender = this.createRenderObject(cellRenders[i].element);
15095
+ cellRender = this.pMeasure.createRenderObject(cellRenders[i].element);
15088
15096
  cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
15089
15097
  cellRender.rect.height = 0;
15090
15098
  ElementUtil.remeasure(cellRender);
@@ -15229,6 +15237,7 @@ class DocumentArrange {
15229
15237
  }
15230
15238
  }
15231
15239
  clearPaintCache(ele, data) {
15240
+ ele.paintRenders.length = 0;
15232
15241
  ele.beginMeasure(data);
15233
15242
  this.identifyComment(ele);
15234
15243
  if (ele instanceof BranchElement) {
@@ -15256,1105 +15265,65 @@ class DocumentArrange {
15256
15265
  */
15257
15266
  generateCommRange() {
15258
15267
  this.seo.commRangeSets.clear();
15259
- const commMarks = this.docCtx.document.markPairs;
15260
- for (let i = 0; i < commMarks.length; i++) {
15261
- const commMark = commMarks[i];
15262
- if (commMark.start && commMark.end) {
15263
- const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15264
- const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15265
- SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
15266
- }
15267
- }
15268
- }
15269
- cacheRenders(renderTree) {
15270
- if (renderTree.element) {
15271
- renderTree.element.paintRenders.push(renderTree);
15272
- }
15273
- for (let i = 0; i < renderTree.length; i++) {
15274
- const currRender = renderTree.getChild(i);
15275
- if (currRender.element) {
15276
- this.cacheCommsRender(currRender);
15277
- }
15278
- if (currRender instanceof BranchRenderObject) {
15279
- this.cacheRenders(currRender);
15280
- }
15281
- else {
15282
- currRender.element && currRender.element.paintRenders.push(currRender);
15283
- }
15284
- }
15285
- }
15286
- /**
15287
- * 缓存批注标志
15288
- * @private
15289
- */
15290
- cacheCommsRender(render) {
15291
- if (render.element && render.element.type === 'comm') {
15292
- const commElement = render.element;
15293
- if (commElement.props.markType === 'start') {
15294
- const currDocRender = this.cacheDoc;
15295
- const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15296
- if (docCommContainer) {
15297
- docCommContainer.commsMarks.push(render);
15298
- }
15299
- }
15300
- }
15301
- if (render.element && render.element.type === 'comm-list') {
15302
- const commContainer = render;
15303
- CommentsUtil.createCommentsImage(commContainer);
15304
- }
15305
- }
15306
- endMeasures(ele) {
15307
- ele.endMeasure();
15308
- if (ele instanceof BranchElement) {
15309
- for (let i = 0; i < ele.length; i++) {
15310
- this.endMeasures(ele.getChild(i));
15311
- }
15312
- }
15313
- }
15314
- createDefaultPara() {
15315
- const tmp = new ParagraphElement();
15316
- tmp.props.lineHeight = this.options.defaultLineHeight;
15317
- return tmp;
15318
- }
15319
- }
15320
-
15321
- /**
15322
- * 文字行渲染模式
15323
- 用于医嘱打印模式
15324
- */
15325
- function runTextLineRender(ele, data) {
15326
- if (!data.options.textRowLineMode) {
15327
- return;
15328
- }
15329
- if (ele instanceof TableElement) {
15330
- // textLineRenderMode(ele, data);
15331
- // remeasureParentRenders(ele.cacheRender)
15332
- return;
15333
- }
15334
- if (ele instanceof BranchElement) {
15335
- for (let i = 0; i < ele.length; i++) {
15336
- runTextLineRender(ele.getChild(i), data);
15337
- }
15338
- }
15339
- }
15340
-
15341
- /**
15342
- * 测量阶段,生成Render-UI
15343
- */
15344
- class ElementMeasure {
15345
- docCtx;
15346
- renderCtx;
15347
- options;
15348
- constructor(docCtx, renderCtx) {
15349
- this.docCtx = docCtx;
15350
- this.renderCtx = renderCtx;
15351
- this.options = docCtx.viewOptions;
15352
- }
15353
- measureDocument(document) {
15354
- //测量阶段,对于空段落会插入段落符号,新表格会插入空段落,此时不需要记录节点的更改,以最大的节点进行记录
15355
- return suppressTracking(() => {
15356
- this.clearPaintCache(document, {
15357
- doc: document,
15358
- viewOptions: this.options,
15359
- parser: new DynamicContextParser(document, this.docCtx.selectionState),
15360
- createParaFn: () => new ParagraphElement()
15361
- });
15362
- const docRender = this.measureControl(document, this.options.docPageSettings.width);
15363
- this.setMeasureCompletedModifyFlag(document);
15364
- runTextLineRender(document, { options: this.options, renderCtx: this.renderCtx });
15365
- return docRender;
15366
- });
15367
- }
15368
- measureControl(element, maxWidth) {
15369
- if (element.modifyFlag === exports.ModifyFlag.None) {
15370
- return element.cacheRender;
15371
- }
15372
- if (element instanceof BlockContentElement) {
15373
- const render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15374
- element.cacheRender = render;
15375
- //测量阶段,只限制最大宽度即可
15376
- render.setRenderWidth(maxWidth);
15377
- if (element instanceof ParagraphElement) {
15378
- this.measureParagraph(element, render);
15379
- }
15380
- else {
15381
- throw new Error('未实现');
15382
- }
15383
- return render;
15384
- }
15385
- else if (element instanceof BlockContainerElement) {
15386
- //ElementUtil.fixBlockContainer(element);
15387
- let render = null;
15388
- if (element.modifyFlag === exports.ModifyFlag.Modify || element.modifyFlag === exports.ModifyFlag.Track) {
15389
- //ElementUtil.fixBlockContainer(element);
15390
- element.cacheRender = null;
15391
- render = element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15392
- if (!render) {
15393
- element.cacheRender = null;
15394
- return null;
15395
- }
15396
- if (!render.rect.width) {
15397
- render.setRenderWidth(maxWidth);
15398
- }
15399
- }
15400
- if (!render) {
15401
- throw new Error('render is null');
15402
- }
15403
- element.cacheRender = render;
15404
- const innerMaxWidth = render.getInnerMaxWidth();
15405
- for (let i = 0; i < element.length; i++) {
15406
- const child = element.getChild(i);
15407
- const blockContentELement = child;
15408
- const childRender = this.measureControl(blockContentELement, innerMaxWidth);
15409
- if (!childRender) {
15410
- continue;
15411
- }
15412
- render.addChild(childRender);
15413
- }
15414
- ElementUtil.remeasure(render);
15415
- return render;
15416
- }
15417
- else {
15418
- throw new Error('未实现');
15419
- }
15420
- }
15421
- /**
15422
- * 生成段落 UI 树
15423
- * @param para
15424
- * @param render
15425
- */
15426
- measureParagraph(para, render) {
15427
- ElementUtil.fixParagraphContent(para);
15428
- const renderObjects = [];
15429
- for (let i = 0; i < para.length; i++) {
15430
- const child = para.getChild(i);
15431
- if (child instanceof InlineGroupElement) {
15432
- child.cacheRender = this.getInlineGroupRenderItem(child);
15433
- if (child.cacheRender) {
15434
- renderObjects.push(child.cacheRender);
15435
- }
15436
- }
15437
- else if (child instanceof LeafElement) {
15438
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15439
- if (child.cacheRender) {
15440
- renderObjects.push(child.cacheRender);
15441
- }
15442
- }
15443
- }
15444
- this.measureInnerParagraph(render, para, renderObjects);
15445
- }
15446
- /**
15447
- * 根据段落UI元素,进行排列
15448
- * @param render
15449
- * @param paragraph
15450
- * @param renderObjects
15451
- */
15452
- measureInnerParagraph(render, paragraph, renderObjects) {
15453
- return;
15454
- // let lineRect = render.createLineRect();
15455
- // let maxLineWidth=render.rect.width;
15456
- // //行内框
15457
- // const innerLineRects: Array<ParagraphLineRectRenderObject> = [];
15458
- // const addInnerLineFunc = (lineRect: ParagraphLineRectRenderObject): void => {
15459
- // maxLineWidth=render.rect.width;
15460
- // innerLineRects.push(lineRect);
15461
- // if (innerLineRects.indexOf(lineRect) === 0) {
15462
- // if (paragraph.props.indent > 0) {
15463
- // maxLineWidth -= paragraph.props.indent;
15464
- // }
15465
- // } else {
15466
- // maxLineWidth -= paragraph.props.hanging;
15467
- // }
15468
- // };
15469
- // addInnerLineFunc(lineRect);
15470
- // let i = 0;
15471
- // let currItem = renderObjects[i++];
15472
- // const inCloseBody = paragraph.parent.type === 'body';
15473
- // while (currItem) {
15474
- // const maxWidth = maxLineWidth;
15475
- // const nextItem = renderObjects[i];
15476
- // const {
15477
- // firstItem,
15478
- // lastItem,
15479
- // br
15480
- // } = this.cutRenderItem(currItem, nextItem, maxWidth - lineRect.rect.width, lineRect.length === 0, inCloseBody);
15481
- // if (firstItem) {
15482
- // if (lastItem) {
15483
- // renderObjects.splice(i, 0, lastItem);
15484
- // }
15485
- // currItem = firstItem;
15486
- // } else {
15487
- // lineRect = render.createLineRect();
15488
- // addInnerLineFunc(lineRect);
15489
- // continue;
15490
- // }
15491
- // lineRect.addChild(currItem);
15492
- // currItem.rect.x = lineRect.rect.width;
15493
- // if (currItem.rect.height > lineRect.rect.height) {
15494
- // lineRect.rect.height = currItem.rect.height;
15495
- // }
15496
- // lineRect.rect.width += currItem.rect.width;
15497
- // if (br) {
15498
- // //lineRect.rect.maxWidth = lineRect.rect.width;
15499
- // lineRect = render.createLineRect();
15500
- // addInnerLineFunc(lineRect);
15501
- // }
15502
- // currItem = renderObjects[i++];
15503
- // }
15504
- // for (let i = 0; i < innerLineRects.length; i++) {
15505
- // const innerLineRect = innerLineRects[i] as ParagraphLineRectRenderObject;
15506
- // innerLineRect.rect.x = this.getParaLineRectStartX(innerLineRects.length, i, paragraph, render, innerLineRect);
15507
- // //限制最大行高
15508
- // const maxLineHeight = paragraph.props.lineHeight !== this.options.defaultLineHeight ? 100 : Math.floor(14 * 2);
15509
- // //fillLineHeight填充行高
15510
- // let fillLineHeight = Math.ceil(innerLineRect.rect.height * (paragraph.props.lineHeight - 1));
15511
- // fillLineHeight = fillLineHeight > maxLineHeight ? maxLineHeight : fillLineHeight;
15512
- // const lineHeight = innerLineRect.rect.height + fillLineHeight;
15513
- // const paddingBottom = Math.ceil(fillLineHeight / 2);
15514
- // innerLineRect.rect.height = lineHeight;
15515
- // for (let j = 0; j < innerLineRect.length; j++) {
15516
- // const leaf = innerLineRect.getChild(j);
15517
- // leaf.rect.y = innerLineRect.rect.height - paddingBottom - leaf.rect.height;
15518
- // }
15519
- // //render.rect.height += lineRect.rect.height;
15520
- // const outterLineRect = render.createLineRect();
15521
- // outterLineRect.rect.width = render.rect.width;
15522
- // outterLineRect.addChild(innerLineRect);
15523
- // ElementUtil.remeasure(outterLineRect, false);
15524
- // render.addChild(outterLineRect);
15525
- // }
15526
- // ElementUtil.remeasure(render);
15527
- }
15528
- /**
15529
- * 获取段落行布局横向坐标起始位置,被段落text-align影响
15530
- */
15531
- getParaLineRectStartX(counter, paraLineIndex, paraElement, paraRenderObject, paraLineRender) {
15532
- //左对齐,首行缩进
15533
- let indent = paraElement.props.indent;
15534
- //存在项目符号
15535
- if (paraLineIndex > 0) {
15536
- indent = paraElement.props.hanging;
15537
- }
15538
- if (paraElement.props.textAlign === 'center') {
15539
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15540
- return Math.ceil(remainSpace / 2) + indent;
15541
- }
15542
- else if (paraElement.props.textAlign === 'right') {
15543
- const remainSpace = paraRenderObject.rect.width - paraLineRender.rect.width;
15544
- return remainSpace + indent;
15545
- }
15546
- else if (paraElement.props.textAlign === 'justify') {
15547
- const renderUnitCount = this.getRenderUnitLength(paraLineRender);
15548
- if (paraLineIndex === counter - 1 || renderUnitCount === 1) {
15549
- return indent;
15550
- }
15551
- const spaceWidth = (paraRenderObject.rect.width - paraLineRender.rect.width) / (renderUnitCount - 1);
15552
- this.setAlignJustify(paraLineRender, 0, spaceWidth);
15553
- return indent;
15554
- }
15555
- else {
15556
- return indent;
15557
- }
15558
- }
15559
- /**
15560
- * 设置两端对齐
15561
- * @param render
15562
- * @param count
15563
- * @param spaceWidth
15564
- */
15565
- setAlignJustify(render, count, spaceWidth) {
15566
- if (render instanceof BranchRenderObject) {
15567
- let width = 0;
15568
- for (let i = 0; i < render.length; i++) {
15569
- const currRender = render.getChild(i);
15570
- count += this.setAlignJustify(currRender, count, spaceWidth);
15571
- currRender.rect.x = width;
15572
- width += currRender.rect.width;
15573
- }
15574
- render.rect.width = width;
15575
- }
15576
- else if (render instanceof LeafRenderObject) {
15577
- if (render instanceof TextGroupRenderObject) {
15578
- let i = count === 0 ? 1 : 0;
15579
- for (; i < render.textMeasures.length; i++) {
15580
- render.textMeasures[i].actualSize = render.textMeasures[i].actualSize + spaceWidth;
15581
- }
15582
- render.measure();
15583
- count += render.textMeasures.length;
15584
- }
15585
- else {
15586
- if (count !== 0) {
15587
- render.rect.width += spaceWidth;
15588
- }
15589
- count += 1;
15590
- }
15591
- }
15592
- return count;
15593
- }
15594
- /**
15595
- * 获取段落行渲染单位个数,字符需要计算为字符长度
15596
- */
15597
- getRenderUnitLength(paraLine) {
15598
- if (paraLine instanceof LeafRenderObject) {
15599
- if (paraLine instanceof TextGroupRenderObject) {
15600
- return paraLine.textMeasures.length;
15601
- }
15602
- else {
15603
- return 1;
15604
- }
15605
- }
15606
- else if (paraLine instanceof BranchRenderObject) {
15607
- let count = 0;
15608
- for (let i = 0; i < paraLine.length; i++) {
15609
- count += this.getRenderUnitLength(paraLine.getChild(i));
15610
- }
15611
- return count;
15612
- }
15613
- throw new Error('未到达计算位置');
15614
- }
15615
- getInlineGroupRenderItem(item) {
15616
- const inlineGroupRender = item.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15617
- if (!inlineGroupRender) {
15618
- return null;
15619
- }
15620
- for (let i = 0; i < item.length; i++) {
15621
- const child = item.getChild(i);
15622
- if (child instanceof LeafElement) {
15623
- child.cacheRender = child.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15624
- if (child.cacheRender) {
15625
- inlineGroupRender.addChild(child.cacheRender);
15626
- }
15627
- }
15628
- else if (child instanceof InlineGroupElement) {
15629
- item.cacheRender = this.getInlineGroupRenderItem(child);
15630
- if (item.cacheRender) {
15631
- inlineGroupRender.addChild(item.cacheRender);
15632
- }
15633
- }
15634
- else {
15635
- throw new Error('未实现');
15636
- }
15637
- }
15638
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15639
- //限制最小长度
15640
- if (item instanceof DataElementInlineGroup) {
15641
- //需要填充null-text
15642
- if (item.length === 2) {
15643
- const nullText = new TextGroupElement();
15644
- nullText.isDecorate = true;
15645
- nullText.disableClick = true;
15646
- const baseTextProps = item.props;
15647
- nullText.text = baseTextProps.nullText;
15648
- baseTextProps.nullTextProps.clone(nullText.props);
15649
- const nullTextRender = nullText.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15650
- inlineGroupRender.insertChild(nullTextRender, 1);
15651
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15652
- }
15653
- const props = item.props;
15654
- let minLength = props.minLength ?? 14;
15655
- minLength = minLength < 14 ? 14 : minLength;
15656
- if (item instanceof DataElementInlineGroup && inlineGroupRender.rect.width < minLength) {
15657
- const fillNullSpace = new FillNullSpaceRenderObject();
15658
- fillNullSpace.rect.width = minLength - inlineGroupRender.rect.width;
15659
- fillNullSpace.rect.height = inlineGroupRender.rect.height;
15660
- inlineGroupRender.insertChild(fillNullSpace, inlineGroupRender.length - 1);
15661
- }
15662
- ElementUtil.remeasureInlineGroupRender(inlineGroupRender);
15663
- }
15664
- return inlineGroupRender;
15665
- }
15666
- cutRenderItem(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15667
- if (render instanceof LeafRenderObject) {
15668
- if (render.rect.width > limitWidth && render instanceof TextGroupRenderObject) {
15669
- return this.cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody);
15670
- }
15671
- if (render instanceof FillNullSpaceRenderObject) {
15672
- return this.cutFillNullRender(render, limitWidth);
15673
- }
15674
- if (render.rect.width < limitWidth || lineEmpty || render.element.type === 'br' || render.element.type === 'psym') {
15675
- return { firstItem: render, lastItem: null, br: render.element.type === 'br' };
15676
- }
15677
- return { firstItem: null, lastItem: null };
15678
- }
15679
- else if (render instanceof InlineGroupRenderObject) {
15680
- return this.cutInlineGroupRenderItem(render, limitWidth, lineEmpty, inCloseBody);
15681
- }
15682
- throw new Error('到达计算边界');
15683
- }
15684
- cutTextRender(render, nextRender, limitWidth, lineEmpty, inCloseBody) {
15685
- let sumWidth = 0;
15686
- const cutRender = render.clone();
15687
- cutRender.textMeasures.length = 0;
15688
- let i = 0;
15689
- for (; i < render.textMeasures.length; i++) {
15690
- sumWidth += render.textMeasures[i].actualSize;
15691
- if (sumWidth > limitWidth) {
15692
- if (lineEmpty && i === 0) {
15693
- i = 1;
15694
- }
15695
- break;
15696
- }
15697
- }
15698
- //后置标点处理
15699
- i = this.patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty);
15700
- //前置标点处理
15701
- i = this.patchHandleLeadingPunctuation(render, i, lineEmpty);
15702
- if (i <= 0) {
15703
- return { firstItem: null, lastItem: null };
15704
- }
15705
- cutRender.textMeasures = render.textMeasures.splice(0, i);
15706
- render.measure();
15707
- cutRender.measure();
15708
- return { firstItem: cutRender, lastItem: render, br: true };
15709
- }
15710
- /**
15711
- * 处理前置标点,前置标点不能出现在末尾
15712
- * @param render
15713
- * @param i
15714
- */
15715
- patchHandleLeadingPunctuation(render, i, lineEmpty) {
15716
- if (i === 1 && lineEmpty) {
15717
- return i;
15718
- }
15719
- if (this.containLeadingPunctuation(render.textMeasures[i]?.char)) {
15720
- return i--;
15721
- }
15722
- return i;
15723
- }
15724
- /**
15725
- * 处理后置标点,后置标点不能出现在行首
15726
- * @param render
15727
- * @param i
15728
- * @param lineEmpty
15729
- */
15730
- patchHandlePostPunctuation(render, nextRender, i, inCloseBody, lineEmpty) {
15731
- if (i === render.textMeasures.length - 1) {
15732
- //紧跟着的字符包含后置标点
15733
- if (this.containerStartSymbolInTextStart(nextRender)) {
15734
- i--;
15735
- }
15736
- }
15737
- if (inCloseBody && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15738
- if (this.containPostPunctuation(render.textMeasures[i + 1]?.char)) {
15739
- i--;
15740
- }
15741
- else {
15742
- i++;
15743
- }
15744
- }
15745
- else {
15746
- if (i > 1 && this.containPostPunctuation(render.textMeasures[i]?.char)) {
15747
- i--;
15748
- }
15749
- }
15750
- return i;
15751
- }
15752
- /**
15753
- * 是否包含后置标点
15754
- * @param str
15755
- * @returns
15756
- */
15757
- containPostPunctuation(str) {
15758
- return '!),.:;?]}¨·ˇˉ―‖’”…∶、。〃々〉》」』】〕〗!"'),.:;?]`|}~¢'.indexOf(str) > -1;
15759
- }
15760
- //是否包含前置标点
15761
- containLeadingPunctuation(str) {
15762
- return '‘“〈《「『【〔〖([{£'.indexOf(str) > -1;
15763
- }
15764
- /**
15765
- * 文本开头是否包含后置标点
15766
- * @param render
15767
- * @returns
15768
- */
15769
- containerStartSymbolInTextStart(render) {
15770
- //return false;
15771
- if (render instanceof TextGroupRenderObject) {
15772
- if (render.textMeasures.length > 0) {
15773
- return this.containPostPunctuation(render.textMeasures[0].char);
15774
- }
15775
- }
15776
- return false;
15777
- }
15778
- cutFillNullRender(render, limitWidth) {
15779
- if (limitWidth === 0) {
15780
- return { firstItem: null, lastItem: null };
15781
- }
15782
- if (render.rect.width > limitWidth) {
15783
- const cutRender = new FillNullSpaceRenderObject();
15784
- cutRender.rect.width = limitWidth;
15785
- cutRender.rect.height = render.rect.height;
15786
- render.rect.width = render.rect.width - limitWidth;
15787
- return { firstItem: cutRender, lastItem: render };
15788
- }
15789
- else {
15790
- return { firstItem: render, lastItem: null };
15791
- }
15792
- }
15793
- /**
15794
- * 行内编组元素超出行内可用空间,需要根据剩余空间长度进行截断
15795
- */
15796
- cutInlineGroupRenderItem(render, limitWidth, emptyLine, inCloseBody) {
15797
- const cutRender = render.element.createRenderObject({ options: this.options, renderCtx: this.renderCtx });
15798
- let x = 0;
15799
- let br = false;
15800
- const items = [...render.getItems()];
15801
- for (let i = 0; i < items.length; i++) {
15802
- const child = items[i];
15803
- if (child instanceof LeafRenderObject) {
15804
- if (x + child.rect.width > limitWidth) {
15805
- const { firstItem, lastItem, br: childBr } = this.cutRenderItem(child, items[i + 1], limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15806
- if (firstItem) {
15807
- cutRender.addChild(firstItem);
15808
- }
15809
- br = childBr || br;
15810
- break;
15811
- }
15812
- else {
15813
- render.removeChild(child);
15814
- cutRender.addChild(child);
15815
- }
15816
- //软换行符
15817
- if (child.element && child.element.type === 'br') {
15818
- br = true;
15819
- break;
15820
- }
15821
- }
15822
- else if (child instanceof InlineGroupRenderObject) {
15823
- if (x + child.rect.width > limitWidth) {
15824
- const { firstItem, br: childBr } = this.cutInlineGroupRenderItem(child, limitWidth - x, emptyLine && cutRender.length === 0, inCloseBody);
15825
- if (firstItem) {
15826
- cutRender.addChild(firstItem);
15827
- }
15828
- br = childBr || br;
15829
- break;
15830
- }
15831
- else {
15832
- render.removeChild(child);
15833
- cutRender.addChild(child);
15834
- }
15835
- }
15836
- x += child.rect.width;
15837
- }
15838
- if (!cutRender.length) {
15839
- return { firstItem: null, lastItem: null };
15840
- }
15841
- ElementUtil.remeasureInlineGroupRender(cutRender);
15842
- ElementUtil.remeasureInlineGroupRender(render);
15843
- return { firstItem: cutRender, lastItem: render.length ? render : null, br };
15844
- }
15845
- /**
15846
- * 修改测量完毕后的元素状态
15847
- * @param ele
15848
- */
15849
- setMeasureCompletedModifyFlag(ele) {
15850
- if (ele instanceof BranchElement) {
15851
- for (let i = 0; i < ele.length; i++) {
15852
- this.setMeasureCompletedModifyFlag(ele.getChild(i));
15853
- }
15854
- }
15855
- ele.modifyFlag = exports.ModifyFlag.None;
15856
- }
15857
- clearPaintCache(ele, data) {
15858
- ele.beginMeasure(data);
15859
- if (ele instanceof BranchElement) {
15860
- for (let i = 0; i < ele.length; i++) {
15861
- this.clearPaintCache(ele.getChild(i), data);
15862
- }
15863
- }
15864
- }
15865
- endMeasures(ele) {
15866
- if (ele instanceof BranchElement) {
15867
- for (let i = 0; i < ele.length; i++) {
15868
- this.endMeasures(ele.getChild(i));
15869
- }
15870
- }
15871
- }
15872
- }
15873
-
15874
- class ElementRenderCut {
15875
- options;
15876
- renderContext;
15877
- constructor(options, renderContext) {
15878
- this.options = options;
15879
- this.renderContext = renderContext;
15880
- }
15881
- cutPage(documentRender, documentElement) {
15882
- if (this.options.fullPageView) {
15883
- return this.getFullViewDocRender(documentRender, documentElement);
15884
- }
15885
- const headerRender = documentRender.getChild(0);
15886
- const bodyRender = documentRender.getChild(1).clone();
15887
- const footerRender = documentRender.getChild(2);
15888
- const commentsRender = documentRender.getChild(3);
15889
- const { headerLine, footerLine } = documentRender;
15890
- let bodyMarginTop = headerLine + headerRender.rect.height + 6;
15891
- let bodyMarginBottom = footerLine + footerRender.rect.height;
15892
- const { top: bodyTop, bottom: bodyBottom } = documentRender.padding;
15893
- bodyMarginTop = bodyMarginTop > bodyTop ? bodyMarginTop : bodyTop;
15894
- bodyMarginBottom = bodyMarginBottom > bodyBottom ? bodyMarginBottom : bodyBottom;
15895
- documentRender.padding.top = bodyMarginTop;
15896
- documentRender.padding.bottom = bodyMarginBottom;
15897
- const bodyLimitRect = this.getDocInnerRect(documentRender);
15898
- const bodyArray = [];
15899
- let { emptyBody: pageBodyRender, innerRect: bodyInnerLimitRect } = this.createEmptyBodyRender(bodyRender, bodyLimitRect);
15900
- bodyArray.push(pageBodyRender);
15901
- const createBodyHolder = () => {
15902
- const { emptyBody, innerRect } = this.createEmptyBodyRender(bodyRender, bodyLimitRect);
15903
- pageBodyRender = emptyBody;
15904
- bodyInnerLimitRect = innerRect;
15905
- bodyArray.push(pageBodyRender);
15906
- };
15907
- const appendToBody = (item) => {
15908
- item.rect.y = bodyInnerLimitRect.height + item.margin.top;
15909
- pageBodyRender.addChild(item);
15910
- bodyInnerLimitRect.height += item.rect.height + item.margin.top + item.margin.bottom;
15911
- //上一个元素的bottom-margin
15912
- //bodyInnerLimitRect.prevMargin = item.margin.bottom;
15913
- ElementUtil.updateRenderHeightByInnerRect(pageBodyRender, bodyInnerLimitRect);
15914
- };
15915
- let i = 0;
15916
- let cloneBlockContentRender = bodyRender.getChild(i);
15917
- while (cloneBlockContentRender) {
15918
- if (bodyInnerLimitRect.maxHeight - bodyInnerLimitRect.height - cloneBlockContentRender.rect.height - cloneBlockContentRender.margin.bottom - cloneBlockContentRender.margin.top < 0) {
15919
- //限制的外框尺寸
15920
- const bodyAvailHeight = bodyInnerLimitRect.maxHeight - bodyInnerLimitRect.height - cloneBlockContentRender.margin.bottom - cloneBlockContentRender.margin.top;
15921
- //限制的内框尺寸
15922
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(cloneBlockContentRender, bodyAvailHeight);
15923
- const cutRenderObject = this.cutRenderItem(cloneBlockContentRender, limitRenderInnterHeight);
15924
- //至少有一个块级行元素被切割出来
15925
- if (cutRenderObject) {
15926
- appendToBody(cutRenderObject);
15927
- }
15928
- createBodyHolder();
15929
- }
15930
- else {
15931
- appendToBody(cloneBlockContentRender);
15932
- if (++i < bodyRender.length) {
15933
- cloneBlockContentRender = bodyRender.getChild(i);
15934
- }
15935
- else {
15936
- cloneBlockContentRender = null;
15937
- }
15938
- }
15939
- }
15940
- const docPages = [];
15941
- let pageY = this.options.docSpace;
15942
- for (let i = 0; i < bodyArray.length; i++) {
15943
- const body = bodyArray[i];
15944
- const documentRender = documentElement.createRenderObject();
15945
- docPages.push(documentRender);
15946
- documentRender.rect.y = pageY;
15947
- const limitRect = documentRender.getInnerRect();
15948
- const cloneHeaderRender = headerRender.clone();
15949
- cloneHeaderRender.rect.x = limitRect.x;
15950
- cloneHeaderRender.rect.y = headerLine;
15951
- documentRender.addChild(cloneHeaderRender);
15952
- body.rect.x = limitRect.x;
15953
- body.rect.y = bodyMarginTop;
15954
- body.rect.height = bodyInnerLimitRect.maxHeight;
15955
- documentRender.addChild(body);
15956
- pageY += documentRender.rect.height + this.options.docSpace;
15957
- const cloneFooterRender = footerRender.clone();
15958
- cloneFooterRender.rect.x = limitRect.x;
15959
- cloneFooterRender.rect.y = documentRender.rect.height - bodyMarginBottom;
15960
- documentRender.addChild(cloneFooterRender);
15961
- //审阅模式,添加审阅窗口
15962
- if (this.options.showReviewWindow && commentsRender) {
15963
- const commentsContainer = commentsRender.element.createRenderObject({
15964
- options: this.options,
15965
- renderCtx: this.renderContext
15966
- });
15967
- commentsContainer.padding.top = bodyMarginTop;
15968
- commentsContainer.rect.height = documentRender.rect.height;
15969
- documentRender.addChild(commentsContainer);
15970
- commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
15971
- documentRender.rect.width += this.options.reviewWindowWidth;
15972
- }
15973
- }
15974
- return docPages;
15975
- }
15976
- getDocInnerRect(documentRender) {
15977
- const render = documentRender.element.createRenderObject({
15978
- options: this.options,
15979
- renderCtx: this.renderContext
15980
- });
15981
- render.padding = documentRender.padding;
15982
- return render.getInnerRect();
15983
- }
15984
- getFullViewDocRender(documentRender, documentElement) {
15985
- const commentsRender = documentRender.getChild(3);
15986
- const commentsContainer = commentsRender.element.createRenderObject({
15987
- options: this.options,
15988
- renderCtx: this.renderContext
15989
- });
15990
- documentRender.rect.height -= commentsContainer.rect.height;
15991
- const bodyRender = documentRender.getChild(1);
15992
- if (this.options.showReviewWindow) {
15993
- documentRender.removeChild(commentsRender);
15994
- documentRender.addChild(commentsContainer);
15995
- commentsContainer.padding.top = bodyRender.rect.y;
15996
- commentsContainer.rect.height = documentRender.rect.height;
15997
- commentsContainer.rect.x = documentRender.rect.x + documentRender.rect.width;
15998
- documentRender.rect.width += this.options.reviewWindowWidth;
15999
- }
16000
- return [documentRender];
16001
- }
16002
- createEmptyBodyRender(bodyRender, limitRect) {
16003
- const pageBodyRender = bodyRender.element.createRenderObject({
16004
- options: this.options,
16005
- renderCtx: this.renderContext
16006
- });
16007
- pageBodyRender.rect.width = limitRect.width;
16008
- const bodyInnerLimitRect = pageBodyRender.getInnerRect();
16009
- if (this.options.fullPageView) {
16010
- bodyInnerLimitRect.height = Number.MAX_VALUE;
16011
- }
16012
- return {
16013
- emptyBody: pageBodyRender,
16014
- innerRect: { ...bodyInnerLimitRect, prevMargin: 0, maxWidth: limitRect.width, maxHeight: limitRect.height }
16015
- };
16016
- }
16017
- /**
16018
- * 切割渲染元素
16019
- * @param render 被切割的对象
16020
- * @param limitHeight
16021
- * @returns
16022
- */
16023
- cutRenderItem(render, limitHeight) {
16024
- if (render instanceof TableRowRenderObject) {
16025
- return this.cutRowRenderItem(render, limitHeight);
16026
- }
16027
- if (render instanceof TableRenderObject) {
16028
- return this.cutTable(render, limitHeight);
16029
- }
16030
- const cloneRender = render.element.createRenderObject({
16031
- options: this.options,
16032
- renderCtx: this.renderContext
16033
- });
16034
- cloneRender.setRenderWidth(render.rect.width);
16035
- if (render instanceof MuiltBlockLineRenderObject) {
16036
- let sumHeight = 0;
16037
- const children = [...render.getItems()];
16038
- let j = 0;
16039
- let blockLine = children[j];
16040
- while (blockLine) {
16041
- //sumHeight = ElementUtil.remeasure(cloneRender);
16042
- const calcBlockLineHeight = this.getBlockLineHeight(blockLine);
16043
- if (calcBlockLineHeight + sumHeight > limitHeight) {
16044
- if (blockLine instanceof MuiltBlockLineRenderObject) {
16045
- //限制的外框尺寸
16046
- const availHeight = limitHeight - sumHeight;
16047
- //限制的内框尺寸
16048
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(render, availHeight);
16049
- const cutRenderObject = this.cutRenderItem(blockLine, limitRenderInnterHeight);
16050
- if (cutRenderObject) {
16051
- cloneRender.addChild(cutRenderObject);
16052
- sumHeight += cutRenderObject.rect.height;
16053
- blockLine = children[++j];
16054
- break;
16055
- }
16056
- else {
16057
- break;
16058
- }
16059
- }
16060
- else {
16061
- break;
16062
- }
16063
- }
16064
- else {
16065
- render.removeChild(blockLine);
16066
- cloneRender.addChild(blockLine);
16067
- sumHeight += blockLine.rect.height;
16068
- blockLine = children[++j];
16069
- }
16070
- }
16071
- ElementUtil.remeasure(cloneRender);
16072
- ElementUtil.remeasure(render);
16073
- if (cloneRender.length === 0) {
16074
- return null;
16075
- }
16076
- else {
16077
- return cloneRender;
16078
- }
16079
- }
16080
- else {
16081
- throw new Error('未实现');
16082
- }
16083
- }
16084
- /**
16085
- * 切割渲染元素
16086
- * @param tbRender 被切割的对象
16087
- * @param limitHeight
16088
- * @param addFunc
16089
- * @returns
16090
- */
16091
- cutTable(tbRender, limitHeight) {
16092
- const cloneTbRender = tbRender.element.createRenderObject();
16093
- cloneTbRender.setRenderWidth(tbRender.rect.width);
16094
- let sumHeight = 0;
16095
- const rows = [...tbRender.getItems()];
16096
- //获取跨页需要重复显示的行
16097
- const headerRows = this.getHeaderRows(tbRender);
16098
- //跨页头的高度
16099
- const headerHeight = headerRows.reduce((prev, curr) => prev + curr.rect.height, 0);
16100
- if (headerHeight > limitHeight) {
16101
- return null;
16102
- }
16103
- const copyHeaderRows = headerRows.map(item => item.clone());
16104
- //获取最后一个截断行,需要根据截断行判断最后一个截断的行位置
16105
- const cutOffRows = rows.filter(row => limitHeight >= row.rect.y && limitHeight <= row.rect.y + row.rect.height)
16106
- .map((row) => ({ rowIndex: row.element.getIndex(), row }))
16107
- .sort((first, second) => second.rowIndex - first.rowIndex);
16108
- if (cutOffRows.length === 0) {
16109
- throw new Error('无法获取截断行');
16110
- }
16111
- const joinRow = cutOffRows[0].row;
16112
- let j = 0;
16113
- let currRow = rows[j];
16114
- const cutRows = [];
16115
- while (currRow) {
16116
- const rowContentHeight = this.getBlockLineHeight(currRow);
16117
- if (rowContentHeight + sumHeight > limitHeight) {
16118
- if (currRow instanceof MuiltBlockLineRenderObject) {
16119
- //限制的外框尺寸
16120
- const availHeight = limitHeight - sumHeight;
16121
- //限制的内框尺寸
16122
- const limitRenderInnterHeight = ElementUtil.innerRectMaxHeight(tbRender, availHeight);
16123
- const cutRow = this.cutRowRenderItem(currRow, limitRenderInnterHeight);
16124
- if (cutRow) {
16125
- cloneTbRender.addChild(cutRow);
16126
- sumHeight += cutRow.rect.height;
16127
- cutRows.push(currRow);
16128
- if (currRow === joinRow) {
16129
- break;
16130
- }
16131
- currRow = rows[++j];
16132
- }
16133
- else {
16134
- break;
16135
- }
16136
- }
16137
- else {
16138
- break;
16139
- }
16140
- }
16141
- else {
16142
- tbRender.removeChild(currRow);
16143
- cloneTbRender.addChild(currRow);
16144
- sumHeight += currRow.rect.height;
16145
- currRow = rows[++j];
16146
- }
16147
- }
16148
- this.fixCutTable(tbRender, cutRows);
16149
- ElementUtil.remeasure(cloneTbRender);
16150
- //存在跨页需要重复显示的行头,则需要重新放置行头
16151
- if (copyHeaderRows.length) {
16152
- copyHeaderRows.forEach((r, i) => tbRender.insertChild(r, i));
16153
- }
16154
- ElementUtil.remeasure(tbRender);
16155
- if (cloneTbRender.length === 0) {
16156
- return null;
16157
- }
16158
- else {
16159
- return cloneTbRender;
16160
- }
16161
- }
16162
- cutRowRenderItem(render, limitHeight) {
16163
- if (render.element.props.minHeight > 0 && render.rect.height > limitHeight) {
16164
- return null;
16165
- }
16166
- const cloneRowRender = render.element.createRenderObject();
16167
- cloneRowRender.rect.width = render.rect.width;
16168
- render.remeasureState = true;
16169
- //cloneRowRender.rect.maxWidth = render.rect.height;
16170
- const cellRenders = [...render.getItems()];
16171
- const cutCellRenders = [];
16172
- for (let i = 0; i < cellRenders.length; i++) {
16173
- const cellRender = cellRenders[i];
16174
- this.markMergeRowRenderDirty(cellRender);
16175
- if (cellRender.rect.height > limitHeight) {
16176
- //限制的内框尺寸
16177
- const limitCellHeight = ElementUtil.innerRectMaxHeight(cellRender, limitHeight);
16178
- const cutCellRender = this.cutRenderItem(cellRender, limitCellHeight);
16179
- if (cutCellRender) {
16180
- cutCellRenders.push(cutCellRender);
16181
- }
16182
- else {
16183
- cutCellRenders.push(null);
16184
- }
16185
- }
16186
- else {
16187
- const cloneCellRender = cellRender;
16188
- render.removeChild(cellRender);
16189
- cutCellRenders.push(cloneCellRender);
16190
- }
16191
- }
16192
- ElementUtil.remeasure(render);
16193
- if (cutCellRenders.filter(item => item).length === 0) {
16194
- return null;
16195
- }
16196
- else {
16197
- //补齐单元格
16198
- for (let i = 0; i < cutCellRenders.length; i++) {
16199
- let cellRender = cutCellRenders[i];
16200
- if (!cellRender) {
16201
- cellRender = cellRenders[i].element.createRenderObject({
16202
- options: this.options,
16203
- renderCtx: this.renderContext
16204
- });
16205
- cellRender.rect = ElementUtil.cloneRect(cellRenders[i].rect);
16206
- ElementUtil.remeasure(cellRender);
16207
- }
16208
- cloneRowRender.addChild(cellRender);
16209
- }
16210
- ElementUtil.remeasure(cloneRowRender);
16211
- return cloneRowRender;
16212
- }
16213
- }
16214
- /**
16215
- * 标记合并单元格所在行需要重新计算
16216
- * @param cellRender
16217
- * @private
16218
- */
16219
- markMergeRowRenderDirty(cellRender) {
16220
- const cellEle = cellRender.element;
16221
- if (cellEle.props.vMerge !== 'restart') {
16222
- return;
16223
- }
16224
- const rowRender = cellRender.parent;
16225
- rowRender.element;
16226
- const tb = rowRender.parent;
16227
- const cellYPos = cellRender.rect.y;
16228
- for (let i = rowRender.getIndex() + 1; i < tb.length; i++) {
16229
- const nextRowRender = tb.getChild(i);
16230
- if (nextRowRender.rect.y <= cellYPos) {
16231
- nextRowRender.remeasureState = true;
16232
- nextRowRender.getItems().forEach(item => {
16233
- this.markMergeRowRenderDirty(item);
16234
- });
16235
- }
16236
- else {
16237
- break;
16238
- }
16239
- }
16240
- }
16241
- /**
16242
- * 修复->已经截断的合并单元格要向下移动到合适的位置
16243
- * @param tbRender
16244
- * @param cutRows
16245
- * @returns
16246
- */
16247
- fixCutTable(tbRender, cutRows) {
16248
- if (!cutRows.length) {
16249
- return;
16250
- }
16251
- const tbEle = tbRender.element;
16252
- const belowMergeRows = new Set();
16253
- for (let i = 0; i < tbRender.length; i++) {
16254
- const row = tbRender.getChild(i);
16255
- const nextRow = tbRender.getChild(i + 1);
16256
- if (!nextRow) {
16257
- break;
16258
- }
16259
- if (!cutRows.some(item => item === row)) {
16260
- break;
16261
- }
16262
- if (row.length === tbEle.getColsCount()) {
16263
- break;
16264
- }
16265
- if (this.checkFullRow(row)) {
16266
- break;
16267
- }
16268
- for (let j = 0; j < row.length; j++) {
16269
- const cell = row.getChild(j);
16270
- const cellEle = cell.element;
16271
- const colIndex = cellEle.getIndex();
16272
- if (!this.existsCellRender(nextRow, colIndex)) {
16273
- const insertColIndex = this.getRowInsertCellIndex(cell, nextRow);
16274
- if (insertColIndex === -1) {
16275
- this.getRowInsertCellIndex(cell, nextRow);
16276
- throw new Error('未在紧挨下方找到可以放置的位置');
16277
- }
16278
- //row.removeChild(cell);
16279
- nextRow.insertChild(cell, insertColIndex);
16280
- belowMergeRows.add(row);
16281
- ElementUtil.remeasure(nextRow);
16282
- }
16283
- }
16284
- }
16285
- if (belowMergeRows.size) {
16286
- for (const row of belowMergeRows) {
16287
- tbRender.removeChild(row);
16288
- row.clear();
16289
- }
16290
- ElementUtil.remeasure(tbRender);
16291
- }
16292
- }
16293
- /**
16294
- * 校验当前是否是一个完整的行,没有Null单元格,检查当前是否还需要向下合并
16295
- * @param row
16296
- */
16297
- checkFullRow(row) {
16298
- let x = 0;
16299
- for (let i = 0; i < row.length; i++) {
16300
- const cell = row.getChild(i);
16301
- if (cell.rect.x !== x) {
16302
- return false;
15268
+ const commMarks = this.docCtx.document.markPairs;
15269
+ for (let i = 0; i < commMarks.length; i++) {
15270
+ const commMark = commMarks[i];
15271
+ if (commMark.start && commMark.end) {
15272
+ const ancestor = DocumentSelection.getAncestorCommonControl(commMark.start, commMark.end);
15273
+ const range = RangeUtil.getSectionRange(commMark.start, 0, commMark.end, 1, ancestor);
15274
+ SelectionOverlays.addToCommentSets(range, this.seo.commRangeSets, commMark.start.color);
16303
15275
  }
16304
- x += cell.rect.width;
16305
15276
  }
16306
- return x === row.rect.width;
16307
15277
  }
16308
- existsCellRender(rowRender, cellIndex) {
16309
- for (let i = 0; i < rowRender.length; i++) {
16310
- const cellRender = rowRender.getChild(i);
16311
- const cellEle = cellRender.element;
16312
- if (cellEle.getIndex() === cellIndex) {
16313
- return true;
16314
- }
15278
+ cacheRenders(renderTree) {
15279
+ if (renderTree.element) {
15280
+ renderTree.element.paintRenders.push(renderTree);
16315
15281
  }
16316
- return false;
16317
- }
16318
- getBlockLineHeight(render) {
16319
- if (render instanceof TableRowRenderObject) {
16320
- let maxCellHeight = 0;
16321
- for (let i = 0; i < render.length; i++) {
16322
- const itemHeight = render.getChild(i).rect.height;
16323
- if (itemHeight > maxCellHeight) {
16324
- maxCellHeight = itemHeight;
16325
- }
15282
+ for (let i = 0; i < renderTree.length; i++) {
15283
+ const currRender = renderTree.getChild(i);
15284
+ if (currRender.element) {
15285
+ this.cacheCommsRender(currRender);
15286
+ }
15287
+ if (currRender instanceof BranchRenderObject) {
15288
+ this.cacheRenders(currRender);
15289
+ }
15290
+ else {
15291
+ currRender.element && currRender.element.paintRenders.push(currRender);
16326
15292
  }
16327
- return maxCellHeight;
16328
15293
  }
16329
- return render.rect.height;
16330
15294
  }
16331
- getRowInsertCellIndex(sourceCell, destRow) {
16332
- for (let i = 0; i < destRow.length; i++) {
16333
- const cell = destRow.getChild(i);
16334
- const rect = cell.rect;
16335
- if (sourceCell.rect.x < rect.x) {
16336
- return i;
15295
+ /**
15296
+ * 缓存批注标志
15297
+ * @private
15298
+ */
15299
+ cacheCommsRender(render) {
15300
+ if (render.element && render.element.type === 'comm') {
15301
+ const commElement = render.element;
15302
+ if (commElement.props.markType === 'start') {
15303
+ const currDocRender = this.cacheDoc;
15304
+ const docCommContainer = currDocRender.getItems().find(item => item instanceof CommsContainerRenderObject);
15305
+ if (docCommContainer) {
15306
+ docCommContainer.commsMarks.push(render);
15307
+ }
16337
15308
  }
16338
15309
  }
16339
- const lastCell = destRow.getChild(destRow.length - 1);
16340
- if (sourceCell.rect.x >= lastCell.rect.x + lastCell.rect.width) {
16341
- return destRow.length;
15310
+ if (render.element && render.element.type === 'comm-list') {
15311
+ const commContainer = render;
15312
+ CommentsUtil.createCommentsImage(commContainer);
16342
15313
  }
16343
- return -1;
16344
15314
  }
16345
- getHeaderRows(tb) {
16346
- const rows = [];
16347
- for (let i = 0; i < tb.length; i++) {
16348
- const rowRender = tb.getChild(i);
16349
- const rowEle = rowRender.element;
16350
- if (rowEle.props.headerRow) {
16351
- rows.push(rowRender);
16352
- }
16353
- else {
16354
- break;
15315
+ endMeasures(ele) {
15316
+ ele.endMeasure();
15317
+ if (ele instanceof BranchElement) {
15318
+ for (let i = 0; i < ele.length; i++) {
15319
+ this.endMeasures(ele.getChild(i));
16355
15320
  }
16356
15321
  }
16357
- return rows;
15322
+ }
15323
+ createDefaultPara() {
15324
+ const tmp = new ParagraphElement();
15325
+ tmp.props.lineHeight = this.options.defaultLineHeight;
15326
+ return tmp;
16358
15327
  }
16359
15328
  }
16360
15329
 
@@ -16362,8 +15331,7 @@ class DocumentPaint {
16362
15331
  renderContext;
16363
15332
  docCtx;
16364
15333
  seo;
16365
- elementMeasure;
16366
- elementRenderCut;
15334
+ //elementRenderCut: ElementRenderCut;
16367
15335
  elementPaint;
16368
15336
  docPages;
16369
15337
  docContainer;
@@ -16374,8 +15342,7 @@ class DocumentPaint {
16374
15342
  this.docCtx = docCtx;
16375
15343
  this.seo = seo;
16376
15344
  this.viewOptions = this.docCtx.viewOptions;
16377
- this.elementMeasure = new ElementMeasure(this.docCtx, this.renderContext);
16378
- this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
15345
+ //this.elementRenderCut = new ElementRenderCut(this.viewOptions, this.renderContext);
16379
15346
  this.elementPaint = new ElementPaint(this.renderContext, this.docCtx);
16380
15347
  }
16381
15348
  rePages() {
@@ -16534,132 +15501,6 @@ class DocumentPaint {
16534
15501
  }
16535
15502
  }
16536
15503
 
16537
- const fontSize = 12;
16538
- const verPadding = 2;
16539
- /**
16540
- * 恒牙牙位图
16541
- */
16542
- class PermanentTeethElement extends LeafElement {
16543
- constructor() {
16544
- super('permanent-teeth');
16545
- this.props = new PermanentTeethProps();
16546
- this.props.topLeft = '';
16547
- this.props.topRight = '';
16548
- this.props.bottomLeft = '';
16549
- this.props.bottomRight = '';
16550
- }
16551
- clone(data) {
16552
- const clone = new PermanentTeethElement();
16553
- clone.props = this.props.clone();
16554
- return clone;
16555
- }
16556
- createRenderObject(data) {
16557
- const clone = new PermanentTeethRenderObject(this);
16558
- clone.rect.width = 150;
16559
- //字体大小*2+上下间距2*2
16560
- clone.rect.height = fontSize * 2 + verPadding * 2;
16561
- //clone.rect= ElementUtil.cloneRect(this.rect);
16562
- return clone;
16563
- }
16564
- serialize(viewOptions) {
16565
- return {
16566
- type: this.type,
16567
- props: this.props.getSerializeProps(viewOptions)
16568
- };
16569
- }
16570
- }
16571
- class PermanentTeethRenderObject extends LeafRenderObject {
16572
- render(e) {
16573
- }
16574
- clone() {
16575
- const clone = new PermanentTeethRenderObject(this.element);
16576
- clone.rect = ElementUtil.cloneRect(this.rect);
16577
- return clone;
16578
- }
16579
- // measure(): { width: number, height: number } {
16580
- // const ele = this.element;
16581
- //
16582
- // }
16583
- exportHTML(event) {
16584
- const ele = this.element;
16585
- const g = super.exportHTML(event);
16586
- const contentHorPadding = 4;
16587
- g.children = [];
16588
- // g.children.push(ElementUtil.getFillSvgPath(`M 0 ${this.rect.height / 2} h${this.rect.width}`, '#000', 1));
16589
- // g.children.push(ElementUtil.getFillSvgPath(`M ${this.rect.width / 2} 0 v${this.rect.height}`, '#000', 1));
16590
- //
16591
- g.children.push(ElementUtil.getFillSvgRect(0, this.rect.height / 2, this.rect.width, 1, '#000'));
16592
- g.children.push(ElementUtil.getFillSvgRect(this.rect.width / 2, 0, 1, this.rect.height, '#000'));
16593
- const getSvgText = (text, x, y) => {
16594
- return {
16595
- sel: 'text',
16596
- text: text,
16597
- data: {
16598
- ns: "http://www.w3.org/2000/svg",
16599
- attrs: {
16600
- 'dominant-baseline': 'hanging',
16601
- 'font-family': 'Arial',
16602
- 'font-size': fontSize,
16603
- x,
16604
- y,
16605
- }
16606
- },
16607
- };
16608
- };
16609
- const topLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.topLeft, {
16610
- fontSize: fontSize,
16611
- fontName: 'Arial'
16612
- });
16613
- const bottomLeftWidth = event.renderCtx.mainContext.measureTextWidth(ele.props.bottomLeft, {
16614
- fontSize: fontSize,
16615
- fontName: 'Arial'
16616
- });
16617
- g.children.push(getSvgText(ele.props.topLeft, this.rect.width / 2 - topLeftWidth - contentHorPadding, verPadding));
16618
- g.children.push(getSvgText(ele.props.topRight, this.rect.width / 2 + contentHorPadding, verPadding));
16619
- g.children.push(getSvgText(ele.props.bottomLeft, this.rect.width / 2 - bottomLeftWidth - contentHorPadding, this.rect.height - fontSize + verPadding));
16620
- g.children.push(getSvgText(ele.props.bottomRight, this.rect.width / 2 + contentHorPadding, this.rect.height - fontSize + verPadding));
16621
- return g;
16622
- }
16623
- }
16624
- class PermanentTeethFactory extends ElementFactory {
16625
- match(type) {
16626
- return type === 'permanent-teeth';
16627
- }
16628
- createElement(data) {
16629
- const ele = new PermanentTeethElement();
16630
- ele.props.bottomLeft = data.props?.bottomLeft ?? '';
16631
- ele.props.bottomRight = data.props?.bottomRight ?? '';
16632
- ele.props.topLeft = data.props?.topLeft ?? '';
16633
- ele.props.topRight = data.props?.topRight ?? '';
16634
- return ele;
16635
- }
16636
- }
16637
- /**
16638
- * 恒牙牙位图属性
16639
- */
16640
- class PermanentTeethProps extends INotifyPropertyChanged {
16641
- topLeft;
16642
- topRight;
16643
- bottomLeft;
16644
- bottomRight;
16645
- getSerializeProps(viewOptions) {
16646
- return {
16647
- topLeft: this.topLeft,
16648
- topRight: this.topRight,
16649
- bottomLeft: this.bottomLeft,
16650
- bottomRight: this.bottomRight,
16651
- };
16652
- }
16653
- clone(dest) {
16654
- dest = dest || new PermanentTeethProps();
16655
- dest.topLeft = this.topLeft;
16656
- dest.topRight = this.topRight;
16657
- dest.bottomLeft = this.bottomLeft;
16658
- dest.bottomRight = this.bottomRight;
16659
- return dest;
16660
- }
16661
- }
16662
-
16663
15504
  class ElementReader {
16664
15505
  docCtx;
16665
15506
  constructor(docCtx) {
@@ -16702,6 +15543,7 @@ class ElementReader {
16702
15543
  this.addFactory(PageBreakFactory);
16703
15544
  this.addFactory(TabFactory);
16704
15545
  this.addFactory(PermanentTeethFactory);
15546
+ this.addFactory(SVGFactory);
16705
15547
  // this.registerReadFunc<TrackRunProps>('ins-run', (data) => {
16706
15548
  // const props = new TrackRunProps(data.type);
16707
15549
  // props.userId = data.userId;
@@ -16722,29 +15564,18 @@ class ElementReader {
16722
15564
  this.setDocument(document);
16723
15565
  }
16724
15566
  setDocument(document) {
16725
- // if (this.docCtx.document) {
16726
- // this.docCtx.document.destroy();
16727
- // }
16728
- // this.document?.clearItems();
16729
- // document.docProps.clone(this.document.docProps);
16730
15567
  document.bodyElement = document.find((item) => item instanceof DocumentBodyElement);
16731
15568
  document.headerElement = document.find((item) => item instanceof DocumentHeaderElement);
16732
15569
  document.footerElement = document.find((item) => item instanceof DocumentFooterElement);
16733
- // document.commentsContainerElement = document.find((item) => item instanceof CommsContainerElement) as CommsContainerElement;
16734
- // if (!document.commentsContainerElement) {
16735
- // document.commentsContainerElement = new CommsContainerElement();
16736
- // }
16737
15570
  document.clearItems();
16738
15571
  document.addChild(document.headerElement);
16739
15572
  document.addChild(document.bodyElement);
16740
15573
  document.addChild(document.footerElement);
16741
- //document.addChild(document.commentsContainerElement);
16742
15574
  this.docCtx.document = document;
16743
15575
  document.viewOptions = this.docCtx.viewOptions;
16744
15576
  const width = Math.floor(document.props.width * this.docCtx.viewOptions.mmToPixelsRatio);
16745
15577
  const height = Math.floor(document.props.height * this.docCtx.viewOptions.mmToPixelsRatio);
16746
15578
  this.docCtx.viewOptions.docPageSettings = new PageOptions(width, height, document.props.orient);
16747
- //this.viewOptions.viewSettings.width = this.viewOptions.docPageSettings.width + 10;
16748
15579
  }
16749
15580
  readElement(data, strictMode = false) {
16750
15581
  if (typeof data === 'string') {
@@ -16766,6 +15597,7 @@ class ElementReader {
16766
15597
  }
16767
15598
  }
16768
15599
  factory.readCompleted(element, childArr);
15600
+ this.readAttribute(data, element);
16769
15601
  return element;
16770
15602
  }
16771
15603
  }
@@ -16777,6 +15609,11 @@ class ElementReader {
16777
15609
  return null;
16778
15610
  }
16779
15611
  }
15612
+ readAttribute(data, ele) {
15613
+ if (data.attribute) {
15614
+ ele.attribute = data.attribute;
15615
+ }
15616
+ }
16780
15617
  /**
16781
15618
  * 读取扩展属性
16782
15619
  * @param data
@@ -17842,7 +16679,10 @@ class DocumentEvent {
17842
16679
  if (renderObject instanceof LeafRenderObject) {
17843
16680
  if (CommonUtil.isInsideRectByPosition(renderObjectRect, hitPos)) {
17844
16681
  const x = hitPos.x - renderObjectRect.x;
17845
- const offset = ElementUtil.getHitRenderOffset(renderObject, x);
16682
+ let offset = ElementUtil.getHitRenderOffset(renderObject, x);
16683
+ if (!this.ismousedown && renderObject.element && renderObject.element.type === 'psym') {
16684
+ offset = 0;
16685
+ }
17846
16686
  return {
17847
16687
  render: renderObject,
17848
16688
  offset,
@@ -17934,7 +16774,10 @@ class DocumentEvent {
17934
16774
  else {
17935
16775
  x = position.x - adjacentRender.rect.x;
17936
16776
  }
17937
- const offset = ElementUtil.getHitRenderOffset(adjacentRender.render, x);
16777
+ let offset = ElementUtil.getHitRenderOffset(adjacentRender.render, x);
16778
+ if (!this.ismousedown && renderObject.element && renderObject.element.type === 'psym') {
16779
+ offset = 0;
16780
+ }
17938
16781
  return {
17939
16782
  render: adjacentRender.render,
17940
16783
  absoluteRenderRect: adjacentRender.rect,
@@ -20993,7 +19836,8 @@ class ElementTrackManage {
20993
19836
  * @private
20994
19837
  */
20995
19838
  mergeOps(ops) {
20996
- return false;
19839
+ return this.mergeFormatOps(ops);
19840
+ //return false;
20997
19841
  //问题在于:
20998
19842
  //1.新输入的字符串,selectState的startOffset、endOffset=1,后输入的字符串的endOffset进行累加
20999
19843
  //2.撤销后重做,选区范围在1-2,英国是0-2,因为之前在创建文本对象后,选区的结束位为1
@@ -21044,6 +19888,41 @@ class ElementTrackManage {
21044
19888
  // }
21045
19889
  // return false;
21046
19890
  }
19891
+ /**
19892
+ * 将对某个元素的最近两次的属性修改合并为一次,ops为当前记录的修改,比较上次的修改,如果为对同一个元素的修改,则合并
19893
+ * @private
19894
+ */
19895
+ mergeFormatOps(ops) {
19896
+ if (ops.length > 1) {
19897
+ return false;
19898
+ }
19899
+ const lastOps = this.actions[this.actions.length - 1];
19900
+ if (!lastOps || lastOps.ops.length > 1) {
19901
+ return false;
19902
+ }
19903
+ const prevOp = lastOps.ops[lastOps.ops.length - 1];
19904
+ const currOp = ops[0];
19905
+ //操作类型相同
19906
+ if ('format' in currOp.ops && 'format' in prevOp.ops && currOp.index === prevOp.index) {
19907
+ // const prevAfterSelection = lastOps.afterSelection;
19908
+ // if (!prevAfterSelection) {
19909
+ // return false;
19910
+ // }
19911
+ //前后是连续的操作
19912
+ const { format: currFormat } = currOp.ops;
19913
+ const { format: prevFormat } = prevOp.ops;
19914
+ Object.keys(currFormat).forEach(key => {
19915
+ const currValue = currFormat[key].newValue;
19916
+ const prevValue = prevFormat[key].newValue;
19917
+ if (CommonUtil.isEqual(currValue, prevValue)) {
19918
+ return;
19919
+ }
19920
+ prevFormat[key].newValue = currValue;
19921
+ });
19922
+ return true;
19923
+ }
19924
+ return false;
19925
+ }
21047
19926
  getSelection() {
21048
19927
  const { startControl, startOffset, endControl, endOffset, editable } = this.docCtx.selectionState;
21049
19928
  if (!startControl) {
@@ -28956,7 +27835,7 @@ class DocEditor {
28956
27835
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
28957
27836
  }
28958
27837
  version() {
28959
- return "2.1.19";
27838
+ return "2.1.21";
28960
27839
  }
28961
27840
  switchPageHeaderEditor() {
28962
27841
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -28964,7 +27843,7 @@ class DocEditor {
28964
27843
  getTextContent() {
28965
27844
  const paras = this.docCtx.document.treeFilter(item => item instanceof ParagraphElement);
28966
27845
  const paraTexts = paras.map(item => ElementSerialize.serializeString(item, { all: false }));
28967
- return paraTexts.join('\n');
27846
+ return paraTexts.join('');
28968
27847
  }
28969
27848
  emit(event, args) {
28970
27849
  this.eventBus.emit(event, args);
@@ -29009,6 +27888,26 @@ class DocumentCombine {
29009
27888
  }
29010
27889
  }
29011
27890
 
27891
+ /**
27892
+ * 文字行渲染模式
27893
+ 用于医嘱打印模式
27894
+ */
27895
+ function runTextLineRender(ele, data) {
27896
+ if (!data.options.textRowLineMode) {
27897
+ return;
27898
+ }
27899
+ if (ele instanceof TableElement) {
27900
+ // textLineRenderMode(ele, data);
27901
+ // remeasureParentRenders(ele.cacheRender)
27902
+ return;
27903
+ }
27904
+ if (ele instanceof BranchElement) {
27905
+ for (let i = 0; i < ele.length; i++) {
27906
+ runTextLineRender(ele.getChild(i), data);
27907
+ }
27908
+ }
27909
+ }
27910
+
29012
27911
  /**
29013
27912
  * 删除当前段落
29014
27913
  * @param evt
@@ -29297,6 +28196,10 @@ exports.ParagraphLineRectRenderObject = ParagraphLineRectRenderObject;
29297
28196
  exports.ParagraphProps = ParagraphProps;
29298
28197
  exports.ParagraphRenderObject = ParagraphRenderObject;
29299
28198
  exports.PasteElementEvent = PasteElementEvent;
28199
+ exports.PermanentTeethElement = PermanentTeethElement;
28200
+ exports.PermanentTeethFactory = PermanentTeethFactory;
28201
+ exports.PermanentTeethProps = PermanentTeethProps;
28202
+ exports.PermanentTeethRenderObject = PermanentTeethRenderObject;
29300
28203
  exports.PictureElement = PictureElement;
29301
28204
  exports.PictureFactory = PictureFactory;
29302
28205
  exports.PictureProps = PictureProps;
@@ -29311,6 +28214,10 @@ exports.RenderContext = RenderContext;
29311
28214
  exports.RenderObject = RenderObject;
29312
28215
  exports.ResizeLeafRenderObject = ResizeLeafRenderObject;
29313
28216
  exports.RunElementFactory = RunElementFactory;
28217
+ exports.SVGElement = SVGElement;
28218
+ exports.SVGFactory = SVGFactory;
28219
+ exports.SVGProps = SVGProps;
28220
+ exports.SVGRenderObject = SVGRenderObject;
29314
28221
  exports.SelectionOverlays = SelectionOverlays;
29315
28222
  exports.SelectionRange = SelectionRange;
29316
28223
  exports.SelectionState = SelectionState;
@@ -29346,8 +28253,11 @@ exports.ValidateElement = ValidateElement;
29346
28253
  exports.ValidateProps = ValidateProps;
29347
28254
  exports.ValidateRenderObject = ValidateRenderObject;
29348
28255
  exports.ViewOptions = ViewOptions;
28256
+ exports.addReturn = addReturn;
29349
28257
  exports.clearChildrenRenderCache = clearChildrenRenderCache;
29350
28258
  exports.clearTraces = clearTraces;
28259
+ exports.cloneChildren = cloneChildren;
28260
+ exports.cloneElementBase = cloneElementBase;
29351
28261
  exports.createPrintTemplate = createPrintTemplate;
29352
28262
  exports.defaultParaHanging = defaultParaHanging;
29353
28263
  exports.deleteCurrentParagraph = deleteCurrentParagraph;