November 30, 2010

Nook: Font Management and Troubleshooting

The Nook ebook reader allows by default to choose amongst 3 different font families, when reading epub documents:
This is done quite simply using the menu system of reader application, through the touch screen.
But probably it happened to you that on some epub document it is not possible to change the displayed font family; often, in these cases you cannot change the font size, too.
Why this happens? Almost surely, the cause is a bad realized epub document.
If you are curious, you can just have a look at your epub document "inside". Simply, change the extension of the document from epub to zip. Now double-click on it and you see the component of your file. Basically, you will find (almost always):
  • some files containing: document meta-data; table of contents structure; and other needed stuff;
  • xhtml files: these files are the main content of your document; they really are html document, and in fact you could open them with any web browser;
  • image files (could be on png, jpg or gif format): any image contained into the document;
  • css files: the style sheets containing all the information to correctly format the content of xhtml files.
One of the information usually contained into CSS files is the font that is to be used to render the content of the (x)html files. This is normally done applying a CSS similar to this:
  font-family: Georgia, Garamond, serif, sansserif, monospace;
  text-align: justify;
  font-size: 1.00em;
In the first part of this snippet, we ask the browser (in our case, the epub Reader application) to render the entire body of our web page (document chapter), unless otherwise specified, using as font "Georgia"; as second choice (in case font "Georgia" is not available on our environment) font "Garamond" is to be used. In case it is not possible to use this font, too, then there is a sort of fall-back mechanism. In fact, we ask the browser to use, in order of preference: any font of type "serif" (for instance: Times New Roman); any font of type "sans-serif" (for instance: Verdana); as last choice, any font of type "monospace" (for instance: Courier).
In the second part of the snippet, you can see that there are the setting to render a generic paragraph element <p>: here, there is no override of the above mentioned font-family declaration for element <body>: therefore that also applies to every <p> element.
There is still a missing link for browser to correctly render a font: how could a browser know what we mean by "Georgia", "Garamond" or any other font? how could it know that "Georgia" is of type serif, "Verdana" is of type sans-serif and so on? Actually, there is a specific CSS property just to do that:
@font-face {
  font-family: Georgia, serif;
  font-style: normal;
  font-weight: normal;
  src: url("Georgia-roman.ttf")
@font-face {
  font-family: Georgia, serif;
  font-style: italic, oblique;
  font-weight: normal;
  src: url("Georgia-italic.ttf")
@font-face {
  font-family: Georgia, serif;
  font-style: normal;
  font-weight: bold;
  src: url("Georgia-bold.ttf")
It's not difficult to understand how the above code snippet works. It defines the font called "Georgia" (and declare it is a font of type serif), respectively in the style plain, italic and bold; and tell the browser what is the location of the True Font files to be used to render the font.
Now the puzzle is complete: for each html element, the browser knows what is the font to be used; and for each font, he knows what is the True Font file to be used to render it.
In our context, the browser is the epubReader application. The html page is any of the xhtml file embedded into the epub document. Normally, the first of the above code snippets is contained into one of the CSS files embedded into the epub document.
And normally, there is no need to include any @font-face directive into the epub document, leaving this duty in charge of the Reader application (that will dinamically append a CSS with the needed @font-face directives to the xhtml file to render).
You should now guess how the font change is possible for Reader application: when we choose one of the 3 font in touch screen display, the reader application simply changes the content of CSS file that contains the @font-face directives, so that they use the wanted TTF (or OTF) file.

So we can come back to the original question: why for some epub documents the font changing does not work?
In most cases, this is due to two possible causes:
  1. the CSS embedded into epub contains some @font-face declarations (and of course, the epub also contains the corresponding font files), and they override the ones contained in the CSS appended by Reader application; this could be a desired feature provided by the epub designer, for various reasons (aesthetic, compatibility, and so on);
  2. the CSS appended by Reader application, that define the font (@font-face) selected by user, do not define (for obvious reasons) specific font family names, but just font types (serif, sans-serif): if the font-family directives included into epub just contains exact font name ("Georgia") but does not provide any feedback to generic font types, the html rendering engine of the Reader application will obviously not be able to associate the required font name to its font type. It is a common (and good!) practice to provide always some fall-back when declaring a font family into the CSS (like is done in the first snippet, where both serif, sans-serif and monospace are mentioned).
In both cases, the only solution to allow font-changing feature involves editing the epub document; depending to how the epub has been realized, this could be either an easy or a rather complicated task.
Some hints about it will be provided in next posts.