@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 3.48 kB
JavaScript
import{isLineBreak as t,isWhiteSpace as e,allowsIdeographicBreak as i,hasVerticalOrientation as s}from"./ScriptUtils.js";import o from"../webgl/Rect.js";const c=24,h=17;class a{constructor(t,e,i,s,o,c,h){this._glyphItems=t,this._maxWidth=e,this._lineHeight=i,this._letterSpacing=s,this._hAnchor=o,this._vAnchor=c,this._justify=h}getShaping(o,c,h){const a=this._letterSpacing,l=this._lineHeight,r=this._justify,n=this._maxWidth,m=[];let f=0,p=0;const g=o.length;for(let t=0;t<g;t++){const e=o.charCodeAt(t),i=h&&s(e);let c;for(const t of this._glyphItems)if(c=t[e],c)break;m.push({codePoint:e,x:f,y:p,vertical:i,glyphMosaicItem:c}),c&&(f+=c.metrics.advance+a)}let y=f;if(n>0){y=f/Math.max(1,Math.ceil(f/n))}const d=o.includes(""),x=[];for(let e=0;e<g-1;e++){const s=m[e].codePoint,o=i(s);if(t(s)||o){let t=0;if(10===s)t-=1e4;else if(o&&d)t+=150;else{40!==s&&65288!==s||(t+=50);const i=m[e+1].codePoint;41!==i&&65289!==i||(t+=50)}x.push(this._buildBreak(e+1,m[e].x,y,x,t,!1))}}const M=this._optimalBreaks(this._buildBreak(g,f,y,x,0,!0));let u=0;const _=c?-l:l;let I=0;for(let t=0;t<M.length;t++){const i=M[t];let s=I;for(;s<i&&e(m[s].codePoint);)m[s].glyphMosaicItem=null,++s;let o=i-1;for(;o>s&&e(m[o].codePoint);)m[o].glyphMosaicItem=null,--o;if(s<=o){const t=m[s].x;for(let i=s;i<=o;i++)m[i].x-=t,m[i].y=p;let e=m[o].x;m[o].glyphMosaicItem&&(e+=m[o].glyphMosaicItem.metrics.advance),u=Math.max(e,u),r&&this._applyJustification(m,s,o)}I=i,p+=_}if(m.length>0){const t=M.length-1,e=(r-this._hAnchor)*u;let i=(-this._vAnchor*(t+1)+.5)*l;c&&t&&(i+=t*l);for(const s of m)s.x+=e,s.y+=i}return m.filter((t=>t.glyphMosaicItem))}static getTextBox(t,e){if(!t.length)return null;let i=1/0,s=1/0,o=0,c=0;for(const a of t){const t=a.glyphMosaicItem.metrics.advance,l=a.x,r=a.y-h,n=l+t,m=r+e;i=Math.min(i,l),o=Math.max(o,n),s=Math.min(s,r),c=Math.max(c,m)}return{x:i,y:s,width:o-i,height:c-s}}static getBox(t){if(!t.length)return null;let e=1/0,i=1/0,s=0,o=0;for(const c of t){const{height:t,left:h,top:a,width:l}=c.glyphMosaicItem.metrics,r=c.x,n=c.y-(t-Math.abs(a)),m=r+l+h,f=n+t;e=Math.min(e,r),s=Math.max(s,m),i=Math.min(i,n),o=Math.max(o,f)}return{x:e,y:i,width:s-e,height:o-i}}static addDecoration(t,e){const i=t.length;if(0===i)return;const s=3;let c=t[0].x+t[0].glyphMosaicItem.metrics.left,h=t[0].y;for(let l=1;l<i;l++){const i=t[l];if(i.y!==h){const a=t[l-1].x+t[l-1].glyphMosaicItem.metrics.left+t[l-1].glyphMosaicItem.metrics.width;t.push({codePoint:0,x:c,y:h+e-s,vertical:!1,glyphMosaicItem:{sdf:!0,rect:new o(4,0,4,8),metrics:{width:a-c,height:2+2*s,left:0,top:0,advance:0},page:0,code:0}}),h=i.y,c=i.x+i.glyphMosaicItem.metrics.left}}const a=t[i-1].x+t[i-1].glyphMosaicItem.metrics.left+t[i-1].glyphMosaicItem.metrics.width;t.push({codePoint:0,x:c,y:h+e-s,vertical:!1,glyphMosaicItem:{sdf:!0,rect:new o(4,0,4,8),metrics:{width:a-c,height:2+2*s,left:0,top:0,advance:0},page:0,code:0}})}_breakScore(t,e,i,s){const o=(t-e)*(t-e);return s?t<e?o/2:2*o:o+Math.abs(i)*i}_buildBreak(t,e,i,s,o,c){let h=null,a=this._breakScore(e,i,o,c);for(const l of s){const t=e-l.x,s=this._breakScore(t,i,o,c)+l.score;s<=a&&(h=l,a=s)}return{index:t,x:e,score:a,previousBreak:h}}_optimalBreaks(t){return t?this._optimalBreaks(t.previousBreak).concat(t.index):[]}_applyJustification(t,e,i){const s=t[i],o=s.vertical?c:s.glyphMosaicItem?s.glyphMosaicItem.metrics.advance:0,h=(s.x+o)*this._justify;for(let c=e;c<=i;c++)t[c].x-=h}}export{h as SDF_GLYPH_BASELINE,c as SDF_GLYPH_SIZE,a as TextShaping};