ClearType - a clarification

Henrik Gedenryd Henrik.Gedenryd at lucs.lu.se
Fri Oct 8 15:18:49 UTC 1999


Ok, there seems to be some confusion about what subpixel rendering is.

Adrian made the same conclusion as I did:

>  It seems most people are not checking out the site

So, here goes a longer explanation. Also look at the new gif I've attached,
which shows a "blown-up" version of sub-pixel vs. ordinary antialiasing,
with the outline of the drawn character overlaid. It's not 100% correct but
the principle's there.

(In my first posting I thought people might look at that web page so I
didn't include any further explanations or images. Do have a look at that
site though! It's basically just 1 page with lots of large images (a
teacher's dream!), or 2 pages if you want the implementation details too:

http://www.grc.com/ctwhat.htm )


1. Ordinary antialiasing (*not* sub-pixel rendering):

The technique on the Acorn and in WarpBlt is what I regard as ordinary
antialiasing, ie. using interpolated bits to even out the usual sharp pixel
edges. This is typically achieved by first drawing at a higher reolution,
say 2x or 4x, and then take the 4 or 16 pixels (etc.) that fit inside one
pixel at 1x resolution, and averaging their value, instead of just taking
the value you get from rendering at 1x.

For simplicity, I consider black&white/grayscale only, although this all
applies also to color.

In eg. type, you get various levels of gray instead of just black or white:
25% gray if one of the 4 pixels is black, instead of all white as you would
get if rendering at 1x directly :

...
..H  (this is 2x) -->  1 pixel of 25% gray ; at 1x you would get just white

....H
...HH
..HHH
HHHH  (this is 4x) --> 10/16 or 1 pixel of 62,5% gray; 1x yields 100% black

(I wouldn't call the use of 2x or 4x a "sub-pixel" technique, but possibly
"4x oversampling" etc, like my first CD player.)

2. Sub-pixel rendering

Now, *sub*-pixel refers to that you take the 3 sub-elements that make up an
LCD-screen pixel, and manipulate each of these 3 individually, as if they
were three gray-scale pixels.

RR GG BB   \
RR GG BB    | --  1 color LCD pixel, but 3 elements/"sub-pixels"
RR GG BB    |
RR GG BB   /

Ordinary antialiasing uses gray levels instead of just black & white,
thereby using grayscale to create a perceived increase in B&W resolution.
(This is Acorn OS, WarpBlt, etc.)
*Sub-pixel* antialiasing manipulates the intensity levels (gray = B&W
intensity) of each R, G, and B sub-element separately:

   ........            ..   \
   ........            ..    |
   ........            ..    |  1 whole pixel
   ........            ..    |
   ........            ..   /
   ++++++++         .. ++
   ++++++++         .. ++
   ++++++++         .. ++
   ++++++++         .. ++
   ++++++++         .. ++
   HHHHHHHH      .. ++ HH
   HHHHHHHH      .. ++ HH
   HHHHHHHH      .. ++ HH
   HHHHHHHH      .. ++ HH
   HHHHHHHH      .. ++ HH

   \______/      \/ \/ \/
    Whole        RR GG BB
    pixels       elements

(Of course, whole-pixel AA also uses the individual R G and B elements, but
doesn't exploit this fact; hence we don't see it and I'm ignoring it in
these 'drawings'.)

Here you also can see why you only get 3x horizontally.



By now you probably realize what's *really* cool and "new" about sub-pixel
rendering: it takes the coolness of the Acorn OS in 1989, and of WarpBlt,
one step further.

Perhaps some of you prefer Smalltalk code to pictures, so here's the
simple-simple version of the algorithm (slooow, no color-balancing etc.):


Form>>#subPixelVer0
  "No color balancing. hardcoded for 16 bit depth. buggy. hg 9/28/1999 09:21"

  | destForm r g b |

  destForm _ Form extent: self extent //(3 at 1) depth: self depth.
  (0 to: self height-1) do: [:y |
   (0 to: self width - 3 by: 3) do: [:x |
    r _ (self pixelValueAt: x at y) >> 10.
    g _ (self pixelValueAt: x+1 at y) >> 10.
    b _ (self pixelValueAt: x+2 at y) >> 10.
    destForm pixelValueAt: x//3 at y
     put: ((r<<10 bitOr: g<<5)  bitOr: b)]].
  ^destForm

Morph>>#subPixelRender
  "World activeHand attachMorph: (SketchMorph new form: (self
subPixelRender))"

  ^(self fullCopy resize: 3 at 1) imageForm subPixelVer0

(resize: does what you think it does. Don't try to run this code anyway as
there are a number of limitations that apply for it to work.)

>  Dan wrote:
>  It should be quite simple to copy Squeak's existing text display loop, but
>  using a font that is N times larger than normal, and using WarpBlt in place
>  of BitBlt.  WarpBlt will do all the sub-pixel alignment and anti-aliasing
>  on the fly (if you give it the right initial values), with no need to save
>  extra fonts or even to allocate a temporary buffer for rendering at the
>  full resolution.

I envision a variant of WarpBlt that takes a source that is N x (3 at 1) times
larger than normal, and that does the 3-gray-pixels-to-1-RGB-pixel trick
above:

     (r<<10 bitOr: g<<5) bitOr: b

>  Tim wrote:
>  Whatever it is, the
>  Apple LCD works best with it and some NEC dispaly looked totally demented!

If you refer to my first sample image, it might be that the NEC uses B-G-R
pixels instead of R-G-B.


If you've come this far, now click here>>  http://www.grc.com/ctwhat.htm


cheers,
Henrik


< = > .

Attachment converted: Anon:subpixel_explain.gif (GIFf/8BIM) (00014B7D)





More information about the Squeak-dev mailing list