convert line ends
[canaan.git] / prj / tech / libsrc / gadget / drawelem.c
blob5ea97f0f79ab0ed27e030a8783c222e28b4bbc05
2 // $Header: x:/prj/tech/libsrc/gadget/RCS/drawelem.c 1.15 1998/02/03 16:37:47 mahk Exp $
4 #include <drawelem.h>
5 #include <2d.h>
6 #include <res.h>
7 #include <lgsprntf.h>
8 #include <rect.h>
9 #include <string.h>
10 #include <util2d.h>
11 #include <gadget.h>
12 #include <stdlib.h>
13 #include <cfgdbg.h>
15 Id lgad_btype_ids[MAX_BTYPES];
16 Id lgad_default_font = 0;
17 Id lgad_internal_id = 0;
18 char *(*lgad_string_get)(int num, char *buf, int bufsize) = NULL;
20 uchar elem_clut[256];
22 static guiStyle* draw_style = NULL;
24 void ElementSetStyle(guiStyle* style)
26 draw_style = style;
29 #if 0
30 static ulong elem_fcolor(DrawElement* d)
32 if (d->fcolor != 0)
33 return d->fcolor;
34 return
35 guiStyleGetColor(draw_style,StyleColorFG);
37 #endif
39 static ulong elem_bcolor(DrawElement* d)
41 if (d->bcolor != 0)
42 return d->bcolor;
43 return
44 guiStyleGetColor(draw_style,StyleColorBG);
48 #define MAGIC_ELEM_CLUT_COLOR 253
50 /* All of these individual element drawing types all take a "size" parameter as their last argument. If it
51 is non-NULL, then that means to not actually draw, but instead fill in the Point with the width of thing
52 as if it were going to draw. This is primarily to prevent a lot of redundant code with the sizing functions. */
54 #pragma off(unreferenced)
55 // Boy, this is an exciting function!
56 void ElementDrawNone(DrawElement *d, DrawElemState state, short x, short y, short w, short h, Point *size)
58 return;
61 // callbacks have a "size" of nothing since we don't know what is going to be in them.
62 void ElementDrawCallback(DrawElement *d, DrawElemState state, short x, short y, short w, short h, Point *size)
65 DrawElemCallback dcb = (DrawElemCallback)d->draw_data;
66 if (size)
68 size->x = 0;
69 size->y = 0;
71 else if (dcb != NULL)
73 grs_canvas canv;
75 gr_init_sub_canvas(grd_canvas,&canv,x,y,w,h);
76 gr_cset_cliprect(&canv,max(grd_clip.left - x,0),
77 max(grd_clip.top - y,0),
78 min(grd_clip.right - x,w),
79 min(grd_clip.bot - y,h));
80 gr_push_canvas(&canv);
81 dcb(d,state);
82 gr_pop_canvas();
83 gr_close_sub_canvas(&canv);
85 return;
88 static int nTabStops = 0;
89 static int *pTabStops = NULL;
91 // set the tabs that will be used for all
92 // text draw elements with DRAWFLAG_FORMAT_TABBED
94 void
95 ElementSetGlobalTabs( int nTabs,
96 int *pTabs )
98 nTabStops = nTabs;
99 pTabStops = pTabs;
104 // return the current tab settings
106 void
107 ElementGetGlobalTabs( int *pnTabs,
108 int **ppTabs )
110 *pnTabs = nTabStops;
111 *ppTabs = pTabStops;
116 // draw text with tab stops (and carriage returns)
118 static void
119 draw_tabbed_string( char *s,
120 int x,
121 int y )
123 char tmp[ DRAWELEM_STRLEN];
124 char c, *pNext;
125 int leftX, yStep, nChars, curTab;
127 if ( (nTabStops == 0) || (pTabStops == NULL) ) {
128 // there are no tab stops set - just do an untabbed string draw
129 gr_string( s, x, y );
130 return;
133 leftX = x;
134 yStep = gr_get_font()->h;
136 pNext = s;
138 nChars = 0;
139 curTab = 0;
140 while ( *pNext != 0 ) {
141 c = *pNext++;
142 switch( c ) {
144 default:
145 tmp[nChars++] = c;
146 break;
148 case '\t':
149 if ( curTab < nTabStops ) {
150 // dump the string up to this point
151 tmp[nChars] = 0;
152 gr_string(tmp, x, y );
153 x = leftX + pTabStops[curTab];
154 curTab++;
155 nChars = 0;
157 break;
159 case '\n':
160 tmp[nChars] = 0;
161 gr_string(tmp, x, y );
162 y += yStep;
163 x = leftX;
164 curTab = 0;
165 nChars = 0;
166 break;
170 // if there was any leftover string, display it
171 if ( nChars != 0 ) {
172 tmp[nChars] = 0;
173 gr_string( tmp, x, y );
178 StyleColorKind textcols[] =
180 StyleColorText,
181 StyleColorHilite,
182 StyleColorDim,
183 StyleColorBright,
187 void ElementDrawText(DrawElement *d, DrawElemState state, short x, short y, short w, short h, Point *size)
189 char s[DRAWELEM_STRLEN],s2[DRAWELEM_STRLEN]; // s carries the final string, some use s2 for formatting or
190 // other temporary string storage
191 Id font_id = guiStyleAvail(draw_style) ? guiStyleGetFont(draw_style,StyleFontNormal) : lgad_default_font; // what font to use, can be overriden
192 short sw,sh; // size in width and height, used for centering and size-setting
193 int *v; // variable contents
194 int stylecol = textcols[state];
195 int format;
196 int color = (d->fcolor != 0)
197 ? d->fcolor
198 : guiStyleGetColor(draw_style,stylecol);
200 switch (d->draw_type)
202 case DRAWTYPE_VAR:
203 strcpy(s2,"%d");
204 v = (int *)d->draw_data2;
205 if (v == NULL)
206 lg_sprintf(s,s2,0);
207 else
208 lg_sprintf(s,s2,*v);
209 break;
210 case DRAWTYPE_VARSTRING:
212 char **carr = (char **)(d->draw_data);
213 v = (int *)d->draw_data2;
214 if (v == NULL)
215 strcpy(s,carr[0]);
216 else
217 strcpy(s,carr[*v]);
218 break;
220 case DRAWTYPE_VARTEXTREF:
222 Ref *carr = (Ref *)(d->draw_data);
223 int val;
224 v = (int *)d->draw_data2;
225 if (v == NULL)
226 val = 0;
227 else
228 val = *v;
229 if (lgad_string_get)
230 lgad_string_get(carr[val],s,DRAWELEM_STRLEN);
231 else
232 strcpy(s,(char *)RefGet(carr[val]));
233 break;
235 case DRAWTYPE_FORMAT:
236 if (d->draw_type == DRAWTYPE_FORMAT)
237 strcpy(s2,(char *)(d->draw_data));
238 case DRAWTYPE_FORMATREF: // NOTE FALLTHROUGH, to share formatting code!
239 if (d->draw_type == DRAWTYPE_FORMATREF)
241 if (lgad_string_get == NULL)
242 Warning(("ElementDrawText: lgad_string_get is null!\n"));
243 else
244 lgad_string_get((Ref)d->draw_data, s2, DRAWELEM_STRLEN);
246 v = (int *)d->draw_data2;
247 if (v == NULL)
248 lg_sprintf(s,s2,0);
249 else
250 lg_sprintf(s,s2,*v);
251 break;
252 case DRAWTYPE_TEXT:
253 strcpy(s,(char *)(d->draw_data));
254 break;
255 case DRAWTYPE_TEXTREF:
256 if (lgad_string_get)
257 lgad_string_get((Ref)d->draw_data, s, DRAWELEM_STRLEN);
258 else
259 strcpy(s,(char *)RefGet((Ref)d->draw_data));
260 break;
263 // For those that can swap out fonts, give them the chance
264 switch (d->draw_type)
266 case DRAWTYPE_TEXT:
267 case DRAWTYPE_TEXTREF:
268 if (d->draw_data2 != NULL)
269 font_id = (Id)(d->draw_data2);
270 break;
273 // Actually do it
274 gr_set_fcolor(color);
275 gr_set_font((grs_font *)ResLock(font_id));
277 format = (d->draw_flags & DRAWFLAG_FORMAT_BITS) >> DRAWFLAG_FORMAT_SHIFT;
279 // Let the wrappers wrap, and the breakers break
280 if (format & DRAWFLAG_FORMAT_WRAP)
282 // NOTE: this thing doesn't know about tab stops!
283 gr_font_string_wrap(gr_get_font(),s,w);
284 format &= ~DRAWFLAG_FORMAT_WRAP; // take the format wrap out
287 gr_string_size(s,&sw,&sh);
288 // Note that if we are re-sizing, we don't do any real work but do some computation
289 // Thus no code outside of the non-sizing case can ever reference x,y,w,h since they
290 // are undefined for the sizing case.
291 if (size)
293 size->x = sw; size->y = sh;
294 switch (format)
296 case DRAWFLAG_FORMAT_LEFT:
297 case DRAWFLAG_FORMAT_RIGHT:
298 size->x += MIN_MARGIN;
299 break;
300 case DRAWFLAG_FORMAT_CENTER:
301 size->x += 1; // to offset for rounding in the centering process
302 break;
305 else
307 switch (format)
309 case DRAWFLAG_FORMAT_CENTER:
310 gr_string(s, x + (w - sw)/2, y + (h - sh)/2);
311 break;
312 case DRAWFLAG_FORMAT_LEFT:
313 gr_string(s, x + MIN_MARGIN, y + (h - sh)/2);
314 break;
315 case DRAWFLAG_FORMAT_RIGHT:
316 gr_string(s, x + w - sw - MIN_MARGIN, y + (h - sh)/2);
317 break;
318 case DRAWFLAG_FORMAT_TABBED:
319 draw_tabbed_string( s, x + MIN_MARGIN, y + (h - sh)/2 );
320 break;
323 ResUnlock(font_id);
327 void ElementDrawBitmap(DrawElement *d, DrawElemState state, short x, short y, short w, short h, Point *size)
329 grs_bitmap *draw_me; // what we should actually draw
330 Ref draw_ref = 0; // What Ref we are drawing?
331 int offs = 0;
333 switch(d->draw_type)
335 case DRAWTYPE_BITMAP:
336 draw_me = (grs_bitmap *)d->draw_data;
337 break;
338 case DRAWTYPE_BITMAPOFFSET:
340 int limit = (int)d->draw_data2;
341 if (limit == 0 || state < limit)
343 draw_me = *(((grs_bitmap**)d->draw_data) + state);
345 break;
347 case DRAWTYPE_RES:
348 if (state == dsDEPRESSED && d->draw_data2 != 0)
349 draw_ref = (Ref)d->draw_data2;
350 else
351 draw_ref = (Ref)d->draw_data;
352 goto common_ref;
354 case DRAWTYPE_RESOFFSET:
355 draw_ref = (Ref)d->draw_data;
357 int limit = (int)d->draw_data2;
358 if (limit == 0 || state < limit)
360 Ref ref = draw_ref + state;
361 RefTable* tbl = ResLock(REFID(ref));
362 if (RefIndexValid(tbl,REFINDEX(ref)))
363 draw_ref = ref;
364 ResUnlock(REFID(ref));
367 goto common_ref;
368 case DRAWTYPE_VARRES:
370 int *v; // the variable offset
371 Ref *rlist; // array of refs to offset into
372 rlist = (Ref *)d->draw_data;
373 v = (int *)d->draw_data2;
374 AssertMsg(rlist, "ElementDrawBitmap: rlist is NULL for DRAWTYPE_VARRES!");
376 if (rlist == NULL)
378 Warning(("ElementDrawBitmap: rlist is NULL for DRAWTYPE_VARRES!\n"));
379 return;
382 if (v == NULL)
383 draw_ref = rlist[0];
384 else
385 draw_ref = rlist[*v];
387 common_ref:
388 draw_me = UtilLockBitmapRef(draw_ref);
389 break;
393 AssertMsg(draw_me, "ElementDrawBitmap: draw_me is NULL!");
394 if (draw_me == NULL)
396 Warning(("ElementDrawBitmap: draw_me is NULL!\n"));
397 return;
401 if (size)
403 size->x = draw_me->w; size->y = draw_me->h;
405 else
406 gr_bitmap(draw_me,x,y);
407 if (draw_ref)
408 RefUnlock(draw_ref);
411 #pragma on(unreferenced)
413 // Big lookup table for how we deal with each kind of element, with duplicate entries for
414 // common functionality.
415 typedef void (*ElemDrawFunc)(DrawElement *d, DrawElemState state, short x, short y, short w, short h, Point *size);
417 ElemDrawFunc elem_draw_funcs[] =
419 ElementDrawNone,
420 ElementDrawText,
421 ElementDrawBitmap,
422 ElementDrawBitmap,
423 ElementDrawText,
424 ElementDrawText,
425 ElementDrawBitmap,
426 ElementDrawText,
427 ElementDrawText,
428 ElementDrawText,
429 /* 10 */
430 ElementDrawCallback,
431 ElementDrawBitmap,
432 ElementDrawText,
433 ElementDrawBitmap
436 #define TREK_UL 0
437 #define TREK_U 1
438 #define TREK_UR 2
439 #define TREK_L 3
440 #define TREK_R 4
441 #define TREK_BL 5
442 #define TREK_B 6
443 #define TREK_BR 7
445 #define NUM_TREK_BM (TREK_BR+1)
447 /* Actually draws a given DrawElement, assuming that the right canvas is already set, to fill the coordinates
448 passed it. This is the function that actually has all the gruesome knowledge of how to carry out the core
449 work of a DrawElement. In the event of a DRAWTYPE_CALLBACK it will use the data parameter to pass on. */
450 /* Note that the "data" field is explicitly for draw-time data (as opposed to the draw_data and draw_data2 fields
451 actually in the DrawElement structure, which are entirely for Setup-time info). */
453 void ElementDraw(DrawElement *d, DrawElemState state, short x, short y, short w, short h)
455 int i; // iterator
456 short m; // max size of intrusion on a side
457 DrawElement *elem = d;
458 ConfigSpew("draw_element", ("Element Draw %d %d to %d %d\n",x,y,x+w,y+h));
460 while(!(elem->statemask & (1 << state)))
462 elem = elem->next;
463 if (elem == NULL)
464 break;
466 // if we didn't find an elem representing the current state,
467 // look for a zero mask, connoting default
468 if (elem == NULL)
470 elem = d;
471 while (elem->statemask != 0)
473 elem = elem->next;
474 if (elem == NULL)
475 return;
478 d = elem;
480 elem_clut[MAGIC_ELEM_CLUT_COLOR] = elem_bcolor(d);
482 // Draw the "outer" elements that are independant of the internal data, like "bevel" or "trek"
483 switch((d->draw_flags & DRAWFLAG_BORDER_BITS) >> DRAWFLAG_BORDER_SHIFT)
485 case DRAWFLAG_BORDER_OUTLINE:
486 gr_set_fcolor(guiStyleGetColor(draw_style,StyleColorBorder));
487 gr_box(x,y,x+w,y+h);
488 x++;y++;w = w - 2;h = h - 2; // to compensate for smaller area
489 break;
490 case DRAWFLAG_BORDER_BEVEL:
491 gr_set_fcolor(guiStyleGetColor(draw_style,StyleColorBevelLight));
492 gr_hline(x,y,x+w-1);
493 gr_hline(x,y+h-1,x+w-1);
494 gr_set_fcolor(guiStyleGetColor(draw_style,StyleColorBevelDark));
495 gr_vline(x+w-1,y,y+h-1);
496 gr_vline(x,y,y+h-1);
497 x++;y++;w-=2;h-=2; // to compensate for smaller area
498 break;
499 case DRAWFLAG_BORDER_BITMAP:
501 grs_bitmap *trek_bms[NUM_TREK_BM];
502 int which_btype = (d->draw_flags & DRAWFLAG_BTYPE_BITS) >> DRAWFLAG_BTYPE_SHIFT;
503 AssertMsg1(which_btype <= MAX_BTYPES, "ElementDraw: btype of %d is invalid!\n", which_btype);
504 if (which_btype > MAX_BTYPES)
506 Warning(("ElementDraw: btype of %d is invalid!\n"));
507 which_btype = 0;
511 // fill in all the bitmaps
512 for (i=0; i < NUM_TREK_BM; i++)
513 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_btype_ids[which_btype],i));
515 // upper row
516 gr_clut_bitmap(trek_bms[TREK_UL],x,y,elem_clut);
517 gr_clut_bitmap(trek_bms[TREK_UR],x + w - trek_bms[TREK_UR]->w, y,elem_clut);
518 gr_clut_scale_bitmap(trek_bms[TREK_U], x + trek_bms[TREK_UL]->w, y,
519 w - trek_bms[TREK_UL]->w - trek_bms[TREK_UR]->w, trek_bms[TREK_U]->h,elem_clut);
521 // sides
522 gr_clut_scale_bitmap(trek_bms[TREK_L], x, y + trek_bms[TREK_UL]->h,
523 trek_bms[TREK_L]->w, h - trek_bms[TREK_UL]->h - trek_bms[TREK_BL]->h,elem_clut);
524 gr_clut_scale_bitmap(trek_bms[TREK_R], x + w - trek_bms[TREK_R]->w, y + trek_bms[TREK_UR]->h,
525 trek_bms[TREK_R]->w, h - trek_bms[TREK_UR]->h - trek_bms[TREK_BR]->h,elem_clut);
527 // bottom row
528 gr_clut_bitmap(trek_bms[TREK_BL], x, y + h - trek_bms[TREK_BL]->h,elem_clut);
529 gr_clut_bitmap(trek_bms[TREK_BR], x + w - trek_bms[TREK_BR]->w, y + h - trek_bms[TREK_BL]->h,elem_clut);
530 gr_clut_scale_bitmap(trek_bms[TREK_B], x + trek_bms[TREK_BL]->w, y + h - trek_bms[TREK_B]->h,
531 w - trek_bms[TREK_BL]->w - trek_bms[TREK_BR]->w, trek_bms[TREK_B]->h,elem_clut);
533 m = trek_bms[TREK_L]->w;
534 x = x + m; w = w - m;
535 w = w - trek_bms[TREK_R]->w;
537 m = max(max(trek_bms[TREK_UL]->h,trek_bms[TREK_U]->h),trek_bms[TREK_UR]->h);
538 y = y + m; h = h - m;
539 h = h - max(max(trek_bms[TREK_BL]->h,trek_bms[TREK_B]->h),trek_bms[TREK_BR]->h);
541 // unlock all those refs
542 for (i=0; i < NUM_TREK_BM; i++)
544 RefUnlock(MKREF(lgad_btype_ids[which_btype],i));
545 trek_bms[i] = NULL;
548 break;
551 // if (d->bcolor)
552 // {
553 // gr_set_fcolor(d->bcolor);
554 // gr_rect(x,y,x+w,y+h);
555 // }
557 // internal draw controls
558 switch((d->draw_flags & DRAWFLAG_INTERNAL_BITS) >> DRAWFLAG_INTERNAL_SHIFT)
560 case DRAWFLAG_INT_TRANSP:
561 break;
562 case DRAWFLAG_INT_SOLID:
563 // lay solid background
564 if (elem_bcolor(d))
566 gr_set_fcolor(elem_bcolor(d));
567 gr_rect(x,y,x+w,y+h);
569 break;
571 case DRAWFLAG_INT_TREK:
573 grs_bitmap *trek_int_bms[3];
574 // lock the art
575 for (i=0; i <= 2; i++)
576 trek_int_bms[i] = UtilLockBitmapRef(MKREF(lgad_internal_id,i));
578 // lay solid background
579 gr_set_fcolor(1); // um, why is this a hard-coded "1" ?
580 gr_rect(x,y,x+w,y+h);
582 // draw the three parts
583 gr_bitmap(trek_int_bms[0],x,y);
584 gr_scale_bitmap(trek_int_bms[1],x + trek_int_bms[0]->w, y,
585 w - trek_int_bms[0]->w, trek_int_bms[1]->h);
586 gr_scale_bitmap(trek_int_bms[2],x, y + trek_int_bms[0]->h,
587 trek_int_bms[2]->w, h - trek_int_bms[0]->h);
589 // if there is an "inner" draw element put it over the title
590 if (d->inner)
591 ElementDraw(d->inner,NULL,x + trek_int_bms[0]->w, y, w - trek_int_bms[0]->w, trek_int_bms[1]->h);
593 // alter drawing area
594 x = x + trek_int_bms[2]->w;
595 w = w - trek_int_bms[2]->w;
596 m = max(trek_int_bms[0]->h,trek_int_bms[1]->h);
597 y = y + m;
598 h = h - m;
600 // unlock all our art
601 for (i=0; i <= 2; i++)
602 RefUnlock(MKREF(lgad_internal_id,i));
604 break;
608 // Now draw the inner contents
609 if (elem_draw_funcs[d->draw_type])
610 elem_draw_funcs[d->draw_type](d,state,x,y,w,h,NULL);
613 void ElementSize(DrawElement *d, short *px, short *py)
615 Point p; // filled in by the sizing function
616 short iw,ih; // internal wid and ht
618 if (elem_draw_funcs[d->draw_type])
620 // Arguments we pass on are "undefined" since in theory they are unused in this case.
621 // zero seems most likely to cause it to die.
622 elem_draw_funcs[d->draw_type](d,NULL,0,0,0,0,&p);
623 *px = p.x;
624 *py = p.y;
626 else
628 Warning(("ElementSize: Don't know how to draw element type %d!\n",d->draw_type));
629 *px = 0; *py = 0;
631 // factor in wacky borders and internal elements
632 ElementExtrasSize(d,&iw,&ih);
633 *px += iw;
634 *py += ih;
637 // determines the total x and y extent of overall "extra" draw elements, such as internal elements and border
639 // This could (and maybe should?) be composed of the two calls to the Offset and the OffsetAlternate to figure
640 // out total pixel displacement needed. However, that is a lot of redundant work. On the other hand, the speed
641 // difference really isn't very significant, so it is probably worth it for the memory savings.
642 void ElementExtrasSize(DrawElement *d, short *pw, short *ph)
644 int i; // iterator
645 *pw = 0;
646 *ph = 0;
647 switch((d->draw_flags & DRAWFLAG_BORDER_BITS) >> DRAWFLAG_BORDER_SHIFT)
649 case DRAWFLAG_BORDER_BEVEL:
650 case DRAWFLAG_BORDER_OUTLINE:
651 *pw += 2;
652 *ph += 2;
653 break;
654 case DRAWFLAG_BORDER_BITMAP: // note this could easily be extended to different types of border art
655 // by altering the base resource that is used
657 grs_bitmap *trek_bms[NUM_TREK_BM];
658 int which_btype = (d->draw_flags & DRAWFLAG_BTYPE_BITS) >> DRAWFLAG_BTYPE_SHIFT;
660 for (i=0; i < NUM_TREK_BM; i++)
661 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_btype_ids[which_btype],i));
662 *pw = *pw + trek_bms[TREK_L]->w;
663 *pw = *pw + trek_bms[TREK_R]->w;
664 *ph = *ph + max(max(trek_bms[TREK_UL]->h,trek_bms[TREK_U]->h),trek_bms[TREK_UR]->h);
665 *ph = *ph + max(max(trek_bms[TREK_BL]->h,trek_bms[TREK_B]->h),trek_bms[TREK_BR]->h);
666 // unlock all those refs
667 for (i=0; i < NUM_TREK_BM; i++)
669 RefUnlock(MKREF(lgad_btype_ids[which_btype],i));
670 trek_bms[i] = NULL;
673 break;
675 switch((d->draw_flags & DRAWFLAG_INTERNAL_BITS) >> DRAWFLAG_INTERNAL_SHIFT)
677 case DRAWFLAG_INT_TREK:
679 grs_bitmap *trek_bms[3];
681 // lock the art
682 for (i=0; i <= 2; i++)
683 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_internal_id,i));
685 *pw = *pw + trek_bms[2]->w;
686 *ph = *ph + max(trek_bms[0]->h,trek_bms[1]->h);
688 // unlock all our art
689 for (i=0; i <= 2; i++)
690 RefUnlock(MKREF(lgad_internal_id,i));
692 break;
696 // *** Needs to become real when internal drawing elements exist!!!!!
697 #pragma off(unreferenced)
699 // Figure out how far into the draw element the extra (internals, borders) bits go
700 // for the upper and left
701 void ElementOffset(DrawElement *d, short *pw, short *ph)
703 int i; // iterator
704 *pw = 0;
705 *ph = 0;
706 switch((d->draw_flags & DRAWFLAG_BORDER_BITS) >> DRAWFLAG_BORDER_SHIFT)
708 case DRAWFLAG_BORDER_BEVEL:
709 case DRAWFLAG_BORDER_OUTLINE:
710 *pw += 1;
711 *ph += 1;
712 break;
713 case DRAWFLAG_BORDER_BITMAP:
715 grs_bitmap *trek_bms[NUM_TREK_BM];
716 int which_btype = (d->draw_flags & DRAWFLAG_BTYPE_BITS) >> DRAWFLAG_BTYPE_SHIFT;
718 for (i=0; i < NUM_TREK_BM; i++)
719 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_btype_ids[which_btype],i));
720 *pw = *pw + trek_bms[TREK_L]->w;
721 *ph = *ph + max(max(trek_bms[TREK_UL]->h,trek_bms[TREK_U]->h),trek_bms[TREK_UR]->h);
722 // unlock all those refs
723 for (i=0; i < NUM_TREK_BM; i++)
725 RefUnlock(MKREF(lgad_btype_ids[which_btype],i));
726 trek_bms[i] = NULL;
729 break;
731 switch((d->draw_flags & DRAWFLAG_INTERNAL_BITS) >> DRAWFLAG_INTERNAL_SHIFT)
733 case DRAWFLAG_INT_TREK:
735 grs_bitmap *trek_bms[3];
736 // lock the art
737 for (i=0; i <= 2; i++)
738 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_internal_id,i));
740 *pw = *pw + trek_bms[2]->w;
741 *ph = *ph + max(trek_bms[0]->h,trek_bms[1]->h);
743 // unlock all our art
744 for (i=0; i <= 2; i++)
745 RefUnlock(MKREF(lgad_internal_id,i));
747 break;
751 // Figure out how far into the draw element the extra (internals, borders) bits go
752 // for the bottom and right
753 void ElementOffsetAlternate(DrawElement *d, short *pw, short *ph)
755 int i; // iterator
756 *pw = 0;
757 *ph = 0;
758 switch((d->draw_flags & DRAWFLAG_BORDER_BITS) >> DRAWFLAG_BORDER_SHIFT)
760 case DRAWFLAG_BORDER_BEVEL:
761 case DRAWFLAG_BORDER_OUTLINE:
762 *pw += 1;
763 *ph += 1;
764 break;
765 case DRAWFLAG_BORDER_BITMAP:
767 grs_bitmap *trek_bms[NUM_TREK_BM];
768 int which_btype = (d->draw_flags & DRAWFLAG_BTYPE_BITS) >> DRAWFLAG_BTYPE_SHIFT;
770 for (i=0; i < NUM_TREK_BM; i++)
771 trek_bms[i] = UtilLockBitmapRef(MKREF(lgad_btype_ids[which_btype],i));
772 *pw = *pw + trek_bms[TREK_R]->w;
773 *ph = *ph + max(max(trek_bms[TREK_BL]->h,trek_bms[TREK_B]->h),trek_bms[TREK_BR]->h);
775 // unlock all those refs
776 for (i=0; i < NUM_TREK_BM; i++)
778 RefUnlock(MKREF(lgad_btype_ids[which_btype],i));
779 trek_bms[i] = NULL;
782 break;
785 // thus far, no internal elements affect the alternative offset.
788 #pragma on(unreferenced)
790 void ElementClear(DrawElement *d)
792 memset(d,0,sizeof(*d));
793 // d->fcolor = 33;
794 // d->bcolor = 1;
795 d->draw_type = DRAWTYPE_NONE;
798 void DrawElementInit(void)
800 int i; // iterator
801 for (i=0; i < 256; i++)
802 elem_clut[i] = i;