digitalbiblesociety / browserbible-3

Bible software that runs in the browser
MIT License
189 stars 76 forks source link

Using Google API Font for Text and Interface #53

Open sbbic opened 9 years ago

sbbic commented 9 years ago

For some languages (like Khmer) many devises do not have access to a font that correctly displays Khmer. So we need to use embedded fonts. Google fonts actually has many Khmer fonts, and so it's a great way to make things look nice.

I can get Bible text to take a font from the Google api, but for some reason on Android and iOS it doesn't use the font (I've even added the font to the mobile.css). Any ideas how to do this?

Here's what I've modified that doesn't currently work on Android or iOS:

mobile.css added code: /* khmer */ @font-face { font-family: 'Content'; font-style: normal; font-weight: 400; src: local('Content'), url(http://fonts.gstatic.com/s/content/v8/NqGGtwtsM97PsXgEIdi-RvY6323mHUZFJMgTvxaG2iE.woff2) format('woff2'); unicode-range: U+1780-17B3, U+17B6-17DB, U+17E0-17E9, U+200B-200C, U+25CC; } [lang=khm], [lang=km], .section[lang=km] .p, .section[lang=khm] .p, .chapter[lang=km] .p, .chapter[lang=khm] .p { font-family: Content!important; line-height: 2; }

fonts.css added code:

/* khmer */ @font-face { font-family: 'Content'; font-style: normal; font-weight: 400; src: local('Content'), url(http://fonts.gstatic.com/s/content/v8/NqGGtwtsM97PsXgEIdi-RvY6323mHUZFJMgTvxaG2iE.woff2) format('woff2'); unicode-range: U+1780-17B3, U+17B6-17DB, U+17E0-17E9, U+200B-200C, U+25CC; }

bible.css added code: body:not(.config-font-family-Libertine) [lang=km], body:not(.config-font-family-Libertine) .section[lang=km] .p, body:not(.config-font-family-Libertine) .chapter[lang=km] .p { font-family: Content, KhmerOS!important; }

It would also be nice to be able to switch the font based on the "Settings" language. So when Khmer is set, a Khmer font is used.

alerque commented 9 years ago

This is actually a really sticky problem. I've been puzzling about the best way to approach it ever since I went through and added the Libertine font option. In doing so I kind of stirred up a wasp's nest of issues that we never really bedded down (that's where the dirty :not() css hack originated).

There are a couple of different kinds of font issues. It's going to be really tricky to make them all fall into line under one interface with a single option. I think the only way to make the resulting UI sane is to have some complicated logic under the hood that will take some extra work on the part of an administrator to setup.

My preferred solution of defaulting to a specialty font that has good support for alternate alphabet and consistent, decent styling across them all works great. For my purposes (Turkish, English, Greek, Hebrew). It has one major drawback in that it is dependent on loading a set of (heavy) font resource files. This upfront delay is a cost I'm willing to pay but is less than ideal for other people's usage. It also hits a wall when the custom general purpose font you pick is missing support for some odd-ball language.

The conflicting needs of preferences vs. needs vs. available options leaves a pretty intricate mess. I propose a hybrid system that unravels the intricacy from a couple different ends. This will be more complicated to setup, but hopefully keep the UI as uncluttered as possible. The app is already well down this road with the latest changes moving font settings into the config options, but here is how I would see the whole thing working together:

  1. The UI font selector should focus on the "preference" aspect. This means not giving end users and exact choice of font for everything, but grouping them into logical ascetic groups. These groups would be something like (generic sans, generic serif, advanced serif 1, alternative 2). Obviously the names are not that important, and some languages don't have the same logical serif/sans-serif breakdown but they often do have some sort of class breakdown that could be substituted.
  2. These selections would not be for specific fonts, but for groupings. Each grouping would have a similar set of ascetic goals and the options in it should cover a similar scope as far as supported languages and technologies. An attempt to load local fonts can always be made in each group definition, but some of them could be arranged in a way that it would fall through to alternative local fonts while other groups would fall through to webfonts. Over time with various contributors balancing various factors a number of groups might be available in the source.
  3. A wide selection of font definitions would be available, as each group could potentially have several fonts included. These font definitions would include a meta data file with a matrix of what languages they have usable support for. Adding a new font definition would not only require the @font-face block for CSS but a list of what languages it would be sane to use the font for.
  4. The site config would define a selection of the available fonts to be in each grouping and which group to start with by default. This would have sane defaults of course, but it is also the main point of the setup that would need be adjustable by site administrator to offer what they considered to be the best experiences. For example the out-of-box config might default to a large group of common system serif fonts, but I would switch my groups around so that the default group was something with more advanced typography and a touch of style.
  5. The default interface language would be set as currently, but an additional default interface language would be set as well. The out of the box config might be a group that included a fallback chain of possible system sans-serif fonts. An administrator for an East Asian focused site might switch this to whatever group has better readability for their language.
  6. Each language resource file would also include the name of a font group that is KNOWN to support it. This is likely to be the same font group chosen as the interface font by the administrator of a site in that language. Somebody coming along to support a new language would possible submit a couple font definitions and a new group along with their language translation.

Now comes the application logic.

This adds a bit of extra backend setup over what we have now, but I think it would cover most eventualities including allowing generic system fonts in the default install while still allowing them to view any language in the text database (i.e. fallback to webfonts for most Western systems looking at not-Western texts) while at the same time allowing administrators to setup an install that worked better for their language and ascetic choices. In the end it adds zero new complexity to the existing UI.

Most of the coding would be in logic to assign a class to each column rather than in the dirty css fallback system we have now to work around the English/Greek/Hebrew mix problem affecting some fonts but not others. The other extra bit would be meta-data for each of the parts, but those parts would be easily sharable and lots of different arrangements could be in the repository making it a straight forward matter of picking some groups for an install.

sungkhum commented 9 years ago

So still a ways to go ;) This might prove helpful: http://24ways.org/2011/creating-custom-font-stacks-with-unicode-range/ A way to simplify things a bit - though Firefox still doesn't support unicode range.

johndyer commented 9 years ago

Yes, I'd love to clean this up and remove :not() CSS from the main code and keep things simply but customizable by the admin. I'm open to consider pull requests.

alerque commented 9 years ago

I may try to hack on this eventually, but it's not going to be right away. In the mean time if anybody else tinkers with it please drop a message in this issue so we can collaborate (or at least not duplicate effort).

sungkhum commented 8 years ago

Been a few years so I thought I would comment again :) I really believe this issue is important, in that there aren't any other Bible apps that allow the user to choose a font that renders their own language beautifully (they are stuck with ugly default system fonts that at times don't even render correctly, like the Mac font for Khmer). I think if there could be a variable thrown when a certain Bible is selected (like a Khmer Bible) to use a Khmer webfont it would be a great addition and extremely valuable to many around the world (not just for Khmer). I realize I am not committing any code, so just asking, but just wanted to put my vote in for this issue again. Thank you!

alerque commented 8 years ago

I don't know where this was (another issue) but at some point I opposed the use of sourcing Google Fonts in this app because Google IP ranges frequently end up on country-wide block lists. Also it's a huge bonus that the current arrangement allows configuring the app to be used completely offline.

That's not to say that we should throw Khmer under the bus, just that the connectivity factor should be considered in whatever solution we come up with.

Thanks to @sungkhum for poking this issue. What font, specifically, would you recommend for Khmer? What typeface makes for a good solid Bible reading experience with good readability and few surprises? Obviously at OFL font would be preferable. I think something that does not have other alphabets built in would actually be better for our purposes. Some fonts bill themselves for easy mix and match with western alphabets, but I suspect it will be more flexible to add language specific problems like this to a font fallback stack, so we don't want it covering character sets that should be covered by the UI default(s).

Also, what do we know about other languages with issues like this? How has the Unfolding Word project handled this in their fork?

sungkhum commented 8 years ago

@alerque That makes sense.

Actually, even if there was a preference added where the user could enter the name of a local font to be used for the text, that also would work (and work for other languages). I can't speak for the default fonts of other languages being that I am not in a position to judge, but I do know it happens (https://bugzilla.mozilla.org/show_bug.cgi?id=84668 https://bugs.chromium.org/p/chromium/issues/detail?id=568030 ) Here's what the default looks like (ugly): bad-khmer

And a nicer font (like Content for Khmer): khmer-nice

The Google font is small, and only contains Khmer characters. I actually made my own with some better punctuation glyphs here: http://reader.cambodianchristianresources.com/true-discipleship/fonts/content-web-v2.woff

Actually changing the font opened up another bug in the Khmer text - non-breaking spaces have been used instead of zero-width spaces. Khmer doesn't have spaces between words like English, but every so often there is a real space. The zero-width spaces are used for line-breaking and so computers can know where a word ends. But I'll open another request for that one.