modern-text 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +107 -106
- package/package.json +1 -1
- package/types/Text.d.ts +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class w{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(
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class w{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(n={}){const{view:t=document.createElement("canvas"),pixelRatio:l=window.devicePixelRatio||1,content:e="",style:a}=n;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=l,this.content=e,this.style={...w.defaultStyle,...a},this.update()}measure(){let{width:n}=this.style;n==="auto"&&(n=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,n);const l=this.context;let e=0;for(let h=t.length,c=0;c<h;c++){const i=t[c];i.contentBox.top=e;let s=0,d=null;for(const o of i.fragments){this._setContextStyle({...o.style,textAlign:"center",verticalAlign:"baseline"});const B=l.measureText(o.content),p=B.width,f=o.style.fontSize;o.inlineBox.left=s,o.inlineBox.top=e,o.inlineBox.width=p,o.inlineBox.height=f*o.style.lineHeight,o.contentBox.left=o.inlineBox.left,o.contentBox.width=p,o.contentBox.height=f,o.contentBox.top=o.inlineBox.top+(o.inlineBox.height-o.contentBox.height)/2,o.glyphBox.width=B.actualBoundingBoxLeft+B.actualBoundingBoxRight,o.glyphBox.height=B.actualBoundingBoxAscent+B.actualBoundingBoxDescent,o.glyphBox.left=o.contentBox.left+(o.contentBox.width-o.glyphBox.width)/2,o.glyphBox.top=o.contentBox.top+(o.contentBox.height-o.glyphBox.height)/2,o.centerX=o.glyphBox.left+B.actualBoundingBoxLeft,o.baseline=o.glyphBox.top+B.actualBoundingBoxAscent,s+=o.contentBox.width+o.style.letterSpacing,i.contentBox.height<o.contentBox.height&&(d=o),i.contentBox.left=Math.min(i.contentBox.left,o.contentBox.left),i.contentBox.top=Math.min(i.contentBox.top,o.contentBox.top),i.contentBox.height=Math.max(i.contentBox.height,o.contentBox.height),i.lineBox.height=Math.max(i.lineBox.height,o.inlineBox.height)}const r=i.fragments[i.fragments.length-1];i.contentBox.width=Math.max(i.contentBox.width,r?r.contentBox.left+Math.max(r.contentBox.width,r.glyphBox.width):0),i.lineBox.left=0,i.lineBox.top=e,i.lineBox.width=Math.max(n,i.contentBox.width),this._setContextStyle({...(d??i).style,textAlign:"left",verticalAlign:"baseline"});const g=l.measureText("X");i.baseline=i.lineBox.top+(i.lineBox.height-g.actualBoundingBoxAscent+g.actualBoundingBoxDescent)/2+g.actualBoundingBoxAscent,e+=i.lineBox.height}for(let h=t.length,c=0;c<h;c++){const i=t[c];i.fragments.forEach(s=>{const d=s.inlineBox.left,r=s.inlineBox.top,g=i.lineBox.height-s.inlineBox.height;switch(s.style.textAlign){case"end":case"right":s.inlineBox.left+=i.lineBox.width-i.contentBox.width;break;case"center":s.inlineBox.left+=(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:s.inlineBox.left+=i.lineBox.left;break}switch(s.style.verticalAlign){case"top":s.inlineBox.top=i.lineBox.top;break;case"middle":s.inlineBox.top=i.lineBox.top+g/2;break;case"bottom":s.inlineBox.top=i.lineBox.top+g;break;case"sub":case"text-top":case"text-bottom":break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(s.inlineBox.top+=i.baseline-s.baseline);break}const o=s.inlineBox.left-d,B=s.inlineBox.top-r;s.contentBox.left+=o,s.contentBox.top+=B,s.glyphBox.left+=o,s.glyphBox.top+=B,s.baseline+=B,s.centerX+=o})}const a=t.reduce((h,c)=>(h.left=Math.min(h.left,c.contentBox.left),h.top=Math.min(h.top,c.contentBox.top),h.width=Math.max(h.width,c.contentBox.width),h.height+=c.contentBox.height,h),{left:0,top:0,width:0,height:0});return{contentBox:t.reduce((h,c)=>(h.left=Math.min(h.left,c.lineBox.left),h.top=Math.min(h.top,c.lineBox.top),h.width=Math.max(h.width,c.lineBox.width),h.height+=c.lineBox.height,h),{left:0,top:0,width:0,height:0}),actualContentBox:a,paragraphs:t}}_createParagraphs(n){const t=(a={})=>{const{width:x,height:h,...c}=this.style;return{contentBox:{left:0,top:0,width:0,height:0},lineBox:{left:0,top:0,width:0,height:0},baseline:0,fragments:[],...a,style:{...c,...a.style}}},l=(a={})=>{const x=[],{width:h,height:c,...i}=this.style;return x.push({contentBox:{left:0,top:0,width:0,height:0},inlineBox:{left:0,top:0,width:0,height:0},glyphBox:{left:0,top:0,width:0,height:0},centerX:0,baseline:0,...a,style:{...i,...a.style},content:a.content??""}),x},e=[];if(typeof n=="string")e.push(t({fragments:l({content:n})}));else{n=Array.isArray(n)?n:[n];for(const a of n)if("fragments"in a){const{fragments:x,...h}=a,c=t({style:h});for(const i of x){const{content:s,...d}=i;c.fragments.push(...l({content:s,style:{...h,...d}}))}e.push(c)}else if("content"in a){const{content:x,...h}=a,c=t({style:h});c.fragments.push(...l({content:x,style:h})),e.push(c)}}return e}_createWrapedParagraphs(n,t){const l=c=>JSON.parse(JSON.stringify(c)),e=[],a=n.slice();let x,h;for(;x=a.shift();){const c=x.fragments.slice();let i=0;const s=[];for(;h=c.shift();){const d=h.style;this._setContextStyle(d);let r="",g=!1;for(const o of h.content){const B=this.context.measureText(o).width,p=/^[\r\n]$/.test(o);if(p||d.textWrap==="wrap"&&t&&i+B>t){let f=p?r.length+1:r.length;!i&&!f&&(r+=o,f++),r.length&&s.push({...l(h),content:r}),s.length&&(e.push({...l(x),fragments:s.slice()}),s.length=0);const u=h.content.substring(f);(u.length||c.length)&&a.unshift({...l(x),fragments:(u.length?[{...l(h),content:u}]:[]).concat(c.slice())}),c.length=0,g=!0;break}else i+=B;r+=o}g||s.push(l(h))}s.length&&e.push({...l(x),fragments:s})}return e}_draw(n){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),n.forEach(l=>{l.style.backgroundColor&&(t.fillStyle=l.style.backgroundColor,t.fillRect(l.lineBox.left,l.lineBox.top,l.lineBox.width,l.lineBox.height))}),n.forEach(l=>{l.fragments.forEach(e=>{switch(e.style.backgroundColor&&(t.fillStyle=e.style.backgroundColor,t.fillRect(e.inlineBox.left,e.inlineBox.top,e.inlineBox.width,e.inlineBox.height)),this._setContextStyle({...e.style,textAlign:"left",verticalAlign:"top"}),e.style.textStrokeWidth&&t.strokeText(e.content,e.contentBox.left,e.contentBox.top),t.fillText(e.content,e.contentBox.left,e.contentBox.top),e.style.textDecoration){case"underline":t.beginPath(),t.moveTo(e.contentBox.left,e.contentBox.top+e.contentBox.height-2),t.lineTo(e.contentBox.left+e.contentBox.width,e.contentBox.top+e.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(e.contentBox.left,e.contentBox.top+e.contentBox.height/2),t.lineTo(e.contentBox.left+e.contentBox.width,e.contentBox.top+e.contentBox.height/2),t.stroke();break}})})}_resizeView(n,t){const l=this.view;l.style.width=`${n}px`,l.style.height=`${t}px`,l.dataset.width=String(n),l.dataset.height=String(t),l.width=Math.max(1,Math.floor(n*this.pixelRatio)),l.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(n){const t=this.context;switch(t.shadowColor=n.shadowColor,t.shadowOffsetX=n.shadowOffsetX,t.shadowOffsetY=n.shadowOffsetY,t.shadowBlur=n.shadowBlur,t.strokeStyle=n.textStrokeColor,t.lineWidth=n.textStrokeWidth,t.fillStyle=n.color,t.direction=n.direction,t.textAlign=n.textAlign,n.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=n.verticalAlign;break}t.font=[n.fontStyle,n.fontWeight,`${n.fontSize}px`,n.fontFamily].join(" "),t.fontKerning=n.fontKerning,t.letterSpacing=`${n.letterSpacing}px`}update(){const n=this.context;let{width:t,height:l}=this.style;t==="auto"&&(t=0),l==="auto"&&(l=0);const{contentBox:e,paragraphs:a}=this.measure();t||(t=e.width),l=Math.max(l,e.height),this._resizeView(t,l);const x=this.pixelRatio;n.scale(x,x),n.clearRect(0,0,n.canvas.width,n.canvas.height),this._draw(a)}}exports.Text=w;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(p,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(p=typeof globalThis<"u"?globalThis:p||self,g(p.modernText={}))})(this,function(p){"use strict";class g{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(
|
|
1
|
+
(function(p,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(p=typeof globalThis<"u"?globalThis:p||self,g(p.modernText={}))})(this,function(p){"use strict";class g{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(n={}){const{view:t=document.createElement("canvas"),pixelRatio:l=window.devicePixelRatio||1,content:e="",style:a}=n;this.view=t,this.context=t.getContext("2d"),this.pixelRatio=l,this.content=e,this.style={...g.defaultStyle,...a},this.update()}measure(){let{width:n}=this.style;n==="auto"&&(n=0);let t=this._createParagraphs(this.content);t=this._createWrapedParagraphs(t,n);const l=this.context;let e=0;for(let h=t.length,c=0;c<h;c++){const i=t[c];i.contentBox.top=e;let s=0,d=null;for(const o of i.fragments){this._setContextStyle({...o.style,textAlign:"center",verticalAlign:"baseline"});const B=l.measureText(o.content),w=B.width,u=o.style.fontSize;o.inlineBox.left=s,o.inlineBox.top=e,o.inlineBox.width=w,o.inlineBox.height=u*o.style.lineHeight,o.contentBox.left=o.inlineBox.left,o.contentBox.width=w,o.contentBox.height=u,o.contentBox.top=o.inlineBox.top+(o.inlineBox.height-o.contentBox.height)/2,o.glyphBox.width=B.actualBoundingBoxLeft+B.actualBoundingBoxRight,o.glyphBox.height=B.actualBoundingBoxAscent+B.actualBoundingBoxDescent,o.glyphBox.left=o.contentBox.left+(o.contentBox.width-o.glyphBox.width)/2,o.glyphBox.top=o.contentBox.top+(o.contentBox.height-o.glyphBox.height)/2,o.centerX=o.glyphBox.left+B.actualBoundingBoxLeft,o.baseline=o.glyphBox.top+B.actualBoundingBoxAscent,s+=o.contentBox.width+o.style.letterSpacing,i.contentBox.height<o.contentBox.height&&(d=o),i.contentBox.left=Math.min(i.contentBox.left,o.contentBox.left),i.contentBox.top=Math.min(i.contentBox.top,o.contentBox.top),i.contentBox.height=Math.max(i.contentBox.height,o.contentBox.height),i.lineBox.height=Math.max(i.lineBox.height,o.inlineBox.height)}const r=i.fragments[i.fragments.length-1];i.contentBox.width=Math.max(i.contentBox.width,r?r.contentBox.left+Math.max(r.contentBox.width,r.glyphBox.width):0),i.lineBox.left=0,i.lineBox.top=e,i.lineBox.width=Math.max(n,i.contentBox.width),this._setContextStyle({...(d??i).style,textAlign:"left",verticalAlign:"baseline"});const f=l.measureText("X");i.baseline=i.lineBox.top+(i.lineBox.height-f.actualBoundingBoxAscent+f.actualBoundingBoxDescent)/2+f.actualBoundingBoxAscent,e+=i.lineBox.height}for(let h=t.length,c=0;c<h;c++){const i=t[c];i.fragments.forEach(s=>{const d=s.inlineBox.left,r=s.inlineBox.top,f=i.lineBox.height-s.inlineBox.height;switch(s.style.textAlign){case"end":case"right":s.inlineBox.left+=i.lineBox.width-i.contentBox.width;break;case"center":s.inlineBox.left+=(i.lineBox.width-i.contentBox.width)/2;break;case"start":case"left":default:s.inlineBox.left+=i.lineBox.left;break}switch(s.style.verticalAlign){case"top":s.inlineBox.top=i.lineBox.top;break;case"middle":s.inlineBox.top=i.lineBox.top+f/2;break;case"bottom":s.inlineBox.top=i.lineBox.top+f;break;case"sub":case"text-top":case"text-bottom":break;case"baseline":default:s.inlineBox.height<i.lineBox.height&&(s.inlineBox.top+=i.baseline-s.baseline);break}const o=s.inlineBox.left-d,B=s.inlineBox.top-r;s.contentBox.left+=o,s.contentBox.top+=B,s.glyphBox.left+=o,s.glyphBox.top+=B,s.baseline+=B,s.centerX+=o})}const a=t.reduce((h,c)=>(h.left=Math.min(h.left,c.contentBox.left),h.top=Math.min(h.top,c.contentBox.top),h.width=Math.max(h.width,c.contentBox.width),h.height+=c.contentBox.height,h),{left:0,top:0,width:0,height:0});return{contentBox:t.reduce((h,c)=>(h.left=Math.min(h.left,c.lineBox.left),h.top=Math.min(h.top,c.lineBox.top),h.width=Math.max(h.width,c.lineBox.width),h.height+=c.lineBox.height,h),{left:0,top:0,width:0,height:0}),actualContentBox:a,paragraphs:t}}_createParagraphs(n){const t=(a={})=>{const{width:x,height:h,...c}=this.style;return{contentBox:{left:0,top:0,width:0,height:0},lineBox:{left:0,top:0,width:0,height:0},baseline:0,fragments:[],...a,style:{...c,...a.style}}},l=(a={})=>{const x=[],{width:h,height:c,...i}=this.style;return x.push({contentBox:{left:0,top:0,width:0,height:0},inlineBox:{left:0,top:0,width:0,height:0},glyphBox:{left:0,top:0,width:0,height:0},centerX:0,baseline:0,...a,style:{...i,...a.style},content:a.content??""}),x},e=[];if(typeof n=="string")e.push(t({fragments:l({content:n})}));else{n=Array.isArray(n)?n:[n];for(const a of n)if("fragments"in a){const{fragments:x,...h}=a,c=t({style:h});for(const i of x){const{content:s,...d}=i;c.fragments.push(...l({content:s,style:{...h,...d}}))}e.push(c)}else if("content"in a){const{content:x,...h}=a,c=t({style:h});c.fragments.push(...l({content:x,style:h})),e.push(c)}}return e}_createWrapedParagraphs(n,t){const l=c=>JSON.parse(JSON.stringify(c)),e=[],a=n.slice();let x,h;for(;x=a.shift();){const c=x.fragments.slice();let i=0;const s=[];for(;h=c.shift();){const d=h.style;this._setContextStyle(d);let r="",f=!1;for(const o of h.content){const B=this.context.measureText(o).width,w=/^[\r\n]$/.test(o);if(w||d.textWrap==="wrap"&&t&&i+B>t){let u=w?r.length+1:r.length;!i&&!u&&(r+=o,u++),r.length&&s.push({...l(h),content:r}),s.length&&(e.push({...l(x),fragments:s.slice()}),s.length=0);const y=h.content.substring(u);(y.length||c.length)&&a.unshift({...l(x),fragments:(y.length?[{...l(h),content:y}]:[]).concat(c.slice())}),c.length=0,f=!0;break}else i+=B;r+=o}f||s.push(l(h))}s.length&&e.push({...l(x),fragments:s})}return e}_draw(n){const t=this.context;this.style.backgroundColor&&(t.fillStyle=this.style.backgroundColor,t.fillRect(0,0,t.canvas.width,t.canvas.height)),n.forEach(l=>{l.style.backgroundColor&&(t.fillStyle=l.style.backgroundColor,t.fillRect(l.lineBox.left,l.lineBox.top,l.lineBox.width,l.lineBox.height))}),n.forEach(l=>{l.fragments.forEach(e=>{switch(e.style.backgroundColor&&(t.fillStyle=e.style.backgroundColor,t.fillRect(e.inlineBox.left,e.inlineBox.top,e.inlineBox.width,e.inlineBox.height)),this._setContextStyle({...e.style,textAlign:"left",verticalAlign:"top"}),e.style.textStrokeWidth&&t.strokeText(e.content,e.contentBox.left,e.contentBox.top),t.fillText(e.content,e.contentBox.left,e.contentBox.top),e.style.textDecoration){case"underline":t.beginPath(),t.moveTo(e.contentBox.left,e.contentBox.top+e.contentBox.height-2),t.lineTo(e.contentBox.left+e.contentBox.width,e.contentBox.top+e.contentBox.height-2),t.stroke();break;case"line-through":t.beginPath(),t.moveTo(e.contentBox.left,e.contentBox.top+e.contentBox.height/2),t.lineTo(e.contentBox.left+e.contentBox.width,e.contentBox.top+e.contentBox.height/2),t.stroke();break}})})}_resizeView(n,t){const l=this.view;l.style.width=`${n}px`,l.style.height=`${t}px`,l.dataset.width=String(n),l.dataset.height=String(t),l.width=Math.max(1,Math.floor(n*this.pixelRatio)),l.height=Math.max(1,Math.floor(t*this.pixelRatio))}_setContextStyle(n){const t=this.context;switch(t.shadowColor=n.shadowColor,t.shadowOffsetX=n.shadowOffsetX,t.shadowOffsetY=n.shadowOffsetY,t.shadowBlur=n.shadowBlur,t.strokeStyle=n.textStrokeColor,t.lineWidth=n.textStrokeWidth,t.fillStyle=n.color,t.direction=n.direction,t.textAlign=n.textAlign,n.verticalAlign){case"baseline":t.textBaseline="alphabetic";break;case"top":case"middle":case"bottom":t.textBaseline=n.verticalAlign;break}t.font=[n.fontStyle,n.fontWeight,`${n.fontSize}px`,n.fontFamily].join(" "),t.fontKerning=n.fontKerning,t.letterSpacing=`${n.letterSpacing}px`}update(){const n=this.context;let{width:t,height:l}=this.style;t==="auto"&&(t=0),l==="auto"&&(l=0);const{contentBox:e,paragraphs:a}=this.measure();t||(t=e.width),l=Math.max(l,e.height),this._resizeView(t,l);const x=this.pixelRatio;n.scale(x,x),n.clearRect(0,0,n.canvas.width,n.canvas.height),this._draw(a)}}p.Text=g,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
|
package/dist/index.mjs
CHANGED
|
@@ -24,77 +24,77 @@ class u {
|
|
|
24
24
|
shadowBlur: 0
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(n = {}) {
|
|
28
28
|
const {
|
|
29
29
|
view: t = document.createElement("canvas"),
|
|
30
30
|
pixelRatio: l = window.devicePixelRatio || 1,
|
|
31
31
|
content: e = "",
|
|
32
|
-
style:
|
|
33
|
-
} =
|
|
32
|
+
style: a
|
|
33
|
+
} = n;
|
|
34
34
|
this.view = t, this.context = t.getContext("2d"), this.pixelRatio = l, this.content = e, this.style = {
|
|
35
35
|
...u.defaultStyle,
|
|
36
|
-
...
|
|
36
|
+
...a
|
|
37
37
|
}, this.update();
|
|
38
38
|
}
|
|
39
39
|
measure() {
|
|
40
|
-
let { width:
|
|
41
|
-
|
|
40
|
+
let { width: n } = this.style;
|
|
41
|
+
n === "auto" && (n = 0);
|
|
42
42
|
let t = this._createParagraphs(this.content);
|
|
43
|
-
t = this._createWrapedParagraphs(t,
|
|
43
|
+
t = this._createWrapedParagraphs(t, n);
|
|
44
44
|
const l = this.context;
|
|
45
45
|
let e = 0;
|
|
46
|
-
for (let h = t.length,
|
|
47
|
-
const i = t[
|
|
46
|
+
for (let h = t.length, c = 0; c < h; c++) {
|
|
47
|
+
const i = t[c];
|
|
48
48
|
i.contentBox.top = e;
|
|
49
|
-
let
|
|
50
|
-
for (const
|
|
49
|
+
let s = 0, d = null;
|
|
50
|
+
for (const o of i.fragments) {
|
|
51
51
|
this._setContextStyle({
|
|
52
|
-
...
|
|
53
|
-
textAlign: "
|
|
52
|
+
...o.style,
|
|
53
|
+
textAlign: "center",
|
|
54
54
|
verticalAlign: "baseline"
|
|
55
55
|
});
|
|
56
|
-
const
|
|
57
|
-
|
|
56
|
+
const B = l.measureText(o.content), p = B.width, f = o.style.fontSize;
|
|
57
|
+
o.inlineBox.left = s, o.inlineBox.top = e, o.inlineBox.width = p, o.inlineBox.height = f * o.style.lineHeight, o.contentBox.left = o.inlineBox.left, o.contentBox.width = p, o.contentBox.height = f, o.contentBox.top = o.inlineBox.top + (o.inlineBox.height - o.contentBox.height) / 2, o.glyphBox.width = B.actualBoundingBoxLeft + B.actualBoundingBoxRight, o.glyphBox.height = B.actualBoundingBoxAscent + B.actualBoundingBoxDescent, o.glyphBox.left = o.contentBox.left + (o.contentBox.width - o.glyphBox.width) / 2, o.glyphBox.top = o.contentBox.top + (o.contentBox.height - o.glyphBox.height) / 2, o.centerX = o.glyphBox.left + B.actualBoundingBoxLeft, o.baseline = o.glyphBox.top + B.actualBoundingBoxAscent, s += o.contentBox.width + o.style.letterSpacing, i.contentBox.height < o.contentBox.height && (d = o), i.contentBox.left = Math.min(i.contentBox.left, o.contentBox.left), i.contentBox.top = Math.min(i.contentBox.top, o.contentBox.top), i.contentBox.height = Math.max(i.contentBox.height, o.contentBox.height), i.lineBox.height = Math.max(i.lineBox.height, o.inlineBox.height);
|
|
58
58
|
}
|
|
59
|
-
const
|
|
59
|
+
const r = i.fragments[i.fragments.length - 1];
|
|
60
60
|
i.contentBox.width = Math.max(
|
|
61
61
|
i.contentBox.width,
|
|
62
|
-
|
|
63
|
-
), i.lineBox.left = 0, i.lineBox.top = e, i.lineBox.width = Math.max(
|
|
62
|
+
r ? r.contentBox.left + Math.max(r.contentBox.width, r.glyphBox.width) : 0
|
|
63
|
+
), i.lineBox.left = 0, i.lineBox.top = e, i.lineBox.width = Math.max(n, i.contentBox.width), this._setContextStyle({
|
|
64
64
|
...(d ?? i).style,
|
|
65
65
|
textAlign: "left",
|
|
66
66
|
verticalAlign: "baseline"
|
|
67
67
|
});
|
|
68
|
-
const
|
|
69
|
-
i.baseline = i.lineBox.top + (i.lineBox.height -
|
|
68
|
+
const g = l.measureText("X");
|
|
69
|
+
i.baseline = i.lineBox.top + (i.lineBox.height - g.actualBoundingBoxAscent + g.actualBoundingBoxDescent) / 2 + g.actualBoundingBoxAscent, e += i.lineBox.height;
|
|
70
70
|
}
|
|
71
|
-
for (let h = t.length,
|
|
72
|
-
const i = t[
|
|
73
|
-
i.fragments.forEach((
|
|
74
|
-
const d =
|
|
75
|
-
switch (
|
|
71
|
+
for (let h = t.length, c = 0; c < h; c++) {
|
|
72
|
+
const i = t[c];
|
|
73
|
+
i.fragments.forEach((s) => {
|
|
74
|
+
const d = s.inlineBox.left, r = s.inlineBox.top, g = i.lineBox.height - s.inlineBox.height;
|
|
75
|
+
switch (s.style.textAlign) {
|
|
76
76
|
case "end":
|
|
77
77
|
case "right":
|
|
78
|
-
|
|
78
|
+
s.inlineBox.left += i.lineBox.width - i.contentBox.width;
|
|
79
79
|
break;
|
|
80
80
|
case "center":
|
|
81
|
-
|
|
81
|
+
s.inlineBox.left += (i.lineBox.width - i.contentBox.width) / 2;
|
|
82
82
|
break;
|
|
83
83
|
case "start":
|
|
84
84
|
case "left":
|
|
85
85
|
default:
|
|
86
|
-
|
|
86
|
+
s.inlineBox.left += i.lineBox.left;
|
|
87
87
|
break;
|
|
88
88
|
}
|
|
89
|
-
switch (
|
|
89
|
+
switch (s.style.verticalAlign) {
|
|
90
90
|
case "top":
|
|
91
|
-
|
|
91
|
+
s.inlineBox.top = i.lineBox.top;
|
|
92
92
|
break;
|
|
93
93
|
case "middle":
|
|
94
|
-
|
|
94
|
+
s.inlineBox.top = i.lineBox.top + g / 2;
|
|
95
95
|
break;
|
|
96
96
|
case "bottom":
|
|
97
|
-
|
|
97
|
+
s.inlineBox.top = i.lineBox.top + g;
|
|
98
98
|
break;
|
|
99
99
|
case "sub":
|
|
100
100
|
case "text-top":
|
|
@@ -102,104 +102,105 @@ class u {
|
|
|
102
102
|
break;
|
|
103
103
|
case "baseline":
|
|
104
104
|
default:
|
|
105
|
-
|
|
105
|
+
s.inlineBox.height < i.lineBox.height && (s.inlineBox.top += i.baseline - s.baseline);
|
|
106
106
|
break;
|
|
107
107
|
}
|
|
108
|
-
const
|
|
109
|
-
|
|
108
|
+
const o = s.inlineBox.left - d, B = s.inlineBox.top - r;
|
|
109
|
+
s.contentBox.left += o, s.contentBox.top += B, s.glyphBox.left += o, s.glyphBox.top += B, s.baseline += B, s.centerX += o;
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
-
const
|
|
113
|
-
return {
|
|
112
|
+
const a = t.reduce((h, c) => (h.left = Math.min(h.left, c.contentBox.left), h.top = Math.min(h.top, c.contentBox.top), h.width = Math.max(h.width, c.contentBox.width), h.height += c.contentBox.height, h), { left: 0, top: 0, width: 0, height: 0 });
|
|
113
|
+
return { contentBox: t.reduce((h, c) => (h.left = Math.min(h.left, c.lineBox.left), h.top = Math.min(h.top, c.lineBox.top), h.width = Math.max(h.width, c.lineBox.width), h.height += c.lineBox.height, h), { left: 0, top: 0, width: 0, height: 0 }), actualContentBox: a, paragraphs: t };
|
|
114
114
|
}
|
|
115
|
-
_createParagraphs(
|
|
116
|
-
const t = (
|
|
117
|
-
const { width:
|
|
115
|
+
_createParagraphs(n) {
|
|
116
|
+
const t = (a = {}) => {
|
|
117
|
+
const { width: x, height: h, ...c } = this.style;
|
|
118
118
|
return {
|
|
119
119
|
contentBox: { left: 0, top: 0, width: 0, height: 0 },
|
|
120
120
|
lineBox: { left: 0, top: 0, width: 0, height: 0 },
|
|
121
121
|
baseline: 0,
|
|
122
122
|
fragments: [],
|
|
123
|
-
...
|
|
123
|
+
...a,
|
|
124
124
|
style: {
|
|
125
|
-
...
|
|
126
|
-
...
|
|
125
|
+
...c,
|
|
126
|
+
...a.style
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
|
-
}, l = (
|
|
130
|
-
const
|
|
131
|
-
return
|
|
129
|
+
}, l = (a = {}) => {
|
|
130
|
+
const x = [], { width: h, height: c, ...i } = this.style;
|
|
131
|
+
return x.push({
|
|
132
132
|
contentBox: { left: 0, top: 0, width: 0, height: 0 },
|
|
133
133
|
inlineBox: { left: 0, top: 0, width: 0, height: 0 },
|
|
134
|
-
|
|
134
|
+
glyphBox: { left: 0, top: 0, width: 0, height: 0 },
|
|
135
|
+
centerX: 0,
|
|
135
136
|
baseline: 0,
|
|
136
|
-
...
|
|
137
|
+
...a,
|
|
137
138
|
style: {
|
|
138
139
|
...i,
|
|
139
|
-
...
|
|
140
|
+
...a.style
|
|
140
141
|
},
|
|
141
|
-
content:
|
|
142
|
-
}),
|
|
142
|
+
content: a.content ?? ""
|
|
143
|
+
}), x;
|
|
143
144
|
}, e = [];
|
|
144
|
-
if (typeof
|
|
145
|
-
e.push(t({ fragments: l({ content:
|
|
145
|
+
if (typeof n == "string")
|
|
146
|
+
e.push(t({ fragments: l({ content: n }) }));
|
|
146
147
|
else {
|
|
147
|
-
|
|
148
|
-
for (const
|
|
149
|
-
if ("fragments" in
|
|
150
|
-
const { fragments:
|
|
151
|
-
for (const i of
|
|
152
|
-
const { content:
|
|
153
|
-
|
|
148
|
+
n = Array.isArray(n) ? n : [n];
|
|
149
|
+
for (const a of n)
|
|
150
|
+
if ("fragments" in a) {
|
|
151
|
+
const { fragments: x, ...h } = a, c = t({ style: h });
|
|
152
|
+
for (const i of x) {
|
|
153
|
+
const { content: s, ...d } = i;
|
|
154
|
+
c.fragments.push(...l({ content: s, style: { ...h, ...d } }));
|
|
154
155
|
}
|
|
155
|
-
e.push(
|
|
156
|
-
} else if ("content" in
|
|
157
|
-
const { content:
|
|
158
|
-
|
|
156
|
+
e.push(c);
|
|
157
|
+
} else if ("content" in a) {
|
|
158
|
+
const { content: x, ...h } = a, c = t({ style: h });
|
|
159
|
+
c.fragments.push(...l({ content: x, style: h })), e.push(c);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
return e;
|
|
162
163
|
}
|
|
163
|
-
_createWrapedParagraphs(
|
|
164
|
-
const l = (
|
|
165
|
-
let
|
|
166
|
-
for (;
|
|
167
|
-
const
|
|
164
|
+
_createWrapedParagraphs(n, t) {
|
|
165
|
+
const l = (c) => JSON.parse(JSON.stringify(c)), e = [], a = n.slice();
|
|
166
|
+
let x, h;
|
|
167
|
+
for (; x = a.shift(); ) {
|
|
168
|
+
const c = x.fragments.slice();
|
|
168
169
|
let i = 0;
|
|
169
|
-
const
|
|
170
|
-
for (; h =
|
|
170
|
+
const s = [];
|
|
171
|
+
for (; h = c.shift(); ) {
|
|
171
172
|
const d = h.style;
|
|
172
173
|
this._setContextStyle(d);
|
|
173
|
-
let
|
|
174
|
-
for (const
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
let
|
|
178
|
-
!i && !
|
|
179
|
-
...l(
|
|
180
|
-
fragments:
|
|
181
|
-
}),
|
|
182
|
-
const
|
|
183
|
-
(
|
|
184
|
-
...l(
|
|
185
|
-
fragments: (
|
|
186
|
-
}),
|
|
174
|
+
let r = "", g = !1;
|
|
175
|
+
for (const o of h.content) {
|
|
176
|
+
const B = this.context.measureText(o).width, p = /^[\r\n]$/.test(o);
|
|
177
|
+
if (p || d.textWrap === "wrap" && t && i + B > t) {
|
|
178
|
+
let f = p ? r.length + 1 : r.length;
|
|
179
|
+
!i && !f && (r += o, f++), r.length && s.push({ ...l(h), content: r }), s.length && (e.push({
|
|
180
|
+
...l(x),
|
|
181
|
+
fragments: s.slice()
|
|
182
|
+
}), s.length = 0);
|
|
183
|
+
const w = h.content.substring(f);
|
|
184
|
+
(w.length || c.length) && a.unshift({
|
|
185
|
+
...l(x),
|
|
186
|
+
fragments: (w.length ? [{ ...l(h), content: w }] : []).concat(c.slice())
|
|
187
|
+
}), c.length = 0, g = !0;
|
|
187
188
|
break;
|
|
188
189
|
} else
|
|
189
|
-
i +=
|
|
190
|
-
|
|
190
|
+
i += B;
|
|
191
|
+
r += o;
|
|
191
192
|
}
|
|
192
|
-
|
|
193
|
+
g || s.push(l(h));
|
|
193
194
|
}
|
|
194
|
-
|
|
195
|
+
s.length && e.push({ ...l(x), fragments: s });
|
|
195
196
|
}
|
|
196
197
|
return e;
|
|
197
198
|
}
|
|
198
|
-
_draw(
|
|
199
|
+
_draw(n) {
|
|
199
200
|
const t = this.context;
|
|
200
|
-
this.style.backgroundColor && (t.fillStyle = this.style.backgroundColor, t.fillRect(0, 0, t.canvas.width, t.canvas.height)),
|
|
201
|
+
this.style.backgroundColor && (t.fillStyle = this.style.backgroundColor, t.fillRect(0, 0, t.canvas.width, t.canvas.height)), n.forEach((l) => {
|
|
201
202
|
l.style.backgroundColor && (t.fillStyle = l.style.backgroundColor, t.fillRect(l.lineBox.left, l.lineBox.top, l.lineBox.width, l.lineBox.height));
|
|
202
|
-
}),
|
|
203
|
+
}), n.forEach((l) => {
|
|
203
204
|
l.fragments.forEach((e) => {
|
|
204
205
|
switch (e.style.backgroundColor && (t.fillStyle = e.style.backgroundColor, t.fillRect(e.inlineBox.left, e.inlineBox.top, e.inlineBox.width, e.inlineBox.height)), this._setContextStyle({
|
|
205
206
|
...e.style,
|
|
@@ -216,37 +217,37 @@ class u {
|
|
|
216
217
|
});
|
|
217
218
|
});
|
|
218
219
|
}
|
|
219
|
-
_resizeView(
|
|
220
|
+
_resizeView(n, t) {
|
|
220
221
|
const l = this.view;
|
|
221
|
-
l.style.width = `${
|
|
222
|
+
l.style.width = `${n}px`, l.style.height = `${t}px`, l.dataset.width = String(n), l.dataset.height = String(t), l.width = Math.max(1, Math.floor(n * this.pixelRatio)), l.height = Math.max(1, Math.floor(t * this.pixelRatio));
|
|
222
223
|
}
|
|
223
|
-
_setContextStyle(
|
|
224
|
+
_setContextStyle(n) {
|
|
224
225
|
const t = this.context;
|
|
225
|
-
switch (t.shadowColor =
|
|
226
|
+
switch (t.shadowColor = n.shadowColor, t.shadowOffsetX = n.shadowOffsetX, t.shadowOffsetY = n.shadowOffsetY, t.shadowBlur = n.shadowBlur, t.strokeStyle = n.textStrokeColor, t.lineWidth = n.textStrokeWidth, t.fillStyle = n.color, t.direction = n.direction, t.textAlign = n.textAlign, n.verticalAlign) {
|
|
226
227
|
case "baseline":
|
|
227
228
|
t.textBaseline = "alphabetic";
|
|
228
229
|
break;
|
|
229
230
|
case "top":
|
|
230
231
|
case "middle":
|
|
231
232
|
case "bottom":
|
|
232
|
-
t.textBaseline =
|
|
233
|
+
t.textBaseline = n.verticalAlign;
|
|
233
234
|
break;
|
|
234
235
|
}
|
|
235
236
|
t.font = [
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
`${
|
|
239
|
-
|
|
240
|
-
].join(" "), t.fontKerning =
|
|
237
|
+
n.fontStyle,
|
|
238
|
+
n.fontWeight,
|
|
239
|
+
`${n.fontSize}px`,
|
|
240
|
+
n.fontFamily
|
|
241
|
+
].join(" "), t.fontKerning = n.fontKerning, t.letterSpacing = `${n.letterSpacing}px`;
|
|
241
242
|
}
|
|
242
243
|
update() {
|
|
243
|
-
const
|
|
244
|
+
const n = this.context;
|
|
244
245
|
let { width: t, height: l } = this.style;
|
|
245
246
|
t === "auto" && (t = 0), l === "auto" && (l = 0);
|
|
246
|
-
const {
|
|
247
|
+
const { contentBox: e, paragraphs: a } = this.measure();
|
|
247
248
|
t || (t = e.width), l = Math.max(l, e.height), this._resizeView(t, l);
|
|
248
|
-
const
|
|
249
|
-
|
|
249
|
+
const x = this.pixelRatio;
|
|
250
|
+
n.scale(x, x), n.clearRect(0, 0, n.canvas.width, n.canvas.height), this._draw(a);
|
|
250
251
|
}
|
|
251
252
|
}
|
|
252
253
|
export {
|
package/package.json
CHANGED
package/types/Text.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ export interface TextParagraph {
|
|
|
21
21
|
export interface TextFragment {
|
|
22
22
|
contentBox: BoundingBox;
|
|
23
23
|
inlineBox: BoundingBox;
|
|
24
|
-
|
|
24
|
+
glyphBox: BoundingBox;
|
|
25
|
+
centerX: number;
|
|
25
26
|
baseline: number;
|
|
26
27
|
content: string;
|
|
27
28
|
style: TextFragmentStyle;
|
|
@@ -68,9 +69,9 @@ export interface TextOptions {
|
|
|
68
69
|
content?: TextContent;
|
|
69
70
|
style?: Partial<TextStyle>;
|
|
70
71
|
}
|
|
71
|
-
export interface
|
|
72
|
+
export interface Metrics {
|
|
72
73
|
contentBox: BoundingBox;
|
|
73
|
-
|
|
74
|
+
actualContentBox: BoundingBox;
|
|
74
75
|
paragraphs: Array<TextParagraph>;
|
|
75
76
|
}
|
|
76
77
|
export declare class Text {
|
|
@@ -81,7 +82,7 @@ export declare class Text {
|
|
|
81
82
|
style: TextStyle;
|
|
82
83
|
content: TextContent;
|
|
83
84
|
constructor(options?: TextOptions);
|
|
84
|
-
measure():
|
|
85
|
+
measure(): Metrics;
|
|
85
86
|
protected _createParagraphs(content: TextContent): Array<TextParagraph>;
|
|
86
87
|
protected _createWrapedParagraphs(paragraphs: Array<TextParagraph>, width: number): Array<TextParagraph>;
|
|
87
88
|
protected _draw(paragraphs: Array<TextParagraph>): void;
|