Entries tagged ‘sIFR 3’

Heads up: Stockholm soon, London next

posted February 24th, 2009, no comments, tagged ,

Life’s quite lovely here in Copenhagen. Last week was filled with gentle snow, mostly enjoyed from behind my office window. It all vanished on Sunday, however, and I strangely miss it

Therefore, albeit not quite, I’m headed up to Stockholm on Thursday to give two talks at Geek Meet. One on Web Typography and sIFR, and one on Homemade Ubicomp. An older version of that talk – which I gave at SHiFT ’08 – is available at Supercollider.

I’ll be in Stockholm until Sunday, so if you want to hang out, ping me. I think Robert Nyman is doing a guided tour through Stockholm on Saturday, so if you don’t know the town either (or think that Robert doesn’t!) perhaps you should join us.

I won’t be back in Copenhagen for long, because I’ll be in London for business for a week and a half from Wednesday on. That means I’ll be there during the weekend as well, anything interesting going on then?

P.S. Regarding sIFR, there’s a lot of interesting things happening with web typography and web typography alternatives. I’ll be speaking about that in Stockholm, and can hopefully do a post on it here afterwards. As you may have noticed, nothing really has happened on sIFR since October. I’m thinking of moving the project onto GitHub, LightHouse and Stack Overflow so more people can be involved. (This, by itself, is too slow a process already, which is why I’m hiding this in a footnote.) Let me know if you’re interested in helping out.

P.P.S. The real me on Twitter is here, if you’re into that kind of thing.

P.P.P.S. Christian Heilmann diggs my favicon. All credit to Nadya Peek.

sIFR 3 without Flash Pro

posted November 7th, 2008, 17 comments, tagged

There are currently two tools available which generate sIFR 3 movies for you, meaning you don’t have to use the Flash IDE to export them yourself. First there’s sIFR Generator, run by Richard Odekerken, which lets you upload a TTF file which is then turned into a sIFR movie. sIFR Generator currently generates movies compatible with r419, so it’s not useful if you want to use the latest sIFR 3 release. Which, of course, you should.

Update, November 25th: sIFR Generator now supports r436.

Also of importance are the legal issues surrounding the uploading of TTF files to a third-party server. Richard writes:

This is a Software-as-a-Service tool. Using this software requires you to upload font files to our website. By uploading the fonts you grant us permission to use the font, on your behalf, to create a sIFR SWF file that contains the font, and make it available to you.

All intellectual property rights and copyrights that apply to the original font, also apply to the generated font file. This file is made available only to the party who uploaded the font file.

We do keep fonts uploaded to sIFRGenerator.com for debug and statistical purposes.

Also available is sIFR Font Maker by CoffeeCup Software. This is a free, open source tool that runs under Windows. It too generates r419-compatible movies, but unlike sIFR Generator there is no notice of this fact. This, along with the lack of direct links to sIFR 3 pages is something CoffeeCup should fix. That said, it does run locally, so that’s a plus over sIFR Generator in terms of uploading TTF files.

I’ve seen a few reports of links not working properly in movies created via sIFR Generator. It wouldn’t surprise me if this issue is present in sIFR Font Maker as well, since they’re quite likely to use the same underlying software. But, if you need to create a font file, and don’t have access to the Flash IDE, and are okay with using r419, these tools are for you.

Over the past few days I’ve been making some improvements to sIFR 3, resulting in r436. A quick overview of the important changes since r372:

  • Now supporting Opera! Playing it safe with Opera 9.61, but there is not much reason to be using older versions.
  • sIFR.prefetch() has been merged with sIFR.activate().
  • sIFR.callbacks() has been renamed to sIFR.replacements.
  • Now using ExternalInterface for Flash – JavaScript communication.
  • Improved whitespace filtering before passing on the content HTML to Flash.
  • Improved CSS Load detection, which is disabled by default, but helps in making sIFR replace elements faster in Safari and Opera.
  • Changed how browser and Flash versions are stored in the sIFR.ua object. Please consult the changelog for r408 for full details.
  • Imitating SWFObject behaviour for inserting Flash movies.

Changes since r419 (which saw close to 12.000 downloads):

  • Made some improvements to decrease the jumpiness on the page caused by the replacements.
  • Dramatically simplified font size calculation, making it more accurate in Internet Explorer, and removing potential issues with IE 8. This also removes the need for specifying line-height: 1em for the elements being replaced.
  • Fixed 2 pixel cut-off from the leading property (caused by Flash).
  • Fixed ratio calculation when leading is specified. The leading is now removed before doing any ratio calculations.
  • Enabled Flash transparency on Linux with Flash 10, Gecko 1.9 and Opera.
  • Font size of nested HTML elements can now be configured in pixels.
  • Merged sIFR-screen.css and sIFR-print.css into sifr.css, using the @media attribute to distinguish the media types.

There’s still a number of issues left to figure out, although so far I haven’t had any reports of these issues impacting users. For example, I still have questions about how browsers handle Flash movies that are outside of the viewport, I’d like to see if CSS Load detection could be improved, and what’s up with cross-domain Flash movies. These issues all need extensive research and browser testing.

As always, you can get the latest release from the nightlies.

Other useful links:

These past few months have seen some interesting new developments. Most important of course is the support for Font Linking in Safari 3.1, as well as the upcoming Firefox 3.1 and Opera 10. Finally it’s becoming possible to embed existing fonts on websites, without going through hacks like sIFR or image generation. That said, the current problem with Font Linking is the required redistribution of original font files to web browsers, forbidden by many font licenses. This leaves many typefaces unavailable for embedding. Furthermore, Chris Wilson of Microsoft expressed that Microsoft (and, by proxy, Internet Explorer) should not support Font Linking in it’s current form. Microsoft does have its own EOT format, which it has proposed to the W3C for standardization, and would solve these issues. Mozilla, Apple and Opera however seem opposed to it, mostly out of fears for DRM. I believe these fears are unfounded, for if EOT is DRM, it’s DRM applied by the licensee, not the licensor. It’s like getting an MP3 from Apple and putting DRM on it before you pass it to a friend, instead of getting DRM from Apple preventing you from passing it to a friend. If we want cross-browser, legal font embedding in the short term, EOT is the way to go.

While we wait for cross-browser font embedding, we’re stuck with the alternative hacks. Some new ones have come up recently. FaceLift now seems to be the best way to use images rather than Flash for displaying the font. It uses server-side image generation through PHP, and cleverly provides a hosted service. In the past week Typeface.js came out, which is a devilishly smart way of actually rendering a typeface using <canvas> or VML, though given the complexity of that problem, Typeface.js probably isn’t ready yet for prime-time.

I’d like to point out that these solutions shouldn’t be seen as much as alternative to sIFR – no matter how eager they are to market themselves as such – but as alternative solutions for the real problem: reliable cross-browser font embedding. We’re merely trying to provide the best hack-that-shouldn’t-be-necessary.

That said, I do think that sIFR 3 provides a better solution in being completely client-side, providing actual selectable text, and supporting a subset of HTML and CSS rendering.

I’ve done a few sIFR presentations and workshops in the past few months, most recently at the <head> web conference. Slides are on Slideshare, however the footnotes have gotten lost in an JSON encoding mishap on their end. Therefore, I’ve put up a PDF with notes (17.3 MB). I’m speaking at DrupalCamp CPH, which takes place November 15th and 16th here in Copenhagen.

If you’re interested in a sIFR workshop at your company, or are looking for a weathered web hacker, please get in touch via Supercollider, my freelance alter-ego.

Now, go try out r436, and report back your findings!

Web Fonts, Licensing and EOT

posted July 24th, 2008, 17 comments, tagged ,

Over on the IEBlog, Bill Hill recently posted about Font Embedding on the Web. In it, he discusses how Microsoft has submitted it’s Embedded OpenType (EOT) file format to the W3C for standardization. This could be an important development for web typography, and here’s why.

Web fonts as currently implemented by Safari 3.1, and supposedly supported in Firefox 3.1 and Opera 10, work by linking to the original TrueType Font or OpenType Font files on a web server. For all intents and purposes, this comes down to distributing a font file. In the case of commercial fonts, this is most likely a violation of the license agreement for the font, which means that you, as a web designer, will get your ass sued.

EOT, however, was designed to enable you to use TrueType or OpenType fonts on the web, without getting your ass sued. Quoting from the W3C submission:

Most commercial fonts have an end user license agreement (EULA) which specifies the rights a person who has purchased a license to use the font may enjoy. As the right to freely distribute the font to others is not normally granted, being restricted to installing within a limited set of parameters, there exists a need for a mechanism to allow people who have licensed the font for use with their documents a way to also use the font for their web content without violating the EULA agreement which they have accepted. The EOT file format was developed by Microsoft in cooperation with font creators for just that reason. The technology has been accepted for use by font makers for over 10 years.

EOT respects the flags in font files regarding embedding and can be limited to domains or full URLs. Another important feature is that it is able to compress the font data and lets you pick the glyphs you want to use – resulting in much smaller files than directly linked TrueType or OpenType fonts.

I believe this is a good, practical solution for having real web typography, which performs well and doesn’t violate font licenses. Some steps still need to be taken, obviously. First of which is cross-browser support for the EOT format, which should be in reach if EOT is accepted by the W3C. Another problem with EOT currently is that the software to generate EOT files is specific to Windows. However, given open formats, that’s a problem that can be overcome as well.

As, apparently, with every Microsoft announcement, there’s plenty of Microsoft bashing being done. Most of the bashing revolves around Microsoft pushing another proprietary format, people not being willing to respect licenses on typefaces, and a feeling that commercial fonts aren’t worth using anyway. I’ll let Chris Wilson reply to this:

As I also stated to the WG – I don’t personally even care that much if that system is EOT as it is today; I’d be okay with building a new system if the details of EOT were a sticking point. But I want to use commercial fonts on my web pages, I want that to work interoperably across browsers, and I want to not have to violate my license for the fonts I use (and get sued for it) in order to make that happen. A solution that only works for freeware fonts is not a solution.

Koebenhavn

posted June 29th, 2008, 8 comments, tagged ,

So, I’m in Copenhagen now. It’s been a long while since my last post here, and people have been asking me to update more frequently – especially now that I’m an expat! Luckily I set the bar quite low, so no problem there ;-)

I got here last Tuesday, courtesy of Ton Zijlstra and Elmine Wijnia (thanks!). I’m in a temporary place, until August, so in desperate need of slightly more permanent housing. Going to check out two apartments on Thursday, hopefully that works out.

This past week was spent on Reboot, which again was pretty awesome. Spoke a lot of Danes, who were extremely kind – thanks for making me feel welcome! Next week I’m going to be at Roskilde. If there’d be a Danish integration course for foreign geeks, I’d have passed by now!

On a somewhat more professional level, I’m still figuring out what to do. I’d like to stay flexible though, so freelancing seems like the obvious answer. Consider this my Mark is on the market announcement. Read what I wrote about myself back in February. One of the things I’d like to do is finish sIFR – and given the cost of living in Copenhagen, it’d be great if I could find a (few) sponsors to enable me to do that. If possible, Danish sponsors, since I do need a residence permit in order to stay here. If you’re interested, get in touch.

Besides finishing sIFR, I want to finally write server-side code again. I’ve got some pretty neat ideas for this website, as well as a dedicated sIFR website. More on that later. A new site should also stimulate me to write more, which I really need to do – too many great (or I’d like to think so) ideas go to waste cause I don’t write about them.

In other news, I’ll be in the Netherlands end of August / early September. Then Brighton for dConstruct. I’ll be in Amsterdam around PICNIC to work on RFID stuff with Mediamatic. And, of course, I’ll be in Lisbon for SHIFT in October, followed a week later by Singularity, where I’ll give a presentation about web typography and sIFR. That’s probably in Copenhagen.

I’m going to see where life takes me, and where I can take life. Mark out ;-)

For the Dutchies reading this, Friday the 29th the Internetcreatieven Kennisdag mini-conference takes place in Delft. Speakers are André Weenink, who’ll be talking about design research in branding, Arjan Westerdiep, who’ll be premiering a pixel-art illustration consisting of no less than 1,664,000 pixels, Gert Hans Berghuis of Fabrique Communicatie & Design, and Bob Corporaal and yours truly. We’ll be speaking about happy marriages between Flash and HTML, with of course sIFR being a prime example.

Registration is only € 23,80, so I hope to see you there!

sIFR 3: r372 Zoom Away!

posted January 26th, 2008, 55 comments, tagged

A quick update with regards to the beta. A number of issues have been found concerning page zoom and Firefox. These issues should all be fixed now. Other changes include:

  • Several bugfixes regarding forceSingleLine.
  • The XHTML demo was not built properly by the build script.
  • Added support for .sIFR-root { cursor: pointer; }.
  • Print preview in Firefox/Windows no longer throws errors.
  • The fixFocus caused infinite recursion, but no more!
  • sIFR should no longer cause the page to “jump” when the window is resized, although the sIFR elements may flicker a bit.
  • Text replaced through replaceText is now remembered after moving back to the page through browser history in Firefox.

You can get r372 from the nightlies.

Useful links:

sIFR 3 Beta 2: Fire Cracker

posted December 31st, 2007, 75 comments, tagged

As years end nears, neighbourhood kids are playing with fireworks around the house. A nice homage to the second beta of sIFR 3 I’d like to imagine. Feature wise sIFR 3 is now complete, and I think it’s gotten pretty awesome. If you’re trying to decide between sIFR 2 and sIFR 3, sIFR 3 is definitely the better choice.

What is sIFR?

sIFR is meant to replace short passages of plain browser text with text rendered in your typeface of choice, regardless of whether or not your users have that font installed on their systems. It accomplishes this by using a combination of JavaScript, CSS, and Flash, which renders the font. It degrades gracefully if Flash is not present. sIFR 3 is open source and licensed under the CC-GNU LGPL.

What’s new?

Here are the major changes since the last beta:

  • The Flash movie and the JavaScript must be of the same version.
  • Added ratios, which make the loading of the Flash movies less jumpy.
  • sIFR does not work when opened straight from the local filesystem. You must load sIFR from a web server.
  • sIFR movies no longer steal user input focus.
  • When the Flash movie is opened directly, it shows its revision in a bold, italic and normal font.
  • The Flash movie insertion code is equivalent to SWFObject 2.

  • sIFR now supports window resizing.

  • Page zoom in Firefox 3 and IE7 is supported!
  • A workaround has been added for transparent or opaque Flash movies in Firefox/Windows, whose ancestor is floated.
  • A workaround has been added for the loss of Flash variables in Internet Explorer if the innerHTML of an ancestor of a Flash movie is changed.
  • Hover effects tend to get stuck in Flash, added a workaround.
  • Added a custom context menu for links when the hover effect is used.
  • In Internet Explorer, the sIFR Flash movies are hidden when the page unloads. This works around rendering glitches where the old and new movies are briefly shown at the same time.

  • You can specify the font size in pixels, directly from sIFR.replace().

  • You can specify different font sizes within the Flash movie, and they will be relative to the main font size if you specify them with a percentage unit.
  • Added support for bitmap fonts, by rounding the font size to the nearest power-of-eight value.
  • You can now force the text to be displayed on one line.
  • You can disable the pointer cursor (the ‘hand’) inside sIFR.
  • Multiple fonts are supported.

  • You can replace the text inside the sIFR Flash movie.

  • You can change some of the CSS that was applied to the Flash movie.
  • You can get mouse events from the Flash movie.
  • You can tell sIFR to check if the CSS has been applied to the document. This will speed up initialization in Safari and Opera.

  • Opera and Konqueror support has been disabled, because these browsers do not support communication between JavaScript and Flash code.

And there have been many, many more minor improvements. Really, this version rocks!

How Do I Get It?

You can check out a demo of sIFR 3, or simply the most recent version of sIFR 3 from the nightlies. (Note: there are newer versions available than beta 2.) If you want, you can subscribe to a feed for the nigthly releases. Major releases are also announced through the sIFR 3 Announce mailing list.

How Can I Help Out?

First of all, it’s very important to test sIFR in as many scenarios as possible. The easiest way to help out is just to install sIFR on your web site and report any bugs you may find. You can also join the forum or the sIFR 3 Development mailing list. These are also the places to report bugs. Documentation on the wiki could use a lot of improvement. And, of course, a donation is much appreciated.

Support?

Documentation (although, to be honest, it’s not fantastic) can be found on the wiki. The best place to go for support is the forum or the sIFR 3 Development. Please do not post support questions in response to this blog post.

Concluding

I’d like to extend many, many thanks to everybody who filed bug reports, helped testing, responded on the mailing list, improved documentation, spread the word and made a donation. With the year 2008 on the horizon, let’s make it the year of sIFR 3!

(P.S. If you’re curious about sIFR, I’d be more than happy to come give a presentation at your organization!)

Firefox 3, or, technically, Gecko 1.9, comes with support for full page zoom. It works by scaling CSS pixels when the page is rendered – from the perspective of JavaScript or CSS there is no difference between a page zoomed to 200%, 50% or 100%.

I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case.

The problem with this solution is that it does not detect the zoom level when the page is first loaded.

Another solution I found relies on Flash. Not so much a problem for sIFR, for which I started this little investigation, but not the best solution either. Flash can be configured not to scale with its container page by setting Stage.scaleMode = "noscale";. The Stage.height value gives the height of the Flash movie as its actually rendered by the browser. In other words, this value is not affected by page zoom. The height assigned to the Flash movie <object>, as it exists in the DOM, however, is affected by the zoom level. Simply dividing Stage.height by <object>.height gives the zoom level, even on page load. See test case.

Of course, these two methods are hacks. It would be great if the browser can be queried for the zoom level.

Addendum: I just tested both approaches in Opera and IE 7. The percentages trick works in Opera, but not in IE. IE’s page zoom is quite a hack anyway, so that’s to be expected. The Flash solution works in all browsers, and is far more precise than the percentages approach. Definitely the way forward I’d say!

On DOM Load (and CSS, too)

posted December 6th, 2007, 3 comments, tagged ,

The discussion on document load detection is more than two years old. The accepted solution for IE looks pretty much like this:

document.write('<scr'+'ipt defer src="//:" '
  + 'onreadystatechange="if(this.readyState==\'complete\'){dojo._loadInit();}">'
  + '</scr'+'ipt>'

(As you can see I took this from Dojo)

Unfortunately this solution is broken. It relies on the defer attribute, which causes the script to change its readyState to complete after the document has finished loading. defer, however, doesn’t always work correctly. If the innerHTML of a descendant of the body element is changed by an inline script, the script may not be deferred properly. This bug cannot always be reproduced – I’ve seen it occur only a few times while others report it happening on every second page load. However, I did find a way to force its appearance. The bug can be triggered by alert()ing right after changing the innerHTML. See also a test case.

So, without the defer trick, what else can we use to detect DOM load in IE? Diego Perini found a pretty cool solution. If you call document.documentElement.doScroll('left'); before the document has loaded, an exception is thrown. Call it every couple of milliseconds until there’s no exception, and you know the document is ready. Diego has also done a superb job of testing his solution, ensuring that it works as expected.

With IE covered, let’s have a look at document load in other browsers. Mozilla 0.9.4 introduced a DOMContentLoaded event for the document object. Opera 9 also supports this event. Since about two months WebKit supports it as well, but only in the nightly builds. Konqueror is in the same situation, and will support it starting with version 4.0. For WebKit and Konqueror, which do not yet support the DOMContentLoaded event, you can poll the readyState of the document, as explained by Dean Edwards.

We can say that document load is covered (again). However, it isn’t sufficient if your script relies on the CSS being applied. Opera, WebKit and Konqueror load CSS and JavaScript in parallel (all CSS is loaded before being applied, however). This means that the document may have finished loading, and your JavaScript may have executed, before the CSS is fully loaded and applied. sIFR relies on CSS, which means that document load may be too early. Preferably there’d be a CSSApplied event, but in lieu of that, we can detect CSS application ourselves.

The trick is to insert an empty element into the body, which has a style property set in the external style sheet. If you insert this element on document load, and poll every couple of milliseconds until the style property can be retrieved using the computed style, you know that the external style sheet has been applied.

I’ve implemented the hacks discussed in this post in sIFR r339. See also hacks.pageLoad under sifr.js:

function checkStyle() {
  dummy           = dom.create("div");
  dummy.className = CSS_DUMMY;
  dom.getBody().appendChild(dummy);
  pollStyle();
};

function pollStyle() {
  if(dom.getComputedStyle(dummy, 'marginLeft') == '42px') afterStyle();
  else setTimeout(pollStyle, 10);
};

function afterStyle() {
  if(dummy && dummy.parentNode) dummy.parentNode.removeChild(dummy);
  dummy = null;
  fire(null, true);
};

And the CSS:

.sIFR-dummy { 
  width: 0px;
  height: 0px;
  margin-left: 42px;
  z-index: 0;
}

sIFR 3: Updates

posted October 11th, 2007, 40 comments, tagged

Life’s busy as usual, but it’s been too long since I last wrote about sIFR. Using the wonders of modern technology I’ve been writing and posting this from a train speeding towards Rotterdam, where I’ll be dropping by at the Xopus booth at ECM Plaza. Afterwards I’ll be going to a place-supposedly-unknown on a company holiday with Q42 and Xopus. (How cool is that, eh?! We’re hiring, too) So anyway, that’s just to tell you that I won’t be responding to questions in the next few days.

I’ve been working on sIFR on and off, so it’s moving slowly. That’s not to say nothing is happening, though! Since the last post there have been 40 new revisions. As usual they can be found through the nightlies. I’ve also created a RSS feed for the nightlies. This is the best way to stay up to date on development.

Which Version to Use?

An oft-asked question is which revision should be used. Since sIFR is under constant development, it’s always a good idea to use the most recent nightly. Using the feed you can keep an eye on bug fixes. sIFR is beta software. Even though I would totally recommend it over version 2, it is your responsibility to stay somewhat up to date and not miss out on important bug fixes. As usual, installing a new version means replacing the JavaScript file and re-exporting the Flash movie. It’s also a good idea to look at the changes between the revision you’re currently using and the new revision, you may have to change some other things.

Roadmap

So what’s the plan going forward? I intend to stabilize the current code base and release a second beta. After the beta is out I’ll be improving the speed of the code and writing documentation – this will likely result in some refactoring. Then one or two release candidates and we’re good to go for 3.0. I’m not giving dates because I honestly have no idea when this’ll be happening. You can view a list of known issues.

Documentation

The documentation is running behind on the code, for which I apologize. Right now I’d prefer to write code rather than text, so it’ll stay this way for a while. Of course you’re welcome to chip in on the wiki.

sIFR on Tour

Last Friday I gave two presentations about sIFR. One at Onstuimig in Amersfoort (they’re hiring too!) and one at Info.nl. In the presentations I talked about the history of sIFR and explained how version 3 works. You can read Tom Greuter’s report of my talk at Info.nl at their weblog. I had a great time giving these talks and meeting web people here in Holland, so I’d like to do this more often. Let me know if you’re interested!

Links

Some useful links regarding sIFR 3:

sIFR 3 Revision 278 Security Update

posted July 4th, 2007, 89 comments, tagged

Newer versions are available. Find out more.

Yesterday, a security vulnerability was found in sIFR 2 and 3. Malicious websites can trick visitors into running JavaScript code on domains hosting sIFR movies. No exploits are known. If you are using sIFR 3, you are advised to update to revision 278 (or any later revision).

Download sIFR 3r278.

You’ll need to update the sifr.js file and re-export the sIFR movies.

Detailed description

sIFR passes the text it has to render to the Flash movie using Flash variables. Normally these variables are specified using a flashvars parameter, however they can also be passed using the query string. Malicious websites can craft an iframe which points to a sIFR movie on the target domain. An HTML link to some JavaScript code can be passed to the movie through the query string. When a visitor of the malicious website clicks on the link, the code is run on the domain the movie resides. Vulnerable browsers are Firefox, Safari, Opera and Netscape. This specific attack does not work in Internet Explorer. An alternative attack is to load the movie directly or in a popup window, this does work in Internet Explorer.

Revision 278 prevents this attack by not rendering any content that is passed through the query string. Credit goes to Arseny Vesnin for finding the vulnerability.

Other changes

Here are the changes since revision 229:

  • Improvements to the Callback API.
  • Improved ratio calculation and handling.
  • No longer replacing elements that have display: none set.
  • Added a transparency and opaqueness option.
  • Increased frame-rate of sIFR movies.
  • Elements with the .sIFR-ignore class will now be visible.
  • Changed semantics of sIFR.prefetch(). When invoked after sIFR.activate() it’ll pre-fetch the given Flash movies in all browsers.
  • Fix for the sticky hover problem.
  • Fixed problem in Internet Explorer when used in combination with (for instance) SWFObject.
  • Anti-aliasing can be specified in JavaScript.
  • Text-wrapping can now be prevented by setting the preventWrap property for sIFR.replace().
  • sIFR will no longer activate when loaded directly from the filesystem. Load it through a webserver instead.
  • Debug mode is automatically enabled if the sifr-debug.js file is loaded (before sifr.js).

As this release has been rushed due to the security issue, I have not been able to update the documentation.

Download sIFR 3r278.

sIFR 3: Revision 229

posted February 25th, 2007, 55 comments, tagged

Here’s a quick overview of what’s changed between revision 209 and 229:

  • Automatic ratio approximation.

    The font size does not correspond directly to the height of the Flash movie. The relation between the font size, the number of lines and the height of the Flash movie is called the ratio. By defining ratios you’ll stop the Flash movies from abruptly resizing, or at least you’ll be able to lessen the impact. You can now use sIFR.debug.ratios() instead of sIFR.replace() to find an approximation of the ratios. For more information see Ratios.

  • Fixed leading for single-line text.

    If you had specified leading, and the text would occupy only one line, the Flash movie would still have the leading applied. This is now fixed. (Thanks, Marty Stake!)

  • Fixed stuck hover effect (except for Opera).

    The hover effect for links inside the Flash movie would get stuck if you moved the mouse away too quickly. I’ve implemented a workaround, which works in Firefox, Safari and Internet Explorer. No luck in Opera so far.

  • Fixes the movie in Internet Explorer after it’s HTML has been reset.

    If you change the innerHTML of an element which contains sIFR movies, the text inside the movies would get lost. This is due to a bug in Internet Explorer. With the Flash-to-JavaScript callbacks I’ve been able to implement a workaround. As this problem exists in sIFR 2.0.2, this is yet another reason to switch to sIFR 3!

  • Improved callbacks, callback access.

    Flash-to-JavaScript callbacks have been improved. You can now get a reference to a callback object, which for example will let you change the text inside the movie.

  • Domain control is now the same in Flash as in JS.

    You can now use the same value for sIFR.domains in the document and in Options.as.

  • Hide movies until rendered

    There’s now a sIFR.delayCss option which will hide the Flash movies until they have finished rendering. It is only supported in Firefox and Safari, and it’s a bit of a risky setting. In Internet Explorer and Opera the callbacks don’t work if the Flash movie is hidden, in the future this might be the case for Firefox and Safari as well. Use with care.

  • As a bonus: as of revision 230 the Flash movies will show their revision

    If you open the Flash movie directly it’ll show it’s revision number. This is an easy way to verify the version of your Flash movies.

And to conclude with some cool news: Ethan Marcotte, designer and CSS wizard, will be making a really flashy sIFR demo. Thank you Ethan!

You can download r230 and subsequent versions from the nightlies.

sIFR 3: Revision 209

posted January 19th, 2007, 24 comments, tagged ,

From time to time I’ll be posting about what’s going on in the sIFR nightlies. Today is such a time, with a lot of interesting changes! I won’t go into too much detail as it’s all documented on the wiki, so here’s the list:

  • Support for pixel fonts through the pixelFont argument. See JavaScript Methods: replace.
  • A way to stop the page jumps by specifying the ratios argument. (More about ratios). See JavaScript Methods: replace.
  • Support for fixed font sizes and sizes relative to the main size, see font-size in Styling.
  • Simplification in the API, you can now pre-fetch by passing the movies to activate() instead of prefetch(). See the How to use.
  • Improved pre-fetch code for Internet Explorer.
  • Laid groundwork to communicate with the Flash movies. Test it!.

Ain’t that cool? You can find r209 under the nightlies.

A Word About That Pre-Fetching Improvement

There were a few reports about sIFR overwriting the class name on the body element in Internet Explorer, but only on the first load. This has been fixed in this revision, and here’s the background for the bug:

It only happened on initial load because the issue was caused by the pre-fetch code, which only runs once per browser session. Pre-fetching was done by document.write()ing an embed element to the document. As it turns out this forced Internet Explorer to create a body element. (It behaves the same for any other element which should be in the body).

Results of this are breaking the *:first-child+html IE 7 CSS hack and overwriting class names on the body. After sIFR sets the class name IE won’t use the class names from the real body element anymore.

The solution is to write a script tag, which does not have the effect of IE creating the body element. Other software, such as Mint suffers from the same problem. I’ve already reported this to Shaun Inman, but in case you keep seeing the problem even with this revision make sure the Mint JavaScript is loaded after sIFR has been activated.

sIFR 3b1: The Mo’ Betta Beta

posted December 18th, 2006, 118 comments, tagged ,

sIFR 3 Revision 278 has been released. Please upgrade to sIFR 3 Revision 278.

Just in time for Christmas, I present you a new sIFR release! It’s been a long time coming but with this release I feel sIFR 3 is ready for widespread deployment. If you’re unfamiliar with sIFR, the obligatory introduction paragraph goes like this:

sIFR is meant to replace short passages of plain browser text with text rendered in your typeface of choice, regardless of whether or not your users have that font installed on their systems. It accomplishes this by using a combination of JavaScript, CSS, and Flash, which renders the font. It degrades gracefully if Flash is not present.

Compared to sIFR 2 the new version is radically different. Backwards compatibility has been broken, but that’s okay since deployment is now ridiculously easy. There’s great control over how the text is rendered inside the Flash movie: you can easily use bold and italics together, or use different colors. There’s support for leading, kerning and opacity, filters, blend modes and anti-aliasing.

The biggest changes from the alpha release are:

  • No more Flash 7 support. This led to a simplification of the code base and made sIFR easier to deploy.
  • No more compatibility mode. Supported browsers are Internet Explorer 6+, Firefox 1.0+, Safari 2.0+, Opera 8+ and Konqueror 3.5.6 (due in Januari) .
  • Improved Flash detection.
  • Improved rendering in Internet Explorer.
  • Firefox and Internet Explorer will now replace the elements before the page has finished loading. No need to put JavaScript inside the body tag.
  • Fine-grained tuning of the text position inside the Flash movie.
  • Callback handlers to modify the content being replaced, the CSS, and the end result.
  • Support for text transformation, including capitalize.
  • Domain validation on the client side, useful for example to stop sIFR from running when the page is being translated by Google Translator.
  • Various bug fixes.

Documentation has improved, too. There’s now a simple introduction tutorial and the configuration settings and methods are properly documented. No doubt this still needs work, and that’s exactly why the documentation takes the form of a wiki. If you see improvements, feel free to make them.

As I said before, I really feel this version is fit for widespread use. However, it’s still a beta so please keep track of developments, for example by subscribing to the mailing list. If you’re using sIFR please consider making a donation, especially if you’re a company. Here’s a nice button to click:

sIFR 3 is open source and licensed under the CC-GNU LGPL. Check out the demo and go download it! If you want to keep track of newer developments, check out the nightlies. Anything from revision 199 is new. And finally, many, many thanks to everybody who filed bug reports, helped testing, responded on the mailing list, improved documentation, spread the word and made a donation.

sIFR 3 Revision 278 has been released. Please upgrade to sIFR 3 Revision 278.

Over the past few weeks I’ve been exchanging e-mails with Bobby van der Sluis, discussing sIFR and UFO. Among the things discussed was DOMContentReady, or more specifically my implementation for Internet Explorer, which was based on the Dojo implementation. Dojo uses the following code:

if(dojo.render.html.ie && dojo.render.os.win){
    document.attachEvent("onreadystatechange", function(e){
        if(document.readyState == "complete"){
            dj_load_init();
        }
    });
}

Whereas the “official” code is as follows:

/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
  if (this.readyState == "complete") {
    init(); // call the onload handler
  }
};
/*@end @*/

The difference may seem minor (readyState on a script instead of the document), but Dean Edwards mentioned in a comment on his site that document.readyState wouldn’t work properly. So, time for some test cases! First of all, domcontentloaded.html logs the following:

  • Safari: changes to document.readyState
  • Mozilla/Opera: firing of the DOMContentLoaded event
  • Internet Explorer: both techniques covered above
  • All browsers: the loading of an image and window.onload

Additionally, an external CSS file is loaded which gives the document a red background color. When the DOMContentLoaded event (or browser specific equivalent) fires, some CSS is written to the page which changes the background color to green. More on this later. The CSS file waits 5 seconds before returning data to the browser, the image waits 10 seconds.

It turns out that in Internet Explorer document.readyState fires after the loading of the image, and right before window.onload. In effect, it’s useless. The “official,” script.readyState variant does fire before the image loads, and is indeed the correct version. In the other browsers the official techniques work properly as well, and the background color of the page is green.

Safari & Style at the Opera

Now, what are we using that background color for? For sIFR it is incredibly important that all CSS has been loaded and applied before kicking into gear. It relies completely on the specified styles for the to-be-replaced elements, without it just won’t function properly. As said before, the first test case showed no surprises with the background color: it appears as if the stylesheets are applied in the correct order. In Safari and Opera, however, this turns out to be false. Enter readstyle-domcontentloaded.html. This test case is virtually the same as the one used before, however on the DOMContentLoaded event it logs the computed background color.

