Skip to content

Instantly share code, notes, and snippets.

@aroben
Last active August 29, 2015 14:04
Show Gist options
  • Save aroben/3dcf3783fc51c917df84 to your computer and use it in GitHub Desktop.
Save aroben/3dcf3783fc51c917df84 to your computer and use it in GitHub Desktop.
Test which Unicode code points are rendered as emoji on your system
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: monospace, "Segoe UI Emoji";
}
</style>
</head>
<body>
<select id="switcher">
<option value="">Show all characters</option>
<option value="color">Show only color emoji</option>
<option value="nocolor">Show only non-color emoji</option>
</select>
<table id="output"></table>
<script src="script.js"></script>
</body>
</html>
var showColorEmoji = location.search !== "?nocolor";
var showNonEmoji = location.search !== "?color";
function log() {
var table = document.getElementById("output");
var row = table.insertRow(-1);
[].slice.call(arguments).forEach(function (arg) {
row.insertCell(-1).textContent = arg;
});
}
function loaded(event) {
var json = JSON.parse(event.target.responseText);
var alternates = [];
json.filter(function(emoji) {
return emoji.emoji;
}).forEach(function(emoji) {
alternates = alternates.concat((emoji.unicodes || []).map(function(unicode) {
return {emoji: unicode, description: emoji.description + " (alias)"};
}));
if (emoji.emoji.length === 1 && !isLeadingSurrogate(emoji.emoji.charCodeAt(0))) {
alternates.push({emoji: emoji.emoji + String.fromCharCode(0xfe0e), description: emoji.description + " + variation selector-15"});
alternates.push({emoji: emoji.emoji + String.fromCharCode(0xfe0f), description: emoji.description + " + variation selector-16"});
} else if (emoji.emoji.charCodeAt(emoji.emoji.length - 1) === 0xfe0f) {
var base = emoji.emoji.substr(0, emoji.emoji.length - 1);
alternates.push({emoji: base, description: emoji.description});
alternates.push({emoji: base + String.fromCharCode(0xfe0e), description: emoji.description + " + variation selector-15"});
emoji.description = emoji.description + " + variation selector-16";
}
alternates.push(emoji);
});
var seen = {};
alternates.filter(function(emoji) {
var duplicate = emoji.emoji in seen;
seen[emoji.emoji] = true;
return !duplicate;
}).sort(function(a, b) {
var aPoints = codePoints(a.emoji);
var bPoints = codePoints(b.emoji);
return aPoints[0] - bPoints[0]
|| aPoints.length - bPoints.length
|| aPoints[1] - bPoints[1];
}).forEach(function(emoji) {
testEmoji(emoji.emoji, emoji.description);
});
}
function testEmoji(emoji, description) {
var points = codePoints(emoji).map(function(point) {
return "U+" + codePointToHex(point).toUpperCase();
}).join(" ");
var color = isColorEmoji(emoji);
if (showColorEmoji && color || showNonEmoji && !color)
log(emoji, points, description);
}
function isColorEmoji(emoji) {
return color(emoji, "#f00") === color(emoji, "#0f0");
}
var canvas = document.createElement("canvas");
function color(emoji, rgb) {
var context = canvas.getContext("2d");
context.clearRect(0, 0, 32, 32);
context.fillStyle = rgb;
context.textBaseline = "top";
context.font = "32px Arial, 'Segoe UI Emoji'";
context.fillText(emoji, 0, 0);
var data = context.getImageData(0, 0, 32, 32).data;
for (var i = 0; i < data.length; i += 4) {
if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0) {
continue;
}
return data[i].toString(16)
+ data[i + 1].toString(16)
+ data[i + 2].toString(16);
}
return "nothing";
}
function codePoints(utf16) {
var points = [];
var index = 0;
while (index < utf16.length) {
var unit = utf16.charCodeAt(index);
if (!isLeadingSurrogate(unit)) {
points.push(unit);
index += 1;
continue;
}
var leading = unit;
var trailing = utf16.charCodeAt(index + 1);
if (trailing < 0xdc00 || trailing > 0xdfff) {
// Invalid surrogate pair
return;
}
// Surrogate pair!
points.push(0x10000 + ((leading - 0xd800) << 10) + (trailing - 0xdc00));
index += 2;
}
return points;
}
function isLeadingSurrogate(codeUnit) {
return codeUnit >= 0xd800 && codeUnit <= 0xdbff;
}
function codePointToHex(point) {
var hex = point.toString(16);
while (hex.length < 4) {
hex = "0" + "" + hex;
}
return hex;
}
var switcher = document.getElementById("switcher");
switcher.value = location.search.substr(1);
switcher.addEventListener("change", function(event) {
location.href = location.pathname + "?" + event.target.value;
});
var xhr = new XMLHttpRequest;
xhr.open("GET", "https://rawgit.com/github/gemoji/master/db/emoji.json");
xhr.onload = loaded;
xhr.send();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment