You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Sven Slootweg 3950dce32f Initial commit; 1.0.0 8 years ago
src Initial commit; 1.0.0 8 years ago
.gitignore Initial commit; 1.0.0 8 years ago
.npmignore Initial commit; 1.0.0 8 years ago
README.md Initial commit; 1.0.0 8 years ago
gulpfile.js Initial commit; 1.0.0 8 years ago
index.js Initial commit; 1.0.0 8 years ago
package.json Initial commit; 1.0.0 8 years ago

README.md

measure-font

Measures the dimensions and baseline offsets of a font in the browser. Written as a workaround for lacking measureText/TextMetrics support in browsers.

Caveats

  • This only works in a browser environment, or some other kind of environment that implements the Canvas API. Support for the following is required:
    • document.createElement
    • context.getImageData
  • I'm not an expert at either fonts or text rendering. This implementation may very well be wrong in some way, even if it worked for my purposes. Patches welcome!
  • If you are using Web Fonts, make sure that all the fonts have loaded before trying to measure them. Otherwise, your measurements will be wrong.

License

WTFPL or CC0, whichever you prefer. A donation and/or attribution are appreciated, but not required.

Donate

Maintaining open-source projects takes a lot of time, and the more donations I receive, the more time I can dedicate to open-source. If this module is useful to you, consider making a donation!

You can donate using Bitcoin, PayPal, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else. Thank you!

Contributing

Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the files in src/, not those in lib/.

Build tool of choice is gulp; simply run gulp while developing, and it will watch for changes.

Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.

Measuring precision

This library accepts two options that control the precision of the measurements: fontSize and tolerance. These are not required to be set, and you do not need to re-measure the font for every font size you wish to use - all measurements are expressed in multipliers, that you can apply to any font size to get the right offsets for that font size. See the "Using the measurements" section for more details.

Fonts are measured by rendering a number of reference characters on an invisible canvas. The fontSize option is used to determine what size the characters should be rendered at - the larger the fontSize, the more accurate the edge detection will be (leading to a more accurate measurement). In practice, the default font size of 20 is usually sufficient.

The invisible canvas needs to have a certain width and height, large enough to fit the measured characters. You can control the size of this canvas using the tolerance parameter - both the width and the height of the canvas will be fontSize * tolerance pixels large. The default tolerance of 6 (3 units in each direction) should be more than sufficient for most cases, but if you're dealing with very strangely sized fonts, you may want to increase this value.

It's not recommended to reduce the tolerance below the default value of 6, unless you have very stringent performance requirements and have thoroughly tested and verified that your tolerance setting works correctly. Setting the tolerance too low will result in measurements silently failing, yielding incorrect results. Often, the better solution to performance issues is to simply memoize the measurement results.

Using the measurements

All measurements are multipliers, and are relative to the alphabetic baseline. That means that if you have an ascender measurement of -0.75, you would calculate the tallest possible ascender in a string at a 40px font size as follows:

tallestPossibleAscender = measurements.ascender * 40;

This would yield a tallestPossibleAscender of -30 - in other words, the tallest possible ascender reaches up to baselineHeight - 30.

Typically, only the descender is a positive number (since it ends up below the baseline), and all the other measurements are negative numbers (since they end up above the baseline).

Usage

A simple example:

const measureFont = require("measure-font");

let sansSerifMeasurements = measureFont("sans-serif");
console.log(sansSerifMeasurements); // {descender: 0.15, ascender: -0.75, capHeight: -0.7, median: -0.55, topBounding: -0.75}

With a custom precision option:

const measureFont = require("measure-font");

let sansSerifMeasurements = measureFont("sans-serif", {
	fontSize: 40
});

console.log(sansSerifMeasurements); // {descender: 0.15, ascender: -0.75, capHeight: -0.7, median: -0.55, topBounding: -0.75}

API

measureFont(fontName, [options])

Measures the specified font.

  • fontName: The (CSS) name of the font family you wish to measure.
  • options: Optional. See the "Measuring precision" section above for more details.
    • fontSize: The font size (in px) to measure at.
    • tolerance: The size multiplier for the measuring canvas.

Returns an object containing measurements. All measurements are multipliers, relative to the alphabetic baseline.

  • descender: The offset of the lowest descender.
  • ascender: The offset of the highest ascender.
  • capHeight: The offset of the cap height.
  • median: The offset of the mean line (usually equals the x-height).
  • topBounding: The offset of the top bounding line, ie. the tallest a regular character could be (this can extend beyond the highest ascender).

Reference image (from Wikipedia):

Font dimension visualization