#1559 Font: points vs pixels

Yuri Strot Tue 14 Jun 2011

Currently if we use Font with size = 12 it appears like 12pt on the desktop and like 12px on the web. I'm not sure which units is better, but I believe it should be the same.

brian Tue 14 Jun 2011

According to the Font.size fandoc it was spec'ed as points

andy Tue 14 Jun 2011

Thats really an implementation detail for how we map into CSS - you should consider them points from an FWT perspective.

Font point sizes are a bit inconsistent in web browsers. The same point size will vary from browser to browser. And a CSS point size always appears bigger than the native OS point size.

From what I have found, the CSS pixel size actually does map to the "correct" OS font point size - which is important for FWT. And it is a reliable way to specify size across browsers. So thats why we map to px under the covers.

Yuri Strot Tue 14 Jun 2011

It looks very strange. Font metrics are well specified to avoid any variance between platforms/environments. Moreover there should be clear dependencies between font size, height, pixels and points. So I've played a bit with different environments and this is what I have: http://oi51.tinypic.com/34pyzwm.jpg

As you see all browsers both on Windows and OS X show more or less the same fonts. It's OK because as I know modern browsers don't care about DPI of OS and assume it equals to 96. Font on Windows+SWT looks equal to font in any browser. However font on cocoa+SWT doesn't look correctly. I see this size is closer to pixels in browser terms, but it's not.

I'll try to go deeper to this, but I think this is swt-cocoa issue.

Yuri Strot Wed 15 Jun 2011

OK, I got the issue. We actually have following:

  1. On Windows: points(SWT) = points(browser) != pixels(SWT) = pixels(browser)
  2. On Mac: points(SWT) = pixels(SWT) = pixels(browser) != points(browser)

And this behaviour correct because of following:

  1. Any font will be rendered in pixels therefore font in pixels have the same presentation on all platforms both in browser and SWT.
  2. If font size specified in points then renderer converts this value to pixels: font size in pixels = font size in points * dpi / 72
  3. On Windows both SWT and browser suppose dpi = 96 and we have points(SWT) = points(browser). However we can change this value in platform settings and in this case SWT will get the new value, but browsers will use dpi = 96.
  4. On Mac by default we have 72 dpi in SWT and 96 dpi in browsers that's why points(browser) != points(SWT). However in SWT with 72 dpi we have font size in pixels = font size in points * 72 / 72 = font size in points.

I propose to use pixels everywhere in FWT because this unit is really cross-platform. Moreover pixel-based metric is native for any software while point is coming from the typography and makes sense only for paper. So if FWT can be used to create layout for printers then it makes sense to have both units. But I'm sure that pixels should be default.

andy Thu 16 Jun 2011

The original intention here was to make sure the size we chose was consistent with the size you used in native platform code - ie:

Font("10pt Lucida Grande") == [NSFont fontWithName:@"Lucida Grande" size:10]

However, when we added the Desktop.sysFontXXX APIs - I stopped using explicit Font definitions in favor of the sys fonts - which I was able to tweak in JavaScript to match the platform. So I'm not sure this actually even holds up anymore.

But it was my understanding AWT and SWT Font APIs only took an integer value specified as points. Do they allow you to specify pixels? I'm open to making changes here - tho would like to understand the SWT side a bit more.

qualidafial Thu 16 Jun 2011

@andy: Correct, SWT's font APIs are based on integer values of points--pixels are not supported directly in the API. However this is pretty simple to reverse engineer:

int pointHeight = pixelHeight * 72 / Display.getDefault().getDPI().y;
FontData fontData = new FontData(name, pointHeight, style);

P.S. I've done quite a bit of SWT programming, so feel free to ask whenever you have questions.

andy Thu 16 Jun 2011

Thanks @qualidfial - good to know.

The baseline should be SWT - and it looks like that works right. We use points because that is what the platform APIs use - and we want to be consistent with them. That all looks right to me.

I got the sys fonts "working" in the browser internally via the Desktop.sysFontXXX methods. But that is sorta a band-aid around the core issue @yuri pointed out. We can do something more sophisticated when we map the Font to CSS - but think we should keep this an implementation detail in the browser if possible.

Yuri Strot Thu 16 Jun 2011

Did I understand correctly that your approach is to use SWT font metrics as a basis and reach the same look-and-feel in a browser? In this case current implementation works only for Mac, because on Windows we should map font to points instead of pixels. Currently I'm using following ugly workaround to get the same look-and-feel: fontSize := (Desktop.isMac || "browser" == Desktop.platform) ? 16 : 12.

Anyway why not allow to specify font in pixels at least as option? As @qualidfial mentioned we can easily use pixels in SWT and in a browser.

andy Thu 16 Jun 2011

Did I understand correctly that your approach is to use SWT font metrics as a basis and reach the same look-and-feel in a browser?

Yep.

In this case current implementation works only for Mac, because on Windows we should map font to points instead of pixels.

Yes its not quite complete. All my code uses (directly or via toSize) the Desktop.sysFontXXX calls - so this hasn't really come up for me. This is the recommended way for getting system fonts. But I am aware things don't quite work if you create your own Fonts.

I was thinking the simplest thing todo - would be to switch off in WidgetPeer.fontToCss based on the platform. Will need to tweak the DesktopPeer.sysFontXXX class as well to match. If you can figure out how to make that work on both OSX and Windows - I'll merge the patch.

Yuri Strot Thu 16 Jun 2011

OK, thanks. I'll look into WidgetPeer.fontToCss and will create a patch.

Login or Signup to reply.