aboutsummaryrefslogtreecommitdiffstats
path: root/w3mimg/win/win_w3mimg.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--w3mimg/win/win_w3mimg.cpp131
1 files changed, 25 insertions, 106 deletions
diff --git a/w3mimg/win/win_w3mimg.cpp b/w3mimg/win/win_w3mimg.cpp
index 1864fcb..8099860 100644
--- a/w3mimg/win/win_w3mimg.cpp
+++ b/w3mimg/win/win_w3mimg.cpp
@@ -1,4 +1,4 @@
-/* $Id: win_w3mimg.cpp,v 1.1 2010/12/21 10:13:55 htrb Exp $ */
+/* $Id: win_w3mimg.cpp,v 1.2 2010/12/24 09:52:06 htrb Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -20,7 +20,6 @@
#define OFFSET_X 2
#define OFFSET_Y 2
#define DEBUG
-#define USE_GDIP_CACHED_BITMAP
#ifdef DEBUG
#define THROW_NONE throw()
@@ -41,11 +40,7 @@ struct window_list {
size_t capacity;
};
-#ifdef USE_GDIP_CACHED_BITMAP
typedef Gdiplus::CachedBitmap *cache_handle;
-#else
-typedef HBITMAP cache_handle;
-#endif
class win_image {
private:
win_image(const win_image &); // decl only
@@ -110,12 +105,7 @@ win_image::~win_image() THROW_NONE
{
if (this->cache) {
for (size_t i = 0; i != this->nframe; ++i) {
-#ifdef USE_GDIP_CACHED_BITMAP
delete this->cache[i];
-#else
- if (this->cache[i])
- DeleteObject(this->cache[i]);
-#endif
}
delete[] this->cache;
}
@@ -146,6 +136,7 @@ win_image::load(w3mimg_op *wop, Gdiplus::Bitmap **p_gpbitmap, int *wreturn, int
unsigned int height = gpbitmap->GetHeight();
unsigned int nframe = gpbitmap->GetFrameCount(&Gdiplus::FrameDimensionTime);
unsigned long loopcount = 0;
+ unsigned int first_frame = 0;
if (xi->logfile)
fprintf(xi->logfile, "win_image::load(): size[0]=%ux%u\n", width, height);
@@ -224,12 +215,13 @@ win_image::load(w3mimg_op *wop, Gdiplus::Bitmap **p_gpbitmap, int *wreturn, int
if (xi->logfile)
fprintf(xi->logfile, "win_image::load(): size[%u]=%ux%u\n", nextframe, iw, ih);
}
- // Back to the top
- status = gpbitmap->SelectActiveFrame(&Gdiplus::FrameDimensionTime, 0);
+ // Go to the first frame
+ first_frame = (0 < -wop->max_anim && -wop->max_anim < nframe) ? (nframe + wop->max_anim) : 0;
+ status = gpbitmap->SelectActiveFrame(&Gdiplus::FrameDimensionTime, first_frame);
if (status != Gdiplus::Ok) {
if (xi->logfile)
fprintf(xi->logfile, "win_image::load(): SelectActiveFrame() to %u frame = %d: %s\n",
- 1U, (int)status, gdip_strerror(status));
+ first_frame, (int)status, gdip_strerror(status));
goto last;
}
}
@@ -252,7 +244,7 @@ win_image::load(w3mimg_op *wop, Gdiplus::Bitmap **p_gpbitmap, int *wreturn, int
this->gpbitmap = gpbitmap;
*p_gpbitmap = NULL; // ownership transfer
this->nframe = nframe;
- this->current = 0;
+ this->current = first_frame;
this->tick = 0;
this->loopcount = loopcount;
this->delay = delay;
@@ -283,21 +275,16 @@ win_image::show(w3mimg_op *wop, int sx, int sy, int sw, int sh, int x, int y) TH
int retval = 0;
Gdiplus::Status status = Gdiplus::Ok;
cache_handle newcache = NULL;
-#ifndef USE_GDIP_CACHED_BITMAP
- HDC windc = NULL;
- HDC memdc = NULL;
-#endif
if (xi->logfile)
- fprintf(xi->logfile, "win_image::show(%p, %d, %d, %d, %d, %d, %d) start\n",
- wop, sx, sy, sw, sh, x, y);
+ fprintf(xi->logfile, "win_image::show(%p, %d, %d, %d, %d, %d, %d) start current=%u\n",
+ wop, sx, sy, sw, sh, x, y, this->current);
if (!window_alive(wop))
goto last;
{
int xx = x + wop->offset_x;
int yy = y + wop->offset_y;
-#ifdef USE_GDIP_CACHED_BITMAP
// Prepare the Graphics object for painting
Gdiplus::Graphics graphics(xi->window);
if ((status = graphics.GetLastStatus()) != Gdiplus::Ok)
@@ -307,16 +294,23 @@ win_image::show(w3mimg_op *wop, int sx, int sy, int sw, int sh, int x, int y) TH
if (status != Gdiplus::Ok)
goto gdip_error;
- // Clear the area first as the picture may be transparent
- status = graphics.Clear(Gdiplus::Color(xi->background_pixel));
- if (status != Gdiplus::Ok)
- goto gdip_error;
-
unsigned int retry_count = 2;
do {
if (this->cache[this->current] == NULL) {
// Cache the image
- Gdiplus::CachedBitmap *newcache = new Gdiplus::CachedBitmap(this->gpbitmap, &graphics);
+ Gdiplus::Bitmap tmp_bitmap(sw, sh, &graphics);
+ if ((status = tmp_bitmap.GetLastStatus()) != Gdiplus::Ok)
+ goto gdip_error;
+ Gdiplus::Graphics tmp_graphics(&tmp_bitmap);
+ if ((status = tmp_graphics.GetLastStatus()) != Gdiplus::Ok)
+ goto gdip_error;
+ status = tmp_graphics.Clear(Gdiplus::Color(xi->background_pixel));
+ if (status != Gdiplus::Ok)
+ goto gdip_error;
+ status = tmp_graphics.DrawImage(this->gpbitmap, 0, 0, sw, sh);
+ if (status != Gdiplus::Ok)
+ goto gdip_error;
+ Gdiplus::CachedBitmap *newcache = new Gdiplus::CachedBitmap(&tmp_bitmap, &graphics);
if (newcache == NULL)
goto last;
if ((status = newcache->GetLastStatus()) != Gdiplus::Ok)
@@ -338,92 +332,15 @@ win_image::show(w3mimg_op *wop, int sx, int sy, int sw, int sh, int x, int y) TH
if (retry_count == 0)
goto last;
} while (1);
-#else /* !USE_GDIP_CACHED_BITMAP */
- // Prepare the GC for painting
- windc = GetDC(xi->window);
- if (windc == NULL)
- goto win32_error;
- // Prepare the GC for read/write access to the cached bitmap
- memdc = CreateCompatibleDC(windc);
- if (memdc == NULL)
- goto win32_error;
- unsigned int retry_count = 2;
- do {
- HGDIOBJ hbitmap_save;
- if (this->cache[this->current] == NULL) {
- unsigned int ow = gpbitmap->GetWidth();
- unsigned int oh = gpbitmap->GetHeight();
- // Cache the image
- newcache = CreateCompatibleBitmap(windc, ow, oh);
- if (newcache == NULL)
- goto win32_error;
- SetLastError(ERROR_SUCCESS); // SelectObject sometimes leave the error unchanged
- hbitmap_save = SelectObject(memdc, newcache);
- if (hbitmap_save == NULL || hbitmap_save == HGDI_ERROR)
- goto win32_error;
- Gdiplus::Graphics tmp_graphics(memdc);
- if ((status = tmp_graphics.GetLastStatus()) != Gdiplus::Ok)
- goto gdip_error;
- status = tmp_graphics.Clear(Gdiplus::Color(xi->background_pixel));
- if (status != Gdiplus::Ok)
- goto gdip_error;
- status = tmp_graphics.DrawImage(this->gpbitmap, 0, 0, ow, oh);
- if (status != Gdiplus::Ok)
- goto gdip_error;
- this->cache[this->current] = newcache;
- newcache = NULL; // ownership transfer
- --retry_count;
- } else {
- SetLastError(ERROR_SUCCESS); // SelectObject sometimes leave the error unchanged
- hbitmap_save = SelectObject(memdc, this->cache[this->current]);
- if (hbitmap_save == NULL || hbitmap_save == HGDI_ERROR)
- goto stale_cache;
- }
- // Draw it
- if (BitBlt(windc, xx, yy, sw, sh, memdc, sx, sy, SRCCOPY))
- break;
- // maybe the user altered the display configuration
-stale_cache:
- if (xi->logfile) {
- DWORD ecode = GetLastError();
- char *msg = win32_strerror_alloc(ecode);
- fprintf(xi->logfile, "win_image::show(): stale cache = %u: %s\n",
- (unsigned int)ecode, msg ? msg : "(unknown)");
- LocalFree(msg);
- }
- SetLastError(ERROR_SUCCESS); // SelectObject sometimes leave the error unchanged
- hbitmap_save = SelectObject(memdc, hbitmap_save);
- if (hbitmap_save == NULL || hbitmap_save == HGDI_ERROR)
- goto win32_error;
- DeleteObject(this->cache[this->current]);
- this->cache[this->current] = NULL;
- if (retry_count == 0)
- goto last;
- } while (1);
-#endif /* !USE_GDIP_CACHED_BITMAP */
retval = 1;
}
goto last;
-#ifndef USE_GDIP_CACHED_BITMAP
-win32_error:
- win32_perror(wop, GetLastError(), "win_image::show");
- goto last;
-#endif
gdip_error:
gdip_perror(wop, status, "win_image::show");
goto last;
last:
-#ifdef USE_GDIP_CACHED_BITMAP
delete newcache;
-#else
- if (memdc)
- DeleteDC(memdc);
- if (windc)
- ReleaseDC(xi->window, windc);
- if (newcache)
- DeleteObject(newcache);
-#endif
if (xi->logfile)
fprintf(xi->logfile, "win_image::show() = %d\n", retval);
return retval;
@@ -447,8 +364,10 @@ win_image::animate(w3mimg_op * wop) THROW_NONE
if (this->tick >= MIN_DELAY && this->tick >= this->delay[this->current]) {
this->tick = 0;
unsigned int nextframe = this->current + 1;
+ if (wop->max_anim == nextframe)
+ goto animation_end;
if (nextframe >= this->nframe) {
- if (this->loopcount == 1) // end of the loop
+ if (this->loopcount == 1 || wop->max_anim < 0) // end of the loop
goto animation_end;
nextframe = 0;
}