Symbian developer community

 
wiki

Programmatically controlling font size in a WRT application

From Symbian Developer Community

Jump to: navigation, search
Recipe
Amount of time required: 15 minutes
Required libraries: N/A
Required header files: N/A
PlatSec Capabilities: N/A
Compatibility: S60 3rd Edition FP2, S60 5th Edition v1.0
Comes with Code: Embedded in this page

Problem: Default font sizes in WRTKit appear very small on hi-resolution devices

Solution: Use em (relative font size) instead of px (pixel based font size) and force font properties inheritance

Discussion: Symbian Web Runtime (WRT) comes with a small JavaScript/CSS toolkit which includes user interface control API necessary to write widgets. If you use Aptana Studio, WRTKit is automatically included in all WRT projects and is stored in the WRTKit/ directory. Note that it is not necessary to use WRTKit - widgets can be written without it.

In both cases however, you may encounter a problem with varying font size on devices with different screen resolutions. Most phones have 320x240 resolution, however newer phones, specifically Series 60 5th Edition phones have high resolution screens. If the widget specifies font size in pixels (using the px unit), this is likely to result in varying text size on different devices. This is especially problematic on touch-screen devices where very small font could render the application unusable.

Original WRTKit style begins as follows:

 
body {
margin: 0px;
background: url("DocumentBackground.png") repeat; /* repeat-x fixed; */
font: normal 12px Arial, sans-serif;
color: rgb(0,0,0);
}
 

Later on, we also find:

 
/* Rules for the list view caption text */
.ListViewCaptionText {
font-size: 18px;
font-weight: bold;
padding: 7px 0px 0px 11px;
}
 


First impulse is to use different units to compensate for different dot pitch on different screens. For example, millimeters can be specified in CSS using mm unit and the browser should auto-adjust font for device DPI. However, if we were to adjust font size programmatically, we would have to modify the font-size property on relevant DOM elements. This is ok in the unlikely case that the application only uses single font size, however if we have a variety of font sizes in a widget, program would need to find and update all DOM elements accordingly.

Specifying font size in mm for the above UI.css segment could look like this:

 
body {
margin: 0px;
background: url("DocumentBackground.png") repeat; /* repeat-x fixed; */
font: normal 4mm Arial, sans-serif;
color: rgb(0,0,0);
}
 
. . .
 
/* Rules for the list view caption text */
.ListViewCaptionText {
font-size: 6mm;
font-weight: bold;
padding: 7px 0px 0px 11px;
}
 

Here is an interesting problem. By any logic, font sizes should be inherited from parent DOM elements. In other words, specifying body font size should apply to all elements in the document - as long as font-size property is not specifically overriden. However, this is not the case. For example, table cells do not inherit font size from the body element by default.

Fortunately, there is a way to overcome this - by forcing inheritance for the relevant properties:

 
/* Fix for font size inheritance */
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,
blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl,
dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td {
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
}
 

This helps a lot!

Still, our functions for programmatically changing font size would still need to change the body DOM element and all DOM elements with ListViewCaptionText style in order to change font size consistently. Keep reading...

Alternative way of specifying font size is using em unit. This allows specifying font size relative to parent element. In our case, we can specify the body element's font size in absolute terms (e.g. 14px) but then specify all other font sizes in the stylesheet in relative terms. Our CSS would now look like this:

 
/* Fix for font size inheritance */
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,
blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl,
dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td {
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
}
 
body {
margin: 0px;
background: url("DocumentBackground.png") repeat; /* repeat-x fixed; */
font: normal 4mm Arial, sans-serif;
color: rgb(0,0,0);
}
 
. . .
 
/* Rules for the list view caption text */
.ListViewCaptionText {
font-size: 1.2em;
font-weight: bold;
padding: 7px 0px 0px 11px;
}
 

DOM elements with ListViewCaptionText style will now be shown with 1.2 times larger text. Also, changing font size in the whole widget can be done by just changing the fontSize property of the body DOM element. Here is the code to do just that:

 
 
var currentFontSize = 4; /* should be the same as in CSS */
 
 
function initFontSize(){
// first check if there is a preference present
if (window.widget) {
var saved = widget.preferenceForKey("fontsize");
if ( widget.preferenceForKey("fontsize") ) {
setCssBodyFontSize(parseInt(saved));
}
}
}
 
 
function increaseFontSize(){
setCssBodyFontSize(currentFontSize + 1);
}
 
function decreaseFontSize(){
if (currentFontSize > 1) {
setCssBodyFontSize(currentFontSize - 1);
}
}
 
function setCssBodyFontSize(size) {
currentFontSize = size;
var sizestring = "" + size;
document.body.style.fontSize = sizestring + "mm";
if (window.widget) {
widget.setPreferenceForKey(sizestring, "fontsize");
}
}
 

The code above will also store the last setting so that the next time widget runs, the previous setting is persisted. Finally, you must add the following call as the last statement in your widget's init function:

 
...
 
function init() {
 
...
 
initFontSize();
}
 
...
 

Comments

Sign in to comment…