Enable asyncio.library.
[AROS-Contrib.git] / bgui / labelclass.c
blob538bb2f6863ad4fd6aef5858aefb16e276c4454b
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_LabelID, ld_TextID, PKCTRL_ULONG),
121 LD_ENTRY(LAB_Style, ld_Style, PKCTRL_UWORD),
122 LD_ENTRY(LAB_SelectedStyle, ld_SelStyle, PKCTRL_UWORD),
123 LD_ENTRY(LAB_Place, ld_Place, PKCTRL_UBYTE),
124 LD_ENTRY(LAB_Underscore, ld_UnderscoreChar, PKCTRL_UBYTE),
125 LD_FLAG(LAB_Highlight, LABF_HIGHLIGHT),
126 LD_FLAG(LAB_HighUScore, LABF_HIGH_USCORE),
127 LD_FLAG(LAB_FlipX, LABF_FLIP_X),
128 LD_FLAG(LAB_FlipY, LABF_FLIP_Y),
129 LD_FLAG(LAB_FlipXY, LABF_FLIP_XY),
130 LD_FLAG(LAB_NoPlaceIn, LABF_NOPLACEIN),
132 PACK_NEWOFFSET(BGUI_PB),
134 LD_PENTRY(IMAGE_ErasePen, ld_ErasePen, PKCTRL_UBYTE),
136 PACK_ENDTABLE
140 /// OM_NEW
142 * Create a shiny new object.
144 METHOD(LabelClassNew, struct opSet *, ops)
146 LD *ld;
147 IPTR rc;
150 * First we let the superclass
151 * create an object.
153 if ((rc = AsmDoSuperMethodA(cl, obj, (Msg)ops)))
156 * Get to the instance data.
158 ld = INST_DATA(cl, rc);
161 * Clear instance data and
162 * setup the defaults.
164 ld->ld_Flags = LABF_DEFPEN|LABF_DEFSELPEN;
165 ld->ld_Style = (UWORD)~0;
166 ld->ld_SelStyle = (UWORD)~0;
167 ld->ld_Place = PLACE_IN;
168 ld->ld_UnderscoreChar = '_';
171 * Set attributes.
173 AsmCoerceMethod(cl, (Object *)rc, RM_SETM, ops->ops_AttrList, RAF_INITIAL);
175 #if 0
176 if (fail)
179 * Failure!
181 AsmCoerceMethod(cl, (Object *)rc, OM_DISPOSE);
182 rc = 0;
184 #endif
185 // ld->ld_Flags |= LABF_FLIP_XY;
188 return rc;
190 METHOD_END
192 /// RM_GETATTRFLAGS
194 * Get the flags of an attribute.
196 METHOD(LabelClassGetAttrFlags, struct rmAttr *, ra)
198 static struct TagItem chart[] =
200 { LAB_Label, CHART_ATTR(ld_, ld_Text ) | RAF_RESIZE, },
201 { LAB_LabelID, CHART_ATTR(ld_, ld_TextID ), },
202 { LAB_TextAttr, CHART_ATTR(ld_, ld_TextAttr ) | RAF_CUSTOM | RAF_RESIZE, },
203 { LAB_Style, CHART_ATTR(ld_, ld_Style ) | RAF_REDRAW, },
204 { LAB_SelectedStyle, CHART_ATTR(ld_, ld_SelStyle ) | RAF_REDRAW, },
205 { LAB_Place, CHART_ATTR(ld_, ld_Place ) | RAF_REDRAW, },
206 { LAB_Underscore, CHART_ATTR(ld_, ld_UnderscoreChar ) | RAF_CUSTOM, },
207 { LAB_Template, CHART_ATTR(ld_, ld_Flags ) | RAF_CUSTOM | RAF_ADDRESS, },
208 { IMAGE_ErasePen, CHART_ATTR(ld_, ld_ErasePen ), },
209 { IMAGE_TextFont, CHART_ATTR(ld_, ld_Font ) | RAF_CUSTOM | RAF_NOP, },
210 { LAB_Pen, CHART_ATTR(ld_, ld_Pen ) | RAF_CUSTOM | RAF_NOP, },
211 { LAB_DriPen, CHART_ATTR(ld_, ld_Pen ) | RAF_CUSTOM | RAF_NOP, },
212 { LAB_SelectedPen, CHART_ATTR(ld_, ld_SelPen ) | RAF_CUSTOM | RAF_NOP, },
213 { LAB_SelectedDriPen, CHART_ATTR(ld_, ld_SelPen ) | RAF_CUSTOM | RAF_NOP, },
215 { LAB_Highlight, CHART_FLAG(ld_, ld_Flags, LABF_HIGHLIGHT ) | RAF_REDRAW, },
216 { LAB_HighUScore, CHART_FLAG(ld_, ld_Flags, LABF_HIGH_USCORE) | RAF_REDRAW, },
217 { LAB_FlipX, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_X ) | RAF_REDRAW, },
218 { LAB_FlipY, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_Y ) | RAF_REDRAW, },
219 { LAB_FlipXY, CHART_FLAG(ld_, ld_Flags, LABF_FLIP_XY ) | RAF_RESIZE, },
220 { LAB_NoPlaceIn, CHART_FLAG(ld_, ld_Flags, LABF_NOPLACEIN ) | RAF_CUSTOM, },
222 { TAG_DONE },
225 ULONG rc = GetTagData(ra->ra_Attr->ti_Tag, 0, chart);
227 return rc;
229 METHOD_END
231 /// RM_SET
233 * Set standard attributes.
235 METHOD(LabelClassSet, struct rmAttr *, ra)
237 return BGUI_SetAttrChart(cl, obj, ra);
239 METHOD_END
241 /// RM_SETCUSTOM
243 * Set custom attributes.
245 METHOD(LabelClassSetCustom, struct rmAttr *, ra)
247 LD *ld = (LD *)INST_DATA(cl, obj);
248 struct TextFont *tf;
249 IPTR attr = ra->ra_Attr->ti_Tag;
250 IPTR data = ra->ra_Attr->ti_Data;
252 switch (attr)
254 case LAB_Template:
255 if (data)
257 attr = 0;
258 Get_Attr((Object *)data, LAB_Template, &attr);
259 if (attr)
261 CopyMem((LD *)attr, ld, sizeof(LD));
262 ld->ld_Flags &= ~LABF_SELFOPEN;
265 break;
267 case IMAGE_TextFont:
268 if (ld->ld_Font && (ld->ld_Flags & LABF_SELFOPEN))
269 BGUI_CloseFont(ld->ld_Font);
270 ld->ld_Font = (struct TextFont *)data;
271 ld->ld_Flags &= ~LABF_SELFOPEN;
272 break;
274 case LAB_Place:
275 case LAB_NoPlaceIn:
276 if ((ld->ld_Flags & LABF_NOPLACEIN) && (ld->ld_Place == PLACE_IN))
277 ld->ld_Place = PLACE_LEFT;
278 break;
280 case LAB_Flags:
281 ld->ld_Flags = (ld->ld_Flags & 0xFFFF0000) | data;
282 break;
284 case LAB_TextAttr:
285 if (data && (tf = BGUI_OpenFont((struct TextAttr *)data)))
287 if (ld->ld_Font && (ld->ld_Flags & LABF_SELFOPEN))
288 BGUI_CloseFont(ld->ld_Font);
289 ld->ld_Font = tf;
290 ld->ld_TextAttr = (struct TextAttr *)data;
291 ld->ld_Flags |= LABF_SELFOPEN;
293 break;
295 case LAB_Pen:
296 case LAB_DriPen:
297 if ((UWORD)data == (UWORD)~0)
299 ld->ld_Flags |= LABF_DEFPEN;
301 else
303 ld->ld_Flags &= ~LABF_DEFPEN;
304 ld->ld_Pen = data;
306 if (attr == LAB_Pen) ld->ld_Flags &= ~LABF_DRIPEN;
307 else ld->ld_Flags |= LABF_DRIPEN;
308 break;
310 case LAB_SelectedPen:
311 case LAB_SelectedDriPen:
312 if ((UWORD)data == (UWORD)~0)
314 ld->ld_Flags |= LABF_DEFSELPEN;
316 else
318 ld->ld_Flags &= ~LABF_DEFSELPEN;
319 ld->ld_SelPen = data;
321 if (attr == LAB_SelectedPen) ld->ld_Flags &= ~LABF_SELDRIPEN;
322 else ld->ld_Flags |= LABF_SELDRIPEN;
323 break;
325 return 1;
327 METHOD_END
330 /// OM_GET
332 * Give an attribute.
334 METHOD(LabelClassGet, struct opGet *, opg)
336 LD *ld = INST_DATA(cl, obj);
337 ULONG rc = 1;
338 Tag tag = opg->opg_AttrID;
339 IPTR *store = opg->opg_Storage;
340 UBYTE *u;
343 * First we try if the attribute is known to us. If not we pass
344 * it on to the superclass.
346 switch (tag)
348 case LAB_Template:
349 STORE ld;
350 break;
351 case LAB_Label:
352 STORE ld->ld_Text;
353 break;
354 case LAB_TextAttr:
355 STORE ld->ld_TextAttr;
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, LabelClassSet, },
937 { RM_SETCUSTOM, LabelClassSetCustom, },
938 { RM_GETATTRFLAGS, LabelClassGetAttrFlags, },
939 { IM_DRAW, LabelClassDrawErase, },
941 { OM_GET, LabelClassGet, },
942 { OM_NEW, LabelClassNew, },
943 { OM_DISPOSE, LabelClassDispose, },
944 { IM_EXTENT, LabelClassDrawErase, },
945 { IM_ERASE, LabelClassDrawErase, },
946 { BASE_LOCALIZE, LabelClassLocalize, },
947 { BASE_DIMENSIONS, LabelClassDimensions, },
948 { DF_END },
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);