刚开始实现在symbian上,后来在Brew上再实现了一次。效率不错。不过现在都使用opengles来做了,这种软件的方法只能留给自己做个纪念。
void drawScaledImage(Image *image, int adx, int ady, int awidth, int aheight, int asx, int asy, int aswidth, int asheight)
{
int dx = adx;
int dy = ady;
int width = awidth;
int height = aheight;
int sx = asx;
int sy = asy;
int swidth = aswidth;
int sheight = asheight;
if (image == NULL || sx >= image->getWidth() || sy >= image->getHeight() || width < = 0 || height <= 0 || sx + swidth <= 0 || sy + sheight<= 0 || swidth <= 0 || sheight <= 0)
return;
dx += transX;
dy += transY;
if (dx >= clip[0] + clip[2] || dy >= clip[1] + clip[3] || dx + width < = clip[0] || dy + height <= clip[1])
return;
if ( asx + aswidth > image->getWidth())
swidth= image->getWidth() - asx;
if (asy + asheight > image->getHeight())
sheight = image->getHeight() -asy;
int zoomlengthy = height + 1;
int zoomlengthx = width + 1;
int* tablex = (int*)static_tablex;
int* tabley = (int*)static_tabley;
ZoomLine(sx, 0, swidth + sx, zoomlengthx, tablex );
ZoomLine(sy, 0, sheight + sy, zoomlengthy, tabley );
int startx = sx;
int starty = sy;
int save_dx = dx;
int save_dy = dy;
if (sx < 0) {
startx = 0;
for (int i = 0; i < zoomlengthx; i++) {
if (tablex[i] >= startx) {
dx += i;
width -= i;
break;
}
}
}
if (sy < 0) {
starty = 0;
for (int i = 0; i < zoomlengthy; i++) {
if(tabley[i] >= starty) {
dy += i;
height -= i;
break;
}
}
}
int endx = sx + swidth;
int endy = sy + sheight;
if (endx > image->getWidth()) {
endx = image->getWidth();
for (int i = zoomlengthx - 2; i >= 0; i--) {
if (tablex[i] < = endx){
if(width > i)
width = i;
break;
}
}
}
if (endy > image->getHeight()) {
endy = image->getHeight();
for (int i = zoomlengthy - 2; i >= 0; i--) {
if(tabley[i] < = endy) {
if( height > i)
height = i;
break;
}
}
}
IBitmap *pback = IDISPLAY_GetDestination(m_pDisplay);
IDIB* pDib = NULL;
IBITMAP_QueryInterface( pback, AEECLSID_DIB, (void**)&pDib);
IBITMAP_Release(pback);///*iBack->m_pIDIB*/;
int startx_dx = dx;
int starty_dy = dy;
if (startx_dx < clip[0]) {
startx = tablex[clip[0] - save_dx];
width -= clip[0] - startx_dx;
startx_dx = clip[0];
}
if (starty_dy < clip[1]) {
starty = tabley[clip[1] - save_dy];
height -= clip[1] - dy;
starty_dy = clip[1];
}
int endx_dx = startx_dx + width;
if (endx_dx > clip[0] + clip[2]) {
endx_dx = clip[0] + clip[2];
endx = tablex[endx_dx - save_dx];
}
int endy_dy = starty_dy + height;
if (endy_dy > clip[1] + clip[3]) {
endy_dy = clip[1] + clip[3];
endy = tabley[endy_dy - save_dy];
}
unsigned short *psrc = (unsigned short*)((unsigned char*)(image->m_pIDIB->pBmp) + image->m_pIDIB->nPitch * starty /*+ (startx < < 1)*/);
unsigned short *pdes = (unsigned short*)((unsigned char*)(pDib->pBmp) + pDib->nPitch * starty_dy + (startx_dx < < 1));
unsigned short *pend = (unsigned short*)((unsigned char*)(image->m_pIDIB->pBmp) + image->m_pIDIB->nPitch * endy + (endx < < 1));
int srcstep = (image->m_pIDIB->nPitch >> 1);// - (endx - startx);
int desstep = (pDib->nPitch >> 1) - (endx_dx - startx_dx);
for (int i = starty_dy; i < endy_dy; i++, psrc += (tabley[i-save_dy] - tabley[i-save_dy-1]) * srcstep, pdes += desstep) {
for (int j = startx_dx; j < endx_dx; j++, pdes++) {
if( psrc[tablex[j-save_dx]] != image->m_pIDIB->ncTransparent )
*pdes = psrc[tablex[j-save_dx]];
}
}
IDIB_Release(pDib);
}
void Graphics::ZoomLine(int aStartX, int aStartY, int aEndX, int aEndY, int *aTable)
{
int t, distance;
int x = 0;
int y = 0;
int iDeltaX = aEndX - aStartX;
int iDeltaY = aEndY - aStartY;
int incx, incy;
if( iDeltaX > 0 )
incx = 1;
else if( iDeltaX == 0 )
incx = 0;
else
incx = - 1;
if( iDeltaY > 0 )
incy = 1;
else if( iDeltaY == 0 )
incy = 0;
else
incy = - 1;
iDeltaX = iDeltaX < 0 ? -iDeltaX : iDeltaX;
iDeltaY = iDeltaY < 0 ? -iDeltaY : iDeltaY;
if( iDeltaX > iDeltaY )
distance = iDeltaX;
else
distance = iDeltaY;
for( t = 0; t < distance; t++ )
{
aTable[aStartY] = aStartX;
x += iDeltaX;
y += iDeltaY;
if( x > distance )
x -= distance, aStartX += incx;
if( y > distance )
y -= distance, aStartY += incy;
}
}