Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

troika-three-text

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

troika-three-text - npm Package Compare versions

Comparing version 0.36.1 to 0.37.0

src/worker/FontParser_Harfbuzz.js

17

CHANGELOG.md

@@ -6,2 +6,19 @@ # Change Log

# [0.37.0](https://github.com/protectwise/troika/compare/v0.36.1...v0.37.0) (2021-01-18)
### Features
* **troika-three-text:** added inner stroke and outline blur capabilities ([e004b9d](https://github.com/protectwise/troika/commit/e004b9d2f7e2ef9e841e61156b68958076533a62))
### Performance Improvements
* **troika-three-text:** swap tiny-inflate to fflate for minor speed boost on woff fonts ([2ae29fa](https://github.com/protectwise/troika/commit/2ae29faffcec2302453ce9dabac633ade8181127))
## [0.36.1](https://github.com/protectwise/troika/compare/v0.36.0...v0.36.1) (2020-12-16)

@@ -8,0 +25,0 @@

0

find-google-font-url.js

@@ -0,0 +0,0 @@ #!/usr/bin/env node

@@ -0,0 +0,0 @@ /*!

8

libs/woff2otf.factory.js
/*!
Custom bundle of woff2otf (https://github.com/arty-name/woff2otf) with tiny-inflate
(https://github.com/foliojs/tiny-inflate) for use in Troika text rendering.
Custom bundle of woff2otf (https://github.com/arty-name/woff2otf) with fflate
(https://github.com/101arrowz/fflate) for use in Troika text rendering.
Original licenses apply:
- tiny-inflate: https://github.com/foliojs/tiny-inflate/blob/master/LICENSE (MIT)
- fflate: https://github.com/101arrowz/fflate/blob/master/LICENSE (MIT)
- woff2otf.js: https://github.com/arty-name/woff2otf/blob/master/woff2otf.js (Apache2)
*/
export default function(){return function(t){"use strict";function e(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function r(t,r){this.source=t,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=r,this.destLen=0,this.ltree=new e,this.dtree=new e}var n=new e,o=new e,a=new Uint8Array(30),s=new Uint16Array(30),i=new Uint8Array(30),u=new Uint16Array(30),f=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),c=new e,g=new Uint8Array(320);function b(t,e,r,n){var o,a;for(o=0;o<r;++o)t[o]=0;for(o=0;o<30-r;++o)t[o+r]=o/r|0;for(a=n,o=0;o<30;++o)e[o]=a,a+=1<<t[o]}var d=new Uint16Array(16);function h(t,e,r,n){var o,a;for(o=0;o<16;++o)t.table[o]=0;for(o=0;o<n;++o)t.table[e[r+o]]++;for(t.table[0]=0,a=0,o=0;o<16;++o)d[o]=a,a+=t.table[o];for(o=0;o<n;++o)e[r+o]&&(t.trans[d[e[r+o]]++]=o)}function l(t){t.bitcount--||(t.tag=t.source[t.sourceIndex++],t.bitcount=7);var e=1&t.tag;return t.tag>>>=1,e}function v(t,e,r){if(!e)return r;for(;t.bitcount<24;)t.tag|=t.source[t.sourceIndex++]<<t.bitcount,t.bitcount+=8;var n=t.tag&65535>>>16-e;return t.tag>>>=e,t.bitcount-=e,n+r}function w(t,e){for(;t.bitcount<24;)t.tag|=t.source[t.sourceIndex++]<<t.bitcount,t.bitcount+=8;var r=0,n=0,o=0,a=t.tag;do{n=2*n+(1&a),a>>>=1,++o,r+=e.table[o],n-=e.table[o]}while(n>=0);return t.tag=a,t.bitcount-=o,e.trans[r+n]}function L(t,e,r){var n,o,a,s,i,u;for(n=v(t,5,257),o=v(t,5,1),a=v(t,4,4),s=0;s<19;++s)g[s]=0;for(s=0;s<a;++s){var b=v(t,3,0);g[f[s]]=b}for(h(c,g,0,19),i=0;i<n+o;){var d=w(t,c);switch(d){case 16:var l=g[i-1];for(u=v(t,2,3);u;--u)g[i++]=l;break;case 17:for(u=v(t,3,3);u;--u)g[i++]=0;break;case 18:for(u=v(t,7,11);u;--u)g[i++]=0;break;default:g[i++]=d}}h(e,g,0,n),h(r,g,n,o)}function U(t,e,r){for(;;){var n,o,f,c,g=w(t,e);if(256===g)return 0;if(g<256)t.dest[t.destLen++]=g;else for(n=v(t,a[g-=257],s[g]),o=w(t,r),c=f=t.destLen-v(t,i[o],u[o]);c<f+n;++c)t.dest[t.destLen++]=t.dest[c]}}function m(t){for(var e,r;t.bitcount>8;)t.sourceIndex--,t.bitcount-=8;if((e=256*(e=t.source[t.sourceIndex+1])+t.source[t.sourceIndex])!==(65535&~(256*t.source[t.sourceIndex+3]+t.source[t.sourceIndex+2])))return-3;for(t.sourceIndex+=4,r=e;r;--r)t.dest[t.destLen++]=t.source[t.sourceIndex++];return t.bitcount=0,0}!function(t,e){var r;for(r=0;r<7;++r)t.table[r]=0;for(t.table[7]=24,t.table[8]=152,t.table[9]=112,r=0;r<24;++r)t.trans[r]=256+r;for(r=0;r<144;++r)t.trans[24+r]=r;for(r=0;r<8;++r)t.trans[168+r]=280+r;for(r=0;r<112;++r)t.trans[176+r]=144+r;for(r=0;r<5;++r)e.table[r]=0;for(e.table[5]=32,r=0;r<32;++r)e.trans[r]=r}(n,o),b(a,s,4,3),b(i,u,2,1),a[28]=0,s[28]=258;var y=function(t,e){var a,s,i=new r(t,e);do{switch(a=l(i),v(i,2,0)){case 0:s=m(i);break;case 1:s=U(i,n,o);break;case 2:L(i,i.ltree,i.dtree),s=U(i,i.ltree,i.dtree);break;default:s=-3}if(0!==s)throw new Error("Data error")}while(!a);return i.destLen<i.dest.length?"function"==typeof i.dest.slice?i.dest.slice(0,i.destLen):i.dest.subarray(0,i.destLen):i.dest};return t.convert_streams=function(t){var e=new DataView(t),r=0;function n(){var t=e.getUint16(r);return r+=2,t}function o(){var t=e.getUint32(r);return r+=4,t}function a(t){w.setUint16(L,t),L+=2}function s(t){w.setUint32(L,t),L+=4}for(var i={signature:o(),flavor:o(),length:o(),numTables:n(),reserved:n(),totalSfntSize:o(),majorVersion:n(),minorVersion:n(),metaOffset:o(),metaLength:o(),metaOrigLength:o(),privOffset:o(),privLength:o()},u=0;Math.pow(2,u)<=i.numTables;)u++;u--;for(var f=16*Math.pow(2,u),c=16*i.numTables-f,g=12,b=[],d=0;d<i.numTables;d++)b.push({tag:o(),offset:o(),compLength:o(),origLength:o(),origChecksum:o()}),g+=16;var h,l=new Uint8Array(12+16*b.length+b.reduce((function(t,e){return t+e.origLength+4}),0)),v=l.buffer,w=new DataView(v),L=0;return s(i.flavor),a(i.numTables),a(f),a(u),a(c),b.forEach((function(t){s(t.tag),s(t.origChecksum),s(g),s(t.origLength),t.outOffset=g,(g+=t.origLength)%4!=0&&(g+=4-g%4)})),b.forEach((function(e){var r=t.slice(e.offset,e.offset+e.compLength);if(e.compLength!=e.origLength){var n=new Uint8Array(e.origLength);y(new Uint8Array(r,2),n)}else n=new Uint8Array(r);l.set(n,e.outOffset);var o=0;(g=e.outOffset+e.origLength)%4!=0&&(o=4-g%4),l.set(new Uint8Array(o).buffer,e.outOffset+e.origLength),h=g+o})),v.slice(0,h)},t}({}).convert_streams}
export default function(){return function(r){"use strict";var e=Uint8Array,n=Uint16Array,t=Uint32Array,a=new e([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),f=new e([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),i=new e([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),o=function(r,e){for(var a=new n(31),f=0;f<31;++f)a[f]=e+=1<<r[f-1];var i=new t(a[30]);for(f=1;f<30;++f)for(var o=a[f];o<a[f+1];++o)i[o]=o-a[f]<<5|f;return[a,i]},u=o(a,2),v=u[0],s=u[1];v[28]=258,s[258]=28;for(var l=o(f,0)[0],c=new n(32768),g=0;g<32768;++g){var h=(43690&g)>>>1|(21845&g)<<1;h=(61680&(h=(52428&h)>>>2|(13107&h)<<2))>>>4|(3855&h)<<4,c[g]=((65280&h)>>>8|(255&h)<<8)>>>1}var w=function(r,e,t){for(var a=r.length,f=0,i=new n(e);f<a;++f)++i[r[f]-1];var o,u=new n(e);for(f=0;f<e;++f)u[f]=u[f-1]+i[f-1]<<1;if(t){o=new n(1<<e);var v=15-e;for(f=0;f<a;++f)if(r[f])for(var s=f<<4|r[f],l=e-r[f],g=u[r[f]-1]++<<l,h=g|(1<<l)-1;g<=h;++g)o[c[g]>>>v]=s}else for(o=new n(a),f=0;f<a;++f)o[f]=c[u[r[f]-1]++]>>>15-r[f];return o},m=new e(288);for(g=0;g<144;++g)m[g]=8;for(g=144;g<256;++g)m[g]=9;for(g=256;g<280;++g)m[g]=7;for(g=280;g<288;++g)m[g]=8;var b=new e(32);for(g=0;g<32;++g)b[g]=5;var p=w(m,9,1),d=w(b,5,1),L=function(r){for(var e=r[0],n=1;n<r.length;++n)r[n]>e&&(e=r[n]);return e},y=function(r,e,n){var t=e/8>>0;return(r[t]|r[t+1]<<8)>>>(7&e)&n},U=function(r,e){var n=e/8>>0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>>(7&e)},O=function(r,o,u){var s=r.length,c=!o||u,g=!u||u.i;u||(u={}),o||(o=new e(3*s));var h,m=function(r){var n=o.length;if(r>n){var t=new e(Math.max(2*n,r));t.set(o),o=t}},b=u.f||0,O=u.p||0,A=u.b||0,k=u.l,x=u.d,E=u.m,T=u.n,F=8*s;do{if(!k){u.f=b=y(r,O,1);var V=y(r,O+1,3);if(O+=3,!V){var M=r[(I=((h=O)/8>>0)+(7&h&&1)+4)-4]|r[I-3]<<8,C=I+M;if(C>s){if(g)throw"unexpected EOF";break}c&&m(A+M),o.set(r.subarray(I,C),A),u.b=A+=M,u.p=O=8*C;continue}if(1==V)k=p,x=d,E=9,T=5;else{if(2!=V)throw"invalid block type";var D=y(r,O,31)+257,S=y(r,O+10,15)+4,_=D+y(r,O+5,31)+1;O+=14;for(var j=new e(_),z=new e(19),q=0;q<S;++q)z[i[q]]=y(r,O+3*q,7);O+=3*S;var B=L(z),G=(1<<B)-1;if(!g&&O+_*(B+7)>F)break;var H=w(z,B,1);for(q=0;q<_;){var I,J=H[y(r,O,G)];if(O+=15&J,(I=J>>>4)<16)j[q++]=I;else{var K=0,N=0;for(16==I?(N=3+y(r,O,3),O+=2,K=j[q-1]):17==I?(N=3+y(r,O,7),O+=3):18==I&&(N=11+y(r,O,127),O+=7);N--;)j[q++]=K}}var P=j.subarray(0,D),Q=j.subarray(D);E=L(P),T=L(Q),k=w(P,E,1),x=w(Q,T,1)}if(O>F)throw"unexpected EOF"}c&&m(A+131072);for(var R=(1<<E)-1,W=(1<<T)-1,X=E+T+18;g||O+X<F;){var Y=(K=k[U(r,O)&R])>>>4;if((O+=15&K)>F)throw"unexpected EOF";if(!K)throw"invalid length/literal";if(Y<256)o[A++]=Y;else{if(256==Y){k=null;break}var Z=Y-254;if(Y>264){var $=a[q=Y-257];Z=y(r,O,(1<<$)-1)+v[q],O+=$}var rr=x[U(r,O)&W],er=rr>>>4;if(!rr)throw"invalid distance";O+=15&rr;Q=l[er];if(er>3){$=f[er];Q+=U(r,O)&(1<<$)-1,O+=$}if(O>F)throw"unexpected EOF";c&&m(A+131072);for(var nr=A+Z;A<nr;A+=4)o[A]=o[A-Q],o[A+1]=o[A+1-Q],o[A+2]=o[A+2-Q],o[A+3]=o[A+3-Q];A=nr}}u.l=k,u.p=O,u.b=A,k&&(b=1,u.m=E,u.d=x,u.n=T)}while(!b);return A==o.length?o:function(r,a,f){(null==a||a<0)&&(a=0),(null==f||f>r.length)&&(f=r.length);var i=new(r instanceof n?n:r instanceof t?t:e)(f-a);return i.set(r.subarray(a,f)),i}(o,0,A)};return r.convert_streams=function(r){var e=new DataView(r),n=0;function t(){var r=e.getUint16(n);return n+=2,r}function a(){var r=e.getUint32(n);return n+=4,r}function f(r){b.setUint16(p,r),p+=2}function i(r){b.setUint32(p,r),p+=4}for(var o={signature:a(),flavor:a(),length:a(),numTables:t(),reserved:t(),totalSfntSize:a(),majorVersion:t(),minorVersion:t(),metaOffset:a(),metaLength:a(),metaOrigLength:a(),privOffset:a(),privLength:a()},u=0;Math.pow(2,u)<=o.numTables;)u++;u--;for(var v=16*Math.pow(2,u),s=16*o.numTables-v,l=12,c=[],g=0;g<o.numTables;g++)c.push({tag:a(),offset:a(),compLength:a(),origLength:a(),origChecksum:a()}),l+=16;var h,w=new Uint8Array(12+16*c.length+c.reduce((function(r,e){return r+e.origLength+4}),0)),m=w.buffer,b=new DataView(m),p=0;return i(o.flavor),f(o.numTables),f(v),f(u),f(s),c.forEach((function(r){i(r.tag),i(r.origChecksum),i(l),i(r.origLength),r.outOffset=l,(l+=r.origLength)%4!=0&&(l+=4-l%4)})),c.forEach((function(e){var n,t=r.slice(e.offset,e.offset+e.compLength);if(e.compLength!=e.origLength){var a=new Uint8Array(e.origLength);n=new Uint8Array(t,2),O(n,a)}else a=new Uint8Array(t);w.set(a,e.outOffset);var f=0;(l=e.outOffset+e.origLength)%4!=0&&(f=4-l%4),w.set(new Uint8Array(f).buffer,e.outOffset+e.origLength),h=l+f})),m.slice(0,h)},r}({}).convert_streams}
{
"name": "troika-three-text",
"version": "0.36.1",
"version": "0.37.0",
"description": "SDF-based text rendering for Three.js",

@@ -17,10 +17,10 @@ "author": "Jason Johnston <jason.johnston@protectwise.com>",

"dependencies": {
"troika-three-utils": "^0.36.0",
"troika-worker-utils": "^0.36.0"
"troika-three-utils": "^0.37.0",
"troika-worker-utils": "^0.37.0"
},
"devDependencies": {
"@fredli74/typr": "0.3.3",
"fflate": "0.4.8",
"node-fetch": "^2.6.0",
"opentype.js": "1.3.3",
"tiny-inflate": "1.0.3"
"opentype.js": "1.3.3"
},

@@ -32,3 +32,3 @@ "scripts": {

},
"gitHead": "1557947d1aa1f8362a3572039a983c679832cfee"
"gitHead": "f2c9c725b22a88ca3275c39150d75f6894ea3503"
}

@@ -120,2 +120,8 @@ # `troika-three-text`

#### `fillOpacity`
Controls the opacity of just the glyph's fill area, separate from any configured `strokeOpacity`, `outlineOpacity`, and the material's `opacity`. A `fillOpacity` of `0` will make the fill invisible, leaving just the stroke and/or outline.
Default: `1`
#### `font`

@@ -182,12 +188,36 @@

#### `outlineBlur`
Specifies a blur radius applied to the outer edge of the text's `outlineWidth`. If the `outlineWidth` is zero, the blur will be applied at the glyph edge, like CSS's `text-shadow` blur radius. A blur plus a nonzero `outlineWidth` can give a solid outline with a fuzzy outer edge.
The blur radius can be specified as either an absolute number in local units, or as a percentage string e.g. `"12%"` which is treated as a percentage of the `fontSize`.
Default: `0`
#### `outlineColor`
The color to use for the text outline when `outlineWidth` is greater than `0`.
The color to use for the text outline when `outlineWidth`, `outlineBlur`, and/or `outlineOffsetX/Y` are set. Accepts a ThreeJS `Color` object, or a number/string accepted by `Color#set`.
Default: black
#### `outlineOffsetX`, `outlineOffsetY`
These define a horizontal and vertical offset of the text outline. Using an offset with `outlineWidth: 0` creates a drop-shadow effect like CSS's `text-shadow`; also see `outlineBlur`.
The offsets can be specified as either an absolute number in local units, or as a percentage string e.g. `"12%"` which is treated as a percentage of the `fontSize`.
Default: `0`
#### `outlineOpacity`
Sets the opacity of a configured text outline, in the range `0` to `1`.
Default: `1`
#### `outlineWidth`
The width of an outline/halo to be drawn around each text glyph using the `outlineColor`. This can help improve readability when the text is displayed against a background of low or varying contrast. The width can be specified as either an absolute number in local units, or as a percentage string e.g. `"10%"` which is interpreted as a percentage of the `fontSize`.
The width of an outline/halo to be drawn around each text glyph using the `outlineColor` and `outlineOpacity`. This can help improve readability when the text is displayed against a background of low or varying contrast.
The width can be specified as either an absolute number in local units, or as a percentage string e.g. `"10%"` which is interpreted as a percentage of the `fontSize`.
Default: `0`

@@ -207,2 +237,22 @@

#### `strokeColor`
The color of the text stroke, when `strokeWidth` is nonzero. Accepts a ThreeJS `Color` object, or a number/string accepted by `Color#set`.
Default: grey
#### `strokeOpacity`
The opacity of the text stroke, when `strokeWidth` is nonzero. Accepts a number from `0` to `1`.
Default: `1`
#### `strokeWidth`
Sets the width of a stroke drawn inside the edge of each text glyph, using the `strokeColor` and `strokeOpacity`.
The width can be specified as either an absolute number in local units, or as a percentage string e.g. `"10%"` which is interpreted as a percentage of the `fontSize`.
Default: `0`
#### `textAlign`

@@ -209,0 +259,0 @@

@@ -0,0 +0,0 @@ // This build file creates a static version of the OpenType.js library used for

@@ -0,0 +0,0 @@ // This build file creates a static version of the Typr.ts library used for

@@ -1,3 +0,3 @@

// This build file creates a static version of the Typr.ts library used for
// processing fonts. It's isolated within a "factory" function wrapper so it can
// This build file assembles a function for converting WOFF fonts to OTF fonts, so they
// can be parsed by Typr. It's isolated within a "factory" function wrapper so it can
// easily be marshalled into a web worker.

@@ -19,6 +19,6 @@

/*!
Custom bundle of woff2otf (https://github.com/arty-name/woff2otf) with tiny-inflate
(https://github.com/foliojs/tiny-inflate) for use in Troika text rendering.
Custom bundle of woff2otf (https://github.com/arty-name/woff2otf) with fflate
(https://github.com/101arrowz/fflate) for use in Troika text rendering.
Original licenses apply:
- tiny-inflate: https://github.com/foliojs/tiny-inflate/blob/master/LICENSE (MIT)
- fflate: https://github.com/101arrowz/fflate/blob/master/LICENSE (MIT)
- woff2otf.js: https://github.com/arty-name/woff2otf/blob/master/woff2otf.js (Apache2)

@@ -43,2 +43,12 @@ */

commonjs(),
{
name: 'custom',
transform(source, id) {
if (/fflate/.test(id)) {
// Remove stray `require` in try/catch block which doesn't get treeshaken
return source.replace(/try\s*{\s*Worker\s*=\s*require\('worker_threads'\)\.Worker;\s*}\s*catch\s*\(.\)\s*{\s*}/, '')
}
return source
}
},
terser({

@@ -45,0 +55,0 @@ ecma: 5

@@ -0,0 +0,0 @@ import {

@@ -0,0 +0,0 @@ // Exports for troika-three-text package:

@@ -0,0 +0,0 @@ //=== Utility functions for dealing with carets and selection ranges ===//

@@ -8,3 +8,4 @@ import {

PlaneBufferGeometry,
Vector3
Vector3,
Vector2,
} from 'three'

@@ -22,2 +23,3 @@ import { GlyphsGeometry } from './GlyphsGeometry.js'

})
const defaultStrokeColor = 0x808080

@@ -221,5 +223,6 @@ const tempMat4 = new Matrix4()

* WARNING: This API is experimental and may change.
* The width of an outline drawn around each text glyph using the `outlineColor`. Can be
* specified as either an absolute number in local units, or as a percentage string e.g.
* `"12%"` which is treated as a percentage of the `fontSize`. Defaults to `0`.
* The width of an outline/halo to be drawn around each text glyph using the `outlineColor` and `outlineOpacity`.
* Can be specified as either an absolute number in local units, or as a percentage string e.g.
* `"12%"` which is treated as a percentage of the `fontSize`. Defaults to `0`, which means
* no outline will be drawn unless an `outlineOffsetX/Y` or `outlineBlur` is set.
*/

@@ -231,7 +234,76 @@ this.outlineWidth = 0

* WARNING: This API is experimental and may change.
* The color of the text outline, if `outlineWidth` is greater than zero. Defaults to black.
* The color of the text outline, if `outlineWidth`/`outlineBlur`/`outlineOffsetX/Y` are set.
* Defaults to black.
*/
this.outlineColor = 0
this.outlineColor = 0x000000
/**
* @member {number} outlineOpacity
* WARNING: This API is experimental and may change.
* The opacity of the outline, if `outlineWidth`/`outlineBlur`/`outlineOffsetX/Y` are set.
* Defaults to `1`.
*/
this.outlineOpacity = 1
/**
* @member {number|string} outlineBlur
* WARNING: This API is experimental and may change.
* A blur radius applied to the outer edge of the text's outline. If the `outlineWidth` is
* zero, the blur will be applied at the glyph edge, like CSS's `text-shadow` blur radius.
* Can be specified as either an absolute number in local units, or as a percentage string e.g.
* `"12%"` which is treated as a percentage of the `fontSize`. Defaults to `0`.
*/
this.outlineBlur = 0
/**
* @member {number|string} outlineOffsetX
* WARNING: This API is experimental and may change.
* A horizontal offset for the text outline.
* Can be specified as either an absolute number in local units, or as a percentage string e.g. `"12%"`
* which is treated as a percentage of the `fontSize`. Defaults to `0`.
*/
this.outlineOffsetX = 0
/**
* @member {number|string} outlineOffsetY
* WARNING: This API is experimental and may change.
* A vertical offset for the text outline.
* Can be specified as either an absolute number in local units, or as a percentage string e.g. `"12%"`
* which is treated as a percentage of the `fontSize`. Defaults to `0`.
*/
this.outlineOffsetY = 0
/**
* @member {number|string} strokeWidth
* WARNING: This API is experimental and may change.
* The width of an inner stroke drawn inside each text glyph using the `strokeColor` and `strokeOpacity`.
* Can be specified as either an absolute number in local units, or as a percentage string e.g. `"12%"`
* which is treated as a percentage of the `fontSize`. Defaults to `0`.
*/
this.strokeWidth = 0
/**
* @member {string|number|THREE.Color} strokeColor
* WARNING: This API is experimental and may change.
* The color of the text stroke, if `strokeWidth` is greater than zero. Defaults to gray.
*/
this.strokeColor = defaultStrokeColor
/**
* @member {number} strokeOpacity
* WARNING: This API is experimental and may change.
* The opacity of the stroke, if `strokeWidth` is greater than zero. Defaults to `1`.
*/
this.strokeOpacity = 1
/**
* @member {number} fillOpacity
* WARNING: This API is experimental and may change.
* The opacity of the glyph's fill from 0 to 1. This behaves like the material's `opacity` but allows
* giving the fill a different opacity than the `strokeOpacity`. A fillOpacity of `0` makes the
* interior of the glyph invisible, leaving just the `strokeWidth`. Defaults to `1`.
*/
this.fillOpacity = 1
/**
* @member {number} depthOffset

@@ -401,7 +473,7 @@ * This is a shortcut for setting the material's `polygonOffset` and related properties,

}
// If text outline is present, render it as a preliminary draw using Three's multi-material
// If text outline is configured, render it as a preliminary draw using Three's multi-material
// feature (see GlyphsGeometry which sets up `groups` for this purpose) Doing it with multi
// materials ensures the layers are always rendered consecutively in a consistent order.
// Each layer will trigger onBeforeRender with the appropriate material.
if (this.outlineWidth) {
if (this.outlineWidth || this.outlineBlur || this.outlineOffsetX || this.outlineOffsetY) {
let outlineMaterial = derivedMaterial._outlineMtl

@@ -463,15 +535,37 @@ if (!outlineMaterial) {

uniforms.uTroikaTotalBounds.value.fromArray(blockBounds)
uniforms.uTroikaUseGlyphColors.value = !!textInfo.glyphColors
uniforms.uTroikaUseGlyphColors.value = !isOutline && !!textInfo.glyphColors
let distanceOffset = 0
let blurRadius = 0
let strokeWidth = 0
let fillOpacity
let strokeOpacity
let strokeColor
let offsetX = 0
let offsetY = 0
if (isOutline) {
let {outlineWidth} = this
if (typeof outlineWidth === 'string') {
let match = outlineWidth.match(/^([\d.]+)%$/)
let pct = match ? parseFloat(match[1]) : NaN
outlineWidth = (isNaN(pct) ? 0 : pct / 100) * this.fontSize
let {outlineWidth, outlineOffsetX, outlineOffsetY, outlineBlur, outlineOpacity} = this
distanceOffset = this._parsePercent(outlineWidth) || 0
blurRadius = this._parsePercent(outlineBlur) || 0
fillOpacity = outlineOpacity
offsetX = this._parsePercent(outlineOffsetX) || 0
offsetY = this._parsePercent(outlineOffsetY) || 0
} else {
strokeWidth = this._parsePercent(this.strokeWidth) || 0
if (strokeWidth) {
strokeColor = this.strokeColor
uniforms.uTroikaStrokeColor.value.set(strokeColor == null ? defaultStrokeColor : strokeColor)
strokeOpacity = this.strokeOpacity
if (strokeOpacity == null) strokeOpacity = 1
}
distanceOffset = outlineWidth
fillOpacity = this.fillOpacity
}
uniforms.uTroikaDistanceOffset.value = distanceOffset
uniforms.uTroikaPositionOffset.value.set(offsetX, offsetY)
uniforms.uTroikaBlurRadius.value = blurRadius
uniforms.uTroikaStrokeWidth.value = strokeWidth
uniforms.uTroikaStrokeOpacity.value = strokeOpacity
uniforms.uTroikaFillOpacity.value = fillOpacity == null ? 1 : fillOpacity

@@ -500,2 +594,3 @@ let clipRect = this.clipRect

const color = isOutline ? (this.outlineColor || 0) : this.color
if (color == null) {

@@ -529,2 +624,11 @@ delete material.color //inherit from base

_parsePercent(value) {
if (typeof value === 'string') {
let match = value.match(/^([\d.]+)%$/)
let pct = match ? parseFloat(match[1]) : NaN
value = (isNaN(pct) ? 0 : pct / 100) * this.fontSize
}
return value
}
/**

@@ -531,0 +635,0 @@ * @override Custom raycasting to test against the whole text block's max rectangular bounds

@@ -0,0 +0,0 @@ import { Color, DataTexture, LinearFilter, LuminanceFormat } from 'three'

@@ -13,2 +13,4 @@ import { createDerivedMaterial, voidMainRegExp } from 'troika-three-utils'

uniform float uTroikaDistanceOffset;
uniform float uTroikaBlurRadius;
uniform vec2 uTroikaPositionOffset;
attribute vec4 aTroikaGlyphBounds;

@@ -26,3 +28,9 @@ attribute float aTroikaGlyphIndex;

vec4 bounds = aTroikaGlyphBounds;
vec4 outlineBounds = vec4(bounds.xy - uTroikaDistanceOffset, bounds.zw + uTroikaDistanceOffset);
bounds.xz += uTroikaPositionOffset.x;
bounds.yw -= uTroikaPositionOffset.y;
vec4 outlineBounds = vec4(
bounds.xy - uTroikaDistanceOffset - uTroikaBlurRadius,
bounds.zw + uTroikaDistanceOffset + uTroikaBlurRadius
);
vec4 clippedBounds = vec4(

@@ -32,2 +40,3 @@ clamp(outlineBounds.xy, uTroikaClipRect.xy, uTroikaClipRect.zw),

);
vec2 clippedXY = (mix(clippedBounds.xy, clippedBounds.zw, position.xy) - bounds.xy) / (bounds.zw - bounds.xy);

@@ -65,2 +74,8 @@

uniform float uTroikaDistanceOffset;
uniform float uTroikaFillOpacity;
uniform float uTroikaOutlineOpacity;
uniform float uTroikaBlurRadius;
uniform vec3 uTroikaStrokeColor;
uniform float uTroikaStrokeWidth;
uniform float uTroikaStrokeOpacity;
uniform bool uTroikaSDFDebug;

@@ -92,6 +107,19 @@ varying vec2 vTroikaGlyphUV;

float troikaGetTextAlpha(float distanceOffset) {
float troikaGetAADist() {
${''/*
When the standard derivatives extension is available, we choose an antialiasing alpha threshold based
on the potential change in the SDF's alpha from this fragment to its neighbor. This strategy maximizes
readability and edge crispness at all sizes and screen resolutions.
*/}
#if defined(GL_OES_standard_derivatives) || __VERSION__ >= 300
return length(fwidth(vTroikaGlyphUV * vTroikaGlyphDimensions)) * 0.5;
#else
return vTroikaGlyphDimensions.x / 64.0;
#endif
}
float troikaGetFragDistValue() {
vec2 clampedGlyphUV = clamp(vTroikaGlyphUV, 0.5 / uTroikaSDFGlyphSize, 1.0 - 0.5 / uTroikaSDFGlyphSize);
float distance = troikaGlyphUvToDistance(clampedGlyphUV);
// Extrapolate distance when outside bounds:

@@ -123,17 +151,11 @@ distance += clampedGlyphUV == vTroikaGlyphUV ? 0.0 :

*/}
return distance;
}
float troikaGetEdgeAlpha(float distance, float distanceOffset, float aaDist) {
#if defined(IS_DEPTH_MATERIAL) || defined(IS_DISTANCE_MATERIAL)
float alpha = step(-distanceOffset, -distance);
#else
${''/*
When the standard derivatives extension is available, we choose an antialiasing alpha threshold based
on the potential change in the SDF's alpha from this fragment to its neighbor. This strategy maximizes
readability and edge crispness at all sizes and screen resolutions.
*/}
#if defined(GL_OES_standard_derivatives) || __VERSION__ >= 300
float aaDist = length(fwidth(vTroikaGlyphUV * vTroikaGlyphDimensions)) * 0.5;
#else
float aaDist = vTroikaGlyphDimensions.x / 64.0;
#endif
float alpha = smoothstep(

@@ -145,3 +167,3 @@ distanceOffset + aaDist,

#endif
return alpha;

@@ -153,11 +175,22 @@ }

const FRAGMENT_TRANSFORM = `
float alpha = uTroikaSDFDebug ?
float aaDist = troikaGetAADist();
float distance = troikaGetFragDistValue();
float edgeAlpha = uTroikaSDFDebug ?
troikaGlyphUvToSdfValue(vTroikaGlyphUV) :
troikaGetTextAlpha(uTroikaDistanceOffset);
troikaGetEdgeAlpha(distance, uTroikaDistanceOffset, max(aaDist, uTroikaBlurRadius));
#if !defined(IS_DEPTH_MATERIAL) && !defined(IS_DISTANCE_MATERIAL)
gl_FragColor.a *= alpha;
vec4 fillRGBA = gl_FragColor;
fillRGBA.a *= uTroikaFillOpacity;
vec4 strokeRGBA = uTroikaStrokeWidth == 0.0 ? fillRGBA : vec4(uTroikaStrokeColor, uTroikaStrokeOpacity);
if (fillRGBA.a == 0.0) fillRGBA.rgb = strokeRGBA.rgb;
gl_FragColor = mix(fillRGBA, strokeRGBA, smoothstep(
-uTroikaStrokeWidth - aaDist,
-uTroikaStrokeWidth + aaDist,
distance
));
gl_FragColor.a *= edgeAlpha;
#endif
if (alpha == 0.0) {
if (edgeAlpha == 0.0) {
discard;

@@ -185,2 +218,9 @@ }

uTroikaDistanceOffset: {value: 0},
uTroikaOutlineOpacity: {value: 0},
uTroikaFillOpacity: {value: 1},
uTroikaPositionOffset: {value: new Vector2()},
uTroikaBlurRadius: {value: 0},
uTroikaStrokeWidth: {value: 0},
uTroikaStrokeColor: {value: new Color()},
uTroikaStrokeOpacity: {value: 1},
uTroikaOrient: {value: new Matrix3()},

@@ -187,0 +227,0 @@ uTroikaUseGlyphColors: {value: true},

@@ -21,3 +21,3 @@ /*

import tinyInflate from 'tiny-inflate'
import { inflateSync } from 'fflate'

@@ -126,3 +126,3 @@ export function convert_streams(bufferIn) {

var uncompressedData = new Uint8Array(TableDirectoryEntry.origLength)
tinyInflate(
inflateSync(
new Uint8Array(compressedData, 2), //skip deflate header

@@ -129,0 +129,0 @@ uncompressedData

@@ -0,0 +0,0 @@ /**

@@ -0,0 +0,0 @@ /**

@@ -0,0 +0,0 @@ /**

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc