michael@0: michael@0: // data associated with gsubtest test font for testing font features michael@0: michael@0: // prefix michael@0: gPrefix = ""; michael@0: michael@0: // equivalent properties michael@0: // setting prop: value should match the specific feature settings listed michael@0: // michael@0: // each of these tests evaluate whether a given feature is enabled as required michael@0: // and also whether features that shouldn't be enabled are or not. michael@0: var gPropertyData = [ michael@0: // font-variant-caps michael@0: // valid values michael@0: { prop: "font-variant-caps", value: "normal", features: {"smcp": 0} }, michael@0: { prop: "font-variant-caps", value: "small-caps", features: {"smcp": 1, "c2sc": 0} }, michael@0: { prop: "font-variant-caps", value: "all-small-caps", features: {"smcp": 1, "c2sc": 1, "pcap": 0} }, michael@0: { prop: "font-variant-caps", value: "petite-caps", features: {"pcap": 1, "smcp": 0} }, michael@0: { prop: "font-variant-caps", value: "all-petite-caps", features: {"c2pc": 1, "pcap": 1, "smcp": 0} }, michael@0: { prop: "font-variant-caps", value: "titling-caps", features: {"titl": 1, "smcp": 0} }, michael@0: { prop: "font-variant-caps", value: "unicase", features: {"unic": 1, "titl": 0} }, michael@0: michael@0: // invalid values michael@0: { prop: "font-variant-caps", value: "normal small-caps", features: {"smcp": 0}, invalid: true }, michael@0: { prop: "font-variant-caps", value: "small-caps potato", features: {"smcp": 0}, invalid: true }, michael@0: { prop: "font-variant-caps", value: "small-caps petite-caps", features: {"smcp": 0, "pcap": 0}, invalid: true }, michael@0: { prop: "font-variant-caps", value: "small-caps all-small-caps", features: {"smcp": 0, "c2sc": 0}, invalid: true }, michael@0: { prop: "font-variant-caps", value: "small-cap", features: {"smcp": 0}, invalid: true }, michael@0: michael@0: // font-variant-east-asian michael@0: // valid values michael@0: { prop: "font-variant-east-asian", value: "jis78", features: {"jp78": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "jis83", features: {"jp83": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "jis90", features: {"jp90": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "jis04", features: {"jp04": 1, "jp78": 0} }, michael@0: { prop: "font-variant-east-asian", value: "simplified", features: {"smpl": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "traditional", features: {"trad": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "full-width", features: {"fwid": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "proportional-width", features: {"pwid": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "ruby", features: {"ruby": 1, "jp04": 0} }, michael@0: { prop: "font-variant-east-asian", value: "jis78 full-width", features: {"jp78": 1, "fwid": 1, "jp83": 0} }, michael@0: { prop: "font-variant-east-asian", value: "jis78 full-width ruby", features: {"jp78": 1, "fwid": 1, "jp83": 0, "ruby": 1} }, michael@0: { prop: "font-variant-east-asian", value: "simplified proportional-width", features: {"smpl": 1, "pwid": 1, "jp83": 0} }, michael@0: { prop: "font-variant-east-asian", value: "ruby simplified", features: {"ruby": 1, "smpl": 1, "trad": 0} }, michael@0: michael@0: // invalid values michael@0: { prop: "font-variant-east-asian", value: "ruby normal", features: {"ruby": 0}, invalid: true }, michael@0: { prop: "font-variant-east-asian", value: "jis90 jis04", features: {"jp90": 0, "jp04": 0}, invalid: true }, michael@0: { prop: "font-variant-east-asian", value: "simplified traditional", features: {"smpl": 0, "trad": 0}, invalid: true }, michael@0: { prop: "font-variant-east-asian", value: "full-width proportional-width", features: {"fwid": 0, "pwid": 0}, invalid: true }, michael@0: { prop: "font-variant-east-asian", value: "ruby simplified ruby", features: {"ruby": 0, "smpl": 0, "jp04": 0}, invalid: true }, michael@0: { prop: "font-variant-east-asian", value: "jis78 ruby simplified", features: {"ruby": 0, "smpl": 0, "jp78": 0}, invalid: true }, michael@0: michael@0: // font-variant-ligatures michael@0: // valid values michael@0: { prop: "font-variant-ligatures", value: "none", features: {"liga": 0, "dlig": 0, "clig": 0, "calt": 0, "hlig": 0} }, michael@0: { prop: "font-variant-ligatures", value: "normal", features: {"liga": 1, "dlig": 0} }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "no-common-ligatures", features: {"liga": 0, "clig": 0, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 1, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "no-discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 1, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "no-historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "no-contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 0} }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures no-discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "historical-ligatures no-common-ligatures", features: {"clig": 0, "liga": 0, "dlig": 0, "hlig": 1, "calt": 1} }, michael@0: { prop: "font-variant-ligatures", value: "no-historical-ligatures discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 1, "hlig": 0, "calt": 1} }, michael@0: { 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} }, michael@0: michael@0: // invalid values michael@0: { prop: "font-variant-ligatures", value: "common-ligatures none", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "none common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures normal", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures no-common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "no-historical-ligatures historical-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "no-contextual contextual", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "no-discretionary-ligatures discretionary-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: { prop: "font-variant-ligatures", value: "common-ligatures no-discretionary-ligatures no-common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0}, invalid: true }, michael@0: michael@0: // font-variant-numeric michael@0: // valid values michael@0: { prop: "font-variant-numeric", value: "normal", features: {"lnum": 0, "tnum": 0, "pnum": 0, "onum": 0} }, michael@0: { prop: "font-variant-numeric", value: "lining-nums", features: {"lnum": 1, "onum": 0, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "oldstyle-nums", features: {"lnum": 0, "onum": 1, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "proportional-nums", features: {"lnum": 0, "onum": 0, "pnum": 1, "tnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "proportional-nums oldstyle-nums", features: {"lnum": 0, "onum": 1, "pnum": 1, "tnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "tabular-nums", features: {"tnum": 1, "onum": 0, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "diagonal-fractions", features: {"frac": 1, "afrc": 0, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "stacked-fractions", features: {"frac": 0, "afrc": 1, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "slashed-zero", features: {"zero": 1, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "ordinal", features: {"ordn": 1, "pnum": 0} }, michael@0: { prop: "font-variant-numeric", value: "lining-nums diagonal-fractions", features: {"frac": 1, "afrc": 0, "lnum": 1} }, michael@0: { prop: "font-variant-numeric", value: "tabular-nums stacked-fractions", features: {"frac": 0, "afrc": 1, "tnum": 1} }, michael@0: { prop: "font-variant-numeric", value: "tabular-nums slashed-zero stacked-fractions", features: {"frac": 0, "afrc": 1, "tnum": 1, "zero": 1} }, michael@0: { 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} }, michael@0: michael@0: // invalid values michael@0: { prop: "font-variant-numeric", value: "lining-nums normal", features: {"lnum": 0, "onum": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "lining-nums oldstyle-nums", features: {"lnum": 0, "onum": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "lining-nums normal slashed-zero ordinal", features: {"lnum": 0, "onum": 0, "zero": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "proportional-nums tabular-nums", features: {"pnum": 0, "tnum": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "diagonal-fractions stacked-fractions", features: {"frac": 0, "afrc": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "slashed-zero diagonal-fractions slashed-zero", features: {"frac": 0, "afrc": 0, "zero": 0}, invalid: true }, michael@0: { prop: "font-variant-numeric", value: "lining-nums slashed-zero diagonal-fractions oldstyle-nums", features: {"frac": 0, "afrc": 0, "zero": 0, "onum": 0}, invalid: true }, michael@0: michael@0: // font-variant-position michael@0: // valid values michael@0: { prop: "font-variant-position", value: "normal", features: {"subs": 0, "sups": 0} }, michael@0: { prop: "font-variant-position", value: "super", features: {"subs": 0, "sups": 1} }, michael@0: { prop: "font-variant-position", value: "sub", features: {"subs": 1, "sups": 0} }, michael@0: michael@0: // invalid values michael@0: { prop: "font-variant-position", value: "super sub", features: {"subs": 0, "sups": 0}, invalid: true }, michael@0: ]; michael@0: michael@0: // note: the code below requires an array "gFeatures" from : michael@0: // layout/reftests/fonts/gsubtest/gsubtest-features.js michael@0: michael@0: // The font defines feature lookups for all OpenType features for a michael@0: // specific set of PUA codepoints, as listed in the gFeatures array. michael@0: // Using these codepoints and feature combinations, tests can be michael@0: // constructed to detect when certain features are enabled or not. michael@0: michael@0: // return a created table containing tests for a given property michael@0: // michael@0: // Ex: { prop: "font-variant-ligatures", value: "common-ligatures", features: {"liga": 1, "clig": 1, "dlig": 0, "hlig": 0} } michael@0: // michael@0: // This means that for the property 'font-variant-ligatures' with the value 'common-ligatures', the features listed should michael@0: // either be explicitly enabled or disabled. michael@0: michael@0: // propData is the prop/value list with corresponding feature assertions michael@0: // whichProp is either "all" or a specific subproperty (i.e. "font-variant-position") michael@0: // isRef is true when this is the reference michael@0: // debug outputs the prop/value pair along with the tests michael@0: michael@0: function createFeatureTestTable(propData, whichProp, isRef, debug) michael@0: { michael@0: var table = document.createElement("table"); michael@0: michael@0: if (typeof(isRef) == "undefined") { michael@0: isRef = false; michael@0: } michael@0: michael@0: if (typeof(debug) == "undefined") { michael@0: debug = false; michael@0: } michael@0: michael@0: var doAll = (whichProp == "all"); michael@0: for (var i in propData) { michael@0: var data = propData[i]; michael@0: michael@0: if (!doAll && data.prop != whichProp) continue; michael@0: michael@0: var row = document.createElement("tr"); michael@0: var invalid = false; michael@0: if ("invalid" in data) { michael@0: invalid = true; michael@0: row.className = "invalid"; michael@0: } michael@0: michael@0: var cell = document.createElement("td"); michael@0: cell.className = "prop"; michael@0: var styledecl = gPrefix + data.prop + ": " + data.value + ";"; michael@0: cell.innerHTML = styledecl; michael@0: row.appendChild(cell); michael@0: if (debug) { michael@0: table.appendChild(row); michael@0: } michael@0: michael@0: row = document.createElement("tr"); michael@0: if (invalid) { michael@0: row.className = "invalid"; michael@0: } michael@0: michael@0: cell = document.createElement("td"); michael@0: cell.className = "features"; michael@0: if (!isRef) { michael@0: cell.style.cssText = styledecl; michael@0: } michael@0: michael@0: for (var f in data.features) { michael@0: var feature = data.features[f]; michael@0: michael@0: var cp, unsupported = "F".charCodeAt(0); michael@0: var basecp = gFeatures[f]; michael@0: michael@0: if (typeof(basecp) == "undefined") { michael@0: cp = unsupported; michael@0: } else { michael@0: switch(feature) { michael@0: case 0: michael@0: cp = basecp; michael@0: break; michael@0: case 1: michael@0: cp = basecp + 1; michael@0: break; michael@0: case 2: michael@0: cp = basecp + 2; michael@0: break; michael@0: case 3: michael@0: cp = basecp + 3; michael@0: break; michael@0: default: michael@0: cp = basecp + 1; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: var span = document.createElement("span"); michael@0: span.innerHTML = (isRef ? "P " : "&#x" + cp.toString(16) + "; "); michael@0: span.title = f + "=" + feature; michael@0: cell.appendChild(span); michael@0: } michael@0: row.appendChild(cell); michael@0: table.appendChild(row); michael@0: } michael@0: michael@0: return table; michael@0: } michael@0: michael@0: