Is there a (fast) way to shrink the width of a bitmap to 1/3, so that *exactly* every third pixel is copied to the resulting bitmap? (Ie. so that RrrGggBbb are always merged exactly into one pixel RGB.)
In other words, can you make sure that eg. WarpBlt doesn't round the value of 1/3 in some way so that alignment goes bad? One can assume that the source width is an even multiple of 3.
Henrik -
I spent quite a while getting this right for the scaling and rotation operations in class Form. This required care in choosing the source quadrilateral points, but I believe they are bit-perfect now. Did you try those routines exactly as presented? I just now tried out the following demo which picks a rectangle on the screen, blows it up 3x, then shrinks that down by 3x, and displays the result at 0@0...
Display restoreAfter: [[Sensor anyButtonPressed] whileFalse: [(((Form fromDisplay: (Sensor cursorPoint extent: 400@400)) magnifyBy: 3.0) magnifyBy: 1/3.0) display]]
This appears to faithfully recreate the orginal form with no artifacts. By default, it uses smoothing in the shrink direction, but I also patched it to avoid smoothing altogether and the result was equally perfect.
PS. Since a few bugs have been removed, the results are *really* nice, yielding very sharp text even at small sizes (10-12pts). Once that FreeType hinting engine is released, of course ;-)
Sounds cool.
- Dan
Thanks for your responses; speed is now at some 700x without compiling! Next would be a new BitBlt transfer mode...
Dan Ingalls wrote:
I spent quite a while getting this right for the scaling and rotation operations in class Form. This required care in choosing the source quadrilateral points, but I believe they are bit-perfect now. Did you try those routines exactly as presented?
Yes, I tried them, and it seemed to work. However, as absence of proof isn't proof of absence (of misalignment)... It does work as advertised.
Another question: Is there a reason why the BitBlt mode #addRgb adds the three color components, but always leaves alpha at 0 (transparent)? The sum of the alphas (or perhaps always fully opaque) would seem more logical.
Andreas Raab wrote:
You need to use 4x1 -> 1x1 transformation of the form AaaaRrrrGgggBbbb because otherwise the resulting pixel word will not fill the entire 32bit depth range.works since R, G and B levels are equal, since:
Thanks for your advice. You are answering something other than my actual question, but the 32-as-8 bit depth was a neat idea indeed.
What you suggest isn't possible, however, since there are no LCD picture elements for the Alpha component ;-) so this would distort the image. One might do some really advanced surgery to insert alphas between every three pixels just before the final step -- but I don't think it would end up being faster...
However, luckily I didn't realize this at first, so I tried to do it. When it failed I realized that since the source contains grays where r=g=b, you can do it anyway with 3x1!! If you take every third byte, you get:
ArgB arGb aRgb ArgB -> ABGR ABGR etc. instead of ARGB ARGB ..., but since B=G=R for each of these, BGR is equivalent to if RGB were extracted instead! Note how ArgB picks both alpha and the first color component from the first of every three pixels! Incredible coincidence, or?? A neat trick, still.
And Andreas, btw, regarding using PostScript (cubic) font outlines, you wrote that they would be slow to convert to squared ones. But you only do this once, ie. on import, right? So is there any other problem?
Henrik
< = > .
squeak-dev@lists.squeakfoundation.org