| 
					
				 | 
			
			
				@@ -1,15 +1,14 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { toPx, CHAR_WIDTH_SCALE_MAP, isNumber, getImageInfo  } from './utils' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { toPx, isNumber, getImageInfo  } from './utils' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { GD } from './gradient' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import QR from './qrcode' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-let id = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	constructor(context, canvas, use2dCanvas = false, isH5PathToBase64 = false, boundary) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	constructor(context, canvas, use2dCanvas = false, isH5PathToBase64 = false, sleep) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.ctx = context 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.canvas = canvas || null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.root = boundary 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.use2dCanvas = use2dCanvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.isH5PathToBase64 = isH5PathToBase64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		this.sleep = sleep 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	roundRect(x, y, w, h, r, fill = false, stroke = false, ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (r < 0) return 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -26,7 +25,6 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				borderBottomRightRadius: br = r || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				borderBottomLeftRadius: bl = r || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} = r || {r,r,r,r} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			ctx.beginPath() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// 右下角 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ctx.arc(x + w - br, y + h - br, br, 0, Math.PI * 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ctx.lineTo(x + bl, y + h) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -44,34 +42,6 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (stroke) ctx.stroke() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (fill) ctx.fill() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	measureText(text, fontSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const { ctx } = this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #ifndef APP-PLUS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return ctx.measureText(text).width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #ifdef APP-PLUS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// app measureText为0需要累加计算0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return text.split("").reduce((widthScaleSum, char) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let code = char.charCodeAt(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let widthScale = CHAR_WIDTH_SCALE_MAP[code - 0x20] || 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return widthScaleSum + widthScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		  }, 0) * fontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	setFont({fontFamily: ff = 'sans-serif', fontSize: fs = 14, fontWeight: fw = 'normal' , textStyle: ts = 'normal'}) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let ctx = this.ctx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 设置属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #ifndef MP-TOUTIAO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// fw = fw == 'bold' ? 'bold' : 'normal' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// ts = ts == 'italic' ? 'italic' : 'normal' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #ifdef MP-TOUTIAO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fw = fw == 'bold' ? 'bold' : '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ts =  ts == 'italic' ? 'italic' : '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// fs = toPx(fs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ctx.font = `${ts} ${fw} ${fs}px ${ff}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	setTransform(box, {transform}) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const {ctx} = this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -118,13 +88,11 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	setShadow({boxShadow: bs = []}) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #ifndef APP-NVUE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const {ctx} = this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (bs.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const [x, y, b, c] = bs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ctx.setShadow(x, y, b, c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	setBorder(box, style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const {ctx} = this 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -263,8 +231,10 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				borderRadius = 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				mode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				padding = {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				backgroundColor: bg, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} = style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			const {paddingTop: pt = 0, paddingLeft: pl= 0, paddingRight: pr= 0, paddingBottom: pb = 0} = padding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			let { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				left: x, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				top: y, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -283,6 +253,10 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ctx.clip() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const _modeImage = (img) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				x += pl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				y += pt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				w = w - pl - pr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				h = h - pt - pb 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 获得图片原始大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				let rWidth = img.width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				let rHeight = img.height 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -291,17 +265,33 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘画区域比例 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const cp = w / h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 原图比例 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 如果大于1 是宽度长 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 如果小于1 是高度长 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const op = rWidth / rHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (cp >= op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					rHeight = rWidth / cp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// startY = Math.round((h - rHeight) / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					rWidth = rHeight * cp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					startX = Math.round(((img.width || w) - rWidth) / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (mode === 'scaleToFill' || !img.width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					ctx.drawImage(img.src, x, y, w, h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else if(mode === 'aspectFit') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if(cp >= op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rWidth = h * op; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rHeight = h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						startX = x + Math.round(w - rWidth) / 2  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						startY = y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rWidth = w 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rHeight = w / op; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						startX = x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						startY = y + Math.round(h - rHeight) / 2  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					ctx.drawImage(img.src, startX, startY, rWidth, rHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if (cp >= op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rHeight = rWidth / cp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// startY = Math.round((h - rHeight) / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						rWidth = rHeight * cp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						startX = Math.round(((img.width || w) - rWidth) / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					// 百度小程序 开发工具 顺序有问题 暂不知晓真机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					// #ifdef MP-BAIDU 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					ctx.drawImage(img.src, x, y, w, h, startX, startY, rWidth, rHeight) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -334,7 +324,7 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				this.setBorder(box, style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					resolve(true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}, this.root.sleep) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}, this.sleep) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(typeof img === 'string') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const {path: src, width, height} = await getImageInfo(img, this.isH5PathToBase64) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -364,24 +354,31 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			verticalAlign: va = 'top', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			backgroundColor: bg, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			maxLines, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			display, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			padding = {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			borderRadius = 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			textDecoration: td 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} = style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const {paddingTop: pt = 0, paddingLeft: pl = 0} = padding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		lineHeight = toPx(lineHeight, fontSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (!text) return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx.save() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.setOpacity(style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.setTransform(box, style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		x = -w/2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		y = -h/2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx.setTextBaseline(va) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		this.setFont({fontFamily, fontSize, fontWeight, textStyle}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ctx.setFont({fontFamily, fontSize, fontWeight, textStyle}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx.setTextAlign(textAlign) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(bg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			this.setBackground(bg, w, h) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.roundRect(x, y, w, h, 1, bg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this.roundRect(x, y, w, h, borderRadius, 1, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 if(display && display.includes('lock')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			x += pl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			y += pt  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.setShadow(style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx.setFillStyle(color) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -418,7 +415,7 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const textWidth = this.measureText(text, fontSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const textWidth = ctx.measureText(text, fontSize).width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const actualHeight = Math.ceil(textWidth / w) * lineHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		let paddingTop = Math.ceil((h - actualHeight) / 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (paddingTop < 0) paddingTop = 0 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -497,7 +494,6 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const _reset = (text, x, y) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const rs = Object.keys(rulesObj) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			for (let i = 0; i < rs.length; i++) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -513,9 +509,9 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const _setText = (isReset, char) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(isReset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const t1 = Math.round(this.measureText('\u0020', fontSize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const t2 = Math.round(this.measureText('\u3000', fontSize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const t3 = Math.round(this.measureText(char, fontSize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const t1 = Math.round(ctx.measureText('\u0020', fontSize).width) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const t2 = Math.round(ctx.measureText('\u3000', fontSize).width) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const t3 = Math.round(ctx.measureText(char, fontSize).width) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				let _char = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				let _num = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if(t3 == t2){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -547,7 +543,7 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					const t = _text[index] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					let char = _setText(rulesObj[index], t)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					_text[index] = char 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					_setRulesObj(t, index, x + this.measureText(text.substring(0, index), fontSize), y + inlinePaddingTop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					_setRulesObj(t, index, x + ctx.measureText(text.substring(0, index), fontSize).width, y + inlinePaddingTop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				_reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -565,7 +561,6 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// 逐行绘制 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		let line = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		let lineIndex = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for(let index = 0 ; index <= chars.length; index++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			let ch = chars[index] || '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const isLine = ch === '\n' 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -573,25 +568,26 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ch = isLine ? '' : ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			let textline = line + _setText(rulesObj[index], ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let textWidth = this.measureText(textline, fontSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			let textWidth = ctx.measureText(textline, fontSize).width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// 绘制行数大于最大行数,则直接跳出循环 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (lineIndex >= maxLines) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(lineIndex == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				textWidth = textWidth + ol 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				_x += ol 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				_x = x + ol 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				textWidth = textWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				_x = x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if(rulesObj[index]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				_setRulesObj(ch, index, _x + this.measureText(line, fontSize), y + inlinePaddingTop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				_setRulesObj(ch, index, _x + ctx.measureText(line, fontSize).width, y + inlinePaddingTop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (textWidth > w || isLine || isRight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				lineIndex++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				line = isRight && textWidth <= w ? textline : line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if(lineIndex === maxLines && textWidth > w) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					while( this.measureText(`${line}...`, fontSize) > w) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					while( ctx.measureText(`${line}...`, fontSize).width > w) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						if (line.length <= 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							// 如果只有一个字符时,直接跳出循环 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							break; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -619,299 +615,6 @@ export class Draw { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx.restore() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.setBorder(box, style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	async findNode(element, parent = {}, index = 0, siblings = [], source) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let computedStyle = Object.assign({}, this.getComputedStyle(element, parent, index)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let attributes = await this.getAttributes(element) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let node = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			id: id++, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			parent, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			computedStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			rules: element.rules, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			attributes: Object.assign({}, attributes), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			name: element?.type || 'view', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(JSON.stringify(parent) === '{}' && !element.type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const {left = 0, top = 0, width = 0, height = 0 } = computedStyle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			node.layoutBox = {left, top, width, height } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			node.layoutBox = Object.assign({left: 0, top: 0}, this.getLayoutBox(node, parent, index, siblings, source)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (element?.views) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let childrens = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			node.children = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let i = 0; i < element.views.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let v = element.views[i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				childrens.push(await this.findNode(v, node, i, childrens, element)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 node.children = childrens 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return node 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	getComputedStyle(element, parent = {}, index = 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const style = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const node = JSON.stringify(parent) == '{}' && !element.type ? element :  element.css; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(parent.computedStyle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let value of Object.keys(parent.computedStyle)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const item = parent.computedStyle[value] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(['color', 'fontSize', 'lineHeight', 'verticalAlign', 'fontWeight', 'textAlign'].includes(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[value] = /em|px$/.test(item) ? toPx(item, node?.fontSize) : item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(!node) return style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (let value of Object.keys(node)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const item = node[value] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(value == 'views') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (['boxShadow', 'shadow'].includes(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let shadows = item.split(' ').map(v => /^\d/.test(v) ? toPx(v) : v) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style.boxShadow = shadows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (value.includes('border') && !value.includes('adius')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const prefix = value.match(/^border([BTRLa-z]+)?/)[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const type = value.match(/[W|S|C][a-z]+/) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let v = item.split(' ').map(v => /^\d/.test(v) ? toPx(v) : v) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(v.length > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[prefix] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Width'] : v[0] || 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Style'] : v[1] || 'solid', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Color'] : v[2] || 'black' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[prefix] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Width'] :  1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Style'] : 'solid', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						[prefix + 'Color'] : 'black' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[prefix][prefix + type[0]] = v[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (['background', 'backgroundColor'].includes(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style['backgroundColor'] = item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(value.includes('padding') || value.includes('margin') || value.includes('adius')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let isRadius = value.includes('adius') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let prefix = isRadius ? 'borderRadius' : value.match(/[a-z]+/)[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let pre = [0,0,0,0].map((item, i) => isRadius ? ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'][i] : [prefix + 'Top', prefix + 'Right', prefix + 'Bottom', prefix + 'Left'][i] ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(value === 'padding' || value === 'margin' || value === 'radius' || value === 'borderRadius') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					let v = item?.split(' ').map((item) => /^\d/.test(item) && toPx(item, node['width']), []) ||[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					let type = isRadius ? 'borderRadius' : value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(v.length == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[type] = v[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let [t, r, b, l] = v 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[type] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[0]]: t, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[1]]: isNumber(r) ? r : t, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[2]]: isNumber(b) ? b : t, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[3]]: isNumber(l) ? l : r 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(typeof style[prefix] === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[prefix][value] = toPx(item, node['width']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[prefix] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[0]]: style[prefix] || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[1]]: style[prefix] || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[2]]: style[prefix] || 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							[pre[3]]: style[prefix] || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[prefix][value] = toPx(item, node['width']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(value.includes('width') || value.includes('height')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(/%$/.test(item)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[value] = toPx(item, parent.layoutBox[value]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					style[value] = /px|rpx$/.test(item) ? toPx(item) : item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(value.includes('transform')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style[value]= {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				item.replace(/([a-zA-Z]+)\(([0-9,-\.%rpxdeg\s]+)\)/g, (g1, g2, g3) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const v = g3.split(',').map(k => k.replace(/(^\s*)|(\s*$)/g,'')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const transform = (v, r) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						return v.includes('deg') ? v * 1 : toPx(v, r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if(g2.includes('matrix')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[value][g2] = v.map(v => v * 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else if(g2.includes('rotate')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[value][g2] = g3.match(/\d+/)[0] * 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}else if(/[X, Y]/.test(g2)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[value][g2] = /[X]/.test(g2) ? transform(v[0], node['width']) : transform(v[0], node['height']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[value][g2+'X'] = transform(v[0], node['width']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						style[value][g2+'Y'] = transform(v[1] || v[0], node['height']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(/em$/.test(item) && !value.includes('lineHeight')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style[value] =  Math.ceil(parseFloat(item.replace('em')) * toPx(node['fontSize'] || 14)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style[value] = /%|px|rpx$/.test(item) ? toPx(item, node['width']) : item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if((element.name == 'image' || element.type == 'image') && !style.mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			style.mode = 'aspectFill' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if((!node.width || node.width == 'auto') && (!node.height || node.width == 'auto') ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				style.mode = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	getLayoutBox(element, parent = {}, index = 0, siblings = [], source = {}) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let box = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let {name, computedStyle: cstyle, layoutBox, attributes} = element || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(!name) return box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const {ctx} = this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const pbox = parent.layoutBox || this.root 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const pstyle = parent.computedStyle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			verticalAlign: v,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			left: x,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			top: y, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			width: w, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			height: h, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			fontSize = 14, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			lineHeight = '1.4em', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			maxLines, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			fontWeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			fontFamily, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			textStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			position, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			display 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}  = cstyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const { paddingTop: pt = 0, paddingRight: pr = 0, paddingBottom: pb = 0, paddingLeft: pl = 0, } = cstyle.padding || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const { marginTop: mt = 0, marginRight: mr = 0, marginBottom: mb = 0, marginLeft: ml = 0, } = cstyle.margin || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(position == 'relative') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			x += pbox.left 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			y += pbox.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(name === 'text') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const text = attributes.text ||'' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			lineHeight = toPx(lineHeight, fontSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			ctx.save() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.setFont({fontFamily, fontSize, fontWeight, textStyle}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const {layoutBox: lbox, computedStyle: ls} = siblings[index - 1] || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const {layoutBox: rbox, computedStyle: rs} = siblings[index + 1] || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const isLeft = index == 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const isblock = display === 'block' || ls?.display === 'block' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const isOnly = isLeft && !rbox || !parent?.id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const lboxR = isLeft || isblock ? 0 : lbox.offsetRight || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let texts = text.split('\n') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let lineIndex = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let line = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const textIndent = cstyle.textIndent || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(!isOnly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				texts.map((t, i) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					lineIndex += i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const chars = t.split('') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					for (let j = 0; j < chars.length; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let ch = chars[j] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let textline = line + ch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let textWidth = this.measureText(textline, fontSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if(lineIndex == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							textWidth = textWidth + (isblock ? 0 : lboxR) +  textIndent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if(textWidth > pbox.width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							lineIndex++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							line = ch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							line = textline 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				line = text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				lineIndex = Math.max(texts.length, Math.ceil(this.measureText(text, fontSize) / ((w || pbox.width) - this.measureText('0', fontSize)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.offsetLeft = (isNumber(x) || isblock || isOnly ? textIndent : lboxR) +  pl + ml; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// 剩下的字宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const remain = (this.measureText(line, fontSize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			let width =  lineIndex > 1 ? pbox.width : remain + box.offsetLeft; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.offsetRight = box.offsetLeft + (w ? w : (isblock ? pbox.width : remain)) + pr + mr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const _getLeft = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return (x || pbox.left) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const _getWidth = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return w || (isOnly ? pbox.width : (width > pbox.width - box.left || lineIndex > 1 ?  pbox.width - box.left : width)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const _getHeight = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(h) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else if(lineIndex > 1 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return (maxLines || lineIndex) * lineHeight + pt + pb + mt + mb 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return lineHeight + pt + pb + mt + mb 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const _getTop = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				let _y = y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(_y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return _y + pt + mt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if(isLeft) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					_y = pbox.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else if(lbox.width < pbox.width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					_y = lbox.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					_y = lbox.top + lbox.height - (ls?.lineHeight || 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return _y + pt + mt + (isblock && ls?.lineHeight || 0 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.left = _getLeft()  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.width = _getWidth()  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.height = _getHeight() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.top = _getTop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			ctx.restore() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} else if(['view', 'qrcode'].includes(name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.left = x || pbox.left 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.width = (w || pbox?.width) - pl - pr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.height = h || 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.top = y || pbox.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} else if(name === 'image') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.left = x || pbox.left 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.width = (w || pbox?.width) - pl - pr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				width: rWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				height: rHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} = attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.height = h || box.width * rHeight / rWidth  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			box.top = y || pbox.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	async getAttributes(element) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let arr = { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(element?.url || element?.src) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			arr.src = element.url || element?.src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const {width = 0, height = 0, path: src} = await getImageInfo(arr.src, this.isH5PathToBase64) || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			arr = Object.assign({}, arr, {width, height, src}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if(element?.text) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			arr.text = element.text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return arr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	async drawBoard(element) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const node = await this.findNode(element) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return this.drawNode(node) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async drawNode(element) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			layoutBox, 
			 |