In Internet Explorer and Mozilla it reads out a red background color, in Safari however it reads rgba(0, 0, 0, 0) or transparent. There is also a Flash Of Unstyled Content. In Opera 9 the background color also reads as transparent, but without a FOUC. Webkit.org has an article by Dave Hyatt explaining the issue (as well as the FOUC):

(WebKit) will continue parsing a page even after a stylesheet directive has been encountered so that stylesheet and script loads can be parallelized (compared to waiting for the stylesheet to load – Mark Wubben). That way everything can be ready for display much earlier. (…) when a script attempts to access a property that involves having accurate layout/style information(, shipping Safari’s) will go ahead and lay out what it’s got even though it doesn’t have the stylesheet yet. It will also display it. This means you see FOUC whenever a script tries to access properties like scrollHeight or offsetWidth before the stylesheet has loaded. (…) we will (…) give back information that the page might consider to be incorrect, since the stylesheet that supplies the up-to-date information hasn’t loaded yet.

The article also discusses ways of solving this issue in WebKit itself. The suggested method is stalling the JavaScript execution when it tries to access a style dependent property. Unfortunately as of nightly r17760 this has not yet been implemented. This behaviour also highlights a need for something like a FinishedRendering event that would fire when the stylesheets referred to in the HTML have loaded and been applied. Right now the DOMContentLoaded movement relies quite heavily on this specific browser behaviour, if things change in Mozilla or Internet Explorer without implementing either a FinishedRendering event or stalling JavaScript execution — for backwards compatibility probably the better solution — many modern sites and applications will break.

In the mean time, no more DOMContentLoaded in sIFR for Safari and Opera.

I was looking at a bug report for sIFR today. It discussed how sIFR 3 crashed Firefox 1.0.0 on Windows. After the better part of the evening, here’s what I found: if you create a non-anonymous method, declare a variable inside it and set a property on the function object with the same name as the variable (and whatever value, I used null), Firefox 1.0.0 will crash after about ten seconds after loading the page. If it doesn’t, close the window and it should crash right away. It seems to be an issue in the JavaScript parser.

Here’s the code, adjusted for readability, but you bet this fits in one line!

(function nonAnonymousMethod() { 
  var aProperty;
}).aProperty = null;

In the case of sIFR, the parseSelector code contained a similar construct. Fixed now in r130.

Full testing details: Firefox 1.0.0 and Firefox 1.0.1 on Windows XP SP2 with the latest updates as of Sept 8, 2006. Firefox 1.0.0 crashes, Firefox 1.0.1 doesn’t. I therefore assume the problem will not occur in any versions later than 1.0.0. Download old Firefox versions.

Flash? Pure Evil

posted May 29th, 2006, 7 comments, tagged

I’ve been working on adding support for a few hours tonight, when I ran into the problem that eval() in ActionScript cannot compute anything. That’s right, the only thing it is good for is for referencing variables! Like we couldn’t do that in a better way already!

Anyhow, I needed eval() so you can configure filters on the client side. Therefore, my own implementation:

