feat: custom letter class #279

pr675
Hufe921 3 years ago
parent 05caccc74c
commit de769778c0

@ -51,10 +51,11 @@ interface IEditorOption {
pageNumber?: IPageNumber // Page number information. {bottom:number; size:number; font:string; color:string; rowFlex:RowFlex; format:string; numberType:NumberType;} pageNumber?: IPageNumber // Page number information. {bottom:number; size:number; font:string; color:string; rowFlex:RowFlex; format:string; numberType:NumberType;}
paperDirection?: PaperDirection // Paper orientation: portrait, landscape paperDirection?: PaperDirection // Paper orientation: portrait, landscape
inactiveAlpha?: number // When the body content is out of focus, transparency. default: 0.6 inactiveAlpha?: number // When the body content is out of focus, transparency. default: 0.6
historyMaxRecordCount: number // History (undo redo) maximum number of records. default: 100 historyMaxRecordCount?: number // History (undo redo) maximum number of records. default: 100
printPixelRatio: number // Print the pixel ratio (larger values are clearer, but larger sizes). default: 3 printPixelRatio?: number // Print the pixel ratio (larger values are clearer, but larger sizes). default: 3
maskMargin: IMargin // Masking margins above the editorfor example: menu bar, bottom toolbar。default: [0, 0, 0, 0] maskMargin?: IMargin // Masking margins above the editorfor example: menu bar, bottom toolbar。default: [0, 0, 0, 0]
wordBreak: WordBreak // Word and punctuation breaks: No punctuation in the first line of the BREAK_WORD &The word is not split, and the line is folded after BREAK_ALL full according to the width of the character. default: BREAK_WORD letterClass? string[] // Alphabet class supported by typesetting. default: a-zA-Z. Built-in alternative alphabet class: LETTER_CLASS
wordBreak?: WordBreak // Word and punctuation breaks: No punctuation in the first line of the BREAK_WORD &The word is not split, and the line is folded after BREAK_ALL full according to the width of the character. default: BREAK_WORD
watermark?: IWatermark // Watermark{data:string; color?:string; opacity?:number; size?:number; font?:string;} watermark?: IWatermark // Watermark{data:string; color?:string; opacity?:number; size?:number; font?:string;}
control?: IControlOption // Control {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;} control?: IControlOption // Control {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;}
checkbox?: ICheckboxOption // Checkbox {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;} checkbox?: ICheckboxOption // Checkbox {width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;}

@ -51,10 +51,11 @@ interface IEditorOption {
pageNumber?: IPageNumber // 页码信息。{bottom:number; size:number; font:string; color:string; rowFlex:RowFlex; format:string; numberType:NumberType;} pageNumber?: IPageNumber // 页码信息。{bottom:number; size:number; font:string; color:string; rowFlex:RowFlex; format:string; numberType:NumberType;}
paperDirection?: PaperDirection // 纸张方向:纵向、横向 paperDirection?: PaperDirection // 纸张方向:纵向、横向
inactiveAlpha?: number // 正文内容失焦时透明度。默认值0.6 inactiveAlpha?: number // 正文内容失焦时透明度。默认值0.6
historyMaxRecordCount: number // 历史撤销重做最大记录次数。默认100次 historyMaxRecordCount?: number // 历史撤销重做最大记录次数。默认100次
printPixelRatio: number // 打印像素比率值越大越清晰但尺寸越大。默认3 printPixelRatio?: number // 打印像素比率值越大越清晰但尺寸越大。默认3
maskMargin: IMargin // 编辑器上的遮盖边距(如悬浮到编辑器上的菜单栏、底部工具栏)。默认:[0, 0, 0, 0] maskMargin?: IMargin // 编辑器上的遮盖边距(如悬浮到编辑器上的菜单栏、底部工具栏)。默认:[0, 0, 0, 0]
wordBreak: WordBreak // 单词与标点断行BREAK_WORD首行不出现标点&单词不拆分、BREAK_ALL按字符宽度撑满后折行。默认BREAK_WORD letterClass? string[] // 排版支持的字母类。默认a-zA-Z。内置可选择的字母表类LETTER_CLASS
wordBreak?: WordBreak // 单词与标点断行BREAK_WORD首行不出现标点&单词不拆分、BREAK_ALL按字符宽度撑满后折行。默认BREAK_WORD
watermark?: IWatermark // 水印信息。{data:string; color?:string; opacity?:number; size?:number; font?:string;} watermark?: IWatermark // 水印信息。{data:string; color?:string; opacity?:number; size?:number; font?:string;}
control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;} control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;}
checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;} checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; fontStyle?: string;}

