modern-text 0.0.16 → 0.0.17

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"});const d=class d{static get defaultStyle(){return{width:"auto",height:"auto",color:"#000000",fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000000",direction:"inherit",lineHeight:1,letterSpacing:0,shadowColor:"#000000",shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0}}constructor(e={}){const{view:t=document.createElement("canvas"),pixelRatio:n=window.devicePixelRatio||1,content:o="",style:h}=e;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=n,this.content=o,this.style={...d.defaultStyle,...h},this.update()}_createBox(e=0,t=0,n=0,o=0){return{left:e,top:t,width:n,height:o,right:e+n,bottom:t+o}}_moveBox(e,t=0,n=0){e.left+=t,e.right+=t,e.top+=n,e.bottom+=n}_updateBoxSize(e){e.width=e.right-e.left,e.height=e.bottom-e.top}_mergeBoxes(e){const t=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{...e[0]});return this._updateBoxSize(t),t}measure(){let{width:e}=this.style;e==="auto"&&(e=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,e);const n=this.context;let o=0;for(let h=t.length,c=0;c<h;c++){const i=t[c],s=[];let B=0,a=null;for(const l of i.fragments){this._setContextStyle({...l.style,textAlign:"center",verticalAlign:"baseline"});const r=n.measureText(l.content),p=r.width,f=l.style.fontSize;l.inlineBox=this._createBox(B,o,p,f*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-f)/2,p,f);const y=r.fontBoundingBoxAscent+r.fontBoundingBoxDescent,w=r.actualBoundingBoxLeft+r.actualBoundingBoxRight,u=r.actualBoundingBoxAscent+r.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-y)/2+r.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left,l.baseline-r.actualBoundingBoxAscent,w,u),l.centerX=l.glyphBox.left+r.actualBoundingBoxLeft,B+=l.contentBox.width,s.push(l.contentBox),i.contentBox=this._mergeBoxes(s),i.contentBox.height<l.contentBox.height&&(a=l)}i.lineBox=this._mergeBoxes([...i.fragments.map(l=>l.inlineBox),this._createBox(0,o,e)]),this._setContextStyle({...(a??i).style,textAlign:"left",verticalAlign:"baseline"});const g=n.measureText("x"),x=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-x)/2+g.fontBoundingBoxAscent,o+=i.lineBox.height}for(let h=t.length,c=0;c<h;c++){const i=t[c];i.fragments.forEach(s=>{const B=s.inlineBox.left,a=s.inlineBox.top;let g,x=a;switch(s.style.textAlign){case"end":case"right":g=B+(i.lineBox.width-i.contentBox.width);break;case"center":g=B+(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:g=B+i.lineBox.left;break}switch(s.style.verticalAlign){case"top":x=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":x=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":x=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":x=a+(i.baseline-s.glyphBox.bottom);break;case"super":x=a+(i.baseline-s.glyphBox.top);break;case"text-top":x=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":x=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(x=a+(i.baseline-s.baseline));break}const l=g-B,r=x-a;this._moveBox(s.inlineBox,l,r),this._moveBox(s.contentBox,l,r),this._moveBox(s.glyphBox,l,r),s.baseline+=r,s.centerX+=l}),i.contentBox=this._mergeBoxes(i.fragments.map(s=>s.contentBox)),i.glyphBox=this._mergeBoxes(i.fragments.map(s=>s.glyphBox))}return{actualContentBox:this._mergeBoxes(t.map(h=>h.contentBox)),contentBox:this._mergeBoxes(t.map(h=>h.lineBox)),glyphBox:this._mergeBoxes(t.map(h=>h.glyphBox)),paragraphs:t}}_createParagraphs(e){const t=(h={})=>{const{width:c,height:i,...s}=this.style;return{contentBox:this._createBox(),lineBox:this._createBox(),glyphBox:this._createBox(),baseline:0,fragments:[],...h,style:{...s,...h.style}}},n=(h={})=>{const c=[],{width:i,height:s,...B}=this.style;return c.push({contentBox:this._createBox(),inlineBox:this._createBox(),glyphBox:this._createBox(),centerX:0,baseline:0,...h,style:{...B,...h.style},content:h.content??""}),c},o=[];if(typeof e=="string")o.push(t({fragments:n({content:e})}));else{e=Array.isArray(e)?e:[e];for(const h of e)if("fragments"in h){const{fragments:c,...i}=h,s=t({style:i});for(const B of c){const{content:a,...g}=B;s.fragments.push(...n({content:a,style:{...i,...g}}))}o.push(s)}else if("content"in h){const{content:c,...i}=h,s=t({style:i});s.fragments.push(...n({content:c,style:i})),o.push(s)}}return o}_createWrapedParagraphs(e,t){const n=s=>JSON.parse(JSON.stringify(s)),o=[],h=e.slice();let c,i;for(;c=h.shift();){const s=c.fragments.slice();let B=0;const a=[];for(;i=s.shift();){const g=i.style;this._setContextStyle(g);let x="",l=!1,r=0,p="";for(const f of i.content){if(p+=f,d.punctuationRegex.test(i.content[++r]))continue;const y=this.context.measureText(p).width,w=/^[\r\n]$/.test(p);if(w||g.textWrap==="wrap"&&t&&B+y>t){let u=w?x.length+1:x.length;!B&&!u&&(x+=p,u+=p.length),x.length&&a.push({...n(i),content:x}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const b=i.content.substring(u);(b.length||s.length)&&h.unshift({...n(c),fragments:(b.length?[{...n(i),content:b}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else B+=y;x+=p,p=""}l||a.push(n(i))}a.length&&o.push({...n(c),fragments:a})}return o}_draw(e){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),e.forEach(n=>{n.style.backgroundColor&&(t.fillStyle=n.style.backgroundColor,t.fillRect(n.lineBox.left,n.lineBox.top,n.lineBox.width,n.lineBox.height))}),e.forEach(n=>{n.fragments.forEach(o=>{switch(o.style.backgroundColor&&(t.fillStyle=o.style.backgroundColor,t.fillRect(o.inlineBox.left,o.inlineBox.top,o.inlineBox.width,o.inlineBox.height)),this._setContextStyle({...o.style,textAlign:"left",verticalAlign:"top"}),o.style.textStrokeWidth&&t.strokeText(o.content,o.contentBox.left,o.contentBox.top),t.fillText(o.content,o.contentBox.left,o.contentBox.top),o.style.textDecoration){case"underline":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height-2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height/2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height/2),t.stroke();break}})})}_resizeView(e,t){const n=this.view;n.style.width=`${e}px`,n.style.height=`${t}px`,n.dataset.width=String(e),n.dataset.height=String(t),n.width=Math.max(1,Math.floor(e*this.pixelRatio)),n.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(e){const t=this.context;switch(t.shadowColor=e.shadowColor,t.shadowOffsetX=e.shadowOffsetX,t.shadowOffsetY=e.shadowOffsetY,t.shadowBlur=e.shadowBlur,t.strokeStyle=e.textStrokeColor,t.lineWidth=e.textStrokeWidth,t.fillStyle=e.color,t.direction=e.direction,t.textAlign=e.textAlign,e.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=e.verticalAlign;break}t.font=[e.fontStyle,e.fontWeight,`${e.fontSize}px`,e.fontFamily].join(" "),t.fontKerning=e.fontKerning,t.letterSpacing=`${e.letterSpacing}px`}update(){const e=this.context;let{width:t,height:n}=this.style;t==="auto"&&(t=0),n==="auto"&&(n=0);const{contentBox:o,paragraphs:h}=this.measure();t||(t=o.width),n=Math.max(n,o.height),this._resizeView(t,n);const c=this.pixelRatio;e.scale(c,c),e.clearRect(0,0,e.canvas.width,e.canvas.height),this._draw(h)}};d.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let _=d;exports.Text=_;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=class d{static get defaultStyle(){return{width:"auto",height:"auto",color:"#000000",fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000000",direction:"inherit",lineHeight:1,letterSpacing:0,shadowColor:"#000000",shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0}}constructor(e={}){const{view:t=document.createElement("canvas"),pixelRatio:n=window.devicePixelRatio||1,content:o="",style:h}=e;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=n,this.content=o,this.style={...d.defaultStyle,...h},this.update()}_createBox(e=0,t=0,n=0,o=0){return{left:e,top:t,width:n,height:o,right:e+n,bottom:t+o}}_moveBox(e,t=0,n=0){e.left+=t,e.right+=t,e.top+=n,e.bottom+=n}_updateBoxSize(e){e.width=e.right-e.left,e.height=e.bottom-e.top}_mergeBoxes(e){const t=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{...e[0]});return this._updateBoxSize(t),t}measure(){let{width:e}=this.style;e==="auto"&&(e=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,e);const n=this.context;let o=0;for(let h=t.length,c=0;c<h;c++){const i=t[c],s=[];let g=0,a=null;for(const l of i.fragments){this._setContextStyle({...l.style,textAlign:"center",verticalAlign:"baseline"});const B=n.measureText(l.content),p=B.width,f=l.style.fontSize;l.inlineBox=this._createBox(g,o,p,f*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-f)/2,p,f);const w=B.fontBoundingBoxAscent+B.fontBoundingBoxDescent,y=B.actualBoundingBoxLeft+B.actualBoundingBoxRight,u=B.actualBoundingBoxAscent+B.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-w)/2+B.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left,l.baseline-B.actualBoundingBoxAscent,y,u),l.centerX=l.glyphBox.left+B.actualBoundingBoxLeft,g+=l.contentBox.width,s.push(l.contentBox),i.contentBox=this._mergeBoxes(s),i.contentBox.height<l.contentBox.height&&(a=l)}i.lineBox=this._mergeBoxes([...i.fragments.map(l=>l.inlineBox),this._createBox(0,o,e)]),this._setContextStyle({...(a??i).style,textAlign:"left",verticalAlign:"baseline"});const r=n.measureText("x"),x=r.fontBoundingBoxAscent+r.fontBoundingBoxDescent;i.xHeight=r.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-x)/2+r.fontBoundingBoxAscent,o+=i.lineBox.height}for(let h=t.length,c=0;c<h;c++){const i=t[c];i.fragments.forEach(s=>{const g=s.inlineBox.left,a=s.inlineBox.top;let r,x=a;switch(s.style.textAlign){case"end":case"right":r=g+(i.lineBox.width-i.contentBox.width);break;case"center":r=g+(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:r=g+i.lineBox.left;break}switch(s.style.verticalAlign){case"top":x=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":x=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":x=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":x=a+(i.baseline-s.glyphBox.bottom);break;case"super":x=a+(i.baseline-s.glyphBox.top);break;case"text-top":x=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":x=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(x=a+(i.baseline-s.baseline));break}const l=r-g,B=x-a;this._moveBox(s.inlineBox,l,B),this._moveBox(s.contentBox,l,B),this._moveBox(s.glyphBox,l,B),s.baseline+=B,s.centerX+=l}),i.contentBox=this._mergeBoxes(i.fragments.map(s=>s.contentBox)),i.glyphBox=this._mergeBoxes(i.fragments.map(s=>s.glyphBox))}return{actualContentBox:this._mergeBoxes(t.map(h=>h.contentBox)),contentBox:this._mergeBoxes(t.map(h=>h.lineBox)),glyphBox:this._mergeBoxes(t.map(h=>h.glyphBox)),paragraphs:t}}_createParagraphs(e){const t=(h={})=>{const{width:c,height:i,...s}=this.style;return{contentBox:this._createBox(),lineBox:this._createBox(),glyphBox:this._createBox(),baseline:0,fragments:[],...h,style:{...s,...h.style}}},n=(h={})=>{const c=[],{width:i,height:s,...g}=this.style,a={...g,...h.style};let r=h.content??"";switch(a.textTransform){case"uppercase":r=r.toUpperCase();break;case"lowercase":r=r.toLowerCase();break}return c.push({contentBox:this._createBox(),inlineBox:this._createBox(),glyphBox:this._createBox(),centerX:0,baseline:0,...h,style:a,content:r}),c},o=[];if(typeof e=="string")o.push(t({fragments:n({content:e})}));else{e=Array.isArray(e)?e:[e];for(const h of e)if("fragments"in h){const{fragments:c,...i}=h,s=t({style:i});for(const g of c){const{content:a,...r}=g;s.fragments.push(...n({content:a,style:{...i,...r}}))}o.push(s)}else if("content"in h){const{content:c,...i}=h,s=t({style:i});s.fragments.push(...n({content:c,style:i})),o.push(s)}}return o}_createWrapedParagraphs(e,t){const n=s=>JSON.parse(JSON.stringify(s)),o=[],h=e.slice();let c,i;for(;c=h.shift();){const s=c.fragments.slice();let g=0;const a=[];for(;i=s.shift();){const r=i.style;this._setContextStyle(r);let x="",l=!1,B=0,p="";for(const f of i.content){if(p+=f,d.punctuationRegex.test(i.content[++B]))continue;const w=this.context.measureText(p).width,y=/^[\r\n]$/.test(p);if(y||r.textWrap==="wrap"&&t&&g+w>t){let u=y?x.length+1:x.length;!g&&!u&&(x+=p,u+=p.length),x.length&&a.push({...n(i),content:x}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const b=i.content.substring(u);(b.length||s.length)&&h.unshift({...n(c),fragments:(b.length?[{...n(i),content:b}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else g+=w;x+=p,p=""}l||a.push(n(i))}a.length&&o.push({...n(c),fragments:a})}return o}_draw(e){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),e.forEach(n=>{n.style.backgroundColor&&(t.fillStyle=n.style.backgroundColor,t.fillRect(n.lineBox.left,n.lineBox.top,n.lineBox.width,n.lineBox.height))}),e.forEach(n=>{n.fragments.forEach(o=>{switch(o.style.backgroundColor&&(t.fillStyle=o.style.backgroundColor,t.fillRect(o.inlineBox.left,o.inlineBox.top,o.inlineBox.width,o.inlineBox.height)),this._setContextStyle({...o.style,textAlign:"left",verticalAlign:"top"}),o.style.textStrokeWidth&&t.strokeText(o.content,o.contentBox.left,o.contentBox.top),t.fillText(o.content,o.contentBox.left,o.contentBox.top),o.style.textDecoration){case"underline":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height-2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height/2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height/2),t.stroke();break}})})}_resizeView(e,t){const n=this.view;n.style.width=`${e}px`,n.style.height=`${t}px`,n.dataset.width=String(e),n.dataset.height=String(t),n.width=Math.max(1,Math.floor(e*this.pixelRatio)),n.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(e){const t=this.context;switch(t.shadowColor=e.shadowColor,t.shadowOffsetX=e.shadowOffsetX,t.shadowOffsetY=e.shadowOffsetY,t.shadowBlur=e.shadowBlur,t.strokeStyle=e.textStrokeColor,t.lineWidth=e.textStrokeWidth,t.fillStyle=e.color,t.direction=e.direction,t.textAlign=e.textAlign,e.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=e.verticalAlign;break}t.font=[e.fontStyle,e.fontWeight,`${e.fontSize}px`,e.fontFamily].join(" "),t.fontKerning=e.fontKerning,t.letterSpacing=`${e.letterSpacing}px`}update(){const e=this.context;let{width:t,height:n}=this.style;t==="auto"&&(t=0),n==="auto"&&(n=0);const{contentBox:o,paragraphs:h}=this.measure();t||(t=o.width),n=Math.max(n,o.height),this._resizeView(t,n);const c=this.pixelRatio;e.scale(c,c),e.clearRect(0,0,e.canvas.width,e.canvas.height),this._draw(h)}};d.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let _=d;exports.Text=_;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(u,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(u=typeof globalThis<"u"?globalThis:u||self,f(u.modernText={}))})(this,function(u){"use strict";const d=class d{static get defaultStyle(){return{width:"auto",height:"auto",color:"#000000",fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000000",direction:"inherit",lineHeight:1,letterSpacing:0,shadowColor:"#000000",shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0}}constructor(e={}){const{view:t=document.createElement("canvas"),pixelRatio:n=window.devicePixelRatio||1,content:o="",style:h}=e;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=n,this.content=o,this.style={...d.defaultStyle,...h},this.update()}_createBox(e=0,t=0,n=0,o=0){return{left:e,top:t,width:n,height:o,right:e+n,bottom:t+o}}_moveBox(e,t=0,n=0){e.left+=t,e.right+=t,e.top+=n,e.bottom+=n}_updateBoxSize(e){e.width=e.right-e.left,e.height=e.bottom-e.top}_mergeBoxes(e){const t=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{...e[0]});return this._updateBoxSize(t),t}measure(){let{width:e}=this.style;e==="auto"&&(e=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,e);const n=this.context;let o=0;for(let h=t.length,c=0;c<h;c++){const i=t[c],s=[];let B=0,a=null;for(const l of i.fragments){this._setContextStyle({...l.style,textAlign:"center",verticalAlign:"baseline"});const r=n.measureText(l.content),p=r.width,y=l.style.fontSize;l.inlineBox=this._createBox(B,o,p,y*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-y)/2,p,y);const b=r.fontBoundingBoxAscent+r.fontBoundingBoxDescent,_=r.actualBoundingBoxLeft+r.actualBoundingBoxRight,w=r.actualBoundingBoxAscent+r.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-b)/2+r.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left,l.baseline-r.actualBoundingBoxAscent,_,w),l.centerX=l.glyphBox.left+r.actualBoundingBoxLeft,B+=l.contentBox.width,s.push(l.contentBox),i.contentBox=this._mergeBoxes(s),i.contentBox.height<l.contentBox.height&&(a=l)}i.lineBox=this._mergeBoxes([...i.fragments.map(l=>l.inlineBox),this._createBox(0,o,e)]),this._setContextStyle({...(a??i).style,textAlign:"left",verticalAlign:"baseline"});const g=n.measureText("x"),x=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-x)/2+g.fontBoundingBoxAscent,o+=i.lineBox.height}for(let h=t.length,c=0;c<h;c++){const i=t[c];i.fragments.forEach(s=>{const B=s.inlineBox.left,a=s.inlineBox.top;let g,x=a;switch(s.style.textAlign){case"end":case"right":g=B+(i.lineBox.width-i.contentBox.width);break;case"center":g=B+(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:g=B+i.lineBox.left;break}switch(s.style.verticalAlign){case"top":x=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":x=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":x=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":x=a+(i.baseline-s.glyphBox.bottom);break;case"super":x=a+(i.baseline-s.glyphBox.top);break;case"text-top":x=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":x=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(x=a+(i.baseline-s.baseline));break}const l=g-B,r=x-a;this._moveBox(s.inlineBox,l,r),this._moveBox(s.contentBox,l,r),this._moveBox(s.glyphBox,l,r),s.baseline+=r,s.centerX+=l}),i.contentBox=this._mergeBoxes(i.fragments.map(s=>s.contentBox)),i.glyphBox=this._mergeBoxes(i.fragments.map(s=>s.glyphBox))}return{actualContentBox:this._mergeBoxes(t.map(h=>h.contentBox)),contentBox:this._mergeBoxes(t.map(h=>h.lineBox)),glyphBox:this._mergeBoxes(t.map(h=>h.glyphBox)),paragraphs:t}}_createParagraphs(e){const t=(h={})=>{const{width:c,height:i,...s}=this.style;return{contentBox:this._createBox(),lineBox:this._createBox(),glyphBox:this._createBox(),baseline:0,fragments:[],...h,style:{...s,...h.style}}},n=(h={})=>{const c=[],{width:i,height:s,...B}=this.style;return c.push({contentBox:this._createBox(),inlineBox:this._createBox(),glyphBox:this._createBox(),centerX:0,baseline:0,...h,style:{...B,...h.style},content:h.content??""}),c},o=[];if(typeof e=="string")o.push(t({fragments:n({content:e})}));else{e=Array.isArray(e)?e:[e];for(const h of e)if("fragments"in h){const{fragments:c,...i}=h,s=t({style:i});for(const B of c){const{content:a,...g}=B;s.fragments.push(...n({content:a,style:{...i,...g}}))}o.push(s)}else if("content"in h){const{content:c,...i}=h,s=t({style:i});s.fragments.push(...n({content:c,style:i})),o.push(s)}}return o}_createWrapedParagraphs(e,t){const n=s=>JSON.parse(JSON.stringify(s)),o=[],h=e.slice();let c,i;for(;c=h.shift();){const s=c.fragments.slice();let B=0;const a=[];for(;i=s.shift();){const g=i.style;this._setContextStyle(g);let x="",l=!1,r=0,p="";for(const y of i.content){if(p+=y,d.punctuationRegex.test(i.content[++r]))continue;const b=this.context.measureText(p).width,_=/^[\r\n]$/.test(p);if(_||g.textWrap==="wrap"&&t&&B+b>t){let w=_?x.length+1:x.length;!B&&!w&&(x+=p,w+=p.length),x.length&&a.push({...n(i),content:x}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const S=i.content.substring(w);(S.length||s.length)&&h.unshift({...n(c),fragments:(S.length?[{...n(i),content:S}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else B+=b;x+=p,p=""}l||a.push(n(i))}a.length&&o.push({...n(c),fragments:a})}return o}_draw(e){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),e.forEach(n=>{n.style.backgroundColor&&(t.fillStyle=n.style.backgroundColor,t.fillRect(n.lineBox.left,n.lineBox.top,n.lineBox.width,n.lineBox.height))}),e.forEach(n=>{n.fragments.forEach(o=>{switch(o.style.backgroundColor&&(t.fillStyle=o.style.backgroundColor,t.fillRect(o.inlineBox.left,o.inlineBox.top,o.inlineBox.width,o.inlineBox.height)),this._setContextStyle({...o.style,textAlign:"left",verticalAlign:"top"}),o.style.textStrokeWidth&&t.strokeText(o.content,o.contentBox.left,o.contentBox.top),t.fillText(o.content,o.contentBox.left,o.contentBox.top),o.style.textDecoration){case"underline":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height-2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height/2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height/2),t.stroke();break}})})}_resizeView(e,t){const n=this.view;n.style.width=`${e}px`,n.style.height=`${t}px`,n.dataset.width=String(e),n.dataset.height=String(t),n.width=Math.max(1,Math.floor(e*this.pixelRatio)),n.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(e){const t=this.context;switch(t.shadowColor=e.shadowColor,t.shadowOffsetX=e.shadowOffsetX,t.shadowOffsetY=e.shadowOffsetY,t.shadowBlur=e.shadowBlur,t.strokeStyle=e.textStrokeColor,t.lineWidth=e.textStrokeWidth,t.fillStyle=e.color,t.direction=e.direction,t.textAlign=e.textAlign,e.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=e.verticalAlign;break}t.font=[e.fontStyle,e.fontWeight,`${e.fontSize}px`,e.fontFamily].join(" "),t.fontKerning=e.fontKerning,t.letterSpacing=`${e.letterSpacing}px`}update(){const e=this.context;let{width:t,height:n}=this.style;t==="auto"&&(t=0),n==="auto"&&(n=0);const{contentBox:o,paragraphs:h}=this.measure();t||(t=o.width),n=Math.max(n,o.height),this._resizeView(t,n);const c=this.pixelRatio;e.scale(c,c),e.clearRect(0,0,e.canvas.width,e.canvas.height),this._draw(h)}};d.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let f=d;u.Text=f,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
1
+ (function(u,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(u=typeof globalThis<"u"?globalThis:u||self,f(u.modernText={}))})(this,function(u){"use strict";const d=class d{static get defaultStyle(){return{width:"auto",height:"auto",color:"#000000",fontSize:14,fontWeight:"normal",fontFamily:"sans-serif",fontStyle:"normal",fontKerning:"normal",textWrap:"wrap",textAlign:"start",verticalAlign:"baseline",textTransform:"none",textDecoration:null,textStrokeWidth:0,textStrokeColor:"#000000",direction:"inherit",lineHeight:1,letterSpacing:0,shadowColor:"#000000",shadowOffsetX:0,shadowOffsetY:0,shadowBlur:0}}constructor(e={}){const{view:t=document.createElement("canvas"),pixelRatio:n=window.devicePixelRatio||1,content:o="",style:h}=e;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=n,this.content=o,this.style={...d.defaultStyle,...h},this.update()}_createBox(e=0,t=0,n=0,o=0){return{left:e,top:t,width:n,height:o,right:e+n,bottom:t+o}}_moveBox(e,t=0,n=0){e.left+=t,e.right+=t,e.top+=n,e.bottom+=n}_updateBoxSize(e){e.width=e.right-e.left,e.height=e.bottom-e.top}_mergeBoxes(e){const t=e.slice(1).reduce((n,o)=>(n.left=Math.min(n.left,o.left),n.top=Math.min(n.top,o.top),n.right=Math.max(n.right,o.right),n.bottom=Math.max(n.bottom,o.bottom),n),{...e[0]});return this._updateBoxSize(t),t}measure(){let{width:e}=this.style;e==="auto"&&(e=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,e);const n=this.context;let o=0;for(let h=t.length,a=0;a<h;a++){const i=t[a],s=[];let g=0,c=null;for(const l of i.fragments){this._setContextStyle({...l.style,textAlign:"center",verticalAlign:"baseline"});const B=n.measureText(l.content),p=B.width,y=l.style.fontSize;l.inlineBox=this._createBox(g,o,p,y*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-y)/2,p,y);const b=B.fontBoundingBoxAscent+B.fontBoundingBoxDescent,_=B.actualBoundingBoxLeft+B.actualBoundingBoxRight,w=B.actualBoundingBoxAscent+B.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-b)/2+B.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left,l.baseline-B.actualBoundingBoxAscent,_,w),l.centerX=l.glyphBox.left+B.actualBoundingBoxLeft,g+=l.contentBox.width,s.push(l.contentBox),i.contentBox=this._mergeBoxes(s),i.contentBox.height<l.contentBox.height&&(c=l)}i.lineBox=this._mergeBoxes([...i.fragments.map(l=>l.inlineBox),this._createBox(0,o,e)]),this._setContextStyle({...(c??i).style,textAlign:"left",verticalAlign:"baseline"});const r=n.measureText("x"),x=r.fontBoundingBoxAscent+r.fontBoundingBoxDescent;i.xHeight=r.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-x)/2+r.fontBoundingBoxAscent,o+=i.lineBox.height}for(let h=t.length,a=0;a<h;a++){const i=t[a];i.fragments.forEach(s=>{const g=s.inlineBox.left,c=s.inlineBox.top;let r,x=c;switch(s.style.textAlign){case"end":case"right":r=g+(i.lineBox.width-i.contentBox.width);break;case"center":r=g+(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:r=g+i.lineBox.left;break}switch(s.style.verticalAlign){case"top":x=c+(i.lineBox.top-s.inlineBox.top);break;case"middle":x=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":x=c+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":x=c+(i.baseline-s.glyphBox.bottom);break;case"super":x=c+(i.baseline-s.glyphBox.top);break;case"text-top":x=c+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":x=c+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(x=c+(i.baseline-s.baseline));break}const l=r-g,B=x-c;this._moveBox(s.inlineBox,l,B),this._moveBox(s.contentBox,l,B),this._moveBox(s.glyphBox,l,B),s.baseline+=B,s.centerX+=l}),i.contentBox=this._mergeBoxes(i.fragments.map(s=>s.contentBox)),i.glyphBox=this._mergeBoxes(i.fragments.map(s=>s.glyphBox))}return{actualContentBox:this._mergeBoxes(t.map(h=>h.contentBox)),contentBox:this._mergeBoxes(t.map(h=>h.lineBox)),glyphBox:this._mergeBoxes(t.map(h=>h.glyphBox)),paragraphs:t}}_createParagraphs(e){const t=(h={})=>{const{width:a,height:i,...s}=this.style;return{contentBox:this._createBox(),lineBox:this._createBox(),glyphBox:this._createBox(),baseline:0,fragments:[],...h,style:{...s,...h.style}}},n=(h={})=>{const a=[],{width:i,height:s,...g}=this.style,c={...g,...h.style};let r=h.content??"";switch(c.textTransform){case"uppercase":r=r.toUpperCase();break;case"lowercase":r=r.toLowerCase();break}return a.push({contentBox:this._createBox(),inlineBox:this._createBox(),glyphBox:this._createBox(),centerX:0,baseline:0,...h,style:c,content:r}),a},o=[];if(typeof e=="string")o.push(t({fragments:n({content:e})}));else{e=Array.isArray(e)?e:[e];for(const h of e)if("fragments"in h){const{fragments:a,...i}=h,s=t({style:i});for(const g of a){const{content:c,...r}=g;s.fragments.push(...n({content:c,style:{...i,...r}}))}o.push(s)}else if("content"in h){const{content:a,...i}=h,s=t({style:i});s.fragments.push(...n({content:a,style:i})),o.push(s)}}return o}_createWrapedParagraphs(e,t){const n=s=>JSON.parse(JSON.stringify(s)),o=[],h=e.slice();let a,i;for(;a=h.shift();){const s=a.fragments.slice();let g=0;const c=[];for(;i=s.shift();){const r=i.style;this._setContextStyle(r);let x="",l=!1,B=0,p="";for(const y of i.content){if(p+=y,d.punctuationRegex.test(i.content[++B]))continue;const b=this.context.measureText(p).width,_=/^[\r\n]$/.test(p);if(_||r.textWrap==="wrap"&&t&&g+b>t){let w=_?x.length+1:x.length;!g&&!w&&(x+=p,w+=p.length),x.length&&c.push({...n(i),content:x}),c.length&&(o.push({...n(a),fragments:c.slice()}),c.length=0);const S=i.content.substring(w);(S.length||s.length)&&h.unshift({...n(a),fragments:(S.length?[{...n(i),content:S}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else g+=b;x+=p,p=""}l||c.push(n(i))}c.length&&o.push({...n(a),fragments:c})}return o}_draw(e){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),e.forEach(n=>{n.style.backgroundColor&&(t.fillStyle=n.style.backgroundColor,t.fillRect(n.lineBox.left,n.lineBox.top,n.lineBox.width,n.lineBox.height))}),e.forEach(n=>{n.fragments.forEach(o=>{switch(o.style.backgroundColor&&(t.fillStyle=o.style.backgroundColor,t.fillRect(o.inlineBox.left,o.inlineBox.top,o.inlineBox.width,o.inlineBox.height)),this._setContextStyle({...o.style,textAlign:"left",verticalAlign:"top"}),o.style.textStrokeWidth&&t.strokeText(o.content,o.contentBox.left,o.contentBox.top),t.fillText(o.content,o.contentBox.left,o.contentBox.top),o.style.textDecoration){case"underline":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height-2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(o.contentBox.left,o.contentBox.top+o.contentBox.height/2),t.lineTo(o.contentBox.left+o.contentBox.width,o.contentBox.top+o.contentBox.height/2),t.stroke();break}})})}_resizeView(e,t){const n=this.view;n.style.width=`${e}px`,n.style.height=`${t}px`,n.dataset.width=String(e),n.dataset.height=String(t),n.width=Math.max(1,Math.floor(e*this.pixelRatio)),n.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(e){const t=this.context;switch(t.shadowColor=e.shadowColor,t.shadowOffsetX=e.shadowOffsetX,t.shadowOffsetY=e.shadowOffsetY,t.shadowBlur=e.shadowBlur,t.strokeStyle=e.textStrokeColor,t.lineWidth=e.textStrokeWidth,t.fillStyle=e.color,t.direction=e.direction,t.textAlign=e.textAlign,e.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=e.verticalAlign;break}t.font=[e.fontStyle,e.fontWeight,`${e.fontSize}px`,e.fontFamily].join(" "),t.fontKerning=e.fontKerning,t.letterSpacing=`${e.letterSpacing}px`}update(){const e=this.context;let{width:t,height:n}=this.style;t==="auto"&&(t=0),n==="auto"&&(n=0);const{contentBox:o,paragraphs:h}=this.measure();t||(t=o.width),n=Math.max(n,o.height),this._resizeView(t,n);const a=this.pixelRatio;e.scale(a,a),e.clearRect(0,0,e.canvas.width,e.canvas.height),this._draw(h)}};d.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let f=d;u.Text=f,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -12,6 +12,7 @@ const d = class d {
12
12
  textWrap: "wrap",
13
13
  textAlign: "start",
14
14
  verticalAlign: "baseline",
15
+ textTransform: "none",
15
16
  textDecoration: null,
16
17
  textStrokeWidth: 0,
17
18
  textStrokeColor: "#000000",
@@ -65,16 +66,16 @@ const d = class d {
65
66
  let o = 0;
66
67
  for (let h = t.length, c = 0; c < h; c++) {
67
68
  const i = t[c], s = [];
68
- let B = 0, a = null;
69
+ let g = 0, a = null;
69
70
  for (const l of i.fragments) {
70
71
  this._setContextStyle({
71
72
  ...l.style,
72
73
  textAlign: "center",
73
74
  verticalAlign: "baseline"
74
75
  });
75
- const r = n.measureText(l.content), p = r.width, f = l.style.fontSize;
76
+ const B = n.measureText(l.content), p = B.width, f = l.style.fontSize;
76
77
  l.inlineBox = this._createBox(
77
- B,
78
+ g,
78
79
  o,
79
80
  p,
80
81
  f * l.style.lineHeight
@@ -84,13 +85,13 @@ const d = class d {
84
85
  p,
85
86
  f
86
87
  );
87
- const w = r.fontBoundingBoxAscent + r.fontBoundingBoxDescent, y = r.actualBoundingBoxLeft + r.actualBoundingBoxRight, u = r.actualBoundingBoxAscent + r.actualBoundingBoxDescent;
88
- l.baseline = l.inlineBox.top + (l.inlineBox.height - w) / 2 + r.fontBoundingBoxAscent, l.glyphBox = this._createBox(
88
+ const w = B.fontBoundingBoxAscent + B.fontBoundingBoxDescent, y = B.actualBoundingBoxLeft + B.actualBoundingBoxRight, u = B.actualBoundingBoxAscent + B.actualBoundingBoxDescent;
89
+ l.baseline = l.inlineBox.top + (l.inlineBox.height - w) / 2 + B.fontBoundingBoxAscent, l.glyphBox = this._createBox(
89
90
  l.contentBox.left,
90
- l.baseline - r.actualBoundingBoxAscent,
91
+ l.baseline - B.actualBoundingBoxAscent,
91
92
  y,
92
93
  u
93
- ), l.centerX = l.glyphBox.left + r.actualBoundingBoxLeft, B += l.contentBox.width, s.push(l.contentBox), i.contentBox = this._mergeBoxes(s), i.contentBox.height < l.contentBox.height && (a = l);
94
+ ), l.centerX = l.glyphBox.left + B.actualBoundingBoxLeft, g += l.contentBox.width, s.push(l.contentBox), i.contentBox = this._mergeBoxes(s), i.contentBox.height < l.contentBox.height && (a = l);
94
95
  }
95
96
  i.lineBox = this._mergeBoxes([
96
97
  ...i.fragments.map((l) => l.inlineBox),
@@ -100,26 +101,26 @@ const d = class d {
100
101
  textAlign: "left",
101
102
  verticalAlign: "baseline"
102
103
  });
103
- const g = n.measureText("x"), x = g.fontBoundingBoxAscent + g.fontBoundingBoxDescent;
104
- i.xHeight = g.actualBoundingBoxAscent, i.baseline = i.lineBox.top + (i.lineBox.height - x) / 2 + g.fontBoundingBoxAscent, o += i.lineBox.height;
104
+ const r = n.measureText("x"), x = r.fontBoundingBoxAscent + r.fontBoundingBoxDescent;
105
+ i.xHeight = r.actualBoundingBoxAscent, i.baseline = i.lineBox.top + (i.lineBox.height - x) / 2 + r.fontBoundingBoxAscent, o += i.lineBox.height;
105
106
  }
106
107
  for (let h = t.length, c = 0; c < h; c++) {
107
108
  const i = t[c];
108
109
  i.fragments.forEach((s) => {
109
- const B = s.inlineBox.left, a = s.inlineBox.top;
110
- let g, x = a;
110
+ const g = s.inlineBox.left, a = s.inlineBox.top;
111
+ let r, x = a;
111
112
  switch (s.style.textAlign) {
112
113
  case "end":
113
114
  case "right":
114
- g = B + (i.lineBox.width - i.contentBox.width);
115
+ r = g + (i.lineBox.width - i.contentBox.width);
115
116
  break;
116
117
  case "center":
117
- g = B + (i.lineBox.width - i.contentBox.width) / 2;
118
+ r = g + (i.lineBox.width - i.contentBox.width) / 2;
118
119
  break;
119
120
  case "start":
120
121
  case "left":
121
122
  default:
122
- g = B + i.lineBox.left;
123
+ r = g + i.lineBox.left;
123
124
  break;
124
125
  }
125
126
  switch (s.style.verticalAlign) {
@@ -149,8 +150,8 @@ const d = class d {
149
150
  s.inlineBox.height < i.lineBox.height && (x = a + (i.baseline - s.baseline));
150
151
  break;
151
152
  }
152
- const l = g - B, r = x - a;
153
- this._moveBox(s.inlineBox, l, r), this._moveBox(s.contentBox, l, r), this._moveBox(s.glyphBox, l, r), s.baseline += r, s.centerX += l;
153
+ const l = r - g, B = x - a;
154
+ this._moveBox(s.inlineBox, l, B), this._moveBox(s.contentBox, l, B), this._moveBox(s.glyphBox, l, B), s.baseline += B, s.centerX += l;
154
155
  }), i.contentBox = this._mergeBoxes(i.fragments.map((s) => s.contentBox)), i.glyphBox = this._mergeBoxes(i.fragments.map((s) => s.glyphBox));
155
156
  }
156
157
  return {
@@ -176,7 +177,19 @@ const d = class d {
176
177
  }
177
178
  };
178
179
  }, n = (h = {}) => {
179
- const c = [], { width: i, height: s, ...B } = this.style;
180
+ const c = [], { width: i, height: s, ...g } = this.style, a = {
181
+ ...g,
182
+ ...h.style
183
+ };
184
+ let r = h.content ?? "";
185
+ switch (a.textTransform) {
186
+ case "uppercase":
187
+ r = r.toUpperCase();
188
+ break;
189
+ case "lowercase":
190
+ r = r.toLowerCase();
191
+ break;
192
+ }
180
193
  return c.push({
181
194
  contentBox: this._createBox(),
182
195
  inlineBox: this._createBox(),
@@ -184,11 +197,8 @@ const d = class d {
184
197
  centerX: 0,
185
198
  baseline: 0,
186
199
  ...h,
187
- style: {
188
- ...B,
189
- ...h.style
190
- },
191
- content: h.content ?? ""
200
+ style: a,
201
+ content: r
192
202
  }), c;
193
203
  }, o = [];
194
204
  if (typeof e == "string")
@@ -198,9 +208,9 @@ const d = class d {
198
208
  for (const h of e)
199
209
  if ("fragments" in h) {
200
210
  const { fragments: c, ...i } = h, s = t({ style: i });
201
- for (const B of c) {
202
- const { content: a, ...g } = B;
203
- s.fragments.push(...n({ content: a, style: { ...i, ...g } }));
211
+ for (const g of c) {
212
+ const { content: a, ...r } = g;
213
+ s.fragments.push(...n({ content: a, style: { ...i, ...r } }));
204
214
  }
205
215
  o.push(s);
206
216
  } else if ("content" in h) {
@@ -215,19 +225,19 @@ const d = class d {
215
225
  let c, i;
216
226
  for (; c = h.shift(); ) {
217
227
  const s = c.fragments.slice();
218
- let B = 0;
228
+ let g = 0;
219
229
  const a = [];
220
230
  for (; i = s.shift(); ) {
221
- const g = i.style;
222
- this._setContextStyle(g);
223
- let x = "", l = !1, r = 0, p = "";
231
+ const r = i.style;
232
+ this._setContextStyle(r);
233
+ let x = "", l = !1, B = 0, p = "";
224
234
  for (const f of i.content) {
225
- if (p += f, d.punctuationRegex.test(i.content[++r]))
235
+ if (p += f, d.punctuationRegex.test(i.content[++B]))
226
236
  continue;
227
237
  const w = this.context.measureText(p).width, y = /^[\r\n]$/.test(p);
228
- if (y || g.textWrap === "wrap" && t && B + w > t) {
238
+ if (y || r.textWrap === "wrap" && t && g + w > t) {
229
239
  let u = y ? x.length + 1 : x.length;
230
- !B && !u && (x += p, u += p.length), x.length && a.push({ ...n(i), content: x }), a.length && (o.push({ ...n(c), fragments: a.slice() }), a.length = 0);
240
+ !g && !u && (x += p, u += p.length), x.length && a.push({ ...n(i), content: x }), a.length && (o.push({ ...n(c), fragments: a.slice() }), a.length = 0);
231
241
  const b = i.content.substring(u);
232
242
  (b.length || s.length) && h.unshift({
233
243
  ...n(c),
@@ -235,7 +245,7 @@ const d = class d {
235
245
  }), s.length = 0, l = !0;
236
246
  break;
237
247
  } else
238
- B += w;
248
+ g += w;
239
249
  x += p, p = "";
240
250
  }
241
251
  l || a.push(n(i));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-text",
3
3
  "type": "module",
4
- "version": "0.0.16",
4
+ "version": "0.0.17",
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",
package/types/Text.d.ts CHANGED
@@ -5,6 +5,7 @@ export type TextWrap = 'wrap' | 'nowrap';
5
5
  export type TextAlign = 'center' | 'end' | 'left' | 'right' | 'start';
6
6
  export type VerticalAlign = 'baseline' | 'top' | 'middle' | 'bottom' | 'sub' | 'super' | 'text-top' | 'text-bottom';
7
7
  export type TextDecoration = 'underline' | 'line-through';
8
+ export type TextTransform = 'uppercase' | 'lowercase' | 'none';
8
9
  export interface BoundingBox {
9
10
  left: number;
10
11
  right: number;
@@ -42,6 +43,7 @@ export interface TextFragmentStyle {
42
43
  textWrap: TextWrap;
43
44
  textAlign: TextAlign;
44
45
  verticalAlign: VerticalAlign;
46
+ textTransform: TextTransform;
45
47
  textDecoration: TextDecoration | null;
46
48
  textStrokeWidth: number;
47
49
  textStrokeColor: string;