static int _AniAva_LoadAvatarFromImage(TCHAR * szFileName, int width, int height, ANIAVATARIMAGEINFO * pRetAII) { ANIAVA_INFO aai={0}; ANIAVA_INFO * paai=NULL; BOOL fNeedInsertToList=FALSE; int idx=0; aai.tcsFilename=szFileName; aai.FrameSize.cx=width; aai.FrameSize.cy=height; if (!li.List_GetIndex(AniAva.AniAvatarList,(void*)&aai,&idx)) idx=-1; if (idx==-1) //item not present in list { HBITMAP hBitmap=NULL; HDC hTempDC; HBITMAP hOldBitmap; HDC hNewDC; HBITMAP hNewBmp; HBITMAP hNewOldBmp; int newWidth; int newHeight; paai=(ANIAVA_INFO *)mir_calloc(sizeof(ANIAVA_INFO)); paai->tcsFilename=mir_tstrdup(szFileName); paai->dwAvatarUniqId=rand(); fNeedInsertToList=TRUE; //get image strip GDIPlus_ExtractAnimatedGIF(szFileName, width, height, &hBitmap, &(paai->pFrameDelays), &(paai->nFrameCount), &(paai->FrameSize)); //copy image to temp DC hTempDC=CreateCompatibleDC(NULL); hOldBitmap=(HBITMAP)SelectObject(hTempDC,hBitmap); //lets create hNewDC /* newWidth=max(paai->FrameSize.cx*paai->nFrameCount,AniAva.width); newHeight=AniAva.height+paai->FrameSize.cy; */ newWidth=AniAva.width+paai->FrameSize.cx*paai->nFrameCount; newHeight=max(paai->FrameSize.cy,AniAva.height); hNewDC=CreateCompatibleDC(NULL); hNewBmp=ske_CreateDIB32(newWidth,newHeight); hNewOldBmp=(HBITMAP)SelectObject(hNewDC,hNewBmp); _AniAva_PausePainting(); GdiFlush(); // copy from old and from new strip BitBlt(hNewDC,0,0,AniAva.width,AniAva.height,AniAva.hAniAvaDC,0,0, SRCCOPY); BitBlt(hNewDC,AniAva.width,0,paai->FrameSize.cx*paai->nFrameCount,paai->FrameSize.cy,hTempDC,0,0, SRCCOPY); paai->nStripTop=AniAva.width; GdiFlush(); //remove temp DC SelectObject(hTempDC,hOldBitmap); DeleteObject(hNewBmp); DeleteDC(hTempDC); DeleteObject(hBitmap); //delete old _AniAva_RemoveAniAvaDC(&AniAva); //setNewDC; AniAva.hAniAvaDC =hNewDC; AniAva.hAniAvaBitmap =hNewBmp; AniAva.hAniAvaOldBitmap =hNewOldBmp; AniAva.width =newWidth; AniAva.height =newHeight; GdiFlush(); _AniAva_ResumePainting(); } else { paai=(ANIAVA_INFO *)AniAva.AniAvatarList->items[idx]; } if (paai) { paai->nRefCount++; pRetAII->nFramesCount=paai->nFrameCount; pRetAII->pFrameDelays=paai->pFrameDelays; pRetAII->ptImagePos.x=paai->nStripTop; pRetAII->ptImagePos.y=0; pRetAII->szSize=paai->FrameSize; if (fNeedInsertToList) { //add to list int idx=AniAva.AniAvatarList->realCount; li.List_GetIndex(AniAva.AniAvatarList, paai,&idx); li.List_Insert(AniAva.AniAvatarList, (void*)paai, idx); } return paai->dwAvatarUniqId; } return 0; }
void GifAvatar::draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options) { if (!av || (w <= 0) || (h <= 0)) return; if (!frameCount || !frameDelays || !hBitmap || (cachedWidth != w) || (cachedHeight != h)) { cachedWidth = w; cachedHeight = h; if (frameDelays) { mir_free(frameDelays); frameDelays = NULL; } if (hBitmap) DeleteObject(hBitmap); GDIPlus_ExtractAnimatedGIF(av->szFilename, w, h, &hBitmap, &frameDelays, &frameCount, &frameSize); } if (!frameCount) return; HRGN rgn; if (options->avatarRadius) { rgn = CreateRoundRectRgn(x, y, x+w, y+h, 2 * options->avatarRadius, 2 * options->avatarRadius); SelectClipRgn(bmp->getDC(), rgn); } else { rgn = CreateRectRgn(x, y, x+w, y+h); } HDC hdcTmp = CreateCompatibleDC(bmp->getDC()); SelectObject(hdcTmp, hBitmap); SetStretchBltMode(bmp->getDC(), HALFTONE); if (av->dwFlags & AVS_PREMULTIPLIED) { BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, bf); if (options->avatarBorders && options->avatarPNGBorders) { HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder); bmp->saveAlpha(x, y, w, h); FrameRgn(bmp->getDC(), rgn, hbr, 1, 1); DeleteObject(hbr); bmp->restoreAlpha(x, y, w, h); } } else { bmp->saveAlpha(x, y, w, h); StretchBlt(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, SRCCOPY); if (options->avatarBorders) { HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder); FrameRgn(bmp->getDC(), rgn, hbr, 1, 1); DeleteObject(hbr); } bmp->restoreAlpha(x, y, w, h); } DeleteObject(rgn); SelectClipRgn(bmp->getDC(), NULL); DeleteDC(hdcTmp); activeFrame = (activeFrame + 1) % frameCount; }