Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 6675c6d

Browse files
committed
[[ RefactorGraphics ]] move common card drawing code to separate methods
[[ RefactorGraphics ]] [[ Bug 11175 ]] revise how card backgrounds are rendered now that patterns may have transparency [[ RefactorGraphics ]] add tilecache_ prefix to MCCard::render_* methods [[ RefactorGraphics ]] add MCGImageIsOpaque function to libgraphics
1 parent a981f20 commit 6675c6d

7 files changed

Lines changed: 104 additions & 38 deletions

File tree

engine/src/card.cpp

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,10 +2637,78 @@ void MCCard::drawcardborder(MCDC *dc, const MCRectangle &dirty)
26372637
//-----------------------------------------------------------------------------
26382638
// Redraw Management
26392639

2640-
void MCCard::draw(MCDC *dc, const MCRectangle& dirty, bool p_isolated)
2640+
// IM-2013-09-13: [[ RefactorGraphics ]] Factor out card background drawing to separate method
2641+
void MCCard::drawbackground(MCContext *p_context, const MCRectangle &p_dirty)
26412642
{
2643+
if (MCcurtheme != nil && getstack() -> ismetal() && MCcurtheme -> drawmetalbackground(p_context, p_dirty, rect, parent))
2644+
return;
2645+
2646+
// IM-2013-09-13: [[ RefactorGraphics ]] [[ Bug 11175 ]] Rework card background drawing to handle transparent background patterns
2647+
// transparent backgrounds will now draw on top of the stack background, which in turn draws on top of solid black if transparent
2648+
MCColor color;
2649+
MCPatternRef t_pattern = nil;
2650+
int2 x, y;
2651+
2652+
MCPatternRef t_stack_pattern = nil;
2653+
int16_t t_stack_x, t_stack_y;
2654+
26422655
Window_mode wm = getstack()->getmode();
26432656

2657+
Boolean t_hilite;
2658+
t_hilite = MClook == LF_WIN95 && (wm == WM_COMBO || wm == WM_OPTION);
2659+
2660+
bool t_opaque;
2661+
t_opaque = getforecolor(DI_BACK, False, t_hilite, color, t_pattern, x, y, p_context, this) || MCPatternIsOpaque(t_pattern);
2662+
2663+
// If the card background is a pattern with transparency, then draw the stack background first
2664+
if (!t_opaque)
2665+
{
2666+
t_opaque = parent->getforecolor(DI_BACK, False, t_hilite, color, t_stack_pattern, t_stack_x, t_stack_y, p_context, parent) || MCPatternIsOpaque(t_stack_pattern);
2667+
2668+
// And if the stack background is a pattern with transparency, then fill with black first
2669+
if (!t_opaque)
2670+
{
2671+
p_context->setforeground(p_context->getblack());
2672+
p_context->setfillstyle(FillSolid, nil, 0, 0);
2673+
p_context->fillrect(p_dirty);
2674+
}
2675+
2676+
if (t_stack_pattern != nil)
2677+
p_context->setfillstyle(FillTiled, t_stack_pattern, t_stack_x, t_stack_y);
2678+
else
2679+
{
2680+
p_context->setforeground(color);
2681+
p_context->setfillstyle(FillSolid, nil, 0, 0);
2682+
}
2683+
2684+
p_context->fillrect(p_dirty);
2685+
}
2686+
2687+
if (t_pattern != nil)
2688+
p_context->setfillstyle(FillTiled, t_pattern, x, y);
2689+
else
2690+
{
2691+
p_context->setforeground(color);
2692+
p_context->setfillstyle(FillSolid, nil, 0, 0);
2693+
}
2694+
2695+
p_context->fillrect(p_dirty);
2696+
}
2697+
2698+
// IM-2013-09-13: [[ RefactorGraphics ]] Factor out card selection rect drawing to separate method
2699+
void MCCard::drawselectionrect(MCContext *p_context)
2700+
{
2701+
p_context->setlineatts(0, LineDoubleDash, CapButt, JoinBevel);
2702+
p_context->setforeground(p_context->getblack());
2703+
p_context->setbackground(p_context->getwhite());
2704+
p_context->setdashes(0, dashlist, 2);
2705+
p_context->drawrect(selrect);
2706+
p_context->setlineatts(0, LineSolid, CapButt, JoinBevel);
2707+
p_context->setbackground(MCzerocolor);
2708+
}
2709+
2710+
void MCCard::draw(MCDC *dc, const MCRectangle& dirty, bool p_isolated)
2711+
{
26442712
bool t_draw_cardborder;
26452713
t_draw_cardborder = true;
26462714

@@ -2649,12 +2717,8 @@ void MCCard::draw(MCDC *dc, const MCRectangle& dirty, bool p_isolated)
26492717
if (MCcurtheme != nil && getstack() -> menuwindow &&
26502718
MCcurtheme -> drawmenubackground(dc, dirty, getrect(), true))
26512719
t_draw_cardborder = false;
2652-
else if (MCcurtheme == nil || !getstack() -> ismetal() ||
2653-
!MCcurtheme -> drawmetalbackground(dc, dirty, rect, parent))
2654-
{
2655-
setforeground(dc, DI_BACK, False, MClook == LF_WIN95 && (wm == WM_COMBO || wm == WM_OPTION));
2656-
dc -> fillrect(dirty);
2657-
}
2720+
else
2721+
drawbackground(dc, dirty);
26582722

26592723
if (objptrs != NULL)
26602724
{
@@ -2675,15 +2739,7 @@ void MCCard::draw(MCDC *dc, const MCRectangle& dirty, bool p_isolated)
26752739
drawcardborder(dc, dirty);
26762740

26772741
if (getstate(CS_SIZE))
2678-
{
2679-
dc->setlineatts(0, LineDoubleDash, CapButt, JoinBevel);
2680-
dc->setforeground(dc->getblack());
2681-
dc->setbackground(dc->getwhite());
2682-
dc->setdashes(0, dashlist, 2);
2683-
dc->drawrect(selrect);
2684-
dc->setlineatts(0, LineSolid, CapButt, JoinBevel);
2685-
dc->setbackground(MCzerocolor);
2686-
}
2742+
drawselectionrect(dc);
26872743
}
26882744

26892745
///////////////////////////////////////////////////////////////////////////////

engine/src/card.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ class MCCard : public MCObject
179179
int2 getborderwidth(void);
180180
void drawcardborder(MCDC *dc, const MCRectangle &dirty);
181181

182+
// IM-2013-09-13: [[ RefactorGraphics ]] render the card background
183+
void drawbackground(MCContext *p_context, const MCRectangle &p_dirty);
184+
// IM-2013-09-13: [[ RefactorGraphics ]] render the card selection rect
185+
void drawselectionrect(MCContext *);
186+
182187
Exec_stat openbackgrounds(bool p_is_preopen, MCCard *p_other);
183188
Exec_stat closebackgrounds(MCCard *p_other);
184189

@@ -199,10 +204,11 @@ class MCCard : public MCObject
199204
// MW-2011-08-26: [[ TileCache ]] Render all layers into the stack's tilecache.
200205
void render(void);
201206

207+
// IM-2013-09-13: [[ RefactorGraphics ]] add tilecache_ prefix to render methods to make their purpose clearer
202208
// MW-2011-09-23: [[ TileCache ]] Render the card's bg layer.
203-
static bool render_background(void *context, MCContext *target, const MCRectangle& dirty);
209+
static bool tilecache_render_background(void *context, MCContext *target, const MCRectangle& dirty);
204210
// MW-2011-09-23: [[ TileCache ]] Render the card's fg layer.
205-
static bool render_foreground(void *context, MCContext *target, const MCRectangle& dirty);
211+
static bool tilecache_render_foreground(void *context, MCContext *target, const MCRectangle& dirty);
206212

207213
// MW-2012-06-08: [[ Relayer ]] This method returns the control on the card with
208214
// the given layer. If nil is returned the control doesn't exist.

engine/src/imagelist.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ void MCPatternRelease(MCPatternRef p_pattern)
6565
}
6666
}
6767

