├── .gitignore ├── src ├── sudofont.sketch ├── svg │ ├── minus.svg │ ├── play.svg │ ├── pause.svg │ ├── flipnote-frog.svg │ ├── plus.svg │ ├── chevron-down.svg │ ├── chevron-left.svg │ ├── chevron-up.svg │ ├── chevron-right.svg │ ├── suit-diamonds.svg │ ├── music.svg │ ├── arrow-down.svg │ ├── arrow-left.svg │ ├── arrow-up.svg │ ├── home.svg │ ├── th-menu.svg │ ├── arrow-right.svg │ ├── cancel.svg │ ├── wrench.svg │ ├── flag.svg │ ├── th-small.svg │ ├── user.svg │ ├── block-warning.svg │ ├── unlock.svg │ ├── button-l.svg │ ├── comment.svg │ ├── x.svg │ ├── device-phone.svg │ ├── lock.svg │ ├── button-y.svg │ ├── play-loop.svg │ ├── th-list.svg │ ├── edit.svg │ ├── play-once.svg │ ├── envelope.svg │ ├── help.svg │ ├── cloud.svg │ ├── citizen.svg │ ├── face-bored.svg │ ├── close.svg │ ├── button-a.svg │ ├── calendar.svg │ ├── snowman.svg │ ├── volume-on.svg │ ├── button-b.svg │ ├── button-x.svg │ ├── note.svg │ ├── button-r.svg │ ├── star.svg │ ├── pin.svg │ ├── post.svg │ ├── dpad.svg │ ├── search.svg │ ├── pencil.svg │ ├── face-sad.svg │ ├── warning.svg │ ├── delete.svg │ ├── user-card.svg │ ├── expand.svg │ ├── download.svg │ ├── user-book.svg │ ├── tag.svg │ ├── block-question.svg │ ├── comment-off.svg │ ├── suit-hearts.svg │ ├── volume-off.svg │ ├── heart.svg │ ├── citizen-off.svg │ ├── ds.svg │ ├── suit-clubs.svg │ ├── suit-spades.svg │ ├── chat.svg │ ├── umbrella.svg │ ├── spinoff.svg │ ├── cog.svg │ ├── delete-off.svg │ ├── star-o.svg │ ├── tags.svg │ ├── face-smile.svg │ ├── th-large.svg │ ├── channels.svg │ ├── news.svg │ ├── user-group.svg │ ├── face-frown.svg │ ├── alarm.svg │ ├── eye.svg │ ├── sun.svg │ ├── globe.svg │ ├── eye-off.svg │ ├── playmode.svg │ └── framemode.svg ├── templates │ ├── template.css │ ├── template.html │ └── template.scss ├── sudofont-svg-loader.js ├── unicode_to_key_mappings.json └── emoji_mappings.json ├── package.json ├── LICENSE ├── gulpfile.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /src/sudofont.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sudomemo/Sudofont/HEAD/src/sudofont.sketch -------------------------------------------------------------------------------- /src/svg/minus.svg: -------------------------------------------------------------------------------- 1 | minus -------------------------------------------------------------------------------- /src/svg/play.svg: -------------------------------------------------------------------------------- 1 | play -------------------------------------------------------------------------------- /src/svg/pause.svg: -------------------------------------------------------------------------------- 1 | pause -------------------------------------------------------------------------------- /src/svg/flipnote-frog.svg: -------------------------------------------------------------------------------- 1 | flipnote-frog 2 | -------------------------------------------------------------------------------- /src/svg/plus.svg: -------------------------------------------------------------------------------- 1 | plus -------------------------------------------------------------------------------- /src/svg/chevron-down.svg: -------------------------------------------------------------------------------- 1 | chevron-down -------------------------------------------------------------------------------- /src/svg/chevron-left.svg: -------------------------------------------------------------------------------- 1 | chevron-left -------------------------------------------------------------------------------- /src/svg/chevron-up.svg: -------------------------------------------------------------------------------- 1 | chevron-up -------------------------------------------------------------------------------- /src/svg/chevron-right.svg: -------------------------------------------------------------------------------- 1 | chevron-right -------------------------------------------------------------------------------- /src/svg/suit-diamonds.svg: -------------------------------------------------------------------------------- 1 | suit-diamonds -------------------------------------------------------------------------------- /src/svg/music.svg: -------------------------------------------------------------------------------- 1 | music -------------------------------------------------------------------------------- /src/svg/arrow-down.svg: -------------------------------------------------------------------------------- 1 | arrow-down -------------------------------------------------------------------------------- /src/svg/arrow-left.svg: -------------------------------------------------------------------------------- 1 | arrow-left -------------------------------------------------------------------------------- /src/svg/arrow-up.svg: -------------------------------------------------------------------------------- 1 | arrow-up -------------------------------------------------------------------------------- /src/svg/home.svg: -------------------------------------------------------------------------------- 1 | home -------------------------------------------------------------------------------- /src/svg/th-menu.svg: -------------------------------------------------------------------------------- 1 | th-menu -------------------------------------------------------------------------------- /src/svg/arrow-right.svg: -------------------------------------------------------------------------------- 1 | arrow-right -------------------------------------------------------------------------------- /src/svg/cancel.svg: -------------------------------------------------------------------------------- 1 | cancel -------------------------------------------------------------------------------- /src/svg/wrench.svg: -------------------------------------------------------------------------------- 1 | wrench -------------------------------------------------------------------------------- /src/svg/flag.svg: -------------------------------------------------------------------------------- 1 | flag -------------------------------------------------------------------------------- /src/svg/th-small.svg: -------------------------------------------------------------------------------- 1 | th-small -------------------------------------------------------------------------------- /src/svg/user.svg: -------------------------------------------------------------------------------- 1 | user -------------------------------------------------------------------------------- /src/svg/block-warning.svg: -------------------------------------------------------------------------------- 1 | block-warning -------------------------------------------------------------------------------- /src/svg/unlock.svg: -------------------------------------------------------------------------------- 1 | unlock -------------------------------------------------------------------------------- /src/svg/button-l.svg: -------------------------------------------------------------------------------- 1 | button-l -------------------------------------------------------------------------------- /src/svg/comment.svg: -------------------------------------------------------------------------------- 1 | comment -------------------------------------------------------------------------------- /src/svg/x.svg: -------------------------------------------------------------------------------- 1 | x -------------------------------------------------------------------------------- /src/svg/device-phone.svg: -------------------------------------------------------------------------------- 1 | device-phone -------------------------------------------------------------------------------- /src/svg/lock.svg: -------------------------------------------------------------------------------- 1 | lock -------------------------------------------------------------------------------- /src/svg/button-y.svg: -------------------------------------------------------------------------------- 1 | button-y -------------------------------------------------------------------------------- /src/svg/play-loop.svg: -------------------------------------------------------------------------------- 1 | play-loop -------------------------------------------------------------------------------- /src/svg/th-list.svg: -------------------------------------------------------------------------------- 1 | th-list -------------------------------------------------------------------------------- /src/svg/edit.svg: -------------------------------------------------------------------------------- 1 | edit -------------------------------------------------------------------------------- /src/svg/play-once.svg: -------------------------------------------------------------------------------- 1 | play-once -------------------------------------------------------------------------------- /src/svg/envelope.svg: -------------------------------------------------------------------------------- 1 | envelope -------------------------------------------------------------------------------- /src/svg/help.svg: -------------------------------------------------------------------------------- 1 | help -------------------------------------------------------------------------------- /src/svg/cloud.svg: -------------------------------------------------------------------------------- 1 | cloud -------------------------------------------------------------------------------- /src/svg/citizen.svg: -------------------------------------------------------------------------------- 1 | citizen -------------------------------------------------------------------------------- /src/svg/face-bored.svg: -------------------------------------------------------------------------------- 1 | face-bored -------------------------------------------------------------------------------- /src/svg/close.svg: -------------------------------------------------------------------------------- 1 | close -------------------------------------------------------------------------------- /src/svg/button-a.svg: -------------------------------------------------------------------------------- 1 | button-a -------------------------------------------------------------------------------- /src/svg/calendar.svg: -------------------------------------------------------------------------------- 1 | calendar -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sudofont", 3 | "version": "2.0.0", 4 | "repository": { 5 | "url": "https://github.com/sudomemo/Sudofont.git", 6 | "type": "git" 7 | }, 8 | "author": "James Daniel ", 9 | "license": "MIT", 10 | "scripts": { 11 | "build": "gulp build" 12 | }, 13 | "dependencies": { 14 | "gulp-consolidate": "^0.2.0", 15 | "gulp-iconfont": "^11.0.1", 16 | "gulp-rename": "^2.0.0", 17 | "gulp-svgo": "^2.2.1", 18 | "lodash": "^4.17.21", 19 | "vinyl": "^2.2.1" 20 | }, 21 | "devDependencies": { 22 | "gulp": "^5.0.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/svg/snowman.svg: -------------------------------------------------------------------------------- 1 | snowman -------------------------------------------------------------------------------- /src/svg/volume-on.svg: -------------------------------------------------------------------------------- 1 | volume-on -------------------------------------------------------------------------------- /src/svg/button-b.svg: -------------------------------------------------------------------------------- 1 | button-b -------------------------------------------------------------------------------- /src/svg/button-x.svg: -------------------------------------------------------------------------------- 1 | button-x -------------------------------------------------------------------------------- /src/svg/note.svg: -------------------------------------------------------------------------------- 1 | note -------------------------------------------------------------------------------- /src/svg/button-r.svg: -------------------------------------------------------------------------------- 1 | button-r -------------------------------------------------------------------------------- /src/svg/star.svg: -------------------------------------------------------------------------------- 1 | star -------------------------------------------------------------------------------- /src/svg/pin.svg: -------------------------------------------------------------------------------- 1 | pin -------------------------------------------------------------------------------- /src/svg/post.svg: -------------------------------------------------------------------------------- 1 | post -------------------------------------------------------------------------------- /src/svg/dpad.svg: -------------------------------------------------------------------------------- 1 | dpad -------------------------------------------------------------------------------- /src/svg/search.svg: -------------------------------------------------------------------------------- 1 | search -------------------------------------------------------------------------------- /src/svg/pencil.svg: -------------------------------------------------------------------------------- 1 | pencil -------------------------------------------------------------------------------- /src/svg/face-sad.svg: -------------------------------------------------------------------------------- 1 | face-sad -------------------------------------------------------------------------------- /src/svg/warning.svg: -------------------------------------------------------------------------------- 1 | warning -------------------------------------------------------------------------------- /src/svg/delete.svg: -------------------------------------------------------------------------------- 1 | delete -------------------------------------------------------------------------------- /src/svg/user-card.svg: -------------------------------------------------------------------------------- 1 | user-card -------------------------------------------------------------------------------- /src/svg/expand.svg: -------------------------------------------------------------------------------- 1 | expand -------------------------------------------------------------------------------- /src/svg/download.svg: -------------------------------------------------------------------------------- 1 | download -------------------------------------------------------------------------------- /src/svg/user-book.svg: -------------------------------------------------------------------------------- 1 | user-book -------------------------------------------------------------------------------- /src/svg/tag.svg: -------------------------------------------------------------------------------- 1 | tag -------------------------------------------------------------------------------- /src/svg/block-question.svg: -------------------------------------------------------------------------------- 1 | block-question -------------------------------------------------------------------------------- /src/svg/comment-off.svg: -------------------------------------------------------------------------------- 1 | comment-off -------------------------------------------------------------------------------- /src/svg/suit-hearts.svg: -------------------------------------------------------------------------------- 1 | suit-hearts -------------------------------------------------------------------------------- /src/svg/volume-off.svg: -------------------------------------------------------------------------------- 1 | volume-off -------------------------------------------------------------------------------- /src/svg/heart.svg: -------------------------------------------------------------------------------- 1 | heart -------------------------------------------------------------------------------- /src/svg/citizen-off.svg: -------------------------------------------------------------------------------- 1 | citizen-off -------------------------------------------------------------------------------- /src/svg/ds.svg: -------------------------------------------------------------------------------- 1 | ds -------------------------------------------------------------------------------- /src/svg/suit-clubs.svg: -------------------------------------------------------------------------------- 1 | suit-clubs -------------------------------------------------------------------------------- /src/svg/suit-spades.svg: -------------------------------------------------------------------------------- 1 | suit-spades -------------------------------------------------------------------------------- /src/svg/chat.svg: -------------------------------------------------------------------------------- 1 | chat -------------------------------------------------------------------------------- /src/svg/umbrella.svg: -------------------------------------------------------------------------------- 1 | umbrella -------------------------------------------------------------------------------- /src/svg/spinoff.svg: -------------------------------------------------------------------------------- 1 | spinoff -------------------------------------------------------------------------------- /src/svg/cog.svg: -------------------------------------------------------------------------------- 1 | cog -------------------------------------------------------------------------------- /src/svg/delete-off.svg: -------------------------------------------------------------------------------- 1 | delete-off -------------------------------------------------------------------------------- /src/svg/star-o.svg: -------------------------------------------------------------------------------- 1 | star-o -------------------------------------------------------------------------------- /src/svg/tags.svg: -------------------------------------------------------------------------------- 1 | tags -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Sudomemo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/svg/face-smile.svg: -------------------------------------------------------------------------------- 1 | face-smile -------------------------------------------------------------------------------- /src/svg/th-large.svg: -------------------------------------------------------------------------------- 1 | th-large -------------------------------------------------------------------------------- /src/svg/channels.svg: -------------------------------------------------------------------------------- 1 | channels -------------------------------------------------------------------------------- /src/svg/news.svg: -------------------------------------------------------------------------------- 1 | news -------------------------------------------------------------------------------- /src/svg/user-group.svg: -------------------------------------------------------------------------------- 1 | user-group -------------------------------------------------------------------------------- /src/svg/face-frown.svg: -------------------------------------------------------------------------------- 1 | face-frown -------------------------------------------------------------------------------- /src/svg/alarm.svg: -------------------------------------------------------------------------------- 1 | alarm -------------------------------------------------------------------------------- /src/svg/eye.svg: -------------------------------------------------------------------------------- 1 | eye -------------------------------------------------------------------------------- /src/svg/sun.svg: -------------------------------------------------------------------------------- 1 | sun -------------------------------------------------------------------------------- /src/svg/globe.svg: -------------------------------------------------------------------------------- 1 | globe -------------------------------------------------------------------------------- /src/templates/template.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "<%= fontName %>"; 3 | src: url("<%= fontPath %><%= fontName %>.eot"); 4 | src: url("<%= fontPath %><%= fontName %>.eot?#iefix") format("eot"), 5 | url("<%= fontPath %><%= fontName %>.woff2") format("woff2"), 6 | url("<%= fontPath %><%= fontName %>.woff") format("woff"), 7 | url("<%= fontPath %><%= fontName %>.ttf") format("truetype"), 8 | url("<%= fontPath %><%= fontName %>.svg#<%= fontName %>") format("svg"); 9 | font-weight: normal; 10 | font-style: normal; 11 | unicode-range: <%= unicodeRange %>; 12 | } 13 | 14 | .<%= className %> { 15 | display: inline-block; 16 | font: normal normal normal 24px/1 "<%= fontName %>"; 17 | font-size: inherit; 18 | text-rendering: auto; 19 | -webkit-font-smoothing: antialiased; 20 | -moz-osx-font-smoothing: grayscale; 21 | } 22 | 23 | .<%= className %>--lg { 24 | font-size: 1.3333333333333333em; 25 | line-height: 0.75em; 26 | vertical-align: -15%; 27 | } 28 | 29 | .<%= className %>--fw { 30 | width: 1.2857142857142858em; 31 | text-align: center; 32 | } 33 | 34 | .<%= className %>--2x { font-size: 2em; } 35 | .<%= className %>--3x { font-size: 3em; } 36 | .<%= className %>--4x { font-size: 4em; } 37 | .<%= className %>--5x { font-size: 5em; } 38 | 39 | <% _.each(glyphs, function(glyph) { %> 40 | .<%= className %>--<%= glyph.name %>:before { 41 | content: "\<%= glyph.codepoint.toString(16).toUpperCase() %>"; 42 | } 43 | <% }); %> 44 | -------------------------------------------------------------------------------- /src/sudofont-svg-loader.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const vinyl = require("vinyl"); 4 | 5 | module.exports = function(svgDir, unicode_to_key_mappings) { 6 | let output = []; 7 | let used_glyph_names = []; 8 | // for each unicode_to_key_mapping (prefix, svg name) copy svg to tempDir/u{prefix}-{svg name}.svg 9 | for (let unicode_to_key_mapping of unicode_to_key_mappings) { 10 | const prefix = unicode_to_key_mapping[0]; 11 | const svgName = unicode_to_key_mapping[1]; 12 | 13 | let outputSvgName = svgName; 14 | 15 | // if the glyph has already been used, suffix the name with a number 16 | while (used_glyph_names.includes(outputSvgName)) { 17 | // console.log(`glyph ${outputSvgName} already used, suffixing with a number`); 18 | let suffix = 1; 19 | while (used_glyph_names.includes(outputSvgName + "-" + suffix)) { 20 | suffix++; 21 | } 22 | outputSvgName = outputSvgName + "-" + suffix; 23 | } 24 | 25 | used_glyph_names.push(outputSvgName); 26 | 27 | const svgFilename = `u${prefix}-${outputSvgName}.svg`; 28 | const svgPath = path.join(svgDir, svgName + ".svg"); 29 | 30 | // vinyl 31 | let svg = new vinyl({ 32 | cwd: '/', 33 | base: '/compiled_svg/', 34 | path: '/compiled_svg/' + svgFilename, 35 | contents: fs.readFileSync(svgPath) 36 | }); 37 | 38 | output.push(svg); 39 | } 40 | 41 | return output; 42 | } -------------------------------------------------------------------------------- /src/svg/eye-off.svg: -------------------------------------------------------------------------------- 1 | eye-off -------------------------------------------------------------------------------- /src/templates/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= fontName %> test page 6 | 7 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | <% _.each(glyphs, function(glyph) { %> 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | <% }); %> 54 |
Glyph NameIcon FontWebfontNon-WebfontInline with text
<%= glyph.name %><%= String.fromCodePoint(glyph.codepoint) %><%= String.fromCodePoint(glyph.codepoint) %><%= String.fromCodePoint(glyph.codepoint) %> Hello <%= String.fromCodePoint(glyph.codepoint) %>, world! <%= String.fromCodePoint(glyph.codepoint) %>
55 | 56 | 57 | -------------------------------------------------------------------------------- /src/svg/playmode.svg: -------------------------------------------------------------------------------- 1 | playmode -------------------------------------------------------------------------------- /src/svg/framemode.svg: -------------------------------------------------------------------------------- 1 | framemode -------------------------------------------------------------------------------- /src/templates/template.scss: -------------------------------------------------------------------------------- 1 | $<%= className %>-font-family: "<%= fontName %>" !default; 2 | $<%= className %>-font-name: "<%= fontName %>" !default; 3 | $<%= className %>-font-size-base: 24px !default; 4 | $<%= className %>-line-height-base: 1 !default; 5 | $<%= className %>-font-path: "<%= fontPath %>" !default; 6 | $<%= className %>-icon-sizes: (2, 3, 4, 5) !default; 7 | 8 | $<%= className %>-map: (<% _.each(glyphs, function(glyph) { %> 9 | <%= glyph.name %>: <%= glyph.codepoint.toString(16) %>,<% }); %> 10 | ); 11 | 12 | @font-face { 13 | font-family: "#{$<%= className %>-font-family}"; 14 | src: url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.eot'); 15 | src: url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.eot?#iefix') format('eot'), 16 | url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.woff2') format('woff2'), 17 | url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.woff') format('woff'), 18 | url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.ttf') format('truetype'), 19 | url('#{$<%= className %>-font-path}#{$<%= className %>-font-name}.svg##{$<%= className %>-font-name}') format('svg'); 20 | font-weight: normal; 21 | font-style: normal; 22 | unicode-range: <%= unicodeRange %>; 23 | } 24 | 25 | @function <%= className %>-get-icon($name){ 26 | @if map-has-key($<%= className %>-map, $name) { 27 | $code: map-get($<%= className %>-map, $name); 28 | @return #{"\"\\"}#{$code + "\""}; 29 | } @else { 30 | @error "<%= fontName %>: invalid icon name: `#{$name}`."; 31 | } 32 | } 33 | 34 | @mixin <%= className %>-icon() { 35 | display: inline-block; 36 | font: normal normal normal #{$<%= className %>-font-size-base}/#{$<%= className %>-line-height-base} "#{$<%= className %>-font-family}"; 37 | font-size: inherit; 38 | text-rendering: auto; 39 | -webkit-font-smoothing: antialiased; 40 | -moz-osx-font-smoothing: grayscale; 41 | } 42 | 43 | @mixin <%= className %>-classes() { 44 | .<%= className %> { 45 | @include <%= className %>-icon(); 46 | } 47 | 48 | .<%= className %>--lg { 49 | font-size: 1.3333333333333333em; 50 | line-height: 0.75em; 51 | vertical-align: -15%; 52 | } 53 | .<%= className %>--fw { 54 | width: 1.2857142857142858em; 55 | text-align: center; 56 | } 57 | 58 | @each $size in $<%= className %>-icon-sizes { 59 | .<%= className %>--#{$size}x { 60 | font-size: #{$size}em; 61 | } 62 | } 63 | 64 | @each $iconName, $iconContent in $<%= className %>-map { 65 | .<%= className %>--#{$iconName}:before { 66 | content: <%= className %>-get-icon($iconName); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/unicode_to_key_mappings.json: -------------------------------------------------------------------------------- 1 | { 2 | "E000": "button-a", 3 | "E001": "button-b", 4 | "E002": "button-x", 5 | "E003": "button-y", 6 | "E004": "button-l", 7 | "E005": "button-r", 8 | "E006": "dpad", 9 | "E007": "alarm", 10 | "E008": "face-smile", 11 | "E009": "face-frown", 12 | "E00A": "face-sad", 13 | "E00B": "face-bored", 14 | "E00C": "sun", 15 | "E00D": "cloud", 16 | "E00E": "umbrella", 17 | "E00F": "snowman", 18 | "E010": "block-warning", 19 | "E011": "block-question", 20 | "E012": "envelope", 21 | "E013": "device-phone", 22 | "E015": "suit-spades", 23 | "E016": "suit-diamonds", 24 | "E017": "suit-hearts", 25 | "E018": "suit-clubs", 26 | "E019": "arrow-right", 27 | "E01A": "arrow-left", 28 | "E01B": "arrow-up", 29 | "E01C": "arrow-down", 30 | "E028": "x", 31 | "E100": "play", 32 | "E101": "pause", 33 | "E102": "volume-off", 34 | "E103": "volume-on", 35 | "E104": "framemode", 36 | "E105": "playmode", 37 | "E110": "expand", 38 | "E111": "close", 39 | "E112": "chevron-left", 40 | "E113": "chevron-right", 41 | "E114": "chevron-up", 42 | "E115": "chevron-down", 43 | "E116": "play-loop", 44 | "E117": "play-once", 45 | "E120": "comment", 46 | "E121": "comment-off", 47 | "E122": "eye", 48 | "E123": "eye-off", 49 | "E124": "delete", 50 | "E125": "delete-off", 51 | "E126": "chat", 52 | "E127": "star", 53 | "E128": "star-o", 54 | "E129": "heart", 55 | "E12A": "tag", 56 | "E12B": "tags", 57 | "E12C": "pencil", 58 | "E12D": "edit", 59 | "E12E": "cog", 60 | "E12F": "warning", 61 | "E130": "calendar", 62 | "E131": "music", 63 | "E132": "cancel", 64 | "E133": "flag", 65 | "E134": "note", 66 | "E135": "pin", 67 | "E136": "plus", 68 | "E137": "minus", 69 | "E138": "th-large", 70 | "E139": "th-list", 71 | "E13A": "th-menu", 72 | "E13B": "th-small", 73 | "E150": "home", 74 | "E151": "search", 75 | "E152": "news", 76 | "E153": "help", 77 | "E154": "channels", 78 | "E155": "globe", 79 | "E156": "user", 80 | "E157": "user-group", 81 | "E158": "user-book", 82 | "E159": "user-card", 83 | "E15A": "citizen", 84 | "E15B": "citizen-off", 85 | "E15C": "post", 86 | "E15D": "download", 87 | "E200": "flipnote-frog", 88 | "E201": "wrench", 89 | "E202": "lock", 90 | "E203": "unlock", 91 | "E204": "spinoff", 92 | "E205": "ds", 93 | "1F603": "face-smile", 94 | "1F620": "face-frown", 95 | "1F614": "face-sad", 96 | "1F611": "face-bored", 97 | "2600": "sun", 98 | "2601": "cloud", 99 | "2614": "umbrella", 100 | "26C4": "snowman", 101 | "2709": "envelope", 102 | "1F4F1": "device-phone", 103 | "23F0": "alarm", 104 | "24B6": "button-a", 105 | "24B7": "button-b", 106 | "24CD": "button-x", 107 | "24CE": "button-y", 108 | "24C1": "button-l", 109 | "24C7": "button-r", 110 | "2795": "dpad", 111 | "2660": "suit-spades", 112 | "2666": "suit-diamonds", 113 | "2665": "suit-hearts", 114 | "2663": "suit-clubs", 115 | "2757": "block-warning", 116 | "2753": "block-question", 117 | "27A1": "arrow-right", 118 | "2B05": "arrow-left", 119 | "2B06": "arrow-up", 120 | "2B07": "arrow-down", 121 | "2715": "x" 122 | } 123 | 124 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const gulp = require("gulp"); 4 | const rename = require("gulp-rename"); 5 | const svgo = require("gulp-svgo"); 6 | const iconfont = require("gulp-iconfont"); 7 | const consolidate = require("gulp-consolidate"); 8 | const fs = require("fs"); 9 | const svgLoader = require("./src/sudofont-svg-loader"); 10 | 11 | let paths = { 12 | svgIn: "src/svg/", 13 | scssTemplate: "src/templates/template.scss", 14 | scssOut: "dist/scss/", 15 | svgOut: "dist/svg/", 16 | fontOut: "dist/fonts/", 17 | fontCSS: "../fonts/", 18 | }; 19 | 20 | let font = { 21 | name: "sudofont", 22 | formats: ["ttf", "eot", "woff", "woff2", "svg"], 23 | className: "sf", 24 | }; 25 | 26 | function getUnicodeRange(array) { 27 | var ranges = [], 28 | rstart, 29 | rend; 30 | for (var i = 0; i < array.length; i++) { 31 | rstart = array[i]; 32 | rend = rstart; 33 | while (array[i + 1] - array[i] == 1) { 34 | rend = array[i + 1]; 35 | i++; 36 | } 37 | let starthex = rstart.toString(16).toUpperCase(); 38 | let endhex = rend.toString(16).toUpperCase(); 39 | ranges.push( 40 | rstart == rend ? "U+" + starthex + "" : "U+" + starthex + "-" + endhex 41 | ); 42 | } 43 | return ranges.join(", "); 44 | } 45 | 46 | gulp.task("build", () => { 47 | // read src/unicode_to_key_mappings.json 48 | let unicode_to_key_mappings = Object.entries( 49 | JSON.parse(fs.readFileSync("./src/unicode_to_key_mappings.json")) 50 | ); 51 | // run svgLoader through gulp 52 | let vinylFiles = svgLoader(paths.svgIn, unicode_to_key_mappings); 53 | 54 | let stream = gulp.src("."); 55 | 56 | for (let vinylFile of vinylFiles) { 57 | stream.write(vinylFile); 58 | } 59 | 60 | return stream 61 | // Minify each svg image 62 | // todo: svgo is breaking the build 63 | //.pipe(svgo()) 64 | // Export to svg 65 | .pipe(gulp.dest(paths.svgOut)) 66 | .pipe( 67 | iconfont({ 68 | fontName: font.name, 69 | prependUnicode: true, 70 | formats: font.formats, 71 | fontHeight: 240, 72 | descent: 40, 73 | }) 74 | ) 75 | .on("glyphs", (glyphs) => { 76 | glyphs = glyphs 77 | .map((glyph) => { 78 | let codepoint = glyph.unicode[0].codePointAt(0); 79 | return { 80 | name: glyph.name, 81 | codepoint: codepoint, 82 | }; 83 | }) 84 | .sort((a, b) => { 85 | return a.codepoint - b.codepoint; 86 | }); 87 | 88 | let codepoints = glyphs.map((glyph) => { 89 | return glyph.codepoint; 90 | }); 91 | 92 | const options = { 93 | className: font.className, 94 | fontName: font.name, 95 | fontPath: paths.fontCSS, 96 | unicodeRange: getUnicodeRange(codepoints), 97 | glyphs: glyphs, 98 | }; 99 | 100 | gulp 101 | .src("src/templates/template.scss") 102 | .pipe(consolidate("lodash", options)) 103 | .pipe(rename({ basename: font.name })) 104 | .pipe(gulp.dest("dist/scss/")); 105 | 106 | gulp 107 | .src("src/templates/template.css") 108 | .pipe(consolidate("lodash", options)) 109 | .pipe(rename({ basename: font.name })) 110 | .pipe(gulp.dest("dist/css/")); 111 | 112 | gulp 113 | .src("src/templates/template.html") 114 | .pipe(consolidate("lodash", options)) 115 | .pipe(rename({ basename: "test" })) 116 | .pipe(gulp.dest("dist")); 117 | }) 118 | .pipe(gulp.dest(paths.fontOut)) 119 | 120 | }); 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Sudofont 2 | 3 | Sudomemo Theatre icon font, with polyfills for the Nintendo DS' special font characters. 4 | 5 | ### What we needed 6 | 7 | Ever since the launch of the Nintendo DS, Nintendo consoles have had a set of special characters added into the internal system font. On [Sudomemo](https://www.sudomemo.net), users can set their username through their Nintendo DSi console, with the option of using these special characters. 8 | 9 | These usernames need to display on the Sudomemo Theatre website for PC and mobile devices. Flipnote Hatena did this by inserting .gif images for the characters into the text, however we thought that we could find a better approach since it's not 2008 anymore. 10 | 11 | We created a font that includes glyphs mapped to the unicode codepoint for each Nintendo DS special character that can appear in a username, thanks to the power of webfonts, we can use this to provide "native" support for these characters within a webpage. 12 | 13 | We also decided to append our own icon-font to this set, so as such Sudofont also serves additional purpose of providing the UI icons for Sudomemo Theatre, killing two birds with one stone. 14 | 15 | ### Building 16 | 17 | For only requirement for building Sudofont yourself is [NodeJS](https://nodejs.org), once you have it set up on your system, clone or download this repository, then `cd` into the directory: 18 | 19 | #### Install the dependencies: 20 | 21 | `npm install` 22 | 23 | #### Run the build script: 24 | 25 | `npm run build` 26 | 27 | ### Mapping table 28 | 29 | | NDS character | NDS hex | Emoji | Emoji shortcode | Char | Hex | 30 | |:--------------|:--------|:---------------------|:-------------------|:-----|:---------| 31 | | A button | 0xE000 | n/a | n/a | Ⓐ | 0x24B6 | 32 | | B button | 0xE001 | n/a | n/a | Ⓑ | 0x24B7 | 33 | | X button | 0xE002 | n/a | n/a | Ⓧ | 0x24CD | 34 | | Y button | 0xE003 | n/a | n/a | Ⓨ | 0x24CE | 35 | | L button | 0xE004 | n/a | n/a | Ⓛ | 0x24C1 | 36 | | R button | 0xE005 | n/a | n/a | Ⓡ | 0x24C7 | 37 | | D-pad | 0xE006 | :heavy_plus_sign: | heavy_plus_sign | ➕ | 0x2795 | 38 | | Alarm | 0xE007 | :alarm_clock: | alarm_clock | ⏰ | 0x23F0 | 39 | | Happy face | 0xE008 | :smiley: | smiley | 😃 | 0x0001F603 | 40 | | Angry face | 0xE009 | :angry: | angry | 😠 | 0x0001F620 | 41 | | Sad face | 0xE00A | :pensive: | pensive | 😔 | 0x0001F614 | 42 | | Neutral face | 0xE00B | :expressionless: | expressionless | 😑 | 0x0001F611 | 43 | | Sun | 0xE00C | :sunny: | sunny | ☀ | 0x2600 | 44 | | Cloud | 0xE00D | :cloud: | cloud | ☁ | 0x2601 | 45 | | Umbrella | 0xE00E | :umbrella: | umbrella | ☔ | 0x2614 | 46 | | Snowman | 0xE00F | :snowman: | snowman | ⛄ | 0x26C4 | 47 | | Exclamation | 0xE010 | :exclamation: | exclamation | ❗ | 0x2757 | 48 | | Question | 0xE011 | :question: | question | ❓ | 0x2753 | 49 | | Envelope | 0xE012 | :envelope: | envelope | ✉ | 0x2709 | 50 | | Phone | 0xE013 | :iphone: | iphone | 📱 | 0x0001F4F1 | 51 | | Spade | 0xE015 | :spades: | spades | ♠ | 0x2660 | 52 | | Diamond | 0xE016 | :diamonds: | diamonds | ♦ | 0x2666 | 53 | | Heart | 0xE017 | :hearts: | hearts | ♥ | 0x2665 | 54 | | Club | 0xE018 | :clubs: | clubs | ♣ | 0x2663 | 55 | | Right arrow | 0xE019 | :arrow_right: | arrow_right | ➡ | 0x27A1 | 56 | | Left arrow | 0xE01A | :arrow_left: | arrow_left | ⬅ | 0x2B05 | 57 | | Up arrow | 0xE01B | :arrow_up: | arrow_up | ⬆ | 0x2B06 | 58 | | Down arrow | 0xE01C | :arrow_down: | arrow_down | ⬇ | 0x2B07 | 59 | | Cross | 0xE028 |:heavy_multiplication_x:|heavy_multiplication_x| ✕ | 0x2715 | 60 | 61 | ### Credits 62 | 63 | * [Wakaba](https://github.com/wakaba) - For open-sourcing this very helpful [Hatena NDS emoji mapping table](https://github.com/wakaba/hatena-emoji-data/blob/master/tables/hatena-00e000.txt) 64 | 65 | * [Typicons](https://github.com/stephenhutchings/typicons.font) - Used as a base for some of the icons 66 | -------------------------------------------------------------------------------- /src/emoji_mappings.json: -------------------------------------------------------------------------------- 1 | { 2 | "E000": { 3 | "nds_text": "", 4 | "emoji_shortcode": false, 5 | "unicode_text": "Ⓐ", 6 | "unicode": "24B6", 7 | "unicode_version" "1.1.0" 8 | }, 9 | "E001": { 10 | "nds_text": "", 11 | "emoji_shortcode": false, 12 | "unicode_text": "Ⓑ", 13 | "unicode": "24B7", 14 | "unicode_version" "1.1.0" 15 | }, 16 | "E002": { 17 | "nds_text": "", 18 | "emoji_shortcode": false, 19 | "unicode_text": "Ⓧ", 20 | "unicode": "24CD", 21 | "unicode_version" "1.1.0" 22 | }, 23 | "E003": { 24 | "nds_text": "", 25 | "emoji_shortcode": false, 26 | "unicode_text": "Ⓨ", 27 | "unicode": "24CE", 28 | "unicode_version" "1.1.0" 29 | }, 30 | "E004": { 31 | "nds_text": "", 32 | "emoji_shortcode": false, 33 | "unicode_text": "Ⓛ", 34 | "unicode": "24C1", 35 | "unicode_version" "1.1.0" 36 | }, 37 | "E005": { 38 | "nds_text": "", 39 | "emoji_shortcode": false, 40 | "unicode_text": "Ⓡ", 41 | "unicode": "24C7", 42 | "unicode_version" "1.1.0" 43 | }, 44 | "E006": { 45 | "nds_text": "", 46 | "emoji_shortcode": ":heavy_plus_sign:", 47 | "unicode_text": "➕", 48 | "unicode": "2795", 49 | "unicode_version" "6.0.0" 50 | }, 51 | "E007": { 52 | "nds_text": "", 53 | "emoji_shortcode": ":alarm_clock:", 54 | "unicode_text": "⏰", 55 | "unicode": "23F0", 56 | "unicode_version" "6.0.0" 57 | }, 58 | "E008": { 59 | "nds_text": "", 60 | "emoji_shortcode": ":smiley:", 61 | "unicode_text": "😃", 62 | "unicode": "1F603", 63 | "unicode_version" "6.0.0" 64 | }, 65 | "E009": { 66 | "nds_text": "", 67 | "emoji_shortcode": ":angry:", 68 | "unicode_text": "😠", 69 | "unicode": "1F620", 70 | "unicode_version" "6.0.0" 71 | }, 72 | "E00A": { 73 | "nds_text": "", 74 | "emoji_shortcode": ":pensive:", 75 | "unicode_text": "😔", 76 | "unicode": "1F614", 77 | "unicode_version" "6.0.0" 78 | }, 79 | "E00B": { 80 | "nds_text": "", 81 | "emoji_shortcode": ":expressionless:", 82 | "unicode_text": "😑", 83 | "unicode": "1F611", 84 | "unicode_version" "6.0.0" 85 | }, 86 | "E00C": { 87 | "nds_text": "", 88 | "emoji_shortcode": ":sunny:", 89 | "unicode_text": "☀", 90 | "unicode": "2600", 91 | "unicode_version" "1.1.0" 92 | }, 93 | "E00D": { 94 | "nds_text": "", 95 | "emoji_shortcode": ":cloud:", 96 | "unicode_text": "☁", 97 | "unicode": "2601", 98 | "unicode_version" "1.1.0" 99 | }, 100 | "E00E": { 101 | "nds_text": "", 102 | "emoji_shortcode": ":umbrella:", 103 | "unicode_text": "☔", 104 | "unicode": "2614", 105 | "unicode_version" "4.0.0" 106 | }, 107 | "E00F": { 108 | "nds_text": "", 109 | "emoji_shortcode": ":snowman:", 110 | "unicode_text": "⛄", 111 | "unicode": "26C4", 112 | "unicode_version" "5.2.0" 113 | }, 114 | "E010": { 115 | "nds_text": "", 116 | "emoji_shortcode": ":exclamation:", 117 | "unicode_text": "❗", 118 | "unicode": "2757", 119 | "unicode_version" "5.2.0" 120 | }, 121 | "E011": { 122 | "nds_text": "", 123 | "emoji_shortcode": ":question:", 124 | "unicode_text": "❓", 125 | "unicode": "2753", 126 | "unicode_version" "6.0.0" 127 | }, 128 | "E012": { 129 | "nds_text": "", 130 | "emoji_shortcode": ":envelope:", 131 | "unicode_text": "✉", 132 | "unicode": "2709", 133 | "unicode_version" "1.1.0" 134 | }, 135 | "E013": { 136 | "nds_text": "", 137 | "emoji_shortcode": ":iphone:", 138 | "unicode_text": "📱", 139 | "unicode": "1F4F1", 140 | "unicode_version" "6.0.0" 141 | }, 142 | "E015": { 143 | "nds_text": "", 144 | "emoji_shortcode": ":spades:", 145 | "unicode_text": "♠", 146 | "unicode": "2660", 147 | "unicode_version" "1.1.0" 148 | }, 149 | "E016": { 150 | "nds_text": "", 151 | "emoji_shortcode": ":diamonds:", 152 | "unicode_text": "♦", 153 | "unicode": "2666", 154 | "unicode_version" "1.1.0" 155 | }, 156 | "E017": { 157 | "nds_text": "", 158 | "emoji_shortcode": ":hearts:", 159 | "unicode_text": "♥", 160 | "unicode": "2665", 161 | "unicode_version" "1.1.0" 162 | }, 163 | "E018": { 164 | "nds_text": "", 165 | "emoji_shortcode": ":clubs:", 166 | "unicode_text": "♣", 167 | "unicode": "2663", 168 | "unicode_version" "1.1.0" 169 | }, 170 | "E019": { 171 | "nds_text": "", 172 | "emoji_shortcode": ":arrow_right:", 173 | "unicode_text": "➡", 174 | "unicode": "27A1", 175 | "unicode_version" "1.1.0" 176 | }, 177 | "E01A": { 178 | "nds_text": "", 179 | "emoji_shortcode": ":arrow_left:", 180 | "unicode_text": "⬅", 181 | "unicode": "2B05", 182 | "unicode_version" "4.0.0" 183 | }, 184 | "E01B": { 185 | "nds_text": "", 186 | "emoji_shortcode": ":arrow_up:", 187 | "unicode_text": "⬆", 188 | "unicode": "2B06", 189 | "unicode_version" "4.0.0" 190 | }, 191 | "E01C": { 192 | "nds_text": "", 193 | "emoji_shortcode": ":arrow_down:", 194 | "unicode_text": "⬇", 195 | "unicode": "2B07", 196 | "unicode_version" "4.0.0" 197 | }, 198 | "E028": { 199 | "nds_text": "", 200 | "emoji_shortcode": ":heavy_multiplication_x:", 201 | "unicode_text": "✕", 202 | "unicode": "2715", 203 | "unicode_version" "1.1.0" 204 | } 205 | } 206 | --------------------------------------------------------------------------------