diff --git a/docs/en/guide/schema.md b/docs/en/guide/schema.md index 4420254..361ec37 100644 --- a/docs/en/guide/schema.md +++ b/docs/en/guide/schema.md @@ -77,6 +77,8 @@ interface IElement { conceptId?: string; prefix?: string; postfix?: string; + minWidth?: number; + underline?: boolean; code: string | null; min?: number; max?: number; diff --git a/docs/guide/schema.md b/docs/guide/schema.md index 59a41b0..7201e0c 100644 --- a/docs/guide/schema.md +++ b/docs/guide/schema.md @@ -77,6 +77,8 @@ interface IElement { conceptId?: string; prefix?: string; postfix?: string; + minWidth?: number; + underline?: boolean; code: string | null; min?: number; max?: number; diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index 0a5220c..7884928 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -1038,6 +1038,8 @@ export class Draw { // 列表位置 let listId: string | undefined let listIndex = 0 + // 控件最小宽度 + let controlRealWidth = 0 for (let i = 0; i < elementList.length; i++) { const curRow: IRow = rowList[rowList.length - 1] const element = elementList[i] @@ -1311,6 +1313,23 @@ export class Draw { metrics, style: this._getFont(element, scale) }) + // 暂时只考虑非换行场景:控件开始时统计宽度,结束时消费宽度及还原 + if (rowElement.control?.minWidth) { + if (rowElement.controlComponent) { + controlRealWidth += metrics.width + } + if (rowElement.controlComponent === ControlComponent.POSTFIX) { + const extraWidth = rowElement.control.minWidth - controlRealWidth + // 消费超出实际最小宽度的长度 + if (extraWidth > 0) { + rowElement.left = extraWidth + curRow.width += extraWidth + } else { + rowElement.left = 0 + } + controlRealWidth = 0 + } + } // 超过限定宽度 const preElement = elementList[i - 1] let nextElement = elementList[i + 1] @@ -1562,20 +1581,27 @@ export class Draw { this.textParticle.record(ctx, element, x, y + offsetY) } // 下划线记录 - if (element.underline) { + if (element.underline || element.control?.underline) { const rowMargin = defaultBasicRowMarginHeight * (element.rowMargin || defaultRowMargin) * scale + // 元素偏移量 + const left = element.left || 0 + // 占位符不参与颜色计算 + const color = + element.controlComponent === ControlComponent.PLACEHOLDER + ? undefined + : element.color this.underline.recordFillInfo( ctx, - x, + x - left, y + curRow.height - rowMargin, - metrics.width, + metrics.width + left, 0, - element.color + color ) - } else if (preElement?.underline) { + } else if (preElement?.underline || preElement?.control?.underline) { this.underline.render(ctx) } // 删除线记录 diff --git a/src/editor/core/draw/control/Control.ts b/src/editor/core/draw/control/Control.ts index b8f1704..bdfb90a 100644 --- a/src/editor/core/draw/control/Control.ts +++ b/src/editor/core/draw/control/Control.ts @@ -57,7 +57,9 @@ export class Control { const editorDataKeys: (keyof IEditorData)[] = ['header', 'main', 'footer'] editorDataKeys.forEach(key => { payload[key] = payload[key].filter(element => { - if (element.type !== ElementType.CONTROL) return true + if (element.type !== ElementType.CONTROL || element.control?.minWidth) { + return true + } return ( element.controlComponent !== ControlComponent.PREFIX && element.controlComponent !== ControlComponent.POSTFIX && diff --git a/src/editor/core/draw/richtext/AbstractRichText.ts b/src/editor/core/draw/richtext/AbstractRichText.ts index dcb09a6..809e69c 100644 --- a/src/editor/core/draw/richtext/AbstractRichText.ts +++ b/src/editor/core/draw/richtext/AbstractRichText.ts @@ -31,6 +31,8 @@ export abstract class AbstractRichText { if (!isFirstRecord && this.fillColor && this.fillColor !== color) { this.render(ctx) this.clearFillInfo() + // 重新记录 + this.recordFillInfo(ctx, x, y, width, height, color) return } if (isFirstRecord) { diff --git a/src/editor/core/position/Position.ts b/src/editor/core/position/Position.ts index e48ae06..7707870 100644 --- a/src/editor/core/position/Position.ts +++ b/src/editor/core/position/Position.ts @@ -119,6 +119,10 @@ export class Position { element.type === ElementType.LATEX ? curRow.ascent - metrics.height : curRow.ascent + // 偏移量 + if (element.left) { + x += element.left + } const positionItem: IElementPosition = { pageNo, index, @@ -126,6 +130,7 @@ export class Position { rowIndex: startRowIndex + i, rowNo: i, metrics, + left: element.left || 0, ascent: offsetY, lineHeight: curRow.height, isFirstLetter: j === 0, @@ -265,13 +270,14 @@ export class Position { const { index, pageNo, + left, isFirstLetter, coordinate: { leftTop, rightTop, leftBottom } } = positionList[j] if (positionNo !== pageNo) continue // 命中元素 if ( - leftTop[0] <= x && + leftTop[0] - left <= x && rightTop[0] >= x && leftTop[1] <= y && leftBottom[1] >= y diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index fbbf222..d268e78 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -325,7 +325,9 @@ export class RangeManager { const size = curElement.size || this.options.defaultSize const bold = !~curElementList.findIndex(el => !el.bold) const italic = !~curElementList.findIndex(el => !el.italic) - const underline = !~curElementList.findIndex(el => !el.underline) + const underline = !~curElementList.findIndex( + el => !el.underline && !el.control?.underline + ) const strikeout = !~curElementList.findIndex(el => !el.strikeout) const color = curElement.color || null const highlight = curElement.highlight || null diff --git a/src/editor/interface/Control.ts b/src/editor/interface/Control.ts index 52ab1ad..b0b848c 100644 --- a/src/editor/interface/Control.ts +++ b/src/editor/interface/Control.ts @@ -27,6 +27,8 @@ export interface IControlBasic { conceptId?: string prefix?: string postfix?: string + minWidth?: number + underline?: boolean } export type IControl = IControlBasic & diff --git a/src/editor/interface/Element.ts b/src/editor/interface/Element.ts index d85b297..c2eaa18 100644 --- a/src/editor/interface/Element.ts +++ b/src/editor/interface/Element.ts @@ -136,6 +136,7 @@ export interface IElementPosition { rowNo: number ascent: number lineHeight: number + left: number metrics: IElementMetrics isFirstLetter: boolean isLastLetter: boolean diff --git a/src/editor/interface/Row.ts b/src/editor/interface/Row.ts index 19f31de..1c6ecac 100644 --- a/src/editor/interface/Row.ts +++ b/src/editor/interface/Row.ts @@ -4,6 +4,7 @@ import { IElement, IElementMetrics } from './Element' export type IRowElement = IElement & { metrics: IElementMetrics style: string + left?: number } export interface IRow { diff --git a/src/mock.ts b/src/mock.ts index 3ea44b3..03030d7 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -396,9 +396,34 @@ elementList.push( ]) ) +// 模拟固定长度下划线 +elementList.push( + ...[ + { + value: '患者签名:' + }, + { + type: ElementType.CONTROL, + value: '', + control: { + type: ControlType.TEXT, + value: null, + placeholder: '', + prefix: '\u200c', + postfix: '\u200c', + minWidth: 160, + underline: true + } + } + ] +) + // 模拟结尾文本 elementList.push( ...[ + { + value: '\n' + }, { value: '', type: ElementType.TAB