WIP iconobject.datatype.
[AROS-Contrib.git] / scalos / datatypes / IconObject / iconobj.c
blob2aeb6e4357f83a3f9148e9971f1a9e2c5825b20c
1 // iconobj.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <exec/resident.h>
8 #include <graphics/gfxbase.h>
9 #include <graphics/gfxmacros.h>
10 #include <intuition/classes.h>
11 #include <intuition/classusr.h>
12 #include <intuition/cghooks.h>
13 #include <intuition/gadgetclass.h>
14 #include <workbench/workbench.h>
15 #include <cybergraphx/cybergraphics.h>
16 #include <datatypes/iconobject.h>
17 #include <utility/pack.h>
18 #include <libraries/mcpgfx.h>
19 #include <scalos/scalosgfx.h>
21 #define __USE_SYSBASE
22 #include <clib/alib_protos.h>
23 #include <proto/exec.h>
24 #include <proto/graphics.h>
25 #include <proto/intuition.h>
26 #include <proto/utility.h>
27 #include <proto/dos.h>
28 #include <proto/cybergraphics.h>
29 #include <proto/scalosgfx.h>
30 #include <proto/timer.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <stddef.h>
35 #include <stdarg.h>
36 #include <limits.h>
38 #include <defs.h>
39 #include <Year.h>
40 #include <ScalosMcpGfx.h>
42 #include "iconobj.h"
44 #ifdef __AROS__
45 // FIXME: temporary fix until we have figured out
46 // how to deal with these deprecated defines.
47 #define IA_ShadowPen (IA_Dummy + 0x09)
48 #define IA_HighlightPen (IA_Dummy + 0x0A)
49 #endif
51 //----------------------------------------------------------------------------
53 #define max(a,b) ((a) > (b) ? (a) : (b))
54 #define min(a,b) ((a) < (b) ? (a) : (b))
56 #define IDTA_TAGBASE (IDTA_Type - 1)
58 #define AREAMAX 30
60 #define TT_RADIUS 5 // default value for iobj_TextRectRadius
62 #define TT_BORDER_X 4 // default value for iobj_TextRectBorderX
63 #define TT_BORDER_Y 2 // default value for iobj_TextRectBorderY
65 //----------------------------------------------------------------------------
67 // Memory allocation
69 #define SCALOS_MEM_START_MAGIC 0x5343414d
70 #define SCALOS_MEM_END_MAGIC 0xe34341cd
72 #define SCALOS_MEM_TRAILER 20
74 struct AllocatedMemFromPoolDebug
76 size_t amp_Size; // Size of allocated memory
78 ULONG amp_Line; // Line number of allocator
79 CONST_STRPTR amp_File; // File name of allocator
80 CONST_STRPTR amp_Function; // Name of allocating function
82 ULONG amp_Magic;
84 UBYTE amp_UserData[0]; // Start of user-visible memory
87 struct AllocatedMemFromPool
89 size_t amp_Size; // Size of allocated memory
90 UBYTE amp_UserData[0]; // Start of user-visible memory
93 //----------------------------------------------------------------------------
95 struct GfxBase *GfxBase;
96 T_UTILITYBASE UtilityBase;
97 struct ExecBase *SysBase;
98 struct Library *CyberGfxBase;
99 struct DosLibrary *DOSBase;
100 struct IntuitionBase *IntuitionBase;
101 struct ScalosGfxBase *ScalosGfxBase;
102 #ifdef TIMESTAMPS
103 T_TIMERBASE TimerBase;
104 #endif /* TIMESTAMPS */
105 #ifdef __amigaos4__
106 struct Library *NewlibBase;
107 struct Interface *INewlib;
108 struct GraphicsIFace *IGraphics;
109 struct UtilityIFace *IUtility;
110 struct ExecIFace *IExec;
111 struct CyberGfxIFace *ICyberGfx;
112 struct DOSIFace *IDOS;
113 struct IntuitionIFace *IIntuition;
114 struct ScalosGfxIFace *IScalosGfx;
115 #endif
117 void *PubMemPool;
118 void *ChipMemPool;
120 static struct SignalSemaphore MemPoolSemaphore;
122 static Class *IconObjectClass;
124 static const ULONG packTable[] =
126 PACK_STARTTABLE(IDTA_TAGBASE),
127 PACK_ENTRY(IDTA_TAGBASE, IDTA_UserFlags, InstanceData, iobj_UserFlags, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
128 PACK_ENTRY(IDTA_TAGBASE, IDTA_OverlayType, InstanceData, iobj_OverlayType, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
129 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextStyle, InstanceData, iobj_TextStyle, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
130 PACK_ENTRY(IDTA_TAGBASE, IDTA_Font, InstanceData, iobj_Font, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
131 PACK_ENTRY(IDTA_TAGBASE, IDTA_Borderless, InstanceData, iobj_Borderless, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
132 PACK_ENTRY(IDTA_TAGBASE, IDTA_Type, InstanceData, iobj_type, PKCTRL_UBYTE | PKCTRL_PACKUNPACK),
133 PACK_ENTRY(IDTA_TAGBASE, IDTA_FontHook, InstanceData, iobj_FontHook, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
134 PACK_ENTRY(IDTA_TAGBASE, IDTA_Fonthandle, InstanceData, iobj_Fonthandle, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
135 PACK_ENTRY(IDTA_TAGBASE, IDTA_Stacksize, InstanceData, iobj_stacksize, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
136 PACK_ENTRY(IDTA_TAGBASE, IDTA_WinCurrentX, InstanceData, iobj_wincurx, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
137 PACK_ENTRY(IDTA_TAGBASE, IDTA_WinCurrentY, InstanceData, iobj_wincury, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
138 PACK_ENTRY(IDTA_TAGBASE, IDTA_FrameType, InstanceData, iobj_frametype, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
139 PACK_ENTRY(IDTA_TAGBASE, IDTA_FrameTypeSel, InstanceData, iobj_frametypesel, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
140 PACK_ENTRY(IDTA_TAGBASE, IDTA_HalfShadowPen, InstanceData, iobj_HalfShadowPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
141 PACK_ENTRY(IDTA_TAGBASE, IDTA_HalfShinePen, InstanceData, iobj_HalfShinePen, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
142 PACK_ENTRY(IDTA_TAGBASE, IDTA_Flags, InstanceData, iobj_ddflags, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
143 PACK_ENTRY(IDTA_TAGBASE, IDTA_ViewModes, InstanceData, iobj_viewmodes, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
144 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPen, InstanceData, iobj_TextPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
145 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenSel, InstanceData, iobj_TextPenSel, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
146 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenBgSel, InstanceData, iobj_TextPenBgSel, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
147 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenOutline, InstanceData, iobj_TextPenOutline, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
148 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenShadow, InstanceData, iobj_TextPenShadow, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
149 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextBackPen, InstanceData, iobj_TextBackPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
150 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextDrawMode, InstanceData, iobj_TextDrawMode, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
151 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextSkip, InstanceData, iobj_textskip, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
152 PACK_ENTRY(IDTA_TAGBASE, IDTA_MultiLineText, InstanceData, iobj_MultiLineText, PKCTRL_UBYTE | PKCTRL_PACKUNPACK),
153 PACK_ENTRY(IDTA_TAGBASE, IDTA_TextMode, InstanceData, iobj_textmode, PKCTRL_UBYTE | PKCTRL_PACKUNPACK),
154 PACK_ENTRY(IDTA_TAGBASE, IDTA_Backfill, InstanceData, iobj_BackfillPenNorm, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
155 PACK_ENTRY(IDTA_TAGBASE, IDTA_BackfillSel, InstanceData, iobj_BackfillPenSel, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
156 PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerLeft, InstanceData, iobj_imgleft, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
157 PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerTop, InstanceData, iobj_imgtop, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
158 PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerRight, InstanceData, iobj_imgright, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
159 PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerBottom, InstanceData, iobj_imgbottom, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
160 PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectBorderX, InstanceData, iobj_TextRectBorderX, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
161 PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectBorderY, InstanceData, iobj_TextRectBorderY, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
162 PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectRadius, InstanceData, iobj_TextRectRadius, PKCTRL_UWORD | PKCTRL_PACKUNPACK),
163 PACK_ENTRY(IDTA_TAGBASE, IDTA_SelectedTextRectangle, InstanceData, iobj_SelectedTextRectangle, PKCTRL_UBYTE | PKCTRL_PACKUNPACK),
164 PACK_ENTRY(IDTA_TAGBASE, IDTA_Width_Mask_Normal, InstanceData, iobj_NormalMask.iom_Width, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
165 PACK_ENTRY(IDTA_TAGBASE, IDTA_Height_Mask_Normal, InstanceData, iobj_NormalMask.iom_Height, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
166 PACK_ENTRY(IDTA_TAGBASE, IDTA_Width_Mask_Selected, InstanceData, iobj_SelectedMask.iom_Width, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
167 PACK_ENTRY(IDTA_TAGBASE, IDTA_Height_Mask_Selected, InstanceData, iobj_SelectedMask.iom_Height, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
168 PACK_ENTRY(IDTA_TAGBASE, IDTA_CopyARGBImageData, InstanceData, iobj_NormalARGB.iargb_CopyARGBImageData, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
169 PACK_ENTRY(IDTA_TAGBASE, IDTA_CopySelARGBImageData, InstanceData, iobj_SelectedARGB.iargb_CopyARGBImageData, PKCTRL_ULONG | PKCTRL_PACKUNPACK),
170 PACK_ENDTABLE
173 //----------------------------------------------------------------------------
175 // must be public for AROS
176 SAVEDS(ULONG) INTERRUPT IconObjectDispatcher(Class *cl, Object *o, Msg msg);
178 //-----------------------------------------------------------------------------
180 static BOOL DtNew(Class *cl, Object *o, struct opSet *ops);
181 static ULONG DtDispose(Class *cl, Object *o, Msg msg);
182 static ULONG DtHitTest(Class *cl, Object *o, struct gpHitTest *gpht);
183 static ULONG DtRender(Class *cl, Object *o, struct gpRender *gpr);
184 static ULONG DtErase(Class *cl, Object *o, struct iopErase *iope);
185 static ULONG DtFindToolType(Class *cl, Object *o, struct iopFindToolType *ioft);
186 static ULONG DtGetToolTypeValue(Class *cl, Object *o, struct iopGetToolTypeValue *iotv);
187 static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd);
188 static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl);
189 static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf);
190 static ULONG DtSet(Class *cl, Object *o, struct opSet *ops);
191 static ULONG DtGet(Class *cl, Object *o, struct opGet *opg);
192 static ULONG DtScaleIcon(Class *cl, Object *o, struct iopScaleIcon *iops);
194 static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops);
195 static void LayoutIconText(struct InstanceData *inst, struct RastPort *rp, struct ExtGadget *gg);
196 static void DrawIconText(Class *cl, Object *o, struct iopDraw *iopd);
197 static void GetPosition(struct iopDraw *iopd, struct ExtGadget *gg, WORD *x, WORD *y);
198 static void DrawTextAt(struct InstanceData *inst, struct RastPort *rp, ULONG x, ULONG y);
199 static void DoReLayout(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp);
200 static BOOL IsSeparator(char ch);
201 static ULONG MySetSoftStyle(struct InstanceData *inst, struct RastPort *rp, ULONG style, ULONG enable);
202 static void MyText(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length);
203 static void MyTextExtent(struct InstanceData *inst, struct RastPort *rp,
204 CONST_STRPTR string, WORD Length, struct TextExtent *tExt);
205 static void MySetFont(struct InstanceData *inst, struct RastPort *rp, struct TextFont *tf);
206 static void MySetTransparency(struct InstanceData *inst, struct RastPort *rp, ULONG Transparency);
207 static void MyDoneRastPort(struct InstanceData *inst, struct RastPort *rp);
208 static UWORD MyGetFontBaseline(struct InstanceData *inst, struct RastPort *rp);
209 static void CalculateTextDimensions(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp);
210 static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents);
211 static void SetTags(Class *cl, Object *o, struct opSet *ops);
212 static void SetAllocTag(ULONG TagValue, STRPTR *DataPtr, struct TagItem *TagList);
213 static void SetAllocTagProtected(ULONG TagValue, STRPTR *DataPtr,
214 struct TagItem *TagList, struct SignalSemaphore *Sema);
215 static STRPTR AllocCopyString(CONST_STRPTR OrigString);
216 static void SetToolTypes(struct InstanceData *inst, const STRPTR *NewToolTypes);
217 static STRPTR *CloneToolTypes(const STRPTR *OrigToolTypes);
218 static void DrawFrame(Class *cl, Object *o, struct RastPort *rp,
219 ULONG Width, ULONG Height, UWORD FrameType);
220 static void DrawMaskFrame(struct InstanceData *inst, struct BitMap *DestBitMap,
221 ULONG Width, ULONG Height, UWORD FrameType);
222 static struct RastPort *InitRast(Class *cl, Object *o, struct iopLayout *iopl, struct RastPort *rp);
223 static struct BitMap *GenMask(Class *cl, Object *o,
224 ULONG BmWidth, ULONG BmHeight, ULONG BmDepth, ULONG BmFlags,
225 UBYTE *MaskPlane,
226 UWORD FrameType, ULONG MaskWidth, ULONG MaskHeight);
227 static struct BitMap *GenInvMask(Class *cl, Object *o, struct BitMap *SrcBitMap);
228 static BOOL ScaleRenderBitMapsNormal(Class *cl, Object *o,
229 ULONG NewWidth, ULONG NewHeight, struct Screen *screen);
230 static BOOL ScaleRenderBitMapsSelected(Class *cl, Object *o,
231 ULONG NewWidth, ULONG NewHeight, struct Screen *screen);
232 static void LayoutIconSize(Class *cl, Object *o, struct RastPort *rp);
233 static struct BitMap *ScaleMaskBitMap(struct BitMap *SourceBM,
234 ULONG SourceWidth, ULONG SourceHeight,
235 ULONG *NewWidth, ULONG *NewHeight,
236 ULONG ScaleFlags, struct BitMap *FriendBM);
237 static void CheckIfScalingRequired(Class *cl, Object *o);
238 static void ReplaceARGBImage(struct IconObjectARGB *img, struct ARGBHeader *argbh);
239 static void FreeARGBImage(struct IconObjectARGB *img);
240 static void FreeARGBImageLayout(struct IconObjectARGB *img);
241 static void FreeMask(struct IconObjectMask *Mask);
242 static void LayoutARGB(Class *cl, Object *o, struct IconObjectARGB *img);
243 static BOOL ScaleARGB(Class *cl, Object *o, struct IconObjectARGB *img,
244 struct IconObjectMask *Mask, ULONG NewWidth, ULONG NewHeight, ULONG ScaleFlags);
245 static void EraseIconText(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y);
246 static void DrawIconTextRect(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y);
248 static void DumpMaskPlane(const struct IconObjectMask *Mask);
249 static void DumpMask(const struct IconObjectMask *Mask);
250 static void DumpMaskBM(const struct IconObjectMask *Mask);
252 //----------------------------------------------------------------------------
254 SAVEDS(LONG) ASM Libstart(void)
256 return -1;
259 //----------------------------------------------------------------------------
261 char ALIGNED libName[] = "iconobject.datatype";
262 char ALIGNED libIdString[] = "$VER: iconobject.datatype "
263 STR(LIB_VERSION) "." STR(LIB_REVISION)
264 " (02 Nov 2008 23:57:06) "
265 COMPILER_STRING
266 " ©1999" CURRENTYEAR " The Scalos Team";
268 //-----------------------------------------------------------------------------
270 LIBFUNC(ObtainInfoEngine, libbase, ULONG)
272 (void) libbase;
274 return (ULONG) IconObjectClass;
276 LIBFUNC_END
278 //-----------------------------------------------------------------------------
280 // return 0 if error occurred
281 ULONG InitDatatype(struct IconObjectDtLibBase *dtLib)
283 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
285 dtLib->nib_Initialized = FALSE;
287 return 1;
290 // return 0 if error occurred
291 ULONG OpenDatatype(struct IconObjectDtLibBase *dtLib)
293 d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt));
295 if (!dtLib->nib_Initialized)
297 struct MsgPort *FBlitPort;
298 ULONG ChipMemPoolFlags;
300 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
302 dtLib->nib_Initialized = TRUE;
304 InitSemaphore(&MemPoolSemaphore);
306 CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0);
307 // CyberGfxBase may be NULL
309 FBlitPort = FindPort("FBlit");
310 d1(kprintf("%s/%s/%ld: FBlitPort=%08lx\n", __FILE__, __FUNC__, __LINE__, FBlitPort));
313 // don't use chip mem if CyberGfx library found or FBlit port found.
314 if (FBlitPort || CyberGfxBase)
316 ChipMemPoolFlags = PUBMEMPOOL_MEMFLAGS;
317 d1(kprintf("%s/%s/%ld: FBlitPort=%08lx CyberGfxBase=%08lx ChipMemPoolFlags = MEMF_PUBLIC\n", \
318 __FILE__, __FUNC__, __LINE__, FBlitPort, CyberGfxBase));
320 else
322 ChipMemPoolFlags = CHIPMEMPOOL_MEMFLAGS;
323 d1(kprintf("%s/%s/%ld: FBlitPort=%08lx CyberGfxBase=%08lx ChipMemPoolFlags = (MEMF_PUBLIC | MEMF_CHIP)\n", \
324 __FILE__, __FUNC__, __LINE__, FBlitPort, CyberGfxBase));
327 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
328 d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase));
329 if (NULL == IntuitionBase)
330 return 0;
332 DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39);
333 d1(kprintf("%s/%s/%ld: DOSBase=%08lx\n", __FILE__, __FUNC__, __LINE__, DOSBase));
334 if (NULL == DOSBase)
335 return 0;
337 UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39);
338 d1(kprintf("%s/%s/%ld: UtilityBase=%08lx\n", __FILE__, __FUNC__, __LINE__, UtilityBase));
339 if (NULL == UtilityBase)
340 return 0;
342 GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39);
343 d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase));
344 if (NULL == GfxBase)
345 return 0;
347 ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41);
348 d1(KPrintF("%s/%s/%ld: ScalosGfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, ScalosGfxBase));
349 if (NULL == ScalosGfxBase)
350 return 0;
352 #ifdef TIMESTAMPS
354 struct timerequest *iorequest;
356 iorequest = (struct timerequest *) CreateIORequest(CreateMsgPort(), sizeof(struct timerequest));
357 OpenDevice("timer.device", UNIT_VBLANK, &iorequest->tr_node, 0);
358 TimerBase = (T_TIMERBASE) iorequest->tr_node.io_Device;
360 #endif /* TIMESTAMPS */
362 #ifdef __amigaos4__
363 NewlibBase = OpenLibrary("newlib.library", 0);
364 if (NULL == NewlibBase)
365 return 0;
366 INewlib = GetInterface(NewlibBase, "main", 1, NULL);
367 if (NULL == INewlib)
368 return 0;
369 IDOS = (struct DOSIFace *) GetInterface((struct Library *) DOSBase, "main", 1, NULL);
370 if (IDOS == NULL)
371 return 0;
372 IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL);
373 if (NULL == IUtility)
374 return 0;
375 if (CyberGfxBase != NULL) // CyberGfxBase may be NULL
377 ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL);
378 if (ICyberGfx == NULL)
379 return 0;
381 IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL);
382 if (NULL == IIntuition)
383 return 0;
384 IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL);
385 if (NULL == IGraphics)
386 return 0;
387 IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL);
388 if (NULL == IScalosGfx)
389 return 0;
390 #endif /* __amigaos4__ */
392 PubMemPool = CreatePool(PUBMEMPOOL_MEMFLAGS, PUBMEMPOOL_PUDDLESIZE, PUBMEMPOOL_THRESHSIZE);
393 d1(kprintf("%s/%s/%ld: PubMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, PubMemPool));
394 if (NULL == PubMemPool)
395 return 0;
397 ChipMemPool = CreatePool(ChipMemPoolFlags, CHIPMEMPOOL_PUDDLESIZE, CHIPMEMPOOL_THRESHSIZE);
398 d1(kprintf("%s/%s/%ld: ChipMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, ChipMemPool));
399 if (NULL == ChipMemPool)
400 return 0;
402 IconObjectClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName,
403 "datatypesclass", NULL, sizeof(struct InstanceData), 0);
404 d1(kprintf("%s/%s/%ld: IconObjectClass=%08lx\n", __FILE__, __FUNC__, __LINE__, IconObjectClass));
405 if (NULL == IconObjectClass)
406 return 0;
408 SETHOOKFUNC(IconObjectClass->cl_Dispatcher, IconObjectDispatcher);
409 IconObjectClass->cl_Dispatcher.h_Data = dtLib;
411 // Make class available for the public
412 AddClass(IconObjectClass);
415 d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__));
417 return 1;
420 void CloseDatatype(struct IconObjectDtLibBase *dtLib)
422 d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt));
424 if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1)
426 if (IconObjectClass)
428 RemoveClass(IconObjectClass);
429 FreeClass(IconObjectClass);
430 IconObjectClass = dtLib->nib_ClassLibrary.cl_Class = NULL;
433 if (NULL != ChipMemPool)
435 DeletePool(ChipMemPool);
436 ChipMemPool = NULL;
438 if (NULL != PubMemPool)
440 DeletePool(PubMemPool);
441 PubMemPool = NULL;
444 #ifdef __amigaos4__
445 if (ICyberGfx)
447 DropInterface((struct Interface *)ICyberGfx);
448 ICyberGfx = NULL;
450 if (IScalosGfx)
452 DropInterface((struct Interface *)IScalosGfx);
453 IScalosGfx = NULL;
455 if (IGraphics)
457 DropInterface((struct Interface *)IGraphics);
458 IGraphics = NULL;
460 if (IIntuition)
462 DropInterface((struct Interface *)IIntuition);
463 IIntuition = NULL;
465 if (IUtility)
467 DropInterface((struct Interface *)IUtility);
468 IUtility = NULL;
470 if (IDOS)
472 DropInterface((struct Interface *)IDOS);
473 IDOS = NULL;
475 if (INewlib)
477 DropInterface(INewlib);
478 INewlib = NULL;
480 if (NewlibBase)
482 CloseLibrary(NewlibBase);
483 NewlibBase = NULL;
485 #endif
487 if (NULL != CyberGfxBase)
489 CloseLibrary(CyberGfxBase);
490 CyberGfxBase = NULL;
492 if (NULL != ScalosGfxBase)
494 CloseLibrary((struct Library *) ScalosGfxBase);
495 ScalosGfxBase = NULL;
497 if (NULL != GfxBase)
499 CloseLibrary((struct Library *) GfxBase);
500 GfxBase = NULL;
502 if (NULL != IntuitionBase)
504 CloseLibrary((struct Library *) IntuitionBase);
505 IntuitionBase = NULL;
507 if (NULL != UtilityBase)
509 CloseLibrary((struct Library *) UtilityBase);
510 UtilityBase = NULL;
512 if (NULL != DOSBase)
514 CloseLibrary((struct Library *) DOSBase);
515 DOSBase = NULL;
519 d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt));
523 //-----------------------------------------------------------------------------
525 SAVEDS(ULONG) INTERRUPT IconObjectDispatcher(Class *cl, Object *o, Msg msg)
527 ULONG Result;
529 d1(kprintf("%s/%s/%ld: cl=%08lx o=%08lx msg=%08lx MethodID=%08ld\n", __FILE__, __FUNC__, __LINE__,
530 cl, o, msg, msg->MethodID));
532 switch (msg->MethodID)
534 case OM_NEW:
535 o = (Object *) DoSuperMethodA(cl, o, msg);
536 d1(KPrintF("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
537 if (o)
539 d1(KPrintF("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
540 if (!DtNew(cl, o, (struct opSet *) msg))
542 DoMethod(o, OM_DISPOSE);
543 o = NULL;
546 Result = (ULONG) o;
547 break;
549 case OM_DISPOSE:
550 d1(kprintf("%s/%s/%ld: OM_DISPOSE cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
551 Result = DtDispose(cl, o, msg);
552 break;
554 case OM_GET:
555 d1(kprintf("%s/%s/%ld: OM_GET cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
556 Result = DtGet(cl, o, (struct opGet *) msg);
557 break;
559 case OM_SET:
560 d1(kprintf("%s/%s/%ld: OM_SET cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
561 Result = DtSet(cl, o, (struct opSet *) msg);
562 break;
564 case GM_HITTEST:
565 d1(kprintf("%s/%s/%ld: GM_HITTEST cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
566 Result = DtHitTest(cl, o, (struct gpHitTest *) msg);
567 break;
569 case GM_RENDER:
570 d1(kprintf("%s/%s/%ld: GM_RENDER cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
571 Result = DtRender(cl, o, (struct gpRender *) msg);
572 break;
574 case GM_GOACTIVE:
575 d1(kprintf("%s/%s/%ld: GM_GOACTIVE cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
576 Result = DtRender(cl, o, (struct gpRender *) msg);
577 break;
579 case GM_GOINACTIVE:
580 d1(kprintf("%s/%s/%ld: GM_GOINACTIVEclcl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
581 Result = DtRender(cl, o, (struct gpRender *) msg);
582 break;
584 case IDTM_Draw:
585 d1(kprintf("%s/%s/%ld: IDTM_Draw cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
586 Result = DtDraw(cl, o, (struct iopDraw *) msg);
587 break;
589 case IDTM_Layout:
590 Result = DtLayout(cl, o, (struct iopLayout *) msg);
591 d1(KPrintF("%s/%s/%ld: IDTM_Layout cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
592 break;
594 case IDTM_FreeLayout:
595 d1(kprintf("%s/%s/%ld: IDTM_FreeLayout cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
596 Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg);
597 break;
599 case IDTM_FindToolType:
600 d1(kprintf("%s/%s/%ld: IDTM_FindToolType cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
601 Result = DtFindToolType(cl, o, (struct iopFindToolType *) msg);
602 break;
604 case IDTM_GetToolTypeValue:
605 d1(kprintf("%s/%s/%ld: IDTM_GetToolTypeValue cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
606 Result = DtGetToolTypeValue(cl, o, (struct iopGetToolTypeValue *) msg);
607 break;
609 case IDTM_Erase:
610 d1(kprintf("%s/%s/%ld: IDTM_Erase cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
612 Result = DtErase(cl, o, (struct iopErase *) msg);
613 break;
615 case IDTM_ScaleIcon:
616 d1(KPrintF("%s/%s/%ld: IDTM_ScaleIcon cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg));
618 Result = DtScaleIcon(cl, o, (struct iopScaleIcon *) msg);
619 break;
621 default:
622 Result = DoSuperMethodA(cl, o, msg);
623 break;
626 d1(kprintf("%s/%s/%ld: result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result));
628 return Result;
631 //-----------------------------------------------------------------------------
633 static BOOL DtNew(Class *cl, Object *o, struct opSet *ops)
635 struct InstanceData *inst = INST_DATA(cl, o);
636 BOOL Success = TRUE;
638 memset(inst, 0, sizeof(struct InstanceData));
640 TIMESTAMP_d1();
642 InitSemaphore(&inst->iobj_TextSemaphore);
643 InitSemaphore(&inst->iobj_LayoutSemaphore);
645 inst->iobj_TextPen = 1;
646 inst->iobj_TextPenSel = 1;
647 inst->iobj_TextPenOutline = 2;
648 inst->iobj_TextPenBgSel = 3;
649 inst->iobj_TextPenShadow = 1;
650 inst->iobj_TextDrawMode = JAM1;
651 inst->iobj_TextBackPen = 0;
652 inst->iobj_TextRectBorderX = TT_BORDER_X;
653 inst->iobj_TextRectBorderY = TT_BORDER_Y;
654 inst->iobj_TextRectRadius = TT_RADIUS;
656 inst->iobj_SelectedTextRectangle = 1;
657 inst->iobj_textskip = 1;
658 inst->iobj_frametypesel = (UWORD) -1;
659 inst->iobj_TextStyle = FS_NORMAL;
660 inst->iobj_BackfillPenNorm = inst->iobj_BackfillPenSel = IDTA_BACKFILL_NONE;
662 inst->iobj_ScalingPercentage = 100;
664 inst->iobj_SizeConstraints.MinX = inst->iobj_SizeConstraints.MinY = 0;
665 inst->iobj_SizeConstraints.MaxX = inst->iobj_SizeConstraints.MaxY = SHRT_MAX;
667 SetTags(cl, o, ops);
669 d1(kprintf("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
670 TIMESTAMP_d1();
672 return Success;
675 //-----------------------------------------------------------------------------
677 static ULONG DtDispose(Class *cl, Object *o, Msg msg)
679 struct InstanceData *inst = INST_DATA(cl, o);
680 struct ExtGadget *gg = (struct ExtGadget *) o;
682 ObtainSemaphore(&inst->iobj_LayoutSemaphore);
684 MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_text);
685 MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_defaulttool);
686 MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_ToolWindow);
687 MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_name);
688 MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_tooltypes);
690 FreeARGBImage(&inst->iobj_NormalARGB);
691 FreeARGBImage(&inst->iobj_SelectedARGB);
693 if (gg->SelectRender)
695 struct RastPort *rp = (struct RastPort *) gg->SelectRender;
697 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap));
698 FreeBitMap(rp->BitMap);
699 gg->SelectRender = NULL;
701 if (gg->GadgetRender)
703 struct RastPort *rp = (struct RastPort *) gg->GadgetRender;
705 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap));
706 FreeBitMap(rp->BitMap);
707 gg->GadgetRender = NULL;
709 if (inst->iobj_BackfillRp)
711 if (inst->iobj_BackfillRp->BitMap)
713 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_BackfillRp->BitMap));
714 FreeBitMap(inst->iobj_BackfillRp->BitMap);
715 inst->iobj_BackfillRp->BitMap = NULL;
718 inst->iobj_BackfillRp = NULL;
721 FreeMask(&inst->iobj_NormalMask);
722 FreeMask(&inst->iobj_SelectedMask);
724 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
726 return DoSuperMethodA(cl, o, msg);
729 //-----------------------------------------------------------------------------
731 // For GM_HITTEST, return GMR_GADGETHIT if you were indeed hit,
732 // otherwise return zero.
734 static ULONG DtHitTest(Class *cl, Object *o, struct gpHitTest *gpht)
736 ULONG Result = 0;
738 d1(kprintf("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
740 Result = DoSuperMethodA(cl, o, (Msg) gpht);
741 if (GMR_GADGETHIT == Result)
743 struct InstanceData *inst = INST_DATA(cl, o);
744 struct ExtGadget *gg = (struct ExtGadget *) o;
745 struct BitMap *MaskBM;
746 LONG x, y;
747 ULONG BmWidth, BmHeight;
749 if (gg->Flags & GFLG_SELECTED)
750 MaskBM = inst->iobj_SelectedMask.iom_MaskBM;
751 else
752 MaskBM = inst->iobj_NormalMask.iom_MaskBM;
754 d1(kprintf("%s/%s/%ld: MaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskBM));
756 if (NULL == MaskBM)
758 Result = GMR_GADGETHIT;
760 else
762 d1(kprintf("%s/%s/%ld: iobj_imgleft=%ld iobj_imgtop=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgtop));
764 x = gpht->gpht_Mouse.X - gg->LeftEdge - inst->iobj_imgleft;
765 y = gpht->gpht_Mouse.Y - gg->TopEdge - inst->iobj_imgtop;
767 BmWidth = GetBitMapAttr(MaskBM, BMA_WIDTH);
768 BmHeight = GetBitMapAttr(MaskBM, BMA_HEIGHT);
770 d1(kprintf("%s/%s/%ld: x=%ld y=%ld BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, x, y, BmWidth, BmHeight));
772 if ( x >= 0 && y >= 0 && x < BmWidth && y < BmHeight)
774 struct RastPort rp;
776 InitRastPort(&rp);
778 rp.BitMap = MaskBM;
780 d1(kprintf("%s/%s/%ld: ReadPixel()=%ld\n", __FILE__, __FUNC__, __LINE__, ReadPixel(&rp, x, y)));
782 if (ReadPixel(&rp, x, y))
783 Result = GMR_GADGETHIT;
784 else
785 Result = 0;
790 d1(kprintf("%s/%s/%ld: o=%08lx Result=%ld\n", __FILE__, __FUNC__, __LINE__, o, Result));
792 return Result;
795 //-----------------------------------------------------------------------------
797 static ULONG DtRender(Class *cl, Object *o, struct gpRender *gpr)
799 struct InstanceData *inst = INST_DATA(cl, o);
800 struct ExtGadget *gg = (struct ExtGadget *) o;
801 struct RastPort *rp;
803 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
805 DoSuperMethodA(cl, o, (Msg) gpr);
807 if (GM_RENDER == gpr->MethodID)
808 rp = gpr->gpr_RPort;
809 else
810 rp = ObtainGIRPort(gpr->gpr_GInfo);
812 if (rp)
814 if (GM_RENDER == gpr->MethodID && !gpr->gpr_Redraw)
815 gg->Flags ^= GFLG_SELECTED;
817 if (((gg->Flags & GFLG_SELECTED) && !(inst->iobj_layoutflags & IOBLAYOUTF_SelectedImage))
818 || (!(gg->Flags & GFLG_SELECTED) && !(inst->iobj_layoutflags & IOBLAYOUTF_NormalImage)))
820 DoMethod(o, IDTM_Layout,
821 gpr->gpr_GInfo->gi_Screen,
822 gpr->gpr_GInfo->gi_Window,
824 gpr->gpr_GInfo->gi_DrInfo,
825 (gg->Flags & GFLG_SELECTED) ? IOLAYOUTF_SelectedImage : IOLAYOUTF_NormalImage);
828 DoMethod(o, IDTM_Draw,
829 gpr->gpr_GInfo->gi_Screen,
830 gpr->gpr_GInfo->gi_Window,
832 gpr->gpr_GInfo->gi_DrInfo,
833 -gpr->gpr_GInfo->gi_Domain.Left,
834 -gpr->gpr_GInfo->gi_Domain.Top,
837 if (GM_RENDER != gpr->MethodID)
838 ReleaseGIRPort(rp);
841 return 0;
844 //-----------------------------------------------------------------------------
846 static ULONG DtErase(Class *cl, Object *o, struct iopErase *iope)
848 struct InstanceData *inst = INST_DATA(cl, o);
849 struct ExtGadget *gg = (struct ExtGadget *) o;
851 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
853 // Erase icon image
854 EraseRect(iope->iope_RastPort,
855 iope->iope_XOffset + gg->LeftEdge,
856 iope->iope_YOffset + gg->TopEdge,
857 iope->iope_XOffset + gg->LeftEdge + gg->Width - 1,
858 iope->iope_YOffset + gg->TopEdge + gg->Height - 1);
860 // Erase icon text
861 EraseIconText(cl, o,
862 iope->iope_RastPort,
863 iope->iope_YOffset + gg->TopEdge,
864 iope->iope_XOffset + gg->LeftEdge);
866 return 0;
869 //-----------------------------------------------------------------------------
871 static ULONG DtFindToolType(Class *cl, Object *o, struct iopFindToolType *ioft)
873 struct InstanceData *inst = INST_DATA(cl, o);
874 ULONG Result = 0;
876 d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx Start=%08lx Name=<%s>\n", \
877 __FILE__, __FUNC__, __LINE__, o, inst, *ioft->ioftt_ToolTypeValue, ioft->ioftt_ToolTypeName));
879 if (inst->iobj_tooltypes)
881 STRPTR *TTSearch = inst->iobj_tooltypes;
883 if (*ioft->ioftt_ToolTypeValue)
885 // Start search from given position
886 TTSearch = ioft->ioftt_ToolTypeValue;
888 // find starting point inf tooltypes array
889 while (*TTSearch)
891 if (*TTSearch == *ioft->ioftt_ToolTypeValue)
892 break;
893 TTSearch++;
896 d1(kprintf("%s/%s/%ld: Start=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, TTSearch, *TTSearch));
899 while (*TTSearch)
901 d1(kprintf("%s/%s/%ld: Search=<%s>\n", __FILE__, __FUNC__, __LINE__, *TTSearch));
903 if (ToolTypeNameCmp(ioft->ioftt_ToolTypeName, *TTSearch))
905 // Found!
906 Result = 1;
907 d1(kprintf("%s/%s/%ld: Found=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, TTSearch, *TTSearch));
908 *ioft->ioftt_ToolTypeValue = *TTSearch;
909 break;
911 TTSearch++;
915 d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
917 return Result;
920 //-----------------------------------------------------------------------------
922 static ULONG DtGetToolTypeValue(Class *cl, Object *o, struct iopGetToolTypeValue *iotv)
924 // struct InstanceData *inst = INST_DATA(cl, o);
925 ULONG Result = 0;
926 STRPTR tt = iotv->iotv_ToolTypeValue;
928 d1(kprintf("%s/%s/%ld: ToolType=<%s>\n", __FILE__, __FUNC__, __LINE__, tt, tt ? tt : (UBYTE *) ""));
930 if (tt)
932 while (*tt && '=' != *tt)
933 tt++;
935 if ('=' == *tt)
937 ++tt; // Skip "="
939 d1(kprintf("%s/%s/%ld: Value=<%s>\n", __FILE__, __FUNC__, __LINE__, tt));
941 if ('$' == *tt || (strlen(tt) > 2 && 0 == Stricmp(tt, "0x")))
943 // Hex string recognized
944 LONG HexVal = 0;
946 Result = 1;
948 while (*tt)
950 UBYTE ch = ToUpper(*tt++);
952 if (!isxdigit(ch))
954 Result = 0;
955 break;
958 if (ch <= '9')
959 HexVal = (HexVal << 4) + (ch - '0');
960 else
961 HexVal = (HexVal << 4) + (ch - 55);
964 if (Result)
965 *iotv->iotv_Value = HexVal;
967 else
969 // Decimal string expected
970 if (-1 != StrToLong(tt, iotv->iotv_Value))
971 Result = 1; // Success!
976 d1(kprintf("%s/%s/%ld: Result=%ld Value=%ld\n", __FILE__, __FUNC__, __LINE__, Result, *iotv->iotv_Value));
978 return Result;
981 //-----------------------------------------------------------------------------
983 static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd)
985 struct InstanceData *inst = INST_DATA(cl, o);
986 struct ExtGadget *gg = (struct ExtGadget *) o;
987 struct RastPort *rp;
988 PLANEPTR MaskPlanePtr;
989 WORD Left, Top;
991 d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst));
992 d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
994 ObtainSemaphoreShared(&inst->iobj_LayoutSemaphore);
996 if (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal)
998 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
999 ScaleRenderBitMapsNormal(cl, o,
1000 inst->iobj_ScaledWidth, inst->iobj_ScaledHeight,
1001 iopd->iopd_Screen);
1003 if (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected)
1005 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1006 ScaleRenderBitMapsSelected(cl, o,
1007 inst->iobj_ScaledWidth, inst->iobj_ScaledHeight,
1008 iopd->iopd_Screen);
1011 if (gg->Flags & GFLG_SELECTED)
1013 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_SelectedMask.iom_MaskBM));
1014 rp = (struct RastPort *) gg->SelectRender;
1015 MaskPlanePtr = inst->iobj_SelectedMask.iom_MaskBM ? inst->iobj_SelectedMask.iom_MaskBM->Planes[0] : NULL;
1017 d1(DumpMask(&inst->iobj_SelectedMask));
1019 if (rp && (inst->iobj_layoutflags & IOBLAYOUTF_BackfillSelected))
1021 inst->iobj_layoutflags &= ~IOBLAYOUTF_BackfillSelected;
1022 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillPenSel=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillPenSel));
1024 if (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenSel)
1026 // Fill transparent parts of icon with backfill color via inverted mask
1027 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx rp=%08lx iobj_BackfillRp=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, rp, inst->iobj_BackfillRp));
1029 ASSERT_d1(gg->Width < GetBitMapAttr(rp->BitMap, BMA_WIDTH));
1030 ASSERT_d1(gg->Height < GetBitMapAttr(rp->BitMap, BMA_HEIGHT));
1032 SetRast(inst->iobj_BackfillRp, inst->iobj_BackfillPenSel);
1033 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1034 BltMaskBitMapRastPort(inst->iobj_BackfillRp->BitMap,
1035 0, 0,
1036 rp, 0, 0,
1037 gg->Width, gg->Height,
1038 ABC | ABNC | ANBC,
1039 inst->iobj_SelectedMask.iom_MaskInvBM->Planes[0]);
1041 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillRp=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillRp));
1045 else
1047 rp = (struct RastPort *) gg->GadgetRender;
1048 MaskPlanePtr = inst->iobj_NormalMask.iom_MaskBM ? inst->iobj_NormalMask.iom_MaskBM->Planes[0] : NULL;
1050 d1(DumpMask(&inst->iobj_NormalMask));
1052 if (rp && (inst->iobj_layoutflags & IOBLAYOUTF_BackfillNormal))
1054 inst->iobj_layoutflags &= ~IOBLAYOUTF_BackfillNormal;
1055 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillPenNorm=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillPenNorm));
1057 if (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenNorm)
1059 // Fill transparent parts of icon with backfill color via inverted mask
1060 ASSERT_d1(gg->Width < GetBitMapAttr(rp->BitMap, BMA_WIDTH));
1061 ASSERT_d1(gg->Height < GetBitMapAttr(rp->BitMap, BMA_HEIGHT));
1063 SetRast(inst->iobj_BackfillRp, inst->iobj_BackfillPenNorm);
1064 BltMaskBitMapRastPort(inst->iobj_BackfillRp->BitMap,
1065 0, 0,
1066 rp, 0, 0,
1067 gg->Width, gg->Height,
1068 ABC | ABNC | ANBC,
1069 inst->iobj_NormalMask.iom_MaskInvBM->Planes[0]);
1074 GetPosition(iopd, gg, &Left, &Top);
1076 if (rp && !(iopd->iopd_DrawFlags & IODRAWF_NoImage))
1078 d1(KPrintF("%s/%s/%ld: o=%08lx rp=%08lx BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, o, rp, rp->BitMap));
1079 d1(KPrintF("%s/%s/%ld: Bytes=%ld Rows=%ld Flags=%02lx Depth=%ld\n", \
1080 __FILE__, __FUNC__, __LINE__, rp->BitMap->BytesPerRow, rp->BitMap->Rows, rp->BitMap->Flags, rp->BitMap->Depth));
1082 if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData && CyberGfxBase
1083 && GetCyberMapAttr(iopd->iopd_Screen->RastPort.BitMap, CYBRMATTR_ISCYBERGFX))
1085 LONG x, y;
1087 d1(KPrintF("%s/%s/%ld: draw via ARGB_Draw o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1089 x = iopd->iopd_XOffset;
1090 y = iopd->iopd_YOffset;
1092 if (IODRAWF_AbsolutePos & iopd->iopd_DrawFlags)
1094 if (!(IODRAWF_NoText & iopd->iopd_DrawFlags))
1096 x += gg->LeftEdge - gg->BoundsLeftEdge;
1097 y += gg->TopEdge - gg->BoundsTopEdge;
1100 else
1102 x += gg->LeftEdge;
1103 y += gg->TopEdge;
1106 ARGB_Draw(cl, o, iopd, x, y);
1108 else
1110 ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm;
1112 if (!(iopd->iopd_DrawFlags & IODRAWF_NoEraseBg))
1114 // Erase icon background
1115 d1(KPrintF("%s/%s/%ld: erase background o=%08lx inst=%08lx\n", \
1116 __FILE__, __FUNC__, __LINE__, o, inst));
1118 EraseRect(iopd->iopd_RastPort,
1119 Left, Top,
1120 Left + gg->Width - 1,
1121 Top + gg->Height - 1);
1124 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx MaskPlanePtr=%08lx BackfillPen=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, MaskPlanePtr, BackfillPen));
1126 if (MaskPlanePtr && (IDTA_BACKFILL_NONE == BackfillPen))
1128 ASSERT_d1(gg->Width < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_WIDTH));
1129 ASSERT_d1(gg->Height < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_HEIGHT));
1131 d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height));
1132 d1(KPrintF("%s/%s/%ld: SelMaskWidth=%lu SelMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_Width, inst->iobj_SelectedMask.iom_Height));
1133 d1(KPrintF("%s/%s/%ld: iom_MaskBM: Width=%lu Height=%lu Depth=%lu Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, \
1134 GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_WIDTH), \
1135 GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_HEIGHT), \
1136 GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_DEPTH), \
1137 GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_FLAGS)));
1138 d1(KPrintF("%s/%s/%ld: gg->Width=%lu gg->Height=%lu\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height));
1139 d1(KPrintF("%s/%s/%ld: use BltMaskBitMapRastPort o=%08lx inst=%08lx\n", \
1140 __FILE__, __FUNC__, __LINE__, o, inst));
1142 d1(DumpMaskPlane(&inst->iobj_NormalMask));
1143 d1(DumpMaskPlane(&inst->iobj_SelectedMask));
1145 BltMaskBitMapRastPort(rp->BitMap,
1146 0, 0,
1147 iopd->iopd_RastPort,
1148 Left, Top,
1149 gg->Width, gg->Height,
1150 ABC | ABNC | ANBC,
1151 MaskPlanePtr);
1153 else
1155 ASSERT_d1(gg->Width < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_WIDTH));
1156 ASSERT_d1(gg->Height < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_HEIGHT));
1158 d1(KPrintF("%s/%s/%ld: use ClipBlit o=%08lx inst=%08lx\n", \
1159 __FILE__, __FUNC__, __LINE__, o, inst));
1160 ClipBlit(rp, 0, 0,
1161 iopd->iopd_RastPort,
1162 Left, Top, gg->Width, gg->Height,
1163 ABC | ABNC);
1168 if (rp && !(iopd->iopd_DrawFlags & IODRAWF_NoText))
1170 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1171 if (inst->iobj_text)
1172 DrawIconText(cl, o, iopd);
1175 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
1177 d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1179 return 0;
1182 //-----------------------------------------------------------------------------
1184 static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl)
1186 struct InstanceData *inst = INST_DATA(cl, o);
1187 struct ExtGadget *gg = (struct ExtGadget *) o;
1189 d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst));
1190 TIMESTAMP_d1();
1192 ObtainSemaphore(&inst->iobj_LayoutSemaphore);
1194 d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1195 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \
1196 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height));
1197 d1(KPrintF("%s/%s/%ld: iobj_layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
1199 if (inst->iobj_UnscaledNakedWidth != inst->iobj_NakedWidth
1200 || inst->iobj_UnscaledNakedHeight != inst->iobj_NakedHeight
1201 || (inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected)))
1203 // We need to scale the icon!
1204 d1(KPrintF("%s/%s/%ld: UnscaledWidth=%lu UnscaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight));
1205 d1(KPrintF("%s/%s/%ld: ScaledWidth=%lu ScaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_ScaledWidth, inst->iobj_ScaledHeight));
1207 DoMethod(o, IDTM_ScaleIcon,
1208 inst->iobj_NakedWidth, inst->iobj_NakedHeight,
1209 iopl->iopl_Flags);
1212 TIMESTAMP_d1();
1214 d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1215 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \
1216 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height));
1218 LayoutIconSize(cl, o, iopl->iopl_RastPort);
1220 d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1221 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \
1222 inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height));
1224 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1225 TIMESTAMP_d1();
1227 // If ARGB image data present, allocate auxiliary buffer for rendering
1228 if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData)
1230 d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags));
1232 LayoutARGB(cl, o, &inst->iobj_NormalARGB);
1234 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1236 // If selected ARGB image data present, allocate auxiliary buffer for rendering
1237 if (inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData)
1239 d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags));
1241 LayoutARGB(cl, o, &inst->iobj_SelectedARGB);
1243 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1247 d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags));
1248 TIMESTAMP_d1();
1250 if (!(inst->iobj_layoutflags & (IOBLAYOUTF_NormalImage | IOBLAYOUTF_SelectedImage))
1251 && (iopl->iopl_Flags & (IOLAYOUTF_NormalImage | IOLAYOUTF_SelectedImage))
1252 && (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenNorm))
1254 inst->iobj_BackfillRp = InitRast(cl, o, iopl, &inst->iobj_BackfillRastPort);
1255 inst->iobj_layoutflags |= IOBLAYOUTF_BackfillNormal | IOBLAYOUTF_BackfillSelected;
1258 TIMESTAMP_d1();
1260 if (!(inst->iobj_layoutflags & IOBLAYOUTF_NormalImage)
1261 && (iopl->iopl_Flags & IOLAYOUTF_NormalImage)
1262 && NULL == gg->GadgetRender)
1264 gg->GadgetRender = InitRast(cl, o, iopl, &inst->iobj_RenderRastPort);
1266 d1(KPrintF("%s/%s/%ld: IOBLAYOUTF_NormalImage GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, gg->GadgetRender));
1267 TIMESTAMP_d1();
1269 if (gg->GadgetRender)
1271 struct RastPort *rp = (struct RastPort *) gg->GadgetRender;
1272 ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm;
1274 if (!(inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal))
1276 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1277 DrawFrame(cl, o, rp,
1278 inst->iobj_UnscaledWidth,
1279 inst->iobj_UnscaledHeight,
1280 inst->iobj_frametype);
1283 inst->iobj_layoutflags |= IOBLAYOUTF_NormalImage;
1284 TIMESTAMP_d1();
1286 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx BackfillPen=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, BackfillPen));
1287 if (IDTA_BACKFILL_NONE != BackfillPen)
1289 SetAPen(rp, BackfillPen);
1290 RectFill(rp,
1291 inst->iobj_imgleft, inst->iobj_imgtop,
1292 gg->Width - inst->iobj_imgleft - inst->iobj_imgright - 1,
1293 gg->Height - inst->iobj_imgtop - inst->iobj_imgbottom - 1);
1296 TIMESTAMP_d1();
1298 // mask bitmap already generated?
1299 if (NULL == inst->iobj_NormalMask.iom_MaskBM)
1301 d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, \
1302 inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height));
1303 d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \
1304 __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight));
1306 inst->iobj_NormalMask.iom_MaskBM = GenMask(cl, o,
1307 GetBitMapAttr(rp->BitMap, BMA_WIDTH),
1308 GetBitMapAttr(rp->BitMap, BMA_HEIGHT),
1309 GetBitMapAttr(rp->BitMap, BMA_DEPTH),
1310 GetBitMapAttr(rp->BitMap, BMA_FLAGS),
1311 inst->iobj_NormalMask.iom_Mask,
1312 (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal) ? FRAMETYPE_NONE : inst->iobj_frametype,
1313 inst->iobj_NormalMask.iom_Width,
1314 inst->iobj_NormalMask.iom_Height);
1316 d1(KPrintF("%s/%s/%ld: iom_Width=%ld iom_Height=%ld\n", \
1317 __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height));
1319 d1(DumpMaskBM(&inst->iobj_NormalMask));
1321 TIMESTAMP_d1();
1322 if (IDTA_BACKFILL_NONE != BackfillPen)
1324 inst->iobj_NormalMask.iom_MaskInvBM = GenInvMask(cl, o, inst->iobj_NormalMask.iom_MaskBM);
1329 d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags));
1330 TIMESTAMP_d1();
1332 if (!(inst->iobj_layoutflags & IOBLAYOUTF_SelectedImage)
1333 && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage)
1334 && NULL == gg->SelectRender)
1336 gg->SelectRender = InitRast(cl, o, iopl, &inst->iobj_SelectRastPort);
1338 d1(KPrintF("%s/%s/%ld: IOBLAYOUTF_SelectedImage SelectRender=%08lx\n", __FILE__, __FUNC__, __LINE__, gg->SelectRender));
1340 if (gg->SelectRender)
1342 struct RastPort *rp = (struct RastPort *) gg->SelectRender;
1343 ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm;
1345 if (!(inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected))
1347 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst));
1348 DrawFrame(cl, o, rp,
1349 inst->iobj_UnscaledWidth,
1350 inst->iobj_UnscaledHeight,
1351 inst->iobj_frametypesel);
1354 inst->iobj_layoutflags |= IOBLAYOUTF_SelectedImage;
1356 if (IDTA_BACKFILL_NONE != BackfillPen)
1358 SetAPen(rp, BackfillPen);
1359 RectFill(rp,
1360 inst->iobj_imgleft, inst->iobj_imgtop,
1361 gg->Width - inst->iobj_imgleft - inst->iobj_imgright - 1,
1362 gg->Height - inst->iobj_imgtop - inst->iobj_imgbottom - 1);
1365 // mask bitmap already generated?
1366 if (NULL == inst->iobj_SelectedMask.iom_MaskBM)
1368 d1(KPrintF("%s/%s/%ld: SelMaskWidth=%lu SelMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_Width, inst->iobj_SelectedMask.iom_Height));
1370 inst->iobj_SelectedMask.iom_MaskBM = GenMask(cl, o,
1371 GetBitMapAttr(rp->BitMap, BMA_WIDTH),
1372 GetBitMapAttr(rp->BitMap, BMA_HEIGHT),
1373 GetBitMapAttr(rp->BitMap, BMA_DEPTH),
1374 GetBitMapAttr(rp->BitMap, BMA_FLAGS),
1375 inst->iobj_SelectedMask.iom_Mask,
1376 (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected) ? FRAMETYPE_NONE : inst->iobj_frametypesel,
1377 inst->iobj_SelectedMask.iom_Width,
1378 inst->iobj_SelectedMask.iom_Height);
1380 d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_selmask=%08lx iobj_selmaskbm=%08lx\n", \
1381 __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_SelectedMask.iom_Mask, inst->iobj_SelectedMask.iom_MaskBM));
1383 if (IDTA_BACKFILL_NONE != BackfillPen)
1385 inst->iobj_SelectedMask.iom_MaskInvBM = GenInvMask(cl, o, inst->iobj_SelectedMask.iom_MaskBM);
1388 d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
1391 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
1393 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
1394 d1(KPrintF("%s/%s/%ld: END.\n", __FILE__, __FUNC__, __LINE__));
1395 TIMESTAMP_d1();
1397 return 0;
1400 //-----------------------------------------------------------------------------
1402 static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf)
1404 struct InstanceData *inst = INST_DATA(cl, o);
1405 struct ExtGadget *gg = (struct ExtGadget *) o;
1407 d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst));
1409 ObtainSemaphore(&inst->iobj_LayoutSemaphore);
1411 FreeARGBImageLayout(&inst->iobj_NormalARGB);
1412 FreeARGBImageLayout(&inst->iobj_SelectedARGB);
1414 if (inst->iobj_BackfillRp)
1416 if (inst->iobj_BackfillRp->BitMap)
1418 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_BackfillRp->BitMap));
1419 FreeBitMap(inst->iobj_BackfillRp->BitMap);
1420 inst->iobj_BackfillRp->BitMap = NULL;
1423 inst->iobj_BackfillRp = NULL;
1425 if (gg->SelectRender)
1427 struct RastPort *rp = (struct RastPort *) gg->SelectRender;
1429 if (rp->BitMap)
1431 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap));
1432 FreeBitMap(rp->BitMap);
1433 rp->BitMap = NULL;
1436 gg->SelectRender = NULL;
1438 if (gg->GadgetRender)
1440 struct RastPort *rp = (struct RastPort *) gg->GadgetRender;
1442 if (rp->BitMap)
1444 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap));
1445 FreeBitMap(rp->BitMap);
1446 rp->BitMap = NULL;
1448 gg->GadgetRender = NULL;
1450 if (inst->iobj_NormalMask.iom_MaskBM)
1452 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM));
1453 FreeBitMap(inst->iobj_NormalMask.iom_MaskBM);
1454 inst->iobj_NormalMask.iom_MaskBM = NULL;
1456 if (inst->iobj_SelectedMask.iom_MaskBM)
1458 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
1459 FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM);
1460 inst->iobj_SelectedMask.iom_MaskBM = NULL;
1462 if (inst->iobj_NormalMask.iom_MaskInvBM)
1464 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskInvBM));
1465 FreeBitMap(inst->iobj_NormalMask.iom_MaskInvBM);
1466 inst->iobj_NormalMask.iom_MaskInvBM = NULL;
1468 if (inst->iobj_SelectedMask.iom_MaskInvBM)
1470 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskInvBM));
1471 FreeBitMap(inst->iobj_SelectedMask.iom_MaskInvBM);
1472 inst->iobj_SelectedMask.iom_MaskInvBM = NULL;
1475 // Remove borders
1476 gg->Width = inst->iobj_NakedWidth;
1477 gg->Height = inst->iobj_NakedHeight;
1479 inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth;
1480 inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight;
1482 d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \
1483 __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight));
1484 d1(KPrintF("%s/%s/%ld: iobj_imgleft=%ld iobj_imgright=%ld\n", \
1485 __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgright));
1486 d1(KPrintF("%s/%s/%ld: iobj_imgtop=%ld iobj_imgbottom=%ld\n", \
1487 __FILE__, __FUNC__, __LINE__, inst->iobj_imgtop, inst->iobj_imgbottom));
1489 inst->iobj_layoutflags &= (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected);
1491 d1(KPrintF("%s/%s/%ld: END layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
1493 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
1495 return DoSuperMethodA(cl, o, (Msg) opf);
1498 //----------------------------------------------------------------------------------------
1500 static ULONG DtSet(Class *cl, Object *o, struct opSet *ops)
1502 struct InstanceData *inst = INST_DATA(cl, o);
1503 ULONG Result;
1505 d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, INST_DATA(cl, o)));
1507 // Make sure we have no pending layout when settings are changed!
1508 ObtainSemaphore(&inst->iobj_LayoutSemaphore);
1510 Result = DoSuperMethodA(cl, o, (Msg) ops);
1512 SetTags(cl, o, ops);
1514 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
1516 d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, INST_DATA(cl, o)));
1518 return Result;
1521 //----------------------------------------------------------------------------------------
1523 static ULONG DtGet(Class *cl, Object *o, struct opGet *opg)
1525 struct InstanceData *inst = INST_DATA(cl, o);
1526 ULONG result = 1;
1527 struct TagItem AttrList[2];
1529 AttrList[0].ti_Tag = opg->opg_AttrID;
1530 AttrList[0].ti_Data = (ULONG) opg->opg_Storage;
1531 AttrList[1].ti_Tag = TAG_END;
1532 UnpackStructureTags(inst, packTable, AttrList);
1534 switch (opg->opg_AttrID)
1536 case IDTA_Text:
1537 *opg->opg_Storage = (ULONG) inst->iobj_text;
1538 break;
1540 case IDTA_LayoutFlags:
1541 *opg->opg_Storage = inst->iobj_layoutflags;
1542 break;
1544 case IDTA_DefaultTool:
1545 *opg->opg_Storage = (ULONG) inst->iobj_defaulttool;
1546 break;
1548 case IDTA_ToolWindow:
1549 *opg->opg_Storage = (ULONG) inst->iobj_ToolWindow;
1550 break;
1552 case IDTA_Mask_Normal:
1553 *opg->opg_Storage = (ULONG) ((inst->iobj_NormalMask.iom_MaskBM && (IDTA_BACKFILL_NONE == inst->iobj_BackfillPenNorm))
1554 ? inst->iobj_NormalMask.iom_MaskBM->Planes[0] : NULL);
1555 break;
1557 case IDTA_Mask_Selected:
1558 *opg->opg_Storage = (ULONG) ((inst->iobj_SelectedMask.iom_MaskBM && (IDTA_BACKFILL_NONE == inst->iobj_BackfillPenSel))
1559 ? inst->iobj_SelectedMask.iom_MaskBM->Planes[0] : NULL);
1560 break;
1562 case IDTA_MaskBM_Normal:
1563 *opg->opg_Storage = (ULONG) ((IDTA_BACKFILL_NONE == inst->iobj_BackfillPenNorm) ? inst->iobj_NormalMask.iom_MaskBM : NULL);
1564 break;
1566 case IDTA_MaskBM_Selected:
1567 *opg->opg_Storage = (ULONG) ((IDTA_BACKFILL_NONE == inst->iobj_BackfillPenSel) ? inst->iobj_SelectedMask.iom_MaskBM : NULL);
1568 break;
1570 case IDTA_AlphaChannel:
1571 *opg->opg_Storage = (ULONG) inst->iobj_NormalARGB.iargb_AlphaChannel;
1572 break;
1574 case IDTA_SelAlphaChannel:
1575 *opg->opg_Storage = (ULONG) inst->iobj_SelectedARGB.iargb_AlphaChannel;
1576 break;
1578 case IDTA_ARGBImageData:
1579 *opg->opg_Storage = (ULONG) &inst->iobj_NormalARGB.iargb_ARGBimage;
1580 d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \
1581 __FILE__, __FUNC__, __LINE__, &inst->iobj_NormalARGB.iargb_ARGBimage,
1582 inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData));
1583 break;
1585 case IDTA_SelARGBImageData:
1586 *opg->opg_Storage = (ULONG) &inst->iobj_SelectedARGB.iargb_ARGBimage;
1587 d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \
1588 __FILE__, __FUNC__, __LINE__, &inst->iobj_SelectedARGB.iargb_ARGBimage,
1589 inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData));
1590 break;
1592 case IDTA_ToolTypes:
1593 *opg->opg_Storage = (ULONG) inst->iobj_tooltypes;
1594 break;
1596 case DTA_Name:
1597 *opg->opg_Storage = (ULONG) inst->iobj_name;
1598 break;
1600 case IDTA_UnscaledWidth:
1601 *opg->opg_Storage = (ULONG) inst->iobj_UnscaledWidth;
1602 break;
1604 case IDTA_UnscaledHeight:
1605 *opg->opg_Storage = (ULONG) inst->iobj_UnscaledHeight;
1606 break;
1608 case IDTA_WindowRect:
1609 switch (inst->iobj_type)
1611 case WBDISK:
1612 case WBDRAWER:
1613 case WBGARBAGE:
1614 d1(kprintf("%s/%s/%ld: IDTA_WindowRect <%s> Left=%ld Top=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \
1615 inst->iobj_text, inst->iobj_winrect.Left, inst->iobj_winrect.Top, \
1616 inst->iobj_winrect.Width, inst->iobj_winrect.Height));
1618 if (0 != inst->iobj_winrect.Width && 0 != inst->iobj_winrect.Height)
1619 *opg->opg_Storage = (ULONG) &inst->iobj_winrect;
1620 else
1621 *opg->opg_Storage = (ULONG) NULL;
1622 break;
1623 default:
1624 result = 0;
1625 break;
1627 break;
1629 default:
1630 result = DoSuperMethodA(cl, o, (Msg) opg);
1631 break;
1634 return result;
1637 //----------------------------------------------------------------------------------------
1639 static ULONG DtScaleIcon(Class *cl, Object *o, struct iopScaleIcon *iops)
1641 struct InstanceData *inst = INST_DATA(cl, o);
1642 ULONG NewWidth, NewHeight;
1643 ULONG Success;
1644 struct Hook *RenderHook = NULL;
1646 d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, inst));
1648 GetAttr(IDTA_RenderHook, o, (APTR) &RenderHook);
1649 if (RenderHook)
1650 return FALSE; // No scaling with RenderHook
1652 NewWidth = iops->iops_NewWidth;
1653 NewHeight = iops->iops_NewHeight;
1655 d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%lu\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight));
1657 ObtainSemaphore(&inst->iobj_LayoutSemaphore);
1659 if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData)
1661 // Scale ARGB icon
1662 ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR
1663 | SCALEFLAGF_AVERAGE;
1665 Success = ScaleARGB(cl, o, &inst->iobj_NormalARGB, &inst->iobj_NormalMask,
1666 NewWidth, NewHeight, ScaleFlags);
1668 if (Success && inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData)
1670 ScaleARGB(cl, o, &inst->iobj_SelectedARGB,
1671 &inst->iobj_SelectedMask, NewWidth, NewHeight, ScaleFlags);
1674 // Mask and Alpha are automatically recreated during IDTM_Layout
1676 if (Success)
1678 // Mask will be generated in scaled size
1679 inst->iobj_NakedMaskWidth = NewWidth;
1680 inst->iobj_NakedMaskHeight = NewHeight;
1681 d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height));
1684 else
1686 // Scaling is postponed until IDTM_Draw
1687 d1(KPrintF("%s/%s/%ld: Scaling is postponed until IDTM_Draw\n", __FILE__, __FUNC__, __LINE__));
1689 Success = TRUE;
1691 if (iops->iops_Flags & IOLAYOUTF_NormalImage)
1692 inst->iobj_layoutflags |= IOBLAYOUTF_ScaleNormal;
1693 if (iops->iops_Flags & IOLAYOUTF_SelectedImage)
1694 inst->iobj_layoutflags |= IOBLAYOUTF_ScaleSelected;
1697 if (Success)
1699 inst->iobj_NakedWidth = NewWidth;
1700 inst->iobj_NakedHeight = NewHeight;
1702 inst->iobj_layoutflags &= ~IOBLAYOUTF_Size;
1705 ReleaseSemaphore(&inst->iobj_LayoutSemaphore);
1707 d1(KPrintF("%s/%s/%ld: END Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, Success, inst->iobj_layoutflags));
1709 return Success;
1712 //----------------------------------------------------------------------------------------
1714 static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops)
1716 struct InstanceData *inst = INST_DATA(cl, o);
1718 PackStructureTags(inst, packTable, ops->ops_AttrList);
1720 return 0;
1723 //----------------------------------------------------------------------------------------
1725 static void LayoutIconText(struct InstanceData *inst, struct RastPort *rp, struct ExtGadget *gg)
1727 TIMESTAMP_d1();
1728 MySetFont(inst, rp, inst->iobj_Font);
1730 inst->iobj_FontBaseLine = MyGetFontBaseline(inst, rp);
1732 TIMESTAMP_d1();
1733 MySetSoftStyle(inst, rp,
1734 inst->iobj_TextStyle, FSF_ITALIC | FSF_UNDERLINED | FSF_BOLD | FSF_EXTENDED);
1736 TIMESTAMP_d1();
1737 DoReLayout(inst, gg, rp);
1739 TIMESTAMP_d1();
1740 MyDoneRastPort(inst, rp);
1742 TIMESTAMP_d1();
1745 //----------------------------------------------------------------------------------------
1747 static void DrawIconText(Class *cl, Object *o, struct iopDraw *iopd)
1749 struct InstanceData *inst = INST_DATA(cl, o);
1750 struct ExtGadget *gg = (struct ExtGadget *) o;
1751 WORD x, y;
1752 WORD TextX, TextY;
1754 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1756 ObtainSemaphoreShared(&inst->iobj_TextSemaphore);
1758 GetPosition(iopd, gg, &x, &y);
1760 MySetFont(inst, iopd->iopd_RastPort, inst->iobj_Font);
1762 MySetSoftStyle(inst, iopd->iopd_RastPort,
1763 inst->iobj_TextStyle, FSF_ITALIC | FSF_UNDERLINED | FSF_BOLD | FSF_EXTENDED);
1765 TextX = x - inst->iobj_GlobalTextLeftOffset + 1;
1766 TextY = y + gg->Height + inst->iobj_textskip + inst->iobj_FontBaseLine;
1768 if (inst->iobj_SelectedTextRectangle)
1770 TextY += inst->iobj_TextRectBorderY;
1771 //TextX += inst->iobj_TextRectBorderX;
1774 if (gg->Flags & GFLG_SELECTED)
1776 DrawIconTextRect(cl, o, iopd->iopd_RastPort, x, y);
1778 else
1780 EraseIconText(cl, o, iopd->iopd_RastPort, x, y);
1783 #if 0
1785 // TEST: Draw frame around image part
1786 WORD x0, y0;
1787 WORD x1, y1;
1789 y0 = y;
1790 y1 = y0 + gg->Height - 1;
1791 x0 = x;
1792 x1 = x0 + gg->Width - 1;
1794 Move(iopd->iopd_RastPort, x0, y0);
1795 Draw(iopd->iopd_RastPort, x0, y1);
1796 Draw(iopd->iopd_RastPort, x1, y1);
1797 Draw(iopd->iopd_RastPort, x1, y0);
1798 Draw(iopd->iopd_RastPort, x0, y0);
1800 #endif
1802 #if 0
1804 // TEST: Draw frame around entire icon
1805 WORD x0, y0;
1806 WORD x1, y1;
1808 y0 = y;
1809 y1 = y0 + gg->BoundsHeight;
1810 x0 = x + (gg->BoundsLeftEdge - gg->LeftEdge);
1811 x1 = x0 + gg->BoundsWidth;
1813 SetAPen(iopd->iopd_RastPort, 1);
1815 Move(iopd->iopd_RastPort, x0, y0);
1816 Draw(iopd->iopd_RastPort, x0, y1);
1817 Draw(iopd->iopd_RastPort, x1, y1);
1818 Draw(iopd->iopd_RastPort, x1, y0);
1819 Draw(iopd->iopd_RastPort, x0, y0);
1821 #endif
1823 #if 0
1825 // TEST: Draw frame around text part
1826 WORD x0, y0;
1827 WORD x1, y1;
1829 SetAPen(iopd->iopd_RastPort, 1);
1831 y0 = TextY - inst->iobj_FontBaseLine;
1832 y1 = y0 + inst->iobj_TextExtent.te_Height;
1833 x0 = TextX;
1834 if (inst->iobj_SelectedTextRectangle)
1835 x0 += inst->iobj_TextRectBorderX;
1836 x1 = x0 + inst->iobj_TextExtent.te_Width;
1838 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, x1 - x0, y1 - y0));
1840 Move(iopd->iopd_RastPort, x0, y0);
1841 Draw(iopd->iopd_RastPort, x0, y1);
1842 Draw(iopd->iopd_RastPort, x1, y1);
1843 Draw(iopd->iopd_RastPort, x1, y0);
1844 Draw(iopd->iopd_RastPort, x0, y0);
1846 #endif
1847 if (IDTV_TextMode_Outline == inst->iobj_textmode)
1849 // draw outline text
1850 ULONG OrigDrMd;
1852 OrigDrMd = GetDrMd(iopd->iopd_RastPort);
1854 MySetTransparency(inst, iopd->iopd_RastPort, 255 / 2); // 50% transparent
1855 SetAPen(iopd->iopd_RastPort, inst->iobj_TextPenOutline);
1857 DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY + 1);
1858 DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY);
1859 DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 2);
1860 DrawTextAt(inst, iopd->iopd_RastPort, TextX + 2, TextY + 1);
1861 DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY);
1863 SetAPen(iopd->iopd_RastPort,
1864 (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen);
1866 MySetTransparency(inst, iopd->iopd_RastPort, 0); // opaque
1867 SetDrMd(iopd->iopd_RastPort, JAM1);
1869 DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 1);
1871 SetDrMd(iopd->iopd_RastPort, OrigDrMd);
1873 else if (IDTV_TextMode_Shadow == inst->iobj_textmode)
1875 // draw shadow
1876 ULONG OrigDrMd;
1878 OrigDrMd = GetDrMd(iopd->iopd_RastPort);
1880 SetAPen(iopd->iopd_RastPort, inst->iobj_TextPenShadow);
1881 MySetTransparency(inst, iopd->iopd_RastPort, 255 / 2); // 50% transparent
1883 DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 1);
1885 SetAPen(iopd->iopd_RastPort,
1886 (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen);
1888 SetDrMd(iopd->iopd_RastPort, JAM1);
1889 MySetTransparency(inst, iopd->iopd_RastPort, 0); // opaque
1891 DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY);
1893 SetDrMd(iopd->iopd_RastPort, OrigDrMd);
1895 else
1897 // standard icon text
1899 SetABPenDrMd(iopd->iopd_RastPort,
1900 (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen,
1901 inst->iobj_TextBackPen,
1902 inst->iobj_TextDrawMode);
1903 DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY);
1906 MyDoneRastPort(inst, iopd->iopd_RastPort);
1908 ReleaseSemaphore(&inst->iobj_TextSemaphore);
1911 //----------------------------------------------------------------------------------------
1913 static void GetPosition(struct iopDraw *iopd, struct ExtGadget *gg, WORD *x, WORD *y)
1915 *x = iopd->iopd_XOffset;
1916 *y = iopd->iopd_YOffset;
1918 if (iopd->iopd_DrawFlags & IODRAWF_AbsolutePos)
1920 if (!(iopd->iopd_DrawFlags & IODRAWF_NoText))
1922 *x += gg->LeftEdge - gg->BoundsLeftEdge;
1923 *y += gg->TopEdge - gg->BoundsTopEdge;
1926 else
1928 *x += gg->LeftEdge;
1929 *y += gg->TopEdge;
1931 if (iopd->iopd_DrawFlags & IODRAWF_NoText)
1933 *x -= gg->LeftEdge - gg->BoundsLeftEdge;
1934 *y -= gg->TopEdge - gg->BoundsTopEdge;
1939 //----------------------------------------------------------------------------------------
1941 static void DrawTextAt(struct InstanceData *inst, struct RastPort *rp, ULONG x, ULONG y)
1943 struct IconObjectTextLine *iotl;
1944 ULONG n;
1946 for (n = 0; n < Sizeof(inst->iobj_TextLines); n++)
1948 iotl = &inst->iobj_TextLines[n];
1950 if (0 == iotl->iotl_numchars)
1951 break;
1953 Move(rp, x + iotl->iotl_TextLeft, y);
1954 MyText(inst, rp, inst->iobj_text + iotl->iotl_TextStart, iotl->iotl_numchars);
1955 y += iotl->iotl_TextExtent.te_Height;
1959 //----------------------------------------------------------------------------------------
1961 static void DoReLayout(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp)
1963 ULONG n;
1965 d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text));
1967 ObtainSemaphoreShared(&inst->iobj_TextSemaphore);
1969 memset(inst->iobj_TextLines, 0, sizeof(inst->iobj_TextLines));
1970 memset(&inst->iobj_TextExtent, 0, sizeof(inst->iobj_TextExtent));
1972 inst->iobj_numchars = strlen(inst->iobj_text);
1974 d1(kprintf("%s/%s/%ld: iobj_text=<%s> iobj_numchars=%lu\n", \
1975 __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_numchars));
1977 for (n = 0; n < Sizeof(inst->iobj_TextLines); n++)
1979 struct IconObjectTextLine *iotl;
1981 iotl = &inst->iobj_TextLines[n];
1983 iotl->iotl_TextStart = 0;
1984 iotl->iotl_numchars = 0;
1987 inst->iobj_TextLines[0].iotl_numchars = inst->iobj_numchars;
1988 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1990 CalculateTextDimensions(inst, gg, rp);
1992 d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text));
1993 d1(kprintf("%s/%s/%ld: Extent.w=%ld Extent.h=%ld\n", \
1994 __FILE__, __FUNC__, __LINE__, inst->iobj_TextExtent.te_Width, inst->iobj_TextExtent.te_Height));
1996 if (inst->iobj_MultiLineText)
1998 ULONG MaxUsedLineIndex = 0;
2000 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
2002 if (2 * gg->BoundsWidth > 3 * gg->Width)
2004 struct IconObjectTextLine *iotl;
2005 BOOL Split = FALSE;
2006 LONG n1, n2;
2008 iotl = &inst->iobj_TextLines[MaxUsedLineIndex];
2009 if (iotl->iotl_numchars > 2 * 3)
2011 // Start at center of text, and check characters left and right of
2012 // center for suitable division point
2013 // Move check points farther and farther from center, until front or back
2014 // borders (3 characters left) are reached.
2015 for (n1 = n2 = iotl->iotl_numchars / 2; !Split
2016 && (n1 > iotl->iotl_TextStart + 3 || n2 < iotl->iotl_numchars - 3); )
2018 if ( IsSeparator(inst->iobj_text[n1]) )
2020 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n1 - 1;
2021 iotl->iotl_numchars = n1 + 1;
2022 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n1 + 1;
2023 Split = TRUE;
2025 else if ( IsSeparator(inst->iobj_text[n2]) )
2027 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n2 - 1;
2028 iotl->iotl_numchars = n2 + 1;
2029 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n2 + 1;
2030 Split = TRUE;
2033 d1(if (Split) kprintf("%s/%s/%ld: SplitChar=%02lx n=%ld\n", \
2034 __FILE__, __FUNC__, __LINE__, inst->iobj_text[n], n));
2036 if (n1 > iotl->iotl_TextStart + 3)
2037 n1--; // move check point 1 left towards start of text
2038 if (n2 < iotl->iotl_numchars - 3)
2039 n2++; // move check point 2 right towards end of text
2042 d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text));
2043 d1(kprintf("%s/%s/%ld: Split=%ld MaxLine=%ld numchars=%ld TextStart=%ld\n", \
2044 __FILE__, __FUNC__, __LINE__, Split, \
2045 MaxUsedLineIndex, inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars,\
2046 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart));
2048 if (!Split && gg->BoundsWidth > 2 * gg->Width)
2050 // No suitable division point found,
2051 // and text more than twice as wide as icon.
2052 // force division at arithmetic center of text (half of length).
2053 n = iotl->iotl_numchars / 2;
2055 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n - 1;
2056 iotl->iotl_numchars = n + 1;
2057 inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n + 1;
2058 Split = TRUE;
2061 if (Split)
2062 CalculateTextDimensions(inst, gg, rp);
2065 d1(kprintf("%s/%s/%ld: Extent.w=%ld Extent.h=%ld\n", \
2066 __FILE__, __FUNC__, __LINE__, inst->iobj_TextExtent.te_Width, inst->iobj_TextExtent.te_Height));
2070 inst->iobj_GlobalTextLeftOffset = inst->iobj_TextExtent.te_Width - gg->Width;
2072 d1(kprintf("%s/%s/%ld: Width=%ld BoundsWidth=%ld Left=%ld\n", \
2073 __FILE__, __FUNC__, __LINE__, gg->Width, gg->BoundsWidth, inst->iobj_GlobalTextLeftOffset));
2075 inst->iobj_GlobalTextLeftOffset /= 2;
2077 if (inst->iobj_SelectedTextRectangle)
2078 inst->iobj_GlobalTextLeftOffset += inst->iobj_TextRectBorderX;
2080 if (inst->iobj_GlobalTextLeftOffset > 0)
2082 // Text is wider than image
2083 gg->BoundsLeftEdge -= inst->iobj_GlobalTextLeftOffset;
2085 else
2087 // Image is wider than text
2088 struct IconObjectTextLine *iotl;
2089 ULONG n;
2091 for (n = 0; n < Sizeof(inst->iobj_TextLines); n++)
2093 iotl = &inst->iobj_TextLines[n];
2095 iotl->iotl_TextLeft += inst->iobj_GlobalTextLeftOffset;
2099 d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text));
2101 ReleaseSemaphore(&inst->iobj_TextSemaphore);
2105 static BOOL IsSeparator(char ch)
2107 return (BOOL) ('-' == ch || '_' == ch || '=' == ch || isspace(ch));
2110 static ULONG MySetSoftStyle(struct InstanceData *inst, struct RastPort *rp, ULONG style, ULONG enable)
2112 if (inst->iobj_FontHook)
2114 struct ioFontMsg_SetFontStyle iofsfs;
2116 iofsfs.MsgID = iofMsg_SETFONTSTYLE;
2117 iofsfs.iofsfs_RastPort = rp;
2118 iofsfs.iofsfs_FontHandle = inst->iobj_Fonthandle;
2119 iofsfs.iofsfs_Style = style;
2120 iofsfs.iofsfs_Enable = enable;
2122 return (ULONG) CallHookPkt(inst->iobj_FontHook, NULL, &iofsfs);
2124 else
2126 return SetSoftStyle(rp, style, enable);
2130 static void MyText(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length)
2132 if (inst->iobj_FontHook)
2134 struct ioFontMsg_Text ioft;
2136 ioft.MsgID = iofMsg_TEXT;
2137 ioft.ioft_RastPort = rp;
2138 ioft.ioft_FontHandle = inst->iobj_Fonthandle;
2139 ioft.ioft_String = string;
2140 ioft.ioft_Length = Length;
2142 CallHookPkt(inst->iobj_FontHook, NULL, &ioft);
2144 else
2146 Text(rp, string, Length);
2150 static void MyTextExtent(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length, struct TextExtent *tExt)
2152 if (inst->iobj_FontHook)
2154 struct ioFontMsg_TextExtent iofte;
2156 iofte.MsgID = iofMsg_TEXTEXTENT;
2157 iofte.iofte_RastPort = rp;
2158 iofte.iofte_FontHandle = inst->iobj_Fonthandle;
2159 iofte.iofte_String = string;
2160 iofte.iofte_Length = Length;
2161 iofte.iofte_TextExtent = tExt;
2163 CallHookPkt(inst->iobj_FontHook, NULL, &iofte);
2165 else
2167 TextExtent(rp, string, Length, tExt);
2171 static void MySetFont(struct InstanceData *inst, struct RastPort *rp, struct TextFont *tf)
2173 if (inst->iobj_FontHook)
2175 struct ioFontMsg_SetFont iofsf;
2177 iofsf.MsgID = iofMsg_SETFONT;
2178 iofsf.iofsf_RastPort = rp;
2179 iofsf.iofsf_FontHandle = inst->iobj_Fonthandle;
2180 iofsf.iofsf_TextFont = tf;
2182 CallHookPkt(inst->iobj_FontHook, NULL, &iofsf);
2184 else
2186 if (tf)
2187 SetFont(rp, tf);
2191 static void MySetTransparency(struct InstanceData *inst, struct RastPort *rp, ULONG Transparency)
2193 if (inst->iobj_FontHook)
2195 struct ioFontMsg_SetTransparency iofst;
2197 iofst.MsgID = iofMsg_SETTRANSPARENCY;
2198 iofst.iofst_RastPort = rp;
2199 iofst.iofst_FontHandle = inst->iobj_Fonthandle;
2200 iofst.iofst_Transparency = Transparency;
2202 CallHookPkt(inst->iobj_FontHook, NULL, &iofst);
2204 else
2206 // not supported for standard fonts
2210 static void MyDoneRastPort(struct InstanceData *inst, struct RastPort *rp)
2212 if (inst->iobj_FontHook)
2214 struct ioFontMsg_DoneRastPort iofdr;
2216 iofdr.MsgID = iofMsg_DONERASTPORT;
2217 iofdr.iofdr_RastPort = rp;
2218 iofdr.iofdr_FontHandle = inst->iobj_Fonthandle;
2220 CallHookPkt(inst->iobj_FontHook, NULL, &iofdr);
2224 static UWORD MyGetFontBaseline(struct InstanceData *inst, struct RastPort *rp)
2226 if (inst->iobj_FontHook)
2228 struct ioFontMsg_GetFontBaseline iofgfb;
2230 iofgfb.MsgID = iofMsg_GETFONTBASELINE;
2231 iofgfb.iofgfb_RastPort = rp;
2232 iofgfb.iofgfb_FontHandle = inst->iobj_Fonthandle;
2234 return (UWORD) CallHookPkt(inst->iobj_FontHook, NULL, &iofgfb);
2236 else
2238 return (UWORD) rp->Font->tf_Baseline;
2242 //-----------------------------------------------------------------------------
2244 static void CalculateTextDimensions(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp)
2246 ULONG n;
2248 gg->BoundsWidth = gg->Width;
2249 gg->BoundsHeight = gg->Height;
2251 if (inst->iobj_SelectedTextRectangle)
2252 gg->BoundsHeight += 2 * TT_BORDER_Y;
2254 inst->iobj_TextExtent.te_Width = inst->iobj_TextExtent.te_Height = 0;
2256 for (n = 0; n < Sizeof(inst->iobj_TextLines); n++)
2258 struct IconObjectTextLine *iotl;
2260 iotl = &inst->iobj_TextLines[n];
2262 if (iotl->iotl_numchars)
2264 d1(KPrintF("%s/%s/%ld: text=<%s> TextStart=%ld numchars=%ld\n", \
2265 __FILE__, __FUNC__, __LINE__, inst->iobj_text + iotl->iotl_TextStart, iotl->iotl_TextStart, iotl->iotl_numchars));
2267 MyTextExtent(inst, rp, inst->iobj_text + iotl->iotl_TextStart,
2268 iotl->iotl_numchars, &iotl->iotl_TextExtent);
2270 iotl->iotl_TextWidth = 1 + iotl->iotl_TextExtent.te_Extent.MaxX - iotl->iotl_TextExtent.te_Extent.MinX;
2271 if (iotl->iotl_TextExtent.te_Width > iotl->iotl_TextWidth)
2272 iotl->iotl_TextWidth = iotl->iotl_TextExtent.te_Width;
2274 iotl->iotl_TextHeight = 1 + iotl->iotl_TextExtent.te_Extent.MaxY - iotl->iotl_TextExtent.te_Extent.MinY;
2275 if (iotl->iotl_TextExtent.te_Height > iotl->iotl_TextHeight)
2276 iotl->iotl_TextHeight = iotl->iotl_TextExtent.te_Height;
2278 iotl->iotl_TextHeight += 1;
2280 switch (inst->iobj_textmode)
2282 case IDTV_TextMode_Outline:
2283 iotl->iotl_TextWidth += 2;
2284 iotl->iotl_TextHeight += 2;
2285 break;
2286 case IDTV_TextMode_Shadow:
2287 iotl->iotl_TextWidth += 1;
2288 iotl->iotl_TextHeight += 1;
2289 break;
2290 default:
2291 break;
2294 inst->iobj_TextExtent.te_Width = max(inst->iobj_TextExtent.te_Width, 2 + iotl->iotl_TextExtent.te_Width);
2295 inst->iobj_TextExtent.te_Height += iotl->iotl_TextExtent.te_Height;
2297 d1(KPrintF("%s/%s/%ld: iotl_TextExtent: te_Width=%ld te_Height=%ld MinX=%ld MaxX=%ld\n", \
2298 __FILE__, __FUNC__, __LINE__, iotl->iotl_TextExtent.te_Width, \
2299 iotl->iotl_TextExtent.te_Height,
2300 iotl->iotl_TextExtent.te_Extent.MinX,
2301 iotl->iotl_TextExtent.te_Extent.MaxX));
2303 if (inst->iobj_SelectedTextRectangle)
2304 gg->BoundsWidth = max(gg->BoundsWidth, (2 * inst->iobj_TextRectBorderX + inst->iobj_TextExtent.te_Width + 1));
2305 else
2306 gg->BoundsWidth = max(gg->BoundsWidth, inst->iobj_TextExtent.te_Width);
2308 gg->BoundsHeight += iotl->iotl_TextHeight + inst->iobj_textskip;
2311 for (n = 0; n < Sizeof(inst->iobj_TextLines); n++)
2313 struct IconObjectTextLine *iotl;
2315 iotl = &inst->iobj_TextLines[n];
2317 if (iotl->iotl_numchars)
2319 // Center text inside <BoundsWidth>
2320 iotl->iotl_TextLeft = (1 + gg->BoundsWidth - iotl->iotl_TextWidth) / 2;
2322 d1(kprintf("%s/%s/%ld: w=%ld h=%ld Extent.w=%ld Extent.h=%ld Left=%ld\n", \
2323 __FILE__, __FUNC__, __LINE__, iotl->iotl_TextWidth, iotl->iotl_TextHeight, iotl->iotl_TextExtent.te_Width, \
2324 iotl->iotl_TextExtent.te_Height, iotl->iotl_TextLeft));
2329 //-----------------------------------------------------------------------------
2331 static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents)
2333 #if 0
2334 while (*ToolTypeName && *ToolTypeContents
2335 && '=' != *ToolTypeContents
2336 && ToLower(*ToolTypeName) == ToLower(*ToolTypeContents))
2338 ToolTypeName++;
2339 ToolTypeContents++;
2341 #else
2342 while (*ToolTypeName && *ToolTypeContents)
2344 UBYTE ch1; // Work-around for GCC compiler bug
2346 if ('=' == *ToolTypeContents)
2347 break;
2348 ch1 = ToLower(*ToolTypeName);
2349 if (ch1 != ToLower(*ToolTypeContents))
2350 break;
2352 ToolTypeName++;
2353 ToolTypeContents++;
2355 #endif
2357 return (BOOL) ('\0' == *ToolTypeName && ('\0' == *ToolTypeContents || '=' == *ToolTypeContents));
2360 //-----------------------------------------------------------------------------
2362 static void SetTags(Class *cl, Object *o, struct opSet *ops)
2364 struct InstanceData *inst = INST_DATA(cl, o);
2365 struct ExtGadget *gg = (struct ExtGadget *) o;
2366 struct TagItem *dTag;
2367 BOOL SizeSet = FALSE;
2368 BOOL NeedFreeLayout = FALSE;
2370 DoOmSet(cl, o, ops);
2372 SetAllocTagProtected(IDTA_Text, &inst->iobj_text, ops->ops_AttrList, &inst->iobj_TextSemaphore);
2373 SetAllocTag(IDTA_DefaultTool, &inst->iobj_defaulttool, ops->ops_AttrList);
2374 SetAllocTag(IDTA_ToolWindow, &inst->iobj_ToolWindow, ops->ops_AttrList);
2376 dTag = FindTagItem(IDTA_ARGBImageData, ops->ops_AttrList);
2377 if (dTag)
2379 d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_ARGBImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data));
2380 NeedFreeLayout = TRUE;
2381 ReplaceARGBImage(&inst->iobj_NormalARGB, (struct ARGBHeader *) dTag->ti_Data);
2384 dTag = FindTagItem(IDTA_SelARGBImageData, ops->ops_AttrList);
2385 if (dTag)
2387 d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_SelARGBImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data));
2388 NeedFreeLayout = TRUE;
2389 ReplaceARGBImage(&inst->iobj_SelectedARGB, (struct ARGBHeader *) dTag->ti_Data);
2392 dTag = FindTagItem(GA_Width, ops->ops_AttrList);
2393 if (dTag)
2395 d1(KPrintF("%s/%s/%ld: o=%08lx GA_Width=%ld\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data));
2396 SizeSet = TRUE;
2397 NeedFreeLayout = TRUE;
2398 gg->Width = inst->iobj_NakedMaskWidth
2399 = inst->iobj_NakedWidth
2400 = inst->iobj_ScaledWidth
2401 = dTag->ti_Data;
2403 if (!(inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected)))
2405 inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth = dTag->ti_Data;
2408 d1(KPrintF("%s/%s/%ld: o=%08lx Width=%lu\n", __FILE__, __FUNC__, __LINE__, o, gg->Width));
2410 dTag = FindTagItem(GA_Height, ops->ops_AttrList);
2411 if (dTag)
2413 SizeSet = TRUE;
2414 NeedFreeLayout = TRUE;
2415 gg->Height = inst->iobj_NakedMaskHeight
2416 = inst->iobj_NakedHeight
2417 = inst->iobj_ScaledHeight
2418 = dTag->ti_Data;
2420 if (!(inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected)))
2422 inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight = dTag->ti_Data;
2425 d1(KPrintF("%s/%s/%ld: o=%08lx Height=%lu\n", __FILE__, __FUNC__, __LINE__, o, gg->Height));
2428 dTag = FindTagItem(IDTA_UnscaledWidth, ops->ops_AttrList);
2429 if (dTag)
2431 inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth = dTag->ti_Data;
2432 NeedFreeLayout = TRUE;
2435 dTag = FindTagItem(IDTA_UnscaledHeight, ops->ops_AttrList);
2436 if (dTag)
2438 inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight = dTag->ti_Data;
2439 NeedFreeLayout = TRUE;
2442 dTag = FindTagItem(IDTA_ToolTypes, ops->ops_AttrList);
2443 if (dTag)
2444 SetToolTypes(inst, (const STRPTR *) dTag->ti_Data);
2446 SetAllocTag(DTA_Name, &inst->iobj_name, ops->ops_AttrList);
2448 dTag = FindTagItem(IDTA_ScalePercentage, ops->ops_AttrList);
2449 if (dTag)
2451 inst->iobj_ScalingPercentage = dTag->ti_Data;
2453 if (inst->iobj_ScalingPercentage < IDTA_ScalePercentage_MIN)
2454 inst->iobj_ScalingPercentage = IDTA_ScalePercentage_MIN;
2455 else if (inst->iobj_ScalingPercentage > IDTA_ScalePercentage_MAX)
2456 inst->iobj_ScalingPercentage = IDTA_ScalePercentage_MAX;
2458 d1(KPrintF("%s/%s/%ld: IDTA_ScalePercentage: %ld\n", \
2459 __FILE__, __FUNC__, __LINE__, inst->iobj_ScalingPercentage));
2462 dTag = FindTagItem(IDTA_SizeConstraints, ops->ops_AttrList);
2463 if (dTag)
2465 struct Rectangle *NewConstraints = (struct Rectangle *) dTag->ti_Data;
2467 inst->iobj_SizeConstraints = *NewConstraints;
2468 d1(KPrintF("%s/%s/%ld: iobj_SizeConstraint: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", \
2469 __FILE__, __FUNC__, __LINE__, inst->iobj_SizeConstraints.MinX, \
2470 inst->iobj_SizeConstraints.MinY, inst->iobj_SizeConstraints.MaxX, \
2471 inst->iobj_SizeConstraints.MaxY));
2474 dTag = FindTagItem(IDTA_Mask_Normal, ops->ops_AttrList);
2475 if (dTag)
2477 // dispose old normal mask
2478 MyFreeVecPooled(ChipMemPool, (APTR *) &inst->iobj_NormalMask.iom_Mask);
2479 if (inst->iobj_NormalMask.iom_MaskBM)
2481 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM));
2482 FreeBitMap(inst->iobj_NormalMask.iom_MaskBM);
2483 inst->iobj_NormalMask.iom_MaskBM = NULL;
2486 d1(KPrintF("%s/%s/%ld: IDTA_Mask_Normal=%08lx iom_Width=%ld iom_Height=%ld\n", \
2487 __FILE__, __FUNC__, __LINE__, dTag->ti_Data, inst->iobj_NormalMask.iom_Width,\
2488 inst->iobj_NormalMask.iom_Height));
2490 if (dTag->ti_Data)
2492 // create new normal mask
2493 size_t Size;
2495 Size = inst->iobj_NormalMask.iom_Height * BYTESPERROW(inst->iobj_NormalMask.iom_Width);
2496 Size = ALIGN_LONG(Size);
2498 inst->iobj_NormalMask.iom_Mask = MyAllocVecPooled(ChipMemPool, Size);
2500 if (inst->iobj_NormalMask.iom_Mask)
2501 CopyMemQuick((UBYTE *) dTag->ti_Data, inst->iobj_NormalMask.iom_Mask, Size);
2503 d1(DumpMask(&inst->iobj_NormalMask));
2507 dTag = FindTagItem(IDTA_Mask_Selected, ops->ops_AttrList);
2508 if (dTag)
2510 // dispose old selected mask
2511 MyFreeVecPooled(ChipMemPool, (APTR *) &inst->iobj_SelectedMask.iom_Mask);
2512 if (inst->iobj_SelectedMask.iom_MaskBM)
2514 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
2515 FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM);
2516 inst->iobj_SelectedMask.iom_MaskBM = NULL;
2519 d1(KPrintF("%s/%s/%ld: IDTA_Mask_Selected=%08lx iom_Width=%ld iom_Height=%ld\n", \
2520 __FILE__, __FUNC__, __LINE__, dTag->ti_Data, inst->iobj_NormalMask.iom_Width, \
2521 inst->iobj_NormalMask.iom_Height));
2522 d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
2524 if (dTag->ti_Data)
2526 // create new selected mask
2527 size_t Size;
2529 Size = inst->iobj_SelectedMask.iom_Height * BYTESPERROW(inst->iobj_SelectedMask.iom_Width);
2530 Size = ALIGN_LONG(Size);
2532 inst->iobj_SelectedMask.iom_Mask = MyAllocVecPooled(ChipMemPool, Size);
2534 if (inst->iobj_SelectedMask.iom_Mask)
2535 CopyMemQuick((UBYTE *) dTag->ti_Data, inst->iobj_SelectedMask.iom_Mask, Size);
2539 dTag = FindTagItem(IDTA_WindowRect, ops->ops_AttrList);
2540 if (dTag && dTag->ti_Data)
2542 struct IBox *WinRect = (struct IBox *) dTag->ti_Data;
2544 d1(kprintf("%s/%s/%ld: IDTA_WindowRect=%08lx <%s> Left=%ld Top=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \
2545 WinRect, inst->iobj_text, WinRect->Left, WinRect->Top, WinRect->Width, WinRect->Height));
2547 inst->iobj_winrect = *WinRect;
2550 if (SizeSet)
2551 CheckIfScalingRequired(cl, o);
2553 if (NeedFreeLayout)
2555 d1(KPrintF("%s/%s/%ld: FreeLayout enforced\n", __FILE__, __FUNC__, __LINE__));
2556 DoMethod(o, IDTM_FreeLayout, IOFREELAYOUTF_ScreenAvailable);
2560 //-----------------------------------------------------------------------------
2562 static void SetAllocTag(ULONG TagValue, STRPTR *DataPtr, struct TagItem *TagList)
2564 struct TagItem *dTag;
2566 dTag = FindTagItem(TagValue, TagList);
2567 if (dTag)
2569 STRPTR OldData = *DataPtr;
2571 *DataPtr = AllocCopyString((CONST_STRPTR) dTag->ti_Data);
2572 MyFreeVecPooled(PubMemPool, (APTR) &OldData);
2576 //-----------------------------------------------------------------------------
2578 static void SetAllocTagProtected(ULONG TagValue, STRPTR *DataPtr,
2579 struct TagItem *TagList, struct SignalSemaphore *Sema)
2581 struct TagItem *dTag;
2583 dTag = FindTagItem(TagValue, TagList);
2584 if (dTag)
2586 STRPTR OldData = *DataPtr;
2588 ObtainSemaphore(Sema);
2590 *DataPtr = AllocCopyString((CONST_STRPTR) dTag->ti_Data);
2591 MyFreeVecPooled(PubMemPool, (APTR) &OldData);
2593 ReleaseSemaphore(Sema);
2597 //-----------------------------------------------------------------------------
2599 static STRPTR AllocCopyString(CONST_STRPTR OrigString)
2601 STRPTR NewString;
2603 if (OrigString)
2605 NewString = MyAllocVecPooled(PubMemPool, 1 + strlen(OrigString));
2606 if (NewString)
2608 strcpy(NewString, OrigString);
2611 else
2613 NewString = NULL;
2616 return NewString;
2619 //-----------------------------------------------------------------------------
2621 static void SetToolTypes(struct InstanceData *inst, const STRPTR *NewToolTypes)
2623 // same ToolType array as before?
2624 if (NewToolTypes != (const STRPTR *) inst->iobj_tooltypes)
2626 STRPTR *OldToolTypes = inst->iobj_tooltypes;
2628 inst->iobj_tooltypes = CloneToolTypes(NewToolTypes);
2630 if (OldToolTypes)
2631 MyFreeVecPooled(PubMemPool, (APTR) &OldToolTypes);
2635 //-----------------------------------------------------------------------------
2637 static STRPTR *CloneToolTypes(const STRPTR *OrigToolTypes)
2639 const STRPTR *TTPtr;
2640 STRPTR *TTClone;
2641 size_t AllocLen = sizeof(STRPTR);
2642 size_t StringCount = 1;
2644 d1(kprintf("%s/%s/%ld: OrigToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, OrigToolTypes));
2646 for (TTPtr = OrigToolTypes; *TTPtr; TTPtr++)
2648 d1(kprintf("%s/%s/%ld: *TTPtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *TTPtr));
2649 StringCount++;
2650 AllocLen += sizeof(STRPTR) + 1 + strlen(*TTPtr);
2653 d1(kprintf("%s/%s/%ld: StringCount=%lu AllocLen=%lu\n", __FILE__, __FUNC__, __LINE__, StringCount, AllocLen));
2655 TTClone = MyAllocVecPooled(PubMemPool, AllocLen);
2656 if (TTClone)
2658 STRPTR *TTDestPtr;
2659 STRPTR StringSpace;
2661 StringSpace = ((STRPTR) TTClone) + StringCount * sizeof(STRPTR);
2662 TTPtr = OrigToolTypes;
2663 TTDestPtr = TTClone;
2665 while (TTPtr && *TTPtr)
2667 *TTDestPtr = StringSpace;
2668 strcpy(*TTDestPtr, *TTPtr);
2670 StringSpace += 1 + strlen(*TTPtr);
2671 TTDestPtr++;
2672 TTPtr++;
2674 *TTDestPtr = NULL;
2677 d1(kprintf("%s/%s/%ld: TTClone=%08lx\n", __FILE__, __FUNC__, __LINE__, TTClone));
2679 return TTClone;
2682 //-----------------------------------------------------------------------------
2684 static void DrawFrame(Class *cl, Object *o, struct RastPort *rp,
2685 ULONG Width, ULONG Height, UWORD FrameType)
2687 struct InstanceData *inst = INST_DATA(cl, o);
2689 if (!inst->iobj_Borderless
2690 && 0 != inst->iobj_imgleft
2691 && 0 != inst->iobj_imgtop
2692 && FRAMETYPE_NONE != FrameType)
2694 struct RastPort rpCopy;
2695 struct InstanceData *inst = INST_DATA(cl, o);
2697 rpCopy = *rp;
2699 McpGfxDrawFrame(&rpCopy, 0, 0,
2700 Width - 1, Height - 1,
2701 IA_HalfShinePen, inst->iobj_HalfShinePen,
2702 IA_HalfShadowPen, inst->iobj_HalfShadowPen,
2703 IA_Recessed, (FrameType & 0x8000) ? TRUE : FALSE,
2704 IA_FrameType, FrameType & 0x7fff,
2705 TAG_END);
2709 //-----------------------------------------------------------------------------
2711 static void DrawMaskFrame(struct InstanceData *inst, struct BitMap *DestBitMap,
2712 ULONG Width, ULONG Height, UWORD FrameType)
2714 if (!inst->iobj_Borderless
2715 && FRAMETYPE_NONE != FrameType
2716 && 0 != inst->iobj_imgleft
2717 && 0 != inst->iobj_imgtop)
2719 struct RastPort TempRp;
2721 InitRastPort(&TempRp);
2722 TempRp.BitMap = DestBitMap;
2724 McpGfxDrawFrame(&TempRp,
2725 0, 0, Width - 1, Height - 1,
2726 IA_ShinePen, 1,
2727 IA_ShadowPen, 1,
2728 IA_HalfShinePen, 1,
2729 IA_HalfShadowPen, 1,
2730 IA_Recessed, (FrameType & 0x8000) ? TRUE : FALSE,
2731 IA_FrameType, FrameType & 0x7fff,
2732 TAG_END);
2736 //-----------------------------------------------------------------------------
2738 static struct RastPort *InitRast(Class *cl, Object *o, struct iopLayout *iopl, struct RastPort *rp)
2740 struct InstanceData *inst = INST_DATA(cl, o);
2741 ULONG BmDepth;
2743 memset(rp, 0, sizeof(struct RastPort));
2744 InitRastPort(rp);
2746 BmDepth = GetBitMapAttr(iopl->iopl_Screen->RastPort.BitMap, BMA_DEPTH);
2748 rp->BitMap = AllocBitMap(1 + inst->iobj_UnscaledWidth, 1 + inst->iobj_UnscaledHeight,
2749 BmDepth,
2750 BMF_MINPLANES | BMF_INTERLEAVED,
2751 iopl->iopl_Screen->RastPort.BitMap);
2753 return rp;
2756 //-----------------------------------------------------------------------------
2758 static struct BitMap *GenMask(Class *cl, Object *o,
2759 ULONG BmWidth, ULONG BmHeight, ULONG BmDepth, ULONG BmFlags,
2760 UBYTE *MaskPlane,
2761 UWORD FrameType, ULONG MaskWidth, ULONG MaskHeight)
2763 struct InstanceData *inst = INST_DATA(cl, o);
2764 struct BitMap *DestBitMap;
2765 LONG ImgMaskWidth, ImgMaskHeight;
2767 ImgMaskWidth = inst->iobj_NakedMaskWidth
2768 + inst->iobj_imgleft + inst->iobj_imgright;
2769 ImgMaskHeight = inst->iobj_NakedMaskHeight
2770 + inst->iobj_imgtop + inst->iobj_imgbottom;
2772 // after ARGB scaling, SrcBitMap might be smaller than actual image
2773 if (BmWidth < ImgMaskWidth)
2774 BmWidth = (ImgMaskWidth + 15) & 0xfff0;
2775 if (BmHeight < ImgMaskHeight)
2776 BmHeight = ImgMaskHeight;
2778 #if !defined(__AROS__)
2779 // XXX: is this really AROS specific?
2780 // maybe it's better to remove BMF_INTERLEAVED at all
2781 if (BmFlags & BMF_INTERLEAVED)
2783 BmWidth *= BmDepth;
2785 #endif
2787 d1(KPrintF("%s/%s/%ld: o=%08lx <%s> BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, BmWidth, BmHeight));
2788 d1(KPrintF("%s/%s/%ld: MaskPlane=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskPlane));
2789 d1(KPrintF("%s/%s/%ld: MaskWidth=%lu MaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, MaskWidth, MaskHeight));
2790 d1(KPrintF("%s/%s/%ld: ImgMaskWidth=%lu ImgMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, ImgMaskWidth, ImgMaskHeight));
2791 d1(KPrintF("%s/%s/%ld: iobj_imgleft=%ld iobj_imgright=%ld\n", \
2792 __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgright));
2793 d1(KPrintF("%s/%s/%ld: iobj_imgtop=%ld iobj_imgbottom=%ld\n", \
2794 __FILE__, __FUNC__, __LINE__, inst->iobj_imgtop, inst->iobj_imgbottom));
2795 d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \
2796 __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight));
2798 DestBitMap = AllocBitMap(BmWidth, BmHeight, 1, BMF_CLEAR, NULL);
2799 d1(KPrintF("%s/%s/%ld: DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap));
2800 if (DestBitMap)
2802 ASSERT_d1(BmWidth >= MaskWidth);
2803 ASSERT_d1(BmHeight >= MaskHeight);
2805 if (MaskPlane && (BmWidth >= MaskWidth) && (BmHeight >= MaskHeight))
2807 struct BitMap TempBM;
2809 d1(KPrintF("%s/%s/%ld: MaskWidth=%lu MaskHeight=%lu BytesPerRow=%ld\n", __FILE__, __FUNC__, __LINE__, MaskWidth, MaskHeight, BYTESPERROW(MaskWidth)));
2810 d1(KPrintF("%s/%s/%ld: ImgMaskWidth=%lu ImgMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, ImgMaskWidth, ImgMaskHeight));
2811 d1(KPrintF("%s/%s/%ld: BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, BmWidth, BmHeight));
2813 memset(&TempBM, 0, sizeof(TempBM));
2814 TempBM.BytesPerRow = BYTESPERROW(MaskWidth);
2815 TempBM.Rows = MaskHeight;
2816 TempBM.Flags = 0;
2817 TempBM.Depth = 1;
2818 TempBM.Planes[0] = MaskPlane;
2820 #if 0
2822 struct RastPort rp;
2824 InitRastPort(&rp);
2825 rp.BitMap = &TempBM;
2826 SetAPen(&rp, 1);
2827 RectFill(&rp,
2828 0, 0,
2829 MaskWidth - 1,
2830 MaskHeight - 1);
2832 #endif
2834 d1(KPrintF("%s/%s/%ld: BytesPerRow=%lu\n", __FILE__, __FUNC__, __LINE__, TempBM.BytesPerRow));
2836 ASSERT_d1(MaskWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH));
2837 ASSERT_d1(MaskHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT));
2839 BltBitMap(&TempBM, 0, 0,
2840 DestBitMap,
2841 inst->iobj_imgleft, inst->iobj_imgtop,
2842 MaskWidth,
2843 MaskHeight,
2844 ABC | ABNC, ~0, NULL);
2846 else
2848 struct ExtGadget *gg = (struct ExtGadget *) o;
2849 struct RastPort rp;
2850 WORD Right, Bottom;
2852 InitRastPort(&rp);
2853 rp.BitMap = DestBitMap;
2855 Right = min(gg->Width - inst->iobj_imgright - 1, BmWidth - 1);
2856 Bottom = min(gg->Height - inst->iobj_imgbottom - 1, BmHeight - 1);
2858 ASSERT_d1(Right < GetBitMapAttr(rp.BitMap, BMA_WIDTH));
2859 ASSERT_d1(Bottom < GetBitMapAttr(rp.BitMap, BMA_HEIGHT));
2861 SetAPen(&rp, 1);
2862 RectFill(&rp,
2863 inst->iobj_imgleft, inst->iobj_imgtop,
2864 Right,
2865 Bottom);
2867 WaitBlit();
2869 ASSERT_d1(ImgMaskWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH));
2870 ASSERT_d1(ImgMaskHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT));
2872 DrawMaskFrame(inst, DestBitMap,
2873 ImgMaskWidth,
2874 ImgMaskHeight,
2875 FrameType);
2878 d1(KPrintF("%s/%s/%ld: END DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap));
2880 return DestBitMap;
2883 //-----------------------------------------------------------------------------
2885 static struct BitMap *GenInvMask(Class *cl, Object *o, struct BitMap *SrcBitMap)
2887 // struct InstanceData *inst = INST_DATA(cl, o);
2888 struct BitMap *DestBitMap;
2889 ULONG BmWidth, BmHeight;
2890 ULONG BmFlags;
2891 ULONG BmDepth;
2893 BmFlags = GetBitMapAttr(SrcBitMap, BMA_FLAGS);
2894 BmWidth = GetBitMapAttr(SrcBitMap, BMA_WIDTH);
2895 BmHeight = GetBitMapAttr(SrcBitMap, BMA_HEIGHT);
2896 BmDepth = GetBitMapAttr(SrcBitMap, BMA_DEPTH);
2898 DestBitMap = AllocBitMap(BmWidth, BmHeight, BmDepth, BmFlags | BMF_CLEAR, NULL);
2899 d1(KPrintF("%s/%s/%ld: DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap));
2900 if (DestBitMap)
2902 // Blit inverted copy of SrcBitMap to DestBitMap
2903 ASSERT_d1(BmWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH));
2904 ASSERT_d1(BmHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT));
2906 BltBitMap(SrcBitMap,
2907 0, 0,
2908 DestBitMap,
2909 0, 0,
2910 BmWidth, BmHeight,
2911 ANBC | ANBNC,
2913 NULL);
2916 d1(KPrintF("%s/%s/%ld: END DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap));
2918 return DestBitMap;
2921 //-----------------------------------------------------------------------------
2923 static BOOL ScaleRenderBitMapsNormal(Class *cl, Object *o,
2924 ULONG NewWidth, ULONG NewHeight, struct Screen *screen)
2926 struct InstanceData *inst = INST_DATA(cl, o);
2927 struct ExtGadget *gg = (struct ExtGadget *) o;
2928 struct RastPort *rpNormal = (struct RastPort *) gg->GadgetRender;
2929 struct BitMap *NormBM = NULL;
2930 struct BitMap *NormMaskBM = NULL;
2931 ULONG *ColorTable;
2932 BOOL Success = FALSE;
2934 d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, cl, o, inst->iobj_name));
2935 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
2937 do {
2938 ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR
2939 | SCALEFLAGF_AVERAGE;
2941 d1(KPrintF("%s/%s/%ld: iobj_UnscaledWidth=%lu iobj_UnscaledHeight=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight));
2942 d1(KPrintF("%s/%s/%ld: iobj_UnscaledNakedWidth=%lu iobj_UnscaledNakedHeight=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledNakedWidth, inst->iobj_UnscaledNakedHeight));
2943 d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%ld\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight));
2944 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
2946 ColorTable = MyAllocVecPooled(PubMemPool,
2947 screen->ViewPort.ColorMap->Count * sizeof(ULONG) * 3);
2948 if (NULL == ColorTable)
2949 break;
2951 GetRGB32(screen->ViewPort.ColorMap,
2952 0, screen->ViewPort.ColorMap->Count, ColorTable);
2954 if (rpNormal && (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal))
2956 struct ScaleBitMapArg sbma;
2958 sbma.sbma_SourceBM = rpNormal->BitMap;
2959 sbma.sbma_SourceWidth = inst->iobj_UnscaledWidth;
2960 sbma.sbma_SourceHeight = inst->iobj_UnscaledHeight;
2961 sbma.sbma_DestWidth = &NewWidth;
2962 sbma.sbma_DestHeight = &NewHeight;
2963 sbma.sbma_NumberOfColors = screen->ViewPort.ColorMap->Count;
2964 sbma.sbma_ColorTable = ColorTable;
2965 sbma.sbma_Flags = ScaleFlags;
2966 sbma.sbma_ScreenBM = screen->RastPort.BitMap;
2968 NormBM = ScalosGfxScaleBitMap(&sbma, NULL);
2969 d1(KPrintF("%s/%s/%ld: NormBM=%08lx\n", __FILE__, __FUNC__, __LINE__, NormBM));
2970 if (NULL == NormBM)
2971 break;
2973 inst->iobj_layoutflags &= ~IOBLAYOUTF_ScaleNormal;
2975 d1(KPrintF("%s/%s/%ld: iom_MaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM));
2976 if (inst->iobj_NormalMask.iom_MaskBM)
2978 d1(DumpMaskBM(&inst->iobj_NormalMask));
2980 NormMaskBM = ScaleMaskBitMap(inst->iobj_NormalMask.iom_MaskBM,
2981 inst->iobj_NormalMask.iom_Width,
2982 inst->iobj_NormalMask.iom_Height,
2983 &NewWidth, &NewHeight,
2984 ScaleFlags,
2985 screen->RastPort.BitMap);
2986 d1(KPrintF("%s/%s/%ld: NormMaskBM=%08lx NewWidth=%ld NewHeight=%ld\n", \
2987 __FILE__, __FUNC__, __LINE__, NormMaskBM, NewWidth, NewHeight));
2988 if (NULL == NormMaskBM)
2989 break;
2991 DrawMaskFrame(inst, NormMaskBM,
2992 NewWidth, NewHeight,
2993 inst->iobj_frametype);
2996 // Replace GadgetRender BitMap by scaled one
2997 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rpNormal->BitMap));
2998 FreeBitMap(rpNormal->BitMap);
2999 rpNormal->BitMap = NormBM;
3000 NormBM = NULL;
3002 // optionally replace normal mask BitMap by scaled one
3003 if (NormMaskBM)
3005 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM));
3006 if (inst->iobj_NormalMask.iom_MaskBM)
3007 FreeBitMap(inst->iobj_NormalMask.iom_MaskBM);
3008 inst->iobj_NormalMask.iom_MaskBM = NormMaskBM;
3010 NormMaskBM = NULL;
3012 d1(DumpMaskBM(&inst->iobj_NormalMask));
3015 DrawFrame(cl, o, rpNormal,
3016 NewWidth,
3017 NewHeight,
3018 inst->iobj_frametype);
3021 Success = TRUE;
3022 } while (0);
3024 d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height));
3025 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, NormBM));
3026 if (NormBM)
3027 FreeBitMap(NormBM);
3028 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, NormMaskBM));
3029 if (NormMaskBM)
3030 FreeBitMap(NormMaskBM);
3031 if (ColorTable)
3032 MyFreeVecPooled(PubMemPool, (APTR) &ColorTable);
3034 d1(KPrintF("%s/%s/%ld: END cl=%08lx o=%08lx Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, Success, inst->iobj_layoutflags));
3036 return Success;
3039 //-----------------------------------------------------------------------------
3041 static BOOL ScaleRenderBitMapsSelected(Class *cl, Object *o,
3042 ULONG NewWidth, ULONG NewHeight, struct Screen *screen)
3044 struct InstanceData *inst = INST_DATA(cl, o);
3045 struct ExtGadget *gg = (struct ExtGadget *) o;
3046 struct RastPort *rpSelect = (struct RastPort *) gg->SelectRender;
3047 struct BitMap *SelBM = NULL;
3048 struct BitMap *SelMaskBM = NULL;
3049 ULONG *ColorTable;
3050 BOOL Success = FALSE;
3052 d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o));
3053 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
3055 do {
3056 ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR
3057 | SCALEFLAGF_AVERAGE;
3059 d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%ld\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight));
3060 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
3061 d1(KPrintF("%s/%s/%ld: SelBM: Width=%lu Height=%ld\n", \
3062 __FILE__, __FUNC__, __LINE__, GetBitMapAttr(rpSelect->BitMap, BMA_WIDTH), \
3063 GetBitMapAttr(rpSelect->BitMap, BMA_HEIGHT)));
3065 ColorTable = MyAllocVecPooled(PubMemPool,
3066 screen->ViewPort.ColorMap->Count * sizeof(ULONG) * 3);
3067 if (NULL == ColorTable)
3068 break;
3070 GetRGB32(screen->ViewPort.ColorMap,
3071 0, screen->ViewPort.ColorMap->Count, ColorTable);
3073 if (rpSelect && (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected))
3075 struct ScaleBitMapArg sbma;
3077 sbma.sbma_SourceBM = rpSelect->BitMap;
3078 sbma.sbma_SourceWidth = inst->iobj_UnscaledWidth;
3079 sbma.sbma_SourceHeight = inst->iobj_UnscaledHeight;
3080 sbma.sbma_DestWidth = &NewWidth;
3081 sbma.sbma_DestHeight = &NewHeight;
3082 sbma.sbma_NumberOfColors = screen->ViewPort.ColorMap->Count;
3083 sbma.sbma_ColorTable = ColorTable;
3084 sbma.sbma_Flags = ScaleFlags;
3085 sbma.sbma_ScreenBM = screen->RastPort.BitMap;
3087 SelBM = ScalosGfxScaleBitMap(&sbma, NULL);
3088 d1(KPrintF("%s/%s/%ld: SelBM=%08lx\n", __FILE__, __FUNC__, __LINE__, SelBM));
3089 if (NULL == SelBM)
3090 break;
3092 inst->iobj_layoutflags &= ~IOBLAYOUTF_ScaleSelected;
3094 d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
3095 if (inst->iobj_SelectedMask.iom_MaskBM)
3097 SelMaskBM = ScaleMaskBitMap(inst->iobj_SelectedMask.iom_MaskBM,
3098 inst->iobj_SelectedMask.iom_Width,
3099 inst->iobj_SelectedMask.iom_Height,
3100 &NewWidth, &NewHeight,
3101 ScaleFlags,
3102 screen->RastPort.BitMap);
3103 d1(KPrintF("%s/%s/%ld: SelMaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, SelMaskBM));
3104 if (NULL == SelMaskBM)
3105 break;
3107 DrawMaskFrame(inst, SelMaskBM,
3108 NewWidth, NewHeight,
3109 inst->iobj_frametypesel);
3112 // Replace SelectRender BitMap by scaled one
3113 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rpSelect->BitMap));
3114 FreeBitMap(rpSelect->BitMap);
3115 rpSelect->BitMap = SelBM;
3116 SelBM = NULL;
3118 // optionally replace selected mask BitMap by scaled one
3119 if (SelMaskBM)
3121 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
3122 if (inst->iobj_SelectedMask.iom_MaskBM)
3123 FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM);
3125 inst->iobj_SelectedMask.iom_MaskBM = SelMaskBM;
3127 SelMaskBM = NULL;
3130 DrawFrame(cl, o, rpSelect,
3131 NewWidth,
3132 NewHeight,
3133 inst->iobj_frametypesel);
3135 Success = TRUE;
3136 } while (0);
3138 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SelBM));
3139 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SelMaskBM));
3140 d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM));
3142 if (SelBM)
3143 FreeBitMap(SelBM);
3144 if (SelMaskBM)
3145 FreeBitMap(SelMaskBM);
3146 if (ColorTable)
3147 MyFreeVecPooled(PubMemPool, (APTR) &ColorTable);
3149 d1(KPrintF("%s/%s/%ld: END cl=%08lx o=%08lx Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, Success, inst->iobj_layoutflags));
3151 return Success;
3154 //-----------------------------------------------------------------------------
3156 static void LayoutIconSize(Class *cl, Object *o, struct RastPort *rp)
3158 struct InstanceData *inst = INST_DATA(cl, o);
3160 d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o));
3161 d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags));
3162 TIMESTAMP_d1();
3164 if (!(inst->iobj_layoutflags & IOBLAYOUTF_Size))
3166 struct ExtGadget *gg = (struct ExtGadget *) o;
3168 inst->iobj_layoutflags |= IOBLAYOUTF_Size;
3170 d1(KPrintF("%s/%s/%ld: NakedWidth=%lu NakedHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NakedWidth, inst->iobj_NakedHeight));
3171 d1(KPrintF("%s/%s/%ld: UnscalednakedWidth=%lu UnscalednakedHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledNakedWidth, inst->iobj_UnscaledNakedHeight));
3172 TIMESTAMP_d1();
3174 // adjust icon dimensions (add border)
3175 gg->Width = inst->iobj_NakedWidth
3176 + inst->iobj_imgleft + inst->iobj_imgright;
3177 gg->Height = inst->iobj_NakedHeight
3178 + inst->iobj_imgtop + inst->iobj_imgbottom;
3180 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height));
3182 inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth
3183 + inst->iobj_imgleft + inst->iobj_imgright;
3184 inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight
3185 + inst->iobj_imgtop + inst->iobj_imgbottom;
3187 d1(KPrintF("%s/%s/%ld: UnscaledWidth=%lu UnscaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight));
3189 inst->iobj_ScaledWidth = inst->iobj_NakedWidth
3190 + inst->iobj_imgleft + inst->iobj_imgright;
3191 inst->iobj_ScaledHeight = inst->iobj_NakedHeight
3192 + inst->iobj_imgtop + inst->iobj_imgbottom;
3194 d1(KPrintF("%s/%s/%ld: ScaledWidth=%lu ScaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_ScaledWidth, inst->iobj_ScaledHeight));
3195 TIMESTAMP_d1();
3197 // ExtGadget has valid bounds
3198 gg->MoreFlags |= GMORE_BOUNDS;
3200 gg->BoundsLeftEdge = gg->LeftEdge;
3201 gg->BoundsTopEdge = gg->TopEdge;
3202 gg->BoundsWidth = gg->Width;
3203 gg->BoundsHeight = gg->Height;
3205 TIMESTAMP_d1();
3207 if (inst->iobj_text)
3208 LayoutIconText(inst, rp, gg);
3210 TIMESTAMP_d1();
3213 //-----------------------------------------------------------------------------
3215 static struct BitMap *ScaleMaskBitMap(struct BitMap *SourceBM,
3216 ULONG SourceWidth, ULONG SourceHeight,
3217 ULONG *NewWidth, ULONG *NewHeight,
3218 ULONG ScaleFlags, struct BitMap *FriendBM)
3220 struct BitMap *SourceBMFriend;
3221 struct BitMap *NewMaskBM = NULL;
3222 struct BitMap *ScaledBM = NULL;
3224 d1(KPrintF("%s/%s/%ld: START SourceWidth=%lu SourceHeight=%lu\n", __FILE__, __FUNC__, __LINE__, SourceWidth, SourceHeight));
3225 d1(KPrintF("%s/%s/%ld: DestWidth=%lu DestHeight=%lu\n", __FILE__, __FUNC__, __LINE__, *NewWidth, *NewHeight));
3226 d1(KPrintF("%s/%s/%ld: SourceBM: Width=%lu Height=%ld BytesPerRow=%ld\n", \
3227 __FILE__, __FUNC__, __LINE__, GetBitMapAttr(SourceBM, BMA_WIDTH), \
3228 GetBitMapAttr(SourceBM, BMA_HEIGHT), SourceBM->BytesPerRow));
3230 do {
3231 ULONG BmWidth;
3232 struct ScaleBitMapArg sbma;
3233 static ULONG ColorTable[] =
3235 0, 0, 0, // pen 0 = black
3236 ~0, ~0, ~0, // pen 1 = white
3239 SourceBMFriend = AllocBitMap(GetBitMapAttr(SourceBM, BMA_WIDTH),
3240 GetBitMapAttr(SourceBM, BMA_HEIGHT),
3241 1, BMF_CLEAR, FriendBM);
3242 if (NULL == SourceBMFriend)
3243 break;
3245 d1(KPrintF("%s/%s/%ld: SourceBMFriend Planes=%08lx %08lx %08lx %08lx\n",
3246 __FILE__, __FUNC__, __LINE__, SourceBMFriend->Planes[0], SourceBMFriend->Planes[1], SourceBMFriend->Planes[2], SourceBMFriend->Planes[3]));
3248 ASSERT_d1(SourceWidth <= GetBitMapAttr(SourceBMFriend, BMA_WIDTH));
3249 ASSERT_d1(SourceHeight <= GetBitMapAttr(SourceBMFriend, BMA_HEIGHT));
3251 BltBitMap(SourceBM, 0, 0,
3252 SourceBMFriend, 0, 0,
3253 SourceWidth, SourceHeight,
3254 ABC | ABNC,
3256 NULL);
3257 WaitBlit();
3259 #if 0
3261 struct RastPort rp;
3263 InitRastPort(&rp);
3264 rp.BitMap = SourceBMFriend;
3265 SetAPen(&rp, 1);
3266 RectFill(&rp,
3267 0, 0,
3268 GetBitMapAttr(SourceBMFriend, BMA_WIDTH) - 1,
3269 GetBitMapAttr(SourceBMFriend, BMA_HEIGHT) - 1);
3271 #endif
3273 sbma.sbma_SourceBM = SourceBMFriend;
3274 sbma.sbma_SourceWidth = SourceWidth;
3275 sbma.sbma_SourceHeight = SourceHeight;
3276 sbma.sbma_DestWidth = NewWidth;
3277 sbma.sbma_DestHeight = NewHeight;
3278 sbma.sbma_NumberOfColors = 2;
3279 sbma.sbma_ColorTable = ColorTable;
3280 sbma.sbma_Flags = ScaleFlags;
3281 sbma.sbma_ScreenBM = FriendBM;
3283 ScaledBM = ScalosGfxScaleBitMap(&sbma, NULL);
3284 if (NULL == ScaledBM)
3285 break;
3287 BmWidth = *NewWidth;
3288 if (GetBitMapAttr(FriendBM, BMA_FLAGS) & BMF_INTERLEAVED)
3289 BmWidth *= GetBitMapAttr(FriendBM, BMA_DEPTH);
3291 NewMaskBM = AllocBitMap(BmWidth, *NewHeight,
3292 1, BMF_CLEAR, NULL);
3293 if (NULL == NewMaskBM)
3294 break;
3296 ASSERT_d1(*NewWidth <= GetBitMapAttr(NewMaskBM, BMA_WIDTH));
3297 ASSERT_d1(*NewHeight <= GetBitMapAttr(NewMaskBM, BMA_HEIGHT));
3299 BltBitMap(ScaledBM, 0, 0,
3300 NewMaskBM, 0, 0,
3301 *NewWidth, *NewHeight,
3302 ABC | ABNC,
3304 NULL);
3306 d1(KPrintF("%s/%s/%ld: NewMaskBM: Width=%lu Height=%ld BytesPerRow=%ld\n", \
3307 __FILE__, __FUNC__, __LINE__, GetBitMapAttr(NewMaskBM, BMA_WIDTH), \
3308 GetBitMapAttr(NewMaskBM, BMA_HEIGHT), NewMaskBM->BytesPerRow));
3310 WaitBlit();
3311 } while (0);
3313 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SourceBMFriend));
3314 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, ScaledBM));
3316 if (SourceBMFriend)
3317 FreeBitMap(SourceBMFriend);
3318 if (ScaledBM)
3319 FreeBitMap(ScaledBM);
3321 d1(KPrintF("%s/%s/%ld: END NewMaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, NewMaskBM));
3323 return NewMaskBM;
3326 //-----------------------------------------------------------------------------
3328 static void CheckIfScalingRequired(Class *cl, Object *o)
3330 struct InstanceData *inst = INST_DATA(cl, o);
3331 struct ExtGadget *gg = (struct ExtGadget *) o;
3333 d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> iobj_NakedWidth=%ld iobj_NakedHeight=%ld\n", \
3334 __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, inst->iobj_NakedWidth, inst->iobj_NakedHeight));
3336 if (inst->iobj_ScalingPercentage != 100
3337 || inst->iobj_NakedWidth < inst->iobj_SizeConstraints.MinX
3338 || inst->iobj_NakedWidth > inst->iobj_SizeConstraints.MaxX
3339 || inst->iobj_NakedHeight < inst->iobj_SizeConstraints.MinY
3340 || inst->iobj_NakedHeight> inst->iobj_SizeConstraints.MaxY)
3342 // We need to scale the icon!
3343 d1(KPrintF("%s/%s/%ld: Need to scale icon <%s>\n", __FILE__, __FUNC__, __LINE__, inst->iobj_name));
3345 inst->iobj_NakedWidth = (gg->Width * inst->iobj_ScalingPercentage) / 100;
3346 inst->iobj_NakedHeight = (gg->Height * inst->iobj_ScalingPercentage) / 100;
3348 if (gg->Width < inst->iobj_SizeConstraints.MinX)
3349 inst->iobj_NakedWidth = inst->iobj_SizeConstraints.MinX;
3350 else if (gg->Width > inst->iobj_SizeConstraints.MaxX)
3351 inst->iobj_NakedWidth = inst->iobj_SizeConstraints.MaxX;
3353 if (gg->Height < inst->iobj_SizeConstraints.MinY)
3354 inst->iobj_NakedHeight = inst->iobj_SizeConstraints.MinY;
3355 else if (gg->Height > inst->iobj_SizeConstraints.MaxY)
3356 inst->iobj_NakedHeight = inst->iobj_SizeConstraints.MaxY;
3358 ScalosGfxCalculateScaleAspect(inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight,
3359 &inst->iobj_NakedWidth, &inst->iobj_NakedHeight);
3361 if (inst->iobj_UnscaledNakedWidth != inst->iobj_NakedWidth
3362 || inst->iobj_UnscaledNakedHeight != inst->iobj_NakedHeight)
3364 gg->Width = inst->iobj_ScaledWidth = inst->iobj_NakedWidth;
3365 gg->Height = inst->iobj_ScaledHeight = inst->iobj_NakedHeight;
3367 inst->iobj_layoutflags &= ~IOBLAYOUTF_Size;
3370 inst->iobj_layoutflags |= IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected;
3373 d1(KPrintF("%s/%s/%ld: END \n", __FILE__, __FUNC__, __LINE__));
3376 //-----------------------------------------------------------------------------
3378 #if defined(DEBUG_MEMORY)
3380 APTR MyAllocVecPooled_Debug(void *MemPool, size_t Size, CONST_STRPTR CallingFile,
3381 CONST_STRPTR CallingFunc, ULONG CallingLine)
3383 struct AllocatedMemFromPoolDebug *ptr;
3385 if (MemPool)
3387 size_t AllocSize;
3389 AllocSize = Size + sizeof(struct AllocatedMemFromPoolDebug) + SCALOS_MEM_TRAILER * sizeof(ULONG);
3391 ObtainSemaphore(&MemPoolSemaphore);
3392 ptr = AllocPooled(MemPool, AllocSize);
3393 ReleaseSemaphore(&MemPoolSemaphore);
3394 if (ptr)
3396 ULONG n;
3398 ptr->amp_Size = AllocSize;
3400 ptr->amp_Line = CallingLine;
3401 ptr->amp_File = CallingFile;
3402 ptr->amp_Function = CallingFunc;
3404 ptr->amp_Magic = SCALOS_MEM_START_MAGIC;
3406 for (n = 0; n < SCALOS_MEM_TRAILER; n++)
3407 *((ULONG *) &ptr->amp_UserData[Size + n * sizeof(ULONG)]) = SCALOS_MEM_END_MAGIC;
3409 return (APTR) &ptr->amp_UserData;
3413 return NULL;
3417 void MyFreeVecPooled_Debug(void *MemPool, APTR *mem, CONST_STRPTR CallingFile,
3418 CONST_STRPTR CallingFunc, ULONG CallingLine)
3420 if (MemPool && *mem)
3422 ULONG n;
3423 size_t OrigSize;
3424 struct AllocatedMemFromPoolDebug *ptr;
3426 ptr = (struct AllocatedMemFromPoolDebug *) (((UBYTE *) *mem) - offsetof(struct AllocatedMemFromPoolDebug, amp_UserData));
3428 if (ptr->amp_Magic != SCALOS_MEM_START_MAGIC)
3430 kprintf("ScalosFreeVecPooled: %08lx START_MAGIC not found, called from %s/%s/%ld\n",
3431 *mem, CallingFile, CallingFunc, CallingLine);
3432 return;
3435 OrigSize = ptr->amp_Size - sizeof(struct AllocatedMemFromPoolDebug) - SCALOS_MEM_TRAILER * sizeof(ULONG);
3437 // Check if block trailer is OK
3438 for (n = 0; n < SCALOS_MEM_TRAILER; n++)
3440 if (*((ULONG *) &ptr->amp_UserData[OrigSize + n * sizeof(ULONG)]) != SCALOS_MEM_END_MAGIC)
3442 kprintf("ScalosFreeVecPooled: %08lx trailer damaged, called from %s/%s/%ld\n",
3443 *mem, CallingFile, CallingFunc, CallingLine);
3444 kprintf(" original Length=%lu, allocated from %s/%s/%ld\n",
3445 OrigSize, ptr->amp_File, ptr->amp_Function, ptr->amp_Line);
3449 ObtainSemaphore(&MemPoolSemaphore);
3450 FreePooled(MemPool, ptr, ptr->amp_Size);
3451 ReleaseSemaphore(&MemPoolSemaphore);
3453 *mem = NULL;
3457 #else /* DEBUG_MEMORY */
3459 APTR MyAllocVecPooled(void *MemPool, size_t Size)
3461 APTR ptr;
3463 d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size));
3465 if (MemPool)
3467 ObtainSemaphore(&MemPoolSemaphore);
3468 ptr = AllocPooled(MemPool, Size + sizeof(size_t));
3469 ReleaseSemaphore(&MemPoolSemaphore);
3470 if (ptr)
3472 size_t *sptr = (size_t *) ptr;
3474 sptr[0] = Size;
3476 d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1]));
3477 return (APTR)(&sptr[1]);
3481 d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size));
3483 return NULL;
3487 void MyFreeVecPooled(void *MemPool, APTR *mem)
3489 d1(KPrintF("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, *mem));
3490 if (MemPool && *mem)
3492 size_t size;
3493 size_t *sptr = (size_t *) *mem;
3494 APTR MemPtr;
3496 MemPtr = &sptr[-1];
3497 size = sptr[-1];
3499 ObtainSemaphore(&MemPoolSemaphore);
3500 FreePooled(MemPool, MemPtr, size + sizeof(size_t));
3501 ReleaseSemaphore(&MemPoolSemaphore);
3504 *mem = NULL;
3508 #endif /* DEBUG_MEMORY */
3510 //-----------------------------------------------------------------------------
3512 struct TagItem *ScalosVTagList(ULONG FirstTag, va_list args)
3514 struct TagItem *ClonedTagList;
3515 ULONG AllocatedSize = 10;
3517 d1(KPrintF("%s/%s/%ld: FirstTag=%08lx args=%08lx\n", __FILE__, __FUNC__, __LINE__, FirstTag, args));
3519 do {
3520 ULONG NumberOfTags = 1;
3521 BOOL Finished = FALSE;
3522 struct TagItem *ti;
3524 ClonedTagList = ti = AllocateTagItems(AllocatedSize);
3525 if (NULL == ClonedTagList)
3526 break;
3528 ClonedTagList->ti_Tag = FirstTag;
3529 while (!Finished)
3531 switch (ti->ti_Tag)
3533 case TAG_MORE:
3534 ti->ti_Data = va_arg(args, ULONG);
3535 Finished = TRUE;
3536 break;
3537 case TAG_END:
3538 Finished = TRUE;
3539 break;
3540 default:
3541 ti->ti_Data = va_arg(args, ULONG);
3542 break;
3545 d1(KPrintF("%s/%s/%ld ti=%08lx Tag=%08lx Data=%08lx\n", __FILE__, __FUNC__, __LINE__, ti, ti->ti_Tag, ti->ti_Data));
3547 if (!Finished)
3549 if (++NumberOfTags >= AllocatedSize)
3551 // we need to extend our allocated taglist
3552 struct TagItem *ExtendedTagList;
3553 ULONG ExtendedSize = 2 * AllocatedSize;
3555 ExtendedTagList = AllocateTagItems(ExtendedSize);
3556 if (NULL == ExtendedTagList)
3558 FreeTagItems(ClonedTagList);
3559 ClonedTagList = NULL;
3560 break;
3563 d1(KPrintF("%s/%s/%ld: ExtendedTagList=%08lx ClonedTagList=%08lx\n", __FILE__, __FUNC__, __LINE__, ExtendedTagList, ClonedTagList));
3565 // copy contents from old to extended taglist
3566 memcpy(ExtendedTagList, ClonedTagList, sizeof(struct TagItem) * AllocatedSize);
3568 // free old taglist
3569 FreeTagItems(ClonedTagList);
3570 ClonedTagList = ExtendedTagList;
3572 ti = ClonedTagList + NumberOfTags - 1;
3573 AllocatedSize = ExtendedSize;
3575 else
3577 ti++;
3580 ti->ti_Tag = va_arg(args, ULONG);
3584 d1(KPrintF("%s/%s/%ld: NumberOfTags=%lu AllocatedSize=%lu\n", __FILE__, __FUNC__, __LINE__, NumberOfTags, AllocatedSize));
3585 } while (0);
3587 d1(KPrintF("%s/%s/%ld: ClonedTagList=%08lx\n", __FILE__, __FUNC__, __LINE__, ClonedTagList));
3589 d1({ ULONG n; \
3590 for (n = 0; ClonedTagList; n++) \
3592 KPrintF("%s/%s/%ld: TagList[%ld]: Tag=%08lx Data=%08lx\n", \
3593 __FILE__, __FUNC__, __LINE__, n, ClonedTagList[n].ti_Tag, ClonedTagList[n].ti_Data); \
3594 if (TAG_END == ClonedTagList[n].ti_Tag || TAG_MORE == ClonedTagList[n].ti_Tag)
3595 break;
3599 return ClonedTagList;
3602 //-----------------------------------------------------------------------------
3604 static void ReplaceARGBImage(struct IconObjectARGB *img, struct ARGBHeader *argbh)
3606 if (argbh)
3607 img->iargb_ARGBimage = *argbh;
3608 else
3609 img->iargb_ARGBimage.argb_ImageData = NULL;
3611 d1(KPrintF("%s/%s/%ld: argb_Width=%ld argb_Height=%ld\n", __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height));
3613 if (img->iargb_CopyARGBImageData)
3615 ScalosGfxFreeARGB(&img->iargb_ClonedARGBImage.argb_ImageData);
3617 if (img->iargb_ARGBimage.argb_ImageData)
3619 ULONG Length = img->iargb_ARGBimage.argb_Width * img->iargb_ARGBimage.argb_Height * sizeof(struct ARGB);
3621 img->iargb_ClonedARGBImage = img->iargb_ARGBimage;
3623 img->iargb_ClonedARGBImage.argb_ImageData = ScalosGfxCreateARGB(img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height, NULL);
3624 if (img->iargb_ClonedARGBImage.argb_ImageData)
3626 memcpy(img->iargb_ClonedARGBImage.argb_ImageData,
3627 img->iargb_ARGBimage.argb_ImageData, Length);
3629 img->iargb_ARGBimage = img->iargb_ClonedARGBImage;
3630 d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \
3631 __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage, img->iargb_ARGBimage.argb_ImageData));
3637 //-----------------------------------------------------------------------------
3639 static void FreeARGBImage(struct IconObjectARGB *img)
3641 if (img)
3643 ScalosGfxFreeARGB(&img->iargb_ScaledARGBImage.argb_ImageData);
3644 ScalosGfxFreeARGB(&img->iargb_ClonedARGBImage.argb_ImageData);
3645 MyFreeVecPooled(PubMemPool, (APTR *) &img->iargb_AlphaChannel);
3646 d1(KPrintF("%s/%s/%ld: w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height));
3650 //-----------------------------------------------------------------------------
3652 static void FreeARGBImageLayout(struct IconObjectARGB *img)
3654 MyFreeVecPooled(PubMemPool, (APTR *) &img->iargb_AlphaChannel);
3657 //-----------------------------------------------------------------------------
3659 static void FreeMask(struct IconObjectMask *Mask)
3661 MyFreeVecPooled(ChipMemPool, (APTR *) &Mask->iom_Mask);
3663 if (Mask->iom_MaskBM)
3665 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, Mask->iom_MaskBM));
3666 FreeBitMap(Mask->iom_MaskBM);
3667 Mask->iom_MaskBM = NULL;
3669 if (Mask->iom_MaskInvBM)
3671 d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, Mask->iom_MaskInvBM));
3672 FreeBitMap(Mask->iom_MaskInvBM);
3673 Mask->iom_MaskInvBM = NULL;
3677 //-----------------------------------------------------------------------------
3679 static void LayoutARGB(Class *cl, Object *o, struct IconObjectARGB *img)
3681 struct ExtGadget *gg = (struct ExtGadget *) o;
3682 struct InstanceData *inst = INST_DATA(cl, o);
3683 struct ARGBHeader *ImgHeader;
3685 d1(KPrintF("%s/%s/%ld: START o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
3686 d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
3687 img->iargb_ARGBimage.argb_Width, \
3688 img->iargb_ARGBimage.argb_Height));
3690 if (img->iargb_ScaledARGBImage.argb_ImageData)
3691 ImgHeader = &img->iargb_ScaledARGBImage;
3692 else
3693 ImgHeader = &img->iargb_ARGBimage;
3695 d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
3697 if ((inst->iobj_imgleft + ImgHeader->argb_Width) > gg->BoundsWidth)
3699 d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
3702 // Generate iobj_normmaskbm+iobj_selmaskbm from ARGB image
3703 GenMasksFromARGB(cl, o);
3705 d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
3707 // Extract alpha channel data from ARGB image
3708 GenAlphaFromARGB(cl, o, img, ImgHeader);
3710 d1(KPrintF("%s/%s/%ld: END o=%08lx\n", __FILE__, __FUNC__, __LINE__, o));
3713 //-----------------------------------------------------------------------------
3715 static BOOL ScaleARGB(Class *cl, Object *o, struct IconObjectARGB *img,
3716 struct IconObjectMask *Mask, ULONG NewWidth, ULONG NewHeight, ULONG ScaleFlags)
3718 struct InstanceData *inst = INST_DATA(cl, o);
3719 BOOL Success = FALSE;
3721 ScalosGfxFreeARGB(&img->iargb_ScaledARGBImage.argb_ImageData);
3723 img->iargb_ScaledARGBImage.argb_Width = NewWidth;
3724 img->iargb_ScaledARGBImage.argb_Height = NewHeight;
3726 img->iargb_ScaledARGBImage.argb_ImageData = ScalosGfxScaleARGBArrayTags(&img->iargb_ARGBimage,
3727 &img->iargb_ScaledARGBImage.argb_Width,
3728 &img->iargb_ScaledARGBImage.argb_Height,
3729 SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags,
3730 TAG_END);
3732 d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%lu\n", __FILE__, __FUNC__, __LINE__, img->iargb_ScaledARGBImage.argb_Width, img->iargb_ScaledARGBImage.argb_Height));
3733 d1(KPrintF("%s/%s/%ld: NewARGB=%08lx\n", __FILE__, __FUNC__, __LINE__, img->iargb_ScaledARGBImage.argb_ImageData));
3735 // Mask and Alpha are automatically recreated during IDTM_Layout
3737 if (img->iargb_ScaledARGBImage.argb_ImageData)
3739 Success = TRUE;
3741 Mask->iom_Width = inst->iobj_SelectedMask.iom_Width = img->iargb_ScaledARGBImage.argb_Width;
3742 Mask->iom_Height = inst->iobj_SelectedMask.iom_Height = img->iargb_ScaledARGBImage.argb_Height;
3743 d1(KPrintF("%s/%s/%ld: Mask->Width=%lu Mask->Height=%lu\n", __FILE__, __FUNC__, __LINE__, Mask->iom_Width, Mask->iom_Height));
3746 return Success;
3749 //-----------------------------------------------------------------------------
3751 static void EraseIconText(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y)
3753 struct InstanceData *inst = INST_DATA(cl, o);
3754 struct ExtGadget *gg = (struct ExtGadget *) o;
3755 WORD TextLeft = x - inst->iobj_GlobalTextLeftOffset + 1;
3756 WORD TextRight = TextLeft + inst->iobj_TextExtent.te_Width - 1;
3757 WORD TextTop = y + gg->Height + inst->iobj_textskip;
3758 WORD TextBottom = TextTop + inst->iobj_TextExtent.te_Height - 1;
3760 if (inst->iobj_SelectedTextRectangle)
3762 // TextLeft -= inst->iobj_TextRectBorderX;
3763 TextRight += 2 * inst->iobj_TextRectBorderX;
3764 TextBottom += 2 * inst->iobj_TextRectBorderY;
3767 EraseRect(rp,
3768 TextLeft, TextTop,
3769 TextRight, TextBottom);
3772 //-----------------------------------------------------------------------------
3774 static void DrawIconTextRect(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y)
3776 struct InstanceData *inst = INST_DATA(cl, o);
3778 if (inst->iobj_SelectedTextRectangle)
3780 PLANEPTR myPlanePtr;
3781 LONG bmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH);
3782 LONG bmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT);
3784 do {
3785 struct ExtGadget *gg = (struct ExtGadget *) o;
3786 WORD AreaBuffer[AREAMAX];
3787 struct TmpRas myTmpRas;
3788 struct AreaInfo AInfo;
3789 struct RastPort myRp = *rp;
3790 WORD TextLeft = x - inst->iobj_GlobalTextLeftOffset + 1;
3791 WORD TextRight = TextLeft + inst->iobj_TextExtent.te_Width + (2 * inst->iobj_TextRectBorderX) - 1;
3792 WORD TextTop = y + gg->Height + inst->iobj_textskip;
3793 WORD TextBottom = TextTop + inst->iobj_TextExtent.te_Height + (2 * inst->iobj_TextRectBorderY) - 1;
3794 UWORD Radius = inst->iobj_TextRectRadius;
3796 myPlanePtr = AllocRaster(bmWidth, bmHeight);
3797 if (myPlanePtr == NULL)
3798 break;
3800 InitTmpRas(&myTmpRas, myPlanePtr, RASSIZE(bmWidth, bmHeight));
3801 myRp.TmpRas = &myTmpRas;
3803 InitArea(&AInfo, AreaBuffer, (AREAMAX * sizeof(WORD)) / 5);
3804 myRp.AreaInfo = &AInfo;
3806 SetABPenDrMd(&myRp,
3807 inst->iobj_TextPenBgSel,
3809 JAM1);
3811 // 1-----2 TextTop
3812 // / \ .
3813 // 8 3 .
3814 // | | .
3815 // 7 4 .
3816 // \ / .
3817 // 6---5 TextBottom
3819 AreaMove(&myRp, TextLeft + Radius, TextTop); // 1
3821 AreaDraw(&myRp, TextRight - Radius, TextTop); // -> 2
3822 AreaDraw(&myRp, TextRight, TextTop + Radius); // -> 3
3823 AreaDraw(&myRp, TextRight, TextBottom - Radius); // -> 4
3824 AreaDraw(&myRp, TextRight - Radius, TextBottom); // -> 5
3826 AreaDraw(&myRp, TextLeft + Radius, TextBottom); // -> 6
3827 AreaDraw(&myRp, TextLeft, TextBottom - Radius); // -> 7
3828 AreaDraw(&myRp, TextLeft, TextTop + Radius); // -> 8
3830 AreaEnd(&myRp);
3832 InitArea(&AInfo, AreaBuffer, (AREAMAX * sizeof(WORD)) / 5);
3834 AreaCircle(&myRp, TextLeft + Radius, TextTop + Radius, Radius); // top left
3835 AreaCircle(&myRp, TextRight - Radius, TextTop + Radius, Radius); // top right
3836 AreaCircle(&myRp, TextLeft + Radius, TextBottom - Radius, Radius); // bottom left
3837 AreaCircle(&myRp, TextRight - Radius, TextBottom - Radius, Radius); // bottom right
3839 AreaEnd(&myRp);
3841 d1(KPrintF("%s/%s/%ld: iobj_TextPenBgSel=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_TextPenBgSel));
3842 } while (0);
3844 if (myPlanePtr)
3845 FreeRaster(myPlanePtr, bmWidth, bmHeight);
3847 else
3849 EraseIconText(cl, o, rp, x, y);
3853 //-----------------------------------------------------------------------------
3854 static void DumpMaskPlane(const struct IconObjectMask *Mask)
3856 LONG x, y;
3857 const UBYTE *mp;
3859 if (!Mask || !Mask->iom_MaskBM || !Mask->iom_MaskBM->Planes[0])
3860 return;
3862 mp = Mask->iom_MaskBM->Planes[0];
3864 for (y = 0; y < Mask->iom_Height; y++)
3866 KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__);
3868 for (x = 0; x < Mask->iom_Width; x++)
3870 UBYTE px = mp[x / 8] & (0x80 >> (x % 8));
3872 KPrintF("%ld", (px ? 1 : 0));
3874 KPrintF("\n");
3876 mp += BYTESPERROW(Mask->iom_Width);
3879 //-----------------------------------------------------------------------------
3880 static void DumpMask(const struct IconObjectMask *Mask)
3882 LONG x, y;
3883 const UBYTE *mp;
3885 if (!Mask || !Mask->iom_Mask)
3886 return;
3888 mp = Mask->iom_Mask;
3890 for (y = 0; y < Mask->iom_Height; y++)
3892 KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__);
3894 for (x = 0; x < Mask->iom_Width; x++)
3896 UBYTE px = mp[x / 8] & (0x80 >> (x % 8));
3898 KPrintF("%ld", (px ? 1 : 0));
3900 KPrintF("\n");
3902 mp += BYTESPERROW(Mask->iom_Width);
3906 //-----------------------------------------------------------------------------
3908 static void DumpMaskBM(const struct IconObjectMask *Mask)
3910 LONG x, y;
3911 const UBYTE *mp;
3912 struct RastPort rp;
3914 if (!Mask || !Mask->iom_Mask)
3915 return;
3917 mp = Mask->iom_Mask;
3919 InitRastPort(&rp);
3920 rp.BitMap = Mask->iom_MaskBM;
3922 for (y = 0; y < Mask->iom_Height; y++)
3924 KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__);
3926 for (x = 0; x < Mask->iom_Width; x++)
3928 UBYTE px = ReadPixel(&rp, x, y);
3930 KPrintF("%ld", (px ? 1 : 0));
3932 KPrintF("\n");
3934 mp += BYTESPERROW(Mask->iom_Width);
3937 //-----------------------------------------------------------------------------
3939 #if !defined(__SASC)
3940 // Replacement for SAS/C library functions
3942 void exit(int x)
3944 (void) x;
3945 while (1)
3949 #endif /* !defined(__SASC) */
3950 //-----------------------------------------------------------------------------
3952 #if defined(__AROS__)
3954 #include "aros/symbolsets.h"
3956 ADD2INITLIB(InitDatatype, 0);
3957 ADD2EXPUNGELIB(CloseDatatype, 0);
3958 ADD2OPENLIB(OpenDatatype, 0);
3960 #endif
3961 //-----------------------------------------------------------------------------