@hailin-zheng/editor-core 2.1.19 → 2.1.21

Sign up to get free protection for your applications and to get access to all the features.
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;