private static function eval(str) {
  var as;

  if(str.charAt(0) == '{') { // Ah, we need to create an object
    as = {};
    str = str.substring(1, str.length - 1);
    var $ = str.split(',');
    for(var i = 0; i < $.length; i++) {
      var $1 = $[i].split(':');
      as[$1[0]] = sIFR.eval($1[1]);
    }
  } else if(str.charAt(0) == '"') { // String
    as = str.substring(1, str.length - 1);
  } else if(str == 'true' || str == 'false') { // Boolean
    as = str == 'true';
  } else { // Integer
    as = parseInt(str);
  }

  return as;
}

Eat that, ActionScript!

Oh, and filters seem to be working. Check out the demo and download the latest nightly. Fun!

P.S. I’m going to be in Copenhagen from Wednesday until Sunday for Reboot. If you’re there, say hi!

Over the past few days I’ve fixed a number of bugs in the code and added some more Flash 8 related features. Here’s a quick post on how to stay up to date. An updated version of the demo distributed with the Alpha release is available.

You can download the latest nightly. The nightlies are similar to the alpha distribution, but you’ll have to re-export the Flash movie and you need to compare the configurations (both in JavaScript as in ActionScript) for changes.

Finally, a list of to-do items for the beta (excluding documentation and testing):

  • Use ExternalInterface when possible, instead of fscommand

  • Handle font and window resizing

  • Add a way to change the font style after the movies have rendered

  • (Test?) support for pixel fonts.

  • Background images inside the Flash.

  • Flash 8 filters.

  • IE focus bug with slow page loading, read more.

Have fun!

sIFR 3 Alpha: Tasting the 3.0

posted May 22nd, 2006, 111 comments, tagged

The beta is out! Read more.

It’s high time for a release of the new sIFR version, 3.0. With Inman’s Flash Replacement as the original, sIFR 1.0 making it scalabale and sIFR 2.0 bringing it to the masses, this version will really make things rock. Flash 8 has brought a lot of new, cool stuff. Now you can use these features, starting with way better font anti-aliasing and auto-kerning. You’ll also be able to use filters to do shadow effects (in the nightlies).

For those unfamiliar with sIFR, here’s a short description:

sIFR is meant to replace short passages of plain browser text with text rendered in your typeface of choice, regardless of whether or not your users have that font installed on their systems. It accomplishes this by using a combination of javascript, CSS, and Flash.

Furthermore, it degrades gracefully when Flash is not present or the browser not supported.

For sIFR 3, the code has underwent a complete rewrite, making it easier to use and making it work even better. There also is a new way to render the Flash font. No longer are guesses being made as to how big the font should be, the cues are taken from the font size used in the HTML page and the number of lines the text spans. In order to provide better styling you can now use FlashCSS. No matter how many colors or font styles you want to use, now you can.

Additionally, leading is now supported by sIFR. A number of small issues has been fixed, and you can now pre-fetch the movies for Internet Explorer and Safari. This solves a problem where these browsers would request the same sIFR movie again and again until it was cached – instead of waiting for the first request. Huge bandwidth saver here! And for the AdBlock users, using a little bit of CSS the object tab has been hidden. sIFR is not an ad, and you should see the text itself, without obstruction.

Here’s the full feature list:

  • A new font sizing algorithm, although it needs some attention with regards to padding and wrapping in the Flash element.

  • FlashCSS, both configurable in ActionScript and in JavaScript.

  • Support for Flash 8 movies, for real good looking text.

  • Font resizing in Opera 7+.

  • Support for leading

  • Flash movie pre-fetching for Internet Explorer and Safari.

  • Easier configuration.

  • No more object tab obscuring the text when AdBlock is being used.

By the grand tradition of alpha (and open source) releases, this version lacks serious testing, actual documentation and a number of features. None the less, it is functional, as you can see by the demo.

As you are probably anxious to get started, here’s a run-down of deploying sIFR 3. Please note though that this is an Alpha release: if you run a high profile website and you really don’t need the new features, sIFR 2 is best for you. If you like playing around with new tech, please give this version a try. The more real life use, the more improvements can be made.

That’s it for this release. I’ll write more about the beta release in another post. Please give the new Alpha a try and let me know what works and what doesn’t. You can also subscribe to the mailing list. Now, without further ado, to the download!

sIFR 3 Feature List

posted March 12th, 2006, 19 comments, tagged ,

As I’ll have to focus on course-work and money-making-work in the next few weeks here is a feature list for sIFR 3. Of course, when something turns out to be too hard to implement, it’ll be removed from the list. Don’t take it for granted!

  • Better and easier font sizing, as explained in Font Sizing with sIFR.
  • FlashCSS: This lets you use multiple colors and different text styles in general. It also aids with link styling. Todd Dominey has a list of supported properties.
  • Controlling kerning, leading and line-height.
  • Font resizing.
  • Better FlashBlock support (actually this’ll be a side-effect of the font resizing).
  • Possibility to ignore specific elements during replacement.
  • Modification of the content passed to sIFR.
  • Pixel fonts.
  • Flash 8 filters.
  • Background images inside the Flash.

sIFR itself will be easier to use, and there’ll be a number of small fixes for edge-cases. Speed improvements are high on the list as well, obviously.

Font Sizing with sIFR

posted March 7th, 2006, 14 comments, tagged ,

Font sizing is the most difficult part of using sIFR. In this post, I’ll discuss how the algorithm in sIFR 2 works, or rather, why it doesn’t work as well as originally intended. Coincidentally, this makes this post an excellent tutorial for font tuning in sIFR 2. We’ll also look at how things will be improved with sIFR 3.

sIFR 2

The algorithm used by sIFR 2 is relatively simple:

  1. Take the width and height of the element you want to replace.
  2. Create a Flash movie which uses these dimensions.
  3. Increase the font size from 6 pixels, pixel by pixel, while rendering the text, until the height of the text is larger than the Flash movie.
  4. Render the font with a size one pixel smaller than obtained in (3).

Unfortunately this doesn’t quite work. First of all: the font used in the Flash movie may be wider or smaller than the font used in the HTML. Let’s say the font is wider, what will happen then is:

  • Because the font is wider, it will wrap to a new line earlier than the HTML font would.
  • This allows for the possibility that the text will reach the allowed height earlier, resulting in a smaller font size (see point 3 above).

A way to deal with this is to set the letter-spacing of the HTML text so the font appears to be wider, having the effect of giving it the same width as the Flash font. This works, assuming that there are no other factors influencing the width and height of the text, such as (unintentionally) using different fonts on different user machines. Default browser settings for CSS properties like font-size or letter-spacing can be of influence as well.

