Browse Source

improved font size/quality handling

Alexander Rose 6 years ago
parent
commit
460f8081fe

+ 16 - 11
src/mol-geo/geometry/text/font-atlas.ts

@@ -6,7 +6,7 @@
 
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { edt } from 'mol-math/geometry/distance-transform';
-import { createTextureImage } from 'mol-gl/renderable/util';
+import { createTextureImage, TextureImage } from 'mol-gl/renderable/util';
 
 const TextAtlasCache: { [k: string]: FontAtlas } = {}
 
@@ -25,7 +25,7 @@ export type FontWeight = 'normal' | 'bold'
 
 export const FontAtlasParams = {
   fontFamily: PD.Select('sans-serif', [['sans-serif', 'Sans Serif'], ['monospace', 'Monospace'], ['serif', 'Serif'], ['cursive', 'Cursive']] as [FontFamily, string][]),
-  fontSize: PD.Numeric(36, { min: 4, max: 96, step: 1 }),
+  fontQuality: PD.Select(3, [[0, 'lower'], [1, 'low'], [2, 'medium'], [3, 'high'], [4, 'higher']]),
   fontStyle: PD.Select('normal', [['normal', 'Normal'], ['italic', 'Italic'], ['oblique', 'Oblique']] as [FontStyle, string][]),
   fontVariant: PD.Select('normal', [['normal', 'Normal'], ['small-caps', 'Small Caps']] as [FontVariant, string][]),
   fontWeight: PD.Select('normal', [['normal', 'Normal'], ['bold', 'Bold']] as [FontWeight, string][]),
@@ -42,7 +42,7 @@ export class FontAtlas {
     readonly props: Readonly<FontAtlasProps>
     readonly mapped: { [k: string]: FontAtlasMap } = {}
     readonly placeholder: FontAtlasMap
-    readonly texture = createTextureImage(4096 * 2048, 1)
+    readonly texture: TextureImage<Uint8Array>
 
     private scratchW = 0
     private scratchH = 0
@@ -73,18 +73,23 @@ export class FontAtlas {
         const p = { ...PD.getDefaultValues(FontAtlasParams), ...props }
         this.props = p
 
-        this.buffer = p.fontSize / 8
-        this.radius = p.fontSize / 3
-        this.lineHeight = Math.round(p.fontSize + 2 * this.buffer + this.radius)
-        this.maxWidth = this.lineHeight * 1.5
+        // create measurements
+        const fontSize = 32 * p.fontQuality
+        this.buffer = fontSize / 8
+        this.radius = fontSize / 3
+        this.lineHeight = Math.round(fontSize + 2 * this.buffer + this.radius)
+        this.maxWidth = Math.round(this.lineHeight * 0.75)
 
-        // Prepare scratch canvas
+        // create texture
+        this.texture = createTextureImage(350 * this.lineHeight * this.maxWidth, 1)
+
+        // prepare scratch canvas
         this.scratchCanvas = document.createElement('canvas')
         this.scratchCanvas.width = this.maxWidth
         this.scratchCanvas.height = this.lineHeight
 
         this.scratchContext = this.scratchCanvas.getContext('2d')!
-        this.scratchContext.font = `${p.fontStyle} ${p.fontVariant} ${p.fontWeight} ${p.fontSize}px ${p.fontFamily}`
+        this.scratchContext.font = `${p.fontStyle} ${p.fontVariant} ${p.fontWeight} ${fontSize}px ${p.fontFamily}`
         this.scratchContext.fillStyle = 'black'
         this.scratchContext.textBaseline = 'middle'
 
@@ -101,7 +106,7 @@ export class FontAtlas {
 
         this.middle = Math.ceil(this.lineHeight / 2)
 
-        // Replacement Character
+        // replacement Character
         this.placeholder = this.get(String.fromCharCode(0xFFFD))
     }
 
@@ -144,7 +149,7 @@ export class FontAtlas {
         const ctx = this.scratchContext
         const data = this.scratchData
 
-        // Measure text
+        // measure text
         const m = ctx.measureText(char)
         const w = Math.min(this.maxWidth, Math.ceil(m.width + 2 * this.buffer))
         const n = w * h

+ 0 - 3
src/mol-geo/geometry/text/text-builder.ts

@@ -34,9 +34,6 @@ export namespace TextBuilder {
         const fontAtlas = getFontAtlas(p)
         const margin = (1 / 2.5) * backgroundMargin
         const outline = fontAtlas.buffer / fontAtlas.lineHeight
-        // console.log('margin', margin)
-        // console.log('attachment', attachment)
-        // console.log('background', background)
 
         return {
             add: (str: string, x: number, y: number, z: number, group: number) => {

+ 1 - 1
src/mol-gl/renderer.ts

@@ -180,9 +180,9 @@ namespace Renderer {
 
                 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
                 gl.enable(gl.BLEND)
-                gl.depthMask(false)
                 for (let i = 0, il = renderables.length; i < il; ++i) {
                     const r = renderables[i]
+                    gl.depthMask(r.values.uAlpha.ref.value === 1.0)
                     if (!r.state.opaque) renderObject(r, variant)
                 }
             } else {

+ 1 - 2
src/mol-gl/shader/chunks/apply-fog.glsl

@@ -1,10 +1,9 @@
 #ifdef dUseFog
 	float depth = length(vViewPosition);
-    // float depth = gl_FragCoord.z / gl_FragCoord.w;
     float fogFactor = smoothstep(uFogNear, uFogFar, depth);
 	gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor);
     float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a;
     if (fogAlpha < 0.01)
         discard;
-    gl_FragColor = vec4( gl_FragColor.rgb, fogAlpha );
+    gl_FragColor = vec4(gl_FragColor.rgb, fogAlpha);
 #endif

+ 2 - 1
src/tests/browser/font-atlas.ts

@@ -10,7 +10,7 @@ import { printTextureImage } from 'mol-gl/renderable/util';
 
 function test() {
     console.time('FontAtlas init')
-    const fontAtlas = new FontAtlas({ fontSize: 96 })
+    const fontAtlas = new FontAtlas({ fontQuality: 3 })
     console.timeEnd('FontAtlas init')
 
     console.time('Basic Latin (subset)')
@@ -34,6 +34,7 @@ function test() {
     console.timeEnd('Angstrom Sign')
 
     printTextureImage(fontAtlas.texture, 0.5)
+    console.log(`${Object.keys(fontAtlas.mapped).length} chars prepared`)
 }
 
 test();

+ 1 - 1
src/tests/browser/render-text.ts

@@ -32,7 +32,7 @@ function textRepr() {
     const props: PD.Values<Text.Params> = {
         ...PD.getDefaultValues(Text.Params),
         attachment: 'middle-center',
-        fontSize: 96,
+        fontQuality: 3,
         fontWeight: 'normal',
         borderWidth: 0.3
     }