font-variant-features.js (12666B)
1 // data associated with gsubtest test font for testing font features 2 3 // prefix 4 gPrefix = ""; 5 6 // equivalent properties 7 // setting prop: value should match the specific feature settings listed 8 // 9 // each of these tests evaluate whether a given feature is enabled as required 10 // and also whether features that shouldn't be enabled are or not. 11 var gPropertyData = [ 12 // font-variant-caps 13 // valid values 14 { prop: "font-variant-caps", value: "normal", features: {"smcp": 0} }, 15 { prop: "font-variant-caps", value: "small-caps", features: {"smcp": 1, "c2sc": 0} }, 16 { prop: "font-variant-caps", value: "all-small-caps", features: {"smcp": 1, "c2sc": 1, "pcap": 0} }, 17 { prop: "font-variant-caps", value: "petite-caps", features: {"pcap": 1, "smcp": 0} }, 18 { prop: "font-variant-caps", value: "all-petite-caps", features: {"c2pc": 1, "pcap": 1, "smcp": 0} }, 19 { prop: "font-variant-caps", value: "titling-caps", features: {"titl": 1, "smcp": 0} }, 20 { prop: "font-variant-caps", value: "unicase", features: {"unic": 1, "titl": 0} }, 21 22 // invalid values 23 { prop: "font-variant-caps", value: "normal small-caps", features: {"smcp": 0}, invalid: true }, 24 { prop: "font-variant-caps", value: "small-caps potato", features: {"smcp": 0}, invalid: true }, 25 { prop: "font-variant-caps", value: "small-caps petite-caps", features: {"smcp": 0, "pcap": 0}, invalid: true }, 26 { prop: "font-variant-caps", value: "small-caps all-small-caps", features: {"smcp": 0, "c2sc": 0}, invalid: true }, 27 { prop: "font-variant-caps", value: "small-cap", features: {"smcp": 0}, invalid: true }, 28 29 // font-variant-east-asian 30 // valid values 31 { prop: "font-variant-east-asian", value: "jis78", features: {"jp78": 1, "jp04": 0} }, 32 { prop: "font-variant-east-asian", value: "jis83", features: {"jp83": 1, "jp04": 0} }, 33 { prop: "font-variant-east-asian", value: "jis90", features: {"jp90": 1, "jp04": 0} }, 34 { prop: "font-variant-east-asian", value: "jis04", features: {"jp04": 1, "jp78": 0} }, 35 { prop: "font-variant-east-asian", value: "simplified", features: {"smpl": 1, "jp04": 0} }, 36 { prop: "font-variant-east-asian", value: "traditional", features: {"trad": 1, "jp04": 0} }, 37 { prop: "font-variant-east-asian", value: "full-width", features: {"fwid": 1, "jp04": 0} }, 38 { prop: "font-variant-east-asian", value: "proportional-width", features: {"pwid": 1, "jp04": 0} }, 39 { prop: "font-variant-east-asian", value: "ruby", features: {"ruby": 1, "jp04": 0} }, 40 { prop: "font-variant-east-asian", value: "jis78 full-width", features: {"jp78": 1, "fwid": 1, "jp83": 0} }, 41 { prop: "font-variant-east-asian", value: "jis78 full-width ruby", features: {"jp78": 1, "fwid": 1, "jp83": 0, "ruby": 1} }, 42 { prop: "font-variant-east-asian", value: "simplified proportional-width", features: {"smpl": 1, "pwid": 1, "jp83": 0} }, 43 { prop: "font-variant-east-asian", value: "ruby simplified", features: {"ruby": 1, "smpl": 1, "trad": 0} }, 44 45 // invalid values 46 { prop: "font-variant-east-asian", value: "ruby normal", features: {"ruby": 0}, invalid: true }, 47 { prop: "font-variant-east-asian", value: "jis90 jis04", features: {"jp90": 0, "jp04": 0}, invalid: true }, 48 { prop: "font-variant-east-asian", value: "simplified traditional", features: {"smpl": 0, "trad": 0}, invalid: true }, 49 { prop: "font-variant-east-asian", value: "full-width proportional-width", features: {"fwid": 0, "pwid": 0}, invalid: true }, 50 { prop: "font-variant-east-asian", value: "ruby simplified ruby", features: {"ruby": 0, "smpl": 0, "jp04": 0}, invalid: true }, 51 { prop: "font-variant-east-asian", value: "jis78 ruby simplified", features: {"ruby": 0, "smpl": 0, "jp78": 0}, invalid: true }, 52 53 // font-variant-ligatures 54 // valid values 55 { prop: "font-variant-ligatures", value: "normal", features: {"liga": 1, "dlig": 0} }, 56 { prop: "font-variant-ligatures", value: "common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, 57 { prop: "font-variant-ligatures", value: "no-common-ligatures", features: {"liga": 0, "clig": 0, "dlig": 0, "hlig": 0, "calt": 1} }, 58 { prop: "font-variant-ligatures", value: "discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 1, "hlig": 0, "calt": 1} }, 59 { prop: "font-variant-ligatures", value: "no-discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, 60 { prop: "font-variant-ligatures", value: "historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 1, "calt": 1} }, 61 { prop: "font-variant-ligatures", value: "no-historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, 62 { prop: "font-variant-ligatures", value: "contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, 63 { prop: "font-variant-ligatures", value: "no-contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 0} }, 64 { prop: "font-variant-ligatures", value: "common-ligatures no-discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, 65 { prop: "font-variant-ligatures", value: "historical-ligatures no-common-ligatures", features: {"clig": 0, "liga": 0, "dlig": 0, "hlig": 1, "calt": 1} }, 66 { prop: "font-variant-ligatures", value: "no-historical-ligatures discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 1, "hlig": 0, "calt": 1} }, 67 { prop: "font-variant-ligatures", value: "common-ligatures no-discretionary-ligatures historical-ligatures no-contextual", features: {"clig": 1, "dlig": 0, "hlig": 1, "liga": 1, "calt": 0} }, 68 69 // invalid values 70 { prop: "font-variant-ligatures", value: "common-ligatures normal", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, 71 { prop: "font-variant-ligatures", value: "common-ligatures no-common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, 72 { prop: "font-variant-ligatures", value: "common-ligatures common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, 73 { prop: "font-variant-ligatures", value: "no-historical-ligatures historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0}, invalid: true }, 74 { prop: "font-variant-ligatures", value: "no-contextual contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0}, invalid: true }, 75 { prop: "font-variant-ligatures", value: "no-discretionary-ligatures discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, 76 { prop: "font-variant-ligatures", value: "common-ligatures no-discretionary-ligatures no-common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, 77 78 // font-variant-numeric 79 // valid values 80 { prop: "font-variant-numeric", value: "normal", features: {"lnum": 0, "tnum": 0, "pnum": 0, "onum": 0} }, 81 { prop: "font-variant-numeric", value: "lining-nums", features: {"lnum": 1, "onum": 0, "pnum": 0} }, 82 { prop: "font-variant-numeric", value: "oldstyle-nums", features: {"lnum": 0, "onum": 1, "pnum": 0} }, 83 { prop: "font-variant-numeric", value: "proportional-nums", features: {"lnum": 0, "onum": 0, "pnum": 1, "tnum": 0} }, 84 { prop: "font-variant-numeric", value: "proportional-nums oldstyle-nums", features: {"lnum": 0, "onum": 1, "pnum": 1, "tnum": 0} }, 85 { prop: "font-variant-numeric", value: "tabular-nums", features: {"tnum": 1, "onum": 0, "pnum": 0} }, 86 { prop: "font-variant-numeric", value: "diagonal-fractions", features: {"frac": 1, "afrc": 0, "pnum": 0} }, 87 { prop: "font-variant-numeric", value: "stacked-fractions", features: {"frac": 0, "afrc": 1, "pnum": 0} }, 88 { prop: "font-variant-numeric", value: "slashed-zero", features: {"zero": 1, "pnum": 0} }, 89 { prop: "font-variant-numeric", value: "ordinal", features: {"ordn": 1, "pnum": 0} }, 90 { prop: "font-variant-numeric", value: "lining-nums diagonal-fractions", features: {"frac": 1, "afrc": 0, "lnum": 1} }, 91 { prop: "font-variant-numeric", value: "tabular-nums stacked-fractions", features: {"frac": 0, "afrc": 1, "tnum": 1} }, 92 { prop: "font-variant-numeric", value: "tabular-nums slashed-zero stacked-fractions", features: {"frac": 0, "afrc": 1, "tnum": 1, "zero": 1} }, 93 { prop: "font-variant-numeric", value: "proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal", features: {"frac": 1, "afrc": 0, "tnum": 0, "pnum": 1, "onum": 1, "ordn": 1, "zero": 1} }, 94 95 // invalid values 96 { prop: "font-variant-numeric", value: "lining-nums normal", features: {"lnum": 0, "onum": 0}, invalid: true }, 97 { prop: "font-variant-numeric", value: "lining-nums oldstyle-nums", features: {"lnum": 0, "onum": 0}, invalid: true }, 98 { prop: "font-variant-numeric", value: "lining-nums normal slashed-zero ordinal", features: {"lnum": 0, "onum": 0, "zero": 0}, invalid: true }, 99 { prop: "font-variant-numeric", value: "proportional-nums tabular-nums", features: {"pnum": 0, "tnum": 0}, invalid: true }, 100 { prop: "font-variant-numeric", value: "diagonal-fractions stacked-fractions", features: {"frac": 0, "afrc": 0}, invalid: true }, 101 { prop: "font-variant-numeric", value: "slashed-zero diagonal-fractions slashed-zero", features: {"frac": 0, "afrc": 0, "zero": 0}, invalid: true }, 102 { prop: "font-variant-numeric", value: "lining-nums slashed-zero diagonal-fractions oldstyle-nums", features: {"frac": 0, "afrc": 0, "zero": 0, "onum": 0}, invalid: true }, 103 104 // font-variant-position 105 // valid values 106 { prop: "font-variant-position", value: "normal", features: {"subs": 0, "sups": 0} }, 107 { prop: "font-variant-position", value: "super", features: {"subs": 0, "sups": 1} }, 108 { prop: "font-variant-position", value: "sub", features: {"subs": 1, "sups": 0} }, 109 110 // invalid values 111 { prop: "font-variant-position", value: "super sub", features: {"subs": 0, "sups": 0}, invalid: true }, 112 ]; 113 114 // note: the code below requires an array "gFeatures" from : 115 // support/fonts/gsubtest-features.js 116 117 // The font defines feature lookups for all OpenType features for a 118 // specific set of PUA codepoints, as listed in the gFeatures array. 119 // Using these codepoints and feature combinations, tests can be 120 // constructed to detect when certain features are enabled or not. 121 122 // return a created table containing tests for a given property 123 // 124 // Ex: { prop: "font-variant-ligatures", value: "common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0} } 125 // 126 // This means that for the property 'font-variant-ligatures' with the value 'common-ligatures', the features listed should 127 // either be explicitly enabled or disabled. 128 129 // propData is the prop/value list with corresponding feature assertions 130 // whichProp is either "all" or a specific subproperty (i.e. "font-variant-position") 131 // isRef is true when this is the reference 132 // debug outputs the prop/value pair along with the tests 133 134 function createFeatureTestTable(propData, whichProp, isRef, debug) 135 { 136 var table = document.createElement("table"); 137 138 if (typeof(isRef) == "undefined") { 139 isRef = false; 140 } 141 142 if (typeof(debug) == "undefined") { 143 debug = false; 144 } 145 146 var doAll = (whichProp == "all"); 147 for (var i in propData) { 148 var data = propData[i]; 149 150 if (!doAll && data.prop != whichProp) continue; 151 152 var row = document.createElement("tr"); 153 var invalid = false; 154 if ("invalid" in data) { 155 invalid = true; 156 row.className = "invalid"; 157 } 158 159 var cell = document.createElement("td"); 160 cell.className = "prop"; 161 var styledecl = gPrefix + data.prop + ": " + data.value + ";"; 162 cell.innerHTML = styledecl; 163 row.appendChild(cell); 164 if (debug) { 165 table.appendChild(row); 166 } 167 168 row = document.createElement("tr"); 169 if (invalid) { 170 row.className = "invalid"; 171 } 172 173 cell = document.createElement("td"); 174 cell.className = "features"; 175 if (!isRef) { 176 cell.style.cssText = styledecl; 177 } 178 179 for (var f in data.features) { 180 var feature = data.features[f]; 181 182 var cp, unsupported = "F".charCodeAt(0); 183 var basecp = gFeatures[f]; 184 185 if (typeof(basecp) == "undefined") { 186 cp = unsupported; 187 } else { 188 switch(feature) { 189 case 0: 190 cp = basecp; 191 break; 192 case 1: 193 cp = basecp + 1; 194 break; 195 case 2: 196 cp = basecp + 2; 197 break; 198 case 3: 199 cp = basecp + 3; 200 break; 201 default: 202 cp = basecp + 1; 203 break; 204 } 205 } 206 207 var span = document.createElement("span"); 208 span.innerHTML = (isRef ? "P " : "&#x" + cp.toString(16) + "; "); 209 span.title = f + "=" + feature; 210 cell.appendChild(span); 211 } 212 row.appendChild(cell); 213 table.appendChild(row); 214 } 215 216 return table; 217 }