Skip to content

Instantly share code, notes, and snippets.

@tingletech
Created January 9, 2012 09:02
Show Gist options
  • Save tingletech/1582068 to your computer and use it in GitHub Desktop.
Save tingletech/1582068 to your computer and use it in GitHub Desktop.
Create a list of fonts that are available on the browser.
<?xml version="1.0"?>
<div>
<style>
.green {color: green;}
.red {color: red;}
</style>
<table id="table" class="_table" border="1" cellspacing="0" cellpadding="5" width="100%" bordercolor="#cccccc">
<tbody>
<tr>
<th>Font Name</th>
<th>Width</th>
<th>Height</th>
<th>Detected?</th>
</tr>
</tbody>
</table>
<script src="./lalit_fonts.js" type="text/javascript"></script>
</div>
/**
* Actual function that does all the work. Returns an array
with all the info.
* My Assumption is that most of the browsers will have
arial set as their default sans-serif font.
*/
var Detector = function(){
var h = document.getElementsByTagName("BODY")[0];
var d = document.createElement("DIV");
var s = document.createElement("SPAN");
d.appendChild(s);
d.style.fontFamily = "serif"; //font for the parent element DIV.
s.style.fontFamily = "serif"; //have to use serif coz in FF3.0, it doesn't fall back to font of parent element.
s.style.fontSize = "72px"; //we test using 72px font size, we may use any size. I guess larger the better.
s.innerHTML = "mmmmmmmmmml"; //we use m or w because these two characters take up the maximum width. And we use a L so that the same matching fonts can get separated
h.appendChild(d);
var defaultWidth = s.offsetWidth; //now we have the defaultWidth
var defaultHeight = s.offsetHeight; //and the defaultHeight, we compare other fonts with these.
h.removeChild(d);
/* test
* params:
* font - name of the font you wish to detect
* return:
* f[0] - Input font name.
* f[1] - Computed width.
* f[2] - Computed height.
* f[3] - Detected? (true/false).
*/
function debug(font) {
h.appendChild(d);
var f = [];
f[0] = s.style.fontFamily = font; // Name of the font
f[1] = s.offsetWidth; // Width
f[2] = s.offsetHeight; // Height
h.removeChild(d);
font = font.toLowerCase();
if (font == "serif") {
f[3] = true; // to set arial and sans-serif true
} else {
f[3] = (f[1] != defaultWidth || f[2] != defaultHeight); // Detected?
}
return f;
}
function test(font){
f = debug(font);
return f[3];
}
this.detailedTest = debug;
this.test = test;
}
var fonts = [];
/**
* other stuff
*/
function init() {
fonts.push("cursive");
fonts.push("monospace");
fonts.push("serif");
fonts.push("sans-serif");
fonts.push("fantasy");
fonts.push("default");
fonts.push("Arial");
fonts.push("Arial Black");
fonts.push("Arial Narrow");
fonts.push("Arial Rounded MT Bold");
fonts.push("Bookman Old Style");
fonts.push("Bradley Hand ITC");
fonts.push("Century");
fonts.push("Century Gothic");
fonts.push("Comic Sans MS");
fonts.push("Courier");
fonts.push("Courier New");
fonts.push("Georgia");
fonts.push("Gentium");
fonts.push("Impact");
fonts.push("King");
fonts.push("Lucida Console");
fonts.push("Lalit");
fonts.push("Modena");
fonts.push("Monotype Corsiva");
fonts.push("Papyrus");
fonts.push("Tahoma");
fonts.push("TeX");
fonts.push("Times");
fonts.push("Times New Roman");
fonts.push("Trebuchet MS");
fonts.push("Verdana");
fonts.push("Verona");
d = new Detector();
// compute height and width for all fonts
for (i=0; i<fonts.length; i++) {
fonts.push(d.detailedTest(fonts.shift()));
}
//sortResults();
listResults();
}
function listResults() {
var table = document.getElementById('table');
for (i=0; i<fonts.length; i++) {
row = table.insertRow(-1);
col = row.insertCell(-1);
col.appendChild(document.createTextNode(fonts[i][0]))
col.style.fontFamily = fonts[i][0];
col = row.insertCell(-1).appendChild(document.createTextNode(fonts[i][1]));
col = row.insertCell(-1).appendChild(document.createTextNode(fonts[i][2]));
col = row.insertCell(-1);
fonts[i][3] ? col.className = "green" : col.className = "red";
col.appendChild(document.createTextNode(fonts[i][3]));
}
}
function sortResults() {
for (i=0; i<fonts.length-1; i++) {
for (j=i; j<fonts.length; j++) {
if(fonts[i][1] < fonts[j][1]) {
t = fonts[i];
fonts[i] = fonts[j];
fonts[j] = t;
}
}
}
}
// Event.observe(window, 'load', init);
window.onload = init;
@wakaztahir
Copy link

  • No allocations
  • Type safe

