Updated to latest source.
[AROS-Contrib.git] / bgui / labelclass.c
blob89ae93f3d26f827d1d8cfb47c1cff3206cc2f30c
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * labelclass.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.8 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.7 2003/01/18 19:09:57 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.6 2000/08/17 15:09:18 chodorowski
21 * Fixed compiler warnings.
23 * Revision 42.5 2000/07/03 21:21:00 bergers
24 * Replaced stch_l & stcu_d and had to make a few changes in other places because of that.
26 * Revision 42.4 2000/07/02 06:08:33 bergers
27 * Compiles library alright (except that I took stch_l & stcu_d out) and seems to create the right type of object. Test1 also compiles alright but crashes somewhere...
29 * Revision 42.3 2000/05/29 15:42:49 stegerg
30 * fixed some "comparison is always 1 due to limited range of data type"
31 * errors
33 * Revision 42.2 2000/05/29 00:40:24 bergers
34 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
36 * Revision 42.1 2000/05/15 19:27:01 stegerg
37 * another hundreds of REG() macro replacements in func headers/protos.
39 * Revision 42.0 2000/05/09 22:09:16 mlemos
40 * Bumped to revision 42.0 before handing BGUI to AROS team
42 * Revision 41.11 2000/05/09 19:54:29 mlemos
43 * Merged with the branch Manuel_Lemos_fixes.
45 * Revision 41.10.2.7 1999/08/03 05:11:53 mlemos
46 * Ensured that the creation of the label rotation bitmaps are allocated as
47 * friends of the rastport's bitmap.
49 * Revision 41.10.2.6 1998/12/07 03:07:01 mlemos
50 * Replaced OpenFont and CloseFont calls by the respective BGUI debug macros.
52 * Revision 41.10.2.5 1998/10/16 02:58:47 mlemos
53 * Fixed a bug in the computation of label dimensions that was ignoring that
54 * labels may have padding space to left or above them.
56 * Revision 41.10.2.4 1998/10/15 04:59:44 mlemos
57 * Fixed a bug in the computation of label dimensions that was ignoring that
58 * labels have padding space arround them depending on their positions.
59 * Fixed a bug that was making label class maximum size to not update
60 * depending on nominal size.
62 * Revision 41.10.2.3 1998/05/22 03:50:04 mlemos
63 * Ensured that the extent fields are initialized even when the label text is
64 * set to NULL.
66 * Revision 41.10.2.2 1998/03/02 23:48:46 mlemos
67 * Switched vector allocation functions calls to BGUI allocation functions.
69 * Revision 41.10.2.1 1998/02/28 02:24:43 mlemos
70 * Made Dimensions method return size (0,0) when the label text is set to NULL
72 * Revision 41.10 1998/02/25 21:12:21 mlemos
73 * Bumping to 41.10
75 * Revision 1.1 1998/02/25 17:08:42 mlemos
76 * Ian sources
81 /// Class definitions.
82 #include "include/classdefs.h"
85 * Object instance data.
87 typedef struct ld_ {
88 ULONG ld_Flags; /* Flags. */
89 UBYTE *ld_Text; /* The label itself. */
90 ULONG ld_TextID; /* Text ID. */
91 struct IBox ld_Extent; /* Label extent. */
92 UWORD ld_Width, ld_Height; /* Nominal label size. */
93 struct TextAttr *ld_TextAttr; /* Font to use. */
94 struct TextFont *ld_Font; /* The opened font. */
95 UWORD ld_Style, ld_SelStyle; /* Style in which to render. */
96 UBYTE ld_Pen, ld_SelPen; /* Pens to render normal/selected. */
97 UBYTE ld_Place; /* Where to render. */
98 UBYTE ld_UnderscoreChar; /* Underscore indicator. */
99 UBYTE ld_ErasePen; /* Pen to erase with. */
100 } LD;
102 #define LABF_SELFOPEN (1<<31)
103 #define LABF_EXT_VALID (1<<30)
104 #define LABF_DRIPEN (1<<29)
105 #define LABF_SELDRIPEN (1<<28)
106 #define LABF_DEFPEN (1<<27)
107 #define LABF_DEFSELPEN (1<<26)
108 #define LABF_NOPLACEIN (1<<25)
110 #define LD_ENTRY(tag, offset, flags) PACK_ENTRY(LAB_TAGSTART, tag, ld_, offset, flags)
111 #define LD_FLAG(tag, flag) PACK_LONGBIT(LAB_TAGSTART, tag, ld_, ld_Flags, PKCTRL_BIT, flag)
113 #define LD_PENTRY(tag, offset, flags) PACK_ENTRY(BGUI_PB, tag, ld_, offset, flags)
114 #define LD_PFLAG(tag, flag) PACK_LONGBIT(BGUI_PB, tag, ld_, ld_Flags, PKCTRL_BIT, flag)
116 static ULONG LabelPackTable[] =
118 PACK_STARTTABLE(LAB_TAGSTART),
120 LD_ENTRY(LAB_Label, ld_Text, PKCTRL_ULONG),
121 LD_ENTRY(LAB_LabelID, ld_TextID, PKCTRL_ULONG),
122 LD_ENTRY(LAB_TextAttr, ld_TextAttr, PKCTRL_ULONG),
123 LD_ENTRY(LAB_Style, ld_Style, PKCTRL_UWORD),
124 LD_ENTRY(LAB_SelectedStyle, ld_SelStyle, PKCTRL_UWORD),
125 LD_ENTRY(LAB_Place, ld_Place, PKCTRL_UBYTE),
126 LD_ENTRY(LAB_Underscore, ld_UnderscoreChar, PKCTRL_UBYTE),
127 LD_FLAG(LAB_Highlight, LABF_HIGHLIGHT),
128 LD_FLAG(LAB_HighUScore, LABF_HIGH_USCORE),
129 LD_FLAG(LAB_FlipX, LABF_FLIP_X),
130 LD_FLAG(LAB_FlipY, LABF_FLIP_Y),
131 LD_FLAG(LAB_FlipXY, LABF_FLIP_XY),
132 LD_FLAG(LAB_NoPlaceIn, LABF_NOPLACEIN),
134 PACK_NEWOFFSET(BGUI_PB),
136 LD_PENTRY(IMAGE_ErasePen, ld_ErasePen, PKCTRL_UBYTE),
138 PACK_ENDTABLE
142 /// OM_NEW
144 * Create a shiny new object.
146 METHOD(LabelClassNew, struct opSet *, ops)
148 LD *ld;
149 ULONG rc;
152 * First we let the superclass
153 * create an object.
155 if (rc = AsmDoSuperMethodA(cl, obj, (Msg)ops))
158 * Get to the instance data.
160 ld = INST_DATA(cl, rc);
163 * Clear instance data and
164 * setup the defaults.
166 ld->ld_Flags = LABF_DEFPEN|LABF_DEFSELPEN;
167 ld->ld_Style = (UWORD)~0;
168 ld->ld_SelStyle = (UWORD)~0;
169 ld->ld_Place = PLACE_IN;
170 ld->ld_UnderscoreChar = '_';
173 * Set attributes.
175 AsmCoerceMethod(cl, (Object *)rc, RM_SETM, ops->ops_AttrList, RAF_INITIAL);
177 #if __AROS__
178 #warning A comment within a comment makes gcc puke...
179 #if 0
182 if (fail)
185 * Failure!
187 AsmCoerceMethod(cl, (Object *)rc, OM_DISPOSE);
188 rc = 0;
191 #endif
192 #endif
193 // ld->ld_Flags |= LABF_FLIP_XY;
196 return rc;
198 METHOD_END
200 /// RM_GETATTRFLAGS
202 * Get the flags of an attribute.
204 METHOD(LabelClassGetAttrFlags, struct rmAttr *, ra)
206 static struct TagItem chart[] =
208 LAB_Label, CHART_ATTR(ld_, ld_Text ) | RAF_RESIZE,
209 LAB_LabelID, CHART_ATTR(ld_, ld_TextID ),
210 LAB_TextAttr, CHART_ATTR(ld_, ld_TextAttr ) | RAF_CUSTOM | RAF_RESIZE,
211 LAB_Style, CHART_ATTR(ld_, ld_Style ) | RAF_REDRAW,
212 LAB_SelectedStyle, CHART_ATTR(ld_, ld_SelStyle ) | RAF_REDRAW,
213 LAB_Place, CHART_ATTR(ld_, ld_Place ) | RAF_REDRAW,
214 LAB_Underscore, CHART_ATTR(ld_, ld_UnderscoreChar ) | RAF_CUSTOM,
215 LAB_Template, CHART_ATTR(ld_, ld_Flags ) | RAF_CUSTOM | RAF_ADDRESS,
216 IMAGE_ErasePen, CHART_ATTR(ld_, ld_ErasePen ),
217 IMAGE_TextFont, CHART_ATTR(ld_, ld_Font ) | RAF_CUSTOM | RAF_NOP,
218 LAB_Pen, CHART_ATTR(ld_, ld_Pen ) | RAF_CUSTOM | RAF_NOP,
219 LAB_DriPen, CHART_ATTR(ld_, ld_Pen ) | RAF_CUSTOM | RAF_NOP,
220 LAB_SelectedPen, CHART_ATTR(ld_, ld_SelPen ) | RAF_CUSTOM | RAF_NOP,
221 LAB_SelectedDriPen, CHART_ATTR(ld_, ld_SelPen ) | RAF_CUSTOM | RAF_NOP,
223 LAB_Highlight, CHART_FLAG(ld_, ld_Flags, LABF_HIGHLIGHT ) | RAF_REDRAW,
224 LAB_HighUScore, CHART_FLAG(ld_, ld_Flags, LABF_HIGH_USCORE) | RAF_REDRAW,
225 LAB_FlipX, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_X ) | RAF_REDRAW,
226 LAB_FlipY, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_Y ) | RAF_REDRAW,
227 LAB_FlipXY, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_XY ) | RAF_RESIZE,
228 LAB_NoPlaceIn, CHART_FLAG(ld_, ld_Flags, LABF_NOPLACEIN ) | RAF_CUSTOM,
230 TAG_DONE
233 ULONG rc = GetTagData(ra->ra_Attr->ti_Tag, 0, chart);
235 return rc;
237 METHOD_END
239 /// RM_SET
241 * Set standard attributes.
243 METHOD(LabelClassSet, struct rmAttr *, ra)
245 return BGUI_SetAttrChart(cl, obj, ra);
247 METHOD_END
249 /// RM_SETCUSTOM
251 * Set custom attributes.
253 METHOD(LabelClassSetCustom, struct rmAttr *, ra)
255 LD *ld = (LD *)INST_DATA(cl, obj);
256 struct TextFont *tf;
257 ULONG attr = ra->ra_Attr->ti_Tag;
258 ULONG data = ra->ra_Attr->ti_Data;
260 switch (attr)
262 case LAB_Template:
263 if (data)
265 attr = NULL;
266 Get_Attr((Object *)data, LAB_Template, &attr);
267 if (attr)
269 CopyMem((LD *)attr, ld, sizeof(LD));
270 ld->ld_Flags &= ~LABF_SELFOPEN;
273 break;
275 case IMAGE_TextFont:
276 if (ld->ld_Font && (ld->ld_Flags & LABF_SELFOPEN))
277 BGUI_CloseFont(ld->ld_Font);
278 ld->ld_Font = (struct TextFont *)data;
279 ld->ld_Flags &= ~LABF_SELFOPEN;
280 break;
282 case LAB_Place:
283 case LAB_NoPlaceIn:
284 if ((ld->ld_Flags & LABF_NOPLACEIN) && (ld->ld_Place == PLACE_IN))
285 ld->ld_Place = PLACE_LEFT;
286 break;
288 case LAB_Flags:
289 ld->ld_Flags = (ld->ld_Flags & 0xFFFF0000) | data;
290 break;
292 case LAB_TextAttr:
293 if (data && (tf = BGUI_OpenFont((struct TextAttr *)data)))
295 if (ld->ld_Font && (ld->ld_Flags & LABF_SELFOPEN))
296 BGUI_CloseFont(ld->ld_Font);
297 ld->ld_Font = tf;
298 ld->ld_TextAttr = (struct TextAttr *)data;
299 ld->ld_Flags |= LABF_SELFOPEN;
301 break;
303 case LAB_Pen:
304 case LAB_DriPen:
305 if ((UWORD)data == (UWORD)~0)
307 ld->ld_Flags |= LABF_DEFPEN;
309 else
311 ld->ld_Flags &= ~LABF_DEFPEN;
312 ld->ld_Pen = data;
314 if (attr == LAB_Pen) ld->ld_Flags &= ~LABF_DRIPEN;
315 else ld->ld_Flags |= LABF_DRIPEN;
316 break;
318 case LAB_SelectedPen:
319 case LAB_SelectedDriPen:
320 if ((UWORD)data == (UWORD)~0)
322 ld->ld_Flags |= LABF_DEFSELPEN;
324 else
326 ld->ld_Flags &= ~LABF_DEFSELPEN;
327 ld->ld_SelPen = data;
329 if (attr == LAB_SelectedPen) ld->ld_Flags &= ~LABF_SELDRIPEN;
330 else ld->ld_Flags |= LABF_SELDRIPEN;
331 break;
333 return 1;
335 METHOD_END
338 /// OM_GET
340 * Give an attribute.
342 METHOD(LabelClassGet, struct opGet *, opg)
344 LD *ld = INST_DATA(cl, obj);
345 ULONG rc = 1, tag = opg->opg_AttrID, *store = opg->opg_Storage;
346 UBYTE *u;
349 * First we try if the attribute is known to us. If not we pass
350 * it on to the superclass.
352 switch (tag)
354 case LAB_Template:
355 STORE ld;
356 break;
357 case LAB_Pen:
358 STORE (!(ld->ld_Flags & LABF_DEFPEN) && !(ld->ld_Flags & LABF_DRIPEN)) ? ld->ld_Pen : (ULONG)~0;
359 break;
360 case LAB_DriPen:
361 STORE (!(ld->ld_Flags & LABF_DEFPEN) && (ld->ld_Flags & LABF_DRIPEN)) ? ld->ld_Pen : (ULONG)~0;
362 break;
363 case LAB_SelectedPen:
364 STORE (!(ld->ld_Flags & LABF_DEFSELPEN) && !(ld->ld_Flags & LABF_SELDRIPEN)) ? ld->ld_SelPen : (ULONG)~0;
365 break;
366 case LAB_SelectedDriPen:
367 STORE (!(ld->ld_Flags & LABF_DEFSELPEN) && (ld->ld_Flags & LABF_SELDRIPEN)) ? ld->ld_SelPen : (ULONG)~0;
368 break;
369 case LAB_KeyChar:
370 if (ld->ld_Text && ld->ld_UnderscoreChar)
372 if (u = strchr(ld->ld_Text, ld->ld_UnderscoreChar))
373 STORE (u + 1);
375 break;
376 case LAB_Flags:
377 STORE ld->ld_Flags;
378 break;
379 default:
380 rc = BGUI_UnpackStructureTag((UBYTE *)ld, LabelPackTable, tag, store);
381 if (!rc) rc = AsmDoSuperMethodA(cl, obj, (Msg)opg);
382 break;
384 return rc;
386 METHOD_END
388 /// OM_DISPOSE
390 * Dispose of the object.
392 METHOD(LabelClassDispose, Msg, msg)
394 LD *ld = INST_DATA(cl, obj);
397 * Close the font.
399 if (ld->ld_Font && (ld->ld_Flags & LABF_SELFOPEN))
400 BGUI_CloseFont(ld->ld_Font);
403 * The rest goes to the superclass.
405 return AsmDoSuperMethodA(cl, obj, msg);
407 METHOD_END
409 /// IM_DRAW, IM_ERASE, IM_EXTENT
411 * Render, erase or find out it's extensions.
413 METHOD(LabelClassDrawErase, struct impDraw *, dr)
415 LD *ld = INST_DATA(cl, obj);
416 struct RastPort rrp = *(dr->imp_RPort), trp;
417 struct impExtent *ie = (struct impExtent *)dr;
418 struct IBox *bounds, box;
419 UBYTE *chunky1, *chunky2;
421 UBYTE *text = NULL, *s, *d, c;
422 UWORD *pens = NULL, pen, style;
423 WORD xpos, ypos, tw, th;
424 ULONG rc = 0;
425 int i1, j1, j2, rw, rh;
427 BOOL sel = (dr->imp_State == IDS_SELECTED) || (dr->imp_State == IDS_INACTIVESELECTED);
430 * Obtain image box bounds.
432 WORD l = IMAGE(obj)->LeftEdge;
433 WORD t = IMAGE(obj)->TopEdge;
434 WORD w = IMAGE(obj)->Width;
435 WORD h = IMAGE(obj)->Height;
438 * Get pens.
440 if (dr->MethodID == IM_DRAW) pens = PENS(dr->imp_DrInfo);
443 * Add offsets when necessary.
445 if (dr->MethodID != IM_EXTENT)
447 l += dr->imp_Offset.X;
448 t += dr->imp_Offset.Y;
450 else
452 bounds = ie->impe_Extent;
453 bounds->Left = bounds->Top = bounds->Width = bounds->Height = 0;
457 * Only do the label when it actually exists.
459 if (s = ld->ld_Text)
461 text = BGUI_AllocPoolMem(strlen(s) + 30);
463 if (d = text)
465 rc = 1;
467 *d++ = '\33'; /* 2 */
468 switch (ld->ld_Place)
470 case PLACE_LEFT:
471 *d++ = 'r';
472 break;
473 case PLACE_RIGHT:
474 *d++ = 'l';
475 break;
476 default:
477 *d++ = 'c';
478 break;
482 * Set font style.
484 style = sel ? ld->ld_SelStyle : ld->ld_Style;
485 if (sel && (style == (UWORD)~0)) style = ld->ld_Style;
487 if (style != (UWORD)~0)
489 if (style & FSF_ITALIC) /* 2 */
491 *d++ = '\33';
492 *d++ = 'i';
494 if (style & FSF_BOLD) /* 2 */
496 *d++ = '\33';
497 *d++ = 'b';
499 if (style & FSF_UNDERLINED) /* 2 */
501 *d++ = '\33';
502 *d++ = 'u';
506 c = 0;
507 if (dr->MethodID == IM_DRAW) /* 5 */
509 if (ld->ld_Flags & LABF_HIGHLIGHT)
511 c = 'd';
512 pen = HIGHLIGHTTEXTPEN;
514 else
517 * What state are we in?
519 if (sel)
522 * First see if a selected (dri)pen is
523 * given. If not use the default colors.
525 if (ld->ld_Flags & LABF_DEFSELPEN)
527 c = 'd';
528 pen = (dr->imp_State == IDS_SELECTED) ? FILLTEXTPEN : TEXTPEN;
530 else
532 c = (ld->ld_Flags & LABF_SELDRIPEN) ? 'd' : 'p';
533 pen = ld->ld_SelPen;
536 else
539 * First see if a normal (dri)pen is
540 * given. If not use the default colors.
542 if (ld->ld_Flags & LABF_DEFPEN)
544 c = 'd';
545 pen = TEXTPEN;
547 else
549 c = (ld->ld_Flags & LABF_DRIPEN) ? 'd' : 'p';
550 pen = ld->ld_Pen;
555 else if (dr->MethodID == IM_ERASE)
557 c = 'p';
558 pen = ld->ld_ErasePen;
560 if (c) /* 6 */
562 *d++ = '\33';
563 *d++ = c;
564 #ifdef __AROS__
565 d += sprintf(d, "%u", pen);
566 #else
567 d += stcu_d(d, pen);
568 #endif
571 *d++ = '\33'; /* 2 */
572 *d++ = '\33';
574 while (c = *s++)
576 if (c == ld->ld_UnderscoreChar) /* 5 */
578 if (*s)
580 if ((*s < 32) || (*s == 127))
582 s++;
584 else
586 c = (ld->ld_Flags & LABF_HIGH_USCORE) ? 'Z' : 'z';
587 *d++ = '\33';
588 *d++ = c;
589 *d++ = *s++;
590 if (*s)
592 *d++ = '\33';
593 *d++ = '-';
594 *d++ = c;
597 strcpy(d, s);
599 break;
601 *d++ = c;
605 * If a font is available, set it in the rastport.
607 if (ld->ld_Font) FSetFont(&rrp, ld->ld_Font);
610 * Setup drawmode.
612 FSetDrMd(&rrp, JAM1);
615 * Get label pixel size.
617 th = TotalHeight(&rrp, text);
618 tw = TotalWidth (&rrp, text);
620 if (ld->ld_Flags & LABF_FLIP_XY)
622 i1 = th; th = tw; tw = i1;
625 ld->ld_Width = tw;
626 ld->ld_Height = th;
629 * Preset x & y position.
631 xpos = l;
632 ypos = t;
635 * No need to place the text when we
636 * want the maximum extentiions.
638 if (dr->MethodID == IM_EXTENT && (ie->impe_Flags & EXTF_MAXIMUM))
639 goto maximumExtent;
641 reCalculate:
644 * Determine Y position.
646 switch (ld->ld_Place)
648 case PLACE_LEFT:
649 case PLACE_IN:
650 case PLACE_RIGHT:
651 ypos += (h - th) >> 1;
652 break;
654 case PLACE_ABOVE:
655 ypos -= (th + 4);
656 break;
658 case PLACE_BELOW:
659 ypos += (h + 3);
660 break;
664 * Determine X position.
666 switch (ld->ld_Place)
668 case PLACE_ABOVE:
669 case PLACE_IN:
670 case PLACE_BELOW:
671 xpos += (w - tw) >> 1;
672 break;
674 case PLACE_LEFT:
675 xpos -= (tw + 8);
676 break;
678 case PLACE_RIGHT:
679 xpos += (w + 7);
680 break;
684 * IM_EXTENT method?
686 if (dr->MethodID == IM_EXTENT)
688 maximumExtent:
690 * Pick up extent storage, preset to 0.
692 bounds = ie->impe_Extent;
693 bounds->Left = bounds->Top = bounds->Width = bounds->Height = 0;
696 * No negative offsets.
698 if ((l <= 0) || (t <= 0))
700 if (l <= 0) l = tw + 8;
701 if (t <= 0) t = th + 4;
702 goto reCalculate;
706 * Maximum?
708 if (ie->impe_Flags & EXTF_MAXIMUM)
710 switch (ld->ld_Place)
712 case PLACE_LEFT:
713 bounds->Left = -(tw + 8);
714 break;
715 case PLACE_RIGHT:
716 bounds->Width = (tw + 7);
717 break;
718 case PLACE_ABOVE:
719 bounds->Top = -(th + 4);
720 break;
721 case PLACE_BELOW:
722 bounds->Height = (th + 3);
723 break;
726 else
728 if (xpos < l) bounds->Left = -(l - xpos);
729 if ((xpos + tw) > (l + w - 1)) bounds->Width = (xpos + tw) - (l + w - 1);
730 if (ypos < t) bounds->Top = -(t - ypos);
731 if ((ypos + th) > (t + h - 1)) bounds->Height = (ypos + th) - (t + h - 1);
735 * Store label width and height.
737 if (ie->impe_LabelSize.Width) *(ie->impe_LabelSize.Width) = tw;
738 if (ie->impe_LabelSize.Height) *(ie->impe_LabelSize.Height) = th;
740 else
742 if (ld->ld_Flags & (LABF_FLIP_XY|LABF_FLIP_X|LABF_FLIP_Y))
744 rrp.BitMap = BGUI_AllocBitMap(tw, th, FGetDepth(&rrp), BMF_STANDARD, dr->imp_RPort->BitMap);
746 if (rrp.BitMap)
748 rrp.Layer = NULL;
749 ClipBlit(dr->imp_RPort, xpos, ypos, &rrp, 0, 0, tw, th, 0xC0);
751 box.Left = box.Top = 0;
753 else
755 box.Left = xpos;
756 box.Top = ypos;
760 * Move to the correct location.
762 box.Width = tw;
763 box.Height = th;
765 if (rrp.BitMap) RenderInfoText(&rrp, text, pens, &box, (UWORD)~0);
767 if (ld->ld_Flags & (LABF_FLIP_XY|LABF_FLIP_X|LABF_FLIP_Y))
769 if (rrp.BitMap)
771 rw = ((tw + 15) >> 4) << 4;
773 if (chunky1 = BGUI_AllocPoolMem(rw * th))
775 trp = rrp;
776 if (trp.BitMap = BGUI_AllocBitMap(rw, 1, FGetDepth(&rrp), BMF_STANDARD, dr->imp_RPort->BitMap))
778 ReadPixelArray8(&rrp, 0, 0, tw - 1, th - 1, chunky1, &trp);
779 BGUI_FreeBitMap(rrp.BitMap);
780 rrp.BitMap = NULL;
782 if (ld->ld_Flags & LABF_FLIP_X)
784 s = chunky1;
786 for (i1 = th; i1; i1--)
788 for (j1 = 0, j2 = tw - 1; j1 < j2; j1++, j2--)
790 c = s[j1];
791 s[j1] = s[j2];
792 s[j2] = c;
794 s += rw;
798 if (ld->ld_Flags & LABF_FLIP_Y)
800 s = chunky1;
801 d = chunky1 + rw * (th - 1);
803 while (s < d)
805 for (j1 = tw - 1; j1; j1--)
807 c = s[j1];
808 s[j1] = d[j1];
809 d[j1] = c;
811 s += rw;
812 d -= rw;
816 if (ld->ld_Flags & LABF_FLIP_XY)
818 chunky2 = chunky1;
819 rh = ((th + 15) >> 4) << 4;
821 if (chunky1 = BGUI_AllocPoolMem(tw * rh))
823 for (i1 = 0; i1 < th; i1++)
825 for (j1 = 0; j1 < tw; j1++)
827 chunky1[(j1 * rh) + i1] = chunky2[(i1 * rw) + j1];
830 BGUI_FreePoolMem(chunky2);
832 else chunky1 = chunky2;
833 i1 = tw; tw = th; th = i1;
835 BGUI_FreeBitMap(trp.BitMap);
836 trp.BitMap = BGUI_AllocBitMap(rw, 1, FGetDepth(&rrp), BMF_STANDARD, dr->imp_RPort->BitMap);
838 if (trp.BitMap)
840 WritePixelArray8(dr->imp_RPort, xpos, ypos,
841 xpos + tw - 1, ypos + th - 1, chunky1, &trp);
842 BGUI_FreeBitMap(trp.BitMap);
845 BGUI_FreePoolMem(chunky1);
847 BGUI_FreeBitMap(rrp.BitMap);
851 BGUI_FreePoolMem(text);
853 return rc;
855 METHOD_END
857 /// BASE_LOCALIZE
859 METHOD(LabelClassLocalize, struct bmLocalize *, bml)
861 LD *ld = INST_DATA(cl, obj);
862 ULONG rc = 0;
864 if (ld->ld_TextID)
866 ld->ld_Text = BGUI_GetCatalogStr(bml->bml_Locale, ld->ld_TextID, ld->ld_Text);
867 rc = 1;
869 return rc;
871 METHOD_END
873 /// BASE_DIMENSIONS
875 METHOD(LabelClassDimensions, struct bmDimensions *, bmd)
877 LD *ld = INST_DATA(cl, obj);
878 struct BaseInfo *bi = bmd->bmd_BInfo;
879 struct bguiExtent *be = bmd->bmd_Extent;
880 UWORD lh;
881 UWORD lw;
884 struct IBox extentions;
886 if(DoExtentMethod(obj, bi->bi_RPort, &extentions, &lw, &lh, EXTF_MAXIMUM))
888 lw=max(lw,max(-extentions.Left,extentions.Width));
889 lh=max(lh,max(-extentions.Top,extentions.Height));
891 else
892 lw=lh=0;
894 switch (ld->ld_Place)
896 case PLACE_ABOVE:
897 case PLACE_BELOW:
898 if (be->be_Min.Width < lw) be->be_Min.Width = lw;
899 if (be->be_Nom.Width < lw) be->be_Nom.Width = lw;
900 break;
901 case PLACE_IN:
902 lw += 4;
903 default:
904 be->be_Min.Width += lw;
905 be->be_Nom.Width += lw;
906 break;
909 switch (ld->ld_Place)
911 case PLACE_LEFT:
912 case PLACE_RIGHT:
913 if (be->be_Min.Height < lh) be->be_Min.Height = lh;
914 if (be->be_Nom.Height < lh) be->be_Nom.Height = lh;
915 break;
916 case PLACE_IN:
917 lh += 2;
918 default:
919 be->be_Min.Height += lh;
920 be->be_Nom.Height += lh;
921 break;
923 be->be_Max.Width=max(be->be_Max.Width,be->be_Nom.Width);
924 be->be_Max.Height=max(be->be_Max.Height,be->be_Nom.Height);
925 return 1;
927 METHOD_END
930 /// Class initialization.
933 * Class function table.
935 STATIC DPFUNC ClassFunc[] = {
936 RM_SET, (FUNCPTR)LabelClassSet,
937 RM_SETCUSTOM, (FUNCPTR)LabelClassSetCustom,
938 RM_GETATTRFLAGS, (FUNCPTR)LabelClassGetAttrFlags,
939 IM_DRAW, (FUNCPTR)LabelClassDrawErase,
941 OM_GET, (FUNCPTR)LabelClassGet,
942 OM_NEW, (FUNCPTR)LabelClassNew,
943 OM_DISPOSE, (FUNCPTR)LabelClassDispose,
944 IM_EXTENT, (FUNCPTR)LabelClassDrawErase,
945 IM_ERASE, (FUNCPTR)LabelClassDrawErase,
946 BASE_LOCALIZE, (FUNCPTR)LabelClassLocalize,
947 BASE_DIMENSIONS, (FUNCPTR)LabelClassDimensions,
948 DF_END, NULL
952 * Simple class initialization.
954 makeproto Class *InitLabelClass(void)
956 return BGUI_MakeClass(CLASS_SuperClassBGUI, BGUI_IMAGE_OBJECT,
957 CLASS_ObjectSize, sizeof(LD),
958 CLASS_DFTable, ClassFunc,
959 TAG_DONE);