Skip to content

Instantly share code, notes, and snippets.

@zer0nka
Forked from obskyr/jitai.user.js
Created January 15, 2020 10:45
Show Gist options
  • Select an option

  • Save zer0nka/97793f046b69b9dabdb42899a0c1d628 to your computer and use it in GitHub Desktop.

Select an option

Save zer0nka/97793f046b69b9dabdb42899a0c1d628 to your computer and use it in GitHub Desktop.

Revisions

  1. @obskyr obskyr revised this gist Jun 28, 2019. 1 changed file with 9 additions and 7 deletions.
    16 changes: 9 additions & 7 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,23 @@
    # List of supported fonts and download links

    ## Fonts from [freejapanesefont.com](http://www.freejapanesefont.com/)
    ## Fonts at some point found on [freejapanesefont.com](http://www.freejapanesefont.com/)

    (But, obscure Japanese links have a tendency of breaking, and a lot of these have moved. If you see a broken link, please tell me in the forum thread!)

    I would recommend taking a look at these fonts, and installing the ones you'd like. Once installed, Jitai will automatically use them. I, personally, have them all installed - it's a good mix!

    Jitai will only use any given font for words where it has all the kanji in it, so don't be afraid of installing fonts that only contain a limited subset of kanji - it can't hurt. Go wild!

    * [Hoso Fuwa Font](http://www.freejapanesefont.com/hoso-fuwa-font-download/)
    * [Chihaya Gothic](http://www.freejapanesefont.com/chihaya-gothic-%E3%81%A1%E3%81%AF%E3%82%84%E3%82%B4%E3%82%B7%E3%83%83%E3%82%AF/)
    * [chifont / chifont+](http://welina.holy.jp/font/tegaki/nchif/) (original source gone, mirror - bottom download link)
    * [Darts Font](http://www.freejapanesefont.com/darts-font-handwriting-font-download/)
    * [San Choume Font](http://www.freejapanesefont.com/sanchoume-handwriting-font-download/)
    * [Hoso Fuwa Font](https://huwahuwa.ff-design.net/%e3%81%bb%e3%81%9d%e3%81%b5%e3%82%8f%e3%83%95%e3%82%a9%e3%83%b3%e3%83%88/)
    * [Chihaya Gothic](https://welina.xyz/font/tegaki/gothic/)
    * [chifont / chifont+](https://welina.xyz/font/tegaki/nchif/) (bottom download link - top won't work)
    * [Darts Font](https://www.p-darts.jp/items/dartsfont.zip)
    * [San Choume Font](http://web.archive.org/web/20190330133455/http://www.geocities.jp/bokurano_yume/)
    * [FC Flower](http://www.freejapanesefont.com/fc-flower-handwriting-font/)
    * [Armed Banana](http://www.freejapanesefont.com/armed-banana-download/) (this one is seriously absurd - I highly recommend it)
    * [Hakusyu Kaisho Bold](http://www.freejapanesefont.com/hakusyu-kaisho-bold-calligraphy/)
    * [Nagayama Kai](http://www.freejapanesefont.com/nagayama-kai-calligraphy-font-download/)
    * [Cinecaption](http://www.jref.com/resources/cinecaption.85/#resourceInfo) (original source gone, mirror)
    * [Cinecaption](http://www.jref.com/resources/cinecaption.85/#resourceInfo)

    ---

  2. @obskyr obskyr revised this gist Mar 11, 2018. 1 changed file with 11 additions and 5 deletions.
    16 changes: 11 additions & 5 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.3.1
    // @version 1.3.2
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @copyright 2016-2018, obskyr
    @@ -85,13 +85,19 @@ function fontExists(fontName) {
    // Approach from kirupa.com/html5/detect_whether_font_is_installed.htm - thanks!
    // Will return false for the browser's default monospace font, sadly.
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    var context = canvas.getContext('2d');
    var text = "wim-—l~ツ亻".repeat(100); // Characters with widths that often vary between fonts.

    context.font = "72px monospace";
    var defaultWidth = context.measureText(text).width;

    context.font = "72px " + fontName + ", monospace";
    // Microsoft Edge raises an error when a context's font is set to a string
    // containing certain special characters... so that needs to be handled.
    try {
    context.font = "72px " + fontName + ", monospace";
    } catch (e) {
    return false;
    }
    var testWidth = context.measureText(text).width;

    return testWidth != defaultWidth;
    @@ -165,7 +171,7 @@ var jitai = {

    getShuffledFonts: function() {
    // This shouldn't have to be part of the Jitai object,
    // but ituses Jitai's local copy of Math.random, so
    // but it uses Jitai's local copy of Math.random, so
    // this is pretty much the most reasonable way to do it.
    var fonts = existingFonts.slice();
    for (var i = fonts.length; i > 0;) {
    @@ -183,10 +189,10 @@ var jitai = {
    // Reorder scripts seem to like overwriting Math.random(!?), so this
    // workaround is required for Jitai to work in conjunction with them.
    var iframe = document.createElement('iframe');
    iframe.className = 'jitai-workaround-for-reorder-script-compatibility';
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    this.random = iframe.contentWindow.Math.random;
    iframe.parentNode.removeChild(iframe);

    this.$characterSpan = $('#character span');
    this.defaultFont = this.$characterSpan.css('font-family');
  3. @obskyr obskyr revised this gist Feb 8, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@
    // @version 1.3.1
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @copyright 2016-2018, obskyr
    // @license MIT
    // @namespace http://obskyr.io/
    // @homepageURL https://gist.github.com/obskyr/9f3c77cf6bf663792c6e
    // @icon http://i.imgur.com/qyuR9bD.png
  4. @obskyr obskyr revised this gist Feb 8, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -25,7 +25,7 @@ var fonts = [
    "MS PMincho, MS P明朝, MS Mincho, MS 明朝",
    "Yu Gothic, YuGothic",
    "Yu Mincho, YuMincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro, ヒラギノ角ゴ Pro W3",
    "Hiragino Maru Gothic Pro, ヒラギノ丸ゴ Pro W3",
  5. @obskyr obskyr revised this gist Feb 8, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -25,7 +25,7 @@ var fonts = [
    "MS PMincho, MS P明朝, MS Mincho, MS 明朝",
    "Yu Gothic, YuGothic",
    "Yu Mincho, YuMincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro, ヒラギノ角ゴ Pro W3",
    "Hiragino Maru Gothic Pro, ヒラギノ丸ゴ Pro W3",
  6. @obskyr obskyr revised this gist Feb 8, 2018. 1 changed file with 54 additions and 45 deletions.
    99 changes: 54 additions & 45 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.3.0
    // @version 1.3.1
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    @@ -25,12 +25,12 @@ var fonts = [
    "MS PMincho, MS P明朝, MS Mincho, MS 明朝",
    "Yu Gothic, YuGothic",
    "Yu Mincho, YuMincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro, ヒラギノ角ゴ Pro W3",
    "Hiragino Maru Gothic Pro, ヒラギノ丸ゴ Pro W3",
    "Hiragino Mincho Pro, ヒラギノ明朝 Pro W3",

    // Common Linux fonts
    "Takao Gothic, TakaoGothic",
    "Takao Mincho, TakaoMincho",
    @@ -41,7 +41,7 @@ var fonts = [
    "Dejima Mincho",
    "Ume Gothic",
    "Ume Mincho",

    // Other Japanese fonts people use.
    // You might want to try some of these!
    "EPSON 行書体M",
    @@ -63,7 +63,7 @@ var fonts = [
    "HakusyuKaisyoExtraBold_kk",
    "aoyagireisyosimo2, AoyagiKouzanFont2OTF",
    "aquafont",

    // Add your fonts here!
    "Fake font name that you can change",
    "Another fake font name",
    @@ -85,13 +85,13 @@ function fontExists(fontName) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    var text = "wim-—l~ツ亻".repeat(100); // Characters with widths that often vary between fonts.

    context.font = "72px monospace";
    var defaultWidth = context.measureText(text).width;

    context.font = "72px " + fontName + ", monospace";
    var testWidth = context.measureText(text).width;

    return testWidth != defaultWidth;
    }

    @@ -106,9 +106,9 @@ function canRepresentGlyphs(fontName, glyphs) {
    blank.width = canvas.width;
    blank.height = canvas.height;
    var blankDataUrl = blank.toDataURL();

    context.font = "24px " + fontName;

    var result = true;
    for (var i = 0; i < glyphs.length; i++) {
    context.fillText(glyphs[i], 0, 0);
    @@ -118,32 +118,17 @@ function canRepresentGlyphs(fontName, glyphs) {
    }
    context.clearRect(0, 0, canvas.width, canvas.height);
    }

    return result;
    }

    function shuffle(arr) {
    // WaniKani Reorder Ultimate overwrites Math.random(!?), so this
    // next line is required for Jitai to work in conjunction with it.
    var random = Math.randomB || Math.random;
    for (var i = arr.length; i > 0;) {
    var otherIndex = Math.floor(random() * i);
    i--;

    var temp = arr[i];
    arr[i] = arr[otherIndex];
    arr[otherIndex] = temp;
    }
    return arr;
    return result;
    }

    var jitai = {
    setToRandomFont: function(glyphs) {
    // The font is set as a randomly shuffled list of the existing fonts
    // in order to always show a random font, even if the first one chosen
    // doesn't have a certain glyph being attempted to be displayed.
    var randomlyOrdered = shuffle(existingFonts.slice());
    var randomlyOrdered = this.getShuffledFonts();

    // Some fonts don't contain certain radicals, for example, so it's best
    // to check that the font used can represent all the glyphs. The reason
    // the browser can't switch automatically is that some fonts report that
    @@ -160,74 +145,98 @@ var jitai = {
    } else {
    currentFont = randomlyOrdered.join(', ');
    }

    this.currentFont = currentFont;

    jitai.setHoverFont(jitai.defaultFont);
    this.$characterSpan.css('font-family', currentFont);
    },
    setToDefaultFont: function(fontName) {

    setToDefaultFont: function() {
    jitai.setHoverFont(jitai.currentFont);
    this.$characterSpan.css('font-family', '');
    },

    setHoverFont: function(fontName) {
    this.$hoverStyle.text("#character span:hover {font-family: " + fontName + " !important;}");
    },

    init: function() {

    getShuffledFonts: function() {
    // This shouldn't have to be part of the Jitai object,
    // but ituses Jitai's local copy of Math.random, so
    // this is pretty much the most reasonable way to do it.
    var fonts = existingFonts.slice();
    for (var i = fonts.length; i > 0;) {
    var otherIndex = Math.floor(this.random() * i);
    i--;

    var temp = fonts[i];
    fonts[i] = fonts[otherIndex];
    fonts[otherIndex] = temp;
    }
    return fonts;
    },

    init: function() {
    // Reorder scripts seem to like overwriting Math.random(!?), so this
    // workaround is required for Jitai to work in conjunction with them.
    var iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    this.random = iframe.contentWindow.Math.random;
    iframe.parentNode.removeChild(iframe);

    this.$characterSpan = $('#character span');
    this.defaultFont = this.$characterSpan.css('font-family');

    this.$hoverStyle = $('<style/>', {'type': 'text/css'});
    $('head').append(this.$hoverStyle);

    // answerChecker.evaluate is only called when checking the answer, which
    // is why we catch it, check for the "proceed to correct/incorrect display"
    // condition, and set the font back to default if it's a non-stopping answer.
    var oldEvaluate = answerChecker.evaluate;
    answerChecker.evaluate = function(questionType, answer) {
    var result = oldEvaluate.apply(this, [questionType, answer]);

    if (!result.exception) {
    jitai.setToDefaultFont();
    }

    return result;
    };

    // $.jStorage.set('currentItem') is only called right when switching to a
    // new question, which is why we hook into it to randomize the font at the
    // exact right time: when a new item shows up.
    var oldSet = $.jStorage.set;
    $.jStorage.set = function(key, value, options) {
    var ret = oldSet.apply(this, [key, value, options]);

    if (key === 'currentItem') {
    jitai.setToRandomFont(value.kan || value.voc || value.rad);
    }

    return ret;
    };
    }
    };

    $(document).ready(function() {
    jitai.init();

    // Make sure page doesn't jump around on hover.
    var $heightStyle = $('<style/>', {'type': 'text/css'});
    var heightCss = "";

    // The different heights here are equal to the different line-heights.
    heightCss += "#question #character {height: 1.6em;}";
    heightCss += "#question #character.vocabulary {height: 3.21em;}";
    heightCss += "@media (max-width: 767px) {";
    heightCss += " #question #character {height: 2.4em;}";
    heightCss += " #question #character.vocabulary {height: 4.85em;}";
    heightCss += "}";

    $heightStyle.text(heightCss);
    $('head').append($heightStyle);
    });
  7. @obskyr obskyr revised this gist Nov 18, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ Jitai will only use any given font for words where it has all the kanji in it, s

    * [Hoso Fuwa Font](http://www.freejapanesefont.com/hoso-fuwa-font-download/)
    * [Chihaya Gothic](http://www.freejapanesefont.com/chihaya-gothic-%E3%81%A1%E3%81%AF%E3%82%84%E3%82%B4%E3%82%B7%E3%83%83%E3%82%AF/)
    * [chifont / chifont+](http://www.freejapanesefont.com/chihaya-font-download/)
    * [chifont / chifont+](http://welina.holy.jp/font/tegaki/nchif/) (original source gone, mirror - bottom download link)
    * [Darts Font](http://www.freejapanesefont.com/darts-font-handwriting-font-download/)
    * [San Choume Font](http://www.freejapanesefont.com/sanchoume-handwriting-font-download/)
    * [FC Flower](http://www.freejapanesefont.com/fc-flower-handwriting-font/)
    @@ -45,7 +45,7 @@ Jitai will only use any given font for words where it has all the kanji in it, s
    * [Ume Gothic](https://launchpad.net/ubuntu/+source/fonts-horai-umefont) (`apt-get install fonts-horai-umefont`)
    * [Ume Mincho](https://launchpad.net/ubuntu/+source/fonts-horai-umefont) (`apt-get install fonts-horai-umefont`)

    ## [EPSON families](http://www.epson.jp/download2/readme/3.0/ttf30.htm) (download and run `ttf30.exe`)
    ## [EPSON families](http://www.epson.jp/download2/readme/3.0/ttf30.htm) (download and run the `.exe`)

    * EPSON 行書体M
    * EPSON 正楷書体M
    @@ -59,4 +59,4 @@ Jitai will only use any given font for words where it has all the kanji in it, s
    * A-OTF Shin Maru Go Pro
    * A-OTF Jun Pro
    * [Aoyagi Kouzan](http://www.jref.com/resources/aoyagi-kouzan.90/#resourceInfo)
    * [aquafont](www.jref.com/resources/aquafont.91/#resourceInfo)
    * [aquafont](http://www.jref.com/resources/aquafont.91/#resourceInfo)
  8. @obskyr obskyr revised this gist Oct 6, 2016. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ Jitai will only use any given font for words where it has all the kanji in it, s
    * [Armed Banana](http://www.freejapanesefont.com/armed-banana-download/) (this one is seriously absurd - I highly recommend it)
    * [Hakusyu Kaisho Bold](http://www.freejapanesefont.com/hakusyu-kaisho-bold-calligraphy/)
    * [Nagayama Kai](http://www.freejapanesefont.com/nagayama-kai-calligraphy-font-download/)
    * [Cinecaption](http://www.freejapanesefont.com/cinecaption/)
    * [Cinecaption](http://www.jref.com/resources/cinecaption.85/#resourceInfo) (original source gone, mirror)

    ---

    @@ -58,5 +58,5 @@ Jitai will only use any given font for words where it has all the kanji in it, s

    * A-OTF Shin Maru Go Pro
    * A-OTF Jun Pro
    * [Aoyagi Kouzan](http://cooltext.com/Download-Font-%E9%9D%92%E6%9F%B3%E8%A1%A1%E5%B1%B1+Aoyagi+Kouzan)
    * [aquafont](http://cooltext.com/Download-Font-%E3%81%82%E3%81%8F%E3%81%82+aqua)
    * [Aoyagi Kouzan](http://www.jref.com/resources/aoyagi-kouzan.90/#resourceInfo)
    * [aquafont](www.jref.com/resources/aquafont.91/#resourceInfo)
  9. @obskyr obskyr revised this gist Apr 18, 2016. 1 changed file with 11 additions and 11 deletions.
    22 changes: 11 additions & 11 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,11 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.2.1
    // @version 1.3.0
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    // @homepageURL https://gist.github.com/obskyr/9f3c77cf6bf663792c6e
    // @icon http://i.imgur.com/7uScPR4.png
    // @icon http://i.imgur.com/qyuR9bD.png
    // @include /^https?://(www\.)?wanikani\.com/review/session/?$/
    // @grant none
    // ==/UserScript==
    @@ -148,19 +148,19 @@ var jitai = {
    // to check that the font used can represent all the glyphs. The reason
    // the browser can't switch automatically is that some fonts report that
    // they have a glyph, when in fact they just show up blank.
    var currentFont;
    if (glyphs) {
    var currentFont = [];
    for (var i = 0; i < randomlyOrdered.length; i++) {
    var fontName = randomlyOrdered[i];
    if (canRepresentGlyphs(fontName, glyphs)) {
    currentFont.push(fontName);
    currentFont = fontName;
    break;
    }
    }
    } else {
    var currentFont = randomlyOrdered;
    currentFont = randomlyOrdered.join(', ');
    }

    currentFont = currentFont.join(', ');
    this.currentFont = currentFont;

    jitai.setHoverFont(jitai.defaultFont);
    @@ -221,11 +221,11 @@ $(document).ready(function() {
    var heightCss = "";

    // The different heights here are equal to the different line-heights.
    heightCss += " #question #character {height: 1.6em;}";
    heightCss += " #question #character.vocabulary {height: 3.21em;}";
    heightCss += " @media (max-width: 767px) {";
    heightCss += " #question #character {height: 2.4em;}";
    heightCss += " #question #character.vocabulary {height: 4.85em;}";
    heightCss += "#question #character {height: 1.6em;}";
    heightCss += "#question #character.vocabulary {height: 3.21em;}";
    heightCss += "@media (max-width: 767px) {";
    heightCss += " #question #character {height: 2.4em;}";
    heightCss += " #question #character.vocabulary {height: 4.85em;}";
    heightCss += "}";

    $heightStyle.text(heightCss);
  10. @obskyr obskyr revised this gist Mar 15, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,8 @@

    I would recommend taking a look at these fonts, and installing the ones you'd like. Once installed, Jitai will automatically use them. I, personally, have them all installed - it's a good mix!

    Jitai will only use any given font for words where it has all the kanji in it, so don't be afraid of installing fonts that only contain a limited subset of kanji - it can't hurt. Go wild!

    * [Hoso Fuwa Font](http://www.freejapanesefont.com/hoso-fuwa-font-download/)
    * [Chihaya Gothic](http://www.freejapanesefont.com/chihaya-gothic-%E3%81%A1%E3%81%AF%E3%82%84%E3%82%B4%E3%82%B7%E3%83%83%E3%82%AF/)
    * [chifont / chifont+](http://www.freejapanesefont.com/chihaya-font-download/)
  11. @obskyr obskyr revised this gist Mar 15, 2016. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.2.0
    // @version 1.2.1
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    @@ -20,16 +20,16 @@

    var fonts = [
    // Default Windows fonts
    "Meiryo",
    "MS Gothic",
    "MS Mincho",
    "Meiryo, メイリオ",
    "MS PGothic, MS Pゴシック, MS Gothic, MS ゴック",
    "MS PMincho, MS P明朝, MS Mincho, MS 明朝",
    "Yu Gothic, YuGothic",
    "Yu Mincho, YuMincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro",
    "Hiragino Maru Gothic Pro",
    "Hiragino Mincho Pro",
    "Hiragino Kaku Gothic Pro, ヒラギノ角ゴ Pro W3",
    "Hiragino Maru Gothic Pro, ヒラギノ丸ゴ Pro W3",
    "Hiragino Mincho Pro, ヒラギノ明朝 Pro W3",

    // Common Linux fonts
    "Takao Gothic, TakaoGothic",
  12. @obskyr obskyr revised this gist Mar 15, 2016. 2 changed files with 9 additions and 4 deletions.
    11 changes: 8 additions & 3 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.1.1
    // @version 1.2.0
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    @@ -62,7 +62,7 @@ var fonts = [
    "ArmedBanana", // This one is completely absurd. I recommend it.
    "HakusyuKaisyoExtraBold_kk",
    "aoyagireisyosimo2, AoyagiKouzanFont2OTF",
    "S2G Nagurigaki font, S2G Nagurigaki font-PRO, nagurigaki, nagurigaki-P",
    "aquafont",

    // Add your fonts here!
    "Fake font name that you can change",
    @@ -123,8 +123,11 @@ function canRepresentGlyphs(fontName, glyphs) {
    }

    function shuffle(arr) {
    // WaniKani Reorder Ultimate overwrites Math.random(!?), so this
    // next line is required for Jitai to work in conjunction with it.
    var random = Math.randomB || Math.random;
    for (var i = arr.length; i > 0;) {
    var otherIndex = Math.floor(Math.random() * i);
    var otherIndex = Math.floor(random() * i);
    i--;

    var temp = arr[i];
    @@ -200,9 +203,11 @@ var jitai = {
    var oldSet = $.jStorage.set;
    $.jStorage.set = function(key, value, options) {
    var ret = oldSet.apply(this, [key, value, options]);

    if (key === 'currentItem') {
    jitai.setToRandomFont(value.kan || value.voc || value.rad);
    }

    return ret;
    };
    }
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -57,4 +57,4 @@ I would recommend taking a look at these fonts, and installing the ones you'd li
    * A-OTF Shin Maru Go Pro
    * A-OTF Jun Pro
    * [Aoyagi Kouzan](http://cooltext.com/Download-Font-%E9%9D%92%E6%9F%B3%E8%A1%A1%E5%B1%B1+Aoyagi+Kouzan)
    * [nagurigaki](http://cooltext.com/Download-Font-%E6%AE%B4%E3%82%8A%E6%9B%B8%E3%81%8D+nagurigaki)
    * [aquafont](http://cooltext.com/Download-Font-%E3%81%82%E3%81%8F%E3%81%82+aqua)
  13. @obskyr obskyr revised this gist Mar 12, 2016. 2 changed files with 4 additions and 10 deletions.
    11 changes: 4 additions & 7 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.1.0
    // @version 1.1.1
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    @@ -23,16 +23,13 @@ var fonts = [
    "Meiryo",
    "MS Gothic",
    "MS Mincho",
    "Yu Gothic",
    "Yu Mincho",
    "Yu Gothic, YuGothic",
    "Yu Mincho, YuMincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro",
    "Hiragino Maru Gothic Pro",
    "Hiragino Mincho Pro",
    "Hannotate TC",
    "HanziPen TC",
    "Kaiti TC",

    // Common Linux fonts
    "Takao Gothic, TakaoGothic",
    @@ -209,7 +206,7 @@ var jitai = {
    return ret;
    };
    }
    }
    };

    $(document).ready(function() {
    jitai.init();
    3 changes: 0 additions & 3 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -30,9 +30,6 @@ I would recommend taking a look at these fonts, and installing the ones you'd li
    * Hiragino Kaku Gothic Pro
    * Hiragino Maru Gothic Pro
    * Hiragino Mincho Pro
    * Hannotate TC
    * HanziPen TC
    * Kaiti TC

    ## Common Linux fonts

  14. @obskyr obskyr revised this gist Mar 12, 2016. 2 changed files with 89 additions and 72 deletions.
    156 changes: 86 additions & 70 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    // ==UserScript==
    // @name Jitai
    // @version 1.0.0
    // @version 1.1.0
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    @@ -30,8 +30,9 @@ var fonts = [
    "Hiragino Kaku Gothic Pro",
    "Hiragino Maru Gothic Pro",
    "Hiragino Mincho Pro",
    "Hannotate",
    "HanziPen",
    "Hannotate TC",
    "HanziPen TC",
    "Kaiti TC",

    // Common Linux fonts
    "Takao Gothic, TakaoGothic",
    @@ -136,80 +137,95 @@ function shuffle(arr) {
    return arr;
    }

    var $characterSpan;
    function setToRandomFont(glyphs) {
    // The font is set as a randomly shuffled list of the existing fonts
    // in order to always show a random font, even if the first one chosen
    // doesn't have a certain glyph being attempted to be displayed.
    var randomlyOrdered = shuffle(existingFonts.slice());

    // Some fonts don't contain certain radicals, for example, so it's best
    // to check that the font used can represent all the glyphs. The reason
    // the browser can't switch automatically is that some fonts report that
    // they have a glyph, when in fact they just show up blank.
    if (glyphs) {
    var currentFont = [];
    for (var i = 0; i < randomlyOrdered.length; i++) {
    var fontName = randomlyOrdered[i];
    if (canRepresentGlyphs(fontName, glyphs)) {
    currentFont.push(fontName);
    var jitai = {
    setToRandomFont: function(glyphs) {
    // The font is set as a randomly shuffled list of the existing fonts
    // in order to always show a random font, even if the first one chosen
    // doesn't have a certain glyph being attempted to be displayed.
    var randomlyOrdered = shuffle(existingFonts.slice());

    // Some fonts don't contain certain radicals, for example, so it's best
    // to check that the font used can represent all the glyphs. The reason
    // the browser can't switch automatically is that some fonts report that
    // they have a glyph, when in fact they just show up blank.
    if (glyphs) {
    var currentFont = [];
    for (var i = 0; i < randomlyOrdered.length; i++) {
    var fontName = randomlyOrdered[i];
    if (canRepresentGlyphs(fontName, glyphs)) {
    currentFont.push(fontName);
    }
    }
    } else {
    var currentFont = randomlyOrdered;
    }
    } else {
    var currentFont = randomlyOrdered;

    currentFont = currentFont.join(', ');
    this.currentFont = currentFont;

    jitai.setHoverFont(jitai.defaultFont);
    this.$characterSpan.css('font-family', currentFont);
    },

    setToDefaultFont: function(fontName) {
    jitai.setHoverFont(jitai.currentFont);
    this.$characterSpan.css('font-family', '');
    },

    setHoverFont: function(fontName) {
    this.$hoverStyle.text("#character span:hover {font-family: " + fontName + " !important;}");
    },

    init: function() {
    this.$characterSpan = $('#character span');
    this.defaultFont = this.$characterSpan.css('font-family');

    this.$hoverStyle = $('<style/>', {'type': 'text/css'});
    $('head').append(this.$hoverStyle);

    // answerChecker.evaluate is only called when checking the answer, which
    // is why we catch it, check for the "proceed to correct/incorrect display"
    // condition, and set the font back to default if it's a non-stopping answer.
    var oldEvaluate = answerChecker.evaluate;
    answerChecker.evaluate = function(questionType, answer) {
    var result = oldEvaluate.apply(this, [questionType, answer]);

    if (!result.exception) {
    jitai.setToDefaultFont();
    }

    return result;
    };

    // $.jStorage.set('currentItem') is only called right when switching to a
    // new question, which is why we hook into it to randomize the font at the
    // exact right time: when a new item shows up.
    var oldSet = $.jStorage.set;
    $.jStorage.set = function(key, value, options) {
    var ret = oldSet.apply(this, [key, value, options]);
    if (key === 'currentItem') {
    jitai.setToRandomFont(value.kan || value.voc || value.rad);
    }
    return ret;
    };
    }

    currentFont = currentFont.join(', ');
    $characterSpan.css('font-family', currentFont);
    }

    function setToDefaultFont(fontName) {
    $characterSpan.css('font-family', '');
    }

    $(document).ready(function() {
    $characterSpan = $('#character span');
    var defaultFont = $characterSpan.css('font-family');

    // Add hover style, to allow hovering away weird fonts.
    var $hoverStyle = $('<style/>', {'type': 'text/css'});
    var hoverCss = "#character span:hover {font-family: " + defaultFont + " !important;}"
    jitai.init();

    // Make sure page doesn't jump around on hover.
    var $heightStyle = $('<style/>', {'type': 'text/css'});
    var heightCss = "";

    // The different heights here are equal to the different line-heights.
    hoverCss += " #question #character {height: 1.6em;}";
    hoverCss += " #question #character.vocabulary {height: 3.21em;}"
    hoverCss += " @media (max-width: 767px) {"
    hoverCss += " #question #character {height: 2.4em;}"
    hoverCss += " #question #character.vocabulary {height: 4.85em;}"
    hoverCss += "}"

    $hoverStyle.text(hoverCss);
    $('head').append($hoverStyle);

    // answerChecker.evaluate is only called when checking the answer, which
    // is why we catch it, check for the "proceed to correct/incorrect display"
    // condition, and set the font back to default if it's a non-stopping answer.
    var oldEvaluate = answerChecker.evaluate;
    answerChecker.evaluate = function(questionType, answer) {
    var result = oldEvaluate.apply(this, [questionType, answer]);

    if (!result.exception) {
    setToDefaultFont();
    }

    return result;
    };

    // $.jStorage.set('currentItem') is only called right when switching to a
    // new question, which is why we hook into it to randomize the font at the
    // exact right time: when a new item shows up.
    var oldSet = $.jStorage.set;
    $.jStorage.set = function(key, value, options) {
    var ret = oldSet.apply(this, [key, value, options]);
    if (key === 'currentItem') {
    setToRandomFont(value.kan || value.voc || value.rad);
    }
    return ret;
    };
    heightCss += " #question #character {height: 1.6em;}";
    heightCss += " #question #character.vocabulary {height: 3.21em;}";
    heightCss += " @media (max-width: 767px) {";
    heightCss += " #question #character {height: 2.4em;}";
    heightCss += " #question #character.vocabulary {height: 4.85em;}";
    heightCss += "}";

    $heightStyle.text(heightCss);
    $('head').append($heightStyle);
    });
    5 changes: 3 additions & 2 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -30,8 +30,9 @@ I would recommend taking a look at these fonts, and installing the ones you'd li
    * Hiragino Kaku Gothic Pro
    * Hiragino Maru Gothic Pro
    * Hiragino Mincho Pro
    * Hannotate
    * HanziPen
    * Hannotate TC
    * HanziPen TC
    * Kaiti TC

    ## Common Linux fonts

  15. @obskyr obskyr revised this gist Mar 11, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ I would recommend taking a look at these fonts, and installing the ones you'd li
    * [Darts Font](http://www.freejapanesefont.com/darts-font-handwriting-font-download/)
    * [San Choume Font](http://www.freejapanesefont.com/sanchoume-handwriting-font-download/)
    * [FC Flower](http://www.freejapanesefont.com/fc-flower-handwriting-font/)
    * [Armed Banana](http://www.freejapanesefont.com/armed-banana-download/)
    * [Armed Banana](http://www.freejapanesefont.com/armed-banana-download/) (this one is seriously absurd - I highly recommend it)
    * [Hakusyu Kaisho Bold](http://www.freejapanesefont.com/hakusyu-kaisho-bold-calligraphy/)
    * [Nagayama Kai](http://www.freejapanesefont.com/nagayama-kai-calligraphy-font-download/)
    * [Cinecaption](http://www.freejapanesefont.com/cinecaption/)
  16. @obskyr obskyr revised this gist Mar 11, 2016. 1 changed file with 12 additions and 7 deletions.
    19 changes: 12 additions & 7 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -169,16 +169,23 @@ function setToDefaultFont(fontName) {

    $(document).ready(function() {
    $characterSpan = $('#character span');
    var defaultFont = $characterSpan.css('font-family') + ' !important';
    var defaultFont = $characterSpan.css('font-family');

    // Add hover style, to allow hovering away weird fonts.
    var $hoverStyle = $('<style/>', {'type': 'text/css'});
    $hoverStyle.text("#character span:hover {font-family: " + defaultFont + ";}");
    $('head').append($hoverStyle);
    var hoverCss = "#character span:hover {font-family: " + defaultFont + " !important;}"

    // Make sure page doesn't jump around on hover.
    $('#character').css('height', $('#character').css('line-height'));

    // The different heights here are equal to the different line-heights.
    hoverCss += " #question #character {height: 1.6em;}";
    hoverCss += " #question #character.vocabulary {height: 3.21em;}"
    hoverCss += " @media (max-width: 767px) {"
    hoverCss += " #question #character {height: 2.4em;}"
    hoverCss += " #question #character.vocabulary {height: 4.85em;}"
    hoverCss += "}"

    $hoverStyle.text(hoverCss);
    $('head').append($hoverStyle);

    // answerChecker.evaluate is only called when checking the answer, which
    // is why we catch it, check for the "proceed to correct/incorrect display"
    @@ -205,6 +212,4 @@ $(document).ready(function() {
    }
    return ret;
    };

    setToRandomFont();
    });
  17. @obskyr obskyr revised this gist Mar 11, 2016. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -57,8 +57,7 @@ var fonts = [
    "A-OTF Shin Maru Go Pro",
    "Hosofuwafont",
    "ChihayaGothic",
    "chifont",
    "'chifont+'",
    "'chifont+', chifont",
    "darts font",
    "santyoume-font",
    "FC-Flower",
  18. @obskyr obskyr revised this gist Mar 11, 2016. 1 changed file with 3 additions and 8 deletions.
    11 changes: 3 additions & 8 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -95,8 +95,6 @@ function fontExists(fontName) {
    context.font = "72px " + fontName + ", monospace";
    var testWidth = context.measureText(text).width;

    delete canvas;

    return testWidth != defaultWidth;
    }

    @@ -124,9 +122,6 @@ function canRepresentGlyphs(fontName, glyphs) {
    context.clearRect(0, 0, canvas.width, canvas.height);
    }

    delete canvas;
    delete blank;

    return result;
    }

    @@ -156,7 +151,7 @@ function setToRandomFont(glyphs) {
    if (glyphs) {
    var currentFont = [];
    for (var i = 0; i < randomlyOrdered.length; i++) {
    var fontName = randomlyOrdered[i]
    var fontName = randomlyOrdered[i];
    if (canRepresentGlyphs(fontName, glyphs)) {
    currentFont.push(fontName);
    }
    @@ -198,7 +193,7 @@ $(document).ready(function() {
    }

    return result;
    }
    };

    // $.jStorage.set('currentItem') is only called right when switching to a
    // new question, which is why we hook into it to randomize the font at the
    @@ -210,7 +205,7 @@ $(document).ready(function() {
    setToRandomFont(value.kan || value.voc || value.rad);
    }
    return ret;
    }
    };

    setToRandomFont();
    });
  19. @obskyr obskyr revised this gist Mar 11, 2016. 1 changed file with 1 addition and 21 deletions.
    22 changes: 1 addition & 21 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -131,7 +131,7 @@ function canRepresentGlyphs(fontName, glyphs) {
    }

    function shuffle(arr) {
    for (var i = arr.length;; i > 0) {
    for (var i = arr.length; i > 0;) {
    var otherIndex = Math.floor(Math.random() * i);
    i--;

    @@ -142,26 +142,6 @@ function shuffle(arr) {
    return arr;
    }

    function shuffle(array) {
    let counter = array.length;

    // While there are elements in the array
    while (counter > 0) {
    // Pick a random index
    let index = Math.floor(Math.random() * counter);

    // Decrease counter by 1
    counter--;

    // And swap the last element with it
    let temp = array[counter];
    array[counter] = array[index];
    array[index] = temp;
    }

    return array;
    }

    var $characterSpan;
    function setToRandomFont(glyphs) {
    // The font is set as a randomly shuffled list of the existing fonts
  20. @obskyr obskyr revised this gist Mar 11, 2016. No changes.
  21. @obskyr obskyr revised this gist Mar 11, 2016. No changes.
  22. @obskyr obskyr renamed this gist Mar 11, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  23. @obskyr obskyr revised this gist Mar 11, 2016. 2 changed files with 65 additions and 0 deletions.
    62 changes: 62 additions & 0 deletions fonts.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    # List of supported fonts and download links

    ## Fonts from [freejapanesefont.com](http://www.freejapanesefont.com/)

    I would recommend taking a look at these fonts, and installing the ones you'd like. Once installed, Jitai will automatically use them. I, personally, have them all installed - it's a good mix!

    * [Hoso Fuwa Font](http://www.freejapanesefont.com/hoso-fuwa-font-download/)
    * [Chihaya Gothic](http://www.freejapanesefont.com/chihaya-gothic-%E3%81%A1%E3%81%AF%E3%82%84%E3%82%B4%E3%82%B7%E3%83%83%E3%82%AF/)
    * [chifont / chifont+](http://www.freejapanesefont.com/chihaya-font-download/)
    * [Darts Font](http://www.freejapanesefont.com/darts-font-handwriting-font-download/)
    * [San Choume Font](http://www.freejapanesefont.com/sanchoume-handwriting-font-download/)
    * [FC Flower](http://www.freejapanesefont.com/fc-flower-handwriting-font/)
    * [Armed Banana](http://www.freejapanesefont.com/armed-banana-download/)
    * [Hakusyu Kaisho Bold](http://www.freejapanesefont.com/hakusyu-kaisho-bold-calligraphy/)
    * [Nagayama Kai](http://www.freejapanesefont.com/nagayama-kai-calligraphy-font-download/)
    * [Cinecaption](http://www.freejapanesefont.com/cinecaption/)

    ---

    ## Default Windows fonts

    * Meiryo
    * MS Gothic
    * MS Mincho
    * Yu Gothic
    * Yu Mincho

    ## Default OS X fonts

    * Hiragino Kaku Gothic Pro
    * Hiragino Maru Gothic Pro
    * Hiragino Mincho Pro
    * Hannotate
    * HanziPen

    ## Common Linux fonts

    * [Takao Gothic](https://launchpad.net/ubuntu/+source/fonts-takao) (`apt-get install fonts-takao`)
    * [Takao Mincho](https://launchpad.net/ubuntu/+source/fonts-takao) (`apt-get install fonts-takao`)
    * [Sazanami Gothic](https://launchpad.net/ubuntu/+source/ttf-sazanami)
    * [Sazanami Mincho](https://launchpad.net/ubuntu/+source/ttf-sazanami)
    * [Kochi Gothic](https://launchpad.net/ubuntu/+source/ttf-kochi) (`apt-get install ttf-kochi-gothic`)
    * [Kochi Mincho](https://launchpad.net/ubuntu/+source/ttf-kochi) (`apt-get install ttf-kochi-mincho`)
    * [Dejima Mincho](https://launchpad.net/ubuntu/+source/fonts-dejima-mincho) (`apt-get install fonts-dejima-mincho`)
    * [Ume Gothic](https://launchpad.net/ubuntu/+source/fonts-horai-umefont) (`apt-get install fonts-horai-umefont`)
    * [Ume Mincho](https://launchpad.net/ubuntu/+source/fonts-horai-umefont) (`apt-get install fonts-horai-umefont`)

    ## [EPSON families](http://www.epson.jp/download2/readme/3.0/ttf30.htm) (download and run `ttf30.exe`)

    * EPSON 行書体M
    * EPSON 正楷書体M
    * EPSON 教科書体M
    * EPSON 太明朝体B
    * EPSON 太行書体B
    * EPSON 丸ゴシック体M

    ## Other fonts (Typekit, etc.)

    * A-OTF Shin Maru Go Pro
    * A-OTF Jun Pro
    * [Aoyagi Kouzan](http://cooltext.com/Download-Font-%E9%9D%92%E6%9F%B3%E8%A1%A1%E5%B1%B1+Aoyagi+Kouzan)
    * [nagurigaki](http://cooltext.com/Download-Font-%E6%AE%B4%E3%82%8A%E6%9B%B8%E3%81%8D+nagurigaki)
    3 changes: 3 additions & 0 deletions jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -56,13 +56,16 @@ var fonts = [
    "nagayama_kai",
    "A-OTF Shin Maru Go Pro",
    "Hosofuwafont",
    "ChihayaGothic",
    "chifont",
    "'chifont+'",
    "darts font",
    "santyoume-font",
    "FC-Flower",
    "ArmedBanana", // This one is completely absurd. I recommend it.
    "HakusyuKaisyoExtraBold_kk",
    "aoyagireisyosimo2, AoyagiKouzanFont2OTF",
    "S2G Nagurigaki font, S2G Nagurigaki font-PRO, nagurigaki, nagurigaki-P",

    // Add your fonts here!
    "Fake font name that you can change",
  24. @obskyr obskyr renamed this gist Mar 11, 2016. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions random_wanikani_fonts.user.js → jitai.user.js
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,12 @@
    // ==UserScript==
    // @name Random WaniKani fonts
    // @namespace http://obskyr.io/
    // @name Jitai
    // @version 1.0.0
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @author Samuel (@obskyr)
    // @namespace http://obskyr.io/
    // @homepageURL https://gist.github.com/obskyr/9f3c77cf6bf663792c6e
    // @icon http://i.imgur.com/7uScPR4.png
    // @include /^https?://(www\.)?wanikani\.com/review/session/?$/
    // @version 1.0.0
    // @grant none
    // ==/UserScript==

  25. @obskyr obskyr created this gist Mar 11, 2016.
    230 changes: 230 additions & 0 deletions random_wanikani_fonts.user.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,230 @@
    // ==UserScript==
    // @name Random WaniKani fonts
    // @namespace http://obskyr.io/
    // @description Display WaniKani reviews in randomized fonts, for more varied reading training.
    // @include /^https?://(www\.)?wanikani\.com/review/session/?$/
    // @version 1.0.0
    // @grant none
    // ==/UserScript==

    /*
    To control which fonts to choose from, edit this list.
    If you feel too many fonts of a certain type are showing
    up, remove a few of those from the list. If you've got
    fonts that aren't in the list that you'd like to be used,
    add their names and they'll be in the rotation.
    */

    var fonts = [
    // Default Windows fonts
    "Meiryo",
    "MS Gothic",
    "MS Mincho",
    "Yu Gothic",
    "Yu Mincho",

    // Default OS X fonts
    "Hiragino Kaku Gothic Pro",
    "Hiragino Maru Gothic Pro",
    "Hiragino Mincho Pro",
    "Hannotate",
    "HanziPen",

    // Common Linux fonts
    "Takao Gothic, TakaoGothic",
    "Takao Mincho, TakaoMincho",
    "Sazanami Gothic",
    "Sazanami Mincho",
    "Kochi Gothic",
    "Kochi Mincho",
    "Dejima Mincho",
    "Ume Gothic",
    "Ume Mincho",

    // Other Japanese fonts people use.
    // You might want to try some of these!
    "EPSON 行書体M",
    "EPSON 正楷書体M",
    "EPSON 教科書体M",
    "EPSON 太明朝体B",
    "EPSON 太行書体B",
    "EPSON 丸ゴシック体M",
    "cinecaption",
    "nagayama_kai",
    "A-OTF Shin Maru Go Pro",
    "Hosofuwafont",
    "chifont",
    "'chifont+'",
    "darts font",
    "santyoume-font",
    "FC-Flower",
    "ArmedBanana", // This one is completely absurd. I recommend it.
    "HakusyuKaisyoExtraBold_kk",

    // Add your fonts here!
    "Fake font name that you can change",
    "Another fake font name",
    "Just add them like this!",
    "Quotes around the name, comma after."
    ];

    var existingFonts = [];
    for (var i = 0; i < fonts.length; i++) {
    var fontName = fonts[i];
    if (fontExists(fontName)) {
    existingFonts.push(fontName);
    }
    }

    function fontExists(fontName) {
    // Approach from kirupa.com/html5/detect_whether_font_is_installed.htm - thanks!
    // Will return false for the browser's default monospace font, sadly.
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    var text = "wim-—l~ツ亻".repeat(100); // Characters with widths that often vary between fonts.

    context.font = "72px monospace";
    var defaultWidth = context.measureText(text).width;

    context.font = "72px " + fontName + ", monospace";
    var testWidth = context.measureText(text).width;

    delete canvas;

    return testWidth != defaultWidth;
    }

    function canRepresentGlyphs(fontName, glyphs) {
    var canvas = document.createElement('canvas');
    canvas.width = 50;
    canvas.height = 50;
    var context = canvas.getContext("2d");
    context.textBaseline = 'top';

    var blank = document.createElement('canvas');
    blank.width = canvas.width;
    blank.height = canvas.height;
    var blankDataUrl = blank.toDataURL();

    context.font = "24px " + fontName;

    var result = true;
    for (var i = 0; i < glyphs.length; i++) {
    context.fillText(glyphs[i], 0, 0);
    if (canvas.toDataURL() === blankDataUrl) {
    result = false;
    break;
    }
    context.clearRect(0, 0, canvas.width, canvas.height);
    }

    delete canvas;
    delete blank;

    return result;
    }

    function shuffle(arr) {
    for (var i = arr.length;; i > 0) {
    var otherIndex = Math.floor(Math.random() * i);
    i--;

    var temp = arr[i];
    arr[i] = arr[otherIndex];
    arr[otherIndex] = temp;
    }
    return arr;
    }

    function shuffle(array) {
    let counter = array.length;

    // While there are elements in the array
    while (counter > 0) {
    // Pick a random index
    let index = Math.floor(Math.random() * counter);

    // Decrease counter by 1
    counter--;

    // And swap the last element with it
    let temp = array[counter];
    array[counter] = array[index];
    array[index] = temp;
    }

    return array;
    }

    var $characterSpan;
    function setToRandomFont(glyphs) {
    // The font is set as a randomly shuffled list of the existing fonts
    // in order to always show a random font, even if the first one chosen
    // doesn't have a certain glyph being attempted to be displayed.
    var randomlyOrdered = shuffle(existingFonts.slice());

    // Some fonts don't contain certain radicals, for example, so it's best
    // to check that the font used can represent all the glyphs. The reason
    // the browser can't switch automatically is that some fonts report that
    // they have a glyph, when in fact they just show up blank.
    if (glyphs) {
    var currentFont = [];
    for (var i = 0; i < randomlyOrdered.length; i++) {
    var fontName = randomlyOrdered[i]
    if (canRepresentGlyphs(fontName, glyphs)) {
    currentFont.push(fontName);
    }
    }
    } else {
    var currentFont = randomlyOrdered;
    }

    currentFont = currentFont.join(', ');
    $characterSpan.css('font-family', currentFont);
    }

    function setToDefaultFont(fontName) {
    $characterSpan.css('font-family', '');
    }

    $(document).ready(function() {
    $characterSpan = $('#character span');
    var defaultFont = $characterSpan.css('font-family') + ' !important';

    // Add hover style, to allow hovering away weird fonts.
    var $hoverStyle = $('<style/>', {'type': 'text/css'});
    $hoverStyle.text("#character span:hover {font-family: " + defaultFont + ";}");
    $('head').append($hoverStyle);

    // Make sure page doesn't jump around on hover.
    $('#character').css('height', $('#character').css('line-height'));


    // answerChecker.evaluate is only called when checking the answer, which
    // is why we catch it, check for the "proceed to correct/incorrect display"
    // condition, and set the font back to default if it's a non-stopping answer.
    var oldEvaluate = answerChecker.evaluate;
    answerChecker.evaluate = function(questionType, answer) {
    var result = oldEvaluate.apply(this, [questionType, answer]);

    if (!result.exception) {
    setToDefaultFont();
    }

    return result;
    }

    // $.jStorage.set('currentItem') is only called right when switching to a
    // new question, which is why we hook into it to randomize the font at the
    // exact right time: when a new item shows up.
    var oldSet = $.jStorage.set;
    $.jStorage.set = function(key, value, options) {
    var ret = oldSet.apply(this, [key, value, options]);
    if (key === 'currentItem') {
    setToRandomFont(value.kan || value.voc || value.rad);
    }
    return ret;
    }

    setToRandomFont();
    });