In short, achieving cross-browser and cross-platform consistency of the width and height of the text, while taking into account the width of the font used, can be very, very hard.

sIFR 3

In sIFR 3, things will work a little different. For starters, the font size is no longer determined by the width and height of the text. Instead I’ve figured out a way to derive the font size from CSS. Here is a short version of the rendering algorithm employed by sIFR 3:

  1. Determine font size and the number of lines the text takes up.
  2. Create a Flash movie using the width and height of the text, these can be changed later.
  3. Render the text.
  4. If the text is wider than the allowed width, try wrapping it to the next (or a new) line.
  5. If a single word is causing the text to be too wide, resize the movie.
  6. If the text now requires more lines, resize the movie.

Resizing the movies requires Flash to talk to the JavaScript code in the website. Since we’ve dropped Flash 6 support, this has now become possible.

Specifying the desired font size in Flash is quite easy as well. All it takes is two properties!

.sIFR-hasFlash h1 {
  font-size: 12pt;
  line-height: 1em;
}

Why the line-height? sIFR uses the line-height and the height of the element itself to calculate how many lines the text uses. By using line-height: 1em; we ensure it has the same value as the font size. As Eric Meyer said:

(…) for line-height, em-based values are calculated using the computed font-size of the element itself. I declared the font-size directly, so we know its computed size in pixels.

It also turns out that if you specify line-height in ems, and don’t specify it in the descendent elements, they will have the same line-height:

So that computed value (…) is what’s passed on to the descendent elements. (These) elements will inherit (the same) line-height value. End of story. They don’t change it based on their own font sizes; in fact, they don’t change it at all (sic).

Concluding

sIFR 3 will bring easier font tuning, as well as other features I’ll talk about later. You can see the original font tuning experiments, as well as a demo of the current stable SVN export.

Evolution

posted February 20th, 2006, 15 comments, tagged

sIFR now does multiple colors, configured by CSS, and with better links. And it’s still missing a lot of features, and is probably incredibly buggy, but hey.

http://dev.novemberborn.net/sifr3/svn/test/demo.html

Next step: making it *scalable*.

February 21st (in the wee hours): Now with a hand-tailored word wrap algorithm!

Sources Are Telling Me…

posted January 17th, 2006, one comment, tagged ,

I’ve made a development subdomain here at Novemberborn to host SVN exports of the sIFR 3 codetree and other development projects.

Current projects:

sIFR 3

The codetree contains the latest version with test cases. If you find bugs, please send a message to the list.

ParseSelector

This is a rewrite of the parseSelector() method used in sIFR 2. This version is extensible and works a lot better. It’s partly based on Dean Edwards cssQuery. Because it’ll be used in sIFR I decided to write my own implementation instead of using cssQuery, which is more advanced than what sIFR needs.

11born-wiki

This is the current code for my wiki server. It’s released under the same license as i2, which as far as I can tell is the MIT license (there is no license notice in the trunk, but it’s in the Rails repository and Rails is licensed under MIT).

Because of this license I’ve removed my stylesheet and the images specific to my site. I rather not have someone duplicate the design because the stylesheet was released as open source.

I’m providing the source because I hope it’ll be useful to you. I’m not, however, going to maintain it or provide support. I simply do not have the time for another open source project. If somebody picks it up (or merges it into i2 itself, even) that’d be great.

Have fun!

Quick: A Wiki!

posted January 14th, 2006, 8 comments, tagged ,

I’ve updated the wiki software running wiki.novemberborn.net to a customized version of i2, the app behind the Ruby on Rails wiki. At first glance it’s a lot more responsive, and I hope it won’t go down as much as the previous incarnation.

Currently it’s being run off Webrick, which is set to be replaced by a lean Lighttpd server. Some problems however are preventing this right now. I’ll write about the new app later when these issues are resolved. I’ll also publish the source then.You can find the source in this post.

Anyway, that’s what I’ve been busy with the past week. Before that, during the winter break from university I’ve been working, hence the slow updates here. But with the wiki out of the way, it’s finally time to focus on sIFR 3 :)

Talk to you again soon,

sIFR 3: A Look into the Future

posted December 16th, 2005, 62 comments, tagged ,

Some time ago Mike and I asked you what features you wanted to see in sIFR 3. While we haven’t defined the exact list of features for the new version it has become time to look into the future to see where sIFR is heading.

As you probably know Mike is now the CEO of Newsvine, and as such he’s pretty occupied. The result of this is that the actual development of sIFR 3 is resting fully on my shoulders. Since I’m no super hero, I’ve been thinking about how the development process should be approached and how you can help with it.

sIFR Wants You

sIFR is meant to work in as many browsers as possible. Being a fully degradable add-on, it should not break sites when a browser has trouble supporting it. To accomplish this goal a lot of testing is needed. Much more testing than I have machines or time for. To speed up and improve with this testing we’re hoping for the user-base to lend a hand. Yes, sIFR wants you.

A mailing-list has been set up to aid in this process. After every significant iteration of the code you’ll be notified through this list of new tests. The tests will mostly be automated, aside from the occasional human verification. We’re hoping to get confirmations from two or three people for each browser and browser version we are supporting (more about that in a later post).

The list will also be used to discuss the way sIFR works itself. Here you can think of the tuning process or how to provide fallback for Flash transparency. sIFR is not going to be “designed by committee” however. While we greatly value your input, at the end of the day it’s going to be our call.

Time

Just as Mike is busy, so am I. Currently I’m studying Computer Science at the University of Twente and I also have to earn some money. If you have an interest in seeing sIFR developed faster please consider donating (by clicking on the Make a Donation button on the right) or hiring me to work on sIFR.

The Future

The future of sIFR is bright. With the advent and acceptance of newer browsers it has become possible to ease the use of sIFR. The release of the new Flash 8 gives us more power, and also means we’re letting go of Flash 6. Good stuff is on it’s way, and I hope you’re in for a ride. Again, please sign up for the mailing-list and thanks in advance for your support.

sIFR 3: A Request for Requests

posted October 28th, 2005, no comments, tagged

As The Seattle Lion pointed out, we’re taking suggestions for sIFR 3. Head over to the request page and let us know what you’d like to see!