the criterion for including surface scaling functions is whether it
can be accelerated in hardware on sufficiently common platforms.
I have a feeling this is the case so this is something we’ll probably
add at some point in the future (probably in 1.3)as usual the hard part isn’t in writing the code but designing a good
api
I think it is a good idea to include scaling functions into SDL. It is a
common operation on 2D images (simple but not trivial to implement). There
are two ways to embed a picture into a screen layout:
1.) the picture dimensions determine the size of the displayed image
2.) the screen layout determines the size of the displayed image
For case 2, there is a need to adapt the picture size. Again, there are
two ways I am aware of:
1.) crop the image
2.) scale the image
I assume that it might be important for some applications to show the
whole picture and fit into a predetermined layout. Thus there is a need
for a scaling operation. I would like to see it in SDL 1.3 if possible.
In Windows GDI, there are two functions taking care of it, StretchBlt and
SetStretchBltMode. The signature of StretchBlt() is
bool StretchBlt(hdc dest, int xorigdest, yorigdest, widthdest, heightdest,
hdc src, int xorigsrc, yorigsrc, widthsrc, heightsrc,
unsigned long rasterop);
There are two surfaces (device contexts in GDI speak), the source and
destination rectangles (x,y,w,h), and a raster operation which controls
the blitter. The needed raster operation in this example is SRCCOPY, where
the source rectangle is directly copied to the destination rectangle (and
stretched, of course). GDI scales the bitmap in memory, then copies the
result
to the destination surface. The color data for patterns/destination
pixels is
merged afterwards. Color format conversion is also done if required.
Is it possible to use the front/back scalers of the graphics
card to speed it up? Video memory is not a problem anymore, I think.
But let’s look at the API which is more important at the moment.
The interface is similar to SDL_BlitSurface(), and it feels to be very
intuitive:
int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect);
I’ll show two versions, the first being simpler than the last:
int SDL_ScaleSurface(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect);
or
int SDL_ScaleSurface(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect,
unsigned long rasterop);
and, to keep it consistent:
int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
SDL_Surface *dst, SDL_Rect *dstrect,
unsigned long rasterop)
[or SDL_ScaleSurfaceROP and SDL_BlitSurfaceROP to keep backward
compatibility]
The raster operations would be supported by the blitter AFAIK, some
examples:
- MERGECOPY: Merges the colors of the source rectangle with the specified
pattern by using the Boolean AND operator - SRCPAINT: Combines the colors of the source and destination rectangles
by using the Boolean OR operator.
I don’t know if it really makes sense to provide the raster operation for
scaling. Some demo coders could comment on this I think.
Another problem is color conversion. There is another call in GDI which
allows color images to be converted nicely:
int SetStretchBltMode(hdc, int StretchMode);
These modes are offered:
- STRETCH_DELETESCANS: simply deletes eliminated pixels
- STRETCH_ANDSCANS: color values of eliminated and existing pixels
are ANDed - STRETCH_ORSCANS: color values of eliminated and existing pixels
are ORed - STRETCH_HALFTONE: maps pixels from src rect into blocks of pixels
in dest rect so that average color over dest block
of pixels approximates color of src pixel
Halftone works very well, a color difference is not visible. I think
it is not hardware supported and very slow, but that is the choice of
the programmer, not of the library. Showing still images allows to
enhance quality at the expense of speed, whereas an animation has to
be fast. So SDL could be used for several different applications,
leaving the policy to the application. A default could opt for speed,
so it would be DELETESCANS in this case.
In SDL, this could be
int SDL_SetScaleSurfaceMode(SDL_Surface *dst, Uint8 flag);
or
int SDL_SetScaleSurfaceMode(SDL_Surface *dst, Uint32 flag);
with ‘flag’ being an enumeration:
SDL_SCALE_DELETESCANS
SDL_SCALE_ANDSCANS
SDL_SCALE_ORSCANS
SDL_SCALE_HALFTONE
Any comments?
Andri HeynatzOn Fri, 16 Mar 2001, “Mattias Engdegard” wrote