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 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 u {
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 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 });
19
- return new u({
20
- x: h.x,
21
- y: h.y,
22
- width: h.right - h.x,
23
- height: h.bottom - h.y
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
- move(t, o) {
27
- return this.x += t, this.y += o, this;
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 u({
31
- x: this.x,
32
- y: this.y,
33
- width: this.width,
34
- height: this.height
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
- class $ {
39
- constructor({
40
- content: t = "",
41
- style: o,
42
- parent: h,
43
- contentBox: l = new u(),
44
- inlineBox: a = new u(),
45
- glyphBox: x = new u(),
46
- centerX: B = 0,
47
- baseline: w = 0
48
- } = {}) {
49
- 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) {
50
- case "uppercase":
51
- this.content = this.content.toUpperCase();
52
- break;
53
- case "lowercase":
54
- this.content = this.content.toLowerCase();
55
- break;
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
- getComputedStyle() {
59
- var t;
60
- return {
61
- ...(t = this.parent) == null ? void 0 : t.getComputedStyle(),
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
- content: this.content,
68
- style: this.style,
69
- parent: this.parent,
70
- contentBox: this.contentBox.clone(),
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 M {
80
- constructor({
81
- style: t,
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
- getComputedStyle() {
97
- return {
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
- return new M({
104
- style: this.style,
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 G(r, t) {
118
- const o = [];
223
+ function K(r, t) {
224
+ const u = [];
119
225
  if (typeof r == "string")
120
- o.push(new M({ parent: t }).addFragment({ content: r }));
226
+ u.push(new v(void 0, t).addFragment(r));
121
227
  else {
122
228
  r = Array.isArray(r) ? r : [r];
123
- for (const h of r)
124
- if (typeof h == "string")
125
- o.push(new M({ parent: t }).addFragment({ content: h }));
126
- else if (Array.isArray(h)) {
127
- const l = new M({ parent: t });
128
- h.forEach((a) => {
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
- l.addFragment({ content: a });
236
+ o.addFragment(a);
131
237
  else {
132
- const { content: x, ...B } = a;
133
- l.addFragment({ content: x, style: B });
238
+ const { content: h, ...E } = a;
239
+ o.addFragment(h, E);
134
240
  }
135
- }), o.push(l);
136
- } else if ("fragments" in h) {
137
- const { fragments: l, ...a } = h, x = new M({ style: a, parent: t });
138
- l.forEach((B) => {
139
- const { content: w, ...m } = B;
140
- x.addFragment({ content: w, style: m });
141
- }), o.push(x);
142
- } else if ("content" in h) {
143
- const { content: l, ...a } = h;
144
- o.push(new M({ style: a, parent: t }).addFragment({ content: l }));
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 o;
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 Y(r, t) {
155
- 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) {
156
- case "baseline":
157
- r.textBaseline = "alphabetic";
158
- break;
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 w = 0;
183
- const m = [];
184
- for (; x = B.shift(); ) {
185
- const b = x.getComputedStyle();
186
- let y = "", s = !1, v = 0, e = "";
187
- for (const i of x.content) {
188
- if (a.maxCharWidth = Math.max(
189
- a.maxCharWidth,
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
- let S, c;
194
- switch (b.writingMode) {
270
+ const D = F.isEOL;
271
+ let x, c;
272
+ switch (p.writingMode) {
195
273
  case "vertical-lr":
196
274
  case "vertical-rl":
197
- S = o, c = e.length * b.fontSize;
275
+ x = u, c = e.update().measure().contentBox.height;
198
276
  break;
199
277
  case "horizontal-tb":
200
278
  default:
201
- S = t, c = z(e, { ...b, letterSpacing: 0 }).width;
279
+ x = t, c = e.update().measure().contentBox.width;
202
280
  break;
203
281
  }
204
- c += e.length * b.letterSpacing;
205
- const f = /^[\r\n]$/.test(e);
206
- if (f || b.textWrap === "wrap" && S && w + c > S) {
207
- let g = f ? y.length + 1 : y.length;
208
- !w && !g && (y += e, g += e.length), y.length && m.push(x.clone({ content: y })), m.length && (h.push(
209
- a.clone({
210
- fragments: m.slice()
211
- })
212
- ), m.length = 0);
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
- w += c;
223
- y += e, e = "";
293
+ f += c;
294
+ i += e.content, e.content = "";
224
295
  }
225
- s || m.push(x.clone());
296
+ w || A.push(h.clone());
226
297
  }
227
- m.length && h.push(a.clone({ fragments: m }));
298
+ A.length && n.push(a.clone(A));
228
299
  }
229
- return h;
300
+ return n;
230
301
  }
231
- function q(r) {
302
+ function G(r) {
232
303
  return {
233
304
  width: 0,
234
305
  height: 0,
235
- color: null,
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: null,
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 J(r) {
260
- const { content: t } = r, { width: o, height: h, ...l } = q(r.style);
261
- let a = G(t, l);
262
- a = V(a, o, h);
263
- let x = a.reduce((e, i) => e + i.maxCharWidth * i.getComputedStyle().lineHeight, 0), B = 0, w = 0;
264
- a.forEach((e) => {
265
- const i = [];
266
- let S = null, c = B, f = w;
267
- e.fragments.forEach((n, k) => {
268
- const d = n.getComputedStyle();
269
- switch (d.writingMode) {
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
- const p = e.maxCharWidth, C = p * d.lineHeight;
273
- k || (f = 0, d.writingMode === "vertical-rl" && (x -= C, c = x));
274
- const A = n.content.length, W = A * d.fontSize + (A - 1) * d.letterSpacing;
275
- 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 + d.letterSpacing;
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
- k || (c = 0);
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 = u.from(...e.fragments.map((n) => n.inlineBox)), B += e.lineBox.width, w += e.lineBox.height;
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 m = u.from(
306
- ...a.map((e) => e.lineBox),
307
- new u({ width: o, height: h })
308
- ), { width: b, height: y } = m;
309
- a.forEach((e) => {
310
- e.contentBox = u.from(...e.fragments.map((i) => i.contentBox)), e.glyphBox = u.from(...e.fragments.map((i) => i.glyphBox)), e.fragments.forEach((i) => {
311
- const S = i.getComputedStyle(), c = i.inlineBox.x, f = i.inlineBox.y;
312
- let g = c, n = f;
313
- switch (S.writingMode) {
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 (S.textAlign) {
378
+ switch (D.textAlign) {
317
379
  case "end":
318
380
  case "right":
319
- n += y - e.contentBox.height;
381
+ c = p - e.contentBox.height;
320
382
  break;
321
383
  case "center":
322
- n += (y - e.contentBox.height) / 2;
384
+ c = (p - e.contentBox.height) / 2;
323
385
  break;
324
386
  }
325
387
  break;
326
388
  case "horizontal-tb": {
327
- switch (S.textAlign) {
389
+ switch (D.textAlign) {
328
390
  case "end":
329
391
  case "right":
330
- g += b - e.contentBox.width;
392
+ x = A - e.contentBox.width;
331
393
  break;
332
394
  case "center":
333
- g += (b - e.contentBox.width) / 2;
395
+ x = (A - e.contentBox.width) / 2;
334
396
  break;
335
397
  }
336
- switch (S.verticalAlign) {
398
+ switch (D.verticalAlign) {
337
399
  case "top":
338
- n += e.lineBox.y - i.inlineBox.y;
400
+ c = e.lineBox.y - F.inlineBox.y;
339
401
  break;
340
402
  case "middle":
341
- n = e.baseline - e.xHeight / 2 - i.inlineBox.height / 2;
403
+ c = F.inlineBox.y - (e.baseline - e.xHeight / 2 - F.inlineBox.height / 2);
342
404
  break;
343
405
  case "bottom":
344
- n += e.lineBox.bottom - i.inlineBox.bottom;
406
+ c = e.lineBox.bottom - F.inlineBox.bottom;
345
407
  break;
346
408
  case "sub":
347
- n += e.baseline - i.glyphBox.bottom;
409
+ c = e.baseline - F.glyphBox.bottom;
348
410
  break;
349
411
  case "super":
350
- n += e.baseline - i.glyphBox.y;
412
+ c = e.baseline - F.glyphBox.y;
351
413
  break;
352
414
  case "text-top":
353
- n += e.glyphBox.y - i.inlineBox.y;
415
+ c = e.glyphBox.y - F.inlineBox.y;
354
416
  break;
355
417
  case "text-bottom":
356
- n += e.glyphBox.bottom - i.inlineBox.bottom;
418
+ c = e.glyphBox.bottom - F.inlineBox.bottom;
357
419
  break;
358
420
  case "baseline":
359
421
  default:
360
- i.inlineBox.height < e.lineBox.height && (n += e.baseline - i.baseline);
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
- const k = g - c, d = n - f;
367
- i.inlineBox.move(k, d), i.contentBox.move(k, d), i.glyphBox.move(k, d), i.baseline += d, i.centerX += k;
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 s = u.from(...a.map((e) => e.contentBox)), v = u.from(...a.map((e) => e.glyphBox));
371
- return {
372
- box: m,
373
- contentBox: s,
374
- glyphBox: v,
375
- paragraphs: a,
376
- viewBox: u.from(m, v)
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 X(r, t, o) {
456
+ function T(r, t, u) {
380
457
  if (typeof t == "string" && t.startsWith("linear-gradient")) {
381
- const { x0: h, y0: l, x1: a, y1: x, stops: B } = Q(t, o.left, o.top, o.width, o.height), w = r.createLinearGradient(h, l, a, x);
382
- return B.forEach((m) => w.addColorStop(m.offset, m.color)), w;
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 Q(r, t, o, h, l) {
387
- var v;
388
- 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);
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 + h / 2 - y,
391
- y0: o + l / 2 + s,
392
- x1: t + h / 2 + y,
393
- y1: o + l / 2 - s,
394
- stops: Array.from(w).map((e) => {
395
- let i = e[2];
396
- return i.startsWith("(") ? i = i.split(",").length > 3 ? `rgba${i}` : `rgb${i}` : i = `#${i}`, {
397
- offset: Number(e[3].replace("%", "")) / 100,
398
- color: i
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 E(r, t, o) {
404
- 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));
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 Z(r) {
483
+ function V(r) {
407
484
  const {
408
485
  view: t = document.createElement("canvas"),
409
- style: o,
410
- draws: h = [],
411
- pixelRatio: l = 1
412
- } = r, a = h.length > 0 ? h : [{}], { viewBox: x, paragraphs: B } = J(r), { x: w, y: m, width: b, height: y } = x, s = t.getContext("2d");
413
- 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);
414
- const v = { ...o };
415
- return E(s, new u({ width: b, height: y }), v), B.forEach((e) => {
416
- E(s, e.contentBox, e.style), e.fragments.forEach((i) => {
417
- E(s, i.contentBox, i.style);
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 i = { ...e };
421
- E(s, new u({ width: b, height: y }), i);
422
- const S = { ...v, ...i };
423
- S != null && S.backgroundColor && (s.fillStyle = S.backgroundColor, s.fillRect(0, 0, t.width, t.height)), B.forEach((c) => {
424
- var f;
425
- (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) => {
426
- var n;
427
- (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));
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
- }), B.forEach((c) => {
430
- c.fragments.forEach((f) => {
431
- const g = { ...f.getComputedStyle(), ...i };
432
- Y(s, {
433
- ...g,
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
- let A = 0;
454
- for (const W of f.content)
455
- s.fillText(W, d, p + A), g.textStrokeWidth && s.strokeText(W, d, p + A), A += g.fontSize + g.letterSpacing;
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.fillText(f.content, d, C), g.textStrokeWidth && s.strokeText(f.content, d, C);
460
- break;
461
- }
462
- switch (g.textDecoration) {
463
- case "underline":
464
- s.strokeStyle = s.fillStyle, s.lineWidth = g.fontSize / 15, s.beginPath(), s.moveTo(d, p + k), s.lineTo(d + n, p + k), s.stroke();
465
- break;
466
- case "line-through":
467
- s.strokeStyle = s.fillStyle, s.lineWidth = g.fontSize / 15, s.beginPath(), s.moveTo(d, p + k / 2), s.lineTo(d + n, p + k / 2), s.stroke();
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
- J as measureText,
476
- Z as renderText
553
+ I as measureText,
554
+ V as renderText
477
555
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-text",
3
3
  "type": "module",
4
- "version": "0.1.9",
4
+ "version": "0.1.11",
5
5
  "packageManager": "pnpm@8.14.1",
6
6
  "description": "Measure and render text in a way that describes the DOM.",
7
7
  "author": "wxm",
@@ -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({ x, y, width, height }?: BoundingBoxOptions);
10
+ constructor(x?: number, y?: number, width?: number, height?: number);
17
11
  static from(...boxes: Array<BoundingBox>): BoundingBox;
18
- move(tx: number, ty: number): this;
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): TextMetrics;
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
+ }
@@ -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
- constructor({ content, style, parent, contentBox, inlineBox, glyphBox, centerX, baseline, }?: FragmentOptions);
24
- getComputedStyle(): TextStyle;
25
- clone(options?: Partial<FragmentOptions>): Fragment;
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
  }
@@ -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;
@@ -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
- constructor({ style, parent, contentBox, lineBox, glyphBox, baseline, xHeight, maxCharWidth, fragments, }?: ParagraphOptions);
27
- addFragment(options: FragmentOptions): this;
28
- getComputedStyle(): TextStyle;
29
- clone(options?: Partial<ParagraphOptions>): Paragraph;
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
  }
@@ -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> {