From 7b02d76ad8b01193cb3f6902a2bca7897cddb4e1 Mon Sep 17 00:00:00 2001 From: avolkov Date: Tue, 29 Dec 2009 14:36:30 +0000 Subject: [PATCH] Add CopyFrameRect() gfxlib call; passing a NULL FRAME is valid; repair a few TFB_Image locking violations; assert on working with off-screen FRAMEs git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3487 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/libs/gfxlib.h | 1 + sc2/src/libs/graphics/drawable.c | 95 +++++++++++++++++++++++++------- sc2/src/libs/graphics/tfb_draw.c | 23 +++++++- sc2/src/libs/graphics/tfb_draw.h | 2 + 4 files changed, 101 insertions(+), 20 deletions(-) diff --git a/sc2/src/libs/gfxlib.h b/sc2/src/libs/gfxlib.h index ef1130f03..48455dbb9 100644 --- a/sc2/src/libs/gfxlib.h +++ b/sc2/src/libs/gfxlib.h @@ -404,6 +404,7 @@ extern FRAME SetRelFrameIndex (FRAME Frame, SIZE FrameOffs); extern FRAME SetEquFrameIndex (FRAME DstFrame, FRAME SrcFrame); extern FRAME IncFrameIndex (FRAME Frame); extern FRAME DecFrameIndex (FRAME Frame); +extern DRAWABLE CopyFrameRect (FRAME Frame, const RECT *area); extern DRAWABLE CloneFrame (FRAME Frame); extern DRAWABLE RotateFrame (FRAME Frame, int angle_deg); extern DRAWABLE RescaleFrame (FRAME, int width, int height); diff --git a/sc2/src/libs/graphics/drawable.c b/sc2/src/libs/graphics/drawable.c index 8499583a4..9766bc7c7 100644 --- a/sc2/src/libs/graphics/drawable.c +++ b/sc2/src/libs/graphics/drawable.c @@ -248,6 +248,11 @@ RotateFrame (FRAME Frame, int angle_deg) double d; double angle = angle_deg * M_PI / 180; + if (!Frame) + return NULL; + + assert (Frame->Type != SCREEN_DRAWABLE); + Drawable = request_drawable (1, RAM_DRAWABLE, WANT_PIXMAP, 0, 0); if (!Drawable) return 0; @@ -283,17 +288,44 @@ RotateFrame (FRAME Frame, int angle_deg) // color.a is ignored void -SetFrameTransparentColor (FRAME Frame, Color color) +SetFrameTransparentColor (FRAME frame, Color color) { - TFB_DrawCanvas_SetTransparentColor (Frame->image->NormalImg, color, - FALSE); + TFB_Image *img; + + if (!frame) + return; + + assert (frame->Type != SCREEN_DRAWABLE); + + img = frame->image; + LockMutex (img->mutex); + + // TODO: This should defer to TFB_DrawImage instead + TFB_DrawCanvas_SetTransparentColor (img->NormalImg, color, FALSE); + + UnlockMutex (img->mutex); } Color GetFramePixel (FRAME frame, POINT pixelPt) { - return TFB_DrawCanvas_GetPixel (frame->image->NormalImg, - pixelPt.x, pixelPt.y); + TFB_Image *img; + Color ret; + + if (!frame) + return BUILD_COLOR_RGBA (0, 0, 0, 0); + + assert (frame->Type != SCREEN_DRAWABLE); + + img = frame->image; + LockMutex (img->mutex); + + // TODO: This should defer to TFB_DrawImage instead + ret = TFB_DrawCanvas_GetPixel (img->NormalImg, pixelPt.x, pixelPt.y); + + UnlockMutex (img->mutex); + + return ret; } static FRAME @@ -317,39 +349,53 @@ makeMatchingFrame (FRAME frame, int width, int height) return newFrame; } +// Creates an new DRAWABLE containing a copy of specified FRAME's rect +// Source FRAME must not be a SCREEN_DRAWABLE +DRAWABLE +CopyFrameRect (FRAME frame, const RECT *area) +{ + FRAME newFrame; + POINT nullPt = MAKE_POINT (0, 0); + + if (!frame) + return NULL; + + assert (frame->Type != SCREEN_DRAWABLE); + + newFrame = makeMatchingFrame (frame, area->extent.width, + area->extent.height); + if (!newFrame) + return NULL; + + TFB_DrawImage_CopyRect (frame->image, area, newFrame->image, nullPt); + + return ReleaseDrawable (newFrame); +} + // Creates an new DRAWABLE mostly identical to specified FRAME +// Source FRAME must not be a SCREEN_DRAWABLE DRAWABLE CloneFrame (FRAME frame) { FRAME newFrame; - TFB_Image *img; - TFB_Canvas src, dst; RECT r; if (!frame) return NULL; + assert (frame->Type != SCREEN_DRAWABLE); + GetFrameRect (frame, &r); r.corner.x = 0; r.corner.y = 0; - newFrame = makeMatchingFrame (frame, r.extent.width, r.extent.height); + newFrame = CaptureDrawable (CopyFrameRect (frame, &r)); if (!newFrame) return NULL; // copy the hot-spot newFrame->HotSpot = frame->HotSpot; - img = frame->image; - LockMutex (img->mutex); - - // copy the pixels - src = img->NormalImg; - dst = newFrame->image->NormalImg; - TFB_DrawCanvas_CopyRect (src, &r, dst, MAKE_POINT (0, 0)); - - UnlockMutex (img->mutex); - return ReleaseDrawable (newFrame); } @@ -365,6 +411,8 @@ RescaleFrame (FRAME frame, int width, int height) if (!frame) return NULL; + assert (frame->Type != SCREEN_DRAWABLE); + newFrame = makeMatchingFrame (frame, width, height); if (!newFrame) return NULL; @@ -375,7 +423,8 @@ RescaleFrame (FRAME frame, int width, int height) img = frame->image; LockMutex (img->mutex); - + // NOTE: We do not lock the target image because nothing has a + // reference to it yet! src = img->NormalImg; dst = newFrame->image->NormalImg; TFB_DrawCanvas_Rescale_Nearest (src, dst, -1, NULL, NULL, NULL); @@ -393,6 +442,8 @@ ReadFramePixelColors (FRAME frame, Color *pixels, int width, int height) if (!frame) return FALSE; + assert (frame->Type != SCREEN_DRAWABLE); + // TODO: Do we need to lock the img->mutex here? img = frame->image; return TFB_DrawCanvas_GetPixelColors (img->NormalImg, pixels, @@ -408,6 +459,8 @@ WriteFramePixelColors (FRAME frame, const Color *pixels, int width, int height) if (!frame) return FALSE; + assert (frame->Type != SCREEN_DRAWABLE); + // TODO: Do we need to lock the img->mutex here? img = frame->image; return TFB_DrawCanvas_SetPixelColors (img->NormalImg, pixels, @@ -422,6 +475,8 @@ ReadFramePixelIndexes (FRAME frame, BYTE *pixels, int width, int height) if (!frame) return FALSE; + assert (frame->Type != SCREEN_DRAWABLE); + // TODO: Do we need to lock the img->mutex here? img = frame->image; return TFB_DrawCanvas_GetPixelIndexes (img->NormalImg, pixels, @@ -437,6 +492,8 @@ WriteFramePixelIndexes (FRAME frame, const BYTE *pixels, int width, int height) if (!frame) return FALSE; + assert (frame->Type != SCREEN_DRAWABLE); + // TODO: Do we need to lock the img->mutex here? img = frame->image; return TFB_DrawCanvas_SetPixelIndexes (img->NormalImg, pixels, diff --git a/sc2/src/libs/graphics/tfb_draw.c b/sc2/src/libs/graphics/tfb_draw.c index fff338ec0..fc752ec50 100644 --- a/sc2/src/libs/graphics/tfb_draw.c +++ b/sc2/src/libs/graphics/tfb_draw.c @@ -458,6 +458,27 @@ BOOLEAN TFB_DrawImage_Intersect (TFB_Image *img1, POINT img1org, TFB_Image *img2, POINT img2org, const RECT *interRect) { - return TFB_DrawCanvas_Intersect (img1->NormalImg, img1org, + BOOLEAN ret; + + LockMutex (img1->mutex); + LockMutex (img2->mutex); + ret = TFB_DrawCanvas_Intersect (img1->NormalImg, img1org, img2->NormalImg, img2org, interRect); + UnlockMutex (img2->mutex); + UnlockMutex (img1->mutex); + + return ret; +} + +void +TFB_DrawImage_CopyRect (TFB_Image *source, const RECT *srcRect, + TFB_Image *target, POINT dstPt) +{ + LockMutex (source->mutex); + LockMutex (target->mutex); + TFB_DrawCanvas_CopyRect (source->NormalImg, srcRect, + target->NormalImg, dstPt); + target->dirty = TRUE; + UnlockMutex (target->mutex); + UnlockMutex (source->mutex); } diff --git a/sc2/src/libs/graphics/tfb_draw.h b/sc2/src/libs/graphics/tfb_draw.h index 8a6850411..11de5b03e 100644 --- a/sc2/src/libs/graphics/tfb_draw.h +++ b/sc2/src/libs/graphics/tfb_draw.h @@ -107,6 +107,8 @@ void TFB_DrawImage_Delete (TFB_Image *image); void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type); BOOLEAN TFB_DrawImage_Intersect (TFB_Image *img1, POINT img1org, TFB_Image *img2, POINT img2org, const RECT *interRect); +void TFB_DrawImage_CopyRect (TFB_Image *source, const RECT *srcRect, + TFB_Image *target, POINT dstPt); void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, Color color, DrawMode, TFB_Image *target);