feat: custom letter class #279
This commit is contained in:
@@ -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 editor(for example: menu bar, bottom toolbar)。default: [0, 0, 0, 0]
|
maskMargin?: IMargin // Masking margins above the editor(for 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 =
|
||||||
|
|||||||
+4
-1
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user