diff --git a/css/css-fonts/resources/vs/MPLUS1-Regular_without-cmap14-subset.ttf b/css/css-fonts/resources/vs/MPLUS1-Regular_without-cmap14-subset.ttf new file mode 100644 index 00000000000000..b77096690df1b4 Binary files /dev/null and b/css/css-fonts/resources/vs/MPLUS1-Regular_without-cmap14-subset.ttf differ diff --git a/css/css-fonts/resources/vs/NotoColorEmoji-Regular_subset.ttf b/css/css-fonts/resources/vs/NotoColorEmoji-Regular_subset.ttf new file mode 100644 index 00000000000000..24ab79fd052951 Binary files /dev/null and b/css/css-fonts/resources/vs/NotoColorEmoji-Regular_subset.ttf differ diff --git a/css/css-fonts/resources/vs/NotoEmoji-Regular_subset.ttf b/css/css-fonts/resources/vs/NotoEmoji-Regular_subset.ttf new file mode 100644 index 00000000000000..0b054c7c8d597e Binary files /dev/null and b/css/css-fonts/resources/vs/NotoEmoji-Regular_subset.ttf differ diff --git a/css/css-fonts/resources/vs/NotoEmoji-Regular_without-cmap14-subset.ttf b/css/css-fonts/resources/vs/NotoEmoji-Regular_without-cmap14-subset.ttf new file mode 100644 index 00000000000000..3d00ef81dea38d Binary files /dev/null and b/css/css-fonts/resources/vs/NotoEmoji-Regular_without-cmap14-subset.ttf differ diff --git a/css/css-fonts/resources/vs/NotoSansJP-Regular_with-cmap14-subset.ttf b/css/css-fonts/resources/vs/NotoSansJP-Regular_with-cmap14-subset.ttf new file mode 100644 index 00000000000000..edcb98e37458b2 Binary files /dev/null and b/css/css-fonts/resources/vs/NotoSansJP-Regular_with-cmap14-subset.ttf differ diff --git a/css/css-fonts/resources/vs/NotoSansMath-Regular_without-cmap14-subset.ttf b/css/css-fonts/resources/vs/NotoSansMath-Regular_without-cmap14-subset.ttf new file mode 100644 index 00000000000000..5436d06dae5273 Binary files /dev/null and b/css/css-fonts/resources/vs/NotoSansMath-Regular_without-cmap14-subset.ttf differ diff --git a/css/css-fonts/resources/vs/STIXTwoMath-Regular_with-cmap14-subset.ttf b/css/css-fonts/resources/vs/STIXTwoMath-Regular_with-cmap14-subset.ttf new file mode 100644 index 00000000000000..c9720cf9ce712d Binary files /dev/null and b/css/css-fonts/resources/vs/STIXTwoMath-Regular_with-cmap14-subset.ttf differ diff --git a/css/css-fonts/support/css/variation-sequences.css b/css/css-fonts/support/css/variation-sequences.css new file mode 100644 index 00000000000000..5977f17b678c28 --- /dev/null +++ b/css/css-fonts/support/css/variation-sequences.css @@ -0,0 +1,38 @@ +@font-face { + font-family: "MonoEmojiFont"; + src: url(../../resources/vs/NotoEmoji-Regular_subset.ttf); +} + +@font-face { + font-family: "ColorEmojiFont"; + src: url(../../resources/vs/NotoColorEmoji-Regular_subset.ttf); +} + +@font-face { + font-family: "EmojiFontWithBaseCharOnly"; + src: url(../../resources/vs/NotoEmoji-Regular_without-cmap14-subset.ttf); +} + +@font-face { + font-family: "CJKFontWithVS"; + src: url(../../resources/vs/NotoSansJP-Regular_with-cmap14-subset.ttf); +} + +@font-face { + font-family: "CJKFontWithBaseCharOnly"; + src: url(../../resources/vs/MPLUS1-Regular_without-cmap14-subset.ttf); +} + +@font-face { + font-family: "MathFontWithVS"; + src: url(../../resources/vs/STIXTwoMath-Regular_with-cmap14-subset.ttf); +} + +@font-face { + font-family: "MathFontWithBaseCharOnly"; + src: url(../../resources/vs/NotoSansMath-Regular_without-cmap14-subset.ttf); +} + +body { + font-size: 24px; +} \ No newline at end of file diff --git a/css/css-fonts/support/js/variation-sequences.js b/css/css-fonts/support/js/variation-sequences.js new file mode 100644 index 00000000000000..84c5a1a9c77932 --- /dev/null +++ b/css/css-fonts/support/js/variation-sequences.js @@ -0,0 +1,125 @@ +var baseChars = { + "emoji": "\u{1fae8}", + "cjk": "\u{8279}", + "math": "\u{2205}" +}; + +var variationSelectors = { + "emoji": ["\u{fe0e}", "\u{fe0f}"], + "cjk": ["", "\u{FE00}", "\u{FE01}", "\u{e0100}", "\u{e0101}", + "\u{e0102}" + ], + "math": ["", "\u{FE00}"] +}; + +var families = { + "emoji": ["ColorEmojiFont", "MonoEmojiFont", + "EmojiFontWithBaseCharOnly", + "sans-serif" + ], + "cjk": ["CJKFontWithVS", "CJKFontWithBaseCharOnly", + "sans-serif" + ], + "math": ["MathFontWithVS", "MathFontWithBaseCharOnly", + "sans-serif" + ] +}; + +var variationSequenceFamilies = new Map([ + ["\u{1fae8}\u{fe0e}", "MonoEmojiFont"], + ["\u{1fae8}\u{fe0f}", "ColorEmojiFont"], + ["\u{8279}\u{fe00}", "CJKFontWithVS"], + ["\u{8279}\u{fe01}", "CJKFontWithVS"], + ["\u{8279}\u{e0100}", "CJKFontWithVS"], + ["\u{8279}\u{e0101}", "CJKFontWithVS"], + ["\u{8279}\u{e0102}", "CJKFontWithVS"], + ["\u{2205}\u{FE00}", "MathFontWithVS"] +]); + +var baseCharFamilies = new Map([ + ["\u{1fae8}", new Set(["MonoEmojiFont", "ColorEmojiFont", + "EmojiFontWithBaseCharOnly" + ])], + ["\u{8279}", new Set(["CJKFontWithVS", + "CJKFontWithBaseCharOnly" + ])], + ["\u{2205}", new Set(["MathFontWithVS", + "MathFontWithBaseCharOnly" + ])] +]); + +const range = function*(l) { + for (let i = 0; i < l; i += 1) yield i; +} +const isEmpty = arr => + arr.length === 0; + +const permutations = + function*(a) { + const r = arguments[1] || []; + if (isEmpty(a)) + yield r; + for (let i of range(a.length)) { + const aa = [...a]; + const rr = [...r, ...aa.splice(i, 1)]; + yield* permutations(aa, rr); + } +} + +function getMatchedFamilyForVariationSequence( + familyList, baseCharacter, variationSelector) { + const variationSequence = baseCharacter + variationSelector; + // First try to find a match for the whole variation sequence. + if (variationSequenceFamilies.has(variationSequence)) { + const matchedFamily = variationSequenceFamilies.get(variationSequence); + if (familyList.includes(matchedFamily)) { + return matchedFamily; + } + } + // If failed, try to match only the base character from the + // variation sequence. + if (baseCharFamilies.has(baseCharacter)) { + const eligibleFamilies = baseCharFamilies.get(baseCharacter); + const matchedFamilies = + familyList.filter(value => eligibleFamilies.has(value)); + if (matchedFamilies.length) { + return matchedFamilies[0]; + } + } + // We should not reach here, we should always match one of the + // specified web fonts in the tests. + return ""; +} + +function generateContent( + families, baseChar, variationSelectors, getFontFamilyValue) { + var rootElem = document.createElement('div'); + // We want to test all possible combinations of variation + // selectors and font-family list values. For the refs, + // we explicitly specify the font that we expect to be + // matched from the maps at the beginning of the files. + const allFamiliesLists = permutations(families); + for (const familyList of allFamiliesLists) { + for (const variationSelector of variationSelectors) { + const contentSpan = document.createElement("span"); + contentSpan.textContent = baseChar + variationSelector; + contentSpan.style.fontFamily = + getFontFamilyValue(familyList, baseChar, variationSelector); + rootElem.appendChild(contentSpan); + } + } + document.body.appendChild(rootElem); +} + +function generateVariationSequenceTests(type) { + var getFontFamilyValue = (familyList, baseChar, variationSelector) => { + return familyList.join(', '); + } + generateContent(families[type], baseChars[type], variationSelectors[type], getFontFamilyValue); +} + +function generateVariationSequenceRefs(type) { + generateContent( + families[type], baseChars[type], variationSelectors[type], + getMatchedFamilyForVariationSequence); +} diff --git a/css/css-fonts/variation-sequences-ref.html b/css/css-fonts/variation-sequences-ref.html new file mode 100644 index 00000000000000..a44f18bb3e1f35 --- /dev/null +++ b/css/css-fonts/variation-sequences-ref.html @@ -0,0 +1,11 @@ + + +CSS Test: Cluster Matching Variation Sequences + + + + \ No newline at end of file diff --git a/css/css-fonts/variation-sequences.html b/css/css-fonts/variation-sequences.html new file mode 100644 index 00000000000000..91e46a84d71cc8 --- /dev/null +++ b/css/css-fonts/variation-sequences.html @@ -0,0 +1,18 @@ + + +CSS Test: Cluster Matching Variation Sequences + + + + + + + + + + + \ No newline at end of file