1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2 
3 /*
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include "gfxintrn.h"
20 #include "gfx_common.h"
21 #include "tfb_draw.h"
22 #include "tfb_prim.h"
23 
24 HOT_SPOT
MAKE_HOT_SPOT(COORD x,COORD y)25 MAKE_HOT_SPOT (COORD x, COORD y)
26 {
27 	HOT_SPOT hs;
28 	hs.x = x;
29 	hs.y = y;
30 	return hs;
31 }
32 
33 // XXX: INTERNAL_PRIMITIVE and INTERNAL_PRIM_DESC are not used
34 typedef union
35 {
36 	POINT Point;
37 	STAMP Stamp;
38 	BRESENHAM_LINE Line;
39 	TEXT Text;
40 	RECT Rect;
41 } INTERNAL_PRIM_DESC;
42 
43 typedef struct
44 {
45 	PRIM_LINKS Links;
46 	GRAPHICS_PRIM Type;
47 	Color Color;
48 	INTERNAL_PRIM_DESC Object;
49 } INTERNAL_PRIMITIVE;
50 
51 
52 // pValidRect or origin may be NULL
53 BOOLEAN
GetContextValidRect(RECT * pValidRect,POINT * origin)54 GetContextValidRect (RECT *pValidRect, POINT *origin)
55 {
56 	RECT tempRect;
57 	POINT tempPt;
58 
59 	if (!pValidRect)
60 		pValidRect = &tempRect;
61 	if (!origin)
62 		origin = &tempPt;
63 
64 	// Start with a rect the size of foreground frame
65 	pValidRect->corner.x = 0;
66 	pValidRect->corner.y = 0;
67 	pValidRect->extent = GetFrameBounds (_CurFramePtr);
68 	*origin = _CurFramePtr->HotSpot;
69 
70 	if (_pCurContext->ClipRect.extent.width)
71 	{
72 		// If the cliprect is completely outside of the valid frame
73 		// bounds we have nothing to draw
74 		if (!BoxIntersect (&_pCurContext->ClipRect,
75 				pValidRect, pValidRect))
76 			return (FALSE);
77 
78 		// Foreground frame hotspot defines a drawing position offset
79 		// WRT the context cliprect
80 		origin->x += _pCurContext->ClipRect.corner.x;
81 		origin->y += _pCurContext->ClipRect.corner.y;
82 	}
83 
84 	return (TRUE);
85 }
86 
87 static void
ClearBackGround(RECT * pClipRect)88 ClearBackGround (RECT *pClipRect)
89 {
90 	RECT clearRect;
91 	Color color = _get_context_bg_color ();
92 	clearRect.corner.x = 0;
93 	clearRect.corner.y = 0;
94 	clearRect.extent = pClipRect->extent;
95 	TFB_Prim_FillRect (&clearRect, color, DRAW_REPLACE_MODE,
96 			pClipRect->corner);
97 }
98 
99 void
DrawBatch(PRIMITIVE * lpBasePrim,PRIM_LINKS PrimLinks,BATCH_FLAGS BatchFlags)100 DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks,
101 		BATCH_FLAGS BatchFlags)
102 {
103 	RECT ValidRect;
104 	POINT origin;
105 
106 	if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, &origin))
107 	{
108 		COUNT CurIndex;
109 		PRIMITIVE *lpPrim;
110 		DrawMode mode = _get_context_draw_mode ();
111 
112 		BatchGraphics ();
113 
114 		if (BatchFlags & BATCH_BUILD_PAGE)
115 		{
116 			ClearBackGround (&ValidRect);
117 		}
118 
119 		CurIndex = GetPredLink (PrimLinks);
120 
121 		for (; CurIndex != END_OF_LIST;
122 				CurIndex = GetSuccLink (GetPrimLinks (lpPrim)))
123 		{
124 			GRAPHICS_PRIM PrimType;
125 			PRIMITIVE *lpWorkPrim;
126 			RECT ClipRect;
127 			Color color;
128 
129 			lpPrim = &lpBasePrim[CurIndex];
130 			PrimType = GetPrimType (lpPrim);
131 			if (!ValidPrimType (PrimType))
132 				continue;
133 
134 			lpWorkPrim = lpPrim;
135 
136 			switch (PrimType)
137 			{
138 				case POINT_PRIM:
139 					color = GetPrimColor (lpWorkPrim);
140 					TFB_Prim_Point (&lpWorkPrim->Object.Point, color,
141 							mode, origin);
142 					break;
143 				case STAMP_PRIM:
144 					TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp, mode, origin);
145 					break;
146 				case STAMPFILL_PRIM:
147 					color = GetPrimColor (lpWorkPrim);
148 					TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, color,
149 							mode, origin);
150 					break;
151 				case LINE_PRIM:
152 					color = GetPrimColor (lpWorkPrim);
153 					TFB_Prim_Line (&lpWorkPrim->Object.Line, color,
154 							mode, origin);
155 					break;
156 				case TEXT_PRIM:
157 					if (!TextRect (&lpWorkPrim->Object.Text, &ClipRect, NULL))
158 						continue;
159 					// ClipRect is relative to origin
160 					_text_blt (&ClipRect, &lpWorkPrim->Object.Text, origin);
161 					break;
162 				case RECT_PRIM:
163 					color = GetPrimColor (lpWorkPrim);
164 					TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color,
165 							mode, origin);
166 					break;
167 				case RECTFILL_PRIM:
168 					color = GetPrimColor (lpWorkPrim);
169 					TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color,
170 							mode, origin);
171 					break;
172 			}
173 		}
174 
175 		UnbatchGraphics ();
176 	}
177 }
178 
179 void
ClearDrawable(void)180 ClearDrawable (void)
181 {
182 	RECT ValidRect;
183 
184 	if (GraphicsSystemActive () && GetContextValidRect (&ValidRect, NULL))
185 	{
186 		ClearBackGround (&ValidRect);
187 	}
188 }
189 
190 void
DrawPoint(POINT * lpPoint)191 DrawPoint (POINT *lpPoint)
192 {
193 	POINT origin;
194 
195 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
196 	{
197 		Color color = GetPrimColor (&_locPrim);
198 		DrawMode mode = _get_context_draw_mode ();
199 		TFB_Prim_Point (lpPoint, color, mode, origin);
200 	}
201 }
202 
203 void
DrawRectangle(RECT * lpRect)204 DrawRectangle (RECT *lpRect)
205 {
206 	POINT origin;
207 
208 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
209 	{
210 		Color color = GetPrimColor (&_locPrim);
211 		DrawMode mode = _get_context_draw_mode ();
212 		TFB_Prim_Rect (lpRect, color, mode, origin);
213 	}
214 }
215 
216 void
DrawFilledRectangle(RECT * lpRect)217 DrawFilledRectangle (RECT *lpRect)
218 {
219 	POINT origin;
220 
221 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
222 	{
223 		Color color = GetPrimColor (&_locPrim);
224 		DrawMode mode = _get_context_draw_mode ();
225 		TFB_Prim_FillRect (lpRect, color, mode, origin);
226 	}
227 }
228 
229 void
DrawLine(LINE * lpLine)230 DrawLine (LINE *lpLine)
231 {
232 	POINT origin;
233 
234 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
235 	{
236 		Color color = GetPrimColor (&_locPrim);
237 		DrawMode mode = _get_context_draw_mode ();
238 		TFB_Prim_Line (lpLine, color, mode, origin);
239 	}
240 }
241 
242 void
DrawStamp(STAMP * stmp)243 DrawStamp (STAMP *stmp)
244 {
245 	POINT origin;
246 
247 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
248 	{
249 		DrawMode mode = _get_context_draw_mode ();
250 		TFB_Prim_Stamp (stmp, mode, origin);
251 	}
252 }
253 
254 void
DrawFilledStamp(STAMP * stmp)255 DrawFilledStamp (STAMP *stmp)
256 {
257 	POINT origin;
258 
259 	if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin))
260 	{
261 		Color color = GetPrimColor (&_locPrim);
262 		DrawMode mode = _get_context_draw_mode ();
263 		TFB_Prim_StampFill (stmp, color, mode, origin);
264 	}
265 }
266 
267