summaryrefslogtreecommitdiff
path: root/docs/lab/index.html
diff options
context:
space:
mode:
authorRasmus Andersson <rasmus@figma.com>2019-02-04 01:01:11 +0300
committerRasmus Andersson <rasmus@figma.com>2019-02-04 01:01:11 +0300
commit8fd3df4c9f1998e09046bcb6da1f0053018428a4 (patch)
treed69edb5e5cd2e30327d79eb63d5a60d7019df9a3 /docs/lab/index.html
parentc383db7c322b14d31243361a53b4044c5d6c655a (diff)
downloadinter-8fd3df4c9f1998e09046bcb6da1f0053018428a4.tar.xz
super- and subscript brackets (note that there are no Unicode codepoints assigned to these glyphs; they are purely for substitution with sups and subs features)
Diffstat (limited to 'docs/lab/index.html')
-rw-r--r--docs/lab/index.html363
1 files changed, 170 insertions, 193 deletions
diff --git a/docs/lab/index.html b/docs/lab/index.html
index 948f33e0f..f989045c9 100644
--- a/docs/lab/index.html
+++ b/docs/lab/index.html
@@ -216,92 +216,64 @@ left side cascades up to 5 characters:
`)
-samples.set('Feature: sups', `
-Dedicated glyphs, corresponding ASCII, codepoint
-\u2070 \t 0 \t U+2070
-\u00b9 \t 1 \t U+00B9
-\u00b2 \t 2 \t U+00B2
-\u00b3 \t 3 \t U+00B3
-\u2074 \t 4 \t U+2074
-\u2075 \t 5 \t U+2075
-\u2076 \t 6 \t U+2076
-\u2077 \t 7 \t U+2077
-\u2078 \t 8 \t U+2078
-\u2079 \t 9 \t U+2079
-\u207a \t + \t U+207A
-\u207b \t - \t U+207B
-\u207c \t = \t U+207C
-\u207d \t ( \t U+207D
-\u207e \t ) \t U+207E
-\u1d43 \t a \t U+1D43
-\u1d47 \t b \t U+1D47
-\u1d9c \t c \t U+1D9C
-\u1d48 \t d \t U+1D48
-\u1d49 \t e \t U+1D49
-\u1da0 \t f \t U+1DA0
-\u1d4d \t g \t U+1D4D
-\u02b0 \t h \t U+02B0
-\u1da6 \t i \t U+1DA6
-\u02b2 \t j \t U+02B2
-\u1d4f \t k \t U+1D4F
-\u02e1 \t l \t U+02E1
-\u1d50 \t m \t U+1D50
-\u207f \t n \t U+207F
-\u1d52 \t o \t U+1D52
-\u1d56 \t p \t U+1D56
-\u146b \t q \t U+146B
-\u02b3 \t r \t U+02B3
-\u02e2 \t s \t U+02E2
-\u1d57 \t t \t U+1D57
-\u1d58 \t u \t U+1D58
-\u1d5b \t v \t U+1D5B
-\u02b7 \t w \t U+02B7
-\u02e3 \t x \t U+02E3
-\u02b8 \t y \t U+02B8
-\u1dbb \t z \t U+1DBB
-
-(enable sups feature to turn column 2 == column 1)
+samples.set('Feature: sups & subs', `
+#!enableFeatures:tnum,sups
+Superscript and subscript tests
+
+m⁽ˣ⁾[ˣ][³]ᵗ⁺⁴x
+m(x)[x][3]t+4x
+
+Table of super- and subscript characters.
+Enable/disable sups and subs feature to explore substitutions.
+
+sups \t \t \t \t | subs
+———————————————————————
+0 \t \u2070 \t U+2070 \t | 0 \t \u2080 \t U+2080
+1 \t \u00b9 \t U+00B9 \t | 1 \t \u2081 \t U+2081
+2 \t \u00b2 \t U+00B2 \t | 2 \t \u2082 \t U+2082
+3 \t \u00b3 \t U+00B3 \t | 3 \t \u2083 \t U+2083
+4 \t \u2074 \t U+2074 \t | 4 \t \u2084 \t U+2084
+5 \t \u2075 \t U+2075 \t | 5 \t \u2085 \t U+2085
+6 \t \u2076 \t U+2076 \t | 6 \t \u2086 \t U+2086
+7 \t \u2077 \t U+2077 \t | 7 \t \u2087 \t U+2087
+8 \t \u2078 \t U+2078 \t | 8 \t \u2088 \t U+2088
+9 \t \u2079 \t U+2079 \t | 9 \t \u2089 \t U+2089
++ \t \u207a \t U+207A \t | + \t \u208A \t U+208A
+- \t \u207b \t U+207B \t | - \t \u208B \t U+208B
+= \t \u207c \t U+207C \t | = \t \u208C \t U+208C
+( \t \u207d \t U+207D \t | ( \t \u208D \t U+208D
+) \t \u207e \t U+207E \t | ) \t \u208E \t U+208E
+[ \t \u0020 \t \t | [ \t
+] \t \u0020 \t \t | ] \t
+a \t \u1d43 \t U+1D43 \t | a \t \u2090 \t U+2090
+b \t \u1d47 \t U+1D47 \t | b \t
+c \t \u1d9c \t U+1D9C \t | c \t
+d \t \u1d48 \t U+1D48 \t | d \t
+e \t \u1d49 \t U+1D49 \t | e \t \u2091 \t U+2091
+f \t \u1da0 \t U+1DA0 \t | f \t
+g \t \u1d4d \t U+1D4D \t | g \t
+h \t \u02b0 \t U+02B0 \t | h \t \u2095 \t U+2095
+i \t \u1da6 \t U+1DA6 \t | i \t \u1D62 \t U+1D62
+j \t \u02b2 \t U+02B2 \t | j \t \u2C7C \t U+2C7C
+k \t \u1d4f \t U+1D4F \t | k \t \u2096 \t U+2096
+l \t \u02e1 \t U+02E1 \t | l \t \u2097 \t U+2097
+m \t \u1d50 \t U+1D50 \t | m \t \u2098 \t U+2098
+n \t \u207f \t U+207F \t | n \t \u2099 \t U+2099
+o \t \u1d52 \t U+1D52 \t | o \t \u2092 \t U+2092
+p \t \u1d56 \t U+1D56 \t | p \t \u209A \t U+209A
+q \t \u146b \t U+146B \t | q \t
+r \t \u02b3 \t U+02B3 \t | r \t \u1D63 \t U+1D63
+s \t \u02e2 \t U+02E2 \t | s \t \u209B \t U+209B
+t \t \u1d57 \t U+1D57 \t | t \t \u209C \t U+209C
+u \t \u1d58 \t U+1D58 \t | u \t \u1D64 \t U+1D64
+v \t \u1d5b \t U+1D5B \t | v \t \u1D65 \t U+1D65
+w \t \u02b7 \t U+02B7 \t | w \t
+x \t \u02e3 \t U+02E3 \t | x \t \u2093 \t x \t U+2093
+y \t \u02b8 \t U+02B8 \t | y \t
+z \t \u1dbb \t U+1DBB \t | z \t
`)
-samples.set('Feature: subs', `
-Dedicated glyphs, corresponding ASCII, codepoint
-\u2080 \t 0 \t U+2080
-\u2081 \t 1 \t U+2081
-\u2082 \t 2 \t U+2082
-\u2083 \t 3 \t U+2083
-\u2084 \t 4 \t U+2084
-\u2085 \t 5 \t U+2085
-\u2086 \t 6 \t U+2086
-\u2087 \t 7 \t U+2087
-\u2088 \t 8 \t U+2088
-\u2089 \t 9 \t U+2089
-\u208A \t + \t U+208A
-\u208B \t - \t U+208B
-\u208C \t = \t U+208C
-\u208D \t ( \t U+208D
-\u208E \t ) \t U+208E
-\u2090 \t a \t U+2090
-\u2091 \t e \t U+2091
-\u2095 \t h \t U+2095
-\u1D62 \t i \t U+1D62
-\u2C7C \t j \t U+2C7C
-\u2096 \t k \t U+2096
-\u2097 \t l \t U+2097
-\u2098 \t m \t U+2098
-\u2099 \t n \t U+2099
-\u2092 \t o \t U+2092
-\u209A \t p \t U+209A
-\u1D63 \t r \t U+1D63
-\u209B \t s \t U+209B
-\u209C \t t \t U+209C
-\u1D64 \t u \t U+1D64
-\u1D65 \t v \t U+1D65
-\u2093 \t x \t U+2093
-
-(enable subs feature to turn column 2 == column 1)
-`)
-
// From http://justanotherfoundry.com/generator
samples.set('Kerning body en',
@@ -1886,59 +1858,6 @@ function main() {
})
}
- // sample text
- const samplesSelect = document.querySelector('select[name="sample"]')
- for (let [k,v] of samples) {
- const opt = document.createElement('option')
- opt.innerText = k
- if (v) {
- opt.value = k
- } else {
- opt.disabled = true
- }
- samplesSelect.appendChild(opt)
- }
- sampleVar = vars.bind('sample', samplesSelect, (e, v) => {
- let sampleText = samples.get(v) || ''+v
-
- if (v == 'Repertoire') {
- repertoireControl.style.display = null
- } else {
- repertoireControl.style.display = 'none'
- }
-
- if (typeof sampleText == 'object' && sampleText.toHTML) {
- const html = sampleText.toHTML()
- interUISample.innerHTML = html
- secondarySample.innerHTML = html
- } else {
- sampleText = String(sampleText).replace(/^[\s\r\n\r]+|[\s\r\n\r]+$/g, '')
- if (sampleText) {
- interUISample.innerText = sampleText
- secondarySample.innerText = sampleText
- }
- }
-
- if (v == 'Repertoire') {
- requestAnimationFrame(() => {
- if (sizeVar) {
- sizeVar.refreshValue(null)
- }
- })
- }
- })
-
- vars.bind('repertoireOrder', (e, v) => {
- let currOrder = repertoireOrder
- if (v == 'u') {
- repertoireOrder = RepertoireOrderUnicode
- } else {
- repertoireOrder = RepertoireOrderGlyphList
- }
- if (sampleVar && currOrder != repertoireOrder) {
- sampleVar.refreshValue(null)
- }
- })
const lineHeightInput = document.querySelector('[name="lineHeight"]')
let measurePending = false
@@ -1982,6 +1901,67 @@ function main() {
setCSSProp('-ms-' + name, value)
}
+
+ let feats = new Map()
+ let featVars = new Map()
+ let updateFeaturesStyleTimer = null
+
+ function updateFeaturesStyle() {
+ let css = Array.from(feats).map(f => `"${f[0]}" ${f[1]}`).join(', ')
+ setCSSProp('font-feature-settings', css)
+ }
+
+ function scheduleUpdateFeaturesStyle() {
+ if (updateFeaturesStyleTimer === null) {
+ updateFeaturesStyleTimer = setTimeout(() => {
+ updateFeaturesStyleTimer = null
+ updateFeaturesStyle()
+ }, 1)
+ }
+ }
+
+ function setFeature(feat, val, dontUpdateVar/*=false*/) {
+ if (typeof val == 'boolean') {
+ val = val ? 1 : 0
+ }
+ let prevVal = feats.get(feat)
+ if (prevVal !== val) {
+ feats.set(feat, val)
+ scheduleUpdateFeaturesStyle()
+ if (!dontUpdateVar) {
+ let vr = featVars.get(feat)
+ if (vr) {
+ vr.setValue(val)
+ }
+ }
+ }
+ }
+
+ // sample text
+ const samplesSelect = document.querySelector('select[name="sample"]')
+ for (let [k,v] of samples) {
+ const opt = document.createElement('option')
+ opt.innerText = k
+ if (v) {
+ opt.value = k
+ } else {
+ opt.disabled = true
+ }
+ samplesSelect.appendChild(opt)
+ }
+
+ vars.bind('repertoireOrder', (e, v) => {
+ let currOrder = repertoireOrder
+ if (v == 'u') {
+ repertoireOrder = RepertoireOrderUnicode
+ } else {
+ repertoireOrder = RepertoireOrderGlyphList
+ }
+ if (sampleVar && currOrder != repertoireOrder) {
+ sampleVar.refreshValue(null)
+ }
+ })
+
const boxes = document.querySelector('boxes')
sizeVar = vars.bind('size', (e, v) => {
boxes.style.display = (v > 20) ? 'none' : null
@@ -2213,73 +2193,70 @@ function main() {
// setCSSProp('font-variant-numeric', e.value = v)
// })
- let features = new Set()
- for (let e of Array.prototype.slice.call(document.querySelectorAll('input.featopt'))) {
+
+ for (let e of Array.from(document.querySelectorAll('input.featopt'))) {
let p = e.name.replace(/^feat\:/, '').split('=')
- let name = p[0], value = p[1] || '1'
- vars.bind('feat-' + name, e, (e, on) => {
- let val = '"' + name + '" ' + value
- if (on) {
- features.add(val)
- } else {
- features.delete(val)
- }
- setCSSProp('font-feature-settings', Array.from(features).join(', '))
+ let name = p[0]
+ let valueOn = parseInt(p[1] || '1')
+ let valueOff = valueOn == 0 ? 1 : 0
+ let vr = vars.bind('feat-' + name, e, (e, on) => {
+ setFeature(name, on ? valueOn : valueOff, /*dontUpdateVar=*/true)
})
+ featVars.set(name, vr)
}
- function initCanvas(canvas) {
- const w = parseInt(canvas.width)
- const h = parseInt(canvas.height)
- const scale = window.devicePixelRatio || 1
- if (scale != 1) {
- canvas.width = w * scale
- canvas.height = h * scale
- canvas.style.width = w + 'px'
- canvas.style.height = h + 'px'
- }
- }
+ updateFeaturesStyle()
- initCanvas(renderCanvas)
- initCanvas(displayCanvas)
-
- function rasterize(text) {
- const ctx = renderCanvas.getContext('2d')
- const width = parseInt(renderCanvas.width)
- const height = parseInt(renderCanvas.height)
-
- ctx.clearRect(0, 0, width, height)
-
- ctx.font = '22px/36px ' + fontFamilyName
- ctx.fillText(text, 4, 24)
-
- ctx.font = '11px/18px ' + fontFamilyName
- ctx.fillText(text, 4, 44)
-
- const zctx = displayCanvas.getContext('2d')
- zctx.webkitImageSmoothingEnabled = false;
- zctx.mozImageSmoothingEnabled = false;
- zctx.imageSmoothingEnabled = false;
- const zwidth = parseInt(displayCanvas.width)
- const zheight = parseInt(displayCanvas.height)
- zctx.clearRect(0, 0, zwidth, zheight)
- zctx.drawImage(
- renderCanvas,
- 0, 0, width, height,
- 0, 0, zwidth, zheight
- )
- }
+ sampleVar = vars.bind('sample', samplesSelect, (e, v) => {
+ let sampleText = samples.get(v) || ''+v
+
+ if (v == 'Repertoire') {
+ repertoireControl.style.display = null
+ } else {
+ repertoireControl.style.display = 'none'
+ }
- let didSetInitialValue = false
+ if (typeof sampleText == 'object' && sampleText.toHTML) {
+ const html = sampleText.toHTML()
+ interUISample.innerHTML = html
+ secondarySample.innerHTML = html
+ } else {
+ // look for directive
+ // #!directive:value
+ sampleText = String(sampleText).replace(/^[\s\r\n\r]+|[\s\r\n\r]+$/g, '')
+ let m = /(?:^|\n)#\!([\w_\-]+):(.+)(?:\n|$)/.exec(sampleText)
+ if (m) {
+ // parse directive
+ sampleText = (
+ sampleText.substring(0, m.index) +
+ sampleText.substr(m.index + m[0].length)
+ )
+ let directive = m[1].toLowerCase()
+ console.log('dir', m[1], '=>', m[2])
+ if (directive == 'enablefeatures') {
+ // #!enableFeatures:tnum,dlig
+ for (let feat of m[2].toLowerCase().split(/\s*,\s*/)) {
+ setFeature(feat, 1)
+ }
+ } else {
+ console.warn(`ignoring unknown directive ${m[0]} in sample text`)
+ }
+ }
+ if (sampleText) {
+ interUISample.innerText = sampleText
+ secondarySample.innerText = sampleText
+ }
+ }
- let rasterizePhraseVar = vars.bind('rasterizePhrase', (e, v) => {
- if (document.readyState == 'complete') {
- rasterize(v)
+ if (v == 'Repertoire') {
+ requestAnimationFrame(() => {
+ if (sizeVar) {
+ sizeVar.refreshValue(null)
+ }
+ })
}
})
- document.onreadystatechange = () => vars.refreshValue('rasterizePhrase')
-
}
</script>
</body>