ed.blog

You will be vectorized.

Subscribe to RSS feed

On mythbusting and the web... and why SVG Fonts are sometimes useful

, , ,

This is a response to "Mythbusting: Why Firefox 4 won’t score 100 on Acid3".

To get the facts straight, let's start with some history.

Acid3 is a test released in 2008 that tests EcmaScript and a number of different W3C Recommendations. The test as a whole is heavily focused on DOM functionality, and gives the tested browser a score from 0 to 100 based on how many subtests were passed. Having 100/100 is not enough by itself to pass the test; the rendering must also look exactly like the reference page.

Ian Hickson compiled the first 84 tests, and announced a competition to fill the 16 remaining subtest slots, open to anyone that had a test that fulfilled the conditions (quoted with emphasis added in red below):

  1. The test must consist of the body of a JavaScript function which returns 5 when the test passes, and which throws an exception otherwise. It doesn't matter what kind of exception.
  2. The test must compile with no syntax errors in Firefox 2, IE 7, Opera 9.25, and Safari 3. (You can use eval() to test things that are related to syntax errors, though.)
  3. The test must not crash any of Firefox 2, IE 7, Opera 9.25, and Safari 3.
  4. The test must fail (throw an exception) in either a Firefox trunk build from January 2008 or a Webkit trunk build from January 2008 (or, ideally, both). (Opera and IE are failing plenty of tests already, I don't want to add more tests that only fail in one of those. Of course if you find something that fails in Firefox or Webkit and Opera or IE, so much the better.)
  5. The behaviour expected by the test must be justifiable using only standards that were in the Candidate Recommendation stage or better in 2004. This includes JavaScript (ECMAScript 3), many W3C specs, RFCs, etc.
  6. You must be willing to put your test into the public domain. (I don't want us to end up with any copyright problems later!)

Several people of various affiliation (myself included) contributed tests during the week the competition was open.

Now, every once in a while (usually around major version release time), various companies and individuals complain about having to fix bugs and/or implement web standards to pass the test.

Opera and Webkit implemented (very brokenly, in at least Opera’s case) a small subset of SVG 1.1 Fonts; basically just enough to pass Acid3.

- Boris Zbarsky

Opera 8 was the first version of Opera that shipped with native SVG support back in 2005. A full version history is also online these days thanks to Frank M. Palinkas. Opera 8 had support for much the same subset of SVG Fonts we support in Opera 11 today. True, we did have to revisit the fonts code several times after Opera 8, to fix it to properly deal with unicode surrogate pairs for example and a slew of other bugs unrelated to Acid3 (remember, this was before Opera even passed Acid2). Granted, we did add support for the SVG <altGlyph> element because that was a required part of subtest 79 (created by Cameron McCormack) in Acid3. That was something that we simply hadn't prioritized, much like many of the other (uncontroversial) things tested by Acid3. As far as the "very brokenly implemented" remark goes, feel free to submit bugs to the Opera bugtracker.

At this point, the SVG working group has decided that SVG Fonts will no longer be a core part of SVG but will be a separate specification, and that it might need some serious work if anyone is ever to implement it in full.

- Boris Zbarsky

It's correct that the SVG WG has been asked to split out the SVG Fonts chapter to a separate specification. This is most likely going to happen as part of the work on SVG 2.0 (or SVG.next, call it what you will). An interesting tidbit is that SVG Tiny 1.2 requires support for the same subset of SVG Fonts that has been implemented independently by several vendors to date. It's a fully backwards-compatible subset, a SVG Tiny 1.2 font is compatible with SVG 1.1 user agents - provided of course that they support at least the same subset of SVG 1.1 Fonts.

In other words, the WOFF font standard is more appropriate, works in more browsers, and is a better way to handle custom font support in browsers.

- Alexander Limi

There are also the TrueType (TTF) and OpenType (OTF) formats, which are equally appropriate, at least if transferred with gzip content-encoding. In fact, downloadable truetype fonts is a part of Acid3 (see the top right corner of the test). WOFF can be used for some things, and it's not a bad format, but it doesn't have the same feature-set that SVG Tiny 1.2 fonts has, and saying they can always replace each other is simply not true. More about that below.

Myth #1: You need to implement the whole SVG 1.1 Fonts chapter to pass Acid3

To be really clear: the entire feature-set of SVG Fonts, where each glyph can have e.g many different fills and strokes, raster images, animation, and be arbitrarily complex, as specified in SVG 1.1, has not been implemented in a single SVG user agent to the very best of my knowledge. Nor is it a required part for passing the Acid3 test.

Myth #2: SVG Fonts and foreignObject support are both required to pass Acid3

Once you put an <iframe> in a glyph, all sorts of issues arise — both in terms of the spec being underdefined and in
terms of the behavior being very difficult to implement, no matter what the spec said.

- Boris Zbarsky

The spec is really quite clear:

It is not required that the SVG user agent supports the ability to invoke other arbitrary user agents to
handle embedded foreign object types

So in fact it's not underdefined, it's explicitly not defined.

But what are SVG Fonts good for?

Here are a couple of examples:

  • Provides simple and manipulable graphics that can help in preserving text as text while maintaining the same visual appearance
  • Crossplatform, crossbrowser, with exact metrics and rendering specified by the SVG specification - e.g very useful for designing tests, or for platforms where you can't install fonts as a user
  • Easy DOM access to glyph outlines (path data)
  • SVG Fonts are fully editable in a text editor
  • The path data syntax is more expressive than what e.g WOFF/OTF/TTF fonts allow
  • Can be "misused" to do specialized stroking (e.g chain fonts, roads or railroad tracks) - granted, this is also true for other kinds of fonts.
I think I'll stop here. I don't like writing long blogposts anyway. And I can't believe I just spent all this time writing this and Firefox 4 still doesn't pass the Acid3 test - man! wink

How to get the svg elements intersected by a given rectangle

, , , ...

Yet another sandbox svg! This time we're going to list all the graphic elements that are intersected by a one-pixel rectangle positioned at the current mousepointer location.

Below is an example of a function that returns the list of elements under the broomsti^Wmousecursor by using the SVG DOM method getIntersectionList. Pass in a MouseEvent object from a mouse event handler to get a static NodeList object back.

function getInteresectedElements(evt)
{
  var rpos = svgroot.createSVGRect();
  rpos.x = evt.clientX;
  rpos.y = evt.clientY;
  rpos.width = rpos.height = 1;
  return root.getIntersectionList(rpos, null);
}

Here's an modified variant of the above running in the browser. Hovering the graphic will show the id's of the currently intersected elements. Note that to work this script requires that the SVG 1.1 DOM method getIntersectionList is implemented, which at the time of writing is not the case in Firefox or Safari. View live example.

The script that shows the intersected elements and the current mouse position can be viewed here. To use it in another svg file just download that script and add a 'script' element to the svg file you want to use it in, like this:

  ...
  <script xlink:href="showintersectedelms.js"/>
  ...
Tested in Opera 10.10.

Getting screen boundingboxes in svg

, , ,

Last time we explored how to get boundingboxes of any svg element. Today I'd like to expand this a bit, and to show what the client (or screen) boundingbox can be used for.

How to get the screen boundingbox

Here's a simple function that returns the boundingbox of an element as a 'rect' element. If the 'rect' element is inserted just after the element that we got a boundingbox for it would in most cases cover that element.

var svgns = "http://www.w3.org/2000/svg";
function getScreenBBoxAsRectElement(elm)
{
  var bb = elm.getScreenBBox();
  var rect = document.createElementNS(svgns, "rect");
  rect.x.baseVal.value = bb.x;
  rect.y.baseVal.value = bb.y;
  rect.width.baseVal.value = bb.width;
  rect.height.baseVal.value = bb.height;
  return rect;
}
As you see from last time, it only changed one tiny thing: getBBox became getScreenBBox. However, not all browsers have native support for the getScreenBBox method so we have to provide a scriptbased fallback solution. This additional scriptfile can be dynamically loaded by another script if the native method is found to be missing.

Here's an example of how to show the boundingbox as a border around any element in an svg, along with the values in text format. The boundingbox in userspace is shown with a red border, the screen boundingbox is shown with blue border. View live example.

The script that shows the boundingboxes and their dimensions can be viewed here. To use it in another svg file just download that script and the getScreenBBox fallback script to the same directory, and add a 'script' element to the svg file you want to use it in, like this:

  ...
  <script xlink:href="showbboxdims.js"/>
  ...
Tested and works in Opera 9+, Firefox 3, Safari 4.

How to get the boundingbox of an svg element

,

A common scenario is that you have an svg file (which often has a 'viewBox' attribute) created in a graphics editor like Inkscape, and now want to make this static svg file interactive or animated. Another scenario is that you want to place/layout elements dynamically and need to know the positions and size of some given elements.

Prerequisites

First it's important to at least be somewhat acquainted with the various coordinate systems at play inside an svg file.

The initial viewport (sometimes referred to as the client- or screen-) coordinate system
This is the actual coordinate system that you see on your computer screen, often defined in pixels. You will need to use this when handling mouseevents for example, since they are going to be in this coordinate system, and they may need to be converted into userspace.
The userspace coordinate system
This is the coordinate system at the place of any given element in the svg file. It depends on what transforms have been specified as well as what the viewport coordinate system specified by the parent svg element(s) and the 'viewBox' if any.

The fun stuff

In order to get the geometric boundingbox of an svg element you can call the getBBox DOM method. This method returns a rectangle DOM object that corresponds to the boundingbox of the element in user units. The returned DOM object is called an SVGRect, and has the following four properties that can be accessed: x, y, width and height.

Note: The boundingbox object is a snapshot of the element's boundingbox at the time the getBBox method was called. Changing the values of the boundingbox has no effect on the visual appearance of the element.

Here's a simple function that returns the boundingbox of an element as a 'rect' element. If the 'rect' element is inserted just after the element that we got a boundingbox for it would in most cases cover that element.

var svgns = "http://www.w3.org/2000/svg";
function getBBoxAsRectElement(elm)
{
  var bb = elm.getBBox();
  var rect = document.createElementNS(svgns, "rect");
  rect.x.baseVal.value = bb.x;
  rect.y.baseVal.value = bb.y;
  rect.width.baseVal.value = bb.width;
  rect.height.baseVal.value = bb.height;
  return rect;
}

Here's an example of how to show the boundingbox as a border around any element in an svg. View live example.

The script that shows the boundingbox as a red rect can be viewed here. To use it in another svg file just download that script and add a 'script' element to the svg file you want to use it in, like this:

  ...
  <script xlink:href="showbbox.js"/>
  ...
Tested and works in Opera 9+, Firefox 3 and Safari 3.

SVG Open 2008

, ,

After nearly two weeks of Bavarian bratwurst, beer and scalable pretzels (though most were of the lesser kind) you'd almost figure it'd take me at least until all the food was digested to make a blogpost about the SVG Open conference, right? wink Anyway, without further delay here are some random thoughts about the SVG Open 2008 conference, which was held this year in Nuremberg, Germany.

  • Andrea Cassera presented a webapp for visualizing historic volcanic activity using svg, which was demo:ed in Opera 9.5. Currently not publicly available in the version that was shown at the conference.
  • Shaun Roe gave a very interesting presentation of a tool called SEDUX which transforms XML data files from the Atlas experiment at CERN into an interactive SVG webapp by using XSLT and clientside scripting. See the paper, and example. Note that Opera 9.6 is required for proper display of the example.
  • Yet another cool example of presenting data was the GPS track webapp by Olaf Schnabel.
  • Zack Rusin talked about how KDE is using SVG and how he'd like to see SVG improved in the future.

The workshops were also quite interesting:
  • Jon Cruz showed some of the new cool features in Inkscape 0.47. The workshop was especially helpful, with many useful tips and tricks.
  • David Dailey gave a session on SVG Filters, and I don't think we had time to more than skim the surface before time was up.

Winmodems are from Venus, Macs are from Mars

, ,

Posting from a dialup connection today, which has a certain retro charm to it. Getting online wasn't as easy as I'd hoped though, read on for the full story.

First off, since I'm packing a macbook and the modem I have to use is a winmodem, a Conexant v90 modem to be exact, there of course weren't any mac drivers for it. So I decided to try using the Parallels VM to get online in Windows XP. No luck though, the modem was detected but it didn't work correctly. This prompted some googling and I thought that maybe I could install and run Windows on the macbook without emulation/virtualization. This turned out to be a major hassle since I didn't want to use the internal harddrive for this installation, but an external usb/firewire drive. A few unsuccessful attempts later, I gave up on that, and tried installing linux on the external drive instead.

Now I learned that Apple recently expired the BootCamp support for OS X Tiger (10.4), as a way of getting people to pay up for Leopard (10.5) I guess, so I had to find some other solution. Turns out there's a free mac boot menu toolkit called rEFIt, which worked just fine. rEFIt can see my external linux install, but alas is still unable to boot from it. Even when I put the linux /boot directory on a partition on the internal drive it didn't want to boot.

Then I remembered that I installed VirtualBox on a few machines recently, but I hadn't yet tried it on my macbook. So I did, and lo and behold the modem just started working!

VirtualBox is free and Open Source virtual machine that can run many different OSes, and it can be installed on OS X, Windows, Linux and Solaris (and I've now tried all except Solaris). Though it should be noted that not all parts of VirtualBox have been released as Open Source.

Probably only a matter of time before I install linux on the internal harddrive anyway, just need to sort out what to throw away first. Though it still sucks that I can't boot linux off the external firewire drive, which is something that obviously works fine for OS X installs.

In conclusion, thanks to Sun for releasing VirtualBox.

Hey little sister!

, ,



I'd like to send these virtual flowers to Camilla Lindberg (fp), as the single parlamentarist in the current government that stood up for the people and voted against massive privacy invasion, a.k.a the FRA law (link in Swedish only). Thank you Camilla.

I only wish that a few more parlamentarists would have been as wise...

Assorted svg news

,

Here's a brief assortment of svg news from June. I don't think any of you missed that the final public version of Opera 9.5 was released, but if you did, nothing is stopping you from picking it up via bittorrent.

  • Jeff Schiller (Motorola) has been appointed co-Chair of the SVG Interest Group. The SVG IG is chartered to produce supplementary documents for the improvement, adoption, and evangelism of SVG; and to foster the engagement of the SVG community, both members and public, in W3C activities. Congratulations Jeff!
  • Opera Mini adds SVG support in their latest server upgrade. Great news for everyone that wants to efficiently use scalable web graphics anywhere.
  • Robert O'Callahan (Mozilla) writes:

    One of the problems with the standards-based Web is that it's hard to use SVG's features to enhance HTML content. [...] So I've been experimenting with better ways to apply SVG effects to HTML content. The first step is to make SVG's 'clip-path', 'mask' and 'filter' properties work when applied to HTML content.

    I'll just let his work speak for itself.

Timetravel

,


The above image should have been an svg image, since that makes it much smaller. However, it tended to freeze in Safari and Firefox, so I'll just link to it for now. Safari 3.1 has issues with the masking and sometimes the fill disappears for the tspans. Firefox 2 doesn't support masks, and has major issues with tspans. Firefox 3.0rc1 still has problems with tspans. Batik 1.7 renders it correctly, but doesn't run the animations (though possibly that's due to the FakeSMILe script). Opera 9.x should be able to play the animation just fine without FakeSMILe though, and you can click the image to stop the rotate animation should you get dizzy or something smile

Falling back, or falling down...

,

Microsoft tries to improve web standards support in IE8 apparently...well, except for...

Known issues we are not planning to change in IE8

  1. is not parsed in a cross-browser compatible way (parsing stops at the OBJECT, whereas other browsers continue parsing all the fallback content and make it available. No support for this parsing behavior is planned for IE8; I'll take this opportunity to ask for real-world scenarios that can help me prioritize this feature.
  2. elements cannot be 'reactivated' by dynamically correcting the attributes that caused the original fallback. Again, your feedback on the potential benefits/use-cases for this feature appreciated.

Source: IE8Blog

Being web standards compliant is not important enough?

Anyway, in practice it means that IE users won't be able to see most graphics on my blog. I usually provide some kind of fallback content for the tags I use. This makes it easier to do progressive enhancement, browsers that don't handle some type of content at all get some other content to munge on instead. Or anyway, that was the thought.