modern-text 0.0.13 → 0.0.14

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 y=class y{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={...y.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 x=n.measureText(l.content),d=x.width,p=l.style.fontSize;l.inlineBox=this._createBox(B,o,d,p*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-p)/2,d,p);const u=x.fontBoundingBoxAscent+x.fontBoundingBoxDescent,f=x.actualBoundingBoxLeft+x.actualBoundingBoxRight,b=x.actualBoundingBoxAscent+x.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-u)/2+x.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left+(l.contentBox.width-f)/2,l.baseline-x.actualBoundingBoxAscent,f,b),l.centerX=l.glyphBox.left+x.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"),r=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-r)/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,r=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":r=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":r=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":r=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":r=a+(i.baseline-s.glyphBox.bottom);break;case"super":r=a+(i.baseline-s.glyphBox.top);break;case"text-top":r=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":r=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(r=a+(i.baseline-s.baseline));break}const l=g-B,x=r-a;this._moveBox(s.inlineBox,l,x),this._moveBox(s.contentBox,l,x),this._moveBox(s.glyphBox,l,x),s.baseline+=x,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 r="",l=!1;for(const x of i.content){const d=this.context.measureText(x).width,p=/^[\r\n]$/.test(x);if(p||g.textWrap==="wrap"&&t&&B+d>t){let u=p?r.length+1:r.length;!B&&!u&&(r+=x,u++),r.length&&a.push({...n(i),content:r}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const f=i.content.substring(u);(f.length||s.length)&&h.unshift({...n(c),fragments:(f.length?[{...n(i),content:f}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else B+=d;r+=x}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)}};y.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let w=y;exports.Text=w;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=class y{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={...y.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 x=n.measureText(l.content),p=x.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 w=x.fontBoundingBoxAscent+x.fontBoundingBoxDescent,u=x.actualBoundingBoxLeft+x.actualBoundingBoxRight,d=x.actualBoundingBoxAscent+x.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-w)/2+x.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left+(l.contentBox.width-u)/2,l.baseline-x.actualBoundingBoxAscent,u,d),l.centerX=l.glyphBox.left+x.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"),r=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-r)/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,r=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":r=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":r=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":r=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":r=a+(i.baseline-s.glyphBox.bottom);break;case"super":r=a+(i.baseline-s.glyphBox.top);break;case"text-top":r=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":r=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(r=a+(i.baseline-s.baseline));break}const l=g-B,x=r-a;this._moveBox(s.inlineBox,l,x),this._moveBox(s.contentBox,l,x),this._moveBox(s.glyphBox,l,x),s.baseline+=x,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 r="",l=!1,x=0,p="";for(const f of i.content){if(y.punctuationRegex.test(i.content[x+1])){x++,p=f;continue}else x++,p+=f;const w=this.context.measureText(p).width,u=/^[\r\n]$/.test(p);if(u||g.textWrap==="wrap"&&t&&B+w>t){let d=u?r.length+1:r.length;!B&&!d&&(r+=p,d+=p.length),r.length&&a.push({...n(i),content:r}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const b=i.content.substring(d);(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+=w;r+=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)}};y.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let _=y;exports.Text=_;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(f,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(f=typeof globalThis<"u"?globalThis:f||self,p(f.modernText={}))})(this,function(f){"use strict";const b=class b{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={...b.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 x=n.measureText(l.content),y=x.width,d=l.style.fontSize;l.inlineBox=this._createBox(B,o,y,d*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-d)/2,y,d);const w=x.fontBoundingBoxAscent+x.fontBoundingBoxDescent,u=x.actualBoundingBoxLeft+x.actualBoundingBoxRight,_=x.actualBoundingBoxAscent+x.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-w)/2+x.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left+(l.contentBox.width-u)/2,l.baseline-x.actualBoundingBoxAscent,u,_),l.centerX=l.glyphBox.left+x.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"),r=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-r)/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,r=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":r=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":r=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":r=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":r=a+(i.baseline-s.glyphBox.bottom);break;case"super":r=a+(i.baseline-s.glyphBox.top);break;case"text-top":r=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":r=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(r=a+(i.baseline-s.baseline));break}const l=g-B,x=r-a;this._moveBox(s.inlineBox,l,x),this._moveBox(s.contentBox,l,x),this._moveBox(s.glyphBox,l,x),s.baseline+=x,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 r="",l=!1;for(const x of i.content){const y=this.context.measureText(x).width,d=/^[\r\n]$/.test(x);if(d||g.textWrap==="wrap"&&t&&B+y>t){let w=d?r.length+1:r.length;!B&&!w&&(r+=x,w++),r.length&&a.push({...n(i),content:r}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const u=i.content.substring(w);(u.length||s.length)&&h.unshift({...n(c),fragments:(u.length?[{...n(i),content:u}]:[]).concat(s.slice())}),s.length=0,l=!0;break}else B+=y;r+=x}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)}};b.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let p=b;f.Text=p,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
1
+ (function(d,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(d=typeof globalThis<"u"?globalThis:d||self,f(d.modernText={}))})(this,function(d){"use strict";const y=class y{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={...y.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 x=n.measureText(l.content),p=x.width,u=l.style.fontSize;l.inlineBox=this._createBox(B,o,p,u*l.style.lineHeight),l.contentBox=this._createBox(l.inlineBox.left,l.inlineBox.top+(l.inlineBox.height-u)/2,p,u);const _=x.fontBoundingBoxAscent+x.fontBoundingBoxDescent,w=x.actualBoundingBoxLeft+x.actualBoundingBoxRight,b=x.actualBoundingBoxAscent+x.actualBoundingBoxDescent;l.baseline=l.inlineBox.top+(l.inlineBox.height-_)/2+x.fontBoundingBoxAscent,l.glyphBox=this._createBox(l.contentBox.left+(l.contentBox.width-w)/2,l.baseline-x.actualBoundingBoxAscent,w,b),l.centerX=l.glyphBox.left+x.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"),r=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent;i.xHeight=g.actualBoundingBoxAscent,i.baseline=i.lineBox.top+(i.lineBox.height-r)/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,r=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":r=a+(i.lineBox.top-s.inlineBox.top);break;case"middle":r=i.baseline-i.xHeight/2-s.inlineBox.height/2;break;case"bottom":r=a+(i.lineBox.bottom-s.inlineBox.bottom);break;case"sub":r=a+(i.baseline-s.glyphBox.bottom);break;case"super":r=a+(i.baseline-s.glyphBox.top);break;case"text-top":r=a+(i.glyphBox.top-s.inlineBox.top);break;case"text-bottom":r=a+(i.glyphBox.bottom-s.inlineBox.bottom);break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(r=a+(i.baseline-s.baseline));break}const l=g-B,x=r-a;this._moveBox(s.inlineBox,l,x),this._moveBox(s.contentBox,l,x),this._moveBox(s.glyphBox,l,x),s.baseline+=x,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 r="",l=!1,x=0,p="";for(const u of i.content){if(y.punctuationRegex.test(i.content[x+1])){x++,p=u;continue}else x++,p+=u;const _=this.context.measureText(p).width,w=/^[\r\n]$/.test(p);if(w||g.textWrap==="wrap"&&t&&B+_>t){let b=w?r.length+1:r.length;!B&&!b&&(r+=p,b+=p.length),r.length&&a.push({...n(i),content:r}),a.length&&(o.push({...n(c),fragments:a.slice()}),a.length=0);const S=i.content.substring(b);(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+=_;r+=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)}};y.punctuationRegex=/[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;let f=y;d.Text=f,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -72,24 +72,24 @@ const w = class w {
72
72
  textAlign: "center",
73
73
  verticalAlign: "baseline"
74
74
  });
75
- const x = n.measureText(l.content), d = x.width, p = l.style.fontSize;
75
+ const x = n.measureText(l.content), p = x.width, f = l.style.fontSize;
76
76
  l.inlineBox = this._createBox(
77
77
  B,
78
78
  o,
79
- d,
80
- p * l.style.lineHeight
79
+ p,
80
+ f * l.style.lineHeight
81
81
  ), l.contentBox = this._createBox(
82
82
  l.inlineBox.left,
83
- l.inlineBox.top + (l.inlineBox.height - p) / 2,
84
- d,
85
- p
83
+ l.inlineBox.top + (l.inlineBox.height - f) / 2,
84
+ p,
85
+ f
86
86
  );
87
- const u = x.fontBoundingBoxAscent + x.fontBoundingBoxDescent, f = x.actualBoundingBoxLeft + x.actualBoundingBoxRight, b = x.actualBoundingBoxAscent + x.actualBoundingBoxDescent;
88
- l.baseline = l.inlineBox.top + (l.inlineBox.height - u) / 2 + x.fontBoundingBoxAscent, l.glyphBox = this._createBox(
89
- l.contentBox.left + (l.contentBox.width - f) / 2,
87
+ const y = x.fontBoundingBoxAscent + x.fontBoundingBoxDescent, u = x.actualBoundingBoxLeft + x.actualBoundingBoxRight, d = x.actualBoundingBoxAscent + x.actualBoundingBoxDescent;
88
+ l.baseline = l.inlineBox.top + (l.inlineBox.height - y) / 2 + x.fontBoundingBoxAscent, l.glyphBox = this._createBox(
89
+ l.contentBox.left + (l.contentBox.width - u) / 2,
90
90
  l.baseline - x.actualBoundingBoxAscent,
91
- f,
92
- b
91
+ u,
92
+ d
93
93
  ), l.centerX = l.glyphBox.left + x.actualBoundingBoxLeft, B += l.contentBox.width, s.push(l.contentBox), i.contentBox = this._mergeBoxes(s), i.contentBox.height < l.contentBox.height && (a = l);
94
94
  }
95
95
  i.lineBox = this._mergeBoxes([
@@ -220,24 +220,26 @@ const w = class w {
220
220
  for (; i = s.shift(); ) {
221
221
  const g = i.style;
222
222
  this._setContextStyle(g);
223
- let r = "", l = !1;
224
- for (const x of i.content) {
225
- const d = this.context.measureText(x).width, p = /^[\r\n]$/.test(x);
226
- if (p || g.textWrap === "wrap" && t && B + d > t) {
227
- let u = p ? r.length + 1 : r.length;
228
- !B && !u && (r += x, u++), r.length && a.push({ ...n(i), content: r }), a.length && (o.push({
229
- ...n(c),
230
- fragments: a.slice()
231
- }), a.length = 0);
232
- const f = i.content.substring(u);
233
- (f.length || s.length) && h.unshift({
223
+ let r = "", l = !1, x = 0, p = "";
224
+ for (const f of i.content) {
225
+ if (w.punctuationRegex.test(i.content[x + 1])) {
226
+ x++, p = f;
227
+ continue;
228
+ } else
229
+ x++, p += f;
230
+ const y = this.context.measureText(p).width, u = /^[\r\n]$/.test(p);
231
+ if (u || g.textWrap === "wrap" && t && B + y > t) {
232
+ let d = u ? r.length + 1 : r.length;
233
+ !B && !d && (r += p, d += p.length), r.length && a.push({ ...n(i), content: r }), a.length && (o.push({ ...n(c), fragments: a.slice() }), a.length = 0);
234
+ const b = i.content.substring(d);
235
+ (b.length || s.length) && h.unshift({
234
236
  ...n(c),
235
- fragments: (f.length ? [{ ...n(i), content: f }] : []).concat(s.slice())
237
+ fragments: (b.length ? [{ ...n(i), content: b }] : []).concat(s.slice())
236
238
  }), s.length = 0, l = !0;
237
239
  break;
238
240
  } else
239
- B += d;
240
- r += x;
241
+ B += y;
242
+ r += p, p = "";
241
243
  }
242
244
  l || a.push(n(i));
243
245
  }
@@ -300,7 +302,7 @@ const w = class w {
300
302
  }
301
303
  };
302
304
  w.punctuationRegex = /[\s\n\t\u200B\u200C\u200D\u200E\u200F.,?!:;"'(){}\[\]<>\/\\|~#\$%\*\+=&^,。?!:;“”‘’()【】《》……——]/;
303
- let y = w;
305
+ let _ = w;
304
306
  export {
305
- y as Text
307
+ _ as Text
306
308
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-text",
3
3
  "type": "module",
4
- "version": "0.0.13",
4
+ "version": "0.0.14",
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",