Didn't test the code though , but get FontResults should be called on document load

interface FontResult {
  fontFamily: string,
  width: number,
  height: number,
  unknown: boolean
}

class Detector {

  h: Element
  d: HTMLElement
  s: HTMLElement

  defaultWidth: number

  defaultHeight: number

  constructor() {
    this.h = document.getElementsByTagName("BODY")[0];
    this.d = document.createElement("DIV");
    this.s = document.createElement("SPAN");
    this.d.appendChild(this.s);
    this.d.style.fontFamily = "serif";    //font for the parent element DIV.
    this.s.style.fontFamily = "serif";    //have to use serif coz in FF3.0, it doesn't fall back to font of parent element.
    this.s.style.fontSize = "72px";      //we test using 72px font size, we may use any size. I guess larger the better.
    this.s.innerHTML = "mmmmmmmmmml";    //we use m or w because these two characters take up the maximum width. And we use a L so that the same matching fonts can get separated
    this.h.appendChild(this.d);
    this.defaultWidth = this.s.offsetWidth;    //now we have the defaultWidth
    this.defaultHeight = this.s.offsetHeight;  //and the defaultHeight, we compare other fonts with these.
    this.h.removeChild(this.d);
  }

  /**
   * Actual function that does all the work. Returns an array
   with all the info.
   * My Assumption is that most of the browsers will have
   arial set as their default sans-serif font.
   */
  detailedTest(font: string): FontResult {
    this.h.appendChild(this.d);
    const name = this.s.style.fontFamily = font;       // Name of the font
    const width = this.s.offsetWidth;                           // Width
    const height = this.s.offsetHeight;                          // Height
    this.h.removeChild(this.d);
    font = font.toLowerCase();
    let unknown: boolean
    if (font == "serif") {
      unknown = true;    // to set arial and sans-serif true
    } else {
      unknown = (width != this.defaultWidth || height != this.defaultHeight); // Detected?
    }
    return {
      fontFamily: name,
      width: width,
      height: height,
      unknown: unknown
    }
  }

}

/**
 * getFontResults
 */
function getFontResults(): FontResult[] {
  const fonts: string[] = [
    "cursive",
    "monospace",
    "serif",
    "sans-serif",
    "fantasy",
    "default",
    "Arial",
    "Arial Black",
    "Arial Narrow",
    "Arial Rounded MT Bold",
    "Bookman Old Style",
    "Bradley Hand ITC",
    "Century",
    "Century Gothic",
    "Comic Sans MS",
    "Courier",
    "Courier New",
    "Georgia",
    "Gentium",
    "Impact",
    "King",
    "Lucida Console",
    "Lalit",
    "Modena",
    "Monotype Corsiva",
    "Papyrus",
    "Tahoma",
    "TeX",
    "Times",
    "Times New Roman",
    "Trebuchet MS",
    "Verdana",
    "Verona"
  ];
  const fontResults: FontResult[] = []
  const d = new Detector();
  // compute height and width for all fonts
  for (let i = 0; i < fonts.length; i++) {
    fontResults.push(d.detailedTest(fonts.shift()!));
  }
  return fontResults
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment