benji shine

View Original

Semi-Transparent Text in Open Laszlo

Due to a limitation in the Flash player, device text can only be visible or invisible; any non-zero opacity values for text will be drawn as opacity=1. "Device text" means text drawn by the Flash player using the client operating system's underlying font technology. Device text is inexpensive both in runtime cost and download cost; it uses the font already present on the client machine, so no font description needs to be downloaded. However, device fonts are handled slightly differently on different operating systems; the font dimensions may not be the same across runtimes, and some OS's may not even have fonts you expect. (Notably, most linux machines lack Verdana.)

Embedded fonts are more flexible, but they cost more, in runtime and download size. The OpenLaszlo platform ships with several TrueType fonts, which can be found in lps/fonts. Specify a font for embedding by using the font tag:
<font name="timmons" src="timmonstb.ttf" />
This includes the timmons TrueType font in the swf built from your lzx code. If you're counting bytes (and you should be) just that one font adds 58624 of 'em to your download. Ouch. If you're design-focused, embedded fonts are worth it for two reasons: one, you can be sure they will look the same on every flash runtime, and two, they can be rendered semi-opaque.

There are two workarounds, both of which increase the download size:


  • Turn the text into an image; render it as an image with dynamic opacity. This is a huge pain to maintain.

  • Use embedded fonts.

The difference between embedded and device fonts has been bothering me for a while, so I put together a little example. It constrains the opacity of various text objects to the value of a slider.

Here's the app:


Here's the code:



<canvas width="600" >
<font name="Arioso" src="ariosor.ttf">
</font>
<font name="timmons" src="timmonsb.ttf"/>

<view name="inset" x="20" y="20">
<simplelayout axis="y" spacing="10" />

<view name="controls" layout="axis:y; spacing:30" width="100%" height="140" >
<text multiline="true" x="10" width="${parent.width-20}" >
This slider controls the opacity of each of the text objects below, as
well as the right half of the rectangle at the bottom of the canvas.
Opacity varies from 0 (slider=0) to 1 (slider=100).
The text using embedded fonts (timmons and arioso) can have fractional
opacity; the text using device fonts can only be visible or invisible.
</text>
<slider id="gSlider" minvalue="0" maxvalue="100" value="50" x="10" width="${parent.width-20}" />
</view>

<view height="130">
<simplelayout axis="y" spacing="10" />
<text id="gText" height="24" font="timmons" fontsize="18" opacity="${gSlider.value/100}">
some text in timmons (an embedded font)
</text>

<text height="24" font="Arioso" fontsize="18" opacity="${gSlider.value/100}">
some text in arioso (an embedded font)
</text>

<text height="24" font="Verdana" fontsize="18" opacity="${gSlider.value/100}">
some text in verdana (a device font)
</text>

<text height="24" font="Sans" fontsize="18" opacity="${gSlider.value/100}">
some text in Sans (a device font)
</text>
</view>

<view width="200" height="100" layout="axis:x">
<view bgcolor="black" width="100" height="100" opacity="1" />
<view bgcolor="black" width="100" height="100" opacity="${gSlider.value/100}" />
</view>

</view>