From fb48357a5467bba9d8cef401ee2dff3656bc0123 Mon Sep 17 00:00:00 2001 From: avolkov Date: Mon, 7 Dec 2009 23:23:46 +0000 Subject: [PATCH] Make context cliprect + foreground frame hotspot semantics actually sane; do not hack _CurFramePtr->HotSpot git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3401 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/libs/gfxlib.h | 5 +- sc2/src/libs/graphics/context.h | 3 + sc2/src/libs/graphics/drawable.h | 6 +- sc2/src/libs/graphics/font.c | 8 +- sc2/src/libs/graphics/frame.c | 131 ++++++++++++++----------------- sc2/src/libs/graphics/tfb_prim.c | 51 ++++++------ sc2/src/libs/graphics/tfb_prim.h | 16 ++-- 7 files changed, 106 insertions(+), 114 deletions(-) diff --git a/sc2/src/libs/gfxlib.h b/sc2/src/libs/gfxlib.h index df4e828b9..73b3ba72d 100644 --- a/sc2/src/libs/gfxlib.h +++ b/sc2/src/libs/gfxlib.h @@ -247,8 +247,11 @@ extern Color GetContextBackGroundColor (void); extern FRAME SetContextFGFrame (FRAME Frame); extern FRAME GetContextFGFrame (void); extern BOOLEAN SetContextClipping (BOOLEAN ClipStatus); +// Context cliprect defines the drawing bounds. Additionally, all +// drawing positions (x,y) are relative to the cliprect corner. extern BOOLEAN SetContextClipRect (RECT *pRect); extern BOOLEAN GetContextClipRect (RECT *pRect); + extern TIME_VALUE DrawablesIntersect (INTERSECT_CONTROL *pControl0, INTERSECT_CONTROL *pControl1, TIME_VALUE max_time_val); extern void DrawStamp (STAMP *pStamp); @@ -264,7 +267,6 @@ extern void DrawBatch (PRIMITIVE *pBasePrim, PRIM_LINKS PrimLinks, extern void BatchGraphics (void); extern void UnbatchGraphics (void); extern void FlushGraphics (void); -extern void ClearBackGround (RECT *pClipRect); extern void ClearDrawable (void); #ifdef DEBUG extern CONTEXT CreateContextAux (const char *name); @@ -297,6 +299,7 @@ extern DRAWABLE LoadDisplayPixmap (RECT *area, FRAME frame); extern FRAME SetContextFontEffect (FRAME EffectFrame); extern FONT SetContextFont (FONT Font); extern BOOLEAN DestroyFont (FONT FontRef); +// The returned pRect is relative to the context drawing origin extern BOOLEAN TextRect (TEXT *pText, RECT *pRect, BYTE *pdelta); extern BOOLEAN GetContextFontLeading (SIZE *pheight); extern BOOLEAN GetContextFontLeadingWidth (SIZE *pwidth); diff --git a/sc2/src/libs/graphics/context.h b/sc2/src/libs/graphics/context.h index 8d3764c35..88ea5f01f 100644 --- a/sc2/src/libs/graphics/context.h +++ b/sc2/src/libs/graphics/context.h @@ -152,5 +152,8 @@ extern GRAPHICS_STATUS _GraphicsStatusFlags; (_GraphicsStatusFlags & (GRAPHICS_STATUS)(GRAPHICS_ACTIVE \ | GRAPHICS_VISIBLE)) +// pValidRect or origin may be NULL +BOOLEAN GetContextValidRect (RECT *pValidRect, POINT *origin); + #endif /* _CONTEXT_H */ diff --git a/sc2/src/libs/graphics/drawable.h b/sc2/src/libs/graphics/drawable.h index b34815296..626ef326e 100644 --- a/sc2/src/libs/graphics/drawable.h +++ b/sc2/src/libs/graphics/drawable.h @@ -57,6 +57,7 @@ struct drawable_desc #define GetFrameWidth(f) ((f)->Bounds.width) #define GetFrameHeight(f) ((f)->Bounds.height) +#define GetFrameBounds(f) ((f)->Bounds) #define SetFrameBounds(f,w,h) \ ((f)->Bounds.width=(w), \ ((f))->Bounds.height=(h)) @@ -84,11 +85,10 @@ extern INTERSECT_CODE _clip_line (RECT *pClipRect, BRESENHAM_LINE *pLine); extern void *_GetCelData (uio_Stream *fp, DWORD length); extern BOOLEAN _ReleaseCelData (void *handle); -extern STAMP _save_stamp; extern FRAME _CurFramePtr; -extern void _rect_blt (RECT *pClipRect, PRIMITIVE *PrimPtr); -extern void _text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr); +// ClipRect is relative to ctxOrigin +extern void _text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr, POINT ctxOrigin); #endif /* _DRAWABLE_H */ diff --git a/sc2/src/libs/graphics/font.c b/sc2/src/libs/graphics/font.c index 2d263e20b..80afbbf39 100644 --- a/sc2/src/libs/graphics/font.c +++ b/sc2/src/libs/graphics/font.c @@ -58,7 +58,6 @@ font_DrawText (TEXT *lpText) DrawBatch (&_locPrim, 0, BATCH_SINGLE); } - /* Draw the stroke by drawing the same text in the * background color one pixel shifted to all 4 directions. */ @@ -225,7 +224,7 @@ TextRect (TEXT *lpText, RECT *pRect, BYTE *pdelta) } void -_text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr) +_text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr, POINT ctxOrigin) { FONT FontPtr; @@ -244,7 +243,7 @@ _text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr) return; TextPtr = &PrimPtr->Object.Text; - origin.x = _save_stamp.origin.x; + origin.x = pClipRect->corner.x; origin.y = TextPtr->baseline.y; num_chars = TextPtr->CharCount; if (num_chars == 0) @@ -277,10 +276,9 @@ _text_blt (RECT *pClipRect, PRIMITIVE *PrimPtr) r.corner.y = origin.y - fontChar->HotSpot.y; r.extent.width = fontChar->disp.width; r.extent.height = fontChar->disp.height; - _save_stamp.origin = r.corner; if (BoxIntersect (&r, pClipRect, &r)) { - TFB_Prim_FontChar (&origin, fontChar, backing); + TFB_Prim_FontChar (origin, fontChar, backing, ctxOrigin); } origin.x += fontChar->disp.width; diff --git a/sc2/src/libs/graphics/frame.c b/sc2/src/libs/graphics/frame.c index f701f593b..29a60bc03 100644 --- a/sc2/src/libs/graphics/frame.c +++ b/sc2/src/libs/graphics/frame.c @@ -48,43 +48,51 @@ typedef struct INTERNAL_PRIM_DESC Object; } INTERNAL_PRIMITIVE; -STAMP _save_stamp; -static BOOLEAN -GetFrameValidRect (RECT *pValidRect, HOT_SPOT *pOldHot) +// pValidRect or origin may be NULL +BOOLEAN +GetContextValidRect (RECT *pValidRect, POINT *origin) { - COORD hx, hy; - HOT_SPOT OldHot; + RECT tempRect; + POINT tempPt; + + if (!pValidRect) + pValidRect = &tempRect; + if (!origin) + origin = &tempPt; + + // Start with a rect the size of foreground frame + pValidRect->corner.x = 0; + pValidRect->corner.y = 0; + pValidRect->extent = GetFrameBounds (_CurFramePtr); + *origin = _CurFramePtr->HotSpot; - OldHot = _CurFramePtr->HotSpot; - hx = OldHot.x; - hy = OldHot.y; - pValidRect->corner.x = hx; - pValidRect->corner.y = hy; - pValidRect->extent.width = GetFrameWidth (_CurFramePtr); - pValidRect->extent.height = GetFrameHeight (_CurFramePtr); if (_pCurContext->ClipRect.extent.width) { + // If the cliprect is completely outside of the valid frame + // bounds we have nothing to draw if (!BoxIntersect (&_pCurContext->ClipRect, pValidRect, pValidRect)) return (FALSE); - hx -= _pCurContext->ClipRect.corner.x; - hy -= _pCurContext->ClipRect.corner.y; - pValidRect->corner.x += hx; - pValidRect->corner.y += hy; - _CurFramePtr->HotSpot = MAKE_HOT_SPOT (hx, hy); + // Foreground frame hotspot defines a drawing position offset + // WRT the context cliprect + origin->x += _pCurContext->ClipRect.corner.x; + origin->y += _pCurContext->ClipRect.corner.y; } - *pOldHot = OldHot; return (TRUE); } -void +static void ClearBackGround (RECT *pClipRect) { + RECT clearRect; Color color = _get_context_bg_color (); - TFB_Prim_FillRect (pClipRect, color); + clearRect.corner.x = 0; + clearRect.corner.y = 0; + clearRect.extent = pClipRect->extent; + TFB_Prim_FillRect (&clearRect, color, pClipRect->corner); } void @@ -92,9 +100,9 @@ DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks, BATCH_FLAGS BatchFlags) { RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, &origin)) { COUNT CurIndex; PRIM_LINKS OldLinks; @@ -145,43 +153,39 @@ DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks, { case POINT_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Point (&lpWorkPrim->Object.Point, color); + TFB_Prim_Point (&lpWorkPrim->Object.Point, color, origin); break; case STAMP_PRIM: - TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp); + TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp, origin); break; case STAMPFILL_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, color); + TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, color, + origin); break; case LINE_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Line (&lpWorkPrim->Object.Line, color); + TFB_Prim_Line (&lpWorkPrim->Object.Line, color, origin); break; case TEXT_PRIM: - if (!TextRect (&lpWorkPrim->Object.Text, - &ClipRect, NULL)) + if (!TextRect (&lpWorkPrim->Object.Text, &ClipRect, NULL)) continue; - - _save_stamp.origin = ClipRect.corner; - - _text_blt (&ClipRect, lpWorkPrim); + // ClipRect is relative to origin + _text_blt (&ClipRect, lpWorkPrim, origin); break; case RECT_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color); + TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color, origin); break; case RECTFILL_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color); + TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color, origin); break; } } UnbatchGraphics (); - _CurFramePtr->HotSpot = OldHot; - if (BatchFlags & BATCH_SINGLE) SetPrimLinks (lpBasePrim, GetPredLink (OldLinks), GetSuccLink (OldLinks)); @@ -192,98 +196,81 @@ void ClearDrawable (void) { RECT ValidRect; - HOT_SPOT OldHot; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, NULL)) { - BatchGraphics (); ClearBackGround (&ValidRect); - UnbatchGraphics (); - - _CurFramePtr->HotSpot = OldHot; } } void DrawPoint (POINT *lpPoint) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Point (lpPoint, color); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_Point (lpPoint, color, origin); } } void DrawRectangle (RECT *lpRect) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Rect (lpRect, color); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_Rect (lpRect, color, origin); } } void DrawFilledRectangle (RECT *lpRect) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_FillRect (lpRect, color); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_FillRect (lpRect, color, origin); } } void DrawLine (LINE *lpLine) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Line (lpLine, color); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_Line (lpLine, color, origin); } } void DrawStamp (STAMP *stmp) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { - TFB_Prim_Stamp (stmp); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_Stamp (stmp, origin); } } void DrawFilledStamp (STAMP *stmp) { - RECT ValidRect; - HOT_SPOT OldHot; + POINT origin; - if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) + if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_StampFill (stmp, color); - _CurFramePtr->HotSpot = OldHot; + TFB_Prim_StampFill (stmp, color, origin); } } diff --git a/sc2/src/libs/graphics/tfb_prim.c b/sc2/src/libs/graphics/tfb_prim.c index 80a2cfbbd..cf213f320 100644 --- a/sc2/src/libs/graphics/tfb_prim.c +++ b/sc2/src/libs/graphics/tfb_prim.c @@ -29,12 +29,12 @@ #include "libs/log.h" void -TFB_Prim_Point (POINT *p, Color color) +TFB_Prim_Point (POINT *p, Color color, POINT ctxOrigin) { RECT r; - r.corner.x = p->x - _CurFramePtr->HotSpot.x; - r.corner.y = p->y - _CurFramePtr->HotSpot.y; + r.corner.x = p->x + ctxOrigin.x; + r.corner.y = p->y + ctxOrigin.y; r.extent.width = r.extent.height = 1; if (_CurFramePtr->Type == SCREEN_DRAWABLE) @@ -44,7 +44,7 @@ TFB_Prim_Point (POINT *p, Color color) } void -TFB_Prim_Rect (RECT *r, Color color) +TFB_Prim_Rect (RECT *r, Color color, POINT ctxOrigin) { RECT arm; int gscale; @@ -52,30 +52,30 @@ TFB_Prim_Rect (RECT *r, Color color) arm = *r; arm.extent.width = r->extent.width; arm.extent.height = 1; - TFB_Prim_FillRect (&arm, color); + TFB_Prim_FillRect (&arm, color, ctxOrigin); arm.extent.height = r->extent.height; arm.extent.width = 1; - TFB_Prim_FillRect (&arm, color); + TFB_Prim_FillRect (&arm, color, ctxOrigin); // rounding error correction here arm.corner.x += ((r->extent.width * gscale + (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY) - 1; - TFB_Prim_FillRect (&arm, color); + TFB_Prim_FillRect (&arm, color, ctxOrigin); arm.corner.x = r->corner.x; arm.corner.y += ((r->extent.height * gscale + (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY) - 1; arm.extent.width = r->extent.width; arm.extent.height = 1; - TFB_Prim_FillRect (&arm, color); + TFB_Prim_FillRect (&arm, color, ctxOrigin); } void -TFB_Prim_FillRect (RECT *r, Color color) +TFB_Prim_FillRect (RECT *r, Color color, POINT ctxOrigin) { RECT rect; int gscale; - rect.corner.x = r->corner.x - _CurFramePtr->HotSpot.x; - rect.corner.y = r->corner.y - _CurFramePtr->HotSpot.y; + rect.corner.x = r->corner.x + ctxOrigin.x; + rect.corner.y = r->corner.y + ctxOrigin.y; rect.extent.width = r->extent.width; rect.extent.height = r->extent.height; @@ -97,14 +97,14 @@ TFB_Prim_FillRect (RECT *r, Color color) } void -TFB_Prim_Line (LINE *line, Color color) +TFB_Prim_Line (LINE *line, Color color, POINT ctxOrigin) { int x1, y1, x2, y2; - x1=line->first.x - _CurFramePtr->HotSpot.x; - y1=line->first.y - _CurFramePtr->HotSpot.y; - x2=line->second.x - _CurFramePtr->HotSpot.x; - y2=line->second.y - _CurFramePtr->HotSpot.y; + x1=line->first.x + ctxOrigin.x; + y1=line->first.y + ctxOrigin.y; + x2=line->second.x + ctxOrigin.x; + y2=line->second.y + ctxOrigin.y; if (_CurFramePtr->Type == SCREEN_DRAWABLE) TFB_DrawScreen_Line (x1, y1, x2, y2, color, TFB_SCREEN_MAIN); @@ -113,7 +113,7 @@ TFB_Prim_Line (LINE *line, Color color) } void -TFB_Prim_Stamp (STAMP *stmp) +TFB_Prim_Stamp (STAMP *stmp, POINT ctxOrigin) { int x, y; FRAME SrcFramePtr; @@ -140,8 +140,8 @@ TFB_Prim_Stamp (STAMP *stmp) LockMutex (img->mutex); img->NormalHs = SrcFramePtr->HotSpot; - x = stmp->origin.x - _CurFramePtr->HotSpot.x; - y = stmp->origin.y - _CurFramePtr->HotSpot.y; + x = stmp->origin.x + ctxOrigin.x; + y = stmp->origin.y + ctxOrigin.y; if (TFB_DrawCanvas_IsPaletted(img->NormalImg) && img->colormap_index != -1) { @@ -162,7 +162,7 @@ TFB_Prim_Stamp (STAMP *stmp) } void -TFB_Prim_StampFill (STAMP *stmp, Color color) +TFB_Prim_StampFill (STAMP *stmp, Color color, POINT ctxOrigin) { int x, y; FRAME SrcFramePtr; @@ -188,8 +188,8 @@ TFB_Prim_StampFill (STAMP *stmp, Color color) LockMutex (img->mutex); img->NormalHs = SrcFramePtr->HotSpot; - x = stmp->origin.x - _CurFramePtr->HotSpot.x; - y = stmp->origin.y - _CurFramePtr->HotSpot.y; + x = stmp->origin.x + ctxOrigin.x; + y = stmp->origin.y + ctxOrigin.y; UnlockMutex (img->mutex); @@ -205,12 +205,13 @@ TFB_Prim_StampFill (STAMP *stmp, Color color) } void -TFB_Prim_FontChar (POINT *origin, TFB_Char *fontChar, TFB_Image *backing) +TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, TFB_Image *backing, + POINT ctxOrigin) { int x, y; - x = origin->x - _CurFramePtr->HotSpot.x; - y = origin->y - _CurFramePtr->HotSpot.y; + x = charOrigin.x + ctxOrigin.x; + y = charOrigin.y + ctxOrigin.y; if (_CurFramePtr->Type == SCREEN_DRAWABLE) { diff --git a/sc2/src/libs/graphics/tfb_prim.h b/sc2/src/libs/graphics/tfb_prim.h index 1f2262d0e..72470061e 100644 --- a/sc2/src/libs/graphics/tfb_prim.h +++ b/sc2/src/libs/graphics/tfb_prim.h @@ -20,11 +20,11 @@ #include "tfb_draw.h" -void TFB_Prim_Line (LINE *line, Color color); -void TFB_Prim_Point (POINT *p, Color color); -void TFB_Prim_Rect (RECT *r, Color color); -void TFB_Prim_FillRect (RECT *r, Color color); -void TFB_Prim_Stamp (STAMP *stamp); -void TFB_Prim_StampFill (STAMP *stamp, Color color); -void TFB_Prim_FontChar (POINT *origin, TFB_Char *fontChar, - TFB_Image *backing); +void TFB_Prim_Line (LINE *line, Color color, POINT ctxOrigin); +void TFB_Prim_Point (POINT *p, Color color, POINT ctxOrigin); +void TFB_Prim_Rect (RECT *r, Color color, POINT ctxOrigin); +void TFB_Prim_FillRect (RECT *r, Color color, POINT ctxOrigin); +void TFB_Prim_Stamp (STAMP *stamp, POINT ctxOrigin); +void TFB_Prim_StampFill (STAMP *stamp, Color color, POINT ctxOrigin); +void TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, + TFB_Image *backing, POINT ctxOrigin);