modern-text 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +395 -317
- package/package.json +1 -1
- package/types/bounding-box.d.ts +4 -8
- package/types/canvas.d.ts +17 -1
- package/types/character.d.ts +16 -0
- package/types/fragment.d.ts +10 -15
- package/types/measure-text.d.ts +2 -1
- package/types/paragraph.d.ts +7 -19
- package/types/render-text.d.ts +0 -6
- package/types/types.d.ts +6 -0
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class B{get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}constructor({x:t=0,y:o=0,width:h=0,height:l=0}={}){this.x=t,this.y=o,this.width=h,this.height=l}static from(...t){const o=t[0],h=t.slice(1).reduce((l,a)=>(l.x=Math.min(l.x,a.x),l.y=Math.min(l.y,a.y),l.right=Math.max(l.right,a.right),l.bottom=Math.max(l.bottom,a.bottom),l),{x:o.x,y:o.y,right:o.right,bottom:o.bottom});return new B({x:h.x,y:h.y,width:h.right-h.x,height:h.bottom-h.y})}move(t,o){return this.x+=t,this.y+=o,this}clone(){return new B({x:this.x,y:this.y,width:this.width,height:this.height})}}class ${constructor({content:t="",style:o,parent:h,contentBox:l=new B,inlineBox:a=new B,glyphBox:x=new B,centerX:u=0,baseline:w=0}={}){switch(this.content=t,this.style=o,this.parent=h,this.contentBox=l,this.inlineBox=a,this.glyphBox=x,this.centerX=u,this.baseline=w,this.getComputedStyle().textTransform){case"uppercase":this.content=this.content.toUpperCase();break;case"lowercase":this.content=this.content.toLowerCase();break}}getComputedStyle(){var t;return{...(t=this.parent)==null?void 0:t.getComputedStyle(),...this.style}}clone(t){return new $({content:this.content,style:this.style,parent:this.parent,contentBox:this.contentBox.clone(),inlineBox:this.inlineBox.clone(),glyphBox:this.glyphBox.clone(),centerX:this.centerX,baseline:this.baseline,...t})}}class M{constructor({style:t,parent:o,contentBox:h=new B,lineBox:l=new B,glyphBox:a=new B,baseline:x=0,xHeight:u=0,maxCharWidth:w=0,fragments:m=[]}={}){this.style=t,this.parent=o,this.contentBox=h,this.lineBox=l,this.glyphBox=a,this.baseline=x,this.xHeight=u,this.maxCharWidth=w,this.fragments=m}addFragment(t){return this.fragments.push(new $({...t,parent:this})),this}getComputedStyle(){return{...this.parent,...this.style}}clone(t){return new M({style:this.style,parent:this.parent,contentBox:this.contentBox.clone(),lineBox:this.lineBox.clone(),glyphBox:this.glyphBox.clone(),baseline:this.baseline,xHeight:this.xHeight,maxCharWidth:this.maxCharWidth,fragments:this.fragments.map(o=>o.clone()),...t})}}function K(r,t){const o=[];if(typeof r=="string")o.push(new M({parent:t}).addFragment({content:r}));else{r=Array.isArray(r)?r:[r];for(const h of r)if(typeof h=="string")o.push(new M({parent:t}).addFragment({content:h}));else if(Array.isArray(h)){const l=new M({parent:t});h.forEach(a=>{if(typeof a=="string")l.addFragment({content:a});else{const{content:x,...u}=a;l.addFragment({content:x,style:u})}}),o.push(l)}else if("fragments"in h){const{fragments:l,...a}=h,x=new M({style:a,parent:t});l.forEach(u=>{const{content:w,...m}=u;x.addFragment({content:w,style:m})}),o.push(x)}else if("content"in h){const{content:l,...a}=h;o.push(new M({style:a,parent:t}).addFragment({content:l}))}}return o}const j="OffscreenCanvas"in globalThis;let U;function I(){return U??(U=j?new OffscreenCanvas(1,1):document.createElement("canvas"))}function R(r,t){switch(t.shadowColor&&(r.shadowColor=t.shadowColor),t.shadowOffsetX!==void 0&&(r.shadowOffsetX=t.shadowOffsetX),t.shadowOffsetY!==void 0&&(r.shadowOffsetY=t.shadowOffsetY),t.shadowBlur!==void 0&&(r.shadowBlur=t.shadowBlur),t.textStrokeColor&&(r.strokeStyle=t.textStrokeColor),t.textStrokeWidth!==void 0&&(r.lineWidth=t.textStrokeWidth),t.color&&(r.fillStyle=t.color),t.textAlign&&(r.textAlign=t.textAlign),t.fontKerning&&(r.fontKerning=t.fontKerning),t.verticalAlign){case"baseline":r.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":r.textBaseline=t.verticalAlign;break}t.letterSpacing!==void 0&&(r.letterSpacing=`${t.letterSpacing}px`),(t.fontStyle||t.fontWeight!==void 0||t.fontSize!==void 0||t.fontFamily)&&(r.font=[t.fontStyle||"normal",t.fontWeight||"normal",`${t.fontSize||14}px`,t.fontFamily||"sans-serif"].join(" "))}function z(r,t){const o=I().getContext("2d");return R(o,t),o.measureText(r)}const V=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;function q(r,t,o){const h=[],l=r.slice();let a,x;for(;a=l.shift();){const u=a.fragments.slice();let w=0;const m=[];for(;x=u.shift();){const b=x.getComputedStyle();let y="",s=!1,v=0,e="";for(const i of x.content){if(a.maxCharWidth=Math.max(a.maxCharWidth,z(i,{...b,letterSpacing:0}).width),e+=i,V.test(x.content[++v]))continue;let S,c;switch(b.writingMode){case"vertical-lr":case"vertical-rl":S=o,c=e.length*b.fontSize;break;case"horizontal-tb":default:S=t,c=z(e,{...b,letterSpacing:0}).width;break}c+=e.length*b.letterSpacing;const d=/^[\r\n]$/.test(e);if(d||b.textWrap==="wrap"&&S&&w+c>S){let g=d?y.length+1:y.length;!w&&!g&&(y+=e,g+=e.length),y.length&&m.push(x.clone({content:y})),m.length&&(h.push(a.clone({fragments:m.slice()})),m.length=0);const n=x.content.substring(g);(n.length||u.length)&&l.unshift(a.clone({maxCharWidth:0,fragments:(n.length?[x.clone({content:n})]:[]).concat(u.slice())})),u.length=0,s=!0;break}else w+=c;y+=e,e=""}s||m.push(x.clone())}m.length&&h.push(a.clone({fragments:m}))}return h}function J(r){return{width:0,height:0,color:null,backgroundColor:null,fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:null,lineHeight:1,letterSpacing:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0,writingMode:"horizontal-tb",...r}}function Y(r){const{content:t}=r,{width:o,height:h,...l}=J(r.style);let a=K(t,l);a=q(a,o,h);let x=a.reduce((e,i)=>e+i.maxCharWidth*i.getComputedStyle().lineHeight,0),u=0,w=0;a.forEach(e=>{const i=[];let S=null,c=u,d=w;e.fragments.forEach((n,k)=>{const f=n.getComputedStyle();switch(f.writingMode){case"vertical-rl":case"vertical-lr":{const p=e.maxCharWidth,C=p*f.lineHeight;k||(d=0,f.writingMode==="vertical-rl"&&(x-=C,c=x));const A=n.content.length,W=A*f.fontSize+(A-1)*f.letterSpacing;n.contentBox.x=c+(C-p)/2,n.contentBox.y=d,n.contentBox.width=p,n.contentBox.height=W,n.inlineBox.x=c,n.inlineBox.y=d,n.inlineBox.width=C,n.inlineBox.height=W,n.glyphBox.x=c+(C-p)/2,n.glyphBox.y=d,n.glyphBox.width=p,n.glyphBox.height=W,n.baseline=0,n.centerX=c+C/2,d+=W+f.letterSpacing;break}case"horizontal-tb":{k||(c=0);const{fontBoundingBoxAscent:p,fontBoundingBoxDescent:C,actualBoundingBoxAscent:A,actualBoundingBoxDescent:W,actualBoundingBoxLeft:O,actualBoundingBoxRight:D,width:T}=z(n.content,{...f,textAlign:"center",verticalAlign:"baseline"}),H=f.fontSize,F=H*f.lineHeight,L=p+C,N=A+W,G=O+D,P=d+(F-L)/2+p;n.contentBox.x=c,n.contentBox.y=d+(F-H)/2,n.contentBox.width=T,n.contentBox.height=H,n.inlineBox.x=c,n.inlineBox.y=d,n.inlineBox.width=T,n.inlineBox.height=F,n.glyphBox.x=c,n.glyphBox.y=P-A,n.glyphBox.width=G,n.glyphBox.height=N,n.baseline=P,n.centerX=c+O,i.push(n.contentBox),e.contentBox=B.from(...i),e.contentBox.height<n.contentBox.height&&(S=n),c+=T;break}}}),e.lineBox=B.from(...e.fragments.map(n=>n.inlineBox)),u+=e.lineBox.width,w+=e.lineBox.height;const g=z("x",{...(S??e).getComputedStyle(),textAlign:"left",verticalAlign:"baseline"});e.xHeight=g.actualBoundingBoxAscent,e.baseline=e.lineBox.y+(e.lineBox.height-(g.fontBoundingBoxAscent+g.fontBoundingBoxDescent))/2+g.fontBoundingBoxAscent});const m=B.from(...a.map(e=>e.lineBox),new B({width:o,height:h})),{width:b,height:y}=m;a.forEach(e=>{e.contentBox=B.from(...e.fragments.map(i=>i.contentBox)),e.glyphBox=B.from(...e.fragments.map(i=>i.glyphBox)),e.fragments.forEach(i=>{const S=i.getComputedStyle(),c=i.inlineBox.x,d=i.inlineBox.y;let g=c,n=d;switch(S.writingMode){case"vertical-rl":case"vertical-lr":switch(S.textAlign){case"end":case"right":n+=y-e.contentBox.height;break;case"center":n+=(y-e.contentBox.height)/2;break}break;case"horizontal-tb":{switch(S.textAlign){case"end":case"right":g+=b-e.contentBox.width;break;case"center":g+=(b-e.contentBox.width)/2;break}switch(S.verticalAlign){case"top":n+=e.lineBox.y-i.inlineBox.y;break;case"middle":n=e.baseline-e.xHeight/2-i.inlineBox.height/2;break;case"bottom":n+=e.lineBox.bottom-i.inlineBox.bottom;break;case"sub":n+=e.baseline-i.glyphBox.bottom;break;case"super":n+=e.baseline-i.glyphBox.y;break;case"text-top":n+=e.glyphBox.y-i.inlineBox.y;break;case"text-bottom":n+=e.glyphBox.bottom-i.inlineBox.bottom;break;case"baseline":default:i.inlineBox.height<e.lineBox.height&&(n+=e.baseline-i.baseline);break}break}}const k=g-c,f=n-d;i.inlineBox.move(k,f),i.contentBox.move(k,f),i.glyphBox.move(k,f),i.baseline+=f,i.centerX+=k}),e.contentBox=B.from(...e.fragments.map(i=>i.contentBox)),e.glyphBox=B.from(...e.fragments.map(i=>i.glyphBox))});const s=B.from(...a.map(e=>e.contentBox)),v=B.from(...a.map(e=>e.glyphBox));return{box:m,contentBox:s,glyphBox:v,paragraphs:a,viewBox:B.from(m,v)}}function X(r,t,o){if(typeof t=="string"&&t.startsWith("linear-gradient")){const{x0:h,y0:l,x1:a,y1:x,stops:u}=Q(t,o.left,o.top,o.width,o.height),w=r.createLinearGradient(h,l,a,x);return u.forEach(m=>w.addColorStop(m.offset,m.color)),w}return t}function Q(r,t,o,h,l){var v;const a=((v=r.match(/linear-gradient\((.+)\)$/))==null?void 0:v[1])??"",x=a.split(",")[0],u=x.includes("deg")?x:"0deg",w=a.replace(u,"").matchAll(/(#|rgba|rgb)(.+?) ([\d.]+?%)/gi),b=(Number(u.replace("deg",""))||0)*Math.PI/180,y=h*Math.sin(b),s=l*Math.cos(b);return{x0:t+h/2-y,y0:o+l/2+s,x1:t+h/2+y,y1:o+l/2-s,stops:Array.from(w).map(e=>{let i=e[2];return i.startsWith("(")?i=i.split(",").length>3?`rgba${i}`:`rgb${i}`:i=`#${i}`,{offset:Number(e[3].replace("%",""))/100,color:i}})}}function E(r,t,o){o!=null&&o.color&&(o.color=X(r,o.color,t)),o!=null&&o.backgroundColor&&(o.backgroundColor=X(r,o.backgroundColor,t)),o!=null&&o.textStrokeColor&&(o.textStrokeColor=X(r,o.textStrokeColor,t))}function Z(r){const{view:t=document.createElement("canvas"),style:o,draws:h=[],pixelRatio:l=1}=r,a=h.length>0?h:[{}],{viewBox:x,paragraphs:u}=Y(r),{x:w,y:m,width:b,height:y}=x,s=t.getContext("2d");t.style.width=`${b}px`,t.style.height=`${y}px`,t.dataset.viewbox=`${w} ${m} ${b} ${y}`,t.dataset.pixelRatio=String(l),t.width=Math.max(1,Math.floor(b*l)),t.height=Math.max(1,Math.floor(y*l)),s.scale(l,l),s.clearRect(0,0,t.width,t.height);const v={...o};return E(s,new B({width:b,height:y}),v),u.forEach(e=>{E(s,e.contentBox,e.style),e.fragments.forEach(i=>{E(s,i.contentBox,i.style)})}),a.forEach(e=>{const i={...e};E(s,new B({width:b,height:y}),i);const S={...v,...i};S!=null&&S.backgroundColor&&(s.fillStyle=S.backgroundColor,s.fillRect(0,0,t.width,t.height)),u.forEach(c=>{var d;(d=c.style)!=null&&d.backgroundColor&&(s.fillStyle=c.style.backgroundColor,s.fillRect(c.lineBox.x,c.lineBox.y,c.lineBox.width,c.lineBox.height)),c.fragments.forEach(g=>{var n;(n=g.style)!=null&&n.backgroundColor&&(s.fillStyle=g.style.backgroundColor,s.fillRect(g.inlineBox.x,g.inlineBox.y,g.inlineBox.width,g.inlineBox.height))})}),u.forEach(c=>{c.fragments.forEach(d=>{const g={...d.getComputedStyle(),...i};R(s,{...g,textAlign:"left",verticalAlign:"baseline"});const{width:n,height:k}=d.contentBox;let f=-x.x,p=-x.y;i.offsetX&&(f+=i.offsetX),i.offsetY&&(p+=i.offsetY);let C=p;switch(g.writingMode){case"vertical-rl":case"vertical-lr":f+=d.contentBox.x,p+=(g.fontSize-c.xHeight)/2+c.xHeight+1;break;case"horizontal-tb":f+=d.contentBox.x,p+=d.contentBox.y,C+=d.baseline;break}switch(g.writingMode){case"vertical-rl":case"vertical-lr":{let A=0;for(const W of d.content)s.fillText(W,f,p+A),g.textStrokeWidth&&s.strokeText(W,f,p+A),A+=g.fontSize+g.letterSpacing;break}case"horizontal-tb":s.fillText(d.content,f,C),g.textStrokeWidth&&s.strokeText(d.content,f,C);break}switch(g.textDecoration){case"underline":s.strokeStyle=s.fillStyle,s.lineWidth=g.fontSize/15,s.beginPath(),s.moveTo(f,p+k),s.lineTo(f+n,p+k),s.stroke();break;case"line-through":s.strokeStyle=s.fillStyle,s.lineWidth=g.fontSize/15,s.beginPath(),s.moveTo(f,p+k/2),s.lineTo(f+n,p+k/2),s.stroke();break}})})}),t}exports.measureText=Y;exports.renderText=Z;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class d{constructor(t=0,u=0,n=0,o=0){this.x=t,this.y=u,this.width=n,this.height=o}get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}static from(...t){const u=t[0],n=t.slice(1).reduce((o,a)=>(o.x=Math.min(o.x,a.x),o.y=Math.min(o.y,a.y),o.right=Math.max(o.right,a.right),o.bottom=Math.max(o.bottom,a.bottom),o),{x:u.x,y:u.y,right:u.right,bottom:u.bottom});return new d(n.x,n.y,n.right-n.x,n.bottom-n.y)}rotate90deg(){const{width:t,height:u}=this;this.width=u,this.height=t}translate(t,u){return this.x+=t,this.y+=u,this}clone(){return new d(this.x,this.y,this.width,this.height)}toArray(){return[this.x,this.y,this.width,this.height]}}const P="OffscreenCanvas"in globalThis;let $;function L(){return $??($=P?new OffscreenCanvas(1,1):document.createElement("canvas"))}function H(h,t){switch(t.shadowColor&&(h.shadowColor=t.shadowColor),t.shadowOffsetX!==void 0&&(h.shadowOffsetX=t.shadowOffsetX),t.shadowOffsetY!==void 0&&(h.shadowOffsetY=t.shadowOffsetY),t.shadowBlur!==void 0&&(h.shadowBlur=t.shadowBlur),h.strokeStyle=t.textStrokeColor??"#000",t.textStrokeWidth!==void 0&&(h.lineWidth=t.textStrokeWidth),h.fillStyle=t.color??"#000",t.textAlign&&(h.textAlign=t.textAlign),t.fontKerning&&(h.fontKerning=t.fontKerning),t.verticalAlign){case"baseline":h.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":h.textBaseline=t.verticalAlign;break}t.letterSpacing!==void 0&&(h.letterSpacing=`${t.letterSpacing}px`),(t.fontStyle||t.fontWeight!==void 0||t.fontSize!==void 0||t.fontFamily)&&(h.font=[t.fontStyle||"normal",t.fontWeight||"normal",`${t.fontSize||14}px`,t.fontFamily||"sans-serif"].join(" "))}function O(h,t){const u=L().getContext("2d");H(u,{...t,textAlign:"center",verticalAlign:"baseline"});const{width:n,actualBoundingBoxAscent:o,actualBoundingBoxDescent:a,actualBoundingBoxLeft:r,actualBoundingBoxRight:E,fontBoundingBoxAscent:B,fontBoundingBoxDescent:f}=u.measureText(h),A=B+f,p=t.fontSize*t.lineHeight,i=o+a,w=(p-A)/2+B;return{typoAscent:B,typoDescent:f,width:n,height:t.fontSize,typoHeight:A,lineHeight:p,leading:p-A,glyphLeft:r,glyphRight:E,glyphAscent:o,glyphDescent:a,glyphWidth:r+E,glyphHeight:i,baseline:w,centerX:r}}const Y=/[\u{00A7}\u{00A9}\u{00AE}\u{00B1}\u{00BC}-\u{00BE}\u{00D7}\u{00F7}\u{02EA}-\u{02EB}\u{1100}-\u{11FF}\u{1401}-\u{166C}\u{166D}\u{166E}\u{166F}-\u{167F}\u{18B0}-\u{18F5}\u{18F6}-\u{18FF}\u{2016}\u{2020}-\u{2021}\u{2030}-\u{2031}\u{203B}-\u{203C}\u{2042}\u{2047}-\u{2049}\u{2051}\u{2065}\u{20DD}-\u{20E0}\u{20E2}-\u{20E4}\u{2100}-\u{2101}\u{2103}-\u{2106}\u{2107}\u{2108}-\u{2109}\u{210F}\u{2113}\u{2114}\u{2116}-\u{2117}\u{211E}-\u{2123}\u{2125}\u{2127}\u{2129}\u{212E}\u{2135}-\u{2138}\u{2139}\u{213A}-\u{213B}\u{213C}-\u{213F}\u{2145}-\u{2149}\u{214A}\u{214C}-\u{214D}\u{214F}\u{2150}-\u{215F}\u{2160}-\u{2182}\u{2183}-\u{2184}\u{2185}-\u{2188}\u{2189}\u{218C}-\u{218F}\u{221E}\u{2234}-\u{2235}\u{2300}-\u{2307}\u{230C}-\u{231F}\u{2324}-\u{2328}\u{232B}\u{237D}-\u{239A}\u{23BE}-\u{23CD}\u{23CF}\u{23D1}-\u{23DB}\u{23E2}-\u{23FF}\u{2400}-\u{2422}\u{2424}-\u{2426}\u{2427}-\u{243F}\u{2440}-\u{244A}\u{244B}-\u{245F}\u{2460}-\u{249B}\u{249C}-\u{24E9}\u{24EA}-\u{24FF}\u{25A0}-\u{25B6}\u{25B7}\u{25B8}-\u{25C0}\u{25C1}\u{25C2}-\u{25F7}\u{25F8}-\u{25FF}\u{2600}-\u{2619}\u{2620}-\u{266E}\u{266F}\u{2670}-\u{26FF}\u{2700}-\u{2767}\u{2776}-\u{2793}\u{2B12}-\u{2B2F}\u{2B50}-\u{2B59}\u{2B97}\u{2BB8}-\u{2BD1}\u{2BD3}-\u{2BEB}\u{2BF0}-\u{2BFF}\u{2E50}-\u{2E51}\u{2E80}-\u{2E99}\u{2E9A}\u{2E9B}-\u{2EF3}\u{2EF4}-\u{2EFF}\u{2F00}-\u{2FD5}\u{2FD6}-\u{2FDF}\u{2FE0}-\u{2FEF}\u{2FF0}-\u{2FFB}\u{2FFC}-\u{2FFF}\u{3000}\u{3001}-\u{3002}\u{3003}\u{3004}\u{3005}\u{3006}\u{3007}\u{3012}-\u{3013}\u{3020}\u{3021}-\u{3029}\u{302A}-\u{302D}\u{302E}-\u{302F}\u{3031}-\u{3035}\u{3036}-\u{3037}\u{3038}-\u{303A}\u{303B}\u{303C}\u{303D}\u{303E}-\u{303F}\u{3040}\u{3041}\u{3042}\u{3043}\u{3044}\u{3045}\u{3046}\u{3047}\u{3048}\u{3049}\u{304A}-\u{3062}\u{3063}\u{3064}-\u{3082}\u{3083}\u{3084}\u{3085}\u{3086}\u{3087}\u{3088}-\u{308D}\u{308E}\u{308F}-\u{3094}\u{3095}-\u{3096}\u{3097}-\u{3098}\u{3099}-\u{309A}\u{309B}-\u{309C}\u{309D}-\u{309E}\u{309F}\u{30A1}\u{30A2}\u{30A3}\u{30A4}\u{30A5}\u{30A6}\u{30A7}\u{30A8}\u{30A9}\u{30AA}-\u{30C2}\u{30C3}\u{30C4}-\u{30E2}\u{30E3}\u{30E4}\u{30E5}\u{30E6}\u{30E7}\u{30E8}-\u{30ED}\u{30EE}\u{30EF}-\u{30F4}\u{30F5}-\u{30F6}\u{30F7}-\u{30FA}\u{30FB}\u{30FD}-\u{30FE}\u{30FF}\u{3100}-\u{3104}\u{3105}-\u{3126}\u{3127}\u{3128}-\u{312F}\u{3130}\u{3131}-\u{318E}\u{318F}\u{3190}-\u{3191}\u{3192}-\u{3195}\u{3196}-\u{319F}\u{31A0}-\u{31BF}\u{31C0}-\u{31E3}\u{31E4}-\u{31EF}\u{31F0}-\u{31FF}\u{3200}-\u{321E}\u{321F}\u{3220}-\u{3229}\u{322A}-\u{3247}\u{3248}-\u{324F}\u{3250}\u{3251}-\u{325F}\u{3260}-\u{327F}\u{3280}-\u{3289}\u{328A}-\u{32B0}\u{32B1}-\u{32BF}\u{32C0}-\u{32FE}\u{32FF}\u{3300}-\u{3357}\u{3358}-\u{337A}\u{337B}-\u{337F}\u{3380}-\u{33FF}\u{3400}-\u{4DBF}\u{4DC0}-\u{4DFF}\u{4E00}-\u{9FFF}\u{A000}-\u{A014}\u{A015}\u{A016}-\u{A48C}\u{A48D}-\u{A48F}\u{A490}-\u{A4C6}\u{A4C7}-\u{A4CF}\u{A960}-\u{A97C}\u{A97D}-\u{A97F}\u{AC00}-\u{D7A3}\u{D7A4}-\u{D7AF}\u{D7B0}-\u{D7C6}\u{D7C7}-\u{D7CA}\u{D7CB}-\u{D7FB}\u{D7FC}-\u{D7FF}\u{E000}-\u{F8FF}\u{F900}-\u{FA6D}\u{FA6E}-\u{FA6F}\u{FA70}-\u{FAD9}\u{FADA}-\u{FAFF}\u{FE10}-\u{FE16}\u{FE17}\u{FE18}\u{FE19}\u{FE1A}-\u{FE1F}\u{FE30}\u{FE31}-\u{FE32}\u{FE33}-\u{FE34}\u{FE35}\u{FE36}\u{FE37}\u{FE38}\u{FE39}\u{FE3A}\u{FE3B}\u{FE3C}\u{FE3D}\u{FE3E}\u{FE3F}\u{FE40}\u{FE41}\u{FE42}\u{FE43}\u{FE44}\u{FE45}-\u{FE46}\u{FE47}\u{FE48}\u{FE50}-\u{FE52}\u{FE53}\u{FE54}-\u{FE57}\u{FE5F}-\u{FE61}\u{FE62}\u{FE67}\u{FE68}\u{FE69}\u{FE6A}-\u{FE6B}\u{FE6C}-\u{FE6F}\u{FF01}\u{FF02}-\u{FF03}\u{FF04}\u{FF05}-\u{FF07}\u{FF0A}\u{FF0B}\u{FF0C}\u{FF0E}\u{FF0F}\u{FF10}-\u{FF19}\u{FF1F}\u{FF20}\u{FF21}-\u{FF3A}\u{FF3C}\u{FF3E}\u{FF40}\u{FF41}-\u{FF5A}\u{FFE0}-\u{FFE1}\u{FFE2}\u{FFE4}\u{FFE5}-\u{FFE6}\u{FFE7}\u{FFF0}-\u{FFF8}\u{FFFC}-\u{FFFD}\u{10980}-\u{1099F}\u{11580}-\u{115AE}\u{115AF}-\u{115B1}\u{115B2}-\u{115B5}\u{115B6}-\u{115B7}\u{115B8}-\u{115BB}\u{115BC}-\u{115BD}\u{115BE}\u{115BF}-\u{115C0}\u{115C1}-\u{115D7}\u{115D8}-\u{115DB}\u{115DC}-\u{115DD}\u{115DE}-\u{115FF}\u{11A00}\u{11A01}-\u{11A0A}\u{11A0B}-\u{11A32}\u{11A33}-\u{11A38}\u{11A39}\u{11A3A}\u{11A3B}-\u{11A3E}\u{11A3F}-\u{11A46}\u{11A47}\u{11A48}-\u{11A4F}\u{11A50}\u{11A51}-\u{11A56}\u{11A57}-\u{11A58}\u{11A59}-\u{11A5B}\u{11A5C}-\u{11A89}\u{11A8A}-\u{11A96}\u{11A97}\u{11A98}-\u{11A99}\u{11A9A}-\u{11A9C}\u{11A9D}\u{11A9E}-\u{11AA2}\u{11AA3}-\u{11AAF}\u{11AB0}-\u{11ABF}\u{13000}-\u{1342E}\u{1342F}\u{13430}-\u{13438}\u{13439}-\u{1343F}\u{14400}-\u{14646}\u{14647}-\u{1467F}\u{16FE0}-\u{16FE1}\u{16FE2}\u{16FE3}\u{16FE4}\u{16FE5}-\u{16FEF}\u{16FF0}-\u{16FF1}\u{16FF2}-\u{16FFF}\u{17000}-\u{187F7}\u{187F8}-\u{187FF}\u{18800}-\u{18AFF}\u{18B00}-\u{18CD5}\u{18CD6}-\u{18CFF}\u{18D00}-\u{18D08}\u{18D09}-\u{18D7F}\u{1AFF0}-\u{1AFF3}\u{1AFF4}\u{1AFF5}-\u{1AFFB}\u{1AFFC}\u{1AFFD}-\u{1AFFE}\u{1AFFF}\u{1B000}-\u{1B0FF}\u{1B100}-\u{1B122}\u{1B123}-\u{1B12F}\u{1B130}-\u{1B14F}\u{1B150}-\u{1B152}\u{1B153}-\u{1B163}\u{1B164}-\u{1B167}\u{1B168}-\u{1B16F}\u{1B170}-\u{1B2FB}\u{1B2FC}-\u{1B2FF}\u{1CF00}-\u{1CF2D}\u{1CF2E}-\u{1CF2F}\u{1CF30}-\u{1CF46}\u{1CF47}-\u{1CF4F}\u{1CF50}-\u{1CFC3}\u{1CFC4}-\u{1CFCF}\u{1D000}-\u{1D0F5}\u{1D0F6}-\u{1D0FF}\u{1D100}-\u{1D126}\u{1D127}-\u{1D128}\u{1D129}-\u{1D164}\u{1D165}-\u{1D166}\u{1D167}-\u{1D169}\u{1D16A}-\u{1D16C}\u{1D16D}-\u{1D172}\u{1D173}-\u{1D17A}\u{1D17B}-\u{1D182}\u{1D183}-\u{1D184}\u{1D185}-\u{1D18B}\u{1D18C}-\u{1D1A9}\u{1D1AA}-\u{1D1AD}\u{1D1AE}-\u{1D1EA}\u{1D1EB}-\u{1D1FF}\u{1D2E0}-\u{1D2F3}\u{1D2F4}-\u{1D2FF}\u{1D300}-\u{1D356}\u{1D357}-\u{1D35F}\u{1D360}-\u{1D378}\u{1D379}-\u{1D37F}\u{1D800}-\u{1D9FF}\u{1DA00}-\u{1DA36}\u{1DA37}-\u{1DA3A}\u{1DA3B}-\u{1DA6C}\u{1DA6D}-\u{1DA74}\u{1DA75}\u{1DA76}-\u{1DA83}\u{1DA84}\u{1DA85}-\u{1DA86}\u{1DA87}-\u{1DA8B}\u{1DA8C}-\u{1DA9A}\u{1DA9B}-\u{1DA9F}\u{1DAA0}\u{1DAA1}-\u{1DAAF}\u{1F000}-\u{1F02B}\u{1F02C}-\u{1F02F}\u{1F030}-\u{1F093}\u{1F094}-\u{1F09F}\u{1F0A0}-\u{1F0AE}\u{1F0AF}-\u{1F0B0}\u{1F0B1}-\u{1F0BF}\u{1F0C0}\u{1F0C1}-\u{1F0CF}\u{1F0D0}\u{1F0D1}-\u{1F0F5}\u{1F0F6}-\u{1F0FF}\u{1F100}-\u{1F10C}\u{1F10D}-\u{1F1AD}\u{1F1AE}-\u{1F1E5}\u{1F1E6}-\u{1F1FF}\u{1F200}-\u{1F201}\u{1F202}\u{1F203}-\u{1F20F}\u{1F210}-\u{1F23B}\u{1F23C}-\u{1F23F}\u{1F240}-\u{1F248}\u{1F249}-\u{1F24F}\u{1F250}-\u{1F251}\u{1F252}-\u{1F25F}\u{1F260}-\u{1F265}\u{1F266}-\u{1F2FF}\u{1F300}-\u{1F3FA}\u{1F3FB}-\u{1F3FF}\u{1F400}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F650}-\u{1F67F}\u{1F680}-\u{1F6D7}\u{1F6D8}-\u{1F6DC}\u{1F6DD}-\u{1F6EC}\u{1F6ED}-\u{1F6EF}\u{1F6F0}-\u{1F6FC}\u{1F6FD}-\u{1F6FF}\u{1F700}-\u{1F773}\u{1F774}-\u{1F77F}\u{1F780}-\u{1F7D8}\u{1F7D9}-\u{1F7DF}\u{1F7E0}-\u{1F7EB}\u{1F7EC}-\u{1F7EF}\u{1F7F0}\u{1F7F1}-\u{1F7FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA53}\u{1FA54}-\u{1FA5F}\u{1FA60}-\u{1FA6D}\u{1FA6E}-\u{1FA6F}\u{1FA70}-\u{1FA74}\u{1FA75}-\u{1FA77}\u{1FA78}-\u{1FA7C}\u{1FA7D}-\u{1FA7F}\u{1FA80}-\u{1FA86}\u{1FA87}-\u{1FA8F}\u{1FA90}-\u{1FAAC}\u{1FAAD}-\u{1FAAF}\u{1FAB0}-\u{1FABA}\u{1FABB}-\u{1FABF}\u{1FAC0}-\u{1FAC5}\u{1FAC6}-\u{1FACF}\u{1FAD0}-\u{1FAD9}\u{1FADA}-\u{1FADF}\u{1FAE0}-\u{1FAE7}\u{1FAE8}-\u{1FAEF}\u{1FAF0}-\u{1FAF6}\u{1FAF7}-\u{1FAFF}\u{20000}-\u{2A6DF}\u{2A6E0}-\u{2A6FF}\u{2A700}-\u{2B738}\u{2B739}-\u{2B73F}\u{2B740}-\u{2B81D}\u{2B81E}-\u{2B81F}\u{2B820}-\u{2CEA1}\u{2CEA2}-\u{2CEAF}\u{2CEB0}-\u{2EBE0}\u{2EBE1}-\u{2F7FF}\u{2F800}-\u{2FA1D}\u{2FA1E}-\u{2FFFD}\u{30000}-\u{3134A}\u{3134B}-\u{3134F}\u{31350}-\u{3FFFD}]/u,U=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/,K=/[\r\n]/;class z{constructor(t,u){this.content=t,this.parent=u,this.contentBox=new d,this.glyphBox=new d}get computedStyle(){return this.parent.computedStyle}get verticalOrientation(){switch(this.computedStyle.textOrientation){case"upright":return"U";case"sideways-right":case"sideways":return"R";case"mixed":default:return Y.test(this.content)?"U":"R"}}get isPunctuation(){return U.test(this.content)}get isEOL(){return K.test(this.content)}measure(){const t=this.computedStyle,{width:u,height:n,glyphWidth:o,glyphHeight:a}=O(this.content,{...t,letterSpacing:0});if(this.contentBox.width=u,this.contentBox.height=n,this.glyphBox.width=o,this.glyphBox.height=a,t.writingMode.startsWith("vertical"))switch(this.verticalOrientation){case"R":case"Tr":this.contentBox.rotate90deg(),this.glyphBox.rotate90deg();break}return this}clone(){const t=new z(this.content,this.parent);return t.contentBox=this.contentBox.clone(),t.glyphBox=this.glyphBox.clone(),t}}class T{constructor(t,u,n){this.content=t,this.style=u,this.parent=n,this.contentBox=new d,this.inlineBox=new d,this.glyphBox=new d,this.centerX=0,this.baseline=0,this.update()}update(){var n;this.computedStyle={...(n=this.parent)==null?void 0:n.computedStyle,...this.style};const t=this.computedStyle;this.computedContent=t.textTransform==="uppercase"?this.content.toUpperCase():t.textTransform==="lowercase"?this.content.toLowerCase():this.content;const u=[];for(const o of this.computedContent)u.push(new z(o,this));return this.characters=u,this}measure(){const t=this.computedStyle;switch(t.writingMode){case"vertical-lr":case"vertical-rl":{let u=0,n=0,o=0;this.characters.forEach((a,r)=>{a.measure(),n=Math.max(n,a.contentBox.width),o=Math.max(o,a.glyphBox.width),u+=a.contentBox.height,r!==this.characters.length-1&&(u+=t.letterSpacing)}),this.contentBox.width=n,this.contentBox.height=u,this.glyphBox.width=o,this.glyphBox.height=u,this.inlineBox.width=t.fontSize*t.lineHeight,this.inlineBox.height=u;break}case"horizontal-tb":{const{width:u,height:n,lineHeight:o,glyphAscent:a,glyphWidth:r,glyphHeight:E,baseline:B,centerX:f}=O(this.computedContent,t);this.inlineBox.width=u,this.inlineBox.height=o,this.contentBox.width=u,this.contentBox.height=n,this.glyphBox.width=r,this.glyphBox.height=E,this.baseline=B,this.inlineBox.x=0,this.inlineBox.y=0,this.contentBox.x=0,this.contentBox.y=(this.inlineBox.height-this.contentBox.height)/2,this.glyphBox.x=0,this.glyphBox.y=B-a,this.centerX=f;break}}return this}clone(t){return new T(t??this.content,this.style,this.parent)}}class v{constructor(t,u){this.style=t,this.parent=u,this.contentBox=new d,this.lineBox=new d,this.glyphBox=new d,this.baseline=0,this.xHeight=0,this.fragments=[],this.update()}update(){this.computedStyle={...this.parent,...this.style}}addFragment(t,u){return this.fragments.push(new T(t,u,this)),this}clone(t){const u=new v;return u.style=this.style,u.parent=this.parent,u.contentBox=this.contentBox.clone(),u.lineBox=this.lineBox.clone(),u.glyphBox=this.glyphBox.clone(),u.baseline=this.baseline,u.xHeight=this.xHeight,u.fragments=t??this.fragments.map(n=>n.clone()),u.computedStyle=this.computedStyle,u}}function N(h,t){const u=[];if(typeof h=="string")u.push(new v(void 0,t).addFragment(h));else{h=Array.isArray(h)?h:[h];for(const n of h)if(typeof n=="string")u.push(new v(void 0,t).addFragment(n));else if(Array.isArray(n)){const o=new v(void 0,t);n.forEach(a=>{if(typeof a=="string")o.addFragment(a);else{const{content:r,...E}=a;o.addFragment(r,E)}}),u.push(o)}else if("fragments"in n){const{fragments:o,...a}=n,r=new v(a,t);o.forEach(E=>{const{content:B,...f}=E;r.addFragment(B,f)}),u.push(r)}else if("content"in n){const{content:o,...a}=n;u.push(new v(a,t).addFragment(o))}}return u}function j(h,t,u){var E;const n=[],o=h.slice();let a,r;for(;a=o.shift();){const B=a.fragments.slice();let f=0;const A=[];for(;r=B.shift();){const p=r.computedStyle;let i="",w=!1,S=0;const e=new T("",r.style,r.parent);for(const F of r.characters){if(e.content+=F.content,(E=r.characters[++S])!=null&&E.isPunctuation)continue;const D=F.isEOL;let x,c;switch(p.writingMode){case"vertical-lr":case"vertical-rl":x=u,c=e.update().measure().contentBox.height;break;case"horizontal-tb":default:x=t,c=e.update().measure().contentBox.width;break}if(D||x&&f+c>x){let l=D?i.length+1:i.length;!f&&!l&&(i+=e.content,l+=e.content.length),i.length&&A.push(r.clone(i)),A.length&&(n.push(a.clone(A.slice())),A.length=0);const g=r.content.substring(l);(g.length||B.length)&&o.unshift(a.clone((g.length?[r.clone(g)]:[]).concat(B.slice()))),B.length=0,w=!0;break}else f+=c;i+=e.content,e.content=""}w||A.push(r.clone())}A.length&&n.push(a.clone(A))}return n}function G(h){return{width:0,height:0,color:"#000",backgroundColor:null,fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000",lineHeight:1,letterSpacing:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0,writingMode:"horizontal-tb",textOrientation:"mixed",...h}}function R(h){const{content:t,effects:u=[{}]}=h,{width:n,height:o,...a}=G(h.style);let r=N(t,a);r=j(r,n,o);let E=0,B=0;r.forEach(e=>{let F=null;e.fragments.forEach(s=>{s.update().measure(),(!F||F.contentBox.height<s.contentBox.height)&&(F=s)});const{typoHeight:D,typoAscent:x,lineHeight:c}=O("x",(F??e).computedStyle);e.xHeight=D,e.baseline=B+(c-D)/2+x;let l=E,g=B,m=0;e.fragments.forEach((s,C)=>{const y=s.computedStyle;switch(y.writingMode){case"vertical-rl":case"vertical-lr":{C||(g=0),s.inlineBox.translate(l,g),s.contentBox.translate(l,g),s.glyphBox.translate(l,g),s.baseline+=g,s.centerX+=l;let k=g;s.characters.forEach((b,X)=>{b.contentBox.x=l+(s.inlineBox.width-b.contentBox.width)/2,b.contentBox.y=k,b.glyphBox.x=l+(s.inlineBox.width-b.glyphBox.width)/2,b.glyphBox.y=k,k+=b.contentBox.height,X!==s.characters.length-1&&(k+=y.letterSpacing)}),g+=s.inlineBox.height,C===e.fragments.length-1&&(l+=s.inlineBox.width);break}case"horizontal-tb":{C||(l=0),s.inlineBox.translate(l,g),s.contentBox.translate(l,g),s.glyphBox.translate(l,g),s.baseline+=g,s.centerX+=l,l+=s.inlineBox.width,m=Math.max(m,s.inlineBox.height),C===e.fragments.length-1&&(g+=m);break}}}),E=l,B=g,e.lineBox=d.from(...e.fragments.map(s=>s.inlineBox))});const f=d.from(...r.map(e=>e.lineBox),new d(0,0,n,o)),{width:A,height:p}=f;r.forEach(e=>{e.lineBox.width=Math.max(e.lineBox.width,A),e.contentBox=d.from(...e.fragments.map(F=>F.contentBox)),e.glyphBox=d.from(...e.fragments.map(F=>F.glyphBox)),e.fragments.forEach(F=>{const D=F.computedStyle;let x=0,c=0;switch(D.writingMode){case"vertical-rl":case"vertical-lr":switch(D.textAlign){case"end":case"right":c=p-e.contentBox.height;break;case"center":c=(p-e.contentBox.height)/2;break}break;case"horizontal-tb":{switch(D.textAlign){case"end":case"right":x=A-e.contentBox.width;break;case"center":x=(A-e.contentBox.width)/2;break}switch(D.verticalAlign){case"top":c=e.lineBox.y-F.inlineBox.y;break;case"middle":c=F.inlineBox.y-(e.baseline-e.xHeight/2-F.inlineBox.height/2);break;case"bottom":c=e.lineBox.bottom-F.inlineBox.bottom;break;case"sub":c=e.baseline-F.glyphBox.bottom;break;case"super":c=e.baseline-F.glyphBox.y;break;case"text-top":c=e.glyphBox.y-F.inlineBox.y;break;case"text-bottom":c=e.glyphBox.bottom-F.inlineBox.bottom;break;case"baseline":default:F.inlineBox.height<e.lineBox.height&&(c=e.baseline-F.baseline);break}break}}F.inlineBox.translate(x,c),F.contentBox.translate(x,c),F.glyphBox.translate(x,c),F.baseline+=c,F.centerX+=x}),e.contentBox=d.from(...e.fragments.map(F=>F.contentBox)),e.glyphBox=d.from(...e.fragments.map(F=>F.glyphBox))});const i=d.from(...r.map(e=>e.contentBox)),w=d.from(...r.map(e=>e.glyphBox)),S=[];return r.forEach(e=>{e.fragments.forEach(F=>{const D=F.computedStyle;u.forEach(x=>{const c={...D,...x},{textStrokeWidth:l=0,offsetX:g=0,offsetY:m=0}=c;if(l||g||m){const{x:s,y:C,width:y,height:k}=F.contentBox;S.push(new d(Math.min(s,s+g-l/2),Math.min(C,C+m-l/2),Math.max(y,y+g+l),Math.max(k,k+m+l)))}})})}),{box:f,contentBox:i,glyphBox:w,paragraphs:r,viewBox:d.from(f,w,...S)}}function W(h,t,u){if(typeof t=="string"&&t.startsWith("linear-gradient")){const{x0:n,y0:o,x1:a,y1:r,stops:E}=I(t,u.left,u.top,u.width,u.height),B=h.createLinearGradient(n,o,a,r);return E.forEach(f=>B.addColorStop(f.offset,f.color)),B}return t}function I(h,t,u,n,o){var w;const a=((w=h.match(/linear-gradient\((.+)\)$/))==null?void 0:w[1])??"",r=a.split(",")[0],E=r.includes("deg")?r:"0deg",B=a.replace(E,"").matchAll(/(#|rgba|rgb)(.+?) ([\d.]+?%)/gi),A=(Number(E.replace("deg",""))||0)*Math.PI/180,p=n*Math.sin(A),i=o*Math.cos(A);return{x0:t+n/2-p,y0:u+o/2+i,x1:t+n/2+p,y1:u+o/2-i,stops:Array.from(B).map(S=>{let e=S[2];return e.startsWith("(")?e=e.split(",").length>3?`rgba${e}`:`rgb${e}`:e=`#${e}`,{offset:Number(S[3].replace("%",""))/100,color:e}})}}function M(h,t,u){u!=null&&u.color&&(u.color=W(h,u.color,t)),u!=null&&u.backgroundColor&&(u.backgroundColor=W(h,u.backgroundColor,t)),u!=null&&u.textStrokeColor&&(u.textStrokeColor=W(h,u.textStrokeColor,t))}function V(h){const{view:t=document.createElement("canvas"),style:u,effects:n=[],pixelRatio:o=1}=h,a=n.length>0?n:[{}],{viewBox:r,paragraphs:E}=R(h),{x:B,y:f,width:A,height:p}=r,i=t.getContext("2d");t.style.width=`${A}px`,t.style.height=`${p}px`,t.dataset.viewbox=`${B} ${f} ${A} ${p}`,t.dataset.pixelRatio=String(o),t.width=Math.max(1,Math.floor(A*o)),t.height=Math.max(1,Math.floor(p*o)),i.scale(o,o),i.clearRect(0,0,t.width,t.height);const w=(e,F,D,x,c)=>{i.fillStyle=e,i.fillRect(-r.x+F,-r.y+D,x,c)},S={...u};return M(i,new d(0,0,A,p),S),E.forEach(e=>{M(i,e.contentBox,e.computedStyle),e.fragments.forEach(F=>{M(i,F.contentBox,F.computedStyle)})}),a.forEach(e=>{const F={...e};M(i,new d(0,0,A,p),F);const D={...S,...F};D!=null&&D.backgroundColor&&w(D.backgroundColor,0,0,t.width,t.height),E.forEach(x=>{var c;(c=x.style)!=null&&c.backgroundColor&&w(x.style.backgroundColor,...x.lineBox.toArray()),x.fragments.forEach(l=>{var g;(g=l.style)!=null&&g.backgroundColor&&w(l.style.backgroundColor,...l.inlineBox.toArray())})}),E.forEach(x=>{x.fragments.forEach(c=>{const l=-r.x+(F.offsetX??0),g=-r.y+(F.offsetY??0),m={...c.computedStyle,...F};switch(H(i,{...m,textAlign:"left",verticalAlign:m.writingMode==="horizontal-tb"?"baseline":"top"}),m.writingMode){case"vertical-rl":case"vertical-lr":{c.characters.forEach(s=>{let{x:C,y}=s.contentBox;switch(C+=l,y+=g,s.verticalOrientation){case"R":case"Tr":{i.translate(C+s.contentBox.width,y),i.rotate(Math.PI/2),i.fillText(s.content,0,0),m.textStrokeWidth&&i.strokeText(s.content,0,0),i.setTransform(1,0,0,1,0,0);break}default:i.fillText(s.content,C,y),m.textStrokeWidth&&i.strokeText(s.content,C,y);break}});break}case"horizontal-tb":{const s=l+c.contentBox.x,C=g+c.contentBox.y,y=g+c.baseline;i.fillText(c.content,s,y),m.textStrokeWidth&&i.strokeText(c.content,s,y);const{width:k,height:b}=c.contentBox;switch(m.textDecoration){case"underline":i.strokeStyle=i.fillStyle,i.lineWidth=m.fontSize/15,i.beginPath(),i.moveTo(s,C+b),i.lineTo(s+k,C+b),i.stroke();break;case"line-through":i.strokeStyle=i.fillStyle,i.lineWidth=m.fontSize/15,i.beginPath(),i.moveTo(s,C+b/2),i.lineTo(s+k,C+b/2),i.stroke();break}break}}})})}),t}exports.measureText=R;exports.renderText=V;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(M,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(M=typeof globalThis<"u"?globalThis:M||self,d(M.modernText={}))})(this,function(M){"use strict";class d{get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}constructor({x:t=0,y:o=0,width:h=0,height:l=0}={}){this.x=t,this.y=o,this.width=h,this.height=l}static from(...t){const o=t[0],h=t.slice(1).reduce((l,a)=>(l.x=Math.min(l.x,a.x),l.y=Math.min(l.y,a.y),l.right=Math.max(l.right,a.right),l.bottom=Math.max(l.bottom,a.bottom),l),{x:o.x,y:o.y,right:o.right,bottom:o.bottom});return new d({x:h.x,y:h.y,width:h.right-h.x,height:h.bottom-h.y})}move(t,o){return this.x+=t,this.y+=o,this}clone(){return new d({x:this.x,y:this.y,width:this.width,height:this.height})}}class H{constructor({content:t="",style:o,parent:h,contentBox:l=new d,inlineBox:a=new d,glyphBox:x=new d,centerX:B=0,baseline:w=0}={}){switch(this.content=t,this.style=o,this.parent=h,this.contentBox=l,this.inlineBox=a,this.glyphBox=x,this.centerX=B,this.baseline=w,this.getComputedStyle().textTransform){case"uppercase":this.content=this.content.toUpperCase();break;case"lowercase":this.content=this.content.toLowerCase();break}}getComputedStyle(){var t;return{...(t=this.parent)==null?void 0:t.getComputedStyle(),...this.style}}clone(t){return new H({content:this.content,style:this.style,parent:this.parent,contentBox:this.contentBox.clone(),inlineBox:this.inlineBox.clone(),glyphBox:this.glyphBox.clone(),centerX:this.centerX,baseline:this.baseline,...t})}}class T{constructor({style:t,parent:o,contentBox:h=new d,lineBox:l=new d,glyphBox:a=new d,baseline:x=0,xHeight:B=0,maxCharWidth:w=0,fragments:m=[]}={}){this.style=t,this.parent=o,this.contentBox=h,this.lineBox=l,this.glyphBox=a,this.baseline=x,this.xHeight=B,this.maxCharWidth=w,this.fragments=m}addFragment(t){return this.fragments.push(new H({...t,parent:this})),this}getComputedStyle(){return{...this.parent,...this.style}}clone(t){return new T({style:this.style,parent:this.parent,contentBox:this.contentBox.clone(),lineBox:this.lineBox.clone(),glyphBox:this.glyphBox.clone(),baseline:this.baseline,xHeight:this.xHeight,maxCharWidth:this.maxCharWidth,fragments:this.fragments.map(o=>o.clone()),...t})}}function L(r,t){const o=[];if(typeof r=="string")o.push(new T({parent:t}).addFragment({content:r}));else{r=Array.isArray(r)?r:[r];for(const h of r)if(typeof h=="string")o.push(new T({parent:t}).addFragment({content:h}));else if(Array.isArray(h)){const l=new T({parent:t});h.forEach(a=>{if(typeof a=="string")l.addFragment({content:a});else{const{content:x,...B}=a;l.addFragment({content:x,style:B})}}),o.push(l)}else if("fragments"in h){const{fragments:l,...a}=h,x=new T({style:a,parent:t});l.forEach(B=>{const{content:w,...m}=B;x.addFragment({content:w,style:m})}),o.push(x)}else if("content"in h){const{content:l,...a}=h;o.push(new T({style:a,parent:t}).addFragment({content:l}))}}return o}const N="OffscreenCanvas"in globalThis;let G;function K(){return G??(G=N?new OffscreenCanvas(1,1):document.createElement("canvas"))}function P(r,t){switch(t.shadowColor&&(r.shadowColor=t.shadowColor),t.shadowOffsetX!==void 0&&(r.shadowOffsetX=t.shadowOffsetX),t.shadowOffsetY!==void 0&&(r.shadowOffsetY=t.shadowOffsetY),t.shadowBlur!==void 0&&(r.shadowBlur=t.shadowBlur),t.textStrokeColor&&(r.strokeStyle=t.textStrokeColor),t.textStrokeWidth!==void 0&&(r.lineWidth=t.textStrokeWidth),t.color&&(r.fillStyle=t.color),t.textAlign&&(r.textAlign=t.textAlign),t.fontKerning&&(r.fontKerning=t.fontKerning),t.verticalAlign){case"baseline":r.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":r.textBaseline=t.verticalAlign;break}t.letterSpacing!==void 0&&(r.letterSpacing=`${t.letterSpacing}px`),(t.fontStyle||t.fontWeight!==void 0||t.fontSize!==void 0||t.fontFamily)&&(r.font=[t.fontStyle||"normal",t.fontWeight||"normal",`${t.fontSize||14}px`,t.fontFamily||"sans-serif"].join(" "))}function E(r,t){const o=K().getContext("2d");return P(o,t),o.measureText(r)}const j=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;function U(r,t,o){const h=[],l=r.slice();let a,x;for(;a=l.shift();){const B=a.fragments.slice();let w=0;const m=[];for(;x=B.shift();){const b=x.getComputedStyle();let y="",s=!1,v=0,e="";for(const i of x.content){if(a.maxCharWidth=Math.max(a.maxCharWidth,E(i,{...b,letterSpacing:0}).width),e+=i,j.test(x.content[++v]))continue;let S,c;switch(b.writingMode){case"vertical-lr":case"vertical-rl":S=o,c=e.length*b.fontSize;break;case"horizontal-tb":default:S=t,c=E(e,{...b,letterSpacing:0}).width;break}c+=e.length*b.letterSpacing;const f=/^[\r\n]$/.test(e);if(f||b.textWrap==="wrap"&&S&&w+c>S){let g=f?y.length+1:y.length;!w&&!g&&(y+=e,g+=e.length),y.length&&m.push(x.clone({content:y})),m.length&&(h.push(a.clone({fragments:m.slice()})),m.length=0);const n=x.content.substring(g);(n.length||B.length)&&l.unshift(a.clone({maxCharWidth:0,fragments:(n.length?[x.clone({content:n})]:[]).concat(B.slice())})),B.length=0,s=!0;break}else w+=c;y+=e,e=""}s||m.push(x.clone())}m.length&&h.push(a.clone({fragments:m}))}return h}function I(r){return{width:0,height:0,color:null,backgroundColor:null,fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:null,lineHeight:1,letterSpacing:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0,writingMode:"horizontal-tb",...r}}function R(r){const{content:t}=r,{width:o,height:h,...l}=I(r.style);let a=L(t,l);a=U(a,o,h);let x=a.reduce((e,i)=>e+i.maxCharWidth*i.getComputedStyle().lineHeight,0),B=0,w=0;a.forEach(e=>{const i=[];let S=null,c=B,f=w;e.fragments.forEach((n,k)=>{const u=n.getComputedStyle();switch(u.writingMode){case"vertical-rl":case"vertical-lr":{const p=e.maxCharWidth,C=p*u.lineHeight;k||(f=0,u.writingMode==="vertical-rl"&&(x-=C,c=x));const A=n.content.length,W=A*u.fontSize+(A-1)*u.letterSpacing;n.contentBox.x=c+(C-p)/2,n.contentBox.y=f,n.contentBox.width=p,n.contentBox.height=W,n.inlineBox.x=c,n.inlineBox.y=f,n.inlineBox.width=C,n.inlineBox.height=W,n.glyphBox.x=c+(C-p)/2,n.glyphBox.y=f,n.glyphBox.width=p,n.glyphBox.height=W,n.baseline=0,n.centerX=c+C/2,f+=W+u.letterSpacing;break}case"horizontal-tb":{k||(c=0);const{fontBoundingBoxAscent:p,fontBoundingBoxDescent:C,actualBoundingBoxAscent:A,actualBoundingBoxDescent:W,actualBoundingBoxLeft:Y,actualBoundingBoxRight:J,width:X}=E(n.content,{...u,textAlign:"center",verticalAlign:"baseline"}),$=u.fontSize,O=$*u.lineHeight,Q=p+C,Z=A+W,_=Y+J,D=f+(O-Q)/2+p;n.contentBox.x=c,n.contentBox.y=f+(O-$)/2,n.contentBox.width=X,n.contentBox.height=$,n.inlineBox.x=c,n.inlineBox.y=f,n.inlineBox.width=X,n.inlineBox.height=O,n.glyphBox.x=c,n.glyphBox.y=D-A,n.glyphBox.width=_,n.glyphBox.height=Z,n.baseline=D,n.centerX=c+Y,i.push(n.contentBox),e.contentBox=d.from(...i),e.contentBox.height<n.contentBox.height&&(S=n),c+=X;break}}}),e.lineBox=d.from(...e.fragments.map(n=>n.inlineBox)),B+=e.lineBox.width,w+=e.lineBox.height;const g=E("x",{...(S??e).getComputedStyle(),textAlign:"left",verticalAlign:"baseline"});e.xHeight=g.actualBoundingBoxAscent,e.baseline=e.lineBox.y+(e.lineBox.height-(g.fontBoundingBoxAscent+g.fontBoundingBoxDescent))/2+g.fontBoundingBoxAscent});const m=d.from(...a.map(e=>e.lineBox),new d({width:o,height:h})),{width:b,height:y}=m;a.forEach(e=>{e.contentBox=d.from(...e.fragments.map(i=>i.contentBox)),e.glyphBox=d.from(...e.fragments.map(i=>i.glyphBox)),e.fragments.forEach(i=>{const S=i.getComputedStyle(),c=i.inlineBox.x,f=i.inlineBox.y;let g=c,n=f;switch(S.writingMode){case"vertical-rl":case"vertical-lr":switch(S.textAlign){case"end":case"right":n+=y-e.contentBox.height;break;case"center":n+=(y-e.contentBox.height)/2;break}break;case"horizontal-tb":{switch(S.textAlign){case"end":case"right":g+=b-e.contentBox.width;break;case"center":g+=(b-e.contentBox.width)/2;break}switch(S.verticalAlign){case"top":n+=e.lineBox.y-i.inlineBox.y;break;case"middle":n=e.baseline-e.xHeight/2-i.inlineBox.height/2;break;case"bottom":n+=e.lineBox.bottom-i.inlineBox.bottom;break;case"sub":n+=e.baseline-i.glyphBox.bottom;break;case"super":n+=e.baseline-i.glyphBox.y;break;case"text-top":n+=e.glyphBox.y-i.inlineBox.y;break;case"text-bottom":n+=e.glyphBox.bottom-i.inlineBox.bottom;break;case"baseline":default:i.inlineBox.height<e.lineBox.height&&(n+=e.baseline-i.baseline);break}break}}const k=g-c,u=n-f;i.inlineBox.move(k,u),i.contentBox.move(k,u),i.glyphBox.move(k,u),i.baseline+=u,i.centerX+=k}),e.contentBox=d.from(...e.fragments.map(i=>i.contentBox)),e.glyphBox=d.from(...e.fragments.map(i=>i.glyphBox))});const s=d.from(...a.map(e=>e.contentBox)),v=d.from(...a.map(e=>e.glyphBox));return{box:m,contentBox:s,glyphBox:v,paragraphs:a,viewBox:d.from(m,v)}}function F(r,t,o){if(typeof t=="string"&&t.startsWith("linear-gradient")){const{x0:h,y0:l,x1:a,y1:x,stops:B}=V(t,o.left,o.top,o.width,o.height),w=r.createLinearGradient(h,l,a,x);return B.forEach(m=>w.addColorStop(m.offset,m.color)),w}return t}function V(r,t,o,h,l){var v;const a=((v=r.match(/linear-gradient\((.+)\)$/))==null?void 0:v[1])??"",x=a.split(",")[0],B=x.includes("deg")?x:"0deg",w=a.replace(B,"").matchAll(/(#|rgba|rgb)(.+?) ([\d.]+?%)/gi),b=(Number(B.replace("deg",""))||0)*Math.PI/180,y=h*Math.sin(b),s=l*Math.cos(b);return{x0:t+h/2-y,y0:o+l/2+s,x1:t+h/2+y,y1:o+l/2-s,stops:Array.from(w).map(e=>{let i=e[2];return i.startsWith("(")?i=i.split(",").length>3?`rgba${i}`:`rgb${i}`:i=`#${i}`,{offset:Number(e[3].replace("%",""))/100,color:i}})}}function z(r,t,o){o!=null&&o.color&&(o.color=F(r,o.color,t)),o!=null&&o.backgroundColor&&(o.backgroundColor=F(r,o.backgroundColor,t)),o!=null&&o.textStrokeColor&&(o.textStrokeColor=F(r,o.textStrokeColor,t))}function q(r){const{view:t=document.createElement("canvas"),style:o,draws:h=[],pixelRatio:l=1}=r,a=h.length>0?h:[{}],{viewBox:x,paragraphs:B}=R(r),{x:w,y:m,width:b,height:y}=x,s=t.getContext("2d");t.style.width=`${b}px`,t.style.height=`${y}px`,t.dataset.viewbox=`${w} ${m} ${b} ${y}`,t.dataset.pixelRatio=String(l),t.width=Math.max(1,Math.floor(b*l)),t.height=Math.max(1,Math.floor(y*l)),s.scale(l,l),s.clearRect(0,0,t.width,t.height);const v={...o};return z(s,new d({width:b,height:y}),v),B.forEach(e=>{z(s,e.contentBox,e.style),e.fragments.forEach(i=>{z(s,i.contentBox,i.style)})}),a.forEach(e=>{const i={...e};z(s,new d({width:b,height:y}),i);const S={...v,...i};S!=null&&S.backgroundColor&&(s.fillStyle=S.backgroundColor,s.fillRect(0,0,t.width,t.height)),B.forEach(c=>{var f;(f=c.style)!=null&&f.backgroundColor&&(s.fillStyle=c.style.backgroundColor,s.fillRect(c.lineBox.x,c.lineBox.y,c.lineBox.width,c.lineBox.height)),c.fragments.forEach(g=>{var n;(n=g.style)!=null&&n.backgroundColor&&(s.fillStyle=g.style.backgroundColor,s.fillRect(g.inlineBox.x,g.inlineBox.y,g.inlineBox.width,g.inlineBox.height))})}),B.forEach(c=>{c.fragments.forEach(f=>{const g={...f.getComputedStyle(),...i};P(s,{...g,textAlign:"left",verticalAlign:"baseline"});const{width:n,height:k}=f.contentBox;let u=-x.x,p=-x.y;i.offsetX&&(u+=i.offsetX),i.offsetY&&(p+=i.offsetY);let C=p;switch(g.writingMode){case"vertical-rl":case"vertical-lr":u+=f.contentBox.x,p+=(g.fontSize-c.xHeight)/2+c.xHeight+1;break;case"horizontal-tb":u+=f.contentBox.x,p+=f.contentBox.y,C+=f.baseline;break}switch(g.writingMode){case"vertical-rl":case"vertical-lr":{let A=0;for(const W of f.content)s.fillText(W,u,p+A),g.textStrokeWidth&&s.strokeText(W,u,p+A),A+=g.fontSize+g.letterSpacing;break}case"horizontal-tb":s.fillText(f.content,u,C),g.textStrokeWidth&&s.strokeText(f.content,u,C);break}switch(g.textDecoration){case"underline":s.strokeStyle=s.fillStyle,s.lineWidth=g.fontSize/15,s.beginPath(),s.moveTo(u,p+k),s.lineTo(u+n,p+k),s.stroke();break;case"line-through":s.strokeStyle=s.fillStyle,s.lineWidth=g.fontSize/15,s.beginPath(),s.moveTo(u,p+k/2),s.lineTo(u+n,p+k/2),s.stroke();break}})})}),t}M.measureText=R,M.renderText=q,Object.defineProperty(M,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(v,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(v=typeof globalThis<"u"?globalThis:v||self,g(v.modernText={}))})(this,function(v){"use strict";class g{constructor(t=0,u=0,n=0,o=0){this.x=t,this.y=u,this.width=n,this.height=o}get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}static from(...t){const u=t[0],n=t.slice(1).reduce((o,a)=>(o.x=Math.min(o.x,a.x),o.y=Math.min(o.y,a.y),o.right=Math.max(o.right,a.right),o.bottom=Math.max(o.bottom,a.bottom),o),{x:u.x,y:u.y,right:u.right,bottom:u.bottom});return new g(n.x,n.y,n.right-n.x,n.bottom-n.y)}rotate90deg(){const{width:t,height:u}=this;this.width=u,this.height=t}translate(t,u){return this.x+=t,this.y+=u,this}clone(){return new g(this.x,this.y,this.width,this.height)}toArray(){return[this.x,this.y,this.width,this.height]}}const P="OffscreenCanvas"in globalThis;let $;function L(){return $??($=P?new OffscreenCanvas(1,1):document.createElement("canvas"))}function R(r,t){switch(t.shadowColor&&(r.shadowColor=t.shadowColor),t.shadowOffsetX!==void 0&&(r.shadowOffsetX=t.shadowOffsetX),t.shadowOffsetY!==void 0&&(r.shadowOffsetY=t.shadowOffsetY),t.shadowBlur!==void 0&&(r.shadowBlur=t.shadowBlur),r.strokeStyle=t.textStrokeColor??"#000",t.textStrokeWidth!==void 0&&(r.lineWidth=t.textStrokeWidth),r.fillStyle=t.color??"#000",t.textAlign&&(r.textAlign=t.textAlign),t.fontKerning&&(r.fontKerning=t.fontKerning),t.verticalAlign){case"baseline":r.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":r.textBaseline=t.verticalAlign;break}t.letterSpacing!==void 0&&(r.letterSpacing=`${t.letterSpacing}px`),(t.fontStyle||t.fontWeight!==void 0||t.fontSize!==void 0||t.fontFamily)&&(r.font=[t.fontStyle||"normal",t.fontWeight||"normal",`${t.fontSize||14}px`,t.fontFamily||"sans-serif"].join(" "))}function O(r,t){const u=L().getContext("2d");R(u,{...t,textAlign:"center",verticalAlign:"baseline"});const{width:n,actualBoundingBoxAscent:o,actualBoundingBoxDescent:a,actualBoundingBoxLeft:s,actualBoundingBoxRight:f,fontBoundingBoxAscent:A,fontBoundingBoxDescent:E}=u.measureText(r),x=A+E,p=t.fontSize*t.lineHeight,i=o+a,w=(p-x)/2+A;return{typoAscent:A,typoDescent:E,width:n,height:t.fontSize,typoHeight:x,lineHeight:p,leading:p-x,glyphLeft:s,glyphRight:f,glyphAscent:o,glyphDescent:a,glyphWidth:s+f,glyphHeight:i,baseline:w,centerX:s}}const Y=/[\u{00A7}\u{00A9}\u{00AE}\u{00B1}\u{00BC}-\u{00BE}\u{00D7}\u{00F7}\u{02EA}-\u{02EB}\u{1100}-\u{11FF}\u{1401}-\u{166C}\u{166D}\u{166E}\u{166F}-\u{167F}\u{18B0}-\u{18F5}\u{18F6}-\u{18FF}\u{2016}\u{2020}-\u{2021}\u{2030}-\u{2031}\u{203B}-\u{203C}\u{2042}\u{2047}-\u{2049}\u{2051}\u{2065}\u{20DD}-\u{20E0}\u{20E2}-\u{20E4}\u{2100}-\u{2101}\u{2103}-\u{2106}\u{2107}\u{2108}-\u{2109}\u{210F}\u{2113}\u{2114}\u{2116}-\u{2117}\u{211E}-\u{2123}\u{2125}\u{2127}\u{2129}\u{212E}\u{2135}-\u{2138}\u{2139}\u{213A}-\u{213B}\u{213C}-\u{213F}\u{2145}-\u{2149}\u{214A}\u{214C}-\u{214D}\u{214F}\u{2150}-\u{215F}\u{2160}-\u{2182}\u{2183}-\u{2184}\u{2185}-\u{2188}\u{2189}\u{218C}-\u{218F}\u{221E}\u{2234}-\u{2235}\u{2300}-\u{2307}\u{230C}-\u{231F}\u{2324}-\u{2328}\u{232B}\u{237D}-\u{239A}\u{23BE}-\u{23CD}\u{23CF}\u{23D1}-\u{23DB}\u{23E2}-\u{23FF}\u{2400}-\u{2422}\u{2424}-\u{2426}\u{2427}-\u{243F}\u{2440}-\u{244A}\u{244B}-\u{245F}\u{2460}-\u{249B}\u{249C}-\u{24E9}\u{24EA}-\u{24FF}\u{25A0}-\u{25B6}\u{25B7}\u{25B8}-\u{25C0}\u{25C1}\u{25C2}-\u{25F7}\u{25F8}-\u{25FF}\u{2600}-\u{2619}\u{2620}-\u{266E}\u{266F}\u{2670}-\u{26FF}\u{2700}-\u{2767}\u{2776}-\u{2793}\u{2B12}-\u{2B2F}\u{2B50}-\u{2B59}\u{2B97}\u{2BB8}-\u{2BD1}\u{2BD3}-\u{2BEB}\u{2BF0}-\u{2BFF}\u{2E50}-\u{2E51}\u{2E80}-\u{2E99}\u{2E9A}\u{2E9B}-\u{2EF3}\u{2EF4}-\u{2EFF}\u{2F00}-\u{2FD5}\u{2FD6}-\u{2FDF}\u{2FE0}-\u{2FEF}\u{2FF0}-\u{2FFB}\u{2FFC}-\u{2FFF}\u{3000}\u{3001}-\u{3002}\u{3003}\u{3004}\u{3005}\u{3006}\u{3007}\u{3012}-\u{3013}\u{3020}\u{3021}-\u{3029}\u{302A}-\u{302D}\u{302E}-\u{302F}\u{3031}-\u{3035}\u{3036}-\u{3037}\u{3038}-\u{303A}\u{303B}\u{303C}\u{303D}\u{303E}-\u{303F}\u{3040}\u{3041}\u{3042}\u{3043}\u{3044}\u{3045}\u{3046}\u{3047}\u{3048}\u{3049}\u{304A}-\u{3062}\u{3063}\u{3064}-\u{3082}\u{3083}\u{3084}\u{3085}\u{3086}\u{3087}\u{3088}-\u{308D}\u{308E}\u{308F}-\u{3094}\u{3095}-\u{3096}\u{3097}-\u{3098}\u{3099}-\u{309A}\u{309B}-\u{309C}\u{309D}-\u{309E}\u{309F}\u{30A1}\u{30A2}\u{30A3}\u{30A4}\u{30A5}\u{30A6}\u{30A7}\u{30A8}\u{30A9}\u{30AA}-\u{30C2}\u{30C3}\u{30C4}-\u{30E2}\u{30E3}\u{30E4}\u{30E5}\u{30E6}\u{30E7}\u{30E8}-\u{30ED}\u{30EE}\u{30EF}-\u{30F4}\u{30F5}-\u{30F6}\u{30F7}-\u{30FA}\u{30FB}\u{30FD}-\u{30FE}\u{30FF}\u{3100}-\u{3104}\u{3105}-\u{3126}\u{3127}\u{3128}-\u{312F}\u{3130}\u{3131}-\u{318E}\u{318F}\u{3190}-\u{3191}\u{3192}-\u{3195}\u{3196}-\u{319F}\u{31A0}-\u{31BF}\u{31C0}-\u{31E3}\u{31E4}-\u{31EF}\u{31F0}-\u{31FF}\u{3200}-\u{321E}\u{321F}\u{3220}-\u{3229}\u{322A}-\u{3247}\u{3248}-\u{324F}\u{3250}\u{3251}-\u{325F}\u{3260}-\u{327F}\u{3280}-\u{3289}\u{328A}-\u{32B0}\u{32B1}-\u{32BF}\u{32C0}-\u{32FE}\u{32FF}\u{3300}-\u{3357}\u{3358}-\u{337A}\u{337B}-\u{337F}\u{3380}-\u{33FF}\u{3400}-\u{4DBF}\u{4DC0}-\u{4DFF}\u{4E00}-\u{9FFF}\u{A000}-\u{A014}\u{A015}\u{A016}-\u{A48C}\u{A48D}-\u{A48F}\u{A490}-\u{A4C6}\u{A4C7}-\u{A4CF}\u{A960}-\u{A97C}\u{A97D}-\u{A97F}\u{AC00}-\u{D7A3}\u{D7A4}-\u{D7AF}\u{D7B0}-\u{D7C6}\u{D7C7}-\u{D7CA}\u{D7CB}-\u{D7FB}\u{D7FC}-\u{D7FF}\u{E000}-\u{F8FF}\u{F900}-\u{FA6D}\u{FA6E}-\u{FA6F}\u{FA70}-\u{FAD9}\u{FADA}-\u{FAFF}\u{FE10}-\u{FE16}\u{FE17}\u{FE18}\u{FE19}\u{FE1A}-\u{FE1F}\u{FE30}\u{FE31}-\u{FE32}\u{FE33}-\u{FE34}\u{FE35}\u{FE36}\u{FE37}\u{FE38}\u{FE39}\u{FE3A}\u{FE3B}\u{FE3C}\u{FE3D}\u{FE3E}\u{FE3F}\u{FE40}\u{FE41}\u{FE42}\u{FE43}\u{FE44}\u{FE45}-\u{FE46}\u{FE47}\u{FE48}\u{FE50}-\u{FE52}\u{FE53}\u{FE54}-\u{FE57}\u{FE5F}-\u{FE61}\u{FE62}\u{FE67}\u{FE68}\u{FE69}\u{FE6A}-\u{FE6B}\u{FE6C}-\u{FE6F}\u{FF01}\u{FF02}-\u{FF03}\u{FF04}\u{FF05}-\u{FF07}\u{FF0A}\u{FF0B}\u{FF0C}\u{FF0E}\u{FF0F}\u{FF10}-\u{FF19}\u{FF1F}\u{FF20}\u{FF21}-\u{FF3A}\u{FF3C}\u{FF3E}\u{FF40}\u{FF41}-\u{FF5A}\u{FFE0}-\u{FFE1}\u{FFE2}\u{FFE4}\u{FFE5}-\u{FFE6}\u{FFE7}\u{FFF0}-\u{FFF8}\u{FFFC}-\u{FFFD}\u{10980}-\u{1099F}\u{11580}-\u{115AE}\u{115AF}-\u{115B1}\u{115B2}-\u{115B5}\u{115B6}-\u{115B7}\u{115B8}-\u{115BB}\u{115BC}-\u{115BD}\u{115BE}\u{115BF}-\u{115C0}\u{115C1}-\u{115D7}\u{115D8}-\u{115DB}\u{115DC}-\u{115DD}\u{115DE}-\u{115FF}\u{11A00}\u{11A01}-\u{11A0A}\u{11A0B}-\u{11A32}\u{11A33}-\u{11A38}\u{11A39}\u{11A3A}\u{11A3B}-\u{11A3E}\u{11A3F}-\u{11A46}\u{11A47}\u{11A48}-\u{11A4F}\u{11A50}\u{11A51}-\u{11A56}\u{11A57}-\u{11A58}\u{11A59}-\u{11A5B}\u{11A5C}-\u{11A89}\u{11A8A}-\u{11A96}\u{11A97}\u{11A98}-\u{11A99}\u{11A9A}-\u{11A9C}\u{11A9D}\u{11A9E}-\u{11AA2}\u{11AA3}-\u{11AAF}\u{11AB0}-\u{11ABF}\u{13000}-\u{1342E}\u{1342F}\u{13430}-\u{13438}\u{13439}-\u{1343F}\u{14400}-\u{14646}\u{14647}-\u{1467F}\u{16FE0}-\u{16FE1}\u{16FE2}\u{16FE3}\u{16FE4}\u{16FE5}-\u{16FEF}\u{16FF0}-\u{16FF1}\u{16FF2}-\u{16FFF}\u{17000}-\u{187F7}\u{187F8}-\u{187FF}\u{18800}-\u{18AFF}\u{18B00}-\u{18CD5}\u{18CD6}-\u{18CFF}\u{18D00}-\u{18D08}\u{18D09}-\u{18D7F}\u{1AFF0}-\u{1AFF3}\u{1AFF4}\u{1AFF5}-\u{1AFFB}\u{1AFFC}\u{1AFFD}-\u{1AFFE}\u{1AFFF}\u{1B000}-\u{1B0FF}\u{1B100}-\u{1B122}\u{1B123}-\u{1B12F}\u{1B130}-\u{1B14F}\u{1B150}-\u{1B152}\u{1B153}-\u{1B163}\u{1B164}-\u{1B167}\u{1B168}-\u{1B16F}\u{1B170}-\u{1B2FB}\u{1B2FC}-\u{1B2FF}\u{1CF00}-\u{1CF2D}\u{1CF2E}-\u{1CF2F}\u{1CF30}-\u{1CF46}\u{1CF47}-\u{1CF4F}\u{1CF50}-\u{1CFC3}\u{1CFC4}-\u{1CFCF}\u{1D000}-\u{1D0F5}\u{1D0F6}-\u{1D0FF}\u{1D100}-\u{1D126}\u{1D127}-\u{1D128}\u{1D129}-\u{1D164}\u{1D165}-\u{1D166}\u{1D167}-\u{1D169}\u{1D16A}-\u{1D16C}\u{1D16D}-\u{1D172}\u{1D173}-\u{1D17A}\u{1D17B}-\u{1D182}\u{1D183}-\u{1D184}\u{1D185}-\u{1D18B}\u{1D18C}-\u{1D1A9}\u{1D1AA}-\u{1D1AD}\u{1D1AE}-\u{1D1EA}\u{1D1EB}-\u{1D1FF}\u{1D2E0}-\u{1D2F3}\u{1D2F4}-\u{1D2FF}\u{1D300}-\u{1D356}\u{1D357}-\u{1D35F}\u{1D360}-\u{1D378}\u{1D379}-\u{1D37F}\u{1D800}-\u{1D9FF}\u{1DA00}-\u{1DA36}\u{1DA37}-\u{1DA3A}\u{1DA3B}-\u{1DA6C}\u{1DA6D}-\u{1DA74}\u{1DA75}\u{1DA76}-\u{1DA83}\u{1DA84}\u{1DA85}-\u{1DA86}\u{1DA87}-\u{1DA8B}\u{1DA8C}-\u{1DA9A}\u{1DA9B}-\u{1DA9F}\u{1DAA0}\u{1DAA1}-\u{1DAAF}\u{1F000}-\u{1F02B}\u{1F02C}-\u{1F02F}\u{1F030}-\u{1F093}\u{1F094}-\u{1F09F}\u{1F0A0}-\u{1F0AE}\u{1F0AF}-\u{1F0B0}\u{1F0B1}-\u{1F0BF}\u{1F0C0}\u{1F0C1}-\u{1F0CF}\u{1F0D0}\u{1F0D1}-\u{1F0F5}\u{1F0F6}-\u{1F0FF}\u{1F100}-\u{1F10C}\u{1F10D}-\u{1F1AD}\u{1F1AE}-\u{1F1E5}\u{1F1E6}-\u{1F1FF}\u{1F200}-\u{1F201}\u{1F202}\u{1F203}-\u{1F20F}\u{1F210}-\u{1F23B}\u{1F23C}-\u{1F23F}\u{1F240}-\u{1F248}\u{1F249}-\u{1F24F}\u{1F250}-\u{1F251}\u{1F252}-\u{1F25F}\u{1F260}-\u{1F265}\u{1F266}-\u{1F2FF}\u{1F300}-\u{1F3FA}\u{1F3FB}-\u{1F3FF}\u{1F400}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F650}-\u{1F67F}\u{1F680}-\u{1F6D7}\u{1F6D8}-\u{1F6DC}\u{1F6DD}-\u{1F6EC}\u{1F6ED}-\u{1F6EF}\u{1F6F0}-\u{1F6FC}\u{1F6FD}-\u{1F6FF}\u{1F700}-\u{1F773}\u{1F774}-\u{1F77F}\u{1F780}-\u{1F7D8}\u{1F7D9}-\u{1F7DF}\u{1F7E0}-\u{1F7EB}\u{1F7EC}-\u{1F7EF}\u{1F7F0}\u{1F7F1}-\u{1F7FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA53}\u{1FA54}-\u{1FA5F}\u{1FA60}-\u{1FA6D}\u{1FA6E}-\u{1FA6F}\u{1FA70}-\u{1FA74}\u{1FA75}-\u{1FA77}\u{1FA78}-\u{1FA7C}\u{1FA7D}-\u{1FA7F}\u{1FA80}-\u{1FA86}\u{1FA87}-\u{1FA8F}\u{1FA90}-\u{1FAAC}\u{1FAAD}-\u{1FAAF}\u{1FAB0}-\u{1FABA}\u{1FABB}-\u{1FABF}\u{1FAC0}-\u{1FAC5}\u{1FAC6}-\u{1FACF}\u{1FAD0}-\u{1FAD9}\u{1FADA}-\u{1FADF}\u{1FAE0}-\u{1FAE7}\u{1FAE8}-\u{1FAEF}\u{1FAF0}-\u{1FAF6}\u{1FAF7}-\u{1FAFF}\u{20000}-\u{2A6DF}\u{2A6E0}-\u{2A6FF}\u{2A700}-\u{2B738}\u{2B739}-\u{2B73F}\u{2B740}-\u{2B81D}\u{2B81E}-\u{2B81F}\u{2B820}-\u{2CEA1}\u{2CEA2}-\u{2CEAF}\u{2CEB0}-\u{2EBE0}\u{2EBE1}-\u{2F7FF}\u{2F800}-\u{2FA1D}\u{2FA1E}-\u{2FFFD}\u{30000}-\u{3134A}\u{3134B}-\u{3134F}\u{31350}-\u{3FFFD}]/u,U=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/,K=/[\r\n]/;class z{constructor(t,u){this.content=t,this.parent=u,this.contentBox=new g,this.glyphBox=new g}get computedStyle(){return this.parent.computedStyle}get verticalOrientation(){switch(this.computedStyle.textOrientation){case"upright":return"U";case"sideways-right":case"sideways":return"R";case"mixed":default:return Y.test(this.content)?"U":"R"}}get isPunctuation(){return U.test(this.content)}get isEOL(){return K.test(this.content)}measure(){const t=this.computedStyle,{width:u,height:n,glyphWidth:o,glyphHeight:a}=O(this.content,{...t,letterSpacing:0});if(this.contentBox.width=u,this.contentBox.height=n,this.glyphBox.width=o,this.glyphBox.height=a,t.writingMode.startsWith("vertical"))switch(this.verticalOrientation){case"R":case"Tr":this.contentBox.rotate90deg(),this.glyphBox.rotate90deg();break}return this}clone(){const t=new z(this.content,this.parent);return t.contentBox=this.contentBox.clone(),t.glyphBox=this.glyphBox.clone(),t}}class T{constructor(t,u,n){this.content=t,this.style=u,this.parent=n,this.contentBox=new g,this.inlineBox=new g,this.glyphBox=new g,this.centerX=0,this.baseline=0,this.update()}update(){var n;this.computedStyle={...(n=this.parent)==null?void 0:n.computedStyle,...this.style};const t=this.computedStyle;this.computedContent=t.textTransform==="uppercase"?this.content.toUpperCase():t.textTransform==="lowercase"?this.content.toLowerCase():this.content;const u=[];for(const o of this.computedContent)u.push(new z(o,this));return this.characters=u,this}measure(){const t=this.computedStyle;switch(t.writingMode){case"vertical-lr":case"vertical-rl":{let u=0,n=0,o=0;this.characters.forEach((a,s)=>{a.measure(),n=Math.max(n,a.contentBox.width),o=Math.max(o,a.glyphBox.width),u+=a.contentBox.height,s!==this.characters.length-1&&(u+=t.letterSpacing)}),this.contentBox.width=n,this.contentBox.height=u,this.glyphBox.width=o,this.glyphBox.height=u,this.inlineBox.width=t.fontSize*t.lineHeight,this.inlineBox.height=u;break}case"horizontal-tb":{const{width:u,height:n,lineHeight:o,glyphAscent:a,glyphWidth:s,glyphHeight:f,baseline:A,centerX:E}=O(this.computedContent,t);this.inlineBox.width=u,this.inlineBox.height=o,this.contentBox.width=u,this.contentBox.height=n,this.glyphBox.width=s,this.glyphBox.height=f,this.baseline=A,this.inlineBox.x=0,this.inlineBox.y=0,this.contentBox.x=0,this.contentBox.y=(this.inlineBox.height-this.contentBox.height)/2,this.glyphBox.x=0,this.glyphBox.y=A-a,this.centerX=E;break}}return this}clone(t){return new T(t??this.content,this.style,this.parent)}}class M{constructor(t,u){this.style=t,this.parent=u,this.contentBox=new g,this.lineBox=new g,this.glyphBox=new g,this.baseline=0,this.xHeight=0,this.fragments=[],this.update()}update(){this.computedStyle={...this.parent,...this.style}}addFragment(t,u){return this.fragments.push(new T(t,u,this)),this}clone(t){const u=new M;return u.style=this.style,u.parent=this.parent,u.contentBox=this.contentBox.clone(),u.lineBox=this.lineBox.clone(),u.glyphBox=this.glyphBox.clone(),u.baseline=this.baseline,u.xHeight=this.xHeight,u.fragments=t??this.fragments.map(n=>n.clone()),u.computedStyle=this.computedStyle,u}}function N(r,t){const u=[];if(typeof r=="string")u.push(new M(void 0,t).addFragment(r));else{r=Array.isArray(r)?r:[r];for(const n of r)if(typeof n=="string")u.push(new M(void 0,t).addFragment(n));else if(Array.isArray(n)){const o=new M(void 0,t);n.forEach(a=>{if(typeof a=="string")o.addFragment(a);else{const{content:s,...f}=a;o.addFragment(s,f)}}),u.push(o)}else if("fragments"in n){const{fragments:o,...a}=n,s=new M(a,t);o.forEach(f=>{const{content:A,...E}=f;s.addFragment(A,E)}),u.push(s)}else if("content"in n){const{content:o,...a}=n;u.push(new M(a,t).addFragment(o))}}return u}function j(r,t,u){var f;const n=[],o=r.slice();let a,s;for(;a=o.shift();){const A=a.fragments.slice();let E=0;const x=[];for(;s=A.shift();){const p=s.computedStyle;let i="",w=!1,S=0;const e=new T("",s.style,s.parent);for(const F of s.characters){if(e.content+=F.content,(f=s.characters[++S])!=null&&f.isPunctuation)continue;const D=F.isEOL;let d,c;switch(p.writingMode){case"vertical-lr":case"vertical-rl":d=u,c=e.update().measure().contentBox.height;break;case"horizontal-tb":default:d=t,c=e.update().measure().contentBox.width;break}if(D||d&&E+c>d){let l=D?i.length+1:i.length;!E&&!l&&(i+=e.content,l+=e.content.length),i.length&&x.push(s.clone(i)),x.length&&(n.push(a.clone(x.slice())),x.length=0);const B=s.content.substring(l);(B.length||A.length)&&o.unshift(a.clone((B.length?[s.clone(B)]:[]).concat(A.slice()))),A.length=0,w=!0;break}else E+=c;i+=e.content,e.content=""}w||x.push(s.clone())}x.length&&n.push(a.clone(x))}return n}function G(r){return{width:0,height:0,color:"#000",backgroundColor:null,fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000",lineHeight:1,letterSpacing:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0,writingMode:"horizontal-tb",textOrientation:"mixed",...r}}function X(r){const{content:t,effects:u=[{}]}=r,{width:n,height:o,...a}=G(r.style);let s=N(t,a);s=j(s,n,o);let f=0,A=0;s.forEach(e=>{let F=null;e.fragments.forEach(h=>{h.update().measure(),(!F||F.contentBox.height<h.contentBox.height)&&(F=h)});const{typoHeight:D,typoAscent:d,lineHeight:c}=O("x",(F??e).computedStyle);e.xHeight=D,e.baseline=A+(c-D)/2+d;let l=f,B=A,m=0;e.fragments.forEach((h,C)=>{const y=h.computedStyle;switch(y.writingMode){case"vertical-rl":case"vertical-lr":{C||(B=0),h.inlineBox.translate(l,B),h.contentBox.translate(l,B),h.glyphBox.translate(l,B),h.baseline+=B,h.centerX+=l;let k=B;h.characters.forEach((b,q)=>{b.contentBox.x=l+(h.inlineBox.width-b.contentBox.width)/2,b.contentBox.y=k,b.glyphBox.x=l+(h.inlineBox.width-b.glyphBox.width)/2,b.glyphBox.y=k,k+=b.contentBox.height,q!==h.characters.length-1&&(k+=y.letterSpacing)}),B+=h.inlineBox.height,C===e.fragments.length-1&&(l+=h.inlineBox.width);break}case"horizontal-tb":{C||(l=0),h.inlineBox.translate(l,B),h.contentBox.translate(l,B),h.glyphBox.translate(l,B),h.baseline+=B,h.centerX+=l,l+=h.inlineBox.width,m=Math.max(m,h.inlineBox.height),C===e.fragments.length-1&&(B+=m);break}}}),f=l,A=B,e.lineBox=g.from(...e.fragments.map(h=>h.inlineBox))});const E=g.from(...s.map(e=>e.lineBox),new g(0,0,n,o)),{width:x,height:p}=E;s.forEach(e=>{e.lineBox.width=Math.max(e.lineBox.width,x),e.contentBox=g.from(...e.fragments.map(F=>F.contentBox)),e.glyphBox=g.from(...e.fragments.map(F=>F.glyphBox)),e.fragments.forEach(F=>{const D=F.computedStyle;let d=0,c=0;switch(D.writingMode){case"vertical-rl":case"vertical-lr":switch(D.textAlign){case"end":case"right":c=p-e.contentBox.height;break;case"center":c=(p-e.contentBox.height)/2;break}break;case"horizontal-tb":{switch(D.textAlign){case"end":case"right":d=x-e.contentBox.width;break;case"center":d=(x-e.contentBox.width)/2;break}switch(D.verticalAlign){case"top":c=e.lineBox.y-F.inlineBox.y;break;case"middle":c=F.inlineBox.y-(e.baseline-e.xHeight/2-F.inlineBox.height/2);break;case"bottom":c=e.lineBox.bottom-F.inlineBox.bottom;break;case"sub":c=e.baseline-F.glyphBox.bottom;break;case"super":c=e.baseline-F.glyphBox.y;break;case"text-top":c=e.glyphBox.y-F.inlineBox.y;break;case"text-bottom":c=e.glyphBox.bottom-F.inlineBox.bottom;break;case"baseline":default:F.inlineBox.height<e.lineBox.height&&(c=e.baseline-F.baseline);break}break}}F.inlineBox.translate(d,c),F.contentBox.translate(d,c),F.glyphBox.translate(d,c),F.baseline+=c,F.centerX+=d}),e.contentBox=g.from(...e.fragments.map(F=>F.contentBox)),e.glyphBox=g.from(...e.fragments.map(F=>F.glyphBox))});const i=g.from(...s.map(e=>e.contentBox)),w=g.from(...s.map(e=>e.glyphBox)),S=[];return s.forEach(e=>{e.fragments.forEach(F=>{const D=F.computedStyle;u.forEach(d=>{const c={...D,...d},{textStrokeWidth:l=0,offsetX:B=0,offsetY:m=0}=c;if(l||B||m){const{x:h,y:C,width:y,height:k}=F.contentBox;S.push(new g(Math.min(h,h+B-l/2),Math.min(C,C+m-l/2),Math.max(y,y+B+l),Math.max(k,k+m+l)))}})})}),{box:E,contentBox:i,glyphBox:w,paragraphs:s,viewBox:g.from(E,w,...S)}}function H(r,t,u){if(typeof t=="string"&&t.startsWith("linear-gradient")){const{x0:n,y0:o,x1:a,y1:s,stops:f}=I(t,u.left,u.top,u.width,u.height),A=r.createLinearGradient(n,o,a,s);return f.forEach(E=>A.addColorStop(E.offset,E.color)),A}return t}function I(r,t,u,n,o){var w;const a=((w=r.match(/linear-gradient\((.+)\)$/))==null?void 0:w[1])??"",s=a.split(",")[0],f=s.includes("deg")?s:"0deg",A=a.replace(f,"").matchAll(/(#|rgba|rgb)(.+?) ([\d.]+?%)/gi),x=(Number(f.replace("deg",""))||0)*Math.PI/180,p=n*Math.sin(x),i=o*Math.cos(x);return{x0:t+n/2-p,y0:u+o/2+i,x1:t+n/2+p,y1:u+o/2-i,stops:Array.from(A).map(S=>{let e=S[2];return e.startsWith("(")?e=e.split(",").length>3?`rgba${e}`:`rgb${e}`:e=`#${e}`,{offset:Number(S[3].replace("%",""))/100,color:e}})}}function W(r,t,u){u!=null&&u.color&&(u.color=H(r,u.color,t)),u!=null&&u.backgroundColor&&(u.backgroundColor=H(r,u.backgroundColor,t)),u!=null&&u.textStrokeColor&&(u.textStrokeColor=H(r,u.textStrokeColor,t))}function V(r){const{view:t=document.createElement("canvas"),style:u,effects:n=[],pixelRatio:o=1}=r,a=n.length>0?n:[{}],{viewBox:s,paragraphs:f}=X(r),{x:A,y:E,width:x,height:p}=s,i=t.getContext("2d");t.style.width=`${x}px`,t.style.height=`${p}px`,t.dataset.viewbox=`${A} ${E} ${x} ${p}`,t.dataset.pixelRatio=String(o),t.width=Math.max(1,Math.floor(x*o)),t.height=Math.max(1,Math.floor(p*o)),i.scale(o,o),i.clearRect(0,0,t.width,t.height);const w=(e,F,D,d,c)=>{i.fillStyle=e,i.fillRect(-s.x+F,-s.y+D,d,c)},S={...u};return W(i,new g(0,0,x,p),S),f.forEach(e=>{W(i,e.contentBox,e.computedStyle),e.fragments.forEach(F=>{W(i,F.contentBox,F.computedStyle)})}),a.forEach(e=>{const F={...e};W(i,new g(0,0,x,p),F);const D={...S,...F};D!=null&&D.backgroundColor&&w(D.backgroundColor,0,0,t.width,t.height),f.forEach(d=>{var c;(c=d.style)!=null&&c.backgroundColor&&w(d.style.backgroundColor,...d.lineBox.toArray()),d.fragments.forEach(l=>{var B;(B=l.style)!=null&&B.backgroundColor&&w(l.style.backgroundColor,...l.inlineBox.toArray())})}),f.forEach(d=>{d.fragments.forEach(c=>{const l=-s.x+(F.offsetX??0),B=-s.y+(F.offsetY??0),m={...c.computedStyle,...F};switch(R(i,{...m,textAlign:"left",verticalAlign:m.writingMode==="horizontal-tb"?"baseline":"top"}),m.writingMode){case"vertical-rl":case"vertical-lr":{c.characters.forEach(h=>{let{x:C,y}=h.contentBox;switch(C+=l,y+=B,h.verticalOrientation){case"R":case"Tr":{i.translate(C+h.contentBox.width,y),i.rotate(Math.PI/2),i.fillText(h.content,0,0),m.textStrokeWidth&&i.strokeText(h.content,0,0),i.setTransform(1,0,0,1,0,0);break}default:i.fillText(h.content,C,y),m.textStrokeWidth&&i.strokeText(h.content,C,y);break}});break}case"horizontal-tb":{const h=l+c.contentBox.x,C=B+c.contentBox.y,y=B+c.baseline;i.fillText(c.content,h,y),m.textStrokeWidth&&i.strokeText(c.content,h,y);const{width:k,height:b}=c.contentBox;switch(m.textDecoration){case"underline":i.strokeStyle=i.fillStyle,i.lineWidth=m.fontSize/15,i.beginPath(),i.moveTo(h,C+b),i.lineTo(h+k,C+b),i.stroke();break;case"line-through":i.strokeStyle=i.fillStyle,i.lineWidth=m.fontSize/15,i.beginPath(),i.moveTo(h,C+b/2),i.lineTo(h+k,C+b/2),i.stroke();break}break}}})})}),t}v.measureText=X,v.renderText=V,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
class
|
|
1
|
+
class d {
|
|
2
|
+
constructor(t = 0, u = 0, n = 0, o = 0) {
|
|
3
|
+
this.x = t, this.y = u, this.width = n, this.height = o;
|
|
4
|
+
}
|
|
2
5
|
get left() {
|
|
3
6
|
return this.x;
|
|
4
7
|
}
|
|
@@ -11,228 +14,296 @@ class u {
|
|
|
11
14
|
get bottom() {
|
|
12
15
|
return this.y + this.height;
|
|
13
16
|
}
|
|
14
|
-
constructor({ x: t = 0, y: o = 0, width: h = 0, height: l = 0 } = {}) {
|
|
15
|
-
this.x = t, this.y = o, this.width = h, this.height = l;
|
|
16
|
-
}
|
|
17
17
|
static from(...t) {
|
|
18
|
-
const
|
|
19
|
-
return new
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
const u = t[0], n = t.slice(1).reduce((o, a) => (o.x = Math.min(o.x, a.x), o.y = Math.min(o.y, a.y), o.right = Math.max(o.right, a.right), o.bottom = Math.max(o.bottom, a.bottom), o), { x: u.x, y: u.y, right: u.right, bottom: u.bottom });
|
|
19
|
+
return new d(
|
|
20
|
+
n.x,
|
|
21
|
+
n.y,
|
|
22
|
+
n.right - n.x,
|
|
23
|
+
n.bottom - n.y
|
|
24
|
+
);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
rotate90deg() {
|
|
27
|
+
const { width: t, height: u } = this;
|
|
28
|
+
this.width = u, this.height = t;
|
|
29
|
+
}
|
|
30
|
+
translate(t, u) {
|
|
31
|
+
return this.x += t, this.y += u, this;
|
|
28
32
|
}
|
|
29
33
|
clone() {
|
|
30
|
-
return new
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
return new d(
|
|
35
|
+
this.x,
|
|
36
|
+
this.y,
|
|
37
|
+
this.width,
|
|
38
|
+
this.height
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
toArray() {
|
|
42
|
+
return [this.x, this.y, this.width, this.height];
|
|
36
43
|
}
|
|
37
44
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
const X = "OffscreenCanvas" in globalThis;
|
|
46
|
+
let $;
|
|
47
|
+
function P() {
|
|
48
|
+
return $ ?? ($ = X ? new OffscreenCanvas(1, 1) : document.createElement("canvas"));
|
|
49
|
+
}
|
|
50
|
+
function H(r, t) {
|
|
51
|
+
switch (t.shadowColor && (r.shadowColor = t.shadowColor), t.shadowOffsetX !== void 0 && (r.shadowOffsetX = t.shadowOffsetX), t.shadowOffsetY !== void 0 && (r.shadowOffsetY = t.shadowOffsetY), t.shadowBlur !== void 0 && (r.shadowBlur = t.shadowBlur), r.strokeStyle = t.textStrokeColor ?? "#000", t.textStrokeWidth !== void 0 && (r.lineWidth = t.textStrokeWidth), r.fillStyle = t.color ?? "#000", t.textAlign && (r.textAlign = t.textAlign), t.fontKerning && (r.fontKerning = t.fontKerning), t.verticalAlign) {
|
|
52
|
+
case "baseline":
|
|
53
|
+
r.textBaseline = "alphabetic";
|
|
54
|
+
break;
|
|
55
|
+
case "top":
|
|
56
|
+
case "middle":
|
|
57
|
+
case "bottom":
|
|
58
|
+
r.textBaseline = t.verticalAlign;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
t.letterSpacing !== void 0 && (r.letterSpacing = `${t.letterSpacing}px`), (t.fontStyle || t.fontWeight !== void 0 || t.fontSize !== void 0 || t.fontFamily) && (r.font = [
|
|
62
|
+
t.fontStyle || "normal",
|
|
63
|
+
t.fontWeight || "normal",
|
|
64
|
+
`${t.fontSize || 14}px`,
|
|
65
|
+
t.fontFamily || "sans-serif"
|
|
66
|
+
].join(" "));
|
|
67
|
+
}
|
|
68
|
+
function O(r, t) {
|
|
69
|
+
const u = P().getContext("2d");
|
|
70
|
+
H(u, {
|
|
71
|
+
...t,
|
|
72
|
+
textAlign: "center",
|
|
73
|
+
verticalAlign: "baseline"
|
|
74
|
+
});
|
|
75
|
+
const {
|
|
76
|
+
width: n,
|
|
77
|
+
actualBoundingBoxAscent: o,
|
|
78
|
+
actualBoundingBoxDescent: a,
|
|
79
|
+
actualBoundingBoxLeft: h,
|
|
80
|
+
actualBoundingBoxRight: E,
|
|
81
|
+
fontBoundingBoxAscent: B,
|
|
82
|
+
fontBoundingBoxDescent: f
|
|
83
|
+
} = u.measureText(r), A = B + f, p = t.fontSize * t.lineHeight, i = o + a, w = (p - A) / 2 + B;
|
|
84
|
+
return {
|
|
85
|
+
typoAscent: B,
|
|
86
|
+
typoDescent: f,
|
|
87
|
+
width: n,
|
|
88
|
+
height: t.fontSize,
|
|
89
|
+
typoHeight: A,
|
|
90
|
+
lineHeight: p,
|
|
91
|
+
leading: p - A,
|
|
92
|
+
glyphLeft: h,
|
|
93
|
+
glyphRight: E,
|
|
94
|
+
glyphAscent: o,
|
|
95
|
+
glyphDescent: a,
|
|
96
|
+
glyphWidth: h + E,
|
|
97
|
+
glyphHeight: i,
|
|
98
|
+
baseline: w,
|
|
99
|
+
centerX: h
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const L = /[\u{00A7}\u{00A9}\u{00AE}\u{00B1}\u{00BC}-\u{00BE}\u{00D7}\u{00F7}\u{02EA}-\u{02EB}\u{1100}-\u{11FF}\u{1401}-\u{166C}\u{166D}\u{166E}\u{166F}-\u{167F}\u{18B0}-\u{18F5}\u{18F6}-\u{18FF}\u{2016}\u{2020}-\u{2021}\u{2030}-\u{2031}\u{203B}-\u{203C}\u{2042}\u{2047}-\u{2049}\u{2051}\u{2065}\u{20DD}-\u{20E0}\u{20E2}-\u{20E4}\u{2100}-\u{2101}\u{2103}-\u{2106}\u{2107}\u{2108}-\u{2109}\u{210F}\u{2113}\u{2114}\u{2116}-\u{2117}\u{211E}-\u{2123}\u{2125}\u{2127}\u{2129}\u{212E}\u{2135}-\u{2138}\u{2139}\u{213A}-\u{213B}\u{213C}-\u{213F}\u{2145}-\u{2149}\u{214A}\u{214C}-\u{214D}\u{214F}\u{2150}-\u{215F}\u{2160}-\u{2182}\u{2183}-\u{2184}\u{2185}-\u{2188}\u{2189}\u{218C}-\u{218F}\u{221E}\u{2234}-\u{2235}\u{2300}-\u{2307}\u{230C}-\u{231F}\u{2324}-\u{2328}\u{232B}\u{237D}-\u{239A}\u{23BE}-\u{23CD}\u{23CF}\u{23D1}-\u{23DB}\u{23E2}-\u{23FF}\u{2400}-\u{2422}\u{2424}-\u{2426}\u{2427}-\u{243F}\u{2440}-\u{244A}\u{244B}-\u{245F}\u{2460}-\u{249B}\u{249C}-\u{24E9}\u{24EA}-\u{24FF}\u{25A0}-\u{25B6}\u{25B7}\u{25B8}-\u{25C0}\u{25C1}\u{25C2}-\u{25F7}\u{25F8}-\u{25FF}\u{2600}-\u{2619}\u{2620}-\u{266E}\u{266F}\u{2670}-\u{26FF}\u{2700}-\u{2767}\u{2776}-\u{2793}\u{2B12}-\u{2B2F}\u{2B50}-\u{2B59}\u{2B97}\u{2BB8}-\u{2BD1}\u{2BD3}-\u{2BEB}\u{2BF0}-\u{2BFF}\u{2E50}-\u{2E51}\u{2E80}-\u{2E99}\u{2E9A}\u{2E9B}-\u{2EF3}\u{2EF4}-\u{2EFF}\u{2F00}-\u{2FD5}\u{2FD6}-\u{2FDF}\u{2FE0}-\u{2FEF}\u{2FF0}-\u{2FFB}\u{2FFC}-\u{2FFF}\u{3000}\u{3001}-\u{3002}\u{3003}\u{3004}\u{3005}\u{3006}\u{3007}\u{3012}-\u{3013}\u{3020}\u{3021}-\u{3029}\u{302A}-\u{302D}\u{302E}-\u{302F}\u{3031}-\u{3035}\u{3036}-\u{3037}\u{3038}-\u{303A}\u{303B}\u{303C}\u{303D}\u{303E}-\u{303F}\u{3040}\u{3041}\u{3042}\u{3043}\u{3044}\u{3045}\u{3046}\u{3047}\u{3048}\u{3049}\u{304A}-\u{3062}\u{3063}\u{3064}-\u{3082}\u{3083}\u{3084}\u{3085}\u{3086}\u{3087}\u{3088}-\u{308D}\u{308E}\u{308F}-\u{3094}\u{3095}-\u{3096}\u{3097}-\u{3098}\u{3099}-\u{309A}\u{309B}-\u{309C}\u{309D}-\u{309E}\u{309F}\u{30A1}\u{30A2}\u{30A3}\u{30A4}\u{30A5}\u{30A6}\u{30A7}\u{30A8}\u{30A9}\u{30AA}-\u{30C2}\u{30C3}\u{30C4}-\u{30E2}\u{30E3}\u{30E4}\u{30E5}\u{30E6}\u{30E7}\u{30E8}-\u{30ED}\u{30EE}\u{30EF}-\u{30F4}\u{30F5}-\u{30F6}\u{30F7}-\u{30FA}\u{30FB}\u{30FD}-\u{30FE}\u{30FF}\u{3100}-\u{3104}\u{3105}-\u{3126}\u{3127}\u{3128}-\u{312F}\u{3130}\u{3131}-\u{318E}\u{318F}\u{3190}-\u{3191}\u{3192}-\u{3195}\u{3196}-\u{319F}\u{31A0}-\u{31BF}\u{31C0}-\u{31E3}\u{31E4}-\u{31EF}\u{31F0}-\u{31FF}\u{3200}-\u{321E}\u{321F}\u{3220}-\u{3229}\u{322A}-\u{3247}\u{3248}-\u{324F}\u{3250}\u{3251}-\u{325F}\u{3260}-\u{327F}\u{3280}-\u{3289}\u{328A}-\u{32B0}\u{32B1}-\u{32BF}\u{32C0}-\u{32FE}\u{32FF}\u{3300}-\u{3357}\u{3358}-\u{337A}\u{337B}-\u{337F}\u{3380}-\u{33FF}\u{3400}-\u{4DBF}\u{4DC0}-\u{4DFF}\u{4E00}-\u{9FFF}\u{A000}-\u{A014}\u{A015}\u{A016}-\u{A48C}\u{A48D}-\u{A48F}\u{A490}-\u{A4C6}\u{A4C7}-\u{A4CF}\u{A960}-\u{A97C}\u{A97D}-\u{A97F}\u{AC00}-\u{D7A3}\u{D7A4}-\u{D7AF}\u{D7B0}-\u{D7C6}\u{D7C7}-\u{D7CA}\u{D7CB}-\u{D7FB}\u{D7FC}-\u{D7FF}\u{E000}-\u{F8FF}\u{F900}-\u{FA6D}\u{FA6E}-\u{FA6F}\u{FA70}-\u{FAD9}\u{FADA}-\u{FAFF}\u{FE10}-\u{FE16}\u{FE17}\u{FE18}\u{FE19}\u{FE1A}-\u{FE1F}\u{FE30}\u{FE31}-\u{FE32}\u{FE33}-\u{FE34}\u{FE35}\u{FE36}\u{FE37}\u{FE38}\u{FE39}\u{FE3A}\u{FE3B}\u{FE3C}\u{FE3D}\u{FE3E}\u{FE3F}\u{FE40}\u{FE41}\u{FE42}\u{FE43}\u{FE44}\u{FE45}-\u{FE46}\u{FE47}\u{FE48}\u{FE50}-\u{FE52}\u{FE53}\u{FE54}-\u{FE57}\u{FE5F}-\u{FE61}\u{FE62}\u{FE67}\u{FE68}\u{FE69}\u{FE6A}-\u{FE6B}\u{FE6C}-\u{FE6F}\u{FF01}\u{FF02}-\u{FF03}\u{FF04}\u{FF05}-\u{FF07}\u{FF0A}\u{FF0B}\u{FF0C}\u{FF0E}\u{FF0F}\u{FF10}-\u{FF19}\u{FF1F}\u{FF20}\u{FF21}-\u{FF3A}\u{FF3C}\u{FF3E}\u{FF40}\u{FF41}-\u{FF5A}\u{FFE0}-\u{FFE1}\u{FFE2}\u{FFE4}\u{FFE5}-\u{FFE6}\u{FFE7}\u{FFF0}-\u{FFF8}\u{FFFC}-\u{FFFD}\u{10980}-\u{1099F}\u{11580}-\u{115AE}\u{115AF}-\u{115B1}\u{115B2}-\u{115B5}\u{115B6}-\u{115B7}\u{115B8}-\u{115BB}\u{115BC}-\u{115BD}\u{115BE}\u{115BF}-\u{115C0}\u{115C1}-\u{115D7}\u{115D8}-\u{115DB}\u{115DC}-\u{115DD}\u{115DE}-\u{115FF}\u{11A00}\u{11A01}-\u{11A0A}\u{11A0B}-\u{11A32}\u{11A33}-\u{11A38}\u{11A39}\u{11A3A}\u{11A3B}-\u{11A3E}\u{11A3F}-\u{11A46}\u{11A47}\u{11A48}-\u{11A4F}\u{11A50}\u{11A51}-\u{11A56}\u{11A57}-\u{11A58}\u{11A59}-\u{11A5B}\u{11A5C}-\u{11A89}\u{11A8A}-\u{11A96}\u{11A97}\u{11A98}-\u{11A99}\u{11A9A}-\u{11A9C}\u{11A9D}\u{11A9E}-\u{11AA2}\u{11AA3}-\u{11AAF}\u{11AB0}-\u{11ABF}\u{13000}-\u{1342E}\u{1342F}\u{13430}-\u{13438}\u{13439}-\u{1343F}\u{14400}-\u{14646}\u{14647}-\u{1467F}\u{16FE0}-\u{16FE1}\u{16FE2}\u{16FE3}\u{16FE4}\u{16FE5}-\u{16FEF}\u{16FF0}-\u{16FF1}\u{16FF2}-\u{16FFF}\u{17000}-\u{187F7}\u{187F8}-\u{187FF}\u{18800}-\u{18AFF}\u{18B00}-\u{18CD5}\u{18CD6}-\u{18CFF}\u{18D00}-\u{18D08}\u{18D09}-\u{18D7F}\u{1AFF0}-\u{1AFF3}\u{1AFF4}\u{1AFF5}-\u{1AFFB}\u{1AFFC}\u{1AFFD}-\u{1AFFE}\u{1AFFF}\u{1B000}-\u{1B0FF}\u{1B100}-\u{1B122}\u{1B123}-\u{1B12F}\u{1B130}-\u{1B14F}\u{1B150}-\u{1B152}\u{1B153}-\u{1B163}\u{1B164}-\u{1B167}\u{1B168}-\u{1B16F}\u{1B170}-\u{1B2FB}\u{1B2FC}-\u{1B2FF}\u{1CF00}-\u{1CF2D}\u{1CF2E}-\u{1CF2F}\u{1CF30}-\u{1CF46}\u{1CF47}-\u{1CF4F}\u{1CF50}-\u{1CFC3}\u{1CFC4}-\u{1CFCF}\u{1D000}-\u{1D0F5}\u{1D0F6}-\u{1D0FF}\u{1D100}-\u{1D126}\u{1D127}-\u{1D128}\u{1D129}-\u{1D164}\u{1D165}-\u{1D166}\u{1D167}-\u{1D169}\u{1D16A}-\u{1D16C}\u{1D16D}-\u{1D172}\u{1D173}-\u{1D17A}\u{1D17B}-\u{1D182}\u{1D183}-\u{1D184}\u{1D185}-\u{1D18B}\u{1D18C}-\u{1D1A9}\u{1D1AA}-\u{1D1AD}\u{1D1AE}-\u{1D1EA}\u{1D1EB}-\u{1D1FF}\u{1D2E0}-\u{1D2F3}\u{1D2F4}-\u{1D2FF}\u{1D300}-\u{1D356}\u{1D357}-\u{1D35F}\u{1D360}-\u{1D378}\u{1D379}-\u{1D37F}\u{1D800}-\u{1D9FF}\u{1DA00}-\u{1DA36}\u{1DA37}-\u{1DA3A}\u{1DA3B}-\u{1DA6C}\u{1DA6D}-\u{1DA74}\u{1DA75}\u{1DA76}-\u{1DA83}\u{1DA84}\u{1DA85}-\u{1DA86}\u{1DA87}-\u{1DA8B}\u{1DA8C}-\u{1DA9A}\u{1DA9B}-\u{1DA9F}\u{1DAA0}\u{1DAA1}-\u{1DAAF}\u{1F000}-\u{1F02B}\u{1F02C}-\u{1F02F}\u{1F030}-\u{1F093}\u{1F094}-\u{1F09F}\u{1F0A0}-\u{1F0AE}\u{1F0AF}-\u{1F0B0}\u{1F0B1}-\u{1F0BF}\u{1F0C0}\u{1F0C1}-\u{1F0CF}\u{1F0D0}\u{1F0D1}-\u{1F0F5}\u{1F0F6}-\u{1F0FF}\u{1F100}-\u{1F10C}\u{1F10D}-\u{1F1AD}\u{1F1AE}-\u{1F1E5}\u{1F1E6}-\u{1F1FF}\u{1F200}-\u{1F201}\u{1F202}\u{1F203}-\u{1F20F}\u{1F210}-\u{1F23B}\u{1F23C}-\u{1F23F}\u{1F240}-\u{1F248}\u{1F249}-\u{1F24F}\u{1F250}-\u{1F251}\u{1F252}-\u{1F25F}\u{1F260}-\u{1F265}\u{1F266}-\u{1F2FF}\u{1F300}-\u{1F3FA}\u{1F3FB}-\u{1F3FF}\u{1F400}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F650}-\u{1F67F}\u{1F680}-\u{1F6D7}\u{1F6D8}-\u{1F6DC}\u{1F6DD}-\u{1F6EC}\u{1F6ED}-\u{1F6EF}\u{1F6F0}-\u{1F6FC}\u{1F6FD}-\u{1F6FF}\u{1F700}-\u{1F773}\u{1F774}-\u{1F77F}\u{1F780}-\u{1F7D8}\u{1F7D9}-\u{1F7DF}\u{1F7E0}-\u{1F7EB}\u{1F7EC}-\u{1F7EF}\u{1F7F0}\u{1F7F1}-\u{1F7FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA53}\u{1FA54}-\u{1FA5F}\u{1FA60}-\u{1FA6D}\u{1FA6E}-\u{1FA6F}\u{1FA70}-\u{1FA74}\u{1FA75}-\u{1FA77}\u{1FA78}-\u{1FA7C}\u{1FA7D}-\u{1FA7F}\u{1FA80}-\u{1FA86}\u{1FA87}-\u{1FA8F}\u{1FA90}-\u{1FAAC}\u{1FAAD}-\u{1FAAF}\u{1FAB0}-\u{1FABA}\u{1FABB}-\u{1FABF}\u{1FAC0}-\u{1FAC5}\u{1FAC6}-\u{1FACF}\u{1FAD0}-\u{1FAD9}\u{1FADA}-\u{1FADF}\u{1FAE0}-\u{1FAE7}\u{1FAE8}-\u{1FAEF}\u{1FAF0}-\u{1FAF6}\u{1FAF7}-\u{1FAFF}\u{20000}-\u{2A6DF}\u{2A6E0}-\u{2A6FF}\u{2A700}-\u{2B738}\u{2B739}-\u{2B73F}\u{2B740}-\u{2B81D}\u{2B81E}-\u{2B81F}\u{2B820}-\u{2CEA1}\u{2CEA2}-\u{2CEAF}\u{2CEB0}-\u{2EBE0}\u{2EBE1}-\u{2F7FF}\u{2F800}-\u{2FA1D}\u{2FA1E}-\u{2FFFD}\u{30000}-\u{3134A}\u{3134B}-\u{3134F}\u{31350}-\u{3FFFD}]/u, Y = /[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/, U = /[\r\n]/;
|
|
103
|
+
class z {
|
|
104
|
+
constructor(t, u) {
|
|
105
|
+
this.content = t, this.parent = u, this.contentBox = new d(), this.glyphBox = new d();
|
|
106
|
+
}
|
|
107
|
+
get computedStyle() {
|
|
108
|
+
return this.parent.computedStyle;
|
|
109
|
+
}
|
|
110
|
+
get verticalOrientation() {
|
|
111
|
+
switch (this.computedStyle.textOrientation) {
|
|
112
|
+
case "upright":
|
|
113
|
+
return "U";
|
|
114
|
+
case "sideways-right":
|
|
115
|
+
case "sideways":
|
|
116
|
+
return "R";
|
|
117
|
+
case "mixed":
|
|
118
|
+
default:
|
|
119
|
+
return L.test(this.content) ? "U" : "R";
|
|
56
120
|
}
|
|
57
121
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
122
|
+
get isPunctuation() {
|
|
123
|
+
return Y.test(this.content);
|
|
124
|
+
}
|
|
125
|
+
get isEOL() {
|
|
126
|
+
return U.test(this.content);
|
|
127
|
+
}
|
|
128
|
+
measure() {
|
|
129
|
+
const t = this.computedStyle, {
|
|
130
|
+
width: u,
|
|
131
|
+
height: n,
|
|
132
|
+
glyphWidth: o,
|
|
133
|
+
glyphHeight: a
|
|
134
|
+
} = O(this.content, {
|
|
135
|
+
...t,
|
|
136
|
+
letterSpacing: 0
|
|
137
|
+
});
|
|
138
|
+
if (this.contentBox.width = u, this.contentBox.height = n, this.glyphBox.width = o, this.glyphBox.height = a, t.writingMode.startsWith("vertical"))
|
|
139
|
+
switch (this.verticalOrientation) {
|
|
140
|
+
case "R":
|
|
141
|
+
case "Tr":
|
|
142
|
+
this.contentBox.rotate90deg(), this.glyphBox.rotate90deg();
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
clone() {
|
|
148
|
+
const t = new z(this.content, this.parent);
|
|
149
|
+
return t.contentBox = this.contentBox.clone(), t.glyphBox = this.glyphBox.clone(), t;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
class W {
|
|
153
|
+
constructor(t, u, n) {
|
|
154
|
+
this.content = t, this.style = u, this.parent = n, this.contentBox = new d(), this.inlineBox = new d(), this.glyphBox = new d(), this.centerX = 0, this.baseline = 0, this.update();
|
|
155
|
+
}
|
|
156
|
+
update() {
|
|
157
|
+
var n;
|
|
158
|
+
this.computedStyle = {
|
|
159
|
+
...(n = this.parent) == null ? void 0 : n.computedStyle,
|
|
62
160
|
...this.style
|
|
63
161
|
};
|
|
162
|
+
const t = this.computedStyle;
|
|
163
|
+
this.computedContent = t.textTransform === "uppercase" ? this.content.toUpperCase() : t.textTransform === "lowercase" ? this.content.toLowerCase() : this.content;
|
|
164
|
+
const u = [];
|
|
165
|
+
for (const o of this.computedContent)
|
|
166
|
+
u.push(new z(o, this));
|
|
167
|
+
return this.characters = u, this;
|
|
168
|
+
}
|
|
169
|
+
measure() {
|
|
170
|
+
const t = this.computedStyle;
|
|
171
|
+
switch (t.writingMode) {
|
|
172
|
+
case "vertical-lr":
|
|
173
|
+
case "vertical-rl": {
|
|
174
|
+
let u = 0, n = 0, o = 0;
|
|
175
|
+
this.characters.forEach((a, h) => {
|
|
176
|
+
a.measure(), n = Math.max(n, a.contentBox.width), o = Math.max(o, a.glyphBox.width), u += a.contentBox.height, h !== this.characters.length - 1 && (u += t.letterSpacing);
|
|
177
|
+
}), this.contentBox.width = n, this.contentBox.height = u, this.glyphBox.width = o, this.glyphBox.height = u, this.inlineBox.width = t.fontSize * t.lineHeight, this.inlineBox.height = u;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "horizontal-tb": {
|
|
181
|
+
const {
|
|
182
|
+
width: u,
|
|
183
|
+
height: n,
|
|
184
|
+
lineHeight: o,
|
|
185
|
+
glyphAscent: a,
|
|
186
|
+
glyphWidth: h,
|
|
187
|
+
glyphHeight: E,
|
|
188
|
+
baseline: B,
|
|
189
|
+
centerX: f
|
|
190
|
+
} = O(this.computedContent, t);
|
|
191
|
+
this.inlineBox.width = u, this.inlineBox.height = o, this.contentBox.width = u, this.contentBox.height = n, this.glyphBox.width = h, this.glyphBox.height = E, this.baseline = B, this.inlineBox.x = 0, this.inlineBox.y = 0, this.contentBox.x = 0, this.contentBox.y = (this.inlineBox.height - this.contentBox.height) / 2, this.glyphBox.x = 0, this.glyphBox.y = B - a, this.centerX = f;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return this;
|
|
64
196
|
}
|
|
65
197
|
clone(t) {
|
|
66
|
-
return new
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
inlineBox: this.inlineBox.clone(),
|
|
72
|
-
glyphBox: this.glyphBox.clone(),
|
|
73
|
-
centerX: this.centerX,
|
|
74
|
-
baseline: this.baseline,
|
|
75
|
-
...t
|
|
76
|
-
});
|
|
198
|
+
return new W(
|
|
199
|
+
t ?? this.content,
|
|
200
|
+
this.style,
|
|
201
|
+
this.parent
|
|
202
|
+
);
|
|
77
203
|
}
|
|
78
204
|
}
|
|
79
|
-
class
|
|
80
|
-
constructor({
|
|
81
|
-
style
|
|
82
|
-
parent: o,
|
|
83
|
-
contentBox: h = new u(),
|
|
84
|
-
lineBox: l = new u(),
|
|
85
|
-
glyphBox: a = new u(),
|
|
86
|
-
baseline: x = 0,
|
|
87
|
-
xHeight: B = 0,
|
|
88
|
-
maxCharWidth: w = 0,
|
|
89
|
-
fragments: m = []
|
|
90
|
-
} = {}) {
|
|
91
|
-
this.style = t, this.parent = o, this.contentBox = h, this.lineBox = l, this.glyphBox = a, this.baseline = x, this.xHeight = B, this.maxCharWidth = w, this.fragments = m;
|
|
92
|
-
}
|
|
93
|
-
addFragment(t) {
|
|
94
|
-
return this.fragments.push(new $({ ...t, parent: this })), this;
|
|
205
|
+
class v {
|
|
206
|
+
constructor(t, u) {
|
|
207
|
+
this.style = t, this.parent = u, this.contentBox = new d(), this.lineBox = new d(), this.glyphBox = new d(), this.baseline = 0, this.xHeight = 0, this.fragments = [], this.update();
|
|
95
208
|
}
|
|
96
|
-
|
|
97
|
-
|
|
209
|
+
update() {
|
|
210
|
+
this.computedStyle = {
|
|
98
211
|
...this.parent,
|
|
99
212
|
...this.style
|
|
100
213
|
};
|
|
101
214
|
}
|
|
215
|
+
addFragment(t, u) {
|
|
216
|
+
return this.fragments.push(new W(t, u, this)), this;
|
|
217
|
+
}
|
|
102
218
|
clone(t) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
parent: this.parent,
|
|
106
|
-
contentBox: this.contentBox.clone(),
|
|
107
|
-
lineBox: this.lineBox.clone(),
|
|
108
|
-
glyphBox: this.glyphBox.clone(),
|
|
109
|
-
baseline: this.baseline,
|
|
110
|
-
xHeight: this.xHeight,
|
|
111
|
-
maxCharWidth: this.maxCharWidth,
|
|
112
|
-
fragments: this.fragments.map((o) => o.clone()),
|
|
113
|
-
...t
|
|
114
|
-
});
|
|
219
|
+
const u = new v();
|
|
220
|
+
return u.style = this.style, u.parent = this.parent, u.contentBox = this.contentBox.clone(), u.lineBox = this.lineBox.clone(), u.glyphBox = this.glyphBox.clone(), u.baseline = this.baseline, u.xHeight = this.xHeight, u.fragments = t ?? this.fragments.map((n) => n.clone()), u.computedStyle = this.computedStyle, u;
|
|
115
221
|
}
|
|
116
222
|
}
|
|
117
|
-
function
|
|
118
|
-
const
|
|
223
|
+
function K(r, t) {
|
|
224
|
+
const u = [];
|
|
119
225
|
if (typeof r == "string")
|
|
120
|
-
|
|
226
|
+
u.push(new v(void 0, t).addFragment(r));
|
|
121
227
|
else {
|
|
122
228
|
r = Array.isArray(r) ? r : [r];
|
|
123
|
-
for (const
|
|
124
|
-
if (typeof
|
|
125
|
-
|
|
126
|
-
else if (Array.isArray(
|
|
127
|
-
const
|
|
128
|
-
|
|
229
|
+
for (const n of r)
|
|
230
|
+
if (typeof n == "string")
|
|
231
|
+
u.push(new v(void 0, t).addFragment(n));
|
|
232
|
+
else if (Array.isArray(n)) {
|
|
233
|
+
const o = new v(void 0, t);
|
|
234
|
+
n.forEach((a) => {
|
|
129
235
|
if (typeof a == "string")
|
|
130
|
-
|
|
236
|
+
o.addFragment(a);
|
|
131
237
|
else {
|
|
132
|
-
const { content:
|
|
133
|
-
|
|
238
|
+
const { content: h, ...E } = a;
|
|
239
|
+
o.addFragment(h, E);
|
|
134
240
|
}
|
|
135
|
-
}),
|
|
136
|
-
} else if ("fragments" in
|
|
137
|
-
const { fragments:
|
|
138
|
-
|
|
139
|
-
const { content:
|
|
140
|
-
|
|
141
|
-
}),
|
|
142
|
-
} else if ("content" in
|
|
143
|
-
const { content:
|
|
144
|
-
|
|
241
|
+
}), u.push(o);
|
|
242
|
+
} else if ("fragments" in n) {
|
|
243
|
+
const { fragments: o, ...a } = n, h = new v(a, t);
|
|
244
|
+
o.forEach((E) => {
|
|
245
|
+
const { content: B, ...f } = E;
|
|
246
|
+
h.addFragment(B, f);
|
|
247
|
+
}), u.push(h);
|
|
248
|
+
} else if ("content" in n) {
|
|
249
|
+
const { content: o, ...a } = n;
|
|
250
|
+
u.push(new v(a, t).addFragment(o));
|
|
145
251
|
}
|
|
146
252
|
}
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
const K = "OffscreenCanvas" in globalThis;
|
|
150
|
-
let U;
|
|
151
|
-
function j() {
|
|
152
|
-
return U ?? (U = K ? new OffscreenCanvas(1, 1) : document.createElement("canvas"));
|
|
253
|
+
return u;
|
|
153
254
|
}
|
|
154
|
-
function
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
case "top":
|
|
160
|
-
case "middle":
|
|
161
|
-
case "bottom":
|
|
162
|
-
r.textBaseline = t.verticalAlign;
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
t.letterSpacing !== void 0 && (r.letterSpacing = `${t.letterSpacing}px`), (t.fontStyle || t.fontWeight !== void 0 || t.fontSize !== void 0 || t.fontFamily) && (r.font = [
|
|
166
|
-
t.fontStyle || "normal",
|
|
167
|
-
t.fontWeight || "normal",
|
|
168
|
-
`${t.fontSize || 14}px`,
|
|
169
|
-
t.fontFamily || "sans-serif"
|
|
170
|
-
].join(" "));
|
|
171
|
-
}
|
|
172
|
-
function z(r, t) {
|
|
173
|
-
const o = j().getContext("2d");
|
|
174
|
-
return Y(o, t), o.measureText(r);
|
|
175
|
-
}
|
|
176
|
-
const I = /[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;
|
|
177
|
-
function V(r, t, o) {
|
|
178
|
-
const h = [], l = r.slice();
|
|
179
|
-
let a, x;
|
|
180
|
-
for (; a = l.shift(); ) {
|
|
255
|
+
function N(r, t, u) {
|
|
256
|
+
var E;
|
|
257
|
+
const n = [], o = r.slice();
|
|
258
|
+
let a, h;
|
|
259
|
+
for (; a = o.shift(); ) {
|
|
181
260
|
const B = a.fragments.slice();
|
|
182
|
-
let
|
|
183
|
-
const
|
|
184
|
-
for (;
|
|
185
|
-
const
|
|
186
|
-
let
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
z(i, { ...b, letterSpacing: 0 }).width
|
|
191
|
-
), e += i, I.test(x.content[++v]))
|
|
261
|
+
let f = 0;
|
|
262
|
+
const A = [];
|
|
263
|
+
for (; h = B.shift(); ) {
|
|
264
|
+
const p = h.computedStyle;
|
|
265
|
+
let i = "", w = !1, S = 0;
|
|
266
|
+
const e = new W("", h.style, h.parent);
|
|
267
|
+
for (const F of h.characters) {
|
|
268
|
+
if (e.content += F.content, (E = h.characters[++S]) != null && E.isPunctuation)
|
|
192
269
|
continue;
|
|
193
|
-
|
|
194
|
-
|
|
270
|
+
const D = F.isEOL;
|
|
271
|
+
let x, c;
|
|
272
|
+
switch (p.writingMode) {
|
|
195
273
|
case "vertical-lr":
|
|
196
274
|
case "vertical-rl":
|
|
197
|
-
|
|
275
|
+
x = u, c = e.update().measure().contentBox.height;
|
|
198
276
|
break;
|
|
199
277
|
case "horizontal-tb":
|
|
200
278
|
default:
|
|
201
|
-
|
|
279
|
+
x = t, c = e.update().measure().contentBox.width;
|
|
202
280
|
break;
|
|
203
281
|
}
|
|
204
|
-
c
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
a.clone(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
),
|
|
213
|
-
const n = x.content.substring(g);
|
|
214
|
-
(n.length || B.length) && l.unshift(
|
|
215
|
-
a.clone({
|
|
216
|
-
maxCharWidth: 0,
|
|
217
|
-
fragments: (n.length ? [x.clone({ content: n })] : []).concat(B.slice())
|
|
218
|
-
})
|
|
219
|
-
), B.length = 0, s = !0;
|
|
282
|
+
if (D || x && f + c > x) {
|
|
283
|
+
let l = D ? i.length + 1 : i.length;
|
|
284
|
+
!f && !l && (i += e.content, l += e.content.length), i.length && A.push(h.clone(i)), A.length && (n.push(a.clone(A.slice())), A.length = 0);
|
|
285
|
+
const g = h.content.substring(l);
|
|
286
|
+
(g.length || B.length) && o.unshift(
|
|
287
|
+
a.clone(
|
|
288
|
+
(g.length ? [h.clone(g)] : []).concat(B.slice())
|
|
289
|
+
)
|
|
290
|
+
), B.length = 0, w = !0;
|
|
220
291
|
break;
|
|
221
292
|
} else
|
|
222
|
-
|
|
223
|
-
|
|
293
|
+
f += c;
|
|
294
|
+
i += e.content, e.content = "";
|
|
224
295
|
}
|
|
225
|
-
|
|
296
|
+
w || A.push(h.clone());
|
|
226
297
|
}
|
|
227
|
-
|
|
298
|
+
A.length && n.push(a.clone(A));
|
|
228
299
|
}
|
|
229
|
-
return
|
|
300
|
+
return n;
|
|
230
301
|
}
|
|
231
|
-
function
|
|
302
|
+
function G(r) {
|
|
232
303
|
return {
|
|
233
304
|
width: 0,
|
|
234
305
|
height: 0,
|
|
235
|
-
color:
|
|
306
|
+
color: "#000",
|
|
236
307
|
backgroundColor: null,
|
|
237
308
|
fontSize: 14,
|
|
238
309
|
fontWeight: "normal",
|
|
@@ -245,7 +316,7 @@ function q(r) {
|
|
|
245
316
|
textTransform: "none",
|
|
246
317
|
textDecoration: null,
|
|
247
318
|
textStrokeWidth: 0,
|
|
248
|
-
textStrokeColor:
|
|
319
|
+
textStrokeColor: "#000",
|
|
249
320
|
lineHeight: 1,
|
|
250
321
|
letterSpacing: 0,
|
|
251
322
|
shadowColor: null,
|
|
@@ -253,225 +324,232 @@ function q(r) {
|
|
|
253
324
|
shadowOffsetY: 0,
|
|
254
325
|
shadowBlur: 0,
|
|
255
326
|
writingMode: "horizontal-tb",
|
|
327
|
+
textOrientation: "mixed",
|
|
256
328
|
...r
|
|
257
329
|
};
|
|
258
330
|
}
|
|
259
|
-
function
|
|
260
|
-
const { content: t } = r, { width:
|
|
261
|
-
let
|
|
262
|
-
|
|
263
|
-
let
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
331
|
+
function I(r) {
|
|
332
|
+
const { content: t, effects: u = [{}] } = r, { width: n, height: o, ...a } = G(r.style);
|
|
333
|
+
let h = K(t, a);
|
|
334
|
+
h = N(h, n, o);
|
|
335
|
+
let E = 0, B = 0;
|
|
336
|
+
h.forEach((e) => {
|
|
337
|
+
let F = null;
|
|
338
|
+
e.fragments.forEach((s) => {
|
|
339
|
+
s.update().measure(), (!F || F.contentBox.height < s.contentBox.height) && (F = s);
|
|
340
|
+
});
|
|
341
|
+
const {
|
|
342
|
+
typoHeight: D,
|
|
343
|
+
typoAscent: x,
|
|
344
|
+
lineHeight: c
|
|
345
|
+
} = O("x", (F ?? e).computedStyle);
|
|
346
|
+
e.xHeight = D, e.baseline = B + (c - D) / 2 + x;
|
|
347
|
+
let l = E, g = B, m = 0;
|
|
348
|
+
e.fragments.forEach((s, C) => {
|
|
349
|
+
const y = s.computedStyle;
|
|
350
|
+
switch (y.writingMode) {
|
|
270
351
|
case "vertical-rl":
|
|
271
352
|
case "vertical-lr": {
|
|
272
|
-
|
|
273
|
-
k
|
|
274
|
-
|
|
275
|
-
|
|
353
|
+
C || (g = 0), s.inlineBox.translate(l, g), s.contentBox.translate(l, g), s.glyphBox.translate(l, g), s.baseline += g, s.centerX += l;
|
|
354
|
+
let k = g;
|
|
355
|
+
s.characters.forEach((b, R) => {
|
|
356
|
+
b.contentBox.x = l + (s.inlineBox.width - b.contentBox.width) / 2, b.contentBox.y = k, b.glyphBox.x = l + (s.inlineBox.width - b.glyphBox.width) / 2, b.glyphBox.y = k, k += b.contentBox.height, R !== s.characters.length - 1 && (k += y.letterSpacing);
|
|
357
|
+
}), g += s.inlineBox.height, C === e.fragments.length - 1 && (l += s.inlineBox.width);
|
|
276
358
|
break;
|
|
277
359
|
}
|
|
278
360
|
case "horizontal-tb": {
|
|
279
|
-
|
|
280
|
-
const {
|
|
281
|
-
fontBoundingBoxAscent: p,
|
|
282
|
-
fontBoundingBoxDescent: C,
|
|
283
|
-
actualBoundingBoxAscent: A,
|
|
284
|
-
actualBoundingBoxDescent: W,
|
|
285
|
-
actualBoundingBoxLeft: O,
|
|
286
|
-
actualBoundingBoxRight: D,
|
|
287
|
-
width: H
|
|
288
|
-
} = z(n.content, {
|
|
289
|
-
...d,
|
|
290
|
-
textAlign: "center",
|
|
291
|
-
verticalAlign: "baseline"
|
|
292
|
-
}), F = d.fontSize, T = F * d.lineHeight, P = p + C, L = A + W, N = O + D, R = f + (T - P) / 2 + p;
|
|
293
|
-
n.contentBox.x = c, n.contentBox.y = f + (T - F) / 2, n.contentBox.width = H, n.contentBox.height = F, n.inlineBox.x = c, n.inlineBox.y = f, n.inlineBox.width = H, n.inlineBox.height = T, n.glyphBox.x = c, n.glyphBox.y = R - A, n.glyphBox.width = N, n.glyphBox.height = L, n.baseline = R, n.centerX = c + O, i.push(n.contentBox), e.contentBox = u.from(...i), e.contentBox.height < n.contentBox.height && (S = n), c += H;
|
|
361
|
+
C || (l = 0), s.inlineBox.translate(l, g), s.contentBox.translate(l, g), s.glyphBox.translate(l, g), s.baseline += g, s.centerX += l, l += s.inlineBox.width, m = Math.max(m, s.inlineBox.height), C === e.fragments.length - 1 && (g += m);
|
|
294
362
|
break;
|
|
295
363
|
}
|
|
296
364
|
}
|
|
297
|
-
}), e.lineBox =
|
|
298
|
-
const g = z("x", {
|
|
299
|
-
...(S ?? e).getComputedStyle(),
|
|
300
|
-
textAlign: "left",
|
|
301
|
-
verticalAlign: "baseline"
|
|
302
|
-
});
|
|
303
|
-
e.xHeight = g.actualBoundingBoxAscent, e.baseline = e.lineBox.y + (e.lineBox.height - (g.fontBoundingBoxAscent + g.fontBoundingBoxDescent)) / 2 + g.fontBoundingBoxAscent;
|
|
365
|
+
}), E = l, B = g, e.lineBox = d.from(...e.fragments.map((s) => s.inlineBox));
|
|
304
366
|
});
|
|
305
|
-
const
|
|
306
|
-
...
|
|
307
|
-
new
|
|
308
|
-
), { width:
|
|
309
|
-
|
|
310
|
-
e.contentBox =
|
|
311
|
-
const
|
|
312
|
-
let
|
|
313
|
-
switch (
|
|
367
|
+
const f = d.from(
|
|
368
|
+
...h.map((e) => e.lineBox),
|
|
369
|
+
new d(0, 0, n, o)
|
|
370
|
+
), { width: A, height: p } = f;
|
|
371
|
+
h.forEach((e) => {
|
|
372
|
+
e.lineBox.width = Math.max(e.lineBox.width, A), e.contentBox = d.from(...e.fragments.map((F) => F.contentBox)), e.glyphBox = d.from(...e.fragments.map((F) => F.glyphBox)), e.fragments.forEach((F) => {
|
|
373
|
+
const D = F.computedStyle;
|
|
374
|
+
let x = 0, c = 0;
|
|
375
|
+
switch (D.writingMode) {
|
|
314
376
|
case "vertical-rl":
|
|
315
377
|
case "vertical-lr":
|
|
316
|
-
switch (
|
|
378
|
+
switch (D.textAlign) {
|
|
317
379
|
case "end":
|
|
318
380
|
case "right":
|
|
319
|
-
|
|
381
|
+
c = p - e.contentBox.height;
|
|
320
382
|
break;
|
|
321
383
|
case "center":
|
|
322
|
-
|
|
384
|
+
c = (p - e.contentBox.height) / 2;
|
|
323
385
|
break;
|
|
324
386
|
}
|
|
325
387
|
break;
|
|
326
388
|
case "horizontal-tb": {
|
|
327
|
-
switch (
|
|
389
|
+
switch (D.textAlign) {
|
|
328
390
|
case "end":
|
|
329
391
|
case "right":
|
|
330
|
-
|
|
392
|
+
x = A - e.contentBox.width;
|
|
331
393
|
break;
|
|
332
394
|
case "center":
|
|
333
|
-
|
|
395
|
+
x = (A - e.contentBox.width) / 2;
|
|
334
396
|
break;
|
|
335
397
|
}
|
|
336
|
-
switch (
|
|
398
|
+
switch (D.verticalAlign) {
|
|
337
399
|
case "top":
|
|
338
|
-
|
|
400
|
+
c = e.lineBox.y - F.inlineBox.y;
|
|
339
401
|
break;
|
|
340
402
|
case "middle":
|
|
341
|
-
|
|
403
|
+
c = F.inlineBox.y - (e.baseline - e.xHeight / 2 - F.inlineBox.height / 2);
|
|
342
404
|
break;
|
|
343
405
|
case "bottom":
|
|
344
|
-
|
|
406
|
+
c = e.lineBox.bottom - F.inlineBox.bottom;
|
|
345
407
|
break;
|
|
346
408
|
case "sub":
|
|
347
|
-
|
|
409
|
+
c = e.baseline - F.glyphBox.bottom;
|
|
348
410
|
break;
|
|
349
411
|
case "super":
|
|
350
|
-
|
|
412
|
+
c = e.baseline - F.glyphBox.y;
|
|
351
413
|
break;
|
|
352
414
|
case "text-top":
|
|
353
|
-
|
|
415
|
+
c = e.glyphBox.y - F.inlineBox.y;
|
|
354
416
|
break;
|
|
355
417
|
case "text-bottom":
|
|
356
|
-
|
|
418
|
+
c = e.glyphBox.bottom - F.inlineBox.bottom;
|
|
357
419
|
break;
|
|
358
420
|
case "baseline":
|
|
359
421
|
default:
|
|
360
|
-
|
|
422
|
+
F.inlineBox.height < e.lineBox.height && (c = e.baseline - F.baseline);
|
|
361
423
|
break;
|
|
362
424
|
}
|
|
363
425
|
break;
|
|
364
426
|
}
|
|
365
427
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}), e.contentBox = u.from(...e.fragments.map((i) => i.contentBox)), e.glyphBox = u.from(...e.fragments.map((i) => i.glyphBox));
|
|
428
|
+
F.inlineBox.translate(x, c), F.contentBox.translate(x, c), F.glyphBox.translate(x, c), F.baseline += c, F.centerX += x;
|
|
429
|
+
}), e.contentBox = d.from(...e.fragments.map((F) => F.contentBox)), e.glyphBox = d.from(...e.fragments.map((F) => F.glyphBox));
|
|
369
430
|
});
|
|
370
|
-
const
|
|
371
|
-
return {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
431
|
+
const i = d.from(...h.map((e) => e.contentBox)), w = d.from(...h.map((e) => e.glyphBox)), S = [];
|
|
432
|
+
return h.forEach((e) => {
|
|
433
|
+
e.fragments.forEach((F) => {
|
|
434
|
+
const D = F.computedStyle;
|
|
435
|
+
u.forEach((x) => {
|
|
436
|
+
const c = { ...D, ...x }, { textStrokeWidth: l = 0, offsetX: g = 0, offsetY: m = 0 } = c;
|
|
437
|
+
if (l || g || m) {
|
|
438
|
+
const { x: s, y: C, width: y, height: k } = F.contentBox;
|
|
439
|
+
S.push(new d(
|
|
440
|
+
Math.min(s, s + g - l / 2),
|
|
441
|
+
Math.min(C, C + m - l / 2),
|
|
442
|
+
Math.max(y, y + g + l),
|
|
443
|
+
Math.max(k, k + m + l)
|
|
444
|
+
));
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
}), {
|
|
449
|
+
box: f,
|
|
450
|
+
contentBox: i,
|
|
451
|
+
glyphBox: w,
|
|
452
|
+
paragraphs: h,
|
|
453
|
+
viewBox: d.from(f, w, ...S)
|
|
377
454
|
};
|
|
378
455
|
}
|
|
379
|
-
function
|
|
456
|
+
function T(r, t, u) {
|
|
380
457
|
if (typeof t == "string" && t.startsWith("linear-gradient")) {
|
|
381
|
-
const { x0:
|
|
382
|
-
return
|
|
458
|
+
const { x0: n, y0: o, x1: a, y1: h, stops: E } = j(t, u.left, u.top, u.width, u.height), B = r.createLinearGradient(n, o, a, h);
|
|
459
|
+
return E.forEach((f) => B.addColorStop(f.offset, f.color)), B;
|
|
383
460
|
}
|
|
384
461
|
return t;
|
|
385
462
|
}
|
|
386
|
-
function
|
|
387
|
-
var
|
|
388
|
-
const a = ((
|
|
463
|
+
function j(r, t, u, n, o) {
|
|
464
|
+
var w;
|
|
465
|
+
const a = ((w = r.match(/linear-gradient\((.+)\)$/)) == null ? void 0 : w[1]) ?? "", h = a.split(",")[0], E = h.includes("deg") ? h : "0deg", B = a.replace(E, "").matchAll(/(#|rgba|rgb)(.+?) ([\d.]+?%)/gi), A = (Number(E.replace("deg", "")) || 0) * Math.PI / 180, p = n * Math.sin(A), i = o * Math.cos(A);
|
|
389
466
|
return {
|
|
390
|
-
x0: t +
|
|
391
|
-
y0:
|
|
392
|
-
x1: t +
|
|
393
|
-
y1:
|
|
394
|
-
stops: Array.from(
|
|
395
|
-
let
|
|
396
|
-
return
|
|
397
|
-
offset: Number(
|
|
398
|
-
color:
|
|
467
|
+
x0: t + n / 2 - p,
|
|
468
|
+
y0: u + o / 2 + i,
|
|
469
|
+
x1: t + n / 2 + p,
|
|
470
|
+
y1: u + o / 2 - i,
|
|
471
|
+
stops: Array.from(B).map((S) => {
|
|
472
|
+
let e = S[2];
|
|
473
|
+
return e.startsWith("(") ? e = e.split(",").length > 3 ? `rgba${e}` : `rgb${e}` : e = `#${e}`, {
|
|
474
|
+
offset: Number(S[3].replace("%", "")) / 100,
|
|
475
|
+
color: e
|
|
399
476
|
};
|
|
400
477
|
})
|
|
401
478
|
};
|
|
402
479
|
}
|
|
403
|
-
function
|
|
404
|
-
|
|
480
|
+
function M(r, t, u) {
|
|
481
|
+
u != null && u.color && (u.color = T(r, u.color, t)), u != null && u.backgroundColor && (u.backgroundColor = T(r, u.backgroundColor, t)), u != null && u.textStrokeColor && (u.textStrokeColor = T(r, u.textStrokeColor, t));
|
|
405
482
|
}
|
|
406
|
-
function
|
|
483
|
+
function V(r) {
|
|
407
484
|
const {
|
|
408
485
|
view: t = document.createElement("canvas"),
|
|
409
|
-
style:
|
|
410
|
-
|
|
411
|
-
pixelRatio:
|
|
412
|
-
} = r, a =
|
|
413
|
-
t.style.width = `${
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
486
|
+
style: u,
|
|
487
|
+
effects: n = [],
|
|
488
|
+
pixelRatio: o = 1
|
|
489
|
+
} = r, a = n.length > 0 ? n : [{}], { viewBox: h, paragraphs: E } = I(r), { x: B, y: f, width: A, height: p } = h, i = t.getContext("2d");
|
|
490
|
+
t.style.width = `${A}px`, t.style.height = `${p}px`, t.dataset.viewbox = `${B} ${f} ${A} ${p}`, t.dataset.pixelRatio = String(o), t.width = Math.max(1, Math.floor(A * o)), t.height = Math.max(1, Math.floor(p * o)), i.scale(o, o), i.clearRect(0, 0, t.width, t.height);
|
|
491
|
+
const w = (e, F, D, x, c) => {
|
|
492
|
+
i.fillStyle = e, i.fillRect(-h.x + F, -h.y + D, x, c);
|
|
493
|
+
}, S = { ...u };
|
|
494
|
+
return M(i, new d(0, 0, A, p), S), E.forEach((e) => {
|
|
495
|
+
M(i, e.contentBox, e.computedStyle), e.fragments.forEach((F) => {
|
|
496
|
+
M(i, F.contentBox, F.computedStyle);
|
|
418
497
|
});
|
|
419
498
|
}), a.forEach((e) => {
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
var
|
|
425
|
-
(
|
|
426
|
-
var
|
|
427
|
-
(
|
|
499
|
+
const F = { ...e };
|
|
500
|
+
M(i, new d(0, 0, A, p), F);
|
|
501
|
+
const D = { ...S, ...F };
|
|
502
|
+
D != null && D.backgroundColor && w(D.backgroundColor, 0, 0, t.width, t.height), E.forEach((x) => {
|
|
503
|
+
var c;
|
|
504
|
+
(c = x.style) != null && c.backgroundColor && w(x.style.backgroundColor, ...x.lineBox.toArray()), x.fragments.forEach((l) => {
|
|
505
|
+
var g;
|
|
506
|
+
(g = l.style) != null && g.backgroundColor && w(l.style.backgroundColor, ...l.inlineBox.toArray());
|
|
428
507
|
});
|
|
429
|
-
}),
|
|
430
|
-
|
|
431
|
-
const g = { ...
|
|
432
|
-
|
|
433
|
-
...
|
|
508
|
+
}), E.forEach((x) => {
|
|
509
|
+
x.fragments.forEach((c) => {
|
|
510
|
+
const l = -h.x + (F.offsetX ?? 0), g = -h.y + (F.offsetY ?? 0), m = { ...c.computedStyle, ...F };
|
|
511
|
+
switch (H(i, {
|
|
512
|
+
...m,
|
|
434
513
|
textAlign: "left",
|
|
435
|
-
verticalAlign: "baseline"
|
|
436
|
-
})
|
|
437
|
-
const { width: n, height: k } = f.contentBox;
|
|
438
|
-
let d = -x.x, p = -x.y;
|
|
439
|
-
i.offsetX && (d += i.offsetX), i.offsetY && (p += i.offsetY);
|
|
440
|
-
let C = p;
|
|
441
|
-
switch (g.writingMode) {
|
|
442
|
-
case "vertical-rl":
|
|
443
|
-
case "vertical-lr":
|
|
444
|
-
d += f.contentBox.x, p += (g.fontSize - c.xHeight) / 2 + c.xHeight + 1;
|
|
445
|
-
break;
|
|
446
|
-
case "horizontal-tb":
|
|
447
|
-
d += f.contentBox.x, p += f.contentBox.y, C += f.baseline;
|
|
448
|
-
break;
|
|
449
|
-
}
|
|
450
|
-
switch (g.writingMode) {
|
|
514
|
+
verticalAlign: m.writingMode === "horizontal-tb" ? "baseline" : "top"
|
|
515
|
+
}), m.writingMode) {
|
|
451
516
|
case "vertical-rl":
|
|
452
517
|
case "vertical-lr": {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
518
|
+
c.characters.forEach((s) => {
|
|
519
|
+
let { x: C, y } = s.contentBox;
|
|
520
|
+
switch (C += l, y += g, s.verticalOrientation) {
|
|
521
|
+
case "R":
|
|
522
|
+
case "Tr": {
|
|
523
|
+
i.translate(C + s.contentBox.width, y), i.rotate(Math.PI / 2), i.fillText(s.content, 0, 0), m.textStrokeWidth && i.strokeText(s.content, 0, 0), i.setTransform(1, 0, 0, 1, 0, 0);
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
default:
|
|
527
|
+
i.fillText(s.content, C, y), m.textStrokeWidth && i.strokeText(s.content, C, y);
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
});
|
|
456
531
|
break;
|
|
457
532
|
}
|
|
458
|
-
case "horizontal-tb":
|
|
459
|
-
s.
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
533
|
+
case "horizontal-tb": {
|
|
534
|
+
const s = l + c.contentBox.x, C = g + c.contentBox.y, y = g + c.baseline;
|
|
535
|
+
i.fillText(c.content, s, y), m.textStrokeWidth && i.strokeText(c.content, s, y);
|
|
536
|
+
const { width: k, height: b } = c.contentBox;
|
|
537
|
+
switch (m.textDecoration) {
|
|
538
|
+
case "underline":
|
|
539
|
+
i.strokeStyle = i.fillStyle, i.lineWidth = m.fontSize / 15, i.beginPath(), i.moveTo(s, C + b), i.lineTo(s + k, C + b), i.stroke();
|
|
540
|
+
break;
|
|
541
|
+
case "line-through":
|
|
542
|
+
i.strokeStyle = i.fillStyle, i.lineWidth = m.fontSize / 15, i.beginPath(), i.moveTo(s, C + b / 2), i.lineTo(s + k, C + b / 2), i.stroke();
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
468
545
|
break;
|
|
546
|
+
}
|
|
469
547
|
}
|
|
470
548
|
});
|
|
471
549
|
});
|
|
472
550
|
}), t;
|
|
473
551
|
}
|
|
474
552
|
export {
|
|
475
|
-
|
|
476
|
-
|
|
553
|
+
I as measureText,
|
|
554
|
+
V as renderText
|
|
477
555
|
};
|
package/package.json
CHANGED
package/types/bounding-box.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
export interface BoundingBoxOptions {
|
|
2
|
-
x?: number;
|
|
3
|
-
y?: number;
|
|
4
|
-
width?: number;
|
|
5
|
-
height?: number;
|
|
6
|
-
}
|
|
7
1
|
export declare class BoundingBox {
|
|
8
2
|
x: number;
|
|
9
3
|
y: number;
|
|
@@ -13,8 +7,10 @@ export declare class BoundingBox {
|
|
|
13
7
|
get top(): number;
|
|
14
8
|
get right(): number;
|
|
15
9
|
get bottom(): number;
|
|
16
|
-
constructor(
|
|
10
|
+
constructor(x?: number, y?: number, width?: number, height?: number);
|
|
17
11
|
static from(...boxes: Array<BoundingBox>): BoundingBox;
|
|
18
|
-
|
|
12
|
+
rotate90deg(): void;
|
|
13
|
+
translate(tx: number, ty: number): this;
|
|
19
14
|
clone(): BoundingBox;
|
|
15
|
+
toArray(): [number, number, number, number];
|
|
20
16
|
}
|
package/types/canvas.d.ts
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import type { TextStyle } from './types';
|
|
2
2
|
export declare function getCurrentCanvas(): OffscreenCanvas | HTMLCanvasElement;
|
|
3
3
|
export declare function setContextStyle(ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D, style: Partial<TextStyle>): void;
|
|
4
|
-
export declare function canvasMeasureText(text: string, style: TextStyle):
|
|
4
|
+
export declare function canvasMeasureText(text: string, style: TextStyle): {
|
|
5
|
+
typoAscent: number;
|
|
6
|
+
typoDescent: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
typoHeight: number;
|
|
10
|
+
lineHeight: number;
|
|
11
|
+
leading: number;
|
|
12
|
+
glyphLeft: number;
|
|
13
|
+
glyphRight: number;
|
|
14
|
+
glyphAscent: number;
|
|
15
|
+
glyphDescent: number;
|
|
16
|
+
glyphWidth: number;
|
|
17
|
+
glyphHeight: number;
|
|
18
|
+
baseline: number;
|
|
19
|
+
centerX: number;
|
|
20
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BoundingBox } from './bounding-box';
|
|
2
|
+
import type { Fragment } from './fragment';
|
|
3
|
+
export type VerticalOrientation = 'U' | 'R' | 'Tu' | 'Tr';
|
|
4
|
+
export declare class Character {
|
|
5
|
+
content: string;
|
|
6
|
+
parent: Fragment;
|
|
7
|
+
contentBox: BoundingBox;
|
|
8
|
+
glyphBox: BoundingBox;
|
|
9
|
+
get computedStyle(): import("./types").TextStyle;
|
|
10
|
+
get verticalOrientation(): VerticalOrientation;
|
|
11
|
+
get isPunctuation(): boolean;
|
|
12
|
+
get isEOL(): boolean;
|
|
13
|
+
constructor(content: string, parent: Fragment);
|
|
14
|
+
measure(): this;
|
|
15
|
+
clone(): Character;
|
|
16
|
+
}
|
package/types/fragment.d.ts
CHANGED
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
import { BoundingBox } from './bounding-box';
|
|
2
|
+
import { Character } from './character';
|
|
2
3
|
import type { Paragraph } from './paragraph';
|
|
3
4
|
import type { TextStyle } from './types';
|
|
4
|
-
export interface FragmentOptions {
|
|
5
|
-
content?: string;
|
|
6
|
-
style?: Partial<TextStyle>;
|
|
7
|
-
parent?: Paragraph;
|
|
8
|
-
contentBox?: BoundingBox;
|
|
9
|
-
inlineBox?: BoundingBox;
|
|
10
|
-
glyphBox?: BoundingBox;
|
|
11
|
-
centerX?: number;
|
|
12
|
-
baseline?: number;
|
|
13
|
-
}
|
|
14
5
|
export declare class Fragment {
|
|
15
6
|
content: string;
|
|
16
|
-
style?: Partial<TextStyle
|
|
17
|
-
parent?: Paragraph;
|
|
7
|
+
style?: Partial<TextStyle> | undefined;
|
|
8
|
+
parent?: Paragraph | undefined;
|
|
18
9
|
contentBox: BoundingBox;
|
|
19
10
|
inlineBox: BoundingBox;
|
|
20
11
|
glyphBox: BoundingBox;
|
|
21
12
|
centerX: number;
|
|
22
13
|
baseline: number;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
characters: Array<Character>;
|
|
15
|
+
computedStyle: TextStyle;
|
|
16
|
+
computedContent: string;
|
|
17
|
+
constructor(content: string, style?: Partial<TextStyle> | undefined, parent?: Paragraph | undefined);
|
|
18
|
+
update(): this;
|
|
19
|
+
measure(): this;
|
|
20
|
+
clone(content?: string): Fragment;
|
|
26
21
|
}
|
package/types/measure-text.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BoundingBox } from './bounding-box';
|
|
2
|
-
import type { TextContent, TextStyle } from './types';
|
|
2
|
+
import type { TextContent, TextEffect, TextStyle } from './types';
|
|
3
3
|
export interface MeasureTextStyle extends TextStyle {
|
|
4
4
|
width: number;
|
|
5
5
|
height: number;
|
|
@@ -7,6 +7,7 @@ export interface MeasureTextStyle extends TextStyle {
|
|
|
7
7
|
export interface MeasureTextOptions {
|
|
8
8
|
content: TextContent;
|
|
9
9
|
style?: Partial<MeasureTextStyle>;
|
|
10
|
+
effects?: Array<TextEffect>;
|
|
10
11
|
}
|
|
11
12
|
export declare function measureText(options: MeasureTextOptions): {
|
|
12
13
|
box: BoundingBox;
|
package/types/paragraph.d.ts
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
import { BoundingBox } from './bounding-box';
|
|
2
2
|
import { Fragment } from './fragment';
|
|
3
|
-
import type { FragmentOptions } from './fragment';
|
|
4
3
|
import type { TextStyle } from './types';
|
|
5
|
-
export interface ParagraphOptions {
|
|
6
|
-
style?: Partial<TextStyle>;
|
|
7
|
-
parent?: TextStyle;
|
|
8
|
-
contentBox?: BoundingBox;
|
|
9
|
-
lineBox?: BoundingBox;
|
|
10
|
-
glyphBox?: BoundingBox;
|
|
11
|
-
baseline?: number;
|
|
12
|
-
xHeight?: number;
|
|
13
|
-
maxCharWidth?: number;
|
|
14
|
-
fragments?: Array<Fragment>;
|
|
15
|
-
}
|
|
16
4
|
export declare class Paragraph {
|
|
17
|
-
style?: Partial<TextStyle
|
|
18
|
-
parent?: TextStyle;
|
|
5
|
+
style?: Partial<TextStyle> | undefined;
|
|
6
|
+
parent?: TextStyle | undefined;
|
|
19
7
|
contentBox: BoundingBox;
|
|
20
8
|
lineBox: BoundingBox;
|
|
21
9
|
glyphBox: BoundingBox;
|
|
22
10
|
baseline: number;
|
|
23
11
|
xHeight: number;
|
|
24
|
-
maxCharWidth: number;
|
|
25
12
|
fragments: Array<Fragment>;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
13
|
+
computedStyle: TextStyle;
|
|
14
|
+
constructor(style?: Partial<TextStyle> | undefined, parent?: TextStyle | undefined);
|
|
15
|
+
update(): void;
|
|
16
|
+
addFragment(content: string, style?: Partial<TextStyle>): this;
|
|
17
|
+
clone(fragments?: Array<Fragment>): Paragraph;
|
|
30
18
|
}
|
package/types/render-text.d.ts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import type { TextDrawStyle } from './types';
|
|
2
1
|
import type { MeasureTextOptions } from './measure-text';
|
|
3
|
-
export type RenderTextDraws = Array<Partial<TextDrawStyle & {
|
|
4
|
-
offsetX: number;
|
|
5
|
-
offsetY: number;
|
|
6
|
-
}>>;
|
|
7
2
|
export interface RenderTextOptions extends MeasureTextOptions {
|
|
8
3
|
view?: HTMLCanvasElement;
|
|
9
|
-
draws?: RenderTextDraws;
|
|
10
4
|
pixelRatio?: number;
|
|
11
5
|
}
|
|
12
6
|
export declare function renderText(options: RenderTextOptions): HTMLCanvasElement;
|
package/types/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type WritingMode = 'horizontal-tb' | 'vertical-lr' | 'vertical-rl';
|
|
2
|
+
export type TextOrientation = 'mixed' | 'upright' | 'sideways-right' | 'sideways';
|
|
2
3
|
export type FontWeight = 'normal' | 'bold' | 'lighter' | 'bolder' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
3
4
|
export type FontStyle = 'normal' | 'italic' | 'oblique' | `oblique ${string}`;
|
|
4
5
|
export type FontKerning = 'auto' | 'none' | 'normal';
|
|
@@ -9,6 +10,7 @@ export type TextTransform = 'uppercase' | 'lowercase' | 'none';
|
|
|
9
10
|
export type TextDecoration = 'underline' | 'line-through';
|
|
10
11
|
export interface TextLayoutStyle {
|
|
11
12
|
writingMode: WritingMode;
|
|
13
|
+
textOrientation: TextOrientation;
|
|
12
14
|
fontSize: number;
|
|
13
15
|
fontWeight: FontWeight;
|
|
14
16
|
fontFamily: string;
|
|
@@ -32,6 +34,10 @@ export interface TextDrawStyle {
|
|
|
32
34
|
shadowOffsetY: number;
|
|
33
35
|
shadowBlur: number;
|
|
34
36
|
}
|
|
37
|
+
export type TextEffect = Partial<TextDrawStyle & {
|
|
38
|
+
offsetX: number;
|
|
39
|
+
offsetY: number;
|
|
40
|
+
}>;
|
|
35
41
|
export interface TextStyle extends TextLayoutStyle, TextDrawStyle {
|
|
36
42
|
}
|
|
37
43
|
export interface FragmentContent extends Partial<TextStyle> {
|