68+
bool MCPatternIsOpaque(MCPatternRef p_pattern)
69+
{
70+
return p_pattern != nil && MCGImageIsOpaque(p_pattern->image));
71+
}
72+
6873
////////////////////////////////////////////////////////////////////////////////
6974

7075
// MW-2009-02-02: [[ Improved image search ]]

engine/src/imagelist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef MCPattern *MCPatternRef;
3434
extern bool MCPatternCreate(MCGImageRef p_image, MCGFloat p_scale, MCPatternRef &r_pattern);
3535
extern MCPatternRef MCPatternRetain(MCPatternRef p_pattern);
3636
extern void MCPatternRelease(MCPatternRef p_pattern);
37+
extern void MCPatternIsOpaque(MCPatternRef p_pattern);
3738

3839
////////////////////////////////////////////////////////////////////////////////
3940

engine/src/redraw.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ static bool testtilecache_device_scenery_renderer(void *p_context, MCGContextRef
984984
return tilecache_device_renderer(testtilecache_scenery_renderer, p_context, p_target, p_rectangle);
985985
}
986986

987-
bool MCCard::render_foreground(void *p_context, MCContext *p_target, const MCRectangle& p_dirty)
987+
bool MCCard::tilecache_render_foreground(void *p_context, MCContext *p_target, const MCRectangle& p_dirty)
988988
{
989989
MCCard *t_card;
990990
t_card = (MCCard *)p_context;
@@ -993,23 +993,18 @@ bool MCCard::render_foreground(void *p_context, MCContext *p_target, const MCRec
993993
p_target -> setfunction(GXcopy);
994994
p_target -> setopacity(255);
995995

996-
p_target->setlineatts(0, LineDoubleDash, CapButt, JoinBevel);
997-
p_target->setforeground(p_target->getblack());
998-
p_target->setbackground(p_target->getwhite());
999-
p_target->setdashes(0, MCCard::dashlist, 2);
1000-
p_target->drawrect(t_card -> selrect);
1001-
p_target->setlineatts(0, LineSolid, CapButt, JoinBevel);
1002-
p_target->setbackground(MCzerocolor);
996+
// IM-2013-09-13: [[ RefactorGraphics ]] Use shared code to render card foreground
997+
t_card -> drawselectionrect(p_target);
1003998

1004999
return true;
10051000
}
10061001

10071002
bool device_render_foreground(void *p_context, MCGContextRef p_target, const MCRectangle& p_rectangle)
10081003
{
1009-
return tilecache_device_renderer(MCCard::render_foreground, p_context, p_target, p_rectangle);
1004+
return tilecache_device_renderer(MCCard::tilecache_render_foreground, p_context, p_target, p_rectangle);
10101005
}
10111006

1012-
bool MCCard::render_background(void *p_context, MCContext *p_target, const MCRectangle& p_dirty)
1007+
bool MCCard::tilecache_render_background(void *p_context, MCContext *p_target, const MCRectangle& p_dirty)
10131008
{
10141009
MCCard *t_card;
10151010
t_card = (MCCard *)p_context;
@@ -1018,21 +1013,15 @@ bool MCCard::render_background(void *p_context, MCContext *p_target, const MCRec
10181013
p_target -> setfunction(GXcopy);
10191014
p_target -> setopacity(255);
10201015

1021-
// MW-2011-09-23: Make sure background is rendered consistently with non-tilecache mode.
1022-
Window_mode wm = t_card -> getstack()->getmode();
1023-
if (MCcurtheme == nil || !t_card -> getstack() -> ismetal() ||
1024-
!MCcurtheme -> drawmetalbackground(p_target, p_dirty, t_card -> getrect(), t_card -> parent))
1025-
{
1026-
t_card -> setforeground(p_target, DI_BACK, False, MClook == LF_WIN95 && (wm == WM_COMBO || wm == WM_OPTION));
1027-
p_target -> fillrect(p_dirty);
1028-
}
1016+
// IM-2013-09-13: [[ RefactorGraphics ]] Use shared code to render card background
1017+
t_card -> drawbackground(p_target, p_dirty);
10291018

10301019
return true;
10311020
}
10321021

10331022
bool device_render_background(void *p_context, MCGContextRef p_target, const MCRectangle& p_rectangle)
10341023
{
1035-
return tilecache_device_renderer(MCCard::render_background, p_context, p_target, p_rectangle);
1024+
return tilecache_device_renderer(MCCard::tilecache_render_background, p_context, p_target, p_rectangle);
10361025
}
10371026

10381027
void MCCard::render(void)

libgraphics/include/graphics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ int32_t MCGImageGetHeight(MCGImageRef image);
410410

411411
MCGSize MCImageGetSize(MCGImageRef image);
412412

413+
bool MCGImageIsOpaque(MCGImageRef image);
414+
413415
////////////////////////////////////////////////////////////////////////////////
414416

415417
bool MCGMaskCreateWithInfoAndRelease(const MCGDeviceMaskInfo& info, MCGMaskRef& r_mask);

libgraphics/src/image.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,11 @@ MCGSize MCGImageGetSize(MCGImageRef self)
175175
return t_size;
176176
}
177177

178-
////////////////////////////////////////////////////////////////////////////////
178+
////////////////////////////////////////////////////////////////////////////////
179+
180+
bool MCGImageIsOpaque(MCGImageRef self)
181+
{
182+
return self != nil && self -> bitmap -> isOpaque();
183+
}
184+
185+
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)