@ -79,7 +79,6 @@ import { Footer } from './frame/Footer'
import { INLINE_ELEMENT_TYPE } from '../../dataset/constant/Element' import { INLINE_ELEMENT_TYPE } from '../../dataset/constant/Element'
import { ListParticle } from './particle/ListParticle' import { ListParticle } from './particle/ListParticle'
import { Placeholder } from './frame/Placeholder' import { Placeholder } from './frame/Placeholder'
import { WORD_LIKE_REG } from '../../dataset/constant/Regular'
import { EventBus } from '../event/eventbus/EventBus' import { EventBus } from '../event/eventbus/EventBus'
import { EventBusMap } from '../../interface/EventBus' import { EventBusMap } from '../../interface/EventBus'
import { Group } from './interactive/Group' import { Group } from './interactive/Group'
@ -140,6 +139,8 @@ export class Draw {
private selectionObserver: SelectionObserver private selectionObserver: SelectionObserver
private imageObserver: ImageObserver private imageObserver: ImageObserver
private LETTER_REG: RegExp
private WORD_LIKE_REG: RegExp
private rowList: IRow[] private rowList: IRow[]
private pageRowList: IRow[][] private pageRowList: IRow[][]
private painterStyle: IElementStyle | null private painterStyle: IElementStyle | null
@ -219,6 +220,11 @@ export class Draw {
this.workerManager = new WorkerManager(this) this.workerManager = new WorkerManager(this)
const { letterClass } = options
this.LETTER_REG = new RegExp(`[${letterClass.join('')}]`)
this.WORD_LIKE_REG = new RegExp(
`${letterClass.map(letter => `[^${letter}][${letter}]`).join('|')}`
)
this.rowList = [] this.rowList = []
this.pageRowList = [] this.pageRowList = []
this.painterStyle = null this.painterStyle = null
@ -234,6 +240,10 @@ export class Draw {
}) })
} }
public getLetterReg(): RegExp {
return this.LETTER_REG
}
public getMode(): EditorMode { public getMode(): EditorMode {
return this.mode return this.mode
} }
@ -1346,7 +1356,7 @@ export class Draw {
) { ) {
// 英文单词 // 英文单词
const word = `${preElement?.value || ''}${element.value}` const word = `${preElement?.value || ''}${element.value}`
if (WORD_LIKE_REG.test(word)) { if (this.WORD_LIKE_REG.test(word)) {
const { width, endElement } = this.textParticle.measureWord( const { width, endElement } = this.textParticle.measureWord(
ctx, ctx,
elementList, elementList,

@ -1,6 +1,5 @@
import { ElementType, IElement } from '../../..' import { ElementType, IElement } from '../../..'
import { PUNCTUATION_LIST } from '../../../dataset/constant/Common' import { PUNCTUATION_LIST } from '../../../dataset/constant/Common'
import { LETTER_REG } from '../../../dataset/constant/Regular'
import { IRowElement } from '../../../interface/Row' import { IRowElement } from '../../../interface/Row'
import { Draw } from '../Draw' import { Draw } from '../Draw'
@ -10,6 +9,7 @@ export interface IMeasureWordResult {
} }
export class TextParticle { export class TextParticle {
private draw: Draw
private ctx: CanvasRenderingContext2D private ctx: CanvasRenderingContext2D
private curX: number private curX: number
private curY: number private curY: number
@ -19,6 +19,7 @@ export class TextParticle {
public cacheMeasureText: Map<string, TextMetrics> public cacheMeasureText: Map<string, TextMetrics>
constructor(draw: Draw) { constructor(draw: Draw) {
this.draw = draw
this.ctx = draw.getCtx() this.ctx = draw.getCtx()
this.curX = -1 this.curX = -1
this.curY = -1 this.curY = -1
@ -32,6 +33,7 @@ export class TextParticle {
elementList: IElement[], elementList: IElement[],
curIndex: number curIndex: number
): IMeasureWordResult { ): IMeasureWordResult {
const LETTER_REG = this.draw.getLetterReg()
let width = 0 let width = 0
let endElement: IElement = elementList[curIndex] let endElement: IElement = elementList[curIndex]
let i = curIndex let i = curIndex

@ -1,9 +1,10 @@
import { ZERO } from '../../../dataset/constant/Common' import { ZERO } from '../../../dataset/constant/Common'
import { LETTER_REG, NUMBER_LIKE_REG } from '../../../dataset/constant/Regular' import { NUMBER_LIKE_REG } from '../../../dataset/constant/Regular'
import { CanvasEvent } from '../CanvasEvent' import { CanvasEvent } from '../CanvasEvent'
function dblclick(host: CanvasEvent, evt: MouseEvent) { function dblclick(host: CanvasEvent, evt: MouseEvent) {
const draw = host.getDraw() const draw = host.getDraw()
const LETTER_REG = draw.getLetterReg()
const position = draw.getPosition() const position = draw.getPosition()
// 切换区域 // 切换区域
if (draw.getIsPagingMode()) { if (draw.getIsPagingMode()) {

@ -27,3 +27,16 @@ export const maxHeightRadioMapping: Record<MaxHeightRatio, number> = {
[MaxHeightRatio.ONE_THIRD]: 1 / 3, [MaxHeightRatio.ONE_THIRD]: 1 / 3,
[MaxHeightRatio.QUARTER]: 1 / 4 [MaxHeightRatio.QUARTER]: 1 / 4
} }
export const LETTER_CLASS = {
ENGLISH: 'A-Za-z',
SPANISH: 'A-Za-zÁÉÍÓÚáéíóúÑñÜü',
FRENCH: 'A-Za-zÀÂÇàâçÉéÈèÊêËëÎîÏïÔôÙùÛûŸÿ',
GERMAN: 'A-Za-zÄäÖöÜüß',
RUSSIAN: 'А-Яа-яЁё',
PORTUGUESE: 'A-Za-zÁÉÍÓÚáéíóúÃÕãõÇç',
ITALIAN: 'A-Za-zÀàÈèÉéÌìÍíÎîÓóÒòÙù',
DUTCH: 'A-Za-zÀàÁáÂâÄäÈèÉéÊêËëÌìÍíÎîÏïÓóÒòÔôÖöÙùÛûÜü',
SWEDISH: 'A-Za-zÅåÄäÖö',
GREEK: 'ΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσςΤτΥυΦφΧχΨψΩω'
}

@ -1,8 +1,6 @@
export const NUMBER_REG = /[0-9]/ export const NUMBER_REG = /[0-9]/
export const LETTER_REG = /[a-zA-Z]/
export const NUMBER_LIKE_REG = /[0-9.]/ export const NUMBER_LIKE_REG = /[0-9.]/
export const CHINESE_REG = /[\u4e00-\u9fa5]/ export const CHINESE_REG = /[\u4e00-\u9fa5]/
export const WORD_LIKE_REG = /[^a-zA-Z][a-zA-Z]/
export const SURROGATE_PAIR_REG = /[\uD800-\uDBFF][\uDC00-\uDFFF]/ // unicode代理对surrogate pair export const SURROGATE_PAIR_REG = /[\uD800-\uDBFF][\uDC00-\uDFFF]/ // unicode代理对surrogate pair
// https://github.com/mathiasbynens/emoji-test-regex-pattern // https://github.com/mathiasbynens/emoji-test-regex-pattern
export const EMOJI_REG = export const EMOJI_REG =

@ -65,6 +65,7 @@ import { IRangeStyle } from './interface/Listener'
import { Override } from './core/override/Override' import { Override } from './core/override/Override'
import { defaultPageBreakOption } from './dataset/constant/PageBreak' import { defaultPageBreakOption } from './dataset/constant/PageBreak'
import { IPageBreak } from './interface/PageBreak' import { IPageBreak } from './interface/PageBreak'
import { LETTER_CLASS } from './dataset/constant/Common'
export default class Editor { export default class Editor {
public command: Command public command: Command
@ -164,6 +165,7 @@ export default class Editor {
wordBreak: WordBreak.BREAK_WORD, wordBreak: WordBreak.BREAK_WORD,
printPixelRatio: 3, printPixelRatio: 3,
maskMargin: [0, 0, 0, 0], maskMargin: [0, 0, 0, 0],
letterClass: [LETTER_CLASS.ENGLISH],
...options, ...options,
header: headerOptions, header: headerOptions,
footer: footerOptions, footer: footerOptions,
@ -243,6 +245,8 @@ export default class Editor {
// 对外对象 // 对外对象
export { export {
EDITOR_COMPONENT,
LETTER_CLASS,
Editor, Editor,
RowFlex, RowFlex,
VerticalAlign, VerticalAlign,
@ -251,7 +255,6 @@ export {
ElementType, ElementType,
ControlType, ControlType,
EditorComponent, EditorComponent,
EDITOR_COMPONENT,
PageMode, PageMode,
ImageDisplay, ImageDisplay,
Command, Command,

@ -63,6 +63,7 @@ export interface IEditorOption {
historyMaxRecordCount?: number historyMaxRecordCount?: number
printPixelRatio?: number printPixelRatio?: number
maskMargin?: IMargin maskMargin?: IMargin
letterClass?: string[]
wordBreak?: WordBreak wordBreak?: WordBreak
header?: IHeader header?: IHeader
footer?: IFooter footer?: IFooter

Loading…
Cancel
Save